extractUsageFromMessages was summing ALL assistant messages, so each
$ai_generation event reported a growing cumulative total — PostHog's
sum() then massively over-counted costs (e.g. $634 reported vs $73 actual).
Integrate version tracking for DenchClaw and OpenClaw into the telemetry system. The versions are now read from the package.json and environment variables, and are included in the PostHog client initialization and telemetry events. This enhancement allows for better monitoring and analytics of the versions in use.
The root layout called getOrCreateAnonymousId() in a Server Component
without marking the route as dynamic. Next.js treated it as static,
pre-rendering the developer's UUID into the standalone build shipped
via npm — so every `npx denchclaw` user shared the same PostHog identity.
- Add `export const dynamic = "force-dynamic"` to root layout
- Replace `process.env.HOME || "~"` fallback with `homedir()` in web
telemetry and posthog-analytics plugin (Node.js path.join doesn't
expand "~", creating a relative path under cwd instead)
Update package versions for denchclaw and dench to 2.0.16. Refactor feedback API to convert chat lines into PostHog-compatible messages, preserving chronological order and including tool calls and results. Improve test cases to reflect changes in message handling.
Use the session key directly as the PostHog trace ID so feedback and generation events share the same trace. Extract non-assistant messages from conversations for $ai_input.
Add extractUsageFromMessages and normalizeOutputForPostHog to pull actual
token counts and cost from OpenClaw per-message usage metadata, and convert
Anthropic-style tool call blocks to OpenAI format for PostHog AI observability.
Integrate gateway daemon restart (stop → install → start) into both the
update and start web runtime commands so the gateway stays in sync with
runtime upgrades.
Switch TraceContextManager from runId to sessionId-based indexing so
tool spans share the same trace_id as their parent generation. Extract
tool names from agent_end messages for the PostHog Tools tab. Guard
against sending $0 cost and null token counts.
Integrate PostHog LLM Analytics via a bundled OpenClaw plugin that captures
$ai_generation, $ai_span, and $ai_trace events with configurable privacy
mode (content redaction on by default). Add like/dislike feedback buttons
to the web chat UI backed by a /api/feedback route. Extend the CLI with
`telemetry privacy on|off` subcommands and fix command delegation so
telemetry subcommands aren't forwarded to OpenClaw. Harden the web runtime
installer to auto-flatten pnpm standalone deps and dereference dangling
symlinks, preventing "Cannot find module 'next'" crashes in dev. Move
plugin installation before onboard in bootstrap so the gateway starts
with plugins.allow already configured.
- Deduplicate SkillEntry/SkillSnapshot imports in workspace.ts
- Add missing skillFilter/applySkillsPromptLimits in workspace skills
- Add sessionEventLog/sessionSubscriptions to runtime state return type
- Add allowRealIpFallback to GatewayConfig type
- Fix agent.subscribe/unsubscribe validation to use AJV pattern
- Add missing imports (RuntimeEnv, inheritOptionFromParent, etc.)
- Fix spread type in run-main.exit.test.ts
- Type chat.ts appendMessage call correctly
- Rename synology-chat workspace ref from openclaw to ironclaw
- Regenerate pnpm-lock.yaml for merged dependencies
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat: implement DM history backfill for BlueBubbles
- Add fetchBlueBubblesHistory function to fetch message history from API
- Modify processMessage to fetch history for both groups and DMs
- Use dmHistoryLimit for DMs and historyLimit for groups
- Add InboundHistory field to finalizeInboundContext call
Fixes#20296
* style: format with oxfmt
* address review: in-memory history cache, resolveAccount try/catch, include is_from_me
- Wrap resolveAccount in try/catch instead of unreachable guard (it throws)
- Include is_from_me messages with 'me' sender label for full conversation context
- Add in-memory rolling history map (chatHistories) matching other channel patterns
- API backfill only on first message per chat, not every incoming message
- Remove unused buildInboundHistoryFromEntries import
* chore: remove unused buildInboundHistoryFromEntries helper
Dead code flagged by Greptile — mapping is done inline in
monitor-processing.ts.
* BlueBubbles: harden DM history backfill state handling
* BlueBubbles: add bounded exponential backoff and history payload guards
* BlueBubbles: evict merged history keys
* Update extensions/bluebubbles/src/monitor-processing.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
---------
Co-authored-by: Ryan Mac Mini <ryanmacmini@ryans-mac-mini.tailf78f8b.ts.net>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* feat(channels): add Synology Chat native channel
Webhook-based integration with Synology NAS Chat (DSM 7+).
Supports outgoing webhooks, incoming messages, multi-account,
DM policies, rate limiting, and input sanitization.
- HMAC-based constant-time token validation
- Configurable SSL verification (allowInsecureSsl) for self-signed NAS certs
- 54 unit tests across 5 test suites
- Follows the same ChannelPlugin pattern as LINE/Discord/Telegram
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(synology-chat): add pairing, warnings, messaging, agent hints
- Enable media capability (file_url already supported by client)
- Add pairing.notifyApproval to message approved users
- Add security.collectWarnings for missing token/URL, insecure SSL, open DM policy
- Add messaging.normalizeTarget and targetResolver for user ID resolution
- Add directory stubs (self, listPeers, listGroups)
- Add agentPrompt.messageToolHints with Synology Chat formatting guide
- 63 tests (up from 54), all passing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(tui): strip inbound metadata blocks from user text
* chore: clean up metadata-strip format and changelog credit
* chore: format tui metadata-strip tests
* test(web): isolate local media fixture paths to allow-listed roots