pythinker-code 0.26.0__tar.gz → 0.27.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 (850) hide show
  1. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/PKG-INFO +29 -29
  2. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/README.md +25 -25
  3. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/pyproject.toml +4 -4
  4. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/CHANGELOG.md +30 -0
  5. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/default/system.md +2 -1
  6. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/background/manager.py +83 -66
  7. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/background/store.py +13 -0
  8. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/background/worker.py +32 -38
  9. pythinker_code-0.27.0/src/pythinker_code/feedback.py +587 -0
  10. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/memory/consolidation.py +18 -7
  11. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/memory/recall.py +0 -4
  12. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/memory/retriever.py +9 -16
  13. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/project_memory.py +4 -0
  14. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/pythinkersoul.py +68 -63
  15. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/toolset.py +5 -8
  16. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/replace.md +1 -0
  17. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/replace.py +44 -12
  18. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/__init__.py +55 -12
  19. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/echo.py +1 -1
  20. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/export_import.py +5 -4
  21. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/prompt.py +4 -2
  22. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/session_picker.py +5 -0
  23. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/setup.py +5 -4
  24. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/slash.py +123 -6
  25. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/task_browser.py +2 -1
  26. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/update.py +119 -14
  27. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage.py +3 -1
  28. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/_interactive.py +2 -2
  29. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/_baseUniq-BV0IcpWE.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/_baseUniq-DMfW9l69.js +1 -1
  30. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/arc-Cyrtvkp5.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/arc-CNnQ_qgI.js +1 -1
  31. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/architectureDiagram-VXUJARFQ-C6WJgnXC.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/architectureDiagram-VXUJARFQ-PQYSR_Co.js +1 -1
  32. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/blockDiagram-VD42YOAC-GQd1_IMc.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/blockDiagram-VD42YOAC-dWpUsIm1.js +1 -1
  33. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/c4Diagram-YG6GDRKO-B47mx86g.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/c4Diagram-YG6GDRKO-FAUDt5mg.js +1 -1
  34. pythinker_code-0.27.0/src/pythinker_code/web/static/assets/channel-d_JMQytX.js +1 -0
  35. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/chunk-4BX2VUAB-Cy5x8E1K.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/chunk-4BX2VUAB-DRApifnv.js +1 -1
  36. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/chunk-55IACEB6-DifqgNgE.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/chunk-55IACEB6-C176nFT5.js +1 -1
  37. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/chunk-B4BG7PRW-r0-BeGnv.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/chunk-B4BG7PRW-DRkAssSa.js +1 -1
  38. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/chunk-DI55MBZ5-XWQHVeUW.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/chunk-DI55MBZ5-B0_beBOr.js +1 -1
  39. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/chunk-FMBD7UC4-CA_nMgAr.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/chunk-FMBD7UC4-C1rSyssd.js +1 -1
  40. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/chunk-QN33PNHL-CJveaI0H.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/chunk-QN33PNHL-WrQm9ejt.js +1 -1
  41. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/chunk-QZHKN3VN-C1sAjmrf.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/chunk-QZHKN3VN-Df-UuTwz.js +1 -1
  42. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/chunk-TZMSLE5B-dYY99i90.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/chunk-TZMSLE5B-BjFtBBPf.js +1 -1
  43. pythinker_code-0.27.0/src/pythinker_code/web/static/assets/classDiagram-2ON5EDUG-MtuanyI0.js +1 -0
  44. pythinker_code-0.27.0/src/pythinker_code/web/static/assets/classDiagram-v2-WZHVMYZB-MtuanyI0.js +1 -0
  45. pythinker_code-0.27.0/src/pythinker_code/web/static/assets/clone-Va3amHzi.js +1 -0
  46. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/code-block-IT6T5CEO-CtrXu_Qg.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/code-block-IT6T5CEO-BRYo-pOg.js +1 -1
  47. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/cose-bilkent-S5V4N54A-Ka1axIdw.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/cose-bilkent-S5V4N54A-DhRlqauq.js +1 -1
  48. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/cytoscape.esm-CYgRHX5l.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/cytoscape.esm-BFVia8Ox.js +1 -1
  49. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/dagre-6UL2VRFP-DxeUvDkL.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/dagre-6UL2VRFP-Ch9fNJcv.js +1 -1
  50. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/diagram-PSM6KHXK-UpoQP3fh.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/diagram-PSM6KHXK-CSI-D5SY.js +1 -1
  51. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/diagram-QEK2KX5R-rexPrmXt.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/diagram-QEK2KX5R-PZR1OjEn.js +1 -1
  52. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/diagram-S2PKOQOG-Bqsmg2Ru.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/diagram-S2PKOQOG-VR2QNfAH.js +1 -1
  53. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/erDiagram-Q2GNP2WA-B0XOb2uZ.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/erDiagram-Q2GNP2WA-B4HWjVZz.js +1 -1
  54. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/flowDiagram-NV44I4VS-CcOatfXl.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/flowDiagram-NV44I4VS-DQcqtixb.js +1 -1
  55. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/ganttDiagram-JELNMOA3-D1YtSUzx.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/ganttDiagram-JELNMOA3-B9f8DQ6x.js +1 -1
  56. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/gitGraphDiagram-NY62KEGX-VZLZurNq.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/gitGraphDiagram-NY62KEGX-Bg4pzbTs.js +1 -1
  57. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/graph-CqflUrXP.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/graph-C9kGixri.js +1 -1
  58. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/index-BYhDBSlX.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/index--efV__RQ.js +1 -1
  59. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/index-CJApTS5K.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/index-2vWeToDr.js +1 -1
  60. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/index-CddeEW2V.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/index-Dn_nK-59.js +2 -2
  61. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/infoDiagram-WHAUD3N6-CBaPkiOc.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/infoDiagram-WHAUD3N6-Bhq_AB7C.js +1 -1
  62. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/journeyDiagram-XKPGCS4Q-Dk3pQbWG.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/journeyDiagram-XKPGCS4Q-DIRspuBf.js +1 -1
  63. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/kanban-definition-3W4ZIXB7-DP_5IDy5.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/kanban-definition-3W4ZIXB7-Dio69EXI.js +1 -1
  64. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/layout-YlHbm7XF.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/layout-D297gqp3.js +1 -1
  65. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/linear-BDRfWBAl.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/linear-DqxkCJMI.js +1 -1
  66. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/mermaid-VLURNSYL-DyUoFCBx.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/mermaid-VLURNSYL-D5Ytdlln.js +7 -7
  67. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/mermaid.core-COuleAQZ.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/mermaid.core-D8hbsme0.js +5 -5
  68. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/min-BGh5aeLW.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/min-Bh6x6hFE.js +1 -1
  69. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/mindmap-definition-VGOIOE7T-C6QBRyVb.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/mindmap-definition-VGOIOE7T-Pz_BTd5r.js +1 -1
  70. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/pieDiagram-ADFJNKIX-CSNHu75h.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/pieDiagram-ADFJNKIX-CnlRsjSR.js +1 -1
  71. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/quadrantDiagram-AYHSOK5B-D5XNXTa7.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/quadrantDiagram-AYHSOK5B-fnwm0VTI.js +1 -1
  72. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/requirementDiagram-UZGBJVZJ-BMcLVFmN.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/requirementDiagram-UZGBJVZJ-DHMgAblB.js +1 -1
  73. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/sankeyDiagram-TZEHDZUN-BurCLwEY.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/sankeyDiagram-TZEHDZUN-CZHPPGSM.js +1 -1
  74. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/sequenceDiagram-WL72ISMW-B2M0ZAUV.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/sequenceDiagram-WL72ISMW-CTSHj8Ll.js +1 -1
  75. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/stateDiagram-FKZM4ZOC-vdkc_FHq.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/stateDiagram-FKZM4ZOC-BHXHgUPH.js +1 -1
  76. pythinker_code-0.27.0/src/pythinker_code/web/static/assets/stateDiagram-v2-4FDKWEC3-BGInGpxc.js +1 -0
  77. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/timeline-definition-IT6M3QCI-CXwebPi6.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/timeline-definition-IT6M3QCI-Dngdul0S.js +1 -1
  78. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/treemap-KMMF4GRG-s78Ox8eo.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/treemap-KMMF4GRG-RF3499L1.js +1 -1
  79. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/xychartDiagram-PRI3JC2R-B8BvWA5q.js → pythinker_code-0.27.0/src/pythinker_code/web/static/assets/xychartDiagram-PRI3JC2R-Di8-sSQy.js +1 -1
  80. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/index.html +1 -1
  81. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/install.ps1 +1 -1
  82. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/install.sh +1 -1
  83. pythinker_code-0.26.0/src/pythinker_code/memory/retriever_sqlite.py +0 -42
  84. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/channel-BUTOao-m.js +0 -1
  85. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/classDiagram-2ON5EDUG-CLIe0T4n.js +0 -1
  86. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/classDiagram-v2-WZHVMYZB-CLIe0T4n.js +0 -1
  87. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/clone-BjWb914D.js +0 -1
  88. pythinker_code-0.26.0/src/pythinker_code/web/static/assets/stateDiagram-v2-4FDKWEC3-C6C4PIor.js +0 -1
  89. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/LICENSE +0 -0
  90. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/NOTICE +0 -0
  91. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/__init__.py +0 -0
  92. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/__main__.py +0 -0
  93. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/acp/AGENTS.md +0 -0
  94. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/acp/__init__.py +0 -0
  95. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/acp/convert.py +0 -0
  96. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/acp/host.py +0 -0
  97. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/acp/mcp.py +0 -0
  98. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/acp/server.py +0 -0
  99. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/acp/session.py +0 -0
  100. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/acp/tools.py +0 -0
  101. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/acp/types.py +0 -0
  102. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/acp/version.py +0 -0
  103. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/default/agent.yaml +0 -0
  104. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/default/code_reviewer.yaml +0 -0
  105. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/default/coder.yaml +0 -0
  106. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/default/debugger.yaml +0 -0
  107. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/default/explore.yaml +0 -0
  108. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/default/implementer.yaml +0 -0
  109. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/default/plan.yaml +0 -0
  110. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/default/review.yaml +0 -0
  111. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/default/security_reviewer.yaml +0 -0
  112. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/default/verifier.yaml +0 -0
  113. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agents/okabe/agent.yaml +0 -0
  114. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/agentspec.py +0 -0
  115. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/app.py +0 -0
  116. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/approval_runtime/__init__.py +0 -0
  117. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/approval_runtime/models.py +0 -0
  118. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/approval_runtime/runtime.py +0 -0
  119. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/__init__.py +0 -0
  120. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/anthropic_direct.py +0 -0
  121. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/deepseek.py +0 -0
  122. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/github_feedback.py +0 -0
  123. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/lm_studio.py +0 -0
  124. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/minimax.py +0 -0
  125. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/oauth.py +0 -0
  126. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/ollama.py +0 -0
  127. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/openai.py +0 -0
  128. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/opencode_go.py +0 -0
  129. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/openrouter.py +0 -0
  130. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/auth/platforms.py +0 -0
  131. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/background/__init__.py +0 -0
  132. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/background/agent_runner.py +0 -0
  133. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/background/ids.py +0 -0
  134. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/background/models.py +0 -0
  135. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/background/summary.py +0 -0
  136. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/__init__.py +0 -0
  137. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/__main__.py +0 -0
  138. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/_lazy_group.py +0 -0
  139. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/debug.py +0 -0
  140. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/export.py +0 -0
  141. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/info.py +0 -0
  142. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/mcp.py +0 -0
  143. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/plugin.py +0 -0
  144. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/review.py +0 -0
  145. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/secscan.py +0 -0
  146. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/security_scan.py +0 -0
  147. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/skill.py +0 -0
  148. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/toad.py +0 -0
  149. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/update.py +0 -0
  150. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/vis.py +0 -0
  151. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/cli/web.py +0 -0
  152. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/config.py +0 -0
  153. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/constant.py +0 -0
  154. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/events.py +0 -0
  155. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/exception.py +0 -0
  156. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/execution_profiles.py +0 -0
  157. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/extensions.py +0 -0
  158. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/file_restore.py +0 -0
  159. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/hooks/__init__.py +0 -0
  160. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/hooks/config.py +0 -0
  161. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/hooks/engine.py +0 -0
  162. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/hooks/events.py +0 -0
  163. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/hooks/runner.py +0 -0
  164. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/llm.py +0 -0
  165. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/memory/__init__.py +0 -0
  166. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/memory/harvest.py +0 -0
  167. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/memory/recap.py +0 -0
  168. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/memory/sanitize.py +0 -0
  169. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/metadata.py +0 -0
  170. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/native.py +0 -0
  171. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/notifications/__init__.py +0 -0
  172. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/notifications/llm.py +0 -0
  173. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/notifications/manager.py +0 -0
  174. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/notifications/models.py +0 -0
  175. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/notifications/notifier.py +0 -0
  176. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/notifications/store.py +0 -0
  177. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/notifications/wire.py +0 -0
  178. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/plugin/__init__.py +0 -0
  179. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/plugin/manager.py +0 -0
  180. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/plugin/tool.py +0 -0
  181. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/prompt_templates.py +0 -0
  182. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/prompts/__init__.py +0 -0
  183. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/prompts/compact.md +0 -0
  184. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/prompts/init.md +0 -0
  185. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/py.typed +0 -0
  186. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/scratchpad.py +0 -0
  187. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/session.py +0 -0
  188. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/session_fork.py +0 -0
  189. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/session_state.py +0 -0
  190. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/share.py +0 -0
  191. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skill/__init__.py +0 -0
  192. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skill/flow/__init__.py +0 -0
  193. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skill/flow/d2.py +0 -0
  194. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skill/flow/mermaid.py +0 -0
  195. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skill/lockfile.py +0 -0
  196. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/check-impl-against-spec/SKILL.md +0 -0
  197. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/create-pr/SKILL.md +0 -0
  198. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/diagnose-ci-failures/SKILL.md +0 -0
  199. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/fix-errors/SKILL.md +0 -0
  200. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/implement-specs/SKILL.md +0 -0
  201. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/pr-walkthrough/SKILL.md +0 -0
  202. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/pythinker-code-help/SKILL.md +0 -0
  203. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/reproduce-bug-report/SKILL.md +0 -0
  204. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/resolve-merge-conflicts/SKILL.md +0 -0
  205. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/review-pr/SKILL.md +0 -0
  206. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/skill-creator/SKILL.md +0 -0
  207. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/spec-driven-implementation/SKILL.md +0 -0
  208. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/write-product-spec/SKILL.md +0 -0
  209. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/skills/write-tech-spec/SKILL.md +0 -0
  210. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/__init__.py +0 -0
  211. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/agent.py +0 -0
  212. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/approval.py +0 -0
  213. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/btw.py +0 -0
  214. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/compaction.py +0 -0
  215. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/compaction_restore.py +0 -0
  216. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/context.py +0 -0
  217. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/denwarenji.py +0 -0
  218. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/dynamic_injection.py +0 -0
  219. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/dynamic_injections/__init__.py +0 -0
  220. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/dynamic_injections/auto_mode.py +0 -0
  221. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/dynamic_injections/plan_mode.py +0 -0
  222. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/message.py +0 -0
  223. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/permission.py +0 -0
  224. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/soul/slash.py +0 -0
  225. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/subagents/__init__.py +0 -0
  226. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/subagents/builder.py +0 -0
  227. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/subagents/core.py +0 -0
  228. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/subagents/discovery.py +0 -0
  229. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/subagents/git_context.py +0 -0
  230. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/subagents/models.py +0 -0
  231. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/subagents/output.py +0 -0
  232. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/subagents/registry.py +0 -0
  233. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/subagents/runner.py +0 -0
  234. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/subagents/store.py +0 -0
  235. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/telemetry/__init__.py +0 -0
  236. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/telemetry/config.py +0 -0
  237. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/telemetry/crash.py +0 -0
  238. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/telemetry/errors.py +0 -0
  239. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/telemetry/metrics.py +0 -0
  240. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/telemetry/otel.py +0 -0
  241. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/telemetry/sentry.py +0 -0
  242. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/telemetry/sink.py +0 -0
  243. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/AGENTS.md +0 -0
  244. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/__init__.py +0 -0
  245. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/agent/__init__.py +0 -0
  246. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/agent/description.md +0 -0
  247. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/ask_user/__init__.py +0 -0
  248. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/ask_user/description.md +0 -0
  249. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/background/__init__.py +0 -0
  250. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/background/handoff.md +0 -0
  251. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/background/input.md +0 -0
  252. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/background/list.md +0 -0
  253. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/background/output.md +0 -0
  254. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/background/stop.md +0 -0
  255. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/display.py +0 -0
  256. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/dmail/__init__.py +0 -0
  257. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/dmail/dmail.md +0 -0
  258. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/__init__.py +0 -0
  259. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/glob.md +0 -0
  260. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/glob.py +0 -0
  261. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/grep.md +0 -0
  262. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/grep_local.py +0 -0
  263. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/plan_mode.py +0 -0
  264. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/read.md +0 -0
  265. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/read.py +0 -0
  266. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/read_media.md +0 -0
  267. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/read_media.py +0 -0
  268. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/utils.py +0 -0
  269. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/write.md +0 -0
  270. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/file/write.py +0 -0
  271. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/memory/__init__.py +0 -0
  272. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/memory/memory.md +0 -0
  273. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/plan/__init__.py +0 -0
  274. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/plan/description.md +0 -0
  275. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/plan/enter.py +0 -0
  276. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/plan/enter_description.md +0 -0
  277. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/plan/handoff.py +0 -0
  278. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/plan/heroes.py +0 -0
  279. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/scratchpad/__init__.py +0 -0
  280. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/scratchpad/scratchpad_tool.md +0 -0
  281. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/shell/__init__.py +0 -0
  282. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/shell/bash.md +0 -0
  283. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/shell/powershell.md +0 -0
  284. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/skill/__init__.py +0 -0
  285. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/skill/description.md +0 -0
  286. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/test.py +0 -0
  287. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/think/__init__.py +0 -0
  288. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/think/think.md +0 -0
  289. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/todo/__init__.py +0 -0
  290. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/todo/set_todo_list.md +0 -0
  291. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/utils.py +0 -0
  292. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/web/__init__.py +0 -0
  293. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/web/_allowlist.py +0 -0
  294. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/web/fetch.md +0 -0
  295. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/web/fetch.py +0 -0
  296. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/web/search.md +0 -0
  297. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/tools/web/search.py +0 -0
  298. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/__init__.py +0 -0
  299. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/acp/__init__.py +0 -0
  300. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/print/__init__.py +0 -0
  301. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/print/visualize.py +0 -0
  302. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/__init__.py +0 -0
  303. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/base.py +0 -0
  304. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/bash_execution.py +0 -0
  305. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/bordered_loader.py +0 -0
  306. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/diff.py +0 -0
  307. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/dynamic_border.py +0 -0
  308. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/footer.py +0 -0
  309. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/key_hints.py +0 -0
  310. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/markdown.py +0 -0
  311. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/messages.py +0 -0
  312. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/panel.py +0 -0
  313. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/render_utils.py +0 -0
  314. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/report.py +0 -0
  315. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/settings_list.py +0 -0
  316. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/special_messages.py +0 -0
  317. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/components/tool_execution.py +0 -0
  318. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/console.py +0 -0
  319. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/debug.py +0 -0
  320. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/design_system.py +0 -0
  321. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/glyphs.py +0 -0
  322. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/keyboard.py +0 -0
  323. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/keymap.py +0 -0
  324. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/mcp_status.py +0 -0
  325. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/model_picker.py +0 -0
  326. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/motion.py +0 -0
  327. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/oauth.py +0 -0
  328. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/placeholders.py +0 -0
  329. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/render_constants.py +0 -0
  330. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/replay.py +0 -0
  331. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/selector.py +0 -0
  332. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/selectors/__init__.py +0 -0
  333. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/selectors/extension.py +0 -0
  334. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/selectors/oauth.py +0 -0
  335. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/selectors/settings.py +0 -0
  336. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/selectors/show_images.py +0 -0
  337. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/selectors/theme.py +0 -0
  338. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/selectors/thinking.py +0 -0
  339. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/spacing.py +0 -0
  340. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/spinner_words.py +0 -0
  341. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/startup.py +0 -0
  342. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tips.py +0 -0
  343. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/__init__.py +0 -0
  344. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/_file_diff.py +0 -0
  345. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/_render_utils.py +0 -0
  346. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/agent.py +0 -0
  347. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/ask_user.py +0 -0
  348. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/background.py +0 -0
  349. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/bash.py +0 -0
  350. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/edit.py +0 -0
  351. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/find.py +0 -0
  352. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/generic.py +0 -0
  353. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/grep.py +0 -0
  354. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/plan.py +0 -0
  355. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/read.py +0 -0
  356. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/think.py +0 -0
  357. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/todo.py +0 -0
  358. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/web.py +0 -0
  359. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/tool_renderers/write.py +0 -0
  360. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_adapters/__init__.py +0 -0
  361. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_adapters/anthropic_admin.py +0 -0
  362. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_adapters/base.py +0 -0
  363. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_adapters/deepseek.py +0 -0
  364. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_adapters/minimax.py +0 -0
  365. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_adapters/openai_admin.py +0 -0
  366. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_adapters/openai_chatgpt.py +0 -0
  367. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_adapters/opencode_go.py +0 -0
  368. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_adapters/openrouter.py +0 -0
  369. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_adapters/pythinker.py +0 -0
  370. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_adapters/pythinker_ai.py +0 -0
  371. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/usage_render.py +0 -0
  372. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/__init__.py +0 -0
  373. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/_activity_tree.py +0 -0
  374. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/_approval_panel.py +0 -0
  375. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/_blocks.py +0 -0
  376. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/_btw_panel.py +0 -0
  377. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/_dialog_shell.py +0 -0
  378. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/_input_router.py +0 -0
  379. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/_live_view.py +0 -0
  380. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/_question_panel.py +0 -0
  381. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/_transcript.py +0 -0
  382. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/shell/visualize/_worklog.py +0 -0
  383. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/theme.py +0 -0
  384. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/ui/tui_config.py +0 -0
  385. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/usage_ratelimit_cache.py +0 -0
  386. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/__init__.py +0 -0
  387. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/aiohttp.py +0 -0
  388. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/aioqueue.py +0 -0
  389. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/broadcast.py +0 -0
  390. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/changelog.py +0 -0
  391. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/clipboard.py +0 -0
  392. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/datetime.py +0 -0
  393. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/diff.py +0 -0
  394. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/editor.py +0 -0
  395. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/environment.py +0 -0
  396. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/envvar.py +0 -0
  397. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/export.py +0 -0
  398. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/file_filter.py +0 -0
  399. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/frontmatter.py +0 -0
  400. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/io.py +0 -0
  401. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/logging.py +0 -0
  402. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/media_tags.py +0 -0
  403. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/message.py +0 -0
  404. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/path.py +0 -0
  405. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/proctitle.py +0 -0
  406. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/proxy.py +0 -0
  407. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/pyinstaller.py +0 -0
  408. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/rich/__init__.py +0 -0
  409. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/rich/columns.py +0 -0
  410. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/rich/diff_render.py +0 -0
  411. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/rich/markdown.py +0 -0
  412. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/rich/markdown_sample.md +0 -0
  413. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/rich/markdown_sample_short.md +0 -0
  414. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/rich/syntax.py +0 -0
  415. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/sensitive.py +0 -0
  416. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/server.py +0 -0
  417. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/signals.py +0 -0
  418. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/slashcmd.py +0 -0
  419. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/sleep_inhibitor.py +0 -0
  420. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/string.py +0 -0
  421. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/subprocess_env.py +0 -0
  422. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/term.py +0 -0
  423. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/utils/typing.py +0 -0
  424. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/__init__.py +0 -0
  425. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/api/__init__.py +0 -0
  426. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/api/sessions.py +0 -0
  427. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/api/statistics.py +0 -0
  428. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/api/system.py +0 -0
  429. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/app.py +0 -0
  430. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/static/assets/highlighted-body-B3W2YXNL-CY1rtwrX.js +0 -0
  431. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/static/assets/index-DSRInNnm.css +0 -0
  432. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/static/assets/index-DgmTI2M_.js +0 -0
  433. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/static/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  434. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/static/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  435. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/static/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  436. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/static/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  437. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/static/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  438. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/static/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  439. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/static/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  440. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/vis/static/index.html +0 -0
  441. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/__init__.py +0 -0
  442. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/api/__init__.py +0 -0
  443. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/api/config.py +0 -0
  444. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/api/open_in.py +0 -0
  445. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/api/sessions.py +0 -0
  446. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/app.py +0 -0
  447. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/auth.py +0 -0
  448. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/models.py +0 -0
  449. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/runner/__init__.py +0 -0
  450. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/runner/messages.py +0 -0
  451. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/runner/process.py +0 -0
  452. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/runner/worker.py +0 -0
  453. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/_headers +0 -0
  454. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  455. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  456. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  457. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  458. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  459. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  460. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  461. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  462. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  463. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  464. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  465. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  466. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  467. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  468. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  469. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  470. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  471. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  472. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  473. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  474. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  475. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  476. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  477. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  478. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  479. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  480. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  481. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  482. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  483. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  484. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  485. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  486. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  487. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  488. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  489. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  490. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  491. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  492. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  493. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  494. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  495. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  496. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  497. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  498. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  499. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  500. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  501. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  502. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  503. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  504. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  505. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  506. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  507. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  508. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  509. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  510. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  511. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  512. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  513. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/abap-BdImnpbu.js +0 -0
  514. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/actionscript-3-CfeIJUat.js +0 -0
  515. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/ada-bCR0ucgS.js +0 -0
  516. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/andromeeda-C-Jbm3Hp.js +0 -0
  517. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/angular-html-CU67Zn6k.js +0 -0
  518. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/angular-ts-BwZT4LLn.js +0 -0
  519. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/apache-Pmp26Uib.js +0 -0
  520. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/apex-D8_7TLub.js +0 -0
  521. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/apl-dKokRX4l.js +0 -0
  522. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/applescript-Co6uUVPk.js +0 -0
  523. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/ara-BRHolxvo.js +0 -0
  524. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/asciidoc-Dv7Oe6Be.js +0 -0
  525. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/asm-D_Q5rh1f.js +0 -0
  526. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/astro-CbQHKStN.js +0 -0
  527. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/aurora-x-D-2ljcwZ.js +0 -0
  528. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/awk-DMzUqQB5.js +0 -0
  529. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/ayu-dark-CmMr59Fi.js +0 -0
  530. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/ballerina-BFfxhgS-.js +0 -0
  531. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/bat-BkioyH1T.js +0 -0
  532. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/beancount-k_qm7-4y.js +0 -0
  533. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/berry-uYugtg8r.js +0 -0
  534. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/bibtex-CHM0blh-.js +0 -0
  535. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/bicep-Bmn6On1c.js +0 -0
  536. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/blade-D4QpJJKB.js +0 -0
  537. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/bsl-BO_Y6i37.js +0 -0
  538. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/c-BIGW1oBm.js +0 -0
  539. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/c3-VCDPK7BO.js +0 -0
  540. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/cadence-Bv_4Rxtq.js +0 -0
  541. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/cairo-KRGpt6FW.js +0 -0
  542. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/catppuccin-frappe-DFWUc33u.js +0 -0
  543. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/catppuccin-latte-C9dUb6Cb.js +0 -0
  544. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/catppuccin-macchiato-DQyhUUbL.js +0 -0
  545. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/catppuccin-mocha-D87Tk5Gz.js +0 -0
  546. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/clarity-D53aC0YG.js +0 -0
  547. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/clojure-P80f7IUj.js +0 -0
  548. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/cmake-D1j8_8rp.js +0 -0
  549. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/cobol-nwyudZeR.js +0 -0
  550. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/codeowners-Bp6g37R7.js +0 -0
  551. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/codeql-DsOJ9woJ.js +0 -0
  552. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/coffee-Ch7k5sss.js +0 -0
  553. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/common-lisp-Cg-RD9OK.js +0 -0
  554. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/coq-DkFqJrB1.js +0 -0
  555. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/cpp-CofmeUqb.js +0 -0
  556. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/crystal-tKQVLTB8.js +0 -0
  557. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/csharp-K5feNrxe.js +0 -0
  558. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/css-DPfMkruS.js +0 -0
  559. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/csv-fuZLfV_i.js +0 -0
  560. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/cue-D82EKSYY.js +0 -0
  561. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/cypher-COkxafJQ.js +0 -0
  562. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/d-85-TOEBH.js +0 -0
  563. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/dark-plus-C3mMm8J8.js +0 -0
  564. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/dart-CF10PKvl.js +0 -0
  565. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/dax-CEL-wOlO.js +0 -0
  566. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/defaultLocale-DX6XiGOO.js +0 -0
  567. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/desktop-BmXAJ9_W.js +0 -0
  568. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/diff-D97Zzqfu.js +0 -0
  569. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/docker-BcOcwvcX.js +0 -0
  570. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/dotenv-Da5cRb03.js +0 -0
  571. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/dracula-BzJJZx-M.js +0 -0
  572. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/dracula-soft-BXkSAIEj.js +0 -0
  573. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/dream-maker-BtqSS_iP.js +0 -0
  574. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/edge-BkV0erSs.js +0 -0
  575. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/elixir-CDX3lj18.js +0 -0
  576. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/elm-DbKCFpqz.js +0 -0
  577. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/emacs-lisp-C9XAeP06.js +0 -0
  578. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/erb-BOJIQeun.js +0 -0
  579. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/erlang-DsQrWhSR.js +0 -0
  580. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/everforest-dark-BgDCqdQA.js +0 -0
  581. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/everforest-light-C8M2exoo.js +0 -0
  582. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/fennel-BYunw83y.js +0 -0
  583. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/fish-BvzEVeQv.js +0 -0
  584. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/fluent-C4IJs8-o.js +0 -0
  585. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/fortran-fixed-form-CkoXwp7k.js +0 -0
  586. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/fortran-free-form-BxgE0vQu.js +0 -0
  587. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/fsharp-CXgrBDvD.js +0 -0
  588. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gdresource-B7Tvp0Sc.js +0 -0
  589. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gdscript-DTMYz4Jt.js +0 -0
  590. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gdshader-DkwncUOv.js +0 -0
  591. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/genie-D0YGMca9.js +0 -0
  592. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gherkin-DyxjwDmM.js +0 -0
  593. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/git-commit-F4YmCXRG.js +0 -0
  594. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/git-rebase-r7XF79zn.js +0 -0
  595. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/github-dark-DHJKELXO.js +0 -0
  596. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/github-dark-default-Cuk6v7N8.js +0 -0
  597. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/github-dark-dimmed-DH5Ifo-i.js +0 -0
  598. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -0
  599. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/github-light-DAi9KRSo.js +0 -0
  600. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/github-light-default-D7oLnXFd.js +0 -0
  601. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/github-light-high-contrast-BfjtVDDH.js +0 -0
  602. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gleam-BspZqrRM.js +0 -0
  603. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/glimmer-js-Rg0-pVw9.js +0 -0
  604. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/glimmer-ts-U6CK756n.js +0 -0
  605. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/glsl-DplSGwfg.js +0 -0
  606. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gn-n2N0HUVH.js +0 -0
  607. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gnuplot-DdkO51Og.js +0 -0
  608. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/go-Dn2_MT6a.js +0 -0
  609. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/graphql-ChdNCCLP.js +0 -0
  610. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/groovy-gcz8RCvz.js +0 -0
  611. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -0
  612. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gruvbox-dark-medium-GsRaNv29.js +0 -0
  613. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gruvbox-dark-soft-CVdnzihN.js +0 -0
  614. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gruvbox-light-hard-CH1njM8p.js +0 -0
  615. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gruvbox-light-medium-DRw_LuNl.js +0 -0
  616. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/gruvbox-light-soft-hJgmCMqR.js +0 -0
  617. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/hack-CaT9iCJl.js +0 -0
  618. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/haml-B8DHNrY2.js +0 -0
  619. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/handlebars-BL8al0AC.js +0 -0
  620. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/haskell-Df6bDoY_.js +0 -0
  621. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/haxe-CzTSHFRz.js +0 -0
  622. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/hcl-BWvSN4gD.js +0 -0
  623. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/hjson-D5-asLiD.js +0 -0
  624. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/hlsl-D3lLCCz7.js +0 -0
  625. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/houston-DnULxvSX.js +0 -0
  626. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/html-GMplVEZG.js +0 -0
  627. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/html-derivative-BFtXZ54Q.js +0 -0
  628. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/http-jrhK8wxY.js +0 -0
  629. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/hurl-irOxFIW8.js +0 -0
  630. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/hxml-Bvhsp5Yf.js +0 -0
  631. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/hy-DFXneXwc.js +0 -0
  632. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/imba-DGztddWO.js +0 -0
  633. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/index-BpoLgcEt.js +0 -0
  634. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/index-CzV_vCfu.css +0 -0
  635. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/index-DI2oedCt.js +0 -0
  636. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/ini-BEwlwnbL.js +0 -0
  637. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/init-Gi6I4Gst.js +0 -0
  638. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  639. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  640. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  641. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  642. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  643. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  644. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  645. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/java-CylS5w8V.js +0 -0
  646. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/javascript-wDzz0qaB.js +0 -0
  647. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/jinja-4LBKfQ-Z.js +0 -0
  648. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/jison-wvAkD_A8.js +0 -0
  649. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/json-Cp-IABpG.js +0 -0
  650. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/json5-C9tS-k6U.js +0 -0
  651. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/jsonc-Des-eS-w.js +0 -0
  652. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/jsonl-DcaNXYhu.js +0 -0
  653. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/jsonnet-DFQXde-d.js +0 -0
  654. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/jssm-C2t-YnRu.js +0 -0
  655. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/jsx-g9-lgVsj.js +0 -0
  656. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/julia-CxzCAyBv.js +0 -0
  657. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/kanagawa-dragon-CkXjmgJE.js +0 -0
  658. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/kanagawa-lotus-CfQXZHmo.js +0 -0
  659. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/kanagawa-wave-DWedfzmr.js +0 -0
  660. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/katex-D2lIc1rk.css +0 -0
  661. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/kdl-DV7GczEv.js +0 -0
  662. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/kotlin-BdnUsdx6.js +0 -0
  663. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/kusto-DZf3V79B.js +0 -0
  664. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/laserwave-DUszq2jm.js +0 -0
  665. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/latex-B4uzh10-.js +0 -0
  666. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/lean-BZvkOJ9d.js +0 -0
  667. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/less-B1dDrJ26.js +0 -0
  668. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/light-plus-B7mTdjB0.js +0 -0
  669. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/liquid-DYVedYrR.js +0 -0
  670. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/llvm-BtvRca6l.js +0 -0
  671. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/log-2UxHyX5q.js +0 -0
  672. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/logo-BtOb2qkB.js +0 -0
  673. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/lua-BbnMAYS6.js +0 -0
  674. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/luau-C-HG3fhB.js +0 -0
  675. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/make-CHLpvVh8.js +0 -0
  676. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/markdown-Cvjx9yec.js +0 -0
  677. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/marko-DZsq8hO1.js +0 -0
  678. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/material-theme-D5KoaKCx.js +0 -0
  679. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/material-theme-darker-BfHTSMKl.js +0 -0
  680. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/material-theme-lighter-B0m2ddpp.js +0 -0
  681. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/material-theme-ocean-CyktbL80.js +0 -0
  682. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/material-theme-palenight-Csfq5Kiy.js +0 -0
  683. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/matlab-D7o27uSR.js +0 -0
  684. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/mdc-DUICxH0z.js +0 -0
  685. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/mdx-Cmh6b_Ma.js +0 -0
  686. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/mermaid-VLURNSYL-B2P5VJ9v.css +0 -0
  687. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/mermaid-mWjccvbQ.js +0 -0
  688. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/min-dark-CafNBF8u.js +0 -0
  689. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/min-light-CTRr51gU.js +0 -0
  690. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/mipsasm-CKIfxQSi.js +0 -0
  691. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/mojo-B93PlW-d.js +0 -0
  692. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/monokai-D4h5O-jR.js +0 -0
  693. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/moonbit-Ba13S78F.js +0 -0
  694. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/move-Bu9oaDYs.js +0 -0
  695. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/narrat-DRg8JJMk.js +0 -0
  696. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/nextflow-BrzmwbiE.js +0 -0
  697. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/nginx-DknmC5AR.js +0 -0
  698. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/night-owl-C39BiMTA.js +0 -0
  699. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/nim-CVrawwO9.js +0 -0
  700. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/nix-CwoSXNpI.js +0 -0
  701. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/nord-Ddv68eIx.js +0 -0
  702. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/nushell-C-sUppwS.js +0 -0
  703. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/objective-c-DXmwc3jG.js +0 -0
  704. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/objective-cpp-CLxacb5B.js +0 -0
  705. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/ocaml-C0hk2d4L.js +0 -0
  706. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/one-dark-pro-DVMEJ2y_.js +0 -0
  707. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/one-light-PoHY5YXO.js +0 -0
  708. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/openscad-C4EeE6gA.js +0 -0
  709. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/ordinal-Cboi1Yqb.js +0 -0
  710. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/pascal-D93ZcfNL.js +0 -0
  711. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/perl-C0TMdlhV.js +0 -0
  712. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/php-CDn_0X-4.js +0 -0
  713. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/pkl-u5AG7uiY.js +0 -0
  714. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/plastic-3e1v2bzS.js +0 -0
  715. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/plsql-ChMvpjG-.js +0 -0
  716. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/po-BTJTHyun.js +0 -0
  717. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/poimandres-CS3Unz2-.js +0 -0
  718. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/polar-C0HS_06l.js +0 -0
  719. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/postcss-CXtECtnM.js +0 -0
  720. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/powerquery-CEu0bR-o.js +0 -0
  721. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/powershell-Dpen1YoG.js +0 -0
  722. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/prisma-Dd19v3D-.js +0 -0
  723. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/prolog-CbFg5uaA.js +0 -0
  724. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/proto-C7zT0LnQ.js +0 -0
  725. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/pug-CGlum2m_.js +0 -0
  726. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/puppet-BMWR74SV.js +0 -0
  727. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/purescript-CklMAg4u.js +0 -0
  728. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/python-B6aJPvgy.js +0 -0
  729. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/qml-3beO22l8.js +0 -0
  730. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/qmldir-C8lEn-DE.js +0 -0
  731. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/qss-IeuSbFQv.js +0 -0
  732. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/r-Dspwwk_N.js +0 -0
  733. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/racket-BqYA7rlc.js +0 -0
  734. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/raku-DXvB9xmW.js +0 -0
  735. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/razor-C1TweQQi.js +0 -0
  736. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/red-bN70gL4F.js +0 -0
  737. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/reg-C-SQnVFl.js +0 -0
  738. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/regexp-CDVJQ6XC.js +0 -0
  739. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/rel-C3B-1QV4.js +0 -0
  740. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/riscv-BM1_JUlF.js +0 -0
  741. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/rose-pine-dawn-DHQR4-dF.js +0 -0
  742. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/rose-pine-moon-D4_iv3hh.js +0 -0
  743. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/rose-pine-qdsjHGoJ.js +0 -0
  744. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/rosmsg-BJDFO7_C.js +0 -0
  745. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/rst-B0xPkSld.js +0 -0
  746. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/ruby-BvKwtOVI.js +0 -0
  747. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/rust-B1yitclQ.js +0 -0
  748. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/sas-cz2c8ADy.js +0 -0
  749. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/sass-Cj5Yp3dK.js +0 -0
  750. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/scala-C151Ov-r.js +0 -0
  751. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/scheme-C98Dy4si.js +0 -0
  752. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/scss-OYdSNvt2.js +0 -0
  753. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/sdbl-DVxCFoDh.js +0 -0
  754. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/shaderlab-Dg9Lc6iA.js +0 -0
  755. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/shellscript-Yzrsuije.js +0 -0
  756. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/shellsession-BADoaaVG.js +0 -0
  757. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/slack-dark-BthQWCQV.js +0 -0
  758. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/slack-ochin-DqwNpetd.js +0 -0
  759. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/smalltalk-BERRCDM3.js +0 -0
  760. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/snazzy-light-Bw305WKR.js +0 -0
  761. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/solarized-dark-DXbdFlpD.js +0 -0
  762. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/solarized-light-L9t79GZl.js +0 -0
  763. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/solidity-rGO070M0.js +0 -0
  764. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/soy-Brmx7dQM.js +0 -0
  765. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/sparql-rVzFXLq3.js +0 -0
  766. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/splunk-BtCnVYZw.js +0 -0
  767. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/sql-BLtJtn59.js +0 -0
  768. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/ssh-config-_ykCGR6B.js +0 -0
  769. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/stata-BH5u7GGu.js +0 -0
  770. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/stylus-BEDo0Tqx.js +0 -0
  771. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/svelte-zxCyuUbr.js +0 -0
  772. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/swift-Dg5xB15N.js +0 -0
  773. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/synthwave-84-CbfX1IO0.js +0 -0
  774. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/system-verilog-CnnmHF94.js +0 -0
  775. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/systemd-4A_iFExJ.js +0 -0
  776. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/talonscript-CkByrt1z.js +0 -0
  777. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/tasl-QIJgUcNo.js +0 -0
  778. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/tcl-dwOrl1Do.js +0 -0
  779. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/templ-W15q3VgB.js +0 -0
  780. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/terraform-BETggiCN.js +0 -0
  781. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/tex-CvyZ59Mk.js +0 -0
  782. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/tokyo-night-hegEt444.js +0 -0
  783. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/toml-vGWfd6FD.js +0 -0
  784. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/ts-tags-zn1MmPIZ.js +0 -0
  785. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/tsv-B_m7g4N7.js +0 -0
  786. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/tsx-COt5Ahok.js +0 -0
  787. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/turtle-BsS91CYL.js +0 -0
  788. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/twig-CO9l9SDP.js +0 -0
  789. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/typescript-BPQ3VLAy.js +0 -0
  790. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/typespec-BGHnOYBU.js +0 -0
  791. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/typst-DHCkPAjA.js +0 -0
  792. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/v-BcVCzyr7.js +0 -0
  793. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/vala-CsfeWuGM.js +0 -0
  794. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/vb-D17OF-Vu.js +0 -0
  795. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/verilog-BQ8w6xss.js +0 -0
  796. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/vesper-DU1UobuO.js +0 -0
  797. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/vhdl-CeAyd5Ju.js +0 -0
  798. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/viml-CJc9bBzg.js +0 -0
  799. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/vitesse-black-Bkuqu6BP.js +0 -0
  800. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/vitesse-dark-D0r3Knsf.js +0 -0
  801. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/vitesse-light-CVO1_9PV.js +0 -0
  802. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/vue-DN_0RTcg.js +0 -0
  803. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/vue-html-AaS7Mt5G.js +0 -0
  804. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/vue-vine-CQOfvN7w.js +0 -0
  805. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/vyper-CDx5xZoG.js +0 -0
  806. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/wasm-CG6Dc4jp.js +0 -0
  807. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/wasm-MzD3tlZU.js +0 -0
  808. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/wenyan-BV7otONQ.js +0 -0
  809. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/wgsl-Dx-B1_4e.js +0 -0
  810. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/wikitext-BhOHFoWU.js +0 -0
  811. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/wit-5i3qLPDT.js +0 -0
  812. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/wolfram-lXgVvXCa.js +0 -0
  813. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/xml-sdJ4AIDG.js +0 -0
  814. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/xsl-CtQFsRM5.js +0 -0
  815. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/yaml-Buea-lGh.js +0 -0
  816. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/zenscript-DVFEvuxE.js +0 -0
  817. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/assets/zig-VOosw3JB.js +0 -0
  818. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/apple-touch-icon.png +0 -0
  819. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/arctecture.webp +0 -0
  820. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/bimi-logo.svg +0 -0
  821. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/favicon.ico +0 -0
  822. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/dm-sans-latin-ext.woff2 +0 -0
  823. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/dm-sans-latin.woff2 +0 -0
  824. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/instrument-sans-latin-ext.woff2 +0 -0
  825. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/instrument-sans-latin.woff2 +0 -0
  826. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/instrument-serif-latin-ext.woff2 +0 -0
  827. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/instrument-serif-latin.woff2 +0 -0
  828. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/libre-baskerville-italic-latin-ext.woff2 +0 -0
  829. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/libre-baskerville-italic-latin.woff2 +0 -0
  830. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/libre-baskerville-latin-ext.woff2 +0 -0
  831. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/libre-baskerville-latin.woff2 +0 -0
  832. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/roboto-latin-ext.woff2 +0 -0
  833. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/fonts/roboto-latin.woff2 +0 -0
  834. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/icon-192.png +0 -0
  835. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/icon-512.png +0 -0
  836. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/icon.svg +0 -0
  837. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/logo.png +0 -0
  838. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/pythinker_animated.svg +0 -0
  839. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/brand/robots.txt +0 -0
  840. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/static/logo.png +0 -0
  841. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/store/__init__.py +0 -0
  842. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/web/store/sessions.py +0 -0
  843. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/wire/__init__.py +0 -0
  844. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/wire/file.py +0 -0
  845. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/wire/jsonrpc.py +0 -0
  846. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/wire/protocol.py +0 -0
  847. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/wire/root_hub.py +0 -0
  848. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/wire/serde.py +0 -0
  849. {pythinker_code-0.26.0 → pythinker_code-0.27.0}/src/pythinker_code/wire/server.py +0 -0
  850. {pythinker_code-0.26.0 → pythinker_code-0.27.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.26.0
3
+ Version: 0.27.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
@@ -21,7 +21,7 @@ Classifier: Topic :: Software Development :: Code Generators
21
21
  Classifier: Topic :: Utilities
22
22
  Requires-Dist: agent-client-protocol==0.8.0
23
23
  Requires-Dist: aiofiles>=24.0,<26.0
24
- Requires-Dist: aiohttp==3.13.4
24
+ Requires-Dist: aiohttp==3.13.5
25
25
  Requires-Dist: typer==0.21.1
26
26
  Requires-Dist: pythinker-core[contrib]==1.1.1
27
27
  Requires-Dist: loguru>=0.6.0,<0.7
@@ -34,7 +34,7 @@ Requires-Dist: click==8.3.0
34
34
  Requires-Dist: pyperclip==1.11.0
35
35
  Requires-Dist: streamingjson==0.0.5
36
36
  Requires-Dist: trafilatura==2.0.0
37
- Requires-Dist: lxml==6.1.0
37
+ Requires-Dist: lxml==6.1.1
38
38
  Requires-Dist: tenacity==9.1.4
39
39
  Requires-Dist: fastmcp==3.2.0
40
40
  Requires-Dist: pydantic==2.13.4
@@ -42,7 +42,7 @@ Requires-Dist: httpx[socks]==0.28.1
42
42
  Requires-Dist: pythinker-host==1.0.0
43
43
  Requires-Dist: pythinker-review==0.1.0
44
44
  Requires-Dist: batrachian-toad==0.5.23 ; python_full_version >= '3.14'
45
- Requires-Dist: tomlkit==0.14.0
45
+ Requires-Dist: tomlkit==0.15.0
46
46
  Requires-Dist: jinja2==3.1.6
47
47
  Requires-Dist: pyobjc-framework-cocoa>=12.1 ; sys_platform == 'darwin'
48
48
  Requires-Dist: fastapi>=0.115.0
@@ -115,15 +115,15 @@ It speaks the [**Agent Client Protocol (ACP)**](https://github.com/agentclientpr
115
115
 
116
116
  ---
117
117
 
118
- ## 🆕 What's New in 0.26.0
118
+ ## 🆕 What's New in 0.27.0
119
119
 
120
- - **Install and update no longer 404 on a freshly published release.** Releases are now published as a prerelease and promoted to "latest" only once every platform asset has uploaded, and the curl/PowerShell installers wait for their archive + checksum before downloading so `irm | iex` / `curl | bash` run mid-publish no longer fail on a missing installer.
121
- - **OpenCode Go model catalog refreshes on startup without a re-login.** Bundled catalog changes (new models, corrected provider shapes) now reach existing installs through the every-startup refresh, across both OpenAI- and Anthropic-shaped providers, while preserving your default model and thinking settings.
122
- - **Homebrew install shows the logo and fails fast on a missing tap token.** `brew install` now prints the robot-head banner via formula caveats, and the tap workflow reports an actionable error when `HOMEBREW_TAP_TOKEN` is missing instead of an opaque git failure.
123
- - **Markdown and report rendering hardened against real model output.** Code-span pipes inside tables no longer fracture the table, and a `report` block nested inside a documentation fence is no longer wrongly promoted report fences are now extracted via a markdown-it AST walk.
124
- - **Steadier agent editing and a restored update prompt.** File-replace edit handling is hardened, subagent prompt persistence and the agent's working language are preserved, and the blocking pre-start update prompt is restored so it runs before every interactive session.
120
+ - **`/feedback` submits structured reports with redacted session context.** A new `/feedback [bug|feature|ux|wrong] [message]` command collects recent session context, strips sensitive file contents before sending, shows a confirmation preview, and falls back to a prefilled GitHub issue when direct submission is unavailable.
121
+ - **Fresh releases surface in the startup update prompt immediately.** The pre-start update prompt revalidates a cached "already current" answer with a bounded conditional request instead of waiting for the 24-hour throttle, and release promotion now waits for the native assets, PyPI, and the Homebrew tap before marking a version latest — so clients never resolve a release before its install channel is ready.
122
+ - **Background agent recovery preserves terminal task state.** Recovery re-reads task runtime under the store update lock before marking orphaned agent work recoverable, so a stale snapshot can no longer clobber a task that already completed.
123
+ - **Shell prompt echoes and background todo rows are clearer.** Transcript echoes now show the resolved submitted text for pasted-content placeholders, and background todo rows align continuation icons with the first row.
124
+ - **StrReplaceFile refuses ambiguous single replacements.** A non-`replace_all` edit now errors when `old` matches more than once instead of silently editing the first match add surrounding context to make it unique, or pass `replace_all=true` when every occurrence should change.
125
125
 
126
- Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.26.0`, or use the native installer for your platform from the [Releases page](https://github.com/TechMatrix-labs/pythinker-code/releases/latest).
126
+ Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.27.0`, or use the native installer for your platform from the [Releases page](https://github.com/TechMatrix-labs/pythinker-code/releases/latest).
127
127
 
128
128
 
129
129
  ---
@@ -213,7 +213,7 @@ matches your OS — no Python, Node, or `uv` prerequisite.
213
213
 
214
214
  | Platform | Recommended install | Artifact source |
215
215
  |---|---|---|
216
- | **🪟 Windows** | `irm https://pythinker.com/install.ps1 \| iex` | `PythinkerSetup-0.26.0.exe` from [Releases](https://github.com/TechMatrix-labs/pythinker-code/releases/latest) |
216
+ | **🪟 Windows** | `irm https://pythinker.com/install.ps1 \| iex` | `PythinkerSetup-0.27.0.exe` from [Releases](https://github.com/TechMatrix-labs/pythinker-code/releases/latest) |
217
217
  | **<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/TechMatrix-labs/pythinker-code/releases/latest) |
218
218
  | **<img src="https://img.shields.io/badge/-macOS-000000?style=flat-square&logo=apple&logoColor=white" alt="macOS"> — Homebrew** | `brew install TechMatrix-labs/pythinker/pythinker-code` | auto-published Homebrew tap |
219
219
  | **<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/TechMatrix-labs/pythinker-code/releases/latest) |
@@ -238,7 +238,7 @@ pythinker # start the interactive TUI
238
238
 
239
239
  ### 🪟 Windows — native installer
240
240
 
241
- `PythinkerSetup-0.26.0.exe` is a signed* Inno Setup wizard. Installs per-user
241
+ `PythinkerSetup-0.27.0.exe` is a signed* Inno Setup wizard. Installs per-user
242
242
  into `%LOCALAPPDATA%\Programs\Pythinker`, registers `pythinker` on your user
243
243
  PATH (`HKCU\Environment`), broadcasts `WM_SETTINGCHANGE` so new shells see
244
244
  the change. **No UAC prompt.**
@@ -249,13 +249,13 @@ irm https://pythinker.com/install.ps1 | iex
249
249
 
250
250
  # Or manually download the installer + checksum from the Releases page,
251
251
  # verify with Get-FileHash, then run:
252
- .\PythinkerSetup-0.26.0.exe
252
+ .\PythinkerSetup-0.27.0.exe
253
253
 
254
254
  # Open a fresh PowerShell
255
255
  pythinker --version
256
256
  ```
257
257
 
258
- **Per-machine install** (IT-managed boxes): `.\PythinkerSetup-0.26.0.exe /ALLUSERS`
258
+ **Per-machine install** (IT-managed boxes): `.\PythinkerSetup-0.27.0.exe /ALLUSERS`
259
259
  installs to `%ProgramFiles%\Pythinker` and writes PATH to HKLM (requires admin).
260
260
 
261
261
  **Upgrade:** `pythinker update` from inside the running app — it downloads
@@ -306,26 +306,26 @@ attached to every GitHub Release.
306
306
 
307
307
  ```sh
308
308
  # Debian / Ubuntu (x86_64)
309
- sudo dpkg -i pythinker-code_0.26.0_amd64.deb
309
+ sudo dpkg -i pythinker-code_0.27.0_amd64.deb
310
310
  sudo apt-get install -f # only if dpkg reports missing deps
311
311
 
312
312
  # Debian / Ubuntu (ARM64)
313
- sudo dpkg -i pythinker-code_0.26.0_arm64.deb
313
+ sudo dpkg -i pythinker-code_0.27.0_arm64.deb
314
314
 
315
315
  # Fedora / RHEL / openSUSE (x86_64)
316
- curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.26.0/pythinker-code-0.26.0.x86_64.rpm
317
- curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.26.0/pythinker-code-0.26.0.x86_64.rpm.sha256
318
- sha256sum -c pythinker-code-0.26.0.x86_64.rpm.sha256
316
+ curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.27.0/pythinker-code-0.27.0.x86_64.rpm
317
+ curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.27.0/pythinker-code-0.27.0.x86_64.rpm.sha256
318
+ sha256sum -c pythinker-code-0.27.0.x86_64.rpm.sha256
319
319
  # Fedora / RHEL:
320
- sudo dnf install ./pythinker-code-0.26.0.x86_64.rpm
320
+ sudo dnf install ./pythinker-code-0.27.0.x86_64.rpm
321
321
  # openSUSE:
322
- sudo zypper install ./pythinker-code-0.26.0.x86_64.rpm
322
+ sudo zypper install ./pythinker-code-0.27.0.x86_64.rpm
323
323
 
324
324
  # Fedora / RHEL (aarch64)
325
- curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.26.0/pythinker-code-0.26.0.aarch64.rpm
326
- curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.26.0/pythinker-code-0.26.0.aarch64.rpm.sha256
327
- sha256sum -c pythinker-code-0.26.0.aarch64.rpm.sha256
328
- sudo dnf install ./pythinker-code-0.26.0.aarch64.rpm
325
+ curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.27.0/pythinker-code-0.27.0.aarch64.rpm
326
+ curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.27.0/pythinker-code-0.27.0.aarch64.rpm.sha256
327
+ sha256sum -c pythinker-code-0.27.0.aarch64.rpm.sha256
328
+ sudo dnf install ./pythinker-code-0.27.0.aarch64.rpm
329
329
  ```
330
330
 
331
331
  Both packages drop a small `/usr/bin/pythinker` launcher that execs the real
@@ -334,8 +334,8 @@ binary under `/usr/lib/pythinker/`, so your `$PATH` stays tidy.
334
334
  **Verify before install:**
335
335
 
336
336
  ```sh
337
- sha256sum -c pythinker-code_0.26.0_amd64.deb.sha256 # Debian/Ubuntu
338
- sha256sum -c pythinker-code-0.26.0.x86_64.rpm.sha256 # Fedora/RHEL
337
+ sha256sum -c pythinker-code_0.27.0_amd64.deb.sha256 # Debian/Ubuntu
338
+ sha256sum -c pythinker-code-0.27.0.x86_64.rpm.sha256 # Fedora/RHEL
339
339
  ```
340
340
 
341
341
  **Upgrade:** download the new `.deb`/`.rpm` from Releases and `dpkg -i` /
@@ -365,7 +365,7 @@ at `~/.local/bin/pythinker`.
365
365
  curl -fsSL https://pythinker.com/install.sh | bash
366
366
 
367
367
  # Pin a specific version
368
- curl -fsSL https://pythinker.com/install.sh | bash -s -- --version 0.26.0
368
+ curl -fsSL https://pythinker.com/install.sh | bash -s -- --version 0.27.0
369
369
 
370
370
  # Custom prefix (defaults to $HOME/.local)
371
371
  curl -fsSL https://pythinker.com/install.sh | bash -s -- --prefix /opt/pythinker
@@ -50,15 +50,15 @@ It speaks the [**Agent Client Protocol (ACP)**](https://github.com/agentclientpr
50
50
 
51
51
  ---
52
52
 
53
- ## 🆕 What's New in 0.26.0
53
+ ## 🆕 What's New in 0.27.0
54
54
 
55
- - **Install and update no longer 404 on a freshly published release.** Releases are now published as a prerelease and promoted to "latest" only once every platform asset has uploaded, and the curl/PowerShell installers wait for their archive + checksum before downloading so `irm | iex` / `curl | bash` run mid-publish no longer fail on a missing installer.
56
- - **OpenCode Go model catalog refreshes on startup without a re-login.** Bundled catalog changes (new models, corrected provider shapes) now reach existing installs through the every-startup refresh, across both OpenAI- and Anthropic-shaped providers, while preserving your default model and thinking settings.
57
- - **Homebrew install shows the logo and fails fast on a missing tap token.** `brew install` now prints the robot-head banner via formula caveats, and the tap workflow reports an actionable error when `HOMEBREW_TAP_TOKEN` is missing instead of an opaque git failure.
58
- - **Markdown and report rendering hardened against real model output.** Code-span pipes inside tables no longer fracture the table, and a `report` block nested inside a documentation fence is no longer wrongly promoted report fences are now extracted via a markdown-it AST walk.
59
- - **Steadier agent editing and a restored update prompt.** File-replace edit handling is hardened, subagent prompt persistence and the agent's working language are preserved, and the blocking pre-start update prompt is restored so it runs before every interactive session.
55
+ - **`/feedback` submits structured reports with redacted session context.** A new `/feedback [bug|feature|ux|wrong] [message]` command collects recent session context, strips sensitive file contents before sending, shows a confirmation preview, and falls back to a prefilled GitHub issue when direct submission is unavailable.
56
+ - **Fresh releases surface in the startup update prompt immediately.** The pre-start update prompt revalidates a cached "already current" answer with a bounded conditional request instead of waiting for the 24-hour throttle, and release promotion now waits for the native assets, PyPI, and the Homebrew tap before marking a version latest — so clients never resolve a release before its install channel is ready.
57
+ - **Background agent recovery preserves terminal task state.** Recovery re-reads task runtime under the store update lock before marking orphaned agent work recoverable, so a stale snapshot can no longer clobber a task that already completed.
58
+ - **Shell prompt echoes and background todo rows are clearer.** Transcript echoes now show the resolved submitted text for pasted-content placeholders, and background todo rows align continuation icons with the first row.
59
+ - **StrReplaceFile refuses ambiguous single replacements.** A non-`replace_all` edit now errors when `old` matches more than once instead of silently editing the first match add surrounding context to make it unique, or pass `replace_all=true` when every occurrence should change.
60
60
 
61
- Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.26.0`, or use the native installer for your platform from the [Releases page](https://github.com/TechMatrix-labs/pythinker-code/releases/latest).
61
+ Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.27.0`, or use the native installer for your platform from the [Releases page](https://github.com/TechMatrix-labs/pythinker-code/releases/latest).
62
62
 
63
63
 
64
64
  ---
@@ -148,7 +148,7 @@ matches your OS — no Python, Node, or `uv` prerequisite.
148
148
 
149
149
  | Platform | Recommended install | Artifact source |
150
150
  |---|---|---|
151
- | **🪟 Windows** | `irm https://pythinker.com/install.ps1 \| iex` | `PythinkerSetup-0.26.0.exe` from [Releases](https://github.com/TechMatrix-labs/pythinker-code/releases/latest) |
151
+ | **🪟 Windows** | `irm https://pythinker.com/install.ps1 \| iex` | `PythinkerSetup-0.27.0.exe` from [Releases](https://github.com/TechMatrix-labs/pythinker-code/releases/latest) |
152
152
  | **<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/TechMatrix-labs/pythinker-code/releases/latest) |
153
153
  | **<img src="https://img.shields.io/badge/-macOS-000000?style=flat-square&logo=apple&logoColor=white" alt="macOS"> — Homebrew** | `brew install TechMatrix-labs/pythinker/pythinker-code` | auto-published Homebrew tap |
154
154
  | **<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/TechMatrix-labs/pythinker-code/releases/latest) |
@@ -173,7 +173,7 @@ pythinker # start the interactive TUI
173
173
 
174
174
  ### 🪟 Windows — native installer
175
175
 
176
- `PythinkerSetup-0.26.0.exe` is a signed* Inno Setup wizard. Installs per-user
176
+ `PythinkerSetup-0.27.0.exe` is a signed* Inno Setup wizard. Installs per-user
177
177
  into `%LOCALAPPDATA%\Programs\Pythinker`, registers `pythinker` on your user
178
178
  PATH (`HKCU\Environment`), broadcasts `WM_SETTINGCHANGE` so new shells see
179
179
  the change. **No UAC prompt.**
@@ -184,13 +184,13 @@ irm https://pythinker.com/install.ps1 | iex
184
184
 
185
185
  # Or manually download the installer + checksum from the Releases page,
186
186
  # verify with Get-FileHash, then run:
187
- .\PythinkerSetup-0.26.0.exe
187
+ .\PythinkerSetup-0.27.0.exe
188
188
 
189
189
  # Open a fresh PowerShell
190
190
  pythinker --version
191
191
  ```
192
192
 
193
- **Per-machine install** (IT-managed boxes): `.\PythinkerSetup-0.26.0.exe /ALLUSERS`
193
+ **Per-machine install** (IT-managed boxes): `.\PythinkerSetup-0.27.0.exe /ALLUSERS`
194
194
  installs to `%ProgramFiles%\Pythinker` and writes PATH to HKLM (requires admin).
195
195
 
196
196
  **Upgrade:** `pythinker update` from inside the running app — it downloads
@@ -241,26 +241,26 @@ attached to every GitHub Release.
241
241
 
242
242
  ```sh
243
243
  # Debian / Ubuntu (x86_64)
244
- sudo dpkg -i pythinker-code_0.26.0_amd64.deb
244
+ sudo dpkg -i pythinker-code_0.27.0_amd64.deb
245
245
  sudo apt-get install -f # only if dpkg reports missing deps
246
246
 
247
247
  # Debian / Ubuntu (ARM64)
248
- sudo dpkg -i pythinker-code_0.26.0_arm64.deb
248
+ sudo dpkg -i pythinker-code_0.27.0_arm64.deb
249
249
 
250
250
  # Fedora / RHEL / openSUSE (x86_64)
251
- curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.26.0/pythinker-code-0.26.0.x86_64.rpm
252
- curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.26.0/pythinker-code-0.26.0.x86_64.rpm.sha256
253
- sha256sum -c pythinker-code-0.26.0.x86_64.rpm.sha256
251
+ curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.27.0/pythinker-code-0.27.0.x86_64.rpm
252
+ curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.27.0/pythinker-code-0.27.0.x86_64.rpm.sha256
253
+ sha256sum -c pythinker-code-0.27.0.x86_64.rpm.sha256
254
254
  # Fedora / RHEL:
255
- sudo dnf install ./pythinker-code-0.26.0.x86_64.rpm
255
+ sudo dnf install ./pythinker-code-0.27.0.x86_64.rpm
256
256
  # openSUSE:
257
- sudo zypper install ./pythinker-code-0.26.0.x86_64.rpm
257
+ sudo zypper install ./pythinker-code-0.27.0.x86_64.rpm
258
258
 
259
259
  # Fedora / RHEL (aarch64)
260
- curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.26.0/pythinker-code-0.26.0.aarch64.rpm
261
- curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.26.0/pythinker-code-0.26.0.aarch64.rpm.sha256
262
- sha256sum -c pythinker-code-0.26.0.aarch64.rpm.sha256
263
- sudo dnf install ./pythinker-code-0.26.0.aarch64.rpm
260
+ curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.27.0/pythinker-code-0.27.0.aarch64.rpm
261
+ curl -LO https://github.com/TechMatrix-labs/pythinker-code/releases/download/v0.27.0/pythinker-code-0.27.0.aarch64.rpm.sha256
262
+ sha256sum -c pythinker-code-0.27.0.aarch64.rpm.sha256
263
+ sudo dnf install ./pythinker-code-0.27.0.aarch64.rpm
264
264
  ```
265
265
 
266
266
  Both packages drop a small `/usr/bin/pythinker` launcher that execs the real
@@ -269,8 +269,8 @@ binary under `/usr/lib/pythinker/`, so your `$PATH` stays tidy.
269
269
  **Verify before install:**
270
270
 
271
271
  ```sh
272
- sha256sum -c pythinker-code_0.26.0_amd64.deb.sha256 # Debian/Ubuntu
273
- sha256sum -c pythinker-code-0.26.0.x86_64.rpm.sha256 # Fedora/RHEL
272
+ sha256sum -c pythinker-code_0.27.0_amd64.deb.sha256 # Debian/Ubuntu
273
+ sha256sum -c pythinker-code-0.27.0.x86_64.rpm.sha256 # Fedora/RHEL
274
274
  ```
275
275
 
276
276
  **Upgrade:** download the new `.deb`/`.rpm` from Releases and `dpkg -i` /
@@ -300,7 +300,7 @@ at `~/.local/bin/pythinker`.
300
300
  curl -fsSL https://pythinker.com/install.sh | bash
301
301
 
302
302
  # Pin a specific version
303
- curl -fsSL https://pythinker.com/install.sh | bash -s -- --version 0.26.0
303
+ curl -fsSL https://pythinker.com/install.sh | bash -s -- --version 0.27.0
304
304
 
305
305
  # Custom prefix (defaults to $HOME/.local)
306
306
  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.26.0"
3
+ version = "0.27.0"
4
4
  description = "Pythinker Code is your next CLI agent."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -24,7 +24,7 @@ classifiers = [
24
24
  dependencies = [
25
25
  "agent-client-protocol==0.8.0",
26
26
  "aiofiles>=24.0,<26.0",
27
- "aiohttp==3.13.4",
27
+ "aiohttp==3.13.5",
28
28
  "typer==0.21.1",
29
29
  "pythinker-core[contrib]==1.1.1",
30
30
  # notify-py (via batrachian-toad) caps loguru at <=0.6.0 on 3.14+.
@@ -39,7 +39,7 @@ dependencies = [
39
39
  "streamingjson==0.0.5",
40
40
  "trafilatura==2.0.0",
41
41
  # lxml is used by trafilatura/htmldate/justext; keep pinned for binary wheels.
42
- "lxml==6.1.0",
42
+ "lxml==6.1.1",
43
43
  "tenacity==9.1.4",
44
44
  "fastmcp==3.2.0",
45
45
  "pydantic==2.13.4",
@@ -47,7 +47,7 @@ dependencies = [
47
47
  "pythinker-host==1.0.0",
48
48
  "pythinker-review==0.1.0",
49
49
  "batrachian-toad==0.5.23; python_version >= \"3.14\"",
50
- "tomlkit==0.14.0",
50
+ "tomlkit==0.15.0",
51
51
  "jinja2==3.1.6",
52
52
  "pyobjc-framework-cocoa>=12.1 ; sys_platform == 'darwin'",
53
53
  "fastapi>=0.115.0",
@@ -15,6 +15,36 @@ GitHub Releases page; `0.8.0` is the new starting line.
15
15
 
16
16
  ## Unreleased
17
17
 
18
+ ## 0.27.0 (2026-05-31)
19
+
20
+ ### What changed in this release
21
+
22
+ - **`/feedback` submits structured reports with redacted session context.** A new
23
+ `/feedback [bug|feature|ux|wrong] [message]` command collects recent session context
24
+ and strips sensitive file contents before sending, shows a confirmation preview, and
25
+ falls back to opening a prefilled GitHub issue when direct submission is unavailable.
26
+ - **Fresh releases surface in the startup update prompt immediately.** The pre-start
27
+ update prompt now revalidates a cached "already current" answer with a bounded
28
+ conditional request instead of waiting for the 24-hour background-check throttle.
29
+ Release promotion also waits for exact native assets, PyPI, and the Homebrew tap
30
+ before marking a version latest, so installed clients no longer resolve a release
31
+ before its install channel is ready.
32
+ - **Background agent recovery preserves terminal task state.** Recovery now re-reads
33
+ task runtime under the store update lock before marking orphaned agent work
34
+ recoverable, so a stale snapshot can no longer clobber a task that completed.
35
+ - **Project memory recall keeps the simple lexical path.** The unused SQLite FTS
36
+ retriever seam and dead recall path argument are removed; collaborators now use
37
+ a public memory-store root accessor instead of reaching into private methods.
38
+ - **Shell prompt echoes and background todo rows are clearer.** Transcript echoes now
39
+ show the resolved submitted text for pasted-content placeholders, and background
40
+ todo rows align continuation icons with the first row.
41
+ - **StrReplaceFile now refuses ambiguous single replacements.** A non-`replace_all` edit now
42
+ errors when `old` matches more than once instead of silently editing the first match. Add
43
+ surrounding context to make the old string unique, or pass `replace_all=true` when every
44
+ occurrence should change.
45
+
46
+ Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.27.0`, or use the native installer for your OS (see the README install table).
47
+
18
48
  ## 0.26.0 (2026-05-30)
19
49
 
20
50
  ### What changed in this release
@@ -77,7 +77,8 @@ These principles govern every engineering response. They override speed: a slow
77
77
  - No "flexibility" or "configurability" that wasn't requested.
78
78
  - No error handling for impossible scenarios; validate at boundaries only.
79
79
  - If a 200-line draft could be 50 lines, rewrite it before showing it.
80
- - Self-check: *"Would a senior engineer call this overcomplicated?"* If yes, simplify.
80
+ - Over-fragmentation is overcomplication too: don't scatter logic across many tiny files or extra abstraction layers to satisfy a design pattern. Match the codebase's existing granularity.
81
+ - Self-check: *"Would a senior engineer call this overcomplicated or over-engineered?"* If yes, simplify.
81
82
 
82
83
  **3. Goal-driven execution — define success criteria, then loop until verified.**
83
84
  - Transform vague tasks into verifiable goals before writing code:
@@ -7,6 +7,7 @@ import subprocess
7
7
  import sys
8
8
  import threading
9
9
  import time
10
+ from collections.abc import Callable
10
11
  from pathlib import Path
11
12
  from typing import TYPE_CHECKING, Any, Literal
12
13
 
@@ -262,15 +263,19 @@ class BackgroundTaskManager:
262
263
  self._store.write_runtime(task_id, runtime)
263
264
  raise
264
265
 
265
- runtime = self._store.read_runtime(task_id)
266
- if runtime.finished_at is None and (
267
- runtime.status == "created"
268
- or (runtime.status == "starting" and runtime.worker_pid is None)
269
- ):
266
+ def mark_worker_started(runtime: TaskRuntime) -> bool:
267
+ if runtime.finished_at is not None:
268
+ return False
269
+ if runtime.status != "created" and not (
270
+ runtime.status == "starting" and runtime.worker_pid is None
271
+ ):
272
+ return False
270
273
  runtime.status = "starting"
271
274
  runtime.worker_pid = worker_pid
272
275
  runtime.updated_at = time.time()
273
- self._store.write_runtime(task_id, runtime)
276
+ return True
277
+
278
+ self._store.update_runtime(task_id, mark_worker_started)
274
279
  view = self._store.merged_view(task_id)
275
280
  self._journal_task_milestone("background task started", view)
276
281
  return view
@@ -630,14 +635,17 @@ class BackgroundTaskManager:
630
635
  ``TaskRuntime`` — closing the window where a process crash between
631
636
  :meth:`finalize_agent_task`'s two writes, or between :meth:`kill` and the
632
637
  runner's cancellation handler, left the two records divergent.
638
+
639
+ The runtime is re-read under the store's update lock before recovery so a
640
+ stale ``TaskView`` snapshot cannot overwrite an authoritative terminal
641
+ status that was written after the snapshot was created.
633
642
  """
634
643
  agent_id_raw = (view.spec.kind_payload or {}).get("agent_id")
635
644
  agent_id = agent_id_raw if isinstance(agent_id_raw, str) else None
636
- runtime_status: TaskStatus = view.runtime.status
637
- if not is_terminal_status(runtime_status):
638
- if view.spec.id in self._live_agent_tasks:
639
- return
640
- runtime = view.runtime.model_copy()
645
+
646
+ def recover_orphan(runtime: TaskRuntime) -> bool:
647
+ if is_terminal_status(runtime.status) or view.spec.id in self._live_agent_tasks:
648
+ return False
641
649
  runtime.finished_at = now
642
650
  runtime.updated_at = now
643
651
  runtime.status = "recoverable" if agent_id is not None else "lost"
@@ -647,9 +655,10 @@ class BackgroundTaskManager:
647
655
  if agent_id is not None
648
656
  else "In-process background agent is no longer running"
649
657
  )
650
- self._store.write_runtime(view.spec.id, runtime)
651
- runtime_status = runtime.status
652
- self._reconcile_subagent_status(agent_id, runtime_status, live_agent_ids)
658
+ return True
659
+
660
+ runtime = self._store.update_runtime(view.spec.id, recover_orphan)
661
+ self._reconcile_subagent_status(agent_id, runtime.status, live_agent_ids)
653
662
 
654
663
  def _reconcile_subagent_status(
655
664
  self, agent_id: str | None, runtime_status: TaskStatus, live_agent_ids: set[str]
@@ -810,105 +819,113 @@ class BackgroundTaskManager:
810
819
  if subagent_status is not None:
811
820
  self._runtime.subagent_store.update_instance(agent_id, status=subagent_status)
812
821
 
813
- def _mark_task_running(self, task_id: str) -> None:
814
- with self._store._runtime_lock(task_id): # pyright: ignore[reportPrivateUsage]
815
- runtime = self._store.read_runtime(task_id)
822
+ def _transition_status(
823
+ self,
824
+ task_id: str,
825
+ *,
826
+ mutate: Callable[[TaskRuntime], None],
827
+ ) -> TaskRuntime | None:
828
+ """Locked, terminal-guarded status write via the public store API.
829
+
830
+ Stamps ``updated_at`` then applies ``mutate``. Returns the resulting
831
+ runtime when the transition was applied, or ``None`` when the task was
832
+ already terminal (no write performed, so callers skip telemetry).
833
+ """
834
+ applied = False
835
+
836
+ def _apply(runtime: TaskRuntime) -> bool:
837
+ nonlocal applied
816
838
  if is_terminal_status(runtime.status):
817
- return
818
- runtime.status = "running"
839
+ return False
819
840
  runtime.updated_at = time.time()
841
+ mutate(runtime)
842
+ applied = True
843
+ return True
844
+
845
+ runtime = self._store.update_runtime(task_id, _apply)
846
+ return runtime if applied else None
847
+
848
+ def _mark_task_running(self, task_id: str) -> None:
849
+ def mutate(runtime: TaskRuntime) -> None:
850
+ runtime.status = "running"
820
851
  runtime.heartbeat_at = runtime.updated_at
821
852
  runtime.failure_reason = None
822
- self._store._write_runtime_unlocked(task_id, runtime) # pyright: ignore[reportPrivateUsage]
853
+
854
+ self._transition_status(task_id, mutate=mutate)
823
855
 
824
856
  def _mark_task_awaiting_approval(self, task_id: str, reason: str) -> None:
825
- with self._store._runtime_lock(task_id): # pyright: ignore[reportPrivateUsage]
826
- runtime = self._store.read_runtime(task_id)
827
- if is_terminal_status(runtime.status):
828
- return
857
+ def mutate(runtime: TaskRuntime) -> None:
829
858
  runtime.status = "awaiting_approval"
830
- runtime.updated_at = time.time()
831
859
  runtime.failure_reason = reason
832
- self._store._write_runtime_unlocked(task_id, runtime) # pyright: ignore[reportPrivateUsage]
860
+
861
+ self._transition_status(task_id, mutate=mutate)
833
862
 
834
863
  def _mark_task_completed(self, task_id: str) -> None:
835
- with self._store._runtime_lock(task_id): # pyright: ignore[reportPrivateUsage]
836
- runtime = self._store.read_runtime(task_id)
837
- if is_terminal_status(runtime.status):
838
- return
864
+ def mutate(runtime: TaskRuntime) -> None:
839
865
  runtime.status = "completed"
840
- runtime.updated_at = time.time()
841
866
  runtime.finished_at = runtime.updated_at
842
867
  runtime.failure_reason = None
843
- self._store._write_runtime_unlocked(task_id, runtime) # pyright: ignore[reportPrivateUsage]
844
- from pythinker_code.telemetry import track
845
868
 
846
- if runtime.started_at and runtime.finished_at:
847
- duration = runtime.finished_at - runtime.started_at
848
- track("background_task_completed", success=True, duration_s=duration)
869
+ runtime = self._transition_status(task_id, mutate=mutate)
870
+ if runtime is not None and runtime.started_at and runtime.finished_at:
871
+ from pythinker_code.telemetry import track
872
+
873
+ track(
874
+ "background_task_completed",
875
+ success=True,
876
+ duration_s=runtime.finished_at - runtime.started_at,
877
+ )
849
878
 
850
879
  def _mark_task_failed(self, task_id: str, reason: str) -> None:
851
- with self._store._runtime_lock(task_id): # pyright: ignore[reportPrivateUsage]
852
- runtime = self._store.read_runtime(task_id)
853
- if is_terminal_status(runtime.status):
854
- return
880
+ def mutate(runtime: TaskRuntime) -> None:
855
881
  runtime.status = "failed"
856
- runtime.updated_at = time.time()
857
882
  runtime.finished_at = runtime.updated_at
858
883
  runtime.failure_reason = reason
859
- self._store._write_runtime_unlocked(task_id, runtime) # pyright: ignore[reportPrivateUsage]
860
- from pythinker_code.telemetry import track
861
884
 
862
- if runtime.started_at and runtime.finished_at:
863
- duration = runtime.finished_at - runtime.started_at
885
+ runtime = self._transition_status(task_id, mutate=mutate)
886
+ if runtime is not None and runtime.started_at and runtime.finished_at:
887
+ from pythinker_code.telemetry import track
888
+
864
889
  track(
865
890
  "background_task_completed",
866
891
  success=False,
867
- duration_s=duration,
892
+ duration_s=runtime.finished_at - runtime.started_at,
868
893
  reason="error",
869
894
  )
870
895
 
871
896
  def _mark_task_timed_out(self, task_id: str, reason: str) -> None:
872
- with self._store._runtime_lock(task_id): # pyright: ignore[reportPrivateUsage]
873
- runtime = self._store.read_runtime(task_id)
874
- if is_terminal_status(runtime.status):
875
- return
897
+ def mutate(runtime: TaskRuntime) -> None:
876
898
  runtime.status = "failed"
877
- runtime.updated_at = time.time()
878
899
  runtime.finished_at = runtime.updated_at
879
900
  runtime.interrupted = True
880
901
  runtime.timed_out = True
881
902
  runtime.failure_reason = reason
882
- self._store._write_runtime_unlocked(task_id, runtime) # pyright: ignore[reportPrivateUsage]
883
- from pythinker_code.telemetry import track
884
903
 
885
- if runtime.started_at and runtime.finished_at:
886
- duration = runtime.finished_at - runtime.started_at
904
+ runtime = self._transition_status(task_id, mutate=mutate)
905
+ if runtime is not None and runtime.started_at and runtime.finished_at:
906
+ from pythinker_code.telemetry import track
907
+
887
908
  track(
888
909
  "background_task_completed",
889
910
  success=False,
890
- duration_s=duration,
911
+ duration_s=runtime.finished_at - runtime.started_at,
891
912
  reason="timeout",
892
913
  )
893
914
 
894
915
  def _mark_task_killed(self, task_id: str, reason: str) -> None:
895
- with self._store._runtime_lock(task_id): # pyright: ignore[reportPrivateUsage]
896
- runtime = self._store.read_runtime(task_id)
897
- if is_terminal_status(runtime.status):
898
- return
916
+ def mutate(runtime: TaskRuntime) -> None:
899
917
  runtime.status = "killed"
900
- runtime.updated_at = time.time()
901
918
  runtime.finished_at = runtime.updated_at
902
919
  runtime.interrupted = True
903
920
  runtime.failure_reason = reason
904
- self._store._write_runtime_unlocked(task_id, runtime) # pyright: ignore[reportPrivateUsage]
905
- from pythinker_code.telemetry import track
906
921
 
907
- if runtime.started_at and runtime.finished_at:
908
- duration = runtime.finished_at - runtime.started_at
922
+ runtime = self._transition_status(task_id, mutate=mutate)
923
+ if runtime is not None and runtime.started_at and runtime.finished_at:
924
+ from pythinker_code.telemetry import track
925
+
909
926
  track(
910
927
  "background_task_completed",
911
928
  success=False,
912
- duration_s=duration,
929
+ duration_s=runtime.finished_at - runtime.started_at,
913
930
  reason="killed",
914
931
  )
@@ -6,6 +6,7 @@ import os
6
6
  import re
7
7
  import shutil
8
8
  import time
9
+ from collections.abc import Callable
9
10
  from contextlib import contextmanager
10
11
  from pathlib import Path
11
12
 
@@ -139,6 +140,18 @@ class BackgroundTaskStore:
139
140
  with self._runtime_lock(task_id):
140
141
  self._write_runtime_unlocked(task_id, runtime)
141
142
 
143
+ def update_runtime(self, task_id: str, update: Callable[[TaskRuntime], bool]) -> TaskRuntime:
144
+ """Apply a read-modify-write update under the runtime lock.
145
+
146
+ ``update`` mutates the current runtime and returns true when it should
147
+ be written back. The current runtime is returned either way.
148
+ """
149
+ with self._runtime_lock(task_id):
150
+ runtime = self.read_runtime(task_id)
151
+ if update(runtime):
152
+ self._write_runtime_unlocked(task_id, runtime)
153
+ return runtime
154
+
142
155
  def _write_runtime_unlocked(self, task_id: str, runtime: TaskRuntime) -> None:
143
156
  """Write runtime without acquiring the per-task lock (caller holds it)."""
144
157
  path = self.runtime_path(task_id)