@azure-id/orc 0.55.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 (449) hide show
  1. package/CHANGELOG.md +2017 -0
  2. package/README-id.md +521 -0
  3. package/README.md +485 -0
  4. package/bin/build-agents.js +86 -0
  5. package/bin/cli.js +29050 -0
  6. package/bin/mockrun-catalog.js +267 -0
  7. package/bin/onboarding-content.js +172 -0
  8. package/bin/pricing.json +200 -0
  9. package/bin/providers.json +437 -0
  10. package/bin/ui.js +95 -0
  11. package/bin/verify-contracts.js +3277 -0
  12. package/bin/verify-package.js +498 -0
  13. package/bin/webui/api.js +1163 -0
  14. package/bin/webui/app.html +198 -0
  15. package/bin/webui/css/00-tokens.css +92 -0
  16. package/bin/webui/css/01-base.css +42 -0
  17. package/bin/webui/css/02-shell.css +103 -0
  18. package/bin/webui/css/03-components.css +462 -0
  19. package/bin/webui/css/04-motion.css +91 -0
  20. package/bin/webui/css/05-tour.css +100 -0
  21. package/bin/webui/css/06-responsive.css +108 -0
  22. package/bin/webui/css/panels/boundary.css +26 -0
  23. package/bin/webui/css/panels/challenge.css +151 -0
  24. package/bin/webui/css/panels/crosslink.css +194 -0
  25. package/bin/webui/css/panels/docs.css +254 -0
  26. package/bin/webui/css/panels/experiment.css +23 -0
  27. package/bin/webui/css/panels/extra.css +536 -0
  28. package/bin/webui/css/panels/flow.css +177 -0
  29. package/bin/webui/css/panels/handoff.css +67 -0
  30. package/bin/webui/css/panels/knowledge.css +86 -0
  31. package/bin/webui/css/panels/learn.css +154 -0
  32. package/bin/webui/css/panels/maintenance.css +55 -0
  33. package/bin/webui/css/panels/mockrun.css +268 -0
  34. package/bin/webui/css/panels/overview.css +100 -0
  35. package/bin/webui/css/panels/pact.css +43 -0
  36. package/bin/webui/css/panels/runs.css +105 -0
  37. package/bin/webui/css/panels/settings.css +227 -0
  38. package/bin/webui/css/panels/stats.css +87 -0
  39. package/bin/webui/fixtures/boundary.js +92 -0
  40. package/bin/webui/fixtures/challenge.js +825 -0
  41. package/bin/webui/fixtures/crosslink.js +31 -0
  42. package/bin/webui/fixtures/docs.js +982 -0
  43. package/bin/webui/fixtures/extra.js +1934 -0
  44. package/bin/webui/fixtures/flow.js +81 -0
  45. package/bin/webui/fixtures/handoff.js +35 -0
  46. package/bin/webui/fixtures/index.js +486 -0
  47. package/bin/webui/fixtures/knowledge.js +291 -0
  48. package/bin/webui/fixtures/maintenance.js +42 -0
  49. package/bin/webui/fixtures/mockrun.js +36 -0
  50. package/bin/webui/fixtures/pact.js +111 -0
  51. package/bin/webui/fixtures/runs.js +109 -0
  52. package/bin/webui/fixtures/settings.js +78 -0
  53. package/bin/webui/fixtures/shell.js +48 -0
  54. package/bin/webui/fixtures/stats.js +104 -0
  55. package/bin/webui/i18n/TERMS.md +134 -0
  56. package/bin/webui/i18n/en/banner.json +29 -0
  57. package/bin/webui/i18n/en/boundary.json +20 -0
  58. package/bin/webui/i18n/en/challenge.json +106 -0
  59. package/bin/webui/i18n/en/common.json +69 -0
  60. package/bin/webui/i18n/en/crosslink.json +69 -0
  61. package/bin/webui/i18n/en/docs.json +175 -0
  62. package/bin/webui/i18n/en/experiment.json +17 -0
  63. package/bin/webui/i18n/en/extra.json +313 -0
  64. package/bin/webui/i18n/en/flow.json +30 -0
  65. package/bin/webui/i18n/en/handoff.json +37 -0
  66. package/bin/webui/i18n/en/knowledge.json +141 -0
  67. package/bin/webui/i18n/en/learn.json +16 -0
  68. package/bin/webui/i18n/en/maintenance.json +52 -0
  69. package/bin/webui/i18n/en/mockrun.json +19 -0
  70. package/bin/webui/i18n/en/nav.json +19 -0
  71. package/bin/webui/i18n/en/overview.json +89 -0
  72. package/bin/webui/i18n/en/pact.json +36 -0
  73. package/bin/webui/i18n/en/runs.json +51 -0
  74. package/bin/webui/i18n/en/settings.json +49 -0
  75. package/bin/webui/i18n/en/stats.json +69 -0
  76. package/bin/webui/i18n/en/tour.json +33 -0
  77. package/bin/webui/i18n/id/banner.json +29 -0
  78. package/bin/webui/i18n/id/boundary.json +20 -0
  79. package/bin/webui/i18n/id/challenge.json +106 -0
  80. package/bin/webui/i18n/id/common.json +70 -0
  81. package/bin/webui/i18n/id/crosslink.json +69 -0
  82. package/bin/webui/i18n/id/docs.json +175 -0
  83. package/bin/webui/i18n/id/experiment.json +17 -0
  84. package/bin/webui/i18n/id/extra.json +313 -0
  85. package/bin/webui/i18n/id/flow.json +30 -0
  86. package/bin/webui/i18n/id/handoff.json +37 -0
  87. package/bin/webui/i18n/id/knowledge.json +141 -0
  88. package/bin/webui/i18n/id/learn.json +16 -0
  89. package/bin/webui/i18n/id/maintenance.json +52 -0
  90. package/bin/webui/i18n/id/mockrun.json +19 -0
  91. package/bin/webui/i18n/id/nav.json +19 -0
  92. package/bin/webui/i18n/id/overview.json +89 -0
  93. package/bin/webui/i18n/id/pact.json +36 -0
  94. package/bin/webui/i18n/id/runs.json +51 -0
  95. package/bin/webui/i18n/id/settings.json +49 -0
  96. package/bin/webui/i18n/id/stats.json +69 -0
  97. package/bin/webui/i18n/id/tour.json +33 -0
  98. package/bin/webui/js/00-core.js +115 -0
  99. package/bin/webui/js/01-i18n.js +149 -0
  100. package/bin/webui/js/02-ui.js +211 -0
  101. package/bin/webui/js/03-md.js +286 -0
  102. package/bin/webui/js/04-router.js +51 -0
  103. package/bin/webui/js/05-banners.js +172 -0
  104. package/bin/webui/js/06-edit.js +183 -0
  105. package/bin/webui/js/90-tour.js +488 -0
  106. package/bin/webui/js/91-shortcuts.js +126 -0
  107. package/bin/webui/js/99-boot.js +118 -0
  108. package/bin/webui/js/panels/boundary.js +104 -0
  109. package/bin/webui/js/panels/challenge.js +781 -0
  110. package/bin/webui/js/panels/crosslink.js +654 -0
  111. package/bin/webui/js/panels/docs.js +1338 -0
  112. package/bin/webui/js/panels/experiment.js +98 -0
  113. package/bin/webui/js/panels/extra.js +3011 -0
  114. package/bin/webui/js/panels/flow.js +297 -0
  115. package/bin/webui/js/panels/handoff.js +169 -0
  116. package/bin/webui/js/panels/knowledge.js +890 -0
  117. package/bin/webui/js/panels/learn.js +220 -0
  118. package/bin/webui/js/panels/maintenance.js +235 -0
  119. package/bin/webui/js/panels/mockrun.js +227 -0
  120. package/bin/webui/js/panels/overview.js +447 -0
  121. package/bin/webui/js/panels/pact.js +189 -0
  122. package/bin/webui/js/panels/runs.js +416 -0
  123. package/bin/webui/js/panels/settings.js +573 -0
  124. package/bin/webui/js/panels/stats.js +378 -0
  125. package/bin/webui/serve.js +557 -0
  126. package/mock-run/INDEX.md +106 -0
  127. package/mock-run/a-normal-day.md +587 -0
  128. package/mock-run/context-combiner.md +100 -0
  129. package/mock-run/extra-recovery.md +330 -0
  130. package/mock-run/extra-slots.md +177 -0
  131. package/mock-run/media/README.md +43 -0
  132. package/mock-run/orc-aftermath.md +392 -0
  133. package/mock-run/orc-boundary.md +356 -0
  134. package/mock-run/orc-brainstorm.md +177 -0
  135. package/mock-run/orc-budget.md +534 -0
  136. package/mock-run/orc-challenge-council.md +262 -0
  137. package/mock-run/orc-challenge.md +416 -0
  138. package/mock-run/orc-cli.md +200 -0
  139. package/mock-run/orc-diy.md +129 -0
  140. package/mock-run/orc-doc.md +448 -0
  141. package/mock-run/orc-explain.md +86 -0
  142. package/mock-run/orc-export.md +423 -0
  143. package/mock-run/orc-extra.md +392 -0
  144. package/mock-run/orc-fast.md +106 -0
  145. package/mock-run/orc-grill.md +151 -0
  146. package/mock-run/orc-handoff.md +480 -0
  147. package/mock-run/orc-pact.md +421 -0
  148. package/mock-run/orc-pattern.md +112 -0
  149. package/mock-run/orc-plan.md +108 -0
  150. package/mock-run/orc-pr-setup.md +126 -0
  151. package/mock-run/orc-quick.md +113 -0
  152. package/mock-run/orc-route.md +93 -0
  153. package/mock-run/orc-ui.md +125 -0
  154. package/mock-run/orc-ultra.md +103 -0
  155. package/mock-run/orc.md +157 -0
  156. package/mock-run/the-example-project.md +55 -0
  157. package/package.json +39 -0
  158. package/templates/agents/MODEL-MAPPING.md +168 -0
  159. package/templates/agents/orc-advisor-fable-5.md +50 -0
  160. package/templates/agents/orc-advisor-opus-5-xhigh.md +56 -0
  161. package/templates/agents/orc-analyst-fable-5.md +115 -0
  162. package/templates/agents/orc-analyze-mini-opus-5-med.md +60 -0
  163. package/templates/agents/orc-analyze-mini-sonnet-5-high.md +58 -0
  164. package/templates/agents/orc-challenge-advisor-opus-5-med.md +75 -0
  165. package/templates/agents/orc-challenge-contrarian-opus-5-high.md +110 -0
  166. package/templates/agents/orc-challenge-executor-opus-5-med.md +114 -0
  167. package/templates/agents/orc-challenge-expansionist-opus-5-med.md +112 -0
  168. package/templates/agents/orc-challenge-judge-opus-5-high.md +132 -0
  169. package/templates/agents/orc-challenge-outsider-opus-5-low.md +109 -0
  170. package/templates/agents/orc-challenge-principles-opus-5-high.md +109 -0
  171. package/templates/agents/orc-challenge-reader-opus-5-low.md +90 -0
  172. package/templates/agents/orc-claude-writer-opus-4-8-high.md +53 -0
  173. package/templates/agents/orc-claude-writer-opus-5-med.md +55 -0
  174. package/templates/agents/orc-context-combiner-opus-5-high.md +88 -0
  175. package/templates/agents/orc-doc-checker-opus-5-low.md +108 -0
  176. package/templates/agents/orc-doc-writer-opus-5-med.md +134 -0
  177. package/templates/agents/orc-executor-haiku-4-5.md +113 -0
  178. package/templates/agents/orc-executor-opus-4-7-high.md +114 -0
  179. package/templates/agents/orc-executor-opus-4-7-med.md +114 -0
  180. package/templates/agents/orc-executor-opus-4-8-high.md +114 -0
  181. package/templates/agents/orc-executor-opus-5-high.md +114 -0
  182. package/templates/agents/orc-executor-opus-5-low.md +114 -0
  183. package/templates/agents/orc-executor-opus-5-med.md +114 -0
  184. package/templates/agents/orc-executor-sonnet-4-6-high.md +114 -0
  185. package/templates/agents/orc-executor-sonnet-4-6-med.md +114 -0
  186. package/templates/agents/orc-executor-sonnet-5-high.md +114 -0
  187. package/templates/agents/orc-judge-fable-5.md +79 -0
  188. package/templates/agents/orc-judge-opus-5-xhigh.md +85 -0
  189. package/templates/agents/orc-learn-writer-opus-5-low.md +73 -0
  190. package/templates/agents/orc-pattern-codifier-opus-5-med.md +65 -0
  191. package/templates/agents/orc-pattern-codifier-sonnet-5-high.md +63 -0
  192. package/templates/agents/orc-planner-fable-5.md +152 -0
  193. package/templates/agents/orc-planner-mini-opus-5-med.md +69 -0
  194. package/templates/agents/orc-planner-mini-sonnet-5-high.md +67 -0
  195. package/templates/agents/orc-planner-opus-5-med.md +160 -0
  196. package/templates/agents/orc-retro-opus-5-med.md +73 -0
  197. package/templates/agents/orc-retro-sonnet-5-high.md +72 -0
  198. package/templates/agents/orc-reviewer-fable-5.md +57 -0
  199. package/templates/agents/orc-reviewer-opus-5-med.md +60 -0
  200. package/templates/agents/orc-scout-opus-5-low.md +40 -0
  201. package/templates/agents/orc-scout-sonnet-4-6-high.md +39 -0
  202. package/templates/agents/orc-system-analyst-opus-5-high.md +120 -0
  203. package/templates/agents/orc-test-author-opus-5-med.md +71 -0
  204. package/templates/agents/orc-trace-writer-haiku-4-5.md +107 -0
  205. package/templates/agents/orc-verifier-opus-5-med.md +69 -0
  206. package/templates/agents/orc-wiki-scanner-opus-4-8-high.md +79 -0
  207. package/templates/agents/orc-wiki-scanner-opus-5-med.md +81 -0
  208. package/templates/agents/orc-wiki-scanner-sonnet-5-high.md +106 -0
  209. package/templates/commands/orc-aftermath.md +49 -0
  210. package/templates/commands/orc-analyze.md +21 -0
  211. package/templates/commands/orc-boundary.md +46 -0
  212. package/templates/commands/orc-brainstorm.md +51 -0
  213. package/templates/commands/orc-budget.md +54 -0
  214. package/templates/commands/orc-challenge.md +58 -0
  215. package/templates/commands/orc-claude.md +14 -0
  216. package/templates/commands/orc-diy.md +13 -0
  217. package/templates/commands/orc-doc.md +128 -0
  218. package/templates/commands/orc-explain.md +20 -0
  219. package/templates/commands/orc-export.md +46 -0
  220. package/templates/commands/orc-fast.md +15 -0
  221. package/templates/commands/orc-grill.md +40 -0
  222. package/templates/commands/orc-handoff.md +52 -0
  223. package/templates/commands/orc-learn.md +17 -0
  224. package/templates/commands/orc-mini.md +12 -0
  225. package/templates/commands/orc-pact.md +44 -0
  226. package/templates/commands/orc-pattern.md +15 -0
  227. package/templates/commands/orc-plan.md +22 -0
  228. package/templates/commands/orc-poly.md +21 -0
  229. package/templates/commands/orc-pr-driver.md +30 -0
  230. package/templates/commands/orc-pr-setup.md +31 -0
  231. package/templates/commands/orc-quick.md +33 -0
  232. package/templates/commands/orc-retro.md +17 -0
  233. package/templates/commands/orc-route.md +41 -0
  234. package/templates/commands/orc-ultra.md +17 -0
  235. package/templates/commands/orc-verify.md +11 -0
  236. package/templates/commands/orc-wiki.md +42 -0
  237. package/templates/commands/orc.md +16 -0
  238. package/templates/hooks/orc-effort-guard.js +178 -0
  239. package/templates/hooks/orc-statusline.js +305 -0
  240. package/templates/hooks/orc-trace.js +471 -0
  241. package/templates/hooks/orc-update-lib.js +125 -0
  242. package/templates/skills/_shared/README.md +50 -0
  243. package/templates/skills/_shared/detecting-artifacts.md +90 -0
  244. package/templates/skills/_shared/drift-recovery.md +98 -0
  245. package/templates/skills/_shared/extra-dispatch.md +1051 -0
  246. package/templates/skills/_shared/fable5-override.md +56 -0
  247. package/templates/skills/_shared/fallback-handoff.md +42 -0
  248. package/templates/skills/_shared/gh-stack-commands.md +65 -0
  249. package/templates/skills/_shared/gotchas.md +177 -0
  250. package/templates/skills/_shared/interview.md +144 -0
  251. package/templates/skills/_shared/lane-suspend.md +82 -0
  252. package/templates/skills/_shared/opus5-only.md +131 -0
  253. package/templates/skills/_shared/pr-templates.md +106 -0
  254. package/templates/skills/_shared/read-ladder.md +54 -0
  255. package/templates/skills/_shared/return-validation.md +145 -0
  256. package/templates/skills/_shared/smoke-gate.md +28 -0
  257. package/templates/skills/_shared/stack-plan.md +135 -0
  258. package/templates/skills/_shared/untrusted-input.md +63 -0
  259. package/templates/skills/context-combiner/SKILL.md +187 -0
  260. package/templates/skills/context-combiner/schemas/combined-report.md +78 -0
  261. package/templates/skills/context-combiner/schemas/combined-requirement-spec.md +87 -0
  262. package/templates/skills/orc/README.md +150 -0
  263. package/templates/skills/orc/SKILL.md +526 -0
  264. package/templates/skills/orc/config.md +389 -0
  265. package/templates/skills/orc/examples/full-run-mock.md +73 -0
  266. package/templates/skills/orc/references/analyst-gates.md +124 -0
  267. package/templates/skills/orc/references/effort-and-mode.md +224 -0
  268. package/templates/skills/orc/references/house-rules.md +20 -0
  269. package/templates/skills/orc/references/intake.md +120 -0
  270. package/templates/skills/orc/references/log-protocol.md +39 -0
  271. package/templates/skills/orc/references/pattern-gate.md +89 -0
  272. package/templates/skills/orc/references/plan-handoff.md +84 -0
  273. package/templates/skills/orc/references/preflight-report.md +220 -0
  274. package/templates/skills/orc/references/security-checklist.md +39 -0
  275. package/templates/skills/orc/references/stop-and-resume.md +160 -0
  276. package/templates/skills/orc/references/trace-protocol.md +314 -0
  277. package/templates/skills/orc/references/ultra-mode.md +123 -0
  278. package/templates/skills/orc/references/wave-grouping.md +121 -0
  279. package/templates/skills/orc/references/wiki-consult.md +177 -0
  280. package/templates/skills/orc/schemas/checkpoint.md +122 -0
  281. package/templates/skills/orc/schemas/intent-spec.md +42 -0
  282. package/templates/skills/orc/schemas/planning-output.md +279 -0
  283. package/templates/skills/orc/subskills/orc-checkpoint/SKILL.md +55 -0
  284. package/templates/skills/orc/subskills/orc-execution/SKILL.md +72 -0
  285. package/templates/skills/orc/subskills/orc-execution/core.md +151 -0
  286. package/templates/skills/orc/subskills/orc-execution/subagent.md +13 -0
  287. package/templates/skills/orc/subskills/orc-planner/SKILL.md +264 -0
  288. package/templates/skills/orc/subskills/orc-planner-mini/SKILL.md +121 -0
  289. package/templates/skills/orc/subskills/orc-pr/SKILL.md +51 -0
  290. package/templates/skills/orc/subskills/orc-pr/pr.md +22 -0
  291. package/templates/skills/orc/subskills/orc-pr/stack-gate.md +108 -0
  292. package/templates/skills/orc/subskills/orc-review-verify/SKILL.md +76 -0
  293. package/templates/skills/orc/subskills/orc-review-verify/core.md +135 -0
  294. package/templates/skills/orc/subskills/orc-review-verify/subagent.md +7 -0
  295. package/templates/skills/orc/subskills/orc-testgen/SKILL.md +45 -0
  296. package/templates/skills/orc/subskills/orc-testgen/core.md +59 -0
  297. package/templates/skills/orc/subskills/orc-testgen/subagent.md +7 -0
  298. package/templates/skills/orc-advisor/SKILL.md +60 -0
  299. package/templates/skills/orc-aftermath/SKILL.md +136 -0
  300. package/templates/skills/orc-aftermath/references/report.md +95 -0
  301. package/templates/skills/orc-analyze/SKILL.md +220 -0
  302. package/templates/skills/orc-analyze/examples/analyze-mock.md +42 -0
  303. package/templates/skills/orc-analyze/references/branching.md +51 -0
  304. package/templates/skills/orc-analyze/references/deep-mode.md +27 -0
  305. package/templates/skills/orc-analyze/references/thin-input.md +77 -0
  306. package/templates/skills/orc-analyze/schemas/report-audit.md +83 -0
  307. package/templates/skills/orc-analyze/schemas/report-prose.md +63 -0
  308. package/templates/skills/orc-analyze/schemas/report-requirement.md +78 -0
  309. package/templates/skills/orc-analyze/schemas/requirement-spec.md +77 -0
  310. package/templates/skills/orc-analyze-mini/SKILL.md +112 -0
  311. package/templates/skills/orc-analyze-mini/examples/quick-analysis-mock.md +31 -0
  312. package/templates/skills/orc-boundary/SKILL.md +208 -0
  313. package/templates/skills/orc-boundary/references/card.md +78 -0
  314. package/templates/skills/orc-boundary/references/gate.md +113 -0
  315. package/templates/skills/orc-brainstorm/SKILL.md +339 -0
  316. package/templates/skills/orc-brainstorm/references/brainstorm-doc.md +133 -0
  317. package/templates/skills/orc-brainstorm/references/lenses.md +152 -0
  318. package/templates/skills/orc-budget/SKILL.md +225 -0
  319. package/templates/skills/orc-budget/references/corpus.md +87 -0
  320. package/templates/skills/orc-challenge/README.md +142 -0
  321. package/templates/skills/orc-challenge/SKILL.md +255 -0
  322. package/templates/skills/orc-challenge/examples/code-module.md +110 -0
  323. package/templates/skills/orc-challenge/examples/council-full-roster.md +273 -0
  324. package/templates/skills/orc-challenge/examples/tsd-two-iterations.md +213 -0
  325. package/templates/skills/orc-challenge/references/conservation.md +107 -0
  326. package/templates/skills/orc-challenge/references/council.md +315 -0
  327. package/templates/skills/orc-challenge/references/cycle-state.md +185 -0
  328. package/templates/skills/orc-challenge/references/dimensions.md +121 -0
  329. package/templates/skills/orc-challenge/references/fix-brief.md +130 -0
  330. package/templates/skills/orc-challenge/references/intake.md +171 -0
  331. package/templates/skills/orc-challenge/references/kinds.md +44 -0
  332. package/templates/skills/orc-challenge/references/plain-english.md +98 -0
  333. package/templates/skills/orc-challenge/references/rubric.md +109 -0
  334. package/templates/skills/orc-challenge/references/sealed-slice.md +97 -0
  335. package/templates/skills/orc-challenge/references/verdict-doc.md +154 -0
  336. package/templates/skills/orc-claude/SKILL.md +199 -0
  337. package/templates/skills/orc-claude/examples/claude-run-mock.md +65 -0
  338. package/templates/skills/orc-claude/references/refresh.md +76 -0
  339. package/templates/skills/orc-claude/references/template.md +109 -0
  340. package/templates/skills/orc-diy/README.md +142 -0
  341. package/templates/skills/orc-diy/SKILL.md +70 -0
  342. package/templates/skills/orc-diy/references/blocks/analyze.md +24 -0
  343. package/templates/skills/orc-diy/references/blocks/execution.md +42 -0
  344. package/templates/skills/orc-diy/references/blocks/extra.md +55 -0
  345. package/templates/skills/orc-diy/references/blocks/header.md +55 -0
  346. package/templates/skills/orc-diy/references/blocks/mock-example.md +22 -0
  347. package/templates/skills/orc-diy/references/blocks/pattern.md +18 -0
  348. package/templates/skills/orc-diy/references/blocks/planning.md +34 -0
  349. package/templates/skills/orc-diy/references/blocks/review.md +18 -0
  350. package/templates/skills/orc-diy/references/blocks/scoring.md +16 -0
  351. package/templates/skills/orc-diy/references/blocks/security.md +25 -0
  352. package/templates/skills/orc-diy/references/blocks/ship.md +25 -0
  353. package/templates/skills/orc-diy/references/blocks/summary.md +18 -0
  354. package/templates/skills/orc-diy/references/blocks/testgen.md +17 -0
  355. package/templates/skills/orc-diy/references/blocks/trace.md +28 -0
  356. package/templates/skills/orc-diy/references/blocks/verify.md +25 -0
  357. package/templates/skills/orc-diy/references/blocks/wiki.md +26 -0
  358. package/templates/skills/orc-diy/references/compile.md +59 -0
  359. package/templates/skills/orc-diy/references/flow-schema.md +100 -0
  360. package/templates/skills/orc-diy/references/locked-blocks.md +37 -0
  361. package/templates/skills/orc-doc/README.md +229 -0
  362. package/templates/skills/orc-doc/SKILL.md +444 -0
  363. package/templates/skills/orc-doc/examples/orc-doc-prd-run.md +325 -0
  364. package/templates/skills/orc-doc/references/chunking.md +527 -0
  365. package/templates/skills/orc-doc/references/gates.md +311 -0
  366. package/templates/skills/orc-doc/references/generation-rules.md +122 -0
  367. package/templates/skills/orc-doc/references/house-rules.md +170 -0
  368. package/templates/skills/orc-doc/references/import-targets.md +40 -0
  369. package/templates/skills/orc-doc/references/plain-language.md +66 -0
  370. package/templates/skills/orc-doc/references/portable-markdown.md +74 -0
  371. package/templates/skills/orc-doc/references/resume-protocol.md +228 -0
  372. package/templates/skills/orc-doc/references/templates/collaboration.md +118 -0
  373. package/templates/skills/orc-doc/references/templates/prd.md +133 -0
  374. package/templates/skills/orc-doc/references/templates/report.md +102 -0
  375. package/templates/skills/orc-doc/references/templates/tsd.md +122 -0
  376. package/templates/skills/orc-doc/references/templates/workflow.md +112 -0
  377. package/templates/skills/orc-explain/SKILL.md +57 -0
  378. package/templates/skills/orc-export/SKILL.md +154 -0
  379. package/templates/skills/orc-fast/SKILL.md +188 -0
  380. package/templates/skills/orc-grill/SKILL.md +207 -0
  381. package/templates/skills/orc-grill/references/grill-doc.md +105 -0
  382. package/templates/skills/orc-handoff/SKILL.md +204 -0
  383. package/templates/skills/orc-handoff/references/handoff-log.md +67 -0
  384. package/templates/skills/orc-handoff/references/surfaces.md +88 -0
  385. package/templates/skills/orc-judge/SKILL.md +82 -0
  386. package/templates/skills/orc-learn/SKILL.md +156 -0
  387. package/templates/skills/orc-learn/examples/learn-run-mock.md +61 -0
  388. package/templates/skills/orc-learn/references/deepen.md +70 -0
  389. package/templates/skills/orc-learn/references/refresh.md +65 -0
  390. package/templates/skills/orc-learn/references/template-knowledge.md +83 -0
  391. package/templates/skills/orc-learn/references/template-learning.md +67 -0
  392. package/templates/skills/orc-mini/SKILL.md +226 -0
  393. package/templates/skills/orc-mini/examples/mini-run-mock.md +50 -0
  394. package/templates/skills/orc-pact/SKILL.md +218 -0
  395. package/templates/skills/orc-pact/references/gate.md +70 -0
  396. package/templates/skills/orc-pact/references/ledger.md +99 -0
  397. package/templates/skills/orc-pattern/SKILL.md +124 -0
  398. package/templates/skills/orc-pattern/references/INDEX.md +73 -0
  399. package/templates/skills/orc-pattern/references/be-django.md +80 -0
  400. package/templates/skills/orc-pattern/references/be-express.md +82 -0
  401. package/templates/skills/orc-pattern/references/be-fastapi.md +107 -0
  402. package/templates/skills/orc-pattern/references/be-go.md +96 -0
  403. package/templates/skills/orc-pattern/references/be-nestjs.md +86 -0
  404. package/templates/skills/orc-pattern/references/be-postgres.md +98 -0
  405. package/templates/skills/orc-pattern/references/fe-a11y.md +36 -0
  406. package/templates/skills/orc-pattern/references/fe-angular.md +87 -0
  407. package/templates/skills/orc-pattern/references/fe-nextjs.md +65 -0
  408. package/templates/skills/orc-pattern/references/fe-perf.md +39 -0
  409. package/templates/skills/orc-pattern/references/fe-react.md +83 -0
  410. package/templates/skills/orc-pattern/references/fe-vue.md +75 -0
  411. package/templates/skills/orc-pattern/schemas/pattern-doc.md +62 -0
  412. package/templates/skills/orc-poly/SKILL.md +216 -0
  413. package/templates/skills/orc-poly/examples/poly-run-mock.md +51 -0
  414. package/templates/skills/orc-poly/references/gather.md +70 -0
  415. package/templates/skills/orc-poly/references/poly-spec.md +84 -0
  416. package/templates/skills/orc-pr-driver/README.md +349 -0
  417. package/templates/skills/orc-pr-driver/SKILL.md +167 -0
  418. package/templates/skills/orc-pr-driver/references/conflict-playbook.md +78 -0
  419. package/templates/skills/orc-pr-driver/references/green-gate.md +105 -0
  420. package/templates/skills/orc-pr-driver/references/orc-run-split.md +99 -0
  421. package/templates/skills/orc-pr-setup/README.md +436 -0
  422. package/templates/skills/orc-pr-setup/SKILL.md +184 -0
  423. package/templates/skills/orc-pr-setup/references/certainty-gate.md +66 -0
  424. package/templates/skills/orc-pr-setup/references/layer-taxonomy.md +67 -0
  425. package/templates/skills/orc-quick/README.md +423 -0
  426. package/templates/skills/orc-quick/SKILL.md +306 -0
  427. package/templates/skills/orc-quick/references/context-doc.md +114 -0
  428. package/templates/skills/orc-quick/references/dispatch-gate.md +163 -0
  429. package/templates/skills/orc-quick/references/gh-mode.md +127 -0
  430. package/templates/skills/orc-retro/SKILL.md +222 -0
  431. package/templates/skills/orc-retro/examples/retro-mock.md +171 -0
  432. package/templates/skills/orc-route/SKILL.md +165 -0
  433. package/templates/skills/orc-verify/SKILL.md +86 -0
  434. package/templates/skills/orc-verify/examples/verify-mock.md +33 -0
  435. package/templates/skills/orc-wiki/README.md +325 -0
  436. package/templates/skills/orc-wiki/SKILL.md +322 -0
  437. package/templates/skills/orc-wiki/examples/wiki-run-mock.md +37 -0
  438. package/templates/skills/orc-wiki/references/claude-md-injection.md +61 -0
  439. package/templates/skills/orc-wiki/references/crosslink-compile.md +39 -0
  440. package/templates/skills/orc-wiki/references/crosslink-kinds.md +57 -0
  441. package/templates/skills/orc-wiki/references/crosslink.md +284 -0
  442. package/templates/skills/orc-wiki/references/extra.md +79 -0
  443. package/templates/skills/orc-wiki/references/integrity-check.md +86 -0
  444. package/templates/skills/orc-wiki/references/orientation.md +51 -0
  445. package/templates/skills/orc-wiki/references/partial-refresh.md +203 -0
  446. package/templates/skills/orc-wiki/references/pattern-prewarm.md +19 -0
  447. package/templates/skills/orc-wiki/references/staleness.md +288 -0
  448. package/templates/skills/orc-wiki/schemas/crosslink-tag.md +166 -0
  449. package/templates/skills/orc-wiki/schemas/wiki-doc.md +120 -0
