@intentic/sandbox-contract 1.232.0 → 1.234.0

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 (538) hide show
  1. package/README.md +11 -5
  2. package/dist/agent-catalog.d.ts +4 -2
  3. package/dist/agent-catalog.d.ts.map +1 -1
  4. package/dist/agent-catalog.js +20 -14
  5. package/dist/agent-catalog.js.map +1 -1
  6. package/dist/chores/chores.d.ts +1 -1
  7. package/dist/chores/chores.d.ts.map +1 -1
  8. package/dist/chores/chores.js +36 -1
  9. package/dist/chores/chores.js.map +1 -1
  10. package/dist/chores/probes.d.ts +1 -1
  11. package/dist/chores/probes.d.ts.map +1 -1
  12. package/dist/chores/probes.js +70 -0
  13. package/dist/chores/probes.js.map +1 -1
  14. package/dist/chores/stack.d.ts.map +1 -1
  15. package/dist/chores/stack.js +2 -1
  16. package/dist/chores/stack.js.map +1 -1
  17. package/dist/chores/verdict.d.ts +1 -1
  18. package/dist/chores/verdict.d.ts.map +1 -1
  19. package/dist/command-classes.d.ts +17 -0
  20. package/dist/command-classes.d.ts.map +1 -0
  21. package/dist/command-classes.js +189 -0
  22. package/dist/command-classes.js.map +1 -0
  23. package/dist/contracts/activity.contract.js +1 -1
  24. package/dist/contracts/activity.contract.js.map +1 -1
  25. package/dist/contracts/agent.contract.d.ts +40 -2
  26. package/dist/contracts/agent.contract.d.ts.map +1 -1
  27. package/dist/contracts/agent.contract.js +4 -1
  28. package/dist/contracts/agent.contract.js.map +1 -1
  29. package/dist/contracts/agents.contract.d.ts +24 -0
  30. package/dist/contracts/agents.contract.d.ts.map +1 -1
  31. package/dist/contracts/agents.contract.js +5 -1
  32. package/dist/contracts/agents.contract.js.map +1 -1
  33. package/dist/contracts/automations.contract.d.ts +30 -0
  34. package/dist/contracts/automations.contract.d.ts.map +1 -1
  35. package/dist/contracts/automations.contract.js +2 -1
  36. package/dist/contracts/automations.contract.js.map +1 -1
  37. package/dist/contracts/capabilities.contract.d.ts +63 -0
  38. package/dist/contracts/capabilities.contract.d.ts.map +1 -1
  39. package/dist/contracts/capabilities.contract.js +3 -1
  40. package/dist/contracts/capabilities.contract.js.map +1 -1
  41. package/dist/contracts/chores.contract.d.ts +17 -0
  42. package/dist/contracts/chores.contract.d.ts.map +1 -1
  43. package/dist/contracts/chores.contract.js +2 -1
  44. package/dist/contracts/chores.contract.js.map +1 -1
  45. package/dist/contracts/ci.contract.js +2 -1
  46. package/dist/contracts/ci.contract.js.map +1 -1
  47. package/dist/contracts/claude.contract.js +2 -1
  48. package/dist/contracts/claude.contract.js.map +1 -1
  49. package/dist/contracts/cursor.contract.js +2 -1
  50. package/dist/contracts/cursor.contract.js.map +1 -1
  51. package/dist/contracts/drafts.contract.d.ts.map +1 -1
  52. package/dist/contracts/drafts.contract.js +2 -1
  53. package/dist/contracts/drafts.contract.js.map +1 -1
  54. package/dist/contracts/endpoints.contract.d.ts.map +1 -1
  55. package/dist/contracts/endpoints.contract.js +2 -1
  56. package/dist/contracts/endpoints.contract.js.map +1 -1
  57. package/dist/contracts/exit.contract.d.ts.map +1 -1
  58. package/dist/contracts/exit.contract.js +2 -1
  59. package/dist/contracts/exit.contract.js.map +1 -1
  60. package/dist/contracts/extensions.contract.d.ts +44 -0
  61. package/dist/contracts/extensions.contract.d.ts.map +1 -1
  62. package/dist/contracts/extensions.contract.js +4 -1
  63. package/dist/contracts/extensions.contract.js.map +1 -1
  64. package/dist/contracts/git.contract.d.ts.map +1 -1
  65. package/dist/contracts/git.contract.js +4 -1
  66. package/dist/contracts/git.contract.js.map +1 -1
  67. package/dist/contracts/grok.contract.d.ts.map +1 -1
  68. package/dist/contracts/grok.contract.js +2 -1
  69. package/dist/contracts/grok.contract.js.map +1 -1
  70. package/dist/contracts/history.contract.d.ts.map +1 -1
  71. package/dist/contracts/history.contract.js +2 -1
  72. package/dist/contracts/history.contract.js.map +1 -1
  73. package/dist/contracts/host.contract.d.ts +7 -0
  74. package/dist/contracts/host.contract.d.ts.map +1 -1
  75. package/dist/contracts/host.contract.js +4 -1
  76. package/dist/contracts/host.contract.js.map +1 -1
  77. package/dist/contracts/intentic.contract.d.ts.map +1 -1
  78. package/dist/contracts/intentic.contract.js +2 -1
  79. package/dist/contracts/intentic.contract.js.map +1 -1
  80. package/dist/contracts/inventory.contract.js +1 -1
  81. package/dist/contracts/inventory.contract.js.map +1 -1
  82. package/dist/contracts/issues.contract.d.ts +89 -0
  83. package/dist/contracts/issues.contract.d.ts.map +1 -0
  84. package/dist/contracts/issues.contract.js +50 -0
  85. package/dist/contracts/issues.contract.js.map +1 -0
  86. package/dist/contracts/logs.contract.d.ts.map +1 -1
  87. package/dist/contracts/logs.contract.js +1 -1
  88. package/dist/contracts/logs.contract.js.map +1 -1
  89. package/dist/contracts/loops.contract.js +2 -1
  90. package/dist/contracts/loops.contract.js.map +1 -1
  91. package/dist/contracts/panels.contract.d.ts.map +1 -1
  92. package/dist/contracts/panels.contract.js +2 -1
  93. package/dist/contracts/panels.contract.js.map +1 -1
  94. package/dist/contracts/personas.contract.js +2 -1
  95. package/dist/contracts/personas.contract.js.map +1 -1
  96. package/dist/contracts/ports.contract.d.ts.map +1 -1
  97. package/dist/contracts/ports.contract.js +2 -1
  98. package/dist/contracts/ports.contract.js.map +1 -1
  99. package/dist/contracts/prepush.contract.d.ts.map +1 -1
  100. package/dist/contracts/prepush.contract.js +2 -1
  101. package/dist/contracts/prepush.contract.js.map +1 -1
  102. package/dist/contracts/providers.contract.d.ts.map +1 -1
  103. package/dist/contracts/providers.contract.js +2 -1
  104. package/dist/contracts/providers.contract.js.map +1 -1
  105. package/dist/contracts/public.contract.d.ts.map +1 -1
  106. package/dist/contracts/public.contract.js +2 -1
  107. package/dist/contracts/public.contract.js.map +1 -1
  108. package/dist/contracts/push.contract.d.ts.map +1 -1
  109. package/dist/contracts/push.contract.js +2 -1
  110. package/dist/contracts/push.contract.js.map +1 -1
  111. package/dist/contracts/runner.contract.d.ts +127 -84
  112. package/dist/contracts/runner.contract.d.ts.map +1 -1
  113. package/dist/contracts/runner.contract.js +10 -2
  114. package/dist/contracts/runner.contract.js.map +1 -1
  115. package/dist/contracts/secrets.contract.d.ts.map +1 -1
  116. package/dist/contracts/secrets.contract.js +2 -1
  117. package/dist/contracts/secrets.contract.js.map +1 -1
  118. package/dist/contracts/sessions.contract.js +1 -1
  119. package/dist/contracts/sessions.contract.js.map +1 -1
  120. package/dist/contracts/settings.contract.d.ts +32 -0
  121. package/dist/contracts/settings.contract.d.ts.map +1 -1
  122. package/dist/contracts/settings.contract.js +3 -1
  123. package/dist/contracts/settings.contract.js.map +1 -1
  124. package/dist/contracts/share.contract.d.ts.map +1 -1
  125. package/dist/contracts/share.contract.js +2 -1
  126. package/dist/contracts/share.contract.js.map +1 -1
  127. package/dist/contracts/skills.contract.d.ts.map +1 -1
  128. package/dist/contracts/skills.contract.js +2 -1
  129. package/dist/contracts/skills.contract.js.map +1 -1
  130. package/dist/contracts/system.contract.d.ts +31 -16
  131. package/dist/contracts/system.contract.d.ts.map +1 -1
  132. package/dist/contracts/system.contract.js +6 -1
  133. package/dist/contracts/system.contract.js.map +1 -1
  134. package/dist/contracts/translator.contract.d.ts.map +1 -1
  135. package/dist/contracts/translator.contract.js +4 -1
  136. package/dist/contracts/translator.contract.js.map +1 -1
  137. package/dist/contracts/usage.contract.js +1 -1
  138. package/dist/contracts/usage.contract.js.map +1 -1
  139. package/dist/contracts/vpn.contract.d.ts.map +1 -1
  140. package/dist/contracts/vpn.contract.js +2 -1
  141. package/dist/contracts/vpn.contract.js.map +1 -1
  142. package/dist/contracts/webext.contract.d.ts +45 -0
  143. package/dist/contracts/webext.contract.d.ts.map +1 -0
  144. package/dist/contracts/webext.contract.js +12 -0
  145. package/dist/contracts/webext.contract.js.map +1 -0
  146. package/dist/contracts/workflows.contract.js +2 -1
  147. package/dist/contracts/workflows.contract.js.map +1 -1
  148. package/dist/contracts/workspace.contract.d.ts +2 -2
  149. package/dist/contracts/workspace.contract.d.ts.map +1 -1
  150. package/dist/contracts/workspace.contract.js +7 -1
  151. package/dist/contracts/workspace.contract.js.map +1 -1
  152. package/dist/credential-material.d.ts +2 -0
  153. package/dist/credential-material.d.ts.map +1 -0
  154. package/dist/credential-material.js +36 -0
  155. package/dist/credential-material.js.map +1 -0
  156. package/dist/definition-action.d.ts +7 -0
  157. package/dist/definition-action.d.ts.map +1 -0
  158. package/dist/definition-action.js +3 -0
  159. package/dist/definition-action.js.map +1 -0
  160. package/dist/definition.d.ts +132 -21
  161. package/dist/definition.d.ts.map +1 -1
  162. package/dist/definition.js +29 -7
  163. package/dist/definition.js.map +1 -1
  164. package/dist/events.d.ts +101 -0
  165. package/dist/events.d.ts.map +1 -1
  166. package/dist/events.js +25 -1
  167. package/dist/events.js.map +1 -1
  168. package/dist/fast-tier.d.ts +1 -1
  169. package/dist/fast-tier.d.ts.map +1 -1
  170. package/dist/history-state.d.ts.map +1 -1
  171. package/dist/history-state.js +2 -0
  172. package/dist/history-state.js.map +1 -1
  173. package/dist/hostnames.d.ts +2 -0
  174. package/dist/hostnames.d.ts.map +1 -1
  175. package/dist/hostnames.js +3 -1
  176. package/dist/hostnames.js.map +1 -1
  177. package/dist/index.d.ts +411 -7
  178. package/dist/index.d.ts.map +1 -1
  179. package/dist/index.js +56 -1
  180. package/dist/index.js.map +1 -1
  181. package/dist/listener-protocol.js +1 -1
  182. package/dist/listener-protocol.js.map +1 -1
  183. package/dist/quick-model.d.ts +1 -1
  184. package/dist/quick-model.d.ts.map +1 -1
  185. package/dist/runner-protocol.d.ts +18 -0
  186. package/dist/runner-protocol.d.ts.map +1 -1
  187. package/dist/runner-protocol.js +8 -4
  188. package/dist/runner-protocol.js.map +1 -1
  189. package/dist/runtime-state.d.ts +9 -0
  190. package/dist/runtime-state.d.ts.map +1 -1
  191. package/dist/runtime-state.js +3 -0
  192. package/dist/runtime-state.js.map +1 -1
  193. package/dist/schemas/activity.d.ts +112 -0
  194. package/dist/schemas/activity.d.ts.map +1 -0
  195. package/dist/schemas/activity.js +70 -0
  196. package/dist/schemas/activity.js.map +1 -0
  197. package/dist/schemas/agent.d.ts +195 -0
  198. package/dist/schemas/agent.d.ts.map +1 -0
  199. package/dist/schemas/agent.js +171 -0
  200. package/dist/schemas/agent.js.map +1 -0
  201. package/dist/schemas/agents.d.ts +690 -0
  202. package/dist/schemas/agents.d.ts.map +1 -0
  203. package/dist/schemas/agents.js +314 -0
  204. package/dist/schemas/agents.js.map +1 -0
  205. package/dist/schemas/automations.d.ts +781 -0
  206. package/dist/schemas/automations.d.ts.map +1 -0
  207. package/dist/schemas/automations.js +223 -0
  208. package/dist/schemas/automations.js.map +1 -0
  209. package/dist/schemas/capabilities.d.ts +753 -0
  210. package/dist/schemas/capabilities.d.ts.map +1 -0
  211. package/dist/schemas/capabilities.js +269 -0
  212. package/dist/schemas/capabilities.js.map +1 -0
  213. package/dist/schemas/ci.d.ts +179 -0
  214. package/dist/schemas/ci.d.ts.map +1 -0
  215. package/dist/schemas/ci.js +99 -0
  216. package/dist/schemas/ci.js.map +1 -0
  217. package/dist/schemas/claude-gate.d.ts +13 -0
  218. package/dist/schemas/claude-gate.d.ts.map +1 -0
  219. package/dist/schemas/claude-gate.js +8 -0
  220. package/dist/schemas/claude-gate.js.map +1 -0
  221. package/dist/schemas/codebase-health.d.ts +56 -0
  222. package/dist/schemas/codebase-health.d.ts.map +1 -0
  223. package/dist/schemas/codebase-health.js +43 -0
  224. package/dist/schemas/codebase-health.js.map +1 -0
  225. package/dist/schemas/computers.d.ts +386 -0
  226. package/dist/schemas/computers.d.ts.map +1 -0
  227. package/dist/schemas/computers.js +107 -0
  228. package/dist/schemas/computers.js.map +1 -0
  229. package/dist/schemas/drafts.d.ts +84 -0
  230. package/dist/schemas/drafts.d.ts.map +1 -0
  231. package/dist/schemas/drafts.js +44 -0
  232. package/dist/schemas/drafts.js.map +1 -0
  233. package/dist/schemas/environment.d.ts +349 -0
  234. package/dist/schemas/environment.d.ts.map +1 -0
  235. package/dist/schemas/environment.js +111 -0
  236. package/dist/schemas/environment.js.map +1 -0
  237. package/dist/schemas/exit.d.ts +151 -0
  238. package/dist/schemas/exit.d.ts.map +1 -0
  239. package/dist/schemas/exit.js +115 -0
  240. package/dist/schemas/exit.js.map +1 -0
  241. package/dist/schemas/extension-updates.d.ts +1016 -0
  242. package/dist/schemas/extension-updates.d.ts.map +1 -0
  243. package/dist/schemas/extension-updates.js +199 -0
  244. package/dist/schemas/extension-updates.js.map +1 -0
  245. package/dist/schemas/fast-mode.d.ts +8 -0
  246. package/dist/schemas/fast-mode.d.ts.map +1 -0
  247. package/dist/schemas/fast-mode.js +3 -0
  248. package/dist/schemas/fast-mode.js.map +1 -0
  249. package/dist/schemas/git-history.d.ts +238 -0
  250. package/dist/schemas/git-history.d.ts.map +1 -0
  251. package/dist/schemas/git-history.js +152 -0
  252. package/dist/schemas/git-history.js.map +1 -0
  253. package/dist/schemas/git.d.ts +471 -0
  254. package/dist/schemas/git.d.ts.map +1 -0
  255. package/dist/schemas/git.js +204 -0
  256. package/dist/schemas/git.js.map +1 -0
  257. package/dist/schemas/history.d.ts +100 -0
  258. package/dist/schemas/history.d.ts.map +1 -0
  259. package/dist/schemas/history.js +54 -0
  260. package/dist/schemas/history.js.map +1 -0
  261. package/dist/schemas/hosts.d.ts +41 -0
  262. package/dist/schemas/hosts.d.ts.map +1 -0
  263. package/dist/schemas/hosts.js +18 -0
  264. package/dist/schemas/hosts.js.map +1 -0
  265. package/dist/schemas/intentic.d.ts +5 -0
  266. package/dist/schemas/intentic.d.ts.map +1 -0
  267. package/dist/schemas/intentic.js +3 -0
  268. package/dist/schemas/intentic.js.map +1 -0
  269. package/dist/schemas/internal.d.ts +8 -0
  270. package/dist/schemas/internal.d.ts.map +1 -0
  271. package/dist/schemas/internal.js +12 -0
  272. package/dist/schemas/internal.js.map +1 -0
  273. package/dist/schemas/inventory.d.ts +171 -0
  274. package/dist/schemas/inventory.d.ts.map +1 -0
  275. package/dist/schemas/inventory.js +51 -0
  276. package/dist/schemas/inventory.js.map +1 -0
  277. package/dist/schemas/issues.d.ts +324 -0
  278. package/dist/schemas/issues.d.ts.map +1 -0
  279. package/dist/schemas/issues.js +107 -0
  280. package/dist/schemas/issues.js.map +1 -0
  281. package/dist/schemas/logs.d.ts +67 -0
  282. package/dist/schemas/logs.d.ts.map +1 -0
  283. package/dist/schemas/logs.js +54 -0
  284. package/dist/schemas/logs.js.map +1 -0
  285. package/dist/schemas/loops.d.ts +415 -0
  286. package/dist/schemas/loops.d.ts.map +1 -0
  287. package/dist/schemas/loops.js +188 -0
  288. package/dist/schemas/loops.js.map +1 -0
  289. package/dist/schemas/maintenance.d.ts +618 -0
  290. package/dist/schemas/maintenance.d.ts.map +1 -0
  291. package/dist/schemas/maintenance.js +222 -0
  292. package/dist/schemas/maintenance.js.map +1 -0
  293. package/dist/schemas/marketplace.d.ts +64 -0
  294. package/dist/schemas/marketplace.d.ts.map +1 -0
  295. package/dist/schemas/marketplace.js +17 -0
  296. package/dist/schemas/marketplace.js.map +1 -0
  297. package/dist/schemas/panels.d.ts +61 -0
  298. package/dist/schemas/panels.d.ts.map +1 -0
  299. package/dist/schemas/panels.js +51 -0
  300. package/dist/schemas/panels.js.map +1 -0
  301. package/dist/schemas/personas.d.ts +122 -0
  302. package/dist/schemas/personas.d.ts.map +1 -0
  303. package/dist/schemas/personas.js +102 -0
  304. package/dist/schemas/personas.js.map +1 -0
  305. package/dist/schemas/plan-limits.d.ts +172 -0
  306. package/dist/schemas/plan-limits.d.ts.map +1 -0
  307. package/dist/schemas/plan-limits.js +126 -0
  308. package/dist/schemas/plan-limits.js.map +1 -0
  309. package/dist/schemas/ports.d.ts +71 -0
  310. package/dist/schemas/ports.d.ts.map +1 -0
  311. package/dist/schemas/ports.js +42 -0
  312. package/dist/schemas/ports.js.map +1 -0
  313. package/dist/schemas/provider-oauth.d.ts +128 -0
  314. package/dist/schemas/provider-oauth.d.ts.map +1 -0
  315. package/dist/schemas/provider-oauth.js +91 -0
  316. package/dist/schemas/provider-oauth.js.map +1 -0
  317. package/dist/schemas/provider-subscriptions.d.ts +9 -0
  318. package/dist/schemas/provider-subscriptions.d.ts.map +1 -0
  319. package/dist/schemas/provider-subscriptions.js +3 -0
  320. package/dist/schemas/provider-subscriptions.js.map +1 -0
  321. package/dist/schemas/public.d.ts +32 -0
  322. package/dist/schemas/public.d.ts.map +1 -0
  323. package/dist/schemas/public.js +29 -0
  324. package/dist/schemas/public.js.map +1 -0
  325. package/dist/schemas/push.d.ts +55 -0
  326. package/dist/schemas/push.d.ts.map +1 -0
  327. package/dist/schemas/push.js +60 -0
  328. package/dist/schemas/push.js.map +1 -0
  329. package/dist/schemas/secrets.d.ts +86 -0
  330. package/dist/schemas/secrets.d.ts.map +1 -0
  331. package/dist/schemas/secrets.js +51 -0
  332. package/dist/schemas/secrets.js.map +1 -0
  333. package/dist/schemas/sessions.d.ts +32 -0
  334. package/dist/schemas/sessions.d.ts.map +1 -0
  335. package/dist/schemas/sessions.js +11 -0
  336. package/dist/schemas/sessions.js.map +1 -0
  337. package/dist/schemas/settings.d.ts +554 -0
  338. package/dist/schemas/settings.d.ts.map +1 -0
  339. package/dist/schemas/settings.js +263 -0
  340. package/dist/schemas/settings.js.map +1 -0
  341. package/dist/schemas/share.d.ts +49 -0
  342. package/dist/schemas/share.d.ts.map +1 -0
  343. package/dist/schemas/share.js +26 -0
  344. package/dist/schemas/share.js.map +1 -0
  345. package/dist/schemas/shared.d.ts +22 -0
  346. package/dist/schemas/shared.d.ts.map +1 -0
  347. package/dist/schemas/shared.js +16 -0
  348. package/dist/schemas/shared.js.map +1 -0
  349. package/dist/schemas/system.d.ts +86 -0
  350. package/dist/schemas/system.d.ts.map +1 -0
  351. package/dist/schemas/system.js +64 -0
  352. package/dist/schemas/system.js.map +1 -0
  353. package/dist/schemas/terminal.d.ts +230 -0
  354. package/dist/schemas/terminal.d.ts.map +1 -0
  355. package/dist/schemas/terminal.js +133 -0
  356. package/dist/schemas/terminal.js.map +1 -0
  357. package/dist/schemas/usage.d.ts +113 -0
  358. package/dist/schemas/usage.d.ts.map +1 -0
  359. package/dist/schemas/usage.js +91 -0
  360. package/dist/schemas/usage.js.map +1 -0
  361. package/dist/schemas/vpn.d.ts +229 -0
  362. package/dist/schemas/vpn.d.ts.map +1 -0
  363. package/dist/schemas/vpn.js +115 -0
  364. package/dist/schemas/vpn.js.map +1 -0
  365. package/dist/schemas/webext.d.ts +122 -0
  366. package/dist/schemas/webext.d.ts.map +1 -0
  367. package/dist/schemas/webext.js +45 -0
  368. package/dist/schemas/webext.js.map +1 -0
  369. package/dist/schemas/workflows.d.ts +881 -0
  370. package/dist/schemas/workflows.d.ts.map +1 -0
  371. package/dist/schemas/workflows.js +164 -0
  372. package/dist/schemas/workflows.js.map +1 -0
  373. package/dist/schemas/workspace-repos.d.ts +143 -0
  374. package/dist/schemas/workspace-repos.d.ts.map +1 -0
  375. package/dist/schemas/workspace-repos.js +87 -0
  376. package/dist/schemas/workspace-repos.js.map +1 -0
  377. package/dist/schemas/workspace-search.d.ts +170 -0
  378. package/dist/schemas/workspace-search.d.ts.map +1 -0
  379. package/dist/schemas/workspace-search.js +85 -0
  380. package/dist/schemas/workspace-search.js.map +1 -0
  381. package/dist/schemas/workspace-setup.d.ts +48 -0
  382. package/dist/schemas/workspace-setup.d.ts.map +1 -0
  383. package/dist/schemas/workspace-setup.js +26 -0
  384. package/dist/schemas/workspace-setup.js.map +1 -0
  385. package/dist/schemas/workspace-tree.d.ts +120 -0
  386. package/dist/schemas/workspace-tree.d.ts.map +1 -0
  387. package/dist/schemas/workspace-tree.js +111 -0
  388. package/dist/schemas/workspace-tree.js.map +1 -0
  389. package/dist/webext-links.d.ts +14 -0
  390. package/dist/webext-links.d.ts.map +1 -0
  391. package/dist/webext-links.js +25 -0
  392. package/dist/webext-links.js.map +1 -0
  393. package/dist/webext-protocol.d.ts +8 -0
  394. package/dist/webext-protocol.d.ts.map +1 -0
  395. package/dist/webext-protocol.js +7 -0
  396. package/dist/webext-protocol.js.map +1 -0
  397. package/dist/workflow-faults.d.ts +1 -1
  398. package/dist/workflow-faults.d.ts.map +1 -1
  399. package/dist/workspace-state.d.ts +12 -8
  400. package/dist/workspace-state.d.ts.map +1 -1
  401. package/dist/workspace-state.js +15 -10
  402. package/dist/workspace-state.js.map +1 -1
  403. package/package.json +19 -8
  404. package/src/agent-catalog.test.ts +56 -55
  405. package/src/agent-catalog.ts +33 -33
  406. package/src/capability-ledger.test.ts +11 -2
  407. package/src/chores/chores.test.ts +1 -1
  408. package/src/chores/chores.ts +67 -2
  409. package/src/chores/probes.test.ts +65 -0
  410. package/src/chores/probes.ts +133 -1
  411. package/src/chores/stack.test.ts +19 -0
  412. package/src/chores/stack.ts +19 -3
  413. package/src/chores/verdict.test.ts +40 -20
  414. package/src/chores/verdict.ts +1 -1
  415. package/src/command-classes.test.ts +445 -0
  416. package/src/command-classes.ts +468 -0
  417. package/src/contracts/activity.contract.ts +1 -1
  418. package/src/contracts/agent.contract.ts +4 -13
  419. package/src/contracts/agents.contract.ts +6 -6
  420. package/src/contracts/automations.contract.ts +2 -2
  421. package/src/contracts/capabilities.contract.ts +3 -4
  422. package/src/contracts/chores.contract.ts +2 -1
  423. package/src/contracts/ci.contract.ts +2 -2
  424. package/src/contracts/claude.contract.ts +2 -2
  425. package/src/contracts/cursor.contract.ts +2 -2
  426. package/src/contracts/drafts.contract.ts +2 -1
  427. package/src/contracts/endpoints.contract.ts +2 -1
  428. package/src/contracts/exit.contract.ts +2 -1
  429. package/src/contracts/extensions.contract.ts +8 -7
  430. package/src/contracts/git.contract.ts +19 -18
  431. package/src/contracts/grok.contract.ts +2 -1
  432. package/src/contracts/history.contract.ts +2 -1
  433. package/src/contracts/host.contract.ts +4 -1
  434. package/src/contracts/intentic.contract.ts +2 -1
  435. package/src/contracts/inventory.contract.ts +1 -1
  436. package/src/contracts/issues.contract.ts +60 -0
  437. package/src/contracts/logs.contract.ts +7 -1
  438. package/src/contracts/loops.contract.ts +2 -2
  439. package/src/contracts/panels.contract.ts +2 -1
  440. package/src/contracts/personas.contract.ts +3 -3
  441. package/src/contracts/ports.contract.ts +3 -2
  442. package/src/contracts/prepush.contract.ts +2 -1
  443. package/src/contracts/providers.contract.ts +2 -1
  444. package/src/contracts/public.contract.ts +3 -2
  445. package/src/contracts/push.contract.ts +2 -1
  446. package/src/contracts/runner.contract.ts +18 -2
  447. package/src/contracts/secrets.contract.ts +2 -1
  448. package/src/contracts/sessions.contract.ts +1 -1
  449. package/src/contracts/settings.contract.ts +3 -9
  450. package/src/contracts/share.contract.ts +3 -2
  451. package/src/contracts/skills.contract.ts +2 -1
  452. package/src/contracts/system.contract.ts +6 -9
  453. package/src/contracts/translator.contract.ts +4 -1
  454. package/src/contracts/usage.contract.ts +1 -1
  455. package/src/contracts/vpn.contract.ts +2 -8
  456. package/src/contracts/webext.contract.ts +37 -0
  457. package/src/contracts/workflows.contract.ts +2 -2
  458. package/src/contracts/workspace.contract.ts +10 -12
  459. package/src/conversation-ids.test.ts +1 -1
  460. package/src/credential-material.test.ts +120 -0
  461. package/src/credential-material.ts +100 -0
  462. package/src/definition-action.ts +8 -0
  463. package/src/definition.ts +74 -10
  464. package/src/events.ts +84 -22
  465. package/src/fast-tier.ts +1 -1
  466. package/src/history-state.ts +17 -0
  467. package/src/host-protocol.ts +1 -1
  468. package/src/hostnames.test.ts +2 -2
  469. package/src/hostnames.ts +18 -2
  470. package/src/index.ts +65 -1
  471. package/src/listener-protocol.ts +1 -1
  472. package/src/quick-model.ts +1 -1
  473. package/src/routes.test.ts +4 -2
  474. package/src/runner-protocol.ts +35 -5
  475. package/src/runtime-state.ts +16 -0
  476. package/src/schemas/activity.ts +123 -0
  477. package/src/schemas/agent.ts +422 -0
  478. package/src/schemas/agents.ts +802 -0
  479. package/src/schemas/automations.ts +522 -0
  480. package/src/schemas/capabilities.ts +729 -0
  481. package/src/schemas/ci.ts +235 -0
  482. package/src/schemas/claude-gate.ts +13 -0
  483. package/src/schemas/codebase-health.ts +64 -0
  484. package/src/schemas/computers.ts +287 -0
  485. package/src/schemas/drafts.ts +108 -0
  486. package/src/schemas/environment.ts +276 -0
  487. package/src/schemas/exit.ts +222 -0
  488. package/src/schemas/extension-updates.ts +324 -0
  489. package/src/schemas/fast-mode.ts +8 -0
  490. package/src/schemas/git-history.ts +265 -0
  491. package/src/schemas/git.ts +430 -0
  492. package/src/schemas/history.ts +112 -0
  493. package/src/schemas/hosts.ts +37 -0
  494. package/src/schemas/intentic.ts +2 -0
  495. package/src/schemas/internal.ts +17 -0
  496. package/src/schemas/inventory.ts +68 -0
  497. package/src/schemas/issues.ts +279 -0
  498. package/src/schemas/logs.ts +96 -0
  499. package/src/schemas/loops.ts +401 -0
  500. package/src/schemas/maintenance.ts +471 -0
  501. package/src/schemas/marketplace.ts +23 -0
  502. package/src/schemas/panels.ts +99 -0
  503. package/src/schemas/personas.ts +281 -0
  504. package/src/schemas/plan-limits.ts +255 -0
  505. package/src/schemas/ports.ts +84 -0
  506. package/src/schemas/provider-oauth.ts +191 -0
  507. package/src/schemas/provider-subscriptions.ts +11 -0
  508. package/src/schemas/public.ts +52 -0
  509. package/src/schemas/push.ts +112 -0
  510. package/src/schemas/secrets.ts +68 -0
  511. package/src/schemas/sessions.ts +16 -0
  512. package/src/schemas/settings.ts +964 -0
  513. package/src/schemas/share.ts +71 -0
  514. package/src/schemas/shared.ts +32 -0
  515. package/src/schemas/system.ts +156 -0
  516. package/src/schemas/terminal.ts +288 -0
  517. package/src/schemas/usage.ts +303 -0
  518. package/src/{schemas.test.ts → schemas/version-seam.test.ts} +4 -2
  519. package/src/schemas/vpn.ts +215 -0
  520. package/src/schemas/webext.ts +108 -0
  521. package/src/schemas/workflows.ts +413 -0
  522. package/src/schemas/workspace-repos.ts +123 -0
  523. package/src/schemas/workspace-search.ts +141 -0
  524. package/src/schemas/workspace-setup.ts +43 -0
  525. package/src/schemas/workspace-tree.ts +234 -0
  526. package/src/title.test.ts +1 -1
  527. package/src/tunnel-ids.test.ts +3 -1
  528. package/src/webext-links.ts +90 -0
  529. package/src/webext-protocol.ts +27 -0
  530. package/src/workflow-faults.test.ts +1 -1
  531. package/src/workflow-faults.ts +1 -1
  532. package/src/workspace-state.test.ts +6 -4
  533. package/src/workspace-state.ts +35 -50
  534. package/dist/schemas.d.ts +0 -9909
  535. package/dist/schemas.d.ts.map +0 -1
  536. package/dist/schemas.js +0 -4288
  537. package/dist/schemas.js.map +0 -1
  538. package/src/schemas.ts +0 -10090
