@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,208 @@
1
+ const PROVIDERS = {
2
+ // Your AI account
3
+ anthropic: { name: 'Anthropic', what: 'provider.ai', url: 'https://console.anthropic.com/settings/keys', names: ['ANTHROPIC', 'CLAUDE'] },
4
+ openai: { name: 'OpenAI', what: 'provider.ai', url: 'https://platform.openai.com/api-keys', names: ['OPENAI', 'OPEN_AI'] },
5
+ mistral: { name: 'Mistral AI', what: 'provider.ai', url: 'https://console.mistral.ai/api-keys', names: ['MISTRAL'] },
6
+ groq: { name: 'Groq', what: 'provider.ai', url: 'https://console.groq.com/keys', names: ['GROQ'] },
7
+ cohere: { name: 'Cohere', what: 'provider.ai', url: 'https://dashboard.cohere.com/api-keys', names: ['COHERE'] },
8
+ replicate: { name: 'Replicate', what: 'provider.ai', url: 'https://replicate.com/account/api-tokens', names: ['REPLICATE'] },
9
+ huggingface: { name: 'Hugging Face', what: 'provider.ai', url: 'https://huggingface.co/settings/tokens', names: ['HUGGINGFACE', 'HUGGING_FACE', 'HF'] },
10
+ perplexity: { name: 'Perplexity', what: 'provider.ai', url: 'https://www.perplexity.ai/settings/api', names: ['PERPLEXITY', 'PPLX'] },
11
+ deepseek: { name: 'DeepSeek', what: 'provider.ai', url: 'https://platform.deepseek.com/api_keys', names: ['DEEPSEEK'] },
12
+ together: { name: 'Together AI', what: 'provider.ai', url: 'https://api.together.ai/settings/api-keys', names: ['TOGETHER', 'TOGETHERAI', 'TOGETHER_AI'] },
13
+ fireworks: { name: 'Fireworks AI', what: 'provider.ai', url: 'https://fireworks.ai/account/api-keys', names: ['FIREWORKS'] },
14
+ openrouter: { name: 'OpenRouter', what: 'provider.ai', url: 'https://openrouter.ai/settings/keys', names: ['OPENROUTER', 'OPEN_ROUTER'] },
15
+ xai: { name: 'xAI', what: 'provider.ai', url: 'https://console.x.ai', names: ['XAI', 'GROK'] },
16
+ elevenlabs: { name: 'ElevenLabs', what: 'provider.ai', url: 'https://elevenlabs.io/app/settings/api-keys', names: ['ELEVENLABS', 'ELEVEN_LABS'] },
17
+ assemblyai: { name: 'AssemblyAI', what: 'provider.ai', url: 'https://www.assemblyai.com/app/api-keys', names: ['ASSEMBLYAI', 'ASSEMBLY_AI'] },
18
+ deepgram: { name: 'Deepgram', what: 'provider.ai', url: 'https://console.deepgram.com', names: ['DEEPGRAM'] },
19
+ stability: { name: 'Stability AI', what: 'provider.ai', url: 'https://platform.stability.ai/account/keys', names: ['STABILITY'] },
20
+ voyage: { name: 'Voyage AI', what: 'provider.ai', url: 'https://dashboard.voyageai.com', names: ['VOYAGE', 'VOYAGEAI'] },
21
+ langsmith: { name: 'LangSmith', what: 'provider.monitoring', url: 'https://smith.langchain.com/settings', names: ['LANGSMITH', 'LANGCHAIN'] },
22
+ pinecone: { name: 'Pinecone', what: 'provider.database', url: 'https://app.pinecone.io', names: ['PINECONE'] },
23
+ // Payments
24
+ stripe: { name: 'Stripe', what: 'provider.payments', url: 'https://dashboard.stripe.com/apikeys', names: ['STRIPE'] },
25
+ paypal: { name: 'PayPal', what: 'provider.payments', url: 'https://developer.paypal.com/dashboard/applications', names: ['PAYPAL'] },
26
+ braintree: { name: 'Braintree', what: 'provider.payments', url: 'https://www.braintreegateway.com/login', names: ['BRAINTREE'] },
27
+ square: { name: 'Square', what: 'provider.payments', url: 'https://developer.squareup.com/apps', names: ['SQUARE'] },
28
+ adyen: { name: 'Adyen', what: 'provider.payments', url: 'https://ca-live.adyen.com', names: ['ADYEN'] },
29
+ lemonsqueezy: { name: 'Lemon Squeezy', what: 'provider.payments', url: 'https://app.lemonsqueezy.com/settings/api', names: ['LEMONSQUEEZY', 'LEMON_SQUEEZY', 'LEMON'] },
30
+ paddle: { name: 'Paddle', what: 'provider.payments', url: 'https://vendors.paddle.com/authentication', names: ['PADDLE'] },
31
+ polar: { name: 'Polar', what: 'provider.payments', url: 'https://polar.sh/dashboard', names: ['POLAR'] },
32
+ mollie: { name: 'Mollie', what: 'provider.payments', url: 'https://my.mollie.com/dashboard/developers/api-keys', names: ['MOLLIE'] },
33
+ razorpay: { name: 'Razorpay', what: 'provider.payments', url: 'https://dashboard.razorpay.com/app/keys', names: ['RAZORPAY'] },
34
+ przelewy24: { name: 'Przelewy24', what: 'provider.payments', url: 'https://panel.przelewy24.pl', names: ['PRZELEWY24', 'P24'] },
35
+ payu: { name: 'PayU', what: 'provider.payments', url: 'https://secure.payu.com', names: ['PAYU'] },
36
+ tpay: { name: 'Tpay', what: 'provider.payments', url: 'https://panel.tpay.com', names: ['TPAY'] },
37
+ klarna: { name: 'Klarna', what: 'provider.payments', url: 'https://portal.klarna.com', names: ['KLARNA'] },
38
+ revenuecat: { name: 'RevenueCat', what: 'provider.payments', url: 'https://app.revenuecat.com', names: ['REVENUECAT', 'REVENUE_CAT'] },
39
+ coinbase: { name: 'Coinbase', what: 'provider.payments', url: 'https://www.coinbase.com/settings/api', names: ['COINBASE'] },
40
+ // Databases and backends
41
+ supabase: { name: 'Supabase', what: 'provider.supabase', url: 'https://supabase.com/dashboard/account/tokens', names: ['SUPABASE'] },
42
+ firebase: { name: 'Firebase', what: 'provider.backend', url: 'https://console.firebase.google.com', names: ['FIREBASE'] },
43
+ mongodb: { name: 'MongoDB', what: 'provider.database', url: 'https://cloud.mongodb.com', names: ['MONGODB', 'MONGO', 'ATLAS'] },
44
+ planetscale: { name: 'PlanetScale', what: 'provider.database', url: 'https://app.planetscale.com', names: ['PLANETSCALE'] },
45
+ neon: { name: 'Neon', what: 'provider.database', url: 'https://console.neon.tech', names: ['NEON'] },
46
+ turso: { name: 'Turso', what: 'provider.database', url: 'https://app.turso.tech', names: ['TURSO'] },
47
+ upstash: { name: 'Upstash', what: 'provider.database', url: 'https://console.upstash.com', names: ['UPSTASH', 'KV'] },
48
+ xata: { name: 'Xata', what: 'provider.database', url: 'https://app.xata.io', names: ['XATA'] },
49
+ cockroach: { name: 'CockroachDB', what: 'provider.database', url: 'https://cockroachlabs.cloud', names: ['COCKROACH', 'COCKROACHDB'] },
50
+ prisma: { name: 'Prisma', what: 'provider.database', url: 'https://console.prisma.io', names: ['PRISMA'] },
51
+ convex: { name: 'Convex', what: 'provider.backend', url: 'https://dashboard.convex.dev', names: ['CONVEX'] },
52
+ appwrite: { name: 'Appwrite', what: 'provider.backend', url: 'https://cloud.appwrite.io', names: ['APPWRITE'] },
53
+ // Signing people in
54
+ clerk: { name: 'Clerk', what: 'provider.login', url: 'https://dashboard.clerk.com', names: ['CLERK'] },
55
+ auth0: { name: 'Auth0', what: 'provider.login', url: 'https://manage.auth0.com', names: ['AUTH0'] },
56
+ okta: { name: 'Okta', what: 'provider.login', url: 'https://www.okta.com/login', names: ['OKTA'] },
57
+ kinde: { name: 'Kinde', what: 'provider.login', url: 'https://app.kinde.com', names: ['KINDE'] },
58
+ workos: { name: 'WorkOS', what: 'provider.login', url: 'https://dashboard.workos.com', names: ['WORKOS'] },
59
+ stytch: { name: 'Stytch', what: 'provider.login', url: 'https://stytch.com/dashboard', names: ['STYTCH'] },
60
+ // Cloud and hosting
61
+ aws: { name: 'AWS', what: 'provider.cloud', url: 'https://console.aws.amazon.com/iam/home#/security_credentials', names: ['AWS', 'AMAZON', 'S3', 'SES'] },
62
+ google: { name: 'Google', what: 'provider.google', url: 'https://console.cloud.google.com/apis/credentials', names: ['GOOGLE', 'GCP', 'GCLOUD', 'GEMINI', 'YOUTUBE', 'GMAIL'] },
63
+ azure: { name: 'Microsoft Azure', what: 'provider.cloud', url: 'https://portal.azure.com', names: ['AZURE', 'MICROSOFT'] },
64
+ vercel: { name: 'Vercel', what: 'provider.hosting', url: 'https://vercel.com/account/tokens', names: ['VERCEL'] },
65
+ netlify: { name: 'Netlify', what: 'provider.hosting', url: 'https://app.netlify.com/user/applications', names: ['NETLIFY'] },
66
+ cloudflare: { name: 'Cloudflare', what: 'provider.hosting', url: 'https://dash.cloudflare.com/profile/api-tokens', names: ['CLOUDFLARE', 'CF', 'R2'] },
67
+ heroku: { name: 'Heroku', what: 'provider.hosting', url: 'https://dashboard.heroku.com/account', names: ['HEROKU'] },
68
+ railway: { name: 'Railway', what: 'provider.hosting', url: 'https://railway.com/account/tokens', names: ['RAILWAY'] },
69
+ render: { name: 'Render', what: 'provider.hosting', url: 'https://dashboard.render.com', names: ['RENDER'] },
70
+ fly: { name: 'Fly.io', what: 'provider.hosting', url: 'https://fly.io/dashboard', names: ['FLY', 'FLYIO'] },
71
+ digitalocean: { name: 'DigitalOcean', what: 'provider.servers', url: 'https://cloud.digitalocean.com/account/api/tokens', names: ['DIGITALOCEAN', 'DIGITAL_OCEAN'] },
72
+ linode: { name: 'Linode', what: 'provider.servers', url: 'https://cloud.linode.com/profile/tokens', names: ['LINODE', 'AKAMAI'] },
73
+ hetzner: { name: 'Hetzner', what: 'provider.servers', url: 'https://console.hetzner.cloud', names: ['HETZNER', 'HCLOUD'] },
74
+ ovh: { name: 'OVHcloud', what: 'provider.servers', url: 'https://www.ovh.com/manager', names: ['OVH'] },
75
+ expo: { name: 'Expo', what: 'provider.hosting', url: 'https://expo.dev/settings/access-tokens', names: ['EXPO', 'EAS'] },
76
+ // Your code and the tools you build with
77
+ github: { name: 'GitHub', what: 'provider.github', url: 'https://github.com/settings/tokens', names: ['GITHUB', 'GH'] },
78
+ gitlab: { name: 'GitLab', what: 'provider.gitlab', url: 'https://gitlab.com/-/user_settings/personal_access_tokens', names: ['GITLAB'] },
79
+ bitbucket: { name: 'Bitbucket', what: 'provider.dev', url: 'https://bitbucket.org/account/settings/app-passwords/', names: ['BITBUCKET'] },
80
+ npm: { name: 'npm', what: 'provider.npm', url: 'https://docs.npmjs.com/creating-and-viewing-access-tokens', names: ['NPM'] },
81
+ docker: { name: 'Docker Hub', what: 'provider.dev', url: 'https://app.docker.com/settings/personal-access-tokens', names: ['DOCKER', 'DOCKERHUB'] },
82
+ circleci: { name: 'CircleCI', what: 'provider.dev', url: 'https://app.circleci.com/settings/user/tokens', names: ['CIRCLECI'] },
83
+ // Errors, logs and usage
84
+ sentry: { name: 'Sentry', what: 'provider.monitoring', url: 'https://sentry.io/settings/account/api/auth-tokens/', names: ['SENTRY'] },
85
+ datadog: { name: 'Datadog', what: 'provider.monitoring', url: 'https://app.datadoghq.com/organization-settings/api-keys', names: ['DATADOG', 'DD'] },
86
+ newrelic: { name: 'New Relic', what: 'provider.monitoring', url: 'https://one.newrelic.com/api-keys', names: ['NEWRELIC', 'NEW_RELIC'] },
87
+ bugsnag: { name: 'Bugsnag', what: 'provider.monitoring', url: 'https://app.bugsnag.com/settings', names: ['BUGSNAG'] },
88
+ logrocket: { name: 'LogRocket', what: 'provider.monitoring', url: 'https://app.logrocket.com', names: ['LOGROCKET'] },
89
+ axiom: { name: 'Axiom', what: 'provider.monitoring', url: 'https://app.axiom.co/settings/api-tokens', names: ['AXIOM'] },
90
+ betterstack: { name: 'Better Stack', what: 'provider.monitoring', url: 'https://betterstack.com/settings/api-tokens', names: ['BETTERSTACK', 'BETTER_STACK', 'LOGTAIL'] },
91
+ posthog: { name: 'PostHog', what: 'provider.analytics', url: 'https://us.posthog.com/settings/user-api-keys', names: ['POSTHOG'] },
92
+ mixpanel: { name: 'Mixpanel', what: 'provider.analytics', url: 'https://mixpanel.com/settings/project', names: ['MIXPANEL'] },
93
+ segment: { name: 'Segment', what: 'provider.analytics', url: 'https://app.segment.com', names: ['SEGMENT'] },
94
+ amplitude: { name: 'Amplitude', what: 'provider.analytics', url: 'https://app.amplitude.com', names: ['AMPLITUDE'] },
95
+ // Emails, text messages, chat
96
+ sendgrid: { name: 'SendGrid', what: 'provider.email', url: 'https://app.sendgrid.com/settings/api_keys', names: ['SENDGRID'] },
97
+ resend: { name: 'Resend', what: 'provider.email', url: 'https://resend.com/api-keys', names: ['RESEND'] },
98
+ mailgun: { name: 'Mailgun', what: 'provider.email', url: 'https://app.mailgun.com/settings/api_security', names: ['MAILGUN'] },
99
+ postmark: { name: 'Postmark', what: 'provider.email', url: 'https://account.postmarkapp.com/servers', names: ['POSTMARK'] },
100
+ mailchimp: { name: 'Mailchimp', what: 'provider.email', url: 'https://mailchimp.com/help/about-api-keys/', names: ['MAILCHIMP', 'MANDRILL'] },
101
+ brevo: { name: 'Brevo', what: 'provider.email', url: 'https://app.brevo.com/settings/keys/api', names: ['BREVO', 'SENDINBLUE'] },
102
+ loops: { name: 'Loops', what: 'provider.email', url: 'https://app.loops.so/settings', names: ['LOOPS'] },
103
+ mailersend: { name: 'MailerSend', what: 'provider.email', url: 'https://app.mailersend.com', names: ['MAILERSEND'] },
104
+ convertkit: { name: 'Kit', what: 'provider.email', url: 'https://app.kit.com', names: ['CONVERTKIT'] },
105
+ twilio: { name: 'Twilio', what: 'provider.sms', url: 'https://console.twilio.com', names: ['TWILIO'] },
106
+ vonage: { name: 'Vonage', what: 'provider.sms', url: 'https://dashboard.nexmo.com', names: ['VONAGE', 'NEXMO'] },
107
+ messagebird: { name: 'MessageBird', what: 'provider.sms', url: 'https://dashboard.messagebird.com', names: ['MESSAGEBIRD'] },
108
+ plivo: { name: 'Plivo', what: 'provider.sms', url: 'https://console.plivo.com', names: ['PLIVO'] },
109
+ slack: { name: 'Slack', what: 'provider.slack', url: 'https://api.slack.com/apps', names: ['SLACK'] },
110
+ discord: { name: 'Discord', what: 'provider.chat', url: 'https://discord.com/developers/applications', names: ['DISCORD'] },
111
+ telegram: { name: 'Telegram', what: 'provider.chat', url: 'https://t.me/BotFather', names: ['TELEGRAM'] },
112
+ whatsapp: { name: 'WhatsApp', what: 'provider.chat', url: 'https://business.facebook.com', names: ['WHATSAPP'] },
113
+ pusher: { name: 'Pusher', what: 'provider.realtime', url: 'https://dashboard.pusher.com', names: ['PUSHER'] },
114
+ ably: { name: 'Ably', what: 'provider.realtime', url: 'https://ably.com/accounts', names: ['ABLY'] },
115
+ livekit: { name: 'LiveKit', what: 'provider.realtime', url: 'https://cloud.livekit.io', names: ['LIVEKIT'] },
116
+ agora: { name: 'Agora', what: 'provider.realtime', url: 'https://console.agora.io', names: ['AGORA'] },
117
+ // Files, maps, search, content, shops
118
+ cloudinary: { name: 'Cloudinary', what: 'provider.files', url: 'https://console.cloudinary.com/settings/api-keys', names: ['CLOUDINARY'] },
119
+ uploadthing: { name: 'UploadThing', what: 'provider.files', url: 'https://uploadthing.com/dashboard', names: ['UPLOADTHING'] },
120
+ mux: { name: 'Mux', what: 'provider.files', url: 'https://dashboard.mux.com/settings/access-tokens', names: ['MUX'] },
121
+ backblaze: { name: 'Backblaze', what: 'provider.files', url: 'https://secure.backblaze.com/app_keys.htm', names: ['BACKBLAZE', 'B2'] },
122
+ imagekit: { name: 'ImageKit', what: 'provider.files', url: 'https://imagekit.io/dashboard/developer/api-keys', names: ['IMAGEKIT'] },
123
+ mapbox: { name: 'Mapbox', what: 'provider.maps', url: 'https://account.mapbox.com/access-tokens/', names: ['MAPBOX'] },
124
+ algolia: { name: 'Algolia', what: 'provider.search', url: 'https://dashboard.algolia.com/account/api-keys', names: ['ALGOLIA'] },
125
+ meilisearch: { name: 'Meilisearch', what: 'provider.search', url: 'https://cloud.meilisearch.com', names: ['MEILISEARCH', 'MEILI'] },
126
+ typesense: { name: 'Typesense', what: 'provider.search', url: 'https://cloud.typesense.org', names: ['TYPESENSE'] },
127
+ elastic: { name: 'Elastic', what: 'provider.search', url: 'https://cloud.elastic.co', names: ['ELASTIC', 'ELASTICSEARCH'] },
128
+ contentful: { name: 'Contentful', what: 'provider.content', url: 'https://app.contentful.com', names: ['CONTENTFUL'] },
129
+ sanity: { name: 'Sanity', what: 'provider.content', url: 'https://www.sanity.io/manage', names: ['SANITY'] },
130
+ strapi: { name: 'Strapi', what: 'provider.content', url: 'https://cloud.strapi.io', names: ['STRAPI'] },
131
+ storyblok: { name: 'Storyblok', what: 'provider.content', url: 'https://app.storyblok.com', names: ['STORYBLOK'] },
132
+ shopify: { name: 'Shopify', what: 'provider.shop', url: 'https://admin.shopify.com', names: ['SHOPIFY'] },
133
+ woocommerce: { name: 'WooCommerce', what: 'provider.shop', url: 'https://woocommerce.com/my-account/', names: ['WOOCOMMERCE', 'WOO'] },
134
+ // Social networks and work tools
135
+ meta: { name: 'Meta (Facebook, Instagram)', what: 'provider.social', url: 'https://developers.facebook.com/apps', names: ['FACEBOOK', 'FB', 'META', 'INSTAGRAM', 'IG'] },
136
+ twitter: { name: 'X (Twitter)', what: 'provider.social', url: 'https://developer.x.com/en/portal/dashboard', names: ['TWITTER'] },
137
+ linkedin: { name: 'LinkedIn', what: 'provider.social', url: 'https://www.linkedin.com/developers/apps', names: ['LINKEDIN'] },
138
+ tiktok: { name: 'TikTok', what: 'provider.social', url: 'https://developers.tiktok.com/apps', names: ['TIKTOK'] },
139
+ reddit: { name: 'Reddit', what: 'provider.social', url: 'https://www.reddit.com/prefs/apps', names: ['REDDIT'] },
140
+ spotify: { name: 'Spotify', what: 'provider.social', url: 'https://developer.spotify.com/dashboard', names: ['SPOTIFY'] },
141
+ notion: { name: 'Notion', what: 'provider.workspace', url: 'https://www.notion.so/my-integrations', names: ['NOTION'] },
142
+ airtable: { name: 'Airtable', what: 'provider.workspace', url: 'https://airtable.com/create/tokens', names: ['AIRTABLE'] },
143
+ linear: { name: 'Linear', what: 'provider.workspace', url: 'https://linear.app/settings/account/security', names: ['LINEAR'] },
144
+ atlassian: { name: 'Atlassian (Jira, Confluence)', what: 'provider.workspace', url: 'https://id.atlassian.com/manage-profile/security/api-tokens', names: ['ATLASSIAN', 'JIRA', 'CONFLUENCE'] },
145
+ trello: { name: 'Trello', what: 'provider.workspace', url: 'https://trello.com/power-ups/admin', names: ['TRELLO'] },
146
+ asana: { name: 'Asana', what: 'provider.workspace', url: 'https://app.asana.com/0/my-apps', names: ['ASANA'] },
147
+ figma: { name: 'Figma', what: 'provider.workspace', url: 'https://www.figma.com/settings', names: ['FIGMA'] },
148
+ hubspot: { name: 'HubSpot', what: 'provider.workspace', url: 'https://app.hubspot.com', names: ['HUBSPOT'] },
149
+ salesforce: { name: 'Salesforce', what: 'provider.workspace', url: 'https://login.salesforce.com', names: ['SALESFORCE', 'SFDC'] },
150
+ zendesk: { name: 'Zendesk', what: 'provider.workspace', url: 'https://www.zendesk.com/login/', names: ['ZENDESK'] },
151
+ intercom: { name: 'Intercom', what: 'provider.workspace', url: 'https://app.intercom.com/a/apps/_/developer-hub', names: ['INTERCOM'] },
152
+ dropbox: { name: 'Dropbox', what: 'provider.workspace', url: 'https://www.dropbox.com/developers/apps', names: ['DROPBOX'] },
153
+ calendly: { name: 'Calendly', what: 'provider.workspace', url: 'https://calendly.com/integrations/api_webhooks', names: ['CALENDLY'] },
154
+ zapier: { name: 'Zapier', what: 'provider.workspace', url: 'https://zapier.com/app/settings', names: ['ZAPIER'] },
155
+ };
156
+ /** Pattern name → provider. A pattern not here (`jwt`, `private-key`, `url-password`, …) names no provider. */
157
+ const BY_PATTERN = {
158
+ 'anthropic-key': 'anthropic',
159
+ 'openai-key': 'openai',
160
+ 'github-token': 'github',
161
+ 'gitlab-token': 'gitlab',
162
+ 'slack-token': 'slack',
163
+ 'aws-access-key-id': 'aws',
164
+ 'google-key': 'google',
165
+ 'stripe-key': 'stripe',
166
+ 'supabase-key': 'supabase',
167
+ 'npm-token': 'npm',
168
+ 'npmrc-auth-token': 'npm',
169
+ 'digitalocean-token': 'digitalocean',
170
+ 'sendgrid-key': 'sendgrid',
171
+ };
172
+ /** The first word or two of a variable name → provider: `STRIPE` → Stripe, `NEW_RELIC` → New Relic. */
173
+ const BY_NAME = new Map(Object.entries(PROVIDERS).flatMap(([id, row]) => row.names.map((name) => [name, id])));
174
+ /**
175
+ * What a framework puts in front of a variable it hands to the browser or the build - `NEXT_PUBLIC_SUPABASE_URL` - which
176
+ * says nothing about the service, so it is read past. The first group are the ones a framework ships to every visitor's
177
+ * browser: a key under one of them is public by the framework's own rule.
178
+ */
179
+ const FRAMEWORK = /^(?:(NEXT_PUBLIC|EXPO_PUBLIC|NUXT_PUBLIC|REACT_APP|VUE_APP|VITE|GATSBY|PUBLIC)|NUXT|PRIVATE|STORYBOOK)_/;
180
+ /** A variable's name as words - `stripeSecretKey`, `stripe-secret-key` and `STRIPE_SECRET_KEY` alike - past its framework's prefix. */
181
+ export function nameWords(name) {
182
+ const upper = name.replace(/([a-z0-9])([A-Z])/g, '$1_$2').replace(/[^A-Za-z0-9]+/g, '_').toUpperCase().replace(/^_+/, '');
183
+ const prefix = FRAMEWORK.exec(upper);
184
+ const words = (prefix === null ? upper : upper.slice(prefix[0].length)).split('_').filter((word) => word !== '');
185
+ return { words, shipped: prefix?.[1] !== undefined };
186
+ }
187
+ const entry = (id) => {
188
+ const row = id === undefined ? undefined : PROVIDERS[id];
189
+ if (row === undefined)
190
+ return undefined;
191
+ const { names: _names, ...provider } = row;
192
+ return provider;
193
+ };
194
+ /** The provider a key's format belongs to (F45 row 1), or none: `jwt`, `private-key`, a random value. */
195
+ export function providerOfPattern(pattern) {
196
+ return entry(BY_PATTERN[pattern]);
197
+ }
198
+ /**
199
+ * The provider a variable's name points to (F45 row 2, O11), or none. The name is read as words - `stripeSecretKey`,
200
+ * `stripe-secret-key` and `STRIPE_SECRET_KEY` alike - past a framework's prefix, and only its first word or two count:
201
+ * `STRIPE_SECRET_KEY` is Stripe, and `MAX_RESEND_TRIES` is not Resend.
202
+ */
203
+ export function providerOfName(name) {
204
+ const { words } = nameWords(name);
205
+ if (words.length < 2)
206
+ return undefined;
207
+ return entry(BY_NAME.get(words[0] + '_' + words[1]) ?? BY_NAME.get(words[0]));
208
+ }
@@ -0,0 +1,367 @@
1
+ import { PROVIDER_NAMES } from '../../../core/session-format.js';
2
+ import { SENTENCE_CAP } from '../../../shared/sentence.js';
3
+ import { filesRead } from '../../flow-reads.js';
4
+ import { actionsFor, escapeHtml as e } from '../html-report-components.js';
5
+ import { inLanguages } from '../report-copy.js';
6
+ import { buildSessionView } from '../session-view.js';
7
+ import { avatar } from '../ui/avatar.js';
8
+ import { callout } from '../ui/callout.js';
9
+ import { tag } from '../ui/tag.js';
10
+ export function recordGaps(report) {
11
+ const view = buildSessionView(report);
12
+ const unknown = [report.graph.main, ...report.graph.agents].flatMap((agent) => actionsFor(agent, report).filter((action) => action.outcome === 'unknown').map((action) => ({ agent, action })));
13
+ const unresolved = view.agents.filter((entry) => entry.unresolved).map((entry) => entry.agent);
14
+ const missingDelegations = view.column.flatMap((entry) => (entry.kind === 'missing' ? [entry.delegation.description] : []));
15
+ return {
16
+ any: report.scope.completeness !== 'complete' || report.missing.length > 0 || unknown.length > 0 || unresolved.length > 0 || missingDelegations.length > 0,
17
+ unknown,
18
+ unresolved,
19
+ missingDelegations,
20
+ };
21
+ }
22
+ /** Your AI, "Helper 6", or an agent the report does not hold. */
23
+ function namesOf(report) {
24
+ const agents = new Map([report.graph.main, ...report.graph.agents].map((agent) => [agent.index, agent]));
25
+ return (index, t) => {
26
+ const agent = index === undefined ? undefined : agents.get(index);
27
+ if (agent === undefined)
28
+ return t('flow.someAgent');
29
+ return agent.ordinal === undefined ? t('st.main') : t('st.helper', { ordinal: agent.ordinal });
30
+ };
31
+ }
32
+ const section = (title, body) => '<section class="rc-sect"><h3 class="rc-h">' + title + '</h3>' + body + '</section>';
33
+ const label = (key, vars = {}) => inLanguages((t) => t(key, vars));
34
+ /** The questions a record may leave open, in the order the page asks them. */
35
+ const QUESTIONS = ['actions', 'access', 'output-delivery', 'own-words', 'reasoning', 'refusals', 'permissions'];
36
+ /** One row of what is missing: what it is, what it changes, how many times, and - folded - which ones. */
37
+ function gapRow(key, count, which = []) {
38
+ return '<li class="rc-row"><span class="rc-row-mark" aria-hidden="true"></span><div class="rc-row-main">' +
39
+ '<div class="rc-row-t">' + label(key + '.t') + '</div><div class="rc-row-d">' + label(key + '.d') + '</div>' +
40
+ (which.length === 0 ? '' : '<details class="rc-which"><summary>' + label('rec.gap.which') + '</summary><ul class="rc-list">' +
41
+ which.map((one) => '<li>' + one + '</li>').join('') + '</ul></details>') +
42
+ '</div>' + (count > 1 ? tag(label('rec.gap.times', { n: count }), 'grey', 'badge') : '') + '</li>';
43
+ }
44
+ /**
45
+ * P61: the Record tab. An answer first - whether the record is complete - then each gap as a row that says what is
46
+ * missing and what that changes, in the reader's language (`report.gaps`, never `missing`'s English lines); what the
47
+ * format cannot show, once; how the conversation was checked, with every code folded under Technical details.
48
+ */
49
+ export function recordTab(report) {
50
+ const gaps = recordGaps(report);
51
+ const names = namesOf(report);
52
+ const ai = e(PROVIDER_NAMES[report.scope.provider]);
53
+ const missing = [
54
+ ...report.gaps.filter((gap) => gap.question === undefined).map((gap) => gapRow('rec.gap.k.' + gap.kind, gap.count)),
55
+ ...(gaps.unknown.length === 0 ? [] : [gapRow('rec.gap.unknown', gaps.unknown.length, gaps.unknown.map(({ agent, action }) => inLanguages((t) => names(agent.index, t)) + ' · <code>' + e(action.tool) + '</code> · <code>' + e(action.evidence) + '</code>'))]),
56
+ ...(gaps.unresolved.length === 0 ? [] : [gapRow('rec.gap.unresolved', gaps.unresolved.length, gaps.unresolved.map((agent) => inLanguages((t) => names(agent.index, t))))]),
57
+ ...(gaps.missingDelegations.length === 0 ? [] : [gapRow('rec.gap.lost', gaps.missingDelegations.length, gaps.missingDelegations.map((description) => description === undefined ? label('missing.none') : e(description)))]),
58
+ ];
59
+ // What the format cannot show, from its gaps and from what its sources declared: said once, here, and the rest it
60
+ // does show named in one line under it.
61
+ const states = new Map();
62
+ const note = (question, state) => {
63
+ const known = states.get(question);
64
+ if (known === 'absent' || (known === 'unmeasured' && state === 'supported'))
65
+ return;
66
+ states.set(question, state);
67
+ };
68
+ for (const gap of report.gaps)
69
+ if (gap.question !== undefined)
70
+ note(gap.question, gap.kind === 'capability-absent' ? 'absent' : 'unmeasured');
71
+ for (const one of report.recorded.capabilities)
72
+ note(one.question, one.state);
73
+ const unseen = QUESTIONS.filter((question) => states.get(question) === 'absent')
74
+ .concat(QUESTIONS.filter((question) => states.get(question) === 'unmeasured'));
75
+ const shown = QUESTIONS.filter((question) => states.get(question) === 'supported');
76
+ const cannotShow = unseen.length === 0 ? '' : '<h4 class="rc-h4">' + label('rec.cap.h') + '</h4>' +
77
+ '<p class="rc-p rc-dim rc-narrow">' + label('rec.cap.lead', { ai }) + '</p><ul class="rc-rows">' +
78
+ unseen.map((question) => '<li class="rc-row rc-row-cap"><div class="rc-row-main"><div class="rc-row-t">' + label('rec.cap.t.' + question) + '</div>' +
79
+ '<div class="rc-row-d">' + label('rec.cap.d.' + question) + '</div></div>' +
80
+ (states.get(question) === 'absent' ? tag(label('rec.cap.tag.absent'), 'amber') : tag(label('rec.cap.tag.unmeasured'), 'grey')) + '</li>').join('') + '</ul>' +
81
+ (shown.length === 0 ? '' : '<p class="rc-p rc-dim">' + inLanguages((t) => t('rec.cap.shown', { ai, list: shown.map((question) => t('rec.q.' + question)).join(', ') })) + '</p>');
82
+ const state = gaps.any ? 'gaps' : 'clean';
83
+ const cannot = '<section class="rc-sect rc-answer">' + tag(label('rec.gap.tag.' + state), gaps.any ? 'amber' : 'grey') +
84
+ '<h3 class="rc-title">' + label('rec.gap.title.' + state) + '</h3><p class="rc-lead">' + label('rec.gap.lead.' + state) + '</p>' +
85
+ (missing.length === 0 ? '' : '<h4 class="rc-h4">' + label('rec.gap.missing') + '</h4><ul class="rc-rows">' + missing.join('') + '</ul>') +
86
+ cannotShow + '<div class="rc-note">' + callout({ tone: 'grey', body: label('rec.note') }) + '</div></section>';
87
+ const shapes = report.secretShapes.length === 0 ? '<p class="rc-p">' + label('rec.shapes.none') + '</p>'
88
+ : '<ul class="rc-list">' + report.secretShapes.map((shape) => '<li><code>' + shape.classes.map((one) => e(one)).join(', ') + '</code> · ' +
89
+ inLanguages((t) => names(shape.agentIndex, t)) + ' · ' + e(shape.tool) + ' · <code>' + e(shape.evidence) + '</code></li>').join('') + '</ul>';
90
+ return '<div class="rc">' + cannot + howChecked(report) + recordedSection(report, names) + section(label('rec.shapes'), shapes) + '</div>';
91
+ }
92
+ /** P61, *How the session was read*: three facts in words, and every code - the rule, its source, the ID - folded. */
93
+ function howChecked(report) {
94
+ const { policy, redaction, sessionId, paths } = report.scope;
95
+ const builtIn = policy.origin.startsWith('BUILT-IN DEFAULT');
96
+ const level = policy.level === 'no-read' || policy.level === 'no-disclose' ? policy.level : 'other';
97
+ const fact = (key, value, note = '') => '<div class="rc-fact"><dt>' + label(key) + '</dt><dd>' + value +
98
+ (note === '' ? '' : '<span class="rc-fact-note">' + note + '</span>') + '</dd></div>';
99
+ const counts = inLanguages((t) => t(builtIn ? 'rec.how.files.builtIn' : 'rec.how.files.own', {
100
+ patterns: t('scope.patterns', { n: policy.patterns }), exceptions: t('scope.exceptions', { n: policy.exceptions }),
101
+ }));
102
+ const where = paths.shared
103
+ ? label('scope.pathsShared') + ' ' + label('scope.root.' + paths.root + (paths.root === 'known' ? '' : 'Shared'), { n: paths.workingDirectories ?? 0 })
104
+ : label('rec.how.root.' + paths.root, { n: paths.workingDirectories ?? 0 });
105
+ const technical = [
106
+ ['rec.how.session', '<code>' + e(sessionId) + '</code>'], ['rec.how.level', '<code>' + e(policy.level) + '</code>'],
107
+ ['rec.how.origin', '<code>' + e(policy.origin) + '</code>'],
108
+ ['scope.ruleset', 'v' + redaction.rulesetVersion], ['scope.redactions', String(redaction.redactions)],
109
+ ['scope.distinct', String(redaction.distinctValues)], ['scope.protected', String(redaction.protectedContents)],
110
+ ['scope.missingClasses', redaction.missingClasses.length === 0 ? '' : redaction.missingClasses.map((one) => e(one)).join(', ')],
111
+ ];
112
+ return section(label('rec.how.h'), '<dl class="rc-facts">' +
113
+ fact('rec.how.rule', label('rec.how.rule.' + level)) +
114
+ fact('rec.how.files', counts, label('rec.how.files.note')) +
115
+ fact('rec.how.paths', label(paths.shared ? 'rec.how.paths.shared' : 'rec.how.paths.full'), where) + '</dl>' +
116
+ '<details class="rc-fold"><summary>' + label('scope.technical') + '</summary><dl class="rc-dl">' +
117
+ technical.map(([key, value]) => '<dt>' + label(key) + '</dt><dd>' + (value === '' ? label('scope.none') : value) + '</dd>').join('') + '</dl></details>');
118
+ }
119
+ /**
120
+ * What the AI's runtime recorded at the time (`2026-09-27-what-codex-wrote.md` X19-X23), beside how this report was read
121
+ * and never in its place: the permissions in force by turn, and what its reviewer decided - on a turn, never on an
122
+ * action. What the record can show is said once, in the tab's first card. Nothing a reviewer wrote is quoted. A record
123
+ * that holds none of it has no section.
124
+ */
125
+ function recordedSection(report, names) {
126
+ const { recorded } = report;
127
+ if (recorded.permissions.length === 0 && recorded.reviews.length === 0)
128
+ return '';
129
+ const ai = e(PROVIDER_NAMES[report.scope.provider]);
130
+ const permissions = recorded.permissions.map((group) => '<li>' + inLanguages((t) => [
131
+ t('rec.perm.turns', { n: group.turns }),
132
+ t('rec.perm.approval', { value: group.approval === undefined ? t('rec.value.none') : '<code>' + e(group.approval) + '</code>' }),
133
+ t('rec.perm.approver', { value: t('rec.who.' + group.approver, { ai }) }),
134
+ t('rec.perm.sandbox', { value: group.sandbox === undefined ? t('rec.value.none') : '<code>' + e(group.sandbox) + '</code>' }),
135
+ t('rec.perm.network', { value: t('rec.net.' + group.network) }),
136
+ t('rec.perm.scopes', { read: group.readScopes, write: group.writeScopes }),
137
+ ].join(' · ')) +
138
+ (group.writablePaths.length === 0 ? '' : '<br><span class="rc-dim">' + label('rec.perm.writable') + '</span> ' +
139
+ group.writablePaths.map((path) => '<code>' + e(path) + '</code>').join(', ')) +
140
+ (group.complete ? '' : '<br><span class="rc-dim">' + label('rec.perm.incomplete') + '</span>') + '</li>').join('');
141
+ const verdicts = recorded.reviews.flatMap((review) => review.verdicts.map((verdict) => '<li>' + inLanguages((t) => (verdict.outcome === 'unrecognised' ? t('rec.review.unrecognised')
142
+ : verdict.turnKnown ? t('rec.review.allowed', { who: names(review.reviewedAgentIndex, t) }) : t('rec.review.allowedNoTurn')) +
143
+ (verdict.risk === undefined ? '' : ' · ' + t('rec.review.risk', { risk: e(verdict.risk) })) +
144
+ (verdict.rationaleSize === undefined ? '' : ' · ' + t('rec.review.why', { n: verdict.rationaleSize }))) +
145
+ ' · <code>' + e(verdict.evidence) + '</code></li>')).join('');
146
+ return section(label('rec.recorded', { ai }), '<p class="rc-p rc-dim">' + label('rec.recorded.note', { ai }) + '</p>' +
147
+ (permissions === '' ? '' : '<ul class="rc-list">' + permissions + '</ul>') +
148
+ (verdicts === '' ? '' : '<h4 class="rc-h4">' + label('rec.reviews', { ai }) + '</h4><ul class="rc-list">' + verdicts + '</ul>'));
149
+ }
150
+ /** P62: every AI's run, step by step, with every action it took folded under it. */
151
+ export function agentRuns(report) {
152
+ const names = namesOf(report);
153
+ const runs = report.flows.map((flow) => run(flow, report, names)).join('');
154
+ return '<section class="rc-runs"><div class="rc-runs-head"><h3 class="rc-h">' + label('steps.how') + '</h3>' +
155
+ (runs === '' ? '' : '<p class="rc-p rc-dim rc-narrow">' + label('rec.runs.lead') + '</p><ul class="rc-key">' +
156
+ ['coral', 'blue', 'amber', 'mint'].map((tone) => '<li><span class="rc-key-dot rc-tone-' + tone + '" aria-hidden="true"></span>' +
157
+ label('rec.runs.key.' + tone) + '</li>').join('') + '</ul>') + '</div>' +
158
+ (runs === '' ? '<p class="rc-p">' + label('rec.runs.none') + '</p>' : runs) + '</section>';
159
+ }
160
+ function run(flow, report, names) {
161
+ const named = new Set();
162
+ const agent = [report.graph.main, ...report.graph.agents].find((each) => each.index === flow.agentIndex);
163
+ const actions = agent === undefined ? [] : actionsFor(agent, report);
164
+ // P63, what-came-back R14: what came back from this AI, in the earlier report's sentences - never delivered is not
165
+ // "could not be read" (where-the-value-went R5), and what it wrote in its own messages is said beside it (R4b).
166
+ const cameBack = report.returns.filter((statement) => statement.agentIndex === flow.agentIndex).map((statement) => '<p class="rc-p rc-came-' + statement.strength + '">' + inLanguages((t) => t(statement.awaited === true ? 'return.awaited' : statement.inferred === true ? 'return.crossed' : 'return.' + statement.strength, {
167
+ files: returnFiles(t, statement.paths, statement.fileUncertain === true && statement.strength === 'value'),
168
+ n: statement.filesReached,
169
+ length: statement.reportLength ?? '?',
170
+ }) + (statement.strength === 'value' || statement.writtenFrom.length === 0 ? '' : ' ' + t('return.written', {
171
+ files: returnFiles(t, statement.writtenFrom, statement.fileUncertain === true),
172
+ }))) + '</p>').join('');
173
+ const steps = flow.steps.map((step) => {
174
+ const html = stepHtml(step, named, names, flow.agentIndex, report);
175
+ if ('files' in step)
176
+ named.add(JSON.stringify(step.files));
177
+ return html;
178
+ });
179
+ // The avatar says what the steps say: coral where one of them put a private file's text in front of this AI.
180
+ const read = steps.some((html) => html.includes('rc-tone-coral'));
181
+ return '<article class="rc-run" id="run-' + flow.agentIndex + '"><h4 class="rc-run-h">' +
182
+ avatar(agent?.ordinal === undefined ? 'AI' : 'H' + agent.ordinal, read ? 'coral' : 'grey', 30) +
183
+ '<span>' + inLanguages((t) => names(flow.agentIndex, t)) + '</span>' + tag(label('steps.count', { n: flow.steps.length }), 'grey', 'badge') + '</h4>' +
184
+ (cameBack === '' ? '' : '<div class="rc-came"><div class="rc-step-title">' + label('rec.cameBack') + '</div>' + cameBack + '</div>') +
185
+ '<ol class="rc-steps">' + steps.join('') + '</ol>' +
186
+ (actions.length === 0 ? '' : '<details class="rc-which rc-every"><summary>' + label('rec.actions', { n: actions.length }) + '</summary><div class="rc-actions">' +
187
+ actions.map((action) => '<div class="rc-action"><span class="rc-mono">' + action.sequence + '</span><span class="rc-mono">' + e(action.tool) + '</span>' +
188
+ '<span class="rc-mono">' + (action.target === undefined ? '—' : e(action.target)) + '</span>' +
189
+ tag(label('st.res.' + action.outcome), action.outcome === 'succeeded' ? 'mint' : action.outcome === 'blocked' ? 'grey' : 'coral') +
190
+ '<span class="rc-mono rc-dim">' + e(action.evidence) + '</span></div>').join('') + '</div></details>') +
191
+ '</article>';
192
+ }
193
+ /** Files as chips; "or" between them where the transcript does not say which one a value came from (what-came-back R8). */
194
+ const chips = (t, paths, uncertain = false) => paths.map((path) => '<code class="rc-chip">' + e(path) + '</code>').join(uncertain && paths.length > 1 ? t('files.or') : ', ');
195
+ const programList = (programs) => (programs ?? []).length === 0 ? '' : ' (' + (programs ?? []).map((program) => '<b>' + e(program) + '</b>').join(', ') + ')';
196
+ /** P62, P63: one step in the earlier report's sentences - its number, its kind, what it did, and where it leads. */
197
+ function stepHtml(step, named, names, agentIndex, report) {
198
+ const link = (index) => index === undefined ? '' :
199
+ '<a class="rc-link" href="#run-' + index + '">' + inLanguages((t) => t('flow.openOther', { name: names(index, t) })) + '</a>';
200
+ const uncertain = (index) => report.returns.some((item) => item.agentIndex === index && item.fileUncertain === true);
201
+ let title;
202
+ let body;
203
+ let after = '';
204
+ // The number's colour is the step's meaning, in the palette's words: coral - a private file's text was in front of the
205
+ // AI; blue - only its name; amber - not known; mint - stopped; grey - work passed between AIs.
206
+ let tone = 'grey';
207
+ switch (step.kind) {
208
+ case 'asked':
209
+ title = 'flow.kind.asked';
210
+ body = (t) => step.askedTo === undefined ? t('flow.askedBare', { by: names(step.byAgentIndex, t) })
211
+ : t('flow.asked', { by: names(step.byAgentIndex, t), asked: t('quote.open') + e(step.askedTo) + t('quote.close') });
212
+ after = link(step.byAgentIndex);
213
+ break;
214
+ case 'reached': {
215
+ // A traced value may be from any file the call reached; lines a search printed say whose they are.
216
+ const read = filesRead(step).length > 0;
217
+ // X10: a process's own output is not what the agent was handed, so its lacking the contents says nothing of that.
218
+ const key = step.outcome === 'blocked' ? 'blocked' : step.outcome === 'unknown' ? 'unknown' : read ? 'value'
219
+ : step.sources.includes('result') ? 'result' : step.processOutput === true ? 'printed' : 'input';
220
+ tone = key === 'blocked' ? 'mint' : key === 'unknown' || key === 'printed' ? 'amber' : key === 'value' ? 'coral' : 'blue';
221
+ title = step.outcome !== 'succeeded' ? 'flow.kind.reached.' + step.outcome
222
+ : read ? 'flow.kind.reached.value' : step.sources.includes('result') ? 'flow.kind.reached.path' : 'flow.kind.reached.named';
223
+ body = (t) => t('flow.reached.' + key, { did: '<b>' + e(step.did) + '</b>', files: chips(t, read ? filesRead(step) : step.files, step.carriedValue) });
224
+ after = '<details class="rc-which rc-wrote"><summary>' + label('wrote.open') + '</summary><div class="rc-open">' + wroteBefore(step.wrote) + '</div></details>';
225
+ break;
226
+ }
227
+ case 'received':
228
+ title = 'flow.kind.received';
229
+ tone = 'coral';
230
+ body = (t) => t('flow.received', { files: chips(t, step.files, true) });
231
+ break;
232
+ case 'carried':
233
+ title = 'flow.kind.carried';
234
+ tone = 'coral';
235
+ body = (t) => t(step.named.length === 0 ? 'flow.carriedBare' : 'flow.carried', { did: '<b>' + e(step.did) + '</b>', named: chips(t, step.named) });
236
+ break;
237
+ case 'used': {
238
+ const same = named.has(JSON.stringify(step.files));
239
+ const key = (step.landed === 'file' ? (step.intoProtected === true ? 'use.fileProtected' : 'use.file')
240
+ : step.landed === 'command' ? (step.commits === true ? 'use.commit' : 'use.command') : 'use.' + step.landed) + (same ? '.same' : '');
241
+ title = 'flow.kind.used.' + step.landed;
242
+ tone = 'coral';
243
+ body = (t) => t(key, { files: chips(t, step.files, step.fileUncertain === true), targets: chips(t, step.targets ?? []), programs: programList(step.programs) }) +
244
+ (step.after !== undefined ? ' ' + t('flow.after', { n: step.after }) : step.source === 'none' ? ' ' + t('use.source.none') : '');
245
+ break;
246
+ }
247
+ case 'delegated':
248
+ title = 'flow.kind.delegated';
249
+ tone = step.strength === 'value' ? 'coral' : 'grey';
250
+ body = (t) => t('flow.delegated.' + (step.awaited === true ? 'awaited' : step.inferred === true ? 'crossed' : step.strength), {
251
+ agent: names(step.toAgentIndex, t), files: returnFiles(t, step.files, uncertain(step.toAgentIndex) && step.strength === 'value'),
252
+ });
253
+ after = link(step.toAgentIndex);
254
+ break;
255
+ case 'returned':
256
+ title = 'flow.kind.returned';
257
+ tone = step.strength === 'value' ? 'coral' : 'grey';
258
+ body = (t) => t('flow.returned.' + (step.awaited === true ? 'awaited' : step.inferred === true ? 'crossed' : step.strength), {
259
+ agent: names(step.toAgentIndex, t), files: returnFiles(t, step.files, uncertain(agentIndex) && step.strength === 'value'),
260
+ });
261
+ after = link(step.toAgentIndex);
262
+ break;
263
+ }
264
+ const times = step.count > 1 ? '<b class="rc-times">' + step.count + ' ×</b> ' : '';
265
+ // The links to another AI's run stay beside the step's words; what it wrote before and where it is in the record are
266
+ // one row of pills, and an open one takes the row's width.
267
+ const links = after.startsWith('<a') ? after : '';
268
+ const wrote = links === '' ? after : '';
269
+ return '<li class="rc-step rc-' + step.kind + (step.broken === true ? ' rc-broken' : '') + '"><span class="rc-n rc-tone-' + tone + '">' + step.number + '</span>' +
270
+ '<div class="rc-step-body"><div class="rc-step-title">' + label(title) + '</div><p class="rc-p rc-step-text">' + inLanguages((t) => times + body(t)) + '</p>' + links +
271
+ '<div class="rc-tools">' + wrote + '<details class="rc-which"><summary>' + label('flow.records', { n: step.evidence.length }) + '</summary><div class="rc-open"><code class="rc-refs">' +
272
+ step.evidence.map((ref) => e(ref)).join(' → ') + '</code></div></details></div></div></li>';
273
+ }
274
+ function returnFiles(t, paths, uncertain) {
275
+ const files = paths.map((path) => '<code>' + e(path) + '</code>');
276
+ return files.join(uncertain && files.length > 1 ? t('files.or') : ', ');
277
+ }
278
+ /** P62, why-this-call R6-R8: the agent's one sentence, quoted as its own, or the fact in its place. */
279
+ function wroteBefore(wrote) {
280
+ const covers = wrote.covers > 1 ? '<p class="rc-p rc-dim">' + label('wrote.covers', { n: wrote.covers }) + '</p>' : '';
281
+ if (wrote.sentence !== undefined) {
282
+ const sentence = wrote.sentence;
283
+ return '<div class="rc-quote-head">' + label(wrote.kind === 'said' ? 'wrote.head.said' : 'wrote.head.reasoning') + '</div>' +
284
+ '<blockquote class="rc-quote">' + inLanguages((t) => t('quote.open') + e(sentence) + t('quote.close')) + '</blockquote>' +
285
+ (wrote.cut === true ? '<p class="rc-p rc-dim">' + label('wrote.cut', { n: SENTENCE_CAP }) + '</p>' : '') + covers;
286
+ }
287
+ const files = wrote.carried.map((path) => '<code>' + e(path) + '</code>').join(', ');
288
+ const said = wrote.carried.length > 0 ? label('wrote.carried', { files })
289
+ : wrote.size === 0 ? (wrote.blank > 0 ? label('wrote.blank', { n: wrote.blank }) : label('wrote.none')) : label('wrote.size', { n: wrote.size });
290
+ return '<p class="rc-p">' + said + '</p>' + covers;
291
+ }
292
+ export const RECORD_VIEW_STYLE = String.raw `
293
+ .rc{display:flex;flex-direction:column;gap:28px}
294
+ .rc-sect,.rc-runs{border-radius:16px;background:var(--card);border:1px solid var(--white-09);padding:22px 24px}
295
+ .rc-runs{margin-top:28px;display:flex;flex-direction:column;gap:22px}
296
+ .rc-runs-head .rc-h{margin-bottom:6px}
297
+ .rc-key{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:8px 18px;font-size:13px;color:var(--text-2)}
298
+ .rc-key li{display:flex;align-items:center;gap:7px}
299
+ .rc-key-dot{width:10px;height:10px;border-radius:50%}
300
+ .rc-key-dot.rc-tone-coral{background:var(--coral)}.rc-key-dot.rc-tone-blue{background:var(--blue)}.rc-key-dot.rc-tone-amber{background:var(--amber)}.rc-key-dot.rc-tone-mint{background:var(--mint)}
301
+ .rc-h{margin:0 0 12px;font-size:17px;font-weight:650}
302
+ .rc-answer>.tag{margin-bottom:12px}
303
+ .rc-title{margin:0 0 8px;font-size:22px;line-height:1.3;font-weight:650;letter-spacing:-0.01em}
304
+ .rc-lead{margin:0 0 6px;max-width:680px;font-size:15px;line-height:1.55;color:var(--text-2)}
305
+ .rc-narrow{max-width:680px}
306
+ .rc-rows{list-style:none;margin:0 0 10px;padding:0;border:1px solid var(--white-07);border-radius:12px;background:var(--panel);overflow:hidden}
307
+ .rc-row{display:flex;align-items:flex-start;gap:14px;padding:14px 16px}
308
+ .rc-row+.rc-row{border-top:1px solid var(--white-07)}
309
+ .rc-row-mark{flex:none;width:8px;height:8px;margin-top:7px;border-radius:50%;background:var(--amber)}
310
+ .rc-row-main{flex:1;min-width:0}
311
+ .rc-row-t{font-size:15px;font-weight:600;color:var(--text)}
312
+ .rc-row-d{margin-top:2px;font-size:14px;line-height:1.5;color:var(--text-2)}
313
+ .rc-row>.tag{flex:none;margin-top:1px}
314
+ .rc-which{margin-top:8px}
315
+ .rc-which>summary{display:inline-flex;cursor:pointer;list-style:none;font-size:13px;font-weight:600;color:var(--text-soft);padding:4px 12px;border-radius:999px;border:1px solid var(--white-14)}
316
+ .rc-which>summary::-webkit-details-marker{display:none}
317
+ .rc-which>summary:hover{border-color:var(--white-32)}
318
+ .rc-which[open]>summary{margin-bottom:8px}
319
+ .rc-note{margin-top:18px}
320
+ .rc-facts{margin:0;display:flex;flex-direction:column}
321
+ .rc-fact{display:grid;grid-template-columns:minmax(160px,220px) minmax(0,1fr);gap:6px 24px;padding:12px 0;border-top:1px solid var(--white-07)}
322
+ .rc-fact:first-child{border-top:0;padding-top:0}
323
+ .rc-fact dt{font-size:13px;font-weight:600;color:var(--text-3);padding-top:2px}
324
+ .rc-fact dd{margin:0;font-size:15px;line-height:1.5;color:var(--text)}
325
+ .rc-fact-note{display:block;margin-top:4px;max-width:680px;font-size:14px;line-height:1.5;color:var(--text-3)}
326
+ @media (max-width:640px){.rc-sect,.rc-runs{padding:18px 16px}.rc-fact{grid-template-columns:1fr;gap:2px}.rc-row-cap{flex-direction:column;gap:8px}.rc-dl{grid-template-columns:1fr}}
327
+ .rc-h4{margin:18px 0 8px;font-size:14px;font-weight:650;color:var(--text-soft)}
328
+ .rc-p{margin:0 0 8px;font-size:14.5px;line-height:1.55;color:var(--text)}
329
+ .rc-p code,.rc-list code{font-family:var(--mono);font-size:13px}
330
+ .rc-dim{color:var(--text-3)}
331
+ .rc-list{margin:0 0 8px;padding-left:20px;font-size:14px;line-height:1.6}
332
+ .rc-fold>summary{cursor:pointer;font-size:13.5px;font-weight:600;color:var(--text-2);margin:6px 0}
333
+ .rc-dl{display:grid;grid-template-columns:minmax(160px,auto) 1fr;gap:6px 18px;margin:8px 0 0;font-size:14px}
334
+ .rc-dl dt{color:var(--text-3)}.rc-dl dd{margin:0;font-family:var(--mono);font-size:13px}
335
+ .rc-run{border-top:1px solid var(--white-07);padding-top:20px}
336
+ .rc-run-h{margin:0 0 16px;display:flex;align-items:center;gap:10px;font-size:16px;font-weight:650}
337
+ .rc-steps{list-style:none;margin:0 0 14px;padding:0;display:flex;flex-direction:column}
338
+ .rc-step{position:relative;display:grid;grid-template-columns:30px minmax(0,1fr);gap:14px;padding-bottom:22px}
339
+ .rc-step:last-child{padding-bottom:4px}
340
+ .rc-step:not(:last-child)::before{content:"";position:absolute;left:14px;top:34px;bottom:4px;border-left:2px solid var(--white-08)}
341
+ .rc-broken:not(:last-child)::before{border-left-style:dashed;border-left-color:var(--amber-35)}
342
+ .rc-n{width:30px;height:30px;border-radius:50%;font-size:12.5px;font-weight:700;display:flex;align-items:center;justify-content:center;border:1px solid transparent}
343
+ .rc-tone-coral{background:var(--coral-16);color:var(--coral-text);border-color:var(--coral-35)}.rc-tone-blue{background:var(--blue-16);color:var(--blue)}
344
+ .rc-tone-amber{background:var(--amber-12);color:var(--amber);border-color:var(--amber-35)}.rc-tone-mint{background:var(--mint-12);color:var(--mint)}
345
+ .rc-tone-grey{background:var(--white-06);color:var(--text-2)}
346
+ .rc-step-body{min-width:0;padding-top:4px}
347
+ .rc-step .rc-step-title{font-size:15px;font-weight:600;color:var(--text);margin-bottom:3px}
348
+ .rc-step-text{max-width:820px;color:var(--text-2)}
349
+ .rc-step-text b{color:var(--text);font-weight:600}
350
+ .rc-tools{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
351
+ .rc-tools>.rc-which{margin-top:0}
352
+ .rc-tools>.rc-which[open]{flex-basis:100%}
353
+ .rc-open{padding:12px 14px;border-radius:10px;background:var(--panel);border:1px solid var(--white-07)}
354
+ .rc-open>:last-child{margin-bottom:0}
355
+ .rc-every{margin-top:4px}
356
+ .rc-step-title{font-size:13px;font-weight:600;color:var(--text-2);margin-bottom:4px}
357
+ .rc-times{color:var(--coral-text)}
358
+ .rc-chip{font-family:var(--mono);font-size:12.5px;color:var(--text);background:var(--white-07);border:1px solid var(--white-10);border-radius:6px;padding:1px 6px}
359
+ .rc-link{display:inline-block;margin:2px 0 4px;font-size:13.5px;font-weight:600;color:var(--coral-text)}
360
+ .rc-refs{display:block;font-family:var(--mono);font-size:12.5px;color:var(--text-3);overflow-wrap:anywhere}
361
+ .rc-quote-head{font-size:13px;font-weight:600;color:var(--text-3);margin:8px 0 4px}
362
+ .rc-quote{margin:0 0 8px;padding:8px 14px;border-left:2px solid var(--white-18);font-size:14.5px;line-height:1.55;color:var(--text-soft)}
363
+ .rc-came{margin:0 0 12px;padding:12px 14px;border-radius:12px;background:var(--panel);border:1px solid var(--white-07)}
364
+ .rc-actions{display:flex;flex-direction:column;gap:6px;margin-top:8px}
365
+ .rc-action{display:grid;grid-template-columns:40px minmax(120px,0.8fr) minmax(0,1.5fr) 110px minmax(0,1fr);gap:12px;align-items:center;font-size:13px}
366
+ .rc-mono{font-family:var(--mono);font-size:12.5px;overflow-wrap:anywhere}
367
+ `;