gitx.do 0.0.1 → 0.0.3
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/dist/cli/commands/blame.d.ts +259 -0
- package/dist/cli/commands/blame.d.ts.map +1 -0
- package/dist/cli/commands/blame.js +609 -0
- package/dist/cli/commands/blame.js.map +1 -0
- package/dist/cli/commands/branch.d.ts +249 -0
- package/dist/cli/commands/branch.d.ts.map +1 -0
- package/dist/cli/commands/branch.js +693 -0
- package/dist/cli/commands/branch.js.map +1 -0
- package/dist/cli/commands/commit.d.ts +182 -0
- package/dist/cli/commands/commit.d.ts.map +1 -0
- package/dist/cli/commands/commit.js +437 -0
- package/dist/cli/commands/commit.js.map +1 -0
- package/dist/cli/commands/diff.d.ts +464 -0
- package/dist/cli/commands/diff.d.ts.map +1 -0
- package/dist/cli/commands/diff.js +958 -0
- package/dist/cli/commands/diff.js.map +1 -0
- package/dist/cli/commands/log.d.ts +239 -0
- package/dist/cli/commands/log.d.ts.map +1 -0
- package/dist/cli/commands/log.js +535 -0
- package/dist/cli/commands/log.js.map +1 -0
- package/dist/cli/commands/review.d.ts +457 -0
- package/dist/cli/commands/review.d.ts.map +1 -0
- package/dist/cli/commands/review.js +533 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/status.d.ts +269 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +493 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/web.d.ts +199 -0
- package/dist/cli/commands/web.d.ts.map +1 -0
- package/dist/cli/commands/web.js +696 -0
- package/dist/cli/commands/web.js.map +1 -0
- package/dist/cli/fs-adapter.d.ts +656 -0
- package/dist/cli/fs-adapter.d.ts.map +1 -0
- package/dist/cli/fs-adapter.js +1179 -0
- package/dist/cli/fs-adapter.js.map +1 -0
- package/dist/cli/index.d.ts +387 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +523 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ui/components/DiffView.d.ts +7 -0
- package/dist/cli/ui/components/DiffView.d.ts.map +1 -0
- package/dist/cli/ui/components/DiffView.js +11 -0
- package/dist/cli/ui/components/DiffView.js.map +1 -0
- package/dist/cli/ui/components/ErrorDisplay.d.ts +6 -0
- package/dist/cli/ui/components/ErrorDisplay.d.ts.map +1 -0
- package/dist/cli/ui/components/ErrorDisplay.js +11 -0
- package/dist/cli/ui/components/ErrorDisplay.js.map +1 -0
- package/dist/cli/ui/components/FuzzySearch.d.ts +9 -0
- package/dist/cli/ui/components/FuzzySearch.d.ts.map +1 -0
- package/dist/cli/ui/components/FuzzySearch.js +12 -0
- package/dist/cli/ui/components/FuzzySearch.js.map +1 -0
- package/dist/cli/ui/components/LoadingSpinner.d.ts +6 -0
- package/dist/cli/ui/components/LoadingSpinner.d.ts.map +1 -0
- package/dist/cli/ui/components/LoadingSpinner.js +10 -0
- package/dist/cli/ui/components/LoadingSpinner.js.map +1 -0
- package/dist/cli/ui/components/NavigationList.d.ts +9 -0
- package/dist/cli/ui/components/NavigationList.d.ts.map +1 -0
- package/dist/cli/ui/components/NavigationList.js +11 -0
- package/dist/cli/ui/components/NavigationList.js.map +1 -0
- package/dist/cli/ui/components/ScrollableContent.d.ts +8 -0
- package/dist/cli/ui/components/ScrollableContent.d.ts.map +1 -0
- package/dist/cli/ui/components/ScrollableContent.js +11 -0
- package/dist/cli/ui/components/ScrollableContent.js.map +1 -0
- package/dist/cli/ui/components/index.d.ts +7 -0
- package/dist/cli/ui/components/index.d.ts.map +1 -0
- package/dist/cli/ui/components/index.js +9 -0
- package/dist/cli/ui/components/index.js.map +1 -0
- package/dist/cli/ui/terminal-ui.d.ts +52 -0
- package/dist/cli/ui/terminal-ui.d.ts.map +1 -0
- package/dist/cli/ui/terminal-ui.js +121 -0
- package/dist/cli/ui/terminal-ui.js.map +1 -0
- package/dist/durable-object/object-store.d.ts +401 -23
- package/dist/durable-object/object-store.d.ts.map +1 -1
- package/dist/durable-object/object-store.js +414 -25
- package/dist/durable-object/object-store.js.map +1 -1
- package/dist/durable-object/schema.d.ts +188 -0
- package/dist/durable-object/schema.d.ts.map +1 -1
- package/dist/durable-object/schema.js +160 -0
- package/dist/durable-object/schema.js.map +1 -1
- package/dist/durable-object/wal.d.ts +336 -31
- package/dist/durable-object/wal.d.ts.map +1 -1
- package/dist/durable-object/wal.js +272 -27
- package/dist/durable-object/wal.js.map +1 -1
- package/dist/index.d.ts +379 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +379 -7
- package/dist/index.js.map +1 -1
- package/dist/mcp/adapter.d.ts +579 -38
- package/dist/mcp/adapter.d.ts.map +1 -1
- package/dist/mcp/adapter.js +426 -33
- package/dist/mcp/adapter.js.map +1 -1
- package/dist/mcp/sandbox.d.ts +532 -29
- package/dist/mcp/sandbox.d.ts.map +1 -1
- package/dist/mcp/sandbox.js +389 -22
- package/dist/mcp/sandbox.js.map +1 -1
- package/dist/mcp/sdk-adapter.d.ts +478 -56
- package/dist/mcp/sdk-adapter.d.ts.map +1 -1
- package/dist/mcp/sdk-adapter.js +346 -44
- package/dist/mcp/sdk-adapter.js.map +1 -1
- package/dist/mcp/tools.d.ts +445 -30
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +363 -33
- package/dist/mcp/tools.js.map +1 -1
- package/dist/ops/blame.d.ts +424 -21
- package/dist/ops/blame.d.ts.map +1 -1
- package/dist/ops/blame.js +303 -20
- package/dist/ops/blame.js.map +1 -1
- package/dist/ops/branch.d.ts +583 -32
- package/dist/ops/branch.d.ts.map +1 -1
- package/dist/ops/branch.js +365 -23
- package/dist/ops/branch.js.map +1 -1
- package/dist/ops/commit-traversal.d.ts +164 -24
- package/dist/ops/commit-traversal.d.ts.map +1 -1
- package/dist/ops/commit-traversal.js +68 -2
- package/dist/ops/commit-traversal.js.map +1 -1
- package/dist/ops/commit.d.ts +387 -53
- package/dist/ops/commit.d.ts.map +1 -1
- package/dist/ops/commit.js +249 -29
- package/dist/ops/commit.js.map +1 -1
- package/dist/ops/merge-base.d.ts +195 -21
- package/dist/ops/merge-base.d.ts.map +1 -1
- package/dist/ops/merge-base.js +122 -12
- package/dist/ops/merge-base.js.map +1 -1
- package/dist/ops/merge.d.ts +600 -130
- package/dist/ops/merge.d.ts.map +1 -1
- package/dist/ops/merge.js +408 -60
- package/dist/ops/merge.js.map +1 -1
- package/dist/ops/tag.d.ts +67 -2
- package/dist/ops/tag.d.ts.map +1 -1
- package/dist/ops/tag.js +42 -1
- package/dist/ops/tag.js.map +1 -1
- package/dist/ops/tree-builder.d.ts +102 -6
- package/dist/ops/tree-builder.d.ts.map +1 -1
- package/dist/ops/tree-builder.js +30 -5
- package/dist/ops/tree-builder.js.map +1 -1
- package/dist/ops/tree-diff.d.ts +50 -2
- package/dist/ops/tree-diff.d.ts.map +1 -1
- package/dist/ops/tree-diff.js +50 -2
- package/dist/ops/tree-diff.js.map +1 -1
- package/dist/pack/delta.d.ts +211 -39
- package/dist/pack/delta.d.ts.map +1 -1
- package/dist/pack/delta.js +232 -46
- package/dist/pack/delta.js.map +1 -1
- package/dist/pack/format.d.ts +390 -28
- package/dist/pack/format.d.ts.map +1 -1
- package/dist/pack/format.js +344 -33
- package/dist/pack/format.js.map +1 -1
- package/dist/pack/full-generation.d.ts +313 -28
- package/dist/pack/full-generation.d.ts.map +1 -1
- package/dist/pack/full-generation.js +238 -19
- package/dist/pack/full-generation.js.map +1 -1
- package/dist/pack/generation.d.ts +346 -23
- package/dist/pack/generation.d.ts.map +1 -1
- package/dist/pack/generation.js +269 -21
- package/dist/pack/generation.js.map +1 -1
- package/dist/pack/index.d.ts +407 -86
- package/dist/pack/index.d.ts.map +1 -1
- package/dist/pack/index.js +351 -70
- package/dist/pack/index.js.map +1 -1
- package/dist/refs/branch.d.ts +517 -71
- package/dist/refs/branch.d.ts.map +1 -1
- package/dist/refs/branch.js +410 -26
- package/dist/refs/branch.js.map +1 -1
- package/dist/refs/storage.d.ts +610 -57
- package/dist/refs/storage.d.ts.map +1 -1
- package/dist/refs/storage.js +481 -29
- package/dist/refs/storage.js.map +1 -1
- package/dist/refs/tag.d.ts +677 -67
- package/dist/refs/tag.d.ts.map +1 -1
- package/dist/refs/tag.js +497 -30
- package/dist/refs/tag.js.map +1 -1
- package/dist/storage/lru-cache.d.ts +556 -53
- package/dist/storage/lru-cache.d.ts.map +1 -1
- package/dist/storage/lru-cache.js +439 -36
- package/dist/storage/lru-cache.js.map +1 -1
- package/dist/storage/object-index.d.ts +483 -38
- package/dist/storage/object-index.d.ts.map +1 -1
- package/dist/storage/object-index.js +388 -22
- package/dist/storage/object-index.js.map +1 -1
- package/dist/storage/r2-pack.d.ts +957 -94
- package/dist/storage/r2-pack.d.ts.map +1 -1
- package/dist/storage/r2-pack.js +756 -48
- package/dist/storage/r2-pack.js.map +1 -1
- package/dist/tiered/cdc-pipeline.d.ts +1610 -38
- package/dist/tiered/cdc-pipeline.d.ts.map +1 -1
- package/dist/tiered/cdc-pipeline.js +1131 -22
- package/dist/tiered/cdc-pipeline.js.map +1 -1
- package/dist/tiered/migration.d.ts +903 -41
- package/dist/tiered/migration.d.ts.map +1 -1
- package/dist/tiered/migration.js +646 -24
- package/dist/tiered/migration.js.map +1 -1
- package/dist/tiered/parquet-writer.d.ts +944 -47
- package/dist/tiered/parquet-writer.d.ts.map +1 -1
- package/dist/tiered/parquet-writer.js +667 -39
- package/dist/tiered/parquet-writer.js.map +1 -1
- package/dist/tiered/read-path.d.ts +728 -34
- package/dist/tiered/read-path.d.ts.map +1 -1
- package/dist/tiered/read-path.js +310 -27
- package/dist/tiered/read-path.js.map +1 -1
- package/dist/types/objects.d.ts +457 -0
- package/dist/types/objects.d.ts.map +1 -1
- package/dist/types/objects.js +305 -4
- package/dist/types/objects.js.map +1 -1
- package/dist/types/storage.d.ts +407 -35
- package/dist/types/storage.d.ts.map +1 -1
- package/dist/types/storage.js +27 -3
- package/dist/types/storage.js.map +1 -1
- package/dist/utils/hash.d.ts +133 -12
- package/dist/utils/hash.d.ts.map +1 -1
- package/dist/utils/hash.js +133 -12
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/sha1.d.ts +102 -9
- package/dist/utils/sha1.d.ts.map +1 -1
- package/dist/utils/sha1.js +114 -11
- package/dist/utils/sha1.js.map +1 -1
- package/dist/wire/capabilities.d.ts +896 -88
- package/dist/wire/capabilities.d.ts.map +1 -1
- package/dist/wire/capabilities.js +566 -62
- package/dist/wire/capabilities.js.map +1 -1
- package/dist/wire/pkt-line.d.ts +293 -15
- package/dist/wire/pkt-line.d.ts.map +1 -1
- package/dist/wire/pkt-line.js +251 -15
- package/dist/wire/pkt-line.js.map +1 -1
- package/dist/wire/receive-pack.d.ts +814 -64
- package/dist/wire/receive-pack.d.ts.map +1 -1
- package/dist/wire/receive-pack.js +542 -41
- package/dist/wire/receive-pack.js.map +1 -1
- package/dist/wire/smart-http.d.ts +575 -97
- package/dist/wire/smart-http.d.ts.map +1 -1
- package/dist/wire/smart-http.js +337 -46
- package/dist/wire/smart-http.js.map +1 -1
- package/dist/wire/upload-pack.d.ts +492 -98
- package/dist/wire/upload-pack.d.ts.map +1 -1
- package/dist/wire/upload-pack.js +347 -59
- package/dist/wire/upload-pack.js.map +1 -1
- package/package.json +10 -2
package/dist/mcp/tools.js
CHANGED
|
@@ -1,8 +1,46 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP (Model Context Protocol) Git Tool Definitions
|
|
2
|
+
* @fileoverview MCP (Model Context Protocol) Git Tool Definitions
|
|
3
3
|
*
|
|
4
4
|
* This module provides tool definitions for git operations that can be
|
|
5
|
-
* exposed via the Model Context Protocol for AI assistants.
|
|
5
|
+
* exposed via the Model Context Protocol for AI assistants. It defines
|
|
6
|
+
* a comprehensive set of git tools including status, log, diff, commit,
|
|
7
|
+
* branch, checkout, push, pull, clone, init, add, reset, merge, rebase,
|
|
8
|
+
* stash, tag, remote, and fetch operations.
|
|
9
|
+
*
|
|
10
|
+
* The module uses a registry pattern for tool management, allowing dynamic
|
|
11
|
+
* registration, validation, and invocation of tools. Each tool follows the
|
|
12
|
+
* MCP specification with JSON Schema input validation and standardized
|
|
13
|
+
* result formatting.
|
|
14
|
+
*
|
|
15
|
+
* @module mcp/tools
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Setting up repository context and invoking a tool
|
|
19
|
+
* import { setRepositoryContext, invokeTool } from './tools'
|
|
20
|
+
*
|
|
21
|
+
* // Set up the repository context first
|
|
22
|
+
* setRepositoryContext({
|
|
23
|
+
* objectStore: myObjectStore,
|
|
24
|
+
* refStore: myRefStore,
|
|
25
|
+
* index: myIndex
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* // Invoke a tool
|
|
29
|
+
* const result = await invokeTool('git_status', { short: true })
|
|
30
|
+
* console.log(result.content[0].text)
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // Registering a custom tool
|
|
34
|
+
* import { registerTool } from './tools'
|
|
35
|
+
*
|
|
36
|
+
* registerTool({
|
|
37
|
+
* name: 'my_custom_tool',
|
|
38
|
+
* description: 'A custom tool',
|
|
39
|
+
* inputSchema: { type: 'object', properties: {} },
|
|
40
|
+
* handler: async (params) => ({
|
|
41
|
+
* content: [{ type: 'text', text: 'Hello!' }]
|
|
42
|
+
* })
|
|
43
|
+
* })
|
|
6
44
|
*/
|
|
7
45
|
import { walkCommits } from '../ops/commit-traversal';
|
|
8
46
|
import { diffTrees, DiffStatus } from '../ops/tree-diff';
|
|
@@ -11,22 +49,66 @@ import { createCommit } from '../ops/commit';
|
|
|
11
49
|
/** Global repository context - set by the application before invoking tools */
|
|
12
50
|
let globalRepositoryContext = null;
|
|
13
51
|
/**
|
|
14
|
-
* Set the global repository context for MCP tools
|
|
52
|
+
* Set the global repository context for MCP tools.
|
|
53
|
+
*
|
|
54
|
+
* @description
|
|
55
|
+
* This function sets the global repository context that will be used by all
|
|
56
|
+
* MCP git tools. The context provides access to the object store, ref store,
|
|
57
|
+
* index, and working directory. This must be called before invoking any tools
|
|
58
|
+
* that require repository access.
|
|
59
|
+
*
|
|
60
|
+
* @param ctx - The repository context to set, or null to clear it
|
|
61
|
+
* @returns void
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Set up context before using tools
|
|
65
|
+
* setRepositoryContext({
|
|
66
|
+
* objectStore: myObjectStore,
|
|
67
|
+
* refStore: myRefStore
|
|
68
|
+
* })
|
|
69
|
+
*
|
|
70
|
+
* // Clear context when done
|
|
71
|
+
* setRepositoryContext(null)
|
|
15
72
|
*/
|
|
16
73
|
export function setRepositoryContext(ctx) {
|
|
17
74
|
globalRepositoryContext = ctx;
|
|
18
75
|
}
|
|
19
76
|
/**
|
|
20
|
-
* Get the global repository context
|
|
77
|
+
* Get the global repository context.
|
|
78
|
+
*
|
|
79
|
+
* @description
|
|
80
|
+
* Returns the currently set repository context, or null if no context has
|
|
81
|
+
* been set. Tools use this internally to access repository data.
|
|
82
|
+
*
|
|
83
|
+
* @returns The current repository context, or null if not set
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* const ctx = getRepositoryContext()
|
|
87
|
+
* if (ctx) {
|
|
88
|
+
* const commit = await ctx.objectStore.getCommit(sha)
|
|
89
|
+
* }
|
|
21
90
|
*/
|
|
22
91
|
export function getRepositoryContext() {
|
|
23
92
|
return globalRepositoryContext;
|
|
24
93
|
}
|
|
25
94
|
/**
|
|
26
|
-
* Validate a path parameter to prevent command injection
|
|
95
|
+
* Validate a path parameter to prevent command injection.
|
|
96
|
+
*
|
|
97
|
+
* @description
|
|
98
|
+
* Security function that validates file paths to prevent path traversal
|
|
99
|
+
* attacks and command injection. Rejects paths containing '..' (parent
|
|
100
|
+
* directory traversal), absolute paths starting with '/', and shell
|
|
101
|
+
* metacharacters.
|
|
102
|
+
*
|
|
27
103
|
* @param path - The path to validate
|
|
28
104
|
* @returns The validated path (defaults to '.' if undefined)
|
|
29
|
-
* @throws Error
|
|
105
|
+
* @throws {Error} If path contains forbidden characters or traversal patterns
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* validatePath('src/file.ts') // Returns 'src/file.ts'
|
|
109
|
+
* validatePath(undefined) // Returns '.'
|
|
110
|
+
* validatePath('../etc/passwd') // Throws Error
|
|
111
|
+
* validatePath('/etc/passwd') // Throws Error
|
|
30
112
|
*/
|
|
31
113
|
function validatePath(path) {
|
|
32
114
|
if (!path)
|
|
@@ -38,10 +120,21 @@ function validatePath(path) {
|
|
|
38
120
|
return path;
|
|
39
121
|
}
|
|
40
122
|
/**
|
|
41
|
-
* Validate a branch or ref name according to git rules
|
|
123
|
+
* Validate a branch or ref name according to git rules.
|
|
124
|
+
*
|
|
125
|
+
* @description
|
|
126
|
+
* Validates that a branch name conforms to git's naming rules. Branch names
|
|
127
|
+
* can contain alphanumeric characters, dots, underscores, forward slashes,
|
|
128
|
+
* and hyphens. The '..' sequence is forbidden as it's used for range notation.
|
|
129
|
+
*
|
|
42
130
|
* @param name - The branch/ref name to validate
|
|
43
131
|
* @returns The validated name
|
|
44
|
-
* @throws Error
|
|
132
|
+
* @throws {Error} If name contains invalid characters
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* validateBranchName('feature/my-branch') // Returns 'feature/my-branch'
|
|
136
|
+
* validateBranchName('v1.0.0') // Returns 'v1.0.0'
|
|
137
|
+
* validateBranchName('main..develop') // Throws Error
|
|
45
138
|
*/
|
|
46
139
|
function validateBranchName(name) {
|
|
47
140
|
// Git branch name rules
|
|
@@ -51,10 +144,22 @@ function validateBranchName(name) {
|
|
|
51
144
|
return name;
|
|
52
145
|
}
|
|
53
146
|
/**
|
|
54
|
-
* Validate a commit reference (hash, branch, tag, HEAD, etc.)
|
|
147
|
+
* Validate a commit reference (hash, branch, tag, HEAD, etc.).
|
|
148
|
+
*
|
|
149
|
+
* @description
|
|
150
|
+
* Validates commit references which can be SHA hashes, branch names, tag names,
|
|
151
|
+
* HEAD, or relative references like HEAD~3 or HEAD^2. The '..' sequence is
|
|
152
|
+
* forbidden to prevent range injection.
|
|
153
|
+
*
|
|
55
154
|
* @param ref - The commit reference to validate
|
|
56
155
|
* @returns The validated reference
|
|
57
|
-
* @throws Error
|
|
156
|
+
* @throws {Error} If reference contains invalid characters
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* validateCommitRef('abc123def456') // Returns the SHA
|
|
160
|
+
* validateCommitRef('HEAD~3') // Returns 'HEAD~3'
|
|
161
|
+
* validateCommitRef('main^2') // Returns 'main^2'
|
|
162
|
+
* validateCommitRef('a..b') // Throws Error
|
|
58
163
|
*/
|
|
59
164
|
function validateCommitRef(ref) {
|
|
60
165
|
// Allow hex hashes, branch names, tags, HEAD, HEAD~n, HEAD^n, etc.
|
|
@@ -64,10 +169,21 @@ function validateCommitRef(ref) {
|
|
|
64
169
|
return ref;
|
|
65
170
|
}
|
|
66
171
|
/**
|
|
67
|
-
* Validate a URL for git clone operations
|
|
172
|
+
* Validate a URL for git clone operations.
|
|
173
|
+
*
|
|
174
|
+
* @description
|
|
175
|
+
* Security function that validates URLs to prevent shell injection.
|
|
176
|
+
* Rejects URLs containing shell metacharacters that could be used
|
|
177
|
+
* for command injection.
|
|
178
|
+
*
|
|
68
179
|
* @param url - The URL to validate
|
|
69
180
|
* @returns The validated URL
|
|
70
|
-
* @throws Error
|
|
181
|
+
* @throws {Error} If URL contains shell injection characters
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* validateUrl('https://github.com/user/repo.git') // Returns the URL
|
|
185
|
+
* validateUrl('git@github.com:user/repo.git') // Returns the URL
|
|
186
|
+
* validateUrl('https://evil.com; rm -rf /') // Throws Error
|
|
71
187
|
*/
|
|
72
188
|
function validateUrl(url) {
|
|
73
189
|
// Reject shell injection characters in URLs
|
|
@@ -77,10 +193,21 @@ function validateUrl(url) {
|
|
|
77
193
|
return url;
|
|
78
194
|
}
|
|
79
195
|
/**
|
|
80
|
-
* Validate a remote name
|
|
196
|
+
* Validate a remote name.
|
|
197
|
+
*
|
|
198
|
+
* @description
|
|
199
|
+
* Validates that a remote name contains only safe characters.
|
|
200
|
+
* Remote names can contain alphanumeric characters, dots, underscores,
|
|
201
|
+
* and hyphens.
|
|
202
|
+
*
|
|
81
203
|
* @param name - The remote name to validate
|
|
82
204
|
* @returns The validated name
|
|
83
|
-
* @throws Error
|
|
205
|
+
* @throws {Error} If name contains invalid characters
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* validateRemoteName('origin') // Returns 'origin'
|
|
209
|
+
* validateRemoteName('my-remote') // Returns 'my-remote'
|
|
210
|
+
* validateRemoteName('remote/bad') // Throws Error
|
|
84
211
|
*/
|
|
85
212
|
function validateRemoteName(name) {
|
|
86
213
|
if (!/^[a-zA-Z0-9._-]+$/.test(name)) {
|
|
@@ -89,7 +216,18 @@ function validateRemoteName(name) {
|
|
|
89
216
|
return name;
|
|
90
217
|
}
|
|
91
218
|
/**
|
|
92
|
-
* Convert DiffStatus to human-readable text
|
|
219
|
+
* Convert DiffStatus enum to human-readable text.
|
|
220
|
+
*
|
|
221
|
+
* @description
|
|
222
|
+
* Maps diff status enum values to their git-style display text
|
|
223
|
+
* for use in status and diff output formatting.
|
|
224
|
+
*
|
|
225
|
+
* @param status - The DiffStatus enum value
|
|
226
|
+
* @returns Human-readable status string
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* getStatusText(DiffStatus.ADDED) // Returns 'new file'
|
|
230
|
+
* getStatusText(DiffStatus.DELETED) // Returns 'deleted'
|
|
93
231
|
*/
|
|
94
232
|
function getStatusText(status) {
|
|
95
233
|
switch (status) {
|
|
@@ -112,7 +250,26 @@ function getStatusText(status) {
|
|
|
112
250
|
}
|
|
113
251
|
}
|
|
114
252
|
/**
|
|
115
|
-
* Format a commit for log output
|
|
253
|
+
* Format a commit for log output.
|
|
254
|
+
*
|
|
255
|
+
* @description
|
|
256
|
+
* Formats a commit object into a display string, supporting both
|
|
257
|
+
* one-line format (abbreviated SHA + subject) and full format
|
|
258
|
+
* (complete commit information with author and date).
|
|
259
|
+
*
|
|
260
|
+
* @param sha - The full 40-character commit SHA
|
|
261
|
+
* @param commit - The parsed commit object
|
|
262
|
+
* @param oneline - If true, returns abbreviated single-line format
|
|
263
|
+
* @returns Formatted commit string
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* // One-line format
|
|
267
|
+
* formatCommit('abc123...', commit, true)
|
|
268
|
+
* // Returns: 'abc123d Fix bug in parser'
|
|
269
|
+
*
|
|
270
|
+
* // Full format
|
|
271
|
+
* formatCommit('abc123...', commit, false)
|
|
272
|
+
* // Returns multi-line commit display
|
|
116
273
|
*/
|
|
117
274
|
function formatCommit(sha, commit, oneline) {
|
|
118
275
|
if (oneline) {
|
|
@@ -134,11 +291,45 @@ function formatCommit(sha, commit, oneline) {
|
|
|
134
291
|
return lines.join('\n');
|
|
135
292
|
}
|
|
136
293
|
/**
|
|
137
|
-
* Internal registry for custom-registered tools
|
|
294
|
+
* Internal registry for custom-registered tools.
|
|
295
|
+
* @internal
|
|
138
296
|
*/
|
|
139
297
|
const toolRegistry = new Map();
|
|
140
298
|
/**
|
|
141
|
-
* Registry of available git tools
|
|
299
|
+
* Registry of available git tools.
|
|
300
|
+
*
|
|
301
|
+
* @description
|
|
302
|
+
* Array containing all built-in git tool definitions. These tools are
|
|
303
|
+
* automatically registered in the tool registry on module load. Each
|
|
304
|
+
* tool implements a specific git operation following the MCP specification.
|
|
305
|
+
*
|
|
306
|
+
* Available tools:
|
|
307
|
+
* - git_status: Show repository status
|
|
308
|
+
* - git_log: Show commit history
|
|
309
|
+
* - git_diff: Show differences between commits
|
|
310
|
+
* - git_commit: Create a new commit
|
|
311
|
+
* - git_branch: List, create, or delete branches
|
|
312
|
+
* - git_checkout: Switch branches or restore files
|
|
313
|
+
* - git_push: Upload commits to remote
|
|
314
|
+
* - git_pull: Fetch and integrate from remote
|
|
315
|
+
* - git_clone: Clone a repository
|
|
316
|
+
* - git_init: Initialize a new repository
|
|
317
|
+
* - git_add: Stage files for commit
|
|
318
|
+
* - git_reset: Reset HEAD to a state
|
|
319
|
+
* - git_merge: Merge branches
|
|
320
|
+
* - git_rebase: Rebase commits
|
|
321
|
+
* - git_stash: Stash changes
|
|
322
|
+
* - git_tag: Manage tags
|
|
323
|
+
* - git_remote: Manage remotes
|
|
324
|
+
* - git_fetch: Fetch from remotes
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* // Access git tools array
|
|
328
|
+
* import { gitTools } from './tools'
|
|
329
|
+
*
|
|
330
|
+
* for (const tool of gitTools) {
|
|
331
|
+
* console.log(`Tool: ${tool.name} - ${tool.description}`)
|
|
332
|
+
* }
|
|
142
333
|
*/
|
|
143
334
|
export const gitTools = [
|
|
144
335
|
// git_status tool
|
|
@@ -1456,9 +1647,44 @@ gitTools.forEach((tool) => {
|
|
|
1456
1647
|
toolRegistry.set(tool.name, tool);
|
|
1457
1648
|
});
|
|
1458
1649
|
/**
|
|
1459
|
-
* Register a new tool in the registry
|
|
1460
|
-
*
|
|
1461
|
-
* @
|
|
1650
|
+
* Register a new tool in the registry.
|
|
1651
|
+
*
|
|
1652
|
+
* @description
|
|
1653
|
+
* Adds a custom tool to the global tool registry. The tool must have a valid
|
|
1654
|
+
* handler function and a unique name. Once registered, the tool can be invoked
|
|
1655
|
+
* using {@link invokeTool}.
|
|
1656
|
+
*
|
|
1657
|
+
* Note: Built-in git tools are automatically registered on module load.
|
|
1658
|
+
*
|
|
1659
|
+
* @param tool - The tool definition to register
|
|
1660
|
+
* @returns void
|
|
1661
|
+
* @throws {Error} If tool handler is missing or not a function
|
|
1662
|
+
* @throws {Error} If a tool with the same name already exists
|
|
1663
|
+
*
|
|
1664
|
+
* @example
|
|
1665
|
+
* import { registerTool, invokeTool } from './tools'
|
|
1666
|
+
*
|
|
1667
|
+
* // Register a custom tool
|
|
1668
|
+
* registerTool({
|
|
1669
|
+
* name: 'custom_operation',
|
|
1670
|
+
* description: 'Performs a custom operation',
|
|
1671
|
+
* inputSchema: {
|
|
1672
|
+
* type: 'object',
|
|
1673
|
+
* properties: {
|
|
1674
|
+
* value: { type: 'string', description: 'Input value' }
|
|
1675
|
+
* },
|
|
1676
|
+
* required: ['value']
|
|
1677
|
+
* },
|
|
1678
|
+
* handler: async (params) => {
|
|
1679
|
+
* const { value } = params as { value: string }
|
|
1680
|
+
* return {
|
|
1681
|
+
* content: [{ type: 'text', text: `Processed: ${value}` }]
|
|
1682
|
+
* }
|
|
1683
|
+
* }
|
|
1684
|
+
* })
|
|
1685
|
+
*
|
|
1686
|
+
* // Now invoke the registered tool
|
|
1687
|
+
* const result = await invokeTool('custom_operation', { value: 'test' })
|
|
1462
1688
|
*/
|
|
1463
1689
|
export function registerTool(tool) {
|
|
1464
1690
|
if (!tool.handler || typeof tool.handler !== 'function') {
|
|
@@ -1470,10 +1696,37 @@ export function registerTool(tool) {
|
|
|
1470
1696
|
toolRegistry.set(tool.name, tool);
|
|
1471
1697
|
}
|
|
1472
1698
|
/**
|
|
1473
|
-
* Validate input parameters against a tool's schema
|
|
1699
|
+
* Validate input parameters against a tool's schema.
|
|
1700
|
+
*
|
|
1701
|
+
* @description
|
|
1702
|
+
* Performs comprehensive validation of tool parameters against the tool's
|
|
1703
|
+
* JSON Schema definition. Checks for required parameters, type correctness,
|
|
1704
|
+
* enum values, numeric constraints, string patterns, and array item types.
|
|
1705
|
+
*
|
|
1706
|
+
* This function is called automatically by {@link invokeTool} before
|
|
1707
|
+
* executing a tool handler, but can also be used independently for
|
|
1708
|
+
* pre-validation.
|
|
1709
|
+
*
|
|
1474
1710
|
* @param tool - The tool whose schema to validate against
|
|
1475
1711
|
* @param params - The parameters to validate
|
|
1476
|
-
* @returns Validation result with
|
|
1712
|
+
* @returns Validation result object with valid flag and array of error messages
|
|
1713
|
+
*
|
|
1714
|
+
* @example
|
|
1715
|
+
* import { validateToolInput, getTool } from './tools'
|
|
1716
|
+
*
|
|
1717
|
+
* const tool = getTool('git_commit')
|
|
1718
|
+
* if (tool) {
|
|
1719
|
+
* const validation = validateToolInput(tool, { path: '/repo' })
|
|
1720
|
+
* if (!validation.valid) {
|
|
1721
|
+
* console.error('Validation errors:', validation.errors)
|
|
1722
|
+
* // Output: ['Missing required parameter: message']
|
|
1723
|
+
* }
|
|
1724
|
+
* }
|
|
1725
|
+
*
|
|
1726
|
+
* @example
|
|
1727
|
+
* // Type validation example
|
|
1728
|
+
* const result = validateToolInput(tool, { maxCount: 'not-a-number' })
|
|
1729
|
+
* // result.errors: ["Parameter 'maxCount' has invalid type: expected number, got string"]
|
|
1477
1730
|
*/
|
|
1478
1731
|
export function validateToolInput(tool, params) {
|
|
1479
1732
|
const errors = [];
|
|
@@ -1537,11 +1790,49 @@ export function validateToolInput(tool, params) {
|
|
|
1537
1790
|
};
|
|
1538
1791
|
}
|
|
1539
1792
|
/**
|
|
1540
|
-
* Invoke a tool by name with the given parameters
|
|
1541
|
-
*
|
|
1542
|
-
* @
|
|
1543
|
-
*
|
|
1544
|
-
*
|
|
1793
|
+
* Invoke a tool by name with the given parameters.
|
|
1794
|
+
*
|
|
1795
|
+
* @description
|
|
1796
|
+
* Looks up a tool by name in the registry, validates the provided parameters
|
|
1797
|
+
* against the tool's schema, and executes the tool's handler. Validation
|
|
1798
|
+
* errors and execution errors are returned as MCPToolResult with isError=true
|
|
1799
|
+
* rather than throwing exceptions.
|
|
1800
|
+
*
|
|
1801
|
+
* This is the primary function for executing MCP tools. Ensure the repository
|
|
1802
|
+
* context is set via {@link setRepositoryContext} before invoking git tools.
|
|
1803
|
+
*
|
|
1804
|
+
* @param toolName - Name of the tool to invoke (e.g., 'git_status')
|
|
1805
|
+
* @param params - Parameters to pass to the tool handler
|
|
1806
|
+
* @returns Promise resolving to the tool result
|
|
1807
|
+
* @throws {Error} If the tool is not found in the registry
|
|
1808
|
+
*
|
|
1809
|
+
* @example
|
|
1810
|
+
* import { invokeTool, setRepositoryContext } from './tools'
|
|
1811
|
+
*
|
|
1812
|
+
* // Set up repository context first
|
|
1813
|
+
* setRepositoryContext(myRepoContext)
|
|
1814
|
+
*
|
|
1815
|
+
* // Invoke git_status tool
|
|
1816
|
+
* const status = await invokeTool('git_status', { short: true })
|
|
1817
|
+
* if (!status.isError) {
|
|
1818
|
+
* console.log(status.content[0].text)
|
|
1819
|
+
* }
|
|
1820
|
+
*
|
|
1821
|
+
* @example
|
|
1822
|
+
* // Invoke git_log with parameters
|
|
1823
|
+
* const log = await invokeTool('git_log', {
|
|
1824
|
+
* maxCount: 10,
|
|
1825
|
+
* oneline: true,
|
|
1826
|
+
* ref: 'main'
|
|
1827
|
+
* })
|
|
1828
|
+
*
|
|
1829
|
+
* @example
|
|
1830
|
+
* // Handle validation errors
|
|
1831
|
+
* const result = await invokeTool('git_commit', {})
|
|
1832
|
+
* if (result.isError) {
|
|
1833
|
+
* // result.content[0].text contains validation error message
|
|
1834
|
+
* console.error('Error:', result.content[0].text)
|
|
1835
|
+
* }
|
|
1545
1836
|
*/
|
|
1546
1837
|
export async function invokeTool(toolName, params) {
|
|
1547
1838
|
const tool = toolRegistry.get(toolName);
|
|
@@ -1578,8 +1869,25 @@ export async function invokeTool(toolName, params) {
|
|
|
1578
1869
|
}
|
|
1579
1870
|
}
|
|
1580
1871
|
/**
|
|
1581
|
-
* Get a list of all registered tools
|
|
1582
|
-
*
|
|
1872
|
+
* Get a list of all registered tools.
|
|
1873
|
+
*
|
|
1874
|
+
* @description
|
|
1875
|
+
* Returns an array of all tools in the registry with their names, descriptions,
|
|
1876
|
+
* and input schemas. Handler functions are omitted for security and serialization.
|
|
1877
|
+
* This is useful for discovery and documentation purposes.
|
|
1878
|
+
*
|
|
1879
|
+
* @returns Array of tool definitions without handler functions
|
|
1880
|
+
*
|
|
1881
|
+
* @example
|
|
1882
|
+
* import { listTools } from './tools'
|
|
1883
|
+
*
|
|
1884
|
+
* const tools = listTools()
|
|
1885
|
+
* console.log(`Available tools: ${tools.length}`)
|
|
1886
|
+
*
|
|
1887
|
+
* for (const tool of tools) {
|
|
1888
|
+
* console.log(`- ${tool.name}: ${tool.description}`)
|
|
1889
|
+
* console.log(` Required params: ${tool.inputSchema.required?.join(', ') || 'none'}`)
|
|
1890
|
+
* }
|
|
1583
1891
|
*/
|
|
1584
1892
|
export function listTools() {
|
|
1585
1893
|
const tools = [];
|
|
@@ -1594,9 +1902,31 @@ export function listTools() {
|
|
|
1594
1902
|
return tools;
|
|
1595
1903
|
}
|
|
1596
1904
|
/**
|
|
1597
|
-
* Get a tool by name
|
|
1598
|
-
*
|
|
1599
|
-
* @
|
|
1905
|
+
* Get a tool by name.
|
|
1906
|
+
*
|
|
1907
|
+
* @description
|
|
1908
|
+
* Retrieves a tool definition from the registry by its name. Returns the
|
|
1909
|
+
* complete tool object including the handler function. Returns undefined
|
|
1910
|
+
* if no tool with the given name exists.
|
|
1911
|
+
*
|
|
1912
|
+
* @param name - Name of the tool to retrieve (e.g., 'git_status')
|
|
1913
|
+
* @returns The complete tool definition if found, undefined otherwise
|
|
1914
|
+
*
|
|
1915
|
+
* @example
|
|
1916
|
+
* import { getTool } from './tools'
|
|
1917
|
+
*
|
|
1918
|
+
* const statusTool = getTool('git_status')
|
|
1919
|
+
* if (statusTool) {
|
|
1920
|
+
* console.log(`Description: ${statusTool.description}`)
|
|
1921
|
+
* console.log(`Parameters:`, Object.keys(statusTool.inputSchema.properties || {}))
|
|
1922
|
+
* }
|
|
1923
|
+
*
|
|
1924
|
+
* @example
|
|
1925
|
+
* // Check if a tool exists before using it
|
|
1926
|
+
* const tool = getTool('my_custom_tool')
|
|
1927
|
+
* if (!tool) {
|
|
1928
|
+
* console.error('Tool not found')
|
|
1929
|
+
* }
|
|
1600
1930
|
*/
|
|
1601
1931
|
export function getTool(name) {
|
|
1602
1932
|
return toolRegistry.get(name);
|