@testchimp/cli 0.1.60 → 0.1.61

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.
@@ -1081,6 +1081,34 @@ function runOpencode(prompt, model, childEnv, opencodeSessionId, callbacks, atta
1081
1081
  const textByPartId = new Map();
1082
1082
  const partTypeById = new Map();
1083
1083
  let sawStdout = false;
1084
+ let cancelEscalationTimer = null;
1085
+ let cancelWatcher = null;
1086
+ const clearCancelWatcher = () => {
1087
+ if (cancelWatcher) {
1088
+ clearInterval(cancelWatcher);
1089
+ cancelWatcher = null;
1090
+ }
1091
+ if (cancelEscalationTimer) {
1092
+ clearTimeout(cancelEscalationTimer);
1093
+ cancelEscalationTimer = null;
1094
+ }
1095
+ };
1096
+ const killActiveChild = (signal) => {
1097
+ try {
1098
+ if (!child.killed)
1099
+ child.kill(signal);
1100
+ }
1101
+ catch {
1102
+ /* ignore */
1103
+ }
1104
+ };
1105
+ cancelWatcher = setInterval(() => {
1106
+ if (!callbacks.getCancelRequested?.())
1107
+ return;
1108
+ clearCancelWatcher();
1109
+ killActiveChild("SIGTERM");
1110
+ cancelEscalationTimer = setTimeout(() => killActiveChild("SIGKILL"), 2000);
1111
+ }, 500);
1084
1112
  let progressTicker = setInterval(() => {
1085
1113
  if (sawStdout) {
1086
1114
  if (progressTicker) {
@@ -1236,6 +1264,7 @@ function runOpencode(prompt, model, childEnv, opencodeSessionId, callbacks, atta
1236
1264
  });
1237
1265
  child.on("close", (code) => {
1238
1266
  callbacks.onActiveChild?.(null);
1267
+ clearCancelWatcher();
1239
1268
  if (progressTicker) {
1240
1269
  clearInterval(progressTicker);
1241
1270
  progressTicker = null;
@@ -1674,29 +1703,40 @@ export async function runChimphands(opts) {
1674
1703
  };
1675
1704
  if (userId)
1676
1705
  childEnv.TESTCHIMP_USER_ID = userId;
1706
+ const handleCancelTurn = () => {
1707
+ cancelTurnRequested = true;
1708
+ const ch = activeOpencodeChild;
1709
+ if (ch && !ch.killed) {
1710
+ try {
1711
+ ch.kill("SIGTERM");
1712
+ setTimeout(() => {
1713
+ try {
1714
+ if (!ch.killed)
1715
+ ch.kill("SIGKILL");
1716
+ }
1717
+ catch {
1718
+ /* ignore */
1719
+ }
1720
+ }, 2000);
1721
+ }
1722
+ catch {
1723
+ /* ignore */
1724
+ }
1725
+ }
1726
+ };
1677
1727
  const stopInbound = connectInboundStream(backend, apiKey, sessionId, {
1678
1728
  onUserMessage: enqueueUserMessage,
1679
1729
  onIdle: () => {
1680
1730
  idle = true;
1681
1731
  },
1682
- onCancelTurn: () => {
1683
- cancelTurnRequested = true;
1684
- const ch = activeOpencodeChild;
1685
- if (ch && !ch.killed) {
1686
- try {
1687
- ch.kill("SIGTERM");
1688
- }
1689
- catch {
1690
- /* ignore */
1691
- }
1692
- }
1693
- },
1732
+ onCancelTurn: handleCancelTurn,
1694
1733
  onUserFileEdit: handleUserFileEdit,
1695
1734
  shouldRun: () => sessionActive,
1696
1735
  });
1697
1736
  if (runtimeId && attachUrl) {
1698
1737
  stopTunnel = startTunnelWorker(backend, apiKey, runtimeId, attachUrl, sessionId, {
1699
1738
  onUserFileEdit: handleUserFileEdit,
1739
+ onCancelTurn: handleCancelTurn,
1700
1740
  });
1701
1741
  }
1702
1742
  const shutdownRuntime = async () => {
@@ -2109,6 +2149,14 @@ function startTunnelWorker(backend, apiKey, runtimeId, attachUrl, sessionId, han
2109
2149
  socket.send(JSON.stringify({ type: "pong" }));
2110
2150
  return;
2111
2151
  }
2152
+ if (frame.type === "inbound_event" && frame.event === "cancel_turn") {
2153
+ const payload = frame.data;
2154
+ if (payload?.sessionId && payload.sessionId !== sessionId) {
2155
+ return;
2156
+ }
2157
+ handlers?.onCancelTurn?.();
2158
+ return;
2159
+ }
2112
2160
  if (frame.type === "inbound_event" && frame.event === "user_file_edit" && frame.data) {
2113
2161
  const edit = frame.data;
2114
2162
  if (edit.sessionId && edit.sessionId !== sessionId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testchimp/cli",
3
- "version": "0.1.60",
3
+ "version": "0.1.61",
4
4
  "description": "TestChimp CLI and MCP server — coverage, plans, EaaS, TrueCoverage, API operations (calls /api/mcp/*)",
5
5
  "type": "module",
6
6
  "main": "dist/bin/testchimp.js",