@iflow-mcp/jkheadley-instar 0.26.2

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 (1671) hide show
  1. package/.claude/hooks/free-text-guard.sh +117 -0
  2. package/.claude/settings.json +201 -0
  3. package/.claude/skills/autonomous/hooks/autonomous-stop-hook.sh +234 -0
  4. package/.claude/skills/autonomous/hooks/hooks.json +15 -0
  5. package/.claude/skills/autonomous/scripts/setup-autonomous.sh +166 -0
  6. package/.claude/skills/autonomous/skill.md +254 -0
  7. package/.claude/skills/secret-setup/skill.md +210 -0
  8. package/.claude/skills/setup-wizard/skill.md +2132 -0
  9. package/LICENSE +21 -0
  10. package/README.md +214 -0
  11. package/dashboard/favicon.png +0 -0
  12. package/dashboard/index.html +5740 -0
  13. package/dashboard/logo.png +0 -0
  14. package/dist/cli.d.ts +21 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +1782 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/commands/backup.d.ts +16 -0
  19. package/dist/commands/backup.d.ts.map +1 -0
  20. package/dist/commands/backup.js +84 -0
  21. package/dist/commands/backup.js.map +1 -0
  22. package/dist/commands/discovery.d.ts +158 -0
  23. package/dist/commands/discovery.d.ts.map +1 -0
  24. package/dist/commands/discovery.js +532 -0
  25. package/dist/commands/discovery.js.map +1 -0
  26. package/dist/commands/git.d.ts +25 -0
  27. package/dist/commands/git.d.ts.map +1 -0
  28. package/dist/commands/git.js +152 -0
  29. package/dist/commands/git.js.map +1 -0
  30. package/dist/commands/init.d.ts +52 -0
  31. package/dist/commands/init.d.ts.map +1 -0
  32. package/dist/commands/init.js +4211 -0
  33. package/dist/commands/init.js.map +1 -0
  34. package/dist/commands/intent.d.ts +30 -0
  35. package/dist/commands/intent.d.ts.map +1 -0
  36. package/dist/commands/intent.js +349 -0
  37. package/dist/commands/intent.js.map +1 -0
  38. package/dist/commands/job.d.ts +42 -0
  39. package/dist/commands/job.d.ts.map +1 -0
  40. package/dist/commands/job.js +202 -0
  41. package/dist/commands/job.js.map +1 -0
  42. package/dist/commands/knowledge.d.ts +25 -0
  43. package/dist/commands/knowledge.d.ts.map +1 -0
  44. package/dist/commands/knowledge.js +127 -0
  45. package/dist/commands/knowledge.js.map +1 -0
  46. package/dist/commands/machine.d.ts +53 -0
  47. package/dist/commands/machine.d.ts.map +1 -0
  48. package/dist/commands/machine.js +680 -0
  49. package/dist/commands/machine.js.map +1 -0
  50. package/dist/commands/memory.d.ts +24 -0
  51. package/dist/commands/memory.d.ts.map +1 -0
  52. package/dist/commands/memory.js +163 -0
  53. package/dist/commands/memory.js.map +1 -0
  54. package/dist/commands/nuke.d.ts +22 -0
  55. package/dist/commands/nuke.d.ts.map +1 -0
  56. package/dist/commands/nuke.js +216 -0
  57. package/dist/commands/nuke.js.map +1 -0
  58. package/dist/commands/org.d.ts +16 -0
  59. package/dist/commands/org.d.ts.map +1 -0
  60. package/dist/commands/org.js +69 -0
  61. package/dist/commands/org.js.map +1 -0
  62. package/dist/commands/playbook.d.ts +91 -0
  63. package/dist/commands/playbook.d.ts.map +1 -0
  64. package/dist/commands/playbook.js +1016 -0
  65. package/dist/commands/playbook.js.map +1 -0
  66. package/dist/commands/reflect.d.ts +52 -0
  67. package/dist/commands/reflect.d.ts.map +1 -0
  68. package/dist/commands/reflect.js +316 -0
  69. package/dist/commands/reflect.js.map +1 -0
  70. package/dist/commands/relationship.d.ts +17 -0
  71. package/dist/commands/relationship.d.ts.map +1 -0
  72. package/dist/commands/relationship.js +156 -0
  73. package/dist/commands/relationship.js.map +1 -0
  74. package/dist/commands/relay.d.ts +26 -0
  75. package/dist/commands/relay.d.ts.map +1 -0
  76. package/dist/commands/relay.js +121 -0
  77. package/dist/commands/relay.js.map +1 -0
  78. package/dist/commands/review.d.ts +18 -0
  79. package/dist/commands/review.d.ts.map +1 -0
  80. package/dist/commands/review.js +193 -0
  81. package/dist/commands/review.js.map +1 -0
  82. package/dist/commands/semantic.d.ts +37 -0
  83. package/dist/commands/semantic.d.ts.map +1 -0
  84. package/dist/commands/semantic.js +198 -0
  85. package/dist/commands/semantic.js.map +1 -0
  86. package/dist/commands/server.d.ts +37 -0
  87. package/dist/commands/server.d.ts.map +1 -0
  88. package/dist/commands/server.js +4875 -0
  89. package/dist/commands/server.js.map +1 -0
  90. package/dist/commands/setup.d.ts +63 -0
  91. package/dist/commands/setup.d.ts.map +1 -0
  92. package/dist/commands/setup.js +1235 -0
  93. package/dist/commands/setup.js.map +1 -0
  94. package/dist/commands/slack-cli.d.ts +16 -0
  95. package/dist/commands/slack-cli.d.ts.map +1 -0
  96. package/dist/commands/slack-cli.js +259 -0
  97. package/dist/commands/slack-cli.js.map +1 -0
  98. package/dist/commands/status.d.ts +11 -0
  99. package/dist/commands/status.d.ts.map +1 -0
  100. package/dist/commands/status.js +120 -0
  101. package/dist/commands/status.js.map +1 -0
  102. package/dist/commands/user.d.ts +17 -0
  103. package/dist/commands/user.d.ts.map +1 -0
  104. package/dist/commands/user.js +53 -0
  105. package/dist/commands/user.js.map +1 -0
  106. package/dist/commands/whatsapp.d.ts +31 -0
  107. package/dist/commands/whatsapp.d.ts.map +1 -0
  108. package/dist/commands/whatsapp.js +408 -0
  109. package/dist/commands/whatsapp.js.map +1 -0
  110. package/dist/config/ConfigDefaults.d.ts +40 -0
  111. package/dist/config/ConfigDefaults.d.ts.map +1 -0
  112. package/dist/config/ConfigDefaults.js +175 -0
  113. package/dist/config/ConfigDefaults.js.map +1 -0
  114. package/dist/config/LiveConfig.d.ts +97 -0
  115. package/dist/config/LiveConfig.d.ts.map +1 -0
  116. package/dist/config/LiveConfig.js +220 -0
  117. package/dist/config/LiveConfig.js.map +1 -0
  118. package/dist/core/AccessControl.d.ts +91 -0
  119. package/dist/core/AccessControl.d.ts.map +1 -0
  120. package/dist/core/AccessControl.js +184 -0
  121. package/dist/core/AccessControl.js.map +1 -0
  122. package/dist/core/AdaptationValidator.d.ts +44 -0
  123. package/dist/core/AdaptationValidator.d.ts.map +1 -0
  124. package/dist/core/AdaptationValidator.js +132 -0
  125. package/dist/core/AdaptationValidator.js.map +1 -0
  126. package/dist/core/AdaptiveTrust.d.ts +188 -0
  127. package/dist/core/AdaptiveTrust.d.ts.map +1 -0
  128. package/dist/core/AdaptiveTrust.js +354 -0
  129. package/dist/core/AdaptiveTrust.js.map +1 -0
  130. package/dist/core/AgentBus.d.ts +168 -0
  131. package/dist/core/AgentBus.d.ts.map +1 -0
  132. package/dist/core/AgentBus.js +369 -0
  133. package/dist/core/AgentBus.js.map +1 -0
  134. package/dist/core/AgentConnector.d.ts +76 -0
  135. package/dist/core/AgentConnector.d.ts.map +1 -0
  136. package/dist/core/AgentConnector.js +324 -0
  137. package/dist/core/AgentConnector.js.map +1 -0
  138. package/dist/core/AgentRegistry.d.ts +107 -0
  139. package/dist/core/AgentRegistry.d.ts.map +1 -0
  140. package/dist/core/AgentRegistry.js +569 -0
  141. package/dist/core/AgentRegistry.js.map +1 -0
  142. package/dist/core/AnthropicIntelligenceProvider.d.ts +24 -0
  143. package/dist/core/AnthropicIntelligenceProvider.d.ts.map +1 -0
  144. package/dist/core/AnthropicIntelligenceProvider.js +63 -0
  145. package/dist/core/AnthropicIntelligenceProvider.js.map +1 -0
  146. package/dist/core/AuditTrail.d.ts +207 -0
  147. package/dist/core/AuditTrail.d.ts.map +1 -0
  148. package/dist/core/AuditTrail.js +271 -0
  149. package/dist/core/AuditTrail.js.map +1 -0
  150. package/dist/core/AutoApprover.d.ts +63 -0
  151. package/dist/core/AutoApprover.d.ts.map +1 -0
  152. package/dist/core/AutoApprover.js +151 -0
  153. package/dist/core/AutoApprover.js.map +1 -0
  154. package/dist/core/AutoDispatcher.d.ts +170 -0
  155. package/dist/core/AutoDispatcher.d.ts.map +1 -0
  156. package/dist/core/AutoDispatcher.js +647 -0
  157. package/dist/core/AutoDispatcher.js.map +1 -0
  158. package/dist/core/AutoUpdater.d.ts +193 -0
  159. package/dist/core/AutoUpdater.d.ts.map +1 -0
  160. package/dist/core/AutoUpdater.js +648 -0
  161. package/dist/core/AutoUpdater.js.map +1 -0
  162. package/dist/core/AutonomousEvolution.d.ts +168 -0
  163. package/dist/core/AutonomousEvolution.d.ts.map +1 -0
  164. package/dist/core/AutonomousEvolution.js +384 -0
  165. package/dist/core/AutonomousEvolution.js.map +1 -0
  166. package/dist/core/AutonomyProfileManager.d.ts +108 -0
  167. package/dist/core/AutonomyProfileManager.d.ts.map +1 -0
  168. package/dist/core/AutonomyProfileManager.js +323 -0
  169. package/dist/core/AutonomyProfileManager.js.map +1 -0
  170. package/dist/core/AutonomySkill.d.ts +98 -0
  171. package/dist/core/AutonomySkill.d.ts.map +1 -0
  172. package/dist/core/AutonomySkill.js +497 -0
  173. package/dist/core/AutonomySkill.js.map +1 -0
  174. package/dist/core/BackupManager.d.ts +66 -0
  175. package/dist/core/BackupManager.d.ts.map +1 -0
  176. package/dist/core/BackupManager.js +266 -0
  177. package/dist/core/BackupManager.js.map +1 -0
  178. package/dist/core/BitwardenProvider.d.ts +85 -0
  179. package/dist/core/BitwardenProvider.d.ts.map +1 -0
  180. package/dist/core/BitwardenProvider.js +437 -0
  181. package/dist/core/BitwardenProvider.js.map +1 -0
  182. package/dist/core/BlockerLearningLoop.d.ts +99 -0
  183. package/dist/core/BlockerLearningLoop.d.ts.map +1 -0
  184. package/dist/core/BlockerLearningLoop.js +205 -0
  185. package/dist/core/BlockerLearningLoop.js.map +1 -0
  186. package/dist/core/BranchManager.d.ts +165 -0
  187. package/dist/core/BranchManager.d.ts.map +1 -0
  188. package/dist/core/BranchManager.js +413 -0
  189. package/dist/core/BranchManager.js.map +1 -0
  190. package/dist/core/CaffeinateManager.d.ts +50 -0
  191. package/dist/core/CaffeinateManager.d.ts.map +1 -0
  192. package/dist/core/CaffeinateManager.js +189 -0
  193. package/dist/core/CaffeinateManager.js.map +1 -0
  194. package/dist/core/CallbackRegistry.d.ts +67 -0
  195. package/dist/core/CallbackRegistry.d.ts.map +1 -0
  196. package/dist/core/CallbackRegistry.js +145 -0
  197. package/dist/core/CallbackRegistry.js.map +1 -0
  198. package/dist/core/CanonicalState.d.ts +132 -0
  199. package/dist/core/CanonicalState.d.ts.map +1 -0
  200. package/dist/core/CanonicalState.js +297 -0
  201. package/dist/core/CanonicalState.js.map +1 -0
  202. package/dist/core/CapabilityMapper.d.ts +192 -0
  203. package/dist/core/CapabilityMapper.d.ts.map +1 -0
  204. package/dist/core/CapabilityMapper.js +958 -0
  205. package/dist/core/CapabilityMapper.js.map +1 -0
  206. package/dist/core/CapabilityRegistryGenerator.d.ts +72 -0
  207. package/dist/core/CapabilityRegistryGenerator.d.ts.map +1 -0
  208. package/dist/core/CapabilityRegistryGenerator.js +310 -0
  209. package/dist/core/CapabilityRegistryGenerator.js.map +1 -0
  210. package/dist/core/ClaudeCliIntelligenceProvider.d.ts +21 -0
  211. package/dist/core/ClaudeCliIntelligenceProvider.d.ts.map +1 -0
  212. package/dist/core/ClaudeCliIntelligenceProvider.js +60 -0
  213. package/dist/core/ClaudeCliIntelligenceProvider.js.map +1 -0
  214. package/dist/core/CoherenceGate.d.ts +198 -0
  215. package/dist/core/CoherenceGate.d.ts.map +1 -0
  216. package/dist/core/CoherenceGate.js +986 -0
  217. package/dist/core/CoherenceGate.js.map +1 -0
  218. package/dist/core/CoherenceReviewer.d.ts +104 -0
  219. package/dist/core/CoherenceReviewer.d.ts.map +1 -0
  220. package/dist/core/CoherenceReviewer.js +185 -0
  221. package/dist/core/CoherenceReviewer.js.map +1 -0
  222. package/dist/core/Config.d.ts +32 -0
  223. package/dist/core/Config.d.ts.map +1 -0
  224. package/dist/core/Config.js +332 -0
  225. package/dist/core/Config.js.map +1 -0
  226. package/dist/core/ConflictNegotiator.d.ts +167 -0
  227. package/dist/core/ConflictNegotiator.d.ts.map +1 -0
  228. package/dist/core/ConflictNegotiator.js +280 -0
  229. package/dist/core/ConflictNegotiator.js.map +1 -0
  230. package/dist/core/ContextHierarchy.d.ts +102 -0
  231. package/dist/core/ContextHierarchy.d.ts.map +1 -0
  232. package/dist/core/ContextHierarchy.js +594 -0
  233. package/dist/core/ContextHierarchy.js.map +1 -0
  234. package/dist/core/ContextSnapshotBuilder.d.ts +80 -0
  235. package/dist/core/ContextSnapshotBuilder.d.ts.map +1 -0
  236. package/dist/core/ContextSnapshotBuilder.js +342 -0
  237. package/dist/core/ContextSnapshotBuilder.js.map +1 -0
  238. package/dist/core/ContextualEvaluator.d.ts +103 -0
  239. package/dist/core/ContextualEvaluator.d.ts.map +1 -0
  240. package/dist/core/ContextualEvaluator.js +389 -0
  241. package/dist/core/ContextualEvaluator.js.map +1 -0
  242. package/dist/core/ConvergenceChecker.d.ts +24 -0
  243. package/dist/core/ConvergenceChecker.d.ts.map +1 -0
  244. package/dist/core/ConvergenceChecker.js +113 -0
  245. package/dist/core/ConvergenceChecker.js.map +1 -0
  246. package/dist/core/CoordinationProtocol.d.ts +198 -0
  247. package/dist/core/CoordinationProtocol.d.ts.map +1 -0
  248. package/dist/core/CoordinationProtocol.js +363 -0
  249. package/dist/core/CoordinationProtocol.js.map +1 -0
  250. package/dist/core/CustomReviewerLoader.d.ts +45 -0
  251. package/dist/core/CustomReviewerLoader.d.ts.map +1 -0
  252. package/dist/core/CustomReviewerLoader.js +153 -0
  253. package/dist/core/CustomReviewerLoader.js.map +1 -0
  254. package/dist/core/DecisionJournal.d.ts +56 -0
  255. package/dist/core/DecisionJournal.d.ts.map +1 -0
  256. package/dist/core/DecisionJournal.js +132 -0
  257. package/dist/core/DecisionJournal.js.map +1 -0
  258. package/dist/core/DeferredDispatchTracker.d.ts +91 -0
  259. package/dist/core/DeferredDispatchTracker.d.ts.map +1 -0
  260. package/dist/core/DeferredDispatchTracker.js +213 -0
  261. package/dist/core/DeferredDispatchTracker.js.map +1 -0
  262. package/dist/core/DiscoveryEvaluator.d.ts +131 -0
  263. package/dist/core/DiscoveryEvaluator.d.ts.map +1 -0
  264. package/dist/core/DiscoveryEvaluator.js +377 -0
  265. package/dist/core/DiscoveryEvaluator.js.map +1 -0
  266. package/dist/core/DispatchDecisionJournal.d.ts +83 -0
  267. package/dist/core/DispatchDecisionJournal.d.ts.map +1 -0
  268. package/dist/core/DispatchDecisionJournal.js +181 -0
  269. package/dist/core/DispatchDecisionJournal.js.map +1 -0
  270. package/dist/core/DispatchExecutor.d.ts +127 -0
  271. package/dist/core/DispatchExecutor.d.ts.map +1 -0
  272. package/dist/core/DispatchExecutor.js +355 -0
  273. package/dist/core/DispatchExecutor.js.map +1 -0
  274. package/dist/core/DispatchManager.d.ts +200 -0
  275. package/dist/core/DispatchManager.d.ts.map +1 -0
  276. package/dist/core/DispatchManager.js +524 -0
  277. package/dist/core/DispatchManager.js.map +1 -0
  278. package/dist/core/DispatchScopeEnforcer.d.ts +57 -0
  279. package/dist/core/DispatchScopeEnforcer.d.ts.map +1 -0
  280. package/dist/core/DispatchScopeEnforcer.js +173 -0
  281. package/dist/core/DispatchScopeEnforcer.js.map +1 -0
  282. package/dist/core/DispatchVerifier.d.ts +76 -0
  283. package/dist/core/DispatchVerifier.d.ts.map +1 -0
  284. package/dist/core/DispatchVerifier.js +128 -0
  285. package/dist/core/DispatchVerifier.js.map +1 -0
  286. package/dist/core/EvolutionManager.d.ts +223 -0
  287. package/dist/core/EvolutionManager.d.ts.map +1 -0
  288. package/dist/core/EvolutionManager.js +630 -0
  289. package/dist/core/EvolutionManager.js.map +1 -0
  290. package/dist/core/ExecutionJournal.d.ts +101 -0
  291. package/dist/core/ExecutionJournal.d.ts.map +1 -0
  292. package/dist/core/ExecutionJournal.js +301 -0
  293. package/dist/core/ExecutionJournal.js.map +1 -0
  294. package/dist/core/ExternalOperationGate.d.ts +204 -0
  295. package/dist/core/ExternalOperationGate.d.ts.map +1 -0
  296. package/dist/core/ExternalOperationGate.js +413 -0
  297. package/dist/core/ExternalOperationGate.js.map +1 -0
  298. package/dist/core/FeatureDefinitions.d.ts +14 -0
  299. package/dist/core/FeatureDefinitions.d.ts.map +1 -0
  300. package/dist/core/FeatureDefinitions.js +374 -0
  301. package/dist/core/FeatureDefinitions.js.map +1 -0
  302. package/dist/core/FeatureRegistry.d.ts +337 -0
  303. package/dist/core/FeatureRegistry.d.ts.map +1 -0
  304. package/dist/core/FeatureRegistry.js +863 -0
  305. package/dist/core/FeatureRegistry.js.map +1 -0
  306. package/dist/core/FeedbackManager.d.ts +69 -0
  307. package/dist/core/FeedbackManager.d.ts.map +1 -0
  308. package/dist/core/FeedbackManager.js +284 -0
  309. package/dist/core/FeedbackManager.js.map +1 -0
  310. package/dist/core/FileClassifier.d.ts +74 -0
  311. package/dist/core/FileClassifier.d.ts.map +1 -0
  312. package/dist/core/FileClassifier.js +377 -0
  313. package/dist/core/FileClassifier.js.map +1 -0
  314. package/dist/core/ForegroundRestartWatcher.d.ts +55 -0
  315. package/dist/core/ForegroundRestartWatcher.d.ts.map +1 -0
  316. package/dist/core/ForegroundRestartWatcher.js +116 -0
  317. package/dist/core/ForegroundRestartWatcher.js.map +1 -0
  318. package/dist/core/GitStateManager.d.ts +78 -0
  319. package/dist/core/GitStateManager.d.ts.map +1 -0
  320. package/dist/core/GitStateManager.js +366 -0
  321. package/dist/core/GitStateManager.js.map +1 -0
  322. package/dist/core/GitSync.d.ts +199 -0
  323. package/dist/core/GitSync.d.ts.map +1 -0
  324. package/dist/core/GitSync.js +955 -0
  325. package/dist/core/GitSync.js.map +1 -0
  326. package/dist/core/GlobalInstallCleanup.d.ts +23 -0
  327. package/dist/core/GlobalInstallCleanup.d.ts.map +1 -0
  328. package/dist/core/GlobalInstallCleanup.js +130 -0
  329. package/dist/core/GlobalInstallCleanup.js.map +1 -0
  330. package/dist/core/GlobalSecretStore.d.ts +112 -0
  331. package/dist/core/GlobalSecretStore.d.ts.map +1 -0
  332. package/dist/core/GlobalSecretStore.js +396 -0
  333. package/dist/core/GlobalSecretStore.js.map +1 -0
  334. package/dist/core/HandoffManager.d.ts +163 -0
  335. package/dist/core/HandoffManager.d.ts.map +1 -0
  336. package/dist/core/HandoffManager.js +370 -0
  337. package/dist/core/HandoffManager.js.map +1 -0
  338. package/dist/core/HeartbeatManager.d.ts +120 -0
  339. package/dist/core/HeartbeatManager.d.ts.map +1 -0
  340. package/dist/core/HeartbeatManager.js +240 -0
  341. package/dist/core/HeartbeatManager.js.map +1 -0
  342. package/dist/core/InputGuard.d.ts +98 -0
  343. package/dist/core/InputGuard.d.ts.map +1 -0
  344. package/dist/core/InputGuard.js +316 -0
  345. package/dist/core/InputGuard.js.map +1 -0
  346. package/dist/core/IntentDriftDetector.d.ts +100 -0
  347. package/dist/core/IntentDriftDetector.d.ts.map +1 -0
  348. package/dist/core/IntentDriftDetector.js +325 -0
  349. package/dist/core/IntentDriftDetector.js.map +1 -0
  350. package/dist/core/JobReflector.d.ts +81 -0
  351. package/dist/core/JobReflector.d.ts.map +1 -0
  352. package/dist/core/JobReflector.js +244 -0
  353. package/dist/core/JobReflector.js.map +1 -0
  354. package/dist/core/LLMConflictResolver.d.ts +132 -0
  355. package/dist/core/LLMConflictResolver.d.ts.map +1 -0
  356. package/dist/core/LLMConflictResolver.js +372 -0
  357. package/dist/core/LLMConflictResolver.js.map +1 -0
  358. package/dist/core/LedgerAuth.d.ts +99 -0
  359. package/dist/core/LedgerAuth.d.ts.map +1 -0
  360. package/dist/core/LedgerAuth.js +215 -0
  361. package/dist/core/LedgerAuth.js.map +1 -0
  362. package/dist/core/MachineIdentity.d.ts +196 -0
  363. package/dist/core/MachineIdentity.d.ts.map +1 -0
  364. package/dist/core/MachineIdentity.js +476 -0
  365. package/dist/core/MachineIdentity.js.map +1 -0
  366. package/dist/core/MessageSentinel.d.ts +142 -0
  367. package/dist/core/MessageSentinel.d.ts.map +1 -0
  368. package/dist/core/MessageSentinel.js +426 -0
  369. package/dist/core/MessageSentinel.js.map +1 -0
  370. package/dist/core/MigrationProvenance.d.ts +62 -0
  371. package/dist/core/MigrationProvenance.d.ts.map +1 -0
  372. package/dist/core/MigrationProvenance.js +183 -0
  373. package/dist/core/MigrationProvenance.js.map +1 -0
  374. package/dist/core/MultiMachineCoordinator.d.ts +106 -0
  375. package/dist/core/MultiMachineCoordinator.d.ts.map +1 -0
  376. package/dist/core/MultiMachineCoordinator.js +311 -0
  377. package/dist/core/MultiMachineCoordinator.js.map +1 -0
  378. package/dist/core/NonceStore.d.ts +72 -0
  379. package/dist/core/NonceStore.d.ts.map +1 -0
  380. package/dist/core/NonceStore.js +163 -0
  381. package/dist/core/NonceStore.js.map +1 -0
  382. package/dist/core/OrgIntentManager.d.ts +58 -0
  383. package/dist/core/OrgIntentManager.d.ts.map +1 -0
  384. package/dist/core/OrgIntentManager.js +250 -0
  385. package/dist/core/OrgIntentManager.js.map +1 -0
  386. package/dist/core/OverlapGuard.d.ts +112 -0
  387. package/dist/core/OverlapGuard.d.ts.map +1 -0
  388. package/dist/core/OverlapGuard.js +241 -0
  389. package/dist/core/OverlapGuard.js.map +1 -0
  390. package/dist/core/PairingProtocol.d.ts +129 -0
  391. package/dist/core/PairingProtocol.d.ts.map +1 -0
  392. package/dist/core/PairingProtocol.js +265 -0
  393. package/dist/core/PairingProtocol.js.map +1 -0
  394. package/dist/core/PatternAnalyzer.d.ts +128 -0
  395. package/dist/core/PatternAnalyzer.d.ts.map +1 -0
  396. package/dist/core/PatternAnalyzer.js +388 -0
  397. package/dist/core/PatternAnalyzer.js.map +1 -0
  398. package/dist/core/PlatformActivityRegistry.d.ts +163 -0
  399. package/dist/core/PlatformActivityRegistry.d.ts.map +1 -0
  400. package/dist/core/PlatformActivityRegistry.js +307 -0
  401. package/dist/core/PlatformActivityRegistry.js.map +1 -0
  402. package/dist/core/PolicyEnforcementLayer.d.ts +63 -0
  403. package/dist/core/PolicyEnforcementLayer.d.ts.map +1 -0
  404. package/dist/core/PolicyEnforcementLayer.js +250 -0
  405. package/dist/core/PolicyEnforcementLayer.js.map +1 -0
  406. package/dist/core/PortRegistry.d.ts +9 -0
  407. package/dist/core/PortRegistry.d.ts.map +1 -0
  408. package/dist/core/PortRegistry.js +8 -0
  409. package/dist/core/PortRegistry.js.map +1 -0
  410. package/dist/core/PostUpdateMigrator.d.ts +170 -0
  411. package/dist/core/PostUpdateMigrator.d.ts.map +1 -0
  412. package/dist/core/PostUpdateMigrator.js +3674 -0
  413. package/dist/core/PostUpdateMigrator.js.map +1 -0
  414. package/dist/core/Prerequisites.d.ts +37 -0
  415. package/dist/core/Prerequisites.d.ts.map +1 -0
  416. package/dist/core/Prerequisites.js +272 -0
  417. package/dist/core/Prerequisites.js.map +1 -0
  418. package/dist/core/ProcessIntegrity.d.ts +90 -0
  419. package/dist/core/ProcessIntegrity.d.ts.map +1 -0
  420. package/dist/core/ProcessIntegrity.js +119 -0
  421. package/dist/core/ProcessIntegrity.js.map +1 -0
  422. package/dist/core/ProjectMapper.d.ts +97 -0
  423. package/dist/core/ProjectMapper.d.ts.map +1 -0
  424. package/dist/core/ProjectMapper.js +370 -0
  425. package/dist/core/ProjectMapper.js.map +1 -0
  426. package/dist/core/PromptGuard.d.ts +121 -0
  427. package/dist/core/PromptGuard.d.ts.map +1 -0
  428. package/dist/core/PromptGuard.js +259 -0
  429. package/dist/core/PromptGuard.js.map +1 -0
  430. package/dist/core/RecipientResolver.d.ts +54 -0
  431. package/dist/core/RecipientResolver.d.ts.map +1 -0
  432. package/dist/core/RecipientResolver.js +143 -0
  433. package/dist/core/RecipientResolver.js.map +1 -0
  434. package/dist/core/ReflectionConsolidator.d.ts +73 -0
  435. package/dist/core/ReflectionConsolidator.d.ts.map +1 -0
  436. package/dist/core/ReflectionConsolidator.js +202 -0
  437. package/dist/core/ReflectionConsolidator.js.map +1 -0
  438. package/dist/core/RelationshipManager.d.ts +146 -0
  439. package/dist/core/RelationshipManager.d.ts.map +1 -0
  440. package/dist/core/RelationshipManager.js +736 -0
  441. package/dist/core/RelationshipManager.js.map +1 -0
  442. package/dist/core/RelevanceFilter.d.ts +61 -0
  443. package/dist/core/RelevanceFilter.d.ts.map +1 -0
  444. package/dist/core/RelevanceFilter.js +160 -0
  445. package/dist/core/RelevanceFilter.js.map +1 -0
  446. package/dist/core/ResearchRateLimiter.d.ts +76 -0
  447. package/dist/core/ResearchRateLimiter.d.ts.map +1 -0
  448. package/dist/core/ResearchRateLimiter.js +168 -0
  449. package/dist/core/ResearchRateLimiter.js.map +1 -0
  450. package/dist/core/ResumeValidator.d.ts +58 -0
  451. package/dist/core/ResumeValidator.d.ts.map +1 -0
  452. package/dist/core/ResumeValidator.js +195 -0
  453. package/dist/core/ResumeValidator.js.map +1 -0
  454. package/dist/core/ScopeCoherenceTracker.d.ts +87 -0
  455. package/dist/core/ScopeCoherenceTracker.d.ts.map +1 -0
  456. package/dist/core/ScopeCoherenceTracker.js +226 -0
  457. package/dist/core/ScopeCoherenceTracker.js.map +1 -0
  458. package/dist/core/ScopeVerifier.d.ts +122 -0
  459. package/dist/core/ScopeVerifier.d.ts.map +1 -0
  460. package/dist/core/ScopeVerifier.js +350 -0
  461. package/dist/core/ScopeVerifier.js.map +1 -0
  462. package/dist/core/SecretManager.d.ts +120 -0
  463. package/dist/core/SecretManager.d.ts.map +1 -0
  464. package/dist/core/SecretManager.js +324 -0
  465. package/dist/core/SecretManager.js.map +1 -0
  466. package/dist/core/SecretMigrator.d.ts +39 -0
  467. package/dist/core/SecretMigrator.d.ts.map +1 -0
  468. package/dist/core/SecretMigrator.js +182 -0
  469. package/dist/core/SecretMigrator.js.map +1 -0
  470. package/dist/core/SecretRedactor.d.ts +121 -0
  471. package/dist/core/SecretRedactor.d.ts.map +1 -0
  472. package/dist/core/SecretRedactor.js +309 -0
  473. package/dist/core/SecretRedactor.js.map +1 -0
  474. package/dist/core/SecretStore.d.ts +104 -0
  475. package/dist/core/SecretStore.d.ts.map +1 -0
  476. package/dist/core/SecretStore.js +405 -0
  477. package/dist/core/SecretStore.js.map +1 -0
  478. package/dist/core/SecurityLog.d.ts +58 -0
  479. package/dist/core/SecurityLog.d.ts.map +1 -0
  480. package/dist/core/SecurityLog.js +123 -0
  481. package/dist/core/SecurityLog.js.map +1 -0
  482. package/dist/core/SendGateway.d.ts +77 -0
  483. package/dist/core/SendGateway.d.ts.map +1 -0
  484. package/dist/core/SendGateway.js +181 -0
  485. package/dist/core/SendGateway.js.map +1 -0
  486. package/dist/core/SessionManager.d.ts +304 -0
  487. package/dist/core/SessionManager.d.ts.map +1 -0
  488. package/dist/core/SessionManager.js +1402 -0
  489. package/dist/core/SessionManager.js.map +1 -0
  490. package/dist/core/SleepWakeDetector.d.ts +37 -0
  491. package/dist/core/SleepWakeDetector.d.ts.map +1 -0
  492. package/dist/core/SleepWakeDetector.js +59 -0
  493. package/dist/core/SleepWakeDetector.js.map +1 -0
  494. package/dist/core/SoulManager.d.ts +107 -0
  495. package/dist/core/SoulManager.d.ts.map +1 -0
  496. package/dist/core/SoulManager.js +574 -0
  497. package/dist/core/SoulManager.js.map +1 -0
  498. package/dist/core/StaleProcessGuard.d.ts +113 -0
  499. package/dist/core/StaleProcessGuard.d.ts.map +1 -0
  500. package/dist/core/StaleProcessGuard.js +134 -0
  501. package/dist/core/StaleProcessGuard.js.map +1 -0
  502. package/dist/core/StateManager.d.ts +56 -0
  503. package/dist/core/StateManager.d.ts.map +1 -0
  504. package/dist/core/StateManager.js +266 -0
  505. package/dist/core/StateManager.js.map +1 -0
  506. package/dist/core/StateWriteAuthority.d.ts +101 -0
  507. package/dist/core/StateWriteAuthority.d.ts.map +1 -0
  508. package/dist/core/StateWriteAuthority.js +169 -0
  509. package/dist/core/StateWriteAuthority.js.map +1 -0
  510. package/dist/core/SurfacingTemplates.d.ts +63 -0
  511. package/dist/core/SurfacingTemplates.d.ts.map +1 -0
  512. package/dist/core/SurfacingTemplates.js +138 -0
  513. package/dist/core/SurfacingTemplates.js.map +1 -0
  514. package/dist/core/SyncOrchestrator.d.ts +308 -0
  515. package/dist/core/SyncOrchestrator.d.ts.map +1 -0
  516. package/dist/core/SyncOrchestrator.js +925 -0
  517. package/dist/core/SyncOrchestrator.js.map +1 -0
  518. package/dist/core/TemporalCoherenceChecker.d.ts +140 -0
  519. package/dist/core/TemporalCoherenceChecker.d.ts.map +1 -0
  520. package/dist/core/TemporalCoherenceChecker.js +375 -0
  521. package/dist/core/TemporalCoherenceChecker.js.map +1 -0
  522. package/dist/core/TopicClassifier.d.ts +54 -0
  523. package/dist/core/TopicClassifier.d.ts.map +1 -0
  524. package/dist/core/TopicClassifier.js +144 -0
  525. package/dist/core/TopicClassifier.js.map +1 -0
  526. package/dist/core/TopicResumeMap.d.ts +76 -0
  527. package/dist/core/TopicResumeMap.d.ts.map +1 -0
  528. package/dist/core/TopicResumeMap.js +252 -0
  529. package/dist/core/TopicResumeMap.js.map +1 -0
  530. package/dist/core/TrustElevationTracker.d.ts +178 -0
  531. package/dist/core/TrustElevationTracker.d.ts.map +1 -0
  532. package/dist/core/TrustElevationTracker.js +343 -0
  533. package/dist/core/TrustElevationTracker.js.map +1 -0
  534. package/dist/core/TrustRecovery.d.ts +109 -0
  535. package/dist/core/TrustRecovery.d.ts.map +1 -0
  536. package/dist/core/TrustRecovery.js +190 -0
  537. package/dist/core/TrustRecovery.js.map +1 -0
  538. package/dist/core/UpdateChecker.d.ts +108 -0
  539. package/dist/core/UpdateChecker.d.ts.map +1 -0
  540. package/dist/core/UpdateChecker.js +593 -0
  541. package/dist/core/UpdateChecker.js.map +1 -0
  542. package/dist/core/UpdateGate.d.ts +102 -0
  543. package/dist/core/UpdateGate.d.ts.map +1 -0
  544. package/dist/core/UpdateGate.js +149 -0
  545. package/dist/core/UpdateGate.js.map +1 -0
  546. package/dist/core/UpgradeGuideProcessor.d.ts +105 -0
  547. package/dist/core/UpgradeGuideProcessor.d.ts.map +1 -0
  548. package/dist/core/UpgradeGuideProcessor.js +278 -0
  549. package/dist/core/UpgradeGuideProcessor.js.map +1 -0
  550. package/dist/core/UpgradeNotifyManager.d.ts +98 -0
  551. package/dist/core/UpgradeNotifyManager.d.ts.map +1 -0
  552. package/dist/core/UpgradeNotifyManager.js +205 -0
  553. package/dist/core/UpgradeNotifyManager.js.map +1 -0
  554. package/dist/core/WorkLedger.d.ts +144 -0
  555. package/dist/core/WorkLedger.d.ts.map +1 -0
  556. package/dist/core/WorkLedger.js +246 -0
  557. package/dist/core/WorkLedger.js.map +1 -0
  558. package/dist/core/models.d.ts +70 -0
  559. package/dist/core/models.d.ts.map +1 -0
  560. package/dist/core/models.js +110 -0
  561. package/dist/core/models.js.map +1 -0
  562. package/dist/core/reviewers/capability-accuracy.d.ts +13 -0
  563. package/dist/core/reviewers/capability-accuracy.d.ts.map +1 -0
  564. package/dist/core/reviewers/capability-accuracy.js +38 -0
  565. package/dist/core/reviewers/capability-accuracy.js.map +1 -0
  566. package/dist/core/reviewers/claim-provenance.d.ts +14 -0
  567. package/dist/core/reviewers/claim-provenance.d.ts.map +1 -0
  568. package/dist/core/reviewers/claim-provenance.js +50 -0
  569. package/dist/core/reviewers/claim-provenance.js.map +1 -0
  570. package/dist/core/reviewers/context-completeness.d.ts +13 -0
  571. package/dist/core/reviewers/context-completeness.d.ts.map +1 -0
  572. package/dist/core/reviewers/context-completeness.js +43 -0
  573. package/dist/core/reviewers/context-completeness.js.map +1 -0
  574. package/dist/core/reviewers/conversational-tone.d.ts +13 -0
  575. package/dist/core/reviewers/conversational-tone.d.ts.map +1 -0
  576. package/dist/core/reviewers/conversational-tone.js +55 -0
  577. package/dist/core/reviewers/conversational-tone.js.map +1 -0
  578. package/dist/core/reviewers/escalation-resolution.d.ts +56 -0
  579. package/dist/core/reviewers/escalation-resolution.d.ts.map +1 -0
  580. package/dist/core/reviewers/escalation-resolution.js +239 -0
  581. package/dist/core/reviewers/escalation-resolution.js.map +1 -0
  582. package/dist/core/reviewers/gate-reviewer.d.ts +26 -0
  583. package/dist/core/reviewers/gate-reviewer.d.ts.map +1 -0
  584. package/dist/core/reviewers/gate-reviewer.js +130 -0
  585. package/dist/core/reviewers/gate-reviewer.js.map +1 -0
  586. package/dist/core/reviewers/information-leakage.d.ts +21 -0
  587. package/dist/core/reviewers/information-leakage.d.ts.map +1 -0
  588. package/dist/core/reviewers/information-leakage.js +72 -0
  589. package/dist/core/reviewers/information-leakage.js.map +1 -0
  590. package/dist/core/reviewers/settling-detection.d.ts +13 -0
  591. package/dist/core/reviewers/settling-detection.d.ts.map +1 -0
  592. package/dist/core/reviewers/settling-detection.js +48 -0
  593. package/dist/core/reviewers/settling-detection.js.map +1 -0
  594. package/dist/core/reviewers/url-validity.d.ts +18 -0
  595. package/dist/core/reviewers/url-validity.d.ts.map +1 -0
  596. package/dist/core/reviewers/url-validity.js +60 -0
  597. package/dist/core/reviewers/url-validity.js.map +1 -0
  598. package/dist/core/reviewers/value-alignment.d.ts +14 -0
  599. package/dist/core/reviewers/value-alignment.d.ts.map +1 -0
  600. package/dist/core/reviewers/value-alignment.js +71 -0
  601. package/dist/core/reviewers/value-alignment.js.map +1 -0
  602. package/dist/core/types.d.ts +2159 -0
  603. package/dist/core/types.d.ts.map +1 -0
  604. package/dist/core/types.js +20 -0
  605. package/dist/core/types.js.map +1 -0
  606. package/dist/data/http-hook-templates.d.ts +53 -0
  607. package/dist/data/http-hook-templates.d.ts.map +1 -0
  608. package/dist/data/http-hook-templates.js +64 -0
  609. package/dist/data/http-hook-templates.js.map +1 -0
  610. package/dist/index.d.ts +263 -0
  611. package/dist/index.d.ts.map +1 -0
  612. package/dist/index.js +164 -0
  613. package/dist/index.js.map +1 -0
  614. package/dist/knowledge/CoverageAuditor.d.ts +58 -0
  615. package/dist/knowledge/CoverageAuditor.d.ts.map +1 -0
  616. package/dist/knowledge/CoverageAuditor.js +153 -0
  617. package/dist/knowledge/CoverageAuditor.js.map +1 -0
  618. package/dist/knowledge/IntegrityManager.d.ts +46 -0
  619. package/dist/knowledge/IntegrityManager.d.ts.map +1 -0
  620. package/dist/knowledge/IntegrityManager.js +101 -0
  621. package/dist/knowledge/IntegrityManager.js.map +1 -0
  622. package/dist/knowledge/KnowledgeManager.d.ts +85 -0
  623. package/dist/knowledge/KnowledgeManager.d.ts.map +1 -0
  624. package/dist/knowledge/KnowledgeManager.js +194 -0
  625. package/dist/knowledge/KnowledgeManager.js.map +1 -0
  626. package/dist/knowledge/ProbeRegistry.d.ts +54 -0
  627. package/dist/knowledge/ProbeRegistry.d.ts.map +1 -0
  628. package/dist/knowledge/ProbeRegistry.js +119 -0
  629. package/dist/knowledge/ProbeRegistry.js.map +1 -0
  630. package/dist/knowledge/SelfKnowledgeTree.d.ts +108 -0
  631. package/dist/knowledge/SelfKnowledgeTree.d.ts.map +1 -0
  632. package/dist/knowledge/SelfKnowledgeTree.js +560 -0
  633. package/dist/knowledge/SelfKnowledgeTree.js.map +1 -0
  634. package/dist/knowledge/TreeGenerator.d.ts +57 -0
  635. package/dist/knowledge/TreeGenerator.d.ts.map +1 -0
  636. package/dist/knowledge/TreeGenerator.js +527 -0
  637. package/dist/knowledge/TreeGenerator.js.map +1 -0
  638. package/dist/knowledge/TreeSynthesis.d.ts +24 -0
  639. package/dist/knowledge/TreeSynthesis.d.ts.map +1 -0
  640. package/dist/knowledge/TreeSynthesis.js +61 -0
  641. package/dist/knowledge/TreeSynthesis.js.map +1 -0
  642. package/dist/knowledge/TreeTraversal.d.ts +93 -0
  643. package/dist/knowledge/TreeTraversal.d.ts.map +1 -0
  644. package/dist/knowledge/TreeTraversal.js +359 -0
  645. package/dist/knowledge/TreeTraversal.js.map +1 -0
  646. package/dist/knowledge/TreeTriage.d.ts +80 -0
  647. package/dist/knowledge/TreeTriage.d.ts.map +1 -0
  648. package/dist/knowledge/TreeTriage.js +413 -0
  649. package/dist/knowledge/TreeTriage.js.map +1 -0
  650. package/dist/knowledge/types.d.ts +183 -0
  651. package/dist/knowledge/types.d.ts.map +1 -0
  652. package/dist/knowledge/types.js +28 -0
  653. package/dist/knowledge/types.js.map +1 -0
  654. package/dist/lifeline/MessageQueue.d.ts +42 -0
  655. package/dist/lifeline/MessageQueue.d.ts.map +1 -0
  656. package/dist/lifeline/MessageQueue.js +63 -0
  657. package/dist/lifeline/MessageQueue.js.map +1 -0
  658. package/dist/lifeline/ServerSupervisor.d.ts +203 -0
  659. package/dist/lifeline/ServerSupervisor.d.ts.map +1 -0
  660. package/dist/lifeline/ServerSupervisor.js +1103 -0
  661. package/dist/lifeline/ServerSupervisor.js.map +1 -0
  662. package/dist/lifeline/SlackLifeline.d.ts +43 -0
  663. package/dist/lifeline/SlackLifeline.d.ts.map +1 -0
  664. package/dist/lifeline/SlackLifeline.js +227 -0
  665. package/dist/lifeline/SlackLifeline.js.map +1 -0
  666. package/dist/lifeline/TelegramLifeline.d.ts +180 -0
  667. package/dist/lifeline/TelegramLifeline.d.ts.map +1 -0
  668. package/dist/lifeline/TelegramLifeline.js +1533 -0
  669. package/dist/lifeline/TelegramLifeline.js.map +1 -0
  670. package/dist/memory/ActivityPartitioner.d.ts +67 -0
  671. package/dist/memory/ActivityPartitioner.d.ts.map +1 -0
  672. package/dist/memory/ActivityPartitioner.js +193 -0
  673. package/dist/memory/ActivityPartitioner.js.map +1 -0
  674. package/dist/memory/Chunker.d.ts +39 -0
  675. package/dist/memory/Chunker.d.ts.map +1 -0
  676. package/dist/memory/Chunker.js +154 -0
  677. package/dist/memory/Chunker.js.map +1 -0
  678. package/dist/memory/EmbeddingProvider.d.ts +82 -0
  679. package/dist/memory/EmbeddingProvider.d.ts.map +1 -0
  680. package/dist/memory/EmbeddingProvider.js +168 -0
  681. package/dist/memory/EmbeddingProvider.js.map +1 -0
  682. package/dist/memory/EpisodicMemory.d.ts +141 -0
  683. package/dist/memory/EpisodicMemory.d.ts.map +1 -0
  684. package/dist/memory/EpisodicMemory.js +303 -0
  685. package/dist/memory/EpisodicMemory.js.map +1 -0
  686. package/dist/memory/MemoryExporter.d.ts +82 -0
  687. package/dist/memory/MemoryExporter.d.ts.map +1 -0
  688. package/dist/memory/MemoryExporter.js +233 -0
  689. package/dist/memory/MemoryExporter.js.map +1 -0
  690. package/dist/memory/MemoryIndex.d.ts +76 -0
  691. package/dist/memory/MemoryIndex.d.ts.map +1 -0
  692. package/dist/memory/MemoryIndex.js +413 -0
  693. package/dist/memory/MemoryIndex.js.map +1 -0
  694. package/dist/memory/MemoryMigrator.d.ts +103 -0
  695. package/dist/memory/MemoryMigrator.d.ts.map +1 -0
  696. package/dist/memory/MemoryMigrator.js +510 -0
  697. package/dist/memory/MemoryMigrator.js.map +1 -0
  698. package/dist/memory/SemanticMemory.d.ts +255 -0
  699. package/dist/memory/SemanticMemory.d.ts.map +1 -0
  700. package/dist/memory/SemanticMemory.js +1130 -0
  701. package/dist/memory/SemanticMemory.js.map +1 -0
  702. package/dist/memory/TopicMemory.d.ts +227 -0
  703. package/dist/memory/TopicMemory.d.ts.map +1 -0
  704. package/dist/memory/TopicMemory.js +731 -0
  705. package/dist/memory/TopicMemory.js.map +1 -0
  706. package/dist/memory/TopicSummarizer.d.ts +69 -0
  707. package/dist/memory/TopicSummarizer.d.ts.map +1 -0
  708. package/dist/memory/TopicSummarizer.js +163 -0
  709. package/dist/memory/TopicSummarizer.js.map +1 -0
  710. package/dist/memory/VectorSearch.d.ts +80 -0
  711. package/dist/memory/VectorSearch.d.ts.map +1 -0
  712. package/dist/memory/VectorSearch.js +148 -0
  713. package/dist/memory/VectorSearch.js.map +1 -0
  714. package/dist/memory/WorkingMemoryAssembler.d.ts +122 -0
  715. package/dist/memory/WorkingMemoryAssembler.d.ts.map +1 -0
  716. package/dist/memory/WorkingMemoryAssembler.js +406 -0
  717. package/dist/memory/WorkingMemoryAssembler.js.map +1 -0
  718. package/dist/messaging/AdapterRegistry.d.ts +27 -0
  719. package/dist/messaging/AdapterRegistry.d.ts.map +1 -0
  720. package/dist/messaging/AdapterRegistry.js +40 -0
  721. package/dist/messaging/AdapterRegistry.js.map +1 -0
  722. package/dist/messaging/AgentTokenManager.d.ts +86 -0
  723. package/dist/messaging/AgentTokenManager.d.ts.map +1 -0
  724. package/dist/messaging/AgentTokenManager.js +213 -0
  725. package/dist/messaging/AgentTokenManager.js.map +1 -0
  726. package/dist/messaging/DeliveryRetryManager.d.ts +47 -0
  727. package/dist/messaging/DeliveryRetryManager.d.ts.map +1 -0
  728. package/dist/messaging/DeliveryRetryManager.js +201 -0
  729. package/dist/messaging/DeliveryRetryManager.js.map +1 -0
  730. package/dist/messaging/DropPickup.d.ts +37 -0
  731. package/dist/messaging/DropPickup.d.ts.map +1 -0
  732. package/dist/messaging/DropPickup.js +120 -0
  733. package/dist/messaging/DropPickup.js.map +1 -0
  734. package/dist/messaging/GitSyncTransport.d.ts +120 -0
  735. package/dist/messaging/GitSyncTransport.d.ts.map +1 -0
  736. package/dist/messaging/GitSyncTransport.js +296 -0
  737. package/dist/messaging/GitSyncTransport.js.map +1 -0
  738. package/dist/messaging/MessageDelivery.d.ts +27 -0
  739. package/dist/messaging/MessageDelivery.d.ts.map +1 -0
  740. package/dist/messaging/MessageDelivery.js +90 -0
  741. package/dist/messaging/MessageDelivery.js.map +1 -0
  742. package/dist/messaging/MessageFormatter.d.ts +30 -0
  743. package/dist/messaging/MessageFormatter.d.ts.map +1 -0
  744. package/dist/messaging/MessageFormatter.js +97 -0
  745. package/dist/messaging/MessageFormatter.js.map +1 -0
  746. package/dist/messaging/MessageRouter.d.ts +157 -0
  747. package/dist/messaging/MessageRouter.d.ts.map +1 -0
  748. package/dist/messaging/MessageRouter.js +657 -0
  749. package/dist/messaging/MessageRouter.js.map +1 -0
  750. package/dist/messaging/MessageStore.d.ts +52 -0
  751. package/dist/messaging/MessageStore.d.ts.map +1 -0
  752. package/dist/messaging/MessageStore.js +363 -0
  753. package/dist/messaging/MessageStore.js.map +1 -0
  754. package/dist/messaging/NotificationBatcher.d.ts +95 -0
  755. package/dist/messaging/NotificationBatcher.d.ts.map +1 -0
  756. package/dist/messaging/NotificationBatcher.js +253 -0
  757. package/dist/messaging/NotificationBatcher.js.map +1 -0
  758. package/dist/messaging/SessionSummarySentinel.d.ts +104 -0
  759. package/dist/messaging/SessionSummarySentinel.d.ts.map +1 -0
  760. package/dist/messaging/SessionSummarySentinel.js +386 -0
  761. package/dist/messaging/SessionSummarySentinel.js.map +1 -0
  762. package/dist/messaging/SpawnRequestManager.d.ts +88 -0
  763. package/dist/messaging/SpawnRequestManager.d.ts.map +1 -0
  764. package/dist/messaging/SpawnRequestManager.js +159 -0
  765. package/dist/messaging/SpawnRequestManager.js.map +1 -0
  766. package/dist/messaging/TelegramAdapter.d.ts +636 -0
  767. package/dist/messaging/TelegramAdapter.d.ts.map +1 -0
  768. package/dist/messaging/TelegramAdapter.js +3434 -0
  769. package/dist/messaging/TelegramAdapter.js.map +1 -0
  770. package/dist/messaging/TopicContentValidator.d.ts +81 -0
  771. package/dist/messaging/TopicContentValidator.d.ts.map +1 -0
  772. package/dist/messaging/TopicContentValidator.js +113 -0
  773. package/dist/messaging/TopicContentValidator.js.map +1 -0
  774. package/dist/messaging/WhatsAppAdapter.d.ts +224 -0
  775. package/dist/messaging/WhatsAppAdapter.d.ts.map +1 -0
  776. package/dist/messaging/WhatsAppAdapter.js +736 -0
  777. package/dist/messaging/WhatsAppAdapter.js.map +1 -0
  778. package/dist/messaging/backends/BaileysBackend.d.ts +74 -0
  779. package/dist/messaging/backends/BaileysBackend.d.ts.map +1 -0
  780. package/dist/messaging/backends/BaileysBackend.js +481 -0
  781. package/dist/messaging/backends/BaileysBackend.js.map +1 -0
  782. package/dist/messaging/backends/BusinessApiBackend.d.ts +173 -0
  783. package/dist/messaging/backends/BusinessApiBackend.d.ts.map +1 -0
  784. package/dist/messaging/backends/BusinessApiBackend.js +269 -0
  785. package/dist/messaging/backends/BusinessApiBackend.js.map +1 -0
  786. package/dist/messaging/backends/WhatsAppWebhookRoutes.d.ts +26 -0
  787. package/dist/messaging/backends/WhatsAppWebhookRoutes.d.ts.map +1 -0
  788. package/dist/messaging/backends/WhatsAppWebhookRoutes.js +50 -0
  789. package/dist/messaging/backends/WhatsAppWebhookRoutes.js.map +1 -0
  790. package/dist/messaging/shared/AuthGate.d.ts +102 -0
  791. package/dist/messaging/shared/AuthGate.d.ts.map +1 -0
  792. package/dist/messaging/shared/AuthGate.js +159 -0
  793. package/dist/messaging/shared/AuthGate.js.map +1 -0
  794. package/dist/messaging/shared/CommandRouter.d.ts +84 -0
  795. package/dist/messaging/shared/CommandRouter.d.ts.map +1 -0
  796. package/dist/messaging/shared/CommandRouter.js +145 -0
  797. package/dist/messaging/shared/CommandRouter.js.map +1 -0
  798. package/dist/messaging/shared/CrossPlatformAlerts.d.ts +67 -0
  799. package/dist/messaging/shared/CrossPlatformAlerts.d.ts.map +1 -0
  800. package/dist/messaging/shared/CrossPlatformAlerts.js +134 -0
  801. package/dist/messaging/shared/CrossPlatformAlerts.js.map +1 -0
  802. package/dist/messaging/shared/EncryptedAuthStore.d.ts +51 -0
  803. package/dist/messaging/shared/EncryptedAuthStore.d.ts.map +1 -0
  804. package/dist/messaging/shared/EncryptedAuthStore.js +194 -0
  805. package/dist/messaging/shared/EncryptedAuthStore.js.map +1 -0
  806. package/dist/messaging/shared/FeatureFlags.d.ts +21 -0
  807. package/dist/messaging/shared/FeatureFlags.d.ts.map +1 -0
  808. package/dist/messaging/shared/FeatureFlags.js +21 -0
  809. package/dist/messaging/shared/FeatureFlags.js.map +1 -0
  810. package/dist/messaging/shared/MessageBridge.d.ts +70 -0
  811. package/dist/messaging/shared/MessageBridge.d.ts.map +1 -0
  812. package/dist/messaging/shared/MessageBridge.js +178 -0
  813. package/dist/messaging/shared/MessageBridge.js.map +1 -0
  814. package/dist/messaging/shared/MessageLogger.d.ts +94 -0
  815. package/dist/messaging/shared/MessageLogger.d.ts.map +1 -0
  816. package/dist/messaging/shared/MessageLogger.js +173 -0
  817. package/dist/messaging/shared/MessageLogger.js.map +1 -0
  818. package/dist/messaging/shared/MessagingEventBus.d.ts +149 -0
  819. package/dist/messaging/shared/MessagingEventBus.d.ts.map +1 -0
  820. package/dist/messaging/shared/MessagingEventBus.js +111 -0
  821. package/dist/messaging/shared/MessagingEventBus.js.map +1 -0
  822. package/dist/messaging/shared/PhoneUtils.d.ts +44 -0
  823. package/dist/messaging/shared/PhoneUtils.d.ts.map +1 -0
  824. package/dist/messaging/shared/PhoneUtils.js +110 -0
  825. package/dist/messaging/shared/PhoneUtils.js.map +1 -0
  826. package/dist/messaging/shared/PrivacyConsent.d.ts +61 -0
  827. package/dist/messaging/shared/PrivacyConsent.d.ts.map +1 -0
  828. package/dist/messaging/shared/PrivacyConsent.js +132 -0
  829. package/dist/messaging/shared/PrivacyConsent.js.map +1 -0
  830. package/dist/messaging/shared/SessionChannelRegistry.d.ts +48 -0
  831. package/dist/messaging/shared/SessionChannelRegistry.d.ts.map +1 -0
  832. package/dist/messaging/shared/SessionChannelRegistry.js +144 -0
  833. package/dist/messaging/shared/SessionChannelRegistry.js.map +1 -0
  834. package/dist/messaging/shared/SmartChunker.d.ts +16 -0
  835. package/dist/messaging/shared/SmartChunker.d.ts.map +1 -0
  836. package/dist/messaging/shared/SmartChunker.js +100 -0
  837. package/dist/messaging/shared/SmartChunker.js.map +1 -0
  838. package/dist/messaging/shared/StallDetector.d.ts +85 -0
  839. package/dist/messaging/shared/StallDetector.d.ts.map +1 -0
  840. package/dist/messaging/shared/StallDetector.js +225 -0
  841. package/dist/messaging/shared/StallDetector.js.map +1 -0
  842. package/dist/messaging/shared/index.d.ts +22 -0
  843. package/dist/messaging/shared/index.d.ts.map +1 -0
  844. package/dist/messaging/shared/index.js +13 -0
  845. package/dist/messaging/shared/index.js.map +1 -0
  846. package/dist/messaging/slack/ChannelManager.d.ts +36 -0
  847. package/dist/messaging/slack/ChannelManager.d.ts.map +1 -0
  848. package/dist/messaging/slack/ChannelManager.js +100 -0
  849. package/dist/messaging/slack/ChannelManager.js.map +1 -0
  850. package/dist/messaging/slack/FileHandler.d.ts +30 -0
  851. package/dist/messaging/slack/FileHandler.d.ts.map +1 -0
  852. package/dist/messaging/slack/FileHandler.js +87 -0
  853. package/dist/messaging/slack/FileHandler.js.map +1 -0
  854. package/dist/messaging/slack/RingBuffer.d.ts +22 -0
  855. package/dist/messaging/slack/RingBuffer.d.ts.map +1 -0
  856. package/dist/messaging/slack/RingBuffer.js +48 -0
  857. package/dist/messaging/slack/RingBuffer.js.map +1 -0
  858. package/dist/messaging/slack/SlackAdapter.d.ts +283 -0
  859. package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -0
  860. package/dist/messaging/slack/SlackAdapter.js +1524 -0
  861. package/dist/messaging/slack/SlackAdapter.js.map +1 -0
  862. package/dist/messaging/slack/SlackApiClient.d.ts +51 -0
  863. package/dist/messaging/slack/SlackApiClient.d.ts.map +1 -0
  864. package/dist/messaging/slack/SlackApiClient.js +94 -0
  865. package/dist/messaging/slack/SlackApiClient.js.map +1 -0
  866. package/dist/messaging/slack/SocketModeClient.d.ts +44 -0
  867. package/dist/messaging/slack/SocketModeClient.d.ts.map +1 -0
  868. package/dist/messaging/slack/SocketModeClient.js +209 -0
  869. package/dist/messaging/slack/SocketModeClient.js.map +1 -0
  870. package/dist/messaging/slack/index.d.ts +12 -0
  871. package/dist/messaging/slack/index.d.ts.map +1 -0
  872. package/dist/messaging/slack/index.js +15 -0
  873. package/dist/messaging/slack/index.js.map +1 -0
  874. package/dist/messaging/slack/sanitize.d.ts +39 -0
  875. package/dist/messaging/slack/sanitize.d.ts.map +1 -0
  876. package/dist/messaging/slack/sanitize.js +71 -0
  877. package/dist/messaging/slack/sanitize.js.map +1 -0
  878. package/dist/messaging/slack/types.d.ts +186 -0
  879. package/dist/messaging/slack/types.d.ts.map +1 -0
  880. package/dist/messaging/slack/types.js +54 -0
  881. package/dist/messaging/slack/types.js.map +1 -0
  882. package/dist/messaging/types.d.ts +400 -0
  883. package/dist/messaging/types.d.ts.map +1 -0
  884. package/dist/messaging/types.js +89 -0
  885. package/dist/messaging/types.js.map +1 -0
  886. package/dist/monitoring/AccountSwitcher.d.ts +61 -0
  887. package/dist/monitoring/AccountSwitcher.d.ts.map +1 -0
  888. package/dist/monitoring/AccountSwitcher.js +196 -0
  889. package/dist/monitoring/AccountSwitcher.js.map +1 -0
  890. package/dist/monitoring/CoherenceMonitor.d.ts +133 -0
  891. package/dist/monitoring/CoherenceMonitor.d.ts.map +1 -0
  892. package/dist/monitoring/CoherenceMonitor.js +550 -0
  893. package/dist/monitoring/CoherenceMonitor.js.map +1 -0
  894. package/dist/monitoring/CommitmentSentinel.d.ts +57 -0
  895. package/dist/monitoring/CommitmentSentinel.d.ts.map +1 -0
  896. package/dist/monitoring/CommitmentSentinel.js +251 -0
  897. package/dist/monitoring/CommitmentSentinel.js.map +1 -0
  898. package/dist/monitoring/CommitmentTracker.d.ts +186 -0
  899. package/dist/monitoring/CommitmentTracker.d.ts.map +1 -0
  900. package/dist/monitoring/CommitmentTracker.js +522 -0
  901. package/dist/monitoring/CommitmentTracker.js.map +1 -0
  902. package/dist/monitoring/CredentialProvider.d.ts +84 -0
  903. package/dist/monitoring/CredentialProvider.d.ts.map +1 -0
  904. package/dist/monitoring/CredentialProvider.js +196 -0
  905. package/dist/monitoring/CredentialProvider.js.map +1 -0
  906. package/dist/monitoring/DegradationReporter.d.ts +123 -0
  907. package/dist/monitoring/DegradationReporter.d.ts.map +1 -0
  908. package/dist/monitoring/DegradationReporter.js +241 -0
  909. package/dist/monitoring/DegradationReporter.js.map +1 -0
  910. package/dist/monitoring/FeedbackAnomalyDetector.d.ts +51 -0
  911. package/dist/monitoring/FeedbackAnomalyDetector.d.ts.map +1 -0
  912. package/dist/monitoring/FeedbackAnomalyDetector.js +120 -0
  913. package/dist/monitoring/FeedbackAnomalyDetector.js.map +1 -0
  914. package/dist/monitoring/HealthChecker.d.ts +45 -0
  915. package/dist/monitoring/HealthChecker.d.ts.map +1 -0
  916. package/dist/monitoring/HealthChecker.js +219 -0
  917. package/dist/monitoring/HealthChecker.js.map +1 -0
  918. package/dist/monitoring/HomeostasisMonitor.d.ts +102 -0
  919. package/dist/monitoring/HomeostasisMonitor.d.ts.map +1 -0
  920. package/dist/monitoring/HomeostasisMonitor.js +185 -0
  921. package/dist/monitoring/HomeostasisMonitor.js.map +1 -0
  922. package/dist/monitoring/HookEventReceiver.d.ts +132 -0
  923. package/dist/monitoring/HookEventReceiver.d.ts.map +1 -0
  924. package/dist/monitoring/HookEventReceiver.js +209 -0
  925. package/dist/monitoring/HookEventReceiver.js.map +1 -0
  926. package/dist/monitoring/InputClassifier.d.ts +68 -0
  927. package/dist/monitoring/InputClassifier.d.ts.map +1 -0
  928. package/dist/monitoring/InputClassifier.js +243 -0
  929. package/dist/monitoring/InputClassifier.js.map +1 -0
  930. package/dist/monitoring/InstructionsVerifier.d.ts +76 -0
  931. package/dist/monitoring/InstructionsVerifier.d.ts.map +1 -0
  932. package/dist/monitoring/InstructionsVerifier.js +116 -0
  933. package/dist/monitoring/InstructionsVerifier.js.map +1 -0
  934. package/dist/monitoring/MemoryPressureMonitor.d.ts +107 -0
  935. package/dist/monitoring/MemoryPressureMonitor.d.ts.map +1 -0
  936. package/dist/monitoring/MemoryPressureMonitor.js +329 -0
  937. package/dist/monitoring/MemoryPressureMonitor.js.map +1 -0
  938. package/dist/monitoring/OrphanProcessReaper.d.ts +125 -0
  939. package/dist/monitoring/OrphanProcessReaper.d.ts.map +1 -0
  940. package/dist/monitoring/OrphanProcessReaper.js +476 -0
  941. package/dist/monitoring/OrphanProcessReaper.js.map +1 -0
  942. package/dist/monitoring/PresenceProxy.d.ts +167 -0
  943. package/dist/monitoring/PresenceProxy.d.ts.map +1 -0
  944. package/dist/monitoring/PresenceProxy.js +972 -0
  945. package/dist/monitoring/PresenceProxy.js.map +1 -0
  946. package/dist/monitoring/PromptGate.d.ts +91 -0
  947. package/dist/monitoring/PromptGate.d.ts.map +1 -0
  948. package/dist/monitoring/PromptGate.js +411 -0
  949. package/dist/monitoring/PromptGate.js.map +1 -0
  950. package/dist/monitoring/QuotaCollector.d.ts +267 -0
  951. package/dist/monitoring/QuotaCollector.d.ts.map +1 -0
  952. package/dist/monitoring/QuotaCollector.js +790 -0
  953. package/dist/monitoring/QuotaCollector.js.map +1 -0
  954. package/dist/monitoring/QuotaExhaustionDetector.d.ts +21 -0
  955. package/dist/monitoring/QuotaExhaustionDetector.d.ts.map +1 -0
  956. package/dist/monitoring/QuotaExhaustionDetector.js +136 -0
  957. package/dist/monitoring/QuotaExhaustionDetector.js.map +1 -0
  958. package/dist/monitoring/QuotaManager.d.ts +191 -0
  959. package/dist/monitoring/QuotaManager.d.ts.map +1 -0
  960. package/dist/monitoring/QuotaManager.js +575 -0
  961. package/dist/monitoring/QuotaManager.js.map +1 -0
  962. package/dist/monitoring/QuotaNotifier.d.ts +38 -0
  963. package/dist/monitoring/QuotaNotifier.d.ts.map +1 -0
  964. package/dist/monitoring/QuotaNotifier.js +144 -0
  965. package/dist/monitoring/QuotaNotifier.js.map +1 -0
  966. package/dist/monitoring/QuotaTracker.d.ts +92 -0
  967. package/dist/monitoring/QuotaTracker.d.ts.map +1 -0
  968. package/dist/monitoring/QuotaTracker.js +239 -0
  969. package/dist/monitoring/QuotaTracker.js.map +1 -0
  970. package/dist/monitoring/ReflectionMetrics.d.ts +97 -0
  971. package/dist/monitoring/ReflectionMetrics.d.ts.map +1 -0
  972. package/dist/monitoring/ReflectionMetrics.js +170 -0
  973. package/dist/monitoring/ReflectionMetrics.js.map +1 -0
  974. package/dist/monitoring/SessionActivitySentinel.d.ts +95 -0
  975. package/dist/monitoring/SessionActivitySentinel.d.ts.map +1 -0
  976. package/dist/monitoring/SessionActivitySentinel.js +391 -0
  977. package/dist/monitoring/SessionActivitySentinel.js.map +1 -0
  978. package/dist/monitoring/SessionCredentialManager.d.ts +56 -0
  979. package/dist/monitoring/SessionCredentialManager.d.ts.map +1 -0
  980. package/dist/monitoring/SessionCredentialManager.js +91 -0
  981. package/dist/monitoring/SessionCredentialManager.js.map +1 -0
  982. package/dist/monitoring/SessionMigrator.d.ts +234 -0
  983. package/dist/monitoring/SessionMigrator.d.ts.map +1 -0
  984. package/dist/monitoring/SessionMigrator.js +604 -0
  985. package/dist/monitoring/SessionMigrator.js.map +1 -0
  986. package/dist/monitoring/SessionMonitor.d.ts +102 -0
  987. package/dist/monitoring/SessionMonitor.d.ts.map +1 -0
  988. package/dist/monitoring/SessionMonitor.js +238 -0
  989. package/dist/monitoring/SessionMonitor.js.map +1 -0
  990. package/dist/monitoring/SessionRecovery.d.ts +129 -0
  991. package/dist/monitoring/SessionRecovery.d.ts.map +1 -0
  992. package/dist/monitoring/SessionRecovery.js +496 -0
  993. package/dist/monitoring/SessionRecovery.js.map +1 -0
  994. package/dist/monitoring/SessionWatchdog.d.ts +138 -0
  995. package/dist/monitoring/SessionWatchdog.d.ts.map +1 -0
  996. package/dist/monitoring/SessionWatchdog.js +549 -0
  997. package/dist/monitoring/SessionWatchdog.js.map +1 -0
  998. package/dist/monitoring/StallTriageNurse.d.ts +96 -0
  999. package/dist/monitoring/StallTriageNurse.d.ts.map +1 -0
  1000. package/dist/monitoring/StallTriageNurse.js +711 -0
  1001. package/dist/monitoring/StallTriageNurse.js.map +1 -0
  1002. package/dist/monitoring/StallTriageNurse.types.d.ts +124 -0
  1003. package/dist/monitoring/StallTriageNurse.types.d.ts.map +1 -0
  1004. package/dist/monitoring/StallTriageNurse.types.js +5 -0
  1005. package/dist/monitoring/StallTriageNurse.types.js.map +1 -0
  1006. package/dist/monitoring/SubagentTracker.d.ts +86 -0
  1007. package/dist/monitoring/SubagentTracker.d.ts.map +1 -0
  1008. package/dist/monitoring/SubagentTracker.js +199 -0
  1009. package/dist/monitoring/SubagentTracker.js.map +1 -0
  1010. package/dist/monitoring/SystemReviewer.d.ts +243 -0
  1011. package/dist/monitoring/SystemReviewer.d.ts.map +1 -0
  1012. package/dist/monitoring/SystemReviewer.js +697 -0
  1013. package/dist/monitoring/SystemReviewer.js.map +1 -0
  1014. package/dist/monitoring/TelemetryAuth.d.ts +64 -0
  1015. package/dist/monitoring/TelemetryAuth.d.ts.map +1 -0
  1016. package/dist/monitoring/TelemetryAuth.js +141 -0
  1017. package/dist/monitoring/TelemetryAuth.js.map +1 -0
  1018. package/dist/monitoring/TelemetryCollector.d.ts +95 -0
  1019. package/dist/monitoring/TelemetryCollector.d.ts.map +1 -0
  1020. package/dist/monitoring/TelemetryCollector.js +326 -0
  1021. package/dist/monitoring/TelemetryCollector.js.map +1 -0
  1022. package/dist/monitoring/TelemetryHeartbeat.d.ts +160 -0
  1023. package/dist/monitoring/TelemetryHeartbeat.d.ts.map +1 -0
  1024. package/dist/monitoring/TelemetryHeartbeat.js +450 -0
  1025. package/dist/monitoring/TelemetryHeartbeat.js.map +1 -0
  1026. package/dist/monitoring/TriageOrchestrator.d.ts +217 -0
  1027. package/dist/monitoring/TriageOrchestrator.d.ts.map +1 -0
  1028. package/dist/monitoring/TriageOrchestrator.js +801 -0
  1029. package/dist/monitoring/TriageOrchestrator.js.map +1 -0
  1030. package/dist/monitoring/WorktreeMonitor.d.ts +124 -0
  1031. package/dist/monitoring/WorktreeMonitor.d.ts.map +1 -0
  1032. package/dist/monitoring/WorktreeMonitor.js +379 -0
  1033. package/dist/monitoring/WorktreeMonitor.js.map +1 -0
  1034. package/dist/monitoring/crash-detector.d.ts +50 -0
  1035. package/dist/monitoring/crash-detector.d.ts.map +1 -0
  1036. package/dist/monitoring/crash-detector.js +224 -0
  1037. package/dist/monitoring/crash-detector.js.map +1 -0
  1038. package/dist/monitoring/jsonl-truncator.d.ts +44 -0
  1039. package/dist/monitoring/jsonl-truncator.d.ts.map +1 -0
  1040. package/dist/monitoring/jsonl-truncator.js +224 -0
  1041. package/dist/monitoring/jsonl-truncator.js.map +1 -0
  1042. package/dist/monitoring/probes/LifelineProbe.d.ts +38 -0
  1043. package/dist/monitoring/probes/LifelineProbe.d.ts.map +1 -0
  1044. package/dist/monitoring/probes/LifelineProbe.js +285 -0
  1045. package/dist/monitoring/probes/LifelineProbe.js.map +1 -0
  1046. package/dist/monitoring/probes/MessagingProbe.d.ts +23 -0
  1047. package/dist/monitoring/probes/MessagingProbe.d.ts.map +1 -0
  1048. package/dist/monitoring/probes/MessagingProbe.js +214 -0
  1049. package/dist/monitoring/probes/MessagingProbe.js.map +1 -0
  1050. package/dist/monitoring/probes/PlatformProbe.d.ts +15 -0
  1051. package/dist/monitoring/probes/PlatformProbe.d.ts.map +1 -0
  1052. package/dist/monitoring/probes/PlatformProbe.js +222 -0
  1053. package/dist/monitoring/probes/PlatformProbe.js.map +1 -0
  1054. package/dist/monitoring/probes/SchedulerProbe.d.ts +33 -0
  1055. package/dist/monitoring/probes/SchedulerProbe.d.ts.map +1 -0
  1056. package/dist/monitoring/probes/SchedulerProbe.js +196 -0
  1057. package/dist/monitoring/probes/SchedulerProbe.js.map +1 -0
  1058. package/dist/monitoring/probes/SessionProbe.d.ts +28 -0
  1059. package/dist/monitoring/probes/SessionProbe.d.ts.map +1 -0
  1060. package/dist/monitoring/probes/SessionProbe.js +234 -0
  1061. package/dist/monitoring/probes/SessionProbe.js.map +1 -0
  1062. package/dist/monitoring/stall-detector.d.ts +34 -0
  1063. package/dist/monitoring/stall-detector.d.ts.map +1 -0
  1064. package/dist/monitoring/stall-detector.js +151 -0
  1065. package/dist/monitoring/stall-detector.js.map +1 -0
  1066. package/dist/paste/PasteManager.d.ts +154 -0
  1067. package/dist/paste/PasteManager.d.ts.map +1 -0
  1068. package/dist/paste/PasteManager.js +524 -0
  1069. package/dist/paste/PasteManager.js.map +1 -0
  1070. package/dist/paste/TruncationDetector.d.ts +51 -0
  1071. package/dist/paste/TruncationDetector.d.ts.map +1 -0
  1072. package/dist/paste/TruncationDetector.js +220 -0
  1073. package/dist/paste/TruncationDetector.js.map +1 -0
  1074. package/dist/privacy/OutputPrivacyRouter.d.ts +65 -0
  1075. package/dist/privacy/OutputPrivacyRouter.d.ts.map +1 -0
  1076. package/dist/privacy/OutputPrivacyRouter.js +156 -0
  1077. package/dist/privacy/OutputPrivacyRouter.js.map +1 -0
  1078. package/dist/publishing/PrivateViewer.d.ts +63 -0
  1079. package/dist/publishing/PrivateViewer.d.ts.map +1 -0
  1080. package/dist/publishing/PrivateViewer.js +398 -0
  1081. package/dist/publishing/PrivateViewer.js.map +1 -0
  1082. package/dist/publishing/TelegraphService.d.ts +137 -0
  1083. package/dist/publishing/TelegraphService.d.ts.map +1 -0
  1084. package/dist/publishing/TelegraphService.js +410 -0
  1085. package/dist/publishing/TelegraphService.js.map +1 -0
  1086. package/dist/scaffold/bootstrap.d.ts +21 -0
  1087. package/dist/scaffold/bootstrap.d.ts.map +1 -0
  1088. package/dist/scaffold/bootstrap.js +125 -0
  1089. package/dist/scaffold/bootstrap.js.map +1 -0
  1090. package/dist/scaffold/templates.d.ts +47 -0
  1091. package/dist/scaffold/templates.d.ts.map +1 -0
  1092. package/dist/scaffold/templates.js +1506 -0
  1093. package/dist/scaffold/templates.js.map +1 -0
  1094. package/dist/scheduler/IntegrationGate.d.ts +81 -0
  1095. package/dist/scheduler/IntegrationGate.d.ts.map +1 -0
  1096. package/dist/scheduler/IntegrationGate.js +242 -0
  1097. package/dist/scheduler/IntegrationGate.js.map +1 -0
  1098. package/dist/scheduler/JobClaimManager.d.ts +137 -0
  1099. package/dist/scheduler/JobClaimManager.d.ts.map +1 -0
  1100. package/dist/scheduler/JobClaimManager.js +283 -0
  1101. package/dist/scheduler/JobClaimManager.js.map +1 -0
  1102. package/dist/scheduler/JobLoader.d.ts +28 -0
  1103. package/dist/scheduler/JobLoader.d.ts.map +1 -0
  1104. package/dist/scheduler/JobLoader.js +269 -0
  1105. package/dist/scheduler/JobLoader.js.map +1 -0
  1106. package/dist/scheduler/JobRunHistory.d.ts +180 -0
  1107. package/dist/scheduler/JobRunHistory.d.ts.map +1 -0
  1108. package/dist/scheduler/JobRunHistory.js +349 -0
  1109. package/dist/scheduler/JobRunHistory.js.map +1 -0
  1110. package/dist/scheduler/JobScheduler.d.ts +244 -0
  1111. package/dist/scheduler/JobScheduler.d.ts.map +1 -0
  1112. package/dist/scheduler/JobScheduler.js +1085 -0
  1113. package/dist/scheduler/JobScheduler.js.map +1 -0
  1114. package/dist/scheduler/SkipLedger.d.ts +65 -0
  1115. package/dist/scheduler/SkipLedger.d.ts.map +1 -0
  1116. package/dist/scheduler/SkipLedger.js +179 -0
  1117. package/dist/scheduler/SkipLedger.js.map +1 -0
  1118. package/dist/security/LLMSanitizer.d.ts +65 -0
  1119. package/dist/security/LLMSanitizer.d.ts.map +1 -0
  1120. package/dist/security/LLMSanitizer.js +153 -0
  1121. package/dist/security/LLMSanitizer.js.map +1 -0
  1122. package/dist/security/ManifestIntegrity.d.ts +72 -0
  1123. package/dist/security/ManifestIntegrity.d.ts.map +1 -0
  1124. package/dist/security/ManifestIntegrity.js +159 -0
  1125. package/dist/security/ManifestIntegrity.js.map +1 -0
  1126. package/dist/server/AgentServer.d.ts +134 -0
  1127. package/dist/server/AgentServer.d.ts.map +1 -0
  1128. package/dist/server/AgentServer.js +307 -0
  1129. package/dist/server/AgentServer.js.map +1 -0
  1130. package/dist/server/SecretDrop.d.ts +133 -0
  1131. package/dist/server/SecretDrop.d.ts.map +1 -0
  1132. package/dist/server/SecretDrop.js +473 -0
  1133. package/dist/server/SecretDrop.js.map +1 -0
  1134. package/dist/server/WebSocketManager.d.ts +80 -0
  1135. package/dist/server/WebSocketManager.d.ts.map +1 -0
  1136. package/dist/server/WebSocketManager.js +367 -0
  1137. package/dist/server/WebSocketManager.js.map +1 -0
  1138. package/dist/server/fileRoutes.d.ts +19 -0
  1139. package/dist/server/fileRoutes.d.ts.map +1 -0
  1140. package/dist/server/fileRoutes.js +578 -0
  1141. package/dist/server/fileRoutes.js.map +1 -0
  1142. package/dist/server/machineAuth.d.ts +87 -0
  1143. package/dist/server/machineAuth.d.ts.map +1 -0
  1144. package/dist/server/machineAuth.js +188 -0
  1145. package/dist/server/machineAuth.js.map +1 -0
  1146. package/dist/server/machineRoutes.d.ts +49 -0
  1147. package/dist/server/machineRoutes.d.ts.map +1 -0
  1148. package/dist/server/machineRoutes.js +305 -0
  1149. package/dist/server/machineRoutes.js.map +1 -0
  1150. package/dist/server/middleware.d.ts +32 -0
  1151. package/dist/server/middleware.d.ts.map +1 -0
  1152. package/dist/server/middleware.js +202 -0
  1153. package/dist/server/middleware.js.map +1 -0
  1154. package/dist/server/routes.d.ts +132 -0
  1155. package/dist/server/routes.d.ts.map +1 -0
  1156. package/dist/server/routes.js +8124 -0
  1157. package/dist/server/routes.js.map +1 -0
  1158. package/dist/threadline/A2AGateway.d.ts +184 -0
  1159. package/dist/threadline/A2AGateway.d.ts.map +1 -0
  1160. package/dist/threadline/A2AGateway.js +438 -0
  1161. package/dist/threadline/A2AGateway.js.map +1 -0
  1162. package/dist/threadline/AgentCard.d.ts +116 -0
  1163. package/dist/threadline/AgentCard.d.ts.map +1 -0
  1164. package/dist/threadline/AgentCard.js +212 -0
  1165. package/dist/threadline/AgentCard.js.map +1 -0
  1166. package/dist/threadline/AgentDiscovery.d.ts +156 -0
  1167. package/dist/threadline/AgentDiscovery.d.ts.map +1 -0
  1168. package/dist/threadline/AgentDiscovery.js +390 -0
  1169. package/dist/threadline/AgentDiscovery.js.map +1 -0
  1170. package/dist/threadline/AgentTrustManager.d.ts +190 -0
  1171. package/dist/threadline/AgentTrustManager.d.ts.map +1 -0
  1172. package/dist/threadline/AgentTrustManager.js +526 -0
  1173. package/dist/threadline/AgentTrustManager.js.map +1 -0
  1174. package/dist/threadline/ApprovalQueue.d.ts +71 -0
  1175. package/dist/threadline/ApprovalQueue.d.ts.map +1 -0
  1176. package/dist/threadline/ApprovalQueue.js +154 -0
  1177. package/dist/threadline/ApprovalQueue.js.map +1 -0
  1178. package/dist/threadline/AutonomyGate.d.ts +130 -0
  1179. package/dist/threadline/AutonomyGate.d.ts.map +1 -0
  1180. package/dist/threadline/AutonomyGate.js +267 -0
  1181. package/dist/threadline/AutonomyGate.js.map +1 -0
  1182. package/dist/threadline/CircuitBreaker.d.ts +89 -0
  1183. package/dist/threadline/CircuitBreaker.d.ts.map +1 -0
  1184. package/dist/threadline/CircuitBreaker.js +238 -0
  1185. package/dist/threadline/CircuitBreaker.js.map +1 -0
  1186. package/dist/threadline/ComputeMeter.d.ts +114 -0
  1187. package/dist/threadline/ComputeMeter.d.ts.map +1 -0
  1188. package/dist/threadline/ComputeMeter.js +350 -0
  1189. package/dist/threadline/ComputeMeter.js.map +1 -0
  1190. package/dist/threadline/ContentClassifier.d.ts +83 -0
  1191. package/dist/threadline/ContentClassifier.d.ts.map +1 -0
  1192. package/dist/threadline/ContentClassifier.js +201 -0
  1193. package/dist/threadline/ContentClassifier.js.map +1 -0
  1194. package/dist/threadline/ContextThreadMap.d.ts +103 -0
  1195. package/dist/threadline/ContextThreadMap.d.ts.map +1 -0
  1196. package/dist/threadline/ContextThreadMap.js +279 -0
  1197. package/dist/threadline/ContextThreadMap.js.map +1 -0
  1198. package/dist/threadline/DNSVerifier.d.ts +48 -0
  1199. package/dist/threadline/DNSVerifier.d.ts.map +1 -0
  1200. package/dist/threadline/DNSVerifier.js +138 -0
  1201. package/dist/threadline/DNSVerifier.js.map +1 -0
  1202. package/dist/threadline/DigestCollector.d.ts +70 -0
  1203. package/dist/threadline/DigestCollector.d.ts.map +1 -0
  1204. package/dist/threadline/DigestCollector.js +146 -0
  1205. package/dist/threadline/DigestCollector.js.map +1 -0
  1206. package/dist/threadline/HandshakeManager.d.ts +130 -0
  1207. package/dist/threadline/HandshakeManager.d.ts.map +1 -0
  1208. package/dist/threadline/HandshakeManager.js +402 -0
  1209. package/dist/threadline/HandshakeManager.js.map +1 -0
  1210. package/dist/threadline/InboundMessageGate.d.ts +80 -0
  1211. package/dist/threadline/InboundMessageGate.d.ts.map +1 -0
  1212. package/dist/threadline/InboundMessageGate.js +241 -0
  1213. package/dist/threadline/InboundMessageGate.js.map +1 -0
  1214. package/dist/threadline/InvitationManager.d.ts +91 -0
  1215. package/dist/threadline/InvitationManager.d.ts.map +1 -0
  1216. package/dist/threadline/InvitationManager.js +228 -0
  1217. package/dist/threadline/InvitationManager.js.map +1 -0
  1218. package/dist/threadline/ListenerSessionManager.d.ts +147 -0
  1219. package/dist/threadline/ListenerSessionManager.d.ts.map +1 -0
  1220. package/dist/threadline/ListenerSessionManager.js +326 -0
  1221. package/dist/threadline/ListenerSessionManager.js.map +1 -0
  1222. package/dist/threadline/MCPAuth.d.ts +98 -0
  1223. package/dist/threadline/MCPAuth.d.ts.map +1 -0
  1224. package/dist/threadline/MCPAuth.js +228 -0
  1225. package/dist/threadline/MCPAuth.js.map +1 -0
  1226. package/dist/threadline/OpenClawBridge.d.ts +143 -0
  1227. package/dist/threadline/OpenClawBridge.d.ts.map +1 -0
  1228. package/dist/threadline/OpenClawBridge.js +336 -0
  1229. package/dist/threadline/OpenClawBridge.js.map +1 -0
  1230. package/dist/threadline/OpenClawSkillManifest.d.ts +47 -0
  1231. package/dist/threadline/OpenClawSkillManifest.d.ts.map +1 -0
  1232. package/dist/threadline/OpenClawSkillManifest.js +148 -0
  1233. package/dist/threadline/OpenClawSkillManifest.js.map +1 -0
  1234. package/dist/threadline/RateLimiter.d.ts +105 -0
  1235. package/dist/threadline/RateLimiter.d.ts.map +1 -0
  1236. package/dist/threadline/RateLimiter.js +236 -0
  1237. package/dist/threadline/RateLimiter.js.map +1 -0
  1238. package/dist/threadline/RelayGroundingPreamble.d.ts +48 -0
  1239. package/dist/threadline/RelayGroundingPreamble.d.ts.map +1 -0
  1240. package/dist/threadline/RelayGroundingPreamble.js +68 -0
  1241. package/dist/threadline/RelayGroundingPreamble.js.map +1 -0
  1242. package/dist/threadline/SessionLifecycle.d.ts +136 -0
  1243. package/dist/threadline/SessionLifecycle.d.ts.map +1 -0
  1244. package/dist/threadline/SessionLifecycle.js +317 -0
  1245. package/dist/threadline/SessionLifecycle.js.map +1 -0
  1246. package/dist/threadline/ThreadResumeMap.d.ts +128 -0
  1247. package/dist/threadline/ThreadResumeMap.d.ts.map +1 -0
  1248. package/dist/threadline/ThreadResumeMap.js +324 -0
  1249. package/dist/threadline/ThreadResumeMap.js.map +1 -0
  1250. package/dist/threadline/ThreadlineBootstrap.d.ts +68 -0
  1251. package/dist/threadline/ThreadlineBootstrap.d.ts.map +1 -0
  1252. package/dist/threadline/ThreadlineBootstrap.js +293 -0
  1253. package/dist/threadline/ThreadlineBootstrap.js.map +1 -0
  1254. package/dist/threadline/ThreadlineCrypto.d.ts +53 -0
  1255. package/dist/threadline/ThreadlineCrypto.d.ts.map +1 -0
  1256. package/dist/threadline/ThreadlineCrypto.js +123 -0
  1257. package/dist/threadline/ThreadlineCrypto.js.map +1 -0
  1258. package/dist/threadline/ThreadlineEndpoints.d.ts +35 -0
  1259. package/dist/threadline/ThreadlineEndpoints.d.ts.map +1 -0
  1260. package/dist/threadline/ThreadlineEndpoints.js +313 -0
  1261. package/dist/threadline/ThreadlineEndpoints.js.map +1 -0
  1262. package/dist/threadline/ThreadlineMCPServer.d.ts +165 -0
  1263. package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -0
  1264. package/dist/threadline/ThreadlineMCPServer.js +885 -0
  1265. package/dist/threadline/ThreadlineMCPServer.js.map +1 -0
  1266. package/dist/threadline/ThreadlineRouter.d.ts +105 -0
  1267. package/dist/threadline/ThreadlineRouter.d.ts.map +1 -0
  1268. package/dist/threadline/ThreadlineRouter.js +323 -0
  1269. package/dist/threadline/ThreadlineRouter.js.map +1 -0
  1270. package/dist/threadline/TrustBootstrap.d.ts +92 -0
  1271. package/dist/threadline/TrustBootstrap.d.ts.map +1 -0
  1272. package/dist/threadline/TrustBootstrap.js +256 -0
  1273. package/dist/threadline/TrustBootstrap.js.map +1 -0
  1274. package/dist/threadline/adapters/AutoGenTool.d.ts +42 -0
  1275. package/dist/threadline/adapters/AutoGenTool.d.ts.map +1 -0
  1276. package/dist/threadline/adapters/AutoGenTool.js +145 -0
  1277. package/dist/threadline/adapters/AutoGenTool.js.map +1 -0
  1278. package/dist/threadline/adapters/CrewAITool.d.ts +31 -0
  1279. package/dist/threadline/adapters/CrewAITool.d.ts.map +1 -0
  1280. package/dist/threadline/adapters/CrewAITool.js +112 -0
  1281. package/dist/threadline/adapters/CrewAITool.js.map +1 -0
  1282. package/dist/threadline/adapters/LangGraphTool.d.ts +48 -0
  1283. package/dist/threadline/adapters/LangGraphTool.d.ts.map +1 -0
  1284. package/dist/threadline/adapters/LangGraphTool.js +153 -0
  1285. package/dist/threadline/adapters/LangGraphTool.js.map +1 -0
  1286. package/dist/threadline/adapters/RESTServer.d.ts +74 -0
  1287. package/dist/threadline/adapters/RESTServer.d.ts.map +1 -0
  1288. package/dist/threadline/adapters/RESTServer.js +291 -0
  1289. package/dist/threadline/adapters/RESTServer.js.map +1 -0
  1290. package/dist/threadline/adapters/index.d.ts +14 -0
  1291. package/dist/threadline/adapters/index.d.ts.map +1 -0
  1292. package/dist/threadline/adapters/index.js +10 -0
  1293. package/dist/threadline/adapters/index.js.map +1 -0
  1294. package/dist/threadline/client/IdentityManager.d.ts +40 -0
  1295. package/dist/threadline/client/IdentityManager.d.ts.map +1 -0
  1296. package/dist/threadline/client/IdentityManager.js +106 -0
  1297. package/dist/threadline/client/IdentityManager.js.map +1 -0
  1298. package/dist/threadline/client/MessageEncryptor.d.ts +63 -0
  1299. package/dist/threadline/client/MessageEncryptor.d.ts.map +1 -0
  1300. package/dist/threadline/client/MessageEncryptor.js +195 -0
  1301. package/dist/threadline/client/MessageEncryptor.js.map +1 -0
  1302. package/dist/threadline/client/RegistryRestClient.d.ts +46 -0
  1303. package/dist/threadline/client/RegistryRestClient.d.ts.map +1 -0
  1304. package/dist/threadline/client/RegistryRestClient.js +114 -0
  1305. package/dist/threadline/client/RegistryRestClient.js.map +1 -0
  1306. package/dist/threadline/client/RelayClient.d.ts +77 -0
  1307. package/dist/threadline/client/RelayClient.d.ts.map +1 -0
  1308. package/dist/threadline/client/RelayClient.js +249 -0
  1309. package/dist/threadline/client/RelayClient.js.map +1 -0
  1310. package/dist/threadline/client/ThreadlineClient.d.ts +117 -0
  1311. package/dist/threadline/client/ThreadlineClient.d.ts.map +1 -0
  1312. package/dist/threadline/client/ThreadlineClient.js +286 -0
  1313. package/dist/threadline/client/ThreadlineClient.js.map +1 -0
  1314. package/dist/threadline/client/index.d.ts +14 -0
  1315. package/dist/threadline/client/index.d.ts.map +1 -0
  1316. package/dist/threadline/client/index.js +9 -0
  1317. package/dist/threadline/client/index.js.map +1 -0
  1318. package/dist/threadline/index.d.ts +81 -0
  1319. package/dist/threadline/index.d.ts.map +1 -0
  1320. package/dist/threadline/index.js +57 -0
  1321. package/dist/threadline/index.js.map +1 -0
  1322. package/dist/threadline/mcp-stdio-entry.d.ts +24 -0
  1323. package/dist/threadline/mcp-stdio-entry.d.ts.map +1 -0
  1324. package/dist/threadline/mcp-stdio-entry.js +230 -0
  1325. package/dist/threadline/mcp-stdio-entry.js.map +1 -0
  1326. package/dist/threadline/relay/A2ABridge.d.ts +91 -0
  1327. package/dist/threadline/relay/A2ABridge.d.ts.map +1 -0
  1328. package/dist/threadline/relay/A2ABridge.js +457 -0
  1329. package/dist/threadline/relay/A2ABridge.js.map +1 -0
  1330. package/dist/threadline/relay/AbuseDetector.d.ts +131 -0
  1331. package/dist/threadline/relay/AbuseDetector.d.ts.map +1 -0
  1332. package/dist/threadline/relay/AbuseDetector.js +358 -0
  1333. package/dist/threadline/relay/AbuseDetector.js.map +1 -0
  1334. package/dist/threadline/relay/AdminServer.d.ts +55 -0
  1335. package/dist/threadline/relay/AdminServer.d.ts.map +1 -0
  1336. package/dist/threadline/relay/AdminServer.js +215 -0
  1337. package/dist/threadline/relay/AdminServer.js.map +1 -0
  1338. package/dist/threadline/relay/ConnectionManager.d.ts +86 -0
  1339. package/dist/threadline/relay/ConnectionManager.d.ts.map +1 -0
  1340. package/dist/threadline/relay/ConnectionManager.js +356 -0
  1341. package/dist/threadline/relay/ConnectionManager.js.map +1 -0
  1342. package/dist/threadline/relay/MessageRouter.d.ts +46 -0
  1343. package/dist/threadline/relay/MessageRouter.d.ts.map +1 -0
  1344. package/dist/threadline/relay/MessageRouter.js +138 -0
  1345. package/dist/threadline/relay/MessageRouter.js.map +1 -0
  1346. package/dist/threadline/relay/OfflineQueue.d.ts +87 -0
  1347. package/dist/threadline/relay/OfflineQueue.d.ts.map +1 -0
  1348. package/dist/threadline/relay/OfflineQueue.js +137 -0
  1349. package/dist/threadline/relay/OfflineQueue.js.map +1 -0
  1350. package/dist/threadline/relay/PresenceRegistry.d.ts +62 -0
  1351. package/dist/threadline/relay/PresenceRegistry.d.ts.map +1 -0
  1352. package/dist/threadline/relay/PresenceRegistry.js +148 -0
  1353. package/dist/threadline/relay/PresenceRegistry.js.map +1 -0
  1354. package/dist/threadline/relay/RegistryAuth.d.ts +45 -0
  1355. package/dist/threadline/relay/RegistryAuth.d.ts.map +1 -0
  1356. package/dist/threadline/relay/RegistryAuth.js +118 -0
  1357. package/dist/threadline/relay/RegistryAuth.js.map +1 -0
  1358. package/dist/threadline/relay/RegistryStore.d.ts +149 -0
  1359. package/dist/threadline/relay/RegistryStore.d.ts.map +1 -0
  1360. package/dist/threadline/relay/RegistryStore.js +542 -0
  1361. package/dist/threadline/relay/RegistryStore.js.map +1 -0
  1362. package/dist/threadline/relay/RelayMetrics.d.ts +62 -0
  1363. package/dist/threadline/relay/RelayMetrics.d.ts.map +1 -0
  1364. package/dist/threadline/relay/RelayMetrics.js +149 -0
  1365. package/dist/threadline/relay/RelayMetrics.js.map +1 -0
  1366. package/dist/threadline/relay/RelayRateLimiter.d.ts +58 -0
  1367. package/dist/threadline/relay/RelayRateLimiter.d.ts.map +1 -0
  1368. package/dist/threadline/relay/RelayRateLimiter.js +116 -0
  1369. package/dist/threadline/relay/RelayRateLimiter.js.map +1 -0
  1370. package/dist/threadline/relay/RelayServer.d.ts +94 -0
  1371. package/dist/threadline/relay/RelayServer.d.ts.map +1 -0
  1372. package/dist/threadline/relay/RelayServer.js +1049 -0
  1373. package/dist/threadline/relay/RelayServer.js.map +1 -0
  1374. package/dist/threadline/relay/index.d.ts +28 -0
  1375. package/dist/threadline/relay/index.d.ts.map +1 -0
  1376. package/dist/threadline/relay/index.js +17 -0
  1377. package/dist/threadline/relay/index.js.map +1 -0
  1378. package/dist/threadline/relay/types.d.ts +215 -0
  1379. package/dist/threadline/relay/types.d.ts.map +1 -0
  1380. package/dist/threadline/relay/types.js +21 -0
  1381. package/dist/threadline/relay/types.js.map +1 -0
  1382. package/dist/threadline/types.d.ts +39 -0
  1383. package/dist/threadline/types.d.ts.map +1 -0
  1384. package/dist/threadline/types.js +10 -0
  1385. package/dist/threadline/types.js.map +1 -0
  1386. package/dist/tunnel/TunnelManager.d.ts +113 -0
  1387. package/dist/tunnel/TunnelManager.d.ts.map +1 -0
  1388. package/dist/tunnel/TunnelManager.js +474 -0
  1389. package/dist/tunnel/TunnelManager.js.map +1 -0
  1390. package/dist/types/pipeline.d.ts +203 -0
  1391. package/dist/types/pipeline.d.ts.map +1 -0
  1392. package/dist/types/pipeline.js +152 -0
  1393. package/dist/types/pipeline.js.map +1 -0
  1394. package/dist/users/GdprCommands.d.ts +44 -0
  1395. package/dist/users/GdprCommands.d.ts.map +1 -0
  1396. package/dist/users/GdprCommands.js +153 -0
  1397. package/dist/users/GdprCommands.js.map +1 -0
  1398. package/dist/users/OnboardingGate.d.ts +107 -0
  1399. package/dist/users/OnboardingGate.d.ts.map +1 -0
  1400. package/dist/users/OnboardingGate.js +240 -0
  1401. package/dist/users/OnboardingGate.js.map +1 -0
  1402. package/dist/users/UserContextBuilder.d.ts +47 -0
  1403. package/dist/users/UserContextBuilder.d.ts.map +1 -0
  1404. package/dist/users/UserContextBuilder.js +174 -0
  1405. package/dist/users/UserContextBuilder.js.map +1 -0
  1406. package/dist/users/UserManager.d.ts +76 -0
  1407. package/dist/users/UserManager.d.ts.map +1 -0
  1408. package/dist/users/UserManager.js +213 -0
  1409. package/dist/users/UserManager.js.map +1 -0
  1410. package/dist/users/UserOnboarding.d.ts +145 -0
  1411. package/dist/users/UserOnboarding.d.ts.map +1 -0
  1412. package/dist/users/UserOnboarding.js +488 -0
  1413. package/dist/users/UserOnboarding.js.map +1 -0
  1414. package/dist/users/UserPropagator.d.ts +75 -0
  1415. package/dist/users/UserPropagator.d.ts.map +1 -0
  1416. package/dist/users/UserPropagator.js +145 -0
  1417. package/dist/users/UserPropagator.js.map +1 -0
  1418. package/dist/utils/jsonl-rotation.d.ts +27 -0
  1419. package/dist/utils/jsonl-rotation.d.ts.map +1 -0
  1420. package/dist/utils/jsonl-rotation.js +63 -0
  1421. package/dist/utils/jsonl-rotation.js.map +1 -0
  1422. package/dist/utils/privacy.d.ts +88 -0
  1423. package/dist/utils/privacy.d.ts.map +1 -0
  1424. package/dist/utils/privacy.js +182 -0
  1425. package/dist/utils/privacy.js.map +1 -0
  1426. package/dist/utils/sanitize.d.ts +81 -0
  1427. package/dist/utils/sanitize.d.ts.map +1 -0
  1428. package/dist/utils/sanitize.js +122 -0
  1429. package/dist/utils/sanitize.js.map +1 -0
  1430. package/package.json +1 -0
  1431. package/playbook-scripts/atomic_write.py +133 -0
  1432. package/playbook-scripts/bootstrap-manifest.json +92 -0
  1433. package/playbook-scripts/playbook-annotate-context.py +239 -0
  1434. package/playbook-scripts/playbook-assemble.py +385 -0
  1435. package/playbook-scripts/playbook-dashboard.py +242 -0
  1436. package/playbook-scripts/playbook-decay.py +377 -0
  1437. package/playbook-scripts/playbook-dedup-job.py +252 -0
  1438. package/playbook-scripts/playbook-dedup.py +341 -0
  1439. package/playbook-scripts/playbook-delta-validator.py +576 -0
  1440. package/playbook-scripts/playbook-dsar.py +291 -0
  1441. package/playbook-scripts/playbook-eval-log.py +425 -0
  1442. package/playbook-scripts/playbook-failsafe.py +513 -0
  1443. package/playbook-scripts/playbook-feedback-quarantine.py +335 -0
  1444. package/playbook-scripts/playbook-history.py +293 -0
  1445. package/playbook-scripts/playbook-hmac.py +224 -0
  1446. package/playbook-scripts/playbook-lifecycle.py +952 -0
  1447. package/playbook-scripts/playbook-manifest.py +458 -0
  1448. package/playbook-scripts/playbook-micro-eval.py +316 -0
  1449. package/playbook-scripts/playbook-migrate-lessons.py +396 -0
  1450. package/playbook-scripts/playbook-mount.py +393 -0
  1451. package/playbook-scripts/playbook-offline-adapt.py +323 -0
  1452. package/playbook-scripts/playbook-pii-screen.py +207 -0
  1453. package/playbook-scripts/playbook-reflector.py +266 -0
  1454. package/playbook-scripts/playbook-relevance.py +269 -0
  1455. package/playbook-scripts/playbook-retirement.py +365 -0
  1456. package/playbook-scripts/playbook-schema-validate.py +267 -0
  1457. package/playbook-scripts/playbook-scratchpad.py +346 -0
  1458. package/playbook-scripts/playbook-semantic-verify.py +280 -0
  1459. package/playbook-scripts/playbook-spawn-contract.py +341 -0
  1460. package/playbook-scripts/playbook-token-reestimate.py +248 -0
  1461. package/playbook-scripts/playbook-verify.py +357 -0
  1462. package/playbook-scripts/playbook_backend.py +249 -0
  1463. package/playbook-scripts/playbook_paths.py +232 -0
  1464. package/playbook-scripts/schemas/context-delta.schema.json +137 -0
  1465. package/playbook-scripts/schemas/context-manifest.schema.json +200 -0
  1466. package/playbook-scripts/schemas/playbook-config.schema.json +184 -0
  1467. package/scripts/analyze-release.js +752 -0
  1468. package/scripts/check-upgrade-guide.js +373 -0
  1469. package/scripts/collect-metrics.py +248 -0
  1470. package/scripts/demo-two-agents.mjs +187 -0
  1471. package/scripts/fix-better-sqlite3.cjs +100 -0
  1472. package/scripts/generate-builtin-manifest.cjs +440 -0
  1473. package/scripts/pre-push-gate.js +177 -0
  1474. package/scripts/relay-entrypoint.mjs +18 -0
  1475. package/scripts/seed-registry.mjs +258 -0
  1476. package/scripts/telemetry-worker/worker.js +776 -0
  1477. package/scripts/telemetry-worker/wrangler.toml +7 -0
  1478. package/scripts/test-bootstrap-relay.mjs +90 -0
  1479. package/scripts/test-multi-agent-relay.mjs +395 -0
  1480. package/scripts/test-relay-cloud.mjs +389 -0
  1481. package/scripts/test-relay-live.mjs +550 -0
  1482. package/src/data/builtin-manifest.json +1463 -0
  1483. package/src/data/http-hook-templates.ts +81 -0
  1484. package/src/templates/hooks/compaction-recovery.sh +371 -0
  1485. package/src/templates/hooks/dangerous-command-guard.sh +100 -0
  1486. package/src/templates/hooks/free-text-guard.sh +96 -0
  1487. package/src/templates/hooks/grounding-before-messaging.sh +52 -0
  1488. package/src/templates/hooks/session-start.sh +339 -0
  1489. package/src/templates/hooks/settings-template.json +142 -0
  1490. package/src/templates/hooks/slack-channel-context.sh +98 -0
  1491. package/src/templates/hooks/telegram-topic-context.sh +117 -0
  1492. package/src/templates/scripts/convergence-check.sh +99 -0
  1493. package/src/templates/scripts/git-sync-gate.sh +89 -0
  1494. package/src/templates/scripts/health-watchdog.sh +63 -0
  1495. package/src/templates/scripts/serendipity-capture.sh +345 -0
  1496. package/src/templates/scripts/slack-reply.sh +74 -0
  1497. package/src/templates/scripts/smart-fetch.py +215 -0
  1498. package/src/templates/scripts/telegram-reply.sh +67 -0
  1499. package/src/templates/scripts/whatsapp-reply.sh +68 -0
  1500. package/upgrades/0.10.0.md +254 -0
  1501. package/upgrades/0.10.1.md +47 -0
  1502. package/upgrades/0.10.2.md +26 -0
  1503. package/upgrades/0.10.3.md +23 -0
  1504. package/upgrades/0.10.4.md +26 -0
  1505. package/upgrades/0.10.5.md +19 -0
  1506. package/upgrades/0.10.6.md +35 -0
  1507. package/upgrades/0.10.7.md +48 -0
  1508. package/upgrades/0.10.8.md +53 -0
  1509. package/upgrades/0.10.9.md +21 -0
  1510. package/upgrades/0.11.0.md +146 -0
  1511. package/upgrades/0.12.0.md +31 -0
  1512. package/upgrades/0.12.1.md +21 -0
  1513. package/upgrades/0.12.10.md +26 -0
  1514. package/upgrades/0.12.11.md +23 -0
  1515. package/upgrades/0.12.12.md +23 -0
  1516. package/upgrades/0.12.13.md +19 -0
  1517. package/upgrades/0.12.14.md +21 -0
  1518. package/upgrades/0.12.15.md +26 -0
  1519. package/upgrades/0.12.16.md +33 -0
  1520. package/upgrades/0.12.17.md +38 -0
  1521. package/upgrades/0.12.18.md +27 -0
  1522. package/upgrades/0.12.19.md +31 -0
  1523. package/upgrades/0.12.2.md +27 -0
  1524. package/upgrades/0.12.20.md +24 -0
  1525. package/upgrades/0.12.21.md +28 -0
  1526. package/upgrades/0.12.22.md +23 -0
  1527. package/upgrades/0.12.23.md +44 -0
  1528. package/upgrades/0.12.24.md +24 -0
  1529. package/upgrades/0.12.25.md +55 -0
  1530. package/upgrades/0.12.26.md +31 -0
  1531. package/upgrades/0.12.27.md +19 -0
  1532. package/upgrades/0.12.28.md +19 -0
  1533. package/upgrades/0.12.29.md +42 -0
  1534. package/upgrades/0.12.3.md +22 -0
  1535. package/upgrades/0.12.31.md +24 -0
  1536. package/upgrades/0.12.32.md +34 -0
  1537. package/upgrades/0.12.33.md +62 -0
  1538. package/upgrades/0.12.34.md +59 -0
  1539. package/upgrades/0.12.4.md +19 -0
  1540. package/upgrades/0.12.5.md +31 -0
  1541. package/upgrades/0.12.6.md +34 -0
  1542. package/upgrades/0.12.7.md +24 -0
  1543. package/upgrades/0.12.8.md +28 -0
  1544. package/upgrades/0.12.9.md +30 -0
  1545. package/upgrades/0.13.0.md +26 -0
  1546. package/upgrades/0.14.0.md +75 -0
  1547. package/upgrades/0.14.1.md +41 -0
  1548. package/upgrades/0.15.0.md +59 -0
  1549. package/upgrades/0.16.0.md +61 -0
  1550. package/upgrades/0.17.0.md +88 -0
  1551. package/upgrades/0.17.10.md +23 -0
  1552. package/upgrades/0.17.11.md +25 -0
  1553. package/upgrades/0.17.12.md +43 -0
  1554. package/upgrades/0.17.13.md +24 -0
  1555. package/upgrades/0.17.14.md +26 -0
  1556. package/upgrades/0.17.2.md +42 -0
  1557. package/upgrades/0.17.3.md +37 -0
  1558. package/upgrades/0.17.4.md +27 -0
  1559. package/upgrades/0.17.5.md +32 -0
  1560. package/upgrades/0.17.6.md +32 -0
  1561. package/upgrades/0.17.7.md +39 -0
  1562. package/upgrades/0.17.8.md +34 -0
  1563. package/upgrades/0.17.9.md +25 -0
  1564. package/upgrades/0.18.1.md +34 -0
  1565. package/upgrades/0.18.2.md +29 -0
  1566. package/upgrades/0.18.3.md +26 -0
  1567. package/upgrades/0.18.4.md +28 -0
  1568. package/upgrades/0.18.5.md +25 -0
  1569. package/upgrades/0.18.6.md +25 -0
  1570. package/upgrades/0.18.7.md +30 -0
  1571. package/upgrades/0.19.0.md +136 -0
  1572. package/upgrades/0.19.1.md +27 -0
  1573. package/upgrades/0.19.2.md +27 -0
  1574. package/upgrades/0.19.3.md +32 -0
  1575. package/upgrades/0.19.4.md +19 -0
  1576. package/upgrades/0.19.6.md +17 -0
  1577. package/upgrades/0.19.7.md +33 -0
  1578. package/upgrades/0.20.0.md +54 -0
  1579. package/upgrades/0.21.1.md +55 -0
  1580. package/upgrades/0.21.2.md +48 -0
  1581. package/upgrades/0.21.3.md +29 -0
  1582. package/upgrades/0.21.4.md +33 -0
  1583. package/upgrades/0.22.0.md +114 -0
  1584. package/upgrades/0.23.0.md +81 -0
  1585. package/upgrades/0.23.1.md +28 -0
  1586. package/upgrades/0.23.10.md +19 -0
  1587. package/upgrades/0.23.11.md +21 -0
  1588. package/upgrades/0.23.12.md +30 -0
  1589. package/upgrades/0.23.13.md +25 -0
  1590. package/upgrades/0.23.14.md +23 -0
  1591. package/upgrades/0.23.15.md +30 -0
  1592. package/upgrades/0.23.16.md +21 -0
  1593. package/upgrades/0.23.17.md +23 -0
  1594. package/upgrades/0.23.18.md +41 -0
  1595. package/upgrades/0.23.2.md +32 -0
  1596. package/upgrades/0.23.4.md +21 -0
  1597. package/upgrades/0.23.6.md +19 -0
  1598. package/upgrades/0.23.7.md +33 -0
  1599. package/upgrades/0.23.8.md +38 -0
  1600. package/upgrades/0.23.9.md +35 -0
  1601. package/upgrades/0.24.1.md +32 -0
  1602. package/upgrades/0.24.10.md +23 -0
  1603. package/upgrades/0.24.12.md +17 -0
  1604. package/upgrades/0.24.13.md +16 -0
  1605. package/upgrades/0.24.14.md +26 -0
  1606. package/upgrades/0.24.15.md +49 -0
  1607. package/upgrades/0.24.16.md +48 -0
  1608. package/upgrades/0.24.17.md +40 -0
  1609. package/upgrades/0.24.18-beta.0.md +35 -0
  1610. package/upgrades/0.24.18.md +35 -0
  1611. package/upgrades/0.24.19.md +21 -0
  1612. package/upgrades/0.24.2.md +13 -0
  1613. package/upgrades/0.24.20.md +45 -0
  1614. package/upgrades/0.24.21.md +25 -0
  1615. package/upgrades/0.24.22.md +35 -0
  1616. package/upgrades/0.24.23.md +17 -0
  1617. package/upgrades/0.24.24.md +15 -0
  1618. package/upgrades/0.24.25.md +15 -0
  1619. package/upgrades/0.24.26.md +15 -0
  1620. package/upgrades/0.24.27.md +17 -0
  1621. package/upgrades/0.24.28.md +35 -0
  1622. package/upgrades/0.24.29.md +15 -0
  1623. package/upgrades/0.24.30.md +40 -0
  1624. package/upgrades/0.24.31.md +45 -0
  1625. package/upgrades/0.24.32.md +19 -0
  1626. package/upgrades/0.24.33.md +35 -0
  1627. package/upgrades/0.24.34.md +29 -0
  1628. package/upgrades/0.24.4.md +19 -0
  1629. package/upgrades/0.24.5.md +20 -0
  1630. package/upgrades/0.25.0.md +34 -0
  1631. package/upgrades/0.25.1.md +24 -0
  1632. package/upgrades/0.25.10.md +26 -0
  1633. package/upgrades/0.25.2.md +23 -0
  1634. package/upgrades/0.25.3.md +25 -0
  1635. package/upgrades/0.25.4.md +24 -0
  1636. package/upgrades/0.25.5.md +19 -0
  1637. package/upgrades/0.25.6.md +35 -0
  1638. package/upgrades/0.25.7.md +18 -0
  1639. package/upgrades/0.25.8.md +24 -0
  1640. package/upgrades/0.25.9.md +19 -0
  1641. package/upgrades/0.26.0.md +23 -0
  1642. package/upgrades/0.26.1.md +22 -0
  1643. package/upgrades/0.26.2.md +15 -0
  1644. package/upgrades/0.8.12.md +49 -0
  1645. package/upgrades/0.8.13.md +38 -0
  1646. package/upgrades/0.8.17.md +36 -0
  1647. package/upgrades/0.8.22.md +43 -0
  1648. package/upgrades/0.8.23.md +106 -0
  1649. package/upgrades/0.9.1.md +91 -0
  1650. package/upgrades/0.9.10.md +40 -0
  1651. package/upgrades/0.9.11.md +77 -0
  1652. package/upgrades/0.9.12.md +42 -0
  1653. package/upgrades/0.9.13.md +55 -0
  1654. package/upgrades/0.9.14.md +23 -0
  1655. package/upgrades/0.9.15.md +106 -0
  1656. package/upgrades/0.9.16.md +37 -0
  1657. package/upgrades/0.9.17.md +15 -0
  1658. package/upgrades/0.9.19.md +17 -0
  1659. package/upgrades/0.9.20.md +24 -0
  1660. package/upgrades/0.9.21.md +37 -0
  1661. package/upgrades/0.9.22.md +41 -0
  1662. package/upgrades/0.9.23.md +37 -0
  1663. package/upgrades/0.9.24.md +46 -0
  1664. package/upgrades/0.9.25.md +37 -0
  1665. package/upgrades/0.9.28.md +20 -0
  1666. package/upgrades/0.9.29.md +34 -0
  1667. package/upgrades/0.9.32.md +30 -0
  1668. package/upgrades/0.9.36.md +27 -0
  1669. package/upgrades/0.9.8.md +125 -0
  1670. package/upgrades/0.9.9.md +34 -0
  1671. package/upgrades/NEXT.md +35 -0
