@stigmer/runner 3.40.1 → 3.41.0

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 (248) hide show
  1. package/README.md +3 -1
  2. package/dist/.build-fingerprint +1 -1
  3. package/dist/__test-utils__/execution-record-fixture.d.ts +2 -1
  4. package/dist/__test-utils__/execution-record-fixture.js.map +1 -1
  5. package/dist/activities/call-agent.js +1 -1
  6. package/dist/activities/discover-mcp-server.d.ts +7 -1
  7. package/dist/activities/discover-mcp-server.js +13 -29
  8. package/dist/activities/discover-mcp-server.js.map +1 -1
  9. package/dist/activities/execute-cursor/__test-utils__/fold.d.ts +4 -2
  10. package/dist/activities/execute-cursor/__test-utils__/fold.js +3 -4
  11. package/dist/activities/execute-cursor/__test-utils__/fold.js.map +1 -1
  12. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +1 -0
  13. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
  14. package/dist/activities/execute-cursor/approval-policy.d.ts +1 -29
  15. package/dist/activities/execute-cursor/approval-policy.js +11 -35
  16. package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
  17. package/dist/activities/execute-cursor/boundary-rows.js +4 -4
  18. package/dist/activities/execute-cursor/boundary-rows.js.map +1 -1
  19. package/dist/activities/execute-cursor/translator.d.ts +12 -17
  20. package/dist/activities/execute-cursor/translator.js +13 -30
  21. package/dist/activities/execute-cursor/translator.js.map +1 -1
  22. package/dist/activities/execute-cursor/turn-stream.js +4 -2
  23. package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
  24. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +11 -1
  25. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +22 -3
  26. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -1
  27. package/dist/activities/execute-deep-agent/inline-publisher.d.ts +33 -2
  28. package/dist/activities/execute-deep-agent/inline-publisher.js +33 -7
  29. package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
  30. package/dist/activities/execute-deep-agent/platform-route.d.ts +48 -13
  31. package/dist/activities/execute-deep-agent/platform-route.js +87 -19
  32. package/dist/activities/execute-deep-agent/platform-route.js.map +1 -1
  33. package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +20 -3
  34. package/dist/activities/execute-deep-agent/streaming-side-effects.js +26 -4
  35. package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
  36. package/dist/activities/execute-deep-agent/translator.d.ts +5 -4
  37. package/dist/activities/execute-deep-agent/translator.js +5 -4
  38. package/dist/activities/execute-deep-agent/translator.js.map +1 -1
  39. package/dist/activities/execute-deep-agent/turn-settle.js +6 -6
  40. package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -1
  41. package/dist/activities/execute-deep-agent/turn-setup.js +7 -7
  42. package/dist/activities/execute-deep-agent/turn-setup.js.map +1 -1
  43. package/dist/activities/execute-deep-agent/turn-stream.d.ts +10 -6
  44. package/dist/activities/execute-deep-agent/turn-stream.js +6 -16
  45. package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -1
  46. package/dist/activities/execute-deep-agent/turn.d.ts +4 -1
  47. package/dist/activities/execute-deep-agent/turn.js +15 -6
  48. package/dist/activities/execute-deep-agent/turn.js.map +1 -1
  49. package/dist/activities/workflow-event-activities.js +2 -0
  50. package/dist/activities/workflow-event-activities.js.map +1 -1
  51. package/dist/config.d.ts +9 -0
  52. package/dist/config.js +2 -0
  53. package/dist/config.js.map +1 -1
  54. package/dist/exit-backstop.d.ts +64 -0
  55. package/dist/exit-backstop.js +79 -0
  56. package/dist/exit-backstop.js.map +1 -0
  57. package/dist/harness/terminal-table.d.ts +12 -5
  58. package/dist/harness/terminal-table.js +13 -13
  59. package/dist/harness/terminal-table.js.map +1 -1
  60. package/dist/harness/transcript/builder.d.ts +21 -0
  61. package/dist/harness/transcript/builder.js +53 -31
  62. package/dist/harness/transcript/builder.js.map +1 -1
  63. package/dist/harness/transcript/events.d.ts +22 -26
  64. package/dist/harness/transcript/events.js +6 -5
  65. package/dist/harness/transcript/events.js.map +1 -1
  66. package/dist/harness/turn-context.d.ts +3 -1
  67. package/dist/harness/turn-context.js +5 -3
  68. package/dist/harness/turn-context.js.map +1 -1
  69. package/dist/main.js +10 -4
  70. package/dist/main.js.map +1 -1
  71. package/dist/middleware/cost-advisory.d.ts +6 -3
  72. package/dist/middleware/cost-advisory.js +6 -3
  73. package/dist/middleware/cost-advisory.js.map +1 -1
  74. package/dist/middleware/execution-budget.d.ts +22 -7
  75. package/dist/middleware/execution-budget.js +57 -35
  76. package/dist/middleware/execution-budget.js.map +1 -1
  77. package/dist/middleware/index.d.ts +10 -7
  78. package/dist/middleware/index.js +10 -7
  79. package/dist/middleware/index.js.map +1 -1
  80. package/dist/middleware/types.d.ts +6 -1
  81. package/dist/runner-manager.js +3 -2
  82. package/dist/runner-manager.js.map +1 -1
  83. package/dist/runner.d.ts +25 -0
  84. package/dist/runner.js +41 -14
  85. package/dist/runner.js.map +1 -1
  86. package/dist/shared/approval-policy.d.ts +23 -13
  87. package/dist/shared/approval-policy.js +47 -14
  88. package/dist/shared/approval-policy.js.map +1 -1
  89. package/dist/shared/caller-identity.d.ts +4 -5
  90. package/dist/shared/caller-identity.js +4 -5
  91. package/dist/shared/caller-identity.js.map +1 -1
  92. package/dist/shared/channel-attachment.js +3 -2
  93. package/dist/shared/channel-attachment.js.map +1 -1
  94. package/dist/shared/connect-backfill.d.ts +2 -1
  95. package/dist/shared/connect-backfill.js +2 -2
  96. package/dist/shared/connect-backfill.js.map +1 -1
  97. package/dist/shared/mcp-resolver.d.ts +10 -1
  98. package/dist/shared/mcp-resolver.js +11 -2
  99. package/dist/shared/mcp-resolver.js.map +1 -1
  100. package/dist/shared/memory-attachment.js +3 -2
  101. package/dist/shared/memory-attachment.js.map +1 -1
  102. package/dist/shared/model-error.d.ts +25 -3
  103. package/dist/shared/model-error.js +78 -10
  104. package/dist/shared/model-error.js.map +1 -1
  105. package/dist/shared/platform-server-address.d.ts +71 -0
  106. package/dist/shared/platform-server-address.js +103 -0
  107. package/dist/shared/platform-server-address.js.map +1 -0
  108. package/dist/shared/synthesized-attachment.d.ts +0 -5
  109. package/dist/shared/synthesized-attachment.js +0 -12
  110. package/dist/shared/synthesized-attachment.js.map +1 -1
  111. package/dist/shared/tool-rounds.d.ts +51 -23
  112. package/dist/shared/tool-rounds.js +67 -24
  113. package/dist/shared/tool-rounds.js.map +1 -1
  114. package/dist/shared/workspace/platform-dir.d.ts +15 -0
  115. package/dist/shared/workspace/platform-dir.js +18 -1
  116. package/dist/shared/workspace/platform-dir.js.map +1 -1
  117. package/dist/shared/workspace/stigmer-link.d.ts +21 -14
  118. package/dist/shared/workspace/stigmer-link.js +91 -29
  119. package/dist/shared/workspace/stigmer-link.js.map +1 -1
  120. package/dist/tools/url-guard.d.ts +5 -1
  121. package/dist/tools/url-guard.js +9 -2
  122. package/dist/tools/url-guard.js.map +1 -1
  123. package/dist/worker.d.ts +11 -2
  124. package/dist/worker.js +1 -1
  125. package/dist/worker.js.map +1 -1
  126. package/dist/workflow-engine/tasks/human-input.d.ts +16 -0
  127. package/dist/workflow-engine/tasks/human-input.js +79 -37
  128. package/dist/workflow-engine/tasks/human-input.js.map +1 -1
  129. package/dist/workflow-engine/types.d.ts +14 -4
  130. package/dist/workflow-engine/types.js.map +1 -1
  131. package/dist/workflows/call-agent-orchestrator.d.ts +13 -0
  132. package/dist/workflows/call-agent-orchestrator.js.map +1 -1
  133. package/dist/workflows/engine-core.d.ts +25 -0
  134. package/dist/workflows/engine-core.js.map +1 -1
  135. package/dist/workflows/execute-from-execution.d.ts +3 -0
  136. package/dist/workflows/execute-from-execution.js.map +1 -1
  137. package/dist/workflows/human-input-orchestrator.d.ts +9 -12
  138. package/dist/workflows/human-input-orchestrator.js +12 -44
  139. package/dist/workflows/human-input-orchestrator.js.map +1 -1
  140. package/package.json +5 -5
  141. package/src/__test-utils__/config-fixture.ts +1 -0
  142. package/src/__test-utils__/execution-record-fixture.ts +2 -1
  143. package/src/__test-utils__/harness-contract/runtime-contract.ts +5 -3
  144. package/src/__test-utils__/test-gate.ts +8 -0
  145. package/src/__tests__/exit-backstop.test.ts +91 -0
  146. package/src/__tests__/golden-e2e.test.ts +80 -62
  147. package/src/__tests__/history-encryption-e2e.test.ts +51 -27
  148. package/src/__tests__/runner.test.ts +60 -2
  149. package/src/activities/__tests__/classify-tool-approvals.test.ts +1 -0
  150. package/src/activities/__tests__/discover-mcp-server.hang.test.ts +5 -1
  151. package/src/activities/__tests__/discover-mcp-server.test.ts +90 -49
  152. package/src/activities/__tests__/workflow-event-activities.test.ts +28 -7
  153. package/src/activities/call-agent.ts +1 -1
  154. package/src/activities/discover-mcp-server.ts +27 -37
  155. package/src/activities/execute-cursor/__test-utils__/fold.ts +6 -4
  156. package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +1 -0
  157. package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +4 -29
  158. package/src/activities/execute-cursor/__tests__/hermetic/bypassed-tool-call.test.ts +120 -0
  159. package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +5 -5
  160. package/src/activities/execute-cursor/__tests__/hermetic/goldens/file-review-capture.status.json +0 -2
  161. package/src/activities/execute-cursor/__tests__/hermetic/goldens/resolution-error.status.json +1 -1
  162. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.error-delta.status.json +0 -3
  163. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.output-first.status.json +0 -2
  164. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.status.json +0 -2
  165. package/src/activities/execute-cursor/__tests__/hermetic/goldens/stall.status.json +0 -2
  166. package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +0 -3
  167. package/src/activities/execute-cursor/__tests__/hermetic/shell-output-delta.test.ts +9 -7
  168. package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +6 -1
  169. package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +8 -11
  170. package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +1 -3
  171. package/src/activities/execute-cursor/__tests__/translator.test.ts +68 -15
  172. package/src/activities/execute-cursor/approval-policy.ts +11 -36
  173. package/src/activities/execute-cursor/boundary-rows.ts +3 -3
  174. package/src/activities/execute-cursor/translator.ts +15 -32
  175. package/src/activities/execute-cursor/turn-stream.ts +4 -1
  176. package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +33 -2
  177. package/src/activities/execute-deep-agent/__tests__/adapter.test.ts +1 -0
  178. package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +4 -0
  179. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +1 -1
  180. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +1 -1
  181. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +1 -1
  182. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +8 -73
  183. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/resolution-error.status.json +1 -1
  184. package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +17 -0
  185. package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +86 -26
  186. package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +9 -5
  187. package/src/activities/execute-deep-agent/__tests__/hermetic/thrown-turn-drains-publishes.test.ts +159 -0
  188. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +84 -0
  189. package/src/activities/execute-deep-agent/__tests__/platform-route.test.ts +47 -10
  190. package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +34 -0
  191. package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +13 -5
  192. package/src/activities/execute-deep-agent/inline-publisher.ts +47 -7
  193. package/src/activities/execute-deep-agent/platform-route.ts +109 -20
  194. package/src/activities/execute-deep-agent/streaming-side-effects.ts +27 -4
  195. package/src/activities/execute-deep-agent/translator.ts +5 -4
  196. package/src/activities/execute-deep-agent/turn-settle.ts +6 -6
  197. package/src/activities/execute-deep-agent/turn-setup.ts +7 -7
  198. package/src/activities/execute-deep-agent/turn-stream.ts +15 -22
  199. package/src/activities/execute-deep-agent/turn.ts +16 -7
  200. package/src/activities/workflow-event-activities.ts +2 -0
  201. package/src/config.ts +11 -0
  202. package/src/exit-backstop.ts +97 -0
  203. package/src/harness/README.md +5 -5
  204. package/src/harness/terminal-table.ts +13 -13
  205. package/src/harness/transcript/__tests__/builder.test.ts +93 -21
  206. package/src/harness/transcript/builder.ts +53 -30
  207. package/src/harness/transcript/events.ts +22 -27
  208. package/src/harness/turn-context.ts +5 -3
  209. package/src/main.ts +9 -5
  210. package/src/middleware/__tests__/execution-budget.test.ts +181 -103
  211. package/src/middleware/cost-advisory.ts +6 -3
  212. package/src/middleware/execution-budget.ts +60 -34
  213. package/src/middleware/index.ts +10 -7
  214. package/src/middleware/types.ts +6 -1
  215. package/src/runner-manager.ts +3 -2
  216. package/src/runner.ts +57 -15
  217. package/src/shared/__tests__/approval-policy.test.ts +41 -0
  218. package/src/shared/__tests__/artifact-storage.test.ts +1 -0
  219. package/src/shared/__tests__/connect-backfill.test.ts +15 -11
  220. package/src/shared/__tests__/mcp-resolver.test.ts +72 -10
  221. package/src/shared/__tests__/model-error.test.ts +71 -3
  222. package/src/shared/__tests__/platform-server-address.test.ts +122 -0
  223. package/src/shared/__tests__/tool-rounds.test.ts +64 -14
  224. package/src/shared/approval-policy.ts +57 -14
  225. package/src/shared/caller-identity.ts +4 -5
  226. package/src/shared/channel-attachment.ts +2 -2
  227. package/src/shared/connect-backfill.ts +5 -1
  228. package/src/shared/mcp-resolver.ts +11 -1
  229. package/src/shared/memory-attachment.ts +2 -2
  230. package/src/shared/model-error.ts +87 -9
  231. package/src/shared/platform-server-address.ts +123 -0
  232. package/src/shared/synthesized-attachment.ts +0 -12
  233. package/src/shared/tool-rounds.ts +70 -24
  234. package/src/shared/workspace/__tests__/stigmer-link.test.ts +107 -10
  235. package/src/shared/workspace/platform-dir.ts +19 -1
  236. package/src/shared/workspace/stigmer-link.ts +99 -29
  237. package/src/tools/__tests__/url-guard.test.ts +19 -1
  238. package/src/tools/url-guard.ts +9 -1
  239. package/src/worker.ts +12 -2
  240. package/src/workflow-engine/__tests__/golden-execution.test.ts +2 -1
  241. package/src/workflow-engine/__tests__/loader.test.ts +1 -1
  242. package/src/workflow-engine/__tests__/tasks/human-input.test.ts +133 -57
  243. package/src/workflow-engine/tasks/human-input.ts +92 -42
  244. package/src/workflow-engine/types.ts +16 -4
  245. package/src/workflows/call-agent-orchestrator.ts +7 -0
  246. package/src/workflows/engine-core.ts +18 -0
  247. package/src/workflows/execute-from-execution.ts +2 -1
  248. package/src/workflows/human-input-orchestrator.ts +15 -56
