@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,579 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
|
|
7
|
+
// Traversal-safe name for any parameter used to build a filesystem path (a
|
|
8
|
+
// workspace name). Blocks path separators, drive letters, "."/".." and NUL, so an
|
|
9
|
+
// MCP client cannot escape the workspaces sandbox; spaces are allowed because the
|
|
10
|
+
// create path sanitizes them to hyphens. Handlers still call safeWorkspacePath()
|
|
11
|
+
// as the authoritative check 2014 this is defense in depth with a clean client error.
|
|
12
|
+
const WS_NAME_RE = /^[A-Za-z0-9 _-]+$/;
|
|
13
|
+
const wsName = z.string().min(1).max(64).regex(WS_NAME_RE, 'may contain only letters, numbers, spaces, hyphens, and underscores (no path separators, "..", or other special characters)');
|
|
14
|
+
import {
|
|
15
|
+
handleListWorkspaces,
|
|
16
|
+
handleWorkspaceStatus,
|
|
17
|
+
handleWorkspaceDiff,
|
|
18
|
+
handleWorkspaceSync,
|
|
19
|
+
handleRunCommand,
|
|
20
|
+
handleListSuites,
|
|
21
|
+
handleWorkspaceInfo,
|
|
22
|
+
handleCreateWorkspace,
|
|
23
|
+
handleUpdateWorkspace,
|
|
24
|
+
handleSearchRepos,
|
|
25
|
+
handleListOrgRepos,
|
|
26
|
+
handleDeleteWorkspace,
|
|
27
|
+
handleRemoveRepo,
|
|
28
|
+
handleWorkspaceDoctor,
|
|
29
|
+
handleAnalyzeDeps,
|
|
30
|
+
handleBranchCreate,
|
|
31
|
+
handleSwitchBranch,
|
|
32
|
+
handleWorkspaceCleanup,
|
|
33
|
+
handleUpdateCache,
|
|
34
|
+
handleArchiveWorkspace,
|
|
35
|
+
handleUnarchiveWorkspace,
|
|
36
|
+
handleBranchMerge,
|
|
37
|
+
handleBranchRebase,
|
|
38
|
+
handleSuiteCreate,
|
|
39
|
+
handleSuiteDelete,
|
|
40
|
+
handleSuiteExport,
|
|
41
|
+
handleSuiteImport,
|
|
42
|
+
handleSuiteUse,
|
|
43
|
+
handleSaveContext,
|
|
44
|
+
} from './tools';
|
|
45
|
+
|
|
46
|
+
import { getPackageVersion } from '../utils/config';
|
|
47
|
+
|
|
48
|
+
const server = new McpServer({
|
|
49
|
+
name: 'workspace-manager',
|
|
50
|
+
version: getPackageVersion(),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
server.tool(
|
|
54
|
+
'list-workspaces',
|
|
55
|
+
'List all workspaces with their repo counts and creation dates',
|
|
56
|
+
{
|
|
57
|
+
includeArchived: z.boolean().optional().default(false).describe('Include archived workspaces in the listing'),
|
|
58
|
+
},
|
|
59
|
+
async ({ includeArchived }) => {
|
|
60
|
+
try {
|
|
61
|
+
const result = await handleListWorkspaces(includeArchived);
|
|
62
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
63
|
+
} catch (error) {
|
|
64
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
65
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
server.tool(
|
|
71
|
+
'archive-workspace',
|
|
72
|
+
'Archive a workspace so it is hidden from default listing. Archived workspaces auto-delete after 30 days.',
|
|
73
|
+
{
|
|
74
|
+
workspace: wsName.describe('Name of the workspace to archive'),
|
|
75
|
+
},
|
|
76
|
+
async ({ workspace }) => {
|
|
77
|
+
try {
|
|
78
|
+
const result = await handleArchiveWorkspace(workspace);
|
|
79
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
80
|
+
} catch (error) {
|
|
81
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
82
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
server.tool(
|
|
88
|
+
'unarchive-workspace',
|
|
89
|
+
'Unarchive a previously archived workspace, making it active again',
|
|
90
|
+
{
|
|
91
|
+
workspace: wsName.describe('Name of the workspace to unarchive'),
|
|
92
|
+
},
|
|
93
|
+
async ({ workspace }) => {
|
|
94
|
+
try {
|
|
95
|
+
const result = await handleUnarchiveWorkspace(workspace);
|
|
96
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
97
|
+
} catch (error) {
|
|
98
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
99
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
server.tool(
|
|
105
|
+
'workspace-status',
|
|
106
|
+
'Show git status (branch, clean/dirty, ahead/behind) for all repos in a workspace',
|
|
107
|
+
{ workspace: wsName.describe('Name of the workspace') },
|
|
108
|
+
async ({ workspace }) => {
|
|
109
|
+
try {
|
|
110
|
+
const result = await handleWorkspaceStatus(workspace);
|
|
111
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
112
|
+
} catch (error) {
|
|
113
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
114
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
server.tool(
|
|
120
|
+
'workspace-diff',
|
|
121
|
+
'Show diff summary (staged/unstaged file counts, insertions, deletions) for all repos in a workspace',
|
|
122
|
+
{
|
|
123
|
+
workspace: wsName.describe('Name of the workspace'),
|
|
124
|
+
full: z.boolean().optional().describe('Include full diff output'),
|
|
125
|
+
},
|
|
126
|
+
async ({ workspace, full }) => {
|
|
127
|
+
try {
|
|
128
|
+
const result = await handleWorkspaceDiff(workspace, full);
|
|
129
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
130
|
+
} catch (error) {
|
|
131
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
132
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
server.tool(
|
|
138
|
+
'workspace-sync',
|
|
139
|
+
'Git pull all repos in a workspace (skips repos with uncommitted changes)',
|
|
140
|
+
{ workspace: wsName.describe('Name of the workspace') },
|
|
141
|
+
async ({ workspace }) => {
|
|
142
|
+
try {
|
|
143
|
+
const result = await handleWorkspaceSync(workspace);
|
|
144
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
145
|
+
} catch (error) {
|
|
146
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
147
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
server.tool(
|
|
153
|
+
'run-command',
|
|
154
|
+
'Run a shell command across all repos in a workspace (3 concurrent, 5min timeout)',
|
|
155
|
+
{
|
|
156
|
+
workspace: wsName.describe('Name of the workspace'),
|
|
157
|
+
command: z.string().describe('Shell command to run in each repo'),
|
|
158
|
+
},
|
|
159
|
+
async ({ workspace, command }) => {
|
|
160
|
+
try {
|
|
161
|
+
const result = await handleRunCommand(workspace, command);
|
|
162
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
163
|
+
} catch (error) {
|
|
164
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
165
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
server.tool(
|
|
171
|
+
'list-suites',
|
|
172
|
+
'List all saved suites (reusable repo collections) with their repo counts',
|
|
173
|
+
{},
|
|
174
|
+
async () => {
|
|
175
|
+
try {
|
|
176
|
+
const result = await handleListSuites();
|
|
177
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
178
|
+
} catch (error) {
|
|
179
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
180
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
server.tool(
|
|
186
|
+
'workspace-info',
|
|
187
|
+
'Get detailed metadata for a workspace including all repository info, dependencies, and tags',
|
|
188
|
+
{ workspace: wsName.describe('Name of the workspace') },
|
|
189
|
+
async ({ workspace }) => {
|
|
190
|
+
try {
|
|
191
|
+
const result = await handleWorkspaceInfo(workspace);
|
|
192
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
193
|
+
} catch (error) {
|
|
194
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
195
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
server.tool(
|
|
201
|
+
'create-workspace',
|
|
202
|
+
'Create a new workspace by cloning specified repositories. Provide the workspace name and an array of repository names (e.g., ["api", "web", "shared-lib"]).',
|
|
203
|
+
{
|
|
204
|
+
workspace: wsName.describe('Name of the workspace to create'),
|
|
205
|
+
repos: z.array(z.string()).describe('Array of repository names to clone'),
|
|
206
|
+
},
|
|
207
|
+
async ({ workspace, repos }) => {
|
|
208
|
+
try {
|
|
209
|
+
const result = await handleCreateWorkspace(workspace, repos);
|
|
210
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
211
|
+
} catch (error) {
|
|
212
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
213
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
server.tool(
|
|
219
|
+
'update-workspace',
|
|
220
|
+
'Add repositories to an existing workspace. Provide the workspace name and an array of repository names to add. Each entry can be a string (e.g., "partnerships-api") or an object with name and suffix (e.g., {"name": "partnerships-api", "suffix": "v2"}) to add the same repo again under a different directory name (partnerships-api-v2). Skips repos whose target directory name already exists in the workspace.',
|
|
221
|
+
{
|
|
222
|
+
workspace: wsName.describe('Name of the existing workspace to update'),
|
|
223
|
+
repos: z.array(z.union([
|
|
224
|
+
z.string(),
|
|
225
|
+
z.object({
|
|
226
|
+
name: z.string().describe('repository name'),
|
|
227
|
+
suffix: z.string().describe('Suffix to append to directory name (e.g., "v2" creates "repo-name-v2")'),
|
|
228
|
+
}),
|
|
229
|
+
])).describe('Array of repo names (strings) or objects with {name, suffix} for adding duplicate repos under a different directory'),
|
|
230
|
+
},
|
|
231
|
+
async ({ workspace, repos }) => {
|
|
232
|
+
try {
|
|
233
|
+
const result = await handleUpdateWorkspace(workspace, repos);
|
|
234
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
235
|
+
} catch (error) {
|
|
236
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
237
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
server.tool(
|
|
243
|
+
'search-repos',
|
|
244
|
+
'Search org repositories by name or description using fuzzy matching',
|
|
245
|
+
{
|
|
246
|
+
query: z.string().describe('Search query to match against repo names and descriptions'),
|
|
247
|
+
limit: z.number().optional().default(20).describe('Maximum number of results to return'),
|
|
248
|
+
},
|
|
249
|
+
async ({ query, limit }) => {
|
|
250
|
+
try {
|
|
251
|
+
const result = await handleSearchRepos(query, limit);
|
|
252
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
253
|
+
} catch (error) {
|
|
254
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
255
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
server.tool(
|
|
261
|
+
'list-org-repos',
|
|
262
|
+
'List all organization repositories from GitHub',
|
|
263
|
+
{
|
|
264
|
+
forceRefresh: z.boolean().optional().default(false).describe('Force refresh the cached repo list'),
|
|
265
|
+
},
|
|
266
|
+
async ({ forceRefresh }) => {
|
|
267
|
+
try {
|
|
268
|
+
const result = await handleListOrgRepos(forceRefresh);
|
|
269
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
270
|
+
} catch (error) {
|
|
271
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
272
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
server.tool(
|
|
278
|
+
'delete-workspace',
|
|
279
|
+
'Delete one or more workspaces and all their contents permanently. Works even if a workspace has no repos or no metadata file.',
|
|
280
|
+
{
|
|
281
|
+
workspaces: z.union([
|
|
282
|
+
wsName,
|
|
283
|
+
z.array(wsName),
|
|
284
|
+
]).describe('Name of the workspace(s) to delete — a single string or an array of names'),
|
|
285
|
+
},
|
|
286
|
+
async ({ workspaces }) => {
|
|
287
|
+
try {
|
|
288
|
+
const result = await handleDeleteWorkspace(workspaces);
|
|
289
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
290
|
+
} catch (error) {
|
|
291
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
292
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
server.tool(
|
|
298
|
+
'remove-repo',
|
|
299
|
+
'Remove a repository from a workspace',
|
|
300
|
+
{
|
|
301
|
+
workspace: wsName.describe('Name of the workspace'),
|
|
302
|
+
repo: z.string().describe('Directory name of the repository to remove'),
|
|
303
|
+
},
|
|
304
|
+
async ({ workspace, repo }) => {
|
|
305
|
+
try {
|
|
306
|
+
const result = await handleRemoveRepo(workspace, repo);
|
|
307
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
308
|
+
} catch (error) {
|
|
309
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
310
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
server.tool(
|
|
316
|
+
'workspace-doctor',
|
|
317
|
+
'Run health checks on a workspace and return a health score (0-100)',
|
|
318
|
+
{
|
|
319
|
+
workspace: wsName.describe('Name of the workspace to check'),
|
|
320
|
+
},
|
|
321
|
+
async ({ workspace }) => {
|
|
322
|
+
try {
|
|
323
|
+
const result = await handleWorkspaceDoctor(workspace);
|
|
324
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
325
|
+
} catch (error) {
|
|
326
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
327
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
server.tool(
|
|
333
|
+
'analyze-deps',
|
|
334
|
+
'Analyze inter-repository dependencies within a workspace and detect circular dependencies',
|
|
335
|
+
{
|
|
336
|
+
workspace: wsName.describe('Name of the workspace to analyze'),
|
|
337
|
+
},
|
|
338
|
+
async ({ workspace }) => {
|
|
339
|
+
try {
|
|
340
|
+
const result = await handleAnalyzeDeps(workspace);
|
|
341
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
342
|
+
} catch (error) {
|
|
343
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
344
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
server.tool(
|
|
350
|
+
'branch-create',
|
|
351
|
+
'Create a new branch across all repos in a workspace',
|
|
352
|
+
{
|
|
353
|
+
workspace: wsName.describe('Name of the workspace'),
|
|
354
|
+
branchName: z.string().describe('Name of the new branch to create'),
|
|
355
|
+
baseBranch: z.string().optional().describe('Base branch to create from (defaults to current branch)'),
|
|
356
|
+
},
|
|
357
|
+
async ({ workspace, branchName, baseBranch }) => {
|
|
358
|
+
try {
|
|
359
|
+
const result = await handleBranchCreate(workspace, branchName, baseBranch);
|
|
360
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
361
|
+
} catch (error) {
|
|
362
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
363
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
server.tool(
|
|
369
|
+
'switch-branch',
|
|
370
|
+
'Switch all repos in a workspace to a specified branch',
|
|
371
|
+
{
|
|
372
|
+
workspace: wsName.describe('Name of the workspace'),
|
|
373
|
+
branch: z.string().describe('Target branch to switch to'),
|
|
374
|
+
},
|
|
375
|
+
async ({ workspace, branch }) => {
|
|
376
|
+
try {
|
|
377
|
+
const result = await handleSwitchBranch(workspace, branch);
|
|
378
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
379
|
+
} catch (error) {
|
|
380
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
381
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
server.tool(
|
|
387
|
+
'workspace-cleanup',
|
|
388
|
+
'Remove node_modules and build artifacts from all repos in a workspace to free disk space',
|
|
389
|
+
{
|
|
390
|
+
workspace: wsName.describe('Name of the workspace'),
|
|
391
|
+
includeNodeModules: z.boolean().optional().default(true).describe('Remove node_modules directories'),
|
|
392
|
+
includeBuildArtifacts: z.boolean().optional().default(true).describe('Remove build artifact directories (dist, build, .next, coverage, out)'),
|
|
393
|
+
},
|
|
394
|
+
async ({ workspace, includeNodeModules, includeBuildArtifacts }) => {
|
|
395
|
+
try {
|
|
396
|
+
const result = await handleWorkspaceCleanup(workspace, includeNodeModules, includeBuildArtifacts);
|
|
397
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
398
|
+
} catch (error) {
|
|
399
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
400
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
server.tool(
|
|
406
|
+
'update-cache',
|
|
407
|
+
'Force refresh the GitHub repository cache so newly added repos become searchable',
|
|
408
|
+
{},
|
|
409
|
+
async () => {
|
|
410
|
+
try {
|
|
411
|
+
const result = await handleUpdateCache();
|
|
412
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
413
|
+
} catch (error) {
|
|
414
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
415
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
);
|
|
419
|
+
|
|
420
|
+
// --- Branch merge/rebase ---
|
|
421
|
+
|
|
422
|
+
server.tool(
|
|
423
|
+
'branch-merge',
|
|
424
|
+
'Merge a source branch into a target branch across all repos in a workspace',
|
|
425
|
+
{
|
|
426
|
+
workspace: wsName.describe('Name of the workspace'),
|
|
427
|
+
sourceBranch: z.string().describe('Branch to merge from'),
|
|
428
|
+
targetBranch: z.string().describe('Branch to merge into'),
|
|
429
|
+
strategy: z.enum(['no-ff', 'ff-only', 'squash']).optional().describe('Merge strategy'),
|
|
430
|
+
},
|
|
431
|
+
async ({ workspace, sourceBranch, targetBranch, strategy }) => {
|
|
432
|
+
try {
|
|
433
|
+
const result = await handleBranchMerge(workspace, sourceBranch, targetBranch, strategy);
|
|
434
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
435
|
+
} catch (error) {
|
|
436
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
437
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
);
|
|
441
|
+
|
|
442
|
+
server.tool(
|
|
443
|
+
'branch-rebase',
|
|
444
|
+
'Rebase all repos in a workspace onto a target branch',
|
|
445
|
+
{
|
|
446
|
+
workspace: wsName.describe('Name of the workspace'),
|
|
447
|
+
targetBranch: z.string().describe('Branch to rebase onto'),
|
|
448
|
+
},
|
|
449
|
+
async ({ workspace, targetBranch }) => {
|
|
450
|
+
try {
|
|
451
|
+
const result = await handleBranchRebase(workspace, targetBranch);
|
|
452
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
453
|
+
} catch (error) {
|
|
454
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
455
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
);
|
|
459
|
+
|
|
460
|
+
// --- Suite operations ---
|
|
461
|
+
|
|
462
|
+
server.tool(
|
|
463
|
+
'suite-create',
|
|
464
|
+
'Create a new suite (reusable collection of repositories)',
|
|
465
|
+
{
|
|
466
|
+
name: z.string().describe('Name for the new suite'),
|
|
467
|
+
repos: z.array(z.string()).describe('Array of repository names to include'),
|
|
468
|
+
description: z.string().optional().describe('Optional description of the suite'),
|
|
469
|
+
},
|
|
470
|
+
async ({ name, repos, description }) => {
|
|
471
|
+
try {
|
|
472
|
+
const result = await handleSuiteCreate(name, repos, description);
|
|
473
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
474
|
+
} catch (error) {
|
|
475
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
476
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
);
|
|
480
|
+
|
|
481
|
+
server.tool(
|
|
482
|
+
'suite-delete',
|
|
483
|
+
'Delete a saved suite',
|
|
484
|
+
{
|
|
485
|
+
name: z.string().describe('Name of the suite to delete'),
|
|
486
|
+
},
|
|
487
|
+
async ({ name }) => {
|
|
488
|
+
try {
|
|
489
|
+
const result = await handleSuiteDelete(name);
|
|
490
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
491
|
+
} catch (error) {
|
|
492
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
493
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
);
|
|
497
|
+
|
|
498
|
+
server.tool(
|
|
499
|
+
'suite-export',
|
|
500
|
+
'Export suite(s) as JSON. Omit name to export all suites.',
|
|
501
|
+
{
|
|
502
|
+
name: z.string().optional().describe('Name of a specific suite to export (omit for all)'),
|
|
503
|
+
},
|
|
504
|
+
async ({ name }) => {
|
|
505
|
+
try {
|
|
506
|
+
const result = await handleSuiteExport(name);
|
|
507
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
508
|
+
} catch (error) {
|
|
509
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
510
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
);
|
|
514
|
+
|
|
515
|
+
server.tool(
|
|
516
|
+
'suite-import',
|
|
517
|
+
'Import suites from a JSON string (same format as suite-export output)',
|
|
518
|
+
{
|
|
519
|
+
content: z.string().describe('JSON string containing suites to import'),
|
|
520
|
+
overwrite: z.boolean().optional().default(false).describe('Overwrite existing suites with same name'),
|
|
521
|
+
},
|
|
522
|
+
async ({ content, overwrite }) => {
|
|
523
|
+
try {
|
|
524
|
+
const result = await handleSuiteImport(content, overwrite);
|
|
525
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
526
|
+
} catch (error) {
|
|
527
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
528
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
);
|
|
532
|
+
|
|
533
|
+
server.tool(
|
|
534
|
+
'suite-use',
|
|
535
|
+
'Create a new workspace from a saved suite',
|
|
536
|
+
{
|
|
537
|
+
suite: z.string().describe('Name of the suite to use'),
|
|
538
|
+
workspace: wsName.describe('Name for the new workspace to create'),
|
|
539
|
+
},
|
|
540
|
+
async ({ suite, workspace }) => {
|
|
541
|
+
try {
|
|
542
|
+
const result = await handleSuiteUse(suite, workspace);
|
|
543
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
544
|
+
} catch (error) {
|
|
545
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
546
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
);
|
|
550
|
+
|
|
551
|
+
server.tool(
|
|
552
|
+
'save-context',
|
|
553
|
+
'Save a progress summary to the workspace. Use this to persist important context that should survive /clear or session restarts. The content is saved to CONTEXT.md in the workspace root.',
|
|
554
|
+
{
|
|
555
|
+
workspace: wsName.describe('Name of the workspace'),
|
|
556
|
+
content: z.string().describe('The progress summary or context to save (markdown supported)'),
|
|
557
|
+
append: z.boolean().optional().describe('Append to existing context instead of replacing (default: false)'),
|
|
558
|
+
},
|
|
559
|
+
async ({ workspace, content, append }) => {
|
|
560
|
+
try {
|
|
561
|
+
const result = await handleSaveContext(workspace, content, append);
|
|
562
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
563
|
+
} catch (error) {
|
|
564
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
565
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
);
|
|
569
|
+
|
|
570
|
+
async function main() {
|
|
571
|
+
const transport = new StdioServerTransport();
|
|
572
|
+
await server.connect(transport);
|
|
573
|
+
process.stderr.write('workspace-manager MCP server started\n');
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
main().catch((error) => {
|
|
577
|
+
process.stderr.write(`MCP server error: ${error}\n`);
|
|
578
|
+
process.exit(1);
|
|
579
|
+
});
|