@@ -179,6 +179,71 @@ describe(`jscpd`, () => {
179
179
  });
180
180
  });
181
181
 
182
+ /* The mutation report is the cross-tool "mutation testing report schema", and the whole risk in this parser is
183
+ * the arithmetic rather than the shape: two of the eight statuses land on the counter-intuitive side, and getting
184
+ * either one backwards produces a number that looks plausible and is wrong. So the statuses are tested by name. */
185
+ describe(`mutation`, () => {
186
+ const report = (...mutants: readonly Record<string, unknown>[]) =>
187
+ JSON.stringify({
188
+ schemaVersion: `2.0`,
189
+ files: { "src/digest.ts": { language: `typescript`, source: `…`, mutants } },
190
+ });
191
+ const mutant = (status: string, line = 1) => ({
192
+ id: `${status}-${line}`,
193
+ mutatorName: `ConditionalExpression`,
194
+ replacement: `false`,
195
+ location: { start: { line, column: 1 }, end: { line, column: 9 } },
196
+ status,
197
+ });
198
+
199
+ test(`counts Killed and Timeout as caught, Survived and NoCoverage as missed`, () => {
200
+ // Stryker's own arithmetic, restated as a test because both halves read backwards at a glance: a mutant
201
+ // that HANGS the suite was noticed by it, and a mutant nothing ran cannot have been.
202
+ const facts = parse(`mutation`, report(mutant(`Killed`), mutant(`Timeout`), mutant(`Survived`), mutant(`NoCoverage`)));
203
+ expect(facts).toMatchObject({ id: `mutation`, mutation: { killed: 2, survived: 2, score: 50 } });
204
+ });
205
+
206
+ test(`leaves mutants that never got a verdict out of the score entirely`, () => {
207
+ // One caught, one missed, and three with no answer: the score is 50%, not 20% and not 80%. Folding the
208
+ // undecided into either column is the mistake this pins.
209
+ const facts = parse(`mutation`, report(mutant(`Killed`), mutant(`Survived`), mutant(`CompileError`), mutant(`RuntimeError`), mutant(`Ignored`)));
210
+ expect(facts).toMatchObject({ id: `mutation`, mutation: { killed: 1, survived: 1, inconclusive: 3, score: 50 } });
211
+ });
212
+
213
+ test(`names each survivor with the change that went unnoticed`, () => {
214
+ const facts = parse(`mutation`, report(mutant(`Survived`, 43)));
215
+ expect(facts).toMatchObject({
216
+ mutation: { survivors: [{ file: `src/digest.ts`, line: 43, mutator: `ConditionalExpression`, replacement: `false` }] },
217
+ });
218
+ });
219
+
220
+ // A mutator that DELETES an expression reports an empty replacement, which would otherwise render as a blank
221
+ // in the panel and read as a missing field rather than as the removal it is.
222
+ test(`renders a deleted expression as a removal rather than as nothing`, () => {
223
+ const facts = parse(`mutation`, report({ ...mutant(`Survived`), replacement: `` }));
224
+ expect(facts).toMatchObject({ mutation: { survivors: [{ replacement: `(removed)` }] } });
225
+ });
226
+
227
+ test(`a run with nothing to mutate is 100%, not a division by zero`, () => {
228
+ expect(parse(`mutation`, JSON.stringify({ schemaVersion: `2.0`, files: {} }))).toMatchObject({
229
+ mutation: { score: 100, killed: 0, survived: 0 },
230
+ });
231
+ });
232
+
233
+ // The distinction the runner depends on: an empty `files` map is a real measurement, a MISSING one is output
234
+ // this parser did not understand, and reporting the second as a clean 100% is the one answer it must never give.
235
+ test(`output without a files map is a failure, not a clean repository`, () => {
236
+ expect(parse(`mutation`, JSON.stringify({ schemaVersion: `2.0` }))).toBeUndefined();
237
+ expect(parse(`mutation`, ``)).toBeUndefined();
238
+ expect(parse(`mutation`, JSON.stringify({ files: [] }))).toBeUndefined();
239
+ });
240
+
241
+ test(`survives a malformed mutant without losing the rest of the file's numbers`, () => {
242
+ const facts = parse(`mutation`, report(mutant(`Killed`), { nonsense: true }, mutant(`Survived`)));
243
+ expect(facts).toMatchObject({ mutation: { killed: 1, survived: 1, inconclusive: 1 } });
244
+ });
245
+ });
246
+
182
247
  /* The UI sweep is the one probe whose output we produce ourselves, which removes the "their JSON moved" failure
183
248
  * and replaces it with a worse one: a command of eleven piped ripgreps in which any single stage can silently
184
249
  * contribute nothing. The marker line is what tells those two apart, and most of what is below is about it. */