@@ -1,18 +1,28 @@
1
1
  /**
2
- * ExecutionConfig.max_tool_rounds → LangGraph recursion_limit resolution.
2
+ * ExecutionConfig.max_tool_rounds: the round budget, its backstop, and the
3
+ * signal that the budget ended a turn.
3
4
  *
4
5
  * Implements the proto contract (agentexecution/v1/spec.proto):
5
- * - 0 / unset = unlimited — no recursionLimit is placed on the invoke
6
- * config, preserving the run-until-done + loop-detection posture.
6
+ * - 0 / unset = unlimited: no round limit and no recursionLimit, preserving
7
+ * the run-until-done + loop-detection posture.
7
8
  * - When set, valid range is 10–1000 rounds; out-of-range values are
8
9
  * clamped to the nearest bound with a warning log.
9
- * - recursion_limit = rounds × 6: each model-tool round consumes multiple
10
- * graph super-steps because every active middleware hook is its own
11
- * node; ×6 is the contract's floor estimate.
10
+ * - A round is one model response that proposes one or more tool calls,
11
+ * followed by their execution; parallel calls are one round.
12
12
  *
13
- * The SAME resolved limit must feed both LangGraph's hard stop (the invoke
14
- * config) and the ExecutionBudgetMiddleware's wrap-up advisory, so the
15
- * "~80% of budget" warning and the enforcement point can never disagree.
13
+ * The budget is COUNTED, not estimated. `middleware/execution-budget.ts`
14
+ * counts rounds where the model is called and throws
15
+ * {@link ToolRoundLimitError} before round N+1's model call, so N rounds
16
+ * run on every middleware stack. The count and the "~80% of budget"
17
+ * advisory live in that one middleware, so they can never disagree. Until
18
+ * #1113 the budget was LangGraph's recursion limit at rounds × 6 super-steps,
19
+ * and because every middleware hook is its own graph node, how many rounds
20
+ * fitted moved whenever the stack did.
21
+ *
22
+ * LangGraph's recursion limit stays only as a backstop
23
+ * ({@link backstopRecursionLimit}): generous enough never to bind before the
24
+ * round count on any stack, it halts a graph that loops without calling the
25
+ * model. Either stop is the same outcome ({@link isToolCallBudgetStop}).
16
26
  *
17
27
  * The knob and its terminal copy live together (the `cost-guard.ts` shape):
18
28
  * when the budget is exhausted the adapter ends its turn `tool_call_limit`
@@ -20,24 +30,34 @@
20
30
  * below — the platform deliberately stopped the run, work is checkpointed,
21
31
  * and the conversation continues on the next message.
22
32
  */
