social-autoposter 1.6.69 → 1.6.71

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/cli.js CHANGED
@@ -367,123 +367,6 @@ function applyAppMakerMcpConfigOverrides() {
367
367
  // uv installed and broke Phase 1's Claude scan (the MCP server's `command:
368
368
  // /root/.local/bin/uv` resolved to ENOENT, Claude got no tools, returned an
369
369
  // empty envelope).
370
- // AppMaker VM self-bootstrap. Single entry point that the appmaker template
371
- // startup.sh calls on every fresh sandbox boot. Reads the stable sessionKey
372
- // from /run/mk0r-session.json (which the appmaker bridge rewrites on every
373
- // session bind, and which survives E2B sandbox substitution — only the
374
- // sandboxId changes), then asks the social-autoposter HTTP API which Twitter
375
- // account this VM is bound to (handle + stored login cookies, keyed by
376
- // social_accounts.vm_session_key). With that single DB answer it sets up
377
- // everything: env file (with the DB-sourced handle), profile symlink, MCP
378
- // config (BH_PORT=9222), uuid-runtime, then restores the Twitter login by
379
- // re-injecting the stored cookies via CDP.
380
- //
381
- // This is the "one proper fix" for sandbox substitution: the VM holds no
382
- // per-VM state on disk — the DB does, keyed by the stable sessionKey. So
383
- // any fresh sandbox can rebuild itself by reading /run/mk0r-session.json
384
- // and calling one route.
385
- function bootstrapVm() {
386
- if (!isAppMakerVm()) {
387
- console.error('bootstrap-vm: not an AppMaker VM (no /opt/startup.sh + CDP :9222). Use `init` or `update` on dev boxes.');
388
- process.exit(2);
389
- }
390
- // Persist VM mode so subsequent `update` runs on this sandbox keep the
391
- // AppMaker tweaks without re-passing --vm/SA_VM.
392
- enableVmMode();
393
- console.log(' AppMaker VM bootstrap: resolving identity from DB by sessionKey...');
394
-
395
- let sessionKey;
396
- try {
397
- const raw = fs.readFileSync('/run/mk0r-session.json', 'utf8');
398
- sessionKey = (JSON.parse(raw) || {}).sessionKey;
399
- } catch (err) {
400
- console.error(`bootstrap-vm: cannot read /run/mk0r-session.json: ${err.message}`);
401
- process.exit(3);
402
- }
403
- if (!sessionKey) {
404
- console.error('bootstrap-vm: /run/mk0r-session.json has no sessionKey');
405
- process.exit(3);
406
- }
407
- console.log(` sessionKey=${sessionKey}`);
408
-
409
- // Get the X-Installation header via identity.py (same Python helper http_api.py
410
- // uses, so auth stays single-sourced).
411
- const identityPath = path.join(PKG_ROOT, 'scripts', 'identity.py');
412
- const headerRes = spawnSync('/usr/bin/python3', [identityPath, 'header'], {
413
- encoding: 'utf8',
414
- });
415
- if (headerRes.status !== 0) {
416
- console.error(`bootstrap-vm: identity.py header failed: ${headerRes.stderr || headerRes.error}`);
417
- process.exit(4);
418
- }
419
- const installHeader = (headerRes.stdout || '').trim();
420
-
421
- const base = (process.env.AUTOPOSTER_API_BASE || 'https://s4l.ai').replace(/\/+$/, '');
422
- const url = `${base}/api/v1/twitter/vm-session?session_key=${encodeURIComponent(sessionKey)}`;
423
- console.log(` GET ${url}`);
424
-
425
- // Use curl (always present on the appmaker template) so we don't pull in
426
- // a Node HTTP dep here.
427
- const curl = spawnSync('curl', [
428
- '-sS', '--max-time', '15',
429
- '-H', `X-Installation: ${installHeader}`,
430
- '-H', 'Content-Type: application/json',
431
- url,
432
- ], { encoding: 'utf8' });
433
- if (curl.status !== 0) {
434
- console.error(`bootstrap-vm: curl failed: ${curl.stderr || curl.error}`);
435
- process.exit(5);
436
- }
437
- let payload;
438
- try {
439
- payload = JSON.parse(curl.stdout || '{}');
440
- } catch (err) {
441
- console.error(`bootstrap-vm: bad JSON from API: ${curl.stdout.slice(0, 300)}`);
442
- process.exit(6);
443
- }
444
- if (!payload.ok || !payload.data) {
445
- console.error(`bootstrap-vm: API error: ${JSON.stringify(payload).slice(0, 300)}`);
446
- process.exit(7);
447
- }
448
- const { handle, cookies, vm_project_id } = payload.data;
449
- if (!handle) {
450
- console.error('bootstrap-vm: API returned no handle. social_accounts.vm_session_key may be unset for this VM.');
451
- process.exit(8);
452
- }
453
- console.log(` bound to @${handle} (vm_project_id=${vm_project_id || 'none'}, cookies=${(cookies || []).length})`);
454
-
455
- // Write env file with DB-sourced handle (durable across `social-autoposter update`).
456
- writeAppMakerEnvFile(handle);
457
-
458
- // Existing setup steps. installBrowserHarness already installs uuid-runtime,
459
- // symlinks the profile, and patches the MCP config — call it directly.
460
- installBrowserHarness();
461
-
462
- // Install Python deps from requirements.txt. installBrowserHarness only
463
- // installs uv + mcp; it does NOT read requirements.txt, so without this the
464
- // VM is missing websocket-client (restore_twitter_session.py aborts on
465
- // import) plus playwright that the cycle scripts need.
466
- installPythonDeps();
467
-
468
- // Restore the Twitter login if we have stored cookies and the Chrome is
469
- // up. No-op when Chrome isn't reachable yet (startup ordering); the cycle
470
- // preflight will run restore_twitter_session.py on its next tick.
471
- if ((cookies || []).length > 0) {
472
- const restorePath = path.join(HOME, 'social-autoposter', 'scripts', 'restore_twitter_session.py');
473
- if (fs.existsSync(restorePath)) {
474
- console.log(' invoking restore_twitter_session.py to re-inject cookies...');
475
- // Source the env file so AUTOPOSTER_TWITTER_HANDLE / TWITTER_CDP_URL are set.
476
- const r = spawnSync('bash', ['-lc',
477
- `source ${HOME}/.social-autoposter-env 2>/dev/null; /usr/bin/python3 ${restorePath} || true`,
478
- ], { stdio: 'inherit' });
479
- void r;
480
- }
481
- } else {
482
- console.log(' no stored cookies; manual login still required this once.');
483
- }
484
-
485
- console.log(' bootstrap-vm: done.');
486
- }
487
370
 
488
371
  function installBrowserHarness() {
489
372
  const onAppMaker = vmModeEnabled();
@@ -1137,8 +1020,6 @@ if (cmd === 'init') {
1137
1020
  update();
1138
1021
  } else if (cmd === 'doctor') {
1139
1022
  doctor();
1140
- } else if (cmd === 'bootstrap-vm') {
1141
- bootstrapVm();
1142
1023
  } else if (cmd === 'install-runtime') {
1143
1024
  installRuntime();
1144
1025
  } else if (cmd === 'reset' || cmd === 'uninstall') {
@@ -1171,7 +1052,6 @@ if (cmd === 'init') {
1171
1052
  console.log(' npx social-autoposter init first-time setup');
1172
1053
  console.log(' npx social-autoposter update update scripts, preserve config');
1173
1054
  console.log(' npx social-autoposter doctor [--json] [--phase pre_connect|full]');
1174
- console.log(' npx social-autoposter bootstrap-vm AppMaker VM self-bootstrap (DB-driven)');
1175
1055
  console.log(' npx social-autoposter install-runtime provision owned Python + Chromium (panel-free)');
1176
1056
  console.log(' npx social-autoposter export-cookies [dir] export browser cookies');
1177
1057
  console.log(' npx social-autoposter import-cookies [dir] import browser cookies');