ai-cli-mcp 2.19.0 → 2.20.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 +26 -0
- package/README.ja.md +34 -8
- package/README.md +41 -8
- package/dist/app/cli.js +1 -0
- package/dist/app/mcp.js +64 -12
- package/dist/cli-builder.js +13 -6
- package/dist/cli-process-service.js +76 -91
- package/dist/cli-utils.js +6 -0
- package/dist/cli.js +1 -1
- package/dist/model-catalog.js +3 -2
- package/dist/parsers.js +8 -2
- package/package.json +27 -3
- package/server.json +3 -3
- package/.gemini/settings.json +0 -11
- package/.github/dependabot.yml +0 -28
- package/.github/pull_request_template.md +0 -28
- package/.github/workflows/ci.yml +0 -34
- package/.github/workflows/dependency-review.yml +0 -22
- package/.github/workflows/publish.yml +0 -89
- package/.github/workflows/test.yml +0 -20
- package/.github/workflows/watch-session-prs.yml +0 -276
- package/.husky/pre-commit +0 -1
- package/.mcp.json +0 -11
- package/.releaserc.json +0 -18
- package/.vscode/settings.json +0 -3
- package/CONTRIBUTING.md +0 -81
- package/dist/__tests__/app-cli.test.js +0 -392
- package/dist/__tests__/cli-bin-smoke.test.js +0 -101
- package/dist/__tests__/cli-builder.test.js +0 -442
- package/dist/__tests__/cli-process-service.test.js +0 -655
- package/dist/__tests__/cli-utils.test.js +0 -171
- package/dist/__tests__/e2e.test.js +0 -256
- package/dist/__tests__/edge-cases.test.js +0 -130
- package/dist/__tests__/error-cases.test.js +0 -292
- package/dist/__tests__/mcp-contract.test.js +0 -636
- package/dist/__tests__/mocks.js +0 -32
- package/dist/__tests__/model-alias.test.js +0 -36
- package/dist/__tests__/parsers.test.js +0 -646
- package/dist/__tests__/peek.test.js +0 -36
- package/dist/__tests__/process-management.test.js +0 -949
- package/dist/__tests__/server.test.js +0 -809
- package/dist/__tests__/setup.js +0 -11
- package/dist/__tests__/utils/claude-mock.js +0 -80
- package/dist/__tests__/utils/mcp-client.js +0 -121
- package/dist/__tests__/utils/opencode-mock.js +0 -91
- package/dist/__tests__/utils/persistent-mock.js +0 -28
- package/dist/__tests__/utils/test-helpers.js +0 -11
- package/dist/__tests__/validation.test.js +0 -308
- package/dist/__tests__/version-print.test.js +0 -65
- package/dist/__tests__/wait.test.js +0 -260
- package/docs/RELEASE_CHECKLIST.md +0 -65
- package/docs/cli-architecture.md +0 -275
- package/docs/concept.md +0 -154
- package/docs/development.md +0 -156
- package/docs/e2e-testing.md +0 -148
- package/docs/prd.md +0 -146
- package/docs/session-stacking.md +0 -67
- package/src/__tests__/app-cli.test.ts +0 -495
- package/src/__tests__/cli-bin-smoke.test.ts +0 -136
- package/src/__tests__/cli-builder.test.ts +0 -549
- package/src/__tests__/cli-process-service.test.ts +0 -759
- package/src/__tests__/cli-utils.test.ts +0 -200
- package/src/__tests__/e2e.test.ts +0 -311
- package/src/__tests__/edge-cases.test.ts +0 -176
- package/src/__tests__/error-cases.test.ts +0 -370
- package/src/__tests__/mcp-contract.test.ts +0 -755
- package/src/__tests__/mocks.ts +0 -35
- package/src/__tests__/model-alias.test.ts +0 -44
- package/src/__tests__/parsers.test.ts +0 -730
- package/src/__tests__/peek.test.ts +0 -44
- package/src/__tests__/process-management.test.ts +0 -1129
- package/src/__tests__/server.test.ts +0 -1020
- package/src/__tests__/setup.ts +0 -13
- package/src/__tests__/utils/claude-mock.ts +0 -87
- package/src/__tests__/utils/mcp-client.ts +0 -159
- package/src/__tests__/utils/opencode-mock.ts +0 -108
- package/src/__tests__/utils/persistent-mock.ts +0 -33
- package/src/__tests__/utils/test-helpers.ts +0 -13
- package/src/__tests__/validation.test.ts +0 -369
- package/src/__tests__/version-print.test.ts +0 -81
- package/src/__tests__/wait.test.ts +0 -302
- package/src/app/cli.ts +0 -424
- package/src/app/mcp.ts +0 -466
- package/src/bin/ai-cli-mcp.ts +0 -7
- package/src/bin/ai-cli.ts +0 -11
- package/src/cli-builder.ts +0 -274
- package/src/cli-parse.ts +0 -105
- package/src/cli-process-service.ts +0 -709
- package/src/cli-utils.ts +0 -258
- package/src/cli.ts +0 -124
- package/src/model-catalog.ts +0 -87
- package/src/parsers.ts +0 -965
- package/src/peek.ts +0 -95
- package/src/process-result.ts +0 -88
- package/src/process-service.ts +0 -368
- package/src/server.ts +0 -10
- package/tsconfig.json +0 -16
- package/vitest.config.e2e.ts +0 -27
- package/vitest.config.ts +0 -22
- package/vitest.config.unit.ts +0 -28
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
name: Watch Session PRs
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
schedule:
|
|
5
|
-
- cron: '17 0 * * *'
|
|
6
|
-
workflow_dispatch:
|
|
7
|
-
|
|
8
|
-
permissions:
|
|
9
|
-
contents: read
|
|
10
|
-
issues: write
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
watch-codex-fork:
|
|
14
|
-
runs-on: ubuntu-latest
|
|
15
|
-
steps:
|
|
16
|
-
- name: Check Codex fork PR and update issue
|
|
17
|
-
uses: actions/github-script@v7
|
|
18
|
-
env:
|
|
19
|
-
UPSTREAM_OWNER: openai
|
|
20
|
-
UPSTREAM_REPO: codex
|
|
21
|
-
UPSTREAM_PR_NUMBER: '13537'
|
|
22
|
-
TARGET_ISSUE_NUMBER: '7'
|
|
23
|
-
COMMENT_MARKER: '<!-- codex-fork-pr-13537-status -->'
|
|
24
|
-
READY_LABEL: '[ready]'
|
|
25
|
-
STOP_LABEL: '[stop]'
|
|
26
|
-
with:
|
|
27
|
-
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
28
|
-
script: |
|
|
29
|
-
const owner = process.env.UPSTREAM_OWNER;
|
|
30
|
-
const repo = process.env.UPSTREAM_REPO;
|
|
31
|
-
const pull_number = Number(process.env.UPSTREAM_PR_NUMBER);
|
|
32
|
-
const issue_number = Number(process.env.TARGET_ISSUE_NUMBER);
|
|
33
|
-
const marker = process.env.COMMENT_MARKER;
|
|
34
|
-
const readyLabel = process.env.READY_LABEL;
|
|
35
|
-
const stopLabel = process.env.STOP_LABEL;
|
|
36
|
-
|
|
37
|
-
const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number });
|
|
38
|
-
const desiredLabel = pr.merged_at ? readyLabel : stopLabel;
|
|
39
|
-
const staleLabel = pr.merged_at ? stopLabel : readyLabel;
|
|
40
|
-
const { data: issue } = await github.rest.issues.get({
|
|
41
|
-
owner: context.repo.owner,
|
|
42
|
-
repo: context.repo.repo,
|
|
43
|
-
issue_number,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
if (!issue.labels.some((label) => label.name === desiredLabel)) {
|
|
47
|
-
await github.rest.issues.addLabels({
|
|
48
|
-
owner: context.repo.owner,
|
|
49
|
-
repo: context.repo.repo,
|
|
50
|
-
issue_number,
|
|
51
|
-
labels: [desiredLabel],
|
|
52
|
-
});
|
|
53
|
-
core.info(`Added label ${desiredLabel} to issue #${issue_number}.`);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (issue.labels.some((label) => label.name === staleLabel)) {
|
|
57
|
-
try {
|
|
58
|
-
await github.rest.issues.removeLabel({
|
|
59
|
-
owner: context.repo.owner,
|
|
60
|
-
repo: context.repo.repo,
|
|
61
|
-
issue_number,
|
|
62
|
-
name: staleLabel,
|
|
63
|
-
});
|
|
64
|
-
core.info(`Removed label ${staleLabel} from issue #${issue_number}.`);
|
|
65
|
-
} catch (error) {
|
|
66
|
-
core.warning(`Failed to remove label ${staleLabel}: ${error.message}`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
core.summary
|
|
71
|
-
.addHeading('Codex PR status')
|
|
72
|
-
.addTable([
|
|
73
|
-
[
|
|
74
|
-
{ data: 'Field', header: true },
|
|
75
|
-
{ data: 'Value', header: true },
|
|
76
|
-
],
|
|
77
|
-
['PR', `${owner}/${repo}#${pr.number}`],
|
|
78
|
-
['Title', pr.title],
|
|
79
|
-
['State', pr.state],
|
|
80
|
-
['Merged', pr.merged_at ? 'yes' : 'no'],
|
|
81
|
-
['Merged at', pr.merged_at ?? 'not merged'],
|
|
82
|
-
['Updated at', pr.updated_at],
|
|
83
|
-
['URL', pr.html_url],
|
|
84
|
-
]);
|
|
85
|
-
|
|
86
|
-
const comments = await github.paginate(github.rest.issues.listComments, {
|
|
87
|
-
owner: context.repo.owner,
|
|
88
|
-
repo: context.repo.repo,
|
|
89
|
-
issue_number,
|
|
90
|
-
per_page: 100,
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
const existingComment = comments.find((comment) => comment.body?.includes(marker));
|
|
94
|
-
const body = [
|
|
95
|
-
marker,
|
|
96
|
-
'upstream PR `openai/codex#13537` status watcher',
|
|
97
|
-
'',
|
|
98
|
-
`- PR: ${pr.html_url}`,
|
|
99
|
-
`- State: ${pr.state}`,
|
|
100
|
-
`- Merged: ${pr.merged_at ? 'yes' : 'no'}`,
|
|
101
|
-
`- Merged at: ${pr.merged_at ?? 'not merged'}`,
|
|
102
|
-
`- Updated at: ${pr.updated_at}`,
|
|
103
|
-
'',
|
|
104
|
-
pr.merged_at
|
|
105
|
-
? 'This PR has been merged. `codex exec --fork <SESSION_ID> [PROMPT]` should become available once the change lands in the installed Codex version.'
|
|
106
|
-
: 'This PR is not merged yet. Non-interactive forking is still not available in released Codex builds.',
|
|
107
|
-
'A new session ID is expected when using `--fork`; `resume` itself continues the same session.',
|
|
108
|
-
].join('\n');
|
|
109
|
-
|
|
110
|
-
if (existingComment?.body === body) {
|
|
111
|
-
core.info(`Issue #${issue_number} status comment is already up to date.`);
|
|
112
|
-
await core.summary.addRaw(`No update needed: ${existingComment.html_url}\n`).write();
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (existingComment) {
|
|
117
|
-
const { data: comment } = await github.rest.issues.updateComment({
|
|
118
|
-
owner: context.repo.owner,
|
|
119
|
-
repo: context.repo.repo,
|
|
120
|
-
comment_id: existingComment.id,
|
|
121
|
-
body,
|
|
122
|
-
});
|
|
123
|
-
core.info(`Updated issue #${issue_number}: ${comment.html_url}`);
|
|
124
|
-
await core.summary.addRaw(`Updated status comment: ${comment.html_url}\n`).write();
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const { data: comment } = await github.rest.issues.createComment({
|
|
129
|
-
owner: context.repo.owner,
|
|
130
|
-
repo: context.repo.repo,
|
|
131
|
-
issue_number,
|
|
132
|
-
body,
|
|
133
|
-
});
|
|
134
|
-
core.info(`Created issue #${issue_number} status comment: ${comment.html_url}`);
|
|
135
|
-
await core.summary.addRaw(`Created status comment: ${comment.html_url}\n`).write();
|
|
136
|
-
|
|
137
|
-
watch-gemini-session-work:
|
|
138
|
-
runs-on: ubuntu-latest
|
|
139
|
-
steps:
|
|
140
|
-
- name: Check Gemini session PRs and update issue
|
|
141
|
-
uses: actions/github-script@v7
|
|
142
|
-
env:
|
|
143
|
-
UPSTREAM_OWNER: google-gemini
|
|
144
|
-
UPSTREAM_REPO: gemini-cli
|
|
145
|
-
TARGET_ISSUE_NUMBER: '16'
|
|
146
|
-
COMMENT_MARKER: '<!-- gemini-session-pr-status -->'
|
|
147
|
-
WATCH_PR_NUMBERS: '17921,19629,19994'
|
|
148
|
-
READY_PR_NUMBERS: '17921,19629'
|
|
149
|
-
READY_LABEL: '[ready]'
|
|
150
|
-
STOP_LABEL: '[stop]'
|
|
151
|
-
with:
|
|
152
|
-
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
153
|
-
script: |
|
|
154
|
-
const owner = process.env.UPSTREAM_OWNER;
|
|
155
|
-
const repo = process.env.UPSTREAM_REPO;
|
|
156
|
-
const issue_number = Number(process.env.TARGET_ISSUE_NUMBER);
|
|
157
|
-
const marker = process.env.COMMENT_MARKER;
|
|
158
|
-
const pullNumbers = process.env.WATCH_PR_NUMBERS.split(',').map((value) => Number(value.trim()));
|
|
159
|
-
const readyPullNumbers = process.env.READY_PR_NUMBERS.split(',').map((value) => Number(value.trim()));
|
|
160
|
-
const readyLabel = process.env.READY_LABEL;
|
|
161
|
-
const stopLabel = process.env.STOP_LABEL;
|
|
162
|
-
|
|
163
|
-
const pulls = await Promise.all(
|
|
164
|
-
pullNumbers.map(async (pull_number) => {
|
|
165
|
-
const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number });
|
|
166
|
-
return pr;
|
|
167
|
-
}),
|
|
168
|
-
);
|
|
169
|
-
const isReady = pulls.some((pr) => readyPullNumbers.includes(pr.number) && Boolean(pr.merged_at));
|
|
170
|
-
const desiredLabel = isReady ? readyLabel : stopLabel;
|
|
171
|
-
const staleLabel = isReady ? stopLabel : readyLabel;
|
|
172
|
-
|
|
173
|
-
const { data: issue } = await github.rest.issues.get({
|
|
174
|
-
owner: context.repo.owner,
|
|
175
|
-
repo: context.repo.repo,
|
|
176
|
-
issue_number,
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
if (!issue.labels.some((label) => label.name === desiredLabel)) {
|
|
180
|
-
await github.rest.issues.addLabels({
|
|
181
|
-
owner: context.repo.owner,
|
|
182
|
-
repo: context.repo.repo,
|
|
183
|
-
issue_number,
|
|
184
|
-
labels: [desiredLabel],
|
|
185
|
-
});
|
|
186
|
-
core.info(`Added label ${desiredLabel} to issue #${issue_number}.`);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (issue.labels.some((label) => label.name === staleLabel)) {
|
|
190
|
-
try {
|
|
191
|
-
await github.rest.issues.removeLabel({
|
|
192
|
-
owner: context.repo.owner,
|
|
193
|
-
repo: context.repo.repo,
|
|
194
|
-
issue_number,
|
|
195
|
-
name: staleLabel,
|
|
196
|
-
});
|
|
197
|
-
core.info(`Removed label ${staleLabel} from issue #${issue_number}.`);
|
|
198
|
-
} catch (error) {
|
|
199
|
-
core.warning(`Failed to remove label ${staleLabel}: ${error.message}`);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const lines = pulls.flatMap((pr) => [
|
|
204
|
-
`- \`${owner}/${repo}#${pr.number}\` ${pr.title}`,
|
|
205
|
-
` - State: ${pr.state}`,
|
|
206
|
-
` - Merged: ${pr.merged_at ? 'yes' : 'no'}`,
|
|
207
|
-
` - Merged at: ${pr.merged_at ?? 'not merged'}`,
|
|
208
|
-
` - Updated at: ${pr.updated_at}`,
|
|
209
|
-
` - URL: ${pr.html_url}`,
|
|
210
|
-
]);
|
|
211
|
-
|
|
212
|
-
core.summary
|
|
213
|
-
.addHeading('Gemini PR status')
|
|
214
|
-
.addTable([
|
|
215
|
-
[
|
|
216
|
-
{ data: 'PR', header: true },
|
|
217
|
-
{ data: 'State', header: true },
|
|
218
|
-
{ data: 'Merged', header: true },
|
|
219
|
-
{ data: 'Updated at', header: true },
|
|
220
|
-
],
|
|
221
|
-
...pulls.map((pr) => [
|
|
222
|
-
`${owner}/${repo}#${pr.number}`,
|
|
223
|
-
pr.state,
|
|
224
|
-
pr.merged_at ? 'yes' : 'no',
|
|
225
|
-
pr.updated_at,
|
|
226
|
-
]),
|
|
227
|
-
]);
|
|
228
|
-
|
|
229
|
-
const comments = await github.paginate(github.rest.issues.listComments, {
|
|
230
|
-
owner: context.repo.owner,
|
|
231
|
-
repo: context.repo.repo,
|
|
232
|
-
issue_number,
|
|
233
|
-
per_page: 100,
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
const existingComment = comments.find((comment) => comment.body?.includes(marker));
|
|
237
|
-
const body = [
|
|
238
|
-
marker,
|
|
239
|
-
'upstream Gemini CLI session-related PR status watcher',
|
|
240
|
-
'',
|
|
241
|
-
'Tracked PRs:',
|
|
242
|
-
...lines,
|
|
243
|
-
'',
|
|
244
|
-
'Interpretation:',
|
|
245
|
-
'- `#19994` is a fix for resumed session ID stats mismatch, not a fork/new-session feature.',
|
|
246
|
-
'- `#17921` is the `/new` command proposal for starting a fresh session while preserving the previous one.',
|
|
247
|
-
'- `#19629` is the `--session-id` proposal for explicit session UUID control.',
|
|
248
|
-
'- Even if these land, that still does not automatically imply Codex-style headless fork semantics from `--resume` alone.',
|
|
249
|
-
].join('\n');
|
|
250
|
-
|
|
251
|
-
if (existingComment?.body === body) {
|
|
252
|
-
core.info(`Issue #${issue_number} Gemini status comment is already up to date.`);
|
|
253
|
-
await core.summary.addRaw(`No update needed: ${existingComment.html_url}\n`).write();
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (existingComment) {
|
|
258
|
-
const { data: comment } = await github.rest.issues.updateComment({
|
|
259
|
-
owner: context.repo.owner,
|
|
260
|
-
repo: context.repo.repo,
|
|
261
|
-
comment_id: existingComment.id,
|
|
262
|
-
body,
|
|
263
|
-
});
|
|
264
|
-
core.info(`Updated issue #${issue_number}: ${comment.html_url}`);
|
|
265
|
-
await core.summary.addRaw(`Updated status comment: ${comment.html_url}\n`).write();
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const { data: comment } = await github.rest.issues.createComment({
|
|
270
|
-
owner: context.repo.owner,
|
|
271
|
-
repo: context.repo.repo,
|
|
272
|
-
issue_number,
|
|
273
|
-
body,
|
|
274
|
-
});
|
|
275
|
-
core.info(`Created issue #${issue_number} status comment: ${comment.html_url}`);
|
|
276
|
-
await core.summary.addRaw(`Created status comment: ${comment.html_url}\n`).write();
|
package/.husky/pre-commit
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
npm run test:unit
|
package/.mcp.json
DELETED
package/.releaserc.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"branches": ["develop"],
|
|
3
|
-
"plugins": [
|
|
4
|
-
"@semantic-release/commit-analyzer",
|
|
5
|
-
"@semantic-release/release-notes-generator",
|
|
6
|
-
["@semantic-release/changelog", {
|
|
7
|
-
"changelogFile": "CHANGELOG.md"
|
|
8
|
-
}],
|
|
9
|
-
"@semantic-release/npm",
|
|
10
|
-
["@semantic-release/github", {
|
|
11
|
-
"assets": []
|
|
12
|
-
}],
|
|
13
|
-
["@semantic-release/git", {
|
|
14
|
-
"assets": ["CHANGELOG.md", "package.json", "package-lock.json"],
|
|
15
|
-
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
|
16
|
-
}]
|
|
17
|
-
]
|
|
18
|
-
}
|
package/.vscode/settings.json
DELETED
package/CONTRIBUTING.md
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
# Contributing
|
|
2
|
-
|
|
3
|
-
## Development Setup
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
git clone https://github.com/mkXultra/ai-cli-mcp.git
|
|
7
|
-
cd ai-cli-mcp
|
|
8
|
-
npm install
|
|
9
|
-
npm run build
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
## Testing
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
# Run all tests
|
|
16
|
-
npm test
|
|
17
|
-
|
|
18
|
-
# Unit tests only
|
|
19
|
-
npm run test:unit
|
|
20
|
-
|
|
21
|
-
# E2E tests (with mocks)
|
|
22
|
-
npm run test:e2e
|
|
23
|
-
|
|
24
|
-
# E2E tests locally (requires Claude CLI)
|
|
25
|
-
npm run test:e2e:local
|
|
26
|
-
|
|
27
|
-
# Watch mode
|
|
28
|
-
npm run test:watch
|
|
29
|
-
|
|
30
|
-
# Coverage
|
|
31
|
-
npm run test:coverage
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Manual Testing with MCP Inspector
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
npm run build
|
|
38
|
-
npx @modelcontextprotocol/inspector node dist/server.js
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## CLI Direct Execution
|
|
42
|
-
|
|
43
|
-
Run AI CLI tools directly from the terminal (foreground, no MCP server):
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
npm run -s cli.run -- --model sonnet --workFolder /tmp --prompt "hello"
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
See [docs/development.md](docs/development.md#cli-direct-execution-clirun) for full options.
|
|
50
|
-
|
|
51
|
-
## Local Development with npm link
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
npm install
|
|
55
|
-
npm run build
|
|
56
|
-
npm link
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Then use `ai-cli-mcp` command globally.
|
|
60
|
-
|
|
61
|
-
## Environment Variables
|
|
62
|
-
|
|
63
|
-
| Variable | Description |
|
|
64
|
-
|----------|-------------|
|
|
65
|
-
| `CLAUDE_CLI_NAME` | Claude CLI binary name or absolute path |
|
|
66
|
-
| `CODEX_CLI_NAME` | Codex CLI binary name or absolute path |
|
|
67
|
-
| `GEMINI_CLI_NAME` | Gemini CLI binary name or absolute path |
|
|
68
|
-
| `MCP_CLAUDE_DEBUG` | Enable debug logging (`true`/`false`) |
|
|
69
|
-
|
|
70
|
-
## Release Process
|
|
71
|
-
|
|
72
|
-
See [docs/RELEASE_CHECKLIST.md](docs/RELEASE_CHECKLIST.md) for release instructions.
|
|
73
|
-
|
|
74
|
-
Uses semantic-release with Conventional Commits:
|
|
75
|
-
- `fix:` → patch release
|
|
76
|
-
- `feat:` → minor release
|
|
77
|
-
- `feat!:` or `BREAKING CHANGE:` → major release
|
|
78
|
-
|
|
79
|
-
## License
|
|
80
|
-
|
|
81
|
-
MIT
|