@arii/boomtick-mcp 0.7.0 → 0.7.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/.mcp/schemas/github.get_merge_conflict_files.json +55 -5
- package/.mcp/schemas/github_get_merge_conflict_files.json +55 -5
- package/.mcp/schemas/repo.create_branch.json +63 -0
- package/.mcp/schemas/repo.create_repair_branch.json +63 -0
- package/.mcp/schemas/repo.get_changed_files.json +39 -0
- package/.mcp/schemas/repo_create_branch.json +63 -0
- package/.mcp/schemas/repo_create_repair_branch.json +63 -0
- package/.mcp/schemas/repo_get_changed_files.json +39 -0
- package/CHANGELOG.md +8 -0
- package/dist/lib/git.js +78 -6
- package/dist/lib/git.test.js +34 -1
- package/dist/tools/contract.js +226 -11
- package/dist/tools/github.get_merge_conflict_files.js +10 -2
- package/dist/tools/repo.create_branch.js +18 -4
- package/dist/tools/repo.create_branch.test.js +41 -5
- package/dist/tools/repo.create_repair_branch.js +26 -9
- package/dist/tools/repo.get_changed_files.js +10 -2
- package/package.json +1 -1
- package/src/lib/git.test.ts +45 -1
- package/src/lib/git.ts +94 -6
- package/src/tools/contract.ts +226 -11
- package/src/tools/github.get_merge_conflict_files.ts +11 -2
- package/src/tools/repo.create_branch.test.ts +73 -5
- package/src/tools/repo.create_branch.ts +30 -4
- package/src/tools/repo.create_repair_branch.ts +31 -9
- package/src/tools/repo.get_changed_files.ts +10 -2
|
@@ -4,20 +4,70 @@
|
|
|
4
4
|
"parameters": {
|
|
5
5
|
"properties": {
|
|
6
6
|
"prNumber": {
|
|
7
|
+
"anyOf": [
|
|
8
|
+
{
|
|
9
|
+
"type": "integer"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"type": "null"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"default": null,
|
|
7
16
|
"description": "The number of the pull request to check for conflicts.",
|
|
8
|
-
"title": "Prnumber"
|
|
9
|
-
"type": "integer"
|
|
17
|
+
"title": "Prnumber"
|
|
10
18
|
},
|
|
11
19
|
"baseBranch": {
|
|
12
20
|
"default": "main",
|
|
13
21
|
"description": "The base branch to check against (default: 'main').",
|
|
14
22
|
"title": "Basebranch",
|
|
15
23
|
"type": "string"
|
|
24
|
+
},
|
|
25
|
+
"headRef": {
|
|
26
|
+
"default": "HEAD",
|
|
27
|
+
"description": "The head ref or branch to check.",
|
|
28
|
+
"title": "Headref",
|
|
29
|
+
"type": "string"
|
|
30
|
+
},
|
|
31
|
+
"repo": {
|
|
32
|
+
"anyOf": [
|
|
33
|
+
{
|
|
34
|
+
"type": "string"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "null"
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"default": null,
|
|
41
|
+
"description": "Target GitHub repository override.",
|
|
42
|
+
"title": "Repo"
|
|
43
|
+
},
|
|
44
|
+
"path": {
|
|
45
|
+
"anyOf": [
|
|
46
|
+
{
|
|
47
|
+
"type": "string"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"type": "null"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"default": null,
|
|
54
|
+
"description": "Local filesystem path to target repository root.",
|
|
55
|
+
"title": "Path"
|
|
56
|
+
},
|
|
57
|
+
"repoPath": {
|
|
58
|
+
"anyOf": [
|
|
59
|
+
{
|
|
60
|
+
"type": "string"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"type": "null"
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"default": null,
|
|
67
|
+
"description": "Alias for path to target repository root.",
|
|
68
|
+
"title": "Repopath"
|
|
16
69
|
}
|
|
17
70
|
},
|
|
18
|
-
"required": [
|
|
19
|
-
"prNumber"
|
|
20
|
-
],
|
|
21
71
|
"title": "GetMergeConflictFilesInput",
|
|
22
72
|
"type": "object"
|
|
23
73
|
},
|
|
@@ -4,20 +4,70 @@
|
|
|
4
4
|
"parameters": {
|
|
5
5
|
"properties": {
|
|
6
6
|
"prNumber": {
|
|
7
|
+
"anyOf": [
|
|
8
|
+
{
|
|
9
|
+
"type": "integer"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"type": "null"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"default": null,
|
|
7
16
|
"description": "The number of the pull request to check for conflicts.",
|
|
8
|
-
"title": "Prnumber"
|
|
9
|
-
"type": "integer"
|
|
17
|
+
"title": "Prnumber"
|
|
10
18
|
},
|
|
11
19
|
"baseBranch": {
|
|
12
20
|
"default": "main",
|
|
13
21
|
"description": "The base branch to check against (default: 'main').",
|
|
14
22
|
"title": "Basebranch",
|
|
15
23
|
"type": "string"
|
|
24
|
+
},
|
|
25
|
+
"headRef": {
|
|
26
|
+
"default": "HEAD",
|
|
27
|
+
"description": "The head ref or branch to check.",
|
|
28
|
+
"title": "Headref",
|
|
29
|
+
"type": "string"
|
|
30
|
+
},
|
|
31
|
+
"repo": {
|
|
32
|
+
"anyOf": [
|
|
33
|
+
{
|
|
34
|
+
"type": "string"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "null"
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"default": null,
|
|
41
|
+
"description": "Target GitHub repository override.",
|
|
42
|
+
"title": "Repo"
|
|
43
|
+
},
|
|
44
|
+
"path": {
|
|
45
|
+
"anyOf": [
|
|
46
|
+
{
|
|
47
|
+
"type": "string"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"type": "null"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"default": null,
|
|
54
|
+
"description": "Local filesystem path to target repository root.",
|
|
55
|
+
"title": "Path"
|
|
56
|
+
},
|
|
57
|
+
"repoPath": {
|
|
58
|
+
"anyOf": [
|
|
59
|
+
{
|
|
60
|
+
"type": "string"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"type": "null"
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"default": null,
|
|
67
|
+
"description": "Alias for path to target repository root.",
|
|
68
|
+
"title": "Repopath"
|
|
16
69
|
}
|
|
17
70
|
},
|
|
18
|
-
"required": [
|
|
19
|
-
"prNumber"
|
|
20
|
-
],
|
|
21
71
|
"title": "GetMergeConflictFilesInput",
|
|
22
72
|
"type": "object"
|
|
23
73
|
},
|
|
@@ -13,6 +13,45 @@
|
|
|
13
13
|
"description": "Branch to branch off from",
|
|
14
14
|
"title": "Basebranch",
|
|
15
15
|
"type": "string"
|
|
16
|
+
},
|
|
17
|
+
"repo": {
|
|
18
|
+
"anyOf": [
|
|
19
|
+
{
|
|
20
|
+
"type": "string"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "null"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"default": null,
|
|
27
|
+
"description": "Target repository override (e.g. org/repo or repo).",
|
|
28
|
+
"title": "Repo"
|
|
29
|
+
},
|
|
30
|
+
"path": {
|
|
31
|
+
"anyOf": [
|
|
32
|
+
{
|
|
33
|
+
"type": "string"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"type": "null"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"default": null,
|
|
40
|
+
"description": "Local filesystem path to target repository root.",
|
|
41
|
+
"title": "Path"
|
|
42
|
+
},
|
|
43
|
+
"repoPath": {
|
|
44
|
+
"anyOf": [
|
|
45
|
+
{
|
|
46
|
+
"type": "string"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"type": "null"
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
"default": null,
|
|
53
|
+
"description": "Alias for path to target repository root.",
|
|
54
|
+
"title": "Repopath"
|
|
16
55
|
}
|
|
17
56
|
},
|
|
18
57
|
"required": [
|
|
@@ -43,6 +82,30 @@
|
|
|
43
82
|
],
|
|
44
83
|
"default": null,
|
|
45
84
|
"title": "Basebranch"
|
|
85
|
+
},
|
|
86
|
+
"repo": {
|
|
87
|
+
"anyOf": [
|
|
88
|
+
{
|
|
89
|
+
"type": "string"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"type": "null"
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"default": null,
|
|
96
|
+
"title": "Repo"
|
|
97
|
+
},
|
|
98
|
+
"path": {
|
|
99
|
+
"anyOf": [
|
|
100
|
+
{
|
|
101
|
+
"type": "string"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"type": "null"
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"default": null,
|
|
108
|
+
"title": "Path"
|
|
46
109
|
}
|
|
47
110
|
},
|
|
48
111
|
"required": [
|
|
@@ -25,6 +25,45 @@
|
|
|
25
25
|
"description": "Safety gate: Must be true to perform branch creation and worktree setup.",
|
|
26
26
|
"title": "Writemode",
|
|
27
27
|
"type": "boolean"
|
|
28
|
+
},
|
|
29
|
+
"repo": {
|
|
30
|
+
"anyOf": [
|
|
31
|
+
{
|
|
32
|
+
"type": "string"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"type": "null"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"default": null,
|
|
39
|
+
"description": "Target repository override (e.g. org/repo or repo).",
|
|
40
|
+
"title": "Repo"
|
|
41
|
+
},
|
|
42
|
+
"path": {
|
|
43
|
+
"anyOf": [
|
|
44
|
+
{
|
|
45
|
+
"type": "string"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"type": "null"
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"default": null,
|
|
52
|
+
"description": "Local filesystem path to target repository root.",
|
|
53
|
+
"title": "Path"
|
|
54
|
+
},
|
|
55
|
+
"repoPath": {
|
|
56
|
+
"anyOf": [
|
|
57
|
+
{
|
|
58
|
+
"type": "string"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"type": "null"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"default": null,
|
|
65
|
+
"description": "Alias for path to target repository root.",
|
|
66
|
+
"title": "Repopath"
|
|
28
67
|
}
|
|
29
68
|
},
|
|
30
69
|
"required": [
|
|
@@ -55,6 +94,30 @@
|
|
|
55
94
|
"worktreePath": {
|
|
56
95
|
"title": "Worktreepath",
|
|
57
96
|
"type": "string"
|
|
97
|
+
},
|
|
98
|
+
"repo": {
|
|
99
|
+
"anyOf": [
|
|
100
|
+
{
|
|
101
|
+
"type": "string"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"type": "null"
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"default": null,
|
|
108
|
+
"title": "Repo"
|
|
109
|
+
},
|
|
110
|
+
"path": {
|
|
111
|
+
"anyOf": [
|
|
112
|
+
{
|
|
113
|
+
"type": "string"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"type": "null"
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"default": null,
|
|
120
|
+
"title": "Path"
|
|
58
121
|
}
|
|
59
122
|
},
|
|
60
123
|
"required": [
|
|
@@ -14,6 +14,45 @@
|
|
|
14
14
|
"description": "The head ref to compare to (default: 'HEAD').",
|
|
15
15
|
"title": "Head",
|
|
16
16
|
"type": "string"
|
|
17
|
+
},
|
|
18
|
+
"repo": {
|
|
19
|
+
"anyOf": [
|
|
20
|
+
{
|
|
21
|
+
"type": "string"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "null"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"default": null,
|
|
28
|
+
"description": "Target GitHub repository override.",
|
|
29
|
+
"title": "Repo"
|
|
30
|
+
},
|
|
31
|
+
"path": {
|
|
32
|
+
"anyOf": [
|
|
33
|
+
{
|
|
34
|
+
"type": "string"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "null"
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"default": null,
|
|
41
|
+
"description": "Local filesystem path to target repository root.",
|
|
42
|
+
"title": "Path"
|
|
43
|
+
},
|
|
44
|
+
"repoPath": {
|
|
45
|
+
"anyOf": [
|
|
46
|
+
{
|
|
47
|
+
"type": "string"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"type": "null"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"default": null,
|
|
54
|
+
"description": "Alias for path to target repository root.",
|
|
55
|
+
"title": "Repopath"
|
|
17
56
|
}
|
|
18
57
|
},
|
|
19
58
|
"title": "GetChangedFilesInput",
|
|
@@ -13,6 +13,45 @@
|
|
|
13
13
|
"description": "Branch to branch off from",
|
|
14
14
|
"title": "Basebranch",
|
|
15
15
|
"type": "string"
|
|
16
|
+
},
|
|
17
|
+
"repo": {
|
|
18
|
+
"anyOf": [
|
|
19
|
+
{
|
|
20
|
+
"type": "string"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "null"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"default": null,
|
|
27
|
+
"description": "Target repository override (e.g. org/repo or repo).",
|
|
28
|
+
"title": "Repo"
|
|
29
|
+
},
|
|
30
|
+
"path": {
|
|
31
|
+
"anyOf": [
|
|
32
|
+
{
|
|
33
|
+
"type": "string"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"type": "null"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"default": null,
|
|
40
|
+
"description": "Local filesystem path to target repository root.",
|
|
41
|
+
"title": "Path"
|
|
42
|
+
},
|
|
43
|
+
"repoPath": {
|
|
44
|
+
"anyOf": [
|
|
45
|
+
{
|
|
46
|
+
"type": "string"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"type": "null"
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
"default": null,
|
|
53
|
+
"description": "Alias for path to target repository root.",
|
|
54
|
+
"title": "Repopath"
|
|
16
55
|
}
|
|
17
56
|
},
|
|
18
57
|
"required": [
|
|
@@ -43,6 +82,30 @@
|
|
|
43
82
|
],
|
|
44
83
|
"default": null,
|
|
45
84
|
"title": "Basebranch"
|
|
85
|
+
},
|
|
86
|
+
"repo": {
|
|
87
|
+
"anyOf": [
|
|
88
|
+
{
|
|
89
|
+
"type": "string"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"type": "null"
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"default": null,
|
|
96
|
+
"title": "Repo"
|
|
97
|
+
},
|
|
98
|
+
"path": {
|
|
99
|
+
"anyOf": [
|
|
100
|
+
{
|
|
101
|
+
"type": "string"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"type": "null"
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"default": null,
|
|
108
|
+
"title": "Path"
|
|
46
109
|
}
|
|
47
110
|
},
|
|
48
111
|
"required": [
|
|
@@ -25,6 +25,45 @@
|
|
|
25
25
|
"description": "Safety gate: Must be true to perform branch creation and worktree setup.",
|
|
26
26
|
"title": "Writemode",
|
|
27
27
|
"type": "boolean"
|
|
28
|
+
},
|
|
29
|
+
"repo": {
|
|
30
|
+
"anyOf": [
|
|
31
|
+
{
|
|
32
|
+
"type": "string"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"type": "null"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"default": null,
|
|
39
|
+
"description": "Target repository override (e.g. org/repo or repo).",
|
|
40
|
+
"title": "Repo"
|
|
41
|
+
},
|
|
42
|
+
"path": {
|
|
43
|
+
"anyOf": [
|
|
44
|
+
{
|
|
45
|
+
"type": "string"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"type": "null"
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"default": null,
|
|
52
|
+
"description": "Local filesystem path to target repository root.",
|
|
53
|
+
"title": "Path"
|
|
54
|
+
},
|
|
55
|
+
"repoPath": {
|
|
56
|
+
"anyOf": [
|
|
57
|
+
{
|
|
58
|
+
"type": "string"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"type": "null"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"default": null,
|
|
65
|
+
"description": "Alias for path to target repository root.",
|
|
66
|
+
"title": "Repopath"
|
|
28
67
|
}
|
|
29
68
|
},
|
|
30
69
|
"required": [
|
|
@@ -55,6 +94,30 @@
|
|
|
55
94
|
"worktreePath": {
|
|
56
95
|
"title": "Worktreepath",
|
|
57
96
|
"type": "string"
|
|
97
|
+
},
|
|
98
|
+
"repo": {
|
|
99
|
+
"anyOf": [
|
|
100
|
+
{
|
|
101
|
+
"type": "string"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"type": "null"
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"default": null,
|
|
108
|
+
"title": "Repo"
|
|
109
|
+
},
|
|
110
|
+
"path": {
|
|
111
|
+
"anyOf": [
|
|
112
|
+
{
|
|
113
|
+
"type": "string"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"type": "null"
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"default": null,
|
|
120
|
+
"title": "Path"
|
|
58
121
|
}
|
|
59
122
|
},
|
|
60
123
|
"required": [
|
|
@@ -14,6 +14,45 @@
|
|
|
14
14
|
"description": "The head ref to compare to (default: 'HEAD').",
|
|
15
15
|
"title": "Head",
|
|
16
16
|
"type": "string"
|
|
17
|
+
},
|
|
18
|
+
"repo": {
|
|
19
|
+
"anyOf": [
|
|
20
|
+
{
|
|
21
|
+
"type": "string"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "null"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"default": null,
|
|
28
|
+
"description": "Target GitHub repository override.",
|
|
29
|
+
"title": "Repo"
|
|
30
|
+
},
|
|
31
|
+
"path": {
|
|
32
|
+
"anyOf": [
|
|
33
|
+
{
|
|
34
|
+
"type": "string"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "null"
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"default": null,
|
|
41
|
+
"description": "Local filesystem path to target repository root.",
|
|
42
|
+
"title": "Path"
|
|
43
|
+
},
|
|
44
|
+
"repoPath": {
|
|
45
|
+
"anyOf": [
|
|
46
|
+
{
|
|
47
|
+
"type": "string"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"type": "null"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"default": null,
|
|
54
|
+
"description": "Alias for path to target repository root.",
|
|
55
|
+
"title": "Repopath"
|
|
17
56
|
}
|
|
18
57
|
},
|
|
19
58
|
"title": "GetChangedFilesInput",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.7.1](https://github.com/arii/boomtick/compare/mcp-v0.7.0...mcp-v0.7.1) (2026-10-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **mcp:** resolve ecosystem_repos without requiring local path existence during isolated test runs ([53ab66a](https://github.com/arii/boomtick/commit/53ab66ab6503c93ff07bfd4e525a5f490df16386))
|
|
9
|
+
* **mcp:** resolve target workspace dynamically in repo.create_branch and worktree tools ([#990](https://github.com/arii/boomtick/issues/990)) ([cd2f34e](https://github.com/arii/boomtick/commit/cd2f34ea8607f037b855d41f899bf5152dc13c1f))
|
|
10
|
+
|
|
3
11
|
## [0.7.0](https://github.com/arii/boomtick/compare/mcp-v0.6.2...mcp-v0.7.0) (2026-10-29)
|
|
4
12
|
|
|
5
13
|
|
package/dist/lib/git.js
CHANGED
|
@@ -2,6 +2,7 @@ import { runCommand } from "./shell.js";
|
|
|
2
2
|
import { config } from "../config.js";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import fs from "fs/promises";
|
|
5
|
+
import * as syncFs from "fs";
|
|
5
6
|
import { execSync } from "child_process";
|
|
6
7
|
const repoCache = new Map();
|
|
7
8
|
export function resolveRepo(explicitRepo, cwd) {
|
|
@@ -31,6 +32,75 @@ export function resolveRepo(explicitRepo, cwd) {
|
|
|
31
32
|
repoCache.set(targetCwd, fallback);
|
|
32
33
|
return fallback;
|
|
33
34
|
}
|
|
35
|
+
export function resolveRepoPath(options = {}) {
|
|
36
|
+
// 1. Explicit path parameter has highest precedence
|
|
37
|
+
if (options.path && options.path.trim().length > 0) {
|
|
38
|
+
return path.resolve(options.path.trim());
|
|
39
|
+
}
|
|
40
|
+
// 2. repoPath alias parameter
|
|
41
|
+
if (options.repoPath && options.repoPath.trim().length > 0) {
|
|
42
|
+
return path.resolve(options.repoPath.trim());
|
|
43
|
+
}
|
|
44
|
+
// 3. Repository name override (e.g. "arii/tech-dancer" or "tech-dancer")
|
|
45
|
+
if (options.repo && options.repo.trim().length > 0) {
|
|
46
|
+
const rawRepo = options.repo.trim();
|
|
47
|
+
const repoName = rawRepo.includes("/") ? rawRepo.split("/")[1] : rawRepo;
|
|
48
|
+
// First check project_config.json ecosystem_repos if available
|
|
49
|
+
let rootPath = process.cwd();
|
|
50
|
+
try {
|
|
51
|
+
if (options.cwd && options.cwd.trim().length > 0) {
|
|
52
|
+
rootPath = options.cwd.trim();
|
|
53
|
+
}
|
|
54
|
+
else if (config.repoPath) {
|
|
55
|
+
rootPath = config.repoPath;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
rootPath = process.cwd();
|
|
60
|
+
}
|
|
61
|
+
const projectConfigPath = path.join(rootPath, "project_config.json");
|
|
62
|
+
if (syncFs.existsSync(projectConfigPath)) {
|
|
63
|
+
try {
|
|
64
|
+
const parsed = JSON.parse(syncFs.readFileSync(projectConfigPath, "utf-8"));
|
|
65
|
+
if (parsed?.ecosystem_repos && typeof parsed.ecosystem_repos === "object") {
|
|
66
|
+
for (const [key, relPath] of Object.entries(parsed.ecosystem_repos)) {
|
|
67
|
+
const keyRepoName = key.includes("/") ? key.split("/")[1] : key;
|
|
68
|
+
if (key === rawRepo || keyRepoName === repoName) {
|
|
69
|
+
return path.resolve(rootPath, relPath);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Fallback to directory inspection
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Check sibling directory relative to cwd or rootPath
|
|
79
|
+
const candidateDirs = [
|
|
80
|
+
path.resolve(process.cwd(), "..", repoName),
|
|
81
|
+
path.resolve(rootPath, "..", repoName),
|
|
82
|
+
];
|
|
83
|
+
for (const cand of candidateDirs) {
|
|
84
|
+
if (syncFs.existsSync(cand)) {
|
|
85
|
+
return cand;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// 4. Explicit cwd parameter
|
|
90
|
+
if (options.cwd && options.cwd.trim().length > 0) {
|
|
91
|
+
return path.resolve(options.cwd.trim());
|
|
92
|
+
}
|
|
93
|
+
// 5. Configured repoPath or process.cwd()
|
|
94
|
+
try {
|
|
95
|
+
if (config.repoPath && syncFs.existsSync(config.repoPath)) {
|
|
96
|
+
return config.repoPath;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Fall back to process.cwd()
|
|
101
|
+
}
|
|
102
|
+
return process.cwd();
|
|
103
|
+
}
|
|
34
104
|
function validatePrNumber(value) {
|
|
35
105
|
const prNumber = Number(value);
|
|
36
106
|
if (!Number.isInteger(prNumber) || prNumber <= 0) {
|
|
@@ -38,26 +108,28 @@ function validatePrNumber(value) {
|
|
|
38
108
|
}
|
|
39
109
|
return prNumber;
|
|
40
110
|
}
|
|
41
|
-
export async function createWorktree(branch, prNumber) {
|
|
111
|
+
export async function createWorktree(branch, prNumber, baseRepoPath) {
|
|
42
112
|
const safePrNumber = validatePrNumber(prNumber);
|
|
43
113
|
const workspaceRoot = "/tmp/boomtick-worktrees";
|
|
44
114
|
// nosemgrep
|
|
45
115
|
const worktreePath = path.join(workspaceRoot, `boomtick-mcp-rescue-${safePrNumber}`);
|
|
116
|
+
const cwdOption = baseRepoPath ? { cwd: baseRepoPath } : undefined;
|
|
46
117
|
// Clean up if exists
|
|
47
118
|
try {
|
|
48
119
|
await fs.rm(worktreePath, { recursive: true, force: true });
|
|
49
|
-
await runCommand("git", ["worktree", "prune"]);
|
|
120
|
+
await runCommand("git", ["worktree", "prune"], cwdOption);
|
|
50
121
|
}
|
|
51
122
|
catch (e) { /* ignore if no previous worktree */ }
|
|
52
|
-
const result = await runCommand("git", ["worktree", "add", "-b", `repair-pr-${prNumber}-${Date.now()}`, worktreePath, branch]);
|
|
123
|
+
const result = await runCommand("git", ["worktree", "add", "-b", `repair-pr-${prNumber}-${Date.now()}`, worktreePath, branch], cwdOption);
|
|
53
124
|
if (result.exitCode !== 0) {
|
|
54
125
|
throw new Error(`Failed to create worktree: ${result.stderr}`);
|
|
55
126
|
}
|
|
56
127
|
return worktreePath;
|
|
57
128
|
}
|
|
58
|
-
export async function removeWorktree(worktreePath) {
|
|
59
|
-
|
|
60
|
-
await runCommand("git", ["worktree", "
|
|
129
|
+
export async function removeWorktree(worktreePath, baseRepoPath) {
|
|
130
|
+
const cwdOption = baseRepoPath ? { cwd: baseRepoPath } : undefined;
|
|
131
|
+
await runCommand("git", ["worktree", "remove", "--force", worktreePath], cwdOption);
|
|
132
|
+
await runCommand("git", ["worktree", "prune"], cwdOption);
|
|
61
133
|
}
|
|
62
134
|
export async function getChangedFiles(base = "main", head = "HEAD", cwd) {
|
|
63
135
|
const result = await runCommand("git", ["diff", "--name-status", "-z", `${base}...${head}`], { cwd });
|