@nemus-cli/nemus 0.2.1

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 (320) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/LICENSE +21 -0
  3. package/README.md +275 -0
  4. package/assets/README.md +53 -0
  5. package/assets/banner.png +0 -0
  6. package/assets/banner.svg +66 -0
  7. package/assets/favicon-32.png +0 -0
  8. package/assets/favicon-64.png +0 -0
  9. package/assets/icon-256.png +0 -0
  10. package/assets/icon.svg +23 -0
  11. package/assets/logo-256.png +0 -0
  12. package/assets/logo-512.png +0 -0
  13. package/assets/logo-wordmark.svg +35 -0
  14. package/assets/logo.svg +32 -0
  15. package/bin/workspace.js +130 -0
  16. package/dist/cli/ai-prompt.js +421 -0
  17. package/dist/cli/dashboard/AgentList.js +61 -0
  18. package/dist/cli/dashboard/DashboardSidebar.js +280 -0
  19. package/dist/cli/dashboard/HelpFooter.js +73 -0
  20. package/dist/cli/dashboard/StatusBadge.js +50 -0
  21. package/dist/cli/dashboard/index.js +11 -0
  22. package/dist/cli/dashboard/types.js +2 -0
  23. package/dist/cli/tui.js +48 -0
  24. package/dist/commands/ai-prompt.js +22 -0
  25. package/dist/commands/analyze-deps.js +138 -0
  26. package/dist/commands/archive.js +113 -0
  27. package/dist/commands/branch/create.js +119 -0
  28. package/dist/commands/branch/index.js +104 -0
  29. package/dist/commands/branch/merge.js +90 -0
  30. package/dist/commands/branch/rebase.js +84 -0
  31. package/dist/commands/branch/switch.js +165 -0
  32. package/dist/commands/cache/index.js +80 -0
  33. package/dist/commands/cache/manager.js +198 -0
  34. package/dist/commands/cleanup.js +153 -0
  35. package/dist/commands/configure-claude.js +55 -0
  36. package/dist/commands/configure.js +231 -0
  37. package/dist/commands/create.js +204 -0
  38. package/dist/commands/dashboard/hook-handler.js +162 -0
  39. package/dist/commands/dashboard/index.js +258 -0
  40. package/dist/commands/dashboard/launcher.js +40 -0
  41. package/dist/commands/dashboard/session-picker.js +106 -0
  42. package/dist/commands/dashboard/sidebar.js +39 -0
  43. package/dist/commands/dashboard/workspace-picker.js +95 -0
  44. package/dist/commands/delete.js +194 -0
  45. package/dist/commands/deprecated-aliases.js +44 -0
  46. package/dist/commands/diff.js +129 -0
  47. package/dist/commands/doctor.js +141 -0
  48. package/dist/commands/generate-docs.js +77 -0
  49. package/dist/commands/ghq-status.js +72 -0
  50. package/dist/commands/go.js +154 -0
  51. package/dist/commands/history.js +124 -0
  52. package/dist/commands/list.js +191 -0
  53. package/dist/commands/mcp/index.js +69 -0
  54. package/dist/commands/migrate.js +296 -0
  55. package/dist/commands/remove-repo.js +217 -0
  56. package/dist/commands/report-bug.js +112 -0
  57. package/dist/commands/run.js +147 -0
  58. package/dist/commands/save-context.js +171 -0
  59. package/dist/commands/sessions.js +129 -0
  60. package/dist/commands/status.js +138 -0
  61. package/dist/commands/suite/create.js +212 -0
  62. package/dist/commands/suite/delete.js +64 -0
  63. package/dist/commands/suite/export.js +126 -0
  64. package/dist/commands/suite/import.js +128 -0
  65. package/dist/commands/suite/index.js +94 -0
  66. package/dist/commands/suite/list.js +49 -0
  67. package/dist/commands/suite/use.js +227 -0
  68. package/dist/commands/sync.js +117 -0
  69. package/dist/commands/update.js +203 -0
  70. package/dist/mcp/install.js +550 -0
  71. package/dist/mcp/server.js +398 -0
  72. package/dist/mcp/tools.js +922 -0
  73. package/dist/pi-extensions/permission-sync.ts.template +41 -0
  74. package/dist/pi-extensions/permissions-gate.ts.template +69 -0
  75. package/dist/pi-extensions/pr-fix-trigger.ts.template +124 -0
  76. package/dist/pi-extensions/review-reminder.ts.template +58 -0
  77. package/dist/pi-extensions/workspace-input-status.ts.template +919 -0
  78. package/dist/program.js +136 -0
  79. package/dist/scripts/workspace-table.py +394 -0
  80. package/dist/types/dashboard.js +11 -0
  81. package/dist/types/index.js +2 -0
  82. package/dist/utils/agent-config.js +263 -0
  83. package/dist/utils/agent-state.js +178 -0
  84. package/dist/utils/banner.js +24 -0
  85. package/dist/utils/branch-operations.js +232 -0
  86. package/dist/utils/bug-report.js +355 -0
  87. package/dist/utils/cache.js +168 -0
  88. package/dist/utils/claude-integration.js +617 -0
  89. package/dist/utils/claude-sessions.js +260 -0
  90. package/dist/utils/cleanup-operations.js +120 -0
  91. package/dist/utils/colors.js +26 -0
  92. package/dist/utils/command-helpers.js +44 -0
  93. package/dist/utils/config.js +150 -0
  94. package/dist/utils/context-file.js +33 -0
  95. package/dist/utils/dashboard-hooks.js +172 -0
  96. package/dist/utils/dependency-analyzer.js +234 -0
  97. package/dist/utils/diff-operations.js +80 -0
  98. package/dist/utils/doc-generator.js +184 -0
  99. package/dist/utils/ghq-integration.js +332 -0
  100. package/dist/utils/git-operations.js +237 -0
  101. package/dist/utils/git-status.js +187 -0
  102. package/dist/utils/github.js +68 -0
  103. package/dist/utils/health-checks.js +345 -0
  104. package/dist/utils/history.js +150 -0
  105. package/dist/utils/hooks.js +100 -0
  106. package/dist/utils/logger.js +40 -0
  107. package/dist/utils/permission-sync.js +681 -0
  108. package/dist/utils/pi-extensions.js +224 -0
  109. package/dist/utils/progress.js +92 -0
  110. package/dist/utils/prompts.js +279 -0
  111. package/dist/utils/repo-resolver.js +260 -0
  112. package/dist/utils/retry.js +65 -0
  113. package/dist/utils/run-operations.js +30 -0
  114. package/dist/utils/suite.js +159 -0
  115. package/dist/utils/sync-operations.js +107 -0
  116. package/dist/utils/tmux-dashboard.js +184 -0
  117. package/dist/utils/validation.js +153 -0
  118. package/dist/utils/version-check.js +121 -0
  119. package/dist/utils/workspace-meta.js +185 -0
  120. package/install-shell-integration.sh +532 -0
  121. package/install.sh +401 -0
  122. package/package.json +90 -0
  123. package/remove-shell-block.awk +44 -0
  124. package/scripts/postinstall.js +85 -0
  125. package/skills/analyze-deps.md +23 -0
  126. package/skills/archive-workspace.md +26 -0
  127. package/skills/branch-create.md +18 -0
  128. package/skills/create-workspace.md +39 -0
  129. package/skills/delete-workspace.md +37 -0
  130. package/skills/list-org-repos.md +26 -0
  131. package/skills/list-suites.md +24 -0
  132. package/skills/list-workspaces.md +27 -0
  133. package/skills/refresh-workspace-docs.md +89 -0
  134. package/skills/remove-repo.md +25 -0
  135. package/skills/run-command.md +23 -0
  136. package/skills/save-context.md +68 -0
  137. package/skills/search-repos.md +31 -0
  138. package/skills/snapshot-list.md +18 -0
  139. package/skills/snapshot-save.md +12 -0
  140. package/skills/switch-branch.md +18 -0
  141. package/skills/update-cache.md +21 -0
  142. package/skills/update-workspace.md +66 -0
  143. package/skills/workspace-cleanup.md +18 -0
  144. package/skills/workspace-diff.md +23 -0
  145. package/skills/workspace-doctor.md +23 -0
  146. package/skills/workspace-info.md +45 -0
  147. package/skills/workspace-manager/SKILL.md +201 -0
  148. package/skills/workspace-manager/references/ai-prompt.md +44 -0
  149. package/skills/workspace-manager/references/analyze-deps.md +45 -0
  150. package/skills/workspace-manager/references/archive-workspace.md +38 -0
  151. package/skills/workspace-manager/references/branch-create.md +31 -0
  152. package/skills/workspace-manager/references/branch-merge.md +22 -0
  153. package/skills/workspace-manager/references/branch-rebase.md +22 -0
  154. package/skills/workspace-manager/references/cache-clear.md +18 -0
  155. package/skills/workspace-manager/references/cache-info.md +22 -0
  156. package/skills/workspace-manager/references/configure-claude.md +31 -0
  157. package/skills/workspace-manager/references/configure.md +35 -0
  158. package/skills/workspace-manager/references/create-workspace.md +45 -0
  159. package/skills/workspace-manager/references/dashboard.md +61 -0
  160. package/skills/workspace-manager/references/delete-workspace.md +33 -0
  161. package/skills/workspace-manager/references/generate-docs.md +36 -0
  162. package/skills/workspace-manager/references/ghq-status.md +28 -0
  163. package/skills/workspace-manager/references/go.md +33 -0
  164. package/skills/workspace-manager/references/history.md +41 -0
  165. package/skills/workspace-manager/references/list-org-repos.md +26 -0
  166. package/skills/workspace-manager/references/list-suites.md +21 -0
  167. package/skills/workspace-manager/references/list-workspaces.md +27 -0
  168. package/skills/workspace-manager/references/mcp.md +49 -0
  169. package/skills/workspace-manager/references/remove-repo.md +26 -0
  170. package/skills/workspace-manager/references/run-command.md +44 -0
  171. package/skills/workspace-manager/references/search-repos.md +24 -0
  172. package/skills/workspace-manager/references/sessions.md +27 -0
  173. package/skills/workspace-manager/references/suite-create.md +22 -0
  174. package/skills/workspace-manager/references/suite-delete.md +21 -0
  175. package/skills/workspace-manager/references/suite-export.md +19 -0
  176. package/skills/workspace-manager/references/suite-import.md +19 -0
  177. package/skills/workspace-manager/references/suite-use.md +27 -0
  178. package/skills/workspace-manager/references/switch-branch.md +25 -0
  179. package/skills/workspace-manager/references/update-cache.md +22 -0
  180. package/skills/workspace-manager/references/update-workspace.md +50 -0
  181. package/skills/workspace-manager/references/workspace-cleanup.md +33 -0
  182. package/skills/workspace-manager/references/workspace-diff.md +27 -0
  183. package/skills/workspace-manager/references/workspace-doctor.md +27 -0
  184. package/skills/workspace-manager/references/workspace-info.md +33 -0
  185. package/skills/workspace-manager/references/workspace-status.md +43 -0
  186. package/skills/workspace-manager/references/workspace-sync.md +26 -0
  187. package/skills/workspace-status.md +26 -0
  188. package/skills/workspace-sync.md +23 -0
  189. package/src/cli/ai-prompt.test.ts +667 -0
  190. package/src/cli/ai-prompt.ts +421 -0
  191. package/src/cli/dashboard/AgentList.tsx +44 -0
  192. package/src/cli/dashboard/DashboardSidebar.tsx +291 -0
  193. package/src/cli/dashboard/HelpFooter.tsx +22 -0
  194. package/src/cli/dashboard/StatusBadge.tsx +23 -0
  195. package/src/cli/dashboard/index.ts +5 -0
  196. package/src/cli/dashboard/types.ts +16 -0
  197. package/src/cli/tui.tsx +51 -0
  198. package/src/cli/workspace-cli.test.ts +30 -0
  199. package/src/commands/ai-prompt.ts +21 -0
  200. package/src/commands/analyze-deps.ts +119 -0
  201. package/src/commands/archive.ts +114 -0
  202. package/src/commands/branch/create.ts +94 -0
  203. package/src/commands/branch/index.ts +74 -0
  204. package/src/commands/branch/merge.ts +61 -0
  205. package/src/commands/branch/rebase.ts +54 -0
  206. package/src/commands/branch/switch.ts +150 -0
  207. package/src/commands/cache/index.ts +51 -0
  208. package/src/commands/cache/manager.ts +168 -0
  209. package/src/commands/cleanup.ts +132 -0
  210. package/src/commands/configure-claude.ts +55 -0
  211. package/src/commands/configure.ts +204 -0
  212. package/src/commands/create.ts +196 -0
  213. package/src/commands/dashboard/hook-handler.ts +138 -0
  214. package/src/commands/dashboard/index.ts +248 -0
  215. package/src/commands/dashboard/launcher.ts +42 -0
  216. package/src/commands/dashboard/session-picker.ts +73 -0
  217. package/src/commands/dashboard/sidebar.js +39 -0
  218. package/src/commands/dashboard/workspace-picker.ts +62 -0
  219. package/src/commands/delete.test.ts +250 -0
  220. package/src/commands/delete.ts +171 -0
  221. package/src/commands/deprecated-aliases.ts +55 -0
  222. package/src/commands/diff.ts +106 -0
  223. package/src/commands/doctor.ts +110 -0
  224. package/src/commands/generate-docs.ts +45 -0
  225. package/src/commands/ghq-status.ts +70 -0
  226. package/src/commands/go.ts +125 -0
  227. package/src/commands/history.ts +136 -0
  228. package/src/commands/list.test.ts +219 -0
  229. package/src/commands/list.ts +176 -0
  230. package/src/commands/mcp/index.ts +39 -0
  231. package/src/commands/migrate.ts +277 -0
  232. package/src/commands/remove-repo.ts +194 -0
  233. package/src/commands/report-bug.ts +88 -0
  234. package/src/commands/run.ts +125 -0
  235. package/src/commands/save-context.test.ts +113 -0
  236. package/src/commands/save-context.ts +141 -0
  237. package/src/commands/sessions.ts +99 -0
  238. package/src/commands/status.ts +111 -0
  239. package/src/commands/suite/create.ts +240 -0
  240. package/src/commands/suite/delete.ts +65 -0
  241. package/src/commands/suite/export.ts +97 -0
  242. package/src/commands/suite/import.ts +100 -0
  243. package/src/commands/suite/index.ts +66 -0
  244. package/src/commands/suite/list.ts +54 -0
  245. package/src/commands/suite/use.ts +232 -0
  246. package/src/commands/sync.ts +97 -0
  247. package/src/commands/update.ts +197 -0
  248. package/src/mcp/install.ts +529 -0
  249. package/src/mcp/server.ts +579 -0
  250. package/src/mcp/tools.test.ts +545 -0
  251. package/src/mcp/tools.ts +1019 -0
  252. package/src/mcp/update-workspace.test.ts +220 -0
  253. package/src/pi-extensions/permission-sync.ts.template +41 -0
  254. package/src/pi-extensions/permissions-gate.ts.template +69 -0
  255. package/src/pi-extensions/pr-fix-trigger.ts.template +124 -0
  256. package/src/pi-extensions/review-reminder.ts.template +58 -0
  257. package/src/pi-extensions/workspace-input-status.ts.template +919 -0
  258. package/src/program.ts +112 -0
  259. package/src/scripts/workspace-table.py +394 -0
  260. package/src/types/dashboard.ts +29 -0
  261. package/src/types/index.ts +109 -0
  262. package/src/types/ink.d.ts +171 -0
  263. package/src/utils/agent-config.test.ts +303 -0
  264. package/src/utils/agent-config.ts +264 -0
  265. package/src/utils/agent-state.test.ts +166 -0
  266. package/src/utils/agent-state.ts +135 -0
  267. package/src/utils/banner.ts +24 -0
  268. package/src/utils/branch-operations.ts +237 -0
  269. package/src/utils/bug-report.test.ts +174 -0
  270. package/src/utils/bug-report.ts +355 -0
  271. package/src/utils/cache.ts +150 -0
  272. package/src/utils/claude-integration.test.ts +381 -0
  273. package/src/utils/claude-integration.ts +649 -0
  274. package/src/utils/claude-sessions.test.ts +262 -0
  275. package/src/utils/claude-sessions.ts +251 -0
  276. package/src/utils/cleanup-operations.ts +94 -0
  277. package/src/utils/colors.ts +25 -0
  278. package/src/utils/command-helpers.ts +46 -0
  279. package/src/utils/config.test.ts +203 -0
  280. package/src/utils/config.ts +133 -0
  281. package/src/utils/context-file.ts +36 -0
  282. package/src/utils/dashboard-hooks.test.ts +168 -0
  283. package/src/utils/dashboard-hooks.ts +163 -0
  284. package/src/utils/dependency-analyzer.ts +243 -0
  285. package/src/utils/diff-operations.ts +59 -0
  286. package/src/utils/doc-generator.ts +187 -0
  287. package/src/utils/ghq-integration.test.ts +195 -0
  288. package/src/utils/ghq-integration.ts +317 -0
  289. package/src/utils/git-operations.test.ts +265 -0
  290. package/src/utils/git-operations.ts +233 -0
  291. package/src/utils/git-status.ts +171 -0
  292. package/src/utils/github.ts +74 -0
  293. package/src/utils/health-checks.ts +359 -0
  294. package/src/utils/history.ts +140 -0
  295. package/src/utils/hooks.ts +92 -0
  296. package/src/utils/logger.ts +37 -0
  297. package/src/utils/permission-sync.test.ts +593 -0
  298. package/src/utils/permission-sync.ts +720 -0
  299. package/src/utils/pi-extensions.test.ts +182 -0
  300. package/src/utils/pi-extensions.ts +226 -0
  301. package/src/utils/progress.ts +73 -0
  302. package/src/utils/prompts.test.ts +169 -0
  303. package/src/utils/prompts.ts +296 -0
  304. package/src/utils/repo-resolver.test.ts +313 -0
  305. package/src/utils/repo-resolver.ts +294 -0
  306. package/src/utils/retry.test.ts +124 -0
  307. package/src/utils/retry.ts +85 -0
  308. package/src/utils/run-operations.ts +38 -0
  309. package/src/utils/suite.test.ts +256 -0
  310. package/src/utils/suite.ts +144 -0
  311. package/src/utils/sync-operations.ts +87 -0
  312. package/src/utils/tmux-dashboard.ts +193 -0
  313. package/src/utils/validation.test.ts +139 -0
  314. package/src/utils/validation.ts +128 -0
  315. package/src/utils/version-check.test.ts +108 -0
  316. package/src/utils/version-check.ts +96 -0
  317. package/src/utils/workspace-meta.ts +173 -0
  318. package/sync-permissions.sh +137 -0
  319. package/tsconfig.json +20 -0
  320. package/uninstall.sh +162 -0
