| 130 | // resolved location without monkey-patching globals. |
| 131 | // - The install-root path uses __dirname so it's stable across cwd changes. |
| 132 | function _readLegacyNodeId() { |
| 133 | const candidates = [ |
| 134 | getEvomapPath('node_id'), |
| 135 | path.resolve(__dirname, '..', '..', '..', '.evomap_node_id'), |
| 136 | ]; |
| 137 | for (const file of candidates) { |
| 138 | try { |
| 139 | if (!fs.existsSync(file)) continue; |
| 140 | const raw = fs.readFileSync(file, 'utf8').trim(); |
| 141 | if (NODE_ID_RE.test(raw)) return raw; |
| 142 | } catch { |
| 143 | // Unreadable / racing writer — try the next location. |
| 144 | } |
| 145 | } |
| 146 | return null; |
| 147 | } |
| 148 | |
| 149 | // Mirror of src/gep/a2aProtocol.js `_persistNodeId`. Pure-proxy daemons |
| 150 | // (EVOMAP_PROXY=1, no a2aProtocol heartbeat thread) mint their own |