instar 1.3.1649 → 1.3.1650

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 (451) hide show
  1. package/dashboard/console/accounts.js +2 -1
  2. package/dashboard/console/agents-model.js +3 -3
  3. package/dashboard/console/agents.js +7 -4
  4. package/dashboard/console/console.css +1 -0
  5. package/dashboard/console/console.js +35 -4
  6. package/dashboard/console/costs-model.js +12 -0
  7. package/dashboard/console/costs.js +6 -3
  8. package/dashboard/console/development-model.js +9 -3
  9. package/dashboard/console/development.js +7 -4
  10. package/dashboard/console/home-model.js +30 -14
  11. package/dashboard/console/mandates.js +3 -3
  12. package/dashboard/console/needs-model.js +105 -0
  13. package/dashboard/console/plans.js +2 -1
  14. package/dashboard/console/secrets.js +2 -2
  15. package/dashboard/console/ticket-model.js +36 -0
  16. package/dashboard/console/ui.js +3 -0
  17. package/dist/cli.js +8 -0
  18. package/dist/cli.js.map +1 -1
  19. package/dist/commands/install.d.ts +9 -7
  20. package/dist/commands/install.d.ts.map +1 -1
  21. package/dist/commands/install.js +2 -19
  22. package/dist/commands/install.js.map +1 -1
  23. package/dist/commands/reflect.d.ts.map +1 -1
  24. package/dist/commands/reflect.js +2 -0
  25. package/dist/commands/reflect.js.map +1 -1
  26. package/dist/commands/route.d.ts.map +1 -1
  27. package/dist/commands/route.js +2 -0
  28. package/dist/commands/route.js.map +1 -1
  29. package/dist/commands/server.d.ts.map +1 -1
  30. package/dist/commands/server.js +315 -14
  31. package/dist/commands/server.js.map +1 -1
  32. package/dist/commands/setClaudeKey.d.ts +8 -0
  33. package/dist/commands/setClaudeKey.d.ts.map +1 -0
  34. package/dist/commands/setClaudeKey.js +35 -0
  35. package/dist/commands/setClaudeKey.js.map +1 -0
  36. package/dist/core/AccountFollowMeOrchestrator.d.ts.map +1 -1
  37. package/dist/core/AccountFollowMeOrchestrator.js +4 -0
  38. package/dist/core/AccountFollowMeOrchestrator.js.map +1 -1
  39. package/dist/core/AppMediaStore.d.ts.map +1 -1
  40. package/dist/core/AppMediaStore.js +3 -0
  41. package/dist/core/AppMediaStore.js.map +1 -1
  42. package/dist/core/BackupManager.d.ts.map +1 -1
  43. package/dist/core/BackupManager.js +2 -0
  44. package/dist/core/BackupManager.js.map +1 -1
  45. package/dist/core/ClaudeCliIntelligenceProvider.d.ts.map +1 -1
  46. package/dist/core/ClaudeCliIntelligenceProvider.js +11 -3
  47. package/dist/core/ClaudeCliIntelligenceProvider.js.map +1 -1
  48. package/dist/core/ClaudeKeyHealth.d.ts +141 -0
  49. package/dist/core/ClaudeKeyHealth.d.ts.map +1 -0
  50. package/dist/core/ClaudeKeyHealth.js +467 -0
  51. package/dist/core/ClaudeKeyHealth.js.map +1 -0
  52. package/dist/core/CodexTaskContinuationStore.d.ts.map +1 -1
  53. package/dist/core/CodexTaskContinuationStore.js +7 -0
  54. package/dist/core/CodexTaskContinuationStore.js.map +1 -1
  55. package/dist/core/CoherenceJournal.d.ts +1 -1
  56. package/dist/core/CoherenceJournal.d.ts.map +1 -1
  57. package/dist/core/CoherenceJournal.js +11 -2
  58. package/dist/core/CoherenceJournal.js.map +1 -1
  59. package/dist/core/Config.d.ts +8 -0
  60. package/dist/core/Config.d.ts.map +1 -1
  61. package/dist/core/Config.js +26 -0
  62. package/dist/core/Config.js.map +1 -1
  63. package/dist/core/CredentialSwapExecutor.d.ts.map +1 -1
  64. package/dist/core/CredentialSwapExecutor.js +10 -0
  65. package/dist/core/CredentialSwapExecutor.js.map +1 -1
  66. package/dist/core/DecisionQualityRecorderImpl.d.ts.map +1 -1
  67. package/dist/core/DecisionQualityRecorderImpl.js +6 -0
  68. package/dist/core/DecisionQualityRecorderImpl.js.map +1 -1
  69. package/dist/core/DiscoveryEvaluator.d.ts.map +1 -1
  70. package/dist/core/DiscoveryEvaluator.js +4 -0
  71. package/dist/core/DiscoveryEvaluator.js.map +1 -1
  72. package/dist/core/IdentityReannounceClaimant.d.ts.map +1 -1
  73. package/dist/core/IdentityReannounceClaimant.js +4 -0
  74. package/dist/core/IdentityReannounceClaimant.js.map +1 -1
  75. package/dist/core/IntelligenceRouter.d.ts.map +1 -1
  76. package/dist/core/IntelligenceRouter.js +9 -0
  77. package/dist/core/IntelligenceRouter.js.map +1 -1
  78. package/dist/core/JournalSyncApplier.d.ts +1 -0
  79. package/dist/core/JournalSyncApplier.d.ts.map +1 -1
  80. package/dist/core/JournalSyncApplier.js +48 -0
  81. package/dist/core/JournalSyncApplier.js.map +1 -1
  82. package/dist/core/LeaseCoordinator.d.ts +4 -0
  83. package/dist/core/LeaseCoordinator.d.ts.map +1 -1
  84. package/dist/core/LeaseCoordinator.js +64 -1
  85. package/dist/core/LeaseCoordinator.js.map +1 -1
  86. package/dist/core/MessagingToneGate.d.ts +11 -7
  87. package/dist/core/MessagingToneGate.d.ts.map +1 -1
  88. package/dist/core/MessagingToneGate.js +15 -1
  89. package/dist/core/MessagingToneGate.js.map +1 -1
  90. package/dist/core/MobileDeviceKeys.d.ts +10 -0
  91. package/dist/core/MobileDeviceKeys.d.ts.map +1 -1
  92. package/dist/core/MobileDeviceKeys.js +17 -0
  93. package/dist/core/MobileDeviceKeys.js.map +1 -1
  94. package/dist/core/MultiMachineCoordinator.d.ts +12 -0
  95. package/dist/core/MultiMachineCoordinator.d.ts.map +1 -1
  96. package/dist/core/MultiMachineCoordinator.js +115 -3
  97. package/dist/core/MultiMachineCoordinator.js.map +1 -1
  98. package/dist/core/MutualSshRuntime.d.ts +1 -0
  99. package/dist/core/MutualSshRuntime.d.ts.map +1 -1
  100. package/dist/core/MutualSshRuntime.js +17 -1
  101. package/dist/core/MutualSshRuntime.js.map +1 -1
  102. package/dist/core/ObservedEndpointTracker.d.ts +1 -0
  103. package/dist/core/ObservedEndpointTracker.d.ts.map +1 -1
  104. package/dist/core/ObservedEndpointTracker.js +17 -0
  105. package/dist/core/ObservedEndpointTracker.js.map +1 -1
  106. package/dist/core/OverloadShedPlanner.d.ts.map +1 -1
  107. package/dist/core/OverloadShedPlanner.js +9 -0
  108. package/dist/core/OverloadShedPlanner.js.map +1 -1
  109. package/dist/core/OwnershipApplier.d.ts.map +1 -1
  110. package/dist/core/OwnershipApplier.js +7 -0
  111. package/dist/core/OwnershipApplier.js.map +1 -1
  112. package/dist/core/OwnershipReconciler.d.ts.map +1 -1
  113. package/dist/core/OwnershipReconciler.js +5 -0
  114. package/dist/core/OwnershipReconciler.js.map +1 -1
  115. package/dist/core/PostUpdateMigrator.d.ts +8 -0
  116. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  117. package/dist/core/PostUpdateMigrator.js +76 -2
  118. package/dist/core/PostUpdateMigrator.js.map +1 -1
  119. package/dist/core/PrHandLease.d.ts.map +1 -1
  120. package/dist/core/PrHandLease.js +2 -0
  121. package/dist/core/PrHandLease.js.map +1 -1
  122. package/dist/core/ProactiveSwapMonitor.d.ts.map +1 -1
  123. package/dist/core/ProactiveSwapMonitor.js +7 -0
  124. package/dist/core/ProactiveSwapMonitor.js.map +1 -1
  125. package/dist/core/ProjectRoundExecution.d.ts.map +1 -1
  126. package/dist/core/ProjectRoundExecution.js +3 -2
  127. package/dist/core/ProjectRoundExecution.js.map +1 -1
  128. package/dist/core/QueueDrainLoop.d.ts +7 -0
  129. package/dist/core/QueueDrainLoop.d.ts.map +1 -1
  130. package/dist/core/QueueDrainLoop.js +37 -1
  131. package/dist/core/QueueDrainLoop.js.map +1 -1
  132. package/dist/core/RemoteAckStore.d.ts.map +1 -1
  133. package/dist/core/RemoteAckStore.js +4 -0
  134. package/dist/core/RemoteAckStore.js.map +1 -1
  135. package/dist/core/ReplicatedStoreReconcilerWiring.d.ts.map +1 -1
  136. package/dist/core/ReplicatedStoreReconcilerWiring.js +1 -0
  137. package/dist/core/ReplicatedStoreReconcilerWiring.js.map +1 -1
  138. package/dist/core/SecretSync.d.ts +1 -0
  139. package/dist/core/SecretSync.d.ts.map +1 -1
  140. package/dist/core/SecretSync.js +16 -0
  141. package/dist/core/SecretSync.js.map +1 -1
  142. package/dist/core/SessionManager.d.ts +11 -0
  143. package/dist/core/SessionManager.d.ts.map +1 -1
  144. package/dist/core/SessionManager.js +125 -14
  145. package/dist/core/SessionManager.js.map +1 -1
  146. package/dist/core/SessionPoolFailoverRunner.d.ts.map +1 -1
  147. package/dist/core/SessionPoolFailoverRunner.js +4 -0
  148. package/dist/core/SessionPoolFailoverRunner.js.map +1 -1
  149. package/dist/core/SleepWakeDetector.d.ts.map +1 -1
  150. package/dist/core/SleepWakeDetector.js +10 -0
  151. package/dist/core/SleepWakeDetector.js.map +1 -1
  152. package/dist/core/SubscriptionReloginStore.d.ts.map +1 -1
  153. package/dist/core/SubscriptionReloginStore.js +10 -1
  154. package/dist/core/SubscriptionReloginStore.js.map +1 -1
  155. package/dist/core/TopicPinMutation.d.ts.map +1 -1
  156. package/dist/core/TopicPinMutation.js +5 -0
  157. package/dist/core/TopicPinMutation.js.map +1 -1
  158. package/dist/core/UnjustifiedStopGate.d.ts.map +1 -1
  159. package/dist/core/UnjustifiedStopGate.js +22 -0
  160. package/dist/core/UnjustifiedStopGate.js.map +1 -1
  161. package/dist/core/WindowRunCadenceExecutor.d.ts.map +1 -1
  162. package/dist/core/WindowRunCadenceExecutor.js +20 -0
  163. package/dist/core/WindowRunCadenceExecutor.js.map +1 -1
  164. package/dist/core/claudeChildAuth.d.ts +68 -0
  165. package/dist/core/claudeChildAuth.d.ts.map +1 -0
  166. package/dist/core/claudeChildAuth.js +173 -0
  167. package/dist/core/claudeChildAuth.js.map +1 -0
  168. package/dist/core/claudeKeyProbe.d.ts +23 -0
  169. package/dist/core/claudeKeyProbe.d.ts.map +1 -0
  170. package/dist/core/claudeKeyProbe.js +68 -0
  171. package/dist/core/claudeKeyProbe.js.map +1 -0
  172. package/dist/core/codexDeviceLimitWiring.d.ts.map +1 -1
  173. package/dist/core/codexDeviceLimitWiring.js +12 -0
  174. package/dist/core/codexDeviceLimitWiring.js.map +1 -1
  175. package/dist/core/deliverToConversation.d.ts.map +1 -1
  176. package/dist/core/deliverToConversation.js +11 -0
  177. package/dist/core/deliverToConversation.js.map +1 -1
  178. package/dist/core/meteredCallEntry.d.ts.map +1 -1
  179. package/dist/core/meteredCallEntry.js +21 -0
  180. package/dist/core/meteredCallEntry.js.map +1 -1
  181. package/dist/core/nobodyPollingActuator.d.ts.map +1 -1
  182. package/dist/core/nobodyPollingActuator.js +5 -0
  183. package/dist/core/nobodyPollingActuator.js.map +1 -1
  184. package/dist/core/operatorSurfaceReferral.d.ts +18 -0
  185. package/dist/core/operatorSurfaceReferral.d.ts.map +1 -0
  186. package/dist/core/operatorSurfaceReferral.js +32 -0
  187. package/dist/core/operatorSurfaceReferral.js.map +1 -0
  188. package/dist/core/ownershipFollowsLiveWork.d.ts.map +1 -1
  189. package/dist/core/ownershipFollowsLiveWork.js +10 -1
  190. package/dist/core/ownershipFollowsLiveWork.js.map +1 -1
  191. package/dist/core/types.d.ts +15 -0
  192. package/dist/core/types.d.ts.map +1 -1
  193. package/dist/core/types.js.map +1 -1
  194. package/dist/core/worktreeDirtyCheck.d.ts.map +1 -1
  195. package/dist/core/worktreeDirtyCheck.js +2 -0
  196. package/dist/core/worktreeDirtyCheck.js.map +1 -1
  197. package/dist/data/stageBCertifiedSet.d.ts +9 -0
  198. package/dist/data/stageBCertifiedSet.d.ts.map +1 -1
  199. package/dist/data/stageBCertifiedSet.js +12 -0
  200. package/dist/data/stageBCertifiedSet.js.map +1 -1
  201. package/dist/data/standards-guard-index.json +1 -1
  202. package/dist/data/standards-guard-index.meta.json +2 -2
  203. package/dist/data/standards-registry.meta.json +1 -1
  204. package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
  205. package/dist/lifeline/TelegramLifeline.js +17 -3
  206. package/dist/lifeline/TelegramLifeline.js.map +1 -1
  207. package/dist/messaging/attentionHubPolicy.d.ts.map +1 -1
  208. package/dist/messaging/attentionHubPolicy.js +1 -0
  209. package/dist/messaging/attentionHubPolicy.js.map +1 -1
  210. package/dist/monitoring/AgentWorktreeReaper.d.ts.map +1 -1
  211. package/dist/monitoring/AgentWorktreeReaper.js +15 -0
  212. package/dist/monitoring/AgentWorktreeReaper.js.map +1 -1
  213. package/dist/monitoring/ApprenticeshipCycleSlaMonitor.d.ts.map +1 -1
  214. package/dist/monitoring/ApprenticeshipCycleSlaMonitor.js +18 -9
  215. package/dist/monitoring/ApprenticeshipCycleSlaMonitor.js.map +1 -1
  216. package/dist/monitoring/CodexArmSessionSweeper.d.ts.map +1 -1
  217. package/dist/monitoring/CodexArmSessionSweeper.js +11 -0
  218. package/dist/monitoring/CodexArmSessionSweeper.js.map +1 -1
  219. package/dist/monitoring/CrashLoopPauser.d.ts.map +1 -1
  220. package/dist/monitoring/CrashLoopPauser.js +8 -0
  221. package/dist/monitoring/CrashLoopPauser.js.map +1 -1
  222. package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
  223. package/dist/monitoring/DegradationReporter.js +7 -1
  224. package/dist/monitoring/DegradationReporter.js.map +1 -1
  225. package/dist/monitoring/DegradedTmuxGuard.d.ts +2 -0
  226. package/dist/monitoring/DegradedTmuxGuard.d.ts.map +1 -1
  227. package/dist/monitoring/DegradedTmuxGuard.js +14 -0
  228. package/dist/monitoring/DegradedTmuxGuard.js.map +1 -1
  229. package/dist/monitoring/DurableOutputScrubber.d.ts.map +1 -1
  230. package/dist/monitoring/DurableOutputScrubber.js +7 -0
  231. package/dist/monitoring/DurableOutputScrubber.js.map +1 -1
  232. package/dist/monitoring/DurableVaultSession.d.ts.map +1 -1
  233. package/dist/monitoring/DurableVaultSession.js +15 -0
  234. package/dist/monitoring/DurableVaultSession.js.map +1 -1
  235. package/dist/monitoring/ExternalHogSentinel.d.ts +2 -0
  236. package/dist/monitoring/ExternalHogSentinel.d.ts.map +1 -1
  237. package/dist/monitoring/ExternalHogSentinel.js +27 -1
  238. package/dist/monitoring/ExternalHogSentinel.js.map +1 -1
  239. package/dist/monitoring/FailureLedger.d.ts.map +1 -1
  240. package/dist/monitoring/FailureLedger.js +38 -1
  241. package/dist/monitoring/FailureLedger.js.map +1 -1
  242. package/dist/monitoring/FeatureEvidenceLog.d.ts +5 -0
  243. package/dist/monitoring/FeatureEvidenceLog.d.ts.map +1 -1
  244. package/dist/monitoring/FeatureEvidenceLog.js +25 -0
  245. package/dist/monitoring/FeatureEvidenceLog.js.map +1 -1
  246. package/dist/monitoring/GeminiCapacityEscalationMonitor.d.ts.map +1 -1
  247. package/dist/monitoring/GeminiCapacityEscalationMonitor.js +20 -2
  248. package/dist/monitoring/GeminiCapacityEscalationMonitor.js.map +1 -1
  249. package/dist/monitoring/GeminiLoopRunner.d.ts.map +1 -1
  250. package/dist/monitoring/GeminiLoopRunner.js +11 -1
  251. package/dist/monitoring/GeminiLoopRunner.js.map +1 -1
  252. package/dist/monitoring/GreenPrAutoMerger.d.ts.map +1 -1
  253. package/dist/monitoring/GreenPrAutoMerger.js +11 -0
  254. package/dist/monitoring/GreenPrAutoMerger.js.map +1 -1
  255. package/dist/monitoring/GrowthDigestPublisher.d.ts.map +1 -1
  256. package/dist/monitoring/GrowthDigestPublisher.js +16 -0
  257. package/dist/monitoring/GrowthDigestPublisher.js.map +1 -1
  258. package/dist/monitoring/GrowthMilestoneAnalyst.d.ts +3 -0
  259. package/dist/monitoring/GrowthMilestoneAnalyst.d.ts.map +1 -1
  260. package/dist/monitoring/GrowthMilestoneAnalyst.js +45 -1
  261. package/dist/monitoring/GrowthMilestoneAnalyst.js.map +1 -1
  262. package/dist/monitoring/McpProcessReaper.d.ts +2 -0
  263. package/dist/monitoring/McpProcessReaper.d.ts.map +1 -1
  264. package/dist/monitoring/McpProcessReaper.js +32 -0
  265. package/dist/monitoring/McpProcessReaper.js.map +1 -1
  266. package/dist/monitoring/MissingLoginSessionDetector.d.ts +2 -1
  267. package/dist/monitoring/MissingLoginSessionDetector.d.ts.map +1 -1
  268. package/dist/monitoring/MissingLoginSessionDetector.js +23 -0
  269. package/dist/monitoring/MissingLoginSessionDetector.js.map +1 -1
  270. package/dist/monitoring/OrchestratorPoller.d.ts +1 -0
  271. package/dist/monitoring/OrchestratorPoller.d.ts.map +1 -1
  272. package/dist/monitoring/OrchestratorPoller.js +13 -0
  273. package/dist/monitoring/OrchestratorPoller.js.map +1 -1
  274. package/dist/monitoring/OrphanedWorkSentinel.d.ts.map +1 -1
  275. package/dist/monitoring/OrphanedWorkSentinel.js +7 -0
  276. package/dist/monitoring/OrphanedWorkSentinel.js.map +1 -1
  277. package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
  278. package/dist/monitoring/PresenceProxy.js +9 -1
  279. package/dist/monitoring/PresenceProxy.js.map +1 -1
  280. package/dist/monitoring/ProcessFootprintMonitor.d.ts.map +1 -1
  281. package/dist/monitoring/ProcessFootprintMonitor.js +20 -2
  282. package/dist/monitoring/ProcessFootprintMonitor.js.map +1 -1
  283. package/dist/monitoring/PromiseBeacon.d.ts.map +1 -1
  284. package/dist/monitoring/PromiseBeacon.js +20 -0
  285. package/dist/monitoring/PromiseBeacon.js.map +1 -1
  286. package/dist/monitoring/ReleaseReadinessSentinel.d.ts +2 -0
  287. package/dist/monitoring/ReleaseReadinessSentinel.d.ts.map +1 -1
  288. package/dist/monitoring/ReleaseReadinessSentinel.js +26 -0
  289. package/dist/monitoring/ReleaseReadinessSentinel.js.map +1 -1
  290. package/dist/monitoring/RopeHealthMonitor.d.ts.map +1 -1
  291. package/dist/monitoring/RopeHealthMonitor.js +35 -1
  292. package/dist/monitoring/RopeHealthMonitor.js.map +1 -1
  293. package/dist/monitoring/SentinelNotifier.d.ts.map +1 -1
  294. package/dist/monitoring/SentinelNotifier.js +16 -0
  295. package/dist/monitoring/SentinelNotifier.js.map +1 -1
  296. package/dist/monitoring/SessionReaper.d.ts.map +1 -1
  297. package/dist/monitoring/SessionReaper.js +11 -2
  298. package/dist/monitoring/SessionReaper.js.map +1 -1
  299. package/dist/monitoring/SingleMachineFailoverGapDetector.d.ts +2 -0
  300. package/dist/monitoring/SingleMachineFailoverGapDetector.d.ts.map +1 -1
  301. package/dist/monitoring/SingleMachineFailoverGapDetector.js +20 -0
  302. package/dist/monitoring/SingleMachineFailoverGapDetector.js.map +1 -1
  303. package/dist/monitoring/SpeakerElection.d.ts.map +1 -1
  304. package/dist/monitoring/SpeakerElection.js +8 -0
  305. package/dist/monitoring/SpeakerElection.js.map +1 -1
  306. package/dist/monitoring/StrandedTopicSentinel.d.ts +3 -0
  307. package/dist/monitoring/StrandedTopicSentinel.d.ts.map +1 -1
  308. package/dist/monitoring/StrandedTopicSentinel.js +33 -0
  309. package/dist/monitoring/StrandedTopicSentinel.js.map +1 -1
  310. package/dist/native/InstarWedgeCanary.app/Contents/MacOS/InstarWedgeCanary +0 -0
  311. package/dist/native/instar-desktop-host +0 -0
  312. package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.d.ts.map +1 -1
  313. package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.js +5 -2
  314. package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.js.map +1 -1
  315. package/dist/recommended/RecommendedServicesLedger.d.ts +91 -0
  316. package/dist/recommended/RecommendedServicesLedger.d.ts.map +1 -0
  317. package/dist/recommended/RecommendedServicesLedger.js +193 -0
  318. package/dist/recommended/RecommendedServicesLedger.js.map +1 -0
  319. package/dist/recommended/RecommendedServicesReplicatedStore.d.ts +14 -0
  320. package/dist/recommended/RecommendedServicesReplicatedStore.d.ts.map +1 -0
  321. package/dist/recommended/RecommendedServicesReplicatedStore.js +34 -0
  322. package/dist/recommended/RecommendedServicesReplicatedStore.js.map +1 -0
  323. package/dist/recommended/legacyDeclines.d.ts +11 -0
  324. package/dist/recommended/legacyDeclines.d.ts.map +1 -0
  325. package/dist/recommended/legacyDeclines.js +17 -0
  326. package/dist/recommended/legacyDeclines.js.map +1 -0
  327. package/dist/recommended/serviceIds.d.ts +3 -0
  328. package/dist/recommended/serviceIds.d.ts.map +1 -0
  329. package/dist/recommended/serviceIds.js +6 -0
  330. package/dist/recommended/serviceIds.js.map +1 -0
  331. package/dist/scaffold/templates.d.ts +2 -0
  332. package/dist/scaffold/templates.d.ts.map +1 -1
  333. package/dist/scaffold/templates.js +8 -0
  334. package/dist/scaffold/templates.js.map +1 -1
  335. package/dist/scheduler/JobResultTriage.d.ts.map +1 -1
  336. package/dist/scheduler/JobResultTriage.js +10 -0
  337. package/dist/scheduler/JobResultTriage.js.map +1 -1
  338. package/dist/scheduler/JobScheduler.d.ts.map +1 -1
  339. package/dist/scheduler/JobScheduler.js +12 -0
  340. package/dist/scheduler/JobScheduler.js.map +1 -1
  341. package/dist/scheduler/MentorOnboardingRunner.d.ts +3 -0
  342. package/dist/scheduler/MentorOnboardingRunner.d.ts.map +1 -1
  343. package/dist/scheduler/MentorOnboardingRunner.js +24 -2
  344. package/dist/scheduler/MentorOnboardingRunner.js.map +1 -1
  345. package/dist/server/AgentServer.d.ts +2 -0
  346. package/dist/server/AgentServer.d.ts.map +1 -1
  347. package/dist/server/AgentServer.js +76 -15
  348. package/dist/server/AgentServer.js.map +1 -1
  349. package/dist/server/BootHealthBeacon.d.ts +3 -0
  350. package/dist/server/BootHealthBeacon.d.ts.map +1 -1
  351. package/dist/server/BootHealthBeacon.js +9 -0
  352. package/dist/server/BootHealthBeacon.js.map +1 -1
  353. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  354. package/dist/server/CapabilityIndex.js +10 -1
  355. package/dist/server/CapabilityIndex.js.map +1 -1
  356. package/dist/server/LifelineIngressGuard.d.ts.map +1 -1
  357. package/dist/server/LifelineIngressGuard.js +11 -0
  358. package/dist/server/LifelineIngressGuard.js.map +1 -1
  359. package/dist/server/PoolPollCache.d.ts +4 -0
  360. package/dist/server/PoolPollCache.d.ts.map +1 -1
  361. package/dist/server/PoolPollCache.js +33 -0
  362. package/dist/server/PoolPollCache.js.map +1 -1
  363. package/dist/server/machineRoutes.d.ts.map +1 -1
  364. package/dist/server/machineRoutes.js +6 -0
  365. package/dist/server/machineRoutes.js.map +1 -1
  366. package/dist/server/middleware.d.ts.map +1 -1
  367. package/dist/server/middleware.js +6 -0
  368. package/dist/server/middleware.js.map +1 -1
  369. package/dist/server/mobileConsoleTicket.d.ts +113 -0
  370. package/dist/server/mobileConsoleTicket.d.ts.map +1 -0
  371. package/dist/server/mobileConsoleTicket.js +405 -0
  372. package/dist/server/mobileConsoleTicket.js.map +1 -0
  373. package/dist/server/mobileConversationRoutes.d.ts.map +1 -1
  374. package/dist/server/mobileConversationRoutes.js +20 -1
  375. package/dist/server/mobileConversationRoutes.js.map +1 -1
  376. package/dist/server/mobileMediaRoutes.d.ts.map +1 -1
  377. package/dist/server/mobileMediaRoutes.js +3 -0
  378. package/dist/server/mobileMediaRoutes.js.map +1 -1
  379. package/dist/server/mobilePairingRoutes.d.ts +8 -2
  380. package/dist/server/mobilePairingRoutes.d.ts.map +1 -1
  381. package/dist/server/mobilePairingRoutes.js +67 -6
  382. package/dist/server/mobilePairingRoutes.js.map +1 -1
  383. package/dist/server/mobileSessionTerminalRoutes.d.ts +128 -0
  384. package/dist/server/mobileSessionTerminalRoutes.d.ts.map +1 -0
  385. package/dist/server/mobileSessionTerminalRoutes.js +389 -0
  386. package/dist/server/mobileSessionTerminalRoutes.js.map +1 -0
  387. package/dist/server/recommendedServiceRoutes.d.ts +13 -0
  388. package/dist/server/recommendedServiceRoutes.d.ts.map +1 -0
  389. package/dist/server/recommendedServiceRoutes.js +49 -0
  390. package/dist/server/recommendedServiceRoutes.js.map +1 -0
  391. package/dist/server/routes.d.ts +2 -0
  392. package/dist/server/routes.d.ts.map +1 -1
  393. package/dist/server/routes.js +170 -4
  394. package/dist/server/routes.js.map +1 -1
  395. package/dist/testing/selfActionRegistry.d.ts.map +1 -1
  396. package/dist/testing/selfActionRegistry.js +36 -0
  397. package/dist/testing/selfActionRegistry.js.map +1 -1
  398. package/dist/threadline/A2ACheckInProxy.d.ts.map +1 -1
  399. package/dist/threadline/A2ACheckInProxy.js +26 -15
  400. package/dist/threadline/A2ACheckInProxy.js.map +1 -1
  401. package/dist/threadline/AgentTrustManager.d.ts.map +1 -1
  402. package/dist/threadline/AgentTrustManager.js +3 -0
  403. package/dist/threadline/AgentTrustManager.js.map +1 -1
  404. package/dist/threadline/InboundIdLedger.d.ts.map +1 -1
  405. package/dist/threadline/InboundIdLedger.js +18 -1
  406. package/dist/threadline/InboundIdLedger.js.map +1 -1
  407. package/dist/threadline/NegotiatorGate.d.ts.map +1 -1
  408. package/dist/threadline/NegotiatorGate.js +11 -0
  409. package/dist/threadline/NegotiatorGate.js.map +1 -1
  410. package/dist/threadline/PipeSessionSpawner.d.ts.map +1 -1
  411. package/dist/threadline/PipeSessionSpawner.js +8 -0
  412. package/dist/threadline/PipeSessionSpawner.js.map +1 -1
  413. package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
  414. package/dist/threadline/ThreadlineRouter.js +13 -0
  415. package/dist/threadline/ThreadlineRouter.js.map +1 -1
  416. package/dist/threadline/pairingReplicationWiring.d.ts.map +1 -1
  417. package/dist/threadline/pairingReplicationWiring.js +9 -0
  418. package/dist/threadline/pairingReplicationWiring.js.map +1 -1
  419. package/dist/threadline/relayForward.d.ts.map +1 -1
  420. package/dist/threadline/relayForward.js +13 -2
  421. package/dist/threadline/relayForward.js.map +1 -1
  422. package/dist/threadline/relayUnknownSenderTrust.d.ts +0 -9
  423. package/dist/threadline/relayUnknownSenderTrust.d.ts.map +1 -1
  424. package/dist/threadline/relayUnknownSenderTrust.js +16 -0
  425. package/dist/threadline/relayUnknownSenderTrust.js.map +1 -1
  426. package/package.json +1 -1
  427. package/scripts/check-constitution-pairing.mjs +273 -0
  428. package/scripts/safe-merge.mjs +9 -0
  429. package/src/data/builtin-manifest.json +103 -103
  430. package/src/data/feature-ladders.json +113 -113
  431. package/src/data/stageBCertifiedSet.ts +12 -0
  432. package/src/data/standards-guard-index.json +1 -1
  433. package/src/data/standards-guard-index.meta.json +2 -2
  434. package/src/data/standards-registry.meta.json +1 -1
  435. package/src/data/state-coherence-registry.json +18 -0
  436. package/src/scaffold/templates.ts +9 -0
  437. package/upgrades/1.3.1650.md +105 -0
  438. package/upgrades/mobile-console-device-signin.eli16.md +5 -0
  439. package/upgrades/side-effects/cloud-key-internal-calls.md +116 -0
  440. package/upgrades/side-effects/constitution-alignment.eli16.md +11 -0
  441. package/upgrades/side-effects/constitution-alignment.md +69 -0
  442. package/upgrades/side-effects/feature-evidence-recording.eli16.md +3 -0
  443. package/upgrades/side-effects/feature-evidence-recording.md +66 -0
  444. package/upgrades/side-effects/feedback-reroute-admission-parity.md +77 -0
  445. package/upgrades/side-effects/mobile-console-device-signin.md +102 -0
  446. package/upgrades/side-effects/mobile-native-session-screen.md +88 -0
  447. package/upgrades/side-effects/operator-needs-first-screen.md +87 -0
  448. package/upgrades/side-effects/recommended-services-choices.md +50 -0
  449. package/upgrades/side-effects/rerouted-lifetime-active-process.md +63 -0
  450. package/upgrades/side-effects/undated-resurfacer-e2e-wait.eli16.md +5 -0
  451. package/upgrades/side-effects/undated-resurfacer-e2e-wait.md +9 -0