23
- export const SUPER_STEPS_PER_ROUND = 6;
33
+ import { unwrapModelError } from "./model-error.js";
24
34
  export const MIN_TOOL_ROUNDS = 10;
25
35
  export const MAX_TOOL_ROUNDS = 1000;
26
36
  /**
27
- * The advisory-only budget used when max_tool_rounds is unset: high enough
28
- * to never fire on a healthy run. Deliberately NOT enforced as a hard
29
- * recursionLimit — unset means unlimited per the proto contract.
37
+ * Super-steps per round the backstop allows: well above the graph nodes one
38
+ * round costs on any stack the runner builds (about five today), so the
39
+ * round count, never the backstop, is what a bounded run meets.
40
+ */
41
+ export const SUPER_STEPS_BACKSTOP_PER_ROUND = 20;
42
+ /**
43
+ * The advisory-only round budget used when max_tool_rounds is unset: high
44
+ * enough to never fire on a healthy run. Deliberately NOT enforced — unset
45
+ * means unlimited per the proto contract.
30
46
  */
31
- export const UNBOUNDED_ADVISORY_RECURSION_LIMIT = 6000;
47
+ export const UNBOUNDED_ADVISORY_TOOL_ROUNDS = MAX_TOOL_ROUNDS;
32
48
  /**
33
- * The recursionLimit for the invoke config, or null when the execution is
34
- * unbounded (max_tool_rounds 0/unset — the pre-existing default posture).
49
+ * The round budget for a turn, clamped to the valid range, or null when the
50
+ * execution is unbounded (max_tool_rounds 0/unset — the default posture).
35
51
  */
