fix: persistent daemon startup, plugin integration, mobile fallback

- Hook handler now loads .env.daemon for proper config (plugin URL/secret, bot user ID)
- Hook logs to /tmp/status-watcher.log instead of /dev/null
- Added .env.daemon config file (.gitignored - contains tokens)
- Added start-daemon.sh convenience script
- Plugin mode: mobile fallback updates post message field with formatted markdown
- Fixed unbounded lines array in status-watcher (capped at 50)
- Added session marker to formatter output for restart recovery
- Go plugin: added updatePostMessageForMobile() for dual-render strategy
  (webapp gets custom React component, mobile gets markdown in message field)

Fixes: daemon silently dying, no plugin connection, mobile showing blank posts
This commit is contained in:
sol
2026-03-08 07:42:18 +00:00
parent 0d0e6e9d90
commit 09441b34c1
7 changed files with 268 additions and 12 deletions

View File

@@ -76,6 +76,8 @@ function format(sessionState, opts = {}) {
return '> ' + l;
})
.join('\n');
// Append invisible session marker for restart recovery (search by marker)
body += '\n<!-- sw:' + sessionState.sessionKey + ' -->';
}
return body;
}

View File

@@ -18,6 +18,8 @@ const path = require('path');
const { EventEmitter } = require('events');
const { resolve: resolveLabel } = require('./tool-labels');
const MAX_LINES_BUFFER = 50; // Cap state.lines to prevent memory leaks on long sessions
class StatusWatcher extends EventEmitter {
/**
* @param {object} opts
@@ -260,6 +262,11 @@ class StatusWatcher extends EventEmitter {
this._parseLine(sessionKey, state, line);
}
// Cap lines buffer to prevent unbounded growth on long sessions
if (state.lines.length > MAX_LINES_BUFFER) {
state.lines = state.lines.slice(-MAX_LINES_BUFFER);
}
// Update activity timestamp
state.lastActivityAt = Date.now();