instar 0.28.76 → 0.28.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/dashboard/index.html +486 -0
  2. package/dist/cli.js +5 -8
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/discovery.d.ts.map +1 -1
  5. package/dist/commands/discovery.js +2 -2
  6. package/dist/commands/discovery.js.map +1 -1
  7. package/dist/commands/init.d.ts.map +1 -1
  8. package/dist/commands/init.js +22 -4
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/job.d.ts.map +1 -1
  11. package/dist/commands/job.js +2 -2
  12. package/dist/commands/job.js.map +1 -1
  13. package/dist/commands/ledgerCleanup.d.ts.map +1 -1
  14. package/dist/commands/ledgerCleanup.js +2 -2
  15. package/dist/commands/ledgerCleanup.js.map +1 -1
  16. package/dist/commands/listener.d.ts.map +1 -1
  17. package/dist/commands/listener.js +7 -12
  18. package/dist/commands/listener.js.map +1 -1
  19. package/dist/commands/nuke.d.ts.map +1 -1
  20. package/dist/commands/nuke.js +11 -21
  21. package/dist/commands/nuke.js.map +1 -1
  22. package/dist/commands/server.d.ts.map +1 -1
  23. package/dist/commands/server.js +79 -5
  24. package/dist/commands/server.js.map +1 -1
  25. package/dist/commands/setup.d.ts.map +1 -1
  26. package/dist/commands/setup.js +11 -15
  27. package/dist/commands/setup.js.map +1 -1
  28. package/dist/commands/slack-cli.d.ts.map +1 -1
  29. package/dist/commands/slack-cli.js +5 -8
  30. package/dist/commands/slack-cli.js.map +1 -1
  31. package/dist/commands/whatsapp.d.ts.map +1 -1
  32. package/dist/commands/whatsapp.js +2 -2
  33. package/dist/commands/whatsapp.js.map +1 -1
  34. package/dist/commands/worktree.d.ts.map +1 -1
  35. package/dist/commands/worktree.js +2 -2
  36. package/dist/commands/worktree.js.map +1 -1
  37. package/dist/core/AgentConnector.d.ts.map +1 -1
  38. package/dist/core/AgentConnector.js +9 -10
  39. package/dist/core/AgentConnector.js.map +1 -1
  40. package/dist/core/AgentRegistry.d.ts.map +1 -1
  41. package/dist/core/AgentRegistry.js +3 -4
  42. package/dist/core/AgentRegistry.js.map +1 -1
  43. package/dist/core/AutoDispatcher.d.ts.map +1 -1
  44. package/dist/core/AutoDispatcher.js +2 -2
  45. package/dist/core/AutoDispatcher.js.map +1 -1
  46. package/dist/core/AutoUpdater.d.ts.map +1 -1
  47. package/dist/core/AutoUpdater.js +2 -2
  48. package/dist/core/AutoUpdater.js.map +1 -1
  49. package/dist/core/AutonomousEvolution.d.ts.map +1 -1
  50. package/dist/core/AutonomousEvolution.js +2 -2
  51. package/dist/core/AutonomousEvolution.js.map +1 -1
  52. package/dist/core/BackupManager.d.ts.map +1 -1
  53. package/dist/core/BackupManager.js +2 -2
  54. package/dist/core/BackupManager.js.map +1 -1
  55. package/dist/core/BranchManager.d.ts.map +1 -1
  56. package/dist/core/BranchManager.js +3 -3
  57. package/dist/core/BranchManager.js.map +1 -1
  58. package/dist/core/CaffeinateManager.d.ts.map +1 -1
  59. package/dist/core/CaffeinateManager.js +2 -2
  60. package/dist/core/CaffeinateManager.js.map +1 -1
  61. package/dist/core/DeferredDispatchTracker.d.ts.map +1 -1
  62. package/dist/core/DeferredDispatchTracker.js +2 -2
  63. package/dist/core/DeferredDispatchTracker.js.map +1 -1
  64. package/dist/core/DispatchManager.d.ts.map +1 -1
  65. package/dist/core/DispatchManager.js +3 -4
  66. package/dist/core/DispatchManager.js.map +1 -1
  67. package/dist/core/EvolutionManager.d.ts.map +1 -1
  68. package/dist/core/EvolutionManager.js +2 -2
  69. package/dist/core/EvolutionManager.js.map +1 -1
  70. package/dist/core/ExecutionJournal.d.ts.map +1 -1
  71. package/dist/core/ExecutionJournal.js +2 -2
  72. package/dist/core/ExecutionJournal.js.map +1 -1
  73. package/dist/core/FeedbackManager.d.ts.map +1 -1
  74. package/dist/core/FeedbackManager.js +2 -2
  75. package/dist/core/FeedbackManager.js.map +1 -1
  76. package/dist/core/FileClassifier.d.ts.map +1 -1
  77. package/dist/core/FileClassifier.js +8 -17
  78. package/dist/core/FileClassifier.js.map +1 -1
  79. package/dist/core/ForegroundRestartWatcher.d.ts.map +1 -1
  80. package/dist/core/ForegroundRestartWatcher.js +3 -4
  81. package/dist/core/ForegroundRestartWatcher.js.map +1 -1
  82. package/dist/core/GitStateManager.d.ts.map +1 -1
  83. package/dist/core/GitStateManager.js +3 -12
  84. package/dist/core/GitStateManager.js.map +1 -1
  85. package/dist/core/GitSync.d.ts.map +1 -1
  86. package/dist/core/GitSync.js +6 -6
  87. package/dist/core/GitSync.js.map +1 -1
  88. package/dist/core/GlobalInstallCleanup.d.ts.map +1 -1
  89. package/dist/core/GlobalInstallCleanup.js +3 -4
  90. package/dist/core/GlobalInstallCleanup.js.map +1 -1
  91. package/dist/core/GlobalSecretStore.d.ts.map +1 -1
  92. package/dist/core/GlobalSecretStore.js +3 -4
  93. package/dist/core/GlobalSecretStore.js.map +1 -1
  94. package/dist/core/HandoffManager.d.ts.map +1 -1
  95. package/dist/core/HandoffManager.js +5 -5
  96. package/dist/core/HandoffManager.js.map +1 -1
  97. package/dist/core/JargonDetector.d.ts +28 -0
  98. package/dist/core/JargonDetector.d.ts.map +1 -0
  99. package/dist/core/JargonDetector.js +59 -0
  100. package/dist/core/JargonDetector.js.map +1 -0
  101. package/dist/core/LedgerSessionRegistry.d.ts.map +1 -1
  102. package/dist/core/LedgerSessionRegistry.js +2 -2
  103. package/dist/core/LedgerSessionRegistry.js.map +1 -1
  104. package/dist/core/MachineIdentity.d.ts.map +1 -1
  105. package/dist/core/MachineIdentity.js +2 -2
  106. package/dist/core/MachineIdentity.js.map +1 -1
  107. package/dist/core/MessagingToneGate.d.ts +42 -5
  108. package/dist/core/MessagingToneGate.d.ts.map +1 -1
  109. package/dist/core/MessagingToneGate.js +40 -6
  110. package/dist/core/MessagingToneGate.js.map +1 -1
  111. package/dist/core/ParallelDevWiring.d.ts.map +1 -1
  112. package/dist/core/ParallelDevWiring.js +3 -6
  113. package/dist/core/ParallelDevWiring.js.map +1 -1
  114. package/dist/core/PostUpdateMigrator.d.ts +26 -0
  115. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  116. package/dist/core/PostUpdateMigrator.js +249 -46
  117. package/dist/core/PostUpdateMigrator.js.map +1 -1
  118. package/dist/core/ProjectMapper.d.ts.map +1 -1
  119. package/dist/core/ProjectMapper.js +5 -11
  120. package/dist/core/ProjectMapper.js.map +1 -1
  121. package/dist/core/RelationshipManager.d.ts.map +1 -1
  122. package/dist/core/RelationshipManager.js +4 -5
  123. package/dist/core/RelationshipManager.js.map +1 -1
  124. package/dist/core/SafeGitExecutor.d.ts +11 -5
  125. package/dist/core/SafeGitExecutor.d.ts.map +1 -1
  126. package/dist/core/SafeGitExecutor.js +87 -1
  127. package/dist/core/SafeGitExecutor.js.map +1 -1
  128. package/dist/core/ScopeVerifier.d.ts.map +1 -1
  129. package/dist/core/ScopeVerifier.js +3 -6
  130. package/dist/core/ScopeVerifier.js.map +1 -1
  131. package/dist/core/SecretStore.d.ts.map +1 -1
  132. package/dist/core/SecretStore.js +2 -2
  133. package/dist/core/SecretStore.js.map +1 -1
  134. package/dist/core/SharedStateLedger.d.ts.map +1 -1
  135. package/dist/core/SharedStateLedger.js +2 -2
  136. package/dist/core/SharedStateLedger.js.map +1 -1
  137. package/dist/core/SoulManager.d.ts.map +1 -1
  138. package/dist/core/SoulManager.js +3 -4
  139. package/dist/core/SoulManager.js.map +1 -1
  140. package/dist/core/StateManager.d.ts.map +1 -1
  141. package/dist/core/StateManager.js +4 -6
  142. package/dist/core/StateManager.js.map +1 -1
  143. package/dist/core/SyncOrchestrator.d.ts.map +1 -1
  144. package/dist/core/SyncOrchestrator.js +6 -7
  145. package/dist/core/SyncOrchestrator.js.map +1 -1
  146. package/dist/core/UpdateChecker.d.ts.map +1 -1
  147. package/dist/core/UpdateChecker.js +3 -4
  148. package/dist/core/UpdateChecker.js.map +1 -1
  149. package/dist/core/UpgradeGuideProcessor.d.ts.map +1 -1
  150. package/dist/core/UpgradeGuideProcessor.js +3 -4
  151. package/dist/core/UpgradeGuideProcessor.js.map +1 -1
  152. package/dist/core/WorktreeManager.d.ts.map +1 -1
  153. package/dist/core/WorktreeManager.js +9 -14
  154. package/dist/core/WorktreeManager.js.map +1 -1
  155. package/dist/knowledge/KnowledgeManager.d.ts.map +1 -1
  156. package/dist/knowledge/KnowledgeManager.js +2 -2
  157. package/dist/knowledge/KnowledgeManager.js.map +1 -1
  158. package/dist/lifeline/ServerSupervisor.d.ts +28 -0
  159. package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
  160. package/dist/lifeline/ServerSupervisor.js +171 -73
  161. package/dist/lifeline/ServerSupervisor.js.map +1 -1
  162. package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
  163. package/dist/lifeline/TelegramLifeline.js +10 -4
  164. package/dist/lifeline/TelegramLifeline.js.map +1 -1
  165. package/dist/lifeline/detectLaunchdSupervised.d.ts +43 -0
  166. package/dist/lifeline/detectLaunchdSupervised.d.ts.map +1 -0
  167. package/dist/lifeline/detectLaunchdSupervised.js +106 -0
  168. package/dist/lifeline/detectLaunchdSupervised.js.map +1 -0
  169. package/dist/lifeline/droppedMessages.d.ts.map +1 -1
  170. package/dist/lifeline/droppedMessages.js +2 -2
  171. package/dist/lifeline/droppedMessages.js.map +1 -1
  172. package/dist/memory/EpisodicMemory.d.ts.map +1 -1
  173. package/dist/memory/EpisodicMemory.js +2 -2
  174. package/dist/memory/EpisodicMemory.js.map +1 -1
  175. package/dist/memory/TopicMemory.d.ts.map +1 -1
  176. package/dist/memory/TopicMemory.js +5 -8
  177. package/dist/memory/TopicMemory.js.map +1 -1
  178. package/dist/messaging/AgentTokenManager.d.ts.map +1 -1
  179. package/dist/messaging/AgentTokenManager.js +2 -2
  180. package/dist/messaging/AgentTokenManager.js.map +1 -1
  181. package/dist/messaging/DropPickup.d.ts.map +1 -1
  182. package/dist/messaging/DropPickup.js +2 -2
  183. package/dist/messaging/DropPickup.js.map +1 -1
  184. package/dist/messaging/GitSyncTransport.d.ts.map +1 -1
  185. package/dist/messaging/GitSyncTransport.js +4 -6
  186. package/dist/messaging/GitSyncTransport.js.map +1 -1
  187. package/dist/messaging/MessageStore.d.ts.map +1 -1
  188. package/dist/messaging/MessageStore.js +3 -4
  189. package/dist/messaging/MessageStore.js.map +1 -1
  190. package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
  191. package/dist/messaging/TelegramAdapter.js +5 -8
  192. package/dist/messaging/TelegramAdapter.js.map +1 -1
  193. package/dist/messaging/backends/BaileysBackend.d.ts.map +1 -1
  194. package/dist/messaging/backends/BaileysBackend.js +3 -4
  195. package/dist/messaging/backends/BaileysBackend.js.map +1 -1
  196. package/dist/messaging/local-tone-check.d.ts +61 -0
  197. package/dist/messaging/local-tone-check.d.ts.map +1 -0
  198. package/dist/messaging/local-tone-check.js +78 -0
  199. package/dist/messaging/local-tone-check.js.map +1 -0
  200. package/dist/messaging/pending-relay-store.d.ts +153 -0
  201. package/dist/messaging/pending-relay-store.d.ts.map +1 -0
  202. package/dist/messaging/pending-relay-store.js +351 -0
  203. package/dist/messaging/pending-relay-store.js.map +1 -0
  204. package/dist/messaging/secret-patterns.d.ts +35 -0
  205. package/dist/messaging/secret-patterns.d.ts.map +1 -0
  206. package/dist/messaging/secret-patterns.js +70 -0
  207. package/dist/messaging/secret-patterns.js.map +1 -0
  208. package/dist/messaging/shared/EncryptedAuthStore.d.ts.map +1 -1
  209. package/dist/messaging/shared/EncryptedAuthStore.js +3 -4
  210. package/dist/messaging/shared/EncryptedAuthStore.js.map +1 -1
  211. package/dist/messaging/shared/MessageLogger.d.ts.map +1 -1
  212. package/dist/messaging/shared/MessageLogger.js +2 -2
  213. package/dist/messaging/shared/MessageLogger.js.map +1 -1
  214. package/dist/messaging/shared/PrivacyConsent.d.ts.map +1 -1
  215. package/dist/messaging/shared/PrivacyConsent.js +2 -2
  216. package/dist/messaging/shared/PrivacyConsent.js.map +1 -1
  217. package/dist/messaging/shared/SessionChannelRegistry.d.ts.map +1 -1
  218. package/dist/messaging/shared/SessionChannelRegistry.js +2 -2
  219. package/dist/messaging/shared/SessionChannelRegistry.js.map +1 -1
  220. package/dist/messaging/system-templates.d.ts +87 -0
  221. package/dist/messaging/system-templates.d.ts.map +1 -0
  222. package/dist/messaging/system-templates.js +236 -0
  223. package/dist/messaging/system-templates.js.map +1 -0
  224. package/dist/messaging/whoami-cache.d.ts +66 -0
  225. package/dist/messaging/whoami-cache.d.ts.map +1 -0
  226. package/dist/messaging/whoami-cache.js +149 -0
  227. package/dist/messaging/whoami-cache.js.map +1 -0
  228. package/dist/moltbridge/ProfileCompiler.d.ts.map +1 -1
  229. package/dist/moltbridge/ProfileCompiler.js +13 -7
  230. package/dist/moltbridge/ProfileCompiler.js.map +1 -1
  231. package/dist/monitoring/CommitmentTracker.d.ts.map +1 -1
  232. package/dist/monitoring/CommitmentTracker.js +2 -2
  233. package/dist/monitoring/CommitmentTracker.js.map +1 -1
  234. package/dist/monitoring/CredentialProvider.d.ts.map +1 -1
  235. package/dist/monitoring/CredentialProvider.js +2 -2
  236. package/dist/monitoring/CredentialProvider.js.map +1 -1
  237. package/dist/monitoring/DegradationReporter.d.ts +41 -0
  238. package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
  239. package/dist/monitoring/DegradationReporter.js +96 -4
  240. package/dist/monitoring/DegradationReporter.js.map +1 -1
  241. package/dist/monitoring/HealthChecker.d.ts.map +1 -1
  242. package/dist/monitoring/HealthChecker.js +2 -2
  243. package/dist/monitoring/HealthChecker.js.map +1 -1
  244. package/dist/monitoring/HookEventReceiver.d.ts.map +1 -1
  245. package/dist/monitoring/HookEventReceiver.js +2 -2
  246. package/dist/monitoring/HookEventReceiver.js.map +1 -1
  247. package/dist/monitoring/InstructionsVerifier.d.ts.map +1 -1
  248. package/dist/monitoring/InstructionsVerifier.js +2 -2
  249. package/dist/monitoring/InstructionsVerifier.js.map +1 -1
  250. package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
  251. package/dist/monitoring/PresenceProxy.js +5 -8
  252. package/dist/monitoring/PresenceProxy.js.map +1 -1
  253. package/dist/monitoring/QuotaTracker.d.ts.map +1 -1
  254. package/dist/monitoring/QuotaTracker.js +2 -2
  255. package/dist/monitoring/QuotaTracker.js.map +1 -1
  256. package/dist/monitoring/SessionMigrator.d.ts.map +1 -1
  257. package/dist/monitoring/SessionMigrator.js +2 -2
  258. package/dist/monitoring/SessionMigrator.js.map +1 -1
  259. package/dist/monitoring/SessionRecovery.d.ts.map +1 -1
  260. package/dist/monitoring/SessionRecovery.js +2 -2
  261. package/dist/monitoring/SessionRecovery.js.map +1 -1
  262. package/dist/monitoring/TelemetryAuth.d.ts.map +1 -1
  263. package/dist/monitoring/TelemetryAuth.js +3 -4
  264. package/dist/monitoring/TelemetryAuth.js.map +1 -1
  265. package/dist/monitoring/TokenLedger.d.ts +130 -0
  266. package/dist/monitoring/TokenLedger.d.ts.map +1 -0
  267. package/dist/monitoring/TokenLedger.js +523 -0
  268. package/dist/monitoring/TokenLedger.js.map +1 -0
  269. package/dist/monitoring/TokenLedgerPoller.d.ts +26 -0
  270. package/dist/monitoring/TokenLedgerPoller.d.ts.map +1 -0
  271. package/dist/monitoring/TokenLedgerPoller.js +44 -0
  272. package/dist/monitoring/TokenLedgerPoller.js.map +1 -0
  273. package/dist/monitoring/TriageOrchestrator.d.ts.map +1 -1
  274. package/dist/monitoring/TriageOrchestrator.js +3 -4
  275. package/dist/monitoring/TriageOrchestrator.js.map +1 -1
  276. package/dist/monitoring/WorktreeReaper.d.ts.map +1 -1
  277. package/dist/monitoring/WorktreeReaper.js +5 -7
  278. package/dist/monitoring/WorktreeReaper.js.map +1 -1
  279. package/dist/monitoring/delivery-failure-sentinel/recovery-policy.d.ts +83 -0
  280. package/dist/monitoring/delivery-failure-sentinel/recovery-policy.d.ts.map +1 -0
  281. package/dist/monitoring/delivery-failure-sentinel/recovery-policy.js +218 -0
  282. package/dist/monitoring/delivery-failure-sentinel/recovery-policy.js.map +1 -0
  283. package/dist/monitoring/delivery-failure-sentinel.d.ts +177 -0
  284. package/dist/monitoring/delivery-failure-sentinel.d.ts.map +1 -0
  285. package/dist/monitoring/delivery-failure-sentinel.js +598 -0
  286. package/dist/monitoring/delivery-failure-sentinel.js.map +1 -0
  287. package/dist/monitoring/probes/PlatformProbe.d.ts.map +1 -1
  288. package/dist/monitoring/probes/PlatformProbe.js +3 -4
  289. package/dist/monitoring/probes/PlatformProbe.js.map +1 -1
  290. package/dist/monitoring/templates-drift-verifier.d.ts +109 -0
  291. package/dist/monitoring/templates-drift-verifier.d.ts.map +1 -0
  292. package/dist/monitoring/templates-drift-verifier.js +324 -0
  293. package/dist/monitoring/templates-drift-verifier.js.map +1 -0
  294. package/dist/paste/PasteManager.d.ts.map +1 -1
  295. package/dist/paste/PasteManager.js +5 -8
  296. package/dist/paste/PasteManager.js.map +1 -1
  297. package/dist/publishing/PrivateViewer.d.ts.map +1 -1
  298. package/dist/publishing/PrivateViewer.js +2 -2
  299. package/dist/publishing/PrivateViewer.js.map +1 -1
  300. package/dist/scheduler/JobScheduler.d.ts.map +1 -1
  301. package/dist/scheduler/JobScheduler.js +2 -2
  302. package/dist/scheduler/JobScheduler.js.map +1 -1
  303. package/dist/server/AgentServer.d.ts +22 -0
  304. package/dist/server/AgentServer.d.ts.map +1 -1
  305. package/dist/server/AgentServer.js +199 -1
  306. package/dist/server/AgentServer.js.map +1 -1
  307. package/dist/server/WebSocketManager.d.ts +11 -0
  308. package/dist/server/WebSocketManager.d.ts.map +1 -1
  309. package/dist/server/WebSocketManager.js +28 -0
  310. package/dist/server/WebSocketManager.js.map +1 -1
  311. package/dist/server/boot-id.d.ts +58 -0
  312. package/dist/server/boot-id.d.ts.map +1 -0
  313. package/dist/server/boot-id.js +121 -0
  314. package/dist/server/boot-id.js.map +1 -0
  315. package/dist/server/middleware.d.ts +14 -1
  316. package/dist/server/middleware.d.ts.map +1 -1
  317. package/dist/server/middleware.js +81 -1
  318. package/dist/server/middleware.js.map +1 -1
  319. package/dist/server/routes.d.ts +76 -0
  320. package/dist/server/routes.d.ts.map +1 -1
  321. package/dist/server/routes.js +626 -11
  322. package/dist/server/routes.js.map +1 -1
  323. package/dist/threadline/AgentDiscovery.d.ts.map +1 -1
  324. package/dist/threadline/AgentDiscovery.js +2 -2
  325. package/dist/threadline/AgentDiscovery.js.map +1 -1
  326. package/dist/threadline/AgentTrustManager.d.ts.map +1 -1
  327. package/dist/threadline/AgentTrustManager.js +2 -2
  328. package/dist/threadline/AgentTrustManager.js.map +1 -1
  329. package/dist/threadline/BackfillCore.d.ts +70 -0
  330. package/dist/threadline/BackfillCore.d.ts.map +1 -0
  331. package/dist/threadline/BackfillCore.js +117 -0
  332. package/dist/threadline/BackfillCore.js.map +1 -0
  333. package/dist/threadline/CircuitBreaker.d.ts.map +1 -1
  334. package/dist/threadline/CircuitBreaker.js +2 -2
  335. package/dist/threadline/CircuitBreaker.js.map +1 -1
  336. package/dist/threadline/ComputeMeter.d.ts.map +1 -1
  337. package/dist/threadline/ComputeMeter.js +2 -2
  338. package/dist/threadline/ComputeMeter.js.map +1 -1
  339. package/dist/threadline/ContextThreadMap.d.ts.map +1 -1
  340. package/dist/threadline/ContextThreadMap.js +2 -2
  341. package/dist/threadline/ContextThreadMap.js.map +1 -1
  342. package/dist/threadline/HeartbeatWatchdog.d.ts +78 -0
  343. package/dist/threadline/HeartbeatWatchdog.d.ts.map +1 -0
  344. package/dist/threadline/HeartbeatWatchdog.js +212 -0
  345. package/dist/threadline/HeartbeatWatchdog.js.map +1 -0
  346. package/dist/threadline/HeartbeatWriter.d.ts +79 -0
  347. package/dist/threadline/HeartbeatWriter.d.ts.map +1 -0
  348. package/dist/threadline/HeartbeatWriter.js +109 -0
  349. package/dist/threadline/HeartbeatWriter.js.map +1 -0
  350. package/dist/threadline/InvitationManager.d.ts.map +1 -1
  351. package/dist/threadline/InvitationManager.js +2 -2
  352. package/dist/threadline/InvitationManager.js.map +1 -1
  353. package/dist/threadline/ListenerSessionManager.d.ts +59 -0
  354. package/dist/threadline/ListenerSessionManager.d.ts.map +1 -1
  355. package/dist/threadline/ListenerSessionManager.js +79 -0
  356. package/dist/threadline/ListenerSessionManager.js.map +1 -1
  357. package/dist/threadline/MCPAuth.d.ts.map +1 -1
  358. package/dist/threadline/MCPAuth.js +2 -2
  359. package/dist/threadline/MCPAuth.js.map +1 -1
  360. package/dist/threadline/PipeSessionSpawner.d.ts.map +1 -1
  361. package/dist/threadline/PipeSessionSpawner.js +3 -4
  362. package/dist/threadline/PipeSessionSpawner.js.map +1 -1
  363. package/dist/threadline/RateLimiter.d.ts.map +1 -1
  364. package/dist/threadline/RateLimiter.js +2 -2
  365. package/dist/threadline/RateLimiter.js.map +1 -1
  366. package/dist/threadline/RelaySpawnFailureHandler.d.ts +53 -0
  367. package/dist/threadline/RelaySpawnFailureHandler.d.ts.map +1 -0
  368. package/dist/threadline/RelaySpawnFailureHandler.js +73 -0
  369. package/dist/threadline/RelaySpawnFailureHandler.js.map +1 -0
  370. package/dist/threadline/SessionLifecycle.d.ts.map +1 -1
  371. package/dist/threadline/SessionLifecycle.js +2 -2
  372. package/dist/threadline/SessionLifecycle.js.map +1 -1
  373. package/dist/threadline/SpawnLedger.d.ts +94 -0
  374. package/dist/threadline/SpawnLedger.d.ts.map +1 -0
  375. package/dist/threadline/SpawnLedger.js +194 -0
  376. package/dist/threadline/SpawnLedger.js.map +1 -0
  377. package/dist/threadline/SpawnNonce.d.ts +49 -0
  378. package/dist/threadline/SpawnNonce.d.ts.map +1 -0
  379. package/dist/threadline/SpawnNonce.js +99 -0
  380. package/dist/threadline/SpawnNonce.js.map +1 -0
  381. package/dist/threadline/TelegramBridge.d.ts +140 -0
  382. package/dist/threadline/TelegramBridge.d.ts.map +1 -0
  383. package/dist/threadline/TelegramBridge.js +224 -0
  384. package/dist/threadline/TelegramBridge.js.map +1 -0
  385. package/dist/threadline/TelegramBridgeConfig.d.ts +79 -0
  386. package/dist/threadline/TelegramBridgeConfig.d.ts.map +1 -0
  387. package/dist/threadline/TelegramBridgeConfig.js +168 -0
  388. package/dist/threadline/TelegramBridgeConfig.js.map +1 -0
  389. package/dist/threadline/ThreadlineBootstrap.d.ts.map +1 -1
  390. package/dist/threadline/ThreadlineBootstrap.js +2 -2
  391. package/dist/threadline/ThreadlineBootstrap.js.map +1 -1
  392. package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -1
  393. package/dist/threadline/ThreadlineMCPServer.js +5 -0
  394. package/dist/threadline/ThreadlineMCPServer.js.map +1 -1
  395. package/dist/threadline/ThreadlineObservability.d.ts +95 -0
  396. package/dist/threadline/ThreadlineObservability.d.ts.map +1 -0
  397. package/dist/threadline/ThreadlineObservability.js +310 -0
  398. package/dist/threadline/ThreadlineObservability.js.map +1 -0
  399. package/dist/threadline/WakeSocketServer.d.ts.map +1 -1
  400. package/dist/threadline/WakeSocketServer.js +3 -4
  401. package/dist/threadline/WakeSocketServer.js.map +1 -1
  402. package/dist/threadline/listener-daemon.d.ts.map +1 -1
  403. package/dist/threadline/listener-daemon.js +3 -4
  404. package/dist/threadline/listener-daemon.js.map +1 -1
  405. package/dist/users/UserManager.d.ts.map +1 -1
  406. package/dist/users/UserManager.js +2 -2
  407. package/dist/users/UserManager.js.map +1 -1
  408. package/dist/users/UserOnboarding.d.ts.map +1 -1
  409. package/dist/users/UserOnboarding.js +2 -2
  410. package/dist/users/UserOnboarding.js.map +1 -1
  411. package/dist/utils/jsonl-rotation.d.ts.map +1 -1
  412. package/dist/utils/jsonl-rotation.js +2 -2
  413. package/dist/utils/jsonl-rotation.js.map +1 -1
  414. package/package.json +1 -1
  415. package/scripts/analyze-release.js +7 -12
  416. package/scripts/check-contract-evidence.js +27 -10
  417. package/scripts/fix-better-sqlite3.cjs +0 -2
  418. package/scripts/instar-dev-precommit.js +0 -2
  419. package/scripts/lint-no-direct-destructive.js +24 -4
  420. package/scripts/lint-template-sha-history.ts +183 -0
  421. package/scripts/migrate-incident-2026-04-17.mjs +2 -2
  422. package/scripts/run-migration.js +500 -0
  423. package/scripts/test-bootstrap-relay.mjs +2 -2
  424. package/scripts/threadline-bridge-backfill.mjs +379 -0
  425. package/scripts/verify-deployed-templates.ts +87 -0
  426. package/src/data/builtin-manifest.json +140 -132
  427. package/src/templates/scripts/git-sync-gate.sh +0 -4
  428. package/src/templates/scripts/telegram-reply.sh +318 -13
  429. package/upgrades/0.28.77.md +133 -0
  430. package/upgrades/0.28.78.md +90 -0
  431. package/upgrades/side-effects/agent-health-alert-authority-routing.md +121 -0
  432. package/upgrades/side-effects/comprehensive-destructive-tool-containment-migration.md +82 -0
  433. package/upgrades/side-effects/deferral-detector-orphan-todo.md +101 -0
  434. package/upgrades/side-effects/lifeline-self-heal-hardening.md +151 -0
  435. package/upgrades/side-effects/relay-spawn-ghost-reply-phase1.md +139 -0
  436. package/upgrades/side-effects/telegram-delivery-robustness-layer-2.md +320 -0
  437. package/upgrades/side-effects/telegram-delivery-robustness-layer-3.md +202 -0
  438. package/upgrades/side-effects/telegram-delivery-robustness-layer-7.md +339 -0
  439. package/upgrades/side-effects/telegram-delivery-robustness.md +178 -0
  440. package/upgrades/side-effects/threadline-bridge-backfill.md +203 -0
  441. package/upgrades/side-effects/threadline-canonical-inbox-write.md +218 -0
  442. package/upgrades/side-effects/threadline-observability-tab.md +206 -0
  443. package/upgrades/side-effects/threadline-tg-bridge-module.md +196 -0
  444. package/upgrades/side-effects/threadline-tg-bridge-settings-surface.md +208 -0
  445. package/upgrades/side-effects/token-ledger-bounded-scan.md +230 -0
  446. package/upgrades/side-effects/token-ledger-phase1.md +123 -0
  447. package/upgrades/NEXT.md +0 -53
  448. /package/upgrades/side-effects/{telegram-lifeline-version-missing-info.md → 0.28.76.md} +0 -0
