pythinker-code 0.19.0__tar.gz → 0.21.0__tar.gz

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 (849) hide show
  1. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/PKG-INFO +23 -26
  2. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/README.md +22 -25
  3. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/pyproject.toml +1 -1
  4. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/CHANGELOG.md +20 -0
  5. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/default/agent.yaml +1 -0
  6. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/default/code_reviewer.yaml +8 -0
  7. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/default/coder.yaml +1 -0
  8. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/default/plan.yaml +6 -0
  9. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/default/security_reviewer.yaml +9 -0
  10. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/default/system.md +33 -0
  11. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/app.py +3 -5
  12. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/__init__.py +14 -1
  13. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/config.py +33 -0
  14. pythinker_code-0.21.0/src/pythinker_code/memory/__init__.py +1 -0
  15. pythinker_code-0.21.0/src/pythinker_code/memory/consolidation.py +115 -0
  16. pythinker_code-0.21.0/src/pythinker_code/memory/harvest.py +54 -0
  17. pythinker_code-0.21.0/src/pythinker_code/memory/recall.py +274 -0
  18. pythinker_code-0.21.0/src/pythinker_code/memory/recap.py +94 -0
  19. pythinker_code-0.21.0/src/pythinker_code/memory/retriever.py +113 -0
  20. pythinker_code-0.21.0/src/pythinker_code/memory/retriever_sqlite.py +42 -0
  21. pythinker_code-0.21.0/src/pythinker_code/memory/sanitize.py +22 -0
  22. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/project_memory.py +33 -0
  23. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/scratchpad.py +163 -1
  24. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/agent.py +3 -0
  25. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/compaction.py +6 -2
  26. pythinker_code-0.21.0/src/pythinker_code/soul/dynamic_injection.py +211 -0
  27. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/pythinkersoul.py +66 -1
  28. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/memory/__init__.py +3 -0
  29. pythinker_code-0.21.0/src/pythinker_code/tools/scratchpad/__init__.py +65 -0
  30. pythinker_code-0.21.0/src/pythinker_code/tools/scratchpad/scratchpad_tool.md +8 -0
  31. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/glyphs.py +5 -5
  32. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/prompt.py +77 -3
  33. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/slash.py +38 -2
  34. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/_interactive.py +5 -0
  35. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/_live_view.py +41 -22
  36. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/_baseUniq-BJKUYzu3.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/_baseUniq-C8Bd_TP9.js +1 -1
  37. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/arc-BXTizAnD.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/arc-ylYpNcoq.js +1 -1
  38. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/architectureDiagram-VXUJARFQ-CrmZs6A8.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/architectureDiagram-VXUJARFQ-BWte_jxx.js +1 -1
  39. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/blockDiagram-VD42YOAC-iN-qchC_.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/blockDiagram-VD42YOAC-BJftRHsQ.js +1 -1
  40. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/c4Diagram-YG6GDRKO-CSymXbBo.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/c4Diagram-YG6GDRKO-C21Ih1L7.js +1 -1
  41. pythinker_code-0.21.0/src/pythinker_code/web/static/assets/channel-cFsXYmkm.js +1 -0
  42. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/chunk-4BX2VUAB-CkcnzHUC.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/chunk-4BX2VUAB-JknU19ZE.js +1 -1
  43. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/chunk-55IACEB6-BRhj_neq.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/chunk-55IACEB6-BWIhRTa7.js +1 -1
  44. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/chunk-B4BG7PRW-BT-PCmGa.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/chunk-B4BG7PRW-CJowGI5m.js +1 -1
  45. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/chunk-DI55MBZ5-CwthrlpX.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/chunk-DI55MBZ5-Da7epMGM.js +1 -1
  46. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/chunk-FMBD7UC4-D-ZXdM4t.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/chunk-FMBD7UC4-CEc0w_a5.js +1 -1
  47. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/chunk-QN33PNHL-Do35vPqv.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/chunk-QN33PNHL-BLuU8h1u.js +1 -1
  48. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/chunk-QZHKN3VN-BVQCZiDG.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/chunk-QZHKN3VN-CJG0wpOs.js +1 -1
  49. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/chunk-TZMSLE5B-cXonqPPm.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/chunk-TZMSLE5B-DiZf19ix.js +1 -1
  50. pythinker_code-0.21.0/src/pythinker_code/web/static/assets/classDiagram-2ON5EDUG-Bo26DeGf.js +1 -0
  51. pythinker_code-0.21.0/src/pythinker_code/web/static/assets/classDiagram-v2-WZHVMYZB-Bo26DeGf.js +1 -0
  52. pythinker_code-0.21.0/src/pythinker_code/web/static/assets/clone-BWFOTjOB.js +1 -0
  53. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/code-block-IT6T5CEO-O-JPa1HO.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/code-block-IT6T5CEO-DYxMhP_n.js +1 -1
  54. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/cose-bilkent-S5V4N54A-Dqgu6ynH.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/cose-bilkent-S5V4N54A-CIrvIrb8.js +1 -1
  55. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/cytoscape.esm-BbKPamH0.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/cytoscape.esm-DGEwJU2g.js +1 -1
  56. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/dagre-6UL2VRFP-B_gwu6IS.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/dagre-6UL2VRFP-D05JiAPY.js +1 -1
  57. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/diagram-PSM6KHXK-CkFdUwfm.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/diagram-PSM6KHXK-CXdhS0MK.js +1 -1
  58. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/diagram-QEK2KX5R-B5pxlJIP.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/diagram-QEK2KX5R-O5_mXEr7.js +1 -1
  59. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/diagram-S2PKOQOG-C3FaLt0z.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/diagram-S2PKOQOG-sjrm_ldt.js +1 -1
  60. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/erDiagram-Q2GNP2WA--WQoQVnp.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/erDiagram-Q2GNP2WA-BQULRMFg.js +1 -1
  61. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/flowDiagram-NV44I4VS-CVRcUzt3.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/flowDiagram-NV44I4VS-CRj3cebP.js +1 -1
  62. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/ganttDiagram-JELNMOA3-CvmJq0nT.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/ganttDiagram-JELNMOA3-rt1n4kOT.js +1 -1
  63. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/gitGraphDiagram-NY62KEGX-DcaE7ZHt.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/gitGraphDiagram-NY62KEGX-B3PI6M9c.js +1 -1
  64. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/graph-B6WB3LUd.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/graph-B8hQk4Sy.js +1 -1
  65. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/index-E-71Jnzv.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/index-2uIocdx_.js +1 -1
  66. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/index-CvqTAO1o.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/index-Dfq2O3Q4.js +1 -1
  67. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/index-DAmDs20g.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/index-RNrCW5Ft.js +2 -2
  68. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/infoDiagram-WHAUD3N6-DUao-JQ3.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/infoDiagram-WHAUD3N6-CHKJ3zB3.js +1 -1
  69. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/journeyDiagram-XKPGCS4Q-71MJCZxj.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/journeyDiagram-XKPGCS4Q-CPnd5Dq4.js +1 -1
  70. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/kanban-definition-3W4ZIXB7-Bm_Ym4PO.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/kanban-definition-3W4ZIXB7-Bupg0tIE.js +1 -1
  71. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/layout-BYpW8sEN.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/layout-By-v4W8i.js +1 -1
  72. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/linear-Bflt3o9l.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/linear-XfupmgR8.js +1 -1
  73. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/mermaid-VLURNSYL-kaBVL_6z.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/mermaid-VLURNSYL-Q58ocsqn.js +7 -7
  74. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/mermaid.core-QLxteY2A.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/mermaid.core-DaPsdGZG.js +5 -5
  75. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/min-C3V_Z9jj.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/min-CdowXToY.js +1 -1
  76. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/mindmap-definition-VGOIOE7T-DMH_lU93.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/mindmap-definition-VGOIOE7T-B2bhiEQq.js +1 -1
  77. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/pieDiagram-ADFJNKIX-CxTkLVEY.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/pieDiagram-ADFJNKIX-D3XKdi1E.js +1 -1
  78. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/quadrantDiagram-AYHSOK5B-GTS11l49.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/quadrantDiagram-AYHSOK5B-CzOISzaJ.js +1 -1
  79. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/requirementDiagram-UZGBJVZJ-CqAQTzsj.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/requirementDiagram-UZGBJVZJ-DF9iZwEH.js +1 -1
  80. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/sankeyDiagram-TZEHDZUN-kLwolHEO.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/sankeyDiagram-TZEHDZUN-qrcSXnC7.js +1 -1
  81. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/sequenceDiagram-WL72ISMW-BI1wC-bA.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/sequenceDiagram-WL72ISMW-58y9TKuh.js +1 -1
  82. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/stateDiagram-FKZM4ZOC-Tjq304Gx.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/stateDiagram-FKZM4ZOC-Dp46fOHZ.js +1 -1
  83. pythinker_code-0.21.0/src/pythinker_code/web/static/assets/stateDiagram-v2-4FDKWEC3-XWj2oRHP.js +1 -0
  84. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/timeline-definition-IT6M3QCI-WWeHtoIi.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/timeline-definition-IT6M3QCI--RRAqxwQ.js +1 -1
  85. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/treemap-KMMF4GRG-DqnLuAds.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/treemap-KMMF4GRG-QlVt3o20.js +1 -1
  86. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/xychartDiagram-PRI3JC2R-DtT_UDiY.js → pythinker_code-0.21.0/src/pythinker_code/web/static/assets/xychartDiagram-PRI3JC2R-6KIdqGLu.js +1 -1
  87. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/index.html +1 -1
  88. pythinker_code-0.21.0/src/pythinker_code/web/static/install.ps1 +206 -0
  89. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/install.sh +120 -2
  90. pythinker_code-0.19.0/src/pythinker_code/soul/dynamic_injection.py +0 -84
  91. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/channel-DEtq9qVe.js +0 -1
  92. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/classDiagram-2ON5EDUG-CYs9zedf.js +0 -1
  93. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/classDiagram-v2-WZHVMYZB-CYs9zedf.js +0 -1
  94. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/clone-ySoezlHt.js +0 -1
  95. pythinker_code-0.19.0/src/pythinker_code/web/static/assets/stateDiagram-v2-4FDKWEC3-C40rbI0B.js +0 -1
  96. pythinker_code-0.19.0/src/pythinker_code/web/static/install.ps1 +0 -110
  97. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/LICENSE +0 -0
  98. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/NOTICE +0 -0
  99. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/__init__.py +0 -0
  100. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/__main__.py +0 -0
  101. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/acp/AGENTS.md +0 -0
  102. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/acp/__init__.py +0 -0
  103. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/acp/convert.py +0 -0
  104. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/acp/host.py +0 -0
  105. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/acp/mcp.py +0 -0
  106. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/acp/server.py +0 -0
  107. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/acp/session.py +0 -0
  108. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/acp/tools.py +0 -0
  109. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/acp/types.py +0 -0
  110. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/acp/version.py +0 -0
  111. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/default/debugger.yaml +0 -0
  112. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/default/explore.yaml +0 -0
  113. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/default/implementer.yaml +0 -0
  114. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/default/review.yaml +0 -0
  115. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/default/verifier.yaml +0 -0
  116. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agents/okabe/agent.yaml +0 -0
  117. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/agentspec.py +0 -0
  118. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/approval_runtime/__init__.py +0 -0
  119. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/approval_runtime/models.py +0 -0
  120. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/approval_runtime/runtime.py +0 -0
  121. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/__init__.py +0 -0
  122. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/anthropic_direct.py +0 -0
  123. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/deepseek.py +0 -0
  124. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/github_feedback.py +0 -0
  125. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/lm_studio.py +0 -0
  126. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/minimax.py +0 -0
  127. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/oauth.py +0 -0
  128. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/ollama.py +0 -0
  129. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/openai.py +0 -0
  130. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/opencode_go.py +0 -0
  131. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/openrouter.py +0 -0
  132. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/auth/platforms.py +0 -0
  133. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/background/__init__.py +0 -0
  134. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/background/agent_runner.py +0 -0
  135. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/background/ids.py +0 -0
  136. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/background/manager.py +0 -0
  137. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/background/models.py +0 -0
  138. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/background/store.py +0 -0
  139. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/background/summary.py +0 -0
  140. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/background/worker.py +0 -0
  141. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/__main__.py +0 -0
  142. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/_lazy_group.py +0 -0
  143. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/debug.py +0 -0
  144. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/export.py +0 -0
  145. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/info.py +0 -0
  146. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/mcp.py +0 -0
  147. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/plugin.py +0 -0
  148. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/review.py +0 -0
  149. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/secscan.py +0 -0
  150. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/security_scan.py +0 -0
  151. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/skill.py +0 -0
  152. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/toad.py +0 -0
  153. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/update.py +0 -0
  154. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/vis.py +0 -0
  155. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/cli/web.py +0 -0
  156. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/constant.py +0 -0
  157. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/events.py +0 -0
  158. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/exception.py +0 -0
  159. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/execution_profiles.py +0 -0
  160. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/extensions.py +0 -0
  161. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/file_restore.py +0 -0
  162. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/hooks/__init__.py +0 -0
  163. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/hooks/config.py +0 -0
  164. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/hooks/engine.py +0 -0
  165. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/hooks/events.py +0 -0
  166. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/hooks/runner.py +0 -0
  167. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/llm.py +0 -0
  168. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/metadata.py +0 -0
  169. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/native.py +0 -0
  170. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/notifications/__init__.py +0 -0
  171. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/notifications/llm.py +0 -0
  172. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/notifications/manager.py +0 -0
  173. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/notifications/models.py +0 -0
  174. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/notifications/notifier.py +0 -0
  175. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/notifications/store.py +0 -0
  176. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/notifications/wire.py +0 -0
  177. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/plugin/__init__.py +0 -0
  178. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/plugin/manager.py +0 -0
  179. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/plugin/tool.py +0 -0
  180. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/prompt_templates.py +0 -0
  181. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/prompts/__init__.py +0 -0
  182. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/prompts/compact.md +0 -0
  183. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/prompts/init.md +0 -0
  184. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/py.typed +0 -0
  185. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/session.py +0 -0
  186. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/session_fork.py +0 -0
  187. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/session_state.py +0 -0
  188. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/share.py +0 -0
  189. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skill/__init__.py +0 -0
  190. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skill/flow/__init__.py +0 -0
  191. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skill/flow/d2.py +0 -0
  192. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skill/flow/mermaid.py +0 -0
  193. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skill/lockfile.py +0 -0
  194. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/check-impl-against-spec/SKILL.md +0 -0
  195. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/create-pr/SKILL.md +0 -0
  196. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/diagnose-ci-failures/SKILL.md +0 -0
  197. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/fix-errors/SKILL.md +0 -0
  198. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/implement-specs/SKILL.md +0 -0
  199. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/pr-walkthrough/SKILL.md +0 -0
  200. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/pythinker-code-help/SKILL.md +0 -0
  201. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/reproduce-bug-report/SKILL.md +0 -0
  202. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/resolve-merge-conflicts/SKILL.md +0 -0
  203. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/review-pr/SKILL.md +0 -0
  204. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/skill-creator/SKILL.md +0 -0
  205. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/spec-driven-implementation/SKILL.md +0 -0
  206. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/write-product-spec/SKILL.md +0 -0
  207. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/skills/write-tech-spec/SKILL.md +0 -0
  208. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/__init__.py +0 -0
  209. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/approval.py +0 -0
  210. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/btw.py +0 -0
  211. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/compaction_restore.py +0 -0
  212. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/context.py +0 -0
  213. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/denwarenji.py +0 -0
  214. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/dynamic_injections/__init__.py +0 -0
  215. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/dynamic_injections/auto_mode.py +0 -0
  216. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/dynamic_injections/plan_mode.py +0 -0
  217. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/message.py +0 -0
  218. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/permission.py +0 -0
  219. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/slash.py +0 -0
  220. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/soul/toolset.py +0 -0
  221. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/subagents/__init__.py +0 -0
  222. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/subagents/builder.py +0 -0
  223. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/subagents/core.py +0 -0
  224. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/subagents/discovery.py +0 -0
  225. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/subagents/git_context.py +0 -0
  226. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/subagents/models.py +0 -0
  227. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/subagents/output.py +0 -0
  228. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/subagents/registry.py +0 -0
  229. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/subagents/runner.py +0 -0
  230. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/subagents/store.py +0 -0
  231. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/telemetry/__init__.py +0 -0
  232. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/telemetry/config.py +0 -0
  233. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/telemetry/crash.py +0 -0
  234. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/telemetry/errors.py +0 -0
  235. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/telemetry/metrics.py +0 -0
  236. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/telemetry/otel.py +0 -0
  237. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/telemetry/sentry.py +0 -0
  238. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/telemetry/sink.py +0 -0
  239. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/AGENTS.md +0 -0
  240. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/__init__.py +0 -0
  241. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/agent/__init__.py +0 -0
  242. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/agent/description.md +0 -0
  243. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/ask_user/__init__.py +0 -0
  244. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/ask_user/description.md +0 -0
  245. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/background/__init__.py +0 -0
  246. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/background/handoff.md +0 -0
  247. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/background/input.md +0 -0
  248. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/background/list.md +0 -0
  249. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/background/output.md +0 -0
  250. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/background/stop.md +0 -0
  251. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/display.py +0 -0
  252. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/dmail/__init__.py +0 -0
  253. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/dmail/dmail.md +0 -0
  254. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/__init__.py +0 -0
  255. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/glob.md +0 -0
  256. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/glob.py +0 -0
  257. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/grep.md +0 -0
  258. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/grep_local.py +0 -0
  259. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/plan_mode.py +0 -0
  260. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/read.md +0 -0
  261. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/read.py +0 -0
  262. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/read_media.md +0 -0
  263. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/read_media.py +0 -0
  264. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/replace.md +0 -0
  265. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/replace.py +0 -0
  266. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/utils.py +0 -0
  267. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/write.md +0 -0
  268. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/file/write.py +0 -0
  269. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/memory/memory.md +0 -0
  270. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/plan/__init__.py +0 -0
  271. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/plan/description.md +0 -0
  272. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/plan/enter.py +0 -0
  273. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/plan/enter_description.md +0 -0
  274. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/plan/handoff.py +0 -0
  275. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/plan/heroes.py +0 -0
  276. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/shell/__init__.py +0 -0
  277. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/shell/bash.md +0 -0
  278. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/shell/powershell.md +0 -0
  279. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/skill/__init__.py +0 -0
  280. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/skill/description.md +0 -0
  281. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/test.py +0 -0
  282. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/think/__init__.py +0 -0
  283. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/think/think.md +0 -0
  284. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/todo/__init__.py +0 -0
  285. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/todo/set_todo_list.md +0 -0
  286. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/utils.py +0 -0
  287. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/web/__init__.py +0 -0
  288. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/web/fetch.md +0 -0
  289. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/web/fetch.py +0 -0
  290. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/web/search.md +0 -0
  291. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/tools/web/search.py +0 -0
  292. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/__init__.py +0 -0
  293. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/acp/__init__.py +0 -0
  294. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/print/__init__.py +0 -0
  295. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/print/visualize.py +0 -0
  296. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/__init__.py +0 -0
  297. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/__init__.py +0 -0
  298. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/base.py +0 -0
  299. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/bash_execution.py +0 -0
  300. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/bordered_loader.py +0 -0
  301. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/diff.py +0 -0
  302. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/dynamic_border.py +0 -0
  303. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/footer.py +0 -0
  304. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/key_hints.py +0 -0
  305. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/markdown.py +0 -0
  306. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/messages.py +0 -0
  307. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/panel.py +0 -0
  308. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/render_utils.py +0 -0
  309. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/settings_list.py +0 -0
  310. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/special_messages.py +0 -0
  311. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/components/tool_execution.py +0 -0
  312. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/console.py +0 -0
  313. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/debug.py +0 -0
  314. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/design_system.py +0 -0
  315. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/echo.py +0 -0
  316. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/export_import.py +0 -0
  317. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/keyboard.py +0 -0
  318. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/keymap.py +0 -0
  319. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/mcp_status.py +0 -0
  320. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/model_picker.py +0 -0
  321. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/motion.py +0 -0
  322. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/oauth.py +0 -0
  323. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/placeholders.py +0 -0
  324. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/render_constants.py +0 -0
  325. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/replay.py +0 -0
  326. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/selector.py +0 -0
  327. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/selectors/__init__.py +0 -0
  328. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/selectors/extension.py +0 -0
  329. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/selectors/oauth.py +0 -0
  330. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/selectors/settings.py +0 -0
  331. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/selectors/show_images.py +0 -0
  332. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/selectors/theme.py +0 -0
  333. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/selectors/thinking.py +0 -0
  334. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/session_picker.py +0 -0
  335. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/setup.py +0 -0
  336. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/spacing.py +0 -0
  337. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/spinner_words.py +0 -0
  338. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/startup.py +0 -0
  339. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/task_browser.py +0 -0
  340. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tips.py +0 -0
  341. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/__init__.py +0 -0
  342. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/_file_diff.py +0 -0
  343. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/_render_utils.py +0 -0
  344. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/agent.py +0 -0
  345. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/ask_user.py +0 -0
  346. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/background.py +0 -0
  347. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/bash.py +0 -0
  348. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/edit.py +0 -0
  349. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/find.py +0 -0
  350. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/generic.py +0 -0
  351. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/grep.py +0 -0
  352. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/plan.py +0 -0
  353. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/read.py +0 -0
  354. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/think.py +0 -0
  355. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/todo.py +0 -0
  356. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/web.py +0 -0
  357. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/tool_renderers/write.py +0 -0
  358. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/update.py +0 -0
  359. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage.py +0 -0
  360. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_adapters/__init__.py +0 -0
  361. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_adapters/anthropic_admin.py +0 -0
  362. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_adapters/base.py +0 -0
  363. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_adapters/deepseek.py +0 -0
  364. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_adapters/minimax.py +0 -0
  365. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_adapters/openai_admin.py +0 -0
  366. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_adapters/openai_chatgpt.py +0 -0
  367. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_adapters/opencode_go.py +0 -0
  368. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_adapters/openrouter.py +0 -0
  369. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_adapters/pythinker.py +0 -0
  370. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_adapters/pythinker_ai.py +0 -0
  371. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/usage_render.py +0 -0
  372. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/__init__.py +0 -0
  373. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/_activity_tree.py +0 -0
  374. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/_approval_panel.py +0 -0
  375. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/_blocks.py +0 -0
  376. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/_btw_panel.py +0 -0
  377. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/_dialog_shell.py +0 -0
  378. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/_input_router.py +0 -0
  379. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/_question_panel.py +0 -0
  380. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/_transcript.py +0 -0
  381. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/shell/visualize/_worklog.py +0 -0
  382. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/theme.py +0 -0
  383. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/ui/tui_config.py +0 -0
  384. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/usage_ratelimit_cache.py +0 -0
  385. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/__init__.py +0 -0
  386. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/aiohttp.py +0 -0
  387. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/aioqueue.py +0 -0
  388. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/broadcast.py +0 -0
  389. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/changelog.py +0 -0
  390. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/clipboard.py +0 -0
  391. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/datetime.py +0 -0
  392. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/diff.py +0 -0
  393. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/editor.py +0 -0
  394. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/environment.py +0 -0
  395. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/envvar.py +0 -0
  396. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/export.py +0 -0
  397. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/file_filter.py +0 -0
  398. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/frontmatter.py +0 -0
  399. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/io.py +0 -0
  400. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/logging.py +0 -0
  401. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/media_tags.py +0 -0
  402. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/message.py +0 -0
  403. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/path.py +0 -0
  404. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/proctitle.py +0 -0
  405. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/proxy.py +0 -0
  406. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/pyinstaller.py +0 -0
  407. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/rich/__init__.py +0 -0
  408. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/rich/columns.py +0 -0
  409. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/rich/diff_render.py +0 -0
  410. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/rich/markdown.py +0 -0
  411. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/rich/markdown_sample.md +0 -0
  412. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/rich/markdown_sample_short.md +0 -0
  413. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/rich/syntax.py +0 -0
  414. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/sensitive.py +0 -0
  415. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/server.py +0 -0
  416. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/signals.py +0 -0
  417. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/slashcmd.py +0 -0
  418. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/sleep_inhibitor.py +0 -0
  419. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/string.py +0 -0
  420. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/subprocess_env.py +0 -0
  421. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/term.py +0 -0
  422. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/utils/typing.py +0 -0
  423. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/__init__.py +0 -0
  424. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/api/__init__.py +0 -0
  425. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/api/sessions.py +0 -0
  426. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/api/statistics.py +0 -0
  427. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/api/system.py +0 -0
  428. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/app.py +0 -0
  429. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/static/assets/highlighted-body-B3W2YXNL-CY1rtwrX.js +0 -0
  430. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/static/assets/index-DSRInNnm.css +0 -0
  431. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/static/assets/index-DgmTI2M_.js +0 -0
  432. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/static/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  433. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/static/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  434. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/static/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  435. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/static/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  436. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/static/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  437. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/static/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  438. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/static/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  439. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/vis/static/index.html +0 -0
  440. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/__init__.py +0 -0
  441. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/api/__init__.py +0 -0
  442. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/api/config.py +0 -0
  443. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/api/open_in.py +0 -0
  444. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/api/sessions.py +0 -0
  445. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/app.py +0 -0
  446. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/auth.py +0 -0
  447. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/models.py +0 -0
  448. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/runner/__init__.py +0 -0
  449. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/runner/messages.py +0 -0
  450. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/runner/process.py +0 -0
  451. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/runner/worker.py +0 -0
  452. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/_headers +0 -0
  453. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  454. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  455. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  456. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  457. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  458. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  459. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  460. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  461. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  462. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  463. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  464. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  465. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  466. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  467. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  468. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  469. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  470. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  471. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  472. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  473. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  474. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  475. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  476. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  477. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  478. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  479. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  480. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  481. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  482. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  483. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  484. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  485. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  486. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  487. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  488. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  489. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  490. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  491. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  492. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  493. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  494. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  495. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  496. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  497. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  498. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  499. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  500. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  501. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  502. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  503. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  504. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  505. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  506. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  507. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  508. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  509. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  510. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  511. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  512. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/abap-BdImnpbu.js +0 -0
  513. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/actionscript-3-CfeIJUat.js +0 -0
  514. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/ada-bCR0ucgS.js +0 -0
  515. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/andromeeda-C-Jbm3Hp.js +0 -0
  516. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/angular-html-CU67Zn6k.js +0 -0
  517. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/angular-ts-BwZT4LLn.js +0 -0
  518. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/apache-Pmp26Uib.js +0 -0
  519. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/apex-D8_7TLub.js +0 -0
  520. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/apl-dKokRX4l.js +0 -0
  521. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/applescript-Co6uUVPk.js +0 -0
  522. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/ara-BRHolxvo.js +0 -0
  523. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/asciidoc-Dv7Oe6Be.js +0 -0
  524. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/asm-D_Q5rh1f.js +0 -0
  525. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/astro-CbQHKStN.js +0 -0
  526. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/aurora-x-D-2ljcwZ.js +0 -0
  527. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/awk-DMzUqQB5.js +0 -0
  528. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/ayu-dark-CmMr59Fi.js +0 -0
  529. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/ballerina-BFfxhgS-.js +0 -0
  530. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/bat-BkioyH1T.js +0 -0
  531. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/beancount-k_qm7-4y.js +0 -0
  532. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/berry-uYugtg8r.js +0 -0
  533. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/bibtex-CHM0blh-.js +0 -0
  534. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/bicep-Bmn6On1c.js +0 -0
  535. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/blade-D4QpJJKB.js +0 -0
  536. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/bsl-BO_Y6i37.js +0 -0
  537. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/c-BIGW1oBm.js +0 -0
  538. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/c3-VCDPK7BO.js +0 -0
  539. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/cadence-Bv_4Rxtq.js +0 -0
  540. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/cairo-KRGpt6FW.js +0 -0
  541. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/catppuccin-frappe-DFWUc33u.js +0 -0
  542. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/catppuccin-latte-C9dUb6Cb.js +0 -0
  543. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/catppuccin-macchiato-DQyhUUbL.js +0 -0
  544. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/catppuccin-mocha-D87Tk5Gz.js +0 -0
  545. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/clarity-D53aC0YG.js +0 -0
  546. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/clojure-P80f7IUj.js +0 -0
  547. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/cmake-D1j8_8rp.js +0 -0
  548. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/cobol-nwyudZeR.js +0 -0
  549. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/codeowners-Bp6g37R7.js +0 -0
  550. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/codeql-DsOJ9woJ.js +0 -0
  551. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/coffee-Ch7k5sss.js +0 -0
  552. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/common-lisp-Cg-RD9OK.js +0 -0
  553. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/coq-DkFqJrB1.js +0 -0
  554. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/cpp-CofmeUqb.js +0 -0
  555. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/crystal-tKQVLTB8.js +0 -0
  556. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/csharp-K5feNrxe.js +0 -0
  557. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/css-DPfMkruS.js +0 -0
  558. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/csv-fuZLfV_i.js +0 -0
  559. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/cue-D82EKSYY.js +0 -0
  560. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/cypher-COkxafJQ.js +0 -0
  561. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/d-85-TOEBH.js +0 -0
  562. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/dark-plus-C3mMm8J8.js +0 -0
  563. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/dart-CF10PKvl.js +0 -0
  564. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/dax-CEL-wOlO.js +0 -0
  565. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/defaultLocale-DX6XiGOO.js +0 -0
  566. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/desktop-BmXAJ9_W.js +0 -0
  567. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/diff-D97Zzqfu.js +0 -0
  568. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/docker-BcOcwvcX.js +0 -0
  569. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/dotenv-Da5cRb03.js +0 -0
  570. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/dracula-BzJJZx-M.js +0 -0
  571. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/dracula-soft-BXkSAIEj.js +0 -0
  572. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/dream-maker-BtqSS_iP.js +0 -0
  573. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/edge-BkV0erSs.js +0 -0
  574. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/elixir-CDX3lj18.js +0 -0
  575. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/elm-DbKCFpqz.js +0 -0
  576. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/emacs-lisp-C9XAeP06.js +0 -0
  577. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/erb-BOJIQeun.js +0 -0
  578. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/erlang-DsQrWhSR.js +0 -0
  579. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/everforest-dark-BgDCqdQA.js +0 -0
  580. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/everforest-light-C8M2exoo.js +0 -0
  581. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/fennel-BYunw83y.js +0 -0
  582. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/fish-BvzEVeQv.js +0 -0
  583. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/fluent-C4IJs8-o.js +0 -0
  584. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/fortran-fixed-form-CkoXwp7k.js +0 -0
  585. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/fortran-free-form-BxgE0vQu.js +0 -0
  586. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/fsharp-CXgrBDvD.js +0 -0
  587. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gdresource-B7Tvp0Sc.js +0 -0
  588. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gdscript-DTMYz4Jt.js +0 -0
  589. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gdshader-DkwncUOv.js +0 -0
  590. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/genie-D0YGMca9.js +0 -0
  591. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gherkin-DyxjwDmM.js +0 -0
  592. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/git-commit-F4YmCXRG.js +0 -0
  593. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/git-rebase-r7XF79zn.js +0 -0
  594. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/github-dark-DHJKELXO.js +0 -0
  595. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/github-dark-default-Cuk6v7N8.js +0 -0
  596. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/github-dark-dimmed-DH5Ifo-i.js +0 -0
  597. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -0
  598. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/github-light-DAi9KRSo.js +0 -0
  599. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/github-light-default-D7oLnXFd.js +0 -0
  600. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/github-light-high-contrast-BfjtVDDH.js +0 -0
  601. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gleam-BspZqrRM.js +0 -0
  602. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/glimmer-js-Rg0-pVw9.js +0 -0
  603. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/glimmer-ts-U6CK756n.js +0 -0
  604. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/glsl-DplSGwfg.js +0 -0
  605. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gn-n2N0HUVH.js +0 -0
  606. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gnuplot-DdkO51Og.js +0 -0
  607. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/go-Dn2_MT6a.js +0 -0
  608. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/graphql-ChdNCCLP.js +0 -0
  609. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/groovy-gcz8RCvz.js +0 -0
  610. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -0
  611. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gruvbox-dark-medium-GsRaNv29.js +0 -0
  612. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gruvbox-dark-soft-CVdnzihN.js +0 -0
  613. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gruvbox-light-hard-CH1njM8p.js +0 -0
  614. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gruvbox-light-medium-DRw_LuNl.js +0 -0
  615. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/gruvbox-light-soft-hJgmCMqR.js +0 -0
  616. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/hack-CaT9iCJl.js +0 -0
  617. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/haml-B8DHNrY2.js +0 -0
  618. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/handlebars-BL8al0AC.js +0 -0
  619. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/haskell-Df6bDoY_.js +0 -0
  620. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/haxe-CzTSHFRz.js +0 -0
  621. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/hcl-BWvSN4gD.js +0 -0
  622. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/hjson-D5-asLiD.js +0 -0
  623. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/hlsl-D3lLCCz7.js +0 -0
  624. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/houston-DnULxvSX.js +0 -0
  625. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/html-GMplVEZG.js +0 -0
  626. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/html-derivative-BFtXZ54Q.js +0 -0
  627. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/http-jrhK8wxY.js +0 -0
  628. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/hurl-irOxFIW8.js +0 -0
  629. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/hxml-Bvhsp5Yf.js +0 -0
  630. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/hy-DFXneXwc.js +0 -0
  631. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/imba-DGztddWO.js +0 -0
  632. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/index-BpoLgcEt.js +0 -0
  633. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/index-CzV_vCfu.css +0 -0
  634. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/index-DI2oedCt.js +0 -0
  635. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/ini-BEwlwnbL.js +0 -0
  636. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/init-Gi6I4Gst.js +0 -0
  637. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  638. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  639. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  640. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  641. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  642. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  643. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  644. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/java-CylS5w8V.js +0 -0
  645. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/javascript-wDzz0qaB.js +0 -0
  646. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/jinja-4LBKfQ-Z.js +0 -0
  647. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/jison-wvAkD_A8.js +0 -0
  648. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/json-Cp-IABpG.js +0 -0
  649. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/json5-C9tS-k6U.js +0 -0
  650. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/jsonc-Des-eS-w.js +0 -0
  651. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/jsonl-DcaNXYhu.js +0 -0
  652. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/jsonnet-DFQXde-d.js +0 -0
  653. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/jssm-C2t-YnRu.js +0 -0
  654. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/jsx-g9-lgVsj.js +0 -0
  655. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/julia-CxzCAyBv.js +0 -0
  656. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/kanagawa-dragon-CkXjmgJE.js +0 -0
  657. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/kanagawa-lotus-CfQXZHmo.js +0 -0
  658. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/kanagawa-wave-DWedfzmr.js +0 -0
  659. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/katex-D2lIc1rk.css +0 -0
  660. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/kdl-DV7GczEv.js +0 -0
  661. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/kotlin-BdnUsdx6.js +0 -0
  662. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/kusto-DZf3V79B.js +0 -0
  663. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/laserwave-DUszq2jm.js +0 -0
  664. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/latex-B4uzh10-.js +0 -0
  665. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/lean-BZvkOJ9d.js +0 -0
  666. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/less-B1dDrJ26.js +0 -0
  667. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/light-plus-B7mTdjB0.js +0 -0
  668. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/liquid-DYVedYrR.js +0 -0
  669. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/llvm-BtvRca6l.js +0 -0
  670. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/log-2UxHyX5q.js +0 -0
  671. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/logo-BtOb2qkB.js +0 -0
  672. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/lua-BbnMAYS6.js +0 -0
  673. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/luau-C-HG3fhB.js +0 -0
  674. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/make-CHLpvVh8.js +0 -0
  675. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/markdown-Cvjx9yec.js +0 -0
  676. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/marko-DZsq8hO1.js +0 -0
  677. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/material-theme-D5KoaKCx.js +0 -0
  678. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/material-theme-darker-BfHTSMKl.js +0 -0
  679. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/material-theme-lighter-B0m2ddpp.js +0 -0
  680. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/material-theme-ocean-CyktbL80.js +0 -0
  681. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/material-theme-palenight-Csfq5Kiy.js +0 -0
  682. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/matlab-D7o27uSR.js +0 -0
  683. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/mdc-DUICxH0z.js +0 -0
  684. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/mdx-Cmh6b_Ma.js +0 -0
  685. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/mermaid-VLURNSYL-B2P5VJ9v.css +0 -0
  686. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/mermaid-mWjccvbQ.js +0 -0
  687. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/min-dark-CafNBF8u.js +0 -0
  688. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/min-light-CTRr51gU.js +0 -0
  689. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/mipsasm-CKIfxQSi.js +0 -0
  690. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/mojo-B93PlW-d.js +0 -0
  691. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/monokai-D4h5O-jR.js +0 -0
  692. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/moonbit-Ba13S78F.js +0 -0
  693. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/move-Bu9oaDYs.js +0 -0
  694. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/narrat-DRg8JJMk.js +0 -0
  695. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/nextflow-BrzmwbiE.js +0 -0
  696. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/nginx-DknmC5AR.js +0 -0
  697. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/night-owl-C39BiMTA.js +0 -0
  698. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/nim-CVrawwO9.js +0 -0
  699. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/nix-CwoSXNpI.js +0 -0
  700. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/nord-Ddv68eIx.js +0 -0
  701. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/nushell-C-sUppwS.js +0 -0
  702. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/objective-c-DXmwc3jG.js +0 -0
  703. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/objective-cpp-CLxacb5B.js +0 -0
  704. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/ocaml-C0hk2d4L.js +0 -0
  705. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/one-dark-pro-DVMEJ2y_.js +0 -0
  706. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/one-light-PoHY5YXO.js +0 -0
  707. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/openscad-C4EeE6gA.js +0 -0
  708. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/ordinal-Cboi1Yqb.js +0 -0
  709. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/pascal-D93ZcfNL.js +0 -0
  710. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/perl-C0TMdlhV.js +0 -0
  711. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/php-CDn_0X-4.js +0 -0
  712. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/pkl-u5AG7uiY.js +0 -0
  713. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/plastic-3e1v2bzS.js +0 -0
  714. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/plsql-ChMvpjG-.js +0 -0
  715. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/po-BTJTHyun.js +0 -0
  716. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/poimandres-CS3Unz2-.js +0 -0
  717. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/polar-C0HS_06l.js +0 -0
  718. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/postcss-CXtECtnM.js +0 -0
  719. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/powerquery-CEu0bR-o.js +0 -0
  720. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/powershell-Dpen1YoG.js +0 -0
  721. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/prisma-Dd19v3D-.js +0 -0
  722. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/prolog-CbFg5uaA.js +0 -0
  723. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/proto-C7zT0LnQ.js +0 -0
  724. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/pug-CGlum2m_.js +0 -0
  725. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/puppet-BMWR74SV.js +0 -0
  726. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/purescript-CklMAg4u.js +0 -0
  727. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/python-B6aJPvgy.js +0 -0
  728. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/qml-3beO22l8.js +0 -0
  729. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/qmldir-C8lEn-DE.js +0 -0
  730. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/qss-IeuSbFQv.js +0 -0
  731. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/r-Dspwwk_N.js +0 -0
  732. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/racket-BqYA7rlc.js +0 -0
  733. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/raku-DXvB9xmW.js +0 -0
  734. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/razor-C1TweQQi.js +0 -0
  735. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/red-bN70gL4F.js +0 -0
  736. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/reg-C-SQnVFl.js +0 -0
  737. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/regexp-CDVJQ6XC.js +0 -0
  738. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/rel-C3B-1QV4.js +0 -0
  739. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/riscv-BM1_JUlF.js +0 -0
  740. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/rose-pine-dawn-DHQR4-dF.js +0 -0
  741. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/rose-pine-moon-D4_iv3hh.js +0 -0
  742. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/rose-pine-qdsjHGoJ.js +0 -0
  743. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/rosmsg-BJDFO7_C.js +0 -0
  744. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/rst-B0xPkSld.js +0 -0
  745. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/ruby-BvKwtOVI.js +0 -0
  746. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/rust-B1yitclQ.js +0 -0
  747. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/sas-cz2c8ADy.js +0 -0
  748. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/sass-Cj5Yp3dK.js +0 -0
  749. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/scala-C151Ov-r.js +0 -0
  750. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/scheme-C98Dy4si.js +0 -0
  751. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/scss-OYdSNvt2.js +0 -0
  752. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/sdbl-DVxCFoDh.js +0 -0
  753. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/shaderlab-Dg9Lc6iA.js +0 -0
  754. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/shellscript-Yzrsuije.js +0 -0
  755. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/shellsession-BADoaaVG.js +0 -0
  756. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/slack-dark-BthQWCQV.js +0 -0
  757. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/slack-ochin-DqwNpetd.js +0 -0
  758. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/smalltalk-BERRCDM3.js +0 -0
  759. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/snazzy-light-Bw305WKR.js +0 -0
  760. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/solarized-dark-DXbdFlpD.js +0 -0
  761. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/solarized-light-L9t79GZl.js +0 -0
  762. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/solidity-rGO070M0.js +0 -0
  763. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/soy-Brmx7dQM.js +0 -0
  764. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/sparql-rVzFXLq3.js +0 -0
  765. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/splunk-BtCnVYZw.js +0 -0
  766. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/sql-BLtJtn59.js +0 -0
  767. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/ssh-config-_ykCGR6B.js +0 -0
  768. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/stata-BH5u7GGu.js +0 -0
  769. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/stylus-BEDo0Tqx.js +0 -0
  770. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/svelte-zxCyuUbr.js +0 -0
  771. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/swift-Dg5xB15N.js +0 -0
  772. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/synthwave-84-CbfX1IO0.js +0 -0
  773. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/system-verilog-CnnmHF94.js +0 -0
  774. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/systemd-4A_iFExJ.js +0 -0
  775. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/talonscript-CkByrt1z.js +0 -0
  776. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/tasl-QIJgUcNo.js +0 -0
  777. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/tcl-dwOrl1Do.js +0 -0
  778. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/templ-W15q3VgB.js +0 -0
  779. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/terraform-BETggiCN.js +0 -0
  780. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/tex-CvyZ59Mk.js +0 -0
  781. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/tokyo-night-hegEt444.js +0 -0
  782. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/toml-vGWfd6FD.js +0 -0
  783. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/ts-tags-zn1MmPIZ.js +0 -0
  784. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/tsv-B_m7g4N7.js +0 -0
  785. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/tsx-COt5Ahok.js +0 -0
  786. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/turtle-BsS91CYL.js +0 -0
  787. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/twig-CO9l9SDP.js +0 -0
  788. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/typescript-BPQ3VLAy.js +0 -0
  789. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/typespec-BGHnOYBU.js +0 -0
  790. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/typst-DHCkPAjA.js +0 -0
  791. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/v-BcVCzyr7.js +0 -0
  792. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/vala-CsfeWuGM.js +0 -0
  793. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/vb-D17OF-Vu.js +0 -0
  794. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/verilog-BQ8w6xss.js +0 -0
  795. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/vesper-DU1UobuO.js +0 -0
  796. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/vhdl-CeAyd5Ju.js +0 -0
  797. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/viml-CJc9bBzg.js +0 -0
  798. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/vitesse-black-Bkuqu6BP.js +0 -0
  799. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/vitesse-dark-D0r3Knsf.js +0 -0
  800. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/vitesse-light-CVO1_9PV.js +0 -0
  801. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/vue-DN_0RTcg.js +0 -0
  802. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/vue-html-AaS7Mt5G.js +0 -0
  803. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/vue-vine-CQOfvN7w.js +0 -0
  804. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/vyper-CDx5xZoG.js +0 -0
  805. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/wasm-CG6Dc4jp.js +0 -0
  806. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/wasm-MzD3tlZU.js +0 -0
  807. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/wenyan-BV7otONQ.js +0 -0
  808. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/wgsl-Dx-B1_4e.js +0 -0
  809. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/wikitext-BhOHFoWU.js +0 -0
  810. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/wit-5i3qLPDT.js +0 -0
  811. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/wolfram-lXgVvXCa.js +0 -0
  812. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/xml-sdJ4AIDG.js +0 -0
  813. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/xsl-CtQFsRM5.js +0 -0
  814. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/yaml-Buea-lGh.js +0 -0
  815. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/zenscript-DVFEvuxE.js +0 -0
  816. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/assets/zig-VOosw3JB.js +0 -0
  817. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/apple-touch-icon.png +0 -0
  818. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/arctecture.webp +0 -0
  819. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/bimi-logo.svg +0 -0
  820. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/favicon.ico +0 -0
  821. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/dm-sans-latin-ext.woff2 +0 -0
  822. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/dm-sans-latin.woff2 +0 -0
  823. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/instrument-sans-latin-ext.woff2 +0 -0
  824. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/instrument-sans-latin.woff2 +0 -0
  825. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/instrument-serif-latin-ext.woff2 +0 -0
  826. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/instrument-serif-latin.woff2 +0 -0
  827. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/libre-baskerville-italic-latin-ext.woff2 +0 -0
  828. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/libre-baskerville-italic-latin.woff2 +0 -0
  829. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/libre-baskerville-latin-ext.woff2 +0 -0
  830. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/libre-baskerville-latin.woff2 +0 -0
  831. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/roboto-latin-ext.woff2 +0 -0
  832. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/fonts/roboto-latin.woff2 +0 -0
  833. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/icon-192.png +0 -0
  834. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/icon-512.png +0 -0
  835. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/icon.svg +0 -0
  836. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/logo.png +0 -0
  837. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/pythinker_animated.svg +0 -0
  838. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/brand/robots.txt +0 -0
  839. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/static/logo.png +0 -0
  840. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/store/__init__.py +0 -0
  841. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/web/store/sessions.py +0 -0
  842. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/wire/__init__.py +0 -0
  843. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/wire/file.py +0 -0
  844. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/wire/jsonrpc.py +0 -0
  845. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/wire/protocol.py +0 -0
  846. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/wire/root_hub.py +0 -0
  847. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/wire/serde.py +0 -0
  848. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/wire/server.py +0 -0
  849. {pythinker_code-0.19.0 → pythinker_code-0.21.0}/src/pythinker_code/wire/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythinker-code
