@hcu-lab.me/mcp-device 1.0.9 → 1.0.12

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 (506) hide show
  1. package/PRIVACY.md +21 -0
  2. package/README.md +58 -3
  3. package/SECURITY.md +67 -0
  4. package/config/revoked-approvals.json +1 -0
  5. package/control-plane/config/mcp-servers.example.toml +52 -0
  6. package/control-plane/config/mcp-servers.toml +52 -0
  7. package/control-plane/contracts/device-public-contract-v1.json +733 -0
  8. package/control-plane/scripts/GATEWAY-LICENSE.txt +7 -0
  9. package/control-plane/scripts/account-http.mjs +220 -0
  10. package/control-plane/scripts/account-store.mjs +368 -0
  11. package/control-plane/scripts/admin.mjs +68 -0
  12. package/control-plane/scripts/auth-session.mjs +411 -0
  13. package/control-plane/scripts/authenticated-mcp-wrapper.mjs +1281 -0
  14. package/control-plane/scripts/benchmark-command.mjs +9 -0
  15. package/control-plane/scripts/benchmark-mcp-catalog.mjs +174 -0
  16. package/control-plane/scripts/catalog-budget.mjs +87 -0
  17. package/control-plane/scripts/check-device-public-contract.mjs +20 -0
  18. package/control-plane/scripts/custom-tools/index.mjs +221 -0
  19. package/control-plane/scripts/custom-tools/path-utils.mjs +117 -0
  20. package/control-plane/scripts/custom-tools/response-utils.mjs +34 -0
  21. package/control-plane/scripts/dashboard-http.mjs +598 -0
  22. package/control-plane/scripts/device-access-policy.mjs +205 -0
  23. package/control-plane/scripts/device-admin.mjs +43 -0
  24. package/control-plane/scripts/device-audit.mjs +63 -0
  25. package/control-plane/scripts/device-broker.mjs +1461 -0
  26. package/control-plane/scripts/device-execution-tool-definitions.mjs +217 -0
  27. package/control-plane/scripts/device-inventory.mjs +128 -0
  28. package/control-plane/scripts/device-pairing-http.mjs +109 -0
  29. package/control-plane/scripts/device-pairing-store.mjs +245 -0
  30. package/control-plane/scripts/device-public-contract.mjs +165 -0
  31. package/control-plane/scripts/device-release.mjs +95 -0
  32. package/control-plane/scripts/device-secure-transport.mjs +128 -0
  33. package/control-plane/scripts/device-store.mjs +283 -0
  34. package/control-plane/scripts/device-usage.mjs +657 -0
  35. package/control-plane/scripts/embedded-device.mjs +149 -0
  36. package/control-plane/scripts/enduser-ui.mjs +45 -0
  37. package/control-plane/scripts/external-tool-broker.mjs +179 -0
  38. package/control-plane/scripts/oauth-authorization-server.mjs +589 -0
  39. package/control-plane/scripts/operator-dashboard-http.mjs +81 -0
  40. package/control-plane/scripts/project-inspection.mjs +227 -0
  41. package/control-plane/scripts/projects/project-id.mjs +69 -0
  42. package/control-plane/scripts/projects/trusted-roots-projects.mjs +375 -0
  43. package/control-plane/scripts/prompts/index.mjs +60 -0
  44. package/control-plane/scripts/remote-process-sessions.mjs +78 -0
  45. package/control-plane/scripts/remote-tool-result.mjs +9 -0
  46. package/control-plane/scripts/resources/index.mjs +166 -0
  47. package/control-plane/scripts/runtime-profile.mjs +54 -0
  48. package/control-plane/scripts/shell-tool-descriptor.mjs +17 -0
  49. package/control-plane/scripts/skill-source-safety.mjs +46 -0
  50. package/control-plane/scripts/skills/README.md +70 -0
  51. package/control-plane/scripts/skills/_upstream_licenses/anthropic-THIRD_PARTY_NOTICES.md +405 -0
  52. package/control-plane/scripts/skills/_upstream_licenses/hallmark-LICENSE.txt +21 -0
  53. package/control-plane/scripts/skills/_upstream_licenses/ponytail-LICENSE.txt +21 -0
  54. package/control-plane/scripts/skills/_upstream_licenses/stitch-skills-LICENSE.txt +201 -0
  55. package/control-plane/scripts/skills/_upstream_licenses/superpowers-LICENSE.txt +21 -0
  56. package/control-plane/scripts/skills/algorithmic-art/LICENSE.txt +202 -0
  57. package/control-plane/scripts/skills/algorithmic-art/SKILL.md +405 -0
  58. package/control-plane/scripts/skills/algorithmic-art/templates/generator_template.js +223 -0
  59. package/control-plane/scripts/skills/algorithmic-art/templates/viewer.html +599 -0
  60. package/control-plane/scripts/skills/brainstorming/SKILL.md +285 -0
  61. package/control-plane/scripts/skills/brainstorming/scripts/frame-template.html +213 -0
  62. package/control-plane/scripts/skills/brainstorming/scripts/helper.js +167 -0
  63. package/control-plane/scripts/skills/brainstorming/scripts/server.cjs +723 -0
  64. package/control-plane/scripts/skills/brainstorming/scripts/start-server.sh +209 -0
  65. package/control-plane/scripts/skills/brainstorming/scripts/stop-server.sh +120 -0
  66. package/control-plane/scripts/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
  67. package/control-plane/scripts/skills/brainstorming/visual-companion.md +299 -0
  68. package/control-plane/scripts/skills/brand-guidelines/LICENSE.txt +202 -0
  69. package/control-plane/scripts/skills/brand-guidelines/SKILL.md +73 -0
  70. package/control-plane/scripts/skills/claude-api/LICENSE.txt +202 -0
  71. package/control-plane/scripts/skills/claude-api/SKILL.md +570 -0
  72. package/control-plane/scripts/skills/claude-api/csharp/claude-api/README.md +362 -0
  73. package/control-plane/scripts/skills/claude-api/csharp/claude-api/batches.md +14 -0
  74. package/control-plane/scripts/skills/claude-api/csharp/claude-api/files-api.md +25 -0
  75. package/control-plane/scripts/skills/claude-api/csharp/claude-api/streaming.md +28 -0
  76. package/control-plane/scripts/skills/claude-api/csharp/claude-api/tool-use.md +164 -0
  77. package/control-plane/scripts/skills/claude-api/curl/examples.md +256 -0
  78. package/control-plane/scripts/skills/claude-api/curl/managed-agents.md +371 -0
  79. package/control-plane/scripts/skills/claude-api/go/claude-api/README.md +188 -0
  80. package/control-plane/scripts/skills/claude-api/go/claude-api/files-api.md +23 -0
  81. package/control-plane/scripts/skills/claude-api/go/claude-api/streaming.md +43 -0
  82. package/control-plane/scripts/skills/claude-api/go/claude-api/tool-use.md +220 -0
  83. package/control-plane/scripts/skills/claude-api/go/managed-agents/README.md +564 -0
  84. package/control-plane/scripts/skills/claude-api/java/claude-api/README.md +238 -0
  85. package/control-plane/scripts/skills/claude-api/java/claude-api/files-api.md +27 -0
  86. package/control-plane/scripts/skills/claude-api/java/claude-api/streaming.md +24 -0
  87. package/control-plane/scripts/skills/claude-api/java/claude-api/tool-use.md +228 -0
  88. package/control-plane/scripts/skills/claude-api/java/managed-agents/README.md +443 -0
  89. package/control-plane/scripts/skills/claude-api/php/claude-api/README.md +174 -0
  90. package/control-plane/scripts/skills/claude-api/php/claude-api/batches.md +15 -0
  91. package/control-plane/scripts/skills/claude-api/php/claude-api/files-api.md +13 -0
  92. package/control-plane/scripts/skills/claude-api/php/claude-api/streaming.md +27 -0
  93. package/control-plane/scripts/skills/claude-api/php/claude-api/tool-use.md +253 -0
  94. package/control-plane/scripts/skills/claude-api/php/managed-agents/README.md +443 -0
  95. package/control-plane/scripts/skills/claude-api/python/claude-api/README.md +565 -0
  96. package/control-plane/scripts/skills/claude-api/python/claude-api/batches.md +198 -0
  97. package/control-plane/scripts/skills/claude-api/python/claude-api/files-api.md +170 -0
  98. package/control-plane/scripts/skills/claude-api/python/claude-api/sdk-upgrade.md +286 -0
  99. package/control-plane/scripts/skills/claude-api/python/claude-api/streaming.md +179 -0
  100. package/control-plane/scripts/skills/claude-api/python/claude-api/tool-use.md +627 -0
  101. package/control-plane/scripts/skills/claude-api/python/managed-agents/README.md +335 -0
  102. package/control-plane/scripts/skills/claude-api/ruby/claude-api/README.md +134 -0
  103. package/control-plane/scripts/skills/claude-api/ruby/claude-api/streaming.md +16 -0
  104. package/control-plane/scripts/skills/claude-api/ruby/claude-api/tool-use.md +41 -0
  105. package/control-plane/scripts/skills/claude-api/ruby/managed-agents/README.md +394 -0
  106. package/control-plane/scripts/skills/claude-api/shared/admin-api.md +179 -0
  107. package/control-plane/scripts/skills/claude-api/shared/agent-design.md +101 -0
  108. package/control-plane/scripts/skills/claude-api/shared/anthropic-cli.md +269 -0
  109. package/control-plane/scripts/skills/claude-api/shared/claude-platform-on-aws.md +59 -0
  110. package/control-plane/scripts/skills/claude-api/shared/cost-optimization.md +233 -0
  111. package/control-plane/scripts/skills/claude-api/shared/error-codes.md +262 -0
  112. package/control-plane/scripts/skills/claude-api/shared/live-sources.md +166 -0
  113. package/control-plane/scripts/skills/claude-api/shared/managed-agents-api-reference.md +455 -0
  114. package/control-plane/scripts/skills/claude-api/shared/managed-agents-client-patterns.md +220 -0
  115. package/control-plane/scripts/skills/claude-api/shared/managed-agents-core.md +359 -0
  116. package/control-plane/scripts/skills/claude-api/shared/managed-agents-environments.md +226 -0
  117. package/control-plane/scripts/skills/claude-api/shared/managed-agents-events.md +290 -0
  118. package/control-plane/scripts/skills/claude-api/shared/managed-agents-memory.md +201 -0
  119. package/control-plane/scripts/skills/claude-api/shared/managed-agents-multiagent.md +260 -0
  120. package/control-plane/scripts/skills/claude-api/shared/managed-agents-onboarding.md +82 -0
  121. package/control-plane/scripts/skills/claude-api/shared/managed-agents-outcomes.md +108 -0
  122. package/control-plane/scripts/skills/claude-api/shared/managed-agents-overview.md +77 -0
  123. package/control-plane/scripts/skills/claude-api/shared/managed-agents-scheduled-deployments.md +156 -0
  124. package/control-plane/scripts/skills/claude-api/shared/managed-agents-self-hosted-sandboxes.md +282 -0
  125. package/control-plane/scripts/skills/claude-api/shared/managed-agents-tools.md +504 -0
  126. package/control-plane/scripts/skills/claude-api/shared/managed-agents-webhooks.md +143 -0
  127. package/control-plane/scripts/skills/claude-api/shared/model-migration.md +1872 -0
  128. package/control-plane/scripts/skills/claude-api/shared/models.md +142 -0
  129. package/control-plane/scripts/skills/claude-api/shared/platform-availability.md +52 -0
  130. package/control-plane/scripts/skills/claude-api/shared/prompt-audit.md +223 -0
  131. package/control-plane/scripts/skills/claude-api/shared/prompt-caching.md +292 -0
  132. package/control-plane/scripts/skills/claude-api/shared/token-counting.md +56 -0
  133. package/control-plane/scripts/skills/claude-api/shared/tool-use-concepts.md +526 -0
  134. package/control-plane/scripts/skills/claude-api/typescript/claude-api/README.md +405 -0
  135. package/control-plane/scripts/skills/claude-api/typescript/claude-api/batches.md +106 -0
  136. package/control-plane/scripts/skills/claude-api/typescript/claude-api/files-api.md +98 -0
  137. package/control-plane/scripts/skills/claude-api/typescript/claude-api/streaming.md +178 -0
  138. package/control-plane/scripts/skills/claude-api/typescript/claude-api/tool-use.md +586 -0
  139. package/control-plane/scripts/skills/claude-api/typescript/managed-agents/README.md +359 -0
  140. package/control-plane/scripts/skills/dispatching-parallel-agents/SKILL.md +167 -0
  141. package/control-plane/scripts/skills/enhance-prompt/README.md +34 -0
  142. package/control-plane/scripts/skills/enhance-prompt/SKILL.md +204 -0
  143. package/control-plane/scripts/skills/enhance-prompt/references/KEYWORDS.md +114 -0
  144. package/control-plane/scripts/skills/executing-plans/SKILL.md +371 -0
  145. package/control-plane/scripts/skills/executing-plans/scripts/task-done +52 -0
  146. package/control-plane/scripts/skills/executing-plans/scripts/task-start +28 -0
  147. package/control-plane/scripts/skills/extract-design-md/SKILL.md +358 -0
  148. package/control-plane/scripts/skills/extract-design-md/examples/DESIGN.md +210 -0
  149. package/control-plane/scripts/skills/extract-design-md/references/angular.md +122 -0
  150. package/control-plane/scripts/skills/extract-design-md/references/plain-css.md +161 -0
  151. package/control-plane/scripts/skills/extract-design-md/references/react-tailwind.md +157 -0
  152. package/control-plane/scripts/skills/extract-design-md/references/svelte.md +101 -0
  153. package/control-plane/scripts/skills/extract-design-md/references/vue.md +107 -0
  154. package/control-plane/scripts/skills/finishing-a-development-branch/SKILL.md +225 -0
  155. package/control-plane/scripts/skills/frontend-design/LICENSE.txt +177 -0
  156. package/control-plane/scripts/skills/frontend-design/SKILL.md +71 -0
  157. package/control-plane/scripts/skills/hallmark/SKILL.md +558 -0
  158. package/control-plane/scripts/skills/hallmark/references/anti-patterns.md +418 -0
  159. package/control-plane/scripts/skills/hallmark/references/assets.md +406 -0
  160. package/control-plane/scripts/skills/hallmark/references/color.md +95 -0
  161. package/control-plane/scripts/skills/hallmark/references/component-cookbook.md +263 -0
  162. package/control-plane/scripts/skills/hallmark/references/components/c1-outlined-chip.md +12 -0
  163. package/control-plane/scripts/skills/hallmark/references/components/c2-inline-form-as-cta.md +16 -0
  164. package/control-plane/scripts/skills/hallmark/references/components/c3-typographic-link.md +8 -0
  165. package/control-plane/scripts/skills/hallmark/references/components/c4-sticky-bottom-bar.md +16 -0
  166. package/control-plane/scripts/skills/hallmark/references/components/f1-bento-grid.md +20 -0
  167. package/control-plane/scripts/skills/hallmark/references/components/f2-sticky-scroll-stack.md +20 -0
  168. package/control-plane/scripts/skills/hallmark/references/components/f3-tabular-spec-sheet.md +11 -0
  169. package/control-plane/scripts/skills/hallmark/references/components/f4-step-sequence.md +11 -0
  170. package/control-plane/scripts/skills/hallmark/references/components/f5-annotated-screenshot.md +11 -0
  171. package/control-plane/scripts/skills/hallmark/references/components/f6-product-card-grid.md +41 -0
  172. package/control-plane/scripts/skills/hallmark/references/components/ft1-mast-headed.md +13 -0
  173. package/control-plane/scripts/skills/hallmark/references/components/ft2-inline-rule-single-line.md +10 -0
  174. package/control-plane/scripts/skills/hallmark/references/components/ft3-index-style-category-list.md +12 -0
  175. package/control-plane/scripts/skills/hallmark/references/components/ft4-dense-typographic.md +10 -0
  176. package/control-plane/scripts/skills/hallmark/references/components/ft5-statement.md +21 -0
  177. package/control-plane/scripts/skills/hallmark/references/components/ft6-letter-close.md +19 -0
  178. package/control-plane/scripts/skills/hallmark/references/components/ft7-newsletter-first.md +27 -0
  179. package/control-plane/scripts/skills/hallmark/references/components/ft8-marquee-scroll.md +25 -0
  180. package/control-plane/scripts/skills/hallmark/references/components/h1-marquee.md +15 -0
  181. package/control-plane/scripts/skills/hallmark/references/components/h2-split-diptych.md +15 -0
  182. package/control-plane/scripts/skills/hallmark/references/components/h3-quote-led.md +11 -0
  183. package/control-plane/scripts/skills/hallmark/references/components/h4-stat-led.md +14 -0
  184. package/control-plane/scripts/skills/hallmark/references/components/h5-letter-hero.md +11 -0
  185. package/control-plane/scripts/skills/hallmark/references/components/h6-photographic-fold.md +16 -0
  186. package/control-plane/scripts/skills/hallmark/references/components/h7-demo-video-clipped-by-viewport-edge.md +27 -0
  187. package/control-plane/scripts/skills/hallmark/references/components/h8-mockup-split-browser-framed.md +23 -0
  188. package/control-plane/scripts/skills/hallmark/references/components/h9-custom-illustration-centerpiece.md +27 -0
  189. package/control-plane/scripts/skills/hallmark/references/components/n1-wordmark-2-links.md +12 -0
  190. package/control-plane/scripts/skills/hallmark/references/components/n10-floating-on-scroll-morph.md +19 -0
  191. package/control-plane/scripts/skills/hallmark/references/components/n11-mega-menu.md +40 -0
  192. package/control-plane/scripts/skills/hallmark/references/components/n12-banner-retract.md +34 -0
  193. package/control-plane/scripts/skills/hallmark/references/components/n13-inline-cmdk-pill.md +39 -0
  194. package/control-plane/scripts/skills/hallmark/references/components/n1b-saas-three-section.md +35 -0
  195. package/control-plane/scripts/skills/hallmark/references/components/n2-floating-chip.md +14 -0
  196. package/control-plane/scripts/skills/hallmark/references/components/n3-side-rail.md +14 -0
  197. package/control-plane/scripts/skills/hallmark/references/components/n4-hidden-behind-k.md +9 -0
  198. package/control-plane/scripts/skills/hallmark/references/components/n5-floating-pill.md +28 -0
  199. package/control-plane/scripts/skills/hallmark/references/components/n6-newspaper-masthead.md +24 -0
  200. package/control-plane/scripts/skills/hallmark/references/components/n7-brutal-slab.md +22 -0
  201. package/control-plane/scripts/skills/hallmark/references/components/n8-terminal-command.md +21 -0
  202. package/control-plane/scripts/skills/hallmark/references/components/n9-edge-aligned-minimal.md +17 -0
  203. package/control-plane/scripts/skills/hallmark/references/components/s1-left-margin-numbered.md +15 -0
  204. package/control-plane/scripts/skills/hallmark/references/components/s2-hanging.md +13 -0
  205. package/control-plane/scripts/skills/hallmark/references/components/s3-sticky-pinned.md +19 -0
  206. package/control-plane/scripts/skills/hallmark/references/components/s4-inline-no-break.md +11 -0
  207. package/control-plane/scripts/skills/hallmark/references/components/s5-bottom-anchored.md +13 -0
  208. package/control-plane/scripts/skills/hallmark/references/components/t1-pull-quote-with-marginalia.md +12 -0
  209. package/control-plane/scripts/skills/hallmark/references/components/t2-logo-wall-hairline.md +19 -0
  210. package/control-plane/scripts/skills/hallmark/references/components/t3-single-huge-quote.md +11 -0
  211. package/control-plane/scripts/skills/hallmark/references/components/t4-numbered-stat-strip.md +14 -0
  212. package/control-plane/scripts/skills/hallmark/references/contract.md +25 -0
  213. package/control-plane/scripts/skills/hallmark/references/copy.md +182 -0
  214. package/control-plane/scripts/skills/hallmark/references/custom-craft.md +626 -0
  215. package/control-plane/scripts/skills/hallmark/references/custom-theme.md +367 -0
  216. package/control-plane/scripts/skills/hallmark/references/design-md.md +116 -0
  217. package/control-plane/scripts/skills/hallmark/references/export-formats.md +329 -0
  218. package/control-plane/scripts/skills/hallmark/references/floating-nav.md +89 -0
  219. package/control-plane/scripts/skills/hallmark/references/genres/atmospheric.md +69 -0
  220. package/control-plane/scripts/skills/hallmark/references/genres/editorial.md +72 -0
  221. package/control-plane/scripts/skills/hallmark/references/genres/modern-minimal.md +71 -0
  222. package/control-plane/scripts/skills/hallmark/references/genres/playful.md +70 -0
  223. package/control-plane/scripts/skills/hallmark/references/hero-enrichment.md +475 -0
  224. package/control-plane/scripts/skills/hallmark/references/imagery-kit.md +170 -0
  225. package/control-plane/scripts/skills/hallmark/references/interaction-and-states.md +208 -0
  226. package/control-plane/scripts/skills/hallmark/references/layout-and-space.md +112 -0
  227. package/control-plane/scripts/skills/hallmark/references/macrostructures/01-bento-grid.md +35 -0
  228. package/control-plane/scripts/skills/hallmark/references/macrostructures/02-long-document.md +34 -0
  229. package/control-plane/scripts/skills/hallmark/references/macrostructures/03-marquee-hero.md +31 -0
  230. package/control-plane/scripts/skills/hallmark/references/macrostructures/04-stat-led.md +34 -0
  231. package/control-plane/scripts/skills/hallmark/references/macrostructures/05-workbench.md +32 -0
  232. package/control-plane/scripts/skills/hallmark/references/macrostructures/06-conversational-faq.md +33 -0
  233. package/control-plane/scripts/skills/hallmark/references/macrostructures/07-manifesto.md +32 -0
  234. package/control-plane/scripts/skills/hallmark/references/macrostructures/08-photographic.md +34 -0
  235. package/control-plane/scripts/skills/hallmark/references/macrostructures/09-quote-led.md +32 -0
  236. package/control-plane/scripts/skills/hallmark/references/macrostructures/10-specimen.md +32 -0
  237. package/control-plane/scripts/skills/hallmark/references/macrostructures/11-catalogue.md +23 -0
  238. package/control-plane/scripts/skills/hallmark/references/macrostructures/12-letter.md +23 -0
  239. package/control-plane/scripts/skills/hallmark/references/macrostructures/13-index-first.md +23 -0
  240. package/control-plane/scripts/skills/hallmark/references/macrostructures/14-narrative-workflow.md +23 -0
  241. package/control-plane/scripts/skills/hallmark/references/macrostructures/15-split-studio.md +23 -0
  242. package/control-plane/scripts/skills/hallmark/references/macrostructures/16-feature-stack.md +23 -0
  243. package/control-plane/scripts/skills/hallmark/references/macrostructures/17-type-specimen.md +23 -0
  244. package/control-plane/scripts/skills/hallmark/references/macrostructures/18-portfolio-grid.md +23 -0
  245. package/control-plane/scripts/skills/hallmark/references/macrostructures/19-map-diagram.md +23 -0
  246. package/control-plane/scripts/skills/hallmark/references/macrostructures/20-ecosystem-index.md +23 -0
  247. package/control-plane/scripts/skills/hallmark/references/macrostructures/21-component-playground.md +23 -0
  248. package/control-plane/scripts/skills/hallmark/references/macrostructures.md +89 -0
  249. package/control-plane/scripts/skills/hallmark/references/microinteractions.md +258 -0
  250. package/control-plane/scripts/skills/hallmark/references/motion.md +109 -0
  251. package/control-plane/scripts/skills/hallmark/references/preview-examples.md +49 -0
  252. package/control-plane/scripts/skills/hallmark/references/responsive.md +138 -0
  253. package/control-plane/scripts/skills/hallmark/references/slop-test.md +192 -0
  254. package/control-plane/scripts/skills/hallmark/references/structure.md +160 -0
  255. package/control-plane/scripts/skills/hallmark/references/study.md +509 -0
  256. package/control-plane/scripts/skills/hallmark/references/themes/carnival.md +301 -0
  257. package/control-plane/scripts/skills/hallmark/references/themes/cobalt.md +146 -0
  258. package/control-plane/scripts/skills/hallmark/references/themes/grid.md +161 -0
  259. package/control-plane/scripts/skills/hallmark/references/themes/hum.md +403 -0
  260. package/control-plane/scripts/skills/hallmark/references/themes/lumen.md +478 -0
  261. package/control-plane/scripts/skills/hallmark/references/typography.md +243 -0
  262. package/control-plane/scripts/skills/hallmark/references/upstream/recipes.md +186 -0
  263. package/control-plane/scripts/skills/hallmark/references/upstream/study-examples.md +176 -0
  264. package/control-plane/scripts/skills/hallmark/references/upstream/tokens.css +1221 -0
  265. package/control-plane/scripts/skills/hallmark/references/verbs/audit.md +25 -0
  266. package/control-plane/scripts/skills/hallmark/references/verbs/redesign.md +269 -0
  267. package/control-plane/scripts/skills/human-comms/SKILL.md +29 -0
  268. package/control-plane/scripts/skills/index.mjs +432 -0
  269. package/control-plane/scripts/skills/internal-comms/LICENSE.txt +202 -0
  270. package/control-plane/scripts/skills/internal-comms/SKILL.md +32 -0
  271. package/control-plane/scripts/skills/internal-comms/examples/3p-updates.md +47 -0
  272. package/control-plane/scripts/skills/internal-comms/examples/company-newsletter.md +65 -0
  273. package/control-plane/scripts/skills/internal-comms/examples/faq-answers.md +30 -0
  274. package/control-plane/scripts/skills/internal-comms/examples/general-comms.md +16 -0
  275. package/control-plane/scripts/skills/mcp-adapter.mjs +94 -0
  276. package/control-plane/scripts/skills/mcp-builder/LICENSE.txt +202 -0
  277. package/control-plane/scripts/skills/mcp-builder/SKILL.md +236 -0
  278. package/control-plane/scripts/skills/mcp-builder/reference/evaluation.md +602 -0
  279. package/control-plane/scripts/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
  280. package/control-plane/scripts/skills/mcp-builder/reference/node_mcp_server.md +970 -0
  281. package/control-plane/scripts/skills/mcp-builder/reference/python_mcp_server.md +719 -0
  282. package/control-plane/scripts/skills/mcp-builder/scripts/connections.py +151 -0
  283. package/control-plane/scripts/skills/mcp-builder/scripts/evaluation.py +373 -0
  284. package/control-plane/scripts/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  285. package/control-plane/scripts/skills/mcp-builder/scripts/requirements.txt +2 -0
  286. package/control-plane/scripts/skills/ponytail/SKILL.md +120 -0
  287. package/control-plane/scripts/skills/ponytail-audit/SKILL.md +41 -0
  288. package/control-plane/scripts/skills/ponytail-debt/SKILL.md +44 -0
  289. package/control-plane/scripts/skills/ponytail-gain/SKILL.md +50 -0
  290. package/control-plane/scripts/skills/ponytail-help/SKILL.md +71 -0
  291. package/control-plane/scripts/skills/ponytail-review/SKILL.md +57 -0
  292. package/control-plane/scripts/skills/receiving-code-review/SKILL.md +205 -0
  293. package/control-plane/scripts/skills/requesting-code-review/SKILL.md +95 -0
  294. package/control-plane/scripts/skills/requesting-code-review/code-reviewer.md +198 -0
  295. package/control-plane/scripts/skills/skill-creator/LICENSE.txt +202 -0
  296. package/control-plane/scripts/skills/skill-creator/SKILL.md +485 -0
  297. package/control-plane/scripts/skills/skill-creator/agents/analyzer.md +274 -0
  298. package/control-plane/scripts/skills/skill-creator/agents/comparator.md +202 -0
  299. package/control-plane/scripts/skills/skill-creator/agents/grader.md +223 -0
  300. package/control-plane/scripts/skills/skill-creator/assets/eval_review.html +146 -0
  301. package/control-plane/scripts/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  302. package/control-plane/scripts/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  303. package/control-plane/scripts/skills/skill-creator/references/schemas.md +430 -0
  304. package/control-plane/scripts/skills/skill-creator/scripts/__init__.py +0 -0
  305. package/control-plane/scripts/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  306. package/control-plane/scripts/skills/skill-creator/scripts/generate_report.py +326 -0
  307. package/control-plane/scripts/skills/skill-creator/scripts/improve_description.py +247 -0
  308. package/control-plane/scripts/skills/skill-creator/scripts/package_skill.py +136 -0
  309. package/control-plane/scripts/skills/skill-creator/scripts/quick_validate.py +103 -0
  310. package/control-plane/scripts/skills/skill-creator/scripts/run_eval.py +310 -0
  311. package/control-plane/scripts/skills/skill-creator/scripts/run_loop.py +328 -0
  312. package/control-plane/scripts/skills/skill-creator/scripts/utils.py +47 -0
  313. package/control-plane/scripts/skills/slack-gif-creator/LICENSE.txt +202 -0
  314. package/control-plane/scripts/skills/slack-gif-creator/SKILL.md +254 -0
  315. package/control-plane/scripts/skills/slack-gif-creator/core/easing.py +234 -0
  316. package/control-plane/scripts/skills/slack-gif-creator/core/frame_composer.py +176 -0
  317. package/control-plane/scripts/skills/slack-gif-creator/core/gif_builder.py +269 -0
  318. package/control-plane/scripts/skills/slack-gif-creator/core/validators.py +136 -0
  319. package/control-plane/scripts/skills/slack-gif-creator/requirements.txt +4 -0
  320. package/control-plane/scripts/skills/sources.json +401 -0
  321. package/control-plane/scripts/skills/sources.lock.json +416 -0
  322. package/control-plane/scripts/skills/subagent-driven-development/SKILL.md +570 -0
  323. package/control-plane/scripts/skills/subagent-driven-development/implementer-prompt.md +154 -0
  324. package/control-plane/scripts/skills/subagent-driven-development/re-review-prompt.md +115 -0
  325. package/control-plane/scripts/skills/subagent-driven-development/scripts/review-package +53 -0
  326. package/control-plane/scripts/skills/subagent-driven-development/scripts/sdd-workspace +82 -0
  327. package/control-plane/scripts/skills/subagent-driven-development/scripts/task-brief +43 -0
  328. package/control-plane/scripts/skills/subagent-driven-development/task-reviewer-prompt.md +207 -0
  329. package/control-plane/scripts/skills/systematic-debugging/CREATION-LOG.md +119 -0
  330. package/control-plane/scripts/skills/systematic-debugging/SKILL.md +283 -0
  331. package/control-plane/scripts/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  332. package/control-plane/scripts/skills/systematic-debugging/condition-based-waiting.md +115 -0
  333. package/control-plane/scripts/skills/systematic-debugging/defense-in-depth.md +122 -0
  334. package/control-plane/scripts/skills/systematic-debugging/find-polluter.sh +72 -0
  335. package/control-plane/scripts/skills/systematic-debugging/root-cause-tracing.md +169 -0
  336. package/control-plane/scripts/skills/systematic-debugging/test-academic.md +14 -0
  337. package/control-plane/scripts/skills/systematic-debugging/test-pressure-1.md +58 -0
  338. package/control-plane/scripts/skills/systematic-debugging/test-pressure-2.md +68 -0
  339. package/control-plane/scripts/skills/systematic-debugging/test-pressure-3.md +69 -0
  340. package/control-plane/scripts/skills/test-driven-development/SKILL.md +330 -0
  341. package/control-plane/scripts/skills/test-driven-development/writing-good-tests.md +198 -0
  342. package/control-plane/scripts/skills/theme-factory/LICENSE.txt +202 -0
  343. package/control-plane/scripts/skills/theme-factory/SKILL.md +59 -0
  344. package/control-plane/scripts/skills/theme-factory/theme-showcase.pdf +0 -0
  345. package/control-plane/scripts/skills/theme-factory/themes/arctic-frost.md +19 -0
  346. package/control-plane/scripts/skills/theme-factory/themes/botanical-garden.md +19 -0
  347. package/control-plane/scripts/skills/theme-factory/themes/desert-rose.md +19 -0
  348. package/control-plane/scripts/skills/theme-factory/themes/forest-canopy.md +19 -0
  349. package/control-plane/scripts/skills/theme-factory/themes/golden-hour.md +19 -0
  350. package/control-plane/scripts/skills/theme-factory/themes/midnight-galaxy.md +19 -0
  351. package/control-plane/scripts/skills/theme-factory/themes/modern-minimalist.md +19 -0
  352. package/control-plane/scripts/skills/theme-factory/themes/ocean-depths.md +19 -0
  353. package/control-plane/scripts/skills/theme-factory/themes/sunset-boulevard.md +19 -0
  354. package/control-plane/scripts/skills/theme-factory/themes/tech-innovation.md +19 -0
  355. package/control-plane/scripts/skills/using-git-worktrees/SKILL.md +167 -0
  356. package/control-plane/scripts/skills/verification-before-completion/SKILL.md +120 -0
  357. package/control-plane/scripts/skills/web-artifacts-builder/LICENSE.txt +202 -0
  358. package/control-plane/scripts/skills/web-artifacts-builder/SKILL.md +74 -0
  359. package/control-plane/scripts/skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
  360. package/control-plane/scripts/skills/web-artifacts-builder/scripts/init-artifact.sh +322 -0
  361. package/control-plane/scripts/skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  362. package/control-plane/scripts/skills/webapp-testing/LICENSE.txt +202 -0
  363. package/control-plane/scripts/skills/webapp-testing/SKILL.md +96 -0
  364. package/control-plane/scripts/skills/webapp-testing/examples/console_logging.py +35 -0
  365. package/control-plane/scripts/skills/webapp-testing/examples/element_discovery.py +40 -0
  366. package/control-plane/scripts/skills/webapp-testing/examples/static_html_automation.py +33 -0
  367. package/control-plane/scripts/skills/webapp-testing/scripts/with_server.py +106 -0
  368. package/control-plane/scripts/skills/writing-plans/SKILL.md +192 -0
  369. package/control-plane/scripts/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
  370. package/control-plane/scripts/skills/writing-skills/SKILL.md +681 -0
  371. package/control-plane/scripts/skills/writing-skills/anthropic-best-practices.md +1150 -0
  372. package/control-plane/scripts/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
  373. package/control-plane/scripts/skills/writing-skills/graphviz-conventions.dot +172 -0
  374. package/control-plane/scripts/skills/writing-skills/persuasion-principles.md +187 -0
  375. package/control-plane/scripts/skills/writing-skills/render-graphs.js +169 -0
  376. package/control-plane/scripts/skills/writing-skills/testing-skills-with-subagents.md +384 -0
  377. package/control-plane/scripts/smoke-mcp-schemas.mjs +30 -0
  378. package/control-plane/scripts/surface-config.mjs +45 -0
  379. package/control-plane/scripts/sync-skills.mjs +370 -0
  380. package/control-plane/scripts/tool-metrics.mjs +74 -0
  381. package/control-plane/scripts/tool-risk.mjs +156 -0
  382. package/control-plane/scripts/tool-surface-stability.mjs +38 -0
  383. package/control-plane/scripts/upstreams/catalog-cache.mjs +28 -0
  384. package/control-plane/scripts/upstreams/config.mjs +158 -0
  385. package/control-plane/scripts/upstreams/diagnostics.mjs +21 -0
  386. package/control-plane/scripts/upstreams/http-client.mjs +67 -0
  387. package/control-plane/scripts/upstreams/manager.mjs +535 -0
  388. package/control-plane/scripts/upstreams/names.mjs +55 -0
  389. package/control-plane/scripts/upstreams/presets.mjs +60 -0
  390. package/control-plane/scripts/upstreams/resource-uri.mjs +29 -0
  391. package/control-plane/scripts/upstreams/stdio-client.mjs +73 -0
  392. package/control-plane/scripts/workspace-registry.mjs +147 -0
  393. package/dist/context/authorization.d.ts +5 -0
  394. package/dist/context/authorization.js +70 -0
  395. package/dist/context/capture.d.ts +46 -0
  396. package/dist/context/capture.js +187 -0
  397. package/dist/context/cli.d.ts +47 -0
  398. package/dist/context/cli.js +287 -0
  399. package/dist/context/device-adapter.d.ts +102 -0
  400. package/dist/context/device-adapter.js +79 -0
  401. package/dist/context/gateway.d.ts +354 -0
  402. package/dist/context/gateway.js +50 -0
  403. package/dist/context/graph.d.ts +63 -0
  404. package/dist/context/graph.js +214 -0
  405. package/dist/context/importer.d.ts +8 -0
  406. package/dist/context/importer.js +69 -0
  407. package/dist/context/indexer.d.ts +14 -0
  408. package/dist/context/indexer.js +57 -0
  409. package/dist/context/migrations/index.d.ts +4 -0
  410. package/dist/context/migrations/index.js +87 -0
  411. package/dist/context/redact.d.ts +15 -0
  412. package/dist/context/redact.js +43 -0
  413. package/dist/context/repositories.d.ts +9 -0
  414. package/dist/context/repositories.js +45 -0
  415. package/dist/context/search.d.ts +63 -0
  416. package/dist/context/search.js +207 -0
  417. package/dist/context/service.d.ts +278 -0
  418. package/dist/context/service.js +160 -0
  419. package/dist/context/store.d.ts +134 -0
  420. package/dist/context/store.js +722 -0
  421. package/dist/context/text.d.ts +4 -0
  422. package/dist/context/text.js +14 -0
  423. package/dist/context/tool-contract.d.ts +534 -0
  424. package/dist/context/tool-contract.js +45 -0
  425. package/dist/device/core.d.ts +29 -0
  426. package/dist/device/core.js +66 -0
  427. package/dist/device/device.d.ts +5 -0
  428. package/dist/device/device.js +94 -37
  429. package/dist/device/gateway-channel.d.ts +8 -1
  430. package/dist/device/gateway-channel.js +51 -3
  431. package/dist/device/gateway-tool-adapter.d.ts +11 -3
  432. package/dist/device/gateway-tool-adapter.js +141 -98
  433. package/dist/device/official-trust.d.ts +12 -0
  434. package/dist/device/official-trust.js +25 -1
  435. package/dist/device/runtime-owner.js +9 -1
  436. package/dist/distribution.d.ts +4 -0
  437. package/dist/distribution.js +8 -0
  438. package/dist/handlers/filesystem-handlers.js +53 -37
  439. package/dist/handlers/search-handlers.d.ts +1 -0
  440. package/dist/handlers/search-handlers.js +51 -1
  441. package/dist/log-palace/cli.d.ts +7 -0
  442. package/dist/log-palace/cli.js +89 -0
  443. package/dist/log-palace/formats.d.ts +26 -0
  444. package/dist/log-palace/formats.js +126 -0
  445. package/dist/log-palace/store.d.ts +129 -0
  446. package/dist/log-palace/store.js +856 -0
  447. package/dist/mcp-device.d.ts +1 -1
  448. package/dist/mcp-device.js +28 -6
  449. package/dist/npm-scripts/remote.js +1 -0
  450. package/dist/platform/activity-journal.d.ts +16 -0
  451. package/dist/platform/activity-journal.js +68 -0
  452. package/dist/platform/cli.d.ts +1 -0
  453. package/dist/platform/cli.js +300 -0
  454. package/dist/platform/coordination-lock.d.ts +45 -0
  455. package/dist/platform/coordination-lock.js +233 -0
  456. package/dist/platform/device-runtime.d.ts +16 -0
  457. package/dist/platform/device-runtime.js +83 -0
  458. package/dist/platform/knowledge-contract.d.ts +46 -0
  459. package/dist/platform/knowledge-contract.js +1 -0
  460. package/dist/platform/knowledge-mcp.d.ts +29 -0
  461. package/dist/platform/knowledge-mcp.js +95 -0
  462. package/dist/platform/knowledge-router.d.ts +64 -0
  463. package/dist/platform/knowledge-router.js +320 -0
  464. package/dist/platform/plugin-child.d.ts +1 -0
  465. package/dist/platform/plugin-child.js +115 -0
  466. package/dist/platform/plugin-contract.d.ts +76 -0
  467. package/dist/platform/plugin-contract.js +53 -0
  468. package/dist/platform/plugin-driver.d.ts +8 -0
  469. package/dist/platform/plugin-driver.js +443 -0
  470. package/dist/platform/plugin-host.d.ts +88 -0
  471. package/dist/platform/plugin-host.js +817 -0
  472. package/dist/platform/plugin-policy.d.ts +3 -0
  473. package/dist/platform/plugin-policy.js +29 -0
  474. package/dist/platform/plugin-services.d.ts +14 -0
  475. package/dist/platform/plugin-services.js +32 -0
  476. package/dist/platform/process-identity.d.ts +9 -0
  477. package/dist/platform/process-identity.js +68 -0
  478. package/dist/platform/runtime-lease.d.ts +4 -0
  479. package/dist/platform/runtime-lease.js +58 -0
  480. package/dist/platform/runtime-root.d.ts +9 -0
  481. package/dist/platform/runtime-root.js +61 -0
  482. package/dist/platform/state-backup.d.ts +92 -0
  483. package/dist/platform/state-backup.js +399 -0
  484. package/dist/plugins/reference/plugin.d.ts +3 -0
  485. package/dist/plugins/reference/plugin.js +13 -0
  486. package/dist/search-manager.d.ts +6 -0
  487. package/dist/search-manager.js +123 -0
  488. package/dist/server.d.ts +13 -0
  489. package/dist/server.js +7 -3
  490. package/dist/terminal-manager.d.ts +16 -0
  491. package/dist/terminal-manager.js +137 -42
  492. package/dist/tool-dispatcher.d.ts +11 -0
  493. package/dist/tool-dispatcher.js +228 -0
  494. package/dist/tools/edit.js +72 -1
  495. package/dist/tools/filesystem.d.ts +1 -1
  496. package/dist/tools/filesystem.js +2 -2
  497. package/dist/tools/improved-process-tools.js +91 -108
  498. package/dist/tools/schemas.d.ts +94 -2
  499. package/dist/tools/schemas.js +20 -6
  500. package/dist/types.d.ts +8 -0
  501. package/dist/utils/output-budget.d.ts +6 -0
  502. package/dist/utils/output-budget.js +15 -0
  503. package/dist/version.d.ts +1 -1
  504. package/dist/version.js +1 -1
  505. package/package.json +29 -6
  506. package/skills/mcp-device-context/SKILL.md +40 -0
