@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,194 @@
1
+ """Error handling tests — file not found, corrupt data, edge cases."""
2
+ import json
3
+ import sys
4
+ import pytest
5
+ from pathlib import Path
6
+
7
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
8
+
9
+ from lib.exceptions import FileNotFoundError_, MemCompressError, ParseError, TokenEstimationError
10
+ from lib.dictionary import load_codebook, save_codebook, compress_text, decompress_text, build_codebook
11
+ from lib.tokens import estimate_tokens
12
+
13
+
14
+ class TestExceptions:
15
+ def test_file_not_found_is_mem_compress_error(self):
16
+ assert issubclass(FileNotFoundError_, MemCompressError)
17
+
18
+ def test_parse_error_is_mem_compress_error(self):
19
+ assert issubclass(ParseError, MemCompressError)
20
+
21
+ def test_token_estimation_error(self):
22
+ assert issubclass(TokenEstimationError, MemCompressError)
23
+
24
+ def test_raise_file_not_found(self):
25
+ with pytest.raises(FileNotFoundError_):
26
+ raise FileNotFoundError_("test.md")
27
+
28
+ def test_raise_parse_error(self):
29
+ with pytest.raises(ParseError):
30
+ raise ParseError("bad markdown")
31
+
32
+ def test_exception_message(self):
33
+ e = FileNotFoundError_("missing.md")
34
+ assert "missing.md" in str(e)
35
+
36
+
37
+ class TestDictionaryErrors:
38
+ def test_load_nonexistent_codebook(self, tmp_path):
39
+ with pytest.raises(Exception):
40
+ load_codebook(tmp_path / "nonexistent.json")
41
+
42
+ def test_load_corrupt_codebook(self, tmp_path):
43
+ bad = tmp_path / "bad.json"
44
+ bad.write_text("this is not json{{{")
45
+ with pytest.raises(Exception):
46
+ load_codebook(bad)
47
+
48
+ def test_load_empty_file(self, tmp_path):
49
+ empty = tmp_path / "empty.json"
50
+ empty.write_text("")
51
+ with pytest.raises(Exception):
52
+ load_codebook(empty)
53
+
54
+ def test_compress_empty_codebook(self):
55
+ result = compress_text("hello world", {})
56
+ assert result == "hello world"
57
+
58
+ def test_decompress_empty_codebook(self):
59
+ result = decompress_text("hello world", {})
60
+ assert result == "hello world"
61
+
62
+ def test_compress_empty_text(self):
63
+ result = compress_text("", {"hello": "$AA"})
64
+ assert result == ""
65
+
66
+ def test_build_codebook_empty_input(self):
67
+ result = build_codebook([])
68
+ assert isinstance(result, dict)
69
+
70
+ def test_build_codebook_whitespace_only(self):
71
+ result = build_codebook([" \n\n "])
72
+ assert isinstance(result, dict)
73
+
74
+ def test_save_load_roundtrip(self, tmp_path):
75
+ codebook = {"hello": "$AA", "world": "$AB"}
76
+ path = tmp_path / "cb.json"
77
+ save_codebook(codebook, path)
78
+ loaded = load_codebook(path)
79
+ assert loaded == codebook
80
+
81
+
82
+ class TestEstimateTokenErrors:
83
+ def test_none_input(self):
84
+ """Estimate tokens with None should raise or handle gracefully."""
85
+ with pytest.raises((TypeError, AttributeError)):
86
+ estimate_tokens(None)
87
+
88
+ def test_numeric_input(self):
89
+ with pytest.raises((TypeError, AttributeError)):
90
+ estimate_tokens(42)
91
+
92
+ def test_bytes_input(self):
93
+ with pytest.raises((TypeError, AttributeError)):
94
+ estimate_tokens(b"hello")
95
+
96
+
97
+ class TestCompressMemoryErrors:
98
+ def test_nonexistent_path(self):
99
+ from compress_memory import _collect_files
100
+ with pytest.raises(FileNotFoundError_):
101
+ _collect_files("/nonexistent/path/xyz123")
102
+
103
+ def test_empty_file(self, tmp_path):
104
+ from compress_memory import compress_file
105
+ f = tmp_path / "empty.md"
106
+ f.write_text("")
107
+ result = compress_file(f, dry_run=True, no_llm=True)
108
+ assert isinstance(result, dict)
109
+
110
+ def test_binary_content(self, tmp_path):
111
+ """Binary-ish content shouldn't crash."""
112
+ from compress_memory import rule_compress
113
+ text = "Normal text\x00\x01\x02 more text"
114
+ result = rule_compress(text)
115
+ assert isinstance(result, str)
116
+
117
+
118
+ class TestDedupErrors:
119
+ def test_nonexistent_path(self):
120
+ from dedup_memory import _collect_entries
121
+ with pytest.raises(FileNotFoundError_):
122
+ _collect_entries("/nonexistent/xyz")
123
+
124
+ def test_empty_directory(self, tmp_path):
125
+ from dedup_memory import _collect_entries
126
+ result = _collect_entries(str(tmp_path))
127
+ assert result == []
128
+
129
+
130
+ class TestEstimateTokensScript:
131
+ def test_nonexistent_path(self):
132
+ from estimate_tokens import scan_path
133
+ with pytest.raises(FileNotFoundError_):
134
+ scan_path("/nonexistent/xyz")
135
+
136
+
137
+ class TestAuditErrors:
138
+ def test_nonexistent_workspace(self):
139
+ from audit_memory import audit_workspace
140
+ with pytest.raises(FileNotFoundError_):
141
+ audit_workspace("/nonexistent/xyz")
142
+
143
+
144
+ class TestTiersErrors:
145
+ def test_nonexistent_path(self):
146
+ from generate_summary_tiers import _find_memory_files
147
+ with pytest.raises(FileNotFoundError_):
148
+ _find_memory_files("/nonexistent/xyz")
149
+
150
+
151
+ class TestObservationErrors:
152
+ def test_nonexistent_file(self):
153
+ from observation_compressor import parse_session_jsonl
154
+ with pytest.raises(Exception):
155
+ parse_session_jsonl(Path("/nonexistent/session.jsonl"))
156
+
157
+ def test_corrupt_jsonl(self, tmp_path):
158
+ from observation_compressor import parse_session_jsonl
159
+ f = tmp_path / "bad.jsonl"
160
+ f.write_text("not json\n{bad json}\n")
161
+ # Should handle gracefully (skip bad lines or raise)
162
+ try:
163
+ result = parse_session_jsonl(f)
164
+ assert isinstance(result, list)
165
+ except Exception:
166
+ pass # Either handling is acceptable
167
+
168
+ def test_empty_jsonl(self, tmp_path):
169
+ from observation_compressor import parse_session_jsonl
170
+ f = tmp_path / "empty.jsonl"
171
+ f.write_text("")
172
+ result = parse_session_jsonl(f)
173
+ assert result == []
174
+
175
+ def test_compress_empty_session(self, tmp_path):
176
+ from observation_compressor import compress_session
177
+ f = tmp_path / "empty.jsonl"
178
+ f.write_text("")
179
+ result = compress_session(f)
180
+ assert isinstance(result, dict)
181
+
182
+
183
+ class TestMainEntryErrors:
184
+ def test_nonexistent_workspace(self):
185
+ from mem_compress import _workspace_path
186
+ with pytest.raises(SystemExit):
187
+ _workspace_path("/nonexistent/xyz")
188
+
189
+ def test_file_as_workspace(self, tmp_path):
190
+ f = tmp_path / "file.txt"
191
+ f.write_text("hello")
192
+ from mem_compress import _workspace_path
193
+ with pytest.raises(SystemExit):
194
+ _workspace_path(str(f))
@@ -0,0 +1,99 @@
1
+ """Tests for estimate_tokens.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 estimate_tokens import scan_path, format_human, _score_potential
11
+ from lib.tokens import estimate_tokens, using_tiktoken
12
+
13
+
14
+ class TestEstimateTokens:
15
+ def test_empty_string(self):
16
+ assert estimate_tokens("") == 0
17
+
18
+ def test_simple_english(self):
19
+ tokens = estimate_tokens("Hello world, this is a test.")
20
+ assert 0 < tokens < 50
21
+
22
+ def test_unicode_chinese(self):
23
+ assert estimate_tokens("你好世界") > 0
24
+
25
+ def test_large_input(self):
26
+ assert estimate_tokens("word " * 25000) > 1000
27
+
28
+
29
+ class TestScorePotential:
30
+ def test_high_tokens(self):
31
+ assert _score_potential(3000, 2500) == "high"
32
+
33
+ def test_high_reduction(self):
34
+ assert _score_potential(1000, 800) == "high"
35
+
36
+ def test_medium(self):
37
+ assert _score_potential(600, 560) == "medium"
38
+
39
+ def test_low(self):
40
+ assert _score_potential(100, 98) == "low"
41
+
42
+ def test_zero(self):
43
+ assert _score_potential(0, 0) == "low"
44
+
45
+
46
+ class TestScanPath:
47
+ def test_workspace(self, tmp_workspace):
48
+ results = scan_path(str(tmp_workspace))
49
+ assert len(results) > 0
50
+ assert all("tokens" in r for r in results)
51
+
52
+ def test_single_file(self, tmp_workspace):
53
+ assert len(scan_path(str(tmp_workspace / "MEMORY.md"))) == 1
54
+
55
+ def test_empty_file(self, empty_file):
56
+ results = scan_path(str(empty_file))
57
+ assert len(results) == 1
58
+ assert results[0]["tokens"] == 0
59
+
60
+ def test_nonexistent(self):
61
+ with pytest.raises(Exception):
62
+ scan_path("/nonexistent/xyz")
63
+
64
+ def test_large_file(self, large_file):
65
+ results = scan_path(str(large_file))
66
+ assert results[0]["tokens"] > 1000
67
+
68
+ def test_unicode(self, unicode_file):
69
+ assert scan_path(str(unicode_file))[0]["tokens"] > 0
70
+
71
+ def test_broken_markdown(self, broken_markdown):
72
+ assert len(scan_path(str(broken_markdown))) == 1
73
+
74
+ def test_threshold(self, tmp_workspace):
75
+ assert len(scan_path(str(tmp_workspace), threshold=999999)) == 0
76
+
77
+ def test_headers_only(self, headers_only):
78
+ assert len(scan_path(str(headers_only))) == 1
79
+
80
+ def test_single_line(self, single_line):
81
+ assert scan_path(str(single_line))[0]["tokens"] > 0
82
+
83
+ def test_sorted_desc(self, tmp_workspace):
84
+ tokens = [r["tokens"] for r in scan_path(str(tmp_workspace))]
85
+ assert tokens == sorted(tokens, reverse=True)
86
+
87
+
88
+ class TestFormatHuman:
89
+ def test_empty(self):
90
+ assert "No files" in format_human([])
91
+
92
+ def test_normal(self, tmp_workspace):
93
+ output = format_human(scan_path(str(tmp_workspace)))
94
+ assert "Token Estimation Report" in output
95
+
96
+ def test_json_roundtrip(self, tmp_workspace):
97
+ results = scan_path(str(tmp_workspace))
98
+ j = json.dumps({"files": results})
99
+ assert "files" in json.loads(j)
@@ -0,0 +1,105 @@
1
+ """Tests for generate_summary_tiers.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 generate_summary_tiers import generate_tiers, format_human, format_tier_template, _find_memory_files, _classify_section
11
+
12
+
13
+ class TestClassifySection:
14
+ def test_decision(self):
15
+ assert _classify_section("Important Decisions") >= 9
16
+
17
+ def test_archive(self):
18
+ assert _classify_section("Archive") <= 2
19
+
20
+ def test_action(self):
21
+ assert _classify_section("Action Items") >= 8
22
+
23
+ def test_unknown(self):
24
+ assert _classify_section("Random Header") == 5
25
+
26
+ def test_case_insensitive(self):
27
+ assert _classify_section("CRITICAL BUGS") >= 9
28
+
29
+
30
+ class TestFindMemoryFiles:
31
+ def test_workspace(self, tmp_workspace):
32
+ files = _find_memory_files(str(tmp_workspace))
33
+ assert len(files) > 0
34
+ assert "MEMORY.md" in str(files[0])
35
+
36
+ def test_single_file(self, tmp_workspace):
37
+ assert len(_find_memory_files(str(tmp_workspace / "MEMORY.md"))) == 1
38
+
39
+ def test_nonexistent(self):
40
+ with pytest.raises(Exception):
41
+ _find_memory_files("/nonexistent/xyz")
42
+
43
+ def test_empty_dir(self, tmp_path):
44
+ assert len(_find_memory_files(str(tmp_path))) == 0
45
+
46
+
47
+ class TestGenerateTiers:
48
+ def test_basic(self, tmp_workspace):
49
+ result = generate_tiers(_find_memory_files(str(tmp_workspace)))
50
+ assert "total_tokens" in result
51
+ assert len(result["tiers"]) == 3
52
+
53
+ def test_budgets_respected(self, tmp_workspace):
54
+ result = generate_tiers(_find_memory_files(str(tmp_workspace)))
55
+ for tier in result["tiers"].values():
56
+ assert tier["tokens_used"] <= tier["budget"]
57
+
58
+ def test_tier_ordering(self, tmp_workspace):
59
+ result = generate_tiers(_find_memory_files(str(tmp_workspace)))
60
+ counts = [result["tiers"][i]["sections_included"] for i in range(3)]
61
+ assert counts[0] <= counts[1] <= counts[2]
62
+
63
+ def test_empty_file(self, empty_file):
64
+ assert generate_tiers([empty_file])["total_tokens"] == 0
65
+
66
+ def test_unicode(self, unicode_file):
67
+ assert generate_tiers([unicode_file])["total_tokens"] > 0
68
+
69
+ def test_large_file(self, large_file):
70
+ assert generate_tiers([large_file])["total_sections"] > 100
71
+
72
+ def test_headers_only(self, headers_only):
73
+ assert isinstance(generate_tiers([headers_only]), dict)
74
+
75
+ def test_single_line(self, single_line):
76
+ assert generate_tiers([single_line])["total_sections"] >= 1
77
+
78
+ def test_broken_markdown(self, broken_markdown):
79
+ assert isinstance(generate_tiers([broken_markdown]), dict)
80
+
81
+
82
+ class TestFormatHuman:
83
+ def test_output(self, tmp_workspace):
84
+ output = format_human(generate_tiers(_find_memory_files(str(tmp_workspace))))
85
+ assert "Summary Tier Analysis" in output
86
+ for level in range(3):
87
+ assert "Level {}".format(level) in output
88
+
89
+
90
+ class TestFormatTierTemplate:
91
+ def test_markdown(self, tmp_workspace):
92
+ result = generate_tiers(_find_memory_files(str(tmp_workspace)))
93
+ for level in range(3):
94
+ t = format_tier_template(result, level)
95
+ assert "Level {}".format(level) in t
96
+ assert "Budget:" in t
97
+
98
+ def test_empty(self, empty_file):
99
+ assert isinstance(format_tier_template(generate_tiers([empty_file]), 0), str)
100
+
101
+
102
+ class TestJsonOutput:
103
+ def test_serializable(self, tmp_workspace):
104
+ result = generate_tiers(_find_memory_files(str(tmp_workspace)))
105
+ assert "tiers" in json.loads(json.dumps(result))
@@ -0,0 +1,249 @@
1
+ """Integration tests: full pipeline and cross-module scenarios."""
2
+
3
+ import json
4
+ import subprocess
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ import pytest
9
+
10
+ from estimate_tokens import scan_path, format_human as est_format
11
+ from compress_memory import rule_compress, compress_file, generate_llm_prompt
12
+ from generate_summary_tiers import generate_tiers
13
+ from dedup_memory import run_dedup
14
+ from lib.tokens import estimate_tokens
15
+ from lib.markdown import parse_sections, strip_markdown_redundancy
16
+ from lib.dedup import find_duplicates
17
+
18
+
19
+ class TestFullPipeline:
20
+ """End-to-end: estimate → compress → tiers → dedup."""
21
+
22
+ def test_estimate_compress_tiers_dedup(self, tmp_workspace: Path) -> None:
23
+ """Full pipeline on a populated workspace."""
24
+ ws = str(tmp_workspace)
25
+
26
+ # 1. Estimate
27
+ results = scan_path(ws)
28
+ assert len(results) > 0
29
+ total_before = sum(r["tokens"] for r in results)
30
+ assert total_before > 0
31
+
32
+ # 2. Compress each daily file
33
+ memory_dir = tmp_workspace / "memory"
34
+ for f in sorted(memory_dir.glob("*.md")):
35
+ stats = compress_file(f, dry_run=True, no_llm=True)
36
+ assert stats["original_tokens"] >= stats["rule_compressed_tokens"]
37
+ assert stats["rule_reduction_pct"] >= 0
38
+
39
+ # 3. Generate tiers
40
+ files = [tmp_workspace / "MEMORY.md"] + sorted(memory_dir.glob("*.md"))
41
+ tier_result = generate_tiers(files)
42
+ assert tier_result["total_tokens"] > 0
43
+ assert 0 in tier_result["tiers"]
44
+ assert 1 in tier_result["tiers"]
45
+ assert 2 in tier_result["tiers"]
46
+ # Level 0 should use fewer tokens than Level 2
47
+ assert tier_result["tiers"][0]["tokens_used"] <= tier_result["tiers"][2]["tokens_used"]
48
+
49
+ # 4. Dedup
50
+ dedup_result = run_dedup(ws)
51
+ assert "duplicate_groups" in dedup_result
52
+ assert dedup_result["total_entries"] >= 0
53
+
54
+ def test_unicode_pipeline(self, unicode_file: Path) -> None:
55
+ """Pipeline with Chinese/mixed content."""
56
+ # Estimate
57
+ results = scan_path(str(unicode_file))
58
+ assert len(results) == 1
59
+ assert results[0]["tokens"] > 0
60
+
61
+ # Compress
62
+ stats = compress_file(unicode_file, dry_run=True, no_llm=True)
63
+ assert stats["original_tokens"] > 0
64
+
65
+ # Parse sections
66
+ text = unicode_file.read_text(encoding="utf-8")
67
+ sections = parse_sections(text)
68
+ assert len(sections) >= 1
69
+
70
+ def test_large_file_pipeline(self, large_file: Path) -> None:
71
+ """Pipeline with ~100k+ char file."""
72
+ results = scan_path(str(large_file))
73
+ assert results[0]["tokens"] > 10000
74
+
75
+ stats = compress_file(large_file, dry_run=True, no_llm=True)
76
+ assert stats["original_tokens"] > 10000
77
+ # Rule compression should remove at least something
78
+ assert stats["rule_compressed_tokens"] <= stats["original_tokens"]
79
+
80
+ def test_empty_file_resilience(self, empty_file: Path) -> None:
81
+ """All tools handle empty file gracefully."""
82
+ results = scan_path(str(empty_file))
83
+ assert len(results) >= 1 # the file exists, just empty
84
+
85
+ stats = compress_file(empty_file, dry_run=True, no_llm=True)
86
+ assert stats["original_tokens"] == 0
87
+
88
+ def test_broken_markdown_resilience(self, broken_markdown: Path) -> None:
89
+ """Broken markdown doesn't crash anything."""
90
+ results = scan_path(str(broken_markdown))
91
+ assert len(results) == 1
92
+
93
+ stats = compress_file(broken_markdown, dry_run=True, no_llm=True)
94
+ assert stats["original_tokens"] > 0
95
+
96
+ sections = parse_sections(broken_markdown.read_text(encoding="utf-8"))
97
+ assert len(sections) >= 1
98
+
99
+ def test_dedup_finds_known_duplicates(self, duplicate_content: Path) -> None:
100
+ """Dedup correctly identifies known duplicate content."""
101
+ result = run_dedup(str(duplicate_content), threshold=0.5)
102
+ assert result["total_entries"] >= 2
103
+ # The two files have nearly identical "Setup" sections
104
+ assert len(result["duplicate_groups"]) >= 1
105
+
106
+ def test_dedup_auto_merge(self, duplicate_content: Path) -> None:
107
+ """Auto-merge removes duplicates and preserves unique content."""
108
+ result = run_dedup(str(duplicate_content), threshold=0.5, auto_merge=True)
109
+ if result["duplicate_groups"]:
110
+ assert result.get("tokens_saved", 0) >= 0
111
+ if "files_modified" in result:
112
+ # Verify unique content survived
113
+ b_text = (duplicate_content / "b.md").read_text(encoding="utf-8")
114
+ assert "Unique content" in b_text
115
+
116
+
117
+ class TestCompressionQuality:
118
+ """Verify compression preserves information."""
119
+
120
+ def test_rule_compress_preserves_facts(self) -> None:
121
+ """Rule compression keeps key facts."""
122
+ text = (
123
+ "# 2025-01-15 Session Notes\n\n"
124
+ "- Fixed critical bug in API endpoint /v2/orders\n"
125
+ "- Server IP: 10.0.2.1\n"
126
+ "- Deployed version 2.1.3 to production\n"
127
+ "- Met with Alice about Q2 roadmap\n"
128
+ "- Decision: migrate to PostgreSQL 16\n"
129
+ )
130
+ compressed = rule_compress(text)
131
+ # All critical facts should survive rule compression
132
+ assert "10.0.2.1" in compressed
133
+ assert "2.1.3" in compressed
134
+ assert "PostgreSQL" in compressed
135
+
136
+ def test_rule_compress_removes_dupes(self) -> None:
137
+ """Rule compression removes exact duplicate lines."""
138
+ text = (
139
+ "# Notes\n"
140
+ "- Deploy on AWS\n"
141
+ "- Deploy on AWS\n"
142
+ "- Different thing\n"
143
+ "- Deploy on AWS\n"
144
+ )
145
+ compressed = rule_compress(text)
146
+ assert compressed.count("Deploy on AWS") == 1
147
+ assert "Different thing" in compressed
148
+
149
+ def test_llm_prompt_contains_content(self) -> None:
150
+ """LLM prompt includes the content to compress."""
151
+ prompt = generate_llm_prompt("My test content here", target_pct=40)
152
+ assert "My test content here" in prompt
153
+ assert "40%" in prompt
154
+
155
+ def test_compression_ratio_reasonable(self, tmp_workspace: Path) -> None:
156
+ """Rule compression achieves reasonable ratio on real-ish content."""
157
+ mem_file = tmp_workspace / "MEMORY.md"
158
+ text = mem_file.read_text(encoding="utf-8")
159
+ original_tokens = estimate_tokens(text)
160
+ compressed = rule_compress(text)
161
+ compressed_tokens = estimate_tokens(compressed)
162
+ # Rule compression alone shouldn't inflate
163
+ assert compressed_tokens <= original_tokens
164
+
165
+
166
+ class TestTierQuality:
167
+ """Verify tier generation correctness."""
168
+
169
+ def test_tier_budget_respected(self, tmp_workspace: Path) -> None:
170
+ """Each tier stays within its token budget."""
171
+ files = [tmp_workspace / "MEMORY.md"]
172
+ result = generate_tiers(files)
173
+ for tier_level, tier in result["tiers"].items():
174
+ assert tier["tokens_used"] <= tier["budget"], (
175
+ f"Tier {tier_level} exceeded budget: "
176
+ f"{tier['tokens_used']} > {tier['budget']}"
177
+ )
178
+
179
+ def test_tier_ordering(self, tmp_workspace: Path) -> None:
180
+ """Higher tiers include more content."""
181
+ files = [tmp_workspace / "MEMORY.md"]
182
+ result = generate_tiers(files)
183
+ tiers = result["tiers"]
184
+ assert tiers[0]["tokens_used"] <= tiers[1]["tokens_used"]
185
+ assert tiers[1]["tokens_used"] <= tiers[2]["tokens_used"]
186
+
187
+ def test_tier_priority_ordering(self, tmp_workspace: Path) -> None:
188
+ """Higher-priority sections are included first."""
189
+ files = [tmp_workspace / "MEMORY.md"]
190
+ result = generate_tiers(files)
191
+ for tier in result["tiers"].values():
192
+ if len(tier["sections"]) >= 2:
193
+ priorities = [s["priority"] for s in tier["sections"]]
194
+ # Should be roughly descending (it IS sorted descending)
195
+ assert priorities == sorted(priorities, reverse=True)
196
+
197
+
198
+ class TestCLIScripts:
199
+ """Test scripts work as standalone CLI tools."""
200
+
201
+ def _run_script(self, script: str, args: list, cwd: str = None) -> subprocess.CompletedProcess:
202
+ script_path = Path(__file__).parent.parent / "scripts" / script
203
+ return subprocess.run(
204
+ [sys.executable, str(script_path)] + args,
205
+ capture_output=True, text=True, timeout=30,
206
+ cwd=cwd,
207
+ )
208
+
209
+ def test_estimate_tokens_cli(self, tmp_workspace: Path) -> None:
210
+ r = self._run_script("estimate_tokens.py", [str(tmp_workspace)])
211
+ assert r.returncode == 0
212
+ assert "tokens" in r.stdout.lower()
213
+
214
+ def test_estimate_tokens_json(self, tmp_workspace: Path) -> None:
215
+ r = self._run_script("estimate_tokens.py", [str(tmp_workspace), "--json"])
216
+ assert r.returncode == 0
217
+ data = json.loads(r.stdout)
218
+ assert "files" in data
219
+
220
+ def test_compress_dry_run(self, tmp_workspace: Path) -> None:
221
+ r = self._run_script("compress_memory.py", [
222
+ str(tmp_workspace / "MEMORY.md"), "--dry-run", "--json"
223
+ ])
224
+ assert r.returncode == 0
225
+
226
+ def test_tiers_cli(self, tmp_workspace: Path) -> None:
227
+ r = self._run_script("generate_summary_tiers.py", [str(tmp_workspace)])
228
+ assert r.returncode == 0
229
+ assert "Level" in r.stdout
230
+
231
+ def test_tiers_json(self, tmp_workspace: Path) -> None:
232
+ r = self._run_script("generate_summary_tiers.py", [str(tmp_workspace), "--json"])
233
+ assert r.returncode == 0
234
+ data = json.loads(r.stdout)
235
+ assert "tiers" in data
236
+
237
+ def test_dedup_cli(self, tmp_workspace: Path) -> None:
238
+ r = self._run_script("dedup_memory.py", [str(tmp_workspace)])
239
+ assert r.returncode == 0
240
+
241
+ def test_dedup_json(self, tmp_workspace: Path) -> None:
242
+ r = self._run_script("dedup_memory.py", [str(tmp_workspace), "--json"])
243
+ assert r.returncode == 0
244
+ data = json.loads(r.stdout)
245
+ assert "duplicate_groups" in data
246
+
247
+ def test_nonexistent_path(self) -> None:
248
+ r = self._run_script("estimate_tokens.py", ["/nonexistent/xyz123"])
249
+ assert r.returncode != 0