openclaw-telegram-manager 2.6.2 → 2.7.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 (49) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/archive.d.ts.map +1 -1
  3. package/dist/commands/archive.js +33 -0
  4. package/dist/commands/archive.js.map +1 -1
  5. package/dist/commands/daily-report.d.ts +0 -3
  6. package/dist/commands/daily-report.d.ts.map +1 -1
  7. package/dist/commands/daily-report.js +8 -49
  8. package/dist/commands/daily-report.js.map +1 -1
  9. package/dist/commands/doctor-all.d.ts +0 -3
  10. package/dist/commands/doctor-all.d.ts.map +1 -1
  11. package/dist/commands/doctor-all.js +4 -81
  12. package/dist/commands/doctor-all.js.map +1 -1
  13. package/dist/commands/init.d.ts.map +1 -1
  14. package/dist/commands/init.js +23 -0
  15. package/dist/commands/init.js.map +1 -1
  16. package/dist/commands/status.d.ts +9 -1
  17. package/dist/commands/status.d.ts.map +1 -1
  18. package/dist/commands/status.js +45 -25
  19. package/dist/commands/status.js.map +1 -1
  20. package/dist/commands/sync.js +9 -8
  21. package/dist/commands/sync.js.map +1 -1
  22. package/dist/lib/config-restart.d.ts.map +1 -1
  23. package/dist/lib/config-restart.js +3 -3
  24. package/dist/lib/config-restart.js.map +1 -1
  25. package/dist/lib/cron.d.ts +32 -0
  26. package/dist/lib/cron.d.ts.map +1 -0
  27. package/dist/lib/cron.js +84 -0
  28. package/dist/lib/cron.js.map +1 -0
  29. package/dist/lib/doctor-checks.d.ts +4 -0
  30. package/dist/lib/doctor-checks.d.ts.map +1 -1
  31. package/dist/lib/doctor-checks.js +13 -0
  32. package/dist/lib/doctor-checks.js.map +1 -1
  33. package/dist/lib/registry.d.ts.map +1 -1
  34. package/dist/lib/registry.js +11 -0
  35. package/dist/lib/registry.js.map +1 -1
  36. package/dist/lib/telegram.d.ts +1 -3
  37. package/dist/lib/telegram.d.ts.map +1 -1
  38. package/dist/lib/telegram.js +6 -19
  39. package/dist/lib/telegram.js.map +1 -1
  40. package/dist/lib/types.d.ts +3 -1
  41. package/dist/lib/types.d.ts.map +1 -1
  42. package/dist/lib/types.js +2 -1
  43. package/dist/lib/types.js.map +1 -1
  44. package/dist/plugin.js +199 -164
  45. package/dist/setup.js +1 -1
  46. package/dist/tool.js +1 -1
  47. package/dist/tool.js.map +1 -1
  48. package/package.json +1 -1
  49. package/skills/tm/SKILL.md +3 -2
package/dist/plugin.js CHANGED
@@ -8815,7 +8815,7 @@ __export(value_exports2, {
8815
8815
  });
8816
8816
 
8817
8817
  // src/lib/types.ts
8818
- var CURRENT_REGISTRY_VERSION = 5;
8818
+ var CURRENT_REGISTRY_VERSION = 6;
8819
8819
  var CAPSULE_VERSION = 3;
8820
8820
  var MAX_POST_ERROR_LENGTH = 500;
8821
8821
  var MAX_NAME_LENGTH = 100;
@@ -8855,6 +8855,7 @@ var TopicEntrySchema = Type.Object({
8855
8855
  snoozeUntil: Type.Union([Type.String(), Type.Null()]),
8856
8856
  consecutiveSilentDoctors: Type.Integer({ minimum: 0 }),
8857
8857
  lastPostError: Type.Union([Type.String({ maxLength: MAX_POST_ERROR_LENGTH }), Type.Null()]),
8858
+ cronJobId: Type.Union([Type.String(), Type.Null()]),
8858
8859
  extras: Type.Record(Type.String(), Type.Unknown())
8859
8860
  });
