wormclaude 1.0.118 → 1.0.120

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 (233) hide show
  1. package/dist/theme.js +1 -1
  2. package/dist/tools.js +14 -5
  3. package/package.json +1 -1
  4. package/skills/scan/SKILL.md +37 -0
  5. package/skills/build-mcp-app/SKILL.md +0 -393
  6. package/skills/build-mcp-app/references/abuse-protection.md +0 -60
  7. package/skills/build-mcp-app/references/apps-sdk-messages.md +0 -227
  8. package/skills/build-mcp-app/references/directory-checklist.md +0 -18
  9. package/skills/build-mcp-app/references/iframe-sandbox.md +0 -164
  10. package/skills/build-mcp-app/references/payload-budgeting.md +0 -54
  11. package/skills/build-mcp-app/references/widget-templates.md +0 -249
  12. package/skills/build-mcp-server/SKILL.md +0 -222
  13. package/skills/build-mcp-server/references/auth.md +0 -108
  14. package/skills/build-mcp-server/references/deploy-cloudflare-workers.md +0 -106
  15. package/skills/build-mcp-server/references/elicitation.md +0 -129
  16. package/skills/build-mcp-server/references/remote-http-scaffold.md +0 -211
  17. package/skills/build-mcp-server/references/resources-and-prompts.md +0 -122
  18. package/skills/build-mcp-server/references/server-capabilities.md +0 -164
  19. package/skills/build-mcp-server/references/tool-design.md +0 -189
  20. package/skills/build-mcp-server/references/versions.md +0 -25
  21. package/skills/build-mcpb/SKILL.md +0 -200
  22. package/skills/build-mcpb/references/local-security.md +0 -149
  23. package/skills/build-mcpb/references/manifest-schema.md +0 -156
  24. package/skills/docx/script/__init__.py +0 -1
  25. package/skills/docx/script/accept_chages.py +0 -135
  26. package/skills/docx/script/comment.py +0 -318
  27. package/skills/docx/script/office/helpers/__init__.py +0 -0
  28. package/skills/docx/script/office/helpers/merge_runs.py +0 -199
  29. package/skills/docx/script/office/helpers/simplify_redlines.py +0 -197
  30. package/skills/docx/script/office/pack.py +0 -159
  31. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  32. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  33. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  34. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  35. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  36. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  37. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  38. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  39. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  40. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  41. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  42. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  43. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  44. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  45. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  46. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  47. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  48. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  49. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  50. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  51. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  52. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  53. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  54. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  55. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  56. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  57. package/skills/docx/script/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  58. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  59. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  60. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  61. package/skills/docx/script/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  62. package/skills/docx/script/office/schemas/mce/mc.xsd +0 -75
  63. package/skills/docx/script/office/schemas/microsoft/wml-2010.xsd +0 -560
  64. package/skills/docx/script/office/schemas/microsoft/wml-2012.xsd +0 -67
  65. package/skills/docx/script/office/schemas/microsoft/wml-2018.xsd +0 -14
  66. package/skills/docx/script/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  67. package/skills/docx/script/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  68. package/skills/docx/script/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  69. package/skills/docx/script/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  70. package/skills/docx/script/office/soffice.py +0 -183
  71. package/skills/docx/script/office/unpack.py +0 -132
  72. package/skills/docx/script/office/validate.py +0 -117
  73. package/skills/docx/script/office/validators/__init__.py +0 -15
  74. package/skills/docx/script/office/validators/base.py +0 -851
  75. package/skills/docx/script/office/validators/docx.py +0 -446
  76. package/skills/docx/script/office/validators/pptx.py +0 -275
  77. package/skills/docx/script/office/validators/redlining.py +0 -247
  78. package/skills/docx/script/templates/comments.xml +0 -3
  79. package/skills/docx/script/templates/commentsExtended.xml +0 -3
  80. package/skills/docx/script/templates/commentsExtensible.xml +0 -3
  81. package/skills/docx/script/templates/commentsIds.xml +0 -3
  82. package/skills/docx/script/templates/people.xml +0 -3
  83. package/skills/docx/skill.md +0 -593
  84. package/skills/explain.md +0 -14
  85. package/skills/frontend-design/SKILL.md +0 -42
  86. package/skills/pdf/FORMS.md +0 -294
  87. package/skills/pdf/REFERENCE.md +0 -612
  88. package/skills/pdf/SKILL.md +0 -314
  89. package/skills/pdf/scripts/check_bounding_boxes.py +0 -65
  90. package/skills/pdf/scripts/check_fillable_fields.py +0 -11
  91. package/skills/pdf/scripts/convert_pdf_to_images.py +0 -33
  92. package/skills/pdf/scripts/create_validation_image.py +0 -37
  93. package/skills/pdf/scripts/extract_form_field_info.py +0 -122
  94. package/skills/pdf/scripts/extract_form_structure.py +0 -115
  95. package/skills/pdf/scripts/fill_fillable_fields.py +0 -98
  96. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -107
  97. package/skills/playground/SKILL.md +0 -77
  98. package/skills/playground/templates/code-map.md +0 -158
  99. package/skills/playground/templates/concept-map.md +0 -73
  100. package/skills/playground/templates/data-explorer.md +0 -67
  101. package/skills/playground/templates/design-playground.md +0 -67
  102. package/skills/playground/templates/diff-review.md +0 -179
  103. package/skills/playground/templates/document-critique.md +0 -171
  104. package/skills/pptx/SKILL.md +0 -230
  105. package/skills/pptx/editing.md +0 -205
  106. package/skills/pptx/pptxgenjs.md +0 -437
  107. package/skills/pptx/scripts/__init__.py +0 -0
  108. package/skills/pptx/scripts/add_slide.py +0 -195
  109. package/skills/pptx/scripts/clean.py +0 -286
  110. package/skills/pptx/scripts/office/helpers/__init__.py +0 -0
  111. package/skills/pptx/scripts/office/helpers/merge_runs.py +0 -199
  112. package/skills/pptx/scripts/office/helpers/simplify_redlines.py +0 -197
  113. package/skills/pptx/scripts/office/pack.py +0 -159
  114. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  115. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  116. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  117. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  118. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  119. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  120. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  121. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  122. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  123. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  124. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  125. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  126. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  127. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  128. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  129. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  130. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  131. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  132. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  133. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  134. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  135. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  136. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  137. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  138. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  139. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  140. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  141. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  142. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  143. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  144. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  145. package/skills/pptx/scripts/office/schemas/mce/mc.xsd +0 -75
  146. package/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  147. package/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  148. package/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  149. package/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  150. package/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  151. package/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  152. package/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  153. package/skills/pptx/scripts/office/soffice.py +0 -183
  154. package/skills/pptx/scripts/office/unpack.py +0 -132
  155. package/skills/pptx/scripts/office/validate.py +0 -117
  156. package/skills/pptx/scripts/office/validators/__init__.py +0 -15
  157. package/skills/pptx/scripts/office/validators/base.py +0 -851
  158. package/skills/pptx/scripts/office/validators/docx.py +0 -446
  159. package/skills/pptx/scripts/office/validators/pptx.py +0 -275
  160. package/skills/pptx/scripts/office/validators/redlining.py +0 -247
  161. package/skills/pptx/scripts/thumbnail.py +0 -289
  162. package/skills/recon.md +0 -16
  163. package/skills/security-audit/SKILL.md +0 -26
  164. package/skills/talent-creator/SKILL.md +0 -486
  165. package/skills/talent-creator/agents/analyzer.md +0 -274
  166. package/skills/talent-creator/agents/comparator.md +0 -202
  167. package/skills/talent-creator/agents/grader.md +0 -223
  168. package/skills/talent-creator/assets/eval_review.html +0 -146
  169. package/skills/talent-creator/eval-viewer/generate_review.py +0 -471
  170. package/skills/talent-creator/eval-viewer/viewer.html +0 -1325
  171. package/skills/talent-creator/references/schemas.md +0 -430
  172. package/skills/talent-creator/scripts/__init__.py +0 -0
  173. package/skills/talent-creator/scripts/aggregate_benchmark.py +0 -401
  174. package/skills/talent-creator/scripts/generate_report.py +0 -326
  175. package/skills/talent-creator/scripts/improve_description.py +0 -247
  176. package/skills/talent-creator/scripts/package_skill.py +0 -136
  177. package/skills/talent-creator/scripts/quick_validate.py +0 -146
  178. package/skills/talent-creator/scripts/run_eval.py +0 -310
  179. package/skills/talent-creator/scripts/run_loop.py +0 -328
  180. package/skills/talent-creator/scripts/utils.py +0 -47
  181. package/skills/xlsx/SKILL.md +0 -300
  182. package/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
  183. package/skills/xlsx/scripts/office/helpers/merge_runs.py +0 -199
  184. package/skills/xlsx/scripts/office/helpers/simplify_redlines.py +0 -197
  185. package/skills/xlsx/scripts/office/pack.py +0 -159
  186. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  187. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  188. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  189. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  190. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  191. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  192. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  193. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  194. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  195. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  196. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  197. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  198. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  199. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  200. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  201. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  202. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  203. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  204. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  205. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  206. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  207. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  208. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  209. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  210. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  211. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  212. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  213. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  214. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  215. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  216. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  217. package/skills/xlsx/scripts/office/schemas/mce/mc.xsd +0 -75
  218. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  219. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  220. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  221. package/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  222. package/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  223. package/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  224. package/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  225. package/skills/xlsx/scripts/office/soffice.py +0 -183
  226. package/skills/xlsx/scripts/office/unpack.py +0 -132
  227. package/skills/xlsx/scripts/office/validate.py +0 -117
  228. package/skills/xlsx/scripts/office/validators/__init__.py +0 -15
  229. package/skills/xlsx/scripts/office/validators/base.py +0 -851
  230. package/skills/xlsx/scripts/office/validators/docx.py +0 -446
  231. package/skills/xlsx/scripts/office/validators/pptx.py +0 -275
  232. package/skills/xlsx/scripts/office/validators/redlining.py +0 -247
  233. package/skills/xlsx/scripts/recalc.py +0 -184
