duclaw-cli 1.8.3 → 1.8.5

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 CHANGED
@@ -30242,7 +30242,7 @@ function printHelp() {
30242
30242
  `);
30243
30243
  }
30244
30244
  function printVersion() {
30245
- console.log(`duclaw-cli v${true ? "1.8.3" : "unknown"}`);
30245
+ console.log(`duclaw-cli v${true ? "1.8.5" : "unknown"}`);
30246
30246
  }
30247
30247
  function getDuclawTemplate() {
30248
30248
  return {
@@ -50332,6 +50332,12 @@ var collectCompactSummaries = async (userId) => {
50332
50332
  return records.sort((a, b) => b.createdAt - a.createdAt);
50333
50333
  };
50334
50334
  var isMailboxScopedUserId = (userId) => userId === "manager" || userId.includes("::") || userId.startsWith("cron-") || userId.startsWith("kanban:goal:");
50335
+ var classifyMemoryUser = (userId) => {
50336
+ if (userId.startsWith("kanban:")) return "kanban";
50337
+ if (userId.includes("::")) return "department";
50338
+ if (userId.startsWith("oc_") || userId.startsWith("chat_")) return "chat";
50339
+ return "user";
50340
+ };
50335
50341
  var collectManagerRelatedUserIds = (userId) => {
50336
50342
  if (isMailboxScopedUserId(userId)) return [userId];
50337
50343
  try {
@@ -50354,10 +50360,12 @@ var collectManagerRelatedUserIds = (userId) => {
50354
50360
  return [userId];
50355
50361
  }
50356
50362
  };
50357
- var collectMemoryScopeUserIds = (userId) => collectManagerRelatedUserIds(userId);
50363
+ var collectMemoryScopeUserIds = async (userId) => {
50364
+ return collectManagerRelatedUserIds(userId);
50365
+ };
50358
50366
  var aggregateMemorySummaries = async (userId, localConversationUserIds) => {
50359
50367
  const { memoryEngine, dreamStorage, dreamStateStorage, topicStorage } = getSharedDeps();
50360
- const relatedUserIds = collectMemoryScopeUserIds(userId);
50368
+ const relatedUserIds = await collectMemoryScopeUserIds(userId);
50361
50369
  const details = await Promise.all(relatedUserIds.map(async (scopeUserId) => {
50362
50370
  const [memories, dreamContent, dreamState, topics] = await Promise.all([
50363
50371
  memoryEngine.list(scopeUserId),
@@ -50377,6 +50385,7 @@ var aggregateMemorySummaries = async (userId, localConversationUserIds) => {
50377
50385
  const memoryCount = details.reduce((sum, detail) => sum + detail.memoryCount, 0);
50378
50386
  return {
50379
50387
  userId,
50388
+ kind: classifyMemoryUser(userId),
50380
50389
  memoryCount,
50381
50390
  hasMemory: memoryCount > 0,
50382
50391
  hasDream: details.some((detail) => detail.hasDream),
@@ -50404,6 +50413,54 @@ var collectUserIds = async () => {
50404
50413
  }
50405
50414
  return { userIds: Array.from(userIds), localConversationUserIds };
50406
50415
  };
50416
+ var dateKeyInShanghai = (timestamp) => new Date(timestamp).toLocaleString("sv-SE", {
50417
+ timeZone: "Asia/Shanghai",
50418
+ year: "numeric",
50419
+ month: "2-digit",
50420
+ day: "2-digit"
50421
+ }).replace(/-/g, "");
50422
+ var messageToAgentLogEntry = (message, index) => ({
50423
+ index,
50424
+ role: message.role,
50425
+ blocks: message.content.map((block) => {
50426
+ if (block.type === "text") return { type: "text", text: block.text };
50427
+ if (block.type === "tool_use") {
50428
+ return {
50429
+ type: "tool_use",
50430
+ id: block.id,
50431
+ name: block.name,
50432
+ input: block.input
50433
+ };
50434
+ }
50435
+ if (block.type === "tool_result") {
50436
+ return {
50437
+ type: "tool_result",
50438
+ toolUseId: block.tool_use_id,
50439
+ content: typeof block.content === "string" ? block.content.slice(0, 4e3) : JSON.stringify(block.content).slice(0, 4e3)
50440
+ };
50441
+ }
50442
+ return { type: "unknown" };
50443
+ })
50444
+ });
50445
+ var collectConversationMessages = async (userId, limit = 300) => {
50446
+ const storageConf = { url: process.env.REDIS_URL };
50447
+ const storage = createRuntimeStorage(storageConf);
50448
+ const now = Date.now();
50449
+ const byDate = [];
50450
+ for (let i = 0; i < 7; i++) {
50451
+ const dateStr = dateKeyInShanghai(now - i * 864e5);
50452
+ const messages = await getMessages(storage, userId, limit, dateStr);
50453
+ if (messages.length > 0) byDate.push(...messages);
50454
+ }
50455
+ const fallback = byDate.length > 0 ? [] : await getMessages(storage, userId, limit);
50456
+ const seen = /* @__PURE__ */ new Set();
50457
+ return [...byDate, ...fallback].filter((message) => {
50458
+ const key = `${message.role}:${message.timestamp ?? ""}:${JSON.stringify(message.content).slice(0, 80)}`;
50459
+ if (seen.has(key)) return false;
50460
+ seen.add(key);
50461
+ return true;
50462
+ });
50463
+ };
50407
50464
  var memoryRoutes = new Hono2();
50408
50465
  memoryRoutes.get("/memory/users", async (c) => {
50409
50466
  try {
@@ -50419,13 +50476,35 @@ memoryRoutes.get("/memory/users", async (c) => {
50419
50476
  return c.json({ error: err.message || "Failed to list memory users" }, 500);
50420
50477
  }
50421
50478
  });
50479
+ memoryRoutes.get("/memory/context-sources", async (c) => {
50480
+ try {
50481
+ loadEnv();
50482
+ const limit = Math.min(Number(c.req.query("limit")) || 300, 500);
50483
+ const { userIds } = await collectUserIds();
50484
+ const sources = (await Promise.all(userIds.map(async (userId) => {
50485
+ const messages = await collectConversationMessages(userId, limit);
50486
+ if (messages.length === 0) return null;
50487
+ return {
50488
+ userId,
50489
+ displayName: void 0,
50490
+ kind: classifyMemoryUser(userId) ?? "user",
50491
+ messageCount: messages.length,
50492
+ agentLogs: messages.map(messageToAgentLogEntry)
50493
+ };
50494
+ }))).filter((source) => !!source).sort((a, b) => b.messageCount - a.messageCount || a.userId.localeCompare(b.userId));
50495
+ return c.json({ sources });
50496
+ } catch (err) {
50497
+ return c.json({ error: err.message || "Failed to list context sources" }, 500);
50498
+ }
50499
+ });
50422
50500
  memoryRoutes.get("/memory", async (c) => {
50423
50501
  const userId = requireUserId(c.req.query("userId"));
50424
50502
  if (!userId) return c.json({ error: "userId is required" }, 400);
50425
50503
  try {
50426
50504
  const { memoryEngine } = getSharedDeps();
50505
+ const scopeUserIds = await collectMemoryScopeUserIds(userId);
50427
50506
  const memories = (await Promise.all(
50428
- collectMemoryScopeUserIds(userId).map((scopeUserId) => memoryEngine.list(scopeUserId))
50507
+ scopeUserIds.map((scopeUserId) => memoryEngine.list(scopeUserId))
50429
50508
  )).flat();
50430
50509
  return c.json(sortMemories(memories));
50431
50510
  } catch (err) {
@@ -50489,7 +50568,8 @@ memoryRoutes.get("/memory/dream", async (c) => {
50489
50568
  if (!userId) return c.json({ error: "userId is required" }, 400);
50490
50569
  try {
50491
50570
  const { dreamStorage, dreamHistoryStorage, dreamStateStorage } = getSharedDeps();
50492
- const scoped = await Promise.all(collectMemoryScopeUserIds(userId).map(async (scopeUserId) => {
50571
+ const scopeUserIds = await collectMemoryScopeUserIds(userId);
50572
+ const scoped = await Promise.all(scopeUserIds.map(async (scopeUserId) => {
50493
50573
  const [dreamContent2, dreamHistory2, state2] = await Promise.all([
50494
50574
  dreamStorage.get(`dream:latest:${scopeUserId}`),
50495
50575
  dreamHistoryStorage.get(`dream:history:${scopeUserId}`),
@@ -50520,7 +50600,7 @@ memoryRoutes.get("/memory/compact", async (c) => {
50520
50600
  if (!userId) return c.json({ error: "userId is required" }, 400);
50521
50601
  try {
50522
50602
  const summaries = (await Promise.all(
50523
- collectMemoryScopeUserIds(userId).map((scopeUserId) => collectCompactSummaries(scopeUserId))
50603
+ (await collectMemoryScopeUserIds(userId)).map((scopeUserId) => collectCompactSummaries(scopeUserId))
50524
50604
  )).flat().sort((a, b) => b.createdAt - a.createdAt);
50525
50605
  return c.json({
50526
50606
  userId,
@@ -50538,7 +50618,7 @@ memoryRoutes.get("/memory/recall", async (c) => {
50538
50618
  const limit = Math.min(Number(c.req.query("limit")) || 20, 50);
50539
50619
  try {
50540
50620
  const { recallIndexStorage } = getSharedDeps();
50541
- const scopeUserIds = collectMemoryScopeUserIds(userId);
50621
+ const scopeUserIds = await collectMemoryScopeUserIds(userId);
50542
50622
  if (query) {
50543
50623
  const scopedResults = await Promise.all(scopeUserIds.map(
50544
50624
  (scopeUserId) => searchRecallIndex(recallIndexStorage, scopeUserId, query, date, limit)
@@ -50574,7 +50654,8 @@ memoryRoutes.get("/memory/context", async (c) => {
50574
50654
  if (!userId) return c.json({ error: "userId is required" }, 400);
50575
50655
  try {
50576
50656
  const { memoryEngine, dreamStorage } = getSharedDeps();
50577
- const scoped = await Promise.all(collectMemoryScopeUserIds(userId).map(async (scopeUserId) => {
50657
+ const scopeUserIds = await collectMemoryScopeUserIds(userId);
50658
+ const scoped = await Promise.all(scopeUserIds.map(async (scopeUserId) => {
50578
50659
  const [memoryContextBlock2, dreamContent2] = await Promise.all([
50579
50660
  memoryEngine.buildContextBlock(scopeUserId),
50580
50661
  dreamStorage.get(`dream:latest:${scopeUserId}`)
@@ -50658,7 +50739,7 @@ var systemRoutes = new Hono2();
50658
50739
  var startTime = Date.now();
50659
50740
  systemRoutes.get("/system/info", (c) => {
50660
50741
  return c.json({
50661
- version: true ? "1.8.3" : "unknown",
50742
+ version: true ? "1.8.5" : "unknown",
50662
50743
  uptime: Math.floor((Date.now() - startTime) / 1e3),
50663
50744
  env: process.env.NODE_ENV || "development",
50664
50745
  nodeVersion: process.version