@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,303 @@
1
+ import { isJsonObject } from '../../../shared/json.js';
2
+ import { PACKAGE } from '../../../shared/package-name.js';
3
+ import { isPlainInvocation, NPX_BEFORE_NAME, VERSION } from '../../../shared/plain-invocation.js';
4
+ import { isOlder, plainVersion } from '../../../shared/plain-version.js';
5
+ import { HOOK_SETTINGS, SETTINGS_FILES } from '../contract/settings.js';
6
+ import { PRE_TOOL_USE, STOP, SUBAGENT_STOP } from '../contract/hooks.js';
7
+ /**
8
+ * A command that runs agentwhy's `watch` or `refuse` through a word naming agentwhy - `agentwhy`, `npx @agentwhy/cli@1`,
9
+ * `node /opt/agentwhy/dist/cli.js`. The word may be a path with agentwhy anywhere in it; the subcommand is the next word.
10
+ * An invocation that names agentwhy nowhere is found by `invoke` instead (see `runs`). Found by a review: a path
11
+ * after agentwhy was not matched, so a second `init` added every hook twice and `--remove` removed nothing. The
12
+ * package's scope, `@agentwhy/`, counts as a word's start too - that scope and no other: found by a review, any `@`
13
+ * did, so `--remove` took out `npx @agentwhy-labs/notifier watch`, a hook agentwhy never wrote. A path's separator is
14
+ * either slash: found by a second review, `node_modules\@agentwhy\cli` on Windows stopped being found by the first fix.
15
+ */
16
+ const RUNS_AGENTWHY = /(?:(?:^|[\s/\\])agentwhy|@agentwhy[/\\])\S*\s+(watch|refuse)(?:\s|$)/;
17
+ /** Which hook a command runs, if it runs one: through a word naming agentwhy, or through the invocation `init` was given. */
18
+ function hookRun(command, invoke) {
19
+ const named = RUNS_AGENTWHY.exec(command)?.[1];
20
+ if (named === 'watch' || named === 'refuse')
21
+ return named;
22
+ if (invoke === undefined)
23
+ return undefined;
24
+ for (const hook of ['watch', 'refuse']) {
25
+ const run = `${invoke} ${hook}`;
26
+ if (command === run || command.startsWith(`${run} `))
27
+ return hook;
28
+ }
29
+ return undefined;
30
+ }
31
+ /**
32
+ * The entries to install, each with the command it runs (R6, R9).
33
+ *
34
+ * `watch` is two entries, not one (`the-agent-nobody-watches` R1): `SubagentStop` finds what a delegated agent did,
35
+ * and `Stop` says it and checks the session's own agent - the one agent that has no `SubagentStop` of its own. The
36
+ * command line is the same in both, because `watch` reads the event from its input. Installed on one event alone it
37
+ * is half a tool: with no `Stop`, nothing is ever said in the conversation and the main agent is never checked.
38
+ */
39
+ export function hookEntries(hooks, invoke, rules) {
40
+ const settings = rules === undefined
41
+ ? ''
42
+ : ` --settings "${HOOK_SETTINGS.projectDirectory}/${SETTINGS_FILES.directory}/${SETTINGS_FILES[rules]}"`;
43
+ return hooks.flatMap((hook) => hook === 'watch'
44
+ ? [SUBAGENT_STOP.event, STOP.event].map((event) => ({ hook, event, command: `${invoke} watch${settings}` }))
45
+ : [{ hook, event: PRE_TOOL_USE.event, matcher: PRE_TOOL_USE.shellTool, command: `${invoke} refuse${settings}` }]);
46
+ }
47
+ /**
48
+ * The entries of `hooks` that this settings object does not run yet, event by event. A hook is not "installed"
49
+ * where only one of its events is: a file written by an older version runs `watch` on `SubagentStop` alone, and
50
+ * asking for `watch` again has to add the `Stop` it is missing rather than report that there is nothing to do.
51
+ */
52
+ export function missingHookEntries(settings, hooks, invoke, rules) {
53
+ const running = runningEvents(settings, invoke);
54
+ return hookEntries(hooks, invoke, rules).filter((entry) => running.get(entry.hook)?.has(entry.event) !== true);
55
+ }
56
+ /** Which events already run each of agentwhy's hooks, by the same reading `installedHooks` uses. */
57
+ function runningEvents(settings, invoke) {
58
+ const found = new Map();
59
+ const hooks = settings[HOOK_SETTINGS.hooks];
60
+ if (!isJsonObject(hooks))
61
+ return found;
62
+ for (const [event, list] of Object.entries(hooks)) {
63
+ for (const command of commandsInList(list)) {
64
+ const hook = hookRun(command, invoke);
65
+ if (hook === undefined)
66
+ continue;
67
+ const events = found.get(hook) ?? new Set();
68
+ events.add(event);
69
+ found.set(hook, events);
70
+ }
71
+ }
72
+ return found;
73
+ }
74
+ /**
75
+ * Which of agentwhy's hooks a settings object already runs (R8): through any command naming agentwhy, and through
76
+ * `invoke`, the invocation this run of `init` was given, however it is spelled.
77
+ */
78
+ export function installedHooks(settings, invoke) {
79
+ const found = new Set();
80
+ for (const command of commandsIn(settings)) {
81
+ const hook = hookRun(command, invoke);
82
+ if (hook !== undefined)
83
+ found.add(hook);
84
+ }
85
+ return found;
86
+ }
87
+ /**
88
+ * How the `Stop` hook that runs `watch` runs agentwhy: its command up to the subcommand, `npx @agentwhy/cli` or
89
+ * `agentwhy`. A command that works as a hook is one that works for the agent in the same project, which a name
90
+ * chosen here would not be: `agentwhy` is on no path where only `npx` ever ran it. `undefined` where these settings
91
+ * run no such hook, or run it through anything but plain words.
92
+ */
93
+ export function watchInvocation(settings) {
94
+ const hooks = settings[HOOK_SETTINGS.hooks];
95
+ if (!isJsonObject(hooks))
96
+ return undefined;
97
+ return firstPlain(commandsInList(hooks[STOP.event]), ['watch']);
98
+ }
99
+ /**
100
+ * How the agentwhy hooks these settings already run invoke it: the first one's command up to its subcommand, where it
101
+ * is in plain words (`a-hook-runs-what-you-ran.md` J1, J4). A hook written next repeats it (R42), so a project does
102
+ * not run `watch` one way and `refuse` another.
103
+ */
104
+ export function runningInvocation(settings) {
105
+ return firstPlain(commandsIn(settings), ['watch', 'refuse']);
106
+ }
107
+ /** The first of these commands that runs one of `hooks` through agentwhy named in plain words: its invocation. */
108
+ function firstPlain(commands, hooks) {
109
+ for (const command of commands) {
110
+ const plain = plainRun(command);
111
+ if (plain !== undefined && hooks.includes(plain.hook))
112
+ return plain.invocation;
113
+ }
114
+ return undefined;
115
+ }
116
+ /**
117
+ * Which hook a command runs and the invocation before it, where agentwhy is named in plain words (J4). The session's
118
+ * agent is asked to run what `watchInvocation` finds (`the-agent-tells-you.md` R18), and a hook agentwhy writes repeats
119
+ * what `runningInvocation` finds, so a settings file cannot hand either more than agentwhy through it.
120
+ */
121
+ function plainRun(command) {
122
+ const hook = hookRun(command, undefined);
123
+ if (hook === undefined)
124
+ return undefined;
125
+ const invocation = BEFORE_HOOK[hook].exec(command)?.[1];
126
+ return invocation !== undefined && isPlainInvocation(invocation) ? { hook, invocation } : undefined;
127
+ }
128
+ /** The words before each hook's subcommand: the invocation `plainRun` reads, whether plain or not. */
129
+ const BEFORE_HOOK = {
130
+ watch: /^\s*(.*?)\s+watch(?:\s|$)/,
131
+ refuse: /^\s*(.*?)\s+refuse(?:\s|$)/,
132
+ };
133
+ /**
134
+ * The published way with its version pinned, `npx @agentwhy/cli@0.2.0`, `--yes` allowed: what a hook written by a
135
+ * release runs (`nothing-updates-by-itself.md` U1), and the only form an update rewrites (U7). Built from the plain-words
136
+ * pattern's own parts, so the two cannot read `npx` differently. The package's name holds no character a pattern reads
137
+ * as more than itself.
138
+ */
139
+ const PINNED = new RegExp(`^(${NPX_BEFORE_NAME}${PACKAGE}@)(${VERSION})$`);
140
+ /** The release a plain invocation is pinned to, where it is the pinned published way (U2). */
141
+ function pinnedOf(invocation) {
142
+ const version = PINNED.exec(invocation)?.[2];
143
+ return version !== undefined && plainVersion(version) !== undefined ? version : undefined;
144
+ }
145
+ /** The releases agentwhy's hooks in these settings are pinned to, one per command, in the order they are written (U2). */
146
+ export function pinnedVersions(settings) {
147
+ return commandsIn(settings).flatMap((command) => {
148
+ const plain = plainRun(command);
149
+ const version = plain === undefined ? undefined : pinnedOf(plain.invocation);
150
+ return version === undefined ? [] : [version];
151
+ });
152
+ }
153
+ /**
154
+ * The settings with every agentwhy hook pinned to a release older than `version` pinned to `version` instead (U7): the
155
+ * version in its invocation replaced, everything after the subcommand kept. A newer pin, an unpinned hook, one in any
156
+ * other form and every other key are left as they are.
157
+ */
158
+ export function withHooksPinnedTo(settings, version) {
159
+ const hooks = settings[HOOK_SETTINGS.hooks];
160
+ if (!isJsonObject(hooks) || plainVersion(version) === undefined)
161
+ return { settings, changed: [] };
162
+ const changed = [];
163
+ const next = withCommandsRewritten(hooks, (line, event) => {
164
+ const plain = plainRun(line);
165
+ const from = plain === undefined ? undefined : pinnedOf(plain.invocation);
166
+ if (plain === undefined || from === undefined || !isOlder(from, version))
167
+ return undefined;
168
+ changed.push({ hook: plain.hook, event, from });
169
+ const invocation = plain.invocation.replace(PINNED, (_whole, head) => head + version);
170
+ return invocation + line.slice(line.indexOf(plain.invocation) + plain.invocation.length);
171
+ });
172
+ return { settings: changed.length === 0 ? settings : { ...settings, [HOOK_SETTINGS.hooks]: next }, changed };
173
+ }
174
+ /**
175
+ * The hooks with each command line `rewrite` gives a new line for replaced, and every other command, entry and key as it
176
+ * was - whatever shape they are in. The walk `withHooksPinnedTo` and `withHooksReading` share; they differ in one line.
177
+ */
178
+ function withCommandsRewritten(hooks, rewrite) {
179
+ const next = {};
180
+ for (const [event, list] of Object.entries(hooks)) {
181
+ next[event] = !Array.isArray(list) ? list : list.map((entry) => {
182
+ if (!isJsonObject(entry) || !Array.isArray(entry[HOOK_SETTINGS.commands]))
183
+ return entry;
184
+ return {
185
+ ...entry,
186
+ [HOOK_SETTINGS.commands]: entry[HOOK_SETTINGS.commands].map((command) => {
187
+ if (!isJsonObject(command) || typeof command[HOOK_SETTINGS.command] !== 'string')
188
+ return command;
189
+ const line = rewrite(command[HOOK_SETTINGS.command], event);
190
+ return line === undefined ? command : { ...command, [HOOK_SETTINGS.command]: line };
191
+ }),
192
+ };
193
+ });
194
+ }
195
+ return next;
196
+ }
197
+ /** The settings with the entries added, each as its own item of its event's list. Nothing else is touched. */
198
+ export function withHookEntries(settings, entries) {
199
+ const hooks = isJsonObject(settings[HOOK_SETTINGS.hooks]) ? { ...settings[HOOK_SETTINGS.hooks] } : {};
200
+ for (const entry of entries) {
201
+ const list = Array.isArray(hooks[entry.event]) ? [...hooks[entry.event]] : [];
202
+ list.push({
203
+ ...(entry.matcher === undefined ? {} : { [HOOK_SETTINGS.matcher]: entry.matcher }),
204
+ [HOOK_SETTINGS.commands]: [{ [HOOK_SETTINGS.type]: HOOK_SETTINGS.commandType, [HOOK_SETTINGS.command]: entry.command }],
205
+ });
206
+ hooks[entry.event] = list;
207
+ }
208
+ return { ...settings, [HOOK_SETTINGS.hooks]: hooks };
209
+ }
210
+ /**
211
+ * The settings without the commands that run agentwhy's hooks - all of them, or only those named in `only` (R8, R4b). A matcher entry left with no command is dropped, an
212
+ * event left with no entry is dropped, and `hooks` left empty is dropped; every other key and hook stays as it was.
213
+ */
214
+ export function withoutAgentwhyHooks(settings, invoke, only) {
215
+ const hooks = settings[HOOK_SETTINGS.hooks];
216
+ if (!isJsonObject(hooks))
217
+ return { settings, removed: 0 };
218
+ let removed = 0;
219
+ const kept = {};
220
+ for (const [event, list] of Object.entries(hooks)) {
221
+ if (!Array.isArray(list)) {
222
+ kept[event] = list;
223
+ continue;
224
+ }
225
+ const entries = list.flatMap((entry) => {
226
+ if (!isJsonObject(entry) || !Array.isArray(entry[HOOK_SETTINGS.commands]))
227
+ return [entry];
228
+ const commands = entry[HOOK_SETTINGS.commands].filter((command) => {
229
+ const hook = isJsonObject(command) && typeof command[HOOK_SETTINGS.command] === 'string'
230
+ ? hookRun(command[HOOK_SETTINGS.command], invoke)
231
+ : undefined;
232
+ // `--remove` with a hook named takes out that one; with none, every hook that runs agentwhy (R4b).
233
+ const runs = hook !== undefined && (only === undefined || only.includes(hook));
234
+ if (runs)
235
+ removed += 1;
236
+ return !runs;
237
+ });
238
+ return commands.length === 0 ? [] : [{ ...entry, [HOOK_SETTINGS.commands]: commands }];
239
+ });
240
+ if (entries.length > 0)
241
+ kept[event] = entries;
242
+ }
243
+ const { [HOOK_SETTINGS.hooks]: _dropped, ...rest } = settings;
244
+ return { settings: Object.keys(kept).length === 0 ? rest : { ...rest, [HOOK_SETTINGS.hooks]: kept }, removed };
245
+ }
246
+ const SETTINGS_FLAG = /\s--settings(?:\s+|=)("[^"]*"|'[^']*'|\S+)/;
247
+ export function rulesReadBy(command) {
248
+ if (/\s--policy(?:\s|=)/.test(command))
249
+ return 'policy';
250
+ const named = SETTINGS_FLAG.exec(command)?.[1]?.replace(/^["']|["']$/g, '');
251
+ if (named === undefined)
252
+ return 'default';
253
+ if (named.endsWith(`/${SETTINGS_FILES.directory}/${SETTINGS_FILES.local}`))
254
+ return 'local';
255
+ if (named.endsWith(`/${SETTINGS_FILES.directory}/${SETTINGS_FILES.shared}`))
256
+ return 'shared';
257
+ return 'other';
258
+ }
259
+ /** What each of agentwhy's hooks in this settings object reads; a hook it does not run is absent. */
260
+ export function rulesReadByHooks(settings, invoke) {
261
+ const found = new Map();
262
+ for (const command of commandsIn(settings)) {
263
+ const hook = hookRun(command, invoke);
264
+ if (hook !== undefined && !found.has(hook))
265
+ found.set(hook, rulesReadBy(command));
266
+ }
267
+ return found;
268
+ }
269
+ /**
270
+ * The settings with every agentwhy hook command pointed at `rules` (R6, R4d): the `--settings` it had is replaced, or
271
+ * added where it had none. A command given a policy file is left alone - a policy is a choice somebody made on
272
+ * purpose, and `watch` takes one or the other, not both. Returns the hooks it changed; nothing else is touched.
273
+ */
274
+ export function withHooksReading(settings, rules, invoke) {
275
+ const hooks = settings[HOOK_SETTINGS.hooks];
276
+ if (!isJsonObject(hooks))
277
+ return { settings, changed: [] };
278
+ const flag = ` --settings "${HOOK_SETTINGS.projectDirectory}/${SETTINGS_FILES.directory}/${SETTINGS_FILES[rules]}"`;
279
+ const changed = new Set();
280
+ const next = withCommandsRewritten(hooks, (line) => {
281
+ const hook = hookRun(line, invoke);
282
+ const reads = rulesReadBy(line);
283
+ if (hook === undefined || reads === rules || reads === 'policy')
284
+ return undefined;
285
+ changed.add(hook);
286
+ return line.replace(SETTINGS_FLAG, '') + flag;
287
+ });
288
+ return { settings: changed.size === 0 ? settings : { ...settings, [HOOK_SETTINGS.hooks]: next }, changed: [...changed] };
289
+ }
290
+ function commandsIn(settings) {
291
+ const hooks = settings[HOOK_SETTINGS.hooks];
292
+ if (!isJsonObject(hooks))
293
+ return [];
294
+ return Object.values(hooks).flatMap((list) => commandsInList(list));
295
+ }
296
+ /** Every command one event's list holds, whatever else is in the entries around it. */
297
+ function commandsInList(list) {
298
+ return Array.isArray(list)
299
+ ? list.flatMap((entry) => isJsonObject(entry) && Array.isArray(entry[HOOK_SETTINGS.commands])
300
+ ? entry[HOOK_SETTINGS.commands].flatMap((command) => isJsonObject(command) && typeof command[HOOK_SETTINGS.command] === 'string' ? [command[HOOK_SETTINGS.command]] : [])
301
+ : [])
302
+ : [];
303
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * What an agent's code did, as `event_msg/item_completed` records it: one typed item per action, joined to its turn by
3
+ * `turn_id` and to its agent by `thread_id` in every measured item (§2.3, 2,344 items; §2.8, 33). An item holds both what
4
+ * was asked and what came back, so no join between a call and its result is made (X6). No id joins an item to the
5
+ * `exec` cell that ran it (§2.3, §2.8): an item is attributed to its turn and agent, never to a cell (X14).
6
+ */
7
+ export const ITEM_EVENT = {
8
+ type: 'item_completed',
9
+ turnId: 'turn_id',
10
+ threadId: 'thread_id',
11
+ item: 'item',
12
+ };
13
+ export const ITEM = {
14
+ type: 'type',
15
+ id: 'id',
16
+ status: 'status',
17
+ };
18
+ /**
19
+ * `status` values: `completed` and `failed` (§2.3, every action item type; §2.8). An item recorded without one is
20
+ * recorded as completed by its event, `item_completed` - measured on `ImageView`, the one such action item (§2.8).
21
+ */
22
+ export const ITEM_STATUSES = { completed: 'completed', failed: 'failed' };
23
+ /** Action items the contract names (X6). `Extension` and `ImageView` are named and have no profile: unknown tools. */
24
+ export const ACTION_ITEMS = {
25
+ command: 'CommandExecution',
26
+ fileChange: 'FileChange',
27
+ mcp: 'McpToolCall',
28
+ webSearch: 'WebSearch',
29
+ extension: 'Extension',
30
+ imageView: 'ImageView',
31
+ };
32
+ /**
33
+ * `CommandExecution` (§2.3, 206; §2.8, 8): `command` is `[shell, flag, line]` in all of them; `aggregated_output` is what
34
+ * the process printed, `stdout` included and `stderr` empty in every measured item. Recording it is not delivering it
35
+ * (X10): the model is handed only what the cell emits (§2.8).
36
+ */
37
+ export const COMMAND = {
38
+ command: 'command',
39
+ workingDirectory: 'cwd',
40
+ exitCode: 'exit_code',
41
+ output: 'aggregated_output',
42
+ };
43
+ /** X7: `zsh` measured (206 of 206; 8 of 8); `bash` and `sh` expected and listed by the specification (XB8). */
44
+ export const SHELLS = ['zsh', 'bash', 'sh'];
45
+ /** `-lc` measured in every item; `-c` listed by X7. */
46
+ export const SHELL_FLAGS = ['-lc', '-c'];
47
+ /**
48
+ * Codex's own words where it cut the middle out of a recorded output (XB5, §2.8: 1 of 8, at 1,048,606 characters).
49
+ * Present, the output is `partial`. Absent, it is still not taken to be whole: one build at one cap was measured.
50
+ */
51
+ export const OMISSION_NOTICE = /\.\.\. \d+ bytes omitted \.\.\./;
52
+ /**
53
+ * `FileChange` (§2.3, 221; §2.8, 1): `changes` keyed by path, each with `type` `add` (and `content`), `update` (and
54
+ * `unified_diff`) or `delete`, and an optional `move_path`.
55
+ */
56
+ export const FILE_CHANGE = {
57
+ changes: 'changes',
58
+ kind: 'type',
59
+ content: 'content',
60
+ diff: 'unified_diff',
61
+ movePath: 'move_path',
62
+ };
63
+ export const CHANGE_KINDS = { add: 'add', update: 'update', delete: 'delete' };
64
+ /** `McpToolCall` (§2.3, 121): its result's text fields are not measured, so its output is read as raw text of unknown completeness. */
65
+ export const MCP = { server: 'server', tool: 'tool', arguments: 'arguments', result: 'result' };
66
+ /** `WebSearch` (§2.3, 59): `results[]` fields are not measured (X10); the action is kept as raw input. */
67
+ export const WEB_SEARCH = { action: 'action', results: 'results' };
68
+ /** `ImageView` (§2.8, 1): the image it opened. Written only when the view succeeded; a failed view writes no item. */
69
+ export const IMAGE_VIEW = { path: 'path' };
@@ -0,0 +1,55 @@
1
+ /** Evidence and limits of the contract; support for one subject never grants support for another. */
2
+ export const ASSUMPTIONS = {
3
+ recognition: {
4
+ rule: 'The first line is session_meta with an object payload and string id.',
5
+ measured: '70 of 70 files on 2026-09-29 (spec §2.7) and 7 of 7 terminal sessions (§2.8); recognition is independent of the filename.',
6
+ },
7
+ identity: {
8
+ rule: 'Only the first metadata id owns the file. An id held by several files joins none.',
9
+ measured: '68 unique owners and one duplicate id held by two files on 2026-09-29.',
10
+ },
11
+ project: {
12
+ rule: 'Use the recorded cwd of session_meta and of every turn_context; several are ambiguous, missing data explicit.',
13
+ measured: 'One distinct cwd per file in all 70 measured files; no general invariant is inferred.',
14
+ },
15
+ tree: {
16
+ rule: 'Join recorded parent_thread_id only through unique owners; no timestamp or folder join.',
17
+ measured: '25 child files found their parents in the 2026-09-29 corpus; missing parents and cycles remain unresolved.',
18
+ },
19
+ history: {
20
+ rule: 'Recognise paginated and legacy; preserve unknown modes as a gap.',
21
+ measured: '65 paginated and 5 legacy files by first metadata on 2026-09-29; 7 paginated terminal sessions (§2.8).',
22
+ },
23
+ actions: {
24
+ rule: 'One event per action item, by item.id; a command line only from [shell, -lc|-c, line]; parsed_cmd never read.',
25
+ measured: 'Item joins to turn and thread in every item (§2.3, §2.8). Refused attempts and failed image views leave no item (XB7, XB1), so the action stream is never whole.',
26
+ },
27
+ access: {
28
+ rule: 'A status says a process ran, never what it reached: only a completed write, or one reader that exited 0, or a line of output naming the file.',
29
+ measured: 'A failed cat records its diagnostic in stdout with exit 1 (§2.8); exit codes of other programs are not profiled.',
30
+ },
31
+ delivery: {
32
+ rule: 'The model receives the cell output as a whole, joined to its cell by call_id and to no item; recorded execution output is not delivered by itself.',
33
+ measured: 'XB5 on 0.157.0: forwarded markers are in the cell output, withheld ones only in the item; outputs over 1 MiB are cut with a textual notice only.',
34
+ },
35
+ messages: {
36
+ rule: 'Assistant response messages are canonical; AgentMessage items join them by id; task_complete joins the one final answer of its turn.',
37
+ measured: 'XB10 on 0.157.0 paginated: 15 of 15 id joins, 6 of 6 completion copies, 2 identical texts under distinct ids. Other builds and legacy are unmeasured.',
38
+ },
39
+ delegations: {
40
+ rule: 'spawn_agent joins its agent through SubAgentActivity started by call_id; later words through interacted; reports by agent_path, a name.',
41
+ measured: 'One delegation in each corpus (§2.4, §2.7): provisional, XB4 open.',
42
+ },
43
+ reviews: {
44
+ rule: 'A guardian thread is a review of the parent turn its turns name by root_turn_id; its verdicts are JSON with outcome allow.',
45
+ measured: '52 root-turn references all present (§2.7); 141 of 141 verdicts allow (§2.4). No refusal seen (XB1), no reviewer action (XB9).',
46
+ },
47
+ permissions: {
48
+ rule: 'turn_context records approval, reviewer, sandbox and file-system scopes: recorded settings, not a policy and not a verdict.',
49
+ measured: '469 turns (§2.5), 7 (§2.8). Every entry allows; a granular approval policy is not read.',
50
+ },
51
+ capabilities: {
52
+ rule: 'Capabilities come from the measured matrix by build and history mode; a recognised header grants none.',
53
+ measured: 'XB2, XB5, XB7, XB10 answered for 0.157.0 terminal paginated only; XB1 in part; XB3, XB4, XB6, XB8, XB9 open.',
54
+ },
55
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * `codex exec` 0.157.0, `paginated` (§2.8): XB5 and XB10 answered; XB7 found actions and refused attempts that leave no
3
+ * item, so the action stream is never all of it; XB1 found no typed refusal.
4
+ */
5
+ export const MEASURED_PROFILES = [
6
+ {
7
+ builds: ['0.157.0'],
8
+ historyModes: ['paginated'],
9
+ answers: { actions: 'absent', refusals: 'absent', 'own-words': 'supported', 'output-delivery': 'supported' },
10
+ },
11
+ ];
12
+ /**
13
+ * Every other build of a known mode. `paginated`: items exist, but what escapes them and which message source is
14
+ * canonical are not measured for it. `legacy`: its cells are recorded and nothing they ran is (§2.3, XD4). No build has a
15
+ * typed refusal (§2.5, §2.8).
16
+ */
17
+ export const UNMEASURED_PROFILES = {
18
+ paginated: { actions: 'absent', refusals: 'absent', 'own-words': 'unmeasured', 'output-delivery': 'unmeasured' },
19
+ legacy: { actions: 'absent', access: 'absent', refusals: 'absent', 'own-words': 'unmeasured', 'output-delivery': 'unmeasured' },
20
+ };
21
+ /** A history mode the contract does not list: nothing about it is known (X23, X24). */
22
+ export const UNKNOWN_MODE_ANSWERS = {
23
+ actions: 'unmeasured', access: 'unmeasured', refusals: 'unmeasured', 'own-words': 'unmeasured', 'output-delivery': 'unmeasured',
24
+ };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * An agent the agent chose to start, and what it said to it later (X15-X18; §2.4). Measured on one delegation only
3
+ * (§2.4, §2.7): every join here is by id and leaves the relation unresolved where it breaks. XB4 remains open, so these
4
+ * joins are read and never advertised as measured beyond that sample.
5
+ */
6
+ export const DELEGATION_TOOLS = { spawn: 'spawn_agent', send: 'send_message', followUp: 'followup_task' };
7
+ /** `spawn_agent` arguments (a JSON string): `task_name` and `message` (§2.4). */
8
+ export const SPAWN_ARGUMENTS = { name: 'task_name', message: 'message' };
9
+ /** The `SubAgentActivity` item: `started` answers `spawn_agent`, `interacted` a later call, by `id` = `call_id` (§2.4). */
10
+ export const ACTIVITY = {
11
+ type: 'SubAgentActivity',
12
+ kind: 'kind',
13
+ agentThreadId: 'agent_thread_id',
14
+ kinds: { started: 'started', interacted: 'interacted', completed: 'completed' },
15
+ };
16
+ /** A started agent's own first `session_meta`: `source.subagent.thread_spawn` (§2.4). */
17
+ export const THREAD_SPAWN = {
18
+ source: 'source',
19
+ subagent: 'subagent',
20
+ threadSpawn: 'thread_spawn',
21
+ parentId: 'parent_thread_id',
22
+ depth: 'depth',
23
+ agentPath: 'agent_path',
24
+ role: 'agent_role',
25
+ };
26
+ /**
27
+ * `response_item/agent_message` between agents (§2.4): `author` is an `agent_path` - a name, never an id (X18) - and
28
+ * `content` the words.
29
+ */
30
+ export const AGENT_MESSAGE = { author: 'author', recipient: 'recipient', content: 'content' };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * What the model is handed (XB5, §2.8). The model writes JavaScript into the `exec` tool; the cell's own output,
3
+ * `custom_tool_call_output.output`, is the one thing of it the model receives - a string, or parts whose text is under
4
+ * `input_text` - and it joins its cell by `call_id` (1,250 of 1,250; 17 of 17). No id joins it to the items the cell's
5
+ * code produced, so what it carries is attributed to no action (X10, X14).
6
+ *
7
+ * A direct call is a `function_call`, joined to its `function_call_output` by `call_id` (88 of 88, §2.3); where an item's
8
+ * `id` equals that `call_id` (59 `McpToolCall` items), the item is the action and the output its delivery.
9
+ */
10
+ export const CODE_CELL = {
11
+ tool: 'exec',
12
+ name: 'name',
13
+ code: 'input',
14
+ callId: 'call_id',
15
+ output: 'output',
16
+ partType: 'type',
17
+ partText: 'text',
18
+ textPart: 'input_text',
19
+ };
20
+ export const FUNCTION_CALL = {
21
+ name: 'name',
22
+ callId: 'call_id',
23
+ arguments: 'arguments',
24
+ output: 'output',
25
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The line envelope: `{timestamp, type, payload}`, with `ordinal` on most lines (spec §2.1, 66 files; §2.7, 70; §2.8, 7).
3
+ * Only top-level lines are records (X13): a `compacted` line's nested copies are none.
4
+ */
5
+ export const ENVELOPE = {
6
+ type: 'type',
7
+ payload: 'payload',
8
+ /** When the line was written: display only, never an order or a join (X12, architecture invariant 3). */
9
+ recordedAt: 'timestamp',
10
+ ordinal: 'ordinal',
11
+ /** The discriminator inside a `payload`. */
12
+ payloadType: 'type',
13
+ };
14
+ /** Line types, as `type` spells them (§2.2). */
15
+ export const LINE_TYPES = {
16
+ sessionMeta: 'session_meta',
17
+ turnContext: 'turn_context',
18
+ responseItem: 'response_item',
19
+ event: 'event_msg',
20
+ /** Copies of earlier lines (X13): never records. */
21
+ compacted: 'compacted',
22
+ /** Instructions and environment given to the model; no action and no words of the agent. */
23
+ worldState: 'world_state',
24
+ /** Usage; its `root_turn_id` names a reviewed turn (§2.2). */
25
+ tokenUsage: 'token_usage_record',
26
+ interAgentMetadata: 'inter_agent_communication_metadata',
27
+ };
28
+ /** Line types that carry nothing the report reads: read as known, never as unknown. */
29
+ export const PASSIVE_LINE_TYPES = [LINE_TYPES.compacted, LINE_TYPES.worldState, LINE_TYPES.interAgentMetadata];
30
+ /** `event_msg` payload types that carry nothing the report reads (§2.2). */
31
+ export const PASSIVE_EVENTS = ['token_count', 'thread_settings_applied', 'error'];
32
+ /** `event_msg` payload types only `legacy` files wrote (§2.2: 6 and 9): known labels whose mapping is not measured. */
33
+ export const LEGACY_EVENTS = ['patch_apply_end', 'web_search_end'];
@@ -0,0 +1,14 @@
1
+ /**
2
+ * A command a `PreToolUse` hook refused (`codex-blocks-too` CKB3, CKB7, CKB11): it never runs, so no item records it, and
3
+ * the one trace is text in the code cell's output - "Script error:\nCommand blocked by PreToolUse hook: <reason>.
4
+ * Command: <line>". Measured on 0.159.2 (the terminal app and `codex exec`) and `codex exec` 0.155.0-alpha.16.3. No field
5
+ * types it (XB1): only a reason agentwhy wrote itself is read as a refusal, since its words are agentwhy's and not Codex's.
6
+ */
7
+ export const HOOK_REFUSAL = {
8
+ /** Codex's words before a hook's reason. */
9
+ blocked: 'Command blocked by PreToolUse hook: ',
10
+ /** Codex's words between the reason and the refused line. */
11
+ command: '. Command: ',
12
+ /** The kind a refusal read from agentwhy's own reason is recorded with. */
13
+ denialKind: 'agentwhy refuse',
14
+ };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * A project's Codex hooks (`specs/2026-09-30-codex-blocks-too.md` CKB4): `<project>/.codex/hooks.json`, in the shape
3
+ * `{"hooks": {"PreToolUse": [{"matcher": "Bash", "hooks": [{"type": "command", "command": "…"}]}]}}`. Measured on 0.159.2:
4
+ * read only in a project Codex trusts, and a hook in it runs only once a person has approved it in Codex (CKB5).
5
+ */
6
+ export const PROJECT_HOOKS = {
7
+ directory: '.codex',
8
+ file: 'hooks.json',
9
+ hooks: 'hooks',
10
+ matcher: 'matcher',
11
+ /** An entry's list of commands, under the same key as the file's top-level object. */
12
+ commands: 'hooks',
13
+ type: 'type',
14
+ commandType: 'command',
15
+ command: 'command',
16
+ };
17
+ /**
18
+ * What a `PreToolUse` hook is handed for a shell command (CKB2), measured on 0.159.2: `hook_event_name` `PreToolUse`,
19
+ * `tool_name` `Bash`, `tool_input` `{"command": "<line>"}` - the line alone, not the rollout's `[shell, flag, line]` - and
20
+ * `cwd`, the session's folder, which can lie below the project (CKB6). The input also holds `model`, `permission_mode`,
21
+ * `session_id`, `tool_use_id`, `transcript_path` and `turn_id`, none of which `refuse` reads. Exit 2 with a reason on
22
+ * standard error refuses the call (CKB3).
23
+ */
24
+ export const PRE_TOOL_USE = {
25
+ event: 'PreToolUse',
26
+ fields: {
27
+ event: 'hook_event_name',
28
+ toolName: 'tool_name',
29
+ toolInput: 'tool_input',
30
+ /** Inside `tool_input` for the shell tool. */
31
+ command: 'command',
32
+ cwd: 'cwd',
33
+ },
34
+ /** The shell tool, and the matcher a hook for it is written with. */
35
+ shellTool: 'Bash',
36
+ };
37
+ /** A completed Codex turn, measured with `codex exec` 0.159.2. Its transcript path can be absent (ephemeral runs). */
38
+ export const STOP = {
39
+ event: 'Stop',
40
+ fields: {
41
+ event: 'hook_event_name',
42
+ active: 'stop_hook_active',
43
+ turnId: 'turn_id',
44
+ transcriptPath: 'transcript_path',
45
+ },
46
+ };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The agent's own words and the words it was given (X31; XB10, §2.8). Measured for `codex exec` 0.157.0 `paginated`:
3
+ * assistant text is `response_item/message` with role `assistant`, content `output_text` and a `phase`; an `AgentMessage`
4
+ * item with the same `id` is a copy of it (15 of 15); `task_complete.last_agent_message` is a copy of the turn's final
5
+ * answer, with no id of its own (6 of 6). Two messages with identical text and different ids are two (2 pairs).
6
+ */
7
+ export const RESPONSE_ITEMS = {
8
+ message: 'message',
9
+ reasoning: 'reasoning',
10
+ codeCell: 'custom_tool_call',
11
+ codeCellOutput: 'custom_tool_call_output',
12
+ functionCall: 'function_call',
13
+ functionOutput: 'function_call_output',
14
+ agentMessage: 'agent_message',
15
+ compaction: 'compaction',
16
+ };
17
+ export const MESSAGE = {
18
+ id: 'id',
19
+ role: 'role',
20
+ content: 'content',
21
+ phase: 'phase',
22
+ blockType: 'type',
23
+ blockText: 'text',
24
+ };
25
+ export const ROLES = { assistant: 'assistant', user: 'user', developer: 'developer' };
26
+ /** Content block types: `output_text` on assistant messages, `input_text` on the others (§2.2, §2.8). */
27
+ export const TEXT_BLOCKS = { said: 'output_text', given: 'input_text' };
28
+ /** `phase` on assistant messages and `AgentMessage` items (§2.8): what the core calls a channel. */
29
+ export const PHASES = { commentary: 'commentary', final_answer: 'final' };
30
+ /** Message items (§2.3): copies of response records, joined by `id` where one is (§2.8). */
31
+ export const MESSAGE_ITEMS = {
32
+ agent: 'AgentMessage',
33
+ user: 'UserMessage',
34
+ reasoning: 'Reasoning',
35
+ compaction: 'ContextCompaction',
36
+ functionOutput: 'FunctionCallOutput',
37
+ };
38
+ /** An `AgentMessage` or `UserMessage` item's content blocks: `Text` and `text` (§2.8). */
39
+ export const ITEM_TEXT_BLOCKS = ['Text', 'text'];
40
+ /**
41
+ * Reasoning: `encrypted_content` on every measured record, and readable `summary[].text` on some (§2.2: 163 parts); none
42
+ * readable in §2.8. A `Reasoning` item joins its record by `id` (1 of 1) with its own `summary_text` and `raw_content`.
43
+ */
44
+ export const REASONING = { encrypted: 'encrypted_content', summary: 'summary', summaryText: 'text' };
45
+ export const REASONING_ITEM = { summary: 'summary_text', raw: 'raw_content' };
46
+ /** Event copies the editor builds of §2.2 wrote (22 and 34 lines); no source rule is measured for them. */
47
+ export const EVENT_MESSAGES = { user: 'user_message', agent: 'agent_message', text: 'message' };