thumbgate 1.4.3 → 1.4.5
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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.well-known/llms.txt +12 -8
- package/.well-known/mcp/server-card.json +1 -1
- package/README.md +18 -8
- package/adapters/README.md +1 -1
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/codex/config.toml +2 -2
- package/adapters/mcp/server-stdio.js +1 -1
- package/adapters/opencode/opencode.json +1 -1
- package/config/github-about.json +2 -2
- package/package.json +158 -10
- package/scripts/billing.js +5 -2
- package/scripts/statusline.sh +1 -0
- package/src/api/server.js +113 -16
- package/src/index.js +3 -0
- package/.claude-plugin/bundle/icon.png +0 -0
- package/.claude-plugin/bundle/icon.svg +0 -18
- package/.claude-plugin/bundle/server/index.js +0 -24
- package/adapters/chatgpt/INSTALL.md +0 -158
- package/adapters/perplexity/.mcp.json +0 -36
- package/adapters/perplexity/config.toml +0 -16
- package/adapters/perplexity/opencode.json +0 -29
- package/bin/memory.sh +0 -64
- package/bin/obsidian-sync.sh +0 -20
- package/plugins/amp-skill/INSTALL.md +0 -52
- package/plugins/amp-skill/SKILL.md +0 -64
- package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +0 -22
- package/plugins/claude-codex-bridge/.mcp.json +0 -14
- package/plugins/claude-codex-bridge/INSTALL.md +0 -43
- package/plugins/claude-codex-bridge/README.md +0 -46
- package/plugins/claude-codex-bridge/scripts/codex-bridge.js +0 -286
- package/plugins/claude-codex-bridge/skills/adversarial-review/SKILL.md +0 -24
- package/plugins/claude-codex-bridge/skills/result/SKILL.md +0 -22
- package/plugins/claude-codex-bridge/skills/review/SKILL.md +0 -28
- package/plugins/claude-codex-bridge/skills/second-pass/SKILL.md +0 -27
- package/plugins/claude-codex-bridge/skills/setup/SKILL.md +0 -21
- package/plugins/claude-codex-bridge/skills/status/SKILL.md +0 -19
- package/plugins/claude-skill/INSTALL.md +0 -55
- package/plugins/claude-skill/SKILL.md +0 -46
- package/plugins/codex-profile/.codex-plugin/plugin.json +0 -43
- package/plugins/codex-profile/.mcp.json +0 -14
- package/plugins/codex-profile/AGENTS.md +0 -20
- package/plugins/codex-profile/INSTALL.md +0 -89
- package/plugins/codex-profile/README.md +0 -61
- package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +0 -23
- package/plugins/cursor-marketplace/CHANGELOG.md +0 -30
- package/plugins/cursor-marketplace/LICENSE +0 -21
- package/plugins/cursor-marketplace/README.md +0 -124
- package/plugins/cursor-marketplace/agents/reliability-reviewer.md +0 -31
- package/plugins/cursor-marketplace/assets/logo-400x400.png +0 -0
- package/plugins/cursor-marketplace/commands/capture-feedback.md +0 -33
- package/plugins/cursor-marketplace/commands/check-gates.md +0 -25
- package/plugins/cursor-marketplace/commands/show-lessons.md +0 -27
- package/plugins/cursor-marketplace/hooks/hooks.json +0 -10
- package/plugins/cursor-marketplace/mcp.json +0 -14
- package/plugins/cursor-marketplace/rules/feedback-capture.mdc +0 -34
- package/plugins/cursor-marketplace/rules/pre-action-gates.mdc +0 -30
- package/plugins/cursor-marketplace/rules/session-continuity.mdc +0 -28
- package/plugins/cursor-marketplace/scripts/gate-check.sh +0 -21
- package/plugins/cursor-marketplace/skills/capture-feedback/SKILL.md +0 -48
- package/plugins/cursor-marketplace/skills/prevention-rules/SKILL.md +0 -31
- package/plugins/cursor-marketplace/skills/recall-context/SKILL.md +0 -30
- package/plugins/cursor-marketplace/skills/search-lessons/SKILL.md +0 -33
- package/plugins/gemini-extension/INSTALL.md +0 -92
- package/plugins/gemini-extension/gemini_prompt.txt +0 -14
- package/plugins/gemini-extension/tool_contract.json +0 -45
- package/plugins/opencode-profile/INSTALL.md +0 -57
- package/public/assets/instagram-card.png +0 -0
- package/public/assets/tiktok-agent-memory.mp4 +0 -0
- package/public/blog.html +0 -474
- package/public/compare/mem0.html +0 -189
- package/public/compare/speclock.html +0 -180
- package/public/compare.html +0 -310
- package/public/dashboard.html +0 -1100
- package/public/guide.html +0 -317
- package/public/guides/claude-code-prevent-repeated-mistakes.html +0 -161
- package/public/guides/codex-cli-guardrails.html +0 -158
- package/public/guides/cursor-prevent-repeated-mistakes.html +0 -161
- package/public/guides/pre-action-gates.html +0 -162
- package/public/guides/stop-repeated-ai-agent-mistakes.html +0 -159
- package/public/index.html +0 -1225
- package/public/js/buyer-intent.js +0 -252
- package/public/learn/agent-harness-pattern.html +0 -180
- package/public/learn/ai-agent-persistent-memory.html +0 -203
- package/public/learn/learn.css +0 -45
- package/public/learn/mcp-pre-action-gates-explained.html +0 -172
- package/public/learn/stop-ai-agent-force-push.html +0 -134
- package/public/learn/vibe-coding-safety-net.html +0 -142
- package/public/learn.html +0 -274
- package/public/lessons.html +0 -967
- package/public/llm-context.md +0 -156
- package/public/pro.html +0 -1087
- package/public/vercel.json +0 -8
- package/scripts/a2ui-engine.js +0 -73
- package/scripts/adk-consolidator.js +0 -274
- package/scripts/agent-security-hardening.js +0 -225
- package/scripts/ai-search-visibility.js +0 -116
- package/scripts/autonomous-sales-agent.js +0 -39
- package/scripts/autoresearch-runner.js +0 -216
- package/scripts/background-agent-governance.js +0 -229
- package/scripts/behavioral-extraction.js +0 -93
- package/scripts/budget-enforcer.js +0 -173
- package/scripts/budget-guard.js +0 -173
- package/scripts/build-claude-mcpb.js +0 -255
- package/scripts/build-codex-plugin.js +0 -152
- package/scripts/capture-railway-diagnostics.sh +0 -97
- package/scripts/changeset-check.js +0 -372
- package/scripts/check-congruence.js +0 -443
- package/scripts/computer-use-firewall.js +0 -280
- package/scripts/content-engine/linkedin-content-generator.js +0 -154
- package/scripts/content-engine/output/linkedin-memento-validation.md +0 -17
- package/scripts/content-engine/output/linkedin-posts-2026-04-09.md +0 -175
- package/scripts/content-engine/reddit-thread-finder.js +0 -154
- package/scripts/context-engine.js +0 -710
- package/scripts/daily-digest.js +0 -11
- package/scripts/data-governance.js +0 -173
- package/scripts/deploy-gcp.sh +0 -44
- package/scripts/deploy-policy.js +0 -249
- package/scripts/disagreement-mining.js +0 -315
- package/scripts/dpo-optimizer.js +0 -206
- package/scripts/ensure-repo-bootstrap.js +0 -130
- package/scripts/ephemeral-agent-store.js +0 -212
- package/scripts/eval-harness.js +0 -56
- package/scripts/export-kto-pairs.js +0 -309
- package/scripts/export-training.js +0 -446
- package/scripts/feedback-fallback.js +0 -111
- package/scripts/feedback-inbox-read.js +0 -162
- package/scripts/feedback-root-consolidator.js +0 -233
- package/scripts/feedback-to-memory.js +0 -185
- package/scripts/gate-satisfy.js +0 -42
- package/scripts/generate-paperbanana-diagrams.sh +0 -99
- package/scripts/generate-pretool-hook.sh +0 -40
- package/scripts/github-about.js +0 -430
- package/scripts/github-outreach.js +0 -65
- package/scripts/gtm-revenue-loop.js +0 -535
- package/scripts/hallucination-detector.js +0 -226
- package/scripts/hf-papers.js +0 -317
- package/scripts/hook-auto-capture.sh +0 -100
- package/scripts/hook-stop-pr-thread-check.sh +0 -68
- package/scripts/hook-stop-self-score.sh +0 -51
- package/scripts/hook-stop-verify-deploy.sh +0 -31
- package/scripts/hook-verify-before-done.sh +0 -20
- package/scripts/managed-dpo-export.js +0 -91
- package/scripts/markdown-escape.js +0 -12
- package/scripts/marketing-experiment.js +0 -657
- package/scripts/memalign-recall.js +0 -111
- package/scripts/memory-migration.js +0 -296
- package/scripts/meta-policy.js +0 -190
- package/scripts/metered-billing.js +0 -16
- package/scripts/model-tier-router.js +0 -310
- package/scripts/money-watcher.js +0 -218
- package/scripts/multi-hop-recall.js +0 -240
- package/scripts/per-step-scoring.js +0 -163
- package/scripts/perplexity-command-center.js +0 -644
- package/scripts/perplexity-marketing.js +0 -454
- package/scripts/pii-scanner.js +0 -153
- package/scripts/plan-gate.js +0 -154
- package/scripts/post-everywhere.js +0 -341
- package/scripts/post-to-x-retry.sh +0 -22
- package/scripts/post-to-x.js +0 -369
- package/scripts/pr-manager.js +0 -421
- package/scripts/principle-extractor.js +0 -162
- package/scripts/pro-features.js +0 -41
- package/scripts/prompt-dlp.js +0 -222
- package/scripts/prove-adapters.js +0 -860
- package/scripts/prove-attribution.js +0 -361
- package/scripts/prove-automation.js +0 -651
- package/scripts/prove-autoresearch.js +0 -304
- package/scripts/prove-claim-verification.js +0 -277
- package/scripts/prove-cloudflare-sandbox.js +0 -161
- package/scripts/prove-data-pipeline.js +0 -408
- package/scripts/prove-data-quality.js +0 -227
- package/scripts/prove-evolution.js +0 -352
- package/scripts/prove-harnesses.js +0 -287
- package/scripts/prove-intelligence.js +0 -257
- package/scripts/prove-lancedb.js +0 -425
- package/scripts/prove-local-intelligence.js +0 -340
- package/scripts/prove-loop-closure.js +0 -263
- package/scripts/prove-packaged-runtime.js +0 -327
- package/scripts/prove-predictive-insights.js +0 -355
- package/scripts/prove-runtime.js +0 -363
- package/scripts/prove-seo-gsd.js +0 -234
- package/scripts/prove-settings.js +0 -279
- package/scripts/prove-subway-upgrades.js +0 -277
- package/scripts/prove-tessl.js +0 -229
- package/scripts/prove-training-export.js +0 -325
- package/scripts/prove-workflow-contract.js +0 -112
- package/scripts/prove-xmemory.js +0 -332
- package/scripts/publish-decision.js +0 -159
- package/scripts/ralph-loop.js +0 -376
- package/scripts/ralph-mode-ci.js +0 -434
- package/scripts/reddit-dm-outreach.js +0 -192
- package/scripts/reddit-monitor-cron.sh +0 -26
- package/scripts/reminder-engine.js +0 -132
- package/scripts/revenue-status.js +0 -472
- package/scripts/rotate-stripe-webhook-secret.js +0 -314
- package/scripts/schedule-manager.js +0 -249
- package/scripts/self-healing-check.js +0 -193
- package/scripts/session-analyzer.js +0 -533
- package/scripts/shieldcortex-memory-firewall-runner.mjs +0 -53
- package/scripts/skill-exporter.js +0 -260
- package/scripts/skill-materializer.js +0 -134
- package/scripts/skill-packs.js +0 -136
- package/scripts/skill-proposer.js +0 -99
- package/scripts/skill-quality-tracker.js +0 -282
- package/scripts/slow-loop.js +0 -72
- package/scripts/social-analytics/db/marketing-db.js +0 -179
- package/scripts/social-analytics/db/schema.sql +0 -55
- package/scripts/social-analytics/digest.js +0 -256
- package/scripts/social-analytics/engagement-audit.js +0 -185
- package/scripts/social-analytics/generate-instagram-card.js +0 -123
- package/scripts/social-analytics/generate-slides.js +0 -268
- package/scripts/social-analytics/instagram-thumbgate-post.js +0 -111
- package/scripts/social-analytics/install-growth-automation.js +0 -114
- package/scripts/social-analytics/load-env.js +0 -77
- package/scripts/social-analytics/mcp-server.js +0 -289
- package/scripts/social-analytics/normalizer.js +0 -580
- package/scripts/social-analytics/notify.js +0 -162
- package/scripts/social-analytics/poll-all.js +0 -107
- package/scripts/social-analytics/pollers/github.js +0 -195
- package/scripts/social-analytics/pollers/instagram.js +0 -253
- package/scripts/social-analytics/pollers/linkedin.js +0 -340
- package/scripts/social-analytics/pollers/plausible.js +0 -245
- package/scripts/social-analytics/pollers/reddit.js +0 -306
- package/scripts/social-analytics/pollers/threads.js +0 -233
- package/scripts/social-analytics/pollers/tiktok.js +0 -203
- package/scripts/social-analytics/pollers/x.js +0 -227
- package/scripts/social-analytics/pollers/youtube.js +0 -304
- package/scripts/social-analytics/pollers/zernio.js +0 -183
- package/scripts/social-analytics/post-video.js +0 -316
- package/scripts/social-analytics/publish-instagram-thumbgate.js +0 -104
- package/scripts/social-analytics/publish-thumbgate-launch.js +0 -322
- package/scripts/social-analytics/publishers/devto.js +0 -122
- package/scripts/social-analytics/publishers/instagram.js +0 -317
- package/scripts/social-analytics/publishers/linkedin.js +0 -294
- package/scripts/social-analytics/publishers/reddit.js +0 -385
- package/scripts/social-analytics/publishers/threads.js +0 -275
- package/scripts/social-analytics/publishers/tiktok.js +0 -217
- package/scripts/social-analytics/publishers/x.js +0 -259
- package/scripts/social-analytics/publishers/youtube.js +0 -223
- package/scripts/social-analytics/publishers/zernio.js +0 -568
- package/scripts/social-analytics/reconcile-thumbgate-campaign.js +0 -165
- package/scripts/social-analytics/run-digest.js +0 -34
- package/scripts/social-analytics/schedule-thumbgate-campaign.js +0 -275
- package/scripts/social-analytics/store.js +0 -455
- package/scripts/social-analytics/sync-launch-assets.js +0 -185
- package/scripts/social-analytics/utm.js +0 -143
- package/scripts/social-pipeline.js +0 -2626
- package/scripts/social-post-hourly.js +0 -228
- package/scripts/social-quality-gate.js +0 -134
- package/scripts/social-reply-monitor.js +0 -592
- package/scripts/status-dashboard.js +0 -155
- package/scripts/stripe-live-status.js +0 -115
- package/scripts/subagent-profiles.js +0 -79
- package/scripts/sync-branch-protection.js +0 -340
- package/scripts/sync-gh-secrets-from-env.sh +0 -70
- package/scripts/sync-github-about.js +0 -55
- package/scripts/sync-version.js +0 -479
- package/scripts/synthetic-dpo.js +0 -234
- package/scripts/tessl-export.js +0 -369
- package/scripts/test-coverage.js +0 -128
- package/scripts/thumbgate-bench.js +0 -494
- package/scripts/thumbgate_session_start.sh +0 -32
- package/scripts/train_from_feedback.py +0 -929
- package/scripts/validate-feedback.js +0 -581
- package/scripts/verify-obsidian-setup.sh +0 -269
- package/scripts/verify-run.js +0 -269
- package/scripts/weekly-auto-post.js +0 -124
- package/scripts/x-autonomous-marketing.js +0 -139
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# verify-obsidian-setup.sh
|
|
3
|
-
# Automated fact-checker: validates every claim in docs/OBSIDIAN_SETUP.md
|
|
4
|
-
# and docs/marketing/reddit-obsidian-post.md maps to real repo artifacts.
|
|
5
|
-
# Exit 0 if all checks pass, exit 1 if any fail.
|
|
6
|
-
|
|
7
|
-
set -euo pipefail
|
|
8
|
-
|
|
9
|
-
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
10
|
-
SETUP_DOC="$REPO_ROOT/docs/OBSIDIAN_SETUP.md"
|
|
11
|
-
REDDIT_DOC="$REPO_ROOT/docs/marketing/reddit-obsidian-post.md"
|
|
12
|
-
PACKAGE_JSON="$REPO_ROOT/package.json"
|
|
13
|
-
|
|
14
|
-
PASS=0
|
|
15
|
-
FAIL=0
|
|
16
|
-
|
|
17
|
-
check() {
|
|
18
|
-
local label="$1"
|
|
19
|
-
local result="$2"
|
|
20
|
-
if [ "$result" = "pass" ]; then
|
|
21
|
-
echo " PASS $label"
|
|
22
|
-
PASS=$((PASS + 1))
|
|
23
|
-
else
|
|
24
|
-
echo " FAIL $label"
|
|
25
|
-
FAIL=$((FAIL + 1))
|
|
26
|
-
fi
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
echo ""
|
|
30
|
-
echo "=== OBSIDIAN SETUP VERIFICATION ==="
|
|
31
|
-
echo ""
|
|
32
|
-
|
|
33
|
-
# --- Section 1: Document files exist ---
|
|
34
|
-
echo "[ Files ]"
|
|
35
|
-
|
|
36
|
-
[ -f "$SETUP_DOC" ] && check "docs/OBSIDIAN_SETUP.md exists" "pass" || check "docs/OBSIDIAN_SETUP.md exists" "fail"
|
|
37
|
-
[ -f "$REDDIT_DOC" ] && check "docs/marketing/reddit-obsidian-post.md exists" "pass" || check "docs/marketing/reddit-obsidian-post.md exists" "fail"
|
|
38
|
-
|
|
39
|
-
# --- Section 2: Line count minimums ---
|
|
40
|
-
echo ""
|
|
41
|
-
echo "[ Line Count Requirements ]"
|
|
42
|
-
|
|
43
|
-
SETUP_LINES=$(wc -l < "$SETUP_DOC" | tr -d ' ')
|
|
44
|
-
REDDIT_LINES=$(wc -l < "$REDDIT_DOC" | tr -d ' ')
|
|
45
|
-
|
|
46
|
-
[ "$SETUP_LINES" -ge 60 ] && check "OBSIDIAN_SETUP.md has >= 60 lines (got $SETUP_LINES)" "pass" || check "OBSIDIAN_SETUP.md has >= 60 lines (got $SETUP_LINES)" "fail"
|
|
47
|
-
[ "$REDDIT_LINES" -ge 40 ] && check "reddit-obsidian-post.md has >= 40 lines (got $REDDIT_LINES)" "pass" || check "reddit-obsidian-post.md has >= 40 lines (got $REDDIT_LINES)" "fail"
|
|
48
|
-
|
|
49
|
-
# --- Section 3: npm scripts referenced in OBSIDIAN_SETUP.md exist in package.json ---
|
|
50
|
-
echo ""
|
|
51
|
-
echo "[ npm Script Verification: OBSIDIAN_SETUP.md ]"
|
|
52
|
-
|
|
53
|
-
check_npm_script() {
|
|
54
|
-
local script="$1"
|
|
55
|
-
if grep -q "\"$script\"" "$PACKAGE_JSON"; then
|
|
56
|
-
check "npm run $script exists in package.json" "pass"
|
|
57
|
-
else
|
|
58
|
-
check "npm run $script exists in package.json" "fail"
|
|
59
|
-
fi
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
# Extract npm scripts referenced in the setup doc
|
|
63
|
-
# These are the scripts explicitly mentioned: feedback:stats, feedback:summary, feedback:rules, self-heal:check
|
|
64
|
-
check_npm_script "feedback:stats"
|
|
65
|
-
check_npm_script "feedback:summary"
|
|
66
|
-
check_npm_script "feedback:rules"
|
|
67
|
-
check_npm_script "self-heal:check"
|
|
68
|
-
|
|
69
|
-
# --- Section 4: MCP server binary reference ---
|
|
70
|
-
echo ""
|
|
71
|
-
echo "[ MCP Server References ]"
|
|
72
|
-
|
|
73
|
-
# Package name in MCP config JSON must match package.json name
|
|
74
|
-
PKG_NAME=$(node -e "const p=require('$PACKAGE_JSON'); process.stdout.write(p.name);" 2>/dev/null || echo "")
|
|
75
|
-
if grep -q "thumbgate" "$SETUP_DOC"; then
|
|
76
|
-
check "OBSIDIAN_SETUP.md references correct MCP package name (thumbgate)" "pass"
|
|
77
|
-
else
|
|
78
|
-
check "OBSIDIAN_SETUP.md references correct MCP package name (thumbgate)" "fail"
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
# MCP server-stdio.js must exist
|
|
82
|
-
if [ -f "$REPO_ROOT/adapters/mcp/server-stdio.js" ]; then
|
|
83
|
-
check "adapters/mcp/server-stdio.js exists (local MCP run command)" "pass"
|
|
84
|
-
else
|
|
85
|
-
check "adapters/mcp/server-stdio.js exists (local MCP run command)" "fail"
|
|
86
|
-
fi
|
|
87
|
-
|
|
88
|
-
# npx command in setup doc
|
|
89
|
-
if grep -q "npx thumbgate serve" "$SETUP_DOC"; then
|
|
90
|
-
check "OBSIDIAN_SETUP.md includes npx thumbgate serve command" "pass"
|
|
91
|
-
else
|
|
92
|
-
check "OBSIDIAN_SETUP.md includes npx thumbgate serve command" "fail"
|
|
93
|
-
fi
|
|
94
|
-
|
|
95
|
-
# --- Section 5: Plugin reference ---
|
|
96
|
-
echo ""
|
|
97
|
-
echo "[ Plugin Reference ]"
|
|
98
|
-
|
|
99
|
-
if grep -q "petersolopov/obsidian-claude-ide" "$SETUP_DOC"; then
|
|
100
|
-
check "OBSIDIAN_SETUP.md references petersolopov/obsidian-claude-ide" "pass"
|
|
101
|
-
else
|
|
102
|
-
check "OBSIDIAN_SETUP.md references petersolopov/obsidian-claude-ide" "fail"
|
|
103
|
-
fi
|
|
104
|
-
|
|
105
|
-
if grep -q "petersolopov/obsidian-claude-ide" "$REDDIT_DOC"; then
|
|
106
|
-
check "reddit-obsidian-post.md references petersolopov/obsidian-claude-ide" "pass"
|
|
107
|
-
else
|
|
108
|
-
check "reddit-obsidian-post.md references petersolopov/obsidian-claude-ide" "fail"
|
|
109
|
-
fi
|
|
110
|
-
|
|
111
|
-
# --- Section 6: Memory file paths are documented as local-only ---
|
|
112
|
-
echo ""
|
|
113
|
-
echo "[ Memory File Path Documentation ]"
|
|
114
|
-
|
|
115
|
-
# These paths are local-only (git-ignored). Verify they are mentioned in OBSIDIAN_SETUP.md
|
|
116
|
-
# and that CLAUDE.md documents them as local-only (not fabricated)
|
|
117
|
-
CLAUDE_MD="$REPO_ROOT/CLAUDE.md"
|
|
118
|
-
|
|
119
|
-
check_path_documented() {
|
|
120
|
-
local path="$1"
|
|
121
|
-
local label="$2"
|
|
122
|
-
if grep -q "$path" "$SETUP_DOC" && grep -q "$path" "$CLAUDE_MD"; then
|
|
123
|
-
check "$label is documented in both OBSIDIAN_SETUP.md and CLAUDE.md" "pass"
|
|
124
|
-
elif grep -q "$path" "$SETUP_DOC"; then
|
|
125
|
-
# Path referenced in setup doc — check if it exists locally OR is in gitignore
|
|
126
|
-
if [ -f "$REPO_ROOT/$path" ] || grep -q "$path" "$REPO_ROOT/.gitignore" 2>/dev/null; then
|
|
127
|
-
check "$label is referenced and is a known local-only path" "pass"
|
|
128
|
-
else
|
|
129
|
-
check "$label is referenced and is a known local-only path" "pass"
|
|
130
|
-
# Local-only files may not exist until runtime — this is expected
|
|
131
|
-
fi
|
|
132
|
-
else
|
|
133
|
-
check "$label is mentioned in OBSIDIAN_SETUP.md" "fail"
|
|
134
|
-
fi
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
check_path_documented ".thumbgate/memory-log.jsonl" "memory-log.jsonl"
|
|
138
|
-
check_path_documented ".thumbgate/prevention-rules.md" "prevention-rules.md"
|
|
139
|
-
check_path_documented ".thumbgate/feedback-log.jsonl" "feedback-log.jsonl"
|
|
140
|
-
|
|
141
|
-
# primer.md must exist (it is committed)
|
|
142
|
-
if [ -f "$REPO_ROOT/primer.md" ]; then
|
|
143
|
-
check "primer.md exists in repo root" "pass"
|
|
144
|
-
else
|
|
145
|
-
check "primer.md exists in repo root" "fail"
|
|
146
|
-
fi
|
|
147
|
-
|
|
148
|
-
# --- Section 7: GitHub repo URL correctness ---
|
|
149
|
-
echo ""
|
|
150
|
-
echo "[ GitHub Repository URL ]"
|
|
151
|
-
|
|
152
|
-
EXPECTED_REPO="https://github.com/IgorGanapolsky/ThumbGate"
|
|
153
|
-
if grep -q "$EXPECTED_REPO" "$SETUP_DOC"; then
|
|
154
|
-
check "OBSIDIAN_SETUP.md contains correct GitHub URL" "pass"
|
|
155
|
-
else
|
|
156
|
-
check "OBSIDIAN_SETUP.md contains correct GitHub URL" "fail"
|
|
157
|
-
fi
|
|
158
|
-
|
|
159
|
-
if grep -q "$EXPECTED_REPO" "$REDDIT_DOC"; then
|
|
160
|
-
check "reddit-obsidian-post.md contains correct GitHub URL" "pass"
|
|
161
|
-
else
|
|
162
|
-
check "reddit-obsidian-post.md contains correct GitHub URL" "fail"
|
|
163
|
-
fi
|
|
164
|
-
|
|
165
|
-
# --- Section 8: No false feature claims in reddit post ---
|
|
166
|
-
echo ""
|
|
167
|
-
echo "[ False Feature Claim Detection: reddit-obsidian-post.md ]"
|
|
168
|
-
|
|
169
|
-
# Check for affirmative (non-negated) false feature claims that don't exist in this repo
|
|
170
|
-
# We grep for patterns like "supports real-time", "includes cloud sync", "auto-updates", etc.
|
|
171
|
-
# We do NOT flag negations like "No real-time sync" or "not cloud sync" — those are correct disclaimers.
|
|
172
|
-
found_false_claim=false
|
|
173
|
-
|
|
174
|
-
# Pattern: affirmative claim — must NOT appear (case-insensitive)
|
|
175
|
-
# Negation pattern: lines with "No ", "not ", "without " before the claim are OK
|
|
176
|
-
check_no_affirmative_claim() {
|
|
177
|
-
local claim="$1"
|
|
178
|
-
# Count lines that have the claim but NOT a negation on the same line
|
|
179
|
-
local affirm_count
|
|
180
|
-
affirm_count=$(grep -ic "$claim" "$REDDIT_DOC" 2>/dev/null; true)
|
|
181
|
-
affirm_count=$(echo "$affirm_count" | head -1 | tr -d '[:space:]')
|
|
182
|
-
affirm_count=${affirm_count:-0}
|
|
183
|
-
local negated_count
|
|
184
|
-
negated_count=$(grep -ic "no $claim\|not $claim\|without $claim\|No $claim\|NOT $claim\|doesn't $claim\|don't $claim\|None of this is.*$claim\|$claim.*isn't\|is not.*$claim" "$REDDIT_DOC" 2>/dev/null; true)
|
|
185
|
-
negated_count=$(echo "$negated_count" | head -1 | tr -d '[:space:]')
|
|
186
|
-
negated_count=${negated_count:-0}
|
|
187
|
-
local net=$(( affirm_count - negated_count ))
|
|
188
|
-
if [ "$net" -gt 0 ]; then
|
|
189
|
-
check "No affirmative false claim '$claim' in reddit post (found $net non-negated)" "fail"
|
|
190
|
-
found_false_claim=true
|
|
191
|
-
fi
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
check_no_affirmative_claim "real-time sync"
|
|
195
|
-
check_no_affirmative_claim "real-time updates"
|
|
196
|
-
check_no_affirmative_claim "auto-update"
|
|
197
|
-
check_no_affirmative_claim "auto-syncing"
|
|
198
|
-
check_no_affirmative_claim "live sync"
|
|
199
|
-
|
|
200
|
-
# "cloud sync" — appears in disclaimer "No real-time Obsidian sync ... no cloud storage"
|
|
201
|
-
# Check it's only used as a negation
|
|
202
|
-
if grep -qi "cloud sync" "$REDDIT_DOC" && ! grep -qi "no cloud\|not cloud\|without cloud" "$REDDIT_DOC"; then
|
|
203
|
-
check "No affirmative false claim 'cloud sync' in reddit post" "fail"
|
|
204
|
-
found_false_claim=true
|
|
205
|
-
fi
|
|
206
|
-
|
|
207
|
-
# "Obsidian sync" — appears as negation: "No real-time Obsidian sync" — this is fine
|
|
208
|
-
# only fail if used affirmatively (e.g., "supports Obsidian Sync")
|
|
209
|
-
if grep -qi "supports Obsidian Sync\|uses Obsidian Sync\|Obsidian Sync enabled" "$REDDIT_DOC"; then
|
|
210
|
-
check "No affirmative 'Obsidian Sync' feature claim" "fail"
|
|
211
|
-
found_false_claim=true
|
|
212
|
-
fi
|
|
213
|
-
|
|
214
|
-
if [ "$found_false_claim" = false ]; then
|
|
215
|
-
check "No affirmative false feature claims (real-time sync, cloud sync, auto-update) detected" "pass"
|
|
216
|
-
fi
|
|
217
|
-
|
|
218
|
-
# Verify the reddit post explicitly disclaims auto-sync (required)
|
|
219
|
-
if grep -q "No real-time\|not real-time\|no real-time\|No auto-update\|not auto\|you control" "$REDDIT_DOC"; then
|
|
220
|
-
check "Reddit post explicitly disclaims non-existent features" "pass"
|
|
221
|
-
else
|
|
222
|
-
check "Reddit post explicitly disclaims non-existent features" "fail"
|
|
223
|
-
fi
|
|
224
|
-
|
|
225
|
-
# --- Section 9: Reddit post references real features only ---
|
|
226
|
-
echo ""
|
|
227
|
-
echo "[ Real Feature Verification: reddit-obsidian-post.md ]"
|
|
228
|
-
|
|
229
|
-
# prevention-rules.md must exist in CLAUDE.md docs section
|
|
230
|
-
if grep -q "prevention-rules.md" "$REDDIT_DOC" && grep -q "prevention-rules.md" "$CLAUDE_MD"; then
|
|
231
|
-
check "prevention-rules.md claim in reddit post backed by CLAUDE.md" "pass"
|
|
232
|
-
else
|
|
233
|
-
check "prevention-rules.md claim in reddit post backed by CLAUDE.md" "fail"
|
|
234
|
-
fi
|
|
235
|
-
|
|
236
|
-
# Thompson Sampling must exist in codebase
|
|
237
|
-
if [ -f "$REPO_ROOT/scripts/thompson-sampling.js" ] || grep -rq "thompson" "$REPO_ROOT/src/" 2>/dev/null || grep -rq "ThompsonSampling\|thompson-sampling\|thompsonSampling" "$REPO_ROOT/scripts/" 2>/dev/null; then
|
|
238
|
-
check "Thompson Sampling claim backed by codebase" "pass"
|
|
239
|
-
else
|
|
240
|
-
# Check tests as proxy
|
|
241
|
-
if [ -f "$REPO_ROOT/tests/thompson-sampling.test.js" ]; then
|
|
242
|
-
check "Thompson Sampling claim backed by codebase (test file)" "pass"
|
|
243
|
-
else
|
|
244
|
-
check "Thompson Sampling claim backed by codebase" "fail"
|
|
245
|
-
fi
|
|
246
|
-
fi
|
|
247
|
-
|
|
248
|
-
# MIT license claim
|
|
249
|
-
if grep -q "\"license\": \"MIT\"" "$PACKAGE_JSON"; then
|
|
250
|
-
check "MIT license claim backed by package.json" "pass"
|
|
251
|
-
else
|
|
252
|
-
check "MIT license claim backed by package.json" "fail"
|
|
253
|
-
fi
|
|
254
|
-
|
|
255
|
-
# --- Summary ---
|
|
256
|
-
echo ""
|
|
257
|
-
echo "=================================="
|
|
258
|
-
TOTAL=$((PASS + FAIL))
|
|
259
|
-
echo "Results: $PASS/$TOTAL checks passed"
|
|
260
|
-
echo ""
|
|
261
|
-
|
|
262
|
-
if [ "$FAIL" -eq 0 ]; then
|
|
263
|
-
echo "All checks passed. Every claim in OBSIDIAN_SETUP.md and reddit-obsidian-post.md"
|
|
264
|
-
echo "maps to a real artifact in this repository."
|
|
265
|
-
exit 0
|
|
266
|
-
else
|
|
267
|
-
echo "FAILED: $FAIL check(s) did not pass. Fix the docs and re-run."
|
|
268
|
-
exit 1
|
|
269
|
-
fi
|
package/scripts/verify-run.js
DELETED
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const fs = require('node:fs');
|
|
5
|
-
const os = require('node:os');
|
|
6
|
-
const path = require('node:path');
|
|
7
|
-
const { spawnSync } = require('node:child_process');
|
|
8
|
-
|
|
9
|
-
const { appendWorkflowRun } = require('./workflow-runs');
|
|
10
|
-
|
|
11
|
-
function npmCommand() {
|
|
12
|
-
return process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function buildVerifyPlan(mode = 'quick') {
|
|
16
|
-
if (mode === 'quick') {
|
|
17
|
-
return [
|
|
18
|
-
{ command: 'node', args: ['--test', 'tests/verify-run.test.js'] },
|
|
19
|
-
{ command: npmCommand(), args: ['run', 'test:cli'] },
|
|
20
|
-
];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (mode === 'full') {
|
|
24
|
-
return [
|
|
25
|
-
{ command: npmCommand(), args: ['test'] },
|
|
26
|
-
{ command: npmCommand(), args: ['run', 'test:coverage'] },
|
|
27
|
-
{ command: npmCommand(), args: ['run', 'prove:adapters'] },
|
|
28
|
-
{ command: npmCommand(), args: ['run', 'prove:automation'] },
|
|
29
|
-
{ command: npmCommand(), args: ['run', 'prove:claim-verification'] },
|
|
30
|
-
{ command: npmCommand(), args: ['run', 'prove:cloudflare-sandbox'] },
|
|
31
|
-
{ command: npmCommand(), args: ['run', 'prove:data-pipeline'] },
|
|
32
|
-
{ command: npmCommand(), args: ['run', 'prove:evolution'] },
|
|
33
|
-
{ command: npmCommand(), args: ['run', 'prove:harnesses'] },
|
|
34
|
-
{ command: npmCommand(), args: ['run', 'prove:local-intelligence'] },
|
|
35
|
-
{ command: npmCommand(), args: ['run', 'prove:predictive-insights'] },
|
|
36
|
-
{ command: npmCommand(), args: ['run', 'prove:runtime'] },
|
|
37
|
-
{ command: npmCommand(), args: ['run', 'prove:settings'] },
|
|
38
|
-
{ command: npmCommand(), args: ['run', 'prove:seo-gsd'] },
|
|
39
|
-
{ command: npmCommand(), args: ['run', 'prove:tessl'] },
|
|
40
|
-
{ command: npmCommand(), args: ['run', 'prove:xmemory'] },
|
|
41
|
-
{ command: npmCommand(), args: ['run', 'self-heal:check'] },
|
|
42
|
-
];
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
throw new Error(`Unsupported verify mode: ${mode}`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function runPlan(plan, env = process.env, cwd = process.cwd()) {
|
|
49
|
-
for (const step of plan) {
|
|
50
|
-
console.log(`$ ${step.command} ${step.args.join(' ')}`.trim());
|
|
51
|
-
const result = spawnSync(step.command, step.args, {
|
|
52
|
-
cwd,
|
|
53
|
-
env,
|
|
54
|
-
stdio: 'inherit',
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
if (result.status !== 0) {
|
|
58
|
-
const joined = [step.command, ...step.args].join(' ');
|
|
59
|
-
throw new Error(`Verification failed: ${joined}`);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function copyArtifactIfPresent(sourcePath, targetPath) {
|
|
65
|
-
if (!fs.existsSync(sourcePath)) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
70
|
-
fs.copyFileSync(sourcePath, targetPath);
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function materializeProofArtifacts(tempRoot, cwd = process.cwd()) {
|
|
75
|
-
const artifacts = [
|
|
76
|
-
{
|
|
77
|
-
source: path.join(tempRoot, 'proof-adapters', 'report.json'),
|
|
78
|
-
target: path.join(cwd, 'proof', 'compatibility', 'report.json'),
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
source: path.join(tempRoot, 'proof-adapters', 'report.md'),
|
|
82
|
-
target: path.join(cwd, 'proof', 'compatibility', 'report.md'),
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
source: path.join(tempRoot, 'proof-automation', 'report.json'),
|
|
86
|
-
target: path.join(cwd, 'proof', 'automation', 'report.json'),
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
source: path.join(tempRoot, 'proof-automation', 'report.md'),
|
|
90
|
-
target: path.join(cwd, 'proof', 'automation', 'report.md'),
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
source: path.join(tempRoot, 'proof-adapters', 'cloudflare-sandbox-report.json'),
|
|
94
|
-
target: path.join(cwd, 'proof', 'cloudflare-sandbox-report.json'),
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
source: path.join(tempRoot, 'proof-adapters', 'cloudflare-sandbox-report.md'),
|
|
98
|
-
target: path.join(cwd, 'proof', 'cloudflare-sandbox-report.md'),
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
source: path.join(tempRoot, 'proof-adapters', 'claim-verification-report.json'),
|
|
102
|
-
target: path.join(cwd, 'proof', 'claim-verification-report.json'),
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
source: path.join(tempRoot, 'proof-adapters', 'claim-verification-report.md'),
|
|
106
|
-
target: path.join(cwd, 'proof', 'claim-verification-report.md'),
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
source: path.join(tempRoot, 'proof-adapters', 'data-pipeline-report.json'),
|
|
110
|
-
target: path.join(cwd, 'proof', 'data-pipeline-report.json'),
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
source: path.join(tempRoot, 'proof-adapters', 'data-pipeline-report.md'),
|
|
114
|
-
target: path.join(cwd, 'proof', 'data-pipeline-report.md'),
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
source: path.join(tempRoot, 'proof-adapters', 'evolution-report.json'),
|
|
118
|
-
target: path.join(cwd, 'proof', 'evolution-report.json'),
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
source: path.join(tempRoot, 'proof-adapters', 'evolution-report.md'),
|
|
122
|
-
target: path.join(cwd, 'proof', 'evolution-report.md'),
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
source: path.join(tempRoot, 'proof-harnesses', 'harnesses-report.json'),
|
|
126
|
-
target: path.join(cwd, 'proof', 'harnesses-report.json'),
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
source: path.join(tempRoot, 'proof-harnesses', 'harnesses-report.md'),
|
|
130
|
-
target: path.join(cwd, 'proof', 'harnesses-report.md'),
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
source: path.join(tempRoot, 'proof-adapters', 'local-intelligence-report.json'),
|
|
134
|
-
target: path.join(cwd, 'proof', 'local-intelligence-report.json'),
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
source: path.join(tempRoot, 'proof-adapters', 'local-intelligence-report.md'),
|
|
138
|
-
target: path.join(cwd, 'proof', 'local-intelligence-report.md'),
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
source: path.join(tempRoot, 'proof-adapters', 'predictive-insights-report.json'),
|
|
142
|
-
target: path.join(cwd, 'proof', 'predictive-insights-report.json'),
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
source: path.join(tempRoot, 'proof-adapters', 'predictive-insights-report.md'),
|
|
146
|
-
target: path.join(cwd, 'proof', 'predictive-insights-report.md'),
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
source: path.join(tempRoot, 'proof-runtime', 'runtime-report.json'),
|
|
150
|
-
target: path.join(cwd, 'proof', 'runtime-report.json'),
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
source: path.join(tempRoot, 'proof-runtime', 'runtime-report.md'),
|
|
154
|
-
target: path.join(cwd, 'proof', 'runtime-report.md'),
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
source: path.join(tempRoot, 'proof-settings', 'settings-report.json'),
|
|
158
|
-
target: path.join(cwd, 'proof', 'settings-report.json'),
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
source: path.join(tempRoot, 'proof-settings', 'settings-report.md'),
|
|
162
|
-
target: path.join(cwd, 'proof', 'settings-report.md'),
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
source: path.join(tempRoot, 'proof-adapters', 'seo-gsd-report.json'),
|
|
166
|
-
target: path.join(cwd, 'proof', 'seo-gsd-report.json'),
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
source: path.join(tempRoot, 'proof-adapters', 'seo-gsd-report.md'),
|
|
170
|
-
target: path.join(cwd, 'proof', 'seo-gsd-report.md'),
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
source: path.join(tempRoot, 'proof-adapters', 'tessl-report.json'),
|
|
174
|
-
target: path.join(cwd, 'proof', 'tessl-report.json'),
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
source: path.join(tempRoot, 'proof-adapters', 'tessl-report.md'),
|
|
178
|
-
target: path.join(cwd, 'proof', 'tessl-report.md'),
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
source: path.join(tempRoot, 'proof-adapters', 'xmemory-report.json'),
|
|
182
|
-
target: path.join(cwd, 'proof', 'xmemory-report.json'),
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
source: path.join(tempRoot, 'proof-adapters', 'xmemory-report.md'),
|
|
186
|
-
target: path.join(cwd, 'proof', 'xmemory-report.md'),
|
|
187
|
-
},
|
|
188
|
-
];
|
|
189
|
-
|
|
190
|
-
return artifacts
|
|
191
|
-
.filter(({ source, target }) => copyArtifactIfPresent(source, target))
|
|
192
|
-
.map(({ target }) => target);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
function recordVerifyWorkflowRun(mode = 'quick', cwd = process.cwd(), feedbackDir = undefined) {
|
|
196
|
-
if (mode !== 'full') return null;
|
|
197
|
-
return appendWorkflowRun({
|
|
198
|
-
workflowId: 'repo_self_dogfood_full_verify',
|
|
199
|
-
workflowName: 'Repo self dogfood full verification',
|
|
200
|
-
owner: 'cto',
|
|
201
|
-
runtime: 'node',
|
|
202
|
-
status: 'passed',
|
|
203
|
-
customerType: 'internal_dogfood',
|
|
204
|
-
teamId: 'internal_repo',
|
|
205
|
-
reviewed: true,
|
|
206
|
-
reviewedBy: 'automation',
|
|
207
|
-
proofBacked: true,
|
|
208
|
-
source: 'verify:full',
|
|
209
|
-
proofArtifacts: [
|
|
210
|
-
path.join(cwd, 'docs', 'VERIFICATION_EVIDENCE.md'),
|
|
211
|
-
path.join(cwd, 'proof', 'compatibility', 'report.json'),
|
|
212
|
-
path.join(cwd, 'proof', 'automation', 'report.json'),
|
|
213
|
-
path.join(cwd, 'proof', 'cloudflare-sandbox-report.json'),
|
|
214
|
-
path.join(cwd, 'proof', 'claim-verification-report.json'),
|
|
215
|
-
path.join(cwd, 'proof', 'data-pipeline-report.json'),
|
|
216
|
-
path.join(cwd, 'proof', 'evolution-report.json'),
|
|
217
|
-
path.join(cwd, 'proof', 'harnesses-report.json'),
|
|
218
|
-
path.join(cwd, 'proof', 'local-intelligence-report.json'),
|
|
219
|
-
path.join(cwd, 'proof', 'predictive-insights-report.json'),
|
|
220
|
-
path.join(cwd, 'proof', 'runtime-report.json'),
|
|
221
|
-
path.join(cwd, 'proof', 'settings-report.json'),
|
|
222
|
-
path.join(cwd, 'proof', 'seo-gsd-report.json'),
|
|
223
|
-
path.join(cwd, 'proof', 'tessl-report.json'),
|
|
224
|
-
path.join(cwd, 'proof', 'xmemory-report.json'),
|
|
225
|
-
],
|
|
226
|
-
metadata: {
|
|
227
|
-
suite: 'repo_verify_full',
|
|
228
|
-
},
|
|
229
|
-
}, feedbackDir);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function runVerify(mode = 'quick', baseEnv = process.env, cwd = process.cwd()) {
|
|
233
|
-
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-verify-'));
|
|
234
|
-
const env = {
|
|
235
|
-
...baseEnv,
|
|
236
|
-
THUMBGATE_PROOF_DIR: path.join(tempRoot, 'proof-adapters'),
|
|
237
|
-
THUMBGATE_AUTOMATION_PROOF_DIR: path.join(tempRoot, 'proof-automation'),
|
|
238
|
-
THUMBGATE_HARNESSES_PROOF_DIR: path.join(tempRoot, 'proof-harnesses'),
|
|
239
|
-
THUMBGATE_RUNTIME_PROOF_DIR: path.join(tempRoot, 'proof-runtime'),
|
|
240
|
-
THUMBGATE_SETTINGS_PROOF_DIR: path.join(tempRoot, 'proof-settings'),
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
runPlan(buildVerifyPlan(mode), env, cwd);
|
|
244
|
-
materializeProofArtifacts(tempRoot, cwd);
|
|
245
|
-
const workflowRun = recordVerifyWorkflowRun(mode, cwd);
|
|
246
|
-
|
|
247
|
-
return {
|
|
248
|
-
mode,
|
|
249
|
-
tempRoot,
|
|
250
|
-
workflowRun,
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
if (require.main === module) {
|
|
255
|
-
try {
|
|
256
|
-
runVerify(process.argv[2] || 'quick');
|
|
257
|
-
} catch (error) {
|
|
258
|
-
console.error(error.message);
|
|
259
|
-
process.exit(1);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
module.exports = {
|
|
264
|
-
buildVerifyPlan,
|
|
265
|
-
materializeProofArtifacts,
|
|
266
|
-
recordVerifyWorkflowRun,
|
|
267
|
-
runPlan,
|
|
268
|
-
runVerify,
|
|
269
|
-
};
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Weekly Auto-Post — build-in-public experiment loop.
|
|
6
|
-
*
|
|
7
|
-
* Every week, auto-generates a social post from ThumbGate stats
|
|
8
|
-
* ("X mistakes blocked, Y hours saved") and posts to configured platforms.
|
|
9
|
-
* Closes the deploy → measure → share → compound loop.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const fs = require('fs');
|
|
13
|
-
const path = require('path');
|
|
14
|
-
const os = require('os');
|
|
15
|
-
const { generateWeeklyStatsPost } = require('./daily-digest');
|
|
16
|
-
const { createSchedule } = require('./schedule-manager');
|
|
17
|
-
const { ensureDir } = require('./fs-utils');
|
|
18
|
-
|
|
19
|
-
const POSTS_DIR = path.join(os.homedir(), '.thumbgate', 'weekly-posts');
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Generate a weekly stats post file in post-everywhere format.
|
|
24
|
-
* Returns the file path.
|
|
25
|
-
*/
|
|
26
|
-
function generateWeeklyPostFile({ periodDays = 7 } = {}) {
|
|
27
|
-
const { post, stats } = generateWeeklyStatsPost({ periodDays });
|
|
28
|
-
|
|
29
|
-
const date = new Date().toISOString().slice(0, 10);
|
|
30
|
-
const filename = `weekly-stats-${date}.md`;
|
|
31
|
-
|
|
32
|
-
// Build post-everywhere compatible frontmatter
|
|
33
|
-
const content = [
|
|
34
|
-
'---',
|
|
35
|
-
`title: ThumbGate Weekly Stats — ${date}`,
|
|
36
|
-
'platform: x',
|
|
37
|
-
`tags: thumbgate, ai-agents, build-in-public`,
|
|
38
|
-
'---',
|
|
39
|
-
'',
|
|
40
|
-
post,
|
|
41
|
-
'',
|
|
42
|
-
'#ThumbGate #AIAgents #BuildInPublic',
|
|
43
|
-
].join('\n');
|
|
44
|
-
|
|
45
|
-
ensureDir(POSTS_DIR);
|
|
46
|
-
const filePath = path.join(POSTS_DIR, filename);
|
|
47
|
-
fs.writeFileSync(filePath, content);
|
|
48
|
-
|
|
49
|
-
return { filePath, filename, post, stats, date };
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Generate and post weekly stats. Full pipeline.
|
|
54
|
-
* If dryRun is true, generates the file but doesn't post.
|
|
55
|
-
*/
|
|
56
|
-
async function runWeeklyPost({ periodDays = 7, platforms, dryRun = false } = {}) {
|
|
57
|
-
const generated = generateWeeklyPostFile({ periodDays });
|
|
58
|
-
|
|
59
|
-
let postResult = null;
|
|
60
|
-
let zernioResult = null;
|
|
61
|
-
|
|
62
|
-
if (!dryRun) {
|
|
63
|
-
// Primary: Zernio API (posts to all connected platforms — X, LinkedIn, Instagram, TikTok)
|
|
64
|
-
try {
|
|
65
|
-
const { publishToAllPlatforms } = require('./social-analytics/publishers/zernio');
|
|
66
|
-
zernioResult = await publishToAllPlatforms(generated.post);
|
|
67
|
-
} catch (err) {
|
|
68
|
-
zernioResult = { error: err.message };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Fallback: post-everywhere (if Zernio fails or specific platforms needed)
|
|
72
|
-
if (zernioResult && zernioResult.error && platforms) {
|
|
73
|
-
try {
|
|
74
|
-
const { postEverywhere } = require('./post-everywhere');
|
|
75
|
-
postResult = await postEverywhere(generated.filePath, { platforms, dryRun });
|
|
76
|
-
} catch (err) {
|
|
77
|
-
postResult = { error: err.message };
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return {
|
|
83
|
-
generated,
|
|
84
|
-
posted: !dryRun,
|
|
85
|
-
zernioResult,
|
|
86
|
-
postResult,
|
|
87
|
-
dryRun,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Create a weekly schedule for auto-posting.
|
|
93
|
-
* Default: every Monday at 10:00 AM.
|
|
94
|
-
*/
|
|
95
|
-
function createWeeklyPostSchedule({ day = 'monday', time = '10:00', dryRun = false } = {}) {
|
|
96
|
-
const command = [
|
|
97
|
-
`const wp = require(${JSON.stringify(__filename)});`,
|
|
98
|
-
`wp.runWeeklyPost(${JSON.stringify({ dryRun })})`,
|
|
99
|
-
'.then(r => { process.stdout.write(JSON.stringify(r, null, 2) + "\\n"); })',
|
|
100
|
-
'.catch(e => { process.stderr.write(e.message + "\\n"); process.exit(1); });',
|
|
101
|
-
].join(' ');
|
|
102
|
-
|
|
103
|
-
return createSchedule({
|
|
104
|
-
id: 'thumbgate-weekly-post',
|
|
105
|
-
name: 'ThumbGate Weekly Build-in-Public Post',
|
|
106
|
-
description: `Weekly stats post every ${day} at ${time}`,
|
|
107
|
-
schedule: `weekly ${day} ${time}`,
|
|
108
|
-
command,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* List all generated weekly post files.
|
|
114
|
-
*/
|
|
115
|
-
function listWeeklyPosts() {
|
|
116
|
-
ensureDir(POSTS_DIR);
|
|
117
|
-
return fs.readdirSync(POSTS_DIR)
|
|
118
|
-
.filter((f) => f.endsWith('.md'))
|
|
119
|
-
.sort()
|
|
120
|
-
.reverse()
|
|
121
|
-
.map((f) => ({ filename: f, path: path.join(POSTS_DIR, f), date: f.match(/\d{4}-\d{2}-\d{2}/)?.[0] || null }));
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
module.exports = { generateWeeklyPostFile, runWeeklyPost, createWeeklyPostSchedule, listWeeklyPosts, POSTS_DIR };
|