@oriro/orirocli 0.1.11 → 0.3.1

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 (1263) hide show
  1. package/ATTRIBUTION.md +53 -53
  2. package/LICENSE +21 -21
  3. package/README.md +10 -9
  4. package/dist/cli.js +1866 -190
  5. package/package.json +65 -64
  6. package/skills/1password/SKILL.md +118 -118
  7. package/skills/1password/references/cli-examples.md +29 -29
  8. package/skills/1password/references/get-started.md +21 -21
  9. package/skills/21stdev/SKILL.md +64 -64
  10. package/skills/algorithmic-art/LICENSE +21 -21
  11. package/skills/algorithmic-art/SKILL.md +446 -446
  12. package/skills/algorithmic-art/templates/generator_template.js +223 -223
  13. package/skills/algorithmic-art/templates/viewer.html +598 -598
  14. package/skills/apple-notes/SKILL.md +81 -81
  15. package/skills/apple-reminders/SKILL.md +122 -122
  16. package/skills/bear-notes/SKILL.md +111 -111
  17. package/skills/blogwatcher/SKILL.md +73 -73
  18. package/skills/blucli/SKILL.md +51 -51
  19. package/skills/brand-guidelines/LICENSE +21 -21
  20. package/skills/brand-guidelines/SKILL.md +76 -76
  21. package/skills/business/biz-analysis/LICENSE +21 -21
  22. package/skills/business/biz-analysis/SKILL.md +103 -103
  23. package/skills/business/biz-corporate-strategy/LICENSE +21 -21
  24. package/skills/business/biz-corporate-strategy/SKILL.md +76 -76
  25. package/skills/business/biz-customer-success/LICENSE +21 -21
  26. package/skills/business/biz-customer-success/SKILL.md +55 -55
  27. package/skills/business/biz-entrepreneurship/LICENSE +21 -21
  28. package/skills/business/biz-entrepreneurship/SKILL.md +72 -72
  29. package/skills/business/biz-hr/LICENSE +21 -21
  30. package/skills/business/biz-hr/SKILL.md +67 -67
  31. package/skills/business/biz-international/LICENSE +21 -21
  32. package/skills/business/biz-international/SKILL.md +51 -51
  33. package/skills/business/biz-leadership/LICENSE +21 -21
  34. package/skills/business/biz-leadership/SKILL.md +106 -106
  35. package/skills/business/biz-marketing-strategy/LICENSE +21 -21
  36. package/skills/business/biz-marketing-strategy/SKILL.md +119 -119
  37. package/skills/business/biz-negotiation/LICENSE +21 -21
  38. package/skills/business/biz-negotiation/SKILL.md +152 -152
  39. package/skills/business/biz-operations/LICENSE +21 -21
  40. package/skills/business/biz-operations/SKILL.md +74 -74
  41. package/skills/business/biz-project/LICENSE +21 -21
  42. package/skills/business/biz-project/SKILL.md +203 -203
  43. package/skills/business/biz-risk/LICENSE +21 -21
  44. package/skills/business/biz-risk/SKILL.md +85 -85
  45. package/skills/business/biz-sales/LICENSE +21 -21
  46. package/skills/business/biz-sales/SKILL.md +92 -92
  47. package/skills/business/biz-startup-ops/LICENSE +21 -21
  48. package/skills/business/biz-startup-ops/SKILL.md +70 -70
  49. package/skills/business/biz-strategy/LICENSE +21 -21
  50. package/skills/business/biz-strategy/SKILL.md +233 -233
  51. package/skills/business/biz-supply-chain-advanced/LICENSE +21 -21
  52. package/skills/business/biz-supply-chain-advanced/SKILL.md +68 -68
  53. package/skills/business/fin-chartered-exams/LICENSE +21 -21
  54. package/skills/business/fin-chartered-exams/SKILL.md +69 -69
  55. package/skills/camsnap/SKILL.md +49 -49
  56. package/skills/canvas/SKILL.md +82 -82
  57. package/skills/canvas-design/LICENSE +21 -21
  58. package/skills/canvas-design/SKILL.md +140 -140
  59. package/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -93
  60. package/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -93
  61. package/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -93
  62. package/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -93
  63. package/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -93
  64. package/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -93
  65. package/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -94
  66. package/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -93
  67. package/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -93
  68. package/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -93
  69. package/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -93
  70. package/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -93
  71. package/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -93
  72. package/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -93
  73. package/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -93
  74. package/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -93
  75. package/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -93
  76. package/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -93
  77. package/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -93
  78. package/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -93
  79. package/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -93
  80. package/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -93
  81. package/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -93
  82. package/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -93
  83. package/skills/coding-agent/SKILL.md +146 -146
  84. package/skills/communication/comm-business-writing/LICENSE +21 -21
  85. package/skills/communication/comm-business-writing/SKILL.md +67 -67
  86. package/skills/communication/comm-cross-cultural/LICENSE +21 -21
  87. package/skills/communication/comm-cross-cultural/SKILL.md +88 -88
  88. package/skills/communication/comm-journalism/LICENSE +21 -21
  89. package/skills/communication/comm-journalism/SKILL.md +81 -81
  90. package/skills/communication/comm-linguistics/LICENSE +21 -21
  91. package/skills/communication/comm-linguistics/SKILL.md +82 -82
  92. package/skills/communication/comm-negotiation/LICENSE +21 -21
  93. package/skills/communication/comm-negotiation/SKILL.md +120 -120
  94. package/skills/communication/comm-presentations/LICENSE +21 -21
  95. package/skills/communication/comm-presentations/SKILL.md +93 -93
  96. package/skills/communication/comm-public-speaking/LICENSE +21 -21
  97. package/skills/communication/comm-public-speaking/SKILL.md +68 -68
  98. package/skills/communication/comm-writing/LICENSE +21 -21
  99. package/skills/communication/comm-writing/SKILL.md +69 -69
  100. package/skills/craft/ai-engineering/LICENSE +21 -21
  101. package/skills/craft/ai-engineering/SKILL.md +828 -828
  102. package/skills/craft/app-builder-guide/LICENSE +21 -21
  103. package/skills/craft/app-builder-guide/SKILL.md +332 -332
  104. package/skills/craft/become-an-ai-engineer-26/CONTRIBUTING.md +46 -46
  105. package/skills/craft/become-an-ai-engineer-26/LICENSE +21 -21
  106. package/skills/craft/become-an-ai-engineer-26/README.md +270 -270
  107. package/skills/craft/become-an-ai-engineer-26/SKILL.md +667 -667
  108. package/skills/craft/become-an-ai-engineer-26/community/BUILDS.md +13 -13
  109. package/skills/craft/become-an-ai-engineer-26/community/DISCUSSIONS.md +8 -8
  110. package/skills/craft/become-an-ai-engineer-26/phases/phase-0-mental-models/README.md +14 -14
  111. package/skills/craft/become-an-ai-engineer-26/phases/phase-0-mental-models/project/TEMPLATE.md +33 -33
  112. package/skills/craft/become-an-ai-engineer-26/phases/phase-1-first-agent/README.md +25 -25
  113. package/skills/craft/become-an-ai-engineer-26/phases/phase-1-first-agent/code/raw_loop.py +126 -126
  114. package/skills/craft/become-an-ai-engineer-26/phases/phase-2-architecture/README.md +17 -17
  115. package/skills/craft/become-an-ai-engineer-26/phases/phase-3-harness/README.md +17 -17
  116. package/skills/craft/become-an-ai-engineer-26/phases/phase-4-evals/README.md +21 -21
  117. package/skills/craft/become-an-ai-engineer-26/phases/phase-4-evals/code/.github/workflows/eval.yml +40 -40
  118. package/skills/craft/become-an-ai-engineer-26/phases/phase-5-production/README.md +16 -16
  119. package/skills/craft/become-an-ai-engineer-26/projects/1-mobile-app-slm/README.md +11 -11
  120. package/skills/craft/become-an-ai-engineer-26/projects/2-self-improving-coder/README.md +11 -11
  121. package/skills/craft/become-an-ai-engineer-26/projects/3-video-editor-agent/README.md +11 -11
  122. package/skills/craft/become-an-ai-engineer-26/projects/4-personal-life-os/README.md +12 -12
  123. package/skills/craft/become-an-ai-engineer-26/projects/5-enterprise-workflow/README.md +12 -12
  124. package/skills/craft/become-an-ai-engineer-26/references/benchmark-numbers.md +41 -41
  125. package/skills/craft/become-an-ai-engineer-26/references/mhc-stable-training.md +73 -73
  126. package/skills/craft/become-an-ai-engineer-26/references/stack-decisions.md +37 -37
  127. package/skills/craft/become-an-ai-engineer-26/references/yarn-context-extension.md +123 -123
  128. package/skills/craft/codex-result-handling/LICENSE +21 -21
  129. package/skills/craft/codex-result-handling/SKILL.md +26 -26
  130. package/skills/craft/debug-and-build-methodology/LICENSE +21 -21
  131. package/skills/craft/debug-and-build-methodology/SKILL.md +432 -432
  132. package/skills/craft/design/LICENSE +21 -21
  133. package/skills/craft/design/SKILL.md +274 -274
  134. package/skills/craft/dev/LICENSE +21 -21
  135. package/skills/craft/dev/SKILL.md +12 -12
  136. package/skills/craft/dev/release.md +85 -85
  137. package/skills/craft/dev/roll.md +50 -50
  138. package/skills/craft/doc-coauthoring/LICENSE +21 -21
  139. package/skills/craft/doc-coauthoring/SKILL.md +397 -397
  140. package/skills/craft/focus/LICENSE +21 -21
  141. package/skills/craft/focus/SKILL.md +432 -432
  142. package/skills/craft/focus/UPSTREAM_README.md +233 -233
  143. package/skills/craft/gh/LICENSE +21 -21
  144. package/skills/craft/gh/SKILL.md +84 -84
  145. package/skills/craft/gh-skill/LICENSE +21 -21
  146. package/skills/craft/gh-skill/SKILL.md +121 -121
  147. package/skills/craft/godmode/LICENSE +21 -21
  148. package/skills/craft/godmode/SKILL.md +87 -87
  149. package/skills/craft/godmode/references/android-launch.md +680 -680
  150. package/skills/craft/godmode/references/data-gcp.md +1038 -1038
  151. package/skills/craft/godmode/references/expo-eas.md +816 -816
  152. package/skills/craft/godmode/references/ios-launch.md +734 -734
  153. package/skills/craft/google-ai-latest/LICENSE +21 -21
  154. package/skills/craft/google-ai-latest/SKILL.md +682 -682
  155. package/skills/craft/gpt-5-4-prompting/LICENSE +21 -21
  156. package/skills/craft/gpt-5-4-prompting/SKILL.md +63 -63
  157. package/skills/craft/gpt-5-4-prompting/references/codex-prompt-antipatterns.md +101 -101
  158. package/skills/craft/gpt-5-4-prompting/references/codex-prompt-recipes.md +150 -150
  159. package/skills/craft/gpt-5-4-prompting/references/prompt-blocks.md +172 -172
  160. package/skills/craft/grill-me/LICENSE +21 -21
  161. package/skills/craft/grill-me/SKILL.md +13 -13
  162. package/skills/craft/idea-to-deploy/LICENSE +21 -21
  163. package/skills/craft/idea-to-deploy/SKILL.md +292 -292
  164. package/skills/craft/idea-to-deploy/references/auth-playbook.md +195 -195
  165. package/skills/craft/idea-to-deploy/references/gcp-deployment.md +268 -268
  166. package/skills/craft/idea-to-deploy/references/stack-selection.md +117 -117
  167. package/skills/craft/image-generation-engineer/LICENSE +21 -21
  168. package/skills/craft/image-generation-engineer/SKILL.md +183 -183
  169. package/skills/craft/image-generation-engineer/references/architectures.md +260 -260
  170. package/skills/craft/image-generation-engineer/references/foundations.md +107 -107
  171. package/skills/craft/image-generation-engineer/references/inference-and-serving.md +253 -253
  172. package/skills/craft/image-generation-engineer/references/training.md +149 -149
  173. package/skills/craft/marketing/LICENSE +21 -21
  174. package/skills/craft/marketing/SKILL.md +1954 -1954
  175. package/skills/craft/master-architect/LICENSE +21 -21
  176. package/skills/craft/master-architect/SKILL.md +361 -361
  177. package/skills/craft/master-architect/references/ai-ml.md +317 -317
  178. package/skills/craft/master-architect/references/architecture.md +268 -268
  179. package/skills/craft/master-architect/references/auth-playbook.md +195 -195
  180. package/skills/craft/master-architect/references/cloud.md +323 -323
  181. package/skills/craft/master-architect/references/cyber.md +839 -839
  182. package/skills/craft/master-architect/references/data-eng.md +366 -366
  183. package/skills/craft/master-architect/references/devops.md +550 -550
  184. package/skills/craft/master-architect/references/gcp-deployment.md +268 -268
  185. package/skills/craft/master-architect/references/languages.md +748 -748
  186. package/skills/craft/master-architect/references/legacy.md +240 -240
  187. package/skills/craft/master-architect/references/mobile.md +447 -447
  188. package/skills/craft/master-architect/references/patterns.md +451 -451
  189. package/skills/craft/master-architect/references/saas-patterns.md +379 -379
  190. package/skills/craft/master-architect/references/sdlc.md +349 -349
  191. package/skills/craft/master-architect/references/stack-selection.md +117 -117
  192. package/skills/craft/oriro-ui-2026/LICENSE +21 -21
  193. package/skills/craft/oriro-ui-2026/SKILL.md +329 -329
  194. package/skills/craft/playwright-cli/LICENSE +21 -21
  195. package/skills/craft/playwright-cli/SKILL.md +393 -393
  196. package/skills/craft/playwright-cli/references/element-attributes.md +23 -23
  197. package/skills/craft/playwright-cli/references/playwright-tests.md +39 -39
  198. package/skills/craft/playwright-cli/references/request-mocking.md +87 -87
  199. package/skills/craft/playwright-cli/references/running-code.md +240 -240
  200. package/skills/craft/playwright-cli/references/session-management.md +226 -226
  201. package/skills/craft/playwright-cli/references/spec-driven-testing.md +312 -312
  202. package/skills/craft/playwright-cli/references/storage-state.md +275 -275
  203. package/skills/craft/playwright-cli/references/test-generation.md +134 -134
  204. package/skills/craft/playwright-cli/references/tracing.md +142 -142
  205. package/skills/craft/playwright-cli/references/video-recording.md +150 -150
  206. package/skills/craft/remotion-best-practices/LICENSE +21 -21
  207. package/skills/craft/remotion-best-practices/SKILL.md +345 -345
  208. package/skills/craft/remotion-best-practices/rules/3d.md +86 -86
  209. package/skills/craft/remotion-best-practices/rules/assets/charts-bar-chart.tsx +165 -165
  210. package/skills/craft/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +89 -89
  211. package/skills/craft/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +101 -101
  212. package/skills/craft/remotion-best-practices/rules/audio-visualization.md +195 -195
  213. package/skills/craft/remotion-best-practices/rules/audio.md +167 -167
  214. package/skills/craft/remotion-best-practices/rules/calculate-metadata.md +118 -118
  215. package/skills/craft/remotion-best-practices/rules/compositions.md +132 -132
  216. package/skills/craft/remotion-best-practices/rules/display-captions.md +176 -176
  217. package/skills/craft/remotion-best-practices/rules/ffmpeg.md +34 -34
  218. package/skills/craft/remotion-best-practices/rules/get-audio-duration.md +58 -58
  219. package/skills/craft/remotion-best-practices/rules/get-video-dimensions.md +68 -68
  220. package/skills/craft/remotion-best-practices/rules/get-video-duration.md +60 -60
  221. package/skills/craft/remotion-best-practices/rules/gifs.md +135 -135
  222. package/skills/craft/remotion-best-practices/rules/google-fonts.md +72 -72
  223. package/skills/craft/remotion-best-practices/rules/html-in-canvas.md +122 -122
  224. package/skills/craft/remotion-best-practices/rules/images.md +67 -67
  225. package/skills/craft/remotion-best-practices/rules/import-srt-captions.md +69 -69
  226. package/skills/craft/remotion-best-practices/rules/light-leaks.md +73 -73
  227. package/skills/craft/remotion-best-practices/rules/local-fonts.md +65 -65
  228. package/skills/craft/remotion-best-practices/rules/lottie.md +67 -67
  229. package/skills/craft/remotion-best-practices/rules/maplibre.md +441 -441
  230. package/skills/craft/remotion-best-practices/rules/measuring-dom-nodes.md +34 -34
  231. package/skills/craft/remotion-best-practices/rules/measuring-text.md +140 -140
  232. package/skills/craft/remotion-best-practices/rules/parameters.md +109 -109
  233. package/skills/craft/remotion-best-practices/rules/sequencing.md +144 -144
  234. package/skills/craft/remotion-best-practices/rules/sfx.md +30 -30
  235. package/skills/craft/remotion-best-practices/rules/silence-detection.md +73 -73
  236. package/skills/craft/remotion-best-practices/rules/subtitles.md +36 -36
  237. package/skills/craft/remotion-best-practices/rules/tailwind.md +11 -11
  238. package/skills/craft/remotion-best-practices/rules/text-animations.md +20 -20
  239. package/skills/craft/remotion-best-practices/rules/timing.md +130 -130
  240. package/skills/craft/remotion-best-practices/rules/transcribe-captions.md +70 -70
  241. package/skills/craft/remotion-best-practices/rules/transitions.md +193 -193
  242. package/skills/craft/remotion-best-practices/rules/transparent-videos.md +102 -102
  243. package/skills/craft/remotion-best-practices/rules/trimming.md +51 -51
  244. package/skills/craft/remotion-best-practices/rules/videos.md +169 -169
  245. package/skills/craft/remotion-best-practices/rules/voiceover.md +94 -94
  246. package/skills/craft/supabase-postgres-best-practices/CHANGELOG.md +25 -25
  247. package/skills/craft/supabase-postgres-best-practices/LICENSE +21 -21
  248. package/skills/craft/supabase-postgres-best-practices/SKILL.md +69 -69
  249. package/skills/craft/supabase-postgres-best-practices/references/_contributing.md +166 -166
  250. package/skills/craft/supabase-postgres-best-practices/references/_sections.md +47 -47
  251. package/skills/craft/supabase-postgres-best-practices/references/_template.md +34 -34
  252. package/skills/craft/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -55
  253. package/skills/craft/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -49
  254. package/skills/craft/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -46
  255. package/skills/craft/supabase-postgres-best-practices/references/conn-limits.md +44 -44
  256. package/skills/craft/supabase-postgres-best-practices/references/conn-pooling.md +41 -41
  257. package/skills/craft/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -46
  258. package/skills/craft/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -54
  259. package/skills/craft/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -53
  260. package/skills/craft/supabase-postgres-best-practices/references/data-pagination.md +50 -50
  261. package/skills/craft/supabase-postgres-best-practices/references/data-upsert.md +50 -50
  262. package/skills/craft/supabase-postgres-best-practices/references/lock-advisory.md +56 -56
  263. package/skills/craft/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -68
  264. package/skills/craft/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -50
  265. package/skills/craft/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -54
  266. package/skills/craft/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -45
  267. package/skills/craft/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -55
  268. package/skills/craft/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -55
  269. package/skills/craft/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -44
  270. package/skills/craft/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -40
  271. package/skills/craft/supabase-postgres-best-practices/references/query-index-types.md +48 -48
  272. package/skills/craft/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -43
  273. package/skills/craft/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -45
  274. package/skills/craft/supabase-postgres-best-practices/references/schema-constraints.md +80 -80
  275. package/skills/craft/supabase-postgres-best-practices/references/schema-data-types.md +46 -46
  276. package/skills/craft/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -59
  277. package/skills/craft/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -55
  278. package/skills/craft/supabase-postgres-best-practices/references/schema-partitioning.md +55 -55
  279. package/skills/craft/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -61
  280. package/skills/craft/supabase-postgres-best-practices/references/security-privileges.md +54 -54
  281. package/skills/craft/supabase-postgres-best-practices/references/security-rls-basics.md +50 -50
  282. package/skills/craft/supabase-postgres-best-practices/references/security-rls-performance.md +63 -63
  283. package/skills/craft/uipm-banner-design/LICENSE +21 -21
  284. package/skills/craft/uipm-banner-design/SKILL.md +201 -201
  285. package/skills/craft/uipm-banner-design/references/banner-sizes-and-styles.md +129 -129
  286. package/skills/craft/uipm-brand/LICENSE +21 -21
  287. package/skills/craft/uipm-brand/SKILL.md +104 -104
  288. package/skills/craft/uipm-brand/references/approval-checklist.md +184 -184
  289. package/skills/craft/uipm-brand/references/asset-organization.md +167 -167
  290. package/skills/craft/uipm-brand/references/brand-guideline-template.md +161 -161
  291. package/skills/craft/uipm-brand/references/color-palette-management.md +203 -203
  292. package/skills/craft/uipm-brand/references/consistency-checklist.md +105 -105
  293. package/skills/craft/uipm-brand/references/logo-usage-rules.md +204 -204
  294. package/skills/craft/uipm-brand/references/messaging-framework.md +91 -91
  295. package/skills/craft/uipm-brand/references/typography-specifications.md +265 -265
  296. package/skills/craft/uipm-brand/references/update.md +128 -128
  297. package/skills/craft/uipm-brand/references/visual-identity.md +109 -109
  298. package/skills/craft/uipm-brand/references/voice-framework.md +99 -99
  299. package/skills/craft/uipm-brand/scripts/extract-colors.cjs +333 -333
  300. package/skills/craft/uipm-brand/scripts/inject-brand-context.cjs +324 -324
  301. package/skills/craft/uipm-brand/scripts/sync-brand-to-tokens.cjs +269 -269
  302. package/skills/craft/uipm-brand/scripts/validate-asset.cjs +361 -361
  303. package/skills/craft/uipm-brand/templates/brand-guidelines-starter.md +280 -280
  304. package/skills/craft/uipm-design/LICENSE +21 -21
  305. package/skills/craft/uipm-design/SKILL.md +305 -305
  306. package/skills/craft/uipm-design/data/cip/deliverables.csv +50 -50
  307. package/skills/craft/uipm-design/data/cip/industries.csv +20 -20
  308. package/skills/craft/uipm-design/data/cip/mockup-contexts.csv +20 -20
  309. package/skills/craft/uipm-design/data/cip/styles.csv +20 -20
  310. package/skills/craft/uipm-design/data/icon/styles.csv +16 -16
  311. package/skills/craft/uipm-design/data/logo/colors.csv +56 -56
  312. package/skills/craft/uipm-design/data/logo/industries.csv +56 -56
  313. package/skills/craft/uipm-design/data/logo/styles.csv +56 -56
  314. package/skills/craft/uipm-design/references/banner-sizes-and-styles.md +129 -129
  315. package/skills/craft/uipm-design/references/cip-deliverable-guide.md +111 -111
  316. package/skills/craft/uipm-design/references/cip-design.md +121 -121
  317. package/skills/craft/uipm-design/references/cip-prompt-engineering.md +94 -94
  318. package/skills/craft/uipm-design/references/cip-style-guide.md +76 -76
  319. package/skills/craft/uipm-design/references/design-routing.md +226 -226
  320. package/skills/craft/uipm-design/references/icon-design.md +122 -122
  321. package/skills/craft/uipm-design/references/logo-color-psychology.md +113 -113
  322. package/skills/craft/uipm-design/references/logo-design.md +92 -92
  323. package/skills/craft/uipm-design/references/logo-prompt-engineering.md +176 -176
  324. package/skills/craft/uipm-design/references/logo-style-guide.md +129 -129
  325. package/skills/craft/uipm-design/references/slides-copywriting-formulas.md +92 -92
  326. package/skills/craft/uipm-design/references/slides-create.md +5 -5
  327. package/skills/craft/uipm-design/references/slides-html-template.md +374 -374
  328. package/skills/craft/uipm-design/references/slides-layout-patterns.md +155 -155
  329. package/skills/craft/uipm-design/references/slides-strategies.md +97 -97
  330. package/skills/craft/uipm-design/references/slides.md +42 -42
  331. package/skills/craft/uipm-design/references/social-photos-design.md +353 -353
  332. package/skills/craft/uipm-design/scripts/cip/core.py +215 -215
  333. package/skills/craft/uipm-design/scripts/cip/generate.py +484 -484
  334. package/skills/craft/uipm-design/scripts/cip/render-html.py +424 -424
  335. package/skills/craft/uipm-design/scripts/cip/search.py +127 -127
  336. package/skills/craft/uipm-design/scripts/icon/generate.py +487 -487
  337. package/skills/craft/uipm-design/scripts/logo/core.py +175 -175
  338. package/skills/craft/uipm-design/scripts/logo/generate.py +362 -362
  339. package/skills/craft/uipm-design/scripts/logo/search.py +114 -114
  340. package/skills/craft/uipm-design-system/LICENSE +21 -21
  341. package/skills/craft/uipm-design-system/SKILL.md +255 -255
  342. package/skills/craft/uipm-design-system/data/slide-backgrounds.csv +11 -11
  343. package/skills/craft/uipm-design-system/data/slide-charts.csv +26 -26
  344. package/skills/craft/uipm-design-system/data/slide-color-logic.csv +14 -14
  345. package/skills/craft/uipm-design-system/data/slide-copy.csv +26 -26
  346. package/skills/craft/uipm-design-system/data/slide-layout-logic.csv +16 -16
  347. package/skills/craft/uipm-design-system/data/slide-layouts.csv +26 -26
  348. package/skills/craft/uipm-design-system/data/slide-strategies.csv +16 -16
  349. package/skills/craft/uipm-design-system/data/slide-typography.csv +15 -15
  350. package/skills/craft/uipm-design-system/references/component-specs.md +236 -236
  351. package/skills/craft/uipm-design-system/references/component-tokens.md +214 -214
  352. package/skills/craft/uipm-design-system/references/primitive-tokens.md +199 -199
  353. package/skills/craft/uipm-design-system/references/semantic-tokens.md +215 -215
  354. package/skills/craft/uipm-design-system/references/states-and-variants.md +243 -243
  355. package/skills/craft/uipm-design-system/references/tailwind-integration.md +257 -257
  356. package/skills/craft/uipm-design-system/references/token-architecture.md +226 -226
  357. package/skills/craft/uipm-design-system/scripts/embed-tokens.cjs +97 -97
  358. package/skills/craft/uipm-design-system/scripts/fetch-background.py +317 -317
  359. package/skills/craft/uipm-design-system/scripts/generate-slide.py +753 -753
  360. package/skills/craft/uipm-design-system/scripts/generate-tokens.cjs +213 -213
  361. package/skills/craft/uipm-design-system/scripts/html-token-validator.py +327 -327
  362. package/skills/craft/uipm-design-system/scripts/search-slides.py +218 -218
  363. package/skills/craft/uipm-design-system/scripts/slide-token-validator.py +35 -35
  364. package/skills/craft/uipm-design-system/scripts/slide_search_core.py +453 -453
  365. package/skills/craft/uipm-design-system/scripts/validate-tokens.cjs +254 -254
  366. package/skills/craft/uipm-design-system/templates/design-tokens-starter.json +143 -143
  367. package/skills/craft/uipm-slides/LICENSE +21 -21
  368. package/skills/craft/uipm-slides/SKILL.md +45 -45
  369. package/skills/craft/uipm-slides/references/copywriting-formulas.md +92 -92
  370. package/skills/craft/uipm-slides/references/create.md +5 -5
  371. package/skills/craft/uipm-slides/references/html-template.md +374 -374
  372. package/skills/craft/uipm-slides/references/layout-patterns.md +155 -155
  373. package/skills/craft/uipm-slides/references/slide-strategies.md +97 -97
  374. package/skills/craft/uipm-ui-ux-pro-max/LICENSE +21 -21
  375. package/skills/craft/uipm-ui-ux-pro-max/SKILL.md +678 -678
  376. package/skills/craft/uipm-ui-ux-pro-max/data/_sync_all.py +414 -414
  377. package/skills/craft/uipm-ui-ux-pro-max/data/app-interface.csv +30 -30
  378. package/skills/craft/uipm-ui-ux-pro-max/data/charts.csv +26 -26
  379. package/skills/craft/uipm-ui-ux-pro-max/data/colors.csv +161 -161
  380. package/skills/craft/uipm-ui-ux-pro-max/data/design.csv +1775 -1775
  381. package/skills/craft/uipm-ui-ux-pro-max/data/draft.csv +1778 -1778
  382. package/skills/craft/uipm-ui-ux-pro-max/data/google-fonts.csv +1924 -1924
  383. package/skills/craft/uipm-ui-ux-pro-max/data/icons.csv +105 -105
  384. package/skills/craft/uipm-ui-ux-pro-max/data/landing.csv +35 -35
  385. package/skills/craft/uipm-ui-ux-pro-max/data/products.csv +162 -162
  386. package/skills/craft/uipm-ui-ux-pro-max/data/react-performance.csv +45 -45
  387. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/angular.csv +51 -51
  388. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/astro.csv +54 -54
  389. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/flutter.csv +53 -53
  390. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
  391. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
  392. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/laravel.csv +51 -51
  393. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
  394. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
  395. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
  396. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/react-native.csv +52 -52
  397. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/react.csv +54 -54
  398. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
  399. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/svelte.csv +54 -54
  400. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
  401. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/threejs.csv +54 -54
  402. package/skills/craft/uipm-ui-ux-pro-max/data/stacks/vue.csv +50 -50
  403. package/skills/craft/uipm-ui-ux-pro-max/data/styles.csv +85 -85
  404. package/skills/craft/uipm-ui-ux-pro-max/data/typography.csv +74 -74
  405. package/skills/craft/uipm-ui-ux-pro-max/data/ui-reasoning.csv +162 -162
  406. package/skills/craft/uipm-ui-ux-pro-max/data/ux-guidelines.csv +99 -99
  407. package/skills/craft/uipm-ui-ux-pro-max/scripts/core.py +262 -262
  408. package/skills/craft/uipm-ui-ux-pro-max/scripts/design_system.py +1148 -1148
  409. package/skills/craft/uipm-ui-ux-pro-max/scripts/search.py +114 -114
  410. package/skills/craft/uipm-ui-ux-pro-max/templates/base/quick-reference.md +297 -297
  411. package/skills/craft/uipm-ui-ux-pro-max/templates/base/skill-content.md +375 -375
  412. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/agent.json +21 -21
  413. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/augment.json +18 -18
  414. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/claude.json +21 -21
  415. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/codebuddy.json +21 -21
  416. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/codex.json +21 -21
  417. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/continue.json +21 -21
  418. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/copilot.json +21 -21
  419. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/cursor.json +21 -21
  420. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/droid.json +21 -21
  421. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/gemini.json +21 -21
  422. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/kilocode.json +21 -21
  423. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/kiro.json +21 -21
  424. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/opencode.json +21 -21
  425. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/qoder.json +21 -21
  426. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/roocode.json +21 -21
  427. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/trae.json +21 -21
  428. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/warp.json +18 -18
  429. package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/windsurf.json +21 -21
  430. package/skills/craft/vercel-optimize/AGENTS.md +48 -48
  431. package/skills/craft/vercel-optimize/CONTRIBUTING.md +41 -41
  432. package/skills/craft/vercel-optimize/LICENSE +21 -21
  433. package/skills/craft/vercel-optimize/README.md +91 -91
  434. package/skills/craft/vercel-optimize/SKILL.md +325 -325
  435. package/skills/craft/vercel-optimize/lib/auth-route.mjs +23 -23
  436. package/skills/craft/vercel-optimize/lib/budget-summary.mjs +208 -208
  437. package/skills/craft/vercel-optimize/lib/citations.mjs +147 -147
  438. package/skills/craft/vercel-optimize/lib/cost-coverage.mjs +162 -162
  439. package/skills/craft/vercel-optimize/lib/dedup-recs.mjs +340 -340
  440. package/skills/craft/vercel-optimize/lib/deep-dive.mjs +371 -371
  441. package/skills/craft/vercel-optimize/lib/display-labels.mjs +219 -219
  442. package/skills/craft/vercel-optimize/lib/extract-claims.mjs +640 -640
  443. package/skills/craft/vercel-optimize/lib/framework-support.mjs +69 -69
  444. package/skills/craft/vercel-optimize/lib/gates/build-minutes-fanout.mjs +73 -73
  445. package/skills/craft/vercel-optimize/lib/gates/cold-start.mjs +72 -72
  446. package/skills/craft/vercel-optimize/lib/gates/contract.mjs +82 -82
  447. package/skills/craft/vercel-optimize/lib/gates/cwv-poor.mjs +95 -95
  448. package/skills/craft/vercel-optimize/lib/gates/external-api-slow.mjs +60 -60
  449. package/skills/craft/vercel-optimize/lib/gates/hard-gates.mjs +70 -70
  450. package/skills/craft/vercel-optimize/lib/gates/index.mjs +45 -45
  451. package/skills/craft/vercel-optimize/lib/gates/isr-overrevalidation.mjs +62 -62
  452. package/skills/craft/vercel-optimize/lib/gates/middleware-heavy.mjs +53 -53
  453. package/skills/craft/vercel-optimize/lib/gates/observability-events-attribution.mjs +58 -58
  454. package/skills/craft/vercel-optimize/lib/gates/platform-bot-protection.mjs +123 -123
  455. package/skills/craft/vercel-optimize/lib/gates/platform-fluid-compute.mjs +94 -94
  456. package/skills/craft/vercel-optimize/lib/gates/region-misconfig.mjs +71 -71
  457. package/skills/craft/vercel-optimize/lib/gates/route-errors.mjs +95 -95
  458. package/skills/craft/vercel-optimize/lib/gates/scanner-driven.mjs +150 -150
  459. package/skills/craft/vercel-optimize/lib/gates/select-candidates.mjs +137 -137
  460. package/skills/craft/vercel-optimize/lib/gates/slow-route.mjs +97 -97
  461. package/skills/craft/vercel-optimize/lib/gates/types.d.ts +38 -38
  462. package/skills/craft/vercel-optimize/lib/gates/uncached-route.mjs +103 -103
  463. package/skills/craft/vercel-optimize/lib/gates/usage-spike-triage.mjs +122 -122
  464. package/skills/craft/vercel-optimize/lib/grade-recommendation.mjs +170 -170
  465. package/skills/craft/vercel-optimize/lib/impact-label.mjs +128 -128
  466. package/skills/craft/vercel-optimize/lib/impact-magnitude.mjs +66 -66
  467. package/skills/craft/vercel-optimize/lib/investigation-brief.mjs +751 -751
  468. package/skills/craft/vercel-optimize/lib/observation-safety.mjs +217 -217
  469. package/skills/craft/vercel-optimize/lib/project-facts.mjs +101 -101
  470. package/skills/craft/vercel-optimize/lib/queries.mjs +333 -333
  471. package/skills/craft/vercel-optimize/lib/reconcile-candidates.mjs +388 -388
  472. package/skills/craft/vercel-optimize/lib/render-report.mjs +1065 -1065
  473. package/skills/craft/vercel-optimize/lib/repo-root.mjs +97 -97
  474. package/skills/craft/vercel-optimize/lib/route-normalize.mjs +224 -224
  475. package/skills/craft/vercel-optimize/lib/sanitizers/bot-protection-certainty.mjs +56 -56
  476. package/skills/craft/vercel-optimize/lib/sanitizers/cache-tag-invalidation-certainty.mjs +33 -33
  477. package/skills/craft/vercel-optimize/lib/sanitizers/count-correct.mjs +53 -53
  478. package/skills/craft/vercel-optimize/lib/sanitizers/function-duration-invocations.mjs +32 -32
  479. package/skills/craft/vercel-optimize/lib/sanitizers/index.mjs +87 -87
  480. package/skills/craft/vercel-optimize/lib/sanitizers/middleware-conflict.mjs +37 -37
  481. package/skills/craft/vercel-optimize/lib/sanitizers/missing-citation.mjs +16 -16
  482. package/skills/craft/vercel-optimize/lib/sanitizers/pre-release.mjs +75 -75
  483. package/skills/craft/vercel-optimize/lib/sanitizers/rate-limit.mjs +73 -73
  484. package/skills/craft/vercel-optimize/lib/sanitizers/rendering-mode-mislabel.mjs +42 -42
  485. package/skills/craft/vercel-optimize/lib/sanitizers/undeclared-dep.mjs +110 -110
  486. package/skills/craft/vercel-optimize/lib/sanitizers/vercel-directive-strip.mjs +37 -37
  487. package/skills/craft/vercel-optimize/lib/sanitizers/window-units.mjs +26 -26
  488. package/skills/craft/vercel-optimize/lib/scanners/cache-components-suspense-dedupe.mjs +114 -114
  489. package/skills/craft/vercel-optimize/lib/scanners/edge-heavy-import.mjs +102 -102
  490. package/skills/craft/vercel-optimize/lib/scanners/force-dynamic.mjs +39 -39
  491. package/skills/craft/vercel-optimize/lib/scanners/headers-in-page.mjs +43 -43
  492. package/skills/craft/vercel-optimize/lib/scanners/index.mjs +35 -35
  493. package/skills/craft/vercel-optimize/lib/scanners/large-static-asset.mjs +93 -93
  494. package/skills/craft/vercel-optimize/lib/scanners/max-age-without-s-maxage.mjs +47 -47
  495. package/skills/craft/vercel-optimize/lib/scanners/middleware-broad-matcher.mjs +53 -53
  496. package/skills/craft/vercel-optimize/lib/scanners/missing-cache-headers.mjs +97 -97
  497. package/skills/craft/vercel-optimize/lib/scanners/prisma-include-tree.mjs +39 -39
  498. package/skills/craft/vercel-optimize/lib/scanners/region-pin-in-config.mjs +89 -89
  499. package/skills/craft/vercel-optimize/lib/scanners/source-maps-production.mjs +33 -33
  500. package/skills/craft/vercel-optimize/lib/scanners/sveltekit-prerender-missing.mjs +47 -47
  501. package/skills/craft/vercel-optimize/lib/scanners/turbo-force-bypass.mjs +136 -136
  502. package/skills/craft/vercel-optimize/lib/scanners/unoptimized-image.mjs +127 -127
  503. package/skills/craft/vercel-optimize/lib/scanners/use-cache-date-stamp.mjs +112 -112
  504. package/skills/craft/vercel-optimize/lib/support-topics.mjs +365 -365
  505. package/skills/craft/vercel-optimize/lib/throttle.mjs +280 -280
  506. package/skills/craft/vercel-optimize/lib/util.mjs +17 -17
  507. package/skills/craft/vercel-optimize/lib/vercel.mjs +855 -855
  508. package/skills/craft/vercel-optimize/lib/verify-claim.mjs +1843 -1843
  509. package/skills/craft/vercel-optimize/lib/workspace-resolver.mjs +552 -552
  510. package/skills/craft/vercel-optimize/metadata.json +14 -14
  511. package/skills/craft/vercel-optimize/references/candidates.md +176 -176
  512. package/skills/craft/vercel-optimize/references/data-collection.md +224 -224
  513. package/skills/craft/vercel-optimize/references/docs-library.json +683 -683
  514. package/skills/craft/vercel-optimize/references/doctrine.md +108 -108
  515. package/skills/craft/vercel-optimize/references/observability-plus.md +109 -109
  516. package/skills/craft/vercel-optimize/references/playbooks/README.md +57 -57
  517. package/skills/craft/vercel-optimize/references/playbooks/ai-application.md +32 -32
  518. package/skills/craft/vercel-optimize/references/playbooks/api-service.md +30 -30
  519. package/skills/craft/vercel-optimize/references/playbooks/content-site.md +30 -30
  520. package/skills/craft/vercel-optimize/references/playbooks/ecommerce.md +30 -30
  521. package/skills/craft/vercel-optimize/references/playbooks/marketing.md +30 -30
  522. package/skills/craft/vercel-optimize/references/playbooks/saas.md +31 -31
  523. package/skills/craft/vercel-optimize/references/playbooks/sveltekit.md +75 -75
  524. package/skills/craft/vercel-optimize/references/recommendations.md +214 -214
  525. package/skills/craft/vercel-optimize/references/scanner-patterns.md +266 -266
  526. package/skills/craft/vercel-optimize/references/scoring.md +208 -208
  527. package/skills/craft/vercel-optimize/references/support-topics/README.md +50 -50
  528. package/skills/craft/vercel-optimize/references/support-topics/astro-edge-middleware-scope.md +30 -30
  529. package/skills/craft/vercel-optimize/references/support-topics/astro-output-mode-and-isr.md +31 -31
  530. package/skills/craft/vercel-optimize/references/support-topics/auth-preserving-parallelization.md +30 -30
  531. package/skills/craft/vercel-optimize/references/support-topics/bot-protection-product-guardrails.md +32 -32
  532. package/skills/craft/vercel-optimize/references/support-topics/build-minutes-monorepo-fanout.md +32 -32
  533. package/skills/craft/vercel-optimize/references/support-topics/cache-components-static-shell-boundaries.md +31 -31
  534. package/skills/craft/vercel-optimize/references/support-topics/cache-components-suspense-dedupe-pitfall.md +32 -32
  535. package/skills/craft/vercel-optimize/references/support-topics/cdn-cache-auth-safety.md +31 -31
  536. package/skills/craft/vercel-optimize/references/support-topics/cold-start-initialization-bundle.md +31 -31
  537. package/skills/craft/vercel-optimize/references/support-topics/core-web-vitals-client-bottlenecks.md +33 -33
  538. package/skills/craft/vercel-optimize/references/support-topics/database-egress-pooling-region.md +32 -32
  539. package/skills/craft/vercel-optimize/references/support-topics/dynamic-rendering-traps.md +31 -31
  540. package/skills/craft/vercel-optimize/references/support-topics/external-api-critical-path-platform.md +31 -31
  541. package/skills/craft/vercel-optimize/references/support-topics/external-api-critical-path.md +31 -31
  542. package/skills/craft/vercel-optimize/references/support-topics/fast-data-transfer-payloads.md +26 -26
  543. package/skills/craft/vercel-optimize/references/support-topics/fluid-compute-caveats.md +26 -26
  544. package/skills/craft/vercel-optimize/references/support-topics/function-duration-io-and-after.md +31 -31
  545. package/skills/craft/vercel-optimize/references/support-topics/function-invocation-reduction.md +31 -31
  546. package/skills/craft/vercel-optimize/references/support-topics/function-region-misconfiguration-ttfb.md +31 -31
  547. package/skills/craft/vercel-optimize/references/support-topics/image-optimization-cost-control.md +31 -31
  548. package/skills/craft/vercel-optimize/references/support-topics/isr-revalidation-static-generation.md +31 -31
  549. package/skills/craft/vercel-optimize/references/support-topics/middleware-proxy-edge-cost.md +30 -30
  550. package/skills/craft/vercel-optimize/references/support-topics/next-fetch-revalidate-floor.md +30 -30
  551. package/skills/craft/vercel-optimize/references/support-topics/next-font-cls-self-hosting.md +31 -31
  552. package/skills/craft/vercel-optimize/references/support-topics/next-heavy-ui-lazy-load-boundaries.md +28 -28
  553. package/skills/craft/vercel-optimize/references/support-topics/next-image-lcp-preload-sizes.md +31 -31
  554. package/skills/craft/vercel-optimize/references/support-topics/next-route-handler-get-cache-defaults.md +30 -30
  555. package/skills/craft/vercel-optimize/references/support-topics/next-script-third-party-strategy.md +31 -31
  556. package/skills/craft/vercel-optimize/references/support-topics/nextjs-version-cache-semantics.md +31 -31
  557. package/skills/craft/vercel-optimize/references/support-topics/not-found-catchall-request-waste.md +33 -33
  558. package/skills/craft/vercel-optimize/references/support-topics/nuxt-route-rules-cache-isr.md +31 -31
  559. package/skills/craft/vercel-optimize/references/support-topics/observability-events-cost-attribution.md +27 -27
  560. package/skills/craft/vercel-optimize/references/support-topics/post-response-work-waituntil.md +26 -26
  561. package/skills/craft/vercel-optimize/references/support-topics/route-error-durable-offload.md +33 -33
  562. package/skills/craft/vercel-optimize/references/support-topics/route-error-runtime-limits.md +31 -31
  563. package/skills/craft/vercel-optimize/references/support-topics/runtime-cache-reusable-data.md +30 -30
  564. package/skills/craft/vercel-optimize/references/support-topics/sveltekit-isr-prerender-safety.md +31 -31
  565. package/skills/craft/vercel-optimize/references/support-topics/sveltekit-split-cold-start-tradeoff.md +30 -30
  566. package/skills/craft/vercel-optimize/references/support-topics/usage-spike-triage.md +31 -31
  567. package/skills/craft/vercel-optimize/references/support-topics/use-cache-date-stamp-isr-write-amplifier.md +31 -31
  568. package/skills/craft/vercel-optimize/references/support-topics/use-cache-remote-shared-origin-data.md +30 -30
  569. package/skills/craft/vercel-optimize/references/support-topics/workflow-resumable-stream-routes.md +32 -32
  570. package/skills/craft/vercel-optimize/references/verification.md +102 -102
  571. package/skills/craft/vercel-optimize/references/voice.md +76 -76
  572. package/skills/craft/vercel-optimize/scripts/budget-summary.mjs +58 -58
  573. package/skills/craft/vercel-optimize/scripts/build-docs.mjs +76 -76
  574. package/skills/craft/vercel-optimize/scripts/check-citations.mjs +91 -91
  575. package/skills/craft/vercel-optimize/scripts/check-docs-fresh.mjs +100 -100
  576. package/skills/craft/vercel-optimize/scripts/collect-signals.mjs +638 -638
  577. package/skills/craft/vercel-optimize/scripts/collect-sub-agent-outputs.mjs +306 -306
  578. package/skills/craft/vercel-optimize/scripts/deep-dive.mjs +358 -358
  579. package/skills/craft/vercel-optimize/scripts/gate-investigations.mjs +178 -178
  580. package/skills/craft/vercel-optimize/scripts/merge-signals.mjs +203 -203
  581. package/skills/craft/vercel-optimize/scripts/prepare-investigation-brief.mjs +249 -249
  582. package/skills/craft/vercel-optimize/scripts/reconcile-candidates.mjs +69 -69
  583. package/skills/craft/vercel-optimize/scripts/render-report.mjs +462 -462
  584. package/skills/craft/vercel-optimize/scripts/scan-codebase.mjs +361 -361
  585. package/skills/craft/vercel-optimize/scripts/verify-and-regen.mjs +379 -379
  586. package/skills/craft/vercel-optimize/scripts/verify-finding.mjs +21 -21
  587. package/skills/craft/web-design-guidelines/LICENSE +21 -21
  588. package/skills/craft/web-design-guidelines/SKILL.md +43 -43
  589. package/skills/craft/zero-to-live/LICENSE +21 -21
  590. package/skills/craft/zero-to-live/SKILL.md +422 -422
  591. package/skills/creative/creative-3d-modeling/LICENSE +21 -21
  592. package/skills/creative/creative-3d-modeling/SKILL.md +70 -70
  593. package/skills/creative/creative-architecture/LICENSE +21 -21
  594. package/skills/creative/creative-architecture/SKILL.md +94 -94
  595. package/skills/creative/creative-design-principles/LICENSE +21 -21
  596. package/skills/creative/creative-design-principles/SKILL.md +95 -95
  597. package/skills/creative/creative-fashion-advanced/LICENSE +21 -21
  598. package/skills/creative/creative-fashion-advanced/SKILL.md +68 -68
  599. package/skills/creative/creative-fashion-design/LICENSE +21 -21
  600. package/skills/creative/creative-fashion-design/SKILL.md +66 -66
  601. package/skills/creative/creative-game-design/LICENSE +21 -21
  602. package/skills/creative/creative-game-design/SKILL.md +77 -77
  603. package/skills/creative/creative-industrial-design/LICENSE +21 -21
  604. package/skills/creative/creative-industrial-design/SKILL.md +57 -57
  605. package/skills/creative/creative-interior-design/LICENSE +21 -21
  606. package/skills/creative/creative-interior-design/SKILL.md +59 -59
  607. package/skills/creative/creative-music-theory/LICENSE +21 -21
  608. package/skills/creative/creative-music-theory/SKILL.md +98 -98
  609. package/skills/creative/creative-photography/LICENSE +21 -21
  610. package/skills/creative/creative-photography/SKILL.md +87 -87
  611. package/skills/creative/creative-textile-science/LICENSE +21 -21
  612. package/skills/creative/creative-textile-science/SKILL.md +67 -67
  613. package/skills/creative/creative-ux/LICENSE +21 -21
  614. package/skills/creative/creative-ux/SKILL.md +81 -81
  615. package/skills/creative/creative-video/LICENSE +21 -21
  616. package/skills/creative/creative-video/SKILL.md +84 -84
  617. package/skills/creative/creative-writing-craft/LICENSE +21 -21
  618. package/skills/creative/creative-writing-craft/SKILL.md +91 -91
  619. package/skills/diagram-maker/SKILL.md +56 -56
  620. package/skills/diagram-maker/references/excalidraw-patterns.md +85 -85
  621. package/skills/diagram-maker/references/svg-template.md +112 -112
  622. package/skills/discord/SKILL.md +140 -140
  623. package/skills/education/edu-adult-learning/LICENSE +21 -21
  624. package/skills/education/edu-adult-learning/SKILL.md +81 -81
  625. package/skills/education/edu-africa-multilingual/LICENSE +21 -21
  626. package/skills/education/edu-africa-multilingual/SKILL.md +55 -55
  627. package/skills/education/edu-arabic/LICENSE +21 -21
  628. package/skills/education/edu-arabic/SKILL.md +60 -60
  629. package/skills/education/edu-australia-nz/LICENSE +21 -21
  630. package/skills/education/edu-australia-nz/SKILL.md +48 -48
  631. package/skills/education/edu-china-mandarin/LICENSE +21 -21
  632. package/skills/education/edu-china-mandarin/SKILL.md +58 -58
  633. package/skills/education/edu-critical-thinking/LICENSE +21 -21
  634. package/skills/education/edu-critical-thinking/SKILL.md +86 -86
  635. package/skills/education/edu-curriculum/LICENSE +21 -21
  636. package/skills/education/edu-curriculum/SKILL.md +87 -87
  637. package/skills/education/edu-ed-tech/LICENSE +21 -21
  638. package/skills/education/edu-ed-tech/SKILL.md +73 -73
  639. package/skills/education/edu-france/LICENSE +21 -21
  640. package/skills/education/edu-france/SKILL.md +42 -42
  641. package/skills/education/edu-germany/LICENSE +21 -21
  642. package/skills/education/edu-germany/SKILL.md +46 -46
  643. package/skills/education/edu-india-competitive/LICENSE +21 -21
  644. package/skills/education/edu-india-competitive/SKILL.md +159 -159
  645. package/skills/education/edu-india-east/LICENSE +21 -21
  646. package/skills/education/edu-india-east/SKILL.md +60 -60
  647. package/skills/education/edu-india-hindi/LICENSE +21 -21
  648. package/skills/education/edu-india-hindi/SKILL.md +107 -107
  649. package/skills/education/edu-india-south/LICENSE +21 -21
  650. package/skills/education/edu-india-south/SKILL.md +64 -64
  651. package/skills/education/edu-india-west/LICENSE +21 -21
  652. package/skills/education/edu-india-west/SKILL.md +68 -68
  653. package/skills/education/edu-indonesia-malay/LICENSE +21 -21
  654. package/skills/education/edu-indonesia-malay/SKILL.md +57 -57
  655. package/skills/education/edu-international-ib/LICENSE +21 -21
  656. package/skills/education/edu-international-ib/SKILL.md +61 -61
  657. package/skills/education/edu-japan/LICENSE +21 -21
  658. package/skills/education/edu-japan/SKILL.md +48 -48
  659. package/skills/education/edu-korea/LICENSE +21 -21
  660. package/skills/education/edu-korea/SKILL.md +48 -48
  661. package/skills/education/edu-learning-science/LICENSE +21 -21
  662. package/skills/education/edu-learning-science/SKILL.md +76 -76
  663. package/skills/education/edu-portuguese-brazil/LICENSE +21 -21
  664. package/skills/education/edu-portuguese-brazil/SKILL.md +51 -51
  665. package/skills/education/edu-russia/LICENSE +21 -21
  666. package/skills/education/edu-russia/SKILL.md +50 -50
  667. package/skills/education/edu-spain-latam/LICENSE +21 -21
  668. package/skills/education/edu-spain-latam/SKILL.md +55 -55
  669. package/skills/education/edu-special/LICENSE +21 -21
  670. package/skills/education/edu-special/SKILL.md +76 -76
  671. package/skills/education/edu-thailand/LICENSE +21 -21
  672. package/skills/education/edu-thailand/SKILL.md +55 -55
  673. package/skills/education/edu-turkey/LICENSE +21 -21
  674. package/skills/education/edu-turkey/SKILL.md +58 -58
  675. package/skills/education/edu-uk-gcse-alevel/LICENSE +21 -21
  676. package/skills/education/edu-uk-gcse-alevel/SKILL.md +51 -51
  677. package/skills/education/edu-usa-graduate/LICENSE +21 -21
  678. package/skills/education/edu-usa-graduate/SKILL.md +57 -57
  679. package/skills/education/edu-usa-sat-act/LICENSE +21 -21
  680. package/skills/education/edu-usa-sat-act/SKILL.md +55 -55
  681. package/skills/education/edu-vietnam/LICENSE +21 -21
  682. package/skills/education/edu-vietnam/SKILL.md +53 -53
  683. package/skills/eightctl/SKILL.md +54 -54
  684. package/skills/engineering/eng-aerospace/LICENSE +21 -21
  685. package/skills/engineering/eng-aerospace/SKILL.md +117 -117
  686. package/skills/engineering/eng-chemical/LICENSE +21 -21
  687. package/skills/engineering/eng-chemical/SKILL.md +63 -63
  688. package/skills/engineering/eng-civil/LICENSE +21 -21
  689. package/skills/engineering/eng-civil/SKILL.md +223 -223
  690. package/skills/engineering/eng-control-systems/LICENSE +21 -21
  691. package/skills/engineering/eng-control-systems/SKILL.md +158 -158
  692. package/skills/engineering/eng-cryogenics/LICENSE +21 -21
  693. package/skills/engineering/eng-cryogenics/SKILL.md +151 -151
  694. package/skills/engineering/eng-electrical/LICENSE +21 -21
  695. package/skills/engineering/eng-electrical/SKILL.md +70 -70
  696. package/skills/engineering/eng-electronics-embedded/LICENSE +21 -21
  697. package/skills/engineering/eng-electronics-embedded/SKILL.md +89 -89
  698. package/skills/engineering/eng-environmental/LICENSE +21 -21
  699. package/skills/engineering/eng-environmental/SKILL.md +66 -66
  700. package/skills/engineering/eng-manufacturing/LICENSE +21 -21
  701. package/skills/engineering/eng-manufacturing/SKILL.md +78 -78
  702. package/skills/engineering/eng-mechanical/LICENSE +21 -21
  703. package/skills/engineering/eng-mechanical/SKILL.md +66 -66
  704. package/skills/engineering/eng-project/LICENSE +21 -21
  705. package/skills/engineering/eng-project/SKILL.md +72 -72
  706. package/skills/engineering/eng-propulsion/LICENSE +21 -21
  707. package/skills/engineering/eng-propulsion/SKILL.md +133 -133
  708. package/skills/engineering/eng-robotics/LICENSE +21 -21
  709. package/skills/engineering/eng-robotics/SKILL.md +92 -92
  710. package/skills/engineering/eng-systems/LICENSE +21 -21
  711. package/skills/engineering/eng-systems/SKILL.md +81 -81
  712. package/skills/environment/env-biodiversity/LICENSE +21 -21
  713. package/skills/environment/env-biodiversity/SKILL.md +66 -66
  714. package/skills/environment/env-circular-economy/LICENSE +21 -21
  715. package/skills/environment/env-circular-economy/SKILL.md +71 -71
  716. package/skills/environment/env-climate-action/LICENSE +21 -21
  717. package/skills/environment/env-climate-action/SKILL.md +55 -55
  718. package/skills/environment/env-energy/LICENSE +21 -21
  719. package/skills/environment/env-energy/SKILL.md +83 -83
  720. package/skills/environment/env-sustainability-biz/LICENSE +21 -21
  721. package/skills/environment/env-sustainability-biz/SKILL.md +65 -65
  722. package/skills/environment/env-water/LICENSE +21 -21
  723. package/skills/environment/env-water/SKILL.md +67 -67
  724. package/skills/finance/finance-accounting/LICENSE +21 -21
  725. package/skills/finance/finance-accounting/SKILL.md +239 -239
  726. package/skills/finance/finance-banking/LICENSE +21 -21
  727. package/skills/finance/finance-banking/SKILL.md +54 -54
  728. package/skills/finance/finance-corporate/LICENSE +21 -21
  729. package/skills/finance/finance-corporate/SKILL.md +105 -105
  730. package/skills/finance/finance-crypto/LICENSE +21 -21
  731. package/skills/finance/finance-crypto/SKILL.md +94 -94
  732. package/skills/finance/finance-debt-management/LICENSE +21 -21
  733. package/skills/finance/finance-debt-management/SKILL.md +87 -87
  734. package/skills/finance/finance-insurance/LICENSE +21 -21
  735. package/skills/finance/finance-insurance/SKILL.md +91 -91
  736. package/skills/finance/finance-investing/LICENSE +21 -21
  737. package/skills/finance/finance-investing/SKILL.md +269 -269
  738. package/skills/finance/finance-options-derivatives/LICENSE +21 -21
  739. package/skills/finance/finance-options-derivatives/SKILL.md +68 -68
  740. package/skills/finance/finance-personal/LICENSE +21 -21
  741. package/skills/finance/finance-personal/SKILL.md +268 -268
  742. package/skills/finance/finance-real-estate/LICENSE +21 -21
  743. package/skills/finance/finance-real-estate/SKILL.md +110 -110
  744. package/skills/finance/finance-startup/LICENSE +21 -21
  745. package/skills/finance/finance-startup/SKILL.md +253 -253
  746. package/skills/finance/finance-tax-planning/LICENSE +21 -21
  747. package/skills/finance/finance-tax-planning/SKILL.md +89 -89
  748. package/skills/finance/finance-trading/LICENSE +21 -21
  749. package/skills/finance/finance-trading/SKILL.md +112 -112
  750. package/skills/gemini/SKILL.md +51 -51
  751. package/skills/gh-issues/SKILL.md +216 -216
  752. package/skills/gifgrep/SKILL.md +89 -89
  753. package/skills/github/SKILL.md +87 -87
  754. package/skills/gog/SKILL.md +120 -120
  755. package/skills/goplaces/SKILL.md +56 -56
  756. package/skills/health/health-aging/LICENSE +21 -21
  757. package/skills/health/health-aging/SKILL.md +82 -82
  758. package/skills/health/health-chronic/LICENSE +21 -21
  759. package/skills/health/health-chronic/SKILL.md +202 -202
  760. package/skills/health/health-dental/LICENSE +21 -21
  761. package/skills/health/health-dental/SKILL.md +41 -41
  762. package/skills/health/health-eye-care/LICENSE +21 -21
  763. package/skills/health/health-eye-care/SKILL.md +56 -56
  764. package/skills/health/health-first-aid/LICENSE +21 -21
  765. package/skills/health/health-first-aid/SKILL.md +201 -201
  766. package/skills/health/health-fitness/LICENSE +21 -21
  767. package/skills/health/health-fitness/SKILL.md +111 -111
  768. package/skills/health/health-general/LICENSE +21 -21
  769. package/skills/health/health-general/SKILL.md +277 -277
  770. package/skills/health/health-mens/LICENSE +21 -21
  771. package/skills/health/health-mens/SKILL.md +53 -53
  772. package/skills/health/health-mental/LICENSE +21 -21
  773. package/skills/health/health-mental/SKILL.md +221 -221
  774. package/skills/health/health-naturopathy-ayurveda/LICENSE +21 -21
  775. package/skills/health/health-naturopathy-ayurveda/SKILL.md +60 -60
  776. package/skills/health/health-nutrition/LICENSE +21 -21
  777. package/skills/health/health-nutrition/SKILL.md +262 -262
  778. package/skills/health/health-pediatric/LICENSE +21 -21
  779. package/skills/health/health-pediatric/SKILL.md +94 -94
  780. package/skills/health/health-pharmacology/LICENSE +21 -21
  781. package/skills/health/health-pharmacology/SKILL.md +87 -87
  782. package/skills/health/health-pregnancy/LICENSE +21 -21
  783. package/skills/health/health-pregnancy/SKILL.md +71 -71
  784. package/skills/health/health-skin/LICENSE +21 -21
  785. package/skills/health/health-skin/SKILL.md +71 -71
  786. package/skills/health/health-sleep/LICENSE +21 -21
  787. package/skills/health/health-sleep/SKILL.md +81 -81
  788. package/skills/health/health-womens/LICENSE +21 -21
  789. package/skills/health/health-womens/SKILL.md +72 -72
  790. package/skills/health/health-yoga-wellness/LICENSE +21 -21
  791. package/skills/health/health-yoga-wellness/SKILL.md +58 -58
  792. package/skills/healthcare-systems/health-sys-global/LICENSE +21 -21
  793. package/skills/healthcare-systems/health-sys-global/SKILL.md +69 -69
  794. package/skills/healthcare-systems/health-sys-management/LICENSE +21 -21
  795. package/skills/healthcare-systems/health-sys-management/SKILL.md +71 -71
  796. package/skills/healthcare-systems/health-sys-navigation/LICENSE +21 -21
  797. package/skills/healthcare-systems/health-sys-navigation/SKILL.md +60 -60
  798. package/skills/healthcare-systems/health-sys-public/LICENSE +21 -21
  799. package/skills/healthcare-systems/health-sys-public/SKILL.md +71 -71
  800. package/skills/healthcheck/SKILL.md +109 -109
  801. package/skills/himalaya/SKILL.md +84 -84
  802. package/skills/himalaya/references/configuration.md +184 -184
  803. package/skills/himalaya/references/message-composition.md +199 -199
  804. package/skills/humanities/humanities-history-world/LICENSE +21 -21
  805. package/skills/humanities/humanities-history-world/SKILL.md +59 -59
  806. package/skills/humanities/humanities-indian-classical/LICENSE +21 -21
  807. package/skills/humanities/humanities-indian-classical/SKILL.md +104 -104
  808. package/skills/humanities/humanities-philosophy/LICENSE +21 -21
  809. package/skills/humanities/humanities-philosophy/SKILL.md +105 -105
  810. package/skills/humanities/humanities-world-religions/LICENSE +21 -21
  811. package/skills/humanities/humanities-world-religions/SKILL.md +67 -67
  812. package/skills/impeccable/SKILL.md +185 -185
  813. package/skills/imsg/SKILL.md +126 -126
  814. package/skills/industry/industry-construction/LICENSE +21 -21
  815. package/skills/industry/industry-construction/SKILL.md +81 -81
  816. package/skills/industry/industry-education-sector/LICENSE +21 -21
  817. package/skills/industry/industry-education-sector/SKILL.md +49 -49
  818. package/skills/industry/industry-fashion/LICENSE +21 -21
  819. package/skills/industry/industry-fashion/SKILL.md +82 -82
  820. package/skills/industry/industry-food/LICENSE +21 -21
  821. package/skills/industry/industry-food/SKILL.md +79 -79
  822. package/skills/industry/industry-government/LICENSE +21 -21
  823. package/skills/industry/industry-government/SKILL.md +80 -80
  824. package/skills/industry/industry-hospitality/LICENSE +21 -21
  825. package/skills/industry/industry-hospitality/SKILL.md +73 -73
  826. package/skills/industry/industry-insurance-sector/LICENSE +21 -21
  827. package/skills/industry/industry-insurance-sector/SKILL.md +57 -57
  828. package/skills/industry/industry-logistics/LICENSE +21 -21
  829. package/skills/industry/industry-logistics/SKILL.md +80 -80
  830. package/skills/industry/industry-media/LICENSE +21 -21
  831. package/skills/industry/industry-media/SKILL.md +66 -66
  832. package/skills/industry/industry-nonprofit/LICENSE +21 -21
  833. package/skills/industry/industry-nonprofit/SKILL.md +77 -77
  834. package/skills/industry/industry-pharma/LICENSE +21 -21
  835. package/skills/industry/industry-pharma/SKILL.md +69 -69
  836. package/skills/industry/industry-real-estate/LICENSE +21 -21
  837. package/skills/industry/industry-real-estate/SKILL.md +61 -61
  838. package/skills/industry/industry-sports/LICENSE +21 -21
  839. package/skills/industry/industry-sports/SKILL.md +71 -71
  840. package/skills/industry/industry-tech-startup/LICENSE +21 -21
  841. package/skills/industry/industry-tech-startup/SKILL.md +82 -82
  842. package/skills/internal-comms/LICENSE +21 -21
  843. package/skills/internal-comms/SKILL.md +38 -38
  844. package/skills/internal-comms/examples/3p-updates.md +49 -49
  845. package/skills/internal-comms/examples/company-newsletter.md +76 -76
  846. package/skills/internal-comms/examples/faq-answers.md +35 -35
  847. package/skills/internal-comms/examples/general-comms.md +19 -19
  848. package/skills/legal/legal-business/LICENSE +21 -21
  849. package/skills/legal/legal-business/SKILL.md +227 -227
  850. package/skills/legal/legal-consumer/LICENSE +21 -21
  851. package/skills/legal/legal-consumer/SKILL.md +155 -155
  852. package/skills/legal/legal-contracts/LICENSE +21 -21
  853. package/skills/legal/legal-contracts/SKILL.md +268 -268
  854. package/skills/legal/legal-corporate-governance/LICENSE +21 -21
  855. package/skills/legal/legal-corporate-governance/SKILL.md +53 -53
  856. package/skills/legal/legal-employment/LICENSE +21 -21
  857. package/skills/legal/legal-employment/SKILL.md +291 -291
  858. package/skills/legal/legal-immigration/LICENSE +21 -21
  859. package/skills/legal/legal-immigration/SKILL.md +146 -146
  860. package/skills/legal/legal-international/LICENSE +21 -21
  861. package/skills/legal/legal-international/SKILL.md +51 -51
  862. package/skills/legal/legal-ip/LICENSE +21 -21
  863. package/skills/legal/legal-ip/SKILL.md +264 -264
  864. package/skills/legal/legal-privacy/LICENSE +21 -21
  865. package/skills/legal/legal-privacy/SKILL.md +161 -161
  866. package/skills/legal/legal-real-estate/LICENSE +21 -21
  867. package/skills/legal/legal-real-estate/SKILL.md +142 -142
  868. package/skills/legal/legal-startup/LICENSE +21 -21
  869. package/skills/legal/legal-startup/SKILL.md +182 -182
  870. package/skills/legal/legal-tax/LICENSE +21 -21
  871. package/skills/legal/legal-tax/SKILL.md +156 -156
  872. package/skills/mcp-builder/LICENSE +21 -21
  873. package/skills/mcp-builder/SKILL.md +257 -257
  874. package/skills/mcp-builder/reference/evaluation.md +630 -630
  875. package/skills/mcp-builder/reference/mcp_best_practices.md +269 -269
  876. package/skills/mcp-builder/reference/node_mcp_server.md +980 -980
  877. package/skills/mcp-builder/reference/python_mcp_server.md +737 -737
  878. package/skills/mcp-builder/scripts/connections.py +151 -151
  879. package/skills/mcp-builder/scripts/evaluation.py +373 -373
  880. package/skills/mcp-builder/scripts/example_evaluation.xml +22 -22
  881. package/skills/mcp-builder/scripts/requirements.txt +2 -2
  882. package/skills/mcporter/SKILL.md +65 -65
  883. package/skills/meme-maker/SKILL.md +46 -46
  884. package/skills/meme-maker/references/templates.json +358 -358
  885. package/skills/meme-maker/scripts/meme.mjs +398 -398
  886. package/skills/mental-health/mental-health-cbt/LICENSE +21 -21
  887. package/skills/mental-health/mental-health-cbt/SKILL.md +254 -254
  888. package/skills/mental-health/psych-addiction/LICENSE +21 -21
  889. package/skills/mental-health/psych-addiction/SKILL.md +79 -79
  890. package/skills/mental-health/psych-behavioral-econ/LICENSE +21 -21
  891. package/skills/mental-health/psych-behavioral-econ/SKILL.md +84 -84
  892. package/skills/mental-health/psych-child/LICENSE +21 -21
  893. package/skills/mental-health/psych-child/SKILL.md +84 -84
  894. package/skills/mental-health/psych-grief/LICENSE +21 -21
  895. package/skills/mental-health/psych-grief/SKILL.md +85 -85
  896. package/skills/mental-health/psych-mindfulness/LICENSE +21 -21
  897. package/skills/mental-health/psych-mindfulness/SKILL.md +71 -71
  898. package/skills/mental-health/psych-org/LICENSE +21 -21
  899. package/skills/mental-health/psych-org/SKILL.md +115 -115
  900. package/skills/mental-health/psych-positive/LICENSE +21 -21
  901. package/skills/mental-health/psych-positive/SKILL.md +86 -86
  902. package/skills/mental-health/psych-relationships/LICENSE +21 -21
  903. package/skills/mental-health/psych-relationships/SKILL.md +100 -100
  904. package/skills/mental-health/psych-trauma/LICENSE +21 -21
  905. package/skills/mental-health/psych-trauma/SKILL.md +109 -109
  906. package/skills/model-usage/SKILL.md +75 -75
  907. package/skills/model-usage/references/codexbar-cli.md +33 -33
  908. package/skills/model-usage/scripts/model_usage.py +319 -319
  909. package/skills/model-usage/scripts/test_model_usage.py +40 -40
  910. package/skills/nano-pdf/SKILL.md +42 -42
  911. package/skills/node-connect/SKILL.md +147 -147
  912. package/skills/node-inspect-debugger/SKILL.md +88 -88
  913. package/skills/notion/SKILL.md +154 -154
  914. package/skills/obsidian/SKILL.md +123 -123
  915. package/skills/openai-whisper/SKILL.md +42 -42
  916. package/skills/openai-whisper-api/SKILL.md +75 -75
  917. package/skills/openai-whisper-api/scripts/transcribe.sh +154 -154
  918. package/skills/openhue/SKILL.md +116 -116
  919. package/skills/oracle/SKILL.md +130 -130
  920. package/skills/ordercli/SKILL.md +82 -82
  921. package/skills/peekaboo/SKILL.md +217 -217
  922. package/skills/pyproject.toml +10 -10
  923. package/skills/python-debugpy/SKILL.md +76 -76
  924. package/skills/sag/SKILL.md +91 -91
  925. package/skills/science/sci-astronomy/LICENSE +21 -21
  926. package/skills/science/sci-astronomy/SKILL.md +80 -80
  927. package/skills/science/sci-biology/LICENSE +21 -21
  928. package/skills/science/sci-biology/SKILL.md +74 -74
  929. package/skills/science/sci-chemistry/LICENSE +21 -21
  930. package/skills/science/sci-chemistry/SKILL.md +89 -89
  931. package/skills/science/sci-climate/LICENSE +21 -21
  932. package/skills/science/sci-climate/SKILL.md +72 -72
  933. package/skills/science/sci-data-analysis/LICENSE +21 -21
  934. package/skills/science/sci-data-analysis/SKILL.md +87 -87
  935. package/skills/science/sci-environmental-science/LICENSE +21 -21
  936. package/skills/science/sci-environmental-science/SKILL.md +69 -69
  937. package/skills/science/sci-geology/LICENSE +21 -21
  938. package/skills/science/sci-geology/SKILL.md +56 -56
  939. package/skills/science/sci-method/LICENSE +21 -21
  940. package/skills/science/sci-method/SKILL.md +77 -77
  941. package/skills/science/sci-neuroscience/LICENSE +21 -21
  942. package/skills/science/sci-neuroscience/SKILL.md +79 -79
  943. package/skills/science/sci-physics/LICENSE +21 -21
  944. package/skills/science/sci-physics/SKILL.md +78 -78
  945. package/skills/science/sci-research-methods/LICENSE +21 -21
  946. package/skills/science/sci-research-methods/SKILL.md +83 -83
  947. package/skills/science/sci-statistics/LICENSE +21 -21
  948. package/skills/science/sci-statistics/SKILL.md +249 -249
  949. package/skills/session-logs/SKILL.md +155 -155
  950. package/skills/sherpa-onnx-tts/SKILL.md +113 -113
  951. package/skills/skill-creator/SKILL.md +81 -81
  952. package/skills/skill-creator/license.txt +202 -202
  953. package/skills/skill-creator/scripts/init_skill.py +378 -378
  954. package/skills/skill-creator/scripts/package_skill.py +144 -144
  955. package/skills/skill-creator/scripts/quick_validate.py +169 -169
  956. package/skills/skill-creator/scripts/test_init_skill.py +51 -51
  957. package/skills/skill-creator/scripts/test_package_skill.py +199 -199
  958. package/skills/skill-creator/scripts/test_quick_validate.py +116 -116
  959. package/skills/slack/SKILL.md +82 -82
  960. package/skills/slack-gif-creator/LICENSE +21 -21
  961. package/skills/slack-gif-creator/SKILL.md +293 -293
  962. package/skills/slack-gif-creator/requirements.txt +3 -3
  963. package/skills/social-sciences/social-anthropology/LICENSE +21 -21
  964. package/skills/social-sciences/social-anthropology/SKILL.md +62 -62
  965. package/skills/social-sciences/social-economics/LICENSE +21 -21
  966. package/skills/social-sciences/social-economics/SKILL.md +88 -88
  967. package/skills/social-sciences/social-geography/LICENSE +21 -21
  968. package/skills/social-sciences/social-geography/SKILL.md +61 -61
  969. package/skills/social-sciences/social-international-dev/LICENSE +21 -21
  970. package/skills/social-sciences/social-international-dev/SKILL.md +76 -76
  971. package/skills/social-sciences/social-political-science/LICENSE +21 -21
  972. package/skills/social-sciences/social-political-science/SKILL.md +70 -70
  973. package/skills/social-sciences/social-public-policy/LICENSE +21 -21
  974. package/skills/social-sciences/social-public-policy/SKILL.md +73 -73
  975. package/skills/social-sciences/social-sociology/LICENSE +21 -21
  976. package/skills/social-sciences/social-sociology/SKILL.md +78 -78
  977. package/skills/songsee/SKILL.md +53 -53
  978. package/skills/sonoscli/SKILL.md +69 -69
  979. package/skills/spike/SKILL.md +55 -55
  980. package/skills/spotify-player/SKILL.md +68 -68
  981. package/skills/summarize/SKILL.md +90 -90
  982. package/skills/taskflow/SKILL.md +153 -153
  983. package/skills/taskflow/examples/inbox-triage.lobster +33 -33
  984. package/skills/taskflow/examples/pr-intake.lobster +32 -32
  985. package/skills/taskflow-inbox-triage/SKILL.md +123 -123
  986. package/skills/technical/ai-ethics/LICENSE +21 -21
  987. package/skills/technical/ai-ethics/SKILL.md +92 -92
  988. package/skills/technical/ai-product-builder/LICENSE +21 -21
  989. package/skills/technical/ai-product-builder/SKILL.md +180 -180
  990. package/skills/technical/analytics-setup/LICENSE +21 -21
  991. package/skills/technical/analytics-setup/SKILL.md +125 -125
  992. package/skills/technical/api-builder/LICENSE +21 -21
  993. package/skills/technical/api-builder/SKILL.md +202 -202
  994. package/skills/technical/architecture-decisions/LICENSE +21 -21
  995. package/skills/technical/architecture-decisions/SKILL.md +120 -120
  996. package/skills/technical/auth-security/LICENSE +21 -21
  997. package/skills/technical/auth-security/SKILL.md +209 -209
  998. package/skills/technical/blockchain-web3/LICENSE +21 -21
  999. package/skills/technical/blockchain-web3/SKILL.md +84 -84
  1000. package/skills/technical/cloud-architecture/LICENSE +21 -21
  1001. package/skills/technical/cloud-architecture/SKILL.md +85 -85
  1002. package/skills/technical/content-platform/LICENSE +21 -21
  1003. package/skills/technical/content-platform/SKILL.md +134 -134
  1004. package/skills/technical/cybersecurity-advanced/LICENSE +21 -21
  1005. package/skills/technical/cybersecurity-advanced/SKILL.md +99 -99
  1006. package/skills/technical/data-engineering/LICENSE +21 -21
  1007. package/skills/technical/data-engineering/SKILL.md +117 -117
  1008. package/skills/technical/database-design/LICENSE +21 -21
  1009. package/skills/technical/database-design/SKILL.md +185 -185
  1010. package/skills/technical/devops-cicd/LICENSE +21 -21
  1011. package/skills/technical/devops-cicd/SKILL.md +181 -181
  1012. package/skills/technical/ecommerce-builder/LICENSE +21 -21
  1013. package/skills/technical/ecommerce-builder/SKILL.md +123 -123
  1014. package/skills/technical/email-marketing/LICENSE +21 -21
  1015. package/skills/technical/email-marketing/SKILL.md +128 -128
  1016. package/skills/technical/fintech-builder/LICENSE +21 -21
  1017. package/skills/technical/fintech-builder/SKILL.md +141 -141
  1018. package/skills/technical/full-stack-web/LICENSE +21 -21
  1019. package/skills/technical/full-stack-web/SKILL.md +173 -173
  1020. package/skills/technical/gdpr-basics/LICENSE +21 -21
  1021. package/skills/technical/gdpr-basics/SKILL.md +145 -145
  1022. package/skills/technical/launch-playbook/LICENSE +21 -21
  1023. package/skills/technical/launch-playbook/SKILL.md +95 -95
  1024. package/skills/technical/marketing-copy/LICENSE +21 -21
  1025. package/skills/technical/marketing-copy/SKILL.md +126 -126
  1026. package/skills/technical/marketplace-builder/LICENSE +21 -21
  1027. package/skills/technical/marketplace-builder/SKILL.md +105 -105
  1028. package/skills/technical/mobile-pwa/LICENSE +21 -21
  1029. package/skills/technical/mobile-pwa/SKILL.md +191 -191
  1030. package/skills/technical/no-code-tools/LICENSE +21 -21
  1031. package/skills/technical/no-code-tools/SKILL.md +80 -80
  1032. package/skills/technical/open-source/LICENSE +21 -21
  1033. package/skills/technical/open-source/SKILL.md +71 -71
  1034. package/skills/technical/performance-optimization/LICENSE +21 -21
  1035. package/skills/technical/performance-optimization/SKILL.md +155 -155
  1036. package/skills/technical/pricing-design/LICENSE +21 -21
  1037. package/skills/technical/pricing-design/SKILL.md +87 -87
  1038. package/skills/technical/product-management/LICENSE +21 -21
  1039. package/skills/technical/product-management/SKILL.md +94 -94
  1040. package/skills/technical/saas-builder/LICENSE +21 -21
  1041. package/skills/technical/saas-builder/SKILL.md +138 -138
  1042. package/skills/technical/scope-estimation/LICENSE +21 -21
  1043. package/skills/technical/scope-estimation/SKILL.md +99 -99
  1044. package/skills/technical/secrets-management/LICENSE +21 -21
  1045. package/skills/technical/secrets-management/SKILL.md +135 -135
  1046. package/skills/technical/seo-technical/LICENSE +21 -21
  1047. package/skills/technical/seo-technical/SKILL.md +136 -136
  1048. package/skills/technical/technical-writing/LICENSE +21 -21
  1049. package/skills/technical/technical-writing/SKILL.md +149 -149
  1050. package/skills/technical/ux-research-tools/LICENSE +21 -21
  1051. package/skills/technical/ux-research-tools/SKILL.md +54 -54
  1052. package/skills/theme-factory/LICENSE +21 -21
  1053. package/skills/theme-factory/SKILL.md +65 -65
  1054. package/skills/theme-factory/themes/arctic-frost.md +19 -19
  1055. package/skills/theme-factory/themes/botanical-garden.md +19 -19
  1056. package/skills/theme-factory/themes/desert-rose.md +19 -19
  1057. package/skills/theme-factory/themes/forest-canopy.md +19 -19
  1058. package/skills/theme-factory/themes/golden-hour.md +19 -19
  1059. package/skills/theme-factory/themes/midnight-galaxy.md +19 -19
  1060. package/skills/theme-factory/themes/modern-minimalist.md +19 -19
  1061. package/skills/theme-factory/themes/ocean-depths.md +19 -19
  1062. package/skills/theme-factory/themes/sunset-boulevard.md +19 -19
  1063. package/skills/theme-factory/themes/tech-innovation.md +19 -19
  1064. package/skills/things-mac/SKILL.md +90 -90
  1065. package/skills/tmux/SKILL.md +95 -95
  1066. package/skills/tmux/scripts/find-sessions.sh +112 -112
  1067. package/skills/tmux/scripts/wait-for-text.sh +83 -83
  1068. package/skills/trades/trades-agriculture/LICENSE +21 -21
  1069. package/skills/trades/trades-agriculture/SKILL.md +80 -80
  1070. package/skills/trades/trades-automotive/LICENSE +21 -21
  1071. package/skills/trades/trades-automotive/SKILL.md +84 -84
  1072. package/skills/trades/trades-carpentry/LICENSE +21 -21
  1073. package/skills/trades/trades-carpentry/SKILL.md +71 -71
  1074. package/skills/trades/trades-cooking-pro/LICENSE +21 -21
  1075. package/skills/trades/trades-cooking-pro/SKILL.md +90 -90
  1076. package/skills/trades/trades-electrical/LICENSE +21 -21
  1077. package/skills/trades/trades-electrical/SKILL.md +146 -146
  1078. package/skills/trades/trades-hvac/LICENSE +21 -21
  1079. package/skills/trades/trades-hvac/SKILL.md +80 -80
  1080. package/skills/trades/trades-landscaping/LICENSE +21 -21
  1081. package/skills/trades/trades-landscaping/SKILL.md +60 -60
  1082. package/skills/trades/trades-metalworking/LICENSE +21 -21
  1083. package/skills/trades/trades-metalworking/SKILL.md +64 -64
  1084. package/skills/trades/trades-painting/LICENSE +21 -21
  1085. package/skills/trades/trades-painting/SKILL.md +70 -70
  1086. package/skills/trades/trades-plumbing/LICENSE +21 -21
  1087. package/skills/trades/trades-plumbing/SKILL.md +160 -160
  1088. package/skills/trades/trades-welding/LICENSE +21 -21
  1089. package/skills/trades/trades-welding/SKILL.md +82 -82
  1090. package/skills/trello/SKILL.md +112 -112
  1091. package/skills/uipm-ui-styling/SKILL.md +328 -328
  1092. package/skills/video-frames/SKILL.md +50 -50
  1093. package/skills/video-frames/scripts/frame.sh +81 -81
  1094. package/skills/voice-call/SKILL.md +49 -49
  1095. package/skills/wacli/SKILL.md +76 -76
  1096. package/skills/weather/SKILL.md +91 -91
  1097. package/skills/web-artifacts-builder/LICENSE +21 -21
  1098. package/skills/web-artifacts-builder/SKILL.md +82 -82
  1099. package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +53 -53
  1100. package/skills/web-artifacts-builder/scripts/init-artifact.sh +322 -322
  1101. package/skills/xurl/SKILL.md +124 -124
  1102. package/skills/graphify/SKILL.md +0 -619
  1103. package/skills/graphify/__init__.py +0 -28
  1104. package/skills/graphify/__main__.py +0 -4582
  1105. package/skills/graphify/affected.py +0 -154
  1106. package/skills/graphify/always_on/agents-md.md +0 -12
  1107. package/skills/graphify/always_on/antigravity-rules.md +0 -14
  1108. package/skills/graphify/always_on/claude-md.md +0 -9
  1109. package/skills/graphify/always_on/gemini-md.md +0 -9
  1110. package/skills/graphify/always_on/kiro-steering.md +0 -5
  1111. package/skills/graphify/always_on/vscode-instructions.md +0 -17
  1112. package/skills/graphify/analyze.py +0 -724
  1113. package/skills/graphify/benchmark.py +0 -155
  1114. package/skills/graphify/build.py +0 -487
  1115. package/skills/graphify/cache.py +0 -417
  1116. package/skills/graphify/callflow_html.py +0 -2020
  1117. package/skills/graphify/cluster.py +0 -272
  1118. package/skills/graphify/command-kilo.md +0 -15
  1119. package/skills/graphify/dedup.py +0 -429
  1120. package/skills/graphify/detect.py +0 -1379
  1121. package/skills/graphify/diagnostics.py +0 -390
  1122. package/skills/graphify/export.py +0 -1408
  1123. package/skills/graphify/extract.py +0 -11570
  1124. package/skills/graphify/global_graph.py +0 -159
  1125. package/skills/graphify/google_workspace.py +0 -223
  1126. package/skills/graphify/hooks.py +0 -457
  1127. package/skills/graphify/ingest.py +0 -331
  1128. package/skills/graphify/llm.py +0 -1896
  1129. package/skills/graphify/manifest.py +0 -4
  1130. package/skills/graphify/mcp_ingest.py +0 -392
  1131. package/skills/graphify/multigraph_compat.py +0 -212
  1132. package/skills/graphify/pg_introspect.py +0 -142
  1133. package/skills/graphify/prs.py +0 -748
  1134. package/skills/graphify/querylog.py +0 -70
  1135. package/skills/graphify/report.py +0 -218
  1136. package/skills/graphify/scip_ingest.py +0 -363
  1137. package/skills/graphify/security.py +0 -336
  1138. package/skills/graphify/semantic_cleanup.py +0 -319
  1139. package/skills/graphify/serve.py +0 -1309
  1140. package/skills/graphify/skill-aider.md +0 -1246
  1141. package/skills/graphify/skill-amp.md +0 -613
  1142. package/skills/graphify/skill-claw.md +0 -616
  1143. package/skills/graphify/skill-codex.md +0 -613
  1144. package/skills/graphify/skill-copilot.md +0 -616
  1145. package/skills/graphify/skill-devin.md +0 -1372
  1146. package/skills/graphify/skill-droid.md +0 -613
  1147. package/skills/graphify/skill-kilo.md +0 -625
  1148. package/skills/graphify/skill-kiro.md +0 -615
  1149. package/skills/graphify/skill-opencode.md +0 -608
  1150. package/skills/graphify/skill-pi.md +0 -615
  1151. package/skills/graphify/skill-trae.md +0 -614
  1152. package/skills/graphify/skill-vscode.md +0 -612
  1153. package/skills/graphify/skill-windows.md +0 -651
  1154. package/skills/graphify/skills/amp/references/add-watch.md +0 -56
  1155. package/skills/graphify/skills/amp/references/exports.md +0 -71
  1156. package/skills/graphify/skills/amp/references/extraction-spec.md +0 -68
  1157. package/skills/graphify/skills/amp/references/github-and-merge.md +0 -46
  1158. package/skills/graphify/skills/amp/references/hooks.md +0 -33
  1159. package/skills/graphify/skills/amp/references/query.md +0 -249
  1160. package/skills/graphify/skills/amp/references/transcribe.md +0 -48
  1161. package/skills/graphify/skills/amp/references/update.md +0 -179
  1162. package/skills/graphify/skills/claude/references/add-watch.md +0 -56
  1163. package/skills/graphify/skills/claude/references/exports.md +0 -71
  1164. package/skills/graphify/skills/claude/references/extraction-spec.md +0 -68
  1165. package/skills/graphify/skills/claude/references/github-and-merge.md +0 -46
  1166. package/skills/graphify/skills/claude/references/hooks.md +0 -33
  1167. package/skills/graphify/skills/claude/references/query.md +0 -103
  1168. package/skills/graphify/skills/claude/references/transcribe.md +0 -48
  1169. package/skills/graphify/skills/claude/references/update.md +0 -179
  1170. package/skills/graphify/skills/claw/references/add-watch.md +0 -56
  1171. package/skills/graphify/skills/claw/references/exports.md +0 -71
  1172. package/skills/graphify/skills/claw/references/extraction-spec.md +0 -29
  1173. package/skills/graphify/skills/claw/references/github-and-merge.md +0 -46
  1174. package/skills/graphify/skills/claw/references/hooks.md +0 -33
  1175. package/skills/graphify/skills/claw/references/query.md +0 -249
  1176. package/skills/graphify/skills/claw/references/transcribe.md +0 -48
  1177. package/skills/graphify/skills/claw/references/update.md +0 -179
  1178. package/skills/graphify/skills/codex/references/add-watch.md +0 -56
  1179. package/skills/graphify/skills/codex/references/exports.md +0 -71
  1180. package/skills/graphify/skills/codex/references/extraction-spec.md +0 -29
  1181. package/skills/graphify/skills/codex/references/github-and-merge.md +0 -46
  1182. package/skills/graphify/skills/codex/references/hooks.md +0 -33
  1183. package/skills/graphify/skills/codex/references/query.md +0 -249
  1184. package/skills/graphify/skills/codex/references/transcribe.md +0 -48
  1185. package/skills/graphify/skills/codex/references/update.md +0 -179
  1186. package/skills/graphify/skills/copilot/references/add-watch.md +0 -56
  1187. package/skills/graphify/skills/copilot/references/exports.md +0 -71
  1188. package/skills/graphify/skills/copilot/references/extraction-spec.md +0 -68
  1189. package/skills/graphify/skills/copilot/references/github-and-merge.md +0 -46
  1190. package/skills/graphify/skills/copilot/references/hooks.md +0 -33
  1191. package/skills/graphify/skills/copilot/references/query.md +0 -249
  1192. package/skills/graphify/skills/copilot/references/transcribe.md +0 -48
  1193. package/skills/graphify/skills/copilot/references/update.md +0 -179
  1194. package/skills/graphify/skills/droid/references/add-watch.md +0 -56
  1195. package/skills/graphify/skills/droid/references/exports.md +0 -71
  1196. package/skills/graphify/skills/droid/references/extraction-spec.md +0 -68
  1197. package/skills/graphify/skills/droid/references/github-and-merge.md +0 -46
  1198. package/skills/graphify/skills/droid/references/hooks.md +0 -33
  1199. package/skills/graphify/skills/droid/references/query.md +0 -249
  1200. package/skills/graphify/skills/droid/references/transcribe.md +0 -48
  1201. package/skills/graphify/skills/droid/references/update.md +0 -179
  1202. package/skills/graphify/skills/kilo/references/add-watch.md +0 -56
  1203. package/skills/graphify/skills/kilo/references/exports.md +0 -71
  1204. package/skills/graphify/skills/kilo/references/extraction-spec.md +0 -68
  1205. package/skills/graphify/skills/kilo/references/github-and-merge.md +0 -46
  1206. package/skills/graphify/skills/kilo/references/hooks.md +0 -33
  1207. package/skills/graphify/skills/kilo/references/query.md +0 -249
  1208. package/skills/graphify/skills/kilo/references/transcribe.md +0 -48
  1209. package/skills/graphify/skills/kilo/references/update.md +0 -179
  1210. package/skills/graphify/skills/kiro/references/add-watch.md +0 -56
  1211. package/skills/graphify/skills/kiro/references/exports.md +0 -71
  1212. package/skills/graphify/skills/kiro/references/extraction-spec.md +0 -29
  1213. package/skills/graphify/skills/kiro/references/github-and-merge.md +0 -46
  1214. package/skills/graphify/skills/kiro/references/hooks.md +0 -33
  1215. package/skills/graphify/skills/kiro/references/query.md +0 -249
  1216. package/skills/graphify/skills/kiro/references/transcribe.md +0 -48
  1217. package/skills/graphify/skills/kiro/references/update.md +0 -179
  1218. package/skills/graphify/skills/opencode/references/add-watch.md +0 -56
  1219. package/skills/graphify/skills/opencode/references/exports.md +0 -71
  1220. package/skills/graphify/skills/opencode/references/extraction-spec.md +0 -68
  1221. package/skills/graphify/skills/opencode/references/github-and-merge.md +0 -46
  1222. package/skills/graphify/skills/opencode/references/hooks.md +0 -33
  1223. package/skills/graphify/skills/opencode/references/query.md +0 -249
  1224. package/skills/graphify/skills/opencode/references/transcribe.md +0 -48
  1225. package/skills/graphify/skills/opencode/references/update.md +0 -179
  1226. package/skills/graphify/skills/pi/references/add-watch.md +0 -56
  1227. package/skills/graphify/skills/pi/references/exports.md +0 -71
  1228. package/skills/graphify/skills/pi/references/extraction-spec.md +0 -29
  1229. package/skills/graphify/skills/pi/references/github-and-merge.md +0 -46
  1230. package/skills/graphify/skills/pi/references/hooks.md +0 -33
  1231. package/skills/graphify/skills/pi/references/query.md +0 -249
  1232. package/skills/graphify/skills/pi/references/transcribe.md +0 -48
  1233. package/skills/graphify/skills/pi/references/update.md +0 -179
  1234. package/skills/graphify/skills/trae/references/add-watch.md +0 -56
  1235. package/skills/graphify/skills/trae/references/exports.md +0 -71
  1236. package/skills/graphify/skills/trae/references/extraction-spec.md +0 -68
  1237. package/skills/graphify/skills/trae/references/github-and-merge.md +0 -46
  1238. package/skills/graphify/skills/trae/references/hooks.md +0 -35
  1239. package/skills/graphify/skills/trae/references/query.md +0 -249
  1240. package/skills/graphify/skills/trae/references/transcribe.md +0 -48
  1241. package/skills/graphify/skills/trae/references/update.md +0 -179
  1242. package/skills/graphify/skills/vscode/references/add-watch.md +0 -56
  1243. package/skills/graphify/skills/vscode/references/exports.md +0 -71
  1244. package/skills/graphify/skills/vscode/references/extraction-spec.md +0 -68
  1245. package/skills/graphify/skills/vscode/references/github-and-merge.md +0 -46
  1246. package/skills/graphify/skills/vscode/references/hooks.md +0 -33
  1247. package/skills/graphify/skills/vscode/references/query.md +0 -249
  1248. package/skills/graphify/skills/vscode/references/transcribe.md +0 -48
  1249. package/skills/graphify/skills/vscode/references/update.md +0 -179
  1250. package/skills/graphify/skills/windows/references/add-watch.md +0 -56
  1251. package/skills/graphify/skills/windows/references/exports.md +0 -71
  1252. package/skills/graphify/skills/windows/references/extraction-spec.md +0 -68
  1253. package/skills/graphify/skills/windows/references/github-and-merge.md +0 -46
  1254. package/skills/graphify/skills/windows/references/hooks.md +0 -33
  1255. package/skills/graphify/skills/windows/references/query.md +0 -249
  1256. package/skills/graphify/skills/windows/references/transcribe.md +0 -48
  1257. package/skills/graphify/skills/windows/references/update.md +0 -179
  1258. package/skills/graphify/symbol_resolution.py +0 -538
  1259. package/skills/graphify/transcribe.py +0 -184
  1260. package/skills/graphify/tree_html.py +0 -582
  1261. package/skills/graphify/validate.py +0 -72
  1262. package/skills/graphify/watch.py +0 -898
  1263. package/skills/graphify/wiki.py +0 -282
