Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
31b16a3
feat: shared line signup, login, and contacts
abhiramkast Apr 14, 2026
c07247d
fix: update tests for changed error messages
abhiramkast Apr 14, 2026
ab05865
refactor: extract shared line guard into requireSharedLine helper
abhiramkast Apr 14, 2026
112f6a9
fix: standardize error handling — remove any cast, consistent formatting
abhiramkast Apr 14, 2026
4a0d7b1
fix: restore profile merge behavior, filter legacy githubLogin field
abhiramkast Apr 15, 2026
54a167b
feat: webhooks listen/logs, phonenumbers set (#29)
abhiramkast Apr 15, 2026
45ec3be
fix: add ws dependency for Node 20 WebSocket compatibility
abhiramkast Apr 15, 2026
8cf1501
fix: update test — githubLogin is now filtered out on save
abhiramkast Apr 15, 2026
ca0f33a
fix: update tests for login refactor and githubLogin filter
abhiramkast Apr 15, 2026
8b53a15
fix: add timeout to webhooks listen tests to prevent CI OOM
abhiramkast Apr 15, 2026
1fe131b
fix: skip webhooks listen tests in CI (WebSocket mock causes OOM)
abhiramkast Apr 15, 2026
644d2f0
fix: mock ws module instead of global WebSocket for Node 20 compat
abhiramkast Apr 15, 2026
f8f11b6
fix: revert to original spread merge in saveProfile, no githubLogin f…
abhiramkast Apr 15, 2026
3d4d35e
feat: friendlier CLI errors for shared-line + auth flows
abhiramkast May 13, 2026
6870734
docs: update README for email-OTP signup/login flow
abhiramkast May 14, 2026
711902b
docs: tighten README — drop --email/--profile examples and internal e…
abhiramkast May 14, 2026
3ce24b4
chore: remove webhooks logs, drop tgz artifacts, standardize auth err…
abhiramkast May 14, 2026
1c6278b
test: replace obsolete GitHub-flow tests with email-OTP signup/login …
abhiramkast May 14, 2026
9784820
chore: tighten Linq API endpoint comment
abhiramkast May 14, 2026
19174c8
fix: actually remove webhooks logs command (deletion was lost in earl…
abhiramkast May 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ pnpm-debug.log*

# Claude
.claude
*.tgz
144 changes: 100 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,70 +38,92 @@ After installation, the `linq` command will be available in your terminal.

## Quick Start

1. **Run the setup wizard**:
1. **Create your account**:

```bash
linq init
linq signup
```

2. **List your phone numbers**:
Enter your email, paste the 6-digit code we send you, then your name. You get a shared phone line you can use right away.

2. **Add a contact** so they can text you:

```bash
linq contacts add +19876543210
```

3. **Listen for incoming messages**:

```bash
linq phonenumbers
linq webhooks listen
```

3. **Create a chat and send a message**:
Have the contact text your shared line — events stream into your terminal.

4. **Reply back**:

```bash
linq chats create --to +19876543210 --from +12025551234 --message "Hello from Linq!"
linq chats create --to +19876543210 --message "Hi from the CLI!"
```

> **Heads up:** shared lines are inbound-first. Someone on your contact list has to text you before you can text them. Upgrade to a dedicated line to message anyone without that restriction.

## Commands

### Setup

#### `linq init`
#### `linq signup`

Interactive setup wizard. Validates your API token and selects a default phone number.
Create a Linq developer account and get a shared phone line. Authenticates via email OTP — no API token needed.

```bash
linq init
linq signup
```

#### `linq signup`
The flow: enter email → check inbox for the 6-digit code → enter the code → enter your name. You're in.

Get a sandbox phone number for testing. Authenticates via GitHub and provisions a temporary sandbox number (valid for 3 hours). Credentials are saved to the `sandbox` profile.
#### `linq login`

Log in to an existing account using email OTP.

```bash
linq signup
linq login
```

#### `linq doctor`
#### `linq logout`

Check your CLI configuration and API connectivity. Runs diagnostic checks and reports any issues.
Clear local credentials. Does **not** revoke your API key on the server — just removes the stored token from this machine.

```bash
linq doctor
linq logout
```

### Authentication
#### `linq whoami`

#### `linq login`
Show your current identity and account info.

Authenticate with Linq and save your API token. Get your token from [Integration Details](https://zero.linqapp.com/api-tooling/) in the Linq dashboard.
```bash
linq whoami
linq whoami --json
```

#### `linq doctor`

Check your CLI configuration and API connectivity. Runs diagnostic checks and reports any issues.

```bash
# Interactive prompt
linq login
linq doctor
```

#### `linq init`

# Or provide token directly
linq login --token YOUR_API_TOKEN
Interactive setup wizard. Useful if you already have an API token (e.g. from the dashboard) and want to wire it up to the CLI without going through the OTP flow.

# Save to a specific profile
linq login --profile work
```bash
linq init
```

Your token is saved to the active profile in `~/.linq/config.json`.
### Profile

#### `linq profile get|set`

Expand All @@ -111,7 +133,7 @@ Manage profile configuration values.
# View current profile config
linq profile get

# Set your API token
# Set your API token manually
linq profile set token YOUR_API_TOKEN

# Set default sender phone (must be one from `linq phonenumbers`)
Expand All @@ -129,7 +151,6 @@ linq profile list
# default (active)
# personal
# work
# sandbox (sandbox +14043848368, expires 8:12:53 PM)
```

#### `linq profile use`
Expand Down Expand Up @@ -159,21 +180,14 @@ linq profile delete staging

### Profiles

Profiles work like AWS CLI profiles - switch between different accounts or phone numbers easily.

The `sandbox` profile is reserved and managed by `linq signup`. It stores credentials for your temporary sandbox phone number.
Profiles work like AWS CLI profiles — switch between different accounts or phone numbers easily. `linq signup` and `linq login` save credentials to the `default` profile.

```bash
# Create a work profile
linq profile create work
linq profile set token WORK_TOKEN --profile work
linq profile set fromPhone +18005551234 --profile work

# Create a personal profile
linq profile create personal
linq profile set token PERSONAL_TOKEN --profile personal
linq profile set fromPhone +12025551234 --profile personal

# Switch default profile
linq profile use work

Expand All @@ -182,8 +196,8 @@ linq chats create --to +19876543210 --message "Hello" --profile personal
```

Environment variables:
- `LINQ_PROFILE` - Override the active profile
- `LINQ_FROM_PHONE` - Override the sender phone number
- `LINQ_PROFILE` Override the active profile
- `LINQ_FROM_PHONE` Override the sender phone number

### Phone Numbers

Expand All @@ -195,6 +209,42 @@ List your available phone numbers.
linq phonenumbers
```

#### `linq phonenumbers set`

Set the default sender phone for the active profile.

```bash
linq phonenumbers set +12025551234
```

### Contacts (shared line)

Shared lines are inbound-first: a contact must text you before you can text them. Use `linq contacts` to manage the allowed contact list (max 100 per shared line).

#### `linq contacts add`

Allow a phone number to message your shared line.

```bash
linq contacts add +19876543210
```

#### `linq contacts list`

List all contacts on your shared line.

```bash
linq contacts list
```

#### `linq contacts remove`

Remove a contact.

```bash
linq contacts remove +19876543210
```

### Chats

#### `linq chats create`
Expand Down Expand Up @@ -524,27 +574,35 @@ linq webhooks events

#### `linq webhooks listen`

Listen for webhook events in real time. Creates a temporary webhook subscription that's automatically deleted when you stop.
Listen for webhook events in real time, optionally forwarding them to a local server. Creates a temporary webhook subscription that's automatically deleted when you stop.

```bash
# Listen for all events
# Listen for all events (structured log output)
linq webhooks listen

# Listen for specific events only
# Forward to a local server (great for local dev)
linq webhooks listen --forward-to http://localhost:3000/webhook

# Filter to specific events
linq webhooks listen --events message.received,message.sent

# Output raw JSON instead of structured logs
linq webhooks listen --json
```

**Flags:**
- `--forward-to`, `-f`: Forward each event to a local URL via HTTP POST
- `--events`: Comma-separated list of events to subscribe to (default: all)
- `--token`, `-t`: API token (overrides stored token)
- `--profile`: Config profile to use
- `--json`: Output raw JSON instead of structured log format

Events are displayed in a structured log format:

```
2024-01-15T10:30:45.123Z [message.received] message.id=msg_123 message.body="Hello world" message.chat_id=chat_456
```

Use `--json` for raw JSON output (useful for piping to `jq`).

Press `Ctrl+C` to stop. The CLI automatically cleans up the webhook subscription.

## Shell Autocomplete
Expand Down Expand Up @@ -585,8 +643,6 @@ export LINQ_TELEMETRY=0
- `LINQ_TOKEN`: API token (overrides config file)
- `LINQ_FROM_PHONE`: Default sender phone number (overrides config file)
- `LINQ_PROFILE`: Profile to use (overrides config file)
- `LINQ_RELAY_URL`: Custom relay URL for `webhooks listen`
- `LINQ_RELAY_WS_URL`: Custom WebSocket relay URL for `webhooks listen`
- `LINQ_TELEMETRY`: Set to `0` to disable telemetry

## Contributing
Expand Down
34 changes: 33 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@
"@oclif/plugin-autocomplete": "^3.2.40",
"@oclif/plugin-help": "^6.2.37",
"@sentry/node": "^10.38.0",
"@types/ws": "^8.18.1",
"chalk": "^5.6.2",
"open": "^11.0.0"
"open": "^11.0.0",
"ws": "^8.20.0"
},
"devDependencies": {
"@commitlint/cli": "^20.4.1",
Expand Down
Loading
Loading