mergestorm-mcp 0.2.5 → 0.2.6
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/README.md +1 -1
- package/dist/index.js +17 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ The stack tools expose reads plus one scoped policy write:
|
|
|
24
24
|
- `stack_status({ stack_id })` returns one owned stack with enriched checks and agent state, plus `attention`, `issues`, and `currentCandidate` from the same blocker rules as `stack_wait`, read against that stack's own merge queue. It returns a structured `stack_not_found` or `rate_limited` error.
|
|
25
25
|
- `stack_wait({ stack_id, timeout_s?, enrolled_head_sha?, after_finished_at?, bounce_id? })` waits for a stack or queue state change and returns the latest snapshots. `timeout_s: 0` returns one snapshot; a positive timeout after a snapshot with no attention returns the current `waiting` or `in_progress` status with selectors to use for the next call. An unread deadline returns `failed`. While Cyclone or Vortex is still working on the blocked PR, `stack_wait` and `stack_status` return `in_progress` instead of `attention`, with `busy[]` naming the PR, blocker, and agent, and `agents` carrying that PR's `vortexStatus`, `cycloneStatus`, `vortexReview`, and busy flags. A nonempty `busy[]` means wait. A queued Vortex run holds for at most 15 minutes, `seam_pending` alone does not hold, and reviewing or patching holds until the run finishes or its lease or check run is cleared. A blocker no agent run clears (a merge conflict vs the live parent, a restack `Conflict` or `Restack failed`, a Draft PR, a seam review pending with no review running) is still named during that `in_progress`, in `blocker`, `prNumber`, `headSha`, and `issues[]`, with `actAfter: "agents_idle"` and `waitingOn` listing the busy agents; act when a snapshot after the agents finish returns `attention`, re-reading the blocker then. `repair` is included when a concrete repair hint is available. Blockers the agents can change keep `blocker` and `actAfter` null. If a hold looks stuck, refresh `stack_status` and tell the human.
|
|
26
26
|
|
|
27
|
-
Agents that cannot hold a long turn open should not poll `stack_wait` inside their turn. The server instructions tell them to run `mg stack watch <stack-id>` from the `mergestorm` CLI as a background command, notify on output matching `MS-WATCH (ATTENTION|LANDED)`, and end the turn. The watcher loops the same stack wait against the Mergestorm API with the cursor, stays silent while the stack is waiting or in progress, and exits on attention (exit 3), a failed read that failed again on retry (exit 3), or a finished watch (exit 0). On wake the agent reads `stack_status` once, fixes the blocker, pushes, and restarts the watcher with `--head <pushed-sha>`. The stack is still not done until it lands. Agents are told not to subscribe to GitHub events to wait on a stack.
|
|
27
|
+
Agents that cannot hold a long turn open should not poll `stack_wait` inside their turn. The server instructions tell them to run `mg stack watch <stack-id>` from the `mergestorm` CLI as a background command, notify on output matching `MS-WATCH (ATTENTION|LANDED)`, and end the turn. The watcher loops the same stack wait against the Mergestorm API with the cursor, stays silent while the stack is waiting or in progress, and exits on attention (exit 3), a failed read that failed again on retry (exit 3), or a finished watch (exit 0). Every `watch.next` carries that command as `watch.next.background`, and every not-done `watch.message` offers it before the next `stack_wait` call. On wake the agent reads `stack_status` once, fixes the blocker, pushes, and restarts the watcher with `--head <pushed-sha>`. The stack is still not done until it lands. Agents are told not to subscribe to GitHub events to wait on a stack.
|
|
28
28
|
|
|
29
29
|
Auth is `MERGESTORM_API_KEY`, then `~/.mergestorm/config.json` (same as `mg`).
|
|
30
30
|
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,17 @@ var MCP_WEBSITE_URL = SITE;
|
|
|
37
37
|
|
|
38
38
|
// src/tools/credits.ts
|
|
39
39
|
import { CommandError, getMe, loadConfig } from "mergestorm/client";
|
|
40
|
+
function formatMinutes(value) {
|
|
41
|
+
return value.toLocaleString("en-US", { maximumFractionDigits: 1 });
|
|
42
|
+
}
|
|
43
|
+
function surgeSummary(surge) {
|
|
44
|
+
if (!surge) return "";
|
|
45
|
+
const wallet = `wallet ${formatMinutes(surge.walletMinutes)} min`;
|
|
46
|
+
if (surge.includedMinutes <= 0) return `
|
|
47
|
+
Surge: ${wallet}`;
|
|
48
|
+
return `
|
|
49
|
+
Surge: ${formatMinutes(surge.usedMinutes)} of ${formatMinutes(surge.includedMinutes)} included min this period \xB7 ${wallet}`;
|
|
50
|
+
}
|
|
40
51
|
async function credits(cfg) {
|
|
41
52
|
const resolved = cfg ?? await loadConfig();
|
|
42
53
|
const me = await getMe(resolved);
|
|
@@ -53,9 +64,10 @@ async function credits(cfg) {
|
|
|
53
64
|
const standard = me.usage.standard;
|
|
54
65
|
const remaining = standard.remaining ?? (standard.limit != null ? Math.max(0, standard.limit - standard.used) : null);
|
|
55
66
|
const bonusRemaining = me.usage.bonus?.remaining;
|
|
67
|
+
const surge = me.usage.surge;
|
|
56
68
|
const bonusSummary = bonusRemaining == null ? "" : ` \xB7 ${bonusRemaining} bonus remaining`;
|
|
57
69
|
return {
|
|
58
|
-
summary: remaining == null ? `${standard.used} used \xB7 unlimited${bonusSummary}` : `${standard.used} used \xB7 ${remaining} remaining${bonusSummary}`,
|
|
70
|
+
summary: remaining == null ? `${standard.used} used \xB7 unlimited${bonusSummary}${surgeSummary(surge)}` : `${standard.used} used \xB7 ${remaining} remaining${bonusSummary}${surgeSummary(surge)}`,
|
|
59
71
|
data: {
|
|
60
72
|
usage: me.usage,
|
|
61
73
|
resets_at: me.resets_at ?? null
|
|
@@ -175,6 +187,7 @@ import {
|
|
|
175
187
|
pollStackWatch,
|
|
176
188
|
StackWatchError,
|
|
177
189
|
StackWatchTimeoutError,
|
|
190
|
+
stackWatchBackgroundCommand,
|
|
178
191
|
stackWatchObligation
|
|
179
192
|
} from "mergestorm/client";
|
|
180
193
|
import { z } from "zod";
|
|
@@ -216,7 +229,7 @@ function stackWaitStatusLine(envelope) {
|
|
|
216
229
|
...envelope.cursor.afterFinishedAt !== void 0 ? [`after_finished_at ${JSON.stringify(envelope.cursor.afterFinishedAt)}`] : [],
|
|
217
230
|
...envelope.cursor.bounceId !== void 0 ? [`bounce_id ${JSON.stringify(envelope.cursor.bounceId)}`] : []
|
|
218
231
|
];
|
|
219
|
-
return `${base} \xB7 watch not finished: call stack_wait again with timeout_s 45 and the same cursor: ${selectors.join(", ")}`;
|
|
232
|
+
return `${base} \xB7 watch not finished: run ${stackWatchBackgroundCommand(envelope.stackId)} as a background command and end your turn, or call stack_wait again with timeout_s 45 and the same cursor: ${selectors.join(", ")}`;
|
|
220
233
|
}
|
|
221
234
|
async function stackWait(input, cfg, deps = {}) {
|
|
222
235
|
const args = z.object(stackWaitSchema).parse(input);
|
|
@@ -1133,14 +1146,14 @@ var MCP_STACK_WATCH_INSTRUCTIONS = [
|
|
|
1133
1146
|
|
|
1134
1147
|
// src/server.ts
|
|
1135
1148
|
var MCP_SERVER_NAME = "mergestorm";
|
|
1136
|
-
var MCP_SERVER_VERSION = "0.2.
|
|
1149
|
+
var MCP_SERVER_VERSION = "0.2.6";
|
|
1137
1150
|
var MCP_SERVER_INSTRUCTIONS = [
|
|
1138
1151
|
MCP_STACK_DONE_INSTRUCTIONS,
|
|
1139
1152
|
MCP_PR_LOOP_INSTRUCTIONS,
|
|
1140
1153
|
MCP_STACK_BASE_INSTRUCTIONS,
|
|
1141
1154
|
MCP_STACK_WATCH_INSTRUCTIONS
|
|
1142
1155
|
].join("\n\n");
|
|
1143
|
-
var STACK_WATCH_RESULT_NOTE = ' The result carries watch {done, until: "landed", reason, next, message}: while watch.done is false the stack is not landed and your task is not done; call stack_wait with watch.next.args.';
|
|
1156
|
+
var STACK_WATCH_RESULT_NOTE = ' The result carries watch {done, until: "landed", reason, next, message}: while watch.done is false the stack is not landed and your task is not done; call stack_wait with watch.next.args, or run watch.next.background as a background command and end your turn.';
|
|
1144
1157
|
function stripNulls(value) {
|
|
1145
1158
|
if (Array.isArray(value)) {
|
|
1146
1159
|
return value.map((item) => stripNulls(item));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mergestorm-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Mergestorm MCP server — identity, review, and read-only stack tools over stdio",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
32
|
-
"mergestorm": "0.3.
|
|
32
|
+
"mergestorm": "0.3.31",
|
|
33
33
|
"zod": "^3.24.2"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|