agent-tune-kit 2.3.4__tar.gz → 2.4.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 (191) hide show
  1. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/.codex-plugin/plugin.json +1 -1
  2. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/PKG-INFO +4 -4
  3. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/README.en.md +3 -3
  4. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/README.md +4 -4
  5. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/__init__.py +1 -1
  6. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/projects.py +74 -18
  7. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/records.py +3 -1
  8. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/dataset/app.js +1 -1
  9. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/failures/app.js +9 -9
  10. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/failures/page.html +3 -3
  11. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/shared/base.css +7 -13
  12. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/app.js +441 -266
  13. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/lanes.js +13 -32
  14. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/page.html +21 -18
  15. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/styles.css +112 -56
  16. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/traces/app.js +160 -85
  17. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/traces/page.html +5 -7
  18. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/traces/styles.css +23 -17
  19. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/failures.py +1 -0
  20. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/history.py +5 -1
  21. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/trace.py +11 -26
  22. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/traces.py +49 -27
  23. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/assets/architecture.svg +1 -1
  24. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/codex_agent_tuning_prd.md +35 -35
  25. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/execution-evidence-and-tracing-plan.md +1 -1
  26. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/ground-truth-and-grading-assessment-2026-10-25.md +1 -1
  27. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/shared-versioning-and-confirmation.md +5 -1
  28. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/skill-template-pack-usage.md +2 -2
  29. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/trace-dashboard-design.md +34 -30
  30. agent_tune_kit-2.4.0/docs/trace-project-attribution-design.md +99 -0
  31. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/trace-swimlane-design.md +44 -30
  32. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/trace-tuning.md +17 -13
  33. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/pyproject.toml +1 -1
  34. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/scripts/validate_skill_pack.py +2 -2
  35. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-optimize/SKILL.md +3 -3
  36. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-report/SKILL.md +4 -4
  37. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-trace-detect/SKILL.md +5 -3
  38. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-trace-diagnose/SKILL.md +17 -15
  39. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-trace-init/SKILL.md +4 -2
  40. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-trace-optimize/SKILL.md +5 -3
  41. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-trace-verify/SKILL.md +4 -2
  42. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-visualize-trace/SKILL.md +4 -2
  43. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_diagnosis.py +13 -2
  44. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_generate_failure_browser.py +1 -1
  45. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_install_plugin.py +1 -1
  46. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_release_scripts.py +1 -1
  47. agent_tune_kit-2.4.0/tests/test_trace_event_list.py +13 -0
  48. agent_tune_kit-2.4.0/tests/test_trace_projects.py +147 -0
  49. agent_tune_kit-2.4.0/tests/test_trace_scroll_layout.py +80 -0
  50. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_visualize_trace.py +24 -2
  51. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_visualize_traces.py +35 -6
  52. agent_tune_kit-2.4.0/tests/trace-controls.cjs +54 -0
  53. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/trace-dashboard.cjs +215 -67
  54. agent_tune_kit-2.4.0/tests/trace-event-detail.cjs +116 -0
  55. agent_tune_kit-2.4.0/tests/trace-event-layout.cjs +178 -0
  56. agent_tune_kit-2.4.0/tests/trace-event-list.cjs +64 -0
  57. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/trace-event-wheel.cjs +1 -1
  58. agent_tune_kit-2.4.0/tests/trace-fragments.cjs +332 -0
  59. agent_tune_kit-2.4.0/tests/trace-issue-cards.cjs +109 -0
  60. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/trace-preview-scroll.cjs +11 -4
  61. agent_tune_kit-2.4.0/tests/trace-projects.cjs +237 -0
  62. agent_tune_kit-2.4.0/tests/trace-scroll-layout.cjs +124 -0
  63. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/trace-stage-cards.cjs +31 -1
  64. agent_tune_kit-2.3.4/docs/trace-project-attribution-design.md +0 -246
  65. agent_tune_kit-2.3.4/tests/test_trace_projects.py +0 -65
  66. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/.gitignore +0 -0
  67. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/__init__.py +0 -0
  68. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/__main__.py +0 -0
  69. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/dataset.py +0 -0
  70. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/evaluation.py +0 -0
  71. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/main.py +0 -0
  72. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/output.py +0 -0
  73. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/results.py +0 -0
  74. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/trace.py +0 -0
  75. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/cli/visualize.py +0 -0
  76. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/datasets/__init__.py +0 -0
  77. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/datasets/prepare.py +0 -0
  78. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/datasets/truth.py +0 -0
  79. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/datasets/updates.py +0 -0
  80. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/datasets/validation.py +0 -0
  81. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/errors.py +0 -0
  82. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/__init__.py +0 -0
  83. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/calibration.py +0 -0
  84. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/logs.py +0 -0
  85. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/rules.py +0 -0
  86. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/runner.py +0 -0
  87. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/runtime.py +0 -0
  88. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/execution/tracing.py +0 -0
  89. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/installer.py +0 -0
  90. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/results/__init__.py +0 -0
  91. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/results/assessment.py +0 -0
  92. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/results/evidence.py +0 -0
  93. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/results/judgments.py +0 -0
  94. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/results/summary.py +0 -0
  95. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/results/versions.py +0 -0
  96. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/__init__.py +0 -0
  97. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/archive.py +0 -0
  98. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/capture.py +0 -0
  99. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/categories.py +0 -0
  100. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/langfuse.py +0 -0
  101. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/migrate.py +0 -0
  102. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/progress.py +0 -0
  103. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/query.py +0 -0
  104. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/segments.py +0 -0
  105. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/traces/store.py +0 -0
  106. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/utils/__init__.py +0 -0
  107. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/utils/csv_io.py +0 -0
  108. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/utils/files.py +0 -0
  109. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/__init__.py +0 -0
  110. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/dataset/page.html +0 -0
  111. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/dataset/styles.css +0 -0
  112. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/dataset/vendor/echarts.min.js +0 -0
  113. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/failures/styles.css +0 -0
  114. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/vendor/markdown-it.LICENSE +0 -0
  115. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/assets/trace/vendor/markdown-it.min.js +0 -0
  116. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/dataset.py +0 -0
  117. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/fields.py +0 -0
  118. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/render.py +0 -0
  119. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/visualize/timeline.py +0 -0
  120. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/agent_tune_kit/workspace.py +0 -0
  121. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/assets/agent_tune_kit_evaluation.png +0 -0
  122. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/assets/agent_tune_kit_trace.png +0 -0
  123. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/assets/arch-en.png +0 -0
  124. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/assets/arch.png +0 -0
  125. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/assets/architecture.en.svg +0 -0
  126. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/ato-atk-project-boundary-recommendation-2026-11-05.md +0 -0
  127. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/cli-skill-modularization-plan.md +0 -0
  128. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/local-context.md +0 -0
  129. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/surginame-atk-capability-review-2026-10-27.md +0 -0
  130. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/trace-change-verification-readability-diagnosis.md +0 -0
  131. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/trace-tuning-validation.md +0 -0
  132. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/docs/truth-and-assessment.md +0 -0
  133. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/scripts/check-release.py +0 -0
  134. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/scripts/dev-refresh-install.sh +0 -0
  135. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/scripts/install_plugin.py +0 -0
  136. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/scripts/publish-pypi.sh +0 -0
  137. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/scripts/publish-release.py +0 -0
  138. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/scripts/release-version.py +0 -0
  139. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/scripts/release-version.sh +0 -0
  140. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-dataset/SKILL.md +0 -0
  141. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-dataset/scripts/update_dataset.py +0 -0
  142. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-diagnose/SKILL.md +0 -0
  143. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-eval/SKILL.md +0 -0
  144. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-init/SKILL.md +0 -0
  145. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-trace-capture/SKILL.md +0 -0
  146. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-visualize-dataset/SKILL.md +0 -0
  147. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-visualize-dataset/scripts/generate_dataset_browser.py +0 -0
  148. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-visualize-failures/SKILL.md +0 -0
  149. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/skills/atk-visualize-failures/scripts/generate_failure_browser.py +0 -0
  150. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/templates/.atk/runner/eval_runner.py.md +0 -0
  151. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/templates/.atk/runner/failure_rule.py.md +0 -0
  152. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/templates/.atk/runner/import_evidence.py.md +0 -0
  153. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/templates/.gitkeep +0 -0
  154. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/__init__.py +0 -0
  155. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/conftest.py +0 -0
  156. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/fixtures/legacy_eval_runner.py.txt +0 -0
  157. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/fixtures/managed_v1.py.md +0 -0
  158. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_assessment_contract.py +0 -0
  159. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_atk_init_contract.py +0 -0
  160. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_cli_workflow.py +0 -0
  161. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_dataset_updates.py +0 -0
  162. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_evidence_import.py +0 -0
  163. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_evidence_judgments.py +0 -0
  164. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_evidence_packaging.py +0 -0
  165. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_evidence_versions.py +0 -0
  166. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_execution_evidence.py +0 -0
  167. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_execution_outcomes.py +0 -0
  168. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_execution_tracing.py +0 -0
  169. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_generate_dataset_browser.py +0 -0
  170. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_judge_calibration.py +0 -0
  171. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_local_context.py +0 -0
  172. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_plugin_cache.py +0 -0
  173. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_runner_output_columns.py +0 -0
  174. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_runner_template_row_logging.py +0 -0
  175. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_runtime_contracts.py +0 -0
  176. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_snapshot_reads.py +0 -0
  177. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_trace_capture.py +0 -0
  178. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_trace_categories.py +0 -0
  179. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_trace_cli.py +0 -0
  180. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_trace_langfuse.py +0 -0
  181. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_trace_progress.py +0 -0
  182. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_trace_query.py +0 -0
  183. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_trace_records.py +0 -0
  184. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_trace_segments.py +0 -0
  185. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_trace_store.py +0 -0
  186. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_truth_browser.py +0 -0
  187. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_truth_cli.py +0 -0
  188. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_truth_contract.py +0 -0
  189. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_truth_runner.py +0 -0
  190. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/test_v2_progress.py +0 -0
  191. {agent_tune_kit-2.3.4 → agent_tune_kit-2.4.0}/tests/trace-selection-reason.cjs +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-tune-kit",
