@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,227 @@
1
+ import { createHash } from 'node:crypto';
2
+
3
+ import { getRuntimeProfile } from './runtime-profile.mjs';
4
+ import { projectRouteKey } from './projects/trusted-roots-projects.mjs';
5
+
6
+ const DEFAULT_LIST_LIMIT = 50;
7
+ const MAX_LIST_LIMIT = 200;
8
+ const CURSOR_VERSION = 1;
9
+
10
+ export const PROJECT_INSPECTION_VIEWS = Object.freeze([
11
+ 'summary',
12
+ 'tree',
13
+ 'git_status',
14
+ 'git_diff',
15
+ 'readme',
16
+ 'package'
17
+ ]);
18
+
19
+ function boundedInteger(value, fallback, min, max, label) {
20
+ if (value === undefined || value === null || value === '') return fallback;
21
+ const number = Number(value);
22
+ if (!Number.isInteger(number) || number < min || number > max) {
23
+ throw new Error(`Invalid ${label}: ${value}. Expected an integer from ${min} to ${max}.`);
24
+ }
25
+ return number;
26
+ }
27
+
28
+ function cursorVersion(kind, parts) {
29
+ return createHash('sha256').update(`${kind}\n${parts.join('\n')}`).digest('base64url').slice(0, 16);
30
+ }
31
+
32
+ function encodeCursor(kind, offset, version) {
33
+ return Buffer.from(JSON.stringify({ v: CURSOR_VERSION, kind, offset, version }), 'utf8').toString('base64url');
34
+ }
35
+
36
+ function decodeCursor(cursor, { kind, version }) {
37
+ if (!cursor) return 0;
38
+ let parsed;
39
+ try {
40
+ parsed = JSON.parse(Buffer.from(String(cursor), 'base64url').toString('utf8'));
41
+ } catch {
42
+ throw new Error('Invalid cursor: expected an opaque cursor returned by the previous page.');
43
+ }
44
+ if (
45
+ parsed?.v !== CURSOR_VERSION ||
46
+ parsed?.kind !== kind ||
47
+ parsed?.version !== version ||
48
+ !Number.isInteger(parsed?.offset) ||
49
+ parsed.offset < 0
50
+ ) {
51
+ throw new Error('Invalid or stale cursor: request parameters or catalog version changed.');
52
+ }
53
+ return parsed.offset;
54
+ }
55
+
56
+ function projectPathExposure(context = {}) {
57
+ if (typeof context.exposePaths === 'boolean') return context.exposePaths;
58
+ return Boolean(
59
+ context.projectRegistry?.exposeProjectPaths ||
60
+ context.env?.MCP_EXPOSE_PROJECT_PATHS === 'true'
61
+ );
62
+ }
63
+
64
+ function projectLookupError(code, message) {
65
+ const error = new Error(`${code}: ${message}`);
66
+ error.code = code;
67
+ return error;
68
+ }
69
+
70
+ function visibleDevices(context = {}) {
71
+ if (typeof context.listVisibleDevices === 'function') {
72
+ const devices = context.listVisibleDevices();
73
+ return Array.isArray(devices) ? devices : [];
74
+ }
75
+ return Array.isArray(context.devices) ? context.devices : [];
76
+ }
77
+
78
+ function requireVisibleOnlineDevice(context, deviceId) {
79
+ const id = String(deviceId || '').trim();
80
+ if (!id) throw projectLookupError('DEVICE_ID_REQUIRED', 'device_id is required.');
81
+ const device = visibleDevices(context).find(item => String(item?.deviceId || '').trim() === id);
82
+ if (!device) throw projectLookupError('DEVICE_NOT_FOUND', `Unknown or unavailable device_id: ${id}`);
83
+ if (device.revoked || !device.online) throw projectLookupError('DEVICE_OFFLINE', `Device ${id} is offline or revoked.`);
84
+ return device;
85
+ }
86
+
87
+ function getProject(projectRegistry, deviceId, projectId) {
88
+ const id = String(projectId || '').trim();
89
+ if (!id) throw projectLookupError('PROJECT_ID_REQUIRED', 'project_id is required.');
90
+ const project = projectRegistry?.projectRoutes?.get(projectRouteKey(deviceId, id));
91
+ if (!project) throw projectLookupError('PROJECT_DEVICE_MISMATCH', `project_id ${id} is not configured for device_id ${deviceId}.`);
92
+ return project;
93
+ }
94
+
95
+ export function resolveProjectRoute(context = {}, { deviceId, projectId } = {}) {
96
+ const normalizedDeviceId = String(deviceId || '').trim();
97
+ requireVisibleOnlineDevice(context, normalizedDeviceId);
98
+ return getProject(context.projectRegistry, normalizedDeviceId, projectId);
99
+ }
100
+
101
+ function projectListItem(project, projectRegistry, exposePaths) {
102
+ const item = {
103
+ device_id: project.deviceId,
104
+ project_id: project.projectId,
105
+ displayName: project.displayName,
106
+ default: projectRegistry?.defaultProjectId === project.projectId
107
+ };
108
+ if (exposePaths) item.repoRoot = project.repoRoot;
109
+ return item;
110
+ }
111
+
112
+ export function listProjects(context = {}, options = {}) {
113
+ const projectRegistry = context.projectRegistry;
114
+ const exposePaths = projectPathExposure(context);
115
+ const deviceId = String(options.device_id ?? options.deviceId ?? '').trim();
116
+ requireVisibleOnlineDevice(context, deviceId);
117
+ const query = String(options.query || '').trim().toLowerCase();
118
+ const limit = boundedInteger(options.limit, DEFAULT_LIST_LIMIT, 1, MAX_LIST_LIMIT, 'limit');
119
+ const all = [...(projectRegistry?.projectRoutes?.values() || [])]
120
+ .filter(project => project.deviceId === deviceId);
121
+ const matched = all
122
+ .map(project => {
123
+ const id = String(project.projectId || '').toLowerCase();
124
+ const display = String(project.displayName || '').toLowerCase();
125
+ const exact = query && (id === query || display === query);
126
+ const contains = !query || id.includes(query) || display.includes(query);
127
+ return { project, exact, contains };
128
+ })
129
+ .filter(entry => entry.contains)
130
+ .sort((a, b) => {
131
+ if (a.exact !== b.exact) return a.exact ? -1 : 1;
132
+ return a.project.projectId.localeCompare(b.project.projectId);
133
+ });
134
+ const version = cursorVersion('projects', [
135
+ deviceId,
136
+ query,
137
+ ...matched.map(entry => `${entry.project.projectId}:${entry.project.displayName}`)
138
+ ]);
139
+ const offset = decodeCursor(options.cursor, { kind: 'projects', version });
140
+ if (offset > matched.length) throw new Error('Invalid or stale cursor: project offset is outside the current result set.');
141
+ const page = matched.slice(offset, offset + limit);
142
+ const nextOffset = offset + page.length;
143
+ const truncated = nextOffset < matched.length;
144
+ return {
145
+ items: page.map(entry => projectListItem(entry.project, projectRegistry, exposePaths)),
146
+ truncated,
147
+ nextCursor: truncated ? encodeCursor('projects', nextOffset, version) : null,
148
+ total: matched.length,
149
+ pathExposure: exposePaths
150
+ };
151
+ }
152
+
153
+ function projectRelativePath(encodedPath) {
154
+ const decoded = decodeURIComponent(encodedPath || '');
155
+ const portable = decoded.replaceAll('\\', '/');
156
+ if (!decoded || portable.startsWith('/') || /^[A-Za-z]:\//.test(portable) || portable.split('/').includes('..')) {
157
+ throw new Error('Invalid project-relative resource path.');
158
+ }
159
+ return decoded;
160
+ }
161
+
162
+ function remoteInspectionArguments(project, view, options = {}) {
163
+ const args = {
164
+ device_id: project.deviceId,
165
+ path: project.repoRoot,
166
+ project_id: project.projectId,
167
+ view
168
+ };
169
+ if (view === 'tree') {
170
+ if (options.depth !== undefined) args.depth = options.depth;
171
+ if (options.limit !== undefined) args.limit = options.limit;
172
+ if (options.cursor !== undefined) args.cursor = options.cursor;
173
+ }
174
+ if (view === 'git_diff' && options.staged !== undefined) args.staged = options.staged === true;
175
+ return args;
176
+ }
177
+
178
+ function shapeInspectionResult(project, context, view, remote = {}) {
179
+ const identity = { device_id: project.deviceId, project_id: project.projectId };
180
+ if (view === 'summary') {
181
+ const result = {
182
+ ...identity,
183
+ displayName: project.displayName,
184
+ defaultRootName: remote.defaultRootName || project.projectId,
185
+ default: context.projectRegistry?.defaultProjectId === project.projectId,
186
+ hasPackageJson: Boolean(remote.hasPackageJson),
187
+ hasReadme: Boolean(remote.hasReadme),
188
+ runtimeProfile: getRuntimeProfile(context.env || process.env).name
189
+ };
190
+ if (projectPathExposure(context)) result.repoRoot = project.repoRoot;
191
+ return result;
192
+ }
193
+ return { ...identity, ...remote };
194
+ }
195
+
196
+ export async function readProjectResourceFile(context = {}, { deviceId, projectId, encodedPath } = {}) {
197
+ const project = resolveProjectRoute(context, { deviceId, projectId });
198
+ if (typeof context.callDeviceTool !== 'function') {
199
+ throw projectLookupError('DEVICE_EXECUTION_UNAVAILABLE', 'Project file access requires device execution routing.');
200
+ }
201
+ const remote = await context.callDeviceTool('project_inspect', {
202
+ device_id: project.deviceId,
203
+ path: project.repoRoot,
204
+ project_id: project.projectId,
205
+ view: 'file',
206
+ relative_path: projectRelativePath(encodedPath)
207
+ });
208
+ if (!remote || typeof remote.text !== 'string') throw new Error('Invalid project file response from device.');
209
+ return remote.text;
210
+ }
211
+
212
+ export async function inspectProject(context = {}, options = {}) {
213
+ const view = String(options.view || 'summary');
214
+ if (!PROJECT_INSPECTION_VIEWS.includes(view)) {
215
+ throw new Error(`Invalid project inspection view: ${view}. Expected one of: ${PROJECT_INSPECTION_VIEWS.join(', ')}.`);
216
+ }
217
+ const deviceId = String(options.deviceId ?? options.device_id ?? '').trim();
218
+ const project = resolveProjectRoute(context, { deviceId, projectId: options.projectId ?? options.project_id });
219
+ if (typeof context.callDeviceTool !== 'function') {
220
+ throw projectLookupError('DEVICE_EXECUTION_UNAVAILABLE', 'Project inspection requires device execution routing.');
221
+ }
222
+ const remote = await context.callDeviceTool('project_inspect', remoteInspectionArguments(project, view, options));
223
+ if (!remote || typeof remote !== 'object' || Array.isArray(remote)) {
224
+ throw new Error('Invalid project inspection response from device.');
225
+ }
226
+ return shapeInspectionResult(project, context, view, remote);
227
+ }
@@ -0,0 +1,69 @@
1
+ import crypto from 'node:crypto';
2
+ import path from 'node:path';
3
+
4
+ export const PROJECT_ID_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/;
5
+
6
+ export function normalizeProjectId(value) {
7
+ return String(value ?? '').trim();
8
+ }
9
+
10
+ export function isValidProjectId(value) {
11
+ const projectId = normalizeProjectId(value);
12
+ return PROJECT_ID_PATTERN.test(projectId) && !projectId.includes('/') && !projectId.includes('\\') && !projectId.includes(':');
13
+ }
14
+
15
+ export function assertValidProjectId(value) {
16
+ const projectId = normalizeProjectId(value);
17
+ if (!isValidProjectId(projectId)) {
18
+ const error = new Error(`Invalid projectId: ${value}`);
19
+ error.code = 'INVALID_PROJECT_ID';
20
+ error.details = {
21
+ projectId: value,
22
+ pattern: PROJECT_ID_PATTERN.source
23
+ };
24
+ throw error;
25
+ }
26
+ return projectId;
27
+ }
28
+
29
+ export function slugifyProjectId(value) {
30
+ const slug = String(value ?? '')
31
+ .trim()
32
+ .toLowerCase()
33
+ .replace(/[^a-z0-9._-]+/g, '-')
34
+ .replace(/^[._-]+|[._-]+$/g, '')
35
+ .replace(/-{2,}/g, '-')
36
+ .slice(0, 64);
37
+
38
+ return isValidProjectId(slug) ? slug : 'project';
39
+ }
40
+
41
+ function shortPathHash(rootPath) {
42
+ return crypto.createHash('sha1').update(path.resolve(String(rootPath))).digest('hex').slice(0, 8);
43
+ }
44
+
45
+ function finalPathSegments(rootPath) {
46
+ const resolved = path.resolve(String(rootPath));
47
+ const parsed = path.parse(resolved);
48
+ const relative = resolved.slice(parsed.root.length);
49
+ return relative.split(/[\\/]+/).filter(Boolean);
50
+ }
51
+
52
+ export function generateProjectIdForRoot(rootPath, usedProjectIds = new Set()) {
53
+ const used = usedProjectIds instanceof Set ? usedProjectIds : new Set(usedProjectIds || []);
54
+ const segments = finalPathSegments(rootPath);
55
+ const folder = segments.at(-1) || 'project';
56
+ const parent = segments.at(-2);
57
+
58
+ const candidates = [slugifyProjectId(folder)];
59
+ if (parent) candidates.push(slugifyProjectId(`${parent}-${folder}`));
60
+
61
+ for (const candidate of candidates) {
62
+ if (!used.has(candidate)) return candidate;
63
+ }
64
+
65
+ const base = candidates.at(-1) || 'project';
66
+ const suffix = shortPathHash(rootPath);
67
+ const maxBaseLength = 64 - suffix.length - 1;
68
+ return `${base.slice(0, maxBaseLength).replace(/[._-]+$/g, '')}-${suffix}`;
69
+ }
@@ -0,0 +1,375 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import * as toml from 'smol-toml';
4
+
5
+ import {
6
+ assertValidProjectId,
7
+ generateProjectIdForRoot,
8
+ normalizeProjectId
9
+ } from './project-id.mjs';
10
+
11
+ function cleanRootPath(rootPath) {
12
+ return String(rootPath ?? '')
13
+ .trim()
14
+ .replace(/^[']|[']$/g, '')
15
+ .replace(/^["]|["]$/g, '')
16
+ .replace(/^\\\\\?\\/, '');
17
+ }
18
+
19
+ function isWindowsDrivePath(rootPath) {
20
+ return /^[A-Za-z]:[\\/]/.test(String(rootPath || ''));
21
+ }
22
+
23
+ function normalizeRootPath(rootPath) {
24
+ const cleaned = cleanRootPath(rootPath);
25
+ if (process.platform !== 'win32' && isWindowsDrivePath(cleaned)) {
26
+ return cleaned.replace(/\\/g, '/');
27
+ }
28
+ return path.resolve(cleaned);
29
+ }
30
+
31
+ function isInsideRoot(candidatePath, rootPath) {
32
+ const relative = path.relative(rootPath, candidatePath);
33
+ return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
34
+ }
35
+
36
+ function normalizeDeviceId(value) {
37
+ const deviceId = String(value || '').trim();
38
+ if (!deviceId) return undefined;
39
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(deviceId)) {
40
+ const error = new Error(`Invalid device_id: ${deviceId}`);
41
+ error.code = 'INVALID_DEVICE_ID';
42
+ throw error;
43
+ }
44
+ return deviceId;
45
+ }
46
+
47
+ export function projectRouteKey(deviceId, projectId) {
48
+ return `${String(deviceId || '').trim()}\u0000${String(projectId || '').trim()}`;
49
+ }
50
+
51
+ export function trustedRootEntryToLine(entry, context = {}) {
52
+ if (typeof entry === 'string') return expandTrustedRootPlaceholders(entry, context);
53
+ if (!entry || typeof entry !== 'object') return '';
54
+ const rawRoot = entry.path ?? entry.root;
55
+ if (!rawRoot) return '';
56
+ const root = expandTrustedRootPlaceholders(String(rawRoot), context);
57
+ const projectId = entry.project_id ?? entry.projectId;
58
+ const displayName = entry.display_name ?? entry.displayName;
59
+ const deviceId = entry.device_id ?? entry.deviceId;
60
+ const fields = [root];
61
+ if (projectId !== undefined || displayName !== undefined || deviceId !== undefined) fields.push(projectId === undefined ? '' : String(projectId));
62
+ if (displayName !== undefined || deviceId !== undefined) fields.push(displayName === undefined ? '' : String(displayName));
63
+ if (deviceId !== undefined) fields.push(String(deviceId));
64
+ return fields.join(' | ');
65
+ }
66
+
67
+ export function trustedRootsTomlToRaw(trustedRootsRaw, context = {}) {
68
+ if (!trustedRootsRaw) return '';
69
+ const entries = Array.isArray(trustedRootsRaw.roots) ? trustedRootsRaw.roots : [];
70
+ return entries.map(entry => trustedRootEntryToLine(entry, context)).filter(Boolean).join('\n');
71
+ }
72
+
73
+ export function expandTrustedRootPlaceholders(value, { repoRoot = process.cwd(), home = process.env.HOME || process.env.USERPROFILE || '' } = {}) {
74
+ return String(value).replace(/\$\{([^}]+)\}/g, (match, name) => {
75
+ if (name === 'repoRoot') return repoRoot;
76
+ if (name === 'home') return home;
77
+ return match;
78
+ });
79
+ }
80
+
81
+ export function loadUnifiedMcpTomlConfig(configPath) {
82
+ if (!configPath || !fs.existsSync(configPath)) return {};
83
+ return toml.parse(fs.readFileSync(configPath, 'utf8'));
84
+ }
85
+
86
+ export function defaultUnifiedMcpConfigPath(repoRoot = process.cwd()) {
87
+ return path.resolve(repoRoot, 'config/mcp-servers.toml');
88
+ }
89
+
90
+ export function findUnifiedMcpConfigPath(env = process.env, repoRoot = process.cwd()) {
91
+ if (String(env.MCP_UPSTREAM_CONFIG || '').trim()) {
92
+ const value = String(env.MCP_UPSTREAM_CONFIG).trim().replace(/^['"]|['"]$/g, '');
93
+ return path.isAbsolute(value) ? path.resolve(value) : path.resolve(repoRoot, value);
94
+ }
95
+ const candidate = defaultUnifiedMcpConfigPath(repoRoot);
96
+ return fs.existsSync(candidate) ? candidate : null;
97
+ }
98
+
99
+ export function trustedRootsRawFromSources({ rawConfig = {}, repoRoot = process.cwd() } = {}) {
100
+ return trustedRootsTomlToRaw(rawConfig.trusted_roots, { repoRoot });
101
+ }
102
+
103
+ export function loadTrustedRootsRawFromUnifiedConfig({ env = process.env, repoRoot = process.cwd() } = {}) {
104
+ const configPath = findUnifiedMcpConfigPath(env, repoRoot);
105
+ const rawConfig = loadUnifiedMcpTomlConfig(configPath);
106
+ return trustedRootsRawFromSources({ rawConfig, env, repoRoot });
107
+ }
108
+
109
+ export function splitTrustedRootConfig(rawValue) {
110
+ return String(rawValue || '')
111
+ .split(/[\r\n;]+/)
112
+ .map(entry => entry.trim())
113
+ .filter(entry => entry && !entry.startsWith('#'));
114
+ }
115
+
116
+ export function resolveTrustedRootPaths(rawValue, fallbackRoot) {
117
+ const roots = [];
118
+ if (fallbackRoot) {
119
+ roots.push(normalizeRootPath(fallbackRoot));
120
+ }
121
+
122
+ for (const entry of splitTrustedRootConfig(rawValue)) {
123
+ const parsed = parseTrustedRootLine(entry);
124
+ if (parsed?.root) {
125
+ roots.push(parsed.root);
126
+ }
127
+ }
128
+
129
+ const resolvedRoots = [...new Set(roots)];
130
+ const existingRoots = [];
131
+ const missingRoots = [];
132
+ for (const root of resolvedRoots) {
133
+ if (fs.existsSync(root)) {
134
+ existingRoots.push(root);
135
+ } else {
136
+ missingRoots.push(root);
137
+ }
138
+ }
139
+
140
+ if (existingRoots.length === 0) {
141
+ throw new Error(`No trusted roots exist. Configured roots: ${resolvedRoots.join('; ')}`);
142
+ }
143
+
144
+ return { existingRoots, missingRoots, resolvedRoots };
145
+ }
146
+
147
+ export function parseTrustedRootLine(line, options = {}) {
148
+ const lineNumber = options.lineNumber;
149
+ const raw = String(line ?? '');
150
+ const trimmed = raw.trim();
151
+
152
+ if (!trimmed || trimmed.startsWith('#')) {
153
+ return null;
154
+ }
155
+
156
+ const parts = raw.split('|').map(part => part.trim());
157
+ if (parts.length > 4) {
158
+ const error = new Error(`Invalid trusted root line${lineNumber ? ` ${lineNumber}` : ''}: expected at most 4 pipe-separated fields`);
159
+ error.code = 'INVALID_TRUSTED_ROOT_LINE';
160
+ error.details = { line, lineNumber };
161
+ throw error;
162
+ }
163
+
164
+ const root = cleanRootPath(parts[0]);
165
+ if (!root) {
166
+ const error = new Error(`Invalid trusted root line${lineNumber ? ` ${lineNumber}` : ''}: missing path`);
167
+ error.code = 'INVALID_TRUSTED_ROOT_LINE';
168
+ error.details = { line, lineNumber };
169
+ throw error;
170
+ }
171
+
172
+ if (!path.isAbsolute(root) && !isWindowsDrivePath(root)) {
173
+ const error = new Error(`Trusted root must be absolute: ${root}`);
174
+ error.code = 'TRUSTED_ROOT_MUST_BE_ABSOLUTE';
175
+ error.details = { root, lineNumber };
176
+ throw error;
177
+ }
178
+
179
+ const resolvedRoot = normalizeRootPath(root);
180
+ const explicitProjectId = parts.length >= 2 && parts[1] !== '';
181
+ const projectId = explicitProjectId ? assertValidProjectId(parts[1]) : undefined;
182
+ const displayName = parts.length >= 3 && parts[2] !== '' ? parts[2] : undefined;
183
+ const explicitDeviceId = parts.length >= 4 && parts[3] !== '';
184
+ const deviceId = explicitDeviceId ? normalizeDeviceId(parts[3]) : undefined;
185
+
186
+ return {
187
+ rawLine: raw,
188
+ lineNumber,
189
+ root: resolvedRoot,
190
+ projectId,
191
+ displayName,
192
+ deviceId,
193
+ explicitProjectId,
194
+ explicitDeviceId
195
+ };
196
+ }
197
+
198
+ export function normalizeTrustedRootEntries(linesOrEntries, options = {}) {
199
+ const entries = [];
200
+ const usedGeneratedIds = new Set();
201
+ const explicitIds = new Set();
202
+ const seenRoots = new Set();
203
+
204
+ const parsedEntries = linesOrEntries.map((item, index) => {
205
+ if (typeof item === 'string') return parseTrustedRootLine(item, { lineNumber: index + 1 });
206
+ return item;
207
+ }).filter(Boolean);
208
+
209
+ for (const entry of parsedEntries) {
210
+ const root = normalizeRootPath(entry.root);
211
+ const deviceId = normalizeDeviceId(entry.deviceId ?? entry.device_id);
212
+ const normalizedRootKey = process.platform === 'win32' ? root.toLowerCase() : root;
213
+ const rootKey = `${deviceId || ''}\u0000${normalizedRootKey}`;
214
+ if (seenRoots.has(rootKey)) continue;
215
+ seenRoots.add(rootKey);
216
+
217
+ let projectId;
218
+ const explicitProjectId = Boolean(entry.explicitProjectId || entry.projectId);
219
+ if (entry.projectId) {
220
+ projectId = assertValidProjectId(entry.projectId);
221
+ explicitIds.add(projectId);
222
+ } else {
223
+ projectId = generateProjectIdForRoot(root, new Set([...explicitIds, ...usedGeneratedIds]));
224
+ usedGeneratedIds.add(projectId);
225
+ }
226
+
227
+ entries.push({
228
+ ...entry,
229
+ root,
230
+ projectId,
231
+ deviceId,
232
+ displayName: entry.displayName || projectId,
233
+ explicitProjectId,
234
+ explicitDeviceId: Boolean(entry.explicitDeviceId || deviceId)
235
+ });
236
+ }
237
+
238
+ return entries;
239
+ }
240
+
241
+ export function buildTrustedRootsProjectRegistry(entries, options = {}) {
242
+ const normalizedEntries = normalizeTrustedRootEntries(entries, options);
243
+ const legacyProjects = new Map();
244
+ const projectRoutes = new Map();
245
+ const missingRoots = [];
246
+
247
+ function addEntry(target, key, entry) {
248
+ const existing = target.get(key);
249
+ if (!existing) {
250
+ target.set(key, {
251
+ projectId: entry.projectId,
252
+ deviceId: entry.deviceId || null,
253
+ displayName: entry.displayName,
254
+ repoRoot: entry.root,
255
+ trustedRoots: [entry.root],
256
+ extraTrustedRoots: [],
257
+ explicitProjectId: entry.explicitProjectId,
258
+ explicitDeviceId: entry.explicitDeviceId
259
+ });
260
+ return;
261
+ }
262
+ if (!existing.trustedRoots.includes(entry.root)) {
263
+ existing.trustedRoots.push(entry.root);
264
+ existing.extraTrustedRoots.push(entry.root);
265
+ }
266
+ existing.explicitProjectId = existing.explicitProjectId || entry.explicitProjectId;
267
+ existing.explicitDeviceId = existing.explicitDeviceId || entry.explicitDeviceId;
268
+ }
269
+
270
+ for (const entry of normalizedEntries) {
271
+ if (options.checkExists && !fs.existsSync(entry.root)) {
272
+ missingRoots.push(entry.root);
273
+ if (options.missingRootMode === 'error') {
274
+ const error = new Error(`Trusted root does not exist: ${entry.root}`);
275
+ error.code = 'TRUSTED_ROOT_NOT_FOUND';
276
+ error.details = { root: entry.root };
277
+ throw error;
278
+ }
279
+ }
280
+
281
+ if (entry.deviceId) {
282
+ addEntry(projectRoutes, projectRouteKey(entry.deviceId, entry.projectId), entry);
283
+ } else {
284
+ addEntry(legacyProjects, entry.projectId, entry);
285
+ }
286
+ }
287
+
288
+ // Legacy project-only lookup remains available only when the id identifies
289
+ // exactly one route. Ambiguous ids deliberately have no project-only entry.
290
+ const projects = new Map(legacyProjects);
291
+ const routesByProjectId = new Map();
292
+ for (const route of projectRoutes.values()) {
293
+ const routes = routesByProjectId.get(route.projectId) || [];
294
+ routes.push(route);
295
+ routesByProjectId.set(route.projectId, routes);
296
+ }
297
+ const ambiguousProjectIds = new Set();
298
+ for (const [projectId, routes] of routesByProjectId) {
299
+ if (legacyProjects.has(projectId) || routes.length !== 1) {
300
+ projects.delete(projectId);
301
+ ambiguousProjectIds.add(projectId);
302
+ } else {
303
+ projects.set(projectId, routes[0]);
304
+ }
305
+ }
306
+
307
+ const allTrustedRoots = [...new Set(normalizedEntries.map(entry => entry.root))];
308
+ const rootIndex = [];
309
+ for (const project of projects.values()) {
310
+ for (const root of project.trustedRoots) {
311
+ rootIndex.push({ projectId: project.projectId, deviceId: project.deviceId, root });
312
+ }
313
+ }
314
+ rootIndex.sort((a, b) => b.root.length - a.root.length);
315
+
316
+ const requestedDefault = normalizeProjectId(options.defaultProjectId || '');
317
+ const defaultProjectId = requestedDefault || normalizedEntries[0]?.projectId;
318
+
319
+ return {
320
+ mode: 'trusted-roots-projects',
321
+ defaultProjectId,
322
+ requireProjectId: Boolean(options.requireProjectId),
323
+ pathInference: options.pathInference !== false,
324
+ exposeProjectPaths: Boolean(options.exposeProjectPaths),
325
+ projects,
326
+ projectRoutes,
327
+ ambiguousProjectIds,
328
+ rootIndex,
329
+ allTrustedRoots,
330
+ missingRoots
331
+ };
332
+ }
333
+
334
+ export function buildTrustedRootsProjectRegistryFromRaw(rawValue, options = {}) {
335
+ const configuredEntries = splitTrustedRootConfig(rawValue);
336
+ const fallbackEntries = options.fallbackRoot ? [options.fallbackRoot] : [];
337
+ return buildTrustedRootsProjectRegistry(configuredEntries.length > 0 ? configuredEntries : fallbackEntries, options);
338
+ }
339
+
340
+ export function loadTrustedRootsProjectRegistry(configPath, options = {}) {
341
+ const content = fs.readFileSync(configPath, 'utf8');
342
+ return buildTrustedRootsProjectRegistry(content.split(/\r?\n/), options);
343
+ }
344
+
345
+ export function listProjectSummaries(registry, options = {}) {
346
+ const showPaths = Boolean(options.showPaths && registry.exposeProjectPaths);
347
+ const projects = [...registry.projects.values()].map(project => {
348
+ const summary = {
349
+ projectId: project.projectId,
350
+ displayName: project.displayName
351
+ };
352
+ if (showPaths) {
353
+ summary.repoRoot = project.repoRoot;
354
+ summary.trustedRoots = [...project.trustedRoots];
355
+ }
356
+ return summary;
357
+ });
358
+
359
+ return {
360
+ defaultProjectId: registry.defaultProjectId,
361
+ requireProjectId: registry.requireProjectId,
362
+ pathInference: registry.pathInference,
363
+ exposeProjectPaths: registry.exposeProjectPaths,
364
+ projects,
365
+ warnings: options.showPaths && !registry.exposeProjectPaths
366
+ ? ['Path exposure is disabled. Set MCP_EXPOSE_PROJECT_PATHS=true to include local paths.']
367
+ : []
368
+ };
369
+ }
370
+
371
+ export function inferProjectIdFromPath(registry, candidatePath) {
372
+ const resolved = normalizeRootPath(candidatePath);
373
+ const match = registry.rootIndex.find(entry => isInsideRoot(resolved, entry.root));
374
+ return match?.projectId;
375
+ }