briefloop 0.27.1__tar.gz → 0.28.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 (519) hide show
  1. {briefloop-0.27.1/src/briefloop.egg-info → briefloop-0.28.0}/PKG-INFO +3 -1
  2. {briefloop-0.27.1 → briefloop-0.28.0}/README.md +2 -0
  3. {briefloop-0.27.1 → briefloop-0.28.0}/pyproject.toml +1 -1
  4. briefloop-0.28.0/src/briefloop/__init__.py +1 -0
  5. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/cli.py +8 -0
  6. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/external_client.py +17 -4
  7. briefloop-0.28.0/src/briefloop/external_mcp.py +177 -0
  8. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/external_requests.py +3 -2
  9. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/server.py +1 -1
  10. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/skill_assets/briefloop-external/SKILL.md +2 -0
  11. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/app.js +1 -1
  12. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/index.html +1 -1
  13. {briefloop-0.27.1 → briefloop-0.28.0/src/briefloop.egg-info}/PKG-INFO +3 -1
  14. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop.egg-info/SOURCES.txt +1 -0
  15. briefloop-0.27.1/src/briefloop/__init__.py +0 -1
  16. {briefloop-0.27.1 → briefloop-0.28.0}/LICENSE +0 -0
  17. {briefloop-0.27.1 → briefloop-0.28.0}/THIRD_PARTY_NOTICES.md +0 -0
  18. {briefloop-0.27.1 → briefloop-0.28.0}/setup.cfg +0 -0
  19. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/__main__.py +0 -0
  20. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/_entrypoint.py +0 -0
  21. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/agent_commands.py +0 -0
  22. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/agent_prompts.py +0 -0
  23. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/analyst.py +0 -0
  24. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/analyst_drafts.py +0 -0
  25. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/app_server.py +0 -0
  26. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/audit_bundle.py +0 -0
  27. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/backends/__init__.py +0 -0
  28. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/backends/opencode_server.py +0 -0
  29. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/backends/opencode_v2.py +0 -0
  30. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/bocha.py +0 -0
  31. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/bridge_harness.py +0 -0
  32. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/chat_dispatch.py +0 -0
  33. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/chat_execution.py +0 -0
  34. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/chat_store.py +0 -0
  35. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/chat_tools.py +0 -0
  36. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/codex_diagnostics.py +0 -0
  37. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/company_context.py +0 -0
  38. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/comparison_contract.py +0 -0
  39. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/conflicts.py +0 -0
  40. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/MATERIALS.md +0 -0
  41. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/README.md +0 -0
  42. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/__init__.py +0 -0
  43. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/config.py +0 -0
  44. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/grants.py +0 -0
  45. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/materials.py +0 -0
  46. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/receipts.py +0 -0
  47. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/runtime.py +0 -0
  48. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/runtime_tools.py +0 -0
  49. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/service.py +0 -0
  50. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/stdio_supervisor.py +0 -0
  51. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/task_client.py +0 -0
  52. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/tasks.py +0 -0
  53. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/transport.py +0 -0
  54. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/connectors/windows_acl.py +0 -0
  55. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/default_fonts.py +0 -0
  56. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/deliverable_spec.py +0 -0
  57. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/delivery_checks.py +0 -0
  58. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/demo.py +0 -0
  59. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/document_export.py +0 -0
  60. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/document_model.py +0 -0
  61. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/document_workflows.py +0 -0
  62. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/docx_text.py +0 -0
  63. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/draft_checks.py +0 -0
  64. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/draft_completion.py +0 -0
  65. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/duckduckgo.py +0 -0
  66. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/evaluation_reading.py +0 -0
  67. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/evidence.py +0 -0
  68. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/evidence_context.py +0 -0
  69. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/execution_records.py +0 -0
  70. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/execution_timing.py +0 -0
  71. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/export_jobs.py +0 -0
  72. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/exports.py +0 -0
  73. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/fact_check.py +0 -0
  74. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/fast_mode.py +0 -0
  75. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/fast_reports.py +0 -0
  76. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/fast_research.py +0 -0
  77. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/feedback_view.py +0 -0
  78. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/figure_support.py +0 -0
  79. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/figure_text.py +0 -0
  80. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/figures.py +0 -0
  81. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/finding_anchors.py +0 -0
  82. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/harness.py +0 -0
  83. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/host_bins.py +0 -0
  84. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/industry_data.py +0 -0
  85. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/industry_export.py +0 -0
  86. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/interactive_runtime.py +0 -0
  87. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/jev.py +0 -0
  88. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/jev_checks.py +0 -0
  89. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/learning.py +0 -0
  90. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/learning_budget.py +0 -0
  91. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/length.py +0 -0
  92. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/media.py +0 -0
  93. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/model_budget.py +0 -0
  94. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/models.py +0 -0
  95. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/native_engine.py +0 -0
  96. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/native_harness.py +0 -0
  97. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/native_orchestrator.py +0 -0
  98. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/native_providers.py +0 -0
  99. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/native_roles.py +0 -0
  100. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/notifications.py +0 -0
  101. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/office_cli.py +0 -0
  102. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/ooxml_order.py +0 -0
  103. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/opencode_harness.py +0 -0
  104. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/opencode_version.py +0 -0
  105. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/packet_views.py +0 -0
  106. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/parent_watch.py +0 -0
  107. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/plain_isolation.py +0 -0
  108. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/platform_support.py +0 -0
  109. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/previous_report.py +0 -0
  110. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/process_host.py +0 -0
  111. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/progress.py +0 -0
  112. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/projections.py +0 -0
  113. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/core.zh.md +0 -0
  114. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/mode.background.zh.md +0 -0
  115. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/mode.interactive.zh.md +0 -0
  116. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/role.analyst.zh.md +0 -0
  117. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/role.chat.zh.md +0 -0
  118. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/role.evaluator.zh.md +0 -0
  119. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/role.fact_checker.zh.md +0 -0
  120. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/role.maintainer.zh.md +0 -0
  121. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/role.orchestrator.zh.md +0 -0
  122. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/role.proposer.zh.md +0 -0
  123. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/role.quick_writer.zh.md +0 -0
  124. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/role.reviewer.zh.md +0 -0
  125. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/prompt_assets/role.scout.zh.md +0 -0
  126. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/provider_catalog.py +0 -0
  127. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/readers.py +0 -0
  128. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/reconciliation.py +0 -0
  129. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/release.py +0 -0
  130. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/report_browsing.py +0 -0
  131. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/report_profiles.py +0 -0
  132. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/report_time.py +0 -0
  133. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/report_tools.py +0 -0
  134. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/research_budget.py +0 -0
  135. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/research_handoff.py +0 -0
  136. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/research_plan.py +0 -0
  137. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/review.py +0 -0
  138. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/review_capability.py +0 -0
  139. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/review_learning.py +0 -0
  140. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/revision_edits.py +0 -0
  141. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/revision_metadata.py +0 -0
  142. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/revision_policy.py +0 -0
  143. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/rpc_writer.py +0 -0
  144. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/runtime.py +0 -0
  145. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/runtime_bridge.py +0 -0
  146. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/runtime_permissions.py +0 -0
  147. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/runtime_reasoning.py +0 -0
  148. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/schedules.py +0 -0
  149. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/scout.py +0 -0
  150. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/scout_coverage.py +0 -0
  151. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/scout_evidence.py +0 -0
  152. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/scout_tools.py +0 -0
  153. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/search_credentials.py +0 -0
  154. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/search_policy.py +0 -0
  155. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/skill_assets/duckduckgo/SKILL.md +0 -0
  156. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/skill_assets/multi-search/SKILL.md +0 -0
  157. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/skill_assets/tavily/SKILL.md +0 -0
  158. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/skill_verification.py +0 -0
  159. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/skills.py +0 -0
  160. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/software_version.py +0 -0
  161. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/source_context.py +0 -0
  162. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/source_extraction.py +0 -0
  163. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/source_ingestion.py +0 -0
  164. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/source_library_search.py +0 -0
  165. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/source_search.py +0 -0
  166. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/source_updates.py +0 -0
  167. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/sources.py +0 -0
  168. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/frontend-licenses.txt +0 -0
  169. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/native-engine-licenses.txt +0 -0
  170. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/native-engine-models.json +0 -0
  171. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/native-engine.mjs +0 -0
  172. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-aider.png +0 -0
  173. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-amr.svg +0 -0
  174. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-antigravity.svg +0 -0
  175. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-bridge.LICENSE.txt +0 -0
  176. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-bridge.NOTICE.txt +0 -0
  177. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-bridge.mjs +0 -0
  178. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-briefloop.svg +0 -0
  179. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-claude.svg +0 -0
  180. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-codebuddy.svg +0 -0
  181. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-codex.svg +0 -0
  182. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-copilot.svg +0 -0
  183. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-cursor-agent.svg +0 -0
  184. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-deepseek.svg +0 -0
  185. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-devin.png +0 -0
  186. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-grok-build.svg +0 -0
  187. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-hermes.svg +0 -0
  188. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-kilo.svg +0 -0
  189. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-kimi.svg +0 -0
  190. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-kiro.svg +0 -0
  191. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-mimo.svg +0 -0
  192. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-opencode.svg +0 -0
  193. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-pi.svg +0 -0
  194. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-qoder.svg +0 -0
  195. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-qwen.svg +0 -0
  196. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-reasoning.json +0 -0
  197. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-reasonix.svg +0 -0
  198. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-trae-cli.png +0 -0
  199. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/runtime-vibe.svg +0 -0
  200. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/style.css +0 -0
  201. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/static/tokens.css +0 -0
  202. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/store.py +0 -0
  203. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/task_labels.py +0 -0
  204. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/task_notify.py +0 -0
  205. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/task_progress.py +0 -0
  206. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/tavily.py +0 -0
  207. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/academic-paper-zh-t1.docx +0 -0
  208. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/academic-paper-zh-t1.spec.json +0 -0
  209. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/academic-paper-zh-t2.docx +0 -0
  210. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/academic-paper-zh-t2.spec.json +0 -0
  211. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/academic-paper-zh-t3.docx +0 -0
  212. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/academic-paper-zh-t3.spec.json +0 -0
  213. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/academic-paper-zh-t4.docx +0 -0
  214. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/academic-paper-zh-t4.spec.json +0 -0
  215. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/academic-paper-zh-t5.docx +0 -0
  216. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/academic-paper-zh-t5.spec.json +0 -0
  217. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/annual-report-zh-t1.docx +0 -0
  218. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/annual-report-zh-t1.spec.json +0 -0
  219. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/annual-report-zh-t2.docx +0 -0
  220. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/annual-report-zh-t2.spec.json +0 -0
  221. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/annual-report-zh-t3.docx +0 -0
  222. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/annual-report-zh-t3.spec.json +0 -0
  223. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/annual-report-zh-t4.docx +0 -0
  224. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/annual-report-zh-t4.spec.json +0 -0
  225. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/annual-report-zh-t5.docx +0 -0
  226. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/annual-report-zh-t5.spec.json +0 -0
  227. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/business-report-zh-t1.docx +0 -0
  228. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/business-report-zh-t1.spec.json +0 -0
  229. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/business-report-zh-t2.docx +0 -0
  230. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/business-report-zh-t2.spec.json +0 -0
  231. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/business-report-zh-t3.docx +0 -0
  232. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/business-report-zh-t3.spec.json +0 -0
  233. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/business-report-zh-t4.docx +0 -0
  234. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/business-report-zh-t4.spec.json +0 -0
  235. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/business-report-zh-t5.docx +0 -0
  236. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/business-report-zh-t5.spec.json +0 -0
  237. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-en-t1.docx +0 -0
  238. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-en-t1.spec.json +0 -0
  239. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-en-t2.docx +0 -0
  240. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-en-t2.spec.json +0 -0
  241. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-en-t3.docx +0 -0
  242. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-en-t3.spec.json +0 -0
  243. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-en-t4.docx +0 -0
  244. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-en-t4.spec.json +0 -0
  245. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-en-t5.docx +0 -0
  246. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-en-t5.spec.json +0 -0
  247. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-zh-t1.docx +0 -0
  248. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-zh-t1.spec.json +0 -0
  249. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-zh-t2.docx +0 -0
  250. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-zh-t2.spec.json +0 -0
  251. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-zh-t3.docx +0 -0
  252. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-zh-t3.spec.json +0 -0
  253. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-zh-t4.docx +0 -0
  254. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-zh-t4.spec.json +0 -0
  255. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-zh-t5.docx +0 -0
  256. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/general-report-zh-t5.spec.json +0 -0
  257. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/government-doc-zh-t4.docx +0 -0
  258. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/government-doc-zh-t4.spec.json +0 -0
  259. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/legal-contract-zh-t1.docx +0 -0
  260. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/legal-contract-zh-t1.spec.json +0 -0
  261. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/legal-contract-zh-t2.docx +0 -0
  262. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/legal-contract-zh-t2.spec.json +0 -0
  263. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/legal-contract-zh-t3.docx +0 -0
  264. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/legal-contract-zh-t3.spec.json +0 -0
  265. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/legal-contract-zh-t4.docx +0 -0
  266. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/legal-contract-zh-t4.spec.json +0 -0
  267. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/legal-contract-zh-t5.docx +0 -0
  268. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/legal-contract-zh-t5.spec.json +0 -0
  269. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/meeting-minutes-zh-t1.docx +0 -0
  270. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/meeting-minutes-zh-t1.spec.json +0 -0
  271. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/meeting-minutes-zh-t2.docx +0 -0
  272. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/meeting-minutes-zh-t2.spec.json +0 -0
  273. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/meeting-minutes-zh-t3.docx +0 -0
  274. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/meeting-minutes-zh-t3.spec.json +0 -0
  275. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/meeting-minutes-zh-t4.docx +0 -0
  276. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/meeting-minutes-zh-t4.spec.json +0 -0
  277. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/meeting-minutes-zh-t5.docx +0 -0
  278. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/meeting-minutes-zh-t5.spec.json +0 -0
  279. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-en-t1.docx +0 -0
  280. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-en-t1.spec.json +0 -0
  281. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-en-t2.docx +0 -0
  282. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-en-t2.spec.json +0 -0
  283. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-en-t3.docx +0 -0
  284. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-en-t3.spec.json +0 -0
  285. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-en-t4.docx +0 -0
  286. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-en-t4.spec.json +0 -0
  287. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-en-t5.docx +0 -0
  288. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-en-t5.spec.json +0 -0
  289. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-zh-t1.docx +0 -0
  290. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-zh-t1.spec.json +0 -0
  291. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-zh-t2.docx +0 -0
  292. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-zh-t2.spec.json +0 -0
  293. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-zh-t3.docx +0 -0
  294. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-zh-t3.spec.json +0 -0
  295. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-zh-t4.docx +0 -0
  296. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-zh-t4.spec.json +0 -0
  297. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-zh-t5.docx +0 -0
  298. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_assets/stock-research-zh-t5.spec.json +0 -0
  299. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/template_conversion.py +0 -0
  300. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/templates.py +0 -0
  301. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/user_input.py +0 -0
  302. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/websearch.py +0 -0
  303. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/windows_process.py +0 -0
  304. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/word_import.py +0 -0
  305. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workbook_figures.py +0 -0
  306. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/business_report/evaluation.md +0 -0
  307. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/business_report/manifest.json +0 -0
  308. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/business_report/methods/decision_memo.md +0 -0
  309. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/business_report/methods/industry_periodic.md +0 -0
  310. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/business_report/methods/work_progress.md +0 -0
  311. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/business_report/planning.md +0 -0
  312. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/business_report/writing.md +0 -0
  313. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/general_report/evaluation.md +0 -0
  314. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/general_report/manifest.json +0 -0
  315. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/general_report/planning.md +0 -0
  316. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/general_report/writing.md +0 -0
  317. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/meeting_minutes/evaluation.md +0 -0
  318. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/meeting_minutes/manifest.json +0 -0
  319. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/meeting_minutes/planning.md +0 -0
  320. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/meeting_minutes/writing.md +0 -0
  321. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/stock_research/evaluation.md +0 -0
  322. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/stock_research/manifest.json +0 -0
  323. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/stock_research/methods/company_research.md +0 -0
  324. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/stock_research/methods/event_commentary.md +0 -0
  325. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/stock_research/methods/industry_tracking.md +0 -0
  326. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/stock_research/planning.md +0 -0
  327. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workflow_assets/stock_research/writing.md +0 -0
  328. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workspace_profile.py +0 -0
  329. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/workspaces.py +0 -0
  330. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/writer_assembly.py +0 -0
  331. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/writer_input.py +0 -0
  332. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/writing_guidance.py +0 -0
  333. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/xlsx_export.py +0 -0
  334. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop/zhipu.py +0 -0
  335. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop.egg-info/dependency_links.txt +0 -0
  336. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop.egg-info/entry_points.txt +0 -0
  337. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop.egg-info/requires.txt +0 -0
  338. {briefloop-0.27.1 → briefloop-0.28.0}/src/briefloop.egg-info/top_level.txt +0 -0
  339. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/__init__.py +0 -0
  340. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/__main__.py +0 -0
  341. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/_licenses/LICENSE +0 -0
  342. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/_licenses/NOTICE.md +0 -0
  343. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/_licenses/third_party/acorn/LICENSE +0 -0
  344. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/_licenses/third_party/acorn/NOTICE.md +0 -0
  345. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/_licenses/third_party/officeqa/LICENSE-APACHE +0 -0
  346. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/_licenses/third_party/officeqa/NOTICE +0 -0
  347. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/alfworld/__init__.py +0 -0
  348. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/alfworld/act.sh +0 -0
  349. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/alfworld/rollout.py +0 -0
  350. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/alfworld/step.py +0 -0
  351. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/benchmarks/__init__.py +0 -0
  352. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/benchmarks/alfworld.py +0 -0
  353. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/benchmarks/livemath.py +0 -0
  354. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/benchmarks/sealqa.py +0 -0
  355. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/benchmarks/spreadsheet.py +0 -0
  356. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/cli.py +0 -0
  357. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/codex_identity.py +0 -0
  358. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/engine.py +0 -0
  359. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/feedback_loop.py +0 -0
  360. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/isolated/__init__.py +0 -0
  361. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/isolated/audit.py +0 -0
  362. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/isolated/runtime.py +0 -0
  363. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/isolated/tools_server.py +0 -0
  364. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/jsonl.py +0 -0
  365. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/k4_lock.py +0 -0
  366. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/livemath/__init__.py +0 -0
  367. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/livemath/loop.py +0 -0
  368. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/livemath/rollout.py +0 -0
  369. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/native_agents.py +0 -0
  370. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/officeqa/__init__.py +0 -0
  371. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/officeqa/dataset.py +0 -0
  372. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/officeqa/fetch.py +0 -0
  373. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/officeqa/loop.py +0 -0
  374. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/officeqa/retrieval.py +0 -0
  375. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/officeqa/reward.py +0 -0
  376. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/officeqa/rollout.py +0 -0
  377. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/officeqa/scoring.py +0 -0
  378. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/officeqa/wiki_agents.py +0 -0
  379. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/paper_alignment/__init__.py +0 -0
  380. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/paper_alignment/contracts.py +0 -0
  381. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/paper_alignment/evidence.py +0 -0
  382. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/product.py +0 -0
  383. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/product_cli.py +0 -0
  384. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/product_install.py +0 -0
  385. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/product_views.py +0 -0
  386. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/alfworld/id_split/split_manifest.json +0 -0
  387. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/alfworld/id_split/test.json +0 -0
  388. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/alfworld/id_split/train.json +0 -0
  389. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/alfworld/id_split/val.json +0 -0
  390. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/alfworld/wiki/SKILL-s0.md +0 -0
  391. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/alfworld/wiki/index.md +0 -0
  392. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/alfworld/wiki/logs.md +0 -0
  393. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/alfworld/wiki/prompts/maintainer.md +0 -0
  394. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/alfworld/wiki/prompts/proposer.md +0 -0
  395. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/alfworld/wiki/skill-impact.md +0 -0
  396. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/isolated/model-catalog-direct.json +0 -0
  397. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/id_split/split_manifest.json +0 -0
  398. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/id_split/test.json +0 -0
  399. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/id_split/train.json +0 -0
  400. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/id_split/val.json +0 -0
  401. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/id_split-v2/split_manifest.json +0 -0
  402. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/id_split-v2/test.json +0 -0
  403. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/id_split-v2/train.json +0 -0
  404. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/id_split-v2/val.json +0 -0
  405. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/protocol.json +0 -0
  406. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/wiki/SKILL-s0.md +0 -0
  407. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/wiki/index.md +0 -0
  408. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/wiki/logs.md +0 -0
  409. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/wiki/prompts/maintainer.md +0 -0
  410. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/wiki/prompts/proposer.md +0 -0
  411. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/livemath/wiki/skill-impact.md +0 -0
  412. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/officeqa/id_split/split_manifest.json +0 -0
  413. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/officeqa/id_split/test.json +0 -0
  414. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/officeqa/id_split/train.json +0 -0
  415. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/officeqa/id_split/val.json +0 -0
  416. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/officeqa/protocol.json +0 -0
  417. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/officeqa/wiki/SKILL-s0.md +0 -0
  418. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/officeqa/wiki/index.md +0 -0
  419. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/officeqa/wiki/logs.md +0 -0
  420. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/officeqa/wiki/prompts/maintainer.md +0 -0
  421. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/officeqa/wiki/prompts/proposer.md +0 -0
  422. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/officeqa/wiki/skill-impact.md +0 -0
  423. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/paper_alignment/README.md +0 -0
  424. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/paper_alignment/prompts/maintainer.paper.md +0 -0
  425. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/paper_alignment/prompts/officeqa.paper.md +0 -0
  426. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/paper_alignment/prompts/proposer.paper.md +0 -0
  427. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/paper_alignment/prompts/spreadsheet.paper.md +0 -0
  428. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/agents/claude-code/wikiskill-executor.md +0 -0
  429. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/agents/claude-code/wikiskill-maintainer.md +0 -0
  430. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/agents/claude-code/wikiskill-proposer.md +0 -0
  431. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/agents/codex/wikiskill-executor.toml +0 -0
  432. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/agents/codex/wikiskill-maintainer.toml +0 -0
  433. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/agents/codex/wikiskill-proposer.toml +0 -0
  434. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/entry-skill/SKILL.md +0 -0
  435. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/entry-skill/agents/openai.yaml +0 -0
  436. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/entry-skill/references/native-subagents.md +0 -0
  437. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/entry-skill/references/workflow.md +0 -0
  438. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/roles/executor.md +0 -0
  439. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/roles/maintainer.md +0 -0
  440. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/product/roles/proposer.md +0 -0
  441. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/final-20260907/manifest.json +0 -0
  442. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/final-20260907/math-episodes.json +0 -0
  443. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/final-20260907/sealqa-pairs.json +0 -0
  444. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/final-20260907/spreadsheet-SKILL.md +0 -0
  445. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/final-20260907/spreadsheet-pairs.json +0 -0
  446. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/final-20260907/summary.json +0 -0
  447. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/repeatability-20260908/example-provenance.json +0 -0
  448. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/repeatability-20260908/installed-smoke.json +0 -0
  449. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/repeatability-20260908/manifest.json +0 -0
  450. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/repeatability-20260908/repeat1-pairs.json +0 -0
  451. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/repeatability-20260908/repeat2-pairs.json +0 -0
  452. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/repeatability-20260908/repeat3-pairs.json +0 -0
  453. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/repeatability-20260908/summary.json +0 -0
  454. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/repeatability-20260908/wiki-deliver-the-recalculated-workbook.md +0 -0
  455. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/skills/livemath/55.md +0 -0
  456. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/skills/livemath/luna.md +0 -0
  457. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/skills/officeqa/55.md +0 -0
  458. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/skills/officeqa/terra.md +0 -0
  459. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/skills/officeqa-retrieval/55.md +0 -0
  460. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/skills/officeqa-retrieval/sol.md +0 -0
  461. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/skills/sealqa/sol.md +0 -0
  462. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/skills/spreadsheet/55.md +0 -0
  463. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/skills/spreadsheet/sol.md +0 -0
  464. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/snapshot.json +0 -0
  465. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/snapshot.sha256 +0 -0
  466. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260906/livemath-luna-pairs.json +0 -0
  467. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260906/livemath-luna-skill.md +0 -0
  468. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260906/manifest.json +0 -0
  469. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260906/officeqa-luna-skill.md +0 -0
  470. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260906/officeqa-sol-skill.md +0 -0
  471. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260906/officeqa-sol-v2-pairs.json +0 -0
  472. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260906/studies.json +0 -0
  473. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260907/effort-analysis.json +0 -0
  474. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260907/effort-pairs.json +0 -0
  475. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260907/manifest.json +0 -0
  476. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260907/officeqa-luna-paper-tools-pairs.json +0 -0
  477. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260907/officeqa-luna-paper-tools-skill.md +0 -0
  478. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260907/spreadsheet-luna-scoped-python-pairs.json +0 -0
  479. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260907/spreadsheet-luna-scoped-python-skill.md +0 -0
  480. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/research/update-20260907/studies.json +0 -0
  481. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/runtime/acorn.mjs +0 -0
  482. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/runtime/audit_js.mjs +0 -0
  483. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/sealqa/id_split/split_manifest.json +0 -0
  484. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/sealqa/id_split/test.json +0 -0
  485. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/sealqa/id_split/train.json +0 -0
  486. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/sealqa/id_split/val.json +0 -0
  487. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/sealqa/protocol.json +0 -0
  488. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/sealqa/wiki/SKILL-s0.md +0 -0
  489. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/sealqa/wiki/index.md +0 -0
  490. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/sealqa/wiki/logs.md +0 -0
  491. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/sealqa/wiki/prompts/maintainer.md +0 -0
  492. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/sealqa/wiki/prompts/proposer.md +0 -0
  493. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/sealqa/wiki/skill-impact.md +0 -0
  494. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/spreadsheet/id_split/split_manifest.json +0 -0
  495. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/spreadsheet/id_split/test.json +0 -0
  496. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/spreadsheet/id_split/train.json +0 -0
  497. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/spreadsheet/id_split/val.json +0 -0
  498. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/spreadsheet/protocol.json +0 -0
  499. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/spreadsheet/wiki/SKILL-s0.md +0 -0
  500. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/spreadsheet/wiki/index.md +0 -0
  501. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/spreadsheet/wiki/logs.md +0 -0
  502. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/spreadsheet/wiki/prompts/maintainer.md +0 -0
  503. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/spreadsheet/wiki/prompts/proposer.md +0 -0
  504. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/resources/spreadsheet/wiki/skill-impact.md +0 -0
  505. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/results.py +0 -0
  506. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/score_rules.py +0 -0
  507. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/scorer_trust.py +0 -0
  508. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/sealqa/__init__.py +0 -0
  509. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/sealqa/loop.py +0 -0
  510. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/sealqa/rollout.py +0 -0
  511. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/settings.py +0 -0
  512. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/skill_proposer.py +0 -0
  513. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/spreadsheet/__init__.py +0 -0
  514. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/spreadsheet/loop.py +0 -0
  515. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/spreadsheet/rollout.py +0 -0
  516. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/spreadsheet/study.py +0 -0
  517. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/tool_audit.py +0 -0
  518. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/wiki.py +0 -0
  519. {briefloop-0.27.1 → briefloop-0.28.0}/src/wikiskill/wiki_maintainer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: briefloop
