@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,573 @@
1
+ "use strict";
2
+ /* panels/settings.js — orc ui client
3
+ The toolbar, the tier accordions, every control kind, the score ladder.
4
+
5
+ Loaded by app.html in the order its numeric prefix names. Classic
6
+ script, no import/export: an ES module import carries no query string,
7
+ and every static request here needs the per-launch session token. */
8
+
9
+
10
+ /* ================================================================ SETTINGS == */
11
+
12
+ // The tier IDS are the CLI's (`k.tier`); only their display name and blurb are
13
+ // ours to translate. A tier name alone does not say why a key lives there, and
14
+ // "advanced" reads as "do not touch" when it means "you need a reason".
15
+ //
16
+ // Written out as a literal map rather than `t("settings.tier." + tier)` so the
17
+ // keys stay GREPPABLE: a build of a string key from a fragment is a key no
18
+ // coverage check can see, and the check is the only thing standing between a
19
+ // renamed key and a raw dotted string on somebody's screen.
20
+ const TIER_LABEL_KEY = { common: "settings.tier.common", fable5: "settings.tier.fable5", advanced: "settings.tier.advanced" };
21
+ const TIER_DESC_KEY = { common: "settings.tierDesc.common", fable5: "settings.tierDesc.fable5", advanced: "settings.tierDesc.advanced" };
22
+ const TIER_LABEL = (tier) => (TIER_LABEL_KEY[tier] ? t(TIER_LABEL_KEY[tier]) : tier);
23
+ const TIER_DESC = (tier) => (TIER_DESC_KEY[tier] ? t(TIER_DESC_KEY[tier]) : "");
24
+
25
+ // The settings toolbar: find a key by name or description across every tier,
26
+ // narrow to just what you have changed, and open/close all sections. It filters
27
+ // what is ALREADY rendered — no refetch, so it stays instant at 36 keys.
28
+ function settingsToolbar(d, tiers) {
29
+ const bar = el("div", "toolbar");
30
+
31
+ const search = el("div", "search");
32
+ const input = el("input", "text-input");
33
+ input.type = "search";
34
+ input.id = "settings-filter";
35
+ input.placeholder = t("settings.filter");
36
+ input.setAttribute("aria-label", t("settings.filterAria"));
37
+ search.append(input);
38
+ bar.append(search);
39
+
40
+ const changedWrap = el("label", "toggle");
41
+ const changed = el("input");
42
+ changed.type = "checkbox";
43
+ const overridden = d.keys.filter((k) => k.is_overridden).length;
44
+ changedWrap.append(changed, document.createTextNode(" " + t("settings.changedOnly", { n: overridden })));
45
+ changedWrap.title = overridden ? t("settings.changedTitle") : t("settings.changedNone");
46
+ if (!overridden) changed.disabled = true;
47
+ bar.append(changedWrap);
48
+
49
+ const result = el("span", "toolbar-result");
50
+ bar.append(result);
51
+
52
+ const toggleAll = el("button", "btn btn-ghost btn-sm", t("settings.collapseAll"));
53
+ toggleAll.type = "button";
54
+ toggleAll.addEventListener("click", () => {
55
+ const anyOpen = tiers.some((x) => !x.wrap.classList.contains("collapsed"));
56
+ for (const x of tiers) {
57
+ x.wrap.classList.toggle("collapsed", anyOpen);
58
+ x.wrap.querySelector(".tier-head").setAttribute("aria-expanded", String(!anyOpen));
59
+ }
60
+ toggleAll.textContent = anyOpen ? t("settings.expandAll") : t("settings.collapseAll");
61
+ });
62
+ bar.append(toggleAll);
63
+
64
+ const apply = () => {
65
+ const q = input.value.trim().toLowerCase();
66
+ const onlyChanged = changed.checked;
67
+ let shown = 0;
68
+ for (const x of tiers) {
69
+ let visible = 0;
70
+ for (const row of x.rows.children) {
71
+ const k = row.dataset.key || "";
72
+ const desc = (row.querySelector(".setting-desc") || {}).textContent || "";
73
+ const hit =
74
+ (!q || k.toLowerCase().includes(q) || desc.toLowerCase().includes(q)) &&
75
+ (!onlyChanged || row.dataset.overridden === "1");
76
+ row.classList.toggle("hidden", !hit);
77
+ if (hit) visible++;
78
+ }
79
+ shown += visible;
80
+ x.count.textContent = visible === x.total ? tn(x.total, "settings.keys") : t("settings.ofTotal", { n: visible, total: x.total });
81
+ // A tier with no matches is hidden outright — an empty titled box is
82
+ // noise between the ones that DID match.
83
+ x.wrap.classList.toggle("hidden", visible === 0);
84
+ // A filter that matches inside a closed section would look like no match
85
+ // at all, so filtering forces the section open.
86
+ if ((q || onlyChanged) && visible) {
87
+ x.wrap.classList.remove("collapsed");
88
+ x.wrap.querySelector(".tier-head").setAttribute("aria-expanded", "true");
89
+ }
90
+ }
91
+ result.textContent = q || onlyChanged ? tn(shown, "settings.matches") : "";
92
+ result.classList.toggle("toolbar-result-none", (q || onlyChanged) && shown === 0);
93
+ };
94
+
95
+ input.addEventListener("input", apply);
96
+ changed.addEventListener("change", apply);
97
+ // Esc clears rather than blurs: the filter is the thing in your way.
98
+ input.addEventListener("keydown", (e) => {
99
+ if (e.key === "Escape" && input.value) {
100
+ e.stopPropagation();
101
+ input.value = "";
102
+ apply();
103
+ }
104
+ });
105
+ return bar;
106
+ }
107
+
108
+ PANELS.settings = function (host) {
109
+ const actions = el("div", "row-actions");
110
+ const profBtn = el("button", "btn btn-sm", t("settings.profiles"));
111
+ profBtn.type = "button";
112
+ profBtn.addEventListener("click", showProfiles);
113
+ const recBtn = el("button", "btn btn-sm", t("settings.recommend"));
114
+ recBtn.type = "button";
115
+ recBtn.addEventListener("click", showRecommend);
116
+ actions.append(profBtn, recBtn);
117
+ head(host, t("settings.title"), t("settings.sub"), actions);
118
+
119
+ const body = el("div", "stack");
120
+ host.append(body);
121
+ renderSettings(body);
122
+ };
123
+
124
+ async function renderSettings(body) {
125
+ body.replaceChildren(skeleton(8));
126
+ let d;
127
+ try {
128
+ d = (await read("/api/config")).data;
129
+ } catch (e) {
130
+ body.replaceChildren(empty(t("settings.readFail"), String(e.message)));
131
+ return;
132
+ }
133
+
134
+ const out = frag();
135
+
136
+ // One edit set per render, so a re-render is also the discard: there is no
137
+ // way for a staged value to outlive the data it was staged against.
138
+ let bar = null;
139
+ const edits = editSet(() => {
140
+ if (bar) bar.paint();
141
+ for (const row of body.querySelectorAll(".setting[data-key]")) {
142
+ row.classList.toggle("staged", edits.map.has(row.dataset.key));
143
+ }
144
+ });
145
+
146
+ const pathCard = card(t("settings.file.title"));
147
+ pathCard.append(
148
+ kvList([
149
+ [t("settings.file.file"), d.config_path],
150
+ [t("settings.file.state"), d.exists ? t("settings.file.exists") : t("settings.file.absent")],
151
+ ])
152
+ );
153
+ // Permanently on, deliberately not a key — say so, or somebody hunts for the
154
+ // switch that does not exist.
155
+ pathCard.append(el("div", "note", t("settings.file.traceNote")));
156
+ if ((d.legacy_keys || []).length)
157
+ for (const l of d.legacy_keys)
158
+ pathCard.append(el("div", "note", `\`${l.key}\` is still in the file — it was renamed to \`${l.renamed_to}\`, and is read as that.`));
159
+ out.append(pathCard);
160
+
161
+ // The ladder is a DIAGRAM, not an editor, and it re-morphs when opus5_only
162
+ // flips — which is how the precedence rule gets taught rather than described.
163
+ out.append(ladderCard(d.score_table));
164
+
165
+ // 36 keys in three flat lists is a wall, and the answer to "where is the one
166
+ // I want" was scrolling. Each tier is now its own collapsible card, and the
167
+ // toolbar filters across ALL of them at once — so finding a key never depends
168
+ // on knowing which tier somebody filed it under.
169
+ const tiers = [];
170
+ out.append(settingsToolbar(d, tiers));
171
+
172
+ for (const tier of ["common", "fable5", "advanced"]) {
173
+ const keys = d.keys.filter((k) => k.tier === tier);
174
+ if (!keys.length) continue;
175
+
176
+ const allInert = keys.every((k) => k.is_shadowed);
177
+ const wrap = el("div", "card tier");
178
+ wrap.dataset.tier = tier;
179
+
180
+ const h = el("button", "tier-head");
181
+ h.type = "button";
182
+ h.setAttribute("aria-expanded", "true");
183
+ h.append(el("span", "tier-caret", "▸"));
184
+ h.append(el("h2", null, TIER_LABEL(tier)));
185
+ const count = el("span", "tier-count", tn(keys.length, "settings.keys"));
186
+ h.append(count);
187
+ if (allInert) h.append(chip(t("settings.inert"), "warn"));
188
+
189
+ const rows = el("div", "tier-rows");
190
+ for (const k of keys) rows.append(settingRow(k, body, edits));
191
+
192
+ // Collapse is height-animated rather than a display swap, so the rows below
193
+ // it move with the section instead of teleporting.
194
+ h.addEventListener("click", () => {
195
+ const open = h.getAttribute("aria-expanded") === "true";
196
+ h.setAttribute("aria-expanded", String(!open));
197
+ wrap.classList.toggle("collapsed", open);
198
+ });
199
+
200
+ // The collapse animates `grid-template-rows: 1fr -> 0fr`, which needs a real
201
+ // element child to collapse against — so the body is wrapped, not folded in
202
+ // place. `height: auto` cannot be transitioned; this can.
203
+ const inner = el("div", "tier-body-inner");
204
+ inner.append(el("div", "tier-desc", TIER_DESC(tier)), rows);
205
+ const bodyWrap = el("div", "tier-body");
206
+ bodyWrap.append(inner);
207
+
208
+ wrap.append(h, bodyWrap);
209
+ tiers.push({ tier, wrap, rows, count, total: keys.length });
210
+ out.append(wrap);
211
+ }
212
+
213
+ if ((d.hand_edited || []).length) {
214
+ const c = card(t("settings.handEdited.title"));
215
+ c.append(el("div", "note", t("settings.handEdited.note")));
216
+ for (const k of d.hand_edited) {
217
+ const row = el("div", "setting" + (k.is_shadowed ? " shadowed" : ""));
218
+ const left = el("div");
219
+ const name = el("div", "setting-name");
220
+ name.append(document.createTextNode(k.key));
221
+ if (k.is_shadowed) {
222
+ const lock = el("span", "lock");
223
+ lock.append(document.createTextNode("🔒 " + t("settings.shadowed")));
224
+ name.append(lock);
225
+ }
226
+ left.append(name);
227
+ left.append(el("div", "setting-desc", t("settings.handEdited.readonly")));
228
+ if (k.shadow_reason) left.append(el("div", "shadow-why", k.shadow_reason));
229
+ const right = el("div", "setting-control");
230
+ right.append(el("div", "readonly-value", String(k.value)));
231
+ row.append(left, right);
232
+ c.append(row);
233
+ }
234
+ out.append(c);
235
+ }
236
+
237
+ // Last block on the panel, and it sticks to the bottom of the viewport once
238
+ // something is pending: with 36 keys across three tiers, an Apply you have to
239
+ // go looking for is an Apply that gets forgotten.
240
+ bar = settingsEditBar(edits, body);
241
+ out.append(bar);
242
+
243
+ body.replaceChildren(out);
244
+ }
245
+
246
+ function ladderCard(table) {
247
+ const c = card(t("settings.ladder.title"));
248
+ c.id = "ladder-card"; // the FLIP morph finds it by id, never by a :has() query
249
+ // `base` is the CLAUDE table that resolves. Since v0.50.0 `active` can be a
250
+ // COMPOSITE (`extra+opus5_only`) because an `orc extra` route row overlays
251
+ // the bands it covers — so branching on `active` here would fall through to
252
+ // the default arm and draw the WRONG ladder the moment Extra is armed. The
253
+ // overlay itself is the Extra panel's rail; this card stays the Claude
254
+ // ladder, which is exactly what it has always been.
255
+ const active = table.base || table.active;
256
+ c.append(
257
+ el(
258
+ "div",
259
+ "note",
260
+ active === "opus5_only"
261
+ ? t("settings.ladder.opus5")
262
+ : active === "rubric_bands_override"
263
+ ? t("settings.ladder.override")
264
+ : t("settings.ladder.default")
265
+ )
266
+ );
267
+ const ladder = el("div", "ladder");
268
+ ladder.id = "ladder";
269
+ const rows = active === "opus5_only" ? table.opus5_only : table.default;
270
+ for (const r of rows) {
271
+ const rung = el("div", "rung");
272
+ rung.dataset.agent = r.agent;
273
+ rung.append(el("span", "rung-band", `[${r.from},${r.to}${r.inclusive_to ? "]" : ")"}`));
274
+ const right = el("div");
275
+ const bar = el("div", "rung-bar");
276
+ bar.style.width = Math.max(6, ((r.to - r.from) / 100) * 100) + "%";
277
+ right.append(bar, el("div", "rung-agent", r.agent));
278
+ rung.append(right);
279
+ ladder.append(rung);
280
+ }
281
+ c.append(ladder);
282
+ c.append(el("div", "ladder-note", t("settings.ladder.note")));
283
+ return c;
284
+ }
285
+
286
+ // FLIP: measure the old rungs, swap in the new table, then animate each rung
287
+ // from where it used to be. The morph is what makes the precedence rule land.
288
+ function morphLadder(oldCard, newCard) {
289
+ const before = new Map();
290
+ for (const r of oldCard.querySelectorAll(".rung")) before.set(r.dataset.agent, r.getBoundingClientRect());
291
+ oldCard.replaceWith(newCard);
292
+ if (matchMedia("(prefers-reduced-motion: reduce)").matches) return;
293
+ for (const r of newCard.querySelectorAll(".rung")) {
294
+ const from = before.get(r.dataset.agent);
295
+ if (!from) {
296
+ r.animate([{ opacity: 0, transform: "scaleY(.4)" }, { opacity: 1, transform: "none" }], { duration: 220, easing: "cubic-bezier(.2,.7,.3,1)" });
297
+ continue;
298
+ }
299
+ const to = r.getBoundingClientRect();
300
+ const dy = from.top - to.top;
301
+ if (!dy) continue;
302
+ r.animate([{ transform: `translateY(${dy}px)` }, { transform: "none" }], { duration: 260, easing: "cubic-bezier(.2,.7,.3,1)" });
303
+ }
304
+ }
305
+
306
+ function settingRow(k, panelBody, edits) {
307
+ const row = el("div", "setting" + (k.is_shadowed ? " shadowed" : ""));
308
+ row.dataset.key = k.key;
309
+ // Read by the toolbar's "changed only" filter. It is on the row rather than
310
+ // recomputed from the control, because the control's shape differs per kind.
311
+ row.dataset.overridden = k.is_overridden ? "1" : "0";
312
+
313
+ const left = el("div");
314
+ const name = el("div", "setting-name");
315
+ name.append(document.createTextNode(k.key));
316
+ if (k.is_overridden) name.append(el("span", "dot"));
317
+ if (k.is_shadowed) {
318
+ const lock = el("span", "lock");
319
+ lock.append(document.createTextNode("🔒 " + t("settings.shadowed")));
320
+ name.append(lock);
321
+ }
322
+ left.append(name);
323
+ // `k.desc` and `k.shadow_reason` are the CLI's registry text — never
324
+ // translated. They name keys, values and precedence rules by their real ids.
325
+ left.append(el("div", "setting-desc", k.desc));
326
+ if (k.shadow_reason) left.append(el("div", "shadow-why", k.shadow_reason));
327
+
328
+ const right = el("div", "setting-control");
329
+ right.append(controlFor(k, edits));
330
+ if (k.is_overridden) {
331
+ const reset = el("button", "btn btn-ghost btn-sm", t("setting.resetTo", { value: String(k.default) }));
332
+ reset.type = "button";
333
+ reset.addEventListener("click", () => edits.reset(k.key));
334
+ right.append(reset);
335
+ }
336
+
337
+ row.append(left, right);
338
+ return row;
339
+ }
340
+
341
+ // The control follows the VALIDATOR, not a hand-kept table: enum → segmented,
342
+ // int/range → stepper with the options list as presets, path/repo/model → a
343
+ // text input whose validation is the CLI's own exit code.
344
+ //
345
+ // Since v0.44.1 a control STAGES its value instead of writing it. Each one also
346
+ // repaints its own selected state from the staged value, because nothing
347
+ // re-renders until Apply — a segmented control that does not follow your click
348
+ // would look broken, and a click that neither writes nor moves is worse than no
349
+ // control at all.
350
+ function controlFor(k, edits) {
351
+ const c = k.control || { kind: "text" };
352
+ const original = String(k.value);
353
+ const stage = (value) => edits.set(k.key, String(value), original);
354
+
355
+ if (c.kind === "enum") {
356
+ const choices = c.choices || k.options || [];
357
+ const seg = el("div", "seg");
358
+ const paint = (v) => {
359
+ for (const b of seg.children) b.setAttribute("aria-pressed", String(b.dataset.value === String(v)));
360
+ };
361
+ for (const opt of choices) {
362
+ const b = el("button", null, String(opt));
363
+ b.type = "button";
364
+ b.dataset.value = String(opt);
365
+ b.addEventListener("click", () => {
366
+ stage(String(opt));
367
+ paint(String(opt));
368
+ });
369
+ seg.append(b);
370
+ }
371
+ paint(original);
372
+ return seg;
373
+ }
374
+
375
+ if (c.kind === "int" || c.kind === "range") {
376
+ const wrap = el("div", "stepper");
377
+ const input = el("input");
378
+ input.type = "number";
379
+ input.value = original;
380
+ if (c.min !== null && c.min !== undefined) input.min = String(c.min);
381
+ if (c.max !== null && c.max !== undefined) input.max = String(c.max);
382
+ // No `set` button here any more: the edit bar's Apply is the one commit
383
+ // point, so a second button beside every number would be two ideas of what
384
+ // "save" means.
385
+ input.addEventListener("input", () => stage(input.value));
386
+ wrap.append(input);
387
+ const presets = (k.options || []).filter((o) => String(o) !== original);
388
+ if (presets.length) {
389
+ const seg = el("div", "seg");
390
+ for (const p of presets.slice(0, 5)) {
391
+ const b = el("button", null, String(p));
392
+ b.type = "button";
393
+ b.addEventListener("click", () => {
394
+ input.value = String(p);
395
+ stage(String(p));
396
+ });
397
+ seg.append(b);
398
+ }
399
+ const box = el("div");
400
+ box.append(wrap, seg);
401
+ box.className = "setting-control";
402
+ return box;
403
+ }
404
+ return wrap;
405
+ }
406
+
407
+ if (c.kind === "subset") {
408
+ const chosen = new Set(
409
+ original
410
+ .replace(/^\[|\]$/g, "")
411
+ .split(",")
412
+ .map((s) => s.trim())
413
+ .filter(Boolean)
414
+ );
415
+ const seg = el("div", "seg");
416
+ for (const opt of c.choices || []) {
417
+ const b = el("button", null, String(opt));
418
+ b.type = "button";
419
+ b.setAttribute("aria-pressed", String(chosen.has(opt)));
420
+ b.addEventListener("click", () => {
421
+ chosen.has(opt) ? chosen.delete(opt) : chosen.add(opt);
422
+ b.setAttribute("aria-pressed", String(chosen.has(opt)));
423
+ stage([...chosen].join(",") || "");
424
+ });
425
+ seg.append(b);
426
+ }
427
+ return seg;
428
+ }
429
+
430
+ // path / repo / free text — validation comes from the CLI's exit code, which
431
+ // means the rules can never drift from the ones a terminal user gets.
432
+ const wrap = el("div");
433
+ wrap.className = "setting-control";
434
+ const input = el("input", "text-input");
435
+ input.value = original;
436
+ input.addEventListener("input", () => stage(input.value));
437
+ wrap.append(input);
438
+ return wrap;
439
+ }
440
+
441
+ // The Settings edit bar. Reset is `orc config reset` with NO key — the CLI's
442
+ // own "put every key back to its default", not a loop of per-key writes. It is
443
+ // a real write, so it is confirmed and it discards anything staged first: a
444
+ // reset that silently kept four pending edits queued behind it would apply them
445
+ // straight back over the defaults.
446
+ function settingsEditBar(edits, panelBody) {
447
+ const bar = editBar(edits, {
448
+ resetLabel: t("edits.resetAll"),
449
+ onApply: async (btn) => {
450
+ await applyEdits(edits, { set: "/api/config/set", reset: "/api/config/reset" }, btn);
451
+ await rerenderSettings(panelBody);
452
+ },
453
+ onReset: () => {
454
+ modal({
455
+ title: t("edits.resetAllTitle"),
456
+ body: (() => {
457
+ const box = el("div", "stack stack-sm");
458
+ box.append(el("div", null, t("edits.resetAllBody")));
459
+ box.append(el("div", "action-cmd", "orc config reset"));
460
+ return box;
461
+ })(),
462
+ actions: [
463
+ { label: t("common.cancel"), onClick: (c) => c() },
464
+ {
465
+ label: t("edits.resetAllApply"),
466
+ cls: "btn-danger",
467
+ onClick: async (close) => {
468
+ close();
469
+ edits.clear();
470
+ const r = await post("/api/config/reset", {});
471
+ toast(r.command, r.ok ? "ok" : "bad", r.output);
472
+ await rerenderSettings(panelBody);
473
+ },
474
+ },
475
+ ],
476
+ });
477
+ },
478
+ onCancel: () => rerenderSettings(panelBody),
479
+ });
480
+ return bar;
481
+ }
482
+
483
+ // A re-render must not lose the ladder morph, so the ladder is swapped through
484
+ // FLIP while everything else is replaced outright.
485
+ async function rerenderSettings(panelBody) {
486
+ const old = panelBody.querySelector("#ladder-card");
487
+ const snapshot = old ? old.cloneNode(true) : null;
488
+ await renderSettings(panelBody);
489
+ const fresh = panelBody.querySelector("#ladder-card");
490
+ // Only morph when the table ACTUALLY changed — i.e. opus5_only was flipped.
491
+ // Any other setting re-renders without a distracting animation.
492
+ if (snapshot && fresh && snapshot.textContent !== fresh.textContent) {
493
+ // Put the old one back for a beat so FLIP has real geometry to measure.
494
+ fresh.parentNode.replaceChild(snapshot, fresh);
495
+ morphLadder(snapshot, fresh);
496
+ }
497
+ }
498
+
499
+ async function showProfiles() {
500
+ const d = (await read("/api/config/profiles")).data;
501
+ const body = el("div", "stack stack-sm");
502
+ body.append(el("div", "note", t("profiles.note")));
503
+ for (const p of d.profiles) {
504
+ const c = el("div", "action");
505
+ const left = el("div");
506
+ // Profile name and description come from the CLI's registry — untranslated.
507
+ left.append(el("div", "setting-name", p.name));
508
+ left.append(el("div", "setting-desc", p.desc));
509
+ if (p.changes.length) {
510
+ const list = el("div", "note");
511
+ list.textContent = t("profiles.wouldChange", {
512
+ list: p.changes.map((c2) => `${c2.key} ${c2.from} → ${c2.to}`).join(", "),
513
+ });
514
+ left.append(list);
515
+ } else left.append(el("div", "note", t("profiles.noChange")));
516
+ const apply = el("button", "btn btn-sm btn-allow-busy" + (p.changes.length ? " btn-primary" : ""), t("profiles.apply"));
517
+ apply.type = "button";
518
+ apply.disabled = !p.changes.length;
519
+ apply.addEventListener("click", async () => {
520
+ const r = await post("/api/config/profile", { name: p.name });
521
+ toast(r.command, r.ok ? "ok" : "bad", r.output);
522
+ close();
523
+ route();
524
+ });
525
+ c.append(left, apply);
526
+ body.append(c);
527
+ }
528
+ const close = modal({ title: t("profiles.title"), body, actions: [{ label: t("common.close"), onClick: (c) => c() }] });
529
+ }
530
+
531
+ async function showRecommend() {
532
+ const d = (await read("/api/config/recommend")).data;
533
+ const body = el("div", "stack stack-sm");
534
+ body.append(el("div", "note", t("recommend.note")));
535
+ const list = el("ul");
536
+ for (const r of d.reasons) {
537
+ const li = el("li", "note", "• " + r);
538
+ list.append(li);
539
+ }
540
+ body.append(list);
541
+ const pick = el("div", "action");
542
+ const left = el("div");
543
+ left.append(el("div", "setting-name", d.recommended));
544
+ left.append(el("div", "setting-desc", d.desc));
545
+ const apply = el("button", "btn btn-sm btn-primary btn-allow-busy", t("recommend.applyIt", { name: d.recommended }));
546
+ apply.type = "button";
547
+ apply.addEventListener("click", async () => {
548
+ const r = await post("/api/config/profile", { name: d.recommended });
549
+ toast(r.command, r.ok ? "ok" : "bad", r.output);
550
+ close();
551
+ route();
552
+ });
553
+ pick.append(left, apply);
554
+ body.append(pick);
555
+ const close = modal({ title: t("recommend.title"), body, actions: [{ label: t("common.close"), onClick: (c) => c() }] });
556
+ }
557
+
558
+ /* ==================================================================== RUNS == */
559
+
560
+ /* THE LIST IS THE DETAIL VIEW (v0.43.6).
561
+ This panel used to be a list with a detail CARD underneath it: clicking the
562
+ fourth run rendered its checkpoint below run forty. On a repo with any
563
+ history that means scrolling past the entire list to read what you just
564
+ clicked, and then scrolling back up to click the next one — the list grows,
565
+ so the problem grows with it, which is the shape of a design that does not
566
+ survive its own success.
567
+
568
+ Now every row EXPANDS IN PLACE. The detail is a child of the row, animated
569
+ open with the same `grid-template-rows: 0fr -> 1fr` fold the settings tiers
570
+ use, so what you clicked stays exactly where your eye already is. One row is
571
+ open at a time — an accordion, not a set of toggles — because two open runs
572
+ re-create the scrolling problem in miniature. Detail is fetched on FIRST open
573
+ and then kept, so re-opening a row is instant and costs nothing. */