social-agent-cli 1.1.7 → 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 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 drivers = getAllDrivers();
134
+ const { getSavedProfile } = require("./core/profiles.js");
135
135
 
136
136
  console.log("\n Platform Durumu\n ───────────────");
137
- for (const d of drivers) {
138
- const icon = d.type === "api" ? "🔗" : "🌐";
139
- console.log(` ${icon} ${d.name} (${d.type})`);
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
- if (!drivers.length) {
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(" config.json düzenle veya 'login <platform>' çalıştır.");
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/install.ts CHANGED
@@ -292,6 +292,7 @@ Kullanıcıya "Arka planda gönderiliyor" de ve diğer işlere devam et.
292
292
  `);
293
293
 
294
294
  const browserPlatforms = [
295
+ { key: "x", name: "X (Twitter)", url: "https://x.com" },
295
296
  { key: "linkedin", name: "LinkedIn", url: "https://www.linkedin.com" },
296
297
  ];
297
298
 
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "platform": "linkedin",
3
3
  "action": "post",
4
- "description": "LinkedIn üzerinden yeni bir metin postu paylaşma",
5
- "version": 1,
6
- "lastUpdated": "2026-03-14T12:00:00.000Z",
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": 2000
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 yeni bir metin postu paylaşma",
5
- "version": 1,
6
- "lastUpdated": "2026-03-14T12:00:00.000Z",
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": 2000
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.1.7",
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",