mergestorm-mcp 0.1.9 → 0.1.10

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.
Files changed (2) hide show
  1. package/dist/index.js +29 -7
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -592,6 +592,17 @@ function settingsPatchFromArgs(args) {
592
592
  const value = args[key];
593
593
  if (value === void 0) continue;
594
594
  const row = BEARER_SETTINGS.find((row2) => row2.key === key);
595
+ if ("kind" in row && row.kind === "seconds") {
596
+ if (typeof value !== "number" || !Number.isInteger(value) || value < row.min || value > row.max) {
597
+ throw new CommandError8(
598
+ `${key} takes a whole number of seconds from ${row.min} through ${row.max}.`,
599
+ 2,
600
+ "usage"
601
+ );
602
+ }
603
+ Object.assign(patch, { [key]: value });
604
+ continue;
605
+ }
595
606
  if ("kind" in row) {
596
607
  const valid = row.kind === "logins" ? Array.isArray(value) && value.every((login) => typeof login === "string") : typeof value === "string" && row.values.includes(value);
597
608
  if (!valid) throw new CommandError8(`Invalid value for ${key}.`, 2, "usage");
@@ -791,6 +802,17 @@ var stackWaitSchema = {
791
802
  after_finished_at: z2.string().nullable().optional(),
792
803
  bounce_id: z2.string().nullable().optional()
793
804
  };
805
+ function stackWaitSummary(envelope) {
806
+ const base = `Stack ${envelope.stackId} \xB7 ${envelope.status}${stackBlockersSummary2(envelope.blocker && envelope.prNumber != null ? { prNumber: envelope.prNumber, blocker: envelope.blocker } : null, envelope.issues)}${envelope.assessment === "unavailable" ? " \xB7 assessment unavailable" : ""}`;
807
+ if (envelope.status !== "waiting" && envelope.status !== "in_progress") return base;
808
+ const selectors = [
809
+ `stack_id ${JSON.stringify(envelope.cursor.stackId)}`,
810
+ `enrolled_head_sha ${JSON.stringify(envelope.cursor.enrolledHeadSha)}`,
811
+ ...envelope.cursor.afterFinishedAt !== void 0 ? [`after_finished_at ${JSON.stringify(envelope.cursor.afterFinishedAt)}`] : [],
812
+ ...envelope.cursor.bounceId !== void 0 ? [`bounce_id ${JSON.stringify(envelope.cursor.bounceId)}`] : []
813
+ ];
814
+ return `${base} \xB7 watch not finished: call stack_wait again with timeout_s 45 and the same cursor: ${selectors.join(", ")}`;
815
+ }
794
816
  async function stackWait(input, cfg, deps = {}) {
795
817
  const args = z2.object(stackWaitSchema).parse(input);
796
818
  const cursor = args.enrolled_head_sha !== void 0 || args.after_finished_at !== void 0 || args.bounce_id !== void 0 ? {
@@ -809,7 +831,7 @@ async function stackWait(input, cfg, deps = {}) {
809
831
  } catch (err) {
810
832
  if (err instanceof StackWatchError) {
811
833
  return {
812
- summary: `Stack ${err.lastEnvelope.stackId} \xB7 ${err.lastEnvelope.status}${stackBlockersSummary2(err.lastEnvelope.blocker && err.lastEnvelope.prNumber != null ? { prNumber: err.lastEnvelope.prNumber, blocker: err.lastEnvelope.blocker } : null, err.lastEnvelope.issues)}${err.lastEnvelope.assessment === "unavailable" ? " \xB7 assessment unavailable" : ""}`,
834
+ summary: stackWaitSummary(err.lastEnvelope),
813
835
  data: {
814
836
  ...err.lastEnvelope,
815
837
  ...err.retryAfterSeconds !== void 0 ? { retry_after_seconds: err.retryAfterSeconds } : {}
@@ -821,7 +843,7 @@ async function stackWait(input, cfg, deps = {}) {
821
843
  envelope = err.lastEnvelope;
822
844
  }
823
845
  return {
824
- summary: `Stack ${envelope.stackId} \xB7 ${envelope.status}${stackBlockersSummary2(envelope.blocker && envelope.prNumber != null ? { prNumber: envelope.prNumber, blocker: envelope.blocker } : null, envelope.issues)}${envelope.assessment === "unavailable" ? " \xB7 assessment unavailable" : ""}`,
846
+ summary: stackWaitSummary(envelope),
825
847
  data: envelope
826
848
  };
827
849
  }
@@ -943,7 +965,7 @@ var MCP_STACK_WATCH_INSTRUCTIONS = [
943
965
 
944
966
  // src/server.ts
945
967
  var MCP_SERVER_NAME = "mergestorm";
946
- var MCP_SERVER_VERSION = "0.1.9";
968
+ var MCP_SERVER_VERSION = "0.1.10";
947
969
  function stripNulls(value) {
948
970
  if (Array.isArray(value)) {
949
971
  return value.map((item) => stripNulls(item));
@@ -1229,7 +1251,7 @@ ${MCP_STACK_WATCH_INSTRUCTIONS}` }
1229
1251
  "stack_wait",
1230
1252
  {
1231
1253
  title: "Wait for stack attention",
1232
- description: "Wait for a stack to need attention. Returns a mergestorm.stack_watch/v1 envelope; timeout_s: 0 returns one snapshot and timeout_s: 1-45 waits up to that many seconds, returning the current status (waiting or in_progress) if a snapshot was read and no attention is found. A timeout with either of those statuses is not a failure. A timeout of failed means no assessment was produced. This tool is read-only. Attention never calls for changing a PR's GitHub base.",
1254
+ description: "Wait for a stack to need attention. Returns a mergestorm.stack_watch/v1 envelope; timeout_s: 0 returns one snapshot and timeout_s: 1-45 waits up to that many seconds, returning the current status (waiting or in_progress) if a snapshot was read and no attention is found. A timeout with either of those statuses is not a failure; waiting and in_progress end this slice, and the next call is stack_wait again with the same cursor. A timeout of failed means no assessment was produced. This tool is read-only. Attention never calls for changing a PR's GitHub base.",
1233
1255
  inputSchema: stackWaitSchema
1234
1256
  },
1235
1257
  async (args, extra) => {
@@ -1262,7 +1284,7 @@ ${MCP_STACK_WATCH_INSTRUCTIONS}` }
1262
1284
  "settings_get",
1263
1285
  {
1264
1286
  title: "Get settings",
1265
- description: "Read the Bearer /api/v1/settings toggles, including auto_patch_enabled and cyclone_connected. This tool is read-only."
1287
+ description: "Read the Bearer /api/v1/settings toggles, including auto_patch_enabled, auto_land_settle_seconds (how long Auto land waits before queueing), and cyclone_connected. This tool is read-only."
1266
1288
  },
1267
1289
  async () => {
1268
1290
  try {
@@ -1276,12 +1298,12 @@ ${MCP_STACK_WATCH_INSTRUCTIONS}` }
1276
1298
  "settings_set",
1277
1299
  {
1278
1300
  title: "Update settings",
1279
- description: "Update writable Bearer /api/v1/settings values and return the stored result. At least one key is required. cyclone_connected and github_connected are read-only and cannot be set.",
1301
+ description: "Update writable Bearer /api/v1/settings values and return the stored result. At least one key is required. auto_land_settle_seconds is a whole number of seconds from 15 through 300; it applies to settle clocks that start after the write. cyclone_connected and github_connected are read-only and cannot be set.",
1280
1302
  inputSchema: {
1281
1303
  ...Object.fromEntries(
1282
1304
  BEARER_SETTINGS2.map((row) => [
1283
1305
  row.key,
1284
- ("kind" in row ? row.kind === "logins" ? z3.array(z3.string()) : z3.enum(row.values) : z3.boolean()).optional()
1306
+ ("kind" in row ? row.kind === "logins" ? z3.array(z3.string()) : row.kind === "seconds" ? z3.number().int().min(row.min).max(row.max) : z3.enum(row.values) : z3.boolean()).optional()
1285
1307
  ])
1286
1308
  ),
1287
1309
  // Preserve these args so the handler rejects them even alongside a writable key.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mergestorm-mcp",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
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.23",
32
+ "mergestorm": "0.3.24",
33
33
  "zod": "^3.24.2"
34
34
  },
35
35
  "devDependencies": {