№ thread
← Atelier
v0.2.1
Proven
Provenreact+draftjswatch

tiktok.com

tiktok.com Starter. Authored by manual_seed. License: cc-by.

Claim this domain · earn 75% open bounty
live pulse

This Thread is actively running in buyer engines + learning from every session.

engines · 24h
0
0 actions
success rate · 24h
no data yet
last auto-heal
1h ago
3 community patches
pending review
0
all clear
recent activityas of 0s ago
  • 🪡

    post_video recipe: caption step changed from eval_js fiber walk to real CDP keystrokes (click + Ctrl+A + Backspace + key_type). Fiber walk visibly updated DOM but didn't sync Draft.js state to TikTok's form binding — verified live by goldenbreath_short_lite posting with filename as caption.

    1h ago

  • 🪡

    Added post_video session_recipe. Engine-independent workflow — replaces tiktok_post_video engine tool. Caller provides {video_path, caption, privacy_label}.

    2h ago

  • 🪡

    First real fractal post to @auralalchemyx via WebLoom — golden-breath 4K fractal meditation, 45s, 19.5MB H.264 + AAC. End-to-end pipe proven.

    2h ago

Forever
Free updatesWhen the author ships a patch, your copy updates automatically. Yours to keep.
1-click
Drift reportsBroken? Hit the report button. Enough reports flag the Thread publicly and alert the author.
Live
Health scorePreflight pass rate shown on every card. You see the real uptime before buying.
Always
Pre-run haltweaver check runs before every recipe — drift detected means zero wasted clicks.
№ 00 — escalation log

Walls
already cracked.

Site-specific knowledge. If your AI hits this exact action and fails, here is the proven chain — what failed, in what order, and what finally worked. Authored from real RE work on this site.

Upload a video to TikTok Studio (file >25MB)by MarStudio (seed)
  1. 01
    upload_file Strategy B (plain CDP setFileInputFiles)failed

    Sets the FileList but React's controlled-input observer ignores synthetic event

  2. 02
    upload_file Strategy A (file-chooser intercept)failed

    CDP websocket drops on Windows + Chrome when native dialog opens. Recovery requires reload.

  3. 03
    ffmpeg re-encode to <25MB + Strategy E (react_input_selector)proven

    ffmpeg -c:v libx264 -b:v 3500k -c:a aac -b:a 128k. Fractals at 1080×1920 compress 82MB → 19.5MB visually identical. Then Strategy E uses native HTMLInputElement.files setter + fiber onChange — React onChange fires.

lesson

For TikTok Studio uploads on Windows: NEVER use Strategy A (CDP dies). Pre-process the file under 25MB with ffmpeg, then Strategy E. Fractal/animation content compresses dramatically with minimal visual loss.

Set caption in Draft.js editorby MarStudio (seed)
  1. 01
    engine draftjs_set_text toolfailed

    v0.3.0 has base64-shadowing bug — fixed in commit 75d4edb but in-memory engine needs reload

  2. 02
    Direct fiber walk → ContentState.createFromText + EditorState.createWithContent + props.onChangeproven

    Walk fiber from .public-DraftEditor-content. Find ancestor stateNode with props.editorState + onChange. Build new state from editorState.getCurrentContent().constructor.createFromText(text). Pass through. Replaces filename default cleanly.

lesson