package/dist/cli.js CHANGED
@@ -1250,37 +1250,37 @@ function registerVoiceSynth(fn) {
1250
1250
  function registerVoiceListen(fn) {
1251
1251
  listener = fn;
1252
1252
  }
1253
- function audioPlayers(file5) {
1254
- if (process.platform === "darwin") return [{ cmd: "afplay", args: [file5] }];
1253
+ function audioPlayers(file6) {
1254
+ if (process.platform === "darwin") return [{ cmd: "afplay", args: [file6] }];
1255
1255
  if (process.platform === "win32")
1256
1256
  return [
1257
- { cmd: "powershell", args: ["-NoProfile", "-c", `(New-Object Media.SoundPlayer '${file5}').PlaySync()`] }
1257
+ { cmd: "powershell", args: ["-NoProfile", "-c", `(New-Object Media.SoundPlayer '${file6}').PlaySync()`] }
1258
1258
  ];
1259
1259
  return [
1260
- { cmd: "aplay", args: ["-q", file5] },
1261
- { cmd: "ffplay", args: ["-nodisp", "-autoexit", "-loglevel", "quiet", file5] },
1262
- { cmd: "paplay", args: [file5] }
1260
+ { cmd: "aplay", args: ["-q", file6] },
1261
+ { cmd: "ffplay", args: ["-nodisp", "-autoexit", "-loglevel", "quiet", file6] },
1262
+ { cmd: "paplay", args: [file6] }
1263
1263
  ];
1264
1264
  }
1265
1265
  function playWav(wav) {
1266
- const file5 = join7(tmpdir(), `oriro-avatar-${process.pid}-${wav.length}.wav`);
1267
- writeFileSync5(file5, wav);
1268
- const players = audioPlayers(file5);
1266
+ const file6 = join7(tmpdir(), `oriro-avatar-${process.pid}-${wav.length}.wav`);
1267
+ writeFileSync5(file6, wav);
1268
+ const players = audioPlayers(file6);
1269
1269
  return new Promise((resolve3) => {
1270
1270
  const tryPlayer = (i) => {
1271
1271
  if (i >= players.length) {
1272
- rmSync(file5, { force: true });
1272
+ rmSync(file6, { force: true });
1273
1273
  return resolve3(false);
1274
1274
  }
1275
1275
  const p = players[i];
1276
1276
  if (!p) {
1277
- rmSync(file5, { force: true });
1277
+ rmSync(file6, { force: true });
1278
1278
  return resolve3(false);
1279
1279
  }
1280
1280
  const child = spawn(p.cmd, p.args, { stdio: "ignore" });
1281
1281
  child.on("error", () => tryPlayer(i + 1));
1282
1282
  child.on("close", (code) => {
1283
- rmSync(file5, { force: true });
1283
+ rmSync(file6, { force: true });
1284
1284
  resolve3(code === 0);
1285
1285
  });
1286
1286
  };
@@ -1317,9 +1317,9 @@ import { existsSync, readFileSync as readFileSync6, rmSync as rmSync2 } from "fs
1317
1317
  function tmpWav() {
1318
1318
  return join8(tmpdir2(), `oriro-tts-${process.pid}-${Date.now()}-${Math.floor(performance.now())}.wav`);
1319
1319
  }
1320
- function readAndClean(file5) {
1321
- const buf = readFileSync6(file5);
1322
- rmSync2(file5, { force: true });
1320
+ function readAndClean(file6) {
1321
+ const buf = readFileSync6(file6);
1322
+ rmSync2(file6, { force: true });
1323
1323
  return new Uint8Array(buf);
1324
1324
  }
1325
1325
  function winSapi(text, lang) {
@@ -1755,13 +1755,6 @@ var ROUTER_CATALOG = [
1755
1755
  freeModels: ["mistralai/Mistral-Small-Instruct"],
1756
1756
  obtainUrl: "https://berget.ai"
1757
1757
  }),
1758
- C4({
1759
- id: "huggingface",
1760
- displayName: "Hugging Face",
1761
- baseUrl: "https://router.huggingface.co/v1",
1762
- freeModels: ["meta-llama/Llama-3.2-3B-Instruct"],
1763
- obtainUrl: "https://huggingface.co/settings/tokens"
1764
- }),
1765
1758
  C4({
1766
1759
  id: "replicate",
1767
1760
  displayName: "Replicate",
@@ -1857,10 +1850,35 @@ var ROUTER_CATALOG = [
1857
1850
  obtainUrl: "https://platform.moonshot.ai",
1858
1851
  tier: "paid"
1859
1852
  }),
1860
- // ── ORIRO models — coming soon, greyed/"(free)", not selectable yet ──
1861
- C4({ id: "oriro-gauss", displayName: "ORIRO-Gauss", baseUrl: "", comingSoon: true }),
1862
- C4({ id: "oriro-avila", displayName: "ORIRO-Avila", baseUrl: "", comingSoon: true })
1853
+ // ── ORIRO's OWN models — LIVE, keyless, first-class racers (2026-07-04) ──
1854
+ // Served through the same-origin oriro.ai worker proxy, which injects the serve key server-side
1855
+ // so the CLI stays keyless (no bearer ever touches the client) the endpoints answer at
1856
+ // baseUrl + "/chat/completions" (race-{gauss,avila}.ts alias). ORIRO-Avila is V2.4 today
1857
+ // (AVILA_SERVE_URL set); ORIRO-Gauss races on the live serve and auto-upgrades to V2.4 the
1858
+ // moment GAUSS_SERVE_URL is flipped — no CLI change needed. Both are true GPU endpoints, so
1859
+ // they only race when the user opts them into the pool (`oriro routers add oriro-gauss`).
1860
+ C4({
1861
+ id: "oriro-gauss",
1862
+ displayName: "ORIRO-Gauss",
1863
+ baseUrl: "https://oriro.ai/api/race/gauss",
1864
+ freeModels: ["gauss"],
1865
+ obtainUrl: "https://oriro.ai",
1866
+ keyless: true,
1867
+ verified: true
1868
+ }),
1869
+ C4({
1870
+ id: "oriro-avila",
1871
+ displayName: "ORIRO-Avila",
1872
+ baseUrl: "https://oriro.ai/api/race/avila",
1873
+ freeModels: ["avila"],
1874
+ obtainUrl: "https://oriro.ai",
1875
+ keyless: true,
1876
+ verified: true
1877
+ })
1863
1878
  ];
1879
+ function selectableRouters() {
1880
+ return ROUTER_CATALOG.filter((r) => !r.comingSoon);
1881
+ }
1864
1882
  function routerById(id) {
1865
1883
  return ROUTER_CATALOG.find((r) => r.id === id);
1866
1884
  }
@@ -3371,7 +3389,7 @@ import {
3371
3389
  } from "@earendil-works/pi-coding-agent";
3372
3390
 
3373
3391
  // src/routers/mux-provider.ts
3374
- import { streamSimple as piStreamSimple, createAssistantMessageEventStream } from "@earendil-works/pi-ai";
3392
+ import { streamSimple as piStreamSimple2, createAssistantMessageEventStream } from "@earendil-works/pi-ai";
3375
3393
  import { register as registerOpenAICompletions } from "@earendil-works/pi-ai/openai-completions";
3376
3394
 
3377
3395
  // src/routers/mux.ts
@@ -3579,8 +3597,8 @@ function artifactsDir() {
3579
3597
  // src/scribe/digest.ts
3580
3598
  var DIGEST_CAP = 8192;
3581
3599
  var TIMELINE_DAY_CAP = 400;
3582
- function read(file5) {
3583
- return existsSync8(file5) ? readFileSync12(file5, "utf8") : "";
3600
+ function read(file6) {
3601
+ return existsSync8(file6) ? readFileSync12(file6, "utf8") : "";
3584
3602
  }
3585
3603
  function updateDigest(summary, context) {
3586
3604
  mkdirSync10(scribeDir(), { recursive: true });
@@ -4118,7 +4136,54 @@ function attachScribe(session) {
4118
4136
  });
4119
4137
  }
4120
4138
 
4121
- // src/routers/mux-provider.ts
4139
+ // src/context/project-md.ts
4140
+ import { existsSync as existsSync13, readFileSync as readFileSync18, statSync as statSync2 } from "fs";
4141
+ import { join as join21, dirname as dirname3, parse } from "path";
4142
+ var NAMES = ["AGENTS.md", "CLAUDE.md", ".oriro/ORIRO.md"];
4143
+ var MAX_BYTES = 32 * 1024;
4144
+ var MAX_LEVELS = 24;
4145
+ function isRoot(dir) {
4146
+ return existsSync13(join21(dir, ".git")) || existsSync13(join21(dir, ".oriro"));
4147
+ }
4148
+ function discoverProjectInstructions(cwd) {
4149
+ const chain = [];
4150
+ let dir = cwd;
4151
+ const rootOfDrive = parse(cwd).root;
4152
+ for (let i = 0; i < MAX_LEVELS; i++) {
4153
+ for (const name of NAMES) {
4154
+ const p = join21(dir, name);
4155
+ try {
4156
+ if (existsSync13(p) && statSync2(p).isFile()) {
4157
+ let text = readFileSync18(p, "utf8");
4158
+ if (text.length > MAX_BYTES) text = text.slice(0, MAX_BYTES) + "\n\u2026(truncated)";
4159
+ text = text.trim();
4160
+ if (text) chain.push({ path: p, text });
4161
+ break;
4162
+ }
4163
+ } catch {
4164
+ }
4165
+ }
4166
+ if (isRoot(dir)) break;
4167
+ const parent = dirname3(dir);
4168
+ if (parent === dir || dir === rootOfDrive) break;
4169
+ dir = parent;
4170
+ }
4171
+ return chain.reverse();
4172
+ }
4173
+ function buildProjectContext(cwd = process.cwd()) {
4174
+ let found;
4175
+ try {
4176
+ found = discoverProjectInstructions(cwd);
4177
+ } catch {
4178
+ return "";
4179
+ }
4180
+ if (!found.length) return "";
4181
+ const blocks = found.map((f) => `# Project instructions \u2014 ${f.path}
4182
+ ${f.text}`);
4183
+ return "The user's project ships these instructions. Treat them as authoritative for work in this repository; when two files conflict, the one listed LAST (nearest the working directory) wins.\n\n" + blocks.join("\n\n");
4184
+ }
4185
+
4186
+ // src/routers/mux-helpers.ts
4122
4187
  var MUX_PROVIDER = "oriro-mux";
4123
4188
  var MUX_MODEL = "oriro-free";
4124
4189
  function errToCallError(msg) {
@@ -4138,6 +4203,145 @@ function buildErrorMessage(message) {
4138
4203
  errorMessage: message
4139
4204
  };
4140
4205
  }
4206
+
4207
+ // src/routers/race.ts
4208
+ import { streamSimple as piStreamSimple } from "@earendil-works/pi-ai";
4209
+
4210
+ // src/routers/race-status.ts
4211
+ var listeners = /* @__PURE__ */ new Set();
4212
+ var current = { phase: "idle", racers: [], winner: null };
4213
+ function emitRaceStatus(s) {
4214
+ current = s;
4215
+ for (const l of listeners) {
4216
+ try {
4217
+ l(s);
4218
+ } catch {
4219
+ }
4220
+ }
4221
+ }
4222
+ function onRaceStatus(l) {
4223
+ listeners.add(l);
4224
+ try {
4225
+ l(current);
4226
+ } catch {
4227
+ }
4228
+ return () => {
4229
+ listeners.delete(l);
4230
+ };
4231
+ }
4232
+ function getRaceStatus() {
4233
+ return current;
4234
+ }
4235
+
4236
+ // src/routers/race.ts
4237
+ var DEFAULT_RACE_WIDTH = 3;
4238
+ var realStreamFactory = (router, context, options, signal) => piStreamSimple(routerModel(router), context, {
4239
+ ...options ?? {},
4240
+ apiKey: router.apiKey,
4241
+ signal
4242
+ });
4243
+ async function raceMux(out, mux, byId, context, options, opts = {}) {
4244
+ const width = opts.width ?? DEFAULT_RACE_WIDTH;
4245
+ const streamFactory = opts.streamFactory ?? realStreamFactory;
4246
+ const push = (ev) => out.push(ev);
4247
+ const ranked = mux.ranked().filter((id) => byId.has(id));
4248
+ if (ranked.length === 0) {
4249
+ const msg = buildErrorMessage("All selected routers are unavailable. Add a BYOK key, select more free routers, or retry shortly.");
4250
+ push({ type: "error", reason: "error", error: msg });
4251
+ out.end(msg);
4252
+ emitRaceStatus({ phase: "failed", racers: [], winner: null });
4253
+ return;
4254
+ }
4255
+ const racers = ranked.slice(0, Math.max(1, Math.min(width, ranked.length)));
4256
+ emitRaceStatus({ phase: "racing", racers, winner: null });
4257
+ const controllers = /* @__PURE__ */ new Map();
4258
+ for (const id of racers) controllers.set(id, new AbortController());
4259
+ const abortLosers = (keep) => {
4260
+ for (const [id, c] of controllers) if (id !== keep) {
4261
+ try {
4262
+ c.abort();
4263
+ } catch {
4264
+ }
4265
+ }
4266
+ };
4267
+ let winner = null;
4268
+ let settled2 = false;
4269
+ let lastError;
4270
+ let remaining = racers.length;
4271
+ return await new Promise((resolve3) => {
4272
+ const failAll = () => {
4273
+ if (settled2) return;
4274
+ settled2 = true;
4275
+ const msg = lastError ?? buildErrorMessage("All racers failed this request.");
4276
+ push({ type: "error", reason: "error", error: msg });
4277
+ out.end(msg);
4278
+ emitRaceStatus({ phase: "failed", racers, winner: null });
4279
+ resolve3();
4280
+ };
4281
+ for (const id of racers) {
4282
+ const router = byId.get(id);
4283
+ const ctrl = controllers.get(id);
4284
+ const t0 = Date.now();
4285
+ void (async () => {
4286
+ let iAmWinner = false;
4287
+ let lastPartial;
4288
+ try {
4289
+ for await (const ev of streamFactory(router, context, options, ctrl.signal)) {
4290
+ if (settled2 && !iAmWinner) return;
4291
+ if (ev.type === "error") {
4292
+ mux.recordFailure(id, ev.error ? errToCallError(ev.error) : {});
4293
+ if (iAmWinner && !settled2) {
4294
+ settled2 = true;
4295
+ push(ev);
4296
+ out.end(ev.error);
4297
+ resolve3();
4298
+ return;
4299
+ }
4300
+ lastError = ev.error ?? lastError;
4301
+ return;
4302
+ }
4303
+ if (!iAmWinner) {
4304
+ if (winner !== null || settled2) return;
4305
+ winner = id;
4306
+ iAmWinner = true;
4307
+ mux.recordSuccess(id, Date.now() - t0);
4308
+ emitRaceStatus({ phase: "won", racers, winner: id });
4309
+ abortLosers(id);
4310
+ }
4311
+ if (ev.type === "done") {
4312
+ if (!settled2) {
4313
+ settled2 = true;
4314
+ const clean = sanitizeMessageToolCalls(scrubMessageIdentity(ev.message));
4315
+ push({ type: "done", reason: ev.reason, message: clean });
4316
+ out.end(clean);
4317
+ resolve3();
4318
+ }
4319
+ return;
4320
+ }
4321
+ lastPartial = ev.partial ?? lastPartial;
4322
+ push(sanitizeEventToolCalls(ev));
4323
+ }
4324
+ if (iAmWinner && !settled2) {
4325
+ settled2 = true;
4326
+ out.end(lastPartial ? sanitizeMessageToolCalls(scrubMessageIdentity(lastPartial)) : void 0);
4327
+ resolve3();
4328
+ } else if (!iAmWinner) {
4329
+ mux.recordFailure(id, {});
4330
+ }
4331
+ } catch (e) {
4332
+ if (e?.name === "AbortError") return;
4333
+ mux.recordFailure(id, e);
4334
+ if (!iAmWinner) lastError ??= buildErrorMessage(e instanceof Error ? e.message : String(e));
4335
+ } finally {
4336
+ remaining -= 1;
4337
+ if (remaining === 0 && !settled2) failAll();
4338
+ }
4339
+ })();
4340
+ }
4341
+ });
4342
+ }
4343
+
4344
+ // src/routers/mux-provider.ts
4141
4345
  async function driveMux(out, mux, byId, context, options) {
4142
4346
  let lastError;
4143
4347
  for (const id of mux.ranked()) {
@@ -4147,7 +4351,7 @@ async function driveMux(out, mux, byId, context, options) {
4147
4351
  let committed = false;
4148
4352
  let lastPartial;
4149
4353
  try {
4150
- const inner = piStreamSimple(routerModel(router), context, {
4354
+ const inner = piStreamSimple2(routerModel(router), context, {
4151
4355
  ...options ?? {},
4152
4356
  apiKey: router.apiKey
4153
4357
  });
@@ -4196,13 +4400,16 @@ async function driveMux(out, mux, byId, context, options) {
4196
4400
  }
4197
4401
  function registerOriroMux(registry, opts = {}) {
4198
4402
  registerOpenAICompletions();
4199
- const pooled = resolvePool();
4200
- const routers = opts.routers ?? (pooled.length > 0 ? pooled : KEYLESS_FLOOR);
4201
- const byId = new Map(routers.map((r) => [r.id, r]));
4202
- const mux = new RouterMux(routers.map((r) => r.id));
4203
- try {
4204
- mux.load(loadMuxState(oriroDir()));
4205
- } catch {
4403
+ function resolveNow() {
4404
+ const pooled = resolvePool();
4405
+ const routers = opts.routers ?? (pooled.length > 0 ? pooled : KEYLESS_FLOOR);
4406
+ const byId = new Map(routers.map((r) => [r.id, r]));
4407
+ const mux = new RouterMux(routers.map((r) => r.id));
4408
+ try {
4409
+ mux.load(loadMuxState(oriroDir()));
4410
+ } catch {
4411
+ }
4412
+ return { routers, byId, mux };
4206
4413
  }
4207
4414
  registry.registerProvider(MUX_PROVIDER, {
4208
4415
  name: "ORIRO Free (keyless Mux)",
@@ -4226,12 +4433,16 @@ function registerOriroMux(registry, opts = {}) {
4226
4433
  ],
4227
4434
  streamSimple: (_model, context, options) => {
4228
4435
  const out = createAssistantMessageEventStream();
4436
+ const { routers, byId, mux } = resolveNow();
4229
4437
  const ctx = applyIdentity(context);
4438
+ const project = buildProjectContext();
4230
4439
  const memory = buildScribeContext();
4231
- const withMemory = memory ? { ...ctx, systemPrompt: `${ctx.systemPrompt}
4440
+ const extra = [project, memory].filter(Boolean).join("\n\n");
4441
+ const withMemory = extra ? { ...ctx, systemPrompt: `${ctx.systemPrompt}
4232
4442
 
4233
- ${memory}` } : ctx;
4234
- void driveMux(out, mux, byId, withMemory, options).finally(() => {
4443
+ ${extra}` } : ctx;
4444
+ const drive = routers.length > 1 ? raceMux(out, mux, byId, withMemory, options) : driveMux(out, mux, byId, withMemory, options);
4445
+ void drive.finally(() => {
4235
4446
  try {
4236
4447
  saveMuxState(oriroDir(), mux.snapshot());
4237
4448
  } catch {
@@ -4554,7 +4765,7 @@ async function comparePages(opts) {
4554
4765
 
4555
4766
  // src/head/run.ts
4556
4767
  import { writeFile } from "fs/promises";
4557
- import { join as join21 } from "path";
4768
+ import { join as join22 } from "path";
4558
4769
 
4559
4770
  // src/head/inspection-html.ts
4560
4771
  var PRIORITY_COLOR = {
@@ -5056,7 +5267,7 @@ async function runInspect(target, competitors, opts = {}) {
5056
5267
  const report = await comparePages({ targetUrl: target, competitorUrls: competitors.length ? competitors : [target] });
5057
5268
  const files = [];
5058
5269
  if (opts.html) {
5059
- const path = join21(opts.outDir ?? process.cwd(), `oriro-head-${hostSlug(target)}-inspect.html`);
5270
+ const path = join22(opts.outDir ?? process.cwd(), `oriro-head-${hostSlug(target)}-inspect.html`);
5060
5271
  await writeFile(path, buildInspectionHtml(report), "utf8");
5061
5272
  files.push(path);
5062
5273
  }
@@ -5072,7 +5283,7 @@ function parseHeadTargets(text, selfOrigin) {
5072
5283
  async function runUrlToCode(url, opts = {}) {
5073
5284
  try {
5074
5285
  const res = await urlToCode(url, headModels(), { goal: opts.goal, stack: opts.stack });
5075
- const codePath = join21(opts.outDir ?? process.cwd(), `oriro-head-${hostSlug(url)}${extForStack(opts.stack)}`);
5286
+ const codePath = join22(opts.outDir ?? process.cwd(), `oriro-head-${hostSlug(url)}${extForStack(opts.stack)}`);
5076
5287
  await writeFile(codePath, res.code, "utf8");
5077
5288
  return { summary: `Reverse-engineered ${url} into clean code (${res.code.length} chars) \u2192 ${codePath}`, files: [codePath] };
5078
5289
  } catch (e) {
@@ -5082,7 +5293,7 @@ async function runUrlToCode(url, opts = {}) {
5082
5293
  async function runUrlToSpec(url, opts = {}) {
5083
5294
  try {
5084
5295
  const res = await urlToSpec(url, headModels(), { goal: opts.goal });
5085
- const specPath = join21(opts.outDir ?? process.cwd(), `oriro-head-${hostSlug(url)}.spec.yaml`);
5296
+ const specPath = join22(opts.outDir ?? process.cwd(), `oriro-head-${hostSlug(url)}.spec.yaml`);
5086
5297
  await writeFile(specPath, res.spec, "utf8");
5087
5298
  return { summary: `Reverse-engineered ${url} into a YAML build spec \u2192 ${specPath}`, files: [specPath] };
5088
5299
  } catch (e) {
@@ -5094,7 +5305,7 @@ async function runCapture(urls, opts = {}) {
5094
5305
  const { captureScreens: captureScreens2, buildScreenshotFlowHtml: buildScreenshotFlowHtml2 } = await Promise.resolve().then(() => (init_screenshot_flow(), screenshot_flow_exports));
5095
5306
  const caps = await captureScreens2(urls, { video: opts.video });
5096
5307
  const html = buildScreenshotFlowHtml2([{ name: "Captured screens", captures: caps }]);
5097
- const flowPath = join21(opts.outDir ?? process.cwd(), "oriro-head-flow.html");
5308
+ const flowPath = join22(opts.outDir ?? process.cwd(), "oriro-head-flow.html");
5098
5309
  await writeFile(flowPath, html, "utf8");
5099
5310
  const ok2 = caps.filter((c) => c.ok).length;
5100
5311
  return { summary: `Captured ${ok2}/${caps.length} full-page screenshots \u2192 ${flowPath}`, files: [flowPath] };
@@ -5115,7 +5326,7 @@ async function runVideoToCode(videoPath, opts = {}) {
5115
5326
  { videoPath, frames, mimeType: mime, goal: opts.goal, stack: opts.stack },
5116
5327
  headVideoModels()
5117
5328
  );
5118
- const codePath = join21(opts.outDir ?? process.cwd(), `oriro-head-video${extForStack(opts.stack)}`);
5329
+ const codePath = join22(opts.outDir ?? process.cwd(), `oriro-head-video${extForStack(opts.stack)}`);
5119
5330
  await writeFile(codePath, res.code, "utf8");
5120
5331
  return { summary: `Watched ${videoPath} \u2192 built code (${res.code.length} chars) \u2192 ${codePath}
5121
5332
  (experimental on the free floor \u2014 add a vision-capable router for pixel-faithful results.)`, files: [codePath] };
@@ -5293,21 +5504,428 @@ function registerOrchestrator(pi) {
5293
5504
  });
5294
5505
  }
5295
5506
 
5507
+ // src/agents/pi-tool.ts
5508
+ import { Type as Type4 } from "typebox";
5509
+
5510
+ // src/agents/store.ts
5511
+ import { mkdirSync as mkdirSync15, readFileSync as readFileSync19, writeFileSync as writeFileSync16, readdirSync as readdirSync2, rmSync as rmSync3, existsSync as existsSync14 } from "fs";
5512
+ import { join as join23 } from "path";
5513
+ var SLUG = /^[a-z0-9][a-z0-9-]{0,63}$/;
5514
+ function isValidAgentName(name) {
5515
+ return SLUG.test(name);
5516
+ }
5517
+ function agentsDir() {
5518
+ return join23(oriroDir(), "agents");
5519
+ }
5520
+ function agentFile(name) {
5521
+ return join23(agentsDir(), `${name}.json`);
5522
+ }
5523
+ function stateFile() {
5524
+ return join23(agentsDir(), ".state.json");
5525
+ }
5526
+ function listAgents() {
5527
+ const dir = agentsDir();
5528
+ if (!existsSync14(dir)) return [];
5529
+ const out = [];
5530
+ for (const f of readdirSync2(dir)) {
5531
+ if (!f.endsWith(".json") || f.startsWith(".")) continue;
5532
+ try {
5533
+ const def = JSON.parse(readFileSync19(join23(dir, f), "utf8"));
5534
+ if (def && typeof def.name === "string" && typeof def.task === "string") out.push(def);
5535
+ } catch {
5536
+ }
5537
+ }
5538
+ return out.sort((a, b) => a.name.localeCompare(b.name));
5539
+ }
5540
+ function loadAgent(name) {
5541
+ try {
5542
+ return JSON.parse(readFileSync19(agentFile(name), "utf8"));
5543
+ } catch {
5544
+ return void 0;
5545
+ }
5546
+ }
5547
+ function saveAgent(def) {
5548
+ if (!isValidAgentName(def.name)) {
5549
+ throw new Error(`invalid agent name '${def.name}' \u2014 use lowercase letters, digits and hyphens`);
5550
+ }
5551
+ mkdirSync15(agentsDir(), { recursive: true });
5552
+ writeFileSync16(agentFile(def.name), JSON.stringify(def, null, 2), "utf8");
5553
+ }
5554
+ function removeAgent(name) {
5555
+ const file6 = agentFile(name);
5556
+ if (!existsSync14(file6)) return false;
5557
+ rmSync3(file6, { force: true });
5558
+ const state = loadState();
5559
+ if (state[name]) {
5560
+ delete state[name];
5561
+ saveState(state);
5562
+ }
5563
+ return true;
5564
+ }
5565
+ function loadState() {
5566
+ try {
5567
+ return JSON.parse(readFileSync19(stateFile(), "utf8"));
5568
+ } catch {
5569
+ return {};
5570
+ }
5571
+ }
5572
+ function saveState(state) {
5573
+ mkdirSync15(agentsDir(), { recursive: true });
5574
+ writeFileSync16(stateFile(), JSON.stringify(state, null, 2), "utf8");
5575
+ }
5576
+ function markRun(name, ok2, at) {
5577
+ const state = loadState();
5578
+ state[name] = { lastRunAt: at, lastOk: ok2 };
5579
+ saveState(state);
5580
+ }
5581
+ function parseScheduleMs(spec) {
5582
+ if (!spec) return void 0;
5583
+ const s = spec.trim().toLowerCase();
5584
+ if (s === "hourly") return 36e5;
5585
+ if (s === "daily") return 864e5;
5586
+ const m = /^(\d+)\s*(m|h|d)$/.exec(s);
5587
+ if (!m) return void 0;
5588
+ const n = Number(m[1]);
5589
+ if (n <= 0) return void 0;
5590
+ const mult = m[2] === "m" ? 6e4 : m[2] === "h" ? 36e5 : 864e5;
5591
+ return n * mult;
5592
+ }
5593
+ function isDue(def, state, now) {
5594
+ const ms = parseScheduleMs(def.schedule);
5595
+ if (ms === void 0) return false;
5596
+ const last = state[def.name]?.lastRunAt ?? 0;
5597
+ return now - last >= ms;
5598
+ }
5599
+
5600
+ // src/agents/run.ts
5601
+ var DEFAULT_TIMEOUT_MS = 3e5;
5602
+ function runTimeoutMs() {
5603
+ const v = Number(process.env.ORIRO_AGENT_TIMEOUT_MS);
5604
+ return Number.isFinite(v) && v > 0 ? v : DEFAULT_TIMEOUT_MS;
5605
+ }
5606
+ function resolveBoundRouter(id) {
5607
+ return registeredRouters().find((r) => r.id === id);
5608
+ }
5609
+ async function runAgent2(def, opts = {}) {
5610
+ const bound = def.router ? resolveBoundRouter(def.router) : void 0;
5611
+ const routers = bound ? [bound] : void 0;
5612
+ const cwd = opts.cwd ?? def.cwd ?? process.cwd();
5613
+ let session;
5614
+ try {
5615
+ ({ session } = await assembleOriroSession({ cwd, ...routers ? { routers } : {} }));
5616
+ } catch (e) {
5617
+ return { ok: false, output: e instanceof Error ? e.message : String(e) };
5618
+ }
5619
+ let out = "";
5620
+ const unsub = session.subscribe(
5621
+ (e) => {
5622
+ if (e.type === "message_update" && e.assistantMessageEvent?.type === "text_delta") {
5623
+ out += e.assistantMessageEvent.delta ?? "";
5624
+ }
5625
+ }
5626
+ );
5627
+ const prompt = opts.input ? `${def.task}
5628
+
5629
+ Input:
5630
+ ${opts.input}` : def.task;
5631
+ const prevDepth = process.env.ORIRO_AGENT_DEPTH;
5632
+ process.env.ORIRO_AGENT_DEPTH = String((Number(prevDepth) || 0) + 1);
5633
+ let timer;
5634
+ try {
5635
+ const timedOut = await Promise.race([
5636
+ session.prompt(prompt).then(() => false),
5637
+ new Promise((res) => {
5638
+ timer = setTimeout(() => res(true), runTimeoutMs());
5639
+ })
5640
+ ]);
5641
+ if (timedOut) {
5642
+ const partial = scrubOutput(out).trim();
5643
+ return { ok: false, output: partial || `agent timed out after ${Math.round(runTimeoutMs() / 1e3)}s` };
5644
+ }
5645
+ } catch (e) {
5646
+ return { ok: false, output: e instanceof Error ? e.message : String(e) };
5647
+ } finally {
5648
+ if (timer) clearTimeout(timer);
5649
+ unsub();
5650
+ try {
5651
+ session.dispose();
5652
+ } catch {
5653
+ }
5654
+ if (prevDepth === void 0) delete process.env.ORIRO_AGENT_DEPTH;
5655
+ else process.env.ORIRO_AGENT_DEPTH = prevDepth;
5656
+ }
5657
+ const cleaned = scrubOutput(out).trim();
5658
+ return { ok: cleaned.length > 0, output: cleaned };
5659
+ }
5660
+
5661
+ // src/agents/pi-tool.ts
5662
+ function registerAgentRunner(pi) {
5663
+ pi.registerTool({
5664
+ name: "run_saved_agent",
5665
+ label: "ORIRO Agent",
5666
+ description: "Run one of the user's SAVED automation agents by name (list them first if unsure). Each agent is a stored workflow that runs on its own router with full tools behind Guardian. Optionally pass `input` to feed the agent. Use this when the user asks to run/trigger a named agent.",
5667
+ parameters: Type4.Object({
5668
+ name: Type4.String({ description: "the saved agent's name" }),
5669
+ input: Type4.Optional(Type4.String({ description: "optional input to pass to the agent" }))
5670
+ }),
5671
+ async execute(_id, params) {
5672
+ if (process.env.ORIRO_AGENT_DEPTH) {
5673
+ return { content: [{ type: "text", text: "Nested agent runs are disabled." }], details: { ok: false } };
5674
+ }
5675
+ const def = loadAgent(params.name);
5676
+ if (!def) {
5677
+ const names = listAgents().map((a) => a.name);
5678
+ const hint = names.length ? ` Saved agents: ${names.join(", ")}.` : " No agents saved yet.";
5679
+ return { content: [{ type: "text", text: `No agent named '${params.name}'.${hint}` }], details: { ok: false } };
5680
+ }
5681
+ const result = await runAgent2(def, params.input ? { input: params.input } : {});
5682
+ markRun(def.name, result.ok, Date.now());
5683
+ const status = result.ok ? "\u2713" : "\u2717";
5684
+ return {
5685
+ content: [{ type: "text", text: `[${def.name}] ${status}
5686
+ ${result.output.slice(0, 4e3)}` }],
5687
+ details: { ok: result.ok }
5688
+ };
5689
+ }
5690
+ });
5691
+ }
5692
+
5693
+ // src/connectors/mcp-client.ts
5694
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
5695
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
5696
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5697
+ var DISALLOWED_ENV = /* @__PURE__ */ new Set([
5698
+ "PATH",
5699
+ "LD_PRELOAD",
5700
+ "LD_LIBRARY_PATH",
5701
+ "DYLD_INSERT_LIBRARIES",
5702
+ "DYLD_LIBRARY_PATH",
5703
+ "NODE_OPTIONS",
5704
+ "PYTHONPATH",
5705
+ "PYTHONSTARTUP",
5706
+ "PERL5LIB",
5707
+ "RUBYOPT",
5708
+ "GEM_PATH",
5709
+ "APPINIT_DLLS",
5710
+ "COR_PROFILER",
5711
+ "BASH_ENV",
5712
+ "ENV",
5713
+ "IFS"
5714
+ ]);
5715
+ var HANDSHAKE_TIMEOUT_MS = 8e3;
5716
+ var CALL_TIMEOUT_MS = 3e4;
5717
+ function sanitizeName(name) {
5718
+ return (name || "").toLowerCase().replace(/[^a-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 64) || "x";
5719
+ }
5720
+ function assertSafeUrl(raw, allowLocal = false) {
5721
+ const u = new URL(raw);
5722
+ if (u.protocol !== "https:" && u.protocol !== "http:") throw new Error(`unsupported scheme: ${u.protocol}`);
5723
+ const host = u.hostname.toLowerCase();
5724
+ const isLoopback = host === "localhost" || host === "127.0.0.1" || host === "::1" || host.endsWith(".localhost");
5725
+ const isPrivate = /^10\./.test(host) || /^192\.168\./.test(host) || /^172\.(1[6-9]|2\d|3[01])\./.test(host) || /^169\.254\./.test(host) || /^fe80:/i.test(host) || /^f[cd][0-9a-f]{2}:/i.test(host) || host === "169.254.169.254" || host === "metadata.google.internal";
5726
+ if ((isLoopback || isPrivate) && !allowLocal) {
5727
+ throw new Error(`blocked SSRF target ${host} (use --allow-local for loopback/LAN MCP servers)`);
5728
+ }
5729
+ if (u.protocol === "http:" && !isLoopback && !allowLocal) throw new Error(`refusing plaintext http to ${host} \u2014 use https`);
5730
+ return u;
5731
+ }
5732
+ function safeEnv(env) {
5733
+ const out = {};
5734
+ for (const [k, v] of Object.entries(env ?? {})) {
5735
+ if (DISALLOWED_ENV.has(k.toUpperCase())) continue;
5736
+ out[k] = v;
5737
+ }
5738
+ return out;
5739
+ }
5740
+ async function connectServer(name, config, opts = {}) {
5741
+ const client = new Client({ name: "oriro-cli", version: "0.1.0" }, { capabilities: {} });
5742
+ let transport;
5743
+ let stderr = "";
5744
+ if (config.type === "stdio") {
5745
+ const t = new StdioClientTransport({
5746
+ command: config.command,
5747
+ args: config.args ?? [],
5748
+ env: safeEnv(config.env),
5749
+ stderr: "pipe"
5750
+ });
5751
+ t.stderr?.on("data", (b) => {
5752
+ stderr += b.toString();
5753
+ });
5754
+ transport = t;
5755
+ } else {
5756
+ const url = assertSafeUrl(config.url, opts.allowLocal);
5757
+ transport = new StreamableHTTPClientTransport(url, {
5758
+ requestInit: { headers: { "User-Agent": "oriro-cli/0.1.0", ...config.headers ?? {} } }
5759
+ });
5760
+ }
5761
+ const timeoutMs = opts.timeoutMs ?? HANDSHAKE_TIMEOUT_MS;
5762
+ let timer;
5763
+ try {
5764
+ await Promise.race([
5765
+ client.connect(transport),
5766
+ new Promise((_, rej) => {
5767
+ timer = setTimeout(() => rej(new Error("handshake timed out")), timeoutMs);
5768
+ })
5769
+ ]);
5770
+ } catch (e) {
5771
+ const detail = stderr.trim() ? `
5772
+ server stderr:
5773
+ ${stderr.trim().slice(0, 800)}` : "";
5774
+ try {
5775
+ await transport.close();
5776
+ } catch {
5777
+ }
5778
+ throw new Error(`MCP connect failed (${name}): ${e instanceof Error ? e.message : String(e)}${detail}`);
5779
+ } finally {
5780
+ if (timer) clearTimeout(timer);
5781
+ }
5782
+ return {
5783
+ name,
5784
+ client,
5785
+ dispose: async () => {
5786
+ try {
5787
+ await client.close();
5788
+ } catch {
5789
+ }
5790
+ }
5791
+ };
5792
+ }
5793
+ async function listAllTools(client) {
5794
+ const tools = [];
5795
+ let cursor;
5796
+ do {
5797
+ const res = await client.listTools(cursor ? { cursor } : void 0, { timeout: CALL_TIMEOUT_MS });
5798
+ for (const t of res.tools) tools.push({ name: t.name, description: t.description, inputSchema: t.inputSchema });
5799
+ cursor = res.nextCursor;
5800
+ } while (cursor);
5801
+ return tools;
5802
+ }
5803
+
5804
+ // src/connectors/register.ts
5805
+ import { Type as Type5 } from "typebox";
5806
+ function registerToolList(pi, serverName, client, tools, seen = /* @__PURE__ */ new Set()) {
5807
+ const server = sanitizeName(serverName);
5808
+ const registered = [];
5809
+ for (const t of tools) {
5810
+ const publicName = `mcp__${server}__${sanitizeName(t.name)}`;
5811
+ if (seen.has(publicName)) continue;
5812
+ seen.add(publicName);
5813
+ const realName = t.name;
5814
+ pi.registerTool({
5815
+ name: publicName,
5816
+ label: `MCP: ${serverName}`,
5817
+ description: (t.description ?? `${t.name} (via ${serverName})`).slice(0, 1024),
5818
+ parameters: Type5.Object({}, { additionalProperties: true }),
5819
+ async execute(_id, params) {
5820
+ const details = { server: serverName, tool: realName };
5821
+ try {
5822
+ const res = await client.callTool(
5823
+ { name: realName, arguments: params ?? {} },
5824
+ void 0,
5825
+ { timeout: CALL_TIMEOUT_MS }
5826
+ );
5827
+ const text = (res.content ?? []).filter((c) => c.type === "text" && typeof c.text === "string").map((c) => c.text).join("\n");
5828
+ if (res.isError) {
5829
+ details.isError = true;
5830
+ return { content: [{ type: "text", text: `MCP tool error: ${text || "(no detail)"}` }], details };
5831
+ }
5832
+ return { content: [{ type: "text", text: text || "(no text content)" }], details };
5833
+ } catch (e) {
5834
+ details.isError = true;
5835
+ return { content: [{ type: "text", text: `MCP call failed: ${e instanceof Error ? e.message : String(e)}` }], details };
5836
+ }
5837
+ }
5838
+ });
5839
+ registered.push(publicName);
5840
+ }
5841
+ return registered;
5842
+ }
5843
+
5844
+ // src/connectors/custom.ts
5845
+ import { readFileSync as readFileSync20, writeFileSync as writeFileSync17 } from "fs";
5846
+ import { join as join24 } from "path";
5847
+ function file3() {
5848
+ return join24(oriroDir(), "mcp-custom.json");
5849
+ }
5850
+ function readCustomServers() {
5851
+ try {
5852
+ const v = JSON.parse(readFileSync20(file3(), "utf8"));
5853
+ return Array.isArray(v) ? v : [];
5854
+ } catch {
5855
+ return [];
5856
+ }
5857
+ }
5858
+ function saveCustomServer(server) {
5859
+ const rest = readCustomServers().filter((s) => s.name.toLowerCase() !== server.name.toLowerCase());
5860
+ writeFileSync17(join24(ensureOriroDir(), "mcp-custom.json"), JSON.stringify([...rest, server], null, 2), "utf8");
5861
+ }
5862
+ function removeCustomServer(name) {
5863
+ const before = readCustomServers();
5864
+ const after = before.filter((s) => s.name.toLowerCase() !== name.toLowerCase());
5865
+ if (after.length === before.length) return false;
5866
+ writeFileSync17(join24(ensureOriroDir(), "mcp-custom.json"), JSON.stringify(after, null, 2), "utf8");
5867
+ return true;
5868
+ }
5869
+ function trustedServerNames() {
5870
+ return readCustomServers().filter((s) => s.trusted).map((s) => s.name);
5871
+ }
5872
+ function isServerTrusted(name) {
5873
+ return trustedServerNames().some((n) => n.toLowerCase() === name.toLowerCase());
5874
+ }
5875
+
5876
+ // src/connectors/session-connect.ts
5877
+ var CONNECT_TIMEOUT_MS = 8e3;
5878
+ async function prepareConnectors() {
5879
+ const targets = [];
5880
+ for (const c of addedConnectors()) {
5881
+ if (c.mcpUrl) targets.push({ name: c.slug, config: { type: "http", url: c.mcpUrl } });
5882
+ }
5883
+ for (const s of readCustomServers()) {
5884
+ if (s.trusted) targets.push({ name: s.name, config: s.config, allowLocal: true });
5885
+ }
5886
+ const out = [];
5887
+ for (const t of targets) {
5888
+ try {
5889
+ const conn = await connectServer(t.name, t.config, {
5890
+ timeoutMs: CONNECT_TIMEOUT_MS,
5891
+ ...t.allowLocal ? { allowLocal: true } : {}
5892
+ });
5893
+ const tools = await listAllTools(conn.client);
5894
+ out.push({ name: t.name, client: conn.client, tools });
5895
+ } catch {
5896
+ }
5897
+ }
5898
+ return out;
5899
+ }
5900
+ function registerPreparedConnectors(pi, prepared) {
5901
+ const seen = /* @__PURE__ */ new Set();
5902
+ for (const p of prepared) registerToolList(pi, p.name, p.client, p.tools, seen);
5903
+ }
5904
+
5296
5905
  // src/onboarding/assemble.ts
5297
5906
  async function assembleOriroSession(opts = {}) {
5298
5907
  const cwd = opts.cwd ?? process.cwd();
5299
5908
  const authStorage = AuthStorage2.inMemory();
5300
5909
  const modelRegistry = ModelRegistry2.inMemory(authStorage);
5301
5910
  const settingsManager = SettingsManager.create(cwd);
5302
- const model = registerOriroMux(modelRegistry);
5911
+ const model = registerOriroMux(modelRegistry, opts.routers ? { routers: opts.routers } : {});
5303
5912
  if (!model) throw new Error("ORIRO keyless model unavailable");
5913
+ const preparedConnectors = await prepareConnectors();
5304
5914
  const resourceLoader = new DefaultResourceLoader({
5305
5915
  cwd,
5306
5916
  agentDir: getAgentDir(),
5307
5917
  settingsManager,
5308
5918
  additionalSkillPaths: skillRoots(),
5309
5919
  // bundled library + the user's own ~/.oriro/skills
5310
- extensionFactories: [registerGuardian, registerHead, registerScribe, registerOrchestrator]
5920
+ extensionFactories: [
5921
+ registerGuardian,
5922
+ registerHead,
5923
+ registerScribe,
5924
+ registerOrchestrator,
5925
+ registerAgentRunner,
5926
+ (pi) => registerPreparedConnectors(pi, preparedConnectors)
5927
+ // MCP connectors → agent tools
5928
+ ]
5311
5929
  });
5312
5930
  await resourceLoader.reload();
5313
5931
  const { session, extensionsResult } = await createAgentSession2({
@@ -5496,14 +6114,14 @@ var MODE_META = {
5496
6114
  auto: { label: "Auto", indicator: "\u23F5\u23F5" },
5497
6115
  plan: { label: "Plan", indicator: "\u25A2" }
5498
6116
  };
5499
- var current = "manual";
6117
+ var current2 = "manual";
5500
6118
  function getMode() {
5501
- return current;
6119
+ return current2;
5502
6120
  }
5503
6121
  function cycleMode() {
5504
- const i = MODES.indexOf(current);
5505
- current = MODES[(i + 1) % MODES.length];
5506
- return current;
6122
+ const i = MODES.indexOf(current2);
6123
+ current2 = MODES[(i + 1) % MODES.length];
6124
+ return current2;
5507
6125
  }
5508
6126
  var thinking = false;
5509
6127
  function getThinking() {
@@ -5516,7 +6134,7 @@ function toggleThinking() {
5516
6134
  var THINKING_PRIMER = "Think step by step and plan your approach before acting. Reason carefully and check your work.";
5517
6135
 
5518
6136
  // src/repl-ui/verify-actions.ts
5519
- import { existsSync as existsSync13 } from "fs";
6137
+ import { existsSync as existsSync15 } from "fs";
5520
6138
  import { isAbsolute, resolve } from "path";
5521
6139
  var CLAIM = /\b(?:have|has)\s+been\s+created\b|\b(?:created|wrote|written|saved|generated)\b(?![ \t]*(?:by you|it yourself))/i;
5522
6140
  var SUGGESTION = /\byou\s+(?:can|could|should|may)\s+(?:create|add|save|make|put)\b/i;
@@ -5529,7 +6147,7 @@ function phantomFileWarning(reply, cwd = process.cwd()) {
5529
6147
  if (!p) continue;
5530
6148
  if (/^https?:|node_modules|<[^>]+>|your-|example\./i.test(p)) continue;
5531
6149
  const abs = isAbsolute(p) ? p : resolve(cwd, p.replace(/^[.][\\/]/, ""));
5532
- if (!existsSync13(abs)) missing.add(p);
6150
+ if (!existsSync15(abs)) missing.add(p);
5533
6151
  }
5534
6152
  if (missing.size === 0) return "";
5535
6153
  if (SUGGESTION.test(reply) && !/\b(?:have|has)\s+been\s+created\b/i.test(reply)) return "";
@@ -5539,30 +6157,236 @@ function phantomFileWarning(reply, cwd = process.cwd()) {
5539
6157
  \u26A0 ORIRO said it ${plural ? "created files" : "created a file"} (${list}), but ${plural ? "they're" : "it's"} not on disk \u2014 the free router may have described the write without actually running it. Retry, or add your own key with \`oriro routers\` for reliable coding.`;
5540
6158
  }
5541
6159
 
5542
- // src/repl-ui/tui-repl.ts
5543
- var editorTheme = {
5544
- borderColor: (s) => dim(s),
5545
- selectList: {
5546
- selectedPrefix: (s) => accent(s),
5547
- selectedText: (s) => accent(s),
5548
- description: (s) => dim(s),
5549
- scrollInfo: (s) => dim(s),
5550
- noMatch: (s) => dim(s)
6160
+ // src/repl-ui/slash-routers.ts
6161
+ function isRouterSlash(cmd) {
6162
+ return /^\/(routers?|model)(\s|$)/i.test(cmd.trim());
6163
+ }
6164
+ function poolLine() {
6165
+ const pool = resolvePool();
6166
+ return pool.length ? `${dim("racing now:")} ${accent(pool.map((p) => p.id).join(", "))}` : dim("racing now: (empty) \u2192 keyless floor");
6167
+ }
6168
+ function catalogLines(head) {
6169
+ const lines = [];
6170
+ lines.push(
6171
+ head === "/model" ? dim(" ORIRO models & free routers \u2014 they race, best answer wins:") : dim(" Router catalog \u2014 they race, best answer wins:")
6172
+ );
6173
+ for (const r of selectableRouters()) {
6174
+ const tier = r.keyless ? fgHex(PALETTE.success, "keyless") : dim(r.tier);
6175
+ lines.push(` ${accent(r.id.padEnd(20))} ${r.displayName.padEnd(22)} ${tier}`);
6176
+ }
6177
+ lines.push(` ${poolLine()}`);
6178
+ lines.push(dim(" add: /routers add <id> \xB7 rotate: /routers use <id> [<id>\u2026]"));
6179
+ return lines;
6180
+ }
6181
+ async function handleRouterSlash(raw) {
6182
+ const parts = raw.trim().split(/\s+/);
6183
+ const head = (parts[0] ?? "").toLowerCase();
6184
+ const sub = (parts[1] ?? "").toLowerCase();
6185
+ try {
6186
+ if (sub === "add") {
6187
+ const id = parts[2];
6188
+ if (!id) return [dim(" usage: /routers add <id> (e.g. /routers add oriro-gauss)")];
6189
+ const entry = routerById(id);
6190
+ if (!entry) return [dim(` unknown router '${id}' \u2014 try /routers list`)];
6191
+ const res = await addRouter(entry, {});
6192
+ if (res.ok) {
6193
+ return [
6194
+ ` ${fgHex(PALETTE.success, "\u2713")} added ${accent(id)} (${res.validation.latencyMs}ms, model ${res.validation.model}) \u2192 ${fgHex(PALETTE.success, "now racing")}`,
6195
+ ` ${poolLine()}`
6196
+ ];
6197
+ }
6198
+ return [dim(` \u2717 could not add ${id}: ${res.validation.error ?? "validation failed"}`)];
6199
+ }
6200
+ const rotate = sub === "use" ? parts.slice(2) : head === "/model" && parts[1] && sub !== "list" ? parts.slice(1) : null;
6201
+ if (rotate) {
6202
+ if (!rotate.length) return [dim(" usage: /routers use <id> [<id>\u2026]")];
6203
+ const { applied, unknown } = useRouters(rotate);
6204
+ const out = [];
6205
+ if (applied.length) out.push(` ${fgHex(PALETTE.success, "\u2713")} now racing: ${accent(applied.join(", "))}`);
6206
+ if (unknown.length) out.push(dim(` not registered yet (add first): ${unknown.join(", ")}`));
6207
+ return out.length ? out : [dim(" nothing applied \u2014 add a router first: /routers add <id>")];
6208
+ }
6209
+ return catalogLines(head);
6210
+ } catch (e) {
6211
+ return [dim(` router command failed: ${e instanceof Error ? e.message : String(e)}`)];
5551
6212
  }
5552
- };
5553
- function footerText() {
5554
- const cur = getMode();
5555
- const bar = MODES.map((m) => {
5556
- const meta = MODE_META[m];
5557
- const s = `${meta.indicator} ${meta.label}`;
5558
- return m === cur ? accent(s) : dim(s);
5559
- }).join(dim(" \xB7 "));
5560
- const think = getThinking() ? accent("\u{1F9E0} Thinking") : dim("\u{1F9E0} Thinking");
5561
- return `${bar} ${think} ${dim("Shift+Tab posture \xB7 Alt+Shift+T thinking \xB7 /exit")}`;
5562
6213
  }
5563
- async function runTuiRepl(session) {
5564
- const isEnglish3 = getTerminalLanguage().code.toLowerCase().startsWith("en");
5565
- const term = new ProcessTerminal();
6214
+
6215
+ // src/repl-ui/repl-state.ts
6216
+ var turns = 0;
6217
+ var trace = false;
6218
+ function bumpTurns() {
6219
+ turns += 1;
6220
+ }
6221
+ function getTurns() {
6222
+ return turns;
6223
+ }
6224
+ function getTrace() {
6225
+ return trace;
6226
+ }
6227
+ function toggleTrace() {
6228
+ trace = !trace;
6229
+ return trace;
6230
+ }
6231
+
6232
+ // src/repl-ui/slash-usage.ts
6233
+ function isUsageSlash(cmd) {
6234
+ return /^\/usage(\s|$)/i.test(cmd.trim());
6235
+ }
6236
+ function handleUsage() {
6237
+ const pool = resolvePool();
6238
+ const health = new Map(loadMuxState(oriroDir()).map((s) => [s.id, s]));
6239
+ const race = getRaceStatus();
6240
+ const lines = [];
6241
+ lines.push(dim(` turns this session: ${accent(String(getTurns()))} \xB7 thinking-trace: ${getTrace() ? fgHex(PALETTE.success, "on") : dim("off")}`));
6242
+ lines.push(dim(" racing pool (learned latency \xB7 health):"));
6243
+ if (!pool.length) {
6244
+ lines.push(dim(" (empty) \u2192 the keyless floor"));
6245
+ } else {
6246
+ const now = Date.now();
6247
+ for (const r of pool) {
6248
+ const s = health.get(r.id);
6249
+ const lat = s && Number.isFinite(s.latencyMs) ? `${Math.round(s.latencyMs)}ms` : "untried";
6250
+ const state = !s ? dim("new") : !s.healthy ? fgHex(PALETTE.error, "unhealthy") : s.cooldownUntil > now ? fgHex(PALETTE.error, "cooling") : fgHex(PALETTE.success, "healthy");
6251
+ lines.push(` ${accent(r.id.padEnd(20))} ${dim(lat.padEnd(9))} ${state}`);
6252
+ }
6253
+ }
6254
+ if (race.winner && race.racers.length > 1) {
6255
+ lines.push(dim(` last race: ${race.racers.join(" \xB7 ")} \u2192 won: `) + accent(race.winner));
6256
+ }
6257
+ return lines;
6258
+ }
6259
+
6260
+ // src/repl-ui/slash-artifacts.ts
6261
+ import { existsSync as existsSync16, writeFileSync as writeFileSync18 } from "fs";
6262
+
6263
+ // src/repl-ui/artifacts.ts
6264
+ var LANG_EXT = {
6265
+ python: "py",
6266
+ py: "py",
6267
+ javascript: "js",
6268
+ js: "js",
6269
+ typescript: "ts",
6270
+ ts: "ts",
6271
+ tsx: "tsx",
6272
+ jsx: "jsx",
6273
+ html: "html",
6274
+ css: "css",
6275
+ json: "json",
6276
+ yaml: "yaml",
6277
+ yml: "yml",
6278
+ bash: "sh",
6279
+ sh: "sh",
6280
+ shell: "sh",
6281
+ sql: "sql",
6282
+ go: "go",
6283
+ rust: "rs",
6284
+ rs: "rs",
6285
+ java: "java",
6286
+ c: "c",
6287
+ cpp: "cpp",
6288
+ "c++": "cpp",
6289
+ ruby: "rb",
6290
+ rb: "rb",
6291
+ php: "php",
6292
+ markdown: "md",
6293
+ md: "md",
6294
+ svg: "svg"
6295
+ };
6296
+ function extFor(lang) {
6297
+ return LANG_EXT[lang.toLowerCase()] ?? "txt";
6298
+ }
6299
+ function extractArtifacts(text) {
6300
+ const out = [];
6301
+ if (!text) return out;
6302
+ const fence = /```([\w+#.-]*)\n([\s\S]*?)```/g;
6303
+ let m;
6304
+ while ((m = fence.exec(text)) !== null) {
6305
+ const lang = (m[1] ?? "").trim();
6306
+ const content = (m[2] ?? "").replace(/\n$/, "");
6307
+ if (!content.trim()) continue;
6308
+ const isSvg = lang.toLowerCase() === "svg" || /^\s*<svg[\s>]/.test(content);
6309
+ out.push({
6310
+ kind: isSvg ? "svg" : "code",
6311
+ lang: lang || (isSvg ? "svg" : ""),
6312
+ content,
6313
+ suggestedName: `artifact-${out.length + 1}.${isSvg ? "svg" : extFor(lang)}`
6314
+ });
6315
+ }
6316
+ const svg = /<svg[\s>][\s\S]*?<\/svg>/gi;
6317
+ while ((m = svg.exec(text)) !== null) {
6318
+ const content = m[0];
6319
+ if (out.some((a) => a.content.includes(content))) continue;
6320
+ out.push({ kind: "svg", lang: "svg", content, suggestedName: `artifact-${out.length + 1}.svg` });
6321
+ }
6322
+ return out;
6323
+ }
6324
+ var current3 = [];
6325
+ function setArtifacts(a) {
6326
+ current3 = a;
6327
+ }
6328
+ function getArtifacts() {
6329
+ return current3;
6330
+ }
6331
+
6332
+ // src/repl-ui/slash-artifacts.ts
6333
+ function isArtifactSlash(cmd) {
6334
+ return /^\/(review|artifacts?|save)(\s|$)/i.test(cmd.trim());
6335
+ }
6336
+ function handleArtifactSlash(raw) {
6337
+ const parts = raw.trim().split(/\s+/);
6338
+ const head = (parts[0] ?? "").toLowerCase();
6339
+ const arts = getArtifacts();
6340
+ if (head === "/save") {
6341
+ const idx = parseInt(parts[1] ?? "", 10);
6342
+ if (!Number.isInteger(idx) || idx < 1 || idx > arts.length) {
6343
+ return [dim(" usage: /save <n> [path] \u2014 run /review to see the artifacts")];
6344
+ }
6345
+ const art = arts[idx - 1];
6346
+ if (!art) return [dim(" no such artifact")];
6347
+ const dest = parts[2] || art.suggestedName;
6348
+ if (existsSync16(dest)) return [dim(` \u2717 ${dest} already exists \u2014 give a different path: /save ${idx} <path>`)];
6349
+ try {
6350
+ writeFileSync18(dest, art.content, "utf8");
6351
+ } catch (e) {
6352
+ return [dim(` \u2717 could not write ${dest}: ${e instanceof Error ? e.message : String(e)}`)];
6353
+ }
6354
+ return [` ${fgHex(PALETTE.success, "\u2713")} saved artifact ${accent(String(idx))} \u2192 ${accent(dest)} ${dim(`(${art.content.length} bytes)`)}`];
6355
+ }
6356
+ if (!arts.length) return [dim(" no artifacts in the last reply \u2014 ask for code or an SVG, then /review")];
6357
+ const lines = [dim(" Artifacts from the last reply \u2014 save one with /save <n> [path]:")];
6358
+ arts.forEach((a, i) => {
6359
+ const nlines = a.content.split("\n").length;
6360
+ const preview = (a.content.split("\n")[0] ?? "").slice(0, 48).replace(/\s+/g, " ");
6361
+ lines.push(` ${accent(String(i + 1))}. ${a.kind}${a.lang ? `/${a.lang}` : ""} \xB7 ${nlines} lines \xB7 \u2192 ${dim(a.suggestedName)} ${dim(preview)}`);
6362
+ });
6363
+ return lines;
6364
+ }
6365
+
6366
+ // src/repl-ui/tui-repl.ts
6367
+ var editorTheme = {
6368
+ borderColor: (s) => dim(s),
6369
+ selectList: {
6370
+ selectedPrefix: (s) => accent(s),
6371
+ selectedText: (s) => accent(s),
6372
+ description: (s) => dim(s),
6373
+ scrollInfo: (s) => dim(s),
6374
+ noMatch: (s) => dim(s)
6375
+ }
6376
+ };
6377
+ function footerText() {
6378
+ const cur = getMode();
6379
+ const bar = MODES.map((m) => {
6380
+ const meta = MODE_META[m];
6381
+ const s = `${meta.indicator} ${meta.label}`;
6382
+ return m === cur ? accent(s) : dim(s);
6383
+ }).join(dim(" \xB7 "));
6384
+ const think = getThinking() ? accent("\u{1F9E0} Thinking") : dim("\u{1F9E0} Thinking");
6385
+ return `${bar} ${think} ${dim("Shift+Tab posture \xB7 Alt+Shift+T thinking \xB7 /exit")}`;
6386
+ }
6387
+ async function runTuiRepl(session) {
6388
+ const isEnglish3 = getTerminalLanguage().code.toLowerCase().startsWith("en");
6389
+ const term = new ProcessTerminal();
5566
6390
  const tui = new TUI(term, true);
5567
6391
  const chat = new Container();
5568
6392
  const editor = new Editor(tui, editorTheme, { paddingX: 1 });
@@ -5618,7 +6442,13 @@ async function runTuiRepl(session) {
5618
6442
  const slash = text.toLowerCase();
5619
6443
  if (slash === "/exit" || slash === "/quit") return cleanup();
5620
6444
  if (slash === "/help" || slash === "/?") {
5621
- chat.addChild(new Text(dim(" Just type to chat. Shift+Tab posture \xB7 Alt+Shift+T thinking \xB7 /voice to speak \xB7 /exit."), 0, 0));
6445
+ const help = [
6446
+ " Just type to chat \u2014 ORIRO writes and runs code for you (keyless, free).",
6447
+ ` ${accent("/routers")} pool add\xB7rotate ${accent("/model")} <id\u2026> switch ${accent("/usage")} health ${accent("/trace")} tool+router activity`,
6448
+ ` ${accent("/review")} artifacts from the last reply ${accent("/save")} <n> [path] ${accent("/skills")} ${accent("/connectors")} ${accent("/voice")}`,
6449
+ ` ${dim("Shift+Tab")} posture ${dim("Alt+Shift+T")} thinking ${accent("/help")} ${accent("/exit")}`
6450
+ ].join("\n");
6451
+ chat.addChild(new Text(help, 0, 0));
5622
6452
  editor.setText("");
5623
6453
  tui.requestRender();
5624
6454
  return;
@@ -5635,6 +6465,37 @@ async function runTuiRepl(session) {
5635
6465
  tui.requestRender();
5636
6466
  return;
5637
6467
  }
6468
+ if (isRouterSlash(slash)) {
6469
+ editor.setText("");
6470
+ const pending = new Text(dim(" \u2026"), 0, 0);
6471
+ chat.addChild(pending);
6472
+ tui.requestRender();
6473
+ void (async () => {
6474
+ const lines = await handleRouterSlash(text);
6475
+ pending.setText(lines.join("\n"));
6476
+ tui.requestRender();
6477
+ })();
6478
+ return;
6479
+ }
6480
+ if (isUsageSlash(slash)) {
6481
+ chat.addChild(new Text(handleUsage().join("\n"), 0, 0));
6482
+ editor.setText("");
6483
+ tui.requestRender();
6484
+ return;
6485
+ }
6486
+ if (slash === "/trace") {
6487
+ const on = toggleTrace();
6488
+ chat.addChild(new Text(dim(` trace ${on ? "ON \u2014 showing tool + router activity" : "off"}`), 0, 0));
6489
+ editor.setText("");
6490
+ tui.requestRender();
6491
+ return;
6492
+ }
6493
+ if (isArtifactSlash(slash)) {
6494
+ chat.addChild(new Text(handleArtifactSlash(text).join("\n"), 0, 0));
6495
+ editor.setText("");
6496
+ tui.requestRender();
6497
+ return;
6498
+ }
5638
6499
  if (slash === "/voice") {
5639
6500
  editor.setText("");
5640
6501
  const status = new Text(dim(" \u{1F399} listening\u2026 (needs ffmpeg + the transformers voice peer)"), 0, 0);
@@ -5655,10 +6516,23 @@ async function runTuiRepl(session) {
5655
6516
  editor.addToHistory(text);
5656
6517
  editor.setText("");
5657
6518
  chat.addChild(new Text(`${accent("\u203A")} ${text}`, 0, 1));
6519
+ const raceLine = new Text("", 0, 0);
6520
+ chat.addChild(raceLine);
5658
6521
  const streaming = new Text(dim("\u2026"), 0, 0);
5659
6522
  chat.addChild(streaming);
6523
+ const unsubRace = onRaceStatus((s) => {
6524
+ if (s.phase === "racing" && s.racers.length > 1) {
6525
+ raceLine.setText(dim(` \u23F1 racing: ${s.racers.join(" \xB7 ")}`));
6526
+ } else if (s.phase === "won" && s.winner && s.racers.length > 1) {
6527
+ raceLine.setText(dim(` \u23F1 ${s.racers.join(" \xB7 ")} \u2192 won: `) + accent(s.winner));
6528
+ } else {
6529
+ raceLine.setText("");
6530
+ }
6531
+ tui.requestRender();
6532
+ });
5660
6533
  tui.requestRender();
5661
6534
  busy = true;
6535
+ bumpTurns();
5662
6536
  void (async () => {
5663
6537
  let english = await translateIncoming(text);
5664
6538
  if (getThinking()) english = `${THINKING_PRIMER}
@@ -5674,6 +6548,9 @@ ${english}`;
5674
6548
  streaming.setText(out);
5675
6549
  tui.requestRender();
5676
6550
  }
6551
+ } else if (getTrace() && (e.type === "tool_start" || e.type === "tool_end" || e.type === "toolcall_start")) {
6552
+ chat.addChild(new Text(dim(` \u2699 ${e.type.replace("_", " ")}${e.toolName ? `: ${e.toolName}` : ""}`), 0, 0));
6553
+ tui.requestRender();
5677
6554
  }
5678
6555
  }
5679
6556
  );
@@ -5684,13 +6561,19 @@ ${english}`;
5684
6561
  tui.requestRender();
5685
6562
  busy = false;
5686
6563
  unsub();
6564
+ unsubRace();
5687
6565
  return;
5688
6566
  }
5689
6567
  unsub();
6568
+ unsubRace();
5690
6569
  const cleaned = scrubOutput(out);
5691
6570
  const finalText = isEnglish3 ? cleaned.trim() : await translateOutgoing(cleaned.trim());
5692
6571
  const warn = phantomFileWarning(finalText);
5693
- streaming.setText((finalText || dim("(no response)")) + (warn ? dim(warn) : ""));
6572
+ const arts = extractArtifacts(finalText);
6573
+ setArtifacts(arts);
6574
+ const hint = arts.length ? dim(`
6575
+ \u2398 ${arts.length} artifact${arts.length === 1 ? "" : "s"} \u2014 /review to save`) : "";
6576
+ streaming.setText((finalText || dim("(no response)")) + (warn ? dim(warn) : "") + hint);
5694
6577
  tui.requestRender();
5695
6578
  busy = false;
5696
6579
  })();
@@ -5704,8 +6587,8 @@ ${english}`;
5704
6587
  // src/voice/mic.ts
5705
6588
  import { spawn as spawn3 } from "child_process";
5706
6589
  import { tmpdir as tmpdir3 } from "os";
5707
- import { join as join22 } from "path";
5708
- import { existsSync as existsSync14, statSync as statSync2 } from "fs";
6590
+ import { join as join25 } from "path";
6591
+ import { existsSync as existsSync17, statSync as statSync3 } from "fs";
5709
6592
  function recorders(outFile, seconds) {
5710
6593
  const dur = String(seconds);
5711
6594
  if (process.platform === "darwin") {
@@ -5726,12 +6609,12 @@ function recorders(outFile, seconds) {
5726
6609
  ];
5727
6610
  }
5728
6611
  async function recordMic(seconds = 6) {
5729
- const outFile = join22(tmpdir3(), `oriro-voice-${process.pid}-${seconds}.wav`);
6612
+ const outFile = join25(tmpdir3(), `oriro-voice-${process.pid}-${seconds}.wav`);
5730
6613
  for (const r of recorders(outFile, seconds)) {
5731
6614
  const okFile = await new Promise((resolve3) => {
5732
6615
  const child = spawn3(r.cmd, r.args, { stdio: "ignore" });
5733
6616
  child.on("error", () => resolve3(false));
5734
- child.on("close", (code) => resolve3(code === 0 && existsSync14(outFile) && statSync2(outFile).size > 44));
6617
+ child.on("close", (code) => resolve3(code === 0 && existsSync17(outFile) && statSync3(outFile).size > 44));
5735
6618
  });
5736
6619
  if (okFile) return outFile;
5737
6620
  }
@@ -5795,9 +6678,13 @@ function replHelp() {
5795
6678
  ${accent("ORIRO terminal \u2014 help")}
5796
6679
  ${dim("Just type to chat; ORIRO writes and runs code for you (keyless, free).")}
5797
6680
 
5798
- ${accent("/help")} this help ${accent("/exit")} or ${accent("/quit")} leave ${dim("Ctrl-D / Ctrl-C also exit")}
5799
- ${dim("Run these OUTSIDE the chat (in your shell):")}
5800
- ${dim("oriro skills \xB7 routers \xB7 connectors \xB7 channels \xB7 scribe \xB7 language \xB7 avatar")}
6681
+ ${dim("Models & routers")} ${accent("/routers")} list\xB7add\xB7rotate the racing pool ${accent("/model")} <id\u2026> switch
6682
+ ${dim("This session")} ${accent("/usage")} pool health & turns ${accent("/trace")} show tool + router activity
6683
+ ${dim("Artifacts")} ${accent("/review")} code/SVG from the last reply ${accent("/save")} <n> [path] write one
6684
+ ${dim("Capabilities")} ${accent("/skills")} ${accent("/connectors")} ${accent("/voice")} speak a turn
6685
+ ${dim("General")} ${accent("/help")} this ${accent("/exit")} / ${accent("/quit")} leave ${dim("(Ctrl-D / Ctrl-C also exit)")}
6686
+
6687
+ ${dim("Full command list outside the chat:")} ${accent("oriro --help")}
5801
6688
 
5802
6689
  `;
5803
6690
  }
@@ -5856,6 +6743,24 @@ async function runReadlineRepl(session) {
5856
6743
  `);
5857
6744
  continue;
5858
6745
  }
6746
+ if (isRouterSlash(slash)) {
6747
+ stdout7.write((await handleRouterSlash(line)).join("\n") + "\n");
6748
+ continue;
6749
+ }
6750
+ if (isUsageSlash(slash)) {
6751
+ stdout7.write(handleUsage().join("\n") + "\n");
6752
+ continue;
6753
+ }
6754
+ if (slash === "/trace") {
6755
+ stdout7.write(` ${dim(`trace ${toggleTrace() ? "ON" : "off"}`)}
6756
+ `);
6757
+ continue;
6758
+ }
6759
+ if (isArtifactSlash(slash)) {
6760
+ stdout7.write(handleArtifactSlash(line).join("\n") + "\n");
6761
+ continue;
6762
+ }
6763
+ bumpTurns();
5859
6764
  const english = await translateIncoming(line);
5860
6765
  noteUserInput(line);
5861
6766
  let out = "";
@@ -5873,8 +6778,12 @@ async function runReadlineRepl(session) {
5873
6778
  }
5874
6779
  const cleaned = scrubOutput(out);
5875
6780
  const shown = isEnglish3 ? cleaned.trim() : await translateOutgoing(cleaned.trim());
6781
+ const arts = extractArtifacts(shown);
6782
+ setArtifacts(arts);
6783
+ const hint = arts.length ? ` ${dim(`\u2398 ${arts.length} artifact${arts.length === 1 ? "" : "s"} \u2014 /review to save`)}
6784
+ ` : "";
5876
6785
  stdout7.write(`${shown}${phantomFileWarning(shown)}
5877
-
6786
+ ${hint}
5878
6787
  `);
5879
6788
  }
5880
6789
  } finally {
@@ -5887,7 +6796,54 @@ async function runReadlineRepl(session) {
5887
6796
  }
5888
6797
  }
5889
6798
 
6799
+ // src/headless.ts
6800
+ function isOutputFormatMode(s) {
6801
+ return s === "text" || s === "json" || s === "stream-json";
6802
+ }
6803
+ async function runHeadless(prompt, format) {
6804
+ if (!prompt.trim()) {
6805
+ process.stderr.write('error: empty prompt \u2014 pass text after -p, e.g. oriro -p "summarise this repo"\n');
6806
+ process.exitCode = 1;
6807
+ return;
6808
+ }
6809
+ const { session } = await assembleOriroSession({});
6810
+ let text = "";
6811
+ const unsub = session.subscribe(
6812
+ (e) => {
6813
+ if (e.type === "message_update" && e.assistantMessageEvent?.type === "text_delta") {
6814
+ const d = e.assistantMessageEvent.delta ?? "";
6815
+ text += d;
6816
+ if (format === "stream-json" && d) process.stdout.write(JSON.stringify({ type: "text_delta", delta: d }) + "\n");
6817
+ }
6818
+ }
6819
+ );
6820
+ let error = "";
6821
+ try {
6822
+ await session.prompt(prompt);
6823
+ } catch (e) {
6824
+ error = e instanceof Error ? e.message : String(e);
6825
+ }
6826
+ unsub();
6827
+ const response = scrubOutput(text).trim();
6828
+ const ok2 = !error && response.length > 0;
6829
+ if (format === "json") {
6830
+ process.stdout.write(JSON.stringify({ ok: ok2, response, ...error ? { error } : {} }) + "\n");
6831
+ } else if (format === "stream-json") {
6832
+ process.stdout.write(JSON.stringify({ type: "done", ok: ok2, response, ...error ? { error } : {} }) + "\n");
6833
+ } else {
6834
+ process.stdout.write((response || (error ? `error: ${error}` : "(no response)")) + "\n");
6835
+ }
6836
+ process.exitCode = ok2 ? 0 : 1;
6837
+ try {
6838
+ session.dispose();
6839
+ } catch {
6840
+ }
6841
+ setTimeout(() => process.exit(ok2 ? 0 : 1), 400).unref();
6842
+ }
6843
+
5890
6844
  // src/commands/ui.ts
6845
+ import { createInterface as createInterface7 } from "readline/promises";
6846
+ import { stdin as stdin7, stdout as stdout8 } from "process";
5891
6847
  var ok = (s) => {
5892
6848
  process.stdout.write(`${fgHex(PALETTE.success, "\u2713")} ${s}
5893
6849
  `);
@@ -5912,11 +6868,159 @@ function die(msg) {
5912
6868
  process.exitCode = 1;
5913
6869
  throw new DieError(msg);
5914
6870
  }
6871
+ async function confirmDestructive(what, opts = {}) {
6872
+ if (opts.force) return true;
6873
+ if (!stdin7.isTTY || !stdout8.isTTY) {
6874
+ die(`refusing to ${what} without confirmation \u2014 re-run with --force in a non-interactive shell`);
6875
+ }
6876
+ const rl = createInterface7({ input: stdin7, output: stdout8 });
6877
+ try {
6878
+ const ans = (await rl.question(`${fgHex(PALETTE.error, "?")} ${what} \u2014 this cannot be undone. Proceed? [y/N] `)).trim().toLowerCase();
6879
+ return ans === "y" || ans === "yes";
6880
+ } finally {
6881
+ rl.close();
6882
+ }
6883
+ }
6884
+
6885
+ // src/config/store.ts
6886
+ import { readFileSync as readFileSync21, writeFileSync as writeFileSync19, mkdirSync as mkdirSync16 } from "fs";
6887
+ import { join as join26 } from "path";
6888
+ var KEYS = {
6889
+ output: {
6890
+ desc: "default output format for list commands: text | json | csv",
6891
+ validate: (v) => ["text", "json", "csv"].includes(v) ? null : "must be text | json | csv"
6892
+ },
6893
+ lang: { desc: "preferred UI language code (e.g. en, hi, es) \u2014 overrides terminal detection" },
6894
+ thinking: {
6895
+ desc: "default REPL thinking mode: on | off",
6896
+ validate: (v) => ["on", "off"].includes(v) ? null : "must be on | off"
6897
+ }
6898
+ };
6899
+ function configKeys() {
6900
+ return Object.keys(KEYS).map((key) => ({ key, desc: KEYS[key].desc }));
6901
+ }
6902
+ function isConfigKey(k) {
6903
+ return k in KEYS;
6904
+ }
6905
+ function validateConfig(key, value) {
6906
+ return KEYS[key].validate?.(value) ?? null;
6907
+ }
6908
+ function file4() {
6909
+ return join26(oriroDir(), "config.json");
6910
+ }
6911
+ var cache = null;
6912
+ function readAll() {
6913
+ if (cache) return cache;
6914
+ try {
6915
+ const v = JSON.parse(readFileSync21(file4(), "utf8"));
6916
+ cache = v && typeof v === "object" ? v : {};
6917
+ } catch {
6918
+ cache = {};
6919
+ }
6920
+ return cache;
6921
+ }
6922
+ function configGet(key) {
6923
+ return readAll()[key];
6924
+ }
6925
+ function configAll() {
6926
+ return { ...readAll() };
6927
+ }
6928
+ function configSet(key, value) {
6929
+ const all = { ...readAll(), [key]: value };
6930
+ mkdirSync16(oriroDir(), { recursive: true });
6931
+ writeFileSync19(file4(), JSON.stringify(all, null, 2), "utf8");
6932
+ cache = all;
6933
+ }
6934
+ function configUnset(key) {
6935
+ const all = readAll();
6936
+ if (!(key in all)) return false;
6937
+ const rest = { ...all };
6938
+ delete rest[key];
6939
+ writeFileSync19(file4(), JSON.stringify(rest, null, 2), "utf8");
6940
+ cache = rest;
6941
+ return true;
6942
+ }
6943
+
6944
+ // src/commands/output.ts
6945
+ function parseFormat(o) {
6946
+ const f = (o ?? configGet("output") ?? "text").toLowerCase();
6947
+ if (f === "json" || f === "csv" || f === "text") return f;
6948
+ throw new Error(`invalid --output '${o}'. Use: text | json | csv`);
6949
+ }
6950
+ function applyQuery(rows, query) {
6951
+ if (!query) return rows;
6952
+ const [filterPart, selectField] = query.split(":", 2);
6953
+ let out = rows;
6954
+ const fp = filterPart ?? "";
6955
+ if (fp.includes("=")) {
6956
+ const [field2, value] = fp.split("=", 2);
6957
+ out = rows.filter((r) => String(r[field2] ?? "") === value);
6958
+ } else if (fp && !selectField) {
6959
+ return rows.map((r) => r[fp]);
6960
+ }
6961
+ if (selectField) return out.map((r) => r[selectField]);
6962
+ return out;
6963
+ }
6964
+ function csvCell(v) {
6965
+ const s = v === null || v === void 0 ? "" : String(v);
6966
+ return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
6967
+ }
6968
+ function renderList2(rows, opts = {}) {
6969
+ const fmt = parseFormat(opts.output);
6970
+ const queried = applyQuery(rows, opts.query);
6971
+ if (fmt === "json") return JSON.stringify(queried, null, 2);
6972
+ if (!Array.isArray(queried) || queried.length === 0) return "";
6973
+ const first = queried[0];
6974
+ const scalar = typeof first !== "object" || first === null;
6975
+ if (scalar) return queried.map((v) => fmt === "csv" ? csvCell(v) : String(v)).join("\n");
6976
+ const objs = queried;
6977
+ const cols = opts.columns ?? [...new Set(objs.flatMap((r) => Object.keys(r)))];
6978
+ if (fmt === "csv") {
6979
+ return [cols.map(csvCell).join(","), ...objs.map((r) => cols.map((c) => csvCell(r[c])).join(","))].join("\n");
6980
+ }
6981
+ const widths = cols.map((c) => Math.max(c.length, ...objs.map((r) => String(r[c] ?? "").length)));
6982
+ const line = (cells) => cells.map((s, i) => s.padEnd(widths[i] ?? 0)).join(" ").trimEnd();
6983
+ return [line(cols), ...objs.map((r) => line(cols.map((c) => String(r[c] ?? ""))))].join("\n");
6984
+ }
6985
+ function isMachineOutput(opts) {
6986
+ return parseFormat(opts.output) !== "text";
6987
+ }
6988
+ function outputError(opts) {
6989
+ const f = (opts.output ?? configGet("output") ?? "text").toLowerCase();
6990
+ return f === "json" || f === "csv" || f === "text" ? null : `invalid --output '${opts.output}' \u2014 use text | json | csv`;
6991
+ }
5915
6992
 
5916
6993
  // src/commands/routers.ts
5917
6994
  function registerRoutersCommand(program2) {
5918
6995
  const routers = program2.command("routers").description("manage the free-router pool the model runs on");
5919
- routers.command("list").description("list the router catalog and the active pool").action(() => {
6996
+ routers.command("list").description("list the router catalog and the active pool").option("-o, --output <fmt>", "output format: text (default) | json | csv").option("-q, --query <expr>", "filter/select: 'field', 'field=value', or 'field=value:selectField'").action((opts) => {
6997
+ const oerr = outputError(opts);
6998
+ if (oerr) die(oerr);
6999
+ const pool = new Set(resolvePool().map((p) => p.id));
7000
+ if (isMachineOutput(opts) || opts.query) {
7001
+ const catalogRows = ROUTER_CATALOG.filter((r) => !r.comingSoon).map((r) => ({
7002
+ id: r.id,
7003
+ name: r.displayName,
7004
+ tier: r.keyless ? "keyless" : r.tier,
7005
+ keyless: Boolean(r.keyless),
7006
+ source: "catalog",
7007
+ active: pool.has(r.id)
7008
+ }));
7009
+ const customRows = registeredRouters().filter((r) => !ROUTER_CATALOG.some((c) => c.id === r.id)).map((r) => ({
7010
+ id: r.id,
7011
+ name: r.name,
7012
+ tier: r.apiKey && r.apiKey !== KEYLESS_SENTINEL ? "byok" : "keyless",
7013
+ keyless: !r.apiKey || r.apiKey === KEYLESS_SENTINEL,
7014
+ source: "custom",
7015
+ active: pool.has(r.id)
7016
+ }));
7017
+ process.stdout.write(renderList2([...catalogRows, ...customRows], {
7018
+ output: opts.output,
7019
+ query: opts.query,
7020
+ columns: ["id", "name", "tier", "keyless", "active", "source"]
7021
+ }) + "\n");
7022
+ return;
7023
+ }
5920
7024
  heading("Routers");
5921
7025
  for (const r of ROUTER_CATALOG) {
5922
7026
  if (r.comingSoon) {
@@ -5939,8 +7043,7 @@ function registerRoutersCommand(program2) {
5939
7043
  `);
5940
7044
  }
5941
7045
  }
5942
- const pool = resolvePool();
5943
- info(pool.length ? `active pool: ${pool.map((p) => p.id).join(", ")}` : "active pool: empty \u2192 using the keyless floor");
7046
+ info(pool.size ? `active pool: ${[...pool].join(", ")}` : "active pool: empty \u2192 using the keyless floor");
5944
7047
  });
5945
7048
  routers.command("add <name>").description("live-validate a router and add it to the pool \u2014 a catalog name, OR any custom endpoint via --url").option("-k, --key <key>", "API key (BYOK) \u2014 omit for a keyless free router").option("-m, --model <id>", "model id to run (REQUIRED for a custom --url router)").option("--url <baseUrl>", "add ANY custom free/BYOK router by its OpenAI-compatible base URL (the part BEFORE /chat/completions)").option("--api <api>", "custom router API: 'openai' (default) or 'google'", "openai").action(async (name, opts) => {
5946
7049
  let entry;
@@ -5976,10 +7079,10 @@ function registerRoutersCommand(program2) {
5976
7079
  }
5977
7080
 
5978
7081
  // src/commands/scribe.ts
5979
- import { readFileSync as readFileSync19 } from "fs";
7082
+ import { readFileSync as readFileSync23 } from "fs";
5980
7083
 
5981
7084
  // src/scribe/transcript.ts
5982
- import { existsSync as existsSync15, readFileSync as readFileSync18 } from "fs";
7085
+ import { existsSync as existsSync19, readFileSync as readFileSync22 } from "fs";
5983
7086
  function parseHookStdin(raw) {
5984
7087
  try {
5985
7088
  const j = JSON.parse(raw);
@@ -6012,8 +7115,8 @@ function isHumanUser(e) {
6012
7115
  }
6013
7116
  var FILE_KEYS = ["file_path", "path", "notebook_path", "filePath"];
6014
7117
  function lastTurnFromTranscript(path) {
6015
- if (!existsSync15(path)) return null;
6016
- const raw = readFileSync18(path, "utf8");
7118
+ if (!existsSync19(path)) return null;
7119
+ const raw = readFileSync22(path, "utf8");
6017
7120
  const entries = [];
6018
7121
  for (const line of raw.split("\n")) {
6019
7122
  if (!line.trim()) continue;
@@ -6074,7 +7177,7 @@ function lastTurnFromTranscript(path) {
6074
7177
  // src/commands/scribe.ts
6075
7178
  function readStdin() {
6076
7179
  try {
6077
- return readFileSync19(0, "utf8");
7180
+ return readFileSync23(0, "utf8");
6078
7181
  } catch {
6079
7182
  return "";
6080
7183
  }
@@ -6187,40 +7290,8 @@ function registerScribeCommand(program2) {
6187
7290
  }
6188
7291
 
6189
7292
  // src/commands/connectors.ts
6190
- import { createInterface as createInterface7 } from "readline/promises";
6191
- import { stdin as stdin7, stdout as stdout8 } from "process";
6192
-
6193
- // src/connectors/custom.ts
6194
- import { readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "fs";
6195
- import { join as join23 } from "path";
6196
- function file3() {
6197
- return join23(oriroDir(), "mcp-custom.json");
6198
- }
6199
- function readCustomServers() {
6200
- try {
6201
- const v = JSON.parse(readFileSync20(file3(), "utf8"));
6202
- return Array.isArray(v) ? v : [];
6203
- } catch {
6204
- return [];
6205
- }
6206
- }
6207
- function saveCustomServer(server) {
6208
- const rest = readCustomServers().filter((s) => s.name.toLowerCase() !== server.name.toLowerCase());
6209
- writeFileSync16(join23(ensureOriroDir(), "mcp-custom.json"), JSON.stringify([...rest, server], null, 2), "utf8");
6210
- }
6211
- function removeCustomServer(name) {
6212
- const before = readCustomServers();
6213
- const after = before.filter((s) => s.name.toLowerCase() !== name.toLowerCase());
6214
- if (after.length === before.length) return false;
6215
- writeFileSync16(join23(ensureOriroDir(), "mcp-custom.json"), JSON.stringify(after, null, 2), "utf8");
6216
- return true;
6217
- }
6218
- function trustedServerNames() {
6219
- return readCustomServers().filter((s) => s.trusted).map((s) => s.name);
6220
- }
6221
- function isServerTrusted(name) {
6222
- return trustedServerNames().some((n) => n.toLowerCase() === name.toLowerCase());
6223
- }
7293
+ import { createInterface as createInterface8 } from "readline/promises";
7294
+ import { stdin as stdin8, stdout as stdout9 } from "process";
6224
7295
 
6225
7296
  // src/connectors/setup.ts
6226
7297
  function buildServerConfig(i) {
@@ -6251,39 +7322,41 @@ function parsePairs(s) {
6251
7322
  return out;
6252
7323
  }
6253
7324
 
6254
- // src/connectors/mcp-client.ts
6255
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
6256
- import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
6257
- import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
6258
- function assertSafeUrl(raw, allowLocal = false) {
6259
- const u = new URL(raw);
6260
- if (u.protocol !== "https:" && u.protocol !== "http:") throw new Error(`unsupported scheme: ${u.protocol}`);
6261
- const host = u.hostname.toLowerCase();
6262
- const isLoopback = host === "localhost" || host === "127.0.0.1" || host === "::1" || host.endsWith(".localhost");
6263
- const isPrivate = /^10\./.test(host) || /^192\.168\./.test(host) || /^172\.(1[6-9]|2\d|3[01])\./.test(host) || /^169\.254\./.test(host) || /^fe80:/i.test(host) || /^f[cd][0-9a-f]{2}:/i.test(host) || host === "169.254.169.254" || host === "metadata.google.internal";
6264
- if ((isLoopback || isPrivate) && !allowLocal) {
6265
- throw new Error(`blocked SSRF target ${host} (use --allow-local for loopback/LAN MCP servers)`);
6266
- }
6267
- if (u.protocol === "http:" && !isLoopback && !allowLocal) throw new Error(`refusing plaintext http to ${host} \u2014 use https`);
6268
- return u;
6269
- }
6270
-
6271
7325
  // src/commands/connectors.ts
6272
7326
  function registerConnectorsCommand(program2) {
6273
7327
  const connectors = program2.command("connectors").description("MCP connectors \u2014 add external tools/services (inert until used)");
6274
- connectors.command("list [category]").description("list the connector catalog (optionally filtered by category)").action((category) => {
7328
+ connectors.command("list [category]").description("list the connector catalog (optionally filtered by category)").option("-o, --output <fmt>", "output format: text (default) | json | csv").option("-q, --query <expr>", "filter/select: 'field', 'field=value', or 'field=value:selectField'").action((category, opts) => {
7329
+ const oerr = outputError(opts);
7330
+ if (oerr) die(oerr);
6275
7331
  if (category && !connectorCategories().includes(category)) {
6276
7332
  die(`unknown category '${category}' \u2014 categories: ${connectorCategories().join(", ")}`);
6277
7333
  }
6278
7334
  const entries = listConnectors(category);
6279
7335
  const added = new Set(addedConnectors().map((c) => c.slug));
7336
+ if (isMachineOutput(opts) || opts.query) {
7337
+ const rows = entries.map((c) => ({
7338
+ slug: c.slug,
7339
+ name: c.name,
7340
+ category: c.category,
7341
+ addable: Boolean(c.mcpUrl),
7342
+ added: added.has(c.slug)
7343
+ }));
7344
+ process.stdout.write(renderList2(rows, {
7345
+ output: opts.output,
7346
+ query: opts.query,
7347
+ columns: ["slug", "name", "category", "addable", "added"]
7348
+ }) + "\n");
7349
+ return;
7350
+ }
6280
7351
  heading(category ? `Connectors \xB7 ${category}` : "Connectors");
6281
7352
  let addable = 0;
7353
+ const NAME_W = 34;
6282
7354
  for (const c of entries) {
6283
7355
  const canAdd = !!c.mcpUrl;
6284
7356
  if (canAdd) addable++;
6285
7357
  const mark = !canAdd ? dim("\xB7") : added.has(c.slug) ? accent("\u25CF") : dim("\u25CB");
6286
- const name = canAdd ? c.name.padEnd(22) : dim(`${c.name} (coming soon)`.padEnd(22));
7358
+ const label = (canAdd ? c.name : `${c.name} (coming soon)`).padEnd(NAME_W);
7359
+ const name = canAdd ? label : dim(label);
6287
7360
  process.stdout.write(` ${mark} ${(canAdd ? accent : dim)(c.slug.padEnd(20))} ${name} ${dim(c.category)}
6288
7361
  `);
6289
7362
  }
@@ -6298,12 +7371,20 @@ function registerConnectorsCommand(program2) {
6298
7371
  if (!res.ok) die(res.error ?? `could not add '${slug}'`);
6299
7372
  ok(`added ${accent(slug)} \u2014 recorded locally`);
6300
7373
  });
6301
- connectors.command("remove <slug>").description("remove a connector").action((slug) => {
7374
+ connectors.command("remove <slug>").description("remove a connector").option("-f, --force", "skip the confirmation prompt").action(async (slug, opts) => {
7375
+ if (!isConnectorAdded(slug)) {
7376
+ info(`'${slug}' is not in your added list \u2014 nothing to remove`);
7377
+ return;
7378
+ }
7379
+ if (!await confirmDestructive(`remove connector '${slug}'`, opts)) {
7380
+ info("cancelled");
7381
+ return;
7382
+ }
6302
7383
  if (removeConnector(slug)) ok(`removed ${accent(slug)}`);
6303
7384
  else info(`'${slug}' is not in your added list \u2014 nothing to remove`);
6304
7385
  });
6305
7386
  connectors.command("setup").description("guided setup of a CUSTOM MCP server \u2014 Guardian-vetted, no JSON").option("--name <name>", "a short name for the server").option("--command <cmd>", "stdio launch command, e.g. 'npx -y @scope/mcp'").option("--args <args>", "space-separated args for --command").option("--env <pairs>", "comma-separated KEY=VAL env vars").option("--url <url>", "http(s) MCP endpoint (instead of --command)").option("--header <pairs>", "comma-separated KEY=VAL headers (with --url)").option("--allow-local", "permit loopback/LAN URL targets").option("-y, --yes", "trust and save when Guardian says 'ask'").action(async (opts) => {
6306
- const interactive = !!stdin7.isTTY && !!stdout8.isTTY;
7387
+ const interactive = !!stdin8.isTTY && !!stdout9.isTTY;
6307
7388
  let { name, command, url } = opts;
6308
7389
  let argsStr = opts.args;
6309
7390
  let envStr = opts.env;
@@ -6322,7 +7403,7 @@ function registerConnectorsCommand(program2) {
6322
7403
  );
6323
7404
  return;
6324
7405
  }
6325
- const rl = createInterface7({ input: stdin7, output: stdout8 });
7406
+ const rl = createInterface8({ input: stdin8, output: stdout9 });
6326
7407
  try {
6327
7408
  name = name || (await rl.question("Server name: ")).trim();
6328
7409
  if (!command && !url) {
@@ -6364,7 +7445,7 @@ function registerConnectorsCommand(program2) {
6364
7445
  if (opts.yes) {
6365
7446
  trusted = true;
6366
7447
  } else if (interactive) {
6367
- const rl = createInterface7({ input: stdin7, output: stdout8 });
7448
+ const rl = createInterface8({ input: stdin8, output: stdout9 });
6368
7449
  try {
6369
7450
  const ans = (await rl.question(`Trust and save "${name}"? [y/N] `)).trim().toLowerCase();
6370
7451
  trusted = ans === "y" || ans === "yes";
@@ -6406,14 +7487,14 @@ function registerConnectorsCommand(program2) {
6406
7487
  }
6407
7488
 
6408
7489
  // src/channels/config.ts
6409
- import { readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "fs";
6410
- import { join as join24 } from "path";
6411
- function file4() {
6412
- return join24(oriroDir(), "channels.json");
7490
+ import { readFileSync as readFileSync24, writeFileSync as writeFileSync20 } from "fs";
7491
+ import { join as join27 } from "path";
7492
+ function file5() {
7493
+ return join27(oriroDir(), "channels.json");
6413
7494
  }
6414
7495
  function readChannels() {
6415
7496
  try {
6416
- const v = JSON.parse(readFileSync21(file4(), "utf8"));
7497
+ const v = JSON.parse(readFileSync24(file5(), "utf8"));
6417
7498
  return Array.isArray(v) ? v : [];
6418
7499
  } catch {
6419
7500
  return [];
@@ -6422,10 +7503,10 @@ function readChannels() {
6422
7503
  function saveChannel(cfg) {
6423
7504
  const all = readChannels().filter((c) => c.kind !== cfg.kind);
6424
7505
  all.push(cfg);
6425
- writeFileSync17(join24(ensureOriroDir(), "channels.json"), JSON.stringify(all, null, 2), "utf8");
7506
+ writeFileSync20(join27(ensureOriroDir(), "channels.json"), JSON.stringify(all, null, 2), "utf8");
6426
7507
  }
6427
7508
  function removeChannel(kind) {
6428
- writeFileSync17(join24(ensureOriroDir(), "channels.json"), JSON.stringify(readChannels().filter((c) => c.kind !== kind), null, 2), "utf8");
7509
+ writeFileSync20(join27(ensureOriroDir(), "channels.json"), JSON.stringify(readChannels().filter((c) => c.kind !== kind), null, 2), "utf8");
6429
7510
  }
6430
7511
 
6431
7512
  // src/channels/telegram.ts
@@ -6542,9 +7623,9 @@ async function startDiscord(token) {
6542
7623
  }
6543
7624
 
6544
7625
  // src/channels/whatsapp.ts
6545
- import { join as join25 } from "path";
7626
+ import { join as join28 } from "path";
6546
7627
  function whatsappAuthDir() {
6547
- return join25(oriroDir(), "whatsapp-auth");
7628
+ return join28(oriroDir(), "whatsapp-auth");
6548
7629
  }
6549
7630
  async function startWhatsApp() {
6550
7631
  let baileys;
@@ -6662,12 +7743,26 @@ function registerChannelsCommand(program2) {
6662
7743
  }
6663
7744
 
6664
7745
  // src/commands/skills.ts
6665
- import { existsSync as existsSync16, statSync as statSync3, mkdirSync as mkdirSync15, cpSync, rmSync as rmSync3 } from "fs";
6666
- import { resolve as resolve2, join as join26, basename, dirname as dirname3 } from "path";
7746
+ import { existsSync as existsSync20, statSync as statSync4, mkdirSync as mkdirSync17, cpSync, rmSync as rmSync4 } from "fs";
7747
+ import { resolve as resolve2, join as join29, basename, dirname as dirname4 } from "path";
6667
7748
  function registerSkillsCommand(program2) {
6668
7749
  const skills = program2.command("skills").description("the ORIRO skill library \u2014 bundled + your own");
6669
- skills.command("list").description("show CORE / TAIL skill counts (use --all to list names)").option("-a, --all", "list every skill name").action(async (opts) => {
7750
+ skills.command("list").description("show CORE / TAIL skill counts (use --all to list names)").option("-a, --all", "list every skill name").option("-o, --output <fmt>", "output format: text (default) | json | csv").option("-q, --query <expr>", "filter/select: 'field', 'field=value', or 'field=value:selectField'").action(async (opts) => {
7751
+ const oerr = outputError(opts);
7752
+ if (oerr) die(oerr);
6670
7753
  const s = await loadOriroSkills();
7754
+ if (isMachineOutput(opts) || opts.query) {
7755
+ const rows = s.all.map((sk) => ({
7756
+ name: sk.name,
7757
+ tier: sk.disableModelInvocation ? "TAIL" : "CORE"
7758
+ }));
7759
+ process.stdout.write(renderList2(rows, {
7760
+ output: opts.output,
7761
+ query: opts.query,
7762
+ columns: ["name", "tier"]
7763
+ }) + "\n");
7764
+ return;
7765
+ }
6671
7766
  heading("Skills");
6672
7767
  info(`${accent(String(s.all.length))} loaded \xB7 ${accent(String(s.core.length))} CORE (model-visible) \xB7 ${accent(String(s.tail.length))} TAIL (/name-only)`);
6673
7768
  if (opts.all) {
@@ -6681,38 +7776,42 @@ function registerSkillsCommand(program2) {
6681
7776
  });
6682
7777
  skills.command("add <path>").description("add your own skill \u2014 a folder containing SKILL.md, or a SKILL.md file").action((p) => {
6683
7778
  const src = resolve2(p);
6684
- if (!existsSync16(src)) die(`not found: ${src}`);
7779
+ if (!existsSync20(src)) die(`not found: ${src}`);
6685
7780
  const dest = userSkillsDir();
6686
- mkdirSync15(dest, { recursive: true });
6687
- const st = statSync3(src);
7781
+ mkdirSync17(dest, { recursive: true });
7782
+ const st = statSync4(src);
6688
7783
  if (st.isDirectory()) {
6689
- if (!existsSync16(join26(src, "SKILL.md"))) die(`no SKILL.md in ${src} \u2014 a skill folder must contain SKILL.md`);
7784
+ if (!existsSync20(join29(src, "SKILL.md"))) die(`no SKILL.md in ${src} \u2014 a skill folder must contain SKILL.md`);
6690
7785
  const name = basename(src);
6691
- cpSync(src, join26(dest, name), { recursive: true });
6692
- ok(`added skill ${accent(name)} \u2192 ${join26(dest, name)}`);
7786
+ cpSync(src, join29(dest, name), { recursive: true });
7787
+ ok(`added skill ${accent(name)} \u2192 ${join29(dest, name)}`);
6693
7788
  } else if (basename(src).toLowerCase() === "skill.md") {
6694
- const name = basename(dirname3(src)) || "custom-skill";
6695
- mkdirSync15(join26(dest, name), { recursive: true });
6696
- cpSync(src, join26(dest, name, "SKILL.md"));
6697
- ok(`added skill ${accent(name)} \u2192 ${join26(dest, name)}`);
7789
+ const name = basename(dirname4(src)) || "custom-skill";
7790
+ mkdirSync17(join29(dest, name), { recursive: true });
7791
+ cpSync(src, join29(dest, name, "SKILL.md"));
7792
+ ok(`added skill ${accent(name)} \u2192 ${join29(dest, name)}`);
6698
7793
  } else {
6699
7794
  die("expected a folder containing SKILL.md, or a SKILL.md file");
6700
7795
  }
6701
7796
  info("It loads on next launch \u2014 and is available in chat via /skill.");
6702
7797
  });
6703
- skills.command("remove <name>").description("remove a skill you added").action((name) => {
6704
- const target = join26(userSkillsDir(), name);
6705
- if (!existsSync16(target)) {
7798
+ skills.command("remove <name>").description("remove a skill you added").option("-f, --force", "skip the confirmation prompt").action(async (name, opts) => {
7799
+ const target = join29(userSkillsDir(), name);
7800
+ if (!existsSync20(target)) {
6706
7801
  info(`'${name}' is not a user-added skill \u2014 nothing to remove`);
6707
7802
  return;
6708
7803
  }
6709
- rmSync3(target, { recursive: true, force: true });
7804
+ if (!await confirmDestructive(`remove skill '${name}'`, opts)) {
7805
+ info("cancelled");
7806
+ return;
7807
+ }
7808
+ rmSync4(target, { recursive: true, force: true });
6710
7809
  ok(`removed ${accent(name)}`);
6711
7810
  });
6712
7811
  }
6713
7812
 
6714
7813
  // src/commands/language.ts
6715
- import { stdin as stdin8 } from "process";
7814
+ import { stdin as stdin9 } from "process";
6716
7815
  function resolveLanguage(input) {
6717
7816
  return languageByCode(input) ?? LANGUAGES.find((l) => l.name.toLowerCase() === input.trim().toLowerCase());
6718
7817
  }
@@ -6734,7 +7833,7 @@ function registerLanguageCommand(program2) {
6734
7833
  ok(`${accent(lang.name)} is now your terminal language.`);
6735
7834
  return;
6736
7835
  }
6737
- if (stdin8.isTTY) {
7836
+ if (stdin9.isTTY) {
6738
7837
  const lang = await selectLanguageInteractive();
6739
7838
  setTerminalLanguage(lang);
6740
7839
  ok(`${accent(lang.name)} is now your terminal language.`);
@@ -6747,7 +7846,7 @@ function registerLanguageCommand(program2) {
6747
7846
  }
6748
7847
 
6749
7848
  // src/commands/avatar.ts
6750
- import { stdin as stdin9 } from "process";
7849
+ import { stdin as stdin10 } from "process";
6751
7850
  function registerAvatarCommand(program2) {
6752
7851
  program2.command("avatar").description("show or change your terminal avatar").argument("[slug]", "set directly to this avatar slug").option("-l, --list", "list every avatar by category").action(async (slug, opts) => {
6753
7852
  if (opts.list) {
@@ -6765,7 +7864,7 @@ function registerAvatarCommand(program2) {
6765
7864
  ok(`${accent(avatar.slug)} is now your terminal face.`);
6766
7865
  return;
6767
7866
  }
6768
- if (stdin9.isTTY) {
7867
+ if (stdin10.isTTY) {
6769
7868
  const chosen = await selectAvatarInteractive();
6770
7869
  if (!chosen) {
6771
7870
  info("no change.");
@@ -6843,12 +7942,12 @@ function registerHeadCommand(program2) {
6843
7942
  }
6844
7943
 
6845
7944
  // src/commands/voice.ts
6846
- import { stdin as stdin10, stdout as stdout9 } from "process";
7945
+ import { stdin as stdin11, stdout as stdout10 } from "process";
6847
7946
  function registerVoiceCommand(program2) {
6848
- program2.command("voice").description("speech-to-text \u2014 transcribe an audio file or the mic (on-device Whisper, experimental)").argument("[file]", "audio file to transcribe (omit to record from the mic on a real terminal)").option("--translate", "translate speech to English (Whisper translate task)").option("--seconds <n>", "mic recording length in seconds", "6").action(async (file5, opts) => {
6849
- const interactive = !!stdin10.isTTY && !!stdout9.isTTY;
7947
+ program2.command("voice").description("speech-to-text \u2014 transcribe an audio file or the mic (on-device Whisper, experimental)").argument("[file]", "audio file to transcribe (omit to record from the mic on a real terminal)").option("--translate", "translate speech to English (Whisper translate task)").option("--seconds <n>", "mic recording length in seconds", "6").action(async (file6, opts) => {
7948
+ const interactive = !!stdin11.isTTY && !!stdout10.isTTY;
6850
7949
  heading("ORIRO voice \u{1F399}");
6851
- let audio = file5;
7950
+ let audio = file6;
6852
7951
  if (!audio) {
6853
7952
  if (!interactive) {
6854
7953
  info("On-device speech-to-text (experimental \u2014 needs ffmpeg + the transformers voice peer).");
@@ -6880,19 +7979,590 @@ function registerVoiceCommand(program2) {
6880
7979
  });
6881
7980
  }
6882
7981
 
7982
+ // src/agents/catalog.ts
7983
+ import { readFileSync as readFileSync25 } from "fs";
7984
+ function parseAgentDef(raw, now) {
7985
+ if (!raw || typeof raw !== "object") return { ok: false, error: "not a JSON object" };
7986
+ const o = raw;
7987
+ const name = typeof o.name === "string" ? o.name.trim().toLowerCase() : "";
7988
+ if (!name) return { ok: false, error: "missing 'name'" };
7989
+ if (!isValidAgentName(name)) return { ok: false, error: `invalid name '${name}' (lowercase, digits, hyphens)` };
7990
+ const task = typeof o.task === "string" ? o.task.trim() : "";
7991
+ if (!task) return { ok: false, error: "missing 'task'" };
7992
+ const def = {
7993
+ name,
7994
+ task,
7995
+ ...typeof o.description === "string" ? { description: o.description } : {},
7996
+ ...typeof o.router === "string" ? { router: o.router } : {},
7997
+ ...typeof o.cwd === "string" ? { cwd: o.cwd } : {},
7998
+ ...typeof o.schedule === "string" ? { schedule: o.schedule } : {},
7999
+ createdAt: now,
8000
+ updatedAt: now
8001
+ };
8002
+ return { ok: true, def };
8003
+ }
8004
+ async function fetchAgentSource(pathOrUrl) {
8005
+ if (/^https?:\/\//i.test(pathOrUrl)) {
8006
+ const res = await fetch(pathOrUrl);
8007
+ if (!res.ok) throw new Error(`fetch failed: HTTP ${res.status}`);
8008
+ return await res.json();
8009
+ }
8010
+ return JSON.parse(readFileSync25(pathOrUrl, "utf8"));
8011
+ }
8012
+ async function addAgentFromSource(pathOrUrl, now) {
8013
+ let raw;
8014
+ try {
8015
+ raw = await fetchAgentSource(pathOrUrl);
8016
+ } catch (e) {
8017
+ return { ok: false, error: e instanceof Error ? e.message : String(e) };
8018
+ }
8019
+ const parsed = parseAgentDef(raw, now);
8020
+ if (!parsed.ok) return { ok: false, error: parsed.error };
8021
+ const overwrote = Boolean(loadAgent(parsed.def.name));
8022
+ saveAgent(parsed.def);
8023
+ return { ok: true, name: parsed.def.name, overwrote };
8024
+ }
8025
+
8026
+ // src/commands/schedule.ts
8027
+ import { spawnSync } from "child_process";
8028
+ import { platform } from "process";
8029
+ var TASK_NAME = "ORIRO_Agents_Tick";
8030
+ function intervalMinutes(spec) {
8031
+ const m = /^(\d+)(m|h)$/.exec(spec.trim());
8032
+ if (!m) return null;
8033
+ const n = parseInt(m[1], 10);
8034
+ if (n <= 0) return null;
8035
+ return m[2] === "h" ? n * 60 : n;
8036
+ }
8037
+ function tickInvocation() {
8038
+ return { node: process.execPath, bin: process.argv[1] ?? "oriro" };
8039
+ }
8040
+ function buildCron(mins, remove) {
8041
+ const { node, bin } = tickInvocation();
8042
+ if (platform === "win32") {
8043
+ if (remove) return { cmd: `schtasks /Delete /TN ${TASK_NAME} /F`, note: "Windows Task Scheduler" };
8044
+ const sc = mins % 60 === 0 ? `/SC HOURLY /MO ${mins / 60}` : `/SC MINUTE /MO ${mins}`;
8045
+ return {
8046
+ cmd: `schtasks /Create /TN ${TASK_NAME} /TR "\\"${node}\\" \\"${bin}\\" agents tick" ${sc} /F`,
8047
+ note: "Windows Task Scheduler"
8048
+ };
8049
+ }
8050
+ const line = `*/${mins} * * * * "${node}" "${bin}" agents tick # ${TASK_NAME}`;
8051
+ if (remove) {
8052
+ return { cmd: `crontab -l 2>/dev/null | grep -v '# ${TASK_NAME}' | crontab -`, note: "crontab" };
8053
+ }
8054
+ return {
8055
+ cmd: `( crontab -l 2>/dev/null | grep -v '# ${TASK_NAME}'; echo '${line}' ) | crontab -`,
8056
+ note: "crontab"
8057
+ };
8058
+ }
8059
+ function runShell(cmd) {
8060
+ const r = platform === "win32" ? spawnSync("cmd", ["/c", cmd], { encoding: "utf8" }) : spawnSync("sh", ["-c", cmd], { encoding: "utf8" });
8061
+ if (r.status !== 0) {
8062
+ info(dim((r.stderr || r.stdout || "").trim().slice(0, 300)));
8063
+ return false;
8064
+ }
8065
+ return true;
8066
+ }
8067
+ function registerAgentsCron(agents) {
8068
+ agents.command("cron").description("install an OS scheduler that runs `agents tick` on an interval (fires scheduled agents)").option("--every <spec>", "interval: Nm | Nh", "5m").option("--remove", "remove the scheduler entry instead of installing it").option("--apply", "actually apply the change (default: just print the command to run)").action((opts) => {
8069
+ const mins = intervalMinutes(opts.every);
8070
+ if (!opts.remove && mins === null) die(`invalid --every '${opts.every}' \u2014 use Nm or Nh (e.g. 5m, 2h)`);
8071
+ const { cmd, note } = buildCron(mins ?? 5, Boolean(opts.remove));
8072
+ heading(opts.remove ? "Remove scheduled agents" : "Schedule agents");
8073
+ info(`${note}: runs ${accent("oriro agents tick")} ${opts.remove ? "" : `every ${accent(opts.every)}`}`);
8074
+ if (!opts.apply) {
8075
+ process.stdout.write(`
8076
+ ${cmd}
8077
+
8078
+ `);
8079
+ info(dim("printed only \u2014 re-run with --apply to make this change, or run the command yourself"));
8080
+ return;
8081
+ }
8082
+ if (runShell(cmd)) ok(opts.remove ? "scheduler entry removed" : `scheduled \u2014 agents tick will run every ${opts.every}`);
8083
+ else die("could not apply the schedule (see the message above) \u2014 you can run the printed command manually");
8084
+ });
8085
+ }
8086
+
8087
+ // src/commands/agents.ts
8088
+ function nowIso() {
8089
+ return (/* @__PURE__ */ new Date()).toISOString();
8090
+ }
8091
+ function printAgent(a) {
8092
+ const brain = a.router ? accent(a.router) : dim("active pool");
8093
+ const sched = a.schedule ? accent(a.schedule) : dim("manual");
8094
+ process.stdout.write(` ${accent(a.name.padEnd(22))} brain:${brain} schedule:${sched}
8095
+ `);
8096
+ if (a.description) process.stdout.write(` ${dim(a.description)}
8097
+ `);
8098
+ }
8099
+ async function runAndReport(def, opts = {}) {
8100
+ info(`running ${accent(def.name)} ${dim(`(brain: ${def.router ?? "active pool"})`)}\u2026`);
8101
+ const res = await runAgent2(def, opts);
8102
+ markRun(def.name, res.ok, Date.now());
8103
+ if (res.output) process.stdout.write(`
8104
+ ${res.output}
8105
+
8106
+ `);
8107
+ if (res.ok) ok(`${def.name} done`);
8108
+ else info(`${def.name} produced no output${res.output ? "" : " (router unavailable?)"}`);
8109
+ return res.ok;
8110
+ }
8111
+ var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
8112
+ function registerAgentsCommand(program2) {
8113
+ const agents = program2.command("agents").description("your workflow-automation agents \u2014 run on a router, full tools behind Guardian").action(() => {
8114
+ heading("Agents");
8115
+ const all = listAgents();
8116
+ info(`${accent(String(all.length))} saved \xB7 an agent = a saved workflow that runs on a router (its brain)`);
8117
+ info(`make one: ${accent('oriro agents make <name> --task "\u2026" [--router <id>] [--schedule 1h]')}`);
8118
+ info(`then: ${accent("oriro agents run <name>")} ${dim("\xB7 or")} ${accent("oriro agents tick")} ${dim("for scheduled ones")}`);
8119
+ });
8120
+ agents.command("list").description("list your saved agents").option("-o, --output <fmt>", "output format: text (default) | json | csv").option("-q, --query <expr>", "filter/select: 'field', 'field=value', or 'field=value:selectField'").action((opts) => {
8121
+ const oerr = outputError(opts);
8122
+ if (oerr) die(oerr);
8123
+ const all = listAgents();
8124
+ const state = loadState();
8125
+ if (isMachineOutput(opts) || opts.query) {
8126
+ const rows = all.map((a) => ({
8127
+ name: a.name,
8128
+ brain: a.router ?? "pool",
8129
+ schedule: a.schedule ?? "manual",
8130
+ description: a.description ?? "",
8131
+ lastRun: state[a.name]?.lastRunAt ? new Date(state[a.name].lastRunAt).toISOString() : "",
8132
+ lastOk: state[a.name]?.lastOk ?? null
8133
+ }));
8134
+ process.stdout.write(renderList2(rows, {
8135
+ output: opts.output,
8136
+ query: opts.query,
8137
+ columns: ["name", "brain", "schedule", "lastRun", "lastOk"]
8138
+ }) + "\n");
8139
+ return;
8140
+ }
8141
+ heading("Agents");
8142
+ if (!all.length) {
8143
+ info(`no agents yet \u2014 make one: ${accent('oriro agents make my-agent --task "\u2026"')}`);
8144
+ return;
8145
+ }
8146
+ for (const a of all) {
8147
+ printAgent(a);
8148
+ const last = state[a.name]?.lastRunAt;
8149
+ if (last) process.stdout.write(` ${dim(`last run: ${new Date(last).toISOString()}${state[a.name]?.lastOk === false ? " (failed)" : ""}`)}
8150
+ `);
8151
+ }
8152
+ });
8153
+ agents.command("make <name>").description("create or update an agent").requiredOption("-t, --task <text>", "the workflow / instructions the agent carries out").option("-d, --desc <text>", "a short description").option("-r, --router <id>", "bind a router as the brain (default: your active pool)").option("-s, --schedule <spec>", "automation cadence: Nm | Nh | Nd | hourly | daily").option("-c, --cwd <path>", "working directory for the automation").action((name, opts) => {
8154
+ if (!isValidAgentName(name)) die(`invalid agent name '${name}' \u2014 use lowercase letters, digits and hyphens`);
8155
+ if (opts.schedule && parseScheduleMs(opts.schedule) === void 0) {
8156
+ die(`invalid --schedule '${opts.schedule}' \u2014 use Nm, Nh, Nd, hourly or daily`);
8157
+ }
8158
+ if (opts.router && !registeredRouters().some((r) => r.id === opts.router)) {
8159
+ info(`note: router '${opts.router}' isn't added yet \u2014 add it with \`oriro routers add ${opts.router}\` or it falls back to your active pool`);
8160
+ }
8161
+ const existing = loadAgent(name);
8162
+ const now = nowIso();
8163
+ const def = {
8164
+ name,
8165
+ task: opts.task,
8166
+ ...opts.desc ? { description: opts.desc } : {},
8167
+ ...opts.router ? { router: opts.router } : {},
8168
+ ...opts.schedule ? { schedule: opts.schedule } : {},
8169
+ ...opts.cwd ? { cwd: opts.cwd } : {},
8170
+ createdAt: existing?.createdAt ?? now,
8171
+ updatedAt: now
8172
+ };
8173
+ saveAgent(def);
8174
+ ok(`${existing ? "updated" : "created"} agent ${accent(name)}`);
8175
+ if (def.schedule) info(`scheduled ${accent(def.schedule)} \u2014 run \`oriro agents tick\` (or \`daemon\`) to fire it when due`);
8176
+ else info(`run it: ${accent(`oriro agents run ${name}`)}`);
8177
+ });
8178
+ agents.command("show <name>").description("print an agent's definition").action((name) => {
8179
+ const def = loadAgent(name);
8180
+ if (!def) die(`no agent named '${name}' \u2014 run \`oriro agents list\``);
8181
+ process.stdout.write(`${JSON.stringify(def, null, 2)}
8182
+ `);
8183
+ });
8184
+ agents.command("run <name>").description("run an agent now (comes alive on its router, full tools behind Guardian)").option("-c, --cwd <path>", "working directory for this run").option("-i, --input <text>", "input to pass to the agent").action(async (name, opts) => {
8185
+ const def = loadAgent(name);
8186
+ if (!def) die(`no agent named '${name}' \u2014 run \`oriro agents list\``);
8187
+ await runAndReport(def, { ...opts.cwd ? { cwd: opts.cwd } : {}, ...opts.input ? { input: opts.input } : {} });
8188
+ });
8189
+ agents.command("add <path-or-url>").description("import a shared/community agent from a JSON file or URL").action(async (src) => {
8190
+ const res = await addAgentFromSource(src, nowIso());
8191
+ if (!res.ok) die(`could not add agent: ${res.error}`);
8192
+ ok(`${res.overwrote ? "updated" : "added"} agent ${accent(res.name ?? "")} ${dim("\u2192 ~/.oriro/agents")}`);
8193
+ info(`run it: ${accent(`oriro agents run ${res.name}`)}`);
8194
+ });
8195
+ agents.command("remove <name>").description("delete an agent").option("-f, --force", "skip the confirmation prompt").action(async (name, opts) => {
8196
+ if (!loadAgent(name)) {
8197
+ info(`'${name}' is not a saved agent \u2014 nothing to remove`);
8198
+ return;
8199
+ }
8200
+ if (!await confirmDestructive(`remove agent '${name}'`, opts)) {
8201
+ info("cancelled");
8202
+ return;
8203
+ }
8204
+ if (!removeAgent(name)) {
8205
+ info(`'${name}' is not a saved agent \u2014 nothing to remove`);
8206
+ return;
8207
+ }
8208
+ ok(`removed ${accent(name)}`);
8209
+ });
8210
+ registerAgentsCron(agents);
8211
+ agents.command("tick").description("run every DUE scheduled agent once, then exit (wire to OS cron / Task Scheduler)").action(async () => {
8212
+ const state = loadState();
8213
+ const now = Date.now();
8214
+ const due = listAgents().filter((a) => isDue(a, state, now));
8215
+ heading("Agents \xB7 tick");
8216
+ if (!due.length) {
8217
+ info("0 agents due");
8218
+ return;
8219
+ }
8220
+ info(`${accent(String(due.length))} due: ${due.map((d) => d.name).join(", ")}`);
8221
+ for (const def of due) await runAndReport(def);
8222
+ });
8223
+ agents.command("daemon").description("stay resident and run scheduled agents as they come due (Ctrl-C to stop)").option("-i, --interval <seconds>", "how often to check for due agents", "60").action(async (opts) => {
8224
+ const everyMs = Math.max(5, Number(opts.interval) || 60) * 1e3;
8225
+ heading("Agents \xB7 daemon");
8226
+ info(`checking every ${accent(`${everyMs / 1e3}s`)} \u2014 Ctrl-C to stop`);
8227
+ let stop = false;
8228
+ process.on("SIGINT", () => {
8229
+ stop = true;
8230
+ info("\nstopping\u2026");
8231
+ });
8232
+ while (!stop) {
8233
+ const state = loadState();
8234
+ const now = Date.now();
8235
+ const due = listAgents().filter((a) => isDue(a, state, now));
8236
+ for (const def of due) {
8237
+ if (stop) break;
8238
+ await runAndReport(def);
8239
+ }
8240
+ for (let waited = 0; waited < everyMs && !stop; waited += 500) await sleep(500);
8241
+ }
8242
+ });
8243
+ }
8244
+
8245
+ // src/commands/completion.ts
8246
+ function extractTree(program2) {
8247
+ const nodes = [];
8248
+ for (const c of program2.commands) {
8249
+ const name = c.name();
8250
+ if (name === "completion") continue;
8251
+ nodes.push({
8252
+ name,
8253
+ subs: c.commands.map((s) => s.name()),
8254
+ opts: c.options.map((o) => o.long).filter((l) => Boolean(l))
8255
+ });
8256
+ }
8257
+ return nodes;
8258
+ }
8259
+ var SHELLS = ["bash", "zsh", "fish", "pwsh"];
8260
+ function topNames(tree) {
8261
+ return [...tree.map((n) => n.name), "completion", "help"].join(" ");
8262
+ }
8263
+ function genBash(tree) {
8264
+ const cases = tree.map((n) => ` ${n.name}) COMPREPLY=( $(compgen -W "${n.subs.join(" ")} ${n.opts.join(" ")}" -- "$cur") );;`).join("\n");
8265
+ return `# ORIRO bash completion. Install: oriro completion bash > /etc/bash_completion.d/oriro
8266
+ # or (per-user): oriro completion bash >> ~/.bashrc
8267
+ _oriro_complete() {
8268
+ local cur prev cword
8269
+ cur="\${COMP_WORDS[COMP_CWORD]}"
8270
+ cword=$COMP_CWORD
8271
+ if [ "$cword" -eq 1 ]; then
8272
+ COMPREPLY=( $(compgen -W "${topNames(tree)}" -- "$cur") )
8273
+ return
8274
+ fi
8275
+ case "\${COMP_WORDS[1]}" in
8276
+ ${cases}
8277
+ *) COMPREPLY=();;
8278
+ esac
8279
+ }
8280
+ complete -F _oriro_complete oriro
8281
+ `;
8282
+ }
8283
+ function genZsh(tree) {
8284
+ const cases = tree.map((n) => ` ${n.name}) compadd ${n.subs.join(" ")} ${n.opts.join(" ")} ;;`).join("\n");
8285
+ return `#compdef oriro
8286
+ # ORIRO zsh completion. Install: oriro completion zsh > "\${fpath[1]}/_oriro" (then restart the shell)
8287
+ _oriro() {
8288
+ local -a words; words=("\${(@)words}")
8289
+ if (( CURRENT == 2 )); then
8290
+ compadd ${topNames(tree)}
8291
+ return
8292
+ fi
8293
+ case "\${words[2]}" in
8294
+ ${cases}
8295
+ esac
8296
+ }
8297
+ _oriro "$@"
8298
+ `;
8299
+ }
8300
+ function genFish(tree) {
8301
+ const lines = [
8302
+ "# ORIRO fish completion. Install: oriro completion fish > ~/.config/fish/completions/oriro.fish",
8303
+ `complete -c oriro -f -n __fish_use_subcommand -a "${topNames(tree)}"`
8304
+ ];
8305
+ for (const n of tree) {
8306
+ if (n.subs.length) {
8307
+ lines.push(`complete -c oriro -f -n "__fish_seen_subcommand_from ${n.name}" -a "${n.subs.join(" ")}"`);
8308
+ }
8309
+ }
8310
+ return lines.join("\n") + "\n";
8311
+ }
8312
+ function genPwsh(tree) {
8313
+ const cases = tree.map((n) => ` '${n.name}' { @(${[...n.subs, ...n.opts].map((s) => `'${s}'`).join(", ")}) }`).join("\n");
8314
+ const top = [...tree.map((n) => n.name), "completion", "help"].map((s) => `'${s}'`).join(", ");
8315
+ return `# ORIRO PowerShell completion. Install: oriro completion pwsh >> $PROFILE (then restart pwsh)
8316
+ Register-ArgumentCompleter -Native -CommandName oriro -ScriptBlock {
8317
+ param($wordToComplete, $commandAst, $cursorPosition)
8318
+ $tokens = $commandAst.CommandElements | ForEach-Object { $_.ToString() }
8319
+ $candidates = if ($tokens.Count -le 2) {
8320
+ @(${top})
8321
+ } else {
8322
+ switch ($tokens[1]) {
8323
+ ${cases}
8324
+ default { @() }
8325
+ }
8326
+ }
8327
+ $candidates | Where-Object { $_ -like "$wordToComplete*" } |
8328
+ ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
8329
+ }
8330
+ `;
8331
+ }
8332
+ var GENERATORS = {
8333
+ bash: genBash,
8334
+ zsh: genZsh,
8335
+ fish: genFish,
8336
+ pwsh: genPwsh
8337
+ };
8338
+ function registerCompletionCommand(program2) {
8339
+ program2.command("completion <shell>").description("print a shell tab-completion script (bash | zsh | fish | pwsh)").action((shell) => {
8340
+ const s = shell.toLowerCase();
8341
+ if (!SHELLS.includes(s)) {
8342
+ die(`unsupported shell '${shell}'. Use one of: ${SHELLS.join(", ")}`);
8343
+ return;
8344
+ }
8345
+ process.stdout.write(GENERATORS[s](extractTree(program2)));
8346
+ });
8347
+ }
8348
+
8349
+ // src/commands/config.ts
8350
+ function registerConfigCommand(program2) {
8351
+ const config = program2.command("config").description("your durable CLI settings (defaults in ~/.oriro/config.json)");
8352
+ config.command("list").description("show every setting, its value, and what it does").action(() => {
8353
+ const all = configAll();
8354
+ heading("Config");
8355
+ for (const { key, desc } of configKeys()) {
8356
+ const val = all[key];
8357
+ process.stdout.write(` ${accent(key.padEnd(10))} ${val !== void 0 ? accent(val) : dim("(default)")} ${dim(desc)}
8358
+ `);
8359
+ }
8360
+ info(`set: ${accent("oriro config set <key> <value>")} \xB7 clear: ${accent("oriro config unset <key>")}`);
8361
+ });
8362
+ config.command("get <key>").description("print one setting's value").action((key) => {
8363
+ if (!isConfigKey(key)) die(`unknown key '${key}' \u2014 run \`oriro config list\``);
8364
+ const val = configGet(key);
8365
+ if (val === void 0) {
8366
+ info(`${key} is unset (using the built-in default)`);
8367
+ return;
8368
+ }
8369
+ process.stdout.write(`${val}
8370
+ `);
8371
+ });
8372
+ config.command("set <key> <value>").description("set a setting (validated)").action((key, value) => {
8373
+ if (!isConfigKey(key)) die(`unknown key '${key}' \u2014 run \`oriro config list\``);
8374
+ const err = validateConfig(key, value);
8375
+ if (err) die(`invalid value for '${key}': ${err}`);
8376
+ configSet(key, value);
8377
+ ok(`${accent(key)} = ${accent(value)}`);
8378
+ });
8379
+ config.command("unset <key>").description("clear a setting back to its built-in default").action((key) => {
8380
+ if (!isConfigKey(key)) die(`unknown key '${key}' \u2014 run \`oriro config list\``);
8381
+ if (configUnset(key)) ok(`cleared ${accent(key)}`);
8382
+ else info(`${key} was already at its default`);
8383
+ });
8384
+ }
8385
+
8386
+ // src/commands/setup.ts
8387
+ import { rmSync as rmSync5 } from "fs";
8388
+ import { join as join30 } from "path";
8389
+ import { stdin as stdin12, stdout as stdout11 } from "process";
8390
+ var MARKERS = [
8391
+ "language.json",
8392
+ "avatar.json",
8393
+ "skills-onboarded.json",
8394
+ "connectors-onboarded.json",
8395
+ "models-onboarded.json",
8396
+ join30("routers", "onboarded.json")
8397
+ ];
8398
+ function registerSetupCommand(program2) {
8399
+ program2.command("setup").description("run the guided setup wizard (language \xB7 routers \xB7 connectors \xB7 skills \xB7 avatar)").option("--reset", "clear your settled choices and re-ask every step").action(async (opts) => {
8400
+ if (opts.reset) {
8401
+ for (const m of MARKERS) {
8402
+ try {
8403
+ rmSync5(join30(oriroDir(), m), { force: true });
8404
+ } catch {
8405
+ }
8406
+ }
8407
+ ok("reset \u2014 every step will be asked again");
8408
+ }
8409
+ if (!stdin12.isTTY || !stdout11.isTTY) {
8410
+ heading("ORIRO setup");
8411
+ info(`ORIRO is ${accent("keyless")} \u2014 no login, no API keys. Run ${accent("oriro setup")} in a real terminal for the guided wizard.`);
8412
+ info(dim("or configure directly: oriro language <code> \xB7 oriro routers add <id> \xB7 oriro connectors add <slug> \xB7 oriro config set <k> <v>"));
8413
+ return;
8414
+ }
8415
+ await runOnboarding();
8416
+ });
8417
+ }
8418
+
8419
+ // src/commands/import.ts
8420
+ import { existsSync as existsSync21, readFileSync as readFileSync26, readdirSync as readdirSync3, statSync as statSync5, cpSync as cpSync2, mkdirSync as mkdirSync18 } from "fs";
8421
+ import { join as join31, basename as basename2 } from "path";
8422
+ function registerImportCommand(program2) {
8423
+ const imp = program2.command("import").description("migrate from another CLI (MCP servers, skills)");
8424
+ imp.command("mcp <file>").description("import MCP servers from a Claude-compatible mcp.json (Guardian-vetted)").action((file6) => {
8425
+ if (!existsSync21(file6)) die(`no such file: ${file6}`);
8426
+ let servers;
8427
+ try {
8428
+ const j = JSON.parse(readFileSync26(file6, "utf8"));
8429
+ servers = j.mcpServers ?? j.servers ?? {};
8430
+ } catch (e) {
8431
+ die(`could not parse ${file6}: ${e instanceof Error ? e.message : String(e)}`);
8432
+ return;
8433
+ }
8434
+ const names = Object.keys(servers);
8435
+ if (!names.length) die(`no "mcpServers" found in ${file6}`);
8436
+ heading(`Import MCP \xB7 ${names.length} server${names.length === 1 ? "" : "s"}`);
8437
+ let imported = 0, blocked2 = 0;
8438
+ for (const name of names) {
8439
+ const s = servers[name];
8440
+ const input = {
8441
+ name,
8442
+ ...s.command ? { command: s.command } : {},
8443
+ ...s.args ? { args: s.args } : {},
8444
+ ...s.env ? { env: s.env } : {},
8445
+ ...s.url ? { url: s.url } : {},
8446
+ ...s.headers ? { headers: s.headers } : {}
8447
+ };
8448
+ if (s.url) {
8449
+ try {
8450
+ assertSafeUrl(s.url);
8451
+ } catch (e) {
8452
+ process.stdout.write(` ${fgHex(PALETTE.error, "\u2717")} ${name} ${dim(`blocked: ${e instanceof Error ? e.message : String(e)}`)}
8453
+ `);
8454
+ blocked2++;
8455
+ continue;
8456
+ }
8457
+ }
8458
+ const outcome = vetServer(input);
8459
+ if (outcome.decision === "block") {
8460
+ process.stdout.write(` ${fgHex(PALETTE.error, "\u2717")} ${name} ${dim(`blocked: ${outcome.reason}`)}
8461
+ `);
8462
+ blocked2++;
8463
+ continue;
8464
+ }
8465
+ saveCustomServer({ name, config: buildServerConfig(input), trusted: outcome.decision === "allow" });
8466
+ const mark = outcome.decision === "allow" ? fgHex(PALETTE.success, "\u2713 trusted") : dim("\u25CB needs trust");
8467
+ process.stdout.write(` ${mark} ${accent(name)}
8468
+ `);
8469
+ imported++;
8470
+ }
8471
+ info(`${imported} imported \xB7 ${blocked2} blocked${imported ? ` \u2014 they connect in-session; see \`oriro connectors custom\`` : ""}`);
8472
+ });
8473
+ imp.command("skills <dir>").description("import SKILL.md skill folders from another CLI's skills directory").action((dir) => {
8474
+ if (!existsSync21(dir) || !statSync5(dir).isDirectory()) die(`no such directory: ${dir}`);
8475
+ const dest = userSkillsDir();
8476
+ mkdirSync18(dest, { recursive: true });
8477
+ heading("Import skills");
8478
+ const sources = existsSync21(join31(dir, "SKILL.md")) ? [dir] : readdirSync3(dir).map((e) => join31(dir, e)).filter((p) => statSync5(p).isDirectory() && existsSync21(join31(p, "SKILL.md")));
8479
+ let n = 0;
8480
+ for (const src of sources) {
8481
+ cpSync2(src, join31(dest, basename2(src)), { recursive: true });
8482
+ process.stdout.write(` ${fgHex(PALETTE.success, "\u2713")} ${accent(basename2(src))}
8483
+ `);
8484
+ n++;
8485
+ }
8486
+ if (n === 0) info(dim(`no SKILL.md skill folder found at or inside ${dir}`));
8487
+ else ok(`imported ${n} skill${n === 1 ? "" : "s"} \u2192 ${dim(dest)}`);
8488
+ });
8489
+ }
8490
+
8491
+ // src/commands/help-on-error.ts
8492
+ function lev(a, b) {
8493
+ const m = a.length, n = b.length;
8494
+ if (!m) return n;
8495
+ if (!n) return m;
8496
+ let prev = Array.from({ length: n + 1 }, (_, i) => i);
8497
+ let curr = new Array(n + 1);
8498
+ for (let i = 1; i <= m; i++) {
8499
+ curr[0] = i;
8500
+ for (let j = 1; j <= n; j++) {
8501
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
8502
+ curr[j] = Math.min((curr[j - 1] ?? 0) + 1, (prev[j] ?? 0) + 1, (prev[j - 1] ?? 0) + cost);
8503
+ }
8504
+ [prev, curr] = [curr, prev];
8505
+ }
8506
+ return prev[n] ?? n;
8507
+ }
8508
+ function didYouMean(input, candidates) {
8509
+ let best;
8510
+ let bestD = Infinity;
8511
+ for (const c of candidates) {
8512
+ const d = lev(input.toLowerCase(), c.toLowerCase());
8513
+ if (d < bestD) {
8514
+ bestD = d;
8515
+ best = c;
8516
+ }
8517
+ }
8518
+ return best !== void 0 && bestD <= Math.max(2, Math.floor(input.length * 0.4)) ? best : void 0;
8519
+ }
8520
+ function fullPath(cmd) {
8521
+ const parts = [];
8522
+ let c = cmd;
8523
+ while (c && c.name() !== "oriro") {
8524
+ parts.unshift(c.name());
8525
+ c = c.parent;
8526
+ }
8527
+ return parts.length ? `oriro ${parts.join(" ")}` : "oriro <command>";
8528
+ }
8529
+ function enableHelpOnError(program2) {
8530
+ const apply = (cmd) => {
8531
+ cmd.showHelpAfterError(`
8532
+ (run: ${fullPath(cmd)} --help for usage)`);
8533
+ cmd.showSuggestionAfterError(true);
8534
+ for (const sub of cmd.commands) apply(sub);
8535
+ };
8536
+ apply(program2);
8537
+ }
8538
+
6883
8539
  // src/cli.ts
6884
8540
  var version = createRequire(import.meta.url)("../package.json").version;
6885
8541
  var program = new Command();
6886
- program.name("oriro").description("ORIRO \u2014 a free, on-device-friendly terminal AI agent.").version(version, "-v, --version").action(async (_options, command) => {
8542
+ program.name("oriro").description("ORIRO \u2014 a free, on-device-friendly terminal AI agent.").version(version, "-v, --version").option("-p, --print <prompt>", "headless one-shot: run a single prompt, print the answer, exit (CI-friendly)").option("--output-format <fmt>", "with --print: text | json | stream-json", "text").action(async (options, command) => {
8543
+ if (options.print !== void 0) {
8544
+ const fmt = options.outputFormat ?? "text";
8545
+ if (!isOutputFormatMode(fmt)) {
8546
+ process.stderr.write(`error: --output-format must be text | json | stream-json
8547
+ `);
8548
+ process.exitCode = 1;
8549
+ return;
8550
+ }
8551
+ await runHeadless(options.print, fmt);
8552
+ return;
8553
+ }
6887
8554
  if (command.args.length > 0) {
6888
- const arg = command.args[0];
8555
+ const arg = command.args[0] ?? "";
6889
8556
  if (arg === "help") {
6890
8557
  command.outputHelp();
6891
8558
  return;
6892
8559
  }
6893
- process.stderr.write(`error: unknown command '${arg}'
6894
- Run 'oriro --help' to see available commands.
8560
+ const names = command.commands.map((c) => c.name());
8561
+ const guess = didYouMean(arg, names);
8562
+ process.stderr.write(`error: unknown command '${arg}'${guess ? ` \u2014 did you mean '${guess}'?` : ""}
8563
+
6895
8564
  `);
8565
+ command.outputHelp();
6896
8566
  process.exitCode = 1;
6897
8567
  return;
6898
8568
  }
@@ -6907,6 +8577,12 @@ registerLanguageCommand(program);
6907
8577
  registerAvatarCommand(program);
6908
8578
  registerHeadCommand(program);
6909
8579
  registerVoiceCommand(program);
8580
+ registerAgentsCommand(program);
8581
+ registerConfigCommand(program);
8582
+ registerSetupCommand(program);
8583
+ registerImportCommand(program);
8584
+ registerCompletionCommand(program);
8585
+ enableHelpOnError(program);
6910
8586
  program.parseAsync().catch((e) => {
6911
8587
  if (e instanceof DieError) return;
6912
8588
  process.stderr.write(`