thumbgate 0.9.9 → 0.9.11
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/README.md +4 -4
- package/.claude-plugin/marketplace.json +4 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.well-known/mcp/server-card.json +1 -1
- package/README.md +115 -312
- package/adapters/README.md +2 -2
- package/adapters/amp/skills/{rlhf-feedback → thumbgate-feedback}/SKILL.md +1 -1
- package/adapters/chatgpt/openapi.yaml +2 -2
- package/adapters/claude/.mcp.json +3 -3
- package/adapters/codex/config.toml +4 -4
- package/adapters/gemini/function-declarations.json +1 -1
- package/adapters/mcp/server-stdio.js +66 -6
- package/adapters/opencode/opencode.json +4 -2
- package/bin/cli.js +188 -39
- package/config/e2e-critical-flows.json +4 -0
- package/config/gates/default.json +74 -2
- package/config/github-about.json +1 -1
- package/config/mcp-allowlists.json +33 -6
- package/config/skill-packs/react-testing.json +1 -1
- package/config/tessl-tiles.json +3 -3
- package/openapi/openapi.yaml +2 -2
- package/package.json +23 -9
- package/plugins/amp-skill/INSTALL.md +3 -2
- package/plugins/amp-skill/SKILL.md +1 -0
- package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +1 -1
- package/plugins/claude-codex-bridge/.mcp.json +5 -3
- package/plugins/claude-codex-bridge/README.md +1 -1
- package/plugins/claude-codex-bridge/skills/setup/SKILL.md +1 -1
- package/plugins/claude-skill/INSTALL.md +4 -3
- package/plugins/claude-skill/SKILL.md +1 -1
- package/plugins/codex-profile/.codex-plugin/plugin.json +1 -1
- package/plugins/codex-profile/.mcp.json +5 -3
- package/plugins/codex-profile/INSTALL.md +2 -2
- package/plugins/codex-profile/README.md +1 -1
- package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +1 -1
- package/plugins/cursor-marketplace/README.md +5 -5
- package/plugins/cursor-marketplace/mcp.json +4 -2
- package/plugins/cursor-marketplace/rules/pre-action-gates.mdc +1 -1
- package/plugins/cursor-marketplace/scripts/gate-check.sh +15 -5
- package/plugins/gemini-extension/INSTALL.md +4 -4
- package/plugins/opencode-profile/INSTALL.md +5 -5
- package/public/dashboard.html +15 -8
- package/public/index.html +134 -375
- package/public/js/buyer-intent.js +252 -0
- package/public/pro.html +1085 -0
- package/scripts/__pycache__/train_from_feedback.cpython-312.pyc +0 -0
- package/scripts/adk-consolidator.js +17 -5
- package/scripts/agent-readiness.js +3 -1
- package/scripts/agent-security-hardening.js +4 -4
- package/scripts/auto-promote-gates.js +8 -0
- package/scripts/auto-wire-hooks.js +105 -21
- package/scripts/billing.js +111 -7
- package/scripts/build-metadata.js +14 -0
- package/scripts/check-congruence.js +1 -1
- package/scripts/context-engine.js +2 -1
- package/scripts/daemon-manager.js +2 -2
- package/scripts/dashboard.js +2 -2
- package/scripts/data-governance.js +1 -1
- package/scripts/deploy-gcp.sh +1 -1
- package/scripts/deploy-policy.js +22 -4
- package/scripts/dispatch-brief.js +1 -1
- package/scripts/ensure-repo-bootstrap.js +1 -1
- package/scripts/feedback-attribution.js +22 -10
- package/scripts/feedback-fallback.js +3 -2
- package/scripts/feedback-inbox-read.js +1 -1
- package/scripts/feedback-loop.js +41 -3
- package/scripts/feedback-paths.js +8 -8
- package/scripts/feedback-schema.js +1 -1
- package/scripts/feedback-to-memory.js +2 -2
- package/scripts/filesystem-search.js +2 -2
- package/scripts/gates-engine.js +765 -34
- package/scripts/generate-paperbanana-diagrams.sh +3 -3
- package/scripts/github-about.js +1 -1
- package/scripts/gtm-revenue-loop.js +20 -1
- package/scripts/hook-runtime.js +89 -0
- package/scripts/hook-stop-self-score.sh +3 -3
- package/scripts/hook-thumbgate-cache-updater.js +98 -37
- package/scripts/hosted-config.js +12 -10
- package/scripts/hybrid-feedback-context.js +54 -13
- package/scripts/install-mcp.js +14 -1
- package/scripts/intent-router.js +1 -1
- package/scripts/internal-agent-bootstrap.js +1 -1
- package/scripts/lesson-inference.js +6 -1
- package/scripts/license.js +54 -16
- package/scripts/mcp-config.js +69 -7
- package/scripts/memory-migration.js +1 -1
- package/scripts/money-watcher.js +166 -16
- package/scripts/operational-integrity.js +480 -0
- package/scripts/optimize-context.js +1 -1
- package/scripts/perplexity-marketing.js +1 -1
- package/scripts/post-everywhere.js +7 -12
- package/scripts/post-to-x.js +1 -1
- package/scripts/pr-manager.js +14 -11
- package/scripts/problem-detail.js +10 -10
- package/scripts/profile-router.js +2 -0
- package/scripts/prompt-dlp.js +1 -0
- package/scripts/prove-adapters.js +6 -6
- package/scripts/prove-automation.js +1 -1
- package/scripts/prove-autoresearch.js +1 -1
- package/scripts/prove-claim-verification.js +3 -3
- package/scripts/prove-data-pipeline.js +5 -5
- package/scripts/prove-data-quality.js +1 -1
- package/scripts/prove-evolution.js +7 -7
- package/scripts/prove-harnesses.js +2 -2
- package/scripts/prove-lancedb.js +2 -2
- package/scripts/prove-local-intelligence.js +1 -1
- package/scripts/prove-loop-closure.js +1 -1
- package/scripts/prove-predictive-insights.js +2 -2
- package/scripts/prove-runtime.js +6 -6
- package/scripts/prove-seo-gsd.js +1 -1
- package/scripts/prove-settings.js +4 -4
- package/scripts/prove-subway-upgrades.js +1 -1
- package/scripts/prove-tessl.js +2 -2
- package/scripts/prove-xmemory.js +2 -2
- package/scripts/publish-decision.js +10 -0
- package/scripts/published-cli.js +34 -0
- package/scripts/rate-limiter.js +2 -2
- package/scripts/reddit-monitor-cron.sh +2 -2
- package/scripts/reminder-engine.js +1 -1
- package/scripts/schedule-manager.js +3 -3
- package/scripts/self-healing-check.js +1 -1
- package/scripts/shieldcortex-memory-firewall-runner.mjs +1 -1
- package/scripts/skill-quality-tracker.js +1 -1
- package/scripts/social-analytics/db/social-analytics.db-shm +0 -0
- package/scripts/social-analytics/db/social-analytics.db-wal +0 -0
- package/scripts/social-analytics/engagement-audit.js +202 -0
- package/scripts/social-analytics/generate-instagram-card.js +1 -1
- package/scripts/social-analytics/instagram-thumbgate-post.js +5 -1
- package/scripts/social-analytics/install-growth-automation.js +114 -0
- package/scripts/social-analytics/publish-instagram-thumbgate.js +8 -2
- package/scripts/social-analytics/publish-thumbgate-launch.js +1 -1
- package/scripts/social-analytics/publishers/reddit.js +7 -12
- package/scripts/social-analytics/publishers/zernio.js +19 -0
- package/scripts/social-analytics/reconcile-thumbgate-campaign.js +165 -0
- package/scripts/social-analytics/schedule-thumbgate-campaign.js +275 -0
- package/scripts/social-analytics/sync-launch-assets.js +185 -0
- package/scripts/social-pipeline.js +2 -2
- package/scripts/social-post-hourly.js +185 -0
- package/scripts/social-quality-gate.js +119 -3
- package/scripts/social-reply-monitor.js +150 -34
- package/scripts/statusline-cache-path.js +27 -0
- package/scripts/statusline-meta.js +22 -0
- package/scripts/statusline.sh +24 -32
- package/scripts/sync-version.js +24 -12
- package/scripts/telemetry-analytics.js +4 -4
- package/scripts/tessl-export.js +1 -1
- package/scripts/test-coverage.js +20 -13
- package/scripts/thumbgate-search.js +2 -2
- package/scripts/tool-registry.js +98 -1
- package/scripts/train_from_feedback.py +1 -1
- package/scripts/user-profile.js +4 -4
- package/scripts/validate-feedback.js +1 -1
- package/scripts/vector-store.js +1 -1
- package/scripts/verification-loop.js +1 -1
- package/scripts/verify-run.js +1 -1
- package/scripts/weekly-auto-post.js +1 -1
- package/skills/{rlhf-feedback → thumbgate-feedback}/SKILL.md +1 -1
- package/src/api/server.js +291 -41
- package/scripts/__pycache__/train_from_feedback.cpython-314.pyc +0 -0
- package/scripts/social-analytics/db/social-analytics.db +0 -0
|
@@ -37,7 +37,7 @@ function parseLeadingJson(text) {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
function initGitRepo() {
|
|
40
|
-
const repoPath = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
40
|
+
const repoPath = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-proof-repo-'));
|
|
41
41
|
execFileSync('git', ['init', '-b', 'main'], { cwd: repoPath, stdio: 'ignore' });
|
|
42
42
|
execFileSync('git', ['config', 'user.name', 'ThumbGate Proof'], { cwd: repoPath, stdio: 'ignore' });
|
|
43
43
|
execFileSync('git', ['config', 'user.email', 'proof@example.com'], { cwd: repoPath, stdio: 'ignore' });
|
|
@@ -189,7 +189,7 @@ async function runProof(options = {}) {
|
|
|
189
189
|
ensureDir(proofDir);
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
const tmpFeedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
192
|
+
const tmpFeedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-proof-'));
|
|
193
193
|
const previousFeedbackDir = process.env.THUMBGATE_FEEDBACK_DIR;
|
|
194
194
|
const previousApiKey = process.env.THUMBGATE_API_KEY;
|
|
195
195
|
const previousMcpProfile = process.env.THUMBGATE_MCP_PROFILE;
|
|
@@ -298,7 +298,7 @@ async function runProof(options = {}) {
|
|
|
298
298
|
{
|
|
299
299
|
currentCheck = 'api.internal_agent.bootstrap';
|
|
300
300
|
const repoPath = initGitRepo();
|
|
301
|
-
const sandboxRoot = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
301
|
+
const sandboxRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-proof-bootstrap-'));
|
|
302
302
|
let sandboxPath = null;
|
|
303
303
|
|
|
304
304
|
try {
|
|
@@ -469,7 +469,7 @@ async function runProof(options = {}) {
|
|
|
469
469
|
|
|
470
470
|
{
|
|
471
471
|
currentCheck = 'mcp.cli.serve.bad_home.initialize';
|
|
472
|
-
const isolatedDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
472
|
+
const isolatedDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-proof-cli-serve-'));
|
|
473
473
|
const badHomePath = path.join(isolatedDir, 'invalid-home');
|
|
474
474
|
fs.writeFileSync(badHomePath, 'not-a-directory\n');
|
|
475
475
|
|
|
@@ -640,7 +640,7 @@ async function runProof(options = {}) {
|
|
|
640
640
|
{
|
|
641
641
|
currentCheck = 'mcp.tools.call.bootstrap_internal_agent';
|
|
642
642
|
const repoPath = initGitRepo();
|
|
643
|
-
const sandboxRoot = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
643
|
+
const sandboxRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-proof-mcp-bootstrap-'));
|
|
644
644
|
let sandboxPath = null;
|
|
645
645
|
|
|
646
646
|
try {
|
|
@@ -778,7 +778,7 @@ async function runProof(options = {}) {
|
|
|
778
778
|
'plugins/codex-profile/.codex-plugin/plugin.json',
|
|
779
779
|
'plugins/codex-profile/.mcp.json',
|
|
780
780
|
'.agents/plugins/marketplace.json',
|
|
781
|
-
'adapters/amp/skills/
|
|
781
|
+
'adapters/amp/skills/thumbgate-feedback/SKILL.md',
|
|
782
782
|
];
|
|
783
783
|
mustExist.forEach((file) => {
|
|
784
784
|
check(fs.existsSync(path.join(ROOT, file)), `missing adapter file: ${file}`);
|
|
@@ -59,7 +59,7 @@ async function runAutomationProof(options = {}) {
|
|
|
59
59
|
|
|
60
60
|
if (writeArtifacts) ensureDir(proofDir);
|
|
61
61
|
|
|
62
|
-
const tmpFeedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
62
|
+
const tmpFeedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-automation-proof-'));
|
|
63
63
|
const previousCodegraphStub = process.env.THUMBGATE_CODEGRAPH_STUB_RESPONSE;
|
|
64
64
|
process.env.THUMBGATE_FEEDBACK_DIR = tmpFeedbackDir;
|
|
65
65
|
process.env.THUMBGATE_API_KEY = 'automation-proof-key';
|
|
@@ -29,7 +29,7 @@ function resolveProofPaths() {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
async function run() {
|
|
32
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
32
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-autoresearch-proof-'));
|
|
33
33
|
const results = { passed: 0, failed: 0, requirements: {} };
|
|
34
34
|
const { proofDir, reportJson, reportMd } = resolveProofPaths();
|
|
35
35
|
|
|
@@ -30,8 +30,8 @@ async function withIsolatedRuntime(fn) {
|
|
|
30
30
|
const previousHome = process.env.HOME;
|
|
31
31
|
const previousFeedbackDir = process.env.THUMBGATE_FEEDBACK_DIR;
|
|
32
32
|
const previousNoRateLimit = process.env.THUMBGATE_NO_RATE_LIMIT;
|
|
33
|
-
const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
34
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
33
|
+
const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-claim-home-'));
|
|
34
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-claim-feedback-'));
|
|
35
35
|
|
|
36
36
|
process.env.HOME = homeDir;
|
|
37
37
|
process.env.THUMBGATE_FEEDBACK_DIR = feedbackDir;
|
|
@@ -183,7 +183,7 @@ async function run() {
|
|
|
183
183
|
desc: 'verify:full includes the claim-verification proof lane and artifact',
|
|
184
184
|
fn: async () => {
|
|
185
185
|
await withIsolatedRuntime(async ({ verifyRun, feedbackDir }) => {
|
|
186
|
-
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
186
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-claim-proof-cwd-'));
|
|
187
187
|
try {
|
|
188
188
|
const plan = verifyRun.buildVerifyPlan('full');
|
|
189
189
|
const commands = plan.map((step) => [step.command, ...(step.args || [])].join(' ')).join('\n');
|
|
@@ -160,7 +160,7 @@ async function run() {
|
|
|
160
160
|
desc: 'materializeAgenticDataPipeline builds raw, staging, semantic, and lineage layers from billing and telemetry inputs',
|
|
161
161
|
fn: async () => {
|
|
162
162
|
const { materializeAgenticDataPipeline } = loadFresh('./agentic-data-pipeline');
|
|
163
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
163
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-data-pipeline-proof-'));
|
|
164
164
|
try {
|
|
165
165
|
const snapshot = await materializeAgenticDataPipeline({
|
|
166
166
|
feedbackDir,
|
|
@@ -202,7 +202,7 @@ async function run() {
|
|
|
202
202
|
desc: 'pipeline reruns are idempotent and downgrade to noop when source hashes do not change',
|
|
203
203
|
fn: async () => {
|
|
204
204
|
const { materializeAgenticDataPipeline } = loadFresh('./agentic-data-pipeline');
|
|
205
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
205
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-data-pipeline-proof-'));
|
|
206
206
|
try {
|
|
207
207
|
const first = await materializeAgenticDataPipeline({
|
|
208
208
|
feedbackDir,
|
|
@@ -237,7 +237,7 @@ async function run() {
|
|
|
237
237
|
desc: 'reconciliation flags unreconciled paid events and telemetry coverage drift as warnings',
|
|
238
238
|
fn: async () => {
|
|
239
239
|
const { materializeAgenticDataPipeline } = loadFresh('./agentic-data-pipeline');
|
|
240
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
240
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-data-pipeline-proof-'));
|
|
241
241
|
try {
|
|
242
242
|
const snapshot = await materializeAgenticDataPipeline({
|
|
243
243
|
feedbackDir,
|
|
@@ -332,8 +332,8 @@ async function run() {
|
|
|
332
332
|
throw new Error('verify:full is missing prove:data-pipeline');
|
|
333
333
|
}
|
|
334
334
|
|
|
335
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
336
|
-
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
335
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-data-pipeline-proof-'));
|
|
336
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-data-pipeline-proof-cwd-'));
|
|
337
337
|
try {
|
|
338
338
|
const entry = recordVerifyWorkflowRun('full', cwd, feedbackDir);
|
|
339
339
|
if (!entry.proofArtifacts.some((artifact) => artifact.endsWith(path.join('proof', 'data-pipeline-report.json')))) {
|
|
@@ -30,7 +30,7 @@ function resolveProofPaths() {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function run() {
|
|
33
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
33
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-qual-proof-'));
|
|
34
34
|
const results = { passed: 0, failed: 0, requirements: {} };
|
|
35
35
|
const { proofDir, reportJson, reportMd } = resolveProofPaths();
|
|
36
36
|
|
|
@@ -93,7 +93,7 @@ async function run() {
|
|
|
93
93
|
id: 'EVOLVE-01',
|
|
94
94
|
desc: 'evolution-state loads defaults and captures rollback snapshots',
|
|
95
95
|
fn: () => {
|
|
96
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
96
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-evolution-proof-'));
|
|
97
97
|
try {
|
|
98
98
|
process.env.THUMBGATE_FEEDBACK_DIR = feedbackDir;
|
|
99
99
|
resetModules();
|
|
@@ -120,7 +120,7 @@ async function run() {
|
|
|
120
120
|
id: 'EVOLVE-02',
|
|
121
121
|
desc: 'workspace-evolver accepts improved candidates only when primary and holdout checks pass',
|
|
122
122
|
fn: () => {
|
|
123
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
123
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-evolution-proof-'));
|
|
124
124
|
try {
|
|
125
125
|
process.env.THUMBGATE_FEEDBACK_DIR = feedbackDir;
|
|
126
126
|
resetModules();
|
|
@@ -149,7 +149,7 @@ async function run() {
|
|
|
149
149
|
id: 'EVOLVE-03',
|
|
150
150
|
desc: 'restoreWorkspaceEvolution rolls accepted state back to the previous snapshot',
|
|
151
151
|
fn: () => {
|
|
152
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
152
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-evolution-proof-'));
|
|
153
153
|
try {
|
|
154
154
|
process.env.THUMBGATE_FEEDBACK_DIR = feedbackDir;
|
|
155
155
|
resetModules();
|
|
@@ -177,7 +177,7 @@ async function run() {
|
|
|
177
177
|
id: 'EVOLVE-04',
|
|
178
178
|
desc: 'autoresearch-runner delegates to workspace evolver and records research metadata plus rollback evidence',
|
|
179
179
|
fn: async () => {
|
|
180
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
180
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-evolution-proof-'));
|
|
181
181
|
try {
|
|
182
182
|
process.env.THUMBGATE_FEEDBACK_DIR = feedbackDir;
|
|
183
183
|
resetModules();
|
|
@@ -216,7 +216,7 @@ async function run() {
|
|
|
216
216
|
id: 'EVOLVE-05',
|
|
217
217
|
desc: 'async-job-runner follow-up experiments include a recommended evolution target and replay command',
|
|
218
218
|
fn: () => {
|
|
219
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
219
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-evolution-proof-'));
|
|
220
220
|
try {
|
|
221
221
|
process.env.THUMBGATE_FEEDBACK_DIR = feedbackDir;
|
|
222
222
|
resetModules();
|
|
@@ -258,8 +258,8 @@ async function run() {
|
|
|
258
258
|
throw new Error('verify:full is missing prove:evolution');
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
262
|
-
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
261
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-evolution-proof-feedback-'));
|
|
262
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-evolution-proof-cwd-'));
|
|
263
263
|
try {
|
|
264
264
|
const entry = recordVerifyWorkflowRun('full', cwd, feedbackDir);
|
|
265
265
|
if (!entry.proofArtifacts.some((artifact) => artifact.endsWith(path.join('proof', 'evolution-report.json')))) {
|
|
@@ -61,7 +61,7 @@ function makeAcceptedVerification() {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
async function withHarnessRuntime(callback) {
|
|
64
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
64
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-harness-proof-'));
|
|
65
65
|
process.env.THUMBGATE_FEEDBACK_DIR = feedbackDir;
|
|
66
66
|
try {
|
|
67
67
|
resetModules();
|
|
@@ -233,7 +233,7 @@ async function run() {
|
|
|
233
233
|
fn: async () => {
|
|
234
234
|
await withHarnessRuntime(({ verifyRun }) => {
|
|
235
235
|
const plan = verifyRun.buildVerifyPlan('full');
|
|
236
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
236
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-harness-run-'));
|
|
237
237
|
try {
|
|
238
238
|
const workflowRun = verifyRun.recordVerifyWorkflowRun('full', ROOT, feedbackDir);
|
|
239
239
|
if (!plan.some((step) => Array.isArray(step.args) && step.args.includes('prove:harnesses'))) {
|
package/scripts/prove-lancedb.js
CHANGED
|
@@ -84,7 +84,7 @@ async function runProof(options = {}) {
|
|
|
84
84
|
vec01Evidence =
|
|
85
85
|
`lancedb dir created at ${lanceDir}. ` +
|
|
86
86
|
`upsertFeedback() resolved, searchSimilar() returned ${results.length} result(s) ` +
|
|
87
|
-
`including proof-vec01. Table name:
|
|
87
|
+
`including proof-vec01. Table name: thumbgate_memories.`;
|
|
88
88
|
} else if (dirExists) {
|
|
89
89
|
vec01Status = 'fail';
|
|
90
90
|
vec01Evidence = `lancedb dir exists but searchSimilar() did not return proof-vec01. Got: ${JSON.stringify(results.map((r) => r.id))}`;
|
|
@@ -207,7 +207,7 @@ async function runProof(options = {}) {
|
|
|
207
207
|
vec04Evidence =
|
|
208
208
|
`searchSimilar() returned ${results2.length} result(s). ` +
|
|
209
209
|
`proof-vec01 present: ${hasVec01}. proof-vec04-b present: ${hasVec04b}. ` +
|
|
210
|
-
`API: searchSimilar(queryText, limit=10) returns vector-ranked rows from
|
|
210
|
+
`API: searchSimilar(queryText, limit=10) returns vector-ranked rows from thumbgate_memories table. ` +
|
|
211
211
|
`Note: stub embed (THUMBGATE_VECTOR_STUB_EMBED=true) returns identical 384-dim unit vectors — ` +
|
|
212
212
|
`ranking is insertion-order with stub, cosine similarity with real ONNX model.`;
|
|
213
213
|
} else {
|
|
@@ -39,7 +39,7 @@ async function main() {
|
|
|
39
39
|
const proofDir = DEFAULT_PROOF_DIR;
|
|
40
40
|
ensureDir(proofDir);
|
|
41
41
|
|
|
42
|
-
const tmpFeedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
42
|
+
const tmpFeedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-local-intel-'));
|
|
43
43
|
const report = {
|
|
44
44
|
generatedAt: new Date().toISOString(),
|
|
45
45
|
checks: [],
|
|
@@ -30,7 +30,7 @@ function resolveProofPaths() {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function run() {
|
|
33
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
33
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-loop-proof-'));
|
|
34
34
|
const results = { passed: 0, failed: 0, requirements: {} };
|
|
35
35
|
const { proofDir, reportJson, reportMd } = resolveProofPaths();
|
|
36
36
|
|
|
@@ -283,8 +283,8 @@ async function run() {
|
|
|
283
283
|
throw new Error('Expected verify:full to include prove:predictive-insights');
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
287
|
-
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
286
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-predictive-proof-'));
|
|
287
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-predictive-proof-cwd-'));
|
|
288
288
|
try {
|
|
289
289
|
const entry = recordVerifyWorkflowRun('full', cwd, feedbackDir);
|
|
290
290
|
if (!entry.proofArtifacts.some((artifact) => artifact.endsWith(path.join('proof', 'predictive-insights-report.json')))) {
|
package/scripts/prove-runtime.js
CHANGED
|
@@ -112,7 +112,7 @@ async function run() {
|
|
|
112
112
|
id: 'RUNTIME-01',
|
|
113
113
|
desc: 'stage execution persists checkpointed state and stage history',
|
|
114
114
|
fn: () => {
|
|
115
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
115
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-runtime-proof-'));
|
|
116
116
|
try {
|
|
117
117
|
const { runner } = loadRuntimeHarness(feedbackDir, () => makeAcceptedVerification());
|
|
118
118
|
runner.executeJob({
|
|
@@ -139,7 +139,7 @@ async function run() {
|
|
|
139
139
|
id: 'RUNTIME-02',
|
|
140
140
|
desc: 'pause requests yield a paused checkpoint and resume continues from the next stage',
|
|
141
141
|
fn: () => {
|
|
142
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
142
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-runtime-proof-'));
|
|
143
143
|
try {
|
|
144
144
|
const { runner } = loadRuntimeHarness(feedbackDir, () => makeAcceptedVerification());
|
|
145
145
|
const job = {
|
|
@@ -178,7 +178,7 @@ async function run() {
|
|
|
178
178
|
id: 'RUNTIME-03',
|
|
179
179
|
desc: 'managed job files auto-resume through resumeManagedJobs without manual stage reconstruction',
|
|
180
180
|
fn: () => {
|
|
181
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
181
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-runtime-proof-'));
|
|
182
182
|
try {
|
|
183
183
|
const { runner } = loadRuntimeHarness(feedbackDir, () => makeAcceptedVerification());
|
|
184
184
|
const jobFile = path.join(feedbackDir, 'managed-job.json');
|
|
@@ -210,7 +210,7 @@ async function run() {
|
|
|
210
210
|
id: 'RUNTIME-04',
|
|
211
211
|
desc: 'failed verification queues an auto-improvement experiment',
|
|
212
212
|
fn: () => {
|
|
213
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
213
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-runtime-proof-'));
|
|
214
214
|
try {
|
|
215
215
|
const { runner, experimentTracker } = loadRuntimeHarness(feedbackDir, () => makeRejectedVerification());
|
|
216
216
|
const result = runner.executeJob({
|
|
@@ -250,8 +250,8 @@ async function run() {
|
|
|
250
250
|
id: 'RUNTIME-06',
|
|
251
251
|
desc: 'verify-run full includes the runtime proof lane and artifact',
|
|
252
252
|
fn: () => {
|
|
253
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
254
|
-
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
253
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-runtime-proof-'));
|
|
254
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-runtime-proof-cwd-'));
|
|
255
255
|
try {
|
|
256
256
|
process.env.THUMBGATE_FEEDBACK_DIR = feedbackDir;
|
|
257
257
|
resetModules();
|
package/scripts/prove-seo-gsd.js
CHANGED
|
@@ -18,7 +18,7 @@ function resolveProofPaths() {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
async function run() {
|
|
21
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
21
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-seo-gsd-proof-'));
|
|
22
22
|
const results = { passed: 0, failed: 0, requirements: {} };
|
|
23
23
|
const { proofDir, reportJson, reportMd } = resolveProofPaths();
|
|
24
24
|
|
|
@@ -45,7 +45,7 @@ function writeJson(filePath, payload) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
function makeTempProject(structure = {}) {
|
|
48
|
-
const projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
48
|
+
const projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-settings-project-'));
|
|
49
49
|
for (const [relativePath, payload] of Object.entries(structure)) {
|
|
50
50
|
const fullPath = path.join(projectRoot, relativePath);
|
|
51
51
|
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
@@ -110,7 +110,7 @@ async function run() {
|
|
|
110
110
|
id: 'SETTINGS-01',
|
|
111
111
|
desc: 'managed > local > project > user > defaults precedence resolves correctly',
|
|
112
112
|
fn: () => {
|
|
113
|
-
const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
113
|
+
const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-settings-home-'));
|
|
114
114
|
const projectRoot = makeTempProject({
|
|
115
115
|
'config/thumbgate-settings.managed.json': { mcp: { defaultProfile: 'locked' } },
|
|
116
116
|
'.thumbgate/settings.json': { mcp: { defaultProfile: 'dispatch' } },
|
|
@@ -193,7 +193,7 @@ async function run() {
|
|
|
193
193
|
id: 'SETTINGS-05',
|
|
194
194
|
desc: 'dashboard and MCP surfaces expose settings status visibility',
|
|
195
195
|
fn: () => {
|
|
196
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
196
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-settings-dashboard-'));
|
|
197
197
|
const { generateDashboard } = require('./dashboard');
|
|
198
198
|
const dashboard = generateDashboard(feedbackDir);
|
|
199
199
|
const { TOOLS } = require('./tool-registry');
|
|
@@ -227,7 +227,7 @@ async function run() {
|
|
|
227
227
|
if (!plan.some((step) => Array.isArray(step.args) && step.args.includes('prove:settings'))) {
|
|
228
228
|
throw new Error('verify:full is missing prove:settings');
|
|
229
229
|
}
|
|
230
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
230
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-settings-proof-run-'));
|
|
231
231
|
try {
|
|
232
232
|
const workflowRun = recordVerifyWorkflowRun('full', ROOT, feedbackDir);
|
|
233
233
|
if (!workflowRun.proofArtifacts.some((artifact) => artifact.endsWith(path.join('proof', 'settings-report.json')))) {
|
|
@@ -67,7 +67,7 @@ function run() {
|
|
|
67
67
|
const vs = require(vsPath);
|
|
68
68
|
if (typeof vs.upsertFeedback !== 'function') throw new Error('upsertFeedback not exported');
|
|
69
69
|
if (typeof vs.searchSimilar !== 'function') throw new Error('searchSimilar not exported');
|
|
70
|
-
if (vs.TABLE_NAME !== '
|
|
70
|
+
if (vs.TABLE_NAME !== 'thumbgate_memories') throw new Error(`TABLE_NAME must be thumbgate_memories, got ${vs.TABLE_NAME}`);
|
|
71
71
|
|
|
72
72
|
// Run Jest tests
|
|
73
73
|
const out = execSync(
|
package/scripts/prove-tessl.js
CHANGED
|
@@ -24,7 +24,7 @@ function resolveProofPaths() {
|
|
|
24
24
|
|
|
25
25
|
async function run() {
|
|
26
26
|
const { proofDir, reportJson, reportMd } = resolveProofPaths();
|
|
27
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
27
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-tessl-proof-'));
|
|
28
28
|
const results = { passed: 0, failed: 0, requirements: {} };
|
|
29
29
|
|
|
30
30
|
const checks = [
|
|
@@ -41,7 +41,7 @@ async function run() {
|
|
|
41
41
|
if (tileNames.length !== 2) {
|
|
42
42
|
throw new Error('Expected exactly two first-party Tessl tiles');
|
|
43
43
|
}
|
|
44
|
-
if (!tileNames.includes('agent-memory') || !tileNames.includes('
|
|
44
|
+
if (!tileNames.includes('agent-memory') || !tileNames.includes('thumbgate-feedback')) {
|
|
45
45
|
throw new Error('High-ROI ThumbGate tiles missing from config');
|
|
46
46
|
}
|
|
47
47
|
},
|
package/scripts/prove-xmemory.js
CHANGED
|
@@ -22,7 +22,7 @@ function loadFresh(modulePath) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function setupTempFeedbackDir() {
|
|
25
|
-
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
25
|
+
const feedbackDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-xmemory-proof-'));
|
|
26
26
|
process.env.THUMBGATE_FEEDBACK_DIR = feedbackDir;
|
|
27
27
|
return feedbackDir;
|
|
28
28
|
}
|
|
@@ -243,7 +243,7 @@ async function run() {
|
|
|
243
243
|
throw new Error('verify:full is missing prove:xmemory');
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), '
|
|
246
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-xmemory-proof-cwd-'));
|
|
247
247
|
try {
|
|
248
248
|
const entry = recordVerifyWorkflowRun('full', cwd, feedbackDir);
|
|
249
249
|
if (!entry.proofArtifacts.some((artifact) => artifact.endsWith(path.join('proof', 'xmemory-report.json')))) {
|
|
@@ -9,6 +9,8 @@ function decidePublishPlan(options) {
|
|
|
9
9
|
const currentSha = String(options.currentSha || '').trim();
|
|
10
10
|
const tagSha = String(options.tagSha || '').trim();
|
|
11
11
|
const version = String(options.version || '').trim();
|
|
12
|
+
const currentBranch = String(options.currentBranch || '').trim();
|
|
13
|
+
const defaultBranch = String(options.defaultBranch || '').trim();
|
|
12
14
|
const published = normalizeBoolean(options.published);
|
|
13
15
|
const tagExists = normalizeBoolean(options.tagExists);
|
|
14
16
|
const tagMatchesCurrentCommit = tagExists && tagSha === currentSha;
|
|
@@ -21,6 +23,12 @@ function decidePublishPlan(options) {
|
|
|
21
23
|
throw new Error('CURRENT_SHA is required.');
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
if (currentBranch && defaultBranch && currentBranch !== defaultBranch) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
`Refusing to publish from ${currentBranch}. Publish workflow must run from ${defaultBranch}.`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
24
32
|
if (published && !tagExists) {
|
|
25
33
|
throw new Error(
|
|
26
34
|
`Version ${version} is already published on npm but has no remote tag. Recover from the original release commit or bump the version.`
|
|
@@ -106,6 +114,8 @@ function runCli(env = process.env) {
|
|
|
106
114
|
const plan = decidePublishPlan({
|
|
107
115
|
version: env.VERSION,
|
|
108
116
|
currentSha: env.CURRENT_SHA || env.GITHUB_SHA,
|
|
117
|
+
currentBranch: env.CURRENT_BRANCH || env.GITHUB_REF_NAME,
|
|
118
|
+
defaultBranch: env.DEFAULT_BRANCH,
|
|
109
119
|
published: env.NPM_PUBLISHED,
|
|
110
120
|
tagExists: env.TAG_EXISTS,
|
|
111
121
|
tagSha: env.TAG_SHA,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { execFileSync } = require('child_process');
|
|
7
|
+
|
|
8
|
+
function publishedCliArgs(pkgVersion, commandArgs = []) {
|
|
9
|
+
return ['--yes', '--package', `thumbgate@${pkgVersion}`, 'thumbgate', ...commandArgs];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function runPublishedCli(pkgVersion, commandArgs = [], options = {}) {
|
|
13
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'thumbgate-published-cli-'));
|
|
14
|
+
try {
|
|
15
|
+
return execFileSync('npx', publishedCliArgs(pkgVersion, commandArgs), {
|
|
16
|
+
encoding: 'utf8',
|
|
17
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
18
|
+
timeout: options.timeout || 8000,
|
|
19
|
+
cwd: tmpDir,
|
|
20
|
+
});
|
|
21
|
+
} finally {
|
|
22
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function runPublishedCliHelp(pkgVersion, options = {}) {
|
|
27
|
+
return runPublishedCli(pkgVersion, ['help'], options);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
publishedCliArgs,
|
|
32
|
+
runPublishedCli,
|
|
33
|
+
runPublishedCliHelp,
|
|
34
|
+
};
|
package/scripts/rate-limiter.js
CHANGED
|
@@ -7,12 +7,12 @@ const {
|
|
|
7
7
|
PRO_MONTHLY_PAYMENT_LINK,
|
|
8
8
|
} = require('./commercial-offer');
|
|
9
9
|
|
|
10
|
-
const USAGE_FILE = path.join(process.env.HOME || '/tmp', '.
|
|
10
|
+
const USAGE_FILE = path.join(process.env.HOME || '/tmp', '.thumbgate', 'usage-limits.json');
|
|
11
11
|
|
|
12
12
|
const FREE_TIER_LIMITS = {
|
|
13
13
|
capture_feedback: { daily: Infinity, label: 'feedback captures' },
|
|
14
14
|
search_lessons: { daily: 5, label: 'lesson searches' },
|
|
15
|
-
|
|
15
|
+
search_thumbgate: { daily: 10, label: 'ThumbGate searches' },
|
|
16
16
|
commerce_recall: { daily: 5, label: 'commerce recalls' },
|
|
17
17
|
export_dpo: { daily: 0, label: 'DPO exports (Pro only)' },
|
|
18
18
|
export_databricks: { daily: 0, label: 'Databricks exports (Pro only)' },
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
|
-
REPO_DIR="/Users/igorganapolsky/workspace/git/igor/
|
|
4
|
+
REPO_DIR="/Users/igorganapolsky/workspace/git/igor/thumbgate"
|
|
5
5
|
LOG_FILE="${REPO_DIR}/.thumbgate/reddit-monitor.log"
|
|
6
6
|
|
|
7
|
-
mkdir -p "${REPO_DIR}/.
|
|
7
|
+
mkdir -p "${REPO_DIR}/.thumbgate"
|
|
8
8
|
|
|
9
9
|
# Load environment
|
|
10
10
|
if [ -f "${REPO_DIR}/.env" ]; then
|
|
@@ -4,7 +4,7 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
6
|
const PROJECT_ROOT = path.join(__dirname, '..');
|
|
7
|
-
const DEFAULT_STATE_PATH = path.join(PROJECT_ROOT, '.
|
|
7
|
+
const DEFAULT_STATE_PATH = path.join(PROJECT_ROOT, '.thumbgate', 'reminder-state.json');
|
|
8
8
|
|
|
9
9
|
const REMINDER_TEMPLATES = {
|
|
10
10
|
guardrail_spike: 'Safety guardrails triggered {{count}} times. Re-apply rule: {{rule}}',
|
|
@@ -7,7 +7,7 @@ const os = require('os');
|
|
|
7
7
|
const { execSync } = require('child_process');
|
|
8
8
|
const { buildAgenticDataPipelineJobSpec } = require('./agentic-data-pipeline');
|
|
9
9
|
|
|
10
|
-
const SCHEDULES_DIR = path.join(os.homedir(), '.
|
|
10
|
+
const SCHEDULES_DIR = path.join(os.homedir(), '.thumbgate', 'schedules');
|
|
11
11
|
const PLIST_PREFIX = 'com.thumbgate.schedule';
|
|
12
12
|
|
|
13
13
|
function ensureDir() {
|
|
@@ -73,7 +73,7 @@ function generatePlist(schedule) {
|
|
|
73
73
|
}
|
|
74
74
|
intervalXml += ' </dict>';
|
|
75
75
|
|
|
76
|
-
const logDir = escapePlistString(path.join(os.homedir(), '.
|
|
76
|
+
const logDir = escapePlistString(path.join(os.homedir(), '.thumbgate', 'logs'));
|
|
77
77
|
const workingDirectory = escapePlistString(schedule.workingDirectory || os.homedir());
|
|
78
78
|
const command = escapePlistString(schedule.command);
|
|
79
79
|
const homeDir = escapePlistString(os.homedir());
|
|
@@ -192,7 +192,7 @@ function createSchedule(params) {
|
|
|
192
192
|
if (process.platform === 'darwin') {
|
|
193
193
|
const plistContent = generatePlist(schedule);
|
|
194
194
|
const plistPath = path.join(os.homedir(), 'Library', 'LaunchAgents', `${PLIST_PREFIX}.${id}.plist`);
|
|
195
|
-
const logDir = path.join(os.homedir(), '.
|
|
195
|
+
const logDir = path.join(os.homedir(), '.thumbgate', 'logs');
|
|
196
196
|
if (!fs.existsSync(logDir)) fs.mkdirSync(logDir, { recursive: true });
|
|
197
197
|
fs.mkdirSync(path.dirname(plistPath), { recursive: true });
|
|
198
198
|
|
|
@@ -51,7 +51,7 @@ function createCheckEnvironment(check) {
|
|
|
51
51
|
let cleanup = null;
|
|
52
52
|
|
|
53
53
|
if (check.useTempProofDir) {
|
|
54
|
-
const proofDir = fs.mkdtempSync(path.join(os.tmpdir(), `
|
|
54
|
+
const proofDir = fs.mkdtempSync(path.join(os.tmpdir(), `thumbgate-${check.name}-`));
|
|
55
55
|
environment.THUMBGATE_PROOF_DIR = proofDir;
|
|
56
56
|
if (check.name === 'prove_automation') {
|
|
57
57
|
environment.THUMBGATE_AUTOMATION_PROOF_DIR = proofDir;
|
|
@@ -59,7 +59,7 @@ async function loadFeedback(filePath) {
|
|
|
59
59
|
for await (const line of rl) {
|
|
60
60
|
const obj = parseLine(line);
|
|
61
61
|
if (obj && obj.timestamp) {
|
|
62
|
-
// Support both 'feedback' (Subway) and 'signal' (
|
|
62
|
+
// Support both 'feedback' (Subway) and 'signal' (ThumbGate) field names
|
|
63
63
|
const feedbackVal = obj.feedback || obj.signal;
|
|
64
64
|
if (feedbackVal) {
|
|
65
65
|
// Normalize to 'positive'/'negative' regardless of source schema
|
|
Binary file
|
|
File without changes
|