fix: Telegram reconnect, rebrand compat, and update restore step
- Add "timed out" to NETWORK_ERROR_SNIPPETS in monitor.ts so grammY's
getUpdates timeout message triggers reconnection instead of exiting
- Add "timed out" to RECOVERABLE_MESSAGE_SNIPPETS in network-errors.ts
for defense in depth
- Fix LEGACY_CLI_NAME from "moltbot" to "clawdbot" and fix duplicated
regex alternations in cli-name.ts and command-format.ts so the legacy
binary name is recognized in PATH
- Remove restore control-ui step from update-runner.ts since
dist/control-ui/ is no longer git-tracked (commit 615ccf641)
- Remove :!dist/control-ui/ pathspec exclusion from update-check.ts
dirty check since those files are now gitignored
- Add test for grammY timeout message format
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8bced6e2bc
commit
9b3828cd50
@ -1,10 +1,10 @@
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
export const DEFAULT_CLI_NAME = "moltbot";
|
export const DEFAULT_CLI_NAME = "moltbot";
|
||||||
export const LEGACY_CLI_NAME = "moltbot";
|
export const LEGACY_CLI_NAME = "clawdbot";
|
||||||
|
|
||||||
const KNOWN_CLI_NAMES = new Set([DEFAULT_CLI_NAME, LEGACY_CLI_NAME]);
|
const KNOWN_CLI_NAMES = new Set([DEFAULT_CLI_NAME, LEGACY_CLI_NAME]);
|
||||||
const CLI_PREFIX_RE = /^(?:((?:pnpm|npm|bunx|npx)\s+))?(moltbot|moltbot)\b/;
|
const CLI_PREFIX_RE = /^(?:((?:pnpm|npm|bunx|npx)\s+))?(moltbot|clawdbot)\b/;
|
||||||
|
|
||||||
export function resolveCliName(
|
export function resolveCliName(
|
||||||
argv: string[] = process.argv,
|
argv: string[] = process.argv,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { normalizeProfileName } from "./profile-utils.js";
|
import { normalizeProfileName } from "./profile-utils.js";
|
||||||
import { replaceCliName, resolveCliName } from "./cli-name.js";
|
import { replaceCliName, resolveCliName } from "./cli-name.js";
|
||||||
|
|
||||||
const CLI_PREFIX_RE = /^(?:pnpm|npm|bunx|npx)\s+(?:moltbot|moltbot)\b|^(?:moltbot|moltbot)\b/;
|
const CLI_PREFIX_RE = /^(?:pnpm|npm|bunx|npx)\s+(?:moltbot|clawdbot)\b|^(?:moltbot|clawdbot)\b/;
|
||||||
const PROFILE_FLAG_RE = /(?:^|\s)--profile(?:\s|=|$)/;
|
const PROFILE_FLAG_RE = /(?:^|\s)--profile(?:\s|=|$)/;
|
||||||
const DEV_FLAG_RE = /(?:^|\s)--dev(?:\s|$)/;
|
const DEV_FLAG_RE = /(?:^|\s)--dev(?:\s|$)/;
|
||||||
|
|
||||||
|
|||||||
@ -129,10 +129,9 @@ export async function checkGitUpdateStatus(params: {
|
|||||||
).catch(() => null);
|
).catch(() => null);
|
||||||
const upstream = upstreamRes && upstreamRes.code === 0 ? upstreamRes.stdout.trim() : null;
|
const upstream = upstreamRes && upstreamRes.code === 0 ? upstreamRes.stdout.trim() : null;
|
||||||
|
|
||||||
const dirtyRes = await runCommandWithTimeout(
|
const dirtyRes = await runCommandWithTimeout(["git", "-C", root, "status", "--porcelain"], {
|
||||||
["git", "-C", root, "status", "--porcelain", "--", ":!dist/control-ui/"],
|
timeoutMs,
|
||||||
{ timeoutMs },
|
}).catch(() => null);
|
||||||
).catch(() => null);
|
|
||||||
const dirty = dirtyRes && dirtyRes.code === 0 ? dirtyRes.stdout.trim().length > 0 : null;
|
const dirty = dirtyRes && dirtyRes.code === 0 ? dirtyRes.stdout.trim().length > 0 : null;
|
||||||
|
|
||||||
const fetchOk = params.fetch
|
const fetchOk = params.fetch
|
||||||
|
|||||||
@ -676,17 +676,6 @@ export async function runGatewayUpdate(opts: UpdateRunnerOptions = {}): Promise<
|
|||||||
);
|
);
|
||||||
steps.push(uiBuildStep);
|
steps.push(uiBuildStep);
|
||||||
|
|
||||||
// Restore dist/control-ui/ to committed state to prevent dirty repo after update
|
|
||||||
// (ui:build regenerates assets with new hashes, which would block future updates)
|
|
||||||
const restoreUiStep = await runStep(
|
|
||||||
step(
|
|
||||||
"restore control-ui",
|
|
||||||
["git", "-C", gitRoot, "checkout", "--", "dist/control-ui/"],
|
|
||||||
gitRoot,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
steps.push(restoreUiStep);
|
|
||||||
|
|
||||||
const doctorStep = await runStep(
|
const doctorStep = await runStep(
|
||||||
step(
|
step(
|
||||||
"moltbot doctor",
|
"moltbot doctor",
|
||||||
|
|||||||
@ -78,6 +78,7 @@ const NETWORK_ERROR_SNIPPETS = [
|
|||||||
"fetch failed",
|
"fetch failed",
|
||||||
"network",
|
"network",
|
||||||
"timeout",
|
"timeout",
|
||||||
|
"timed out",
|
||||||
"socket",
|
"socket",
|
||||||
"econnreset",
|
"econnreset",
|
||||||
"econnrefused",
|
"econnrefused",
|
||||||
|
|||||||
@ -31,6 +31,11 @@ describe("isRecoverableTelegramNetworkError", () => {
|
|||||||
expect(isRecoverableTelegramNetworkError(new Error("Undici: socket failure"))).toBe(true);
|
expect(isRecoverableTelegramNetworkError(new Error("Undici: socket failure"))).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("detects grammY getUpdates timeout format", () => {
|
||||||
|
const err = new Error("Request to 'getUpdates' timed out after 500 seconds");
|
||||||
|
expect(isRecoverableTelegramNetworkError(err)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
it("skips message matches for send context", () => {
|
it("skips message matches for send context", () => {
|
||||||
const err = new TypeError("fetch failed");
|
const err = new TypeError("fetch failed");
|
||||||
expect(isRecoverableTelegramNetworkError(err, { context: "send" })).toBe(false);
|
expect(isRecoverableTelegramNetworkError(err, { context: "send" })).toBe(false);
|
||||||
|
|||||||
@ -36,6 +36,7 @@ const RECOVERABLE_MESSAGE_SNIPPETS = [
|
|||||||
"client network socket disconnected",
|
"client network socket disconnected",
|
||||||
"socket hang up",
|
"socket hang up",
|
||||||
"getaddrinfo",
|
"getaddrinfo",
|
||||||
|
"timed out",
|
||||||
];
|
];
|
||||||
|
|
||||||
function normalizeCode(code?: string): string {
|
function normalizeCode(code?: string): string {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user