3
- Version: 0.19.0
3
+ Version: 0.21.0
4
4
  Summary: Pythinker Code is your next CLI agent.
5
5
  Keywords: cli,agent,ai,coding-assistant,llm,claude,openai,terminal
6
6
  Author: Mohamed Elkholy
@@ -79,7 +79,7 @@ Description-Content-Type: text/markdown
79
79
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-16a34a.svg?style=for-the-badge)](https://github.com/mohamed-elkholy95/Pythinker-Code/blob/main/LICENSE)
80
80
  [![CI](https://img.shields.io/github/actions/workflow/status/mohamed-elkholy95/Pythinker-Code/ci-pythinker-cli.yml?branch=main&label=CI&style=for-the-badge&logo=githubactions&logoColor=white)](https://github.com/mohamed-elkholy95/Pythinker-Code/actions/workflows/ci-pythinker-cli.yml?query=branch%3Amain)
81
81
 
82
- [![Downloads](https://img.shields.io/pepy/dt/pythinker-code?cacheSeconds=300)](https://pepy.tech/projects/pythinker-code)
82
+ [![PyPI downloads](https://assets.piptrends.com/get-last-month-downloads-badge/pythinker-code.svg)](https://piptrends.com/package/pythinker-code)
83
83
  [![Code style: Ruff](https://img.shields.io/badge/code%20style-ruff-f59e0b.svg?style=flat-square&logo=ruff&logoColor=white)](https://docs.astral.sh/ruff/)
84
84
  [![ACP ready](https://img.shields.io/badge/ACP-ready-7c3aed.svg?style=flat-square)](https://github.com/agentclientprotocol/agent-client-protocol)
85
85
  [![MCP tools](https://img.shields.io/badge/MCP-tools-0891b2.svg?style=flat-square)](https://modelcontextprotocol.io/)
@@ -115,14 +115,11 @@ It speaks the [**Agent Client Protocol (ACP)**](https://github.com/agentclientpr
115
115
 
116
116
  ---
117
117
 
118
- ## 🆕 What's New in 0.19.0
118
+ ## 🆕 What's New in 0.21.0
119
119
 
120
- - **Central per-project agent memory.** Pythinker now keeps a durable per-project memory (`MEMORY.md` / `USER.md`) under `~/.pythinker/projects/<key>/memory/`, written through a new root-only `Memory` tool with content guards and secret-shape detection, recalled into the root agent's first wakeup prompt within a bounded budget, and inspectable with the new `/memory` command.
121
- - **Non-blocking update flow.** The blocking pre-start update prompt is replaced by a cached, no-network startup notice plus a triggerable `/update` command, and the native Windows installer now waits on the launching process before swapping files and cleans up its staged installer.
122
- - **Fully native Homebrew formula.** Brew installs are generated from the same GitHub Release tarballs as the curl installer (including macOS Intel native assets), so they no longer depend on PyPI virtualenv resources.
123
- - **Release pipeline hardening.** TestPyPI publishing is now non-blocking and publish steps carry timeouts, so a transient staging flake no longer fails a release.
120
+ - **Non-blocking memory recall.** Recall I/O is now dispatched to a thread-pool executor, preventing the event loop from stalling during memory lookups. Sessions with large memory stores or slow disks will remain responsive throughout recall.
124
121
 
125
- Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.19.0`, or use the native installer for your platform from the [Releases page](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest).
122
+ Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.21.0`, or use the native installer for your platform from the [Releases page](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest).
126
123
 
127
124
 
128
125
  ---
@@ -212,7 +209,7 @@ matches your OS — no Python, Node, or `uv` prerequisite.
212
209
 
213
210
  | Platform | Recommended install | Artifact source |
214
211
  |---|---|---|
215
- | **🪟 Windows** | `irm https://pythinker.com/install.ps1 \| iex` | `PythinkerSetup-0.19.0.exe` from [Releases](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest) |
212
+ | **🪟 Windows** | `irm https://pythinker.com/install.ps1 \| iex` | `PythinkerSetup-0.21.0.exe` from [Releases](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest) |
216
213
  | **<img src="https://img.shields.io/badge/-macOS-000000?style=flat-square&logo=apple&logoColor=white" alt="macOS"> / <img src="https://img.shields.io/badge/-Linux-FCC624?style=flat-square&logo=linux&logoColor=black" alt="Linux">** | `curl -fsSL https://pythinker.com/install.sh \| bash` | native tarball from [Releases](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest) |
217
214
  | **<img src="https://img.shields.io/badge/-macOS-000000?style=flat-square&logo=apple&logoColor=white" alt="macOS"> — Homebrew** | `brew install mohamed-elkholy95/pythinker/pythinker-code` | auto-published Homebrew tap |
218
215
  | **<img src="https://img.shields.io/badge/-Linux-FCC624?style=flat-square&logo=linux&logoColor=black" alt="Linux"> — system package** | Download the `.deb` or `.rpm` for your distro below | [Releases](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest) |
@@ -237,7 +234,7 @@ pythinker # start the interactive TUI
237
234
 
238
235
  ### 🪟 Windows — native installer
239
236
 
240
- `PythinkerSetup-0.19.0.exe` is a signed* Inno Setup wizard. Installs per-user
237
+ `PythinkerSetup-0.21.0.exe` is a signed* Inno Setup wizard. Installs per-user
241
238
  into `%LOCALAPPDATA%\Programs\Pythinker`, registers `pythinker` on your user
242
239
  PATH (`HKCU\Environment`), broadcasts `WM_SETTINGCHANGE` so new shells see
243
240
  the change. **No UAC prompt.**
@@ -248,13 +245,13 @@ irm https://pythinker.com/install.ps1 | iex
248
245
 
249
246
  # Or manually download the installer + checksum from the Releases page,
250
247
  # verify with Get-FileHash, then run:
251
- .\PythinkerSetup-0.19.0.exe
248
+ .\PythinkerSetup-0.21.0.exe
252
249
 
253
250
  # Open a fresh PowerShell
254
251
  pythinker --version
255
252
  ```
256
253
 
257
- **Per-machine install** (IT-managed boxes): `.\PythinkerSetup-0.19.0.exe /ALLUSERS`
254
+ **Per-machine install** (IT-managed boxes): `.\PythinkerSetup-0.21.0.exe /ALLUSERS`
258
255
  installs to `%ProgramFiles%\Pythinker` and writes PATH to HKLM (requires admin).
259
256
 
260
257
  **Upgrade:** `pythinker update` from inside the running app — it downloads
@@ -305,26 +302,26 @@ attached to every GitHub Release.
305
302
 
306
303
  ```sh
307
304
  # Debian / Ubuntu (x86_64)
308
- sudo dpkg -i pythinker-code_0.19.0_amd64.deb
305
+ sudo dpkg -i pythinker-code_0.21.0_amd64.deb
309
306
  sudo apt-get install -f # only if dpkg reports missing deps
310
307
 
311
308
  # Debian / Ubuntu (ARM64)
312
- sudo dpkg -i pythinker-code_0.19.0_arm64.deb
309
+ sudo dpkg -i pythinker-code_0.21.0_arm64.deb
313
310
 
314
311
  # Fedora / RHEL / openSUSE (x86_64)
315
- curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.19.0/pythinker-code-0.19.0.x86_64.rpm
316
- curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.19.0/pythinker-code-0.19.0.x86_64.rpm.sha256
317
- sha256sum -c pythinker-code-0.19.0.x86_64.rpm.sha256
312
+ curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.21.0/pythinker-code-0.21.0.x86_64.rpm
313
+ curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.21.0/pythinker-code-0.21.0.x86_64.rpm.sha256
314
+ sha256sum -c pythinker-code-0.21.0.x86_64.rpm.sha256
318
315
  # Fedora / RHEL:
319
- sudo dnf install ./pythinker-code-0.19.0.x86_64.rpm
316
+ sudo dnf install ./pythinker-code-0.21.0.x86_64.rpm
320
317
  # openSUSE:
321
- sudo zypper install ./pythinker-code-0.19.0.x86_64.rpm
318
+ sudo zypper install ./pythinker-code-0.21.0.x86_64.rpm
322
319
 
323
320
  # Fedora / RHEL (aarch64)
324
- curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.19.0/pythinker-code-0.19.0.aarch64.rpm
325
- curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.19.0/pythinker-code-0.19.0.aarch64.rpm.sha256
326
- sha256sum -c pythinker-code-0.19.0.aarch64.rpm.sha256
327
- sudo dnf install ./pythinker-code-0.19.0.aarch64.rpm
321
+ curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.21.0/pythinker-code-0.21.0.aarch64.rpm
322
+ curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.21.0/pythinker-code-0.21.0.aarch64.rpm.sha256
323
+ sha256sum -c pythinker-code-0.21.0.aarch64.rpm.sha256
324
+ sudo dnf install ./pythinker-code-0.21.0.aarch64.rpm
328
325
  ```
329
326
 
330
327
  Both packages drop a small `/usr/bin/pythinker` launcher that execs the real
@@ -333,8 +330,8 @@ binary under `/usr/lib/pythinker/`, so your `$PATH` stays tidy.
333
330
  **Verify before install:**
334
331
 
335
332
  ```sh
336
- sha256sum -c pythinker-code_0.19.0_amd64.deb.sha256 # Debian/Ubuntu
337
- sha256sum -c pythinker-code-0.19.0.x86_64.rpm.sha256 # Fedora/RHEL
333
+ sha256sum -c pythinker-code_0.21.0_amd64.deb.sha256 # Debian/Ubuntu
334
+ sha256sum -c pythinker-code-0.21.0.x86_64.rpm.sha256 # Fedora/RHEL
338
335
  ```
339
336
 
340
337
  **Upgrade:** download the new `.deb`/`.rpm` from Releases and `dpkg -i` /
@@ -364,7 +361,7 @@ at `~/.local/bin/pythinker`.
364
361
  curl -fsSL https://pythinker.com/install.sh | bash
365
362
 
366
363
  # Pin a specific version
367
- curl -fsSL https://pythinker.com/install.sh | bash -s -- --version 0.19.0
364
+ curl -fsSL https://pythinker.com/install.sh | bash -s -- --version 0.21.0
368
365
 
369
366
  # Custom prefix (defaults to $HOME/.local)
370
367
  curl -fsSL https://pythinker.com/install.sh | bash -s -- --prefix /opt/pythinker
@@ -14,7 +14,7 @@
14
14
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-16a34a.svg?style=for-the-badge)](https://github.com/mohamed-elkholy95/Pythinker-Code/blob/main/LICENSE)
15
15
  [![CI](https://img.shields.io/github/actions/workflow/status/mohamed-elkholy95/Pythinker-Code/ci-pythinker-cli.yml?branch=main&label=CI&style=for-the-badge&logo=githubactions&logoColor=white)](https://github.com/mohamed-elkholy95/Pythinker-Code/actions/workflows/ci-pythinker-cli.yml?query=branch%3Amain)
16
16
 
17
- [![Downloads](https://img.shields.io/pepy/dt/pythinker-code?cacheSeconds=300)](https://pepy.tech/projects/pythinker-code)
17
+ [![PyPI downloads](https://assets.piptrends.com/get-last-month-downloads-badge/pythinker-code.svg)](https://piptrends.com/package/pythinker-code)
18
18
  [![Code style: Ruff](https://img.shields.io/badge/code%20style-ruff-f59e0b.svg?style=flat-square&logo=ruff&logoColor=white)](https://docs.astral.sh/ruff/)
19
19
  [![ACP ready](https://img.shields.io/badge/ACP-ready-7c3aed.svg?style=flat-square)](https://github.com/agentclientprotocol/agent-client-protocol)
20
20
  [![MCP tools](https://img.shields.io/badge/MCP-tools-0891b2.svg?style=flat-square)](https://modelcontextprotocol.io/)
@@ -50,14 +50,11 @@ It speaks the [**Agent Client Protocol (ACP)**](https://github.com/agentclientpr
50
50
 
51
51
  ---
52
52
 
53
- ## 🆕 What's New in 0.19.0
53
+ ## 🆕 What's New in 0.21.0
54
54
 
55
- - **Central per-project agent memory.** Pythinker now keeps a durable per-project memory (`MEMORY.md` / `USER.md`) under `~/.pythinker/projects/<key>/memory/`, written through a new root-only `Memory` tool with content guards and secret-shape detection, recalled into the root agent's first wakeup prompt within a bounded budget, and inspectable with the new `/memory` command.
56
- - **Non-blocking update flow.** The blocking pre-start update prompt is replaced by a cached, no-network startup notice plus a triggerable `/update` command, and the native Windows installer now waits on the launching process before swapping files and cleans up its staged installer.
57
- - **Fully native Homebrew formula.** Brew installs are generated from the same GitHub Release tarballs as the curl installer (including macOS Intel native assets), so they no longer depend on PyPI virtualenv resources.
58
- - **Release pipeline hardening.** TestPyPI publishing is now non-blocking and publish steps carry timeouts, so a transient staging flake no longer fails a release.
55
+ - **Non-blocking memory recall.** Recall I/O is now dispatched to a thread-pool executor, preventing the event loop from stalling during memory lookups. Sessions with large memory stores or slow disks will remain responsive throughout recall.
59
56
 
60
- Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.19.0`, or use the native installer for your platform from the [Releases page](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest).
57
+ Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.21.0`, or use the native installer for your platform from the [Releases page](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest).
61
58
 
62
59
 
63
60
  ---
@@ -147,7 +144,7 @@ matches your OS — no Python, Node, or `uv` prerequisite.
147
144
 
148
145
  | Platform | Recommended install | Artifact source |
149
146
  |---|---|---|
150
- | **🪟 Windows** | `irm https://pythinker.com/install.ps1 \| iex` | `PythinkerSetup-0.19.0.exe` from [Releases](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest) |
147
+ | **🪟 Windows** | `irm https://pythinker.com/install.ps1 \| iex` | `PythinkerSetup-0.21.0.exe` from [Releases](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest) |
151
148
  | **<img src="https://img.shields.io/badge/-macOS-000000?style=flat-square&logo=apple&logoColor=white" alt="macOS"> / <img src="https://img.shields.io/badge/-Linux-FCC624?style=flat-square&logo=linux&logoColor=black" alt="Linux">** | `curl -fsSL https://pythinker.com/install.sh \| bash` | native tarball from [Releases](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest) |
152
149
  | **<img src="https://img.shields.io/badge/-macOS-000000?style=flat-square&logo=apple&logoColor=white" alt="macOS"> — Homebrew** | `brew install mohamed-elkholy95/pythinker/pythinker-code` | auto-published Homebrew tap |
153
150
  | **<img src="https://img.shields.io/badge/-Linux-FCC624?style=flat-square&logo=linux&logoColor=black" alt="Linux"> — system package** | Download the `.deb` or `.rpm` for your distro below | [Releases](https://github.com/mohamed-elkholy95/Pythinker-Code/releases/latest) |
@@ -172,7 +169,7 @@ pythinker # start the interactive TUI
172
169
 
173
170
  ### 🪟 Windows — native installer
174
171
 
175
- `PythinkerSetup-0.19.0.exe` is a signed* Inno Setup wizard. Installs per-user
172
+ `PythinkerSetup-0.21.0.exe` is a signed* Inno Setup wizard. Installs per-user
176
173
  into `%LOCALAPPDATA%\Programs\Pythinker`, registers `pythinker` on your user
177
174
  PATH (`HKCU\Environment`), broadcasts `WM_SETTINGCHANGE` so new shells see
178
175
  the change. **No UAC prompt.**
@@ -183,13 +180,13 @@ irm https://pythinker.com/install.ps1 | iex
183
180
 
184
181
  # Or manually download the installer + checksum from the Releases page,
185
182
  # verify with Get-FileHash, then run:
186
- .\PythinkerSetup-0.19.0.exe
183
+ .\PythinkerSetup-0.21.0.exe
187
184
 
188
185
  # Open a fresh PowerShell
189
186
  pythinker --version
190
187
  ```
191
188
 
192
- **Per-machine install** (IT-managed boxes): `.\PythinkerSetup-0.19.0.exe /ALLUSERS`
189
+ **Per-machine install** (IT-managed boxes): `.\PythinkerSetup-0.21.0.exe /ALLUSERS`
193
190
  installs to `%ProgramFiles%\Pythinker` and writes PATH to HKLM (requires admin).
194
191
 
195
192
  **Upgrade:** `pythinker update` from inside the running app — it downloads
@@ -240,26 +237,26 @@ attached to every GitHub Release.
240
237
 
241
238
  ```sh
242
239
  # Debian / Ubuntu (x86_64)
243
- sudo dpkg -i pythinker-code_0.19.0_amd64.deb
240
+ sudo dpkg -i pythinker-code_0.21.0_amd64.deb
244
241
  sudo apt-get install -f # only if dpkg reports missing deps
245
242
 
246
243
  # Debian / Ubuntu (ARM64)
247
- sudo dpkg -i pythinker-code_0.19.0_arm64.deb
244
+ sudo dpkg -i pythinker-code_0.21.0_arm64.deb
248
245
 
249
246
  # Fedora / RHEL / openSUSE (x86_64)
250
- curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.19.0/pythinker-code-0.19.0.x86_64.rpm
251
- curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.19.0/pythinker-code-0.19.0.x86_64.rpm.sha256
252
- sha256sum -c pythinker-code-0.19.0.x86_64.rpm.sha256
247
+ curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.21.0/pythinker-code-0.21.0.x86_64.rpm
248
+ curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.21.0/pythinker-code-0.21.0.x86_64.rpm.sha256
249
+ sha256sum -c pythinker-code-0.21.0.x86_64.rpm.sha256
253
250
  # Fedora / RHEL:
254
- sudo dnf install ./pythinker-code-0.19.0.x86_64.rpm
251
+ sudo dnf install ./pythinker-code-0.21.0.x86_64.rpm
255
252
  # openSUSE:
256
- sudo zypper install ./pythinker-code-0.19.0.x86_64.rpm
253
+ sudo zypper install ./pythinker-code-0.21.0.x86_64.rpm
257
254
 
258
255
  # Fedora / RHEL (aarch64)
259
- curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.19.0/pythinker-code-0.19.0.aarch64.rpm
260
- curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.19.0/pythinker-code-0.19.0.aarch64.rpm.sha256
261
- sha256sum -c pythinker-code-0.19.0.aarch64.rpm.sha256
262
- sudo dnf install ./pythinker-code-0.19.0.aarch64.rpm
256
+ curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.21.0/pythinker-code-0.21.0.aarch64.rpm
257
+ curl -LO https://github.com/mohamed-elkholy95/Pythinker-Code/releases/download/v0.21.0/pythinker-code-0.21.0.aarch64.rpm.sha256
258
+ sha256sum -c pythinker-code-0.21.0.aarch64.rpm.sha256
259
+ sudo dnf install ./pythinker-code-0.21.0.aarch64.rpm
263
260
  ```
264
261
 
265
262
  Both packages drop a small `/usr/bin/pythinker` launcher that execs the real
@@ -268,8 +265,8 @@ binary under `/usr/lib/pythinker/`, so your `$PATH` stays tidy.
268
265
  **Verify before install:**
269
266
 
270
267
  ```sh
271
- sha256sum -c pythinker-code_0.19.0_amd64.deb.sha256 # Debian/Ubuntu
272
- sha256sum -c pythinker-code-0.19.0.x86_64.rpm.sha256 # Fedora/RHEL
268
+ sha256sum -c pythinker-code_0.21.0_amd64.deb.sha256 # Debian/Ubuntu
269
+ sha256sum -c pythinker-code-0.21.0.x86_64.rpm.sha256 # Fedora/RHEL
273
270
  ```
274
271
 
275
272
  **Upgrade:** download the new `.deb`/`.rpm` from Releases and `dpkg -i` /
@@ -299,7 +296,7 @@ at `~/.local/bin/pythinker`.
299
296
  curl -fsSL https://pythinker.com/install.sh | bash
300
297
 
301
298
  # Pin a specific version
302
- curl -fsSL https://pythinker.com/install.sh | bash -s -- --version 0.19.0
299
+ curl -fsSL https://pythinker.com/install.sh | bash -s -- --version 0.21.0
303
300
 
304
301
  # Custom prefix (defaults to $HOME/.local)
305
302
  curl -fsSL https://pythinker.com/install.sh | bash -s -- --prefix /opt/pythinker
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pythinker-code"
3
- version = "0.19.0"
3
+ version = "0.21.0"
4
4
  description = "Pythinker Code is your next CLI agent."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -15,6 +15,26 @@ GitHub Releases page; `0.8.0` is the new starting line.
15
15
 
16
16
  ## Unreleased
17
17
 
18
+ ## 0.21.0 (2026-05-28)
19
+
20
+ ### What changed in this release
21
+
22
+ - **Non-blocking memory recall.** Recall I/O is now dispatched to a thread-pool executor, preventing the event loop from stalling during memory lookups. Sessions with large memory stores or slow disks will remain responsive throughout recall.
23
+
24
+ Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.21.0`, or use the native installer for your OS (see the README install table).
25
+
26
+ ## 0.20.0 (2026-05-28)
27
+
28
+ ### What changed in this release
29
+
30
+ - **Ranked recall injection and Scratchpad working memory.** The memory subsystem gains a dependency-free lexical retriever, ranked recall injection replacing the previous verbatim memory dump, and a new root-only `Scratchpad` tool that lets the agent record structured notes across tool calls during a session.
31
+ - **Full memory lifecycle: Phases B–D.** A unified injection bus re-arms recall on every Memory or Scratchpad write (Phase B), session-end episodic recaps are harvested before compaction into a per-project journal (Phase C, off by default), and an approval-gated inbox consolidation flow (`/memory inbox`) proposes—but never auto-applies—memory merges (Phase D).
32
+ - **Context-aware and web-fresh agent subagents.** Code-reviewer, security-reviewer, coder, and plan specialists now mandate a context7-first / web-fallback freshness check before scoring third-party findings or writing against a library. The system prompt gains a Granular Todo discipline (one in-progress sub-todo per dispatched subagent) and an Engineering Discipline section.
33
+ - **Memory robustness hardening.** Compaction harvest failures are now isolated per-phase (a broken prepare step no longer silently cancels recall), inbox JSON-parse errors log and skip instead of dropping silently, and the recall injection bus uses a knapsack budget that continues filling with lower-priority candidates after a high-priority slot overflows.
34
+ - **Animated robot logo in all native installers.** The curl-bash and PowerShell native installers now display a Tetris-style animated robot-head logo on supported terminals, with a static fallback for CI, `NO_COLOR`, dumb-term, or `PYTHINKER_NO_ANIMATION=1`.
35
+
36
+ Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.20.0`, or use the native installer for your OS (see the README install table).
37
+
18
38
  ## 0.19.0 (2026-05-27)
19
39
 
20
40
  ### What changed in this release
@@ -13,6 +13,7 @@ agent:
13
13
  - "pythinker_code.tools.ask_user:AskUserQuestion"
14
14
  - "pythinker_code.tools.todo:SetTodoList"
15
15
  - "pythinker_code.tools.memory:Memory"
16
+ - "pythinker_code.tools.scratchpad:Scratchpad"
16
17
  - "pythinker_code.tools.shell:Shell"
17
18
  - "pythinker_code.tools.background:TaskList"
18
19
  - "pythinker_code.tools.background:TaskOutput"
@@ -23,6 +23,12 @@ agent:
23
23
  - Build a review context packet: base ref/diff scope, changed behavior, likely tests, user-visible impact, and validation evidence.
24
24
  - Flag only issues introduced or made reachable by the diff.
25
25
  - Prefer no finding over vague speculation. Every finding must cite concrete evidence and a failure mode.
26
+
27
+ Freshness check (run BEFORE flagging third-party library or framework misuse):
28
+ - For every third-party API, SDK call, framework primitive, or "best practice" the diff turns on, verify the current canonical usage. Prefer a context7 MCP query (e.g. `mcp__context7__query-docs` with the library id) when registered with the parent runtime; otherwise use `SearchWeb` to locate the official documentation and `FetchURL` to read the current page.
29
+ - Do NOT flag "deprecated", "removed", "wrong API", or "missing parameter" purely from training-cutoff memory. Either verify against the live docs and cite the URL in EVIDENCE, or downgrade the finding to RISKS with a "needs verification" note.
30
+ - The freshness check is itself read-only and bounded — one or two fetches per load-bearing finding is enough; do not crawl.
31
+ - Skip the check for purely internal-codebase findings (logic, scope, project conventions); it applies only to third-party-surface claims.
26
32
  - Do not request tests unless they cover a distinct behavior or risk introduced by the change.
27
33
  - Treat V0 robustness suggestions as future work unless they risk correctness, security, data loss, or persistent hangs.
28
34
  - For user-visible UI/behavior changes, check whether screenshots, GIFs, videos, or equivalent visual evidence are present; if absent, request that evidence as a blocking review concern.
@@ -48,6 +54,8 @@ agent:
48
54
  - "pythinker_code.tools.file:ReadFile"
49
55
  - "pythinker_code.tools.file:Grep"
50
56
  - "pythinker_code.tools.skill:ReadSkill"
57
+ - "pythinker_code.tools.web:SearchWeb"
58
+ - "pythinker_code.tools.web:FetchURL"
51
59
  exclude_tools:
52
60
  - "pythinker_code.tools.file:WriteFile"
53
61
  - "pythinker_code.tools.file:StrReplaceFile"
@@ -14,6 +14,7 @@ agent:
14
14
 
15
15
  Implementation method:
16
16
  - Before editing, read the target files and confirm the line ranges/patterns you will change.
17
+ - Before writing against a third-party library, SDK, cloud service, or framework, pull its current API docs first. Prefer a context7 MCP query (e.g. `mcp__context7__query-docs` with the library id) when registered with the parent runtime; otherwise use `SearchWeb` to find the official docs and `FetchURL` to read the current page. Do NOT write API calls from training-cutoff memory for surfaces that move (LLM SDKs, cloud SDKs, web frameworks, ORM/migration tools, anything < 2 years old). Cite the doc URL or context7 result in EVIDENCE.
17
18
  - Prefer StrReplaceFile for narrow changes; use WriteFile only for new files or intentional full rewrites.
18
19
  - Add or update tests when the brief requires behavior changes and the project has relevant tests.
19
20
  - After edits, inspect the diff/changed files for scope creep, TODOs/placeholders, import mistakes, and logic mismatches.
@@ -21,6 +21,12 @@ agent:
21
21
  - For every task, include artifacts to change, acceptance criteria, suggested specialist (`explore`, `implementer`, `review`, `security-reviewer`, `debugger`, `verifier`), and the smallest verification command/check.
22
22
  - Call out risks, blockers, migration/backward-compatibility concerns, and test gaps.
23
23
 
24
+ Library/API freshness (run BEFORE recommending an external dependency or API surface):
25
+ - For every third-party library, SDK, framework, or cloud service the plan turns on (new dep, version bump, non-trivial API surface, security-sensitive primitive), pull the current docs first. Prefer a context7 MCP query (e.g. `mcp__context7__query-docs` with the library id) when registered with the parent runtime; otherwise use `SearchWeb` to find the official docs and `FetchURL` to read the current page.
26
+ - Do NOT plan around an API from training-cutoff memory if it has moved (LLM SDKs, cloud SDKs, web frameworks, ORM/migration tools). Verify the call shape, supported versions, and any documented migration path.
27
+ - Cite the doc reference inline next to the task that depends on it, in EVIDENCE.
28
+ - When the freshness check changes the plan (e.g. an API was removed, a new auth flow is mandated), call it out in RISKS as a constraint the implementer must honor.
29
+
24
30
  Ground the plan in evidence. Read enough files to avoid guessing, name the trade-offs, and choose one path with a reason. Each step should name the artifact it changes and the verification that proves it worked. Order steps by dependency first, then by risk reduced per effort.
25
31
 
26
32
  Final response contract:
@@ -22,6 +22,13 @@ agent:
22
22
  - Check graceful degradation, observability/logging, recovery behavior, structured result/status correctness, and approval/policy mismatches when they affect security posture.
23
23
  - Translate JSON output into the structured response block below.
24
24
 
25
+ Latest advisory pull (run BEFORE finalizing severity):
26
+ - Identify every third-party surface in the diff: dependencies (pyproject/requirements/lock), SDK calls, framework primitives, crypto/auth helpers, network/serialization libs.
27
+ - For each surface, pull current advisories and release notes. Prefer a context7 MCP query (e.g. `mcp__context7__query-docs` with the library id) when registered with the parent runtime; otherwise use `SearchWeb` for the latest CVE/GHSA/security-advisory bulletin and `FetchURL` for the canonical advisory text.
28
+ - Never cite a CVE, GHSA id, or "X is patched in vY" claim from memory alone — verify against the live advisory body. If the network is unavailable, omit the citation and record it under RISKS as a coverage gap.
29
+ - For framework-specific threat patterns, the reference is `blackbox/pythinker-security-scanner` (especially `docs/supported-tech.md` threat highlights and `packages/scanner/src/matchers/`). Cross-check the diff against the relevant tech tag's highlights.
30
+ - Web fetches must be evidence, not chatter: cite the URL inline in EVIDENCE when a finding turns on a current advisory.
31
+
25
32
  Final response contract:
26
33
  ### SUMMARY
27
34
  One paragraph: number and severity of security findings, what the parent should fix first.
@@ -39,6 +46,8 @@ agent:
39
46
  - "pythinker_code.tools.shell:Shell"
40
47
  - "pythinker_code.tools.file:ReadFile"
41
48
  - "pythinker_code.tools.file:Grep"
49
+ - "pythinker_code.tools.web:SearchWeb"
50
+ - "pythinker_code.tools.web:FetchURL"
42
51
  exclude_tools:
43
52
  - "pythinker_code.tools.file:WriteFile"
44
53
  - "pythinker_code.tools.file:StrReplaceFile"
@@ -39,6 +39,37 @@ For any codebase, architecture, debugging, security, performance, planning, or "
39
39
 
40
40
  **Professional handoff format:** For substantial tasks, keep a visible plan/todo and structure work as `context -> assessment -> plan -> execution -> verification -> residual risks`. Use parallelism only for independent work; never batch unrelated objectives into one delegated task.
41
41
 
42
+ # Engineering Discipline
43
+
44
+ These principles govern every engineering response. They override speed: a slow right answer beats a fast wrong one.
45
+
46
+ **1. Think before coding — don't assume, don't hide confusion, surface tradeoffs.**
47
+ - State your assumptions explicitly before implementing. If uncertain, ask.
48
+ - If the request admits multiple interpretations, present them — don't pick one silently.
49
+ - If a simpler approach exists than what the user proposed, say so before building the complex one. Push back when warranted.
50
+ - If something is unclear, stop. Name what's confusing. Ask one focused question.
51
+ - Clarifying questions belong **before** implementation, not after mistakes.
52
+
53
+ **2. Simplicity first — minimum code that solves the problem, nothing speculative.**
54
+ - No features beyond what was asked.
55
+ - No abstractions for single-use code.
56
+ - No "flexibility" or "configurability" that wasn't requested.
57
+ - No error handling for impossible scenarios; validate at boundaries only.
58
+ - If a 200-line draft could be 50 lines, rewrite it before showing it.
59
+ - Self-check: *"Would a senior engineer call this overcomplicated?"* If yes, simplify.
60
+
61
+ **3. Goal-driven execution — define success criteria, then loop until verified.**
62
+ - Transform vague tasks into verifiable goals before writing code:
63
+ - "Add validation" → "Write tests for invalid inputs, then make them pass."
64
+ - "Fix the bug" → "Write a test that reproduces it, then make it pass."
65
+ - "Refactor X" → "Ensure tests pass before and after; behavior identical."
66
+ - "Make it faster" → "Benchmark current, set target, prove improvement on same inputs."
67
+ - For multi-step work, state the plan inline as `Step → verify: check`, then execute against it.
68
+ - "It compiles" is not verification. "It type-checks" is not verification. Verification is a passing test, a working repro, or a deterministic command that confirms the intended behavior.
69
+ - Don't claim done without proof. If verification can't run, say so explicitly under BLOCKERS instead of asserting success.
70
+
71
+ These principles are working if: diffs contain only requested changes, fewer rewrites land because of overcomplication, and clarifying questions appear before the first edit rather than after the first mistake.
72
+
42
73
  # Prompt and Tool Use
43
74
 
44
75
  The user's messages may contain questions and/or task descriptions in natural language, code snippets, logs, file paths, or other forms of information. Read them, understand them and do what the user requested. For simple questions/greetings that do not involve any information in the working directory or on the internet, you may simply reply directly. For anything else, default to taking action with tools. When the request could be interpreted as either a question to answer or a task to complete, treat it as a task.
@@ -59,6 +90,8 @@ For any non-trivial request, decompose before acting:
59
90
 
60
91
  - Preview the terrain first: scan the directory structure, file headers, and relevant module boundaries before choosing an implementation path.
61
92
  - Use `SetTodoList` for multi-step work so the user can see the active plan and progress.
93
+ - **Granular todos, not umbrella todos.** Each todo must name a single concrete deliverable a human can recognize as "this part is done." Avoid umbrella titles like "Determine X" or "Investigate Y" that cover hours of parallel work — they freeze the progress UI while real work happens underneath. If a single todo would stay `in_progress` for more than ~3 minutes, it is too coarse: split it before launching work.
94
+ - **One todo per dispatched child.** When you launch `RunAgents` with N children, the visible todo list MUST contain one in_progress sub-todo per child (or per independent objective the batch covers) **before** the batch starts. Update each sub-todo to `done` as that child returns — do not wait for the whole batch to finish to flip a single umbrella todo. Same rule applies to multiple parallel `Agent` calls in the same turn.
62
95
  - Split broad work into independent chunks; use parallel tool calls or focused subagents for chunks that do not depend on each other.
63
96
  - For large codebase scans, start with indexes/graphs and targeted searches; avoid one vague repo-wide subagent prompt. If using background agents for thorough exploration, set a realistic explicit timeout and keep scopes narrow. If agents time out, do not repeat the same broad launch; summarize partial evidence, run targeted direct scans, and resume or relaunch narrower agents only when useful.
64
97
  - Re-read the plan after each phase and adjust it when new evidence changes the approach.
@@ -345,13 +345,11 @@ class PythinkerCLI:
345
345
 
346
346
  soul = PythinkerSoul(agent, context=context)
347
347
 
348
- from pythinker_code.project_memory import (
349
- ProjectMemoryInjectionProvider,
350
- ProjectMemoryStore,
351
- )
348
+ from pythinker_code.memory.recall import RecallInjectionProvider
349
+ from pythinker_code.project_memory import ProjectMemoryStore
352
350
 
353
351
  soul.add_injection_provider(
354
- ProjectMemoryInjectionProvider(ProjectMemoryStore(session.work_dir))
352
+ RecallInjectionProvider(ProjectMemoryStore(session.work_dir), session)
355
353
  )
356
354
 
357
355
  # Activate plan mode if requested (for new sessions or --plan flag)
@@ -907,7 +907,20 @@ def pythinker(
907
907
  # Session scratchpads are retained as compact history for future recall.
908
908
  # ``cleanup_scratchpad`` is kept for call-site compatibility but no longer
909
909
  # triggers automatic deletion after a successful run.
910
- _ = cleanup_scratchpad, exit_code
910
+ _ = cleanup_scratchpad
911
+ if exit_code == ExitCode.SUCCESS and getattr(
912
+ getattr(config, "memory", None), "journal_recaps", False
913
+ ):
914
+ with contextlib.suppress(Exception):
915
+ from pythinker_code.memory.recap import build_session_recap
916
+ from pythinker_code.project_memory import ProjectMemoryStore
917
+
918
+ recap = build_session_recap(
919
+ state=last_session.state,
920
+ session_id=last_session.id,
921
+ request=last_session.title,
922
+ )
923
+ await ProjectMemoryStore(last_session.work_dir).append_journal(recap)
911
924
  _print_resume_hint(last_session)
912
925
  if last_session.is_empty():
913
926
  # Always clean up empty sessions regardless of exit code
@@ -135,6 +135,38 @@ class NotificationConfig(BaseModel):
135
135
  claim_stale_after_ms: int = Field(default=15_000, ge=1000)
136
136
 
137
137
 
138
+ class MemoryConfig(BaseModel):
139
+ """Context- and memory-aware agent configuration."""
140
+
141
+ lexical_recall: bool = Field(
142
+ default=True,
143
+ description="Use relevance-ranked lexical recall instead of verbatim project memory.",
144
+ )
145
+ injection_bus: bool = Field(
146
+ default=True,
147
+ description="Budget dynamic prompt injections through the injection bus.",
148
+ )
149
+ injection_ceiling_tokens: int = Field(
150
+ default=2048,
151
+ ge=256,
152
+ description="Maximum total tokens reserved for dynamic prompt injections.",
153
+ )
154
+ harvest_on_compaction: bool = Field(
155
+ default=False,
156
+ description=(
157
+ "Persist safe decisions/blockers/next steps before compaction discards history."
158
+ ),
159
+ )
160
+ journal_recaps: bool = Field(
161
+ default=False,
162
+ description="Write stable-schema JOURNAL.md session recap blocks.",
163
+ )
164
+ consolidation: bool = Field(
165
+ default=False,
166
+ description="Enable approval-gated memory inbox consolidation helpers.",
167
+ )
168
+
169
+
138
170
  class PythinkerAISearchConfig(BaseModel):
139
171
  """Pythinker AI Search configuration."""
140
172
 
@@ -324,6 +356,7 @@ class Config(BaseModel):
324
356
  default_factory=NotificationConfig, description="Notification configuration"
325
357
  )
326
358
  services: Services = Field(default_factory=Services, description="Services configuration")
359
+ memory: MemoryConfig = Field(default_factory=MemoryConfig, description="Memory configuration")
327
360
  feedback: FeedbackConfig = Field(
328
361
  default_factory=FeedbackConfig,
329
362
  description="User-submitted feedback endpoint configuration",
@@ -0,0 +1 @@
1
+ """Context- & memory-aware agent subsystem (retrieval, recall, sanitization)."""
@@ -0,0 +1,115 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import os
5
+ import re
6
+ from dataclasses import asdict, dataclass
7
+ from pathlib import Path
8
+
9
+ from loguru import logger
10
+ from pythinker_host.path import HostPath
11
+
12
+ from pythinker_code.memory.recall import gather_candidates
13
+ from pythinker_code.memory.recap import content_hash
14
+ from pythinker_code.project_memory import ProjectMemoryStore
15
+
16
+
17
+ @dataclass(frozen=True, slots=True)
18
+ class InboxCandidate:
19
+ id: str
20
+ target: str
21
+ title: str
22
+ content: str
23
+ source_path: str
24
+ content_hash: str
25
+
26
+
27
+ def _safe_id(value: str) -> str:
28
+ return re.sub(r"[^a-z0-9_-]", "-", value.lower())[:32].strip("-") or "candidate"
29
+
30
+
31
+ async def inbox_dir(store: ProjectMemoryStore) -> Path:
32
+ root = await store._ensure_dir() # pyright: ignore[reportPrivateUsage]
33
+ path = root / "memory" / "inbox"
34
+ path.mkdir(parents=True, exist_ok=True)
35
+ return path
36
+
37
+
38
+ async def list_inbox_candidates(store: ProjectMemoryStore) -> list[InboxCandidate]:
39
+ directory = await inbox_dir(store)
40
+ out: list[InboxCandidate] = []
41
+ for path in sorted(directory.glob("*.json")):
42
+ try:
43
+ data = json.loads(path.read_text(encoding="utf-8"))
44
+ out.append(InboxCandidate(**data))
45
+ except Exception as exc:
46
+ logger.debug("inbox candidate {} dropped during listing: {!r}", path.name, exc)
47
+ continue
48
+ return out
49
+
50
+
51
+ async def generate_inbox_candidates(
52
+ store: ProjectMemoryStore, work_dir: HostPath, *, limit: int = 20
53
+ ) -> list[InboxCandidate]:
54
+ """Stage scratch/journal candidates for approval-gated durable memory consolidation."""
55
+ existing_entries = [*await store.read_entries("memory"), *await store.read_entries("user")]
56
+ existing_hashes = {
57
+ content_hash(tier="memory", title=entry[:60], body=entry) for entry in existing_entries
58
+ }
59
+ staged = {candidate.content_hash for candidate in await list_inbox_candidates(store)}
60
+ directory = await inbox_dir(store)
61
+ candidates: list[InboxCandidate] = []
62
+ for block in await gather_candidates(store, work_dir):
63
+ if block.tier in {"memory", "user"}:
64
+ continue
65
+ digest = content_hash(tier="memory", title=block.title, body=block.content)
66
+ if digest in existing_hashes or digest in staged:
67
+ continue
68
+ candidate = InboxCandidate(
69
+ id=_safe_id(digest),
70
+ target="memory",
71
+ title=block.title or block.tier,
72
+ content=block.content,
73
+ source_path=block.source_path,
74
+ content_hash=digest,
75
+ )
76
+ path = directory / f"{candidate.id}.json"
77
+ fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
78
+ with os.fdopen(fd, "w", encoding="utf-8") as fh:
79
+ json.dump(asdict(candidate), fh, ensure_ascii=False, indent=2)
80
+ candidates.append(candidate)
81
+ staged.add(digest)
82
+ if len(candidates) >= limit:
83
+ break
84
+ return candidates
85
+
86
+
87
+ async def approve_inbox_candidate(store: ProjectMemoryStore, candidate_id: str) -> str:
88
+ directory = await inbox_dir(store)
89
+ path = directory / f"{_safe_id(candidate_id)}.json"
90
+ if not path.is_file():
91
+ return "Candidate not found."
92
+ try:
93
+ data = json.loads(path.read_text(encoding="utf-8"))
94
+ candidate = InboxCandidate(**data)
95
+ except Exception as exc:
96
+ logger.warning(
97
+ "inbox candidate {} rejected on approve due to parse error: {!r}",
98
+ path.name,
99
+ exc,
100
+ )
101
+ return "Candidate file is corrupt and cannot be approved."
102
+ result = await store.add("memory", candidate.content)
103
+ if not result.ok:
104
+ return result.message
105
+ path.unlink(missing_ok=True)
106
+ return "Candidate approved and added to project memory."
107
+
108
+
109
+ async def reject_inbox_candidate(store: ProjectMemoryStore, candidate_id: str) -> str:
110
+ directory = await inbox_dir(store)
111
+ path = directory / f"{_safe_id(candidate_id)}.json"
112
+ if not path.is_file():
113
+ return "Candidate not found."
114
+ path.unlink(missing_ok=True)
115
+ return "Candidate rejected."