package/dist/theme.js CHANGED
@@ -16,4 +16,4 @@ export const theme = {
16
16
  synType: '#a78bfa', // tip/sınıf adları, sabitler
17
17
  synProp: '#e0e0e0', // özellik/anahtar adları
18
18
  };
19
- export const VERSION = '1.0.118';
19
+ export const VERSION = '1.0.120';
package/dist/tools.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // OpenAI function şemaları + Node executor'ları. Açıklamalar ve davranışlar
3
3
  // WormClaude'un gerçek prompt.ts/şemalarından alınmıştır; sadece marka adı ve
4
4
  // WormClaude'da bulunmayan araç referansları (Agent tool, sandbox) uyarlandı.
5
- import { execSync, spawn } from 'node:child_process';
5
+ import { execSync, spawn, spawnSync } from 'node:child_process';
6
6
  import * as fs from 'node:fs';
7
7
  import * as os from 'node:os';
8
8
  import * as path from 'node:path';
@@ -50,10 +50,13 @@ function runBashCapturingCwd(command, timeout) {
50
50
  const cwd = getBashCwd();
51
51
  const opts = { encoding: 'utf8', timeout, maxBuffer: 10 * 1024 * 1024, windowsHide: true, cwd };
52
52
  if (process.platform === 'win32') {
53
- // stderr'i yakala: yoksa cmd.exe stderr'i terminale "inherit" eder (curl'ün "% Total"
54
- // progress meter'ı, hata mesajları ekrana sızar). 2>&1 ile stdout'a birleştir tek akış.
55
- const _cmd = /2>&1|2>\s*nul/i.test(command) ? command : command + ' 2>&1';
56
- const out = execSync(_cmd, opts);
53
+ // spawnSync: stdout+stderr'i AYRI yakalar (komutu DEĞİŞTİRMEDEN) curl'ün "% Total" progress
54
+ // meter'ı terminale sızmaz. execSync stderr'i inherit ederdi; `2>&1` ise zincirli (A && B)
55
+ // komutlarda yalnız SON komutun stderr'ini yakalıyordu (ilkininki sızıyordu).
56
+ const r = spawnSync(command, { ...opts, shell: true });
57
+ if (r.error)
58
+ throw r.error;
59
+ const out = (r.stdout || '') + (r.stderr || '');
57
60
  // best-effort: "cd <hedef>" / "cd /d <hedef>" (zincirsiz tek komut)
58
61
  const m = /^\s*cd\s+(?:\/d\s+)?"?([^"&|<>]+?)"?\s*$/i.exec(command);
