@rubytech/taskmaster 1.22.1 → 1.22.3
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/build-info.json +3 -3
- package/dist/config/validation.js +8 -8
- package/dist/control-ui/assets/{index-BErknDpG.js → index-CT2I2Boa.js} +3 -3
- package/dist/control-ui/assets/index-CT2I2Boa.js.map +1 -0
- package/dist/control-ui/index.html +1 -1
- package/dist/gateway/server.impl.js +32 -0
- package/dist/plugins/discovery.js +2 -2
- package/dist/web/auto-reply/monitor.js +48 -7
- package/package.json +1 -1
- package/dist/control-ui/assets/index-BErknDpG.js.map +0 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>Taskmaster Control</title>
|
|
7
7
|
<meta name="color-scheme" content="dark light" />
|
|
8
8
|
<link rel="icon" type="image/png" href="./favicon.png" />
|
|
9
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
+
<script type="module" crossorigin src="./assets/index-CT2I2Boa.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="./assets/index-C7ieCeTV.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
@@ -28,6 +28,8 @@ import { setGatewaySigusr1RestartPolicy } from "../infra/restart.js";
|
|
|
28
28
|
import { startDiagnosticHeartbeat, stopDiagnosticHeartbeat } from "../logging/diagnostic.js";
|
|
29
29
|
import { createSubsystemLogger, runtimeForLogger } from "../logging/subsystem.js";
|
|
30
30
|
import { getMemorySearchManager } from "../memory/index.js";
|
|
31
|
+
import { resolveBundledPluginsDirDetailed } from "../plugins/bundled-dir.js";
|
|
32
|
+
import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js";
|
|
31
33
|
import { runOnboardingWizard } from "../wizard/onboarding.js";
|
|
32
34
|
import { startGatewayConfigReloader } from "./config-reload.js";
|
|
33
35
|
import { getHealthCache, getHealthVersion, getPresenceVersion, incrementPresenceVersion, refreshGatewayHealthSnapshot, } from "./server/health-state.js";
|
|
@@ -131,6 +133,36 @@ export async function startGatewayServer(port = 18789, opts = {}) {
|
|
|
131
133
|
: "Unknown validation issue.";
|
|
132
134
|
throw new Error(`Invalid config at ${configSnapshot.path}.\n${issues}\nRun "${formatCliCommand("taskmaster doctor")}" to repair, then retry.`);
|
|
133
135
|
}
|
|
136
|
+
// Log plugin discovery results at startup for diagnostics.
|
|
137
|
+
{
|
|
138
|
+
const pluginRegistry = loadPluginManifestRegistry({
|
|
139
|
+
config: configSnapshot.config,
|
|
140
|
+
workspaceDir: resolveAgentWorkspaceDir(configSnapshot.config, resolveDefaultAgentId(configSnapshot.config)) ?? undefined,
|
|
141
|
+
});
|
|
142
|
+
const bundled = resolveBundledPluginsDirDetailed();
|
|
143
|
+
if (bundled.dir) {
|
|
144
|
+
logPlugins.info(`bundled extensions: ${bundled.dir} (${bundled.source})`);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
logPlugins.warn(`bundled extensions dir not found (resolved: ${bundled.resolvedPath ?? "unknown"}, source: ${bundled.source ?? "package-relative"})`);
|
|
148
|
+
}
|
|
149
|
+
const pluginIds = pluginRegistry.plugins.map((p) => p.id);
|
|
150
|
+
if (pluginIds.length > 0) {
|
|
151
|
+
logPlugins.info(`discovered plugins: ${pluginIds.join(", ")}`);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
logPlugins.warn("no plugins discovered");
|
|
155
|
+
}
|
|
156
|
+
for (const diag of pluginRegistry.diagnostics) {
|
|
157
|
+
const msg = `plugin discovery: ${diag.message}`;
|
|
158
|
+
if (diag.level === "error")
|
|
159
|
+
logPlugins.error(msg);
|
|
160
|
+
else if (diag.level === "warn")
|
|
161
|
+
logPlugins.warn(msg);
|
|
162
|
+
else
|
|
163
|
+
logPlugins.info(msg);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
134
166
|
const autoEnable = applyPluginAutoEnable({ config: configSnapshot.config, env: process.env });
|
|
135
167
|
if (autoEnable.changes.length > 0) {
|
|
136
168
|
try {
|
|
@@ -274,8 +274,8 @@ export function discoverTaskmasterPlugins(params) {
|
|
|
274
274
|
}
|
|
275
275
|
else {
|
|
276
276
|
diagnostics.push({
|
|
277
|
-
level: "
|
|
278
|
-
message: `bundled extensions dir not found at ${bundled.resolvedPath ?? "unknown"}`,
|
|
277
|
+
level: "warn",
|
|
278
|
+
message: `bundled extensions dir not found at ${bundled.resolvedPath ?? "unknown"} (source: ${bundled.source ?? "package-relative"})`,
|
|
279
279
|
source: "bundled-dir",
|
|
280
280
|
});
|
|
281
281
|
}
|
|
@@ -23,6 +23,52 @@ import { buildMentionConfig } from "./mentions.js";
|
|
|
23
23
|
import { createEchoTracker } from "./monitor/echo.js";
|
|
24
24
|
import { createWebOnMessageHandler } from "./monitor/on-message.js";
|
|
25
25
|
import { isLikelyWhatsAppCryptoError } from "./util.js";
|
|
26
|
+
/**
|
|
27
|
+
* Translate raw Baileys error strings into messages a non-technical user can act on.
|
|
28
|
+
* The raw error is still logged to the system log file for debugging.
|
|
29
|
+
*/
|
|
30
|
+
function humanizeWhatsAppError(statusCode, rawError) {
|
|
31
|
+
const lower = rawError.toLowerCase();
|
|
32
|
+
// Conflict: another WhatsApp Web session took over (credentials still valid)
|
|
33
|
+
if (/conflict/i.test(rawError)) {
|
|
34
|
+
return "WhatsApp was opened on another device or browser. Reconnecting automatically…";
|
|
35
|
+
}
|
|
36
|
+
// True logout — session credentials are no longer valid
|
|
37
|
+
if (statusCode === 401) {
|
|
38
|
+
return "WhatsApp session expired or was removed from the phone. Open the setup page and re-link WhatsApp.";
|
|
39
|
+
}
|
|
40
|
+
// Connection lost / timed out (408)
|
|
41
|
+
if (statusCode === 408 || lower.includes("timed out") || lower.includes("connection was lost")) {
|
|
42
|
+
return "Connection to WhatsApp lost. Reconnecting automatically…";
|
|
43
|
+
}
|
|
44
|
+
// Connection closed by server (428)
|
|
45
|
+
if (statusCode === 428 ||
|
|
46
|
+
lower.includes("connection closed") ||
|
|
47
|
+
lower.includes("connection terminated")) {
|
|
48
|
+
return "WhatsApp connection closed unexpectedly. Reconnecting automatically…";
|
|
49
|
+
}
|
|
50
|
+
// Connection replaced (440) — another session, similar to conflict
|
|
51
|
+
if (statusCode === 440) {
|
|
52
|
+
return "WhatsApp was opened on another device. Reconnecting automatically…";
|
|
53
|
+
}
|
|
54
|
+
// Bad session data (500)
|
|
55
|
+
if (statusCode === 500 || lower.includes("bad session")) {
|
|
56
|
+
return "WhatsApp session data may be corrupted. Try re-linking WhatsApp from the setup page.";
|
|
57
|
+
}
|
|
58
|
+
// Restart required (515)
|
|
59
|
+
if (statusCode === 515) {
|
|
60
|
+
return "WhatsApp requires a reconnection. Reconnecting automatically…";
|
|
61
|
+
}
|
|
62
|
+
// Forbidden (403)
|
|
63
|
+
if (statusCode === 403) {
|
|
64
|
+
return "WhatsApp rejected the connection. The phone number may be banned or restricted.";
|
|
65
|
+
}
|
|
66
|
+
// Fallback: strip technical prefixes but keep the core message
|
|
67
|
+
return (rawError
|
|
68
|
+
.replace(/^(Boom:|Error:)\s*/i, "")
|
|
69
|
+
.replace(/\s*\{.*\}\s*$/, "")
|
|
70
|
+
.trim() || "WhatsApp disconnected unexpectedly. Reconnecting…");
|
|
71
|
+
}
|
|
26
72
|
export async function monitorWebChannel(verbose, listenerFactory = monitorWebInbox, keepAlive = true, replyResolver = getReplyFromConfig, runtime = defaultRuntime, abortSignal, tuning = {}) {
|
|
27
73
|
const runId = newConnectionId();
|
|
28
74
|
const replyLogger = getChildLogger({ module: "web-auto-reply", runId });
|
|
@@ -173,9 +219,7 @@ export async function monitorWebChannel(verbose, listenerFactory = monitorWebInb
|
|
|
173
219
|
// carry status 401, but it is NOT a true logout — credentials remain valid.
|
|
174
220
|
const isConflict = /conflict/i.test(errorStr);
|
|
175
221
|
const loggedOut = statusCode === 401 && !isConflict;
|
|
176
|
-
const userError =
|
|
177
|
-
? "WhatsApp was opened on another device or browser. Reconnecting automatically…"
|
|
178
|
-
: errorStr;
|
|
222
|
+
const userError = humanizeWhatsAppError(statusCode, errorStr);
|
|
179
223
|
status.connected = false;
|
|
180
224
|
status.lastEventAt = Date.now();
|
|
181
225
|
status.lastDisconnect = {
|
|
@@ -355,10 +399,7 @@ export async function monitorWebChannel(verbose, listenerFactory = monitorWebInb
|
|
|
355
399
|
"isLoggedOut" in reason &&
|
|
356
400
|
reason.isLoggedOut;
|
|
357
401
|
const errorStr = formatError(reason);
|
|
358
|
-
const
|
|
359
|
-
const userError = isConflict
|
|
360
|
-
? "WhatsApp was opened on another device or browser. Reconnecting automatically…"
|
|
361
|
-
: errorStr;
|
|
402
|
+
const userError = humanizeWhatsAppError(statusCode, errorStr);
|
|
362
403
|
status.connected = false;
|
|
363
404
|
status.lastEventAt = Date.now();
|
|
364
405
|
status.lastDisconnect = {
|