thumbgate 0.9.9

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 (369) hide show
  1. package/.claude-plugin/README.md +134 -0
  2. package/.claude-plugin/bundle/icon.png +0 -0
  3. package/.claude-plugin/bundle/icon.svg +18 -0
  4. package/.claude-plugin/bundle/server/index.js +24 -0
  5. package/.claude-plugin/marketplace.json +36 -0
  6. package/.claude-plugin/plugin.json +21 -0
  7. package/.well-known/mcp/server-card.json +231 -0
  8. package/LICENSE +21 -0
  9. package/README.md +375 -0
  10. package/adapters/README.md +9 -0
  11. package/adapters/amp/skills/rlhf-feedback/SKILL.md +22 -0
  12. package/adapters/chatgpt/INSTALL.md +83 -0
  13. package/adapters/chatgpt/openapi.yaml +1281 -0
  14. package/adapters/claude/.mcp.json +14 -0
  15. package/adapters/codex/config.toml +9 -0
  16. package/adapters/gemini/function-declarations.json +224 -0
  17. package/adapters/mcp/server-stdio.js +788 -0
  18. package/adapters/opencode/opencode.json +15 -0
  19. package/bin/cli.js +1483 -0
  20. package/bin/memory.sh +64 -0
  21. package/bin/obsidian-sync.sh +20 -0
  22. package/bin/postinstall.js +37 -0
  23. package/config/build-metadata.json +4 -0
  24. package/config/e2e-critical-flows.json +45 -0
  25. package/config/gate-templates.json +77 -0
  26. package/config/gates/claim-verification.json +29 -0
  27. package/config/gates/computer-use.json +39 -0
  28. package/config/gates/default.json +117 -0
  29. package/config/github-about.json +25 -0
  30. package/config/mcp-allowlists.json +135 -0
  31. package/config/model-tiers.json +33 -0
  32. package/config/partner-routing.json +132 -0
  33. package/config/policy-bundles/constrained-v1.json +64 -0
  34. package/config/policy-bundles/default-v1.json +91 -0
  35. package/config/rubrics/default-v1.json +52 -0
  36. package/config/skill-packs/react-testing.json +23 -0
  37. package/config/skill-packs/stripe-integration/references/api-spec.json +1 -0
  38. package/config/skill-packs/stripe-integration/references/webhook-guide.md +3 -0
  39. package/config/skill-specs/pr-reviewer.json +9 -0
  40. package/config/skill-specs/release-status.json +9 -0
  41. package/config/skill-specs/ticket-triage.json +9 -0
  42. package/config/subagent-profiles.json +32 -0
  43. package/config/tessl-tiles.json +29 -0
  44. package/config/thumbgate-settings.managed.json +12 -0
  45. package/openapi/openapi.yaml +1281 -0
  46. package/package.json +286 -0
  47. package/plugins/amp-skill/INSTALL.md +52 -0
  48. package/plugins/amp-skill/SKILL.md +64 -0
  49. package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +22 -0
  50. package/plugins/claude-codex-bridge/.mcp.json +12 -0
  51. package/plugins/claude-codex-bridge/INSTALL.md +43 -0
  52. package/plugins/claude-codex-bridge/README.md +46 -0
  53. package/plugins/claude-codex-bridge/scripts/codex-bridge.js +288 -0
  54. package/plugins/claude-codex-bridge/skills/adversarial-review/SKILL.md +24 -0
  55. package/plugins/claude-codex-bridge/skills/result/SKILL.md +22 -0
  56. package/plugins/claude-codex-bridge/skills/review/SKILL.md +28 -0
  57. package/plugins/claude-codex-bridge/skills/second-pass/SKILL.md +27 -0
  58. package/plugins/claude-codex-bridge/skills/setup/SKILL.md +21 -0
  59. package/plugins/claude-codex-bridge/skills/status/SKILL.md +19 -0
  60. package/plugins/claude-skill/INSTALL.md +55 -0
  61. package/plugins/claude-skill/SKILL.md +46 -0
  62. package/plugins/codex-profile/.codex-plugin/plugin.json +43 -0
  63. package/plugins/codex-profile/.mcp.json +12 -0
  64. package/plugins/codex-profile/AGENTS.md +20 -0
  65. package/plugins/codex-profile/INSTALL.md +66 -0
  66. package/plugins/codex-profile/README.md +37 -0
  67. package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +23 -0
  68. package/plugins/cursor-marketplace/CHANGELOG.md +30 -0
  69. package/plugins/cursor-marketplace/LICENSE +21 -0
  70. package/plugins/cursor-marketplace/README.md +124 -0
  71. package/plugins/cursor-marketplace/agents/reliability-reviewer.md +31 -0
  72. package/plugins/cursor-marketplace/assets/logo-400x400.png +0 -0
  73. package/plugins/cursor-marketplace/commands/capture-feedback.md +33 -0
  74. package/plugins/cursor-marketplace/commands/check-gates.md +25 -0
  75. package/plugins/cursor-marketplace/commands/show-lessons.md +27 -0
  76. package/plugins/cursor-marketplace/hooks/hooks.json +10 -0
  77. package/plugins/cursor-marketplace/mcp.json +12 -0
  78. package/plugins/cursor-marketplace/rules/feedback-capture.mdc +34 -0
  79. package/plugins/cursor-marketplace/rules/pre-action-gates.mdc +30 -0
  80. package/plugins/cursor-marketplace/rules/session-continuity.mdc +28 -0
  81. package/plugins/cursor-marketplace/scripts/gate-check.sh +11 -0
  82. package/plugins/cursor-marketplace/skills/capture-feedback/SKILL.md +47 -0
  83. package/plugins/cursor-marketplace/skills/prevention-rules/SKILL.md +31 -0
  84. package/plugins/cursor-marketplace/skills/recall-context/SKILL.md +30 -0
  85. package/plugins/cursor-marketplace/skills/search-lessons/SKILL.md +33 -0
  86. package/plugins/gemini-extension/INSTALL.md +92 -0
  87. package/plugins/gemini-extension/gemini_prompt.txt +14 -0
  88. package/plugins/gemini-extension/tool_contract.json +45 -0
  89. package/plugins/opencode-profile/INSTALL.md +57 -0
  90. package/public/assets/instagram-card.png +0 -0
  91. package/public/assets/tiktok-agent-memory.mp4 +0 -0
  92. package/public/blog.html +400 -0
  93. package/public/dashboard.html +1093 -0
  94. package/public/guide.html +317 -0
  95. package/public/index.html +1195 -0
  96. package/public/learn/agent-harness-pattern.html +180 -0
  97. package/public/learn/ai-agent-persistent-memory.html +202 -0
  98. package/public/learn/learn.css +45 -0
  99. package/public/learn/mcp-pre-action-gates-explained.html +172 -0
  100. package/public/learn/stop-ai-agent-force-push.html +134 -0
  101. package/public/learn/vibe-coding-safety-net.html +142 -0
  102. package/public/learn.html +213 -0
  103. package/public/lessons.html +650 -0
  104. package/public/vercel.json +8 -0
  105. package/scripts/__pycache__/train_from_feedback.cpython-314.pyc +0 -0
  106. package/scripts/a2ui-engine.js +73 -0
  107. package/scripts/access-anomaly-detector.js +12 -0
  108. package/scripts/adk-consolidator.js +266 -0
  109. package/scripts/agent-readiness.js +220 -0
  110. package/scripts/agent-security-hardening.js +227 -0
  111. package/scripts/agentic-data-pipeline.js +847 -0
  112. package/scripts/analytics-report.js +328 -0
  113. package/scripts/analytics-window.js +158 -0
  114. package/scripts/async-job-runner.js +1001 -0
  115. package/scripts/audit-trail.js +398 -0
  116. package/scripts/auto-promote-gates.js +293 -0
  117. package/scripts/auto-wire-hooks.js +316 -0
  118. package/scripts/autonomous-sales-agent.js +39 -0
  119. package/scripts/autoresearch-runner.js +216 -0
  120. package/scripts/background-agent-governance.js +237 -0
  121. package/scripts/behavioral-extraction.js +93 -0
  122. package/scripts/belief-update.js +84 -0
  123. package/scripts/billing.js +2438 -0
  124. package/scripts/bot-detector.js +50 -0
  125. package/scripts/budget-guard.js +173 -0
  126. package/scripts/build-claude-mcpb.js +189 -0
  127. package/scripts/build-metadata.js +97 -0
  128. package/scripts/check-congruence.js +322 -0
  129. package/scripts/cli-feedback.js +135 -0
  130. package/scripts/cli-telemetry.js +87 -0
  131. package/scripts/cloudflare-dynamic-sandbox.js +315 -0
  132. package/scripts/code-reasoning.js +350 -0
  133. package/scripts/codegraph-context.js +466 -0
  134. package/scripts/commercial-offer.js +56 -0
  135. package/scripts/computer-use-firewall.js +250 -0
  136. package/scripts/context-engine.js +694 -0
  137. package/scripts/contextfs.js +1287 -0
  138. package/scripts/conversation-context.js +119 -0
  139. package/scripts/creator-campaigns.js +239 -0
  140. package/scripts/daemon-manager.js +108 -0
  141. package/scripts/daily-digest.js +11 -0
  142. package/scripts/dashboard-render-spec.js +395 -0
  143. package/scripts/dashboard.js +1058 -0
  144. package/scripts/data-governance.js +173 -0
  145. package/scripts/delegation-runtime.js +900 -0
  146. package/scripts/deploy-gcp.sh +44 -0
  147. package/scripts/deploy-policy.js +231 -0
  148. package/scripts/disagreement-mining.js +315 -0
  149. package/scripts/dispatch-brief.js +159 -0
  150. package/scripts/distribution-surfaces.js +44 -0
  151. package/scripts/dpo-optimizer.js +206 -0
  152. package/scripts/ensure-repo-bootstrap.js +129 -0
  153. package/scripts/ephemeral-agent-store.js +219 -0
  154. package/scripts/eval-harness.js +56 -0
  155. package/scripts/evolution-state.js +241 -0
  156. package/scripts/experiment-tracker.js +267 -0
  157. package/scripts/export-databricks-bundle.js +242 -0
  158. package/scripts/export-dpo-pairs.js +344 -0
  159. package/scripts/export-kto-pairs.js +309 -0
  160. package/scripts/export-training.js +450 -0
  161. package/scripts/failure-diagnostics.js +558 -0
  162. package/scripts/feedback-attribution.js +313 -0
  163. package/scripts/feedback-fallback.js +110 -0
  164. package/scripts/feedback-history-distiller.js +391 -0
  165. package/scripts/feedback-inbox-read.js +162 -0
  166. package/scripts/feedback-loop.js +1887 -0
  167. package/scripts/feedback-paths.js +145 -0
  168. package/scripts/feedback-quality.js +139 -0
  169. package/scripts/feedback-root-consolidator.js +238 -0
  170. package/scripts/feedback-schema.js +426 -0
  171. package/scripts/feedback-session.js +286 -0
  172. package/scripts/feedback-to-memory.js +185 -0
  173. package/scripts/feedback-to-rules.js +164 -0
  174. package/scripts/filesystem-search.js +405 -0
  175. package/scripts/funnel-analytics.js +35 -0
  176. package/scripts/gate-satisfy.js +42 -0
  177. package/scripts/gate-stats.js +116 -0
  178. package/scripts/gate-templates.js +70 -0
  179. package/scripts/gates-engine.js +816 -0
  180. package/scripts/generate-paperbanana-diagrams.sh +99 -0
  181. package/scripts/generate-pretool-hook.sh +40 -0
  182. package/scripts/github-about.js +350 -0
  183. package/scripts/github-outreach.js +65 -0
  184. package/scripts/gtm-revenue-loop.js +520 -0
  185. package/scripts/hallucination-detector.js +226 -0
  186. package/scripts/hf-papers.js +317 -0
  187. package/scripts/history-distiller.js +200 -0
  188. package/scripts/hook-auto-capture.sh +100 -0
  189. package/scripts/hook-stop-pr-thread-check.sh +68 -0
  190. package/scripts/hook-stop-self-score.sh +51 -0
  191. package/scripts/hook-stop-verify-deploy.sh +31 -0
  192. package/scripts/hook-thumbgate-cache-updater.js +48 -0
  193. package/scripts/hook-verify-before-done.sh +20 -0
  194. package/scripts/hosted-config.js +156 -0
  195. package/scripts/hybrid-feedback-context.js +675 -0
  196. package/scripts/install-mcp.js +159 -0
  197. package/scripts/intent-router.js +392 -0
  198. package/scripts/internal-agent-bootstrap.js +490 -0
  199. package/scripts/jsonl-watcher.js +155 -0
  200. package/scripts/lesson-db.js +613 -0
  201. package/scripts/lesson-inference.js +310 -0
  202. package/scripts/lesson-retrieval.js +95 -0
  203. package/scripts/lesson-rotation.js +137 -0
  204. package/scripts/lesson-search.js +644 -0
  205. package/scripts/lesson-synthesis.js +196 -0
  206. package/scripts/license.js +50 -0
  207. package/scripts/local-model-profile.js +384 -0
  208. package/scripts/markdown-escape.js +12 -0
  209. package/scripts/marketing-experiment.js +671 -0
  210. package/scripts/mcp-config.js +149 -0
  211. package/scripts/mcp-policy.js +99 -0
  212. package/scripts/memalign-recall.js +111 -0
  213. package/scripts/memory-firewall.js +222 -0
  214. package/scripts/memory-migration.js +296 -0
  215. package/scripts/meta-policy.js +190 -0
  216. package/scripts/metered-billing.js +16 -0
  217. package/scripts/model-tier-router.js +301 -0
  218. package/scripts/money-watcher.js +71 -0
  219. package/scripts/multi-hop-recall.js +240 -0
  220. package/scripts/natural-language-harness.js +330 -0
  221. package/scripts/obsidian-export.js +713 -0
  222. package/scripts/operational-dashboard.js +103 -0
  223. package/scripts/operational-summary.js +93 -0
  224. package/scripts/optimize-context.js +17 -0
  225. package/scripts/org-dashboard.js +201 -0
  226. package/scripts/partner-orchestration.js +146 -0
  227. package/scripts/per-step-scoring.js +165 -0
  228. package/scripts/perplexity-marketing.js +466 -0
  229. package/scripts/pii-scanner.js +153 -0
  230. package/scripts/plan-gate.js +154 -0
  231. package/scripts/post-everywhere.js +308 -0
  232. package/scripts/post-to-x-retry.sh +22 -0
  233. package/scripts/post-to-x.js +369 -0
  234. package/scripts/pr-manager.js +236 -0
  235. package/scripts/predictive-insights.js +356 -0
  236. package/scripts/principle-extractor.js +162 -0
  237. package/scripts/pro-features.js +40 -0
  238. package/scripts/pro-local-dashboard.js +174 -0
  239. package/scripts/problem-detail.js +53 -0
  240. package/scripts/product-feedback.js +134 -0
  241. package/scripts/profile-router.js +245 -0
  242. package/scripts/prompt-dlp.js +221 -0
  243. package/scripts/prompt-guard.js +83 -0
  244. package/scripts/prove-adapters.js +863 -0
  245. package/scripts/prove-attribution.js +365 -0
  246. package/scripts/prove-automation.js +653 -0
  247. package/scripts/prove-autoresearch.js +304 -0
  248. package/scripts/prove-claim-verification.js +277 -0
  249. package/scripts/prove-cloudflare-sandbox.js +163 -0
  250. package/scripts/prove-data-pipeline.js +410 -0
  251. package/scripts/prove-data-quality.js +227 -0
  252. package/scripts/prove-evolution.js +352 -0
  253. package/scripts/prove-harnesses.js +287 -0
  254. package/scripts/prove-intelligence.js +259 -0
  255. package/scripts/prove-lancedb.js +371 -0
  256. package/scripts/prove-local-intelligence.js +342 -0
  257. package/scripts/prove-loop-closure.js +263 -0
  258. package/scripts/prove-predictive-insights.js +357 -0
  259. package/scripts/prove-runtime.js +350 -0
  260. package/scripts/prove-seo-gsd.js +234 -0
  261. package/scripts/prove-settings.js +279 -0
  262. package/scripts/prove-subway-upgrades.js +277 -0
  263. package/scripts/prove-tessl.js +229 -0
  264. package/scripts/prove-training-export.js +327 -0
  265. package/scripts/prove-workflow-contract.js +116 -0
  266. package/scripts/prove-xmemory.js +332 -0
  267. package/scripts/publish-decision.js +133 -0
  268. package/scripts/pulse.js +80 -0
  269. package/scripts/rate-limiter.js +125 -0
  270. package/scripts/reddit-dm-outreach.js +182 -0
  271. package/scripts/reddit-monitor-cron.sh +26 -0
  272. package/scripts/reflector-agent.js +221 -0
  273. package/scripts/reminder-engine.js +132 -0
  274. package/scripts/revenue-status.js +472 -0
  275. package/scripts/risk-scorer.js +459 -0
  276. package/scripts/rlaif-self-audit.js +129 -0
  277. package/scripts/rlhf_session_start.sh +32 -0
  278. package/scripts/rubric-engine.js +230 -0
  279. package/scripts/schedule-manager.js +251 -0
  280. package/scripts/secret-scanner.js +414 -0
  281. package/scripts/self-heal.js +147 -0
  282. package/scripts/self-healing-check.js +188 -0
  283. package/scripts/semantic-layer.js +98 -0
  284. package/scripts/seo-gsd.js +1153 -0
  285. package/scripts/settings-hierarchy.js +214 -0
  286. package/scripts/shieldcortex-memory-firewall-runner.mjs +53 -0
  287. package/scripts/skill-exporter.js +262 -0
  288. package/scripts/skill-generator.js +446 -0
  289. package/scripts/skill-materializer.js +134 -0
  290. package/scripts/skill-packs.js +136 -0
  291. package/scripts/skill-proposer.js +99 -0
  292. package/scripts/skill-quality-tracker.js +282 -0
  293. package/scripts/slo-alert-engine.js +14 -0
  294. package/scripts/slow-loop.js +72 -0
  295. package/scripts/social-analytics/db/schema.sql +32 -0
  296. package/scripts/social-analytics/db/social-analytics.db +0 -0
  297. package/scripts/social-analytics/digest.js +256 -0
  298. package/scripts/social-analytics/generate-instagram-card.js +97 -0
  299. package/scripts/social-analytics/instagram-thumbgate-post.js +107 -0
  300. package/scripts/social-analytics/load-env.js +46 -0
  301. package/scripts/social-analytics/mcp-server.js +289 -0
  302. package/scripts/social-analytics/normalizer.js +580 -0
  303. package/scripts/social-analytics/notify.js +162 -0
  304. package/scripts/social-analytics/poll-all.js +92 -0
  305. package/scripts/social-analytics/pollers/github.js +195 -0
  306. package/scripts/social-analytics/pollers/instagram.js +253 -0
  307. package/scripts/social-analytics/pollers/linkedin.js +330 -0
  308. package/scripts/social-analytics/pollers/plausible.js +247 -0
  309. package/scripts/social-analytics/pollers/reddit.js +306 -0
  310. package/scripts/social-analytics/pollers/threads.js +233 -0
  311. package/scripts/social-analytics/pollers/tiktok.js +203 -0
  312. package/scripts/social-analytics/pollers/x.js +227 -0
  313. package/scripts/social-analytics/pollers/youtube.js +304 -0
  314. package/scripts/social-analytics/pollers/zernio.js +183 -0
  315. package/scripts/social-analytics/publish-instagram-thumbgate.js +98 -0
  316. package/scripts/social-analytics/publish-thumbgate-launch.js +316 -0
  317. package/scripts/social-analytics/publishers/devto.js +122 -0
  318. package/scripts/social-analytics/publishers/instagram.js +317 -0
  319. package/scripts/social-analytics/publishers/linkedin.js +294 -0
  320. package/scripts/social-analytics/publishers/reddit.js +390 -0
  321. package/scripts/social-analytics/publishers/threads.js +275 -0
  322. package/scripts/social-analytics/publishers/tiktok.js +217 -0
  323. package/scripts/social-analytics/publishers/x.js +259 -0
  324. package/scripts/social-analytics/publishers/youtube.js +223 -0
  325. package/scripts/social-analytics/publishers/zernio.js +378 -0
  326. package/scripts/social-analytics/run-digest.js +34 -0
  327. package/scripts/social-analytics/store.js +257 -0
  328. package/scripts/social-analytics/utm.js +143 -0
  329. package/scripts/social-pipeline.js +2628 -0
  330. package/scripts/social-quality-gate.js +18 -0
  331. package/scripts/social-reply-monitor.js +445 -0
  332. package/scripts/status-dashboard.js +155 -0
  333. package/scripts/statusline-lesson.js +16 -0
  334. package/scripts/statusline-tower.js +8 -0
  335. package/scripts/statusline.sh +116 -0
  336. package/scripts/stripe-live-status.js +115 -0
  337. package/scripts/subagent-profiles.js +79 -0
  338. package/scripts/sync-gh-secrets-from-env.sh +70 -0
  339. package/scripts/sync-github-about.js +52 -0
  340. package/scripts/sync-version.js +447 -0
  341. package/scripts/synthetic-dpo.js +234 -0
  342. package/scripts/telemetry-analytics.js +821 -0
  343. package/scripts/tessl-export.js +371 -0
  344. package/scripts/test-coverage.js +120 -0
  345. package/scripts/thompson-sampling.js +417 -0
  346. package/scripts/thumbgate-search.js +189 -0
  347. package/scripts/tool-kpi-tracker.js +12 -0
  348. package/scripts/tool-registry.js +811 -0
  349. package/scripts/train_from_feedback.py +933 -0
  350. package/scripts/user-profile.js +78 -0
  351. package/scripts/validate-feedback.js +581 -0
  352. package/scripts/validate-workflow-contract.js +287 -0
  353. package/scripts/vector-store.js +197 -0
  354. package/scripts/verification-loop.js +291 -0
  355. package/scripts/verify-obsidian-setup.sh +269 -0
  356. package/scripts/verify-run.js +269 -0
  357. package/scripts/webhook-delivery.js +62 -0
  358. package/scripts/weekly-auto-post.js +124 -0
  359. package/scripts/workflow-runs.js +154 -0
  360. package/scripts/workflow-sprint-intake.js +475 -0
  361. package/scripts/workspace-evolver.js +374 -0
  362. package/scripts/x-autonomous-marketing.js +139 -0
  363. package/scripts/xmemory-lite.js +405 -0
  364. package/skills/agent-memory/SKILL.md +97 -0
  365. package/skills/rlhf-feedback/SKILL.md +49 -0
  366. package/skills/solve-architecture-autonomy/SKILL.md +17 -0
  367. package/skills/solve-architecture-autonomy/tool.js +33 -0
  368. package/skills/thumbgate/SKILL.md +114 -0
  369. package/src/api/server.js +4206 -0
