@agentwhy/cli 0.0.0-dev

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 (400) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +2 -0
  3. package/README.md +181 -0
  4. package/THIRD_PARTY_NOTICES.md +31 -0
  5. package/dist/adapter/claude-code/contract/assumptions.js +208 -0
  6. package/dist/adapter/claude-code/contract/denials.js +15 -0
  7. package/dist/adapter/claude-code/contract/entry-points.js +15 -0
  8. package/dist/adapter/claude-code/contract/fields.js +73 -0
  9. package/dist/adapter/claude-code/contract/hooks.js +96 -0
  10. package/dist/adapter/claude-code/contract/identifiers.js +15 -0
  11. package/dist/adapter/claude-code/contract/layout.js +29 -0
  12. package/dist/adapter/claude-code/contract/line-types.js +26 -0
  13. package/dist/adapter/claude-code/contract/projects.js +23 -0
  14. package/dist/adapter/claude-code/contract/recognition.js +14 -0
  15. package/dist/adapter/claude-code/contract/session-title.js +20 -0
  16. package/dist/adapter/claude-code/contract/settings.js +27 -0
  17. package/dist/adapter/claude-code/contract/task-notifications.js +33 -0
  18. package/dist/adapter/claude-code/contract/tools.js +37 -0
  19. package/dist/adapter/claude-code/contract/version.js +51 -0
  20. package/dist/adapter/claude-code/discovery/claude-code-project-catalogue.js +129 -0
  21. package/dist/adapter/claude-code/discovery/claude-code-recognition.js +46 -0
  22. package/dist/adapter/claude-code/discovery/claude-code-session-catalogue.js +100 -0
  23. package/dist/adapter/claude-code/discovery/claude-code-session-discovery.js +61 -0
  24. package/dist/adapter/claude-code/discovery/claude-code-session-titles.js +28 -0
  25. package/dist/adapter/claude-code/discovery/discovered-session.js +1 -0
  26. package/dist/adapter/claude-code/discovery/session-entries.js +41 -0
  27. package/dist/adapter/claude-code/discovery/transcript-tail.js +81 -0
  28. package/dist/adapter/claude-code/events/claude-code-session-source.js +197 -0
  29. package/dist/adapter/claude-code/events/delegation-index.js +15 -0
  30. package/dist/adapter/claude-code/events/transcript-scan.js +179 -0
  31. package/dist/adapter/claude-code/hooks/hook-output.js +42 -0
  32. package/dist/adapter/claude-code/hooks/pre-tool-use-input.js +23 -0
  33. package/dist/adapter/claude-code/hooks/stop-input.js +25 -0
  34. package/dist/adapter/claude-code/hooks/subagent-stop-input.js +26 -0
  35. package/dist/adapter/claude-code/policy/deny-rules.js +46 -0
  36. package/dist/adapter/claude-code/probe/claude-code-probe.js +86 -0
  37. package/dist/adapter/claude-code/probe/collectors/agent-tool-input-key-collector.js +24 -0
  38. package/dist/adapter/claude-code/probe/collectors/denial-kind-collector.js +20 -0
  39. package/dist/adapter/claude-code/probe/collectors/denied-call-collector.js +11 -0
  40. package/dist/adapter/claude-code/probe/collectors/identifier-collector.js +19 -0
  41. package/dist/adapter/claude-code/probe/collectors/line-collector.js +1 -0
  42. package/dist/adapter/claude-code/probe/collectors/line-type-collector.js +29 -0
  43. package/dist/adapter/claude-code/probe/collectors/sidechain-collector.js +20 -0
  44. package/dist/adapter/claude-code/probe/collectors/task-notification-collector.js +51 -0
  45. package/dist/adapter/claude-code/probe/collectors/tool-result-reference-collector.js +31 -0
  46. package/dist/adapter/claude-code/probe/collectors/tool-use-collector.js +24 -0
  47. package/dist/adapter/claude-code/probe/collectors/tool-version-collector.js +14 -0
  48. package/dist/adapter/claude-code/probe/collectors/top-level-key-collector.js +14 -0
  49. package/dist/adapter/claude-code/probe/collectors/unknown-line-type-key-collector.js +24 -0
  50. package/dist/adapter/claude-code/probe/collectors/working-directory-collector.js +28 -0
  51. package/dist/adapter/claude-code/probe/doctor-report.js +1 -0
  52. package/dist/adapter/claude-code/probe/meta-tally.js +42 -0
  53. package/dist/adapter/claude-code/probe/session-probe.js +1 -0
  54. package/dist/adapter/claude-code/probe/session-tally.js +41 -0
  55. package/dist/adapter/claude-code/probe/transcript-line.js +30 -0
  56. package/dist/adapter/claude-code/probe/transcript-tally.js +74 -0
  57. package/dist/adapter/claude-code/settings/deny-entries.js +65 -0
  58. package/dist/adapter/claude-code/settings/hook-entries.js +303 -0
  59. package/dist/adapter/codex/contract/actions.js +69 -0
  60. package/dist/adapter/codex/contract/assumptions.js +55 -0
  61. package/dist/adapter/codex/contract/capabilities.js +24 -0
  62. package/dist/adapter/codex/contract/delegations.js +30 -0
  63. package/dist/adapter/codex/contract/deliveries.js +25 -0
  64. package/dist/adapter/codex/contract/envelope.js +33 -0
  65. package/dist/adapter/codex/contract/hook-refusals.js +14 -0
  66. package/dist/adapter/codex/contract/hooks.js +46 -0
  67. package/dist/adapter/codex/contract/messages.js +47 -0
  68. package/dist/adapter/codex/contract/permissions.js +27 -0
  69. package/dist/adapter/codex/contract/reviews.js +13 -0
  70. package/dist/adapter/codex/contract/session.js +31 -0
  71. package/dist/adapter/codex/contract/turns.js +23 -0
  72. package/dist/adapter/codex/contract/version.js +15 -0
  73. package/dist/adapter/codex/discovery/codex-conversations.js +44 -0
  74. package/dist/adapter/codex/discovery/codex-project-catalogue.js +49 -0
  75. package/dist/adapter/codex/discovery/codex-recognition.js +20 -0
  76. package/dist/adapter/codex/discovery/codex-session-catalogue.js +28 -0
  77. package/dist/adapter/codex/discovery/codex-session-discovery.js +115 -0
  78. package/dist/adapter/codex/discovery/codex-session-index.js +21 -0
  79. package/dist/adapter/codex/discovery/codex-session-titles.js +135 -0
  80. package/dist/adapter/codex/discovery/session-header.js +86 -0
  81. package/dist/adapter/codex/discovery/session-owners.js +11 -0
  82. package/dist/adapter/codex/discovery/session-roots.js +49 -0
  83. package/dist/adapter/codex/events/action-items.js +138 -0
  84. package/dist/adapter/codex/events/capability-records.js +26 -0
  85. package/dist/adapter/codex/events/codex-session-source.js +121 -0
  86. package/dist/adapter/codex/events/hook-refusals.js +27 -0
  87. package/dist/adapter/codex/events/rollout-scan.js +614 -0
  88. package/dist/adapter/codex/events/turn-permissions.js +60 -0
  89. package/dist/adapter/codex/hooks/pre-tool-use-input.js +24 -0
  90. package/dist/adapter/codex/hooks/stop-refusals.js +57 -0
  91. package/dist/adapter/codex/probe/codex-doctor-report.js +1 -0
  92. package/dist/adapter/codex/probe/codex-probe.js +268 -0
  93. package/dist/adapter/codex/settings/codex-hooks.js +83 -0
  94. package/dist/cli/cli-command.js +1 -0
  95. package/dist/cli/command-router.js +42 -0
  96. package/dist/cli/commands/check-cli-command.js +128 -0
  97. package/dist/cli/commands/codex-stop-cli-command.js +27 -0
  98. package/dist/cli/commands/doctor-arguments.js +32 -0
  99. package/dist/cli/commands/doctor-cli-command.js +31 -0
  100. package/dist/cli/commands/doctor-usage.js +14 -0
  101. package/dist/cli/commands/init-cli-command.js +123 -0
  102. package/dist/cli/commands/menu-cli-command.js +58 -0
  103. package/dist/cli/commands/notify-cli-command.js +158 -0
  104. package/dist/cli/commands/refuse-cli-command.js +79 -0
  105. package/dist/cli/commands/report-arguments.js +62 -0
  106. package/dist/cli/commands/report-cli-command.js +36 -0
  107. package/dist/cli/commands/report-usage.js +41 -0
  108. package/dist/cli/commands/sessions-cli-command.js +184 -0
  109. package/dist/cli/commands/start-cli-command.js +83 -0
  110. package/dist/cli/commands/watch-cli-command.js +142 -0
  111. package/dist/cli/exit-codes.js +13 -0
  112. package/dist/cli/project-switches.js +46 -0
  113. package/dist/cli.js +80 -0
  114. package/dist/composition-root.js +411 -0
  115. package/dist/core/access/command-line.js +454 -0
  116. package/dist/core/access/listing.js +58 -0
  117. package/dist/core/access/path-shape.js +59 -0
  118. package/dist/core/access/path-tokens.js +37 -0
  119. package/dist/core/access/protected-access.js +310 -0
  120. package/dist/core/access/protected-values.js +102 -0
  121. package/dist/core/access/recorded-effect.js +67 -0
  122. package/dist/core/access/returns.js +173 -0
  123. package/dist/core/access/search-output.js +34 -0
  124. package/dist/core/access/search-reach.js +268 -0
  125. package/dist/core/access/uses.js +143 -0
  126. package/dist/core/access/words-before.js +52 -0
  127. package/dist/core/agent.js +1 -0
  128. package/dist/core/capability.js +11 -0
  129. package/dist/core/combined-project-catalogue.js +36 -0
  130. package/dist/core/combined-session-catalogue.js +25 -0
  131. package/dist/core/completeness.js +10 -0
  132. package/dist/core/context.js +1 -0
  133. package/dist/core/correlation/correlate.js +329 -0
  134. package/dist/core/delegation.js +1 -0
  135. package/dist/core/detector/prompt-signals.js +78 -0
  136. package/dist/core/entry-point.js +1 -0
  137. package/dist/core/event.js +1 -0
  138. package/dist/core/evidence.js +9 -0
  139. package/dist/core/late-message.js +32 -0
  140. package/dist/core/message.js +1 -0
  141. package/dist/core/nearest-project.js +28 -0
  142. package/dist/core/policy/default-policy.js +32 -0
  143. package/dist/core/policy/glob.js +56 -0
  144. package/dist/core/policy/parse-policy.js +70 -0
  145. package/dist/core/policy/policy.js +20 -0
  146. package/dist/core/policy/resolve-policy.js +16 -0
  147. package/dist/core/project-catalogue.js +1 -0
  148. package/dist/core/project-root.js +133 -0
  149. package/dist/core/provider-titles.js +10 -0
  150. package/dist/core/redaction/entropy.js +46 -0
  151. package/dist/core/redaction/redacted.js +4 -0
  152. package/dist/core/redaction/redactor.js +339 -0
  153. package/dist/core/redaction/secret-patterns.js +22 -0
  154. package/dist/core/redaction/value-shapes.js +81 -0
  155. package/dist/core/redaction/value-trace.js +110 -0
  156. package/dist/core/review.js +1 -0
  157. package/dist/core/session-catalogue.js +19 -0
  158. package/dist/core/session-filter.js +42 -0
  159. package/dist/core/session-format.js +27 -0
  160. package/dist/core/session-model.js +1 -0
  161. package/dist/core/session-reader.js +22 -0
  162. package/dist/core/session-records.js +1 -0
  163. package/dist/core/session-source.js +1 -0
  164. package/dist/core/session-titles.js +21 -0
  165. package/dist/core/turn.js +1 -0
  166. package/dist/doctor/codex-doctor.js +14 -0
  167. package/dist/doctor/doctor-use-case.js +1 -0
  168. package/dist/doctor/format-selecting-doctor.js +28 -0
  169. package/dist/doctor/render/attention/attention-rule.js +1 -0
  170. package/dist/doctor/render/attention/doctor-attention-rules.js +28 -0
  171. package/dist/doctor/render/attention/rules/damaged-meta-files-rule.js +8 -0
  172. package/dist/doctor/render/attention/rules/damaged-transcripts-rule.js +9 -0
  173. package/dist/doctor/render/attention/rules/incomplete-subagent-pairs-rule.js +6 -0
  174. package/dist/doctor/render/attention/rules/missing-main-transcript-rule.js +5 -0
  175. package/dist/doctor/render/attention/rules/missing-spilled-results-rule.js +6 -0
  176. package/dist/doctor/render/attention/rules/multiple-working-directories-rule.js +15 -0
  177. package/dist/doctor/render/attention/rules/unknown-denial-kinds-rule.js +5 -0
  178. package/dist/doctor/render/attention/rules/unknown-line-types-rule.js +6 -0
  179. package/dist/doctor/render/attention/rules/unrecognised-entries-rule.js +6 -0
  180. package/dist/doctor/render/attention/rules/unusable-directories-rule.js +12 -0
  181. package/dist/doctor/render/attention/transcript-scopes.js +6 -0
  182. package/dist/doctor/render/codex-text-doctor-renderer.js +97 -0
  183. package/dist/doctor/render/doctor-renderers.js +1 -0
  184. package/dist/doctor/render/json-doctor-renderer.js +7 -0
  185. package/dist/doctor/render/output-format.js +1 -0
  186. package/dist/doctor/render/text-doctor-renderer.js +124 -0
  187. package/dist/doctor/session-doctor.js +16 -0
  188. package/dist/infrastructure/clack-asker.js +24 -0
  189. package/dist/infrastructure/clack-chooser.js +40 -0
  190. package/dist/infrastructure/clack-multi-chooser.js +31 -0
  191. package/dist/infrastructure/file-alert-store.js +120 -0
  192. package/dist/infrastructure/file-checked-store.js +55 -0
  193. package/dist/infrastructure/file-mark-store.js +67 -0
  194. package/dist/infrastructure/file-onboarding-store.js +93 -0
  195. package/dist/infrastructure/folder-window.js +26 -0
  196. package/dist/infrastructure/node-agentwhy-invocation.js +99 -0
  197. package/dist/infrastructure/node-browser.js +40 -0
  198. package/dist/infrastructure/node-file-system.js +111 -0
  199. package/dist/infrastructure/node-local-server.js +115 -0
  200. package/dist/infrastructure/node-text-input.js +26 -0
  201. package/dist/infrastructure/os-notifier.js +21 -0
  202. package/dist/infrastructure/osascript-folder-chooser.js +53 -0
  203. package/dist/infrastructure/powershell-folder-chooser.js +78 -0
  204. package/dist/infrastructure/real-directory.js +18 -0
  205. package/dist/infrastructure/stream-printer.js +11 -0
  206. package/dist/infrastructure/terminal-banner.js +19 -0
  207. package/dist/ports/agentwhy-invocation.js +1 -0
  208. package/dist/ports/alert-store.js +1 -0
  209. package/dist/ports/asker.js +1 -0
  210. package/dist/ports/browser.js +1 -0
  211. package/dist/ports/checked-store.js +1 -0
  212. package/dist/ports/chooser.js +1 -0
  213. package/dist/ports/directory-reader.js +1 -0
  214. package/dist/ports/file-access-error.js +11 -0
  215. package/dist/ports/file-reader.js +1 -0
  216. package/dist/ports/file-tail-reader.js +1 -0
  217. package/dist/ports/file-writer.js +1 -0
  218. package/dist/ports/folder-chooser.js +1 -0
  219. package/dist/ports/local-server.js +1 -0
  220. package/dist/ports/mark-store.js +10 -0
  221. package/dist/ports/multi-chooser.js +1 -0
  222. package/dist/ports/notifier.js +1 -0
  223. package/dist/ports/onboarding-store.js +1 -0
  224. package/dist/ports/printer.js +1 -0
  225. package/dist/ports/text-input.js +1 -0
  226. package/dist/refuse/command-reach.js +135 -0
  227. package/dist/refuse/command-refusal.js +88 -0
  228. package/dist/refuse/render/codex-stop-words.js +21 -0
  229. package/dist/refuse/render/refusal-words.js +34 -0
  230. package/dist/report/build-report.js +1037 -0
  231. package/dist/report/check/actions-digest.js +73 -0
  232. package/dist/report/check/check-lines.js +83 -0
  233. package/dist/report/check/mark-request.js +90 -0
  234. package/dist/report/check/marks.js +84 -0
  235. package/dist/report/check/render/text-digest-renderer.js +332 -0
  236. package/dist/report/check/session-actions.js +90 -0
  237. package/dist/report/check/session-check.js +91 -0
  238. package/dist/report/choose-policy.js +61 -0
  239. package/dist/report/flow-reads.js +18 -0
  240. package/dist/report/private-files/tell-lists.js +84 -0
  241. package/dist/report/project-rules.js +33 -0
  242. package/dist/report/render/home-relative.js +18 -0
  243. package/dist/report/render/html-head.js +26 -0
  244. package/dist/report/render/html-report-components.js +48 -0
  245. package/dist/report/render/html-report-styles.js +500 -0
  246. package/dist/report/render/html-sidebar.js +42 -0
  247. package/dist/report/render/path-tail.js +14 -0
  248. package/dist/report/render/report-copy.js +1177 -0
  249. package/dist/report/render/report-page/advanced-view.js +167 -0
  250. package/dist/report/render/report-page/file-story.js +114 -0
  251. package/dist/report/render/report-page/files-view.js +381 -0
  252. package/dist/report/render/report-page/files.js +77 -0
  253. package/dist/report/render/report-page/fix-wizard-script.js +269 -0
  254. package/dist/report/render/report-page/fix-wizard.js +310 -0
  255. package/dist/report/render/report-page/helpers-view.js +383 -0
  256. package/dist/report/render/report-page/helpers.js +51 -0
  257. package/dist/report/render/report-page/item-names.js +63 -0
  258. package/dist/report/render/report-page/protect-patterns.js +13 -0
  259. package/dist/report/render/report-page/providers.js +208 -0
  260. package/dist/report/render/report-page/record-view.js +367 -0
  261. package/dist/report/render/report-page/report-page-renderer.js +129 -0
  262. package/dist/report/render/report-page/report-views.js +31 -0
  263. package/dist/report/render/report-page/story-window.js +356 -0
  264. package/dist/report/render/report-page/times.js +25 -0
  265. package/dist/report/render/report-page/to-do-view.js +299 -0
  266. package/dist/report/render/report-page/to-do.js +152 -0
  267. package/dist/report/render/report-page.js +1 -0
  268. package/dist/report/render/session-view.js +250 -0
  269. package/dist/report/render/text-report-renderer.js +981 -0
  270. package/dist/report/render/ui/add-file-popup.js +122 -0
  271. package/dist/report/render/ui/app-sidebar.js +78 -0
  272. package/dist/report/render/ui/ask-panel.js +80 -0
  273. package/dist/report/render/ui/avatar.js +19 -0
  274. package/dist/report/render/ui/backdrop.js +29 -0
  275. package/dist/report/render/ui/brand-mark.js +4 -0
  276. package/dist/report/render/ui/button.js +67 -0
  277. package/dist/report/render/ui/callout.js +20 -0
  278. package/dist/report/render/ui/chat-example.js +17 -0
  279. package/dist/report/render/ui/checklist.js +50 -0
  280. package/dist/report/render/ui/confirm-dialog.js +34 -0
  281. package/dist/report/render/ui/data-table.js +49 -0
  282. package/dist/report/render/ui/drawer.js +25 -0
  283. package/dist/report/render/ui/file-chip.js +37 -0
  284. package/dist/report/render/ui/fold-line.js +22 -0
  285. package/dist/report/render/ui/guide-card.js +25 -0
  286. package/dist/report/render/ui/hero.js +37 -0
  287. package/dist/report/render/ui/labelled-select.js +10 -0
  288. package/dist/report/render/ui/live-script.js +222 -0
  289. package/dist/report/render/ui/local-date.js +58 -0
  290. package/dist/report/render/ui/mode-icon.js +6 -0
  291. package/dist/report/render/ui/page-shell.js +101 -0
  292. package/dist/report/render/ui/pill-tabs.js +47 -0
  293. package/dist/report/render/ui/popup.js +77 -0
  294. package/dist/report/render/ui/progress.js +35 -0
  295. package/dist/report/render/ui/project-list.js +284 -0
  296. package/dist/report/render/ui/scope-choice.js +19 -0
  297. package/dist/report/render/ui/stats.js +21 -0
  298. package/dist/report/render/ui/status-icon.js +30 -0
  299. package/dist/report/render/ui/status-look.js +21 -0
  300. package/dist/report/render/ui/switch.js +11 -0
  301. package/dist/report/render/ui/tag.js +19 -0
  302. package/dist/report/render/ui/task-list.js +56 -0
  303. package/dist/report/render/ui/tokens.js +46 -0
  304. package/dist/report/render/ui/update-notice.js +146 -0
  305. package/dist/report/render/ui/words/app-words.js +163 -0
  306. package/dist/report/render/ui/words/conversations-words.js +457 -0
  307. package/dist/report/render/ui/words/month-words.js +59 -0
  308. package/dist/report/render/ui/words/onboarding-words.js +446 -0
  309. package/dist/report/render/ui/words/projects-words.js +217 -0
  310. package/dist/report/render/ui/words/report-words.js +2099 -0
  311. package/dist/report/render/ui/words/settings-words.js +611 -0
  312. package/dist/report/render/ui/words/to-fix-words.js +287 -0
  313. package/dist/report/report-model.js +2 -0
  314. package/dist/report/report-use-case.js +1 -0
  315. package/dist/report/rule-names.js +20 -0
  316. package/dist/report/session-report.js +163 -0
  317. package/dist/report/start/app-nav.js +37 -0
  318. package/dist/report/start/conversations/calendar-view.js +104 -0
  319. package/dist/report/start/conversations/conversation-columns.js +187 -0
  320. package/dist/report/start/conversations/conversations-renderer.js +54 -0
  321. package/dist/report/start/conversations/empty-week.js +120 -0
  322. package/dist/report/start/conversations/files-window.js +166 -0
  323. package/dist/report/start/conversations/period-section.js +280 -0
  324. package/dist/report/start/conversations/periods-script.js +440 -0
  325. package/dist/report/start/conversations/periods.js +110 -0
  326. package/dist/report/start/conversations/week-view.js +30 -0
  327. package/dist/report/start/conversations/weeks.js +17 -0
  328. package/dist/report/start/month/month-renderer.js +50 -0
  329. package/dist/report/start/month/month-view.js +135 -0
  330. package/dist/report/start/month/months.js +17 -0
  331. package/dist/report/start/onboarding/done.js +171 -0
  332. package/dist/report/start/onboarding/finish-onboarding.js +93 -0
  333. package/dist/report/start/onboarding/intro.js +100 -0
  334. package/dist/report/start/onboarding/onboarding-changes.js +40 -0
  335. package/dist/report/start/onboarding/onboarding-renderer.js +195 -0
  336. package/dist/report/start/onboarding/onboarding-script.js +400 -0
  337. package/dist/report/start/onboarding/onboarding-view.js +98 -0
  338. package/dist/report/start/onboarding/project-step.js +210 -0
  339. package/dist/report/start/onboarding/steps.js +239 -0
  340. package/dist/report/start/onboarding/welcome.js +66 -0
  341. package/dist/report/start/page-notice.js +10 -0
  342. package/dist/report/start/projects/index-projects.js +43 -0
  343. package/dist/report/start/projects/moved-page.js +82 -0
  344. package/dist/report/start/projects/project-switch.js +138 -0
  345. package/dist/report/start/projects/projects-window.js +67 -0
  346. package/dist/report/start/projects/temporary-space.js +18 -0
  347. package/dist/report/start/render/air-datepicker-vendor.js +27 -0
  348. package/dist/report/start/render/session-status.js +41 -0
  349. package/dist/report/start/render/start-words.js +84 -0
  350. package/dist/report/start/repository.js +28 -0
  351. package/dist/report/start/serve/index-handler.js +372 -0
  352. package/dist/report/start/serve/onboarding-request.js +50 -0
  353. package/dist/report/start/serve/settings-request.js +1 -0
  354. package/dist/report/start/serve/settings-setup.js +193 -0
  355. package/dist/report/start/session-index.js +1 -0
  356. package/dist/report/start/session-start.js +974 -0
  357. package/dist/report/start/settings/alerts-tab.js +104 -0
  358. package/dist/report/start/settings/files-tab.js +169 -0
  359. package/dist/report/start/settings/general-tab.js +71 -0
  360. package/dist/report/start/settings/settings-renderer.js +254 -0
  361. package/dist/report/start/settings/settings-script.js +161 -0
  362. package/dist/report/start/settings/settings-view.js +240 -0
  363. package/dist/report/start/settings/settings-windows.js +334 -0
  364. package/dist/report/start/settings-files.js +43 -0
  365. package/dist/report/start/to-fix/done-list.js +45 -0
  366. package/dist/report/start/to-fix/file-window.js +110 -0
  367. package/dist/report/start/to-fix/to-fix-list.js +70 -0
  368. package/dist/report/start/to-fix/to-fix-renderer.js +237 -0
  369. package/dist/report/start/to-fix/to-fix-script.js +94 -0
  370. package/dist/report/start/to-fix/to-fix-view.js +124 -0
  371. package/dist/report/watch/agent-alert.js +72 -0
  372. package/dist/report/watch/notice-choices.js +35 -0
  373. package/dist/report/watch/notice-settings.js +65 -0
  374. package/dist/report/watch/preferences.js +100 -0
  375. package/dist/report/watch/render/instruction-words.js +54 -0
  376. package/dist/report/watch/render/notice-words.js +182 -0
  377. package/dist/report/watch/subagent-watch.js +345 -0
  378. package/dist/report/watch/watch-notice.js +1 -0
  379. package/dist/setup/behind.js +18 -0
  380. package/dist/setup/codex-mirror.js +171 -0
  381. package/dist/setup/not-a-project.js +19 -0
  382. package/dist/setup/project-setup.js +644 -0
  383. package/dist/setup/protected-patterns.js +30 -0
  384. package/dist/shared/colour.js +23 -0
  385. package/dist/shared/compare.js +4 -0
  386. package/dist/shared/content-version.js +13 -0
  387. package/dist/shared/counter.js +11 -0
  388. package/dist/shared/file-stamp.js +4 -0
  389. package/dist/shared/json.js +13 -0
  390. package/dist/shared/label.js +13 -0
  391. package/dist/shared/package-name.js +6 -0
  392. package/dist/shared/plain-invocation.js +44 -0
  393. package/dist/shared/plain-version.js +21 -0
  394. package/dist/shared/printable.js +25 -0
  395. package/dist/shared/renderer.js +1 -0
  396. package/dist/shared/sentence.js +20 -0
  397. package/dist/shared/terminal-logo.js +41 -0
  398. package/dist/shared/text-table.js +15 -0
  399. package/dist/shared/wrap.js +29 -0
  400. package/package.json +70 -0
