duclaw-cli 1.8.2 → 1.8.4
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/bundle.js +180 -44
- package/dist/main.js +1 -1
- package/dist/web/assets/{index-irglpeKE.js → index-DNZUkHie.js} +1 -1
- package/dist/web/assets/index-tSI9zUzw.css +1 -0
- package/dist/web/index.html +2 -2
- package/dist/worker-main.js +1 -1
- package/package.json +1 -1
- package/dist/web/assets/index-DAfUZGs6.css +0 -1
package/dist/bundle.js
CHANGED
|
@@ -30242,7 +30242,7 @@ function printHelp() {
|
|
|
30242
30242
|
`);
|
|
30243
30243
|
}
|
|
30244
30244
|
function printVersion() {
|
|
30245
|
-
console.log(`duclaw-cli v${true ? "1.8.
|
|
30245
|
+
console.log(`duclaw-cli v${true ? "1.8.4" : "unknown"}`);
|
|
30246
30246
|
}
|
|
30247
30247
|
function getDuclawTemplate() {
|
|
30248
30248
|
return {
|
|
@@ -45312,10 +45312,24 @@ var executeJob = async (job) => {
|
|
|
45312
45312
|
const resultFilePath = saveResultToFile(job, result);
|
|
45313
45313
|
console.log(`[cron\u6267\u884C\u5B8C\u6210] \u5B9A\u65F6\u4EFB\u52A1\u6267\u884C\u7ED3\u679C: ${resultFilePath}`);
|
|
45314
45314
|
updateJobLastRunTime(job.id);
|
|
45315
|
+
return { ok: true, resultFilePath };
|
|
45315
45316
|
} catch (error) {
|
|
45316
|
-
|
|
45317
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
45318
|
+
console.error(`[cron] \u4EFB\u52A1\u6267\u884C\u5931\u8D25: ${job.id} - ${message}`);
|
|
45319
|
+
return { ok: false, error: message };
|
|
45317
45320
|
}
|
|
45318
45321
|
};
|
|
45322
|
+
var runJobById = async (jobId) => {
|
|
45323
|
+
const job = listJobs().find((item) => item.id === jobId);
|
|
45324
|
+
if (!job) {
|
|
45325
|
+
return { ok: false, error: "job_not_found" };
|
|
45326
|
+
}
|
|
45327
|
+
if (!job.enabled) {
|
|
45328
|
+
return { ok: false, error: "job_disabled", job };
|
|
45329
|
+
}
|
|
45330
|
+
const result = await executeJob(job);
|
|
45331
|
+
return { ...result, job };
|
|
45332
|
+
};
|
|
45319
45333
|
var executeAgentJob = async (job) => {
|
|
45320
45334
|
const { registry: registry2, executor } = getCronTools();
|
|
45321
45335
|
const tools = getAllTools(registry2);
|
|
@@ -49998,6 +50012,23 @@ cronRoutes.get("/cron/jobs/:id/history", (c) => {
|
|
|
49998
50012
|
return c.json({ error: err.message || "Failed to get job history" }, 500);
|
|
49999
50013
|
}
|
|
50000
50014
|
});
|
|
50015
|
+
cronRoutes.post("/cron/jobs/:id/run", async (c) => {
|
|
50016
|
+
const id = c.req.param("id");
|
|
50017
|
+
try {
|
|
50018
|
+
const result = await runJobById(id);
|
|
50019
|
+
if (!result.ok) {
|
|
50020
|
+
const status = result.error === "job_not_found" ? 404 : 400;
|
|
50021
|
+
return c.json({ error: result.error || "Failed to run job" }, status);
|
|
50022
|
+
}
|
|
50023
|
+
return c.json({
|
|
50024
|
+
ok: true,
|
|
50025
|
+
jobId: result.job?.id ?? id,
|
|
50026
|
+
resultFilePath: result.resultFilePath
|
|
50027
|
+
});
|
|
50028
|
+
} catch (err) {
|
|
50029
|
+
return c.json({ error: err.message || "Failed to run job" }, 500);
|
|
50030
|
+
}
|
|
50031
|
+
});
|
|
50001
50032
|
|
|
50002
50033
|
// src/server/routes/mailbox.ts
|
|
50003
50034
|
var mailboxRoutes = new Hono2();
|
|
@@ -50175,6 +50206,7 @@ var userKeyPatterns = [
|
|
|
50175
50206
|
];
|
|
50176
50207
|
var conversationKeyPattern = { match: "agent:mem:*", prefix: "agent:mem:" };
|
|
50177
50208
|
var dateSegmentPattern = /^\d{8}$/;
|
|
50209
|
+
var MAIN_MANAGER_USER_ID = "__main_manager__";
|
|
50178
50210
|
var isPlausibleUserId = (userId) => {
|
|
50179
50211
|
if (!userId) return false;
|
|
50180
50212
|
if (userId.length > 240) return false;
|
|
@@ -50276,7 +50308,16 @@ var extractMemoryUserIdsFromKeys = (keys) => {
|
|
|
50276
50308
|
};
|
|
50277
50309
|
var collectCompactSummaries = async (userId) => {
|
|
50278
50310
|
if (isFileBackedRuntime()) {
|
|
50279
|
-
|
|
50311
|
+
const { compactSummaryStorage: compactSummaryStorage2 } = getSharedDeps();
|
|
50312
|
+
const records2 = [];
|
|
50313
|
+
const prefix2 = `agent:compact:summary:${userId}:`;
|
|
50314
|
+
for (const key of extractFileBackedStorageKeysForTest(getDuclawDataDir())) {
|
|
50315
|
+
if (!key.startsWith(prefix2)) continue;
|
|
50316
|
+
const logicalKey = key.startsWith("agent:") ? key.slice("agent:".length) : key;
|
|
50317
|
+
const value = await compactSummaryStorage2.get(logicalKey);
|
|
50318
|
+
if (value?.length) records2.push(...value);
|
|
50319
|
+
}
|
|
50320
|
+
return records2.sort((a, b) => b.createdAt - a.createdAt);
|
|
50280
50321
|
}
|
|
50281
50322
|
const client2 = await getRedisClient();
|
|
50282
50323
|
const { compactSummaryStorage } = getSharedDeps();
|
|
@@ -50291,6 +50332,78 @@ var collectCompactSummaries = async (userId) => {
|
|
|
50291
50332
|
}
|
|
50292
50333
|
return records.sort((a, b) => b.createdAt - a.createdAt);
|
|
50293
50334
|
};
|
|
50335
|
+
var isMailboxScopedUserId = (userId) => userId === "manager" || userId.includes("::") || userId.startsWith("cron-") || userId.startsWith("kanban:goal:");
|
|
50336
|
+
var classifyMemoryUser = (userId) => {
|
|
50337
|
+
if (userId === MAIN_MANAGER_USER_ID) return "main-manager";
|
|
50338
|
+
if (userId.startsWith("kanban:")) return "kanban";
|
|
50339
|
+
if (userId.includes("::")) return "department";
|
|
50340
|
+
if (userId.startsWith("oc_") || userId.startsWith("chat_")) return "chat";
|
|
50341
|
+
return "user";
|
|
50342
|
+
};
|
|
50343
|
+
var collectManagerRelatedUserIds = (userId) => {
|
|
50344
|
+
if (isMailboxScopedUserId(userId)) return [userId];
|
|
50345
|
+
try {
|
|
50346
|
+
const db3 = createSqliteDB();
|
|
50347
|
+
const rows = db3.prepare(
|
|
50348
|
+
`SELECT DISTINCT to_mailbox_id AS toMailboxId, from_mailbox_id AS fromMailboxId
|
|
50349
|
+
FROM mailbox
|
|
50350
|
+
WHERE origin_user_id = ?
|
|
50351
|
+
ORDER BY to_mailbox_id ASC, from_mailbox_id ASC`
|
|
50352
|
+
).all(userId);
|
|
50353
|
+
const ids = /* @__PURE__ */ new Set([userId]);
|
|
50354
|
+
for (const row of rows) {
|
|
50355
|
+
addPlausibleUserId(ids, row.toMailboxId || void 0);
|
|
50356
|
+
addPlausibleUserId(ids, row.fromMailboxId || void 0);
|
|
50357
|
+
}
|
|
50358
|
+
ids.delete("manager");
|
|
50359
|
+
return Array.from(ids);
|
|
50360
|
+
} catch (err) {
|
|
50361
|
+
console.warn(`[memoryRoutes] \u83B7\u53D6 Main Manager \u5173\u8054\u4E0A\u4E0B\u6587\u5931\u8D25 userId=${userId}: ${err.message}`);
|
|
50362
|
+
return [userId];
|
|
50363
|
+
}
|
|
50364
|
+
};
|
|
50365
|
+
var collectMainManagerScopeUserIds = async () => {
|
|
50366
|
+
const { userIds } = await collectUserIds();
|
|
50367
|
+
return Array.from(new Set(userIds.filter((id) => id !== MAIN_MANAGER_USER_ID && !isMailboxScopedUserId(id))));
|
|
50368
|
+
};
|
|
50369
|
+
var collectMemoryScopeUserIds = async (userId) => {
|
|
50370
|
+
if (userId === MAIN_MANAGER_USER_ID) return collectMainManagerScopeUserIds();
|
|
50371
|
+
return collectManagerRelatedUserIds(userId);
|
|
50372
|
+
};
|
|
50373
|
+
var aggregateMemorySummaries = async (userId, localConversationUserIds) => {
|
|
50374
|
+
const { memoryEngine, dreamStorage, dreamStateStorage, topicStorage } = getSharedDeps();
|
|
50375
|
+
const relatedUserIds = await collectMemoryScopeUserIds(userId);
|
|
50376
|
+
const details = await Promise.all(relatedUserIds.map(async (scopeUserId) => {
|
|
50377
|
+
const [memories, dreamContent, dreamState, topics] = await Promise.all([
|
|
50378
|
+
memoryEngine.list(scopeUserId),
|
|
50379
|
+
dreamStorage.get(`dream:latest:${scopeUserId}`),
|
|
50380
|
+
dreamStateStorage.get(`dream:state:${scopeUserId}`),
|
|
50381
|
+
topicStorage.get(`topics:${scopeUserId}`)
|
|
50382
|
+
]);
|
|
50383
|
+
return {
|
|
50384
|
+
userId: scopeUserId,
|
|
50385
|
+
memoryCount: memories.length,
|
|
50386
|
+
hasDream: !!dreamContent,
|
|
50387
|
+
hasConversation: (topics?.length ?? 0) > 0 || localConversationUserIds.has(scopeUserId),
|
|
50388
|
+
lastDreamAt: dreamState?.lastDreamAt ?? null,
|
|
50389
|
+
lastActivityAt: dreamState?.lastActivityAt ?? null
|
|
50390
|
+
};
|
|
50391
|
+
}));
|
|
50392
|
+
const memoryCount = details.reduce((sum, detail) => sum + detail.memoryCount, 0);
|
|
50393
|
+
return {
|
|
50394
|
+
userId,
|
|
50395
|
+
displayName: userId === MAIN_MANAGER_USER_ID ? "Main Manager \u6C47\u603B" : void 0,
|
|
50396
|
+
kind: classifyMemoryUser(userId),
|
|
50397
|
+
memoryCount,
|
|
50398
|
+
hasMemory: memoryCount > 0,
|
|
50399
|
+
hasDream: details.some((detail) => detail.hasDream),
|
|
50400
|
+
hasConversation: details.some((detail) => detail.hasConversation),
|
|
50401
|
+
lastDreamAt: Math.max(0, ...details.map((detail) => detail.lastDreamAt ?? 0)) || null,
|
|
50402
|
+
lastActivityAt: Math.max(0, ...details.map((detail) => detail.lastActivityAt ?? 0)) || null,
|
|
50403
|
+
relatedUserIds: relatedUserIds.length > 0 && (userId === MAIN_MANAGER_USER_ID || relatedUserIds.length > 1) ? relatedUserIds : void 0,
|
|
50404
|
+
isAggregate: userId === MAIN_MANAGER_USER_ID || relatedUserIds.length > 1 || void 0
|
|
50405
|
+
};
|
|
50406
|
+
};
|
|
50294
50407
|
var collectUserIds = async () => {
|
|
50295
50408
|
const userIds = /* @__PURE__ */ new Set();
|
|
50296
50409
|
const localConversationUserIds = collectLocalConversationUserIds();
|
|
@@ -50312,28 +50425,15 @@ var collectUserIds = async () => {
|
|
|
50312
50425
|
var memoryRoutes = new Hono2();
|
|
50313
50426
|
memoryRoutes.get("/memory/users", async (c) => {
|
|
50314
50427
|
try {
|
|
50315
|
-
const { memoryEngine, dreamStorage, dreamStateStorage, topicStorage } = getSharedDeps();
|
|
50316
50428
|
const { userIds, localConversationUserIds } = await collectUserIds();
|
|
50317
|
-
const summaries = await Promise.all(userIds.map(
|
|
50318
|
-
|
|
50319
|
-
|
|
50320
|
-
|
|
50321
|
-
|
|
50322
|
-
|
|
50323
|
-
]);
|
|
50324
|
-
const summary = {
|
|
50325
|
-
userId,
|
|
50326
|
-
memoryCount: memories.length,
|
|
50327
|
-
hasMemory: memories.length > 0,
|
|
50328
|
-
hasDream: !!dreamContent,
|
|
50329
|
-
hasConversation: (topics?.length ?? 0) > 0 || localConversationUserIds.has(userId),
|
|
50330
|
-
lastDreamAt: dreamState?.lastDreamAt ?? null,
|
|
50331
|
-
lastActivityAt: dreamState?.lastActivityAt ?? null
|
|
50332
|
-
};
|
|
50333
|
-
return summary;
|
|
50334
|
-
}));
|
|
50429
|
+
const summaries = await Promise.all(userIds.map(
|
|
50430
|
+
(userId) => aggregateMemorySummaries(userId, localConversationUserIds)
|
|
50431
|
+
));
|
|
50432
|
+
if (userIds.length > 0) {
|
|
50433
|
+
summaries.unshift(await aggregateMemorySummaries(MAIN_MANAGER_USER_ID, localConversationUserIds));
|
|
50434
|
+
}
|
|
50335
50435
|
summaries.sort(
|
|
50336
|
-
(a, b) => (b.lastActivityAt ?? 0) - (a.lastActivityAt ?? 0) || a.userId.localeCompare(b.userId)
|
|
50436
|
+
(a, b) => Number(b.userId === MAIN_MANAGER_USER_ID) - Number(a.userId === MAIN_MANAGER_USER_ID) || (b.lastActivityAt ?? 0) - (a.lastActivityAt ?? 0) || a.userId.localeCompare(b.userId)
|
|
50337
50437
|
);
|
|
50338
50438
|
return c.json(summaries);
|
|
50339
50439
|
} catch (err) {
|
|
@@ -50345,7 +50445,10 @@ memoryRoutes.get("/memory", async (c) => {
|
|
|
50345
50445
|
if (!userId) return c.json({ error: "userId is required" }, 400);
|
|
50346
50446
|
try {
|
|
50347
50447
|
const { memoryEngine } = getSharedDeps();
|
|
50348
|
-
const
|
|
50448
|
+
const scopeUserIds = await collectMemoryScopeUserIds(userId);
|
|
50449
|
+
const memories = (await Promise.all(
|
|
50450
|
+
scopeUserIds.map((scopeUserId) => memoryEngine.list(scopeUserId))
|
|
50451
|
+
)).flat();
|
|
50349
50452
|
return c.json(sortMemories(memories));
|
|
50350
50453
|
} catch (err) {
|
|
50351
50454
|
return c.json({ error: err.message || "Failed to list memories" }, 500);
|
|
@@ -50408,16 +50511,28 @@ memoryRoutes.get("/memory/dream", async (c) => {
|
|
|
50408
50511
|
if (!userId) return c.json({ error: "userId is required" }, 400);
|
|
50409
50512
|
try {
|
|
50410
50513
|
const { dreamStorage, dreamHistoryStorage, dreamStateStorage } = getSharedDeps();
|
|
50411
|
-
const
|
|
50412
|
-
|
|
50413
|
-
|
|
50414
|
-
|
|
50415
|
-
|
|
50514
|
+
const scopeUserIds = await collectMemoryScopeUserIds(userId);
|
|
50515
|
+
const scoped = await Promise.all(scopeUserIds.map(async (scopeUserId) => {
|
|
50516
|
+
const [dreamContent2, dreamHistory2, state2] = await Promise.all([
|
|
50517
|
+
dreamStorage.get(`dream:latest:${scopeUserId}`),
|
|
50518
|
+
dreamHistoryStorage.get(`dream:history:${scopeUserId}`),
|
|
50519
|
+
dreamStateStorage.get(`dream:state:${scopeUserId}`)
|
|
50520
|
+
]);
|
|
50521
|
+
return { userId: scopeUserId, dreamContent: dreamContent2 || "", dreamHistory: dreamHistory2 || [], state: state2 || null };
|
|
50522
|
+
}));
|
|
50523
|
+
const dreamContent = scoped.filter((item) => item.dreamContent.trim()).map((item) => scoped.length > 1 ? `## ${item.userId}
|
|
50524
|
+
${item.dreamContent}` : item.dreamContent).join("\n\n");
|
|
50525
|
+
const dreamHistory = scoped.flatMap((item) => item.dreamHistory.map((entry) => ({
|
|
50526
|
+
...entry,
|
|
50527
|
+
content: scoped.length > 1 ? `[${item.userId}]
|
|
50528
|
+
${entry.content}` : entry.content
|
|
50529
|
+
}))).sort((a, b) => b.createdAt - a.createdAt);
|
|
50530
|
+
const state = scoped.map((item) => item.state).filter((item) => !!item).sort((a, b) => b.lastActivityAt - a.lastActivityAt)[0] ?? null;
|
|
50416
50531
|
return c.json({
|
|
50417
50532
|
userId,
|
|
50418
|
-
dreamContent
|
|
50419
|
-
dreamHistory
|
|
50420
|
-
state
|
|
50533
|
+
dreamContent,
|
|
50534
|
+
dreamHistory,
|
|
50535
|
+
state
|
|
50421
50536
|
});
|
|
50422
50537
|
} catch (err) {
|
|
50423
50538
|
return c.json({ error: err.message || "Failed to get dream summary" }, 500);
|
|
@@ -50427,7 +50542,9 @@ memoryRoutes.get("/memory/compact", async (c) => {
|
|
|
50427
50542
|
const userId = requireUserId(c.req.query("userId"));
|
|
50428
50543
|
if (!userId) return c.json({ error: "userId is required" }, 400);
|
|
50429
50544
|
try {
|
|
50430
|
-
const summaries = await
|
|
50545
|
+
const summaries = (await Promise.all(
|
|
50546
|
+
(await collectMemoryScopeUserIds(userId)).map((scopeUserId) => collectCompactSummaries(scopeUserId))
|
|
50547
|
+
)).flat().sort((a, b) => b.createdAt - a.createdAt);
|
|
50431
50548
|
return c.json({
|
|
50432
50549
|
userId,
|
|
50433
50550
|
summaries
|
|
@@ -50444,19 +50561,25 @@ memoryRoutes.get("/memory/recall", async (c) => {
|
|
|
50444
50561
|
const limit = Math.min(Number(c.req.query("limit")) || 20, 50);
|
|
50445
50562
|
try {
|
|
50446
50563
|
const { recallIndexStorage } = getSharedDeps();
|
|
50564
|
+
const scopeUserIds = await collectMemoryScopeUserIds(userId);
|
|
50447
50565
|
if (query) {
|
|
50448
|
-
const
|
|
50566
|
+
const scopedResults = await Promise.all(scopeUserIds.map(
|
|
50567
|
+
(scopeUserId) => searchRecallIndex(recallIndexStorage, scopeUserId, query, date, limit)
|
|
50568
|
+
));
|
|
50569
|
+
const matches = scopedResults.flatMap((result) => result.matches).sort((a, b) => b.score - a.score).slice(0, limit);
|
|
50449
50570
|
return c.json({
|
|
50450
50571
|
userId,
|
|
50451
50572
|
query,
|
|
50452
|
-
total: result.total,
|
|
50453
|
-
entries:
|
|
50573
|
+
total: scopedResults.reduce((sum, result) => sum + result.total, 0),
|
|
50574
|
+
entries: matches.map((match2) => ({
|
|
50454
50575
|
...match2.entry,
|
|
50455
50576
|
score: match2.score
|
|
50456
50577
|
}))
|
|
50457
50578
|
});
|
|
50458
50579
|
}
|
|
50459
|
-
const entries = await
|
|
50580
|
+
const entries = (await Promise.all(
|
|
50581
|
+
scopeUserIds.map((scopeUserId) => recallIndexStorage.get(`recall:index:${scopeUserId}`))
|
|
50582
|
+
)).flatMap((items) => items ?? []);
|
|
50460
50583
|
const filtered = date ? entries.filter((entry) => entry.date === date) : entries;
|
|
50461
50584
|
filtered.sort((a, b) => b.createdAt - a.createdAt);
|
|
50462
50585
|
return c.json({
|
|
@@ -50474,10 +50597,19 @@ memoryRoutes.get("/memory/context", async (c) => {
|
|
|
50474
50597
|
if (!userId) return c.json({ error: "userId is required" }, 400);
|
|
50475
50598
|
try {
|
|
50476
50599
|
const { memoryEngine, dreamStorage } = getSharedDeps();
|
|
50477
|
-
const
|
|
50478
|
-
|
|
50479
|
-
|
|
50480
|
-
|
|
50600
|
+
const scopeUserIds = await collectMemoryScopeUserIds(userId);
|
|
50601
|
+
const scoped = await Promise.all(scopeUserIds.map(async (scopeUserId) => {
|
|
50602
|
+
const [memoryContextBlock2, dreamContent2] = await Promise.all([
|
|
50603
|
+
memoryEngine.buildContextBlock(scopeUserId),
|
|
50604
|
+
dreamStorage.get(`dream:latest:${scopeUserId}`)
|
|
50605
|
+
]);
|
|
50606
|
+
return { userId: scopeUserId, memoryContextBlock: memoryContextBlock2, dreamContent: dreamContent2 };
|
|
50607
|
+
}));
|
|
50608
|
+
const memoryContextBlock = scoped.filter((item) => item.memoryContextBlock.trim()).map((item) => scoped.length > 1 ? `<main-manager-context-source userId="${item.userId}">
|
|
50609
|
+
${item.memoryContextBlock}
|
|
50610
|
+
</main-manager-context-source>` : item.memoryContextBlock).join("\n\n");
|
|
50611
|
+
const dreamContent = scoped.filter((item) => item.dreamContent?.trim()).map((item) => scoped.length > 1 ? `## ${item.userId}
|
|
50612
|
+
${item.dreamContent}` : item.dreamContent).join("\n\n");
|
|
50481
50613
|
const dreamContextBlock = dreamContent ? [
|
|
50482
50614
|
"<memory-context>",
|
|
50483
50615
|
"\u4EE5\u4E0B\u662F\u4F60\u901A\u8FC7\u505A\u68A6\u4FDD\u7559\u7684\u8DE8\u5929\u8BB0\u5FC6\u3002\u8BB0\u4F4F\u8FD9\u4E9B\u4FE1\u606F\uFF0C\u4F46\u4E0D\u8981\u4E3B\u52A8\u63D0\u53CA\u2014\u2014\u9664\u975E\u7528\u6237\u7684\u8BDD\u9898\u76F8\u5173\u3002",
|
|
@@ -50550,7 +50682,7 @@ var systemRoutes = new Hono2();
|
|
|
50550
50682
|
var startTime = Date.now();
|
|
50551
50683
|
systemRoutes.get("/system/info", (c) => {
|
|
50552
50684
|
return c.json({
|
|
50553
|
-
version: true ? "1.8.
|
|
50685
|
+
version: true ? "1.8.4" : "unknown",
|
|
50554
50686
|
uptime: Math.floor((Date.now() - startTime) / 1e3),
|
|
50555
50687
|
env: process.env.NODE_ENV || "development",
|
|
50556
50688
|
nodeVersion: process.version
|
|
@@ -50651,8 +50783,12 @@ async function main() {
|
|
|
50651
50783
|
} else {
|
|
50652
50784
|
console.log(`[main] Core Channel Gateway \u5DF2\u8DF3\u8FC7\uFF0C\u5F53\u524D\u5916\u90E8\u6D88\u606F\u5165\u53E3\u7531 SaaS \u5C42\u63A5\u7BA1`);
|
|
50653
50785
|
}
|
|
50654
|
-
|
|
50655
|
-
|
|
50786
|
+
if (process.env.DUCLAW_CRON_SCHEDULER === "saas") {
|
|
50787
|
+
console.log(`[main] \u5B9A\u65F6\u4EFB\u52A1\u8C03\u5EA6\u5668\u5DF2\u8DF3\u8FC7\uFF0C\u5F53\u524D\u7531 SaaS \u5C42\u63A5\u7BA1`);
|
|
50788
|
+
} else {
|
|
50789
|
+
startScheduler();
|
|
50790
|
+
console.log(`[main] \u5B9A\u65F6\u4EFB\u52A1\u8C03\u5EA6\u5668\u5DF2\u542F\u52A8`);
|
|
50791
|
+
}
|
|
50656
50792
|
startMailboxPoller();
|
|
50657
50793
|
console.log(`[main] \u591A\u667A\u80FD\u4F53\u90AE\u7BB1\u8F6E\u8BE2\u5DF2\u542F\u52A8`);
|
|
50658
50794
|
const kanbanPort = Number(process.env.KANBAN_PORT || 3e3);
|