3
- Version: 0.27.1
3
+ Version: 0.28.0
4
4
  Summary: Local multi-runtime agent workbench for sourced briefings, independent review and skill learning
5
5
  Author: Stahl-G
6
6
  License-Expression: MIT
@@ -286,6 +286,8 @@ briefloop external --workspace "/absolute/workspace" request --file request.json
286
286
 
287
287
  详见 [外部 Agent 调用文档](docs/WorkBuddy外部入口.md)、[随包 Skill 与请求示例](src/briefloop/skill_assets/briefloop-external/SKILL.md);官网提供 [调用指南](https://briefloop.ai/docs/external-agent.html)。
288
288
 
289
+ 下一版增加本机 stdio MCP 服务:客户端执行 `briefloop mcp --workspace "/absolute/workspace"`,即可发现与 external 相同的报告工具。启动时固定工作区路径和身份;不启动后台服务、不新增网络监听。配置示例、工具参数及异步查询方式见 [MCP 调用说明](docs/WorkBuddy外部入口.md#本机-stdio-mcp)。
290
+
289
291
  会议纪要内容方法:选择内置纪要模板即可建议相应用途,输入本次会议转写或笔记,整理决议、待办和未定事项。见 [会议纪要说明与合成材料](docs/会议纪要.md)。
290
292
 
291
293
  证券研究方法提供事件点评、公司研究和行业跟踪,按来源区分实际、预测与估值假设,使用有依据的数据生成图表。见 [证券研究说明与合成材料](docs/证券研究.md)。
@@ -246,6 +246,8 @@ briefloop external --workspace "/absolute/workspace" request --file request.json
246
246
 
247
247
  详见 [外部 Agent 调用文档](docs/WorkBuddy外部入口.md)、[随包 Skill 与请求示例](src/briefloop/skill_assets/briefloop-external/SKILL.md);官网提供 [调用指南](https://briefloop.ai/docs/external-agent.html)。
248
248
 
249
+ 下一版增加本机 stdio MCP 服务:客户端执行 `briefloop mcp --workspace "/absolute/workspace"`,即可发现与 external 相同的报告工具。启动时固定工作区路径和身份;不启动后台服务、不新增网络监听。配置示例、工具参数及异步查询方式见 [MCP 调用说明](docs/WorkBuddy外部入口.md#本机-stdio-mcp)。
250
+
249
251
  会议纪要内容方法:选择内置纪要模板即可建议相应用途,输入本次会议转写或笔记,整理决议、待办和未定事项。见 [会议纪要说明与合成材料](docs/会议纪要.md)。
250
252
 
251
253
  证券研究方法提供事件点评、公司研究和行业跟踪,按来源区分实际、预测与估值假设,使用有依据的数据生成图表。见 [证券研究说明与合成材料](docs/证券研究.md)。
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "briefloop"
7
- version = "0.27.1"
7
+ version = "0.28.0"
8
8
  description = "Local multi-runtime agent workbench for sourced briefings, independent review and skill learning"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -0,0 +1 @@
1
+ __version__ = "0.28.0"
@@ -51,6 +51,8 @@ def main():
51
51
  er.add_argument('--file',required=True,help='UTF-8 JSON 请求文件')
52
52
  ed=es.add_parser('download',help='下载指定已完成导出任务的Word,不覆盖不同内容的文件')
53
53
  ed.add_argument('--job',required=True);ed.add_argument('--output',required=True)
54
+ mcp=sub.add_parser('mcp',help='stdio MCP 服务;只连接用户选定的现有本机工作区')
55
+ mcp.add_argument('--workspace',required=True,help='已选择工作区的绝对路径;不自动创建或启动服务')
54
56
  tool=sub.add_parser('tool',help='agent 使用的来源工具')
55
57
  tool.add_argument('--workspace',required=True)
56
58
  ts=tool.add_subparsers(dest='tool',required=True)
@@ -136,6 +138,12 @@ def main():
136
138
  print(json.dumps(result,ensure_ascii=False))
137
139
  except (OSError,ValueError,KeyError,http.client.HTTPException) as exc:
138
140
  p.exit(2,json.dumps({'status':'error','message':sanitize(str(exc))},ensure_ascii=False)+'\n')
141
+ elif a.command=='mcp':
142
+ from .external_mcp import serve as serve_mcp
143
+ try:serve_mcp(a.workspace)
144
+ except ValueError as exc:
145
+ from .execution_records import sanitize
146
+ p.exit(2,sanitize(str(exc))+'\n')
139
147
  elif a.command=='serve':
140
148
  from .server import serve
141
149
  serve(a.workspace,a.port,paused=a.paused,backend=a.backend)
@@ -10,6 +10,13 @@ from urllib.parse import urlsplit, urlencode
10
10
  from .workspaces import _workspace_id, _validated_info, _alive, _read_api
11
11
 
12
12
 
13
+ class RequestError(ValueError):
14
+ """HTTP status without reflecting the server's possibly input-bearing error."""
15
+ def __init__(self, status):
16
+ self.status = status
17
+ super().__init__(f'外部请求失败 (HTTP {status})')
18
+
19
+
13
20
  def discover(workspace):
14
21
  root = Path(workspace).expanduser().resolve()
15
22
  wid = _workspace_id(root) if root.is_dir() else None
@@ -22,13 +29,19 @@ def discover(workspace):
22
29
  if urlsplit(info['url']).hostname != '127.0.0.1':
23
30
  return {**result, 'status': 'service_unavailable', 'message': '工作区未使用受支持的本地服务地址'}
24
31
  try:
32
+ caps = _read_api(info['url'], '/api/external/capabilities')
33
+ if caps.get('protocol') != 1:
34
+ return {**result, 'status': 'unsupported', 'message': '此版本未提供外部任务接口'}
35
+ service_path = caps.get('workspace_path')
36
+ if (not isinstance(service_path, str) or not Path(service_path).is_absolute()
37
+ or Path(service_path).resolve() != root or caps.get('workspace_id') != wid):
38
+ return {**result, 'status': 'identity_changed', 'message': '服务与选定工作区的路径或身份不匹配,未连接'}
39
+ # Verify only the narrow identity response before reading runtime/task
40
+ # state or obtaining a session token from a possibly copied service URL.
25
41
  runtime = _read_api(info['url'], '/api/runtime')
26
42
  status = _read_api(info['url'], '/api/service-status')
27
- caps = _read_api(info['url'], '/api/external/capabilities')
28
43
  if runtime.get('server_pid') != info['pid'] or status.get('pid') != info['pid'] or status.get('workspace_id') != wid:
29
44
  return {**result, 'status': 'identity_changed', 'message': '服务与工作区身份不匹配,未连接'}
30
- if caps.get('protocol') != 1:
31
- return {**result, 'status': 'unsupported', 'message': '此版本未提供外部任务接口'}
32
45
  ready = bool(runtime.get('worker_alive')) and not status.get('draining')
33
46
  return {**result, 'url': info['url'], 'pid': info['pid'], 'ready': ready,
34
47
  'status': 'ready' if ready else 'not_ready', 'capabilities': caps}
@@ -60,7 +73,7 @@ class Client:
60
73
  raise ValueError('响应过大;请通过 BriefLoop 页面读取报告')
61
74
  value = json.loads(data)
62
75
  if response.status != 200:
63
- raise ValueError(value.get('error', '外部请求失败') + f' (HTTP {response.status})')
76
+ raise RequestError(response.status)
64
77
  return value
65
78
  finally:
66
79
  connection.close()
@@ -0,0 +1,177 @@
1
+ """Stdio MCP adapter to the existing, authenticated local external client.
2
+
3
+ No Store, Worker, credentials, model calls or HTTP listener live in this process.
4
+ The selected canonical path and durable workspace identity cannot be changed by
5
+ tool arguments or by replacing the workspace while a client is connected.
6
+ """
7
+ import http.client
8
+ import json
9
+ from pathlib import Path
10
+
11
+ import anyio
12
+ from jsonschema import Draft202012Validator
13
+ from mcp.server import Server
14
+ from mcp.server.stdio import stdio_server
15
+ from mcp.types import CallToolResult, ListToolsResult, TextContent, Tool, ToolAnnotations
16
+
17
+ from . import __version__
18
+ from .external_client import Client, RequestError, discover
19
+ from .external_requests import FIELDS, MUTATIONS
20
+ from .workspaces import _workspace_id
21
+
22
+
23
+ ID = {'type': 'string', 'minLength': 1}
24
+ REQUEST_ID = {'type': 'string', 'pattern': r'^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$'}
25
+ PROPERTIES = {
26
+ 'source_id': ID, 'job_id': ID, 'version_id': ID, 'base_version': ID,
27
+ 'requirements': {'type': 'object'}, 'editor_document': {'type': 'object'},
28
+ 'source_ids': {'type': 'array', 'items': ID},
29
+ }
30
+ DESCRIPTIONS = {
31
+ 'discover': '检查启动时选定工作区的现有服务和能力;不创建或启动服务。',
32
+ 'inspect': '列出选定工作区最近 100 个来源和 20 个稿件;返回真实 ID。',
33
+ 'source': '读取指定来源正文和出处。source_id 必须来自该工作区。',
34
+ 'submit': '提交报告,立即返回 job_id/run_id;用 query 查进度。沿用工作区模型、企业背景与需求规则。每次新写操作使用稳定 request_id;响应丢失仅重发原 ID 和原内容。',
35
+ 'query': '查询原 job_id 的实际状态、安全错误、版本和 Word 文件可用性;不重建失败任务。latest_version_id 可来自后续修订。',
36
+ 'read': '读取精确 version_id 的 Markdown 和完整 editor_document。',
37
+ 'revise': '保存 base_version 的完整 editor_document 为新版本,保留图表、引用和未修改节点;已有新版本时报冲突。用稳定 request_id 重试原内容。',
38
+ 'export': '排队生成明确 version_id 的 Word 工作稿,立即返回 job_id;query 至 artifact_available=true 后 download。不代表正式交付审核通过。用稳定 request_id 重试原内容。',
39
+ 'download': '将已完成导出 job_id 的 Word 保存到明确 output 文件路径;父目录须已存在。校验 SHA256、复用相同文件,不覆盖不同内容,不重新排队。',
40
+ }
41
+
42
+
43
+ class WorkspaceUnavailable(ValueError):
44
+ pass
45
+
46
+
47
+ def failure(code, message):
48
+ return {'status': 'error', 'code': code, 'message': message}
49
+
50
+
51
+ def request_failure(status):
52
+ if status == 409:
53
+ return failure('conflict', '稿件已有更新或 request_id 已用于不同内容;请核对原请求,并重新读取最新版本后合并修订')
54
+ if status == 400:
55
+ return failure('invalid_request', '请求参数或报告配置不符合要求;请检查需求、来源 ID、完整富文档及工作区设置')
56
+ if status == 403:
57
+ return failure('access_denied', '本地服务拒绝鉴权;请重新连接用户选定的工作区')
58
+ if status == 503:
59
+ return failure('service_unavailable', '本地服务尚未就绪或正在停止接收任务;请查询原任务,不自动重建')
60
+ return failure('request_failed', '本地服务请求失败;写操作结果可能未知,请保留原 request_id 和原内容重试')
61
+
62
+
63
+ def tools():
64
+ catalog = []
65
+ for action, description in DESCRIPTIONS.items():
66
+ if action == 'download':
67
+ properties = {'job_id': ID, 'output': {'type': 'string', 'minLength': 1}}
68
+ required = list(properties)
69
+ else:
70
+ fields = FIELDS.get(action, set())
71
+ properties = {field: PROPERTIES[field] for field in sorted(fields)}
72
+ required = sorted(fields - ({'source_ids'} if action == 'submit' else set()))
73
+ if action in MUTATIONS:
74
+ properties['request_id'] = REQUEST_ID
75
+ required.append('request_id')
76
+ catalog.append(Tool(
77
+ name='briefloop_' + action, description=description,
78
+ input_schema={'type': 'object', 'properties': properties,
79
+ 'required': required, 'additionalProperties': False},
80
+ annotations=ToolAnnotations(
81
+ read_only_hint=action not in MUTATIONS | {'download'},
82
+ destructive_hint=False, idempotent_hint=True,
83
+ # Only submit can invoke models or research outside this
84
+ # workspace. Revise saves as author=agent, without learning.
85
+ open_world_hint=action == 'submit',
86
+ ),
87
+ ))
88
+ return catalog
89
+
90
+
91
+ class WorkspaceAdapter:
92
+ def __init__(self, workspace):
93
+ path = Path(workspace).expanduser()
94
+ if not path.is_absolute():
95
+ raise ValueError('--workspace 必须是用户选定工作区的绝对路径')
96
+ self.root = path.resolve()
97
+ self.workspace_id = _workspace_id(self.root) if self.root.is_dir() else None
98
+
99
+ def discovery(self):
100
+ info = discover(self.root)
101
+ if info.get('workspace_id') != self.workspace_id:
102
+ return {'path': str(self.root), 'workspace_id': self.workspace_id,
103
+ 'ready': False, 'status': 'identity_changed',
104
+ 'message': '工作区身份已变化;请重新启动 MCP 连接到用户选择的工作区'}
105
+ return info
106
+
107
+ def invoke(self, action, arguments):
108
+ if action == 'discover':
109
+ return self.discovery()
110
+ if not self.workspace_id:
111
+ raise WorkspaceUnavailable()
112
+ try:
113
+ client = Client(self.root)
114
+ except ValueError:
115
+ raise WorkspaceUnavailable() from None
116
+ if client.info['workspace_id'] != self.workspace_id:
117
+ raise WorkspaceUnavailable()
118
+ if action == 'download':
119
+ return client.download(arguments['job_id'], arguments['output'])
120
+ return client.request({'action': action, 'workspace_id': self.workspace_id, **arguments})
121
+
122
+
123
+ def create_server(workspace):
124
+ adapter = WorkspaceAdapter(workspace)
125
+ catalog = tools()
126
+ validators = {tool.name: Draft202012Validator(tool.input_schema) for tool in catalog}
127
+ limiter = anyio.CapacityLimiter(4)
128
+
129
+ async def list_tools(context, params):
130
+ return ListToolsResult(tools=catalog)
131
+
132
+ async def call_tool(context, params):
133
+ arguments = params.arguments if params.arguments is not None else {}
134
+ validator = validators.get(params.name)
135
+ # Never echo invalid arguments (which may contain credential-shaped
136
+ # values), validation traces or internal exception details to clients.
137
+ if validator is None:
138
+ value = failure('unknown_tool', '未知 BriefLoop 工具')
139
+ failed = True
140
+ elif not validator.is_valid(arguments):
141
+ value = failure('invalid_arguments', '工具参数不符合公布的 schema;不得传入其他工作区或服务地址')
142
+ failed = True
143
+ else:
144
+ try:
145
+ action = params.name.removeprefix('briefloop_')
146
+ value = await anyio.to_thread.run_sync(adapter.invoke, action, arguments, limiter=limiter)
147
+ failed = False
148
+ except WorkspaceUnavailable:
149
+ value = failure('workspace_unavailable', '选定工作区服务尚未就绪,或服务路径/身份不匹配;请在 BriefLoop 打开用户选定的工作区后重新连接')
150
+ failed = True
151
+ except RequestError as exc:
152
+ value = request_failure(exc.status)
153
+ failed = True
154
+ except (OSError, http.client.HTTPException):
155
+ value = failure('local_io_failed', '本地服务通信或文件操作失败;写操作结果可能未知,请使用原 request_id 和原内容重试')
156
+ failed = True
157
+ except (ValueError, KeyError):
158
+ value = failure('invalid_request', '请求、完整富文档或下载目标不符合要求;请检查指定 ID、父目录及目标文件,不覆盖不同内容')
159
+ failed = True
160
+ except Exception:
161
+ value = failure('request_failed', '本地外部请求失败;写操作结果可能未知,请用原 request_id 和原内容重试,勿新建任务')
162
+ failed = True
163
+ return CallToolResult(content=[TextContent(type='text', text=json.dumps(value, ensure_ascii=False))],
164
+ structured_content=value, is_error=failed)
165
+
166
+ return Server('BriefLoop', version=__version__, on_list_tools=list_tools, on_call_tool=call_tool,
167
+ instructions='仅操作启动时用户选定的本机工作区。先 discover 确认 ready,再 inspect/source。写操作保留原 request_id 与完整请求;submit/export 返回 job_id 后查询,不等待模型生成。修订先读取精确版本、保留完整富文档;Word 是指定版本的工作稿。MCP 取消或断开不取消已接收的后台任务;重连后查询原任务。')
168
+
169
+
170
+ def serve(workspace):
171
+ server = create_server(workspace)
172
+
173
+ async def run():
174
+ async with stdio_server() as (read, write):
175
+ await server.run(read, write, server.create_initialization_options())
176
+
177
+ anyio.run(run)
@@ -51,9 +51,10 @@ class _RequestStore(Store):
51
51
  return [dict(row) for row in self.connection.execute(query, args)]
52
52
 
53
53
 
54
- def capabilities():
54
+ def capabilities(store):
55
55
  return {'protocol': 1, 'actions': list(FIELDS), 'request_id_required': sorted(MUTATIONS),
56
- 'export_kind': 'working_draft', 'starts_service': False}
56
+ 'export_kind': 'working_draft', 'starts_service': False,
57
+ 'workspace_path': str(store.root.resolve()), 'workspace_id': store.meta('workspace_id')}
57
58
 
58
59
 
59
60
  def _operation(store, action, body):
@@ -256,7 +256,7 @@ def _make_server(workspace, port, *, paused, backend, lock):
256
256
  else:self.send(200,selected.snapshot(q['id'][0],int(q.get('after',['0'])[0]),reasoning=q.get('reasoning',['0'])[0]=='1'))
257
257
  elif u.path=='/api/external/capabilities':
258
258
  from .external_requests import capabilities
259
- self.send(200,capabilities())
259
+ self.send(200,capabilities(store))
260
260
  elif u.path=='/api/session':self.send(200,{'token':token,'upload_limits':{'max_file_bytes':MAX_UPLOAD_BYTES,'max_request_bytes':MAX_REQUEST_BYTES,'max_pdf_bytes':MAX_PDF_UPLOAD_BYTES}})
261
261
  elif u.path=='/api/service-status':self.send(200,_service_status(self.server))
262
262
  elif u.path=='/api/connectors':self.send(200,{'connectors':self.server.connectors.list()})
@@ -9,6 +9,8 @@ description: Use an existing local BriefLoop workspace from WorkBuddy or another
9
9
 
10
10
  ## 连接与提交
11
11
 
12
+ 支持 stdio MCP 的宿主可使用 `briefloop mcp --workspace "/absolute/workspace"`(随下一版发布)。先调用 `briefloop_discover` 确认 `ready=true`;其余工具为 `briefloop_inspect/source/submit/query/read/revise/export/download`,字段与下表和 CLI 下载参数一致,不传 `action`、工作区、URL 或 Token。`briefloop_download` 使用 `job_id` 和明确本机文件路径 `output`。连接固定启动时选定的绝对路径及工作区身份,不创建或启动后台。停止 MCP 连接不取消已接收任务,重连后查询原任务并用原 request_id、原内容重试未知写结果。
13
+
12
14
  使用已安装的 `briefloop`,或同一 Python 环境中的 `python -m briefloop`。先执行:
13
15
 
14
16
  ```sh
@@ -249,7 +249,7 @@ Please report this to https://github.com/markedjs/marked.`,t){let r="<p>An error
249
249
  <button type="button" data-edit="${v(m.id)}">\u4FEE\u6539</button><button type="button" data-delete="${v(m.id)}">\u79FB\u9664</button></div>
250
250
  <div data-remove="${v(m.id)}" class="connector-remove" hidden><p>\u79FB\u9664\u6B64\u8FDE\u63A5\u914D\u7F6E\u548C\u672C\u673A\u4FDD\u5B58\u7684\u8FDE\u63A5\u51ED\u636E\uFF1F\u5DF2\u6709\u62A5\u544A\u4E0E\u6765\u6E90\u4FDD\u7559\u3002</p><button type="button" data-op="delete" data-id="${v(m.id)}">\u786E\u8BA4\u79FB\u9664</button><button type="button" data-keep>\u4FDD\u7559</button></div></article>`}).join(""):'<p class="help">\u8FD8\u6CA1\u6709\u8FDE\u63A5\u5668\u3002\u6DFB\u52A0\u4E00\u4E2A MCP \u670D\u52A1\u540E\u5373\u53EF\u6D4B\u8BD5\u8FDE\u63A5\u3002</p>',t.querySelectorAll("[data-edit]").forEach(m=>m.onclick=()=>d(r.find(g=>g.id===m.dataset.edit))),t.querySelectorAll("[data-delete]").forEach(m=>m.onclick=()=>{m.closest("article").querySelector("[data-remove]").hidden=!1}),t.querySelectorAll("[data-keep]").forEach(m=>m.onclick=()=>{m.parentElement.hidden=!0}),t.querySelectorAll("[data-op]").forEach(m=>m.onclick=()=>h(async()=>{let g=await e("connectors/"+m.dataset.op,{connector_id:m.dataset.id});return await f(),m.dataset.op==="test"?g.ok?"\u8FDE\u63A5\u6D4B\u8BD5\u901A\u8FC7\u3002":g.error?.message||"\u8FDE\u63A5\u6D4B\u8BD5\u672A\u901A\u8FC7\u3002":g.error?g.error.message:(m.dataset.op==="delete"&&s===m.dataset.id&&(a.reset(),a.hidden=!0,s=null),{enable:"\u8FDE\u63A5\u5DF2\u542F\u7528\u3002",disable:"\u8FDE\u63A5\u5DF2\u505C\u7528\u3002",delete:"\u8FDE\u63A5\u914D\u7F6E\u5DF2\u79FB\u9664\u3002"}[m.dataset.op])},m.dataset.op==="test"?"\u6B63\u5728\u8FDE\u63A5\u5E76\u8BFB\u53D6\u80FD\u529B\u76EE\u5F55\u2026":"\u6B63\u5728\u5904\u7406\u8FDE\u63A5\u2026"))}async function f(){r=(await e("connectors")).connectors,p()}async function h(m,g="\u6B63\u5728\u4FDD\u5B58\u2026"){if(!i){i=!0,o("[data-status]").textContent=g,t.querySelectorAll("button").forEach(y=>y.disabled=!0);try{let y=await m();o("[data-status]").textContent=y||""}catch(y){o("[data-status]").textContent=y.message||"\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5\u3002"}finally{i=!1,t.querySelectorAll("button").forEach(y=>y.disabled=!1)}}}return a.onsubmit=m=>{m.preventDefault(),h(async()=>{let g=l("transport").value==="http",y={name:l("name").value,transport:l("transport").value,timeout_seconds:Number(l("timeout_seconds").value),max_response_bytes:Math.round(Number(l("max_response_mb").value)*1048576)};g?y.url=l("url").value.trim():Object.assign(y,{command:l("command").value.trim(),args:l("args").value.split(`
251
251
  `).filter(k=>k!==""),cwd:l("cwd").value.trim()||null});let b={config:y,connector_id:s};if(l("clear_credentials").checked)b.secrets={};else if(g&&l("credential_value").value){if(!["authorization","bearer"].includes(l("credential_type").value))throw Error("\u8BF7\u9009\u62E9\u65B0\u51ED\u636E\u7684\u8BA4\u8BC1\u65B9\u5F0F\u3002");b.secrets={[l("credential_type").value==="authorization"?"authorization_header":"bearer_token"]:l("credential_value").value}}else if(!g&&l("env").value.trim()){let k={};for(let x of l("env").value.split(`
252
- `).filter(C=>C.trim())){let C=x.indexOf("=");if(C<1)throw Error("\u6BCF\u884C\u73AF\u5883\u53D8\u91CF\u8BF7\u4F7F\u7528 NAME=VALUE \u683C\u5F0F\u3002");k[x.slice(0,C).trim()]=x.slice(C+1)}b.secrets={env:k}}return await e("connectors/save",b),a.reset(),a.hidden=!0,s=null,await f(),"\u914D\u7F6E\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u6D4B\u8BD5\u6216\u542F\u7528\u8FDE\u63A5\u3002"})},l("transport").onchange=c,o("[data-new]").onclick=()=>d(),o("[data-cancel]").onclick=()=>{a.reset(),a.hidden=!0,s=null},o("[data-refresh]").onclick=()=>h(f,"\u6B63\u5728\u8BFB\u53D6\u8FDE\u63A5\u72B6\u6001\u2026"),{refresh:()=>h(f,"\u6B63\u5728\u8BFB\u53D6\u8FDE\u63A5\u72B6\u6001\u2026")}}function HA(t,e,n,r){let s=[];for(let[o,a]of e){if(!a.resources.size&&!a.tools.size)continue;let l=t.find(c=>c.id===o);if(!l?.enabled||l.state!=="connected"||[...a.resources].some(c=>!l.capabilities?.resources?.some(d=>d.uri===c))||[...a.tools].some(c=>!l.capabilities?.tools?.some(d=>d.name===c)))throw Error("\u5DF2\u9009\u8FDE\u63A5\u5668\u6216\u6750\u6599\u4E0D\u518D\u53EF\u7528\uFF0C\u8BF7\u5237\u65B0\u5E76\u91CD\u65B0\u9009\u62E9")}for(let o of t){if(!o.enabled||o.state!=="connected")continue;let a=e.get(o.id);if(!a)continue;let l=(o.capabilities?.resources||[]).map(d=>d.uri).filter(d=>a.resources.has(d)),c=(o.capabilities?.tools||[]).map(d=>d.name).filter(d=>a.tools.has(d));(l.length||c.length)&&s.push({connector_id:o.id,resources:l,tools:c})}if(!s.length)return null;if(!Number.isInteger(n)||n<1||n>1e3)throw Error("\u8FDE\u63A5\u5668\u8C03\u7528\u6B21\u6570\u987B\u4E3A 1\u20131000 \u7684\u6574\u6570");if(!Number.isInteger(r)||r<1||r>1073741824)throw Error("\u8FDE\u63A5\u5668\u6750\u6599\u9884\u7B97\u987B\u4E3A 1\u20131024 MiB");let i=Math.max(...t.filter(o=>s.some(a=>a.connector_id===o.id)).map(o=>o.max_response_bytes||0));if(r<i)throw Error("\u6750\u6599\u9884\u7B97\u4E0D\u80FD\u5C0F\u4E8E\u6240\u9009\u8FDE\u63A5\u5668\u7684\u5355\u6B21\u54CD\u5E94\u4E0A\u9650");return{selections:s,max_calls:n,max_total_bytes:r}}function sv(t,e){let n=new Map,r=[],s=!1,i=!1;t.innerHTML='<details><summary>\u672C\u8F6E\u8FDE\u63A5\u5668\u6750\u6599\uFF08\u53EF\u9009\uFF09</summary><p class="help">\u9009\u62E9\u5141\u8BB8 BriefLoop \u8BFB\u53D6\u7684\u6750\u6599\u548C\u8C03\u7528\u7684\u5DE5\u5177\u3002\u8054\u7F51\u5F00\u5173\u5355\u72EC\u63A7\u5236\u516C\u5F00\u641C\u7D22\u3002</p><button type="button" class="outline" data-refresh>\u5237\u65B0\u8FDE\u63A5\u5668</button><p data-status role="status"></p><div data-catalog></div><div class="row"><label>\u8C03\u7528\u6B21\u6570\u4E0A\u9650<input type="number" data-calls min="1" max="1000" step="1" value="20"></label><label>\u6750\u6599\u603B\u91CF\u4E0A\u9650\uFF08MiB\uFF09<input type="number" data-bytes min="1" max="1024" step="1" value="20"></label></div><p class="help">\u4EC5\u52FE\u9009\u9879\u6388\u4E88\u672C\u8F6E\u4EFB\u52A1\uFF1B\u672A\u52FE\u9009\u65F6\u4E0D\u4F7F\u7528\u8FDE\u63A5\u5668\u3002\u8BFB\u53D6\u6210\u529F\u7684\u6750\u6599\u4F1A\u51FA\u73B0\u5728\u62A5\u544A\u6765\u6E90\u4E2D\u3002</p></details>';let o=c=>t.querySelector(c);function a(){let c=r.filter(d=>d.enabled);o("[data-catalog]").innerHTML=c.map(d=>{let p=n.get(d.id),f=d.capabilities||{},h=d.state==="connected";return`<fieldset><legend>${v(d.name||d.id)} \xB7 ${h?"\u5DF2\u8FDE\u63A5":"\u5C1A\u672A\u8FDE\u63A5"}</legend>${h?"":'<p class="help">\u8BF7\u5148\u5728\u8BBE\u7F6E\u4E2D\u542F\u7528\u5E76\u8FDE\u63A5\uFF0C\u518D\u5237\u65B0\u3002</p>'}${(f.resources||[]).map(m=>`<label class="check"><input type="checkbox" data-connector="${v(d.id)}" data-kind="resources" data-item="${v(m.uri)}" ${p?.resources.has(m.uri)?"checked":""}>${v(m.name||m.uri)}</label>`).join("")}${(f.tools||[]).map(m=>`<label class="check"><input type="checkbox" data-connector="${v(d.id)}" data-kind="tools" data-item="${v(m.name)}" ${p?.tools.has(m.name)?"checked":""}>${v(m.title||m.name)}${m.annotations?.readOnlyHint===!0?"\uFF08\u58F0\u660E\u53EA\u8BFB\uFF09":"\uFF08\u53EF\u80FD\u4FEE\u6539\u5916\u90E8\u6570\u636E\uFF0C\u8BF7\u786E\u8BA4\u7528\u9014\uFF09"}</label>`).join("")}${h&&!f.resources?.length&&!f.tools?.length?'<p class="help">\u672A\u63D0\u4F9B\u53EF\u9009\u6750\u6599\u6216\u5DE5\u5177\u3002</p>':""}</fieldset>`}).join("")||'<p class="help">\u6CA1\u6709\u5DF2\u542F\u7528\u7684\u8FDE\u63A5\u5668\u3002\u53EF\u5728\u8BBE\u7F6E \u2192 \u6570\u636E\u8FDE\u63A5\u5668\u4E2D\u6DFB\u52A0\u3002</p>',t.querySelectorAll("[data-item]").forEach(d=>d.onchange=()=>{let{connector:p,kind:f,item:h}=d.dataset;n.has(p)||n.set(p,{resources:new Set,tools:new Set});let m=n.get(p)[f];d.checked?m.add(h):m.delete(h)})}async function l(){if(!s){s=!0,o("[data-refresh]").disabled=!0,o("[data-status]").textContent="\u6B63\u5728\u8BFB\u53D6\u8FDE\u63A5\u5668\u2026";try{r=(await e("connectors")).connectors||[],i=!1,a(),o("[data-status]").textContent=""}catch(c){i=!0,o("[data-status]").textContent="\u65E0\u6CD5\u8BFB\u53D6\u8FDE\u63A5\u5668\uFF1A"+c.message}finally{s=!1,o("[data-refresh]").disabled=!1}}}return o("[data-refresh]").onclick=l,{refresh:l,selection(){if(s)throw Error("\u8FDE\u63A5\u5668\u76EE\u5F55\u6B63\u5728\u5237\u65B0\uFF0C\u8BF7\u7A0D\u540E\u63D0\u4EA4");if(i&&[...n.values()].some(c=>c.resources.size||c.tools.size))throw Error("\u8FDE\u63A5\u5668\u76EE\u5F55\u8BFB\u53D6\u5931\u8D25\uFF0C\u8BF7\u5237\u65B0\u540E\u63D0\u4EA4");return HA(r,n,Number(o("[data-calls]").value),Number(o("[data-bytes]").value)*1048576)}}}function iv({api:t,notice:e}){let n=null,r=null,s=!1,i="check";function o(d=n){if(!u("settings-view-updates"))return;let f=typeof window.briefloopDesktop?.updateStatus=="function";u("app-update-controls").hidden=!1,u("app-update-version").textContent=r?`BriefLoop v${r.version}${r.build?` \xB7 \u6784\u5EFA ${r.build}`:""}${f?` \xB7 \u684C\u9762 App v${d?.currentAppVersion||"\u8BFB\u53D6\u4E2D"}`:""}`:"\u6B63\u5728\u8BFB\u53D6\u5B9E\u9645\u8FD0\u884C\u7248\u672C\u2026";let h={desktop:"\u684C\u9762\u7BA1\u7406\u7684\u540E\u7AEF \xB7 App \u4E0E CLI \u5171\u7528",source:"\u5F00\u53D1\u6E90\u7801",pip:"Python \u5305\u5B89\u88C5",pipx:"pipx \u5B89\u88C5",uv:"uv \u5DE5\u5177\u5B89\u88C5"};u("app-update-installation").textContent=r?h[r.installation]||"\u72EC\u7ACB\u5B89\u88C5":"",u("app-update-command").hidden=!r?.update_command,u("app-update-command").textContent=r?.update_command||"",u("app-update-source").textContent=d?.source==="local-test"?"\u672C\u5730\u6D4B\u8BD5\u66F4\u65B0\u6E90 \xB7 \u4EC5\u9A8C\u8BC1\u6D41\u7A0B\uFF0C\u4E0D\u4EE3\u8868\u5B98\u65B9\u53D1\u5E03":f?"\u5B98\u65B9\u7A33\u5B9A\u6765\u6E90\uFF1AStahl-G/briefloop \xB7 GitHub Releases":"Python \u5305\u7A33\u5B9A\u6765\u6E90\uFF1APyPI \xB7 briefloop";let m=d?.source==="local-test"&&d?.reinstall===!0;u("app-update-guidance").textContent=f?d?.installMode==="zip"?"\u4F18\u5148\u589E\u91CF\u4E0B\u8F7D ZIP \u66F4\u65B0\u5305\u5E76\u6821\u9A8C\u5B8C\u6574\u6587\u4EF6\u3002\u4FDD\u5B58\u5E76\u9000\u51FA\u540E\u6253\u5F00 Finder\uFF1B\u5C06 BriefLoop \u62D6\u5230 Applications \u66FF\u6362\uFF0C\u518D\u91CD\u65B0\u542F\u52A8\u3002":d?.installMode==="dmg"?`\u4E0B\u8F7D\u540E\u4F1A\u5148\u4FDD\u5B58\u7F16\u8F91\u5E76\u5904\u7406\u5FD9\u4EFB\u52A1\uFF0C\u518D\u9000\u51FA App\u3001\u6253\u5F00 DMG\uFF1B\u8BF7\u5728 Finder \u4E2D${m?"\u91CD\u65B0\u5B89\u88C5\u5F53\u524D\u7248\u672C":"\u624B\u52A8\u5B89\u88C5\u65B0\u7248\u672C"}\u3002`:"\u4E0B\u8F7D\u540E\u4F1A\u5148\u4FDD\u5B58\u7F16\u8F91\u5E76\u5904\u7406\u5FD9\u4EFB\u52A1\uFF0C\u518D\u9000\u51FA App \u5E76\u4EA4\u7ED9\u539F\u751F\u5B89\u88C5\u5668\u66F4\u65B0\u3002":r?.guidance||"\u6B63\u5728\u8BFB\u53D6\u5B89\u88C5\u6765\u6E90\u2026";let g=d?.error?.operation||(d?.error?.code==="open_failed"?"install":i),b={idle:"\u5C1A\u672A\u68C0\u67E5\u66F4\u65B0",checking:"\u6B63\u5728\u68C0\u67E5\u66F4\u65B0\u2026",available:"\u53D1\u73B0\u53EF\u7528\u66F4\u65B0",current:"\u5F53\u524D App \u65E0\u9700\u66F4\u65B0",downloading:"\u6B63\u5728\u4E0B\u8F7D\u66F4\u65B0\u2026",downloaded:"\u4E0B\u8F7D\u5B8C\u6210\uFF0C\u7B49\u5F85\u5B89\u88C5",error:{check:"\u66F4\u65B0\u68C0\u67E5\u5931\u8D25\uFF08\u5F53\u524D\u5B89\u88C5\u4E0D\u53D7\u5F71\u54CD\uFF09",download:"\u66F4\u65B0\u5305\u4E0B\u8F7D\u672A\u5B8C\u6210",install:"\u66F4\u65B0\u5B89\u88C5\u672A\u5B8C\u6210"}[g]||"\u66F4\u65B0\u68C0\u67E5\u5931\u8D25\uFF08\u5F53\u524D\u5B89\u88C5\u4E0D\u53D7\u5F71\u54CD\uFF09"},k=`\u91CD\u65B0\u5B89\u88C5\u5F53\u524D App v${d?.currentAppVersion||""}`;u("app-update-status").textContent=f?m&&d?.state==="available"?k:(b[d?.state]||"\u6B63\u5728\u8BFB\u53D6 App \u7248\u672C\u2026")+(d?.state==="error"&&g==="check"?"":m?` \xB7 ${k}`:d?.releaseVersion?` \xB7 v${d.releaseVersion}`:""):{idle:"\u5C1A\u672A\u68C0\u67E5\u66F4\u65B0",checking:"\u6B63\u5728\u68C0\u67E5\u66F4\u65B0\u2026",available:`\u53D1\u73B0\u53EF\u7528\u540E\u7AEF\u7248\u672C v${d?.releaseVersion||""}`,current:"\u5F53\u524D\u540E\u7AEF\u5DF2\u662F PyPI \u6700\u65B0\u7A33\u5B9A\u7248",ahead:`\u5F53\u524D\u540E\u7AEF\u9AD8\u4E8E PyPI \u5DF2\u53D1\u5E03\u7248\u672C v${d?.releaseVersion||""}`,error:"\u7248\u672C\u68C0\u67E5\u672A\u5B8C\u6210"}[d?.state||"idle"]||"\u5C1A\u672A\u68C0\u67E5\u66F4\u65B0",u("app-update-download").textContent=m?"\u4E0B\u8F7D\u5F53\u524D\u7248\u672C\u5B89\u88C5\u5305":"\u4E0B\u8F7D\u66F4\u65B0";let x=s||["checking","downloading"].includes(d?.state);u("app-update-check").disabled=x,u("app-update-download").hidden=!f||d?.state!=="available",u("app-update-download").disabled=x,u("app-update-install").hidden=!f||d?.state!=="downloaded",u("app-update-install").disabled=x,u("app-update-install").textContent=d?.installMode==="zip"?"\u4FDD\u5B58\u5E76\u6253\u5F00\u66F4\u65B0\u6587\u4EF6\u5939":d?.installMode==="dmg"?"\u4FDD\u5B58\u5E76\u6253\u5F00 DMG":"\u4FDD\u5B58\u5E76\u5B89\u88C5\u66F4\u65B0",u("app-update-retry").hidden=d?.state!=="error"||!d?.retryable,u("app-update-retry").disabled=x,u("app-update-error").hidden=!d?.error,u("app-update-error").textContent=d?.error?.message||"";let C=d?.progress;u("app-update-progress-box").hidden=!C,u("app-update-progress").value=C?.percent||0,u("app-update-progress-text").textContent=C?`${Math.round(C.percent||0)}% \xB7 ${(Math.max(0,C.transferred||0)/1048576).toFixed(1)} / ${(Math.max(0,C.total||0)/1048576).toFixed(1)} MiB`:"",C?.mode==="differential"?u("app-update-progress-text").textContent+=` \xB7 \u589E\u91CF\u4E0B\u8F7D\uFF0C\u590D\u7528 ${(Math.max(0,C.reused||0)/1048576).toFixed(1)} MiB`:C?.mode==="full"&&(u("app-update-progress-text").textContent+=" \xB7 "+({no_baseline:"\u65E0\u6709\u6548\u57FA\u51C6\u7F13\u5B58\uFF0C\u5B8C\u6574\u4E0B\u8F7D\u5E76\u5EFA\u7ACB\u7F13\u5B58",little_reuse:"\u672C\u6B21\u53EF\u590D\u7528\u5185\u5BB9\u8F83\u5C11\uFF0C\u5B8C\u6574\u4E0B\u8F7D",range_unavailable:"\u4E0B\u8F7D\u670D\u52A1\u4E0D\u652F\u6301\u5206\u6BB5\u4F20\u8F93\uFF0C\u5B8C\u6574\u4E0B\u8F7D",range_size:"\u5206\u6BB5\u54CD\u5E94\u4E0D\u5B8C\u6574\uFF0C\u91CD\u65B0\u5B8C\u6574\u4E0B\u8F7D",delta_hash:"\u589E\u91CF\u91CD\u5EFA\u6821\u9A8C\u5931\u8D25\uFF0C\u91CD\u65B0\u5B8C\u6574\u4E0B\u8F7D",differential_unavailable:"\u589E\u91CF\u4E0D\u53EF\u7528\uFF0C\u5DF2\u56DE\u9000\u5B8C\u6574\u4E0B\u8F7D",blockmap_unavailable:"\u6B64\u7248\u672C\u65E0\u53EF\u7528\u589E\u91CF\u4FE1\u606F\uFF0C\u5B8C\u6574\u4E0B\u8F7D"}[C.fallback]||"\u5B8C\u6574\u4E0B\u8F7D")),u("app-update-notes-box").hidden=!d?.notes,u("app-update-notes").textContent=d?.notes||""}async function a(){o();try{r=await t("software-version"),typeof window.briefloopDesktop?.updateStatus=="function"&&(n=await window.briefloopDesktop.updateStatus()),o()}catch{e("\u65E0\u6CD5\u8BFB\u53D6 App \u66F4\u65B0\u72B6\u6001\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u8BBE\u7F6E\u3002",!0)}}async function l(d){if(s)return;let p=window.briefloopDesktop;if(typeof p?.updateStatus!="function"){if(d!=="check")return;s=!0,n={state:"checking"},o();try{n=await t("software-update-check",{}),r=n}catch(f){n={state:"error",retryable:!0,error:{message:f.message||"\u7248\u672C\u68C0\u67E5\u672A\u5B8C\u6210"}}}finally{s=!1,o()}return}s=!0,i=d,o();try{if(d==="install"){let f=await p.installUpdate();f?.cancelled&&e("\u5DF2\u4FDD\u7559\u5F53\u524D\u5DE5\u4F5C\u533A\uFF0C\u66F4\u65B0\u5305\u4ECD\u53EF\u7A0D\u540E\u5B89\u88C5\u3002"),f?.cancelled&&(n=await p.updateStatus())}else n=await(d==="download"?p.downloadUpdate():p.checkForUpdates())}catch(f){e(f.message||"\u66F4\u65B0\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5\u3002",!0);try{n=await p.updateStatus()}catch{}}finally{s=!1,o()}}function c(){u("settings-view-updates")&&(u("app-update-check").onclick=()=>l("check"),u("app-update-download").onclick=()=>l("download"),u("app-update-install").onclick=()=>l("install"),u("app-update-retry").onclick=()=>l(n?.error?.code==="open_failed"?"install":(n?.error?.operation||i)==="install"?"download":n?.error?.operation||i),window.briefloopDesktop?.onUpdateStatus?.(d=>{n=d,o()}),o())}return{init:c,renderAppUpdates:o,refreshAppUpdates:a,runAppUpdate:l}}var jA=[["taste","\u5199\u6CD5\u504F\u597D","\u539F\u7A3F\u6CA1\u9519\uFF0C\u53EA\u662F\u6211\u60F3\u8FD9\u6837\u5199"],["fact_correction","\u4E8B\u5B9E\u7EA0\u9519","\u539F\u7A3F\u7684\u6570\u5B57\u3001\u4E8B\u5B9E\u6216\u53E3\u5F84\u4E0D\u5BF9"],["reader_specific","\u53EA\u9488\u5BF9\u8FD9\u4F4D\u8BFB\u8005","\u6362\u4E00\u4F4D\u8BFB\u8005\u672A\u5FC5\u8981\u8FD9\u6837\u6539"]];function Ss(t,e=160){let n=String(t||"").replace(/\s+/g," ").trim();return n.length>e?n.slice(0,e)+"\u2026":n}function ov(t){let e=t.op==="delete"?`\u5220\u6389\u4E86\uFF1A<q>${v(Ss(t.before))}</q>`:t.op==="insert"?`\u52A0\u5165\u4E86\uFF1A<q>${v(Ss(t.after))}</q>`:`\u628A <q>${v(Ss(t.before))}</q> \u6539\u6210 <q>${v(Ss(t.after))}</q>`;return`<div class="revision-question" data-edit="${v(t.id)}"><p class="revision-question-where">${v(t.heading||"\u6B63\u6587")}</p><p>${e}</p><p class="help">\u4E3A\u4EC0\u4E48\u8FD9\u6837\u6539\uFF1F</p><div class="revision-question-choices">${jA.map(([n,r,s])=>`<button type="button" class="outline" data-answer="${n}" title="${v(s)}">${v(r)}</button>`).join("")}<button type="button" class="ghost" data-answer="skip" title="\u8FD9\u5904\u6539\u52A8\u4E0D\u8FDB\u5165\u5B66\u4E60">\u8DF3\u8FC7</button></div></div>`}function av({api:t,action:e,$:n=u}){function r(i){i.querySelectorAll("[data-answer]").forEach(o=>o.onclick=()=>{let a=o.closest("[data-edit]").dataset.edit,l=o.dataset.answer;e(()=>t("revision-answer",{edit_id:a,category:l}),l==="skip"?"\u5DF2\u8DF3\u8FC7\uFF0C\u8FD9\u5904\u6539\u52A8\u4E0D\u8FDB\u5165\u5B66\u4E60":l==="fact_correction"?"\u5DF2\u8BB0\u4E3A\u4E8B\u5B9E\u7EA0\u9519\uFF0C\u4E0D\u4F5C\u4E3A\u5199\u4F5C\u7ECF\u9A8C":l==="reader_specific"?"\u8BFB\u8005\u7279\u5B9A\u6539\u52A8\u5DF2\u4FDD\u7559\uFF1B\u672A\u7ED1\u5B9A\u8BFB\u8005\u65F6\u4FDD\u6301\u672A\u786E\u8BA4\uFF0C\u4E0D\u8FDB\u5165\u5168\u5C40\u5B66\u4E60":"\u5DF2\u8BB0\u4E0B\uFF0C\u4F1A\u8FDB\u5165\u4E0B\u4E00\u6B21\u5B66\u4E60")})}function s(i){let o=i?.questions||[],a=i?.unconfirmed||[],l=i?.fact_corrections||[],c=n("revision-questions");c&&(c.hidden=!o.length&&!a.length,c.innerHTML=o.length?`<h3>${o.length} \u5904\u6539\u52A8\u9700\u8981\u4F60\u786E\u8BA4\u539F\u56E0</h3><p class="help">\u53EA\u95EE\u62FF\u4E0D\u51C6\u3001\u6539\u52A8\u8F83\u5927\u7684\u5730\u65B9\u3002\u4E8B\u5B9E\u7EA0\u9519\u4E0D\u4F1A\u5199\u8FDB\u5199\u4F5C\u6280\u5DE7\uFF1B\u8DF3\u8FC7\u7684\u6539\u52A8\u4E0D\u8FDB\u5165\u5B66\u4E60\u3002</p>${o.map(ov).join("")}`:"",a.length&&(c.innerHTML+=`<details><summary>${a.length} \u5904\u672A\u786E\u8BA4\u6539\u52A8 \xB7 \u4E0D\u8FDB\u5165\u5B66\u4E60</summary><p class="help">\u65E0\u9700\u9010\u6761\u5904\u7406\u3002\u4F60\u4E5F\u53EF\u4EE5\u5C55\u5F00\u540E\u786E\u8BA4\u6539\u52A8\u539F\u56E0\u3002</p>${a.map(ov).join("")}</details>`),r(c));let d=n("fact-corrections");d&&(d.innerHTML=l.length?l.map(f=>`<div class="fact-correction"><small>${v(f.heading||"\u6B63\u6587")} \xB7 ${f.decided_by==="user"?"\u4F60\u786E\u8BA4":"Evaluator \u5224\u65AD"}</small><p><del>${v(Ss(f.before,120))}</del> \u2192 ${v(Ss(f.after,120))}</p></div>`).join(""):'<p class="help">\u8FD8\u6CA1\u6709\u4E8B\u5B9E\u7EA0\u9519\u8BB0\u5F55\u3002</p>');let p=n("revision-questions-hint");p&&(p.hidden=!o.length,p.textContent=o.length?`\u6709 ${o.length} \u5904\u6539\u52A8\u7B49\u4F60\u786E\u8BA4\u539F\u56E0\uFF0C\u5728\u201C\u7ECF\u9A8C\u201D\u9875\u5904\u7406\u3002`:"")}return{render:s}}function lv({$:t,esc:e,getState:n,openLearning:r}){let s=l=>{try{return typeof l=="string"?JSON.parse(l):l||{}}catch{return{}}},i={queued:"\u6392\u961F\u6574\u7406",running:"\u6B63\u5728\u6574\u7406",complete:"\u5DF2\u6574\u7406",failed:"\u6574\u7406\u5931\u8D25",interrupted:"\u6574\u7406\u4E2D\u65AD",cancelled:"\u6574\u7406\u5DF2\u505C\u6B62"};function o(){let l=n()||{},c=new Map((l.jobs||[]).filter(d=>d.kind==="learn").map(d=>[d.id,d]));return(l.feedback||[]).map(d=>{let p=s(d.data),f=c.get(d.batch_id),h="learning_status"in d?d.learning_status:f?.status,m=d.batch_id?i[h]||"\u6574\u7406\u72B6\u6001\u672A\u77E5":"\u5F85\u6574\u7406",g=d.kind==="revision"||d.kind==="revision_edit",y=p.summary||p.text||p.verified_reason||(g?"\u6539\u7A3F\u8BB0\u5F55":"\u53CD\u9988\u8BB0\u5F55"),b=g?"\u6539\u7A3F":d.kind==="review_correction"?"\u6838\u67E5\u4FEE\u8BA2":p.learning_intent==="explicit_requirement"?"\u5FC5\u987B\u4FDD\u7559\u7684\u8981\u6C42":"\u53CD\u9988";return{id:d.id,text:y,kind:b,status:m,pending:!d.batch_id,created:d.created}})}function a(){let l=o(),c=n()?.feedback_summary,d=c?.total??l.length,p=c?.pending??l.filter(y=>y.pending).length,f=d>l.length,h=c?`\u5171 ${d} \u6761\uFF0C\u5176\u4E2D ${p} \u6761\u5F85\u6574\u7406\u3002`:`\u6700\u8FD1 ${d} \u6761\uFF0C\u5176\u4E2D ${p} \u6761\u5F85\u6574\u7406\u3002`,m=t("feedback-list");m&&(m.innerHTML=`<h2>\u5DF2\u4FDD\u5B58\u7684\u53CD\u9988</h2><p class="help">${d?h:"\u8FD8\u6CA1\u6709\u4FDD\u5B58\u7684\u53CD\u9988\u3002"}${f?`\u4EC5\u663E\u793A\u6700\u8FD1 ${l.length} \u6761\u3002`:""}\u5F85\u6574\u7406\u7684\u53CD\u9988\u5728\u4F60\u70B9\u201C\u73B0\u5728\u6574\u7406\u6210\u7ECF\u9A8C\u201D\u6216\u5F00\u542F\u81EA\u52A8\u5B66\u4E60\u540E\uFF0C\u7531 Wiki \u7EF4\u62A4\u8005\u6574\u7406\uFF1B\u4E8B\u5B9E\u7EA0\u9519\u53EA\u8BB0\u5F55\uFF0C\u4E0D\u5199\u8FDB\u5199\u4F5C\u6280\u5DE7\u3002</p>`+(l.length?`<ul class="feedback-items">${l.map(y=>`<li><span class="chip">${e(y.status)}</span> <span class="help">${e(y.kind)} \xB7 ${e((y.created||"").slice(0,16).replace("T"," "))}</span><p>${e(y.text)}</p></li>`).join("")}</ul>`:""));let g=t("feedback-saved-hint");g&&(g.hidden=!d,g.innerHTML=d?`${c?"\u5DF2\u4FDD\u5B58":"\u6700\u8FD1\u5DF2\u4FDD\u5B58"} ${d} \u6761\u53CD\u9988${p?`\uFF0C${p} \u6761\u5F85\u6574\u7406`:""} \xB7 <button type="button" class="outline" data-feedback-open>\u67E5\u770B\u53CD\u9988</button>`:"",g.querySelector("[data-feedback-open]")?.addEventListener("click",r))}return{render:a,rows:o}}function cv({api:t,action:e,$:n=u}){let r=null,s=[],i=!1;function o(h,m){let g=n("reader-select");if(!g)return;let y=i?g.value:m??g.value;g.innerHTML='<option value="">\u4E0D\u6307\u5B9A\u8BFB\u8005\u6863\u6848</option>'+h.map(b=>`<option value="${v(b.id)}">${v(b.name)}</option>`).join(""),g.value=h.some(b=>b.id===y)?y:"",i=!0}function a(){let h=n("reader-select"),m=h?.form?.elements?.audience;if(!h||!m)return;let g=s.find(y=>y.id===h.value);g&&(!m.value.trim()||m.value==="\u81EA\u5DF1"||s.some(y=>y.name===m.value))&&(m.value=g.name)}function l(h){return`<div class="reader-profile" data-reader="${v(h.id)}"><div class="reader-profile-head"><strong>${v(h.name)}</strong><span>${h.skill_id?"\u5386\u53F2\u4E13\u5C5E\u6280\u80FD "+v(h.skill_id)+"\uFF08\u6682\u4E0D\u542F\u7528\uFF09":"\u4F7F\u7528\u5DE5\u4F5C\u533A\u6280\u80FD"}</span></div>${h.decisions?`<p><small>\u7528\u62A5\u544A\u505A\u4EC0\u4E48\u51B3\u5B9A</small>${v(h.decisions)}</p>`:""}${h.preferences?`<p><small>\u504F\u597D</small>${v(h.preferences)}</p>`:""}<div class="reader-profile-actions"><button type="button" class="outline" data-reader-edit>\u7F16\u8F91</button>${h.skill_id?'<button type="button" class="outline" data-reader-unbind>\u6E05\u9664\u5386\u53F2\u7ED1\u5B9A</button>':""}<button type="button" class="ghost" data-reader-archive>\u5F52\u6863</button></div>${h.wiki?`<details><summary>\u5386\u53F2\u8BFB\u8005\u7ECF\u9A8C\uFF08\u6682\u4E0D\u542F\u7528\uFF09</summary><pre class="reader-wiki">${v(h.wiki)}</pre></details>`:""}</div>`}function c(h){let m=n("reader-profiles");m&&(m.innerHTML=h.length?h.map(l).join(""):'<p class="help">\u8FD8\u6CA1\u6709\u8BFB\u8005\u6863\u6848\u3002\u5199\u7ED9\u56FA\u5B9A\u8BFB\u8005\u7684\u62A5\u544A\uFF0C\u5EFA\u4E00\u4E2A\u6863\u6848\u540E\uFF0C\u62A5\u544A\u4F1A\u8BB0\u5F55\u7528\u9014\u4E0E\u504F\u597D\u3002\u8BFB\u8005\u7279\u5B9A\u6539\u52A8\u5148\u4FDD\u7559\uFF0C\u7B49\u5F85\u9002\u7528\u6761\u4EF6\u4E0E\u8DE8\u8BFB\u8005\u9A8C\u8BC1\u3002</p>',m.querySelectorAll("[data-reader]").forEach(g=>{let y=h.find(k=>k.id===g.dataset.reader);g.querySelector("[data-reader-edit]").onclick=()=>d(y),g.querySelector("[data-reader-archive]").onclick=()=>e(()=>t("reader-archive",{id:y.id}),"\u8BFB\u8005\u6863\u6848\u5DF2\u5F52\u6863\uFF0C\u65E7\u62A5\u544A\u4FDD\u7559\u539F\u6837");let b=g.querySelector("[data-reader-unbind]");b&&(b.onclick=()=>e(()=>t("reader-skill",{reader_id:y.id,skill_id:null}),"\u5DF2\u6E05\u9664\u5386\u53F2\u4E13\u5C5E\u6280\u80FD\u7ED1\u5B9A"))}))}function d(h=null){let m=n("reader-form");m&&(r=h?.id||null,m.hidden=!1,m.elements.name.value=h?.name||"",m.elements.decisions.value=h?.decisions||"",m.elements.preferences.value=h?.preferences||"",m.querySelector("[data-reader-form-title]").textContent=h?"\u7F16\u8F91\u8BFB\u8005\u6863\u6848":"\u65B0\u5EFA\u8BFB\u8005\u6863\u6848",m.elements.name.focus?.())}function p(){let h=n("reader-add");h&&(h.onclick=()=>d());let m=n("reader-form");if(m){m.onsubmit=b=>{b.preventDefault();let k={name:m.elements.name.value,decisions:m.elements.decisions.value,preferences:m.elements.preferences.value,...r?{id:r}:{}};e(async()=>{await t("reader-save",k),m.hidden=!0,r=null},"\u8BFB\u8005\u6863\u6848\u5DF2\u4FDD\u5B58")};let y=m.querySelector("[data-reader-cancel]");y&&(y.onclick=()=>{m.hidden=!0,r=null})}let g=n("reader-select");g&&g.addEventListener("change",a)}function f(h=[],{readerId:m}={}){s=h,o(h,m),c(h)}return{render:f,bind:p,openForm:d}}function dv(t){if(!t)return"";let e=t.status==="untracked"&&!t.registration_conflict,n=e?"untracked":"pending",r=e?"\u65E0\u53EF\u8FFD\u8E2A\u6539\u52A8":"\u5F85\u9A8C\u6536",s=e?["\u6CA1\u6709\u53EF\u8FFD\u8E2A\u7684\u6539\u52A8"]:["\u521D\u6B65\u89C2\u5BDF\uFF0C\u672A\u9A8C\u6536",`\u5B8C\u6574\u6838\u9A8C ${t.observed||0} \u4EFD \xB7 \u672A\u77E5 ${t.unknown??t.reports??0} \u4EFD`];return t.flagged_reports&&s.push(`\u660E\u786E\u6807\u51FA\u590D\u53D1 ${t.repeats||0} \u6B21\uFF08${t.flagged_reports} \u4EFD\u62A5\u544A\uFF09`),t.excluded&&s.push(`\u8303\u56F4\u4E0D\u4E00\u81F4\uFF0C\u6392\u9664 ${t.excluded} \u4EFD`),t.registration_conflict&&s.push("\u540C\u4E00\u6280\u80FD\u5BF9\u5E94\u4E0D\u540C\u8BFB\u8005\u6216\u6279\u6B21\uFF0C\u7ED1\u5B9A\u5F85\u6F84\u6E05"),e||s.push(t.note||"\u5C1A\u672A\u5B8C\u6210\u5B8C\u6574\u590D\u53D1\u6838\u9A8C\u3001\u53CC\u6A21\u578B family \u6821\u51C6\u3001\u4EBA\u5DE5\u5206\u6B67\u5904\u7406\u4E0E\u7559\u51FA\u9A8C\u6536"),(t.legacy_status_corrected||["adopted","not_improving"].includes(t.status))&&s.push(t.legacy_note||"\u65E7\u81EA\u52A8\u72B6\u6001\u4E0D\u8BC1\u660E\u9A8C\u6536\uFF0C\u539F\u8BB0\u5F55\u4E0E\u6280\u80FD\u4FDD\u7559"),`<span class="skill-verification skill-verification-${v(n)}"><span class="tag">${v(r)}</span><small>${v(s.join(" \xB7 "))}</small></span>`}function FA(t){return`/discuss \u8FD9\u662F\u6211\u4EEC\u5DF2\u7ECF\u4EA4\u4ED8\u8FC7\u7684\u4E00\u671F\u62A5\u544A\u300A${t}\u300B\uFF08\u89C1\u9644\u4EF6\uFF09\u3002\u8BF7\u9605\u8BFB\u5B83\uFF0C\u53CD\u63A8\u8FD9\u4EFD\u5468\u671F\u62A5\u544A\u7684\u7B80\u62A5\u7EA6\u5B9A\uFF1A\u8BFB\u8005\u662F\u8C01\u3001\u8BFB\u5B8C\u8981\u505A\u4EC0\u4E48\u51B3\u5B9A\uFF1B\u6CBF\u7528\u7684\u7AE0\u8282\u7ED3\u6784\uFF1B\u6570\u5B57\u5355\u4F4D\u3001\u65F6\u95F4\u8303\u56F4\u4E0E\u6765\u6E90\u7B49\u53E3\u5F84\uFF1B\u6709\u660E\u786E\u4F9D\u636E\u7684\u7981\u533A\uFF08\u6CA1\u6709\u5199\u4E0D\u7B49\u4E8E\u7981\u6B62\uFF09\u3002\u5F80\u671F\u6570\u5B57\u4E0D\u662F\u672C\u671F\u4E8B\u5B9E\uFF1B\u5168\u90E8\u7EA6\u5B9A\u5148\u4F5C\u4E3A\u5F85\u786E\u8BA4\u5EFA\u8BAE\uFF0C\u770B\u4E0D\u51FA\u6765\u7684\u5217\u4E3A\u672A\u51B3\u9879\uFF0C\u4E0D\u8981\u731C\u3002\u6574\u7406\u597D\u540E\u7ED9\u51FA briefloop-requirements\uFF0C\u8BFB\u8005\u6E05\u695A\u65F6\u518D\u7ED9\u4E00\u4E2A briefloop-reader\u3002`}function WA(t){let e=/```briefloop-reader\s*([\s\S]*?)```/.exec(t||"");if(!e)return null;try{let n=JSON.parse(e[1].trim());return!n||typeof n.name!="string"||!n.name.trim()?null:{name:n.name.trim(),decisions:typeof n.decisions=="string"?n.decisions:"",preferences:typeof n.preferences=="string"?n.preferences:""}}catch{return null}}function uv({api:t,uploadPayload:e,getUploadLimits:n,openChat:r,notice:s,saveReader:i,$:o=u}){async function a(d){let p=await t("import-previous",await e(d,n(),{}));return await r({text:FA(p.title),source_id:p.source_id}),s(p.tracked_changes?"\u5DF2\u5BFC\u5165\u5F80\u671F\u62A5\u544A\uFF1B\u5176\u4E2D\u7684 Word \u4FEE\u8BA2\u5DF2\u8BB0\u4E3A\u6539\u7A3F\uFF0C\u4E0B\u6B21\u5B66\u4E60\u65F6\u5206\u7C7B\u3002\u786E\u8BA4\u540E\u628A\u8BF7\u6C42\u53D1\u7ED9 BriefLoop\u3002":"\u5DF2\u5BFC\u5165\u5F80\u671F\u62A5\u544A\u3002\u786E\u8BA4\u540E\u628A\u8BF7\u6C42\u53D1\u7ED9 BriefLoop\uFF0C\u5B83\u4F1A\u53CD\u63A8\u7B80\u62A5\u7EA6\u5B9A\u3002"),p}function l(){let d=o("previous-report-file");d&&(d.onchange=async p=>{let f=p.target.files[0];if(p.target.value="",!!f)try{await a(f)}catch(h){s(h.message,!0)}})}function c(d,p){let f=WA(p);if(!f||!i)return;let h=document.createElement("button");h.type="button",h.className="outline apply-requirements",h.textContent="\u4FDD\u5B58\u4E3A\u8BFB\u8005\u6863\u6848",h.onclick=()=>i(f),d.append(h)}return{bind:l,importFile:a,appendReaderAction:c}}function pv({api:t,getPlan:e,confirm:n,describePlan:r}){return async s=>{let i={job_id:s.id,use_current_model:!0};if(s.kind==="learn"){let o=e();if(!o||!n(`\u6309\u5F53\u524D\u6A21\u578B\u65B0\u5EFA\u5B66\u4E60\u5C1D\u8BD5\uFF0C\u4FDD\u7559\u539F\u4EFB\u52A1\u4E0E\u53CD\u9988\u3002
252
+ `).filter(C=>C.trim())){let C=x.indexOf("=");if(C<1)throw Error("\u6BCF\u884C\u73AF\u5883\u53D8\u91CF\u8BF7\u4F7F\u7528 NAME=VALUE \u683C\u5F0F\u3002");k[x.slice(0,C).trim()]=x.slice(C+1)}b.secrets={env:k}}return await e("connectors/save",b),a.reset(),a.hidden=!0,s=null,await f(),"\u914D\u7F6E\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u6D4B\u8BD5\u6216\u542F\u7528\u8FDE\u63A5\u3002"})},l("transport").onchange=c,o("[data-new]").onclick=()=>d(),o("[data-cancel]").onclick=()=>{a.reset(),a.hidden=!0,s=null},o("[data-refresh]").onclick=()=>h(f,"\u6B63\u5728\u8BFB\u53D6\u8FDE\u63A5\u72B6\u6001\u2026"),{refresh:()=>h(f,"\u6B63\u5728\u8BFB\u53D6\u8FDE\u63A5\u72B6\u6001\u2026")}}function HA(t,e,n,r){let s=[];for(let[o,a]of e){if(!a.resources.size&&!a.tools.size)continue;let l=t.find(c=>c.id===o);if(!l?.enabled||l.state!=="connected"||[...a.resources].some(c=>!l.capabilities?.resources?.some(d=>d.uri===c))||[...a.tools].some(c=>!l.capabilities?.tools?.some(d=>d.name===c)))throw Error("\u5DF2\u9009\u8FDE\u63A5\u5668\u6216\u6750\u6599\u4E0D\u518D\u53EF\u7528\uFF0C\u8BF7\u5237\u65B0\u5E76\u91CD\u65B0\u9009\u62E9")}for(let o of t){if(!o.enabled||o.state!=="connected")continue;let a=e.get(o.id);if(!a)continue;let l=(o.capabilities?.resources||[]).map(d=>d.uri).filter(d=>a.resources.has(d)),c=(o.capabilities?.tools||[]).map(d=>d.name).filter(d=>a.tools.has(d));(l.length||c.length)&&s.push({connector_id:o.id,resources:l,tools:c})}if(!s.length)return null;if(!Number.isInteger(n)||n<1||n>1e3)throw Error("\u8FDE\u63A5\u5668\u8C03\u7528\u6B21\u6570\u987B\u4E3A 1\u20131000 \u7684\u6574\u6570");if(!Number.isInteger(r)||r<1||r>1073741824)throw Error("\u8FDE\u63A5\u5668\u6750\u6599\u9884\u7B97\u987B\u4E3A 1\u20131024 MiB");let i=Math.max(...t.filter(o=>s.some(a=>a.connector_id===o.id)).map(o=>o.max_response_bytes||0));if(r<i)throw Error("\u6750\u6599\u9884\u7B97\u4E0D\u80FD\u5C0F\u4E8E\u6240\u9009\u8FDE\u63A5\u5668\u7684\u5355\u6B21\u54CD\u5E94\u4E0A\u9650");return{selections:s,max_calls:n,max_total_bytes:r}}function sv(t,e){let n=new Map,r=[],s=!1,i=!1;t.innerHTML='<details><summary>\u672C\u8F6E\u8FDE\u63A5\u5668\u6750\u6599\uFF08\u53EF\u9009\uFF09</summary><p class="help">\u9009\u62E9\u5141\u8BB8 BriefLoop \u8BFB\u53D6\u7684\u6750\u6599\u548C\u8C03\u7528\u7684\u5DE5\u5177\u3002\u8054\u7F51\u5F00\u5173\u5355\u72EC\u63A7\u5236\u516C\u5F00\u641C\u7D22\u3002</p><button type="button" class="outline" data-refresh>\u5237\u65B0\u8FDE\u63A5\u5668</button><p data-status role="status"></p><div data-catalog></div><div class="row"><label>\u8C03\u7528\u6B21\u6570\u4E0A\u9650<input type="number" data-calls min="1" max="1000" step="1" value="20"></label><label>\u6750\u6599\u603B\u91CF\u4E0A\u9650\uFF08MiB\uFF09<input type="number" data-bytes min="1" max="1024" step="1" value="20"></label></div><p class="help">\u4EC5\u52FE\u9009\u9879\u6388\u4E88\u672C\u8F6E\u4EFB\u52A1\uFF1B\u672A\u52FE\u9009\u65F6\u4E0D\u4F7F\u7528\u8FDE\u63A5\u5668\u3002\u8BFB\u53D6\u6210\u529F\u7684\u6750\u6599\u4F1A\u51FA\u73B0\u5728\u62A5\u544A\u6765\u6E90\u4E2D\u3002</p></details>';let o=c=>t.querySelector(c);function a(){let c=r.filter(d=>d.enabled);o("[data-catalog]").innerHTML=c.map(d=>{let p=n.get(d.id),f=d.capabilities||{},h=d.state==="connected";return`<fieldset><legend>${v(d.name||d.id)} \xB7 ${h?"\u5DF2\u8FDE\u63A5":"\u5C1A\u672A\u8FDE\u63A5"}</legend>${h?"":'<p class="help">\u8BF7\u5148\u5728\u8BBE\u7F6E\u4E2D\u542F\u7528\u5E76\u8FDE\u63A5\uFF0C\u518D\u5237\u65B0\u3002</p>'}${(f.resources||[]).map(m=>`<label class="check"><input type="checkbox" data-connector="${v(d.id)}" data-kind="resources" data-item="${v(m.uri)}" ${p?.resources.has(m.uri)?"checked":""}>${v(m.name||m.uri)}</label>`).join("")}${(f.tools||[]).map(m=>`<label class="check"><input type="checkbox" data-connector="${v(d.id)}" data-kind="tools" data-item="${v(m.name)}" ${p?.tools.has(m.name)?"checked":""}>${v(m.title||m.name)}${m.annotations?.readOnlyHint===!0?"\uFF08\u58F0\u660E\u53EA\u8BFB\uFF09":"\uFF08\u53EF\u80FD\u4FEE\u6539\u5916\u90E8\u6570\u636E\uFF0C\u8BF7\u786E\u8BA4\u7528\u9014\uFF09"}</label>`).join("")}${h&&!f.resources?.length&&!f.tools?.length?'<p class="help">\u672A\u63D0\u4F9B\u53EF\u9009\u6750\u6599\u6216\u5DE5\u5177\u3002</p>':""}</fieldset>`}).join("")||'<p class="help">\u6CA1\u6709\u5DF2\u542F\u7528\u7684\u8FDE\u63A5\u5668\u3002\u53EF\u5728\u8BBE\u7F6E \u2192 \u6570\u636E\u8FDE\u63A5\u5668\u4E2D\u6DFB\u52A0\u3002</p>',t.querySelectorAll("[data-item]").forEach(d=>d.onchange=()=>{let{connector:p,kind:f,item:h}=d.dataset;n.has(p)||n.set(p,{resources:new Set,tools:new Set});let m=n.get(p)[f];d.checked?m.add(h):m.delete(h)})}async function l(){if(!s){s=!0,o("[data-refresh]").disabled=!0,o("[data-status]").textContent="\u6B63\u5728\u8BFB\u53D6\u8FDE\u63A5\u5668\u2026";try{r=(await e("connectors")).connectors||[],i=!1,a(),o("[data-status]").textContent=""}catch(c){i=!0,o("[data-status]").textContent="\u65E0\u6CD5\u8BFB\u53D6\u8FDE\u63A5\u5668\uFF1A"+c.message}finally{s=!1,o("[data-refresh]").disabled=!1}}}return o("[data-refresh]").onclick=l,{refresh:l,selection(){if(s)throw Error("\u8FDE\u63A5\u5668\u76EE\u5F55\u6B63\u5728\u5237\u65B0\uFF0C\u8BF7\u7A0D\u540E\u63D0\u4EA4");if(i&&[...n.values()].some(c=>c.resources.size||c.tools.size))throw Error("\u8FDE\u63A5\u5668\u76EE\u5F55\u8BFB\u53D6\u5931\u8D25\uFF0C\u8BF7\u5237\u65B0\u540E\u63D0\u4EA4");return HA(r,n,Number(o("[data-calls]").value),Number(o("[data-bytes]").value)*1048576)}}}function iv({api:t,notice:e}){let n=null,r=null,s=!1,i="check";function o(d=n){if(!u("settings-view-updates"))return;let f=typeof window.briefloopDesktop?.updateStatus=="function";u("app-update-controls").hidden=!1,u("app-update-version").textContent=r?`BriefLoop v${r.version}${r.build?` \xB7 \u6784\u5EFA ${r.build}`:""}${f?` \xB7 \u684C\u9762 App v${d?.currentAppVersion||"\u8BFB\u53D6\u4E2D"}`:""}`:"\u6B63\u5728\u8BFB\u53D6\u5B9E\u9645\u8FD0\u884C\u7248\u672C\u2026";let h={desktop:"\u684C\u9762\u7BA1\u7406\u7684\u540E\u7AEF \xB7 App \u4E0E CLI \u5171\u7528",source:"\u5F00\u53D1\u6E90\u7801",pip:"Python \u5305\u5B89\u88C5",pipx:"pipx \u5B89\u88C5",uv:"uv \u5DE5\u5177\u5B89\u88C5"};u("app-update-installation").textContent=r?h[r.installation]||"\u72EC\u7ACB\u5B89\u88C5":"",u("app-update-command").hidden=!r?.update_command,u("app-update-command").textContent=r?.update_command||"",u("app-update-source").textContent=d?.source==="local-test"?"\u672C\u5730\u6D4B\u8BD5\u66F4\u65B0\u6E90 \xB7 \u4EC5\u9A8C\u8BC1\u6D41\u7A0B\uFF0C\u4E0D\u4EE3\u8868\u5B98\u65B9\u53D1\u5E03":f?"\u5B98\u65B9\u7A33\u5B9A\u6765\u6E90\uFF1AStahl-G/briefloop \xB7 GitHub Releases":"Python \u5305\u7A33\u5B9A\u6765\u6E90\uFF1APyPI \xB7 briefloop";let m=d?.source==="local-test"&&d?.reinstall===!0;u("app-update-guidance").textContent=f?d?.installMode==="zip"?"\u4E0B\u8F7D\u5B8C\u6210\u540E\uFF0C\u70B9\u51FB\u4E0B\u65B9\u6309\u94AE\u4FDD\u5B58\u5E76\u9000\u51FA\u3002Finder \u4F1A\u6253\u5F00\u65B0\u7248 App \u548C\u201C\u5B89\u88C5\u4F4D\u7F6E\u201D\uFF1A\u5C06 App \u62D6\u5165\u5E76\u66FF\u6362\uFF0C\u518D\u6253\u5F00 BriefLoop\u3002\u62A5\u544A\u4E0E\u5DE5\u4F5C\u533A\u4F1A\u4FDD\u7559\u3002":d?.installMode==="dmg"?`\u4E0B\u8F7D\u540E\u4F1A\u5148\u4FDD\u5B58\u7F16\u8F91\u5E76\u5904\u7406\u5FD9\u4EFB\u52A1\uFF0C\u518D\u9000\u51FA App\u3001\u6253\u5F00 DMG\uFF1B\u8BF7\u5728 Finder \u4E2D${m?"\u91CD\u65B0\u5B89\u88C5\u5F53\u524D\u7248\u672C":"\u624B\u52A8\u5B89\u88C5\u65B0\u7248\u672C"}\u3002`:"\u4E0B\u8F7D\u540E\u4F1A\u5148\u4FDD\u5B58\u7F16\u8F91\u5E76\u5904\u7406\u5FD9\u4EFB\u52A1\uFF0C\u518D\u9000\u51FA App \u5E76\u4EA4\u7ED9\u539F\u751F\u5B89\u88C5\u5668\u66F4\u65B0\u3002":r?.guidance||"\u6B63\u5728\u8BFB\u53D6\u5B89\u88C5\u6765\u6E90\u2026";let g=d?.error?.operation||(d?.error?.code==="open_failed"?"install":i),b={idle:"\u5C1A\u672A\u68C0\u67E5\u66F4\u65B0",checking:"\u6B63\u5728\u68C0\u67E5\u66F4\u65B0\u2026",available:"\u53D1\u73B0\u53EF\u7528\u66F4\u65B0",current:"\u5F53\u524D App \u65E0\u9700\u66F4\u65B0",downloading:"\u6B63\u5728\u4E0B\u8F7D\u66F4\u65B0\u2026",downloaded:"\u4E0B\u8F7D\u5B8C\u6210\uFF0C\u7B49\u5F85\u5B89\u88C5",error:{check:"\u66F4\u65B0\u68C0\u67E5\u5931\u8D25\uFF08\u5F53\u524D\u5B89\u88C5\u4E0D\u53D7\u5F71\u54CD\uFF09",download:"\u66F4\u65B0\u5305\u4E0B\u8F7D\u672A\u5B8C\u6210",install:"\u66F4\u65B0\u5B89\u88C5\u672A\u5B8C\u6210"}[g]||"\u66F4\u65B0\u68C0\u67E5\u5931\u8D25\uFF08\u5F53\u524D\u5B89\u88C5\u4E0D\u53D7\u5F71\u54CD\uFF09"},k=`\u91CD\u65B0\u5B89\u88C5\u5F53\u524D App v${d?.currentAppVersion||""}`;u("app-update-status").textContent=f?m&&d?.state==="available"?k:(b[d?.state]||"\u6B63\u5728\u8BFB\u53D6 App \u7248\u672C\u2026")+(d?.state==="error"&&g==="check"?"":m?` \xB7 ${k}`:d?.releaseVersion?` \xB7 v${d.releaseVersion}`:""):{idle:"\u5C1A\u672A\u68C0\u67E5\u66F4\u65B0",checking:"\u6B63\u5728\u68C0\u67E5\u66F4\u65B0\u2026",available:`\u53D1\u73B0\u53EF\u7528\u540E\u7AEF\u7248\u672C v${d?.releaseVersion||""}`,current:"\u5F53\u524D\u540E\u7AEF\u5DF2\u662F PyPI \u6700\u65B0\u7A33\u5B9A\u7248",ahead:`\u5F53\u524D\u540E\u7AEF\u9AD8\u4E8E PyPI \u5DF2\u53D1\u5E03\u7248\u672C v${d?.releaseVersion||""}`,error:"\u7248\u672C\u68C0\u67E5\u672A\u5B8C\u6210"}[d?.state||"idle"]||"\u5C1A\u672A\u68C0\u67E5\u66F4\u65B0",u("app-update-download").textContent=m?"\u4E0B\u8F7D\u5F53\u524D\u7248\u672C\u5B89\u88C5\u5305":"\u4E0B\u8F7D\u66F4\u65B0";let x=s||["checking","downloading"].includes(d?.state);u("app-update-check").disabled=x,u("app-update-download").hidden=!f||d?.state!=="available",u("app-update-download").disabled=x,u("app-update-install").hidden=!f||d?.state!=="downloaded",u("app-update-install").disabled=x,u("app-update-install").textContent=d?.installMode==="zip"?"\u4FDD\u5B58\u5E76\u9000\u51FA\uFF0C\u6253\u5F00\u5B89\u88C5\u6587\u4EF6\u5939":d?.installMode==="dmg"?"\u4FDD\u5B58\u5E76\u6253\u5F00 DMG":"\u4FDD\u5B58\u5E76\u5B89\u88C5\u66F4\u65B0",u("app-update-retry").hidden=d?.state!=="error"||!d?.retryable,u("app-update-retry").disabled=x,u("app-update-error").hidden=!d?.error,u("app-update-error").textContent=d?.error?.message||"";let C=d?.progress;u("app-update-progress-box").hidden=!C,u("app-update-progress").value=C?.percent||0,u("app-update-progress-text").textContent=C?`${Math.round(C.percent||0)}% \xB7 ${(Math.max(0,C.transferred||0)/1048576).toFixed(1)} / ${(Math.max(0,C.total||0)/1048576).toFixed(1)} MiB`:"",C?.mode==="differential"?u("app-update-progress-text").textContent+=` \xB7 \u589E\u91CF\u4E0B\u8F7D\uFF0C\u590D\u7528 ${(Math.max(0,C.reused||0)/1048576).toFixed(1)} MiB`:C?.mode==="full"&&(u("app-update-progress-text").textContent+=" \xB7 "+({no_baseline:"\u65E0\u6709\u6548\u57FA\u51C6\u7F13\u5B58\uFF0C\u5B8C\u6574\u4E0B\u8F7D\u5E76\u5EFA\u7ACB\u7F13\u5B58",little_reuse:"\u672C\u6B21\u53EF\u590D\u7528\u5185\u5BB9\u8F83\u5C11\uFF0C\u5B8C\u6574\u4E0B\u8F7D",range_unavailable:"\u4E0B\u8F7D\u670D\u52A1\u4E0D\u652F\u6301\u5206\u6BB5\u4F20\u8F93\uFF0C\u5B8C\u6574\u4E0B\u8F7D",range_size:"\u5206\u6BB5\u54CD\u5E94\u4E0D\u5B8C\u6574\uFF0C\u91CD\u65B0\u5B8C\u6574\u4E0B\u8F7D",delta_hash:"\u589E\u91CF\u91CD\u5EFA\u6821\u9A8C\u5931\u8D25\uFF0C\u91CD\u65B0\u5B8C\u6574\u4E0B\u8F7D",differential_unavailable:"\u589E\u91CF\u4E0D\u53EF\u7528\uFF0C\u5DF2\u56DE\u9000\u5B8C\u6574\u4E0B\u8F7D",blockmap_unavailable:"\u6B64\u7248\u672C\u65E0\u53EF\u7528\u589E\u91CF\u4FE1\u606F\uFF0C\u5B8C\u6574\u4E0B\u8F7D"}[C.fallback]||"\u5B8C\u6574\u4E0B\u8F7D")),u("app-update-notes-box").hidden=!d?.notes,u("app-update-notes").textContent=d?.notes||""}async function a(){o();try{r=await t("software-version"),typeof window.briefloopDesktop?.updateStatus=="function"&&(n=await window.briefloopDesktop.updateStatus()),o()}catch{e("\u65E0\u6CD5\u8BFB\u53D6 App \u66F4\u65B0\u72B6\u6001\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u8BBE\u7F6E\u3002",!0)}}async function l(d){if(s)return;let p=window.briefloopDesktop;if(typeof p?.updateStatus!="function"){if(d!=="check")return;s=!0,n={state:"checking"},o();try{n=await t("software-update-check",{}),r=n}catch(f){n={state:"error",retryable:!0,error:{message:f.message||"\u7248\u672C\u68C0\u67E5\u672A\u5B8C\u6210"}}}finally{s=!1,o()}return}s=!0,i=d,o();try{if(d==="install"){let f=await p.installUpdate();f?.cancelled&&e("\u5DF2\u4FDD\u7559\u5F53\u524D\u5DE5\u4F5C\u533A\uFF0C\u66F4\u65B0\u5305\u4ECD\u53EF\u7A0D\u540E\u5B89\u88C5\u3002"),f?.cancelled&&(n=await p.updateStatus())}else n=await(d==="download"?p.downloadUpdate():p.checkForUpdates())}catch(f){e(f.message||"\u66F4\u65B0\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5\u3002",!0);try{n=await p.updateStatus()}catch{}}finally{s=!1,o()}}function c(){u("settings-view-updates")&&(u("app-update-check").onclick=()=>l("check"),u("app-update-download").onclick=()=>l("download"),u("app-update-install").onclick=()=>l("install"),u("app-update-retry").onclick=()=>l(n?.error?.code==="open_failed"?"install":(n?.error?.operation||i)==="install"?"download":n?.error?.operation||i),window.briefloopDesktop?.onUpdateStatus?.(d=>{n=d,o()}),o())}return{init:c,renderAppUpdates:o,refreshAppUpdates:a,runAppUpdate:l}}var jA=[["taste","\u5199\u6CD5\u504F\u597D","\u539F\u7A3F\u6CA1\u9519\uFF0C\u53EA\u662F\u6211\u60F3\u8FD9\u6837\u5199"],["fact_correction","\u4E8B\u5B9E\u7EA0\u9519","\u539F\u7A3F\u7684\u6570\u5B57\u3001\u4E8B\u5B9E\u6216\u53E3\u5F84\u4E0D\u5BF9"],["reader_specific","\u53EA\u9488\u5BF9\u8FD9\u4F4D\u8BFB\u8005","\u6362\u4E00\u4F4D\u8BFB\u8005\u672A\u5FC5\u8981\u8FD9\u6837\u6539"]];function Ss(t,e=160){let n=String(t||"").replace(/\s+/g," ").trim();return n.length>e?n.slice(0,e)+"\u2026":n}function ov(t){let e=t.op==="delete"?`\u5220\u6389\u4E86\uFF1A<q>${v(Ss(t.before))}</q>`:t.op==="insert"?`\u52A0\u5165\u4E86\uFF1A<q>${v(Ss(t.after))}</q>`:`\u628A <q>${v(Ss(t.before))}</q> \u6539\u6210 <q>${v(Ss(t.after))}</q>`;return`<div class="revision-question" data-edit="${v(t.id)}"><p class="revision-question-where">${v(t.heading||"\u6B63\u6587")}</p><p>${e}</p><p class="help">\u4E3A\u4EC0\u4E48\u8FD9\u6837\u6539\uFF1F</p><div class="revision-question-choices">${jA.map(([n,r,s])=>`<button type="button" class="outline" data-answer="${n}" title="${v(s)}">${v(r)}</button>`).join("")}<button type="button" class="ghost" data-answer="skip" title="\u8FD9\u5904\u6539\u52A8\u4E0D\u8FDB\u5165\u5B66\u4E60">\u8DF3\u8FC7</button></div></div>`}function av({api:t,action:e,$:n=u}){function r(i){i.querySelectorAll("[data-answer]").forEach(o=>o.onclick=()=>{let a=o.closest("[data-edit]").dataset.edit,l=o.dataset.answer;e(()=>t("revision-answer",{edit_id:a,category:l}),l==="skip"?"\u5DF2\u8DF3\u8FC7\uFF0C\u8FD9\u5904\u6539\u52A8\u4E0D\u8FDB\u5165\u5B66\u4E60":l==="fact_correction"?"\u5DF2\u8BB0\u4E3A\u4E8B\u5B9E\u7EA0\u9519\uFF0C\u4E0D\u4F5C\u4E3A\u5199\u4F5C\u7ECF\u9A8C":l==="reader_specific"?"\u8BFB\u8005\u7279\u5B9A\u6539\u52A8\u5DF2\u4FDD\u7559\uFF1B\u672A\u7ED1\u5B9A\u8BFB\u8005\u65F6\u4FDD\u6301\u672A\u786E\u8BA4\uFF0C\u4E0D\u8FDB\u5165\u5168\u5C40\u5B66\u4E60":"\u5DF2\u8BB0\u4E0B\uFF0C\u4F1A\u8FDB\u5165\u4E0B\u4E00\u6B21\u5B66\u4E60")})}function s(i){let o=i?.questions||[],a=i?.unconfirmed||[],l=i?.fact_corrections||[],c=n("revision-questions");c&&(c.hidden=!o.length&&!a.length,c.innerHTML=o.length?`<h3>${o.length} \u5904\u6539\u52A8\u9700\u8981\u4F60\u786E\u8BA4\u539F\u56E0</h3><p class="help">\u53EA\u95EE\u62FF\u4E0D\u51C6\u3001\u6539\u52A8\u8F83\u5927\u7684\u5730\u65B9\u3002\u4E8B\u5B9E\u7EA0\u9519\u4E0D\u4F1A\u5199\u8FDB\u5199\u4F5C\u6280\u5DE7\uFF1B\u8DF3\u8FC7\u7684\u6539\u52A8\u4E0D\u8FDB\u5165\u5B66\u4E60\u3002</p>${o.map(ov).join("")}`:"",a.length&&(c.innerHTML+=`<details><summary>${a.length} \u5904\u672A\u786E\u8BA4\u6539\u52A8 \xB7 \u4E0D\u8FDB\u5165\u5B66\u4E60</summary><p class="help">\u65E0\u9700\u9010\u6761\u5904\u7406\u3002\u4F60\u4E5F\u53EF\u4EE5\u5C55\u5F00\u540E\u786E\u8BA4\u6539\u52A8\u539F\u56E0\u3002</p>${a.map(ov).join("")}</details>`),r(c));let d=n("fact-corrections");d&&(d.innerHTML=l.length?l.map(f=>`<div class="fact-correction"><small>${v(f.heading||"\u6B63\u6587")} \xB7 ${f.decided_by==="user"?"\u4F60\u786E\u8BA4":"Evaluator \u5224\u65AD"}</small><p><del>${v(Ss(f.before,120))}</del> \u2192 ${v(Ss(f.after,120))}</p></div>`).join(""):'<p class="help">\u8FD8\u6CA1\u6709\u4E8B\u5B9E\u7EA0\u9519\u8BB0\u5F55\u3002</p>');let p=n("revision-questions-hint");p&&(p.hidden=!o.length,p.textContent=o.length?`\u6709 ${o.length} \u5904\u6539\u52A8\u7B49\u4F60\u786E\u8BA4\u539F\u56E0\uFF0C\u5728\u201C\u7ECF\u9A8C\u201D\u9875\u5904\u7406\u3002`:"")}return{render:s}}function lv({$:t,esc:e,getState:n,openLearning:r}){let s=l=>{try{return typeof l=="string"?JSON.parse(l):l||{}}catch{return{}}},i={queued:"\u6392\u961F\u6574\u7406",running:"\u6B63\u5728\u6574\u7406",complete:"\u5DF2\u6574\u7406",failed:"\u6574\u7406\u5931\u8D25",interrupted:"\u6574\u7406\u4E2D\u65AD",cancelled:"\u6574\u7406\u5DF2\u505C\u6B62"};function o(){let l=n()||{},c=new Map((l.jobs||[]).filter(d=>d.kind==="learn").map(d=>[d.id,d]));return(l.feedback||[]).map(d=>{let p=s(d.data),f=c.get(d.batch_id),h="learning_status"in d?d.learning_status:f?.status,m=d.batch_id?i[h]||"\u6574\u7406\u72B6\u6001\u672A\u77E5":"\u5F85\u6574\u7406",g=d.kind==="revision"||d.kind==="revision_edit",y=p.summary||p.text||p.verified_reason||(g?"\u6539\u7A3F\u8BB0\u5F55":"\u53CD\u9988\u8BB0\u5F55"),b=g?"\u6539\u7A3F":d.kind==="review_correction"?"\u6838\u67E5\u4FEE\u8BA2":p.learning_intent==="explicit_requirement"?"\u5FC5\u987B\u4FDD\u7559\u7684\u8981\u6C42":"\u53CD\u9988";return{id:d.id,text:y,kind:b,status:m,pending:!d.batch_id,created:d.created}})}function a(){let l=o(),c=n()?.feedback_summary,d=c?.total??l.length,p=c?.pending??l.filter(y=>y.pending).length,f=d>l.length,h=c?`\u5171 ${d} \u6761\uFF0C\u5176\u4E2D ${p} \u6761\u5F85\u6574\u7406\u3002`:`\u6700\u8FD1 ${d} \u6761\uFF0C\u5176\u4E2D ${p} \u6761\u5F85\u6574\u7406\u3002`,m=t("feedback-list");m&&(m.innerHTML=`<h2>\u5DF2\u4FDD\u5B58\u7684\u53CD\u9988</h2><p class="help">${d?h:"\u8FD8\u6CA1\u6709\u4FDD\u5B58\u7684\u53CD\u9988\u3002"}${f?`\u4EC5\u663E\u793A\u6700\u8FD1 ${l.length} \u6761\u3002`:""}\u5F85\u6574\u7406\u7684\u53CD\u9988\u5728\u4F60\u70B9\u201C\u73B0\u5728\u6574\u7406\u6210\u7ECF\u9A8C\u201D\u6216\u5F00\u542F\u81EA\u52A8\u5B66\u4E60\u540E\uFF0C\u7531 Wiki \u7EF4\u62A4\u8005\u6574\u7406\uFF1B\u4E8B\u5B9E\u7EA0\u9519\u53EA\u8BB0\u5F55\uFF0C\u4E0D\u5199\u8FDB\u5199\u4F5C\u6280\u5DE7\u3002</p>`+(l.length?`<ul class="feedback-items">${l.map(y=>`<li><span class="chip">${e(y.status)}</span> <span class="help">${e(y.kind)} \xB7 ${e((y.created||"").slice(0,16).replace("T"," "))}</span><p>${e(y.text)}</p></li>`).join("")}</ul>`:""));let g=t("feedback-saved-hint");g&&(g.hidden=!d,g.innerHTML=d?`${c?"\u5DF2\u4FDD\u5B58":"\u6700\u8FD1\u5DF2\u4FDD\u5B58"} ${d} \u6761\u53CD\u9988${p?`\uFF0C${p} \u6761\u5F85\u6574\u7406`:""} \xB7 <button type="button" class="outline" data-feedback-open>\u67E5\u770B\u53CD\u9988</button>`:"",g.querySelector("[data-feedback-open]")?.addEventListener("click",r))}return{render:a,rows:o}}function cv({api:t,action:e,$:n=u}){let r=null,s=[],i=!1;function o(h,m){let g=n("reader-select");if(!g)return;let y=i?g.value:m??g.value;g.innerHTML='<option value="">\u4E0D\u6307\u5B9A\u8BFB\u8005\u6863\u6848</option>'+h.map(b=>`<option value="${v(b.id)}">${v(b.name)}</option>`).join(""),g.value=h.some(b=>b.id===y)?y:"",i=!0}function a(){let h=n("reader-select"),m=h?.form?.elements?.audience;if(!h||!m)return;let g=s.find(y=>y.id===h.value);g&&(!m.value.trim()||m.value==="\u81EA\u5DF1"||s.some(y=>y.name===m.value))&&(m.value=g.name)}function l(h){return`<div class="reader-profile" data-reader="${v(h.id)}"><div class="reader-profile-head"><strong>${v(h.name)}</strong><span>${h.skill_id?"\u5386\u53F2\u4E13\u5C5E\u6280\u80FD "+v(h.skill_id)+"\uFF08\u6682\u4E0D\u542F\u7528\uFF09":"\u4F7F\u7528\u5DE5\u4F5C\u533A\u6280\u80FD"}</span></div>${h.decisions?`<p><small>\u7528\u62A5\u544A\u505A\u4EC0\u4E48\u51B3\u5B9A</small>${v(h.decisions)}</p>`:""}${h.preferences?`<p><small>\u504F\u597D</small>${v(h.preferences)}</p>`:""}<div class="reader-profile-actions"><button type="button" class="outline" data-reader-edit>\u7F16\u8F91</button>${h.skill_id?'<button type="button" class="outline" data-reader-unbind>\u6E05\u9664\u5386\u53F2\u7ED1\u5B9A</button>':""}<button type="button" class="ghost" data-reader-archive>\u5F52\u6863</button></div>${h.wiki?`<details><summary>\u5386\u53F2\u8BFB\u8005\u7ECF\u9A8C\uFF08\u6682\u4E0D\u542F\u7528\uFF09</summary><pre class="reader-wiki">${v(h.wiki)}</pre></details>`:""}</div>`}function c(h){let m=n("reader-profiles");m&&(m.innerHTML=h.length?h.map(l).join(""):'<p class="help">\u8FD8\u6CA1\u6709\u8BFB\u8005\u6863\u6848\u3002\u5199\u7ED9\u56FA\u5B9A\u8BFB\u8005\u7684\u62A5\u544A\uFF0C\u5EFA\u4E00\u4E2A\u6863\u6848\u540E\uFF0C\u62A5\u544A\u4F1A\u8BB0\u5F55\u7528\u9014\u4E0E\u504F\u597D\u3002\u8BFB\u8005\u7279\u5B9A\u6539\u52A8\u5148\u4FDD\u7559\uFF0C\u7B49\u5F85\u9002\u7528\u6761\u4EF6\u4E0E\u8DE8\u8BFB\u8005\u9A8C\u8BC1\u3002</p>',m.querySelectorAll("[data-reader]").forEach(g=>{let y=h.find(k=>k.id===g.dataset.reader);g.querySelector("[data-reader-edit]").onclick=()=>d(y),g.querySelector("[data-reader-archive]").onclick=()=>e(()=>t("reader-archive",{id:y.id}),"\u8BFB\u8005\u6863\u6848\u5DF2\u5F52\u6863\uFF0C\u65E7\u62A5\u544A\u4FDD\u7559\u539F\u6837");let b=g.querySelector("[data-reader-unbind]");b&&(b.onclick=()=>e(()=>t("reader-skill",{reader_id:y.id,skill_id:null}),"\u5DF2\u6E05\u9664\u5386\u53F2\u4E13\u5C5E\u6280\u80FD\u7ED1\u5B9A"))}))}function d(h=null){let m=n("reader-form");m&&(r=h?.id||null,m.hidden=!1,m.elements.name.value=h?.name||"",m.elements.decisions.value=h?.decisions||"",m.elements.preferences.value=h?.preferences||"",m.querySelector("[data-reader-form-title]").textContent=h?"\u7F16\u8F91\u8BFB\u8005\u6863\u6848":"\u65B0\u5EFA\u8BFB\u8005\u6863\u6848",m.elements.name.focus?.())}function p(){let h=n("reader-add");h&&(h.onclick=()=>d());let m=n("reader-form");if(m){m.onsubmit=b=>{b.preventDefault();let k={name:m.elements.name.value,decisions:m.elements.decisions.value,preferences:m.elements.preferences.value,...r?{id:r}:{}};e(async()=>{await t("reader-save",k),m.hidden=!0,r=null},"\u8BFB\u8005\u6863\u6848\u5DF2\u4FDD\u5B58")};let y=m.querySelector("[data-reader-cancel]");y&&(y.onclick=()=>{m.hidden=!0,r=null})}let g=n("reader-select");g&&g.addEventListener("change",a)}function f(h=[],{readerId:m}={}){s=h,o(h,m),c(h)}return{render:f,bind:p,openForm:d}}function dv(t){if(!t)return"";let e=t.status==="untracked"&&!t.registration_conflict,n=e?"untracked":"pending",r=e?"\u65E0\u53EF\u8FFD\u8E2A\u6539\u52A8":"\u5F85\u9A8C\u6536",s=e?["\u6CA1\u6709\u53EF\u8FFD\u8E2A\u7684\u6539\u52A8"]:["\u521D\u6B65\u89C2\u5BDF\uFF0C\u672A\u9A8C\u6536",`\u5B8C\u6574\u6838\u9A8C ${t.observed||0} \u4EFD \xB7 \u672A\u77E5 ${t.unknown??t.reports??0} \u4EFD`];return t.flagged_reports&&s.push(`\u660E\u786E\u6807\u51FA\u590D\u53D1 ${t.repeats||0} \u6B21\uFF08${t.flagged_reports} \u4EFD\u62A5\u544A\uFF09`),t.excluded&&s.push(`\u8303\u56F4\u4E0D\u4E00\u81F4\uFF0C\u6392\u9664 ${t.excluded} \u4EFD`),t.registration_conflict&&s.push("\u540C\u4E00\u6280\u80FD\u5BF9\u5E94\u4E0D\u540C\u8BFB\u8005\u6216\u6279\u6B21\uFF0C\u7ED1\u5B9A\u5F85\u6F84\u6E05"),e||s.push(t.note||"\u5C1A\u672A\u5B8C\u6210\u5B8C\u6574\u590D\u53D1\u6838\u9A8C\u3001\u53CC\u6A21\u578B family \u6821\u51C6\u3001\u4EBA\u5DE5\u5206\u6B67\u5904\u7406\u4E0E\u7559\u51FA\u9A8C\u6536"),(t.legacy_status_corrected||["adopted","not_improving"].includes(t.status))&&s.push(t.legacy_note||"\u65E7\u81EA\u52A8\u72B6\u6001\u4E0D\u8BC1\u660E\u9A8C\u6536\uFF0C\u539F\u8BB0\u5F55\u4E0E\u6280\u80FD\u4FDD\u7559"),`<span class="skill-verification skill-verification-${v(n)}"><span class="tag">${v(r)}</span><small>${v(s.join(" \xB7 "))}</small></span>`}function FA(t){return`/discuss \u8FD9\u662F\u6211\u4EEC\u5DF2\u7ECF\u4EA4\u4ED8\u8FC7\u7684\u4E00\u671F\u62A5\u544A\u300A${t}\u300B\uFF08\u89C1\u9644\u4EF6\uFF09\u3002\u8BF7\u9605\u8BFB\u5B83\uFF0C\u53CD\u63A8\u8FD9\u4EFD\u5468\u671F\u62A5\u544A\u7684\u7B80\u62A5\u7EA6\u5B9A\uFF1A\u8BFB\u8005\u662F\u8C01\u3001\u8BFB\u5B8C\u8981\u505A\u4EC0\u4E48\u51B3\u5B9A\uFF1B\u6CBF\u7528\u7684\u7AE0\u8282\u7ED3\u6784\uFF1B\u6570\u5B57\u5355\u4F4D\u3001\u65F6\u95F4\u8303\u56F4\u4E0E\u6765\u6E90\u7B49\u53E3\u5F84\uFF1B\u6709\u660E\u786E\u4F9D\u636E\u7684\u7981\u533A\uFF08\u6CA1\u6709\u5199\u4E0D\u7B49\u4E8E\u7981\u6B62\uFF09\u3002\u5F80\u671F\u6570\u5B57\u4E0D\u662F\u672C\u671F\u4E8B\u5B9E\uFF1B\u5168\u90E8\u7EA6\u5B9A\u5148\u4F5C\u4E3A\u5F85\u786E\u8BA4\u5EFA\u8BAE\uFF0C\u770B\u4E0D\u51FA\u6765\u7684\u5217\u4E3A\u672A\u51B3\u9879\uFF0C\u4E0D\u8981\u731C\u3002\u6574\u7406\u597D\u540E\u7ED9\u51FA briefloop-requirements\uFF0C\u8BFB\u8005\u6E05\u695A\u65F6\u518D\u7ED9\u4E00\u4E2A briefloop-reader\u3002`}function WA(t){let e=/```briefloop-reader\s*([\s\S]*?)```/.exec(t||"");if(!e)return null;try{let n=JSON.parse(e[1].trim());return!n||typeof n.name!="string"||!n.name.trim()?null:{name:n.name.trim(),decisions:typeof n.decisions=="string"?n.decisions:"",preferences:typeof n.preferences=="string"?n.preferences:""}}catch{return null}}function uv({api:t,uploadPayload:e,getUploadLimits:n,openChat:r,notice:s,saveReader:i,$:o=u}){async function a(d){let p=await t("import-previous",await e(d,n(),{}));return await r({text:FA(p.title),source_id:p.source_id}),s(p.tracked_changes?"\u5DF2\u5BFC\u5165\u5F80\u671F\u62A5\u544A\uFF1B\u5176\u4E2D\u7684 Word \u4FEE\u8BA2\u5DF2\u8BB0\u4E3A\u6539\u7A3F\uFF0C\u4E0B\u6B21\u5B66\u4E60\u65F6\u5206\u7C7B\u3002\u786E\u8BA4\u540E\u628A\u8BF7\u6C42\u53D1\u7ED9 BriefLoop\u3002":"\u5DF2\u5BFC\u5165\u5F80\u671F\u62A5\u544A\u3002\u786E\u8BA4\u540E\u628A\u8BF7\u6C42\u53D1\u7ED9 BriefLoop\uFF0C\u5B83\u4F1A\u53CD\u63A8\u7B80\u62A5\u7EA6\u5B9A\u3002"),p}function l(){let d=o("previous-report-file");d&&(d.onchange=async p=>{let f=p.target.files[0];if(p.target.value="",!!f)try{await a(f)}catch(h){s(h.message,!0)}})}function c(d,p){let f=WA(p);if(!f||!i)return;let h=document.createElement("button");h.type="button",h.className="outline apply-requirements",h.textContent="\u4FDD\u5B58\u4E3A\u8BFB\u8005\u6863\u6848",h.onclick=()=>i(f),d.append(h)}return{bind:l,importFile:a,appendReaderAction:c}}function pv({api:t,getPlan:e,confirm:n,describePlan:r}){return async s=>{let i={job_id:s.id,use_current_model:!0};if(s.kind==="learn"){let o=e();if(!o||!n(`\u6309\u5F53\u524D\u6A21\u578B\u65B0\u5EFA\u5B66\u4E60\u5C1D\u8BD5\uFF0C\u4FDD\u7559\u539F\u4EFB\u52A1\u4E0E\u53CD\u9988\u3002
253
253
 
254
254
  `+r(o)))return;i.confirm_plan=o.fingerprint}return t("resume",i)}}var fv=["\u5546\u4E1A\u62A5\u544A","\u5238\u5546\u7814\u62A5","\u5B66\u672F\u8BBA\u6587","\u4F1A\u8BAE\u7EAA\u8981","\u5408\u540C","\u4E0A\u5E02\u516C\u53F8\u5E74\u62A5","\u653F\u5E9C\u516C\u6587","\u901A\u7528\u62A5\u544A","\u82F1\u6587\u901A\u7528\u62A5\u544A","\u82F1\u6587\u7814\u62A5"],op={\u5546\u4E1A\u62A5\u544A:{desc:"\u9002\u7528\u4E8E\u5546\u4E1A\u5206\u6790\u3001\u5E02\u573A\u7814\u7A76\u7B49\u3002",icon:"briefcase",cat:"cat-business"},\u5238\u5546\u7814\u62A5:{desc:"\u9002\u7528\u4E8E\u8BC1\u5238\u7814\u7A76\u3001\u884C\u4E1A\u5206\u6790\u3002",icon:"chart",cat:"cat-markets"},\u5B66\u672F\u8BBA\u6587:{desc:"\u9002\u7528\u4E8E\u5B66\u672F\u7814\u7A76\u3001\u8BBA\u6587\u5199\u4F5C\u3002",icon:"book",cat:"cat-academic"},\u4F1A\u8BAE\u7EAA\u8981:{desc:"\u9002\u7528\u4E8E\u4F1A\u8BAE\u8BB0\u5F55\u3001\u8BA8\u8BBA\u8981\u70B9\u3002",icon:"users",cat:"cat-collab"},\u5408\u540C:{desc:"\u9002\u7528\u4E8E\u5404\u7C7B\u5408\u540C\u3001\u534F\u8BAE\u3002",icon:"file",cat:"cat-business"},\u4E0A\u5E02\u516C\u53F8\u5E74\u62A5:{desc:"\u9002\u7528\u4E8E\u4E0A\u5E02\u516C\u53F8\u5E74\u5EA6\u62A5\u544A\u3002",icon:"bars",cat:"cat-business"},\u653F\u5E9C\u516C\u6587:{desc:"\u9002\u7528\u4E8E\u653F\u5E9C\u673A\u5173\u516C\u6587\u3001\u653F\u7B56\u6587\u4EF6\uFF1B\u7EA2\u5934\u4E0E\u5B57\u4F53\u6309 GB/T 9704 \u56FA\u5B9A\u3002",icon:"landmark",cat:"cat-markets"},\u901A\u7528\u62A5\u544A:{desc:"\u9002\u7528\u4E8E\u5404\u7C7B\u901A\u7528\u578B\u62A5\u544A\u3002",icon:"layers",cat:"cat-neutral"},\u82F1\u6587\u901A\u7528\u62A5\u544A:{desc:"\u82F1\u6587\u6B63\u6587\u4E0E\u7AE0\u8282\u6807\u9898\uFF0C\u9002\u7528\u4E8E\u9762\u5411\u6D77\u5916\u8BFB\u8005\u7684\u62A5\u544A\uFF1B\u9009\u7528\u540E\u62A5\u544A\u8BED\u8A00\u8BBE\u4E3A\u82F1\u6587\u3002",icon:"layers",cat:"cat-neutral"},\u82F1\u6587\u7814\u62A5:{desc:"\u82F1\u6587\u8BC1\u5238\u7814\u7A76\u7248\u5F0F\uFF0C\u9002\u7528\u4E8E\u9762\u5411\u6D77\u5916\u6295\u8D44\u8005\u7684\u516C\u53F8\u4E0E\u884C\u4E1A\u7814\u7A76\uFF1B\u9009\u7528\u540E\u62A5\u544A\u8BED\u8A00\u8BBE\u4E3A\u82F1\u6587\u3002",icon:"chart",cat:"cat-markets"}},kl={briefcase:'<rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/>',chart:'<rect x="4" y="12" width="4" height="8" rx="1.2"/><rect x="10" y="6" width="4" height="14" rx="1.2"/><rect x="16" y="9" width="4" height="11" rx="1.2"/>',book:'<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>',users:'<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',file:'<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/>',bars:'<rect x="4" y="12" width="4" height="8" rx="1.2"/><rect x="10" y="6" width="4" height="14" rx="1.2"/><rect x="16" y="9" width="4" height="11" rx="1.2"/>',compare:'<rect x="3" y="10" width="3.5" height="10" rx="1"/><rect x="7.5" y="6" width="3.5" height="14" rx="1"/><rect x="13" y="13" width="3.5" height="7" rx="1"/><rect x="17.5" y="8" width="3.5" height="12" rx="1"/>',landmark:'<line x1="3" y1="22" x2="21" y2="22"/><line x1="5" y1="22" x2="5" y2="11"/><line x1="9" y1="22" x2="9" y2="11"/><line x1="15" y1="22" x2="15" y2="11"/><line x1="19" y1="22" x2="19" y2="11"/><path d="M2 11L12 3l10 8z"/>',layers:'<polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/>',paperclip:'<path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/>',buildingsSlash:'<path d="M4 21V9.5L9 6v15"/><path d="M4 21h7"/><line x1="6.2" y1="11" x2="7.8" y2="11"/><line x1="6.2" y1="14" x2="7.8" y2="14"/><line x1="6.2" y1="17" x2="7.8" y2="17"/><line x1="13.2" y1="5.5" x2="17.8" y2="18.5"/><path d="M14 21v-9.5L18.5 8.5V21"/><path d="M14 21h7"/><line x1="16" y1="14" x2="17.5" y2="14"/><line x1="16" y1="17" x2="17.5" y2="17"/>'},mv={\u54C1\u724C\u7EFF:"#006838",\u6781\u7B80\u84DD:"#2563EB",\u73CA\u745A\u7EA2:"#C62828",\u77F3\u58A8\u9ED1:"#1E2320",\u5178\u96C5\u7070:"#8A9089"},hv=Object.keys(mv);function bl(t){let e=t.lastIndexOf("\xB7");return e<0?{genre:t,theme:""}:{genre:t.slice(0,e),theme:t.slice(e+1)}}function UA(t){let e=new Map;for(let n of t.filter(r=>r.origin==="builtin"&&r.name.includes("\xB7"))){let{genre:r,theme:s}=bl(n.name),i=r+"\0"+s,o=e.get(i);(!o||((l,c)=>+(l.status==="ready")-+(c.status==="ready")||Number(l.revision||0)-Number(c.revision||0)||String(l.created||"").localeCompare(String(c.created||""))||String(l.id).localeCompare(String(c.id)))(n,o)>0)&&e.set(i,n)}return[...e.values()].map(n=>({...n,...bl(n.name)}))}function gv({notice:t,action:e,page:n,renderWorkflowChoices:r,templateSections:s,getState:i,syncTemplateLanguage:o,openTemplateOutput:a}){let l=null,c=null;function d(){let p=i(),f=u("templates-page-list");if(!f||!p)return;c!==p.workspace_id&&(c=p.workspace_id,l=null,d.sig="");let h=p.templates||[],m=UA(h),g=h.filter($=>$.origin!=="builtin"),y=[...m,...g],b=JSON.stringify([c,p.settings?.default_template_id,l,...h.map($=>[$.id,$.status,$.revision,$.created,$.name,$.origin,$.error])]);if(d.sig===b)return;if(d.sig=b,!y.some($=>$.id===l&&$.status==="ready")){let $=h.find(I=>I.id===p.settings?.default_template_id),H=$&&m.find(I=>I.name===$.name&&I.status==="ready");l=(y.find(I=>I.id===$?.id&&I.status==="ready")||H||m.find(I=>I.genre==="\u5546\u4E1A\u62A5\u544A"&&I.theme==="\u54C1\u724C\u7EFF"&&I.status==="ready")||y.find(I=>I.status==="ready"))?.id||null}let k={};for(let $ of m)(k[$.genre]??=[]).push($);for(let $ of Object.values(k))$.sort((H,I)=>hv.indexOf(H.theme)-hv.indexOf(I.theme));let C=[...fv,...Object.keys(k).filter($=>!fv.includes($))].filter($=>k[$]).map($=>{let H=op[$]||{desc:"",icon:"file",cat:"cat-neutral"},I=k[$],w=I.some(O=>O.id===l),q=I.find(O=>O.id===l)||I.find(O=>O.status==="ready")||I[0],D=I.map(O=>`<button type="button" class="color-dot${q.id===O.id?" selected":""}" style="--swatch-color:${mv[O.theme]||"var(--color-text-muted)"}" data-genre="${v($)}" data-theme="${v(O.theme)}" data-id="${v(O.id)}" data-testid="template-theme" title="${v($+" \xB7 "+O.theme)}" aria-label="${v($+" "+O.theme)}" aria-pressed="${O.id===l}" ${O.status==="ready"?"":"disabled"}></button>`).join("");return`<div class="tpl-card${w?" selected":""}" data-genre="${v($)}"><span class="tpl-check" aria-hidden="true">\u2713</span><span class="tpl-icon ${H.cat}"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${kl[H.icon]||""}</svg></span><button type="button" class="tpl-name tpl-select" data-template-pick="${v(q.id)}" aria-pressed="${w}" ${I.some(O=>O.status==="ready")?"":"disabled"}>${v($)}</button><span class="tpl-desc" title="${v(H.desc)}">${v(H.desc)}</span><span class="tpl-dots"><span class="label">\u914D\u8272</span>${D}</span></div>`}).join(""),M=y.find($=>$.id===l),E=M?`\u5DF2\u9009\uFF1A<strong>${v(M.name.replace("\xB7"," \xB7 "))}</strong>`:"\u5C1A\u65E0\u53EF\u7528\u6A21\u677F",R=g.length?'<div class="tpl-custom"><h2>\u6211\u7684\u7248\u5F0F\u6A21\u677F</h2>'+g.map($=>`<div class="source-row tpl-custom-row${l===$.id?" selected":""}"><span class="name">${v($.name)} \xB7 v${v($.revision)}</span><span class="tag ${$.status!=="ready"?"error":""}">${$.status==="ready"?"\u53EF\u7528":v($.error||"\u51C6\u5907\u4E2D")}</span><button type="button" class="outline" data-template-pick="${v($.id)}" data-testid="custom-template-select" aria-pressed="${l===$.id}" ${$.status==="ready"?"":"disabled"}>${l===$.id?"\u5DF2\u9009\u62E9":"\u9009\u62E9\u6A21\u677F"}</button></div>`).join("")+"</div>":"";f.innerHTML=(C?`<div class="tpl-grid">${C}</div>`:"")+R+(h.length?`<div class="tpl-bar tpl-output-bar"><span class="picked">${E}</span><div class="tpl-output-actions"><button type="button" id="template-use-upload" data-testid="template-use-upload" class="primary" ${M?"":"disabled"}>\u4E0A\u4F20\u539F\u7A3F\u5957\u7528</button><button type="button" id="template-use-report" data-testid="template-use-report" class="outline" ${M?"":"disabled"}>\u4ECE\u5DF2\u6709\u62A5\u544A\u5957\u7528</button><button type="button" id="template-new-report" data-testid="template-new-report" class="ghost" ${M?"":"disabled"}>\u6309\u6A21\u677F\u65B0\u5EFA\u62A5\u544A</button></div><p class="help">\u4E0A\u4F20\u539F\u7A3F\u6216\u9009\u62E9\u5DF2\u6709\u62A5\u544A\uFF0C\u6309\u6240\u9009\u7248\u5F0F\u751F\u6210 Word\uFF1B\u65B0\u5EFA\u62A5\u544A\u4F1A\u8FDB\u5165\u5199\u4F5C\u8BBE\u7F6E\u3002</p></div>`:'<p class="help">\u8FD8\u6CA1\u6709\u6A21\u677F\u3002\u6DFB\u52A0\u4E00\u4E2A Word \u4F5C\u4E3A\u7248\u5F0F\u6A21\u677F\u3002</p>');let A=$=>{y.some(H=>H.id===$&&H.status==="ready")&&(l=$,d.sig="",d())};f.querySelectorAll(".tpl-card").forEach($=>$.onclick=H=>{if(H.target.closest("button"))return;let I=k[$.dataset.genre]||[];A((I.find(w=>w.id===l)||I.find(w=>w.status==="ready"))?.id)}),f.querySelectorAll("[data-template-pick]").forEach($=>$.onclick=()=>A($.dataset.templatePick)),f.querySelectorAll(".color-dot").forEach($=>$.onclick=H=>{H.stopPropagation(),A($.dataset.id)});for(let[$,H]of[["template-use-upload","upload"],["template-use-report","report"]]){let I=u($);I&&(I.onclick=()=>{l&&a?.(l,H)})}let T=u("template-new-report");T&&(T.onclick=()=>e(async()=>{let $=(i().templates||[]).find(H=>H.id===l&&H.status==="ready");$&&(u("template-select").value=$.id,r(),s(),o?.($),t(`\u65B0\u5EFA\u62A5\u544A\u5DF2\u9009\u62E9 ${$.name}`),n("setup"))}))}return{render:d}}var VA=t=>["queued","running"].includes(t?.status),KA=t=>{try{return typeof t=="string"?JSON.parse(t):t||{}}catch{return{}}},JA=t=>KA(t?.detail).title||t?.title||"\u672A\u547D\u540D\u62A5\u544A";function yv({api:t,notice:e,refresh:n,getState:r,openBrief:s,uploadPayload:i,getUploadLimits:o,getCurrent:a=()=>null,savedVersion:l}){let c=null,d=null,p=0,f=new Map,h=w=>w.epoch===p&&r()?.workspace_id===w.workspace,m=w=>d===w&&c?.open&&h(w);function g(){c||(c=document.createElement("dialog"),c.id="template-output-dialog",c.className="template-output-dialog",c.setAttribute("aria-labelledby","template-output-title"),c.dataset.testid="template-output-dialog",c.addEventListener("cancel",w=>{w.preventDefault(),y()}),document.body.append(c))}function y(){c?.close()}function b(){++p;for(let w of f.values())clearTimeout(w.timer);f.clear(),d=null,y()}function k(w){return clearTimeout(w.timer),w.busy=!1,!1}function x(w){return h(w)||k(w)}function C(w){return w.versions.find(q=>q.id===w.selectedId)}function M(w){if(!m(w))return;let q=w.job?.status==="complete",D=!!w.job,O=w.busy||q,J=["failed","cancelled","interrupted"].includes(w.job?.status),ee=w.error||w.message||"",X=document.activeElement,ie=c.contains?.(X)?X?.id:null;c.innerHTML=`<div class="section-title"><h2 id="template-output-title">${w.mode==="upload"?"\u4E0A\u4F20\u539F\u7A3F\u5957\u7528":"\u4ECE\u5DF2\u6709\u62A5\u544A\u5957\u7528"}</h2><button type="button" id="template-output-close" data-testid="template-output-close" class="ghost" aria-label="\u5173\u95ED\u5957\u7528\u9762\u677F">\u5173\u95ED</button></div><p class="template-output-choice">\u7248\u5F0F\uFF1A<strong>${v(w.template.name.replace("\xB7"," \xB7 "))}</strong><span class="help">\u8F93\u51FA Word\uFF08.docx\uFF09</span></p>`+(w.mode==="upload"?`<p class="help">\u652F\u6301 DOCX\u3001Markdown\u3001TXT \u7684\u6B63\u6587\u3001\u6807\u9898\u3001\u5217\u8868\u548C\u8868\u683C\uFF1B\u4E0D\u8054\u7F51\u3001\u4E0D\u6539\u5199\u3002\u590D\u6742 Word \u5185\u5BB9\u6682\u4E0D\u652F\u6301\uFF0C\u539F\u6587\u4EF6\u4F1A\u4FDD\u7559\u3002</p><label class="template-output-field" ${w.file?"hidden":""}>\u9009\u62E9\u8981\u6392\u7248\u7684\u539F\u7A3F<input type="file" id="template-output-file" data-testid="template-output-file" accept=".docx,.md,.markdown,.txt" ${O||D?"disabled":""}></label>${w.file?`<div class="template-output-file-choice"><p class="help">\u5DF2\u9009\u539F\u7A3F\uFF1A${v(w.file.name)}</p>${O||D?"":'<button type="button" id="template-output-change-file" data-testid="template-output-change-file" class="outline">\u66F4\u6362\u6587\u4EF6</button>'}</div>`:""}`:`<p class="help">\u9009\u62E9\u5F53\u524D\u5DE5\u4F5C\u533A\u7684\u62A5\u544A\uFF0C\u4EE5\u9009\u4E2D\u7684\u5DF2\u4FDD\u5B58\u7248\u672C\u751F\u6210 Word\u3002\u82E5\u9009\u4E2D\u7248\u672C\u6B63\u5728\u7F16\u8F91\uFF0C\u4F1A\u5148\u4FDD\u5B58\u5176\u5F53\u524D\u4FEE\u6539\u3002</p><form id="template-output-search-form" class="template-output-search"><label for="template-output-search">\u67E5\u627E\u62A5\u544A</label><input type="search" id="template-output-search" data-testid="template-output-search" placeholder="\u641C\u7D22\u6807\u9898\u6216\u6B63\u6587" maxlength="200" value="${v(w.query)}" ${O||D?"disabled":""}><button type="submit" class="outline" ${O||D?"disabled":""}>\u67E5\u627E</button></form><label class="template-output-field">\u9009\u62E9\u62A5\u544A<select id="template-output-report" data-testid="template-output-report" ${O||D||w.loading?"disabled":""}><option value="">${w.loading?"\u6B63\u5728\u8BFB\u53D6\u62A5\u544A\u2026":"\u8BF7\u9009\u62E9\u4E00\u4EFD\u62A5\u544A"}</option>${w.items.map(L=>`<option value="${v(L.id)}" ${w.reportId===L.id?"selected":""}>${v(JA(L))} \xB7 ${v(Bs(L.created)||"\u4FDD\u5B58\u65F6\u95F4\u672A\u77E5")}</option>`).join("")}</select></label>${!w.loading&&!w.items.length?`<p class="help">${w.query?"\u6CA1\u6709\u627E\u5230\u7B26\u5408\u641C\u7D22\u6761\u4EF6\u7684\u62A5\u544A\u3002":"\u5F53\u524D\u5DE5\u4F5C\u533A\u8FD8\u6CA1\u6709\u5DF2\u4FDD\u5B58\u62A5\u544A\u3002"}</p>`:""}${w.listError?`<p class="template-output-error" role="alert">${v(w.listError)}</p><button type="button" id="template-output-reload" class="outline">\u91CD\u65B0\u8BFB\u53D6\u62A5\u544A</button>`:""}${w.cursor?`<button type="button" id="template-output-more" data-testid="template-output-more" class="ghost" ${O||D||w.loading?"disabled":""}>${w.loading?"\u6B63\u5728\u8BFB\u53D6\u2026":"\u52A0\u8F7D\u66F4\u591A\u62A5\u544A"}</button>`:""}`)+(w.mode==="report"&&w.reportId?`<label class="template-output-field">\u9009\u62E9\u5DF2\u4FDD\u5B58\u7248\u672C<select id="template-output-version" data-testid="template-output-version" ${O||D||w.historyLoading?"disabled":""}><option value="">${w.historyLoading?"\u6B63\u5728\u8BFB\u53D6\u7248\u672C\u2026":"\u8BF7\u9009\u62E9\u7248\u672C"}</option>${w.versions.map((L,K)=>`<option value="${v(L.id)}" ${w.selectedId===L.id?"selected":""}>${v(L.parent_id?"\u4FEE\u8BA2\u7A3F":"\u539F\u7A3F")} \xB7 ${v(Bs(L.created)||"\u4FDD\u5B58\u65F6\u95F4\u672A\u77E5")} \xB7 ${v(L.version_count>K?"\u7B2C"+(L.version_count-K)+"\u7248":L.author==="user"?"\u4EBA\u5DE5\u4FDD\u5B58":"\u5DF2\u4FDD\u5B58")}</option>`).join("")}</select></label>${w.historyError?`<p class="template-output-error" role="alert">${v(w.historyError)}</p><button type="button" id="template-output-history-reload" class="outline">\u91CD\u65B0\u8BFB\u53D6\u7248\u672C</button>`:""}${w.historyCursor?`<button type="button" id="template-output-history-more" class="ghost" ${O||D||w.historyLoading?"disabled":""}>\u52A0\u8F7D\u66F4\u65E9\u7248\u672C</button>`:""}`:"")+`<p id="template-output-status" data-testid="template-output-status" class="template-output-status${w.error?" template-output-error":""}" role="status" aria-live="polite">${v(ee)}</p>`+(w.notes.length?`<ul class="template-output-notes">${w.notes.map(L=>`<li>${v(typeof L=="string"?L:L?.message||L?.description||String(L))}</li>`).join("")}</ul>`:"")+`<div class="template-output-actions">${q?`<a class="primary template-output-download" id="template-output-download" data-testid="template-output-download" href="/api/export-file?${new URLSearchParams({job:w.job.id,workspace_id:w.workspace})}" download>\u4E0B\u8F7D Word</a><button type="button" id="template-output-open" data-testid="template-output-open" class="outline">${w.mode==="upload"?"\u6253\u5F00\u8F6C\u6362\u7A3F":"\u6253\u5F00\u6240\u9009\u62A5\u544A"}</button><button type="button" id="template-output-again" class="ghost">${w.mode==="upload"?"\u5957\u7528\u53E6\u4E00\u4EFD\u539F\u7A3F":"\u5957\u7528\u53E6\u4E00\u4EFD\u62A5\u544A"}</button>`:w.pollError?'<button type="button" id="template-output-poll" data-testid="template-output-poll" class="primary">\u91CD\u65B0\u68C0\u67E5\u8FDB\u5EA6</button>':`<button type="button" id="template-output-submit" data-testid="template-output-submit" class="primary" ${w.busy||w.loading||w.historyLoading||!(w.mode==="upload"?w.file:w.selectedId)?"disabled":""}>${w.busy?"\u6B63\u5728\u5236\u4F5C\u2026":D?"\u91CD\u8BD5\u751F\u6210 Word":"\u5957\u7528\u5E76\u751F\u6210 Word"}</button>`}${J?`<button type="button" id="template-output-again" class="outline">${w.mode==="upload"?"\u66F4\u6362\u539F\u7A3F":"\u91CD\u65B0\u9009\u62E9\u62A5\u544A"}</button>`:""}</div>`+(w.busy?'<p class="help">\u5173\u95ED\u9762\u677F\u4E0D\u4F1A\u505C\u6B62\u5DF2\u63D0\u4EA4\u7684\u5236\u4F5C\u4EFB\u52A1\uFF1B\u518D\u6B21\u70B9\u51FB\u540C\u4E00\u6A21\u677F\u7684\u5957\u7528\u5165\u53E3\u53EF\u67E5\u770B\u8FDB\u5EA6\u3002</p>':""),u("template-output-close").onclick=y,u("template-output-file")&&(u("template-output-file").onchange=L=>{w.file=L.target.files?.[0]||null,w.requestId=crypto.randomUUID(),w.version=null,w.error="",w.message="",w.file&&!/\.(docx|md|markdown|txt)$/i.test(w.file.name)&&(w.file=null,w.error="\u8BF7\u9009\u62E9 DOCX\u3001Markdown \u6216 TXT \u539F\u7A3F\u3002"),M(w)}),u("template-output-change-file")&&(u("template-output-change-file").onclick=()=>u("template-output-file").click()),u("template-output-search-form")&&(u("template-output-search-form").onsubmit=L=>{L.preventDefault(),w.query=u("template-output-search").value.trim(),R(w),w.version=null,E(w)}),u("template-output-report")&&(u("template-output-report").onchange=L=>{R(w),w.reportId=L.target.value,w.version=null,w.error="",M(w),w.reportId&&A(w)}),u("template-output-version")&&(u("template-output-version").onchange=L=>{w.selectedId=L.target.value,w.version=null,w.error="",M(w)}),u("template-output-history-more")&&(u("template-output-history-more").onclick=()=>A(w,!0)),u("template-output-history-reload")&&(u("template-output-history-reload").onclick=()=>A(w)),u("template-output-more")&&(u("template-output-more").onclick=()=>E(w,!0)),u("template-output-reload")&&(u("template-output-reload").onclick=()=>E(w)),u("template-output-submit")&&(u("template-output-submit").onclick=()=>H(w)),u("template-output-poll")&&(u("template-output-poll").onclick=()=>{w.busy||(w.busy=!0,w.pollError=!1,w.error="",M(w),$(w))}),u("template-output-download")&&(u("template-output-download").onclick=L=>{h(w)||(L.preventDefault(),e("\u5DE5\u4F5C\u533A\u5DF2\u5207\u6362\uFF0C\u8BF7\u56DE\u5230\u539F\u5DE5\u4F5C\u533A\u4E0B\u8F7D\u3002",!0))}),u("template-output-open")&&(u("template-output-open").onclick=async()=>{if(!x(w))return;let L=u("template-output-open");L.disabled=!0;try{await s(w.version)&&y()}catch(K){m(w)&&e(K.message,!0)}finally{m(w)&&(L.disabled=!1)}}),u("template-output-again")&&(u("template-output-again").onclick=()=>{clearTimeout(w.timer),R(w),w.job=null,w.version=null,w.file=null,w.requestId=null,w.pollError=!1,w.error="",w.message="",w.notes=[],M(w),w.mode==="report"&&E(w)}),ie&&(ie==="template-output-file"&&w.file?u("template-output-change-file"):u(ie))?.focus?.()}async function E(w,q=!1){if(!x(w)||w.busy||w.job)return;let D=++w.listTicket,O=w.query;w.loading=!0,w.listError="",M(w);let J=new URLSearchParams({q:O,workspace_id:w.workspace});q&&w.cursor&&J.set("cursor",w.cursor);try{let ee=await t("reports?"+J);if(!x(w)||D!==w.listTicket)return;let X=Array.isArray(ee.items)?ee.items:[];w.items=q?[...w.items,...X.filter(ie=>!w.items.some(L=>L.id===ie.id))]:X,w.cursor=ee.next_cursor||"",w.items.some(ie=>ie.id===w.reportId)||R(w)}catch(ee){h(w)&&D===w.listTicket&&(w.listError="\u62A5\u544A\u8BFB\u53D6\u5931\u8D25\uFF1A"+ee.message)}finally{h(w)&&D===w.listTicket&&(w.loading=!1,M(w))}}function R(w){++w.historyTicket,w.reportId="",w.selectedId="",w.versions=[],w.historyCursor="",w.historyLoading=!1,w.historyError=""}async function A(w,q=!1){if(!x(w)||w.busy||w.job)return;let D=w.items.find(X=>X.id===w.reportId);if(!D)return;let O=++w.historyTicket,J=w.reportId;w.historyLoading=!0,w.historyError="",M(w);let ee=new URLSearchParams({run_id:D.run_id,workspace_id:w.workspace});q&&w.historyCursor&&ee.set("cursor",w.historyCursor);try{let X=await t("report-history?"+ee);if(!x(w)||O!==w.historyTicket||w.reportId!==J)return;let ie=(Array.isArray(X.items)?X.items:[]).filter(L=>L.run_id===D.run_id);w.versions=q?[...w.versions,...ie.filter(L=>!w.versions.some(K=>K.id===L.id))]:ie,w.historyCursor=X.next_cursor||"",w.versions.some(L=>L.id===w.selectedId)||(w.selectedId=w.versions[0]?.id||"")}catch(X){h(w)&&O===w.historyTicket&&(w.historyError="\u7248\u672C\u8BFB\u53D6\u5931\u8D25\uFF1A"+X.message)}finally{h(w)&&O===w.historyTicket&&(w.historyLoading=!1,M(w))}}function T(w,q){if(!q?.id)throw Error("\u672A\u6536\u5230\u6587\u4EF6\u5236\u4F5C\u4EFB\u52A1\uFF0C\u8BF7\u68C0\u67E5\u62A5\u544A\u5217\u8868\u540E\u518D\u8BD5\u3002");if(w.job=q,q.status==="complete"){w.busy=!1,w.pollError=!1,w.error="",w.message=w.mode==="upload"?"Word \u5DF2\u751F\u6210\uFF0C\u8F6C\u6362\u7A3F\u5DF2\u4FDD\u5B58\u3002":"Word \u5DF2\u751F\u6210\u3002",M(w),Promise.resolve().then(()=>h(w)&&n?.()).catch(()=>{h(w)&&(w.message+=" \u62A5\u544A\u5217\u8868\u6682\u672A\u5237\u65B0\uFF0C\u53EF\u7A0D\u540E\u91CD\u8BD5\u3002",M(w))});return}if(!VA(q)){w.busy=!1,w.pollError=!1,w.error=q.error||{cancelled:"Word \u5236\u4F5C\u5DF2\u53D6\u6D88\uFF0C\u53EF\u91CD\u8BD5\u3002",interrupted:"Word \u5236\u4F5C\u5DF2\u4E2D\u65AD\uFF0C\u53EF\u91CD\u8BD5\u3002",failed:"Word \u5236\u4F5C\u5931\u8D25\uFF0C\u53EF\u91CD\u8BD5\u3002"}[q.status]||"Word \u5C1A\u672A\u5236\u4F5C\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5\u3002",M(w);return}let D=q.status==="queued"?"\u5DF2\u63D0\u4EA4\uFF0C\u7B49\u5F85\u5236\u4F5C Word\u2026":"\u6B63\u5728\u5236\u4F5C Word\u2026";w.message!==D&&(w.message=D,M(w)),w.timer=setTimeout(()=>$(w),1e3)}async function $(w){if(clearTimeout(w.timer),!(!x(w)||!w.job))try{let q=await t("export-status?"+new URLSearchParams({job:w.job.id,workspace_id:w.workspace}));x(w)&&T(w,q)}catch(q){h(w)&&(w.busy=!1,w.pollError=!0,w.error="\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u5236\u4F5C\u8FDB\u5EA6\uFF1A"+q.message+"\u3002\u4EFB\u52A1\u53EF\u80FD\u4ECD\u5728\u8FD0\u884C\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u8FDB\u5EA6\u3002",M(w))}}async function H(w){if(!x(w)||w.busy||w.loading||w.historyLoading||w.pollError||w.job?.status==="complete")return;if((r().templates||[]).find(O=>O.id===w.template.id)?.status!=="ready"){w.error="\u6240\u9009\u6A21\u677F\u5C1A\u4E0D\u53EF\u7528\uFF0C\u8BF7\u8FD4\u56DE\u6A21\u677F\u9875\u91CD\u65B0\u9009\u62E9\u3002",M(w);return}let D=C(w);if(!(w.mode==="upload"&&!w.file||w.mode==="report"&&!D)){w.busy=!0,w.error="",w.message="\u6B63\u5728\u51C6\u5907\u539F\u7A3F\u2026",M(w);try{if(w.mode==="upload"&&!w.version){let O=await i(w.file,o(),{template_id:w.template.id,workspace_id:w.workspace,request_id:w.requestId});if(!x(w))return;let J=await t("template-convert",O);if(!x(w))return;if(!J.version?.id)throw Error("\u672A\u6536\u5230\u5DF2\u4FDD\u5B58\u7684\u8F6C\u6362\u7A3F\uFF0C\u8BF7\u68C0\u67E5\u62A5\u544A\u5217\u8868\u540E\u518D\u8BD5\u3002");w.version=J.version,w.notes=Array.isArray(J.notes)?J.notes:[],T(w,J.job)}else{let O=w.version||D;if(!w.version&&a()?.id===D.id&&l){let ee=await l();if(!x(w))return;if(a()?.run_id!==D.run_id||a()?.id!==ee)throw Error("\u6B63\u5728\u7F16\u8F91\u7684\u62A5\u544A\u5DF2\u5207\u6362\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u62A5\u544A\u3002");O={...a(),id:ee}}if(!x(w))return;w.version=O;let J=await t("export",{version_id:O.id,template_id:w.template.id,workspace_id:w.workspace});x(w)&&T(w,J)}}catch(O){h(w)&&(w.busy=!1,w.error=O.message,M(w))}}}function I(w,q="upload"){let D=r(),O=D?.templates?.find(X=>X.id===w);if(!D?.workspace_id||O?.status!=="ready")return e("\u6240\u9009\u6A21\u677F\u5C1A\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u3002",!0),!1;q=q==="report"?"report":"upload",g();let J=JSON.stringify([D.workspace_id,w,q]),ee=f.get(J);return ee||(ee={epoch:p,workspace:D.workspace_id,template:O,mode:q,file:null,requestId:null,items:[],query:"",cursor:"",selectedId:"",reportId:"",versions:[],historyTicket:0,historyCursor:"",historyLoading:!1,historyError:"",listTicket:0,loading:!1,listError:"",busy:!1,pollError:!1,job:null,version:null,notes:[],message:"",error:""},f.set(J,ee)),d=ee,c.open||c.showModal(),M(ee),(u("template-output-download")||u("template-output-change-file")||u(q==="upload"?"template-output-file":"template-output-search"))?.focus?.(),q==="report"&&!ee.job&&!ee.loading&&E(ee),!0}return{open:I,close:y,reset:b}}var ji={initial:"\u9996\u6B21\u4EA4\u4ED8",correction:"\u66F4\u6B63",update:"\u540E\u7EED\u4FE1\u606F\u66F4\u65B0"},Fi=t=>t?Kt(t):"\u65F6\u95F4\u672A\u8BB0\u5F55";function bv({api:t,notice:e,action:n,page:r,openBrief:s,savedVersion:i,statuses:o,getState:a,getCurrent:l,isDirty:c,isSaving:d,office:p}){let f={version:null,data:null,loading:!1},h=null,m={pending:"\u7B49\u5F85\u5236\u4F5C",released:"\u6B63\u5F0F\u4EF6\u5DF2\u4FDD\u5B58",failed:"\u5236\u4F5C\u672A\u5B8C\u6210",cancelled:"\u5DF2\u505C\u6B62"};function g(A){if(!A)return"<p>\u4EA4\u4ED8\u6761\u4EF6\u6682\u4E0D\u53EF\u7528\uFF0C\u5C1A\u672A\u5224\u5B9A\u901A\u8FC7\u3002</p>";let T=A.blockers||[],$=A.notices||[];return`<h3>${A.eligible?"\u5F53\u524D\u7248\u672C\u6EE1\u8DB3\u6B63\u5F0F\u4EA4\u4ED8\u6761\u4EF6":"\u5F53\u524D\u7248\u672C\u8FD8\u6709\u9700\u5904\u7406\u4E8B\u9879"}</h3>${T.length?`<ul class="release-blockers">${T.map(H=>`<li>${v(H.message||H)}</li>`).join("")}</ul>`:""}${$.length?`<details open><summary>\u4FDD\u7559\u7684\u63D0\u793A \xB7 ${$.length} \u9879</summary><ul>${$.map(H=>`<li>${v(H.message||H)}</li>`).join("")}</ul></details>`:""}${A.eligible?"":'<p class="help">\u5DE5\u4F5C\u7A3F\u4ECD\u53EF\u7F16\u8F91\u548C\u4E0B\u8F7D\u3002\u8BF7\u5728\u201C\u5BA1\u9605\u4E0E\u9700\u5904\u7406\u201D\u4E2D\u5904\u7406\u95EE\u9898\u540E\u590D\u6838\u3002</p>'}`}function y(A){let T=a(),$=l(),H=T.jobs.find(q=>q.id===A.job_id),I=A.status==="released"?m.released:o[H?.status]||m[A.status]||A.status,w=ji[A.change_type]||(A.previous_id?"\u5173\u8054\u65E7\u6B63\u5F0F\u4EF6":"\u9996\u6B21\u4EA4\u4ED8");return`<article class="release-card"><div class="section-title"><strong>${v(w)} \xB7 ${v(Fi(A.created))}</strong><span class="tag">${v(I)}</span></div><p class="help">${A.version_id===$?.id?"\u5F53\u524D\u6B63\u5728\u67E5\u770B\u7684\u7A3F\u4EF6\u7248\u672C":"\u5386\u53F2\u7A3F\u4EF6\u7248\u672C"}${A.previous_id?" \xB7 \u5173\u8054\u65E7\u6B63\u5F0F\u4EF6 "+v(A.previous_id.slice(-8)):""}</p>${A.change_reason?`<p>${v(A.change_reason)}</p>`:""}${H?.error?`<p class="error">${v(H.error)}</p>`:""}${A.status==="released"?`<div class="release-actions"><a href="/api/release-file?id=${encodeURIComponent(A.id)}" download>\u4E0B\u8F7D\u6B63\u5F0F Word</a><button type="button" data-audit-release="${v(A.id)}">\u5BFC\u51FA\u5BA1\u8BA1\u5305\u2026</button></div>`:'<p class="help">\u4EFB\u52A1\u8FDB\u5EA6\u89C1\u62A5\u544A\u4E0B\u65B9\u7684\u6587\u4EF6\u5236\u4F5C\u8BB0\u5F55\u3002</p>'}</article>`}async function b(){if(f.loading||!u("release-dialog").open)return;let A=l()?.id;if(A){f.loading=!0;try{let T=await t("release-state?version="+encodeURIComponent(A));if(!u("release-dialog").open||l()?.id!==A)return;f.version=A,f.data=T,u("release-eligibility").innerHTML=(c()?'<p class="help">\u6709\u672A\u4FDD\u5B58\u4FEE\u6539\uFF0C\u4E0B\u5217\u6761\u4EF6\u9488\u5BF9\u4E0A\u6B21\u4FDD\u5B58\u7684\u7248\u672C\u3002</p>':"")+g(T.eligibility),u("release-submit").disabled=c()||d()||!T.eligibility?.eligible||f.submitting;let $=(T.releases||[]).filter(q=>q.status==="released"),H=u("release-previous"),I=$.map(q=>q.id).join(",");if(H.dataset.choices!==I){let q=H.value;H.innerHTML='<option value="">\u9996\u6B21\u4EA4\u4ED8</option>'+$.map(D=>`<option value="${v(D.id)}">${v(Fi(D.created))} \xB7 ${v(ji[D.change_type]||"\u6B63\u5F0F\u4EF6")} \xB7 ${v(D.id.slice(-8))}</option>`).join(""),H.dataset.choices=I,$.some(D=>D.id===q)&&(H.value=q),k()}let w=(T.releases||[]).map(y).join("")||'<p class="help">\u6B64\u62A5\u544A\u5C1A\u65E0\u6B63\u5F0F\u4EA4\u4ED8\u8BB0\u5F55\u3002</p>';u("release-list").innerHTML!==w&&(u("release-list").innerHTML=w,u("release-list").querySelectorAll("[data-audit-release]").forEach(q=>q.onclick=()=>M(q.dataset.auditRelease)))}finally{f.loading=!1}}}function k(){let A=!!u("release-previous").value;u("release-change-fields").hidden=!A,u("release-change-reason").required=A}async function x(A=null){if(A&&!s(A,{follow:!1}))return;let T=s.request;if(T&&(!await T.promise||s.request||l()?.id!==T.id)||A&&l()?.id!==A.id)return;let $=l()?.run_id,H=await i();s.request||l()?.id!==H||l()?.run_id!==$||(r("report"),u("release-eligibility").textContent="\u6B63\u5728\u6838\u5BF9\u5F53\u524D\u7248\u672C\u7684\u4EA4\u4ED8\u6761\u4EF6\u2026",u("release-submit").disabled=!0,u("release-dialog").showModal(),await b())}async function C(){let A=u("release-previous").value,T=u("release-change-type").value,$=u("release-change-reason").value.trim();if(A&&!$)throw Error("\u8BF7\u8BF4\u660E\u672C\u6B21\u66F4\u6B63\u6216\u66F4\u65B0\u7684\u4F9D\u636E\u548C\u5F71\u54CD");let I={version_id:await i()};return A&&Object.assign(I,{previous_id:A,change_type:T,change_reason:$}),await t("release",I)}function M(A){let T=f.data?.releases.find(I=>I.id===A);if(!T||T.status!=="released"){e("\u8BF7\u5148\u7B49\u5F85\u6B63\u5F0F\u4EF6\u5236\u4F5C\u5B8C\u6210",!0);return}h=T;let $=u("audit-office-render");$&&($.checked=!1);let H=u("audit-office-row");H&&(H.hidden=!p?.officeEnabled()),u("audit-target").textContent="\u6B63\u5F0F\u4EF6\uFF1A"+Fi(T.created)+" \xB7 "+(ji[T.change_type]||"\u9996\u6B21\u4EA4\u4ED8")+" \xB7 "+T.id.slice(-8),u("audit-source-list").innerHTML=(T.sources||T.data?.snapshot?.sources||[]).map(I=>`<label class="audit-source-row"><span>${v(I.name||I.id)}</span><select data-audit-source="${v(I.id)}" aria-label="${v(I.name||I.id)}\u7684\u6253\u5305\u8303\u56F4"><option value="metadata">\u4EC5\u5B9A\u4F4D\uFF0C\u4E0D\u542B\u539F\u4EF6\u548C\u6458\u5F55</option><option value="excerpt">\u5B9A\u4F4D\u4E0E\u8BC1\u636E\u6458\u5F55</option><option value="original">\u539F\u4EF6\u53CA\u8BC1\u636E\u6458\u5F55</option></select></label>`).join("")||'<p class="help">\u6B64\u6B63\u5F0F\u4EF6\u6CA1\u6709\u767B\u8BB0\u6765\u6E90\u6587\u4EF6\u3002</p>',u("audit-submit").disabled=!1,u("audit-dialog").showModal()}async function E(){if(!h)throw Error("\u8BF7\u5148\u9009\u62E9\u4E00\u4E2A\u5DF2\u4FDD\u5B58\u7684\u6B63\u5F0F\u4EF6");let A=h.id,T=Object.fromEntries([...u("audit-source-list").querySelectorAll("[data-audit-source]")].map($=>[$.dataset.auditSource,$.value]));return t("audit-bundle",{release_id:A,source_permissions:T,include_office_render:u("audit-office-render")?.checked===!0})}function R(){u("release-previous").onchange=k,u("release-open").onclick=()=>n(()=>x()),u("release-close").onclick=()=>u("release-dialog").close(),u("release-form").onsubmit=A=>{A.preventDefault(),!f.submitting&&(f.submitting=!0,u("release-submit").disabled=!0,n(async()=>{try{await C(),u("release-dialog").close(),e("\u6B63\u5F0F Word \u5DF2\u6392\u961F\uFF0C\u4F7F\u7528\u672C\u6B21\u63D0\u4EA4\u65F6\u56FA\u5B9A\u7684\u7248\u672C")}finally{f.submitting=!1,await b()}}))},u("audit-close").onclick=()=>u("audit-dialog").close(),u("audit-all-original").onclick=()=>{u("audit-source-list").querySelectorAll("[data-audit-source]").forEach(A=>A.value="original")},u("audit-all-metadata").onclick=()=>{u("audit-source-list").querySelectorAll("[data-audit-source]").forEach(A=>A.value="metadata")},u("audit-form").onsubmit=A=>{A.preventDefault(),!u("audit-submit").disabled&&(u("audit-submit").disabled=!0,n(async()=>{try{await E(),u("audit-dialog").close(),u("release-dialog").close(),e("\u5BA1\u8BA1\u5305\u5DF2\u6392\u961F\uFF0C\u5B8C\u6210\u540E\u53EF\u5728\u6587\u4EF6\u5236\u4F5C\u8BB0\u5F55\u4E0B\u8F7D")}finally{u("audit-submit").disabled=!1}}))}}return{init:R,refreshReleaseState:b,openReleaseDialog:x,openAuditBundle:M,submitFormalRelease:C,submitAuditBundle:E}}function vv(t){if(/^#[a-f\d]{6}$/i.test(t||""))return t.toLowerCase();let e=/^rgb\(\s*(\d+)[, ]+\s*(\d+)[, ]+\s*(\d+)\s*\)$/.exec(t||"");return e?"#"+e.slice(1).map(n=>Math.min(255,Number(n)).toString(16).padStart(2,"0")).join(""):null}var Wi=ht.create({name:"textStyle",addAttributes(){return{color:{default:null,parseHTML:t=>vv(t.style.color),renderHTML:t=>t.color?{style:"color:"+t.color}:{}}}},parseHTML(){return[{tag:"span",getAttrs:t=>t.style.color?{}:!1}]},renderHTML({HTMLAttributes:t}){return["span",ue(t),0]},renderMarkdown(t,e){return e.renderChildren(t)}}),Ui=we.create({name:"reportLayout",addGlobalAttributes(){return[{types:["paragraph","heading","image","table","tableCell","tableHeader"],attributes:{textAlign:{default:null,parseHTML:t=>t.style.textAlign||null,renderHTML:t=>t.textAlign?{style:"text-align:"+t.textAlign}:{}},blockId:{default:null,parseHTML:t=>t.getAttribute("data-block-id"),renderHTML:t=>t.blockId?{"data-block-id":t.blockId}:{}}}},{types:["tableCell","tableHeader"],attributes:{backgroundColor:{default:null,parseHTML:t=>vv(t.style.backgroundColor),renderHTML:t=>t.backgroundColor?{style:"background-color:"+t.backgroundColor}:{}},textAlign:{default:null,parseHTML:t=>t.style.textAlign||null,renderHTML:t=>t.textAlign?{style:"text-align:"+t.textAlign}:{}}}}]}});function GA(){return new de({appendTransaction(t,e,n){let r=n.schema.nodes.paragraph;return!t.some(s=>s.docChanged)||!r||n.doc.lastChild?.type===r?null:n.tr.insert(n.doc.content.size,r.create()).setMeta("addToHistory",!1)}})}var wv=we.create({name:"reportTrailingParagraph",addProseMirrorPlugins(){return[GA()]}}),Vi=qk.extend({addAttributes(){return{...this.parent?.(),width:{default:null,parseHTML:t=>Number(t.getAttribute("width"))||null},height:{default:null,parseHTML:t=>Number(t.getAttribute("height"))||null},caption:{default:null,parseHTML:t=>t.getAttribute("data-caption"),renderHTML:t=>t.caption?{"data-caption":t.caption}:{}}}},renderHTML({node:t,HTMLAttributes:e}){return["figure",{class:"report-image"},["img",ue(this.options.HTMLAttributes,e)],...t.attrs.caption?[["figcaption",{},t.attrs.caption]]:[]]},renderMarkdown(t){let e=t.attrs;return"!["+(e.alt||"").replaceAll("]","\\]")+"]("+e.src+")"+(e.caption?`
255
255
 
@@ -78,7 +78,7 @@
78
78
  <div class="settings-page-header"><div><p class="eyebrow">BRIEFLOOP · 设置</p><h1 id="settings-title">模型与工作设置</h1><p class="help">配置执行引擎、模型与工作习惯。</p></div><button id="settings-close" type="button" class="outline">返回对话 ↗</button></div>
79
79
  <div class="settings-layout"><nav class="settings-nav" aria-label="设置分类"><button type="button" data-settings-view="models" class="active">模型与提供商</button><button type="button" data-settings-view="connectors">数据连接器(MCP)</button><button type="button" data-settings-view="execution">运行与搜索</button><button type="button" data-settings-view="learning">反馈与学习</button><button type="button" data-settings-view="workspaces">工作区</button><button type="button" data-settings-view="updates">版本与更新</button></nav>
80
80
  <div class="settings-content"><section id="settings-view-models"><div class="settings-segments" role="tablist" aria-label="模型接入方式"><button id="settings-tab-api" role="tab" aria-selected="false" aria-controls="settings-api" type="button" title="基于 Pi SDK">BriefLoop Agent</button><button id="settings-tab-cli" role="tab" aria-selected="true" aria-controls="settings-cli" type="button">Agent CLI</button></div><div id="settings-session-note" class="settings-session-note help" hidden></div><section id="settings-cli" role="tabpanel" aria-labelledby="settings-tab-cli"><div id="settings-runtime-list"></div><div id="settings-model-block"></div></section><section id="settings-api" role="tabpanel" aria-labelledby="settings-tab-api" hidden><div id="settings-native-runtime"></div></section></section>
81
- <section id="settings-view-updates" data-web-version="0.27.1" hidden>
81
+ <section id="settings-view-updates" data-web-version="0.28.0" hidden>
82
82
  <h2>版本与更新</h2><p id="app-update-version">正在读取实际运行版本…</p><p id="app-update-installation" class="help"></p><pre id="app-update-command" hidden></pre>
83
83
  <p id="app-update-source" class="help">官方稳定来源:Stahl-G/briefloop · GitHub Releases</p>
84
84
  <p id="app-update-status" role="status" aria-live="polite">尚未检查更新</p>