thumbgate 0.9.10

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 (364) 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/thumbgate-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 +1484 -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 +283 -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 +1014 -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-312.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 +299 -0
  117. package/scripts/auto-wire-hooks.js +312 -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 +97 -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 +263 -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 +209 -0
  152. package/scripts/ephemeral-agent-store.js +219 -0
  153. package/scripts/eval-harness.js +56 -0
  154. package/scripts/evolution-state.js +241 -0
  155. package/scripts/experiment-tracker.js +267 -0
  156. package/scripts/export-databricks-bundle.js +242 -0
  157. package/scripts/export-dpo-pairs.js +345 -0
  158. package/scripts/export-kto-pairs.js +310 -0
  159. package/scripts/export-training.js +448 -0
  160. package/scripts/failure-diagnostics.js +558 -0
  161. package/scripts/feedback-attribution.js +313 -0
  162. package/scripts/feedback-fallback.js +111 -0
  163. package/scripts/feedback-history-distiller.js +391 -0
  164. package/scripts/feedback-inbox-read.js +162 -0
  165. package/scripts/feedback-loop.js +1887 -0
  166. package/scripts/feedback-paths.js +145 -0
  167. package/scripts/feedback-quality.js +139 -0
  168. package/scripts/feedback-root-consolidator.js +238 -0
  169. package/scripts/feedback-schema.js +426 -0
  170. package/scripts/feedback-session.js +286 -0
  171. package/scripts/feedback-to-memory.js +185 -0
  172. package/scripts/feedback-to-rules.js +163 -0
  173. package/scripts/filesystem-search.js +404 -0
  174. package/scripts/funnel-analytics.js +35 -0
  175. package/scripts/gate-satisfy.js +42 -0
  176. package/scripts/gate-stats.js +116 -0
  177. package/scripts/gate-templates.js +70 -0
  178. package/scripts/gates-engine.js +816 -0
  179. package/scripts/generate-paperbanana-diagrams.sh +99 -0
  180. package/scripts/generate-pretool-hook.sh +40 -0
  181. package/scripts/github-about.js +350 -0
  182. package/scripts/github-outreach.js +65 -0
  183. package/scripts/gtm-revenue-loop.js +520 -0
  184. package/scripts/hallucination-detector.js +226 -0
  185. package/scripts/hf-papers.js +317 -0
  186. package/scripts/history-distiller.js +200 -0
  187. package/scripts/hook-auto-capture.sh +95 -0
  188. package/scripts/hook-stop-pr-thread-check.sh +68 -0
  189. package/scripts/hook-stop-self-score.sh +51 -0
  190. package/scripts/hook-stop-verify-deploy.sh +31 -0
  191. package/scripts/hook-thumbgate-cache-updater.js +48 -0
  192. package/scripts/hook-verify-before-done.sh +20 -0
  193. package/scripts/hosted-config.js +170 -0
  194. package/scripts/hybrid-feedback-context.js +676 -0
  195. package/scripts/install-mcp.js +159 -0
  196. package/scripts/intent-router.js +392 -0
  197. package/scripts/internal-agent-bootstrap.js +490 -0
  198. package/scripts/jsonl-watcher.js +155 -0
  199. package/scripts/lesson-db.js +613 -0
  200. package/scripts/lesson-inference.js +315 -0
  201. package/scripts/lesson-retrieval.js +95 -0
  202. package/scripts/lesson-rotation.js +137 -0
  203. package/scripts/lesson-search.js +644 -0
  204. package/scripts/lesson-synthesis.js +196 -0
  205. package/scripts/license.js +50 -0
  206. package/scripts/local-model-profile.js +383 -0
  207. package/scripts/markdown-escape.js +12 -0
  208. package/scripts/marketing-experiment.js +671 -0
  209. package/scripts/mcp-config.js +149 -0
  210. package/scripts/mcp-policy.js +99 -0
  211. package/scripts/memalign-recall.js +111 -0
  212. package/scripts/memory-firewall.js +222 -0
  213. package/scripts/memory-migration.js +296 -0
  214. package/scripts/meta-policy.js +194 -0
  215. package/scripts/metered-billing.js +16 -0
  216. package/scripts/model-tier-router.js +301 -0
  217. package/scripts/money-watcher.js +71 -0
  218. package/scripts/multi-hop-recall.js +240 -0
  219. package/scripts/natural-language-harness.js +330 -0
  220. package/scripts/obsidian-export.js +712 -0
  221. package/scripts/operational-dashboard.js +103 -0
  222. package/scripts/operational-summary.js +93 -0
  223. package/scripts/optimize-context.js +17 -0
  224. package/scripts/org-dashboard.js +201 -0
  225. package/scripts/partner-orchestration.js +146 -0
  226. package/scripts/per-step-scoring.js +165 -0
  227. package/scripts/perplexity-marketing.js +466 -0
  228. package/scripts/pii-scanner.js +153 -0
  229. package/scripts/plan-gate.js +154 -0
  230. package/scripts/post-everywhere.js +308 -0
  231. package/scripts/post-to-x-retry.sh +22 -0
  232. package/scripts/post-to-x.js +369 -0
  233. package/scripts/pr-manager.js +236 -0
  234. package/scripts/predictive-insights.js +356 -0
  235. package/scripts/principle-extractor.js +162 -0
  236. package/scripts/pro-features.js +40 -0
  237. package/scripts/pro-local-dashboard.js +174 -0
  238. package/scripts/problem-detail.js +53 -0
  239. package/scripts/product-feedback.js +134 -0
  240. package/scripts/profile-router.js +245 -0
  241. package/scripts/prompt-dlp.js +221 -0
  242. package/scripts/prompt-guard.js +83 -0
  243. package/scripts/prove-adapters.js +863 -0
  244. package/scripts/prove-attribution.js +365 -0
  245. package/scripts/prove-automation.js +653 -0
  246. package/scripts/prove-autoresearch.js +304 -0
  247. package/scripts/prove-claim-verification.js +277 -0
  248. package/scripts/prove-cloudflare-sandbox.js +163 -0
  249. package/scripts/prove-data-pipeline.js +410 -0
  250. package/scripts/prove-data-quality.js +227 -0
  251. package/scripts/prove-evolution.js +352 -0
  252. package/scripts/prove-harnesses.js +287 -0
  253. package/scripts/prove-intelligence.js +259 -0
  254. package/scripts/prove-lancedb.js +371 -0
  255. package/scripts/prove-local-intelligence.js +342 -0
  256. package/scripts/prove-loop-closure.js +263 -0
  257. package/scripts/prove-predictive-insights.js +357 -0
  258. package/scripts/prove-runtime.js +350 -0
  259. package/scripts/prove-seo-gsd.js +234 -0
  260. package/scripts/prove-settings.js +279 -0
  261. package/scripts/prove-subway-upgrades.js +277 -0
  262. package/scripts/prove-tessl.js +229 -0
  263. package/scripts/prove-training-export.js +327 -0
  264. package/scripts/prove-workflow-contract.js +116 -0
  265. package/scripts/prove-xmemory.js +332 -0
  266. package/scripts/publish-decision.js +133 -0
  267. package/scripts/pulse.js +80 -0
  268. package/scripts/rate-limiter.js +125 -0
  269. package/scripts/reddit-dm-outreach.js +182 -0
  270. package/scripts/reddit-monitor-cron.sh +26 -0
  271. package/scripts/reflector-agent.js +221 -0
  272. package/scripts/reminder-engine.js +132 -0
  273. package/scripts/revenue-status.js +472 -0
  274. package/scripts/risk-scorer.js +458 -0
  275. package/scripts/rlaif-self-audit.js +129 -0
  276. package/scripts/rubric-engine.js +230 -0
  277. package/scripts/schedule-manager.js +251 -0
  278. package/scripts/secret-scanner.js +414 -0
  279. package/scripts/self-heal.js +147 -0
  280. package/scripts/self-healing-check.js +188 -0
  281. package/scripts/semantic-layer.js +98 -0
  282. package/scripts/seo-gsd.js +1153 -0
  283. package/scripts/settings-hierarchy.js +214 -0
  284. package/scripts/shieldcortex-memory-firewall-runner.mjs +53 -0
  285. package/scripts/skill-exporter.js +262 -0
  286. package/scripts/skill-generator.js +446 -0
  287. package/scripts/skill-materializer.js +134 -0
  288. package/scripts/skill-packs.js +136 -0
  289. package/scripts/skill-proposer.js +99 -0
  290. package/scripts/skill-quality-tracker.js +284 -0
  291. package/scripts/slo-alert-engine.js +14 -0
  292. package/scripts/slow-loop.js +72 -0
  293. package/scripts/social-analytics/db/schema.sql +32 -0
  294. package/scripts/social-analytics/digest.js +256 -0
  295. package/scripts/social-analytics/generate-instagram-card.js +97 -0
  296. package/scripts/social-analytics/instagram-thumbgate-post.js +73 -0
  297. package/scripts/social-analytics/mcp-server.js +289 -0
  298. package/scripts/social-analytics/normalizer.js +580 -0
  299. package/scripts/social-analytics/notify.js +162 -0
  300. package/scripts/social-analytics/poll-all.js +107 -0
  301. package/scripts/social-analytics/pollers/github.js +195 -0
  302. package/scripts/social-analytics/pollers/instagram.js +253 -0
  303. package/scripts/social-analytics/pollers/linkedin.js +330 -0
  304. package/scripts/social-analytics/pollers/plausible.js +247 -0
  305. package/scripts/social-analytics/pollers/reddit.js +306 -0
  306. package/scripts/social-analytics/pollers/threads.js +233 -0
  307. package/scripts/social-analytics/pollers/tiktok.js +203 -0
  308. package/scripts/social-analytics/pollers/x.js +227 -0
  309. package/scripts/social-analytics/pollers/youtube.js +304 -0
  310. package/scripts/social-analytics/pollers/zernio.js +180 -0
  311. package/scripts/social-analytics/publish-instagram-thumbgate.js +85 -0
  312. package/scripts/social-analytics/publishers/devto.js +122 -0
  313. package/scripts/social-analytics/publishers/instagram.js +317 -0
  314. package/scripts/social-analytics/publishers/linkedin.js +294 -0
  315. package/scripts/social-analytics/publishers/reddit.js +390 -0
  316. package/scripts/social-analytics/publishers/threads.js +275 -0
  317. package/scripts/social-analytics/publishers/tiktok.js +217 -0
  318. package/scripts/social-analytics/publishers/x.js +259 -0
  319. package/scripts/social-analytics/publishers/youtube.js +223 -0
  320. package/scripts/social-analytics/publishers/zernio.js +209 -0
  321. package/scripts/social-analytics/run-digest.js +34 -0
  322. package/scripts/social-analytics/store.js +257 -0
  323. package/scripts/social-analytics/utm.js +143 -0
  324. package/scripts/social-pipeline.js +2628 -0
  325. package/scripts/social-quality-gate.js +18 -0
  326. package/scripts/social-reply-monitor.js +445 -0
  327. package/scripts/status-dashboard.js +155 -0
  328. package/scripts/statusline-lesson.js +16 -0
  329. package/scripts/statusline-tower.js +8 -0
  330. package/scripts/statusline.sh +116 -0
  331. package/scripts/stripe-live-status.js +115 -0
  332. package/scripts/subagent-profiles.js +79 -0
  333. package/scripts/sync-gh-secrets-from-env.sh +70 -0
  334. package/scripts/sync-github-about.js +52 -0
  335. package/scripts/sync-version.js +451 -0
  336. package/scripts/synthetic-dpo.js +234 -0
  337. package/scripts/telemetry-analytics.js +821 -0
  338. package/scripts/tessl-export.js +371 -0
  339. package/scripts/test-coverage.js +120 -0
  340. package/scripts/thompson-sampling.js +417 -0
  341. package/scripts/thumbgate-search.js +189 -0
  342. package/scripts/tool-kpi-tracker.js +12 -0
  343. package/scripts/tool-registry.js +811 -0
  344. package/scripts/train_from_feedback.py +910 -0
  345. package/scripts/user-profile.js +78 -0
  346. package/scripts/validate-feedback.js +580 -0
  347. package/scripts/validate-workflow-contract.js +287 -0
  348. package/scripts/vector-store.js +198 -0
  349. package/scripts/verification-loop.js +291 -0
  350. package/scripts/verify-obsidian-setup.sh +269 -0
  351. package/scripts/verify-run.js +269 -0
  352. package/scripts/webhook-delivery.js +62 -0
  353. package/scripts/weekly-auto-post.js +124 -0
  354. package/scripts/workflow-runs.js +154 -0
  355. package/scripts/workflow-sprint-intake.js +475 -0
  356. package/scripts/workspace-evolver.js +374 -0
  357. package/scripts/x-autonomous-marketing.js +139 -0
  358. package/scripts/xmemory-lite.js +405 -0
  359. package/skills/agent-memory/SKILL.md +97 -0
  360. package/skills/solve-architecture-autonomy/SKILL.md +17 -0
  361. package/skills/solve-architecture-autonomy/tool.js +33 -0
  362. package/skills/thumbgate/SKILL.md +114 -0
  363. package/skills/thumbgate-feedback/SKILL.md +49 -0
  364. package/src/api/server.js +4208 -0
