@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,136 @@
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.program = void 0;
37
+ const commander_1 = require("commander");
38
+ const path = __importStar(require("path"));
39
+ const fs = __importStar(require("fs"));
40
+ const colors_1 = require("./utils/colors");
41
+ // Read version from package.json
42
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'));
43
+ const g = colors_1.colors.green;
44
+ const d = colors_1.colors.dim;
45
+ const b = colors_1.colors.bright;
46
+ const r = colors_1.colors.reset;
47
+ const INNER = 38;
48
+ const titleLine = `>_ Nemus`;
49
+ const titlePad = ' '.repeat(Math.max(0, INNER - 2 - titleLine.length));
50
+ const versionLine = `v${pkg.version} · multi-repo workspaces`;
51
+ const versionPad = ' '.repeat(Math.max(0, INNER - 7 - versionLine.length));
52
+ const bar = '─'.repeat(INNER);
53
+ const bannerText = `
54
+ ${d} ╭${bar}╮${r}
55
+ ${d} │${r} ${g}>_${r} ${b}Nemus${r}${titlePad}${d}│${r}
56
+ ${d} │${r} ${d}${versionLine}${r}${versionPad}${d}│${r}
57
+ ${d} ╰${bar}╯${r}
58
+ `;
59
+ exports.program = new commander_1.Command();
60
+ exports.program
61
+ .name('workspace')
62
+ .description('Multi-repo workspace manager')
63
+ .version(pkg.version, '-V, --version')
64
+ .option('-f, --force-refresh', 'Force refresh GitHub repos (skip cache)')
65
+ .option('-y, --yes', 'Skip confirmations')
66
+ .addHelpText('before', bannerText);
67
+ // Register top-level commands
68
+ const create_1 = require("./commands/create");
69
+ const list_1 = require("./commands/list");
70
+ const update_1 = require("./commands/update");
71
+ const delete_1 = require("./commands/delete");
72
+ const sync_1 = require("./commands/sync");
73
+ const status_1 = require("./commands/status");
74
+ const diff_1 = require("./commands/diff");
75
+ const run_1 = require("./commands/run");
76
+ const go_1 = require("./commands/go");
77
+ const doctor_1 = require("./commands/doctor");
78
+ const analyze_deps_1 = require("./commands/analyze-deps");
79
+ const history_1 = require("./commands/history");
80
+ const cleanup_1 = require("./commands/cleanup");
81
+ const remove_repo_1 = require("./commands/remove-repo");
82
+ const archive_1 = require("./commands/archive");
83
+ const sessions_1 = require("./commands/sessions");
84
+ const generate_docs_1 = require("./commands/generate-docs");
85
+ const configure_1 = require("./commands/configure");
86
+ const configure_claude_1 = require("./commands/configure-claude");
87
+ const ghq_status_1 = require("./commands/ghq-status");
88
+ const save_context_1 = require("./commands/save-context");
89
+ const migrate_1 = require("./commands/migrate");
90
+ const report_bug_1 = require("./commands/report-bug");
91
+ (0, create_1.registerCreateCommand)(exports.program);
92
+ (0, list_1.registerListCommand)(exports.program);
93
+ (0, update_1.registerUpdateCommand)(exports.program);
94
+ (0, delete_1.registerDeleteCommand)(exports.program);
95
+ (0, sync_1.registerSyncCommand)(exports.program);
96
+ (0, status_1.registerStatusCommand)(exports.program);
97
+ (0, diff_1.registerDiffCommand)(exports.program);
98
+ (0, run_1.registerRunCommand)(exports.program);
99
+ (0, go_1.registerGoCommand)(exports.program);
100
+ (0, doctor_1.registerDoctorCommand)(exports.program);
101
+ (0, analyze_deps_1.registerAnalyzeDepsCommand)(exports.program);
102
+ (0, history_1.registerHistoryCommand)(exports.program);
103
+ (0, cleanup_1.registerCleanupCommand)(exports.program);
104
+ (0, remove_repo_1.registerRemoveRepoCommand)(exports.program);
105
+ (0, archive_1.registerArchiveCommand)(exports.program);
106
+ (0, sessions_1.registerSessionsCommand)(exports.program);
107
+ (0, generate_docs_1.registerGenerateDocsCommand)(exports.program);
108
+ (0, configure_1.registerConfigureCommand)(exports.program);
109
+ (0, configure_claude_1.registerConfigureClaudeCommand)(exports.program);
110
+ (0, ghq_status_1.registerGhqStatusCommand)(exports.program);
111
+ (0, save_context_1.registerSaveContextCommand)(exports.program);
112
+ (0, migrate_1.registerMigrateCommand)(exports.program);
113
+ (0, report_bug_1.registerReportBugCommand)(exports.program);
114
+ // Register TUI (delegates to existing Ink/React implementation)
115
+ exports.program
116
+ .command('tui')
117
+ .description('Launch interactive terminal UI')
118
+ .action(async () => {
119
+ const { main } = await Promise.resolve().then(() => __importStar(require('./cli/tui')));
120
+ await main();
121
+ });
122
+ // Register dashboard command
123
+ const dashboard_1 = require("./commands/dashboard");
124
+ (0, dashboard_1.registerDashboardCommand)(exports.program);
125
+ // Register grouped commands
126
+ const suite_1 = require("./commands/suite");
127
+ const branch_1 = require("./commands/branch");
128
+ const cache_1 = require("./commands/cache");
129
+ const mcp_1 = require("./commands/mcp");
130
+ (0, suite_1.registerSuiteCommands)(exports.program);
131
+ (0, branch_1.registerBranchCommands)(exports.program);
132
+ (0, cache_1.registerCacheCommands)(exports.program);
133
+ (0, mcp_1.registerMcpCommands)(exports.program);
134
+ // Register deprecated aliases
135
+ const deprecated_aliases_1 = require("./commands/deprecated-aliases");
136
+ (0, deprecated_aliases_1.registerDeprecatedAliases)(exports.program);
@@ -0,0 +1,394 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ workspace-table.py — Workspace Manager status-line extension for Claude Code
4
+ (auto-generated by workspace-manager)
5
+
6
+ Outputs ONLY the workspace repo table (branch · PR · CI · dirty state).
7
+ Claude Code already renders model / cost / context itself, so this script
8
+ adds only what it doesn't show.
9
+
10
+ Configure in ~/.claude/settings.json:
11
+ "statusLine": {
12
+ "type": "command",
13
+ "command": "~/.workspace-manager-table.py",
14
+ "padding": 0
15
+ }
16
+
17
+ Claude Code passes session data as JSON on stdin.
18
+ """
19
+
20
+ import hashlib
21
+ import json
22
+ import os
23
+ import subprocess
24
+ import sys
25
+ import time
26
+ from concurrent.futures import ThreadPoolExecutor
27
+ from pathlib import Path
28
+
29
+ # ─── Cache ───────────────────────────────────────────────────────────────────
30
+ CACHE_FILE = Path.home() / ".workspace-manager-cache" / "pr-status.json"
31
+ CACHE_TTL = 300 # seconds
32
+
33
+ # ─── ANSI helpers ─────────────────────────────────────────────────────────────
34
+ RESET = "\033[0m"
35
+ BOLD = "\033[1m"
36
+ DIM = "\033[2m"
37
+ CYAN = "\033[38;5;87m"
38
+ BLUE = "\033[38;5;75m"
39
+ MAGENTA = "\033[38;5;213m"
40
+ GREEN = "\033[38;5;120m"
41
+ YELLOW = "\033[38;5;221m"
42
+ RED = "\033[38;5;203m"
43
+ GRAY = "\033[38;5;245m"
44
+ PURPLE = "\033[38;5;141m"
45
+
46
+
47
+ def color(text: str, c: str) -> str:
48
+ return f"{c}{text}{RESET}"
49
+
50
+
51
+ def hyperlink(text: str, url: str | None) -> str:
52
+ if not url:
53
+ return text
54
+ return f"\033]8;;{url}\033\\{text}\033]8;;\033\\"
55
+
56
+
57
+ # ─── Cache helpers ────────────────────────────────────────────────────────────
58
+ def load_cache() -> dict:
59
+ try:
60
+ return json.loads(CACHE_FILE.read_text())
61
+ except Exception:
62
+ return {}
63
+
64
+
65
+ def save_cache(cache: dict) -> None:
66
+ try:
67
+ CACHE_FILE.parent.mkdir(parents=True, exist_ok=True)
68
+ CACHE_FILE.write_text(json.dumps(cache))
69
+ except Exception:
70
+ pass
71
+
72
+
73
+ # ─── Git / PR helpers ─────────────────────────────────────────────────────────
74
+ def repo_web_url(cwd: str) -> str | None:
75
+ try:
76
+ r = subprocess.run(
77
+ ["git", "-C", cwd, "remote", "get-url", "origin"],
78
+ capture_output=True, text=True, timeout=0.3,
79
+ )
80
+ if r.returncode != 0:
81
+ return None
82
+ url = r.stdout.strip()
83
+ if url.startswith("git@"):
84
+ host, path = url[4:].split(":", 1)
85
+ url = f"https://{host}/{path}"
86
+ if url.endswith(".git"):
87
+ url = url[:-4]
88
+ return url
89
+ except Exception:
90
+ return None
91
+
92
+
93
+ def pr_info(cwd: str, branch: str) -> dict:
94
+ """Return cached PR info, firing a background refresh if stale."""
95
+ repo_url = repo_web_url(cwd)
96
+ if not repo_url:
97
+ return {"url": None, "fallback": None, "number": None,
98
+ "state": None, "isDraft": None, "ci": None}
99
+ key = hashlib.sha1(f"{repo_url}@{branch}".encode()).hexdigest()
100
+ cache = load_cache()
101
+ entry = cache.get(key)
102
+ now = time.time()
103
+ fresh = entry and now - entry.get("ts", 0) < CACHE_TTL
104
+ fallback = f"{repo_url}/tree/{branch}"
105
+ if not fresh:
106
+ try:
107
+ subprocess.Popen(
108
+ [sys.executable, str(Path(__file__).resolve()), "--refresh-pr", key, cwd, branch],
109
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
110
+ stdin=subprocess.DEVNULL, start_new_session=True,
111
+ )
112
+ except Exception:
113
+ pass
114
+ e = entry or {}
115
+ return {
116
+ "url": e.get("url"),
117
+ "fallback": fallback,
118
+ "number": e.get("number"),
119
+ "state": e.get("state"),
120
+ "isDraft": e.get("isDraft"),
121
+ "ci": e.get("ci"),
122
+ }
123
+
124
+
125
+ def refresh_pr(key: str, cwd: str, branch: str) -> None:
126
+ info: dict = {"url": None, "number": None, "state": None,
127
+ "isDraft": None, "ci": None}
128
+ try:
129
+ r = subprocess.run(
130
+ ["gh", "pr", "view", "--json",
131
+ "url,number,state,isDraft,statusCheckRollup"],
132
+ capture_output=True, text=True, timeout=10, cwd=cwd,
133
+ )
134
+ if r.returncode == 0 and r.stdout.strip():
135
+ data = json.loads(r.stdout)
136
+ info["url"] = data.get("url")
137
+ info["number"] = data.get("number")
138
+ info["state"] = data.get("state")
139
+ info["isDraft"] = data.get("isDraft")
140
+ # Summarise CI rollup
141
+ rollup = data.get("statusCheckRollup") or []
142
+ info["ci"] = _rollup_ci(rollup)
143
+ except Exception:
144
+ pass
145
+ cache = load_cache()
146
+ cache[key] = {**info, "ts": time.time()}
147
+ save_cache(cache)
148
+
149
+
150
+ def _rollup_ci(rollup: list) -> str | None:
151
+ if not rollup:
152
+ return None
153
+ has_fail = has_pending = False
154
+ for c in rollup:
155
+ s = (c.get("state") or c.get("conclusion") or c.get("status") or "").upper()
156
+ if s in ("FAILURE", "TIMED_OUT", "CANCELLED", "ERROR"):
157
+ has_fail = True
158
+ elif s in ("PENDING", "IN_PROGRESS", "QUEUED", "", "EXPECTED"):
159
+ has_pending = True
160
+ if has_fail:
161
+ return "failure"
162
+ if has_pending:
163
+ return "pending"
164
+ return "success"
165
+
166
+
167
+ def git_info(cwd: str) -> tuple[str, int | None] | None:
168
+ try:
169
+ r = subprocess.run(
170
+ ["git", "-C", cwd, "rev-parse", "--abbrev-ref", "HEAD"],
171
+ capture_output=True, text=True, timeout=1.0,
172
+ )
173
+ if r.returncode != 0:
174
+ return None
175
+ branch = r.stdout.strip()
176
+ except Exception:
177
+ return None
178
+ dirty: int | None = None
179
+ try:
180
+ s = subprocess.run(
181
+ ["git", "-C", cwd, "status", "--porcelain"],
182
+ capture_output=True, text=True, timeout=2.0,
183
+ )
184
+ if s.returncode == 0:
185
+ dirty = len([l for l in s.stdout.splitlines() if l.strip()])
186
+ except Exception:
187
+ pass
188
+ return branch, dirty
189
+
190
+
191
+ # ─── Workspace discovery ───────────────────────────────────────────────────────
192
+ DEFAULT_BRANCHES = {"main", "master", "develop", "production", "trunk"}
193
+
194
+ CI_ICON = {"success": "✓", "failure": "✗", "pending": "◌"}
195
+ CI_COLOR = {"success": GREEN, "failure": RED, "pending": YELLOW}
196
+ PR_ICONS = {
197
+ "open": "\ue725", # nf-cod-git_pull_request
198
+ "draft": "\uea64", # nf-oct-git_pull_request_draft
199
+ "merged": "\uea6a", # nf-oct-git_merge
200
+ "closed": "\ue729", # nf-cod-git_pull_request_closed
201
+ }
202
+
203
+
204
+ def find_workspace(cwd: str) -> tuple[Path, dict] | None:
205
+ p = Path(cwd).resolve()
206
+ for candidate in [p, *p.parents]:
207
+ meta = candidate / ".workspace-meta.json"
208
+ if meta.is_file():
209
+ try:
210
+ data = json.loads(meta.read_text())
211
+ return candidate, data
212
+ except Exception:
213
+ return None
214
+ return None
215
+
216
+
217
+ def gather_repo_row(repo_path: Path, is_active: bool) -> dict:
218
+ cwd_str = str(repo_path)
219
+ g = git_info(cwd_str)
220
+ name = repo_path.name
221
+ if not g:
222
+ return {"active": is_active, "name": name, "branch": None,
223
+ "branch_url": None, "pr": None, "dirty": None, "no_git": True}
224
+ branch, dirty = g
225
+ pi = pr_info(cwd_str, branch)
226
+ return {
227
+ "active": is_active,
228
+ "name": name,
229
+ "branch": branch,
230
+ "branch_url": pi.get("url") or pi.get("fallback"),
231
+ "pr_num": pi.get("number"),
232
+ "pr_url": pi.get("url"),
233
+ "pr_state": pi.get("state"),
234
+ "pr_draft": pi.get("isDraft"),
235
+ "pr_ci": pi.get("ci"),
236
+ "dirty": dirty,
237
+ "no_git": False,
238
+ }
239
+
240
+
241
+ # ─── Cell renderers ────────────────────────────────────────────────────────────
242
+ def pr_plain(row: dict) -> str:
243
+ if row["no_git"] or not row.get("pr_num"):
244
+ return "—" if not row["no_git"] and row.get("branch") else ""
245
+ s = f"#{row['pr_num']}"
246
+ if row.get("pr_draft"): s += " draft"
247
+ elif row.get("pr_state") == "MERGED": s += " merged"
248
+ elif row.get("pr_state") == "CLOSED": s += " closed"
249
+ ci = row.get("pr_ci")
250
+ if ci:
251
+ s += f" {CI_ICON.get(ci, '')}"
252
+ return s
253
+
254
+
255
+ def pr_styled(row: dict) -> str:
256
+ if row["no_git"] or not row.get("pr_num"):
257
+ return color("—", GRAY) if not row["no_git"] and row.get("branch") else ""
258
+ num = f"#{row['pr_num']}"
259
+ draft = row.get("pr_draft")
260
+ state = row.get("pr_state", "OPEN")
261
+ icon = PR_ICONS.get("draft" if draft else state.lower(), PR_ICONS["open"])
262
+ if draft: c = GRAY
263
+ elif state == "MERGED": c = PURPLE
264
+ elif state == "CLOSED": c = RED
265
+ else: c = GREEN
266
+ label = f"{icon} {num} {'draft' if draft else state.lower()}"
267
+ ci = row.get("pr_ci")
268
+ ci_part = f" {color(CI_ICON.get(ci,''), CI_COLOR.get(ci, GRAY))}" if ci else ""
269
+ return hyperlink(color(label, c), row.get("pr_url")) + ci_part
270
+
271
+
272
+ def dirty_plain(row: dict) -> str:
273
+ if row["no_git"]: return "(no git)"
274
+ if row["dirty"] is None: return "*?"
275
+ return f"*{row['dirty']}" if row["dirty"] > 0 else ""
276
+
277
+
278
+ def dirty_styled(row: dict) -> str:
279
+ if row["no_git"]: return color("(no git)", GRAY)
280
+ if row["dirty"] is None: return color("*?", GRAY)
281
+ return color(f"*{row['dirty']}", RED) if row["dirty"] > 0 else ""
282
+
283
+
284
+ # ─── Table renderer ────────────────────────────────────────────────────────────
285
+ def render_repo_table(rows: list[dict]) -> list[str]:
286
+ headers = ("REPO", "BRANCH", "PR", "DIRTY")
287
+ plain_rows = [(r["name"], r.get("branch") or "", pr_plain(r), dirty_plain(r))
288
+ for r in rows]
289
+ plain_rows.insert(0, headers)
290
+ widths = [max(len(p[i]) for p in plain_rows) for i in range(4)]
291
+
292
+ def pad(s: str, w: int) -> str:
293
+ return s + " " * (w - len(s))
294
+
295
+ header = " " + " ".join(
296
+ color(pad(h, widths[i]), DIM + GRAY) for i, h in enumerate(headers)
297
+ )
298
+
299
+ result = [header]
300
+ for r in rows:
301
+ marker = color("▸ ", PURPLE) if r["active"] else " "
302
+ name_c = PURPLE + BOLD if r["active"] else BLUE
303
+ name_cell = color(r["name"], name_c if not r["no_git"] else DIM + GRAY)
304
+ name_cell += " " * (widths[0] - len(r["name"]))
305
+
306
+ br_plain = r.get("branch") or ""
307
+ br_styled = (hyperlink(color(br_plain, MAGENTA), r.get("branch_url"))
308
+ if br_plain else "")
309
+ br_cell = br_styled + " " * (widths[1] - len(br_plain))
310
+
311
+ pp = pr_plain(r)
312
+ pr_cell = pr_styled(r) + " " * (widths[2] - len(pp))
313
+
314
+ dp = dirty_plain(r)
315
+ d_cell = dirty_styled(r) + " " * (widths[3] - len(dp))
316
+
317
+ result.append(f"{marker}{name_cell} {br_cell} {pr_cell} {d_cell}".rstrip())
318
+ return result
319
+
320
+
321
+ # ─── Main ─────────────────────────────────────────────────────────────────────
322
+ def main() -> None:
323
+ """
324
+ Claude Code calls this script and shows whatever we write to stdout
325
+ as the statusLine — an *additional* line shown below the editor.
326
+ Claude Code's own header (model · tokens · cost) is always shown
327
+ regardless of what we output here.
328
+
329
+ Behaviour contract:
330
+ - Not in a workspace → output nothing (CC shows its default footer)
331
+ - In workspace, all repos on default branch → output nothing
332
+ - In workspace with feature-branch repos → output the repo table only
333
+
334
+ We NEVER output model info, cost, or anything that duplicates CC's
335
+ own display. We NEVER modify the user's existing styling.
336
+ """
337
+ try:
338
+ data = json.load(sys.stdin)
339
+ except Exception:
340
+ data = {}
341
+
342
+ cwd = (data.get("workspace") or {}).get("current_dir") or os.getcwd()
343
+ ws = find_workspace(cwd)
344
+
345
+ if not ws:
346
+ # Not in a workspace — output nothing so CC's default footer is shown unchanged.
347
+ return
348
+
349
+ ws_path, ws_meta = ws
350
+
351
+ # Find which repo (if any) is currently active
352
+ active_repo: str | None = None
353
+ try:
354
+ rel = Path(cwd).resolve().relative_to(ws_path)
355
+ if rel.parts:
356
+ active_repo = rel.parts[0]
357
+ except ValueError:
358
+ pass
359
+
360
+ repo_tasks = []
361
+ for repo in ws_meta.get("repositories") or []:
362
+ dir_name = repo.get("directoryName") or repo.get("name")
363
+ if not dir_name:
364
+ continue
365
+ repo_path = ws_path / dir_name
366
+ if not repo_path.is_dir():
367
+ continue
368
+ repo_tasks.append((repo_path, dir_name == active_repo))
369
+
370
+ if not repo_tasks:
371
+ return
372
+
373
+ max_workers = min(8, len(repo_tasks))
374
+ with ThreadPoolExecutor(max_workers=max_workers) as ex:
375
+ rows = list(ex.map(lambda t: gather_repo_row(*t), repo_tasks))
376
+
377
+ # Filter: only repos on non-default branches (toggle not available in CC)
378
+ rows = [r for r in rows if r.get("branch")
379
+ and r["branch"] not in DEFAULT_BRANCHES]
380
+
381
+ if not rows:
382
+ # All repos are on default branches — nothing interesting to show.
383
+ # Output nothing to preserve CC's default footer.
384
+ return
385
+
386
+ # Output ONLY the table. CC's model/cost header is shown above this independently.
387
+ sys.stdout.write("\n".join(render_repo_table(rows)))
388
+
389
+
390
+ if __name__ == "__main__":
391
+ if len(sys.argv) >= 4 and sys.argv[1] == "--refresh-pr":
392
+ refresh_pr(sys.argv[2], sys.argv[3], sys.argv[4] if len(sys.argv) > 4 else "")
393
+ else:
394
+ main()
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HOOK_MARKER = exports.DASHBOARD_DEFAULTS = void 0;
4
+ exports.DASHBOARD_DEFAULTS = {
5
+ sessionName: 'ws-dashboard',
6
+ sidebarWidthPercent: 20,
7
+ pollIntervalMs: 2000,
8
+ staleTtlMs: 300000,
9
+ };
10
+ /** Marker string embedded in hook commands for detection/removal */
11
+ exports.HOOK_MARKER = 'workspace-dashboard-hook';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });