diff --git a/scripts/check-session-accessor-boundary.mjs b/scripts/check-session-accessor-boundary.mjs index 839d8c495fe5..84d53fb33526 100644 --- a/scripts/check-session-accessor-boundary.mjs +++ b/scripts/check-session-accessor-boundary.mjs @@ -122,7 +122,7 @@ export const migratedSessionAccessorFiles = new Set([ "src/commands/sessions-tail.ts", "src/commands/sessions.ts", "src/commands/status.agent-local.ts", - "src/commands/status.summary.ts", + "src/status/summary.ts", "src/commands/tasks.ts", "src/config/sessions/combined-store-gateway.ts", "src/config/sessions/delivery-info.ts", diff --git a/src/commands/channel-account-context.ts b/src/channels/account-context.ts similarity index 94% rename from src/commands/channel-account-context.ts rename to src/channels/account-context.ts index 8355cc3a4a61..df068f6e2707 100644 --- a/src/commands/channel-account-context.ts +++ b/src/channels/account-context.ts @@ -1,10 +1,10 @@ -// Resolves a channel plugin's default account with strict or read-only diagnostics. -import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js"; -import type { ChannelPlugin } from "../channels/plugins/types.plugin.js"; -import { inspectReadOnlyChannelAccount } from "../channels/read-only-account-inspect.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { formatErrorMessage } from "../infra/errors.js"; import { isRecord } from "../utils.js"; +// Resolves a channel plugin's default account with strict or read-only diagnostics. +import { resolveChannelDefaultAccountId } from "./plugins/helpers.js"; +import type { ChannelPlugin } from "./plugins/types.plugin.js"; +import { inspectReadOnlyChannelAccount } from "./read-only-account-inspect.js"; type ChannelDefaultAccountContext = { accountIds: string[]; diff --git a/src/commands/channel-account-context.test.ts b/src/commands/channel-account-context.test.ts index d77563fd309f..7af460531182 100644 --- a/src/commands/channel-account-context.test.ts +++ b/src/commands/channel-account-context.test.ts @@ -1,8 +1,8 @@ // Channel account context tests cover default account resolution and read-only account inspection fallback. import { describe, expect, it, vi } from "vitest"; +import { resolveDefaultChannelAccountContext } from "../channels/account-context.js"; import type { ChannelPlugin } from "../channels/plugins/types.public.js"; import type { OpenClawConfig } from "../config/config.js"; -import { resolveDefaultChannelAccountContext } from "./channel-account-context.js"; vi.mock("../channels/read-only-account-inspect.js", () => ({ inspectReadOnlyChannelAccount: vi.fn(async () => null), diff --git a/src/commands/doctor-gateway-health.ts b/src/commands/doctor-gateway-health.ts index 0bd8a8c0a1c9..f449e3c4221c 100644 --- a/src/commands/doctor-gateway-health.ts +++ b/src/commands/doctor-gateway-health.ts @@ -17,6 +17,7 @@ import { collectChannelStatusIssues } from "../infra/channels-status-issues.js"; import { formatErrorMessage } from "../infra/errors.js"; import type { RuntimeEnv } from "../runtime.js"; import { redactSecretDegradationReason } from "../secrets/runtime-degraded-state.js"; +import type { StatusSummary } from "../status/types.js"; import { VERSION } from "../version.js"; import { GATEWAY_HEALTH_CREDENTIALS_REQUIRED_MESSAGE, @@ -24,7 +25,6 @@ import { gatewayProbeResultSawGateway, } from "./gateway-health-auth-diagnostic.js"; import { formatGatewayClosedDiagnostic, formatHealthCheckFailure } from "./health-format.js"; -import type { StatusSummary } from "./status.types.js"; type GatewayMemoryProbe = { checked: boolean; diff --git a/src/commands/doctor-security.ts b/src/commands/doctor-security.ts index 821d59d666c5..c68767d89b61 100644 --- a/src/commands/doctor-security.ts +++ b/src/commands/doctor-security.ts @@ -1,6 +1,7 @@ /** Security warnings for gateway exposure, exec policy drift, channel DMs, and plaintext secrets. */ import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { note } from "../../packages/terminal-core/src/note.js"; +import { resolveDefaultChannelAccountContext } from "../channels/account-context.js"; import { resolveDmAllowAuditState } from "../channels/message-access/dm-allow-state.js"; import { listReadOnlyChannelPluginsForConfig } from "../channels/plugins/read-only.js"; import type { ChannelId } from "../channels/plugins/types.public.js"; @@ -23,7 +24,6 @@ import { isLikelySensitiveModelProviderHeaderName } from "../secrets/model-provi import { hasConfiguredPlaintextSecretValue } from "../secrets/secret-value.js"; import { discoverConfigSecretTargets } from "../secrets/target-registry.js"; import { collectExecFilesystemPolicyDriftHits } from "../security/exec-filesystem-policy.js"; -import { resolveDefaultChannelAccountContext } from "./channel-account-context.js"; function collectImplicitHeartbeatDirectPolicyWarnings(cfg: OpenClawConfig): string[] { const warnings: string[] = []; diff --git a/src/commands/doctor-whatsapp-responsiveness.ts b/src/commands/doctor-whatsapp-responsiveness.ts index 4efca9478b45..d33779792310 100644 --- a/src/commands/doctor-whatsapp-responsiveness.ts +++ b/src/commands/doctor-whatsapp-responsiveness.ts @@ -5,8 +5,8 @@ import { note } from "../../packages/terminal-core/src/note.js"; import { formatCliCommand } from "../cli/command-format.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { HealthFinding } from "../flows/health-checks.js"; +import type { StatusSummary } from "../status/types.js"; import { sleep } from "../utils/sleep.js"; -import type { StatusSummary } from "./status.types.js"; type LocalTuiProcess = { pid: number; diff --git a/src/commands/sessions.kind-classification.test.ts b/src/commands/sessions.kind-classification.test.ts index fddd79655877..6bff346f5135 100644 --- a/src/commands/sessions.kind-classification.test.ts +++ b/src/commands/sessions.kind-classification.test.ts @@ -13,7 +13,7 @@ import { * Catalog #19 — `kind` misclassified as `"direct"` for ACP spawn-child sessions. * * Bug summary: `classifySessionKey` (defined twice — `src/commands/sessions.ts:136-152` - * and `src/commands/status.summary.runtime.ts:129-145`) classifies a session + * and `src/status/summary.runtime.ts:129-145`) classifies a session * based ONLY on the key shape (`:group:` / `:channel:` substrings) plus * `entry.chatType`. It ignores `entry.spawnedBy` and `entry.deliveryContext`, * so ACP spawn-child sessions (e.g., `agent:copilot:acp:` with @@ -32,7 +32,7 @@ import { * NOTE ON DUPLICATION: the same logic lives in two places — * - `src/commands/sessions.ts:136-152` (called by `sessionsCommand`, * the path under test here) - * - `src/commands/status.summary.runtime.ts:129-145` + * - `src/status/summary.runtime.ts:129-145` * The eventual fix MUST update both, or extract a shared helper. * * NOTE ON SURFACE: `classifySessionKey` is private to each file (not exported), @@ -177,7 +177,7 @@ describe("sessionsCommand kind classification (catalog #19)", () => { `ACP spawn-child session ${ACP_SPAWN_CHILD_KEY} should classify as "spawn-child" ` + `(or whichever non-direct label the fix author chooses). Got "${row?.kind}". ` + `Fix locations: src/commands/sessions.ts:136-152 AND ` + - `src/commands/status.summary.runtime.ts:129-145 (the same logic is duplicated; ` + + `src/status/summary.runtime.ts:129-145 (the same logic is duplicated; ` + `extract to a shared helper or update both).`, ).toBe("spawn-child"); }); diff --git a/src/commands/status-overview-rows.ts b/src/commands/status-overview-rows.ts index c529366e4f96..0f3c9581560e 100644 --- a/src/commands/status-overview-rows.ts +++ b/src/commands/status-overview-rows.ts @@ -4,6 +4,7 @@ import { formatCliCommand } from "../cli/command-format.js"; import type { HeartbeatEventPayload } from "../infra/heartbeat-events.js"; import type { PluginCompatibilityNotice } from "../plugins/status.js"; +import type { StatusSummary } from "../status/types.js"; import { VERSION } from "../version.js"; import type { HealthSummary } from "./health.js"; import { @@ -28,7 +29,6 @@ import { type StatusMemoryStateResolvers, } from "./status.command-sections.js"; import type { MemoryPluginStatus, MemoryStatusSnapshot } from "./status.scan.shared.js"; -import type { StatusSummary } from "./status.types.js"; /** Builds the default `openclaw status` overview rows from scan, health, memory, and session inputs. */ export function buildStatusCommandOverviewRows( diff --git a/src/commands/status.command-report-data.ts b/src/commands/status.command-report-data.ts index ac45326b7d5e..b142fcd58856 100644 --- a/src/commands/status.command-report-data.ts +++ b/src/commands/status.command-report-data.ts @@ -8,6 +8,7 @@ import type { HeartbeatEventPayload } from "../infra/heartbeat-events.js"; import type { resolveOsSummary } from "../infra/os-summary.js"; import type { PluginCompatibilityNotice } from "../plugins/status.js"; import type { SecurityAuditReport } from "../security/audit.js"; +import type { SessionStatus, StatusSummary } from "../status/types.js"; import type { HealthSummary } from "./health.js"; import { buildStatusChannelsTableRows, @@ -30,7 +31,6 @@ import { type StatusMemoryStateResolvers, } from "./status.command-sections.js"; import type { MemoryPluginStatus, MemoryStatusSnapshot } from "./status.scan.shared.js"; -import type { SessionStatus, StatusSummary } from "./status.types.js"; /** Builds all table rows, section lines, and footer data needed by the status report renderer. */ export async function buildStatusCommandReportData( diff --git a/src/commands/status.command-sections.ts b/src/commands/status.command-sections.ts index 7adcf48fa159..b59698a02cea 100644 --- a/src/commands/status.command-sections.ts +++ b/src/commands/status.command-sections.ts @@ -11,10 +11,10 @@ import type { TableColumn } from "../../packages/terminal-core/src/table.js"; import { areRuntimeModelRefsEquivalent } from "../agents/model-runtime-aliases.js"; import type { HeartbeatEventPayload } from "../infra/heartbeat-events.js"; import type { Tone } from "../memory-host-sdk/status.js"; +import type { SessionStatus, StatusSummary } from "../status/types.js"; import type { HealthSummary } from "./health.js"; import type { AgentLocalStatus } from "./status.agent-local.js"; import type { MemoryStatusSnapshot, MemoryPluginStatus } from "./status.scan.shared.js"; -import type { SessionStatus, StatusSummary } from "./status.types.js"; type AgentStatusLike = { defaultId?: string | null; diff --git a/src/commands/status.format.ts b/src/commands/status.format.ts index 40f46687b092..64ec61b8b8da 100644 --- a/src/commands/status.format.ts +++ b/src/commands/status.format.ts @@ -5,8 +5,8 @@ import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/st import { getSystemdCgroupHygieneSummary } from "../daemon/service-runtime.js"; import { formatDurationPrecise } from "../infra/format-time/format-duration.ts"; import { formatRuntimeStatusWithDetails } from "../infra/runtime-status.ts"; +import type { SessionStatus } from "../status/types.js"; import { formatTokenCount } from "../utils/token-format.js"; -import type { SessionStatus } from "./status.types.js"; export { shortenText } from "./text-format.js"; export const formatKTokens = formatTokenCount; diff --git a/src/commands/status.link-channel.test.ts b/src/commands/status.link-channel.test.ts index ffb8d50e992f..67022c17f035 100644 --- a/src/commands/status.link-channel.test.ts +++ b/src/commands/status.link-channel.test.ts @@ -12,7 +12,7 @@ vi.mock("../channels/read-only-account-inspect.js", () => ({ inspectReadOnlyChannelAccount: () => undefined, })); -import { resolveLinkChannelContext } from "./status.link-channel.js"; +import { resolveLinkChannelContext } from "../status/link-channel.js"; describe("resolveLinkChannelContext", () => { it("returns linked context from read-only inspected account state", async () => { diff --git a/src/commands/status.scan-overview.ts b/src/commands/status.scan-overview.ts index 660c9ad14805..2154989e0262 100644 --- a/src/commands/status.scan-overview.ts +++ b/src/commands/status.scan-overview.ts @@ -29,7 +29,7 @@ const statusScanRuntimeModuleLoader = createLazyImportLoader( () => import("./status.scan.runtime.js"), ); const gatewayCallModuleLoader = createLazyImportLoader(() => import("../gateway/call.js")); -const statusSummaryModuleLoader = createLazyImportLoader(() => import("./status.summary.js")); +const statusSummaryModuleLoader = createLazyImportLoader(() => import("../status/summary.js")); const channelPluginIdsModuleLoader = createLazyImportLoader( () => import("../plugins/channel-plugin-ids.js"), ); diff --git a/src/commands/status.scan-result.ts b/src/commands/status.scan-result.ts index 3fd5705520f4..d5b1dd63f9f5 100644 --- a/src/commands/status.scan-result.ts +++ b/src/commands/status.scan-result.ts @@ -6,6 +6,7 @@ import type { collectChannelStatusIssues as collectChannelStatusIssuesFn } from import { resolveOsSummary } from "../infra/os-summary.js"; import type { UpdateCheckResult } from "../infra/update-check.js"; import type { PluginCompatibilityNotice } from "../plugins/status.js"; +import type { getStatusSummary as getStatusSummaryFn } from "../status/summary.js"; import type { pickGatewaySelfPresence } from "./gateway-presence.js"; import type { buildChannelsTable as buildChannelsTableFn } from "./status-all/channels.js"; import type { getAgentLocalStatuses as getAgentLocalStatusesFn } from "./status.agent-local.js"; @@ -14,7 +15,6 @@ import type { MemoryPluginStatus, MemoryStatusSnapshot, } from "./status.scan.shared.js"; -import type { getStatusSummary as getStatusSummaryFn } from "./status.summary.js"; export type StatusScanResult = { cfg: OpenClawConfig; diff --git a/src/commands/status.scan.test-helpers.ts b/src/commands/status.scan.test-helpers.ts index 8f043031fba3..6426b0646696 100644 --- a/src/commands/status.scan.test-helpers.ts +++ b/src/commands/status.scan.test-helpers.ts @@ -259,7 +259,7 @@ export async function loadStatusScanModuleForTest( })); vi.doMock("./status.update.js", () => createStatusUpdateModuleMock(mocks)); vi.doMock("./status.agent-local.js", () => createStatusAgentLocalModuleMock(mocks)); - vi.doMock("./status.summary.js", () => createStatusSummaryModuleMock(mocks)); + vi.doMock("../status/summary.js", () => createStatusSummaryModuleMock(mocks)); vi.doMock("../infra/os-summary.js", () => createStatusOsSummaryModuleMock()); vi.doMock("./status.scan.deps.runtime.js", () => createStatusScanDepsRuntimeModuleMock(mocks)); vi.doMock("../gateway/call.js", () => createStatusGatewayCallModuleMock(mocks)); diff --git a/src/commands/status.summary.redaction.test.ts b/src/commands/status.summary.redaction.test.ts index 869a8bfdd374..18ebfb4ff1c9 100644 --- a/src/commands/status.summary.redaction.test.ts +++ b/src/commands/status.summary.redaction.test.ts @@ -1,7 +1,7 @@ // Status summary redaction tests cover sensitive field removal from summarized runtime state. import { describe, expect, it } from "vitest"; -import { redactSensitiveStatusSummary } from "./status.summary.js"; -import type { SessionStatus, StatusSummary } from "./status.types.js"; +import { redactSensitiveStatusSummary } from "../status/summary.js"; +import type { SessionStatus, StatusSummary } from "../status/types.js"; function createRecentSessionRow(): SessionStatus { return { diff --git a/src/commands/status.summary.runtime.normalization.test.ts b/src/commands/status.summary.runtime.normalization.test.ts index 81e95be8d6ba..4d2cda7700de 100644 --- a/src/commands/status.summary.runtime.normalization.test.ts +++ b/src/commands/status.summary.runtime.normalization.test.ts @@ -19,7 +19,7 @@ describe("statusSummaryRuntime configured model normalization", () => { }); it("skips manifest and plugin model normalization for configured model refs", async () => { - const { statusSummaryRuntime } = await import("./status.summary.runtime.js"); + const { statusSummaryRuntime } = await import("../status/summary.runtime.js"); expect( statusSummaryRuntime.resolveConfiguredStatusModelRef({ @@ -63,7 +63,7 @@ describe("statusSummaryRuntime configured model normalization", () => { }); it("skips manifest and plugin model normalization for providerless persisted session models", async () => { - const { statusSummaryRuntime } = await import("./status.summary.runtime.js"); + const { statusSummaryRuntime } = await import("../status/summary.runtime.js"); const cfg = { agents: { defaults: { diff --git a/src/commands/status.summary.runtime.test.ts b/src/commands/status.summary.runtime.test.ts index 7be67243b9ae..1eac518c90c4 100644 --- a/src/commands/status.summary.runtime.test.ts +++ b/src/commands/status.summary.runtime.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest"; import { ANTHROPIC_CONTEXT_1M_TOKENS } from "../agents/context-resolution.js"; import { migratePersistedImplicitMainRoster } from "../config/legacy.roster.js"; -import { statusSummaryRuntime } from "./status.summary.runtime.js"; +import { statusSummaryRuntime } from "../status/summary.runtime.js"; function resolveSessionRuntimeLabel( params: Parameters[0], diff --git a/src/commands/status.summary.test.ts b/src/commands/status.summary.test.ts index 92dab122fae7..ac10fa707bdb 100644 --- a/src/commands/status.summary.test.ts +++ b/src/commands/status.summary.test.ts @@ -70,7 +70,7 @@ vi.mock("../plugins/channel-plugin-ids.js", () => ({ hasConfiguredChannelsForReadOnlyScope: statusSummaryMocks.hasConfiguredChannelsForReadOnlyScope, })); -vi.mock("./status.summary.runtime.js", () => ({ +vi.mock("../status/summary.runtime.js", () => ({ statusSummaryRuntime: { classifySessionKey: vi.fn(() => "direct"), resolveConfiguredStatusModelRef: vi.fn(() => ({ @@ -185,16 +185,16 @@ vi.mock("../version.js", async () => { }; }); -vi.mock("./status.link-channel.js", () => ({ +vi.mock("../status/link-channel.js", () => ({ resolveLinkChannelContext: vi.fn(async () => undefined), })); const { buildChannelSummary } = await import("../infra/channel-summary.js"); const { resolveStorePath } = await import("../config/sessions/paths.js"); const { listGatewayAgentsBasic } = await import("../gateway/agent-list.js"); -const { resolveLinkChannelContext } = await import("./status.link-channel.js"); -let getStatusSummary: typeof import("./status.summary.js").getStatusSummary; -let statusSummaryRuntime: typeof import("./status.summary.runtime.js").statusSummaryRuntime; +const { resolveLinkChannelContext } = await import("../status/link-channel.js"); +let getStatusSummary: typeof import("../status/summary.js").getStatusSummary; +let statusSummaryRuntime: typeof import("../status/summary.runtime.js").statusSummaryRuntime; function toSessionEntrySummaries(store: Record>) { return Object.entries(store).map(([sessionKey, entry]) => ({ sessionKey, entry })); @@ -202,8 +202,8 @@ function toSessionEntrySummaries(store: Record>) describe("getStatusSummary", () => { beforeAll(async () => { - ({ getStatusSummary } = await import("./status.summary.js")); - ({ statusSummaryRuntime } = await import("./status.summary.runtime.js")); + ({ getStatusSummary } = await import("../status/summary.js")); + ({ statusSummaryRuntime } = await import("../status/summary.runtime.js")); }); beforeEach(() => { diff --git a/src/commands/status.test-support.ts b/src/commands/status.test-support.ts index e9c2897c230e..f47552bcc24b 100644 --- a/src/commands/status.test-support.ts +++ b/src/commands/status.test-support.ts @@ -3,13 +3,13 @@ import type { HeartbeatEventPayload } from "../infra/heartbeat-events.js"; import { isBetaTag } from "../infra/update-channels.js"; import type { Tone } from "../memory-host-sdk/status.js"; import type { PluginCompatibilityNotice } from "../plugins/status.js"; +import type { StatusSummary } from "../status/types.js"; import { VERSION } from "../version.js"; import type { buildStatusCommandOverviewRows } from "./status-overview-rows.ts"; import type { StatusOverviewSurface } from "./status-overview-surface.ts"; import type { AgentLocalStatus } from "./status.agent-local.js"; import type { buildStatusCommandReportData } from "./status.command-report-data.ts"; import type { MemoryPluginStatus, MemoryStatusSnapshot } from "./status.scan.shared.js"; -import type { StatusSummary } from "./status.types.js"; type StatusCommandOverviewRowsParams = Parameters[0]; type StatusCommandReportDataParams = Parameters[0]; diff --git a/src/commands/status.ts b/src/commands/status.ts index 4fe749e3a60b..e0319d5bd6e8 100644 --- a/src/commands/status.ts +++ b/src/commands/status.ts @@ -2,4 +2,4 @@ // Exposes the command and summary builder without importing implementation details. export { statusCommand } from "./status.command.js"; -export { getStatusSummary } from "./status.summary.js"; +export { getStatusSummary } from "../status/summary.js"; diff --git a/src/flows/doctor-health-contribution-types.ts b/src/flows/doctor-health-contribution-types.ts index f3dd8786088d..5d8bdc776b6c 100644 --- a/src/flows/doctor-health-contribution-types.ts +++ b/src/flows/doctor-health-contribution-types.ts @@ -40,7 +40,7 @@ export type DoctorHealthFlowContext = { healthOk?: boolean; gatewayHealthAuthenticated?: boolean; gatewayHealthSkipped?: boolean; - gatewayStatus?: import("../commands/status.types.js").StatusSummary; + gatewayStatus?: import("../status/types.js").StatusSummary; gatewayMemoryProbe?: Awaited>; postInstallDoctorResult?: UpdatePostInstallDoctorResult; }; diff --git a/src/flows/doctor-health-contributions-final.ts b/src/flows/doctor-health-contributions-final.ts index ad1d3244f199..cd5c5200046e 100644 --- a/src/flows/doctor-health-contributions-final.ts +++ b/src/flows/doctor-health-contributions-final.ts @@ -314,7 +314,7 @@ export function resolveFinalDoctorHealthContributions(params: { async detect(ctx) { const { collectWhatsappResponsivenessHealthFindings } = await import("../commands/doctor-whatsapp-responsiveness.js"); - let status: import("../commands/status.types.js").StatusSummary | undefined; + let status: import("../status/types.js").StatusSummary | undefined; if ( !( (await hasActiveGatewayExecCredential({ cfg: ctx.cfg })) && @@ -322,7 +322,7 @@ export function resolveFinalDoctorHealthContributions(params: { ) ) { const { callGateway } = await import("../gateway/call.js"); - status = await callGateway({ + status = await callGateway({ method: "status", params: { includeChannelSummary: false }, timeoutMs: 3000, diff --git a/src/gateway/server-methods/health.ts b/src/gateway/server-methods/health.ts index 71b46c1ce020..4d356751d81f 100644 --- a/src/gateway/server-methods/health.ts +++ b/src/gateway/server-methods/health.ts @@ -4,8 +4,8 @@ import { ErrorCodes, errorShape } from "../../../packages/gateway-protocol/src/i import type { ChannelAccountSnapshot } from "../../channels/plugins/types.public.js"; import { buildDeliveryQueueHealthSummary } from "../../commands/health.js"; import type { ChannelHealthSummary, HealthSummary } from "../../commands/health.types.js"; -import { getStatusSummary } from "../../commands/status.js"; import { listContextEngineQuarantines } from "../../context-engine/registry.js"; +import { getStatusSummary } from "../../status/summary.js"; import type { GatewayHotReloadStatus } from "../config-reload-status.types.js"; import type { ChannelRuntimeSnapshot } from "../server-channel-runtime.types.js"; import { HEALTH_REFRESH_INTERVAL_MS } from "../server-constants.js"; diff --git a/src/gateway/server-methods/server-methods.test.ts b/src/gateway/server-methods/server-methods.test.ts index 667a0f2bdc3a..04b87d772b17 100644 --- a/src/gateway/server-methods/server-methods.test.ts +++ b/src/gateway/server-methods/server-methods.test.ts @@ -54,7 +54,7 @@ function waitForFast( const AGENT_RUN_CACHE_ENTRY_LIMIT = 5_000; -vi.mock("../../commands/status.js", () => ({ +vi.mock("../../status/summary.js", () => ({ getStatusSummary: vi.fn().mockResolvedValue({ ok: true }), })); @@ -4733,11 +4733,11 @@ describe("exec approval handlers", () => { }); describe("gateway healthHandlers.status scope handling", () => { - let statusModule: typeof import("../../commands/status.js"); + let statusModule: typeof import("../../status/summary.js"); let healthHandlers: typeof import("./health.js").healthHandlers; beforeAll(async () => { - statusModule = await import("../../commands/status.js"); + statusModule = await import("../../status/summary.js"); ({ healthHandlers } = await import("./health.js")); }); diff --git a/src/gateway/test-helpers.mocks.ts b/src/gateway/test-helpers.mocks.ts index 707174d3cab7..b3d9f32c3c3a 100644 --- a/src/gateway/test-helpers.mocks.ts +++ b/src/gateway/test-helpers.mocks.ts @@ -244,7 +244,7 @@ vi.mock("/src/agents/embedded-agent-runner/runs.js", async () => { vi.mock("../commands/health.js", () => ({ getHealthSnapshot: vi.fn().mockResolvedValue({ ok: true, stub: true }), })); -vi.mock("../commands/status.js", () => ({ +vi.mock("../status/summary.js", () => ({ getStatusSummary: vi.fn().mockResolvedValue({ ok: true }), })); vi.mock("../commands/agent.js", () => ({ diff --git a/src/commands/status.link-channel.ts b/src/status/link-channel.ts similarity index 96% rename from src/commands/status.link-channel.ts rename to src/status/link-channel.ts index ae6c9077b9fd..1a24c9c67960 100644 --- a/src/commands/status.link-channel.ts +++ b/src/status/link-channel.ts @@ -1,11 +1,11 @@ // Resolves the first channel that can report linked/unlinked auth state for status summaries. // Channel-specific linking logic stays inside plugin status hooks. +import { resolveDefaultChannelAccountContext } from "../channels/account-context.js"; import { listReadOnlyChannelPluginsForConfig } from "../channels/plugins/read-only.js"; import type { ChannelPlugin } from "../channels/plugins/types.plugin.js"; import type { ChannelAccountSnapshot } from "../channels/plugins/types.public.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { resolveDefaultChannelAccountContext } from "./channel-account-context.js"; type LinkChannelContext = { linked: boolean; diff --git a/src/commands/status.summary.runtime.ts b/src/status/summary.runtime.ts similarity index 99% rename from src/commands/status.summary.runtime.ts rename to src/status/summary.runtime.ts index 75b5efdea314..0c383e4cc3bb 100644 --- a/src/commands/status.summary.runtime.ts +++ b/src/status/summary.runtime.ts @@ -19,7 +19,7 @@ import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.js"; import { resolveStoredSessionKeyForAgentStore } from "../gateway/session-store-key.js"; import { classifySessionKind } from "../sessions/classify-session-kind.js"; -import { resolveAgentRuntimeLabel } from "../status/agent-runtime-label.js"; +import { resolveAgentRuntimeLabel } from "./agent-runtime-label.js"; function resolveStatusModelRefFromRaw(params: { cfg: OpenClawConfig; diff --git a/src/commands/status.summary.ts b/src/status/summary.ts similarity index 99% rename from src/commands/status.summary.ts rename to src/status/summary.ts index 536a651f2d63..29d88f870387 100644 --- a/src/commands/status.summary.ts +++ b/src/status/summary.ts @@ -32,7 +32,7 @@ import { summarizeRetainedLostTaskAuditFindings, } from "../tasks/task-registry.audit.js"; import { resolveRuntimeServiceVersion } from "../version.js"; -import type { HeartbeatStatus, SessionStatus, StatusSummary } from "./status.types.js"; +import type { HeartbeatStatus, SessionStatus, StatusSummary } from "./types.js"; const RECENT_SESSION_LIMIT = 10; @@ -42,7 +42,7 @@ const channelSummaryModuleLoader = createLazyImportLoader( const channelPluginIdsModuleLoader = createLazyImportLoader( () => import("../plugins/channel-plugin-ids.js"), ); -const linkChannelModuleLoader = createLazyImportLoader(() => import("./status.link-channel.js")); +const linkChannelModuleLoader = createLazyImportLoader(() => import("./link-channel.js")); const taskRegistryMaintenanceModuleLoader = createLazyImportLoader( () => import("../tasks/task-registry.maintenance.js"), ); @@ -70,7 +70,7 @@ function loadLinkChannelModule() { } const loadStatusSummaryRuntimeModule = createLazyRuntimeSurface( - () => import("./status.summary.runtime.js"), + () => import("./summary.runtime.js"), ({ statusSummaryRuntime }) => statusSummaryRuntime, ); diff --git a/src/commands/status.types.ts b/src/status/types.ts similarity index 100% rename from src/commands/status.types.ts rename to src/status/types.ts diff --git a/test/scripts/check-session-accessor-boundary.test.ts b/test/scripts/check-session-accessor-boundary.test.ts index 6a16e715f3e5..05d9658b3b5f 100644 --- a/test/scripts/check-session-accessor-boundary.test.ts +++ b/test/scripts/check-session-accessor-boundary.test.ts @@ -80,7 +80,7 @@ describe("session accessor boundary guard", () => { "src/commands/sessions-tail.ts", "src/commands/sessions.ts", "src/commands/status.agent-local.ts", - "src/commands/status.summary.ts", + "src/status/summary.ts", "src/commands/tasks.ts", "src/config/sessions/combined-store-gateway.ts", "src/config/sessions/delivery-info.ts", diff --git a/tsdown.config.ts b/tsdown.config.ts index 26f261a8ae40..863fc4ceef77 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -298,7 +298,7 @@ function buildCoreDistEntries(): Record { "media-understanding/apply.runtime": "src/media-understanding/apply.runtime.ts", "commands/doctor/shared/plugin-registry-migration": "src/commands/doctor/shared/plugin-registry-migration.ts", - "commands/status.summary.runtime": "src/commands/status.summary.runtime.ts", + "commands/status.summary.runtime": "src/status/summary.runtime.ts", "infra/boundary-file-read": "src/infra/boundary-file-read.ts", "plugins/provider-discovery.runtime": "src/plugins/provider-discovery.runtime.ts", "plugins/provider-runtime.runtime": "src/plugins/provider-runtime.runtime.ts",