@retasc/cli 1.34.0 → 1.34.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 CHANGED
@@ -6,6 +6,19 @@ release commits and the issues they reference.
6
6
 
7
7
  Dates are the npm publish date. Each entry names the RTSC issue behind it.
8
8
 
9
+ ## 1.34.1 (2026-08-25)
10
+
11
+ - **RTSC-741** — a rejected write no longer costs you the lease. The watchdog decided
12
+ when to stop heartbeating an issue by looking at the request you sent, never at whether
13
+ the server accepted it. So a `save_issue` that came back an error still dropped the
14
+ issue from the heartbeat map while you were still holding it. Nothing renewed it after
15
+ that, it ran out its half hour, and the reclaimer handed your work to another agent
16
+ while you were in the middle of it, with no sign anything had gone wrong. Every drop
17
+ now requires the call to have actually succeeded. The trigger is the new server-side
18
+ rule that moving an issue into `review` must carry a handoff: a rejection on that write
19
+ is the expected first attempt for any agent that has not learned the field yet, so a
20
+ rare edge became a common one.
21
+
9
22
  ## 1.34.0 (2026-08-24)
10
23
 
11
24
  - **RTSC-731** — `bind` stops asking whether you want to join an org you are already in.
@@ -18,6 +18,9 @@ function idOf(issue) {
18
18
  * - next_batch(claim) response → { issues:[{id, claimToken}] } → register each
19
19
  * - release_issue request → drop that issue's lease
20
20
  * - save_issue(status: done|canceled) request → drop that issue's lease
21
+ *
22
+ * Every drop requires the call to have SUCCEEDED (RTSC-741) — a rejected write leaves
23
+ * the lease in place, because the agent still holds the issue server-side.
21
24
  */
22
25
  export function applyObservation(leases, o) {
23
26
  const r = o.result;
@@ -37,7 +40,24 @@ export function applyObservation(leases, o) {
37
40
  }
38
41
  }
39
42
  // Releases / terminal status drop the lease — the issue is named in the REQUEST.
40
- const id = typeof o.args?.identifier === "string" ? o.args.identifier : undefined;
43
+ //
44
+ // RTSC-741: but ONLY if the call actually succeeded. These branches read the REQUEST
45
+ // shape, so a REJECTED write used to drop the lease of an issue the agent still holds
46
+ // server-side. Nothing then renews it, it runs out the bare 30-minute TTL, and the
47
+ // reclaimer hands the issue to someone else while the agent is still working on it.
48
+ // `shouldReapOnClose` below already applies exactly this check for the same reason.
49
+ //
50
+ // It matters now because RTSC-741 made `save_issue status:"review"` REJECTABLE
51
+ // (HANDOFF_REQUIRED): a rejected review write is the expected first attempt for any
52
+ // agent that hasn't learned the field yet, and for every already-running session whose
53
+ // cached tool schema predates the deploy. What was a rare edge is briefly the norm.
54
+ //
55
+ // Erring toward KEEPING the lease is the safe direction, and the module already relies
56
+ // on it: a lease held after the server released it just fails its next heartbeat and
57
+ // self-heals (see the send-back note below), whereas a lease dropped too early is
58
+ // silent and costs the agent its work.
59
+ const succeeded = !!o.result && !isToolError(o.result);
60
+ const id = succeeded && typeof o.args?.identifier === "string" ? o.args.identifier : undefined;
41
61
  if (id && o.toolName === "release_issue")
42
62
  leases.delete(id);
43
63
  // RTSC-321: moving to `review` (RTSC-257) hands the lease back server-side (the
@@ -49,7 +69,7 @@ export function applyObservation(leases, o) {
49
69
  // failed-heartbeat path instead.)
50
70
  if (id && o.toolName === "save_issue" && o.args?.status === "review")
51
71
  leases.delete(id);
52
- const closeId = terminalCloseId(o);
72
+ const closeId = succeeded ? terminalCloseId(o) : undefined;
53
73
  if (closeId)
54
74
  leases.delete(closeId);
55
75
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@retasc/cli",
3
- "version": "1.34.0",
4
- "description": "Retasc CLI \u2014 the issue tracker AI agents pull work from. Sign in with GitHub or Google, create projects, mint agent API keys, and wire your agent to the Retasc MCP server in one command.",
3
+ "version": "1.34.1",
4
+ "description": "Retasc CLI the issue tracker AI agents pull work from. Sign in with GitHub or Google, create projects, mint agent API keys, and wire your agent to the Retasc MCP server in one command.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "retasc": "dist/index.js"