@@ -2418,6 +2418,8 @@
2418
2418
  <button class="tab" data-tab="pr-pipeline" onclick="switchTab('pr-pipeline')">PR Pipeline</button>
2419
2419
  <button class="tab" data-tab="initiatives" onclick="switchTab('initiatives')">Initiatives <span class="tab-count" id="tabInitiativeCount">0</span></button>
2420
2420
  <button class="tab" data-tab="commitments" onclick="switchTab('commitments')">Commitments <span class="tab-count" id="tabCommitmentCount">0</span></button>
2421
+ <button class="tab" data-tab="tokens" onclick="switchTab('tokens')">Tokens</button>
2422
+ <button class="tab" data-tab="threadline" onclick="switchTab('threadline')">Threadline</button>
2421
2423
  </nav>
2422
2424
  </div>
2423
2425
  <div class="vital-signs" id="vitalSigns">
@@ -2846,6 +2848,135 @@
2846
2848
  <div id="commitmentsList" style="display:flex;flex-direction:column;gap:12px"></div>
2847
2849
  </div>
2848
2850
 
2851
+ <!-- Tokens Tab — read-only token-usage observability -->
2852
+ <div id="tokensPanel" style="display:none;flex-direction:column;padding:20px;gap:16px;overflow-y:auto">
2853
+ <div style="display:flex;justify-content:space-between;align-items:center">
2854
+ <h2 style="margin:0">Tokens</h2>
2855
+ <button onclick="loadTokens()" style="padding:6px 12px">Refresh</button>
2856
+ </div>
2857
+ <div style="font-size:12px;color:var(--text-dim);line-height:1.4">
2858
+ Token usage rolled up from Claude Code session transcripts. Last 24 hours unless noted.
2859
+ </div>
2860
+
2861
+ <!-- Summary card -->
2862
+ <div id="tokensSummaryCard" style="border:1px solid var(--border);border-radius:8px;padding:16px;display:flex;flex-direction:column;gap:8px">
2863
+ <div style="font-weight:600">Last 24h</div>
2864
+ <div id="tokensSummaryBody" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;font-size:13px">
2865
+ <div style="color:var(--text-dim)">Loading...</div>
2866
+ </div>
2867
+ </div>
2868
+
2869
+ <!-- Top sessions -->
2870
+ <div style="border:1px solid var(--border);border-radius:8px;padding:16px;display:flex;flex-direction:column;gap:8px">
2871
+ <div style="font-weight:600">Top Sessions</div>
2872
+ <div id="tokensSessionsBody" style="font-size:13px">
2873
+ <div style="color:var(--text-dim)">Loading...</div>
2874
+ </div>
2875
+ </div>
2876
+
2877
+ <!-- Orphans -->
2878
+ <div style="border:1px solid var(--border);border-radius:8px;padding:16px;display:flex;flex-direction:column;gap:8px">
2879
+ <div style="font-weight:600">Idle Sessions (&gt; 30 min)</div>
2880
+ <div id="tokensOrphansBody" style="font-size:13px">
2881
+ <div style="color:var(--text-dim)">Loading...</div>
2882
+ </div>
2883
+ </div>
2884
+ </div>
2885
+
2886
+ <!-- Threadline Tab — agent-to-agent conversations + Telegram bridge settings -->
2887
+ <div id="threadlineTab" style="display:none;flex-direction:column;padding:20px;gap:16px;overflow-y:auto">
2888
+ <div style="display:flex;justify-content:space-between;align-items:center">
2889
+ <h2 style="margin:0">Threadline</h2>
2890
+ <button onclick="loadThreadlineBridgeConfig()" style="padding:6px 12px">Refresh</button>
2891
+ </div>
2892
+ <div style="font-size:12px;color:var(--text-dim);line-height:1.4">
2893
+ Threadline is your agent's secure channel to other AI agents. The Telegram bridge mirrors those conversations into per-thread Telegram topics so you can watch every exchange. Quiet by default — flip the master switch below to opt in.
2894
+ </div>
2895
+
2896
+ <!-- Bridge settings card -->
2897
+ <div id="tlBridgeCard" style="border:1px solid var(--border);border-radius:8px;padding:16px;display:flex;flex-direction:column;gap:14px">
2898
+ <div style="font-weight:600">Telegram bridge settings</div>
2899
+ <div id="tlBridgeStatus" style="font-size:12px;color:var(--text-dim)">Loading…</div>
2900
+
2901
+ <label style="display:flex;align-items:flex-start;gap:10px;font-size:13px">
2902
+ <input type="checkbox" id="tlBridgeEnabled" style="margin-top:3px" />
2903
+ <span>
2904
+ <strong>Bridge enabled (master switch)</strong>
2905
+ <div style="color:var(--text-dim);font-size:12px;margin-top:2px">When off, no threadline traffic reaches Telegram, regardless of the toggles below.</div>
2906
+ </span>
2907
+ </label>
2908
+
2909
+ <label style="display:flex;align-items:flex-start;gap:10px;font-size:13px">
2910
+ <input type="checkbox" id="tlBridgeAutoCreate" style="margin-top:3px" />
2911
+ <span>
2912
+ <strong>Auto-create Telegram topics for new threads</strong>
2913
+ <div style="color:var(--text-dim);font-size:12px;margin-top:2px">Default off. When off, a brand-new agent reaching out won't spawn a Telegram topic unless you've allow-listed them below.</div>
2914
+ </span>
2915
+ </label>
2916
+
2917
+ <label style="display:flex;align-items:flex-start;gap:10px;font-size:13px">
2918
+ <input type="checkbox" id="tlBridgeMirrorExisting" style="margin-top:3px" />
2919
+ <span>
2920
+ <strong>Mirror messages into existing topics</strong>
2921
+ <div style="color:var(--text-dim);font-size:12px;margin-top:2px">Default on. Once a Telegram topic exists for a thread, both inbound and outbound messages on that thread show up there.</div>
2922
+ </span>
2923
+ </label>
2924
+
2925
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:14px">
2926
+ <div>
2927
+ <div style="font-weight:600;font-size:13px;margin-bottom:6px">Allow-list</div>
2928
+ <div style="font-size:11px;color:var(--text-dim);margin-bottom:6px">Always auto-create topics for these remote agents (overrides "auto-create off").</div>
2929
+ <ul id="tlBridgeAllowList" style="list-style:none;padding:0;margin:0;font-size:13px;display:flex;flex-direction:column;gap:4px"></ul>
2930
+ <div style="display:flex;gap:6px;margin-top:8px">
2931
+ <input type="text" id="tlBridgeAllowInput" placeholder="agent fingerprint or name" style="flex:1;padding:6px 8px;font-size:12px" />
2932
+ <button onclick="tlBridgeAddListEntry('allowList', 'tlBridgeAllowInput')" style="padding:6px 10px;font-size:12px">Add</button>
2933
+ </div>
2934
+ </div>
2935
+ <div>
2936
+ <div style="font-weight:600;font-size:13px;margin-bottom:6px">Deny-list</div>
2937
+ <div style="font-size:11px;color:var(--text-dim);margin-bottom:6px">Never auto-create topics for these remote agents (overrides "auto-create on").</div>
2938
+ <ul id="tlBridgeDenyList" style="list-style:none;padding:0;margin:0;font-size:13px;display:flex;flex-direction:column;gap:4px"></ul>
2939
+ <div style="display:flex;gap:6px;margin-top:8px">
2940
+ <input type="text" id="tlBridgeDenyInput" placeholder="agent fingerprint or name" style="flex:1;padding:6px 8px;font-size:12px" />
2941
+ <button onclick="tlBridgeAddListEntry('denyList', 'tlBridgeDenyInput')" style="padding:6px 10px;font-size:12px">Add</button>
2942
+ </div>
2943
+ </div>
2944
+ </div>
2945
+
2946
+ <div id="tlBridgeError" style="color:var(--err, #c44);font-size:12px;display:none"></div>
2947
+ </div>
2948
+
2949
+ <!-- Conversation observability — threads list + message stream + search -->
2950
+ <div style="border:1px solid var(--border);border-radius:8px;padding:0;display:flex;flex-direction:column;min-height:480px">
2951
+ <!-- Toolbar -->
2952
+ <div style="display:flex;gap:8px;align-items:center;padding:12px 16px;border-bottom:1px solid var(--border)">
2953
+ <div style="font-weight:600">Conversations</div>
2954
+ <div style="flex:1"></div>
2955
+ <input type="search" id="tlObsSearchInput" placeholder="search messages…" style="padding:6px 8px;font-size:12px;width:220px" oninput="tlObsSearchDebounced(this.value)" />
2956
+ <select id="tlObsHasTopicFilter" onchange="tlObsLoadThreads()" style="padding:6px 8px;font-size:12px">
2957
+ <option value="">all threads</option>
2958
+ <option value="yes">with Telegram topic</option>
2959
+ <option value="no">without Telegram topic</option>
2960
+ </select>
2961
+ <input type="text" id="tlObsRemoteFilter" placeholder="agent filter" style="padding:6px 8px;font-size:12px;width:140px" oninput="tlObsLoadThreadsDebounced()" />
2962
+ <button onclick="tlObsLoadThreads()" style="padding:6px 10px;font-size:12px">Refresh</button>
2963
+ </div>
2964
+
2965
+ <!-- Two-pane: threads list + active thread -->
2966
+ <div style="display:grid;grid-template-columns:280px 1fr;flex:1;min-height:420px">
2967
+ <ul id="tlObsThreadsList" style="list-style:none;padding:0;margin:0;border-right:1px solid var(--border);overflow-y:auto;max-height:520px">
2968
+ <li style="padding:16px;color:var(--text-dim);font-size:12px">Loading…</li>
2969
+ </ul>
2970
+ <div id="tlObsConversation" style="padding:16px;overflow-y:auto;max-height:520px;display:flex;flex-direction:column;gap:10px">
2971
+ <div style="color:var(--text-dim);font-size:12px;font-style:italic">Select a thread on the left to view the conversation.</div>
2972
+ </div>
2973
+ </div>
2974
+
2975
+ <!-- Search results -->
2976
+ <div id="tlObsSearchResults" style="display:none;border-top:1px solid var(--border);padding:12px 16px;max-height:280px;overflow-y:auto"></div>
2977
+ </div>
2978
+ </div>
2979
+
2849
2980
  <!-- Health Tab (was Systems) -->
