@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,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
+ }