@harness.farm/social-cli 0.1.1 → 0.1.3

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.
@@ -0,0 +1,37 @@
1
+ import { connectTab } from '../browser/cdp.js';
2
+ const client = await connectTab(9222);
3
+ await client.send('Page.bringToFront');
4
+ await new Promise(r => setTimeout(r, 300));
5
+ // Deep focus into bili-comments shadow DOM
6
+ const focused = await client.eval(`(function(){
7
+ var host = document.querySelector("bili-comments");
8
+ if(!host) return "no bili-comments";
9
+ function deepFocus(root){
10
+ var sr = root.shadowRoot;
11
+ if(!sr) return null;
12
+ var editor = sr.querySelector(".brt-editor");
13
+ if(editor) { editor.click(); editor.focus(); return "ok"; }
14
+ var els = sr.querySelectorAll("*");
15
+ for(var i=0; i<els.length; i++){
16
+ var r = deepFocus(els[i]);
17
+ if(r) return r;
18
+ }
19
+ return null;
20
+ }
21
+ return deepFocus(host) || "not found";
22
+ })()`);
23
+ console.log('focus result:', focused);
24
+ await new Promise(r => setTimeout(r, 500));
25
+ // Try Input.insertText
26
+ await client.send('Input.insertText', { text: 'hello shadow insertText' });
27
+ await new Promise(r => setTimeout(r, 500));
28
+ const content = await client.eval(`(function(){
29
+ var ed = document.querySelector("bili-comments")
30
+ .shadowRoot.querySelector("bili-comments-header-renderer")
31
+ .shadowRoot.querySelector("bili-comment-box")
32
+ .shadowRoot.querySelector("bili-comment-rich-textarea")
33
+ .shadowRoot.querySelector(".brt-editor");
34
+ return ed ? JSON.stringify({ text: ed.textContent.trim(), html: ed.innerHTML.slice(0,100) }) : "not found";
35
+ })()`);
36
+ console.log('editor content:', content);
37
+ client.close();
@@ -0,0 +1,30 @@
1
+ import { connectTab } from '../browser/cdp.js';
2
+ const client = await connectTab(9222);
3
+ await client.send('Page.bringToFront');
4
+ await new Promise(r => setTimeout(r, 200));
5
+ // Get follow button (JbfEzak6) coordinates
6
+ const coords = await client.eval(`(function(){
7
+ var el = document.querySelector('.JbfEzak6');
8
+ if(!el) return 'null';
9
+ var r = el.getBoundingClientRect();
10
+ return JSON.stringify({ x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2) });
11
+ })()`);
12
+ console.log('follow btn coords:', coords);
13
+ // check current state by checking parent avatar area
14
+ const beforeInfo = await client.eval(`JSON.stringify({
15
+ JbfEzak6Count: document.querySelectorAll('.JbfEzak6').length,
16
+ hasFollowedState: document.body.innerHTML.includes('已关注')
17
+ })`);
18
+ console.log('before:', JSON.parse(beforeInfo));
19
+ const { x, y } = JSON.parse(coords);
20
+ await client.send('Input.dispatchMouseEvent', { type: 'mouseMoved', x, y });
21
+ await client.send('Input.dispatchMouseEvent', { type: 'mousePressed', x, y, button: 'left', clickCount: 1 });
22
+ await client.send('Input.dispatchMouseEvent', { type: 'mouseReleased', x, y, button: 'left', clickCount: 1 });
23
+ await new Promise(r => setTimeout(r, 2000));
24
+ const afterInfo = await client.eval(`JSON.stringify({
25
+ JbfEzak6Count: document.querySelectorAll('.JbfEzak6').length,
26
+ hasFollowedState: document.body.innerHTML.includes('已关注'),
27
+ bodySnippet: [...document.querySelectorAll('[class*=follow]')].map(function(el){ return el.className.slice(0,60) + ':' + el.textContent.trim().slice(0,20); }).join(' | ')
28
+ })`);
29
+ console.log('after:', JSON.parse(afterInfo));
30
+ client.close();
@@ -0,0 +1,31 @@
1
+ import { newTab } from '../browser/cdp.js';
2
+ const client = await newTab(9222);
3
+ await client.navigate('https://x.com/search?q=AI+law&src=typed_query&f=top', 4000);
4
+ const info = await client.eval(`JSON.stringify({
5
+ url: location.href,
6
+ tweetItems: (() => {
7
+ var tweets = [...document.querySelectorAll('[data-testid="tweet"]')];
8
+ return tweets.slice(0,3).map(function(t){
9
+ return {
10
+ text: t.querySelector('[data-testid="tweetText"]')?.textContent?.trim()?.slice(0,60) || '',
11
+ user: t.querySelector('[data-testid="User-Name"]')?.textContent?.trim()?.slice(0,30) || '',
12
+ link: (() => {
13
+ var a = [...t.querySelectorAll('a')].find(function(a){ return /\\/status\\//.test(a.href); });
14
+ return a ? a.href : '';
15
+ })(),
16
+ time: t.querySelector('time')?.getAttribute('datetime') || ''
17
+ };
18
+ });
19
+ })()
20
+ })`);
21
+ const d = JSON.parse(info);
22
+ console.log('URL:', d.url);
23
+ console.log('\n搜索结果结构:');
24
+ d.tweetItems.forEach((t, i) => {
25
+ console.log(`\n[${i + 1}]`);
26
+ console.log(' text:', t.text);
27
+ console.log(' user:', t.user);
28
+ console.log(' link:', t.link);
29
+ console.log(' time:', t.time);
30
+ });
31
+ client.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harness.farm/social-cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "CDP-based social media automation CLI — X, 小红书, 抖音, B站, Temu",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -14,6 +14,7 @@
14
14
  "adapters"
15
15
  ],
16
16
  "scripts": {
17
+ "prepublishOnly": "tsc",
17
18
  "dev": "tsx src/cli.ts",
18
19
  "build": "tsc",
19
20
  "x": "tsx src/cli.ts x",