@abide/abide 0.28.0

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 (562) hide show
  1. package/CHANGELOG.md +607 -0
  2. package/LICENSE +21 -0
  3. package/README.md +154 -0
  4. package/bin/abide.ts +212 -0
  5. package/package.json +155 -0
  6. package/src/abideLsp.ts +211 -0
  7. package/src/abideModules.d.ts +8 -0
  8. package/src/abideResolverPlugin.ts +923 -0
  9. package/src/appEntry.ts +151 -0
  10. package/src/assets/app.html +12 -0
  11. package/src/build.ts +143 -0
  12. package/src/buildCli.ts +127 -0
  13. package/src/buildDisconnected.ts +118 -0
  14. package/src/bundleApp.ts +147 -0
  15. package/src/bundleDisconnectedEntry.ts +14 -0
  16. package/src/checkAbide.ts +77 -0
  17. package/src/cliEntry.ts +25 -0
  18. package/src/clientBuildPlugins.ts +33 -0
  19. package/src/clientEntry.ts +17 -0
  20. package/src/compile.ts +63 -0
  21. package/src/controlServerWorker.ts +426 -0
  22. package/src/devEntry.ts +250 -0
  23. package/src/discoveryEntry.ts +81 -0
  24. package/src/lib/bundle/BundleMenu.ts +12 -0
  25. package/src/lib/bundle/BundleMenuItem.ts +25 -0
  26. package/src/lib/bundle/BundleWindow.ts +37 -0
  27. package/src/lib/bundle/WEBVIEW_BUILD_REVISION.ts +9 -0
  28. package/src/lib/bundle/WEBVIEW_VERSION.ts +7 -0
  29. package/src/lib/bundle/bindConnectedFlag.ts +29 -0
  30. package/src/lib/bundle/bindRequestNavigate.ts +34 -0
  31. package/src/lib/bundle/buildWebviewLib.ts +111 -0
  32. package/src/lib/bundle/bundled.ts +35 -0
  33. package/src/lib/bundle/disconnected.abide +236 -0
  34. package/src/lib/bundle/disconnected.css +9 -0
  35. package/src/lib/bundle/ensureWebviewLib.ts +20 -0
  36. package/src/lib/bundle/exitWithParent.ts +28 -0
  37. package/src/lib/bundle/infoPlist.ts +46 -0
  38. package/src/lib/bundle/installDownloads.ts +24 -0
  39. package/src/lib/bundle/installMacMenu.ts +39 -0
  40. package/src/lib/bundle/listenLocalControlServer.ts +19 -0
  41. package/src/lib/bundle/native/abideMenu.mm +422 -0
  42. package/src/lib/bundle/native/webview.h +4557 -0
  43. package/src/lib/bundle/onMenu.ts +42 -0
  44. package/src/lib/bundle/openWebview.ts +104 -0
  45. package/src/lib/bundle/pngToIcns.ts +47 -0
  46. package/src/lib/bundle/probeAbideServer.ts +57 -0
  47. package/src/lib/bundle/resolveServerBinary.ts +12 -0
  48. package/src/lib/bundle/resolveWebviewLib.ts +53 -0
  49. package/src/lib/bundle/serverBinaryFilename.ts +8 -0
  50. package/src/lib/bundle/signMacApp.ts +37 -0
  51. package/src/lib/bundle/spawnEmbeddedServer.ts +64 -0
  52. package/src/lib/bundle/stableLocalPort.ts +19 -0
  53. package/src/lib/bundle/waitForServer.ts +23 -0
  54. package/src/lib/bundle/webviewCachePath.ts +23 -0
  55. package/src/lib/bundle/webviewLibName.ts +11 -0
  56. package/src/lib/cli/connectToServer.ts +23 -0
  57. package/src/lib/cli/createClient.ts +108 -0
  58. package/src/lib/cli/dispatchCommand.ts +71 -0
  59. package/src/lib/cli/loadEnvFromBinaryDir.ts +15 -0
  60. package/src/lib/cli/parseArgvForRpc.ts +100 -0
  61. package/src/lib/cli/printHelp.ts +119 -0
  62. package/src/lib/cli/printSessionHelp.ts +27 -0
  63. package/src/lib/cli/printSessionStatus.ts +21 -0
  64. package/src/lib/cli/printTrimmed.ts +8 -0
  65. package/src/lib/cli/printValue.ts +10 -0
  66. package/src/lib/cli/resolveCliTarget.ts +48 -0
  67. package/src/lib/cli/runCli.ts +176 -0
  68. package/src/lib/cli/runSession.ts +108 -0
  69. package/src/lib/cli/startLocalInstance.ts +14 -0
  70. package/src/lib/cli/tokenizeLine.ts +51 -0
  71. package/src/lib/cli/types/CliManifest.ts +9 -0
  72. package/src/lib/cli/types/CliManifestEntry.ts +17 -0
  73. package/src/lib/cli/types/CliTarget.ts +13 -0
  74. package/src/lib/mcp/annotationsForMethod.ts +29 -0
  75. package/src/lib/mcp/createMcpResourceServer.ts +102 -0
  76. package/src/lib/mcp/createMcpServer.ts +48 -0
  77. package/src/lib/mcp/dispatchMcpRequest.ts +138 -0
  78. package/src/lib/mcp/mcpResourceServerSlot.ts +18 -0
  79. package/src/lib/mcp/mcpSurface.ts +295 -0
  80. package/src/lib/mcp/toolResultFromResponse.ts +66 -0
  81. package/src/lib/mcp/types/JsonRpcRequest.ts +12 -0
  82. package/src/lib/mcp/types/JsonRpcResponse.ts +20 -0
  83. package/src/lib/mcp/types/McpResourceContents.ts +10 -0
  84. package/src/lib/mcp/types/McpResourceDescriptor.ts +6 -0
  85. package/src/lib/mcp/types/McpResourceServer.ts +12 -0
  86. package/src/lib/mcp/types/McpServer.ts +9 -0
  87. package/src/lib/mcp/types/McpServerOptions.ts +16 -0
  88. package/src/lib/server/AppModule.ts +47 -0
  89. package/src/lib/server/DELETE.ts +10 -0
  90. package/src/lib/server/GET.ts +10 -0
  91. package/src/lib/server/HEAD.ts +10 -0
  92. package/src/lib/server/PATCH.ts +10 -0
  93. package/src/lib/server/POST.ts +10 -0
  94. package/src/lib/server/PUT.ts +10 -0
  95. package/src/lib/server/agent.ts +86 -0
  96. package/src/lib/server/appDataDir.ts +16 -0
  97. package/src/lib/server/cli/buildEnvContent.ts +19 -0
  98. package/src/lib/server/cli/createTarGz.ts +77 -0
  99. package/src/lib/server/cli/handleCliDownload.ts +150 -0
  100. package/src/lib/server/cli/handleCliInstall.ts +37 -0
  101. package/src/lib/server/cli/installScript.ts +31 -0
  102. package/src/lib/server/cli/maxSourceMtime.ts +26 -0
  103. package/src/lib/server/cookies.ts +30 -0
  104. package/src/lib/server/env.ts +51 -0
  105. package/src/lib/server/error.ts +73 -0
  106. package/src/lib/server/json.ts +42 -0
  107. package/src/lib/server/jsonl.ts +47 -0
  108. package/src/lib/server/prompts/definePrompt.ts +21 -0
  109. package/src/lib/server/prompts/promptRegistry.ts +9 -0
  110. package/src/lib/server/prompts/registerPrompt.ts +6 -0
  111. package/src/lib/server/prompts/renderPromptTemplate.ts +17 -0
  112. package/src/lib/server/prompts/types/Prompt.ts +13 -0
  113. package/src/lib/server/prompts/types/PromptOptions.ts +12 -0
  114. package/src/lib/server/prompts/types/PromptRegistryEntry.ts +13 -0
  115. package/src/lib/server/prompts/types/PromptRoutes.ts +10 -0
  116. package/src/lib/server/reachable.ts +45 -0
  117. package/src/lib/server/redirect.ts +43 -0
  118. package/src/lib/server/request.ts +19 -0
  119. package/src/lib/server/rpc/defineVerb.ts +210 -0
  120. package/src/lib/server/rpc/dispatchVerbInProcess.ts +46 -0
  121. package/src/lib/server/rpc/findVerbByCommandName.ts +18 -0
  122. package/src/lib/server/rpc/parseArgs.ts +127 -0
  123. package/src/lib/server/rpc/readBodyWithinLimit.ts +44 -0
  124. package/src/lib/server/rpc/registerVerb.ts +6 -0
  125. package/src/lib/server/rpc/runWithVerbTimeout.ts +49 -0
  126. package/src/lib/server/rpc/types/RemoteHandler.ts +27 -0
  127. package/src/lib/server/rpc/types/RemoteRoutes.ts +13 -0
  128. package/src/lib/server/rpc/types/TypedResponse.ts +18 -0
  129. package/src/lib/server/rpc/types/VerbHelper.ts +87 -0
  130. package/src/lib/server/rpc/types/VerbRegistryEntry.ts +35 -0
  131. package/src/lib/server/rpc/unprocessed.ts +14 -0
  132. package/src/lib/server/rpc/verbRegistry.ts +11 -0
  133. package/src/lib/server/runtime/DEFAULT_PORT.ts +6 -0
  134. package/src/lib/server/runtime/DEV_READY_MESSAGE.ts +6 -0
  135. package/src/lib/server/runtime/DEV_REBUILD_MESSAGE.ts +4 -0
  136. package/src/lib/server/runtime/DEV_RELOAD_CLIENT_SCRIPT.ts +107 -0
  137. package/src/lib/server/runtime/SSR_SWAP_SCRIPT.ts +16 -0
  138. package/src/lib/server/runtime/acceptsGzip.ts +24 -0
  139. package/src/lib/server/runtime/buildCacheSnapshot.ts +61 -0
  140. package/src/lib/server/runtime/buildHealthPayload.ts +34 -0
  141. package/src/lib/server/runtime/buildInspectorSurface.ts +37 -0
  142. package/src/lib/server/runtime/buildOpenApiSpec.ts +106 -0
  143. package/src/lib/server/runtime/cacheControlForAsset.ts +22 -0
  144. package/src/lib/server/runtime/containsTraversal.ts +37 -0
  145. package/src/lib/server/runtime/createAppAssetServer.ts +76 -0
  146. package/src/lib/server/runtime/createAssetHeaderCache.ts +31 -0
  147. package/src/lib/server/runtime/createPublicAssetServer.ts +67 -0
  148. package/src/lib/server/runtime/createReachable.ts +109 -0
  149. package/src/lib/server/runtime/createRouteDispatcher.ts +127 -0
  150. package/src/lib/server/runtime/createServer.ts +674 -0
  151. package/src/lib/server/runtime/createUiPageRenderer.ts +181 -0
  152. package/src/lib/server/runtime/crossOriginForbidden.ts +17 -0
  153. package/src/lib/server/runtime/crossOriginGate.ts +29 -0
  154. package/src/lib/server/runtime/devClientFingerprint.ts +117 -0
  155. package/src/lib/server/runtime/devHotModuleResponse.ts +40 -0
  156. package/src/lib/server/runtime/devReloadResponse.ts +41 -0
  157. package/src/lib/server/runtime/disableIdleTimeoutForStream.ts +27 -0
  158. package/src/lib/server/runtime/envSchemaStore.ts +15 -0
  159. package/src/lib/server/runtime/findOpenPort.ts +21 -0
  160. package/src/lib/server/runtime/getActiveServer.ts +6 -0
  161. package/src/lib/server/runtime/globToPathSet.ts +29 -0
  162. package/src/lib/server/runtime/gzipResponse.ts +46 -0
  163. package/src/lib/server/runtime/inProcessServer.ts +20 -0
  164. package/src/lib/server/runtime/internalErrorResponse.ts +25 -0
  165. package/src/lib/server/runtime/isCrossOriginRequest.ts +23 -0
  166. package/src/lib/server/runtime/listenOnOpenPort.ts +36 -0
  167. package/src/lib/server/runtime/logExposedSurfaces.ts +156 -0
  168. package/src/lib/server/runtime/maybeMountInspector.ts +97 -0
  169. package/src/lib/server/runtime/mimeForExtension.ts +14 -0
  170. package/src/lib/server/runtime/pageUrlFromStore.ts +15 -0
  171. package/src/lib/server/runtime/parseIdleTimeout.ts +10 -0
  172. package/src/lib/server/runtime/parsePort.ts +11 -0
  173. package/src/lib/server/runtime/registryManifests.ts +66 -0
  174. package/src/lib/server/runtime/requestContext.ts +5 -0
  175. package/src/lib/server/runtime/resolvePageSnapshot.ts +25 -0
  176. package/src/lib/server/runtime/respondWithEmbeddedAsset.ts +18 -0
  177. package/src/lib/server/runtime/runWithRequestScope.ts +150 -0
  178. package/src/lib/server/runtime/safeJsonForScript.ts +17 -0
  179. package/src/lib/server/runtime/serializeCacheSnapshot.ts +45 -0
  180. package/src/lib/server/runtime/serverSlot.ts +13 -0
  181. package/src/lib/server/runtime/setActiveServer.ts +6 -0
  182. package/src/lib/server/runtime/snapshotEntryFromCache.ts +83 -0
  183. package/src/lib/server/runtime/streamCacheResolutions.ts +37 -0
  184. package/src/lib/server/runtime/streamFromIterator.ts +86 -0
  185. package/src/lib/server/runtime/types/Assets.ts +6 -0
  186. package/src/lib/server/runtime/types/DevReloadStamp.ts +18 -0
  187. package/src/lib/server/runtime/types/InspectorCacheEntry.ts +24 -0
  188. package/src/lib/server/runtime/types/InspectorCacheSnapshot.ts +11 -0
  189. package/src/lib/server/runtime/types/InspectorContext.ts +30 -0
  190. package/src/lib/server/runtime/types/InspectorSocket.ts +17 -0
  191. package/src/lib/server/runtime/types/InspectorSurface.ts +13 -0
  192. package/src/lib/server/runtime/types/InspectorVerb.ts +27 -0
  193. package/src/lib/server/runtime/types/RequestStore.ts +55 -0
  194. package/src/lib/server/runtime/warnUnguardedMcp.ts +32 -0
  195. package/src/lib/server/runtime/withResponseDefaults.ts +24 -0
  196. package/src/lib/server/server.ts +33 -0
  197. package/src/lib/server/socket.ts +32 -0
  198. package/src/lib/server/sockets/createSocketDispatcher.ts +337 -0
  199. package/src/lib/server/sockets/defineSocket.ts +179 -0
  200. package/src/lib/server/sockets/lookupSocket.ts +6 -0
  201. package/src/lib/server/sockets/registerSocket.ts +6 -0
  202. package/src/lib/server/sockets/socketOperations.ts +36 -0
  203. package/src/lib/server/sockets/socketRegistry.ts +9 -0
  204. package/src/lib/server/sockets/types/Socket.ts +23 -0
  205. package/src/lib/server/sockets/types/SocketClientFrame.ts +19 -0
  206. package/src/lib/server/sockets/types/SocketOperation.ts +22 -0
  207. package/src/lib/server/sockets/types/SocketOptions.ts +26 -0
  208. package/src/lib/server/sockets/types/SocketRegistryEntry.ts +19 -0
  209. package/src/lib/server/sockets/types/SocketRoutes.ts +10 -0
  210. package/src/lib/server/sockets/types/SocketServerFrame.ts +24 -0
  211. package/src/lib/server/sse.ts +54 -0
  212. package/src/lib/shared/ABIDE_PACKAGE_NAME.ts +7 -0
  213. package/src/lib/shared/ABIDE_VERSION.ts +9 -0
  214. package/src/lib/shared/CACHE_CONTROL_VALUES.ts +16 -0
  215. package/src/lib/shared/CACHE_WRAPPED.ts +8 -0
  216. package/src/lib/shared/CLI_PATH.ts +7 -0
  217. package/src/lib/shared/DEV_HOT_PREFIX.ts +7 -0
  218. package/src/lib/shared/DEV_RELOAD_PATH.ts +6 -0
  219. package/src/lib/shared/HEALTH_PATH.ts +7 -0
  220. package/src/lib/shared/HttpError.ts +20 -0
  221. package/src/lib/shared/IDENTITY_PATH.ts +6 -0
  222. package/src/lib/shared/INSPECTOR_PATH.ts +7 -0
  223. package/src/lib/shared/NAV_HEADER.ts +8 -0
  224. package/src/lib/shared/OFFLINE_HEADER.ts +8 -0
  225. package/src/lib/shared/REMOTE_FUNCTION.ts +8 -0
  226. package/src/lib/shared/REPLAYABLE_METHODS.ts +12 -0
  227. package/src/lib/shared/SOCKETS_PATH.ts +7 -0
  228. package/src/lib/shared/STREAMING_CONTENT_TYPES.ts +11 -0
  229. package/src/lib/shared/SocketDisconnectedError.ts +13 -0
  230. package/src/lib/shared/TEXT_PLAIN.ts +7 -0
  231. package/src/lib/shared/abideImportName.ts +44 -0
  232. package/src/lib/shared/abideLog.ts +38 -0
  233. package/src/lib/shared/activeCacheStore.ts +20 -0
  234. package/src/lib/shared/activePage.ts +25 -0
  235. package/src/lib/shared/appDataDir.ts +34 -0
  236. package/src/lib/shared/appNameSlot.ts +10 -0
  237. package/src/lib/shared/basePath.ts +10 -0
  238. package/src/lib/shared/basePathFromAppUrl.ts +20 -0
  239. package/src/lib/shared/baseSlot.ts +14 -0
  240. package/src/lib/shared/binaryDirEnvPath.ts +12 -0
  241. package/src/lib/shared/browserClientFlags.ts +10 -0
  242. package/src/lib/shared/buildRpcProxy.ts +39 -0
  243. package/src/lib/shared/buildRpcRequest.ts +70 -0
  244. package/src/lib/shared/buildSocketOverChannel.ts +58 -0
  245. package/src/lib/shared/bundleLayout.ts +36 -0
  246. package/src/lib/shared/cache.ts +951 -0
  247. package/src/lib/shared/cacheEntryFromSnapshot.ts +59 -0
  248. package/src/lib/shared/cacheStoreSlot.ts +16 -0
  249. package/src/lib/shared/cacheStores.ts +10 -0
  250. package/src/lib/shared/canonicalJson.ts +63 -0
  251. package/src/lib/shared/carriesBodyArgs.ts +13 -0
  252. package/src/lib/shared/clearLastConnection.ts +7 -0
  253. package/src/lib/shared/commandNameForUrl.ts +17 -0
  254. package/src/lib/shared/createCacheStore.ts +104 -0
  255. package/src/lib/shared/createChannelLog.ts +122 -0
  256. package/src/lib/shared/createLifecycleChannel.ts +56 -0
  257. package/src/lib/shared/createLivenessWatch.ts +118 -0
  258. package/src/lib/shared/createPushIterator.ts +127 -0
  259. package/src/lib/shared/createRemoteFunction.ts +122 -0
  260. package/src/lib/shared/createSubscriber.ts +55 -0
  261. package/src/lib/shared/createTraceContext.ts +21 -0
  262. package/src/lib/shared/dataDirEnvPath.ts +12 -0
  263. package/src/lib/shared/decodeResponse.ts +47 -0
  264. package/src/lib/shared/detectTarget.ts +27 -0
  265. package/src/lib/shared/detectVerbMethod.ts +17 -0
  266. package/src/lib/shared/emitLogRecord.ts +190 -0
  267. package/src/lib/shared/exeSuffix.ts +9 -0
  268. package/src/lib/shared/exitOnBuildFailure.ts +17 -0
  269. package/src/lib/shared/extraForwardHeaders.ts +16 -0
  270. package/src/lib/shared/fileStem.ts +9 -0
  271. package/src/lib/shared/findExportCallSite.ts +476 -0
  272. package/src/lib/shared/formatTraceparent.ts +6 -0
  273. package/src/lib/shared/forwardHeaders.ts +44 -0
  274. package/src/lib/shared/getRemoteMeta.ts +5 -0
  275. package/src/lib/shared/globalCacheStore.ts +15 -0
  276. package/src/lib/shared/globalCacheStoreSlot.ts +14 -0
  277. package/src/lib/shared/health.ts +179 -0
  278. package/src/lib/shared/healthReadSlot.ts +11 -0
  279. package/src/lib/shared/healthSeedSlot.ts +12 -0
  280. package/src/lib/shared/html.ts +38 -0
  281. package/src/lib/shared/importNamesToStrip.ts +13 -0
  282. package/src/lib/shared/invalidateEvent.ts +11 -0
  283. package/src/lib/shared/invalidateTripwire.ts +40 -0
  284. package/src/lib/shared/isAbideHealthPayload.ts +11 -0
  285. package/src/lib/shared/isCompileTarget.ts +15 -0
  286. package/src/lib/shared/isDebugEnabled.ts +26 -0
  287. package/src/lib/shared/isDebugNegated.ts +19 -0
  288. package/src/lib/shared/isModuleNotFound.ts +16 -0
  289. package/src/lib/shared/isReadOnlyMethod.ts +14 -0
  290. package/src/lib/shared/isReplayableMethod.ts +7 -0
  291. package/src/lib/shared/isStreamingResponse.ts +11 -0
  292. package/src/lib/shared/isSubscribable.ts +15 -0
  293. package/src/lib/shared/jsonSchemaForPromptArguments.ts +29 -0
  294. package/src/lib/shared/jsonSchemaForSchema.ts +39 -0
  295. package/src/lib/shared/jsonlErrorFrame.ts +24 -0
  296. package/src/lib/shared/keyForRemoteCall.ts +29 -0
  297. package/src/lib/shared/keyMatchesPrefix.ts +9 -0
  298. package/src/lib/shared/lastConnectionPath.ts +7 -0
  299. package/src/lib/shared/layoutChainForRoute.ts +22 -0
  300. package/src/lib/shared/loadEnvFile.ts +17 -0
  301. package/src/lib/shared/loadEnvFromDataDir.ts +14 -0
  302. package/src/lib/shared/log.ts +24 -0
  303. package/src/lib/shared/logClosingRecord.ts +28 -0
  304. package/src/lib/shared/logTapSlot.ts +13 -0
  305. package/src/lib/shared/manifestModule.ts +39 -0
  306. package/src/lib/shared/matchesDebugPattern.ts +16 -0
  307. package/src/lib/shared/memoizeByKey.ts +32 -0
  308. package/src/lib/shared/normalizeTarget.ts +10 -0
  309. package/src/lib/shared/online.ts +51 -0
  310. package/src/lib/shared/page.ts +30 -0
  311. package/src/lib/shared/pageSlot.ts +17 -0
  312. package/src/lib/shared/pageUrlForFile.ts +14 -0
  313. package/src/lib/shared/parseBoundedEnvInt.ts +20 -0
  314. package/src/lib/shared/parseDebugPatterns.ts +21 -0
  315. package/src/lib/shared/parseEnv.ts +30 -0
  316. package/src/lib/shared/parsePromptMarkdown.ts +35 -0
  317. package/src/lib/shared/parseRouteSegments.ts +22 -0
  318. package/src/lib/shared/parseTraceparent.ts +26 -0
  319. package/src/lib/shared/pending.ts +30 -0
  320. package/src/lib/shared/prepareRpcModule.ts +59 -0
  321. package/src/lib/shared/prepareSocketModule.ts +49 -0
  322. package/src/lib/shared/probeRegistries.ts +68 -0
  323. package/src/lib/shared/producerKey.ts +32 -0
  324. package/src/lib/shared/programNameForPackage.ts +14 -0
  325. package/src/lib/shared/promptNameForFile.ts +10 -0
  326. package/src/lib/shared/queryStringFromArgs.ts +27 -0
  327. package/src/lib/shared/randomHexId.ts +14 -0
  328. package/src/lib/shared/readEnvFile.ts +15 -0
  329. package/src/lib/shared/readLastConnection.ts +18 -0
  330. package/src/lib/shared/readPackageJson.ts +9 -0
  331. package/src/lib/shared/recordRemoteMeta.ts +5 -0
  332. package/src/lib/shared/refreshing.ts +31 -0
  333. package/src/lib/shared/remoteMetaStore.ts +16 -0
  334. package/src/lib/shared/requestScopeSlot.ts +15 -0
  335. package/src/lib/shared/resolveClientFlags.ts +20 -0
  336. package/src/lib/shared/responseErrorText.ts +9 -0
  337. package/src/lib/shared/rpcTimeoutSlot.ts +9 -0
  338. package/src/lib/shared/rpcUrlForFile.ts +19 -0
  339. package/src/lib/shared/runningAsStandaloneBinary.ts +13 -0
  340. package/src/lib/shared/selectorMatcher.ts +68 -0
  341. package/src/lib/shared/selectorPrefix.ts +39 -0
  342. package/src/lib/shared/serializeEnv.ts +18 -0
  343. package/src/lib/shared/setAppName.ts +5 -0
  344. package/src/lib/shared/setBaseResolver.ts +6 -0
  345. package/src/lib/shared/setCacheStoreResolver.ts +6 -0
  346. package/src/lib/shared/setGlobalCacheStoreResolver.ts +6 -0
  347. package/src/lib/shared/setPageResolver.ts +7 -0
  348. package/src/lib/shared/setRequestScopeResolver.ts +6 -0
  349. package/src/lib/shared/snippet.ts +25 -0
  350. package/src/lib/shared/socketNameForFile.ts +11 -0
  351. package/src/lib/shared/socketTapSlot.ts +12 -0
  352. package/src/lib/shared/sseErrorFrame.ts +29 -0
  353. package/src/lib/shared/streamResponse.ts +169 -0
  354. package/src/lib/shared/stripImport.ts +27 -0
  355. package/src/lib/shared/subscribableFromResponse.ts +51 -0
  356. package/src/lib/shared/tailProbeSlot.ts +16 -0
  357. package/src/lib/shared/toBunRoutePattern.ts +28 -0
  358. package/src/lib/shared/toScopeSet.ts +4 -0
  359. package/src/lib/shared/trace.ts +16 -0
  360. package/src/lib/shared/types/CacheEntry.ts +84 -0
  361. package/src/lib/shared/types/CacheInvalidation.ts +9 -0
  362. package/src/lib/shared/types/CacheOnContext.ts +25 -0
  363. package/src/lib/shared/types/CacheOptions.ts +39 -0
  364. package/src/lib/shared/types/CacheSelector.ts +17 -0
  365. package/src/lib/shared/types/CacheSnapshot.ts +16 -0
  366. package/src/lib/shared/types/CacheSnapshotEntry.ts +17 -0
  367. package/src/lib/shared/types/CacheStats.ts +13 -0
  368. package/src/lib/shared/types/CacheStore.ts +39 -0
  369. package/src/lib/shared/types/ChannelLog.ts +13 -0
  370. package/src/lib/shared/types/ClientFlags.ts +11 -0
  371. package/src/lib/shared/types/CompileTarget.ts +6 -0
  372. package/src/lib/shared/types/FrameworkLog.ts +13 -0
  373. package/src/lib/shared/types/HttpVerb.ts +1 -0
  374. package/src/lib/shared/types/LastConnection.ts +9 -0
  375. package/src/lib/shared/types/Log.ts +13 -0
  376. package/src/lib/shared/types/LogRecord.ts +42 -0
  377. package/src/lib/shared/types/LogVoice.ts +7 -0
  378. package/src/lib/shared/types/PageSnapshot.ts +14 -0
  379. package/src/lib/shared/types/PromptArgument.ts +12 -0
  380. package/src/lib/shared/types/RawRemoteFunction.ts +14 -0
  381. package/src/lib/shared/types/RemoteCallable.ts +12 -0
  382. package/src/lib/shared/types/RemoteFunction.ts +47 -0
  383. package/src/lib/shared/types/ReplayableMethod.ts +7 -0
  384. package/src/lib/shared/types/RequestScopeInfo.ts +16 -0
  385. package/src/lib/shared/types/RpcInvoker.ts +6 -0
  386. package/src/lib/shared/types/SocketChannel.ts +17 -0
  387. package/src/lib/shared/types/SocketSubCallbacks.ts +13 -0
  388. package/src/lib/shared/types/StandardSchemaV1.ts +56 -0
  389. package/src/lib/shared/types/StreamedResolution.ts +10 -0
  390. package/src/lib/shared/types/Subscribable.ts +26 -0
  391. package/src/lib/shared/types/TailHooks.ts +12 -0
  392. package/src/lib/shared/types/TailOptions.ts +10 -0
  393. package/src/lib/shared/types/TraceContext.ts +17 -0
  394. package/src/lib/shared/url.ts +118 -0
  395. package/src/lib/shared/withBase.ts +11 -0
  396. package/src/lib/shared/withBaseUrl.ts +17 -0
  397. package/src/lib/shared/withJsonSchema.ts +21 -0
  398. package/src/lib/shared/writeDts.ts +12 -0
  399. package/src/lib/shared/writeHealthDts.ts +36 -0
  400. package/src/lib/shared/writeLastConnection.ts +13 -0
  401. package/src/lib/shared/writePublicAssetsDts.ts +31 -0
  402. package/src/lib/shared/writeRoutesDts.ts +73 -0
  403. package/src/lib/shared/writeRpcDts.ts +49 -0
  404. package/src/lib/shared/writeTestRpcDts.ts +45 -0
  405. package/src/lib/shared/writeTestSocketsDts.ts +34 -0
  406. package/src/lib/test/assertAgentFrameConformance.ts +73 -0
  407. package/src/lib/test/createScriptedSurface.ts +45 -0
  408. package/src/lib/test/createTestApp.ts +203 -0
  409. package/src/lib/test/createTestSocketChannel.ts +142 -0
  410. package/src/lib/ui/README.md +86 -0
  411. package/src/lib/ui/compile/SSR_ESCAPE.ts +25 -0
  412. package/src/lib/ui/compile/UI_RUNTIME_IMPORTS.ts +36 -0
  413. package/src/lib/ui/compile/VOID_TAGS.ts +21 -0
  414. package/src/lib/ui/compile/abideUiPlugin.ts +65 -0
  415. package/src/lib/ui/compile/analyzeComponent.ts +117 -0
  416. package/src/lib/ui/compile/assetModulesFile.ts +32 -0
  417. package/src/lib/ui/compile/branchElements.ts +50 -0
  418. package/src/lib/ui/compile/collectAbideDiagnostics.ts +59 -0
  419. package/src/lib/ui/compile/compileComponent.ts +20 -0
  420. package/src/lib/ui/compile/compileModule.ts +116 -0
  421. package/src/lib/ui/compile/compileSSR.ts +36 -0
  422. package/src/lib/ui/compile/compileShadow.ts +352 -0
  423. package/src/lib/ui/compile/createShadowLanguageService.ts +197 -0
  424. package/src/lib/ui/compile/createShadowProgram.ts +96 -0
  425. package/src/lib/ui/compile/decodeHtmlEntities.ts +49 -0
  426. package/src/lib/ui/compile/desugarSignals.ts +133 -0
  427. package/src/lib/ui/compile/escapeHtml.ts +15 -0
  428. package/src/lib/ui/compile/generateBuild.ts +638 -0
  429. package/src/lib/ui/compile/generateSSR.ts +380 -0
  430. package/src/lib/ui/compile/groupBindParts.ts +28 -0
  431. package/src/lib/ui/compile/hoistCells.ts +120 -0
  432. package/src/lib/ui/compile/loadShadowTsConfig.ts +31 -0
  433. package/src/lib/ui/compile/lowerDocAccess.ts +202 -0
  434. package/src/lib/ui/compile/nearestProjectRoot.ts +16 -0
  435. package/src/lib/ui/compile/parseTemplate.ts +396 -0
  436. package/src/lib/ui/compile/partitionSlots.ts +36 -0
  437. package/src/lib/ui/compile/prepareNestedScript.ts +42 -0
  438. package/src/lib/ui/compile/remapShadowDiagnostic.ts +30 -0
  439. package/src/lib/ui/compile/renameSignalRefs.ts +85 -0
  440. package/src/lib/ui/compile/resolveAbideImports.ts +29 -0
  441. package/src/lib/ui/compile/scopeCss.ts +115 -0
  442. package/src/lib/ui/compile/shadowNaming.ts +11 -0
  443. package/src/lib/ui/compile/sourceToShadowOffset.ts +24 -0
  444. package/src/lib/ui/compile/staticAttrValue.ts +13 -0
  445. package/src/lib/ui/compile/stripEffects.ts +32 -0
  446. package/src/lib/ui/compile/types/AbideDiagnostic.ts +14 -0
  447. package/src/lib/ui/compile/types/AnalyzedComponent.ts +25 -0
  448. package/src/lib/ui/compile/types/CompiledShadow.ts +15 -0
  449. package/src/lib/ui/compile/types/TemplateAttr.ts +16 -0
  450. package/src/lib/ui/compile/types/TemplateNode.ts +78 -0
  451. package/src/lib/ui/compile/types/TextPart.ts +8 -0
  452. package/src/lib/ui/derived.ts +28 -0
  453. package/src/lib/ui/doc.ts +15 -0
  454. package/src/lib/ui/dom/appendSnippet.ts +34 -0
  455. package/src/lib/ui/dom/appendStatic.ts +27 -0
  456. package/src/lib/ui/dom/appendText.ts +114 -0
  457. package/src/lib/ui/dom/applyResolved.ts +72 -0
  458. package/src/lib/ui/dom/attach.ts +20 -0
  459. package/src/lib/ui/dom/attr.ts +19 -0
  460. package/src/lib/ui/dom/awaitBlock.ts +224 -0
  461. package/src/lib/ui/dom/cloneStatic.ts +52 -0
  462. package/src/lib/ui/dom/each.ts +115 -0
  463. package/src/lib/ui/dom/eachAsync.ts +153 -0
  464. package/src/lib/ui/dom/hydrate.ts +35 -0
  465. package/src/lib/ui/dom/mount.ts +29 -0
  466. package/src/lib/ui/dom/mountChild.ts +33 -0
  467. package/src/lib/ui/dom/on.ts +15 -0
  468. package/src/lib/ui/dom/openChild.ts +22 -0
  469. package/src/lib/ui/dom/openRoot.ts +20 -0
  470. package/src/lib/ui/dom/switchBlock.ts +75 -0
  471. package/src/lib/ui/dom/text.ts +20 -0
  472. package/src/lib/ui/dom/tryBlock.ts +112 -0
  473. package/src/lib/ui/dom/types/EachRow.ts +3 -0
  474. package/src/lib/ui/dom/types/SwitchCase.ts +6 -0
  475. package/src/lib/ui/dom/when.ts +73 -0
  476. package/src/lib/ui/effect.ts +16 -0
  477. package/src/lib/ui/installHotBridge.ts +73 -0
  478. package/src/lib/ui/matchRoute.ts +89 -0
  479. package/src/lib/ui/navigate.ts +17 -0
  480. package/src/lib/ui/probeNavigation.ts +33 -0
  481. package/src/lib/ui/remoteProxy.ts +97 -0
  482. package/src/lib/ui/renderChain.ts +50 -0
  483. package/src/lib/ui/renderToStream.ts +104 -0
  484. package/src/lib/ui/router.ts +286 -0
  485. package/src/lib/ui/runtime/OUTLET_TAG.ts +8 -0
  486. package/src/lib/ui/runtime/OWNER.ts +8 -0
  487. package/src/lib/ui/runtime/REACTIVE_CONTEXT.ts +14 -0
  488. package/src/lib/ui/runtime/RENDER.ts +23 -0
  489. package/src/lib/ui/runtime/RESUME.ts +16 -0
  490. package/src/lib/ui/runtime/applyPatchToTree.ts +41 -0
  491. package/src/lib/ui/runtime/claimChild.ts +10 -0
  492. package/src/lib/ui/runtime/clientPage.ts +16 -0
  493. package/src/lib/ui/runtime/createComputedNode.ts +16 -0
  494. package/src/lib/ui/runtime/createDoc.ts +177 -0
  495. package/src/lib/ui/runtime/createEffectNode.ts +58 -0
  496. package/src/lib/ui/runtime/createSignalNode.ts +16 -0
  497. package/src/lib/ui/runtime/detachLink.ts +21 -0
  498. package/src/lib/ui/runtime/endTracking.ts +24 -0
  499. package/src/lib/ui/runtime/enterRenderPass.ts +12 -0
  500. package/src/lib/ui/runtime/exitRenderPass.ts +7 -0
  501. package/src/lib/ui/runtime/firstOutlet.ts +22 -0
  502. package/src/lib/ui/runtime/flushEffects.ts +17 -0
  503. package/src/lib/ui/runtime/hotInstances.ts +10 -0
  504. package/src/lib/ui/runtime/hotReloadEnabled.ts +8 -0
  505. package/src/lib/ui/runtime/hotReplace.ts +25 -0
  506. package/src/lib/ui/runtime/nextBlockId.ts +11 -0
  507. package/src/lib/ui/runtime/pathExists.ts +23 -0
  508. package/src/lib/ui/runtime/readNode.ts +17 -0
  509. package/src/lib/ui/runtime/registerHotInstance.ts +23 -0
  510. package/src/lib/ui/runtime/runNode.ts +28 -0
  511. package/src/lib/ui/runtime/runtimePath.ts +9 -0
  512. package/src/lib/ui/runtime/scope.ts +24 -0
  513. package/src/lib/ui/runtime/toTeardown.ts +26 -0
  514. package/src/lib/ui/runtime/track.ts +58 -0
  515. package/src/lib/ui/runtime/trigger.ts +44 -0
  516. package/src/lib/ui/runtime/types/Cell.ts +5 -0
  517. package/src/lib/ui/runtime/types/Derived.ts +3 -0
  518. package/src/lib/ui/runtime/types/Doc.ts +19 -0
  519. package/src/lib/ui/runtime/types/EffectResult.ts +10 -0
  520. package/src/lib/ui/runtime/types/HotInstance.ts +14 -0
  521. package/src/lib/ui/runtime/types/NavVerdict.ts +9 -0
  522. package/src/lib/ui/runtime/types/Patch.ts +11 -0
  523. package/src/lib/ui/runtime/types/ReactiveLink.ts +21 -0
  524. package/src/lib/ui/runtime/types/ReactiveNode.ts +25 -0
  525. package/src/lib/ui/runtime/types/Route.ts +8 -0
  526. package/src/lib/ui/runtime/types/RouteLoader.ts +7 -0
  527. package/src/lib/ui/runtime/types/SsrRender.ts +22 -0
  528. package/src/lib/ui/runtime/types/State.ts +3 -0
  529. package/src/lib/ui/runtime/types/Teardown.ts +5 -0
  530. package/src/lib/ui/runtime/types/UiComponent.ts +16 -0
  531. package/src/lib/ui/runtime/types/UiProps.ts +15 -0
  532. package/src/lib/ui/runtime/unlinkDeps.ts +20 -0
  533. package/src/lib/ui/runtime/untrack.ts +20 -0
  534. package/src/lib/ui/runtime/valueAtPath.ts +18 -0
  535. package/src/lib/ui/runtime/writeNode.ts +16 -0
  536. package/src/lib/ui/socketChannel.ts +227 -0
  537. package/src/lib/ui/socketProxy.ts +25 -0
  538. package/src/lib/ui/startClient.ts +58 -0
  539. package/src/lib/ui/state.ts +25 -0
  540. package/src/lib/ui/tail.ts +324 -0
  541. package/src/lib/ui/types/Layouts.ts +9 -0
  542. package/src/lib/ui/types/Pages.ts +8 -0
  543. package/src/preload.ts +19 -0
  544. package/src/scaffold.ts +153 -0
  545. package/src/serverBuildPlugins.ts +19 -0
  546. package/src/serverEntry.ts +95 -0
  547. package/template/bunfig.toml +4 -0
  548. package/template/package.json +18 -0
  549. package/template/src/app.ts +28 -0
  550. package/template/src/bundle/icon.png +0 -0
  551. package/template/src/cli/banner.txt +3 -0
  552. package/template/src/cli/footer.txt +1 -0
  553. package/template/src/server/config.ts +17 -0
  554. package/template/src/server/rpc/getHello.ts +36 -0
  555. package/template/src/ui/Layout.abide +19 -0
  556. package/template/src/ui/app.css +21 -0
  557. package/template/src/ui/app.html +24 -0
  558. package/template/src/ui/pages/about/page.abide +9 -0
  559. package/template/src/ui/pages/page.abide +22 -0
  560. package/template/test/app.test.ts +30 -0
  561. package/template/tsconfig.json +18 -0
  562. package/tsconfig.app.json +17 -0
