10x-chat 0.1.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/README.md +168 -0
- package/dist/bin/cli.d.ts +3 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +24 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/browser/index.d.ts +3 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +3 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/lock.d.ts +14 -0
- package/dist/browser/lock.d.ts.map +1 -0
- package/dist/browser/lock.js +89 -0
- package/dist/browser/lock.js.map +1 -0
- package/dist/browser/manager.d.ts +21 -0
- package/dist/browser/manager.d.ts.map +1 -0
- package/dist/browser/manager.js +46 -0
- package/dist/browser/manager.js.map +1 -0
- package/dist/cli/chat.d.ts +3 -0
- package/dist/cli/chat.d.ts.map +1 -0
- package/dist/cli/chat.js +74 -0
- package/dist/cli/chat.js.map +1 -0
- package/dist/cli/config.d.ts +3 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +49 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/login.d.ts +3 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/login.js +89 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/skill.d.ts +3 -0
- package/dist/cli/skill.d.ts.map +1 -0
- package/dist/cli/skill.js +51 -0
- package/dist/cli/skill.js.map +1 -0
- package/dist/cli/status.d.ts +4 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +73 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +25 -0
- package/dist/config.js.map +1 -0
- package/dist/core/bundle.d.ts +12 -0
- package/dist/core/bundle.d.ts.map +1 -0
- package/dist/core/bundle.js +77 -0
- package/dist/core/bundle.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/orchestrator.d.ts +18 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +90 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/paths.d.ts +11 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +24 -0
- package/dist/paths.js.map +1 -0
- package/dist/providers/chatgpt.d.ts +4 -0
- package/dist/providers/chatgpt.d.ts.map +1 -0
- package/dist/providers/chatgpt.js +107 -0
- package/dist/providers/chatgpt.js.map +1 -0
- package/dist/providers/claude.d.ts +4 -0
- package/dist/providers/claude.d.ts.map +1 -0
- package/dist/providers/claude.js +89 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/gemini.d.ts +4 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +89 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +5 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/registry.d.ts +8 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +26 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +2 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/store.d.ts +16 -0
- package/dist/session/store.d.ts.map +1 -0
- package/dist/session/store.js +95 -0
- package/dist/session/store.js.map +1 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +74 -0
- package/skills/10x-chat/SKILL.md +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# 10x-chat
|
|
2
|
+
|
|
3
|
+
> Chat with web AI agents (ChatGPT, Gemini, Claude) from your terminal via browser automation.
|
|
4
|
+
|
|
5
|
+
10x-chat uses [Playwright](https://playwright.dev) to automate browser sessions with persisted login profiles. Login once, then send prompts — bundled with file context — from your CLI or AI coding agent.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g 10x-chat
|
|
11
|
+
npx playwright install chromium # one-time browser setup
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# 1. Login to a provider (opens a browser window)
|
|
18
|
+
10x-chat login chatgpt
|
|
19
|
+
|
|
20
|
+
# 2. Send a prompt
|
|
21
|
+
10x-chat chat -p "Explain this error" --provider chatgpt --file "src/**/*.ts"
|
|
22
|
+
|
|
23
|
+
# 3. View session history
|
|
24
|
+
10x-chat status
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Commands
|
|
28
|
+
|
|
29
|
+
### `login <provider>`
|
|
30
|
+
|
|
31
|
+
Opens a headed browser for you to authenticate. The session persists across runs.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
10x-chat login chatgpt # Login to ChatGPT
|
|
35
|
+
10x-chat login gemini # Login to Gemini
|
|
36
|
+
10x-chat login claude # Login to Claude
|
|
37
|
+
10x-chat login --status # Check login status for all providers
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### `chat`
|
|
41
|
+
|
|
42
|
+
Send a prompt to an AI provider via browser automation.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
10x-chat chat -p "Review this code for bugs" --provider chatgpt --file "src/**/*.ts"
|
|
46
|
+
10x-chat chat -p "Debug this error" --file "logs/error.log"
|
|
47
|
+
10x-chat chat -p "Explain this" --dry-run # Preview bundle without sending
|
|
48
|
+
10x-chat chat -p "Explain this" --copy # Copy bundle to clipboard
|
|
49
|
+
10x-chat chat -p "Long task" --timeout 600000 --headed # 10min timeout, visible browser
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
| Flag | Description |
|
|
53
|
+
|------|-------------|
|
|
54
|
+
| `-p, --prompt <text>` | **(required)** The prompt to send |
|
|
55
|
+
| `--provider <name>` | Provider: `chatgpt`, `gemini`, `claude` (default: config) |
|
|
56
|
+
| `--model <name>` | Model to select in the UI |
|
|
57
|
+
| `-f, --file <paths...>` | Files/globs to bundle as context |
|
|
58
|
+
| `--copy` | Copy bundle to clipboard instead of sending |
|
|
59
|
+
| `--dry-run` | Preview the bundle without sending |
|
|
60
|
+
| `--headed` | Show browser window during chat |
|
|
61
|
+
| `--timeout <ms>` | Response timeout in milliseconds (default: 300000) |
|
|
62
|
+
|
|
63
|
+
### `status`
|
|
64
|
+
|
|
65
|
+
List recent chat sessions.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
10x-chat status # Last 24 hours
|
|
69
|
+
10x-chat status --hours 72 # Last 3 days
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `session <id>`
|
|
73
|
+
|
|
74
|
+
View details of a specific session.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
10x-chat session <id> --render # Pretty-print the response
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `config`
|
|
81
|
+
|
|
82
|
+
View or modify configuration.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
10x-chat config show
|
|
86
|
+
10x-chat config set provider gemini
|
|
87
|
+
10x-chat config set timeout 600000
|
|
88
|
+
10x-chat config set headless false
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `skill`
|
|
92
|
+
|
|
93
|
+
Manage the agent integration skill (for Codex, Claude Code, etc).
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
10x-chat skill install # Install SKILL.md to ~/.codex/skills/
|
|
97
|
+
10x-chat skill show # Display SKILL.md content
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## File Bundling
|
|
101
|
+
|
|
102
|
+
The `--file` flag accepts globs. Files are assembled into a markdown bundle sent as the prompt:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
10x-chat chat -p "Review these" --file "src/**/*.ts" "!src/**/*.test.ts"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Security-sensitive files (`.env*`, `*.pem`, `*.key`, etc.) are automatically excluded.
|
|
109
|
+
|
|
110
|
+
## Data Layout
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
~/.10x-chat/
|
|
114
|
+
├── profiles/
|
|
115
|
+
│ ├── chatgpt/ # Playwright persistent browser profile
|
|
116
|
+
│ ├── gemini/
|
|
117
|
+
│ └── claude/
|
|
118
|
+
├── sessions/
|
|
119
|
+
│ └── <uuid>/
|
|
120
|
+
│ ├── meta.json # Session metadata
|
|
121
|
+
│ ├── bundle.md # Prompt bundle sent
|
|
122
|
+
│ └── response.md # Captured response
|
|
123
|
+
└── config.json # User configuration
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Agent Integration
|
|
127
|
+
|
|
128
|
+
10x-chat includes a `SKILL.md` for AI coding agents. Install it with:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
10x-chat skill install
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
This lets agents like Codex or Claude Code use 10x-chat to query other models for cross-validation, code review, or debugging help.
|
|
135
|
+
|
|
136
|
+
## Supported Providers
|
|
137
|
+
|
|
138
|
+
| Provider | Status | URL |
|
|
139
|
+
|----------|--------|-----|
|
|
140
|
+
| ChatGPT | ✅ | chatgpt.com |
|
|
141
|
+
| Gemini | ✅ | gemini.google.com |
|
|
142
|
+
| Claude | ✅ | claude.ai |
|
|
143
|
+
|
|
144
|
+
## Development
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
pnpm install
|
|
148
|
+
pnpm run dev login chatgpt # Run CLI in dev mode
|
|
149
|
+
pnpm run typecheck # Type check
|
|
150
|
+
pnpm run lint # Lint
|
|
151
|
+
pnpm run test # Run tests
|
|
152
|
+
pnpm run build # Build for production
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Publishing
|
|
156
|
+
|
|
157
|
+
Releases are automated via GitHub Actions. Push a version tag to publish:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npm version patch # or minor / major
|
|
161
|
+
git push --follow-tags
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Requires `NPM_TOKEN` secret in the GitHub repository settings.
|
|
165
|
+
|
|
166
|
+
## License
|
|
167
|
+
|
|
168
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":""}
|
package/dist/bin/cli.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { createChatCommand } from '../cli/chat.js';
|
|
5
|
+
import { createConfigCommand } from '../cli/config.js';
|
|
6
|
+
import { createLoginCommand } from '../cli/login.js';
|
|
7
|
+
import { createSkillCommand } from '../cli/skill.js';
|
|
8
|
+
import { createSessionCommand, createStatusCommand } from '../cli/status.js';
|
|
9
|
+
const program = new Command();
|
|
10
|
+
program
|
|
11
|
+
.name('10x-chat')
|
|
12
|
+
.description('Chat with web AI agents (ChatGPT, Gemini, Claude) via browser automation')
|
|
13
|
+
.version('0.1.0');
|
|
14
|
+
program.addCommand(createLoginCommand());
|
|
15
|
+
program.addCommand(createChatCommand());
|
|
16
|
+
program.addCommand(createStatusCommand());
|
|
17
|
+
program.addCommand(createSessionCommand());
|
|
18
|
+
program.addCommand(createConfigCommand());
|
|
19
|
+
program.addCommand(createSkillCommand());
|
|
20
|
+
program.parseAsync(process.argv).catch((error) => {
|
|
21
|
+
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
|
|
22
|
+
process.exit(1);
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE7E,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,0EAA0E,CAAC;KACvF,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;AACzC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAEzC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC/C,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAoB,MAAM,WAAW,CAAC;AACjE,OAAO,EAA2C,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ProfileLock {
|
|
2
|
+
lockPath: string;
|
|
3
|
+
lockId: string;
|
|
4
|
+
release: () => Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Acquire a file-based lock for a provider profile directory.
|
|
8
|
+
* Prevents concurrent browser sessions on the same profile.
|
|
9
|
+
*/
|
|
10
|
+
export declare function acquireProfileLock(profileDir: string, opts?: {
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
pollMs?: number;
|
|
13
|
+
}): Promise<ProfileLock>;
|
|
14
|
+
//# sourceMappingURL=lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/browser/lock.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAYD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD,OAAO,CAAC,WAAW,CAAC,CA0EtB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
const LOCK_FILENAME = '10x-chat.lock';
|
|
5
|
+
/** Check if a process is still alive. */
|
|
6
|
+
function isProcessAlive(pid) {
|
|
7
|
+
try {
|
|
8
|
+
process.kill(pid, 0);
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Acquire a file-based lock for a provider profile directory.
|
|
17
|
+
* Prevents concurrent browser sessions on the same profile.
|
|
18
|
+
*/
|
|
19
|
+
export async function acquireProfileLock(profileDir, opts = {}) {
|
|
20
|
+
const { timeoutMs = 30_000, pollMs = 500 } = opts;
|
|
21
|
+
const lockPath = path.join(profileDir, LOCK_FILENAME);
|
|
22
|
+
const lockId = randomUUID();
|
|
23
|
+
const deadline = Date.now() + timeoutMs;
|
|
24
|
+
await mkdir(profileDir, { recursive: true });
|
|
25
|
+
while (Date.now() < deadline) {
|
|
26
|
+
// Try to read existing lock
|
|
27
|
+
try {
|
|
28
|
+
const raw = await readFile(lockPath, 'utf-8');
|
|
29
|
+
const record = JSON.parse(raw);
|
|
30
|
+
// Check if the lock holder is still alive
|
|
31
|
+
if (!isProcessAlive(record.pid)) {
|
|
32
|
+
// Stale lock from a dead process — remove it
|
|
33
|
+
await rm(lockPath, { force: true });
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Lock is held by a live process — wait
|
|
37
|
+
await new Promise((r) => setTimeout(r, pollMs));
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// No lock file exists or unreadable — proceed to acquire
|
|
43
|
+
}
|
|
44
|
+
// Try to write our lock
|
|
45
|
+
const record = {
|
|
46
|
+
pid: process.pid,
|
|
47
|
+
lockId,
|
|
48
|
+
createdAt: new Date().toISOString(),
|
|
49
|
+
};
|
|
50
|
+
try {
|
|
51
|
+
await writeFile(lockPath, JSON.stringify(record), { flag: 'wx' });
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Race condition: another process grabbed it first
|
|
55
|
+
await new Promise((r) => setTimeout(r, pollMs));
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// Verify we actually hold the lock
|
|
59
|
+
try {
|
|
60
|
+
const raw = await readFile(lockPath, 'utf-8');
|
|
61
|
+
const current = JSON.parse(raw);
|
|
62
|
+
if (current.lockId === lockId) {
|
|
63
|
+
return {
|
|
64
|
+
lockPath,
|
|
65
|
+
lockId,
|
|
66
|
+
release: async () => {
|
|
67
|
+
try {
|
|
68
|
+
const raw = await readFile(lockPath, 'utf-8');
|
|
69
|
+
const current = JSON.parse(raw);
|
|
70
|
+
if (current.lockId === lockId) {
|
|
71
|
+
await rm(lockPath, { force: true });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Lock file already gone
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Lock vanished — retry
|
|
83
|
+
}
|
|
84
|
+
await new Promise((r) => setTimeout(r, pollMs));
|
|
85
|
+
}
|
|
86
|
+
throw new Error(`Failed to acquire profile lock at ${lockPath} within ${timeoutMs}ms. ` +
|
|
87
|
+
'Another 10x-chat session may be using this profile.');
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/browser/lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type BrowserContext, type Page } from 'playwright';
|
|
2
|
+
import type { ProviderName } from '../types.js';
|
|
3
|
+
import { type ProfileLock } from './lock.js';
|
|
4
|
+
export interface BrowserSession {
|
|
5
|
+
context: BrowserContext;
|
|
6
|
+
page: Page;
|
|
7
|
+
lock: ProfileLock;
|
|
8
|
+
close: () => Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
export interface LaunchOptions {
|
|
11
|
+
provider: ProviderName;
|
|
12
|
+
headless?: boolean;
|
|
13
|
+
/** Initial URL to navigate to after launch. */
|
|
14
|
+
url?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Launch a Playwright persistent browser context for a provider.
|
|
18
|
+
* The profile directory is per-provider, ensuring login state persists.
|
|
19
|
+
*/
|
|
20
|
+
export declare function launchBrowser(opts: LaunchOptions): Promise<BrowserSession>;
|
|
21
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/browser/manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,cAAc,EAAY,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAwChF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { mkdir } from 'node:fs/promises';
|
|
2
|
+
import { chromium } from 'playwright';
|
|
3
|
+
import { getProfileDir } from '../paths.js';
|
|
4
|
+
import { acquireProfileLock } from './lock.js';
|
|
5
|
+
/**
|
|
6
|
+
* Launch a Playwright persistent browser context for a provider.
|
|
7
|
+
* The profile directory is per-provider, ensuring login state persists.
|
|
8
|
+
*/
|
|
9
|
+
export async function launchBrowser(opts) {
|
|
10
|
+
const { provider, headless = true, url } = opts;
|
|
11
|
+
const profileDir = getProfileDir(provider);
|
|
12
|
+
await mkdir(profileDir, { recursive: true });
|
|
13
|
+
// Acquire lock to prevent concurrent use of the same profile
|
|
14
|
+
const lock = await acquireProfileLock(profileDir);
|
|
15
|
+
let context;
|
|
16
|
+
let page;
|
|
17
|
+
try {
|
|
18
|
+
context = await chromium.launchPersistentContext(profileDir, {
|
|
19
|
+
headless,
|
|
20
|
+
viewport: { width: 1280, height: 900 },
|
|
21
|
+
args: [
|
|
22
|
+
'--disable-blink-features=AutomationControlled',
|
|
23
|
+
'--no-first-run',
|
|
24
|
+
'--no-default-browser-check',
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
page = context.pages()[0] ?? (await context.newPage());
|
|
28
|
+
if (url) {
|
|
29
|
+
await page.goto(url, { waitUntil: 'domcontentloaded' });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
await lock.release();
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
const close = async () => {
|
|
37
|
+
try {
|
|
38
|
+
await context.close();
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
await lock.release();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
return { context, page, lock, close };
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/browser/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAuB,QAAQ,EAAa,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAoB,MAAM,WAAW,CAAC;AAgBjE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAmB;IACrD,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAChD,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,6DAA6D;IAC7D,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAElD,IAAI,OAAuB,CAAC;IAC5B,IAAI,IAAU,CAAC;IACf,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,uBAAuB,CAAC,UAAU,EAAE;YAC3D,QAAQ;YACR,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;YACtC,IAAI,EAAE;gBACJ,+CAA+C;gBAC/C,gBAAgB;gBAChB,4BAA4B;aAC7B;SACF,CAAC,CAAC;QAEH,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAEvD,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE;QACvB,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/cli/chat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,iBAAiB,IAAI,OAAO,CAuE3C"}
|
package/dist/cli/chat.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { buildBundle } from '../core/bundle.js';
|
|
4
|
+
import { runChat } from '../core/index.js';
|
|
5
|
+
import { isValidProvider } from '../providers/index.js';
|
|
6
|
+
export function createChatCommand() {
|
|
7
|
+
const cmd = new Command('chat')
|
|
8
|
+
.description('Chat with an AI provider via browser automation')
|
|
9
|
+
.requiredOption('-p, --prompt <text>', 'The prompt to send')
|
|
10
|
+
.option('--provider <name>', 'Provider to use (chatgpt, gemini, claude)')
|
|
11
|
+
.option('--model <name>', 'Model to select')
|
|
12
|
+
.option('-f, --file <paths...>', 'Files/globs to include as context')
|
|
13
|
+
.option('--copy', 'Copy the bundle to clipboard instead of sending')
|
|
14
|
+
.option('--dry-run', 'Preview the bundle without sending')
|
|
15
|
+
.option('--headed', 'Show browser window during chat')
|
|
16
|
+
.option('--timeout <ms>', 'Response timeout in milliseconds', '300000')
|
|
17
|
+
.action(async (options) => {
|
|
18
|
+
const provider = options.provider;
|
|
19
|
+
if (provider && !isValidProvider(provider)) {
|
|
20
|
+
console.error(chalk.red(`Unknown provider: ${provider}`));
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
// Dry run: just show the bundle
|
|
24
|
+
if (options.dryRun) {
|
|
25
|
+
const bundle = await buildBundle({
|
|
26
|
+
prompt: options.prompt,
|
|
27
|
+
files: options.file,
|
|
28
|
+
});
|
|
29
|
+
console.log(chalk.bold('--- Bundle Preview ---\n'));
|
|
30
|
+
console.log(bundle);
|
|
31
|
+
console.log(chalk.bold('\n--- End Preview ---'));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Copy to clipboard
|
|
35
|
+
if (options.copy) {
|
|
36
|
+
const bundle = await buildBundle({
|
|
37
|
+
prompt: options.prompt,
|
|
38
|
+
files: options.file,
|
|
39
|
+
});
|
|
40
|
+
const { default: clipboardy } = await import('clipboardy');
|
|
41
|
+
await clipboardy.write(bundle);
|
|
42
|
+
console.log(chalk.green('✓ Bundle copied to clipboard'));
|
|
43
|
+
console.log(chalk.dim(`${bundle.length} characters`));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// Run the chat
|
|
47
|
+
try {
|
|
48
|
+
const result = await runChat({
|
|
49
|
+
prompt: options.prompt,
|
|
50
|
+
provider: provider,
|
|
51
|
+
model: options.model,
|
|
52
|
+
file: options.file,
|
|
53
|
+
headed: options.headed,
|
|
54
|
+
timeoutMs: Number.parseInt(options.timeout, 10),
|
|
55
|
+
});
|
|
56
|
+
console.log('');
|
|
57
|
+
console.log(chalk.bold.green('--- Response ---\n'));
|
|
58
|
+
console.log(result.response);
|
|
59
|
+
console.log('');
|
|
60
|
+
console.log(chalk.dim(`Session: ${result.sessionId}`));
|
|
61
|
+
console.log(chalk.dim(`Duration: ${Math.round(result.durationMs / 1000)}s`));
|
|
62
|
+
if (result.truncated) {
|
|
63
|
+
console.log(chalk.yellow('⚠ Response may be truncated (timeout reached)'));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
68
|
+
console.error(chalk.red(`Error: ${message}`));
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return cmd;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=chat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/cli/chat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,mBAAmB,IAAI,OAAO,CAgD7C"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { loadConfig, saveConfig } from '../config.js';
|
|
4
|
+
import { isValidProvider } from '../providers/index.js';
|
|
5
|
+
export function createConfigCommand() {
|
|
6
|
+
const cmd = new Command('config').description('View or modify configuration');
|
|
7
|
+
cmd
|
|
8
|
+
.command('show')
|
|
9
|
+
.description('Show current configuration')
|
|
10
|
+
.action(async () => {
|
|
11
|
+
const config = await loadConfig();
|
|
12
|
+
console.log(chalk.bold('Current Configuration\n'));
|
|
13
|
+
console.log(JSON.stringify(config, null, 2));
|
|
14
|
+
});
|
|
15
|
+
cmd
|
|
16
|
+
.command('set')
|
|
17
|
+
.description('Set a configuration value')
|
|
18
|
+
.argument('<key>', 'Configuration key (provider, model, timeout, headless)')
|
|
19
|
+
.argument('<value>', 'Configuration value')
|
|
20
|
+
.action(async (key, value) => {
|
|
21
|
+
const config = await loadConfig();
|
|
22
|
+
switch (key) {
|
|
23
|
+
case 'provider':
|
|
24
|
+
if (!isValidProvider(value)) {
|
|
25
|
+
console.error(chalk.red(`Invalid provider: ${value}`));
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
config.defaultProvider = value;
|
|
29
|
+
break;
|
|
30
|
+
case 'model':
|
|
31
|
+
config.defaultModel = value;
|
|
32
|
+
break;
|
|
33
|
+
case 'timeout':
|
|
34
|
+
config.defaultTimeoutMs = Number.parseInt(value, 10);
|
|
35
|
+
break;
|
|
36
|
+
case 'headless':
|
|
37
|
+
config.headless = value === 'true';
|
|
38
|
+
break;
|
|
39
|
+
default:
|
|
40
|
+
console.error(chalk.red(`Unknown config key: ${key}`));
|
|
41
|
+
console.log(chalk.dim('Available keys: provider, model, timeout, headless'));
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
await saveConfig(config);
|
|
45
|
+
console.log(chalk.green(`✓ Set ${key} = ${value}`));
|
|
46
|
+
});
|
|
47
|
+
return cmd;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,MAAM,UAAU,mBAAmB;IACjC,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,8BAA8B,CAAC,CAAC;IAE9E,GAAG;SACA,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,4BAA4B,CAAC;SACzC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEL,GAAG;SACA,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,2BAA2B,CAAC;SACxC,QAAQ,CAAC,OAAO,EAAE,wDAAwD,CAAC;SAC3E,QAAQ,CAAC,SAAS,EAAE,qBAAqB,CAAC;SAC1C,MAAM,CAAC,KAAK,EAAE,GAAW,EAAE,KAAa,EAAE,EAAE;QAC3C,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAElC,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,UAAU;gBACb,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC5B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,KAAK,EAAE,CAAC,CAAC,CAAC;oBACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;gBACD,MAAM,CAAC,eAAe,GAAG,KAAqB,CAAC;gBAC/C,MAAM;YACR,KAAK,OAAO;gBACV,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC;gBAC5B,MAAM;YACR,KAAK,SAAS;gBACZ,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACrD,MAAM;YACR,KAAK,UAAU;gBACb,MAAM,CAAC,QAAQ,GAAG,KAAK,KAAK,MAAM,CAAC;gBACnC,MAAM;YACR;gBACE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC,CAAC;gBACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC,CAAC;gBAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEL,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/cli/login.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,kBAAkB,IAAI,OAAO,CAmC5C"}
|