@stephendolan/helpscout-cli 2.4.1 → 2.5.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 +27 -137
- package/dist/cli.js +145 -3
- package/dist/cli.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,218 +1,108 @@
|
|
|
1
1
|
# Help Scout CLI
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@stephendolan/helpscout-cli)
|
|
4
|
-
[](https://www.npmjs.com/package/@stephendolan/helpscout-cli)
|
|
5
4
|
[](https://opensource.org/licenses/MIT)
|
|
6
|
-
[](https://bun.sh)
|
|
7
5
|
|
|
8
|
-
A
|
|
9
|
-
|
|
10
|
-
## Features
|
|
11
|
-
|
|
12
|
-
- **LLM-First Design**: JSON output by default for easy parsing and integration with AI assistants
|
|
13
|
-
- **Output Control**: Strip HTML from bodies, select specific fields, exclude API metadata
|
|
14
|
-
- **Advanced Search**: Full query syntax support for filtering conversations
|
|
15
|
-
- **Comprehensive Coverage**: Conversations, customers, tags, workflows, and mailboxes
|
|
16
|
-
- **Type Safety**: Built with TypeScript for robust error handling
|
|
17
|
-
- **Simple Authentication**: OAuth 2.0 credentials stored securely in OS keychain
|
|
6
|
+
A CLI for Help Scout's Mailbox API 2.0. JSON output by default for LLM and automation workflows.
|
|
18
7
|
|
|
19
8
|
## Installation
|
|
20
9
|
|
|
21
|
-
Requires [Bun](https://bun.sh) runtime.
|
|
22
|
-
|
|
23
10
|
```bash
|
|
24
|
-
# Install globally with bun (recommended)
|
|
25
11
|
bun install -g @stephendolan/helpscout-cli
|
|
26
12
|
|
|
27
|
-
# Or run
|
|
13
|
+
# Or run without installing
|
|
28
14
|
bunx @stephendolan/helpscout-cli conversations list
|
|
29
|
-
npx @stephendolan/helpscout-cli conversations list # also works
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Linux Prerequisites
|
|
33
|
-
|
|
34
|
-
Requires `libsecret` for keychain storage:
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
# Ubuntu/Debian
|
|
38
|
-
sudo apt-get install libsecret-1-dev
|
|
39
|
-
|
|
40
|
-
# Fedora/RHEL
|
|
41
|
-
sudo dnf install libsecret-devel
|
|
42
|
-
|
|
43
|
-
# Arch Linux
|
|
44
|
-
sudo pacman -S libsecret
|
|
45
15
|
```
|
|
46
16
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
### From Source
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
git clone https://github.com/stephendolan/helpscout-cli.git
|
|
53
|
-
cd helpscout-cli
|
|
54
|
-
bun install
|
|
55
|
-
bun run link # Build and link globally
|
|
56
|
-
```
|
|
17
|
+
**Linux**: Requires `libsecret` for keychain storage (`apt install libsecret-1-dev`), or use environment variables.
|
|
57
18
|
|
|
58
19
|
## Authentication
|
|
59
20
|
|
|
60
|
-
|
|
21
|
+
Create an OAuth app at [Help Scout > Your Profile > My Apps](https://secure.helpscout.net/authentication/authorizeClientApplication).
|
|
61
22
|
|
|
62
23
|
```bash
|
|
63
24
|
helpscout auth login --app-id YOUR_APP_ID --app-secret YOUR_APP_SECRET
|
|
64
|
-
helpscout auth status
|
|
65
|
-
helpscout auth logout
|
|
25
|
+
helpscout auth status
|
|
26
|
+
helpscout auth logout
|
|
66
27
|
```
|
|
67
28
|
|
|
68
|
-
Or use environment variables:
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
export HELPSCOUT_APP_ID=your_app_id
|
|
72
|
-
export HELPSCOUT_APP_SECRET=your_app_secret
|
|
73
|
-
export HELPSCOUT_MAILBOX_ID=your_default_mailbox_id # Optional
|
|
74
|
-
```
|
|
29
|
+
Or use environment variables: `HELPSCOUT_APP_ID`, `HELPSCOUT_APP_SECRET`, `HELPSCOUT_MAILBOX_ID`
|
|
75
30
|
|
|
76
|
-
##
|
|
31
|
+
## Commands
|
|
77
32
|
|
|
78
33
|
### Conversations
|
|
79
34
|
|
|
80
35
|
```bash
|
|
81
|
-
# List conversations
|
|
82
36
|
helpscout conversations list
|
|
83
|
-
helpscout conversations list --status active
|
|
84
|
-
helpscout conversations list
|
|
85
|
-
|
|
86
|
-
# Advanced search
|
|
87
|
-
helpscout conversations list -q 'status:open tag:urgent'
|
|
88
|
-
helpscout conversations list -q 'customer:john@example.com'
|
|
89
|
-
|
|
90
|
-
# Aggregated summary
|
|
37
|
+
helpscout conversations list --status active --mailbox 123 --tag urgent
|
|
38
|
+
helpscout conversations list -q 'status:open customer:john@example.com'
|
|
91
39
|
helpscout conversations list --summary
|
|
92
40
|
|
|
93
|
-
# View a conversation
|
|
94
41
|
helpscout conversations view 456
|
|
95
|
-
|
|
96
|
-
# View conversation threads
|
|
97
42
|
helpscout conversations threads 456
|
|
98
|
-
|
|
99
|
-
|
|
43
|
+
helpscout conversations reply 456 --text "Thanks for reaching out!"
|
|
44
|
+
helpscout conversations note 456 --text "Internal note"
|
|
100
45
|
helpscout conversations add-tag 456 urgent
|
|
101
46
|
helpscout conversations remove-tag 456 urgent
|
|
102
|
-
|
|
103
|
-
# Reply to a conversation
|
|
104
|
-
helpscout conversations reply 456 --text "Thank you for reaching out!"
|
|
105
|
-
|
|
106
|
-
# Add a note
|
|
107
|
-
helpscout conversations note 456 --text "Internal note here"
|
|
108
|
-
|
|
109
|
-
# Delete a conversation
|
|
110
47
|
helpscout conversations delete 456
|
|
111
48
|
```
|
|
112
49
|
|
|
113
50
|
### Customers
|
|
114
51
|
|
|
115
52
|
```bash
|
|
116
|
-
# List customers
|
|
117
53
|
helpscout customers list
|
|
118
54
|
helpscout customers list --first-name John
|
|
119
|
-
|
|
120
|
-
# View a customer
|
|
121
55
|
helpscout customers view 789
|
|
122
|
-
|
|
123
|
-
# Create a customer
|
|
124
56
|
helpscout customers create --first-name John --last-name Doe --email john@example.com
|
|
125
|
-
|
|
126
|
-
# Update a customer
|
|
127
57
|
helpscout customers update 789 --organization "Acme Corp"
|
|
128
|
-
|
|
129
|
-
# Delete a customer
|
|
130
58
|
helpscout customers delete 789
|
|
131
59
|
```
|
|
132
60
|
|
|
133
|
-
### Tags
|
|
61
|
+
### Tags, Workflows, Mailboxes
|
|
134
62
|
|
|
135
63
|
```bash
|
|
136
|
-
# List all tags
|
|
137
64
|
helpscout tags list
|
|
138
|
-
|
|
139
|
-
# View a tag
|
|
140
65
|
helpscout tags view 123
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Workflows
|
|
144
66
|
|
|
145
|
-
```bash
|
|
146
|
-
# List workflows
|
|
147
67
|
helpscout workflows list
|
|
148
68
|
helpscout workflows list --type manual
|
|
149
|
-
|
|
150
|
-
# Run a manual workflow
|
|
151
69
|
helpscout workflows run 123 --conversations 456,789
|
|
152
|
-
|
|
153
|
-
# Activate/deactivate
|
|
154
70
|
helpscout workflows activate 123
|
|
155
71
|
helpscout workflows deactivate 123
|
|
156
|
-
```
|
|
157
72
|
|
|
158
|
-
### Mailboxes
|
|
159
|
-
|
|
160
|
-
```bash
|
|
161
|
-
# List mailboxes
|
|
162
73
|
helpscout mailboxes list
|
|
163
|
-
|
|
164
|
-
# View a mailbox
|
|
165
74
|
helpscout mailboxes view 123
|
|
166
|
-
|
|
167
|
-
# Set default mailbox
|
|
168
75
|
helpscout mailboxes set-default 123
|
|
169
76
|
```
|
|
170
77
|
|
|
171
|
-
##
|
|
172
|
-
|
|
173
|
-
- `-c, --compact` - Output minified JSON (single line)
|
|
174
|
-
- `-p, --plain` - Strip HTML from body fields, output plain text
|
|
175
|
-
- `-f, --fields <fields>` - Comma-separated list of fields to include in output
|
|
176
|
-
- `--include-metadata` - Include `_links` and `_embedded` in responses (stripped by default)
|
|
177
|
-
- `--help` - Show help for any command
|
|
178
|
-
|
|
179
|
-
## Output Format
|
|
78
|
+
## Options
|
|
180
79
|
|
|
181
|
-
|
|
80
|
+
| Flag | Description |
|
|
81
|
+
|------|-------------|
|
|
82
|
+
| `-c, --compact` | Minified JSON output |
|
|
83
|
+
| `-p, --plain` | Strip HTML from body fields |
|
|
84
|
+
| `-f, --fields <fields>` | Include only specified fields |
|
|
85
|
+
| `--include-metadata` | Include `_links` and `_embedded` |
|
|
182
86
|
|
|
183
|
-
|
|
184
|
-
- **Single items**: Objects directly
|
|
185
|
-
- **Errors**: `{"error": {"name": "...", "detail": "...", "statusCode": 400}}`
|
|
186
|
-
|
|
187
|
-
### Working with JSON Output
|
|
87
|
+
## Output
|
|
188
88
|
|
|
189
89
|
```bash
|
|
190
|
-
#
|
|
90
|
+
# Filter with jq
|
|
191
91
|
helpscout conversations list | jq '.conversations[].subject'
|
|
192
92
|
|
|
193
|
-
#
|
|
93
|
+
# Select fields
|
|
194
94
|
helpscout conversations list --fields id,subject
|
|
195
95
|
|
|
196
|
-
#
|
|
96
|
+
# Plain text bodies
|
|
197
97
|
helpscout conversations threads 456 --plain
|
|
198
|
-
|
|
199
|
-
# Count conversations by status
|
|
200
|
-
helpscout conversations list --summary | jq '.byStatus'
|
|
201
98
|
```
|
|
202
99
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
Help Scout enforces these rate limits:
|
|
206
|
-
|
|
207
|
-
- **200 requests per minute** per account
|
|
208
|
-
- **12 write requests per 5 seconds** (POST, PUT, DELETE)
|
|
209
|
-
|
|
210
|
-
When exceeded, the API returns HTTP 429 errors. The CLI will report these as JSON errors.
|
|
100
|
+
Errors return: `{"error": {"name": "...", "detail": "...", "statusCode": 400}}`
|
|
211
101
|
|
|
212
102
|
## References
|
|
213
103
|
|
|
214
|
-
- [Help Scout API
|
|
215
|
-
- [
|
|
104
|
+
- [Help Scout API Docs](https://developer.helpscout.com/mailbox-api/)
|
|
105
|
+
- [Search Filters](https://docs.helpscout.com/article/47-search-filters-with-operators)
|
|
216
106
|
|
|
217
107
|
## License
|
|
218
108
|
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command8 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/lib/output.ts
|
|
7
7
|
import { convert } from "html-to-text";
|
|
@@ -1136,9 +1136,150 @@ function createWorkflowsCommand() {
|
|
|
1136
1136
|
return cmd;
|
|
1137
1137
|
}
|
|
1138
1138
|
|
|
1139
|
+
// src/commands/mcp.ts
|
|
1140
|
+
import { Command as Command7 } from "commander";
|
|
1141
|
+
|
|
1142
|
+
// src/mcp/server.ts
|
|
1143
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
1144
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
1145
|
+
import { z } from "zod";
|
|
1146
|
+
var server = new McpServer({
|
|
1147
|
+
name: "helpscout",
|
|
1148
|
+
version: "1.0.0"
|
|
1149
|
+
});
|
|
1150
|
+
function jsonResponse(data) {
|
|
1151
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
1152
|
+
}
|
|
1153
|
+
server.tool(
|
|
1154
|
+
"list_conversations",
|
|
1155
|
+
"List conversations with optional filtering by status, mailbox, tag, or assignee",
|
|
1156
|
+
{
|
|
1157
|
+
status: z.enum(["active", "pending", "closed", "spam", "all"]).optional().describe("Conversation status filter"),
|
|
1158
|
+
mailbox: z.string().optional().describe("Mailbox ID to filter by"),
|
|
1159
|
+
tag: z.string().optional().describe("Tag to filter by"),
|
|
1160
|
+
assignedTo: z.string().optional().describe("User ID assigned to"),
|
|
1161
|
+
query: z.string().optional().describe("Search query"),
|
|
1162
|
+
page: z.number().optional().describe("Page number")
|
|
1163
|
+
},
|
|
1164
|
+
async ({ status, mailbox, tag, assignedTo, query, page }) => jsonResponse(await client.listConversations({ status, mailbox, tag, assignedTo, query, page }))
|
|
1165
|
+
);
|
|
1166
|
+
server.tool(
|
|
1167
|
+
"get_conversation",
|
|
1168
|
+
"Get detailed information about a specific conversation including threads",
|
|
1169
|
+
{
|
|
1170
|
+
conversationId: z.number().describe("Conversation ID"),
|
|
1171
|
+
includeThreads: z.boolean().optional().describe("Include conversation threads")
|
|
1172
|
+
},
|
|
1173
|
+
async ({ conversationId, includeThreads }) => {
|
|
1174
|
+
const conversation = await client.getConversation(conversationId);
|
|
1175
|
+
if (includeThreads) {
|
|
1176
|
+
const threads = await client.getConversationThreads(conversationId);
|
|
1177
|
+
return jsonResponse({ ...conversation, threads });
|
|
1178
|
+
}
|
|
1179
|
+
return jsonResponse(conversation);
|
|
1180
|
+
}
|
|
1181
|
+
);
|
|
1182
|
+
server.tool(
|
|
1183
|
+
"search_conversations",
|
|
1184
|
+
"Search all conversations matching a query",
|
|
1185
|
+
{
|
|
1186
|
+
query: z.string().describe('Search query (e.g., "email:domain.com", "subject:billing")'),
|
|
1187
|
+
status: z.enum(["active", "pending", "closed", "spam", "all"]).optional().describe("Status filter")
|
|
1188
|
+
},
|
|
1189
|
+
async ({ query, status }) => jsonResponse(await client.listAllConversations({ query, status }))
|
|
1190
|
+
);
|
|
1191
|
+
server.tool(
|
|
1192
|
+
"list_mailboxes",
|
|
1193
|
+
"List all mailboxes in the Help Scout account",
|
|
1194
|
+
{},
|
|
1195
|
+
async () => jsonResponse(await client.listMailboxes())
|
|
1196
|
+
);
|
|
1197
|
+
server.tool(
|
|
1198
|
+
"get_mailbox",
|
|
1199
|
+
"Get detailed information about a specific mailbox",
|
|
1200
|
+
{ mailboxId: z.number().describe("Mailbox ID") },
|
|
1201
|
+
async ({ mailboxId }) => jsonResponse(await client.getMailbox(mailboxId))
|
|
1202
|
+
);
|
|
1203
|
+
server.tool(
|
|
1204
|
+
"list_customers",
|
|
1205
|
+
"List customers with optional filtering",
|
|
1206
|
+
{
|
|
1207
|
+
query: z.string().optional().describe("Search query"),
|
|
1208
|
+
firstName: z.string().optional().describe("Filter by first name"),
|
|
1209
|
+
lastName: z.string().optional().describe("Filter by last name"),
|
|
1210
|
+
page: z.number().optional().describe("Page number")
|
|
1211
|
+
},
|
|
1212
|
+
async ({ query, firstName, lastName, page }) => jsonResponse(await client.listCustomers({ query, firstName, lastName, page }))
|
|
1213
|
+
);
|
|
1214
|
+
server.tool(
|
|
1215
|
+
"get_customer",
|
|
1216
|
+
"Get detailed information about a specific customer",
|
|
1217
|
+
{ customerId: z.number().describe("Customer ID") },
|
|
1218
|
+
async ({ customerId }) => jsonResponse(await client.getCustomer(customerId))
|
|
1219
|
+
);
|
|
1220
|
+
server.tool(
|
|
1221
|
+
"list_tags",
|
|
1222
|
+
"List all tags in the Help Scout account",
|
|
1223
|
+
{ page: z.number().optional().describe("Page number") },
|
|
1224
|
+
async ({ page }) => jsonResponse(await client.listTags(page))
|
|
1225
|
+
);
|
|
1226
|
+
server.tool(
|
|
1227
|
+
"list_workflows",
|
|
1228
|
+
"List workflows with optional filtering",
|
|
1229
|
+
{
|
|
1230
|
+
mailbox: z.number().optional().describe("Mailbox ID to filter by"),
|
|
1231
|
+
type: z.enum(["automatic", "manual"]).optional().describe("Workflow type"),
|
|
1232
|
+
page: z.number().optional().describe("Page number")
|
|
1233
|
+
},
|
|
1234
|
+
async ({ mailbox, type, page }) => jsonResponse(await client.listWorkflows({ mailbox, type, page }))
|
|
1235
|
+
);
|
|
1236
|
+
server.tool(
|
|
1237
|
+
"create_note",
|
|
1238
|
+
"Add a private note to a conversation",
|
|
1239
|
+
{
|
|
1240
|
+
conversationId: z.number().describe("Conversation ID"),
|
|
1241
|
+
text: z.string().describe("Note text content")
|
|
1242
|
+
},
|
|
1243
|
+
async ({ conversationId, text }) => {
|
|
1244
|
+
await client.createNote(conversationId, { text });
|
|
1245
|
+
return jsonResponse({ success: true });
|
|
1246
|
+
}
|
|
1247
|
+
);
|
|
1248
|
+
server.tool(
|
|
1249
|
+
"add_tag",
|
|
1250
|
+
"Add a tag to a conversation",
|
|
1251
|
+
{
|
|
1252
|
+
conversationId: z.number().describe("Conversation ID"),
|
|
1253
|
+
tag: z.string().describe("Tag name to add")
|
|
1254
|
+
},
|
|
1255
|
+
async ({ conversationId, tag }) => {
|
|
1256
|
+
await client.addConversationTag(conversationId, tag);
|
|
1257
|
+
return jsonResponse({ success: true });
|
|
1258
|
+
}
|
|
1259
|
+
);
|
|
1260
|
+
server.tool(
|
|
1261
|
+
"check_auth",
|
|
1262
|
+
"Check if Help Scout authentication is configured",
|
|
1263
|
+
{},
|
|
1264
|
+
async () => jsonResponse({ authenticated: await auth.isAuthenticated() })
|
|
1265
|
+
);
|
|
1266
|
+
async function runMcpServer() {
|
|
1267
|
+
const transport = new StdioServerTransport();
|
|
1268
|
+
await server.connect(transport);
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
// src/commands/mcp.ts
|
|
1272
|
+
function createMcpCommand() {
|
|
1273
|
+
const cmd = new Command7("mcp").description("Run Help Scout MCP server");
|
|
1274
|
+
cmd.action(async () => {
|
|
1275
|
+
await runMcpServer();
|
|
1276
|
+
});
|
|
1277
|
+
return cmd;
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1139
1280
|
// src/cli.ts
|
|
1140
|
-
var program = new
|
|
1141
|
-
program.name("helpscout").description("A command-line interface for Help Scout").version("2.
|
|
1281
|
+
var program = new Command8();
|
|
1282
|
+
program.name("helpscout").description("A command-line interface for Help Scout").version("2.5.0").option("-c, --compact", "Minified JSON output (single line)").option("-p, --plain", "Strip HTML from body fields, output plain text").option("--include-metadata", "Include _links and _embedded in responses (stripped by default)").option("-f, --fields <fields>", "Comma-separated list of fields to include in output").hook("preAction", (thisCommand) => {
|
|
1142
1283
|
const options = thisCommand.opts();
|
|
1143
1284
|
setOutputOptions({
|
|
1144
1285
|
compact: options.compact,
|
|
@@ -1153,6 +1294,7 @@ program.addCommand(createConversationsCommand());
|
|
|
1153
1294
|
program.addCommand(createCustomersCommand());
|
|
1154
1295
|
program.addCommand(createTagsCommand());
|
|
1155
1296
|
program.addCommand(createWorkflowsCommand());
|
|
1297
|
+
program.addCommand(createMcpCommand());
|
|
1156
1298
|
program.parseAsync().catch(() => {
|
|
1157
1299
|
process.exit(1);
|
|
1158
1300
|
});
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/lib/output.ts","../src/commands/auth.ts","../src/lib/auth.ts","../src/lib/config.ts","../src/lib/errors.ts","../src/lib/api-client.ts","../src/lib/command-utils.ts","../src/commands/mailboxes.ts","../src/commands/conversations.ts","../src/lib/dates.ts","../src/commands/customers.ts","../src/commands/tags.ts","../src/commands/workflows.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport { Command } from 'commander';\nimport { setOutputOptions } from './lib/output.js';\nimport { createAuthCommand } from './commands/auth.js';\nimport { createMailboxesCommand } from './commands/mailboxes.js';\nimport { createConversationsCommand } from './commands/conversations.js';\nimport { createCustomersCommand } from './commands/customers.js';\nimport { createTagsCommand } from './commands/tags.js';\nimport { createWorkflowsCommand } from './commands/workflows.js';\n\ndeclare const __VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name('helpscout')\n .description('A command-line interface for Help Scout')\n .version(__VERSION__)\n .option('-c, --compact', 'Minified JSON output (single line)')\n .option('-p, --plain', 'Strip HTML from body fields, output plain text')\n .option('--include-metadata', 'Include _links and _embedded in responses (stripped by default)')\n .option('-f, --fields <fields>', 'Comma-separated list of fields to include in output')\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n setOutputOptions({\n compact: options.compact,\n slim: !options.includeMetadata,\n plain: options.plain,\n fields: options.fields,\n });\n });\n\nprogram.addCommand(createAuthCommand());\nprogram.addCommand(createMailboxesCommand());\nprogram.addCommand(createConversationsCommand());\nprogram.addCommand(createCustomersCommand());\nprogram.addCommand(createTagsCommand());\nprogram.addCommand(createWorkflowsCommand());\n\nprogram.parseAsync().catch(() => {\n process.exit(1);\n});\n","import { convert } from 'html-to-text';\nimport type { OutputOptions } from '../types/index.js';\n\nlet globalOutputOptions: OutputOptions = {};\n\nexport function setOutputOptions(options: OutputOptions): void {\n globalOutputOptions = options;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function htmlToPlainText(html: string): string {\n const text = convert(html, {\n wordwrap: false,\n preserveNewlines: false,\n selectors: [\n { selector: 'a', options: { ignoreHref: true } },\n { selector: 'img', format: 'skip' },\n ],\n });\n\n return text\n .replace(/\\n{3,}/g, '\\n\\n')\n .replace(/[ \\t]+/g, ' ')\n .trim();\n}\n\nfunction convertBodiesToPlainText(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(convertBodiesToPlainText);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (key === 'body' && typeof value === 'string') {\n result[key] = htmlToPlainText(value);\n } else {\n result[key] = convertBodiesToPlainText(value);\n }\n }\n return result;\n }\n\n return data;\n}\n\nfunction stripMetadata(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(stripMetadata);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (key === '_links' || key === '_embedded') {\n continue;\n }\n result[key] = stripMetadata(value);\n }\n return result;\n }\n\n return data;\n}\n\nfunction stripTagStyles(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(stripTagStyles);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n const isTag = 'id' in data && 'name' in data && 'slug' in data;\n\n for (const [key, value] of Object.entries(data)) {\n if (isTag && (key === 'color' || key === 'styles')) {\n continue;\n }\n result[key] = stripTagStyles(value);\n }\n return result;\n }\n\n return data;\n}\n\nexport function buildName(first?: string, last?: string): string | undefined {\n const name = [first, last].filter(Boolean).join(' ');\n return name || undefined;\n}\n\nfunction isPersonObject(data: Record<string, unknown>): boolean {\n return ('first' in data || 'last' in data) && ('email' in data || 'id' in data);\n}\n\nfunction isPlaceholderPerson(data: Record<string, unknown>): boolean {\n return data.id === 0 || data.first === 'unknown';\n}\n\nfunction addNameToPersonObjects(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(addNameToPersonObjects);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n result[key] = addNameToPersonObjects(value);\n }\n\n if (isPersonObject(result) && !isPlaceholderPerson(result)) {\n const name = buildName(result.first as string | undefined, result.last as string | undefined);\n if (name) {\n result.name = name;\n }\n }\n\n return result;\n }\n\n return data;\n}\n\nfunction stripPlaceholderValues(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(stripPlaceholderValues);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (key === 'closedBy' && value === 0) continue;\n if (key === 'savedReplyId' && value === 0) continue;\n\n if (isObject(value) && isPlaceholderPerson(value)) continue;\n\n result[key] = stripPlaceholderValues(value);\n }\n\n return result;\n }\n\n return data;\n}\n\nfunction stripEmptyArrays(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(stripEmptyArrays);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (Array.isArray(value) && value.length === 0) continue;\n result[key] = stripEmptyArrays(value);\n }\n\n return result;\n }\n\n return data;\n}\n\nfunction stripPhotoUrls(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(stripPhotoUrls);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (key === 'photoUrl') continue;\n result[key] = stripPhotoUrls(value);\n }\n\n return result;\n }\n\n return data;\n}\n\nfunction selectFields(data: unknown, fields: string[]): unknown {\n if (Array.isArray(data)) {\n return data.map((item) => selectFields(item, fields));\n }\n\n if (isObject(data)) {\n const hasRequestedFields = fields.some((f) => f in data);\n if (hasRequestedFields) {\n const result: Record<string, unknown> = {};\n for (const field of fields) {\n if (field in data) {\n result[field] = data[field];\n }\n }\n return result;\n }\n\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n result[key] = selectFields(value, fields);\n }\n return result;\n }\n\n return data;\n}\n\nexport function outputJson(data: unknown, options: OutputOptions = {}): void {\n const mergedOptions = { ...globalOutputOptions, ...options };\n\n let processed = data;\n\n if (mergedOptions.slim) {\n processed = stripMetadata(processed);\n }\n\n if (mergedOptions.plain) {\n processed = convertBodiesToPlainText(processed);\n }\n\n processed = stripTagStyles(processed);\n processed = addNameToPersonObjects(processed);\n processed = stripPlaceholderValues(processed);\n processed = stripEmptyArrays(processed);\n processed = stripPhotoUrls(processed);\n\n if (mergedOptions.fields) {\n const fieldList = mergedOptions.fields.split(',').map((f) => f.trim());\n processed = selectFields(processed, fieldList);\n }\n\n const jsonString = mergedOptions.compact\n ? JSON.stringify(processed)\n : JSON.stringify(processed, null, 2);\n\n console.log(jsonString);\n}\n","import { Command } from 'commander';\nimport { auth } from '../lib/auth.js';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\n\nexport function createAuthCommand(): Command {\n const cmd = new Command('auth').description('Authentication operations');\n\n cmd\n .command('login')\n .description('Configure Help Scout API credentials')\n .requiredOption('--app-id <id>', 'Help Scout App ID')\n .requiredOption('--app-secret <secret>', 'Help Scout App Secret')\n .action(\n withErrorHandling(async (options: { appId: string; appSecret: string }) => {\n await auth.setAppId(options.appId);\n await auth.setAppSecret(options.appSecret);\n\n client.clearToken();\n await client.refreshAccessToken();\n\n outputJson({ message: 'Successfully authenticated with Help Scout' });\n })\n );\n\n cmd\n .command('logout')\n .description('Remove stored credentials')\n .action(\n withErrorHandling(async () => {\n await auth.logout();\n client.clearToken();\n outputJson({ message: 'Logged out successfully' });\n })\n );\n\n cmd\n .command('status')\n .description('Check authentication status')\n .action(\n withErrorHandling(async () => {\n const hasToken = await auth.isAuthenticated();\n const hasAppId = !!(await auth.getAppId());\n const hasAppSecret = !!(await auth.getAppSecret());\n\n outputJson({\n authenticated: hasToken,\n configured: hasAppId && hasAppSecret,\n });\n })\n );\n\n cmd\n .command('refresh')\n .description('Refresh access token')\n .action(\n withErrorHandling(async () => {\n client.clearToken();\n await client.refreshAccessToken();\n outputJson({ message: 'Access token refreshed' });\n })\n );\n\n return cmd;\n}\n","import { Entry } from '@napi-rs/keyring';\nimport { config } from './config.js';\n\nconst SERVICE_NAME = 'helpscout-cli';\nconst ACCESS_TOKEN_ACCOUNT = 'access-token';\nconst REFRESH_TOKEN_ACCOUNT = 'refresh-token';\nconst APP_ID_ACCOUNT = 'app-id';\nconst APP_SECRET_ACCOUNT = 'app-secret';\n\nconst KEYRING_UNAVAILABLE_ERROR =\n 'Keychain storage unavailable. Cannot store credentials securely.\\n' +\n 'On Linux, install libsecret: sudo apt-get install libsecret-1-dev\\n' +\n 'Then reinstall: bun install -g @stephendolan/helpscout-cli\\n' +\n 'Alternatively, use HELPSCOUT_APP_ID and HELPSCOUT_APP_SECRET environment variables.';\n\nconst keyringCache = new Map<string, Entry | null>();\n\nfunction getKeyring(account: string): Entry | null {\n if (keyringCache.has(account)) {\n return keyringCache.get(account)!;\n }\n try {\n const entry = new Entry(SERVICE_NAME, account);\n keyringCache.set(account, entry);\n return entry;\n } catch {\n keyringCache.set(account, null);\n return null;\n }\n}\n\nasync function getPassword(account: string): Promise<string | null> {\n const entry = getKeyring(account);\n if (entry) {\n try {\n return entry.getPassword();\n } catch {\n return null;\n }\n }\n return null;\n}\n\nasync function setPassword(account: string, value: string): Promise<void> {\n const entry = getKeyring(account);\n if (!entry) {\n throw new Error(KEYRING_UNAVAILABLE_ERROR);\n }\n entry.setPassword(value);\n}\n\nasync function deletePassword(account: string): Promise<boolean> {\n const entry = getKeyring(account);\n if (entry) {\n return entry.deletePassword();\n }\n return false;\n}\n\nexport class AuthManager {\n async getAccessToken(): Promise<string | null> {\n return getPassword(ACCESS_TOKEN_ACCOUNT);\n }\n\n async setAccessToken(token: string): Promise<void> {\n return setPassword(ACCESS_TOKEN_ACCOUNT, token);\n }\n\n async getRefreshToken(): Promise<string | null> {\n return getPassword(REFRESH_TOKEN_ACCOUNT);\n }\n\n async setRefreshToken(token: string): Promise<void> {\n return setPassword(REFRESH_TOKEN_ACCOUNT, token);\n }\n\n async getAppId(): Promise<string | null> {\n const keychainValue = await getPassword(APP_ID_ACCOUNT);\n return keychainValue || process.env.HELPSCOUT_APP_ID || null;\n }\n\n async setAppId(appId: string): Promise<void> {\n return setPassword(APP_ID_ACCOUNT, appId);\n }\n\n async getAppSecret(): Promise<string | null> {\n const keychainValue = await getPassword(APP_SECRET_ACCOUNT);\n return keychainValue || process.env.HELPSCOUT_APP_SECRET || null;\n }\n\n async setAppSecret(appSecret: string): Promise<void> {\n return setPassword(APP_SECRET_ACCOUNT, appSecret);\n }\n\n async isAuthenticated(): Promise<boolean> {\n return (await this.getAccessToken()) !== null;\n }\n\n async logout(): Promise<void> {\n await deletePassword(ACCESS_TOKEN_ACCOUNT);\n await deletePassword(REFRESH_TOKEN_ACCOUNT);\n config.clearDefaultMailbox();\n }\n\n async clearAll(): Promise<void> {\n await deletePassword(ACCESS_TOKEN_ACCOUNT);\n await deletePassword(REFRESH_TOKEN_ACCOUNT);\n await deletePassword(APP_ID_ACCOUNT);\n await deletePassword(APP_SECRET_ACCOUNT);\n config.clear();\n }\n}\n\nexport const auth = new AuthManager();\n","import Conf from 'conf';\n\ninterface ConfigSchema {\n defaultMailbox?: string;\n}\n\nconst store = new Conf<ConfigSchema>({\n projectName: 'helpscout-cli',\n});\n\nexport const config = {\n getDefaultMailbox(): string | undefined {\n return store.get('defaultMailbox') || process.env.HELPSCOUT_MAILBOX_ID;\n },\n\n setDefaultMailbox(mailboxId: string): void {\n store.set('defaultMailbox', mailboxId);\n },\n\n clearDefaultMailbox(): void {\n store.delete('defaultMailbox');\n },\n\n clear(): void {\n store.clear();\n },\n};\n","import type { HelpScoutError } from '../types/index.js';\nimport { outputJson } from './output.js';\n\nexport class HelpScoutCliError extends Error {\n constructor(\n message: string,\n public statusCode?: number\n ) {\n super(message);\n this.name = 'HelpScoutCliError';\n }\n}\n\nexport class HelpScoutApiError extends Error {\n constructor(\n message: string,\n public apiError: unknown,\n public statusCode: number\n ) {\n super(message);\n this.name = 'HelpScoutApiError';\n }\n}\n\nconst ERROR_STATUS_CODES: Record<string, number> = {\n bad_request: 400,\n unauthorized: 401,\n forbidden: 403,\n not_found: 404,\n conflict: 409,\n too_many_requests: 429,\n internal_server_error: 500,\n service_unavailable: 503,\n};\n\nexport function sanitizeErrorMessage(message: string): string {\n const sensitivePatterns = [\n /Bearer\\s+[\\w\\-._~+/]+=*/gi,\n /token[=:]\\s*[\\w\\-._~+/]+=*/gi,\n /client[_-]?secret[=:]\\s*[\\w\\-._~+/]+=*/gi,\n /authorization:\\s*bearer\\s+[\\w\\-._~+/]+=*/gi,\n ];\n\n let sanitized = message;\n for (const pattern of sensitivePatterns) {\n sanitized = sanitized.replace(pattern, '[REDACTED]');\n }\n\n return sanitized.length > 500 ? sanitized.substring(0, 500) + '...' : sanitized;\n}\n\ninterface ApiErrorResponse {\n error?: string;\n error_description?: string;\n message?: string;\n _embedded?: {\n errors?: Array<{\n path?: string;\n message?: string;\n rejectedValue?: string;\n }>;\n };\n}\n\nfunction isErrorObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nexport function sanitizeApiError(error: unknown): HelpScoutError {\n if (!isErrorObject(error)) {\n return {\n name: 'api_error',\n detail: 'An error occurred',\n };\n }\n\n const apiError = error as ApiErrorResponse;\n\n let detail = 'An error occurred';\n if (apiError.error_description) {\n detail = apiError.error_description;\n } else if (apiError.message) {\n detail = apiError.message;\n } else if (apiError._embedded?.errors?.length) {\n detail = apiError._embedded.errors\n .map((e) => e.message || e.path)\n .filter(Boolean)\n .join('; ');\n }\n\n return {\n name: apiError.error || 'api_error',\n detail: sanitizeErrorMessage(detail),\n };\n}\n\nfunction formatErrorResponse(name: string, detail: string, statusCode: number): never {\n const hint =\n name === 'too_many_requests'\n ? 'Help Scout API limit: 200 requests/minute. Wait a moment and retry.'\n : undefined;\n\n const response: { error: { name: string; detail: string; statusCode: number }; hint?: string } = {\n error: { name, detail, statusCode },\n };\n\n if (hint) {\n response.hint = hint;\n }\n\n outputJson(response);\n process.exit(1);\n}\n\nexport function handleHelpScoutError(error: unknown): never {\n if (error instanceof HelpScoutCliError) {\n const sanitized = sanitizeErrorMessage(error.message);\n formatErrorResponse('cli_error', sanitized, error.statusCode || 1);\n }\n\n if (error instanceof HelpScoutApiError) {\n const hsError: HelpScoutError = sanitizeApiError(error.apiError);\n formatErrorResponse(\n hsError.name,\n hsError.detail,\n error.statusCode || ERROR_STATUS_CODES[hsError.name] || 500\n );\n }\n\n if (error instanceof Error) {\n const sanitized = sanitizeErrorMessage(error.message);\n formatErrorResponse('unknown_error', sanitized, 1);\n }\n\n formatErrorResponse('unknown_error', 'An unexpected error occurred', 1);\n}\n","import { auth } from './auth.js';\nimport { HelpScoutCliError, HelpScoutApiError } from './errors.js';\nimport type {\n Conversation,\n Customer,\n Tag,\n Workflow,\n Mailbox,\n Thread,\n PageInfo,\n} from '../types/index.js';\n\nconst API_BASE = 'https://api.helpscout.net/v2';\nconst TOKEN_URL = 'https://api.helpscout.net/v2/oauth2/token';\n\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n token_type: string;\n expires_in: number;\n}\n\ninterface PaginatedResponse<T> {\n _embedded: T;\n page: PageInfo;\n}\n\nexport class HelpScoutClient {\n private accessToken: string | null = null;\n\n clearToken(): void {\n this.accessToken = null;\n }\n\n async refreshAccessToken(): Promise<string> {\n const appId = await auth.getAppId();\n const appSecret = await auth.getAppSecret();\n const refreshToken = await auth.getRefreshToken();\n\n if (!appId || !appSecret) {\n throw new HelpScoutCliError('Not configured. Please run: helpscout auth login', 401);\n }\n\n if (refreshToken) {\n try {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n client_id: appId,\n client_secret: appSecret,\n refresh_token: refreshToken,\n }),\n });\n\n if (response.ok) {\n const data = (await response.json()) as TokenResponse;\n await auth.setAccessToken(data.access_token);\n if (data.refresh_token) {\n await auth.setRefreshToken(data.refresh_token);\n }\n this.accessToken = data.access_token;\n return data.access_token;\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n console.error(\n JSON.stringify({\n warning: 'Refresh token failed, using client credentials',\n reason: message,\n })\n );\n }\n }\n\n let response: Response;\n try {\n response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: appId,\n client_secret: appSecret,\n }),\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown network error';\n throw new HelpScoutCliError(`Network request failed during authentication: ${message}`, 0);\n }\n\n if (!response.ok) {\n const error = await response.json();\n throw new HelpScoutApiError('OAuth token request failed', error, response.status);\n }\n\n const data = (await response.json()) as TokenResponse;\n await auth.setAccessToken(data.access_token);\n this.accessToken = data.access_token;\n return data.access_token;\n }\n\n async getAccessToken(): Promise<string> {\n if (this.accessToken) {\n return this.accessToken;\n }\n\n const storedToken = await auth.getAccessToken();\n if (storedToken) {\n this.accessToken = storedToken;\n return storedToken;\n }\n\n return this.refreshAccessToken();\n }\n\n private async request<T>(\n method: string,\n path: string,\n options: {\n params?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n retry?: boolean;\n rateLimitRetry?: boolean;\n } = {}\n ): Promise<T> {\n const { params, body, retry = true, rateLimitRetry = true } = options;\n\n const url = new URL(`${API_BASE}${path}`);\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n });\n }\n\n const token = await this.getAccessToken();\n const fetchOptions: RequestInit = {\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n };\n if (body) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n let response: Response;\n try {\n response = await fetch(url.toString(), fetchOptions);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown network error';\n throw new HelpScoutCliError(`Network request failed: ${message}`, 0);\n }\n\n if (response.status === 401 && retry) {\n this.accessToken = null;\n await this.refreshAccessToken();\n return this.request(method, path, { ...options, retry: false });\n }\n\n if (response.status === 429 && rateLimitRetry) {\n const retryAfter = parseInt(response.headers.get('Retry-After') || '60', 10);\n const waitSeconds = Math.min(retryAfter, 120);\n console.error(\n JSON.stringify({ warning: `Rate limited. Waiting ${waitSeconds}s before retry...` })\n );\n await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1000));\n return this.request(method, path, { ...options, rateLimitRetry: false });\n }\n\n if (response.status === 204) {\n return {} as T;\n }\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new HelpScoutApiError('API request failed', error, response.status);\n }\n\n return response.json() as Promise<T>;\n }\n\n // Conversations\n async listConversations(\n params: {\n mailbox?: string;\n status?: string;\n tag?: string;\n assignedTo?: string;\n sortField?: string;\n sortOrder?: string;\n page?: number;\n embed?: string;\n query?: string;\n } = {}\n ) {\n const response = await this.request<PaginatedResponse<{ conversations: Conversation[] }>>(\n 'GET',\n '/conversations',\n { params }\n );\n return {\n conversations: response._embedded?.conversations || [],\n page: response.page,\n };\n }\n\n async listAllConversations(\n params: {\n mailbox?: string;\n status?: string;\n tag?: string;\n assignedTo?: string;\n query?: string;\n embed?: string;\n } = {}\n ): Promise<Conversation[]> {\n const allConversations: Conversation[] = [];\n let page = 1;\n let totalPages = 1;\n\n do {\n const result = await this.listConversations({ ...params, page });\n allConversations.push(...result.conversations);\n totalPages = result.page.totalPages;\n page++;\n } while (page <= totalPages);\n\n return allConversations;\n }\n\n async getConversation(conversationId: number, embed?: string) {\n const params = embed ? { embed } : undefined;\n return this.request<Conversation>('GET', `/conversations/${conversationId}`, { params });\n }\n\n async getConversationThreads(conversationId: number) {\n const response = await this.request<PaginatedResponse<{ threads: Thread[] }>>(\n 'GET',\n `/conversations/${conversationId}/threads`\n );\n return response._embedded?.threads || [];\n }\n\n async updateConversation(\n conversationId: number,\n data: Partial<{\n op: string;\n path: string;\n value: unknown;\n }>\n ) {\n await this.request<void>('PATCH', `/conversations/${conversationId}`, { body: data });\n }\n\n async deleteConversation(conversationId: number) {\n await this.request<void>('DELETE', `/conversations/${conversationId}`);\n }\n\n async addConversationTag(conversationId: number, tag: string) {\n await this.request<void>('PUT', `/conversations/${conversationId}/tags`, {\n body: { tags: [tag] },\n });\n }\n\n async removeConversationTag(conversationId: number, tag: string) {\n const conversation = await this.getConversation(conversationId);\n const existingTags = conversation?.tags?.map((t) => t.name) || [];\n const newTags = existingTags.filter((t) => t !== tag);\n await this.request<void>('PUT', `/conversations/${conversationId}/tags`, {\n body: { tags: newTags },\n });\n }\n\n async createReply(\n conversationId: number,\n data: {\n text: string;\n user?: number;\n draft?: boolean;\n status?: string;\n }\n ) {\n await this.request<void>('POST', `/conversations/${conversationId}/reply`, { body: data });\n }\n\n async createNote(\n conversationId: number,\n data: {\n text: string;\n user?: number;\n }\n ) {\n await this.request<void>('POST', `/conversations/${conversationId}/notes`, { body: data });\n }\n\n // Customers\n async listCustomers(\n params: {\n mailbox?: string;\n firstName?: string;\n lastName?: string;\n sortField?: string;\n sortOrder?: string;\n page?: number;\n query?: string;\n } = {}\n ) {\n const response = await this.request<PaginatedResponse<{ customers: Customer[] }>>(\n 'GET',\n '/customers',\n { params }\n );\n return {\n customers: response._embedded?.customers || [],\n page: response.page,\n };\n }\n\n async getCustomer(customerId: number) {\n return this.request<Customer>('GET', `/customers/${customerId}`);\n }\n\n async createCustomer(data: {\n firstName?: string;\n lastName?: string;\n emails?: Array<{ type: string; value: string }>;\n phones?: Array<{ type: string; value: string }>;\n }) {\n await this.request<void>('POST', '/customers', { body: data });\n }\n\n async updateCustomer(\n customerId: number,\n data: Partial<{\n firstName: string;\n lastName: string;\n jobTitle: string;\n location: string;\n organization: string;\n background: string;\n }>\n ) {\n await this.request<void>('PUT', `/customers/${customerId}`, { body: data });\n }\n\n async deleteCustomer(customerId: number) {\n await this.request<void>('DELETE', `/customers/${customerId}`);\n }\n\n // Tags\n async listTags(page?: number) {\n const response = await this.request<PaginatedResponse<{ tags: Tag[] }>>('GET', '/tags', {\n params: page ? { page } : undefined,\n });\n return {\n tags: response._embedded?.tags || [],\n page: response.page,\n };\n }\n\n async getTag(tagId: number) {\n return this.request<Tag>('GET', `/tags/${tagId}`);\n }\n\n // Workflows\n async listWorkflows(\n params: {\n mailbox?: number;\n type?: string;\n page?: number;\n } = {}\n ) {\n const response = await this.request<PaginatedResponse<{ workflows: Workflow[] }>>(\n 'GET',\n '/workflows',\n { params: { mailboxId: params.mailbox, type: params.type, page: params.page } }\n );\n return {\n workflows: response._embedded?.workflows || [],\n page: response.page,\n };\n }\n\n async runWorkflow(workflowId: number, conversationIds: number[]) {\n await this.request<void>('POST', `/workflows/${workflowId}/run`, {\n body: { conversationIds },\n });\n }\n\n async updateWorkflowStatus(workflowId: number, status: 'active' | 'inactive') {\n await this.request<void>('PATCH', `/workflows/${workflowId}`, {\n body: { op: 'replace', path: '/status', value: status },\n });\n }\n\n // Mailboxes\n async listMailboxes(page?: number) {\n const response = await this.request<PaginatedResponse<{ mailboxes: Mailbox[] }>>(\n 'GET',\n '/mailboxes',\n { params: page ? { page } : undefined }\n );\n return {\n mailboxes: response._embedded?.mailboxes || [],\n page: response.page,\n };\n }\n\n async getMailbox(mailboxId: number) {\n return this.request<Mailbox>('GET', `/mailboxes/${mailboxId}`);\n }\n}\n\nexport const client = new HelpScoutClient();\n","import { handleHelpScoutError, HelpScoutCliError } from './errors.js';\n\nexport function withErrorHandling<T extends unknown[], R>(\n fn: (...args: T) => Promise<R>\n): (...args: T) => Promise<void> {\n return async (...args: T) => {\n try {\n await fn(...args);\n } catch (error) {\n handleHelpScoutError(error);\n }\n };\n}\n\nexport function parseIdArg(value: string, resourceType: string = 'resource'): number {\n const parsed = parseInt(value, 10);\n if (isNaN(parsed) || parsed <= 0) {\n throw new HelpScoutCliError(`Invalid ${resourceType} ID: \"${value}\"`, 400);\n }\n return parsed;\n}\n\nexport function requireAtLeastOneField(data: Record<string, unknown>, operation: string): void {\n const hasFields = Object.values(data).some((v) => v !== undefined);\n if (!hasFields) {\n throw new HelpScoutCliError(`${operation} requires at least one field to update`, 400);\n }\n}\n\nexport function requireConfirmation(itemType: string, confirmed: boolean = false): void {\n if (!confirmed) {\n throw new HelpScoutCliError(\n `Deleting ${itemType} requires --yes flag to confirm`,\n 400\n );\n }\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { config } from '../lib/config.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling, parseIdArg } from '../lib/command-utils.js';\n\nexport function createMailboxesCommand(): Command {\n const cmd = new Command('mailboxes').description('Mailbox operations');\n\n cmd\n .command('list')\n .description('List mailboxes')\n .option('--page <number>', 'Page number')\n .action(\n withErrorHandling(async (options: { page?: string }) => {\n const result = await client.listMailboxes(\n options.page ? parseInt(options.page, 10) : undefined\n );\n outputJson(result);\n })\n );\n\n cmd\n .command('view')\n .description('View a mailbox')\n .argument('<id>', 'Mailbox ID')\n .action(\n withErrorHandling(async (id: string) => {\n const mailbox = await client.getMailbox(parseIdArg(id, 'mailbox'));\n outputJson(mailbox);\n })\n );\n\n cmd\n .command('set-default')\n .description('Set default mailbox')\n .argument('<id>', 'Mailbox ID')\n .action(\n withErrorHandling(async (id: string) => {\n const mailboxId = parseIdArg(id, 'mailbox');\n config.setDefaultMailbox(String(mailboxId));\n outputJson({ message: `Default mailbox set to ${mailboxId}` });\n })\n );\n\n cmd\n .command('get-default')\n .description('Get default mailbox')\n .action(\n withErrorHandling(async () => {\n const mailboxId = config.getDefaultMailbox();\n outputJson({ defaultMailbox: mailboxId || null });\n })\n );\n\n cmd\n .command('clear-default')\n .description('Clear default mailbox')\n .action(\n withErrorHandling(async () => {\n config.clearDefaultMailbox();\n outputJson({ message: 'Default mailbox cleared' });\n })\n );\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson, htmlToPlainText, buildName } from '../lib/output.js';\nimport { withErrorHandling, requireConfirmation, parseIdArg } from '../lib/command-utils.js';\nimport { buildDateQuery } from '../lib/dates.js';\nimport type { Conversation, Thread } from '../types/index.js';\n\ninterface ParticipantInfo {\n name?: string;\n email?: string;\n messageCount: number;\n firstMessage?: string;\n}\n\ninterface ConversationSummary {\n total: number;\n byStatus: Record<string, number>;\n byTag: Record<string, number>;\n conversations: Array<{\n id: number;\n subject: string;\n status: string;\n tags: string[];\n customer: ParticipantInfo;\n user: ParticipantInfo;\n }>;\n}\n\nconst MAX_MESSAGE_LENGTH = 300;\n\nfunction truncate(text: string): string {\n if (text.length <= MAX_MESSAGE_LENGTH) return text;\n return text.slice(0, MAX_MESSAGE_LENGTH).trim() + '...';\n}\n\nfunction buildPersonName(info: { first?: string; last?: string } | undefined): string | undefined {\n if (!info) return undefined;\n return buildName(info.first, info.last);\n}\n\nfunction extractThreadInfo(threads: Thread[] | undefined): {\n customer: ParticipantInfo;\n user: ParticipantInfo;\n} {\n if (!threads?.length) {\n return {\n customer: { messageCount: 0 },\n user: { messageCount: 0 },\n };\n }\n\n const sortedThreads = [...threads].sort(\n (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()\n );\n\n const customerThreads = sortedThreads.filter((t) => t.type === 'customer');\n const userThreads = sortedThreads.filter((t) => t.type === 'message');\n\n const firstCustomerWithBody = customerThreads.find((t) => t.body);\n const firstUserWithBody = userThreads.find((t) => t.body);\n const mostRecentUserThread = userThreads[userThreads.length - 1];\n\n const customerSource = firstCustomerWithBody?.customer || firstCustomerWithBody?.createdBy;\n const userSource = mostRecentUserThread?.createdBy;\n\n return {\n customer: {\n name: buildPersonName(customerSource),\n email: customerSource?.email,\n messageCount: customerThreads.length,\n firstMessage: firstCustomerWithBody?.body\n ? truncate(htmlToPlainText(firstCustomerWithBody.body))\n : undefined,\n },\n user: {\n name: buildPersonName(userSource),\n email: userSource?.email,\n messageCount: userThreads.length,\n firstMessage: firstUserWithBody?.body\n ? truncate(htmlToPlainText(firstUserWithBody.body))\n : undefined,\n },\n };\n}\n\nfunction summarizeConversations(conversations: Conversation[]): ConversationSummary {\n const byStatus: Record<string, number> = {};\n const byTag: Record<string, number> = {};\n\n for (const conv of conversations) {\n byStatus[conv.status] = (byStatus[conv.status] || 0) + 1;\n\n for (const tag of conv.tags || []) {\n byTag[tag.name] = (byTag[tag.name] || 0) + 1;\n }\n }\n\n return {\n total: conversations.length,\n byStatus,\n byTag,\n conversations: conversations.map((c) => {\n const threadInfo = extractThreadInfo(c._embedded?.threads);\n return {\n id: c.id,\n subject: c.subject,\n status: c.status,\n tags: (c.tags || []).map((t) => t.name),\n ...threadInfo,\n };\n }),\n };\n}\n\nexport function createConversationsCommand(): Command {\n const cmd = new Command('conversations').description('Conversation operations');\n\n cmd\n .command('list')\n .description('List conversations')\n .option('-m, --mailbox <id>', 'Filter by mailbox ID')\n .option('-s, --status <status>', 'Filter by status (active, all, closed, open, pending, spam)')\n .option('-t, --tag <tags>', 'Filter by tag(s), comma-separated')\n .option('--assigned-to <id>', 'Filter by assignee user ID')\n .option('--created-since <date>', 'Show conversations created after this date')\n .option('--created-before <date>', 'Show conversations created before this date')\n .option('--modified-since <date>', 'Show conversations modified after this date')\n .option('--modified-before <date>', 'Show conversations modified before this date')\n .option(\n '--sort-field <field>',\n 'Sort by field (createdAt, modifiedAt, number, status, subject)'\n )\n .option('--sort-order <order>', 'Sort order (asc, desc)')\n .option('--page <number>', 'Page number')\n .option('--embed <resources>', 'Embed resources (threads)')\n .option(\n '-q, --query <query>',\n 'Advanced search query (see https://docs.helpscout.com/article/47-search-filters-with-operators)'\n )\n .option('--summary', 'Output aggregated summary instead of full conversation list')\n .action(\n withErrorHandling(\n async (options: {\n mailbox?: string;\n status?: string;\n tag?: string;\n assignedTo?: string;\n createdSince?: string;\n createdBefore?: string;\n modifiedSince?: string;\n modifiedBefore?: string;\n sortField?: string;\n sortOrder?: string;\n page?: string;\n embed?: string;\n query?: string;\n summary?: boolean;\n }) => {\n const query = buildDateQuery(\n {\n createdSince: options.createdSince,\n createdBefore: options.createdBefore,\n modifiedSince: options.modifiedSince,\n modifiedBefore: options.modifiedBefore,\n },\n options.query\n );\n\n if (options.summary) {\n const allConversations = await client.listAllConversations({\n mailbox: options.mailbox,\n status: options.status,\n tag: options.tag,\n assignedTo: options.assignedTo,\n query,\n embed: 'threads',\n });\n const summary = summarizeConversations(allConversations);\n outputJson(summary);\n return;\n }\n\n const result = await client.listConversations({\n mailbox: options.mailbox,\n status: options.status,\n tag: options.tag,\n assignedTo: options.assignedTo,\n sortField: options.sortField,\n sortOrder: options.sortOrder,\n page: options.page ? parseInt(options.page, 10) : undefined,\n embed: options.embed,\n query,\n });\n outputJson(result);\n }\n )\n );\n\n cmd\n .command('view')\n .description('View a conversation')\n .argument('<id>', 'Conversation ID')\n .action(\n withErrorHandling(async (id: string) => {\n const conversation = await client.getConversation(parseIdArg(id, 'conversation'), 'threads');\n const threadInfo = extractThreadInfo(conversation._embedded?.threads);\n const result = {\n ...conversation,\n customer: threadInfo.customer,\n user: threadInfo.user,\n };\n outputJson(result, { plain: true });\n })\n );\n\n cmd\n .command('threads')\n .description('List threads for a conversation (defaults to email communications only)')\n .argument('<id>', 'Conversation ID')\n .option('--include-notes', 'Include internal notes')\n .option('--all', 'Show all thread types including lineitems, workflows, etc.')\n .option(\n '-t, --type <types>',\n 'Filter by specific thread type(s), comma-separated (customer, message, note, lineitem, chat, phone, forwardchild, forwardparent, beaconchat)'\n )\n .option('--html', 'Output thread bodies as HTML (default is plain text)')\n .action(\n withErrorHandling(\n async (\n id: string,\n options: { includeNotes?: boolean; all?: boolean; type?: string; html?: boolean }\n ) => {\n let threads = await client.getConversationThreads(parseIdArg(id, 'conversation'));\n\n if (options.type) {\n const types = options.type.split(',').map((t) => t.trim().toLowerCase());\n threads = threads.filter((t) => types.includes(t.type));\n } else if (!options.all) {\n const allowedTypes = options.includeNotes\n ? ['customer', 'message', 'note', 'chat', 'phone']\n : ['customer', 'message', 'chat', 'phone'];\n threads = threads.filter((t) => allowedTypes.includes(t.type));\n }\n\n outputJson(threads, { plain: !options.html });\n }\n )\n );\n\n cmd\n .command('delete')\n .description('Delete a conversation')\n .argument('<id>', 'Conversation ID')\n .option('-y, --yes', 'Skip confirmation')\n .action(\n withErrorHandling(async (id: string, options: { yes?: boolean }) => {\n requireConfirmation('conversation', options.yes);\n await client.deleteConversation(parseIdArg(id, 'conversation'));\n outputJson({ message: 'Conversation deleted' });\n })\n );\n\n cmd\n .command('add-tag')\n .description('Add a tag to a conversation')\n .argument('<id>', 'Conversation ID')\n .argument('<tag>', 'Tag name')\n .action(\n withErrorHandling(async (id: string, tag: string) => {\n await client.addConversationTag(parseIdArg(id, 'conversation'), tag);\n outputJson({ message: `Tag \"${tag}\" added` });\n })\n );\n\n cmd\n .command('remove-tag')\n .description('Remove a tag from a conversation')\n .argument('<id>', 'Conversation ID')\n .argument('<tag>', 'Tag name')\n .action(\n withErrorHandling(async (id: string, tag: string) => {\n await client.removeConversationTag(parseIdArg(id, 'conversation'), tag);\n outputJson({ message: `Tag \"${tag}\" removed` });\n })\n );\n\n cmd\n .command('reply')\n .description('Reply to a conversation')\n .argument('<id>', 'Conversation ID')\n .requiredOption('--text <text>', 'Reply text')\n .option('--user <id>', 'User ID sending the reply')\n .option('--draft', 'Save as draft')\n .option('--status <status>', 'Set conversation status after reply (active, closed, pending)')\n .action(\n withErrorHandling(\n async (\n id: string,\n options: {\n text: string;\n user?: string;\n draft?: boolean;\n status?: string;\n }\n ) => {\n await client.createReply(parseIdArg(id, 'conversation'), {\n text: options.text,\n user: options.user ? parseIdArg(options.user, 'user') : undefined,\n draft: options.draft,\n status: options.status,\n });\n outputJson({ message: 'Reply sent' });\n }\n )\n );\n\n cmd\n .command('note')\n .description('Add a note to a conversation')\n .argument('<id>', 'Conversation ID')\n .requiredOption('--text <text>', 'Note text')\n .option('--user <id>', 'User ID adding the note')\n .action(\n withErrorHandling(\n async (\n id: string,\n options: {\n text: string;\n user?: string;\n }\n ) => {\n await client.createNote(parseIdArg(id, 'conversation'), {\n text: options.text,\n user: options.user ? parseIdArg(options.user, 'user') : undefined,\n });\n outputJson({ message: 'Note added' });\n }\n )\n );\n\n return cmd;\n}\n","import dayjs from 'dayjs';\nimport { HelpScoutCliError } from './errors.js';\n\nexport function parseDateTime(input: string): string {\n const d = dayjs(input);\n if (!d.isValid()) {\n throw new HelpScoutCliError(`Invalid date: ${input}`, 400);\n }\n return d.toISOString().replace(/\\.\\d{3}Z$/, 'Z');\n}\n\ninterface DateFilters {\n createdSince?: string;\n createdBefore?: string;\n modifiedSince?: string;\n modifiedBefore?: string;\n}\n\nfunction rangeClause(field: string, since?: string, before?: string): string[] {\n const clauses: string[] = [];\n if (since) clauses.push(`${field}:[${parseDateTime(since)} TO *]`);\n if (before) clauses.push(`${field}:[* TO ${parseDateTime(before)}]`);\n return clauses;\n}\n\nexport function buildDateQuery(filters: DateFilters, existingQuery?: string): string | undefined {\n const parts = [\n ...rangeClause('createdAt', filters.createdSince, filters.createdBefore),\n ...rangeClause('modifiedAt', filters.modifiedSince, filters.modifiedBefore),\n ];\n\n if (parts.length === 0) return existingQuery;\n\n const dateQuery = parts.join(' AND ');\n return existingQuery ? `(${existingQuery}) AND ${dateQuery}` : dateQuery;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport {\n withErrorHandling,\n requireConfirmation,\n parseIdArg,\n requireAtLeastOneField,\n} from '../lib/command-utils.js';\nimport { buildDateQuery } from '../lib/dates.js';\n\nexport function createCustomersCommand(): Command {\n const cmd = new Command('customers').description('Customer operations');\n\n cmd\n .command('list')\n .description('List customers')\n .option('-m, --mailbox <id>', 'Filter by mailbox ID')\n .option('--first-name <name>', 'Filter by first name')\n .option('--last-name <name>', 'Filter by last name')\n .option('--created-since <date>', 'Show customers created after this date')\n .option('--created-before <date>', 'Show customers created before this date')\n .option('--modified-since <date>', 'Show customers modified after this date')\n .option('--modified-before <date>', 'Show customers modified before this date')\n .option('--sort-field <field>', 'Sort by field (createdAt, firstName, lastName, modifiedAt)')\n .option('--sort-order <order>', 'Sort order (asc, desc)')\n .option('--page <number>', 'Page number')\n .option('-q, --query <query>', 'Advanced search query')\n .action(\n withErrorHandling(\n async (options: {\n mailbox?: string;\n firstName?: string;\n lastName?: string;\n createdSince?: string;\n createdBefore?: string;\n modifiedSince?: string;\n modifiedBefore?: string;\n sortField?: string;\n sortOrder?: string;\n page?: string;\n query?: string;\n }) => {\n const query = buildDateQuery(\n {\n createdSince: options.createdSince,\n createdBefore: options.createdBefore,\n modifiedSince: options.modifiedSince,\n modifiedBefore: options.modifiedBefore,\n },\n options.query\n );\n\n const result = await client.listCustomers({\n mailbox: options.mailbox,\n firstName: options.firstName,\n lastName: options.lastName,\n sortField: options.sortField,\n sortOrder: options.sortOrder,\n page: options.page ? parseInt(options.page, 10) : undefined,\n query,\n });\n outputJson(result);\n }\n )\n );\n\n cmd\n .command('view')\n .description('View a customer')\n .argument('<id>', 'Customer ID')\n .action(\n withErrorHandling(async (id: string) => {\n const customer = await client.getCustomer(parseIdArg(id, 'customer'));\n outputJson(customer);\n })\n );\n\n cmd\n .command('create')\n .description('Create a customer')\n .option('--first-name <name>', 'First name')\n .option('--last-name <name>', 'Last name')\n .option('--email <email>', 'Email address')\n .option('--phone <phone>', 'Phone number')\n .action(\n withErrorHandling(\n async (options: {\n firstName?: string;\n lastName?: string;\n email?: string;\n phone?: string;\n }) => {\n const data = {\n ...(options.firstName && { firstName: options.firstName }),\n ...(options.lastName && { lastName: options.lastName }),\n ...(options.email && { emails: [{ type: 'work', value: options.email }] }),\n ...(options.phone && { phones: [{ type: 'work', value: options.phone }] }),\n };\n requireAtLeastOneField(data, 'Customer create');\n await client.createCustomer(data);\n outputJson({ message: 'Customer created' });\n }\n )\n );\n\n cmd\n .command('update')\n .description('Update a customer')\n .argument('<id>', 'Customer ID')\n .option('--first-name <name>', 'First name')\n .option('--last-name <name>', 'Last name')\n .option('--job-title <title>', 'Job title')\n .option('--location <location>', 'Location')\n .option('--organization <org>', 'Organization')\n .option('--background <text>', 'Background notes')\n .action(\n withErrorHandling(\n async (\n id: string,\n options: {\n firstName?: string;\n lastName?: string;\n jobTitle?: string;\n location?: string;\n organization?: string;\n background?: string;\n }\n ) => {\n const data = {\n ...(options.firstName && { firstName: options.firstName }),\n ...(options.lastName && { lastName: options.lastName }),\n ...(options.jobTitle && { jobTitle: options.jobTitle }),\n ...(options.location && { location: options.location }),\n ...(options.organization && { organization: options.organization }),\n ...(options.background && { background: options.background }),\n };\n requireAtLeastOneField(data, 'Customer update');\n await client.updateCustomer(parseIdArg(id, 'customer'), data);\n outputJson({ message: 'Customer updated' });\n }\n )\n );\n\n cmd\n .command('delete')\n .description('Delete a customer')\n .argument('<id>', 'Customer ID')\n .option('-y, --yes', 'Skip confirmation')\n .action(\n withErrorHandling(async (id: string, options: { yes?: boolean }) => {\n requireConfirmation('customer', options.yes);\n await client.deleteCustomer(parseIdArg(id, 'customer'));\n outputJson({ message: 'Customer deleted' });\n })\n );\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling, parseIdArg } from '../lib/command-utils.js';\n\nexport function createTagsCommand(): Command {\n const cmd = new Command('tags').description('Tag operations');\n\n cmd\n .command('list')\n .description('List all tags')\n .option('--page <number>', 'Page number')\n .action(\n withErrorHandling(async (options: { page?: string }) => {\n const result = await client.listTags(options.page ? parseInt(options.page, 10) : undefined);\n outputJson(result);\n })\n );\n\n cmd\n .command('view')\n .description('View a tag')\n .argument('<id>', 'Tag ID')\n .action(\n withErrorHandling(async (id: string) => {\n const tag = await client.getTag(parseIdArg(id, 'tag'));\n outputJson(tag);\n })\n );\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling, parseIdArg } from '../lib/command-utils.js';\n\nexport function createWorkflowsCommand(): Command {\n const cmd = new Command('workflows').description('Workflow operations');\n\n cmd\n .command('list')\n .description('List workflows')\n .option('-m, --mailbox <id>', 'Filter by mailbox ID')\n .option('-t, --type <type>', 'Filter by type (manual, automatic)')\n .option('--page <number>', 'Page number')\n .action(\n withErrorHandling(\n async (options: {\n mailbox?: string;\n type?: string;\n page?: string;\n }) => {\n const result = await client.listWorkflows({\n mailbox: options.mailbox ? parseIdArg(options.mailbox, 'mailbox') : undefined,\n type: options.type,\n page: options.page ? parseInt(options.page, 10) : undefined,\n });\n outputJson(result);\n }\n )\n );\n\n cmd\n .command('run')\n .description('Run a manual workflow on conversations')\n .argument('<workflow-id>', 'Workflow ID')\n .requiredOption('--conversations <ids>', 'Comma-separated conversation IDs')\n .action(\n withErrorHandling(async (workflowId: string, options: { conversations: string }) => {\n const conversationIds = options.conversations\n .split(',')\n .map((id) => parseIdArg(id.trim(), 'conversation'));\n await client.runWorkflow(parseIdArg(workflowId, 'workflow'), conversationIds);\n outputJson({ message: 'Workflow executed' });\n })\n );\n\n cmd\n .command('activate')\n .description('Activate a workflow')\n .argument('<id>', 'Workflow ID')\n .action(\n withErrorHandling(async (id: string) => {\n await client.updateWorkflowStatus(parseIdArg(id, 'workflow'), 'active');\n outputJson({ message: 'Workflow activated' });\n })\n );\n\n cmd\n .command('deactivate')\n .description('Deactivate a workflow')\n .argument('<id>', 'Workflow ID')\n .action(\n withErrorHandling(async (id: string) => {\n await client.updateWorkflowStatus(parseIdArg(id, 'workflow'), 'inactive');\n outputJson({ message: 'Workflow deactivated' });\n })\n );\n\n return cmd;\n}\n"],"mappings":";;;AAEA,SAAS,WAAAA,gBAAe;;;ACFxB,SAAS,eAAe;AAGxB,IAAI,sBAAqC,CAAC;AAEnC,SAAS,iBAAiB,SAA8B;AAC7D,wBAAsB;AACxB;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEO,SAAS,gBAAgB,MAAsB;AACpD,QAAM,OAAO,QAAQ,MAAM;AAAA,IACzB,UAAU;AAAA,IACV,kBAAkB;AAAA,IAClB,WAAW;AAAA,MACT,EAAE,UAAU,KAAK,SAAS,EAAE,YAAY,KAAK,EAAE;AAAA,MAC/C,EAAE,UAAU,OAAO,QAAQ,OAAO;AAAA,IACpC;AAAA,EACF,CAAC;AAED,SAAO,KACJ,QAAQ,WAAW,MAAM,EACzB,QAAQ,WAAW,GAAG,EACtB,KAAK;AACV;AAEA,SAAS,yBAAyB,MAAwB;AACxD,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,IAAI,wBAAwB;AAAA,EAC1C;AAEA,MAAI,SAAS,IAAI,GAAG;AAClB,UAAM,SAAkC,CAAC;AACzC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAI,QAAQ,UAAU,OAAO,UAAU,UAAU;AAC/C,eAAO,GAAG,IAAI,gBAAgB,KAAK;AAAA,MACrC,OAAO;AACL,eAAO,GAAG,IAAI,yBAAyB,KAAK;AAAA,MAC9C;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,cAAc,MAAwB;AAC7C,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,IAAI,aAAa;AAAA,EAC/B;AAEA,MAAI,SAAS,IAAI,GAAG;AAClB,UAAM,SAAkC,CAAC;AACzC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAI,QAAQ,YAAY,QAAQ,aAAa;AAC3C;AAAA,MACF;AACA,aAAO,GAAG,IAAI,cAAc,KAAK;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,MAAwB;AAC9C,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,IAAI,cAAc;AAAA,EAChC;AAEA,MAAI,SAAS,IAAI,GAAG;AAClB,UAAM,SAAkC,CAAC;AACzC,UAAM,QAAQ,QAAQ,QAAQ,UAAU,QAAQ,UAAU;AAE1D,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAI,UAAU,QAAQ,WAAW,QAAQ,WAAW;AAClD;AAAA,MACF;AACA,aAAO,GAAG,IAAI,eAAe,KAAK;AAAA,IACpC;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEO,SAAS,UAAU,OAAgB,MAAmC;AAC3E,QAAM,OAAO,CAAC,OAAO,IAAI,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AACnD,SAAO,QAAQ;AACjB;AAEA,SAAS,eAAe,MAAwC;AAC9D,UAAQ,WAAW,QAAQ,UAAU,UAAU,WAAW,QAAQ,QAAQ;AAC5E;AAEA,SAAS,oBAAoB,MAAwC;AACnE,SAAO,KAAK,OAAO,KAAK,KAAK,UAAU;AACzC;AAEA,SAAS,uBAAuB,MAAwB;AACtD,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,IAAI,sBAAsB;AAAA,EACxC;AAEA,MAAI,SAAS,IAAI,GAAG;AAClB,UAAM,SAAkC,CAAC;AAEzC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,aAAO,GAAG,IAAI,uBAAuB,KAAK;AAAA,IAC5C;AAEA,QAAI,eAAe,MAAM,KAAK,CAAC,oBAAoB,MAAM,GAAG;AAC1D,YAAM,OAAO,UAAU,OAAO,OAA6B,OAAO,IAA0B;AAC5F,UAAI,MAAM;AACR,eAAO,OAAO;AAAA,MAChB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,uBAAuB,MAAwB;AACtD,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,IAAI,sBAAsB;AAAA,EACxC;AAEA,MAAI,SAAS,IAAI,GAAG;AAClB,UAAM,SAAkC,CAAC;AAEzC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAI,QAAQ,cAAc,UAAU,EAAG;AACvC,UAAI,QAAQ,kBAAkB,UAAU,EAAG;AAE3C,UAAI,SAAS,KAAK,KAAK,oBAAoB,KAAK,EAAG;AAEnD,aAAO,GAAG,IAAI,uBAAuB,KAAK;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,iBAAiB,MAAwB;AAChD,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,IAAI,gBAAgB;AAAA,EAClC;AAEA,MAAI,SAAS,IAAI,GAAG;AAClB,UAAM,SAAkC,CAAC;AAEzC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,EAAG;AAChD,aAAO,GAAG,IAAI,iBAAiB,KAAK;AAAA,IACtC;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,MAAwB;AAC9C,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,IAAI,cAAc;AAAA,EAChC;AAEA,MAAI,SAAS,IAAI,GAAG;AAClB,UAAM,SAAkC,CAAC;AAEzC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAI,QAAQ,WAAY;AACxB,aAAO,GAAG,IAAI,eAAe,KAAK;AAAA,IACpC;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,MAAe,QAA2B;AAC9D,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,IAAI,CAAC,SAAS,aAAa,MAAM,MAAM,CAAC;AAAA,EACtD;AAEA,MAAI,SAAS,IAAI,GAAG;AAClB,UAAM,qBAAqB,OAAO,KAAK,CAAC,MAAM,KAAK,IAAI;AACvD,QAAI,oBAAoB;AACtB,YAAMC,UAAkC,CAAC;AACzC,iBAAW,SAAS,QAAQ;AAC1B,YAAI,SAAS,MAAM;AACjB,UAAAA,QAAO,KAAK,IAAI,KAAK,KAAK;AAAA,QAC5B;AAAA,MACF;AACA,aAAOA;AAAA,IACT;AAEA,UAAM,SAAkC,CAAC;AACzC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,aAAO,GAAG,IAAI,aAAa,OAAO,MAAM;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEO,SAAS,WAAW,MAAe,UAAyB,CAAC,GAAS;AAC3E,QAAM,gBAAgB,EAAE,GAAG,qBAAqB,GAAG,QAAQ;AAE3D,MAAI,YAAY;AAEhB,MAAI,cAAc,MAAM;AACtB,gBAAY,cAAc,SAAS;AAAA,EACrC;AAEA,MAAI,cAAc,OAAO;AACvB,gBAAY,yBAAyB,SAAS;AAAA,EAChD;AAEA,cAAY,eAAe,SAAS;AACpC,cAAY,uBAAuB,SAAS;AAC5C,cAAY,uBAAuB,SAAS;AAC5C,cAAY,iBAAiB,SAAS;AACtC,cAAY,eAAe,SAAS;AAEpC,MAAI,cAAc,QAAQ;AACxB,UAAM,YAAY,cAAc,OAAO,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACrE,gBAAY,aAAa,WAAW,SAAS;AAAA,EAC/C;AAEA,QAAM,aAAa,cAAc,UAC7B,KAAK,UAAU,SAAS,IACxB,KAAK,UAAU,WAAW,MAAM,CAAC;AAErC,UAAQ,IAAI,UAAU;AACxB;;;ACpPA,SAAS,eAAe;;;ACAxB,SAAS,aAAa;;;ACAtB,OAAO,UAAU;AAMjB,IAAM,QAAQ,IAAI,KAAmB;AAAA,EACnC,aAAa;AACf,CAAC;AAEM,IAAM,SAAS;AAAA,EACpB,oBAAwC;AACtC,WAAO,MAAM,IAAI,gBAAgB,KAAK,QAAQ,IAAI;AAAA,EACpD;AAAA,EAEA,kBAAkB,WAAyB;AACzC,UAAM,IAAI,kBAAkB,SAAS;AAAA,EACvC;AAAA,EAEA,sBAA4B;AAC1B,UAAM,OAAO,gBAAgB;AAAA,EAC/B;AAAA,EAEA,QAAc;AACZ,UAAM,MAAM;AAAA,EACd;AACF;;;ADvBA,IAAM,eAAe;AACrB,IAAM,uBAAuB;AAC7B,IAAM,wBAAwB;AAC9B,IAAM,iBAAiB;AACvB,IAAM,qBAAqB;AAE3B,IAAM,4BACJ;AAKF,IAAM,eAAe,oBAAI,IAA0B;AAEnD,SAAS,WAAW,SAA+B;AACjD,MAAI,aAAa,IAAI,OAAO,GAAG;AAC7B,WAAO,aAAa,IAAI,OAAO;AAAA,EACjC;AACA,MAAI;AACF,UAAM,QAAQ,IAAI,MAAM,cAAc,OAAO;AAC7C,iBAAa,IAAI,SAAS,KAAK;AAC/B,WAAO;AAAA,EACT,QAAQ;AACN,iBAAa,IAAI,SAAS,IAAI;AAC9B,WAAO;AAAA,EACT;AACF;AAEA,eAAe,YAAY,SAAyC;AAClE,QAAM,QAAQ,WAAW,OAAO;AAChC,MAAI,OAAO;AACT,QAAI;AACF,aAAO,MAAM,YAAY;AAAA,IAC3B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAe,YAAY,SAAiB,OAA8B;AACxE,QAAM,QAAQ,WAAW,OAAO;AAChC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AACA,QAAM,YAAY,KAAK;AACzB;AAEA,eAAe,eAAe,SAAmC;AAC/D,QAAM,QAAQ,WAAW,OAAO;AAChC,MAAI,OAAO;AACT,WAAO,MAAM,eAAe;AAAA,EAC9B;AACA,SAAO;AACT;AAEO,IAAM,cAAN,MAAkB;AAAA,EACvB,MAAM,iBAAyC;AAC7C,WAAO,YAAY,oBAAoB;AAAA,EACzC;AAAA,EAEA,MAAM,eAAe,OAA8B;AACjD,WAAO,YAAY,sBAAsB,KAAK;AAAA,EAChD;AAAA,EAEA,MAAM,kBAA0C;AAC9C,WAAO,YAAY,qBAAqB;AAAA,EAC1C;AAAA,EAEA,MAAM,gBAAgB,OAA8B;AAClD,WAAO,YAAY,uBAAuB,KAAK;AAAA,EACjD;AAAA,EAEA,MAAM,WAAmC;AACvC,UAAM,gBAAgB,MAAM,YAAY,cAAc;AACtD,WAAO,iBAAiB,QAAQ,IAAI,oBAAoB;AAAA,EAC1D;AAAA,EAEA,MAAM,SAAS,OAA8B;AAC3C,WAAO,YAAY,gBAAgB,KAAK;AAAA,EAC1C;AAAA,EAEA,MAAM,eAAuC;AAC3C,UAAM,gBAAgB,MAAM,YAAY,kBAAkB;AAC1D,WAAO,iBAAiB,QAAQ,IAAI,wBAAwB;AAAA,EAC9D;AAAA,EAEA,MAAM,aAAa,WAAkC;AACnD,WAAO,YAAY,oBAAoB,SAAS;AAAA,EAClD;AAAA,EAEA,MAAM,kBAAoC;AACxC,WAAQ,MAAM,KAAK,eAAe,MAAO;AAAA,EAC3C;AAAA,EAEA,MAAM,SAAwB;AAC5B,UAAM,eAAe,oBAAoB;AACzC,UAAM,eAAe,qBAAqB;AAC1C,WAAO,oBAAoB;AAAA,EAC7B;AAAA,EAEA,MAAM,WAA0B;AAC9B,UAAM,eAAe,oBAAoB;AACzC,UAAM,eAAe,qBAAqB;AAC1C,UAAM,eAAe,cAAc;AACnC,UAAM,eAAe,kBAAkB;AACvC,WAAO,MAAM;AAAA,EACf;AACF;AAEO,IAAM,OAAO,IAAI,YAAY;;;AE9G7B,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,YACE,SACO,YACP;AACA,UAAM,OAAO;AAFN;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,YACE,SACO,UACA,YACP;AACA,UAAM,OAAO;AAHN;AACA;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAEA,IAAM,qBAA6C;AAAA,EACjD,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,qBAAqB;AACvB;AAEO,SAAS,qBAAqB,SAAyB;AAC5D,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,YAAY;AAChB,aAAW,WAAW,mBAAmB;AACvC,gBAAY,UAAU,QAAQ,SAAS,YAAY;AAAA,EACrD;AAEA,SAAO,UAAU,SAAS,MAAM,UAAU,UAAU,GAAG,GAAG,IAAI,QAAQ;AACxE;AAeA,SAAS,cAAc,OAAkD;AACvE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEO,SAAS,iBAAiB,OAAgC;AAC/D,MAAI,CAAC,cAAc,KAAK,GAAG;AACzB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,WAAW;AAEjB,MAAI,SAAS;AACb,MAAI,SAAS,mBAAmB;AAC9B,aAAS,SAAS;AAAA,EACpB,WAAW,SAAS,SAAS;AAC3B,aAAS,SAAS;AAAA,EACpB,WAAW,SAAS,WAAW,QAAQ,QAAQ;AAC7C,aAAS,SAAS,UAAU,OACzB,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAC9B,OAAO,OAAO,EACd,KAAK,IAAI;AAAA,EACd;AAEA,SAAO;AAAA,IACL,MAAM,SAAS,SAAS;AAAA,IACxB,QAAQ,qBAAqB,MAAM;AAAA,EACrC;AACF;AAEA,SAAS,oBAAoB,MAAc,QAAgB,YAA2B;AACpF,QAAM,OACJ,SAAS,sBACL,wEACA;AAEN,QAAM,WAA2F;AAAA,IAC/F,OAAO,EAAE,MAAM,QAAQ,WAAW;AAAA,EACpC;AAEA,MAAI,MAAM;AACR,aAAS,OAAO;AAAA,EAClB;AAEA,aAAW,QAAQ;AACnB,UAAQ,KAAK,CAAC;AAChB;AAEO,SAAS,qBAAqB,OAAuB;AAC1D,MAAI,iBAAiB,mBAAmB;AACtC,UAAM,YAAY,qBAAqB,MAAM,OAAO;AACpD,wBAAoB,aAAa,WAAW,MAAM,cAAc,CAAC;AAAA,EACnE;AAEA,MAAI,iBAAiB,mBAAmB;AACtC,UAAM,UAA0B,iBAAiB,MAAM,QAAQ;AAC/D;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,MAAM,cAAc,mBAAmB,QAAQ,IAAI,KAAK;AAAA,IAC1D;AAAA,EACF;AAEA,MAAI,iBAAiB,OAAO;AAC1B,UAAM,YAAY,qBAAqB,MAAM,OAAO;AACpD,wBAAoB,iBAAiB,WAAW,CAAC;AAAA,EACnD;AAEA,sBAAoB,iBAAiB,gCAAgC,CAAC;AACxE;;;AC3HA,IAAM,WAAW;AACjB,IAAM,YAAY;AAcX,IAAM,kBAAN,MAAsB;AAAA,EACnB,cAA6B;AAAA,EAErC,aAAmB;AACjB,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,MAAM,qBAAsC;AAC1C,UAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,UAAM,YAAY,MAAM,KAAK,aAAa;AAC1C,UAAM,eAAe,MAAM,KAAK,gBAAgB;AAEhD,QAAI,CAAC,SAAS,CAAC,WAAW;AACxB,YAAM,IAAI,kBAAkB,oDAAoD,GAAG;AAAA,IACrF;AAEA,QAAI,cAAc;AAChB,UAAI;AACF,cAAMC,YAAW,MAAM,MAAM,WAAW;AAAA,UACtC,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,oCAAoC;AAAA,UAC/D,MAAM,IAAI,gBAAgB;AAAA,YACxB,YAAY;AAAA,YACZ,WAAW;AAAA,YACX,eAAe;AAAA,YACf,eAAe;AAAA,UACjB,CAAC;AAAA,QACH,CAAC;AAED,YAAIA,UAAS,IAAI;AACf,gBAAMC,QAAQ,MAAMD,UAAS,KAAK;AAClC,gBAAM,KAAK,eAAeC,MAAK,YAAY;AAC3C,cAAIA,MAAK,eAAe;AACtB,kBAAM,KAAK,gBAAgBA,MAAK,aAAa;AAAA,UAC/C;AACA,eAAK,cAAcA,MAAK;AACxB,iBAAOA,MAAK;AAAA,QACd;AAAA,MACF,SAAS,OAAO;AACd,cAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,gBAAQ;AAAA,UACN,KAAK,UAAU;AAAA,YACb,SAAS;AAAA,YACT,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,MAAM,WAAW;AAAA,QAChC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,oCAAoC;AAAA,QAC/D,MAAM,IAAI,gBAAgB;AAAA,UACxB,YAAY;AAAA,UACZ,WAAW;AAAA,UACX,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,YAAM,IAAI,kBAAkB,iDAAiD,OAAO,IAAI,CAAC;AAAA,IAC3F;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,YAAM,IAAI,kBAAkB,8BAA8B,OAAO,SAAS,MAAM;AAAA,IAClF;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAM,KAAK,eAAe,KAAK,YAAY;AAC3C,SAAK,cAAc,KAAK;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,iBAAkC;AACtC,QAAI,KAAK,aAAa;AACpB,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,cAAc,MAAM,KAAK,eAAe;AAC9C,QAAI,aAAa;AACf,WAAK,cAAc;AACnB,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,mBAAmB;AAAA,EACjC;AAAA,EAEA,MAAc,QACZ,QACA,MACA,UAKI,CAAC,GACO;AACZ,UAAM,EAAE,QAAQ,MAAM,QAAQ,MAAM,iBAAiB,KAAK,IAAI;AAE9D,UAAM,MAAM,IAAI,IAAI,GAAG,QAAQ,GAAG,IAAI,EAAE;AACxC,QAAI,QAAQ;AACV,aAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC/C,YAAI,UAAU,QAAW;AACvB,cAAI,aAAa,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,QACzC;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,QAAQ,MAAM,KAAK,eAAe;AACxC,UAAM,eAA4B;AAAA,MAChC;AAAA,MACA,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,gBAAgB;AAAA,MAClB;AAAA,IACF;AACA,QAAI,MAAM;AACR,mBAAa,OAAO,KAAK,UAAU,IAAI;AAAA,IACzC;AAEA,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,MAAM,IAAI,SAAS,GAAG,YAAY;AAAA,IACrD,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,YAAM,IAAI,kBAAkB,2BAA2B,OAAO,IAAI,CAAC;AAAA,IACrE;AAEA,QAAI,SAAS,WAAW,OAAO,OAAO;AACpC,WAAK,cAAc;AACnB,YAAM,KAAK,mBAAmB;AAC9B,aAAO,KAAK,QAAQ,QAAQ,MAAM,EAAE,GAAG,SAAS,OAAO,MAAM,CAAC;AAAA,IAChE;AAEA,QAAI,SAAS,WAAW,OAAO,gBAAgB;AAC7C,YAAM,aAAa,SAAS,SAAS,QAAQ,IAAI,aAAa,KAAK,MAAM,EAAE;AAC3E,YAAM,cAAc,KAAK,IAAI,YAAY,GAAG;AAC5C,cAAQ;AAAA,QACN,KAAK,UAAU,EAAE,SAAS,yBAAyB,WAAW,oBAAoB,CAAC;AAAA,MACrF;AACA,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,cAAc,GAAI,CAAC;AACtE,aAAO,KAAK,QAAQ,QAAQ,MAAM,EAAE,GAAG,SAAS,gBAAgB,MAAM,CAAC;AAAA,IACzE;AAEA,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO,CAAC;AAAA,IACV;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,QAAQ,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACpD,YAAM,IAAI,kBAAkB,sBAAsB,OAAO,SAAS,MAAM;AAAA,IAC1E;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA;AAAA,EAGA,MAAM,kBACJ,SAUI,CAAC,GACL;AACA,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,EAAE,OAAO;AAAA,IACX;AACA,WAAO;AAAA,MACL,eAAe,SAAS,WAAW,iBAAiB,CAAC;AAAA,MACrD,MAAM,SAAS;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,qBACJ,SAOI,CAAC,GACoB;AACzB,UAAM,mBAAmC,CAAC;AAC1C,QAAI,OAAO;AACX,QAAI,aAAa;AAEjB,OAAG;AACD,YAAM,SAAS,MAAM,KAAK,kBAAkB,EAAE,GAAG,QAAQ,KAAK,CAAC;AAC/D,uBAAiB,KAAK,GAAG,OAAO,aAAa;AAC7C,mBAAa,OAAO,KAAK;AACzB;AAAA,IACF,SAAS,QAAQ;AAEjB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBAAgB,gBAAwB,OAAgB;AAC5D,UAAM,SAAS,QAAQ,EAAE,MAAM,IAAI;AACnC,WAAO,KAAK,QAAsB,OAAO,kBAAkB,cAAc,IAAI,EAAE,OAAO,CAAC;AAAA,EACzF;AAAA,EAEA,MAAM,uBAAuB,gBAAwB;AACnD,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA,kBAAkB,cAAc;AAAA,IAClC;AACA,WAAO,SAAS,WAAW,WAAW,CAAC;AAAA,EACzC;AAAA,EAEA,MAAM,mBACJ,gBACA,MAKA;AACA,UAAM,KAAK,QAAc,SAAS,kBAAkB,cAAc,IAAI,EAAE,MAAM,KAAK,CAAC;AAAA,EACtF;AAAA,EAEA,MAAM,mBAAmB,gBAAwB;AAC/C,UAAM,KAAK,QAAc,UAAU,kBAAkB,cAAc,EAAE;AAAA,EACvE;AAAA,EAEA,MAAM,mBAAmB,gBAAwB,KAAa;AAC5D,UAAM,KAAK,QAAc,OAAO,kBAAkB,cAAc,SAAS;AAAA,MACvE,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE;AAAA,IACtB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,sBAAsB,gBAAwB,KAAa;AAC/D,UAAM,eAAe,MAAM,KAAK,gBAAgB,cAAc;AAC9D,UAAM,eAAe,cAAc,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC;AAChE,UAAM,UAAU,aAAa,OAAO,CAAC,MAAM,MAAM,GAAG;AACpD,UAAM,KAAK,QAAc,OAAO,kBAAkB,cAAc,SAAS;AAAA,MACvE,MAAM,EAAE,MAAM,QAAQ;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,YACJ,gBACA,MAMA;AACA,UAAM,KAAK,QAAc,QAAQ,kBAAkB,cAAc,UAAU,EAAE,MAAM,KAAK,CAAC;AAAA,EAC3F;AAAA,EAEA,MAAM,WACJ,gBACA,MAIA;AACA,UAAM,KAAK,QAAc,QAAQ,kBAAkB,cAAc,UAAU,EAAE,MAAM,KAAK,CAAC;AAAA,EAC3F;AAAA;AAAA,EAGA,MAAM,cACJ,SAQI,CAAC,GACL;AACA,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,EAAE,OAAO;AAAA,IACX;AACA,WAAO;AAAA,MACL,WAAW,SAAS,WAAW,aAAa,CAAC;AAAA,MAC7C,MAAM,SAAS;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,YAAoB;AACpC,WAAO,KAAK,QAAkB,OAAO,cAAc,UAAU,EAAE;AAAA,EACjE;AAAA,EAEA,MAAM,eAAe,MAKlB;AACD,UAAM,KAAK,QAAc,QAAQ,cAAc,EAAE,MAAM,KAAK,CAAC;AAAA,EAC/D;AAAA,EAEA,MAAM,eACJ,YACA,MAQA;AACA,UAAM,KAAK,QAAc,OAAO,cAAc,UAAU,IAAI,EAAE,MAAM,KAAK,CAAC;AAAA,EAC5E;AAAA,EAEA,MAAM,eAAe,YAAoB;AACvC,UAAM,KAAK,QAAc,UAAU,cAAc,UAAU,EAAE;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAM,SAAS,MAAe;AAC5B,UAAM,WAAW,MAAM,KAAK,QAA4C,OAAO,SAAS;AAAA,MACtF,QAAQ,OAAO,EAAE,KAAK,IAAI;AAAA,IAC5B,CAAC;AACD,WAAO;AAAA,MACL,MAAM,SAAS,WAAW,QAAQ,CAAC;AAAA,MACnC,MAAM,SAAS;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,OAAe;AAC1B,WAAO,KAAK,QAAa,OAAO,SAAS,KAAK,EAAE;AAAA,EAClD;AAAA;AAAA,EAGA,MAAM,cACJ,SAII,CAAC,GACL;AACA,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,EAAE,QAAQ,EAAE,WAAW,OAAO,SAAS,MAAM,OAAO,MAAM,MAAM,OAAO,KAAK,EAAE;AAAA,IAChF;AACA,WAAO;AAAA,MACL,WAAW,SAAS,WAAW,aAAa,CAAC;AAAA,MAC7C,MAAM,SAAS;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,YAAoB,iBAA2B;AAC/D,UAAM,KAAK,QAAc,QAAQ,cAAc,UAAU,QAAQ;AAAA,MAC/D,MAAM,EAAE,gBAAgB;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,qBAAqB,YAAoB,QAA+B;AAC5E,UAAM,KAAK,QAAc,SAAS,cAAc,UAAU,IAAI;AAAA,MAC5D,MAAM,EAAE,IAAI,WAAW,MAAM,WAAW,OAAO,OAAO;AAAA,IACxD,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,cAAc,MAAe;AACjC,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,EAAE,QAAQ,OAAO,EAAE,KAAK,IAAI,OAAU;AAAA,IACxC;AACA,WAAO;AAAA,MACL,WAAW,SAAS,WAAW,aAAa,CAAC;AAAA,MAC7C,MAAM,SAAS;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,WAAmB;AAClC,WAAO,KAAK,QAAiB,OAAO,cAAc,SAAS,EAAE;AAAA,EAC/D;AACF;AAEO,IAAM,SAAS,IAAI,gBAAgB;;;AChanC,SAAS,kBACd,IAC+B;AAC/B,SAAO,UAAU,SAAY;AAC3B,QAAI;AACF,YAAM,GAAG,GAAG,IAAI;AAAA,IAClB,SAAS,OAAO;AACd,2BAAqB,KAAK;AAAA,IAC5B;AAAA,EACF;AACF;AAEO,SAAS,WAAW,OAAe,eAAuB,YAAoB;AACnF,QAAM,SAAS,SAAS,OAAO,EAAE;AACjC,MAAI,MAAM,MAAM,KAAK,UAAU,GAAG;AAChC,UAAM,IAAI,kBAAkB,WAAW,YAAY,SAAS,KAAK,KAAK,GAAG;AAAA,EAC3E;AACA,SAAO;AACT;AAEO,SAAS,uBAAuB,MAA+B,WAAyB;AAC7F,QAAM,YAAY,OAAO,OAAO,IAAI,EAAE,KAAK,CAAC,MAAM,MAAM,MAAS;AACjE,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,kBAAkB,GAAG,SAAS,0CAA0C,GAAG;AAAA,EACvF;AACF;AAEO,SAAS,oBAAoB,UAAkB,YAAqB,OAAa;AACtF,MAAI,CAAC,WAAW;AACd,UAAM,IAAI;AAAA,MACR,YAAY,QAAQ;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACF;;;AL9BO,SAAS,oBAA6B;AAC3C,QAAM,MAAM,IAAI,QAAQ,MAAM,EAAE,YAAY,2BAA2B;AAEvE,MACG,QAAQ,OAAO,EACf,YAAY,sCAAsC,EAClD,eAAe,iBAAiB,mBAAmB,EACnD,eAAe,yBAAyB,uBAAuB,EAC/D;AAAA,IACC,kBAAkB,OAAO,YAAkD;AACzE,YAAM,KAAK,SAAS,QAAQ,KAAK;AACjC,YAAM,KAAK,aAAa,QAAQ,SAAS;AAEzC,aAAO,WAAW;AAClB,YAAM,OAAO,mBAAmB;AAEhC,iBAAW,EAAE,SAAS,6CAA6C,CAAC;AAAA,IACtE,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,QAAQ,EAChB,YAAY,2BAA2B,EACvC;AAAA,IACC,kBAAkB,YAAY;AAC5B,YAAM,KAAK,OAAO;AAClB,aAAO,WAAW;AAClB,iBAAW,EAAE,SAAS,0BAA0B,CAAC;AAAA,IACnD,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,QAAQ,EAChB,YAAY,6BAA6B,EACzC;AAAA,IACC,kBAAkB,YAAY;AAC5B,YAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,YAAM,WAAW,CAAC,CAAE,MAAM,KAAK,SAAS;AACxC,YAAM,eAAe,CAAC,CAAE,MAAM,KAAK,aAAa;AAEhD,iBAAW;AAAA,QACT,eAAe;AAAA,QACf,YAAY,YAAY;AAAA,MAC1B,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,SAAS,EACjB,YAAY,sBAAsB,EAClC;AAAA,IACC,kBAAkB,YAAY;AAC5B,aAAO,WAAW;AAClB,YAAM,OAAO,mBAAmB;AAChC,iBAAW,EAAE,SAAS,yBAAyB,CAAC;AAAA,IAClD,CAAC;AAAA,EACH;AAEF,SAAO;AACT;;;AMjEA,SAAS,WAAAC,gBAAe;AAMjB,SAAS,yBAAkC;AAChD,QAAM,MAAM,IAAIC,SAAQ,WAAW,EAAE,YAAY,oBAAoB;AAErE,MACG,QAAQ,MAAM,EACd,YAAY,gBAAgB,EAC5B,OAAO,mBAAmB,aAAa,EACvC;AAAA,IACC,kBAAkB,OAAO,YAA+B;AACtD,YAAM,SAAS,MAAM,OAAO;AAAA,QAC1B,QAAQ,OAAO,SAAS,QAAQ,MAAM,EAAE,IAAI;AAAA,MAC9C;AACA,iBAAW,MAAM;AAAA,IACnB,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,MAAM,EACd,YAAY,gBAAgB,EAC5B,SAAS,QAAQ,YAAY,EAC7B;AAAA,IACC,kBAAkB,OAAO,OAAe;AACtC,YAAM,UAAU,MAAM,OAAO,WAAW,WAAW,IAAI,SAAS,CAAC;AACjE,iBAAW,OAAO;AAAA,IACpB,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,aAAa,EACrB,YAAY,qBAAqB,EACjC,SAAS,QAAQ,YAAY,EAC7B;AAAA,IACC,kBAAkB,OAAO,OAAe;AACtC,YAAM,YAAY,WAAW,IAAI,SAAS;AAC1C,aAAO,kBAAkB,OAAO,SAAS,CAAC;AAC1C,iBAAW,EAAE,SAAS,0BAA0B,SAAS,GAAG,CAAC;AAAA,IAC/D,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,aAAa,EACrB,YAAY,qBAAqB,EACjC;AAAA,IACC,kBAAkB,YAAY;AAC5B,YAAM,YAAY,OAAO,kBAAkB;AAC3C,iBAAW,EAAE,gBAAgB,aAAa,KAAK,CAAC;AAAA,IAClD,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,eAAe,EACvB,YAAY,uBAAuB,EACnC;AAAA,IACC,kBAAkB,YAAY;AAC5B,aAAO,oBAAoB;AAC3B,iBAAW,EAAE,SAAS,0BAA0B,CAAC;AAAA,IACnD,CAAC;AAAA,EACH;AAEF,SAAO;AACT;;;AClEA,SAAS,WAAAC,gBAAe;;;ACAxB,OAAO,WAAW;AAGX,SAAS,cAAc,OAAuB;AACnD,QAAM,IAAI,MAAM,KAAK;AACrB,MAAI,CAAC,EAAE,QAAQ,GAAG;AAChB,UAAM,IAAI,kBAAkB,iBAAiB,KAAK,IAAI,GAAG;AAAA,EAC3D;AACA,SAAO,EAAE,YAAY,EAAE,QAAQ,aAAa,GAAG;AACjD;AASA,SAAS,YAAY,OAAe,OAAgB,QAA2B;AAC7E,QAAM,UAAoB,CAAC;AAC3B,MAAI,MAAO,SAAQ,KAAK,GAAG,KAAK,KAAK,cAAc,KAAK,CAAC,QAAQ;AACjE,MAAI,OAAQ,SAAQ,KAAK,GAAG,KAAK,UAAU,cAAc,MAAM,CAAC,GAAG;AACnE,SAAO;AACT;AAEO,SAAS,eAAe,SAAsB,eAA4C;AAC/F,QAAM,QAAQ;AAAA,IACZ,GAAG,YAAY,aAAa,QAAQ,cAAc,QAAQ,aAAa;AAAA,IACvE,GAAG,YAAY,cAAc,QAAQ,eAAe,QAAQ,cAAc;AAAA,EAC5E;AAEA,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,QAAM,YAAY,MAAM,KAAK,OAAO;AACpC,SAAO,gBAAgB,IAAI,aAAa,SAAS,SAAS,KAAK;AACjE;;;ADPA,IAAM,qBAAqB;AAE3B,SAAS,SAAS,MAAsB;AACtC,MAAI,KAAK,UAAU,mBAAoB,QAAO;AAC9C,SAAO,KAAK,MAAM,GAAG,kBAAkB,EAAE,KAAK,IAAI;AACpD;AAEA,SAAS,gBAAgB,MAAyE;AAChG,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,UAAU,KAAK,OAAO,KAAK,IAAI;AACxC;AAEA,SAAS,kBAAkB,SAGzB;AACA,MAAI,CAAC,SAAS,QAAQ;AACpB,WAAO;AAAA,MACL,UAAU,EAAE,cAAc,EAAE;AAAA,MAC5B,MAAM,EAAE,cAAc,EAAE;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,GAAG,OAAO,EAAE;AAAA,IACjC,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ;AAAA,EAC5E;AAEA,QAAM,kBAAkB,cAAc,OAAO,CAAC,MAAM,EAAE,SAAS,UAAU;AACzE,QAAM,cAAc,cAAc,OAAO,CAAC,MAAM,EAAE,SAAS,SAAS;AAEpE,QAAM,wBAAwB,gBAAgB,KAAK,CAAC,MAAM,EAAE,IAAI;AAChE,QAAM,oBAAoB,YAAY,KAAK,CAAC,MAAM,EAAE,IAAI;AACxD,QAAM,uBAAuB,YAAY,YAAY,SAAS,CAAC;AAE/D,QAAM,iBAAiB,uBAAuB,YAAY,uBAAuB;AACjF,QAAM,aAAa,sBAAsB;AAEzC,SAAO;AAAA,IACL,UAAU;AAAA,MACR,MAAM,gBAAgB,cAAc;AAAA,MACpC,OAAO,gBAAgB;AAAA,MACvB,cAAc,gBAAgB;AAAA,MAC9B,cAAc,uBAAuB,OACjC,SAAS,gBAAgB,sBAAsB,IAAI,CAAC,IACpD;AAAA,IACN;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,gBAAgB,UAAU;AAAA,MAChC,OAAO,YAAY;AAAA,MACnB,cAAc,YAAY;AAAA,MAC1B,cAAc,mBAAmB,OAC7B,SAAS,gBAAgB,kBAAkB,IAAI,CAAC,IAChD;AAAA,IACN;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,eAAoD;AAClF,QAAM,WAAmC,CAAC;AAC1C,QAAM,QAAgC,CAAC;AAEvC,aAAW,QAAQ,eAAe;AAChC,aAAS,KAAK,MAAM,KAAK,SAAS,KAAK,MAAM,KAAK,KAAK;AAEvD,eAAW,OAAO,KAAK,QAAQ,CAAC,GAAG;AACjC,YAAM,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,KAAK;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,cAAc;AAAA,IACrB;AAAA,IACA;AAAA,IACA,eAAe,cAAc,IAAI,CAAC,MAAM;AACtC,YAAM,aAAa,kBAAkB,EAAE,WAAW,OAAO;AACzD,aAAO;AAAA,QACL,IAAI,EAAE;AAAA,QACN,SAAS,EAAE;AAAA,QACX,QAAQ,EAAE;AAAA,QACV,OAAO,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,QACtC,GAAG;AAAA,MACL;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,6BAAsC;AACpD,QAAM,MAAM,IAAIC,SAAQ,eAAe,EAAE,YAAY,yBAAyB;AAE9E,MACG,QAAQ,MAAM,EACd,YAAY,oBAAoB,EAChC,OAAO,sBAAsB,sBAAsB,EACnD,OAAO,yBAAyB,6DAA6D,EAC7F,OAAO,oBAAoB,mCAAmC,EAC9D,OAAO,sBAAsB,4BAA4B,EACzD,OAAO,0BAA0B,4CAA4C,EAC7E,OAAO,2BAA2B,6CAA6C,EAC/E,OAAO,2BAA2B,6CAA6C,EAC/E,OAAO,4BAA4B,8CAA8C,EACjF;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,wBAAwB,wBAAwB,EACvD,OAAO,mBAAmB,aAAa,EACvC,OAAO,uBAAuB,2BAA2B,EACzD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,aAAa,6DAA6D,EACjF;AAAA,IACC;AAAA,MACE,OAAO,YAeD;AACJ,cAAM,QAAQ;AAAA,UACZ;AAAA,YACE,cAAc,QAAQ;AAAA,YACtB,eAAe,QAAQ;AAAA,YACvB,eAAe,QAAQ;AAAA,YACvB,gBAAgB,QAAQ;AAAA,UAC1B;AAAA,UACA,QAAQ;AAAA,QACV;AAEA,YAAI,QAAQ,SAAS;AACnB,gBAAM,mBAAmB,MAAM,OAAO,qBAAqB;AAAA,YACzD,SAAS,QAAQ;AAAA,YACjB,QAAQ,QAAQ;AAAA,YAChB,KAAK,QAAQ;AAAA,YACb,YAAY,QAAQ;AAAA,YACpB;AAAA,YACA,OAAO;AAAA,UACT,CAAC;AACD,gBAAM,UAAU,uBAAuB,gBAAgB;AACvD,qBAAW,OAAO;AAClB;AAAA,QACF;AAEA,cAAM,SAAS,MAAM,OAAO,kBAAkB;AAAA,UAC5C,SAAS,QAAQ;AAAA,UACjB,QAAQ,QAAQ;AAAA,UAChB,KAAK,QAAQ;AAAA,UACb,YAAY,QAAQ;AAAA,UACpB,WAAW,QAAQ;AAAA,UACnB,WAAW,QAAQ;AAAA,UACnB,MAAM,QAAQ,OAAO,SAAS,QAAQ,MAAM,EAAE,IAAI;AAAA,UAClD,OAAO,QAAQ;AAAA,UACf;AAAA,QACF,CAAC;AACD,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEF,MACG,QAAQ,MAAM,EACd,YAAY,qBAAqB,EACjC,SAAS,QAAQ,iBAAiB,EAClC;AAAA,IACC,kBAAkB,OAAO,OAAe;AACtC,YAAM,eAAe,MAAM,OAAO,gBAAgB,WAAW,IAAI,cAAc,GAAG,SAAS;AAC3F,YAAM,aAAa,kBAAkB,aAAa,WAAW,OAAO;AACpE,YAAM,SAAS;AAAA,QACb,GAAG;AAAA,QACH,UAAU,WAAW;AAAA,QACrB,MAAM,WAAW;AAAA,MACnB;AACA,iBAAW,QAAQ,EAAE,OAAO,KAAK,CAAC;AAAA,IACpC,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,SAAS,EACjB,YAAY,yEAAyE,EACrF,SAAS,QAAQ,iBAAiB,EAClC,OAAO,mBAAmB,wBAAwB,EAClD,OAAO,SAAS,4DAA4D,EAC5E;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,UAAU,sDAAsD,EACvE;AAAA,IACC;AAAA,MACE,OACE,IACA,YACG;AACH,YAAI,UAAU,MAAM,OAAO,uBAAuB,WAAW,IAAI,cAAc,CAAC;AAEhF,YAAI,QAAQ,MAAM;AAChB,gBAAM,QAAQ,QAAQ,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC;AACvE,oBAAU,QAAQ,OAAO,CAAC,MAAM,MAAM,SAAS,EAAE,IAAI,CAAC;AAAA,QACxD,WAAW,CAAC,QAAQ,KAAK;AACvB,gBAAM,eAAe,QAAQ,eACzB,CAAC,YAAY,WAAW,QAAQ,QAAQ,OAAO,IAC/C,CAAC,YAAY,WAAW,QAAQ,OAAO;AAC3C,oBAAU,QAAQ,OAAO,CAAC,MAAM,aAAa,SAAS,EAAE,IAAI,CAAC;AAAA,QAC/D;AAEA,mBAAW,SAAS,EAAE,OAAO,CAAC,QAAQ,KAAK,CAAC;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;AAEF,MACG,QAAQ,QAAQ,EAChB,YAAY,uBAAuB,EACnC,SAAS,QAAQ,iBAAiB,EAClC,OAAO,aAAa,mBAAmB,EACvC;AAAA,IACC,kBAAkB,OAAO,IAAY,YAA+B;AAClE,0BAAoB,gBAAgB,QAAQ,GAAG;AAC/C,YAAM,OAAO,mBAAmB,WAAW,IAAI,cAAc,CAAC;AAC9D,iBAAW,EAAE,SAAS,uBAAuB,CAAC;AAAA,IAChD,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,SAAS,EACjB,YAAY,6BAA6B,EACzC,SAAS,QAAQ,iBAAiB,EAClC,SAAS,SAAS,UAAU,EAC5B;AAAA,IACC,kBAAkB,OAAO,IAAY,QAAgB;AACnD,YAAM,OAAO,mBAAmB,WAAW,IAAI,cAAc,GAAG,GAAG;AACnE,iBAAW,EAAE,SAAS,QAAQ,GAAG,UAAU,CAAC;AAAA,IAC9C,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,YAAY,EACpB,YAAY,kCAAkC,EAC9C,SAAS,QAAQ,iBAAiB,EAClC,SAAS,SAAS,UAAU,EAC5B;AAAA,IACC,kBAAkB,OAAO,IAAY,QAAgB;AACnD,YAAM,OAAO,sBAAsB,WAAW,IAAI,cAAc,GAAG,GAAG;AACtE,iBAAW,EAAE,SAAS,QAAQ,GAAG,YAAY,CAAC;AAAA,IAChD,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,OAAO,EACf,YAAY,yBAAyB,EACrC,SAAS,QAAQ,iBAAiB,EAClC,eAAe,iBAAiB,YAAY,EAC5C,OAAO,eAAe,2BAA2B,EACjD,OAAO,WAAW,eAAe,EACjC,OAAO,qBAAqB,+DAA+D,EAC3F;AAAA,IACC;AAAA,MACE,OACE,IACA,YAMG;AACH,cAAM,OAAO,YAAY,WAAW,IAAI,cAAc,GAAG;AAAA,UACvD,MAAM,QAAQ;AAAA,UACd,MAAM,QAAQ,OAAO,WAAW,QAAQ,MAAM,MAAM,IAAI;AAAA,UACxD,OAAO,QAAQ;AAAA,UACf,QAAQ,QAAQ;AAAA,QAClB,CAAC;AACD,mBAAW,EAAE,SAAS,aAAa,CAAC;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AAEF,MACG,QAAQ,MAAM,EACd,YAAY,8BAA8B,EAC1C,SAAS,QAAQ,iBAAiB,EAClC,eAAe,iBAAiB,WAAW,EAC3C,OAAO,eAAe,yBAAyB,EAC/C;AAAA,IACC;AAAA,MACE,OACE,IACA,YAIG;AACH,cAAM,OAAO,WAAW,WAAW,IAAI,cAAc,GAAG;AAAA,UACtD,MAAM,QAAQ;AAAA,UACd,MAAM,QAAQ,OAAO,WAAW,QAAQ,MAAM,MAAM,IAAI;AAAA,QAC1D,CAAC;AACD,mBAAW,EAAE,SAAS,aAAa,CAAC;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AAEF,SAAO;AACT;;;AErVA,SAAS,WAAAC,gBAAe;AAWjB,SAAS,yBAAkC;AAChD,QAAM,MAAM,IAAIC,SAAQ,WAAW,EAAE,YAAY,qBAAqB;AAEtE,MACG,QAAQ,MAAM,EACd,YAAY,gBAAgB,EAC5B,OAAO,sBAAsB,sBAAsB,EACnD,OAAO,uBAAuB,sBAAsB,EACpD,OAAO,sBAAsB,qBAAqB,EAClD,OAAO,0BAA0B,wCAAwC,EACzE,OAAO,2BAA2B,yCAAyC,EAC3E,OAAO,2BAA2B,yCAAyC,EAC3E,OAAO,4BAA4B,0CAA0C,EAC7E,OAAO,wBAAwB,4DAA4D,EAC3F,OAAO,wBAAwB,wBAAwB,EACvD,OAAO,mBAAmB,aAAa,EACvC,OAAO,uBAAuB,uBAAuB,EACrD;AAAA,IACC;AAAA,MACE,OAAO,YAYD;AACJ,cAAM,QAAQ;AAAA,UACZ;AAAA,YACE,cAAc,QAAQ;AAAA,YACtB,eAAe,QAAQ;AAAA,YACvB,eAAe,QAAQ;AAAA,YACvB,gBAAgB,QAAQ;AAAA,UAC1B;AAAA,UACA,QAAQ;AAAA,QACV;AAEA,cAAM,SAAS,MAAM,OAAO,cAAc;AAAA,UACxC,SAAS,QAAQ;AAAA,UACjB,WAAW,QAAQ;AAAA,UACnB,UAAU,QAAQ;AAAA,UAClB,WAAW,QAAQ;AAAA,UACnB,WAAW,QAAQ;AAAA,UACnB,MAAM,QAAQ,OAAO,SAAS,QAAQ,MAAM,EAAE,IAAI;AAAA,UAClD;AAAA,QACF,CAAC;AACD,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEF,MACG,QAAQ,MAAM,EACd,YAAY,iBAAiB,EAC7B,SAAS,QAAQ,aAAa,EAC9B;AAAA,IACC,kBAAkB,OAAO,OAAe;AACtC,YAAM,WAAW,MAAM,OAAO,YAAY,WAAW,IAAI,UAAU,CAAC;AACpE,iBAAW,QAAQ;AAAA,IACrB,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,QAAQ,EAChB,YAAY,mBAAmB,EAC/B,OAAO,uBAAuB,YAAY,EAC1C,OAAO,sBAAsB,WAAW,EACxC,OAAO,mBAAmB,eAAe,EACzC,OAAO,mBAAmB,cAAc,EACxC;AAAA,IACC;AAAA,MACE,OAAO,YAKD;AACJ,cAAM,OAAO;AAAA,UACX,GAAI,QAAQ,aAAa,EAAE,WAAW,QAAQ,UAAU;AAAA,UACxD,GAAI,QAAQ,YAAY,EAAE,UAAU,QAAQ,SAAS;AAAA,UACrD,GAAI,QAAQ,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,QAAQ,OAAO,QAAQ,MAAM,CAAC,EAAE;AAAA,UACxE,GAAI,QAAQ,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,QAAQ,OAAO,QAAQ,MAAM,CAAC,EAAE;AAAA,QAC1E;AACA,+BAAuB,MAAM,iBAAiB;AAC9C,cAAM,OAAO,eAAe,IAAI;AAChC,mBAAW,EAAE,SAAS,mBAAmB,CAAC;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEF,MACG,QAAQ,QAAQ,EAChB,YAAY,mBAAmB,EAC/B,SAAS,QAAQ,aAAa,EAC9B,OAAO,uBAAuB,YAAY,EAC1C,OAAO,sBAAsB,WAAW,EACxC,OAAO,uBAAuB,WAAW,EACzC,OAAO,yBAAyB,UAAU,EAC1C,OAAO,wBAAwB,cAAc,EAC7C,OAAO,uBAAuB,kBAAkB,EAChD;AAAA,IACC;AAAA,MACE,OACE,IACA,YAQG;AACH,cAAM,OAAO;AAAA,UACX,GAAI,QAAQ,aAAa,EAAE,WAAW,QAAQ,UAAU;AAAA,UACxD,GAAI,QAAQ,YAAY,EAAE,UAAU,QAAQ,SAAS;AAAA,UACrD,GAAI,QAAQ,YAAY,EAAE,UAAU,QAAQ,SAAS;AAAA,UACrD,GAAI,QAAQ,YAAY,EAAE,UAAU,QAAQ,SAAS;AAAA,UACrD,GAAI,QAAQ,gBAAgB,EAAE,cAAc,QAAQ,aAAa;AAAA,UACjE,GAAI,QAAQ,cAAc,EAAE,YAAY,QAAQ,WAAW;AAAA,QAC7D;AACA,+BAAuB,MAAM,iBAAiB;AAC9C,cAAM,OAAO,eAAe,WAAW,IAAI,UAAU,GAAG,IAAI;AAC5D,mBAAW,EAAE,SAAS,mBAAmB,CAAC;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEF,MACG,QAAQ,QAAQ,EAChB,YAAY,mBAAmB,EAC/B,SAAS,QAAQ,aAAa,EAC9B,OAAO,aAAa,mBAAmB,EACvC;AAAA,IACC,kBAAkB,OAAO,IAAY,YAA+B;AAClE,0BAAoB,YAAY,QAAQ,GAAG;AAC3C,YAAM,OAAO,eAAe,WAAW,IAAI,UAAU,CAAC;AACtD,iBAAW,EAAE,SAAS,mBAAmB,CAAC;AAAA,IAC5C,CAAC;AAAA,EACH;AAEF,SAAO;AACT;;;AC9JA,SAAS,WAAAC,gBAAe;AAKjB,SAAS,oBAA6B;AAC3C,QAAM,MAAM,IAAIC,SAAQ,MAAM,EAAE,YAAY,gBAAgB;AAE5D,MACG,QAAQ,MAAM,EACd,YAAY,eAAe,EAC3B,OAAO,mBAAmB,aAAa,EACvC;AAAA,IACC,kBAAkB,OAAO,YAA+B;AACtD,YAAM,SAAS,MAAM,OAAO,SAAS,QAAQ,OAAO,SAAS,QAAQ,MAAM,EAAE,IAAI,MAAS;AAC1F,iBAAW,MAAM;AAAA,IACnB,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,MAAM,EACd,YAAY,YAAY,EACxB,SAAS,QAAQ,QAAQ,EACzB;AAAA,IACC,kBAAkB,OAAO,OAAe;AACtC,YAAM,MAAM,MAAM,OAAO,OAAO,WAAW,IAAI,KAAK,CAAC;AACrD,iBAAW,GAAG;AAAA,IAChB,CAAC;AAAA,EACH;AAEF,SAAO;AACT;;;AC/BA,SAAS,WAAAC,gBAAe;AAKjB,SAAS,yBAAkC;AAChD,QAAM,MAAM,IAAIC,SAAQ,WAAW,EAAE,YAAY,qBAAqB;AAEtE,MACG,QAAQ,MAAM,EACd,YAAY,gBAAgB,EAC5B,OAAO,sBAAsB,sBAAsB,EACnD,OAAO,qBAAqB,oCAAoC,EAChE,OAAO,mBAAmB,aAAa,EACvC;AAAA,IACC;AAAA,MACE,OAAO,YAID;AACJ,cAAM,SAAS,MAAM,OAAO,cAAc;AAAA,UACxC,SAAS,QAAQ,UAAU,WAAW,QAAQ,SAAS,SAAS,IAAI;AAAA,UACpE,MAAM,QAAQ;AAAA,UACd,MAAM,QAAQ,OAAO,SAAS,QAAQ,MAAM,EAAE,IAAI;AAAA,QACpD,CAAC;AACD,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEF,MACG,QAAQ,KAAK,EACb,YAAY,wCAAwC,EACpD,SAAS,iBAAiB,aAAa,EACvC,eAAe,yBAAyB,kCAAkC,EAC1E;AAAA,IACC,kBAAkB,OAAO,YAAoB,YAAuC;AAClF,YAAM,kBAAkB,QAAQ,cAC7B,MAAM,GAAG,EACT,IAAI,CAAC,OAAO,WAAW,GAAG,KAAK,GAAG,cAAc,CAAC;AACpD,YAAM,OAAO,YAAY,WAAW,YAAY,UAAU,GAAG,eAAe;AAC5E,iBAAW,EAAE,SAAS,oBAAoB,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,UAAU,EAClB,YAAY,qBAAqB,EACjC,SAAS,QAAQ,aAAa,EAC9B;AAAA,IACC,kBAAkB,OAAO,OAAe;AACtC,YAAM,OAAO,qBAAqB,WAAW,IAAI,UAAU,GAAG,QAAQ;AACtE,iBAAW,EAAE,SAAS,qBAAqB,CAAC;AAAA,IAC9C,CAAC;AAAA,EACH;AAEF,MACG,QAAQ,YAAY,EACpB,YAAY,uBAAuB,EACnC,SAAS,QAAQ,aAAa,EAC9B;AAAA,IACC,kBAAkB,OAAO,OAAe;AACtC,YAAM,OAAO,qBAAqB,WAAW,IAAI,UAAU,GAAG,UAAU;AACxE,iBAAW,EAAE,SAAS,uBAAuB,CAAC;AAAA,IAChD,CAAC;AAAA,EACH;AAEF,SAAO;AACT;;;AbxDA,IAAM,UAAU,IAAIC,SAAQ;AAE5B,QACG,KAAK,WAAW,EAChB,YAAY,yCAAyC,EACrD,QAAQ,OAAW,EACnB,OAAO,iBAAiB,oCAAoC,EAC5D,OAAO,eAAe,gDAAgD,EACtE,OAAO,sBAAsB,iEAAiE,EAC9F,OAAO,yBAAyB,qDAAqD,EACrF,KAAK,aAAa,CAAC,gBAAgB;AAClC,QAAM,UAAU,YAAY,KAAK;AACjC,mBAAiB;AAAA,IACf,SAAS,QAAQ;AAAA,IACjB,MAAM,CAAC,QAAQ;AAAA,IACf,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AACH,CAAC;AAEH,QAAQ,WAAW,kBAAkB,CAAC;AACtC,QAAQ,WAAW,uBAAuB,CAAC;AAC3C,QAAQ,WAAW,2BAA2B,CAAC;AAC/C,QAAQ,WAAW,uBAAuB,CAAC;AAC3C,QAAQ,WAAW,kBAAkB,CAAC;AACtC,QAAQ,WAAW,uBAAuB,CAAC;AAE3C,QAAQ,WAAW,EAAE,MAAM,MAAM;AAC/B,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["Command","result","response","data","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/lib/output.ts","../src/commands/auth.ts","../src/lib/auth.ts","../src/lib/config.ts","../src/lib/errors.ts","../src/lib/api-client.ts","../src/lib/command-utils.ts","../src/commands/mailboxes.ts","../src/commands/conversations.ts","../src/lib/dates.ts","../src/commands/customers.ts","../src/commands/tags.ts","../src/commands/workflows.ts","../src/commands/mcp.ts","../src/mcp/server.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport { Command } from 'commander';\nimport { setOutputOptions } from './lib/output.js';\nimport { createAuthCommand } from './commands/auth.js';\nimport { createMailboxesCommand } from './commands/mailboxes.js';\nimport { createConversationsCommand } from './commands/conversations.js';\nimport { createCustomersCommand } from './commands/customers.js';\nimport { createTagsCommand } from './commands/tags.js';\nimport { createWorkflowsCommand } from './commands/workflows.js';\nimport { createMcpCommand } from './commands/mcp.js';\n\ndeclare const __VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name('helpscout')\n .description('A command-line interface for Help Scout')\n .version(__VERSION__)\n .option('-c, --compact', 'Minified JSON output (single line)')\n .option('-p, --plain', 'Strip HTML from body fields, output plain text')\n .option('--include-metadata', 'Include _links and _embedded in responses (stripped by default)')\n .option('-f, --fields <fields>', 'Comma-separated list of fields to include in output')\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n setOutputOptions({\n compact: options.compact,\n slim: !options.includeMetadata,\n plain: options.plain,\n fields: options.fields,\n });\n });\n\nprogram.addCommand(createAuthCommand());\nprogram.addCommand(createMailboxesCommand());\nprogram.addCommand(createConversationsCommand());\nprogram.addCommand(createCustomersCommand());\nprogram.addCommand(createTagsCommand());\nprogram.addCommand(createWorkflowsCommand());\nprogram.addCommand(createMcpCommand());\n\nprogram.parseAsync().catch(() => {\n process.exit(1);\n});\n","import { convert } from 'html-to-text';\nimport type { OutputOptions } from '../types/index.js';\n\nlet globalOutputOptions: OutputOptions = {};\n\nexport function setOutputOptions(options: OutputOptions): void {\n globalOutputOptions = options;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function htmlToPlainText(html: string): string {\n const text = convert(html, {\n wordwrap: false,\n preserveNewlines: false,\n selectors: [\n { selector: 'a', options: { ignoreHref: true } },\n { selector: 'img', format: 'skip' },\n ],\n });\n\n return text\n .replace(/\\n{3,}/g, '\\n\\n')\n .replace(/[ \\t]+/g, ' ')\n .trim();\n}\n\nfunction convertBodiesToPlainText(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(convertBodiesToPlainText);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (key === 'body' && typeof value === 'string') {\n result[key] = htmlToPlainText(value);\n } else {\n result[key] = convertBodiesToPlainText(value);\n }\n }\n return result;\n }\n\n return data;\n}\n\nfunction stripMetadata(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(stripMetadata);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (key === '_links' || key === '_embedded') {\n continue;\n }\n result[key] = stripMetadata(value);\n }\n return result;\n }\n\n return data;\n}\n\nfunction stripTagStyles(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(stripTagStyles);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n const isTag = 'id' in data && 'name' in data && 'slug' in data;\n\n for (const [key, value] of Object.entries(data)) {\n if (isTag && (key === 'color' || key === 'styles')) {\n continue;\n }\n result[key] = stripTagStyles(value);\n }\n return result;\n }\n\n return data;\n}\n\nexport function buildName(first?: string, last?: string): string | undefined {\n const name = [first, last].filter(Boolean).join(' ');\n return name || undefined;\n}\n\nfunction isPersonObject(data: Record<string, unknown>): boolean {\n return ('first' in data || 'last' in data) && ('email' in data || 'id' in data);\n}\n\nfunction isPlaceholderPerson(data: Record<string, unknown>): boolean {\n return data.id === 0 || data.first === 'unknown';\n}\n\nfunction addNameToPersonObjects(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(addNameToPersonObjects);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n result[key] = addNameToPersonObjects(value);\n }\n\n if (isPersonObject(result) && !isPlaceholderPerson(result)) {\n const name = buildName(result.first as string | undefined, result.last as string | undefined);\n if (name) {\n result.name = name;\n }\n }\n\n return result;\n }\n\n return data;\n}\n\nfunction stripPlaceholderValues(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(stripPlaceholderValues);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (key === 'closedBy' && value === 0) continue;\n if (key === 'savedReplyId' && value === 0) continue;\n\n if (isObject(value) && isPlaceholderPerson(value)) continue;\n\n result[key] = stripPlaceholderValues(value);\n }\n\n return result;\n }\n\n return data;\n}\n\nfunction stripEmptyArrays(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(stripEmptyArrays);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (Array.isArray(value) && value.length === 0) continue;\n result[key] = stripEmptyArrays(value);\n }\n\n return result;\n }\n\n return data;\n}\n\nfunction stripPhotoUrls(data: unknown): unknown {\n if (Array.isArray(data)) {\n return data.map(stripPhotoUrls);\n }\n\n if (isObject(data)) {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (key === 'photoUrl') continue;\n result[key] = stripPhotoUrls(value);\n }\n\n return result;\n }\n\n return data;\n}\n\nfunction selectFields(data: unknown, fields: string[]): unknown {\n if (Array.isArray(data)) {\n return data.map((item) => selectFields(item, fields));\n }\n\n if (isObject(data)) {\n const hasRequestedFields = fields.some((f) => f in data);\n if (hasRequestedFields) {\n const result: Record<string, unknown> = {};\n for (const field of fields) {\n if (field in data) {\n result[field] = data[field];\n }\n }\n return result;\n }\n\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n result[key] = selectFields(value, fields);\n }\n return result;\n }\n\n return data;\n}\n\nexport function outputJson(data: unknown, options: OutputOptions = {}): void {\n const mergedOptions = { ...globalOutputOptions, ...options };\n\n let processed = data;\n\n if (mergedOptions.slim) {\n processed = stripMetadata(processed);\n }\n\n if (mergedOptions.plain) {\n processed = convertBodiesToPlainText(processed);\n }\n\n processed = stripTagStyles(processed);\n processed = addNameToPersonObjects(processed);\n processed = stripPlaceholderValues(processed);\n processed = stripEmptyArrays(processed);\n processed = stripPhotoUrls(processed);\n\n if (mergedOptions.fields) {\n const fieldList = mergedOptions.fields.split(',').map((f) => f.trim());\n processed = selectFields(processed, fieldList);\n }\n\n const jsonString = mergedOptions.compact\n ? JSON.stringify(processed)\n : JSON.stringify(processed, null, 2);\n\n console.log(jsonString);\n}\n","import { Command } from 'commander';\nimport { auth } from '../lib/auth.js';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\n\nexport function createAuthCommand(): Command {\n const cmd = new Command('auth').description('Authentication operations');\n\n cmd\n .command('login')\n .description('Configure Help Scout API credentials')\n .requiredOption('--app-id <id>', 'Help Scout App ID')\n .requiredOption('--app-secret <secret>', 'Help Scout App Secret')\n .action(\n withErrorHandling(async (options: { appId: string; appSecret: string }) => {\n await auth.setAppId(options.appId);\n await auth.setAppSecret(options.appSecret);\n\n client.clearToken();\n await client.refreshAccessToken();\n\n outputJson({ message: 'Successfully authenticated with Help Scout' });\n })\n );\n\n cmd\n .command('logout')\n .description('Remove stored credentials')\n .action(\n withErrorHandling(async () => {\n await auth.logout();\n client.clearToken();\n outputJson({ message: 'Logged out successfully' });\n })\n );\n\n cmd\n .command('status')\n .description('Check authentication status')\n .action(\n withErrorHandling(async () => {\n const hasToken = await auth.isAuthenticated();\n const hasAppId = !!(await auth.getAppId());\n const hasAppSecret = !!(await auth.getAppSecret());\n\n outputJson({\n authenticated: hasToken,\n configured: hasAppId && hasAppSecret,\n });\n })\n );\n\n cmd\n .command('refresh')\n .description('Refresh access token')\n .action(\n withErrorHandling(async () => {\n client.clearToken();\n await client.refreshAccessToken();\n outputJson({ message: 'Access token refreshed' });\n })\n );\n\n return cmd;\n}\n","import { Entry } from '@napi-rs/keyring';\nimport { config } from './config.js';\n\nconst SERVICE_NAME = 'helpscout-cli';\nconst ACCESS_TOKEN_ACCOUNT = 'access-token';\nconst REFRESH_TOKEN_ACCOUNT = 'refresh-token';\nconst APP_ID_ACCOUNT = 'app-id';\nconst APP_SECRET_ACCOUNT = 'app-secret';\n\nconst KEYRING_UNAVAILABLE_ERROR =\n 'Keychain storage unavailable. Cannot store credentials securely.\\n' +\n 'On Linux, install libsecret: sudo apt-get install libsecret-1-dev\\n' +\n 'Then reinstall: bun install -g @stephendolan/helpscout-cli\\n' +\n 'Alternatively, use HELPSCOUT_APP_ID and HELPSCOUT_APP_SECRET environment variables.';\n\nconst keyringCache = new Map<string, Entry | null>();\n\nfunction getKeyring(account: string): Entry | null {\n if (keyringCache.has(account)) {\n return keyringCache.get(account)!;\n }\n try {\n const entry = new Entry(SERVICE_NAME, account);\n keyringCache.set(account, entry);\n return entry;\n } catch {\n keyringCache.set(account, null);\n return null;\n }\n}\n\nasync function getPassword(account: string): Promise<string | null> {\n const entry = getKeyring(account);\n if (entry) {\n try {\n return entry.getPassword();\n } catch {\n return null;\n }\n }\n return null;\n}\n\nasync function setPassword(account: string, value: string): Promise<void> {\n const entry = getKeyring(account);\n if (!entry) {\n throw new Error(KEYRING_UNAVAILABLE_ERROR);\n }\n entry.setPassword(value);\n}\n\nasync function deletePassword(account: string): Promise<boolean> {\n const entry = getKeyring(account);\n if (entry) {\n return entry.deletePassword();\n }\n return false;\n}\n\nexport class AuthManager {\n async getAccessToken(): Promise<string | null> {\n return getPassword(ACCESS_TOKEN_ACCOUNT);\n }\n\n async setAccessToken(token: string): Promise<void> {\n return setPassword(ACCESS_TOKEN_ACCOUNT, token);\n }\n\n async getRefreshToken(): Promise<string | null> {\n return getPassword(REFRESH_TOKEN_ACCOUNT);\n }\n\n async setRefreshToken(token: string): Promise<void> {\n return setPassword(REFRESH_TOKEN_ACCOUNT, token);\n }\n\n async getAppId(): Promise<string | null> {\n const keychainValue = await getPassword(APP_ID_ACCOUNT);\n return keychainValue || process.env.HELPSCOUT_APP_ID || null;\n }\n\n async setAppId(appId: string): Promise<void> {\n return setPassword(APP_ID_ACCOUNT, appId);\n }\n\n async getAppSecret(): Promise<string | null> {\n const keychainValue = await getPassword(APP_SECRET_ACCOUNT);\n return keychainValue || process.env.HELPSCOUT_APP_SECRET || null;\n }\n\n async setAppSecret(appSecret: string): Promise<void> {\n return setPassword(APP_SECRET_ACCOUNT, appSecret);\n }\n\n async isAuthenticated(): Promise<boolean> {\n return (await this.getAccessToken()) !== null;\n }\n\n async logout(): Promise<void> {\n await deletePassword(ACCESS_TOKEN_ACCOUNT);\n await deletePassword(REFRESH_TOKEN_ACCOUNT);\n config.clearDefaultMailbox();\n }\n\n async clearAll(): Promise<void> {\n await deletePassword(ACCESS_TOKEN_ACCOUNT);\n await deletePassword(REFRESH_TOKEN_ACCOUNT);\n await deletePassword(APP_ID_ACCOUNT);\n await deletePassword(APP_SECRET_ACCOUNT);\n config.clear();\n }\n}\n\nexport const auth = new AuthManager();\n","import Conf from 'conf';\n\ninterface ConfigSchema {\n defaultMailbox?: string;\n}\n\nconst store = new Conf<ConfigSchema>({\n projectName: 'helpscout-cli',\n});\n\nexport const config = {\n getDefaultMailbox(): string | undefined {\n return store.get('defaultMailbox') || process.env.HELPSCOUT_MAILBOX_ID;\n },\n\n setDefaultMailbox(mailboxId: string): void {\n store.set('defaultMailbox', mailboxId);\n },\n\n clearDefaultMailbox(): void {\n store.delete('defaultMailbox');\n },\n\n clear(): void {\n store.clear();\n },\n};\n","import type { HelpScoutError } from '../types/index.js';\nimport { outputJson } from './output.js';\n\nexport class HelpScoutCliError extends Error {\n constructor(\n message: string,\n public statusCode?: number\n ) {\n super(message);\n this.name = 'HelpScoutCliError';\n }\n}\n\nexport class HelpScoutApiError extends Error {\n constructor(\n message: string,\n public apiError: unknown,\n public statusCode: number\n ) {\n super(message);\n this.name = 'HelpScoutApiError';\n }\n}\n\nconst ERROR_STATUS_CODES: Record<string, number> = {\n bad_request: 400,\n unauthorized: 401,\n forbidden: 403,\n not_found: 404,\n conflict: 409,\n too_many_requests: 429,\n internal_server_error: 500,\n service_unavailable: 503,\n};\n\nexport function sanitizeErrorMessage(message: string): string {\n const sensitivePatterns = [\n /Bearer\\s+[\\w\\-._~+/]+=*/gi,\n /token[=:]\\s*[\\w\\-._~+/]+=*/gi,\n /client[_-]?secret[=:]\\s*[\\w\\-._~+/]+=*/gi,\n /authorization:\\s*bearer\\s+[\\w\\-._~+/]+=*/gi,\n ];\n\n let sanitized = message;\n for (const pattern of sensitivePatterns) {\n sanitized = sanitized.replace(pattern, '[REDACTED]');\n }\n\n return sanitized.length > 500 ? sanitized.substring(0, 500) + '...' : sanitized;\n}\n\ninterface ApiErrorResponse {\n error?: string;\n error_description?: string;\n message?: string;\n _embedded?: {\n errors?: Array<{\n path?: string;\n message?: string;\n rejectedValue?: string;\n }>;\n };\n}\n\nfunction isErrorObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nexport function sanitizeApiError(error: unknown): HelpScoutError {\n if (!isErrorObject(error)) {\n return {\n name: 'api_error',\n detail: 'An error occurred',\n };\n }\n\n const apiError = error as ApiErrorResponse;\n\n let detail = 'An error occurred';\n if (apiError.error_description) {\n detail = apiError.error_description;\n } else if (apiError.message) {\n detail = apiError.message;\n } else if (apiError._embedded?.errors?.length) {\n detail = apiError._embedded.errors\n .map((e) => e.message || e.path)\n .filter(Boolean)\n .join('; ');\n }\n\n return {\n name: apiError.error || 'api_error',\n detail: sanitizeErrorMessage(detail),\n };\n}\n\nfunction formatErrorResponse(name: string, detail: string, statusCode: number): never {\n const hint =\n name === 'too_many_requests'\n ? 'Help Scout API limit: 200 requests/minute. Wait a moment and retry.'\n : undefined;\n\n const response: { error: { name: string; detail: string; statusCode: number }; hint?: string } = {\n error: { name, detail, statusCode },\n };\n\n if (hint) {\n response.hint = hint;\n }\n\n outputJson(response);\n process.exit(1);\n}\n\nexport function handleHelpScoutError(error: unknown): never {\n if (error instanceof HelpScoutCliError) {\n const sanitized = sanitizeErrorMessage(error.message);\n formatErrorResponse('cli_error', sanitized, error.statusCode || 1);\n }\n\n if (error instanceof HelpScoutApiError) {\n const hsError: HelpScoutError = sanitizeApiError(error.apiError);\n formatErrorResponse(\n hsError.name,\n hsError.detail,\n error.statusCode || ERROR_STATUS_CODES[hsError.name] || 500\n );\n }\n\n if (error instanceof Error) {\n const sanitized = sanitizeErrorMessage(error.message);\n formatErrorResponse('unknown_error', sanitized, 1);\n }\n\n formatErrorResponse('unknown_error', 'An unexpected error occurred', 1);\n}\n","import { auth } from './auth.js';\nimport { HelpScoutCliError, HelpScoutApiError } from './errors.js';\nimport type {\n Conversation,\n Customer,\n Tag,\n Workflow,\n Mailbox,\n Thread,\n PageInfo,\n} from '../types/index.js';\n\nconst API_BASE = 'https://api.helpscout.net/v2';\nconst TOKEN_URL = 'https://api.helpscout.net/v2/oauth2/token';\n\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n token_type: string;\n expires_in: number;\n}\n\ninterface PaginatedResponse<T> {\n _embedded: T;\n page: PageInfo;\n}\n\nexport class HelpScoutClient {\n private accessToken: string | null = null;\n\n clearToken(): void {\n this.accessToken = null;\n }\n\n async refreshAccessToken(): Promise<string> {\n const appId = await auth.getAppId();\n const appSecret = await auth.getAppSecret();\n const refreshToken = await auth.getRefreshToken();\n\n if (!appId || !appSecret) {\n throw new HelpScoutCliError('Not configured. Please run: helpscout auth login', 401);\n }\n\n if (refreshToken) {\n try {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n client_id: appId,\n client_secret: appSecret,\n refresh_token: refreshToken,\n }),\n });\n\n if (response.ok) {\n const data = (await response.json()) as TokenResponse;\n await auth.setAccessToken(data.access_token);\n if (data.refresh_token) {\n await auth.setRefreshToken(data.refresh_token);\n }\n this.accessToken = data.access_token;\n return data.access_token;\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n console.error(\n JSON.stringify({\n warning: 'Refresh token failed, using client credentials',\n reason: message,\n })\n );\n }\n }\n\n let response: Response;\n try {\n response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: appId,\n client_secret: appSecret,\n }),\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown network error';\n throw new HelpScoutCliError(`Network request failed during authentication: ${message}`, 0);\n }\n\n if (!response.ok) {\n const error = await response.json();\n throw new HelpScoutApiError('OAuth token request failed', error, response.status);\n }\n\n const data = (await response.json()) as TokenResponse;\n await auth.setAccessToken(data.access_token);\n this.accessToken = data.access_token;\n return data.access_token;\n }\n\n async getAccessToken(): Promise<string> {\n if (this.accessToken) {\n return this.accessToken;\n }\n\n const storedToken = await auth.getAccessToken();\n if (storedToken) {\n this.accessToken = storedToken;\n return storedToken;\n }\n\n return this.refreshAccessToken();\n }\n\n private async request<T>(\n method: string,\n path: string,\n options: {\n params?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n retry?: boolean;\n rateLimitRetry?: boolean;\n } = {}\n ): Promise<T> {\n const { params, body, retry = true, rateLimitRetry = true } = options;\n\n const url = new URL(`${API_BASE}${path}`);\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n });\n }\n\n const token = await this.getAccessToken();\n const fetchOptions: RequestInit = {\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n };\n if (body) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n let response: Response;\n try {\n response = await fetch(url.toString(), fetchOptions);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown network error';\n throw new HelpScoutCliError(`Network request failed: ${message}`, 0);\n }\n\n if (response.status === 401 && retry) {\n this.accessToken = null;\n await this.refreshAccessToken();\n return this.request(method, path, { ...options, retry: false });\n }\n\n if (response.status === 429 && rateLimitRetry) {\n const retryAfter = parseInt(response.headers.get('Retry-After') || '60', 10);\n const waitSeconds = Math.min(retryAfter, 120);\n console.error(\n JSON.stringify({ warning: `Rate limited. Waiting ${waitSeconds}s before retry...` })\n );\n await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1000));\n return this.request(method, path, { ...options, rateLimitRetry: false });\n }\n\n if (response.status === 204) {\n return {} as T;\n }\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new HelpScoutApiError('API request failed', error, response.status);\n }\n\n return response.json() as Promise<T>;\n }\n\n // Conversations\n async listConversations(\n params: {\n mailbox?: string;\n status?: string;\n tag?: string;\n assignedTo?: string;\n sortField?: string;\n sortOrder?: string;\n page?: number;\n embed?: string;\n query?: string;\n } = {}\n ) {\n const response = await this.request<PaginatedResponse<{ conversations: Conversation[] }>>(\n 'GET',\n '/conversations',\n { params }\n );\n return {\n conversations: response._embedded?.conversations || [],\n page: response.page,\n };\n }\n\n async listAllConversations(\n params: {\n mailbox?: string;\n status?: string;\n tag?: string;\n assignedTo?: string;\n query?: string;\n embed?: string;\n } = {}\n ): Promise<Conversation[]> {\n const allConversations: Conversation[] = [];\n let page = 1;\n let totalPages = 1;\n\n do {\n const result = await this.listConversations({ ...params, page });\n allConversations.push(...result.conversations);\n totalPages = result.page.totalPages;\n page++;\n } while (page <= totalPages);\n\n return allConversations;\n }\n\n async getConversation(conversationId: number, embed?: string) {\n const params = embed ? { embed } : undefined;\n return this.request<Conversation>('GET', `/conversations/${conversationId}`, { params });\n }\n\n async getConversationThreads(conversationId: number) {\n const response = await this.request<PaginatedResponse<{ threads: Thread[] }>>(\n 'GET',\n `/conversations/${conversationId}/threads`\n );\n return response._embedded?.threads || [];\n }\n\n async updateConversation(\n conversationId: number,\n data: Partial<{\n op: string;\n path: string;\n value: unknown;\n }>\n ) {\n await this.request<void>('PATCH', `/conversations/${conversationId}`, { body: data });\n }\n\n async deleteConversation(conversationId: number) {\n await this.request<void>('DELETE', `/conversations/${conversationId}`);\n }\n\n async addConversationTag(conversationId: number, tag: string) {\n await this.request<void>('PUT', `/conversations/${conversationId}/tags`, {\n body: { tags: [tag] },\n });\n }\n\n async removeConversationTag(conversationId: number, tag: string) {\n const conversation = await this.getConversation(conversationId);\n const existingTags = conversation?.tags?.map((t) => t.name) || [];\n const newTags = existingTags.filter((t) => t !== tag);\n await this.request<void>('PUT', `/conversations/${conversationId}/tags`, {\n body: { tags: newTags },\n });\n }\n\n async createReply(\n conversationId: number,\n data: {\n text: string;\n user?: number;\n draft?: boolean;\n status?: string;\n }\n ) {\n await this.request<void>('POST', `/conversations/${conversationId}/reply`, { body: data });\n }\n\n async createNote(\n conversationId: number,\n data: {\n text: string;\n user?: number;\n }\n ) {\n await this.request<void>('POST', `/conversations/${conversationId}/notes`, { body: data });\n }\n\n // Customers\n async listCustomers(\n params: {\n mailbox?: string;\n firstName?: string;\n lastName?: string;\n sortField?: string;\n sortOrder?: string;\n page?: number;\n query?: string;\n } = {}\n ) {\n const response = await this.request<PaginatedResponse<{ customers: Customer[] }>>(\n 'GET',\n '/customers',\n { params }\n );\n return {\n customers: response._embedded?.customers || [],\n page: response.page,\n };\n }\n\n async getCustomer(customerId: number) {\n return this.request<Customer>('GET', `/customers/${customerId}`);\n }\n\n async createCustomer(data: {\n firstName?: string;\n lastName?: string;\n emails?: Array<{ type: string; value: string }>;\n phones?: Array<{ type: string; value: string }>;\n }) {\n await this.request<void>('POST', '/customers', { body: data });\n }\n\n async updateCustomer(\n customerId: number,\n data: Partial<{\n firstName: string;\n lastName: string;\n jobTitle: string;\n location: string;\n organization: string;\n background: string;\n }>\n ) {\n await this.request<void>('PUT', `/customers/${customerId}`, { body: data });\n }\n\n async deleteCustomer(customerId: number) {\n await this.request<void>('DELETE', `/customers/${customerId}`);\n }\n\n // Tags\n async listTags(page?: number) {\n const response = await this.request<PaginatedResponse<{ tags: Tag[] }>>('GET', '/tags', {\n params: page ? { page } : undefined,\n });\n return {\n tags: response._embedded?.tags || [],\n page: response.page,\n };\n }\n\n async getTag(tagId: number) {\n return this.request<Tag>('GET', `/tags/${tagId}`);\n }\n\n // Workflows\n async listWorkflows(\n params: {\n mailbox?: number;\n type?: string;\n page?: number;\n } = {}\n ) {\n const response = await this.request<PaginatedResponse<{ workflows: Workflow[] }>>(\n 'GET',\n '/workflows',\n { params: { mailboxId: params.mailbox, type: params.type, page: params.page } }\n );\n return {\n workflows: response._embedded?.workflows || [],\n page: response.page,\n };\n }\n\n async runWorkflow(workflowId: number, conversationIds: number[]) {\n await this.request<void>('POST', `/workflows/${workflowId}/run`, {\n body: { conversationIds },\n });\n }\n\n async updateWorkflowStatus(workflowId: number, status: 'active' | 'inactive') {\n await this.request<void>('PATCH', `/workflows/${workflowId}`, {\n body: { op: 'replace', path: '/status', value: status },\n });\n }\n\n // Mailboxes\n async listMailboxes(page?: number) {\n const response = await this.request<PaginatedResponse<{ mailboxes: Mailbox[] }>>(\n 'GET',\n '/mailboxes',\n { params: page ? { page } : undefined }\n );\n return {\n mailboxes: response._embedded?.mailboxes || [],\n page: response.page,\n };\n }\n\n async getMailbox(mailboxId: number) {\n return this.request<Mailbox>('GET', `/mailboxes/${mailboxId}`);\n }\n}\n\nexport const client = new HelpScoutClient();\n","import { handleHelpScoutError, HelpScoutCliError } from './errors.js';\n\nexport function withErrorHandling<T extends unknown[], R>(\n fn: (...args: T) => Promise<R>\n): (...args: T) => Promise<void> {\n return async (...args: T) => {\n try {\n await fn(...args);\n } catch (error) {\n handleHelpScoutError(error);\n }\n };\n}\n\nexport function parseIdArg(value: string, resourceType: string = 'resource'): number {\n const parsed = parseInt(value, 10);\n if (isNaN(parsed) || parsed <= 0) {\n throw new HelpScoutCliError(`Invalid ${resourceType} ID: \"${value}\"`, 400);\n }\n return parsed;\n}\n\nexport function requireAtLeastOneField(data: Record<string, unknown>, operation: string): void {\n const hasFields = Object.values(data).some((v) => v !== undefined);\n if (!hasFields) {\n throw new HelpScoutCliError(`${operation} requires at least one field to update`, 400);\n }\n}\n\nexport function requireConfirmation(itemType: string, confirmed: boolean = false): void {\n if (!confirmed) {\n throw new HelpScoutCliError(\n `Deleting ${itemType} requires --yes flag to confirm`,\n 400\n );\n }\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { config } from '../lib/config.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling, parseIdArg } from '../lib/command-utils.js';\n\nexport function createMailboxesCommand(): Command {\n const cmd = new Command('mailboxes').description('Mailbox operations');\n\n cmd\n .command('list')\n .description('List mailboxes')\n .option('--page <number>', 'Page number')\n .action(\n withErrorHandling(async (options: { page?: string }) => {\n const result = await client.listMailboxes(\n options.page ? parseInt(options.page, 10) : undefined\n );\n outputJson(result);\n })\n );\n\n cmd\n .command('view')\n .description('View a mailbox')\n .argument('<id>', 'Mailbox ID')\n .action(\n withErrorHandling(async (id: string) => {\n const mailbox = await client.getMailbox(parseIdArg(id, 'mailbox'));\n outputJson(mailbox);\n })\n );\n\n cmd\n .command('set-default')\n .description('Set default mailbox')\n .argument('<id>', 'Mailbox ID')\n .action(\n withErrorHandling(async (id: string) => {\n const mailboxId = parseIdArg(id, 'mailbox');\n config.setDefaultMailbox(String(mailboxId));\n outputJson({ message: `Default mailbox set to ${mailboxId}` });\n })\n );\n\n cmd\n .command('get-default')\n .description('Get default mailbox')\n .action(\n withErrorHandling(async () => {\n const mailboxId = config.getDefaultMailbox();\n outputJson({ defaultMailbox: mailboxId || null });\n })\n );\n\n cmd\n .command('clear-default')\n .description('Clear default mailbox')\n .action(\n withErrorHandling(async () => {\n config.clearDefaultMailbox();\n outputJson({ message: 'Default mailbox cleared' });\n })\n );\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson, htmlToPlainText, buildName } from '../lib/output.js';\nimport { withErrorHandling, requireConfirmation, parseIdArg } from '../lib/command-utils.js';\nimport { buildDateQuery } from '../lib/dates.js';\nimport type { Conversation, Thread } from '../types/index.js';\n\ninterface ParticipantInfo {\n name?: string;\n email?: string;\n messageCount: number;\n firstMessage?: string;\n}\n\ninterface ConversationSummary {\n total: number;\n byStatus: Record<string, number>;\n byTag: Record<string, number>;\n conversations: Array<{\n id: number;\n subject: string;\n status: string;\n tags: string[];\n customer: ParticipantInfo;\n user: ParticipantInfo;\n }>;\n}\n\nconst MAX_MESSAGE_LENGTH = 300;\n\nfunction truncate(text: string): string {\n if (text.length <= MAX_MESSAGE_LENGTH) return text;\n return text.slice(0, MAX_MESSAGE_LENGTH).trim() + '...';\n}\n\nfunction buildPersonName(info: { first?: string; last?: string } | undefined): string | undefined {\n if (!info) return undefined;\n return buildName(info.first, info.last);\n}\n\nfunction extractThreadInfo(threads: Thread[] | undefined): {\n customer: ParticipantInfo;\n user: ParticipantInfo;\n} {\n if (!threads?.length) {\n return {\n customer: { messageCount: 0 },\n user: { messageCount: 0 },\n };\n }\n\n const sortedThreads = [...threads].sort(\n (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()\n );\n\n const customerThreads = sortedThreads.filter((t) => t.type === 'customer');\n const userThreads = sortedThreads.filter((t) => t.type === 'message');\n\n const firstCustomerWithBody = customerThreads.find((t) => t.body);\n const firstUserWithBody = userThreads.find((t) => t.body);\n const mostRecentUserThread = userThreads[userThreads.length - 1];\n\n const customerSource = firstCustomerWithBody?.customer || firstCustomerWithBody?.createdBy;\n const userSource = mostRecentUserThread?.createdBy;\n\n return {\n customer: {\n name: buildPersonName(customerSource),\n email: customerSource?.email,\n messageCount: customerThreads.length,\n firstMessage: firstCustomerWithBody?.body\n ? truncate(htmlToPlainText(firstCustomerWithBody.body))\n : undefined,\n },\n user: {\n name: buildPersonName(userSource),\n email: userSource?.email,\n messageCount: userThreads.length,\n firstMessage: firstUserWithBody?.body\n ? truncate(htmlToPlainText(firstUserWithBody.body))\n : undefined,\n },\n };\n}\n\nfunction summarizeConversations(conversations: Conversation[]): ConversationSummary {\n const byStatus: Record<string, number> = {};\n const byTag: Record<string, number> = {};\n\n for (const conv of conversations) {\n byStatus[conv.status] = (byStatus[conv.status] || 0) + 1;\n\n for (const tag of conv.tags || []) {\n byTag[tag.name] = (byTag[tag.name] || 0) + 1;\n }\n }\n\n return {\n total: conversations.length,\n byStatus,\n byTag,\n conversations: conversations.map((c) => {\n const threadInfo = extractThreadInfo(c._embedded?.threads);\n return {\n id: c.id,\n subject: c.subject,\n status: c.status,\n tags: (c.tags || []).map((t) => t.name),\n ...threadInfo,\n };\n }),\n };\n}\n\nexport function createConversationsCommand(): Command {\n const cmd = new Command('conversations').description('Conversation operations');\n\n cmd\n .command('list')\n .description('List conversations')\n .option('-m, --mailbox <id>', 'Filter by mailbox ID')\n .option('-s, --status <status>', 'Filter by status (active, all, closed, open, pending, spam)')\n .option('-t, --tag <tags>', 'Filter by tag(s), comma-separated')\n .option('--assigned-to <id>', 'Filter by assignee user ID')\n .option('--created-since <date>', 'Show conversations created after this date')\n .option('--created-before <date>', 'Show conversations created before this date')\n .option('--modified-since <date>', 'Show conversations modified after this date')\n .option('--modified-before <date>', 'Show conversations modified before this date')\n .option(\n '--sort-field <field>',\n 'Sort by field (createdAt, modifiedAt, number, status, subject)'\n )\n .option('--sort-order <order>', 'Sort order (asc, desc)')\n .option('--page <number>', 'Page number')\n .option('--embed <resources>', 'Embed resources (threads)')\n .option(\n '-q, --query <query>',\n 'Advanced search query (see https://docs.helpscout.com/article/47-search-filters-with-operators)'\n )\n .option('--summary', 'Output aggregated summary instead of full conversation list')\n .action(\n withErrorHandling(\n async (options: {\n mailbox?: string;\n status?: string;\n tag?: string;\n assignedTo?: string;\n createdSince?: string;\n createdBefore?: string;\n modifiedSince?: string;\n modifiedBefore?: string;\n sortField?: string;\n sortOrder?: string;\n page?: string;\n embed?: string;\n query?: string;\n summary?: boolean;\n }) => {\n const query = buildDateQuery(\n {\n createdSince: options.createdSince,\n createdBefore: options.createdBefore,\n modifiedSince: options.modifiedSince,\n modifiedBefore: options.modifiedBefore,\n },\n options.query\n );\n\n if (options.summary) {\n const allConversations = await client.listAllConversations({\n mailbox: options.mailbox,\n status: options.status,\n tag: options.tag,\n assignedTo: options.assignedTo,\n query,\n embed: 'threads',\n });\n const summary = summarizeConversations(allConversations);\n outputJson(summary);\n return;\n }\n\n const result = await client.listConversations({\n mailbox: options.mailbox,\n status: options.status,\n tag: options.tag,\n assignedTo: options.assignedTo,\n sortField: options.sortField,\n sortOrder: options.sortOrder,\n page: options.page ? parseInt(options.page, 10) : undefined,\n embed: options.embed,\n query,\n });\n outputJson(result);\n }\n )\n );\n\n cmd\n .command('view')\n .description('View a conversation')\n .argument('<id>', 'Conversation ID')\n .action(\n withErrorHandling(async (id: string) => {\n const conversation = await client.getConversation(parseIdArg(id, 'conversation'), 'threads');\n const threadInfo = extractThreadInfo(conversation._embedded?.threads);\n const result = {\n ...conversation,\n customer: threadInfo.customer,\n user: threadInfo.user,\n };\n outputJson(result, { plain: true });\n })\n );\n\n cmd\n .command('threads')\n .description('List threads for a conversation (defaults to email communications only)')\n .argument('<id>', 'Conversation ID')\n .option('--include-notes', 'Include internal notes')\n .option('--all', 'Show all thread types including lineitems, workflows, etc.')\n .option(\n '-t, --type <types>',\n 'Filter by specific thread type(s), comma-separated (customer, message, note, lineitem, chat, phone, forwardchild, forwardparent, beaconchat)'\n )\n .option('--html', 'Output thread bodies as HTML (default is plain text)')\n .action(\n withErrorHandling(\n async (\n id: string,\n options: { includeNotes?: boolean; all?: boolean; type?: string; html?: boolean }\n ) => {\n let threads = await client.getConversationThreads(parseIdArg(id, 'conversation'));\n\n if (options.type) {\n const types = options.type.split(',').map((t) => t.trim().toLowerCase());\n threads = threads.filter((t) => types.includes(t.type));\n } else if (!options.all) {\n const allowedTypes = options.includeNotes\n ? ['customer', 'message', 'note', 'chat', 'phone']\n : ['customer', 'message', 'chat', 'phone'];\n threads = threads.filter((t) => allowedTypes.includes(t.type));\n }\n\n outputJson(threads, { plain: !options.html });\n }\n )\n );\n\n cmd\n .command('delete')\n .description('Delete a conversation')\n .argument('<id>', 'Conversation ID')\n .option('-y, --yes', 'Skip confirmation')\n .action(\n withErrorHandling(async (id: string, options: { yes?: boolean }) => {\n requireConfirmation('conversation', options.yes);\n await client.deleteConversation(parseIdArg(id, 'conversation'));\n outputJson({ message: 'Conversation deleted' });\n })\n );\n\n cmd\n .command('add-tag')\n .description('Add a tag to a conversation')\n .argument('<id>', 'Conversation ID')\n .argument('<tag>', 'Tag name')\n .action(\n withErrorHandling(async (id: string, tag: string) => {\n await client.addConversationTag(parseIdArg(id, 'conversation'), tag);\n outputJson({ message: `Tag \"${tag}\" added` });\n })\n );\n\n cmd\n .command('remove-tag')\n .description('Remove a tag from a conversation')\n .argument('<id>', 'Conversation ID')\n .argument('<tag>', 'Tag name')\n .action(\n withErrorHandling(async (id: string, tag: string) => {\n await client.removeConversationTag(parseIdArg(id, 'conversation'), tag);\n outputJson({ message: `Tag \"${tag}\" removed` });\n })\n );\n\n cmd\n .command('reply')\n .description('Reply to a conversation')\n .argument('<id>', 'Conversation ID')\n .requiredOption('--text <text>', 'Reply text')\n .option('--user <id>', 'User ID sending the reply')\n .option('--draft', 'Save as draft')\n .option('--status <status>', 'Set conversation status after reply (active, closed, pending)')\n .action(\n withErrorHandling(\n async (\n id: string,\n options: {\n text: string;\n user?: string;\n draft?: boolean;\n status?: string;\n }\n ) => {\n await client.createReply(parseIdArg(id, 'conversation'), {\n text: options.text,\n user: options.user ? parseIdArg(options.user, 'user') : undefined,\n draft: options.draft,\n status: options.status,\n });\n outputJson({ message: 'Reply sent' });\n }\n )\n );\n\n cmd\n .command('note')\n .description('Add a note to a conversation')\n .argument('<id>', 'Conversation ID')\n .requiredOption('--text <text>', 'Note text')\n .option('--user <id>', 'User ID adding the note')\n .action(\n withErrorHandling(\n async (\n id: string,\n options: {\n text: string;\n user?: string;\n }\n ) => {\n await client.createNote(parseIdArg(id, 'conversation'), {\n text: options.text,\n user: options.user ? parseIdArg(options.user, 'user') : undefined,\n });\n outputJson({ message: 'Note added' });\n }\n )\n );\n\n return cmd;\n}\n","import dayjs from 'dayjs';\nimport { HelpScoutCliError } from './errors.js';\n\nexport function parseDateTime(input: string): string {\n const d = dayjs(input);\n if (!d.isValid()) {\n throw new HelpScoutCliError(`Invalid date: ${input}`, 400);\n }\n return d.toISOString().replace(/\\.\\d{3}Z$/, 'Z');\n}\n\ninterface DateFilters {\n createdSince?: string;\n createdBefore?: string;\n modifiedSince?: string;\n modifiedBefore?: string;\n}\n\nfunction rangeClause(field: string, since?: string, before?: string): string[] {\n const clauses: string[] = [];\n if (since) clauses.push(`${field}:[${parseDateTime(since)} TO *]`);\n if (before) clauses.push(`${field}:[* TO ${parseDateTime(before)}]`);\n return clauses;\n}\n\nexport function buildDateQuery(filters: DateFilters, existingQuery?: string): string | undefined {\n const parts = [\n ...rangeClause('createdAt', filters.createdSince, filters.createdBefore),\n ...rangeClause('modifiedAt', filters.modifiedSince, filters.modifiedBefore),\n ];\n\n if (parts.length === 0) return existingQuery;\n\n const dateQuery = parts.join(' AND ');\n return existingQuery ? `(${existingQuery}) AND ${dateQuery}` : dateQuery;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport {\n withErrorHandling,\n requireConfirmation,\n parseIdArg,\n requireAtLeastOneField,\n} from '../lib/command-utils.js';\nimport { buildDateQuery } from '../lib/dates.js';\n\nexport function createCustomersCommand(): Command {\n const cmd = new Command('customers').description('Customer operations');\n\n cmd\n .command('list')\n .description('List customers')\n .option('-m, --mailbox <id>', 'Filter by mailbox ID')\n .option('--first-name <name>', 'Filter by first name')\n .option('--last-name <name>', 'Filter by last name')\n .option('--created-since <date>', 'Show customers created after this date')\n .option('--created-before <date>', 'Show customers created before this date')\n .option('--modified-since <date>', 'Show customers modified after this date')\n .option('--modified-before <date>', 'Show customers modified before this date')\n .option('--sort-field <field>', 'Sort by field (createdAt, firstName, lastName, modifiedAt)')\n .option('--sort-order <order>', 'Sort order (asc, desc)')\n .option('--page <number>', 'Page number')\n .option('-q, --query <query>', 'Advanced search query')\n .action(\n withErrorHandling(\n async (options: {\n mailbox?: string;\n firstName?: string;\n lastName?: string;\n createdSince?: string;\n createdBefore?: string;\n modifiedSince?: string;\n modifiedBefore?: string;\n sortField?: string;\n sortOrder?: string;\n page?: string;\n query?: string;\n }) => {\n const query = buildDateQuery(\n {\n createdSince: options.createdSince,\n createdBefore: options.createdBefore,\n modifiedSince: options.modifiedSince,\n modifiedBefore: options.modifiedBefore,\n },\n options.query\n );\n\n const result = await client.listCustomers({\n mailbox: options.mailbox,\n firstName: options.firstName,\n lastName: options.lastName,\n sortField: options.sortField,\n sortOrder: options.sortOrder,\n page: options.page ? parseInt(options.page, 10) : undefined,\n query,\n });\n outputJson(result);\n }\n )\n );\n\n cmd\n .command('view')\n .description('View a customer')\n .argument('<id>', 'Customer ID')\n .action(\n withErrorHandling(async (id: string) => {\n const customer = await client.getCustomer(parseIdArg(id, 'customer'));\n outputJson(customer);\n })\n );\n\n cmd\n .command('create')\n .description('Create a customer')\n .option('--first-name <name>', 'First name')\n .option('--last-name <name>', 'Last name')\n .option('--email <email>', 'Email address')\n .option('--phone <phone>', 'Phone number')\n .action(\n withErrorHandling(\n async (options: {\n firstName?: string;\n lastName?: string;\n email?: string;\n phone?: string;\n }) => {\n const data = {\n ...(options.firstName && { firstName: options.firstName }),\n ...(options.lastName && { lastName: options.lastName }),\n ...(options.email && { emails: [{ type: 'work', value: options.email }] }),\n ...(options.phone && { phones: [{ type: 'work', value: options.phone }] }),\n };\n requireAtLeastOneField(data, 'Customer create');\n await client.createCustomer(data);\n outputJson({ message: 'Customer created' });\n }\n )\n );\n\n cmd\n .command('update')\n .description('Update a customer')\n .argument('<id>', 'Customer ID')\n .option('--first-name <name>', 'First name')\n .option('--last-name <name>', 'Last name')\n .option('--job-title <title>', 'Job title')\n .option('--location <location>', 'Location')\n .option('--organization <org>', 'Organization')\n .option('--background <text>', 'Background notes')\n .action(\n withErrorHandling(\n async (\n id: string,\n options: {\n firstName?: string;\n lastName?: string;\n jobTitle?: string;\n location?: string;\n organization?: string;\n background?: string;\n }\n ) => {\n const data = {\n ...(options.firstName && { firstName: options.firstName }),\n ...(options.lastName && { lastName: options.lastName }),\n ...(options.jobTitle && { jobTitle: options.jobTitle }),\n ...(options.location && { location: options.location }),\n ...(options.organization && { organization: options.organization }),\n ...(options.background && { background: options.background }),\n };\n requireAtLeastOneField(data, 'Customer update');\n await client.updateCustomer(parseIdArg(id, 'customer'), data);\n outputJson({ message: 'Customer updated' });\n }\n )\n );\n\n cmd\n .command('delete')\n .description('Delete a customer')\n .argument('<id>', 'Customer ID')\n .option('-y, --yes', 'Skip confirmation')\n .action(\n withErrorHandling(async (id: string, options: { yes?: boolean }) => {\n requireConfirmation('customer', options.yes);\n await client.deleteCustomer(parseIdArg(id, 'customer'));\n outputJson({ message: 'Customer deleted' });\n })\n );\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling, parseIdArg } from '../lib/command-utils.js';\n\nexport function createTagsCommand(): Command {\n const cmd = new Command('tags').description('Tag operations');\n\n cmd\n .command('list')\n .description('List all tags')\n .option('--page <number>', 'Page number')\n .action(\n withErrorHandling(async (options: { page?: string }) => {\n const result = await client.listTags(options.page ? parseInt(options.page, 10) : undefined);\n outputJson(result);\n })\n );\n\n cmd\n .command('view')\n .description('View a tag')\n .argument('<id>', 'Tag ID')\n .action(\n withErrorHandling(async (id: string) => {\n const tag = await client.getTag(parseIdArg(id, 'tag'));\n outputJson(tag);\n })\n );\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling, parseIdArg } from '../lib/command-utils.js';\n\nexport function createWorkflowsCommand(): Command {\n const cmd = new Command('workflows').description('Workflow operations');\n\n cmd\n .command('list')\n .description('List workflows')\n .option('-m, --mailbox <id>', 'Filter by mailbox ID')\n .option('-t, --type <type>', 'Filter by type (manual, automatic)')\n .option('--page <number>', 'Page number')\n .action(\n withErrorHandling(\n async (options: {\n mailbox?: string;\n type?: string;\n page?: string;\n }) => {\n const result = await client.listWorkflows({\n mailbox: options.mailbox ? parseIdArg(options.mailbox, 'mailbox') : undefined,\n type: options.type,\n page: options.page ? parseInt(options.page, 10) : undefined,\n });\n outputJson(result);\n }\n )\n );\n\n cmd\n .command('run')\n .description('Run a manual workflow on conversations')\n .argument('<workflow-id>', 'Workflow ID')\n .requiredOption('--conversations <ids>', 'Comma-separated conversation IDs')\n .action(\n withErrorHandling(async (workflowId: string, options: { conversations: string }) => {\n const conversationIds = options.conversations\n .split(',')\n .map((id) => parseIdArg(id.trim(), 'conversation'));\n await client.runWorkflow(parseIdArg(workflowId, 'workflow'), conversationIds);\n outputJson({ message: 'Workflow executed' });\n })\n );\n\n cmd\n .command('activate')\n .description('Activate a workflow')\n .argument('<id>', 'Workflow ID')\n .action(\n withErrorHandling(async (id: string) => {\n await client.updateWorkflowStatus(parseIdArg(id, 'workflow'), 'active');\n outputJson({ message: 'Workflow activated' });\n })\n );\n\n cmd\n .command('deactivate')\n .description('Deactivate a workflow')\n .argument('<id>', 'Workflow ID')\n .action(\n withErrorHandling(async (id: string) => {\n await client.updateWorkflowStatus(parseIdArg(id, 'workflow'), 'inactive');\n outputJson({ message: 'Workflow deactivated' });\n })\n );\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { runMcpServer } from '../mcp/server.js';\n\nexport function createMcpCommand(): Command {\n const cmd = new Command('mcp').description('Run Help Scout MCP server');\n\n cmd.action(async () => {\n await runMcpServer();\n });\n\n return cmd;\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport { client } from '../lib/api-client.js';\nimport { auth } from '../lib/auth.js';\n\nconst server = new McpServer({\n name: 'helpscout',\n version: '1.0.0',\n});\n\nfunction jsonResponse(data: unknown) {\n return { content: [{ type: 'text' as const, text: JSON.stringify(data, null, 2) }] };\n}\n\nserver.tool(\n 'list_conversations',\n 'List conversations with optional filtering by status, mailbox, tag, or assignee',\n {\n status: z\n .enum(['active', 'pending', 'closed', 'spam', 'all'])\n .optional()\n .describe('Conversation status filter'),\n mailbox: z.string().optional().describe('Mailbox ID to filter by'),\n tag: z.string().optional().describe('Tag to filter by'),\n assignedTo: z.string().optional().describe('User ID assigned to'),\n query: z.string().optional().describe('Search query'),\n page: z.number().optional().describe('Page number'),\n },\n async ({ status, mailbox, tag, assignedTo, query, page }) =>\n jsonResponse(await client.listConversations({ status, mailbox, tag, assignedTo, query, page }))\n);\n\nserver.tool(\n 'get_conversation',\n 'Get detailed information about a specific conversation including threads',\n {\n conversationId: z.number().describe('Conversation ID'),\n includeThreads: z.boolean().optional().describe('Include conversation threads'),\n },\n async ({ conversationId, includeThreads }) => {\n const conversation = await client.getConversation(conversationId);\n if (includeThreads) {\n const threads = await client.getConversationThreads(conversationId);\n return jsonResponse({ ...conversation, threads });\n }\n return jsonResponse(conversation);\n }\n);\n\nserver.tool(\n 'search_conversations',\n 'Search all conversations matching a query',\n {\n query: z.string().describe('Search query (e.g., \"email:domain.com\", \"subject:billing\")'),\n status: z\n .enum(['active', 'pending', 'closed', 'spam', 'all'])\n .optional()\n .describe('Status filter'),\n },\n async ({ query, status }) => jsonResponse(await client.listAllConversations({ query, status }))\n);\n\nserver.tool(\n 'list_mailboxes',\n 'List all mailboxes in the Help Scout account',\n {},\n async () => jsonResponse(await client.listMailboxes())\n);\n\nserver.tool(\n 'get_mailbox',\n 'Get detailed information about a specific mailbox',\n { mailboxId: z.number().describe('Mailbox ID') },\n async ({ mailboxId }) => jsonResponse(await client.getMailbox(mailboxId))\n);\n\nserver.tool(\n 'list_customers',\n 'List customers with optional filtering',\n {\n query: z.string().optional().describe('Search query'),\n firstName: z.string().optional().describe('Filter by first name'),\n lastName: z.string().optional().describe('Filter by last name'),\n page: z.number().optional().describe('Page number'),\n },\n async ({ query, firstName, lastName, page }) =>\n jsonResponse(await client.listCustomers({ query, firstName, lastName, page }))\n);\n\nserver.tool(\n 'get_customer',\n 'Get detailed information about a specific customer',\n { customerId: z.number().describe('Customer ID') },\n async ({ customerId }) => jsonResponse(await client.getCustomer(customerId))\n);\n\nserver.tool(\n 'list_tags',\n 'List all tags in the Help Scout account',\n { page: z.number().optional().describe('Page number') },\n async ({ page }) => jsonResponse(await client.listTags(page))\n);\n\nserver.tool(\n 'list_workflows',\n 'List workflows with optional filtering',\n {\n mailbox: z.number().optional().describe('Mailbox ID to filter by'),\n type: z.enum(['automatic', 'manual']).optional().describe('Workflow type'),\n page: z.number().optional().describe('Page number'),\n },\n async ({ mailbox, type, page }) => jsonResponse(await client.listWorkflows({ mailbox, type, page }))\n);\n\nserver.tool(\n 'create_note',\n 'Add a private note to a conversation',\n {\n conversationId: z.number().describe('Conversation ID'),\n text: z.string().describe('Note text content'),\n },\n async ({ conversationId, text }) => {\n await client.createNote(conversationId, { text });\n return jsonResponse({ success: true });\n }\n);\n\nserver.tool(\n 'add_tag',\n 'Add a tag to a conversation',\n {\n conversationId: z.number().describe('Conversation ID'),\n tag: z.string().describe('Tag name to add'),\n },\n async ({ conversationId, tag }) => {\n await client.addConversationTag(conversationId, tag);\n return jsonResponse({ success: true });\n }\n);\n\nserver.tool(\n 'check_auth',\n 'Check if Help Scout authentication is configured',\n {},\n async () => jsonResponse({ authenticated: await auth.isAuthenticated() })\n);\n\nexport async function runMcpServer() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n"],"mappings":"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","names":["Command","result","response","data","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stephendolan/helpscout-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "A command-line interface for Help Scout",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cli.js",
|
|
@@ -44,11 +44,13 @@
|
|
|
44
44
|
"LICENSE"
|
|
45
45
|
],
|
|
46
46
|
"dependencies": {
|
|
47
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
47
48
|
"@napi-rs/keyring": "^1.2.0",
|
|
48
49
|
"commander": "^12.0.0",
|
|
49
50
|
"conf": "^12.0.0",
|
|
50
51
|
"dayjs": "^1.11.19",
|
|
51
|
-
"html-to-text": "^9.0.5"
|
|
52
|
+
"html-to-text": "^9.0.5",
|
|
53
|
+
"zod": "^3.24.0"
|
|
52
54
|
},
|
|
53
55
|
"devDependencies": {
|
|
54
56
|
"@biomejs/biome": "^1.9.4",
|