diff --git a/scripts/deadcode-exports.baseline.mjs b/scripts/deadcode-exports.baseline.mjs index 2fe24940a073..1ade685b60cf 100644 --- a/scripts/deadcode-exports.baseline.mjs +++ b/scripts/deadcode-exports.baseline.mjs @@ -1339,8 +1339,6 @@ export const KNIP_UNUSED_EXPORT_BASELINE = [ "src/cli/update-cli/update-command-service.ts: shouldUseLegacyProcessRestartAfterUpdate", "src/commands/audit.ts: testApi", "src/commands/auth-choice-options.ts: buildAuthChoiceOptions", - "src/commands/auth-choice.model-check.ts: DefaultModelAuthStatus", - "src/commands/auth-choice.model-check.ts: DefaultModelCatalogFacts", "src/commands/backup-shared.ts: encodeAbsolutePathForBackupArchive", "src/commands/backup-shared.ts: formatBackupArchiveTimestamp", "src/commands/backup-shared.ts: resolveBackupPlanFromPaths", @@ -1364,7 +1362,6 @@ export const KNIP_UNUSED_EXPORT_BASELINE = [ "src/commands/doctor-sandbox.ts: resolveSandboxScript", "src/commands/doctor-session-snapshots.ts: resolveSessionSnapshotBundledSkillsDir", "src/commands/doctor-session-snapshots.ts: scanSessionStoreForStaleRuntimeSnapshotPaths", - "src/commands/doctor-session-sqlite-migration-run.ts: SessionSqliteMigrationManifest", "src/commands/doctor-session-state-providers.ts: applySessionRouteStateRepair", "src/commands/doctor-session-state-providers.ts: resolveConfiguredDoctorSessionStateRoute", "src/commands/doctor-session-state-providers.ts: scanSessionRouteStateOwners", @@ -1372,8 +1369,6 @@ export const KNIP_UNUSED_EXPORT_BASELINE = [ "src/commands/doctor-session-transcripts.ts: repairBrokenSessionTranscriptFile", "src/commands/doctor-skills.ts: describeGhConfigDirHintFromDiscovery", "src/commands/doctor-skills.ts: formatUnavailableSkillDoctorLines", - "src/commands/doctor-state-sqlite-compact.ts: DoctorStateSqliteCompactReport", - "src/commands/doctor-ui.ts: UiProtocolFreshnessIssue", "src/commands/doctor-whatsapp-responsiveness.ts: listLocalTuiProcesses", "src/commands/doctor-whatsapp-responsiveness.ts: terminateLocalTuiProcesses", "src/commands/doctor/cron/legacy-delivery.ts: buildDeliveryFromLegacyPayload", @@ -1396,11 +1391,6 @@ export const KNIP_UNUSED_EXPORT_BASELINE = [ "src/commands/doctor/shared/release-configured-plugin-installs.ts: shouldRunConfiguredPluginInstallReleaseStep", "src/commands/doctor/shared/stale-auth-order.ts: repairStaleConfiguredAuthOrders", "src/commands/doctor/shared/stale-oauth-profile-shadows.ts: testing", - "src/commands/migrate/selection.ts: MIGRATION_PLUGIN_NOT_SELECTED_REASON", - "src/commands/migrate/selection.ts: MIGRATION_SKILL_NOT_SELECTED_REASON", - "src/commands/migrate/selection.ts: MIGRATION_SKILL_SELECTION_ACCEPT", - "src/commands/migrate/selection.ts: MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF", - "src/commands/migrate/selection.ts: MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON", "src/commands/onboard-inference.ts: detectNativeCodexAppServer", "src/commands/onboard-non-interactive/local.ts: resolveGatewayHealthProbeToken", "src/commands/onboard-non-interactive/local.ts: resolveInstallDaemonGatewayHealthTiming", @@ -1413,8 +1403,6 @@ export const KNIP_UNUSED_EXPORT_BASELINE = [ "src/commands/sessions-tail.ts: setSessionsTailFollowIntervalMsForTests", "src/commands/sessions.ts: testing", "src/commands/status.command.ts: resolvePairingRecoveryContext", - "src/commands/status.scan.config-shared.ts: resolveStatusScanColdStart", - "src/commands/status.scan.config-shared.ts: shouldSkipStatusScanMissingConfigFastPath", "src/commitments/extraction.ts: validateCommitmentCandidates", "src/commitments/runtime.ts: configureCommitmentExtractionRuntime", "src/commitments/runtime.ts: drainCommitmentExtractionQueue", diff --git a/src/commands/auth-choice.model-check.ts b/src/commands/auth-choice.model-check.ts index db66796b7c01..aef5b64a6835 100644 --- a/src/commands/auth-choice.model-check.ts +++ b/src/commands/auth-choice.model-check.ts @@ -16,7 +16,7 @@ type ModelRouteObservation = { baseUrl?: unknown; }; -export type DefaultModelAuthStatus = { +type DefaultModelAuthStatus = { provider: string; model: string; } & ( @@ -112,7 +112,7 @@ function catalogRouteObservation( }; } -export type DefaultModelCatalogFacts = { +type DefaultModelCatalogFacts = { found: boolean; observedRoutes?: readonly ModelRouteObservation[]; }; diff --git a/src/commands/doctor-session-sqlite-migration-run.ts b/src/commands/doctor-session-sqlite-migration-run.ts index 427e7d17c735..073446bc6dcd 100644 --- a/src/commands/doctor-session-sqlite-migration-run.ts +++ b/src/commands/doctor-session-sqlite-migration-run.ts @@ -39,7 +39,7 @@ type SessionSqliteMigrationTargetManifest = SessionSqliteMigrationTargetInput & validationBeforeArchive: "not_run" | "passed" | "failed"; }; -export type SessionSqliteMigrationManifest = { +type SessionSqliteMigrationManifest = { completedAt?: string; failedAt?: string; failureReports?: { diff --git a/src/commands/doctor-session-sqlite.test.ts b/src/commands/doctor-session-sqlite.test.ts index 353ca86436e3..2dcb3d60d6bd 100644 --- a/src/commands/doctor-session-sqlite.test.ts +++ b/src/commands/doctor-session-sqlite.test.ts @@ -24,11 +24,13 @@ import { closeOpenClawStateDatabaseForTest } from "../state/openclaw-state-db.js import { assertSafeSessionSqliteMigrationMove, restoreSessionSqliteMigrationRun, - type SessionSqliteMigrationManifest, + type ActiveSessionSqliteMigrationRun, } from "./doctor-session-sqlite-migration-run.js"; import { resolveTargetSqlitePath } from "./doctor-session-sqlite-readers.js"; import { runDoctorSessionSqlite } from "./doctor-session-sqlite.js"; +type SessionSqliteMigrationManifest = ActiveSessionSqliteMigrationRun["manifest"]; + type TestStore = { configPath: string; env: NodeJS.ProcessEnv; diff --git a/src/commands/doctor-state-sqlite-compact.test.ts b/src/commands/doctor-state-sqlite-compact.test.ts index 74c596b083ae..89ed40a55777 100644 --- a/src/commands/doctor-state-sqlite-compact.test.ts +++ b/src/commands/doctor-state-sqlite-compact.test.ts @@ -11,10 +11,7 @@ import { } from "../state/openclaw-state-db.js"; import { resolveOpenClawStateSqlitePath } from "../state/openclaw-state-db.paths.js"; import { OPENCLAW_STATE_SCHEMA_SQL } from "../state/openclaw-state-schema.generated.js"; -import { - type DoctorStateSqliteCompactReport, - runDoctorStateSqliteCompact, -} from "./doctor-state-sqlite-compact.js"; +import { runDoctorStateSqliteCompact } from "./doctor-state-sqlite-compact.js"; const tempDirs = useAutoCleanupTempDirTracker((cleanup) => { afterEach(() => { @@ -22,6 +19,7 @@ const tempDirs = useAutoCleanupTempDirTracker((cleanup) => { cleanup(); }); }); +type DoctorStateSqliteCompactReport = Awaited>; type CompletedStateSqliteCompactReport = Extract< DoctorStateSqliteCompactReport, { skipped: false } diff --git a/src/commands/doctor-state-sqlite-compact.ts b/src/commands/doctor-state-sqlite-compact.ts index 555ca4ba8c2d..33d2d024aeec 100644 --- a/src/commands/doctor-state-sqlite-compact.ts +++ b/src/commands/doctor-state-sqlite-compact.ts @@ -12,7 +12,7 @@ import { } from "./doctor-sqlite-compact.js"; import { withDoctorSqliteMaintenanceLock } from "./doctor-sqlite-maintenance-lock.js"; -export type DoctorStateSqliteCompactReport = +type DoctorStateSqliteCompactReport = | { mode: "compact"; path: string; diff --git a/src/commands/doctor-ui.test.ts b/src/commands/doctor-ui.test.ts index e3e09f6c1c85..3587f15f73d7 100644 --- a/src/commands/doctor-ui.test.ts +++ b/src/commands/doctor-ui.test.ts @@ -7,10 +7,10 @@ import { detectUiProtocolFreshnessIssues, uiProtocolFreshnessIssueToHealthFinding, uiProtocolFreshnessIssueToRepairEffects, - type UiProtocolFreshnessIssue, } from "./doctor-ui.js"; const tempRoots: string[] = []; +type UiProtocolFreshnessIssue = Awaited>[number]; function issue(overrides: Partial = {}): UiProtocolFreshnessIssue { return { diff --git a/src/commands/doctor-ui.ts b/src/commands/doctor-ui.ts index 67b51abd8d88..b8abec904778 100644 --- a/src/commands/doctor-ui.ts +++ b/src/commands/doctor-ui.ts @@ -12,7 +12,7 @@ import { runCommandWithTimeout } from "../process/exec.js"; import type { RuntimeEnv } from "../runtime.js"; import type { DoctorPrompter } from "./doctor-prompter.js"; -export type UiProtocolFreshnessIssue = +type UiProtocolFreshnessIssue = | { readonly kind: "missing-assets"; readonly root: string; diff --git a/src/commands/migrate.test.ts b/src/commands/migrate.test.ts index 999aedc2a203..11c3ac91b496 100644 --- a/src/commands/migrate.test.ts +++ b/src/commands/migrate.test.ts @@ -71,9 +71,9 @@ vi.mock("./backup.js", () => ({ })); const { - MIGRATION_SKILL_SELECTION_ACCEPT, - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, + MIGRATION_SELECTION_ACCEPT, + MIGRATION_SELECTION_TOGGLE_ALL_OFF, + MIGRATION_SELECTION_TOGGLE_ALL_ON, } = await import("./migrate/selection.js"); const { migrateApplyCommand, migrateDefaultCommand, migratePlanCommand } = await import("./migrate.js"); @@ -685,11 +685,11 @@ describe("migrateApplyCommand", () => { expect(selectionPrompt.initialValues).toStrictEqual(["skill:alpha", "skill:beta"]); expect(selectionPrompt.required).toBe(false); expect(selectionPrompt.options?.map(({ label, value }) => ({ label, value }))).toStrictEqual([ - { value: MIGRATION_SKILL_SELECTION_ACCEPT, label: "Accept recommended" }, + { value: MIGRATION_SELECTION_ACCEPT, label: "Accept recommended" }, { value: "skill:alpha", label: "alpha" }, { value: "skill:beta", label: "beta" }, - { value: MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, label: "Toggle all on" }, - { value: MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, label: "Toggle all off" }, + { value: MIGRATION_SELECTION_TOGGLE_ALL_ON, label: "Toggle all on" }, + { value: MIGRATION_SELECTION_TOGGLE_ALL_OFF, label: "Toggle all off" }, ]); expect(mocks.promptYesNo).toHaveBeenCalledWith("Apply this migration now?", false); const appliedPlan = firstAppliedPlan(); @@ -745,11 +745,11 @@ describe("migrateApplyCommand", () => { expect(pluginPrompt.initialValues).toStrictEqual(["plugin:google-calendar", "plugin:gmail"]); expect(pluginPrompt.required).toBe(false); expect(pluginPrompt.options?.map(({ label, value }) => ({ label, value }))).toStrictEqual([ - { value: MIGRATION_SKILL_SELECTION_ACCEPT, label: "Accept recommended" }, + { value: MIGRATION_SELECTION_ACCEPT, label: "Accept recommended" }, { value: "plugin:google-calendar", label: "google-calendar" }, { value: "plugin:gmail", label: "gmail" }, - { value: MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, label: "Toggle all on" }, - { value: MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, label: "Toggle all off" }, + { value: MIGRATION_SELECTION_TOGGLE_ALL_ON, label: "Toggle all on" }, + { value: MIGRATION_SELECTION_TOGGLE_ALL_OFF, label: "Toggle all off" }, ]); expect(mocks.promptYesNo).toHaveBeenCalledWith("Apply this migration now?", false); const appliedPlan = firstAppliedPlan(); @@ -799,7 +799,7 @@ describe("migrateApplyCommand", () => { }); mocks.provider.plan.mockResolvedValue(planned); mocks.multiselect - .mockResolvedValueOnce([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF]) + .mockResolvedValueOnce([MIGRATION_SELECTION_TOGGLE_ALL_OFF]) .mockResolvedValueOnce(["plugin:google-calendar", "plugin:gmail"]); mocks.promptYesNo.mockResolvedValue(true); mocks.provider.apply.mockImplementation(async (_ctx, selectedPlan: MigrationPlan) => ({ @@ -900,7 +900,7 @@ describe("migrateApplyCommand", () => { }); const planned = codexPluginPlan(); mocks.provider.plan.mockResolvedValue(planned); - mocks.multiselect.mockResolvedValue([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF]); + mocks.multiselect.mockResolvedValue([MIGRATION_SELECTION_TOGGLE_ALL_OFF]); const result = await migrateDefaultCommand(runtime, { provider: "codex" }); @@ -1016,7 +1016,7 @@ describe("migrateApplyCommand", () => { }); const planned = codexSkillPlan(); mocks.provider.plan.mockResolvedValue(planned); - mocks.multiselect.mockResolvedValue([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF]); + mocks.multiselect.mockResolvedValue([MIGRATION_SELECTION_TOGGLE_ALL_OFF]); const result = await migrateDefaultCommand(runtime, { provider: "codex" }); @@ -1044,7 +1044,7 @@ describe("migrateApplyCommand", () => { }); const planned = codexSkillPlan(); mocks.provider.plan.mockResolvedValue(planned); - mocks.multiselect.mockResolvedValue([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON]); + mocks.multiselect.mockResolvedValue([MIGRATION_SELECTION_TOGGLE_ALL_ON]); mocks.promptYesNo.mockResolvedValue(true); mocks.provider.apply.mockImplementation(async (_ctx, selectedPlan: MigrationPlan) => ({ ...selectedPlan, @@ -1063,8 +1063,8 @@ describe("migrateApplyCommand", () => { mocks.provider.plan.mockResolvedValue(planned); mocks.multiselect.mockResolvedValue([ - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, + MIGRATION_SELECTION_TOGGLE_ALL_ON, + MIGRATION_SELECTION_TOGGLE_ALL_OFF, ]); mocks.promptYesNo.mockResolvedValue(true); mocks.provider.apply.mockClear(); diff --git a/src/commands/migrate/selection.test.ts b/src/commands/migrate/selection.test.ts index 684924c9d38c..9f96f821fcd6 100644 --- a/src/commands/migrate/selection.test.ts +++ b/src/commands/migrate/selection.test.ts @@ -12,10 +12,8 @@ import { getDefaultMigrationPluginSelectionValues, getSelectableMigrationPluginItems, getDefaultMigrationSkillSelectionValues, - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, - MIGRATION_PLUGIN_NOT_SELECTED_REASON, - MIGRATION_SKILL_NOT_SELECTED_REASON, + MIGRATION_SELECTION_TOGGLE_ALL_OFF, + MIGRATION_SELECTION_TOGGLE_ALL_ON, reconcileInteractiveMigrationEnterValues, reconcileInteractiveMigrationShortcutValues, reconcileInteractiveMigrationSkillToggleValues, @@ -23,6 +21,8 @@ import { resolveInteractiveMigrationSkillSelection, } from "./selection.js"; +const MIGRATION_NOT_SELECTED_REASON = "not selected for migration"; + function skillItem(params: { id: string; name: string; @@ -197,7 +197,7 @@ describe("applyMigrationSkillSelection", () => { conflicts: 0, }); expectItemStatus(selected.items, "skill:alpha", "planned"); - expectItemStatus(selected.items, "skill:beta", "skipped", MIGRATION_SKILL_NOT_SELECTED_REASON); + expectItemStatus(selected.items, "skill:beta", "skipped", MIGRATION_NOT_SELECTED_REASON); expectItemStatus(selected.items, "archive:config.toml", "planned"); }); @@ -227,7 +227,7 @@ describe("applyMigrationSkillSelection", () => { expect(selected.summary.conflicts).toBe(0); expectItemStatus(selected.items, "skill:alpha", "planned"); - expectItemStatus(selected.items, "skill:beta", "skipped", MIGRATION_SKILL_NOT_SELECTED_REASON); + expectItemStatus(selected.items, "skill:beta", "skipped", MIGRATION_NOT_SELECTED_REASON); }); it("allows interactive selection to choose no skills", () => { @@ -270,12 +270,12 @@ describe("applyMigrationSkillSelection", () => { expect( resolveInteractiveMigrationSkillSelection(items, [ - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, + MIGRATION_SELECTION_TOGGLE_ALL_ON, + MIGRATION_SELECTION_TOGGLE_ALL_OFF, ]), ).toEqual({ action: "select", selectedItemIds: new Set() }); expect( - resolveInteractiveMigrationSkillSelection(items, [MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON]), + resolveInteractiveMigrationSkillSelection(items, [MIGRATION_SELECTION_TOGGLE_ALL_ON]), ).toEqual({ action: "select", selectedItemIds: new Set(["skill:alpha", "skill:beta"]), @@ -287,28 +287,28 @@ describe("applyMigrationSkillSelection", () => { expect( reconcileInteractiveMigrationSkillToggleValues( - [MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON], - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, + [MIGRATION_SELECTION_TOGGLE_ALL_ON], + MIGRATION_SELECTION_TOGGLE_ALL_ON, selectable, ), - ).toEqual([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, "skill:alpha", "skill:beta"]); + ).toEqual([MIGRATION_SELECTION_TOGGLE_ALL_ON, "skill:alpha", "skill:beta"]); expect( reconcileInteractiveMigrationSkillToggleValues( [ - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, + MIGRATION_SELECTION_TOGGLE_ALL_ON, "skill:alpha", "skill:beta", - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, + MIGRATION_SELECTION_TOGGLE_ALL_OFF, ], - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, + MIGRATION_SELECTION_TOGGLE_ALL_OFF, selectable, ), - ).toEqual([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF]); + ).toEqual([MIGRATION_SELECTION_TOGGLE_ALL_OFF]); expect( reconcileInteractiveMigrationSkillToggleValues( - [MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, "skill:alpha"], + [MIGRATION_SELECTION_TOGGLE_ALL_OFF, "skill:alpha"], "skill:alpha", selectable, ), @@ -318,24 +318,24 @@ describe("applyMigrationSkillSelection", () => { reconcileInteractiveMigrationShortcutValues( ["skill:alpha", "skill:beta"], [ - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, + MIGRATION_SELECTION_TOGGLE_ALL_ON, + MIGRATION_SELECTION_TOGGLE_ALL_OFF, "skill:alpha", "skill:beta", ], selectable, "a", ), - ).toEqual([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF]); + ).toEqual([MIGRATION_SELECTION_TOGGLE_ALL_OFF]); expect( reconcileInteractiveMigrationShortcutValues( - [MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF], - [MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON], + [MIGRATION_SELECTION_TOGGLE_ALL_OFF], + [MIGRATION_SELECTION_TOGGLE_ALL_OFF, MIGRATION_SELECTION_TOGGLE_ALL_ON], selectable, "i", ), - ).toEqual([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF]); + ).toEqual([MIGRATION_SELECTION_TOGGLE_ALL_OFF]); }); it("reconciles enter as activating the cursor row without toggling it off", () => { @@ -344,18 +344,18 @@ describe("applyMigrationSkillSelection", () => { expect( reconcileInteractiveMigrationEnterValues( ["skill:alpha"], - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, + MIGRATION_SELECTION_TOGGLE_ALL_ON, selectable, ), - ).toEqual([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, "skill:alpha", "skill:beta"]); + ).toEqual([MIGRATION_SELECTION_TOGGLE_ALL_ON, "skill:alpha", "skill:beta"]); expect( reconcileInteractiveMigrationEnterValues( ["skill:alpha"], - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, + MIGRATION_SELECTION_TOGGLE_ALL_OFF, selectable, ), - ).toEqual([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF]); + ).toEqual([MIGRATION_SELECTION_TOGGLE_ALL_OFF]); expect( reconcileInteractiveMigrationEnterValues(["skill:alpha"], "skill:beta", selectable), @@ -402,12 +402,7 @@ describe("applyMigrationPluginSelection", () => { expectSummaryFields(selected.summary, { planned: 2, skipped: 1, conflicts: 0 }); expectItemStatus(selected.items, "plugin:google-calendar", "planned"); - expectItemStatus( - selected.items, - "plugin:gmail", - "skipped", - MIGRATION_PLUGIN_NOT_SELECTED_REASON, - ); + expectItemStatus(selected.items, "plugin:gmail", "skipped", MIGRATION_NOT_SELECTED_REASON); const configItem = requireItem(selected.items, "config:codex-plugins"); expect(configItem.status).toBe("planned"); const plugins = requireCodexPluginConfigPlugins(configItem); @@ -434,19 +429,14 @@ describe("applyMigrationPluginSelection", () => { selected.items, "plugin:google-calendar", "skipped", - MIGRATION_PLUGIN_NOT_SELECTED_REASON, - ); - expectItemStatus( - selected.items, - "plugin:gmail", - "skipped", - MIGRATION_PLUGIN_NOT_SELECTED_REASON, + MIGRATION_NOT_SELECTED_REASON, ); + expectItemStatus(selected.items, "plugin:gmail", "skipped", MIGRATION_NOT_SELECTED_REASON); expectItemStatus( selected.items, "config:codex-plugins", "skipped", - MIGRATION_PLUGIN_NOT_SELECTED_REASON, + MIGRATION_NOT_SELECTED_REASON, ); }); @@ -506,12 +496,12 @@ describe("applyMigrationPluginSelection", () => { expect( resolveInteractiveMigrationPluginSelection(items, [ - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, + MIGRATION_SELECTION_TOGGLE_ALL_ON, + MIGRATION_SELECTION_TOGGLE_ALL_OFF, ]), ).toEqual({ action: "select", selectedItemIds: new Set() }); expect( - resolveInteractiveMigrationPluginSelection(items, [MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON]), + resolveInteractiveMigrationPluginSelection(items, [MIGRATION_SELECTION_TOGGLE_ALL_ON]), ).toEqual({ action: "select", selectedItemIds: new Set(["plugin:google-calendar", "plugin:gmail"]), diff --git a/src/commands/migrate/selection.ts b/src/commands/migrate/selection.ts index 2272cbf4c53e..fd95fd6b6d0a 100644 --- a/src/commands/migrate/selection.ts +++ b/src/commands/migrate/selection.ts @@ -8,15 +8,11 @@ import { markMigrationItemSkipped, summarizeMigrationItems } from "../../plugin- import type { MigrationItem, MigrationPlan } from "../../plugins/types.js"; import { MIGRATION_CONFLICT_REASON_PHRASES } from "./output.js"; -// Public selection tokens and skip reasons shared with prompt tests and apply filtering. -export const MIGRATION_SKILL_NOT_SELECTED_REASON = "not selected for migration"; -export const MIGRATION_PLUGIN_NOT_SELECTED_REASON = "not selected for migration"; +// Selection tokens are shared with the command and prompt implementations. +const MIGRATION_NOT_SELECTED_REASON = "not selected for migration"; export const MIGRATION_SELECTION_ACCEPT = "__openclaw_migrate_accept_recommended__"; export const MIGRATION_SELECTION_TOGGLE_ALL_ON = "__openclaw_migrate_toggle_all_on__"; export const MIGRATION_SELECTION_TOGGLE_ALL_OFF = "__openclaw_migrate_toggle_all_off__"; -export const MIGRATION_SKILL_SELECTION_ACCEPT = MIGRATION_SELECTION_ACCEPT; -export const MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON = MIGRATION_SELECTION_TOGGLE_ALL_ON; -export const MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF = MIGRATION_SELECTION_TOGGLE_ALL_OFF; type InteractiveMigrationSelection = { action: "select"; selectedItemIds: Set }; /** Interactive skill selection result consumed by the apply flow. */ @@ -274,7 +270,7 @@ export function applyMigrationSelectedSkillItemIds( if (!selectableIds.has(item.id) || selectedItemIds.has(item.id)) { return item; } - return markMigrationItemSkipped(item, MIGRATION_SKILL_NOT_SELECTED_REASON); + return markMigrationItemSkipped(item, MIGRATION_NOT_SELECTED_REASON); }); return { ...plan, @@ -329,7 +325,7 @@ export function applyMigrationSelectedPluginItemIds( if (!selectableIds.has(item.id) || selectedItemIds.has(item.id)) { return item; } - return markMigrationItemSkipped(item, MIGRATION_PLUGIN_NOT_SELECTED_REASON); + return markMigrationItemSkipped(item, MIGRATION_NOT_SELECTED_REASON); }); return { ...plan, @@ -377,7 +373,7 @@ function applyCodexPluginConfigSelection( Object.entries(codexPlugins.plugins).filter(([configKey]) => selectedConfigKeys.has(configKey)), ); if (Object.keys(plugins).length === 0) { - return markMigrationItemSkipped(item, MIGRATION_PLUGIN_NOT_SELECTED_REASON); + return markMigrationItemSkipped(item, MIGRATION_NOT_SELECTED_REASON); } return { ...item, diff --git a/src/commands/migrate/skill-selection-prompt.test.ts b/src/commands/migrate/skill-selection-prompt.test.ts index 994268370819..b6e746895d35 100644 --- a/src/commands/migrate/skill-selection-prompt.test.ts +++ b/src/commands/migrate/skill-selection-prompt.test.ts @@ -2,9 +2,9 @@ import { PassThrough, Writable } from "node:stream"; import { describe, expect, it } from "vitest"; import { - MIGRATION_SKILL_SELECTION_ACCEPT, - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, - MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, + MIGRATION_SELECTION_ACCEPT, + MIGRATION_SELECTION_TOGGLE_ALL_OFF, + MIGRATION_SELECTION_TOGGLE_ALL_ON, } from "./selection.js"; import { promptMigrationSkillSelectionValues } from "./skill-selection-prompt.js"; @@ -30,11 +30,11 @@ async function runPromptWithKeys(params: { const result = promptMigrationSkillSelectionValues({ message: "Select Codex skills", options: [ - { value: MIGRATION_SKILL_SELECTION_ACCEPT, label: "Accept recommended" }, + { value: MIGRATION_SELECTION_ACCEPT, label: "Accept recommended" }, { value: "skill:alpha", label: "alpha" }, { value: "skill:beta", label: "beta" }, - { value: MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, label: "Toggle all on" }, - { value: MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, label: "Toggle all off" }, + { value: MIGRATION_SELECTION_TOGGLE_ALL_ON, label: "Toggle all on" }, + { value: MIGRATION_SELECTION_TOGGLE_ALL_OFF, label: "Toggle all off" }, ], initialValues: params.initialValues, required: false, @@ -93,25 +93,25 @@ describe("promptMigrationSkillSelectionValues", () => { it("activates Toggle all off before submitting with return", async () => { await expect( runPromptWithReturn({ - cursorAt: MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF, + cursorAt: MIGRATION_SELECTION_TOGGLE_ALL_OFF, initialValues: ["skill:alpha", "skill:beta"], }), - ).resolves.toEqual([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_OFF]); + ).resolves.toEqual([MIGRATION_SELECTION_TOGGLE_ALL_OFF]); }); it("activates Toggle all on before submitting with return", async () => { await expect( runPromptWithReturn({ - cursorAt: MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, + cursorAt: MIGRATION_SELECTION_TOGGLE_ALL_ON, initialValues: [], }), - ).resolves.toEqual([MIGRATION_SKILL_SELECTION_TOGGLE_ALL_ON, "skill:alpha", "skill:beta"]); + ).resolves.toEqual([MIGRATION_SELECTION_TOGGLE_ALL_ON, "skill:alpha", "skill:beta"]); }); it("submits the initial recommended set when Enter is pressed on Accept recommended", async () => { await expect( runPromptWithReturn({ - cursorAt: MIGRATION_SKILL_SELECTION_ACCEPT, + cursorAt: MIGRATION_SELECTION_ACCEPT, initialValues: ["skill:alpha", "skill:beta"], }), ).resolves.toEqual(["skill:alpha", "skill:beta"]); @@ -124,7 +124,7 @@ describe("promptMigrationSkillSelectionValues", () => { // submitted value list. await expect( runPromptWithKeys({ - cursorAt: MIGRATION_SKILL_SELECTION_ACCEPT, + cursorAt: MIGRATION_SELECTION_ACCEPT, initialValues: ["skill:alpha", "skill:beta"], keys: [" ", "\r"], }), diff --git a/src/commands/status.scan.config-shared.test.ts b/src/commands/status.scan.config-shared.test.ts index cbb0332a2fc9..0ec8d908b228 100644 --- a/src/commands/status.scan.config-shared.test.ts +++ b/src/commands/status.scan.config-shared.test.ts @@ -1,11 +1,7 @@ // Status scan config tests cover scan command config loading and cold-start resolution. import { beforeEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { - loadStatusScanCommandConfig, - resolveStatusScanColdStart, - shouldSkipStatusScanMissingConfigFastPath, -} from "./status.scan.config-shared.js"; +import { loadStatusScanCommandConfig } from "./status.scan.config-shared.js"; const mocks = vi.hoisted(() => ({ resolveConfigPath: vi.fn(), @@ -23,20 +19,6 @@ describe("status.scan.config-shared", () => { ); }); - it("detects the test fast-path env toggle", () => { - expect(shouldSkipStatusScanMissingConfigFastPath({ ...process.env, VITEST: "true" })).toBe( - true, - ); - expect(shouldSkipStatusScanMissingConfigFastPath({ ...process.env, NODE_ENV: "test" })).toBe( - true, - ); - expect(shouldSkipStatusScanMissingConfigFastPath({})).toBe(false); - }); - - it("treats missing config as cold-start when fast-path bypass is disabled", () => { - expect(resolveStatusScanColdStart({ env: {}, allowMissingConfigFastPath: false })).toBe(true); - }); - it("skips read/resolve on fast-json cold-start outside tests", async () => { const readConfigSnapshot = vi.fn(async () => ({ config: { channels: { quietchat: {} } }, diff --git a/src/commands/status.scan.config-shared.ts b/src/commands/status.scan.config-shared.ts index 7037603adecc..caab70eb83f9 100644 --- a/src/commands/status.scan.config-shared.ts +++ b/src/commands/status.scan.config-shared.ts @@ -7,14 +7,12 @@ import type { OpenClawConfig } from "../config/types.js"; import { resolveGatewayAuthTokenSourceConflict } from "../gateway/auth-token-source-conflict.js"; /** Returns true when tests should avoid the missing-config cold-start fast path. */ -export function shouldSkipStatusScanMissingConfigFastPath( - env: NodeJS.ProcessEnv = process.env, -): boolean { +function shouldSkipStatusScanMissingConfigFastPath(env: NodeJS.ProcessEnv = process.env): boolean { return env.VITEST === "true" || env.VITEST_POOL_ID !== undefined || env.NODE_ENV === "test"; } /** Returns whether status should treat this run as a no-config cold start. */ -export function resolveStatusScanColdStart(params?: { +function resolveStatusScanColdStart(params?: { env?: NodeJS.ProcessEnv; allowMissingConfigFastPath?: boolean; }): boolean { diff --git a/src/wizard/setup.finalize.test.ts b/src/wizard/setup.finalize.test.ts index 0f9b7164cc6b..6904702babb2 100644 --- a/src/wizard/setup.finalize.test.ts +++ b/src/wizard/setup.finalize.test.ts @@ -3,14 +3,16 @@ import fs from "node:fs/promises"; import { expectDefined } from "@openclaw/normalization-core"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { createWizardPrompter as buildWizardPrompter } from "../../test/helpers/wizard-prompter.js"; -import type { - DefaultModelAuthStatus, - DefaultModelCatalogFacts, -} from "../commands/auth-choice.model-check.js"; +import type * as AuthChoiceModelCheck from "../commands/auth-choice.model-check.js"; import type { OpenClawConfig } from "../config/config.js"; import type { PluginWebSearchProviderEntry } from "../plugins/types.js"; import type { RuntimeEnv } from "../runtime.js"; +type DefaultModelAuthStatus = ReturnType; +type DefaultModelCatalogFacts = ReturnType< + typeof AuthChoiceModelCheck.resolveDefaultModelCatalogFacts +>; + const launchTuiCli = vi.hoisted(() => vi.fn(async () => {})); const restoreTerminalState = vi.hoisted(() => vi.fn()); const probeGatewayReachable = vi.hoisted(() =>