@@ -0,0 +1,245 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import crypto from 'node:crypto';
4
+ import { DatabaseSync } from 'node:sqlite';
5
+
6
+ import { normalizeEd25519PublicKey } from './device-store.mjs';
7
+
8
+ const DEVICE_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
9
+ const USER_CODE_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
10
+
11
+ function requiredText(value, label, max = 512) {
12
+ const text = String(value ?? '').trim();
13
+ if (!text || text.length > max) throw new Error(`${label} is required and must be at most ${max} characters.`);
14
+ return text;
15
+ }
16
+
17
+ function normalizeDeviceId(value) {
18
+ const deviceId = requiredText(value, 'device_id', 64);
19
+ if (!DEVICE_ID_PATTERN.test(deviceId)) throw new Error('Invalid device_id.');
20
+ return deviceId;
21
+ }
22
+
23
+ function normalizeCodeChallenge(value) {
24
+ const challenge = requiredText(value, 'code_challenge', 128);
25
+ if (!/^[A-Za-z0-9_-]{43,128}$/.test(challenge)) throw new Error('Invalid PKCE code_challenge.');
26
+ return challenge;
27
+ }
28
+
29
+ function sha256(value) {
30
+ return crypto.createHash('sha256').update(String(value), 'utf8').digest('base64url');
31
+ }
32
+
33
+ function publicKeyFingerprint(publicKeyPem) {
34
+ return sha256(normalizeEd25519PublicKey(publicKeyPem));
35
+ }
36
+
37
+ function generateUserCode() {
38
+ const bytes = crypto.randomBytes(8);
39
+ let code = '';
40
+ for (let i = 0; i < 8; i += 1) code += USER_CODE_ALPHABET[bytes[i] % USER_CODE_ALPHABET.length];
41
+ return `${code.slice(0, 4)}-${code.slice(4)}`;
42
+ }
43
+
44
+ function statusFromRow(row, nowMs) {
45
+ if (!row) return null;
46
+ const expired = Number(row.expires_at) < nowMs;
47
+ let status = 'pending';
48
+ if (expired) status = 'expired';
49
+ else if (row.grant_consumed_at) status = 'consumed';
50
+ else if (row.approved_at) status = 'approved';
51
+ return {
52
+ userCode: row.user_code,
53
+ deviceId: row.device_id,
54
+ deviceName: row.device_name,
55
+ status,
56
+ expiresAt: Number(row.expires_at),
57
+ approvedAt: row.approved_at ? Number(row.approved_at) : null,
58
+ accountId: row.owner_account_id || null,
59
+ accountLabel: row.account_label || null
60
+ };
61
+ }
62
+
63
+ export function createDevicePairingStore({
64
+ dbPath,
65
+ now = () => Date.now(),
66
+ ttlMs = 10 * 60_000,
67
+ pollIntervalSec = 2
68
+ } = {}) {
69
+ if (!dbPath) throw new Error('dbPath is required for device pairing store.');
70
+ if (!Number.isInteger(ttlMs) || ttlMs < 60_000 || ttlMs > 60 * 60_000) throw new Error('Pairing ttlMs must be between 60000 and 3600000.');
71
+ if (!Number.isInteger(pollIntervalSec) || pollIntervalSec < 1 || pollIntervalSec > 30) throw new Error('Pairing pollIntervalSec must be between 1 and 30.');
72
+
73
+ const resolved = path.resolve(dbPath);
74
+ fs.mkdirSync(path.dirname(resolved), { recursive: true });
75
+ const db = new DatabaseSync(resolved);
76
+ db.exec(`
77
+ PRAGMA journal_mode = WAL;
78
+ PRAGMA synchronous = NORMAL;
79
+ PRAGMA busy_timeout = 5000;
80
+ CREATE TABLE IF NOT EXISTS device_pairings (
81
+ device_code TEXT PRIMARY KEY,
82
+ user_code TEXT NOT NULL UNIQUE,
83
+ client_id TEXT NOT NULL,
84
+ device_id TEXT NOT NULL,
85
+ device_name TEXT NOT NULL,
86
+ public_key_fingerprint TEXT NOT NULL,
87
+ code_challenge TEXT NOT NULL,
88
+ created_at INTEGER NOT NULL,
89
+ expires_at INTEGER NOT NULL,
90
+ approved_at INTEGER,
91
+ owner_account_id TEXT,
92
+ account_label TEXT,
93
+ grant_hash TEXT UNIQUE,
94
+ grant_issued_at INTEGER,
95
+ grant_consumed_at INTEGER
96
+ );
97
+ CREATE INDEX IF NOT EXISTS device_pairings_user_code_idx ON device_pairings(user_code);
98
+ CREATE INDEX IF NOT EXISTS device_pairings_grant_hash_idx ON device_pairings(grant_hash);
99
+ `);
100
+
101
+ const columns = db.prepare('PRAGMA table_info(device_pairings)').all();
102
+ if (!columns.some(column => column.name === 'owner_account_id')) {
103
+ db.exec('ALTER TABLE device_pairings ADD COLUMN owner_account_id TEXT');
104
+ }
105
+
106
+ const getByUserCodeStatement = db.prepare('SELECT * FROM device_pairings WHERE user_code = ?');
107
+ const getByDeviceCodeStatement = db.prepare('SELECT * FROM device_pairings WHERE device_code = ?');
108
+ const getByGrantHashStatement = db.prepare('SELECT * FROM device_pairings WHERE grant_hash = ?');
109
+ const insertStatement = db.prepare(`
110
+ INSERT INTO device_pairings (
111
+ device_code, user_code, client_id, device_id, device_name,
112
+ public_key_fingerprint, code_challenge, created_at, expires_at
113
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
114
+ `);
115
+ const approveStatement = db.prepare(`
116
+ UPDATE device_pairings
117
+ SET approved_at = ?, owner_account_id = ?, account_label = ?
118
+ WHERE user_code = ? AND approved_at IS NULL
119
+ `);
120
+ const grantStatement = db.prepare(`
121
+ UPDATE device_pairings
122
+ SET grant_hash = ?, grant_issued_at = ?
123
+ WHERE device_code = ? AND grant_hash IS NULL
124
+ `);
125
+ const consumeStatement = db.prepare(`
126
+ UPDATE device_pairings
127
+ SET grant_consumed_at = ?
128
+ WHERE grant_hash = ? AND grant_consumed_at IS NULL
129
+ `);
130
+
131
+ function start({ clientId, deviceId, deviceName, publicKeyPem, codeChallenge }) {
132
+ const normalizedClientId = requiredText(clientId, 'client_id', 128);
133
+ const normalizedDeviceId = normalizeDeviceId(deviceId);
134
+ const normalizedDeviceName = requiredText(deviceName, 'device_name', 128);
135
+ const fingerprint = publicKeyFingerprint(publicKeyPem);
136
+ const normalizedChallenge = normalizeCodeChallenge(codeChallenge);
137
+ const createdAt = Number(now());
138
+ const expiresAt = createdAt + ttlMs;
139
+ const deviceCode = crypto.randomBytes(32).toString('base64url');
140
+
141
+ let userCode;
142
+ for (let attempt = 0; attempt < 8; attempt += 1) {
143
+ const candidate = generateUserCode();
144
+ try {
145
+ insertStatement.run(
146
+ deviceCode,
147
+ candidate,
148
+ normalizedClientId,
149
+ normalizedDeviceId,
150
+ normalizedDeviceName,
151
+ fingerprint,
152
+ normalizedChallenge,
153
+ createdAt,
154
+ expiresAt
155
+ );
156
+ userCode = candidate;
157
+ break;
158
+ } catch (error) {
159
+ if (!String(error?.message || '').toLowerCase().includes('unique')) throw error;
160
+ }
161
+ }
162
+ if (!userCode) throw new Error('Unable to allocate a unique device pairing code.');
163
+
164
+ return {
165
+ deviceCode,
166
+ userCode,
167
+ expiresIn: Math.floor(ttlMs / 1000),
168
+ interval: pollIntervalSec
169
+ };
170
+ }
171
+
172
+ function getStatusByUserCode(userCode) {
173
+ const normalized = requiredText(userCode, 'user_code', 16).toUpperCase();
174
+ const row = getByUserCodeStatement.get(normalized);
175
+ if (!row) throw new Error('Unknown pairing code.');
176
+ return statusFromRow(row, Number(now()));
177
+ }
178
+
179
+ function approve({ userCode, accountId, accountLabel }) {
180
+ const normalized = requiredText(userCode, 'user_code', 16).toUpperCase();
181
+ const owner = requiredText(accountId, 'account_id', 64);
182
+ const label = requiredText(accountLabel, 'account_label', 128);
183
+ const row = getByUserCodeStatement.get(normalized);
184
+ if (!row) throw new Error('Unknown pairing code.');
185
+ const nowMs = Number(now());
186
+ if (Number(row.expires_at) < nowMs) throw new Error('Pairing code expired.');
187
+ if (row.grant_consumed_at) throw new Error('Pairing code was already consumed.');
188
+ if (!row.approved_at) approveStatement.run(nowMs, owner, label, normalized);
189
+ const updated = getByUserCodeStatement.get(normalized);
190
+ return statusFromRow(updated, nowMs);
191
+ }
192
+
193
+ function poll({ deviceCode, clientId, codeVerifier }) {
194
+ const normalizedDeviceCode = requiredText(deviceCode, 'device_code', 128);
195
+ const normalizedClientId = requiredText(clientId, 'client_id', 128);
196
+ const verifier = requiredText(codeVerifier, 'code_verifier', 256);
197
+ const row = getByDeviceCodeStatement.get(normalizedDeviceCode);
198
+ if (!row) throw new Error('Unknown device code.');
199
+ const nowMs = Number(now());
200
+ if (Number(row.expires_at) < nowMs) throw new Error('Device pairing code expired.');
201
+ if (row.client_id !== normalizedClientId) throw new Error('Device code was not issued to this client.');
202
+ if (sha256(verifier) !== row.code_challenge) throw new Error('PKCE verifier does not match device pairing request.');
203
+ if (!row.approved_at) return { status: 'authorization_pending' };
204
+ if (row.grant_consumed_at) throw new Error('Pairing enrollment grant was already consumed.');
205
+ if (row.grant_hash) throw new Error('Pairing enrollment grant was already issued.');
206
+
207
+ const enrollmentGrant = crypto.randomBytes(32).toString('base64url');
208
+ const grantHash = sha256(enrollmentGrant);
209
+ const changed = grantStatement.run(grantHash, nowMs, normalizedDeviceCode);
210
+ if (Number(changed.changes) !== 1) throw new Error('Pairing enrollment grant was already issued.');
211
+ return {
212
+ status: 'approved',
213
+ enrollmentGrant,
214
+ deviceId: row.device_id,
215
+ account: { connected: true, account_id: row.owner_account_id, label: row.account_label }
216
+ };
217
+ }
218
+
219
+ function consumeGrant({ enrollmentGrant, deviceId, publicKeyPem }) {
220
+ const grant = requiredText(enrollmentGrant, 'enrollment_grant', 256);
221
+ const normalizedDeviceId = normalizeDeviceId(deviceId);
222
+ const fingerprint = publicKeyFingerprint(publicKeyPem);
223
+ const grantHash = sha256(grant);
224
+ const row = getByGrantHashStatement.get(grantHash);
225
+ if (!row) throw new Error('Invalid enrollment grant.');
226
+ const nowMs = Number(now());
227
+ if (Number(row.expires_at) < nowMs) throw new Error('Enrollment grant expired.');
228
+ if (row.grant_consumed_at) throw new Error('Enrollment grant was already consumed.');
229
+ if (row.device_id !== normalizedDeviceId) throw new Error('Enrollment grant is bound to a different device.');
230
+ if (row.public_key_fingerprint !== fingerprint) throw new Error('Enrollment grant is bound to a different device key.');
231
+ const changed = consumeStatement.run(nowMs, grantHash);
232
+ if (Number(changed.changes) !== 1) throw new Error('Enrollment grant was already consumed.');
233
+ return {
234
+ deviceId: row.device_id,
235
+ deviceName: row.device_name,
236
+ account: { connected: true, account_id: row.owner_account_id, label: row.account_label }
237
+ };
238
+ }
239
+
240
+ function close() {
241
+ db.close();
242
+ }
243
+
244
+ return { start, getStatusByUserCode, approve, poll, consumeGrant, close };
245
+ }
@@ -0,0 +1,165 @@
1
+ import { DEVICE_PUBLIC_TOOL_NAMES, listStaticDevicePublicTools } from './device-execution-tool-definitions.mjs';
2
+
3
+ function clone(value) {
4
+ return value === undefined ? undefined : JSON.parse(JSON.stringify(value));
5
+ }
6
+
7
+ function toolContract(tool) {
8
+ return {
9
+ name: tool.name,
10
+ description: tool.description,
11
+ inputSchema: clone(tool.inputSchema),
12
+ ...(tool.outputSchema ? { outputSchema: clone(tool.outputSchema) } : {}),
13
+ ...(tool.annotations ? { annotations: clone(tool.annotations) } : {}),
14
+ ...(tool._meta ? { _meta: clone(tool._meta) } : {})
15
+ };
16
+ }
17
+
18
+ export function buildDevicePublicContract() {
19
+ const tools = listStaticDevicePublicTools();
20
+ if (tools.length !== DEVICE_PUBLIC_TOOL_NAMES.length) {
21
+ throw new Error('Device public contract tool count drifted from the fixed device surface.');
22
+ }
23
+ return {
24
+ schemaVersion: 1,
25
+ scope: 'gateway-device-public-tools',
26
+ mcpSpecificationRevision: '2026-07-28',
27
+ resultEnvelope: {
28
+ success: {
29
+ content: 'MCP CallToolResult content array',
30
+ structuredContent: 'JSON object when the gateway normalizes a structured device result'
31
+ }
32
+ },
33
+ errorEnvelope: {
34
+ publicProtocolError: {
35
+ type: 'JSON-RPC request error',
36
+ code: -32603,
37
+ message: 'Gateway/device error message',
38
+ customInternalCodeExposed: false
39
+ },
40
+ internalRoutingCodes: [
41
+ 'DEVICE_ID_REQUIRED',
42
+ 'DEVICE_NOT_READY',
43
+ 'DEVICE_OFFLINE',
44
+ 'DEVICE_RUNTIME_CHANGED',
45
+ 'PROCESS_SESSION_STALE',
46
+ 'DEVICE_ACCESS_DENIED',
47
+ 'DEVICE_PATH_DENIED',
48
+ 'DEVICE_RATE_LIMIT',
49
+ 'DEVICE_INPUT_TOO_LARGE',
50
+ 'DEVICE_OUTPUT_TOO_LARGE',
51
+ 'DEVICE_NOT_FOUND',
52
+ 'DEVICE_SELECTION_AMBIGUOUS',
53
+ 'PATH_HINT_REQUIRED',
54
+ 'PATH_HINT_UNSUPPORTED',
55
+ 'REMOTE_DEVICE_ERROR'
56
+ ]
57
+ },
58
+ tools: tools.map(toolContract)
59
+ };
60
+ }
61
+
62
+ function jsonEqual(left, right) {
63
+ return JSON.stringify(left) === JSON.stringify(right);
64
+ }
65
+
66
+ function addChange(changes, classification, path, before, after) {
67
+ changes.push({ classification, path, before, after });
68
+ }
69
+
70
+ function classifyInputSchema(toolName, before = {}, after = {}, changes) {
71
+ const beforeRequired = new Set(before.required || []);
72
+ const afterRequired = new Set(after.required || []);
73
+ for (const name of afterRequired) {
74
+ if (!beforeRequired.has(name)) addChange(changes, 'breaking', `tools.${toolName}.inputSchema.required+${name}`, false, true);
75
+ }
76
+ for (const name of beforeRequired) {
77
+ if (!afterRequired.has(name)) addChange(changes, 'additive', `tools.${toolName}.inputSchema.required-${name}`, true, false);
78
+ }
79
+
80
+ const beforeProps = before.properties || {};
81
+ const afterProps = after.properties || {};
82
+ for (const name of Object.keys(beforeProps)) {
83
+ if (!(name in afterProps)) {
84
+ addChange(changes, 'breaking', `tools.${toolName}.inputSchema.properties.${name}`, beforeProps[name], undefined);
85
+ continue;
86
+ }
87
+ if (!jsonEqual(beforeProps[name], afterProps[name])) {
88
+ addChange(changes, 'breaking', `tools.${toolName}.inputSchema.properties.${name}`, beforeProps[name], afterProps[name]);
89
+ }
90
+ }
91
+ for (const name of Object.keys(afterProps)) {
92
+ if (name in beforeProps) continue;
93
+ addChange(
94
+ changes,
95
+ afterRequired.has(name) ? 'breaking' : 'additive',
96
+ `tools.${toolName}.inputSchema.properties.${name}`,
97
+ undefined,
98
+ afterProps[name]
99
+ );
100
+ }
101
+
102
+ const beforeAdditional = before.additionalProperties;
103
+ const afterAdditional = after.additionalProperties;
104
+ if (!jsonEqual(beforeAdditional, afterAdditional)) {
105
+ const classification = beforeAdditional === false && afterAdditional !== false ? 'additive' : 'breaking';
106
+ addChange(changes, classification, `tools.${toolName}.inputSchema.additionalProperties`, beforeAdditional, afterAdditional);
107
+ }
108
+
109
+ const handled = new Set(['required', 'properties', 'additionalProperties']);
110
+ const beforeRest = Object.fromEntries(Object.entries(before).filter(([key]) => !handled.has(key)));
111
+ const afterRest = Object.fromEntries(Object.entries(after).filter(([key]) => !handled.has(key)));
112
+ if (!jsonEqual(beforeRest, afterRest)) {
113
+ addChange(changes, 'breaking', `tools.${toolName}.inputSchema`, beforeRest, afterRest);
114
+ }
115
+ }
116
+
117
+ export function classifyDevicePublicContractChanges(baseline, current) {
118
+ const changes = [];
119
+ const baselineTools = new Map((baseline?.tools || []).map(tool => [tool.name, tool]));
120
+ const currentTools = new Map((current?.tools || []).map(tool => [tool.name, tool]));
121
+
122
+ for (const [name, before] of baselineTools) {
123
+ const after = currentTools.get(name);
124
+ if (!after) {
125
+ addChange(changes, 'breaking', `tools.${name}`, before, undefined);
126
+ continue;
127
+ }
128
+
129
+ const beforeDeprecated = before?._meta?.deprecated === true;
130
+ const afterDeprecated = after?._meta?.deprecated === true;
131
+ if (!beforeDeprecated && afterDeprecated) {
132
+ addChange(changes, 'deprecated', `tools.${name}._meta.deprecated`, false, true);
133
+ }
134
+
135
+ classifyInputSchema(name, before.inputSchema, after.inputSchema, changes);
136
+
137
+ for (const key of ['description', 'outputSchema', 'annotations']) {
138
+ if (!jsonEqual(before[key], after[key])) {
139
+ addChange(changes, 'breaking', `tools.${name}.${key}`, before[key], after[key]);
140
+ }
141
+ }
142
+
143
+ const beforeMeta = { ...(before._meta || {}) };
144
+ const afterMeta = { ...(after._meta || {}) };
145
+ delete beforeMeta.deprecated;
146
+ delete afterMeta.deprecated;
147
+ if (!jsonEqual(beforeMeta, afterMeta)) {
148
+ addChange(changes, 'breaking', `tools.${name}._meta`, beforeMeta, afterMeta);
149
+ }
150
+ }
151
+
152
+ for (const [name, after] of currentTools) {
153
+ if (!baselineTools.has(name)) addChange(changes, 'additive', `tools.${name}`, undefined, after);
154
+ }
155
+
156
+ for (const key of ['schemaVersion', 'scope', 'mcpSpecificationRevision', 'resultEnvelope', 'errorEnvelope']) {
157
+ if (!jsonEqual(baseline?.[key], current?.[key])) {
158
+ addChange(changes, 'breaking', key, baseline?.[key], current?.[key]);
159
+ }
160
+ }
161
+
162
+ const counts = { unchanged: changes.length === 0 ? 1 : 0, additive: 0, deprecated: 0, breaking: 0 };
163
+ for (const change of changes) counts[change.classification] += 1;
164
+ return { counts, changes };
165
+ }
@@ -0,0 +1,95 @@
1
+ const DEFAULT_PACKAGE = '@hcu-lab.me/mcp-device';
2
+ const DEFAULT_REGISTRY = 'https://registry.npmjs.org';
3
+
4
+ export function normalizeStableVersion(value) {
5
+ const version = String(value || '').trim();
6
+ if (!/^\d+\.\d+\.\d+$/.test(version)) throw new Error('Expected an exact stable semantic version.');
7
+ return version;
8
+ }
9
+
10
+ export function compareStableVersions(left, right) {
11
+ const a = normalizeStableVersion(left).split('.').map(Number);
12
+ const b = normalizeStableVersion(right).split('.').map(Number);
13
+ for (let index = 0; index < 3; index += 1) {
14
+ if (a[index] !== b[index]) return a[index] < b[index] ? -1 : 1;
15
+ }
16
+ return 0;
17
+ }
18
+
19
+ export function isNewerStableVersion(current, latest) {
20
+ try { return compareStableVersions(current, latest) < 0; }
21
+ catch { return false; }
22
+ }
23
+
24
+ export function minimumSelfUpdateVersion(platform) {
25
+ const normalized = String(platform || '').trim().toLowerCase();
26
+ if (normalized === 'win32') return '1.0.6';
27
+ if (normalized === 'linux') return '1.0.8';
28
+ return '1.0.5';
29
+ }
30
+
31
+ export function supportsDeviceSelfUpdate(packageVersion, platform) {
32
+ try {
33
+ return Boolean(packageVersion) && compareStableVersions(packageVersion, minimumSelfUpdateVersion(platform)) >= 0;
34
+ } catch {
35
+ return false;
36
+ }
37
+ }
38
+
39
+ export function createDeviceReleaseProvider(options = {}) {
40
+ const packageName = String(options.packageName || DEFAULT_PACKAGE).trim();
41
+ const registryUrl = String(options.registryUrl || DEFAULT_REGISTRY).replace(/\/+$/, '');
42
+ const fetchFn = options.fetchFn || globalThis.fetch;
43
+ const enabled = options.enabled !== false;
44
+ const ttlMs = Math.max(1_000, Number(options.ttlMs || 60_000));
45
+ const timeoutMs = Math.max(500, Number(options.timeoutMs || 4_000));
46
+ let fallbackVersion = null;
47
+ try { fallbackVersion = options.fallbackVersion ? normalizeStableVersion(options.fallbackVersion) : null; } catch {}
48
+ let cachedVersion = fallbackVersion;
49
+ let cachedAt = fallbackVersion ? Date.now() : 0;
50
+ let inFlight = null;
51
+
52
+ async function fetchLatest() {
53
+ if (typeof fetchFn !== 'function') throw new Error('fetch is unavailable');
54
+ const controller = new AbortController();
55
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
56
+ timer.unref?.();
57
+ try {
58
+ const response = await fetchFn(`${registryUrl}/${encodeURIComponent(packageName)}/latest`, {
59
+ headers: { accept: 'application/json' },
60
+ signal: controller.signal
61
+ });
62
+ if (!response?.ok) throw new Error(`npm registry returned HTTP ${response?.status || 'unknown'}`);
63
+ const body = await response.json();
64
+ return normalizeStableVersion(body?.version);
65
+ } finally {
66
+ clearTimeout(timer);
67
+ }
68
+ }
69
+
70
+ async function latestVersion() {
71
+ if (!enabled) return cachedVersion || fallbackVersion || null;
72
+ const now = Date.now();
73
+ if (cachedVersion && now - cachedAt < ttlMs) return cachedVersion;
74
+ if (inFlight) return await inFlight;
75
+ inFlight = (async () => {
76
+ try {
77
+ const latest = await fetchLatest();
78
+ cachedVersion = latest;
79
+ cachedAt = Date.now();
80
+ return latest;
81
+ } catch {
82
+ return cachedVersion || fallbackVersion || null;
83
+ } finally {
84
+ inFlight = null;
85
+ }
86
+ })();
87
+ return await inFlight;
88
+ }
89
+
90
+ return {
91
+ latestVersion,
92
+ peek: () => cachedVersion,
93
+ packageName
94
+ };
95
+ }
@@ -0,0 +1,128 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readFileSync } from 'node:fs';
3
+ import tls from 'node:tls';
4
+ import { Duplex } from 'node:stream';
5
+ import { WebSocket } from 'ws';
6
+
7
+ export const DEVICE_INNER_TLS_SUBPROTOCOL = 'hcu-device-v2-inner-tls';
8
+ export const DEVICE_MAX_MESSAGE_BYTES = 64 * 1024;
9
+
10
+ export function loadDeviceInnerTlsConfig(env = process.env, readFile = readFileSync) {
11
+ const certPath = String(env.MCP_DEVICE_INNER_TLS_CERT_PATH || '').trim();
12
+ const keyPath = String(env.MCP_DEVICE_INNER_TLS_KEY_PATH || '').trim();
13
+ if (!certPath && !keyPath) return null;
14
+ if (!certPath || !keyPath) throw new Error('MCP_DEVICE_INNER_TLS_CERT_PATH and MCP_DEVICE_INNER_TLS_KEY_PATH must be configured together.');
15
+ return { cert: readFile(certPath), key: readFile(keyPath) };
16
+ }
17
+
18
+ export class WebSocketDuplex extends Duplex {
19
+ constructor(ws) {
20
+ super();
21
+ this.ws = ws;
22
+ ws.on('message', (data, isBinary) => {
23
+ if (!isBinary) {
24
+ this.destroy(new Error('Inner TLS transport requires binary WebSocket messages.'));
25
+ return;
26
+ }
27
+ const chunk = Buffer.isBuffer(data) ? data : Buffer.from(data);
28
+ this.push(chunk);
29
+ });
30
+ ws.once('close', () => this.push(null));
31
+ ws.once('error', error => this.destroy(error));
32
+ }
33
+
34
+ _read() {}
35
+
36
+ _write(chunk, _encoding, callback) {
37
+ if (this.ws.readyState !== WebSocket.OPEN) {
38
+ callback(new Error('WebSocket is not open.'));
39
+ return;
40
+ }
41
+ this.ws.send(Buffer.from(chunk), { binary: true }, callback);
42
+ }
43
+
44
+ _destroy(error, callback) {
45
+ try {
46
+ if (this.ws.readyState === WebSocket.OPEN) this.ws.close(1000, 'inner transport closed');
47
+ else if (this.ws.readyState === WebSocket.CONNECTING) this.ws.terminate();
48
+ } catch {}
49
+ callback(error);
50
+ }
51
+ }
52
+
53
+ export function createWebSocketDuplex(ws) {
54
+ return new WebSocketDuplex(ws);
55
+ }
56
+
57
+ export function createServerInnerTls(ws, { cert, key, secureContext } = {}) {
58
+ const context = secureContext || tls.createSecureContext({ cert, key, minVersion: 'TLSv1.3' });
59
+ return new tls.TLSSocket(createWebSocketDuplex(ws), {
60
+ isServer: true,
61
+ secureContext: context
62
+ });
63
+ }
64
+
65
+ export function exportDeviceAuthKeyingMaterial(socket, deviceId, mode) {
66
+ const context = createHash('sha256')
67
+ .update(`hcu-mcp-device-auth-v2\n${String(deviceId)}\n${String(mode)}`, 'utf8')
68
+ .digest();
69
+ return socket.exportKeyingMaterial(32, 'EXPERIMENTAL-HCU-MCP-DEVICE-AUTH-V2', context);
70
+ }
71
+
72
+ export function encodeJsonFrame(message, maxMessageBytes = DEVICE_MAX_MESSAGE_BYTES) {
73
+ const payload = Buffer.from(JSON.stringify(message), 'utf8');
74
+ if (payload.length < 1 || payload.length > maxMessageBytes) {
75
+ throw new Error('Device JSON frame exceeds maximum size.');
76
+ }
77
+ const frame = Buffer.allocUnsafe(4 + payload.length);
78
+ frame.writeUInt32BE(payload.length, 0);
79
+ payload.copy(frame, 4);
80
+ return frame;
81
+ }
82
+
83
+ export function createJsonFrameParser({ maxMessageBytes = DEVICE_MAX_MESSAGE_BYTES, onMessage }) {
84
+ if (typeof onMessage !== 'function') throw new Error('onMessage callback is required.');
85
+ const header = Buffer.allocUnsafe(4);
86
+ let headerBytes = 0;
87
+ let expectedLength = null;
88
+ let bodyBytes = 0;
89
+ let bodyParts = [];
90
+
91
+ return {
92
+ push(value) {
93
+ const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
94
+ let offset = 0;
95
+ while (offset < chunk.length) {
96
+ if (expectedLength === null) {
97
+ const take = Math.min(4 - headerBytes, chunk.length - offset);
98
+ chunk.copy(header, headerBytes, offset, offset + take);
99
+ headerBytes += take;
100
+ offset += take;
101
+ if (headerBytes < 4) continue;
102
+ const length = header.readUInt32BE(0);
103
+ headerBytes = 0;
104
+ if (length < 1 || length > maxMessageBytes) throw new Error('Invalid device JSON frame length.');
105
+ expectedLength = length;
106
+ bodyBytes = 0;
107
+ bodyParts = [];
108
+ continue;
109
+ }
110
+
111
+ const remaining = expectedLength - bodyBytes;
112
+ const take = Math.min(remaining, chunk.length - offset);
113
+ bodyParts.push(chunk.subarray(offset, offset + take));
114
+ bodyBytes += take;
115
+ offset += take;
116
+ if (bodyBytes !== expectedLength) continue;
117
+
118
+ const text = Buffer.concat(bodyParts, expectedLength).toString('utf8');
119
+ expectedLength = null;
120
+ bodyBytes = 0;
121
+ bodyParts = [];
122
+ const message = JSON.parse(text);
123
+ if (!message || typeof message !== 'object') throw new Error('Device JSON frame must contain an object.');
124
+ onMessage(message);
125
+ }
126
+ }
127
+ };
128
+ }