openclaw-telegram-manager 2.9.0 → 2.11.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/README.md +3 -2
- package/dist/commands/archive.d.ts.map +1 -1
- package/dist/commands/archive.js +0 -33
- package/dist/commands/archive.js.map +1 -1
- package/dist/commands/autopilot.d.ts +11 -1
- package/dist/commands/autopilot.d.ts.map +1 -1
- package/dist/commands/autopilot.js +70 -11
- package/dist/commands/autopilot.js.map +1 -1
- package/dist/commands/daily-report-all.d.ts +28 -0
- package/dist/commands/daily-report-all.d.ts.map +1 -0
- package/dist/commands/daily-report-all.js +255 -0
- package/dist/commands/daily-report-all.js.map +1 -0
- package/dist/commands/doctor-all.d.ts +1 -0
- package/dist/commands/doctor-all.d.ts.map +1 -1
- package/dist/commands/doctor-all.js +1 -1
- package/dist/commands/doctor-all.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +11 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +0 -22
- package/dist/commands/init.js.map +1 -1
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +2 -0
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/cron.d.ts +11 -0
- package/dist/lib/cron.d.ts.map +1 -1
- package/dist/lib/cron.js +40 -0
- package/dist/lib/cron.js.map +1 -1
- package/dist/lib/registry.d.ts.map +1 -1
- package/dist/lib/registry.js +7 -0
- package/dist/lib/registry.js.map +1 -1
- package/dist/lib/telegram.d.ts.map +1 -1
- package/dist/lib/telegram.js +3 -2
- package/dist/lib/telegram.js.map +1 -1
- package/dist/lib/types.d.ts +2 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +3 -2
- package/dist/lib/types.js.map +1 -1
- package/dist/plugin.js +706 -452
- package/dist/setup.js +49 -9
- package/dist/setup.js.map +1 -1
- package/dist/tool.d.ts.map +1 -1
- package/dist/tool.js +23 -0
- package/dist/tool.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,6 +84,7 @@ You don't need any of these — everything runs automatically. They're there if
|
|
|
84
84
|
| `/tm doctor` | Run health checks |
|
|
85
85
|
| `/tm doctor --all` | Health check all topics at once |
|
|
86
86
|
| `/tm daily-report` | Post a daily summary |
|
|
87
|
+
| `/tm daily-report --all` | Post daily summaries for all topics |
|
|
87
88
|
| `/tm list` | List all topics |
|
|
88
89
|
|
|
89
90
|
**Make changes**
|
|
@@ -107,7 +108,7 @@ You don't need any of these — everything runs automatically. They're there if
|
|
|
107
108
|
|
|
108
109
|
Two roles:
|
|
109
110
|
- **User** — can manage topics they have access to
|
|
110
|
-
- **Admin** — can run `doctor --all` and manage anyone's topics
|
|
111
|
+
- **Admin** — can run `doctor --all`, `daily-report --all`, and manage anyone's topics
|
|
111
112
|
|
|
112
113
|
The first person to run `/tm init` automatically becomes admin.
|
|
113
114
|
|
|
@@ -127,7 +128,7 @@ See [SECURITY.md](SECURITY.md) for reporting vulnerabilities.
|
|
|
127
128
|
npx openclaw-telegram-manager uninstall
|
|
128
129
|
```
|
|
129
130
|
|
|
130
|
-
This removes the plugin, the config reference, and the generated include file, then restarts the gateway. You'll be asked whether to delete your topic data. To skip the prompt and delete everything:
|
|
131
|
+
This removes any scheduled cron jobs, the plugin, the config reference, and the generated include file, then restarts the gateway. You'll be asked whether to delete your topic data. To skip the prompt and delete everything:
|
|
131
132
|
|
|
132
133
|
```bash
|
|
133
134
|
npx openclaw-telegram-manager uninstall --purge-data
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/commands/archive.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/commands/archive.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/D,wBAAsB,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAE/E;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAEjF"}
|
package/dist/commands/archive.js
CHANGED
|
@@ -4,7 +4,6 @@ import { topicKey } from '../lib/types.js';
|
|
|
4
4
|
import { appendAudit, buildAuditEntry } from '../lib/audit.js';
|
|
5
5
|
import { generateInclude } from '../lib/include-generator.js';
|
|
6
6
|
import { triggerRestart, getConfigWrites } from '../lib/config-restart.js';
|
|
7
|
-
import { removeCronJob, registerDailyReportCron } from '../lib/cron.js';
|
|
8
7
|
export async function handleArchive(ctx) {
|
|
9
8
|
return handleArchiveToggle(ctx, true);
|
|
10
9
|
}
|
|
@@ -44,38 +43,6 @@ async function handleArchiveToggle(ctx, archive) {
|
|
|
44
43
|
}
|
|
45
44
|
}
|
|
46
45
|
});
|
|
47
|
-
// Manage cron job: remove on archive, re-register on unarchive (non-critical)
|
|
48
|
-
if (archive && entry.cronJobId) {
|
|
49
|
-
await removeCronJob(rpc, entry.cronJobId, logger);
|
|
50
|
-
await withRegistry(workspaceDir, (data) => {
|
|
51
|
-
const topic = data.topics[key];
|
|
52
|
-
if (topic) {
|
|
53
|
-
topic.cronJobId = null;
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
else if (!archive && !entry.cronJobId) {
|
|
58
|
-
try {
|
|
59
|
-
const cronResult = await registerDailyReportCron(rpc, {
|
|
60
|
-
topicName: entry.name,
|
|
61
|
-
slug: entry.slug,
|
|
62
|
-
groupId,
|
|
63
|
-
threadId,
|
|
64
|
-
}, logger);
|
|
65
|
-
if (cronResult.jobId) {
|
|
66
|
-
await withRegistry(workspaceDir, (data) => {
|
|
67
|
-
const topic = data.topics[key];
|
|
68
|
-
if (topic) {
|
|
69
|
-
topic.cronJobId = cronResult.jobId;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
catch (err) {
|
|
75
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
76
|
-
logger.error(`[archive] Cron re-registration failed: ${msg}`);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
46
|
// Regenerate include file so config stays in sync
|
|
80
47
|
let restartMsg = '';
|
|
81
48
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/commands/archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/commands/archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import type { CommandContext, CommandResult } from './help.js';
|
|
2
2
|
export declare const MARKER_START = "<!-- TM_AUTOPILOT_START -->";
|
|
3
3
|
export declare const MARKER_END = "<!-- TM_AUTOPILOT_END -->";
|
|
4
|
-
export declare const HEARTBEAT_BLOCK = "<!-- TM_AUTOPILOT_START -->\n## Topic Manager \u2014 Balanced Autopilot\n\
|
|
4
|
+
export declare const HEARTBEAT_BLOCK = "<!-- TM_AUTOPILOT_START -->\n## Topic Manager \u2014 Balanced Autopilot\n\nDaily reports and health checks are handled by the cron scheduler.\nNo action needed here (HEARTBEAT_OK).\n<!-- TM_AUTOPILOT_END -->";
|
|
5
5
|
export declare const HEARTBEAT_FILENAME = "HEARTBEAT.md";
|
|
6
6
|
export declare function handleAutopilot(ctx: CommandContext, args: string): Promise<CommandResult>;
|
|
7
|
+
import type { RpcInterface, Logger } from '../lib/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Register the combined daily cron job if not already registered.
|
|
10
|
+
* Stores the job ID in the registry's `dailyReportCronJobId`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function ensureCombinedCron(workspaceDir: string, rpc: RpcInterface | null | undefined, logger: Logger): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Remove all per-topic cron jobs and clear their cronJobId fields.
|
|
15
|
+
*/
|
|
16
|
+
export declare function cleanupPerTopicCrons(workspaceDir: string, rpc: RpcInterface | null | undefined, logger: Logger): Promise<void>;
|
|
7
17
|
//# sourceMappingURL=autopilot.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autopilot.d.ts","sourceRoot":"","sources":["../../src/commands/autopilot.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"autopilot.d.ts","sourceRoot":"","sources":["../../src/commands/autopilot.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAI/D,eAAO,MAAM,YAAY,gCAAgC,CAAC;AAC1D,eAAO,MAAM,UAAU,8BAA8B,CAAC;AAEtD,eAAO,MAAM,eAAe,oNAKd,CAAC;AAEf,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AAIjD,wBAAsB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA0B/F;AAgID,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE5D;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,EACpC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAUf;AAmBD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,EACpC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -3,19 +3,15 @@ import * as path from 'node:path';
|
|
|
3
3
|
import { readRegistry, withRegistry } from '../lib/registry.js';
|
|
4
4
|
import { checkAuthorization } from '../lib/auth.js';
|
|
5
5
|
import { relativeTime } from '../lib/telegram.js';
|
|
6
|
+
import { registerCombinedCron, removeCronJob } from '../lib/cron.js';
|
|
6
7
|
// ── Marker constants ────────────────────────────────────────────────
|
|
7
8
|
export const MARKER_START = '<!-- TM_AUTOPILOT_START -->';
|
|
8
9
|
export const MARKER_END = '<!-- TM_AUTOPILOT_END -->';
|
|
9
10
|
export const HEARTBEAT_BLOCK = `${MARKER_START}
|
|
10
11
|
## Topic Manager — Balanced Autopilot
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
1. CALL \`topic_manager\` with command "doctor --all" to health-check all active topics.
|
|
15
|
-
This runs health checks AND posts daily progress reports for each eligible topic automatically.
|
|
16
|
-
2. For each topic where STATUS.md "Last done (UTC)" is >3 days old:
|
|
17
|
-
post a brief nudge in that topic asking the user for a status update.
|
|
18
|
-
3. If no actions were taken in steps 1-2, do nothing (HEARTBEAT_OK).
|
|
13
|
+
Daily reports and health checks are handled by the cron scheduler.
|
|
14
|
+
No action needed here (HEARTBEAT_OK).
|
|
19
15
|
${MARKER_END}`;
|
|
20
16
|
export const HEARTBEAT_FILENAME = 'HEARTBEAT.md';
|
|
21
17
|
// ── Main handler ────────────────────────────────────────────────────
|
|
@@ -43,7 +39,7 @@ export async function handleAutopilot(ctx, args) {
|
|
|
43
39
|
}
|
|
44
40
|
// ── Enable ──────────────────────────────────────────────────────────
|
|
45
41
|
async function handleEnable(ctx) {
|
|
46
|
-
const { workspaceDir } = ctx;
|
|
42
|
+
const { workspaceDir, rpc, logger } = ctx;
|
|
47
43
|
const heartbeatPath = path.join(workspaceDir, HEARTBEAT_FILENAME);
|
|
48
44
|
// Read or create HEARTBEAT.md
|
|
49
45
|
let content = '';
|
|
@@ -61,6 +57,8 @@ async function handleEnable(ctx) {
|
|
|
61
57
|
await withRegistry(workspaceDir, (data) => {
|
|
62
58
|
data.autopilotEnabled = true;
|
|
63
59
|
});
|
|
60
|
+
// Ensure combined cron is registered
|
|
61
|
+
await ensureCombinedCron(workspaceDir, rpc, logger);
|
|
64
62
|
return { text: 'Autopilot is already enabled.' };
|
|
65
63
|
}
|
|
66
64
|
// Append block to HEARTBEAT.md
|
|
@@ -69,15 +67,19 @@ async function handleEnable(ctx) {
|
|
|
69
67
|
await withRegistry(workspaceDir, (data) => {
|
|
70
68
|
data.autopilotEnabled = true;
|
|
71
69
|
});
|
|
70
|
+
// Register combined cron + cleanup per-topic crons
|
|
71
|
+
await ensureCombinedCron(workspaceDir, rpc, logger);
|
|
72
|
+
await cleanupPerTopicCrons(workspaceDir, rpc, logger);
|
|
72
73
|
return {
|
|
73
|
-
text: '**Autopilot enabled.**\
|
|
74
|
+
text: '**Autopilot enabled.**\nDaily reports and health checks will run automatically at 09:00 UTC.',
|
|
74
75
|
};
|
|
75
76
|
}
|
|
76
77
|
// ── Disable ─────────────────────────────────────────────────────────
|
|
77
78
|
async function handleDisable(ctx) {
|
|
78
|
-
const { workspaceDir } = ctx;
|
|
79
|
+
const { workspaceDir, rpc, logger } = ctx;
|
|
79
80
|
const heartbeatPath = path.join(workspaceDir, HEARTBEAT_FILENAME);
|
|
80
81
|
if (!fs.existsSync(heartbeatPath)) {
|
|
82
|
+
await removeCombinedCron(workspaceDir, rpc, logger);
|
|
81
83
|
await withRegistry(workspaceDir, (data) => {
|
|
82
84
|
data.autopilotEnabled = false;
|
|
83
85
|
});
|
|
@@ -85,6 +87,7 @@ async function handleDisable(ctx) {
|
|
|
85
87
|
}
|
|
86
88
|
let content = fs.readFileSync(heartbeatPath, 'utf-8');
|
|
87
89
|
if (!content.includes(MARKER_START)) {
|
|
90
|
+
await removeCombinedCron(workspaceDir, rpc, logger);
|
|
88
91
|
await withRegistry(workspaceDir, (data) => {
|
|
89
92
|
data.autopilotEnabled = false;
|
|
90
93
|
});
|
|
@@ -104,11 +107,13 @@ async function handleDisable(ctx) {
|
|
|
104
107
|
fs.unlinkSync(heartbeatPath);
|
|
105
108
|
}
|
|
106
109
|
}
|
|
110
|
+
// Remove combined cron
|
|
111
|
+
await removeCombinedCron(workspaceDir, rpc, logger);
|
|
107
112
|
await withRegistry(workspaceDir, (data) => {
|
|
108
113
|
data.autopilotEnabled = false;
|
|
109
114
|
});
|
|
110
115
|
return {
|
|
111
|
-
text: '**Autopilot disabled.**\nAutomatic health checks are now off.',
|
|
116
|
+
text: '**Autopilot disabled.**\nAutomatic daily reports and health checks are now off.',
|
|
112
117
|
};
|
|
113
118
|
}
|
|
114
119
|
// ── Status ──────────────────────────────────────────────────────────
|
|
@@ -119,12 +124,66 @@ async function handleStatus(ctx) {
|
|
|
119
124
|
const lastRun = registry.lastDoctorAllRunAt
|
|
120
125
|
? relativeTime(registry.lastDoctorAllRunAt)
|
|
121
126
|
: 'never';
|
|
127
|
+
const cronStatus = registry.dailyReportCronJobId
|
|
128
|
+
? 'active (09:00 UTC)'
|
|
129
|
+
: 'not registered';
|
|
122
130
|
const lines = [
|
|
123
131
|
`**Autopilot:** ${enabled ? 'enabled' : 'disabled'}`,
|
|
132
|
+
`**Daily cron:** ${cronStatus}`,
|
|
124
133
|
`**Last health check run:** ${lastRun}`,
|
|
125
134
|
];
|
|
126
135
|
return {
|
|
127
136
|
text: lines.join('\n'),
|
|
128
137
|
};
|
|
129
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Register the combined daily cron job if not already registered.
|
|
141
|
+
* Stores the job ID in the registry's `dailyReportCronJobId`.
|
|
142
|
+
*/
|
|
143
|
+
export async function ensureCombinedCron(workspaceDir, rpc, logger) {
|
|
144
|
+
const registry = readRegistry(workspaceDir);
|
|
145
|
+
if (registry.dailyReportCronJobId)
|
|
146
|
+
return;
|
|
147
|
+
const result = await registerCombinedCron(rpc, logger);
|
|
148
|
+
if (result.jobId) {
|
|
149
|
+
await withRegistry(workspaceDir, (data) => {
|
|
150
|
+
data.dailyReportCronJobId = result.jobId;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Remove the combined daily cron job and clear the registry field.
|
|
156
|
+
*/
|
|
157
|
+
async function removeCombinedCron(workspaceDir, rpc, logger) {
|
|
158
|
+
const registry = readRegistry(workspaceDir);
|
|
159
|
+
if (!registry.dailyReportCronJobId)
|
|
160
|
+
return;
|
|
161
|
+
await removeCronJob(rpc, registry.dailyReportCronJobId, logger);
|
|
162
|
+
await withRegistry(workspaceDir, (data) => {
|
|
163
|
+
data.dailyReportCronJobId = null;
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Remove all per-topic cron jobs and clear their cronJobId fields.
|
|
168
|
+
*/
|
|
169
|
+
export async function cleanupPerTopicCrons(workspaceDir, rpc, logger) {
|
|
170
|
+
const registry = readRegistry(workspaceDir);
|
|
171
|
+
const topicsWithCron = Object.entries(registry.topics)
|
|
172
|
+
.filter(([, entry]) => entry.cronJobId !== null);
|
|
173
|
+
if (topicsWithCron.length === 0)
|
|
174
|
+
return;
|
|
175
|
+
for (const [, entry] of topicsWithCron) {
|
|
176
|
+
if (entry.cronJobId) {
|
|
177
|
+
await removeCronJob(rpc, entry.cronJobId, logger);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
await withRegistry(workspaceDir, (data) => {
|
|
181
|
+
for (const [key] of topicsWithCron) {
|
|
182
|
+
const entry = data.topics[key];
|
|
183
|
+
if (entry) {
|
|
184
|
+
entry.cronJobId = null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
130
189
|
//# sourceMappingURL=autopilot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autopilot.js","sourceRoot":"","sources":["../../src/commands/autopilot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"autopilot.js","sourceRoot":"","sources":["../../src/commands/autopilot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { TopicEntry } from '../lib/types.js';
|
|
2
|
+
import type { CommandContext, CommandResult } from './help.js';
|
|
3
|
+
export type DailyReportSkipReason = 'archived' | 'snoozed' | 'inactive' | 'already-reported-today';
|
|
4
|
+
export interface DailyReportEligibilityResult {
|
|
5
|
+
eligible: boolean;
|
|
6
|
+
skipReason?: DailyReportSkipReason;
|
|
7
|
+
}
|
|
8
|
+
interface TopicOutcome {
|
|
9
|
+
name: string;
|
|
10
|
+
slug: string;
|
|
11
|
+
status: 'reported' | 'post-failed';
|
|
12
|
+
}
|
|
13
|
+
interface SkippedTopic {
|
|
14
|
+
name: string;
|
|
15
|
+
reason: DailyReportSkipReason;
|
|
16
|
+
}
|
|
17
|
+
export declare function getDailyReportEligibility(entry: TopicEntry, now: Date, statusTimestamp?: string | null): DailyReportEligibilityResult;
|
|
18
|
+
export interface DailyReportAllSummaryData {
|
|
19
|
+
reportedTopics: TopicOutcome[];
|
|
20
|
+
skippedTopics: SkippedTopic[];
|
|
21
|
+
postFailures: number;
|
|
22
|
+
migrationGroups: number;
|
|
23
|
+
errors: string[];
|
|
24
|
+
}
|
|
25
|
+
export declare function buildDailyReportAllSummary(data: DailyReportAllSummaryData): string;
|
|
26
|
+
export declare function handleDailyReportAll(ctx: CommandContext): Promise<CommandResult>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=daily-report-all.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daily-report-all.d.ts","sourceRoot":"","sources":["../../src/commands/daily-report-all.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AASlD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAI/D,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,wBAAwB,CAAC;AAEnG,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,aAAa,CAAC;CACpC;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAID,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,IAAI,EACT,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC9B,4BAA4B,CA6B9B;AAkBD,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAID,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,yBAAyB,GAAG,MAAM,CAoFlF;AAID,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAkKtF"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import { readRegistry, withRegistry } from '../lib/registry.js';
|
|
3
|
+
import { checkAuthorization } from '../lib/auth.js';
|
|
4
|
+
import { INACTIVE_AFTER_DAYS, MAX_POST_ERROR_LENGTH, } from '../lib/types.js';
|
|
5
|
+
import { buildDailyReport, createRateLimitedPoster, truncateMessage } from '../lib/telegram.js';
|
|
6
|
+
import { mostRecent, extractStatusTimestamp } from './doctor-all.js';
|
|
7
|
+
import { readFileOrNull, extractDoneSection, extractBlockers, extractNextActions, } from './daily-report.js';
|
|
8
|
+
// ── Eligibility ──────────────────────────────────────────────────────
|
|
9
|
+
export function getDailyReportEligibility(entry, now, statusTimestamp) {
|
|
10
|
+
if (entry.status === 'archived')
|
|
11
|
+
return { eligible: false, skipReason: 'archived' };
|
|
12
|
+
if (entry.snoozeUntil && new Date(entry.snoozeUntil).getTime() > now.getTime()) {
|
|
13
|
+
return { eligible: false, skipReason: 'snoozed' };
|
|
14
|
+
}
|
|
15
|
+
const lastActive = mostRecent(entry.lastMessageAt, statusTimestamp);
|
|
16
|
+
if (lastActive) {
|
|
17
|
+
const lastActiveMs = new Date(lastActive).getTime();
|
|
18
|
+
const inactiveMs = INACTIVE_AFTER_DAYS * 24 * 60 * 60 * 1000;
|
|
19
|
+
if (now.getTime() - lastActiveMs > inactiveMs) {
|
|
20
|
+
return { eligible: false, skipReason: 'inactive' };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Calendar-day dedup (UTC)
|
|
24
|
+
if (entry.lastDailyReportAt) {
|
|
25
|
+
const lastReport = new Date(entry.lastDailyReportAt);
|
|
26
|
+
if (lastReport.getUTCFullYear() === now.getUTCFullYear() &&
|
|
27
|
+
lastReport.getUTCMonth() === now.getUTCMonth() &&
|
|
28
|
+
lastReport.getUTCDate() === now.getUTCDate()) {
|
|
29
|
+
return { eligible: false, skipReason: 'already-reported-today' };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { eligible: true };
|
|
33
|
+
}
|
|
34
|
+
// ── Summary builder ──────────────────────────────────────────────────
|
|
35
|
+
const SKIP_ICONS = {
|
|
36
|
+
archived: '\ud83d\udce6', // 📦
|
|
37
|
+
snoozed: '\ud83d\udca4', // 💤
|
|
38
|
+
inactive: '\ud83d\udd07', // 🔇
|
|
39
|
+
'already-reported-today': '\u23f0', // ⏰
|
|
40
|
+
};
|
|
41
|
+
const SKIP_LABELS = {
|
|
42
|
+
archived: 'archived',
|
|
43
|
+
snoozed: 'snoozed',
|
|
44
|
+
inactive: 'inactive',
|
|
45
|
+
'already-reported-today': 'already reported today',
|
|
46
|
+
};
|
|
47
|
+
const SUMMARY_SOFT_LIMIT = 3800;
|
|
48
|
+
export function buildDailyReportAllSummary(data) {
|
|
49
|
+
const { reportedTopics, skippedTopics, postFailures, migrationGroups, errors, } = data;
|
|
50
|
+
if (reportedTopics.length === 0 && skippedTopics.length === 0) {
|
|
51
|
+
return '**Daily Report Summary**\n\nNo topics registered yet.';
|
|
52
|
+
}
|
|
53
|
+
const lines = ['**Daily Report Summary**', ''];
|
|
54
|
+
// ── Reported topics ──
|
|
55
|
+
let renderedCount = 0;
|
|
56
|
+
for (const t of reportedTopics) {
|
|
57
|
+
let icon;
|
|
58
|
+
let label;
|
|
59
|
+
switch (t.status) {
|
|
60
|
+
case 'reported':
|
|
61
|
+
icon = '\u2705'; // ✅
|
|
62
|
+
label = 'reported';
|
|
63
|
+
break;
|
|
64
|
+
case 'post-failed':
|
|
65
|
+
icon = '\u26a0\ufe0f'; // ⚠️
|
|
66
|
+
label = 'failed to post';
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
const line = `${icon} ${t.name} \u2014 ${label}`;
|
|
70
|
+
if (lines.join('\n').length + line.length > SUMMARY_SOFT_LIMIT) {
|
|
71
|
+
const remaining = reportedTopics.length - renderedCount;
|
|
72
|
+
lines.push(`... and ${remaining} more`);
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
lines.push(line);
|
|
76
|
+
renderedCount++;
|
|
77
|
+
}
|
|
78
|
+
// ── Skipped topics ──
|
|
79
|
+
if (skippedTopics.length > 0) {
|
|
80
|
+
lines.push('');
|
|
81
|
+
lines.push('\u23ed\ufe0f Skipped:'); // ⏭️
|
|
82
|
+
let skippedRendered = 0;
|
|
83
|
+
for (const t of skippedTopics) {
|
|
84
|
+
const icon = SKIP_ICONS[t.reason];
|
|
85
|
+
const label = SKIP_LABELS[t.reason];
|
|
86
|
+
const line = `${icon} ${t.name} \u2014 ${label}`;
|
|
87
|
+
if (lines.join('\n').length + line.length > SUMMARY_SOFT_LIMIT) {
|
|
88
|
+
const remaining = skippedTopics.length - skippedRendered;
|
|
89
|
+
lines.push(`... and ${remaining} more`);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
lines.push(line);
|
|
93
|
+
skippedRendered++;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// ── Post failures callout ──
|
|
97
|
+
if (postFailures > 0) {
|
|
98
|
+
lines.push('');
|
|
99
|
+
lines.push(`\u26a0\ufe0f ${postFailures} topic(s) failed to post`);
|
|
100
|
+
}
|
|
101
|
+
// ── Migration warning ──
|
|
102
|
+
if (migrationGroups > 0) {
|
|
103
|
+
lines.push('');
|
|
104
|
+
lines.push(`**Warning:** ${migrationGroups} group(s) had all topics fail. The group may have been migrated or deleted.`);
|
|
105
|
+
}
|
|
106
|
+
// ── Errors (internal) ──
|
|
107
|
+
if (errors.length > 0) {
|
|
108
|
+
lines.push('');
|
|
109
|
+
lines.push(`**Errors (${errors.length}):**`);
|
|
110
|
+
for (const e of errors.slice(0, 10)) {
|
|
111
|
+
lines.push(`- ${e}`);
|
|
112
|
+
}
|
|
113
|
+
if (errors.length > 10) {
|
|
114
|
+
lines.push(`... and ${errors.length - 10} more`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return truncateMessage(lines.join('\n'));
|
|
118
|
+
}
|
|
119
|
+
// ── Main handler ─────────────────────────────────────────────────────
|
|
120
|
+
export async function handleDailyReportAll(ctx) {
|
|
121
|
+
const { workspaceDir, logger } = ctx;
|
|
122
|
+
const registry = readRegistry(workspaceDir);
|
|
123
|
+
// Autopilot calls have no Telegram user context — fall back to first admin
|
|
124
|
+
const userId = ctx.userId ?? registry.topicManagerAdmins[0];
|
|
125
|
+
if (!userId) {
|
|
126
|
+
return { text: 'Something went wrong — could not identify your user account.' };
|
|
127
|
+
}
|
|
128
|
+
// Auth check (admin tier)
|
|
129
|
+
const auth = checkAuthorization(userId, 'daily-report-all', registry);
|
|
130
|
+
if (!auth.authorized) {
|
|
131
|
+
return { text: auth.message ?? 'Not authorized.' };
|
|
132
|
+
}
|
|
133
|
+
const now = new Date();
|
|
134
|
+
const projectsBase = path.join(workspaceDir, 'projects');
|
|
135
|
+
const allEntries = Object.entries(registry.topics);
|
|
136
|
+
const reportedTopics = [];
|
|
137
|
+
const skippedTopics = [];
|
|
138
|
+
const errors = [];
|
|
139
|
+
// Group tracking for migration detection
|
|
140
|
+
const groupPostResults = new Map();
|
|
141
|
+
const reports = [];
|
|
142
|
+
for (const [_key, entry] of allEntries) {
|
|
143
|
+
const capsuleDir = path.join(projectsBase, entry.slug);
|
|
144
|
+
const statusContent = readFileOrNull(path.join(capsuleDir, 'STATUS.md'));
|
|
145
|
+
const statusTs = statusContent ? extractStatusTimestamp(statusContent) : null;
|
|
146
|
+
const eligibility = getDailyReportEligibility(entry, now, statusTs);
|
|
147
|
+
if (!eligibility.eligible) {
|
|
148
|
+
skippedTopics.push({ name: entry.name, reason: eligibility.skipReason });
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
const doneContent = extractDoneSection(statusContent);
|
|
153
|
+
const blockers = extractBlockers(statusContent);
|
|
154
|
+
const nextContent = extractNextActions(statusContent);
|
|
155
|
+
const reportData = {
|
|
156
|
+
name: entry.name,
|
|
157
|
+
doneContent,
|
|
158
|
+
blockersContent: blockers,
|
|
159
|
+
nextContent,
|
|
160
|
+
};
|
|
161
|
+
const reportText = buildDailyReport(reportData, 'html');
|
|
162
|
+
reports.push({
|
|
163
|
+
slug: entry.slug,
|
|
164
|
+
groupId: entry.groupId,
|
|
165
|
+
threadId: entry.threadId,
|
|
166
|
+
text: reportText,
|
|
167
|
+
});
|
|
168
|
+
// Track group post results for migration detection
|
|
169
|
+
const gk = entry.groupId;
|
|
170
|
+
if (!groupPostResults.has(gk)) {
|
|
171
|
+
groupPostResults.set(gk, { total: 0, failed: 0 });
|
|
172
|
+
}
|
|
173
|
+
groupPostResults.get(gk).total++;
|
|
174
|
+
reportedTopics.push({ name: entry.name, slug: entry.slug, status: 'reported' });
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
178
|
+
errors.push(`${entry.slug}: ${msg}`);
|
|
179
|
+
logger.error(`[daily-report-all] Error processing ${entry.slug}: ${msg}`);
|
|
180
|
+
const gk = entry.groupId;
|
|
181
|
+
if (!groupPostResults.has(gk)) {
|
|
182
|
+
groupPostResults.set(gk, { total: 0, failed: 0 });
|
|
183
|
+
}
|
|
184
|
+
groupPostResults.get(gk).total++;
|
|
185
|
+
groupPostResults.get(gk).failed++;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Migration detection: all topics in a group failed
|
|
189
|
+
const migrationGroups = [];
|
|
190
|
+
for (const [gid, stats] of groupPostResults) {
|
|
191
|
+
if (stats.total > 0 && stats.failed === stats.total) {
|
|
192
|
+
migrationGroups.push(gid);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Fan-out posting
|
|
196
|
+
let postFailures = 0;
|
|
197
|
+
const postFailedSlugs = new Set();
|
|
198
|
+
if (ctx.postFn && reports.length > 0) {
|
|
199
|
+
const rateLimitedPost = createRateLimitedPoster(ctx.postFn);
|
|
200
|
+
for (const report of reports) {
|
|
201
|
+
try {
|
|
202
|
+
await rateLimitedPost(report.groupId, report.threadId, report.text);
|
|
203
|
+
await withRegistry(workspaceDir, (data) => {
|
|
204
|
+
const key = `${report.groupId}:${report.threadId}`;
|
|
205
|
+
const entry = data.topics[key];
|
|
206
|
+
if (entry) {
|
|
207
|
+
entry.lastDailyReportAt = now.toISOString();
|
|
208
|
+
entry.lastPostError = null;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
postFailures++;
|
|
214
|
+
postFailedSlugs.add(report.slug);
|
|
215
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
216
|
+
logger.error(`[daily-report-all] Post failed for ${report.slug}: ${msg}`);
|
|
217
|
+
await withRegistry(workspaceDir, (data) => {
|
|
218
|
+
const key = `${report.groupId}:${report.threadId}`;
|
|
219
|
+
const entry = data.topics[key];
|
|
220
|
+
if (entry) {
|
|
221
|
+
entry.lastPostError = msg.slice(0, MAX_POST_ERROR_LENGTH);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Update outcomes for post-failed topics
|
|
227
|
+
for (const outcome of reportedTopics) {
|
|
228
|
+
if (postFailedSlugs.has(outcome.slug) && outcome.status === 'reported') {
|
|
229
|
+
outcome.status = 'post-failed';
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else if (reports.length > 0) {
|
|
234
|
+
// No postFn — still update lastDailyReportAt
|
|
235
|
+
await withRegistry(workspaceDir, (data) => {
|
|
236
|
+
for (const report of reports) {
|
|
237
|
+
const key = `${report.groupId}:${report.threadId}`;
|
|
238
|
+
const entry = data.topics[key];
|
|
239
|
+
if (entry) {
|
|
240
|
+
entry.lastDailyReportAt = now.toISOString();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
text: buildDailyReportAllSummary({
|
|
247
|
+
reportedTopics,
|
|
248
|
+
skippedTopics,
|
|
249
|
+
postFailures,
|
|
250
|
+
migrationGroups: migrationGroups.length,
|
|
251
|
+
errors,
|
|
252
|
+
}),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=daily-report-all.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daily-report-all.js","sourceRoot":"","sources":["../../src/commands/daily-report-all.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,6 +29,7 @@ export interface DoctorAllSummaryData {
|
|
|
29
29
|
export declare function buildDoctorAllSummary(data: DoctorAllSummaryData): string;
|
|
30
30
|
export declare function handleDoctorAll(ctx: CommandContext): Promise<CommandResult>;
|
|
31
31
|
export declare function extractStatusTimestamp(content: string): string | null;
|
|
32
|
+
export declare function mostRecent(a: string | null | undefined, b: string | null | undefined): string | null;
|
|
32
33
|
export declare function isEligible(entry: TopicEntry, now: Date, statusTimestamp?: string | null): boolean;
|
|
33
34
|
export {};
|
|
34
35
|
//# sourceMappingURL=doctor-all.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-all.d.ts","sourceRoot":"","sources":["../../src/commands/doctor-all.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAC;AAQxE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAa/D,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,kBAAkB,CAAC;AAElF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,cAAc,GAAG,aAAa,CAAC;CACpD;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,IAAI,EACT,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC9B,iBAAiB,CAwBnB;AAkBD,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAID,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAwFxE;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAuPjF;AAKD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQrE;
|
|
1
|
+
{"version":3,"file":"doctor-all.d.ts","sourceRoot":"","sources":["../../src/commands/doctor-all.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAC;AAQxE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAa/D,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,kBAAkB,CAAC;AAElF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,cAAc,GAAG,aAAa,CAAC;CACpD;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,IAAI,EACT,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC9B,iBAAiB,CAwBnB;AAkBD,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAID,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAwFxE;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAuPjF;AAKD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQrE;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAKpG;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAsBjG"}
|
|
@@ -345,7 +345,7 @@ export function extractStatusTimestamp(content) {
|
|
|
345
345
|
const match = section.match(ISO_TIMESTAMP_RE);
|
|
346
346
|
return match ? match[0] : null;
|
|
347
347
|
}
|
|
348
|
-
function mostRecent(a, b) {
|
|
348
|
+
export function mostRecent(a, b) {
|
|
349
349
|
if (!a && !b)
|
|
350
350
|
return null;
|
|
351
351
|
if (!a)
|