36
- export function resolveRecursionLimit(maxToolRounds) {
52
+ export function resolveToolRoundLimit(maxToolRounds) {
37
53
  if (!maxToolRounds || maxToolRounds <= 0) {
38
54
  return null;
39
55
  }
40
- return clampToolRounds(maxToolRounds) * SUPER_STEPS_PER_ROUND;
56
+ return clampToolRounds(maxToolRounds);
57
+ }
58
+ /** The recursionLimit backstop for a bounded turn's invoke config; see {@link SUPER_STEPS_BACKSTOP_PER_ROUND}. */
59
+ export function backstopRecursionLimit(toolRoundLimit) {
60
+ return toolRoundLimit * SUPER_STEPS_BACKSTOP_PER_ROUND;
41
61
  }
42
62
  function clampToolRounds(requested) {
43
63
  if (requested < MIN_TOOL_ROUNDS) {
@@ -75,13 +95,36 @@ export const TOOL_CALL_LIMIT_USER_COPY = "The agent reached the tool-call limit
75
95
  "Work completed so far has been saved. " +
76
96
  "Send another message to continue where the agent left off.";
77
97
  /**
78
- * Whether an error thrown out of a LangGraph run is the graph exhausting the
79
- * recursion limit `resolveRecursionLimit` placed on it — the budget's own
80
- * signal, not a failure: the adapter ends the turn `tool_call_limit`.
81
- * Matched by class name and message because the error class is not
82
- * exported on a stable path across `@langchain/langgraph` versions.
98
+ * The execution budget's stop: thrown by `middleware/execution-budget.ts` in
99
+ * place of round N+1's model call, so the graph ends on round N's tool
100
+ * results with no proposed call left unexecuted.
101
+ */
102
+ export class ToolRoundLimitError extends Error {
103
+ toolRoundLimit;
104
+ constructor(toolRoundLimit) {
105
+ super(`Tool-round limit reached: ${toolRoundLimit} rounds`);
106
+ this.toolRoundLimit = toolRoundLimit;
107
+ this.name = "ToolRoundLimitError";
108
+ }
109
+ }
110
+ /**
111
+ * Whether an error thrown out of a LangGraph run is the tool-call budget
112
+ * ending the turn — the budget's own signal, not a failure: the adapter ends
113
+ * the turn `tool_call_limit`. Two producers, one outcome: the round count's
114
+ * {@link ToolRoundLimitError}, which reaches the turn wrapped in LangChain's
115
+ * `MiddlewareError` once per `wrapModelCall` layer (so the cause chain is
116
+ * walked, as `unwrapModelError` does for a model error), and the backstop's
117
+ * `GraphRecursionError`.
118
+ */
119
+ export function isToolCallBudgetStop(err) {
120
+ return unwrapModelError(err) instanceof ToolRoundLimitError || isRecursionLimitError(err);
121
+ }
122
+ /**
123
+ * LangGraph exhausting the backstop recursion limit. Matched by class name and
124
+ * message because the error class is not exported on a stable path across
125
+ * `@langchain/langgraph` versions.
83
126
  */
84
- export function isGraphRecursionError(err) {
127
+ function isRecursionLimitError(err) {
85
128
  if (err instanceof Error) {
86
129
  return err.constructor.name === "GraphRecursionError" ||
87
130
  err.message.includes("GraphRecursionError") ||
@@ -1 +1 @@
1
- {"version":3,"file":"tool-rounds.js","sourceRoot":"","sources":["../../src/shared/tool-rounds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AACvC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,IAAI,CAAC;AAEvD;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,aAAiC;IACrE,IAAI,CAAC,aAAa,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,eAAe,CAAC,aAAa,CAAC,GAAG,qBAAqB,CAAC;AAChE,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB;IACxC,IAAI,SAAS,GAAG,eAAe,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CACV,iCAAiC,SAAS,yBAAyB;YACnE,IAAI,eAAe,IAAI,eAAe,kBAAkB,eAAe,EAAE,CAC1E,CAAC;QACF,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,IAAI,SAAS,GAAG,eAAe,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CACV,iCAAiC,SAAS,yBAAyB;YACnE,IAAI,eAAe,IAAI,eAAe,kBAAkB,eAAe,EAAE,CAC1E,CAAC;QACF,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,mCAAmC,CAAC;AAEhF,6GAA6G;AAC7G,MAAM,UAAU,wBAAwB;IACtC,OAAO,GAAG,4BAA4B,sDAAsD,CAAC;AAC/F,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GACpC,0DAA0D;IAC1D,wCAAwC;IACxC,4DAA4D,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAY;IAChD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,KAAK,qBAAqB;YACnD,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YAC3C,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"tool-rounds.js","sourceRoot":"","sources":["../../src/shared/tool-rounds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,eAAe,CAAC;AAE9D;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,aAAiC;IACrE,IAAI,CAAC,aAAa,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,eAAe,CAAC,aAAa,CAAC,CAAC;AACxC,CAAC;AAED,kHAAkH;AAClH,MAAM,UAAU,sBAAsB,CAAC,cAAsB;IAC3D,OAAO,cAAc,GAAG,8BAA8B,CAAC;AACzD,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB;IACxC,IAAI,SAAS,GAAG,eAAe,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CACV,iCAAiC,SAAS,yBAAyB;YACnE,IAAI,eAAe,IAAI,eAAe,kBAAkB,eAAe,EAAE,CAC1E,CAAC;QACF,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,IAAI,SAAS,GAAG,eAAe,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CACV,iCAAiC,SAAS,yBAAyB;YACnE,IAAI,eAAe,IAAI,eAAe,kBAAkB,eAAe,EAAE,CAC1E,CAAC;QACF,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,mCAAmC,CAAC;AAEhF,6GAA6G;AAC7G,MAAM,UAAU,wBAAwB;IACtC,OAAO,GAAG,4BAA4B,sDAAsD,CAAC;AAC/F,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GACpC,0DAA0D;IAC1D,wCAAwC;IACxC,4DAA4D,CAAC;AAE/D;;;;GAIG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACvB;IAArB,YAAqB,cAAsB;QACzC,KAAK,CAAC,6BAA6B,cAAc,SAAS,CAAC,CAAC;QADzC,mBAAc,GAAd,cAAc,CAAQ;QAEzC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAY;IAC/C,OAAO,gBAAgB,CAAC,GAAG,CAAC,YAAY,mBAAmB,IAAI,qBAAqB,CAAC,GAAG,CAAC,CAAC;AAC5F,CAAC;AAED;;;;GAIG;AACH,SAAS,qBAAqB,CAAC,GAAY;IACzC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,KAAK,qBAAqB;YACnD,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YAC3C,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -10,6 +10,8 @@
10
10
  * a real repo never leaves Stigmer files behind in it (see issue #173); only
11
11
  * a minimal, transient `.cursor/hooks.json` referencing the absolute script
12
12
  * path is written into the workspace itself.
13
+ * - `displaced/` — a real `.stigmer` entry found in the workspace when the
14
+ * platform link takes the name, kept rather than deleted (stigmer-link.ts).
13
15
  *
14
16
  * This module replaces the duplicated `getPlatformDir` helpers in
15
17
  * execute-cursor/skill-resolver.ts and shared/attachment-resolver.ts.
@@ -70,6 +72,19 @@ export declare function ensureCheckpointDbPath(sessionId: string): Promise<strin
70
72
  * safe to call multiple times for the same session.
71
73
  */
72
74
  export declare function ensurePlatformDir(sessionId: string): Promise<string>;
75
+ /**
76
+ * Compute where a real `.stigmer` entry found in a workspace is moved when the
77
+ * platform link takes the name — `displaced/<stamp>` beside the session's
78
+ * `platform/` and `hitl/` trees (see stigmer-link.ts). Outside the workspace,
79
+ * so a real repo is never left holding it (issue #173) and a write-back never
80
+ * commits it; outside `platform/`, so the agent never reads it back as
81
+ * platform content.
82
+ *
83
+ * Takes the platform dir rather than a session id, unlike its siblings: the
84
+ * link step knows only the dir it links to, and the session dir is its parent.
85
+ * Pure function — performs no I/O.
86
+ */
87
+ export declare function getDisplacedDir(platformDir: string, stamp: string): string;
73
88
  /**
74
89
  * Compute the HITL directory path for a session — the runner-owned home for the
75
90
  * approval gate's hook script, approval-state file, and denial ledger.
@@ -10,11 +10,13 @@
10
10
  * a real repo never leaves Stigmer files behind in it (see issue #173); only
11
11
  * a minimal, transient `.cursor/hooks.json` referencing the absolute script
12
12
  * path is written into the workspace itself.
13
+ * - `displaced/` — a real `.stigmer` entry found in the workspace when the
14
+ * platform link takes the name, kept rather than deleted (stigmer-link.ts).
13
15
  *
14
16
  * This module replaces the duplicated `getPlatformDir` helpers in
15
17
  * execute-cursor/skill-resolver.ts and shared/attachment-resolver.ts.
16
18
  */
17
- import { join } from "node:path";
19
+ import { dirname, join } from "node:path";
18
20
  import { mkdir } from "node:fs/promises";
19
21
  import { homedir } from "node:os";
20
22
  import { createHash } from "node:crypto";
@@ -100,6 +102,21 @@ export async function ensurePlatformDir(sessionId) {
100
102
  await mkdir(dir, { recursive: true });
101
103
  return dir;
102
104
  }
105
+ /**
106
+ * Compute where a real `.stigmer` entry found in a workspace is moved when the
107
+ * platform link takes the name — `displaced/<stamp>` beside the session's
108
+ * `platform/` and `hitl/` trees (see stigmer-link.ts). Outside the workspace,
109
+ * so a real repo is never left holding it (issue #173) and a write-back never
110
+ * commits it; outside `platform/`, so the agent never reads it back as
111
+ * platform content.
112
+ *
113
+ * Takes the platform dir rather than a session id, unlike its siblings: the
114
+ * link step knows only the dir it links to, and the session dir is its parent.
115
+ * Pure function — performs no I/O.
116
+ */
117
+ export function getDisplacedDir(platformDir, stamp) {
118
+ return join(dirname(platformDir), "displaced", stamp);
119
+ }
103
120
  /**
104
121
  * Compute the HITL directory path for a session — the runner-owned home for the
105
122
  * approval gate's hook script, approval-state file, and denial ledger.
@@ -1 +1 @@
1
- {"version":3,"file":"platform-dir.js","sourceRoot":"","sources":["../../../src/shared/workspace/platform-dir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,qFAAqF;AACrF,SAAS,cAAc;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,EAAE,CAAC;AAClE,CAAC;AAED,+EAA+E;AAC/E,SAAS,aAAa,CAAC,SAAiB;IACtC,OAAO,IAAI,CAAC,cAAc,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,cAAc,CAAC,aAAqB;IAClD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAClF,OAAO,IAAI,CAAC,cAAc,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,aAAqB;IAC3D,MAAM,GAAG,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;IAC1C,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,SAAiB;IAC5D,MAAM,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,OAAO,mBAAmB,CAAC,SAAS,CAAC,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAiB;IACvD,MAAM,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACtC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IAClC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"platform-dir.js","sourceRoot":"","sources":["../../../src/shared/workspace/platform-dir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,qFAAqF;AACrF,SAAS,cAAc;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,EAAE,CAAC;AAClE,CAAC;AAED,+EAA+E;AAC/E,SAAS,aAAa,CAAC,SAAiB;IACtC,OAAO,IAAI,CAAC,cAAc,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,cAAc,CAAC,aAAqB;IAClD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAClF,OAAO,IAAI,CAAC,cAAc,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,aAAqB;IAC3D,MAAM,GAAG,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;IAC1C,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,SAAiB;IAC5D,MAAM,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,OAAO,mBAAmB,CAAC,SAAS,CAAC,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAiB;IACvD,MAAM,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACtC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB,EAAE,KAAa;IAChE,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IAClC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -11,10 +11,10 @@
11
11
  * `.stigmer/…` paths those agents are prompted with (skill locations,
12
12
  * `.stigmer/inputs/…` attachments) actually resolve. The native harness's
13
13
  * FILE tools are the exception: their virtual-rooted backend refuses a path
14
- * whose real location leaves the workspace, so they read the platform dir
15
- * through a read-only `.stigmer/` route instead
16
- * (`activities/execute-deep-agent/platform-route.ts`), mounted on exactly
17
- * the turns this link exists ({@link stigmerSymlinkPointsAt}).
14
+ * whose real location leaves the workspace, so they reach `.stigmer/` through
15
+ * a route instead (`activities/execute-deep-agent/platform-route.ts`),
16
+ * mounted on every turn and exposing the platform dir on exactly the turns
17
+ * this link exists ({@link stigmerSymlinkPointsAt}).
18
18
  *
19
19
  * Lifecycle contract (same for both harnesses):
20
20
  * - Created per turn, under the workspace turn lock — the link is a
@@ -29,21 +29,28 @@
29
29
  * - {@link ensureStigmerSymlink} is idempotent, so multiple populaters may
30
30
  * run in any order within a turn.
31
31
  *
32
- * OWNERSHIP SHARP EDGE: the platform owns the `.stigmer` name inside a
33
- * workspace. {@link ensureStigmerSymlink} REPLACES a real (non-symlink)
34
- * `.stigmer` directory it finds there — deliberate, so a directory left
35
- * behind by an older runner can never shadow the platform mount. (A user's
36
- * own `.stigmer` content is unreachable anyway: the runner's
37
- * `LocalWorkspaceBackend` routes every `.stigmer/…` path to the platform
38
- * dir.) Turn-end removal is the conservative half: it only ever removes a
39
- * SYMLINK.
32
+ * OWNERSHIP: the platform owns the `.stigmer` name inside a workspace, but
33
+ * never deletes what it did not make. A real (non-symlink) `.stigmer` entry
34
+ * found where the link goes — left by an older runner, or written by a shell
35
+ * command or a Cursor edit on a turn with no link, where nothing sits between
36
+ * those tools and the disk (#1123) — is MOVED out of the workspace to the
37
+ * session's `displaced/` dir (platform-dir.ts `getDisplacedDir`) and named in
38
+ * a warning; an empty directory is simply removed. Out of the workspace
39
+ * because a write-back commits everything the tree holds (`git add -A`) and
40
+ * git excludes only the exact `.stigmer` name. One case is refused outright:
41
+ * a `.stigmer` that is, or holds, the platform dir itself — a workspace
42
+ * rooted at the home directory, whose `.stigmer` is the Stigmer home (#1424).
43
+ * Turn-end removal is the conservative half: it only ever removes a SYMLINK.
40
44
  */
41
45
  /** The workspace-visible name of the platform namespace. */
42
46
  export declare const STIGMER_LOCAL_STATE_DIR = ".stigmer";
43
47
  /**
44
48
  * Ensure the workspace `.stigmer` symlink points to the platform dir.
45
- * Idempotent: an existing correct link is kept; a stale link (or a non-link
46
- * left behind by an older runner) is replaced.
49
+ * Idempotent: an existing correct link is kept and a stale link is
50
+ * re-pointed. A real entry in the link's place is moved to the session's
51
+ * `displaced/` dir first (an empty directory is removed); a real `.stigmer`
52
+ * that holds the platform dir is refused with an error naming it, before
53
+ * anything is touched. See the module header, OWNERSHIP.
47
54
  */
48
55
  export declare function ensureStigmerSymlink(workspaceDir: string, platformDir: string): Promise<void>;
49
56
  /**
@@ -11,10 +11,10 @@
11
11
  * `.stigmer/…` paths those agents are prompted with (skill locations,
12
12
  * `.stigmer/inputs/…` attachments) actually resolve. The native harness's
13
13
  * FILE tools are the exception: their virtual-rooted backend refuses a path
14
- * whose real location leaves the workspace, so they read the platform dir
15
- * through a read-only `.stigmer/` route instead
16
- * (`activities/execute-deep-agent/platform-route.ts`), mounted on exactly
17
- * the turns this link exists ({@link stigmerSymlinkPointsAt}).
14
+ * whose real location leaves the workspace, so they reach `.stigmer/` through
15
+ * a route instead (`activities/execute-deep-agent/platform-route.ts`),
16
+ * mounted on every turn and exposing the platform dir on exactly the turns
17
+ * this link exists ({@link stigmerSymlinkPointsAt}).
18
18
  *
19
19
  * Lifecycle contract (same for both harnesses):
20
20
  * - Created per turn, under the workspace turn lock — the link is a
@@ -29,45 +29,107 @@
29
29
  * - {@link ensureStigmerSymlink} is idempotent, so multiple populaters may
30
30
  * run in any order within a turn.
31
31
  *
32
- * OWNERSHIP SHARP EDGE: the platform owns the `.stigmer` name inside a
33
- * workspace. {@link ensureStigmerSymlink} REPLACES a real (non-symlink)
34
- * `.stigmer` directory it finds there — deliberate, so a directory left
35
- * behind by an older runner can never shadow the platform mount. (A user's
36
- * own `.stigmer` content is unreachable anyway: the runner's
37
- * `LocalWorkspaceBackend` routes every `.stigmer/…` path to the platform
38
- * dir.) Turn-end removal is the conservative half: it only ever removes a
39
- * SYMLINK.
32
+ * OWNERSHIP: the platform owns the `.stigmer` name inside a workspace, but
33
+ * never deletes what it did not make. A real (non-symlink) `.stigmer` entry
34
+ * found where the link goes — left by an older runner, or written by a shell
35
+ * command or a Cursor edit on a turn with no link, where nothing sits between
36
+ * those tools and the disk (#1123) — is MOVED out of the workspace to the
37
+ * session's `displaced/` dir (platform-dir.ts `getDisplacedDir`) and named in
38
+ * a warning; an empty directory is simply removed. Out of the workspace
39
+ * because a write-back commits everything the tree holds (`git add -A`) and
40
+ * git excludes only the exact `.stigmer` name. One case is refused outright:
41
+ * a `.stigmer` that is, or holds, the platform dir itself — a workspace
42
+ * rooted at the home directory, whose `.stigmer` is the Stigmer home (#1424).
43
+ * Turn-end removal is the conservative half: it only ever removes a SYMLINK.
40
44
  */
41
- import { symlink, readlink, unlink, rm, lstat } from "node:fs/promises";
42
- import { join } from "node:path";
45
+ import { cp, lstat, mkdir, readdir, readlink, realpath, rename, rm, rmdir, symlink, unlink } from "node:fs/promises";
46
+ import { dirname, isAbsolute, join, relative, sep } from "node:path";
47
+ import { getDisplacedDir } from "./platform-dir.js";
43
48
  /** The workspace-visible name of the platform namespace. */
44
49
  export const STIGMER_LOCAL_STATE_DIR = ".stigmer";
45
50
  /**
46
51
  * Ensure the workspace `.stigmer` symlink points to the platform dir.
47
- * Idempotent: an existing correct link is kept; a stale link (or a non-link
48
- * left behind by an older runner) is replaced.
52
+ * Idempotent: an existing correct link is kept and a stale link is
53
+ * re-pointed. A real entry in the link's place is moved to the session's
54
+ * `displaced/` dir first (an empty directory is removed); a real `.stigmer`
55
+ * that holds the platform dir is refused with an error naming it, before
56
+ * anything is touched. See the module header, OWNERSHIP.
49
57
  */
50
58
  export async function ensureStigmerSymlink(workspaceDir, platformDir) {
51
59
  const linkPath = join(workspaceDir, STIGMER_LOCAL_STATE_DIR);
60
+ let entry;
52
61
  try {
53
- const existing = await readlink(linkPath);
54
- if (existing === platformDir)
62
+ entry = await lstat(linkPath);
63
+ }
64
+ catch (err) {
65
+ if (errnoCode(err) !== "ENOENT")
66
+ throw err;
67
+ }
68
+ if (entry?.isSymbolicLink()) {
69
+ if ((await readlink(linkPath)) === platformDir)
55
70
  return;
56
71
  await unlink(linkPath);
57
72
  }
58
- catch (err) {
59
- if (err.code === "ENOENT") {
60
- // No existing symlink
61
- }
62
- else if (err.code === "EINVAL") {
63
- // Exists but is not a symlink — remove the directory
64
- await rm(linkPath, { recursive: true, force: true });
73
+ else if (entry !== undefined) {
74
+ await displaceRealEntry(linkPath, platformDir, entry);
75
+ }
76
+ await symlink(platformDir, linkPath, "dir");
77
+ }
78
+ /**
79
+ * Clear a real `.stigmer` entry out of the link's place without losing it:
80
+ * refuse the Stigmer home, remove an empty directory, move anything else.
81
+ */
82
+ async function displaceRealEntry(linkPath, platformDir, entry) {
83
+ if (entry.isDirectory()) {
84
+ await refuseDirHoldingPlatform(linkPath, platformDir);
85
+ if ((await readdir(linkPath)).length === 0) {
86
+ await rmdir(linkPath);
87
+ return;
65
88
  }
66
- else {
89
+ }
90
+ const destination = getDisplacedDir(platformDir, displacementStamp(new Date()));
91
+ await mkdir(dirname(destination), { recursive: true });
92
+ await moveEntry(linkPath, destination);
93
+ console.warn(`ensureStigmerSymlink: moved the real ${linkPath} out of the workspace to ${destination}; ` +
94
+ "the platform owns the .stigmer name, so the link to the session's platform dir takes its place");
95
+ }
96
+ /**
97
+ * Throw when the real `.stigmer` directory is, or contains, the platform dir:
98
+ * a workspace rooted at the home directory resolves `.stigmer` to the Stigmer
99
+ * home, where the platform dir, the CLI's config and every session live.
100
+ * Compared by real path, so a symlinked or `HOME`-overridden spelling of
101
+ * either side cannot slip past.
102
+ */
103
+ async function refuseDirHoldingPlatform(linkPath, platformDir) {
104
+ const [realLink, realPlatform] = await Promise.all([realpath(linkPath), realpath(platformDir)]);
105
+ const fromLink = relative(realLink, realPlatform);
106
+ const outside = fromLink === ".." || fromLink.startsWith(`..${sep}`) || isAbsolute(fromLink);
107
+ if (!outside) {
108
+ throw new Error(`The workspace's ${linkPath} is the Stigmer home (it holds this session's platform dir, ${platformDir}); ` +
109
+ "use a project directory as the workspace, not the home directory");
110
+ }
111
+ }
112
+ /** Rename, or copy then remove when the destination is on another filesystem (a cloud workspace volume and `$HOME` are). */
113
+ async function moveEntry(source, destination) {
114
+ try {
115
+ await rename(source, destination);
116
+ }
117
+ catch (err) {
118
+ if (errnoCode(err) !== "EXDEV")
67
119
  throw err;
68
- }
120
+ await cp(source, destination, { recursive: true, errorOnExist: true, force: false, verbatimSymlinks: true });
121
+ await rm(source, { recursive: true, force: true });
69
122
  }
70
- await symlink(platformDir, linkPath, "dir");
123
+ }
124
+ /** A compact UTC stamp with milliseconds (`20260929T101500123Z`): sortable, and free of the colons a path should not carry. */
125
+ function displacementStamp(now) {
126
+ return now.toISOString().replace(/[-:.]/g, "");
127
+ }
128
+ /** The errno code of a Node filesystem error, or `undefined` for anything else. */
129
+ function errnoCode(err) {
130
+ if (typeof err !== "object" || err === null || !("code" in err))
131
+ return undefined;
132
+ return typeof err.code === "string" ? err.code : undefined;
71
133
  }
72
134
  /**
73
135
  * Whether the workspace's `.stigmer` is, right now, the link
@@ -102,7 +164,7 @@ export async function removeStigmerSymlink(workspaceDir) {
102
164
  }
103
165
  }
104
166
  catch (err) {
105
- if (err?.code !== "ENOENT") {
167
+ if (errnoCode(err) !== "ENOENT") {
106
168
  console.warn(`removeStigmerSymlink: failed to remove ${linkPath} (non-fatal): ` +
107
169
  `${err instanceof Error ? err.message : err}`);
108
170
  }
@@ -1 +1 @@
1
- {"version":3,"file":"stigmer-link.js","sourceRoot":"","sources":["../../../src/shared/workspace/stigmer-link.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,YAAoB,EACpB,WAAmB;IAEnB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAAC;IAE7D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,QAAQ,KAAK,WAAW;YAAE,OAAO;QACrC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,sBAAsB;QACxB,CAAC;aAAM,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACjC,qDAAqD;YACrD,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,MAAM,OAAO,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,YAAoB,EAAE,WAAmB;IACpF,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC;IACvF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,YAAoB;IAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAAC;IAC7D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAC1B,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAI,GAAG,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CACV,0CAA0C,QAAQ,gBAAgB;gBAClE,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAC9C,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"stigmer-link.js","sourceRoot":"","sources":["../../../src/shared/workspace/stigmer-link.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,11 @@
12
12
  * IPv4-mapped IPv6 is unwrapped, how every resolved address is judged) has
13
13
  * one home, `@stigmer/outbound/egress`, shared with the control plane, which
14
14
  * dials user-supplied URLs too. This module keeps what is the runner's:
15
- * deriving the posture from its mode, and the sentence a model reads.
15
+ * deriving the posture from its mode, and the sentence a model reads. What
16
+ * that sentence may say is the shared rule too (`refusalWithholdsResolution`):
17
+ * on a strict runner a name that does not resolve and one that resolves to
18
+ * a refused address read alike and name no address, because the runner
19
+ * resolves through a network its caller does not own.
16
20
  *
17
21
  * Posture is mode-aware because locality differs, not trust:
18
22
  *
@@ -12,7 +12,11 @@
12
12
  * IPv4-mapped IPv6 is unwrapped, how every resolved address is judged) has
13
13
  * one home, `@stigmer/outbound/egress`, shared with the control plane, which
14
14
  * dials user-supplied URLs too. This module keeps what is the runner's:
15
- * deriving the posture from its mode, and the sentence a model reads.
15
+ * deriving the posture from its mode, and the sentence a model reads. What
16
+ * that sentence may say is the shared rule too (`refusalWithholdsResolution`):
17
+ * on a strict runner a name that does not resolve and one that resolves to
18
+ * a refused address read alike and name no address, because the runner
19
+ * resolves through a network its caller does not own.
16
20
  *
17
21
  * Posture is mode-aware because locality differs, not trust:
18
22
  *
@@ -37,7 +41,7 @@
37
41
  * The accepted DNS-rebinding limitation is stated in the shared check's
38
42
  * header.
39
43
  */
40
- import { checkEgress, egressPolicyForPosture, nodeLookup, blockedReason as sharedBlockedReason, } from "@stigmer/outbound/egress";
44
+ import { checkEgress, egressPolicyForPosture, nodeLookup, refusalWithholdsResolution, blockedReason as sharedBlockedReason, } from "@stigmer/outbound/egress";
41
45
  /** Thrown for every guard rejection; message is safe to surface to the model. */
42
46
  export class UrlGuardError extends Error {
43
47
  constructor(message) {
@@ -75,6 +79,9 @@ export async function validateFetchUrl(rawUrl, posture) {
75
79
  if (check.ok)
76
80
  return check.url;
77
81
  const refusal = check.refusal;
82
+ if (refusalWithholdsResolution(refusal) && (refusal.kind === "unresolvable" || refusal.kind === "blocked")) {
83
+ throw new UrlGuardError(`Refusing to fetch ${refusal.hostname}: it does not resolve to a public address.`);
84
+ }
78
85
  switch (refusal.kind) {
79
86
  case "invalid-url":
80
87
  throw new UrlGuardError(`Invalid URL: ${refusal.url}`);
@@ -1 +1 @@
1
- {"version":3,"file":"url-guard.js","sourceRoot":"","sources":["../../src/tools/url-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EACL,WAAW,EACX,sBAAsB,EACtB,UAAU,EACV,aAAa,IAAI,mBAAmB,GAErC,MAAM,0BAA0B,CAAC;AAIlC,iFAAiF;AACjF,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAuB,EACvB,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,QAAQ,GAAG,GAAG,CAAC,+BAA+B,CAAC;IACrD,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC1C,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAED,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;AAE5B;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,OAAqB;IAErB,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACrF,IAAI,KAAK,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC;IAE/B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,aAAa;YAChB,MAAM,IAAI,aAAa,CAAC,gBAAgB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACzD,KAAK,oBAAoB;YACvB,MAAM,IAAI,aAAa,CACrB,2BAA2B,OAAO,CAAC,MAAM,sCAAsC,CAChF,CAAC;QACJ,KAAK,cAAc;YACjB,MAAM,IAAI,aAAa,CAAC,+BAA+B,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC7E,KAAK,SAAS;YACZ,MAAM,IAAI,aAAa,CACrB,qBAAqB,OAAO,CAAC,QAAQ,oBAAoB,OAAO,CAAC,OAAO,OAAO,OAAO,CAAC,MAAM,gDAAgD,CAC9I,CAAC;QACJ,KAAK,oBAAoB;YACvB,kEAAkE;YAClE,qEAAqE;YACrE,MAAM,IAAI,aAAa,CAAC,gCAAgC,OAAO,CAAC,IAAI,aAAa,CAAC,CAAC;QACrF,KAAK,oBAAoB;YACvB,6DAA6D;YAC7D,MAAM,IAAI,aAAa,CAAC,8BAA8B,OAAO,CAAC,QAAQ,SAAS,CAAC,CAAC;QACnF,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,UAAU,GAAU,OAAO,CAAC;YAClC,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,OAAqB;IAClE,OAAO,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"url-guard.js","sourceRoot":"","sources":["../../src/tools/url-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,OAAO,EACL,WAAW,EACX,sBAAsB,EACtB,UAAU,EACV,0BAA0B,EAC1B,aAAa,IAAI,mBAAmB,GAErC,MAAM,0BAA0B,CAAC;AAIlC,iFAAiF;AACjF,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAuB,EACvB,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,QAAQ,GAAG,GAAG,CAAC,+BAA+B,CAAC;IACrD,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC1C,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAED,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;AAE5B;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,OAAqB;IAErB,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACrF,IAAI,KAAK,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC;IAE/B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,IAAI,0BAA0B,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,cAAc,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC;QAC3G,MAAM,IAAI,aAAa,CAAC,qBAAqB,OAAO,CAAC,QAAQ,4CAA4C,CAAC,CAAC;IAC7G,CAAC;IACD,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,aAAa;YAChB,MAAM,IAAI,aAAa,CAAC,gBAAgB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACzD,KAAK,oBAAoB;YACvB,MAAM,IAAI,aAAa,CACrB,2BAA2B,OAAO,CAAC,MAAM,sCAAsC,CAChF,CAAC;QACJ,KAAK,cAAc;YACjB,MAAM,IAAI,aAAa,CAAC,+BAA+B,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC7E,KAAK,SAAS;YACZ,MAAM,IAAI,aAAa,CACrB,qBAAqB,OAAO,CAAC,QAAQ,oBAAoB,OAAO,CAAC,OAAO,OAAO,OAAO,CAAC,MAAM,gDAAgD,CAC9I,CAAC;QACJ,KAAK,oBAAoB;YACvB,kEAAkE;YAClE,qEAAqE;YACrE,MAAM,IAAI,aAAa,CAAC,gCAAgC,OAAO,CAAC,IAAI,aAAa,CAAC,CAAC;QACrF,KAAK,oBAAoB;YACvB,6DAA6D;YAC7D,MAAM,IAAI,aAAa,CAAC,8BAA8B,OAAO,CAAC,QAAQ,SAAS,CAAC,CAAC;QACnF,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,UAAU,GAAU,OAAO,CAAC;YAClC,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,OAAqB;IAClE,OAAO,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC"}
package/dist/worker.d.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  * - This TypeScript worker handles both workflow and activity tasks
12
12
  * - Activities are dispatched by name within the same queue
13
13
  */
14
- import { Worker } from "@temporalio/worker";
14
+ import { NativeConnection, Worker } from "@temporalio/worker";
15
15
  import type { PayloadCodec } from "@temporalio/common";
16
16
  import type { Config } from "./config.js";
17
17
  export interface WorkerActivities {
@@ -23,4 +23,13 @@ export interface StartWorkerOptions {
23
23
  /** Ordered codec chain from createPayloadCodecs (order is load-bearing). */
24
24
  payloadCodecs?: PayloadCodec[];
25
25
  }
26
- export declare function startWorker(opts: StartWorkerOptions): Promise<Worker>;
26
+ /**
27
+ * The worker and the connection it polls on. The caller owns both: it runs
28
+ * and shuts down the worker, then closes the connection once `run()` has
29
+ * resolved (the SDK refuses to close a connection a worker still holds).
30
+ */
31
+ export interface StartedWorker {
32
+ readonly worker: Worker;
33
+ readonly connection: NativeConnection;
34
+ }
35
+ export declare function startWorker(opts: StartWorkerOptions): Promise<StartedWorker>;
package/dist/worker.js CHANGED
@@ -71,6 +71,6 @@ export async function startWorker(opts) {
71
71
  ...(workflowInterceptorModules.length > 0 ? { workflowModules: workflowInterceptorModules } : {}),
72
72
  },
73
73
  });
74
- return worker;
74
+ return { worker, connection };
75
75
  }
76
76
  //# sourceMappingURL=worker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
@@ -32,8 +32,24 @@
32
32
  * activation and attached to the approval_requested event — inline when
33
33
  * small, as an artifact reference when at/above the promotion threshold —
34
34
  * so the approval record captures exactly what the reviewer saw.
35
+ *
36
+ * Timeout policy lives here, whole. `ctx.awaitHumanInput()` only reports
37
+ * that the timer won; this module decides what that means. approve, deny and
38
+ * escalate resolve the gate to a declared outcome. fail logs an
39
+ * approval_resolved with `auto_resolved` set and no outcome, then fails the
40
+ * task with the error it has always raised, so every approval_requested in
41
+ * the event log is closed by an approval_resolved (stigmer/stigmer#1442).
42
+ * That emit is a new workflow command on an existing path, so it runs behind
43
+ * {@link HUMAN_INPUT_FAIL_TIMEOUT_RESOLVED_PATCH}: a history recorded before
44
+ * it replays the old order (no emit, then the throw).
35
45
  */
36
46
  import type { HumanInputTaskDef, WorkflowState, TaskExecutionContext } from "../types.js";
47
+ /**
48
+ * Temporal patch id for logging approval_resolved before a fail-policy
49
+ * timeout fails the task. Wire bytes: a rename makes every history that
50
+ * carries the marker replay down the old path.
51
+ */
52
+ export declare const HUMAN_INPUT_FAIL_TIMEOUT_RESOLVED_PATCH = "human-input-fail-timeout-resolved";
37
53
  /**
38
54
  * Executes a human_input task. Called from `runSingleTask` in do-executor
39
55
  * when the task kind is "human_input".