@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,68 @@
1
+ import { cacheStores } from './cacheStores.ts'
2
+ import { isSubscribable } from './isSubscribable.ts'
3
+ import { selectorMatcher } from './selectorMatcher.ts'
4
+ import { selectorPrefix } from './selectorPrefix.ts'
5
+ import { tailProbeSlot } from './tailProbeSlot.ts'
6
+ import type { CacheEntry } from './types/CacheEntry.ts'
7
+ import type { CacheSelector } from './types/CacheSelector.ts'
8
+ import type { CacheStore } from './types/CacheStore.ts'
9
+ import type { Subscribable } from './types/Subscribable.ts'
10
+
11
+ /*
12
+ Shared scan behind the pending() / refreshing() probes: one selector
13
+ interpretation and one tap order — the lifecycle channel is tapped before
14
+ any check, so short-circuiting can't skip a subscription and a $derived
15
+ re-runs whenever a matching call or stream changes state. The tap is scoped
16
+ to the selector: a fn selector taps only its own prefix channel, so reading
17
+ `pending(fn)` in an effect can't be re-woken by unrelated cache events (an
18
+ effect that probes one fn and invalidates another no longer feeds itself);
19
+ bare and scope selectors scan many entries and tap the store-wide channel. A
20
+ producer never cached resolves no prefix yet and taps store-wide — its first
21
+ cache() marks that channel, the re-derive resolves the prefix, and the scope
22
+ re-tracks narrowed. `matchesEntry` is the probe's cache-side question;
23
+ `field` selects the stream-side answer; `unprobed` is the answer for a
24
+ stream no prober can see (server, or tail never imported) — matching what
25
+ tail() itself reports there. The bare form (no selector) spans both
26
+ registries; fn/scope selectors are cache identities only. Outside a tracking
27
+ scope the taps are no-ops and the current value returns.
28
+ */
29
+ export function probeRegistries<Args, Return>(
30
+ arg: CacheSelector<Args, Return> | Subscribable<unknown> | undefined,
31
+ args: Args | undefined,
32
+ field: 'pending' | 'refreshing',
33
+ matchesEntry: (entry: CacheEntry) => boolean,
34
+ unprobed: boolean,
35
+ ): boolean {
36
+ if (isSubscribable(arg)) {
37
+ return tailProbeSlot.probe?.(arg.name)?.[field] ?? unprobed
38
+ }
39
+ /* fn + args narrows further: the exact key is a one-entry "prefix" (its === branch). */
40
+ const prefix = selectorPrefix(arg, args)
41
+ const stores = cacheStores()
42
+ stores.forEach((store) => {
43
+ store.trackLifecycle(prefix)
44
+ })
45
+ const streams = arg === undefined ? tailProbeSlot.probe?.() : undefined
46
+ const matches = selectorMatcher(arg, args, prefix)
47
+ return (
48
+ stores.some((store) => anyEntryMatches(store, matchesEntry, matches)) ||
49
+ streams?.[field] === true
50
+ )
51
+ }
52
+
53
+ /*
54
+ A plain for-of over the entries Map rather than .values().some() — Iterator
55
+ Helpers are too new for this module's browser baseline (see producerKey).
56
+ */
57
+ function anyEntryMatches(
58
+ store: CacheStore,
59
+ matchesEntry: (entry: CacheEntry) => boolean,
60
+ matches: (entry: CacheEntry) => boolean,
61
+ ): boolean {
62
+ for (const entry of store.entries.values()) {
63
+ if (matchesEntry(entry) && matches(entry)) {
64
+ return true
65
+ }
66
+ }
67
+ return false
68
+ }
@@ -0,0 +1,32 @@
1
+ import { canonicalJson } from './canonicalJson.ts'
2
+
3
+ /*
4
+ Producers have no wire identity, so each is assigned a stable id on first use,
5
+ kept in a WeakMap so it's collected with the function. The cache key is that id
6
+ plus the canonicalised args — a hoisted producer dedupes across calls; an inline
7
+ arrow gets a fresh id every call and never does.
8
+
9
+ `producerKey.existing` reads the id without assigning one — selectors matching
10
+ prior entries must not mint identities for producers never cached.
11
+ */
12
+ const producerIds = new WeakMap<object, string>()
13
+ let producerCounter = 0
14
+
15
+ export function producerKey(producer: object, args: unknown): string {
16
+ /* Not getOrInsertComputed: shared module ships to the browser, where support is too new (Safari 26.2 / Chrome 145). */
17
+ let id = producerIds.get(producer)
18
+ if (id === undefined) {
19
+ id = `@producer:${++producerCounter}`
20
+ producerIds.set(producer, id)
21
+ }
22
+ return args === undefined ? id : `${id} ${canonicalJson(args)}`
23
+ }
24
+
25
+ /* With `args`, the exact entry key for that call (same format as producerKey) — still never minting. */
26
+ producerKey.existing = function existing(producer: object, args?: unknown): string | undefined {
27
+ const id = producerIds.get(producer)
28
+ if (id === undefined || args === undefined) {
29
+ return id
30
+ }
31
+ return `${id} ${canonicalJson(args)}`
32
+ }
@@ -0,0 +1,14 @@
1
+ /*
2
+ Derives the CLI program/binary name from a package.json `name` field.
3
+ Scoped names (`@scope/tool`) keep only the final segment so the value is
4
+ safe as a filesystem path, tar entry name, and CLI display name — a raw
5
+ `/` would otherwise nest the binary into an unexpected directory and break
6
+ the `/__abide/cli/<platform>` download route's path lookup. Falls back to
7
+ `app` when the name is absent or empty.
8
+ */
9
+ export function programNameForPackage(name: string | undefined): string {
10
+ if (name === undefined || name === '') {
11
+ return 'app'
12
+ }
13
+ return name.split('/').pop() || 'app'
14
+ }
@@ -0,0 +1,10 @@
1
+ /*
2
+ Translates a prompt file path under `src/mcp/prompts/` into the prompt's
3
+ MCP name. Strips `.md` and joins nested folder segments with `-` (e.g.
4
+ `code/review.md` → `code-review`) so two prompts with the same stem in
5
+ different folders don't collide and the name stays a single valid MCP
6
+ prompt identifier.
7
+ */
8
+ export function promptNameForFile(relativePath: string): string {
9
+ return relativePath.replace(/\.md$/, '').replaceAll('/', '-')
10
+ }
@@ -0,0 +1,27 @@
1
+ /*
2
+ Canonical query-string encoding for a query-carrying verb's args bag. The
3
+ single definition both the synthesized Request (buildRpcRequest) and its
4
+ cache key (keyForRemoteCall) build their query from, so the request URL and
5
+ the key encode every value identically and can't drift. `undefined` values
6
+ are dropped; each surviving value is coerced with String() and percent-
7
+ encoded with encodeURIComponent on both name and value. Keys come in
8
+ insertion order for the request and sorted for the key (`sort`), so the key
9
+ is stable under arg reordering. Returns the query body without a leading
10
+ `?` (empty string when nothing survives the filter). Concatenated in one
11
+ walk — no entries / filtered / URLSearchParams intermediates — to keep the
12
+ hot GET-cache path allocation-light. Callers validate that `args` is a
13
+ plain object first; this assumes that.
14
+ */
15
+ export function queryStringFromArgs(args: Record<string, unknown>, sort: boolean): string {
16
+ const keys = sort ? Object.keys(args).sort() : Object.keys(args)
17
+ let query = ''
18
+ for (const key of keys) {
19
+ const value = args[key]
20
+ if (value === undefined) {
21
+ continue
22
+ }
23
+ query += query ? '&' : ''
24
+ query += `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`
25
+ }
26
+ return query
27
+ }
@@ -0,0 +1,14 @@
1
+ /*
2
+ Mints a random lowercase-hex id of `bytes` length via the web-standard
3
+ crypto.getRandomValues — trace ids (16 bytes) and span ids (8 bytes). Loops on
4
+ the all-zero value, which W3C Trace Context reserves as invalid.
5
+ */
6
+ export function randomHexId(bytes: number): string {
7
+ const buffer = new Uint8Array(bytes)
8
+ let id = ''
9
+ do {
10
+ crypto.getRandomValues(buffer)
11
+ id = Array.from(buffer, (byte) => byte.toString(16).padStart(2, '0')).join('')
12
+ } while (/^0+$/.test(id))
13
+ return id
14
+ }
@@ -0,0 +1,15 @@
1
+ import { existsSync } from 'node:fs'
2
+ import { parseEnv } from './parseEnv.ts'
3
+
4
+ /*
5
+ Reads a `.env` at `path` into a key→value record, or {} when it doesn't exist.
6
+ The shared read-and-parse primitive: loadEnvFile builds on it to merge into
7
+ process.env, and the bundle launcher uses the record directly to resolve config
8
+ form pre-fills.
9
+ */
10
+ export async function readEnvFile(path: string): Promise<Record<string, string>> {
11
+ if (!existsSync(path)) {
12
+ return {}
13
+ }
14
+ return parseEnv(await Bun.file(path).text())
15
+ }
@@ -0,0 +1,18 @@
1
+ import { lastConnectionPath } from './lastConnectionPath.ts'
2
+ import type { LastConnection } from './types/LastConnection.ts'
3
+
4
+ /*
5
+ Reads the saved connection intent, or undefined when none is recorded or the file
6
+ is unreadable/corrupt — callers treat undefined as "nothing to resume".
7
+ */
8
+ export async function readLastConnection(programName: string): Promise<LastConnection | undefined> {
9
+ const file = Bun.file(lastConnectionPath(programName))
10
+ if (!(await file.exists())) {
11
+ return undefined
12
+ }
13
+ try {
14
+ return (await file.json()) as LastConnection
15
+ } catch {
16
+ return undefined
17
+ }
18
+ }
@@ -0,0 +1,9 @@
1
+ /*
2
+ Reads and parses a project's `package.json`, or undefined when absent. Callers
3
+ apply their own field defaults — this centralizes only the exists-check + parse
4
+ boilerplate. Bun.file().json() so no Node fs.
5
+ */
6
+ export async function readPackageJson(cwd: string): Promise<Record<string, unknown> | undefined> {
7
+ const file = Bun.file(`${cwd}/package.json`)
8
+ return (await file.exists()) ? ((await file.json()) as Record<string, unknown>) : undefined
9
+ }
@@ -0,0 +1,5 @@
1
+ import { remoteMetaStore } from './remoteMetaStore.ts'
2
+
3
+ export function recordRemoteMeta(promise: Promise<unknown>, getRequest: () => Request): void {
4
+ remoteMetaStore.set(promise, getRequest)
5
+ }
@@ -0,0 +1,31 @@
1
+ import { probeRegistries } from './probeRegistries.ts'
2
+ import type { CacheEntry } from './types/CacheEntry.ts'
3
+ import type { CacheSelector } from './types/CacheSelector.ts'
4
+ import type { Subscribable } from './types/Subscribable.ts'
5
+
6
+ /*
7
+ Reactive revalidation probe over both registries. Refreshing means "holding a
8
+ value it already had while a fresher source is in flight":
9
+ refreshing() → anything reloading data it already had
10
+ refreshing(fn) → that function's calls (per-route "updating…" badge)
11
+ refreshing(fn, args) → exactly that call (per-row badge)
12
+ refreshing({ scope }) → a tagged group
13
+ refreshing(subscribable) → that stream reconnecting with its last value
14
+ retained — never merely `open`; a live stream's
15
+ arriving frames are its normal mode, not a reload
16
+ On the cache side this covers a policy stale-while-revalidate refetch (settled,
17
+ value visible, fresh fetch in flight) and the default drop-then-reload (pending
18
+ is also true there). The distinction from pending(): pending answers "is there
19
+ no value yet?", refreshing answers "is a held value being superseded?".
20
+ Probes report, never act. Scan semantics (tap order, selector grammar,
21
+ registry spans) live in probeRegistries.
22
+ */
23
+ // @readme probes
24
+ export function refreshing<Args, Return>(
25
+ arg?: CacheSelector<Args, Return> | Subscribable<unknown>,
26
+ args?: Args,
27
+ ): boolean {
28
+ return probeRegistries(arg, args, 'refreshing', reloading, false)
29
+ }
30
+
31
+ const reloading = (entry: CacheEntry) => entry.refreshing === true
@@ -0,0 +1,16 @@
1
+ /*
2
+ WeakMap that records how to obtain the synthesized Request for a verb
3
+ call. The cache layer reads it to populate an entry's stored request
4
+ without rebuilding from scratch.
5
+
6
+ Stored as a thunk rather than the Request itself so SSR pages that fire
7
+ dozens of in-process verb calls without ever reaching cache() don't pay
8
+ the URL + Headers + Request allocation per call. The thunk memoises its
9
+ own first call inside createRemoteFunction, so cache() and any future
10
+ meta reader see the same Request instance.
11
+
12
+ method/url/key are intentionally not stored — they're derivable from
13
+ the RemoteFunction itself, and cache() does that derivation
14
+ independently.
15
+ */
16
+ export const remoteMetaStore = new WeakMap<Promise<unknown>, () => Request>()
@@ -0,0 +1,15 @@
1
+ import type { RequestScopeInfo } from './types/RequestScopeInfo.ts'
2
+
3
+ /*
4
+ Internal slot the runtime entries register their request-scope resolver into.
5
+ The server installs an ALS-backed resolver (createServer, reading the
6
+ RequestStore); the client installs a module-singleton resolver seeded from
7
+ __SSR__ (startClient). Undefined resolver — or a resolver returning undefined
8
+ outside any request — means "no scope": trace() returns undefined and log
9
+ lines print without the context prefix. Mirrors pageSlot / cacheStoreSlot.
10
+ */
11
+ export const requestScopeSlot: {
12
+ resolver: (() => RequestScopeInfo | undefined) | undefined
13
+ } = {
14
+ resolver: undefined,
15
+ }
@@ -0,0 +1,20 @@
1
+ import type { ClientFlags } from './types/ClientFlags.ts'
2
+
3
+ /*
4
+ Fills in the missing keys of a user-supplied `clients` option. Browser
5
+ always defaults to true (the historical surface). The mcp/cli auto-on
6
+ defaults are decided by the caller and passed in, since the safe default
7
+ differs per declaration: a read-only verb may auto-expose to MCP while a
8
+ mutating one must not, and sockets gate differently again. Explicit
9
+ values in `flags` always win over the computed defaults.
10
+ */
11
+ export function resolveClientFlags(
12
+ flags: Partial<ClientFlags> | undefined,
13
+ defaults: { mcp: boolean; cli: boolean },
14
+ ): ClientFlags {
15
+ return {
16
+ browser: flags?.browser ?? true,
17
+ mcp: flags?.mcp ?? defaults.mcp,
18
+ cli: flags?.cli ?? defaults.cli,
19
+ }
20
+ }
@@ -0,0 +1,9 @@
1
+ /*
2
+ Human-readable message for a non-2xx Response: `status statusText: body`.
3
+ Shared by the CLI error path and the MCP tool result so the two frame a
4
+ failed request identically. Consumes the body, so call only on a response
5
+ you're done with.
6
+ */
7
+ export async function responseErrorText(response: Response): Promise<string> {
8
+ return `${response.status} ${response.statusText}: ${await response.text()}`
9
+ }
@@ -0,0 +1,9 @@
1
+ /*
2
+ Slot the client entry registers the env-configured RPC fetch timeout (ms)
3
+ into. The server reads ABIDE_CLIENT_TIMEOUT at boot and ships it via
4
+ __SSR__.clientTimeout, so the value reflects the running server's env rather
5
+ than build time; startClient installs it here and remoteProxy reads it.
6
+ undefined = no timeout (the default — RPC fetches stay unbounded as before).
7
+ Mirrors baseSlot.
8
+ */
9
+ export const rpcTimeoutSlot: { ms: number | undefined } = { ms: undefined }
@@ -0,0 +1,19 @@
1
+ /*
2
+ Maps an rpc-relative path (under `src/server/rpc/`) to its URL. Each file
3
+ is one endpoint at `/rpc/<file path>`, dropping the `.ts` extension.
4
+ $rpc URLs are flat function-call endpoints (args go in query or body), so
5
+ bracket-style `[name]` / `[...rest]` segments are rejected — those belong
6
+ in `src/ui/pages/` where they map to dynamic path params.
7
+ */
8
+ export function rpcUrlForFile(relPath: string): string {
9
+ const withoutExt = relPath.replace(/\.ts$/, '')
10
+ const segments = withoutExt.split('/').filter(Boolean)
11
+ for (const segment of segments) {
12
+ if (segment.startsWith('[')) {
13
+ throw new Error(
14
+ `[abide] src/server/rpc/${relPath} has a dynamic segment '${segment}' — $rpc URLs are flat; pass identifiers via args, not the path`,
15
+ )
16
+ }
17
+ }
18
+ return `/rpc/${segments.join('/')}`
19
+ }
@@ -0,0 +1,13 @@
1
+ /*
2
+ True when this code runs inside a `bun build --compile` standalone executable
3
+ (the bundle's embedded server, or an install-tarball server binary) rather than
4
+ under the `bun` CLI. Bun mounts a compiled binary's embedded modules under a
5
+ synthetic root — `/$bunfs/…` on posix, `…~BUN…` on Windows — so `Bun.main`
6
+ carries that marker only in a standalone binary; under `bun dev`/`bun start`
7
+ it's a real on-disk path. Used to scope the bundle's data-dir/binary-dir `.env`
8
+ loading to the shipped app, so `bun dev`/`bun start` keep to their project-local
9
+ CWD `.env` alone.
10
+ */
11
+ export function runningAsStandaloneBinary(): boolean {
12
+ return Bun.main.includes('$bunfs') || Bun.main.includes('~BUN')
13
+ }
@@ -0,0 +1,68 @@
1
+ import { keyMatchesPrefix } from './keyMatchesPrefix.ts'
2
+ import { selectorPrefix } from './selectorPrefix.ts'
3
+ import { toScopeSet } from './toScopeSet.ts'
4
+ import type { CacheEntry } from './types/CacheEntry.ts'
5
+ import type { CacheSelector } from './types/CacheSelector.ts'
6
+
7
+ /*
8
+ Compiles a selector into an entry predicate shared by cache.invalidate(),
9
+ pending(), and refreshing() so all three interpret the call shapes identically:
10
+ undefined → every entry
11
+ remote fn → that function's calls (method+url prefix). `arg.url` is
12
+ the route template; per-call args appear as `?...`
13
+ (GET/DELETE) or after a space (canonical-json body) —
14
+ see keyForRemoteCall. `fn` and `fn.raw` match the same
15
+ set since they share method+url.
16
+ producer fn → that producer's calls (reference id prefix). Matches
17
+ only if the producer was cached at least once (else it
18
+ has no id and nothing matches).
19
+ { scope } → any entry sharing one of the requested scope tags. An
20
+ empty selector matches nothing.
21
+ fn + args → exactly that call's entry (the key derived from the
22
+ same encoders the read path uses); other args
23
+ variants of the fn are untouched.
24
+ Fn-selector identity (prefix resolution + the cache()-wrapper throw) lives in
25
+ selectorPrefix, the prefix grammar in keyMatchesPrefix — both shared with the
26
+ probes' scoped lifecycle channels so a probe subscribes to exactly the entries
27
+ this predicate would match. A caller that already resolved the prefix (the
28
+ invalidate/probe paths derive it for their own use) passes it as
29
+ `precomputedPrefix` so the args encoding isn't re-derived per call.
30
+ */
31
+ export function selectorMatcher<Args, Return>(
32
+ arg?: CacheSelector<Args, Return>,
33
+ args?: Args,
34
+ precomputedPrefix?: string,
35
+ ): (entry: CacheEntry) => boolean {
36
+ if (arg === undefined) {
37
+ return () => true
38
+ }
39
+ if (typeof arg === 'function') {
40
+ const prefix = precomputedPrefix ?? selectorPrefix(arg, args)
41
+ if (prefix === undefined) {
42
+ return () => false
43
+ }
44
+ if (args !== undefined) {
45
+ return (entry) => entry.key === prefix
46
+ }
47
+ return (entry) => keyMatchesPrefix(entry.key, prefix)
48
+ }
49
+ if (arg.scope === undefined) {
50
+ return () => false
51
+ }
52
+ const requestedScopes = toScopeSet(arg.scope)
53
+ return (entry) => entry.scope !== undefined && intersects(entry.scope, requestedScopes)
54
+ }
55
+
56
+ /*
57
+ True when an entry's tags and the requested tags overlap on any tag. A plain
58
+ for-of over the Set rather than .values().some() — Iterator Helpers are too new
59
+ for this module's browser baseline (see producerKey).
60
+ */
61
+ function intersects(entryScopes: Set<string>, requestedScopes: Set<string>): boolean {
62
+ for (const scope of requestedScopes) {
63
+ if (entryScopes.has(scope)) {
64
+ return true
65
+ }
66
+ }
67
+ return false
68
+ }
@@ -0,0 +1,39 @@
1
+ import { CACHE_WRAPPED } from './CACHE_WRAPPED.ts'
2
+ import { keyForRemoteCall } from './keyForRemoteCall.ts'
3
+ import { producerKey } from './producerKey.ts'
4
+ import { REMOTE_FUNCTION } from './REMOTE_FUNCTION.ts'
5
+ import type { CacheSelector } from './types/CacheSelector.ts'
6
+ import type { RawRemoteFunction } from './types/RawRemoteFunction.ts'
7
+
8
+ /*
9
+ Resolves a fn selector to the key prefix its entries share: a remote keys on
10
+ method+url (fn and fn.raw agree — same wire identity), a producer on the
11
+ reference id minted at first cache. With `args`, the exact entry key for that
12
+ one call instead — derived through the same encoders the read path uses
13
+ (keyForRemoteCall / producerKey format), so selector and entry can't
14
+ disagree. Undefined when no prefix exists — bare and scope selectors (they
15
+ scan, not prefix-match) and producers never cached (no id was minted;
16
+ minting one here would leak identities for probe-only reads). The
17
+ cache()-wrapper throw lives here so both consumers — the matcher and the
18
+ probes' channel tap — reject it before subscribing to anything.
19
+ */
20
+ export function selectorPrefix<Args, Return>(
21
+ arg: CacheSelector<Args, Return> | undefined,
22
+ args?: Args,
23
+ ): string | undefined {
24
+ if (typeof arg !== 'function') {
25
+ return undefined
26
+ }
27
+ if (CACHE_WRAPPED in arg) {
28
+ throw new Error(
29
+ '[abide] a cache() wrapper is not a selector — pass the function it wraps, e.g. pending(getPost), not pending(cache(getPost))',
30
+ )
31
+ }
32
+ const remote = REMOTE_FUNCTION in arg ? (arg as RawRemoteFunction<Args>) : undefined
33
+ if (remote) {
34
+ return args === undefined
35
+ ? `${remote.method} ${remote.url}`
36
+ : keyForRemoteCall(remote.method, remote.url, args)
37
+ }
38
+ return producerKey.existing(arg, args)
39
+ }
@@ -0,0 +1,18 @@
1
+ // Quote only values that wouldn't round-trip bare through parseEnv — empties and
2
+ // anything carrying whitespace or a `#` (which would otherwise read as a comment).
3
+ function needsQuoting(value: string): boolean {
4
+ return value === '' || /[\s#]/.test(value)
5
+ }
6
+
7
+ /*
8
+ Serializes a key→value record to `.env` text — the inverse of parseEnv, used by
9
+ the connect-screen config form to persist the user's answers to the data-dir
10
+ `.env`. One `KEY=value` per line; values that need it are wrapped in double
11
+ quotes so parseEnv reads them back unchanged.
12
+ */
13
+ export function serializeEnv(values: Record<string, string>): string {
14
+ const lines = Object.entries(values).map(([key, value]) =>
15
+ needsQuoting(value) ? `${key}="${value}"` : `${key}=${value}`,
16
+ )
17
+ return `${lines.join('\n')}\n`
18
+ }
@@ -0,0 +1,5 @@
1
+ import { appNameSlot } from './appNameSlot.ts'
2
+
3
+ export function setAppName(name: string | undefined): void {
4
+ appNameSlot.name = name
5
+ }
@@ -0,0 +1,6 @@
1
+ import { baseSlot } from './baseSlot.ts'
2
+
3
+ // Registers the runtime's mount-base resolver. Called once per side at boot.
4
+ export function setBaseResolver(fn: () => string): void {
5
+ baseSlot.resolver = fn
6
+ }
@@ -0,0 +1,6 @@
1
+ import { cacheStoreSlot } from './cacheStoreSlot.ts'
2
+ import type { CacheStore } from './types/CacheStore.ts'
3
+
4
+ export function setCacheStoreResolver(fn: () => CacheStore | undefined): void {
5
+ cacheStoreSlot.resolver = fn
6
+ }
@@ -0,0 +1,6 @@
1
+ import { globalCacheStoreSlot } from './globalCacheStoreSlot.ts'
2
+ import type { CacheStore } from './types/CacheStore.ts'
3
+
4
+ export function setGlobalCacheStoreResolver(fn: () => CacheStore | undefined): void {
5
+ globalCacheStoreSlot.resolver = fn
6
+ }
@@ -0,0 +1,7 @@
1
+ import { pageSlot } from './pageSlot.ts'
2
+ import type { PageSnapshot } from './types/PageSnapshot.ts'
3
+
4
+ // Registers the runtime's page resolver. Called once per side at boot.
5
+ export function setPageResolver(fn: () => PageSnapshot | undefined): void {
6
+ pageSlot.resolver = fn
7
+ }
@@ -0,0 +1,6 @@
1
+ import { requestScopeSlot } from './requestScopeSlot.ts'
2
+ import type { RequestScopeInfo } from './types/RequestScopeInfo.ts'
3
+
4
+ export function setRequestScopeResolver(fn: () => RequestScopeInfo | undefined): void {
5
+ requestScopeSlot.resolver = fn
6
+ }
@@ -0,0 +1,25 @@
1
+ const SNIPPET = Symbol.for('abide.snippet')
2
+
3
+ /* A `<template name args>` snippet, called like a function: it carries a payload a
4
+ `{expr}` interpolation mounts in place — a DOM builder `(host) => void` on the
5
+ client, the pre-rendered HTML string on the server. The brand is a registered
6
+ Symbol so it survives across module/bundle copies (same idiom as `html\`\``). */
7
+ export type Snippet<Payload> = { readonly [SNIPPET]: Payload }
8
+
9
+ /* Brands a snippet payload so a `{expr}` interpolation mounts it instead of
10
+ inserting escaped text. The compiler wraps a snippet's body in this — the client
11
+ builder closes over the defining component's scope, the server string is its SSR
12
+ render — so a snippet value passes through props like any other value. */
13
+ // @readme plumbing
14
+ export function snippet<Payload>(payload: Payload): Snippet<Payload> {
15
+ return { [SNIPPET]: payload }
16
+ }
17
+
18
+ /* The payload of a snippet-branded value, or undefined for anything else — so a
19
+ text binding fast-paths plain values and only branded ones mount. The client
20
+ reads a builder function; the server reads the rendered string. */
21
+ export function snippetPayload(value: unknown): unknown {
22
+ return value !== null && typeof value === 'object' && SNIPPET in value
23
+ ? (value as Snippet<unknown>)[SNIPPET]
24
+ : undefined
25
+ }
@@ -0,0 +1,11 @@
1
+ /*
2
+ Translates a socket file path under `src/server/sockets/` into the socket's
3
+ identity used on the wire. The name is the file path minus `.ts` so
4
+ nested paths (e.g. `orders/new.ts`) become `orders/new`. Sockets don't
5
+ need a URL prefix the way rpc routes do — they multiplex over the
6
+ framework-owned `/__abide/sockets` ws and are dispatched by name in the
7
+ registry, not by HTTP path.
8
+ */
9
+ export function socketNameForFile(relativePath: string): string {
10
+ return relativePath.replace(/\.ts$/, '')
11
+ }
@@ -0,0 +1,12 @@
1
+ /*
2
+ Passive observation seam for published socket frames — the socket analogue of
3
+ logTapSlot. defineSocket's publish() calls the tap (when set) with every frame
4
+ it fans out, so an observer sees the same payloads subscribers receive. The
5
+ inspector installs one to fold socket traffic into its feed; unset everywhere
6
+ else, so the call no-ops. One slot, one in-process observer. Mirrors logTapSlot.
7
+ */
8
+ export const socketTapSlot: {
9
+ tap: ((frame: { socket: string; message: unknown }) => void) | undefined
10
+ } = {
11
+ tap: undefined,
12
+ }
@@ -0,0 +1,29 @@
1
+ /*
2
+ The in-band error sentinel for an SSE stream: when a handler's generator
3
+ throws, `sse()` emits an `event: error` frame whose data is `{ message }`,
4
+ and `streamResponse` re-throws it on the consumer side. Encoder and decoder
5
+ live together here so the sentinel (event name + payload shape) has one
6
+ definition and can't drift between the two ends of the wire.
7
+ */
8
+ export const sseErrorFrame = {
9
+ // Full `event: error` frame for a thrown message, including the SSE delimiters.
10
+ encode(message: string): string {
11
+ return `event: error\ndata: ${JSON.stringify({ message })}\n\n`
12
+ },
13
+ /*
14
+ The message carried by an error frame, or undefined when `event` isn't
15
+ the error sentinel. Falls back to the raw data when it isn't the JSON
16
+ the encoder produces.
17
+ */
18
+ decode(event: string, data: string): string | undefined {
19
+ if (event !== 'error') {
20
+ return undefined
21
+ }
22
+ try {
23
+ const decoded = JSON.parse(data) as { message?: string }
24
+ return decoded?.message ?? 'sse stream error'
25
+ } catch {
26
+ return data || 'sse stream error'
27
+ }
28
+ },
29
+ }