botmux 3.2.1 → 3.3.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.
- package/dist/adapters/cli/pi.d.ts.map +1 -1
- package/dist/adapters/cli/pi.js +4 -0
- package/dist/adapters/cli/pi.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +8 -1
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/cli/deferred-topic-send.d.ts +37 -0
- package/dist/cli/deferred-topic-send.d.ts.map +1 -0
- package/dist/cli/deferred-topic-send.js +69 -0
- package/dist/cli/deferred-topic-send.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +160 -34
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +17 -12
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts +4 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +78 -8
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/deferred-schedule-settlement.d.ts +20 -0
- package/dist/core/deferred-schedule-settlement.d.ts.map +1 -0
- package/dist/core/deferred-schedule-settlement.js +18 -0
- package/dist/core/deferred-schedule-settlement.js.map +1 -0
- package/dist/core/deferred-topic-binding.d.ts +19 -0
- package/dist/core/deferred-topic-binding.d.ts.map +1 -0
- package/dist/core/deferred-topic-binding.js +55 -0
- package/dist/core/deferred-topic-binding.js.map +1 -0
- package/dist/core/scheduler.d.ts +26 -20
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +114 -56
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +47 -15
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts +17 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +178 -84
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/types.d.ts +4 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +10 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +7 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +51 -1
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +90 -5
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/schedule-card-model.d.ts +12 -3
- package/dist/dashboard/schedule-card-model.d.ts.map +1 -1
- package/dist/dashboard/schedule-card-model.js +32 -8
- package/dist/dashboard/schedule-card-model.js.map +1 -1
- package/dist/dashboard/web/dashboard-components.d.ts +7 -0
- package/dist/dashboard/web/dashboard-components.d.ts.map +1 -1
- package/dist/dashboard/web/dashboard-components.js +11 -2
- package/dist/dashboard/web/dashboard-components.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +30 -6
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/schedules-page.d.ts +2 -0
- package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
- package/dist/dashboard/web/schedules-page.js +74 -27
- package/dist/dashboard/web/schedules-page.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/{bot-defaults-page-O37SAQD5.js → bot-defaults-page-B5AY4B2J.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-6QHMLMIM.js → chunk-CUV65BIQ.js} +3 -3
- package/dist/dashboard-web/chunks/{chunk-O2DPQL7C.js → chunk-JNRSPKLS.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-FYALHCPG.js → chunk-P6GO5KT4.js} +1 -1
- package/dist/dashboard-web/chunks/chunk-QFMH6ITB.js +1 -0
- package/dist/dashboard-web/chunks/{chunk-B42PCL5P.js → chunk-UBOLHQCK.js} +1 -1
- package/dist/dashboard-web/chunks/{connectors-page-DZBQ42MH.js → connectors-page-KTC2QWNW.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-3IEGRZKQ.js → groups-page-B3EKGOLY.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-X3ADRON3.js → insights-page-X6RXNCWX.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-IV36RGQY.js → monitor-room-LLRA5LQW.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-ADFKVON4.js → monitoring-page-7MT5FEOS.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-CALAOWNS.js → office-page-KD46D5TD.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-SLMGLK3M.js → overview-page-JUWNH32O.js} +1 -1
- package/dist/dashboard-web/chunks/{roles-page-L7JJ4FFV.js → roles-page-P6F7NLOI.js} +1 -1
- package/dist/dashboard-web/chunks/schedules-page-XIHWZST4.js +1 -0
- package/dist/dashboard-web/chunks/{sessions-page-OKJ5YWUZ.js → sessions-page-2VECQ27T.js} +1 -1
- package/dist/dashboard-web/chunks/{settings-page-P6MI2ZUE.js → settings-page-HMIUE2JA.js} +1 -1
- package/dist/dashboard-web/chunks/{skills-page-FT7BVZ6X.js → skills-page-A46KVWBL.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-DEYCPUFB.js → team-federation-page-SDUC56DF.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-4IOWREZG.js → v3-page-J5JOTUSQ.js} +1 -1
- package/dist/dashboard-web/chunks/{whiteboards-page-2VMBETZH.js → whiteboards-page-U7LSOAWI.js} +1 -1
- package/dist/dashboard-web/style.css +34 -4
- package/dist/dashboard.js +16 -1
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +16 -7
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +16 -7
- 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 +3 -0
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +1 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +1 -1
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/schedules-card.d.ts +2 -2
- package/dist/im/lark/schedules-card.d.ts.map +1 -1
- package/dist/im/lark/schedules-card.js +50 -34
- package/dist/im/lark/schedules-card.js.map +1 -1
- package/dist/index-daemon.js +13 -1
- package/dist/index-daemon.js.map +1 -1
- package/dist/services/schedule-store.d.ts +6 -2
- package/dist/services/schedule-store.d.ts.map +1 -1
- package/dist/services/schedule-store.js +19 -4
- package/dist/services/schedule-store.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +4 -5
- package/dist/skills/definitions.js.map +1 -1
- package/dist/types.d.ts +36 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/child-env.d.ts +40 -1
- package/dist/utils/child-env.d.ts.map +1 -1
- package/dist/utils/child-env.js +45 -0
- package/dist/utils/child-env.js.map +1 -1
- package/dist/utils/pending-input-queue.d.ts +10 -0
- package/dist/utils/pending-input-queue.d.ts.map +1 -1
- package/dist/utils/pending-input-queue.js +15 -0
- package/dist/utils/pending-input-queue.js.map +1 -1
- package/dist/worker.js +102 -9
- package/dist/worker.js.map +1 -1
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts +3 -1
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/botmux-schedule.js +14 -3
- package/dist/workflows/hostExecutors/botmux-schedule.js.map +1 -1
- package/dist/workflows/v3/architect.js +1 -1
- package/dist/workflows/v3/architect.js.map +1 -1
- package/dist/workflows/v3/contract.d.ts +8 -0
- package/dist/workflows/v3/contract.d.ts.map +1 -1
- package/dist/workflows/v3/contract.js.map +1 -1
- package/dist/workflows/v3/daemon-run.d.ts.map +1 -1
- package/dist/workflows/v3/daemon-run.js +2 -0
- package/dist/workflows/v3/daemon-run.js.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.js +10 -2
- package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
- package/dist/workflows/v3/run-envelope.d.ts +24 -24
- package/dist/workflows/v3/runtime.d.ts +5 -0
- package/dist/workflows/v3/runtime.d.ts.map +1 -1
- package/dist/workflows/v3/runtime.js +1 -0
- package/dist/workflows/v3/runtime.js.map +1 -1
- package/package.json +1 -1
- package/dist/dashboard-web/chunks/chunk-I35DXGM4.js +0 -1
- package/dist/dashboard-web/chunks/schedules-page-Z3672POL.js +0 -1
|
@@ -19,7 +19,7 @@ export type BotAvatarOutcome = {
|
|
|
19
19
|
};
|
|
20
20
|
export declare function setBotAvatarChanger(fn: ((image: Buffer) => Promise<BotAvatarOutcome>) | null): void;
|
|
21
21
|
import { composeRowFromActive, composeRowFromClosed, type SessionRow } from './dashboard-rows.js';
|
|
22
|
-
import type { ParsedSchedule } from '../types.js';
|
|
22
|
+
import type { ParsedSchedule, ScheduleExecutionPosition } from '../types.js';
|
|
23
23
|
export interface IpcServerHandle {
|
|
24
24
|
port: number;
|
|
25
25
|
close: () => Promise<void>;
|
|
@@ -49,6 +49,9 @@ export interface ScheduleRow {
|
|
|
49
49
|
workingDir: string;
|
|
50
50
|
chatId: string;
|
|
51
51
|
rootMessageId?: string;
|
|
52
|
+
scope?: 'thread' | 'chat';
|
|
53
|
+
executionPosition?: ScheduleExecutionPosition;
|
|
54
|
+
topicTitle?: string;
|
|
52
55
|
larkAppId?: string;
|
|
53
56
|
botName?: string;
|
|
54
57
|
enabled: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-ipc-server.d.ts","sourceRoot":"","sources":["../../src/core/dashboard-ipc-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAe,MAAM,WAAW,CAAC;AAiGjG,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,wBAAgB,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAE/F;AAID,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAEnG;AACD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EAIpB,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAU7B,OAAO,KAAK,EAAiC,cAAc,EAAW,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"dashboard-ipc-server.d.ts","sourceRoot":"","sources":["../../src/core/dashboard-ipc-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAe,MAAM,WAAW,CAAC;AAiGjG,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,wBAAgB,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAE/F;AAID,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAEnG;AACD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EAIpB,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAU7B,OAAO,KAAK,EAAiC,cAAc,EAAE,yBAAyB,EAAW,MAAM,aAAa,CAAC;AAKrH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,MAAM,MAAM,OAAO,GAAG,CACpB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC3B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAe1B,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAErE;AAED,0FAA0F;AAC1F,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAM7E;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAGhF;AAED,wBAAsB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,CAAC,CAAC,CAKhF;AAaD,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAgC;AAM7F;;;wBAGwB;AACxB,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAS/D;AAyED,YAAY,EAAE,UAAU,EAAE,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,CAAC;AAMtD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAA0B;AAKxE,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAA0B;AAq6BxE,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,yBAAyB,CAAC;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,WAAW,CAAC;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAyrDD,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb;;;+EAG2E;IAC3E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,GAAG,OAAO,CAAC,eAAe,CAAC,CAmD3B"}
|
|
@@ -102,6 +102,7 @@ import { repinSessionWorkingDir } from './session-cwd.js';
|
|
|
102
102
|
import { authorizeSessionScopedIpc } from './daemon-ipc-session-auth.js';
|
|
103
103
|
import { updateSessionTitle } from './session-title.js';
|
|
104
104
|
import { requestAgentSessionRename } from './session-rename.js';
|
|
105
|
+
import { sessionAnchorId } from './types.js';
|
|
105
106
|
import { attachSkillPolicy, detachSkillPolicy } from './skills/im-command.js';
|
|
106
107
|
import { readSkillRegistry } from '../services/skill-registry-store.js';
|
|
107
108
|
const routes = [];
|
|
@@ -1111,7 +1112,7 @@ ipcRoute('POST', '/api/sessions/migrate-to-chat', async (req, res) => {
|
|
|
1111
1112
|
return jsonRes(res, 503, { ok: false, error: 'registry_unavailable' });
|
|
1112
1113
|
let ds = undefined;
|
|
1113
1114
|
for (const candidate of reg.values()) {
|
|
1114
|
-
const candAnchor = candidate
|
|
1115
|
+
const candAnchor = sessionAnchorId(candidate);
|
|
1115
1116
|
if (candAnchor === sourceAnchor && candidate.larkAppId === cachedLarkAppId) {
|
|
1116
1117
|
ds = candidate;
|
|
1117
1118
|
break;
|
|
@@ -1215,6 +1216,9 @@ function composeScheduleRow(t) {
|
|
|
1215
1216
|
workingDir: t.workingDir,
|
|
1216
1217
|
chatId: t.chatId,
|
|
1217
1218
|
rootMessageId: t.rootMessageId,
|
|
1219
|
+
scope: t.scope,
|
|
1220
|
+
executionPosition: scheduler.resolveTaskExecutionPosition(t),
|
|
1221
|
+
topicTitle: t.topicTitle,
|
|
1218
1222
|
larkAppId: t.larkAppId,
|
|
1219
1223
|
botName: getBotName(),
|
|
1220
1224
|
enabled: t.enabled,
|
|
@@ -1239,9 +1243,29 @@ ipcRoute('GET', '/api/schedules', (_req, res) => {
|
|
|
1239
1243
|
ipcRoute('POST', '/api/schedules/:id/run', (_req, res, p) => jsonRes(res, 200, scheduler.runNow(p.id)));
|
|
1240
1244
|
ipcRoute('POST', '/api/schedules/:id/pause', (_req, res, p) => jsonRes(res, 200, scheduler.setEnabled(p.id, false)));
|
|
1241
1245
|
ipcRoute('POST', '/api/schedules/:id/resume', (_req, res, p) => jsonRes(res, 200, scheduler.setEnabled(p.id, true)));
|
|
1242
|
-
//
|
|
1243
|
-
//
|
|
1244
|
-
|
|
1246
|
+
// Backward-compatible route used by Lark cards and cached dashboard clients.
|
|
1247
|
+
// Modern callers send an exact target; body-less legacy callers keep the
|
|
1248
|
+
// historical toggle behavior, now cycling topic → top-level → fresh topic.
|
|
1249
|
+
ipcRoute('POST', '/api/schedules/:id/delivery', async (req, res, p) => {
|
|
1250
|
+
let body;
|
|
1251
|
+
try {
|
|
1252
|
+
body = await readJsonBody(req);
|
|
1253
|
+
}
|
|
1254
|
+
catch {
|
|
1255
|
+
return jsonRes(res, 400, { ok: false, error: 'invalid_json' });
|
|
1256
|
+
}
|
|
1257
|
+
const requested = body && typeof body === 'object'
|
|
1258
|
+
? body.executionPosition
|
|
1259
|
+
: undefined;
|
|
1260
|
+
if (requested !== undefined) {
|
|
1261
|
+
if (requested !== 'top-level' && requested !== 'topic' && requested !== 'new-topic') {
|
|
1262
|
+
return jsonRes(res, 400, { ok: false, error: 'invalid_execution_position', field: 'executionPosition' });
|
|
1263
|
+
}
|
|
1264
|
+
const result = scheduler.updateTask(p.id, { executionPosition: requested });
|
|
1265
|
+
return jsonRes(res, 200, result.ok ? { ...result, executionPosition: requested } : result);
|
|
1266
|
+
}
|
|
1267
|
+
return jsonRes(res, 200, scheduler.toggleDelivery(p.id));
|
|
1268
|
+
});
|
|
1245
1269
|
// Create a new scheduled task from the dashboard. chatId selects which chat
|
|
1246
1270
|
// the task fires into; workingDir defaults to the daemon's cwd.
|
|
1247
1271
|
ipcRoute('POST', '/api/schedules', async (req, res) => {
|
|
@@ -1263,6 +1287,7 @@ ipcRoute('POST', '/api/schedules', async (req, res) => {
|
|
|
1263
1287
|
const schedule = typeof b.schedule === 'string' ? b.schedule.trim() : '';
|
|
1264
1288
|
const prompt = typeof b.prompt === 'string' ? b.prompt : '';
|
|
1265
1289
|
const chatId = typeof b.chatId === 'string' ? b.chatId.trim() : '';
|
|
1290
|
+
const rootMessageId = typeof b.rootMessageId === 'string' ? b.rootMessageId.trim() : '';
|
|
1266
1291
|
// Validate silent type — if present, must be boolean (no silent degradation).
|
|
1267
1292
|
let silent = false;
|
|
1268
1293
|
if (b.silent !== undefined) {
|
|
@@ -1271,14 +1296,30 @@ ipcRoute('POST', '/api/schedules', async (req, res) => {
|
|
|
1271
1296
|
}
|
|
1272
1297
|
silent = b.silent;
|
|
1273
1298
|
}
|
|
1274
|
-
|
|
1275
|
-
|
|
1299
|
+
let executionPosition = 'top-level';
|
|
1300
|
+
if (b.executionPosition !== undefined) {
|
|
1301
|
+
if (b.executionPosition !== 'top-level' && b.executionPosition !== 'topic' && b.executionPosition !== 'new-topic') {
|
|
1302
|
+
return jsonRes(res, 400, { ok: false, error: 'invalid_execution_position', field: 'executionPosition' });
|
|
1303
|
+
}
|
|
1304
|
+
executionPosition = b.executionPosition;
|
|
1305
|
+
}
|
|
1306
|
+
const topicTitle = typeof b.topicTitle === 'string' ? b.topicTitle.trim() : '';
|
|
1307
|
+
if (b.topicTitle !== undefined && typeof b.topicTitle !== 'string') {
|
|
1308
|
+
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'topicTitle' });
|
|
1309
|
+
}
|
|
1310
|
+
if (Array.from(topicTitle).length > 200) {
|
|
1311
|
+
return jsonRes(res, 400, { ok: false, error: 'topic_title_too_long', field: 'topicTitle' });
|
|
1312
|
+
}
|
|
1313
|
+
// Legacy clients sending deliver:new-topic retain the historical meaning:
|
|
1314
|
+
// open a fresh topic/session on every run.
|
|
1276
1315
|
let deliver = 'origin';
|
|
1277
1316
|
if (b.deliver !== undefined) {
|
|
1278
1317
|
if (b.deliver !== 'origin' && b.deliver !== 'new-topic') {
|
|
1279
1318
|
return jsonRes(res, 400, { ok: false, error: 'invalid_deliver', field: 'deliver' });
|
|
1280
1319
|
}
|
|
1281
1320
|
deliver = b.deliver;
|
|
1321
|
+
if (b.executionPosition === undefined && deliver === 'new-topic')
|
|
1322
|
+
executionPosition = 'new-topic';
|
|
1282
1323
|
}
|
|
1283
1324
|
// Validate required fields are present AND non-empty after trim.
|
|
1284
1325
|
if (!name)
|
|
@@ -1289,6 +1330,9 @@ ipcRoute('POST', '/api/schedules', async (req, res) => {
|
|
|
1289
1330
|
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'prompt' });
|
|
1290
1331
|
if (!chatId)
|
|
1291
1332
|
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'chatId' });
|
|
1333
|
+
if (executionPosition === 'topic' && !rootMessageId) {
|
|
1334
|
+
return jsonRes(res, 400, { ok: false, error: 'topic_root_required', field: 'rootMessageId' });
|
|
1335
|
+
}
|
|
1292
1336
|
// Note: bot↔chat membership is intentionally NOT validated here.
|
|
1293
1337
|
// listChatBotMembers returns [] both when the API is unavailable and when
|
|
1294
1338
|
// no bot has been observed in the chat yet, so we cannot reliably tell
|
|
@@ -1303,7 +1347,10 @@ ipcRoute('POST', '/api/schedules', async (req, res) => {
|
|
|
1303
1347
|
prompt,
|
|
1304
1348
|
workingDir: typeof b.workingDir === 'string' ? b.workingDir : process.cwd(),
|
|
1305
1349
|
chatId,
|
|
1306
|
-
|
|
1350
|
+
rootMessageId: rootMessageId || undefined,
|
|
1351
|
+
scope: executionPosition === 'topic' ? 'thread' : 'chat',
|
|
1352
|
+
executionPosition,
|
|
1353
|
+
topicTitle: topicTitle || undefined,
|
|
1307
1354
|
chatType: 'group',
|
|
1308
1355
|
larkAppId: cachedLarkAppId,
|
|
1309
1356
|
deliver,
|
|
@@ -1317,7 +1364,8 @@ ipcRoute('POST', '/api/schedules', async (req, res) => {
|
|
|
1317
1364
|
jsonRes(res, 400, { ok: false, error: msg });
|
|
1318
1365
|
}
|
|
1319
1366
|
});
|
|
1320
|
-
// Update editable fields of an existing task
|
|
1367
|
+
// Update editable fields of an existing task. Execution position is explicit;
|
|
1368
|
+
// topic execution requires a retained/provided topic root message id.
|
|
1321
1369
|
ipcRoute('PATCH', '/api/schedules/:id', async (req, res, p) => {
|
|
1322
1370
|
let body;
|
|
1323
1371
|
try {
|
|
@@ -1357,6 +1405,28 @@ ipcRoute('PATCH', '/api/schedules/:id', async (req, res, p) => {
|
|
|
1357
1405
|
}
|
|
1358
1406
|
updates.deliver = b.deliver;
|
|
1359
1407
|
}
|
|
1408
|
+
if (b.executionPosition !== undefined) {
|
|
1409
|
+
if (b.executionPosition !== 'top-level' && b.executionPosition !== 'topic' && b.executionPosition !== 'new-topic') {
|
|
1410
|
+
return jsonRes(res, 400, { ok: false, error: 'invalid_execution_position', field: 'executionPosition' });
|
|
1411
|
+
}
|
|
1412
|
+
updates.executionPosition = b.executionPosition;
|
|
1413
|
+
}
|
|
1414
|
+
if (b.rootMessageId !== undefined) {
|
|
1415
|
+
if (typeof b.rootMessageId !== 'string') {
|
|
1416
|
+
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'rootMessageId' });
|
|
1417
|
+
}
|
|
1418
|
+
updates.rootMessageId = b.rootMessageId.trim();
|
|
1419
|
+
}
|
|
1420
|
+
if (b.topicTitle !== undefined) {
|
|
1421
|
+
if (typeof b.topicTitle !== 'string') {
|
|
1422
|
+
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'topicTitle' });
|
|
1423
|
+
}
|
|
1424
|
+
const topicTitle = b.topicTitle.trim();
|
|
1425
|
+
if (Array.from(topicTitle).length > 200) {
|
|
1426
|
+
return jsonRes(res, 400, { ok: false, error: 'topic_title_too_long', field: 'topicTitle' });
|
|
1427
|
+
}
|
|
1428
|
+
updates.topicTitle = topicTitle;
|
|
1429
|
+
}
|
|
1360
1430
|
if (b.silent !== undefined) {
|
|
1361
1431
|
if (typeof b.silent !== 'boolean') {
|
|
1362
1432
|
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'silent' });
|