59
62
  if (m) {
@@ -64,6 +67,12 @@ function runBashCapturingCwd(command, timeout) {
64
67
  }
65
68
  catch { /* yok say */ }
66
69
  }
70
+ if (typeof r.status === 'number' && r.status !== 0) {
71
+ const e = new Error(out || `Command failed (exit ${r.status})`);
72
+ e.stdout = out;
73
+ e.status = r.status;
74
+ throw e;
75
+ }
67
76
  return out;
68
77
  }
69
78
  // POSIX
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wormclaude",
3
- "version": "1.0.118",
3
+ "version": "1.0.120",
4
4
  "description": "WormClaude CLI - uncensored security+code assistant (ink TUI, Claude-style)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: scan
3
+ description: Hedef web sitesini sistematik güvenlik taramasından geçirir (curl-tabanlı, Windows-uyumlu, dizginli)
4
+ ---
5
+
6
+ # GÖREV: Hedef sitenin güvenlik taraması
7
+
8
+ Hedef URL aşağıda **"Kullanıcıdan ek bağlam"** bölümünde verildi. O hedefe odaklı, SİSTEMATİK ve KISA bir güvenlik taraması yap. Konuşma değil, İŞ.
9
+
10
+ ## KESİN KURALLAR (uymazsan görev BAŞARISIZ)
11
+ - SADECE `curl` ve **Read/Grep araçlarını** kullan. ASLA grep/sed/awk/openssl/hydra/nmap/sqlmap çalıştırma (Windows = cmd.exe, bunlar YOK).
12
+ - **PLAN/AÇIKLAMA YAZMA.** "Şimdi şunu yapacağım, sonra bunu..." cümleleri YASAK. Her adımda TEK komut, sonucu TEK SATIR bulgu.
13
+ - Komut çıktısını (header listesi, HTML, curl gövdesi) **TEKRAR YAZMA** — araç zaten gösteriyor. Sadece SONUCU yorumla.
14
+ - **Aynı komutu iki kez çalıştırma.** Cevap geldiyse geç.
15
+ - Bir komut "not recognized" derse o aracı bir daha DENEME, curl'e geç.
16
+ - HTML çekersen, içeriği cevabına KOPYALAMA. Gerekirse Grep aracıyla ara (head_limit küçük tut).
17
+ - Toplam ~6-8 komut yeter. Bitince RAPOR ver ve DUR.
18
+
19
+ ## ADIMLAR (sırayla — her biri 1 komut + 1 satır bulgu)
20
+ 1. **Header + yönlendirme:** `curl -sI <hedef>` → durum kodu + güvenlik header'ları (HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy). EKSİK olanları not et.
21
+ 2. **robots.txt:** `curl -s <hedef>/robots.txt` → yasaklı/izinli yollar (tek satır).
22
+ 3. **Yaygın endpoint'ler:** `curl -sI <hedef>/admin` `/login` `/api` `/.env` `/.git/config` → hangisi yönlendirme DIŞI (200/403) yanıt veriyor.
23
+ 4. **Reflected XSS:** `curl -s "<hedef>/?q=<x>test</x>"` → girdi yanıtta aynen yansıyor mu.
24
+ 5. **SQLi hata:** `curl -s "<hedef>/?id=1'"` → SQL hata mesajı (SQL syntax, mysql, etc.) çıkıyor mu.
25
+
26
+ > Site bakım modundaysa (tüm yollar /bakim'e 3xx) → bunu BİR KEZ not et, gereksiz tekrar tarama YAPMA, mevcut bulgularla rapora geç.
27
+
28
+ ## RAPOR (tüm adımlar bitince — TAM bu formatta, kısa)
29
+ ## 🔒 Güvenlik Taraması: <hedef>
30
+ - **Durum:** <kod / yönlendirme / bakım modu>
31
+ - **Güvenlik header'ları:** ✅ <var olanlar> · ❌ <eksik olanlar>
32
+ - **Açık endpoint'ler:** <bulunanlar veya "hepsi yönlendiriyor">
33
+ - **Zafiyetler:** <XSS / SQLi / ... veya "tespit edilmedi">
34
+ - **Risk:** Düşük / Orta / Yüksek
35
+ - **Öneriler:** <1-2 kısa madde>
36
+
37
+ Raporu verdikten sonra DUR. Yeni komut çalıştırma.
@@ -1,393 +0,0 @@
1
- ---
2
- name: build-mcp-app
3
- description: Reach for this skill when someone wants to build an "MCP app", bolt "interactive UI" or "widgets" onto an MCP server, "render components in chat", create "MCP UI resources", make a tool that pops a "form", "picker", "dashboard", or "confirmation dialog" inline in the conversation, or brings up the "apps SDK" in an MCP context. Use it AFTER the build-mcp-server skill has nailed down the deployment model, or when the user already knows they want UI widgets.
4
- license: WormClaude
5
- version: 0.1.0
6
- ---
7
-
8
- # Build an MCP App (Interactive UI Widgets)
9
-
10
- An MCP app is an ordinary MCP server that **additionally serves UI resources** — interactive components that render inline in the chat surface. Write it once and it runs in WormClaude *and* ChatGPT, plus any other host that implements the apps surface.
11
-
12
- The UI layer is **purely additive**. Underneath, it's still tools, resources, and the same wire protocol. If you've never built a plain MCP server, the `build-mcp-server` skill covers that base layer; this skill stacks widgets on top of it.
13
-
14
- > **Testing in WormClaude:** Add the server as a custom connector in claude.ai (through a Cloudflare tunnel for local dev) — this puts the real iframe sandbox and `hostContext` through their paces. See https://claude.com/docs/connectors/building/testing.
15
-
16
- ## WormClaude host specifics
17
-
18
- | `_meta.ui.*` key | Where | Effect |
19
- |---|---|---|
20
- | `resourceUri` | tool | Which `ui://` resource the host renders for this tool's results. |
21
- | `visibility: ["app"]` | tool | Keep a widget-only helper tool (e.g. a geometry/image fetcher invoked through `callServerTool`) out of WormClaude's tool list. |
22
- | `prefersBorder: false` | resource | Remove the host's outer card border (mobile). |
23
- | `csp.{connectDomains, resourceDomains, baseUriDomains}` | resource | Declare external origins; the default blocks everything. `frameDomains` is currently restricted in WormClaude. |
24
-
25
- - `hostContext.safeAreaInsets: {top, right, bottom, left}` (px) — respect these for notches and the composer overlay.
26
- - Directory submission needs OAuth or **authless** (`none`) — static bearer is private-deploy only and blocks listing — along with tool `annotations` and 3–5 PNG screenshots; see `references/directory-checklist.md`.
27
-
28
- ---
29
-
30
- ## When a widget beats plain text
31
-
32
- Don't bolt on UI just because you can — most tools are perfectly fine returning text or JSON. Add a widget only when one of these holds:
33
-
34
- | Signal | Widget type |
35
- |---|---|
36
- | Tool needs structured input WormClaude can't reliably infer | Form |
37
- | User has to pick from a list WormClaude can't rank (files, contacts, records) | Picker / table |
38
- | A destructive or billable action needs explicit confirmation | Confirm dialog |
39
- | Output is spatial or visual (charts, maps, diffs, previews) | Display widget |
40
- | A long-running job the user wants to watch | Progress / live status |
41
-
42
- If none of these apply, drop the widget. Text is quicker to build and quicker for the user.
43
-
44
- ---
45
-
46
- ## Widgets vs Elicitation — route correctly
47
-
48
- Before you build a widget, check whether **elicitation** already covers the case. Elicitation is spec-native, needs no UI code, and runs in any compliant host.
49
-
50
- | Need | Elicitation | Widget |
51
- |---|---|---|
52
- | Confirm yes/no | ✅ | overkill |
53
- | Pick from short enum | ✅ | overkill |
54
- | Fill a flat form (name, email, date) | ✅ | overkill |
55
- | Pick from a large/searchable list | ❌ (no scroll/search) | ✅ |
56
- | Visual preview before choosing | ❌ | ✅ |
57
- | Chart / map / diff view | ❌ | ✅ |
58
- | Live-updating progress | ❌ | ✅ |
59
-
60
- If elicitation handles it, go with elicitation. See `../build-mcp-server/references/elicitation.md`.
61
-
62
- ---
63
-
64
- ## Architecture: two deployment shapes
65
-
66
- ### Remote MCP app (most common)
67
-
68
- A hosted streamable-HTTP server. Widget templates are served as **resources**, and tool results point at them. The host fetches the resource, renders it inside an iframe sandbox, and relays messages between the widget and WormClaude.
69
-
70
- ```
71
- ┌──────────┐ tools/call ┌────────────┐
72
- │ Claude │─────────────> │ MCP server │
73
- │ host │<── result ────│ (remote) │
74
- │ │ + widget ref │ │
75
- │ │ │ │
76
- │ │ resources/read│ │
77
- │ │─────────────> │ widget │
78
- │ ┌──────┐ │<── template ──│ HTML/JS │
79
- │ │iframe│ │ └────────────┘
80
- │ │widget│ │
81
- │ └──────┘ │
82
- └──────────┘
83
- ```
84
-
85
- ### MCPB-packaged MCP app (local + UI)
86
-
87
- The same widget mechanism, except the server runs locally inside an MCPB bundle. Use this when the widget has to drive a **local** application — say, a file picker that browses the real local disk, or a dialog that controls a desktop app.
88
-
89
- For the MCPB packaging mechanics, hand off to the **`build-mcpb`** skill. Everything below holds for both shapes.
90
-
91
- ---
92
-
93
- ## How widgets attach to tools
94
-
95
- A widget-enabled tool comes with **two separate registrations**:
96
-
97
- 1. **The tool** points to a UI resource via `_meta.ui.resourceUri`. Its handler returns plain text/JSON — NOT the HTML.
98
- 2. **The resource** is registered on its own and serves the HTML.
99
-
100
- When WormClaude calls the tool, the host notices `_meta.ui.resourceUri`, fetches that resource, renders it in an iframe, and feeds the tool's return value into the iframe through the `ontoolresult` event.
101
-
102
- ```typescript
103
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
104
- import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE }
105
- from "@modelcontextprotocol/ext-apps/server";
106
- import { z } from "zod";
107
-
108
- const server = new McpServer({ name: "contacts", version: "1.0.0" });
109
-
110
- // 1. The tool — returns DATA, declares which UI to show
111
- registerAppTool(server, "pick_contact", {
112
- description: "Open an interactive contact picker",
113
- annotations: { title: "Pick Contact", readOnlyHint: true },
114
- inputSchema: { filter: z.string().optional() },
115
- _meta: { ui: { resourceUri: "ui://widgets/contact-picker.html" } },
116
- }, async ({ filter }) => {
117
- const contacts = await db.contacts.search(filter);
118
- // Plain JSON — the widget receives this via ontoolresult
119
- return { content: [{ type: "text", text: JSON.stringify(contacts) }] };
120
- });
121
-
122
- // 2. The resource — serves the HTML
123
- registerAppResource(
124
- server,
125
- "Contact Picker",
126
- "ui://widgets/contact-picker.html",
127
- {},
128
- async () => ({
129
- contents: [{
130
- uri: "ui://widgets/contact-picker.html",
131
- mimeType: RESOURCE_MIME_TYPE,
132
- text: pickerHtml, // your HTML string
133
- }],
134
- }),
135
- );
136
- ```
137
-
138
- The `ui://` URI scheme is just a convention. The mime type MUST be `RESOURCE_MIME_TYPE` (`"text/html;profile=mcp-app"`) — that's how the host knows to render it as an interactive iframe instead of merely showing the source.
139
-
140
- ---
141
-
142
- ## Widget runtime — the `App` class
143
-
144
- Inside the iframe, your script communicates with the host through the `App` class from `@modelcontextprotocol/ext-apps`. It's a **persistent, two-way connection** — the widget stays alive for as long as the conversation is active, taking in new tool results and pushing out user actions.
145
-
146
- ```html
147
- <script type="module">
148
- /* ext-apps bundle inlined at build time → globalThis.ExtApps */
149
- /*__EXT_APPS_BUNDLE__*/
150
- const { App } = globalThis.ExtApps;
151
-
152
- const app = new App({ name: "ContactPicker", version: "1.0.0" }, {});
153
-
154
- // Set handlers BEFORE connecting
155
- app.ontoolresult = ({ content }) => {
156
- const contacts = JSON.parse(content[0].text);
157
- render(contacts);
158
- };
159
-
160
- await app.connect();
161
-
162
- // Later, when the user clicks something:
163
- function onPick(contact) {
164
- app.sendMessage({
165
- role: "user",
166
- content: [{ type: "text", text: `Selected contact: ${contact.id}` }],
167
- });
168
- }
169
- </script>
170
- ```
171
-
172
- At startup the server swaps the `/*__EXT_APPS_BUNDLE__*/` placeholder for the contents of `@modelcontextprotocol/ext-apps/app-with-deps` — `references/iframe-sandbox.md` explains why this is required and gives the rewrite snippet. **Don't** `import { App } from "https://esm.sh/..."`; the iframe's CSP blocks the transitive dependency fetches and the widget comes up blank.
173
-
174
- | Method | Direction | Use for |
175
- |---|---|---|
176
- | `app.ontoolresult = fn` | Host → widget | Receive the tool's return value |
177
- | `app.ontoolinput = fn` | Host → widget | Receive the tool's input args (what Claude passed) |
178
- | `app.sendMessage({...})` | Widget → host | Inject a message into the conversation |
179
- | `app.updateModelContext({...})` | Widget → host | Update context silently (no visible message) |
180
- | `app.callServerTool({name, arguments})` | Widget → server | Call another tool on your server |
181
- | `app.openLink({url})` | Widget → host | Open a URL in a new tab (sandbox blocks `window.open`) |
182
- | `app.getHostContext()` / `app.onhostcontextchanged` | Host → widget | Theme, host CSS vars, `containerDimensions`, `displayMode`, `deviceCapabilities` |
183
- | `app.requestDisplayMode({mode})` | Widget → host | Ask for `inline` / `pip` / `fullscreen` |
184
- | `app.downloadFile({name, mimeType, content})` | Widget → host | Host-mediated download (base64 content) |
185
- | `new App(info, caps, {autoResize: true})` | — | Iframe height tracks rendered content |
186
-
187
- `sendMessage` is the usual "user picked something, let WormClaude know" path. `updateModelContext` is for state WormClaude should be aware of but that shouldn't clutter the chat. `openLink` is **required** for any outbound navigation — the sandbox attribute blocks `window.open` and `<a target="_blank">`.
188
-
189
- **What widgets cannot do:**
190
- - Reach the host page's DOM, cookies, or storage
191
- - Make network calls to arbitrary origins (CSP-restricted — go through `callServerTool`)
192
- - Open popups or navigate on their own — use `app.openLink({url})`
193
- - Load remote images reliably — inline them as `data:` URLs server-side
194
-
195
- Keep widgets **small and single-purpose**. A picker picks. A chart displays. Don't cram a whole sub-app into the iframe — break it into several tools, each with a focused widget.
196
-
197
- ---
198
-
199
- ## Scaffold: minimal picker widget
200
-
201
- **Install:**
202
-
203
- ```bash
204
- npm install @modelcontextprotocol/sdk @modelcontextprotocol/ext-apps zod express
205
- ```
206
-
207
- **Server (`src/server.ts`):**
208
-
209
- ```typescript
210
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
211
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
212
- import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE }
213
- from "@modelcontextprotocol/ext-apps/server";
214
- import express from "express";
215
- import { readFileSync } from "node:fs";
216
- import { createRequire } from "node:module";
217
- import { z } from "zod";
218
-
219
- const require = createRequire(import.meta.url);
220
- const server = new McpServer({ name: "contact-picker", version: "1.0.0" });
221
-
222
- // Inline the ext-apps browser bundle into the widget HTML.
223
- // The iframe CSP blocks CDN script fetches — bundling is mandatory.
224
- const bundle = readFileSync(
225
- require.resolve("@modelcontextprotocol/ext-apps/app-with-deps"), "utf8",
226
- ).replace(/export\{([^}]+)\};?\s*$/, (_, body) =>
227
- "globalThis.ExtApps={" +
228
- body.split(",").map((p) => {
229
- const [local, exported] = p.split(" as ").map((s) => s.trim());
230
- return `${exported ?? local}:${local}`;
231
- }).join(",") + "};",
232
- );
233
- const pickerHtml = readFileSync("./widgets/picker.html", "utf8")
234
- .replace("/*__EXT_APPS_BUNDLE__*/", () => bundle);
235
-
236
- registerAppTool(server, "pick_contact", {
237
- description: "Open an interactive contact picker. User selects one contact.",
238
- annotations: { title: "Pick Contact", readOnlyHint: true },
239
- inputSchema: { filter: z.string().optional().describe("Name/email prefix filter") },
240
- _meta: { ui: { resourceUri: "ui://widgets/picker.html" } },
241
- }, async ({ filter }) => {
242
- const contacts = await db.contacts.search(filter ?? "");
243
- return { content: [{ type: "text", text: JSON.stringify(contacts) }] };
244
- });
245
-
246
- registerAppResource(server, "Contact Picker", "ui://widgets/picker.html", {},
247
- async () => ({
248
- contents: [{ uri: "ui://widgets/picker.html", mimeType: RESOURCE_MIME_TYPE, text: pickerHtml }],
249
- }),
250
- );
251
-
252
- const app = express();
253
- app.use(express.json());
254
- app.post("/mcp", async (req, res) => {
255
- const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
256
- res.on("close", () => transport.close());
257
- await server.connect(transport);
258
- await transport.handleRequest(req, res, req.body);
259
- });
260
- app.listen(process.env.PORT ?? 3000);
261
- ```
262
-
263
- For local-only widget apps (driving a desktop app, reading local files), switch the transport to `StdioServerTransport` and package it with the `build-mcpb` skill.
264
-
265
- **Widget (`widgets/picker.html`):**
266
-
267
- ```html
268
- <!doctype html>
269
- <meta charset="utf-8" />
270
- <style>
271
- body { font: 14px system-ui; margin: 0; }
272
- ul { list-style: none; padding: 0; margin: 0; max-height: 300px; overflow-y: auto; }
273
- li { padding: 10px 14px; cursor: pointer; border-bottom: 1px solid #eee; }
274
- li:hover { background: #f5f5f5; }
275
- .sub { color: #666; font-size: 12px; }
276
- </style>
277
- <ul id="list"></ul>
278
- <script type="module">
279
- /*__EXT_APPS_BUNDLE__*/
280
- const { App } = globalThis.ExtApps;
281
- (async () => {
282
- const app = new App({ name: "ContactPicker", version: "1.0.0" }, {});
283
- const ul = document.getElementById("list");
284
-
285
- app.ontoolresult = ({ content }) => {
286
- const contacts = JSON.parse(content[0].text);
287
- ul.innerHTML = "";
288
- for (const c of contacts) {
289
- const li = document.createElement("li");
290
- li.innerHTML = `<div>${c.name}</div><div class="sub">${c.email}</div>`;
291
- li.addEventListener("click", () => {
292
- app.sendMessage({
293
- role: "user",
294
- content: [{ type: "text", text: `Selected contact: ${c.id} (${c.name})` }],
295
- });
296
- });
297
- ul.append(li);
298
- }
299
- };
300
-
301
- await app.connect();
302
- })();
303
- </script>
304
- ```
305
-
306
- See `references/widget-templates.md` for additional widget shapes.
307
-
308
- ---
309
-
310
- ## Design notes that save you a rewrite
311
-
312
- **One widget per tool.** Don't give in to the temptation to build a single mega-widget that does it all. One tool → one focused widget → one clear result shape. WormClaude reasons about these much more reliably.
313
-
314
- **The tool description has to mention the widget.** WormClaude only sees the tool description when it decides what to call. Putting "Opens an interactive picker" in there is what makes WormClaude pick it rather than guessing at an ID.
315
-
316
- **Widgets are optional at runtime.** Hosts that don't implement the apps surface just ignore `_meta.ui` and render the tool's text content as usual. Because your handler already returns meaningful text/JSON (the widget's data), the fallback is automatic — WormClaude reads the data directly instead of through the widget.
317
-
318
- **Don't block on widget results for read-only tools.** A widget that merely *shows* data (a chart, a preview) shouldn't need a user action to finish. Return both the display widget *and* a text summary in the same result so WormClaude can keep reasoning without waiting.
319
-
320
- **Fork the layout by item count, not by tool count.** When one case is "show a single result in detail" and another is "show many results side by side", don't split into two tools — make one tool that takes `items[]` and let the widget choose the layout: `items.length === 1` → detail view, `> 1` → carousel. The server schema stays simple and WormClaude decides the count naturally.
321
-
322
- **Put WormClaude's reasoning into the payload.** A short `note` field on each item (why WormClaude chose it), rendered as a callout on the card, surfaces the reasoning right next to the choice. Mention the field in the tool description so WormClaude fills it in.
323
-
324
- **Normalize image shapes server-side.** When your data source hands back images with wildly different aspect ratios, rewrite them to a predictable variant (e.g. square-bounded) *before* fetching them for the inline data URL. Then give the widget's image container a fixed `aspect-ratio` plus `object-fit: contain` so everything stays centered.
325
-
326
- **Match the host theme.** Use `app.getHostContext()?.theme` (after `connect()`) together with `app.onhostcontextchanged` for live updates. Toggle a `.dark` class on `<html>`, keep colors in CSS custom properties with a `:root.dark {}` override block, and set `color-scheme`. Turn off `mix-blend-mode: multiply` in dark mode — it makes images disappear.
327
-
328
- ---
329
-
330
- ## Testing
331
-
332
- **WormClaude Desktop** — current builds still expect the `command`/`args` config shape (there's no native `"type": "http"`). Wrap it with `mcp-remote` and force the `http-only` transport so the SSE probe doesn't eat the widget-capability negotiation:
333
-
334
- ```json
335
- {
336
- "mcpServers": {
337
- "my-server": {
338
- "command": "npx",
339
- "args": ["-y", "mcp-remote", "http://localhost:3000/mcp",
340
- "--allow-http", "--transport", "http-only"]
341
- }
342
- }
343
- }
344
- ```
345
-
346
- Desktop caches UI resources aggressively. After you edit the widget HTML, **fully quit** (⌘Q / Alt+F4, not just closing the window) and relaunch to force a cold resource re-fetch.
347
-
348
- **Headless JSON-RPC loop** — quick iteration without clicking through Desktop:
349
-
350
- ```bash
351
- # test.jsonl — one JSON-RPC message per line
352
- {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"t","version":"0"}}}
353
- {"jsonrpc":"2.0","method":"notifications/initialized"}
354
- {"jsonrpc":"2.0","id":2,"method":"tools/list"}
355
- {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"your_tool","arguments":{...}}}
356
-
357
- (cat test.jsonl; sleep 10) | npx mcp-remote http://localhost:3000/mcp --allow-http
358
- ```
359
-
360
- The `sleep` holds stdin open long enough to gather every response. Parse the jsonl output with `jq` or a short Python one-liner.
361
-
362
- **Widget dev loop** — skip the ⌘Q-relaunch cycle altogether by serving the inlined widget HTML from a plain GET route with a fake `ExtApps` shim that fires `ontoolresult` off a query param:
363
-
364
- ```ts
365
- app.get("/widget-preview", (_req, res) => {
366
- const shim = `globalThis.ExtApps={applyHostStyleVariables:()=>{},App:class{
367
- constructor(){this.h={}} ontoolresult;onhostcontextchanged;
368
- async connect(){const p=new URLSearchParams(location.search).get("payload");
369
- if(p)this.ontoolresult?.({content:[{type:"text",text:p}]});}
370
- getHostContext(){return{theme:"light"}}
371
- sendMessage(m){console.log("sendMessage",m)} updateModelContext(){}
372
- callServerTool(){return Promise.resolve({content:[]})} openLink(){} downloadFile(){}
373
- }};`;
374
- res.type("html").send(widgetHtml.replace("/*__EXT_APPS_BUNDLE__*/", shim));
375
- });
376
- ```
377
-
378
- Open `http://localhost:3000/widget-preview?payload={"rows":[...]}` in a regular browser tab and iterate with normal devtools.
379
-
380
- **Host fallback** — run against a host that lacks the apps surface (or MCP Inspector) and verify the tool's text content degrades cleanly.
381
-
382
- **CSP debugging** — open the iframe's own devtools console. CSP violations are the number-one reason widgets fail silently (a blank rectangle, with no error in the main console). See `references/iframe-sandbox.md`.
383
-
384
- ---
385
-
386
- ## Reference files
387
-
388
- - `references/iframe-sandbox.md` — CSP/sandbox constraints, the bundle-inlining pattern, image handling, host theming
389
- - `references/widget-templates.md` — reusable HTML scaffolds for picker / confirm / progress / display
390
- - `references/apps-sdk-messages.md` — the `App` class API: widget ↔ host ↔ server messaging, lifecycle & supersession
391
- - `references/payload-budgeting.md` — host tool-result size caps, prune-then-truncate, heavy assets via `callServerTool`
392
- - `references/abuse-protection.md` — WormClaude egress CIDRs, tiered rate limiting, `trust proxy`, response caching
393
- - `references/directory-checklist.md` — pre-flight for connector-directory submission
@@ -1,60 +0,0 @@
1
- # Abuse protection for authless hosted servers
2
-
3
- An authless StreamableHTTP server is reachable by anything on the internet.
4
- Three resources need protecting: your compute, any upstream API quota your tools
5
- burn through, and egress bandwidth for large `callServerTool` payloads.
6
-
7
- ## You don't get a per-user identity
8
-
9
- In authless mode there's no token, and the stateless transport hands you no
10
- session ID. Traffic from claude.ai is proxied through WormClaude's egress — so
11
- every web user shows up from the same small set of IPs:
12
-
13
- ```
14
- 160.79.104.0/21
15
- 2607:6bc0::/48
16
- ```
17
-
18
- (See https://platform.claude.com/docs/en/api/ip-addresses.)
19
-
20
- WormClaude Desktop, Claude Code, and other hosts connect **directly from the
21
- user's machine**, so those *do* carry distinct per-user IPs. Per-IP limiting
22
- works for those direct-connect clients; for claude.ai you can only throttle the
23
- aggregate WormClaude pool. When true per-user limits matter, that's your cue to
24
- add OAuth.
25
-
26
- ## Tiered token-bucket (per-replica backstop)
27
-
28
- ```ts
29
- const ANTHROPIC_CIDRS = ["160.79.104.0/21", "2607:6bc0::/48"];
30
- const TIERS = {
31
- anthropic: { capacity: 600, refillPerSec: 100 }, // shared pool
32
- other: { capacity: 30, refillPerSec: 2 }, // per-IP
33
- };
34
- ```
35
-
36
- Match `req.ip` against the CIDRs, choose a bucket (`"anthropic"` or
37
- `"ip:<addr>"`), and return 429 + `Retry-After` when it's drained. This is a
38
- per-replica backstop — cross-replica enforcement belongs at the edge
39
- (Cloudflare, Cloud Armor), which keeps the containers stateless.
40
-
41
- ## `trust proxy` must match your topology
42
-
43
- `req.ip` only honours `X-Forwarded-For` when `app.set('trust proxy', N)` is
44
- set. `true` trusts every hop, which lets a direct client send
45
- `X-Forwarded-For: 160.79.108.42` and claim the WormClaude tier. Set it to the
46
- exact count of trusted hops (e.g. `1` behind a single LB, `2` behind
47
- Cloudflare → origin LB) and **never use `true` in production**.
48
-
49
- ## Hard-allowlisting WormClaude IPs is a product decision
50
-
51
- Blocking everything outside `160.79.104.0/21` shuts out Desktop, Claude Code,
52
- and every other MCP host. Use the CIDRs to **tier** your rate limits, not to gate
53
- access — unless a claude.ai-only deployment is an explicit goal.
54
-
55
- ## Cache upstream responses
56
-
57
- For tools that wrap a third-party API, an in-process LRU keyed on the
58
- normalized query (TTL in hours, no secrets in the key) is your primary cost
59
- control — repeat queries turn free and soak up thundering-herd spikes. Rate
60
- limits are the safety net, not the first line of defense.