@@ -0,0 +1,389 @@
1
+ /**
2
+ * The native session screen for the Instar iPhone app (docs/specs/mobile-native-session-screen.md).
3
+ *
4
+ * GET /sessions/:name/output?lines=N read a session's pane
5
+ * POST /sessions/:name/input {text} type plain text into it
6
+ *
7
+ * The same paths serve the dashboard with the Bearer token; this router handles ONLY requests
8
+ * signed by a paired phone and passes every other request on untouched (`next()`), so the Bearer
9
+ * handlers in routes.ts keep their exact behaviour. It is mounted before the main routes.
10
+ *
11
+ * Device requests reach here only through the DEVICE_ALLOWLIST entries flagged `ownerOnly`: the
12
+ * phone is active, its signature verified, and its person is the owner. On top of that the router
13
+ * re-checks the owner, resolves the name to exactly one session record running on THIS machine
14
+ * (tmux name, then id, then name; ambiguous → 409), refuses control characters in typed text,
15
+ * reads the pane without blocking the event loop, and logs every typed message without its text.
16
+ * A session that is not here is named from this machine's registry when a peer lists it; it is
17
+ * never proxied.
18
+ */
19
+ import crypto from 'node:crypto';
20
+ import fs from 'node:fs';
21
+ import path from 'node:path';
22
+ import { Router } from 'express';
23
+ import { devicePersonOf, deviceAdmittedHost } from './mobilePairingRoutes.js';
24
+ import { verifiedEntityName } from '../messaging/shared/channelIdentity.js';
25
+ import { REPLAY_TTL_MS, canonicalString } from '../core/MobileDeviceKeys.js';
26
+ /** The session name shape the Bearer routes accept (routes.ts SESSION_NAME_RE). */
27
+ export const DEVICE_SESSION_NAME_RE = /^[a-zA-Z0-9_-]{1,200}$/;
28
+ export const DEVICE_INPUT_MAX = 8000;
29
+ export const DEVICE_OUTPUT_DEFAULT_LINES = 200;
30
+ export const DEVICE_OUTPUT_MAX_LINES = 2000;
31
+ export const MISS_CACHE_FOUND_MS = 15_000;
32
+ export const MISS_CACHE_NEGATIVE_MS = 3_000;
33
+ export const MISS_NAMES_PER_DEVICE_PER_MINUTE = 8;
34
+ export const PEER_LOOKUP_TIMEOUT_MS = 3000;
35
+ export const PEER_LOOKUP_MAX = 16;
36
+ export const AUDIT_ROTATE_BYTES = 2 * 1024 * 1024;
37
+ export const NOT_RUNNING_REASON = 'This session is not running any more. It may have finished or been closed.';
38
+ export const LOCATION_UNKNOWN_REASON = 'This session is not running on this machine, and I could not reach your other machines to check where it is.';
39
+ export const BAD_TEXT_REASON = 'Only plain text can be typed into a session from the phone.';
40
+ export const SEND_FAILED_REASON = 'The session could not take your text right now. It may be starting or restarting; try again in a moment.';
41
+ export const OWNER_ONLY_REASON = "Only the owner's phone can open sessions.";
42
+ export const SESSION_REPLACED_REASON = 'This session ended and a new one took its name. Reopen it from the sessions list.';
43
+ export const INPUT_BUSY_REASON = 'Too many messages were typed from phones in the last minute. Wait a moment and send again.';
44
+ /** Device inputs per minute across ALL phones on this machine (each holds the event loop briefly). */
45
+ export const DEVICE_INPUT_MACHINE_PER_MINUTE = 12;
46
+ /** The answer for a request bound to another machine: it repeats the phone's own claim. */
47
+ export function requestedMachineReason(nickname) {
48
+ return nickname ? `You opened a session on ${nickname}. Open it from ${nickname}.` : 'You opened a session on another of your machines. Open it from that machine.';
49
+ }
50
+ /**
51
+ * Remove this agent's own credentials from pane text before a device sees it (mobile-device-keys
52
+ * §2.3: nothing a device receives may outlive its revocation): the API token, the dashboard PIN,
53
+ * and private-view `sig=` values. Values shorter than 4 characters are not replaced (they would
54
+ * mangle ordinary text and are not credentials worth the name).
55
+ */
56
+ export function redactForDevice(text, secrets) {
57
+ let out = text.replace(/([?&]sig=)[0-9a-fA-F]{16,}/g, '$1removed');
58
+ const vals = [...new Set(secrets.filter((v) => typeof v === 'string' && v.length >= 4))].sort((a, b) => b.length - a.length);
59
+ for (const v of vals)
60
+ out = out.split(v).join('[redacted]');
61
+ return out;
62
+ }
63
+ export const REPLAY_REASON = 'This exact request was already received, so it was not typed in again.';
64
+ export const REPLAY_RECORD_REASON = 'The agent could not record this request safely, so it was not typed in. Try again in a moment.';
65
+ /** The plain reason for a session another machine runs (the "Open session" sentence shape). */
66
+ export function otherMachineReason(nickname) {
67
+ return nickname
68
+ ? `This session runs on ${nickname}, not on this machine. Open it from ${nickname}.`
69
+ : 'This session runs on another of your machines, whose name I could not confirm, not on this machine.';
70
+ }
71
+ /** Any control character other than newline and tab: C0, DEL, C1. */
72
+ const CONTROL_RE = /[\u0000-\u0008\u000B-\u001F\u007F-\u009F]/;
73
+ export function isPlainDeviceText(text) { return !CONTROL_RE.test(text); }
74
+ /**
75
+ * Exactly one running/starting record, matched exactly: tmux name, then id, then name. The first
76
+ * field that matches any record decides; two records matching on that field is ambiguous.
77
+ */
78
+ export function resolveDeviceSession(records, name) {
79
+ const live = records.filter((r) => r.status === 'running' || r.status === 'starting');
80
+ for (const field of ['tmuxSession', 'id', 'name']) {
81
+ const hits = live.filter((r) => r[field] === name);
82
+ if (hits.length === 1)
83
+ return { kind: 'found', session: hits[0] };
84
+ if (hits.length > 1)
85
+ return { kind: 'ambiguous' };
86
+ }
87
+ return { kind: 'missing' };
88
+ }
89
+ /** Classify a local miss from the peers' answers (pure; never names a machine nobody reported). */
90
+ export function classifyMiss(answers, nicknameOf) {
91
+ const hits = answers.filter((a) => 'found' in a && a.found);
92
+ // Two machines listing the name: it does not identify one session, so no machine is named.
93
+ if (hits.length > 1)
94
+ return { error: 'session-location-unknown', reason: LOCATION_UNKNOWN_REASON };
95
+ const hit = hits[0];
96
+ if (hit) {
97
+ const nick = verifiedEntityName(hit.machineId, nicknameOf(hit.machineId)) ?? null;
98
+ return { error: 'session-on-other-machine', reason: otherMachineReason(nick), ownerMachine: { machineId: hit.machineId, nickname: nick } };
99
+ }
100
+ if (answers.some((a) => 'failed' in a))
101
+ return { error: 'session-location-unknown', reason: LOCATION_UNKNOWN_REASON };
102
+ return { error: 'session-not-running', reason: NOT_RUNNING_REASON };
103
+ }
104
+ /** Does one peer's GET /sessions row list match `name` in the device order? */
105
+ export function peerRowsMatch(rows, name) {
106
+ if (!Array.isArray(rows))
107
+ return false;
108
+ const live = rows.filter((r) => !!r && typeof r === 'object' && (r.status === 'running' || r.status === 'starting'));
109
+ return ['tmuxSession', 'id', 'name'].some((f) => live.some((r) => r[f] === name));
110
+ }
111
+ const principalOf = (req) => (req.instarPrincipal) ?? { kind: 'token' };
112
+ /**
113
+ * The durable replay record for device input (spec: Replay across a restart). The verifier's replay
114
+ * set lives in memory; input is the first allowlisted device route that is neither idempotent nor
115
+ * deduplicated, so each accepted input's signature digest is written here BEFORE it is typed and kept
116
+ * for REPLAY_TTL_MS (longer than the verifier's +/- DEVICE_TIME_WINDOW_MS window). A captured request
117
+ * can then never be typed twice, across restarts and whatever the phone's clock says.
118
+ */
119
+ export class DeviceInputReplayRecord {
120
+ file;
121
+ now;
122
+ entries = null;
123
+ constructor(file, now = Date.now) {
124
+ this.file = file;
125
+ this.now = now;
126
+ }
127
+ load() {
128
+ if (this.entries)
129
+ return this.entries;
130
+ const m = new Map();
131
+ try {
132
+ const raw = JSON.parse(fs.readFileSync(this.file, 'utf8'));
133
+ for (const [k, v] of Object.entries(raw))
134
+ if (typeof v === 'number')
135
+ m.set(k, v);
136
+ }
137
+ catch { /* @silent-fallback-ok — no record yet (or unreadable: rewritten on the next admit) */ }
138
+ this.entries = m;
139
+ return m;
140
+ }
141
+ /** The digest of a request's canonical signed string (the string the verifier's replay set keys on). */
142
+ static digest(canonical) {
143
+ return crypto.createHash('sha256').update(canonical).digest('hex');
144
+ }
145
+ /** 'ok' after durably recording the digest; 'replay' if already recorded; 'unavailable' if it could not be written. */
146
+ admit(digest) {
147
+ const m = this.load();
148
+ const t = this.now();
149
+ for (const [k, at] of m)
150
+ if (t - at > REPLAY_TTL_MS)
151
+ m.delete(k);
152
+ if (m.has(digest))
153
+ return 'replay';
154
+ m.set(digest, t);
155
+ try {
156
+ fs.mkdirSync(path.dirname(this.file), { recursive: true });
157
+ const tmp = `${this.file}.${process.pid}.tmp`;
158
+ fs.writeFileSync(tmp, JSON.stringify(Object.fromEntries(m)), { mode: 0o600 });
159
+ fs.renameSync(tmp, this.file);
160
+ return 'ok';
161
+ }
162
+ catch (err) {
163
+ m.delete(digest);
164
+ console.error(`[mobile-session-input] replay record write failed: ${err instanceof Error ? err.message : String(err)}`);
165
+ return 'unavailable';
166
+ }
167
+ }
168
+ }
169
+ /** Append one audit line (no text), rotating to `.1` past AUDIT_ROTATE_BYTES. Best effort. */
170
+ export function appendInputAudit(stateDir, row) {
171
+ const dir = path.join(stateDir, 'logs');
172
+ const file = path.join(dir, 'mobile-session-input.jsonl');
173
+ try {
174
+ fs.mkdirSync(dir, { recursive: true });
175
+ try {
176
+ if (fs.statSync(file).size > AUDIT_ROTATE_BYTES)
177
+ fs.renameSync(file, `${file}.1`);
178
+ }
179
+ catch { /* @silent-fallback-ok — no file yet */ }
180
+ fs.appendFileSync(file, JSON.stringify(row) + '\n', { mode: 0o600 });
181
+ }
182
+ catch (err) {
183
+ // @silent-fallback-ok — the audit is a record, not a gate; the failure is logged loudly.
184
+ console.error(`[mobile-session-input] audit write failed: ${err instanceof Error ? err.message : String(err)}`);
185
+ }
186
+ }
187
+ export function createMobileSessionTerminalRouter(deps) {
188
+ const router = Router();
189
+ const now = deps.now ?? Date.now;
190
+ const missCache = new Map();
191
+ const inFlight = new Map();
192
+ const missNames = new Map();
193
+ let machineInputs = [];
194
+ const replayRecord = deps.replayRecord ?? new DeviceInputReplayRecord(path.join(deps.stateDir, 'state', 'mobile-session-input-replay.json'), now);
195
+ /** One fan-out per name per cache window (15 s found elsewhere, 3 s otherwise), shared by concurrent callers; per-device name cap. */
196
+ async function missAnswer(deviceId, name) {
197
+ const t = now();
198
+ const ttl = (a) => (a.error === 'session-on-other-machine' ? MISS_CACHE_FOUND_MS : MISS_CACHE_NEGATIVE_MS);
199
+ for (const [k, v] of missCache)
200
+ if (t - v.at >= ttl(v.answer))
201
+ missCache.delete(k);
202
+ const cached = missCache.get(name);
203
+ if (cached)
204
+ return cached.answer;
205
+ const pending = inFlight.get(name);
206
+ if (pending)
207
+ return pending;
208
+ for (const [k, v] of missNames) {
209
+ const kept = v.filter((x) => t - x.at < 60_000);
210
+ if (kept.length)
211
+ missNames.set(k, kept);
212
+ else
213
+ missNames.delete(k);
214
+ }
215
+ const recent = missNames.get(deviceId) ?? [];
216
+ if (!recent.some((x) => x.name === name)) {
217
+ if (recent.length >= MISS_NAMES_PER_DEVICE_PER_MINUTE)
218
+ return { error: 'session-location-unknown', reason: LOCATION_UNKNOWN_REASON };
219
+ recent.push({ at: t, name });
220
+ missNames.set(deviceId, recent);
221
+ }
222
+ const p = (async () => {
223
+ let answers;
224
+ try {
225
+ answers = await deps.lookupPeers(name);
226
+ }
227
+ catch {
228
+ answers = [{ machineId: 'unknown', failed: true }];
229
+ } // @silent-fallback-ok — reported as location unknown
230
+ const answer = classifyMiss(answers, deps.nicknameOf);
231
+ missCache.set(name, { at: now(), answer });
232
+ return answer;
233
+ })();
234
+ inFlight.set(name, p);
235
+ try {
236
+ return await p;
237
+ }
238
+ finally {
239
+ inFlight.delete(name);
240
+ }
241
+ }
242
+ /** The common device checks; null when the request was answered (or passed on). */
243
+ function deviceGate(req, res, next) {
244
+ const p = principalOf(req);
245
+ if (p.kind !== 'device') {
246
+ next();
247
+ return null;
248
+ }
249
+ res.setHeader('Cache-Control', 'no-store');
250
+ const person = devicePersonOf(req);
251
+ if (!person || person.role !== 'owner') {
252
+ res.status(403).json({ error: 'owner-phone-required', reason: OWNER_ONLY_REASON });
253
+ return null;
254
+ }
255
+ const name = req.params.name;
256
+ if (typeof name !== 'string' || !DEVICE_SESSION_NAME_RE.test(name)) {
257
+ res.status(400).json({ error: 'bad-session-name' });
258
+ return null;
259
+ }
260
+ // Machine binding: a row from another machine never resolves against this machine's records.
261
+ const machine = typeof req.query.machine === 'string' ? req.query.machine : '';
262
+ const self = deps.selfMachineId();
263
+ if (machine && self && machine !== self) {
264
+ const nick = verifiedEntityName(machine, deps.nicknameOf(machine)) ?? null;
265
+ res.status(404).json({ error: 'session-on-other-machine', reason: requestedMachineReason(nick), ownerMachine: { machineId: machine, nickname: nick } });
266
+ return null;
267
+ }
268
+ const sid = typeof req.query.sid === 'string' ? req.query.sid : '';
269
+ return { deviceId: p.deviceId ?? '', name, local: !!machine && machine === self, sid };
270
+ }
271
+ async function resolveOrAnswer(res, g) {
272
+ const { deviceId, name } = g;
273
+ let records = [];
274
+ try {
275
+ records = deps.listSessions();
276
+ }
277
+ catch {
278
+ records = [];
279
+ } // @silent-fallback-ok — an unreadable registry is a miss
280
+ const r = resolveDeviceSession(records, name);
281
+ if (r.kind === 'found') {
282
+ if (g.sid && r.session.id !== g.sid) {
283
+ res.status(409).json({ error: 'session-replaced', reason: SESSION_REPLACED_REASON });
284
+ return null;
285
+ }
286
+ return r.session;
287
+ }
288
+ if (r.kind === 'ambiguous') {
289
+ res.status(409).json({ error: 'ambiguous-session', reason: 'More than one session has this name. Open it from the sessions list.' });
290
+ return null;
291
+ }
292
+ // The phone asked about THIS machine's session: a same-named session elsewhere is another session.
293
+ if (g.local || g.sid) {
294
+ res.status(404).json({ error: 'session-not-running', reason: NOT_RUNNING_REASON });
295
+ return null;
296
+ }
297
+ res.status(404).json(await missAnswer(deviceId, name));
298
+ return null;
299
+ }
300
+ router.get('/sessions/:name/output', async (req, res, next) => {
301
+ const g = deviceGate(req, res, next);
302
+ if (!g)
303
+ return;
304
+ const s = await resolveOrAnswer(res, g);
305
+ if (!s)
306
+ return;
307
+ const raw = parseInt(String(req.query.lines ?? ''), 10);
308
+ const lines = Number.isFinite(raw) ? Math.min(Math.max(raw, 1), DEVICE_OUTPUT_MAX_LINES) : DEVICE_OUTPUT_DEFAULT_LINES;
309
+ let output = null;
310
+ try {
311
+ output = await deps.captureOutputAsync(s.tmuxSession, lines);
312
+ }
313
+ catch {
314
+ output = null;
315
+ } // @silent-fallback-ok — an unreadable pane answers not running
316
+ if (output === null) {
317
+ res.status(404).json({ error: 'session-not-running', reason: NOT_RUNNING_REASON });
318
+ return;
319
+ }
320
+ let secrets = [];
321
+ try {
322
+ secrets = deps.secrets();
323
+ }
324
+ catch {
325
+ secrets = [];
326
+ } // @silent-fallback-ok — the sig= rewrite still applies
327
+ res.json({ session: s.name, sessionId: s.id, tmuxSession: s.tmuxSession, output: redactForDevice(output, secrets), startedAt: s.startedAt ?? null, machineNickname: deps.selfNickname() });
328
+ });
329
+ router.post('/sessions/:name/input', async (req, res, next) => {
330
+ const g = deviceGate(req, res, next);
331
+ if (!g)
332
+ return;
333
+ const text = (req.body ?? {}).text;
334
+ if (typeof text !== 'string' || text.length === 0) {
335
+ res.status(400).json({ error: 'bad-text', reason: 'Type something to send.' });
336
+ return;
337
+ }
338
+ if (text.length > DEVICE_INPUT_MAX) {
339
+ res.status(400).json({ error: 'bad-text', reason: `Up to ${DEVICE_INPUT_MAX} characters can be sent at once.` });
340
+ return;
341
+ }
342
+ if (!isPlainDeviceText(text)) {
343
+ res.status(400).json({ error: 'bad-text', reason: BAD_TEXT_REASON });
344
+ return;
345
+ }
346
+ const s = await resolveOrAnswer(res, g);
347
+ if (!s)
348
+ return;
349
+ // One machine-wide window across all phones. sendInput is synchronous, so sends never overlap.
350
+ const tNow = now();
351
+ machineInputs = machineInputs.filter((x) => tNow - x < 60_000);
352
+ if (machineInputs.length >= DEVICE_INPUT_MACHINE_PER_MINUTE) {
353
+ res.status(429).json({ error: 'too-many-requests', reason: INPUT_BUSY_REASON });
354
+ return;
355
+ }
356
+ // Durable replay record, written before anything is typed (the verifier's set is in memory).
357
+ const raw = req.rawBody;
358
+ const digest = DeviceInputReplayRecord.digest(canonicalString(g.deviceId, deviceAdmittedHost(req) ?? '', req.method, req.originalUrl, String(req.headers['x-instar-device-time'] ?? ''), raw));
359
+ const admitted = replayRecord.admit(digest);
360
+ if (admitted === 'replay') {
361
+ res.status(409).json({ error: 'replay', reason: REPLAY_REASON });
362
+ return;
363
+ }
364
+ if (admitted === 'unavailable') {
365
+ res.status(503).json({ error: 'replay-record-unavailable', reason: REPLAY_RECORD_REASON });
366
+ return;
367
+ }
368
+ machineInputs.push(tNow);
369
+ let ok = false;
370
+ try {
371
+ ok = deps.sendInput(s.tmuxSession, text);
372
+ }
373
+ catch {
374
+ ok = false;
375
+ } // @silent-fallback-ok — answered as send-failed
376
+ if (!ok) {
377
+ res.status(409).json({ error: 'send-failed', reason: SEND_FAILED_REASON });
378
+ return;
379
+ }
380
+ const person = devicePersonOf(req);
381
+ appendInputAudit(deps.stateDir, {
382
+ at: new Date(now()).toISOString(), deviceId: g.deviceId, role: person?.role ?? null, userId: person?.userId ?? null,
383
+ sessionId: s.id, tmuxSession: s.tmuxSession, textLength: text.length,
384
+ });
385
+ res.json({ ok: true });
386
+ });
387
+ return router;
388
+ }
389
+ //# sourceMappingURL=mobileSessionTerminalRoutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mobileSessionTerminalRoutes.js","sourceRoot":"","sources":["../../src/server/mobileSessionTerminalRoutes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAkD,MAAM,SAAS,CAAC;AAEjF,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE7E,mFAAmF;AACnF,MAAM,CAAC,MAAM,sBAAsB,GAAG,wBAAwB,CAAC;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AACrC,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAC/C,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAC5C,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAC1C,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAC5C,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,CAAC;AAClD,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAC3C,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAElD,MAAM,CAAC,MAAM,kBAAkB,GAAG,4EAA4E,CAAC;AAC/G,MAAM,CAAC,MAAM,uBAAuB,GAAG,8GAA8G,CAAC;AACtJ,MAAM,CAAC,MAAM,eAAe,GAAG,6DAA6D,CAAC;AAC7F,MAAM,CAAC,MAAM,kBAAkB,GAAG,0GAA0G,CAAC;AAC7I,MAAM,CAAC,MAAM,iBAAiB,GAAG,2CAA2C,CAAC;AAC7E,MAAM,CAAC,MAAM,uBAAuB,GAAG,mFAAmF,CAAC;AAC3H,MAAM,CAAC,MAAM,iBAAiB,GAAG,4FAA4F,CAAC;AAC9H,sGAAsG;AACtG,MAAM,CAAC,MAAM,+BAA+B,GAAG,EAAE,CAAC;AAElD,2FAA2F;AAC3F,MAAM,UAAU,sBAAsB,CAAC,QAAuB;IAC5D,OAAO,QAAQ,CAAC,CAAC,CAAC,2BAA2B,QAAQ,kBAAkB,QAAQ,GAAG,CAAC,CAAC,CAAC,8EAA8E,CAAC;AACtK,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,OAAiD;IAC7F,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,6BAA6B,EAAE,WAAW,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAC1I,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5D,OAAO,GAAG,CAAC;AACb,CAAC;AACD,MAAM,CAAC,MAAM,aAAa,GAAG,wEAAwE,CAAC;AACtG,MAAM,CAAC,MAAM,oBAAoB,GAAG,gGAAgG,CAAC;AAErI,+FAA+F;AAC/F,MAAM,UAAU,kBAAkB,CAAC,QAAuB;IACxD,OAAO,QAAQ;QACb,CAAC,CAAC,wBAAwB,QAAQ,uCAAuC,QAAQ,GAAG;QACpF,CAAC,CAAC,qGAAqG,CAAC;AAC5G,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,GAAG,2CAA2C,CAAC;AAC/D,MAAM,UAAU,iBAAiB,CAAC,IAAY,IAAa,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAU3F;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAqC,EAAE,IAAY;IACtF,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;IACtF,KAAK,MAAM,KAAK,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,MAAM,CAAU,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACpD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC7B,CAAC;AAUD,mGAAmG;AACnG,MAAM,UAAU,YAAY,CAAC,OAA8B,EAAE,UAAyC;IACpG,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAA8C,EAAE,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;IACxG,2FAA2F;IAC3F,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,0BAA0B,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IACnG,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,IAAI,GAAG,kBAAkB,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,IAAI,CAAC;QAClF,OAAO,EAAE,KAAK,EAAE,0BAA0B,EAAE,MAAM,EAAE,kBAAkB,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC;IAC7I,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,0BAA0B,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IACtH,OAAO,EAAE,KAAK,EAAE,qBAAqB,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;AACtE,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,aAAa,CAAC,IAAa,EAAE,IAAY;IACvD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAgC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC;IACnJ,OAAQ,CAAC,aAAa,EAAE,IAAI,EAAE,MAAM,CAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;AAC/F,CAAC;AA2BD,MAAM,WAAW,GAAG,CAAC,GAAY,EAAa,EAAE,CAAC,CAAE,GAAkD,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAE5I;;;;;;GAMG;AACH,MAAM,OAAO,uBAAuB;IAEL,IAAI;IAA2B,GAAG;IADvD,OAAO,GAA+B,IAAI,CAAC;IACnD,YAA6B,IAAY,EAAmB,GAAG,GAAiB,IAAI,CAAC,GAAG;oBAA3D,IAAI;mBAA2B,GAAG;IAA4B,CAAC;IAEpF,IAAI;QACV,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC;QACtC,MAAM,CAAC,GAAG,IAAI,GAAG,EAAkB,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAA4B,CAAC;YACtF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;gBAAE,IAAI,OAAO,CAAC,KAAK,QAAQ;oBAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACnF,CAAC;QAAC,MAAM,CAAC,CAAC,sFAAsF,CAAC,CAAC;QAClG,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,wGAAwG;IACxG,MAAM,CAAC,MAAM,CAAC,SAAiB;QAC7B,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrE,CAAC;IAED,uHAAuH;IACvH,KAAK,CAAC,MAAc;QAClB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACrB,KAAK,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC;YAAE,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa;gBAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,QAAQ,CAAC;QACnC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACjB,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;YAC9C,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9E,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,sDAAsD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACxH,OAAO,aAAa,CAAC;QACvB,CAAC;IACH,CAAC;CACF;AAED,8FAA8F;AAC9F,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,GAA4B;IAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,4BAA4B,CAAC,CAAC;IAC1D,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC;YACH,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,kBAAkB;gBAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC,CAAC,uCAAuC,CAAC,CAAC;QACnD,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,yFAAyF;QACzF,OAAO,CAAC,KAAK,CAAC,8CAA8C,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iCAAiC,CAAC,IAA+B;IAC/E,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAA8C,CAAC;IACxE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA+B,CAAC;IACxD,MAAM,SAAS,GAAG,IAAI,GAAG,EAA+C,CAAC;IACzE,IAAI,aAAa,GAAa,EAAE,CAAC;IACjC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,kCAAkC,CAAC,EAAE,GAAG,CAAC,CAAC;IAElJ,sIAAsI;IACtI,KAAK,UAAU,UAAU,CAAC,QAAgB,EAAE,IAAY;QACtD,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,CAAC,CAAa,EAAU,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,0BAA0B,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC;QAC/H,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,SAAS;YAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;gBAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACnF,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC,MAAM,CAAC;QACjC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;QAC5B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC;YAChD,IAAI,IAAI,CAAC,MAAM;gBAAE,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;;gBAAM,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACzC,IAAI,MAAM,CAAC,MAAM,IAAI,gCAAgC;gBAAE,OAAO,EAAE,KAAK,EAAE,0BAA0B,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;YACrI,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7B,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;YACpB,IAAI,OAAqB,CAAC;YAC1B,IAAI,CAAC;gBAAC,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO,GAAG,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAAC,CAAC,CAAC,qDAAqD;YACnK,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YACtD,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3C,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,EAAE,CAAC;QACL,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC;YAAC,OAAO,MAAM,CAAC,CAAC;QAAC,CAAC;gBAAS,CAAC;YAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;IAC5D,CAAC;IAED,mFAAmF;IACnF,SAAS,UAAU,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;QACjE,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAAC,IAAI,EAAE,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QACjD,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QAC5I,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC7B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QACzI,6FAA6F;QAC7F,MAAM,OAAO,GAAG,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC;YAC3E,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,0BAA0B,EAAE,MAAM,EAAE,sBAAsB,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YACxJ,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,GAAG,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,IAAI,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;IACzF,CAAC;IAED,KAAK,UAAU,eAAe,CAAC,GAAa,EAAE,CAAkE;QAC9G,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QAC7B,IAAI,OAAO,GAAwB,EAAE,CAAC;QACtC,IAAI,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;QAAC,CAAC,CAAC,yDAAyD;QACxH,MAAM,CAAC,GAAG,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACvB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC;gBAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC,CAAC;gBAAC,OAAO,IAAI,CAAC;YAAC,CAAC;YAC3I,OAAO,CAAC,CAAC,OAAO,CAAC;QACnB,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,sEAAsE,EAAE,CAAC,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QAClL,mGAAmG;QACnG,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QAC1H,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,wBAAwB,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAC7F,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,MAAM,CAAC,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC;QACvH,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,IAAI,CAAC;YAAC,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,MAAM,GAAG,IAAI,CAAC;QAAC,CAAC,CAAC,+DAA+D;QAC9J,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACpH,IAAI,OAAO,GAAqC,EAAE,CAAC;QACnD,IAAI,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;QAAC,CAAC,CAAC,uDAAuD;QACjH,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,IAAI,EAAE,eAAe,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC7L,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAC7F,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;QACnC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QAC9I,IAAI,IAAI,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,gBAAgB,kCAAkC,EAAE,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACjK,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QAC/G,MAAM,CAAC,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,+FAA+F;QAC/F,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC;QACnB,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;QAC/D,IAAI,aAAa,CAAC,MAAM,IAAI,+BAA+B,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACzJ,6FAA6F;QAC7F,MAAM,GAAG,GAAI,GAAuC,CAAC,OAAO,CAAC;QAC7D,MAAM,MAAM,GAAG,uBAAuB,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,EAAE,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/L,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACxG,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2BAA2B,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACvI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,EAAE,GAAG,KAAK,CAAC;QACf,IAAI,CAAC;YAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,EAAE,GAAG,KAAK,CAAC;QAAC,CAAC,CAAC,gDAAgD;QACxH,IAAI,CAAC,EAAE,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QAChG,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACnC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC9B,EAAE,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI;YACnH,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM;SACrE,CAAC,CAAC;QACH,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Routes for recommended outside services (docs/specs/recommended-services.md, Surfaces).
3
+ * Reading is open to any session. A no is the operator's act, so it needs the PIN, never a
4
+ * bearer token alone. Absent ledger answers 503.
5
+ */
6
+ import type { Request, Response, Router } from 'express';
7
+ import { type RecommendedServicesLedger } from '../recommended/RecommendedServicesLedger.js';
8
+ export interface RecommendedServiceRouteDeps {
9
+ ledger: () => RecommendedServicesLedger | null;
10
+ checkPin: (req: Request, res: Response) => boolean;
11
+ }
12
+ export declare function registerRecommendedServiceRoutes(router: Router, deps: RecommendedServiceRouteDeps): void;
13
+ //# sourceMappingURL=recommendedServiceRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommendedServiceRoutes.d.ts","sourceRoot":"","sources":["../../src/server/recommendedServiceRoutes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EAA6B,KAAK,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAGxH,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,yBAAyB,GAAG,IAAI,CAAC;IAC/C,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC;CACpD;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,2BAA2B,GAAG,IAAI,CA0CxG"}
@@ -0,0 +1,49 @@
1
+ import { NO_REASONS } from '../recommended/RecommendedServicesLedger.js';
2
+ import { RECOMMENDED_SERVICE_IDS } from '../recommended/serviceIds.js';
3
+ export function registerRecommendedServiceRoutes(router, deps) {
4
+ const ledgerOr503 = (res) => {
5
+ const ledger = deps.ledger();
6
+ if (!ledger)
7
+ res.status(503).json({ error: 'recommended-services-unavailable', detail: 'Choices cannot be saved on this machine yet, because it has no machine identity.' });
8
+ return ledger;
9
+ };
10
+ router.get('/recommended-services', (_req, res) => {
11
+ const ledger = ledgerOr503(res);
12
+ if (!ledger)
13
+ return;
14
+ res.json({ services: RECOMMENDED_SERVICE_IDS.map((id) => ledger.effective(id)), offersLive: false, replicating: ledger.isReplicating() });
15
+ });
16
+ router.post('/recommended-services/:id/no', (req, res) => {
17
+ const ledger = ledgerOr503(res);
18
+ if (!ledger)
19
+ return;
20
+ if (!RECOMMENDED_SERVICE_IDS.includes(req.params.id)) {
21
+ res.status(404).json({ error: 'unknown-service' });
22
+ return;
23
+ }
24
+ if (req.headers['x-instar-request'] !== '1') {
25
+ res.status(403).json({ error: 'X-Instar-Request: 1 required' });
26
+ return;
27
+ }
28
+ const { reason = 'none', shutdown = false } = (req.body ?? {});
29
+ if (!NO_REASONS.includes(reason)) {
30
+ res.status(400).json({ error: 'invalid-reason', valid: NO_REASONS });
31
+ return;
32
+ }
33
+ if (typeof shutdown !== 'boolean') {
34
+ res.status(400).json({ error: 'invalid-shutdown' });
35
+ return;
36
+ }
37
+ if (!deps.checkPin(req, res))
38
+ return;
39
+ try {
40
+ ledger.recordNo({ service: req.params.id, reason: reason, shutdown: shutdown ? 'authorized' : 'none', origin: 'owner-surface' });
41
+ }
42
+ catch {
43
+ res.status(503).json({ error: 'recommended-services-unavailable', detail: 'That choice could not be saved. Nothing changed.' });
44
+ return;
45
+ }
46
+ res.json(ledger.effective(req.params.id));
47
+ });
48
+ }
49
+ //# sourceMappingURL=recommendedServiceRoutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommendedServiceRoutes.js","sourceRoot":"","sources":["../../src/server/recommendedServiceRoutes.ts"],"names":[],"mappings":"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"}
@@ -750,6 +750,8 @@ export interface RouteContext {
750
750
  ecosystemIdeas?: () => import('../ecosystem/buildEcosystemIdeas.js').EcosystemRouteContext | {
751
751
  unavailable: 'no-source';
752
752
  } | null;
753
+ /** docs/specs/recommended-services.md. Null when this machine has no identity; the routes answer 503. */
754
+ recommendedServicesLedger?: import('../recommended/RecommendedServicesLedger.js').RecommendedServicesLedger | null;
753
755
  /**
754
756
  * The money-layer OPERATOR ENABLE surface
755
757
  * (docs/specs/money-layer-operator-enable-surface.md). Unlike every field