Pre-submission checklist | 提交前检查
Bug Description | 问题描述
The ESM bridge entry never asks the logger to initialize, so a bridge started from dist/bridge.mjs writes no log files at all.
core/pipeline/memory-core.ts:236 gates logger construction on its caller:
if (options.initLogging) {
initLogger(config, home);
}
The option is declared at memory-core.ts:193 and documented as "Embedded hosts skip this and keep their own logger." That makes setting it the entry point's job.
bridge.mts:260 calls bootstrapMemoryCoreFull({ ... hostLlmBridge ... }) and never passes initLogging. The CommonJS entry does — bridge.cts:324 sends initLogging: true — so the two hand-maintained launchers disagree, and the flag only ever landed on one of them (it arrived in the dev-v2.0.25 release merge, e8204062).
That would be harmless if .cjs were still what runs. It isn't. bridge_client.py:100 documents the resolution order as:
dist/bridge.mjs — pure ESM compiled output, the only entry
dist/bridge.cjs — legacy CommonJS compiled output, kept for installations whose dist/ predates the ESM entrypoint
So dist/bridge.cjs is a fallback for stale builds, and both spawn sites resolve bridge.mjs first. On any current build the logger is therefore never constructed, config.logging is inert, and no sink exists — not the console channel, not the file sinks under the home's logs/ directory.
Two things keep it silent rather than loud:
initLogging is optional and skipped when falsy, so nothing warns.
- The one file that does keep growing is a bootstrap-created
daemon-start.log, which nothing rotates — because the code that would rotate it is the code that never ran.
Expected: starting a bridge from the packaged entry produces the sinks described by config.logging.
How to Reproduce | 如何重现
cd apps/memos-local-plugin && npm run build, and confirm dist/bridge.mjs exists.
- Record the contents of the home's
logs/ directory, plus the current size of daemon-start.log.
- Start a bridge from the packaged entry:
node dist/bridge.mjs --agent=hermes --home=<home> --daemon.
- Re-check
logs/: no new sink appears and no app log is written, while daemon-start.log keeps growing.
- Add
initLogging: true to the bootstrapMemoryCoreFull({...}) call in bridge.mts, rebuild, and repeat 3-4. The sinks now appear.
Environment | 环境信息
- Node.js: 22.x
- Operating System: Linux
- Version: current
main (176d4f67), also present on the v2.0.25 line
- Entry point:
dist/bridge.mjs (ESM)
Additional Context | 其他信息
Two related notes, both in the same files:
- The launchers are duplicated by hand.
bridge.cts and bridge.mts carry the same bootstrap call and drifted in exactly this way. Since .cjs is now only a legacy fallback, collapsing to a single entry would remove the class rather than just this instance.
- The stale prose in
bridge_client.py (the module docstring naming dist/bridge.cjs as what is spawned, and the "every turn spawns new bridge.cjs" comment) is a second symptom of the same drift.
Willingness to Implement | 实现意愿
Pre-submission checklist | 提交前检查
Bug Description | 问题描述
The ESM bridge entry never asks the logger to initialize, so a bridge started from
dist/bridge.mjswrites no log files at all.core/pipeline/memory-core.ts:236gates logger construction on its caller:The option is declared at
memory-core.ts:193and documented as "Embedded hosts skip this and keep their own logger." That makes setting it the entry point's job.bridge.mts:260callsbootstrapMemoryCoreFull({ ... hostLlmBridge ... })and never passesinitLogging. The CommonJS entry does —bridge.cts:324sendsinitLogging: true— so the two hand-maintained launchers disagree, and the flag only ever landed on one of them (it arrived in thedev-v2.0.25release merge,e8204062).That would be harmless if
.cjswere still what runs. It isn't.bridge_client.py:100documents the resolution order as:So
dist/bridge.cjsis a fallback for stale builds, and both spawn sites resolvebridge.mjsfirst. On any current build the logger is therefore never constructed,config.loggingis inert, and no sink exists — not the console channel, not the file sinks under the home'slogs/directory.Two things keep it silent rather than loud:
initLoggingis optional and skipped when falsy, so nothing warns.daemon-start.log, which nothing rotates — because the code that would rotate it is the code that never ran.Expected: starting a bridge from the packaged entry produces the sinks described by
config.logging.How to Reproduce | 如何重现
cd apps/memos-local-plugin && npm run build, and confirmdist/bridge.mjsexists.logs/directory, plus the current size ofdaemon-start.log.node dist/bridge.mjs --agent=hermes --home=<home> --daemon.logs/: no new sink appears and no app log is written, whiledaemon-start.logkeeps growing.initLogging: trueto thebootstrapMemoryCoreFull({...})call inbridge.mts, rebuild, and repeat 3-4. The sinks now appear.Environment | 环境信息
main(176d4f67), also present on the v2.0.25 linedist/bridge.mjs(ESM)Additional Context | 其他信息
Two related notes, both in the same files:
bridge.ctsandbridge.mtscarry the same bootstrap call and drifted in exactly this way. Since.cjsis now only a legacy fallback, collapsing to a single entry would remove the class rather than just this instance.bridge_client.py(the module docstring namingdist/bridge.cjsas what is spawned, and the "every turn spawns new bridge.cjs" comment) is a second symptom of the same drift.Willingness to Implement | 实现意愿