From 0a762b8c080d9b7bd603c987d65fc4ac2f308659 Mon Sep 17 00:00:00 2001 From: zhayujie Date: Tue, 30 Jun 2026 10:03:12 +0800 Subject: [PATCH] fix(desktop): bundle cli command modules --- desktop/build/cowagent-backend.spec | 21 +++++++++++++++++++++ plugins/banwords/banwords.py | 15 +++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/desktop/build/cowagent-backend.spec b/desktop/build/cowagent-backend.spec index 123656e3..94506d59 100644 --- a/desktop/build/cowagent-backend.spec +++ b/desktop/build/cowagent-backend.spec @@ -64,7 +64,24 @@ hiddenimports += [ 'plugins.plugin_manager', ] hiddenimports += collect_submodules('plugins') + +# `cli` powers cow_cli's slash commands (`cow skill install`, `cow status`, …). +# Its command modules are imported lazily inside functions, so static analysis +# misses them. collect_submodules('cli') alone proved unreliable (a build can +# end up with `cli` but not `cli.commands`), so list the command modules +# explicitly AND ship the package as data (see datas) as a belt-and-suspenders. hiddenimports += collect_submodules('cli') +hiddenimports += [ + 'cli', + 'cli.cli', + 'cli.utils', + 'cli.commands', + 'cli.commands.skill', + 'cli.commands.process', + 'cli.commands.context', + 'cli.commands.install', + 'cli.commands.knowledge', +] # Third-party SDKs that use lazy/conditional imports internally. hiddenimports += collect_submodules('dashscope') @@ -97,6 +114,10 @@ datas = [ # PluginManager.scan_plugins() walks the on-disk ./plugins dir at runtime # (it doesn't rely solely on imports), so ship the package directory too. (rp('plugins'), 'plugins'), + # Ship the `cli` package as loose files too: onedir adds _internal to + # sys.path, so `import cli.commands.*` resolves even if PyInstaller's + # submodule collection misses the lazily-imported command modules. + (rp('cli'), 'cli'), # Web console served on the backend port: ship chat.html plus its static # assets (~1.9MB) so the browser-based console works as a debug/fallback # entry alongside the Electron UI. diff --git a/plugins/banwords/banwords.py b/plugins/banwords/banwords.py index 9478f728..0a1f43fa 100644 --- a/plugins/banwords/banwords.py +++ b/plugins/banwords/banwords.py @@ -37,13 +37,16 @@ class Banwords(Plugin): self.searchr = WordsSearch() self.action = conf["action"] + # banwords.txt is gitignored / not shipped by default; treat a + # missing file as an empty ban list instead of failing to init. banwords_path = os.path.join(curdir, "banwords.txt") - with open(banwords_path, "r", encoding="utf-8") as f: - words = [] - for line in f: - word = line.strip() - if word: - words.append(word) + words = [] + if os.path.exists(banwords_path): + with open(banwords_path, "r", encoding="utf-8") as f: + for line in f: + word = line.strip() + if word: + words.append(word) self.searchr.SetKeywords(words) self.handlers[Event.ON_HANDLE_CONTEXT] = self.on_handle_context if conf.get("reply_filter", True):