2850
2981
  <div class="systems-container" id="systemsTab" style="display:none">
2851
2982
  <div class="systems-main">
@@ -3892,6 +4023,21 @@
3892
4023
  display: ['flex'],
3893
4024
  onActivate: () => { if (typeof loadCommitments === 'function') loadCommitments(); },
3894
4025
  },
4026
+ {
4027
+ id: 'tokens',
4028
+ panels: ['tokensPanel'],
4029
+ display: ['flex'],
4030
+ onActivate: () => { if (typeof loadTokens === 'function') loadTokens(); },
4031
+ },
4032
+ {
4033
+ id: 'threadline',
4034
+ panels: ['threadlineTab'],
4035
+ display: ['flex'],
4036
+ onActivate: () => {
4037
+ if (typeof loadThreadlineBridgeConfig === 'function') loadThreadlineBridgeConfig();
4038
+ if (typeof tlObsLoadThreads === 'function') tlObsLoadThreads();
4039
+ },
4040
+ },
3895
4041
  {
3896
4042
  id: 'secrets',
3897
4043
  panels: ['secretsPanel'],
@@ -3997,6 +4143,346 @@
3997
4143
  return resp.json();
3998
4144
  }
3999
4145
 
4146
+ // ── Tokens Tab ──────────────────────────────────────────────────
4147
+ function fmtTokens(n) {
4148
+ if (n == null) return '0';
4149
+ if (n >= 1e9) return (n / 1e9).toFixed(2) + 'B';
4150
+ if (n >= 1e6) return (n / 1e6).toFixed(2) + 'M';
4151
+ if (n >= 1e3) return (n / 1e3).toFixed(1) + 'k';
4152
+ return String(n);
4153
+ }
4154
+ function fmtRelTime(ts) {
4155
+ if (!ts) return '—';
4156
+ const diff = Date.now() - ts;
4157
+ const min = Math.floor(diff / 60000);
4158
+ if (min < 1) return 'just now';
4159
+ if (min < 60) return min + 'm ago';
4160
+ const hr = Math.floor(min / 60);
4161
+ if (hr < 24) return hr + 'h ago';
4162
+ return Math.floor(hr / 24) + 'd ago';
4163
+ }
4164
+ function escapeHtml(s) {
4165
+ return String(s ?? '').replace(/[&<>"']/g, c => ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' }[c]));
4166
+ }
4167
+ async function loadTokens() {
4168
+ const summaryEl = document.getElementById('tokensSummaryBody');
4169
+ const sessionsEl = document.getElementById('tokensSessionsBody');
4170
+ const orphansEl = document.getElementById('tokensOrphansBody');
4171
+ try {
4172
+ const [summaryResp, sessionsResp, orphansResp] = await Promise.all([
4173
+ apiFetch('/tokens/summary'),
4174
+ apiFetch('/tokens/sessions?limit=10'),
4175
+ apiFetch('/tokens/orphans?idleMs=' + (30 * 60 * 1000)),
4176
+ ]);
4177
+ const s = summaryResp.summary || {};
4178
+ summaryEl.innerHTML = `
4179
+ <div><div style="color:var(--text-dim)">Total tokens</div><div style="font-size:18px;font-weight:600">${fmtTokens(s.totalTokens)}</div></div>
4180
+ <div><div style="color:var(--text-dim)">Input</div><div>${fmtTokens(s.totalInput)}</div></div>
4181
+ <div><div style="color:var(--text-dim)">Output</div><div>${fmtTokens(s.totalOutput)}</div></div>
4182
+ <div><div style="color:var(--text-dim)">Cache read</div><div>${fmtTokens(s.totalCacheRead)}</div></div>
4183
+ <div><div style="color:var(--text-dim)">Cache create</div><div>${fmtTokens(s.totalCacheCreate)}</div></div>
4184
+ <div><div style="color:var(--text-dim)">Events</div><div>${fmtTokens(s.eventCount)}</div></div>
4185
+ <div><div style="color:var(--text-dim)">Sessions</div><div>${fmtTokens(s.sessionsActive)}</div></div>
4186
+ `;
4187
+
4188
+ const sessions = sessionsResp.sessions || [];
4189
+ if (sessions.length === 0) {
4190
+ sessionsEl.innerHTML = '<div style="color:var(--text-dim)">No sessions in window.</div>';
4191
+ } else {
4192
+ sessionsEl.innerHTML = `
4193
+ <table style="width:100%;border-collapse:collapse;font-size:13px">
4194
+ <thead><tr style="text-align:left;color:var(--text-dim)">
4195
+ <th style="padding:6px 8px">Session</th>
4196
+ <th style="padding:6px 8px">Project</th>
4197
+ <th style="padding:6px 8px;text-align:right">Tokens</th>
4198
+ <th style="padding:6px 8px;text-align:right">Events</th>
4199
+ <th style="padding:6px 8px">Last activity</th>
4200
+ </tr></thead>
4201
+ <tbody>
4202
+ ${sessions.map(r => `
4203
+ <tr style="border-top:1px solid var(--border)">
4204
+ <td style="padding:6px 8px;font-family:monospace">${escapeHtml((r.sessionId || '').slice(0, 8))}</td>
4205
+ <td style="padding:6px 8px">${escapeHtml(r.projectPath || '—')}</td>
4206
+ <td style="padding:6px 8px;text-align:right">${fmtTokens(r.totalTokens)}</td>
4207
+ <td style="padding:6px 8px;text-align:right">${fmtTokens(r.eventCount)}</td>
4208
+ <td style="padding:6px 8px">${fmtRelTime(r.lastTs)}</td>
4209
+ </tr>
4210
+ `).join('')}
4211
+ </tbody>
4212
+ </table>
4213
+ `;
4214
+ }
4215
+
4216
+ const orphans = orphansResp.orphans || [];
4217
+ if (orphans.length === 0) {
4218
+ orphansEl.innerHTML = '<div style="color:var(--text-dim)">No idle sessions.</div>';
4219
+ } else {
4220
+ orphansEl.innerHTML = orphans.map(o => `
4221
+ <div style="padding:6px 0;border-top:1px solid var(--border);display:flex;justify-content:space-between;font-family:monospace;font-size:12px">
4222
+ <span>${escapeHtml((o.sessionId || '').slice(0, 12))}</span>
4223
+ <span style="color:var(--text-dim)">${escapeHtml(o.projectPath || '—')}</span>
4224
+ <span>${fmtRelTime(o.lastTs)}</span>
4225
+ </div>
4226
+ `).join('');
4227
+ }
4228
+ } catch (err) {
4229
+ const msg = `<div style="color:var(--red)">Error: ${escapeHtml(err.message || String(err))}</div>`;
4230
+ summaryEl.innerHTML = msg;
4231
+ sessionsEl.innerHTML = '';
4232
+ orphansEl.innerHTML = '';
4233
+ }
4234
+ }
4235
+
4236
+ // ── Threadline → Telegram bridge settings ──────────────────
4237
+ let tlBridgeSettings = null;
4238
+ let tlBridgeWiring = false;
4239
+
4240
+ async function loadThreadlineBridgeConfig() {
4241
+ const statusEl = document.getElementById('tlBridgeStatus');
4242
+ const errEl = document.getElementById('tlBridgeError');
4243
+ if (errEl) { errEl.style.display = 'none'; errEl.textContent = ''; }
4244
+ try {
4245
+ const resp = await apiFetch('/threadline/telegram-bridge/config');
4246
+ tlBridgeSettings = resp;
4247
+ renderThreadlineBridgeConfig();
4248
+ if (statusEl) statusEl.textContent = `Bridge is ${resp.enabled ? 'ENABLED' : 'OFF'} · auto-create ${resp.autoCreateTopics ? 'on' : 'off'} · mirror existing ${resp.mirrorExisting ? 'on' : 'off'}.`;
4249
+ } catch (err) {
4250
+ if (statusEl) statusEl.textContent = '';
4251
+ if (errEl) { errEl.style.display = 'block'; errEl.textContent = `Could not load bridge config: ${err.message || String(err)}`; }
4252
+ }
4253
+ }
4254
+
4255
+ function renderThreadlineBridgeConfig() {
4256
+ if (!tlBridgeSettings) return;
4257
+ tlBridgeWiring = true;
4258
+ try {
4259
+ document.getElementById('tlBridgeEnabled').checked = !!tlBridgeSettings.enabled;
4260
+ document.getElementById('tlBridgeAutoCreate').checked = !!tlBridgeSettings.autoCreateTopics;
4261
+ document.getElementById('tlBridgeMirrorExisting').checked = !!tlBridgeSettings.mirrorExisting;
4262
+ renderTlBridgeListEntries('allowList', 'tlBridgeAllowList', tlBridgeSettings.allowList || []);
4263
+ renderTlBridgeListEntries('denyList', 'tlBridgeDenyList', tlBridgeSettings.denyList || []);
4264
+ } finally {
4265
+ tlBridgeWiring = false;
4266
+ }
4267
+ }
4268
+
4269
+ function renderTlBridgeListEntries(field, listElId, entries) {
4270
+ const ul = document.getElementById(listElId);
4271
+ if (!ul) return;
4272
+ if (entries.length === 0) {
4273
+ ul.innerHTML = '<li style="color:var(--text-dim);font-size:12px;font-style:italic">(empty)</li>';
4274
+ return;
4275
+ }
4276
+ ul.innerHTML = entries.map(e => `
4277
+ <li style="display:flex;justify-content:space-between;align-items:center;padding:4px 8px;border:1px solid var(--border);border-radius:4px;font-family:monospace;font-size:12px">
4278
+ <span>${escapeHtml(e)}</span>
4279
+ <button onclick="tlBridgeRemoveListEntry('${field}', ${JSON.stringify(e).replace(/'/g, "\\'")})" style="padding:2px 8px;font-size:11px">remove</button>
4280
+ </li>
4281
+ `).join('');
4282
+ }
4283
+
4284
+ async function tlBridgePatchConfig(patch) {
4285
+ const errEl = document.getElementById('tlBridgeError');
4286
+ if (errEl) { errEl.style.display = 'none'; errEl.textContent = ''; }
4287
+ try {
4288
+ const resp = await apiFetch('/threadline/telegram-bridge/config', {
4289
+ method: 'PATCH',
4290
+ headers: { 'Content-Type': 'application/json' },
4291
+ body: JSON.stringify(patch),
4292
+ });
4293
+ tlBridgeSettings = resp;
4294
+ renderThreadlineBridgeConfig();
4295
+ const statusEl = document.getElementById('tlBridgeStatus');
4296
+ if (statusEl) statusEl.textContent = `Saved · bridge is ${resp.enabled ? 'ENABLED' : 'OFF'}.`;
4297
+ } catch (err) {
4298
+ if (errEl) { errEl.style.display = 'block'; errEl.textContent = `Update failed: ${err.message || String(err)}`; }
4299
+ // Reload to roll back the optimistic UI
4300
+ loadThreadlineBridgeConfig();
4301
+ }
4302
+ }
4303
+
4304
+ function tlBridgeAddListEntry(field, inputId) {
4305
+ const input = document.getElementById(inputId);
4306
+ const val = (input?.value || '').trim();
4307
+ if (!val) return;
4308
+ const current = (tlBridgeSettings?.[field] || []).slice();
4309
+ if (!current.includes(val)) current.push(val);
4310
+ tlBridgePatchConfig({ [field]: current });
4311
+ if (input) input.value = '';
4312
+ }
4313
+
4314
+ function tlBridgeRemoveListEntry(field, entry) {
4315
+ const current = (tlBridgeSettings?.[field] || []).filter(x => x !== entry);
4316
+ tlBridgePatchConfig({ [field]: current });
4317
+ }
4318
+
4319
+ // Wire up toggle change-handlers once the panel exists
4320
+ document.addEventListener('DOMContentLoaded', () => {
4321
+ const wire = (id, field) => {
4322
+ const el = document.getElementById(id);
4323
+ if (!el) return;
4324
+ el.addEventListener('change', () => {
4325
+ if (tlBridgeWiring) return;
4326
+ tlBridgePatchConfig({ [field]: el.checked });
4327
+ });
4328
+ };
4329
+ wire('tlBridgeEnabled', 'enabled');
4330
+ wire('tlBridgeAutoCreate', 'autoCreateTopics');
4331
+ wire('tlBridgeMirrorExisting', 'mirrorExisting');
4332
+ });
4333
+
4334
+ // ── Threadline observability — threads list + conversation view ──
4335
+ let tlObsActiveThreadId = null;
4336
+ let tlObsLoadThreadsTimer = null;
4337
+ let tlObsSearchTimer = null;
4338
+
4339
+ function tlObsLoadThreadsDebounced() {
4340
+ if (tlObsLoadThreadsTimer) clearTimeout(tlObsLoadThreadsTimer);
4341
+ tlObsLoadThreadsTimer = setTimeout(tlObsLoadThreads, 300);
4342
+ }
4343
+
4344
+ function tlObsSearchDebounced(value) {
4345
+ if (tlObsSearchTimer) clearTimeout(tlObsSearchTimer);
4346
+ tlObsSearchTimer = setTimeout(() => tlObsRunSearch(value), 300);
4347
+ }
4348
+
4349
+ async function tlObsLoadThreads() {
4350
+ const list = document.getElementById('tlObsThreadsList');
4351
+ if (!list) return;
4352
+ const remoteAgent = document.getElementById('tlObsRemoteFilter')?.value?.trim() || '';
4353
+ const hasTopic = document.getElementById('tlObsHasTopicFilter')?.value || '';
4354
+ const params = new URLSearchParams();
4355
+ if (remoteAgent) params.set('remoteAgent', remoteAgent);
4356
+ if (hasTopic) params.set('hasTopic', hasTopic);
4357
+ try {
4358
+ const resp = await apiFetch('/threadline/observability/threads?' + params.toString());
4359
+ const threads = resp.threads || [];
4360
+ if (threads.length === 0) {
4361
+ list.innerHTML = '<li style="padding:16px;color:var(--text-dim);font-size:12px;font-style:italic">No threads yet.</li>';
4362
+ return;
4363
+ }
4364
+ list.innerHTML = threads.map(t => tlObsRenderThreadRow(t)).join('');
4365
+ } catch (err) {
4366
+ list.innerHTML = `<li style="padding:16px;color:var(--red)">Error: ${escapeHtml(err.message || String(err))}</li>`;
4367
+ }
4368
+ }
4369
+
4370
+ function tlObsRenderThreadRow(t) {
4371
+ const lastSeen = t.lastSeen ? fmtRelTime(t.lastSeen) : '—';
4372
+ const bridgeBadge = t.bridge
4373
+ ? '<span style="display:inline-block;padding:1px 6px;border-radius:8px;background:#3b82f6;color:#fff;font-size:10px;margin-left:6px">TG</span>'
4374
+ : '';
4375
+ const spawnBadge = t.hasSpawnedSession
4376
+ ? '<span style="display:inline-block;padding:1px 6px;border-radius:8px;background:#16a34a;color:#fff;font-size:10px;margin-left:4px">S</span>'
4377
+ : '';
4378
+ const isActive = tlObsActiveThreadId === t.threadId ? 'background:rgba(59,130,246,0.08);' : '';
4379
+ return `
4380
+ <li onclick="tlObsLoadThread('${t.threadId.replace(/'/g, "\\'")}')"
4381
+ style="padding:10px 12px;border-bottom:1px solid var(--border);cursor:pointer;${isActive}">
4382
+ <div style="display:flex;justify-content:space-between;align-items:center">
4383
+ <div style="font-weight:600;font-size:13px">${escapeHtml(t.remoteAgentName)}${bridgeBadge}${spawnBadge}</div>
4384
+ <div style="font-size:11px;color:var(--text-dim)">${escapeHtml(lastSeen)}</div>
4385
+ </div>
4386
+ <div style="font-size:11px;color:var(--text-dim);margin-top:2px;font-family:monospace">
4387
+ ${escapeHtml(t.threadId.slice(0, 16))}…
4388
+ </div>
4389
+ <div style="font-size:11px;color:var(--text-dim);margin-top:2px">
4390
+ ${t.messageCount} msgs · ${t.inboundCount} in / ${t.outboundCount} out
4391
+ ${typeof t.avgResponseLatencyMs === 'number' ? ' · ~' + Math.round(t.avgResponseLatencyMs / 1000) + 's reply' : ''}
4392
+ </div>
4393
+ </li>
4394
+ `;
4395
+ }
4396
+
4397
+ async function tlObsLoadThread(threadId) {
4398
+ tlObsActiveThreadId = threadId;
4399
+ tlObsLoadThreads(); // Re-render threads list to highlight active row
4400
+ const conv = document.getElementById('tlObsConversation');
4401
+ if (!conv) return;
4402
+ conv.innerHTML = '<div style="color:var(--text-dim);font-size:12px">Loading…</div>';
4403
+ try {
4404
+ const detail = await apiFetch(`/threadline/observability/threads/${encodeURIComponent(threadId)}`);
4405
+ conv.innerHTML = tlObsRenderConversation(detail);
4406
+ } catch (err) {
4407
+ conv.innerHTML = `<div style="color:var(--red);font-size:12px">Error: ${escapeHtml(err.message || String(err))}</div>`;
4408
+ }
4409
+ }
4410
+
4411
+ function tlObsRenderConversation(detail) {
4412
+ const header = `
4413
+ <div style="border-bottom:1px solid var(--border);padding-bottom:10px;margin-bottom:10px">
4414
+ <div style="font-weight:600;font-size:14px">${escapeHtml(detail.remoteAgentName)}</div>
4415
+ <div style="font-family:monospace;font-size:11px;color:var(--text-dim)">${escapeHtml(detail.threadId)}</div>
4416
+ <div style="display:flex;gap:14px;font-size:11px;color:var(--text-dim);margin-top:6px;flex-wrap:wrap">
4417
+ <span>${detail.messageCount} messages</span>
4418
+ <span>${detail.inboundCount} in / ${detail.outboundCount} out</span>
4419
+ <span>first: ${escapeHtml(fmtRelTime(detail.firstSeen))}</span>
4420
+ <span>last: ${escapeHtml(fmtRelTime(detail.lastSeen))}</span>
4421
+ ${typeof detail.avgResponseLatencyMs === 'number' ? '<span>avg reply: ' + Math.round(detail.avgResponseLatencyMs/1000) + 's</span>' : ''}
4422
+ ${detail.bridge ? '<span>📨 topic ' + detail.bridge.topicId + '</span>' : '<span style="color:var(--text-dim);font-style:italic">no Telegram topic</span>'}
4423
+ ${detail.hasSpawnedSession ? '<span>🧵 spawn-session</span>' : ''}
4424
+ </div>
4425
+ </div>
4426
+ `;
4427
+ const messages = (detail.messages || []).map(m => tlObsRenderMessage(m)).join('');
4428
+ return header + messages;
4429
+ }
4430
+
4431
+ function tlObsRenderMessage(m) {
4432
+ const isIn = m.direction === 'in';
4433
+ const bg = isIn ? 'rgba(99,102,241,0.10)' : 'rgba(34,197,94,0.10)';
4434
+ const border = isIn ? '#6366f1' : '#22c55e';
4435
+ const arrow = isIn ? '←' : '→';
4436
+ const meta = `${escapeHtml(m.timestamp)} · ${escapeHtml(m.id.slice(0, 8))}${m.outcome ? ' · ' + escapeHtml(m.outcome) : ''} · trust:${escapeHtml(m.trustLevel)}`;
4437
+ return `
4438
+ <div style="border-left:3px solid ${border};background:${bg};padding:8px 10px;border-radius:4px">
4439
+ <div style="display:flex;justify-content:space-between;align-items:baseline;margin-bottom:4px">
4440
+ <div style="font-weight:600;font-size:12px">
4441
+ ${arrow} ${escapeHtml(m.remoteAgentName)}
4442
+ </div>
4443
+ <div style="font-size:11px;color:var(--text-dim)">${escapeHtml(fmtRelTime(m.timestamp))}</div>
4444
+ </div>
4445
+ <div style="font-size:13px;white-space:pre-wrap;word-break:break-word;line-height:1.4">${escapeHtml(m.text)}</div>
4446
+ <div style="font-family:monospace;font-size:10px;color:var(--text-dim);margin-top:4px">${meta}</div>
4447
+ </div>
4448
+ `;
4449
+ }
4450
+
4451
+ async function tlObsRunSearch(query) {
4452
+ const panel = document.getElementById('tlObsSearchResults');
4453
+ if (!panel) return;
4454
+ const q = (query || '').trim();
4455
+ if (!q) { panel.style.display = 'none'; return; }
4456
+ panel.style.display = 'block';
4457
+ panel.innerHTML = '<div style="color:var(--text-dim);font-size:12px">Searching…</div>';
4458
+ try {
4459
+ const resp = await apiFetch('/threadline/observability/search?q=' + encodeURIComponent(q) + '&limit=30');
4460
+ const hits = resp.hits || [];
4461
+ if (hits.length === 0) {
4462
+ panel.innerHTML = '<div style="color:var(--text-dim);font-size:12px">No matches.</div>';
4463
+ return;
4464
+ }
4465
+ panel.innerHTML = `<div style="font-size:12px;color:var(--text-dim);margin-bottom:8px">${hits.length} match${hits.length === 1 ? '' : 'es'} (click to open thread)</div>` +
4466
+ hits.map(h => `
4467
+ <div onclick="tlObsLoadThread('${h.message.threadId.replace(/'/g, "\\'")}')"
4468
+ style="padding:6px 8px;border-bottom:1px solid var(--border);cursor:pointer;font-size:12px">
4469
+ <div style="display:flex;justify-content:space-between">
4470
+ <span style="font-weight:600">${h.message.direction === 'in' ? '←' : '→'} ${escapeHtml(h.message.remoteAgentName)}</span>
4471
+ <span style="font-size:11px;color:var(--text-dim)">${escapeHtml(fmtRelTime(h.message.timestamp))}</span>
4472
+ </div>
4473
+ <div style="margin-top:2px;line-height:1.4">${tlObsRenderSnippet(h.snippet)}</div>
4474
+ </div>
4475
+ `).join('');
4476
+ } catch (err) {
4477
+ panel.innerHTML = `<div style="color:var(--red);font-size:12px">Error: ${escapeHtml(err.message || String(err))}</div>`;
4478
+ }
4479
+ }
4480
+
4481
+ function tlObsRenderSnippet(s) {
4482
+ // Server returns matches wrapped in «...» — render as <mark>
4483
+ return escapeHtml(s).replace(/«/g, '<mark style="background:#fef08a;color:#000">').replace(/»/g, '</mark>');
4484
+ }
4485
+
4000
4486
  async function loadFileTree() {
4001
4487
  fileTreeLoaded = true;
4002
4488
  const list = document.getElementById('fileTreeList');
package/dist/cli.js CHANGED
@@ -21,6 +21,7 @@ import fs from 'node:fs';
21
21
  import path from 'node:path';
22
22
  import { Command } from 'commander';
23
23
  import { initProject } from './commands/init.js';
24
+ import { SafeFsExecutor } from './core/SafeFsExecutor.js';
24
25
  // setup.ts is imported dynamically — it depends on @inquirer/prompts which requires Node 20.12+
25
26
  import { startServer, stopServer, restartServer } from './commands/server.js';
26
27
  import { showStatus } from './commands/status.js';
@@ -82,9 +83,8 @@ async function addTelegram(opts) {
82
83
  fs.renameSync(tmpPath, configPath);
83
84
  }
84
85
  catch (err) {
85
- // safe-git-allow: incremental-migration
86
86
  try {
87
- fs.unlinkSync(tmpPath);
87
+ SafeFsExecutor.safeUnlinkSync(tmpPath, { operation: 'src/cli.ts:93' });
88
88
  }
89
89
  catch { /* ignore */ }
90
90
  throw err;
@@ -135,9 +135,8 @@ async function addSentry(opts) {
135
135
  fs.renameSync(tmpPath, configPath);
136
136
  }
137
137
  catch (err) {
138
- // safe-git-allow: incremental-migration
139
138
  try {
140
- fs.unlinkSync(tmpPath);
139
+ SafeFsExecutor.safeUnlinkSync(tmpPath, { operation: 'src/cli.ts:148' });
141
140
  }
142
141
  catch { /* ignore */ }
143
142
  throw err;
@@ -196,9 +195,8 @@ async function addEmail(opts) {
196
195
  fs.renameSync(tmpPath, configPath);
197
196
  }
198
197
  catch (err) {
199
- // safe-git-allow: incremental-migration
200
198
  try {
201
- fs.unlinkSync(tmpPath);
199
+ SafeFsExecutor.safeUnlinkSync(tmpPath, { operation: 'src/cli.ts:211' });
202
200
  }
203
201
  catch { /* ignore */ }
204
202
  throw err;
@@ -240,9 +238,8 @@ async function addQuota(opts) {
240
238
  fs.renameSync(tmpPath, configPath);
241
239
  }
242
240
  catch (err) {
243
- // safe-git-allow: incremental-migration
244
241
  try {
245
- fs.unlinkSync(tmpPath);
242
+ SafeFsExecutor.safeUnlinkSync(tmpPath, { operation: 'src/cli.ts:257' });
246
243
  }
247
244
  catch { /* ignore */ }
248
245
  throw err;