lark-remote 0.1.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 (201) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/LICENSE +21 -0
  3. package/README.en.md +162 -0
  4. package/README.md +161 -0
  5. package/dist/binder.d.ts +57 -0
  6. package/dist/binder.js +105 -0
  7. package/dist/bridge/index.d.ts +338 -0
  8. package/dist/bridge/index.js +1281 -0
  9. package/dist/bridge/queue-manager.d.ts +277 -0
  10. package/dist/bridge/queue-manager.js +729 -0
  11. package/dist/card/bash-card-session.d.ts +78 -0
  12. package/dist/card/bash-card-session.js +174 -0
  13. package/dist/card/bash-renderer.d.ts +24 -0
  14. package/dist/card/bash-renderer.js +187 -0
  15. package/dist/card/card-budget.d.ts +31 -0
  16. package/dist/card/card-budget.js +280 -0
  17. package/dist/card/card-session.d.ts +83 -0
  18. package/dist/card/card-session.js +185 -0
  19. package/dist/card/card-shared.d.ts +28 -0
  20. package/dist/card/card-shared.js +99 -0
  21. package/dist/card/collapsible.d.ts +26 -0
  22. package/dist/card/collapsible.js +87 -0
  23. package/dist/card/run-card-session.d.ts +78 -0
  24. package/dist/card/run-card-session.js +165 -0
  25. package/dist/card/run-renderer.d.ts +66 -0
  26. package/dist/card/run-renderer.js +841 -0
  27. package/dist/card/run-state.d.ts +103 -0
  28. package/dist/card/run-state.js +313 -0
  29. package/dist/card/text-truncate.d.ts +56 -0
  30. package/dist/card/text-truncate.js +184 -0
  31. package/dist/card/time.d.ts +1 -0
  32. package/dist/card/time.js +14 -0
  33. package/dist/card/tool-render.d.ts +25 -0
  34. package/dist/card/tool-render.js +176 -0
  35. package/dist/cli.d.ts +28 -0
  36. package/dist/cli.js +89 -0
  37. package/dist/common/guards.d.ts +37 -0
  38. package/dist/common/guards.js +65 -0
  39. package/dist/config/codex-config.d.ts +113 -0
  40. package/dist/config/codex-config.js +428 -0
  41. package/dist/config/dir.d.ts +17 -0
  42. package/dist/config/dir.js +81 -0
  43. package/dist/config/index.d.ts +219 -0
  44. package/dist/config/index.js +388 -0
  45. package/dist/config/kimi-config.d.ts +33 -0
  46. package/dist/config/kimi-config.js +111 -0
  47. package/dist/config/opencode-config.d.ts +20 -0
  48. package/dist/config/opencode-config.js +124 -0
  49. package/dist/config/pi-config.d.ts +49 -0
  50. package/dist/config/pi-config.js +151 -0
  51. package/dist/config/wizard.d.ts +12 -0
  52. package/dist/config/wizard.js +84 -0
  53. package/dist/connector/file-limits.d.ts +7 -0
  54. package/dist/connector/file-limits.js +8 -0
  55. package/dist/connector/index.d.ts +86 -0
  56. package/dist/connector/index.js +340 -0
  57. package/dist/error-classification.d.ts +15 -0
  58. package/dist/error-classification.js +24 -0
  59. package/dist/index.d.ts +1 -0
  60. package/dist/index.js +580 -0
  61. package/dist/instance-lock.d.ts +30 -0
  62. package/dist/instance-lock.js +184 -0
  63. package/dist/logger/index.d.ts +57 -0
  64. package/dist/logger/index.js +178 -0
  65. package/dist/order/index.d.ts +27 -0
  66. package/dist/order/index.js +90 -0
  67. package/dist/persistence/atomic-write.d.ts +10 -0
  68. package/dist/persistence/atomic-write.js +65 -0
  69. package/dist/persistence/load-json-file.d.ts +9 -0
  70. package/dist/persistence/load-json-file.js +23 -0
  71. package/dist/restart.d.ts +24 -0
  72. package/dist/restart.js +73 -0
  73. package/dist/router/card-helpers.d.ts +28 -0
  74. package/dist/router/card-helpers.js +65 -0
  75. package/dist/router/config/claude.d.ts +14 -0
  76. package/dist/router/config/claude.js +72 -0
  77. package/dist/router/config/codex.d.ts +22 -0
  78. package/dist/router/config/codex.js +100 -0
  79. package/dist/router/config/common/render.d.ts +16 -0
  80. package/dist/router/config/common/render.js +158 -0
  81. package/dist/router/config/index.d.ts +18 -0
  82. package/dist/router/config/index.js +38 -0
  83. package/dist/router/config/kimi.d.ts +21 -0
  84. package/dist/router/config/kimi.js +63 -0
  85. package/dist/router/config/opencode.d.ts +12 -0
  86. package/dist/router/config/opencode.js +44 -0
  87. package/dist/router/config/pi.d.ts +12 -0
  88. package/dist/router/config/pi.js +50 -0
  89. package/dist/router/config/types.d.ts +43 -0
  90. package/dist/router/config/types.js +8 -0
  91. package/dist/router/index.d.ts +318 -0
  92. package/dist/router/index.js +2715 -0
  93. package/dist/router/order-exec-dispatch.d.ts +30 -0
  94. package/dist/router/order-exec-dispatch.js +48 -0
  95. package/dist/router/utils.d.ts +44 -0
  96. package/dist/router/utils.js +116 -0
  97. package/dist/runner/bash/index.d.ts +4 -0
  98. package/dist/runner/bash/index.js +5 -0
  99. package/dist/runner/bash/runner.d.ts +55 -0
  100. package/dist/runner/bash/runner.js +213 -0
  101. package/dist/runner/claude/index.d.ts +4 -0
  102. package/dist/runner/claude/index.js +5 -0
  103. package/dist/runner/claude/runner.d.ts +29 -0
  104. package/dist/runner/claude/runner.js +83 -0
  105. package/dist/runner/codex/argv.d.ts +33 -0
  106. package/dist/runner/codex/argv.js +40 -0
  107. package/dist/runner/codex/index.d.ts +1 -0
  108. package/dist/runner/codex/index.js +2 -0
  109. package/dist/runner/codex/jsonl.d.ts +37 -0
  110. package/dist/runner/codex/jsonl.js +221 -0
  111. package/dist/runner/codex/runner.d.ts +65 -0
  112. package/dist/runner/codex/runner.js +124 -0
  113. package/dist/runner/common/exec-translator.d.ts +73 -0
  114. package/dist/runner/common/exec-translator.js +105 -0
  115. package/dist/runner/common/jsonl-stream.d.ts +39 -0
  116. package/dist/runner/common/jsonl-stream.js +203 -0
  117. package/dist/runner/common/process-stopper.d.ts +28 -0
  118. package/dist/runner/common/process-stopper.js +79 -0
  119. package/dist/runner/common/runner-utils.d.ts +21 -0
  120. package/dist/runner/common/runner-utils.js +65 -0
  121. package/dist/runner/common/spawn-heartbeat.d.ts +33 -0
  122. package/dist/runner/common/spawn-heartbeat.js +51 -0
  123. package/dist/runner/common/spawning-runner.d.ts +321 -0
  124. package/dist/runner/common/spawning-runner.js +634 -0
  125. package/dist/runner/common/usage.d.ts +31 -0
  126. package/dist/runner/common/usage.js +29 -0
  127. package/dist/runner/index.d.ts +19 -0
  128. package/dist/runner/index.js +24 -0
  129. package/dist/runner/kimi/index.d.ts +1 -0
  130. package/dist/runner/kimi/index.js +2 -0
  131. package/dist/runner/kimi/jsonl.d.ts +28 -0
  132. package/dist/runner/kimi/jsonl.js +143 -0
  133. package/dist/runner/kimi/runner.d.ts +50 -0
  134. package/dist/runner/kimi/runner.js +105 -0
  135. package/dist/runner/opencode/argv.d.ts +32 -0
  136. package/dist/runner/opencode/argv.js +35 -0
  137. package/dist/runner/opencode/index.d.ts +1 -0
  138. package/dist/runner/opencode/index.js +2 -0
  139. package/dist/runner/opencode/jsonl.d.ts +68 -0
  140. package/dist/runner/opencode/jsonl.js +295 -0
  141. package/dist/runner/opencode/runner.d.ts +63 -0
  142. package/dist/runner/opencode/runner.js +93 -0
  143. package/dist/runner/pi/index.d.ts +1 -0
  144. package/dist/runner/pi/index.js +2 -0
  145. package/dist/runner/pi/jsonl.d.ts +128 -0
  146. package/dist/runner/pi/jsonl.js +249 -0
  147. package/dist/runner/pi/runner.d.ts +37 -0
  148. package/dist/runner/pi/runner.js +76 -0
  149. package/dist/runner/registry.d.ts +54 -0
  150. package/dist/runner/registry.js +75 -0
  151. package/dist/runner/resolve-agent-choices.d.ts +7 -0
  152. package/dist/runner/resolve-agent-choices.js +76 -0
  153. package/dist/runner/sync-agent-choices.d.ts +6 -0
  154. package/dist/runner/sync-agent-choices.js +73 -0
  155. package/dist/runner/types.d.ts +250 -0
  156. package/dist/runner/types.js +8 -0
  157. package/dist/session/claude/index.d.ts +1 -0
  158. package/dist/session/claude/index.js +2 -0
  159. package/dist/session/claude/session-reader.d.ts +34 -0
  160. package/dist/session/claude/session-reader.js +46 -0
  161. package/dist/session/claude/sessions.d.ts +53 -0
  162. package/dist/session/claude/sessions.js +528 -0
  163. package/dist/session/codex/index.d.ts +1 -0
  164. package/dist/session/codex/index.js +2 -0
  165. package/dist/session/codex/rollout-reader.d.ts +88 -0
  166. package/dist/session/codex/rollout-reader.js +473 -0
  167. package/dist/session/codex/sessions.d.ts +21 -0
  168. package/dist/session/codex/sessions.js +40 -0
  169. package/dist/session/common/catch-up.d.ts +12 -0
  170. package/dist/session/common/catch-up.js +31 -0
  171. package/dist/session/common/constants.d.ts +11 -0
  172. package/dist/session/common/constants.js +12 -0
  173. package/dist/session/common/content-blocks.d.ts +37 -0
  174. package/dist/session/common/content-blocks.js +68 -0
  175. package/dist/session/common/jsonl.d.ts +77 -0
  176. package/dist/session/common/jsonl.js +351 -0
  177. package/dist/session/common/usage-accumulator.d.ts +58 -0
  178. package/dist/session/common/usage-accumulator.js +72 -0
  179. package/dist/session/index.d.ts +7 -0
  180. package/dist/session/index.js +11 -0
  181. package/dist/session/kimi/index.d.ts +1 -0
  182. package/dist/session/kimi/index.js +2 -0
  183. package/dist/session/kimi/sessions.d.ts +81 -0
  184. package/dist/session/kimi/sessions.js +527 -0
  185. package/dist/session/opencode/index.d.ts +1 -0
  186. package/dist/session/opencode/index.js +2 -0
  187. package/dist/session/opencode/sessions.d.ts +81 -0
  188. package/dist/session/opencode/sessions.js +388 -0
  189. package/dist/session/pi/index.d.ts +1 -0
  190. package/dist/session/pi/index.js +2 -0
  191. package/dist/session/pi/sessions.d.ts +27 -0
  192. package/dist/session/pi/sessions.js +399 -0
  193. package/dist/session/registry.d.ts +12 -0
  194. package/dist/session/registry.js +20 -0
  195. package/dist/session/session-store.d.ts +86 -0
  196. package/dist/session/session-store.js +450 -0
  197. package/dist/startup-contact.d.ts +18 -0
  198. package/dist/startup-contact.js +51 -0
  199. package/dist/workspace/index.d.ts +19 -0
  200. package/dist/workspace/index.js +53 -0
  201. package/package.json +93 -0