8860
8861
  var RegistrySchema = Type.Object({
@@ -8942,6 +8943,17 @@ var migrations = {
8942
8943
  }
8943
8944
  }
8944
8945
  return data;
8946
+ },
8947
+ "5_to_6": (data) => {
8948
+ const topics = data["topics"];
8949
+ if (topics && typeof topics === "object" && !Array.isArray(topics)) {
8950
+ for (const entry of Object.values(topics)) {
8951
+ if (entry["cronJobId"] === void 0) {
8952
+ entry["cronJobId"] = null;
8953
+ }
8954
+ }
8955
+ }
8956
+ return data;
8945
8957
  }
8946
8958
  };
8947
8959
  function migrateRegistry(data) {
@@ -9341,39 +9353,22 @@ function checkAuthorization(userId, command, registry, topicAllowFrom) {
9341
9353
 
9342
9354
  // src/lib/telegram.ts
9343
9355
  var TELEGRAM_MSG_LIMIT = 4096;
9344
- var HEALTH_LABELS = {
9345
- fresh: "\u2705 Active",
9346
- // green check
9347
- stale: "\u23F3 Inactive",
9348
- // hourglass
9349
- blocked: "\u26A0\uFE0F Blocked"
9350
- // warning
9351
- };
9352
9356
  function buildDailyReport(data, format = "html") {
9353
9357
  const isHtml = format === "html";
9354
9358
  const esc = (s) => isHtml ? htmlEscape(s) : s;
9355
9359
  const bold = (s) => isHtml ? `<b>${s}</b>` : `**${s}**`;
9356
9360
  const n = esc(data.name);
9357
- const healthLabel = HEALTH_LABELS[data.health] ?? data.health;
9358
9361
  const lines = [
9359
9362
  bold(`Daily Report: ${n}`),
9360
9363
  "",
9361
- bold("Done today"),
9364
+ bold("Done"),
9362
9365
  esc(data.doneContent),
9363
9366
  "",
9364
- bold("New learnings"),
9365
- esc(data.learningsContent),
9366
- "",
9367
- bold("Blockers/Risks"),
9368
- esc(data.blockersContent),
9369
- "",
9370
- bold("Next actions (now)"),
9367
+ bold("Next"),
9371
9368
  esc(data.nextContent),
9372
9369
  "",
9373
- bold("Upcoming"),
9374
- esc(data.upcomingContent),
9375
- "",
9376
- `${bold("Health:")} ${healthLabel}`
9370
+ bold("Blockers"),
9371
+ esc(data.blockersContent)
9377
9372
  ];
9378
9373
  return truncateMessage(lines.join("\n"));
9379
9374
  }
@@ -9522,7 +9517,7 @@ function buildHelpCard() {
9522
9517
  "",
9523
9518
  "**Basics**",
9524
9519
  "/tm init \u2014 set up this topic",
9525
- "/tm status \u2014 see current progress",
9520
+ "/tm status \u2014 see current progress (add --expanded for more detail)",
9526
9521
  "/tm list \u2014 all topics",
9527
9522
  "/tm help \u2014 this message",
9528
9523
  "",
@@ -9802,7 +9797,7 @@ async function triggerRestart(rpc, logger) {
9802
9797
  if (!rpc) {
9803
9798
  return {
9804
9799
  success: false,
9805
- fallbackMessage: "Config updated. Run `openclaw gateway restart` or send SIGUSR1 to apply."
9800
+ fallbackMessage: "Restart the gateway to apply changes."
9806
9801
  };
9807
9802
  }
9808
9803
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
@@ -9844,13 +9839,13 @@ async function triggerRestart(rpc, logger) {
9844
9839
  logger.error(`config.patch failed after ${attempt + 1} attempt(s): ${errMsg}`);
9845
9840
  return {
9846
9841
  success: false,
9847
- fallbackMessage: "Config updated. Run `openclaw gateway restart` or send SIGUSR1 to apply."
9842
+ fallbackMessage: "Restart the gateway to apply changes."
9848
9843
  };
9849
9844
  }
9850
9845
  }
9851
9846
  return {
9852
9847
  success: false,
9853
- fallbackMessage: "Config updated. Run `openclaw gateway restart` or send SIGUSR1 to apply."
9848
+ fallbackMessage: "Restart the gateway to apply changes."
9854
9849
  };
9855
9850
  }
9856
9851
  function isHashMismatchError(err) {
@@ -9881,6 +9876,67 @@ async function getConfigWrites(rpc) {
9881
9876
  }
9882
9877
  }
9883
9878
 
9879
+ // src/lib/cron.ts
9880
+ var DEFAULT_CRON_SCHEDULE = "0 9 * * *";
9881
+ var DEFAULT_CRON_TZ = "UTC";
9882
+ async function registerDailyReportCron(rpc, params, logger) {
9883
+ if (!rpc) {
9884
+ return { jobId: null, error: "RPC not available" };
9885
+ }
9886
+ const { topicName, slug, groupId, threadId, schedule, tz } = params;
9887
+ const cronExpr = schedule ?? DEFAULT_CRON_SCHEDULE;
9888
+ const timezone = tz ?? DEFAULT_CRON_TZ;
9889
+ const telegramTarget = `${groupId}:topic:${threadId}`;
9890
+ try {
9891
+ const result = await rpc.call("cron.add", {
9892
+ name: `tm-daily-${slug}`,
9893
+ schedule: {
9894
+ kind: "cron",
9895
+ expr: cronExpr,
9896
+ tz: timezone
9897
+ },
9898
+ sessionTarget: "isolated",
9899
+ wakeMode: "now",
9900
+ payload: {
9901
+ kind: "agentTurn",
9902
+ message: `Run topic_manager with command "daily-report" for the topic "${topicName}" (slug: ${slug}, group: ${groupId}, thread: ${threadId}). Post the report to this topic.`
9903
+ },
9904
+ delivery: {
9905
+ mode: "announce",
9906
+ channels: {
9907
+ telegram: {
9908
+ to: telegramTarget
9909
+ }
9910
+ }
9911
+ }
9912
+ });
9913
+ const jobId = result["jobId"] ?? result["id"] ?? null;
9914
+ if (jobId) {
9915
+ logger.info(`[cron] Created daily report job "${jobId}" for ${slug} (${cronExpr} ${timezone})`);
9916
+ return { jobId };
9917
+ }
9918
+ return { jobId: null, error: "Gateway did not return a job ID" };
9919
+ } catch (err) {
9920
+ const msg = err instanceof Error ? err.message : String(err);
9921
+ logger.error(`[cron] Failed to create daily report job for ${slug}: ${msg}`);
9922
+ return { jobId: null, error: msg };
9923
+ }
9924
+ }
9925
+ async function removeCronJob(rpc, jobId, logger) {
9926
+ if (!rpc) {
9927
+ return false;
9928
+ }
9929
+ try {
9930
+ await rpc.call("cron.remove", { jobId });
9931
+ logger.info(`[cron] Removed cron job "${jobId}"`);
9932
+ return true;
9933
+ } catch (err) {
9934
+ const msg = err instanceof Error ? err.message : String(err);
9935
+ logger.error(`[cron] Failed to remove cron job "${jobId}": ${msg}`);
9936
+ return false;
9937
+ }
9938
+ }
9939
+
9884
9940
  // src/commands/autopilot.ts
9885
9941
  import * as fs6 from "node:fs";
9886
9942
  import * as path6 from "node:path";
@@ -10085,6 +10141,7 @@ async function handleInit(ctx, args) {
10085
10141
  snoozeUntil: null,
10086
10142
  consecutiveSilentDoctors: 0,
10087
10143
  lastPostError: null,
10144
+ cronJobId: null,
10088
10145
  extras: {}
10089
10146
  };
10090
10147
  data.topics[key] = newEntry;
@@ -10133,6 +10190,25 @@ async function handleInit(ctx, args) {
10133
10190
  restartMsg = `
10134
10191
  Warning: config sync failed: ${msg}`;
10135
10192
  }
10193
+ try {
10194
+ const cronResult = await registerDailyReportCron(rpc, {
10195
+ topicName: name,
10196
+ slug: finalSlug,
10197
+ groupId,
10198
+ threadId
10199
+ }, logger);
10200
+ if (cronResult.jobId) {
10201
+ await withRegistry(workspaceDir, (data) => {
10202
+ const entry = data.topics[key];
10203
+ if (entry) {
10204
+ entry.cronJobId = cronResult.jobId;
10205
+ }
10206
+ });
10207
+ }
10208
+ } catch (err) {
10209
+ const msg = err instanceof Error ? err.message : String(err);
10210
+ logger.error(`[init] Cron registration failed: ${msg}`);
10211
+ }
10136
10212
  appendAudit(
10137
10213
  workspaceDir,
10138
10214
  buildAuditEntry(userId, "init", finalSlug, `Initialized topic name="${name}" type=${topicType} group=${groupId} thread=${threadId}`)
@@ -10543,10 +10619,26 @@ function runSpamControlCheck(entry) {
10543
10619
  }
10544
10620
  return results;
10545
10621
  }
10622
+ function runPostErrorCheck(entry) {
10623
+ const results = [];
10624
+ if (entry.lastPostError) {
10625
+ results.push(
10626
+ check(
10627
+ Severity.WARN,
10628
+ "lastPostFailed",
10629
+ `Last report delivery failed: ${entry.lastPostError}`,
10630
+ false,
10631
+ "This will be retried on the next health check cycle"
10632
+ )
10633
+ );
10634
+ }
10635
+ return results;
10636
+ }
10546
10637
  function runAllChecksForTopic(entry, projectsBase, includeContent, registry, cronJobsPath) {
10547
10638
  const results = [];
10548
10639
  const capsuleDir = path8.join(projectsBase, entry.slug);
10549
10640
  results.push(...runRegistryChecks(entry, projectsBase));
10641
+ results.push(...runPostErrorCheck(entry));
10550
10642
  if (!fs8.existsSync(capsuleDir)) return results;
10551
10643
  results.push(...runCapsuleChecks(entry, projectsBase));
10552
10644
  const capsuleFiles = readCapsuleFiles(capsuleDir);
@@ -10712,21 +10804,14 @@ async function handleDailyReport(ctx) {
10712
10804
  }
10713
10805
  const statusContent = readFileOrNull(path10.join(capsuleDir, "STATUS.md"));
10714
10806
  const todoContent = readFileOrNull(path10.join(capsuleDir, "TODO.md"));
10715
- const learningsContent = readFileOrNull(path10.join(capsuleDir, "LEARNINGS.md"));
10716
10807
  const doneContent = extractDoneSection(statusContent);
10717
- const newLearnings = extractTodayLearnings(learningsContent);
10718
10808
  const blockers = extractBlockers(todoContent);
10719
10809
  const nextContent = extractNextActions(statusContent);
10720
- const upcomingContent = extractUpcoming(statusContent);
10721
- const health = computeHealth(entry.lastMessageAt, statusContent, blockers);
10722
10810
  const reportData = {
10723
10811
  name: entry.name,
10724
10812
  doneContent,
10725
- learningsContent: newLearnings,
10726
10813
  blockersContent: blockers,
10727
- nextContent,
10728
- upcomingContent,
10729
- health
10814
+ nextContent
10730
10815
  };
10731
10816
  if (ctx.postFn) {
10732
10817
  try {
@@ -10736,11 +10821,18 @@ async function handleDailyReport(ctx) {
10736
10821
  const e = data.topics[key];
10737
10822
  if (e) {
10738
10823
  e.lastDailyReportAt = (/* @__PURE__ */ new Date()).toISOString();
10824
+ e.lastPostError = null;
10739
10825
  }
10740
10826
  });
10741
10827
  } catch (err) {
10742
10828
  const msg = err instanceof Error ? err.message : String(err);
10743
10829
  logger.error(`[daily-report] Post failed: ${msg}`);
10830
+ await withRegistry(workspaceDir, (data) => {
10831
+ const e = data.topics[key];
10832
+ if (e) {
10833
+ e.lastPostError = msg.slice(0, MAX_POST_ERROR_LENGTH);
10834
+ }
10835
+ });
10744
10836
  return { text: `Daily report generated but post failed: ${msg}` };
10745
10837
  }
10746
10838
  } else {
@@ -10767,26 +10859,6 @@ function extractDoneSection(statusContent) {
10767
10859
  const text = match[1]?.trim();
10768
10860
  return text || "Empty.";
10769
10861
  }
10770
- function extractTodayLearnings(learningsContent) {
10771
- if (!learningsContent) return "No learnings recorded yet.";
10772
- const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
10773
- const lines = learningsContent.split("\n");
10774
- const todayLines = [];
10775
- let inTodaySection = false;
10776
- for (const line of lines) {
10777
- if (line.startsWith("## ") && line.includes(today)) {
10778
- inTodaySection = true;
10779
- continue;
10780
- }
10781
- if (inTodaySection && line.startsWith("## ")) {
10782
- break;
10783
- }
10784
- if (inTodaySection && line.trim()) {
10785
- todayLines.push(line);
10786
- }
10787
- }
10788
- return todayLines.length > 0 ? todayLines.join("\n") : "None today.";
10789
- }
10790
10862
  function extractBlockers(todoContent) {
10791
10863
  if (!todoContent) return "No tasks recorded yet.";
10792
10864
  const lines = todoContent.split("\n");
@@ -10802,22 +10874,6 @@ function extractNextActions(statusContent) {
10802
10874
  const text = match[1]?.trim();
10803
10875
  return text || "None yet.";
10804
10876
  }
10805
- function extractUpcoming(statusContent) {
10806
- if (!statusContent) return "No status available yet.";
10807
- const match = statusContent.match(/^##\s*Upcoming actions\s*\n([\s\S]*?)(?=\n##\s|\n*$)/im);
10808
- if (!match) return "None yet.";
10809
- const text = match[1]?.trim();
10810
- return text || "None yet.";
10811
- }
10812
- function computeHealth(lastMessageAt, statusContent, blockers) {
10813
- if (blockers && blockers !== "None." && blockers !== "No tasks recorded yet.") {
10814
- return "blocked";
10815
- }
10816
- if (!lastMessageAt) return "stale";
10817
- const hoursSinceActivity = (Date.now() - new Date(lastMessageAt).getTime()) / 36e5;
10818
- if (hoursSinceActivity > 72) return "stale";
10819
- return "fresh";
10820
- }
10821
10877
 
10822
10878
  // src/commands/doctor-all.ts
10823
10879
  function getEligibility(entry, now, statusTimestamp) {
@@ -10863,9 +10919,6 @@ function buildDoctorAllSummary(data) {
10863
10919
  checkedTopics,
10864
10920
  skippedTopics,
10865
10921
  postFailures,
10866
- dailyReportsSent,
10867
- dailyReportsSkipped,
10868
- hasPostFn,
10869
10922
  migrationGroups,
10870
10923
  errors
10871
10924
  } = data;
@@ -10921,15 +10974,6 @@ function buildDoctorAllSummary(data) {
10921
10974
  lines.push("");
10922
10975
  lines.push(`\u26A0\uFE0F ${postFailures} topic(s) failed to post`);
10923
10976
  }
10924
- if (hasPostFn) {
10925
- const parts = [];
10926
- if (dailyReportsSent > 0) parts.push(`${dailyReportsSent} sent`);
10927
- if (dailyReportsSkipped > 0) parts.push(`${dailyReportsSkipped} skipped`);
10928
- if (parts.length > 0) {
10929
- lines.push("");
10930
- lines.push(`Daily reports: ${parts.join(", ")}`);
10931
- }
10932
- }
10933
10977
  if (migrationGroups > 0) {
10934
10978
  lines.push("");
10935
10979
  lines.push(`**Warning:** ${migrationGroups} group(s) had all topics fail. The group may have been migrated or deleted.`);
@@ -11082,54 +11126,6 @@ async function handleDoctorAll(ctx) {
11082
11126
  }
11083
11127
  }
11084
11128
  }
11085
- let dailyReportSuccesses = 0;
11086
- let dailyReportSkipped = 0;
11087
- const dailyReportKeys = /* @__PURE__ */ new Set();
11088
- if (ctx.postFn && reports.length > 0) {
11089
- const rateLimitedPost = createRateLimitedPoster(ctx.postFn);
11090
- const nowDate = now.toISOString().slice(0, 10);
11091
- for (const report of reports) {
11092
- const key = `${report.groupId}:${report.threadId}`;
11093
- const entry = registry.topics[key];
11094
- if (!entry) continue;
11095
- if (entry.lastDailyReportAt) {
11096
- const lastReport = new Date(entry.lastDailyReportAt);
11097
- const lastDate = `${lastReport.getUTCFullYear()}-${String(lastReport.getUTCMonth() + 1).padStart(2, "0")}-${String(lastReport.getUTCDate()).padStart(2, "0")}`;
11098
- if (lastDate === nowDate) {
11099
- dailyReportSkipped++;
11100
- continue;
11101
- }
11102
- }
11103
- const capsuleDir = path11.join(projectsBase, entry.slug);
11104
- const statusContent = readFileOrNull(path11.join(capsuleDir, "STATUS.md"));
11105
- const todoContent = readFileOrNull(path11.join(capsuleDir, "TODO.md"));
11106
- const learningsContent = readFileOrNull(path11.join(capsuleDir, "LEARNINGS.md"));
11107
- const doneContent = extractDoneSection(statusContent);
11108
- const newLearnings = extractTodayLearnings(learningsContent);
11109
- const blockers = extractBlockers(todoContent);
11110
- const nextContent = extractNextActions(statusContent);
11111
- const upcomingContent = extractUpcoming(statusContent);
11112
- const health = computeHealth(entry.lastMessageAt, statusContent, blockers);
11113
- const reportData = {
11114
- name: entry.name,
11115
- doneContent,
11116
- learningsContent: newLearnings,
11117
- blockersContent: blockers,
11118
- nextContent,
11119
- upcomingContent,
11120
- health
11121
- };
11122
- try {
11123
- const htmlReport = buildDailyReport(reportData, "html");
11124
- await rateLimitedPost(report.groupId, report.threadId, htmlReport);
11125
- dailyReportSuccesses++;
11126
- dailyReportKeys.add(key);
11127
- } catch (err) {
11128
- const msg = err instanceof Error ? err.message : String(err);
11129
- logger.error(`[doctor-all] Daily report post failed for ${entry.slug}: ${msg}`);
11130
- }
11131
- }
11132
- }
11133
11129
  await withRegistry(workspaceDir, (data) => {
11134
11130
  data.lastDoctorAllRunAt = now.toISOString();
11135
11131
  for (const [_key, entry] of Object.entries(data.topics)) {
@@ -11155,21 +11151,12 @@ async function handleDoctorAll(ctx) {
11155
11151
  entry.consecutiveSilentDoctors = 0;
11156
11152
  }
11157
11153
  }
11158
- for (const key of dailyReportKeys) {
11159
- const entry = data.topics[key];
11160
- if (entry) {
11161
- entry.lastDailyReportAt = now.toISOString();
11162
- }
11163
- }
11164
11154
  });
11165
11155
  return {
11166
11156
  text: buildDoctorAllSummary({
11167
11157
  checkedTopics,
11168
11158
  skippedTopics,
11169
11159
  postFailures,
11170
- dailyReportsSent: dailyReportSuccesses,
11171
- dailyReportsSkipped: dailyReportSkipped,
11172
- hasPostFn: !!ctx.postFn,
11173
11160
  migrationGroups: migrationGroups.length,
11174
11161
  errors
11175
11162
  })
@@ -11253,38 +11240,49 @@ function formatSection(raw) {
11253
11240
  if (isPlaceholder(raw)) return "_None yet._";
11254
11241
  return raw;
11255
11242
  }
11256
- function formatStatus(name, content) {
11257
- const timestamp = extractTimestamp(content);
11258
- const nextRaw = extractSection(content, NEXT_ACTIONS_RE2);
11259
- const upcomingRaw = extractSection(content, UPCOMING_RE);
11260
- const doneMatch = content.match(LAST_DONE_RE2);
11243
+ function hasBlockers(blockers) {
11244
+ return blockers !== "None." && blockers !== "No tasks recorded yet.";
11245
+ }
11246
+ function formatStatus(data) {
11247
+ const { name, type, statusContent, todoContent, expanded } = data;
11248
+ const timestamp = extractTimestamp(statusContent);
11249
+ const nextRaw = extractSection(statusContent, NEXT_ACTIONS_RE2);
11250
+ const blockers = extractBlockers(todoContent);
11251
+ const doneMatch = statusContent.match(LAST_DONE_RE2);
11261
11252
  let lastDoneBody = "";
11262
11253
  if (doneMatch) {
11263
11254
  const section = doneMatch[1]?.trim() ?? "";
11264
11255
  lastDoneBody = section.replace(ISO_RE, "").trim();
11265
11256
  }
11266
- const lines = [
11267
- `**${name}**`,
11268
- ""
11269
- ];
11257
+ const lines = [];
11258
+ lines.push(`**${name}** \xB7 ${type}`);
11270
11259
  if (timestamp) {
11271
11260
  lines.push(`\u{1F552} **Last activity:** ${relativeTime(timestamp)}`);
11272
11261
  }
11262
+ lines.push("");
11273
11263
  if (lastDoneBody && !isPlaceholder(lastDoneBody)) {
11264
+ lines.push("\u2705 **Done recently**");
11274
11265
  lines.push(lastDoneBody);
11266
+ lines.push("");
11275
11267
  }
11276
- lines.push("");
11277
11268
  lines.push("\u{1F3AF} **Next actions**");
11278
11269
  lines.push(formatSection(nextRaw));
11279
- const upcomingFormatted = formatSection(upcomingRaw);
11280
- if (upcomingFormatted !== "_None yet._") {
11270
+ if (hasBlockers(blockers)) {
11281
11271
  lines.push("");
11282
- lines.push("\u{1F4C5} **Upcoming**");
11283
- lines.push(upcomingFormatted);
11272
+ lines.push("\u26A0\uFE0F **Blockers**");
11273
+ lines.push(blockers);
11274
+ }
11275
+ if (expanded) {
11276
+ const upcomingRaw = extractSection(statusContent, UPCOMING_RE);
11277
+ if (!isPlaceholder(upcomingRaw)) {
11278
+ lines.push("");
11279
+ lines.push("\u{1F4C5} **Upcoming**");
11280
+ lines.push(upcomingRaw);
11281
+ }
11284
11282
  }
11285
11283
  return lines.join("\n");
11286
11284
  }
11287
- async function handleStatus2(ctx) {
11285
+ async function handleStatus2(ctx, args) {
11288
11286
  const { workspaceDir, userId, groupId, threadId } = ctx;
11289
11287
  if (!userId || !groupId || !threadId) {
11290
11288
  return { text: "Something went wrong \u2014 this command must be run inside a Telegram forum topic." };
@@ -11311,10 +11309,18 @@ async function handleStatus2(ctx) {
11311
11309
  if (!fs12.existsSync(statusPath)) {
11312
11310
  return { text: "No status available yet. Run /tm doctor to diagnose." };
11313
11311
  }
11312
+ const expanded = args.trim() === "--expanded";
11314
11313
  try {
11315
- const content = fs12.readFileSync(statusPath, "utf-8");
11314
+ const statusContent = fs12.readFileSync(statusPath, "utf-8");
11315
+ const todoContent = readFileOrNull(path12.join(capsuleDir, "TODO.md"));
11316
11316
  return {
11317
- text: truncateMessage(formatStatus(entry.name, content))
11317
+ text: truncateMessage(formatStatus({
11318
+ name: entry.name,
11319
+ type: entry.type,
11320
+ statusContent,
11321
+ todoContent,
11322
+ expanded
11323
+ }))
11318
11324
  };
11319
11325
  } catch (err) {
11320
11326
  const msg = err instanceof Error ? err.message : String(err);
@@ -11341,15 +11347,15 @@ async function handleSync(ctx) {
11341
11347
  text: `Sync failed: ${msg}`
11342
11348
  };
11343
11349
  }
11344
- const restartResult = await triggerRestart(rpc, logger);
11345
11350
  const topicCount = Object.keys(registry.topics).length;
11346
- let text = `Config synced for ${topicCount} topic(s).`;
11347
- if (!restartResult.success && restartResult.fallbackMessage) {
11348
- text += "\n" + restartResult.fallbackMessage;
11351
+ const configWritesEnabled = await getConfigWrites(rpc);
11352
+ if (configWritesEnabled) {
11353
+ const restartResult = await triggerRestart(rpc, logger);
11354
+ if (restartResult.success) {
11355
+ return { text: `All synced \u2014 config updated for ${topicCount} topic(s) and changes are live.` };
11356
+ }
11349
11357
  }
11350
- return {
11351
- text
11352
- };
11358
+ return { text: `Config synced for ${topicCount} topic(s). Restart the gateway to apply changes.` };
11353
11359
  }
11354
11360
 
11355
11361
  // src/commands/rename.ts
@@ -11539,6 +11545,35 @@ async function handleArchiveToggle(ctx, archive) {
11539
11545
  }
11540
11546
  }
11541
11547
  });
11548
+ if (archive && entry.cronJobId) {
11549
+ await removeCronJob(rpc, entry.cronJobId, logger);
11550
+ await withRegistry(workspaceDir, (data) => {
11551
+ const topic = data.topics[key];
11552
+ if (topic) {
11553
+ topic.cronJobId = null;
11554
+ }
11555
+ });
11556
+ } else if (!archive && !entry.cronJobId) {
11557
+ try {
11558
+ const cronResult = await registerDailyReportCron(rpc, {
11559
+ topicName: entry.name,
11560
+ slug: entry.slug,
11561
+ groupId,
11562
+ threadId
11563
+ }, logger);
11564
+ if (cronResult.jobId) {
11565
+ await withRegistry(workspaceDir, (data) => {
11566
+ const topic = data.topics[key];
11567
+ if (topic) {
11568
+ topic.cronJobId = cronResult.jobId;
11569
+ }
11570
+ });
11571
+ }
11572
+ } catch (err) {
11573
+ const msg = err instanceof Error ? err.message : String(err);
11574
+ logger.error(`[archive] Cron re-registration failed: ${msg}`);
11575
+ }
11576
+ }
11542
11577
  let restartMsg = "";
11543
11578
  try {
11544
11579
  const updatedRegistry = readRegistry(workspaceDir);
@@ -11620,7 +11655,7 @@ function createTopicManagerTool(deps) {
11620
11655
  case "list":
11621
11656
  return await handleList(ctx);
11622
11657
  case "status":
11623
- return await handleStatus2(ctx);
11658
+ return await handleStatus2(ctx, args);
11624
11659
  case "sync":
11625
11660
  return await handleSync(ctx);
11626
11661
  case "rename":
package/dist/setup.js CHANGED
@@ -1156,7 +1156,7 @@ var PLUGIN_FILES = ["openclaw.plugin.json", "dist/plugin.js", "skills", "package
1156
1156
  var REQUIRED_PLUGIN_FILES = ["openclaw.plugin.json", "dist/plugin.js"];
1157
1157
  var FLUSH_TAG = "[tm]";
1158
1158
  var FLUSH_FINGERPRINTS = [FLUSH_TAG, "STATUS.md"];
1159
- var SETUP_REGISTRY_VERSION = 5;
1159
+ var SETUP_REGISTRY_VERSION = 6;
1160
1160
  var MEMORY_FLUSH_INSTRUCTION = `If you are working on a Telegram topic folder (projects/<slug>/), update its STATUS.md with current "Last done (UTC)" and "Next actions (now)" before this context is compacted. ${FLUSH_TAG}`;
1161
1161
  var SETUP_MARKER_START = "<!-- TM_AUTOPILOT_START -->";
1162
1162
  var SETUP_MARKER_END = "<!-- TM_AUTOPILOT_END -->";
package/dist/tool.js CHANGED
@@ -72,7 +72,7 @@ export function createTopicManagerTool(deps) {
72
72
  case 'list':
73
73
  return await handleList(ctx);
74
74
  case 'status':
75
- return await handleStatus(ctx);
75
+ return await handleStatus(ctx, args);
76
76
  case 'sync':
77
77
  return await handleSync(ctx);
78
78
  case 'rename':
package/dist/tool.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-telegram-manager",
3
- "version": "2.6.2",
3
+ "version": "2.7.0",
4
4
  "type": "module",
5
5
  "description": "Deterministic Telegram forum topic management for OpenClaw",
6
6
  "keywords": [
@@ -28,8 +28,9 @@ If you detect any of these conditions, invoke `topic_manager` proactively:
28
28
 
29
29
  Autopilot is enabled by default on setup and first-user init. The OpenClaw
30
30
  heartbeat triggers `doctor --all` roughly once per hour, which health-checks
31
- all active topics and posts a daily progress report (one per UTC day).
32
- No manual intervention is needed. Users can disable with `/tm autopilot disable`.
31
+ all active topics. Daily progress reports are posted by per-topic cron jobs
32
+ (registered on init, default 09:00 UTC). No manual intervention is needed.
33
+ Users can disable with `/tm autopilot disable`.
33
34
 
34
35
  ## Callback routing
35
36