When the engine tool has a bug, the underlying RE path (fiber walk + state replacement via the editor's own constructor) is reliable enough to embed in a one-off eval_js call.

№ 01 — proven actions

Cracked moves.

Each row is a real action successfully driven through WebLoom on this site — recorded automatically when an author ran the engine. Strategy tells the engine which click path works here.

descriptor
strategy
successes
last used
Navigate to upload studio
navigate
×1
6/16/2026
Upload video via Strategy E
react_input_selector
×1
6/16/2026
Set Draft.js caption via fiber onChange
fiber-walk-direct
×1
6/16/2026
Click Post button
direct_click
×1
6/16/2026
№ 02 — preflight

Drift detection.

These checks run before every recipe. Any failure halts execution and notifies you.

name
kind
probe
logged_in
dom
[class*='studioMenuItem'], [data-e2e*='nav']
msToken_cookie
cookie
msToken
№ 03 — quirks

Lessons learned.

01

TikTok Studio uses a React-controlled <input type=file>. Strategy B (plain CDP setFileInputFiles) DOES NOT fire React's onChange — must use Strategy E (react_input_selector) which uses the native HTMLInputElement.files setter + fiber-walked onChange.

02

Strategy A (file-chooser intercept) drops CDP on Windows + Chrome when the native dialog opens. AVOID on Windows.

03

Strategy E inline-injection has a 25MB cap. For larger files, re-encode first (ffmpeg) OR chunk — fractal videos at 1080×1920 compress well to 3.5Mbps H.264 + 128k AAC.

04

Caption editor is Draft.js (.public-DraftEditor-content). The engine's draftjs_set_text tool had a base64 shadowing bug in v0.3.0 (fixed in commit 75d4edb). Manual fix: walk fiber from contenteditable → find stateNode.props.editorState + onChange → ContentState.createFromText(text) + EditorState.createWithContent → inst.props.onChange(newState). REPLACES filename default cleanly.

05

Post button: button[data-e2e='post_video_button']. Direct btn.click() works (no fiber walk needed).

06

On post success, URL flips /tiktokstudio/upload → /tiktokstudio/content.

07

Privacy default is 'Only me' — locked during 'Content under review' (~10 min). After review clears, toggle via the TUXButton.Privacy dropdown (text 'Only me' → click → dialog opens with Everyone/Friends/Only me options).

08

msToken is in document.cookie. byted_acrawler signer NOT on window on current TikTok Studio build (renamed/relocated) — use UI driving for now; native batch needs new signer probe.

№ 05 — raw thread

The file.

This is what installs to ~/.webloom/threads/. No magic. Just JSON.

tiktok.com.thread.json10.1 KB
{
  "domain": "tiktok.com",
  "name": "tiktok.com Starter",
  "version": "0.2.1",
  "author": "manual_seed",
  "license": "cc-by",
  "tier": "starter",
  "source_url": "https://tiktok.com",
  "framework": "react+draftjs",
  "frameworks_detected": [
    "react",
    "next",
    "draftjs",
    "tux-design-system"
  ],
  "anti_bot_verdict": "watch",
  "anti_bot_signals": [
    {
      "type": "body-signed-msToken",
      "confidence": "high"
    }
  ],
  "default_strategy": "cdp",
  "category_hint": "social_video",
  "use_cases": [
    "Upload a video to TikTok Studio (any creator account)",
    "Set caption + hashtags via Draft.js fiber walk",
    "Toggle privacy after content review clears"
  ],
  "notes": [
    "TikTok Studio uses a React-controlled <input type=file>. Strategy B (plain CDP setFileInputFiles) DOES NOT fire React's onChange — must use Strategy E (react_input_selector) which uses the native HTMLInputElement.files setter + fiber-walked onChange.",
    "Strategy A (file-chooser intercept) drops CDP on Windows + Chrome when the native dialog opens. AVOID on Windows.",
    "Strategy E inline-injection has a 25MB cap. For larger files, re-encode first (ffmpeg) OR chunk — fractal videos at 1080×1920 compress well to 3.5Mbps H.264 + 128k AAC.",
    "Caption editor is Draft.js (.public-DraftEditor-content). The engine's draftjs_set_text tool had a base64 shadowing bug in v0.3.0 (fixed in commit 75d4edb). Manual fix: walk fiber from contenteditable → find stateNode.props.editorState + onChange → ContentState.createFromText(text) + EditorState.createWithContent → inst.props.onChange(newState). REPLACES filename default cleanly.",
    "Post button: button[data-e2e='post_video_button']. Direct btn.click() works (no fiber walk needed).",
    "On post success, URL flips /tiktokstudio/upload → /tiktokstudio/content.",
    "Privacy default is 'Only me' — locked during 'Content under review' (~10 min). After review clears, toggle via the TUXButton.Privacy dropdown (text 'Only me' → click → dialog opens with Everyone/Friends/Only me options).",
    "msToken is in document.cookie. byted_acrawler signer NOT on window on current TikTok Studio build (renamed/relocated) — use UI driving for now; native batch needs new signer probe."
  ],
  "quirks": {
    "react_controlled_file_input": "Always use upload_file Strategy E for the studio upload input",
    "draftjs_caption": "Bypass engine draftjs_set_text — walk fiber directly to onChange (engine has 25MB ceiling via inline-base64)",
    "privacy_locked_during_review": "TikTok gates privacy changes for ~10 min after post. Toggle after review clears."
  },
  "preflight": [
    {
      "name": "logged_in",
      "kind": "dom",
      "probe": "[class*='studioMenuItem'], [data-e2e*='nav']",
      "expected": "present"
    },
    {
      "name": "msToken_cookie",
      "kind": "cookie",
      "probe": "msToken",
      "expected": "present"
    }
  ],
  "proven_actions": [
    {
      "descriptor": "Navigate to upload studio",
      "kind": "navigate",
      "strategy": "navigate",
      "selector_pattern": "/tiktokstudio/upload",
      "successes": 1,
      "failures": 0,
      "last_at": 1781652413
    },
    {
      "descriptor": "Upload video via Strategy E",
      "kind": "upload",
      "strategy": "react_input_selector",
      "selector_pattern": "input[type=file]",
      "successes": 1,
      "failures": 0,
      "last_at": 1781652413
    },
    {
      "descriptor": "Set Draft.js caption via fiber onChange",
      "kind": "fill",
      "strategy": "fiber-walk-direct",
      "selector_pattern": ".public-DraftEditor-content",
      "successes": 1,
      "failures": 0,
      "last_at": 1781652413
    },
    {
      "descriptor": "Click Post button",
      "kind": "click",
      "strategy": "direct_click",
      "selector_pattern": "button[data-e2e='post_video_button']",
      "successes": 1,
      "failures": 0,
      "last_at": 1781652413
    }
  ],
  "escalation_log": [
    {
      "action": "Upload a video to TikTok Studio (file >25MB)",
      "tried": [
        {
          "strategy": "upload_file Strategy B (plain CDP setFileInputFiles)",
          "outcome": "failed",
          "notes": "Sets the FileList but React's controlled-input observer ignores synthetic event"
        },
        {
          "strategy": "upload_file Strategy A (file-chooser intercept)",
          "outcome": "failed",
          "notes": "CDP websocket drops on Windows + Chrome when native dialog opens. Recovery requires reload."
        },
        {
          "strategy": "ffmpeg re-encode to <25MB + Strategy E (react_input_selector)",
          "outcome": "proven",
          "notes": "ffmpeg -c:v libx264 -b:v 3500k -c:a aac -b:a 128k. Fractals at 1080×1920 compress 82MB → 19.5MB visually identical. Then Strategy E uses native HTMLInputElement.files setter + fiber onChange — React onChange fires."
        }
      ],
      "lesson": "For TikTok Studio uploads on Windows: NEVER use Strategy A (CDP dies). Pre-process the file under 25MB with ffmpeg, then Strategy E. Fractal/animation content compresses dramatically with minimal visual loss.",
      "by": "MarStudio (seed)",
      "last_verified_at": 1781652413
    },
    {
      "action": "Set caption in Draft.js editor",
      "tried": [
        {
          "strategy": "engine draftjs_set_text tool",
          "outcome": "failed",
          "notes": "v0.3.0 has base64-shadowing bug — fixed in commit 75d4edb but in-memory engine needs reload"
        },
        {
          "strategy": "Direct fiber walk → ContentState.createFromText + EditorState.createWithContent + props.onChange",
          "outcome": "proven",
          "notes": "Walk fiber from .public-DraftEditor-content. Find ancestor stateNode with props.editorState + onChange. Build new state from editorState.getCurrentContent().constructor.createFromText(text). Pass through. Replaces filename default cleanly."
        }
      ],
      "lesson": "When the engine tool has a bug, the underlying RE path (fiber walk + state replacement via the editor's own constructor) is reliable enough to embed in a one-off eval_js call.",
      "by": "MarStudio (seed)",
      "last_verified_at": 1781652413
    }
  ],
  "states": [],
  "pacing": {
    "profile": "human",
    "signals": {}
  },
  "created_at": 1781652413,
  "created_by": "live_usage_seed_with_real_post",
  "authored_by": [
    "MarStudio (seed)"
  ],
  "open_for_claim": true,
  "patch_log": [
    {
      "ts": 1781653939,
      "kind": "recipe_fix",
      "descriptor": "post_video recipe: caption step changed from eval_js fiber walk to real CDP keystrokes (click + Ctrl+A + Backspace + key_type). Fiber walk visibly updated DOM but didn't sync Draft.js state to TikTok's form binding — verified live by goldenbreath_short_lite posting with filename as caption."
    },
    {
      "ts": 1781653628,
      "kind": "session_recipe_added",
      "descriptor": "Added post_video session_recipe. Engine-independent workflow — replaces tiktok_post_video engine tool. Caller provides {video_path, caption, privacy_label}."
    },
    {
      "ts": 1781652413,
      "kind": "seed_from_live_usage",
      "descriptor": "First real fractal post to @auralalchemyx via WebLoom — golden-breath 4K fractal meditation, 45s, 19.5MB H.264 + AAC. End-to-end pipe proven."
    }
  ],
  "session_recipes": [
    {
      "name": "post_video",
      "outcome": "success",
      "parameters": [
        "video_path",
        "caption",
        "privacy_label"
      ],
      "description": "End-to-end TikTok upload via the Studio UI. Drives generic engine primitives only — no site-specific engine tool needed. Caller provides {video_path, caption, privacy_label} where privacy_label is 'Everyone' (public), 'Friends', or 'Only me'.",
      "actions": [
        {
          "tool": "navigate",
          "args": {
            "url": "https://www.tiktok.com/tiktokstudio/upload"
          }
        },
        {
          "tool": "wait_for",
          "args": {
            "selector": "input[type=file]",
            "timeout_ms": 10000
          }
        },
        {
          "tool": "upload_file",
          "args": {
            "selector": "input[type=file]",
            "react_input_selector": "input[type=file]",
            "files": [
              "{{video_path}}"
            ]
          },
          "notes": "Strategy E (react_input_selector) required — TikTok input is React-controlled. Strategy B silently fails. 25MB cap → pre-encode larger files with ffmpeg (1080×1920 H.264 3.5Mbps + AAC 128k for fractal-style content)."
        },
        {
          "tool": "wait_for",
          "args": {
            "selector": ".public-DraftEditor-content",
            "timeout_ms": 90000
          }
        },
        {
          "tool": "click",
          "args": {
            "description": ".public-DraftEditor-content"
          },
          "notes": "Focus the Draft.js editor. Required before any keystrokes will land in the right form field."
        },
        {
          "tool": "key_press",
          "args": {
            "key": "a",
            "modifiers": [
              "Control"
            ]
          },
          "notes": "Ctrl+A to select the entire current caption (default = filename like 'goldenbreath_short_lite')."
        },
        {
          "tool": "key_press",
          "args": {
            "key": "Backspace"
          },
          "notes": "Delete the selected default. Editor is now empty."
        },
        {
          "tool": "key_type",
          "args": {
            "text": "{{caption}}",
            "delay_ms": 30
          },
          "notes": "Type the caption with real CDP keystrokes — flows through Draft.js's keypress handler → TikTok's form binding → post serializes correct text. Fiber-walk onChange does NOT work (verified 2026-06-16: fiber walk updated visible DOM but post serialized the filename default)."
        },
        {
          "tool": "eval_js",
          "args": {
            "code": "(async function() {\n  const sleep = (ms) => new Promise(r => setTimeout(r, ms));\n  const want = {{privacy_label_json}};\n  const labels = ['Everyone','Friends','Only me'];\n  const fire = (el) => {\n    const r = el.getBoundingClientRect();\n    const cx = r.left + r.width/2, cy = r.top + r.height/2;\n    for (const t of ['pointerdown','mousedown','pointerup','mouseup','click']) {\n      el.dispatchEvent(new MouseEvent(t, {bubbles:true,cancelable:true,composed:true,view:window,clientX:cx,clientY:cy,button:0,buttons:1}));\n    }\n  };\n  const trigger = Array.from(document.querySelectorAll('button')).filter(b => b.offsetWidth > 0).find(b => labels.includes((b.innerText||'').trim()));\n  if (!trigger) return 'NO_PRIVACY_TRIGGER';\n  if ((trigger.innerText||'').trim() === want) return 'ALREADY:' + want;\n  trigger.scrollIntoView({block:'center'});\n  fire(trigger);\n  await sleep(400);\n  const dlg = document.querySelector('[role=dialog]:not([aria-hidden=true])') || document.querySelector('.Dropdown__content');\n  if (!dlg) return 'NO_DROPDOWN';\n  let opt = null;\n  for (const el of dlg.querySelectorAll('*')) {\n    if (el.children.length === 0 && (el.innerText||'').trim() === want) {\n      let p = el;\n      while (p && p !== dlg && p.tagName !== 'BUTTON' && getComputedStyle(p).cursor !== 'pointer') p = p.parentElement;\n      if (p && p !== dlg) { opt = p; break; }\n    }\n  }\n  if (!opt) return 'NO_OPTION:' + want;\n  fire(opt);\n  await sleep(500);\n  return 'OK:' + want;\n})()"
          },
          "notes": "MUST run BEFORE Post. Skipping = video defaults to account preference (often 'Only me'), then enters 'Content under review' where TikTok rejects further privacy changes for up to 12 hours. Verified live on @auralalchemy 2026-06-16."
        },
        {
          "tool": "eval_js",
          "args": {
            "code": "(() => {\n  const btn = document.querySelector('button[data-e2e=\"post_video_button\"]');\n  if (!btn) return 'NO_POST_BUTTON';\n  if (btn.disabled || btn.getAttribute('aria-disabled') === 'true') return 'POST_DISABLED';\n  btn.click();\n  return 'OK';\n})()"
          },
          "notes": "Direct .click() on canonical Post button. URL flips /tiktokstudio/upload → /tiktokstudio/content on success."
        },
        {
          "tool": "wait_for",
          "args": {
            "selector": "body",
            "timeout_ms": 8000
          }
        }
      ]
    }
  ]
}