Skip to content

Commit 5734193

Browse files
Kaspresteipete
andauthored
fix(plugins): keep metadata snapshot memo fresh
* fix(plugins): keep metadata memo freshness * fix(plugins): keep metadata memo freshness * fix(plugins): resolve metadata memo review gaps * fix(plugins): scope metadata memo watches to env * fix(plugins): tighten metadata memo fingerprint return type `resolvePersistedRegistryFastMemoFingerprint` was annotated `: unknown` but always returns object literals (`{ disabled: true }` or `{ index, npmPackageJson }`). Spreading the unknown-typed result on line 478 (`...fastFingerprint`) was rejected by tsgo with TS2698, which cascaded across every check that runs the project compile (build, tsgo:prod, check:test-types, lint, all node test shards). Tighten the return type to `Record<string, unknown>` to match the function's actual return shapes and unblock the spread. * test(gateway): tolerate ENOENT in sessions.list spy predicate The `sessions.list configuredAgentsOnly hides disk-discovered unregistered agent stores` test spies on `fsSync.readFileSync` and predicates with `fsSync.realpathSync.native(file) === realDiskOnlyStorePath` for every captured read. The native realpath call throws on missing files, so any new readFileSync of a path that may not exist (e.g. the persisted plugin install records probe added in this PR) crashes the predicate before the assertion runs. Wrap the predicate in ENOENT tolerance so the test stays robust against any future readFileSync of files that may not exist on disk. * fix(plugins): refresh memo from cached registry * fix(plugins): use high resolution memo fingerprints * test(plugins): stabilize memo freshness regression * test(cli): satisfy config mutation mock hash contract --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
1 parent 7289e14 commit 5734193

5 files changed

Lines changed: 832 additions & 36 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ Docs: https://docs.openclaw.ai
140140
- CLI/plugins: route lazy plugin command-registration chatter to stderr only during JSON-output command registration, keeping plugin-backed `--json` stdout parseable without changing parse-only or pass-through `--json` behavior. Fixes #81535. (#81536) Thanks @ScientificProgrammer and @vincentkoc.
141141
- Plugins: treat git plugin install refs as refs instead of checkout flags, so option-like selectors fail checkout instead of silently installing the default branch. Fixes #79898. (#79901) Thanks @afurm and @vincentkoc.
142142
- Doctor/memory: stop warning that no memory plugin is active when an enabled alternate memory plugin explicitly owns the memory slot, while preserving the warning for missing or disabled slot entries. Fixes #78540. (#78557) Thanks @carladams1299-lab and @vincentkoc.
143+
- Plugins: keep process-local plugin metadata snapshot memo freshness tied to the cached registry snapshot so policy-stale derived plugin metadata edits invalidate the memo instead of returning stale owners or command aliases. (#81064) Thanks @Kaspre.
144+
- Plugins: discover provider plugins from `setup.providers[].envVars` credentials during provider discovery while keeping the deprecated `providerAuthEnvVars` fallback. (#81542) Thanks @JARVIS-Glasses.
145+
- Docs/Codex harness: clarify that per-agent `CODEX_HOME` isolates `~/.codex` while inherited `HOME` intentionally keeps `.agents` discovery and subprocess user-home state available.
146+
- CLI/plugins: keep bare plugin and parent-command help on the lightweight path, avoiding plugin registry discovery before rendering help.
147+
- Auth: reclaim dead-owner stale file locks before retrying locked writes, so crashed OAuth refreshes no longer wedge `auth-profiles.json` until manual cleanup.
148+
- CLI tables: preserve muted/color styling on wrapped continuation lines after multiline cells, keeping `openclaw plugins list` descriptions readable.
149+
- Process execution: collapse case-insensitive duplicate child environment keys on Windows so caller-provided overrides such as `PATH` cannot be shadowed by host `Path`.
150+
- Browser CLI: request the existing `operator.admin` gateway scope explicitly for browser control commands, avoiding unnecessary scope-upgrade approval loops. Fixes #81555. (#81716) Thanks @joshavant.
143151
- Web: honor explicitly configured global `web_search` providers during provider ownership resolution while keeping sandboxed `web_fetch` limited to bundled providers.
144152
- Plugins/doctor: repair configured legacy npm declaration stubs by reinstalling their npm packages into the managed plugin root instead of loading workspace `node_modules`, and warn when discovery sees those stubs. Fixes #79632. Thanks @Dylanzhang1128 and @vincentkoc.
145153
- Channels: keep configured third-party channel plugins visible in `openclaw channels list` when their manifest declares `channels` but has not added `channelConfigs` metadata yet. Fixes #81334. (#81340) Thanks @AllynSheep and @vincentkoc.

src/cli/update-cli.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ describe("update-cli", () => {
445445
previousHash: snapshot.hash ?? null,
446446
snapshot,
447447
nextConfig,
448+
persistedHash: snapshot.hash ?? null,
448449
result: undefined,
449450
attempts: 1,
450451
afterWrite: { mode: "none", reason: "test" },
@@ -1190,6 +1191,7 @@ describe("update-cli", () => {
11901191
previousHash: newerSnapshot.hash,
11911192
snapshot: newerSnapshot,
11921193
nextConfig,
1194+
persistedHash: newerSnapshot.hash,
11931195
result: undefined,
11941196
attempts: 2,
11951197
afterWrite: { mode: "none", reason: "test" },

src/gateway/server.sessions.store-rpc.test.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -494,10 +494,16 @@ test("sessions.list configuredAgentsOnly hides disk-discovered unregistered agen
494494
"agent:main:main",
495495
]);
496496
expect(
497-
readFileSyncSpy.mock.calls.some(
498-
([file]) =>
499-
typeof file === "string" && fsSync.realpathSync.native(file) === realDiskOnlyStorePath,
500-
),
497+
readFileSyncSpy.mock.calls.some(([file]) => {
498+
if (typeof file !== "string") {
499+
return false;
500+
}
501+
try {
502+
return fsSync.realpathSync.native(file) === realDiskOnlyStorePath;
503+
} catch {
504+
return false;
505+
}
506+
}),
501507
).toBe(false);
502508
} finally {
503509
readFileSyncSpy.mockRestore();

0 commit comments

Comments
 (0)