botmux 3.9.1 → 3.9.2
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/dist/.runtime-build-id +1 -1
- package/dist/adapters/cli/traex.d.ts.map +1 -1
- package/dist/adapters/cli/traex.js +87 -87
- package/dist/adapters/cli/traex.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +94 -16
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +40 -1
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/passthrough-commands.d.ts.map +1 -1
- package/dist/core/passthrough-commands.js +1 -1
- package/dist/core/passthrough-commands.js.map +1 -1
- package/dist/daemon.d.ts +11 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +32 -3
- package/dist/daemon.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +1 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +1 -0
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +9 -0
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/issue-card.d.ts +223 -0
- package/dist/im/lark/issue-card.d.ts.map +1 -0
- package/dist/im/lark/issue-card.js +542 -0
- package/dist/im/lark/issue-card.js.map +1 -0
- package/dist/im/lark/issue-command-deps.d.ts +41 -0
- package/dist/im/lark/issue-command-deps.d.ts.map +1 -0
- package/dist/im/lark/issue-command-deps.js +195 -0
- package/dist/im/lark/issue-command-deps.js.map +1 -0
- package/dist/im/lark/issue-command.d.ts +137 -0
- package/dist/im/lark/issue-command.d.ts.map +1 -0
- package/dist/im/lark/issue-command.js +335 -0
- package/dist/im/lark/issue-command.js.map +1 -0
- package/dist/platform/issue-client.d.ts +201 -0
- package/dist/platform/issue-client.d.ts.map +1 -0
- package/dist/platform/issue-client.js +142 -0
- package/dist/platform/issue-client.js.map +1 -0
- package/dist/platform/platform-http.d.ts +4 -0
- package/dist/platform/platform-http.d.ts.map +1 -1
- package/dist/platform/platform-http.js +38 -2
- package/dist/platform/platform-http.js.map +1 -1
- package/dist/services/issue-board-store.d.ts +214 -0
- package/dist/services/issue-board-store.d.ts.map +1 -0
- package/dist/services/issue-board-store.js +472 -0
- package/dist/services/issue-board-store.js.map +1 -0
- package/dist/services/issue-claim-flow.d.ts +160 -0
- package/dist/services/issue-claim-flow.d.ts.map +1 -0
- package/dist/services/issue-claim-flow.js +222 -0
- package/dist/services/issue-claim-flow.js.map +1 -0
- package/dist/services/issue-outbox-pump.d.ts +25 -0
- package/dist/services/issue-outbox-pump.d.ts.map +1 -0
- package/dist/services/issue-outbox-pump.js +102 -0
- package/dist/services/issue-outbox-pump.js.map +1 -0
- package/dist/services/issue-release.d.ts +78 -0
- package/dist/services/issue-release.d.ts.map +1 -0
- package/dist/services/issue-release.js +89 -0
- package/dist/services/issue-release.js.map +1 -0
- package/dist/services/issue-report.d.ts +72 -0
- package/dist/services/issue-report.d.ts.map +1 -0
- package/dist/services/issue-report.js +84 -0
- package/dist/services/issue-report.js.map +1 -0
- package/dist/services/issue-status-view.d.ts +52 -0
- package/dist/services/issue-status-view.d.ts.map +1 -0
- package/dist/services/issue-status-view.js +42 -0
- package/dist/services/issue-status-view.js.map +1 -0
- package/dist/services/issue-status-writer.d.ts +98 -0
- package/dist/services/issue-status-writer.d.ts.map +1 -0
- package/dist/services/issue-status-writer.js +123 -0
- package/dist/services/issue-status-writer.js.map +1 -0
- package/dist/services/traex-paths.d.ts +14 -2
- package/dist/services/traex-paths.d.ts.map +1 -1
- package/dist/services/traex-paths.js +16 -2
- package/dist/services/traex-paths.js.map +1 -1
- package/dist/services/traex-transcript.d.ts +33 -0
- package/dist/services/traex-transcript.d.ts.map +1 -1
- package/dist/services/traex-transcript.js +135 -28
- package/dist/services/traex-transcript.js.map +1 -1
- package/dist/setup/lark-scopes.json +0 -2
- package/dist/worker.js +143 -17
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
package/dist/.runtime-build-id
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
b41572b678541078ba1a6e5360583a320c50a5af4cc0b41ee11977625bf2800d
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traex.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/traex.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"traex.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/traex.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AA6HxD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,2BAA2B,wEAG9B,CAAC;AAEX,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAoNpE;AAED,eAAO,MAAM,MAAM,2BAAqB,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { existsSync
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { resolveCommand } from './registry.js';
|
|
4
4
|
import { BOTMUX_SHELL_HINTS } from './shared-hints.js';
|
|
5
|
-
import { traeStateDbPath, traeSessionsRoot } from '../../services/traex-paths.js';
|
|
6
|
-
import {
|
|
5
|
+
import { traeStateDbPath, traeSessionsRoot, traeHistoryPath } from '../../services/traex-paths.js';
|
|
6
|
+
import { traexHistoryMatchDelta, traexHistorySize, findTraexRolloutSetByPid, traexHistorySidIsOwned, } from '../../services/traex-transcript.js';
|
|
7
7
|
import { discoverRolloutSessions } from '../../services/resumable-session-discovery.js';
|
|
8
8
|
import { delay } from '../../utils/timing.js';
|
|
9
9
|
let sqliteModule = null;
|
|
@@ -49,60 +49,12 @@ function withDb(fn) {
|
|
|
49
49
|
catch { /* ignore */ }
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
catch {
|
|
59
|
-
return 0;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
/** Snapshot recent SQLite thread rows and each rollout's complete byte size
|
|
63
|
-
* before touching the PTY. The DB is an index; the rollout delta below is the
|
|
64
|
-
* actual submit proof. `null` means verification is unavailable and callers
|
|
65
|
-
* must fail closed before writing any bytes. */
|
|
66
|
-
function snapRecentThreads() {
|
|
67
|
-
return withDb((db) => {
|
|
68
|
-
const rows = db.prepare('SELECT id, COALESCE(updated_at_ms, 0) AS updatedAtMs, rollout_path AS rolloutPath ' +
|
|
69
|
-
'FROM threads ORDER BY updated_at_ms DESC LIMIT 64').all();
|
|
70
|
-
const byId = new Map();
|
|
71
|
-
let newestUpdatedAtMs = 0;
|
|
72
|
-
for (const row of rows) {
|
|
73
|
-
if (!row.id || !row.rolloutPath)
|
|
74
|
-
continue;
|
|
75
|
-
newestUpdatedAtMs = Math.max(newestUpdatedAtMs, Number(row.updatedAtMs) || 0);
|
|
76
|
-
byId.set(row.id, {
|
|
77
|
-
id: row.id,
|
|
78
|
-
updatedAtMs: Number(row.updatedAtMs) || 0,
|
|
79
|
-
rolloutPath: row.rolloutPath,
|
|
80
|
-
rolloutOffset: currentFileSize(row.rolloutPath),
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
return { newestUpdatedAtMs, byId };
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
/** Resolve the session whose rollout gained this exact role=user record.
|
|
87
|
-
* Works for the first prompt, later prompts in the same thread, and a freshly
|
|
88
|
-
* rotated thread. Sibling processes can update SQLite concurrently, but their
|
|
89
|
-
* rollout delta cannot match our full prompt accidentally. */
|
|
90
|
-
function detectSubmittedThread(before, expectedText) {
|
|
91
|
-
return withDb((db) => {
|
|
92
|
-
const rows = db.prepare('SELECT id, COALESCE(updated_at_ms, 0) AS updatedAtMs, rollout_path AS rolloutPath ' +
|
|
93
|
-
'FROM threads WHERE COALESCE(updated_at_ms, 0) >= ? ORDER BY updated_at_ms DESC LIMIT 64').all(before.newestUpdatedAtMs);
|
|
94
|
-
for (const r of rows) {
|
|
95
|
-
if (!r.id || !r.rolloutPath)
|
|
96
|
-
continue;
|
|
97
|
-
const prior = before.byId.get(r.id);
|
|
98
|
-
const fromOffset = prior?.rolloutPath === r.rolloutPath ? prior.rolloutOffset : 0;
|
|
99
|
-
if (traexRolloutHasUserInputSince(r.rolloutPath, fromOffset, expectedText)) {
|
|
100
|
-
return { found: true, cliSessionId: r.id };
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return { found: false };
|
|
104
|
-
}) ?? { found: false };
|
|
105
|
-
}
|
|
52
|
+
/** Adapter-side session-id ownership uses findTraexRolloutSetByPid +
|
|
53
|
+
* traexHistorySidIsOwned directly in writeInput (kept as raw three-state so the
|
|
54
|
+
* enumeration-unavailable case can fast-degrade). The authoritative persist /
|
|
55
|
+
* bridge-attach decision additionally re-checks worker-side via
|
|
56
|
+
* traexHistorySidOwnedByCurrentPid, whose pid resolution is richer than
|
|
57
|
+
* pty.cliPid (and covers the sandbox bwrap-supervisor case). */
|
|
106
58
|
/** Scan threads backwards for the most recent thread whose first_user_message
|
|
107
59
|
* references the botmux session id. Used by buildArgs(resume) and
|
|
108
60
|
* buildResumeCommand to recover a TRAE-native session UUID from a botmux
|
|
@@ -251,17 +203,44 @@ export function createTraexAdapter(pathOverride) {
|
|
|
251
203
|
return false;
|
|
252
204
|
}
|
|
253
205
|
};
|
|
254
|
-
//
|
|
255
|
-
//
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
206
|
+
// Submit confirmation polls the global submit log history.jsonl, NOT the
|
|
207
|
+
// per-session rollout. TRAE is a type-ahead CLI: a message pasted while a
|
|
208
|
+
// turn is running is PARKED in TRAE's queue and only written to the
|
|
209
|
+
// rollout when the running turn dequeues it — which can exceed the
|
|
210
|
+
// worker's confirmation deadline and fire a false "submission couldn't be
|
|
211
|
+
// confirmed" warning even though TRAE received it. history.jsonl is
|
|
212
|
+
// written at SUBMIT time (verified empirically on traecli 0.200.19: a
|
|
213
|
+
// mid-turn follow-up appears here in ~1s while the rollout lags past 20s),
|
|
214
|
+
// so it confirms parked submits immediately. This mirrors the codex
|
|
215
|
+
// adapter, which polls its identically-shaped history.jsonl for the same
|
|
216
|
+
// reason. history.jsonl is created lazily on the first submit, so an
|
|
217
|
+
// absent file just means baseByte=0 and the first appended line matches.
|
|
218
|
+
const historyPath = traeHistoryPath();
|
|
219
|
+
const baseByte = traexHistorySize(historyPath);
|
|
220
|
+
const cliPid = typeof pty.cliPid === 'number' && Number.isInteger(pty.cliPid) && pty.cliPid > 0
|
|
221
|
+
? pty.cliPid
|
|
222
|
+
: undefined;
|
|
223
|
+
// Two separable facts, matched with two different scans:
|
|
224
|
+
// - SUBMIT confirmation: any full-content match in the global submit log,
|
|
225
|
+
// ownership-INDEPENDENT (a foreign-first line or unknown pid must never
|
|
226
|
+
// suppress it, or the false "submission couldn't be confirmed" warning
|
|
227
|
+
// this fix removes would come back).
|
|
228
|
+
// - SESSION ID: history.jsonl is shared by every TRAE pane under one
|
|
229
|
+
// TRAE_HOME, so a sibling's identical text can surface a foreign id.
|
|
230
|
+
// Return the id ONLY when this pid provably owns that rollout.
|
|
231
|
+
//
|
|
232
|
+
// The three states of findTraexRolloutSetByPid are kept DISTINCT (not
|
|
233
|
+
// flattened through a boolean helper) because they drive different waits:
|
|
234
|
+
// • undefined → fd enumeration unavailable (no pid / not on Linux /
|
|
235
|
+
// proc unreadable): we can never prove ownership, so there is no point
|
|
236
|
+
// polling for an owned line — confirm the submit on any-text at once.
|
|
237
|
+
// • Set (maybe empty) → enumeration works; an owned line may simply not
|
|
238
|
+
// be on disk yet. KEEP polling for it and do NOT let a foreign-first
|
|
239
|
+
// any-text hit end the loop early (a sibling's identical line can land
|
|
240
|
+
// on poll N while our owned line appears on poll N+k — returning
|
|
241
|
+
// no-SID on the first foreign sighting would permanently drop our id).
|
|
242
|
+
const ownedMatch = (owned) => traexHistoryMatchDelta(historyPath, baseByte, content, (sid) => traexHistorySidIsOwned(sid ?? '', owned));
|
|
243
|
+
const anyMatch = () => traexHistoryMatchDelta(historyPath, baseByte, content);
|
|
265
244
|
try {
|
|
266
245
|
if (pty.pasteText)
|
|
267
246
|
pty.pasteText(content);
|
|
@@ -274,29 +253,50 @@ export function createTraexAdapter(pathOverride) {
|
|
|
274
253
|
await delay(200);
|
|
275
254
|
if (!trySendEnter())
|
|
276
255
|
return { submitted: false };
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
256
|
+
// `sawAnyText` remembers that the submit is proven (an any-text line
|
|
257
|
+
// exists) even while we keep polling for the OWNED line. Once set, no
|
|
258
|
+
// further Enter is needed — the message is in TRAE's log — so the loop only
|
|
259
|
+
// waits for the owned rollout to surface.
|
|
260
|
+
let sawAnyText = false;
|
|
261
|
+
// Prefer an owned id whenever enumeration is possible. Returns a final
|
|
262
|
+
// result to return now, or null to keep waiting. `final` relaxes the
|
|
263
|
+
// owned-wait: at budget end / on the worker recheck, confirm on any-text.
|
|
264
|
+
const resolve = (final) => {
|
|
265
|
+
const owned = cliPid ? findTraexRolloutSetByPid(cliPid) : undefined;
|
|
266
|
+
if (owned !== undefined) {
|
|
267
|
+
const m = ownedMatch(owned);
|
|
268
|
+
if (m.found && m.cliSessionId)
|
|
269
|
+
return { submitted: true, cliSessionId: m.cliSessionId };
|
|
270
|
+
// Enumeration works but no owned line yet. Note submit evidence but
|
|
271
|
+
// keep waiting for the owned id — unless the budget is spent.
|
|
272
|
+
if (anyMatch().found)
|
|
273
|
+
sawAnyText = true;
|
|
274
|
+
return final && sawAnyText ? { submitted: true } : null;
|
|
283
275
|
}
|
|
276
|
+
// Enumeration unavailable — can't prove ownership, so confirm the submit
|
|
277
|
+
// on any-text as soon as it appears (no owned line to wait for).
|
|
278
|
+
if (anyMatch().found)
|
|
279
|
+
return { submitted: true };
|
|
280
|
+
return null;
|
|
281
|
+
};
|
|
282
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
283
|
+
const confirmed = resolve(false);
|
|
284
|
+
if (confirmed)
|
|
285
|
+
return confirmed;
|
|
284
286
|
await delay(800);
|
|
285
|
-
|
|
287
|
+
// Only re-Enter while the submit is still unproven; once any-text is
|
|
288
|
+
// seen the message is committed and we're merely waiting for the owned
|
|
289
|
+
// rollout fd, so another Enter would risk a duplicate submit.
|
|
290
|
+
if (!sawAnyText && !trySendEnter())
|
|
286
291
|
return { submitted: false };
|
|
287
292
|
}
|
|
288
|
-
const
|
|
289
|
-
if (
|
|
290
|
-
return
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
const recheck = () =>
|
|
295
|
-
const late = detectSubmittedThread(beforeSnap, content);
|
|
296
|
-
return late.found
|
|
297
|
-
? { submitted: true, cliSessionId: late.cliSessionId }
|
|
298
|
-
: false;
|
|
299
|
-
};
|
|
293
|
+
const finalConfirmed = resolve(true);
|
|
294
|
+
if (finalConfirmed)
|
|
295
|
+
return finalConfirmed;
|
|
296
|
+
// In-band budget exhausted. Hand the worker a recheck closure: a slow or
|
|
297
|
+
// busy TRAE may still append our history line after the retries gave up,
|
|
298
|
+
// and the worker re-scans on a delay before warning the user.
|
|
299
|
+
const recheck = () => resolve(true) ?? false;
|
|
300
300
|
return { submitted: false, recheck };
|
|
301
301
|
},
|
|
302
302
|
completionPattern: undefined,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traex.js","sourceRoot":"","sources":["../../../src/adapters/cli/traex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"traex.js","sourceRoot":"","sources":["../../../src/adapters/cli/traex.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAonFA,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,SAAS,GAAG,gBAAgB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnG,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,SAAS,GAAG,iBAAiB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACvE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAonFA,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,SAAS,GAAG,gBAAgB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnG,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,SAAS,GAAG,iBAAiB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACvE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAukNtE;;;;;;;;;;;GAWG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,qBAAqB,EAAE,SAAS,CAAC,EAC9F,KAAK,EAAE,MAAM,EACb,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,2BAA2B,EAAE,UAAU,GAAG,IAAI,CAAC,GACzF,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA8F7B"}
|
package/dist/cli.js
CHANGED
|
@@ -8152,22 +8152,19 @@ async function cmdDispatch(rest) {
|
|
|
8152
8152
|
}
|
|
8153
8153
|
}
|
|
8154
8154
|
/**
|
|
8155
|
-
* `botmux report` —
|
|
8156
|
-
* orchestrator that dispatched it.
|
|
8155
|
+
* `botmux report` — delivery / progress report.
|
|
8157
8156
|
*
|
|
8158
|
-
*
|
|
8159
|
-
*
|
|
8160
|
-
*
|
|
8161
|
-
*
|
|
8162
|
-
*
|
|
8163
|
-
*
|
|
8164
|
-
*
|
|
8165
|
-
* (the dispatcher of the turn that opened this sub-topic); orchestrator thread =
|
|
8166
|
-
* the registry entry keyed by this sub-bot's session.rootMessageId (== the seed).
|
|
8157
|
+
* Two paths:
|
|
8158
|
+
* 1) Platform Issue 领取群:session 有活跃 issue binding → enqueue+write `in_review`
|
|
8159
|
+
* (待验收). This is what kickoff means by 「完成后执行 botmux report」.
|
|
8160
|
+
* 2) 多话题协作:dispatched sub-bot reports back to the orchestrator session.
|
|
8161
|
+
* The sub-bot lives in its own sub-topic where the orchestrator has no session;
|
|
8162
|
+
* @-ing the orchestrator there would spawn a fresh context-less one. Instead this
|
|
8163
|
+
* routes INTO the orchestrator's thread (orchestrate-dispatch.json) and @-s it there.
|
|
8167
8164
|
*/
|
|
8168
8165
|
async function cmdReport(rest) {
|
|
8169
8166
|
if (rest.includes('--help') || rest.includes('-h')) {
|
|
8170
|
-
console.log(`botmux report —
|
|
8167
|
+
console.log(`botmux report — 交付回报(issue 待验收 / 多话题协作回主编排)
|
|
8171
8168
|
|
|
8172
8169
|
用法:
|
|
8173
8170
|
botmux report "子项目X 完成,产出在 …"
|
|
@@ -8175,9 +8172,10 @@ async function cmdReport(rest) {
|
|
|
8175
8172
|
botmux report --content-file <path>
|
|
8176
8173
|
|
|
8177
8174
|
说明:
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8175
|
+
1) 平台 Issue 领取群:本会话绑定了平台 issue 时,把 issue 推到「待验收」(in_review)。
|
|
8176
|
+
kickoff 里「完成后执行 botmux report」指的就是这条路径。
|
|
8177
|
+
2) 多话题协作:被 botmux dispatch 派活的子话题里,把回报发回主编排会话并 @ 主 bot
|
|
8178
|
+
(不要在子话题里 @ 主 bot——会另起无上下文会话)。
|
|
8181
8179
|
|
|
8182
8180
|
选项:
|
|
8183
8181
|
--content-file <path> 从文件读取回报内容
|
|
@@ -8217,7 +8215,7 @@ async function cmdReport(rest) {
|
|
|
8217
8215
|
}
|
|
8218
8216
|
const sid = sessionIdArg ?? findAncestorSessionId();
|
|
8219
8217
|
if (!sid) {
|
|
8220
|
-
console.error('无法推断 session-id
|
|
8218
|
+
console.error('无法推断 session-id。请在 issue 领取群 / 被 dispatch 派活的会话里运行,或传 --session-id <id>。');
|
|
8221
8219
|
process.exit(1);
|
|
8222
8220
|
}
|
|
8223
8221
|
const sessions = loadSessions();
|
|
@@ -8230,6 +8228,86 @@ async function cmdReport(rest) {
|
|
|
8230
8228
|
console.error(`session ${sid} 缺少 larkAppId`);
|
|
8231
8229
|
process.exit(1);
|
|
8232
8230
|
}
|
|
8231
|
+
// ── Issue Board 交付:绑定了平台 issue 的领取群 → 推 in_review(待验收)────────
|
|
8232
|
+
// 优先于 dispatch 路径:领取群没有 creatorOpenId,走 dispatch 会硬失败。
|
|
8233
|
+
// 显式 --dispatch-root 时仍走协作回报(避免 issue 群里误 dispatch 被静默改道)。
|
|
8234
|
+
if (!explicitDispatchRoot) {
|
|
8235
|
+
try {
|
|
8236
|
+
const dataDir = resolveDataDir();
|
|
8237
|
+
const { findActiveBindingForSession, reportIssueInReview } = await import('./services/issue-report.js');
|
|
8238
|
+
const binding = findActiveBindingForSession(dataDir, {
|
|
8239
|
+
chatId: s.chatId,
|
|
8240
|
+
rootMessageId: s.rootMessageId,
|
|
8241
|
+
});
|
|
8242
|
+
if (binding) {
|
|
8243
|
+
const { writeIssueStatus, findIssueById } = await import('./platform/issue-client.js');
|
|
8244
|
+
const result = await reportIssueInReview({
|
|
8245
|
+
dataDir,
|
|
8246
|
+
writeStatus: (issueId, args) => writeIssueStatus(issueId, args),
|
|
8247
|
+
fetchIssue: (teamId, issueId) => findIssueById(teamId, issueId),
|
|
8248
|
+
}, binding.anchorId);
|
|
8249
|
+
if (!result.ok) {
|
|
8250
|
+
if (result.reason === 'platform') {
|
|
8251
|
+
console.error(result.permanent
|
|
8252
|
+
? `issue 交付失败(${result.detail})。平台明确拒绝,重试不会好转——去平台看看这条任务还在不在、领取有没有被收回。`
|
|
8253
|
+
: `issue 交付失败(${result.detail})。可稍后重试同一 botmux report。`);
|
|
8254
|
+
}
|
|
8255
|
+
else if (result.reason === 'detached') {
|
|
8256
|
+
// 重试没有意义:平台上这条 claim 已经不是本机的了。
|
|
8257
|
+
console.error(`issue 交付失败:平台上这个任务的领取已不属于本机(被回收、租约过期或已被别人领走),`
|
|
8258
|
+
+ `交付没有落地。去平台看看任务 ${binding.issueId} 的状态。`);
|
|
8259
|
+
}
|
|
8260
|
+
else {
|
|
8261
|
+
console.error(`issue 交付失败:${result.reason}`);
|
|
8262
|
+
}
|
|
8263
|
+
process.exit(1);
|
|
8264
|
+
}
|
|
8265
|
+
// 交付说明必须发回群里:平台的 /status 只收状态、不收正文(没有 note 字段),
|
|
8266
|
+
// 这段文字在平台上无处可放。不发的话验收的人只看到状态变成「待验收」,完全不知道
|
|
8267
|
+
// 交付了什么,而 stdout 只有 agent 自己看得到。
|
|
8268
|
+
let delivered = false;
|
|
8269
|
+
try {
|
|
8270
|
+
const { registerBot, loadBotConfigs } = await import('./bot-registry.js');
|
|
8271
|
+
await registerSelfFromCredFile();
|
|
8272
|
+
try {
|
|
8273
|
+
for (const cfg of loadBotConfigs())
|
|
8274
|
+
registerBot(cfg);
|
|
8275
|
+
}
|
|
8276
|
+
catch { /* 已注册/读不到 */ }
|
|
8277
|
+
const { buildIssueDeliveryCard } = await import('./im/lark/issue-card.js');
|
|
8278
|
+
const { issueDetailUrl } = await import('./services/issue-claim-flow.js');
|
|
8279
|
+
const { sendMessage: larkSend } = await import('./im/lark/client.js');
|
|
8280
|
+
const url = issueDetailUrl(binding.platformBaseUrl, result.issueId);
|
|
8281
|
+
await larkSend(s.larkAppId, binding.chatId ?? binding.anchorId, buildIssueDeliveryCard({
|
|
8282
|
+
issueId: result.issueId,
|
|
8283
|
+
report: content,
|
|
8284
|
+
alreadyInReview: result.alreadyInReview,
|
|
8285
|
+
...(url ? { issueUrl: url } : {}),
|
|
8286
|
+
}), 'interactive');
|
|
8287
|
+
delivered = true;
|
|
8288
|
+
}
|
|
8289
|
+
catch (e) {
|
|
8290
|
+
// 状态已经写成功了,播报失败不该让整条命令失败——但要如实说出来,
|
|
8291
|
+
// 否则 agent 以为交付说明已经送达。
|
|
8292
|
+
console.error(`交付说明未能发回群里(状态已是待验收):${e?.message ?? e}`);
|
|
8293
|
+
}
|
|
8294
|
+
console.log(JSON.stringify({
|
|
8295
|
+
success: true,
|
|
8296
|
+
delivery: 'issue-in-review',
|
|
8297
|
+
issueId: result.issueId,
|
|
8298
|
+
anchorId: binding.anchorId,
|
|
8299
|
+
alreadyInReview: result.alreadyInReview,
|
|
8300
|
+
reportPostedToChat: delivered,
|
|
8301
|
+
reportPreview: content.trim().slice(0, 200),
|
|
8302
|
+
}));
|
|
8303
|
+
return;
|
|
8304
|
+
}
|
|
8305
|
+
}
|
|
8306
|
+
catch (err) {
|
|
8307
|
+
console.error(`issue 交付异常: ${err?.message ?? err}`);
|
|
8308
|
+
process.exit(1);
|
|
8309
|
+
}
|
|
8310
|
+
}
|
|
8233
8311
|
// Resolve where the report goes + who to @. Same-machine: the dispatch registry
|
|
8234
8312
|
// (keyed by this sub-bot's thread root) carries the orchestrator's exact coords.
|
|
8235
8313
|
// CROSS-MACHINE: the orchestrator is on another machine, so its registry isn't
|