@hcu-lab.me/mcp-device 1.0.10 → 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 (491) hide show
  1. package/PRIVACY.md +21 -0
  2. package/README.md +57 -2
  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 -1
  428. package/dist/device/device.js +87 -39
  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 +9 -0
  432. package/dist/device/gateway-tool-adapter.js +20 -1
  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/log-palace/cli.d.ts +7 -0
  439. package/dist/log-palace/cli.js +89 -0
  440. package/dist/log-palace/formats.d.ts +26 -0
  441. package/dist/log-palace/formats.js +126 -0
  442. package/dist/log-palace/store.d.ts +129 -0
  443. package/dist/log-palace/store.js +856 -0
  444. package/dist/mcp-device.js +27 -5
  445. package/dist/npm-scripts/remote.js +1 -0
  446. package/dist/platform/activity-journal.d.ts +16 -0
  447. package/dist/platform/activity-journal.js +68 -0
  448. package/dist/platform/cli.d.ts +1 -0
  449. package/dist/platform/cli.js +300 -0
  450. package/dist/platform/coordination-lock.d.ts +45 -0
  451. package/dist/platform/coordination-lock.js +233 -0
  452. package/dist/platform/device-runtime.d.ts +16 -0
  453. package/dist/platform/device-runtime.js +83 -0
  454. package/dist/platform/knowledge-contract.d.ts +46 -0
  455. package/dist/platform/knowledge-contract.js +1 -0
  456. package/dist/platform/knowledge-mcp.d.ts +29 -0
  457. package/dist/platform/knowledge-mcp.js +95 -0
  458. package/dist/platform/knowledge-router.d.ts +64 -0
  459. package/dist/platform/knowledge-router.js +320 -0
  460. package/dist/platform/plugin-child.d.ts +1 -0
  461. package/dist/platform/plugin-child.js +115 -0
  462. package/dist/platform/plugin-contract.d.ts +76 -0
  463. package/dist/platform/plugin-contract.js +53 -0
  464. package/dist/platform/plugin-driver.d.ts +8 -0
  465. package/dist/platform/plugin-driver.js +443 -0
  466. package/dist/platform/plugin-host.d.ts +88 -0
  467. package/dist/platform/plugin-host.js +817 -0
  468. package/dist/platform/plugin-policy.d.ts +3 -0
  469. package/dist/platform/plugin-policy.js +29 -0
  470. package/dist/platform/plugin-services.d.ts +14 -0
  471. package/dist/platform/plugin-services.js +32 -0
  472. package/dist/platform/process-identity.d.ts +9 -0
  473. package/dist/platform/process-identity.js +68 -0
  474. package/dist/platform/runtime-lease.d.ts +4 -0
  475. package/dist/platform/runtime-lease.js +58 -0
  476. package/dist/platform/runtime-root.d.ts +9 -0
  477. package/dist/platform/runtime-root.js +61 -0
  478. package/dist/platform/state-backup.d.ts +92 -0
  479. package/dist/platform/state-backup.js +399 -0
  480. package/dist/plugins/reference/plugin.d.ts +3 -0
  481. package/dist/plugins/reference/plugin.js +13 -0
  482. package/dist/server.js +5 -1
  483. package/dist/terminal-manager.d.ts +7 -0
  484. package/dist/terminal-manager.js +10 -0
  485. package/dist/tool-dispatcher.js +5 -1
  486. package/dist/tools/improved-process-tools.js +4 -0
  487. package/dist/types.d.ts +1 -0
  488. package/dist/version.d.ts +1 -1
  489. package/dist/version.js +1 -1
  490. package/package.json +29 -6
  491. package/skills/mcp-device-context/SKILL.md +40 -0