3
- "version": "2.3.4",
3
+ "version": "2.4.0",
4
4
  "description": "Local Codex plugin for batch Agent evaluation and session trace tuning with evidence-backed issues, focused changes, verification and offline review.",
5
5
  "author": {
6
6
  "name": "hustyichi",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agent-tune-kit
3
- Version: 2.3.4
3
+ Version: 2.4.0
4
4
  Summary: Local Codex plugin for iterative Agent tuning with guided Skills, reusable runner templates, versioned results, and static validation.
5
5
  Project-URL: Homepage, https://github.com/hustyichi/agent-tune-kit
6
6
  Project-URL: Repository, https://github.com/hustyichi/agent-tune-kit
@@ -180,7 +180,7 @@ $atk-trace-optimize Implement the selected plan for ISSUE-001 in session <sessio
180
180
  $atk-trace-verify Verify the candidate for ISSUE-001 in session <session-id> and check relevant behavior that should still work.
181
181
  ```
182
182
 
183
- Without specified issues, diagnosis reviews all available session traces and works through existing and newly found anomalies, prioritizing causes directly related to project code, configuration, tool contracts, Prompt or Skill. Findings established as unrelated to the existing implementation may be skipped with an explanation. Findings with uncertain relevance remain open for investigation. Specified issues or concrete symptoms limit the investigation scope. You can start directly with diagnosis without a separate detection invocation.
183
+ Without specified issues, diagnosis reviews all available session traces and works through existing and newly found issues, prioritizing causes directly related to project code, configuration, tool contracts, Prompt or Skill. Findings established as unrelated to the existing implementation may be skipped with an explanation. Findings with uncertain relevance remain open for investigation. Specified issues or concrete symptoms limit the investigation scope. You can start directly with diagnosis without a separate detection invocation.
184
184
 
185
185
  Diagnoses and verification conclusions are saved per issue. If the evidence cannot establish which candidate loaded or whether key verification conditions were met, the verification outcome is `inconclusive`. Investigation results identify unread ranges and evidence gaps. As new issues surface, work through them individually or start another analysis with a new session trace.
186
186
 
@@ -196,6 +196,6 @@ Each session archive is stored under `.atk/traces/<session_id>/` in your Agent p
196
196
 
197
197
  [Trace tuning guide for source configuration, supported formats, and archive layout](docs/trace-tuning.md)
198
198
 
199
- [Multi-project attribution and filtering proposal (not yet implemented, Chinese)](docs/trace-project-attribution-design.md)
199
+ [Multi-project attribution and filtering details (Chinese)](docs/trace-project-attribution-design.md)
200
200
 
201
- Use `atk trace project` to register workspace projects and submodules. Issues can have multiple root-cause projects, filterable in the dashboard and session issue list. Repair details describe modification locations.
201
+ Use `atk trace project` to register workspace projects and submodules. Record associated projects with reasonable causal explanations for human review, and filter them in the dashboard and session issue list. Associations do not require a completed or verified fix; reasons describe uncertainty, and repair details describe modification locations.
@@ -166,7 +166,7 @@ $atk-trace-optimize Implement the selected plan for ISSUE-001 in session <sessio
166
166
  $atk-trace-verify Verify the candidate for ISSUE-001 in session <session-id> and check relevant behavior that should still work.
167
167
  ```
168
168
 
169
- Without specified issues, diagnosis reviews all available session traces and works through existing and newly found anomalies, prioritizing causes directly related to project code, configuration, tool contracts, Prompt or Skill. Findings established as unrelated to the existing implementation may be skipped with an explanation. Findings with uncertain relevance remain open for investigation. Specified issues or concrete symptoms limit the investigation scope. You can start directly with diagnosis without a separate detection invocation.
169
+ Without specified issues, diagnosis reviews all available session traces and works through existing and newly found issues, prioritizing causes directly related to project code, configuration, tool contracts, Prompt or Skill. Findings established as unrelated to the existing implementation may be skipped with an explanation. Findings with uncertain relevance remain open for investigation. Specified issues or concrete symptoms limit the investigation scope. You can start directly with diagnosis without a separate detection invocation.
170
170
 
171
171
  Diagnoses and verification conclusions are saved per issue. If the evidence cannot establish which candidate loaded or whether key verification conditions were met, the verification outcome is `inconclusive`. Investigation results identify unread ranges and evidence gaps. As new issues surface, work through them individually or start another analysis with a new session trace.
172
172
 
@@ -182,6 +182,6 @@ Each session archive is stored under `.atk/traces/<session_id>/` in your Agent p
182
182
 
183
183
  [Trace tuning guide for source configuration, supported formats, and archive layout](docs/trace-tuning.md)
184
184
 
185
- [Multi-project attribution and filtering proposal (not yet implemented, Chinese)](docs/trace-project-attribution-design.md)
185
+ [Multi-project attribution and filtering details (Chinese)](docs/trace-project-attribution-design.md)
186
186
 
187
- Use `atk trace project` to register workspace projects and submodules. Issues can have multiple root-cause projects, filterable in the dashboard and session issue list. Repair details describe modification locations.
187
+ Use `atk trace project` to register workspace projects and submodules. Record associated projects with reasonable causal explanations for human review, and filter them in the dashboard and session issue list. Associations do not require a completed or verified fix; reasons describe uncertainty, and repair details describe modification locations.
@@ -153,7 +153,7 @@ $atk-visualize-trace 打开 <session-id> 的执行泳道,从问题跳到相关
153
153
 
154
154
  采集、分析、诊断、修复和验证 Skill 在阶段结束后默认生成或更新 `.atk/traces/<session_id>/preview.html`,不自动打开浏览器。需要打开时使用 `$atk-visualize-trace`;已打开的页面在文件更新后需刷新。初始化没有会话轨迹,不生成空页面。
155
155
 
156
- 这些阶段同时刷新项目大盘 `.atk/traces/index.html`,按会话或异常分类查看全部会话的问题和实际进度,并可跳回各会话页。需要打开时发送 `$atk-visualize-trace 打开轨迹大盘`。早于分类功能的问题显示为“未分类”,对应会话重新分析时补上。
156
+ 这些阶段同时刷新项目大盘 `.atk/traces/index.html`,按会话或问题分类查看全部会话的问题和实际进度,并可跳回各会话页。需要打开时发送 `$atk-visualize-trace 打开轨迹大盘`。早于分类功能的问题显示为“未分类”,对应会话重新分析时补上。
157
157
 
158
158
  可用 Trace ID 定位会话内的证据,在问题详情中查看保留理由。分享 HTML 前请核对其中留存的正文。
159
159
 
@@ -166,7 +166,7 @@ $atk-trace-optimize 实施 <session-id> 的 ISSUE-001 已选定的方案。
166
166
  $atk-trace-verify 验证 <session-id> 的 ISSUE-001 对应候选,并检查相关正常行为。
167
167
  ```
168
168
 
169
- 未指定异常时,调查默认检查会话中可用的全部轨迹,逐项处理已记录和新发现的异常,优先定位与项目代码、配置、工具契约、Prompt 或 Skill 直接相关的原因。证据确认与现有实现无关的异常可以忽略,并说明理由。关联尚不明确的异常保留待查。指定异常或具体症状时,按指定范围调查。可以直接从调查开始,无需先单独执行检测。
169
+ 未指定问题时,调查默认检查会话中可用的全部轨迹,逐项处理已记录和新发现的问题,优先定位与项目代码、配置、工具契约、Prompt 或 Skill 直接相关的原因。证据确认与现有实现无关的问题可以忽略,并说明理由。关联尚不明确的问题保留待查。指定问题或具体症状时,按指定范围调查。可以直接从调查开始,无需先单独执行检测。
170
170
 
171
171
  诊断和验证结论分别按问题保存。证据不足以确认实际加载的候选或关键验证条件时,验证效果记为 `inconclusive`(无法判断)。调查结果会说明未检查的范围和证据缺口。后续发现新的问题,可继续按问题处理,或用新会话的轨迹开始下一次分析。
172
172
 
@@ -182,6 +182,6 @@ $atk-trace-verify 验证 <session-id> 的 ISSUE-001 对应候选,并检查相
182
182
 
183
183
  [轨迹调优指南,包含来源配置、支持格式和归档结构](docs/trace-tuning.md)
184
184
 
185
- [多工程关联与项目筛选方案(待实现)](docs/trace-project-attribution-design.md)
185
+ [多工程关联与项目筛选说明](docs/trace-project-attribution-design.md)
186
186
 
187
- 支持通过 `atk trace project` 登记工作区及子模块;诊断可记录多个根因项目,大盘与会话问题栏按根因项目筛选。修改位置在修复详情中说明。
187
+ 支持通过 `atk trace project` 登记工作区及子模块;诊断按合理的原因解释记录“关联项目”,供人工审核,大盘与会话问题栏均可筛选。关联不以修复完成或验证通过为前提;不确定性写在关联理由中,修改位置在修复详情中说明。
@@ -1,3 +1,3 @@
1
1
  """Agent Tune Kit package."""
2
2
 
3
- __version__ = "2.3.4"
3
+ __version__ = "2.4.0"
@@ -1,4 +1,4 @@
1
- """Workspace project registry and evidence-backed attribution."""
1
+ """Workspace project registry and issue associations for human review."""
2
2
 
3
3
  import configparser
4
4
  import hashlib
@@ -150,14 +150,12 @@ def validate_links(session_dir, links):
150
150
  projects = project_map(Path(session_dir).parent)
151
151
  seen = set()
152
152
  for link in links:
153
- if not isinstance(link, dict):
153
+ if not isinstance(link, dict) or set(link) - {"project_id", "reason", "evidence", "source_paths"}:
154
154
  raise UserActionRequired("Invalid project link.")
155
- key = (link.get("project_id"), link.get("role"))
156
- if not all(isinstance(k, str) for k in key) or key[0] not in projects or key in seen:
155
+ key = link.get("project_id")
156
+ if not isinstance(key, str) or key not in projects or key in seen:
157
157
  raise UserActionRequired("Unknown or duplicate project link.")
158
158
  seen.add(key)
159
- if key[1] not in {"root_cause", "improvement"} or link.get("evidence_state") not in {"hypothesis", "supported"}:
160
- raise UserActionRequired("Invalid project attribution state.")
161
159
  if (
162
160
  not isinstance(link.get("reason"), str)
163
161
  or not link["reason"].strip()
@@ -176,26 +174,84 @@ def validate_links(session_dir, links):
176
174
  return links
177
175
 
178
176
 
179
- def root_projects(root, issue):
180
- projects = project_map(root)
177
+ def _display_name(entry, project_id):
178
+ return entry.get("abbreviation") or entry.get("name") or project_id
179
+
180
+
181
+ def linked_projects(root, issue, projects=None):
182
+ """Return the display identity of each project an issue links to, once per project.
183
+
184
+ Pages only need the stable ID, the shown name and aliases for search; the rest of the registry stays out of them.
185
+ Pass ``projects`` (from ``project_map``) when resolving many issues so the registry is read once.
186
+ """
187
+ projects = project_map(root) if projects is None else projects
181
188
  result = []
182
189
  links = issue.get("project_links", [])
183
190
  if not isinstance(links, list):
184
191
  return result
192
+ seen = set()
185
193
  for link in links:
186
- if (
187
- not isinstance(link, dict)
188
- or not isinstance(link.get("project_id"), str)
189
- or link.get("role") != "root_cause"
190
- ):
194
+ if not isinstance(link, dict) or not isinstance(link.get("project_id"), str) or link["project_id"] in seen:
191
195
  continue
192
- entry = projects.get(link["project_id"], {})
196
+ project_id = link["project_id"]
197
+ seen.add(project_id)
198
+ entry = projects.get(project_id, {})
199
+ aliases = entry.get("aliases")
200
+ result.append(
201
+ {
202
+ "id": project_id,
203
+ "name": _display_name(entry, project_id),
204
+ "aliases": [alias for alias in aliases if isinstance(alias, str)] if isinstance(aliases, list) else [],
205
+ }
206
+ )
207
+ return result
208
+
209
+
210
+ def project_index(root, linked, projects=None):
211
+ """Summarize the projects that issues actually link to, for the pages' single-choice project filter.
212
+
213
+ ``linked`` yields ``(session_key, linked_projects)`` per issue. Registered projects without any linked issue are
214
+ left out: nothing could be found by choosing them. A linked ID missing from the registry stays in, shown by its ID,
215
+ so its issues remain reachable. Counts are per project; an issue linked to several projects counts once in each,
216
+ so the entries must not be added up as an issue total.
217
+ """
218
+ projects = project_map(root) if projects is None else projects
219
+ found = {}
220
+ for session, items in linked:
221
+ for item in items:
222
+ entry = found.setdefault(
223
+ item["id"], {"id": item["id"], "name": item["name"], "issues": 0, "sessions": set()}
224
+ )
225
+ entry["issues"] += 1
226
+ entry["sessions"].add(session)
227
+ names = {}
228
+ for entry in found.values():
229
+ names.setdefault(entry["name"], []).append(entry["id"])
230
+ result = []
231
+ for entry in found.values():
232
+ registered = projects.get(entry["id"])
233
+ name = entry["name"]
234
+ if len(names[name]) > 1:
235
+ # Two projects share an abbreviation: tell the filter's choices apart by where each one lives.
236
+ tail = Path(registered["path"]).name if registered and registered.get("path") else entry["id"]
237
+ name = f"{name} · {tail or entry['id']}"
193
238
  result.append(
194
239
  {
195
- **entry,
196
- "id": link["project_id"],
197
- "name": entry.get("abbreviation") or entry.get("name") or link["project_id"],
198
- "pending": link.get("evidence_state") != "supported",
240
+ "id": entry["id"],
241
+ "name": name,
242
+ "issues": entry["issues"],
243
+ "sessions": len(entry["sessions"]),
244
+ "registered": registered is not None,
245
+ "deprecated": bool(registered and registered.get("deprecated") is True),
199
246
  }
200
247
  )
248
+ result.sort(
249
+ key=lambda item: (
250
+ item["deprecated"],
251
+ not item["registered"],
252
+ -item["issues"],
253
+ item["name"].casefold(),
254
+ item["id"],
255
+ )
256
+ )
201
257
  return result
@@ -172,6 +172,7 @@ def prepare_issue(session_dir, data, *, dry_run=False):
172
172
  "created_at": now(),
173
173
  "status": "open",
174
174
  "segments": [],
175
+ "project_links": [],
175
176
  }
176
177
  )
177
178
  if "project_links" in data:
@@ -347,9 +348,10 @@ def save_diagnosis(session_dir, issue_id, text, diagnosis_id=None, expected_revi
347
348
  "description": issue["description"],
348
349
  "evidence": issue["evidence"],
349
350
  "segments": issue.get("segments", []),
351
+ "project_links": validate_links(directory, issue.get("project_links", [])),
350
352
  "created_at": now(),
351
353
  }
352
- for optional in ("selection_reason", "category", "project_links"):
354
+ for optional in ("selection_reason", "category"):
353
355
  if optional in issue:
354
356
  snapshot[optional] = issue[optional]
355
357
  if issue.get("project_links"):
@@ -720,7 +720,7 @@
720
720
  box.appendChild(el("p", { text: "导出后由 atk-dataset 导入生效;修改答案不会继承旧确认。" }));
721
721
  var feedback = el("textarea", {
722
722
  class: "review-note",
723
- placeholder: "仅异常项填写:用一句明确反馈描述预期结果或验收标准应如何调整…",
723
+ placeholder: "仅问题项填写:用一句明确反馈描述预期结果或验收标准应如何调整…",
724
724
  oninput: function (ev) {
725
725
  setFeedback(row, ev.target.value);
726
726
  renderMeta();
@@ -17,7 +17,7 @@
17
17
  input: "输入",
18
18
  expected: "期望",
19
19
  actual: "实际输出",
20
- reason: "异常原因",
20
+ reason: "问题原因",
21
21
  log: "日志",
22
22
  };
23
23
 
@@ -488,7 +488,7 @@
488
488
  var isAbnormal = ["true", "1", "yes", "y", "异常", "失败", "fail", "failed", "bad"].indexOf(value.toLowerCase()) >= 0;
489
489
  if (isAbnormal) {
490
490
  return el("div", { class: "cell-text" }, [
491
- el("span", { class: "badge issue", text: "● 异常" })
491
+ el("span", { class: "badge issue", text: "● 问题" })
492
492
  ]);
493
493
  } else if (value.toLowerCase() === "false") {
494
494
  return el("div", { class: "cell-text" }, [
@@ -567,7 +567,7 @@
567
567
  function openInspector(row) {
568
568
  state.selectedRowNumber = row.rowNumber;
569
569
  setText("inspector-row-badge", "#" + row.rowNumber);
570
- setText("inspector-title", "异常数据详情");
570
+ setText("inspector-title", "问题数据详情");
571
571
  setText("inspector-subtitle", "case " + rowId(row) + " · " + (roleField("reason") || "保留全部 failure_cases.csv 字段"));
572
572
  renderInspectorBody(row);
573
573
  if ($("inspector-overlay-pane")) $("inspector-overlay-pane").hidden = false;
@@ -717,8 +717,8 @@
717
717
 
718
718
  var reasonText = reasonField ? normalizeText(row.values[reasonField]) : "";
719
719
  var descBox = el("div", { class: "status-banner-desc-box" });
720
- var label = el("strong", { class: "status-banner-desc-label" }, ["异常原因描述:"]);
721
- var textVal = el("span", { class: "status-banner-desc-val", text: reasonText || "无异常原因描述" });
720
+ var label = el("strong", { class: "status-banner-desc-label" }, ["问题原因描述:"]);
721
+ var textVal = el("span", { class: "status-banner-desc-val", text: reasonText || "尚未记录问题原因" });
722
722
  descBox.appendChild(label);
723
723
  descBox.appendChild(textVal);
724
724
  content.appendChild(descBox);
@@ -873,14 +873,14 @@
873
873
  },
874
874
  }, [
875
875
  el("option", { value: "", text: "未审阅" }),
876
- el("option", { value: "confirmed_failure", text: "确认异常" }),
877
- el("option", { value: "false_positive", text: "误报/非异常" }),
876
+ el("option", { value: "confirmed_failure", text: "确认问题" }),
877
+ el("option", { value: "false_positive", text: "误报/无问题" }),
878
878
  el("option", { value: "needs_followup", text: "需继续分析" }),
879
879
  ]);
880
880
  select.value = getStatus(row);
881
881
  var note = el("textarea", {
882
882
  class: "review-note",
883
- placeholder: "审阅备注(可选):记录异常原因、修复建议或复核结论…",
883
+ placeholder: "审阅备注(可选):记录问题原因、修复建议或复核结论…",
884
884
  oninput: function (ev) {
885
885
  setNote(row, ev.target.value);
886
886
  renderMeta();
@@ -1248,7 +1248,7 @@
1248
1248
  }
1249
1249
  }, [
1250
1250
  el("span", { html: '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle;"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>' }),
1251
- "异常 (" + counts.abnormal + ")"
1251
+ "问题 (" + counts.abnormal + ")"
1252
1252
  ]);
1253
1253
 
1254
1254
  container.appendChild(allBtn);
@@ -63,7 +63,7 @@ __ATK_STYLES__
63
63
  </div>
64
64
 
65
65
  <div id="empty-state-all" class="empty-state" hidden>
66
- <strong>当前版本没有异常行</strong>
66
+ <strong>当前版本没有问题样本</strong>
67
67
  <span>No failure rows in current failure_cases.csv</span>
68
68
  </div>
69
69
  <div id="empty-state-filtered" class="empty-state" hidden>
@@ -132,7 +132,7 @@ __ATK_STYLES__
132
132
  </svg>
133
133
  </span>
134
134
  <div>
135
- <span class="stat-label">合并异常用例</span>
135
+ <span class="stat-label">合并问题用例</span>
136
136
  <strong id="stat-abnormal">0</strong>
137
137
  <span id="stat-abnormal-rate" class="stat-subvalue">失败率 0%</span>
138
138
  </div>
@@ -171,7 +171,7 @@ __ATK_STYLES__
171
171
  <div class="inspector-title-wrap">
172
172
  <span id="inspector-row-badge" class="row-badge">#</span>
173
173
  <div>
174
- <h2 id="inspector-title">异常数据详情</h2>
174
+ <h2 id="inspector-title">问题数据详情</h2>
175
175
  <p id="inspector-subtitle"></p>
176
176
  </div>
177
177
  </div>
@@ -11,6 +11,7 @@
11
11
  --tint: #fff4e9;
12
12
  --track: #537b8e;
13
13
  --drawer-width: 480px;
14
+ --control-height: 34px;
14
15
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
15
16
  --p-pending: #b7c4ce;
16
17
  --p-diagnosed: #d8892f;
@@ -37,7 +38,7 @@ h3 { font-size: 14px }
37
38
  .topbar { background: white; border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 5; flex-shrink: 0 }
38
39
  .topbar-inner { max-width: none; margin: 0; padding-inline: clamp(12px, 2vw, 24px); min-height: 52px; display: flex; align-items: center; justify-content: space-between; gap: 16px }
39
40
  .brand-line, .topbar-meta { display: flex; align-items: center; gap: 10px }
40
- .brand-line { min-width: 0 }
41
+ .brand-line { min-width: 0; max-width: 100% }
41
42
  .brand { background: var(--brand); color: #fff; border-radius: 6px; padding: 2px 6px; font-weight: 850; letter-spacing: -.04em }
42
43
  .brand-line strong { white-space: nowrap }
43
44
  .session-id { border-left: 1px solid var(--line); padding-left: 12px; color: var(--muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
@@ -62,15 +63,16 @@ h3 { font-size: 14px }
62
63
  .progress-dot.excluded { background: transparent; box-shadow: inset 0 0 0 1.5px var(--p-pending) }
63
64
  .category-tag { display: inline-block; max-width: 100%; background: #fff8f1; color: var(--accent); font-size: 11px; line-height: 1.5; padding: 2px 6px; border-radius: 4px; text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
64
65
  a.category-tag:hover { background: #ffe8d2 }
65
- select {
66
- display: block; height: 34px; max-width: 100%; padding: 0 11px;
66
+ input:not([type=checkbox]), select {
67
+ display: block; height: var(--control-height); min-width: 0; max-width: 100%; padding: 0 11px;
67
68
  font-size: 13px; line-height: normal; border-color: #cdd8e1;
68
69
  }
69
70
  select {
70
71
  appearance: none; padding-right: 32px; text-overflow: ellipsis;
71
72
  background: white url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e") no-repeat right 11px center / 14px;
72
73
  }
73
- select:hover { border-color: #9baebb }
74
+ input:not([type=checkbox]):hover, select:hover { border-color: #9baebb }
75
+ input[type=checkbox] { width: 16px; height: 16px; margin: 0; padding: 0; flex-shrink: 0; accent-color: var(--brand) }
74
76
  @media (forced-colors: active) {
75
77
  select { appearance: auto; background-image: none; padding-right: 8px }
76
78
  }
@@ -89,16 +91,8 @@ select:hover { border-color: #9baebb }
89
91
  @media(max-width:800px) {
90
92
  .topbar-inner { align-items: flex-start; flex-direction: column; gap: 4px; padding-top: 8px; padding-bottom: 8px }
91
93
  h1 { font-size: 18px }
92
- .drawer { inset: auto 0 0; width: 100% !important; height: 48vh; height: 48dvh; border-radius: 12px 12px 0 0; border-left: 0; border-top: 1px solid var(--line) }
94
+ .drawer { inset: auto 0 0; width: 100% !important; max-width: 100%; height: 48vh; height: 48dvh; border-radius: 12px 12px 0 0; border-left: 0; border-top: 1px solid var(--line) }
93
95
  .drawer.above-record { inset: 0 0 auto; border-radius: 0 0 12px 12px; border-top: 0; border-bottom: 1px solid var(--line) }
94
96
  .drawer-resizer { display: none }
95
97
  }
96
98
 
97
- /* Project attribution belongs to issues; the menu is shared by both issue views. */
98
- .project-choice { position: relative; margin-bottom: 7px; font-size: 13px }
99
- .project-choice summary { height: 34px; padding: 6px 12px; border: 1px solid #cdd8e1; border-radius: 6px; background: white }
100
- .project-choice summary:hover { border-color: #9baebb }
101
- .project-menu { position: absolute; right: 0; z-index: 20; width: min(300px, 80vw); max-height: 320px; overflow: auto; padding: 12px; border: 1px solid var(--line); border-radius: 6px; background: white; box-shadow: 0 6px 20px #0002 }
102
- .project-menu p { margin: 0 0 8px }
103
- #project-filter label { display: flex; align-items: center; gap: 8px; padding: 6px 0 }
104
- #project-filter input { width: 16px; height: 16px; min-width: 16px; padding: 0 }