social-agent-cli 1.1.8 → 1.2.0
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/ai/runner.ts +30 -0
- package/cli.ts +18 -6
- package/core/types.ts +1 -1
- package/maps/linkedin_post.json +22 -10
- package/maps/x_post.json +23 -8
- package/package.json +3 -2
package/ai/runner.ts
CHANGED
|
@@ -331,5 +331,35 @@ async function executeMapStep(
|
|
|
331
331
|
await page.keyboard.press(step.key || "Enter");
|
|
332
332
|
if (step.waitMs) await page.waitForTimeout(step.waitMs);
|
|
333
333
|
break;
|
|
334
|
+
|
|
335
|
+
case "upload": {
|
|
336
|
+
// Dosya yükleme - hidden file input'a dosya set et
|
|
337
|
+
const filePath = rp(step.value || "{{IMAGE}}");
|
|
338
|
+
if (!filePath || filePath.includes("{{")) break; // dosya yoksa atla
|
|
339
|
+
|
|
340
|
+
let uploaded = false;
|
|
341
|
+
for (const sel of selectors) {
|
|
342
|
+
try {
|
|
343
|
+
const input = await page.waitForSelector(sel, { timeout: 5000 });
|
|
344
|
+
await input.setInputFiles(filePath);
|
|
345
|
+
uploaded = true;
|
|
346
|
+
break;
|
|
347
|
+
} catch {}
|
|
348
|
+
}
|
|
349
|
+
if (!uploaded) {
|
|
350
|
+
// Hidden input bulunamazsa, file chooser ile dene
|
|
351
|
+
try {
|
|
352
|
+
const [fileChooser] = await Promise.all([
|
|
353
|
+
page.waitForEvent("filechooser", { timeout: 5000 }),
|
|
354
|
+
page.click(selectors[0] || "[data-testid='fileInput']"),
|
|
355
|
+
]);
|
|
356
|
+
await fileChooser.setFiles(filePath);
|
|
357
|
+
uploaded = true;
|
|
358
|
+
} catch {}
|
|
359
|
+
}
|
|
360
|
+
if (!uploaded) throw new Error(`Upload failed: ${filePath}`);
|
|
361
|
+
if (step.waitMs) await page.waitForTimeout(step.waitMs);
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
334
364
|
}
|
|
335
365
|
}
|
package/cli.ts
CHANGED
|
@@ -131,17 +131,29 @@ async function cmdTest(platform: string) {
|
|
|
131
131
|
|
|
132
132
|
function cmdStatus() {
|
|
133
133
|
const config = loadConfig();
|
|
134
|
-
const
|
|
134
|
+
const { getSavedProfile } = require("./core/profiles.js");
|
|
135
135
|
|
|
136
136
|
console.log("\n Platform Durumu\n ───────────────");
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
|
|
138
|
+
// API platformları - config'de varsa göster
|
|
139
|
+
if (config.mastodon) console.log(` 🔗 mastodon (api) → ${config.mastodon.instanceUrl}`);
|
|
140
|
+
if (config.bluesky) console.log(` 🔗 bluesky (api) → ${config.bluesky.identifier}`);
|
|
141
|
+
if (config.telegram) console.log(` 🔗 telegram (api)`);
|
|
142
|
+
|
|
143
|
+
// Browser platformları - sadece login olmuşları göster
|
|
144
|
+
for (const [name] of Object.entries(BROWSER_PLATFORMS)) {
|
|
145
|
+
const profile = getSavedProfile(name);
|
|
146
|
+
if (profile) {
|
|
147
|
+
console.log(` 🌐 ${name} (browser) → ${profile.name} (${profile.email})`);
|
|
148
|
+
}
|
|
140
149
|
}
|
|
141
150
|
|
|
142
|
-
|
|
151
|
+
const hasAny = config.mastodon || config.bluesky || config.telegram ||
|
|
152
|
+
Object.keys(BROWSER_PLATFORMS).some(p => getSavedProfile(p));
|
|
153
|
+
|
|
154
|
+
if (!hasAny) {
|
|
143
155
|
console.log(" Hiçbir platform yapılandırılmamış.");
|
|
144
|
-
console.log("
|
|
156
|
+
console.log(" sa setup çalıştır.");
|
|
145
157
|
}
|
|
146
158
|
console.log();
|
|
147
159
|
}
|
package/core/types.ts
CHANGED
|
@@ -22,7 +22,7 @@ export interface SelectorMap {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export interface SelectorStep {
|
|
25
|
-
action: "click" | "type" | "wait" | "screenshot" | "keypress" | "goto";
|
|
25
|
+
action: "click" | "type" | "wait" | "screenshot" | "keypress" | "goto" | "upload";
|
|
26
26
|
description: string;
|
|
27
27
|
selector?: string;
|
|
28
28
|
value?: string; // for type action
|
package/maps/linkedin_post.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"platform": "linkedin",
|
|
3
3
|
"action": "post",
|
|
4
|
-
"description": "LinkedIn üzerinden
|
|
5
|
-
"version":
|
|
6
|
-
"lastUpdated": "2026-03-
|
|
7
|
-
"parameters": ["{{CONTENT}}"],
|
|
4
|
+
"description": "LinkedIn üzerinden metin + opsiyonel görsel postu paylaşma",
|
|
5
|
+
"version": 2,
|
|
6
|
+
"lastUpdated": "2026-03-14T15:00:00.000Z",
|
|
7
|
+
"parameters": ["{{CONTENT}}", "{{IMAGE}}"],
|
|
8
8
|
"steps": [
|
|
9
9
|
{
|
|
10
10
|
"action": "click",
|
|
@@ -29,9 +29,7 @@
|
|
|
29
29
|
"fallbackSelectors": [
|
|
30
30
|
"[role='textbox'][contenteditable='true']",
|
|
31
31
|
".ql-editor[contenteditable='true']",
|
|
32
|
-
"[aria-label*='Metin düzenleyici']"
|
|
33
|
-
"[data-placeholder*='What do you want']",
|
|
34
|
-
"[data-placeholder*='Ne hakkında']"
|
|
32
|
+
"[aria-label*='Metin düzenleyici']"
|
|
35
33
|
]
|
|
36
34
|
},
|
|
37
35
|
{
|
|
@@ -49,6 +47,21 @@
|
|
|
49
47
|
"description": "Metin girişi sonrası bekleme",
|
|
50
48
|
"waitMs": 1000
|
|
51
49
|
},
|
|
50
|
+
{
|
|
51
|
+
"action": "upload",
|
|
52
|
+
"description": "Görsel yükle (varsa)",
|
|
53
|
+
"selector": "input[type='file'][accept*='image']",
|
|
54
|
+
"value": "{{IMAGE}}",
|
|
55
|
+
"fallbackSelectors": [
|
|
56
|
+
".share-creation-state__file-input input[type='file']",
|
|
57
|
+
"input[type='file']"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"action": "wait",
|
|
62
|
+
"description": "Görsel yüklenmesini bekle",
|
|
63
|
+
"waitMs": 3000
|
|
64
|
+
},
|
|
52
65
|
{
|
|
53
66
|
"action": "click",
|
|
54
67
|
"description": "Gönder butonuna tıkla",
|
|
@@ -57,14 +70,13 @@
|
|
|
57
70
|
"[aria-label='Post']",
|
|
58
71
|
"[aria-label='Gönder']",
|
|
59
72
|
"button[aria-label*='Post']",
|
|
60
|
-
"button[aria-label*='Paylaş']"
|
|
61
|
-
"button.artdeco-button--primary[type='button']"
|
|
73
|
+
"button[aria-label*='Paylaş']"
|
|
62
74
|
]
|
|
63
75
|
},
|
|
64
76
|
{
|
|
65
77
|
"action": "wait",
|
|
66
78
|
"description": "Post gönderimini bekle",
|
|
67
|
-
"waitMs":
|
|
79
|
+
"waitMs": 3000
|
|
68
80
|
}
|
|
69
81
|
]
|
|
70
82
|
}
|
package/maps/x_post.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"platform": "x",
|
|
3
3
|
"action": "post",
|
|
4
|
-
"description": "X (Twitter) üzerinden
|
|
5
|
-
"version":
|
|
6
|
-
"lastUpdated": "2026-03-
|
|
7
|
-
"parameters": ["{{CONTENT}}"],
|
|
4
|
+
"description": "X (Twitter) üzerinden metin + opsiyonel görsel postu paylaşma",
|
|
5
|
+
"version": 2,
|
|
6
|
+
"lastUpdated": "2026-03-14T15:00:00.000Z",
|
|
7
|
+
"parameters": ["{{CONTENT}}", "{{IMAGE}}"],
|
|
8
8
|
"steps": [
|
|
9
9
|
{
|
|
10
10
|
"action": "click",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"fallbackSelectors": [
|
|
14
14
|
"a[href='/compose/post']",
|
|
15
15
|
"[aria-label*='Post'][role='link']",
|
|
16
|
-
"[aria-label*='Gönder'][role='link']"
|
|
16
|
+
"[aria-label*='Gönder'][role='link']",
|
|
17
|
+
"[data-testid='FloatingActionButton']"
|
|
17
18
|
]
|
|
18
19
|
},
|
|
19
20
|
{
|
|
@@ -27,8 +28,7 @@
|
|
|
27
28
|
"selector": "[data-testid='tweetTextarea_0']",
|
|
28
29
|
"fallbackSelectors": [
|
|
29
30
|
"[role='textbox'][contenteditable='true']",
|
|
30
|
-
".public-DraftEditor-content"
|
|
31
|
-
"[data-testid='tweetTextarea_0RichTextInputContainer'] [contenteditable]"
|
|
31
|
+
".public-DraftEditor-content"
|
|
32
32
|
]
|
|
33
33
|
},
|
|
34
34
|
{
|
|
@@ -46,6 +46,21 @@
|
|
|
46
46
|
"description": "Metin girişi sonrası bekleme",
|
|
47
47
|
"waitMs": 500
|
|
48
48
|
},
|
|
49
|
+
{
|
|
50
|
+
"action": "upload",
|
|
51
|
+
"description": "Görsel yükle (varsa)",
|
|
52
|
+
"selector": "[data-testid='fileInput']",
|
|
53
|
+
"value": "{{IMAGE}}",
|
|
54
|
+
"fallbackSelectors": [
|
|
55
|
+
"input[type='file'][accept*='image']",
|
|
56
|
+
"input[data-testid='fileInput']"
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"action": "wait",
|
|
61
|
+
"description": "Görsel yüklenmesini bekle",
|
|
62
|
+
"waitMs": 2000
|
|
63
|
+
},
|
|
49
64
|
{
|
|
50
65
|
"action": "click",
|
|
51
66
|
"description": "Gönder butonuna tıkla",
|
|
@@ -58,7 +73,7 @@
|
|
|
58
73
|
{
|
|
59
74
|
"action": "wait",
|
|
60
75
|
"description": "Post gönderimini bekle",
|
|
61
|
-
"waitMs":
|
|
76
|
+
"waitMs": 3000
|
|
62
77
|
}
|
|
63
78
|
]
|
|
64
79
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "social-agent-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "AI-powered social media agent - free APIs + browser automation with self-healing selectors",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"social-agent": "./bin/social-agent.js"
|
|
7
|
+
"social-agent": "./bin/social-agent.js",
|
|
8
|
+
"sa": "./bin/social-agent.js"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
11
|
"postinstall": "node bin/postinstall.js",
|