@@ -0,0 +1,280 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DashboardSidebar = void 0;
37
+ const React = __importStar(require("react"));
38
+ const child_process_1 = require("child_process");
39
+ const path = __importStar(require("path"));
40
+ const agent_state_1 = require("../../utils/agent-state");
41
+ const dashboard_1 = require("../../types/dashboard");
42
+ const AgentList_1 = require("./AgentList");
43
+ const HelpFooter_1 = require("./HelpFooter");
44
+ const tmux_dashboard_1 = require("../../utils/tmux-dashboard");
45
+ const { sessionName, pollIntervalMs } = dashboard_1.DASHBOARD_DEFAULTS;
46
+ const DashboardSidebar = ({ Box, Text, useInput, useApp }) => {
47
+ const [agents, setAgents] = React.useState([]);
48
+ const [selectedIndex, setSelectedIndex] = React.useState(0);
49
+ const [isZoomed, setIsZoomed] = React.useState(false);
50
+ const { exit } = useApp();
51
+ // Refs for always-current values inside the useInput closure
52
+ const agentsRef = React.useRef([]);
53
+ const selectedIndexRef = React.useRef(0);
54
+ const isZoomedRef = React.useRef(false);
55
+ // Store original pane PID order before zoom so we can restore it
56
+ const originalPaneOrderRef = React.useRef([]);
57
+ // Poll agent states every 2s
58
+ React.useEffect(() => {
59
+ function refresh() {
60
+ const visiblePanes = (0, tmux_dashboard_1.getAgentPanes)();
61
+ const hiddenPanes = (0, tmux_dashboard_1.getHiddenPanes)();
62
+ const allPanes = [...visiblePanes, ...hiddenPanes];
63
+ const panePids = new Set(allPanes.map(p => p.pid));
64
+ const allStates = (0, agent_state_1.readAllAgentStates)().filter(s => {
65
+ if (s.status === 'stopped')
66
+ return false;
67
+ return panePids.has(s.pid);
68
+ });
69
+ // When zoomed, sort by the original pane order so the sidebar
70
+ // display stays stable (zoomed pane doesn't jump to the top)
71
+ const originalOrder = originalPaneOrderRef.current;
72
+ let sorted;
73
+ if (originalOrder.length > 0) {
74
+ sorted = (0, tmux_dashboard_1.sortAgentsByPidOrder)(allStates, originalOrder);
75
+ }
76
+ else {
77
+ sorted = (0, tmux_dashboard_1.sortAgentsByPaneOrder)(allStates, allPanes);
78
+ }
79
+ agentsRef.current = sorted;
80
+ setAgents(sorted);
81
+ }
82
+ refresh();
83
+ const timer = setInterval(refresh, pollIntervalMs);
84
+ return () => clearInterval(timer);
85
+ }, []);
86
+ // Keep selectedIndex ref in sync
87
+ React.useEffect(() => {
88
+ selectedIndexRef.current = selectedIndex;
89
+ }, [selectedIndex]);
90
+ // Keep isZoomed ref in sync
91
+ React.useEffect(() => {
92
+ isZoomedRef.current = isZoomed;
93
+ }, [isZoomed]);
94
+ // Clamp selection — handles both too-high and negative values
95
+ const clampedIndex = Math.min(Math.max(selectedIndex, 0), Math.max(0, agents.length - 1));
96
+ if (clampedIndex !== selectedIndex) {
97
+ setSelectedIndex(clampedIndex);
98
+ selectedIndexRef.current = clampedIndex;
99
+ }
100
+ /**
101
+ * Apply zoom to a specific agent index.
102
+ */
103
+ function applyZoom(agentIndex) {
104
+ const currentAgents = agentsRef.current;
105
+ if (agentIndex >= currentAgents.length)
106
+ return;
107
+ if (isZoomedRef.current) {
108
+ // Already zoomed — restore panes in original order, then re-zoom
109
+ (0, tmux_dashboard_1.restoreHiddenPanes)(originalPaneOrderRef.current);
110
+ }
111
+ else {
112
+ // First zoom — capture the current pane order before hiding anything
113
+ const panes = (0, tmux_dashboard_1.getAgentPanes)();
114
+ originalPaneOrderRef.current = panes.map(p => p.pid);
115
+ (0, tmux_dashboard_1.restoreHiddenPanes)(); // no-op if nothing hidden
116
+ }
117
+ (0, child_process_1.spawnSync)('tmux', ['select-layout', '-t', sessionName, 'main-vertical'], { stdio: 'pipe' });
118
+ (0, child_process_1.spawnSync)('tmux', ['resize-pane', '-t', `${sessionName}:0.0`, '-x', '32'], { stdio: 'pipe' });
119
+ const panes = (0, tmux_dashboard_1.getAgentPanes)();
120
+ const pane = (0, tmux_dashboard_1.findPaneForAgent)(currentAgents[agentIndex], panes);
121
+ if (pane) {
122
+ (0, tmux_dashboard_1.zoomPane)(pane);
123
+ setIsZoomed(true);
124
+ isZoomedRef.current = true;
125
+ }
126
+ }
127
+ /**
128
+ * Unzoom and reset layout, restoring original pane order.
129
+ */
130
+ function unzoom() {
131
+ (0, tmux_dashboard_1.restoreHiddenPanes)(originalPaneOrderRef.current);
132
+ originalPaneOrderRef.current = [];
133
+ (0, child_process_1.spawnSync)('tmux', ['select-layout', '-t', sessionName, 'main-vertical'], { stdio: 'pipe' });
134
+ (0, child_process_1.spawnSync)('tmux', ['resize-pane', '-t', `${sessionName}:0.0`, '-x', '32'], { stdio: 'pipe' });
135
+ (0, child_process_1.spawnSync)('tmux', ['select-pane', '-t', `${sessionName}:0.0`], { stdio: 'pipe' });
136
+ setIsZoomed(false);
137
+ isZoomedRef.current = false;
138
+ }
139
+ // Keyboard handling — reads from refs for always-current data
140
+ useInput((input, key) => {
141
+ const currentAgents = agentsRef.current;
142
+ const currentIdx = selectedIndexRef.current;
143
+ const currentZoomed = isZoomedRef.current;
144
+ const clampedIdx = Math.min(Math.max(currentIdx, 0), Math.max(0, currentAgents.length - 1));
145
+ // q — detach (session stays running in background, agents keep working)
146
+ if (input === 'q') {
147
+ (0, tmux_dashboard_1.restoreHiddenPanes)();
148
+ (0, child_process_1.spawnSync)('tmux', ['detach-client', '-s', sessionName], { stdio: 'pipe' });
149
+ // Do NOT call exit() — the sidebar process must keep running so
150
+ // the session is alive when the user re-attaches with 'w dash'
151
+ return;
152
+ }
153
+ // Q (shift+q) — kill session and all agents
154
+ if (input === 'Q') {
155
+ (0, tmux_dashboard_1.restoreHiddenPanes)();
156
+ (0, child_process_1.spawnSync)('tmux', ['kill-session', '-t', sessionName], { stdio: 'pipe' });
157
+ exit();
158
+ return;
159
+ }
160
+ // Navigation
161
+ if (key.upArrow || input === 'K') {
162
+ const next = Math.max(0, clampedIdx - 1);
163
+ setSelectedIndex(next);
164
+ selectedIndexRef.current = next;
165
+ return;
166
+ }
167
+ if (key.downArrow || input === 'J') {
168
+ const next = Math.max(0, Math.min(currentAgents.length - 1, clampedIdx + 1));
169
+ setSelectedIndex(next);
170
+ selectedIndexRef.current = next;
171
+ return;
172
+ }
173
+ // Number keys 1-9
174
+ if (input >= '1' && input <= '9') {
175
+ const idx = parseInt(input, 10) - 1;
176
+ if (idx < currentAgents.length) {
177
+ setSelectedIndex(idx);
178
+ selectedIndexRef.current = idx;
179
+ }
180
+ return;
181
+ }
182
+ // Focus — switch to agent pane
183
+ if (input === 'f' || key.return) {
184
+ if (clampedIdx < currentAgents.length) {
185
+ if (currentZoomed) {
186
+ applyZoom(clampedIdx);
187
+ const panes = (0, tmux_dashboard_1.getAgentPanes)();
188
+ const pane = (0, tmux_dashboard_1.findPaneForAgent)(currentAgents[clampedIdx], panes);
189
+ if (pane) {
190
+ (0, child_process_1.spawnSync)('tmux', ['select-pane', '-t', `${sessionName}:0.${pane.index}`], { stdio: 'pipe' });
191
+ }
192
+ }
193
+ else {
194
+ const panes = (0, tmux_dashboard_1.getAgentPanes)();
195
+ const pane = (0, tmux_dashboard_1.findPaneForAgent)(currentAgents[clampedIdx], panes);
196
+ if (pane) {
197
+ (0, child_process_1.spawnSync)('tmux', ['select-pane', '-t', `${sessionName}:0.${pane.index}`], { stdio: 'pipe' });
198
+ }
199
+ }
200
+ }
201
+ return;
202
+ }
203
+ // Zoom toggle
204
+ if (input === 'z') {
205
+ if (currentZoomed) {
206
+ unzoom();
207
+ isZoomedRef.current = false;
208
+ }
209
+ else {
210
+ applyZoom(clampedIdx);
211
+ }
212
+ return;
213
+ }
214
+ // Reset layout
215
+ if (input === 'r') {
216
+ unzoom();
217
+ isZoomedRef.current = false;
218
+ return;
219
+ }
220
+ // New agent
221
+ if (input === 'n') {
222
+ if (currentZoomed) {
223
+ unzoom();
224
+ isZoomedRef.current = false;
225
+ }
226
+ const pickerScript = path.join(__dirname, '..', '..', 'commands', 'dashboard', 'workspace-picker.js');
227
+ const popupResult = (0, child_process_1.spawnSync)('tmux', [
228
+ 'display-popup', '-E', '-w', '60%', '-h', '60%',
229
+ '-t', sessionName,
230
+ `node "${pickerScript}"`,
231
+ ], { stdio: 'pipe' });
232
+ if (popupResult.status !== 0) {
233
+ (0, child_process_1.spawnSync)('tmux', ['split-window', '-t', sessionName, '-v', `node "${pickerScript}"`], { stdio: 'pipe' });
234
+ }
235
+ setTimeout(() => (0, tmux_dashboard_1.resetLayout)(), 500);
236
+ return;
237
+ }
238
+ // Resume session
239
+ if (input === 's') {
240
+ if (currentZoomed) {
241
+ unzoom();
242
+ isZoomedRef.current = false;
243
+ }
244
+ const sessionPickerScript = path.join(__dirname, '..', '..', 'commands', 'dashboard', 'session-picker.js');
245
+ const popupResult = (0, child_process_1.spawnSync)('tmux', [
246
+ 'display-popup', '-E', '-w', '60%', '-h', '60%',
247
+ '-t', sessionName,
248
+ `node "${sessionPickerScript}"`,
249
+ ], { stdio: 'pipe' });
250
+ if (popupResult.status !== 0) {
251
+ (0, child_process_1.spawnSync)('tmux', ['split-window', '-t', sessionName, '-v', `node "${sessionPickerScript}"`], { stdio: 'pipe' });
252
+ }
253
+ setTimeout(() => (0, tmux_dashboard_1.resetLayout)(), 500);
254
+ return;
255
+ }
256
+ // Kill / close session
257
+ if (input === 'x') {
258
+ if (clampedIdx < currentAgents.length) {
259
+ if (currentZoomed) {
260
+ unzoom();
261
+ isZoomedRef.current = false;
262
+ }
263
+ const panes = (0, tmux_dashboard_1.getAgentPanes)();
264
+ const pane = (0, tmux_dashboard_1.findPaneForAgent)(currentAgents[clampedIdx], panes);
265
+ if (pane) {
266
+ (0, child_process_1.spawnSync)('tmux', ['kill-pane', '-t', `${sessionName}:0.${pane.index}`], { stdio: 'pipe' });
267
+ setTimeout(() => (0, tmux_dashboard_1.resetLayout)(), 100);
268
+ }
269
+ }
270
+ return;
271
+ }
272
+ });
273
+ return (React.createElement(Box, { flexDirection: "column" },
274
+ React.createElement(Box, { marginBottom: 1 },
275
+ React.createElement(Text, { bold: true, color: "cyan" }, '─ Agent Dashboard ─'),
276
+ isZoomed && React.createElement(Text, { color: "yellow" }, " [ZOOM]")),
277
+ React.createElement(AgentList_1.AgentList, { agents: agents, selectedIndex: clampedIndex, onSelect: setSelectedIndex, Box: Box, Text: Text }),
278
+ React.createElement(HelpFooter_1.HelpFooter, { isZoomed: isZoomed, Box: Box, Text: Text })));
279
+ };
280
+ exports.DashboardSidebar = DashboardSidebar;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.HelpFooter = void 0;
37
+ const React = __importStar(require("react"));
38
+ const HelpFooter = ({ isZoomed, Box, Text }) => {
39
+ return (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
40
+ React.createElement(Text, { dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),
41
+ React.createElement(Text, null,
42
+ React.createElement(Text, { color: "yellow" }, "\u2191\u2193"),
43
+ " select ",
44
+ React.createElement(Text, { color: "yellow" }, "f"),
45
+ "/\u23CE focus"),
46
+ React.createElement(Text, null,
47
+ React.createElement(Text, { color: "yellow" }, "z"),
48
+ " ",
49
+ isZoomed ? 'unzoom' : 'zoom',
50
+ " ",
51
+ React.createElement(Text, { color: "yellow" }, "x"),
52
+ " kill"),
53
+ React.createElement(Text, null,
54
+ React.createElement(Text, { color: "yellow" }, "n"),
55
+ " new ",
56
+ React.createElement(Text, { color: "yellow" }, "q"),
57
+ " detach"),
58
+ React.createElement(Text, null,
59
+ React.createElement(Text, { color: "yellow" }, "s"),
60
+ " resume ",
61
+ React.createElement(Text, { color: "yellow" }, "Q"),
62
+ " quit all"),
63
+ React.createElement(Text, null,
64
+ React.createElement(Text, { color: "yellow" }, "r"),
65
+ " reset layout"),
66
+ React.createElement(Text, { dimColor: true }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),
67
+ React.createElement(Text, { dimColor: true }, "From agent pane:"),
68
+ React.createElement(Text, null,
69
+ " ",
70
+ React.createElement(Text, { color: "yellow" }, "prefix+M"),
71
+ " sidebar/reset")));
72
+ };
73
+ exports.HelpFooter = HelpFooter;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.StatusBadge = void 0;
37
+ const React = __importStar(require("react"));
38
+ const STATUS_CONFIG = {
39
+ working: { icon: '●', color: 'green', label: 'working' },
40
+ waiting: { icon: '●', color: 'yellow', label: 'approve' },
41
+ idle: { icon: '◌', color: 'gray', label: 'idle' },
42
+ stopped: { icon: '✕', color: 'red', label: 'stopped' },
43
+ };
44
+ const StatusBadge = ({ status, Box, Text }) => {
45
+ const config = STATUS_CONFIG[status] || STATUS_CONFIG.idle;
46
+ return (React.createElement(Box, { gap: 1 },
47
+ React.createElement(Text, { color: config.color }, config.icon),
48
+ React.createElement(Text, { color: config.color }, config.label)));
49
+ };
50
+ exports.StatusBadge = StatusBadge;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HelpFooter = exports.StatusBadge = exports.AgentList = exports.DashboardSidebar = void 0;
4
+ var DashboardSidebar_1 = require("./DashboardSidebar");
5
+ Object.defineProperty(exports, "DashboardSidebar", { enumerable: true, get: function () { return DashboardSidebar_1.DashboardSidebar; } });
6
+ var AgentList_1 = require("./AgentList");
7
+ Object.defineProperty(exports, "AgentList", { enumerable: true, get: function () { return AgentList_1.AgentList; } });
8
+ var StatusBadge_1 = require("./StatusBadge");
9
+ Object.defineProperty(exports, "StatusBadge", { enumerable: true, get: function () { return StatusBadge_1.StatusBadge; } });
10
+ var HelpFooter_1 = require("./HelpFooter");
11
+ Object.defineProperty(exports, "HelpFooter", { enumerable: true, get: function () { return HelpFooter_1.HelpFooter; } });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ // TUI implementation - simplified version without ink for now
4
+ // Full ink-based implementation can be added after dependencies are installed
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.main = void 0;
7
+ const workspace_meta_1 = require("../utils/workspace-meta");
8
+ const logger_1 = require("../utils/logger");
9
+ const colors_1 = require("../utils/colors");
10
+ const main = async () => {
11
+ try {
12
+ (0, logger_1.logInfo)('Interactive TUI mode');
13
+ console.log((0, colors_1.colorize)('\n╔══════════════════════════════════════════╗', 'cyan'));
14
+ console.log((0, colors_1.colorize)('║ Workspace Manager - Interactive UI ║', 'cyan'));
15
+ console.log((0, colors_1.colorize)('╚══════════════════════════════════════════╝\n', 'cyan'));
16
+ const workspaces = await (0, workspace_meta_1.listWorkspaces)();
17
+ if (workspaces.length === 0) {
18
+ (0, logger_1.logError)('No workspaces found');
19
+ console.log((0, colors_1.colorize)('Create a workspace with: workspace create', 'gray'));
20
+ process.exit(1);
21
+ }
22
+ console.log((0, colors_1.colorize)('Available Workspaces:', 'bright'));
23
+ for (let i = 0; i < workspaces.length; i++) {
24
+ const ws = workspaces[i];
25
+ const repoCount = ws.metadata?.repositories.length || 0;
26
+ console.log(` ${i + 1}. ${(0, colors_1.colorize)(ws.name, 'cyan')} (${repoCount} repos)`);
27
+ }
28
+ console.log('\n' + (0, colors_1.colorize)('Commands:', 'bright'));
29
+ console.log(' workspace status <name> - Check git status');
30
+ console.log(' workspace doctor <name> - Run health checks');
31
+ console.log(' workspace sync <name> - Pull latest changes');
32
+ console.log(' wgo <name> - Navigate to workspace');
33
+ console.log('');
34
+ (0, logger_1.logInfo)('Full interactive TUI with ink will be available after running: npm install');
35
+ }
36
+ catch (error) {
37
+ (0, logger_1.logError)('TUI failed');
38
+ if (error instanceof Error) {
39
+ (0, logger_1.logError)(error.message);
40
+ }
41
+ process.exit(1);
42
+ }
43
+ };
44
+ exports.main = main;
45
+ // Auto-execute only when run directly (not when imported by Commander)
46
+ if (require.main === module) {
47
+ (0, exports.main)();
48
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleAiPrompt = handleAiPrompt;
4
+ const logger_1 = require("../utils/logger");
5
+ const colors_1 = require("../utils/colors");
6
+ const ai_prompt_1 = require("../cli/ai-prompt");
7
+ /**
8
+ * Handle the `nemus -- <prompt>` command.
9
+ * This is called directly from bin/workspace.js before Commander parses,
10
+ * because Commander treats `--` as end-of-options.
11
+ */
12
+ async function handleAiPrompt(prompt) {
13
+ if (!prompt || !prompt.trim()) {
14
+ (0, logger_1.logError)('No prompt provided');
15
+ console.log(`\n Usage: ${(0, colors_1.colorize)('nemus -- <prompt>', 'green')}`);
16
+ console.log(` Example: ${(0, colors_1.colorize)('nemus -- create a workspace for the payments team', 'gray')}\n`);
17
+ process.exit(1);
18
+ return;
19
+ }
20
+ const exitCode = await (0, ai_prompt_1.run)(prompt.trim());
21
+ process.exit(exitCode);
22
+ }
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.registerAnalyzeDepsCommand = registerAnalyzeDepsCommand;
40
+ const path = __importStar(require("path"));
41
+ const config_1 = require("../utils/config");
42
+ const workspace_meta_1 = require("../utils/workspace-meta");
43
+ const dependency_analyzer_1 = require("../utils/dependency-analyzer");
44
+ const logger_1 = require("../utils/logger");
45
+ const colors_1 = require("../utils/colors");
46
+ const inquirer_1 = __importDefault(require("inquirer"));
47
+ const command_helpers_1 = require("../utils/command-helpers");
48
+ const displayDependencyAnalysis = (analyses) => {
49
+ console.log('\n' + (0, colors_1.colorize)('Dependency Analysis', 'bright'));
50
+ console.log((0, colors_1.colorize)('═'.repeat(100), 'gray'));
51
+ for (const [repoName, analysis] of analyses) {
52
+ console.log(`\n${(0, colors_1.colorize)(repoName, 'cyan')}`);
53
+ if (analysis.dependencies.length > 0) {
54
+ console.log(` ${(0, colors_1.colorize)('Depends on:', 'gray')} ${analysis.dependencies.join(', ')}`);
55
+ }
56
+ if (analysis.dependents.length > 0) {
57
+ console.log(` ${(0, colors_1.colorize)('Depended by:', 'gray')} ${analysis.dependents.join(', ')}`);
58
+ }
59
+ if (analysis.missingDependencies.length > 0) {
60
+ console.log(` ${(0, colors_1.colorize)('⚠ Missing deps:', 'yellow')} ${analysis.missingDependencies.join(', ')}`);
61
+ }
62
+ if (analysis.dependencies.length === 0 && analysis.dependents.length === 0 && analysis.missingDependencies.length === 0) {
63
+ console.log(` ${(0, colors_1.colorize)('No dependencies detected', 'gray')}`);
64
+ }
65
+ }
66
+ console.log('\n' + (0, colors_1.colorize)('═'.repeat(100), 'gray'));
67
+ };
68
+ function registerAnalyzeDepsCommand(parent) {
69
+ parent
70
+ .command('analyze-deps')
71
+ .alias('ad')
72
+ .description('Analyze inter-repo dependencies')
73
+ .argument('[workspace]', 'Workspace name')
74
+ .action(async (workspace) => {
75
+ await handleAnalyzeDeps(workspace);
76
+ });
77
+ }
78
+ async function handleAnalyzeDeps(workspaceArg) {
79
+ try {
80
+ const selectedWorkspace = await (0, command_helpers_1.resolveWorkspace)(workspaceArg);
81
+ const workspacePath = path.join(config_1.WORKSPACES_DIR, selectedWorkspace);
82
+ const metadata = await (0, workspace_meta_1.loadMetadata)(workspacePath);
83
+ if (!metadata) {
84
+ (0, logger_1.logError)(`Workspace metadata not found for: ${selectedWorkspace}`);
85
+ process.exit(1);
86
+ }
87
+ (0, logger_1.logStep)(`Analyzing dependencies for workspace: ${(0, colors_1.colorize)(selectedWorkspace, 'cyan')}`);
88
+ (0, logger_1.logInfo)('Scanning package.json, Dockerfile, and docker-compose.yml files...');
89
+ const repoNames = metadata.repositories.map(r => r.name);
90
+ const analyses = await (0, dependency_analyzer_1.analyzeDependencies)(workspacePath, repoNames);
91
+ displayDependencyAnalysis(analyses);
92
+ const cycles = (0, dependency_analyzer_1.detectCircularDependencies)(analyses);
93
+ if (cycles.length > 0) {
94
+ console.log('\n' + (0, colors_1.colorize)('⚠ Circular Dependencies Detected:', 'yellow'));
95
+ for (const cycle of cycles) {
96
+ console.log(` ${cycle.join(' → ')}`);
97
+ }
98
+ }
99
+ const diagram = (0, dependency_analyzer_1.generateMermaidDiagram)(analyses);
100
+ console.log('\n' + (0, colors_1.colorize)('Dependency Graph (Mermaid):', 'bright'));
101
+ console.log(diagram);
102
+ const missingDeps = new Set();
103
+ for (const [, analysis] of analyses) {
104
+ for (const dep of analysis.missingDependencies) {
105
+ missingDeps.add(dep);
106
+ }
107
+ }
108
+ if (missingDeps.size > 0) {
109
+ console.log('\n' + (0, colors_1.colorize)('💡 Suggested Missing Repositories:', 'yellow'));
110
+ for (const dep of missingDeps) {
111
+ console.log(` • ${dep}`);
112
+ }
113
+ (0, logger_1.logInfo)(`Consider adding these repositories with: workspace update ${selectedWorkspace}`);
114
+ }
115
+ if (process.stdout.isTTY) {
116
+ const { saveToMetadata } = await inquirer_1.default.prompt([
117
+ {
118
+ type: 'confirm',
119
+ name: 'saveToMetadata',
120
+ message: 'Save dependency analysis to workspace metadata?',
121
+ default: true,
122
+ },
123
+ ]);
124
+ if (saveToMetadata) {
125
+ const updatedMetadata = (0, dependency_analyzer_1.updateWorkspaceMetadata)(metadata, analyses);
126
+ await (0, workspace_meta_1.saveMetadata)(workspacePath, updatedMetadata);
127
+ (0, logger_1.logSuccess)('Dependency analysis saved to metadata');
128
+ }
129
+ }
130
+ }
131
+ catch (error) {
132
+ (0, logger_1.logError)('Failed to analyze dependencies');
133
+ if (error instanceof Error) {
134
+ (0, logger_1.logError)(error.message);
135
+ }
136
+ process.exit(1);
137
+ }
138
+ }