viruagent-cli 0.6.2 → 0.7.1

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/README.ko.md CHANGED
@@ -29,6 +29,7 @@
29
29
  | **Tistory** | Playwright (카카오) | 글 발행, 임시저장, 카테고리, 이미지 업로드 | [가이드](docs/ko/guide-tistory.md) |
30
30
  | **Naver Blog** | Playwright (네이버) | 글 발행, 카테고리, SE Editor, 이미지 업로드 | [가이드](docs/ko/guide-naver.md) |
31
31
  | **Instagram** | HTTP (브라우저 불필요) | 좋아요, 댓글, 팔로우, 포스팅, 프로필, 피드 | [가이드](docs/ko/guide-instagram.md) |
32
+ | **X (Twitter)** | HTTP (쿠키 인증) | 트윗, 좋아요, 리트윗, 팔로우, 검색, 타임라인, 미디어 업로드 | [가이드](docs/ko/guide-x.md) |
32
33
 
33
34
  ## 동작 방식
34
35
 
@@ -50,7 +51,7 @@
50
51
 
51
52
  ## 빠른 시작
52
53
 
53
- ![viru_install](https://github.com/user-attachments/assets/35efb57f-fada-44c0-8dd4-6d586ef33a7c)
54
+ ![viruagent-cli demo](demo/demo.gif)
54
55
 
55
56
  아래 내용을 AI 에이전트에게 그대로 복사해서 보여주세요.
56
57
 
@@ -95,6 +96,15 @@ npx viruagent-cli login --provider insta --username <인스타 ID> --password <
95
96
  >
96
97
  > 전체 API 레퍼런스와 rate limit 규칙은 [Instagram 가이드](docs/ko/guide-instagram.md)를 참고하세요.
97
98
 
99
+ ### X (Twitter)
100
+
101
+ ```bash
102
+ npx viruagent-cli login --provider x --auth-token <토큰> --ct0 <ct0>
103
+ ```
104
+ > 브라우저에서 `auth_token`과 `ct0` 쿠키를 추출하세요. 비밀번호 로그인 없음 — 쿠키 기반 인증만 지원.
105
+ >
106
+ > 전체 API 레퍼런스, GraphQL 동기화, rate limit 규칙은 [X 가이드](docs/ko/guide-x.md)를 참고하세요.
107
+
98
108
  ## 사용법
99
109
 
100
110
  | 이렇게 말하면 | 에이전트가 알아서 |
@@ -107,12 +117,17 @@ npx viruagent-cli login --provider insta --username <인스타 ID> --password <
107
117
  | "이 사람 피드 분석해서 댓글 달아줘" | analyzePost → AI 댓글 생성 → comment |
108
118
  | "@user 팔로우해줘" | 로그인 → follow (딜레이 자동 적용) |
109
119
  | "인스타 rate limit 확인해줘" | rate-limit-status → 카운터 표시 |
120
+ | "이 내용으로 트윗해줘" | X 로그인 → publish (rate limit 자동 적용) |
121
+ | "X에서 AI 도구 검색해줘" | search → 결과 반환 |
122
+ | "X에서 IT 개발자 좋아요하고 팔로우해줘" | search → like + follow (딜레이 자동 적용) |
123
+ | "내 X 타임라인 보여줘" | getFeed → 최신 트윗 표시 |
110
124
 
111
125
  ## 플랫폼별 가이드
112
126
 
113
127
  - **[Tistory 가이드](docs/ko/guide-tistory.md)** — 블로그 발행, 이미지 업로드, 카테고리
114
128
  - **[Naver Blog 가이드](docs/ko/guide-naver.md)** — SE Editor, 블로그 발행, 이미지 업로드
115
129
  - **[Instagram 가이드](docs/ko/guide-instagram.md)** — 18개 API 메서드, rate limit 규칙, AI 댓글
130
+ - **[X (Twitter) 가이드](docs/ko/guide-x.md)** — GraphQL API, queryId 동적 동기화, rate limit 규칙
116
131
 
117
132
  ## 지원 환경
118
133
 
@@ -129,6 +144,7 @@ npx viruagent-cli login --provider insta --username <인스타 ID> --password <
129
144
  | CLI 프레임워크 | Commander.js |
130
145
  | 브라우저 자동화 | Playwright (Tistory, Naver만 사용) |
131
146
  | Instagram API | 순수 HTTP fetch (브라우저 불필요) |
147
+ | X (Twitter) API | 내부 GraphQL API + queryId 동적 추출 |
132
148
  | 세션 관리 | JSON 파일 (`~/.viruagent-cli/`) |
133
149
  | Rate Limiting | 유저별 영속 카운터 + 랜덤 딜레이 |
134
150
  | 이미지 검색 | DuckDuckGo, Wikimedia Commons |
package/README.md CHANGED
@@ -29,6 +29,7 @@ Designed not for humans, but for **AI agents**.
29
29
  | **Tistory** | Playwright (Kakao) | Publish, Draft, Categories, Image Upload | [Guide](docs/en/guide-tistory.md) |
30
30
  | **Naver Blog** | Playwright (Naver) | Publish, Categories, SE Editor, Image Upload | [Guide](docs/en/guide-naver.md) |
31
31
  | **Instagram** | HTTP (No Browser) | Like, Comment, Follow, Post, Profile, Feed, Rate Limit | [Guide](docs/en/guide-instagram.md) |
32
+ | **X (Twitter)** | HTTP (Cookie Auth) | Tweet, Like, Retweet, Follow, Search, Timeline, Media Upload | [Guide](docs/en/guide-x.md) |
32
33
 
33
34
  ## How It Works
34
35
 
@@ -50,7 +51,7 @@ User: "Like and comment on all posts from @username"
50
51
 
51
52
  ## Quick Start
52
53
 
53
- ![viru_install](https://github.com/user-attachments/assets/35efb57f-fada-44c0-8dd4-6d586ef33a7c)
54
+ ![viruagent-cli demo](demo/demo.gif)
54
55
 
55
56
  Copy the following to your AI agent:
56
57
 
@@ -95,6 +96,15 @@ npx viruagent-cli login --provider insta --username <id> --password <pw>
95
96
  >
96
97
  > See the [Instagram Guide](docs/en/guide-instagram.md) for full API reference and rate limit rules.
97
98
 
99
+ ### X (Twitter)
100
+
101
+ ```bash
102
+ npx viruagent-cli login --provider x --auth-token <token> --ct0 <ct0>
103
+ ```
104
+ > Extract `auth_token` and `ct0` cookies from your browser. No password login — cookie-based auth only.
105
+ >
106
+ > See the [X Guide](docs/en/guide-x.md) for full API reference, GraphQL sync, and rate limit rules.
107
+
98
108
  ## Usage
99
109
 
100
110
  | Say this | Agent handles |
@@ -107,12 +117,17 @@ npx viruagent-cli login --provider insta --username <id> --password <pw>
107
117
  | "Analyze and comment on @user's feed" | analyzePost → AI generates comment → comment |
108
118
  | "Follow @user" | Login → follow (with delay) |
109
119
  | "Check Instagram rate limit" | rate-limit-status → show counters |
120
+ | "Tweet this text" | X login → publish (with rate limit) |
121
+ | "Search X for AI tools" | search → return results |
122
+ | "Like and follow IT devs on X" | search → like + follow (with delays) |
123
+ | "Show my X timeline" | getFeed → show latest tweets |
110
124
 
111
125
  ## Platform Guides
112
126
 
113
127
  - **[Tistory Guide](docs/en/guide-tistory.md)** — Blog publishing, image upload, categories
114
128
  - **[Naver Blog Guide](docs/en/guide-naver.md)** — SE Editor, blog publishing, image upload
115
129
  - **[Instagram Guide](docs/en/guide-instagram.md)** — 18 API methods, rate limits, AI commenting
130
+ - **[X (Twitter) Guide](docs/en/guide-x.md)** — GraphQL API, dynamic queryId sync, rate limits
116
131
 
117
132
  ## Supported Environments
118
133
 
@@ -129,6 +144,7 @@ npx viruagent-cli login --provider insta --username <id> --password <pw>
129
144
  | CLI Framework | Commander.js |
130
145
  | Browser Automation | Playwright (Tistory, Naver only) |
131
146
  | Instagram API | Pure HTTP fetch (no browser) |
147
+ | X (Twitter) API | Internal GraphQL API with dynamic queryId extraction |
132
148
  | Session Management | JSON file (`~/.viruagent-cli/`) |
133
149
  | Rate Limiting | Per-user persistent counters with random delays |
134
150
  | Image Search | DuckDuckGo, Wikimedia Commons |
package/bin/index.js CHANGED
@@ -18,7 +18,7 @@ program
18
18
 
19
19
  // Global options
20
20
  const addProviderOption = (cmd) =>
21
- cmd.option('--provider <name>', 'Provider name (tistory, naver, insta)', 'tistory');
21
+ cmd.option('--provider <name>', 'Provider name (tistory, naver, insta, x, reddit)', 'tistory');
22
22
 
23
23
  const addDryRunOption = (cmd) =>
24
24
  cmd.option('--dry-run', 'Validate params without executing', false);
@@ -49,6 +49,10 @@ loginCmd
49
49
  .option('--headless', 'Run browser in headless mode', false)
50
50
  .option('--manual', 'Use manual login mode', false)
51
51
  .option('--two-factor-code <code>', '2FA verification code')
52
+ .option('--auth-token <token>', 'Auth token (X provider)')
53
+ .option('--ct0 <ct0>', 'CT0 token (X provider)')
54
+ .option('--client-id <id>', 'OAuth Client ID (Reddit)')
55
+ .option('--client-secret <secret>', 'OAuth Client Secret (Reddit)')
52
56
  .action((opts) => execute('login', opts));
53
57
 
54
58
  const publishCmd = program
@@ -70,6 +74,9 @@ publishCmd
70
74
  .option('--minimum-image-count <n>', 'Minimum required images', '1')
71
75
  .option('--no-auto-upload-images', 'Disable automatic image uploading')
72
76
  .option('--no-enforce-system-prompt', 'Disable system prompt enforcement')
77
+ .option('--subreddit <name>', 'Subreddit name (Reddit)')
78
+ .option('--kind <type>', 'Post kind: self or link (Reddit)', 'self')
79
+ .option('--flair <id>', 'Flair template ID (Reddit)')
73
80
  .action((opts) => execute('publish', opts));
74
81
 
75
82
  const saveDraftCmd = program
@@ -250,6 +257,22 @@ const rateLimitCmd = program
250
257
  addProviderOption(rateLimitCmd);
251
258
  rateLimitCmd.action((opts) => execute('rate-limit-status', opts));
252
259
 
260
+ const subscribeCmd = program
261
+ .command('subscribe')
262
+ .description('Subscribe to a subreddit (Reddit)');
263
+ addProviderOption(subscribeCmd);
264
+ subscribeCmd
265
+ .option('--subreddit <name>', 'Subreddit name')
266
+ .action((opts) => execute('subscribe', opts));
267
+
268
+ const unsubscribeCmd = program
269
+ .command('unsubscribe')
270
+ .description('Unsubscribe from a subreddit (Reddit)');
271
+ addProviderOption(unsubscribeCmd);
272
+ unsubscribeCmd
273
+ .option('--subreddit <name>', 'Subreddit name')
274
+ .action((opts) => execute('unsubscribe', opts));
275
+
253
276
  // --- Utility commands ---
254
277
 
255
278
  const installSkillCmd = program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viruagent-cli",
3
- "version": "0.6.2",
3
+ "version": "0.7.1",
4
4
  "description": "AI-agent-optimized CLI for blog publishing (Tistory, Naver) and Instagram automation",
5
5
  "private": false,
6
6
  "type": "commonjs",
@@ -42,6 +42,7 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "commander": "^14.0.3",
45
- "playwright": "^1.58.2"
45
+ "playwright": "^1.58.2",
46
+ "x-client-transaction-id": "^0.2.0"
46
47
  }
47
48
  }
@@ -167,9 +167,10 @@ const createInstaApiClient = ({ sessionPath }) => {
167
167
  ...options.headers,
168
168
  };
169
169
 
170
- const res = await fetch(url, { ...options, headers, redirect: 'manual' });
170
+ const redirectMode = options.followRedirect ? 'follow' : 'manual';
171
+ const res = await fetch(url, { ...options, headers, redirect: redirectMode });
171
172
 
172
- if (res.status === 302 || res.status === 301) {
173
+ if (!options.followRedirect && (res.status === 302 || res.status === 301)) {
173
174
  const location = res.headers.get('location') || '';
174
175
  if (location.includes('/accounts/login')) {
175
176
  throw new Error('Session expired. Please log in again.');
@@ -608,6 +609,7 @@ const createInstaApiClient = ({ sessionPath }) => {
608
609
  Offset: '0',
609
610
  },
610
611
  body: imageBuffer,
612
+ followRedirect: true,
611
613
  },
612
614
  );
613
615
  const data = await res.json();