@@ -0,0 +1,277 @@
1
+ import type { AgentKind } from '../runner/types.js';
2
+ /**
3
+ * 入队时刻快照:当前 defaultAgent + 该 agent 的 sessionId(无 session 则 undefined)。
4
+ * 唯一捕获点:排队消息在 T0 把 agent+session 钉进 AgentBinding,随任务闭包带到 T1
5
+ * 执行时刻,避免 /new、/config 在排队期间改写 live 状态导致语义漂移(方案 D4)。
6
+ */
7
+ export interface AgentBinding {
8
+ agent: AgentKind;
9
+ sessionId?: string;
10
+ }
11
+ /** A queued task with its metadata for queue display cards. */
12
+ export interface QueuedTask {
13
+ userId: string;
14
+ chatId: string;
15
+ /**
16
+ * Queue dedup/identity key. For hand-typed messages this is the Feishu
17
+ * message id; for card-action dispatches (e.g. `order.exec`, where one card
18
+ * is clickable N times) this is a project-minted internal key (NOT a valid
19
+ * Feishu message id). It is used for task lookup, cancellation, and queue
20
+ * card button callbacks — never as a Feishu reply target.
21
+ */
22
+ messageId: string;
23
+ /**
24
+ * The Feishu message id the queue status card should reply to, when it
25
+ * differs from `messageId` (i.e. `messageId` is an internal key). Falls back
26
+ * to `messageId` for hand-typed messages, where the two coincide.
27
+ */
28
+ feishuReplyTo?: string;
29
+ workspace: string;
30
+ timestamp: number;
31
+ messagePreview: string;
32
+ /**
33
+ * Edited message content. Set by `updateQueuedTaskMessage` when the user
34
+ * edits a queued message. The original closure captured at enqueue time
35
+ * is immutable, so `handleQueueImmediate` reads this field to register a
36
+ * one-shot replacement closure with the edited content (see router
37
+ * `handleQueueImmediate`).
38
+ */
39
+ editedMessage?: string;
40
+ /** 入队时刻捕获的 agent+session 绑定(方案 D4),随任务闭包带到执行时刻。 */
41
+ binding?: AgentBinding;
42
+ }
43
+ /** Options for enqueue operation */
44
+ export interface EnqueueOptions {
45
+ taskMeta?: {
46
+ userId: string;
47
+ chatId: string;
48
+ messageId: string;
49
+ messagePreview: string;
50
+ /**
51
+ * Feishu message id the queue status card should reply to, when the queue
52
+ * dedup key (`messageId`) is NOT a valid Feishu id (e.g. an order.exec
53
+ * internal key). Omitted for hand-typed messages, where `messageId` is the
54
+ * real Feishu id and doubles as the reply target.
55
+ */
56
+ feishuReplyTo?: string;
57
+ /** 入队时刻捕获的 agent+session 绑定(方案 D4)。 */
58
+ binding?: AgentBinding;
59
+ };
60
+ }
61
+ /** Queue info for a workspace */
62
+ interface QueueInfo {
63
+ position: number;
64
+ tasksAhead: number;
65
+ isRunning: boolean;
66
+ }
67
+ /**
68
+ * QueueManager handles the per-workspace serial processing queue.
69
+ * Manages task queuing, cancellation, and queue status card rendering.
70
+ */
71
+ export declare class QueueManager {
72
+ /** Per-workspace (cwd) serial queues. Key = cwd, value = tail of promise chain. */
73
+ private queues;
74
+ /** Per-workspace queued tasks for queue display cards. Key = cwd, value = task list. */
75
+ private queuedTasks;
76
+ /**
77
+ * P3-5: per-workspace `messageId → QueuedTask` index mirroring `queuedTasks`.
78
+ * O(1) lookup for the task-start removal path (replacing the old double
79
+ * `find`+`findIndex` O(N) scan) and for `getQueuedTask`/`removeFromQueue`/
80
+ * `updateQueuedTaskMessage`. The ordered array remains the source of truth
81
+ * (position display depends on order); the index must be kept in sync on
82
+ * every mutation (push / splice / shift) via the `indexAdd`/`indexRemove`
83
+ * helpers. Same messageId is never enqueued twice in one workspace
84
+ * (Feishu dedup + internal-key dedup), so no overwrite concern.
85
+ */
86
+ private taskIndex;
87
+ /**
88
+ * Map from user messageId to the queue card's Feishu send promise. Storing
89
+ * the promise (not the resolved id) closes the race where the card send is
90
+ * still in flight when the task begins: the begin path awaits the stored
91
+ * promise, so a late-arriving card id still gets reconciled to the
92
+ * executing/cancelled state. The promise never rejects (send failures
93
+ * resolve undefined), so awaiting it is always safe.
94
+ */
95
+ private queueCardMessages;
96
+ /** Track number of executing tasks per workspace (for queue card display). */
97
+ private pendingOrExecutingCount;
98
+ /**
99
+ * Monotonic counter minting a unique slot id per enqueued task. A slot
100
+ * identifies one task's execution period for the interrupt bookkeeping in
101
+ * `executingSlot`/`interruptedSlots` — replacing the unowned skip-credit
102
+ * counter, which any settle could consume and which therefore leaked a
103
+ * re-armed count after repeated resets (see A4 anchor).
104
+ */
105
+ private slotCounter;
106
+ /**
107
+ * Per-workspace slot id of the task currently executing. Set in the begin
108
+ * path right before the task runs; deleted when that task's settle fires.
109
+ * `resetExecutingCount` reads it to bind the interrupt credit to exactly
110
+ * the interrupted task's slot.
111
+ */
112
+ private executingSlot;
113
+ /**
114
+ * Per-workspace set of slot ids whose task was interrupted by
115
+ * `resetExecutingCount`. When such a slot settles, its decrement is skipped
116
+ * (the reset already zeroed the count). A slot is granted at most once —
117
+ * repeated resets of the same executing task do not mint extra credits —
118
+ * which prevents a normal task's settle from consuming a credit instead of
119
+ * decrementing, leaking the re-armed count to 1.
120
+ */
121
+ private interruptedSlots;
122
+ /** Per-workspace messageId → replacement closure, set by queue.edit + immediate. */
123
+ private taskReplacements;
124
+ /**
125
+ * MessageIds of tasks that have actually begun executing (cancellation check
126
+ * passed, task removed from the queue). Entries are sticky: they remain
127
+ * after the task settles (A21). `handleQueueImmediate` step 6 uses this to
128
+ * distinguish "target was cancelled (never began)" from "target began while
129
+ * the interrupt was in flight" so the final feedback can report the true
130
+ * state instead of telling a running task's user that nothing was
131
+ * scheduled. A task that began and then settled quickly must still report
132
+ * "已开始执行", which requires the marker to survive settle. Message ids are
133
+ * globally unique and never reused, so a sticky marker cannot misclassify a
134
+ * later task; the set is bounded-pruned on insert to prevent unbounded
135
+ * growth. Removed/cancelled tasks never enter the set (cancellation happens
136
+ * before begin); `removeFromQueue` therefore needs no cleanup here.
137
+ */
138
+ private beganMessageIds;
139
+ /** Callback to check if workspace has an active run */
140
+ private isWorkspaceRunning;
141
+ /** Callback to send card updates */
142
+ private sendCard;
143
+ /** Callback to update existing card */
144
+ private updateCard;
145
+ constructor(isWorkspaceRunning: (workspace: string) => boolean, sendCard: (chatId: string, card: object, opts?: {
146
+ replyTo?: string;
147
+ }) => Promise<string>, updateCard: (messageId: string, card: object) => Promise<void>);
148
+ /** P3-5: register a queued task in the per-workspace `messageId → task` index. */
149
+ private indexAdd;
150
+ /** P3-5: drop a task from the per-workspace index by messageId. */
151
+ private indexRemove;
152
+ /** P3-5: O(1) lookup of a queued task by messageId via the index. */
153
+ private indexGet;
154
+ /**
155
+ * Enqueue a task into the workspace-level serial queue.
156
+ * Each workspace has its own serial queue for parallel execution across workspaces.
157
+ */
158
+ enqueue(workspace: string, task: () => Promise<void>, opts?: EnqueueOptions): void;
159
+ /**
160
+ * Execute a task immediately without going through the queue.
161
+ * Used for / commands that should respond immediately.
162
+ */
163
+ enqueueImmediate(workspace: string, task: () => Promise<void>): void;
164
+ /**
165
+ * One-shot: replace the execution closure of an existing queued task in
166
+ * place, preserving its queue position (tasks queued behind it still run
167
+ * after it). Consumed when the task's slot begins; removed if cancelled.
168
+ */
169
+ setTaskReplacement(workspace: string, messageId: string, task: () => Promise<void>): void;
170
+ /** Send a queue status card showing current queue position and actions. */
171
+ private sendQueueStatusCard;
172
+ /** Get queue info for a workspace. */
173
+ getQueueInfo(workspace: string): QueueInfo;
174
+ /** Build queue status card elements. */
175
+ private buildQueueStatusCardElements;
176
+ /**
177
+ * Build the 撤销/立即执行 action button pair for a queue card.
178
+ *
179
+ * Both buttons route to `queue.cancel` / `queue.immediate` callbacks with
180
+ * the same workspace/messageId; only the `disabled` flag varies by card
181
+ * state — pending cards enable both, executing/cancelled cards disable
182
+ * both. Centralizing the pair here eliminates the 3-way duplication
183
+ * between `buildQueueStatusCardElements`, `updateQueueCardToExecuting`,
184
+ * and `updateQueueCardToCancelled` (Clean Code P2-1).
185
+ */
186
+ private buildQueueActionButtons;
187
+ /**
188
+ * Update queue card to "started executing" status when task begins.
189
+ *
190
+ * `started` tells the method whether the caller has already confirmed the
191
+ * task really began (begin path: cancellation check passed and the task has
192
+ * been removed from the queue). When `started` is false (queue.immediate
193
+ * mark path), a membership guard re-checks the task right before the card
194
+ * update: if the task was removed/cancelled while the send was in flight,
195
+ * the card must keep its "❌ 已撤销" state instead of being flipped back to
196
+ * executing. The mapping is deleted in finally in both cases.
197
+ */
198
+ updateQueueCardToExecuting(workspace: string, messageId: string, messagePreview: string, started?: boolean): Promise<void>;
199
+ /** Remove a task from the queue by messageId. Returns true if found and removed. */
200
+ removeFromQueue(workspace: string, messageId: string): boolean;
201
+ /** Update queue card to "cancelled" status when user clicks 撤销. */
202
+ updateQueueCardToCancelled(workspace: string, messageId: string): Promise<void>;
203
+ /** Get task metadata from queue. */
204
+ getQueuedTask(workspace: string, messageId: string): QueuedTask | undefined;
205
+ /**
206
+ * Whether a task with the given messageId has begun executing (cancellation
207
+ * check passed, task removed from the queue). Sticky: true even after the
208
+ * task settles, so queue.immediate can distinguish "began (possibly already
209
+ * completed)" from "never began / cancelled".
210
+ */
211
+ hasBegan(messageId: string): boolean;
212
+ /** Get all queued tasks for a workspace. Returns a copy to prevent aliasing bugs. */
213
+ getQueuedTasks(workspace: string): QueuedTask[];
214
+ /** Update the messagePreview for a queued task. Returns true if found and updated. */
215
+ updateQueuedTaskMessage(workspace: string, messageId: string, newMessage: string): boolean;
216
+ /**
217
+ * Build the orange queue card reflecting the edited message content. Returns
218
+ * the card object (sent as the cardAction callback response `card.data`,
219
+ * which Feishu renders in place) or null if the task is no longer queued.
220
+ *
221
+ * Why a callback-response card instead of a PATCH updateCard API call:
222
+ * when handleQueueInput returns a { toast } callback response, Feishu uses
223
+ * that response to render the clicked card; a response without a `card`
224
+ * field leaves the card in its pre-click (edit) state, overriding the
225
+ * concurrent PATCH updateCard result. Returning { card } in the callback
226
+ * response updates the card synchronously with no API race.
227
+ */
228
+ buildQueueCardForEdit(workspace: string, messageId: string, newMessagePreview: string): object | null;
229
+ /**
230
+ * Decrement `pendingOrExecutingCount` for a workspace, honoring per-slot
231
+ * interrupt bookkeeping.
232
+ *
233
+ * Called from the queue chain's `.then()`/`.catch()` settle with the slot
234
+ * id minted at enqueue time. Three cases:
235
+ *
236
+ * 1. The slot is the workspace's current executing slot → its execution
237
+ * period ends (`executingSlot` marker removed).
238
+ * 2. The slot is in `interruptedSlots` (its task was interrupted by
239
+ * `resetExecutingCount`) → skip the decrement: the reset already zeroed
240
+ * the count, so a stale decrement could wrongly zero it again while a
241
+ * newer task (enqueued after the reset) is still running.
242
+ * 3. Otherwise → normal decrement.
243
+ */
244
+ private decrementExecutingCount;
245
+ /**
246
+ * Reset the executing task count for a workspace.
247
+ *
248
+ * This should be called when a running task is interrupted externally
249
+ * (e.g., via /stop command or "立即执行" button) so that the queue
250
+ * correctly reflects that no tasks are currently executing.
251
+ *
252
+ * Without this reset, the pendingOrExecutingCount would remain > 0 even after
253
+ * the task process is killed, causing subsequent messages to incorrectly
254
+ * show as "排队中" because the queue thinks a task is still running.
255
+ *
256
+ * Also marks the currently executing task's slot as interrupted, so its
257
+ * eventual `.then()`/`.catch()` settle skips the decrement (which could
258
+ * otherwise zero the count while a newer task is still running). The mark
259
+ * is granted at most once per slot: repeated resets of the same executing
260
+ * task do not accumulate credits.
261
+ *
262
+ * `expectedSlot` binds the reset to the task that was actually interrupted:
263
+ * the caller captures the executing slot BEFORE stopping the runner, and
264
+ * the stop window may outlive the interrupted task's settle (the chain can
265
+ * advance to a NEW task, which then owns `executingSlot`). When the current
266
+ * slot no longer matches the interrupted task's slot, the interrupted task
267
+ * already decremented normally — resetting now would zero the count of the
268
+ * running successor and mark ITS slot interrupted, hiding it from the
269
+ * queue card (A22).
270
+ */
271
+ resetExecutingCount(workspace: string, expectedSlot: number): void;
272
+ /**
273
+ * The slot id of the task currently executing in this workspace (if any).
274
+ */
275
+ getExecutingSlot(workspace: string): number | undefined;
276
+ }
277
+ export {};