@@ -0,0 +1,16 @@
1
+ // @ts-expect-error virtual module resolved by abideResolverPlugin
2
+ import cliProgramName from '../../_virtual/cli-name.ts'
3
+ import { appDataDir as appDataDirForName } from '../shared/appDataDir.ts'
4
+
5
+ /*
6
+ The running bundle's per-user data dir — keyed by the same program name abide
7
+ uses for the user's `.env` and `last-connection.json`, so an app's DB/cache lands
8
+ beside abide's own config instead of a drifted sibling directory. cwd-independent:
9
+ the path derives from the bundler-injected program name, not the process working
10
+ directory (which `open` sets to `/`). Pure: computes the path, never touches the
11
+ filesystem.
12
+ */
13
+ // @readme reference
14
+ export function appDataDir(): string {
15
+ return appDataDirForName(cliProgramName)
16
+ }
@@ -0,0 +1,19 @@
1
+ import { serializeEnv } from '../../shared/serializeEnv.ts'
2
+
3
+ /*
4
+ Generates the `.env` file content shipped alongside the CLI binary in
5
+ the download tarball. ABIDE_APP_URL is always present (derived from the
6
+ inbound request's origin); ABIDE_APP_TOKEN is included only when the inbound
7
+ request carried an Authorization: Bearer header, so an authenticated
8
+ download bakes the caller's credential into the binary's env.
9
+
10
+ Tokens forward verbatim — the framework doesn't issue or refresh; the
11
+ user's auth code at the actual RPC endpoints validates whatever value
12
+ arrives back in subsequent calls.
13
+ */
14
+ export function buildEnvContent(appUrl: string, bearerToken: string | undefined): string {
15
+ return serializeEnv({
16
+ ABIDE_APP_URL: appUrl,
17
+ ...(bearerToken ? { ABIDE_APP_TOKEN: bearerToken } : {}),
18
+ })
19
+ }
@@ -0,0 +1,77 @@
1
+ /*
2
+ Minimal ustar tarball writer. Each entry is a 512-byte header followed
3
+ by the content padded to a 512-byte boundary; the archive ends with two
4
+ 512-byte zero blocks. After assembly the buffer is gzipped via
5
+ Bun.gzipSync — no external `tar` invocation, no extra deps.
6
+
7
+ Format constraints:
8
+ - File names ≤ 100 bytes (we never write longer paths).
9
+ - Numeric fields are zero-padded octal ASCII strings (POSIX rule).
10
+ - Checksum is the sum of all header bytes treating the checksum
11
+ field as spaces; encoded as 6 octal digits + NUL + space.
12
+ */
13
+
14
+ type TarEntry = {
15
+ name: string
16
+ content: Uint8Array
17
+ mode?: number
18
+ }
19
+
20
+ const BLOCK = 512
21
+ const ENC = new TextEncoder()
22
+
23
+ function writeString(buf: Uint8Array, offset: number, length: number, value: string): void {
24
+ const bytes = ENC.encode(value)
25
+ buf.set(bytes.subarray(0, Math.min(bytes.length, length)), offset)
26
+ }
27
+
28
+ function writeOctal(buf: Uint8Array, offset: number, length: number, value: number): void {
29
+ // length-1 octal digits + trailing NUL
30
+ const oct = value.toString(8).padStart(length - 1, '0')
31
+ writeString(buf, offset, length - 1, oct)
32
+ buf[offset + length - 1] = 0
33
+ }
34
+
35
+ function buildHeader(entry: TarEntry): Uint8Array {
36
+ const header = new Uint8Array(BLOCK)
37
+ writeString(header, 0, 100, entry.name)
38
+ writeOctal(header, 100, 8, entry.mode ?? 0o644)
39
+ writeOctal(header, 108, 8, 0)
40
+ writeOctal(header, 116, 8, 0)
41
+ writeOctal(header, 124, 12, entry.content.length)
42
+ writeOctal(header, 136, 12, Math.floor(Date.now() / 1000))
43
+ header.fill(0x20, 148, 156)
44
+ header[156] = 0x30 // '0' = regular file
45
+ writeString(header, 257, 6, 'ustar\0')
46
+ writeString(header, 263, 2, '00')
47
+ // Checksum: sum of all bytes with checksum field treated as spaces.
48
+ let sum = 0
49
+ for (let index = 0; index < BLOCK; index++) {
50
+ sum += header[index] ?? 0
51
+ }
52
+ writeOctal(header, 148, 7, sum)
53
+ header[155] = 0x20 // trailing space after checksum digits
54
+ return header
55
+ }
56
+
57
+ /*
58
+ Builds a gzipped tarball from the given entries and returns the bytes.
59
+ Sized eagerly (sum of headers + padded contents + 2 trailing blocks).
60
+ */
61
+ export function createTarGz(entries: TarEntry[]): Uint8Array<ArrayBuffer> {
62
+ let totalSize = BLOCK * 2 // trailing zero blocks
63
+ for (const entry of entries) {
64
+ totalSize += BLOCK
65
+ totalSize += Math.ceil(entry.content.length / BLOCK) * BLOCK
66
+ }
67
+ const tar = new Uint8Array(totalSize)
68
+ let offset = 0
69
+ for (const entry of entries) {
70
+ tar.set(buildHeader(entry), offset)
71
+ offset += BLOCK
72
+ tar.set(entry.content, offset)
73
+ offset += Math.ceil(entry.content.length / BLOCK) * BLOCK
74
+ }
75
+ /* gzipSync allocates a fresh plain ArrayBuffer; @types/bun widens it to ArrayBufferLike, which BodyInit rejects. */
76
+ return Bun.gzipSync(tar) as Uint8Array<ArrayBuffer>
77
+ }
@@ -0,0 +1,150 @@
1
+ import { abideLog } from '../../shared/abideLog.ts'
2
+ import { NO_STORE } from '../../shared/CACHE_CONTROL_VALUES.ts'
3
+ import { exeSuffix } from '../../shared/exeSuffix.ts'
4
+ import { isCompileTarget } from '../../shared/isCompileTarget.ts'
5
+ import { normalizeTarget } from '../../shared/normalizeTarget.ts'
6
+ import { buildEnvContent } from './buildEnvContent.ts'
7
+ import { createTarGz } from './createTarGz.ts'
8
+ import { maxSourceMtime } from './maxSourceMtime.ts'
9
+
10
+ // The sibling server binary's name for a platform — `server` / `server.exe` — must
11
+ // match what resolveServerBinary() looks for next to the unpacked CLI binary.
12
+ function serverBinaryName(platform: string): string {
13
+ return `server${exeSuffix(normalizeTarget(platform))}`
14
+ }
15
+
16
+ /*
17
+ Process-wide per-platform build coalescing. Two concurrent curls for
18
+ the same /__abide/cli/<platform> share one promise; the later requests
19
+ await the same one the first installed. The promise both runs the
20
+ freshness check AND the rebuild, so the map insertion is synchronous
21
+ relative to the first request's entry into the function — no window
22
+ between an `await` and `pendingBuilds.set` for a second concurrent
23
+ request to slip through and fire its own buildCli against the same
24
+ output paths.
25
+ */
26
+ const pendingBuilds = new Map<string, Promise<string | undefined>>()
27
+
28
+ async function ensurePlatformBinary(
29
+ platform: string,
30
+ programName: string,
31
+ cwd: string,
32
+ ): Promise<string | undefined> {
33
+ const existing = pendingBuilds.get(platform)
34
+ if (existing) {
35
+ return existing
36
+ }
37
+ const promise = computeBinary(platform, programName, cwd)
38
+ pendingBuilds.set(platform, promise)
39
+ /*
40
+ Drop the entry after settlement so a later request rebuilds if the
41
+ source has changed again. Identity-guard so a still-pending entry
42
+ installed by a follow-up request isn't evicted by ours.
43
+ */
44
+ promise.finally(() => {
45
+ if (pendingBuilds.get(platform) === promise) {
46
+ pendingBuilds.delete(platform)
47
+ }
48
+ })
49
+ return promise
50
+ }
51
+
52
+ async function computeBinary(
53
+ platform: string,
54
+ programName: string,
55
+ cwd: string,
56
+ ): Promise<string | undefined> {
57
+ const dir = `${cwd}/dist/cli-thin/${platform}`
58
+ const binaryPath = `${dir}/${programName}`
59
+ const serverPath = `${dir}/${serverBinaryName(platform)}`
60
+ /*
61
+ On-disk binaries are fresh when both the CLI and its sibling server exist AND
62
+ the CLI's mtime beats the newest rpc/socket source mtime. The mtime check
63
+ catches the common dev iteration where the user edits an rpc handler but didn't
64
+ run `abide cli` again; the server-exists check forces a rebuild for a dist
65
+ produced before the CLI co-shipped a server. Other source paths (project lib,
66
+ transitive imports) fall back to manual rebuild.
67
+ */
68
+ const binaryFile = Bun.file(binaryPath)
69
+ const serverFile = Bun.file(serverPath)
70
+ if ((await binaryFile.exists()) && (await serverFile.exists())) {
71
+ const binaryMtime = (await binaryFile.stat()).mtimeMs
72
+ const sourceMtime = await maxSourceMtime(cwd)
73
+ if (binaryMtime >= sourceMtime) {
74
+ return binaryPath
75
+ }
76
+ abideLog.info(`thin cli for ${platform} is stale — rebuilding`)
77
+ }
78
+ try {
79
+ abideLog.info(`lazy-building cli + server for ${platform}…`)
80
+ // Lazy-import buildCli so the build pipeline isn't pulled into
81
+ // production processes that never serve a download.
82
+ const { buildCli } = await import('../../../buildCli.ts')
83
+ await buildCli({
84
+ cwd,
85
+ platforms: [normalizeTarget(platform)],
86
+ })
87
+ return (await binaryFile.exists()) && (await serverFile.exists()) ? binaryPath : undefined
88
+ } catch (error) {
89
+ abideLog.error(error)
90
+ return undefined
91
+ }
92
+ }
93
+
94
+ /*
95
+ Handles GET /__abide/cli/<platform> — streams a gzipped tarball
96
+ containing the platform-specific thin binary + a `.env` carrying
97
+ ABIDE_APP_URL (and ABIDE_APP_TOKEN if the inbound request was authenticated).
98
+
99
+ Thin binaries live at `dist/cli-thin/<platform>/<programName>`
100
+ (produced by `abide cli` with ABIDE_APP_URL set). Missing platforms produce
101
+ 404 — the install script reports it, doesn't try to fall back.
102
+ */
103
+ export async function handleCliDownload(
104
+ request: Request,
105
+ platform: string,
106
+ programName: string,
107
+ cwd: string,
108
+ ): Promise<Response> {
109
+ /*
110
+ Validate the URL-supplied platform against the known target set before any
111
+ filesystem access or lazy build. Without this, an arbitrary `platform`
112
+ segment flows into `dist/cli-thin/<platform>` paths (a traversal/oracle
113
+ surface) and a cache miss triggers an expensive cross-compile — so spraying
114
+ distinct junk strings amplifies into unbounded concurrent builds.
115
+ */
116
+ const binaryPath = isCompileTarget(normalizeTarget(platform))
117
+ ? await ensurePlatformBinary(platform, programName, cwd)
118
+ : undefined
119
+ if (!binaryPath) {
120
+ return new Response(`unknown platform: ${platform}`, {
121
+ status: 404,
122
+ headers: { 'Cache-Control': NO_STORE },
123
+ })
124
+ }
125
+ const appUrl = new URL(request.url).origin
126
+ const auth = request.headers.get('authorization')
127
+ const bearer = auth?.toLowerCase().startsWith('bearer ')
128
+ ? auth.slice('bearer '.length)
129
+ : undefined
130
+ const envContent = buildEnvContent(appUrl, bearer)
131
+
132
+ const serverPath = `${cwd}/dist/cli-thin/${platform}/${serverBinaryName(platform)}`
133
+ const [binaryBytes, serverBytes] = await Promise.all([
134
+ Bun.file(binaryPath).bytes(),
135
+ Bun.file(serverPath).bytes(),
136
+ ])
137
+ // Ship the server beside the CLI so `/start` can spawn a local instance.
138
+ const archive = createTarGz([
139
+ { name: programName, content: binaryBytes, mode: 0o755 },
140
+ { name: serverBinaryName(platform), content: serverBytes, mode: 0o755 },
141
+ { name: '.env', content: new TextEncoder().encode(envContent), mode: 0o644 },
142
+ ])
143
+ return new Response(archive, {
144
+ headers: {
145
+ 'Content-Type': 'application/gzip',
146
+ 'Content-Disposition': `attachment; filename="${programName}-${platform}.tar.gz"`,
147
+ 'Cache-Control': NO_STORE,
148
+ },
149
+ })
150
+ }
@@ -0,0 +1,37 @@
1
+ import { NO_STORE } from '../../shared/CACHE_CONTROL_VALUES.ts'
2
+ import { installScript } from './installScript.ts'
3
+
4
+ /*
5
+ The request host is reflected verbatim into a shell script the user pipes
6
+ to `sh`, so it's constrained to the strict authority charset: letters,
7
+ digits, `.`, `-`, `_`, `:` (port + IPv6 separators), and IPv6 `[` `]`
8
+ brackets. That set excludes every character that could break out of the
9
+ interpolated `URL="…"` line in installScript (`"`, `$`, backtick, `\`,
10
+ whitespace), neutralising shell injection via a crafted Host header
11
+ regardless of how lenient the upstream URL parser is.
12
+ */
13
+ const SAFE_HOST = /^[A-Za-z0-9._:[\]-]+$/
14
+
15
+ /*
16
+ Handles GET /__abide/cli — returns the platform-detecting shell script.
17
+ Authoritative URL for the tarball is derived from the inbound request
18
+ (so the script's curl line points at whatever host the user reached us
19
+ on). Program name is the bundler-emitted `abide:cli-name` value.
20
+ */
21
+ export function handleCliInstall(request: Request, programName: string): Response {
22
+ const url = new URL(request.url)
23
+ if (!SAFE_HOST.test(url.host)) {
24
+ return new Response('Bad Request', {
25
+ status: 400,
26
+ headers: { 'Cache-Control': NO_STORE },
27
+ })
28
+ }
29
+ const appUrl = url.origin
30
+ const script = installScript(appUrl, programName)
31
+ return new Response(script, {
32
+ headers: {
33
+ 'Content-Type': 'text/x-shellscript; charset=utf-8',
34
+ 'Cache-Control': NO_STORE,
35
+ },
36
+ })
37
+ }
@@ -0,0 +1,31 @@
1
+ import { CLI_PATH } from '../../shared/CLI_PATH.ts'
2
+
3
+ /*
4
+ The shell script returned by `GET /__abide/cli` (no platform). Detects
5
+ uname OS + arch, normalises common arch aliases, then curls the right
6
+ platform-specific tarball and extracts it into `$ABIDE_INSTALL_DIR`
7
+ (default `~/.local/bin`). The tarball already contains the `.env` next
8
+ to the binary — no separate config write step in the script.
9
+
10
+ The script is rendered server-side so `<ABIDE_APP_URL>` is the request's own
11
+ origin and the embedded curl URL needs no escaping or quoting beyond
12
+ basic shell hygiene.
13
+ */
14
+ export function installScript(appUrl: string, programName: string): string {
15
+ return `#!/usr/bin/env sh
16
+ set -e
17
+ OS=$(uname -s | tr '[:upper:]' '[:lower:]')
18
+ case "$(uname -m)" in
19
+ x86_64|amd64) ARCH=x64 ;;
20
+ aarch64|arm64) ARCH=arm64 ;;
21
+ *) echo "unsupported architecture: $(uname -m)" >&2 ; exit 1 ;;
22
+ esac
23
+ INSTALL_DIR="\${ABIDE_INSTALL_DIR:-$HOME/.local/bin}"
24
+ mkdir -p "$INSTALL_DIR"
25
+ URL="${appUrl.replace(/\/$/, '')}${CLI_PATH}/\${OS}-\${ARCH}"
26
+ echo "installing ${programName} from $URL into $INSTALL_DIR"
27
+ curl -fsSL "$URL" | tar -xz -C "$INSTALL_DIR"
28
+ echo "installed: $INSTALL_DIR/${programName}"
29
+ echo "ensure $INSTALL_DIR is in your PATH"
30
+ `
31
+ }
@@ -0,0 +1,26 @@
1
+ import { existsSync } from 'node:fs'
2
+ import { Glob } from 'bun'
3
+
4
+ /*
5
+ Returns the most-recent mtime across every rpc + socket source file in
6
+ the project, or 0 when both directories are absent. The lazy CLI
7
+ download path compares this to the binary's mtime to decide whether to
8
+ rebuild — covers the common dev iteration of "user edited an rpc
9
+ handler" without needing to scan transitively-imported modules. Globs and
10
+ stats run concurrently since each file is independent.
11
+ */
12
+ export async function maxSourceMtime(cwd: string): Promise<number> {
13
+ const roots = [`${cwd}/src/server/rpc`, `${cwd}/src/server/sockets`].filter(existsSync)
14
+ const perRoot = await Promise.all(
15
+ roots.map(async (root) => {
16
+ const files = await Array.fromAsync(
17
+ new Glob('**/*.ts').scan({ cwd: root, onlyFiles: true }),
18
+ )
19
+ return files.map((file) => `${root}/${file}`)
20
+ }),
21
+ )
22
+ const mtimes = await Promise.all(
23
+ perRoot.flat().map(async (path) => (await Bun.file(path).stat()).mtimeMs),
24
+ )
25
+ return mtimes.reduce((newest, mtime) => Math.max(newest, mtime), 0)
26
+ }
@@ -0,0 +1,30 @@
1
+ import { requestContext } from './runtime/requestContext.ts'
2
+
3
+ /*
4
+ The cookie jar for the in-flight request. Reads parse the inbound `Cookie`
5
+ header; writes (`set` / `delete`) are collected and flushed to the response as
6
+ `Set-Cookie` headers when the handler returns (see runWithRequestScope). Backed
7
+ by Bun's native `CookieMap`, so it's a live `Map<string, string>` plus
8
+ `.set(name, value, options)` carrying the standard attributes (httpOnly, secure,
9
+ sameSite, maxAge, path, …) and `.delete(name)` for expiry:
10
+
11
+ const jar = cookies()
12
+ const session = jar.get('session') // read inbound
13
+ jar.set('session', token, { httpOnly: true, sameSite: 'lax' })
14
+ jar.delete('session') // expire on the way out
15
+
16
+ Materialized lazily on first call and cached on the request store, so a request
17
+ that never touches cookies parses nothing and emits no `Set-Cookie`. Throws
18
+ outside a request scope, like request().
19
+ */
20
+ // @readme request-scope
21
+ export function cookies(): Bun.CookieMap {
22
+ const store = requestContext.getStore()
23
+ if (!store) {
24
+ throw new Error(
25
+ '[abide] cookies() called outside a request scope — it only resolves while an SSR render or rpc handler is in flight',
26
+ )
27
+ }
28
+ store.cookies ??= new Bun.CookieMap(store.req.headers.get('cookie') ?? '')
29
+ return store.cookies
30
+ }
@@ -0,0 +1,51 @@
1
+ import type { StandardSchemaV1 } from '../shared/types/StandardSchemaV1.ts'
2
+ import { envSchemaStore } from './runtime/envSchemaStore.ts'
3
+
4
+ /*
5
+ Validates the process environment against a Standard Schema and returns the
6
+ typed, parsed config. Built to be called at module top level so a missing or
7
+ malformed variable fails the boot loudly rather than surfacing as `undefined`
8
+ deep inside a handler:
9
+
10
+ // src/server/config.ts
11
+ export const config = env(
12
+ v.object({ DATABASE_URL: v.string(), STRIPE_KEY: v.string() }),
13
+ )
14
+
15
+ Reads `Bun.env` (the process environment plus any `.env` Bun loaded), so any
16
+ Standard Schema library — zod, valibot, arktype — works without an adapter,
17
+ same as the verb helpers. Coercion (e.g. a numeric PORT) lives in the schema.
18
+
19
+ The schema is registered (envSchemaStore) so the bundle launcher can project
20
+ the first-run setup form from the same declaration. When the launcher imports
21
+ this purely to read that schema it sets `skipValidation`, so env() registers
22
+ and returns without validating Bun.env — boot validation stays the server's.
23
+
24
+ Validation must be synchronous — boot can't await config — so a schema whose
25
+ `validate` returns a Promise throws. On failure every issue is reported at once
26
+ (path + message) so a misconfigured deploy shows the full list rather than one
27
+ variable per restart.
28
+ */
29
+ // @readme configuration
30
+ export function env<Schema extends StandardSchemaV1>(
31
+ schema: Schema,
32
+ ): StandardSchemaV1.InferOutput<Schema> {
33
+ envSchemaStore.schema = schema
34
+ if (envSchemaStore.skipValidation) {
35
+ return Bun.env as unknown as StandardSchemaV1.InferOutput<Schema>
36
+ }
37
+ const result = schema['~standard'].validate(Bun.env)
38
+ if (result instanceof Promise) {
39
+ throw new Error('[abide] env() schema must validate synchronously')
40
+ }
41
+ if (result.issues) {
42
+ const lines = result.issues.map((issue) => {
43
+ const path = issue.path
44
+ ?.map((segment) => String(typeof segment === 'object' ? segment.key : segment))
45
+ .join('.')
46
+ return path ? ` ${path}: ${issue.message}` : ` ${issue.message}`
47
+ })
48
+ throw new Error(`[abide] invalid environment:\n${lines.join('\n')}`)
49
+ }
50
+ return result.value
51
+ }
@@ -0,0 +1,73 @@
1
+ import { NO_STORE } from '../shared/CACHE_CONTROL_VALUES.ts'
2
+ import { TEXT_PLAIN } from '../shared/TEXT_PLAIN.ts'
3
+ import type { TypedResponse } from './rpc/types/TypedResponse.ts'
4
+ import { withResponseDefaults } from './runtime/withResponseDefaults.ts'
5
+
6
+ /*
7
+ Plain-text error Response — clearer than constructing a Response by
8
+ hand with a status and a text body, and shaped so the client's
9
+ HttpError carries the message verbatim (`HttpError.response.text()`
10
+ returns the message, no parsing).
11
+
12
+ if (!order) return error(404, 'order not found')
13
+
14
+ `message` defaults to the status's standard reason phrase when
15
+ omitted (e.g. `error(404)` body = 'Not Found'). The body is
16
+ text/plain so intermediaries don't try to render or sniff it. A final
17
+ `ResponseInit` adds headers (e.g. `Retry-After` on a 429); the positional
18
+ `status` always wins over any `init.status`.
19
+
20
+ To short-circuit a handler instead of returning, `throw new Error(...)`
21
+ or `throw new HttpError(error(...))` — the framework's `app.handleError`
22
+ hook catches thrown errors. This helper deliberately returns a Response
23
+ rather than throwing one so a single `return error(...)` is the
24
+ expected pattern, with the same control flow as `return json(...)`.
25
+ */
26
+
27
+ /*
28
+ Standard reason phrases for the statuses error() is realistically called
29
+ with. Maintained explicitly because Bun's `Response` does not populate
30
+ `statusText` from the status code, so there's no platform table to read.
31
+ Unlisted codes fall back to `HTTP <status>`.
32
+ */
33
+ const STATUS_TEXT: Record<number, string> = {
34
+ 400: 'Bad Request',
35
+ 401: 'Unauthorized',
36
+ 403: 'Forbidden',
37
+ 404: 'Not Found',
38
+ 405: 'Method Not Allowed',
39
+ 409: 'Conflict',
40
+ 410: 'Gone',
41
+ 413: 'Content Too Large',
42
+ 422: 'Unprocessable Content',
43
+ 429: 'Too Many Requests',
44
+ 500: 'Internal Server Error',
45
+ 501: 'Not Implemented',
46
+ 502: 'Bad Gateway',
47
+ 503: 'Service Unavailable',
48
+ 504: 'Gateway Timeout',
49
+ }
50
+
51
+ /*
52
+ Body type is `never` because `error()` only travels the non-2xx path on
53
+ the wire — the caller's `await fn(args)` throws `HttpError` and never
54
+ resolves to this response's body. Returning a TypedResponse<never> lets
55
+ the union of branches in a handler narrow to whatever the success
56
+ branch carries (`TypedResponse<{user}> | TypedResponse<never>` → Return
57
+ = {user}).
58
+ */
59
+ // @readme response
60
+ export function error(status: number, message?: string, init?: ResponseInit): TypedResponse<never> {
61
+ const body = message ?? STATUS_TEXT[status] ?? `HTTP ${status}`
62
+ return new Response(
63
+ body,
64
+ withResponseDefaults(
65
+ init,
66
+ {
67
+ 'Content-Type': TEXT_PLAIN,
68
+ 'Cache-Control': NO_STORE,
69
+ },
70
+ status,
71
+ ),
72
+ ) as TypedResponse<never>
73
+ }
@@ -0,0 +1,42 @@
1
+ import { NO_STORE } from '../shared/CACHE_CONTROL_VALUES.ts'
2
+ import type { TypedResponse } from './rpc/types/TypedResponse.ts'
3
+ import { withResponseDefaults } from './runtime/withResponseDefaults.ts'
4
+
5
+ /*
6
+ JSON Response with rpc-friendly defaults — same shape as
7
+ `Response.json(data, init)`, except `Cache-Control: no-store` is set
8
+ unless the caller overrides it. Intermediary caches (browsers, CDNs,
9
+ shared proxies) shouldn't cache rpc replies by default; the framework's
10
+ own per-request cache handles in-process dedupe.
11
+
12
+ export const getOrder = GET<{ id: string }>(async ({ id }) =>
13
+ json(await db.getOrder(id)),
14
+ )
15
+
16
+ The return type carries `T` as a phantom brand so the verb helper can
17
+ infer the caller-facing `Return` from the handler body — no need to
18
+ annotate `GET<Args, Return>` just to type the response shape.
19
+
20
+ For non-default cache policy pass `init.headers`; explicit
21
+ `cache-control` wins over the default.
22
+
23
+ JSON has no encoding for `undefined` — `Response.json(undefined)` throws
24
+ TypeError. `json(undefined)` instead emits 204 No Content, which
25
+ decodeResponse maps back to `undefined` on both the fetch and in-process
26
+ paths, so a handler typed `Shape | undefined` round-trips the wire. The
27
+ helper owns the 204 (a body-bearing status with no body would break the
28
+ round trip), so it wins over any `init.status`.
29
+ */
30
+ // @readme response
31
+ export function json<T>(data: T, init?: ResponseInit): TypedResponse<T> {
32
+ if (data === undefined) {
33
+ return new Response(
34
+ undefined,
35
+ withResponseDefaults(init, { 'Cache-Control': NO_STORE }, 204),
36
+ ) as TypedResponse<T>
37
+ }
38
+ return Response.json(
39
+ data,
40
+ withResponseDefaults(init, { 'Cache-Control': NO_STORE }),
41
+ ) as TypedResponse<T>
42
+ }
@@ -0,0 +1,47 @@
1
+ /*
2
+ Wraps an AsyncIterable<Frame> in a Response whose body is JSON Lines
3
+ (application/jsonl) — one JSON value per line, terminated by `\n`. Used
4
+ inside an rpc handler to turn a generator into a streaming HTTP response
5
+ that `tail(fn.stream(args))` consumes frame-by-frame on the client.
6
+
7
+ export const orderFeed = GET<Args>((args) =>
8
+ jsonl(async function* () {
9
+ for await (const order of db.watchOrders(args)) yield order
10
+ }())
11
+ )
12
+
13
+ Cancellation flows from the consumer through ReadableStream's `cancel`
14
+ into `iter.return()` so the handler's `for await` exits via its normal
15
+ control path (DB cursors, file handles, etc. get to release in finally).
16
+
17
+ Errors thrown by the generator are emitted as a final
18
+ `{"$error":"<message>"}` line before the stream closes. The convention
19
+ keeps the format JSON-safe and lets the consumer distinguish "stream
20
+ ended cleanly" from "handler threw" without a side-channel. The full
21
+ error is logged server-side via the framework's error handler — only the
22
+ message crosses the wire.
23
+ */
24
+ import { NO_STORE } from '../shared/CACHE_CONTROL_VALUES.ts'
25
+ import { jsonlErrorFrame } from '../shared/jsonlErrorFrame.ts'
26
+ import type { TypedResponse } from './rpc/types/TypedResponse.ts'
27
+ import { streamFromIterator } from './runtime/streamFromIterator.ts'
28
+ import { withResponseDefaults } from './runtime/withResponseDefaults.ts'
29
+
30
+ // @readme response
31
+ export function jsonl<Frame>(
32
+ iterable: AsyncIterable<Frame>,
33
+ init?: ResponseInit,
34
+ ): TypedResponse<Frame> {
35
+ const body = streamFromIterator(iterable, {
36
+ encodeFrame: (value) => `${JSON.stringify(value)}\n`,
37
+ encodeError: (message) => jsonlErrorFrame.encode(message),
38
+ })
39
+ return new Response(
40
+ body,
41
+ withResponseDefaults(init, {
42
+ 'Content-Type': 'application/jsonl; charset=utf-8',
43
+ 'Cache-Control': NO_STORE,
44
+ 'X-Content-Type-Options': 'nosniff',
45
+ }),
46
+ ) as TypedResponse<Frame>
47
+ }
@@ -0,0 +1,21 @@
1
+ import { registerPrompt } from './registerPrompt.ts'
2
+ import type { Prompt } from './types/Prompt.ts'
3
+ import type { PromptOptions } from './types/PromptOptions.ts'
4
+
5
+ /*
6
+ Builds a Prompt from a name + options. The resolver plugin parses every
7
+ `src/mcp/prompts/<file>.md` and generates a module that calls
8
+ `definePrompt("<name>", { description, jsonSchema, render })`, so the file
9
+ path becomes the prompt's identity. Registers itself so the MCP dispatcher
10
+ can enumerate and render it.
11
+ */
12
+ // @readme plumbing
13
+ export function definePrompt(name: string, opts: PromptOptions): Prompt {
14
+ const self: Prompt = {
15
+ name,
16
+ description: opts.description,
17
+ render: opts.render,
18
+ }
19
+ registerPrompt({ prompt: self, jsonSchema: opts.jsonSchema })
20
+ return self
21
+ }
@@ -0,0 +1,9 @@
1
+ import type { PromptRegistryEntry } from './types/PromptRegistryEntry.ts'
2
+
3
+ /*
4
+ Process-wide registry of every prompt declared in the app. definePrompt
5
+ inserts on first construction (eagerly when the registry loader walks the
6
+ prompts manifest at MCP boot). The MCP server reads this to build its
7
+ `prompts/list` + `prompts/get` responses.
8
+ */
9
+ export const promptRegistry = new Map<string, PromptRegistryEntry>()
@@ -0,0 +1,6 @@
1
+ import { promptRegistry } from './promptRegistry.ts'
2
+ import type { PromptRegistryEntry } from './types/PromptRegistryEntry.ts'
3
+
4
+ export function registerPrompt(entry: PromptRegistryEntry): void {
5
+ promptRegistry.set(entry.prompt.name, entry)
6
+ }
@@ -0,0 +1,17 @@
1
+ // `{{name}}` placeholder, surrounding whitespace tolerated, names are
2
+ // word chars or hyphens to match valid MCP argument identifiers.
3
+ const PLACEHOLDER = /\{\{\s*([\w-]+)\s*\}\}/g
4
+
5
+ /*
6
+ Renders a markdown prompt body by substituting each `{{name}}` placeholder
7
+ with the matching argument value. Missing arguments collapse to an empty
8
+ string — MCP only enforces `required` at the client, so an optional
9
+ argument the model omits should vanish from the text. Called by the
10
+ render closure the resolver plugin generates for every `.md` prompt.
11
+ */
12
+ // @readme plumbing
13
+ export function renderPromptTemplate(template: string, args: Record<string, string>): string {
14
+ return template.replace(PLACEHOLDER, (_match, key: string) =>
15
+ args[key] === undefined ? '' : String(args[key]),
16
+ )
17
+ }