social-autoposter 1.6.1 → 1.6.2
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/bin/server.js +17 -7
- package/package.json +1 -1
- package/skill/run-twitter-cycle.sh +8 -2
package/bin/server.js
CHANGED
|
@@ -49,6 +49,13 @@ const JOBS = [
|
|
|
49
49
|
// Post Threads row (original threads/posts)
|
|
50
50
|
{ label: 'com.m13v.social-reddit-threads', name: 'Reddit Threads', type: 'Post Threads', platform: 'Reddit', script: 'run-reddit-threads.sh', logPrefix: 'run-reddit-threads-', plist: 'com.m13v.social-reddit-threads.plist' },
|
|
51
51
|
{ label: 'com.m13v.social-twitter-threads', name: 'Twitter Threads', type: 'Post Threads', platform: 'Twitter', script: 'run-twitter-threads.sh', logPrefix: 'run-twitter-threads-', plist: 'com.m13v.social-twitter-threads.plist' },
|
|
52
|
+
// Instagram per-account daily posters (5×/day each, FORCE_ACCOUNT pinned).
|
|
53
|
+
{ label: 'com.m13v.social-instagram-daily-matt_diak', name: 'IG Daily (matt_diak)', type: 'Post Threads', platform: 'Instagram', script: 'run-instagram-daily.sh', logPrefix: 'instagram-daily-', plist: 'com.m13v.social-instagram-daily-matt_diak.plist' },
|
|
54
|
+
{ label: 'com.m13v.social-instagram-daily-matthewheartful', name: 'IG Daily (matthewheartful)', type: 'Post Threads', platform: 'Instagram', script: 'run-instagram-daily.sh', logPrefix: 'instagram-daily-', plist: 'com.m13v.social-instagram-daily-matthewheartful.plist' },
|
|
55
|
+
// Instagram per-account render (upstream of daily-posters; produces the
|
|
56
|
+
// mp4 + caption draft that the daily-poster then uploads).
|
|
57
|
+
{ label: 'com.m13v.social-instagram-render-matt_diak', name: 'IG Render (matt_diak)', type: 'Other', platform: 'Instagram', script: 'run-instagram-render.sh', logPrefix: 'instagram-render-', plist: 'com.m13v.social-instagram-render-matt_diak.plist' },
|
|
58
|
+
{ label: 'com.m13v.social-instagram-render-matthewheartful', name: 'IG Render (matthewheartful)', type: 'Other', platform: 'Instagram', script: 'run-instagram-render.sh', logPrefix: 'instagram-render-', plist: 'com.m13v.social-instagram-render-matthewheartful.plist' },
|
|
52
59
|
// Post Comments row (replies/comments on others' content)
|
|
53
60
|
{ label: 'com.m13v.social-reddit-search', name: 'Reddit', type: 'Post Comments', platform: 'Reddit', script: 'run-reddit-search.sh', logPrefix: 'run-reddit-search-', plist: 'com.m13v.social-reddit-search.plist' },
|
|
54
61
|
{ label: 'com.m13v.social-twitter-cycle', name: 'Twitter', type: 'Post Comments', platform: 'Twitter', script: 'run-twitter-cycle.sh', logPrefix: 'twitter-cycle-', plist: 'com.m13v.social-twitter-cycle.plist' },
|
|
@@ -130,6 +137,8 @@ const REQUIRED_LOCKS = {
|
|
|
130
137
|
'link-edit-github.sh': ['link-edit-github'],
|
|
131
138
|
'stats-reddit.sh': ['reddit-browser'],
|
|
132
139
|
'stats-instagram.sh': ['instagram-poster'],
|
|
140
|
+
'run-instagram-daily.sh': ['instagram-poster'],
|
|
141
|
+
'run-instagram-render.sh': ['instagram-render'],
|
|
133
142
|
'audit-reddit.sh': ['reddit-browser', 'audit-reddit'],
|
|
134
143
|
'audit-twitter.sh': ['twitter-browser', 'audit-twitter'],
|
|
135
144
|
'audit-linkedin.sh': ['linkedin-browser', 'audit-linkedin'],
|
|
@@ -5234,7 +5243,7 @@ async function handleApi(req, res) {
|
|
|
5234
5243
|
const url = new URL(req.url, 'http://localhost');
|
|
5235
5244
|
const windowHours = Math.max(1, Math.min(720, parseInt(url.searchParams.get('hours') || '24', 10) || 24));
|
|
5236
5245
|
const rawProject = (url.searchParams.get('project') || '').trim();
|
|
5237
|
-
const ALLOWED_COST_PLATFORMS = new Set(['reddit', 'twitter', 'linkedin', 'moltbook', 'github', 'seo', 'email']);
|
|
5246
|
+
const ALLOWED_COST_PLATFORMS = new Set(['reddit', 'twitter', 'linkedin', 'moltbook', 'github', 'seo', 'email', 'instagram']);
|
|
5238
5247
|
let rawPlat = String(url.searchParams.get('platform') || '').toLowerCase().trim();
|
|
5239
5248
|
if (rawPlat === 'x') rawPlat = 'twitter';
|
|
5240
5249
|
const plat = ALLOWED_COST_PLATFORMS.has(rawPlat) ? rawPlat : '';
|
|
@@ -5376,7 +5385,7 @@ async function handleApi(req, res) {
|
|
|
5376
5385
|
const project = (rawProject === '' || rawProject.toLowerCase() === 'all') ? '' : rawProject;
|
|
5377
5386
|
const projectOk = project === '' || /^[A-Za-z0-9_\- ]{1,64}$/.test(project);
|
|
5378
5387
|
if (!projectOk) return json(res, { error: 'invalid project' }, 400);
|
|
5379
|
-
const ALLOWED_COST_PLATFORMS = new Set(['reddit', 'twitter', 'linkedin', 'moltbook', 'github', 'seo', 'email']);
|
|
5388
|
+
const ALLOWED_COST_PLATFORMS = new Set(['reddit', 'twitter', 'linkedin', 'moltbook', 'github', 'seo', 'email', 'instagram']);
|
|
5380
5389
|
let rawPlat = String(url.searchParams.get('platform') || '').toLowerCase().trim();
|
|
5381
5390
|
if (rawPlat === 'x') rawPlat = 'twitter';
|
|
5382
5391
|
const plat = ALLOWED_COST_PLATFORMS.has(rawPlat) ? rawPlat : '';
|
|
@@ -6751,7 +6760,7 @@ async function handleApi(req, res) {
|
|
|
6751
6760
|
const configuredProjects = Array.isArray(config.projects) ? config.projects : [];
|
|
6752
6761
|
const weighted = configuredProjects.filter(p => (p.weight || 0) > 0);
|
|
6753
6762
|
const totalWeight = weighted.reduce((a, p) => a + (p.weight || 0), 0) || 1;
|
|
6754
|
-
const platforms = ['reddit', 'twitter', 'linkedin', 'moltbook', 'github'];
|
|
6763
|
+
const platforms = ['reddit', 'twitter', 'linkedin', 'moltbook', 'github', 'instagram'];
|
|
6755
6764
|
// Per-platform eligibility: a project is eligible to be picked for a
|
|
6756
6765
|
// platform only if it has the data that platform's picker needs. Mirrors
|
|
6757
6766
|
// scripts/pick_project.py and scripts/pick_thread_target.py. Projects
|
|
@@ -8093,6 +8102,7 @@ const HTML = `<!DOCTYPE html>
|
|
|
8093
8102
|
<th>LinkedIn</th>
|
|
8094
8103
|
<th>MoltBook</th>
|
|
8095
8104
|
<th>GitHub</th>
|
|
8105
|
+
<th>Instagram</th>
|
|
8096
8106
|
</tr>
|
|
8097
8107
|
</thead>
|
|
8098
8108
|
<tbody id="matrix-body"></tbody>
|
|
@@ -10574,8 +10584,8 @@ const EVENT_DESCRIPTIONS = {
|
|
|
10574
10584
|
page_expired: 'SEO page deleted by the daily expire pipeline because it had zero clicks in the last 30 days. The on-disk source file was removed; Next.js now returns 404 for the URL. Logged for audit/revert in seo_expired_pages.',
|
|
10575
10585
|
resurrected: 'Previously archived or unavailable item brought back into rotation (e.g., a removed post restored after reappearing).',
|
|
10576
10586
|
};
|
|
10577
|
-
const ACTIVITY_PLATFORMS = ['reddit', 'twitter', 'linkedin', 'moltbook', 'github', 'seo'];
|
|
10578
|
-
const ACTIVITY_PLATFORM_LABELS = { reddit: 'Reddit', twitter: 'Twitter / X', linkedin: 'LinkedIn', moltbook: 'Moltbook', github: 'GitHub', seo: 'SEO' };
|
|
10587
|
+
const ACTIVITY_PLATFORMS = ['reddit', 'twitter', 'linkedin', 'moltbook', 'github', 'seo', 'instagram'];
|
|
10588
|
+
const ACTIVITY_PLATFORM_LABELS = { reddit: 'Reddit', twitter: 'Twitter / X', linkedin: 'LinkedIn', moltbook: 'Moltbook', github: 'GitHub', seo: 'SEO', instagram: 'Instagram' };
|
|
10579
10589
|
const PROJECT_LABELS = { tenxats: '10xats' };
|
|
10580
10590
|
const ACTIVITY_PROJECT_NONE = '(none)';
|
|
10581
10591
|
const ACTIVITY_CAMPAIGN_ORGANIC = '(organic)';
|
|
@@ -16515,10 +16525,10 @@ async function loadDeployHealth() {
|
|
|
16515
16525
|
// hours by platform against config.json weight targets. Each platform cell
|
|
16516
16526
|
// shows the count plus that project's share of the platform's posts in
|
|
16517
16527
|
// brackets, so operators can spot imbalance without a separate deficit field.
|
|
16518
|
-
const PROJECT_STATUS_PLATFORMS = ['reddit', 'twitter', 'linkedin', 'moltbook', 'github'];
|
|
16528
|
+
const PROJECT_STATUS_PLATFORMS = ['reddit', 'twitter', 'linkedin', 'moltbook', 'github', 'instagram'];
|
|
16519
16529
|
const PROJECT_STATUS_PLATFORM_LABELS = {
|
|
16520
16530
|
reddit: 'Reddit', twitter: 'Twitter', linkedin: 'LinkedIn',
|
|
16521
|
-
moltbook: 'MoltBook', github: 'GitHub',
|
|
16531
|
+
moltbook: 'MoltBook', github: 'GitHub', instagram: 'Instagram',
|
|
16522
16532
|
};
|
|
16523
16533
|
let _projectStatusLoading = false;
|
|
16524
16534
|
let _projectStatusData = null;
|
package/package.json
CHANGED
|
@@ -1047,7 +1047,7 @@ export CLAUDE_SESSION_ID
|
|
|
1047
1047
|
|
|
1048
1048
|
PREP_SCHEMA='{"type":"object","properties":{"candidates":{"type":"array","items":{"type":"object","properties":{"candidate_id":{"type":"integer"},"candidate_url":{"type":"string"},"thread_author":{"type":"string"},"thread_text":{"type":"string"},"matched_project":{"type":"string"},"reply_text":{"type":"string"},"engagement_style":{"type":"string"},"language":{"type":"string"},"has_landing_pages":{"type":"boolean"},"link_keyword":{"type":"string"},"link_slug":{"type":"string"}},"required":["candidate_id","candidate_url","matched_project","reply_text","engagement_style","language","has_landing_pages"]}},"rejected":{"type":"array","items":{"type":"object","properties":{"candidate_id":{"type":"integer"},"reason":{"type":"string"},"proposed_excludes":{"type":"array","items":{"type":"string"}}},"required":["candidate_id","reason"]}}},"required":["candidates","rejected"]}'
|
|
1049
1049
|
|
|
1050
|
-
|
|
1050
|
+
PREP_PROMPT="${TW_ENGINE_PREFIX}You are the Social Autoposter prep step.
|
|
1051
1051
|
|
|
1052
1052
|
Your ONLY job in THIS session:
|
|
1053
1053
|
1. Read each thread you decide to reply to (browser tools from the BROWSER BACKEND block above, READ-ONLY).
|
|
@@ -1130,7 +1130,13 @@ CRITICAL:
|
|
|
1130
1130
|
- DO NOT call log_post.py or campaign_bump.py.
|
|
1131
1131
|
- Browser tools (from the BROWSER BACKEND block) are READ-ONLY in this step.
|
|
1132
1132
|
- NEVER use em dashes. Use commas, periods, or regular dashes (-).
|
|
1133
|
-
- Reply in the SAME LANGUAGE as the parent tweet."
|
|
1133
|
+
- Reply in the SAME LANGUAGE as the parent tweet."
|
|
1134
|
+
|
|
1135
|
+
# Pipe the prep prompt via stdin instead of passing as a shell argument.
|
|
1136
|
+
# On Linux ARG_MAX is 2MB; the assembled prompt (config.json + top_report +
|
|
1137
|
+
# styles + schema + candidates) busts that on the VM, dying with E2BIG
|
|
1138
|
+
# "Argument list too long". stdin has no such cap.
|
|
1139
|
+
PREP_OUTPUT=$(printf '%s' "$PREP_PROMPT" | "$REPO_DIR/scripts/run_claude.sh" "run-twitter-cycle-prep" --strict-mcp-config --mcp-config "$TW_MCP_CONFIG" -p --output-format json --json-schema "$PREP_SCHEMA" 2>&1)
|
|
1134
1140
|
|
|
1135
1141
|
echo "$PREP_OUTPUT" >> "$LOG_FILE"
|
|
1136
1142
|
|