@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,488 @@
1
+ "use strict";
2
+ /* 90-tour.js — orc ui client
3
+ refreshJob (the maintenance job poller) plus the guided tour.
4
+
5
+ A tour step is MODAL: .tour-block sits ABOVE the highlighted element and a
6
+ capture-phase key handler makes Next/Skip the only live controls. The upgrade
7
+ spotlight is the ONE opt-out, because blocking it would block the click that
8
+ dismisses it. A spotlight re-places on ANY layout change via a ResizeObserver
9
+ AND a MutationObserver — never RO alone.
10
+
11
+ Loaded by app.html in the order its numeric prefix names. Classic
12
+ script, no import/export: an ES module import carries no query string,
13
+ and every static request here needs the per-launch session token. */
14
+
15
+
16
+ let jobPoll = null;
17
+ async function refreshJob() {
18
+ const host = document.getElementById("job-card");
19
+ if (!host) return;
20
+ let j;
21
+ try {
22
+ j = await api("/api/job");
23
+ } catch (_) {
24
+ return;
25
+ }
26
+ host.replaceChildren();
27
+ if (!j.id) {
28
+ const h0 = el("div", "card-head");
29
+ h0.append(el("h2", null, t("maintenance.lastRun")));
30
+ host.append(h0, el("div", "note", t("maintenance.nothingRun")));
31
+ return;
32
+ }
33
+ const h = el("div", "card-head");
34
+ h.append(el("h2", null, j.command));
35
+ h.append(
36
+ chip(
37
+ j.running ? t("maintenance.running") : j.exit_code === 0 ? t("common.done") : t("maintenance.failed"),
38
+ j.running ? "info" : j.exit_code === 0 ? "ok" : "bad"
39
+ )
40
+ );
41
+ host.append(h);
42
+ const out = el("pre", "job-output", j.output || t("maintenance.noOutput"));
43
+ host.append(out);
44
+ out.scrollTop = out.scrollHeight;
45
+
46
+ if (j.running) {
47
+ setBusy(true);
48
+ clearTimeout(jobPoll);
49
+ jobPoll = setTimeout(refreshJob, 700);
50
+ } else {
51
+ setBusy(false);
52
+ clearTimeout(jobPoll);
53
+ jobPoll = null;
54
+ // The command that just succeeded replaced the code this page is running.
55
+ // The output is already rendered above, so nothing is lost by handing over
56
+ // now — and the reload is what makes an upgrade visible without the user
57
+ // stopping the server and starting it again.
58
+ if (j.restart_pending) handOver(host);
59
+ }
60
+ }
61
+
62
+ /* ------------------------------------------------------- restarting in place -- */
63
+
64
+ // Once per page. A second call while the handover is in flight would ask a
65
+ // server that is already leaving.
66
+ let handingOver = false;
67
+
68
+ async function handOver(host) {
69
+ if (handingOver) return;
70
+ handingOver = true;
71
+ const box = el("div", "banner");
72
+ box.append(el("div", null, t("maintenance.restarting")));
73
+ host.append(box);
74
+ try {
75
+ await post("/api/ui/restart", {});
76
+ } catch (e) {
77
+ handingOver = false;
78
+ return handOverFailed(box, e);
79
+ }
80
+ // The successor takes the same port and the same token, so THIS url stays
81
+ // valid — waiting for /api/meta to answer again is waiting for the new
82
+ // process, not for a new address.
83
+ const deadline = Date.now() + 30000;
84
+ const tryOnce = async () => {
85
+ try {
86
+ await api("/api/meta");
87
+ reloadWithToken();
88
+ return;
89
+ } catch (_) {}
90
+ if (Date.now() > deadline) {
91
+ handingOver = false;
92
+ return handOverFailed(box, new Error(t("maintenance.restartTimeout")));
93
+ }
94
+ setTimeout(tryOnce, 700);
95
+ };
96
+ // The old process needs a moment to close its socket before the new one
97
+ // answers; polling immediately just burns a failed request.
98
+ setTimeout(tryOnce, 900);
99
+ }
100
+
101
+ // A handover that did not happen leaves the OLD panel running and working. That
102
+ // is the safe resting state, so this is a note plus the two commands to type —
103
+ // never an error that takes the page down.
104
+ function handOverFailed(box, e) {
105
+ box.className = "banner banner-bad";
106
+ box.replaceChildren();
107
+ box.append(el("div", null, t("maintenance.restartFailed")));
108
+ box.append(el("div", "action-cmd", "orc ui --stop"));
109
+ box.append(el("div", "action-cmd", "orc ui"));
110
+ if (e && e.message) box.append(el("div", "note", String(e.message)));
111
+ }
112
+
113
+ /* ==================================================================== tour == */
114
+
115
+ // A spotlight tour. Two callers, two shapes:
116
+ // · the first-run walkthrough — next/skip, remembered once finished or skipped
117
+ // · the upgrade spotlight — no buttons at all; it clears when you do the thing
118
+ //
119
+ // Seen-state is per PROJECT, keyed on the project root, so a second repo gets
120
+ // its own tour and clearing it for one does not clear it for the rest. It lives
121
+ // in localStorage rather than a config key on purpose: this panel writes config
122
+ // only by shelling the CLI, and "this browser has seen the tour" is not a fact
123
+ // about the project that belongs in a file the whole team shares.
124
+ const TOUR_KEY = "orc-ui-tour-seen";
125
+
126
+ function tourSeen(root) {
127
+ try {
128
+ return JSON.parse(localStorage.getItem(TOUR_KEY) || "{}")[root || "?"] === true;
129
+ } catch (_) {
130
+ return false;
131
+ }
132
+ }
133
+ function markTourSeen(root) {
134
+ try {
135
+ const all = JSON.parse(localStorage.getItem(TOUR_KEY) || "{}");
136
+ all[root || "?"] = true;
137
+ localStorage.setItem(TOUR_KEY, JSON.stringify(all));
138
+ } catch (_) {}
139
+ }
140
+
141
+ let tourActive = null;
142
+
143
+ function clearTour() {
144
+ if (!tourActive) return;
145
+ tourActive.cleanup();
146
+ tourActive = null;
147
+ }
148
+
149
+ // One spotlight over one element. The target is found at SHOW time, never
150
+ // captured up front: panels re-render, and a held reference points at a node
151
+ // that is no longer in the document.
152
+ //
153
+ // MODALITY (v0.43.6). The guided tour is now a MODAL spotlight: while a step is
154
+ // up, Next and Skip are the only things you can click, the rail is inert, and
155
+ // the panel underneath cannot be navigated. It shipped fully click-through,
156
+ // which sounds friendlier and is not: clicking the sidebar mid-tour swapped the
157
+ // panel out from under the popover, so the ring was left pointing at an element
158
+ // that no longer existed and the step's text described a page you were no
159
+ // longer on. A tour that can be walked away from without ending is a tour that
160
+ // silently breaks.
161
+ //
162
+ // The ONE exception is the upgrade spotlight, which has no buttons and whose
163
+ // entire design is "do the thing and I go away" — it passes `interactive: true`
164
+ // and keeps the page live underneath. Modality is opt-out precisely because
165
+ // that variant is the odd one, not the rule.
166
+ function spotlight({ selector, title, text, step, total, onNext, onSkip, dismissOnClickSelector, interactive }) {
167
+ clearTour();
168
+
169
+ const target = selector ? document.querySelector(selector) : null;
170
+ // A step whose target is missing is SKIPPED, never shown floating in the
171
+ // middle of the screen pointing at nothing.
172
+ if (selector && !target) return false;
173
+
174
+ // OFF-SCREEN TARGETS (v0.44.0). A spotlight only works on something you can
175
+ // SEE. The upgrade row is the fourth action on Maintenance and sits below the
176
+ // fold on a normal window, so arriving from the changelog's "go upgrade" drew
177
+ // the ring at y≈760 in a 720px viewport — the popover floated near the bottom
178
+ // pointing at nothing, and the thing it was pointing at was off screen.
179
+ // Scroll FIRST, place after; `place()` also re-runs on every scroll, so the
180
+ // ring keeps tracking if the user scrolls away.
181
+ //
182
+ // INSTANT, not smooth. A smooth scroll needs animation frames to finish, so
183
+ // the ring's position would depend on frames arriving — and a spotlight that
184
+ // is correct only when the tab is in the foreground and unthrottled is not
185
+ // correct. The step appears in place instead of gliding to it, which is the
186
+ // right trade for the one control that has to be pointing at something.
187
+ if (target) target.scrollIntoView({ block: "center", inline: "nearest" });
188
+ // A spotlight also freezes the panel's entrance animations. `panel-in` and
189
+ // `block-in` both animate `transform`, and a running transform animation makes
190
+ // its element a STACKING CONTEXT — which traps the highlighted element's
191
+ // z-index inside the panel and decides the ring/popover ladder by accident of
192
+ // timing. With the animations off, the documented ladder is the only thing
193
+ // that orders these layers.
194
+ document.body.classList.add("tour-on");
195
+
196
+ const layer = el("div", "tour-layer");
197
+ // The blocker sits ABOVE the highlighted element and below the popover, so
198
+ // the only live controls on screen are the ones inside the popover. It is a
199
+ // real element rather than a `pointer-events: none` trick because it also
200
+ // has to swallow the click, not merely fail to receive it.
201
+ const blocker = interactive ? null : el("div", "tour-block");
202
+ const ring = el("div", "tour-ring");
203
+ const pop = el("div", "tour-pop");
204
+
205
+ const place = () => {
206
+ if (!target) return;
207
+ const r = target.getBoundingClientRect();
208
+ const pad = 6;
209
+ ring.style.top = r.top - pad + "px";
210
+ ring.style.left = r.left - pad + "px";
211
+ ring.style.width = r.width + pad * 2 + "px";
212
+ ring.style.height = r.height + pad * 2 + "px";
213
+ // Below the target unless that would run off-screen, then above it.
214
+ const below = r.bottom + 12;
215
+ const wantAbove = below + 150 > window.innerHeight;
216
+ pop.style.top = (wantAbove ? Math.max(8, r.top - 12 - pop.offsetHeight) : below) + "px";
217
+ pop.style.left = Math.min(Math.max(8, r.left), Math.max(8, window.innerWidth - pop.offsetWidth - 8)) + "px";
218
+ };
219
+
220
+ if (title) pop.append(el("div", "tour-title", title));
221
+ pop.append(el("div", "tour-text", text));
222
+
223
+ const foot = el("div", "tour-foot");
224
+ if (total) foot.append(el("span", "tour-count", t("common.step", { n: step, total })));
225
+ let nextBtn = null;
226
+ if (onSkip) {
227
+ const skip = el("button", "btn btn-ghost btn-sm btn-allow-busy", t("common.skipTour"));
228
+ skip.type = "button";
229
+ skip.addEventListener("click", onSkip);
230
+ foot.append(skip);
231
+ }
232
+ if (onNext) {
233
+ nextBtn = el("button", "btn btn-primary btn-sm btn-allow-busy", step === total ? t("common.done") : t("common.next"));
234
+ nextBtn.type = "button";
235
+ nextBtn.addEventListener("click", onNext);
236
+ foot.append(nextBtn);
237
+ }
238
+ // The upgrade spotlight has no buttons — it says what to do and waits.
239
+ if (!onNext && !onSkip) foot.append(el("span", "tour-waiting", t("common.waiting")));
240
+ pop.append(foot);
241
+
242
+ if (blocker) layer.append(blocker);
243
+ layer.append(ring, pop);
244
+ document.body.append(layer);
245
+ // Focus moves into the popover so the keyboard agrees with the mouse about
246
+ // what is live — and Enter/Space advance the tour without reaching for it.
247
+ if (nextBtn) nextBtn.focus({ preventScroll: true });
248
+ place();
249
+ // Re-place after layout settles, so the popover's own height is known — and
250
+ // again once the smooth scroll above has finished moving the target.
251
+ requestAnimationFrame(place);
252
+ const settle = [setTimeout(place, 160), setTimeout(place, 420)];
253
+
254
+ const onResize = () => place();
255
+ window.addEventListener("resize", onResize);
256
+ window.addEventListener("scroll", onResize, true);
257
+
258
+ // LAYOUT SHIFTS UNDER THE SPOTLIGHT (v0.44.1). The ring and the popover are
259
+ // `position: fixed` at coordinates measured ONCE, and this page grows things
260
+ // above the fold on its own schedule: the blue update banner lands after a
261
+ // network check, `orc doctor` adds its own banners after that, and on
262
+ // Maintenance the upgrade row fills in a version chip and a "Check again"
263
+ // button of its own. Every one of those pushes the target down by tens of
264
+ // pixels — and the ring stayed where it was, so the spotlight ended up
265
+ // framing empty space above the thing it was pointing at.
266
+ //
267
+ // Re-place on any of it. `place()` alone handles a target that merely MOVED;
268
+ // `keepInView()` handles one shoved off the viewport entirely, and is
269
+ // deliberately NOT wired to the scroll listener — a spotlight that scrolls
270
+ // back every time you scroll away is a spotlight you cannot get out of.
271
+ let adjusting = false;
272
+ const keepInView = () => {
273
+ if (!target || adjusting) return;
274
+ const r = target.getBoundingClientRect();
275
+ if (r.top >= 0 && r.bottom <= window.innerHeight) return;
276
+ adjusting = true;
277
+ target.scrollIntoView({ block: "center", inline: "nearest" });
278
+ requestAnimationFrame(() => {
279
+ adjusting = false;
280
+ });
281
+ };
282
+ const reflow = () => {
283
+ keepInView();
284
+ place();
285
+ };
286
+
287
+ // TWO observers, because one of them is not enough on its own.
288
+ //
289
+ // A ResizeObserver is the right instrument — it fires on the height change
290
+ // however it was caused, without this file having to know every place that
291
+ // can grow. But it is delivered from the RENDERING lifecycle, so a tab the
292
+ // browser has throttled (backgrounded, or not compositing) never gets the
293
+ // callback, and that is exactly a tab somebody comes back to.
294
+ //
295
+ // A MutationObserver runs off the microtask queue and needs no frames at all.
296
+ // It watches the whole document because the growth is never in one place: the
297
+ // update banner is inserted into `#banners`, doctor's banners after it, and
298
+ // the upgrade row grows a version chip INSIDE itself. Coalesced to one reflow
299
+ // per task, so a panel re-render costs one re-place, not one per node.
300
+ let ro = null;
301
+ let mo = null;
302
+ if (typeof ResizeObserver === "function") {
303
+ ro = new ResizeObserver(reflow);
304
+ for (const n of [document.body, document.getElementById("banners"), document.getElementById("panel"), target]) {
305
+ if (n) ro.observe(n);
306
+ }
307
+ }
308
+ let queued = null;
309
+ if (typeof MutationObserver === "function") {
310
+ mo = new MutationObserver(() => {
311
+ if (queued) return;
312
+ queued = setTimeout(() => {
313
+ queued = null;
314
+ reflow();
315
+ }, 0);
316
+ });
317
+ // Attributes are NOT observed on purpose: `place()` writes inline styles on
318
+ // the ring and the popover, and observing them would make this trigger
319
+ // itself forever.
320
+ mo.observe(document.body, { childList: true, subtree: true, characterData: true });
321
+ }
322
+
323
+ // The "do the thing and I go away" variant. Capture phase, so it fires even
324
+ // though the layer sits above the page.
325
+ let onDo = null;
326
+ if (dismissOnClickSelector) {
327
+ onDo = (e) => {
328
+ const hit = e.target.closest && e.target.closest(dismissOnClickSelector);
329
+ if (hit) clearTour();
330
+ };
331
+ document.addEventListener("click", onDo, true);
332
+ }
333
+
334
+ if (target) {
335
+ target.classList.add("tour-target");
336
+ // z-index only applies to positioned elements, so a static target needs
337
+ // `position: relative` to lift above the scrim. A target that is ALREADY
338
+ // positioned (the rail is sticky) must keep what it has — overriding it
339
+ // unsticks the sidebar for the duration of the tour.
340
+ if (getComputedStyle(target).position === "static") target.classList.add("tour-target-rel");
341
+ }
342
+
343
+ // A blocked tour also owns the KEYBOARD: without this, `1`–`9` still navigate
344
+ // the rail and `r` still reloads the panel, which is the same "the page moved
345
+ // out from under the step" failure the blocker exists to prevent. Only Escape
346
+ // gets through, and it means the same thing Skip does.
347
+ let onKey = null;
348
+ if (blocker) {
349
+ onKey = (e) => {
350
+ if (e.key === "Escape") {
351
+ e.preventDefault();
352
+ e.stopPropagation();
353
+ (onSkip || clearTour)();
354
+ return;
355
+ }
356
+ if (e.key === "Tab") return; // focus stays reachable inside the popover
357
+ if (pop.contains(e.target)) return;
358
+ e.preventDefault();
359
+ e.stopPropagation();
360
+ };
361
+ document.addEventListener("keydown", onKey, true);
362
+ }
363
+
364
+ tourActive = {
365
+ blocking: !!blocker,
366
+ cleanup() {
367
+ window.removeEventListener("resize", onResize);
368
+ window.removeEventListener("scroll", onResize, true);
369
+ if (onDo) document.removeEventListener("click", onDo, true);
370
+ if (onKey) document.removeEventListener("keydown", onKey, true);
371
+ if (ro) ro.disconnect();
372
+ if (mo) mo.disconnect();
373
+ if (queued) clearTimeout(queued);
374
+ for (const id of settle) clearTimeout(id);
375
+ if (target) target.classList.remove("tour-target", "tour-target-rel");
376
+ document.body.classList.remove("tour-on");
377
+ layer.remove();
378
+ },
379
+ };
380
+ return true;
381
+ }
382
+
383
+ // The first-run walkthrough. Each step names the panel it lives on, so the tour
384
+ // navigates for you rather than telling you to go somewhere. Titles and text are
385
+ // keys, not sentences — the tour is panel prose, so it translates with the rest.
386
+ // Both keys are spelled out rather than derived from a step number, for the
387
+ // same reason the tier labels are: a key assembled from a fragment is invisible
388
+ // to the coverage check that keeps the tables honest.
389
+ const TOUR_STEPS = [
390
+ { panel: "overview", selector: ".rail", title: "tour.1.title", text: "tour.1.text" },
391
+ { panel: "overview", selector: ".grid-3", title: "tour.2.title", text: "tour.2.text" },
392
+ { panel: "settings", selector: ".toolbar", title: "tour.3.title", text: "tour.3.text" },
393
+ { panel: "settings", selector: "#ladder-card", title: "tour.4.title", text: "tour.4.text" },
394
+ { panel: "runs", selector: ".run-list, .empty", title: "tour.5.title", text: "tour.5.text" },
395
+ { panel: "knowledge", selector: ".stack", title: "tour.6.title", text: "tour.6.text" },
396
+ { panel: "experiment", selector: ".lane-list", title: "tour.7.title", text: "tour.7.text" },
397
+ { panel: "maintenance", selector: ".action", title: "tour.8.title", text: "tour.8.text" },
398
+ /* v0.46.0 — four steps for the four new surfaces. Each MUST point at something
399
+ with a SIZE: the fallbacks are the reason a `.lane-cmd` is listed second in
400
+ every selector, because an empty Promises panel still renders the /orc-pact
401
+ command box and a zero-height target makes the spotlight land on nothing. */
402
+ { panel: "pact", selector: ".promise, .lane-cmd", title: "tour.9.title", text: "tour.9.text" },
403
+ { panel: "boundary", selector: ".checklist, .lane-cmd, .card", title: "tour.10.title", text: "tour.10.text" },
404
+ { panel: "handoff", selector: ".promise, .lane-cmd", title: "tour.11.title", text: "tour.11.text" },
405
+ { panel: "knowledge", selector: ".free-box, .tbl, .stack", title: "tour.12.title", text: "tour.12.text" },
406
+ /* v0.48.0 — the ribbon. Same rule as every step above: it must point at
407
+ something with a SIZE, and the ribbon only exists once a document has been
408
+ assembled — so `.lane-cmd` and `.doc-list` are the fallbacks, because an
409
+ empty Docs panel still renders the /orc-doc command box. */
410
+ { panel: "docs", selector: ".doc-ribbon-wrap, .doc-list, .lane-cmd", title: "tour.13.title", text: "tour.13.text" },
411
+ /* v0.53.0 — Extra is TABBED now, and that moved this step's target. It used
412
+ to point at the routing rail, which was correct while the panel was one
413
+ scroll: the rail rendered in every state, because it is drawn from the
414
+ Claude table and its worst case is eight Claude rows rather than nothing.
415
+ The band ladder that replaced it lives on the Routing tab, and that tab is
416
+ NOT RENDERED until something has answered — so a step pointing at it would
417
+ highlight nothing on exactly the first-run panel this tour exists for. The
418
+ boundary card is on Setup, which always exists, and it renders
419
+ unconditionally; the header strip sits outside the tabs entirely and is the
420
+ fallback. Same rule a fourth time: point at something with a SIZE. */
421
+ { panel: "extra", selector: ".ex-boundary, .ex-strip", title: "tour.14.title", text: "tour.14.text" },
422
+ ];
423
+
424
+ function startFirstRunTour(root) {
425
+ let i = 0;
426
+ const finish = () => {
427
+ clearTour();
428
+ markTourSeen(root);
429
+ toast(t("tour.finished"), "ok");
430
+ };
431
+ const show = () => {
432
+ if (i >= TOUR_STEPS.length) return finish();
433
+ const s = TOUR_STEPS[i];
434
+ const go = () => {
435
+ const ok = spotlight({
436
+ selector: s.selector,
437
+ title: t(s.title),
438
+ text: t(s.text),
439
+ step: i + 1,
440
+ total: TOUR_STEPS.length,
441
+ onNext: () => {
442
+ i++;
443
+ show();
444
+ },
445
+ onSkip: finish,
446
+ });
447
+ // A step whose target never appeared is skipped rather than shown empty.
448
+ if (!ok) {
449
+ i++;
450
+ show();
451
+ }
452
+ };
453
+ if (currentPanel !== s.panel) {
454
+ location.hash = "#/" + s.panel;
455
+ // Panels render async; wait for the body rather than guessing a delay.
456
+ waitFor(s.selector, go);
457
+ } else {
458
+ waitFor(s.selector, go);
459
+ }
460
+ };
461
+ show();
462
+ }
463
+
464
+ // Poll briefly for a selector — panels fetch before they render, so a step must
465
+ // wait for its target instead of assuming it is already there.
466
+ function waitFor(selector, cb, tries) {
467
+ const n = tries === undefined ? 40 : tries;
468
+ if (!selector || document.querySelector(selector)) return cb();
469
+ if (n <= 0) return cb();
470
+ setTimeout(() => waitFor(selector, cb, n - 1), 50);
471
+ }
472
+
473
+ // The upgrade spotlight: no next, no skip. It points at the upgrade row and
474
+ // clears the moment you click its Preview button — the tour ends because you
475
+ // did the thing, not because you dismissed it. That makes it the ONE spotlight
476
+ // that must stay click-through (`interactive: true`): blocking the page here
477
+ // would block the very click that dismisses it.
478
+ function startUpgradeSpotlight() {
479
+ waitFor("[data-action='upgrade']", () => {
480
+ spotlight({
481
+ selector: "[data-action='upgrade']",
482
+ title: t("tour.upgrade.title"),
483
+ text: t("tour.upgrade.text"),
484
+ dismissOnClickSelector: "[data-action='upgrade'] button",
485
+ interactive: true,
486
+ });
487
+ });
488
+ }
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ /* 91-shortcuts.js — orc ui client
3
+ Single keys, and ONLY when you are not typing into something.
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
+ /* =============================================================== shortcuts == */
10
+
11
+ // Keyboard nav for a panel app that is otherwise all mouse. Deliberately small
12
+ // and unmodified: single keys, and ONLY when you are not typing into something.
13
+ const SHORTCUTS = () => [
14
+ ["1 – 9, 0", t("shortcuts.panels")],
15
+ ["d · c · p · b · h · e · m", t("shortcuts.panelsLetters")],
16
+ ["/", t("shortcuts.filter")],
17
+ ["r", t("shortcuts.reload")],
18
+ ["t", t("shortcuts.theme")],
19
+ ["l", t("shortcuts.lang")],
20
+ ["?", t("shortcuts.list")],
21
+ ["Esc", t("shortcuts.escape")],
22
+ ];
23
+
24
+ // A keystroke must never be stolen from an input, a textarea or a select — that
25
+ // is how a UI eats the "r" in the middle of a path somebody is typing.
26
+ function typingInto(t) {
27
+ return !!t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.tagName === "SELECT" || t.isContentEditable);
28
+ }
29
+
30
+ function showShortcuts() {
31
+ const body = el("div", "stack stack-sm");
32
+ const list = el("dl", "kv");
33
+ for (const [key, what] of SHORTCUTS()) {
34
+ const dt = el("dt");
35
+ dt.append(el("kbd", null, key));
36
+ list.append(dt, el("dd", null, what));
37
+ }
38
+ body.append(list);
39
+ body.append(el("div", "note", t("shortcuts.note")));
40
+ modal({
41
+ title: t("shortcuts.title"),
42
+ body,
43
+ actions: [
44
+ // Dismissing the tour must never be a one-way door: it is skippable
45
+ // precisely because it can be replayed.
46
+ {
47
+ label: t("shortcuts.replay"),
48
+ onClick: (c) => {
49
+ c();
50
+ startFirstRunTour(metaInfo.project_root);
51
+ },
52
+ },
53
+ { label: t("common.close"), onClick: (c) => c() },
54
+ ],
55
+ });
56
+ }
57
+
58
+ function installShortcuts() {
59
+ document.addEventListener("keydown", (e) => {
60
+ if (e.metaKey || e.ctrlKey || e.altKey) return;
61
+ // A dialog owns the keyboard while it is open; it has its own Esc handler.
62
+ if (!$("#modal-host").hidden) return;
63
+ // …and so does a blocking tour step. Its own capture-phase handler has
64
+ // already swallowed the key by now; this is the second lock on the door.
65
+ if (tourActive && tourActive.blocking) return;
66
+ if (typingInto(e.target)) return;
67
+
68
+ if (e.key >= "0" && e.key <= "9") {
69
+ // Matched on data-idx, not on position: the rail's order is HTML's to
70
+ // decide, and a positional lookup silently rebinds every key the moment a
71
+ // panel is inserted in the middle.
72
+ const target = document.querySelector('#nav a[data-idx="' + e.key + '"]');
73
+ if (target) {
74
+ e.preventDefault();
75
+ location.hash = target.getAttribute("href");
76
+ }
77
+ return;
78
+ }
79
+ // v0.46.0: the rail outgrew ten digits, so several panels carry a LETTER key.
80
+ // Same lookup, same rule — matched on data-idx, never on position — and the
81
+ // letters are checked before the r/t/l actions so a rail key can never be
82
+ // shadowed by one of them. Adding a panel whose letter collides with an
83
+ // action would break the action; p/b/h/m/c/d were free.
84
+ //
85
+ // The class is derived from the rail rather than re-listed, because that is
86
+ // what went wrong the first time: `c` was given to Challenge in the markup
87
+ // and never added to a hardcoded `[pbhm]`, so the key did nothing and
88
+ // nothing failed. A rail key now works because it is IN THE RAIL.
89
+ if (/^[a-z]$/.test(e.key)) {
90
+ const target = document.querySelector('#nav a[data-idx="' + e.key + '"]');
91
+ if (target) {
92
+ e.preventDefault();
93
+ location.hash = target.getAttribute("href");
94
+ return;
95
+ }
96
+ }
97
+ if (e.key === "/") {
98
+ const f = $("#settings-filter");
99
+ if (f) {
100
+ e.preventDefault();
101
+ f.focus();
102
+ f.select();
103
+ }
104
+ return;
105
+ }
106
+ if (e.key === "r") {
107
+ e.preventDefault();
108
+ route();
109
+ return;
110
+ }
111
+ if (e.key === "t") {
112
+ e.preventDefault();
113
+ $("#theme-toggle").click();
114
+ return;
115
+ }
116
+ if (e.key === "l") {
117
+ e.preventDefault();
118
+ cycleLang();
119
+ return;
120
+ }
121
+ if (e.key === "?") {
122
+ e.preventDefault();
123
+ showShortcuts();
124
+ }
125
+ });
126
+ }