@plurnk/plurnk-service 1.0.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 (343) hide show
  1. package/.env.defaults +208 -0
  2. package/INSTALL.md +69 -0
  3. package/LICENSE +21 -0
  4. package/README.md +46 -0
  5. package/SPEC.md +1511 -0
  6. package/dist/Paths.d.ts +13 -0
  7. package/dist/Paths.d.ts.map +1 -0
  8. package/dist/Paths.js +60 -0
  9. package/dist/Paths.js.map +1 -0
  10. package/dist/content/edited-span.d.ts +2 -0
  11. package/dist/content/edited-span.d.ts.map +1 -0
  12. package/dist/content/edited-span.js +33 -0
  13. package/dist/content/edited-span.js.map +1 -0
  14. package/dist/content/index.d.ts +10 -0
  15. package/dist/content/index.d.ts.map +1 -0
  16. package/dist/content/index.js +11 -0
  17. package/dist/content/index.js.map +1 -0
  18. package/dist/content/line-marker.d.ts +15 -0
  19. package/dist/content/line-marker.d.ts.map +1 -0
  20. package/dist/content/line-marker.js +21 -0
  21. package/dist/content/line-marker.js.map +1 -0
  22. package/dist/content/matcher.d.ts +44 -0
  23. package/dist/content/matcher.d.ts.map +1 -0
  24. package/dist/content/matcher.js +126 -0
  25. package/dist/content/matcher.js.map +1 -0
  26. package/dist/content/mimetype-binary.d.ts +8 -0
  27. package/dist/content/mimetype-binary.d.ts.map +1 -0
  28. package/dist/content/mimetype-binary.js +17 -0
  29. package/dist/content/mimetype-binary.js.map +1 -0
  30. package/dist/content/path-mimetype.d.ts +5 -0
  31. package/dist/content/path-mimetype.d.ts.map +1 -0
  32. package/dist/content/path-mimetype.js +15 -0
  33. package/dist/content/path-mimetype.js.map +1 -0
  34. package/dist/content/read-resolve.d.ts +20 -0
  35. package/dist/content/read-resolve.d.ts.map +1 -0
  36. package/dist/content/read-resolve.js +68 -0
  37. package/dist/content/read-resolve.js.map +1 -0
  38. package/dist/core/ChannelWrite.d.ts +100 -0
  39. package/dist/core/ChannelWrite.d.ts.map +1 -0
  40. package/dist/core/ChannelWrite.js +112 -0
  41. package/dist/core/ChannelWrite.js.map +1 -0
  42. package/dist/core/ChannelWrite.sql +84 -0
  43. package/dist/core/Db.d.ts +14 -0
  44. package/dist/core/Db.d.ts.map +1 -0
  45. package/dist/core/Db.js +7 -0
  46. package/dist/core/Db.js.map +1 -0
  47. package/dist/core/Dispatcher.d.ts +67 -0
  48. package/dist/core/Dispatcher.d.ts.map +1 -0
  49. package/dist/core/Dispatcher.js +1021 -0
  50. package/dist/core/Dispatcher.js.map +1 -0
  51. package/dist/core/Engine.d.ts +113 -0
  52. package/dist/core/Engine.d.ts.map +1 -0
  53. package/dist/core/Engine.js +1410 -0
  54. package/dist/core/Engine.js.map +1 -0
  55. package/dist/core/Engine.sql +538 -0
  56. package/dist/core/EnvFlags.d.ts +13 -0
  57. package/dist/core/EnvFlags.d.ts.map +1 -0
  58. package/dist/core/EnvFlags.js +84 -0
  59. package/dist/core/EnvFlags.js.map +1 -0
  60. package/dist/core/ExecutorRegistry.d.ts +45 -0
  61. package/dist/core/ExecutorRegistry.d.ts.map +1 -0
  62. package/dist/core/ExecutorRegistry.js +128 -0
  63. package/dist/core/ExecutorRegistry.js.map +1 -0
  64. package/dist/core/PacketBuilder.d.ts +67 -0
  65. package/dist/core/PacketBuilder.d.ts.map +1 -0
  66. package/dist/core/PacketBuilder.js +524 -0
  67. package/dist/core/PacketBuilder.js.map +1 -0
  68. package/dist/core/PluginLoader.d.ts +17 -0
  69. package/dist/core/PluginLoader.d.ts.map +1 -0
  70. package/dist/core/PluginLoader.js +97 -0
  71. package/dist/core/PluginLoader.js.map +1 -0
  72. package/dist/core/ProposalLifecycle.d.ts +59 -0
  73. package/dist/core/ProposalLifecycle.d.ts.map +1 -0
  74. package/dist/core/ProposalLifecycle.js +215 -0
  75. package/dist/core/ProposalLifecycle.js.map +1 -0
  76. package/dist/core/ProviderInstantiate.d.ts +9 -0
  77. package/dist/core/ProviderInstantiate.d.ts.map +1 -0
  78. package/dist/core/ProviderInstantiate.js +156 -0
  79. package/dist/core/ProviderInstantiate.js.map +1 -0
  80. package/dist/core/SchemeRegistry.d.ts +26 -0
  81. package/dist/core/SchemeRegistry.d.ts.map +1 -0
  82. package/dist/core/SchemeRegistry.js +205 -0
  83. package/dist/core/SchemeRegistry.js.map +1 -0
  84. package/dist/core/StrikeRail.d.ts +28 -0
  85. package/dist/core/StrikeRail.d.ts.map +1 -0
  86. package/dist/core/StrikeRail.js +165 -0
  87. package/dist/core/StrikeRail.js.map +1 -0
  88. package/dist/core/TelemetryChannel.d.ts +37 -0
  89. package/dist/core/TelemetryChannel.d.ts.map +1 -0
  90. package/dist/core/TelemetryChannel.js +77 -0
  91. package/dist/core/TelemetryChannel.js.map +1 -0
  92. package/dist/core/TokenGauge.d.ts +16 -0
  93. package/dist/core/TokenGauge.d.ts.map +1 -0
  94. package/dist/core/TokenGauge.js +58 -0
  95. package/dist/core/TokenGauge.js.map +1 -0
  96. package/dist/core/caps/CapsResolve.d.ts +5 -0
  97. package/dist/core/caps/CapsResolve.d.ts.map +1 -0
  98. package/dist/core/caps/CapsResolve.js +13 -0
  99. package/dist/core/caps/CapsResolve.js.map +1 -0
  100. package/dist/core/caps/DbChannelCaps.d.ts +16 -0
  101. package/dist/core/caps/DbChannelCaps.d.ts.map +1 -0
  102. package/dist/core/caps/DbChannelCaps.js +41 -0
  103. package/dist/core/caps/DbChannelCaps.js.map +1 -0
  104. package/dist/core/caps/DbEntryCaps.d.ts +19 -0
  105. package/dist/core/caps/DbEntryCaps.d.ts.map +1 -0
  106. package/dist/core/caps/DbEntryCaps.js +28 -0
  107. package/dist/core/caps/DbEntryCaps.js.map +1 -0
  108. package/dist/core/caps/DbNotifyCaps.d.ts +8 -0
  109. package/dist/core/caps/DbNotifyCaps.d.ts.map +1 -0
  110. package/dist/core/caps/DbNotifyCaps.js +35 -0
  111. package/dist/core/caps/DbNotifyCaps.js.map +1 -0
  112. package/dist/core/caps/DbSubscriptionCaps.d.ts +10 -0
  113. package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -0
  114. package/dist/core/caps/DbSubscriptionCaps.js +86 -0
  115. package/dist/core/caps/DbSubscriptionCaps.js.map +1 -0
  116. package/dist/core/caps/DbTagCaps.d.ts +17 -0
  117. package/dist/core/caps/DbTagCaps.d.ts.map +1 -0
  118. package/dist/core/caps/DbTagCaps.js +37 -0
  119. package/dist/core/caps/DbTagCaps.js.map +1 -0
  120. package/dist/core/caps/SchemeCtxImpl.d.ts +18 -0
  121. package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -0
  122. package/dist/core/caps/SchemeCtxImpl.js +42 -0
  123. package/dist/core/caps/SchemeCtxImpl.js.map +1 -0
  124. package/dist/core/env-defaults.d.ts +19 -0
  125. package/dist/core/env-defaults.d.ts.map +1 -0
  126. package/dist/core/env-defaults.js +89 -0
  127. package/dist/core/env-defaults.js.map +1 -0
  128. package/dist/core/fork.d.ts +6 -0
  129. package/dist/core/fork.d.ts.map +1 -0
  130. package/dist/core/fork.js +84 -0
  131. package/dist/core/fork.js.map +1 -0
  132. package/dist/core/fork.sql +85 -0
  133. package/dist/core/git-membership.d.ts +23 -0
  134. package/dist/core/git-membership.d.ts.map +1 -0
  135. package/dist/core/git-membership.js +366 -0
  136. package/dist/core/git-membership.js.map +1 -0
  137. package/dist/core/git-state.d.ts +15 -0
  138. package/dist/core/git-state.d.ts.map +1 -0
  139. package/dist/core/git-state.js +67 -0
  140. package/dist/core/git-state.js.map +1 -0
  141. package/dist/core/packet-inject.d.ts +5 -0
  142. package/dist/core/packet-inject.d.ts.map +1 -0
  143. package/dist/core/packet-inject.js +48 -0
  144. package/dist/core/packet-inject.js.map +1 -0
  145. package/dist/core/packet-wire.d.ts +46 -0
  146. package/dist/core/packet-wire.d.ts.map +1 -0
  147. package/dist/core/packet-wire.js +453 -0
  148. package/dist/core/packet-wire.js.map +1 -0
  149. package/dist/core/path-decode.d.ts +2 -0
  150. package/dist/core/path-decode.d.ts.map +1 -0
  151. package/dist/core/path-decode.js +8 -0
  152. package/dist/core/path-decode.js.map +1 -0
  153. package/dist/core/plugin-attribution.d.ts +5 -0
  154. package/dist/core/plugin-attribution.d.ts.map +1 -0
  155. package/dist/core/plugin-attribution.js +39 -0
  156. package/dist/core/plugin-attribution.js.map +1 -0
  157. package/dist/core/plurnk-uri.d.ts +7 -0
  158. package/dist/core/plurnk-uri.d.ts.map +1 -0
  159. package/dist/core/plurnk-uri.js +52 -0
  160. package/dist/core/plurnk-uri.js.map +1 -0
  161. package/dist/core/resolveForLoop.d.ts +5 -0
  162. package/dist/core/resolveForLoop.d.ts.map +1 -0
  163. package/dist/core/resolveForLoop.js +12 -0
  164. package/dist/core/resolveForLoop.js.map +1 -0
  165. package/dist/core/results.d.ts +12 -0
  166. package/dist/core/results.d.ts.map +1 -0
  167. package/dist/core/results.js +27 -0
  168. package/dist/core/results.js.map +1 -0
  169. package/dist/core/run-cap.d.ts +8 -0
  170. package/dist/core/run-cap.d.ts.map +1 -0
  171. package/dist/core/run-cap.js +20 -0
  172. package/dist/core/run-cap.js.map +1 -0
  173. package/dist/core/run-ops.sql +43 -0
  174. package/dist/core/scheme-types.d.ts +45 -0
  175. package/dist/core/scheme-types.d.ts.map +1 -0
  176. package/dist/core/scheme-types.js +6 -0
  177. package/dist/core/scheme-types.js.map +1 -0
  178. package/dist/core/session-settings.d.ts +23 -0
  179. package/dist/core/session-settings.d.ts.map +1 -0
  180. package/dist/core/session-settings.js +55 -0
  181. package/dist/core/session-settings.js.map +1 -0
  182. package/dist/core/teaching.d.ts +3 -0
  183. package/dist/core/teaching.d.ts.map +1 -0
  184. package/dist/core/teaching.js +13 -0
  185. package/dist/core/teaching.js.map +1 -0
  186. package/dist/core/types.d.ts +3 -0
  187. package/dist/core/types.d.ts.map +1 -0
  188. package/dist/core/types.js +2 -0
  189. package/dist/core/types.js.map +1 -0
  190. package/dist/digest/Digest.d.ts +20 -0
  191. package/dist/digest/Digest.d.ts.map +1 -0
  192. package/dist/digest/Digest.js +451 -0
  193. package/dist/digest/Digest.js.map +1 -0
  194. package/dist/digest/Digest.sql +1 -0
  195. package/dist/digest/digest.sql +55 -0
  196. package/dist/index.d.ts +18 -0
  197. package/dist/index.d.ts.map +1 -0
  198. package/dist/index.js +28 -0
  199. package/dist/index.js.map +1 -0
  200. package/dist/schemes/EffectPolicy.d.ts +6 -0
  201. package/dist/schemes/EffectPolicy.d.ts.map +1 -0
  202. package/dist/schemes/EffectPolicy.js +18 -0
  203. package/dist/schemes/EffectPolicy.js.map +1 -0
  204. package/dist/schemes/Exec.d.ts +39 -0
  205. package/dist/schemes/Exec.d.ts.map +1 -0
  206. package/dist/schemes/Exec.js +510 -0
  207. package/dist/schemes/Exec.js.map +1 -0
  208. package/dist/schemes/ExecOutputScheme.d.ts +20 -0
  209. package/dist/schemes/ExecOutputScheme.d.ts.map +1 -0
  210. package/dist/schemes/ExecOutputScheme.js +39 -0
  211. package/dist/schemes/ExecOutputScheme.js.map +1 -0
  212. package/dist/schemes/File.d.ts +42 -0
  213. package/dist/schemes/File.d.ts.map +1 -0
  214. package/dist/schemes/File.js +356 -0
  215. package/dist/schemes/File.js.map +1 -0
  216. package/dist/schemes/Known.d.ts +17 -0
  217. package/dist/schemes/Known.d.ts.map +1 -0
  218. package/dist/schemes/Known.js +40 -0
  219. package/dist/schemes/Known.js.map +1 -0
  220. package/dist/schemes/Log.d.ts +22 -0
  221. package/dist/schemes/Log.d.ts.map +1 -0
  222. package/dist/schemes/Log.js +269 -0
  223. package/dist/schemes/Log.js.map +1 -0
  224. package/dist/schemes/Log.sql +59 -0
  225. package/dist/schemes/Plurnk.d.ts +17 -0
  226. package/dist/schemes/Plurnk.d.ts.map +1 -0
  227. package/dist/schemes/Plurnk.js +46 -0
  228. package/dist/schemes/Plurnk.js.map +1 -0
  229. package/dist/schemes/Run.d.ts +25 -0
  230. package/dist/schemes/Run.d.ts.map +1 -0
  231. package/dist/schemes/Run.js +172 -0
  232. package/dist/schemes/Run.js.map +1 -0
  233. package/dist/schemes/Skill.d.ts +17 -0
  234. package/dist/schemes/Skill.d.ts.map +1 -0
  235. package/dist/schemes/Skill.js +40 -0
  236. package/dist/schemes/Skill.js.map +1 -0
  237. package/dist/schemes/Unknown.d.ts +17 -0
  238. package/dist/schemes/Unknown.d.ts.map +1 -0
  239. package/dist/schemes/Unknown.js +39 -0
  240. package/dist/schemes/Unknown.js.map +1 -0
  241. package/dist/schemes/_entry-chunk.d.ts +11 -0
  242. package/dist/schemes/_entry-chunk.d.ts.map +1 -0
  243. package/dist/schemes/_entry-chunk.js +100 -0
  244. package/dist/schemes/_entry-chunk.js.map +1 -0
  245. package/dist/schemes/_entry-crud.d.ts +31 -0
  246. package/dist/schemes/_entry-crud.d.ts.map +1 -0
  247. package/dist/schemes/_entry-crud.js +77 -0
  248. package/dist/schemes/_entry-crud.js.map +1 -0
  249. package/dist/schemes/_entry-crud.sql +101 -0
  250. package/dist/schemes/_entry-find.d.ts +32 -0
  251. package/dist/schemes/_entry-find.d.ts.map +1 -0
  252. package/dist/schemes/_entry-find.js +226 -0
  253. package/dist/schemes/_entry-find.js.map +1 -0
  254. package/dist/schemes/_entry-find.sql +54 -0
  255. package/dist/schemes/_entry-graph.d.ts +16 -0
  256. package/dist/schemes/_entry-graph.d.ts.map +1 -0
  257. package/dist/schemes/_entry-graph.js +94 -0
  258. package/dist/schemes/_entry-graph.js.map +1 -0
  259. package/dist/schemes/_entry-graph.sql +52 -0
  260. package/dist/schemes/_entry-manifest.d.ts +25 -0
  261. package/dist/schemes/_entry-manifest.d.ts.map +1 -0
  262. package/dist/schemes/_entry-manifest.js +266 -0
  263. package/dist/schemes/_entry-manifest.js.map +1 -0
  264. package/dist/schemes/_entry-ops.d.ts +32 -0
  265. package/dist/schemes/_entry-ops.d.ts.map +1 -0
  266. package/dist/schemes/_entry-ops.js +216 -0
  267. package/dist/schemes/_entry-ops.js.map +1 -0
  268. package/dist/schemes/_entry-ops.sql +31 -0
  269. package/dist/schemes/_entry-semantic.d.ts +38 -0
  270. package/dist/schemes/_entry-semantic.d.ts.map +1 -0
  271. package/dist/schemes/_entry-semantic.js +202 -0
  272. package/dist/schemes/_entry-semantic.js.map +1 -0
  273. package/dist/schemes/_entry-semantic.sql +95 -0
  274. package/dist/schemes/_entry-send.d.ts +11 -0
  275. package/dist/schemes/_entry-send.d.ts.map +1 -0
  276. package/dist/schemes/_entry-send.js +66 -0
  277. package/dist/schemes/_entry-send.js.map +1 -0
  278. package/dist/schemes/cosine.d.ts +4 -0
  279. package/dist/schemes/cosine.d.ts.map +1 -0
  280. package/dist/schemes/cosine.js +9 -0
  281. package/dist/schemes/cosine.js.map +1 -0
  282. package/dist/schemes/exec-abort.d.ts +15 -0
  283. package/dist/schemes/exec-abort.d.ts.map +1 -0
  284. package/dist/schemes/exec-abort.js +29 -0
  285. package/dist/schemes/exec-abort.js.map +1 -0
  286. package/dist/schemes/exec-env.d.ts +5 -0
  287. package/dist/schemes/exec-env.d.ts.map +1 -0
  288. package/dist/schemes/exec-env.js +34 -0
  289. package/dist/schemes/exec-env.js.map +1 -0
  290. package/dist/server/Daemon.d.ts +244 -0
  291. package/dist/server/Daemon.d.ts.map +1 -0
  292. package/dist/server/Daemon.js +1119 -0
  293. package/dist/server/Daemon.js.map +1 -0
  294. package/dist/server/client-input.d.ts +11 -0
  295. package/dist/server/client-input.d.ts.map +1 -0
  296. package/dist/server/client-input.js +145 -0
  297. package/dist/server/client-input.js.map +1 -0
  298. package/dist/server/clientTurn.d.ts +6 -0
  299. package/dist/server/clientTurn.d.ts.map +1 -0
  300. package/dist/server/clientTurn.js +23 -0
  301. package/dist/server/clientTurn.js.map +1 -0
  302. package/dist/server/clientTurn.sql +10 -0
  303. package/dist/server/dispatch-as-plurnk.d.ts +7 -0
  304. package/dist/server/dispatch-as-plurnk.d.ts.map +1 -0
  305. package/dist/server/dispatch-as-plurnk.js +23 -0
  306. package/dist/server/dispatch-as-plurnk.js.map +1 -0
  307. package/dist/server/drain.sql +124 -0
  308. package/dist/server/envelope.d.ts +53 -0
  309. package/dist/server/envelope.d.ts.map +1 -0
  310. package/dist/server/envelope.js +172 -0
  311. package/dist/server/envelope.js.map +1 -0
  312. package/dist/server/envelope.sql +76 -0
  313. package/dist/server/logEntry.d.ts +35 -0
  314. package/dist/server/logEntry.d.ts.map +1 -0
  315. package/dist/server/logEntry.js +49 -0
  316. package/dist/server/logEntry.js.map +1 -0
  317. package/dist/server/logEntry.sql +10 -0
  318. package/dist/server/loopDocs.d.ts +6 -0
  319. package/dist/server/loopDocs.d.ts.map +1 -0
  320. package/dist/server/loopDocs.js +22 -0
  321. package/dist/server/loopDocs.js.map +1 -0
  322. package/dist/server/noProposals.d.ts +6 -0
  323. package/dist/server/noProposals.d.ts.map +1 -0
  324. package/dist/server/noProposals.js +37 -0
  325. package/dist/server/noProposals.js.map +1 -0
  326. package/dist/server/seam-entry-read.sql +21 -0
  327. package/dist/server/seam-log-read.sql +21 -0
  328. package/dist/server/seam-loop.sql +9 -0
  329. package/dist/server/seam-proposal-list.sql +13 -0
  330. package/dist/server/version-info.d.ts +14 -0
  331. package/dist/server/version-info.d.ts.map +1 -0
  332. package/dist/server/version-info.js +69 -0
  333. package/dist/server/version-info.js.map +1 -0
  334. package/dist/server/yolo.d.ts +6 -0
  335. package/dist/server/yolo.d.ts.map +1 -0
  336. package/dist/server/yolo.js +64 -0
  337. package/dist/server/yolo.js.map +1 -0
  338. package/dist/service.d.ts +6 -0
  339. package/dist/service.d.ts.map +1 -0
  340. package/dist/service.js +309 -0
  341. package/dist/service.js.map +1 -0
  342. package/migrations/0000-00-00.01_schema.sql +500 -0
  343. package/package.json +86 -0