@@ -1,4 +1,4 @@
1
- import type { Advisory, Bundle, DeadCode, Duplication, OutdatedPackage, ProbeFacts, ProbeId, UiScan } from "../schemas.js";
1
+ import type { Advisory, Bundle, DeadCode, Duplication, MutationScore, OutdatedPackage, ProbeFacts, ProbeId, UiScan } from "../schemas/maintenance.js";
2
2
  import type { IdiomRule } from "./stack.js";
3
3
  import {
4
4
  BYPASS_PATTERN,
@@ -227,6 +227,103 @@ const parseJscpd = (stdout: string): ProbeFacts | undefined => {
227
227
  return { id: `jscpd`, duplication };
228
228
  };
229
229
 
230
+ /* WHAT THE SUITE WOULD NOTICE IF THE CODE BROKE, from Stryker's report.
231
+ *
232
+ * The report is the cross-tool "mutation testing report schema": `files` maps a path to `{ mutants: [{ mutatorName,
233
+ * replacement, location.start.line, status }] }`. Statuses are Killed, Survived, NoCoverage, Timeout, CompileError,
234
+ * RuntimeError, Ignored, Pending.
235
+ *
236
+ * THE ARITHMETIC IS STRYKER'S, NOT OURS, and that is a deliberate constraint rather than laziness. A timeout counts
237
+ * as DETECTED (a mutant that hangs the suite is one the suite noticed) and NoCoverage counts as UNDETECTED (nothing
238
+ * ran, so nothing could have caught it). Both are counter-intuitive enough to be worth restating here, and both are
239
+ * what the tool's own score means — a row that recomputed them differently would be quietly arguing with the
240
+ * evidence printed underneath it.
241
+ *
242
+ * `Pending` is treated as inconclusive rather than dropped: an interrupted incremental run leaves them, and
243
+ * counting them either way would move the score for a reason that has nothing to do with the tests. */
244
+ const SURVIVOR_SAMPLE = 8;
245
+ const DETECTED = new Set([`Killed`, `Timeout`]);
246
+ const UNDETECTED = new Set([`Survived`, `NoCoverage`]);
247
+
248
+ type Survivor = MutationScore["survivors"][number];
249
+
250
+ // One file's mutant list, or nothing. Every shape this cannot recognise reads as "no mutants here" rather than
251
+ // throwing: a report with one malformed entry is still worth the rest of its numbers.
252
+ const mutantsOf = (raw: unknown): readonly Record<string, unknown>[] => {
253
+ if (typeof raw !== `object` || raw === null) {
254
+ return [];
255
+ }
256
+ const mutants = (raw as Record<string, unknown>)[`mutants`];
257
+ return Array.isArray(mutants) ? mutants.filter((entry): entry is Record<string, unknown> => typeof entry === `object` && entry !== null) : [];
258
+ };
259
+
260
+ const lineOf = (mutant: Record<string, unknown>): number => {
261
+ const location = mutant[`location`];
262
+ const start = typeof location === `object` && location !== null ? (location as Record<string, unknown>)[`start`] : undefined;
263
+ const line = typeof start === `object` && start !== null ? (start as Record<string, unknown>)[`line`] : undefined;
264
+ return typeof line === `number` ? line : 0;
265
+ };
266
+
267
+ const survivorOf = (file: string, mutant: Record<string, unknown>): Survivor => ({
268
+ file,
269
+ line: lineOf(mutant),
270
+ mutator: asString(mutant[`mutatorName`]) ?? `?`,
271
+ // An empty replacement is meaningful — the mutator deleted the expression — so it is rendered as the removal
272
+ // it is rather than left blank for a reader to puzzle over.
273
+ replacement: asString(mutant[`replacement`]) ?? `(removed)`,
274
+ });
275
+
276
+ interface Tally {
277
+ killed: number;
278
+ survived: number;
279
+ inconclusive: number;
280
+ readonly survivors: Survivor[];
281
+ }
282
+
283
+ const tallyMutants = (files: Record<string, unknown>): Tally => {
284
+ const tally: Tally = { killed: 0, survived: 0, inconclusive: 0, survivors: [] };
285
+ for (const [file, raw] of Object.entries(files)) {
286
+ for (const mutant of mutantsOf(raw)) {
287
+ const status = asString(mutant[`status`]) ?? ``;
288
+ if (DETECTED.has(status)) {
289
+ tally.killed++;
290
+ continue;
291
+ }
292
+ // Anything that is neither detected nor undetected never got a verdict — it would not compile, or the
293
+ // configuration ignored it. Counting it either way would move the score for a reason that has nothing
294
+ // to do with the tests.
295
+ if (!UNDETECTED.has(status)) {
296
+ tally.inconclusive++;
297
+ continue;
298
+ }
299
+ tally.survived++;
300
+ tally.survivors.push(survivorOf(file, mutant));
301
+ }
302
+ }
303
+ return tally;
304
+ };
305
+
306
+ const parseMutation = (stdout: string): ProbeFacts | undefined => {
307
+ const files = asObject(stdout)?.[`files`];
308
+ // No `files` key at all means this is not a mutation report. An EMPTY one is a real answer (nothing was
309
+ // mutated) and a missing one is a parse failure, and the runner has to be able to tell them apart.
310
+ if (typeof files !== `object` || files === null || Array.isArray(files)) {
311
+ return undefined;
312
+ }
313
+ const tally = tallyMutants(files as Record<string, unknown>);
314
+ const valid = tally.killed + tally.survived;
315
+ const mutation: MutationScore = {
316
+ // Nothing to mutate scores 100 rather than NaN: there is no undetected fault in it, which is the honest
317
+ // reading and the one that keeps the chore quiet instead of dividing by zero.
318
+ score: valid === 0 ? 100 : Math.round((tally.killed / valid) * 100),
319
+ killed: tally.killed,
320
+ survived: tally.survived,
321
+ inconclusive: tally.inconclusive,
322
+ survivors: tally.survivors.slice(0, SURVIVOR_SAMPLE),
323
+ };
324
+ return { id: `mutation`, mutation };
325
+ };
326
+
230
327
  /* THE UI SWEEP. The only probe here whose command is COMPOSED rather than written out, because its subject is a
231
328
  * table (stack.ts) that will grow and a hand-written command would be a second copy of it going stale.
232
329
  *
@@ -370,6 +467,9 @@ const parseBundle = (stdout: string): ProbeFacts | undefined => {
370
467
  // immediately after, never something to keep, the cached ProbeResult is the artefact that survives. The same
371
468
  // path the scheduled form of this chore uses (chores.ts), so a workspace running both keeps one copy.
372
469
  const JSCPD_DIR = `/tmp/intentic-chore-jscpd`;
470
+ // Where Stryker's json reporter writes, which is its own default and not configurable per run on the CLI. Read
471
+ // from the repo directory the probe runs in, like jscpd's report above.
472
+ const MUTATION_REPORT = `reports/mutation/mutation.json`;
373
473
 
374
474
  export const PROBES: readonly ProbeSpec[] = [
375
475
  {
@@ -430,6 +530,38 @@ export const PROBES: readonly ProbeSpec[] = [
430
530
  `cat ${JSCPD_DIR}/jscpd-report.json 2>/dev/null`,
431
531
  parse: parseJscpd,
432
532
  },
533
+ {
534
+ id: `mutation`,
535
+ title: `Test strength`,
536
+ measures: `how much of the code could break with every test still green`,
537
+ /* THE MOST EXPENSIVE PROBE HERE, and the tier does not really capture it: this runs the suite once per
538
+ * injected fault. `--incremental` is what makes it liveable — Stryker keeps a result file and re-runs only
539
+ * the mutants whose code or tests changed, so the first run costs what a full run costs and every one
540
+ * after it costs the diff. The monthly TTL is set against the FIRST run, not the incremental ones.
541
+ *
542
+ * Opt-in per repository, by the presence of a `stryker.conf.json`, and that is the load-bearing part of
543
+ * the design rather than a convenience. This monorepo has 65 packages with their own vitest configs and no
544
+ * root suite; mutating all of them unasked would be hours of CPU nobody agreed to spend. A repo says which
545
+ * code is worth the measurement by writing that file, which is also where `mutate` narrows the scope. */
546
+ tier: 2,
547
+ ttlMs: 30 * DAY_MS,
548
+ timeoutMs: 90 * 60_000,
549
+ /* Two conditions, and the config is the one that matters: Stryker being installed says the tool COULD run,
550
+ * the config says somebody decided it should. Without the second this would report "unavailable" on every
551
+ * repo that merely shares this monorepo's lockfile.
552
+ *
553
+ * The repo's OWN Stryker, never a floating one, for a reason measured rather than assumed: under
554
+ * `pnpm dlx` the plugin loader resolves from the working directory and finds nothing — "Cannot find
555
+ * TestRunner plugin \"vitest\". In fact, no TestRunner plugins were loaded" — and the runner has to agree
556
+ * with the vitest the repo actually runs. Same argument as knip above. */
557
+ available: `{ test -f stryker.conf.mjs || test -f stryker.conf.json; } && pnpm exec stryker --version >/dev/null 2>&1`,
558
+ unavailable: `no stryker config in this repo`,
559
+ // `|| true` for the same reason the others carry it: Stryker exits non-zero when the score is under its
560
+ // own threshold, which is an opinion about the number, not a failure to produce one. The judgement is the
561
+ // chore's, made from the score, and the runner decides by whether the parser recognised the report.
562
+ command: `pnpm exec stryker run --reporters json --incremental >/dev/null 2>&1 || true; cat ${MUTATION_REPORT} 2>/dev/null`,
563
+ parse: parseMutation,
564
+ },
433
565
  {
434
566
  id: `ui`,
435
567
  title: `Front-end source`,
@@ -108,6 +108,25 @@ describe(`the name two components share`, () => {
108
108
  expect(componentStem(`src/components/Button/index.tsx`)).toBeUndefined();
109
109
  });
110
110
 
111
+ /* The same argument, for the names the framework hands out rather than the author. A monorepo has one root
112
+ * per app and a Next App Router has one `page` per route, so these families form by construction: the thirty
113
+ * `page.tsx` of a thirty-route app would sort above every real finding the chore has. */
114
+ test(`framework entry names never form a family`, () => {
115
+ expect(componentStem(`apps/web/src/App.vue`)).toBeUndefined();
116
+ expect(componentStem(`apps/desktop/src/App.vue`)).toBeUndefined();
117
+ expect(componentStem(`app/dashboard/page.tsx`)).toBeUndefined();
118
+ expect(componentStem(`app/settings/layout.tsx`)).toBeUndefined();
119
+ expect(componentStem(`app/settings/not-found.tsx`)).toBeUndefined();
120
+ });
121
+
122
+ // …and only on the whole name. A component that merely BEGINS with one is the author's own and keeps its
123
+ // stem, or the guard above would swallow half the components in a repo that prefixes them.
124
+ test(`a component that only starts with a framework name is kept`, () => {
125
+ expect(componentStem(`src/shell/AppShell.vue`)).toBe(`appshell`);
126
+ expect(componentStem(`src/ErrorBoundary.tsx`)).toBe(`errorboundary`);
127
+ expect(componentStem(`src/PageHeader.vue`)).toBe(`pageheader`);
128
+ });
129
+
111
130
  /* The trap in stripping a trailing number. `H1` and `H2` are different components and reduce to the same
112
131
  * single letter, so the stem is only accepted when what survives is still long enough to mean something:
113
132
  * otherwise the untouched name is kept and the two stay apart. */
@@ -220,6 +220,19 @@ const MIN_STEM = 3;
220
220
  const QUALIFIER_PREFIX = /^(base|the)/;
221
221
  const QUALIFIER_SUFFIX = /(v[0-9]+|new|old|legacy|copy|component|[0-9]+)$/;
222
222
 
223
+ /* NAMES THE FRAMEWORK CHOSE, NOT THE AUTHOR, and therefore never evidence of anything.
224
+ *
225
+ * A repository gets one of these per app (`app`, `main`, `root`) or one per route directory (Next's App Router
226
+ * mandates `page`, `layout`, `loading`, `error`, `not-found`, `template`, `default`) BY CONSTRUCTION, so two files
227
+ * sharing one is a fact about the framework and not about duplication. A monorepo with two front-ends has two
228
+ * `App.vue`; a thirty-route Next app has thirty `page.tsx`, which sorts to the top of the families list and becomes
229
+ * the loudest thing the chore says while being entirely false.
230
+ *
231
+ * Same argument as `index` below, and the same disposal. Matched against the whole base name rather than as a
232
+ * prefix, so `AppShell.vue` and `ErrorBoundary.tsx` are ordinary components and keep their own stems: the only
233
+ * files dropped are the ones that could not have been built twice in the first place. */
234
+ const FRAMEWORK_NAMES = new Set([`index`, `app`, `main`, `root`, `page`, `layout`, `loading`, `error`, `template`, `default`, `notfound`]);
235
+
223
236
  /* THE NAME TWO COMPONENTS SHARE WHEN THEY ARE THE SAME COMPONENT TWICE, or `undefined` when the file has no
224
237
  * name worth comparing.
225
238
  *
@@ -228,14 +241,17 @@ const QUALIFIER_SUFFIX = /(v[0-9]+|new|old|legacy|copy|component|[0-9]+)$/;
228
241
  * component is making a claim anyone can agree or disagree with in a second. A fuzzy distance would be right more
229
242
  * often and checkable never, and an unarguable finding is one nobody can improve.
230
243
  *
231
- * `index` is dropped rather than normalised. Every barrel file in the repository is called it, and a family of
232
- * forty index files is a finding about the naming convention rather than about any duplication. */
244
+ * `index` is dropped rather than normalised, along with the rest of the framework's own vocabulary
245
+ * (FRAMEWORK_NAMES). Every barrel file in the repository is called it, and a family of forty index files is a
246
+ * finding about the naming convention rather than about any duplication. */
233
247
  export const componentStem = (path: string): string | undefined => {
234
248
  const file = normalizePath(path).split(`/`).pop() ?? ``;
235
249
  // `.component.ts` loses both suffixes, `.vue` loses one, taking everything before the first dot handles both
236
250
  // without a table, since a component's name is never the part after a dot.
237
251
  const base = (file.split(`.`)[0] ?? ``).toLowerCase().replace(/[^a-z0-9]/g, ``);
238
- if (base === `` || base === `index`) {
252
+ // Tested before the stripping below, so a framework name is dropped on its own terms rather than after a
253
+ // qualifier rule has had a chance to turn it into something else.
254
+ if (base === `` || FRAMEWORK_NAMES.has(base)) {
239
255
  return undefined;
240
256
  }
241
257
  const withoutSuffix = base.replace(QUALIFIER_SUFFIX, ``);
@@ -1,4 +1,14 @@
1
- import type { Bundle, ChoreLedgerEntry, ChorePackage, ChoresReport, ChoreShape, ChoreSignals, Duplication, ProbeResult, UiScan } from "../schemas.js";
1
+ import type {
2
+ Bundle,
3
+ ChoreLedgerEntry,
4
+ ChorePackage,
5
+ ChoreShape,
6
+ ChoreSignals,
7
+ ChoresReport,
8
+ Duplication,
9
+ ProbeResult,
10
+ UiScan,
11
+ } from "../schemas/maintenance.js";
2
12
  import { describe, expect, test } from "vitest";
3
13
  import { choreById, CHORES } from "./chores.js";
4
14
  import { assessReport, ledgerKey, unseenVerdicts } from "./verdict.js";
@@ -75,20 +85,21 @@ describe(`what "we have not measured this" means`, () => {
75
85
  test(`a chore whose probe never ran is unavailable, not clear`, () => {
76
86
  const verdict = verdictFor(report(), `security-advisories`);
77
87
  expect(verdict.state).toBe(`unavailable`);
78
- expect(verdict.detail).toEqual([`Security advisories · not measured yet`]);
88
+ expect(verdict.detail.join(` `)).toContain(`Security advisories`);
79
89
  });
80
90
 
81
91
  // The distinction that stops the panel reporting a green repository it has never looked at. A tool the repo
82
92
  // does not have is not evidence of anything, and it carries the tool's own reason rather than an invented one.
83
93
  test(`a probe the repository cannot run says so, and never badges`, () => {
94
+ const knipReason = `knip is not a devDependency`;
84
95
  const input = report({
85
96
  repos: [
86
- { repo: `app`, probes: [probe({ id: `knip`, state: `unavailable`, reason: `knip is not a devDependency` })], signals: signals() },
97
+ { repo: `app`, probes: [probe({ id: `knip`, state: `unavailable`, reason: knipReason })], signals: signals() },
87
98
  ],
88
99
  });
89
100
  const verdict = verdictFor(input, `dead-code`);
90
101
  expect(verdict.state).toBe(`unavailable`);
91
- expect(verdict.detail[0]).toContain(`knip is not a devDependency`);
102
+ expect(verdict.detail[0]).toContain(knipReason);
92
103
  expect(unseenVerdicts([verdict], {})).toEqual([]);
93
104
  });
94
105
 
@@ -132,9 +143,10 @@ describe(`the ledger debounces; it cannot hide`, () => {
132
143
  });
133
144
 
134
145
  test(`an agent reporting the findings did not hold up clears the chore until the evidence changes`, () => {
146
+ const due = verdictFor(withAdvisories, `security-advisories`);
135
147
  const verdict = verdictFor({ ...withAdvisories, ledger: [ledgerEntry({ outcome: `clean` })] }, `security-advisories`);
136
148
  expect(verdict.state).toBe(`clear`);
137
- expect(verdict.headline).toBe(`Checked, the findings did not hold up`);
149
+ expect(verdict.headline).not.toBe(due.headline);
138
150
  });
139
151
 
140
152
  test(`a snooze silences a due chore without hiding it, and lapses on its own`, () => {
@@ -245,9 +257,10 @@ describe(`surveys are due because time passed, and say so`, () => {
245
257
  });
246
258
 
247
259
  test(`run inside the period is clear, and reports when it was read rather than claiming nothing to do`, () => {
248
- const verdict = verdictFor({ ...report(), ledger: [surveyLedger(NOW - 10 * DAY)] }, `standardize-patterns`);
260
+ const daysAgo = 10;
261
+ const verdict = verdictFor({ ...report(), ledger: [surveyLedger(NOW - daysAgo * DAY)] }, `standardize-patterns`);
249
262
  expect(verdict.state).toBe(`clear`);
250
- expect(verdict.headline).toBe(`Surveyed 10 days ago`);
263
+ expect(verdict.headline).toContain(String(daysAgo));
251
264
  });
252
265
 
253
266
  test(`run longer ago than the cadence is due again`, () => {
@@ -372,9 +385,11 @@ describe(`the prompts`, () => {
372
385
  });
373
386
 
374
387
  test(`tell an acting chore to keep the diff reviewable and a reporting chore not to edit at all`, () => {
375
- expect(dueVerdict().prompt).toContain(`separately explainable`);
388
+ const acting = dueVerdict().prompt ?? ``;
376
389
  const survey = verdictFor(report(), `standardize-patterns`);
377
- expect(survey.prompt).toContain(`Change nothing.`);
390
+ expect(acting).toContain(`left-pad`);
391
+ expect(acting).not.toBe(survey.prompt);
392
+ expect(survey.prompt).not.toBe(acting);
378
393
  });
379
394
 
380
395
  test(`every chore that can be due can produce a prompt`, () => {
@@ -443,7 +458,7 @@ describe(`what does not apply here`, () => {
443
458
  test(`a repository with no documents is not asked to re-read its documentation`, () => {
444
459
  const verdict = verdictFor(withShape({ docs: [] }), `documentation-drift`);
445
460
  expect(verdict.state).toBe(`not-applicable`);
446
- expect(verdict.headline).toBe(`no architecture documents`);
461
+ expect(verdict.headline).toContain(`document`);
447
462
  expect(verdict.prompt).toBeUndefined();
448
463
  });
449
464
 
@@ -472,12 +487,13 @@ describe(`what does not apply here`, () => {
472
487
  // fires forever in repositories where its subject does not exist. This is the regression that motivated
473
488
  // making `applies` a required field on SurveySpec rather than an optional one.
474
489
  test(`a tiny repository is not surveyed for cross-cutting patterns it cannot have`, () => {
490
+ const fileCount = 4;
475
491
  const tiny = report({
476
- repos: [{ repo: `app`, probes: [], signals: signals({ totals: { files: 4, symbols: 10, complexity: 5, hotspots: 0 } }) }],
492
+ repos: [{ repo: `app`, probes: [], signals: signals({ totals: { files: fileCount, symbols: 10, complexity: 5, hotspots: 0 } }) }],
477
493
  });
478
494
  const verdict = verdictFor(tiny, `standardize-patterns`);
479
495
  expect(verdict.state).toBe(`not-applicable`);
480
- expect(verdict.headline).toBe(`only 4 indexed files`);
496
+ expect(verdict.headline).toContain(String(fileCount));
481
497
  });
482
498
 
483
499
  test(`applicability is decided before measurement, so a missing probe never masks it`, () => {
@@ -598,7 +614,9 @@ describe(`idioms the framework has replaced`, () => {
598
614
  test(`names what is still in use and what replaced it`, () => {
599
615
  const verdict = verdictFor(withProbes([uiProbe({ idioms: [idioms(`vue-options-api`, 3)] })]), `framework-idiom`);
600
616
  expect(verdict.state).toBe(`due`);
601
- expect(verdict.detail).toEqual([`3 files · the Options API → <script setup> with the Composition API`]);
617
+ expect(verdict.detail[0]).toContain(`3 files`);
618
+ expect(verdict.detail[0]).toContain(`Options API`);
619
+ expect(verdict.detail[0]).toContain(`script setup`);
602
620
  });
603
621
 
604
622
  /* A migration in progress is a set that changes on every commit, so digesting the file identities, which is
@@ -642,8 +660,9 @@ describe(`components built twice`, () => {
642
660
  `component-overlap`,
643
661
  );
644
662
  expect(verdict.state).toBe(`due`);
645
- expect(verdict.headline).toBe(`1 name used by more than one component`);
646
- expect(verdict.detail).toEqual([`button · src/checkout/ButtonV2.tsx, src/ui/BaseButton.vue`]);
663
+ expect(verdict.headline).toContain(`1 name`);
664
+ expect(verdict.detail[0]).toContain(`button`);
665
+ expect(verdict.detail[0]).toContain(`ButtonV2.tsx`);
647
666
  });
648
667
 
649
668
  test(`components that merely coexist are not a finding`, () => {
@@ -663,7 +682,7 @@ describe(`components built twice`, () => {
663
682
  `component-overlap`,
664
683
  );
665
684
  expect(shared.state).toBe(`due`);
666
- expect(shared.headline).toBe(`1 clone spanning two of them`);
685
+ expect(shared.headline).toContain(`clone`);
667
686
  expect(oneSided.state).toBe(`clear`);
668
687
  });
669
688
 
@@ -688,8 +707,10 @@ describe(`hard-coded styles`, () => {
688
707
  `tailwind-arbitrary-values`,
689
708
  );
690
709
  expect(verdict.state).toBe(`due`);
691
- expect(verdict.headline).toBe(`13 hard-coded values across 2 files`);
692
- expect(verdict.detail[0]).toBe(`src/Checkout.vue · 11 values`);
710
+ expect(verdict.headline).toContain(`13`);
711
+ expect(verdict.headline).toContain(`2 files`);
712
+ expect(verdict.detail[0]).toContain(`Checkout.vue`);
713
+ expect(verdict.detail[0]).toContain(`11`);
693
714
  });
694
715
 
695
716
  // Tailwind gates this one alone: a Vue repository with no Tailwind has no theme scale to have bypassed, and
@@ -700,7 +721,7 @@ describe(`hard-coded styles`, () => {
700
721
  `tailwind-arbitrary-values`,
701
722
  );
702
723
  expect(verdict.state).toBe(`not-applicable`);
703
- expect(verdict.headline).toBe(`no Tailwind`);
724
+ expect(verdict.headline).toContain(`Tailwind`);
704
725
  });
705
726
 
706
727
  // And the framework gate the other four share, from the other side: deps come from shape, not from packages,
@@ -726,7 +747,6 @@ describe(`every chore says what would make it due`, () => {
726
747
 
727
748
  test(`the criterion reaches the prompt, so the agent can tell us the rule was wrong`, () => {
728
749
  const due = verdictFor(report({ repos: [{ repo: `app`, probes: [auditProbe([`left-pad`])], signals: signals() }] }), `security-advisories`);
729
- expect(due.prompt).toContain(`You were woken because:`);
730
750
  expect(due.prompt).toContain(due.chore.criterion);
731
751
  });
732
752
  });
@@ -1,4 +1,4 @@
1
- import type { ChoreLedgerEntry, ChoresReport, ProbeId, ProbeResult } from "../schemas.js";
1
+ import type { ChoreLedgerEntry, ChoresReport, ProbeId, ProbeResult } from "../schemas/maintenance.js";
2
2
  import { type Chore, type ChoreContext, type ChoreFinding, CHORES, chorePrompt } from "./chores.js";
3
3
  import { probeSpec } from "./probes.js";
4
4