@jairodri/huckleberry-cli 1.0.2 → 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 +347 -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,161 @@
1
+ """Performance tests against real workspace data — verifies actual savings."""
2
+ import sys
3
+ import pytest
4
+ from pathlib import Path
5
+
6
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
7
+
8
+ from compress_memory import rule_compress
9
+ from lib.tokens import estimate_tokens
10
+ from lib.dictionary import build_codebook, compress_text, decompress_text
11
+ from lib.tokenizer_optimizer import optimize_tokens
12
+ from lib.rle import compress as rle_compress
13
+
14
+ WORKSPACE = Path("/home/user/workspace")
15
+
16
+
17
+ def _skip_if_no_workspace():
18
+ if not WORKSPACE.is_dir():
19
+ pytest.skip("Real workspace not available")
20
+
21
+
22
+ def _read_workspace_texts():
23
+ _skip_if_no_workspace()
24
+ texts = {}
25
+ for name in ["MEMORY.md", "TOOLS.md", "AGENTS.md", "SOUL.md", "USER.md"]:
26
+ p = WORKSPACE / name
27
+ if p.exists():
28
+ texts[name] = p.read_text()
29
+ mem = WORKSPACE / "memory"
30
+ if mem.is_dir():
31
+ for f in sorted(mem.rglob("*.md"))[:20]:
32
+ texts[f.name] = f.read_text()
33
+ return texts
34
+
35
+
36
+ class TestRealWorkspacePerformance:
37
+ """Tests against real workspace data to verify savings claims."""
38
+
39
+ def test_rule_compress_saves_tokens(self):
40
+ texts = _read_workspace_texts()
41
+ if not texts:
42
+ pytest.skip("No workspace files")
43
+ total_before = sum(estimate_tokens(t) for t in texts.values())
44
+ total_after = sum(estimate_tokens(rule_compress(t)) for t in texts.values())
45
+ saved = total_before - total_after
46
+ pct = (saved / total_before * 100) if total_before > 0 else 0
47
+ assert saved >= 0, "Rule compression should not increase tokens"
48
+ print(f"\nRule compress: {total_before:,} → {total_after:,} (saved {saved:,}, {pct:.1f}%)")
49
+
50
+ def test_dictionary_saves_tokens(self):
51
+ texts = _read_workspace_texts()
52
+ if not texts:
53
+ pytest.skip("No workspace files")
54
+ combined = "\n".join(texts.values())
55
+ codebook = build_codebook([combined])
56
+ compressed = compress_text(combined, codebook)
57
+ before = estimate_tokens(combined)
58
+ after = estimate_tokens(compressed)
59
+ saved = before - after
60
+ assert saved >= 0, "Dictionary compression should not increase tokens"
61
+ # Verify roundtrip
62
+ assert decompress_text(compressed, codebook) == combined
63
+ print(f"\nDict compress: {before:,} → {after:,} (saved {saved:,})")
64
+
65
+ def test_tokenizer_optimize_saves_tokens(self):
66
+ texts = _read_workspace_texts()
67
+ if not texts:
68
+ pytest.skip("No workspace files")
69
+ total_before = sum(estimate_tokens(t) for t in texts.values())
70
+ total_after = sum(estimate_tokens(optimize_tokens(t)) for t in texts.values())
71
+ saved = total_before - total_after
72
+ assert saved >= 0, "Tokenizer optimize should not increase tokens"
73
+ print(f"\nTokenizer optimize: {total_before:,} → {total_after:,} (saved {saved:,})")
74
+
75
+ def test_combined_pipeline_savings(self):
76
+ """Full pipeline on real data."""
77
+ texts = _read_workspace_texts()
78
+ if not texts:
79
+ pytest.skip("No workspace files")
80
+
81
+ combined = "\n".join(texts.values())
82
+ initial = estimate_tokens(combined)
83
+
84
+ # Step 1: Rule compress
85
+ rule_texts = {k: rule_compress(v) for k, v in texts.items()}
86
+ rule_combined = "\n".join(rule_texts.values())
87
+ after_rule = estimate_tokens(rule_combined)
88
+
89
+ # Step 2: Dict compress
90
+ codebook = build_codebook([rule_combined])
91
+ dict_combined = compress_text(rule_combined, codebook)
92
+ after_dict = estimate_tokens(dict_combined)
93
+
94
+ # Step 3: Tokenizer optimize
95
+ opt_combined = optimize_tokens(dict_combined)
96
+ after_opt = estimate_tokens(opt_combined)
97
+
98
+ total_saved = initial - after_opt
99
+ pct = (total_saved / initial * 100) if initial > 0 else 0
100
+
101
+ print(f"\n=== Combined Pipeline ===")
102
+ print(f" Initial: {initial:,} tokens")
103
+ print(f" After rule: {after_rule:,} ({initial - after_rule:,} saved)")
104
+ print(f" After dict: {after_dict:,} ({after_rule - after_dict:,} saved)")
105
+ print(f" After opt: {after_opt:,} ({after_dict - after_opt:,} saved)")
106
+ print(f" TOTAL: {total_saved:,} tokens saved ({pct:.1f}%)")
107
+
108
+ assert total_saved >= 0
109
+
110
+ def test_per_file_breakdown(self):
111
+ texts = _read_workspace_texts()
112
+ if not texts:
113
+ pytest.skip("No workspace files")
114
+
115
+ print(f"\n{'File':<25} | {'Before':>7} | {'After':>7} | {'Saved':>6} | {'%':>5}")
116
+ print(f"{'-'*25}-+-{'-'*7}-+-{'-'*7}-+-{'-'*6}-+-{'-'*5}")
117
+
118
+ for name, text in sorted(texts.items()):
119
+ before = estimate_tokens(text)
120
+ compressed = rule_compress(text)
121
+ after = estimate_tokens(compressed)
122
+ saved = before - after
123
+ pct = (saved / before * 100) if before > 0 else 0
124
+ print(f"{name:<25} | {before:>7,} | {after:>7,} | {saved:>6,} | {pct:>4.1f}%")
125
+ assert saved >= 0, f"{name}: compression increased tokens!"
126
+
127
+
128
+ class TestSessionTranscriptStats:
129
+ """Verify session transcript compression claims."""
130
+
131
+ def test_transcript_exists(self):
132
+ _skip_if_no_workspace()
133
+ sessions_dir = Path.home() / ".openclaw" / "agents" / "main" / "sessions"
134
+ if not sessions_dir.is_dir():
135
+ pytest.skip("No sessions directory")
136
+ files = list(sessions_dir.glob("*.jsonl"))
137
+ print(f"\nFound {len(files)} session transcripts")
138
+ assert len(files) >= 0 # Just report
139
+
140
+ def test_sample_transcript_compression(self):
141
+ _skip_if_no_workspace()
142
+ sessions_dir = Path.home() / ".openclaw" / "agents" / "main" / "sessions"
143
+ if not sessions_dir.is_dir():
144
+ pytest.skip("No sessions directory")
145
+ files = sorted(sessions_dir.glob("*.jsonl"))
146
+ if not files:
147
+ pytest.skip("No session files")
148
+
149
+ from observation_compressor import compress_session, format_observations_md
150
+
151
+ # Take first file only
152
+ f = files[0]
153
+ original_tokens = estimate_tokens(f.read_text())
154
+ result = compress_session(f)
155
+ obs = result.get("observations", [])
156
+ compressed_text = format_observations_md(obs)
157
+ compressed_tokens = estimate_tokens(compressed_text) if compressed_text.strip() else 0
158
+
159
+ if original_tokens > 0:
160
+ ratio = (1 - compressed_tokens / original_tokens) * 100
161
+ print(f"\nSample transcript: {original_tokens:,} → {compressed_tokens:,} ({ratio:.1f}% compression)")
@@ -0,0 +1,114 @@
1
+ """Tests for RLE (Run-Length Encoding) structured data compression."""
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 lib.rle import (
10
+ compress_paths, decompress_paths,
11
+ compress_ip_families, decompress_ip_families,
12
+ compress_enumerations, compress,
13
+ decompress,
14
+ )
15
+
16
+
17
+ WS_PATH = "/home/user/workspace"
18
+
19
+
20
+ class TestCompressPaths:
21
+ def test_basic(self):
22
+ text = f"File at {WS_PATH}/memory/test.md"
23
+ result = compress_paths(text, [WS_PATH])
24
+ assert "$WS/memory/test.md" in result
25
+ assert WS_PATH not in result
26
+
27
+ def test_multiple_occurrences(self):
28
+ text = f"{WS_PATH}/a.md and {WS_PATH}/b.md"
29
+ result = compress_paths(text, [WS_PATH])
30
+ assert result.count("$WS") == 2
31
+
32
+ def test_no_match(self):
33
+ text = "No paths here"
34
+ assert compress_paths(text, [WS_PATH]) == text
35
+
36
+ def test_roundtrip(self):
37
+ text = f"Path: {WS_PATH}/skills/claw-compactor"
38
+ compressed = compress_paths(text, [WS_PATH])
39
+ decompressed = decompress_paths(compressed, WS_PATH)
40
+ assert decompressed == text
41
+
42
+
43
+ class TestCompressIPFamilies:
44
+ def test_basic(self):
45
+ text = "Server at 10.0.1.1 and node at 10.0.1.2"
46
+ result, prefix_map = compress_ip_families(text)
47
+ assert len(prefix_map) > 0
48
+ # Should be shorter
49
+ assert len(result) < len(text)
50
+
51
+ def test_roundtrip(self):
52
+ text = "IPs: 10.0.1.1, 10.0.1.2, 10.0.1.3"
53
+ compressed, prefix_map = compress_ip_families(text)
54
+ decompressed = decompress_ip_families(compressed, prefix_map)
55
+ # All original IPs should be present
56
+ assert "10.0.1.1" in decompressed
57
+ assert "10.0.1.2" in decompressed
58
+ assert "10.0.1.3" in decompressed
59
+
60
+ def test_different_subnets(self):
61
+ text = "10.0.0.1 and 10.0.0.2 and 192.168.1.1"
62
+ result, prefix_map = compress_ip_families(text)
63
+ # 10.0.0.x family should be compressed
64
+ assert "$IP" in result or len(prefix_map) > 0
65
+
66
+ def test_single_ip_no_compress(self):
67
+ text = "Only one IP: 10.0.0.1"
68
+ result, prefix_map = compress_ip_families(text)
69
+ assert result == text
70
+ assert len(prefix_map) == 0
71
+
72
+
73
+ class TestCompressEnumerations:
74
+ def test_ticker_list(self):
75
+ text = "Trading pairs: BTC, ETH, SOL, BNB, DOGE"
76
+ result = compress_enumerations(text)
77
+ assert "[BTC,ETH,SOL,BNB,DOGE]" in result
78
+
79
+ def test_short_list_no_change(self):
80
+ text = "BTC, ETH, SOL"
81
+ result = compress_enumerations(text)
82
+ assert result == text # Only 3 items, no change
83
+
84
+ def test_mixed_case_no_change(self):
85
+ text = "apple, banana, cherry, date"
86
+ result = compress_enumerations(text)
87
+ assert result == text # Not all-caps codes
88
+
89
+
90
+ class TestCompress:
91
+ def test_combined(self):
92
+ text = (
93
+ f"Connected to {WS_PATH}/config\n"
94
+ "IPs: 10.0.1.1, 10.0.1.2\n"
95
+ "Tokens: BTC, ETH, SOL, BNB, DOGE\n"
96
+ )
97
+ result = compress(text, [WS_PATH])
98
+ assert "$WS" in result
99
+ assert len(result) < len(text)
100
+
101
+ def test_empty(self):
102
+ assert compress("") == ""
103
+
104
+ def test_unicode(self):
105
+ text = f"中文路径 {WS_PATH}/中文文件.md"
106
+ result = compress(text, [WS_PATH])
107
+ assert "中文" in result
108
+ assert "$WS" in result
109
+
110
+ def test_decompress_paths(self):
111
+ text = f"Path: {WS_PATH}/test"
112
+ compressed = compress(text, [WS_PATH])
113
+ decompressed = decompress(compressed, WS_PATH)
114
+ assert WS_PATH in decompressed
@@ -0,0 +1,151 @@
1
+ """Comprehensive tests for lib/rle.py."""
2
+ import sys
3
+ import pytest
4
+ from pathlib import Path
5
+
6
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
7
+ from lib.rle import (
8
+ compress_paths, decompress_paths,
9
+ compress_ip_families, decompress_ip_families,
10
+ compress_enumerations, compress_repeated_headers,
11
+ compress, decompress,
12
+ )
13
+
14
+
15
+ class TestCompressPaths:
16
+ def test_basic(self):
17
+ ws = "/Users/duke/workspace"
18
+ text = f"File at {ws}/memory/test.md"
19
+ result = compress_paths(text, [ws])
20
+ assert "$WS" in result or ws not in result or result == text
21
+
22
+ def test_multiple_paths(self):
23
+ ws = "/Users/duke/workspace"
24
+ text = f"{ws}/a.md and {ws}/b.md and {ws}/c.md"
25
+ result = compress_paths(text, [ws])
26
+ assert isinstance(result, str)
27
+
28
+ def test_no_match(self):
29
+ text = "no paths here"
30
+ result = compress_paths(text, ["/Users/duke/workspace"])
31
+ assert result == text
32
+
33
+ def test_empty(self):
34
+ result = compress_paths("", ["/Users/duke"])
35
+ assert result == ""
36
+
37
+ def test_none_workspace(self):
38
+ result = compress_paths("some text", None)
39
+ assert result == "some text"
40
+
41
+ def test_empty_workspace_list(self):
42
+ result = compress_paths("some text", [])
43
+ assert result == "some text"
44
+
45
+
46
+ class TestCompressIPFamilies:
47
+ def test_basic_family(self):
48
+ text = "192.168.1.100 and 192.168.1.200 and 192.168.1.50"
49
+ result, prefix_map = compress_ip_families(text)
50
+ assert isinstance(result, str)
51
+ assert isinstance(prefix_map, dict)
52
+
53
+ def test_no_ips(self):
54
+ text = "no ips here"
55
+ result, prefix_map = compress_ip_families(text)
56
+ assert result == text
57
+
58
+ def test_single_ip(self):
59
+ text = "host: 10.0.0.1"
60
+ result, prefix_map = compress_ip_families(text)
61
+ assert isinstance(result, str)
62
+
63
+ def test_different_subnets(self):
64
+ text = "10.0.0.1 and 192.168.1.1 and 172.16.0.1"
65
+ result, prefix_map = compress_ip_families(text)
66
+ assert isinstance(result, str)
67
+
68
+ def test_empty(self):
69
+ result, _ = compress_ip_families("")
70
+ assert result == ""
71
+
72
+ def test_min_occurrences(self):
73
+ text = "10.0.0.1 once"
74
+ result, _ = compress_ip_families(text, min_occurrences=5)
75
+ assert result == text
76
+
77
+
78
+ class TestCompressEnumerations:
79
+ def test_basic(self):
80
+ text = "worker-1, worker-2, worker-3, worker-4, worker-5"
81
+ result = compress_enumerations(text)
82
+ assert isinstance(result, str)
83
+
84
+ def test_no_enumerations(self):
85
+ text = "no enumerations here"
86
+ assert compress_enumerations(text) == text
87
+
88
+ def test_empty(self):
89
+ assert compress_enumerations("") == ""
90
+
91
+ def test_numbered_items(self):
92
+ text = "node-1 node-2 node-3 node-4"
93
+ result = compress_enumerations(text)
94
+ assert isinstance(result, str)
95
+
96
+
97
+ class TestCompressRepeatedHeaders:
98
+ def test_repeated(self):
99
+ text = "## Section\nfoo\n## Section\nbar"
100
+ result = compress_repeated_headers(text)
101
+ assert isinstance(result, str)
102
+
103
+ def test_no_repeats(self):
104
+ text = "## A\nfoo\n## B\nbar"
105
+ result = compress_repeated_headers(text)
106
+ assert "A" in result and "B" in result
107
+
108
+ def test_empty(self):
109
+ assert compress_repeated_headers("") == ""
110
+
111
+
112
+ class TestCompress:
113
+ """Test the main compress() function."""
114
+
115
+ def test_basic(self):
116
+ text = "Some text with /Users/duke/workspace/file.md"
117
+ result = compress(text, ["/Users/duke/workspace"])
118
+ assert isinstance(result, str)
119
+
120
+ def test_empty(self):
121
+ assert compress("") == ""
122
+
123
+ def test_no_compression_needed(self):
124
+ text = "plain text"
125
+ result = compress(text)
126
+ assert result == text
127
+
128
+ def test_combined_features(self):
129
+ text = (
130
+ "192.168.1.100 and 192.168.1.200\n"
131
+ "worker-1, worker-2, worker-3\n"
132
+ "## Header\nfoo\n## Header\nbar"
133
+ )
134
+ result = compress(text)
135
+ assert isinstance(result, str)
136
+
137
+
138
+ class TestDecompress:
139
+ def test_basic_roundtrip(self):
140
+ ws = "/Users/duke/workspace"
141
+ text = f"{ws}/test.md"
142
+ compressed = compress(text, [ws])
143
+ decompressed = decompress(compressed, ws)
144
+ assert text in decompressed or decompressed == text
145
+
146
+ def test_empty(self):
147
+ assert decompress("", "/Users/duke") == ""
148
+
149
+ def test_no_markers(self):
150
+ text = "nothing to decompress"
151
+ assert decompress(text, "/Users/duke") == text
@@ -0,0 +1,253 @@
1
+ """Roundtrip tests — the most important invariant.
2
+
3
+ compress → decompress MUST equal original for all lossless techniques.
4
+ Tests cover: ASCII, Chinese, mixed, edge cases, $-containing text.
5
+ """
6
+
7
+ import json
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ import pytest
12
+
13
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
14
+ from lib.dictionary import (
15
+ build_codebook, compress_text, decompress_text,
16
+ save_codebook, load_codebook,
17
+ )
18
+ from lib.rle import (
19
+ compress_paths, decompress_paths,
20
+ compress_ip_families, decompress_ip_families,
21
+ )
22
+
23
+
24
+ # --- Dictionary Roundtrip ---
25
+
26
+ class TestDictionaryRoundtripASCII:
27
+ """Pure ASCII text roundtrips."""
28
+
29
+ @pytest.fixture
30
+ def codebook(self):
31
+ return {
32
+ "$GW": "10.0.1.1",
33
+ "$JP": "10.0.1.2",
34
+ "$TK": "my-secret-token-2024",
35
+ "$WS": "/home/user/workspace",
36
+ }
37
+
38
+ def test_simple(self, codebook):
39
+ text = "Gateway at 10.0.1.1 running"
40
+ assert decompress_text(compress_text(text, codebook), codebook) == text
41
+
42
+ def test_multiple_replacements(self, codebook):
43
+ text = "Connect to 10.0.1.1 via 10.0.1.2 using my-secret-token-2024"
44
+ assert decompress_text(compress_text(text, codebook), codebook) == text
45
+
46
+ def test_no_matches(self, codebook):
47
+ text = "Nothing matches here at all"
48
+ assert decompress_text(compress_text(text, codebook), codebook) == text
49
+
50
+ def test_all_replaced(self, codebook):
51
+ text = "10.0.1.1"
52
+ assert decompress_text(compress_text(text, codebook), codebook) == text
53
+
54
+ def test_multiline(self, codebook):
55
+ text = "Line 1: 10.0.1.1\nLine 2: 10.0.1.2\nLine 3: done"
56
+ assert decompress_text(compress_text(text, codebook), codebook) == text
57
+
58
+ def test_adjacent_matches(self, codebook):
59
+ text = "10.0.1.110.0.1.2"
60
+ assert decompress_text(compress_text(text, codebook), codebook) == text
61
+
62
+ def test_repeated(self, codebook):
63
+ text = "10.0.1.1 and 10.0.1.1 and 10.0.1.1"
64
+ assert decompress_text(compress_text(text, codebook), codebook) == text
65
+
66
+
67
+ class TestDictionaryRoundtripChinese:
68
+ """Chinese text roundtrips."""
69
+
70
+ @pytest.fixture
71
+ def codebook(self):
72
+ return {
73
+ "$CN": "日本节点",
74
+ "$GW": "网关服务器",
75
+ "$WS": "工作空间目录",
76
+ }
77
+
78
+ def test_pure_chinese(self, codebook):
79
+ text = "连接到日本节点的网关服务器,在工作空间目录下操作"
80
+ assert decompress_text(compress_text(text, codebook), codebook) == text
81
+
82
+ def test_no_chinese_matches(self, codebook):
83
+ text = "纯中文但没有匹配的词语"
84
+ assert decompress_text(compress_text(text, codebook), codebook) == text
85
+
86
+
87
+ class TestDictionaryRoundtripMixed:
88
+ """Mixed ASCII + Chinese text roundtrips."""
89
+
90
+ @pytest.fixture
91
+ def codebook(self):
92
+ return {
93
+ "$GW": "10.0.1.1",
94
+ "$JP": "日本节点",
95
+ "$TK": "my-secret-token-2024",
96
+ }
97
+
98
+ def test_mixed(self, codebook):
99
+ text = "连接到10.0.1.1的日本节点,使用my-secret-token-2024认证"
100
+ assert decompress_text(compress_text(text, codebook), codebook) == text
101
+
102
+ def test_mixed_multiline(self, codebook):
103
+ text = "# 配置\n- 网关: 10.0.1.1\n- 节点: 日本节点\n- Token: my-secret-token-2024\n"
104
+ assert decompress_text(compress_text(text, codebook), codebook) == text
105
+
106
+
107
+ class TestDictionaryRoundtripDollarSign:
108
+ """Text containing $ that could conflict with code format."""
109
+
110
+ @pytest.fixture
111
+ def codebook(self):
112
+ return {
113
+ "$GW": "gateway",
114
+ "$JP": "japan",
115
+ }
116
+
117
+ def test_dollar_in_text(self, codebook):
118
+ """Text with $ should not be corrupted."""
119
+ text = "Price is $100 and gateway is main"
120
+ compressed = compress_text(text, codebook)
121
+ decompressed = decompress_text(compressed, codebook)
122
+ assert decompressed == text
123
+
124
+ def test_dollar_code_like_in_text(self, codebook):
125
+ """Text that looks like a code ($XX) but isn't in codebook."""
126
+ text = "Variable $AB is not a code, gateway runs"
127
+ compressed = compress_text(text, codebook)
128
+ decompressed = decompress_text(compressed, codebook)
129
+ assert decompressed == text
130
+
131
+ def test_existing_code_in_text(self, codebook):
132
+ """If text already contains $GW literally (not from codebook),
133
+ roundtrip may not be perfect — this is a known limitation.
134
+ The codebook should avoid phrases that look like codes."""
135
+ text = "The code $GW was already in the text"
136
+ compressed = compress_text(text, codebook)
137
+ # After compress: $GW is still $GW (text didn't contain "gateway" to replace)
138
+ # After decompress: $GW → "gateway"... this corrupts!
139
+ # This is expected — the codebook builder avoids this case
140
+ # by not creating codes that conflict with existing text
141
+
142
+
143
+ class TestDictionaryRoundtripEmpty:
144
+ """Empty and edge case roundtrips."""
145
+
146
+ def test_empty_text(self):
147
+ cb = {"$AA": "test"}
148
+ assert decompress_text(compress_text("", cb), cb) == ""
149
+
150
+ def test_empty_codebook(self):
151
+ assert decompress_text(compress_text("hello", {}), {}) == "hello"
152
+
153
+ def test_both_empty(self):
154
+ assert decompress_text(compress_text("", {}), {}) == ""
155
+
156
+ def test_only_whitespace(self):
157
+ cb = {"$AA": "test"}
158
+ text = " \n\n\t "
159
+ assert decompress_text(compress_text(text, cb), cb) == text
160
+
161
+
162
+ class TestDictionaryRoundtripBuiltCodebook:
163
+ """Roundtrip using auto-built codebooks from real-ish data."""
164
+
165
+ def test_workspace_like_data(self):
166
+ texts = [
167
+ "# Config\n- Gateway: 10.0.1.1\n- Node: remote-node 10.0.1.2\n"
168
+ "- Path: /home/user/workspace\n- Token: my-token-2024\n",
169
+ ] * 5 # Repeat to ensure frequency
170
+ cb = build_codebook(texts, min_freq=3)
171
+ for text in texts:
172
+ assert decompress_text(compress_text(text, cb), cb) == text
173
+
174
+ def test_unicode_heavy_data(self):
175
+ texts = [
176
+ "# 服务器配置\n- 网关服务器地址: 10.0.1.1\n- 日本节点地址: 10.0.2.1\n",
177
+ ] * 5
178
+ cb = build_codebook(texts, min_freq=3)
179
+ for text in texts:
180
+ assert decompress_text(compress_text(text, cb), cb) == text
181
+
182
+ def test_save_load_preserves_roundtrip(self, tmp_path):
183
+ """Codebook saved to disk and reloaded still roundtrips."""
184
+ texts = [
185
+ "server 192.168.1.100 with token super-long-token-value-here\n" * 3,
186
+ ] * 3
187
+ cb = build_codebook(texts, min_freq=2)
188
+ if not cb:
189
+ pytest.skip("No codebook built")
190
+
191
+ path = tmp_path / "cb.json"
192
+ save_codebook(cb, path)
193
+ loaded_cb = load_codebook(path)
194
+
195
+ combined = '\n'.join(texts)
196
+ compressed = compress_text(combined, loaded_cb)
197
+ decompressed = decompress_text(compressed, loaded_cb)
198
+ assert decompressed == combined
199
+
200
+
201
+ # --- RLE Roundtrip ---
202
+
203
+ class TestRLEPathRoundtrip:
204
+ """$WS path roundtrip."""
205
+
206
+ WS = "/home/user/workspace"
207
+
208
+ def test_basic(self):
209
+ text = f"File: {self.WS}/memory/test.md"
210
+ compressed = compress_paths(text, [self.WS])
211
+ decompressed = decompress_paths(compressed, self.WS)
212
+ assert decompressed == text
213
+
214
+ def test_multiple(self):
215
+ text = f"{self.WS}/a.md and {self.WS}/b.md"
216
+ compressed = compress_paths(text, [self.WS])
217
+ decompressed = decompress_paths(compressed, self.WS)
218
+ assert decompressed == text
219
+
220
+ def test_no_match(self):
221
+ text = "no paths here"
222
+ compressed = compress_paths(text, [self.WS])
223
+ decompressed = decompress_paths(compressed, self.WS)
224
+ assert decompressed == text
225
+
226
+ def test_empty(self):
227
+ compressed = compress_paths("", [self.WS])
228
+ decompressed = decompress_paths(compressed, self.WS)
229
+ assert decompressed == ""
230
+
231
+
232
+ class TestRLEIPRoundtrip:
233
+ """IP family compression roundtrip."""
234
+
235
+ def test_basic(self):
236
+ text = "IPs: 10.0.1.1, 10.0.1.2, 10.0.1.3"
237
+ compressed, prefix_map = compress_ip_families(text)
238
+ decompressed = decompress_ip_families(compressed, prefix_map)
239
+ assert "10.0.1.1" in decompressed
240
+ assert "10.0.1.2" in decompressed
241
+ assert "10.0.1.3" in decompressed
242
+
243
+ def test_no_ips(self):
244
+ text = "no IPs"
245
+ compressed, prefix_map = compress_ip_families(text)
246
+ decompressed = decompress_ip_families(compressed, prefix_map)
247
+ assert decompressed == text
248
+
249
+ def test_single_ip(self):
250
+ text = "Only 10.0.0.1 here"
251
+ compressed, prefix_map = compress_ip_families(text)
252
+ decompressed = decompress_ip_families(compressed, prefix_map)
253
+ assert decompressed == text