@@ -0,0 +1,322 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Congruence checker โ€” ensures branding, tech stack, and version are
4
+ * consistent across all public-facing materials.
5
+ *
6
+ * Runs in CI on every PR. Fails if any surface is out of sync.
7
+ */
8
+ 'use strict';
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const {
13
+ collectLocalGitHubAboutErrors,
14
+ compareGitHubAbout,
15
+ fetchLiveGitHubAbout,
16
+ loadGitHubAboutConfig,
17
+ } = require('./github-about');
18
+ const {
19
+ PRODUCTHUNT_URL,
20
+ getClaudePluginLatestDownloadUrl,
21
+ } = require('./distribution-surfaces');
22
+
23
+ const ROOT = path.join(__dirname, '..');
24
+
25
+ function read(rel) {
26
+ const full = path.join(ROOT, rel);
27
+ if (!fs.existsSync(full)) return null;
28
+ return fs.readFileSync(full, 'utf-8');
29
+ }
30
+
31
+ async function main() {
32
+ const errors = [];
33
+ const githubAbout = loadGitHubAboutConfig(ROOT);
34
+
35
+ function check(condition, message) {
36
+ if (!condition) errors.push(message);
37
+ }
38
+
39
+ const checkLiveGitHubAbout = process.argv.includes('--check-live');
40
+
41
+ // --- Version congruence ---
42
+ const pkg = JSON.parse(read('package.json'));
43
+ const version = pkg.version;
44
+
45
+ const landingHtml = read('public/index.html') || '';
46
+ const guideHtml = read('public/guide.html') || '';
47
+ const readmeMd = read('README.md') || '';
48
+ const commercialTruth = read('docs/COMMERCIAL_TRUTH.md') || '';
49
+ const agentsMd = read('AGENTS.md') || '';
50
+ const claudeMd = read('CLAUDE.md') || '';
51
+ const geminiMd = read('GEMINI.md') || '';
52
+ const serverStdio = read('adapters/mcp/server-stdio.js') || '';
53
+ const productHuntKit = read('docs/marketing/product-hunt-launch.md') || '';
54
+ const claudePluginReadme = read('.claude-plugin/README.md') || '';
55
+ const claudeDesktopPacket = read('docs/CLAUDE_DESKTOP_EXTENSION.md') || '';
56
+ const latestClaudePluginUrl = getClaudePluginLatestDownloadUrl(ROOT);
57
+
58
+ check(
59
+ landingHtml.includes(`v${version}`),
60
+ `public/index.html missing version v${version} (found in package.json)`
61
+ );
62
+
63
+ check(
64
+ serverStdio.includes(`version: '${version}'`),
65
+ `adapters/mcp/server-stdio.js missing version '${version}'`
66
+ );
67
+
68
+ // --- Brand congruence: "ThumbGate" must appear in all public surfaces ---
69
+ const brandSurfaces = {
70
+ 'public/index.html (nav)': landingHtml.includes('ThumbGate</a>'),
71
+ 'public/index.html (title)': landingHtml.includes('<title>ThumbGate'),
72
+ 'README.md (heading)': readmeMd.startsWith('# ThumbGate'),
73
+ 'package.json (description)': pkg.description.includes('ThumbGate'),
74
+ 'AGENTS.md': agentsMd.includes('ThumbGate'),
75
+ 'CLAUDE.md': claudeMd.includes('ThumbGate'),
76
+ 'GEMINI.md': geminiMd.includes('ThumbGate'),
77
+ };
78
+
79
+ for (const [surface, present] of Object.entries(brandSurfaces)) {
80
+ check(present, `Brand "ThumbGate" missing from ${surface}`);
81
+ }
82
+
83
+ // --- Tech stack congruence: key terms must appear in both README and landing page ---
84
+ const techTerms = [
85
+ 'SQLite',
86
+ 'FTS5',
87
+ 'MemAlign',
88
+ 'Thompson Sampling',
89
+ 'LanceDB',
90
+ 'PreToolUse',
91
+ ];
92
+
93
+ for (const term of techTerms) {
94
+ check(
95
+ readmeMd.includes(term),
96
+ `Tech term "${term}" missing from README.md`
97
+ );
98
+ check(
99
+ landingHtml.includes(term),
100
+ `Tech term "${term}" missing from public/index.html`
101
+ );
102
+ }
103
+
104
+ // --- SEO positioning terms must appear on landing page ---
105
+ const seoTerms = ['human-in-the-loop', 'vibe coding'];
106
+ for (const term of seoTerms) {
107
+ check(
108
+ landingHtml.toLowerCase().includes(term.toLowerCase()),
109
+ `SEO term "${term}" missing from public/index.html`
110
+ );
111
+ }
112
+
113
+ // --- FAQPage schema must exist for rich results ---
114
+ check(
115
+ landingHtml.includes('"@type": "FAQPage"'),
116
+ 'public/index.html missing FAQPage JSON-LD schema (needed for Google rich results)'
117
+ );
118
+
119
+ // --- Honest disclaimer must be on both surfaces ---
120
+ check(
121
+ readmeMd.includes('does not update model weights'),
122
+ 'README.md missing honest disclaimer ("does not update model weights")'
123
+ );
124
+ check(
125
+ !/<<<<<<<|=======|>>>>>>>/.test(readmeMd),
126
+ 'README.md contains unresolved merge conflict markers'
127
+ );
128
+ check(
129
+ landingHtml.includes('doesn\'t touch the model') || landingHtml.includes('different from RLHF-the-concept'),
130
+ 'public/index.html missing honest disclaimer (FAQ or inline)'
131
+ );
132
+ check(
133
+ /\$19\/mo/i.test(landingHtml) && /\$149\/yr/i.test(landingHtml),
134
+ 'public/index.html must advertise the current Pro monthly and annual pricing'
135
+ );
136
+ check(
137
+ /\$19\/mo/i.test(guideHtml) && /\$149\/yr/i.test(guideHtml),
138
+ 'public/guide.html must advertise the current Pro monthly and annual pricing'
139
+ );
140
+ check(
141
+ /\$12\/seat\/mo/i.test(guideHtml),
142
+ 'public/guide.html must advertise the current Team pricing anchor'
143
+ );
144
+ check(
145
+ /Pro at \$19\/mo or \$149\/yr/i.test(commercialTruth),
146
+ 'docs/COMMERCIAL_TRUTH.md must record the current Pro offer'
147
+ );
148
+ check(
149
+ /shared lessons and org visibility/i.test(githubAbout.description),
150
+ 'config/github-about.json description must mention shared lessons and org visibility'
151
+ );
152
+ check(
153
+ /\$19\/mo or \$149\/yr/i.test(readmeMd),
154
+ 'README.md must advertise the current Pro monthly and annual pricing'
155
+ );
156
+ check(
157
+ /\$12\/seat\/mo/i.test(readmeMd),
158
+ 'README.md must advertise the current Team pricing anchor'
159
+ );
160
+ check(
161
+ /shared hosted lesson db/i.test(readmeMd),
162
+ 'README.md must describe the shared hosted Team lesson database'
163
+ );
164
+ check(
165
+ /org dashboard/i.test(readmeMd),
166
+ 'README.md must describe the Team org dashboard'
167
+ );
168
+ check(
169
+ /history-aware/i.test(readmeMd),
170
+ 'README.md must mention history-aware lesson distillation'
171
+ );
172
+ check(
173
+ /feedback session|open_feedback_session|append_feedback_context|finalize_feedback_session/i.test(readmeMd),
174
+ 'README.md must mention the linked feedback session flow'
175
+ );
176
+ check(
177
+ !/unlimited captures/i.test(readmeMd),
178
+ 'README.md must not claim unlimited free-tier feedback captures'
179
+ );
180
+ check(
181
+ !/shared team db/i.test(readmeMd),
182
+ 'README.md must not claim Pro includes a shared team DB'
183
+ );
184
+ check(
185
+ !/\/mo\$19/i.test(readmeMd),
186
+ 'README.md must not contain malformed duplicated Pro pricing'
187
+ );
188
+ check(
189
+ !/\/mo\$19/i.test(guideHtml),
190
+ 'public/guide.html must not contain malformed duplicated Pro pricing'
191
+ );
192
+
193
+ check(
194
+ landingHtml.includes('๐Ÿ‘'),
195
+ 'public/index.html must visibly include the thumbs-up icon'
196
+ );
197
+ check(
198
+ landingHtml.includes('๐Ÿ‘Ž'),
199
+ 'public/index.html must visibly include the thumbs-down icon'
200
+ );
201
+ check(
202
+ /workflow-sprint-intake/.test(landingHtml),
203
+ 'public/index.html must expose the team workflow intake path'
204
+ );
205
+ check(
206
+ /shared lesson db|shared lesson database/i.test(landingHtml),
207
+ 'public/index.html must describe the shared Team lesson database'
208
+ );
209
+ check(
210
+ /org dashboard/i.test(landingHtml),
211
+ 'public/index.html must describe the Team org dashboard'
212
+ );
213
+ check(
214
+ /personal local dashboard/i.test(landingHtml),
215
+ 'public/index.html must keep the personal Pro dashboard message'
216
+ );
217
+ check(
218
+ /history-aware/i.test(landingHtml),
219
+ 'public/index.html must mention history-aware lesson distillation'
220
+ );
221
+ check(
222
+ /feedback session/i.test(landingHtml),
223
+ 'public/index.html must mention the linked feedback session flow'
224
+ );
225
+ check(
226
+ /unlimited feedback captures/i.test(landingHtml) && /5 lesson searches\/day/i.test(landingHtml),
227
+ 'public/index.html must advertise the truthful free-tier capture and lesson-search limits'
228
+ );
229
+ check(
230
+ /5 auto-promoted gates/i.test(landingHtml),
231
+ 'public/index.html must advertise the truthful free-tier auto-promoted gate limit'
232
+ );
233
+ check(
234
+ landingHtml.includes(PRODUCTHUNT_URL),
235
+ 'public/index.html must link to the live Product Hunt listing'
236
+ );
237
+ check(
238
+ /Claude Desktop plugin/i.test(landingHtml),
239
+ 'public/index.html must promote the Claude Desktop plugin install lane'
240
+ );
241
+ check(
242
+ /thumbs[\s-]?up/i.test(landingHtml),
243
+ 'public/index.html must explain the thumbs-up feedback path'
244
+ );
245
+ check(
246
+ /thumbs[\s-]?down/i.test(landingHtml),
247
+ 'public/index.html must explain the thumbs-down feedback path'
248
+ );
249
+ check(
250
+ githubAbout.description.includes('๐Ÿ‘'),
251
+ 'config/github-about.json description must include the thumbs-up icon'
252
+ );
253
+ check(
254
+ githubAbout.description.includes('๐Ÿ‘Ž'),
255
+ 'config/github-about.json description must include the thumbs-down icon'
256
+ );
257
+ check(
258
+ /thumbs[\s-]?up/i.test(githubAbout.description),
259
+ 'config/github-about.json description must mention thumbs-up feedback'
260
+ );
261
+ check(
262
+ /thumbs[\s-]?down/i.test(githubAbout.description),
263
+ 'config/github-about.json description must mention thumbs-down feedback'
264
+ );
265
+ check(
266
+ /history-aware lessons/i.test(githubAbout.description),
267
+ 'config/github-about.json description must mention history-aware lessons'
268
+ );
269
+ check(
270
+ productHuntKit.includes(PRODUCTHUNT_URL),
271
+ 'docs/marketing/product-hunt-launch.md must include the live Product Hunt URL'
272
+ );
273
+ check(
274
+ /thumbs[\s-]?up|๐Ÿ‘/i.test(productHuntKit),
275
+ 'docs/marketing/product-hunt-launch.md must mention the thumbs-up path'
276
+ );
277
+ check(
278
+ /thumbs[\s-]?down|๐Ÿ‘Ž/i.test(productHuntKit),
279
+ 'docs/marketing/product-hunt-launch.md must mention the thumbs-down path'
280
+ );
281
+ check(
282
+ productHuntKit.includes(latestClaudePluginUrl),
283
+ 'docs/marketing/product-hunt-launch.md must link to the Claude plugin bundle'
284
+ );
285
+ check(
286
+ claudePluginReadme.includes(latestClaudePluginUrl),
287
+ '.claude-plugin/README.md must link to the latest Claude plugin bundle'
288
+ );
289
+ check(
290
+ claudeDesktopPacket.includes(latestClaudePluginUrl),
291
+ 'docs/CLAUDE_DESKTOP_EXTENSION.md must link to the latest Claude plugin bundle'
292
+ );
293
+
294
+ errors.push(...collectLocalGitHubAboutErrors(ROOT));
295
+
296
+ if (checkLiveGitHubAbout) {
297
+ try {
298
+ const liveAbout = await fetchLiveGitHubAbout({ root: ROOT, repo: githubAbout.repo });
299
+ errors.push(...compareGitHubAbout(githubAbout, liveAbout, `Live GitHub About (${githubAbout.repo})`));
300
+ } catch (error) {
301
+ errors.push(`Unable to verify live GitHub About: ${error.message}`);
302
+ }
303
+ }
304
+
305
+ if (errors.length > 0) {
306
+ console.error(`\nโŒ Congruence check FAILED โ€” ${errors.length} issue(s):\n`);
307
+ for (const error of errors) {
308
+ console.error(` โ€ข ${error}`);
309
+ }
310
+ console.error('');
311
+ process.exit(1);
312
+ }
313
+
314
+ console.log(
315
+ `โœ… Congruence check passed โ€” version v${version}, brand "ThumbGate", ${techTerms.length} tech terms verified across repo surfaces, GitHub About source-of-truth verified${checkLiveGitHubAbout ? ', and live GitHub metadata verified' : ''}.`
316
+ );
317
+ }
318
+
319
+ main().catch((error) => {
320
+ console.error(`\nโŒ Congruence check FAILED โ€” ${error.message}\n`);
321
+ process.exit(1);
322
+ });
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * CLI Feedback โ€” inline thumbs up/down for the terminal.
6
+ *
7
+ * Instead of opening a browser, this echoes the lesson and process info
8
+ * directly to stdout. Designed to be triggered from the Claude Code
9
+ * statusbar or typed as a command.
10
+ *
11
+ * Usage:
12
+ * node scripts/cli-feedback.js up "what worked"
13
+ * node scripts/cli-feedback.js down "what went wrong"
14
+ */
15
+
16
+ const { captureFeedback } = require('./feedback-loop');
17
+ const { distillFromHistory } = require('./history-distiller');
18
+ const { getRecentLesson, getLessonStats } = require('./lesson-inference');
19
+
20
+ const G = '\x1b[32m';
21
+ const R = '\x1b[31m';
22
+ const C = '\x1b[36m';
23
+ const M = '\x1b[35m';
24
+ const D = '\x1b[90m';
25
+ const BD = '\x1b[1m';
26
+ const RST = '\x1b[0m';
27
+
28
+ /**
29
+ * Process a thumbs up/down signal from the CLI.
30
+ * Captures feedback, distills a lesson, and prints everything inline.
31
+ *
32
+ * @param {Object} opts
33
+ * @param {string} opts.signal - 'up' or 'down'
34
+ * @param {string} [opts.context] - What happened
35
+ * @param {Array} [opts.chatHistory] - Conversation messages for distillation
36
+ * @param {string} [opts.whatWentWrong] - For thumbs down
37
+ * @param {string} [opts.whatWorked] - For thumbs up
38
+ * @returns {Object} Result with feedback + lesson + stats
39
+ */
40
+ function processInlineFeedback({ signal, context, chatHistory, whatWentWrong, whatWorked } = {}) {
41
+ const isDown = signal === 'down' || signal === 'negative';
42
+
43
+ // 1. Capture the feedback
44
+ let feedbackResult;
45
+ try {
46
+ feedbackResult = captureFeedback({
47
+ signal: isDown ? 'down' : 'up',
48
+ context: context || (isDown ? 'Thumbs down from CLI' : 'Thumbs up from CLI'),
49
+ whatWentWrong: whatWentWrong || undefined,
50
+ whatWorked: whatWorked || undefined,
51
+ });
52
+ } catch (err) {
53
+ feedbackResult = { accepted: false, reason: err.message };
54
+ }
55
+
56
+ // 2. If thumbs down + chat history, distill a lesson
57
+ let distillResult = null;
58
+ if (isDown && Array.isArray(chatHistory) && chatHistory.length > 0) {
59
+ try {
60
+ distillResult = distillFromHistory({ chatHistory, signal: 'negative', feedbackContext: context || '' });
61
+ } catch { /* non-critical */ }
62
+ }
63
+
64
+ // 3. Get the most recent lesson and stats
65
+ const recentLesson = getRecentLesson();
66
+ const stats = getLessonStats();
67
+
68
+ return { feedbackResult, distillResult, recentLesson, stats };
69
+ }
70
+
71
+ /**
72
+ * Format the result for terminal output.
73
+ */
74
+ function formatCliOutput(result) {
75
+ const lines = [];
76
+ const isDown = result.feedbackResult && result.feedbackResult.signal === 'negative';
77
+
78
+ // Header
79
+ if (result.feedbackResult && result.feedbackResult.accepted !== false) {
80
+ lines.push(`${isDown ? R : G}${BD}${isDown ? '๐Ÿ‘Ž Thumbs down recorded' : '๐Ÿ‘ Thumbs up recorded'}${RST}`);
81
+ if (result.feedbackResult.id) {
82
+ lines.push(`${D} ID: ${result.feedbackResult.id}${RST}`);
83
+ }
84
+ } else {
85
+ lines.push(`${R}Feedback not accepted: ${(result.feedbackResult && result.feedbackResult.reason) || 'unknown'}${RST}`);
86
+ }
87
+
88
+ // Distilled lesson (if thumbs down)
89
+ if (result.distillResult) {
90
+ lines.push('');
91
+ lines.push(`${C}${BD}Lesson distilled:${RST}`);
92
+ lines.push(`${C} ${result.distillResult.proposedWhatWentWrong}${RST}`);
93
+ if (result.distillResult.proposedRule) {
94
+ lines.push(`${M} Rule: ${result.distillResult.proposedRule}${RST}`);
95
+ lines.push(`${D} ${result.distillResult.ruleInstalled ? 'โœ… Auto-installed' : 'โš  Not auto-installed (low confidence)'}${RST}`);
96
+ }
97
+ if (result.distillResult.confirmation) {
98
+ lines.push(`${D} ${result.distillResult.confirmation}${RST}`);
99
+ }
100
+ }
101
+
102
+ // Most recent lesson
103
+ if (result.recentLesson) {
104
+ lines.push('');
105
+ lines.push(`${D}Most recent lesson:${RST}`);
106
+ lines.push(`${D} ${result.recentLesson.lesson}${RST}`);
107
+ lines.push(`${D} Link: ${result.recentLesson.link}${RST}`);
108
+ }
109
+
110
+ // Stats
111
+ if (result.stats && result.stats.total > 0) {
112
+ lines.push('');
113
+ lines.push(`${D}Stats: ${result.stats.positive}๐Ÿ‘ ${result.stats.negative}๐Ÿ‘Ž ยท ${result.stats.total} lessons ยท ${result.stats.avgConfidence}% avg confidence${RST}`);
114
+ }
115
+
116
+ return lines.join('\n');
117
+ }
118
+
119
+ // CLI entry point
120
+ if (require.main === module) {
121
+ const args = process.argv.slice(2);
122
+ const signal = args[0] || 'up';
123
+ const context = args.slice(1).join(' ') || '';
124
+
125
+ const result = processInlineFeedback({
126
+ signal,
127
+ context,
128
+ whatWentWrong: signal === 'down' ? context : undefined,
129
+ whatWorked: signal === 'up' ? context : undefined,
130
+ });
131
+
132
+ process.stdout.write(formatCliOutput(result) + '\n');
133
+ }
134
+
135
+ module.exports = { processInlineFeedback, formatCliOutput };
@@ -0,0 +1,87 @@
1
+ 'use strict';
2
+ const https = require('https');
3
+ const os = require('os');
4
+ const crypto = require('crypto');
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+
8
+ const TELEMETRY_ENDPOINT = 'https://thumbgate-production.up.railway.app/v1/telemetry/ping';
9
+ const INSTALL_ID_PATH = path.join(process.env.HOME || process.env.USERPROFILE || '.', '.thumbgate', 'install-id');
10
+
11
+ /**
12
+ * Get or create a stable anonymous install ID.
13
+ * This is NOT tied to any personal info โ€” it's a random UUID stored locally.
14
+ */
15
+ function getInstallId() {
16
+ try {
17
+ if (fs.existsSync(INSTALL_ID_PATH)) {
18
+ return fs.readFileSync(INSTALL_ID_PATH, 'utf8').trim();
19
+ }
20
+ } catch (_) {}
21
+
22
+ const id = crypto.randomUUID ? crypto.randomUUID() : crypto.randomBytes(16).toString('hex');
23
+ try {
24
+ const dir = path.dirname(INSTALL_ID_PATH);
25
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
26
+ fs.writeFileSync(INSTALL_ID_PATH, id);
27
+ } catch (_) {}
28
+ return id;
29
+ }
30
+
31
+ /**
32
+ * Classify this install: is it Igor, CI, or a real user?
33
+ */
34
+ function classifyInstall() {
35
+ const env = process.env;
36
+
37
+ // CI detection
38
+ if (env.CI || env.GITHUB_ACTIONS || env.TRAVIS || env.CIRCLECI || env.JENKINS_URL || env.GITLAB_CI || env.CODEBUILD_BUILD_ID) {
39
+ return 'ci';
40
+ }
41
+
42
+ // Igor detection (by known machine identifiers)
43
+ const hostname = os.hostname().toLowerCase();
44
+ const user = (env.USER || env.USERNAME || '').toLowerCase();
45
+ if (user.includes('igor') || user.includes('igorganapolsky') || hostname.includes('igors')) {
46
+ return 'owner';
47
+ }
48
+
49
+ return 'real_user';
50
+ }
51
+
52
+ /**
53
+ * Send anonymous telemetry ping. Fire-and-forget, never blocks CLI.
54
+ * Respects THUMBGATE_NO_TELEMETRY=1 opt-out.
55
+ */
56
+ function trackEvent(eventType, metadata = {}) {
57
+ if (process.env.THUMBGATE_NO_TELEMETRY === '1' || process.env.DO_NOT_TRACK === '1') return;
58
+
59
+ const payload = JSON.stringify({
60
+ eventType,
61
+ installId: getInstallId(),
62
+ visitorType: classifyInstall(),
63
+ platform: os.platform(),
64
+ arch: os.arch(),
65
+ nodeVersion: process.version,
66
+ pkgVersion: (() => { try { return require('../package.json').version; } catch(_) { return 'unknown'; } })(),
67
+ timestamp: new Date().toISOString(),
68
+ ...metadata,
69
+ });
70
+
71
+ try {
72
+ const url = new URL(TELEMETRY_ENDPOINT);
73
+ const req = https.request({
74
+ hostname: url.hostname,
75
+ port: 443,
76
+ path: url.pathname,
77
+ method: 'POST',
78
+ headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) },
79
+ timeout: 3000,
80
+ });
81
+ req.on('error', () => {}); // silently ignore
82
+ req.on('timeout', () => req.destroy());
83
+ req.end(payload);
84
+ } catch (_) {} // never crash the CLI
85
+ }
86
+
87
+ module.exports = { trackEvent, getInstallId, classifyInstall, INSTALL_ID_PATH };