@@ -0,0 +1,9 @@
1
+ function shellQuote(value) {
2
+ return `'${String(value).replaceAll("'", "''")}'`;
3
+ }
4
+
5
+ export function buildNodeOutputCommand(bytes, { platform = process.platform, execPath = process.execPath } = {}) {
6
+ const executable = shellQuote(execPath);
7
+ const script = shellQuote(`process.stdout.write(Buffer.alloc(${bytes}, 120))`);
8
+ return platform === 'win32' ? `& ${executable} -e ${script}` : `${executable} -e ${script}`;
9
+ }
@@ -0,0 +1,174 @@
1
+ import { pathToFileURL } from 'node:url';
2
+
3
+ function jsonBytes(value) {
4
+ return Buffer.byteLength(JSON.stringify(value), 'utf8');
5
+ }
6
+
7
+ function defaultClassifyTool(tool) {
8
+ if (tool?._meta?.upstream?.source === 'external-mcp') return 'external';
9
+ return 'core';
10
+ }
11
+
12
+ export function measureCatalogPayload({
13
+ toolsPayload = { tools: [] },
14
+ resourcesPayload = { resources: [] },
15
+ templatesPayload = { resourceTemplates: [] },
16
+ promptsPayload = { prompts: [] },
17
+ classifyTool = defaultClassifyTool
18
+ } = {}) {
19
+ const tools = Array.isArray(toolsPayload?.tools) ? toolsPayload.tools : [];
20
+ const resources = Array.isArray(resourcesPayload?.resources) ? resourcesPayload.resources : [];
21
+ const templates = Array.isArray(templatesPayload?.resourceTemplates) ? templatesPayload.resourceTemplates : [];
22
+ const prompts = Array.isArray(promptsPayload?.prompts) ? promptsPayload.prompts : [];
23
+ const groups = {
24
+ core: { count: 0, bytes: 0 },
25
+ external: { count: 0, bytes: 0 },
26
+ other: { count: 0, bytes: 0 }
27
+ };
28
+
29
+ for (const tool of tools) {
30
+ const rawGroup = classifyTool(tool);
31
+ const group = Object.prototype.hasOwnProperty.call(groups, rawGroup) ? rawGroup : 'other';
32
+ groups[group].count += 1;
33
+ groups[group].bytes += jsonBytes(tool);
34
+ }
35
+
36
+ return {
37
+ toolCount: tools.length,
38
+ toolSchemaBytes: jsonBytes(toolsPayload),
39
+ resourceCount: resources.length,
40
+ resourceTemplateCount: templates.length,
41
+ promptCount: prompts.length,
42
+ groups
43
+ };
44
+ }
45
+
46
+ export function parseSyntheticCounts(value) {
47
+ const parts = String(value ?? '').split(',').map(part => Number(part.trim()));
48
+ if (parts.length !== 4 || parts.some(part => !Number.isInteger(part) || part < 0)) {
49
+ throw new Error('Invalid synthetic counts; expected tools,resources,templates,prompts as non-negative integers.');
50
+ }
51
+ const [tools, resources, templates, prompts] = parts;
52
+ return { tools, resources, templates, prompts };
53
+ }
54
+
55
+ function syntheticPayloads(counts) {
56
+ return {
57
+ toolsPayload: {
58
+ tools: Array.from({ length: counts.tools }, (_, index) => ({
59
+ name: `synthetic_tool_${index + 1}`,
60
+ description: 'Synthetic catalog benchmark tool.',
61
+ inputSchema: { type: 'object', properties: {} }
62
+ }))
63
+ },
64
+ resourcesPayload: {
65
+ resources: Array.from({ length: counts.resources }, (_, index) => ({
66
+ uri: `synthetic://resource/${index + 1}`,
67
+ name: `Synthetic resource ${index + 1}`
68
+ }))
69
+ },
70
+ templatesPayload: {
71
+ resourceTemplates: Array.from({ length: counts.templates }, (_, index) => ({
72
+ uriTemplate: `synthetic://template/${index + 1}/{id}`,
73
+ name: `Synthetic template ${index + 1}`
74
+ }))
75
+ },
76
+ promptsPayload: {
77
+ prompts: Array.from({ length: counts.prompts }, (_, index) => ({ name: `synthetic_prompt_${index + 1}` }))
78
+ }
79
+ };
80
+ }
81
+
82
+ function parseArgs(argv) {
83
+ const result = { url: '', bearerEnv: '', synthetic: '' };
84
+ for (let index = 0; index < argv.length; index += 1) {
85
+ const arg = argv[index];
86
+ if (arg === '--url') result.url = argv[++index] || '';
87
+ else if (arg === '--bearer-env') result.bearerEnv = argv[++index] || '';
88
+ else if (arg === '--synthetic') result.synthetic = argv[++index] || '';
89
+ else if (arg === '--help' || arg === '-h') result.help = true;
90
+ else throw new Error(`Unknown argument: ${arg}`);
91
+ }
92
+ return result;
93
+ }
94
+
95
+ function parseMcpResponse(text) {
96
+ const trimmed = String(text || '').trim();
97
+ if (!trimmed) throw new Error('Empty MCP response.');
98
+ if (trimmed.startsWith('{')) return JSON.parse(trimmed);
99
+ const dataLines = trimmed
100
+ .split(/\r?\n/)
101
+ .filter(line => line.startsWith('data:'))
102
+ .map(line => line.slice(5).trim())
103
+ .filter(Boolean);
104
+ if (!dataLines.length) throw new Error(`Unexpected MCP response: ${trimmed.slice(0, 300)}`);
105
+ return JSON.parse(dataLines.join('\n'));
106
+ }
107
+
108
+ async function mcpRequest(url, id, method, token, params = {}) {
109
+ const headers = {
110
+ accept: 'application/json, text/event-stream',
111
+ 'content-type': 'application/json'
112
+ };
113
+ if (token) headers.authorization = `Bearer ${token}`;
114
+ const response = await fetch(url, {
115
+ method: 'POST',
116
+ headers,
117
+ body: JSON.stringify({ jsonrpc: '2.0', id, method, params })
118
+ });
119
+ const text = await response.text();
120
+ if (!response.ok) throw new Error(`MCP HTTP ${response.status}: ${text.slice(0, 300)}`);
121
+ const parsed = parseMcpResponse(text);
122
+ if (parsed?.error) throw new Error(`MCP ${method} failed: ${parsed.error.message || JSON.stringify(parsed.error)}`);
123
+ return parsed?.result || {};
124
+ }
125
+
126
+ async function measureRemoteCatalog({ url, token }) {
127
+ let id = 1;
128
+ await mcpRequest(url, id++, 'initialize', token, {
129
+ protocolVersion: '2025-03-26',
130
+ capabilities: {},
131
+ clientInfo: { name: 'catalog-benchmark', version: '1.0.0' }
132
+ });
133
+ const [toolsPayload, resourcesPayload, templatesPayload, promptsPayload] = await Promise.all([
134
+ mcpRequest(url, id++, 'tools/list', token),
135
+ mcpRequest(url, id++, 'resources/list', token),
136
+ mcpRequest(url, id++, 'resources/templates/list', token),
137
+ mcpRequest(url, id++, 'prompts/list', token)
138
+ ]);
139
+ return measureCatalogPayload({ toolsPayload, resourcesPayload, templatesPayload, promptsPayload });
140
+ }
141
+
142
+ function usage() {
143
+ return [
144
+ 'Usage:',
145
+ ' npm run benchmark:catalog -- --url http://127.0.0.1:8102/mcp [--bearer-env MCP_BEARER_TOKEN]',
146
+ ' npm run benchmark:catalog -- --synthetic 86,75,3,36'
147
+ ].join('\n');
148
+ }
149
+
150
+ export async function main(argv = process.argv.slice(2), env = process.env) {
151
+ const args = parseArgs(argv);
152
+ if (args.help) {
153
+ process.stdout.write(`${usage()}\n`);
154
+ return;
155
+ }
156
+
157
+ let report;
158
+ if (args.synthetic) {
159
+ report = measureCatalogPayload(syntheticPayloads(parseSyntheticCounts(args.synthetic)));
160
+ } else {
161
+ if (!args.url) throw new Error('--url is required unless --synthetic is used.');
162
+ const token = args.bearerEnv ? String(env[args.bearerEnv] || '') : '';
163
+ if (args.bearerEnv && !token) throw new Error(`Bearer token environment variable is empty: ${args.bearerEnv}`);
164
+ report = await measureRemoteCatalog({ url: args.url, token });
165
+ }
166
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
167
+ }
168
+
169
+ if (import.meta.url === pathToFileURL(process.argv[1] || '').href) {
170
+ main().catch(error => {
171
+ console.error(error.message);
172
+ process.exitCode = 1;
173
+ });
174
+ }
@@ -0,0 +1,87 @@
1
+ export function catalogToolBytes(tool) {
2
+ return Buffer.byteLength(JSON.stringify(tool), 'utf8');
3
+ }
4
+
5
+ export function classifyExternalToolLane(tool) {
6
+ const annotations = tool?.annotations;
7
+ return annotations?.readOnlyHint === true &&
8
+ annotations?.destructiveHint === false &&
9
+ annotations?.openWorldHint === false
10
+ ? 'read'
11
+ : 'write';
12
+ }
13
+
14
+ function diagnostics(mode, budgetBytes, tools, eagerTools, deferredTools) {
15
+ const sumBytes = items => items.reduce((sum, tool) => sum + catalogToolBytes(tool), 0);
16
+ return {
17
+ mode,
18
+ budgetBytes,
19
+ total: { count: tools.length, bytes: sumBytes(tools) },
20
+ eager: { count: eagerTools.length, bytes: sumBytes(eagerTools) },
21
+ deferred: { count: deferredTools.length, bytes: sumBytes(deferredTools) }
22
+ };
23
+ }
24
+
25
+ export function selectExternalCatalog(tools = [], externalConfig = {}, servers = []) {
26
+ const mode = externalConfig.exposure_mode || 'direct';
27
+ const budgetBytes = Number(externalConfig.eager_schema_budget_bytes ?? 24576);
28
+ const allowlist = Array.isArray(externalConfig.eager_allowlist) ? externalConfig.eager_allowlist : [];
29
+
30
+ if (mode === 'direct') {
31
+ return {
32
+ eagerTools: [...tools],
33
+ deferredTools: [],
34
+ diagnostics: diagnostics(mode, budgetBytes, tools, tools, [])
35
+ };
36
+ }
37
+ if (mode === 'brokered') {
38
+ return {
39
+ eagerTools: [],
40
+ deferredTools: [...tools],
41
+ diagnostics: diagnostics(mode, budgetBytes, tools, [], tools)
42
+ };
43
+ }
44
+ if (mode !== 'hybrid') throw new Error(`Invalid external exposure mode: ${mode}`);
45
+
46
+ const byName = new Map(tools.map(tool => [tool.name, tool]));
47
+ const selected = [];
48
+ const selectedNames = new Set();
49
+ let usedBytes = 0;
50
+
51
+ for (const name of allowlist) {
52
+ const tool = byName.get(name);
53
+ if (!tool) throw new Error(`External MCP eager allowlist contains unknown tool: ${name}`);
54
+ const bytes = catalogToolBytes(tool);
55
+ if (usedBytes + bytes > budgetBytes) {
56
+ throw new Error(`External MCP eager allowlist exceeds schema budget at ${name}: ${usedBytes + bytes} > ${budgetBytes} bytes`);
57
+ }
58
+ selected.push(tool);
59
+ selectedNames.add(tool.name);
60
+ usedBytes += bytes;
61
+ }
62
+
63
+ const serverOrder = new Map(servers.map((server, index) => [server.id, index]));
64
+ const candidates = tools
65
+ .filter(tool => !selectedNames.has(tool.name) && classifyExternalToolLane(tool) === 'read')
66
+ .sort((left, right) => {
67
+ const leftOrder = serverOrder.get(left?._meta?.upstream?.upstreamId) ?? Number.MAX_SAFE_INTEGER;
68
+ const rightOrder = serverOrder.get(right?._meta?.upstream?.upstreamId) ?? Number.MAX_SAFE_INTEGER;
69
+ if (leftOrder !== rightOrder) return leftOrder - rightOrder;
70
+ return String(left.name).localeCompare(String(right.name));
71
+ });
72
+
73
+ for (const tool of candidates) {
74
+ const bytes = catalogToolBytes(tool);
75
+ if (usedBytes + bytes > budgetBytes) break;
76
+ selected.push(tool);
77
+ selectedNames.add(tool.name);
78
+ usedBytes += bytes;
79
+ }
80
+
81
+ const deferredTools = tools.filter(tool => !selectedNames.has(tool.name));
82
+ return {
83
+ eagerTools: selected,
84
+ deferredTools,
85
+ diagnostics: diagnostics(mode, budgetBytes, tools, selected, deferredTools)
86
+ };
87
+ }
@@ -0,0 +1,20 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { buildDevicePublicContract, classifyDevicePublicContractChanges } from './device-public-contract.mjs';
5
+
6
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
7
+ const fixturePath = path.join(root, 'contracts', 'device-public-contract-v1.json');
8
+ const current = buildDevicePublicContract();
9
+
10
+ if (process.argv.includes('--write')) {
11
+ fs.mkdirSync(path.dirname(fixturePath), { recursive: true });
12
+ fs.writeFileSync(fixturePath, `${JSON.stringify(current, null, 2)}\n`);
13
+ console.log(`Wrote ${path.relative(root, fixturePath)}`);
14
+ process.exit(0);
15
+ }
16
+
17
+ const baseline = JSON.parse(fs.readFileSync(fixturePath, 'utf8'));
18
+ const result = classifyDevicePublicContractChanges(baseline, current);
19
+ console.log(JSON.stringify(result, null, 2));
20
+ if (result.counts.breaking > 0) process.exit(1);
@@ -0,0 +1,221 @@
1
+ import { fail, ok } from './response-utils.mjs';
2
+ import { inspectProject, listProjects, PROJECT_INSPECTION_VIEWS } from '../project-inspection.mjs';
3
+ import { applyToolRisk } from '../tool-risk.mjs';
4
+ import { skillResourceUri } from '../skills/index.mjs';
5
+
6
+ function schema(properties = {}, required = []) {
7
+ return { type: 'object', properties, required, additionalProperties: false };
8
+ }
9
+
10
+ function structuredOutputSchema() {
11
+ return {
12
+ type: 'object',
13
+ properties: {
14
+ ok: { type: 'boolean' },
15
+ tool: { type: 'string' },
16
+ summary: { type: 'string' },
17
+ data: { type: 'object' }
18
+ },
19
+ required: ['ok', 'tool', 'summary', 'data'],
20
+ additionalProperties: false
21
+ };
22
+ }
23
+
24
+ function requireExternalToolBroker(context = {}) {
25
+ if (!context.externalToolBroker) throw new Error('External tool broker is unavailable.');
26
+ return context.externalToolBroker;
27
+ }
28
+
29
+ function requireSkillRegistry(context = {}) {
30
+ if (!context.skillRegistry) throw new Error('Skill registry is unavailable.');
31
+ return context.skillRegistry;
32
+ }
33
+
34
+ function skillCatalog(args = {}, context = {}) {
35
+ const snapshot = requireSkillRegistry(context).snapshot();
36
+ const version = snapshot.catalogVersion;
37
+ if (String(args.known_version || '') === version) return { changed: false, version };
38
+ return {
39
+ changed: true,
40
+ version,
41
+ skills: snapshot.skills.map(skill => ({
42
+ name: skill.name,
43
+ description: skill.description,
44
+ uri: skill.uri,
45
+ revision: skill.skillRevision
46
+ }))
47
+ };
48
+ }
49
+
50
+ function loadSkill(args = {}, context = {}) {
51
+ const registry = requireSkillRegistry(context);
52
+ const skill = registry.getByName(String(args.name || ''));
53
+ if (!skill) throw new Error(`Unknown skill: ${args.name}`);
54
+ const resource = String(args.resource || '').trim();
55
+ if (!resource) {
56
+ return {
57
+ name: skill.name,
58
+ description: skill.description,
59
+ uri: skill.uri,
60
+ revision: skill.skillRevision,
61
+ body: skill.body,
62
+ resources: skill.resources
63
+ };
64
+ }
65
+ if (resource.startsWith('/') || resource.includes('\\') || resource.split('/').some(segment => !segment || segment === '.' || segment === '..')) {
66
+ throw new Error('Invalid skill resource path.');
67
+ }
68
+ const requestedUri = skillResourceUri(skill.name, resource);
69
+ const entry = skill.resources.find(item => item.uri === requestedUri);
70
+ if (!entry) throw new Error(`Unknown resource for ${skill.name}: ${resource}`);
71
+ const loaded = registry.readResource(entry.uri);
72
+ if (!loaded) throw new Error(`Unknown resource for ${skill.name}: ${resource}`);
73
+ return {
74
+ name: skill.name,
75
+ uri: loaded.uri,
76
+ revision: skill.skillRevision,
77
+ mimeType: loaded.mimeType,
78
+ digest: loaded.digest,
79
+ size: loaded.size,
80
+ ...(loaded.text !== undefined ? { text: loaded.text } : { blob: loaded.blob })
81
+ };
82
+ }
83
+
84
+ const TOOL_DEFINITIONS = [
85
+ {
86
+ name: 'skill_catalog',
87
+ description: 'Discover the current reusable skill catalog for clients that do not natively implement the MCP Skills extension. Returns compact metadata only; use load_skill for content.',
88
+ inputSchema: schema({
89
+ known_version: { type: 'string', description: 'Previously observed catalog version; matching versions return changed:false.' }
90
+ }),
91
+ outputSchema: structuredOutputSchema(),
92
+ annotations: { readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
93
+ handler: (args, context) => ok('skill_catalog', 'Read skill catalog', skillCatalog(args, context))
94
+ },
95
+ {
96
+ name: 'load_skill',
97
+ description: 'Load one reusable skill, or one explicitly listed supporting resource, for clients that do not natively implement the MCP Skills extension.',
98
+ inputSchema: schema({
99
+ name: { type: 'string', minLength: 1, description: 'Canonical skill name from skill_catalog.' },
100
+ resource: { type: 'string', description: 'Optional relative resource path from the selected skill manifest.' }
101
+ }, ['name']),
102
+ outputSchema: structuredOutputSchema(),
103
+ annotations: { readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
104
+ handler: (args, context) => ok('load_skill', 'Loaded skill content', loadSkill(args, context))
105
+ },
106
+ {
107
+ name: 'image_preview',
108
+ description: 'Load a bounded image preview from one explicit owned online device for visual inspection.',
109
+ inputSchema: schema({
110
+ device_id: { type: 'string', minLength: 1, description: 'Owned online device containing the image.' },
111
+ path: { type: 'string' },
112
+ file: { type: 'string' },
113
+ sourcePath: { type: 'string' },
114
+ embed: { type: 'boolean', default: true },
115
+ includeImage: { type: 'boolean', default: true },
116
+ includeData: { type: 'boolean', default: true },
117
+ maxBytes: { type: 'number', default: 8388608 }
118
+ }, ['device_id']),
119
+ annotations: { readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
120
+ handler: (args, context) => {
121
+ if (!context.callDeviceTool) throw new Error('Device execution routing is unavailable.');
122
+ return context.callDeviceTool('image_preview', args);
123
+ }
124
+ },
125
+ {
126
+ name: 'project_list',
127
+ description: 'List configured projects for one explicit owned online device. Local absolute paths stay hidden unless path exposure is explicitly enabled.',
128
+ inputSchema: schema({
129
+ device_id: { type: 'string', minLength: 1, description: 'Owned online device id whose configured projects should be listed.' },
130
+ query: { type: 'string', description: 'Optional project id or display-name filter.' },
131
+ cursor: { type: 'string', description: 'Opaque cursor returned by the previous page.' },
132
+ limit: { type: 'integer', minimum: 1, maximum: 200, default: 50 }
133
+ }, ['device_id']),
134
+ outputSchema: structuredOutputSchema(),
135
+ annotations: { readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
136
+ handler: (args, context) => ok('project_list', 'Listed projects', listProjects(context, args))
137
+ },
138
+ {
139
+ name: 'project_inspect',
140
+ description: 'Inspect one configured project through bounded summary, tree, Git, README, or package views. Use read_text_file for generic file bodies.',
141
+ inputSchema: schema({
142
+ device_id: { type: 'string', minLength: 1, description: 'Owned online device id associated with the project.' },
143
+ project_id: { type: 'string', description: 'Configured project id on that device.' },
144
+ view: { type: 'string', enum: [...PROJECT_INSPECTION_VIEWS] },
145
+ depth: { type: 'integer', minimum: 1, maximum: 10, default: 3 },
146
+ staged: { type: 'boolean', default: false },
147
+ cursor: { type: 'string', description: 'Opaque cursor returned by a bounded tree page.' },
148
+ limit: { type: 'integer', minimum: 1, maximum: 500, default: 200 }
149
+ }, ['device_id', 'project_id', 'view']),
150
+ outputSchema: structuredOutputSchema(),
151
+ annotations: { readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
152
+ handler: async (args, context) => ok(
153
+ 'project_inspect',
154
+ `Inspected project ${args.project_id}`,
155
+ await inspectProject(context, { ...args, deviceId: args.device_id, projectId: args.project_id })
156
+ )
157
+ },
158
+ {
159
+ name: 'external_tool_search',
160
+ description: 'Search the bounded external MCP catalog without exposing full deferred schemas. Results are filtered by runtime profile.',
161
+ inputSchema: schema({
162
+ query: { type: 'string', description: 'Optional name/description search text.' },
163
+ server: { type: 'string', description: 'Optional external MCP server id.' },
164
+ lane: { type: 'string', enum: ['read', 'write'], description: 'Optional risk lane filter.' },
165
+ cursor: { type: 'string', description: 'Opaque cursor returned by the previous search page.' },
166
+ limit: { type: 'integer', minimum: 1, maximum: 50, default: 20 }
167
+ }),
168
+ outputSchema: structuredOutputSchema(),
169
+ annotations: { readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
170
+ handler: (args, context) => ok(
171
+ 'external_tool_search',
172
+ 'Searched external MCP tools',
173
+ requireExternalToolBroker(context).search(args, context.runtimeProfile)
174
+ )
175
+ },
176
+ {
177
+ name: 'external_tool_call_read',
178
+ description: 'Invoke one discovered external MCP tool only when its cached annotations place it in the read lane. Arguments are validated against the cached full input schema before forwarding.',
179
+ inputSchema: schema({
180
+ name: { type: 'string', minLength: 1 },
181
+ arguments: { type: 'object', default: {} }
182
+ }, ['name']),
183
+ annotations: { readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
184
+ handler: (args, context) => requireExternalToolBroker(context).call('read', args, context.runtimeProfile)
185
+ },
186
+ {
187
+ name: 'external_tool_call_write',
188
+ description: 'Invoke one discovered external MCP tool only when its cached annotations place it in the write lane. Arguments are validated against the cached full input schema before forwarding.',
189
+ inputSchema: schema({
190
+ name: { type: 'string', minLength: 1 },
191
+ arguments: { type: 'object', default: {} }
192
+ }, ['name']),
193
+ annotations: { readOnlyHint: false, idempotentHint: false, destructiveHint: true, openWorldHint: false },
194
+ handler: (args, context) => requireExternalToolBroker(context).call('write', args, context.runtimeProfile)
195
+ }
196
+ ];
197
+
198
+ const LOCAL_TOOLS = new Map(TOOL_DEFINITIONS.map(tool => [tool.name, tool]));
199
+
200
+ export function isLocalCustomTool(name) {
201
+ return LOCAL_TOOLS.has(String(name || ''));
202
+ }
203
+
204
+ export function listCustomTools(_context = {}) {
205
+ return TOOL_DEFINITIONS.map(tool => applyToolRisk({
206
+ name: tool.name,
207
+ description: tool.description,
208
+ inputSchema: tool.inputSchema,
209
+ ...(tool.outputSchema ? { outputSchema: tool.outputSchema } : {}),
210
+ annotations: { ...tool.annotations }
211
+ }));
212
+ }
213
+
214
+ export async function callCustomTool(name, args = {}, context = {}) {
215
+ const localName = String(name || '');
216
+ const tool = LOCAL_TOOLS.get(localName);
217
+ if (!tool) return fail(localName || 'unknown', 'UNKNOWN_TOOL', `Unknown local tool: ${name}`);
218
+ return await tool.handler(args || {}, context);
219
+ }
220
+
221
+ export const LOCAL_TOOL_NAMES = [...LOCAL_TOOLS.keys()];
@@ -0,0 +1,117 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ export const DEFAULT_EXCLUDES = ['node_modules/**', '.git/**', 'logs/**', 'packages/**', '_zip_temp/**'];
5
+
6
+ export function normalizeWindowsPath(value) {
7
+ return String(value ?? '').trim().replace(/^['"]|['"]$/g, '').replace(/^\\\\\?\\/, '').replaceAll('/', path.sep);
8
+ }
9
+
10
+ export function getTrustedRoots(context = {}) {
11
+ const roots = Array.isArray(context.resolvedRepoRoots) && context.resolvedRepoRoots.length > 0
12
+ ? context.resolvedRepoRoots
13
+ : [context.resolvedRepoRoot || context.packageRoot || process.cwd()];
14
+ return [...new Set(roots.filter(Boolean).map(root => path.resolve(normalizeWindowsPath(root))))];
15
+ }
16
+
17
+ export function assertInsideTrustedRoots(targetPath, roots) {
18
+ const resolved = path.resolve(normalizeWindowsPath(targetPath));
19
+ const trustedRoots = getTrustedRoots({ resolvedRepoRoots: roots });
20
+ const root = trustedRoots.find(candidate => {
21
+ const relative = path.relative(candidate, resolved);
22
+ return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
23
+ });
24
+ if (!root) {
25
+ const error = new Error(`Path is outside current workspace scope: ${targetPath}`);
26
+ error.code = 'PATH_OUT_OF_SCOPE';
27
+ error.details = { path: targetPath, trustedRoots };
28
+ throw error;
29
+ }
30
+ return { path: resolved, root };
31
+ }
32
+
33
+ export function resolveInsideTrustedRoots(inputPath, context = {}, options = {}) {
34
+ const roots = getTrustedRoots(context);
35
+ const base = options.workingDirectory
36
+ ? assertInsideTrustedRoots(options.workingDirectory, roots).path
37
+ : roots[0];
38
+ const raw = inputPath === undefined || inputPath === null || String(inputPath).trim() === '' ? base : normalizeWindowsPath(inputPath);
39
+ const resolved = path.isAbsolute(raw) ? path.resolve(raw) : path.resolve(base, raw);
40
+ const checked = assertInsideTrustedRoots(resolved, roots);
41
+ if (options.mustExist && !fs.existsSync(checked.path)) {
42
+ const error = new Error(`Path does not exist: ${checked.path}`);
43
+ error.code = 'PATH_NOT_FOUND';
44
+ error.details = { path: checked.path };
45
+ throw error;
46
+ }
47
+ return checked;
48
+ }
49
+
50
+ export function toRelativeFromRoot(targetPath, root) {
51
+ return path.relative(path.resolve(root), path.resolve(targetPath)).replaceAll(path.sep, '/');
52
+ }
53
+
54
+ export function defaultExcludePatterns(extra = [], options = {}) {
55
+ const base = DEFAULT_EXCLUDES.filter(pattern => !options.includeGit || pattern !== '.git/**');
56
+ return [...new Set([...base, ...extra])];
57
+ }
58
+
59
+ function escapeRegex(text) {
60
+ return String(text).replace(/[.+^${}()|[\]\\]/g, '\\$&');
61
+ }
62
+
63
+ export function globToRegExp(pattern) {
64
+ const normalized = String(pattern || '**/*').replaceAll('\\', '/');
65
+ let out = '^';
66
+ for (let i = 0; i < normalized.length; i += 1) {
67
+ const ch = normalized[i];
68
+ const next = normalized[i + 1];
69
+ if (ch === '*' && next === '*') {
70
+ const after = normalized[i + 2];
71
+ if (after === '/') {
72
+ out += '(?:.*/)?';
73
+ i += 2;
74
+ } else {
75
+ out += '.*';
76
+ i += 1;
77
+ }
78
+ } else if (ch === '*') {
79
+ out += '[^/]*';
80
+ } else if (ch === '?') {
81
+ out += '[^/]';
82
+ } else {
83
+ out += escapeRegex(ch);
84
+ }
85
+ }
86
+ out += '$';
87
+ return new RegExp(out);
88
+ }
89
+
90
+ export function matchesAnyGlob(relativePath, patterns = ['**/*']) {
91
+ const value = String(relativePath).replaceAll('\\', '/');
92
+ return patterns.some(pattern => globToRegExp(pattern).test(value));
93
+ }
94
+
95
+ export function shouldExclude(relativePath, patterns = []) {
96
+ const value = String(relativePath).replaceAll('\\', '/');
97
+ return patterns.some(pattern => globToRegExp(pattern).test(value) || value === String(pattern).replace(/\/\*\*$/, ''));
98
+ }
99
+
100
+ export async function walkFiles(startPath, root, options = {}) {
101
+ const include = options.include?.length ? options.include : ['**/*'];
102
+ const exclude = options.exclude || defaultExcludePatterns();
103
+ const files = [];
104
+ async function visit(current) {
105
+ const stat = await fs.promises.stat(current);
106
+ const rel = toRelativeFromRoot(current, root);
107
+ if (rel && shouldExclude(rel, exclude)) return;
108
+ if (stat.isDirectory()) {
109
+ const entries = await fs.promises.readdir(current);
110
+ for (const entry of entries) await visit(path.join(current, entry));
111
+ return;
112
+ }
113
+ if (stat.isFile() && matchesAnyGlob(rel, include) && !shouldExclude(rel, exclude)) files.push(current);
114
+ }
115
+ await visit(startPath);
116
+ return files;
117
+ }
@@ -0,0 +1,34 @@
1
+ export function textJson(value) {
2
+ return { content: [{ type: 'text', text: JSON.stringify(value, null, 2) }] };
3
+ }
4
+
5
+ export function ok(tool, summary, data = {}) {
6
+ const value = { ok: true, tool: String(tool), summary, data };
7
+ return { ...textJson(value), structuredContent: value };
8
+ }
9
+
10
+ export function fail(tool, code, message, details = {}) {
11
+ return textJson({ ok: false, tool: String(tool), error: { code, message, details } });
12
+ }
13
+
14
+ export function redactSecret(value) {
15
+ const text = String(value ?? '');
16
+ if (text.length <= 8) return '****';
17
+ return `${text.slice(0, 4)}...${text.slice(-4)}`;
18
+ }
19
+
20
+ export function truncateText(text, maxBytes = 200000) {
21
+ const value = String(text ?? '');
22
+ const limit = Number(maxBytes);
23
+ if (!Number.isFinite(limit) || limit <= 0) return { text: '', truncated: value.length > 0 };
24
+ const bytes = Buffer.byteLength(value, 'utf8');
25
+ if (bytes <= limit) return { text: value, truncated: false };
26
+ let end = Math.min(value.length, limit);
27
+ while (Buffer.byteLength(value.slice(0, end), 'utf8') > limit && end > 0) end -= 1;
28
+ return { text: value.slice(0, end), truncated: true };
29
+ }
30
+
31
+ export function parseToolResult(result) {
32
+ const text = result?.content?.find?.(entry => entry?.type === 'text')?.text ?? '{}';
33
+ return JSON.parse(text);
34
+ }