@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.
- package/CHANGELOG.md +86 -0
- package/LICENSE +21 -0
- package/README.md +275 -0
- package/assets/README.md +53 -0
- package/assets/banner.png +0 -0
- package/assets/banner.svg +66 -0
- package/assets/favicon-32.png +0 -0
- package/assets/favicon-64.png +0 -0
- package/assets/icon-256.png +0 -0
- package/assets/icon.svg +23 -0
- package/assets/logo-256.png +0 -0
- package/assets/logo-512.png +0 -0
- package/assets/logo-wordmark.svg +35 -0
- package/assets/logo.svg +32 -0
- package/bin/workspace.js +130 -0
- package/dist/cli/ai-prompt.js +421 -0
- package/dist/cli/dashboard/AgentList.js +61 -0
- package/dist/cli/dashboard/DashboardSidebar.js +280 -0
- package/dist/cli/dashboard/HelpFooter.js +73 -0
- package/dist/cli/dashboard/StatusBadge.js +50 -0
- package/dist/cli/dashboard/index.js +11 -0
- package/dist/cli/dashboard/types.js +2 -0
- package/dist/cli/tui.js +48 -0
- package/dist/commands/ai-prompt.js +22 -0
- package/dist/commands/analyze-deps.js +138 -0
- package/dist/commands/archive.js +113 -0
- package/dist/commands/branch/create.js +119 -0
- package/dist/commands/branch/index.js +104 -0
- package/dist/commands/branch/merge.js +90 -0
- package/dist/commands/branch/rebase.js +84 -0
- package/dist/commands/branch/switch.js +165 -0
- package/dist/commands/cache/index.js +80 -0
- package/dist/commands/cache/manager.js +198 -0
- package/dist/commands/cleanup.js +153 -0
- package/dist/commands/configure-claude.js +55 -0
- package/dist/commands/configure.js +231 -0
- package/dist/commands/create.js +204 -0
- package/dist/commands/dashboard/hook-handler.js +162 -0
- package/dist/commands/dashboard/index.js +258 -0
- package/dist/commands/dashboard/launcher.js +40 -0
- package/dist/commands/dashboard/session-picker.js +106 -0
- package/dist/commands/dashboard/sidebar.js +39 -0
- package/dist/commands/dashboard/workspace-picker.js +95 -0
- package/dist/commands/delete.js +194 -0
- package/dist/commands/deprecated-aliases.js +44 -0
- package/dist/commands/diff.js +129 -0
- package/dist/commands/doctor.js +141 -0
- package/dist/commands/generate-docs.js +77 -0
- package/dist/commands/ghq-status.js +72 -0
- package/dist/commands/go.js +154 -0
- package/dist/commands/history.js +124 -0
- package/dist/commands/list.js +191 -0
- package/dist/commands/mcp/index.js +69 -0
- package/dist/commands/migrate.js +296 -0
- package/dist/commands/remove-repo.js +217 -0
- package/dist/commands/report-bug.js +112 -0
- package/dist/commands/run.js +147 -0
- package/dist/commands/save-context.js +171 -0
- package/dist/commands/sessions.js +129 -0
- package/dist/commands/status.js +138 -0
- package/dist/commands/suite/create.js +212 -0
- package/dist/commands/suite/delete.js +64 -0
- package/dist/commands/suite/export.js +126 -0
- package/dist/commands/suite/import.js +128 -0
- package/dist/commands/suite/index.js +94 -0
- package/dist/commands/suite/list.js +49 -0
- package/dist/commands/suite/use.js +227 -0
- package/dist/commands/sync.js +117 -0
- package/dist/commands/update.js +203 -0
- package/dist/mcp/install.js +550 -0
- package/dist/mcp/server.js +398 -0
- package/dist/mcp/tools.js +922 -0
- package/dist/pi-extensions/permission-sync.ts.template +41 -0
- package/dist/pi-extensions/permissions-gate.ts.template +69 -0
- package/dist/pi-extensions/pr-fix-trigger.ts.template +124 -0
- package/dist/pi-extensions/review-reminder.ts.template +58 -0
- package/dist/pi-extensions/workspace-input-status.ts.template +919 -0
- package/dist/program.js +136 -0
- package/dist/scripts/workspace-table.py +394 -0
- package/dist/types/dashboard.js +11 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/agent-config.js +263 -0
- package/dist/utils/agent-state.js +178 -0
- package/dist/utils/banner.js +24 -0
- package/dist/utils/branch-operations.js +232 -0
- package/dist/utils/bug-report.js +355 -0
- package/dist/utils/cache.js +168 -0
- package/dist/utils/claude-integration.js +617 -0
- package/dist/utils/claude-sessions.js +260 -0
- package/dist/utils/cleanup-operations.js +120 -0
- package/dist/utils/colors.js +26 -0
- package/dist/utils/command-helpers.js +44 -0
- package/dist/utils/config.js +150 -0
- package/dist/utils/context-file.js +33 -0
- package/dist/utils/dashboard-hooks.js +172 -0
- package/dist/utils/dependency-analyzer.js +234 -0
- package/dist/utils/diff-operations.js +80 -0
- package/dist/utils/doc-generator.js +184 -0
- package/dist/utils/ghq-integration.js +332 -0
- package/dist/utils/git-operations.js +237 -0
- package/dist/utils/git-status.js +187 -0
- package/dist/utils/github.js +68 -0
- package/dist/utils/health-checks.js +345 -0
- package/dist/utils/history.js +150 -0
- package/dist/utils/hooks.js +100 -0
- package/dist/utils/logger.js +40 -0
- package/dist/utils/permission-sync.js +681 -0
- package/dist/utils/pi-extensions.js +224 -0
- package/dist/utils/progress.js +92 -0
- package/dist/utils/prompts.js +279 -0
- package/dist/utils/repo-resolver.js +260 -0
- package/dist/utils/retry.js +65 -0
- package/dist/utils/run-operations.js +30 -0
- package/dist/utils/suite.js +159 -0
- package/dist/utils/sync-operations.js +107 -0
- package/dist/utils/tmux-dashboard.js +184 -0
- package/dist/utils/validation.js +153 -0
- package/dist/utils/version-check.js +121 -0
- package/dist/utils/workspace-meta.js +185 -0
- package/install-shell-integration.sh +532 -0
- package/install.sh +401 -0
- package/package.json +90 -0
- package/remove-shell-block.awk +44 -0
- package/scripts/postinstall.js +85 -0
- package/skills/analyze-deps.md +23 -0
- package/skills/archive-workspace.md +26 -0
- package/skills/branch-create.md +18 -0
- package/skills/create-workspace.md +39 -0
- package/skills/delete-workspace.md +37 -0
- package/skills/list-org-repos.md +26 -0
- package/skills/list-suites.md +24 -0
- package/skills/list-workspaces.md +27 -0
- package/skills/refresh-workspace-docs.md +89 -0
- package/skills/remove-repo.md +25 -0
- package/skills/run-command.md +23 -0
- package/skills/save-context.md +68 -0
- package/skills/search-repos.md +31 -0
- package/skills/snapshot-list.md +18 -0
- package/skills/snapshot-save.md +12 -0
- package/skills/switch-branch.md +18 -0
- package/skills/update-cache.md +21 -0
- package/skills/update-workspace.md +66 -0
- package/skills/workspace-cleanup.md +18 -0
- package/skills/workspace-diff.md +23 -0
- package/skills/workspace-doctor.md +23 -0
- package/skills/workspace-info.md +45 -0
- package/skills/workspace-manager/SKILL.md +201 -0
- package/skills/workspace-manager/references/ai-prompt.md +44 -0
- package/skills/workspace-manager/references/analyze-deps.md +45 -0
- package/skills/workspace-manager/references/archive-workspace.md +38 -0
- package/skills/workspace-manager/references/branch-create.md +31 -0
- package/skills/workspace-manager/references/branch-merge.md +22 -0
- package/skills/workspace-manager/references/branch-rebase.md +22 -0
- package/skills/workspace-manager/references/cache-clear.md +18 -0
- package/skills/workspace-manager/references/cache-info.md +22 -0
- package/skills/workspace-manager/references/configure-claude.md +31 -0
- package/skills/workspace-manager/references/configure.md +35 -0
- package/skills/workspace-manager/references/create-workspace.md +45 -0
- package/skills/workspace-manager/references/dashboard.md +61 -0
- package/skills/workspace-manager/references/delete-workspace.md +33 -0
- package/skills/workspace-manager/references/generate-docs.md +36 -0
- package/skills/workspace-manager/references/ghq-status.md +28 -0
- package/skills/workspace-manager/references/go.md +33 -0
- package/skills/workspace-manager/references/history.md +41 -0
- package/skills/workspace-manager/references/list-org-repos.md +26 -0
- package/skills/workspace-manager/references/list-suites.md +21 -0
- package/skills/workspace-manager/references/list-workspaces.md +27 -0
- package/skills/workspace-manager/references/mcp.md +49 -0
- package/skills/workspace-manager/references/remove-repo.md +26 -0
- package/skills/workspace-manager/references/run-command.md +44 -0
- package/skills/workspace-manager/references/search-repos.md +24 -0
- package/skills/workspace-manager/references/sessions.md +27 -0
- package/skills/workspace-manager/references/suite-create.md +22 -0
- package/skills/workspace-manager/references/suite-delete.md +21 -0
- package/skills/workspace-manager/references/suite-export.md +19 -0
- package/skills/workspace-manager/references/suite-import.md +19 -0
- package/skills/workspace-manager/references/suite-use.md +27 -0
- package/skills/workspace-manager/references/switch-branch.md +25 -0
- package/skills/workspace-manager/references/update-cache.md +22 -0
- package/skills/workspace-manager/references/update-workspace.md +50 -0
- package/skills/workspace-manager/references/workspace-cleanup.md +33 -0
- package/skills/workspace-manager/references/workspace-diff.md +27 -0
- package/skills/workspace-manager/references/workspace-doctor.md +27 -0
- package/skills/workspace-manager/references/workspace-info.md +33 -0
- package/skills/workspace-manager/references/workspace-status.md +43 -0
- package/skills/workspace-manager/references/workspace-sync.md +26 -0
- package/skills/workspace-status.md +26 -0
- package/skills/workspace-sync.md +23 -0
- package/src/cli/ai-prompt.test.ts +667 -0
- package/src/cli/ai-prompt.ts +421 -0
- package/src/cli/dashboard/AgentList.tsx +44 -0
- package/src/cli/dashboard/DashboardSidebar.tsx +291 -0
- package/src/cli/dashboard/HelpFooter.tsx +22 -0
- package/src/cli/dashboard/StatusBadge.tsx +23 -0
- package/src/cli/dashboard/index.ts +5 -0
- package/src/cli/dashboard/types.ts +16 -0
- package/src/cli/tui.tsx +51 -0
- package/src/cli/workspace-cli.test.ts +30 -0
- package/src/commands/ai-prompt.ts +21 -0
- package/src/commands/analyze-deps.ts +119 -0
- package/src/commands/archive.ts +114 -0
- package/src/commands/branch/create.ts +94 -0
- package/src/commands/branch/index.ts +74 -0
- package/src/commands/branch/merge.ts +61 -0
- package/src/commands/branch/rebase.ts +54 -0
- package/src/commands/branch/switch.ts +150 -0
- package/src/commands/cache/index.ts +51 -0
- package/src/commands/cache/manager.ts +168 -0
- package/src/commands/cleanup.ts +132 -0
- package/src/commands/configure-claude.ts +55 -0
- package/src/commands/configure.ts +204 -0
- package/src/commands/create.ts +196 -0
- package/src/commands/dashboard/hook-handler.ts +138 -0
- package/src/commands/dashboard/index.ts +248 -0
- package/src/commands/dashboard/launcher.ts +42 -0
- package/src/commands/dashboard/session-picker.ts +73 -0
- package/src/commands/dashboard/sidebar.js +39 -0
- package/src/commands/dashboard/workspace-picker.ts +62 -0
- package/src/commands/delete.test.ts +250 -0
- package/src/commands/delete.ts +171 -0
- package/src/commands/deprecated-aliases.ts +55 -0
- package/src/commands/diff.ts +106 -0
- package/src/commands/doctor.ts +110 -0
- package/src/commands/generate-docs.ts +45 -0
- package/src/commands/ghq-status.ts +70 -0
- package/src/commands/go.ts +125 -0
- package/src/commands/history.ts +136 -0
- package/src/commands/list.test.ts +219 -0
- package/src/commands/list.ts +176 -0
- package/src/commands/mcp/index.ts +39 -0
- package/src/commands/migrate.ts +277 -0
- package/src/commands/remove-repo.ts +194 -0
- package/src/commands/report-bug.ts +88 -0
- package/src/commands/run.ts +125 -0
- package/src/commands/save-context.test.ts +113 -0
- package/src/commands/save-context.ts +141 -0
- package/src/commands/sessions.ts +99 -0
- package/src/commands/status.ts +111 -0
- package/src/commands/suite/create.ts +240 -0
- package/src/commands/suite/delete.ts +65 -0
- package/src/commands/suite/export.ts +97 -0
- package/src/commands/suite/import.ts +100 -0
- package/src/commands/suite/index.ts +66 -0
- package/src/commands/suite/list.ts +54 -0
- package/src/commands/suite/use.ts +232 -0
- package/src/commands/sync.ts +97 -0
- package/src/commands/update.ts +197 -0
- package/src/mcp/install.ts +529 -0
- package/src/mcp/server.ts +579 -0
- package/src/mcp/tools.test.ts +545 -0
- package/src/mcp/tools.ts +1019 -0
- package/src/mcp/update-workspace.test.ts +220 -0
- package/src/pi-extensions/permission-sync.ts.template +41 -0
- package/src/pi-extensions/permissions-gate.ts.template +69 -0
- package/src/pi-extensions/pr-fix-trigger.ts.template +124 -0
- package/src/pi-extensions/review-reminder.ts.template +58 -0
- package/src/pi-extensions/workspace-input-status.ts.template +919 -0
- package/src/program.ts +112 -0
- package/src/scripts/workspace-table.py +394 -0
- package/src/types/dashboard.ts +29 -0
- package/src/types/index.ts +109 -0
- package/src/types/ink.d.ts +171 -0
- package/src/utils/agent-config.test.ts +303 -0
- package/src/utils/agent-config.ts +264 -0
- package/src/utils/agent-state.test.ts +166 -0
- package/src/utils/agent-state.ts +135 -0
- package/src/utils/banner.ts +24 -0
- package/src/utils/branch-operations.ts +237 -0
- package/src/utils/bug-report.test.ts +174 -0
- package/src/utils/bug-report.ts +355 -0
- package/src/utils/cache.ts +150 -0
- package/src/utils/claude-integration.test.ts +381 -0
- package/src/utils/claude-integration.ts +649 -0
- package/src/utils/claude-sessions.test.ts +262 -0
- package/src/utils/claude-sessions.ts +251 -0
- package/src/utils/cleanup-operations.ts +94 -0
- package/src/utils/colors.ts +25 -0
- package/src/utils/command-helpers.ts +46 -0
- package/src/utils/config.test.ts +203 -0
- package/src/utils/config.ts +133 -0
- package/src/utils/context-file.ts +36 -0
- package/src/utils/dashboard-hooks.test.ts +168 -0
- package/src/utils/dashboard-hooks.ts +163 -0
- package/src/utils/dependency-analyzer.ts +243 -0
- package/src/utils/diff-operations.ts +59 -0
- package/src/utils/doc-generator.ts +187 -0
- package/src/utils/ghq-integration.test.ts +195 -0
- package/src/utils/ghq-integration.ts +317 -0
- package/src/utils/git-operations.test.ts +265 -0
- package/src/utils/git-operations.ts +233 -0
- package/src/utils/git-status.ts +171 -0
- package/src/utils/github.ts +74 -0
- package/src/utils/health-checks.ts +359 -0
- package/src/utils/history.ts +140 -0
- package/src/utils/hooks.ts +92 -0
- package/src/utils/logger.ts +37 -0
- package/src/utils/permission-sync.test.ts +593 -0
- package/src/utils/permission-sync.ts +720 -0
- package/src/utils/pi-extensions.test.ts +182 -0
- package/src/utils/pi-extensions.ts +226 -0
- package/src/utils/progress.ts +73 -0
- package/src/utils/prompts.test.ts +169 -0
- package/src/utils/prompts.ts +296 -0
- package/src/utils/repo-resolver.test.ts +313 -0
- package/src/utils/repo-resolver.ts +294 -0
- package/src/utils/retry.test.ts +124 -0
- package/src/utils/retry.ts +85 -0
- package/src/utils/run-operations.ts +38 -0
- package/src/utils/suite.test.ts +256 -0
- package/src/utils/suite.ts +144 -0
- package/src/utils/sync-operations.ts +87 -0
- package/src/utils/tmux-dashboard.ts +193 -0
- package/src/utils/validation.test.ts +139 -0
- package/src/utils/validation.ts +128 -0
- package/src/utils/version-check.test.ts +108 -0
- package/src/utils/version-check.ts +96 -0
- package/src/utils/workspace-meta.ts +173 -0
- package/sync-permissions.sh +137 -0
- package/tsconfig.json +20 -0
- package/uninstall.sh +162 -0
|
@@ -0,0 +1,258 @@
|
|
|
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.registerDashboardCommand = registerDashboardCommand;
|
|
37
|
+
const child_process_1 = require("child_process");
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const logger_1 = require("../../utils/logger");
|
|
40
|
+
const colors_1 = require("../../utils/colors");
|
|
41
|
+
const dashboard_hooks_1 = require("../../utils/dashboard-hooks");
|
|
42
|
+
const dashboard_1 = require("../../types/dashboard");
|
|
43
|
+
const agent_state_1 = require("../../utils/agent-state");
|
|
44
|
+
const tmux_dashboard_1 = require("../../utils/tmux-dashboard");
|
|
45
|
+
const agent_config_1 = require("../../utils/agent-config");
|
|
46
|
+
const { sessionName, sidebarWidthPercent } = dashboard_1.DASHBOARD_DEFAULTS;
|
|
47
|
+
function isTmuxAvailable() {
|
|
48
|
+
try {
|
|
49
|
+
(0, child_process_1.execFileSync)('which', ['tmux'], { stdio: 'pipe' });
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function isInsideTmux() {
|
|
57
|
+
return !!process.env.TMUX;
|
|
58
|
+
}
|
|
59
|
+
function registerDashboardCommand(parent) {
|
|
60
|
+
parent
|
|
61
|
+
.command('dashboard')
|
|
62
|
+
.alias('dash')
|
|
63
|
+
.description('Launch multi-agent management dashboard')
|
|
64
|
+
.option('--install-hooks', 'Install Claude status hooks without launching dashboard')
|
|
65
|
+
.option('--uninstall-hooks', 'Remove dashboard hooks from Claude settings')
|
|
66
|
+
.option('--list', 'List running agents as JSON (non-interactive)')
|
|
67
|
+
.option('--status', 'Show agent status summary (non-interactive)')
|
|
68
|
+
.option('--kill <sessionId>', 'Kill agent by session ID (non-interactive)')
|
|
69
|
+
.option('--launch <workspace>', 'Launch a new agent in a workspace (non-interactive)')
|
|
70
|
+
.action(async (opts) => {
|
|
71
|
+
await handleDashboard(opts);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async function handleDashboard(opts) {
|
|
75
|
+
// Handle hook-only commands
|
|
76
|
+
if (opts.installHooks) {
|
|
77
|
+
(0, dashboard_hooks_1.installDashboardHooks)();
|
|
78
|
+
(0, logger_1.logSuccess)('Dashboard hooks installed in ~/.claude/settings.json');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (opts.uninstallHooks) {
|
|
82
|
+
(0, dashboard_hooks_1.uninstallDashboardHooks)();
|
|
83
|
+
(0, logger_1.logSuccess)('Dashboard hooks removed from ~/.claude/settings.json');
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// --list: print running agents as JSON
|
|
87
|
+
if (opts.list) {
|
|
88
|
+
const agents = (0, agent_state_1.readAllAgentStates)().filter(a => a.status !== 'stopped');
|
|
89
|
+
console.log(JSON.stringify(agents, null, 2));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// --status: human-readable status summary
|
|
93
|
+
if (opts.status) {
|
|
94
|
+
const agents = (0, agent_state_1.readAllAgentStates)().filter(a => a.status !== 'stopped');
|
|
95
|
+
if (agents.length === 0) {
|
|
96
|
+
console.log('No agents running.');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
for (const a of agents) {
|
|
100
|
+
console.log(`${(0, colors_1.colorize)(a.workspace, 'cyan')} ${(0, colors_1.colorize)(a.status, 'yellow')} ${a.sessionId.slice(0, 8)}`);
|
|
101
|
+
}
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// --kill: kill agent by session ID
|
|
105
|
+
if (opts.kill) {
|
|
106
|
+
const sessionId = opts.kill;
|
|
107
|
+
const agents = (0, agent_state_1.readAllAgentStates)();
|
|
108
|
+
const agent = agents.find(a => a.sessionId === sessionId || a.sessionId.startsWith(sessionId));
|
|
109
|
+
if (!agent) {
|
|
110
|
+
(0, logger_1.logError)(`No agent found with session ID: ${sessionId}`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
// Try to kill the tmux pane if dashboard is running
|
|
114
|
+
const panes = (0, tmux_dashboard_1.getAgentPanes)();
|
|
115
|
+
const pane = (0, tmux_dashboard_1.findPaneForAgent)(agent, panes);
|
|
116
|
+
if (pane) {
|
|
117
|
+
(0, child_process_1.spawnSync)('tmux', ['kill-pane', '-t', `${sessionName}:0.${pane.index}`], { stdio: 'pipe' });
|
|
118
|
+
setTimeout(() => (0, tmux_dashboard_1.resetLayout)(), 100);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// Kill the process directly (guard: pid 0 would kill entire process group)
|
|
122
|
+
if (agent.pid > 0) {
|
|
123
|
+
try {
|
|
124
|
+
process.kill(agent.pid);
|
|
125
|
+
}
|
|
126
|
+
catch { /* already dead */ }
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
(0, agent_state_1.removeAgentState)(agent.sessionId);
|
|
130
|
+
(0, logger_1.logSuccess)(`Killed agent: ${agent.workspace} (${agent.sessionId.slice(0, 8)})`);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// --launch: launch a new agent in a workspace
|
|
134
|
+
if (opts.launch) {
|
|
135
|
+
const workspaceName = opts.launch;
|
|
136
|
+
const { listWorkspaces } = await Promise.resolve().then(() => __importStar(require('../../utils/workspace-meta')));
|
|
137
|
+
const workspaces = await listWorkspaces();
|
|
138
|
+
const ws = workspaces.find(w => w.name === workspaceName);
|
|
139
|
+
if (!ws) {
|
|
140
|
+
(0, logger_1.logError)(`Workspace not found: ${workspaceName}`);
|
|
141
|
+
(0, logger_1.logInfo)(`Available: ${workspaces.map(w => w.name).join(', ')}`);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
// Check if dashboard is running by verifying the session exists
|
|
145
|
+
const sessionCheck = (0, child_process_1.spawnSync)('tmux', ['has-session', '-t', sessionName], { stdio: 'pipe' });
|
|
146
|
+
if (sessionCheck.status === 0) {
|
|
147
|
+
// Dashboard running — split a pane
|
|
148
|
+
(0, child_process_1.spawnSync)('tmux', [
|
|
149
|
+
'split-window', '-t', `${sessionName}:0`, '-h',
|
|
150
|
+
'-c', ws.path,
|
|
151
|
+
(0, agent_config_1.getPrimaryAgent)().launchCommand,
|
|
152
|
+
], { stdio: 'pipe' });
|
|
153
|
+
(0, child_process_1.spawnSync)('tmux', ['select-layout', '-t', sessionName, 'main-vertical'], { stdio: 'pipe' });
|
|
154
|
+
(0, child_process_1.spawnSync)('tmux', ['resize-pane', '-t', `${sessionName}:0.0`, '-x', '32'], { stdio: 'pipe' });
|
|
155
|
+
(0, logger_1.logSuccess)(`Launched agent in workspace: ${workspaceName}`);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
(0, logger_1.logInfo)(`Dashboard not running. Start it with: w dash`);
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Check tmux for interactive dashboard
|
|
163
|
+
if (!isTmuxAvailable()) {
|
|
164
|
+
(0, logger_1.logError)('tmux is required for the agent dashboard');
|
|
165
|
+
console.log((0, colors_1.colorize)('Install tmux: brew install tmux', 'gray'));
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
// Auto-install hooks if not present
|
|
169
|
+
if (!(0, dashboard_hooks_1.areDashboardHooksInstalled)()) {
|
|
170
|
+
(0, dashboard_hooks_1.installDashboardHooks)();
|
|
171
|
+
(0, logger_1.logInfo)('Installed dashboard hooks in ~/.claude/settings.json');
|
|
172
|
+
}
|
|
173
|
+
// Check if dashboard session already exists — reconnect if so
|
|
174
|
+
const sessionExists = (0, child_process_1.spawnSync)('tmux', [
|
|
175
|
+
'has-session', '-t', sessionName,
|
|
176
|
+
], { stdio: 'pipe' }).status === 0;
|
|
177
|
+
if (sessionExists) {
|
|
178
|
+
(0, logger_1.logInfo)('Reconnecting to existing dashboard session...');
|
|
179
|
+
if (isInsideTmux()) {
|
|
180
|
+
(0, child_process_1.spawnSync)('tmux', ['switch-client', '-t', sessionName], { stdio: 'inherit' });
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
(0, child_process_1.spawnSync)('tmux', ['attach-session', '-t', sessionName], { stdio: 'inherit' });
|
|
184
|
+
}
|
|
185
|
+
(0, logger_1.logSuccess)('Dashboard session ended');
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// Resolve paths to compiled scripts
|
|
189
|
+
const sidebarScript = path.join(__dirname, 'sidebar.js');
|
|
190
|
+
// Create tmux session with sidebar in the left pane
|
|
191
|
+
const newSessionResult = (0, child_process_1.spawnSync)('tmux', [
|
|
192
|
+
'new-session', '-d', '-s', sessionName,
|
|
193
|
+
'-x', '200', '-y', '50',
|
|
194
|
+
`node "${sidebarScript}"`,
|
|
195
|
+
], { stdio: 'pipe' });
|
|
196
|
+
if (newSessionResult.status !== 0) {
|
|
197
|
+
(0, logger_1.logError)('Failed to create tmux session');
|
|
198
|
+
const stderr = newSessionResult.stderr?.toString();
|
|
199
|
+
if (stderr)
|
|
200
|
+
(0, logger_1.logError)(stderr);
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
// Split right pane (80%) with placeholder message
|
|
204
|
+
(0, child_process_1.spawnSync)('tmux', [
|
|
205
|
+
'split-window', '-h', '-t', sessionName,
|
|
206
|
+
'-p', String(100 - sidebarWidthPercent),
|
|
207
|
+
'bash', '-c',
|
|
208
|
+
'echo ""; echo " No agents running."; echo " Press n in the sidebar to launch an agent."; echo ""; sleep infinity',
|
|
209
|
+
], { stdio: 'pipe' });
|
|
210
|
+
// Focus the sidebar pane (left)
|
|
211
|
+
(0, child_process_1.spawnSync)('tmux', ['select-pane', '-t', `${sessionName}:0.0`], { stdio: 'pipe' });
|
|
212
|
+
// ── Session-scoped key bindings ──
|
|
213
|
+
// Use set-hook to add bindings only while this session is active and
|
|
214
|
+
// restore them on detach — avoids polluting global tmux key tables.
|
|
215
|
+
// prefix + M → focus sidebar + reset layout (M chosen to avoid overriding standard keys)
|
|
216
|
+
(0, child_process_1.spawnSync)('tmux', [
|
|
217
|
+
'set-hook', '-t', sessionName, 'session-created',
|
|
218
|
+
`bind-key -T prefix M run-shell "tmux select-layout -t ${sessionName} main-vertical \\\\; resize-pane -t ${sessionName}:0.0 -x 32 \\\\; select-pane -t ${sessionName}:0.0"`,
|
|
219
|
+
], { stdio: 'pipe' });
|
|
220
|
+
// Bind immediately for the current session
|
|
221
|
+
(0, child_process_1.spawnSync)('tmux', [
|
|
222
|
+
'bind-key', '-T', 'prefix', 'M',
|
|
223
|
+
'run-shell',
|
|
224
|
+
`tmux select-layout -t ${sessionName} main-vertical \\; resize-pane -t ${sessionName}:0.0 -x 32 \\; select-pane -t ${sessionName}:0.0`,
|
|
225
|
+
], { stdio: 'pipe' });
|
|
226
|
+
// Unbind prefix+M when the dashboard session ends (cleanup)
|
|
227
|
+
(0, child_process_1.spawnSync)('tmux', [
|
|
228
|
+
'set-hook', '-t', sessionName, 'session-closed',
|
|
229
|
+
'unbind-key -T prefix M',
|
|
230
|
+
], { stdio: 'pipe' });
|
|
231
|
+
// ── Status bar ──
|
|
232
|
+
(0, child_process_1.spawnSync)('tmux', [
|
|
233
|
+
'set-option', '-t', sessionName,
|
|
234
|
+
'status-left', ' 🤖 Agent Dashboard ',
|
|
235
|
+
], { stdio: 'pipe' });
|
|
236
|
+
(0, child_process_1.spawnSync)('tmux', [
|
|
237
|
+
'set-option', '-t', sessionName,
|
|
238
|
+
'status-right', ' prefix+M:sidebar/reset q:detach Q:quit ',
|
|
239
|
+
], { stdio: 'pipe' });
|
|
240
|
+
(0, child_process_1.spawnSync)('tmux', [
|
|
241
|
+
'set-option', '-t', sessionName,
|
|
242
|
+
'status-style', 'bg=colour235,fg=colour255',
|
|
243
|
+
], { stdio: 'pipe' });
|
|
244
|
+
// Enable mouse support for pane selection
|
|
245
|
+
(0, child_process_1.spawnSync)('tmux', [
|
|
246
|
+
'set-option', '-t', sessionName,
|
|
247
|
+
'mouse', 'on',
|
|
248
|
+
], { stdio: 'pipe' });
|
|
249
|
+
(0, logger_1.logInfo)('Launching agent dashboard...');
|
|
250
|
+
// Attach to the session
|
|
251
|
+
if (isInsideTmux()) {
|
|
252
|
+
(0, child_process_1.spawnSync)('tmux', ['switch-client', '-t', sessionName], { stdio: 'inherit' });
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
(0, child_process_1.spawnSync)('tmux', ['attach-session', '-t', sessionName], { stdio: 'inherit' });
|
|
256
|
+
}
|
|
257
|
+
(0, logger_1.logSuccess)('Agent dashboard session ended');
|
|
258
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.launchAgentPane = launchAgentPane;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const dashboard_1 = require("../../types/dashboard");
|
|
6
|
+
const { sessionName } = dashboard_1.DASHBOARD_DEFAULTS;
|
|
7
|
+
/**
|
|
8
|
+
* Launch an agent in the dashboard by spawning a new tmux pane.
|
|
9
|
+
* Kills any placeholder pane (sleep infinity), splits a new pane,
|
|
10
|
+
* and rebalances the layout.
|
|
11
|
+
*
|
|
12
|
+
* @param workspacePath - absolute path to the workspace directory
|
|
13
|
+
* @param command - shell command to run in the new pane (e.g. 'claude' or 'claude --resume <id> --fork-session')
|
|
14
|
+
*/
|
|
15
|
+
function launchAgentPane(workspacePath, command) {
|
|
16
|
+
// Kill placeholder pane (sleep infinity) if present
|
|
17
|
+
const paneResult = (0, child_process_1.spawnSync)('tmux', [
|
|
18
|
+
'list-panes', '-t', sessionName, '-F',
|
|
19
|
+
'#{pane_index} #{pane_current_command}',
|
|
20
|
+
], { stdio: 'pipe' });
|
|
21
|
+
if (paneResult.stdout) {
|
|
22
|
+
const lines = paneResult.stdout.toString().trim().split('\n');
|
|
23
|
+
for (const line of lines) {
|
|
24
|
+
const parts = line.split(' ');
|
|
25
|
+
if (parts[0] !== '0' && parts.slice(1).join(' ').includes('sleep')) {
|
|
26
|
+
(0, child_process_1.spawnSync)('tmux', ['kill-pane', '-t', `${sessionName}:0.${parts[0]}`], { stdio: 'pipe' });
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Create a new pane for the agent
|
|
32
|
+
(0, child_process_1.spawnSync)('tmux', [
|
|
33
|
+
'split-window', '-t', `${sessionName}:0`, '-h',
|
|
34
|
+
'-c', workspacePath,
|
|
35
|
+
command,
|
|
36
|
+
], { stdio: 'pipe' });
|
|
37
|
+
// Rebalance layout: sidebar left, agents stacked right
|
|
38
|
+
(0, child_process_1.spawnSync)('tmux', ['select-layout', '-t', sessionName, 'main-vertical'], { stdio: 'pipe' });
|
|
39
|
+
(0, child_process_1.spawnSync)('tmux', ['resize-pane', '-t', `${sessionName}:0.0`, '-x', '32'], { stdio: 'pipe' });
|
|
40
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Session resume picker for the agent dashboard.
|
|
5
|
+
* Shows recent sessions sorted by last active, launches
|
|
6
|
+
* the appropriate agent CLI with --resume <id> --fork in a new dashboard pane.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
42
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
const claude_sessions_1 = require("../../utils/claude-sessions");
|
|
46
|
+
const launcher_1 = require("./launcher");
|
|
47
|
+
const agent_config_1 = require("../../utils/agent-config");
|
|
48
|
+
const colors_1 = require("../../utils/colors");
|
|
49
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
50
|
+
const inquirer_autocomplete_prompt_1 = __importDefault(require("inquirer-autocomplete-prompt"));
|
|
51
|
+
const fuzzy = __importStar(require("fuzzy"));
|
|
52
|
+
inquirer_1.default.registerPrompt('autocomplete', inquirer_autocomplete_prompt_1.default);
|
|
53
|
+
async function main() {
|
|
54
|
+
try {
|
|
55
|
+
const sessions = await (0, claude_sessions_1.getWorkspaceSessions)();
|
|
56
|
+
if (sessions.length === 0) {
|
|
57
|
+
console.log('No sessions found. Launch a new agent with n.');
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
const items = sessions.map(session => ({
|
|
61
|
+
session,
|
|
62
|
+
displayName: session.workspaceName,
|
|
63
|
+
timeLabel: session.lastActiveLabel,
|
|
64
|
+
}));
|
|
65
|
+
const { selected } = await inquirer_1.default.prompt([{
|
|
66
|
+
type: 'autocomplete',
|
|
67
|
+
name: 'selected',
|
|
68
|
+
message: 'Select session to resume:',
|
|
69
|
+
source: async (_answersSoFar, input) => {
|
|
70
|
+
const searchInput = input || '';
|
|
71
|
+
const source = items.map(item => ({
|
|
72
|
+
name: `${item.displayName} ${(0, colors_1.colorize)(item.timeLabel, 'dim')}`,
|
|
73
|
+
value: item,
|
|
74
|
+
}));
|
|
75
|
+
if (!searchInput)
|
|
76
|
+
return source;
|
|
77
|
+
const results = fuzzy.filter(searchInput, items, { extract: (item) => item.displayName });
|
|
78
|
+
return results.map(result => ({
|
|
79
|
+
name: `${result.original.displayName} ${(0, colors_1.colorize)(result.original.timeLabel, 'dim')}`,
|
|
80
|
+
value: result.original,
|
|
81
|
+
}));
|
|
82
|
+
},
|
|
83
|
+
pageSize: 15,
|
|
84
|
+
}]);
|
|
85
|
+
const item = selected;
|
|
86
|
+
const session = item.session;
|
|
87
|
+
const rawSessionId = session.sessionId;
|
|
88
|
+
// Sanitize session ID before interpolating into shell command
|
|
89
|
+
if (!/^[a-zA-Z0-9\-]{1,100}$/.test(rawSessionId)) {
|
|
90
|
+
console.error('Invalid session ID format — skipping');
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
// Use the session's agent type for resume, fall back to primary if missing
|
|
94
|
+
// (sessions from before the multi-agent upgrade won't have agentType)
|
|
95
|
+
const agentType = session.agentType || (0, agent_config_1.getPrimaryAgent)().type;
|
|
96
|
+
const agent = (0, agent_config_1.getAgentPaths)(agentType);
|
|
97
|
+
(0, launcher_1.launchAgentPane)(session.workspacePath, agent.resumeCommand(rawSessionId));
|
|
98
|
+
console.log(`\nResuming ${agentType} session in ${session.workspaceName}`);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
if (error?.name === 'ExitPromptError')
|
|
102
|
+
process.exit(0);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
main();
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Dashboard sidebar entry point.
|
|
4
|
+
*
|
|
5
|
+
* This is a plain .js file (not .ts) to preserve the real dynamic import().
|
|
6
|
+
* TypeScript compiles `await import('ink')` into `require('ink')` in CJS mode,
|
|
7
|
+
* which fails because ink v5 is ESM-only with top-level await.
|
|
8
|
+
*
|
|
9
|
+
* By keeping this as .js, tsc copies it as-is to dist/ and the real
|
|
10
|
+
* import() call is preserved at runtime.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
async function main() {
|
|
14
|
+
try {
|
|
15
|
+
const React = require('react');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
|
|
18
|
+
// Real dynamic ESM import — NOT compiled by tsc
|
|
19
|
+
const { render, Box, Text, useInput, useApp } = await import('ink');
|
|
20
|
+
|
|
21
|
+
// CJS require for our compiled TSX components
|
|
22
|
+
const { DashboardSidebar } = require(path.join(__dirname, '..', '..', 'cli', 'dashboard'));
|
|
23
|
+
|
|
24
|
+
const App = () => React.createElement(DashboardSidebar, {
|
|
25
|
+
Box,
|
|
26
|
+
Text,
|
|
27
|
+
useInput,
|
|
28
|
+
useApp,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
render(React.createElement(App), { exitOnCtrlC: false });
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error('Dashboard sidebar failed to start:', error.message);
|
|
34
|
+
// Keep the pane alive so user can see the error
|
|
35
|
+
await new Promise(() => {});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
main();
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Workspace picker for the agent dashboard.
|
|
5
|
+
* Runs inside a tmux popup — lets the user select a workspace,
|
|
6
|
+
* then spawns a fresh claude agent pane in the dashboard session.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
42
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
const workspace_meta_1 = require("../../utils/workspace-meta");
|
|
46
|
+
const launcher_1 = require("./launcher");
|
|
47
|
+
const agent_config_1 = require("../../utils/agent-config");
|
|
48
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
49
|
+
const inquirer_autocomplete_prompt_1 = __importDefault(require("inquirer-autocomplete-prompt"));
|
|
50
|
+
const fuzzy = __importStar(require("fuzzy"));
|
|
51
|
+
inquirer_1.default.registerPrompt('autocomplete', inquirer_autocomplete_prompt_1.default);
|
|
52
|
+
async function main() {
|
|
53
|
+
try {
|
|
54
|
+
const workspaces = await (0, workspace_meta_1.listWorkspaces)();
|
|
55
|
+
if (workspaces.length === 0) {
|
|
56
|
+
console.log('No workspaces found. Create one with: workspace create');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
const items = workspaces.map(ws => ({
|
|
60
|
+
name: ws.name,
|
|
61
|
+
path: ws.path,
|
|
62
|
+
repoCount: ws.metadata?.repositories?.length ?? 0,
|
|
63
|
+
}));
|
|
64
|
+
const { selected } = await inquirer_1.default.prompt([{
|
|
65
|
+
type: 'autocomplete',
|
|
66
|
+
name: 'selected',
|
|
67
|
+
message: 'Select workspace to launch agent in:',
|
|
68
|
+
source: async (_answersSoFar, input) => {
|
|
69
|
+
const searchInput = input || '';
|
|
70
|
+
const source = items.map(item => ({
|
|
71
|
+
name: `${item.name} (${item.repoCount} repos)`,
|
|
72
|
+
value: item,
|
|
73
|
+
}));
|
|
74
|
+
if (!searchInput)
|
|
75
|
+
return source;
|
|
76
|
+
const results = fuzzy.filter(searchInput, items, { extract: (item) => item.name });
|
|
77
|
+
return results.map(result => ({
|
|
78
|
+
name: `${result.original.name} (${result.original.repoCount} repos)`,
|
|
79
|
+
value: result.original,
|
|
80
|
+
}));
|
|
81
|
+
},
|
|
82
|
+
pageSize: 15,
|
|
83
|
+
}]);
|
|
84
|
+
const workspace = selected;
|
|
85
|
+
const agent = (0, agent_config_1.getPrimaryAgent)();
|
|
86
|
+
(0, launcher_1.launchAgentPane)(workspace.path, agent.launchCommand);
|
|
87
|
+
console.log(`\nLaunched agent in ${workspace.name}`);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (error?.name === 'ExitPromptError')
|
|
91
|
+
process.exit(0);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
main();
|