@jairodri/huckleberry-cli 1.0.1 → 1.1.0

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 (745) hide show
  1. package/README.md +85 -0
  2. package/agents/cos.json +2 -5
  3. package/agents/hermes/AGENTS.md +25 -49
  4. package/agents/hermes/fix-kimaki/SKILL.md +19 -92
  5. package/agents/hermes/hermes-fixer.md +44 -74
  6. package/agents/hermes.json +6 -18
  7. package/kanban/SKILL.md +18 -18
  8. package/kanban/package.json +1 -1
  9. package/kanban/src/dispatcher.mjs +1 -1
  10. package/kanban/templates/blog-social-campaign.yaml +6 -2
  11. package/kanban/templates/social-campaign.yaml +9 -4
  12. package/mcp/jev-calibration.mjs +335 -0
  13. package/mcp/jev-client.mjs +119 -0
  14. package/mcp/jev-thresholds.json +27 -0
  15. package/package.json +13 -9
  16. package/scripts/doctor-watchdog.sh +73 -0
  17. package/scripts/install-services.sh +34 -27
  18. package/scripts/self-improve-weekly.sh +34 -0
  19. package/scripts/sync-skills.mjs +121 -0
  20. package/skills/ab-test-setup/SKILL.md +266 -0
  21. package/skills/ab-test-setup/evals/evals.json +105 -0
  22. package/skills/ab-test-setup/references/sample-size-guide.md +263 -0
  23. package/skills/ab-test-setup/references/test-templates.md +277 -0
  24. package/skills/agent-reach/SKILL.md +132 -0
  25. package/skills/agent-reach/references/career.md +29 -0
  26. package/skills/agent-reach/references/dev.md +62 -0
  27. package/skills/agent-reach/references/search.md +33 -0
  28. package/skills/agent-reach/references/social.md +232 -0
  29. package/skills/agent-reach/references/video.md +130 -0
  30. package/skills/agent-reach/references/web.md +50 -0
  31. package/skills/ai-agent-seo/SKILL.md +450 -0
  32. package/skills/ai-cold-email-intelligence/SKILL.md +54 -0
  33. package/skills/ai-cold-email-intelligence/references/prompts.md +21 -0
  34. package/skills/ai-consensus-builder/SKILL.md +324 -0
  35. package/skills/ai-seo/SKILL.md +399 -0
  36. package/skills/ai-seo/evals/evals.json +90 -0
  37. package/skills/ai-seo/references/content-patterns.md +284 -0
  38. package/skills/ai-seo/references/platform-ranking-factors.md +152 -0
  39. package/skills/ai-visibility-audit/SKILL.md +322 -0
  40. package/skills/analytics-tracking/SKILL.md +309 -0
  41. package/skills/analytics-tracking/evals/evals.json +90 -0
  42. package/skills/analytics-tracking/references/event-library.md +260 -0
  43. package/skills/analytics-tracking/references/ga4-implementation.md +300 -0
  44. package/skills/analytics-tracking/references/gtm-implementation.md +390 -0
  45. package/skills/article-generator/SKILL.md +216 -0
  46. package/skills/auto-indexing/SKILL.md +179 -0
  47. package/skills/auto-indexing/scripts/auto-indexing.js +257 -0
  48. package/skills/auto-skill/SKILL.md +151 -0
  49. package/skills/auto-skill/correction-queue.js +102 -0
  50. package/skills/auto-skill/dedup.js +97 -0
  51. package/skills/auto-skill/skill-router.js +224 -0
  52. package/skills/autoresearch/SKILL.md +334 -0
  53. package/skills/autoresearch/autoresearch-autoresearch/SKILL.md.baseline +329 -0
  54. package/skills/autoresearch/autoresearch-autoresearch/changelog.md +34 -0
  55. package/skills/autoresearch/autoresearch-autoresearch/dashboard.html +116 -0
  56. package/skills/autoresearch/autoresearch-autoresearch/evals.md +39 -0
  57. package/skills/autoresearch/autoresearch-autoresearch/results.json +44 -0
  58. package/skills/autoresearch/autoresearch-autoresearch/results.tsv +3 -0
  59. package/skills/autoresearch/eval-guide.md +121 -0
  60. package/skills/b2b-cold-outreach/SKILL.md +322 -0
  61. package/skills/birdclaw/SKILL.md +82 -0
  62. package/skills/brainstorm/SKILL.md +168 -0
  63. package/skills/brand-kit-playground/SKILL.md +312 -0
  64. package/skills/brand-kit-playground/references/html-architecture.md +316 -0
  65. package/skills/brand-kit-playground/references/steal-patterns.md +88 -0
  66. package/skills/brand-voice/SKILL.md +223 -0
  67. package/skills/brand-voice/references/honesty-as-positioning.md +60 -0
  68. package/skills/brand-voice/references/voice-modes.md +1158 -0
  69. package/skills/business-advisory-council/README.md +136 -0
  70. package/skills/business-advisory-council/SKILL.md +94 -0
  71. package/skills/business-advisory-council/business-advisory-council.py +492 -0
  72. package/skills/business-advisory-council/discord-components-decision.json +8 -0
  73. package/skills/business-advisory-council/examples/steve-conley-partnership.json +6 -0
  74. package/skills/business-advisory-council/steve-conley-call-brief.json +6 -0
  75. package/skills/churn-prevention/SKILL.md +305 -0
  76. package/skills/churn-prevention/evals/evals.json +93 -0
  77. package/skills/churn-prevention/references/cancel-flow-patterns.md +316 -0
  78. package/skills/churn-prevention/references/dunning-playbook.md +408 -0
  79. package/skills/claw-compactor/LICENSE +21 -0
  80. package/skills/claw-compactor/README.md +459 -0
  81. package/skills/claw-compactor/SKILL.md +329 -0
  82. package/skills/claw-compactor/benchmark/RESULTS.md +104 -0
  83. package/skills/claw-compactor/benchmark/__init__.py +1 -0
  84. package/skills/claw-compactor/benchmark/compressors.py +520 -0
  85. package/skills/claw-compactor/benchmark/data/sample_01_devops.json +82 -0
  86. package/skills/claw-compactor/benchmark/data/sample_02_trading.json +54 -0
  87. package/skills/claw-compactor/benchmark/data/sample_03_ml_short.json +38 -0
  88. package/skills/claw-compactor/benchmark/data/sample_04_mixed_long.json +318 -0
  89. package/skills/claw-compactor/benchmark/data/sample_05_sysadmin.json +56 -0
  90. package/skills/claw-compactor/benchmark/evaluate.py +278 -0
  91. package/skills/claw-compactor/benchmark/report.py +241 -0
  92. package/skills/claw-compactor/benchmark/results/benchmark_results.json +405 -0
  93. package/skills/claw-compactor/benchmark/run_benchmark.py +238 -0
  94. package/skills/claw-compactor/engram.yaml +49 -0
  95. package/skills/claw-compactor/proxy/README.md +87 -0
  96. package/skills/claw-compactor/proxy/dashboard.html +804 -0
  97. package/skills/claw-compactor/proxy/event-log.mjs +213 -0
  98. package/skills/claw-compactor/proxy/fair-queue.mjs +288 -0
  99. package/skills/claw-compactor/proxy/metrics-store.mjs +425 -0
  100. package/skills/claw-compactor/proxy/package-lock.json +125 -0
  101. package/skills/claw-compactor/proxy/package.json +15 -0
  102. package/skills/claw-compactor/proxy/portal.html +360 -0
  103. package/skills/claw-compactor/proxy/process-registry.mjs +447 -0
  104. package/skills/claw-compactor/proxy/rate-limiter.mjs +117 -0
  105. package/skills/claw-compactor/proxy/redis-client.mjs +75 -0
  106. package/skills/claw-compactor/proxy/retry.mjs +182 -0
  107. package/skills/claw-compactor/proxy/server.mjs +2100 -0
  108. package/skills/claw-compactor/proxy/session-affinity.mjs +177 -0
  109. package/skills/claw-compactor/proxy/start.sh +23 -0
  110. package/skills/claw-compactor/proxy/test/event-log.test.mjs +237 -0
  111. package/skills/claw-compactor/proxy/test/helpers.mjs +103 -0
  112. package/skills/claw-compactor/proxy/test/integration.test.mjs +297 -0
  113. package/skills/claw-compactor/proxy/test/metrics-store.test.mjs +243 -0
  114. package/skills/claw-compactor/proxy/test/process-registry.test.mjs +390 -0
  115. package/skills/claw-compactor/proxy/test/rate-limiter.test.mjs +121 -0
  116. package/skills/claw-compactor/proxy/test/redis-client.test.mjs +62 -0
  117. package/skills/claw-compactor/proxy/test/token-tracker.test.mjs +200 -0
  118. package/skills/claw-compactor/proxy/token-tracker.mjs +482 -0
  119. package/skills/claw-compactor/pyproject.toml +26 -0
  120. package/skills/claw-compactor/references/README.md +44 -0
  121. package/skills/claw-compactor/references/architecture.md +197 -0
  122. package/skills/claw-compactor/references/benchmarks.md +94 -0
  123. package/skills/claw-compactor/references/compression-prompts.md +39 -0
  124. package/skills/claw-compactor/references/compression-techniques.md +219 -0
  125. package/skills/claw-compactor/references/testing.md +160 -0
  126. package/skills/claw-compactor/scripts/audit_memory.py +216 -0
  127. package/skills/claw-compactor/scripts/compress_memory.py +236 -0
  128. package/skills/claw-compactor/scripts/compressed_context.py +280 -0
  129. package/skills/claw-compactor/scripts/dedup_memory.py +147 -0
  130. package/skills/claw-compactor/scripts/dictionary_compress.py +170 -0
  131. package/skills/claw-compactor/scripts/engram-auto.sh +152 -0
  132. package/skills/claw-compactor/scripts/engram_auto.py +695 -0
  133. package/skills/claw-compactor/scripts/engram_cli.py +474 -0
  134. package/skills/claw-compactor/scripts/estimate_tokens.py +131 -0
  135. package/skills/claw-compactor/scripts/generate_summary_tiers.py +292 -0
  136. package/skills/claw-compactor/scripts/lib/__init__.py +34 -0
  137. package/skills/claw-compactor/scripts/lib/config.py +289 -0
  138. package/skills/claw-compactor/scripts/lib/dedup.py +119 -0
  139. package/skills/claw-compactor/scripts/lib/dictionary.py +281 -0
  140. package/skills/claw-compactor/scripts/lib/engram.py +793 -0
  141. package/skills/claw-compactor/scripts/lib/engram_prompts.py +175 -0
  142. package/skills/claw-compactor/scripts/lib/engram_storage.py +254 -0
  143. package/skills/claw-compactor/scripts/lib/exceptions.py +24 -0
  144. package/skills/claw-compactor/scripts/lib/markdown.py +312 -0
  145. package/skills/claw-compactor/scripts/lib/rle.py +165 -0
  146. package/skills/claw-compactor/scripts/lib/tokenizer_optimizer.py +188 -0
  147. package/skills/claw-compactor/scripts/lib/tokens.py +68 -0
  148. package/skills/claw-compactor/scripts/mem_compress.py +788 -0
  149. package/skills/claw-compactor/scripts/observation_compressor.py +346 -0
  150. package/skills/claw-compactor/tests/__init__.py +0 -0
  151. package/skills/claw-compactor/tests/conftest.py +94 -0
  152. package/skills/claw-compactor/tests/test_audit_comprehensive.py +123 -0
  153. package/skills/claw-compactor/tests/test_audit_memory.py +67 -0
  154. package/skills/claw-compactor/tests/test_benchmark.py +122 -0
  155. package/skills/claw-compactor/tests/test_cli_commands.py +228 -0
  156. package/skills/claw-compactor/tests/test_compress_memory.py +109 -0
  157. package/skills/claw-compactor/tests/test_compress_memory_comprehensive.py +191 -0
  158. package/skills/claw-compactor/tests/test_compressed_context.py +145 -0
  159. package/skills/claw-compactor/tests/test_config.py +54 -0
  160. package/skills/claw-compactor/tests/test_dedup_memory.py +124 -0
  161. package/skills/claw-compactor/tests/test_dictionary.py +327 -0
  162. package/skills/claw-compactor/tests/test_dictionary_comprehensive.py +241 -0
  163. package/skills/claw-compactor/tests/test_engram.py +1091 -0
  164. package/skills/claw-compactor/tests/test_engram_auto.py +529 -0
  165. package/skills/claw-compactor/tests/test_error_handling.py +194 -0
  166. package/skills/claw-compactor/tests/test_estimate_tokens.py +99 -0
  167. package/skills/claw-compactor/tests/test_generate_summary_tiers.py +105 -0
  168. package/skills/claw-compactor/tests/test_integration.py +249 -0
  169. package/skills/claw-compactor/tests/test_lib_dedup.py +135 -0
  170. package/skills/claw-compactor/tests/test_lib_markdown.py +388 -0
  171. package/skills/claw-compactor/tests/test_lib_tokens.py +82 -0
  172. package/skills/claw-compactor/tests/test_main_entry.py +176 -0
  173. package/skills/claw-compactor/tests/test_markdown_advanced.py +284 -0
  174. package/skills/claw-compactor/tests/test_new_features.py +77 -0
  175. package/skills/claw-compactor/tests/test_observation_comprehensive.py +261 -0
  176. package/skills/claw-compactor/tests/test_observation_compressor.py +128 -0
  177. package/skills/claw-compactor/tests/test_performance.py +172 -0
  178. package/skills/claw-compactor/tests/test_pipeline.py +109 -0
  179. package/skills/claw-compactor/tests/test_real_workspace.py +161 -0
  180. package/skills/claw-compactor/tests/test_rle.py +114 -0
  181. package/skills/claw-compactor/tests/test_rle_comprehensive.py +151 -0
  182. package/skills/claw-compactor/tests/test_roundtrip.py +253 -0
  183. package/skills/claw-compactor/tests/test_roundtrip_comprehensive.py +192 -0
  184. package/skills/claw-compactor/tests/test_tiers_comprehensive.py +171 -0
  185. package/skills/claw-compactor/tests/test_token_economics.py +237 -0
  186. package/skills/claw-compactor/tests/test_tokenizer_optimizer.py +175 -0
  187. package/skills/claw-compactor/tests/test_tokenizer_optimizer_comprehensive.py +241 -0
  188. package/skills/claw-compactor/tests/test_tokens.py +27 -0
  189. package/skills/cmo/CHANGELOG.md +61 -0
  190. package/skills/cmo/SKILL.md +500 -0
  191. package/skills/cmo/references/ai-slop-patterns.md +56 -0
  192. package/skills/cmo/references/analytics-guide.md +152 -0
  193. package/skills/cmo/references/ideas-library.md +197 -0
  194. package/skills/cmo/rules/brand-file-map.md +198 -0
  195. package/skills/cmo/rules/brand-memory.md +158 -0
  196. package/skills/cmo/rules/cli-runtime-index.md +95 -0
  197. package/skills/cmo/rules/command-reference.md +167 -0
  198. package/skills/cmo/rules/communication.md +15 -0
  199. package/skills/cmo/rules/context-switch.md +101 -0
  200. package/skills/cmo/rules/ecosystem.md +125 -0
  201. package/skills/cmo/rules/error-recovery.md +98 -0
  202. package/skills/cmo/rules/learning-loop.md +170 -0
  203. package/skills/cmo/rules/monorepo.md +78 -0
  204. package/skills/cmo/rules/output-format.md +124 -0
  205. package/skills/cmo/rules/persona.md +15 -0
  206. package/skills/cmo/rules/playbooks.md +327 -0
  207. package/skills/cmo/rules/progressive-enhancement.md +231 -0
  208. package/skills/cmo/rules/publish-index.md +106 -0
  209. package/skills/cmo/rules/quality-gate.md +90 -0
  210. package/skills/cmo/rules/recency-grounding.md +124 -0
  211. package/skills/cmo/rules/safety.md +80 -0
  212. package/skills/cmo/rules/studio-api-index.md +138 -0
  213. package/skills/cmo/rules/studio-integration.md +147 -0
  214. package/skills/cmo/rules/sub-agents.md +167 -0
  215. package/skills/cold-email/SKILL.md +240 -0
  216. package/skills/cold-email/evals/evals.json +94 -0
  217. package/skills/cold-email/references/benchmarks.md +83 -0
  218. package/skills/cold-email/references/follow-up-sequences.md +81 -0
  219. package/skills/cold-email/references/frameworks.md +90 -0
  220. package/skills/cold-email/references/personalization.md +79 -0
  221. package/skills/cold-email/references/subject-lines.md +53 -0
  222. package/skills/competitive-intel/SKILL.md +433 -0
  223. package/skills/competitive-intel/references/competitive-frameworks.md +145 -0
  224. package/skills/competitor-alternatives/SKILL.md +362 -0
  225. package/skills/competitor-alternatives/evals/evals.json +93 -0
  226. package/skills/competitor-alternatives/references/content-architecture.md +271 -0
  227. package/skills/competitor-alternatives/references/templates.md +223 -0
  228. package/skills/concreteness-fixer/SKILL.md +483 -0
  229. package/skills/concreteness-fixer/scripts/validation/concreteness-validator.js +221 -0
  230. package/skills/concreteness-fixer/utils/execFileNoThrow.js +16 -0
  231. package/skills/content-atomizer/SKILL.md +424 -0
  232. package/skills/content-atomizer/references/hook-strategies.md +56 -0
  233. package/skills/content-atomizer/references/platform-specs.md +118 -0
  234. package/skills/content-atomizer/references/platforms/bluesky.md +64 -0
  235. package/skills/content-atomizer/references/platforms/instagram.md +77 -0
  236. package/skills/content-atomizer/references/platforms/linkedin.md +120 -0
  237. package/skills/content-atomizer/references/platforms/reddit.md +73 -0
  238. package/skills/content-atomizer/references/platforms/threads.md +64 -0
  239. package/skills/content-atomizer/references/platforms/tiktok.md +55 -0
  240. package/skills/content-atomizer/references/platforms/twitter.md +123 -0
  241. package/skills/content-atomizer/references/platforms/youtube.md +56 -0
  242. package/skills/content-atomizer/references/tweet-patterns.md +40 -0
  243. package/skills/content-repost-manager/SKILL.md +245 -0
  244. package/skills/content-repost-manager/scripts/content-repost-scan.py +133 -0
  245. package/skills/context-recovery/.clawdhub/origin.json +7 -0
  246. package/skills/context-recovery/SKILL.md +198 -0
  247. package/skills/context-recovery/_meta.json +6 -0
  248. package/skills/conversion-flow-cro/SKILL.md +248 -0
  249. package/skills/conversion-flow-cro/references/flow-benchmarks.md +158 -0
  250. package/skills/copy-editing/SKILL.md +474 -0
  251. package/skills/copy-editing/evals/evals.json +89 -0
  252. package/skills/copy-editing/references/plain-english-alternatives.md +394 -0
  253. package/skills/copywriting/SKILL.md +349 -0
  254. package/skills/copywriting/evals/evals.json +111 -0
  255. package/skills/copywriting/references/awareness-level-guide.md +227 -0
  256. package/skills/copywriting/references/copy-frameworks.md +389 -0
  257. package/skills/copywriting/references/natural-transitions.md +272 -0
  258. package/skills/creative/SKILL.md +365 -0
  259. package/skills/creative/modes/ad-creative.md +1748 -0
  260. package/skills/creative/modes/product-photo.md +1520 -0
  261. package/skills/creative/modes/product-video.md +1657 -0
  262. package/skills/creative/modes/social-graphics.md +1511 -0
  263. package/skills/creative/modes/talking-head.md +2208 -0
  264. package/skills/creative/references/VISUAL_INTELLIGENCE.md +1233 -0
  265. package/skills/deep-serp-article/SKILL.md +677 -0
  266. package/skills/deep-serp-article/SKILL.md.bak +530 -0
  267. package/skills/earned-media/SKILL.md +260 -0
  268. package/skills/email-sequences/SKILL.md +446 -0
  269. package/skills/email-sequences/references/sequence-templates.md +1217 -0
  270. package/skills/firecrawl/.skill-meta.json +13 -0
  271. package/skills/firecrawl/SKILL.md +154 -0
  272. package/skills/firecrawl/rules/install.md +63 -0
  273. package/skills/firecrawl/rules/security.md +26 -0
  274. package/skills/form-cro/SKILL.md +429 -0
  275. package/skills/form-cro/evals/evals.json +90 -0
  276. package/skills/free-tool-strategy/SKILL.md +325 -0
  277. package/skills/free-tool-strategy/evals/evals.json +90 -0
  278. package/skills/free-tool-strategy/references/tool-types.md +253 -0
  279. package/skills/frontend-slides/SKILL.md +248 -0
  280. package/skills/frontend-slides/STYLE_PRESETS.md +347 -0
  281. package/skills/frontend-slides/animation-patterns.md +110 -0
  282. package/skills/frontend-slides/html-template.md +347 -0
  283. package/skills/frontend-slides/scripts/extract-pptx.py +96 -0
  284. package/skills/frontend-slides/viewport-base.css +153 -0
  285. package/skills/guardrail-framework/SKILL.md +319 -0
  286. package/skills/hook-generator/SKILL.md +438 -0
  287. package/skills/hook-generator/database/2026-PLATFORM-RESEARCH.md +211 -0
  288. package/skills/hook-generator/database/instagram-hooks.json +591 -0
  289. package/skills/hook-generator/database/linkedin-hooks.json +502 -0
  290. package/skills/hook-generator/database/medium-hooks.json +181 -0
  291. package/skills/hook-generator/database/tiktok-hooks.json +337 -0
  292. package/skills/hook-generator/database/twitter-hooks.json +567 -0
  293. package/skills/hook-generator/database/youtube-hooks.json +275 -0
  294. package/skills/hook-generator/package-lock.json +24 -0
  295. package/skills/hook-generator/package.json +5 -0
  296. package/skills/hook-generator/references/hook-generation-system.md +257 -0
  297. package/skills/hook-generator/references/hook-performance-analysis.json +153 -0
  298. package/skills/hook-generator/references/hooks-library.md +128 -0
  299. package/skills/hook-generator/references/platform-hook-frameworks.md +275 -0
  300. package/skills/hook-generator/scripts/generate-hooks-unified.js +722 -0
  301. package/skills/hook-generator/scripts/generate-hooks.js +225 -0
  302. package/skills/hook-generator/scripts/generate.sh +36 -0
  303. package/skills/hook-generator/scripts/ralph-hook-enhancer.js +864 -0
  304. package/skills/hook-generator/scripts/test-gemini-output.js +51 -0
  305. package/skills/humanizer/README.md +120 -0
  306. package/skills/humanizer/SKILL.md +699 -0
  307. package/skills/image-gen/SKILL.md +277 -0
  308. package/skills/image-gen/references/prompt-patterns.md +114 -0
  309. package/skills/image-gen/references/visual-metaphors.md +51 -0
  310. package/skills/impeccable/SKILL.md +86 -0
  311. package/skills/impeccable/reference/adapt.md +312 -0
  312. package/skills/impeccable/reference/adapt.native.md +58 -0
  313. package/skills/impeccable/reference/android.md +40 -0
  314. package/skills/impeccable/reference/animate.md +86 -0
  315. package/skills/impeccable/reference/audit.md +136 -0
  316. package/skills/impeccable/reference/audit.native.md +139 -0
  317. package/skills/impeccable/reference/bolder.md +31 -0
  318. package/skills/impeccable/reference/clarify.md +94 -0
  319. package/skills/impeccable/reference/colorize.md +86 -0
  320. package/skills/impeccable/reference/craft-floor.md +42 -0
  321. package/skills/impeccable/reference/craft.md +5 -0
  322. package/skills/impeccable/reference/critique.md +788 -0
  323. package/skills/impeccable/reference/degraded/asset-producer.md +90 -0
  324. package/skills/impeccable/reference/degraded/documenter.md +24 -0
  325. package/skills/impeccable/reference/degraded/finish-reviewer.md +37 -0
  326. package/skills/impeccable/reference/degraded/manual-edit-applier.md +92 -0
  327. package/skills/impeccable/reference/delight.md +70 -0
  328. package/skills/impeccable/reference/distill.md +111 -0
  329. package/skills/impeccable/reference/doctor.md +53 -0
  330. package/skills/impeccable/reference/document.md +416 -0
  331. package/skills/impeccable/reference/extract.md +69 -0
  332. package/skills/impeccable/reference/harden.md +336 -0
  333. package/skills/impeccable/reference/hooks.md +105 -0
  334. package/skills/impeccable/reference/init.md +125 -0
  335. package/skills/impeccable/reference/ios.md +45 -0
  336. package/skills/impeccable/reference/layout.md +84 -0
  337. package/skills/impeccable/reference/live-setup.md +102 -0
  338. package/skills/impeccable/reference/live.md +323 -0
  339. package/skills/impeccable/reference/new-work.md +110 -0
  340. package/skills/impeccable/reference/onboard.md +234 -0
  341. package/skills/impeccable/reference/operate.md +61 -0
  342. package/skills/impeccable/reference/optimize.md +258 -0
  343. package/skills/impeccable/reference/overdrive.md +127 -0
  344. package/skills/impeccable/reference/polish.md +97 -0
  345. package/skills/impeccable/reference/quieter.md +99 -0
  346. package/skills/impeccable/reference/routing.md +18 -0
  347. package/skills/impeccable/reference/shape.md +59 -0
  348. package/skills/impeccable/reference/typeset.md +80 -0
  349. package/skills/impeccable/reference/visualize.md +49 -0
  350. package/skills/impeccable/scripts/command-metadata.json +94 -0
  351. package/skills/impeccable/scripts/concept-seed.mjs +558 -0
  352. package/skills/impeccable/scripts/context-signals.mjs +334 -0
  353. package/skills/impeccable/scripts/context.mjs +1467 -0
  354. package/skills/impeccable/scripts/critique-storage.mjs +213 -0
  355. package/skills/impeccable/scripts/detect-csp.mjs +198 -0
  356. package/skills/impeccable/scripts/detect.mjs +21 -0
  357. package/skills/impeccable/scripts/detector/browser/injected/index.mjs +2023 -0
  358. package/skills/impeccable/scripts/detector/cli/main.mjs +438 -0
  359. package/skills/impeccable/scripts/detector/design-system.mjs +1046 -0
  360. package/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +8283 -0
  361. package/skills/impeccable/scripts/detector/detect-antipatterns.mjs +50 -0
  362. package/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +372 -0
  363. package/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +1168 -0
  364. package/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +1186 -0
  365. package/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs +264 -0
  366. package/skills/impeccable/scripts/detector/engines/visual/screenshot-contrast.mjs +189 -0
  367. package/skills/impeccable/scripts/detector/findings.mjs +18 -0
  368. package/skills/impeccable/scripts/detector/node/file-system.mjs +203 -0
  369. package/skills/impeccable/scripts/detector/profile/profiler.mjs +166 -0
  370. package/skills/impeccable/scripts/detector/registry/antipatterns.mjs +617 -0
  371. package/skills/impeccable/scripts/detector/rules/checks.mjs +5580 -0
  372. package/skills/impeccable/scripts/detector/shared/color.mjs +124 -0
  373. package/skills/impeccable/scripts/detector/shared/constants.mjs +112 -0
  374. package/skills/impeccable/scripts/detector/shared/fonts.mjs +30 -0
  375. package/skills/impeccable/scripts/detector/shared/inline-ignores.mjs +148 -0
  376. package/skills/impeccable/scripts/detector/shared/page.mjs +7 -0
  377. package/skills/impeccable/scripts/doctor.mjs +336 -0
  378. package/skills/impeccable/scripts/embed-prompt.mjs +133 -0
  379. package/skills/impeccable/scripts/generate-image.mjs +240 -0
  380. package/skills/impeccable/scripts/hook-admin.mjs +801 -0
  381. package/skills/impeccable/scripts/hook-before-edit.mjs +508 -0
  382. package/skills/impeccable/scripts/hook-lib.mjs +2153 -0
  383. package/skills/impeccable/scripts/hook.mjs +78 -0
  384. package/skills/impeccable/scripts/lib/artifact-schema.mjs +93 -0
  385. package/skills/impeccable/scripts/lib/composition-catalog.mjs +200 -0
  386. package/skills/impeccable/scripts/lib/concept-catalog.mjs +384 -0
  387. package/skills/impeccable/scripts/lib/design-parser.mjs +925 -0
  388. package/skills/impeccable/scripts/lib/impeccable-config.mjs +658 -0
  389. package/skills/impeccable/scripts/lib/impeccable-paths.mjs +137 -0
  390. package/skills/impeccable/scripts/lib/is-generated.mjs +69 -0
  391. package/skills/impeccable/scripts/lib/provider.mjs +5 -0
  392. package/skills/impeccable/scripts/lib/roll-selection.mjs +362 -0
  393. package/skills/impeccable/scripts/lib/staleness-deep.mjs +478 -0
  394. package/skills/impeccable/scripts/lib/staleness-notice.mjs +169 -0
  395. package/skills/impeccable/scripts/lib/staleness.mjs +457 -0
  396. package/skills/impeccable/scripts/lib/surface-briefs.mjs +151 -0
  397. package/skills/impeccable/scripts/lib/target-args.mjs +42 -0
  398. package/skills/impeccable/scripts/lib/target-slug.mjs +33 -0
  399. package/skills/impeccable/scripts/lib/template-extensions.mjs +146 -0
  400. package/skills/impeccable/scripts/live/accept-css.mjs +617 -0
  401. package/skills/impeccable/scripts/live/accept-verify.mjs +60 -0
  402. package/skills/impeccable/scripts/live/browser-script-parts.mjs +55 -0
  403. package/skills/impeccable/scripts/live/completion.mjs +28 -0
  404. package/skills/impeccable/scripts/live/event-validation.mjs +199 -0
  405. package/skills/impeccable/scripts/live/frameworks/astro.mjs +47 -0
  406. package/skills/impeccable/scripts/live/frameworks/detect-utils.mjs +73 -0
  407. package/skills/impeccable/scripts/live/frameworks/index.mjs +143 -0
  408. package/skills/impeccable/scripts/live/frameworks/journal.mjs +197 -0
  409. package/skills/impeccable/scripts/live/frameworks/nextjs.mjs +49 -0
  410. package/skills/impeccable/scripts/live/frameworks/nuxt.mjs +161 -0
  411. package/skills/impeccable/scripts/live/frameworks/script-src.mjs +17 -0
  412. package/skills/impeccable/scripts/live/frameworks/static-html.mjs +26 -0
  413. package/skills/impeccable/scripts/live/frameworks/sveltekit.mjs +71 -0
  414. package/skills/impeccable/scripts/live/frameworks/tag-strategy.mjs +247 -0
  415. package/skills/impeccable/scripts/live/frameworks/tanstack-start.mjs +70 -0
  416. package/skills/impeccable/scripts/live/frameworks/vite-generic.mjs +42 -0
  417. package/skills/impeccable/scripts/live/generation-preflight.mjs +149 -0
  418. package/skills/impeccable/scripts/live/insert-ui.mjs +458 -0
  419. package/skills/impeccable/scripts/live/instructions.mjs +142 -0
  420. package/skills/impeccable/scripts/live/manual-apply.mjs +939 -0
  421. package/skills/impeccable/scripts/live/manual-edit-routes.mjs +357 -0
  422. package/skills/impeccable/scripts/live/manual-edits-buffer.mjs +152 -0
  423. package/skills/impeccable/scripts/live/poll-lanes.mjs +14 -0
  424. package/skills/impeccable/scripts/live/roots.mjs +508 -0
  425. package/skills/impeccable/scripts/live/session-store.mjs +563 -0
  426. package/skills/impeccable/scripts/live/source-lock.mjs +105 -0
  427. package/skills/impeccable/scripts/live/source-search.mjs +105 -0
  428. package/skills/impeccable/scripts/live/svelte-ast.mjs +961 -0
  429. package/skills/impeccable/scripts/live/svelte-component.mjs +1342 -0
  430. package/skills/impeccable/scripts/live/sveltekit-adapter.mjs +316 -0
  431. package/skills/impeccable/scripts/live/tanstack-adapter.mjs +280 -0
  432. package/skills/impeccable/scripts/live/ui-core.mjs +180 -0
  433. package/skills/impeccable/scripts/live/vocabulary.mjs +171 -0
  434. package/skills/impeccable/scripts/live-accept.mjs +954 -0
  435. package/skills/impeccable/scripts/live-browser-dom.js +146 -0
  436. package/skills/impeccable/scripts/live-browser-session.js +123 -0
  437. package/skills/impeccable/scripts/live-browser.js +12520 -0
  438. package/skills/impeccable/scripts/live-commit-manual-edits.mjs +1244 -0
  439. package/skills/impeccable/scripts/live-complete.mjs +107 -0
  440. package/skills/impeccable/scripts/live-copy-edit-agent.mjs +683 -0
  441. package/skills/impeccable/scripts/live-discard-manual-edits.mjs +51 -0
  442. package/skills/impeccable/scripts/live-inject.mjs +503 -0
  443. package/skills/impeccable/scripts/live-insert.mjs +292 -0
  444. package/skills/impeccable/scripts/live-manual-edit-evidence.mjs +368 -0
  445. package/skills/impeccable/scripts/live-poll.mjs +429 -0
  446. package/skills/impeccable/scripts/live-resume.mjs +123 -0
  447. package/skills/impeccable/scripts/live-server.mjs +1669 -0
  448. package/skills/impeccable/scripts/live-status.mjs +71 -0
  449. package/skills/impeccable/scripts/live-target.mjs +30 -0
  450. package/skills/impeccable/scripts/live-wrap.mjs +927 -0
  451. package/skills/impeccable/scripts/live.mjs +359 -0
  452. package/skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
  453. package/skills/impeccable/scripts/palette.mjs +628 -0
  454. package/skills/impeccable/scripts/pin.mjs +221 -0
  455. package/skills/impeccable/scripts/serve-question.mjs +932 -0
  456. package/skills/impeccable/scripts/surface-brief.mjs +74 -0
  457. package/skills/inkstone-admin/SKILL.md +66 -0
  458. package/skills/jev-hook-gate/SKILL.md +111 -0
  459. package/skills/keyword-research/SKILL.md +503 -0
  460. package/skills/keyword-research/references/dr-cap-and-confidence.md +62 -0
  461. package/skills/keyword-research/references/keyword-examples.md +769 -0
  462. package/skills/landing-page-architect/SKILL.md +585 -0
  463. package/skills/landing-page-architect/references/architecture-reference.md +32 -0
  464. package/skills/launch-strategy/SKILL.md +384 -0
  465. package/skills/launch-strategy/evals/evals.json +91 -0
  466. package/skills/launch-strategy/references/launch-checklist.md +209 -0
  467. package/skills/launch-strategy/references/launch-timeline.md +159 -0
  468. package/skills/lead-email-craft/SKILL.md +522 -0
  469. package/skills/lead-magnets/SKILL.md +310 -0
  470. package/skills/lead-magnets/references/benchmarks.md +129 -0
  471. package/skills/lead-magnets/references/format-guide.md +196 -0
  472. package/skills/link-building-seo/SKILL.md +210 -0
  473. package/skills/lint-report.txt +1 -0
  474. package/skills/manifest.json +129 -0
  475. package/skills/marketing-demo/SKILL.md +249 -0
  476. package/skills/marketing-demo/references/remotion-examples.md +281 -0
  477. package/skills/marketing-ideas/SKILL.md +167 -0
  478. package/skills/marketing-ideas/evals/evals.json +90 -0
  479. package/skills/marketing-ideas/references/ideas-by-category.md +366 -0
  480. package/skills/marketing-psychology/SKILL.md +374 -0
  481. package/skills/marketing-psychology/evals/evals.json +88 -0
  482. package/skills/marketing-psychology/references/case-studies.md +148 -0
  483. package/skills/narrative-research-article/SKILL.md +469 -0
  484. package/skills/narrative-research-article/references/lanusse-patterns.md +166 -0
  485. package/skills/notebooklm/SKILL.md +674 -0
  486. package/skills/off-page-seo/SKILL.md +219 -0
  487. package/skills/onboarding-cro/SKILL.md +220 -0
  488. package/skills/onboarding-cro/evals/evals.json +92 -0
  489. package/skills/onboarding-cro/references/experiments.md +258 -0
  490. package/skills/original-research/SKILL.md +388 -0
  491. package/skills/page-cro/SKILL.md +269 -0
  492. package/skills/page-cro/references/cro-benchmarks.md +140 -0
  493. package/skills/paper-marketing/SKILL.md +448 -0
  494. package/skills/paper-marketing/references/agent-quality-rubric.md +68 -0
  495. package/skills/paper-marketing/references/brand-system-template.md +120 -0
  496. package/skills/paper-marketing/references/paper-mcp-rules.md +71 -0
  497. package/skills/paper-marketing/references/platform-conventions.md +43 -0
  498. package/skills/paywall-upgrade-cro/SKILL.md +227 -0
  499. package/skills/paywall-upgrade-cro/evals/evals.json +93 -0
  500. package/skills/paywall-upgrade-cro/references/experiments.md +164 -0
  501. package/skills/platform-formatting/SKILL.md +51 -0
  502. package/skills/popup-cro/SKILL.md +454 -0
  503. package/skills/popup-cro/evals/evals.json +94 -0
  504. package/skills/positioning-angles/SKILL.md +524 -0
  505. package/skills/positioning-angles/references/ad-matrix-and-examples.md +176 -0
  506. package/skills/positioning-angles/references/angle-frameworks.md +187 -0
  507. package/skills/positioning-angles/references/dunford-positioning.md +135 -0
  508. package/skills/positioning-angles/references/hormozi-offer.md +247 -0
  509. package/skills/positioning-angles/references/schwartz-sophistication.md +166 -0
  510. package/skills/positioning-angles/references/unique-mechanism.md +162 -0
  511. package/skills/pricing-strategy/SKILL.md +346 -0
  512. package/skills/pricing-strategy/evals/evals.json +90 -0
  513. package/skills/pricing-strategy/references/research-methods.md +152 -0
  514. package/skills/pricing-strategy/references/tier-structure.md +307 -0
  515. package/skills/programmatic-seo/SKILL.md +238 -0
  516. package/skills/programmatic-seo/evals/evals.json +94 -0
  517. package/skills/programmatic-seo/references/playbooks.md +308 -0
  518. package/skills/project-rag/SKILL.md +127 -0
  519. package/skills/quality-gate/SKILL.md +519 -0
  520. package/skills/quality-gate/judge-personas/buyer.md +47 -0
  521. package/skills/quality-gate/judge-personas/expert.md +47 -0
  522. package/skills/quality-gate/judge-personas/outsider.md +47 -0
  523. package/skills/quality-gate/judge-personas/scanner.md +41 -0
  524. package/skills/quality-gate/judge-personas/skeptic.md +40 -0
  525. package/skills/referral-program/SKILL.md +290 -0
  526. package/skills/referral-program/evals/evals.json +89 -0
  527. package/skills/referral-program/references/affiliate-programs.md +163 -0
  528. package/skills/referral-program/references/program-examples.md +143 -0
  529. package/skills/review-sites/SKILL.md +279 -0
  530. package/skills/revops/SKILL.md +343 -0
  531. package/skills/revops/evals/evals.json +91 -0
  532. package/skills/revops/references/automation-playbooks.md +290 -0
  533. package/skills/revops/references/lifecycle-definitions.md +278 -0
  534. package/skills/revops/references/routing-rules.md +203 -0
  535. package/skills/revops/references/scoring-models.md +247 -0
  536. package/skills/saas-product-seo/SKILL.md +324 -0
  537. package/skills/sales-enablement/SKILL.md +349 -0
  538. package/skills/sales-enablement/evals/evals.json +91 -0
  539. package/skills/sales-enablement/references/deck-frameworks.md +263 -0
  540. package/skills/sales-enablement/references/demo-scripts.md +355 -0
  541. package/skills/sales-enablement/references/objection-library.md +270 -0
  542. package/skills/sales-enablement/references/one-pager-templates.md +208 -0
  543. package/skills/schema-markup/SKILL.md +179 -0
  544. package/skills/schema-markup/evals/evals.json +87 -0
  545. package/skills/schema-markup/references/schema-examples.md +398 -0
  546. package/skills/self-improve/SKILL.md +166 -0
  547. package/skills/self-improving-agent/README.md +243 -0
  548. package/skills/self-improving-agent/SKILL.md +437 -0
  549. package/skills/self-improving-agent/scripts/__init__.py +16 -0
  550. package/skills/self-improving-agent/scripts/__pycache__/auto_detect.cpython-314.pyc +0 -0
  551. package/skills/self-improving-agent/scripts/__pycache__/nlm_curation.cpython-314.pyc +0 -0
  552. package/skills/self-improving-agent/scripts/__pycache__/self_improving_agent.cpython-314.pyc +0 -0
  553. package/skills/self-improving-agent/scripts/auto_detect.py +270 -0
  554. package/skills/self-improving-agent/scripts/init_expertise_registry.py +89 -0
  555. package/skills/self-improving-agent/scripts/nlm_curation.py +259 -0
  556. package/skills/self-improving-agent/scripts/self-improving-agent +113 -0
  557. package/skills/self-improving-agent/scripts/self_improving_agent.py +603 -0
  558. package/skills/self-improving-agent/scripts/test_curation_scorer.py +20 -0
  559. package/skills/self-improving-agent/scripts/test_self_improving.py +184 -0
  560. package/skills/send-email/SKILL.md +426 -0
  561. package/skills/send-email/references/batch-email-examples.md +807 -0
  562. package/skills/send-email/references/best-practices.md +453 -0
  563. package/skills/send-email/references/installation.md +123 -0
  564. package/skills/send-email/references/single-email-examples.md +470 -0
  565. package/skills/send-email/references/webhooks.md +221 -0
  566. package/skills/seo-audit/SKILL.md +362 -0
  567. package/skills/seo-audit/references/ai-writing-detection.md +200 -0
  568. package/skills/seo-audit/references/architecture-patterns.md +271 -0
  569. package/skills/seo-audit/references/schema-templates.md +427 -0
  570. package/skills/seo-content/SKILL.md +510 -0
  571. package/skills/seo-content/references/anti-ai-detection.md +184 -0
  572. package/skills/seo-content/references/content-structures.md +148 -0
  573. package/skills/seo-content/references/eeat-examples.md +235 -0
  574. package/skills/seo-content/references/on-page-seo.md +261 -0
  575. package/skills/seo-content/references/pseo-playbooks.md +226 -0
  576. package/skills/seo-content/references/schema-templates.md +104 -0
  577. package/skills/seo-content/references/serp-analysis-format.md +151 -0
  578. package/skills/seo-machine/SKILL.md +331 -0
  579. package/skills/seo-machine/assets/brand-template.md +73 -0
  580. package/skills/seo-machine/assets/link-inventory-template.md +74 -0
  581. package/skills/seo-machine/assets/roadmap-template.md +184 -0
  582. package/skills/seo-machine/references/api-stack-recipes.md +230 -0
  583. package/skills/seo-machine/references/exa-recipes.md +260 -0
  584. package/skills/seo-machine/references/manual-research.md +73 -0
  585. package/skills/seo-machine/references/methodology.md +87 -0
  586. package/skills/seo-machine/references/off-page.md +123 -0
  587. package/skills/seo-machine/references/patterns/alternatives.md +176 -0
  588. package/skills/seo-machine/references/patterns/compare.md +105 -0
  589. package/skills/seo-machine/references/patterns/playbooks.md +106 -0
  590. package/skills/seo-machine/references/patterns/use-case.md +109 -0
  591. package/skills/seo-machine/references/quality-bars.md +99 -0
  592. package/skills/seo-machine/references/stacks/astro.md +156 -0
  593. package/skills/seo-machine/references/stacks/detection.md +61 -0
  594. package/skills/seo-machine/references/stacks/markdown-fallback.md +181 -0
  595. package/skills/seo-machine/references/stacks/nextjs.md +108 -0
  596. package/skills/seo-machine/references/stacks/rails-inertia.md +99 -0
  597. package/skills/seo-machine/references/striking-distance.md +116 -0
  598. package/skills/seo-machine/references/technical-audit.md +153 -0
  599. package/skills/seo-machine/scripts/link_audit.py +265 -0
  600. package/skills/seo-machine/scripts/tech_audit.py +221 -0
  601. package/skills/seo-machine/scripts/word_count.py +154 -0
  602. package/skills/sharp-thesis-validator/SKILL.md +393 -0
  603. package/skills/sharp-thesis-validator/examples.md +186 -0
  604. package/skills/signup-flow-cro/SKILL.md +359 -0
  605. package/skills/signup-flow-cro/evals/evals.json +88 -0
  606. package/skills/site-architecture/SKILL.md +357 -0
  607. package/skills/site-architecture/evals/evals.json +88 -0
  608. package/skills/site-architecture/references/mermaid-templates.md +216 -0
  609. package/skills/site-architecture/references/navigation-patterns.md +305 -0
  610. package/skills/site-architecture/references/site-type-templates.md +293 -0
  611. package/skills/skill-self-improvement/SKILL.md +151 -0
  612. package/skills/slideshow-script/SKILL.md +274 -0
  613. package/skills/slideshow-script/references/content-spec-schema.md +77 -0
  614. package/skills/slideshow-script/references/frameworks.md +84 -0
  615. package/skills/slideshow-script/references/paips-framework.md +37 -0
  616. package/skills/social-campaign/SKILL.md +419 -0
  617. package/skills/social-campaign/references/paper-mcp-workflow.md +48 -0
  618. package/skills/social-content/SKILL.md +359 -0
  619. package/skills/social-content/evals/evals.json +92 -0
  620. package/skills/social-content/references/platforms.md +170 -0
  621. package/skills/social-content/references/post-templates.md +177 -0
  622. package/skills/social-content/references/reverse-engineering.md +195 -0
  623. package/skills/social-worker/SKILL.md +204 -0
  624. package/skills/startup-launcher/SKILL.md +252 -0
  625. package/skills/startup-launcher/references/file-router.md +64 -0
  626. package/skills/startup-launcher/references/platform-matrix.md +65 -0
  627. package/skills/startup-launcher/references/platforms/alternativeto.md +283 -0
  628. package/skills/startup-launcher/references/platforms/appsumo.md +495 -0
  629. package/skills/startup-launcher/references/platforms/auraplusplus.md +736 -0
  630. package/skills/startup-launcher/references/platforms/betalist.md +98 -0
  631. package/skills/startup-launcher/references/platforms/capterra.md +276 -0
  632. package/skills/startup-launcher/references/platforms/crunchbase.md +514 -0
  633. package/skills/startup-launcher/references/platforms/dealify.md +291 -0
  634. package/skills/startup-launcher/references/platforms/dealmirror.md +313 -0
  635. package/skills/startup-launcher/references/platforms/desifounder.md +490 -0
  636. package/skills/startup-launcher/references/platforms/devhunt.md +210 -0
  637. package/skills/startup-launcher/references/platforms/devpost.md +448 -0
  638. package/skills/startup-launcher/references/platforms/fazier.md +56 -0
  639. package/skills/startup-launcher/references/platforms/firsto.md +489 -0
  640. package/skills/startup-launcher/references/platforms/g2.md +226 -0
  641. package/skills/startup-launcher/references/platforms/hackernews.md +99 -0
  642. package/skills/startup-launcher/references/platforms/hackernoon.md +385 -0
  643. package/skills/startup-launcher/references/platforms/indiedeals.md +367 -0
  644. package/skills/startup-launcher/references/platforms/indiehackers.md +80 -0
  645. package/skills/startup-launcher/references/platforms/kenmoo.md +231 -0
  646. package/skills/startup-launcher/references/platforms/labstartups.md +618 -0
  647. package/skills/startup-launcher/references/platforms/launchboard.md +307 -0
  648. package/skills/startup-launcher/references/platforms/launchfast.md +560 -0
  649. package/skills/startup-launcher/references/platforms/launchigniter.md +56 -0
  650. package/skills/startup-launcher/references/platforms/launchingnext.md +674 -0
  651. package/skills/startup-launcher/references/platforms/launchit.md +574 -0
  652. package/skills/startup-launcher/references/platforms/launchyourapp.md +677 -0
  653. package/skills/startup-launcher/references/platforms/libhunt.md +220 -0
  654. package/skills/startup-launcher/references/platforms/ltdhunt.md +221 -0
  655. package/skills/startup-launcher/references/platforms/microlaunch.md +45 -0
  656. package/skills/startup-launcher/references/platforms/openalternative.md +195 -0
  657. package/skills/startup-launcher/references/platforms/peerlist.md +56 -0
  658. package/skills/startup-launcher/references/platforms/peerpush.md +64 -0
  659. package/skills/startup-launcher/references/platforms/primeclub.md +282 -0
  660. package/skills/startup-launcher/references/platforms/productcanyon.md +190 -0
  661. package/skills/startup-launcher/references/platforms/producthunt.md +98 -0
  662. package/skills/startup-launcher/references/platforms/rankinpublic.md +315 -0
  663. package/skills/startup-launcher/references/platforms/rockethub.md +374 -0
  664. package/skills/startup-launcher/references/platforms/saasgenius.md +175 -0
  665. package/skills/startup-launcher/references/platforms/saashub.md +205 -0
  666. package/skills/startup-launcher/references/platforms/saasmantra.md +221 -0
  667. package/skills/startup-launcher/references/platforms/saaspirate.md +287 -0
  668. package/skills/startup-launcher/references/platforms/saaswarrior.md +190 -0
  669. package/skills/startup-launcher/references/platforms/saaszilla.md +194 -0
  670. package/skills/startup-launcher/references/platforms/selected.md +925 -0
  671. package/skills/startup-launcher/references/platforms/sideprojectors.md +86 -0
  672. package/skills/startup-launcher/references/platforms/softonic.md +240 -0
  673. package/skills/startup-launcher/references/platforms/sourceforge.md +251 -0
  674. package/skills/startup-launcher/references/platforms/stacksocial.md +244 -0
  675. package/skills/startup-launcher/references/platforms/startupstash.md +326 -0
  676. package/skills/startup-launcher/references/platforms/theresanaiforthat.md +253 -0
  677. package/skills/startup-launcher/references/platforms/tinylaunch.md +70 -0
  678. package/skills/startup-launcher/references/platforms/tinystartups.md +72 -0
  679. package/skills/startup-launcher/references/platforms/toolfolio.md +291 -0
  680. package/skills/startup-launcher/references/platforms/trustmrr.md +194 -0
  681. package/skills/startup-launcher/references/platforms/trylaunch.md +531 -0
  682. package/skills/startup-launcher/references/platforms/uneed.md +57 -0
  683. package/skills/startup-launcher/references/templates/asset-checklist.md +218 -0
  684. package/skills/startup-launcher/references/templates/launch-tracker.md +195 -0
  685. package/skills/startup-launcher/references/templates/product-brief.md +98 -0
  686. package/skills/summarize/.skill-meta.json +13 -0
  687. package/skills/summarize/SKILL.md +170 -0
  688. package/skills/summarize/rules/install.md +157 -0
  689. package/skills/summarize/rules/usage.md +207 -0
  690. package/skills/topical-authority/SKILL.md +307 -0
  691. package/skills/topical-authority/references/jake-ward-framework.md +201 -0
  692. package/skills/topical-authority/references/serp-clustering-algorithm.md +325 -0
  693. package/skills/topical-authority/scripts/orchestrator.js +367 -0
  694. package/skills/topical-authority/scripts/seo/analyze-competitor-coverage.js +3 -0
  695. package/skills/topical-authority/scripts/seo/audit-internal-links.js +3 -0
  696. package/skills/topical-authority/scripts/seo/build-clusters-from-serp.js +3 -0
  697. package/skills/topical-authority/scripts/seo/extract-keywords-from-forums.js +3 -0
  698. package/skills/topical-authority/scripts/seo/extract-paa-questions.js +3 -0
  699. package/skills/topical-authority/scripts/seo/fetch-serp-urls.js +3 -0
  700. package/skills/topical-authority/scripts/seo/gemini-serp-clustering.js +3 -0
  701. package/skills/topical-authority/scripts/seo/identify-content-gaps.js +3 -0
  702. package/skills/topical-authority/scripts/seo/identify-research-gaps.js +3 -0
  703. package/skills/topical-authority/scripts/seo/scrape-quora-questions.js +3 -0
  704. package/skills/topical-authority/scripts/seo/scrape-reddit-pain-points.js +3 -0
  705. package/skills/topical-authority/scripts/seo/weave-internal-links.js +3 -0
  706. package/skills/visual-style/SKILL.md +199 -0
  707. package/skills/voice-brand-alignment/SKILL.md +70 -0
  708. package/skills/voice-brand-alignment/references/ai-slop-patterns.md +405 -0
  709. package/skills/voice-brand-alignment/scripts/validation/gemini-voice-validator.js +96 -0
  710. package/skills/voice-extraction/SKILL.md +234 -0
  711. package/skills/voice-extraction/references/extraction-prompt.md +155 -0
  712. package/skills/voice-extraction/references/voice-dna-template.md +168 -0
  713. package/skills/voice-extraction/references/voice-elements.md +259 -0
  714. package/skills/voice-extraction/scripts/build-corpus.js +120 -0
  715. package/skills/voice-extraction/scripts/collect-sources.sh +168 -0
  716. package/skills/warm-outbound/SKILL.md +299 -0
  717. package/skills/warm-outbound/templates/warm-message.md +39 -0
  718. package/skills/weekly-newsletter-digest/SKILL.md +78 -0
  719. package/skills/x-playwriter/SKILL.md +428 -0
  720. package/skills/x-playwriter/scripts/x-browser.js +185 -0
  721. package/skills/x-post-generator-openclaw/SKILL.md +138 -0
  722. package/skills/x-post-generator-openclaw/scripts/generate-x-post.js +537 -0
  723. package/skills/x-posting-playwriter/SKILL.md +203 -0
  724. package/skills/x-research/SKILL.md +129 -0
  725. package/skills/x-research/x-research.sh +85 -0
  726. package/skills/youtube-summarize/SKILL.md +90 -0
  727. package/skills/youtube-summarize/scripts/youtube-summarize.sh +143 -0
  728. package/src/cli.js +349 -172
  729. package/src/harness/deepseek-adapter.js +102 -0
  730. package/src/harness/deepseek.js +225 -0
  731. package/src/harness/opencode-adapter.js +174 -0
  732. package/src/harness/pi-adapter.js +172 -0
  733. package/src/harness/registry.js +121 -0
  734. package/src/harness/telemetry.js +102 -0
  735. package/src/harness/types.js +165 -0
  736. package/src/interview.js +36 -4
  737. package/src/postinstall.js +10 -12
  738. package/templates/AGENTS.md +17 -17
  739. package/templates/ORG.md +1 -1
  740. package/templates/TOOLS.md +7 -2
  741. package/templates/opencode.json +26 -29
  742. package/wiki/doctor.md +54 -0
  743. package/wiki/inkstone.md +4 -4
  744. package/wiki/opencode.md +3 -3
  745. package/skills/curated.txt +0 -68
