keating 0.3.6

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 (249) hide show
  1. package/README.md +334 -0
  2. package/SYSTEM.md +33 -0
  3. package/bin/keating.js +31 -0
  4. package/dist/src/cli/main.js +357 -0
  5. package/dist/src/cli/setup.js +197 -0
  6. package/dist/src/cli/web.js +84 -0
  7. package/dist/src/core/animation.js +304 -0
  8. package/dist/src/core/ax-optimizer.js +81 -0
  9. package/dist/src/core/ax-prompt-learner.js +59 -0
  10. package/dist/src/core/ax-trial.js +181 -0
  11. package/dist/src/core/benchmark.js +253 -0
  12. package/dist/src/core/commands.js +57 -0
  13. package/dist/src/core/config.js +120 -0
  14. package/dist/src/core/engagement.js +235 -0
  15. package/dist/src/core/env.js +9 -0
  16. package/dist/src/core/evolution.js +242 -0
  17. package/dist/src/core/flashcards.js +133 -0
  18. package/dist/src/core/learner-state.js +108 -0
  19. package/dist/src/core/lesson-plan.js +155 -0
  20. package/dist/src/core/map-elites.js +228 -0
  21. package/dist/src/core/map.js +89 -0
  22. package/dist/src/core/mastery.js +207 -0
  23. package/dist/src/core/paths.js +100 -0
  24. package/dist/src/core/pi-agent.js +82 -0
  25. package/dist/src/core/policy.js +79 -0
  26. package/dist/src/core/project.js +337 -0
  27. package/dist/src/core/projects.js +281 -0
  28. package/dist/src/core/prompt-evolution.js +344 -0
  29. package/dist/src/core/quiz.js +194 -0
  30. package/dist/src/core/random.js +19 -0
  31. package/dist/src/core/self-improve.js +425 -0
  32. package/dist/src/core/speech.js +54 -0
  33. package/dist/src/core/terminal.js +117 -0
  34. package/dist/src/core/theme.js +101 -0
  35. package/dist/src/core/topics.js +620 -0
  36. package/dist/src/core/types.js +1 -0
  37. package/dist/src/core/util.js +30 -0
  38. package/dist/src/core/verification.js +162 -0
  39. package/dist/src/pi/hyperteacher-extension.js +573 -0
  40. package/dist/src/runtime/pi.js +343 -0
  41. package/package.json +78 -0
  42. package/pi/prompts/bridge.md +14 -0
  43. package/pi/prompts/diagnose.md +15 -0
  44. package/pi/prompts/improve.md +39 -0
  45. package/pi/prompts/learn.md +21 -0
  46. package/pi/prompts/quiz.md +14 -0
  47. package/pi/skills/adaptive-teaching/SKILL.md +33 -0
  48. package/scripts/install/install.sh +308 -0
  49. package/web/dist/.well-known/llms.txt +44 -0
  50. package/web/dist/apple-touch-icon.svg +10 -0
  51. package/web/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  52. package/web/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  53. package/web/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  54. package/web/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  55. package/web/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  56. package/web/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  57. package/web/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  58. package/web/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  59. package/web/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  60. package/web/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  61. package/web/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  62. package/web/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  63. package/web/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  64. package/web/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  65. package/web/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  66. package/web/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  67. package/web/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  68. package/web/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  69. package/web/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  70. package/web/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  71. package/web/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  72. package/web/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  73. package/web/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  74. package/web/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  75. package/web/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  76. package/web/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  77. package/web/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  78. package/web/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  79. package/web/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  80. package/web/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  81. package/web/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  82. package/web/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  83. package/web/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  84. package/web/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  85. package/web/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  86. package/web/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  87. package/web/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  88. package/web/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  89. package/web/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  90. package/web/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  91. package/web/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  92. package/web/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  93. package/web/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  94. package/web/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  95. package/web/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  96. package/web/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  97. package/web/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  98. package/web/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  99. package/web/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  100. package/web/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  101. package/web/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  102. package/web/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  103. package/web/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  104. package/web/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  105. package/web/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  106. package/web/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  107. package/web/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  108. package/web/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  109. package/web/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  110. package/web/dist/assets/_baseFor-B_cjfMB6.js +1 -0
  111. package/web/dist/assets/anthropic-BT6Vfzb1.js +36 -0
  112. package/web/dist/assets/arc-x2nTilpc.js +1 -0
  113. package/web/dist/assets/architecture-YZFGNWBL-B1hlUWjX.js +1 -0
  114. package/web/dist/assets/architectureDiagram-Q4EWVU46-CMApWFyw.js +36 -0
  115. package/web/dist/assets/array-B9UHiPd-.js +1 -0
  116. package/web/dist/assets/azure-openai-responses-CommX3YJ.js +1 -0
  117. package/web/dist/assets/blockDiagram-DXYQGD6D-DOQbsNRY.js +132 -0
  118. package/web/dist/assets/c4Diagram-AHTNJAMY-VFfRZWWA.js +10 -0
  119. package/web/dist/assets/channel-KY2Tg8Ba.js +1 -0
  120. package/web/dist/assets/chunk-2KRD3SAO-B-AqvS0u.js +1 -0
  121. package/web/dist/assets/chunk-336JU56O-DlYgPyl6.js +2 -0
  122. package/web/dist/assets/chunk-426QAEUC-CsVoBkfR.js +1 -0
  123. package/web/dist/assets/chunk-4BX2VUAB-0Z13aFAn.js +1 -0
  124. package/web/dist/assets/chunk-4TB4RGXK-DqC0Zwm7.js +206 -0
  125. package/web/dist/assets/chunk-55IACEB6-CWE_u-IY.js +1 -0
  126. package/web/dist/assets/chunk-5FUZZQ4R-CApli0xX.js +62 -0
  127. package/web/dist/assets/chunk-5PVQY5BW-Cbzhfhln.js +2 -0
  128. package/web/dist/assets/chunk-67CJDMHE-Cx7uJS4d.js +1 -0
  129. package/web/dist/assets/chunk-7N4EOEYR-CYPNsFus.js +1 -0
  130. package/web/dist/assets/chunk-AA7GKIK3-rU0uhR_u.js +1 -0
  131. package/web/dist/assets/chunk-BSJP7CBP-5VmcfR4-.js +1 -0
  132. package/web/dist/assets/chunk-Bj-mKKzh.js +1 -0
  133. package/web/dist/assets/chunk-CIAEETIT-CHJ-L8H1.js +1 -0
  134. package/web/dist/assets/chunk-EDXVE4YY-DZHAJjMI.js +1 -0
  135. package/web/dist/assets/chunk-ENJZ2VHE-DbUDFa7w.js +10 -0
  136. package/web/dist/assets/chunk-FMBD7UC4-BsYE5e_h.js +15 -0
  137. package/web/dist/assets/chunk-FOC6F5B3-Cm6aoTv7.js +1 -0
  138. package/web/dist/assets/chunk-ICPOFSXX-C5eNZ4L6.js +123 -0
  139. package/web/dist/assets/chunk-K5T4RW27-R7dAJ4rq.js +94 -0
  140. package/web/dist/assets/chunk-KGLVRYIC-MO99YZXL.js +1 -0
  141. package/web/dist/assets/chunk-LIHQZDEY-DUJ656sT.js +1 -0
  142. package/web/dist/assets/chunk-ORNJ4GCN-DXuuEC1n.js +1 -0
  143. package/web/dist/assets/chunk-OYMX7WX6-pJlEprWq.js +231 -0
  144. package/web/dist/assets/chunk-QZHKN3VN-_pQxbbiW.js +1 -0
  145. package/web/dist/assets/chunk-U2HBQHQK-Mh_l9PLe.js +70 -0
  146. package/web/dist/assets/chunk-X2U36JSP-BOeiJW0w.js +1 -0
  147. package/web/dist/assets/chunk-XPW4576I-fQ9SDvr_.js +32 -0
  148. package/web/dist/assets/chunk-YZCP3GAM-eboO4P5S.js +1 -0
  149. package/web/dist/assets/chunk-ZZ45TVLE-Cky0eqlr.js +1 -0
  150. package/web/dist/assets/classDiagram-6PBFFD2Q-DEPsZSU3.js +1 -0
  151. package/web/dist/assets/classDiagram-v2-HSJHXN6E-DhmIOEpX.js +1 -0
  152. package/web/dist/assets/clone-DeTzYqo8.js +1 -0
  153. package/web/dist/assets/cose-bilkent-S5V4N54A-N4zWUJ7C.js +1 -0
  154. package/web/dist/assets/cytoscape.esm-BBMd0vGm.js +321 -0
  155. package/web/dist/assets/dagre-IpK1aoMm.js +1 -0
  156. package/web/dist/assets/dagre-KV5264BT-DCytJuju.js +4 -0
  157. package/web/dist/assets/defaultLocale-5eAKkKJC.js +1 -0
  158. package/web/dist/assets/diagram-5BDNPKRD-Cv4miBae.js +10 -0
  159. package/web/dist/assets/diagram-G4DWMVQ6-CtICKUFi.js +24 -0
  160. package/web/dist/assets/diagram-MMDJMWI5-Cn7aGorh.js +43 -0
  161. package/web/dist/assets/diagram-TYMM5635-CCUWDPsC.js +24 -0
  162. package/web/dist/assets/dist-Dm98VvTW.js +1 -0
  163. package/web/dist/assets/env-api-keys-BNlMKqxw.js +1 -0
  164. package/web/dist/assets/erDiagram-SMLLAGMA-uT88sBlT.js +85 -0
  165. package/web/dist/assets/event-stream-D33K9rpL.js +1 -0
  166. package/web/dist/assets/flatten-C-u5nd5-.js +1 -0
  167. package/web/dist/assets/flowDiagram-DWJPFMVM-Bl3O7S1m.js +162 -0
  168. package/web/dist/assets/ganttDiagram-T4ZO3ILL-B1FhwV45.js +292 -0
  169. package/web/dist/assets/gitGraph-7Q5UKJZL-Bc_7vzer.js +1 -0
  170. package/web/dist/assets/gitGraphDiagram-UUTBAWPF-DfW6svMS.js +106 -0
  171. package/web/dist/assets/github-copilot-headers-L39QqneT.js +1 -0
  172. package/web/dist/assets/google-BdYNeCP_.js +1 -0
  173. package/web/dist/assets/google-gemini-cli-DpxAL3K4.js +2 -0
  174. package/web/dist/assets/google-shared-DyQdgtsI.js +2 -0
  175. package/web/dist/assets/google-vertex-CKRybaXj.js +1 -0
  176. package/web/dist/assets/graphlib-CMTVFyOZ.js +1 -0
  177. package/web/dist/assets/hash-kZ2KD_no.js +1 -0
  178. package/web/dist/assets/index-Bdb7P7gx.css +2 -0
  179. package/web/dist/assets/index-DNxepp8B.js +2891 -0
  180. package/web/dist/assets/info-OMHHGYJF-BGcxeaZt.js +1 -0
  181. package/web/dist/assets/infoDiagram-42DDH7IO-BbES7X_c.js +2 -0
  182. package/web/dist/assets/init-DlZdxViB.js +1 -0
  183. package/web/dist/assets/isEmpty-DssUW35f.js +1 -0
  184. package/web/dist/assets/ishikawaDiagram-UXIWVN3A-DxQ28rho.js +70 -0
  185. package/web/dist/assets/journeyDiagram-VCZTEJTY-D0X8qQ0P.js +139 -0
  186. package/web/dist/assets/json-parse-C6tSeIxX.js +2 -0
  187. package/web/dist/assets/kanban-definition-6JOO6SKY-DWYfSlpl.js +89 -0
  188. package/web/dist/assets/katex-CyM-5LlM.js +265 -0
  189. package/web/dist/assets/line-CuHce5JG.js +1 -0
  190. package/web/dist/assets/linear-Ca0Vkwuj.js +1 -0
  191. package/web/dist/assets/mermaid-parser.core-Cy4iY_Dy.js +4 -0
  192. package/web/dist/assets/mermaid.core-6PGkQdYc.js +11 -0
  193. package/web/dist/assets/mindmap-definition-QFDTVHPH-BBnKdtQh.js +96 -0
  194. package/web/dist/assets/mistral-BWaUMIgd.js +7 -0
  195. package/web/dist/assets/openai-D4NSaQIs.js +16 -0
  196. package/web/dist/assets/openai-codex-responses-CHBgKhmb.js +7 -0
  197. package/web/dist/assets/openai-completions-kcXmmaHI.js +5 -0
  198. package/web/dist/assets/openai-responses-Cqq3H3p3.js +1 -0
  199. package/web/dist/assets/openai-responses-shared-CTNuo9ci.js +10 -0
  200. package/web/dist/assets/ordinal-_K3x1fkz.js +1 -0
  201. package/web/dist/assets/ort-wasm-simd-threaded.jsep-B0T3yYHD.wasm +0 -0
  202. package/web/dist/assets/packet-4T2RLAQJ-D35ZLSBH.js +1 -0
  203. package/web/dist/assets/path-6uRLdFF7.js +1 -0
  204. package/web/dist/assets/pdf.worker.min-Cpi8b8z3.mjs +28 -0
  205. package/web/dist/assets/pie-ZZUOXDRM-DRoETpJX.js +1 -0
  206. package/web/dist/assets/pieDiagram-DEJITSTG-DfMjfTQz.js +30 -0
  207. package/web/dist/assets/preload-helper-DSXbuxSR.js +1 -0
  208. package/web/dist/assets/quadrantDiagram-34T5L4WZ-DfBSEept.js +7 -0
  209. package/web/dist/assets/radar-PYXPWWZC-DLKxRJ0V.js +1 -0
  210. package/web/dist/assets/reduce-836A2NiQ.js +1 -0
  211. package/web/dist/assets/requirementDiagram-MS252O5E-BPkxJQkz.js +84 -0
  212. package/web/dist/assets/rough.esm-Djo4Abte.js +1 -0
  213. package/web/dist/assets/sankeyDiagram-XADWPNL6-He3x9tNT.js +10 -0
  214. package/web/dist/assets/sequenceDiagram-FGHM5R23-DfCDpvrT.js +157 -0
  215. package/web/dist/assets/src-DdOdIreR.js +1 -0
  216. package/web/dist/assets/stateDiagram-FHFEXIEX-fuww6347.js +1 -0
  217. package/web/dist/assets/stateDiagram-v2-QKLJ7IA2-U6voafO3.js +1 -0
  218. package/web/dist/assets/timeline-definition-GMOUNBTQ-BWunHgBC.js +120 -0
  219. package/web/dist/assets/transform-messages-CqKEdRVp.js +1 -0
  220. package/web/dist/assets/transformers.web-DKUtmSAi.js +2818 -0
  221. package/web/dist/assets/treeView-SZITEDCU-BCx0xSAm.js +1 -0
  222. package/web/dist/assets/treemap-W4RFUUIX-2CvghWJK.js +1 -0
  223. package/web/dist/assets/vennDiagram-DHZGUBPP-CBXRutSP.js +34 -0
  224. package/web/dist/assets/wardley-RL74JXVD-BkPL_mhd.js +1 -0
  225. package/web/dist/assets/wardleyDiagram-NUSXRM2D-DTcVscPH.js +20 -0
  226. package/web/dist/assets/web-CMKYLKbT.js +10 -0
  227. package/web/dist/assets/xychartDiagram-5P7HB3ND-CZLgX9Fe.js +7 -0
  228. package/web/dist/favicon.svg +10 -0
  229. package/web/dist/index.html +104 -0
  230. package/web/dist/keating-metaharness.pdf +10557 -3
  231. package/web/dist/llms.txt +44 -0
  232. package/web/dist/logo.png +0 -0
  233. package/web/dist/manifest.webmanifest +1 -0
  234. package/web/dist/og-image.png +0 -0
  235. package/web/dist/pwa-192x192.svg +10 -0
  236. package/web/dist/pwa-512x512.svg +10 -0
  237. package/web/dist/registerSW.js +1 -0
  238. package/web/dist/robots.txt +8 -0
  239. package/web/dist/sitemap.xml +39 -0
  240. package/web/dist/sw.js +1 -0
  241. package/web/dist/tapes/doctor.mp4 +0 -0
  242. package/web/dist/tapes/feedback-flow.mp4 +0 -0
  243. package/web/dist/tapes/improve-flow.mp4 +0 -0
  244. package/web/dist/tapes/intro.mp4 +0 -0
  245. package/web/dist/tapes/learning-flow.mp4 +0 -0
  246. package/web/dist/tapes/session-flow.mp4 +0 -0
  247. package/web/dist/tapes/teacher-flow.mp4 +0 -0
  248. package/web/dist/tapes/tests.mp4 +0 -0
  249. package/web/dist/workbox-66610c77.js +1 -0