@@ -0,0 +1,378 @@
1
+ "use strict";
2
+ /* panels/stats.js — orc ui client
3
+ Usage and Cost. The four-part token bar exists so cache-read stays visibly
4
+ separate from the other three.
5
+
6
+ Loaded by app.html in the order its numeric prefix names. Classic
7
+ script, no import/export: an ES module import carries no query string,
8
+ and every static request here needs the per-launch session token. */
9
+
10
+ /* =================================================================== STATS == */
11
+
12
+ /* The Cost tab's unit choice persists: a Max user who picked Quota once should
13
+ not have to pick it every time the panel reloads. It is a per-browser display
14
+ preference, exactly like the theme and the language — never a project setting,
15
+ and never written to config. */
16
+ const COST_UNIT_KEY = "orc-ui-cost-unit";
17
+ const COST_UNITS = ["tokens", "quota", "usd"];
18
+ // Written out in full, never assembled from `"cost.unit." + u` — a key built
19
+ // from a fragment is invisible to the i18n coverage check.
20
+ const COST_UNIT_KEY_OF = { tokens: "cost.unit.tokens", quota: "cost.unit.quota", usd: "cost.unit.usd" };
21
+
22
+ PANELS.stats = function (host) {
23
+ head(host, t("stats.title"), t("stats.sub"));
24
+ const tabs = el("div", "tabs");
25
+ const body = el("div", "stack");
26
+ let active = "usage";
27
+ const mk = (id, label) => {
28
+ const b = el("button", "tab" + (id === active ? " tab-on" : ""), label);
29
+ b.type = "button";
30
+ b.addEventListener("click", () => {
31
+ active = id;
32
+ for (const x of tabs.children) x.classList.toggle("tab-on", x === b);
33
+ body.replaceChildren();
34
+ (id === "usage" ? renderStatsUsage : renderStatsCost)(body);
35
+ });
36
+ return b;
37
+ };
38
+ tabs.append(mk("usage", t("stats.tab.usage")), mk("cost", t("stats.tab.cost")));
39
+ host.append(tabs, body);
40
+ renderStatsUsage(body);
41
+ };
42
+
43
+ function renderStatsUsage(host) {
44
+ section(
45
+ host,
46
+ () => read("/api/stats").then((r) => r.data),
47
+ (d) => {
48
+ if (!d.runs) return empty(t("stats.empty"), t("stats.emptyHint", { dir: d.log_dir }));
49
+ const out = frag();
50
+
51
+ const tiles = el("div", "grid grid-3");
52
+ tiles.append(statTile(t("stats.runs"), String(d.runs), `${d.from} → ${d.to}`));
53
+ tiles.append(statTile(t("stats.dispatches"), String(d.dispatches)));
54
+ tiles.append(
55
+ statTile(t("stats.downgrades"), String(d.downgrades), t("stats.downgradesNote"), d.downgrades ? "warn" : "ok")
56
+ );
57
+ out.append(tiles);
58
+
59
+ // Lane and agent NAMES are the CLI's — only the card titles are ours.
60
+ out.append(barCard(t("stats.lanes"), d.lanes, (k) => (k === "unknown" ? "(no lane)" : "/" + k)));
61
+ if (Object.keys(d.agents || {}).length) out.append(barCard(t("stats.agents"), d.agents, (k) => k.replace(/^orc-/, "")));
62
+
63
+ const health = card(t("stats.health"));
64
+ health.append(
65
+ kvList([
66
+ [t("stats.unfinished"), String(d.unfinished)],
67
+ [t("stats.unknownLane"), d.unknown_lane ? String(d.unknown_lane) + " (pre-v0.34.2 bootstrap files)" : "0"],
68
+ [t("stats.logDir"), d.log_dir],
69
+ ])
70
+ );
71
+ health.append(el("div", "note", t("stats.note")));
72
+ out.append(health);
73
+ return out;
74
+ }
75
+ );
76
+ }
77
+
78
+ /* --------------------------------------------------------------- STATS · COST
79
+ Unit-aware, because a dollar figure is the wrong headline for most Claude Code
80
+ users: on Pro or Max you burn a 5-hour window, not an invoice.
81
+
82
+ THE STACKED BAR EXISTS SO CACHE-READ IS VISIBLY SEPARATE. A single-value bar
83
+ would re-hide the exact thing the four-component vector exists to expose — and
84
+ the four components are the CLI's, never recomputed here. */
85
+
86
+ const kTokUi = (n) =>
87
+ n >= 1e6 ? (n / 1e6).toFixed(2) + "M" : n >= 1000 ? Math.round(n / 1000) + "k" : String(Math.round(n || 0));
88
+
89
+ function costUnit() {
90
+ try {
91
+ const v = localStorage.getItem(COST_UNIT_KEY);
92
+ return COST_UNITS.includes(v) ? v : "tokens";
93
+ } catch (_) {
94
+ return "tokens";
95
+ }
96
+ }
97
+
98
+ async function renderStatsCost(host) {
99
+ host.replaceChildren(skeleton(5));
100
+ const url = statsPlanPath ? "/api/budget/forecast?plan=" + encodeURIComponent(statsPlanPath) : "/api/budget/rates";
101
+ const [main, rates] = await Promise.all([
102
+ read(url).catch(() => ({ data: null })),
103
+ read("/api/budget/rates").catch(() => ({ data: null })),
104
+ ]);
105
+ const out = frag();
106
+
107
+ // --- the plan picker. `browse` reuses /api/fs/list, which is a DIRECTORY
108
+ // lister: names only, never a file's contents. The server passes the PATH to
109
+ // `orc budget forecast`; nothing here opens the plan.
110
+ const pick = card(t("cost.plan"));
111
+ const row = el("div", "row-actions");
112
+ const input = el("input", "input");
113
+ input.type = "text";
114
+ input.value = statsPlanPath || "";
115
+ input.placeholder = t("cost.planPlaceholder");
116
+ const browse = el("button", "btn btn-ghost btn-sm", t("cost.browse"));
117
+ browse.type = "button";
118
+ browse.addEventListener("click", () => pickFolder((p) => (input.value = p)));
119
+ const go = el("button", "btn btn-sm", t("cost.forecast"));
120
+ go.type = "button";
121
+ go.addEventListener("click", () => {
122
+ statsPlanPath = input.value.trim();
123
+ host.replaceChildren();
124
+ renderStatsCost(host);
125
+ });
126
+ row.append(input, browse, go);
127
+ pick.append(row);
128
+ pick.append(el("div", "note", t("cost.planOnly")));
129
+ out.append(pick);
130
+
131
+ const d = main.data;
132
+ if (!statsPlanPath || !d || !d.ok || !d.lanes) {
133
+ const c = card(t("cost.title"));
134
+ c.append(empty(t("cost.noForecast"), t("cost.noForecastHint")));
135
+ if (rates.data && rates.data.dispatches_joined) c.append(ratesCard(rates.data));
136
+ else c.append(laneCommand("orc budget calibrate", t("cost.calibrateWhy")));
137
+ out.append(c);
138
+ host.replaceChildren(out);
139
+ await costDocuments(out);
140
+ return;
141
+ }
142
+
143
+ // --- the unit switch
144
+ const unit = costUnit();
145
+ const c = card(t("cost.title"), unitSwitch(unit, host));
146
+ c.append(el("div", "note", t("cost.sub", { tasks: d.tasks, waves: d.waves })));
147
+
148
+ // --- one stacked bar per lane
149
+ const maxRaw = Math.max(...d.lanes.map((l) => l.raw || 0), 1);
150
+ const bars = el("div", "bars");
151
+ for (const l of d.lanes) {
152
+ const r = el("div", "bar-row");
153
+ r.append(el("div", "bar-label", l.cmd || l.lane));
154
+ if (!l.raw) {
155
+ // A lane with no measurable cost is NOT free. Saying so is the honest
156
+ // rendering; a zero-length bar would read as "cheapest".
157
+ const box = el("div", "bar-track");
158
+ box.append(el("div", "bar-none", t("cost.notPossible")));
159
+ r.append(box, el("div", "bar-value", "—"));
160
+ bars.append(r);
161
+ continue;
162
+ }
163
+ const track = el("div", "bar-track");
164
+ const st = el("div", "bar-stack");
165
+ // The vector's four parts, in their real proportions, from the primary
166
+ // lane's own breakdown when we have it and the lane totals otherwise.
167
+ const parts = l.lane === "orc" && d.tokens ? d.tokens.p50 : null;
168
+ if (parts) {
169
+ for (const [k, cls] of [["input", "seg-in"], ["cache_write", "seg-cw"], ["cache_read", "seg-cr"], ["output", "seg-out"]]) {
170
+ const seg = el("div", "bar-seg " + cls);
171
+ seg.title = `${k}: ${kTokUi(parts[k])}`;
172
+ st.append(seg);
173
+ requestAnimationFrame(() => seg.style.setProperty("flex-grow", String(parts[k] || 0)));
174
+ }
175
+ } else {
176
+ const seg = el("div", "bar-seg seg-cr");
177
+ st.append(seg);
178
+ requestAnimationFrame(() => seg.style.setProperty("flex-grow", "1"));
179
+ }
180
+ track.append(st);
181
+ requestAnimationFrame(() => st.style.setProperty("width", Math.max(4, (l.raw / maxRaw) * 100) + "%"));
182
+ r.append(track);
183
+ r.append(el("div", "bar-value", laneUnitValue(l, d, unit)));
184
+ if (l.lane === "orc") r.append(el("span", "bar-mark", "←"));
185
+ bars.append(r);
186
+ }
187
+ c.append(bars);
188
+
189
+ const legend = el("div", "legend");
190
+ for (const [k, cls] of [["cost.legend.in", "seg-in"], ["cost.legend.cw", "seg-cw"], ["cost.legend.cr", "seg-cr"], ["cost.legend.out", "seg-out"]]) {
191
+ const item = el("span", "legend-item");
192
+ item.append(el("span", "legend-dot " + cls));
193
+ item.append(el("span", null, t(k)));
194
+ legend.append(item);
195
+ }
196
+ c.append(legend);
197
+ c.append(el("div", "note", t("cost.cacheNote")));
198
+
199
+ // --- the honesty block. NONE of this is optional chrome: an honest range
200
+ // rendered as a confident bar is a lie the panel invented.
201
+ if (d.low_confidence_bands)
202
+ c.append(el("div", "note warn", tn(d.low_confidence_bands, "cost.lowConfidence", { min: d.min_samples })));
203
+ if (d.price_table && d.price_table.stale)
204
+ c.append(el("div", "note warn", t("cost.priceStale", { as_of: d.price_table.as_of, days: d.price_table.age_days })));
205
+ if (!d.transcripts_readable) c.append(el("div", "note warn", t("cost.noTranscripts")));
206
+ if (d.unattributed && d.unattributed.blocks)
207
+ c.append(el("div", "note", tn(d.unattributed.blocks, "cost.unattributed")));
208
+ out.append(c);
209
+
210
+ // --- context risk. The output nobody else has, so it gets its own card.
211
+ if (d.context_risk && d.context_risk.length) {
212
+ const rc = card(t("cost.contextTitle"));
213
+ rc.append(el("div", "note warn", t("cost.contextIntro")));
214
+ for (const r of d.context_risk) {
215
+ const line = el("div", "row-actions");
216
+ line.append(chip(r.task, "warn"));
217
+ line.append(el("span", null, t("cost.contextRow", { agent: r.agent.replace(/^orc-executor-/, ""), peak: kTokUi(r.peak), window: kTokUi(r.window), pct: r.pct })));
218
+ const b = el("button", "btn btn-ghost btn-sm", t("cost.contextOpenUsage"));
219
+ b.type = "button";
220
+ b.addEventListener("click", () => (location.hash = "#/knowledge"));
221
+ line.append(b);
222
+ rc.append(line);
223
+ }
224
+ rc.append(el("div", "note", t("cost.contextHint")));
225
+ out.append(rc);
226
+ }
227
+
228
+ // --- the per-band table, rendered from the CLI's own rows
229
+ const bc = card(t("cost.bands"));
230
+ const tbl = el("table", "tbl");
231
+ const thead = el("tr");
232
+ for (const h of ["cost.col.band", "cost.col.model", "cost.col.n", "cost.col.in", "cost.col.cw", "cost.col.cr", "cost.col.out", "cost.col.samples"])
233
+ thead.append(el("th", null, t(h)));
234
+ tbl.append(thead);
235
+ for (const b of d.bands || []) {
236
+ const tr = el("tr", b.samples < d.min_samples ? "row-soft" : null);
237
+ tr.append(el("td", "mono", b.band));
238
+ tr.append(el("td", null, String(b.agent || "").replace(/^orc-executor-/, "")));
239
+ tr.append(el("td", null, String(b.count)));
240
+ for (const k of ["input", "cache_write", "cache_read", "output"]) tr.append(el("td", "num", b.p50 ? kTokUi(b.p50[k]) : "—"));
241
+ tr.append(el("td", "num", String(b.samples)));
242
+ tbl.append(tr);
243
+ }
244
+ bc.append(tbl);
245
+ bc.append(el("div", "note", t("cost.bandsNote")));
246
+ out.append(bc);
247
+ out.append(laneCommand("/orc-budget", t("cost.laneWhy")));
248
+ host.replaceChildren(out);
249
+ await costDocuments(out);
250
+ }
251
+
252
+ /* DOCUMENTS (v0.49.2). `orc budget` works per RUN, and a /orc-doc document spans
253
+ several. Each row EXPANDS IN PLACE — the Runs-row rule — and fetches
254
+ `orc doc forecast --json` on first open. It duplicates no logic and names no
255
+ number itself; the card is the Docs panel's, rendered here because this is the
256
+ panel somebody opens when the question is "what is this costing me". */
257
+ async function costDocuments(out) {
258
+ let list = null;
259
+ try {
260
+ list = (await read("/api/doc")).data;
261
+ } catch (_) {}
262
+ if (!list || !(list.documents || []).length) return;
263
+
264
+ const c = card(t("cost.docs"));
265
+ c.append(el("div", "note", t("cost.docsNote")));
266
+ const box = el("div", "run-list");
267
+ for (const doc of list.documents) {
268
+ const row = el("div", "run-row");
269
+ const head = el("button", "run-card", null);
270
+ head.type = "button";
271
+ head.setAttribute("aria-expanded", "false");
272
+ head.append(el("span", "run-caret", "▸"));
273
+ // The CLI's own word for the document's state — never a friendlier synonym.
274
+ head.append(chip(doc.document, doc.document === "present" ? "ok" : ""));
275
+ const mid = el("div", "run-mid");
276
+ mid.append(el("div", "run-slug", doc.title || doc.slug));
277
+ mid.append(el("div", "run-where", `${String(doc.type).toUpperCase()} · ${doc.slug}`));
278
+ head.append(mid, el("div", "run-age", `${doc.sections_written}/${doc.sections_total}`));
279
+
280
+ const pane = el("div", "run-pane stack stack-sm");
281
+ pane.append(skeleton(3));
282
+ const inner = el("div", "run-body-inner");
283
+ inner.append(pane);
284
+ const fold = el("div", "run-body");
285
+ fold.append(inner);
286
+ // ONE loader, so "recompute" refetches THIS row and nothing else — it must
287
+ // never re-render the Docs panel's detail into a card that is not it.
288
+ const load = async () => {
289
+ pane.replaceChildren(skeleton(3));
290
+ const q = "?slug=" + encodeURIComponent(doc.slug);
291
+ const fc = (await read("/api/doc/forecast" + q).catch(() => ({ data: null }))).data;
292
+ const cost = (await read("/api/doc/cost" + q).catch(() => ({ data: null }))).data;
293
+ const f = frag();
294
+ if (fc) f.append(docForecastCard(fc, doc.slug, load));
295
+ if (cost) f.append(docCostCard(cost));
296
+ pane.replaceChildren(f);
297
+ };
298
+ let loaded = false;
299
+ head.addEventListener("click", () => {
300
+ const open = !row.classList.contains("open");
301
+ row.classList.toggle("open", open);
302
+ head.setAttribute("aria-expanded", String(open));
303
+ if (!open || loaded) return;
304
+ loaded = true;
305
+ load();
306
+ });
307
+ row.append(head, fold);
308
+ box.append(row);
309
+ }
310
+ c.append(box);
311
+ out.append(c);
312
+ }
313
+
314
+ let statsPlanPath = "";
315
+
316
+ function unitSwitch(active, host) {
317
+ const wrap = el("div", "seg-ctl");
318
+ for (const u of COST_UNITS) {
319
+ const b = el("button", "seg-btn" + (u === active ? " seg-on" : ""), t(COST_UNIT_KEY_OF[u]));
320
+ b.type = "button";
321
+ b.addEventListener("click", () => {
322
+ try {
323
+ localStorage.setItem(COST_UNIT_KEY, u);
324
+ } catch (_) {}
325
+ host.replaceChildren();
326
+ renderStatsCost(host);
327
+ });
328
+ wrap.append(b);
329
+ }
330
+ return wrap;
331
+ }
332
+
333
+ function laneUnitValue(l, d, unit) {
334
+ if (unit === "usd") return l.usd === null || l.usd === undefined ? "—" : "$" + l.usd.toFixed(2);
335
+ if (unit === "quota") {
336
+ // NEVER a quota figure without a known plan — the CLI decides that, and when
337
+ // it says unavailable the cell says so rather than inventing a percentage.
338
+ if (!d.quota || !d.quota.available) return t("cost.quotaNa");
339
+ const share = d.weighted && d.weighted.p50 ? l.weighted / d.weighted.p50 : 1;
340
+ return (d.quota.window_pct * share).toFixed(1) + "%";
341
+ }
342
+ return kTokUi(l.raw);
343
+ }
344
+
345
+ function ratesCard(r) {
346
+ const c = card(t("cost.ratesTitle"));
347
+ c.append(
348
+ kvList([
349
+ [t("cost.rates.calibrated"), r.calibrated_at],
350
+ [t("cost.rates.joined"), String(r.dispatches_joined)],
351
+ [t("cost.rates.transcripts"), r.transcripts_readable ? `${r.transcript_files}` : t("cost.rates.unreadable")],
352
+ [t("cost.rates.unattributed"), `${r.unattributed.blocks}`],
353
+ ])
354
+ );
355
+ return c;
356
+ }
357
+
358
+ function barCard(title, map, label) {
359
+ const c = card(title);
360
+ const rows = Object.entries(map).sort((a, b) => b[1] - a[1]);
361
+ const max = rows.length ? rows[0][1] : 1;
362
+ const total = rows.reduce((n, r) => n + r[1], 0);
363
+ const bars = el("div", "bars");
364
+ for (const [k, n] of rows) {
365
+ const row = el("div", "bar-row");
366
+ row.append(el("div", "bar-label", label ? label(k) : k));
367
+ const track = el("div", "bar-track");
368
+ const fill = el("div", "bar-fill");
369
+ track.append(fill);
370
+ row.append(track);
371
+ row.append(el("div", "bar-value", `${n} ${Math.round((n / total) * 100)}%`));
372
+ bars.append(row);
373
+ // Set the width after insertion so the 320ms grow transition runs.
374
+ requestAnimationFrame(() => fill.style.setProperty("width", Math.max(2, (n / max) * 100) + "%"));
375
+ }
376
+ c.append(bars);
377
+ return c;
378
+ }