@@ -0,0 +1,145 @@
1
+ """Tests for Compressed Context Protocol."""
2
+
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ import pytest
7
+
8
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
9
+ from compressed_context import (
10
+ compress_ultra, compress_medium, compress_light,
11
+ compress, compress_with_stats,
12
+ DECOMPRESS_INSTRUCTIONS,
13
+ )
14
+
15
+
16
+ SAMPLE_BIO = (
17
+ "Alex is the CTO of ExampleCorp and founder of DataPlatform. "
18
+ "He has 13+ years of crypto quantitative trading experience. "
19
+ "He is based in Los Gatos, CA with offices in Shanghai and Taipei."
20
+ )
21
+
22
+ SAMPLE_TECH = (
23
+ "The infrastructure uses Kubernetes for container orchestration "
24
+ "with continuous integration and deployment pipelines. "
25
+ "The application architecture includes distributed database "
26
+ "systems and monitoring dashboards for production environments."
27
+ )
28
+
29
+
30
+ class TestCompressUltra:
31
+ def test_reduces_length(self):
32
+ result = compress_ultra(SAMPLE_BIO)
33
+ assert len(result) < len(SAMPLE_BIO)
34
+
35
+ def test_preserves_names(self):
36
+ result = compress_ultra(SAMPLE_BIO)
37
+ assert "Alex" in result
38
+ assert "Alex" in result
39
+ assert "ExampleCorp" in result
40
+
41
+ def test_abbreviates(self):
42
+ result = compress_ultra(SAMPLE_TECH)
43
+ # Should use abbreviations
44
+ assert "k8s" in result or "infra" in result or len(result) < len(SAMPLE_TECH) * 0.8
45
+
46
+ def test_empty(self):
47
+ assert compress_ultra("") == ""
48
+
49
+ def test_removes_fillers(self):
50
+ text = "He has extensive experience. In addition, he is skilled."
51
+ result = compress_ultra(text)
52
+ assert "In addition" not in result
53
+
54
+
55
+ class TestCompressMedium:
56
+ def test_less_aggressive(self):
57
+ ultra = compress_ultra(SAMPLE_BIO)
58
+ medium = compress_medium(SAMPLE_BIO)
59
+ # Medium should be longer than ultra (less aggressive)
60
+ assert len(medium) >= len(ultra)
61
+
62
+ def test_reduces_length(self):
63
+ result = compress_medium(SAMPLE_TECH)
64
+ assert len(result) < len(SAMPLE_TECH)
65
+
66
+
67
+ class TestCompressLight:
68
+ def test_minimal_changes(self):
69
+ text = "Simple text with no issues"
70
+ assert compress_light(text) == text
71
+
72
+ def test_cleanup(self):
73
+ text = "Extra spaces here\n\n\n\nToo many lines"
74
+ result = compress_light(text)
75
+ assert " " not in result.replace(" ", " ") # might still have some
76
+ assert "\n\n\n" not in result
77
+
78
+
79
+ class TestCompress:
80
+ def test_returns_dict(self):
81
+ result = compress(SAMPLE_BIO, "ultra")
82
+ assert "compressed" in result
83
+ assert "instructions" in result
84
+ assert result["level"] == "ultra"
85
+
86
+ def test_all_levels(self):
87
+ for level in ["ultra", "medium", "light"]:
88
+ result = compress(SAMPLE_BIO, level)
89
+ assert result["level"] == level
90
+ assert len(result["compressed"]) > 0
91
+ assert len(result["instructions"]) > 0
92
+
93
+ def test_invalid_level(self):
94
+ with pytest.raises(ValueError):
95
+ compress(SAMPLE_BIO, "extreme")
96
+
97
+ def test_instructions_exist(self):
98
+ for level in ["ultra", "medium", "light"]:
99
+ assert level in DECOMPRESS_INSTRUCTIONS
100
+
101
+
102
+ class TestCompressWithStats:
103
+ def test_basic(self):
104
+ stats = compress_with_stats(SAMPLE_BIO, "ultra")
105
+ assert stats["original_tokens"] > 0
106
+ assert stats["compressed_tokens"] > 0
107
+ assert stats["compressed_tokens"] < stats["original_tokens"]
108
+ # Note: reduction_pct includes instruction overhead so may be negative for short texts
109
+ assert "instructions" in stats
110
+
111
+ def test_all_levels(self):
112
+ for level in ["ultra", "medium", "light"]:
113
+ stats = compress_with_stats(SAMPLE_BIO, level)
114
+ assert stats["original_tokens"] > 0
115
+ assert isinstance(stats["reduction_pct"], float)
116
+
117
+ def test_empty(self):
118
+ stats = compress_with_stats("", "ultra")
119
+ assert stats["original_tokens"] == 0
120
+
121
+ def test_unicode(self):
122
+ text = "中文内容测试:这是一个很长的中文段落,包含了很多信息。"
123
+ stats = compress_with_stats(text, "ultra")
124
+ assert stats["compressed_tokens"] > 0
125
+ assert "中文" in stats["compressed"]
126
+
127
+ def test_real_bio_compression(self):
128
+ """The sample bio should compress the text itself significantly."""
129
+ stats = compress_with_stats(SAMPLE_BIO, "ultra")
130
+ # Compressed text alone should be smaller than original
131
+ assert stats["compressed_tokens"] < stats["original_tokens"]
132
+ # For longer texts, net reduction (including instructions) should be positive
133
+ # For short texts like this, just verify text compression works
134
+ text_reduction = (stats["original_tokens"] - stats["compressed_tokens"]) / stats["original_tokens"] * 100
135
+ assert text_reduction > 5, f"Only {text_reduction:.1f}% text reduction"
136
+
137
+
138
+ class TestCLI:
139
+ def test_file_compress(self, tmp_path):
140
+ """Test that compress works on a file's content."""
141
+ f = tmp_path / "test.md"
142
+ f.write_text(SAMPLE_BIO)
143
+ text = f.read_text()
144
+ stats = compress_with_stats(text, "ultra")
145
+ assert stats["compressed_tokens"] < stats["original_tokens"]
@@ -0,0 +1,54 @@
1
+ """Tests for lib.config module."""
2
+
3
+ import json
4
+ from pathlib import Path
5
+
6
+ import pytest
7
+
8
+ from lib.config import MemCompressConfig, load_config, DEFAULT_CONFIG
9
+
10
+
11
+ class TestMemCompressConfig:
12
+ def test_defaults(self) -> None:
13
+ cfg = MemCompressConfig()
14
+ assert cfg.chars_per_token == 4
15
+ assert cfg.level0_max_tokens == 200
16
+
17
+ def test_custom_values(self) -> None:
18
+ cfg = MemCompressConfig(chars_per_token=3)
19
+ assert cfg.chars_per_token == 3
20
+
21
+
22
+ class TestLoadConfig:
23
+ def test_no_config_file(self, tmp_path: Path) -> None:
24
+ cfg = load_config(tmp_path)
25
+ assert cfg.chars_per_token == DEFAULT_CONFIG["chars_per_token"]
26
+
27
+ def test_valid_config(self, tmp_path: Path) -> None:
28
+ (tmp_path / "claw-compactor-config.json").write_text(
29
+ json.dumps({"chars_per_token": 3}), encoding="utf-8"
30
+ )
31
+ cfg = load_config(tmp_path)
32
+ assert cfg.chars_per_token == 3
33
+
34
+ def test_invalid_json(self, tmp_path: Path) -> None:
35
+ (tmp_path / "claw-compactor-config.json").write_text("{{bad", encoding="utf-8")
36
+ cfg = load_config(tmp_path)
37
+ assert cfg.chars_per_token == 4
38
+
39
+ def test_non_dict(self, tmp_path: Path) -> None:
40
+ (tmp_path / "claw-compactor-config.json").write_text('["arr"]', encoding="utf-8")
41
+ cfg = load_config(tmp_path)
42
+ assert cfg.chars_per_token == 4
43
+
44
+ def test_unknown_keys_ignored(self, tmp_path: Path) -> None:
45
+ (tmp_path / "claw-compactor-config.json").write_text(
46
+ json.dumps({"chars_per_token": 5, "bogus": 99}), encoding="utf-8"
47
+ )
48
+ cfg = load_config(tmp_path)
49
+ assert cfg.chars_per_token == 5
50
+
51
+ def test_empty_file(self, tmp_path: Path) -> None:
52
+ (tmp_path / "claw-compactor-config.json").write_text("", encoding="utf-8")
53
+ cfg = load_config(tmp_path)
54
+ assert cfg.chars_per_token == 4
@@ -0,0 +1,124 @@
1
+ """Tests for dedup_memory.py."""
2
+
3
+ import json
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ import pytest
8
+
9
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
10
+ from dedup_memory import run_dedup, format_human, _collect_entries
11
+ from lib.dedup import find_duplicates, merge_duplicates, jaccard, _shingles
12
+
13
+
14
+ class TestShingles:
15
+ def test_basic(self):
16
+ assert len(_shingles("the quick brown fox jumps over")) > 0
17
+
18
+ def test_short(self):
19
+ assert len(_shingles("hi")) == 1
20
+
21
+ def test_empty(self):
22
+ assert len(_shingles("")) == 1
23
+
24
+
25
+ class TestJaccard:
26
+ def test_identical(self):
27
+ assert jaccard({1, 2, 3}, {1, 2, 3}) == 1.0
28
+
29
+ def test_disjoint(self):
30
+ assert jaccard({1, 2}, {3, 4}) == 0.0
31
+
32
+ def test_partial(self):
33
+ assert 0 < jaccard({1, 2, 3}, {2, 3, 4}) < 1
34
+
35
+ def test_empty(self):
36
+ assert jaccard(set(), set()) == 1.0
37
+
38
+ def test_one_empty(self):
39
+ assert jaccard({1}, set()) == 0.0
40
+
41
+
42
+ class TestFindDuplicates:
43
+ def test_exact(self):
44
+ entries = ["Install Python 3.10 and configure environment", "Install Python 3.10 and configure environment", "Something different about database"]
45
+ groups = find_duplicates(entries, threshold=0.5)
46
+ assert len(groups) >= 1
47
+
48
+ def test_near(self):
49
+ entries = ["Install Python 3.10 and set up virtual env for dev", "Install Python 3.10 and set up virtual env for prod", "Configure nginx reverse proxy"]
50
+ assert len(find_duplicates(entries, threshold=0.5)) >= 1
51
+
52
+ def test_no_duplicates(self):
53
+ assert len(find_duplicates(["Alpha beta gamma", "One two three four", "日本語テスト"], threshold=0.8)) == 0
54
+
55
+ def test_single(self):
56
+ assert find_duplicates(["one"]) == []
57
+
58
+ def test_empty(self):
59
+ assert find_duplicates([]) == []
60
+
61
+ def test_large(self):
62
+ entries = ["Entry {} with filler content for testing".format(i) for i in range(500)]
63
+ entries += [entries[0], entries[1]]
64
+ assert len(find_duplicates(entries, threshold=0.8)) >= 2
65
+
66
+ def test_unicode(self):
67
+ entries = ["配置数据库连接字符串和环境变量", "配置数据库连接字符串和环境变量", "不同的内容关于部署"]
68
+ assert len(find_duplicates(entries, threshold=0.5)) >= 1
69
+
70
+
71
+ class TestMergeDuplicates:
72
+ def test_no_groups(self):
73
+ assert merge_duplicates(["a", "b"], []) == ["a", "b"]
74
+
75
+
76
+ class TestCollectEntries:
77
+ def test_workspace(self, tmp_workspace):
78
+ entries = _collect_entries(str(tmp_workspace))
79
+ assert len(entries) > 0
80
+
81
+ def test_nonexistent(self):
82
+ with pytest.raises(Exception):
83
+ _collect_entries("/nonexistent/xyz")
84
+
85
+ def test_empty(self, empty_file):
86
+ assert len(_collect_entries(str(empty_file))) == 0
87
+
88
+ def test_unicode(self, unicode_file):
89
+ assert len(_collect_entries(str(unicode_file))) > 0
90
+
91
+
92
+ class TestRunDedup:
93
+ def test_basic(self, tmp_workspace):
94
+ result = run_dedup(str(tmp_workspace))
95
+ assert "total_entries" in result
96
+ assert "duplicate_groups" in result
97
+
98
+ def test_with_dupes(self, duplicate_content):
99
+ result = run_dedup(str(duplicate_content), threshold=0.5)
100
+ assert result["total_entries"] > 0
101
+
102
+ def test_auto_merge(self, duplicate_content):
103
+ result = run_dedup(str(duplicate_content), threshold=0.5, auto_merge=True)
104
+ assert "tokens_before" in result
105
+
106
+ def test_empty(self, tmp_path):
107
+ (tmp_path / "e.md").write_text("", encoding="utf-8")
108
+ assert run_dedup(str(tmp_path))["total_entries"] == 0
109
+
110
+ def test_nonexistent(self):
111
+ with pytest.raises(Exception):
112
+ run_dedup("/nonexistent/xyz")
113
+
114
+ def test_json(self, tmp_workspace):
115
+ assert json.loads(json.dumps(run_dedup(str(tmp_workspace))))
116
+
117
+
118
+ class TestFormatHuman:
119
+ def test_no_dupes(self):
120
+ assert "No duplicates" in format_human({"total_entries": 5, "duplicate_groups": [], "entries_removed": 0})
121
+
122
+ def test_with_dupes(self, duplicate_content):
123
+ output = format_human(run_dedup(str(duplicate_content), threshold=0.3))
124
+ assert "Deduplication Report" in output
@@ -0,0 +1,327 @@
1
+ """Tests for dictionary-based compression."""
2
+
3
+ import json
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ import pytest
8
+
9
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
10
+ from lib.dictionary import (
11
+ build_codebook, compress_text, decompress_text,
12
+ save_codebook, load_codebook, compression_stats,
13
+ _generate_codes, _tokenize_ngrams, _extract_ip_prefixes,
14
+ _extract_path_prefixes,
15
+ )
16
+
17
+
18
+ # --- Fixtures ---
19
+
20
+ @pytest.fixture
21
+ def sample_texts():
22
+ """Realistic memory-style texts with repetition."""
23
+ return [
24
+ "# Server Config\n\n- Gateway IP: 10.0.1.1\n- Node: remote-node at 10.0.1.2\n"
25
+ "- User: example_user\n- Path: /home/user/workspace\n"
26
+ "- NetworkID: abc123network456\n- Token: my-secret-token-2024\n",
27
+
28
+ "# Daily Notes\n\n- Connected to 10.0.1.1 gateway\n"
29
+ "- Deployed on remote-node (10.0.1.2)\n"
30
+ "- User example_user ran backup\n"
31
+ "- Workspace: /home/user/workspace\n"
32
+ "- Using token my-secret-token-2024\n",
33
+
34
+ "# More Notes\n\n- Gateway 10.0.1.1 is stable\n"
35
+ "- remote-node running fine at 10.0.1.2\n"
36
+ "- example_user home: /home/user/workspace\n"
37
+ "- Auth: my-secret-token-2024\n",
38
+ ]
39
+
40
+
41
+ @pytest.fixture
42
+ def codebook():
43
+ return {
44
+ "$GW": "10.0.1.1",
45
+ "$JP": "10.0.1.2",
46
+ "$U": "example_user",
47
+ "$WS": "/home/user/workspace",
48
+ "$TK": "my-secret-token-2024",
49
+ }
50
+
51
+
52
+ # --- Code generation ---
53
+
54
+ class TestGenerateCodes:
55
+ def test_count(self):
56
+ codes = _generate_codes(10)
57
+ assert len(codes) == 10
58
+
59
+ def test_uniqueness(self):
60
+ codes = _generate_codes(676)
61
+ assert len(set(codes)) == 676
62
+
63
+ def test_format(self):
64
+ codes = _generate_codes(5)
65
+ for c in codes:
66
+ assert c.startswith('$')
67
+ assert len(c) == 3
68
+ assert c[1:].isalpha() and c[1:].isupper()
69
+
70
+ def test_overflow_to_3char(self):
71
+ codes = _generate_codes(677)
72
+ assert len(codes) == 677
73
+ assert len(codes[-1]) == 4 # $AAA
74
+
75
+
76
+ # --- N-gram extraction ---
77
+
78
+ class TestTokenizeNgrams:
79
+ def test_basic(self):
80
+ ngrams = _tokenize_ngrams("the quick brown fox jumps over the lazy dog")
81
+ assert any("quick brown" in k for k in ngrams)
82
+
83
+ def test_min_length_filter(self):
84
+ ngrams = _tokenize_ngrams("a b c d e f")
85
+ # All ngrams shorter than MIN_PHRASE_LEN should be filtered
86
+ for gram in ngrams:
87
+ assert len(gram) >= 6
88
+
89
+ def test_empty(self):
90
+ assert len(_tokenize_ngrams("")) == 0
91
+
92
+
93
+ # --- IP prefix extraction ---
94
+
95
+ class TestExtractIpPrefixes:
96
+ def test_finds_common_prefix(self):
97
+ texts = [
98
+ "Server at 192.168.1.10 and 192.168.1.20",
99
+ "Also 192.168.1.30 and 10.0.0.1",
100
+ "More at 192.168.1.40",
101
+ ]
102
+ prefixes = _extract_ip_prefixes(texts)
103
+ assert any("192.168.1." in p for p in prefixes)
104
+
105
+ def test_no_ips(self):
106
+ assert _extract_ip_prefixes(["no ips here"]) == {}
107
+
108
+
109
+ # --- Path prefix extraction ---
110
+
111
+ class TestExtractPathPrefixes:
112
+ def test_finds_common_path(self):
113
+ texts = [
114
+ "File at /Users/duke/.openclaw/workspace/MEMORY.md",
115
+ "Also /Users/duke/.openclaw/workspace/TOOLS.md",
116
+ "And /Users/duke/.openclaw/workspace/memory/2026-01.md",
117
+ ]
118
+ prefixes = _extract_path_prefixes(texts)
119
+ assert any("/Users/duke/.openclaw" in p for p in prefixes)
120
+
121
+ def test_no_paths(self):
122
+ assert _extract_path_prefixes(["no paths"]) == {}
123
+
124
+
125
+ # --- Codebook building ---
126
+
127
+ class TestBuildCodebook:
128
+ def test_builds_from_texts(self, sample_texts):
129
+ cb = build_codebook(sample_texts, min_freq=2)
130
+ assert len(cb) > 0
131
+ # All values should be real phrases
132
+ for code, phrase in cb.items():
133
+ assert code.startswith('$')
134
+ assert len(phrase) >= 6
135
+
136
+ def test_empty_texts(self):
137
+ cb = build_codebook([], min_freq=2)
138
+ assert cb == {}
139
+
140
+ def test_no_frequent_phrases(self):
141
+ cb = build_codebook(["unique text one", "different text two"], min_freq=5)
142
+ assert cb == {}
143
+
144
+ def test_max_entries(self, sample_texts):
145
+ cb = build_codebook(sample_texts, max_entries=3, min_freq=2)
146
+ assert len(cb) <= 3
147
+
148
+ def test_no_overlapping_codes(self, sample_texts):
149
+ cb = build_codebook(sample_texts, min_freq=2)
150
+ codes = list(cb.keys())
151
+ for i, c1 in enumerate(codes):
152
+ for c2 in codes[i+1:]:
153
+ assert c1 != c2
154
+
155
+
156
+ # --- Compression / Decompression ---
157
+
158
+ class TestCompressDecompress:
159
+ def test_basic_compress(self, codebook):
160
+ text = "Gateway at 10.0.1.1 running"
161
+ r = compress_text(text, codebook)
162
+ assert "$GW" in r
163
+ assert "10.0.1.1" not in r
164
+
165
+ def test_basic_decompress(self, codebook):
166
+ compressed = "Gateway at $GW running"
167
+ r = decompress_text(compressed, codebook)
168
+ assert "10.0.1.1" in r
169
+ assert "$GW" not in r
170
+
171
+ def test_roundtrip(self, codebook):
172
+ """Compression then decompression must be lossless."""
173
+ text = (
174
+ "Connect to 10.0.1.1 as example_user\n"
175
+ "Node 10.0.1.2 is remote-node\n"
176
+ "Workspace: /home/user/workspace\n"
177
+ "Token: my-secret-token-2024\n"
178
+ )
179
+ compressed = compress_text(text, codebook)
180
+ decompressed = decompress_text(compressed, codebook)
181
+ assert decompressed == text
182
+
183
+ def test_roundtrip_no_matches(self, codebook):
184
+ text = "Nothing to compress here."
185
+ assert decompress_text(compress_text(text, codebook), codebook) == text
186
+
187
+ def test_roundtrip_all_matches(self, codebook):
188
+ text = "10.0.1.1 10.0.1.2 example_user"
189
+ assert decompress_text(compress_text(text, codebook), codebook) == text
190
+
191
+ def test_empty_codebook(self):
192
+ assert compress_text("hello", {}) == "hello"
193
+ assert decompress_text("hello", {}) == "hello"
194
+
195
+ def test_empty_text(self, codebook):
196
+ assert compress_text("", codebook) == ""
197
+ assert decompress_text("", codebook) == ""
198
+
199
+ def test_multiple_occurrences(self, codebook):
200
+ text = "IP 10.0.1.1 and again 10.0.1.1"
201
+ compressed = compress_text(text, codebook)
202
+ assert compressed.count("$GW") == 2
203
+ assert decompress_text(compressed, codebook) == text
204
+
205
+ def test_adjacent_codes(self, codebook):
206
+ text = "10.0.1.1example_user"
207
+ compressed = compress_text(text, codebook)
208
+ decompressed = decompress_text(compressed, codebook)
209
+ assert decompressed == text
210
+
211
+
212
+ class TestRoundtripWithBuiltCodebook:
213
+ """Test that build → compress → decompress is lossless."""
214
+
215
+ def test_full_pipeline(self, sample_texts):
216
+ cb = build_codebook(sample_texts, min_freq=2)
217
+ for text in sample_texts:
218
+ compressed = compress_text(text, cb)
219
+ decompressed = decompress_text(compressed, cb)
220
+ assert decompressed == text, f"Roundtrip failed for text starting with: {text[:50]}"
221
+
222
+ def test_large_corpus(self):
223
+ """Test with a larger synthetic corpus."""
224
+ base = "Server 192.168.1.{i} is running service-{i} on /opt/app/service-{i}/config"
225
+ texts = [base.format(i=i) for i in range(50)]
226
+ cb = build_codebook(texts, min_freq=3)
227
+ combined = '\n'.join(texts)
228
+ compressed = compress_text(combined, cb)
229
+ decompressed = decompress_text(compressed, cb)
230
+ assert decompressed == combined
231
+
232
+
233
+ # --- Save / Load ---
234
+
235
+ class TestSaveLoadCodebook:
236
+ def test_save_load_roundtrip(self, tmp_path, codebook):
237
+ path = tmp_path / "cb.json"
238
+ save_codebook(codebook, path)
239
+ loaded = load_codebook(path)
240
+ assert loaded == codebook
241
+
242
+ def test_load_nonexistent(self, tmp_path):
243
+ with pytest.raises(FileNotFoundError):
244
+ load_codebook(tmp_path / "nope.json")
245
+
246
+ def test_load_invalid(self, tmp_path):
247
+ path = tmp_path / "bad.json"
248
+ path.write_text('{"not_entries": true}')
249
+ with pytest.raises(ValueError):
250
+ load_codebook(path)
251
+
252
+ def test_save_creates_dirs(self, tmp_path, codebook):
253
+ path = tmp_path / "deep" / "nested" / "cb.json"
254
+ save_codebook(codebook, path)
255
+ assert path.exists()
256
+
257
+
258
+ # --- Stats ---
259
+
260
+ class TestCompressionStats:
261
+ def test_basic(self, codebook):
262
+ original = "10.0.1.1 is the gateway for example_user"
263
+ compressed = compress_text(original, codebook)
264
+ stats = compression_stats(original, compressed, codebook)
265
+ assert stats["gross_reduction_pct"] > 0
266
+ assert stats["codebook_entries"] == len(codebook)
267
+ assert stats["codes_used"] > 0
268
+
269
+ def test_empty(self):
270
+ stats = compression_stats("", "", {})
271
+ assert stats["gross_reduction_pct"] == 0.0
272
+
273
+
274
+ # --- Integration with dictionary_compress.py CLI ---
275
+
276
+ class TestCLICommands:
277
+ def test_build_and_stats(self, tmp_path):
278
+ from dictionary_compress import cmd_build, cmd_stats
279
+ # Create workspace
280
+ (tmp_path / "MEMORY.md").write_text(
281
+ "# Mem\n\n- Server: 192.168.1.100\n- Server: 192.168.1.100\n"
282
+ "- Path: /long/repeated/path/here\n- Path: /long/repeated/path/here\n"
283
+ "- Token: my-long-token-value-2024\n- Token: my-long-token-value-2024\n"
284
+ "- Again server 192.168.1.100 and /long/repeated/path/here\n"
285
+ )
286
+ mem = tmp_path / "memory"
287
+ mem.mkdir()
288
+ (mem / "day1.md").write_text(
289
+ "# Day\n- Used 192.168.1.100\n- At /long/repeated/path/here\n"
290
+ "- Auth: my-long-token-value-2024\n"
291
+ )
292
+
293
+ cb_path = tmp_path / "memory" / ".codebook.json"
294
+ result = cmd_build(tmp_path, cb_path, min_freq=2)
295
+ assert result["codebook_entries"] > 0
296
+ assert cb_path.exists()
297
+
298
+ stats = cmd_stats(tmp_path, cb_path)
299
+ assert stats["codebook_entries"] > 0
300
+
301
+ def test_compress_decompress_roundtrip(self, tmp_path):
302
+ from dictionary_compress import cmd_build, cmd_compress, cmd_decompress
303
+
304
+ original_text = (
305
+ "# Notes\n- IP: 10.20.30.40 is primary\n- IP: 10.20.30.40 backup too\n"
306
+ "- Workspace /home/user/.openclaw/workspace is main\n"
307
+ "- Also /home/user/.openclaw/workspace for backup\n"
308
+ "- Token super-secret-token-2024 used\n"
309
+ "- Again super-secret-token-2024 here\n"
310
+ "- And 10.20.30.40 again\n"
311
+ )
312
+ (tmp_path / "MEMORY.md").write_text(original_text)
313
+ mem = tmp_path / "memory"
314
+ mem.mkdir()
315
+
316
+ cb_path = mem / ".codebook.json"
317
+ cmd_build(tmp_path, cb_path, min_freq=2)
318
+
319
+ # Compress
320
+ cmd_compress(tmp_path, cb_path, dry_run=False)
321
+ compressed = (tmp_path / "MEMORY.md").read_text()
322
+ assert len(compressed) <= len(original_text)
323
+
324
+ # Decompress
325
+ cmd_decompress(tmp_path, cb_path, dry_run=False)
326
+ restored = (tmp_path / "MEMORY.md").read_text()
327
+ assert restored == original_text