@@ -0,0 +1,116 @@
1
+ #!/bin/bash
2
+ # ThumbGate Status Line for Claude Code
3
+ # Shows ThumbGate feedback stats + most recent lesson at a glance.
4
+ # Thumbs icons trigger CLI feedback capture inline (no browser).
5
+ # Installed by: npx thumbgate init --agent claude-code
6
+
7
+ # Resolve script directory safely (CodeQL: no uncontrolled paths)
8
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
9
+ case "$SCRIPT_DIR" in *[!a-zA-Z0-9/_.-]*) echo "ThumbGate: invalid script path"; exit 1;; esac
10
+
11
+ # ── Parse Claude Code session JSON from stdin ─────────────────────
12
+ eval "$(cat | jq -r '
13
+ def n(f): f // 0;
14
+ @sh "CTX_PCT=\(n(.context_window.used_percentage) | floor)"
15
+ ' 2>/dev/null)"
16
+ CTX_PCT="${CTX_PCT:-0}"
17
+
18
+ # ── ThumbGate stats from cache ────────────────────────────────────────
19
+ THUMBGATE_CACHE=""
20
+ for base in "${THUMBGATE_FEEDBACK_DIR:-.}" "." "${HOME}"; do
21
+ for rel in ".thumbgate/statusline_cache.json"; do
22
+ if [ -f "${base}/${rel}" ]; then
23
+ THUMBGATE_CACHE="${base}/${rel}"
24
+ break 2
25
+ fi
26
+ done
27
+ done
28
+ if [ -z "$THUMBGATE_CACHE" ]; then
29
+ THUMBGATE_CACHE="${THUMBGATE_FEEDBACK_DIR:-.}/.thumbgate/statusline_cache.json"
30
+ fi
31
+
32
+ UP="0"; DOWN="0"; LESSONS="0"; TREND="?"; CACHE_TS="0"
33
+ if [ -f "$THUMBGATE_CACHE" ]; then
34
+ eval "$(jq -r '
35
+ @sh "UP=\(.thumbs_up // "0")",
36
+ @sh "DOWN=\(.thumbs_down // "0")",
37
+ @sh "LESSONS=\(.lessons // "0")",
38
+ @sh "TREND=\(.trend // "?")",
39
+ @sh "CACHE_TS=\(.updated_at // "0")"
40
+ ' "$THUMBGATE_CACHE" 2>/dev/null)"
41
+ fi
42
+
43
+ # Background refresh from REST API when cache is stale (>120s)
44
+ _NOW=$(date +%s)
45
+ if [ $(( _NOW - ${CACHE_TS:-0} )) -gt 120 ]; then
46
+ (
47
+ _R=$(curl -s --max-time 3 "http://localhost:3456/v1/feedback/stats" -H "Authorization: Bearer ${THUMBGATE_API_KEY:-tg_creator_dev_enterprise}" 2>/dev/null)
48
+ [ -z "$_R" ] && exit 0
49
+ echo "$_R" | python3 -c "
50
+ import json,sys,time,os
51
+ try:
52
+ d=json.load(sys.stdin)
53
+ c={'thumbs_up':str(d.get('totalPositive',0)),'thumbs_down':str(d.get('totalNegative',0)),'lessons':str(d.get('rubric',{}).get('samples',0)),'approval_rate':str(round(d.get('approvalRate',0)*100,1)),'trend':d.get('trend','?'),'total_feedback':str(d.get('total',0)),'updated_at':str(int(time.time()))}
54
+ os.makedirs(os.path.dirname('$THUMBGATE_CACHE'),exist_ok=True)
55
+ json.dump(c,open('$THUMBGATE_CACHE','w'))
56
+ except:pass
57
+ " 2>/dev/null
58
+ ) &>/dev/null &
59
+ disown 2>/dev/null
60
+ fi
61
+
62
+ # ── Most recent lesson from lesson-inference ──────────────────────
63
+ LESSON_TEXT=""; LESSON_ID=""
64
+ _LESSON_JSON=$(node "${SCRIPT_DIR}/statusline-lesson.js" 2>/dev/null)
65
+ if [ -n "$_LESSON_JSON" ]; then
66
+ eval "$(echo "$_LESSON_JSON" | jq -r '
67
+ @sh "LESSON_TEXT=\(.text // "")",
68
+ @sh "LESSON_ID=\(.lessonId // "")"
69
+ ' 2>/dev/null)"
70
+ fi
71
+
72
+ # ── Control Tower stats ──────────────────────────────────────────
73
+ SLO_V="0"; AT_RISK="0"; ANOMALIES="0"
74
+ _TOWER_JSON=$(node "${SCRIPT_DIR}/statusline-tower.js" 2>/dev/null)
75
+ if [ -n "$_TOWER_JSON" ]; then
76
+ eval "$(echo "$_TOWER_JSON" | jq -r '
77
+ @sh "SLO_V=\(.sloViolations // 0)",
78
+ @sh "AT_RISK=\(.atRiskToolCount // 0)",
79
+ @sh "ANOMALIES=\(.anomalyCount // 0)"
80
+ ' 2>/dev/null)"
81
+ fi
82
+
83
+ # ── Colors ────────────────────────────────────────────────────────
84
+ G='\033[32m'; R='\033[31m'; M='\033[35m'; C='\033[36m'; D='\033[90m'; BD='\033[1m'; RST='\033[0m'
85
+
86
+ # Trend arrow
87
+ case "${TREND}" in
88
+ improving) ARROW="↗" ;; degrading) ARROW="↘" ;; stable) ARROW="→" ;; *) ARROW="?" ;;
89
+ esac
90
+
91
+ # ── OSC 8 clickable links ────────────────────────────────────────
92
+ # Links use CLI commands instead of browser URLs.
93
+ # Clicking 👍 runs: node bin/cli.js feedback --signal=up
94
+ # Clicking 👎 runs: node bin/cli.js feedback --signal=down
95
+ osc_link() { printf '\033]8;;%s\a%s\033]8;;\a' "$1" "$2"; }
96
+ CLI="node ${SCRIPT_DIR}/../bin/cli.js"
97
+
98
+ # ── Output (single line) ─────────────────────────────────────────
99
+ if [ "$UP" = "0" ] && [ "$DOWN" = "0" ]; then
100
+ echo -e "${D}ThumbGate: no feedback yet — type 'thumbs up' or 'thumbs down'${RST}"
101
+ else
102
+ # Feedback counts
103
+ LINE="ThumbGate: ${G}${BD}${UP}${RST}👍 ${R}${BD}${DOWN}${RST}👎 · ${M}${BD}${LESSONS}${RST} lessons ${ARROW}"
104
+
105
+ # Control Tower alerts (if any)
106
+ [ "${SLO_V:-0}" -gt 0 ] && LINE="${LINE} ${R}${SLO_V} SLO${RST}"
107
+ [ "${AT_RISK:-0}" -gt 0 ] && LINE="${LINE} ${R}${AT_RISK}⚠${RST}"
108
+ [ "${ANOMALIES:-0}" -gt 0 ] && LINE="${LINE} ${R}${ANOMALIES}☠${RST}"
109
+
110
+ # Most recent lesson
111
+ if [ -n "$LESSON_TEXT" ]; then
112
+ LINE="${LINE} · ${C}${LESSON_TEXT}${RST}"
113
+ fi
114
+
115
+ echo -e "$LINE"
116
+ fi
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * stripe-live-status.js — Pull live financial data from Stripe API.
4
+ * Shows real revenue, not local ledger approximations.
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const Stripe = require('stripe');
10
+
11
+ const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
12
+
13
+ if (!STRIPE_SECRET_KEY) {
14
+ console.error('STRIPE_SECRET_KEY not set');
15
+ process.exit(1);
16
+ }
17
+
18
+ const stripe = new Stripe(STRIPE_SECRET_KEY);
19
+
20
+ async function getLiveStatus() {
21
+ const [balance, charges, subscriptions, products, prices, sessions] = await Promise.all([
22
+ stripe.balance.retrieve(),
23
+ stripe.charges.list({ limit: 100 }),
24
+ stripe.subscriptions.list({ limit: 100, status: 'all' }),
25
+ stripe.products.list({ limit: 20, active: true }),
26
+ stripe.prices.list({ limit: 20, active: true }),
27
+ stripe.checkout.sessions.list({ limit: 50 }),
28
+ ]);
29
+
30
+ const availableBalance = balance.available.reduce((sum, b) => sum + b.amount, 0);
31
+ const pendingBalance = balance.pending.reduce((sum, b) => sum + b.amount, 0);
32
+
33
+ const paidCharges = charges.data.filter(c => c.paid && !c.refunded);
34
+ const refundedCharges = charges.data.filter(c => c.refunded);
35
+ const failedCharges = charges.data.filter(c => c.status === 'failed');
36
+
37
+ const grossRevenue = paidCharges.reduce((sum, c) => sum + c.amount, 0);
38
+ const refundedAmount = refundedCharges.reduce((sum, c) => sum + c.amount_refunded, 0);
39
+
40
+ const activeSubs = subscriptions.data.filter(s => s.status === 'active');
41
+ const cancelledSubs = subscriptions.data.filter(s => s.status === 'canceled');
42
+
43
+ const completedSessions = sessions.data.filter(s => s.payment_status === 'paid');
44
+ const expiredSessions = sessions.data.filter(s => s.status === 'expired');
45
+
46
+ const todayStart = new Date();
47
+ todayStart.setHours(0, 0, 0, 0);
48
+ const todayCharges = paidCharges.filter(c => c.created * 1000 >= todayStart.getTime());
49
+ const todayRevenue = todayCharges.reduce((sum, c) => sum + c.amount, 0);
50
+
51
+ const report = {
52
+ generatedAt: new Date().toISOString(),
53
+ source: 'stripe_live_api',
54
+ balance: {
55
+ available: availableBalance / 100,
56
+ pending: pendingBalance / 100,
57
+ currency: 'USD',
58
+ },
59
+ revenue: {
60
+ grossLifetime: grossRevenue / 100,
61
+ refundedLifetime: refundedAmount / 100,
62
+ netLifetime: (grossRevenue - refundedAmount) / 100,
63
+ today: todayRevenue / 100,
64
+ todayChargeCount: todayCharges.length,
65
+ },
66
+ charges: {
67
+ total: charges.data.length,
68
+ paid: paidCharges.length,
69
+ refunded: refundedCharges.length,
70
+ failed: failedCharges.length,
71
+ },
72
+ subscriptions: {
73
+ active: activeSubs.length,
74
+ cancelled: cancelledSubs.length,
75
+ total: subscriptions.data.length,
76
+ mrr: activeSubs.reduce((sum, s) => sum + (s.plan?.amount || 0), 0) / 100,
77
+ },
78
+ checkout: {
79
+ completed: completedSessions.length,
80
+ expired: expiredSessions.length,
81
+ total: sessions.data.length,
82
+ conversionRate: sessions.data.length > 0
83
+ ? (completedSessions.length / sessions.data.length * 100).toFixed(1) + '%'
84
+ : '0%',
85
+ },
86
+ products: products.data.map(p => ({
87
+ id: p.id,
88
+ name: p.name,
89
+ defaultPrice: p.default_price,
90
+ })),
91
+ activePrices: prices.data.map(p => ({
92
+ id: p.id,
93
+ amount: p.unit_amount / 100,
94
+ type: p.type,
95
+ interval: p.recurring?.interval || 'one_time',
96
+ product: p.product,
97
+ })),
98
+ };
99
+
100
+ return report;
101
+ }
102
+
103
+ async function main() {
104
+ const report = await getLiveStatus();
105
+ console.log(JSON.stringify(report, null, 2));
106
+ }
107
+
108
+ if (require.main === module) {
109
+ main().catch(err => {
110
+ console.error('Stripe live status failed:', err.message);
111
+ process.exit(1);
112
+ });
113
+ }
114
+
115
+ module.exports = { getLiveStatus };
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const { loadMcpPolicy } = require('./mcp-policy');
5
+
6
+ const PROJECT_ROOT = path.join(__dirname, '..');
7
+ const DEFAULT_SUBAGENT_PROFILE_PATH = path.join(PROJECT_ROOT, 'config', 'subagent-profiles.json');
8
+
9
+ function getSubagentProfilePath() {
10
+ return process.env.THUMBGATE_SUBAGENT_PROFILE_PATH || DEFAULT_SUBAGENT_PROFILE_PATH;
11
+ }
12
+
13
+ function loadSubagentProfiles() {
14
+ const raw = fs.readFileSync(getSubagentProfilePath(), 'utf-8');
15
+ const parsed = JSON.parse(raw);
16
+ if (!parsed.profiles || typeof parsed.profiles !== 'object') {
17
+ throw new Error('Invalid subagent profile config: missing profiles object');
18
+ }
19
+ return parsed;
20
+ }
21
+
22
+ function listSubagentProfiles() {
23
+ const parsed = loadSubagentProfiles();
24
+ return Object.keys(parsed.profiles);
25
+ }
26
+
27
+ function getSubagentProfile(name) {
28
+ const parsed = loadSubagentProfiles();
29
+ const profile = parsed.profiles[name];
30
+ if (!profile) {
31
+ throw new Error(`Unknown subagent profile: ${name}`);
32
+ }
33
+ return profile;
34
+ }
35
+
36
+ function validateSubagentProfiles() {
37
+ const parsed = loadSubagentProfiles();
38
+ const policy = loadMcpPolicy();
39
+ const issues = [];
40
+
41
+ for (const [name, profile] of Object.entries(parsed.profiles)) {
42
+ if (!profile.mcpProfile) {
43
+ issues.push(`${name}: missing mcpProfile`);
44
+ } else if (!policy.profiles[profile.mcpProfile]) {
45
+ issues.push(`${name}: unknown mcpProfile '${profile.mcpProfile}'`);
46
+ }
47
+
48
+ if (!profile.context || typeof profile.context !== 'object') {
49
+ issues.push(`${name}: missing context settings`);
50
+ } else {
51
+ if (!Number.isFinite(profile.context.maxItems) || profile.context.maxItems <= 0) {
52
+ issues.push(`${name}: invalid context.maxItems`);
53
+ }
54
+ if (!Number.isFinite(profile.context.maxChars) || profile.context.maxChars <= 0) {
55
+ issues.push(`${name}: invalid context.maxChars`);
56
+ }
57
+ }
58
+ }
59
+
60
+ return {
61
+ valid: issues.length === 0,
62
+ issues,
63
+ };
64
+ }
65
+
66
+ module.exports = {
67
+ DEFAULT_SUBAGENT_PROFILE_PATH,
68
+ getSubagentProfilePath,
69
+ loadSubagentProfiles,
70
+ listSubagentProfiles,
71
+ getSubagentProfile,
72
+ validateSubagentProfiles,
73
+ };
74
+
75
+ if (require.main === module) {
76
+ const result = validateSubagentProfiles();
77
+ console.log(JSON.stringify({ profiles: listSubagentProfiles(), ...result }, null, 2));
78
+ process.exit(result.valid ? 0 : 1);
79
+ }
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ REPO="${1:-IgorGanapolsky/ThumbGate}"
5
+
6
+ # Runtime + deploy secrets used by hosted billing and CI.
7
+ SECRET_KEYS=(
8
+ GH_PAT
9
+ SENTRY_DSN
10
+ SENTRY_AUTH_TOKEN
11
+ LLM_GATEWAY_BASE_URL
12
+ LLM_GATEWAY_API_KEY
13
+ TETRATE_API_KEY
14
+ THUMBGATE_API_KEY
15
+ STRIPE_SECRET_KEY
16
+ STRIPE_WEBHOOK_SECRET
17
+ GITHUB_MARKETPLACE_WEBHOOK_SECRET
18
+ RAILWAY_TOKEN
19
+ )
20
+
21
+ VARIABLE_KEYS=(
22
+ THUMBGATE_PUBLIC_APP_ORIGIN
23
+ THUMBGATE_BILLING_API_BASE_URL
24
+ THUMBGATE_FEEDBACK_DIR
25
+ THUMBGATE_GA_MEASUREMENT_ID
26
+ THUMBGATE_GOOGLE_SITE_VERIFICATION
27
+ RAILWAY_PROJECT_ID
28
+ RAILWAY_ENVIRONMENT_ID
29
+ RAILWAY_SERVICE
30
+ RAILWAY_HEALTHCHECK_URL
31
+ THUMBGATE_API_KEY_ROTATED_AT
32
+ STRIPE_SECRET_KEY_ROTATED_AT
33
+ STRIPE_WEBHOOK_SECRET_ROTATED_AT
34
+ GITHUB_MARKETPLACE_WEBHOOK_SECRET_ROTATED_AT
35
+ RAILWAY_TOKEN_ROTATED_AT
36
+ GEMINI_API_KEY_ROTATED_AT
37
+ PERPLEXITY_API_KEY_ROTATED_AT
38
+ X_API_KEY_ROTATED_AT
39
+ X_API_SECRET_ROTATED_AT
40
+ X_ACCESS_TOKEN_ROTATED_AT
41
+ X_ACCESS_TOKEN_SECRET_ROTATED_AT
42
+ )
43
+
44
+ echo "Syncing secrets to $REPO (only keys present in current environment)..."
45
+
46
+ for key in "${SECRET_KEYS[@]}"; do
47
+ value="${!key:-}"
48
+ if [[ -z "$value" ]]; then
49
+ echo "- skip $key (not set)"
50
+ continue
51
+ fi
52
+
53
+ printf '%s' "$value" | gh secret set "$key" -R "$REPO"
54
+ echo "- set $key"
55
+ done
56
+
57
+ echo "Syncing repo variables to $REPO (only keys present in current environment)..."
58
+
59
+ for key in "${VARIABLE_KEYS[@]}"; do
60
+ value="${!key:-}"
61
+ if [[ -z "$value" ]]; then
62
+ echo "- skip $key (not set)"
63
+ continue
64
+ fi
65
+
66
+ gh variable set "$key" -R "$REPO" --body "$value"
67
+ echo "- set $key"
68
+ done
69
+
70
+ echo "Done."
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const {
5
+ compareGitHubAbout,
6
+ fetchLiveGitHubAbout,
7
+ loadGitHubAboutConfig,
8
+ updateLiveGitHubAbout,
9
+ } = require('./github-about');
10
+
11
+ async function main() {
12
+ const args = new Set(process.argv.slice(2));
13
+ const write = args.has('--write');
14
+ const about = loadGitHubAboutConfig();
15
+ const before = await fetchLiveGitHubAbout({ repo: about.repo });
16
+ const drift = compareGitHubAbout(about, before, `Live GitHub About (${about.repo})`);
17
+
18
+ if (drift.length === 0) {
19
+ console.log(`✅ GitHub About already matches source of truth for ${about.repo}.`);
20
+ return;
21
+ }
22
+
23
+ if (!write) {
24
+ console.error(`\n❌ GitHub About drift detected for ${about.repo}:\n`);
25
+ for (const error of drift) {
26
+ console.error(` • ${error}`);
27
+ }
28
+ console.error('');
29
+ process.exit(1);
30
+ }
31
+
32
+ console.log(`Syncing GitHub About for ${about.repo}...`);
33
+ await updateLiveGitHubAbout({ repo: about.repo });
34
+
35
+ const after = await fetchLiveGitHubAbout({ repo: about.repo });
36
+ const remaining = compareGitHubAbout(about, after, `Live GitHub About (${about.repo})`);
37
+ if (remaining.length > 0) {
38
+ console.error(`\n❌ GitHub About sync incomplete for ${about.repo}:\n`);
39
+ for (const error of remaining) {
40
+ console.error(` • ${error}`);
41
+ }
42
+ console.error('');
43
+ process.exit(1);
44
+ }
45
+
46
+ console.log(`✅ GitHub About synced for ${about.repo}.`);
47
+ }
48
+
49
+ main().catch((error) => {
50
+ console.error(`\n❌ GitHub About sync failed: ${error.message}\n`);
51
+ process.exit(1);
52
+ });