@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,147 @@
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.registerRunCommand = registerRunCommand;
37
+ const path = __importStar(require("path"));
38
+ const config_1 = require("../utils/config");
39
+ const workspace_meta_1 = require("../utils/workspace-meta");
40
+ const logger_1 = require("../utils/logger");
41
+ const colors_1 = require("../utils/colors");
42
+ const command_helpers_1 = require("../utils/command-helpers");
43
+ const run_operations_1 = require("../utils/run-operations");
44
+ const CONCURRENCY_LIMIT = 3;
45
+ function registerRunCommand(parent) {
46
+ parent
47
+ .command('run')
48
+ .alias('r')
49
+ .description('Run command across all repos')
50
+ .argument('[workspace]', 'Workspace name')
51
+ .argument('[command...]', 'Command to run (use quotes for flags: "git status -s")')
52
+ .allowUnknownOption()
53
+ .allowExcessArguments()
54
+ .action(async (workspace, commandParts) => {
55
+ // Commander parses positional args correctly even with allowUnknownOption.
56
+ // workspace = first positional, commandParts = rest as array.
57
+ // Unknown options (like -s in "git status -s") end up in commandParts too.
58
+ if (!workspace && (!commandParts || commandParts.length === 0)) {
59
+ // No args at all
60
+ await handleRun(undefined, []);
61
+ }
62
+ else if (!commandParts || commandParts.length === 0) {
63
+ // Single arg: treat as command, prompt for workspace
64
+ await handleRun(undefined, [workspace]);
65
+ }
66
+ else {
67
+ // First arg is workspace, rest is command
68
+ await handleRun(workspace, commandParts);
69
+ }
70
+ });
71
+ }
72
+ async function handleRun(workspaceArg, commandParts) {
73
+ try {
74
+ let workspaceName;
75
+ let command;
76
+ if (!commandParts || commandParts.length === 0) {
77
+ if (!workspaceArg) {
78
+ (0, logger_1.logError)('Usage: w run [workspace-name] "<command>"');
79
+ process.exit(1);
80
+ }
81
+ // Only one arg: treat as command, prompt for workspace
82
+ command = workspaceArg;
83
+ workspaceName = await (0, command_helpers_1.resolveWorkspace)();
84
+ }
85
+ else if (!workspaceArg) {
86
+ // commandParts provided but no workspace — treat first part as command
87
+ command = commandParts.join(' ');
88
+ workspaceName = await (0, command_helpers_1.resolveWorkspace)();
89
+ }
90
+ else {
91
+ // Both workspace and command provided
92
+ workspaceName = workspaceArg;
93
+ command = commandParts.join(' ');
94
+ }
95
+ const workspacePath = path.join(config_1.WORKSPACES_DIR, workspaceName);
96
+ const metadata = await (0, workspace_meta_1.loadMetadata)(workspacePath);
97
+ if (!metadata) {
98
+ (0, logger_1.logError)(`Workspace metadata not found for: ${workspaceName}`);
99
+ process.exit(1);
100
+ }
101
+ const repos = metadata.repositories.filter(r => r.status === 'success');
102
+ console.log('\n' + (0, colors_1.colorize)('Run Command Across Workspace', 'bright'));
103
+ console.log(`Workspace: ${(0, colors_1.colorize)(workspaceName, 'cyan')}`);
104
+ console.log(`Command: ${(0, colors_1.colorize)(command, 'yellow')}`);
105
+ console.log(`Repos: ${repos.length}\n`);
106
+ const results = [];
107
+ for (let i = 0; i < repos.length; i += CONCURRENCY_LIMIT) {
108
+ const chunk = repos.slice(i, i + CONCURRENCY_LIMIT);
109
+ const chunkResults = await Promise.all(chunk.map(repo => {
110
+ const repoPath = path.join(workspacePath, repo.directoryName);
111
+ const displayName = repo.directoryName !== repo.name
112
+ ? `${repo.directoryName} (${repo.name})`
113
+ : repo.name;
114
+ return (0, run_operations_1.runInRepo)(repoPath, displayName, command);
115
+ }));
116
+ results.push(...chunkResults);
117
+ }
118
+ console.log((0, colors_1.colorize)('═'.repeat(60), 'gray'));
119
+ for (const result of results) {
120
+ const icon = result.status === 'success'
121
+ ? (0, colors_1.colorize)('✓', 'green')
122
+ : (0, colors_1.colorize)('✗', 'red');
123
+ console.log(`\n${icon} ${(0, colors_1.colorize)(result.repo, 'cyan')}`);
124
+ if (result.stdout) {
125
+ console.log(result.stdout);
126
+ }
127
+ if (result.stderr) {
128
+ console.log((0, colors_1.colorize)(result.stderr, 'yellow'));
129
+ }
130
+ }
131
+ const successful = results.filter(r => r.status === 'success').length;
132
+ const failed = results.filter(r => r.status === 'failed').length;
133
+ console.log('\n' + (0, colors_1.colorize)('═'.repeat(60), 'gray'));
134
+ console.log(`${(0, colors_1.colorize)('✓', 'green')} ${successful} successful, ${(0, colors_1.colorize)('✗', 'red')} ${failed} failed`);
135
+ console.log('');
136
+ if (failed > 0) {
137
+ process.exit(1);
138
+ }
139
+ }
140
+ catch (error) {
141
+ (0, logger_1.logError)('Failed to run command');
142
+ if (error instanceof Error) {
143
+ (0, logger_1.logError)(error.message);
144
+ }
145
+ process.exit(1);
146
+ }
147
+ }
@@ -0,0 +1,171 @@
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.registerSaveContextCommand = registerSaveContextCommand;
40
+ const path = __importStar(require("path"));
41
+ const fs = __importStar(require("fs/promises"));
42
+ const config_1 = require("../utils/config");
43
+ const logger_1 = require("../utils/logger");
44
+ const colors_1 = require("../utils/colors");
45
+ const workspace_meta_1 = require("../utils/workspace-meta");
46
+ const context_file_1 = require("../utils/context-file");
47
+ const inquirer_1 = __importDefault(require("inquirer"));
48
+ const CONTEXT_FILENAME = 'CONTEXT.md';
49
+ function registerSaveContextCommand(parent) {
50
+ parent
51
+ .command('save-context')
52
+ .alias('ctx')
53
+ .description('Save a progress summary to the workspace (persists across /clear)')
54
+ .option('-w, --workspace <name>', 'Workspace name (default: current directory)')
55
+ .option('-m, --message <text>', 'Summary text to save')
56
+ .option('-f, --file <path>', 'Read summary from a file')
57
+ .option('--append', 'Append to existing context instead of replacing')
58
+ .action(async (opts) => {
59
+ await handleSaveContext(opts);
60
+ });
61
+ }
62
+ async function resolveWorkspacePath(workspaceName) {
63
+ // Try current directory first
64
+ if (!workspaceName) {
65
+ const cwd = process.cwd();
66
+ const metaPath = path.join(cwd, config_1.META_FILENAME);
67
+ try {
68
+ await fs.access(metaPath);
69
+ const meta = JSON.parse(await fs.readFile(metaPath, 'utf-8'));
70
+ return { name: meta.workspaceName || path.basename(cwd), path: cwd };
71
+ }
72
+ catch {
73
+ // Not in a workspace directory — check if we're inside a workspace subdirectory
74
+ const parentDir = path.dirname(cwd);
75
+ const parentMeta = path.join(parentDir, config_1.META_FILENAME);
76
+ try {
77
+ await fs.access(parentMeta);
78
+ const meta = JSON.parse(await fs.readFile(parentMeta, 'utf-8'));
79
+ return { name: meta.workspaceName || path.basename(parentDir), path: parentDir };
80
+ }
81
+ catch {
82
+ // Not in any workspace
83
+ }
84
+ }
85
+ }
86
+ // Use provided workspace name
87
+ if (workspaceName) {
88
+ const wsPath = path.join(config_1.WORKSPACES_DIR, workspaceName);
89
+ try {
90
+ await fs.access(path.join(wsPath, config_1.META_FILENAME));
91
+ return { name: workspaceName, path: wsPath };
92
+ }
93
+ catch {
94
+ (0, logger_1.logError)(`Workspace not found: ${workspaceName}`);
95
+ return null;
96
+ }
97
+ }
98
+ // Interactive selection
99
+ if (process.stdout.isTTY) {
100
+ const workspaces = await (0, workspace_meta_1.listWorkspaces)(false);
101
+ if (workspaces.length === 0) {
102
+ (0, logger_1.logError)('No workspaces found');
103
+ return null;
104
+ }
105
+ const { selected } = await inquirer_1.default.prompt([{
106
+ type: 'list',
107
+ name: 'selected',
108
+ message: 'Select workspace:',
109
+ choices: workspaces.map(w => ({ name: w.name, value: w.name })),
110
+ }]);
111
+ return { name: selected, path: path.join(config_1.WORKSPACES_DIR, selected) };
112
+ }
113
+ (0, logger_1.logError)('Could not determine workspace. Use --workspace <name> or run from within a workspace.');
114
+ return null;
115
+ }
116
+ async function handleSaveContext(opts) {
117
+ const ws = await resolveWorkspacePath(opts.workspace);
118
+ if (!ws)
119
+ return;
120
+ // Get content from message, file, or stdin
121
+ let content;
122
+ if (opts.message) {
123
+ content = opts.message;
124
+ }
125
+ else if (opts.file) {
126
+ try {
127
+ content = await fs.readFile(opts.file, 'utf-8');
128
+ }
129
+ catch (err) {
130
+ (0, logger_1.logError)(`Failed to read file: ${opts.file}`);
131
+ return;
132
+ }
133
+ }
134
+ else if (!process.stdin.isTTY) {
135
+ // Read from stdin (piped input)
136
+ const chunks = [];
137
+ for await (const chunk of process.stdin) {
138
+ chunks.push(chunk);
139
+ }
140
+ content = Buffer.concat(chunks).toString('utf-8').trim();
141
+ }
142
+ else {
143
+ (0, logger_1.logError)('No content provided. Use --message, --file, or pipe content via stdin.');
144
+ console.log(`\n Usage:`);
145
+ console.log(` ${(0, colors_1.colorize)('w save-context -m "Completed auth refactor, moved to payments"', 'green')}`);
146
+ console.log(` ${(0, colors_1.colorize)('w save-context -f summary.md', 'green')}`);
147
+ console.log(` ${(0, colors_1.colorize)('echo "progress notes" | w save-context', 'green')}`);
148
+ return;
149
+ }
150
+ if (!content.trim()) {
151
+ (0, logger_1.logError)('Empty content — nothing to save.');
152
+ return;
153
+ }
154
+ const contextPath = path.join(ws.path, CONTEXT_FILENAME);
155
+ if (opts.append) {
156
+ let existing = null;
157
+ try {
158
+ existing = await fs.readFile(contextPath, 'utf-8');
159
+ }
160
+ catch {
161
+ // File doesn't exist yet
162
+ }
163
+ content = (0, context_file_1.appendToContextFile)(existing, ws.name, content);
164
+ }
165
+ else {
166
+ content = (0, context_file_1.formatContextFile)(ws.name, content);
167
+ }
168
+ await fs.writeFile(contextPath, content, 'utf-8');
169
+ (0, logger_1.logSuccess)(`Context saved to ${(0, colors_1.colorize)(CONTEXT_FILENAME, 'cyan')} in ${ws.name}`);
170
+ (0, logger_1.logInfo)('This file persists across /clear and session restarts.');
171
+ }
@@ -0,0 +1,129 @@
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.registerSessionsCommand = registerSessionsCommand;
40
+ const path = __importStar(require("path"));
41
+ const os = __importStar(require("os"));
42
+ const fs = __importStar(require("fs/promises"));
43
+ const claude_sessions_1 = require("../utils/claude-sessions");
44
+ const workspace_meta_1 = require("../utils/workspace-meta");
45
+ const logger_1 = require("../utils/logger");
46
+ const colors_1 = require("../utils/colors");
47
+ const inquirer_1 = __importDefault(require("inquirer"));
48
+ const inquirer_autocomplete_prompt_1 = __importDefault(require("inquirer-autocomplete-prompt"));
49
+ const fuzzy = __importStar(require("fuzzy"));
50
+ inquirer_1.default.registerPrompt('autocomplete', inquirer_autocomplete_prompt_1.default);
51
+ const TEMP_FILE = path.join(os.homedir(), '.workspace-last-go');
52
+ const RESUME_FLAG_FILE = path.join(os.homedir(), '.workspace-resume-session');
53
+ function registerSessionsCommand(parent) {
54
+ parent
55
+ .command('sessions')
56
+ .alias('ses')
57
+ .description('Resume a Claude session in a workspace')
58
+ .action(async () => {
59
+ await handleSessions();
60
+ });
61
+ }
62
+ async function handleSessions() {
63
+ try {
64
+ const sessions = await (0, claude_sessions_1.getWorkspaceSessions)();
65
+ if (sessions.length === 0) {
66
+ (0, logger_1.logInfo)('No workspace sessions found.');
67
+ console.log('\nYou can create a workspace with: nemus create');
68
+ console.log('Or navigate to one with: w go');
69
+ return;
70
+ }
71
+ const workspaces = await (0, workspace_meta_1.listWorkspaces)(false);
72
+ const workspaceMap = new Map(workspaces.map(ws => [ws.name, ws]));
73
+ const items = sessions.map(session => {
74
+ const ws = workspaceMap.get(session.workspaceName);
75
+ const repoCount = ws?.metadata?.repositories?.length ?? 0;
76
+ const repoLabel = repoCount > 0 ? `${repoCount} repos` : 'no repos';
77
+ return { session, repoLabel };
78
+ });
79
+ const maxNameLen = Math.max(...items.map(i => i.session.workspaceName.length));
80
+ console.log('');
81
+ console.log((0, colors_1.colorize)(' Workspace Sessions', 'bright') + (0, colors_1.colorize)(' (sorted by last active)', 'dim'));
82
+ console.log((0, colors_1.colorize)(' ' + '─'.repeat(50), 'dim'));
83
+ for (const item of items.slice(0, 10)) {
84
+ const name = item.session.workspaceName.padEnd(maxNameLen);
85
+ const time = item.session.lastActiveLabel;
86
+ console.log(` ${(0, colors_1.colorize)(name, 'cyan')} ${(0, colors_1.colorize)(time, 'yellow')} ${(0, colors_1.colorize)(item.repoLabel, 'dim')}`);
87
+ }
88
+ if (items.length > 10) {
89
+ console.log((0, colors_1.colorize)(` ... and ${items.length - 10} more`, 'dim'));
90
+ }
91
+ console.log('');
92
+ const { selected } = await inquirer_1.default.prompt([{
93
+ type: 'autocomplete', name: 'selected',
94
+ message: 'Select workspace to resume:',
95
+ source: async (_answersSoFar, input) => {
96
+ const searchInput = input || '';
97
+ const source = items.map(item => ({
98
+ name: `${item.session.workspaceName} ${(0, colors_1.colorize)(item.session.lastActiveLabel, 'dim')} ${(0, colors_1.colorize)(item.repoLabel, 'dim')}`,
99
+ value: item.session,
100
+ }));
101
+ if (!searchInput)
102
+ return source;
103
+ const results = fuzzy.filter(searchInput, items, { extract: (item) => item.session.workspaceName });
104
+ return results.map(result => ({
105
+ name: `${result.original.session.workspaceName} ${(0, colors_1.colorize)(result.original.session.lastActiveLabel, 'dim')} ${(0, colors_1.colorize)(result.original.repoLabel, 'dim')}`,
106
+ value: result.original.session,
107
+ }));
108
+ },
109
+ pageSize: 15,
110
+ }]);
111
+ const session = selected;
112
+ await fs.writeFile(TEMP_FILE, session.workspacePath, 'utf-8');
113
+ // Write JSON with session ID and agent type for correct resume
114
+ await fs.writeFile(RESUME_FLAG_FILE, JSON.stringify({
115
+ sessionId: session.sessionId,
116
+ agentType: session.agentType,
117
+ }), 'utf-8');
118
+ console.log(`\n${(0, colors_1.colorize)('Resuming:', 'green')} ${session.workspaceName} (last active ${session.lastActiveLabel})`);
119
+ }
120
+ catch (error) {
121
+ if (error?.name === 'ExitPromptError')
122
+ return;
123
+ (0, logger_1.logError)('Failed to list sessions');
124
+ if (error instanceof Error) {
125
+ (0, logger_1.logError)(error.message);
126
+ }
127
+ process.exit(1);
128
+ }
129
+ }
@@ -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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.registerStatusCommand = registerStatusCommand;
37
+ const path = __importStar(require("path"));
38
+ const config_1 = require("../utils/config");
39
+ const workspace_meta_1 = require("../utils/workspace-meta");
40
+ const git_status_1 = require("../utils/git-status");
41
+ const logger_1 = require("../utils/logger");
42
+ const colors_1 = require("../utils/colors");
43
+ const command_helpers_1 = require("../utils/command-helpers");
44
+ const displayStatusTable = (statuses) => {
45
+ console.log('\n' + (0, colors_1.colorize)('═'.repeat(100), 'gray'));
46
+ console.log((0, colors_1.colorize)('Repo', 'bright').padEnd(30) +
47
+ (0, colors_1.colorize)('Branch', 'bright').padEnd(25) +
48
+ (0, colors_1.colorize)('Status', 'bright').padEnd(15) +
49
+ (0, colors_1.colorize)('Ahead/Behind', 'bright').padEnd(15) +
50
+ (0, colors_1.colorize)('Modified', 'bright'));
51
+ console.log((0, colors_1.colorize)('─'.repeat(100), 'gray'));
52
+ for (const status of statuses) {
53
+ const repoName = status.repo.padEnd(20);
54
+ let branchDisplay = status.branch.padEnd(15);
55
+ if (status.detachedHead) {
56
+ branchDisplay = (0, colors_1.colorize)(branchDisplay, 'yellow');
57
+ }
58
+ let statusDisplay = '';
59
+ if (status.clean) {
60
+ statusDisplay = (0, colors_1.colorize)('✓ Clean', 'green').padEnd(15);
61
+ }
62
+ else {
63
+ const changes = [];
64
+ if (status.modifiedFiles > 0)
65
+ changes.push(`${status.modifiedFiles} modified`);
66
+ if (status.untrackedFiles > 0)
67
+ changes.push(`${status.untrackedFiles} untracked`);
68
+ statusDisplay = (0, colors_1.colorize)(`⚠ ${changes.join(', ')}`, 'yellow').padEnd(15);
69
+ }
70
+ let trackingDisplay = '';
71
+ if (!status.hasRemote) {
72
+ trackingDisplay = (0, colors_1.colorize)('No remote', 'gray').padEnd(15);
73
+ }
74
+ else if (status.ahead === 0 && status.behind === 0) {
75
+ trackingDisplay = (0, colors_1.colorize)('Up to date', 'green').padEnd(15);
76
+ }
77
+ else {
78
+ const parts = [];
79
+ if (status.ahead > 0)
80
+ parts.push((0, colors_1.colorize)(`↑${status.ahead}`, 'cyan'));
81
+ if (status.behind > 0)
82
+ parts.push((0, colors_1.colorize)(`↓${status.behind}`, 'red'));
83
+ trackingDisplay = parts.join(' ').padEnd(15);
84
+ }
85
+ const modifiedDisplay = status.clean ? '-' : `${status.modifiedFiles + status.untrackedFiles} files`;
86
+ console.log(`${repoName} ${branchDisplay} ${statusDisplay} ${trackingDisplay} ${modifiedDisplay}`);
87
+ }
88
+ console.log((0, colors_1.colorize)('═'.repeat(100), 'gray'));
89
+ const cleanRepos = statuses.filter(s => s.clean).length;
90
+ const dirtyRepos = statuses.filter(s => !s.clean).length;
91
+ const needsPush = statuses.filter(s => s.ahead > 0).length;
92
+ const needsPull = statuses.filter(s => s.behind > 0).length;
93
+ console.log('\n' + (0, colors_1.colorize)('Summary:', 'bright'));
94
+ console.log(` ${(0, colors_1.colorize)('✓', 'green')} ${cleanRepos} clean repositories`);
95
+ if (dirtyRepos > 0) {
96
+ console.log(` ${(0, colors_1.colorize)('⚠', 'yellow')} ${dirtyRepos} repositories with uncommitted changes`);
97
+ }
98
+ if (needsPush > 0) {
99
+ console.log(` ${(0, colors_1.colorize)('↑', 'cyan')} ${needsPush} repositories ahead of remote`);
100
+ }
101
+ if (needsPull > 0) {
102
+ console.log(` ${(0, colors_1.colorize)('↓', 'red')} ${needsPull} repositories behind remote`);
103
+ }
104
+ console.log('');
105
+ };
106
+ function registerStatusCommand(parent) {
107
+ parent
108
+ .command('status')
109
+ .alias('st')
110
+ .description('Show git status across all repos')
111
+ .argument('[workspace]', 'Workspace name')
112
+ .action(async (workspace) => {
113
+ await handleStatus(workspace);
114
+ });
115
+ }
116
+ async function handleStatus(workspaceArg) {
117
+ try {
118
+ const selectedWorkspace = await (0, command_helpers_1.resolveWorkspace)(workspaceArg);
119
+ const workspacePath = path.join(config_1.WORKSPACES_DIR, selectedWorkspace);
120
+ const metadata = await (0, workspace_meta_1.loadMetadata)(workspacePath);
121
+ if (!metadata) {
122
+ (0, logger_1.logError)(`Workspace metadata not found for: ${selectedWorkspace}`);
123
+ process.exit(1);
124
+ }
125
+ (0, logger_1.logStep)(`Checking status for workspace: ${(0, colors_1.colorize)(selectedWorkspace, 'cyan')}`);
126
+ (0, logger_1.logInfo)(`Found ${metadata.repositories.length} repositories`);
127
+ const repoDirectoryNames = metadata.repositories.map(r => r.directoryName);
128
+ const statuses = await (0, git_status_1.getAllReposStatus)(workspacePath, repoDirectoryNames, 3);
129
+ displayStatusTable(statuses);
130
+ }
131
+ catch (error) {
132
+ (0, logger_1.logError)('Failed to check workspace status');
133
+ if (error instanceof Error) {
134
+ (0, logger_1.logError)(error.message);
135
+ }
136
+ process.exit(1);
137
+ }
138
+ }