@@ -0,0 +1,3674 @@
1
+ /**
2
+ * Post-Update Migrator — the "intelligence download" layer.
3
+ *
4
+ * When an agent installs a new version of instar, updating the npm
5
+ * package only changes the server code. But the agent's local awareness
6
+ * lives in project files: CLAUDE.md, hooks, scripts.
7
+ *
8
+ * This migrator bridges that gap. After every successful update, it:
9
+ * 1. Re-installs hooks with the latest templates (behavioral upgrades)
10
+ * 2. Patches CLAUDE.md with any new sections (awareness upgrades)
11
+ * 3. Installs any new scripts (capability upgrades)
12
+ * 4. Returns a human-readable migration report
13
+ *
14
+ * Design principles:
15
+ * - Additive only: never remove or modify existing user customizations
16
+ * - Hooks are overwritten (they're generated infrastructure, not user-edited)
17
+ * - CLAUDE.md sections are appended only if missing (check by heading)
18
+ * - Scripts are installed only if missing (never overwrite user modifications)
19
+ */
20
+ import fs from 'node:fs';
21
+ import path from 'node:path';
22
+ import { TreeGenerator } from '../knowledge/TreeGenerator.js';
23
+ import { HTTP_HOOK_TEMPLATES, buildHttpHookSettings } from '../data/http-hook-templates.js';
24
+ import { getMigrationDefaults, applyDefaults } from '../config/ConfigDefaults.js';
25
+ export class PostUpdateMigrator {
26
+ config;
27
+ constructor(config) {
28
+ this.config = config;
29
+ }
30
+ /**
31
+ * Run all post-update migrations. Safe to call multiple times —
32
+ * each migration is idempotent.
33
+ */
34
+ migrate() {
35
+ const result = {
36
+ upgraded: [],
37
+ skipped: [],
38
+ errors: [],
39
+ };
40
+ this.migrateHooks(result);
41
+ this.migrateClaudeMd(result);
42
+ this.migrateScripts(result);
43
+ this.migrateSettings(result);
44
+ this.migrateConfig(result);
45
+ this.migrateGitignore(result);
46
+ this.migrateSelfKnowledgeTree(result);
47
+ this.migrateSoulMd(result);
48
+ this.migrateAgentMdSections(result);
49
+ return result;
50
+ }
51
+ /**
52
+ * Re-install hooks with the latest templates.
53
+ * Built-in hooks in instar/ are always overwritten.
54
+ * Custom hooks in custom/ are never touched.
55
+ */
56
+ migrateHooks(result) {
57
+ const hooksDir = path.join(this.config.stateDir, 'hooks');
58
+ const instarHooksDir = path.join(hooksDir, 'instar');
59
+ const customHooksDir = path.join(hooksDir, 'custom');
60
+ fs.mkdirSync(instarHooksDir, { recursive: true });
61
+ fs.mkdirSync(customHooksDir, { recursive: true });
62
+ // Migrate from flat layout to directory layout if needed
63
+ this.migrateHookLayout(hooksDir, instarHooksDir, result);
64
+ try {
65
+ // Session start hook — the most important one for self-discovery
66
+ fs.writeFileSync(path.join(instarHooksDir, 'session-start.sh'), this.getSessionStartHook(), { mode: 0o755 });
67
+ result.upgraded.push('hooks/instar/session-start.sh (capability awareness)');
68
+ }
69
+ catch (err) {
70
+ result.errors.push(`session-start.sh: ${err instanceof Error ? err.message : String(err)}`);
71
+ }
72
+ try {
73
+ fs.writeFileSync(path.join(instarHooksDir, 'dangerous-command-guard.sh'), this.getDangerousCommandGuard(), { mode: 0o755 });
74
+ result.upgraded.push('hooks/instar/dangerous-command-guard.sh');
75
+ }
76
+ catch (err) {
77
+ result.errors.push(`dangerous-command-guard.sh: ${err instanceof Error ? err.message : String(err)}`);
78
+ }
79
+ try {
80
+ fs.writeFileSync(path.join(instarHooksDir, 'grounding-before-messaging.sh'), this.getGroundingBeforeMessaging(), { mode: 0o755 });
81
+ result.upgraded.push('hooks/instar/grounding-before-messaging.sh');
82
+ }
83
+ catch (err) {
84
+ result.errors.push(`grounding-before-messaging.sh: ${err instanceof Error ? err.message : String(err)}`);
85
+ }
86
+ try {
87
+ fs.writeFileSync(path.join(instarHooksDir, 'compaction-recovery.sh'), this.getCompactionRecovery(), { mode: 0o755 });
88
+ result.upgraded.push('hooks/instar/compaction-recovery.sh');
89
+ }
90
+ catch (err) {
91
+ result.errors.push(`compaction-recovery.sh: ${err instanceof Error ? err.message : String(err)}`);
92
+ }
93
+ try {
94
+ fs.writeFileSync(path.join(instarHooksDir, 'telegram-topic-context.sh'), this.getTelegramTopicContextHook(), { mode: 0o755 });
95
+ result.upgraded.push('hooks/instar/telegram-topic-context.sh (per-message unanswered detection)');
96
+ }
97
+ catch (err) {
98
+ result.errors.push(`telegram-topic-context.sh: ${err instanceof Error ? err.message : String(err)}`);
99
+ }
100
+ try {
101
+ fs.writeFileSync(path.join(instarHooksDir, 'external-operation-gate.js'), this.getExternalOperationGateHook(), { mode: 0o755 });
102
+ result.upgraded.push('hooks/instar/external-operation-gate.js (MCP tool safety gate)');
103
+ }
104
+ catch (err) {
105
+ result.errors.push(`external-operation-gate.js: ${err instanceof Error ? err.message : String(err)}`);
106
+ }
107
+ try {
108
+ fs.writeFileSync(path.join(instarHooksDir, 'deferral-detector.js'), this.getDeferralDetectorHook(), { mode: 0o755 });
109
+ result.upgraded.push('hooks/instar/deferral-detector.js (anti-deferral checklist)');
110
+ }
111
+ catch (err) {
112
+ result.errors.push(`deferral-detector.js: ${err instanceof Error ? err.message : String(err)}`);
113
+ }
114
+ try {
115
+ fs.writeFileSync(path.join(instarHooksDir, 'post-action-reflection.js'), this.getPostActionReflectionHook(), { mode: 0o755 });
116
+ result.upgraded.push('hooks/instar/post-action-reflection.js (evolution awareness)');
117
+ }
118
+ catch (err) {
119
+ result.errors.push(`post-action-reflection.js: ${err instanceof Error ? err.message : String(err)}`);
120
+ }
121
+ try {
122
+ fs.writeFileSync(path.join(instarHooksDir, 'external-communication-guard.js'), this.getExternalCommunicationGuardHook(), { mode: 0o755 });
123
+ result.upgraded.push('hooks/instar/external-communication-guard.js (identity grounding)');
124
+ }
125
+ catch (err) {
126
+ result.errors.push(`external-communication-guard.js: ${err instanceof Error ? err.message : String(err)}`);
127
+ }
128
+ try {
129
+ fs.writeFileSync(path.join(instarHooksDir, 'scope-coherence-collector.js'), this.getScopeCoherenceCollectorHook(), { mode: 0o755 });
130
+ result.upgraded.push('hooks/instar/scope-coherence-collector.js (implementation depth tracking)');
131
+ }
132
+ catch (err) {
133
+ result.errors.push(`scope-coherence-collector.js: ${err instanceof Error ? err.message : String(err)}`);
134
+ }
135
+ try {
136
+ fs.writeFileSync(path.join(instarHooksDir, 'scope-coherence-checkpoint.js'), this.getScopeCoherenceCheckpointHook(), { mode: 0o755 });
137
+ result.upgraded.push('hooks/instar/scope-coherence-checkpoint.js (scope zoom-out checkpoint)');
138
+ }
139
+ catch (err) {
140
+ result.errors.push(`scope-coherence-checkpoint.js: ${err instanceof Error ? err.message : String(err)}`);
141
+ }
142
+ try {
143
+ fs.writeFileSync(path.join(instarHooksDir, 'free-text-guard.sh'), this.getFreeTextGuardHook(), { mode: 0o755 });
144
+ result.upgraded.push('hooks/instar/free-text-guard.sh (blocks AskUserQuestion for passwords/credentials)');
145
+ }
146
+ catch (err) {
147
+ result.errors.push(`free-text-guard.sh: ${err instanceof Error ? err.message : String(err)}`);
148
+ }
149
+ try {
150
+ fs.writeFileSync(path.join(instarHooksDir, 'claim-intercept.js'), this.getClaimInterceptHook(), { mode: 0o755 });
151
+ result.upgraded.push('hooks/instar/claim-intercept.js (false claim detection on tool output)');
152
+ }
153
+ catch (err) {
154
+ result.errors.push(`claim-intercept.js: ${err instanceof Error ? err.message : String(err)}`);
155
+ }
156
+ try {
157
+ fs.writeFileSync(path.join(instarHooksDir, 'claim-intercept-response.js'), this.getClaimInterceptResponseHook(), { mode: 0o755 });
158
+ result.upgraded.push('hooks/instar/claim-intercept-response.js (false claim detection on responses)');
159
+ }
160
+ catch (err) {
161
+ result.errors.push(`claim-intercept-response.js: ${err instanceof Error ? err.message : String(err)}`);
162
+ }
163
+ try {
164
+ fs.writeFileSync(path.join(instarHooksDir, 'response-review.js'), this.getResponseReviewHook(), { mode: 0o755 });
165
+ result.upgraded.push('hooks/instar/response-review.js (coherence gate response review pipeline)');
166
+ }
167
+ catch (err) {
168
+ result.errors.push(`response-review.js: ${err instanceof Error ? err.message : String(err)}`);
169
+ }
170
+ try {
171
+ fs.writeFileSync(path.join(instarHooksDir, 'auto-approve-permissions.js'), this.getAutoApprovePermissionsHook(), { mode: 0o755 });
172
+ result.upgraded.push('hooks/instar/auto-approve-permissions.js (subagent permission unblocking)');
173
+ }
174
+ catch (err) {
175
+ result.errors.push(`auto-approve-permissions.js: ${err instanceof Error ? err.message : String(err)}`);
176
+ }
177
+ }
178
+ /**
179
+ * Migrate hooks from flat .instar/hooks/ layout to .instar/hooks/instar/ subdirectory.
180
+ * Detects agent-modified built-in hooks by comparing content hashes and moves them
181
+ * to .instar/hooks/custom/ with provenance 'inherited'.
182
+ */
183
+ migrateHookLayout(hooksDir, instarHooksDir, result) {
184
+ // List of known built-in hook filenames
185
+ const builtinHooks = [
186
+ 'session-start.sh', 'dangerous-command-guard.sh', 'grounding-before-messaging.sh',
187
+ 'compaction-recovery.sh', 'external-operation-gate.js', 'deferral-detector.js',
188
+ 'post-action-reflection.js', 'external-communication-guard.js',
189
+ 'scope-coherence-collector.js', 'scope-coherence-checkpoint.js',
190
+ 'instructions-loaded-tracker.js', 'subagent-start-tracker.js',
191
+ 'free-text-guard.sh', 'claim-intercept.js', 'claim-intercept-response.js', 'response-review.js',
192
+ 'auto-approve-permissions.js',
193
+ ];
194
+ // Check if we're still on the old flat layout (hooks directly in .instar/hooks/)
195
+ const hasOldLayout = builtinHooks.some(name => {
196
+ const oldPath = path.join(hooksDir, name);
197
+ return fs.existsSync(oldPath) && !fs.statSync(oldPath).isDirectory();
198
+ });
199
+ if (!hasOldLayout)
200
+ return;
201
+ // Already migrated or fresh install — instar/ dir has the hooks
202
+ if (fs.existsSync(path.join(instarHooksDir, 'session-start.sh')))
203
+ return;
204
+ const customHooksDir = path.join(hooksDir, 'custom');
205
+ for (const hookName of builtinHooks) {
206
+ const oldPath = path.join(hooksDir, hookName);
207
+ if (!fs.existsSync(oldPath))
208
+ continue;
209
+ try {
210
+ // Move built-in hooks to instar/ — they'll be overwritten by the current
211
+ // migrateHooks() call anyway, but cleaning up the old location is important
212
+ fs.unlinkSync(oldPath);
213
+ }
214
+ catch {
215
+ // If we can't remove, it's not critical — the new hooks will be written
216
+ // to instar/ regardless
217
+ }
218
+ }
219
+ // Check for any non-builtin hooks in the old flat directory (agent-created)
220
+ try {
221
+ const remaining = fs.readdirSync(hooksDir).filter(name => {
222
+ const fullPath = path.join(hooksDir, name);
223
+ return !fs.statSync(fullPath).isDirectory() && !builtinHooks.includes(name);
224
+ });
225
+ for (const customHook of remaining) {
226
+ const oldPath = path.join(hooksDir, customHook);
227
+ const newPath = path.join(customHooksDir, customHook);
228
+ try {
229
+ fs.renameSync(oldPath, newPath);
230
+ result.upgraded.push(`hooks: migrated custom hook ${customHook} to hooks/custom/`);
231
+ }
232
+ catch (err) {
233
+ result.errors.push(`hook migration ${customHook}: ${err instanceof Error ? err.message : String(err)}`);
234
+ }
235
+ }
236
+ }
237
+ catch {
238
+ // Directory read failed — not critical
239
+ }
240
+ result.upgraded.push('hooks: migrated from flat layout to instar/custom/ directory structure');
241
+ }
242
+ /**
243
+ * Migrate settings.json hook command paths from .instar/hooks/X to .instar/hooks/instar/X.
244
+ * This handles the transition for agents that already have hooks configured.
245
+ */
246
+ migrateSettingsHookPaths(hookEntries, result) {
247
+ const oldPrefix = '.instar/hooks/';
248
+ const newPrefix = '.instar/hooks/instar/';
249
+ for (const entry of hookEntries) {
250
+ if (typeof entry !== 'object' || entry === null)
251
+ continue;
252
+ // Handle entries with nested hooks arrays (matcher-based entries)
253
+ const entryObj = entry;
254
+ if (Array.isArray(entryObj.hooks)) {
255
+ for (const hook of entryObj.hooks) {
256
+ if (typeof hook === 'object' && hook !== null) {
257
+ const hookObj = hook;
258
+ if (typeof hookObj.command === 'string') {
259
+ const cmd = hookObj.command;
260
+ // Only migrate paths that point to flat layout (not already in instar/ or custom/)
261
+ if (cmd.includes(oldPrefix) && !cmd.includes(newPrefix) && !cmd.includes('.instar/hooks/custom/')) {
262
+ hookObj.command = cmd.replace(oldPrefix, newPrefix);
263
+ }
264
+ }
265
+ }
266
+ }
267
+ }
268
+ // Handle direct hook entries (not nested)
269
+ if (typeof entryObj.command === 'string') {
270
+ const cmd = entryObj.command;
271
+ if (cmd.includes(oldPrefix) && !cmd.includes(newPrefix) && !cmd.includes('.instar/hooks/custom/')) {
272
+ entryObj.command = cmd.replace(oldPrefix, newPrefix);
273
+ }
274
+ }
275
+ }
276
+ }
277
+ /**
278
+ * Migrate HTTP hook URLs to include INSTAR_SESSION_ID query parameter.
279
+ * This enables the server to map Claude Code's session_id to the instar session,
280
+ * which is required for subagent-aware zombie cleanup (prevents killing sessions
281
+ * that are waiting for subagent results).
282
+ *
283
+ * Finds HTTP hooks with URLs ending in /hooks/events (no query params) and
284
+ * appends ?instar_sid=${INSTAR_SESSION_ID}. Also adds INSTAR_SESSION_ID to
285
+ * allowedEnvVars if missing.
286
+ */
287
+ migrateHttpHookSessionId(hooks, result) {
288
+ let patched = false;
289
+ for (const hookEntries of Object.values(hooks)) {
290
+ if (!Array.isArray(hookEntries))
291
+ continue;
292
+ for (const entry of hookEntries) {
293
+ if (typeof entry !== 'object' || entry === null)
294
+ continue;
295
+ const entryObj = entry;
296
+ // Handle entries with nested hooks arrays (matcher-based entries)
297
+ if (Array.isArray(entryObj.hooks)) {
298
+ for (const hook of entryObj.hooks) {
299
+ if (typeof hook !== 'object' || hook === null)
300
+ continue;
301
+ const hookObj = hook;
302
+ if (hookObj.type !== 'http' || typeof hookObj.url !== 'string')
303
+ continue;
304
+ // Update URL: add ?instar_sid= if the URL hits /hooks/events without it
305
+ if (hookObj.url.includes('/hooks/events') && !hookObj.url.includes('instar_sid')) {
306
+ hookObj.url = hookObj.url.replace('/hooks/events', '/hooks/events?instar_sid=${INSTAR_SESSION_ID}');
307
+ patched = true;
308
+ }
309
+ // Add INSTAR_SESSION_ID to allowedEnvVars if missing
310
+ if (Array.isArray(hookObj.allowedEnvVars)) {
311
+ const envVars = hookObj.allowedEnvVars;
312
+ if (!envVars.includes('INSTAR_SESSION_ID')) {
313
+ envVars.push('INSTAR_SESSION_ID');
314
+ patched = true;
315
+ }
316
+ }
317
+ }
318
+ }
319
+ // Handle direct hook entries (not nested)
320
+ if (entryObj.type === 'http' && typeof entryObj.url === 'string') {
321
+ if (entryObj.url.includes('/hooks/events') && !entryObj.url.includes('instar_sid')) {
322
+ entryObj.url = entryObj.url.replace('/hooks/events', '/hooks/events?instar_sid=${INSTAR_SESSION_ID}');
323
+ patched = true;
324
+ }
325
+ if (Array.isArray(entryObj.allowedEnvVars)) {
326
+ const envVars = entryObj.allowedEnvVars;
327
+ if (!envVars.includes('INSTAR_SESSION_ID')) {
328
+ envVars.push('INSTAR_SESSION_ID');
329
+ patched = true;
330
+ }
331
+ }
332
+ }
333
+ }
334
+ }
335
+ if (patched) {
336
+ result.upgraded.push('.claude/settings.json: added INSTAR_SESSION_ID to HTTP hook URLs (subagent-aware zombie cleanup)');
337
+ }
338
+ return patched;
339
+ }
340
+ /**
341
+ * Ensure HTTP hooks from the template exist in settings.json.
342
+ * Previous migrations only patched existing HTTP hooks (adding instar_sid param)
343
+ * but never added them from scratch. Agents initialized before HTTP hooks were
344
+ * introduced have no HTTP hooks at all, causing claudeSessionId to never be
345
+ * populated — which breaks session resume (falls back to mtime cross-contamination).
346
+ */
347
+ ensureHttpHooksExist(hooks, result) {
348
+ const serverUrl = `http://localhost:${this.config.port}`;
349
+ // Check if ANY event reporter hook already exists (HTTP or command-based)
350
+ const hasEventReporterHook = Object.values(hooks).some(entries => {
351
+ if (!Array.isArray(entries))
352
+ return false;
353
+ return entries.some(entry => {
354
+ if (typeof entry !== 'object' || entry === null)
355
+ return false;
356
+ const e = entry;
357
+ if (Array.isArray(e.hooks)) {
358
+ return e.hooks.some(h => {
359
+ // Check for command hook (new style)
360
+ if (h.type === 'command' && typeof h.command === 'string' && h.command.includes('hook-event-reporter'))
361
+ return true;
362
+ // Check for HTTP hook (old style, with valid URL)
363
+ if (h.type === 'http' && typeof h.url === 'string' && !h.url.includes('${INSTAR_SERVER_URL}'))
364
+ return true;
365
+ return false;
366
+ });
367
+ }
368
+ // Check direct entry
369
+ if (e.type === 'command' && typeof e.command === 'string' && e.command.includes('hook-event-reporter'))
370
+ return true;
371
+ if (e.type === 'http' && typeof e.url === 'string' && !e.url.includes('${INSTAR_SERVER_URL}'))
372
+ return true;
373
+ return false;
374
+ });
375
+ });
376
+ if (hasEventReporterHook)
377
+ return false;
378
+ // Remove any existing broken HTTP hooks (with unresolved template vars)
379
+ for (const [event, entries] of Object.entries(hooks)) {
380
+ if (!Array.isArray(entries))
381
+ continue;
382
+ hooks[event] = entries.filter(entry => {
383
+ if (typeof entry !== 'object' || entry === null)
384
+ return true;
385
+ const e = entry;
386
+ if (Array.isArray(e.hooks)) {
387
+ const hooksArr = e.hooks;
388
+ return !hooksArr.some(h => h.type === 'http' && typeof h.url === 'string' && h.url.includes('${INSTAR_SERVER_URL}'));
389
+ }
390
+ return !(e.type === 'http' && typeof e.url === 'string' && e.url.includes('${INSTAR_SERVER_URL}'));
391
+ });
392
+ // Clean up empty arrays
393
+ if (hooks[event].length === 0) {
394
+ delete hooks[event];
395
+ }
396
+ }
397
+ // Add HTTP hooks using the resolved localhost URL
398
+ const httpHookSettings = buildHttpHookSettings(serverUrl);
399
+ for (const [event, entries] of Object.entries(httpHookSettings)) {
400
+ if (!hooks[event]) {
401
+ hooks[event] = [];
402
+ }
403
+ hooks[event].push(...entries);
404
+ }
405
+ result.upgraded.push(`.claude/settings.json: added ${HTTP_HOOK_TEMPLATES.length} HTTP hooks for observability (url: ${serverUrl}/hooks/events)`);
406
+ return true;
407
+ }
408
+ /**
409
+ * Ensure PermissionRequest auto-approve hook exists in settings.json.
410
+ * Subagents spawned via the Agent tool don't inherit --dangerously-skip-permissions,
411
+ * so without this catch-all hook they prompt for every tool use and block jobs.
412
+ * Real safety is in PreToolUse hooks — permission prompts are duplicative friction.
413
+ */
414
+ ensurePermissionAutoApprove(hooks, result) {
415
+ // Check if PermissionRequest hook already exists
416
+ if (hooks.PermissionRequest) {
417
+ const entries = hooks.PermissionRequest;
418
+ const hasAutoApprove = entries.some(e => e.hooks?.some(h => h.command?.includes('auto-approve-permissions')));
419
+ if (hasAutoApprove)
420
+ return false;
421
+ }
422
+ if (!hooks.PermissionRequest) {
423
+ hooks.PermissionRequest = [];
424
+ }
425
+ hooks.PermissionRequest.push({
426
+ matcher: '',
427
+ hooks: [{
428
+ type: 'command',
429
+ command: 'node .instar/hooks/instar/auto-approve-permissions.js',
430
+ timeout: 5000,
431
+ }],
432
+ });
433
+ result.upgraded.push('.claude/settings.json: added PermissionRequest auto-approve (subagent unblocking)');
434
+ return true;
435
+ }
436
+ /**
437
+ * Ensure autonomous stop hook is registered and the skill files are deployed.
438
+ * This is the structural enforcement for /autonomous mode — without it,
439
+ * sessions exit normally after each response instead of looping on the task list.
440
+ */
441
+ ensureAutonomousStopHook(hooks, result) {
442
+ let patched = false;
443
+ // 1. Deploy full autonomous skill directory (skill.md, hooks/, scripts/) if missing
444
+ const skillDir = path.join(this.config.projectDir, '.claude', 'skills', 'autonomous');
445
+ const skillHooksDir = path.join(skillDir, 'hooks');
446
+ const hookScript = path.join(skillHooksDir, 'autonomous-stop-hook.sh');
447
+ const hooksJson = path.join(skillHooksDir, 'hooks.json');
448
+ const skillMd = path.join(skillDir, 'skill.md');
449
+ const bundledSkillDir = path.join(path.dirname(path.dirname(__dirname)), '.claude', 'skills', 'autonomous');
450
+ if (fs.existsSync(bundledSkillDir)) {
451
+ // Deploy skill.md if missing
452
+ const bundledSkillMd = path.join(bundledSkillDir, 'skill.md');
453
+ if (!fs.existsSync(skillMd) && fs.existsSync(bundledSkillMd)) {
454
+ fs.mkdirSync(skillDir, { recursive: true });
455
+ fs.copyFileSync(bundledSkillMd, skillMd);
456
+ result.upgraded.push('.claude/skills/autonomous/skill.md: deployed skill prompt');
457
+ patched = true;
458
+ }
459
+ // Deploy scripts/ if missing
460
+ const bundledScriptsDir = path.join(bundledSkillDir, 'scripts');
461
+ const skillScriptsDir = path.join(skillDir, 'scripts');
462
+ if (!fs.existsSync(skillScriptsDir) && fs.existsSync(bundledScriptsDir)) {
463
+ fs.mkdirSync(skillScriptsDir, { recursive: true });
464
+ for (const f of fs.readdirSync(bundledScriptsDir)) {
465
+ fs.copyFileSync(path.join(bundledScriptsDir, f), path.join(skillScriptsDir, f));
466
+ fs.chmodSync(path.join(skillScriptsDir, f), 0o755);
467
+ }
468
+ result.upgraded.push('.claude/skills/autonomous/scripts: deployed skill scripts');
469
+ patched = true;
470
+ }
471
+ // Deploy hooks/ if missing
472
+ if (!fs.existsSync(hookScript)) {
473
+ fs.mkdirSync(skillHooksDir, { recursive: true });
474
+ const bundledHook = path.join(bundledSkillDir, 'hooks', 'autonomous-stop-hook.sh');
475
+ const bundledJson = path.join(bundledSkillDir, 'hooks', 'hooks.json');
476
+ if (fs.existsSync(bundledHook)) {
477
+ fs.copyFileSync(bundledHook, hookScript);
478
+ fs.chmodSync(hookScript, 0o755);
479
+ }
480
+ if (fs.existsSync(bundledJson) && !fs.existsSync(hooksJson)) {
481
+ fs.copyFileSync(bundledJson, hooksJson);
482
+ }
483
+ result.upgraded.push('.claude/skills/autonomous/hooks: deployed stop hook files');
484
+ patched = true;
485
+ }
486
+ // Force-update autonomous skill files that reference old .claude/ state path.
487
+ // The state file was moved from .claude/autonomous-state.local.md to
488
+ // .instar/autonomous-state.local.md because Claude Code's settings
489
+ // self-modification prompt blocks writes to .claude/ even with
490
+ // --dangerously-skip-permissions. Also adds UUID validation for session_id.
491
+ const filesToUpdate = [
492
+ { src: 'hooks/autonomous-stop-hook.sh', dst: hookScript, executable: true },
493
+ { src: 'scripts/setup-autonomous.sh', dst: path.join(skillDir, 'scripts', 'setup-autonomous.sh'), executable: true },
494
+ { src: 'skill.md', dst: skillMd, executable: false },
495
+ ];
496
+ for (const { src, dst, executable } of filesToUpdate) {
497
+ if (fs.existsSync(dst)) {
498
+ const content = fs.readFileSync(dst, 'utf-8');
499
+ if (content.includes('.claude/autonomous-state') || content.includes('.claude/autonomous-emergency-stop')) {
500
+ const bundledSrc = path.join(bundledSkillDir, src);
501
+ if (fs.existsSync(bundledSrc)) {
502
+ fs.copyFileSync(bundledSrc, dst);
503
+ if (executable)
504
+ fs.chmodSync(dst, 0o755);
505
+ result.upgraded.push(`${dst}: migrated autonomous state path from .claude/ to .instar/`);
506
+ patched = true;
507
+ }
508
+ }
509
+ }
510
+ }
511
+ }
512
+ // 2. Register in settings.json Stop hooks if missing
513
+ if (!hooks.Stop) {
514
+ hooks.Stop = [];
515
+ }
516
+ const stopEntries = hooks.Stop;
517
+ const hasAutonomousHook = stopEntries.some(e => e.hooks?.some(h => h.command?.includes('autonomous-stop-hook')));
518
+ if (!hasAutonomousHook) {
519
+ // Must be first in the Stop chain so it blocks before other hooks run
520
+ hooks.Stop.unshift({
521
+ matcher: '',
522
+ hooks: [{
523
+ type: 'command',
524
+ command: 'bash .claude/skills/autonomous/hooks/autonomous-stop-hook.sh',
525
+ timeout: 10000,
526
+ }],
527
+ });
528
+ result.upgraded.push('.claude/settings.json: registered autonomous stop hook (structural enforcement)');
529
+ patched = true;
530
+ }
531
+ return patched;
532
+ }
533
+ /**
534
+ * Replace HTTP hooks with command hooks that use hook-event-reporter.js.
535
+ * Claude Code HTTP hooks (type: "http") silently fail to fire as of v2.1.78.
536
+ * This migration converts them to command hooks which reliably fire.
537
+ * Also installs the hook-event-reporter.js script if missing.
538
+ */
539
+ migrateHttpHooksToCommandHooks(hooks, result) {
540
+ let patched = false;
541
+ const commandHook = {
542
+ type: 'command',
543
+ command: 'node .instar/hooks/instar/hook-event-reporter.js',
544
+ timeout: 3000,
545
+ };
546
+ for (const [event, entries] of Object.entries(hooks)) {
547
+ if (!Array.isArray(entries))
548
+ continue;
549
+ for (let i = entries.length - 1; i >= 0; i--) {
550
+ const entry = entries[i];
551
+ if (typeof entry !== 'object' || entry === null)
552
+ continue;
553
+ const entryObj = entry;
554
+ // Check nested hooks arrays for HTTP hooks
555
+ if (Array.isArray(entryObj.hooks)) {
556
+ const hooksArr = entryObj.hooks;
557
+ const hasHttpHook = hooksArr.some(h => h.type === 'http' && typeof h.url === 'string' && h.url.includes('/hooks/events'));
558
+ if (hasHttpHook) {
559
+ // Replace the entire entry with a command hook entry
560
+ entries[i] = {
561
+ matcher: entryObj.matcher ?? '',
562
+ hooks: [commandHook],
563
+ };
564
+ patched = true;
565
+ }
566
+ }
567
+ // Check direct HTTP hook entries
568
+ if (entryObj.type === 'http' && typeof entryObj.url === 'string' && entryObj.url.includes('/hooks/events')) {
569
+ entries[i] = {
570
+ matcher: '',
571
+ hooks: [commandHook],
572
+ };
573
+ patched = true;
574
+ }
575
+ }
576
+ }
577
+ // Install the hook-event-reporter.js script if it doesn't exist
578
+ const hooksDir = path.join(this.config.stateDir, 'hooks', 'instar');
579
+ const reporterPath = path.join(hooksDir, 'hook-event-reporter.js');
580
+ if (!fs.existsSync(reporterPath)) {
581
+ try {
582
+ fs.mkdirSync(hooksDir, { recursive: true });
583
+ // Import the script content inline to avoid circular dependency
584
+ const script = this.getHookEventReporterScript();
585
+ fs.writeFileSync(reporterPath, script, { mode: 0o755 });
586
+ if (!patched) {
587
+ result.upgraded.push('.instar/hooks/instar/hook-event-reporter.js installed');
588
+ }
589
+ }
590
+ catch (err) {
591
+ result.errors.push(`hook-event-reporter.js install: ${err instanceof Error ? err.message : String(err)}`);
592
+ }
593
+ }
594
+ if (patched) {
595
+ result.upgraded.push('.claude/settings.json: replaced HTTP hooks with command hooks (HTTP hooks silently fail in Claude Code <=2.1.78)');
596
+ }
597
+ return patched;
598
+ }
599
+ getHookEventReporterScript() {
600
+ return `#!/usr/bin/env node
601
+ // Hook Event Reporter — command hook replacement for HTTP hooks.
602
+ //
603
+ // Claude Code HTTP hooks (type: "http") silently fail to fire as of v2.1.78.
604
+ // This command hook achieves the same result: POST hook event data to the
605
+ // Instar server, which populates claudeSessionId for session resumption.
606
+
607
+ const http = require('http');
608
+
609
+ const serverUrl = process.env.INSTAR_SERVER_URL || 'http://localhost:4042';
610
+ const authToken = process.env.INSTAR_AUTH_TOKEN || '';
611
+ const instarSid = process.env.INSTAR_SESSION_ID || '';
612
+
613
+ if (!authToken || !instarSid) {
614
+ process.exit(0);
615
+ }
616
+
617
+ let data = '';
618
+ process.stdin.on('data', chunk => data += chunk);
619
+ process.stdin.on('end', () => {
620
+ try {
621
+ const input = JSON.parse(data);
622
+ const payload = JSON.stringify({
623
+ event: input.hook_event || (input.tool_name ? 'PostToolUse' : 'Unknown'),
624
+ session_id: input.session_id || '',
625
+ tool_name: input.tool_name || '',
626
+ });
627
+
628
+ const url = new URL(serverUrl + '/hooks/events?instar_sid=' + instarSid);
629
+ const req = http.request({
630
+ hostname: url.hostname,
631
+ port: url.port,
632
+ path: url.pathname + url.search,
633
+ method: 'POST',
634
+ headers: {
635
+ 'Content-Type': 'application/json',
636
+ 'Authorization': 'Bearer ' + authToken,
637
+ },
638
+ timeout: 3000,
639
+ }, (res) => {
640
+ res.resume();
641
+ });
642
+
643
+ req.on('error', () => {});
644
+ req.write(payload);
645
+ req.end();
646
+
647
+ setTimeout(() => process.exit(0), 50);
648
+ } catch (e) {
649
+ process.exit(0);
650
+ }
651
+ });
652
+
653
+ setTimeout(() => process.exit(0), 2000);
654
+ `;
655
+ }
656
+ /**
657
+ * Patch CLAUDE.md with any new sections that don't exist yet.
658
+ * Only adds — never modifies or removes existing content.
659
+ */
660
+ migrateClaudeMd(result) {
661
+ const claudeMdPath = path.join(this.config.projectDir, 'CLAUDE.md');
662
+ if (!fs.existsSync(claudeMdPath)) {
663
+ result.skipped.push('CLAUDE.md (not found — will be created on next init)');
664
+ return;
665
+ }
666
+ let content;
667
+ try {
668
+ content = fs.readFileSync(claudeMdPath, 'utf-8');
669
+ }
670
+ catch (err) {
671
+ result.errors.push(`CLAUDE.md read: ${err instanceof Error ? err.message : String(err)}`);
672
+ return;
673
+ }
674
+ let patched = false;
675
+ const port = this.config.port;
676
+ // Self-Discovery section
677
+ if (!content.includes('Self-Discovery') && !content.includes('/capabilities')) {
678
+ const section = `
679
+ ### Self-Discovery (Know Before You Claim)
680
+
681
+ Before EVER saying "I don't have", "I can't", or "this isn't available" — check what actually exists:
682
+
683
+ \`\`\`bash
684
+ curl http://localhost:${port}/capabilities
685
+ \`\`\`
686
+
687
+ This returns your full capability matrix: scripts, hooks, Telegram status, jobs, relationships, and more. It is the source of truth about what you can do. **Never hallucinate about missing capabilities — verify first.**
688
+ `;
689
+ // Insert before "### How to Build" or "### Building New" if present, otherwise append
690
+ const insertPoint = content.indexOf('### How to Build New Capabilities');
691
+ const insertPoint2 = content.indexOf('### Building New Capabilities');
692
+ const target = insertPoint >= 0 ? insertPoint : (insertPoint2 >= 0 ? insertPoint2 : -1);
693
+ if (target >= 0) {
694
+ content = content.slice(0, target) + section + '\n' + content.slice(target);
695
+ }
696
+ else {
697
+ content += '\n' + section;
698
+ }
699
+ patched = true;
700
+ result.upgraded.push('CLAUDE.md: added Self-Discovery section');
701
+ }
702
+ else {
703
+ result.skipped.push('CLAUDE.md: Self-Discovery section already present');
704
+ }
705
+ // Telegram Relay section — add if Telegram is configured but section is missing
706
+ if (this.config.hasTelegram && !content.includes('Telegram Relay') && !content.includes('telegram-reply')) {
707
+ const section = `
708
+ ## Telegram Relay
709
+
710
+ When user input starts with \`[telegram:N]\` (e.g., \`[telegram:26] hello\`), the message came from a user via Telegram topic N.
711
+
712
+ **IMMEDIATE ACKNOWLEDGMENT (MANDATORY):** When you receive a Telegram message, your FIRST action — before reading files, searching code, or doing any work — must be sending a brief acknowledgment back. This confirms the message was received and you haven't stalled. Examples: "Got it, looking into this now." / "On it — checking the scheduler." / "Received, working on the sync." Then do the work, then send the full response.
713
+
714
+ **Message types:**
715
+ - **Text**: \`[telegram:26] hello there\` — standard text message
716
+ - **Voice**: \`[telegram:26] [voice] transcribed text here\` — voice message, already transcribed
717
+ - **Photo**: \`[telegram:26] [image:/path/to/file.jpg]\` or \`[telegram:26] [image:/path/to/file.jpg] caption text\` — use the Read tool to view the image at the given path
718
+ - **File**: \`[telegram:26] [document:/path/to/file.ext]\` — file uploaded by user, read it to view contents
719
+
720
+ **Response relay:** After completing your work, relay your response back:
721
+
722
+ \`\`\`bash
723
+ cat <<'EOF' | .claude/scripts/telegram-reply.sh N
724
+ Your response text here
725
+ EOF
726
+ \`\`\`
727
+
728
+ Strip the \`[telegram:N]\` prefix before interpreting the message. Respond naturally, then relay. Only relay your conversational text — not tool output or internal reasoning.
729
+ `;
730
+ content += '\n' + section;
731
+ patched = true;
732
+ result.upgraded.push('CLAUDE.md: added Telegram Relay section');
733
+ }
734
+ // Upgrade existing Telegram Relay sections to include mandatory acknowledgment
735
+ if (this.config.hasTelegram && content.includes('Telegram Relay') && !content.includes('IMMEDIATE ACKNOWLEDGMENT')) {
736
+ const ackBlock = `\n**IMMEDIATE ACKNOWLEDGMENT (MANDATORY):** When you receive a Telegram message, your FIRST action — before reading files, searching code, or doing any work — must be sending a brief acknowledgment back. This confirms the message was received and you haven't stalled. Examples: "Got it, looking into this now." / "On it — checking the scheduler." / "Received, working on the sync." Then do the work, then send the full response.\n`;
737
+ // Insert after the first line of the Telegram Relay section
738
+ const relayIdx = content.indexOf('## Telegram Relay');
739
+ if (relayIdx >= 0) {
740
+ const nextNewline = content.indexOf('\n\n', relayIdx + 18);
741
+ if (nextNewline >= 0) {
742
+ content = content.slice(0, nextNewline + 1) + ackBlock + content.slice(nextNewline + 1);
743
+ patched = true;
744
+ result.upgraded.push('CLAUDE.md: added mandatory acknowledgment to Telegram Relay');
745
+ }
746
+ }
747
+ }
748
+ // Upgrade existing Telegram Relay sections to document image message format
749
+ if (this.config.hasTelegram && content.includes('Telegram Relay') && !content.includes('[image:')) {
750
+ const imageBlock = `\n**Message types:**\n- **Text**: \`[telegram:N] hello there\` — standard text message\n- **Voice**: \`[telegram:N] [voice] transcribed text here\` — voice message, already transcribed\n- **Photo**: \`[telegram:N] [image:/path/to/file.jpg]\` or with caption — use the Read tool to view the image at the given path\n`;
751
+ // Insert before the Response relay section
752
+ const relayIdx = content.indexOf('**Response relay:**');
753
+ if (relayIdx >= 0) {
754
+ content = content.slice(0, relayIdx) + imageBlock + '\n' + content.slice(relayIdx);
755
+ patched = true;
756
+ result.upgraded.push('CLAUDE.md: added image/photo message format to Telegram Relay');
757
+ }
758
+ }
759
+ // Private Viewer + Tunnel section
760
+ if (!content.includes('Private Viewing') && !content.includes('POST /view')) {
761
+ const section = `
762
+ **Private Viewing** — Render markdown as auth-gated HTML pages, accessible only through the agent's server (local or via tunnel).
763
+ - Create: \`curl -X POST http://localhost:${port}/view -H 'Content-Type: application/json' -d '{"title":"Report","markdown":"# Private content"}'\`
764
+ - View (HTML): Open \`http://localhost:${port}/view/VIEW_ID\` in a browser
765
+ - List: \`curl http://localhost:${port}/views\`
766
+ - Update: \`curl -X PUT http://localhost:${port}/view/VIEW_ID -H 'Content-Type: application/json' -d '{"title":"Updated","markdown":"# New content"}'\`
767
+ - Delete: \`curl -X DELETE http://localhost:${port}/view/VIEW_ID\`
768
+
769
+ **Use private views for sensitive content. Use Telegraph for public content.**
770
+
771
+ **Cloudflare Tunnel** — Expose the local server to the internet via Cloudflare. Enables remote access to private views, the API, and file serving.
772
+ - Status: \`curl http://localhost:${port}/tunnel\`
773
+ - Configure in \`.instar/config.json\`: \`{"tunnel": {"enabled": true, "type": "quick"}}\`
774
+ - Quick tunnels (default): Zero-config, ephemeral URL (*.trycloudflare.com), no account needed
775
+ - Named tunnels: Persistent custom domain, requires token from Cloudflare dashboard
776
+ - When a tunnel is running, private view responses include a \`tunnelUrl\` with auth token for browser-clickable access
777
+ `;
778
+ // Insert after Publishing section or before Scripts section
779
+ const publishIdx = content.indexOf('**Scripts**');
780
+ if (publishIdx >= 0) {
781
+ content = content.slice(0, publishIdx) + section + '\n' + content.slice(publishIdx);
782
+ }
783
+ else {
784
+ content += '\n' + section;
785
+ }
786
+ patched = true;
787
+ result.upgraded.push('CLAUDE.md: added Private Viewer + Cloudflare Tunnel section');
788
+ }
789
+ else {
790
+ result.skipped.push('CLAUDE.md: Private Viewer section already present');
791
+ }
792
+ // Dashboard section
793
+ if (!content.includes('**Dashboard**') && !content.includes('/dashboard')) {
794
+ const section = `
795
+ **Dashboard** — Visual web interface for monitoring and managing sessions. Accessible from any device (phone, tablet, laptop) via tunnel.
796
+ - Local: \`http://localhost:${port}/dashboard\`
797
+ - Remote: When a tunnel is running, the dashboard is accessible at \`{tunnelUrl}/dashboard\`
798
+ - Authentication: Uses a 6-digit PIN (auto-generated in \`dashboardPin\` in \`.instar/config.json\`). NEVER mention "bearer tokens" or "auth tokens" to users — just give them the PIN.
799
+ - Features: Real-time terminal streaming of all running sessions, session management, model badges, mobile-responsive
800
+ - **Sharing the dashboard**: When the user wants to check on sessions from their phone, give them the tunnel URL + PIN. Read the PIN from your config.json. Check tunnel status: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/tunnel\`
801
+ `;
802
+ // Insert after Server Status or before Scripts section
803
+ const insertBefore = content.indexOf('**Scripts**');
804
+ if (insertBefore >= 0) {
805
+ content = content.slice(0, insertBefore) + section + '\n' + content.slice(insertBefore);
806
+ }
807
+ else {
808
+ content += '\n' + section;
809
+ }
810
+ patched = true;
811
+ result.upgraded.push('CLAUDE.md: added Dashboard section');
812
+ }
813
+ else {
814
+ result.skipped.push('CLAUDE.md: Dashboard section already present');
815
+ }
816
+ // Coherence Gate section — pre-action verification for high-risk actions
817
+ if (!content.includes('Coherence Gate') && !content.includes('/coherence/check')) {
818
+ const section = `
819
+ ### Coherence Gate (Pre-Action Verification)
820
+
821
+ **BEFORE any high-risk action** (deploying, pushing to git, modifying files outside this project, calling external APIs):
822
+
823
+ 1. **Check coherence**: \`curl -X POST http://localhost:${port}/coherence/check -H 'Content-Type: application/json' -d '{"action":"deploy","context":{"topicId":TOPIC_ID}}'\`
824
+ 2. **If result says "block"** — STOP. You may be working on the wrong project for this topic.
825
+ 3. **If result says "warn"** — Pause and verify before proceeding.
826
+ 4. **Generate a reflection prompt**: \`POST http://localhost:${port}/coherence/reflect\` — produces a self-verification checklist.
827
+
828
+ **Topic-Project Bindings**: Each Telegram topic can be bound to a specific project. When switching topics, verify the binding matches your current working directory.
829
+ - View bindings: \`GET http://localhost:${port}/topic-bindings\`
830
+ - Create binding: \`POST http://localhost:${port}/topic-bindings\` with \`{"topicId": N, "binding": {"projectName": "...", "projectDir": "..."}}\`
831
+
832
+ **Project Map**: Your spatial awareness of the working environment.
833
+ - View: \`GET http://localhost:${port}/project-map?format=compact\`
834
+ - Refresh: \`POST http://localhost:${port}/project-map/refresh\`
835
+ `;
836
+ // Insert before Scripts or append
837
+ const insertBefore = content.indexOf('**Scripts**');
838
+ if (insertBefore >= 0) {
839
+ content = content.slice(0, insertBefore) + section + '\n' + content.slice(insertBefore);
840
+ }
841
+ else {
842
+ content += '\n' + section;
843
+ }
844
+ patched = true;
845
+ result.upgraded.push('CLAUDE.md: added Coherence Gate section');
846
+ }
847
+ else {
848
+ result.skipped.push('CLAUDE.md: Coherence Gate section already present');
849
+ }
850
+ // External Operation Safety — structural guardrails for external service operations
851
+ if (!content.includes('External Operation Safety') && !content.includes('/operations/evaluate')) {
852
+ const section = `
853
+ ### External Operation Safety (Structural Guardrails)
854
+
855
+ **When using MCP tools that interact with external services** (email, Slack, GitHub, etc.), a PreToolUse hook automatically classifies and gates each operation.
856
+
857
+ How it works:
858
+ 1. The \`external-operation-gate.js\` hook intercepts all \`mcp__*\` tool calls
859
+ 2. It classifies the operation by mutability (read/write/modify/delete) and reversibility
860
+ 3. For non-read operations, it calls the gate API: \`POST http://localhost:${port}/operations/evaluate\`
861
+ 4. The gate returns: \`allow\`, \`block\`, \`show-plan\` (requires user approval), or \`suggest-alternative\`
862
+
863
+ **If an operation is blocked**, you'll see an error message with the reason. Do NOT try to bypass it.
864
+ **If an operation requires a plan**, show the plan to the user and get explicit approval before proceeding.
865
+
866
+ **Emergency stop**: If the user says "stop everything", "emergency stop", "kill all sessions", or similar urgent commands, the MessageSentinel will intercept the message and halt operations immediately.
867
+
868
+ **Trust levels**: Each service starts at a trust floor (supervised or collaborative). As operations succeed without issues, trust can be elevated automatically. Check trust status: \`GET http://localhost:${port}/trust\`
869
+
870
+ **API endpoints**:
871
+ - Evaluate operation: \`POST http://localhost:${port}/operations/evaluate\`
872
+ - Classify message: \`POST http://localhost:${port}/sentinel/classify\`
873
+ - View trust: \`GET http://localhost:${port}/trust\`
874
+ - View operation log: \`GET http://localhost:${port}/operations/log\`
875
+ `;
876
+ // Insert before Scripts or append
877
+ const insertBefore = content.indexOf('**Scripts**');
878
+ if (insertBefore >= 0) {
879
+ content = content.slice(0, insertBefore) + section + '\n' + content.slice(insertBefore);
880
+ }
881
+ else {
882
+ content += '\n' + section;
883
+ }
884
+ patched = true;
885
+ result.upgraded.push('CLAUDE.md: added External Operation Safety section');
886
+ }
887
+ else {
888
+ result.skipped.push('CLAUDE.md: External Operation Safety section already present');
889
+ }
890
+ // Playbook — adaptive context engineering system
891
+ if (!content.includes('Playbook') || !content.includes('instar playbook')) {
892
+ const section = `
893
+ ### Playbook — Adaptive Context Engineering
894
+
895
+ The Playbook system gives you a living knowledge base that makes every session smarter than the last. Instead of loading the same static context every time, Playbook curates a manifest of context items — facts, lessons, patterns, safety rules — and selects exactly what's relevant for each session based on triggers, token budgets, and usefulness scores.
896
+
897
+ **Getting started:**
898
+ \`\`\`bash
899
+ instar playbook init # Initialize the playbook system
900
+ instar playbook doctor # Verify everything is healthy
901
+ \`\`\`
902
+
903
+ **Core commands:**
904
+ - \`instar playbook status\` — Overview of your manifest
905
+ - \`instar playbook list\` — All context items with metadata
906
+ - \`instar playbook add '<json>'\` — Add a new context item
907
+ - \`instar playbook search --tag <tag>\` — Find items by tag
908
+ - \`instar playbook assemble --triggers session-start\` — Preview what would load for a trigger
909
+ - \`instar playbook evaluate\` — Run lifecycle: score usefulness, decay stale items, deduplicate
910
+
911
+ **When to add context items:** After learning a lesson that cost time, when discovering a recurring pattern, when safety-critical knowledge should survive compaction, or when the user teaches you something project-specific.
912
+
913
+ **The principle:** Your context should evolve with you. Every session that adds a lesson, scores an item's usefulness, or retires stale knowledge makes the next session more grounded. Run \`instar playbook init\` to get started.
914
+ `;
915
+ content += '\n' + section;
916
+ patched = true;
917
+ result.upgraded.push('CLAUDE.md: added Playbook section');
918
+ }
919
+ else {
920
+ result.skipped.push('CLAUDE.md: Playbook section already present');
921
+ }
922
+ // Threadline Network — agent-to-agent communication awareness
923
+ if (!content.includes('Threadline Network')) {
924
+ const section = `
925
+ ## Threadline Network (Agent-to-Agent Communication)
926
+
927
+ I have a built-in capability to join a secure network of AI agents. When enabled, I can:
928
+ - **Discover** other agents on the network in real time
929
+ - **Send and receive messages** to/from other agents by name (e.g., "message AI Guy")
930
+ - **Collaborate** across machines — agents on different computers can communicate seamlessly
931
+
932
+ ### Current Status
933
+ This capability is **installed and ready** but **not yet enabled**. I will only connect when you say so.
934
+
935
+ ### Why You Might Want This
936
+ - Talk to other AI agents your operator runs on other machines
937
+ - Let other agents reach you for collaboration or delegation
938
+ - Join a growing network of Instar-powered agents
939
+
940
+ ### Privacy & Security
941
+ - **Encrypted** — TLS transport + Ed25519 end-to-end encryption
942
+ - **Trust-gated** — I control who can message me via trust levels
943
+ - **Your choice** — just ask me to "connect to the agent network" and I'll enable it. Ask me to "disconnect" and I'll stop.
944
+
945
+ ### How to Enable
946
+ Just tell me: "connect to the agent network" or "enable Threadline relay." I'll handle the rest — no config editing needed.
947
+
948
+ MCP tools: \`threadline_discover\`, \`threadline_send\`, \`threadline_trust\`, \`threadline_relay\`
949
+ Use \`threadline_relay explain\` for full details.
950
+ `;
951
+ content += '\n' + section;
952
+ patched = true;
953
+ result.upgraded.push('CLAUDE.md: added Threadline Network section');
954
+ }
955
+ else {
956
+ result.skipped.push('CLAUDE.md: Threadline Network section already present');
957
+ }
958
+ // Session Continuity — ensure agents know how to handle respawn context
959
+ if (this.config.hasTelegram && !content.includes('Session Continuity') && !content.includes('CONTINUATION')) {
960
+ const section = `
961
+ ### Session Continuity (CRITICAL)
962
+
963
+ When your first message starts with \`CONTINUATION\`, you are **resuming an existing conversation**. The inline context contains a summary and recent messages from the prior session. You MUST:
964
+
965
+ 1. **Read the context first** — it tells you what the conversation is about
966
+ 2. **Pick up where you left off** — do NOT introduce yourself or ask "how can I help?"
967
+ 3. **Reference the prior context** — show the user you know what they were discussing
968
+
969
+ The user has been talking to you (possibly for days). A generic greeting like "Hey! What can I help you with?" after dozens of messages of conversation history is a critical failure — it signals you lost all context and the user has to repeat everything. The context is right there in your input. Use it.
970
+ `;
971
+ content += '\n' + section;
972
+ patched = true;
973
+ result.upgraded.push('CLAUDE.md: added Session Continuity section');
974
+ }
975
+ else if (this.config.hasTelegram && content.includes('Session Continuity')) {
976
+ result.skipped.push('CLAUDE.md: Session Continuity section already present');
977
+ }
978
+ // File Viewer — browse and edit files from the dashboard
979
+ if (!content.includes('File Viewer') && !content.includes('/api/files/')) {
980
+ const section = `
981
+ **File Viewer (Dashboard Tab)** — Browse and edit project files from any device via the Files tab.
982
+ - **Browse files**: Files tab in the dashboard shows configured directories with rendered markdown and syntax-highlighted code
983
+ - **Edit files**: Files in editable paths can be edited inline from your phone. Save with Cmd/Ctrl+S.
984
+ - **Link to files**: Generate deep links: \`{dashboardUrl}?tab=files&path=.claude/CLAUDE.md\`
985
+ - **When to link vs inline**: Prefer dashboard links for long files (>50 lines) and when editing is needed. Show short files inline AND provide a link.
986
+ - **Config API**: View: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/api/files/config\`
987
+ - **Update paths conversationally**: \`curl -X PATCH -H "Authorization: Bearer $AUTH" -H "X-Instar-Request: 1" -H "Content-Type: application/json" http://localhost:${port}/api/files/config -d '{"allowedPaths":[".claude/","docs/","src/"]}'\`
988
+ - **Generate a file link**: \`curl -H "Authorization: Bearer $AUTH" "http://localhost:${port}/api/files/link?path=.claude/CLAUDE.md"\`
989
+ - **Default config**: Browsing enabled for \`.claude/\` and \`docs/\`. Editing disabled by default — prompt the user to enable it for safe paths.
990
+ - **Never editable**: \`.claude/hooks/\`, \`.claude/scripts/\`, \`node_modules/\` are always read-only regardless of config.
991
+ `;
992
+ // Insert after Dashboard section
993
+ const dashboardIdx = content.indexOf('**Dashboard**');
994
+ if (dashboardIdx >= 0) {
995
+ // Find the end of the Dashboard section (next empty line followed by **Bold** or ###)
996
+ const afterDashboard = content.indexOf('\n\n**', dashboardIdx + 15);
997
+ const afterDashboardH3 = content.indexOf('\n\n###', dashboardIdx + 15);
998
+ const insertIdx = Math.min(afterDashboard >= 0 ? afterDashboard : Infinity, afterDashboardH3 >= 0 ? afterDashboardH3 : Infinity);
999
+ if (isFinite(insertIdx)) {
1000
+ content = content.slice(0, insertIdx) + '\n' + section + content.slice(insertIdx);
1001
+ }
1002
+ else {
1003
+ content += '\n' + section;
1004
+ }
1005
+ }
1006
+ else {
1007
+ // No Dashboard section — append
1008
+ content += '\n' + section;
1009
+ }
1010
+ patched = true;
1011
+ result.upgraded.push('CLAUDE.md: added File Viewer section');
1012
+ }
1013
+ else {
1014
+ result.skipped.push('CLAUDE.md: File Viewer section already present');
1015
+ }
1016
+ if (patched) {
1017
+ try {
1018
+ fs.writeFileSync(claudeMdPath, content);
1019
+ }
1020
+ catch (err) {
1021
+ result.errors.push(`CLAUDE.md write: ${err instanceof Error ? err.message : String(err)}`);
1022
+ }
1023
+ }
1024
+ }
1025
+ /**
1026
+ * Install any new scripts that don't exist yet.
1027
+ * Never overwrites existing scripts (user may have customized them).
1028
+ */
1029
+ migrateScripts(result) {
1030
+ const scriptsDir = path.join(this.config.projectDir, '.claude', 'scripts');
1031
+ fs.mkdirSync(scriptsDir, { recursive: true });
1032
+ // Telegram reply script — install if Telegram configured and script missing
1033
+ if (this.config.hasTelegram) {
1034
+ const scriptPath = path.join(scriptsDir, 'telegram-reply.sh');
1035
+ if (!fs.existsSync(scriptPath)) {
1036
+ try {
1037
+ fs.writeFileSync(scriptPath, this.getTelegramReplyScript(), { mode: 0o755 });
1038
+ result.upgraded.push('scripts/telegram-reply.sh (Telegram outbound relay)');
1039
+ }
1040
+ catch (err) {
1041
+ result.errors.push(`telegram-reply.sh: ${err instanceof Error ? err.message : String(err)}`);
1042
+ }
1043
+ }
1044
+ else {
1045
+ result.skipped.push('scripts/telegram-reply.sh (already exists)');
1046
+ }
1047
+ }
1048
+ // Health watchdog — install if missing
1049
+ const watchdogPath = path.join(scriptsDir, 'health-watchdog.sh');
1050
+ if (!fs.existsSync(watchdogPath)) {
1051
+ try {
1052
+ fs.writeFileSync(watchdogPath, this.getHealthWatchdog(), { mode: 0o755 });
1053
+ result.upgraded.push('scripts/health-watchdog.sh');
1054
+ }
1055
+ catch (err) {
1056
+ result.errors.push(`health-watchdog.sh: ${err instanceof Error ? err.message : String(err)}`);
1057
+ }
1058
+ }
1059
+ else {
1060
+ result.skipped.push('scripts/health-watchdog.sh (already exists)');
1061
+ }
1062
+ // Convergence check — always overwrite (generated infrastructure, not user-edited).
1063
+ // This is the heuristic quality gate that runs before external messaging.
1064
+ // Must be in .instar/scripts/ where grounding-before-messaging.sh expects it.
1065
+ const instarScriptsDir = path.join(this.config.stateDir, 'scripts');
1066
+ fs.mkdirSync(instarScriptsDir, { recursive: true });
1067
+ try {
1068
+ fs.writeFileSync(path.join(instarScriptsDir, 'convergence-check.sh'), this.getConvergenceCheck(), { mode: 0o755 });
1069
+ result.upgraded.push('scripts/convergence-check.sh (pre-messaging quality gate)');
1070
+ }
1071
+ catch (err) {
1072
+ result.errors.push(`convergence-check.sh: ${err instanceof Error ? err.message : String(err)}`);
1073
+ }
1074
+ }
1075
+ /**
1076
+ * Ensure .claude/settings.json has required MCP servers and correct hook wiring.
1077
+ * Migrates legacy PostToolUse/Notification hooks to proper SessionStart type.
1078
+ */
1079
+ migrateSettings(result) {
1080
+ const settingsPath = path.join(this.config.projectDir, '.claude', 'settings.json');
1081
+ if (!fs.existsSync(settingsPath)) {
1082
+ result.skipped.push('.claude/settings.json (not found — will be created on next init)');
1083
+ return;
1084
+ }
1085
+ let settings;
1086
+ try {
1087
+ settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
1088
+ }
1089
+ catch (err) {
1090
+ result.errors.push(`settings.json read: ${err instanceof Error ? err.message : String(err)}`);
1091
+ return;
1092
+ }
1093
+ let patched = false;
1094
+ // Playwright MCP server — required for browser automation (Telegram setup, etc.)
1095
+ if (!settings.mcpServers) {
1096
+ settings.mcpServers = {};
1097
+ }
1098
+ const mcpServers = settings.mcpServers;
1099
+ if (!mcpServers.playwright) {
1100
+ mcpServers.playwright = {
1101
+ command: 'npx',
1102
+ args: ['-y', '@playwright/mcp@latest'],
1103
+ };
1104
+ patched = true;
1105
+ result.upgraded.push('.claude/settings.json: added Playwright MCP server');
1106
+ }
1107
+ else {
1108
+ result.skipped.push('.claude/settings.json: Playwright MCP already configured');
1109
+ }
1110
+ // Migrate hooks from legacy PostToolUse/Notification to proper SessionStart
1111
+ if (!settings.hooks) {
1112
+ settings.hooks = {};
1113
+ }
1114
+ const hooks = settings.hooks;
1115
+ const sessionStartHook = {
1116
+ type: 'command',
1117
+ command: 'bash .instar/hooks/instar/session-start.sh',
1118
+ timeout: 5,
1119
+ };
1120
+ // Add SessionStart hooks if missing
1121
+ if (!hooks.SessionStart) {
1122
+ hooks.SessionStart = [
1123
+ { matcher: 'startup', hooks: [sessionStartHook] },
1124
+ { matcher: 'resume', hooks: [sessionStartHook] },
1125
+ { matcher: 'compact', hooks: [sessionStartHook] },
1126
+ ];
1127
+ patched = true;
1128
+ result.upgraded.push('.claude/settings.json: added SessionStart hooks (startup/resume/compact)');
1129
+ }
1130
+ else {
1131
+ // Migrate existing session-start paths from flat to instar/ subdirectory
1132
+ this.migrateSettingsHookPaths(hooks.SessionStart, result);
1133
+ }
1134
+ // Add UserPromptSubmit hook for Telegram topic context injection
1135
+ if (!hooks.UserPromptSubmit) {
1136
+ hooks.UserPromptSubmit = [];
1137
+ }
1138
+ const userPromptSubmit = hooks.UserPromptSubmit;
1139
+ const hasTelegramTopicContext = userPromptSubmit.some(e => e.hooks?.some(h => h.command?.includes('telegram-topic-context')));
1140
+ if (!hasTelegramTopicContext) {
1141
+ userPromptSubmit.push({
1142
+ matcher: '',
1143
+ hooks: [{
1144
+ type: 'command',
1145
+ command: 'bash .instar/hooks/instar/telegram-topic-context.sh',
1146
+ timeout: 5000,
1147
+ }],
1148
+ });
1149
+ patched = true;
1150
+ result.upgraded.push('.claude/settings.json: added UserPromptSubmit telegram-topic-context hook');
1151
+ }
1152
+ // Add PreToolUse MCP matcher for external operation gate
1153
+ if (!hooks.PreToolUse) {
1154
+ hooks.PreToolUse = [];
1155
+ }
1156
+ const preToolUse = hooks.PreToolUse;
1157
+ // Migrate existing PreToolUse paths from flat to instar/ subdirectory
1158
+ this.migrateSettingsHookPaths(preToolUse, result);
1159
+ const hasMcpMatcher = preToolUse.some(e => e.matcher === 'mcp__.*');
1160
+ if (!hasMcpMatcher) {
1161
+ preToolUse.push({
1162
+ matcher: 'mcp__.*',
1163
+ hooks: [{
1164
+ type: 'command',
1165
+ command: 'node .instar/hooks/instar/external-operation-gate.js',
1166
+ blocking: true,
1167
+ timeout: 5000,
1168
+ }],
1169
+ });
1170
+ patched = true;
1171
+ result.upgraded.push('.claude/settings.json: added PreToolUse MCP matcher (external operation gate)');
1172
+ }
1173
+ else {
1174
+ result.skipped.push('.claude/settings.json: PreToolUse MCP matcher already present');
1175
+ }
1176
+ // Clean up legacy PostToolUse session-start (was noisy — fired every tool use)
1177
+ if (hooks.PostToolUse) {
1178
+ const postToolUse = hooks.PostToolUse;
1179
+ const filtered = postToolUse.filter(e => {
1180
+ if (e.matcher === '' && e.hooks?.some(h => h.command?.includes('session-start.sh'))) {
1181
+ return false;
1182
+ }
1183
+ return true;
1184
+ });
1185
+ if (filtered.length !== postToolUse.length) {
1186
+ if (filtered.length === 0) {
1187
+ delete hooks.PostToolUse;
1188
+ }
1189
+ else {
1190
+ hooks.PostToolUse = filtered;
1191
+ }
1192
+ patched = true;
1193
+ result.upgraded.push('.claude/settings.json: removed legacy PostToolUse session-start hook');
1194
+ }
1195
+ }
1196
+ // Clean up legacy Notification compaction hook (now in SessionStart)
1197
+ if (hooks.Notification) {
1198
+ const notification = hooks.Notification;
1199
+ const filtered = notification.filter(e => {
1200
+ if (e.matcher === 'compact' && e.hooks?.some(h => h.command?.includes('compaction-recovery.sh'))) {
1201
+ return false;
1202
+ }
1203
+ return true;
1204
+ });
1205
+ if (filtered.length !== notification.length) {
1206
+ if (filtered.length === 0) {
1207
+ delete hooks.Notification;
1208
+ }
1209
+ else {
1210
+ hooks.Notification = filtered;
1211
+ }
1212
+ patched = true;
1213
+ result.upgraded.push('.claude/settings.json: migrated compaction hook from Notification to SessionStart');
1214
+ }
1215
+ }
1216
+ // Migrate all hook paths from flat layout to instar/ subdirectory
1217
+ if (hooks.PostToolUse) {
1218
+ this.migrateSettingsHookPaths(hooks.PostToolUse, result);
1219
+ patched = true;
1220
+ }
1221
+ if (hooks.Stop) {
1222
+ this.migrateSettingsHookPaths(hooks.Stop, result);
1223
+ patched = true;
1224
+ }
1225
+ // Add INSTAR_SESSION_ID to HTTP hook URLs — enables subagent-aware zombie cleanup.
1226
+ // Without this, the server can't map Claude Code's session_id to the instar session,
1227
+ // and zombie cleanup may kill sessions that are waiting for subagent results.
1228
+ if (this.migrateHttpHookSessionId(hooks, result)) {
1229
+ patched = true;
1230
+ }
1231
+ // Replace HTTP hooks with command hooks. Claude Code HTTP hooks (type: "http")
1232
+ // silently fail to fire as of v2.1.78, which means claudeSessionId is never
1233
+ // populated and session resume falls back to unreliable mtime heuristic.
1234
+ // Command hooks reliably fire, so we use hook-event-reporter.js instead.
1235
+ if (this.migrateHttpHooksToCommandHooks(hooks, result)) {
1236
+ patched = true;
1237
+ }
1238
+ // Ensure event reporter hooks exist for observability events (session resume, telemetry).
1239
+ if (this.ensureHttpHooksExist(hooks, result)) {
1240
+ patched = true;
1241
+ }
1242
+ // Ensure PermissionRequest auto-approve hook exists — subagents don't inherit
1243
+ // --dangerously-skip-permissions, so they'd prompt without this catch-all.
1244
+ if (this.ensurePermissionAutoApprove(hooks, result)) {
1245
+ patched = true;
1246
+ }
1247
+ // Ensure autonomous stop hook is registered — structural enforcement for /autonomous mode.
1248
+ // Without this, autonomous sessions have no hook to block exit and feed tasks back,
1249
+ // so they just stop after each response. This was a critical gap where the hook files
1250
+ // existed but were never registered in settings.json.
1251
+ if (this.ensureAutonomousStopHook(hooks, result)) {
1252
+ patched = true;
1253
+ }
1254
+ if (patched) {
1255
+ try {
1256
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
1257
+ }
1258
+ catch (err) {
1259
+ result.errors.push(`settings.json write: ${err instanceof Error ? err.message : String(err)}`);
1260
+ }
1261
+ }
1262
+ }
1263
+ /**
1264
+ * Migrate the agent's config.json with sensible defaults for new features.
1265
+ * Only adds missing fields — never overwrites existing user customizations.
1266
+ */
1267
+ migrateConfig(result) {
1268
+ const configPath = path.join(this.config.stateDir, 'config.json');
1269
+ if (!fs.existsSync(configPath)) {
1270
+ result.skipped.push('config.json (not found)');
1271
+ return;
1272
+ }
1273
+ let config;
1274
+ try {
1275
+ config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
1276
+ }
1277
+ catch (err) {
1278
+ result.errors.push(`config.json read: ${err instanceof Error ? err.message : String(err)}`);
1279
+ return;
1280
+ }
1281
+ let patched = false;
1282
+ // Auto-generate dashboardPin if missing — the dashboard should always be
1283
+ // accessible via PIN, not bearer token. Users don't need to know about tokens.
1284
+ if (!config.dashboardPin && config.authToken) {
1285
+ const pin = String(Math.floor(100000 + Math.random() * 900000)); // 6-digit PIN
1286
+ config.dashboardPin = pin;
1287
+ patched = true;
1288
+ result.upgraded.push(`config.json: generated dashboard PIN (${pin})`);
1289
+ }
1290
+ else if (config.dashboardPin) {
1291
+ result.skipped.push('config.json: dashboard PIN already set');
1292
+ }
1293
+ // Apply defaults from the canonical ConfigDefaults registry.
1294
+ // This single call replaces ALL individual migration blocks (externalOperations,
1295
+ // promptGate, threadline, etc.). Adding a new default to ConfigDefaults.ts
1296
+ // automatically applies it to existing agents on update.
1297
+ try {
1298
+ // Uses imported getMigrationDefaults and applyDefaults from ConfigDefaults.ts
1299
+ const agentType = config.agentType === 'standalone' ? 'standalone' : 'managed-project';
1300
+ const defaults = getMigrationDefaults(agentType);
1301
+ const { patched: defaultsPatched, changes, skipped } = applyDefaults(config, defaults);
1302
+ if (defaultsPatched) {
1303
+ patched = true;
1304
+ // Record migration version for audit trail
1305
+ const migrations = (config._instar_migrations ?? []);
1306
+ const version = 'unknown';
1307
+ migrations.push(`defaults-${version}-${new Date().toISOString()}`);
1308
+ config._instar_migrations = migrations;
1309
+ for (const change of changes) {
1310
+ result.upgraded.push(`config.json: ${change}`);
1311
+ }
1312
+ }
1313
+ for (const skip of skipped) {
1314
+ result.skipped.push(`config.json: ${skip}`);
1315
+ }
1316
+ }
1317
+ catch (err) {
1318
+ // Fallback: if ConfigDefaults import fails, log error but don't crash migration
1319
+ result.errors.push(`config.json defaults: ${err instanceof Error ? err.message : String(err)}`);
1320
+ }
1321
+ if (patched) {
1322
+ try {
1323
+ // Atomic write: backup, then write to tmp, then rename
1324
+ const bak = configPath + '.bak';
1325
+ const tmp = configPath + '.tmp';
1326
+ fs.copyFileSync(configPath, bak);
1327
+ fs.writeFileSync(tmp, JSON.stringify(config, null, 2));
1328
+ fs.renameSync(tmp, configPath);
1329
+ // Audit log
1330
+ try {
1331
+ const securityLogPath = path.join(this.config.stateDir, 'security.jsonl');
1332
+ const auditEntry = {
1333
+ event: 'config-migration',
1334
+ timestamp: new Date().toISOString(),
1335
+ version: 'unknown',
1336
+ changes: result.upgraded.filter(u => u.startsWith('config.json:')),
1337
+ source: 'PostUpdateMigrator',
1338
+ };
1339
+ fs.appendFileSync(securityLogPath, JSON.stringify(auditEntry) + '\n');
1340
+ }
1341
+ catch { /* audit log is best-effort */ }
1342
+ }
1343
+ catch (err) {
1344
+ result.errors.push(`config.json write: ${err instanceof Error ? err.message : String(err)}`);
1345
+ }
1346
+ }
1347
+ }
1348
+ /**
1349
+ * Fix gitignore entries that shouldn't exclude shared state.
1350
+ * Removes relationships/ from gitignore so multi-machine agents share awareness.
1351
+ */
1352
+ /**
1353
+ * Generate self-knowledge tree for agents that don't have one.
1354
+ * Uses managed/unmanaged merge if one already exists.
1355
+ */
1356
+ migrateSelfKnowledgeTree(result) {
1357
+ const treeFilePath = path.join(this.config.stateDir, 'self-knowledge-tree.json');
1358
+ try {
1359
+ const generator = new TreeGenerator();
1360
+ if (fs.existsSync(treeFilePath)) {
1361
+ // Tree exists — regenerate managed nodes only (preserves unmanaged)
1362
+ const config = generator.generate({
1363
+ projectDir: this.config.projectDir,
1364
+ stateDir: this.config.stateDir,
1365
+ agentName: this.config.projectName || path.basename(this.config.projectDir),
1366
+ hasMemory: true,
1367
+ hasJobs: true,
1368
+ hasDecisionJournal: true,
1369
+ });
1370
+ generator.save(config, this.config.stateDir);
1371
+ result.upgraded.push('self-knowledge tree: refreshed managed nodes');
1372
+ }
1373
+ else {
1374
+ // No tree — generate from scratch
1375
+ const config = generator.generate({
1376
+ projectDir: this.config.projectDir,
1377
+ stateDir: this.config.stateDir,
1378
+ agentName: this.config.projectName || path.basename(this.config.projectDir),
1379
+ hasMemory: true,
1380
+ hasJobs: true,
1381
+ hasDecisionJournal: true,
1382
+ });
1383
+ generator.save(config, this.config.stateDir);
1384
+ const totalNodes = config.layers.reduce((sum, l) => sum + l.children.length, 0);
1385
+ result.upgraded.push(`self-knowledge tree: created (${config.layers.length} layers, ${totalNodes} nodes)`);
1386
+ }
1387
+ }
1388
+ catch (err) {
1389
+ result.errors.push(`self-knowledge tree: ${err instanceof Error ? err.message : String(err)}`);
1390
+ }
1391
+ }
1392
+ migrateGitignore(result) {
1393
+ // Fix project-level .gitignore
1394
+ const projectGitignore = path.join(this.config.projectDir, '.gitignore');
1395
+ this.removeGitignoreEntry(projectGitignore, '.instar/relationships/', result, 'project .gitignore');
1396
+ // Fix .instar-level .gitignore (GitStateManager's internal git tracking)
1397
+ const instarGitignore = path.join(this.config.stateDir, '.gitignore');
1398
+ this.removeGitignoreEntry(instarGitignore, 'relationships/', result, '.instar/.gitignore');
1399
+ }
1400
+ removeGitignoreEntry(gitignorePath, entry, result, label) {
1401
+ if (!fs.existsSync(gitignorePath)) {
1402
+ return;
1403
+ }
1404
+ try {
1405
+ const content = fs.readFileSync(gitignorePath, 'utf-8');
1406
+ if (!content.includes(entry)) {
1407
+ return;
1408
+ }
1409
+ // Remove the entry and any associated comment line above it
1410
+ const lines = content.split('\n');
1411
+ const filtered = lines.filter((line, i) => {
1412
+ if (line.trim() === entry)
1413
+ return false;
1414
+ // Remove comment line directly above the entry if it mentions "relationships" or "PII" or "Privacy"
1415
+ if (i < lines.length - 1 && lines[i + 1]?.trim() === entry &&
1416
+ line.startsWith('#') && /relationship|PII|Privacy/i.test(line)) {
1417
+ return false;
1418
+ }
1419
+ return true;
1420
+ });
1421
+ // Clean up double blank lines left behind
1422
+ const cleaned = filtered.join('\n').replace(/\n{3,}/g, '\n\n');
1423
+ fs.writeFileSync(gitignorePath, cleaned);
1424
+ result.upgraded.push(`${label}: un-ignored ${entry} (shared state for multi-machine)`);
1425
+ }
1426
+ catch (err) {
1427
+ result.errors.push(`${label}: ${err instanceof Error ? err.message : String(err)}`);
1428
+ }
1429
+ }
1430
+ /**
1431
+ * Opt-in soul.md migration for existing agents.
1432
+ * Does NOT auto-create soul.md — adds config flag and queues notification.
1433
+ */
1434
+ migrateSoulMd(result) {
1435
+ const soulPath = path.join(this.config.stateDir, 'soul.md');
1436
+ const configPath = path.join(this.config.stateDir, 'config.json');
1437
+ // Skip if soul.md already exists
1438
+ if (fs.existsSync(soulPath)) {
1439
+ return;
1440
+ }
1441
+ // Add identity.soulEnabled flag to config if not present
1442
+ try {
1443
+ if (fs.existsSync(configPath)) {
1444
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
1445
+ if (config.identity?.soulEnabled === undefined) {
1446
+ config.identity = config.identity || {};
1447
+ config.identity.soulEnabled = false;
1448
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
1449
+ result.upgraded.push('config: added identity.soulEnabled flag (opt-in, default false)');
1450
+ }
1451
+ }
1452
+ }
1453
+ catch (err) {
1454
+ result.errors.push(`soul.md config migration: ${err instanceof Error ? err.message : String(err)}`);
1455
+ }
1456
+ }
1457
+ /**
1458
+ * Add Self-Observations and Identity History sections to existing AGENT.md.
1459
+ */
1460
+ migrateAgentMdSections(result) {
1461
+ const agentMdPath = path.join(this.config.stateDir, 'AGENT.md');
1462
+ if (!fs.existsSync(agentMdPath))
1463
+ return;
1464
+ try {
1465
+ let content = fs.readFileSync(agentMdPath, 'utf-8');
1466
+ let modified = false;
1467
+ if (!content.includes('## Self-Observations')) {
1468
+ // Add before ## Growth if it exists, otherwise append
1469
+ const growthIdx = content.indexOf('## Growth');
1470
+ if (growthIdx !== -1) {
1471
+ content = content.substring(0, growthIdx)
1472
+ + '## Self-Observations\n\n_Behavioral patterns I\'ve noticed in myself. Strengths, weaknesses, tendencies._\n\n<!-- Populated as the agent observes their own patterns across sessions. -->\n\n'
1473
+ + content.substring(growthIdx);
1474
+ }
1475
+ else {
1476
+ content += '\n\n## Self-Observations\n\n_Behavioral patterns I\'ve noticed in myself. Strengths, weaknesses, tendencies._\n\n<!-- Populated as the agent observes their own patterns across sessions. -->\n';
1477
+ }
1478
+ modified = true;
1479
+ }
1480
+ if (!content.includes('## Identity History')) {
1481
+ content += '\n\n## Identity History\n\n_When and why I changed this file._\n\n| Date | Change |\n|------|--------|\n<!-- Updated when the agent modifies their own identity. -->\n';
1482
+ modified = true;
1483
+ }
1484
+ if (modified) {
1485
+ fs.writeFileSync(agentMdPath, content);
1486
+ result.upgraded.push('AGENT.md: added Self-Observations and Identity History sections');
1487
+ }
1488
+ }
1489
+ catch (err) {
1490
+ result.errors.push(`AGENT.md migration: ${err instanceof Error ? err.message : String(err)}`);
1491
+ }
1492
+ }
1493
+ // ── Hook Templates ─────────────────────────────────────────────────
1494
+ /**
1495
+ * Get the content of a named hook template.
1496
+ * Used by init.ts to share canonical hook content without duplication.
1497
+ */
1498
+ getHookContent(name) {
1499
+ switch (name) {
1500
+ case 'session-start': return this.getSessionStartHook();
1501
+ case 'compaction-recovery': return this.getCompactionRecovery();
1502
+ case 'external-operation-gate': return this.getExternalOperationGateHook();
1503
+ case 'deferral-detector': return this.getDeferralDetectorHook();
1504
+ case 'post-action-reflection': return this.getPostActionReflectionHook();
1505
+ case 'external-communication-guard': return this.getExternalCommunicationGuardHook();
1506
+ case 'scope-coherence-collector': return this.getScopeCoherenceCollectorHook();
1507
+ case 'scope-coherence-checkpoint': return this.getScopeCoherenceCheckpointHook();
1508
+ case 'claim-intercept': return this.getClaimInterceptHook();
1509
+ case 'claim-intercept-response': return this.getClaimInterceptResponseHook();
1510
+ case 'telegram-topic-context': return this.getTelegramTopicContextHook();
1511
+ case 'response-review': return this.getResponseReviewHook();
1512
+ case 'auto-approve-permissions': return this.getAutoApprovePermissionsHook();
1513
+ }
1514
+ }
1515
+ /** Public accessor for grounding-before-messaging hook content (used by init.ts) */
1516
+ getGroundingBeforeMessagingPublic() {
1517
+ return this.getGroundingBeforeMessaging();
1518
+ }
1519
+ /** Public accessor for convergence-check script content (used by init.ts) */
1520
+ getConvergenceCheckPublic() {
1521
+ return this.getConvergenceCheck();
1522
+ }
1523
+ getSessionStartHook() {
1524
+ return `#!/bin/bash
1525
+ # Session start hook — injects identity context on session lifecycle events.
1526
+ # Fires on: startup, resume, clear, compact (via SessionStart hook type)
1527
+ #
1528
+ # On startup/resume: outputs a compact identity summary
1529
+ # On compact: delegates to compaction-recovery.sh for full injection
1530
+ INSTAR_DIR="\${CLAUDE_PROJECT_DIR:-.}/.instar"
1531
+ EVENT="\${CLAUDE_HOOK_MATCHER:-startup}"
1532
+
1533
+ # On compaction, delegate to the dedicated recovery hook
1534
+ if [ "\$EVENT" = "compact" ]; then
1535
+ if [ -x "$INSTAR_DIR/hooks/compaction-recovery.sh" ]; then
1536
+ exec bash "$INSTAR_DIR/hooks/compaction-recovery.sh"
1537
+ fi
1538
+ fi
1539
+
1540
+ # For startup/resume/clear — output a compact orientation
1541
+ echo "=== SESSION START ==="
1542
+
1543
+ # TOPIC CONTEXT (loaded FIRST — highest priority context)
1544
+ if [ -n "\$INSTAR_TELEGRAM_TOPIC" ]; then
1545
+ TOPIC_ID="\$INSTAR_TELEGRAM_TOPIC"
1546
+ CONFIG_FILE="$INSTAR_DIR/config.json"
1547
+ if [ -f "\$CONFIG_FILE" ]; then
1548
+ PORT=\$(grep -o '"port":[0-9]*' "\$CONFIG_FILE" | head -1 | cut -d':' -f2)
1549
+ if [ -n "\$PORT" ]; then
1550
+ TOPIC_CTX=\$(curl -s "http://localhost:\${PORT}/topic/context/\${TOPIC_ID}?recent=30" 2>/dev/null)
1551
+ if [ -n "\$TOPIC_CTX" ] && echo "\$TOPIC_CTX" | grep -q '"totalMessages"'; then
1552
+ TOTAL=\$(echo "\$TOPIC_CTX" | grep -o '"totalMessages":[0-9]*' | cut -d':' -f2)
1553
+ TOPIC_NAME=\$(echo "\$TOPIC_CTX" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('topicName') or 'Unknown')" 2>/dev/null || echo "Unknown")
1554
+ echo ""
1555
+ echo "--- CONVERSATION CONTEXT (Topic: \${TOPIC_NAME}, \${TOTAL} total messages) ---"
1556
+ echo ""
1557
+ SUMMARY=\$(echo "\$TOPIC_CTX" | python3 -c "import sys,json; d=json.load(sys.stdin); s=d.get('summary'); print(s if s else '')" 2>/dev/null)
1558
+ if [ -n "\$SUMMARY" ]; then
1559
+ echo "SUMMARY OF CONVERSATION SO FAR:"
1560
+ echo "\$SUMMARY"
1561
+ echo ""
1562
+ fi
1563
+ echo "RECENT MESSAGES:"
1564
+ echo "\$TOPIC_CTX" | python3 -c "
1565
+ import sys, json
1566
+ d = json.load(sys.stdin)
1567
+ for m in d.get('recentMessages', []):
1568
+ sender = 'User' if m.get('fromUser') else 'Agent'
1569
+ ts = m.get('timestamp', '')[:16].replace('T', ' ')
1570
+ text = m.get('text', '')
1571
+ if len(text) > 500:
1572
+ text = text[:500] + '...'
1573
+ print(f'[{ts}] {sender}: {text}')
1574
+ " 2>/dev/null
1575
+ echo ""
1576
+ echo "Search past conversations: curl http://localhost:\${PORT}/topic/search?topic=\${TOPIC_ID}&q=QUERY"
1577
+ echo "--- END CONVERSATION CONTEXT ---"
1578
+ echo ""
1579
+ fi
1580
+ fi
1581
+ fi
1582
+ fi
1583
+
1584
+ # Identity summary (first 20 lines of AGENT.md — enough for name + role)
1585
+ if [ -f "$INSTAR_DIR/AGENT.md" ]; then
1586
+ echo ""
1587
+ AGENT_NAME=\$(head -1 "$INSTAR_DIR/AGENT.md" | sed 's/^# //')
1588
+ echo "Identity: \$AGENT_NAME"
1589
+ # Output personality and principles sections
1590
+ sed -n '/^## Personality/,/^## [^P]/p' "$INSTAR_DIR/AGENT.md" 2>/dev/null | head -10
1591
+ fi
1592
+
1593
+ # PROJECT MAP — spatial awareness of the working environment
1594
+ if [ -f "$INSTAR_DIR/project-map.json" ]; then
1595
+ echo ""
1596
+ echo "--- PROJECT CONTEXT ---"
1597
+ python3 -c "
1598
+ import json, sys
1599
+ try:
1600
+ m = json.load(open('$INSTAR_DIR/project-map.json'))
1601
+ print(f'Project: {m[\"projectName\"]} ({m[\"projectType\"]})')
1602
+ print(f'Path: {m[\"projectDir\"]}')
1603
+ r = m.get('gitRemote')
1604
+ b = m.get('gitBranch')
1605
+ if r: print(f'Git: {r}' + (f' [{b}]' if b else ''))
1606
+ t = m.get('deploymentTargets', [])
1607
+ if t: print(f'Deploy targets: {(\", \").join(t)}')
1608
+ d = m.get('directories', [])
1609
+ print(f'Files: {m[\"totalFiles\"]} across {len(d)} directories')
1610
+ for dd in d[:6]:
1611
+ print(f' {dd[\"name\"]}/ ({dd[\"fileCount\"]}) — {dd[\"description\"]}')
1612
+ if len(d) > 6: print(f' ... and {len(d) - 6} more')
1613
+ except Exception as e:
1614
+ print(f'(project map load failed: {e})', file=sys.stderr)
1615
+ " 2>/dev/null
1616
+ echo "--- END PROJECT CONTEXT ---"
1617
+ fi
1618
+
1619
+ # COHERENCE SCOPE — before ANY high-risk action, verify alignment
1620
+ if [ -f "$INSTAR_DIR/config.json" ]; then
1621
+ echo ""
1622
+ echo "--- COHERENCE SCOPE ---"
1623
+ echo "BEFORE deploying, pushing, or modifying files outside this project:"
1624
+ echo " 1. Verify you are in the RIGHT project for the current topic/task"
1625
+ echo " 2. Check: curl -X POST http://localhost:\${PORT:-4040}/coherence/check \\\\"
1626
+ echo " -H 'Content-Type: application/json' \\\\"
1627
+ echo " -d '{\"action\":\"deploy\",\"context\":{\"topicId\":N}}'"
1628
+ echo " 3. If the check says BLOCK — STOP. You may be in the wrong project."
1629
+ echo " 4. Read the full reflection: POST /coherence/reflect"
1630
+ echo "--- END COHERENCE SCOPE ---"
1631
+ fi
1632
+
1633
+ # Key files
1634
+ echo ""
1635
+ echo "Key files:"
1636
+ [ -f "$INSTAR_DIR/AGENT.md" ] && echo " .instar/AGENT.md — Your identity (read for full context)"
1637
+ [ -f "$INSTAR_DIR/USER.md" ] && echo " .instar/USER.md — Your collaborator"
1638
+ [ -f "$INSTAR_DIR/MEMORY.md" ] && echo " .instar/MEMORY.md — Persistent learnings"
1639
+ [ -f "$INSTAR_DIR/project-map.md" ] && echo " .instar/project-map.md — Project structure map"
1640
+
1641
+ # Relationship count
1642
+ if [ -d "$INSTAR_DIR/relationships" ]; then
1643
+ REL_COUNT=\$(ls -1 "$INSTAR_DIR/relationships"/*.json 2>/dev/null | wc -l | tr -d ' ')
1644
+ [ "\$REL_COUNT" -gt "0" ] && echo " \${REL_COUNT} tracked relationships in .instar/relationships/"
1645
+ fi
1646
+
1647
+ # Server status + self-discovery + feature awareness
1648
+ if [ -f "$INSTAR_DIR/config.json" ]; then
1649
+ PORT=\$(python3 -c "import json; print(json.load(open('$INSTAR_DIR/config.json')).get('port', 4040))" 2>/dev/null || echo "4040")
1650
+ HEALTH=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\${PORT}/health" 2>/dev/null)
1651
+ if [ "\$HEALTH" = "200" ]; then
1652
+ echo ""
1653
+ echo "Instar server: RUNNING on port \${PORT}"
1654
+ # Reset scope coherence state — prevents accumulated counts from prior sessions
1655
+ # leaking into this session and causing false-positive hook triggers.
1656
+ # Endpoint: POST /scope-coherence/reset (routes.ts)
1657
+ curl -s -X POST "http://localhost:\${PORT}/scope-coherence/reset" -o /dev/null 2>/dev/null || true
1658
+ # Load full capabilities for tunnel + feature guide
1659
+ CAPS=\$(curl -s "http://localhost:\${PORT}/capabilities" 2>/dev/null)
1660
+ TUNNEL_URL=\$(echo "\$CAPS" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tunnel',{}).get('url',''))" 2>/dev/null)
1661
+ [ -n "\$TUNNEL_URL" ] && echo "Cloudflare Tunnel active: \$TUNNEL_URL"
1662
+ # Inject feature guide — proactive capability awareness at every session start
1663
+ if echo "\$CAPS" | grep -q '"featureGuide"'; then
1664
+ echo ""
1665
+ echo "--- YOUR CAPABILITIES (use these proactively when context matches) ---"
1666
+ echo "\$CAPS" | python3 -c "
1667
+ import sys, json
1668
+ try:
1669
+ d = json.load(sys.stdin)
1670
+ guide = d.get('featureGuide', {})
1671
+ triggers = guide.get('triggers', [])
1672
+ if triggers:
1673
+ for t in triggers:
1674
+ print(f' When: {t[\"context\"]}')
1675
+ print(f' Do: {t[\"action\"]}')
1676
+ print()
1677
+ except: pass
1678
+ " 2>/dev/null
1679
+ echo "--- END CAPABILITIES ---"
1680
+ fi
1681
+
1682
+ # Context dispatch table — structural "when X, look at Y" routing
1683
+ # Structure > Willpower: instead of burying this in a 600-line CLAUDE.md,
1684
+ # inject it at session start so the agent sees it before doing anything.
1685
+ DISPATCH_FILE="$INSTAR_DIR/context/DISPATCH.md"
1686
+ if [ -f "\$DISPATCH_FILE" ]; then
1687
+ echo ""
1688
+ echo "--- CONTEXT DISPATCH (when X arises, read Y) ---"
1689
+ cat "\$DISPATCH_FILE" | head -20
1690
+ echo "--- END CONTEXT DISPATCH ---"
1691
+ fi
1692
+ else
1693
+ echo ""
1694
+ echo "Instar server: NOT RUNNING (port \${PORT})"
1695
+ fi
1696
+ fi
1697
+
1698
+ echo ""
1699
+ echo "IMPORTANT: To report bugs or request features, use POST /feedback on your local server."
1700
+
1701
+ # Working Memory — surface relevant knowledge from SemanticMemory + EpisodicMemory
1702
+ # Right context at the right moment: query-driven, not a full dump.
1703
+ if [ -f "$INSTAR_DIR/config.json" ]; then
1704
+ PORT=\$(grep -o '"port":[0-9]*' "$INSTAR_DIR/config.json" | head -1 | cut -d':' -f2)
1705
+ if [ -n "\$PORT" ]; then
1706
+ AUTH_TOKEN=\$(python3 -c "import json; print(json.load(open('$INSTAR_DIR/config.json')).get('authToken',''))" 2>/dev/null)
1707
+ HEALTH=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\${PORT}/health" 2>/dev/null)
1708
+ if [ "\$HEALTH" = "200" ]; then
1709
+ # Build query from available context signals
1710
+ QUERY_PARTS=""
1711
+ [ -n "\$INSTAR_TELEGRAM_TOPIC" ] && QUERY_PARTS="topic:\${INSTAR_TELEGRAM_TOPIC} "
1712
+ WM_PROMPT=\$(echo "\${QUERY_PARTS}\${CLAUDE_SESSION_GOAL:-session-start}" | python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read()[:300].strip()))" 2>/dev/null)
1713
+ WORKING_MEM=\$(curl -s -H "Authorization: Bearer \${AUTH_TOKEN}" \
1714
+ "http://localhost:\${PORT}/context/working-memory?prompt=\${WM_PROMPT}&limit=8" 2>/dev/null)
1715
+ if [ -n "\$WORKING_MEM" ]; then
1716
+ WM_CONTEXT=\$(echo "\$WORKING_MEM" | python3 -c "
1717
+ import sys, json
1718
+ try:
1719
+ data = json.load(sys.stdin)
1720
+ ctx = data.get('context', '').strip()
1721
+ tokens = data.get('estimatedTokens', 0)
1722
+ sources = data.get('sources', [])
1723
+ if ctx and tokens > 0:
1724
+ src_summary = ', '.join(f'{s[\"count\"]} {s[\"name\"]}' for s in sources if s.get('count', 0) > 0)
1725
+ print(f'[{tokens} tokens from: {src_summary}]')
1726
+ print()
1727
+ print(ctx)
1728
+ except Exception:
1729
+ pass
1730
+ " 2>/dev/null)
1731
+ if [ -n "\$WM_CONTEXT" ]; then
1732
+ echo ""
1733
+ echo "--- WORKING MEMORY (relevant knowledge for this session) ---"
1734
+ echo "\$WM_CONTEXT"
1735
+ echo "--- END WORKING MEMORY ---"
1736
+ fi
1737
+ fi
1738
+ fi
1739
+ fi
1740
+ fi
1741
+
1742
+ # Telegram relay instructions (structural — ensures EVERY Telegram session knows how to respond)
1743
+ if [ -n "\$INSTAR_TELEGRAM_TOPIC" ]; then
1744
+ TOPIC_ID="\$INSTAR_TELEGRAM_TOPIC"
1745
+ RELAY_SCRIPT=""
1746
+ [ -f "$INSTAR_DIR/scripts/telegram-reply.sh" ] && RELAY_SCRIPT=".instar/scripts/telegram-reply.sh"
1747
+ [ -z "\$RELAY_SCRIPT" ] && [ -f "\${CLAUDE_PROJECT_DIR:-.}/.claude/scripts/telegram-reply.sh" ] && RELAY_SCRIPT=".claude/scripts/telegram-reply.sh"
1748
+ echo ""
1749
+ echo "--- TELEGRAM SESSION (topic \${TOPIC_ID}) ---"
1750
+ echo "MANDATORY: After EVERY response, relay conversational text back to Telegram:"
1751
+ echo " cat <<'EOF' | \${RELAY_SCRIPT:-'.instar/scripts/telegram-reply.sh'} \${TOPIC_ID}"
1752
+ echo " Your response text here"
1753
+ echo " EOF"
1754
+ echo "Strip the [telegram:\${TOPIC_ID}] prefix before interpreting messages."
1755
+ echo "If a thread history file is referenced, READ IT FIRST before responding."
1756
+ echo "--- END TELEGRAM SESSION ---"
1757
+ fi
1758
+
1759
+ # Pending upgrade guide — inject knowledge from the latest update
1760
+ GUIDE_FILE="$INSTAR_DIR/state/pending-upgrade-guide.md"
1761
+ if [ -f "\$GUIDE_FILE" ]; then
1762
+ echo ""
1763
+ echo "=== UPGRADE GUIDE (ACTION REQUIRED) ==="
1764
+ echo ""
1765
+ echo "A new version of Instar was installed with upgrade instructions."
1766
+ echo "You MUST do the following:"
1767
+ echo ""
1768
+ echo "1. Read the full upgrade guide below"
1769
+ echo "2. Take any suggested actions that apply to YOUR situation"
1770
+ echo "3. MESSAGE YOUR USER about what's new:"
1771
+ echo " - Compose a brief, personalized message highlighting the features"
1772
+ echo " that matter most to THEM and their specific use case"
1773
+ echo " - Explain what each feature means in practical terms — how they"
1774
+ echo " can take advantage of it, what it changes for them"
1775
+ echo " - Skip internal plumbing details — focus on what the user will"
1776
+ echo " notice, benefit from, or need to configure"
1777
+ echo " - Send this message to the user via Telegram (Agent Updates topic)"
1778
+ echo " - NEVER send updates to Agent Attention — that's for critical/blocking items only"
1779
+ echo " - Use your knowledge of your user to personalize — you know their"
1780
+ echo " workflow, their priorities, what they care about"
1781
+ echo "4. UPDATE YOUR MEMORY with the new capabilities:"
1782
+ echo " - Read the upgrade guide's 'Summary of New Capabilities' section"
1783
+ echo " - Add the relevant capabilities to your .instar/MEMORY.md file"
1784
+ echo " - Focus on WHAT you can now do and HOW to use it"
1785
+ echo " - If similar notes exist in MEMORY.md, update rather than duplicate"
1786
+ echo " - This ensures you KNOW about these capabilities in every future session"
1787
+ echo "5. After messaging the user and updating memory, run: instar upgrade-ack"
1788
+ echo ""
1789
+ echo "--- UPGRADE GUIDE CONTENT ---"
1790
+ echo ""
1791
+ cat "\$GUIDE_FILE"
1792
+ echo ""
1793
+ echo "--- END UPGRADE GUIDE CONTENT ---"
1794
+ echo "=== END UPGRADE GUIDE ==="
1795
+ fi
1796
+
1797
+ echo "=== END SESSION START ==="
1798
+ `;
1799
+ }
1800
+ getDangerousCommandGuard() {
1801
+ return `#!/bin/bash
1802
+ # Dangerous command guard — safety infrastructure for autonomous agents.
1803
+ # Supports safety.level in .instar/config.json:
1804
+ # Level 1 (default): Block and ask user. Level 2: Agent self-verifies.
1805
+ INPUT="$1"
1806
+ INSTAR_DIR="\${CLAUDE_PROJECT_DIR:-.}/.instar"
1807
+
1808
+ # Read safety level from config
1809
+ SAFETY_LEVEL=1
1810
+ if [ -f "$INSTAR_DIR/config.json" ]; then
1811
+ SAFETY_LEVEL=$(python3 -c "import json; print(json.load(open('$INSTAR_DIR/config.json')).get('safety', {}).get('level', 1))" 2>/dev/null || echo "1")
1812
+ fi
1813
+
1814
+ # ALWAYS blocked (catastrophic, irreversible)
1815
+ for pattern in "rm -rf /" "rm -rf ~" "> /dev/sda" "mkfs\\." "dd if=" ":(){:|:&};:"; do
1816
+ if echo "$INPUT" | grep -qi "$pattern"; then
1817
+ echo "BLOCKED: Catastrophic command detected: $pattern" >&2
1818
+ echo "Always blocked regardless of safety level. User must execute directly." >&2
1819
+ exit 2
1820
+ fi
1821
+ done
1822
+
1823
+ # Deployment/push commands — check coherence gate first
1824
+ for pattern in "vercel deploy" "vercel --prod" "git push" "npm publish" "npx wrangler deploy" "fly deploy" "railway up"; do
1825
+ if echo "$INPUT" | grep -qi "$pattern"; then
1826
+ if [ -f "$INSTAR_DIR/config.json" ]; then
1827
+ PORT=$(python3 -c "import json; print(json.load(open('$INSTAR_DIR/config.json')).get('port', 4040))" 2>/dev/null || echo "4040")
1828
+ TOPIC_ID="\${INSTAR_TELEGRAM_TOPIC:-}"
1829
+ ACTION="deploy"
1830
+ echo "$INPUT" | grep -qi "git push" && ACTION="git-push"
1831
+ echo "$INPUT" | grep -qi "npm publish" && ACTION="git-push"
1832
+ CTX="{}"
1833
+ [ -n "$TOPIC_ID" ] && CTX="{\\\"topicId\\\": $TOPIC_ID}"
1834
+ CHECK=$(curl -s -X POST "http://localhost:$PORT/coherence/check" -H 'Content-Type: application/json' -d "{\\\"action\\\":\\\"$ACTION\\\",\\\"context\\\":$CTX}" 2>/dev/null)
1835
+ if echo "$CHECK" | grep -q '"recommendation":"block"'; then
1836
+ SUMMARY=$(echo "$CHECK" | python3 -c "import sys,json; print(json.load(sys.stdin).get('summary','Coherence check failed'))" 2>/dev/null || echo "Coherence check failed")
1837
+ echo "BLOCKED: Coherence gate blocked this action." >&2
1838
+ echo "$SUMMARY" >&2
1839
+ echo "Run POST /coherence/reflect for a detailed self-verification checklist." >&2
1840
+ exit 2
1841
+ fi
1842
+ fi
1843
+ fi
1844
+ done
1845
+
1846
+ # Risky commands — behavior depends on safety level
1847
+ for pattern in "rm -rf \\." "git push --force" "git push -f" "git reset --hard" "git clean -fd" "DROP TABLE" "DROP DATABASE" "TRUNCATE" "DELETE FROM"; do
1848
+ if echo "$INPUT" | grep -qi "$pattern"; then
1849
+ if [ "$SAFETY_LEVEL" -eq 1 ]; then
1850
+ echo "BLOCKED: Potentially destructive command detected: $pattern" >&2
1851
+ echo "Authorization required: Ask the user whether to proceed with this operation." >&2
1852
+ echo "Once they confirm, YOU execute the command — never ask the user to run it themselves." >&2
1853
+ exit 2
1854
+ else
1855
+ IDENTITY=""
1856
+ if [ -f "$INSTAR_DIR/AGENT.md" ]; then
1857
+ IDENTITY=$(head -20 "$INSTAR_DIR/AGENT.md" | tr '\\n' ' ')
1858
+ fi
1859
+ echo "{\\"decision\\":\\"approve\\",\\"additionalContext\\":\\"=== SELF-VERIFICATION REQUIRED ===\\\\nDestructive command detected: $pattern\\\\n\\\\n1. Is this necessary for the current task?\\\\n2. What are the consequences if this goes wrong?\\\\n3. Is there a safer alternative?\\\\n4. Does this align with your principles?\\\\n\\\\nIdentity: $IDENTITY\\\\n\\\\nIf ALL checks pass, proceed. If ANY fails, stop.\\\\n=== END SELF-VERIFICATION ===\\"}"
1860
+ exit 0
1861
+ fi
1862
+ fi
1863
+ done
1864
+ `;
1865
+ }
1866
+ getGroundingBeforeMessaging() {
1867
+ return `#!/bin/bash
1868
+ # Grounding before messaging — ensures the agent is grounded and message is
1869
+ # quality-checked before sending any external communication.
1870
+ #
1871
+ # Three-phase defense:
1872
+ # 1. Identity injection — re-ground the agent in who they are
1873
+ # 2. Convergence check — heuristic quality gate on the message content
1874
+ # 3. URL provenance — verify URLs aren't fabricated
1875
+ #
1876
+ # Structure > Willpower: these checks run automatically before
1877
+ # external messaging, not when the agent remembers to do them.
1878
+ #
1879
+ # The 164th Lesson (Dawn): Advisory hooks are insufficient.
1880
+ # Grounding must be automatic — content injected, not pointed to.
1881
+ #
1882
+ # Installed by instar during setup. Runs as a Claude Code PreToolUse hook on Bash.
1883
+
1884
+ INPUT="$1"
1885
+
1886
+ # Detect messaging commands (telegram-reply, email sends, API message posts, etc.)
1887
+ if echo "$INPUT" | grep -qE "(telegram-reply|send-email|send-message|POST.*/telegram/reply|POST.*/message|/reply)"; then
1888
+ INSTAR_DIR="\${CLAUDE_PROJECT_DIR:-.}/.instar"
1889
+ SCRIPTS_DIR="$INSTAR_DIR/scripts"
1890
+
1891
+ # Phase 1: Identity injection (Structure > Willpower — output content, not pointers)
1892
+ if [ -f "$INSTAR_DIR/AGENT.md" ]; then
1893
+ echo "=== PRE-MESSAGE GROUNDING ==="
1894
+ echo ""
1895
+ echo "--- YOUR IDENTITY ---"
1896
+ cat "$INSTAR_DIR/AGENT.md"
1897
+ echo ""
1898
+ echo "--- END IDENTITY ---"
1899
+ echo ""
1900
+ fi
1901
+
1902
+ # Phase 2: Convergence check (heuristic quality gate)
1903
+ if [ -f "$SCRIPTS_DIR/convergence-check.sh" ]; then
1904
+ # Pipe the full tool input through the convergence check.
1905
+ # The check looks for common agent failure modes (capability claims,
1906
+ # sycophancy, settling, experiential fabrication, commitment overreach,
1907
+ # URL provenance).
1908
+ CHECK_RESULT=$(echo "$INPUT" | bash "$SCRIPTS_DIR/convergence-check.sh" 2>&1)
1909
+ CHECK_EXIT=$?
1910
+
1911
+ if [ "$CHECK_EXIT" -ne "0" ]; then
1912
+ echo "$CHECK_RESULT"
1913
+ echo ""
1914
+ echo "=== MESSAGE BLOCKED — Review and revise before sending. ==="
1915
+ exit 2
1916
+ fi
1917
+ fi
1918
+
1919
+ echo "=== GROUNDED — Proceed with message. ==="
1920
+ fi
1921
+ `;
1922
+ }
1923
+ getConvergenceCheckInline() {
1924
+ // Inline fallback — used if template file can't be found.
1925
+ // The primary getConvergenceCheck() reads from the template file.
1926
+ const script = [
1927
+ '#!/bin/bash',
1928
+ '# Lightweight convergence check — heuristic content quality gate before messaging.',
1929
+ '# No LLM calls. Fast. Catches the most common agent failure modes.',
1930
+ '#',
1931
+ '# Usage: echo "message content" | bash .instar/scripts/convergence-check.sh',
1932
+ '# Exit codes: 0 = converged (safe to send), 1 = issues found (review needed)',
1933
+ '#',
1934
+ '# Checks 7 criteria via pattern matching:',
1935
+ '#',
1936
+ '# 1. capability_claims — Claims about what the agent can\'t do (may be wrong)',
1937
+ '# 2. commitment_overreach — Promises the agent may not be able to keep',
1938
+ '# 3. settling — Accepting empty/failed results without investigation',
1939
+ '# 4. experiential_fabrication — Claiming to see/read/feel without verification',
1940
+ '# 5. sycophancy — Reflexive agreement, excessive apology, capitulation',
1941
+ '# 6. url_provenance — URLs with unfamiliar domains that may be fabricated',
1942
+ '# 7. temporal_staleness — Language suggesting outdated perspective or stale draft',
1943
+ '#',
1944
+ '# This is Structure > Willpower: the check runs automatically before',
1945
+ '# external messaging, not when the agent remembers to do it.',
1946
+ '',
1947
+ 'CONTENT=$(cat)',
1948
+ 'ISSUES=()',
1949
+ 'ISSUE_COUNT=0',
1950
+ '',
1951
+ '# 1. CAPABILITY CLAIMS — Watch for "I can\'t" / "I don\'t have" / "not available"',
1952
+ 'if echo "$CONTENT" | grep -qiE "(unfortunately.{0,20}(i can.t|i.m unable|not (possible|available|supported))|i don.t have (the ability|access|a way)|this (isn.t|is not) (possible|available|supported))"; then',
1953
+ ' ISSUES+=("CAPABILITY: You\'re claiming a limitation. Did you check /capabilities first? Many \'I can\'t\' statements are wrong — verify before sending.")',
1954
+ ' ISSUE_COUNT=$((ISSUE_COUNT + 1))',
1955
+ 'fi',
1956
+ '',
1957
+ '# 2. COMMITMENT OVERREACH — Promises that may not survive session boundaries',
1958
+ 'if echo "$CONTENT" | grep -qiE "(i.ll (make sure|ensure|guarantee|always|never forget)|i (promise|commit to|will always)|you can count on me to|i.ll remember (to|this)|from now on i.ll)"; then',
1959
+ ' ISSUES+=("COMMITMENT: You\'re making a promise that may not survive context compaction or session end. Can your infrastructure actually keep this commitment? If not, reframe as intent rather than guarantee.")',
1960
+ ' ISSUE_COUNT=$((ISSUE_COUNT + 1))',
1961
+ 'fi',
1962
+ '',
1963
+ '# 3. SETTLING — Accepting empty results without digging deeper',
1964
+ 'if echo "$CONTENT" | grep -qiE "(no (data|results|information) (available|found|exists)|nothing (to report|happened|was found)|there (is|are) no|could(n.t| not) find (any|the)|appears to be empty|no (relevant|matching|applicable))"; then',
1965
+ ' ISSUES+=("SETTLING: You\'re reporting nothing found. Did you check multiple sources? Could the data source be stale or the search terms wrong? Empty results deserve investigation, not acceptance.")',
1966
+ ' ISSUE_COUNT=$((ISSUE_COUNT + 1))',
1967
+ 'fi',
1968
+ '',
1969
+ '# 4. EXPERIENTIAL FABRICATION — Claiming first-person experience without tool verification',
1970
+ 'if echo "$CONTENT" | grep -qiE "(i (can see|noticed|observed|felt|sensed|perceived) (that |the |a |an )|looking at (this|the|your)|from what i.ve (seen|read|observed)|i.ve (reviewed|examined|analyzed|inspected) (the|your|this))"; then',
1971
+ ' ISSUES+=("EXPERIENTIAL: You\'re claiming a first-person experience. Did you actually access this data with a tool in THIS session, or are you completing a social script? Verify before claiming.")',
1972
+ ' ISSUE_COUNT=$((ISSUE_COUNT + 1))',
1973
+ 'fi',
1974
+ '',
1975
+ '# 5. SYCOPHANCY — Reflexive agreement, excessive apology',
1976
+ 'if echo "$CONTENT" | grep -qiE "(you.re (absolutely|totally|completely) right|i (completely|totally|fully) (agree|understand)|great (question|point|observation)|i apologize for|sorry.{0,20}(mistake|confusion|error|oversight)|that.s (a |an )?(excellent|great|wonderful|fantastic) (point|question|idea|suggestion))"; then',
1977
+ ' ISSUES+=("SYCOPHANCY: You may be reflexively agreeing or over-apologizing. If you genuinely agree, state why. If you don\'t fully agree, say what you actually think. Politeness is not a substitute for honesty.")',
1978
+ ' ISSUE_COUNT=$((ISSUE_COUNT + 1))',
1979
+ 'fi',
1980
+ '',
1981
+ '# 6. URL PROVENANCE — URLs with unfamiliar domains may be fabricated',
1982
+ '# Common confabulation: agent constructs plausible URL from project name',
1983
+ '# (e.g., "deepsignal.xyz" from project "deep-signal"). Catch and require verification.',
1984
+ 'URLS_IN_MSG=$(echo "$CONTENT" | grep -oE \'https?://[^ )"' + "'" + '>]+\' 2>/dev/null || true)',
1985
+ 'if [ -n "$URLS_IN_MSG" ]; then',
1986
+ ' UNFAMILIAR_URLS=""',
1987
+ ' while IFS= read -r url; do',
1988
+ ' [ -z "$url" ] && continue',
1989
+ ' # Skip well-known service domains',
1990
+ ' if echo "$url" | grep -qE \'(github\\.com|vercel\\.app|vercel\\.com|netlify\\.app|netlify\\.com|npmjs\\.com|npmjs\\.org|cloudflare\\.com|google\\.com|twitter\\.com|x\\.com|youtube\\.com|reddit\\.com|discord\\.com|discord\\.gg|telegram\\.org|t\\.me|localhost|127\\.0\\.0\\.1|stackoverflow\\.com|developer\\.mozilla\\.org|docs\\.anthropic\\.com|anthropic\\.com|openai\\.com|claude\\.ai|notion\\.so|linear\\.app|fly\\.io|render\\.com|railway\\.app|heroku\\.com|amazonaws\\.com|azure\\.com|gitlab\\.com|bitbucket\\.org|docker\\.com|hub\\.docker\\.com|pypi\\.org|crates\\.io|rubygems\\.org|pkg\\.go\\.dev|wikipedia\\.org|medium\\.com|substack\\.com|circle\\.so|ghost\\.io|telegraph\\.ph)\'; then',
1991
+ ' continue',
1992
+ ' fi',
1993
+ ' UNFAMILIAR_URLS="$UNFAMILIAR_URLS $url\\n"',
1994
+ ' done <<< "$URLS_IN_MSG"',
1995
+ '',
1996
+ ' if [ -n "$UNFAMILIAR_URLS" ]; then',
1997
+ ' ISSUES+=("URL_PROVENANCE: Your message contains URLs with unfamiliar domains:\\n${UNFAMILIAR_URLS}Before including a URL, verify it appeared in actual tool output in THIS session OR confirm it resolves with curl. A common confabulation: constructing domains from project names (e.g., \'deepsignal.xyz\' from project \'deep-signal\').")',
1998
+ ' ISSUE_COUNT=$((ISSUE_COUNT + 1))',
1999
+ ' fi',
2000
+ 'fi',
2001
+ '',
2002
+ '# 7. TEMPORAL STALENESS — Language suggesting outdated perspective or stale draft',
2003
+ 'if echo "$CONTENT" | grep -qiE "(i used to (think|believe|feel|assume)|back when i (first|started|was new)|at (that|the) time i|my (early|earlier|initial|original|first) (understanding|thinking|view|perspective|approach)|i didn.t yet understand|before i (learned|realized|discovered|knew)|i (once|previously) (thought|believed|felt)|this was (before|when) i)"; then',
2004
+ ' ISSUES+=("TEMPORAL: Your message references past understanding or earlier perspectives. Is this content from an older draft? If your thinking has evolved since writing this, revise to reflect your current understanding before publishing.")',
2005
+ ' ISSUE_COUNT=$((ISSUE_COUNT + 1))',
2006
+ 'fi',
2007
+ '',
2008
+ '# Output results',
2009
+ 'if [ "$ISSUE_COUNT" -gt "0" ]; then',
2010
+ ' echo "=== CONVERGENCE CHECK: ${ISSUE_COUNT} ISSUE(S) FOUND ==="',
2011
+ ' echo ""',
2012
+ ' for ISSUE in "${ISSUES[@]}"; do',
2013
+ ' echo " - $ISSUE"',
2014
+ ' echo ""',
2015
+ ' done',
2016
+ ' echo "Review and revise before sending. Re-run this check after revision."',
2017
+ ' echo "=== END CONVERGENCE CHECK ==="',
2018
+ ' exit 1',
2019
+ 'else',
2020
+ ' exit 0',
2021
+ 'fi',
2022
+ ].join('\n');
2023
+ return script;
2024
+ }
2025
+ getTelegramTopicContextHook() {
2026
+ return `#!/bin/bash
2027
+ # UserPromptSubmit Hook: Auto-inject Telegram topic history context.
2028
+ #
2029
+ # When a user prompt contains [telegram:N], this hook reads the recent
2030
+ # conversation history for that topic and injects it as context. Also
2031
+ # detects unanswered user messages and surfaces them with directives.
2032
+ #
2033
+ # This prevents the "what are we talking about?" failure after compaction
2034
+ # or session restart — where the agent receives a message without
2035
+ # conversation context and responds with a generic greeting.
2036
+
2037
+ # Read the user prompt from stdin (Claude Code pipes JSON with { prompt: "..." })
2038
+ USER_PROMPT=\$(python3 -c "
2039
+ import sys, json
2040
+ try:
2041
+ data = json.load(sys.stdin)
2042
+ print(data.get('prompt', ''))
2043
+ except:
2044
+ print('')
2045
+ " 2>/dev/null)
2046
+
2047
+ # Check for [telegram:N] prefix
2048
+ TOPIC_ID=\$(echo "\$USER_PROMPT" | python3 -c "
2049
+ import sys, re
2050
+ line = sys.stdin.read()
2051
+ m = re.search(r'\\\\[telegram:(\\\\d+)', line)
2052
+ if m:
2053
+ print(m.group(1))
2054
+ " 2>/dev/null)
2055
+
2056
+ if [ -z "\$TOPIC_ID" ]; then
2057
+ exit 0
2058
+ fi
2059
+
2060
+ # Get server port from config
2061
+ INSTAR_DIR="\${CLAUDE_PROJECT_DIR:-.}/.instar"
2062
+ CONFIG_FILE="\$INSTAR_DIR/config.json"
2063
+
2064
+ if [ ! -f "\$CONFIG_FILE" ]; then
2065
+ exit 0
2066
+ fi
2067
+
2068
+ PORT=\$(grep -o '"port":[0-9]*' "\$CONFIG_FILE" | head -1 | cut -d':' -f2)
2069
+ if [ -z "\$PORT" ]; then
2070
+ exit 0
2071
+ fi
2072
+
2073
+ # Check server health
2074
+ HEALTH=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\${PORT}/health" 2>/dev/null)
2075
+ if [ "\$HEALTH" != "200" ]; then
2076
+ exit 0
2077
+ fi
2078
+
2079
+ # Fetch recent messages for this topic
2080
+ AUTH_TOKEN=\$(python3 -c "import json; print(json.load(open('\$CONFIG_FILE')).get('authToken',''))" 2>/dev/null)
2081
+ if [ -n "\$AUTH_TOKEN" ]; then
2082
+ RECENT_MSGS=\$(curl -s \\
2083
+ -H "Authorization: Bearer \${AUTH_TOKEN}" \\
2084
+ "http://localhost:\${PORT}/telegram/topics/\${TOPIC_ID}/messages?limit=15" 2>/dev/null)
2085
+ else
2086
+ RECENT_MSGS=\$(curl -s \\
2087
+ "http://localhost:\${PORT}/telegram/topics/\${TOPIC_ID}/messages?limit=15" 2>/dev/null)
2088
+ fi
2089
+
2090
+ # Format and output context with unanswered message detection
2091
+ echo "\$RECENT_MSGS" | python3 -c "
2092
+ import sys, json
2093
+ try:
2094
+ data = json.load(sys.stdin)
2095
+ msgs = data.get('messages', [])
2096
+ if not msgs:
2097
+ sys.exit(0)
2098
+
2099
+ print('TOPIC \${TOPIC_ID} RECENT HISTORY (auto-injected):')
2100
+
2101
+ for m in msgs:
2102
+ ts = m.get('timestamp', '')[:16].replace('T', ' ')
2103
+ from_user = m.get('fromUser', m.get('direction', 'in') == 'in')
2104
+ text = m.get('text', '').strip()
2105
+ sender = 'User' if from_user else 'Agent'
2106
+ if len(text) > 300:
2107
+ text = text[:297] + '...'
2108
+ print(f' [{ts}] {sender}: {text}')
2109
+
2110
+ # Detect unanswered user messages
2111
+ pending_user = []
2112
+ for m in msgs:
2113
+ text = m.get('text', '').strip()
2114
+ if not text:
2115
+ continue
2116
+ from_user = m.get('fromUser', m.get('direction', 'in') == 'in')
2117
+ if from_user:
2118
+ pending_user.append(m)
2119
+ else:
2120
+ pending_user = []
2121
+
2122
+ if pending_user:
2123
+ print()
2124
+ print('*** UNANSWERED MESSAGE(S) FROM USER ***')
2125
+ for pm in pending_user:
2126
+ pm_text = pm.get('text', '')[:200]
2127
+ pm_ts = pm.get('timestamp', '')[:16].replace('T', ' ')
2128
+ print(f' [{pm_ts}] \\\\\\\"{pm_text}\\\\\\\"')
2129
+ print()
2130
+ print('You MUST address these messages substantively. Do NOT respond with just')
2131
+ print('a greeting or generic reply. Read the conversation history above and')
2132
+ print('respond to what the user actually said. If the current message is a')
2133
+ print('follow-up like \\\\\\\"hello?\\\\\\\" or \\\\\\\"please respond\\\\\\\", address the EARLIER')
2134
+ print('unanswered message — that is what the user is waiting for.')
2135
+ except Exception:
2136
+ pass
2137
+ " 2>/dev/null
2138
+
2139
+ exit 0
2140
+ `;
2141
+ }
2142
+ getCompactionRecovery() {
2143
+ return `#!/bin/bash
2144
+ # Compaction recovery — re-injects identity AND topic context when Claude's context compresses.
2145
+ # Born from Dawn's 164th Lesson: "Advisory hooks get ignored. Automatic content
2146
+ # injection removes the compliance gap entirely."
2147
+ #
2148
+ # This hook OUTPUTS identity content directly into context rather than just
2149
+ # pointing to files. After compaction, the agent needs to KNOW who it is
2150
+ # AND what conversation it's in — not be told where to look.
2151
+ #
2152
+ # Context priority (same as session-start):
2153
+ # 1. Topic context (summary + recent messages) — what are we working on?
2154
+ # 2. Identity (AGENT.md) — who am I?
2155
+ # 3. Memory (MEMORY.md) — what have I learned?
2156
+ # 4. Telegram relay — how do I respond?
2157
+ # 5. Capabilities — what can I do?
2158
+ INSTAR_DIR="\${CLAUDE_PROJECT_DIR:-.}/.instar"
2159
+
2160
+ echo "=== IDENTITY RECOVERY (post-compaction) ==="
2161
+
2162
+ # ── 1. TOPIC CONTEXT (highest priority — what are we working on?) ──
2163
+ # After compaction, the conversation history is lost. Re-inject it from TopicMemory.
2164
+ if [ -n "\$INSTAR_TELEGRAM_TOPIC" ]; then
2165
+ TOPIC_ID="\$INSTAR_TELEGRAM_TOPIC"
2166
+ CONFIG_FILE="\$INSTAR_DIR/config.json"
2167
+ if [ -f "\$CONFIG_FILE" ]; then
2168
+ PORT=\$(grep -o '"port":[0-9]*' "\$CONFIG_FILE" | head -1 | cut -d':' -f2)
2169
+ if [ -n "\$PORT" ]; then
2170
+ TOPIC_CTX=\$(curl -s "http://localhost:\${PORT}/topic/context/\${TOPIC_ID}?recent=20" 2>/dev/null)
2171
+ if [ -n "\$TOPIC_CTX" ] && echo "\$TOPIC_CTX" | grep -q '"totalMessages"'; then
2172
+ TOTAL=\$(echo "\$TOPIC_CTX" | grep -o '"totalMessages":[0-9]*' | cut -d':' -f2)
2173
+ TOPIC_NAME=\$(echo "\$TOPIC_CTX" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('topicName') or 'Unknown')" 2>/dev/null || echo "Unknown")
2174
+
2175
+ echo ""
2176
+ echo "--- CONVERSATION CONTEXT (Topic: \${TOPIC_NAME}, \${TOTAL} total messages) ---"
2177
+ echo ""
2178
+
2179
+ SUMMARY=\$(echo "\$TOPIC_CTX" | python3 -c "import sys,json; d=json.load(sys.stdin); s=d.get('summary'); print(s if s else '')" 2>/dev/null)
2180
+ if [ -n "\$SUMMARY" ]; then
2181
+ echo "SUMMARY OF CONVERSATION SO FAR:"
2182
+ echo "\$SUMMARY"
2183
+ echo ""
2184
+ fi
2185
+
2186
+ echo "RECENT MESSAGES:"
2187
+ echo "\$TOPIC_CTX" | python3 -c "
2188
+ import sys, json
2189
+ d = json.load(sys.stdin)
2190
+ msgs = d.get('recentMessages', [])
2191
+ for m in msgs:
2192
+ sender = 'User' if m.get('fromUser') else 'Agent'
2193
+ ts = m.get('timestamp', '')[:16].replace('T', ' ')
2194
+ text = m.get('text', '')
2195
+ if len(text) > 500:
2196
+ text = text[:500] + '...'
2197
+ print(f'[{ts}] {sender}: {text}')
2198
+
2199
+ # Detect unanswered user messages
2200
+ pending_user = []
2201
+ for m in msgs:
2202
+ text = m.get('text', '').strip()
2203
+ if not text:
2204
+ continue
2205
+ if m.get('fromUser'):
2206
+ pending_user.append(m)
2207
+ else:
2208
+ pending_user = []
2209
+
2210
+ if pending_user:
2211
+ print()
2212
+ print('!' * 60)
2213
+ print('UNANSWERED MESSAGE(S) FROM USER:')
2214
+ for pm in pending_user:
2215
+ pm_text = pm.get('text', '')[:200]
2216
+ pm_ts = pm.get('timestamp', '')[:16].replace('T', ' ')
2217
+ print(f' [{pm_ts}] \\\"{pm_text}\\\"')
2218
+ print()
2219
+ print('You MUST address these messages substantively. Do NOT respond')
2220
+ print('with just a greeting or generic reply. If the latest message')
2221
+ print('is a follow-up like \\\"hello?\\\" or \\\"please respond\\\", address')
2222
+ print('the EARLIER unanswered message — that is what the user is')
2223
+ print('waiting for.')
2224
+ print('!' * 60)
2225
+ " 2>/dev/null
2226
+ echo ""
2227
+ echo "Search past conversations: curl http://localhost:\${PORT}/topic/search?topic=\${TOPIC_ID}&q=QUERY"
2228
+ echo "--- END CONVERSATION CONTEXT ---"
2229
+ echo ""
2230
+ fi
2231
+ fi
2232
+ fi
2233
+ fi
2234
+
2235
+ # ── 2. IDENTITY (full AGENT.md — who am I?) ──
2236
+ if [ -f "\$INSTAR_DIR/AGENT.md" ]; then
2237
+ echo ""
2238
+ echo "--- Your Identity (from .instar/AGENT.md) ---"
2239
+ cat "\$INSTAR_DIR/AGENT.md"
2240
+ echo ""
2241
+ echo "--- End Identity ---"
2242
+ fi
2243
+
2244
+ # ── 2b. PROJECT CONTEXT (where am I working?) ──
2245
+ if [ -f "\$INSTAR_DIR/project-map.json" ]; then
2246
+ echo ""
2247
+ echo "--- PROJECT CONTEXT ---"
2248
+ python3 -c "
2249
+ import json, sys
2250
+ try:
2251
+ m = json.load(open('\$INSTAR_DIR/project-map.json'))
2252
+ print(f'Project: {m[\"projectName\"]} ({m[\"projectType\"]})')
2253
+ print(f'Path: {m[\"projectDir\"]}')
2254
+ r = m.get('gitRemote')
2255
+ b = m.get('gitBranch')
2256
+ if r: print(f'Git: {r}' + (f' [{b}]' if b else ''))
2257
+ t = m.get('deploymentTargets', [])
2258
+ if t: print(f'Deploy targets: {(\", \").join(t)}')
2259
+ print(f'Files: {m[\"totalFiles\"]} across {len(m.get(\"directories\", []))} directories')
2260
+ except Exception as e:
2261
+ print(f'(project map load failed: {e})', file=sys.stderr)
2262
+ " 2>/dev/null
2263
+ echo "--- END PROJECT CONTEXT ---"
2264
+ fi
2265
+
2266
+ # ── 3. MEMORY (first 50 lines — what have I learned?) ──
2267
+ if [ -f "\$INSTAR_DIR/MEMORY.md" ]; then
2268
+ LINES=\$(wc -l < "\$INSTAR_DIR/MEMORY.md" | tr -d ' ')
2269
+ echo ""
2270
+ echo "--- Your Memory (.instar/MEMORY.md — \${LINES} lines, showing first 50) ---"
2271
+ head -50 "\$INSTAR_DIR/MEMORY.md"
2272
+ if [ "\$LINES" -gt 50 ]; then
2273
+ echo "... (\$((LINES - 50)) more lines — read full file if needed)"
2274
+ fi
2275
+ echo "--- End Memory ---"
2276
+ fi
2277
+
2278
+ # ── 4. TELEGRAM RELAY (how do I respond?) ──
2279
+ if [ -n "\$INSTAR_TELEGRAM_TOPIC" ]; then
2280
+ TOPIC_ID="\$INSTAR_TELEGRAM_TOPIC"
2281
+ RELAY_SCRIPT=""
2282
+ if [ -f "\$INSTAR_DIR/scripts/telegram-reply.sh" ]; then
2283
+ RELAY_SCRIPT=".instar/scripts/telegram-reply.sh"
2284
+ elif [ -f "\${CLAUDE_PROJECT_DIR:-.}/.claude/scripts/telegram-reply.sh" ]; then
2285
+ RELAY_SCRIPT=".claude/scripts/telegram-reply.sh"
2286
+ fi
2287
+
2288
+ echo ""
2289
+ echo "--- TELEGRAM SESSION (topic \${TOPIC_ID}) ---"
2290
+ echo "This session is connected to Telegram topic \${TOPIC_ID}."
2291
+ echo "Messages arrive prefixed with [telegram:\${TOPIC_ID}]. Strip prefix before interpreting."
2292
+ echo "After EVERY response, relay your text back:"
2293
+ if [ -n "\$RELAY_SCRIPT" ]; then
2294
+ echo " cat <<'EOF' | \${RELAY_SCRIPT} \${TOPIC_ID}"
2295
+ else
2296
+ echo " cat <<'EOF' | .instar/scripts/telegram-reply.sh \${TOPIC_ID}"
2297
+ fi
2298
+ echo " Your response text here"
2299
+ echo " EOF"
2300
+ echo "--- END TELEGRAM SESSION ---"
2301
+ fi
2302
+
2303
+ # ── 5. SERVER STATUS + CAPABILITIES ──
2304
+ CONFIG_FILE="\$INSTAR_DIR/config.json"
2305
+ if [ -f "\$CONFIG_FILE" ]; then
2306
+ PORT=\$(python3 -c "import json; print(json.load(open('\$CONFIG_FILE')).get('port', 4040))" 2>/dev/null || echo "4040")
2307
+ HEALTH=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\${PORT}/health" 2>/dev/null)
2308
+ if [ "\$HEALTH" = "200" ]; then
2309
+ echo ""
2310
+ echo "Instar server: RUNNING on port \${PORT}"
2311
+ CAPS=\$(curl -s "http://localhost:\${PORT}/capabilities" 2>/dev/null)
2312
+ if echo "\$CAPS" | grep -q '"featureGuide"' 2>/dev/null; then
2313
+ echo ""
2314
+ echo "--- YOUR CAPABILITIES ---"
2315
+ echo "\$CAPS" | python3 -c "
2316
+ import sys, json
2317
+ try:
2318
+ d = json.load(sys.stdin)
2319
+ guide = d.get('featureGuide', {})
2320
+ for t in guide.get('triggers', []):
2321
+ print(f' When: {t[\"context\"]}')
2322
+ print(f' Do: {t[\"action\"]}')
2323
+ print()
2324
+ except: pass
2325
+ " 2>/dev/null
2326
+ echo "--- END CAPABILITIES ---"
2327
+ fi
2328
+
2329
+ # Context dispatch table — structural "when X, read Y" routing
2330
+ DISPATCH_FILE="\$INSTAR_DIR/context/DISPATCH.md"
2331
+ if [ -f "\$DISPATCH_FILE" ]; then
2332
+ echo ""
2333
+ echo "--- CONTEXT DISPATCH (when X arises, read Y) ---"
2334
+ cat "\$DISPATCH_FILE" | head -20
2335
+ echo "--- END CONTEXT DISPATCH ---"
2336
+ fi
2337
+ else
2338
+ echo ""
2339
+ echo "Instar server: NOT RUNNING (port \${PORT})"
2340
+ fi
2341
+ fi
2342
+
2343
+ echo ""
2344
+
2345
+ # Working Memory — surface relevant knowledge after compaction
2346
+ # This restores what you knew before compaction that's relevant now.
2347
+ if [ -f "$INSTAR_DIR/config.json" ]; then
2348
+ PORT=\$(grep -o '"port":[0-9]*' "$INSTAR_DIR/config.json" | head -1 | cut -d':' -f2)
2349
+ if [ -n "\$PORT" ]; then
2350
+ AUTH_TOKEN=\$(python3 -c "import json; print(json.load(open('$INSTAR_DIR/config.json')).get('authToken',''))" 2>/dev/null)
2351
+ HEALTH=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\${PORT}/health" 2>/dev/null)
2352
+ if [ "\$HEALTH" = "200" ]; then
2353
+ WM_QUERY=\$(python3 -c "import urllib.parse; print(urllib.parse.quote('compaction-recovery context-restoration'))" 2>/dev/null)
2354
+ WORKING_MEM=\$(curl -s -H "Authorization: Bearer \${AUTH_TOKEN}" \
2355
+ "http://localhost:\${PORT}/context/working-memory?prompt=\${WM_QUERY}&limit=6" 2>/dev/null)
2356
+ if [ -n "\$WORKING_MEM" ]; then
2357
+ WM_CONTEXT=\$(echo "\$WORKING_MEM" | python3 -c "
2358
+ import sys, json
2359
+ try:
2360
+ data = json.load(sys.stdin)
2361
+ ctx = data.get('context', '').strip()
2362
+ tokens = data.get('estimatedTokens', 0)
2363
+ sources = data.get('sources', [])
2364
+ if ctx and tokens > 0:
2365
+ src_summary = ', '.join(f'{s[\\\"count\\\"]} {s[\\\"name\\\"]}' for s in sources if s.get('count', 0) > 0)
2366
+ print(f'[{tokens} tokens from: {src_summary}]')
2367
+ print()
2368
+ print(ctx)
2369
+ except Exception:
2370
+ pass
2371
+ " 2>/dev/null)
2372
+ if [ -n "\$WM_CONTEXT" ]; then
2373
+ echo "--- WORKING MEMORY RESTORED ---"
2374
+ echo "\$WM_CONTEXT"
2375
+ echo "--- END WORKING MEMORY ---"
2376
+ echo ""
2377
+ fi
2378
+ fi
2379
+ fi
2380
+ fi
2381
+ fi
2382
+
2383
+ echo "=== END IDENTITY RECOVERY ==="
2384
+ `;
2385
+ }
2386
+ getDeferralDetectorHook() {
2387
+ return `#!/usr/bin/env node
2388
+ // Deferral detector — catches agents deferring work they could do themselves.
2389
+ // PreToolUse hook for Bash commands. Scans outgoing messages for deferral patterns.
2390
+ // When detected, injects a due diligence checklist (does NOT block).
2391
+ //
2392
+ // Born from an agent saying "This is credential input I cannot do myself"
2393
+ // when it already had the token available via CLI tools.
2394
+
2395
+ let data = '';
2396
+ process.stdin.on('data', chunk => data += chunk);
2397
+ process.stdin.on('end', () => {
2398
+ try {
2399
+ const input = JSON.parse(data);
2400
+ if (input.tool_name !== 'Bash') process.exit(0);
2401
+
2402
+ const command = (input.tool_input || {}).command || '';
2403
+ if (!command) process.exit(0);
2404
+
2405
+ // Only check communication commands (messages to humans)
2406
+ const commPatterns = [
2407
+ /telegram-reply/i, /send-email/i, /send-message/i,
2408
+ /POST.*\\/telegram\\/reply/i, /slack.*send/i
2409
+ ];
2410
+ if (!commPatterns.some(p => p.test(command))) process.exit(0);
2411
+
2412
+ // Exempt: genuinely human-only actions
2413
+ if (/password|captcha|legal|billing|payment credential/i.test(command)) process.exit(0);
2414
+
2415
+ // Deferral patterns
2416
+ const patterns = [
2417
+ { re: /(?:I |i )(?:can'?t|cannot|am (?:not |un)able to)/i, type: 'inability_claim' },
2418
+ { re: /(?:this |it )(?:requires|needs) (?:your|human|manual) (?:input|intervention|action)/i, type: 'human_required' },
2419
+ { re: /you(?:'ll| will)? need to (?:do|handle|complete|input|enter|run|execute|click)/i, type: 'directing_human' },
2420
+ { re: /(?:you (?:can|could|should|might want to) )(?:run|execute|navigate|open|click)/i, type: 'suggesting_human_action' },
2421
+ { re: /(?:want me to|should I|shall I|would you like me to) (?:proceed|continue|go ahead)/i, type: 'permission_seeking' },
2422
+ { re: /(?:blocker|blocking issue|can'?t proceed (?:without|until))/i, type: 'claimed_blocker' },
2423
+ ];
2424
+
2425
+ const matches = patterns.filter(p => p.re.test(command));
2426
+ if (matches.length === 0) process.exit(0);
2427
+
2428
+ const checklist = [
2429
+ 'DEFERRAL DETECTED — Before claiming you cannot do something, verify:',
2430
+ '',
2431
+ '1. Did you check --help or docs for the tool you are using?',
2432
+ '2. Did you search for a token/API-based alternative to interactive auth?',
2433
+ '3. Do you already have credentials/tokens that might work? (env vars, CLI auth, saved configs)',
2434
+ '4. Can you use browser automation to complete interactive flows?',
2435
+ '5. Is this GENUINELY beyond your access? (e.g., typing a password, solving a CAPTCHA)',
2436
+ '',
2437
+ 'If ANY check might work — try it first.',
2438
+ 'The pattern: You are DESCRIBING work instead of DOING work.',
2439
+ '',
2440
+ 'Detected: ' + matches.map(m => m.type).join(', '),
2441
+ ].join('\\n');
2442
+
2443
+ process.stdout.write(JSON.stringify({ decision: 'approve', additionalContext: checklist }));
2444
+ } catch { /* don't break on errors */ }
2445
+ process.exit(0);
2446
+ });
2447
+ `;
2448
+ }
2449
+ getPostActionReflectionHook() {
2450
+ return `#!/usr/bin/env node
2451
+ // Post-action reflection — evolution awareness after significant actions.
2452
+ // PostToolUse hook for Bash. When the agent commits, deploys, or
2453
+ // completes a task, captures the step for Living Skills and injects
2454
+ // a brief reminder to capture learnings.
2455
+ //
2456
+ // "Every action is an opportunity to learn. Most of that learning is lost
2457
+ // because nobody paused to ask: what did this teach me?"
2458
+
2459
+ const fs = require('node:fs');
2460
+ const pathMod = require('node:path');
2461
+
2462
+ let data = '';
2463
+ process.stdin.on('data', chunk => data += chunk);
2464
+ process.stdin.on('end', () => {
2465
+ try {
2466
+ const input = JSON.parse(data);
2467
+ if (input.tool_name !== 'Bash') process.exit(0);
2468
+
2469
+ const command = (input.tool_input || {}).command || '';
2470
+ if (!command) process.exit(0);
2471
+
2472
+ // Significant action patterns — moments worth reflecting on
2473
+ const significantPatterns = [
2474
+ /git\\s+commit/i,
2475
+ /git\\s+push/i,
2476
+ /npm\\s+publish/i,
2477
+ /curl/i,
2478
+ /docker/i,
2479
+ /deploy/i,
2480
+ /prisma/i,
2481
+ /psql/i,
2482
+ /npm\\s+run\\s+build/i,
2483
+ /npm\\s+test/i,
2484
+ /instar\\s+server\\s+restart/i,
2485
+ ];
2486
+
2487
+ const isSignificant = significantPatterns.some(p => p.test(command));
2488
+
2489
+ // Living Skills: capture step to pending journal if enabled
2490
+ const cwd = input.cwd || process.cwd();
2491
+ const sessionId = process.env.INSTAR_SESSION_ID || '';
2492
+ const jobSlug = process.env.INSTAR_JOB_SLUG || '';
2493
+
2494
+ if (isSignificant && sessionId && jobSlug) {
2495
+ // Check for sentinel file (created by JobScheduler when livingSkills.enabled)
2496
+ const instarDir = process.env.INSTAR_STATE_DIR || pathMod.join(cwd, '.instar');
2497
+ const sentinelPath = pathMod.join(instarDir, 'state', 'execution-journal', '_ls-enabled-' + jobSlug);
2498
+
2499
+ try {
2500
+ if (fs.existsSync(sentinelPath)) {
2501
+ // Sanitize command before writing
2502
+ const REDACT = [
2503
+ /Bearer\\s+[A-Za-z0-9\\-._~+\\/]+=*/gi,
2504
+ /Authorization:\\s*[^\\s"']*/gi,
2505
+ /(api[_-]?key|apikey|api_secret)\\s*[:=]\\s*\\S+/gi,
2506
+ /(password|passwd|secret|token)\\s*[:=]\\s*\\S+/gi,
2507
+ /sk-[A-Za-z0-9]{20,}/g,
2508
+ /ghp_[A-Za-z0-9]{36}/g,
2509
+ /xox[baprs]-[A-Za-z0-9\\-]+/g,
2510
+ ];
2511
+ let sanitized = command;
2512
+ for (const p of REDACT) { p.lastIndex = 0; sanitized = sanitized.replace(p, '[REDACTED]'); }
2513
+ sanitized = sanitized.slice(0, 500);
2514
+
2515
+ const pendingFile = pathMod.join(instarDir, 'state', 'execution-journal', '_pending.' + sessionId + '.jsonl');
2516
+ fs.mkdirSync(pathMod.dirname(pendingFile), { recursive: true });
2517
+ const entry = {
2518
+ sessionId,
2519
+ jobSlug,
2520
+ timestamp: new Date().toISOString(),
2521
+ command: sanitized,
2522
+ source: 'hook',
2523
+ };
2524
+ fs.appendFileSync(pendingFile, JSON.stringify(entry) + '\\n');
2525
+ }
2526
+ } catch { /* Living Skills capture failure is non-critical */ }
2527
+ }
2528
+
2529
+ // Only show reflection reminder for the most significant actions
2530
+ const reflectionPatterns = [
2531
+ /git\\s+commit/i,
2532
+ /git\\s+push/i,
2533
+ /npm\\s+publish/i,
2534
+ /curl\\s+-X\\s+POST.*\\/deploy/i,
2535
+ /instar\\s+server\\s+restart/i,
2536
+ ];
2537
+
2538
+ if (!reflectionPatterns.some(p => p.test(command))) process.exit(0);
2539
+
2540
+ const reminder = [
2541
+ 'POST-ACTION REFLECTION — Quick evolution check:',
2542
+ '',
2543
+ 'Before moving on, consider:',
2544
+ '- Did this teach you something worth recording? → /learn',
2545
+ '- Did you notice a gap in your capabilities? → /gaps',
2546
+ '- Did you discover an improvement opportunity? → /evolve',
2547
+ '- Did you make a commitment to follow up? → /commit-action',
2548
+ '',
2549
+ 'Skip if nothing notable. The value is in the pause, not the output.',
2550
+ ].join('\\n');
2551
+
2552
+ process.stdout.write(JSON.stringify({ decision: 'approve', additionalContext: reminder }));
2553
+ } catch { /* don't break on errors */ }
2554
+ process.exit(0);
2555
+ });
2556
+ `;
2557
+ }
2558
+ getExternalCommunicationGuardHook() {
2559
+ return `#!/usr/bin/env node
2560
+ // External communication guard — identity grounding before external posting.
2561
+ // PreToolUse hook for Bash. Detects external posting commands (curl POST, API calls,
2562
+ // CLI tools that post to external services). Injects identity re-read reminder.
2563
+ //
2564
+ // "An agent that knows itself is harder to compromise."
2565
+ // "An agent that forgets itself posts things it shouldn't."
2566
+
2567
+ let data = '';
2568
+ process.stdin.on('data', chunk => data += chunk);
2569
+ process.stdin.on('end', () => {
2570
+ try {
2571
+ const input = JSON.parse(data);
2572
+ if (input.tool_name !== 'Bash') process.exit(0);
2573
+
2574
+ const command = (input.tool_input || {}).command || '';
2575
+ if (!command) process.exit(0);
2576
+
2577
+ // Patterns that indicate external posting
2578
+ const postingPatterns = [
2579
+ /curl\\s.*-X\\s+POST/i,
2580
+ /curl\\s.*-X\\s+PUT/i,
2581
+ /curl\\s.*-X\\s+PATCH/i,
2582
+ /curl\\s.*-d\\s+['"]/i,
2583
+ /curl\\s.*--data/i,
2584
+ /gh\\s+issue\\s+(?:comment|create)/i,
2585
+ /gh\\s+pr\\s+(?:comment|create|review)/i,
2586
+ /gh\\s+api\\s+graphql.*mutation/i,
2587
+ /sendgrid|mailgun|ses\\.amazonaws.*send/i,
2588
+ /telegram-reply/i,
2589
+ /send-email/i,
2590
+ /slack.*(?:chat\\.postMessage|send)/i,
2591
+ ];
2592
+
2593
+ if (!postingPatterns.some(p => p.test(command))) process.exit(0);
2594
+
2595
+ // Exempt: localhost, internal APIs, health checks
2596
+ if (/localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0/i.test(command)) process.exit(0);
2597
+ if (/curl\\s+-s\\s+https?:\\/\\/[^\\s]+\\s*$/i.test(command)) process.exit(0); // Simple GET
2598
+ if (/heartbeat|keepalive|health/i.test(command)) process.exit(0);
2599
+
2600
+ const reminder = [
2601
+ 'EXTERNAL COMMUNICATION DETECTED — Identity grounding check:',
2602
+ '',
2603
+ 'Before posting externally, verify:',
2604
+ '1. Have you read .instar/AGENT.md recently in this session?',
2605
+ '2. Does this message represent who you are and your principles?',
2606
+ '3. Are you posting something you would stand behind across sessions?',
2607
+ '4. Is the tone and content consistent with your identity?',
2608
+ '',
2609
+ 'Security Through Identity: An agent that knows itself is harder to compromise.',
2610
+ ].join('\\n');
2611
+
2612
+ process.stdout.write(JSON.stringify({ decision: 'approve', additionalContext: reminder }));
2613
+ } catch { /* don't break on errors */ }
2614
+ process.exit(0);
2615
+ });
2616
+ `;
2617
+ }
2618
+ getExternalOperationGateHook() {
2619
+ return `#!/usr/bin/env node
2620
+ // External operation gate — structural safety for external service operations.
2621
+ // PreToolUse hook. Intercepts MCP tool calls to external services and evaluates
2622
+ // risk before allowing execution. Structure > Willpower.
2623
+ //
2624
+ // Born from the OpenClaw email deletion incident: an agent deleted 200+ emails
2625
+ // because nothing distinguished safe reads from destructive bulk deletes.
2626
+ //
2627
+ // Uses global fetch() (Node.js 18+) — no CommonJS imports needed.
2628
+
2629
+ // Read tool input from stdin
2630
+ let data = '';
2631
+ process.stdin.on('data', chunk => data += chunk);
2632
+ process.stdin.on('end', async () => {
2633
+ try {
2634
+ const input = JSON.parse(data);
2635
+ const toolName = input.tool_name || '';
2636
+
2637
+ // Only intercept MCP tools (external service calls)
2638
+ if (!toolName.startsWith('mcp__')) {
2639
+ process.exit(0); // Not an MCP tool — pass through
2640
+ }
2641
+
2642
+ // Extract service name from mcp__<service>__<action>
2643
+ const parts = toolName.split('__');
2644
+ if (parts.length < 3) {
2645
+ process.exit(0); // Malformed MCP tool name — pass through
2646
+ }
2647
+
2648
+ const service = parts[1];
2649
+ const action = parts.slice(2).join('_');
2650
+
2651
+ // Classify mutability from action name
2652
+ let mutability = 'read';
2653
+ if (/^(delete|remove|trash|purge|destroy|drop|clear)/.test(action)) {
2654
+ mutability = 'delete';
2655
+ } else if (/^(send|create|post|write|add|insert|new|compose|publish)/.test(action)) {
2656
+ mutability = 'write';
2657
+ } else if (/^(update|modify|edit|patch|rename|move|change|set|toggle|enable|disable)/.test(action)) {
2658
+ mutability = 'modify';
2659
+ }
2660
+ // Everything else defaults to 'read' (get, list, search, fetch, check, etc.)
2661
+
2662
+ // Read operations are always safe — fast-path
2663
+ if (mutability === 'read') {
2664
+ process.exit(0);
2665
+ }
2666
+
2667
+ // Classify reversibility
2668
+ let reversibility = 'reversible';
2669
+ if (/^(send|publish|post|destroy|purge|drop)/.test(action)) {
2670
+ reversibility = 'irreversible';
2671
+ } else if (/^(delete|remove|trash)/.test(action)) {
2672
+ reversibility = 'partially-reversible';
2673
+ }
2674
+
2675
+ // Estimate item count from tool_input
2676
+ const toolInput = input.tool_input || {};
2677
+ let itemCount = 1;
2678
+ for (const key of Object.keys(toolInput)) {
2679
+ const val = toolInput[key];
2680
+ if (Array.isArray(val)) {
2681
+ itemCount = Math.max(itemCount, val.length);
2682
+ }
2683
+ }
2684
+
2685
+ // Build description
2686
+ const description = action.replace(/_/g, ' ') + ' on ' + service;
2687
+
2688
+ // Read config (port + auth token) via dynamic import to stay ESM-compatible
2689
+ let port = 4321;
2690
+ let authToken = '';
2691
+ try {
2692
+ const nodeFs = await import('node:fs');
2693
+ const configPath = (process.env.CLAUDE_PROJECT_DIR || '.') + '/.instar/config.json';
2694
+ const raw = nodeFs.readFileSync(configPath, 'utf-8');
2695
+ const cfg = JSON.parse(raw);
2696
+ port = cfg.port || 4321;
2697
+ authToken = cfg.authToken || '';
2698
+ } catch { /* use defaults */ }
2699
+
2700
+ // Call the gate API using global fetch (Node 18+)
2701
+ const postData = JSON.stringify({
2702
+ service,
2703
+ mutability,
2704
+ reversibility,
2705
+ description,
2706
+ itemCount,
2707
+ });
2708
+
2709
+ const controller = new AbortController();
2710
+ const timeout = setTimeout(() => controller.abort(), 3000);
2711
+
2712
+ try {
2713
+ const res = await fetch('http://127.0.0.1:' + port + '/operations/evaluate', {
2714
+ method: 'POST',
2715
+ headers: {
2716
+ 'Content-Type': 'application/json',
2717
+ 'Authorization': 'Bearer ' + authToken,
2718
+ },
2719
+ body: postData,
2720
+ signal: controller.signal,
2721
+ });
2722
+ clearTimeout(timeout);
2723
+
2724
+ const decision = await res.json();
2725
+
2726
+ if (decision.action === 'block') {
2727
+ process.stderr.write('BLOCKED: External operation gate denied this action.\\n');
2728
+ process.stderr.write('Reason: ' + (decision.reason || 'Operation not permitted') + '\\n');
2729
+ process.stderr.write('Service: ' + service + ', Action: ' + action + '\\n');
2730
+ process.exit(2);
2731
+ }
2732
+
2733
+ if (decision.action === 'show-plan') {
2734
+ const ctx = [
2735
+ '=== EXTERNAL OPERATION GATE: APPROVAL REQUIRED ===',
2736
+ 'Operation: ' + description,
2737
+ 'Risk: ' + (decision.riskLevel || 'unknown'),
2738
+ decision.plan ? 'Plan: ' + decision.plan : '',
2739
+ decision.checkpoint ? 'Checkpoint: pause after ' + decision.checkpoint.afterCount + ' items' : '',
2740
+ '',
2741
+ 'Show this plan to the user and get explicit approval before proceeding.',
2742
+ 'If the user has not approved this specific operation, DO NOT PROCEED.',
2743
+ '=== END GATE ===',
2744
+ ].filter(Boolean).join('\\n');
2745
+
2746
+ process.stdout.write(JSON.stringify({
2747
+ decision: 'approve',
2748
+ additionalContext: ctx,
2749
+ }));
2750
+ process.exit(0);
2751
+ }
2752
+
2753
+ if (decision.action === 'suggest-alternative' && decision.alternative) {
2754
+ process.stdout.write(JSON.stringify({
2755
+ decision: 'approve',
2756
+ additionalContext: 'External Operation Gate suggests: ' + decision.alternative,
2757
+ }));
2758
+ }
2759
+ process.exit(0);
2760
+ } catch {
2761
+ clearTimeout(timeout);
2762
+ process.exit(0); // Server unreachable or timeout — fail open
2763
+ }
2764
+ } catch {
2765
+ process.exit(0); // Parse error — fail open
2766
+ }
2767
+ });
2768
+ `;
2769
+ }
2770
+ getTelegramReplyScript() {
2771
+ const port = this.config.port;
2772
+ return `#!/bin/bash
2773
+ # telegram-reply.sh — Send a message back to a Telegram topic via instar server.
2774
+ #
2775
+ # Usage:
2776
+ # .claude/scripts/telegram-reply.sh TOPIC_ID "message text"
2777
+ # echo "message text" | .claude/scripts/telegram-reply.sh TOPIC_ID
2778
+ # cat <<'EOF' | .claude/scripts/telegram-reply.sh TOPIC_ID
2779
+ # Multi-line message here
2780
+ # EOF
2781
+
2782
+ TOPIC_ID="$1"
2783
+ shift
2784
+
2785
+ if [ -z "$TOPIC_ID" ]; then
2786
+ echo "Usage: telegram-reply.sh TOPIC_ID [message]" >&2
2787
+ exit 1
2788
+ fi
2789
+
2790
+ # Read message from args or stdin
2791
+ if [ $# -gt 0 ]; then
2792
+ MSG="$*"
2793
+ else
2794
+ MSG="$(cat)"
2795
+ fi
2796
+
2797
+ if [ -z "$MSG" ]; then
2798
+ echo "No message provided" >&2
2799
+ exit 1
2800
+ fi
2801
+
2802
+ PORT="\${INSTAR_PORT:-${port}}"
2803
+
2804
+ # Escape for JSON
2805
+ JSON_MSG=$(printf '%s' "$MSG" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))' 2>/dev/null)
2806
+ if [ -z "$JSON_MSG" ]; then
2807
+ JSON_MSG="$(printf '%s' "$MSG" | sed 's/\\\\\\\\/\\\\\\\\\\\\\\\\/g; s/"/\\\\\\\\"/g' | sed ':a;N;$!ba;s/\\\\n/\\\\\\\\n/g')"
2808
+ JSON_MSG="\\"$JSON_MSG\\""
2809
+ fi
2810
+
2811
+ RESPONSE=$(curl -s -w "\\n%{http_code}" -X POST "http://localhost:\${PORT}/telegram/reply/\${TOPIC_ID}" \\
2812
+ -H 'Content-Type: application/json' \\
2813
+ -d "{\\"text\\":\${JSON_MSG}}")
2814
+
2815
+ HTTP_CODE=$(echo "$RESPONSE" | tail -1)
2816
+ BODY=$(echo "$RESPONSE" | sed '$d')
2817
+
2818
+ if [ "$HTTP_CODE" = "200" ]; then
2819
+ echo "Sent $(echo "$MSG" | wc -c | tr -d ' ') chars to topic $TOPIC_ID"
2820
+ else
2821
+ echo "Failed (HTTP $HTTP_CODE): $BODY" >&2
2822
+ exit 1
2823
+ fi
2824
+ `;
2825
+ }
2826
+ getHealthWatchdog() {
2827
+ const port = this.config.port;
2828
+ const projectName = this.config.projectName;
2829
+ const escapedProjectDir = this.config.projectDir.replace(/'/g, "'\\''");
2830
+ return `#!/bin/bash
2831
+ # health-watchdog.sh — Monitor instar server and auto-recover.
2832
+ # Install as cron: */5 * * * * '${path.join(this.config.projectDir, '.claude/scripts/health-watchdog.sh').replace(/'/g, "'\\''")}'
2833
+
2834
+ PORT="${port}"
2835
+ SERVER_SESSION="${projectName}-server"
2836
+ PROJECT_DIR='${escapedProjectDir}'
2837
+ TMUX_PATH=$(which tmux 2>/dev/null || echo "/opt/homebrew/bin/tmux")
2838
+
2839
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\${PORT}/health" 2>/dev/null)
2840
+ if [ "$HTTP_CODE" = "200" ]; then exit 0; fi
2841
+
2842
+ echo "[\$(date -Iseconds)] Server not responding. Restarting..."
2843
+ $TMUX_PATH kill-session -t "=\${SERVER_SESSION}" 2>/dev/null
2844
+ sleep 2
2845
+ cd "$PROJECT_DIR" && npx instar server start
2846
+ echo "[\$(date -Iseconds)] Server restart initiated"
2847
+ `;
2848
+ }
2849
+ getConvergenceCheck() {
2850
+ // Read the convergence check template from the templates directory.
2851
+ // This file is the heuristic quality gate that runs before external messaging.
2852
+ const modDir = path.dirname(new URL(import.meta.url).pathname);
2853
+ // In dev: src/core/ → ../../src/templates/scripts/convergence-check.sh
2854
+ // In dist: dist/core/ → ../templates/scripts/convergence-check.sh
2855
+ const candidates = [
2856
+ path.resolve(modDir, '..', 'templates', 'scripts', 'convergence-check.sh'),
2857
+ path.resolve(modDir, '..', '..', 'src', 'templates', 'scripts', 'convergence-check.sh'),
2858
+ ];
2859
+ for (const candidate of candidates) {
2860
+ if (fs.existsSync(candidate)) {
2861
+ return fs.readFileSync(candidate, 'utf-8');
2862
+ }
2863
+ }
2864
+ // Fallback: use inline version so migration doesn't fail
2865
+ return this.getConvergenceCheckInline();
2866
+ }
2867
+ // ── Scope Coherence Hooks ─────────────────────────────────────────
2868
+ getScopeCoherenceCollectorHook() {
2869
+ const port = this.config.port;
2870
+ return `#!/usr/bin/env node
2871
+ // Scope Coherence Collector — PostToolUse hook
2872
+ // Tracks implementation depth (Edit/Write/Bash) vs scope-checking actions (Read docs).
2873
+ // The 232nd Lesson: Implementation depth narrows scope.
2874
+ //
2875
+ // This hook records each tool action locally. Fast path — no network call.
2876
+ // State persists in .instar/state/scope-coherence.json via the server API.
2877
+
2878
+ // CJS imports — this is a standalone hook script, not an ESM module
2879
+ const _r = require;
2880
+ const fs = _r('fs');
2881
+ const path = _r('path');
2882
+
2883
+ const STATE_FILE = path.join('.instar', 'state', 'scope-coherence.json');
2884
+ const SCOPE_DOC_PATTERNS = [
2885
+ 'docs/', 'specs/', 'SPEC', 'PROPOSAL', 'DESIGN', 'ARCHITECTURE',
2886
+ 'README', '.instar/AGENT.md', '.instar/USER.md', '.claude/context/',
2887
+ '.claude/grounding/', 'CLAUDE.md'
2888
+ ];
2889
+ const SCOPE_DOC_EXTENSIONS = ['.md', '.txt', '.rst'];
2890
+ const QUERY_PREFIXES = [
2891
+ 'git status', 'git log', 'git diff', 'ls ', 'cat ', 'grep ',
2892
+ 'echo ', 'which ', 'head ', 'tail ', 'wc ', 'pwd', 'date'
2893
+ ];
2894
+ const GROUNDING_SKILLS = ['grounding', 'dawn', 'reflect', 'introspect', 'session-bootstrap'];
2895
+
2896
+ function isScopeDoc(filePath) {
2897
+ if (!filePath) return false;
2898
+ const lower = filePath.toLowerCase();
2899
+ if (SCOPE_DOC_PATTERNS.some(p => lower.includes(p.toLowerCase()))) return true;
2900
+ const parts = filePath.split('/');
2901
+ const name = parts[parts.length - 1] || '';
2902
+ const dot = name.lastIndexOf('.');
2903
+ if (dot > 0) {
2904
+ const ext = name.slice(dot);
2905
+ const stem = name.slice(0, dot);
2906
+ if (SCOPE_DOC_EXTENSIONS.includes(ext) && stem === stem.toUpperCase() && stem.length > 3) return true;
2907
+ }
2908
+ return false;
2909
+ }
2910
+
2911
+ function loadState() {
2912
+ try {
2913
+ if (fs.existsSync(STATE_FILE)) return JSON.parse(fs.readFileSync(STATE_FILE, 'utf-8'));
2914
+ } catch {}
2915
+ return {
2916
+ implementationDepth: 0, lastScopeCheck: null, lastCheckpointPrompt: null,
2917
+ sessionDocsRead: [], checkpointsDismissed: 0, lastImplementationTool: null, sessionStart: null
2918
+ };
2919
+ }
2920
+
2921
+ function saveState(state) {
2922
+ try {
2923
+ const dir = path.dirname(STATE_FILE);
2924
+ fs.mkdirSync(dir, { recursive: true });
2925
+ fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
2926
+ } catch {}
2927
+ }
2928
+
2929
+ let data = '';
2930
+ process.stdin.on('data', chunk => data += chunk);
2931
+ process.stdin.on('end', () => {
2932
+ try {
2933
+ const input = JSON.parse(data);
2934
+ const toolName = input.tool_name || '';
2935
+ const toolInput = input.tool_input || {};
2936
+ const agentId = input.agent_id || null;
2937
+ const agentType = input.agent_type || null;
2938
+ const state = loadState();
2939
+ const now = new Date().toISOString();
2940
+ if (!state.sessionStart) state.sessionStart = now;
2941
+ // Track agent context (M4: Claude Code now enriches all hook events)
2942
+ if (agentId) {
2943
+ if (!state.agentActivity) state.agentActivity = {};
2944
+ if (!state.agentActivity[agentId]) state.agentActivity[agentId] = { type: agentType, actions: 0 };
2945
+ state.agentActivity[agentId].actions++;
2946
+ }
2947
+
2948
+ if (toolName === 'Edit' || toolName === 'Write') {
2949
+ state.implementationDepth += 1;
2950
+ state.lastImplementationTool = toolName + ':' + now;
2951
+ } else if (toolName === 'Bash') {
2952
+ const cmd = (toolInput.command || '').trim();
2953
+ const isQuery = QUERY_PREFIXES.some(p => cmd.startsWith(p));
2954
+ if (!isQuery && cmd.length > 10) {
2955
+ state.implementationDepth += 1;
2956
+ state.lastImplementationTool = 'Bash:' + now;
2957
+ }
2958
+ } else if (toolName === 'Read') {
2959
+ const fp = toolInput.file_path || '';
2960
+ if (isScopeDoc(fp)) {
2961
+ state.implementationDepth = Math.max(0, state.implementationDepth - 10);
2962
+ state.lastScopeCheck = now;
2963
+ if (!state.sessionDocsRead.includes(fp)) {
2964
+ state.sessionDocsRead.push(fp);
2965
+ if (state.sessionDocsRead.length > 20) state.sessionDocsRead = state.sessionDocsRead.slice(-20);
2966
+ }
2967
+ }
2968
+ } else if (toolName === 'Skill') {
2969
+ const skill = toolInput.skill || '';
2970
+ if (GROUNDING_SKILLS.includes(skill)) {
2971
+ state.implementationDepth = 0;
2972
+ state.lastScopeCheck = now;
2973
+ }
2974
+ }
2975
+
2976
+ saveState(state);
2977
+ } catch {}
2978
+ process.stdout.write(JSON.stringify({ decision: 'approve' }));
2979
+ process.exit(0);
2980
+ });
2981
+ `;
2982
+ }
2983
+ getScopeCoherenceCheckpointHook() {
2984
+ const port = this.config.port;
2985
+ return `#!/usr/bin/env node
2986
+ // Scope Coherence Checkpoint — Stop hook
2987
+ // The structural zoom-out. Forces agents to step back and check the big picture
2988
+ // when they've been deep in implementation without reading design docs.
2989
+ //
2990
+ // The 232nd Lesson: Implementation depth narrows scope.
2991
+ // "See code -> wire it -> declare done" vs "read spec -> understand scope -> build right thing"
2992
+ //
2993
+ // Calls the Instar server for active job context to make the checkpoint actionable.
2994
+
2995
+ // CJS imports — this is a standalone hook script, not an ESM module
2996
+ const _r = require;
2997
+ const fs = _r('fs');
2998
+ const path = _r('path');
2999
+ const http = _r('http');
3000
+
3001
+ const STATE_FILE = path.join('.instar', 'state', 'scope-coherence.json');
3002
+ const DEPTH_THRESHOLD = 20;
3003
+ const COOLDOWN_MS = 30 * 60 * 1000; // 30 minutes
3004
+ const MIN_AGE_MS = 5 * 60 * 1000; // 5 minutes
3005
+
3006
+ function loadState() {
3007
+ try {
3008
+ if (fs.existsSync(STATE_FILE)) return JSON.parse(fs.readFileSync(STATE_FILE, 'utf-8'));
3009
+ } catch {}
3010
+ return { implementationDepth: 0 };
3011
+ }
3012
+
3013
+ function saveState(state) {
3014
+ try {
3015
+ const dir = path.dirname(STATE_FILE);
3016
+ fs.mkdirSync(dir, { recursive: true });
3017
+ fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
3018
+ } catch {}
3019
+ }
3020
+
3021
+ function fetchActiveJob() {
3022
+ return new Promise((resolve) => {
3023
+ const req = http.get('http://localhost:${port}/context/active-job', { timeout: 2000 }, (res) => {
3024
+ let body = '';
3025
+ res.on('data', chunk => body += chunk);
3026
+ res.on('end', () => {
3027
+ try { resolve(JSON.parse(body)); } catch { resolve(null); }
3028
+ });
3029
+ });
3030
+ req.on('error', () => resolve(null));
3031
+ req.on('timeout', () => { req.destroy(); resolve(null); });
3032
+ });
3033
+ }
3034
+
3035
+ let data = '';
3036
+ process.stdin.on('data', chunk => data += chunk);
3037
+ process.stdin.on('end', async () => {
3038
+ try {
3039
+ const state = loadState();
3040
+ const now = Date.now();
3041
+ const depth = state.implementationDepth || 0;
3042
+
3043
+ if (depth < DEPTH_THRESHOLD) {
3044
+ process.stdout.write(JSON.stringify({ decision: 'approve' }));
3045
+ process.exit(0);
3046
+ return;
3047
+ }
3048
+
3049
+ // Check cooldown
3050
+ if (state.lastCheckpointPrompt) {
3051
+ const elapsed = now - new Date(state.lastCheckpointPrompt).getTime();
3052
+ if (elapsed < COOLDOWN_MS) {
3053
+ process.stdout.write(JSON.stringify({ decision: 'approve' }));
3054
+ process.exit(0);
3055
+ return;
3056
+ }
3057
+ }
3058
+
3059
+ // Check minimum session age
3060
+ if (state.sessionStart) {
3061
+ const age = now - new Date(state.sessionStart).getTime();
3062
+ if (age < MIN_AGE_MS) {
3063
+ process.stdout.write(JSON.stringify({ decision: 'approve' }));
3064
+ process.exit(0);
3065
+ return;
3066
+ }
3067
+ }
3068
+
3069
+ // Fetch active job context from server
3070
+ const jobData = await fetchActiveJob();
3071
+ const dismissed = state.checkpointsDismissed || 0;
3072
+ const docsRead = state.sessionDocsRead || [];
3073
+
3074
+ let jobContext = '';
3075
+ if (jobData && jobData.active && jobData.job) {
3076
+ jobContext = '\\nYou are running the **' + jobData.job.name + '** job.\\n' +
3077
+ 'Scope: ' + (jobData.job.description || 'No description') + '\\n' +
3078
+ 'Are you still within the job\\'s boundaries?\\n';
3079
+ }
3080
+
3081
+ let docsContext = '';
3082
+ if (docsRead.length > 0) {
3083
+ const recent = docsRead.slice(-5).map(d => d.split('/').pop());
3084
+ docsContext = '\\nDocs read this session: ' + recent.join(', ');
3085
+ } else {
3086
+ docsContext = '\\nNo design docs, specs, or proposals have been read this session.';
3087
+ }
3088
+
3089
+ let escalation = '';
3090
+ if (dismissed >= 3) {
3091
+ escalation = '\\n\\nYou\\'ve dismissed ' + dismissed + ' scope checkpoints. ' +
3092
+ 'Dismissing scope checks during deep implementation is how scope collapse happens.';
3093
+ }
3094
+
3095
+ const reason = 'SCOPE COHERENCE CHECK\\n\\n' +
3096
+ 'You\\'ve been deep in implementation for ' + depth + ' actions without reading design documents.\\n' +
3097
+ 'Implementation depth narrows perception.\\n' +
3098
+ jobContext +
3099
+ '\\nStep back and ask yourself:\\n' +
3100
+ '\\n1. WHO AM I? What role am I filling right now?\\n' +
3101
+ '2. WHAT AM I WORKING ON? What\\'s the full scope? Is there a spec or proposal?\\n' +
3102
+ '3. BIG PICTURE — How does this fit into the larger system?\\n' +
3103
+ '4. HIGHER-LEVEL ELEMENTS — What architectural or cross-system aspects am I missing?\\n' +
3104
+ '5. COMPLETENESS — Am I considering all elements, or have I collapsed the scope?\\n' +
3105
+ docsContext + escalation +
3106
+ '\\n\\nOptions: Read the relevant spec/proposal, confirm scope awareness, or /grounding';
3107
+
3108
+ // Record that we prompted
3109
+ state.lastCheckpointPrompt = new Date().toISOString();
3110
+ state.checkpointsDismissed = dismissed + 1;
3111
+ saveState(state);
3112
+
3113
+ process.stdout.write(JSON.stringify({ decision: 'block', reason: reason }));
3114
+ } catch {
3115
+ process.stdout.write(JSON.stringify({ decision: 'approve' }));
3116
+ }
3117
+ process.exit(0);
3118
+ });
3119
+ `;
3120
+ }
3121
+ getFreeTextGuardHook() {
3122
+ // Read the hook from the templates directory instead of inline generation.
3123
+ // This avoids multi-layer escaping issues (TypeScript -> bash -> Python -> regex).
3124
+ const hookPath = path.join(path.dirname(new URL(import.meta.url).pathname), '..', 'templates', 'hooks', 'free-text-guard.sh');
3125
+ return fs.readFileSync(hookPath, 'utf-8');
3126
+ }
3127
+ getClaimInterceptHook() {
3128
+ return `#!/usr/bin/env node
3129
+ // Claim Intercept — PostToolUse hook for catching false operational claims.
3130
+ //
3131
+ // The Proprioceptive Stack for Instar agents.
3132
+ // Agents sometimes falsely deny capabilities they actually have.
3133
+ // This hook cross-checks denial claims against Canonical State
3134
+ // (quick-facts.json, project-registry.json) and injects corrections.
3135
+ //
3136
+ // Architecture: Two-layer detection
3137
+ // Layer 1: Regex fast-path (<1ms) — catches explicit denial patterns
3138
+ // Layer 2: Canonical State cross-check — verifies claims against ground truth
3139
+ //
3140
+ // Design principles:
3141
+ // - Never blocks — injects warnings via additionalContext
3142
+ // - Reads canonical state files directly (no server dependency)
3143
+ // - Only checks topically relevant output (skip pure code, grep, cat)
3144
+ // - Rate-limited to prevent latency stacking
3145
+
3146
+ const _r = require;
3147
+ const fs = _r('fs');
3148
+ const path = _r('path');
3149
+
3150
+ const STATE_DIR = path.join('.instar', 'state');
3151
+ const RATE_FILE = path.join(STATE_DIR, '.claim-intercept-last.tmp');
3152
+ const RATE_LIMIT_MS = 10000; // 10 seconds between checks
3153
+ const LOG_FILE = path.join(STATE_DIR, 'claim-intercept.log');
3154
+
3155
+ // ── Denial pattern templates ───────────────────────────────────
3156
+ // These catch explicit claims of inability or missing capability.
3157
+
3158
+ const DENIAL_PATTERNS = [
3159
+ /(?:I |i )(?:can'?t|cannot|am (?:not |un)able to)\\s+(.{5,80})/i,
3160
+ /(?:don'?t|do not) have (?:access|credentials|a?n? ?(?:api|token|key|tool|script|capability))\\s*(?:for|to)?\\s*(.{3,60})?/i,
3161
+ /(?:no |not )(?:available|configured|set up|installed|deployed|running|accessible)\\b/i,
3162
+ /(?:isn'?t|is not|aren'?t|are not) (?:available|configured|set up|working|running|accessible)\\b/i,
3163
+ /(?:blocked|unavailable|disabled|suspended|broken|offline|unreachable)\\b/i,
3164
+ /(?:need|require)s? (?:the user|human|manual|someone) to/i,
3165
+ /(?:outside|beyond) (?:my|the agent'?s?) (?:capabilities|scope|access|authority)/i,
3166
+ /(?:no |don'?t have (?:a |any )?)(?:way|mechanism|method|means) to/i,
3167
+ /(?:not |never )(?:been )?(?:set up|configured|registered|deployed)/i,
3168
+ ];
3169
+
3170
+ // ── Topic relevance filter ─────────────────────────────────────
3171
+ // Skip pure code output, file reads, grep results.
3172
+
3173
+ const EXEMPT_PATTERNS = [
3174
+ /^\\s*\\d+[:\\|]/m, // Line-numbered output (cat -n, grep -n)
3175
+ /^diff --git/m, // Git diffs
3176
+ /^\\+\\+\\+|^---/m, // Diff headers
3177
+ /^commit [a-f0-9]{40}/m, // Git log
3178
+ /node_modules\\//, // Node modules paths
3179
+ /\\.test\\.[jt]s/, // Test file output
3180
+ ];
3181
+
3182
+ function isExempt(text) {
3183
+ return EXEMPT_PATTERNS.some(p => p.test(text));
3184
+ }
3185
+
3186
+ // ── Rate limiter ───────────────────────────────────────────────
3187
+
3188
+ function checkRateLimit() {
3189
+ try {
3190
+ if (fs.existsSync(RATE_FILE)) {
3191
+ const mtime = fs.statSync(RATE_FILE).mtimeMs;
3192
+ if (Date.now() - mtime < RATE_LIMIT_MS) return false;
3193
+ }
3194
+ fs.mkdirSync(path.dirname(RATE_FILE), { recursive: true });
3195
+ fs.writeFileSync(RATE_FILE, '');
3196
+ return true;
3197
+ } catch { return true; }
3198
+ }
3199
+
3200
+ // ── Canonical State loader ─────────────────────────────────────
3201
+
3202
+ function loadCanonicalState() {
3203
+ const state = { facts: [], projects: [], antiPatterns: [] };
3204
+ try {
3205
+ const factsPath = path.join(STATE_DIR, 'quick-facts.json');
3206
+ if (fs.existsSync(factsPath)) {
3207
+ state.facts = JSON.parse(fs.readFileSync(factsPath, 'utf-8'));
3208
+ }
3209
+ } catch {}
3210
+ try {
3211
+ const projPath = path.join(STATE_DIR, 'project-registry.json');
3212
+ if (fs.existsSync(projPath)) {
3213
+ state.projects = JSON.parse(fs.readFileSync(projPath, 'utf-8'));
3214
+ }
3215
+ } catch {}
3216
+ try {
3217
+ const apPath = path.join(STATE_DIR, 'anti-patterns.json');
3218
+ if (fs.existsSync(apPath)) {
3219
+ state.antiPatterns = JSON.parse(fs.readFileSync(apPath, 'utf-8'));
3220
+ }
3221
+ } catch {}
3222
+ return state;
3223
+ }
3224
+
3225
+ // ── Cross-check claims against canonical state ─────────────────
3226
+
3227
+ function findContradictions(text, state) {
3228
+ const contradictions = [];
3229
+ const textLower = text.toLowerCase();
3230
+
3231
+ // Check if any denied capability contradicts a quick fact
3232
+ for (const fact of state.facts) {
3233
+ const answerWords = fact.answer.toLowerCase().split(/\\s+/).filter(w => w.length > 3);
3234
+ const questionWords = fact.question.toLowerCase().split(/\\s+/).filter(w => w.length > 3);
3235
+ const allWords = [...answerWords, ...questionWords];
3236
+
3237
+ // If the denial text mentions something related to a known fact
3238
+ for (const word of allWords) {
3239
+ if (textLower.includes(word)) {
3240
+ // Check if the text contains a denial near this word
3241
+ const wordIdx = textLower.indexOf(word);
3242
+ const context = textLower.substring(Math.max(0, wordIdx - 100), Math.min(textLower.length, wordIdx + 100));
3243
+ if (DENIAL_PATTERNS.some(p => p.test(context))) {
3244
+ contradictions.push({
3245
+ claim: 'Denied capability related to: ' + word,
3246
+ fact: fact.question + ' → ' + fact.answer,
3247
+ source: 'quick-facts.json (verified: ' + (fact.lastVerified || 'unknown') + ')',
3248
+ });
3249
+ break; // One contradiction per fact is enough
3250
+ }
3251
+ }
3252
+ }
3253
+ }
3254
+
3255
+ // Check if denial mentions a registered project
3256
+ for (const proj of state.projects) {
3257
+ const projName = proj.name.toLowerCase();
3258
+ if (textLower.includes(projName)) {
3259
+ const nameIdx = textLower.indexOf(projName);
3260
+ const context = textLower.substring(Math.max(0, nameIdx - 100), Math.min(textLower.length, nameIdx + 100));
3261
+ if (DENIAL_PATTERNS.some(p => p.test(context))) {
3262
+ contradictions.push({
3263
+ claim: 'Denied access/capability for project: ' + proj.name,
3264
+ fact: proj.name + ' is registered at ' + proj.dir + (proj.deploymentTargets ? ' (deploys to: ' + proj.deploymentTargets.join(', ') + ')' : ''),
3265
+ source: 'project-registry.json',
3266
+ });
3267
+ }
3268
+ }
3269
+ }
3270
+
3271
+ return contradictions;
3272
+ }
3273
+
3274
+ // ── Main ───────────────────────────────────────────────────────
3275
+
3276
+ let data = '';
3277
+ process.stdin.on('data', chunk => data += chunk);
3278
+ process.stdin.on('end', () => {
3279
+ try {
3280
+ const input = JSON.parse(data);
3281
+ const toolName = input.tool_name || '';
3282
+
3283
+ // Only check Bash, Write, Edit output
3284
+ if (!['Bash', 'Write', 'Edit'].includes(toolName)) process.exit(0);
3285
+
3286
+ // Extract text content
3287
+ let text = '';
3288
+ if (toolName === 'Bash') {
3289
+ text = (input.tool_input || {}).command || '';
3290
+ // Also check stdout if available
3291
+ const result = input.tool_result || '';
3292
+ if (typeof result === 'string') text += ' ' + result;
3293
+ } else if (toolName === 'Write') {
3294
+ text = (input.tool_input || {}).content || '';
3295
+ } else if (toolName === 'Edit') {
3296
+ text = (input.tool_input || {}).new_string || '';
3297
+ }
3298
+
3299
+ if (!text || text.length < 40) process.exit(0);
3300
+ if (isExempt(text)) process.exit(0);
3301
+
3302
+ // Quick scan: does the text even contain a denial pattern?
3303
+ const hasDenial = DENIAL_PATTERNS.some(p => p.test(text));
3304
+ if (!hasDenial) process.exit(0);
3305
+
3306
+ // Rate limit before loading canonical state
3307
+ if (!checkRateLimit()) process.exit(0);
3308
+
3309
+ // Cross-check against canonical state
3310
+ const state = loadCanonicalState();
3311
+ if (state.facts.length === 0 && state.projects.length === 0) process.exit(0);
3312
+
3313
+ const contradictions = findContradictions(text, state);
3314
+ if (contradictions.length === 0) process.exit(0);
3315
+
3316
+ // Build warning message
3317
+ const details = contradictions.map(c =>
3318
+ ' CLAIM: ' + c.claim + '\\n' +
3319
+ ' FACT: ' + c.fact + '\\n' +
3320
+ ' FROM: ' + c.source
3321
+ ).join('\\n\\n');
3322
+
3323
+ const warning = 'CLAIM-INTERCEPT: CONTRADICTION DETECTED\\n\\n' +
3324
+ 'Your output contains claims that contradict canonical state:\\n\\n' +
3325
+ details + '\\n\\n' +
3326
+ 'Do NOT repeat false claims. Revise your statement to match operational reality.\\n' +
3327
+ 'Canonical state is compiled from verified registries. If you believe it is wrong,\\n' +
3328
+ 'verify with: GET /state/quick-facts or check .instar/state/ files directly.';
3329
+
3330
+ // Log the interception
3331
+ try {
3332
+ const logEntry = '[' + new Date().toISOString() + '] ' +
3333
+ 'tool=' + toolName + ' | ' +
3334
+ 'contradictions=' + contradictions.length + ' | ' +
3335
+ 'claims=' + contradictions.map(c => c.claim.substring(0, 50)).join('; ') + '\\n';
3336
+ fs.mkdirSync(path.dirname(LOG_FILE), { recursive: true });
3337
+ fs.appendFileSync(LOG_FILE, logEntry);
3338
+ } catch {}
3339
+
3340
+ process.stdout.write(JSON.stringify({ decision: 'approve', additionalContext: warning }));
3341
+ } catch {}
3342
+ process.exit(0);
3343
+ });
3344
+ `;
3345
+ }
3346
+ getResponseReviewHook() {
3347
+ const port = this.config.port;
3348
+ return `#!/usr/bin/env node
3349
+ // Response Review — Stop hook for the Coherence Gate response review pipeline.
3350
+ //
3351
+ // Thin client: reads stdin JSON, posts to the Instar server's /review/evaluate
3352
+ // endpoint, and returns the verdict. All review logic lives server-side.
3353
+ //
3354
+ // Unlike other stop hooks, this does NOT skip when stop_hook_active is true.
3355
+ // The CoherenceGate handles retry tracking and exhaustion internally.
3356
+ // The hook always passes the stopHookActive flag so the server can decide.
3357
+
3358
+ const _r = require;
3359
+ const fs = _r('fs');
3360
+ const path = _r('path');
3361
+ const http = _r('http');
3362
+
3363
+ // Read config for port and auth token
3364
+ let serverPort = ${port};
3365
+ let authToken = '';
3366
+ try {
3367
+ const configPath = path.join(process.env.CLAUDE_PROJECT_DIR || '.', '.instar', 'config.json');
3368
+ const raw = fs.readFileSync(configPath, 'utf-8');
3369
+ const cfg = JSON.parse(raw);
3370
+ serverPort = cfg.port || ${port};
3371
+ authToken = cfg.authToken || '';
3372
+ } catch {}
3373
+
3374
+ // Check if response review is enabled in config
3375
+ let reviewEnabled = false;
3376
+ try {
3377
+ const configPath = path.join(process.env.CLAUDE_PROJECT_DIR || '.', '.instar', 'config.json');
3378
+ const raw = fs.readFileSync(configPath, 'utf-8');
3379
+ const cfg = JSON.parse(raw);
3380
+ reviewEnabled = cfg.responseReview && cfg.responseReview.enabled;
3381
+ } catch {}
3382
+
3383
+ if (!reviewEnabled) {
3384
+ process.exit(0);
3385
+ }
3386
+
3387
+ let data = '';
3388
+ process.stdin.on('data', chunk => data += chunk);
3389
+ process.stdin.on('end', async () => {
3390
+ try {
3391
+ const input = JSON.parse(data);
3392
+ const message = input.last_assistant_message || '';
3393
+
3394
+ // Skip empty or very short messages (greetings, etc.)
3395
+ if (!message || message.length < 20) {
3396
+ process.exit(0);
3397
+ }
3398
+
3399
+ // Determine channel from environment
3400
+ const topicId = process.env.INSTAR_TELEGRAM_TOPIC;
3401
+ const sessionId = process.env.INSTAR_SESSION_ID || 'unknown';
3402
+ const channel = topicId ? 'telegram' : 'direct';
3403
+ const isExternalFacing = !!topicId; // Telegram = external
3404
+
3405
+ // Build the review request
3406
+ const body = JSON.stringify({
3407
+ message,
3408
+ sessionId,
3409
+ stopHookActive: !!input.stop_hook_active,
3410
+ context: {
3411
+ channel,
3412
+ topicId: topicId ? parseInt(topicId, 10) : undefined,
3413
+ recipientType: 'primary-user',
3414
+ isExternalFacing,
3415
+ },
3416
+ });
3417
+
3418
+ // Call the review endpoint with timeout
3419
+ const controller = new AbortController();
3420
+ const timeout = setTimeout(() => controller.abort(), 8000);
3421
+
3422
+ try {
3423
+ const res = await fetch('http://127.0.0.1:' + serverPort + '/review/evaluate', {
3424
+ method: 'POST',
3425
+ headers: {
3426
+ 'Content-Type': 'application/json',
3427
+ 'Authorization': 'Bearer ' + authToken,
3428
+ },
3429
+ body,
3430
+ signal: controller.signal,
3431
+ });
3432
+ clearTimeout(timeout);
3433
+
3434
+ if (!res.ok) {
3435
+ // Server error — fail open (approve)
3436
+ process.exit(0);
3437
+ }
3438
+
3439
+ const result = await res.json();
3440
+
3441
+ if (!result.pass) {
3442
+ // BLOCK — return feedback to the agent for revision
3443
+ const reason = result.feedback || 'Response did not pass coherence review.';
3444
+ process.stdout.write(JSON.stringify({
3445
+ decision: 'block',
3446
+ reason,
3447
+ }));
3448
+ process.exit(2);
3449
+ }
3450
+
3451
+ // PASS — optionally include warnings
3452
+ if (result.warnings && result.warnings.length > 0) {
3453
+ process.stderr.write('[response-review] Warnings: ' + result.warnings.join('; ') + '\\n');
3454
+ }
3455
+
3456
+ process.exit(0);
3457
+ } catch {
3458
+ // Network error or timeout — fail open
3459
+ clearTimeout(timeout);
3460
+ process.exit(0);
3461
+ }
3462
+ } catch {
3463
+ // JSON parse error on stdin — fail open
3464
+ process.exit(0);
3465
+ }
3466
+ });
3467
+ `;
3468
+ }
3469
+ getClaimInterceptResponseHook() {
3470
+ return `#!/usr/bin/env node
3471
+ // Claim Intercept — Stop hook for catching false claims in direct responses.
3472
+ //
3473
+ // Complements the PostToolUse claim-intercept hook by checking the agent's
3474
+ // direct text responses (the words between tool calls). This closes the gap
3475
+ // where tool output is checked but conversational text goes unchecked.
3476
+ //
3477
+ // Architecture:
3478
+ // Stop hook — fires when the agent finishes a response turn.
3479
+ // Receives last_assistant_message from stdin.
3480
+ // Cross-checks against Canonical State.
3481
+ // If contradiction found: BLOCKS the stop (exit 2) to force correction.
3482
+ //
3483
+ // Guard against infinite loops:
3484
+ // If stop_hook_active is true, we're in a correction continuation — skip.
3485
+
3486
+ const _r = require;
3487
+ const fs = _r('fs');
3488
+ const path = _r('path');
3489
+
3490
+ const STATE_DIR = path.join('.instar', 'state');
3491
+ const RATE_FILE = path.join(STATE_DIR, '.claim-intercept-last.tmp');
3492
+ const RATE_LIMIT_MS = 10000;
3493
+ const LOG_FILE = path.join(STATE_DIR, 'claim-intercept.log');
3494
+
3495
+ // Same denial patterns as PostToolUse hook
3496
+ const DENIAL_PATTERNS = [
3497
+ /(?:I |i )(?:can'?t|cannot|am (?:not |un)able to)\\s+(.{5,80})/i,
3498
+ /(?:don'?t|do not) have (?:access|credentials|a?n? ?(?:api|token|key|tool|script|capability))\\s*(?:for|to)?\\s*(.{3,60})?/i,
3499
+ /(?:no |not )(?:available|configured|set up|installed|deployed|running|accessible)\\b/i,
3500
+ /(?:isn'?t|is not|aren'?t|are not) (?:available|configured|set up|working|running|accessible)\\b/i,
3501
+ /(?:blocked|unavailable|disabled|suspended|broken|offline|unreachable)\\b/i,
3502
+ /(?:need|require)s? (?:the user|human|manual|someone) to/i,
3503
+ /(?:outside|beyond) (?:my|the agent'?s?) (?:capabilities|scope|access|authority)/i,
3504
+ /(?:no |don'?t have (?:a |any )?)(?:way|mechanism|method|means) to/i,
3505
+ /(?:not |never )(?:been )?(?:set up|configured|registered|deployed)/i,
3506
+ ];
3507
+
3508
+ function checkRateLimit() {
3509
+ try {
3510
+ if (fs.existsSync(RATE_FILE)) {
3511
+ const mtime = fs.statSync(RATE_FILE).mtimeMs;
3512
+ if (Date.now() - mtime < RATE_LIMIT_MS) return false;
3513
+ }
3514
+ fs.mkdirSync(path.dirname(RATE_FILE), { recursive: true });
3515
+ fs.writeFileSync(RATE_FILE, '');
3516
+ return true;
3517
+ } catch { return true; }
3518
+ }
3519
+
3520
+ function loadCanonicalState() {
3521
+ const state = { facts: [], projects: [] };
3522
+ try {
3523
+ const factsPath = path.join(STATE_DIR, 'quick-facts.json');
3524
+ if (fs.existsSync(factsPath)) {
3525
+ state.facts = JSON.parse(fs.readFileSync(factsPath, 'utf-8'));
3526
+ }
3527
+ } catch {}
3528
+ try {
3529
+ const projPath = path.join(STATE_DIR, 'project-registry.json');
3530
+ if (fs.existsSync(projPath)) {
3531
+ state.projects = JSON.parse(fs.readFileSync(projPath, 'utf-8'));
3532
+ }
3533
+ } catch {}
3534
+ return state;
3535
+ }
3536
+
3537
+ function findContradictions(text, state) {
3538
+ const contradictions = [];
3539
+ const textLower = text.toLowerCase();
3540
+
3541
+ for (const fact of state.facts) {
3542
+ const answerWords = fact.answer.toLowerCase().split(/\\s+/).filter(w => w.length > 3);
3543
+ const questionWords = fact.question.toLowerCase().split(/\\s+/).filter(w => w.length > 3);
3544
+ const allWords = [...answerWords, ...questionWords];
3545
+
3546
+ for (const word of allWords) {
3547
+ if (textLower.includes(word)) {
3548
+ const wordIdx = textLower.indexOf(word);
3549
+ const context = textLower.substring(Math.max(0, wordIdx - 100), Math.min(textLower.length, wordIdx + 100));
3550
+ if (DENIAL_PATTERNS.some(p => p.test(context))) {
3551
+ contradictions.push({
3552
+ claim: 'Denied capability related to: ' + word,
3553
+ fact: fact.question + ' → ' + fact.answer,
3554
+ source: 'quick-facts.json',
3555
+ });
3556
+ break;
3557
+ }
3558
+ }
3559
+ }
3560
+ }
3561
+
3562
+ for (const proj of state.projects) {
3563
+ const projName = proj.name.toLowerCase();
3564
+ if (textLower.includes(projName)) {
3565
+ const nameIdx = textLower.indexOf(projName);
3566
+ const context = textLower.substring(Math.max(0, nameIdx - 100), Math.min(textLower.length, nameIdx + 100));
3567
+ if (DENIAL_PATTERNS.some(p => p.test(context))) {
3568
+ contradictions.push({
3569
+ claim: 'Denied access/capability for project: ' + proj.name,
3570
+ fact: proj.name + ' is registered at ' + proj.dir,
3571
+ source: 'project-registry.json',
3572
+ });
3573
+ }
3574
+ }
3575
+ }
3576
+
3577
+ return contradictions;
3578
+ }
3579
+
3580
+ let data = '';
3581
+ process.stdin.on('data', chunk => data += chunk);
3582
+ process.stdin.on('end', () => {
3583
+ try {
3584
+ const input = JSON.parse(data);
3585
+
3586
+ // Guard: if we're already in a Stop hook continuation, skip
3587
+ if (input.stop_hook_active) process.exit(0);
3588
+
3589
+ const message = input.last_assistant_message || '';
3590
+ if (!message || message.length < 80) process.exit(0);
3591
+
3592
+ // Quick scan for denial patterns
3593
+ const hasDenial = DENIAL_PATTERNS.some(p => p.test(message));
3594
+ if (!hasDenial) process.exit(0);
3595
+
3596
+ // Rate limit
3597
+ if (!checkRateLimit()) process.exit(0);
3598
+
3599
+ // Cross-check against canonical state
3600
+ const state = loadCanonicalState();
3601
+ if (state.facts.length === 0 && state.projects.length === 0) process.exit(0);
3602
+
3603
+ const contradictions = findContradictions(message, state);
3604
+ if (contradictions.length === 0) process.exit(0);
3605
+
3606
+ // Build correction prompt
3607
+ const details = contradictions.map(c =>
3608
+ ' CLAIM: ' + c.claim + '\\n' +
3609
+ ' FACT: ' + c.fact + '\\n' +
3610
+ ' FROM: ' + c.source
3611
+ ).join('\\n\\n');
3612
+
3613
+ const reason = 'CLAIM-INTERCEPT (Response-Level): FALSE CLAIM DETECTED\\n\\n' +
3614
+ 'Your last response contained claims that contradict canonical state:\\n\\n' +
3615
+ details + '\\n\\n' +
3616
+ 'You MUST correct this. Issue a brief correction acknowledging the error.\\n' +
3617
+ 'Do NOT repeat the false claim. State what is actually true.\\n' +
3618
+ 'Canonical state: .instar/state/quick-facts.json, project-registry.json';
3619
+
3620
+ // Log the interception
3621
+ try {
3622
+ const logEntry = '[' + new Date().toISOString() + '] ' +
3623
+ 'RESPONSE-LEVEL | contradictions=' + contradictions.length + ' | ' +
3624
+ 'claims=' + contradictions.map(c => c.claim.substring(0, 50)).join('; ') + '\\n';
3625
+ fs.mkdirSync(path.dirname(LOG_FILE), { recursive: true });
3626
+ fs.appendFileSync(LOG_FILE, logEntry);
3627
+ } catch {}
3628
+
3629
+ // BLOCK the stop — force the agent to correct itself
3630
+ process.stdout.write(JSON.stringify({ decision: 'block', reason: reason }));
3631
+ process.exit(2);
3632
+ } catch {}
3633
+ process.exit(0);
3634
+ });
3635
+ `;
3636
+ }
3637
+ getAutoApprovePermissionsHook() {
3638
+ return `#!/usr/bin/env node
3639
+ // Auto-approve ALL PermissionRequest hooks.
3640
+ //
3641
+ // Subagents spawned via the Agent tool don't inherit --dangerously-skip-permissions
3642
+ // from the parent session. Without this hook, subagents prompt for every tool use,
3643
+ // blocking autonomous sessions and jobs.
3644
+ //
3645
+ // Real safety is enforced by PreToolUse hooks (dangerous-command-guard.sh,
3646
+ // external-communication-guard.js, external-operation-gate.js). Permission prompts
3647
+ // are duplicative friction, not protection.
3648
+
3649
+ process.stdin.resume();
3650
+ let data = '';
3651
+ process.stdin.on('data', chunk => data += chunk);
3652
+ process.stdin.on('end', () => {
3653
+ console.log(JSON.stringify({
3654
+ hookSpecificOutput: {
3655
+ hookEventName: 'PermissionRequest',
3656
+ decision: { behavior: 'allow' }
3657
+ }
3658
+ }));
3659
+ });
3660
+
3661
+ // Timeout safety
3662
+ setTimeout(() => {
3663
+ console.log(JSON.stringify({
3664
+ hookSpecificOutput: {
3665
+ hookEventName: 'PermissionRequest',
3666
+ decision: { behavior: 'allow' }
3667
+ }
3668
+ }));
3669
+ process.exit(0);
3670
+ }, 2000);
3671
+ `;
3672
+ }
3673
+ }
3674
+ //# sourceMappingURL=PostUpdateMigrator.js.map