From fd6d3f270d2d258bf6b320fe472cc9a7b6fda52d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 7 Apr 2026 08:58:24 +0100 Subject: [PATCH] fix: repair ci lockfile and boundary drift --- .../googlechat/src/secret-contract.test.ts | 10 +- pnpm-lock.yaml | 140 +++++- scripts/lib/extension-source-classifier.mjs | 2 + src/config/io.ts | 408 +++++++++--------- src/config/io.write-config.test.ts | 7 +- src/config/io.write-prepare.test.ts | 20 +- test/extension-test-boundary.test.ts | 1 + 7 files changed, 348 insertions(+), 240 deletions(-) diff --git a/extensions/googlechat/src/secret-contract.test.ts b/extensions/googlechat/src/secret-contract.test.ts index c8cf0a3e7c1..c6d7f941526 100644 --- a/extensions/googlechat/src/secret-contract.test.ts +++ b/extensions/googlechat/src/secret-contract.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from "vitest"; +import type { OpenClawConfig } from "../../../src/config/types.js"; import { resolveSecretRefValues } from "../../../src/secrets/resolve.js"; import { applyResolvedAssignments, @@ -24,8 +25,8 @@ describe("googlechat secret contract", () => { }, }, }, - }; - const resolvedConfig = structuredClone(sourceConfig); + } satisfies OpenClawConfig; + const resolvedConfig: OpenClawConfig = structuredClone(sourceConfig); const context = createResolverContext({ sourceConfig, env: { @@ -52,9 +53,8 @@ describe("googlechat secret contract", () => { resolved, }); - expect(resolvedConfig.channels.googlechat.accounts.work.serviceAccount).toBe( - '{"client_email":"bot@example.com"}', - ); + const workAccount = resolvedConfig.channels?.googlechat?.accounts?.work; + expect(workAccount?.serviceAccount).toBe('{"client_email":"bot@example.com"}'); expect(context.warnings).toEqual([]); }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dfbadef5262..21944eb40a0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -286,7 +286,11 @@ importers: extensions/anthropic: {} - extensions/anthropic-vertex: {} + extensions/anthropic-vertex: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/arcee: {} @@ -296,7 +300,11 @@ importers: specifier: workspace:* version: link:../.. - extensions/brave: {} + extensions/brave: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/browser: {} @@ -304,15 +312,27 @@ importers: extensions/chutes: {} - extensions/cloudflare-ai-gateway: {} + extensions/cloudflare-ai-gateway: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/comfy: {} - extensions/copilot-proxy: {} + extensions/copilot-proxy: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/deepgram: {} - extensions/deepseek: {} + extensions/deepseek: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/diagnostics-otel: dependencies: @@ -349,6 +369,10 @@ importers: '@opentelemetry/semantic-conventions': specifier: ^1.40.0 version: 1.40.0 + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/diffs: dependencies: @@ -394,11 +418,19 @@ importers: specifier: ^0.10.0 version: 0.10.0 - extensions/duckduckgo: {} + extensions/duckduckgo: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/elevenlabs: {} - extensions/exa: {} + extensions/exa: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/fal: {} @@ -415,9 +447,17 @@ importers: specifier: workspace:* version: link:../.. - extensions/firecrawl: {} + extensions/firecrawl: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk - extensions/fireworks: {} + extensions/fireworks: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/github-copilot: {} @@ -437,11 +477,19 @@ importers: specifier: workspace:* version: link:../.. - extensions/groq: {} + extensions/groq: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/huggingface: {} - extensions/image-generation-core: {} + extensions/image-generation-core: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/imessage: {} @@ -457,7 +505,11 @@ importers: specifier: workspace:* version: link:../.. - extensions/litellm: {} + extensions/litellm: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/llm-task: dependencies: @@ -467,6 +519,10 @@ importers: ajv: specifier: ^8.18.0 version: 8.18.0 + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/lobster: dependencies: @@ -515,7 +571,11 @@ importers: specifier: workspace:* version: link:../.. - extensions/media-understanding-core: {} + extensions/media-understanding-core: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/memory-core: devDependencies: @@ -591,11 +651,19 @@ importers: specifier: workspace:* version: link:../.. - extensions/nvidia: {} + extensions/nvidia: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/ollama: {} - extensions/open-prose: {} + extensions/open-prose: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/openai: dependencies: @@ -611,7 +679,11 @@ importers: extensions/openshell: {} - extensions/perplexity: {} + extensions/perplexity: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/qa-channel: devDependencies: @@ -625,7 +697,11 @@ importers: specifier: workspace:* version: link:../.. - extensions/qianfan: {} + extensions/qianfan: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/qqbot: dependencies: @@ -650,7 +726,11 @@ importers: extensions/runway: {} - extensions/searxng: {} + extensions/searxng: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/sglang: {} @@ -671,9 +751,17 @@ importers: extensions/synology-chat: {} - extensions/synthetic: {} + extensions/synthetic: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk - extensions/tavily: {} + extensions/tavily: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/telegram: dependencies: @@ -720,11 +808,19 @@ importers: specifier: ^8.1.3 version: 8.1.3(@twurple/auth@8.1.3) - extensions/venice: {} + extensions/venice: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/vercel-ai-gateway: {} - extensions/video-generation-core: {} + extensions/video-generation-core: + devDependencies: + '@openclaw/plugin-sdk': + specifier: workspace:* + version: link:../../packages/plugin-sdk extensions/vllm: {} diff --git a/scripts/lib/extension-source-classifier.mjs b/scripts/lib/extension-source-classifier.mjs index 88bb3bc1a73..8efc885ab9b 100644 --- a/scripts/lib/extension-source-classifier.mjs +++ b/scripts/lib/extension-source-classifier.mjs @@ -7,6 +7,7 @@ const TEST_LIKE_SEGMENT_RE = const TEST_LIKE_FILENAME_RE = /(^|\/)[^/]*test-(?:support|helpers|fixtures|harness)\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/u; const TEST_SHARED_FILENAME_RE = /(^|\/)[^/]*\.test-[^/]*\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/u; +const TEST_CANARY_FILENAME_RE = /(^|\/)__rootdir_boundary_canary__\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/u; const SNAPSHOT_FILE_RE = /\.snap$/u; const SUFFIX_SKIP_RE = /\.(?:test|spec|fixture)\./u; const INFRA_DIR_RE = /(^|\/)(?:coverage|dist|node_modules)(?:\/|$)/u; @@ -25,6 +26,7 @@ export function classifyBundledExtensionSourcePath(filePath) { TEST_LIKE_SEGMENT_RE.test(normalizedPath) || TEST_LIKE_FILENAME_RE.test(normalizedPath) || TEST_SHARED_FILENAME_RE.test(normalizedPath) || + TEST_CANARY_FILENAME_RE.test(normalizedPath) || SUFFIX_SKIP_RE.test(normalizedPath) || SNAPSHOT_FILE_RE.test(normalizedPath) || INFRA_NAME_RE.test(normalizedPath); diff --git a/src/config/io.ts b/src/config/io.ts index 3204fd4101a..477ae788bef 100644 --- a/src/config/io.ts +++ b/src/config/io.ts @@ -609,56 +609,58 @@ async function maybeRecoverSuspiciousConfigRead(params: { fs: params.deps.fs, env: params.deps.env, homedir: params.deps.homedir, - ts: now, - source: "config-io", - event: "config.observe", - phase: "read", - configPath: params.configPath, - pid: process.pid, - ppid: process.ppid, - cwd: process.cwd(), - argv: process.argv.slice(0, 8), - execArgv: process.execArgv.slice(0, 8), - exists: true, - valid: true, - hash: current.hash, - bytes: current.bytes, - mtimeMs: current.mtimeMs, - ctimeMs: current.ctimeMs, - dev: current.dev, - ino: current.ino, - mode: current.mode, - nlink: current.nlink, - uid: current.uid, - gid: current.gid, - hasMeta: current.hasMeta, - gatewayMode: current.gatewayMode, - suspicious, - lastKnownGoodHash: entry.lastKnownGood?.hash ?? null, - lastKnownGoodBytes: entry.lastKnownGood?.bytes ?? null, - lastKnownGoodMtimeMs: entry.lastKnownGood?.mtimeMs ?? null, - lastKnownGoodCtimeMs: entry.lastKnownGood?.ctimeMs ?? null, - lastKnownGoodDev: entry.lastKnownGood?.dev ?? null, - lastKnownGoodIno: entry.lastKnownGood?.ino ?? null, - lastKnownGoodMode: entry.lastKnownGood?.mode ?? null, - lastKnownGoodNlink: entry.lastKnownGood?.nlink ?? null, - lastKnownGoodUid: entry.lastKnownGood?.uid ?? null, - lastKnownGoodGid: entry.lastKnownGood?.gid ?? null, - lastKnownGoodGatewayMode: entry.lastKnownGood?.gatewayMode ?? null, - backupHash: backup?.hash ?? null, - backupBytes: backup?.bytes ?? null, - backupMtimeMs: backup?.mtimeMs ?? null, - backupCtimeMs: backup?.ctimeMs ?? null, - backupDev: backup?.dev ?? null, - backupIno: backup?.ino ?? null, - backupMode: backup?.mode ?? null, - backupNlink: backup?.nlink ?? null, - backupUid: backup?.uid ?? null, - backupGid: backup?.gid ?? null, - backupGatewayMode: backup?.gatewayMode ?? null, - clobberedPath, - restoredFromBackup, - restoredBackupPath: backupPath, + record: { + ts: now, + source: "config-io", + event: "config.observe", + phase: "read", + configPath: params.configPath, + pid: process.pid, + ppid: process.ppid, + cwd: process.cwd(), + argv: process.argv.slice(0, 8), + execArgv: process.execArgv.slice(0, 8), + exists: true, + valid: true, + hash: current.hash, + bytes: current.bytes, + mtimeMs: current.mtimeMs, + ctimeMs: current.ctimeMs, + dev: current.dev, + ino: current.ino, + mode: current.mode, + nlink: current.nlink, + uid: current.uid, + gid: current.gid, + hasMeta: current.hasMeta, + gatewayMode: current.gatewayMode, + suspicious, + lastKnownGoodHash: entry.lastKnownGood?.hash ?? null, + lastKnownGoodBytes: entry.lastKnownGood?.bytes ?? null, + lastKnownGoodMtimeMs: entry.lastKnownGood?.mtimeMs ?? null, + lastKnownGoodCtimeMs: entry.lastKnownGood?.ctimeMs ?? null, + lastKnownGoodDev: entry.lastKnownGood?.dev ?? null, + lastKnownGoodIno: entry.lastKnownGood?.ino ?? null, + lastKnownGoodMode: entry.lastKnownGood?.mode ?? null, + lastKnownGoodNlink: entry.lastKnownGood?.nlink ?? null, + lastKnownGoodUid: entry.lastKnownGood?.uid ?? null, + lastKnownGoodGid: entry.lastKnownGood?.gid ?? null, + lastKnownGoodGatewayMode: entry.lastKnownGood?.gatewayMode ?? null, + backupHash: backup?.hash ?? null, + backupBytes: backup?.bytes ?? null, + backupMtimeMs: backup?.mtimeMs ?? null, + backupCtimeMs: backup?.ctimeMs ?? null, + backupDev: backup?.dev ?? null, + backupIno: backup?.ino ?? null, + backupMode: backup?.mode ?? null, + backupNlink: backup?.nlink ?? null, + backupUid: backup?.uid ?? null, + backupGid: backup?.gid ?? null, + backupGatewayMode: backup?.gatewayMode ?? null, + clobberedPath, + restoredFromBackup, + restoredBackupPath: backupPath, + }, }); healthState = setConfigHealthEntry(healthState, params.configPath, { @@ -742,56 +744,58 @@ function maybeRecoverSuspiciousConfigReadSync(params: { fs: params.deps.fs, env: params.deps.env, homedir: params.deps.homedir, - ts: now, - source: "config-io", - event: "config.observe", - phase: "read", - configPath: params.configPath, - pid: process.pid, - ppid: process.ppid, - cwd: process.cwd(), - argv: process.argv.slice(0, 8), - execArgv: process.execArgv.slice(0, 8), - exists: true, - valid: true, - hash: current.hash, - bytes: current.bytes, - mtimeMs: current.mtimeMs, - ctimeMs: current.ctimeMs, - dev: current.dev, - ino: current.ino, - mode: current.mode, - nlink: current.nlink, - uid: current.uid, - gid: current.gid, - hasMeta: current.hasMeta, - gatewayMode: current.gatewayMode, - suspicious, - lastKnownGoodHash: entry.lastKnownGood?.hash ?? null, - lastKnownGoodBytes: entry.lastKnownGood?.bytes ?? null, - lastKnownGoodMtimeMs: entry.lastKnownGood?.mtimeMs ?? null, - lastKnownGoodCtimeMs: entry.lastKnownGood?.ctimeMs ?? null, - lastKnownGoodDev: entry.lastKnownGood?.dev ?? null, - lastKnownGoodIno: entry.lastKnownGood?.ino ?? null, - lastKnownGoodMode: entry.lastKnownGood?.mode ?? null, - lastKnownGoodNlink: entry.lastKnownGood?.nlink ?? null, - lastKnownGoodUid: entry.lastKnownGood?.uid ?? null, - lastKnownGoodGid: entry.lastKnownGood?.gid ?? null, - lastKnownGoodGatewayMode: entry.lastKnownGood?.gatewayMode ?? null, - backupHash: backup?.hash ?? null, - backupBytes: backup?.bytes ?? null, - backupMtimeMs: backup?.mtimeMs ?? null, - backupCtimeMs: backup?.ctimeMs ?? null, - backupDev: backup?.dev ?? null, - backupIno: backup?.ino ?? null, - backupMode: backup?.mode ?? null, - backupNlink: backup?.nlink ?? null, - backupUid: backup?.uid ?? null, - backupGid: backup?.gid ?? null, - backupGatewayMode: backup?.gatewayMode ?? null, - clobberedPath, - restoredFromBackup, - restoredBackupPath: backupPath, + record: { + ts: now, + source: "config-io", + event: "config.observe", + phase: "read", + configPath: params.configPath, + pid: process.pid, + ppid: process.ppid, + cwd: process.cwd(), + argv: process.argv.slice(0, 8), + execArgv: process.execArgv.slice(0, 8), + exists: true, + valid: true, + hash: current.hash, + bytes: current.bytes, + mtimeMs: current.mtimeMs, + ctimeMs: current.ctimeMs, + dev: current.dev, + ino: current.ino, + mode: current.mode, + nlink: current.nlink, + uid: current.uid, + gid: current.gid, + hasMeta: current.hasMeta, + gatewayMode: current.gatewayMode, + suspicious, + lastKnownGoodHash: entry.lastKnownGood?.hash ?? null, + lastKnownGoodBytes: entry.lastKnownGood?.bytes ?? null, + lastKnownGoodMtimeMs: entry.lastKnownGood?.mtimeMs ?? null, + lastKnownGoodCtimeMs: entry.lastKnownGood?.ctimeMs ?? null, + lastKnownGoodDev: entry.lastKnownGood?.dev ?? null, + lastKnownGoodIno: entry.lastKnownGood?.ino ?? null, + lastKnownGoodMode: entry.lastKnownGood?.mode ?? null, + lastKnownGoodNlink: entry.lastKnownGood?.nlink ?? null, + lastKnownGoodUid: entry.lastKnownGood?.uid ?? null, + lastKnownGoodGid: entry.lastKnownGood?.gid ?? null, + lastKnownGoodGatewayMode: entry.lastKnownGood?.gatewayMode ?? null, + backupHash: backup?.hash ?? null, + backupBytes: backup?.bytes ?? null, + backupMtimeMs: backup?.mtimeMs ?? null, + backupCtimeMs: backup?.ctimeMs ?? null, + backupDev: backup?.dev ?? null, + backupIno: backup?.ino ?? null, + backupMode: backup?.mode ?? null, + backupNlink: backup?.nlink ?? null, + backupUid: backup?.uid ?? null, + backupGid: backup?.gid ?? null, + backupGatewayMode: backup?.gatewayMode ?? null, + clobberedPath, + restoredFromBackup, + restoredBackupPath: backupPath, + }, }); healthState = setConfigHealthEntry(healthState, params.configPath, { @@ -897,56 +901,58 @@ async function observeConfigSnapshot( fs: deps.fs, env: deps.env, homedir: deps.homedir, - ts: now, - source: "config-io", - event: "config.observe", - phase: "read", - configPath: snapshot.path, - pid: process.pid, - ppid: process.ppid, - cwd: process.cwd(), - argv: process.argv.slice(0, 8), - execArgv: process.execArgv.slice(0, 8), - exists: true, - valid: snapshot.valid, - hash: current.hash, - bytes: current.bytes, - mtimeMs: current.mtimeMs, - ctimeMs: current.ctimeMs, - dev: current.dev, - ino: current.ino, - mode: current.mode, - nlink: current.nlink, - uid: current.uid, - gid: current.gid, - hasMeta: current.hasMeta, - gatewayMode: current.gatewayMode, - suspicious, - lastKnownGoodHash: entry.lastKnownGood?.hash ?? null, - lastKnownGoodBytes: entry.lastKnownGood?.bytes ?? null, - lastKnownGoodMtimeMs: entry.lastKnownGood?.mtimeMs ?? null, - lastKnownGoodCtimeMs: entry.lastKnownGood?.ctimeMs ?? null, - lastKnownGoodDev: entry.lastKnownGood?.dev ?? null, - lastKnownGoodIno: entry.lastKnownGood?.ino ?? null, - lastKnownGoodMode: entry.lastKnownGood?.mode ?? null, - lastKnownGoodNlink: entry.lastKnownGood?.nlink ?? null, - lastKnownGoodUid: entry.lastKnownGood?.uid ?? null, - lastKnownGoodGid: entry.lastKnownGood?.gid ?? null, - lastKnownGoodGatewayMode: entry.lastKnownGood?.gatewayMode ?? null, - backupHash: backup?.hash ?? null, - backupBytes: backup?.bytes ?? null, - backupMtimeMs: backup?.mtimeMs ?? null, - backupCtimeMs: backup?.ctimeMs ?? null, - backupDev: backup?.dev ?? null, - backupIno: backup?.ino ?? null, - backupMode: backup?.mode ?? null, - backupNlink: backup?.nlink ?? null, - backupUid: backup?.uid ?? null, - backupGid: backup?.gid ?? null, - backupGatewayMode: backup?.gatewayMode ?? null, - clobberedPath, - restoredFromBackup: false, - restoredBackupPath: null, + record: { + ts: now, + source: "config-io", + event: "config.observe", + phase: "read", + configPath: snapshot.path, + pid: process.pid, + ppid: process.ppid, + cwd: process.cwd(), + argv: process.argv.slice(0, 8), + execArgv: process.execArgv.slice(0, 8), + exists: true, + valid: snapshot.valid, + hash: current.hash, + bytes: current.bytes, + mtimeMs: current.mtimeMs, + ctimeMs: current.ctimeMs, + dev: current.dev, + ino: current.ino, + mode: current.mode, + nlink: current.nlink, + uid: current.uid, + gid: current.gid, + hasMeta: current.hasMeta, + gatewayMode: current.gatewayMode, + suspicious, + lastKnownGoodHash: entry.lastKnownGood?.hash ?? null, + lastKnownGoodBytes: entry.lastKnownGood?.bytes ?? null, + lastKnownGoodMtimeMs: entry.lastKnownGood?.mtimeMs ?? null, + lastKnownGoodCtimeMs: entry.lastKnownGood?.ctimeMs ?? null, + lastKnownGoodDev: entry.lastKnownGood?.dev ?? null, + lastKnownGoodIno: entry.lastKnownGood?.ino ?? null, + lastKnownGoodMode: entry.lastKnownGood?.mode ?? null, + lastKnownGoodNlink: entry.lastKnownGood?.nlink ?? null, + lastKnownGoodUid: entry.lastKnownGood?.uid ?? null, + lastKnownGoodGid: entry.lastKnownGood?.gid ?? null, + lastKnownGoodGatewayMode: entry.lastKnownGood?.gatewayMode ?? null, + backupHash: backup?.hash ?? null, + backupBytes: backup?.bytes ?? null, + backupMtimeMs: backup?.mtimeMs ?? null, + backupCtimeMs: backup?.ctimeMs ?? null, + backupDev: backup?.dev ?? null, + backupIno: backup?.ino ?? null, + backupMode: backup?.mode ?? null, + backupNlink: backup?.nlink ?? null, + backupUid: backup?.uid ?? null, + backupGid: backup?.gid ?? null, + backupGatewayMode: backup?.gatewayMode ?? null, + clobberedPath, + restoredFromBackup: false, + restoredBackupPath: null, + }, }); healthState = setConfigHealthEntry(healthState, snapshot.path, { @@ -1028,56 +1034,58 @@ function observeConfigSnapshotSync( fs: deps.fs, env: deps.env, homedir: deps.homedir, - ts: now, - source: "config-io", - event: "config.observe", - phase: "read", - configPath: snapshot.path, - pid: process.pid, - ppid: process.ppid, - cwd: process.cwd(), - argv: process.argv.slice(0, 8), - execArgv: process.execArgv.slice(0, 8), - exists: true, - valid: snapshot.valid, - hash: current.hash, - bytes: current.bytes, - mtimeMs: current.mtimeMs, - ctimeMs: current.ctimeMs, - dev: current.dev, - ino: current.ino, - mode: current.mode, - nlink: current.nlink, - uid: current.uid, - gid: current.gid, - hasMeta: current.hasMeta, - gatewayMode: current.gatewayMode, - suspicious, - lastKnownGoodHash: entry.lastKnownGood?.hash ?? null, - lastKnownGoodBytes: entry.lastKnownGood?.bytes ?? null, - lastKnownGoodMtimeMs: entry.lastKnownGood?.mtimeMs ?? null, - lastKnownGoodCtimeMs: entry.lastKnownGood?.ctimeMs ?? null, - lastKnownGoodDev: entry.lastKnownGood?.dev ?? null, - lastKnownGoodIno: entry.lastKnownGood?.ino ?? null, - lastKnownGoodMode: entry.lastKnownGood?.mode ?? null, - lastKnownGoodNlink: entry.lastKnownGood?.nlink ?? null, - lastKnownGoodUid: entry.lastKnownGood?.uid ?? null, - lastKnownGoodGid: entry.lastKnownGood?.gid ?? null, - lastKnownGoodGatewayMode: entry.lastKnownGood?.gatewayMode ?? null, - backupHash: backup?.hash ?? null, - backupBytes: backup?.bytes ?? null, - backupMtimeMs: backup?.mtimeMs ?? null, - backupCtimeMs: backup?.ctimeMs ?? null, - backupDev: backup?.dev ?? null, - backupIno: backup?.ino ?? null, - backupMode: backup?.mode ?? null, - backupNlink: backup?.nlink ?? null, - backupUid: backup?.uid ?? null, - backupGid: backup?.gid ?? null, - backupGatewayMode: backup?.gatewayMode ?? null, - clobberedPath, - restoredFromBackup: false, - restoredBackupPath: null, + record: { + ts: now, + source: "config-io", + event: "config.observe", + phase: "read", + configPath: snapshot.path, + pid: process.pid, + ppid: process.ppid, + cwd: process.cwd(), + argv: process.argv.slice(0, 8), + execArgv: process.execArgv.slice(0, 8), + exists: true, + valid: snapshot.valid, + hash: current.hash, + bytes: current.bytes, + mtimeMs: current.mtimeMs, + ctimeMs: current.ctimeMs, + dev: current.dev, + ino: current.ino, + mode: current.mode, + nlink: current.nlink, + uid: current.uid, + gid: current.gid, + hasMeta: current.hasMeta, + gatewayMode: current.gatewayMode, + suspicious, + lastKnownGoodHash: entry.lastKnownGood?.hash ?? null, + lastKnownGoodBytes: entry.lastKnownGood?.bytes ?? null, + lastKnownGoodMtimeMs: entry.lastKnownGood?.mtimeMs ?? null, + lastKnownGoodCtimeMs: entry.lastKnownGood?.ctimeMs ?? null, + lastKnownGoodDev: entry.lastKnownGood?.dev ?? null, + lastKnownGoodIno: entry.lastKnownGood?.ino ?? null, + lastKnownGoodMode: entry.lastKnownGood?.mode ?? null, + lastKnownGoodNlink: entry.lastKnownGood?.nlink ?? null, + lastKnownGoodUid: entry.lastKnownGood?.uid ?? null, + lastKnownGoodGid: entry.lastKnownGood?.gid ?? null, + lastKnownGoodGatewayMode: entry.lastKnownGood?.gatewayMode ?? null, + backupHash: backup?.hash ?? null, + backupBytes: backup?.bytes ?? null, + backupMtimeMs: backup?.mtimeMs ?? null, + backupCtimeMs: backup?.ctimeMs ?? null, + backupDev: backup?.dev ?? null, + backupIno: backup?.ino ?? null, + backupMode: backup?.mode ?? null, + backupNlink: backup?.nlink ?? null, + backupUid: backup?.uid ?? null, + backupGid: backup?.gid ?? null, + backupGatewayMode: backup?.gatewayMode ?? null, + clobberedPath, + restoredFromBackup: false, + restoredBackupPath: null, + }, }); healthState = setConfigHealthEntry(healthState, snapshot.path, { diff --git a/src/config/io.write-config.test.ts b/src/config/io.write-config.test.ts index c5880f4584e..f3fdcd9336f 100644 --- a/src/config/io.write-config.test.ts +++ b/src/config/io.write-config.test.ts @@ -17,7 +17,9 @@ const mockLoadPluginManifestRegistry = vi.hoisted(() => }), ), ); -const mockMaintainConfigBackups = vi.hoisted(() => vi.fn(async () => {})); +const mockMaintainConfigBackups = vi.hoisted(() => + vi.fn(async () => {}), +); vi.mock("../plugins/manifest-registry.js", () => ({ loadPluginManifestRegistry: mockLoadPluginManifestRegistry, @@ -27,8 +29,7 @@ vi.mock("./backup-rotation.js", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, - maintainConfigBackups: (..._args: Parameters) => - mockMaintainConfigBackups(), + maintainConfigBackups: mockMaintainConfigBackups, }; }); diff --git a/src/config/io.write-prepare.test.ts b/src/config/io.write-prepare.test.ts index 3b7c07b2c74..95870b4c901 100644 --- a/src/config/io.write-prepare.test.ts +++ b/src/config/io.write-prepare.test.ts @@ -65,7 +65,7 @@ describe("config io write prepare", () => { const input: OpenClawConfig = { gateway: { mode: "local" }, commands: { ownerDisplay: "hash" }, - }; + } satisfies OpenClawConfig; const next = unsetPathForWrite(input, ["commands", "ownerDisplay"]); @@ -80,7 +80,7 @@ describe("config io write prepare", () => { const input: OpenClawConfig = { gateway: { mode: "local" }, tools: { alsoAllow: ["exec", "fetch", "read"] }, - }; + } satisfies OpenClawConfig; const next = unsetPathForWrite(input, ["tools", "alsoAllow", "1"]); @@ -95,7 +95,7 @@ describe("config io write prepare", () => { const input: OpenClawConfig = { gateway: { mode: "local" }, commands: { ownerDisplay: "hash" }, - }; + } satisfies OpenClawConfig; const next = unsetPathForWrite(input, ["commands", "missingKey"]); @@ -111,7 +111,7 @@ describe("config io write prepare", () => { const input: OpenClawConfig = { gateway: { mode: "local" }, commands: { ownerDisplay: "hash" }, - }; + } satisfies OpenClawConfig; const blocked = [ ["commands", "__proto__"], @@ -279,7 +279,7 @@ describe("config io write prepare", () => { password: "test-password", }, }, - }; + } satisfies OpenClawConfig; const runtimeConfig: OpenClawConfig = { gateway: { port: 18789 }, @@ -290,9 +290,9 @@ describe("config io write prepare", () => { enrichGroupParticipantsFromContacts: true, }, }, - }; + } satisfies OpenClawConfig; - const nextConfig = structuredClone(runtimeConfig); + const nextConfig: OpenClawConfig = structuredClone(runtimeConfig); nextConfig.gateway = { ...nextConfig.gateway, auth: { mode: "token" }, @@ -328,7 +328,7 @@ describe("config io write prepare", () => { }, }, gateway: { port: 18789 }, - }; + } satisfies OpenClawConfig; const nextConfig = structuredClone(sourceConfig); delete (nextConfig.channels?.discord?.dm as { enabled?: boolean; policy?: string } | undefined) @@ -382,9 +382,9 @@ describe("config io write prepare", () => { }, }, }, - }; + } satisfies OpenClawConfig; - const nextConfig = { + const nextConfig: OpenClawConfig = { ...structuredClone(sourceConfig), gateway: { auth: { mode: "token" }, diff --git a/test/extension-test-boundary.test.ts b/test/extension-test-boundary.test.ts index 45b82094bda..c6258d913bc 100644 --- a/test/extension-test-boundary.test.ts +++ b/test/extension-test-boundary.test.ts @@ -19,6 +19,7 @@ const allowedNonExtensionTests = new Set([ "src/commands/onboard-channels.e2e.test.ts", "src/gateway/hooks.test.ts", "src/infra/outbound/deliver.test.ts", + "src/media-generation/provider-capabilities.contract.test.ts", "src/plugins/interactive.test.ts", "src/plugins/contracts/discovery.contract.test.ts", "src/plugin-sdk/telegram-command-config.test.ts",