@@ -0,0 +1,205 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import Plurnk from "../schemes/Plurnk.js";
10
+ import Log from "../schemes/Log.js";
11
+ import Exec from "../schemes/Exec.js";
12
+ import Known from "../schemes/Known.js";
13
+ import Unknown from "../schemes/Unknown.js";
14
+ import Skill from "../schemes/Skill.js";
15
+ import File from "../schemes/File.js";
16
+ import Run from "../schemes/Run.js";
17
+ import ResolveForLoop from "./resolveForLoop.js";
18
+ import { SchemeDiscovery } from "@plurnk/plurnk-schemes";
19
+ import PluginAttribution from "./plugin-attribution.js";
20
+ import ExecOutputScheme from "../schemes/ExecOutputScheme.js";
21
+ import { readdir, readFile } from "node:fs/promises";
22
+ import { resolve } from "node:path";
23
+ import Paths from "../Paths.js";
24
+ import { teachingLine, docsExcludeSet } from "./teaching.js";
25
+ // The in-tree CORE-scheme depth (run/known/unknown/log) lives in the docs corpus (docs/)
26
+ // (Paths.schemeDocs), NOT inline — the docs agent owns the prose; loaded once at module eval.
27
+ // teach()/docs() prefer this over a manifest's inline `documentation` (the path that stays for
28
+ // stubs + daughter schemes). Absent dir → empty map.
29
+ const SCHEME_DOCS = await (async () => {
30
+ try {
31
+ const files = (await readdir(Paths.schemeDocs)).filter((f) => f.endsWith(".md"));
32
+ const loaded = await Promise.all(files.map(async (f) => [f.slice(0, -3), await readFile(resolve(Paths.schemeDocs, f), "utf8")]));
33
+ return new Map(loaded);
34
+ }
35
+ catch {
36
+ return new Map();
37
+ }
38
+ })();
39
+ export default class SchemeRegistry {
40
+ // Heterogeneous handler store — in-tree schemes take PlurnkSchemeContext, external
41
+ // siblings the DB-free SchemeCtx of the imported SchemeHandler; the common supertype
42
+ // is `object`. Dispatch (Dispatcher.#run) borrows SchemeHandler's op-key set, not its ctx.
43
+ #handlers = new Map();
44
+ #external = new Set();
45
+ #attributions = []; // #249 — declared attribution tags of discovered external schemes
46
+ // §exec — runtime-tag schemes (sh/node/…) that ALIAS the exec handler for output-entry
47
+ // addressing (sh:///l/t/s). Routable via get(), but NOT separately taught or doc-materialized
48
+ // (exec is taught once); else the catalog + docs bloat by one redundant line/entry per tag.
49
+ #runtimeSchemes = new Set();
50
+ // #240 — built-in scheme names (captured at construction), reserved namespace-wide.
51
+ #reserved = new Set();
52
+ constructor() {
53
+ this.register("plurnk", new Plurnk());
54
+ this.register("log", new Log());
55
+ this.register("exec", new Exec());
56
+ this.register("known", new Known());
57
+ this.register("unknown", new Unknown());
58
+ this.register("skill", new Skill());
59
+ this.register("file", new File());
60
+ this.register("run", new Run());
61
+ // #240 — the in-tree names are RESERVED across the whole scheme namespace: a
62
+ // discovered executor or external scheme claiming one fails the boot hard, never
63
+ // silently shadowed. (exec stays poisoned-but-registered — the EXEC op + kill state.)
64
+ this.#reserved = new Set(this.#handlers.keys());
65
+ }
66
+ register(name, handler) {
67
+ if (this.#handlers.has(name))
68
+ throw new Error(`scheme '${name}' is already registered`);
69
+ this.#handlers.set(name, handler);
70
+ }
71
+ // §exec / #240 — exec OUTPUT entries address by their runtime TAG as authority
72
+ // (sh:///l/t/s). Register each discovered executor as its OWN per-tag scheme face
73
+ // (ExecOutputScheme): READ/FIND tag-scoped via the executor's manifest, process-KILL
74
+ // delegated to the shared Exec handler. Minted from the boot ExecutorRegistry; in-tree
75
+ // names take precedence (a tag shadowing a built-in is skipped, never overrides it).
76
+ registerRuntimeSchemes(executors) {
77
+ for (const tag of executors.availableRuntimes()) {
78
+ const entry = executors.entry(tag);
79
+ if (entry === undefined)
80
+ continue;
81
+ this.registerRuntimeScheme(tag, entry.executor);
82
+ }
83
+ }
84
+ // Register ONE executor tag's scheme face (the boot loop above + the #289 runtime hotload:
85
+ // an MCP server connected live becomes EXEC[<server>]). The reserved/cross-family arbitration
86
+ // lives HERE so both paths share it — one name, one owner across the exec/scheme families (#240):
87
+ // idempotent on a tag that already has its own runtime scheme (a boot re-scan), fail-hard on a
88
+ // collision with a reserved built-in or a DIFFERENT already-claimed scheme.
89
+ registerRuntimeScheme(tag, executor) {
90
+ const exec = this.#handlers.get("exec");
91
+ if (!(exec instanceof Exec))
92
+ throw new Error("registerRuntimeScheme: the exec handler is not registered");
93
+ if (this.#reserved.has(tag))
94
+ throw new Error(`executor tag '${tag}' collides with a reserved built-in scheme — fail-hard (#240)`);
95
+ if (this.#runtimeSchemes.has(tag))
96
+ return; // idempotent — already this tag's own runtime scheme
97
+ if (this.#handlers.has(tag))
98
+ throw new Error(`executor tag '${tag}' collides with an already-claimed scheme '${tag}' — one name, one owner across the exec/scheme families (#240)`);
99
+ this.register(tag, new ExecOutputScheme(executor, exec));
100
+ this.#runtimeSchemes.add(tag);
101
+ }
102
+ get(name) { return this.#handlers.get(name); }
103
+ has(name) { return this.#handlers.has(name); }
104
+ // True for schemes registered via discoverExternal — they receive the
105
+ // DB-free SchemeCtx (caps), not the in-tree PlurnkSchemeContext.
106
+ isExternal(name) { return this.#external.has(name); }
107
+ list() { return [...this.#handlers.keys()].toSorted(); }
108
+ // A scheme's default channel (manifest.defaultChannel) — the channel a fragment-less
109
+ // address targets. Drives the manifest's address-keyed channels (note 4); null → file (body).
110
+ defaultChannelFor(scheme) {
111
+ if (scheme === null)
112
+ return "body";
113
+ const manifest = this.#handlers.get(scheme)?.constructor?.manifest;
114
+ return manifest?.defaultChannel ?? "body";
115
+ }
116
+ // The scheme directory — the `schemes` packet section (below tools). grammar
117
+ // 0.49+ teaches grammar/dialects only, not the scheme set (grammar#239), so the
118
+ // service advertises what schemes exist at packet-time. Each handler that ships a
119
+ // `manifest.example` contributes ONE terse line — its canonical usage — plus a
120
+ // doc-link when it ships `manifest.documentation` (materialized at
121
+ // plurnk://docs/<name>.md by loop_run, READ on demand). The verbose semantics live
122
+ // in that pull doc, not here: terse pushes, depth pulls — exactly the exec tools
123
+ // sheet's shape (#collectTools). Insertion order; a scheme with no example
124
+ // (provisional, e.g. skill) is omitted. The doc's token cost rides its manifest entry.
125
+ teach() {
126
+ const lines = [];
127
+ const excluded = docsExcludeSet();
128
+ for (const [name, handler] of this.#handlers) {
129
+ if (this.#runtimeSchemes.has(name))
130
+ continue; // §exec — runtime aliases route, but exec is taught once
131
+ if (excluded.has(name))
132
+ continue; // #240 — PLURNK_SERVICE_DOCS_EXCLUDE drops the oneliner + the doc
133
+ const manifest = handler.constructor.manifest;
134
+ const example = manifest?.example;
135
+ if (typeof example !== "string" || example.length === 0)
136
+ continue;
137
+ lines.push(teachingLine(example)); // doc links removed (#270) — docs are FIND(plurnk://docs/**)-discovered
138
+ }
139
+ return lines.join("\n");
140
+ }
141
+ // #note12 — schemes that ship a `documentation` string, for materialization at
142
+ // plurnk:///docs/<name>.md. Optional + currently none in-tree; future-proofs the link.
143
+ docs() {
144
+ const out = [];
145
+ const excluded = docsExcludeSet();
146
+ for (const [name, handler] of this.#handlers) {
147
+ if (this.#runtimeSchemes.has(name))
148
+ continue; // §exec — runtime aliases share exec's doc, not their own
149
+ if (excluded.has(name))
150
+ continue; // #240 — PLURNK_SERVICE_DOCS_EXCLUDE drops the doc
151
+ const inline = handler.constructor.manifest?.documentation;
152
+ const content = SCHEME_DOCS.get(name) ?? (typeof inline === "string" && inline.length > 0 ? inline : undefined);
153
+ if (content !== undefined && content.length > 0)
154
+ out.push({ name, content });
155
+ }
156
+ return out;
157
+ }
158
+ // Plugin packet control (§packet-assembly): pipe the engine's default
159
+ // section list through every registered scheme that implements
160
+ // transformSections, in registration order. A scheme returns whatever list it
161
+ // wants — add, remove, reorder. The trusted in-process seam; the client wire
162
+ // never touches the packet. In-tree + external handlers both, duck-typed.
163
+ async transformSections(sections) {
164
+ let current = sections;
165
+ for (const handler of this.#handlers.values()) {
166
+ const transform = handler.transformSections;
167
+ if (typeof transform === "function")
168
+ current = await transform.call(handler, current);
169
+ }
170
+ return current;
171
+ }
172
+ // Discover external scheme siblings — delegated to the framework's SchemeDiscovery
173
+ // (schemes 0.9+): the scope-agnostic node_modules scan for plurnk.kind:"scheme" +
174
+ // plurnk.name AND the PLURNK_PLUGINS_TRUSTED_ONLY trust gate (untrusted → `skipped`,
175
+ // never crashed) both live there now, single-sourced across the plugin families
176
+ // (the "delegate upstream" rule — execs/mimetypes/providers already ship discover()).
177
+ // The service keeps only consumer policy: in-tree precedence (a name a built-in owns
178
+ // is left as-is) and importing + registering the trusted descriptors. A sibling reaches
179
+ // the substrate only through the DB-free SchemeCtx the engine wraps for isExternal() schemes.
180
+ async discoverExternal(cwd = process.cwd()) {
181
+ const { schemes, skipped } = await SchemeDiscovery.discover({ cwd });
182
+ for (const name of skipped) {
183
+ console.warn(`scheme discovery: '${name}' is discovered but untrusted (PLURNK_PLUGINS_TRUSTED_ONLY); not registered`);
184
+ }
185
+ for (const { name, packageName } of schemes) {
186
+ if (this.#reserved.has(name))
187
+ throw new Error(`external scheme '${name}' (${packageName}) collides with a reserved built-in — boot fail-hard (#240)`);
188
+ if (this.has(name))
189
+ continue; // idempotent re-scan
190
+ const mod = await import(__rewriteRelativeImportExtension(packageName));
191
+ this.register(name, new mod.default());
192
+ this.#external.add(name);
193
+ this.#attributions.push(...PluginAttribution.read(packageName)); // #249 — fail-hard if it claims @plurnk/
194
+ }
195
+ }
196
+ // #249 — declared attribution tags of the discovered external schemes (opaque; the
197
+ // engine unions these across plugin families onto the generate() `attributions` wire).
198
+ attributions() { return [...this.#attributions]; }
199
+ // Active set under the given loop flags (SPEC §engine-rails). Delegates to
200
+ // the in-tree ResolveForLoop utility.
201
+ resolveForLoop(flags) {
202
+ return ResolveForLoop.resolveForLoop(this.#handlers, flags);
203
+ }
204
+ }
205
+ //# sourceMappingURL=SchemeRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemeRegistry.js","sourceRoot":"","sources":["../../src/core/SchemeRegistry.ts"],"names":[],"mappings":";;;;;;;;AAAA,OAAO,MAAM,MAAM,sBAAsB,CAAC;AAC1C,OAAO,GAAG,MAAM,mBAAmB,CAAC;AACpC,OAAO,IAAI,MAAM,oBAAoB,CAAC;AACtC,OAAO,KAAK,MAAM,qBAAqB,CAAC;AACxC,OAAO,OAAO,MAAM,uBAAuB,CAAC;AAC5C,OAAO,KAAK,MAAM,qBAAqB,CAAC;AACxC,OAAO,IAAI,MAAM,oBAAoB,CAAC;AACtC,OAAO,GAAG,MAAM,mBAAmB,CAAC;AACpC,OAAO,cAAc,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,eAAe,EAAsB,MAAM,wBAAwB,CAAC;AAG7E,OAAO,iBAAiB,MAAM,yBAAyB,CAAC;AACxD,OAAO,gBAAgB,MAAM,gCAAgC,CAAC;AAG9D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,aAAa,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7D,yFAAyF;AACzF,8FAA8F;AAC9F,+FAA+F;AAC/F,qDAAqD;AACrD,MAAM,WAAW,GAAgC,MAAM,CAAC,KAAK,IAAI,EAAE;IAC/D,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACjF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAU,CAAC,CAAC,CAAC;QAC1I,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,GAAG,EAAE,CAAC;IAAC,CAAC;AACjC,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,CAAC,OAAO,OAAO,cAAc;IAC/B,mFAAmF;IACnF,qFAAqF;IACrF,2FAA2F;IAC3F,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,aAAa,GAAa,EAAE,CAAC,CAAC,kEAAkE;IAChG,uFAAuF;IACvF,8FAA8F;IAC9F,4FAA4F;IAC5F,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,oFAAoF;IACpF,SAAS,GAAwB,IAAI,GAAG,EAAE,CAAC;IAE3C;QACI,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAG,IAAI,MAAM,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAM,IAAI,GAAG,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAK,IAAI,IAAI,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAI,IAAI,KAAK,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,OAAO,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAI,IAAI,KAAK,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAK,IAAI,IAAI,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAM,IAAI,GAAG,EAAE,CAAC,CAAC;QACpC,6EAA6E;QAC7E,iFAAiF;QACjF,sFAAsF;QACtF,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,QAAQ,CAAC,IAAY,EAAE,OAAe;QAClC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,yBAAyB,CAAC,CAAC;QACxF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,+EAA+E;IAC/E,kFAAkF;IAClF,qFAAqF;IACrF,uFAAuF;IACvF,qFAAqF;IACrF,sBAAsB,CAAC,SAA2B;QAC9C,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,iBAAiB,EAAE,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAS;YAClC,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QACpD,CAAC;IACL,CAAC;IAED,2FAA2F;IAC3F,8FAA8F;IAC9F,kGAAkG;IAClG,+FAA+F;IAC/F,4EAA4E;IAC5E,qBAAqB,CAAC,GAAW,EAAE,QAAkB;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,CAAC,IAAI,YAAY,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC1G,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,GAAG,+DAA+D,CAAC,CAAC;QAClI,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,qDAAqD;QAChG,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,GAAG,8CAA8C,GAAG,gEAAgE,CAAC,CAAC;QACpL,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,IAAY,IAAwB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE1E,GAAG,CAAC,IAAY,IAAa,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE/D,sEAAsE;IACtE,iEAAiE;IACjE,UAAU,CAAC,IAAY,IAAa,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEtE,IAAI,KAAe,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAElE,qFAAqF;IACrF,8FAA8F;IAC9F,iBAAiB,CAAC,MAAqB;QACnC,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QACnC,MAAM,QAAQ,GAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,WAA0D,EAAE,QAAQ,CAAC;QACnH,OAAO,QAAQ,EAAE,cAAc,IAAI,MAAM,CAAC;IAC9C,CAAC;IAED,6EAA6E;IAC7E,gFAAgF;IAChF,kFAAkF;IAClF,+EAA+E;IAC/E,mEAAmE;IACnE,mFAAmF;IACnF,iFAAiF;IACjF,2EAA2E;IAC3E,uFAAuF;IACvF,KAAK;QACD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS,CAAC,yDAAyD;YACvG,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS,CAAC,kEAAkE;YACpG,MAAM,QAAQ,GAAI,OAAO,CAAC,WAA2E,CAAC,QAAQ,CAAC;YAC/G,MAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,CAAC;YAClC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAClE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,wEAAwE;QAC/G,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,+EAA+E;IAC/E,uFAAuF;IACvF,IAAI;QACA,MAAM,GAAG,GAA6C,EAAE,CAAC;QACzD,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS,CAAC,0DAA0D;YACxG,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS,CAAC,mDAAmD;YACrF,MAAM,MAAM,GAAI,OAAO,CAAC,WAAyD,CAAC,QAAQ,EAAE,aAAa,CAAC;YAC1G,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAChH,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED,sEAAsE;IACtE,+DAA+D;IAC/D,8EAA8E;IAC9E,6EAA6E;IAC7E,0EAA0E;IAC1E,KAAK,CAAC,iBAAiB,CAAC,QAAyB;QAC7C,IAAI,OAAO,GAAG,QAAQ,CAAC;QACvB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5C,MAAM,SAAS,GAAI,OAA6C,CAAC,iBAAiB,CAAC;YACnF,IAAI,OAAO,SAAS,KAAK,UAAU;gBAAE,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1F,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,mFAAmF;IACnF,kFAAkF;IAClF,qFAAqF;IACrF,gFAAgF;IAChF,sFAAsF;IACtF,qFAAqF;IACrF,wFAAwF;IACxF,8FAA8F;IAC9F,KAAK,CAAC,gBAAgB,CAAC,GAAG,GAAW,OAAO,CAAC,GAAG,EAAE;QAC9C,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACrE,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,sBAAsB,IAAI,6EAA6E,CAAC,CAAC;QAC1H,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,OAAO,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,MAAM,WAAW,6DAA6D,CAAC,CAAC;YACtJ,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS,CAAC,qBAAqB;YACnD,MAAM,GAAG,GAAG,MAAM,MAAM,kCAAC,WAAW,EAAyC,CAAC;YAC9E,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACvC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,yCAAyC;QAC9G,CAAC;IACL,CAAC;IAED,mFAAmF;IACnF,uFAAuF;IACvF,YAAY,KAAe,OAAO,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAE5D,2EAA2E;IAC3E,sCAAsC;IACtC,cAAc,CAAC,KAAgB;QAC3B,OAAO,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAChE,CAAC;CACJ"}
@@ -0,0 +1,28 @@
1
+ import type { PlurnkStatement } from "@plurnk/plurnk-grammar";
2
+ export default class StrikeRail {
3
+ #private;
4
+ static fingerprintTurn(ops: ReadonlyArray<PlurnkStatement>): string;
5
+ static detectCycle(history: ReadonlyArray<string>, minCycles: number, maxCyclePeriod: number): {
6
+ detected: false;
7
+ } | {
8
+ detected: true;
9
+ period: number;
10
+ cycles: number;
11
+ };
12
+ streak(loopId: number): number;
13
+ assess(loopId: number, turn: {
14
+ fingerprint: string;
15
+ statuses: ReadonlyArray<number>;
16
+ noOps: boolean;
17
+ budgetStruck: boolean;
18
+ steerStruck: boolean;
19
+ minCycles: number;
20
+ maxCyclePeriod: number;
21
+ maxStrikes: number;
22
+ }): {
23
+ cycleDetected: boolean;
24
+ thresholdCrossed: boolean;
25
+ };
26
+ delete(loopId: number): void;
27
+ }
28
+ //# sourceMappingURL=StrikeRail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StrikeRail.d.ts","sourceRoot":"","sources":["../../src/core/StrikeRail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAc,MAAM,wBAAwB,CAAC;AA8E1E,MAAM,CAAC,OAAO,OAAO,UAAU;;IAG3B,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,MAAM,CAElE;IAMD,MAAM,CAAC,WAAW,CACd,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GACvB;QAAE,QAAQ,EAAE,KAAK,CAAA;KAAE,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAe1E;IAYD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE7B;IAUD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAChC,KAAK,EAAE,OAAO,CAAC;QACf,YAAY,EAAE,OAAO,CAAC;QACtB,WAAW,EAAE,OAAO,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;KACtB,GAAG;QAAE,aAAa,EAAE,OAAO,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAA;KAAE,CA4BxD;IAED,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE3B;CACJ"}
@@ -0,0 +1,165 @@
1
+ // Rail #38: action-entry statuses that DON'T accumulate strikes. Model adapted
2
+ // to a finding (not_found, op_not_supported); no penalty. Rummy parallel:
3
+ // SOFT_FAILURE_OUTCOMES = {"not_found", "unparsed"}.
4
+ // Exploratory misses are not failures: probing a path that doesn't exist (404), a line
5
+ // range that doesn't exist (416), or a capability a scheme lacks (501) is how discovery
6
+ // works — striking them prices caution into the motions we most want (range-reads ARE
7
+ // the surgical behavior under budget pressure). One simple set, evenly applied.
8
+ // 409 (premature-terminate refusal) is SOFT here: whether it strikes is decided by steerStruck
9
+ // (Engine sets it true for a stream/child refusal — discarding live work IS serious — and false
10
+ // for a retrievals-only refusal, which teaches without striking, §send-premature-terminate/#346).
11
+ // Counting the raw 409 status ALSO would double-strike the stream/child case and WRONGLY strike
12
+ // the retrieval-only case (a cloud atomic-turn model repeating read+conclude struck out 500 on
13
+ // firefast despite the ruling). The cycle detector remains the backstop for a genuinely-spinning
14
+ // model (508 loop-detected — the honest signal, not a 500 failure).
15
+ const SOFT_FAILURE_STATUSES = new Set([404, 409, 416, 501]);
16
+ // Per-op fingerprint: op verb + target URI, plus an op-specific discriminator
17
+ // where the activity isn't fully captured by target alone:
18
+ // - EDIT/COPY/MOVE: body excluded — re-writing the same target with varied
19
+ // content IS cycling (the model is producing different versions of the
20
+ // same artifact instead of progressing).
21
+ // - FIND/READ/OPEN/FOLD: body IS the search/selection pattern; varied
22
+ // matchers on the same target ARE different activities (the model is
23
+ // exploring different queries, not repeating one).
24
+ const fingerprintOp = (stmt) => {
25
+ const path = stmt.target;
26
+ const matcherDiscriminator = () => {
27
+ // For matcher-bearing ops, the body's `raw` (matcher source) plus
28
+ // any lineMarker forms the activity discriminator.
29
+ const parts = [];
30
+ const body = stmt.body;
31
+ if (body !== null && typeof body === "object" && typeof body.raw === "string") {
32
+ parts.push(`body:${body.raw.slice(0, 64)}`);
33
+ }
34
+ const lm = stmt.lineMarker;
35
+ if (lm !== null && lm !== undefined)
36
+ parts.push(`L:${lm.marks.join(",")}`);
37
+ return parts.length > 0 ? `|${parts.join("|")}` : "";
38
+ };
39
+ if (path === null) {
40
+ // Path-less ops need an activity-defining discriminator other
41
+ // than `target`. Picked per op so the cycle detector reflects
42
+ // intent rather than syntax:
43
+ // - EXEC: the command body IS the activity. Without a body
44
+ // digest, varied shell commands (find / ls / wc) collapse to
45
+ // one fingerprint and the detector mislabels exploration
46
+ // as a loop.
47
+ // - SEND: the status code (signal) IS the activity. Different
48
+ // SEND[X] are different intentions; same SEND[X] with
49
+ // different message bodies is the same termination signal.
50
+ if (stmt.op === "EXEC") {
51
+ const body = typeof stmt.body === "string" ? stmt.body : "";
52
+ return `EXEC|(no-path)${body.length > 0 ? `|body:${body.slice(0, 64)}` : ""}`;
53
+ }
54
+ if (stmt.op === "SEND") {
55
+ const signal = typeof stmt.signal === "number" ? stmt.signal : "";
56
+ return `SEND|(no-path)|signal:${signal}`;
57
+ }
58
+ return `${stmt.op}|(no-path)`;
59
+ }
60
+ const base = path.kind === "url"
61
+ ? `${stmt.op}|${path.scheme}://${path.pathname}`
62
+ : `${stmt.op}|local:${path.raw}`;
63
+ if (stmt.op === "FIND" || stmt.op === "READ" || stmt.op === "OPEN" || stmt.op === "FOLD") {
64
+ return `${base}${matcherDiscriminator()}`;
65
+ }
66
+ return base;
67
+ };
68
+ // Rails #38 (strikes) + #39 (cycle detection): the per-loop failure-streak
69
+ // accounting that decides abandonment. Strike accounting is engine-internal
70
+ // bookkeeping. Per rummy precedent (plugins/error/error.js#verdict) and SPEC
71
+ // §telemetry policy: model sees errors that happened (parse_error,
72
+ // action_failure), never the engine's accounting about them (strike counts,
73
+ // cycle detection, sudden-death threshold). Surfacing internal state to the
74
+ // model creates a gamification surface — model optimizes for engine metrics
75
+ // rather than task progress.
76
+ export default class StrikeRail {
77
+ // Per-turn fingerprint: sorted set of per-op fingerprints, joined. Order
78
+ // within a turn doesn't matter — we want the SET of activities.
79
+ static fingerprintTurn(ops) {
80
+ return ops.map(fingerprintOp).toSorted().join(",");
81
+ }
82
+ // Rail #39 cycle detector. For each candidate period k in [1, maxCyclePeriod],
83
+ // check whether the last k*minCycles entries form minCycles repetitions of the
84
+ // same length-k pattern. O(maxCyclePeriod × minCycles × max k) ≈ tiny. Rummy
85
+ // parallel: src/plugins/error/error.js detectCycle.
86
+ static detectCycle(history, minCycles, maxCyclePeriod) {
87
+ for (let k = 1; k <= maxCyclePeriod; k++) {
88
+ const needed = k * minCycles;
89
+ if (history.length < needed)
90
+ continue;
91
+ const tail = history.slice(-needed);
92
+ const cycle = tail.slice(0, k);
93
+ let match = true;
94
+ outer: for (let rep = 0; rep < minCycles; rep++) {
95
+ for (let j = 0; j < k; j++) {
96
+ if (tail[rep * k + j] !== cycle[j]) {
97
+ match = false;
98
+ break outer;
99
+ }
100
+ }
101
+ }
102
+ if (match)
103
+ return { detected: true, period: k, cycles: minCycles };
104
+ }
105
+ return { detected: false };
106
+ }
107
+ // Rail #38 strike state per loop. `streak` = consecutive struck turns;
108
+ // resets on a clean turn. `turnErrors` is bumped by per-turn rails (cycle
109
+ // detection #39, grinder, steer) — read and reset at end of each turn.
110
+ // `history` holds per-turn fingerprints for rail #39 cycle detection.
111
+ #state = new Map();
112
+ // The loop's CURRENT strike streak — the same figure the 500-threshold compares. Rides
113
+ // generate({strikes}) as first-party outbound metadata (Plurnk-Strikes, #313): the hosted
114
+ // router's escalation signal. NEVER model-facing (§engine-rails — a surfaced count is a
115
+ // metric to game); the packet does not carry it.
116
+ streak(loopId) {
117
+ return this.#state.get(loopId)?.streak ?? 0;
118
+ }
119
+ // Per-turn strike accounting, run by runLoop after every turn. Three
120
+ // sources strike a turn:
121
+ // 1. recordedFailed — any action-entry at hard failure status
122
+ // (>= 400 and not in SOFT_FAILURE_STATUSES).
123
+ // 2. noOps — the turn emitted no ops at all (per #41).
124
+ // 3. turnErrors — bumped by per-turn rails (#39 cycle, grinder, steer).
125
+ // Struck → streak++; clean → streak = 0. Threshold → thresholdCrossed,
126
+ // and runLoop owns the abandonment.
127
+ assess(loopId, turn) {
128
+ // Rail #39: cycle detection. Push this turn's fingerprint to
129
+ // history, scan for repetition patterns. Detection bumps
130
+ // turnErrors so the strike system handles abandonment
131
+ // naturally — same internal-only role rummy gave it
132
+ // (plugins/error/error.js#verdict). Intentionally NOT a
133
+ // model-facing telemetry kind: model sees the strike pile-up
134
+ // (which IS the actionable signal); cycle is the engine's
135
+ // reason for treating the turn as a failure, not its own alert.
136
+ const state = this.#state.get(loopId) ?? { streak: 0, turnErrors: 0, history: [] };
137
+ state.history.push(turn.fingerprint);
138
+ const cycle = StrikeRail.detectCycle(state.history, turn.minCycles, turn.maxCyclePeriod);
139
+ if (cycle.detected)
140
+ state.turnErrors++;
141
+ // SPEC §grinder: a non-soft grinder fire counts toward the strike streak.
142
+ if (turn.budgetStruck)
143
+ state.turnErrors++; // a grinder fire bumps the strike streak — §grinder-strike-coupling
144
+ if (turn.steerStruck)
145
+ state.turnErrors++; // idle / premature-terminate steer struck — §send the terminal contract
146
+ const recordedFailed = turn.statuses.some((s) => s >= 400 && !SOFT_FAILURE_STATUSES.has(s));
147
+ const struck = turn.noOps || recordedFailed || state.turnErrors > 0;
148
+ let thresholdCrossed = false;
149
+ if (struck) {
150
+ state.streak++;
151
+ if (state.streak >= turn.maxStrikes)
152
+ thresholdCrossed = true;
153
+ }
154
+ else {
155
+ state.streak = 0;
156
+ }
157
+ state.turnErrors = 0;
158
+ this.#state.set(loopId, state);
159
+ return { cycleDetected: cycle.detected, thresholdCrossed };
160
+ }
161
+ delete(loopId) {
162
+ this.#state.delete(loopId);
163
+ }
164
+ }
165
+ //# sourceMappingURL=StrikeRail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StrikeRail.js","sourceRoot":"","sources":["../../src/core/StrikeRail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { TelemetryEvent } from "@plurnk/plurnk-grammar";
2
+ import type { Db } from "./Db.ts";
3
+ import type { TelemetryEventNotify } from "./ChannelWrite.ts";
4
+ declare const ENGINE_ERRORS: Readonly<{
5
+ readonly budget_overflow: {
6
+ readonly status: 413;
7
+ readonly term: "Budget Overflow: newest log items automatically FOLDed — a retrieval larger than Tokens Free arrives folded; FOLD older items first, then fetch within the room made";
8
+ };
9
+ readonly max_commands_exceeded: {
10
+ readonly status: 429;
11
+ readonly term: "Max Commands Exceeded";
12
+ };
13
+ readonly idle_turn: {
14
+ readonly status: 409;
15
+ readonly term: "Idle Turn — this turn delivered no new work; act on something pending, deliver a result, or conclude ([200]) / abandon ([499])";
16
+ };
17
+ }>;
18
+ export type EngineErrorKind = keyof typeof ENGINE_ERRORS;
19
+ export default class TelemetryChannel {
20
+ #private;
21
+ constructor({ db, notify }: {
22
+ db: Db;
23
+ notify?: TelemetryEventNotify;
24
+ });
25
+ push(sessionId: number, loopId: number, event: TelemetryEvent): void;
26
+ notify(sessionId: number, loopId: number, event: TelemetryEvent): void;
27
+ drain(loopId: number): object[];
28
+ delete(loopId: number): void;
29
+ mintEngineError(kind: EngineErrorKind, { runId, loopId, turnId, sequence }: {
30
+ runId: number;
31
+ loopId: number;
32
+ turnId: number;
33
+ sequence: number;
34
+ }): Promise<void>;
35
+ }
36
+ export {};
37
+ //# sourceMappingURL=TelemetryChannel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TelemetryChannel.d.ts","sourceRoot":"","sources":["../../src/core/TelemetryChannel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAM9D,QAAA,MAAM,aAAa;;iBACI,MAAM,EAAE,GAAG;iBAAE,IAAI,EAAE,sKAAsK;;;iBACnL,MAAM,EAAE,GAAG;iBAAE,IAAI,EAAE,uBAAuB;;;iBAItD,MAAM,EAAE,GAAG;iBAAE,IAAI,EAAE,gIAAgI;;EACzJ,CAAC;AACZ,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,aAAa,CAAC;AAKzD,MAAM,CAAC,OAAO,OAAO,gBAAgB;;IAajC,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE;QAAE,EAAE,EAAE,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,oBAAoB,CAAA;KAAE,EAGpE;IAED,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAQnE;IAID,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAErE;IAGD,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAK9B;IAED,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE3B;IAMK,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAYpK;CACJ"}
@@ -0,0 +1,77 @@
1
+ // §telemetry — the uniform error channel. Every engine failure is a terse op='error'
2
+ // log row: a status code + the canonical term, no prose (the packet teaches recovery).
3
+ // Each surfaces as a LogCoordinate TelemetryEvent derived from log≥400 — one channel,
4
+ // no per-kind handling. {§telemetry-uniform-error-channel}
5
+ const ENGINE_ERRORS = Object.freeze({
6
+ budget_overflow: { status: 413, term: "Budget Overflow: newest log items automatically FOLDed — a retrieval larger than Tokens Free arrives folded; FOLD older items first, then fetch within the room made" },
7
+ max_commands_exceeded: { status: 429, term: "Max Commands Exceeded" },
8
+ // premature-terminate is NOT a terse engine-error: it's a SEND op-result (409 + an actionable
9
+ // outcome, §send-premature-terminate) — the SEND row records the [200] attempt faithfully and
10
+ // auto-surfaces (status≥400) like any op failure, never an erasure to 102.
11
+ idle_turn: { status: 409, term: "Idle Turn — this turn delivered no new work; act on something pending, deliver a result, or conclude ([200]) / abandon ([499])" },
12
+ });
13
+ // The model-facing alert channel: a per-loop transient buffer of actionless failures
14
+ // pending surface in the NEXT packet's user.telemetry.errors[], plus the live client
15
+ // fan-out and the uniform op='error' log-row mint. SPEC §telemetry.
16
+ export default class TelemetryChannel {
17
+ #db;
18
+ // Per-loop transient buffer of actionless failures pending surface in the
19
+ // NEXT packet's user.telemetry.errors[]. Drained by PacketBuilder.buildTelemetryErrors.
20
+ // Map<loopId, TelemetryError[]>. SPEC §telemetry.
21
+ #buffer = new Map();
22
+ // Telemetry event fan-out: every TelemetryEvent pushed to the loop's
23
+ // buffer is also broadcast live to the connected client(s) on the
24
+ // session. Without this, the client sees `loop/terminated` with a
25
+ // status code but has no way to surface why the loop degraded.
26
+ // Per-grammar 0.17.0 protocol — see SPEC §telemetry.
27
+ #notify;
28
+ constructor({ db, notify }) {
29
+ this.#db = db;
30
+ this.#notify = notify;
31
+ }
32
+ push(sessionId, loopId, event) {
33
+ const existing = this.#buffer.get(loopId);
34
+ if (existing === undefined)
35
+ this.#buffer.set(loopId, [event]);
36
+ else
37
+ existing.push(event);
38
+ // Live fan-out: client sees the event the moment it lands in the
39
+ // model's buffer (not at the next packet build). Same envelope on
40
+ // both sides per the grammar 0.17.0 TelemetryEvent protocol.
41
+ this.#notify?.(sessionId, { loopId, event });
42
+ }
43
+ // Live fan-out ONLY, never buffered — for work with no loop to drain the
44
+ // buffer (e.g. session-scope derivation warming, loopId 0).
45
+ notify(sessionId, loopId, event) {
46
+ this.#notify?.(sessionId, { loopId, event });
47
+ }
48
+ // Telemetry drains as it's read into the packet — each event surfaces once. §telemetry-drain-on-read
49
+ drain(loopId) {
50
+ const buf = this.#buffer.get(loopId);
51
+ if (buf === undefined)
52
+ return [];
53
+ this.#buffer.delete(loopId);
54
+ return buf;
55
+ }
56
+ delete(loopId) {
57
+ this.#buffer.delete(loopId);
58
+ }
59
+ // Mint an engine failure as a uniform op='error' log row (§telemetry-uniform-error-channel):
60
+ // a terse status + canonical term keyed by `kind` (the packet teaches recovery, not the row),
61
+ // origin engine:rail. The errors section derives its LogCoordinate pointer from log≥400 — one
62
+ // channel, no per-kind handling.
63
+ async mintEngineError(kind, { runId, loopId, turnId, sequence }) {
64
+ const { status, term } = ENGINE_ERRORS[kind];
65
+ await this.#db.engine_insert_log_entry.get({
66
+ run_id: runId, loop_id: loopId, turn_id: turnId, sequence,
67
+ origin: "plurnk", source: "rail", op: "error", suffix: "", signal: null,
68
+ scheme: null, username: null, password: null, hostname: null, port: null,
69
+ pathname: null, params: null, fragment: null, lineMarker: null,
70
+ tx: "", mimetype_tx: "text/plain",
71
+ rx: JSON.stringify({ kind, message: term }),
72
+ mimetype_rx: "application/json",
73
+ status_rx: status, tokens: 0, state: "resolved", outcome: null, attrs: "{}",
74
+ });
75
+ }
76
+ }
77
+ //# sourceMappingURL=TelemetryChannel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TelemetryChannel.js","sourceRoot":"","sources":["../../src/core/TelemetryChannel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Mimetypes } from "@plurnk/plurnk-mimetypes";
2
+ import type { Provider } from "@plurnk/plurnk-providers";
3
+ import type { Db } from "./Db.ts";
4
+ import type { TelemetryEvent } from "@plurnk/plurnk-grammar";
5
+ export interface GaugeResolution {
6
+ tokenizerId: string;
7
+ exact: boolean;
8
+ count: (text: string) => Promise<number>;
9
+ }
10
+ export default class TokenGauge {
11
+ #private;
12
+ static contentHash(content: string): string;
13
+ static resolve(mimetypes: Mimetypes | undefined, provider: Provider, pushTelemetry?: (e: TelemetryEvent) => void): Promise<GaugeResolution>;
14
+ static tokensFor(db: Db, gauge: GaugeResolution, contentHash: string, content: string): Promise<number>;
15
+ }
16
+ //# sourceMappingURL=TokenGauge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenGauge.d.ts","sourceRoot":"","sources":["../../src/core/TokenGauge.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5C;AAED,MAAM,CAAC,OAAO,OAAO,UAAU;;IAI3B,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1C;IAQD,OAAa,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAsBhJ;IAID,OAAa,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAM5G;CACJ"}