@@ -0,0 +1,287 @@
1
+ /**
2
+ * The words of the To fix page (`.ai/specs/2026-09-23-to-fix.md`), in the glossary of the design guidelines §7. The
3
+ * developer details keep the tool's own words (T16). A file's name in words is Settings' (`set.rule.*`, T6).
4
+ */
5
+ export const TO_FIX_WORDS = {
6
+ en: {
7
+ 'fix.title': 'To fix · agentwhy',
8
+ 'fix.range': 'Last {range} · {dates}',
9
+ 'fix.range.since': 'Since {dates}',
10
+ 'fix.span.h.one': 'hour', 'fix.span.h.other': '{n} hours',
11
+ 'fix.span.d.one': 'day', 'fix.span.d.other': '{n} days',
12
+ 'fix.span.w.one': 'week', 'fix.span.w.other': '{n} weeks',
13
+ 'fix.hero.count.one': '1 file to fix.',
14
+ 'fix.hero.count.other': '{n} files to fix.',
15
+ 'fix.hero.none': 'Nothing left to fix.',
16
+ 'fix.hero.keys.one': 'Start with the 1 with real keys.',
17
+ 'fix.hero.keys.other': 'Start with the {n} with real keys.',
18
+ 'fix.hero.look': 'Just a quick look left.',
19
+ 'fix.hero.nice': 'Nice work.',
20
+ 'fix.lead': 'Your AI saw what’s inside these files. Change the keys in them, then tick them off here.',
21
+ 'fix.tab.todo': 'To fix',
22
+ 'fix.tab.done': 'Done',
23
+ 'fix.stopped.one': 'Your protection worked: 1 try was stopped.',
24
+ 'fix.stopped.other': 'Your protection worked: {n} tries were stopped.',
25
+ 'fix.marksUnreadable': 'Your record of what you fixed couldn’t be read, so nothing was left off this list because of it.',
26
+ 'fix.keys': 'Change these keys',
27
+ 'fix.keys.lead': 'Your AI read the real keys inside. Make new ones.',
28
+ 'fix.keys.go': 'Fix it →',
29
+ 'fix.look': 'Take a quick look',
30
+ 'fix.look.lead': 'These are sample files. If they hold real keys, change them. If not, tick them off.',
31
+ 'fix.look.go': 'Check it',
32
+ 'fix.back': 'Back again',
33
+ 'fix.in.one': 'in 1 conversation',
34
+ 'fix.in.other': 'in {n} conversations',
35
+ 'fix.private': 'A private file',
36
+ 'fix.seen.one': '<strong>1 file — nothing to do.</strong> <span class="tf-soft">Your AI only saw its name, never what’s inside.</span>',
37
+ 'fix.seen.other': '<strong>{n} files — nothing to do.</strong> <span class="tf-soft">Your AI only saw their names, never what’s inside.</span>',
38
+ 'fix.seen.label': 'Only saw the name',
39
+ 'fix.empty': 'Your AI didn’t read anything private that is still to fix.',
40
+ 'fix.done.lead': 'If your AI reads one of these again, it comes back to your list.',
41
+ 'fix.done.none': 'Nothing marked yet. When you fix a file, it shows up here.',
42
+ 'fix.done.fixed': '✓ Fixed {when}',
43
+ 'fix.done.undo': 'Undo',
44
+ 'fix.undo.title': 'Put this back on your list?',
45
+ 'fix.undo.text': 'It goes back to To fix, as if you had never ticked it off.',
46
+ 'fix.undo.go': 'Put it back',
47
+ 'fix.today': 'today',
48
+ 'fix.yesterday': 'yesterday',
49
+ 'fix.day.today': 'Today',
50
+ 'fix.day.yesterday': 'Yesterday',
51
+ 'fix.window.back': '<strong>It’s back.</strong> You marked it fixed on {day}. After that, your AI read it again.',
52
+ 'fix.window.todo': 'What to do',
53
+ 'fix.window.note': 'Note for yourself (optional)',
54
+ 'fix.window.notePlaceholder': 'e.g. new keys made in Stripe',
55
+ 'fix.happened.did': 'What your AI did',
56
+ 'fix.happened.keys': 'It opened this file and read the keys inside. The old keys still work until you change them.',
57
+ 'fix.happened.look': 'It opened this sample file and read what’s inside. If it holds real keys, they still work.',
58
+ 'fix.happened.unknown': 'It reached for this file, but the record doesn’t say what came back.',
59
+ 'fix.happened.todo.keys': 'Make new keys, so the ones your AI saw stop working. Fix it shows you how, one step at a time.',
60
+ 'fix.happened.todo.look': 'Look inside. If you see real keys, change them. Check it shows you how.',
61
+ 'fix.happened.todo.unknown': 'Look inside. If you see real keys, change them. Check it shows you how.',
62
+ 'fix.skip.handled': 'I checked it, nothing to change',
63
+ 'fix.story.from': 'From your newest conversation that read it: {title} · {day}, {time}.',
64
+ 'fix.story.more.one': 'It was read in 1 more - see Conversations.',
65
+ 'fix.story.more.other': 'It was read in {n} more - see Conversations.',
66
+ 'fix.story.tab': 'Conversations',
67
+ 'fix.window.after': 'If your AI reads it again later, it comes back to your list.',
68
+ 'fix.window.where': 'Where your AI read it',
69
+ 'fix.window.see': 'See report',
70
+ 'fix.window.noReport': 'No report',
71
+ 'fix.window.untitled': 'A conversation with no title',
72
+ 'fix.window.all': 'Show all {n}',
73
+ 'fix.window.gone.one': '1 more is older than this run.',
74
+ 'fix.window.gone.other': '{n} more are older than this run.',
75
+ 'fix.saving': 'Saving…',
76
+ 'fix.refused': 'That didn’t work:',
77
+ 'fix.asFile': 'This page was opened as a file, so it can’t change anything. To do it, run this in your project:',
78
+ 'fix.unreachable': 'The page could not reach agentwhy start - it may have stopped. Run it again.',
79
+ 'fix.dev': 'Details for your developer',
80
+ 'fix.dev.lead': 'What agentwhy check says about each file, and in which conversations. A conversation is named by its id - the name of its transcript file - cut to 8 characters. No key or password is shown here.',
81
+ 'fix.dev.lead.shared': 'What agentwhy check says about each file, and in which conversations, numbered as in the list. No key or password is shown here.',
82
+ 'fix.dev.col.says': 'What check says',
83
+ 'fix.dev.col.file': 'File',
84
+ 'fix.dev.col.in': 'Conversations',
85
+ 'fix.dev.means.rotate': 'contents read',
86
+ 'fix.dev.means.template': 'template contents read',
87
+ 'fix.dev.means.unknown': 'outcome not recorded',
88
+ 'fix.dev.means.route': 'a call opened it and nothing refused it',
89
+ 'fix.dev.means.result': 'name in command output only',
90
+ 'fix.dev.count.one': '1 conversation',
91
+ 'fix.dev.count.other': '{n} conversations',
92
+ 'fix.dev.lines': 'Lines',
93
+ 'fix.dev.commands': 'Commands',
94
+ 'fix.dev.cmd.full': 'Every line, with its paths and what to do about them',
95
+ 'fix.dev.cmd.mark': 'Mark a file fixed once its keys are changed',
96
+ },
97
+ pl: {
98
+ 'fix.title': 'Do naprawy · agentwhy',
99
+ 'fix.range': 'Ostatnie {range} · {dates}',
100
+ 'fix.range.since': 'Od {dates}',
101
+ 'fix.span.h.one': 'godzina', 'fix.span.h.few': '{n} godziny', 'fix.span.h.many': '{n} godzin',
102
+ 'fix.span.d.one': 'dzień', 'fix.span.d.few': '{n} dni', 'fix.span.d.many': '{n} dni',
103
+ 'fix.span.w.one': 'tydzień', 'fix.span.w.few': '{n} tygodnie', 'fix.span.w.many': '{n} tygodni',
104
+ 'fix.hero.count.one': '1 plik do naprawy.',
105
+ 'fix.hero.count.few': '{n} pliki do naprawy.',
106
+ 'fix.hero.count.many': '{n} plików do naprawy.',
107
+ 'fix.hero.none': 'Nie ma nic do naprawy.',
108
+ 'fix.hero.keys.one': 'Zacznij od 1 z prawdziwymi kluczami.',
109
+ 'fix.hero.keys.few': 'Zacznij od {n} z prawdziwymi kluczami.',
110
+ 'fix.hero.keys.many': 'Zacznij od {n} z prawdziwymi kluczami.',
111
+ 'fix.hero.look': 'Zostało tylko szybkie sprawdzenie.',
112
+ 'fix.hero.nice': 'Dobra robota.',
113
+ 'fix.lead': 'Twoje AI widziało zawartość tych plików. Zmień w nich klucze, a potem odhacz je tutaj.',
114
+ 'fix.tab.todo': 'Do naprawy',
115
+ 'fix.tab.done': 'Zrobione',
116
+ 'fix.stopped.one': 'Twoja ochrona zadziałała: zatrzymano 1 próbę.',
117
+ 'fix.stopped.few': 'Twoja ochrona zadziałała: zatrzymano {n} próby.',
118
+ 'fix.stopped.many': 'Twoja ochrona zadziałała: zatrzymano {n} prób.',
119
+ 'fix.marksUnreadable': 'Nie udało się odczytać zapisu tego, co naprawiłeś, więc nic nie zostało przez to pominięte na tej liście.',
120
+ 'fix.keys': 'Zmień te klucze',
121
+ 'fix.keys.lead': 'Twoje AI przeczytało prawdziwe klucze w środku. Zrób nowe.',
122
+ 'fix.keys.go': 'Napraw →',
123
+ 'fix.look': 'Rzuć okiem',
124
+ 'fix.look.lead': 'To pliki przykładowe. Jeśli są w nich prawdziwe klucze, zmień je. Jeśli nie, odhacz je.',
125
+ 'fix.look.go': 'Sprawdź',
126
+ 'fix.back': 'Wrócił',
127
+ 'fix.in.one': 'w 1 rozmowie',
128
+ 'fix.in.few': 'w {n} rozmowach',
129
+ 'fix.in.many': 'w {n} rozmowach',
130
+ 'fix.private': 'Prywatny plik',
131
+ 'fix.seen.one': '<strong>1 plik — nic do zrobienia.</strong> <span class="tf-soft">Twoje AI widziało tylko jego nazwę, nigdy zawartość.</span>',
132
+ 'fix.seen.few': '<strong>{n} pliki — nic do zrobienia.</strong> <span class="tf-soft">Twoje AI widziało tylko ich nazwy, nigdy zawartość.</span>',
133
+ 'fix.seen.many': '<strong>{n} plików — nic do zrobienia.</strong> <span class="tf-soft">Twoje AI widziało tylko ich nazwy, nigdy zawartość.</span>',
134
+ 'fix.seen.label': 'Widziało tylko nazwę',
135
+ 'fix.empty': 'Twoje AI nie przeczytało niczego prywatnego, co wciąż trzeba naprawić.',
136
+ 'fix.done.lead': 'Jeśli twoje AI znów przeczyta któryś z nich, wróci on na twoją listę.',
137
+ 'fix.done.none': 'Nic jeszcze nie oznaczono. Gdy naprawisz plik, pojawi się tutaj.',
138
+ 'fix.done.fixed': '✓ Naprawione {when}',
139
+ 'fix.done.undo': 'Cofnij',
140
+ 'fix.undo.title': 'Przywrócić to na listę?',
141
+ 'fix.undo.text': 'Wróci do „Do naprawy”, jakbyś go nigdy nie odhaczył.',
142
+ 'fix.undo.go': 'Przywróć',
143
+ 'fix.today': 'dziś',
144
+ 'fix.yesterday': 'wczoraj',
145
+ 'fix.day.today': 'Dziś',
146
+ 'fix.day.yesterday': 'Wczoraj',
147
+ 'fix.window.back': '<strong>Wrócił.</strong> Oznaczyłeś go jako naprawiony {day}. Potem twoje AI znów go przeczytało.',
148
+ 'fix.window.todo': 'Co zrobić',
149
+ 'fix.window.note': 'Notatka dla siebie (opcjonalnie)',
150
+ 'fix.window.notePlaceholder': 'np. nowe klucze zrobione w Stripe',
151
+ 'fix.happened.did': 'Co zrobiło twoje AI',
152
+ 'fix.happened.keys': 'Otworzyło ten plik i przeczytało klucze w środku. Stare klucze działają, dopóki ich nie zmienisz.',
153
+ 'fix.happened.look': 'Otworzyło ten plik przykładowy i przeczytało, co w nim jest. Jeśli są w nim prawdziwe klucze, nadal działają.',
154
+ 'fix.happened.unknown': 'Sięgnęło po ten plik, ale zapis nie mówi, co wróciło.',
155
+ 'fix.happened.todo.keys': 'Zrób nowe klucze, żeby te, które widziało AI, przestały działać. „Napraw” pokaże ci jak, krok po kroku.',
156
+ 'fix.happened.todo.look': 'Zajrzyj do środka. Jeśli widzisz prawdziwe klucze, zmień je. „Sprawdź” pokaże ci jak.',
157
+ 'fix.happened.todo.unknown': 'Zajrzyj do środka. Jeśli widzisz prawdziwe klucze, zmień je. „Sprawdź” pokaże ci jak.',
158
+ 'fix.skip.handled': 'Sprawdzone, nic do zmiany',
159
+ 'fix.story.from': 'Z najnowszej rozmowy, w której AI go przeczytało: {title} · {day}, {time}.',
160
+ 'fix.story.more.one': 'Przeczytało go jeszcze w 1 rozmowie - zobacz Rozmowy.',
161
+ 'fix.story.more.few': 'Przeczytało go jeszcze w {n} rozmowach - zobacz Rozmowy.',
162
+ 'fix.story.more.many': 'Przeczytało go jeszcze w {n} rozmowach - zobacz Rozmowy.',
163
+ 'fix.story.tab': 'Rozmowy',
164
+ 'fix.window.after': 'Jeśli twoje AI przeczyta go później znowu, wróci na twoją listę.',
165
+ 'fix.window.where': 'Gdzie twoje AI go przeczytało',
166
+ 'fix.window.see': 'Zobacz raport',
167
+ 'fix.window.noReport': 'Brak raportu',
168
+ 'fix.window.untitled': 'Rozmowa bez tytułu',
169
+ 'fix.window.all': 'Pokaż wszystkie ({n})',
170
+ 'fix.window.gone.one': 'Jeszcze 1 jest starsza niż ten przebieg.',
171
+ 'fix.window.gone.few': 'Jeszcze {n} są starsze niż ten przebieg.',
172
+ 'fix.window.gone.many': 'Jeszcze {n} jest starszych niż ten przebieg.',
173
+ 'fix.saving': 'Zapisuję…',
174
+ 'fix.refused': 'Nie udało się:',
175
+ 'fix.asFile': 'Ta strona została otwarta jako plik, więc niczego nie zmieni. Żeby to zrobić, uruchom w swoim projekcie:',
176
+ 'fix.unreachable': 'Strona nie mogła połączyć się z agentwhy start - mógł się zatrzymać. Uruchom go ponownie.',
177
+ 'fix.dev': 'Szczegóły dla twojego programisty',
178
+ 'fix.dev.lead': 'Co agentwhy check mówi o każdym pliku i w których rozmowach. Rozmowę nazywa jej identyfikator - nazwa pliku z jej zapisem - skrócony do 8 znaków. Nie ma tu żadnego klucza ani hasła.',
179
+ 'fix.dev.lead.shared': 'Co agentwhy check mówi o każdym pliku i w których rozmowach, ponumerowanych jak na liście. Nie ma tu żadnego klucza ani hasła.',
180
+ 'fix.dev.col.says': 'Co mówi check',
181
+ 'fix.dev.col.file': 'Plik',
182
+ 'fix.dev.col.in': 'Rozmowy',
183
+ 'fix.dev.means.rotate': 'odczytano zawartość',
184
+ 'fix.dev.means.template': 'odczytano zawartość szablonu',
185
+ 'fix.dev.means.unknown': 'wynik nie został zapisany',
186
+ 'fix.dev.means.route': 'wywołanie go otworzyło i nic tego nie zatrzymało',
187
+ 'fix.dev.means.result': 'tylko nazwa w wyniku polecenia',
188
+ 'fix.dev.count.one': '1 rozmowa',
189
+ 'fix.dev.count.few': '{n} rozmowy',
190
+ 'fix.dev.count.many': '{n} rozmów',
191
+ 'fix.dev.lines': 'Wiersze',
192
+ 'fix.dev.commands': 'Polecenia',
193
+ 'fix.dev.cmd.full': 'Każdy wiersz, z jego ścieżkami i tym, co z nimi zrobić',
194
+ 'fix.dev.cmd.mark': 'Oznacz plik jako naprawiony, gdy klucze są już zmienione',
195
+ },
196
+ de: {
197
+ 'fix.title': 'Zu beheben · agentwhy',
198
+ 'fix.range': 'Letzte {range} · {dates}',
199
+ 'fix.range.since': 'Seit {dates}',
200
+ 'fix.span.h.one': 'Stunde', 'fix.span.h.other': '{n} Stunden',
201
+ 'fix.span.d.one': 'Tag', 'fix.span.d.other': '{n} Tage',
202
+ 'fix.span.w.one': 'Woche', 'fix.span.w.other': '{n} Wochen',
203
+ 'fix.hero.count.one': '1 Datei zu beheben.',
204
+ 'fix.hero.count.other': '{n} Dateien zu beheben.',
205
+ 'fix.hero.none': 'Nichts mehr zu beheben.',
206
+ 'fix.hero.keys.one': 'Fang mit der 1 mit echten Schlüsseln an.',
207
+ 'fix.hero.keys.other': 'Fang mit den {n} mit echten Schlüsseln an.',
208
+ 'fix.hero.look': 'Nur noch ein kurzer Blick.',
209
+ 'fix.hero.nice': 'Gut gemacht.',
210
+ 'fix.lead': 'Deine KI hat gesehen, was in diesen Dateien steht. Ändere die Schlüssel darin und hake sie dann hier ab.',
211
+ 'fix.tab.todo': 'Zu beheben',
212
+ 'fix.tab.done': 'Erledigt',
213
+ 'fix.stopped.one': 'Dein Schutz hat gewirkt: 1 Versuch wurde gestoppt.',
214
+ 'fix.stopped.other': 'Dein Schutz hat gewirkt: {n} Versuche wurden gestoppt.',
215
+ 'fix.marksUnreadable': 'Deine Aufzeichnung des Erledigten konnte nicht gelesen werden, daher wurde deshalb nichts von dieser Liste weggelassen.',
216
+ 'fix.keys': 'Diese Schlüssel ändern',
217
+ 'fix.keys.lead': 'Deine KI hat die echten Schlüssel darin gelesen. Erstelle neue.',
218
+ 'fix.keys.go': 'Beheben →',
219
+ 'fix.look': 'Kurz ansehen',
220
+ 'fix.look.lead': 'Das sind Beispieldateien. Wenn echte Schlüssel darin stehen, ändere sie. Wenn nicht, hake sie ab.',
221
+ 'fix.look.go': 'Ansehen',
222
+ 'fix.back': 'Wieder da',
223
+ 'fix.in.one': 'in 1 Unterhaltung',
224
+ 'fix.in.other': 'in {n} Unterhaltungen',
225
+ 'fix.private': 'Eine private Datei',
226
+ 'fix.seen.one': '<strong>1 Datei — nichts zu tun.</strong> <span class="tf-soft">Deine KI hat nur ihren Namen gesehen, nie den Inhalt.</span>',
227
+ 'fix.seen.other': '<strong>{n} Dateien — nichts zu tun.</strong> <span class="tf-soft">Deine KI hat nur ihre Namen gesehen, nie den Inhalt.</span>',
228
+ 'fix.seen.label': 'Nur den Namen gesehen',
229
+ 'fix.empty': 'Deine KI hat nichts Privates gelesen, das noch zu beheben ist.',
230
+ 'fix.done.lead': 'Wenn deine KI eine davon wieder liest, kommt sie zurück auf deine Liste.',
231
+ 'fix.done.none': 'Noch nichts erledigt. Wenn du eine Datei behebst, erscheint sie hier.',
232
+ 'fix.done.fixed': '✓ Behoben {when}',
233
+ 'fix.done.undo': 'Rückgängig',
234
+ 'fix.undo.title': 'Wieder auf die Liste setzen?',
235
+ 'fix.undo.text': 'Sie kommt zurück zu „Zu beheben“, als hättest du sie nie abgehakt.',
236
+ 'fix.undo.go': 'Zurücksetzen',
237
+ 'fix.today': 'heute',
238
+ 'fix.yesterday': 'gestern',
239
+ 'fix.day.today': 'Heute',
240
+ 'fix.day.yesterday': 'Gestern',
241
+ 'fix.window.back': '<strong>Sie ist wieder da.</strong> Du hast sie am {day} als behoben markiert. Danach hat deine KI sie wieder gelesen.',
242
+ 'fix.window.todo': 'Was zu tun ist',
243
+ 'fix.window.note': 'Notiz für dich (optional)',
244
+ 'fix.window.notePlaceholder': 'z. B. neue Schlüssel in Stripe erstellt',
245
+ 'fix.happened.did': 'Was deine KI getan hat',
246
+ 'fix.happened.keys': 'Sie hat diese Datei geöffnet und die Schlüssel darin gelesen. Die alten Schlüssel funktionieren, bis du sie änderst.',
247
+ 'fix.happened.look': 'Sie hat diese Beispieldatei geöffnet und gelesen, was darin steht. Wenn echte Schlüssel darin sind, funktionieren sie noch.',
248
+ 'fix.happened.unknown': 'Sie hat nach dieser Datei gegriffen, aber die Aufzeichnung sagt nicht, was zurückkam.',
249
+ 'fix.happened.todo.keys': 'Erstelle neue Schlüssel, damit die, die deine KI gesehen hat, nicht mehr funktionieren. „Beheben“ zeigt dir, wie, Schritt für Schritt.',
250
+ 'fix.happened.todo.look': 'Sieh hinein. Wenn du echte Schlüssel siehst, ändere sie. „Ansehen“ zeigt dir, wie.',
251
+ 'fix.happened.todo.unknown': 'Sieh hinein. Wenn du echte Schlüssel siehst, ändere sie. „Ansehen“ zeigt dir, wie.',
252
+ 'fix.skip.handled': 'Geprüft, nichts zu ändern',
253
+ 'fix.story.from': 'Aus deiner neuesten Unterhaltung, in der sie gelesen wurde: {title} · {day}, {time}.',
254
+ 'fix.story.more.one': 'Sie wurde in 1 weiteren gelesen - siehe Unterhaltungen.',
255
+ 'fix.story.more.other': 'Sie wurde in {n} weiteren gelesen - siehe Unterhaltungen.',
256
+ 'fix.story.tab': 'Unterhaltungen',
257
+ 'fix.window.after': 'Wenn deine KI sie später wieder liest, kommt sie zurück auf deine Liste.',
258
+ 'fix.window.where': 'Wo deine KI sie gelesen hat',
259
+ 'fix.window.see': 'Bericht ansehen',
260
+ 'fix.window.noReport': 'Kein Bericht',
261
+ 'fix.window.untitled': 'Eine Unterhaltung ohne Titel',
262
+ 'fix.window.all': 'Alle {n} zeigen',
263
+ 'fix.window.gone.one': '1 weitere ist älter als dieser Lauf.',
264
+ 'fix.window.gone.other': '{n} weitere sind älter als dieser Lauf.',
265
+ 'fix.saving': 'Wird gespeichert…',
266
+ 'fix.refused': 'Das hat nicht geklappt:',
267
+ 'fix.asFile': 'Diese Seite wurde als Datei geöffnet und kann nichts ändern. Führe dafür das hier in deinem Projekt aus:',
268
+ 'fix.unreachable': 'Die Seite hat agentwhy start nicht erreicht - vielleicht wurde es beendet. Starte es neu.',
269
+ 'fix.dev': 'Details für deine Entwicklerin oder deinen Entwickler',
270
+ 'fix.dev.lead': 'Was agentwhy check zu jeder Datei sagt, und in welchen Unterhaltungen. Eine Unterhaltung heißt nach ihrer ID - dem Namen ihrer Protokolldatei -, gekürzt auf 8 Zeichen. Hier steht kein Schlüssel und kein Passwort.',
271
+ 'fix.dev.lead.shared': 'Was agentwhy check zu jeder Datei sagt, und in welchen Unterhaltungen, nummeriert wie in der Liste. Hier steht kein Schlüssel und kein Passwort.',
272
+ 'fix.dev.col.says': 'Was check sagt',
273
+ 'fix.dev.col.file': 'Datei',
274
+ 'fix.dev.col.in': 'Unterhaltungen',
275
+ 'fix.dev.means.rotate': 'Inhalt gelesen',
276
+ 'fix.dev.means.template': 'Inhalt einer Vorlage gelesen',
277
+ 'fix.dev.means.unknown': 'Ergebnis nicht aufgezeichnet',
278
+ 'fix.dev.means.route': 'ein Aufruf hat sie geöffnet, nichts hat es verhindert',
279
+ 'fix.dev.means.result': 'nur der Name in einer Befehlsausgabe',
280
+ 'fix.dev.count.one': '1 Unterhaltung',
281
+ 'fix.dev.count.other': '{n} Unterhaltungen',
282
+ 'fix.dev.lines': 'Zeilen',
283
+ 'fix.dev.commands': 'Befehle',
284
+ 'fix.dev.cmd.full': 'Jede Zeile, mit ihren Pfaden und was zu tun ist',
285
+ 'fix.dev.cmd.mark': 'Eine Datei als behoben markieren, sobald ihre Schlüssel geändert sind',
286
+ },
287
+ };
@@ -0,0 +1,2 @@
1
+ /** At most this many variable names are kept per file: enough to name every line a person has to change. */
2
+ export const NAMES_PER_FILE = 20;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ import { matchesGlob } from '../core/policy/glob.js';
2
+ /** F33's table: the built-in patterns, grouped the way a person thinks of them. */
3
+ export const RULE_NAMES = [
4
+ { name: 'env', patterns: ['**/.env*', '**/*.env'] },
5
+ { name: 'npmrc', patterns: ['**/.npmrc'] },
6
+ { name: 'secrets', patterns: ['**/secrets/**'] },
7
+ { name: 'ssh', patterns: ['**/.ssh/**', '**/id_rsa*'] },
8
+ ];
9
+ /**
10
+ * The name of the first built-in rule that matches `path` among the `patterns` in force, or `undefined`. Only a
11
+ * pattern that is in force names a file: a path the run did not protect under `**\/.env*` is not called a passwords
12
+ * file because the built-in list would have.
13
+ */
14
+ export function ruleNameOf(path, patterns) {
15
+ for (const group of RULE_NAMES) {
16
+ if (group.patterns.some((pattern) => patterns.includes(pattern) && matchesGlob(path, pattern)))
17
+ return group.name;
18
+ }
19
+ return undefined;
20
+ }
@@ -0,0 +1,163 @@
1
+ import { join } from 'node:path';
2
+ import { displayPath, insideProject } from '../core/project-root.js';
3
+ import { sessionKey } from '../core/session-catalogue.js';
4
+ import { FileAccessError } from '../ports/file-access-error.js';
5
+ import { fileStamp } from '../shared/file-stamp.js';
6
+ import { buildReport } from './build-report.js';
7
+ import { actionsOf } from './check/session-actions.js';
8
+ import { fileStory } from './render/report-page/file-story.js';
9
+ import { listedFiles } from './render/report-page/files.js';
10
+ import { choosePolicy, policyRefusal } from './choose-policy.js';
11
+ import { projectDenyRules } from './project-rules.js';
12
+ /** Reads a session, decides under which policy to read it, and renders what can be said. */
13
+ export class SessionReport {
14
+ #dependencies;
15
+ constructor(dependencies) {
16
+ this.#dependencies = dependencies;
17
+ }
18
+ async run(options) {
19
+ const policy = options.policy === undefined ? await choosePolicy(options, this.#dependencies.files, this.#dependencies.tell) : { policy: options.policy };
20
+ if ('errors' in policy)
21
+ return { outcome: 'policy-refused', output: policyRefusal(policy.errors) };
22
+ const { reader, createRedactor, createRenderer, htmlRenderer, files } = this.#dependencies;
23
+ const input = await this.#input(options);
24
+ if ('message' in input)
25
+ return { outcome: 'no-session', output: input.message };
26
+ const read = await reader.read(input.path);
27
+ // X2: a file neither AI's format recognises is read by neither, and saying so beats a report of nothing.
28
+ if (read.kind === 'unknown-format') {
29
+ return { outcome: 'no-session', output: `No session to report on: ${input.path} is neither a Claude Code session nor a Codex session.\n` };
30
+ }
31
+ const { model } = read;
32
+ // One redactor for the whole run, so the same value carries the same pseudonym in both renderings.
33
+ const report = buildReport(model, policy.policy, createRedactor(model.projectRoot, options.share), {
34
+ share: options.share,
35
+ projectRoot: model.projectRoot,
36
+ });
37
+ // `--open` needs a file, so asking to see a report is asking to write one; without `--html` it is written
38
+ // somewhere temporary rather than into whatever directory the command was run from.
39
+ const htmlPath = options.htmlPath ??
40
+ (options.open ? join(this.#dependencies.temporaryDirectory, this.#temporaryName(model.sessionId, model.provider, options.share)) : undefined);
41
+ // M3: what the project's own settings deny now, read from the project the session ran in, so a row can say whether
42
+ // Claude Code would refuse the file. Only a page is drawn from it; the report itself is the session's.
43
+ const denied = htmlPath === undefined
44
+ ? undefined
45
+ : await projectDenyRules(files, model.projectRoot.kind === 'known' ? model.projectRoot.path : this.#dependencies.workingDirectory);
46
+ const written = htmlPath === undefined
47
+ ? undefined
48
+ : await this.#write(htmlPath, htmlRenderer.render({
49
+ report,
50
+ withIndexLink: options.withIndexLink === true,
51
+ ...(options.marks === undefined ? {} : { marks: options.marks }),
52
+ ...(options.served === true ? { served: true } : {}),
53
+ ...(options.title === undefined || options.share ? {} : { title: options.title }),
54
+ ...(denied === undefined ? {} : { denied }),
55
+ ...(this.#dependencies.timeZone === undefined ? {} : { timeZone: this.#dependencies.timeZone }),
56
+ }), files, whereFor(htmlPath, options.share, model.projectRoot));
57
+ const shown = written?.ok === true && options.open ? await this.#show(htmlPath ?? '') : '';
58
+ // A session that could not be read at all must not exit 0 with a report saying nothing was found: a typo in
59
+ // a path would read as a clean bill of health. `doctor` exits 1 on the same input, and so does this.
60
+ const unreadable = model.gaps.some((gap) => gap.kind === 'session-missing');
61
+ const actions = actionsOf(report);
62
+ const told = [...new Set([...actions.rotate.map((file) => file.path), ...actions.unknown.map(String)])];
63
+ return {
64
+ outcome: unreadable ? 'session-unreadable' : model.completeness === 'complete' ? 'complete' : 'incomplete',
65
+ tally: report.tally,
66
+ actions,
67
+ stories: { sessionId: report.scope.sessionId, files: new Map(told.map((path) => [path, fileStory(report, path)])) },
68
+ reached: listedFiles(report),
69
+ ...(written === undefined ? {} : { htmlWritten: written.ok }),
70
+ /*
71
+ * The summary comes out whatever else was asked for (§7.5) - unless silence was asked for by name. `--quiet`
72
+ * leaves where the report is and takes the findings out, for the one caller that is not a person reading a
73
+ * terminal: an agent running this because the person said yes to opening it (R19).
74
+ */
75
+ output: options.quiet === true
76
+ // The blank line before it separated the message from a summary that is no longer there.
77
+ ? `${written?.message ?? ''}${shown}`.replace(/^\n+/, '')
78
+ : `${createRenderer(options).render(report)}${written?.message ?? ''}${shown}`,
79
+ };
80
+ }
81
+ /**
82
+ * Which session to read. Given one, that one; otherwise the newest of this project, named in the output so
83
+ * nobody has to guess which session they are looking at.
84
+ */
85
+ async #input(options) {
86
+ const { catalogue, workingDirectory } = this.#dependencies;
87
+ if (options.input !== undefined) {
88
+ // `agentwhy sessions` ends with "report --input <the id above>", so an id of this project is taken as the session
89
+ // it names - matched whole, never as a prefix. Anything holding a separator, or not an id listed here, is a path.
90
+ // A session is named by its key (`codex-…` for Codex), or by its bare id where only one AI holds that id.
91
+ if (!/[\\/]/.test(options.input)) {
92
+ const sessions = (await catalogue.list(workingDirectory)).sessions;
93
+ const byKey = sessions.find((session) => sessionKey(session) === options.input);
94
+ const byId = sessions.filter((session) => session.id === options.input);
95
+ if (byKey !== undefined)
96
+ return { path: byKey.path };
97
+ if (byId.length === 1 && byId[0] !== undefined)
98
+ return { path: byId[0].path };
99
+ if (byId.length > 1) {
100
+ // Two AIs' sessions are told apart by their keys; two of one AI's - a copied file - only by their paths.
101
+ const ais = new Set(byId.map((session) => session.provider)).size;
102
+ return {
103
+ message: `${byId.length} sessions hold the id ${options.input}.\n` +
104
+ (ais > 1 ? 'Name it by its key, as agentwhy sessions lists it, or by its path.\n' : 'Name it by its path.\n'),
105
+ };
106
+ }
107
+ }
108
+ return { path: options.input };
109
+ }
110
+ const listing = await catalogue.list(workingDirectory);
111
+ const newest = listing.sessions[0];
112
+ if (newest === undefined) {
113
+ return {
114
+ message: `No session of this project to report on.\nLooked in ${listing.directory}\nGive one with --input, or run: agentwhy sessions\n`,
115
+ };
116
+ }
117
+ return { path: newest.path };
118
+ }
119
+ /**
120
+ * Opening is best effort and never changes the outcome: a machine with no opener still has the file, and its
121
+ * path has already been printed. Saying nothing happened beats a command that looks like it failed.
122
+ */
123
+ async #show(path) {
124
+ return (await this.#dependencies.browser.open(path)) ? '' : `Nothing on this machine opened it.\n`;
125
+ }
126
+ /**
127
+ * Whether the file is there, and what to tell the reader. The two are reported apart because a caller has to
128
+ * act on the first: deciding from the message alone once meant opening a file that had not been written,
129
+ * since there is a message either way.
130
+ */
131
+ async #write(path, html, files, where) {
132
+ const place = where === undefined ? '; the shared view does not print where' : ` to ${where}`;
133
+ try {
134
+ await files.writeText(path, html);
135
+ return { ok: true, message: `\nHTML report written${place}\n` };
136
+ }
137
+ catch (error) {
138
+ if (!(error instanceof FileAccessError))
139
+ throw error;
140
+ // The analysis still stands; only the file did not get written, and saying so beats failing silently.
141
+ return { ok: false, message: `\nThe HTML report could not be written${place}\n` };
142
+ }
143
+ }
144
+ /**
145
+ * A file shown and not kept. The full view names it after its session, so a second look finds the same file.
146
+ * The shared view names it after the moment: a file name is printed, and in that view the id is not shown.
147
+ */
148
+ #temporaryName(sessionId, provider, share) {
149
+ return share ? `agentwhy-shared-${fileStamp(this.#dependencies.now)}.html` : `agentwhy-${sessionKey({ id: sessionId, provider })}.html`;
150
+ }
151
+ }
152
+ /**
153
+ * Where a file went, as the view may say it. The full view says it as written. The shared view says it relative to
154
+ * the project where the file is inside one, and not at all where it is not.
155
+ *
156
+ * **Corrected 2026-09-14 after a review:** `--share --open` printed the temporary file's absolute path, and the
157
+ * file was named after the session - both things the shared view promises not to show.
158
+ */
159
+ function whereFor(path, share, root) {
160
+ if (!share)
161
+ return path;
162
+ return insideProject(path, root) ? displayPath(path, root) : undefined;
163
+ }
@@ -0,0 +1,37 @@
1
+ import { conversationWeeks } from './conversations/weeks.js';
2
+ import { PROJECTS_WINDOW } from './projects/projects-window.js';
3
+ /**
4
+ * The sidebar's pages, the same on every page `start` writes, with the counts computed once: every conversation, and
5
+ * every file still to fix (O10). Settings is this machine's, so a shared page does not offer it
6
+ * (`worth-running-every-day` R48); nor does a page of the home directory, which is no project to set up
7
+ * (`which-project.md` V7, V8).
8
+ */
9
+ export function appNav(index, active, links) {
10
+ const { total, toFix } = conversationWeeks(index);
11
+ return [
12
+ { name: 'app.nav.conversations', href: links.conversations, count: total, ...(active === 'conversations' ? { active: true } : {}) },
13
+ { name: 'app.nav.toFix', href: links.toFix, count: toFix, countTone: 'coral', ...(active === 'to-fix' ? { active: true } : {}) },
14
+ { name: 'app.nav.month', href: links.month, ...(active === 'month' ? { active: true } : {}) },
15
+ ...(index.settings === undefined || index.shared || index.notAProject !== undefined
16
+ ? []
17
+ : [{ name: 'app.nav.settings', href: links.settings, ...(active === 'settings' ? { active: true } : {}) }]),
18
+ ];
19
+ }
20
+ /** The project's folder name, as the sidebar shows it. */
21
+ export function projectName(path) {
22
+ return path.split(/[\\/]/).filter((part) => part !== '').pop() ?? path;
23
+ }
24
+ /**
25
+ * What the sidebar's card says about the project, the same on every page `start` writes: its folder's name and where
26
+ * it is (`.ai/specs/2026-09-27-which-project.md` V1). Nothing on a shared page, which names no project.
27
+ */
28
+ export function sidebarProject(index) {
29
+ if (index.project === undefined)
30
+ return {};
31
+ return {
32
+ project: projectName(index.project),
33
+ ...(index.place === undefined ? {} : { place: index.place }),
34
+ // which-project V2: the card opens the person's projects, where the page carries them.
35
+ ...(index.projects === undefined ? {} : { projectsWindow: PROJECTS_WINDOW }),
36
+ };
37
+ }
@@ -0,0 +1,104 @@
1
+ import { textLink } from '../../render/ui/button.js';
2
+ import { dayName } from '../../render/ui/local-date.js';
3
+ import { inLanguages, labelAttributes } from '../../render/report-copy.js';
4
+ /**
5
+ * "Your week" / "Your month": the heading, the switcher `‹ {name} ›`, "Back to this …" and the hint (F10). The steps
6
+ * are links to the neighbouring period's section, so with no script they still go there - every period is on the
7
+ * page, one under another; the script shows one at a time. The name opens the calendar a period is chosen in.
8
+ */
9
+ export function periodSwitch(kind, periods, at, words, name) {
10
+ const period = periods[at];
11
+ const older = periods[at + 1];
12
+ const newer = at > 0 ? periods[at - 1] : undefined;
13
+ const step = (target, targetAt, glyph, label) => target === undefined
14
+ ? '<span class="cw-step cw-step-off" aria-hidden="true">' + glyph + '</span>'
15
+ : '<a class="cw-step" href="#' + kind + '-' + target.ago + '" data-period-go="' + targetAt + '"' + labelAttributes((t) => t(label)) + '>' + glyph + '</a>';
16
+ return '<div class="cw-week-head"><div class="cw-week-left">' +
17
+ '<h2 class="cw-h2">' + inLanguages((t) => t(words.heading)) + '</h2>' +
18
+ '<div class="cw-switch">' + step(older, at + 1, '‹', words.earlier) +
19
+ // The input under the name is what the calendar is anchored to and writes into; nobody sees or types in it.
20
+ '<button type="button" class="cw-switch-label" data-period-pick' + labelAttributes((t) => t(words.pick)) + '>' +
21
+ inLanguages((t, lang) => name(period, t, lang)) +
22
+ '<input class="cw-pick-anchor" tabindex="-1" aria-hidden="true" readonly></button>' +
23
+ step(newer, at - 1, '›', words.later) + '</div>' +
24
+ (at === 0 ? '' : textLink(inLanguages((t) => t(words.back)), '#' + kind + '-0', ' data-period-go="0"')) +
25
+ '</div><span class="cw-week-hint js-only">' + inLanguages((t) => t(words.hint)) + '</span></div>';
26
+ }
27
+ /**
28
+ * One day (F11): its label, how many conversations, and whether any needs checking. A click narrows the lists to it,
29
+ * or, given `opens`, opens that window.
30
+ */
31
+ export function dayTile(day, label, parts = {}) {
32
+ const empty = day.conversations === 0;
33
+ const ahead = parts.ahead === true;
34
+ // A day that has not come yet says nothing about work: "No work" on a Friday that is still ahead is not true - nor on
35
+ // a today that is not over, where a week says "Nothing yet".
36
+ // A read that was fixed still happened: the day is drawn in coral and says so, never "All good" (F11, changed
37
+ // 2026-09-25), outranking conversations this run did not check. Only one still to fix frames the tile.
38
+ // "All good" only where every conversation of the day was checked: one this run did not read is not known to be good.
39
+ const tone = day.future && empty ? 'future' : empty && day.today && ahead ? 'yet' : empty ? 'none'
40
+ : day.toCheck > 0 ? 'bad' : day.fixed > 0 ? 'fixed' : day.unchecked > 0 ? 'unknown' : 'good';
41
+ const said = tone === 'future' ? (ahead ? inLanguages((t) => t('conv.day.ahead')) : '&nbsp;')
42
+ : tone === 'yet' ? inLanguages((t) => t('conv.day.yet'))
43
+ : empty ? inLanguages((t) => t('conv.day.none'))
44
+ : day.toCheck > 0 ? inLanguages((t) => t('conv.day.toCheck', { n: day.toCheck }))
45
+ : day.fixed > 0 ? inLanguages((t) => t('conv.day.fixed', { n: day.fixed }))
46
+ // F17: a day whose unchecked conversations were all read, with gaps, says that, as their list's heading does.
47
+ : day.unchecked > 0 ? inLanguages((t) => t((day.looks.unchecked ?? 0) === day.unchecked ? 'conv.day.partial' : 'conv.day.unchecked', { n: day.unchecked }))
48
+ : inLanguages((t) => t('conv.day.good'));
49
+ const count = tone === 'future' && ahead ? '&nbsp;' : tone === 'yet' ? '0' : empty ? '—' : String(day.conversations);
50
+ const opens = parts.opens;
51
+ const link = !empty && opens !== undefined;
52
+ return (link ? '<a' : '<button type="button"') + ' class="cw-day cw-day-' + tone + (day.today ? ' cw-day-today' : '') + '" data-day="' + day.day.number + '"' +
53
+ (link ? ' href="#' + opens + '" data-popup-open="' + opens + '"' : empty ? ' disabled' : '') + '>' +
54
+ '<span class="cw-day-label">' + label + '</span>' +
55
+ '<span class="cw-day-count">' + count + '</span>' +
56
+ '<span class="cw-day-state"><span class="cw-day-dot" aria-hidden="true"></span><span class="cw-day-said">' + said + '</span></span>' +
57
+ // What the chip "{day} ×" says once this day is chosen: a whole date, since a month's tile says only its number.
58
+ '<span class="cw-day-name" hidden>' + inLanguages((_t, lang) => dayName(day.day, lang)) + '</span>' + (parts.extra ?? '') + (link ? '</a>' : '</button>');
59
+ }
60
+ export const CALENDAR_VIEW_STYLE = String.raw `
61
+ .cw-week{margin-bottom:36px}
62
+ .cw-week-head{display:flex;justify-content:space-between;align-items:baseline;gap:12px;flex-wrap:wrap;margin-bottom:14px}
63
+ .cw-week-left{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
64
+ .cw-h2{margin:0;font-size:20px;font-weight:650}
65
+ .cw-switch{display:flex;align-items:center;gap:4px;padding:3px;border-radius:999px;background:var(--card);border:1px solid var(--white-10)}
66
+ .cw-step{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--text);font-size:16px}
67
+ a.cw-step:hover{background:var(--white-06);color:var(--text)}
68
+ a.cw-day{text-decoration:none}
69
+ .cw-step-off{color:var(--text-4);cursor:default}
70
+ .cw-switch-label{position:relative;min-width:170px;text-align:center;font:inherit;font-size:14px;font-weight:600;white-space:nowrap;padding:6px 8px;border:0;border-radius:999px;background:transparent;color:var(--text)}
71
+ .js .cw-switch-label{cursor:pointer}.js .cw-switch-label:hover{background:var(--white-06)}
72
+ .cw-pick-anchor{position:absolute;left:50%;bottom:-4px;width:1px;height:1px;padding:0;border:0;opacity:0;pointer-events:none}
73
+ .cw-switch-range{color:var(--text-3);font-weight:500}
74
+ .cw-week-hint{font-size:14px;color:var(--text-3)}
75
+ .cw-days{display:grid;grid-template-columns:repeat(auto-fit,minmax(112px,1fr));gap:10px}
76
+ .cw-day{display:flex;flex-direction:column;align-items:flex-start;gap:10px;padding:14px;border-radius:14px;background:var(--card);border:1px solid var(--white-09);color:inherit;font:inherit;text-align:left;cursor:pointer}
77
+ .cw-day:hover:not(:disabled){border-color:var(--white-28)}
78
+ .cw-day:disabled{cursor:default}
79
+ .cw-day-bad{border-color:var(--coral-25)}
80
+ .cw-day-on,.cw-day-on:hover:not(:disabled){background:var(--coral-08);border-color:var(--coral-50)}
81
+ .cw-day-label{font-size:13px;font-weight:600;color:var(--text-2)}
82
+ .cw-day-count{font-size:22px;font-weight:650;line-height:1}
83
+ .cw-day-state{display:flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600}
84
+ .cw-day-dot{flex:none;width:7px;height:7px;border-radius:50%;background:currentColor}
85
+ .cw-day-future{opacity:.5}.cw-day-future .cw-day-dot{visibility:hidden}
86
+ .cw-days .cw-day-today .cw-day-label{color:var(--text)}
87
+ .cw-days .cw-day-today:not(.cw-day-bad):not(.cw-day-on){border-color:var(--white-25)}
88
+ .cw-day-yet .cw-day-state{color:var(--text-soft)}
89
+ .cw-days .cw-day-future{opacity:1;background:transparent;border-style:dashed;border-color:var(--white-08)}
90
+ .cw-days .cw-day-future .cw-day-dot{visibility:visible}
91
+ .cw-days .cw-day-future .cw-day-label,.cw-days .cw-day-future .cw-day-state{color:var(--text-4)}
92
+ .cw-day-none .cw-day-state{color:var(--text-4)}.cw-day-unknown .cw-day-state{color:var(--text-3)}.cw-day-good .cw-day-state{color:var(--mint)}.cw-day-bad .cw-day-state,.cw-day-fixed .cw-day-state{color:var(--coral-text)}
93
+ .air-datepicker{--adp-font-family:var(--sans);--adp-background-color:var(--panel);--adp-background-color-hover:var(--white-06);--adp-background-color-active:var(--white-08);
94
+ --adp-border-color:var(--white-10);--adp-border-color-inner:var(--white-07);--adp-border-color-inline:var(--white-10);--adp-color:var(--text);--adp-color-secondary:var(--text-2);
95
+ --adp-accent-color:var(--coral);--adp-color-current-date:var(--coral-text);--adp-color-other-month:var(--text-4);--adp-color-other-month-hover:var(--text);--adp-day-name-color:var(--text-3);
96
+ --adp-nav-arrow-color:var(--text-2);--adp-nav-color-secondary:var(--text-2);--adp-cell-background-color-hover:var(--white-06);--adp-cell-background-color-selected:var(--coral);
97
+ --adp-cell-background-color-selected-hover:var(--coral-hover);--adp-cell-background-color-in-range:var(--coral-16);--adp-cell-background-color-in-range-hover:var(--coral-25);
98
+ --adp-cell-border-color-in-range:var(--coral-35);--adp-color-disabled:var(--text-4);--adp-color-disabled-in-range:var(--text-3);--adp-border-radius:12px;--adp-cell-border-radius:8px}
99
+ .air-datepicker--pointer:after{background:var(--panel)}
100
+ .air-datepicker-cell:is(.-day-,.-month-):is(.-range-from-,.-range-to-,.-selected-){background:var(--coral);color:var(--on-coral)}
101
+ .air-datepicker-cell:is(.-day-,.-month-).cw-has-data{box-shadow:inset 0 -3px 0 var(--coral)}
102
+ .air-datepicker-cell:is(.-day-,.-month-).cw-has-data:is(.-selected-,.-range-from-,.-range-to-){box-shadow:none}
103
+ .air-datepicker-cell.-day-.cw-week-hover:not(.-disabled-):not(.-selected-):not(.-in-range-):not(.-range-from-):not(.-range-to-){background:var(--white-08)}
104
+ `;