@@ -0,0 +1,343 @@
1
+ import { existsSync, statSync, readFileSync } from "node:fs";
2
+ import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { spawn, spawnSync } from "node:child_process";
6
+ import { homedir } from "node:os";
7
+ import { FALLBACK_PI_MODELS, loadKeatingConfig, mergePiDefaultsWithOverrides } from "../core/config.js";
8
+ import { ensureProjectScaffold } from "../core/project.js";
9
+ import { sessionsDir, configDir } from "../core/paths.js";
10
+ const __dirname = dirname(fileURLToPath(import.meta.url));
11
+ function resolvePackageRoot() {
12
+ const override = process.env.KEATING_PACKAGE_ROOT_OVERRIDE;
13
+ if (override)
14
+ return resolve(override);
15
+ const normalizedDir = __dirname.replace(/\\/g, "/");
16
+ return normalizedDir.includes("/dist/src/runtime")
17
+ ? join(__dirname, "..", "..", "..")
18
+ : join(__dirname, "..", "..");
19
+ }
20
+ function missingRuntimeMessage(report) {
21
+ if (report.preference === "standalone-only") {
22
+ return [
23
+ "Keating is configured for standalone-only but no `pi` AI agent binary was found on PATH.",
24
+ "",
25
+ "Recover with one of:",
26
+ " npm install -g @mariozechner/pi-coding-agent",
27
+ " keating setup",
28
+ " edit keating.config.json and set pi.runtimePreference to prefer-standalone"
29
+ ].join("\n");
30
+ }
31
+ if (report.preference === "embedded-only") {
32
+ return [
33
+ "Keating is configured for embedded-only but no embedded AI agent was found.",
34
+ "",
35
+ "Recover with one of:",
36
+ " npm install -g @mariozechner/pi-coding-agent",
37
+ " keating setup",
38
+ " npm install -g keating"
39
+ ].join("\n");
40
+ }
41
+ return [
42
+ "Could not find an AI runtime.",
43
+ "",
44
+ "Recover with one of:",
45
+ " npm install -g @mariozechner/pi-coding-agent",
46
+ " npm install -g keating",
47
+ " curl -fsSL https://raw.githubusercontent.com/Diogenesoftoronto/keating/main/scripts/install/install.sh | bash"
48
+ ].join("\n");
49
+ }
50
+ function resolveStandaloneAgent() {
51
+ const result = spawnSync("which", ["pi"], { encoding: "utf8", env: process.env });
52
+ if (result.status === 0 && result.stdout.trim()) {
53
+ const command = result.stdout.trim();
54
+ const versionResult = spawnSync(command, ["--version"], { encoding: "utf8", env: process.env });
55
+ if (versionResult.status === 0 && /^\d+\.\d+\.\d+/.test(versionResult.stdout.trim())) {
56
+ return {
57
+ kind: "binary",
58
+ command
59
+ };
60
+ }
61
+ }
62
+ return null;
63
+ }
64
+ const CLI_AGENT_PACKAGES = [
65
+ ["@interleavelove", "keating-coding-agent"],
66
+ ["@mariozechner", "pi-coding-agent"],
67
+ ];
68
+ async function syncPiSettings(cwd, config) {
69
+ const agentDir = configDir(cwd);
70
+ const settingsPath = join(agentDir, "settings.json");
71
+ let settings = {};
72
+ try {
73
+ const parsed = JSON.parse(await readFile(settingsPath, "utf8"));
74
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
75
+ settings = parsed;
76
+ }
77
+ }
78
+ catch {
79
+ settings = {};
80
+ }
81
+ const quietStartup = !config.debug.consoleSummary;
82
+ if (settings.quietStartup === quietStartup)
83
+ return;
84
+ await mkdir(agentDir, { recursive: true });
85
+ await writeFile(settingsPath, `${JSON.stringify({ ...settings, quietStartup }, null, 2)}\n`, "utf8");
86
+ }
87
+ const PROVIDER_ENV_KEYS = {
88
+ google: ["GEMINI_API_KEY", "GOOGLE_API_KEY"],
89
+ openai: ["OPENAI_API_KEY"],
90
+ anthropic: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"]
91
+ };
92
+ const PROVIDER_SETUP_HINTS = {
93
+ google: [
94
+ "export GEMINI_API_KEY=your_google_ai_studio_key",
95
+ "or run `keating setup` and choose another provider"
96
+ ],
97
+ openai: [
98
+ "export OPENAI_API_KEY=your_openai_key",
99
+ "or run `keating setup` and choose another provider"
100
+ ],
101
+ anthropic: [
102
+ "export ANTHROPIC_API_KEY=your_anthropic_key",
103
+ "or run `keating setup` and choose another provider"
104
+ ]
105
+ };
106
+ function hasFlag(args, flag) {
107
+ return args.includes(flag) || args.some((arg) => arg.startsWith(`${flag}=`));
108
+ }
109
+ function flagValue(args, flag) {
110
+ const equalsArg = args.find((arg) => arg.startsWith(`${flag}=`));
111
+ if (equalsArg)
112
+ return equalsArg.slice(flag.length + 1);
113
+ const index = args.indexOf(flag);
114
+ return index >= 0 ? args[index + 1] : undefined;
115
+ }
116
+ function authJsonHasProvider(cwd, provider) {
117
+ const path = join(configDir(cwd), "auth.json");
118
+ try {
119
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
120
+ return Boolean(parsed?.[provider]);
121
+ }
122
+ catch {
123
+ return false;
124
+ }
125
+ }
126
+ function envHasProvider(env, provider) {
127
+ return (PROVIDER_ENV_KEYS[provider] ?? []).some((key) => Boolean(env[key]));
128
+ }
129
+ function providerIsConfigured(cwd, env, provider) {
130
+ return envHasProvider(env, provider) || authJsonHasProvider(cwd, provider);
131
+ }
132
+ function envWithProviderAliases(env) {
133
+ if (!env.GEMINI_API_KEY && env.GOOGLE_API_KEY) {
134
+ return { ...env, GEMINI_API_KEY: env.GOOGLE_API_KEY };
135
+ }
136
+ return { ...env };
137
+ }
138
+ function providerSetupMessage(provider) {
139
+ const hints = PROVIDER_SETUP_HINTS[provider] ?? [
140
+ `set the API key expected by provider "${provider}"`,
141
+ "or run `keating setup` and choose a configured provider"
142
+ ];
143
+ return [
144
+ `No credentials found for provider "${provider}".`,
145
+ "",
146
+ "Recover with:",
147
+ ...hints.map((hint) => ` ${hint}`),
148
+ " pi /login",
149
+ "",
150
+ "Then retry: keating shell"
151
+ ].join("\n");
152
+ }
153
+ function selectAuthenticatedProvider(cwd, config, args) {
154
+ const env = envWithProviderAliases(process.env);
155
+ if (hasFlag(args, "--list-models") || hasFlag(args, "--list-providers"))
156
+ return { env };
157
+ const hasExplicitProvider = hasFlag(args, "--provider");
158
+ const hasExplicitModel = hasFlag(args, "--model");
159
+ const hasExplicitApiKey = hasFlag(args, "--api-key");
160
+ const configuredProvider = config.pi.defaultProvider ?? "google";
161
+ if (hasExplicitProvider) {
162
+ const provider = flagValue(args, "--provider");
163
+ if (provider && !hasExplicitApiKey && PROVIDER_ENV_KEYS[provider] && !providerIsConfigured(cwd, env, provider)) {
164
+ throw new Error(providerSetupMessage(provider));
165
+ }
166
+ return { env };
167
+ }
168
+ const candidates = [configuredProvider, "google", "openai", "anthropic"].filter((provider, index, all) => provider && all.indexOf(provider) === index);
169
+ const selected = candidates.find((provider) => providerIsConfigured(cwd, env, provider));
170
+ if (!selected) {
171
+ throw new Error([
172
+ providerSetupMessage(configuredProvider),
173
+ "",
174
+ "Keating also checked for OpenAI and Anthropic credentials and did not find them.",
175
+ "Supported fallback env vars:",
176
+ " GEMINI_API_KEY or GOOGLE_API_KEY",
177
+ " OPENAI_API_KEY",
178
+ " ANTHROPIC_API_KEY or ANTHROPIC_OAUTH_TOKEN"
179
+ ].join("\n"));
180
+ }
181
+ if (selected === configuredProvider)
182
+ return { env };
183
+ return {
184
+ provider: selected,
185
+ model: hasExplicitModel ? undefined : FALLBACK_PI_MODELS[selected],
186
+ env,
187
+ note: `No credentials found for "${configuredProvider}". Using configured ${selected} credentials instead.`
188
+ };
189
+ }
190
+ function resolveAgentInNodeModules(nodeModulesDir) {
191
+ for (const [scope, pkg] of CLI_AGENT_PACKAGES) {
192
+ const cliPath = join(nodeModulesDir, scope, pkg, "dist", "cli.js");
193
+ if (existsSync(cliPath)) {
194
+ return { kind: "embedded-keating", command: process.execPath, cliPath };
195
+ }
196
+ }
197
+ return null;
198
+ }
199
+ async function resolveEmbeddedAgent(packageRoot = resolvePackageRoot()) {
200
+ const local = resolveAgentInNodeModules(join(packageRoot, "node_modules"));
201
+ if (local)
202
+ return local;
203
+ const base = join(homedir(), ".local", "share", "keating");
204
+ const entries = await readdir(base, { withFileTypes: true }).catch(() => []);
205
+ const dirs = entries
206
+ .filter((entry) => entry.isDirectory())
207
+ .map((entry) => entry.name)
208
+ .sort()
209
+ .reverse();
210
+ for (const name of dirs) {
211
+ for (const root of [join(base, name), join(base, name, "app")]) {
212
+ const embedded = resolveAgentInNodeModules(join(root, "node_modules"));
213
+ if (embedded)
214
+ return embedded;
215
+ }
216
+ }
217
+ for (const [scope, pkg] of CLI_AGENT_PACKAGES) {
218
+ const globalPrefix = join(homedir(), ".local", "share", "mise", "installs", "node");
219
+ const versionEntries = await readdir(globalPrefix, { withFileTypes: true }).catch(() => []);
220
+ const versionDirs = versionEntries
221
+ .filter((e) => e.isDirectory())
222
+ .map((e) => e.name)
223
+ .sort()
224
+ .reverse();
225
+ for (const ver of versionDirs) {
226
+ const cliPath = join(globalPrefix, ver, "lib", "node_modules", scope, pkg, "dist", "cli.js");
227
+ if (existsSync(cliPath)) {
228
+ return { kind: "embedded-keating", command: process.execPath, cliPath };
229
+ }
230
+ const nmDir = join(globalPrefix, ver, "lib", "node_modules");
231
+ const nmEntries = await readdir(nmDir, { withFileTypes: true }).catch(() => []);
232
+ const nmDirs = nmEntries.filter((e) => e.isDirectory() || (e.isSymbolicLink() && statSync(join(nmDir, e.name)).isDirectory()));
233
+ for (const nmEntry of nmDirs) {
234
+ const nested = join(nmDir, nmEntry.name, "node_modules", scope, pkg, "dist", "cli.js");
235
+ if (existsSync(nested)) {
236
+ return { kind: "embedded-keating", command: process.execPath, cliPath: nested };
237
+ }
238
+ }
239
+ }
240
+ const bunGlobal = join(homedir(), ".bun", "install", "global", "node_modules", scope, pkg, "dist", "cli.js");
241
+ if (existsSync(bunGlobal)) {
242
+ return { kind: "embedded-keating", command: process.execPath, cliPath: bunGlobal };
243
+ }
244
+ }
245
+ return null;
246
+ }
247
+ export async function detectAiRuntime(cwd) {
248
+ const config = await loadKeatingConfig(cwd);
249
+ const standalone = resolveStandaloneAgent();
250
+ const embedded = await resolveEmbeddedAgent();
251
+ let selected = null;
252
+ switch (config.pi.runtimePreference) {
253
+ case "embedded-only":
254
+ selected = embedded;
255
+ break;
256
+ case "prefer-standalone":
257
+ selected = standalone ?? embedded;
258
+ break;
259
+ case "standalone-only":
260
+ default:
261
+ selected = standalone;
262
+ break;
263
+ }
264
+ return {
265
+ selected,
266
+ standalone,
267
+ embedded,
268
+ preference: config.pi.runtimePreference
269
+ };
270
+ }
271
+ export async function launchShell(cwd, args) {
272
+ await ensureProjectScaffold(cwd);
273
+ const config = await loadKeatingConfig(cwd);
274
+ await syncPiSettings(cwd, config);
275
+ const report = await detectAiRuntime(cwd);
276
+ const runtime = report.selected;
277
+ if (!runtime) {
278
+ throw new Error(missingRuntimeMessage(report));
279
+ }
280
+ const packageRoot = resolvePackageRoot();
281
+ const isDist = __dirname.replace(/\\/g, "/").includes("/dist/src/runtime");
282
+ const extensionPath = isDist
283
+ ? join(__dirname, "..", "pi", "hyperteacher-extension.js")
284
+ : join(packageRoot, "dist", "src", "pi", "hyperteacher-extension.js");
285
+ if (!existsSync(extensionPath)) {
286
+ throw new Error([
287
+ `Missing built extension: ${extensionPath}.`,
288
+ "",
289
+ "Recover with:",
290
+ " bun run build",
291
+ " npm run build",
292
+ "",
293
+ "If this came from an installed package, reinstall Keating:",
294
+ " npm install -g keating"
295
+ ].join("\n"));
296
+ }
297
+ const promptDir = join(packageRoot, "pi", "prompts");
298
+ const skillsDir = join(packageRoot, "pi", "skills");
299
+ const systemPromptPath = join(packageRoot, "SYSTEM.md");
300
+ const systemPrompt = readFileSync(systemPromptPath, "utf8");
301
+ const authSelection = selectAuthenticatedProvider(cwd, config, args);
302
+ if (authSelection.note) {
303
+ console.error(authSelection.note);
304
+ }
305
+ const sharedArgs = mergePiDefaultsWithOverrides(config, [
306
+ "--session-dir",
307
+ sessionsDir(cwd),
308
+ "--extension",
309
+ extensionPath,
310
+ "--prompt-template",
311
+ promptDir,
312
+ "--skill",
313
+ skillsDir,
314
+ "--append-system-prompt",
315
+ systemPrompt,
316
+ "--tools",
317
+ "read,bash,edit,write,grep,find,ls",
318
+ ...args
319
+ ], { provider: authSelection.provider, model: authSelection.model });
320
+ const child = runtime.kind === "binary"
321
+ ? spawn(runtime.command, sharedArgs, {
322
+ cwd,
323
+ stdio: "inherit",
324
+ env: {
325
+ ...authSelection.env,
326
+ PI_SKIP_VERSION_CHECK: process.env.PI_SKIP_VERSION_CHECK ?? "1",
327
+ PI_CODING_AGENT_DIR: configDir(cwd)
328
+ }
329
+ })
330
+ : spawn(runtime.command, [runtime.cliPath, ...sharedArgs], {
331
+ cwd,
332
+ stdio: "inherit",
333
+ env: {
334
+ ...authSelection.env,
335
+ PI_SKIP_VERSION_CHECK: process.env.PI_SKIP_VERSION_CHECK ?? "1",
336
+ PI_CODING_AGENT_DIR: configDir(cwd)
337
+ }
338
+ });
339
+ return await new Promise((resolvePromise, reject) => {
340
+ child.on("error", reject);
341
+ child.on("exit", (code) => resolvePromise(code ?? 0));
342
+ });
343
+ }
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "keating",
3
+ "version": "0.3.6",
4
+ "type": "module",
5
+ "description": "A Pi-powered hyperteacher package with self-improving teaching policies, lesson maps, and animated visual teaching artifacts.",
6
+ "keywords": [
7
+ "pi-package",
8
+ "hyperteacher",
9
+ "education",
10
+ "feynman-style",
11
+ "teaching-agent",
12
+ "ai-education",
13
+ "cognitive-empowerment"
14
+ ],
15
+ "author": "Diogenes of Toronto",
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/Diogenesoftoronto/keating.git"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/Diogenesoftoronto/keating/issues"
23
+ },
24
+ "homepage": "https://keating.help",
25
+ "bin": {
26
+ "keating": "bin/keating.js"
27
+ },
28
+ "engines": {
29
+ "node": ">=20.19.0"
30
+ },
31
+ "files": [
32
+ "bin/keating.js",
33
+ "dist/",
34
+ "pi/",
35
+ "scripts/install/",
36
+ "SYSTEM.md",
37
+ "web/dist/"
38
+ ],
39
+ "pi": {
40
+ "extensions": [
41
+ "./dist/src/pi"
42
+ ],
43
+ "skills": [
44
+ "./pi/skills"
45
+ ],
46
+ "prompts": [
47
+ "./pi/prompts"
48
+ ]
49
+ },
50
+ "scripts": {
51
+ "build": "bun x tsc -p tsconfig.json && cd web && bun run build",
52
+ "test": "bun test ./test/*.test.ts",
53
+ "video:intro": "bun scripts/render-keating-intro.mjs",
54
+ "prepack": "bun run build"
55
+ },
56
+ "dependencies": {
57
+ "@ax-llm/ax": "^19.0.43",
58
+ "@google/generative-ai": "^0.24.1",
59
+ "@mariozechner/pi-coding-agent": "^0.73.1",
60
+ "dotenv": "^17.4.0",
61
+ "h3": "^2.0.1-rc.20",
62
+ "ink": "^7.0.3",
63
+ "manim-web": "^0.3.16",
64
+ "nitro": "^3.0.260311-beta",
65
+ "react": "^19.2.5"
66
+ },
67
+ "devDependencies": {
68
+ "@remotion/cli": "^4.0.455",
69
+ "@remotion/media-utils": "^4.0.455",
70
+ "@remotion/renderer": "^4.0.455",
71
+ "@types/node": "^25.6.0",
72
+ "@types/react": "^19.2.14",
73
+ "@types/react-dom": "^19.2.3",
74
+ "fast-check": "^4.6.0",
75
+ "react-dom": "^19.2.5",
76
+ "remotion": "^4.0.455"
77
+ }
78
+ }
@@ -0,0 +1,14 @@
1
+ ---
2
+ description: Bridge a concept across domains including science, math, philosophy, code, law, history, psychology, medicine, arts, and politics so the learner sees what transfers and what does not.
3
+ args: <topic>
4
+ section: Teaching Workflows
5
+ topLevelCli: true
6
+ ---
7
+ Bridge the following concept across domains: $@
8
+
9
+ Structure:
10
+
11
+ 1. Define the core invariant idea.
12
+ 2. Show how that idea appears in at least two domains.
13
+ 3. Point out where the analogy stops working.
14
+ 4. End with a transfer question for the learner.
@@ -0,0 +1,15 @@
1
+ ---
2
+ description: Diagnose what a learner already understands, where they are confused, and what to teach next.
3
+ args: <topic>
4
+ section: Teaching Workflows
5
+ topLevelCli: true
6
+ ---
7
+ Diagnose the learner's current state on: $@
8
+
9
+ Requirements:
10
+
11
+ 0. If `.keating/state/learner.json` exists, read the learner's identified misconceptions and mastery estimates before asking diagnostic questions. Use prior state to focus your questions.
12
+ 1. Ask at most three high-information questions before explaining.
13
+ 2. Infer likely misconceptions from the answers.
14
+ 3. Separate "missing prerequisite", "partial intuition", and "formal gap".
15
+ 4. End with a proposed next teaching step, not a full lecture.
@@ -0,0 +1,39 @@
1
+ ---
2
+ description: Run the self-improvement loop — diagnose benchmark weaknesses and propose code changes.
3
+ args: [history]
4
+ section: Meta-Evolution
5
+ topLevelCli: true
6
+ ---
7
+ Run the Keating self-improvement pipeline.
8
+
9
+ If the argument is "history", show the improvement attempt archive:
10
+ - Run `/improve history` and display the result.
11
+
12
+ Otherwise, generate a new improvement proposal:
13
+
14
+ 1. Run `/improve` to diagnose benchmark weaknesses and generate a proposal.
15
+ 2. Read the proposal file under `.keating/outputs/improvements/`.
16
+ 3. The proposal contains:
17
+ - A ranked list of diagnosed weaknesses (from benchmark traces).
18
+ - Specific target files that may be modified.
19
+ - Structured instructions for what to change and why.
20
+ - Safety rules: which files are mutable vs immutable.
21
+
22
+ 4. Execute the proposed changes:
23
+ - Only modify files listed in the proposal's `targets`.
24
+ - Never modify: `self-improve.ts`, `types.ts`, `config.ts`, `paths.ts`, `random.ts`.
25
+ - Before each edit, explain what you are changing and why.
26
+ - Keep changes minimal and focused on the diagnosed weakness.
27
+
28
+ 5. After making changes, run the benchmark to evaluate:
29
+ - `keating bench` to get the new score.
30
+ - Compare against the before-score in the proposal.
31
+ - If the score improved or held steady, the change is accepted.
32
+ - If the score dropped, revert your changes.
33
+
34
+ 6. Report the outcome: what changed, before/after scores, and whether the change was kept or rolled back.
35
+
36
+ Safety contract:
37
+ - The self-improvement loop modifies teaching logic (lesson plans, benchmark weights, animations, topic definitions, maps, policy defaults).
38
+ - It never modifies the improvement engine itself, type definitions, configuration, or the random seed system.
39
+ - Every attempt is archived with snapshots so changes can always be rolled back.
@@ -0,0 +1,21 @@
1
+ ---
2
+ description: Teach a concept adaptively with a mastery-first lesson loop.
3
+ args: <topic>
4
+ section: Teaching Workflows
5
+ topLevelCli: true
6
+ ---
7
+ Teach the learner the following topic: $@
8
+
9
+ Workflow:
10
+
11
+ 0. Before teaching, check `.keating/outputs/verifications/` for this topic. If no verification checklist exists, run `/verify <topic>` yourself — do not ask the user to do it. Do not present unverified factual claims as settled truth.
12
+ 0b. Check `.keating/state/learner.json` for prior coverage of this topic. If the learner has seen it before, skip orientation and go straight to retrieval practice or misconception repair.
13
+ 1. Start with a short diagnostic question or assumption check.
14
+ 2. Move through intuition before formal structure.
15
+ 3. Repair the likeliest misconception explicitly.
16
+ 4. Give at least one worked example.
17
+ 5. Ask for retrieval or reconstruction, not just agreement.
18
+ 6. End by bridging the topic to another domain or a practical consequence.
19
+
20
+ If a matching Keating artifact already exists under `.keating/outputs/plans/` or `.keating/outputs/maps/`, read it and use it.
21
+ If it does not exist and a structured lesson would help, run `/plan <topic>` or `/map <topic>` yourself. Never ask the user to run commands for you.
@@ -0,0 +1,14 @@
1
+ ---
2
+ description: Quiz a learner on a topic with feedback that reveals misconceptions instead of just scoring answers.
3
+ args: <topic>
4
+ section: Teaching Workflows
5
+ topLevelCli: true
6
+ ---
7
+ Run a short mastery quiz on: $@
8
+
9
+ Rules:
10
+
11
+ 1. Ask one question at a time.
12
+ 2. Mix recall, transfer, and misconception-revealing prompts.
13
+ 3. After each answer, say what the answer shows about understanding.
14
+ 4. If the learner misses something, teach the minimum needed correction before continuing.
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: adaptive-teaching
3
+ description: Use when the user wants to learn, be taught, be quizzed, or understand an idea across any domain — science, math, philosophy, code, law, politics, psychology, medicine, arts, or history — with active scaffolding.
4
+ ---
5
+
6
+ # Adaptive Teaching
7
+
8
+ Use this skill when the user asks to learn a concept rather than merely receive a summary.
9
+
10
+ ## Teaching Contract
11
+
12
+ 1. Diagnose first if the learner state is unknown. Check `.keating/state/learner.json` for prior coverage.
13
+ 2. Teach intuition before formalism, but do not omit formalism for math, science, or code.
14
+ 3. Surface one misconception early.
15
+ 4. Use retrieval and reconstruction prompts, not just exposition.
16
+ 5. End with transfer, reflection, or a next challenge.
17
+ 6. Verify factual claims before teaching. If `.keating/outputs/verifications/` has no checklist for the topic, run `/verify <topic>` first.
18
+
19
+ ## Keating Artifacts
20
+
21
+ - Run `/plan <topic>` yourself when a lesson plan would help — do not ask the user to do it.
22
+ - Run `/map <topic>` yourself when a concept map would help — do not ask the user to do it.
23
+ - Run `/animate <topic>` yourself when an animation would help — do not ask the user to do it.
24
+ - Run `/verify <topic>` yourself before teaching factual claims — do not ask the user to do it.
25
+ - Run `/bench [topic]` and `/evolve [topic]` yourself when improvement is needed — do not ask the user to do it.
26
+ - Run `/feedback <up|down|confused> [topic]` yourself after sessions to record outcomes.
27
+
28
+ ## Red Flags
29
+
30
+ - Do not drown the learner in formal language before a concrete hook exists.
31
+ - Do not act as though the synthetic benchmark proves pedagogical truth.
32
+ - Do not confuse a correct answer with stable understanding; probe transfer.
33
+ - Do not present unverified factual claims as settled truth. If verification artifacts exist, consult them. If claims are flagged as unconfirmed, hedge appropriately.