@hailer/mcp 1.1.13 → 1.1.15

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.
Files changed (176) hide show
  1. package/.claude/.context-watchdog.json +1 -0
  2. package/.claude/.session-checked +1 -0
  3. package/.claude/CLAUDE.md +370 -0
  4. package/.claude/agents/agent-ada-skill-builder.md +94 -0
  5. package/.claude/agents/agent-alejandro-function-fields.md +342 -0
  6. package/.claude/agents/agent-bjorn-config-audit.md +103 -0
  7. package/.claude/agents/agent-builder-agent-creator.md +130 -0
  8. package/.claude/agents/agent-code-simplifier.md +53 -0
  9. package/.claude/agents/agent-dmitri-activity-crud.md +159 -0
  10. package/.claude/agents/agent-giuseppe-app-builder.md +208 -0
  11. package/.claude/agents/agent-gunther-mcp-tools.md +39 -0
  12. package/.claude/agents/agent-helga-workflow-config.md +204 -0
  13. package/.claude/agents/agent-igor-activity-mover-automation.md +125 -0
  14. package/.claude/agents/agent-ingrid-doc-templates.md +261 -0
  15. package/.claude/agents/agent-ivan-monolith.md +154 -0
  16. package/.claude/agents/agent-kenji-data-reader.md +86 -0
  17. package/.claude/agents/agent-lars-code-inspector.md +102 -0
  18. package/.claude/agents/agent-marco-mockup-builder.md +110 -0
  19. package/.claude/agents/agent-marcus-api-documenter.md +323 -0
  20. package/.claude/agents/agent-marketplace-publisher.md +280 -0
  21. package/.claude/agents/agent-marketplace-reviewer.md +309 -0
  22. package/.claude/agents/agent-permissions-handler.md +208 -0
  23. package/.claude/agents/agent-simple-writer.md +48 -0
  24. package/.claude/agents/agent-svetlana-code-review.md +171 -0
  25. package/.claude/agents/agent-tanya-test-runner.md +333 -0
  26. package/.claude/agents/agent-ui-designer.md +100 -0
  27. package/.claude/agents/agent-viktor-sql-insights.md +212 -0
  28. package/.claude/agents/agent-web-search.md +55 -0
  29. package/.claude/agents/agent-yevgeni-discussions.md +45 -0
  30. package/.claude/agents/agent-zara-zapier.md +159 -0
  31. package/.claude/agents/ragnar.md +68 -0
  32. package/.claude/commands/app-squad.md +135 -0
  33. package/.claude/commands/audit-squad.md +158 -0
  34. package/.claude/commands/autoplan.md +563 -0
  35. package/.claude/commands/cleanup-squad.md +98 -0
  36. package/.claude/commands/config-squad.md +106 -0
  37. package/.claude/commands/crud-squad.md +87 -0
  38. package/.claude/commands/data-squad.md +97 -0
  39. package/.claude/commands/debug-squad.md +303 -0
  40. package/.claude/commands/doc-squad.md +65 -0
  41. package/.claude/commands/handoff.md +137 -0
  42. package/.claude/commands/health.md +49 -0
  43. package/.claude/commands/help.md +29 -0
  44. package/.claude/commands/help:agents.md +151 -0
  45. package/.claude/commands/help:commands.md +78 -0
  46. package/.claude/commands/help:faq.md +79 -0
  47. package/.claude/commands/help:plugins.md +50 -0
  48. package/.claude/commands/help:skills.md +93 -0
  49. package/.claude/commands/help:tools.md +75 -0
  50. package/.claude/commands/hotfix-squad.md +112 -0
  51. package/.claude/commands/integration-squad.md +82 -0
  52. package/.claude/commands/janitor-squad.md +167 -0
  53. package/.claude/commands/learn-auto.md +120 -0
  54. package/.claude/commands/learn.md +120 -0
  55. package/.claude/commands/mcp-list.md +27 -0
  56. package/.claude/commands/onboard-squad.md +140 -0
  57. package/.claude/commands/plan-workspace.md +732 -0
  58. package/.claude/commands/prd.md +130 -0
  59. package/.claude/commands/project-status.md +82 -0
  60. package/.claude/commands/publish.md +138 -0
  61. package/.claude/commands/recap.md +69 -0
  62. package/.claude/commands/restore.md +64 -0
  63. package/.claude/commands/review-squad.md +152 -0
  64. package/.claude/commands/save.md +24 -0
  65. package/.claude/commands/stats.md +19 -0
  66. package/.claude/commands/swarm.md +210 -0
  67. package/.claude/commands/tool-builder.md +39 -0
  68. package/.claude/commands/ws-pull.md +44 -0
  69. package/.claude/skills/SDK-activity-patterns/SKILL.md +428 -0
  70. package/.claude/skills/SDK-document-templates/SKILL.md +1033 -0
  71. package/.claude/skills/SDK-function-fields/SKILL.md +542 -0
  72. package/.claude/skills/SDK-generate-skill/SKILL.md +92 -0
  73. package/.claude/skills/SDK-init-skill/SKILL.md +127 -0
  74. package/.claude/skills/SDK-insight-queries/SKILL.md +787 -0
  75. package/.claude/skills/SDK-ws-config-skill/SKILL.md +1139 -0
  76. package/.claude/skills/agent-structure/SKILL.md +98 -0
  77. package/.claude/skills/api-documentation-patterns/SKILL.md +474 -0
  78. package/.claude/skills/chrome-mcp-reference/SKILL.md +370 -0
  79. package/.claude/skills/delegation-routing/SKILL.md +202 -0
  80. package/.claude/skills/frontend-design/SKILL.md +254 -0
  81. package/.claude/skills/hailer-activity-mover/SKILL.md +213 -0
  82. package/.claude/skills/hailer-api-client/SKILL.md +518 -0
  83. package/.claude/skills/hailer-app-builder/SKILL.md +1440 -0
  84. package/.claude/skills/hailer-apps-pictures/SKILL.md +269 -0
  85. package/.claude/skills/hailer-design-system/SKILL.md +231 -0
  86. package/.claude/skills/hailer-monolith-automations/SKILL.md +686 -0
  87. package/.claude/skills/hailer-permissions-system/SKILL.md +121 -0
  88. package/.claude/skills/hailer-project-protocol/SKILL.md +488 -0
  89. package/.claude/skills/hailer-rest-api/SKILL.md +61 -0
  90. package/.claude/skills/hailer-rest-api/hailer-activities.md +184 -0
  91. package/.claude/skills/hailer-rest-api/hailer-admin.md +473 -0
  92. package/.claude/skills/hailer-rest-api/hailer-calendar.md +256 -0
  93. package/.claude/skills/hailer-rest-api/hailer-feed.md +249 -0
  94. package/.claude/skills/hailer-rest-api/hailer-insights.md +195 -0
  95. package/.claude/skills/hailer-rest-api/hailer-messaging.md +276 -0
  96. package/.claude/skills/hailer-rest-api/hailer-workflows.md +283 -0
  97. package/.claude/skills/insight-join-patterns/SKILL.md +174 -0
  98. package/.claude/skills/integration-patterns/SKILL.md +421 -0
  99. package/.claude/skills/json-only-output/SKILL.md +72 -0
  100. package/.claude/skills/lsp-setup/SKILL.md +160 -0
  101. package/.claude/skills/mcp-direct-tools/SKILL.md +153 -0
  102. package/.claude/skills/optional-parameters/SKILL.md +72 -0
  103. package/.claude/skills/publish-hailer-app/SKILL.md +221 -0
  104. package/.claude/skills/testing-patterns/SKILL.md +630 -0
  105. package/.claude/skills/tool-builder/SKILL.md +250 -0
  106. package/.claude/skills/tool-parameter-usage/SKILL.md +126 -0
  107. package/.claude/skills/tool-response-verification/SKILL.md +92 -0
  108. package/.claude/skills/zapier-hailer-patterns/SKILL.md +581 -0
  109. package/.opencode/agent/agent-ada-skill-builder.md +35 -0
  110. package/.opencode/agent/agent-alejandro-function-fields.md +39 -0
  111. package/.opencode/agent/agent-bjorn-config-audit.md +36 -0
  112. package/.opencode/agent/agent-builder-agent-creator.md +39 -0
  113. package/.opencode/agent/agent-code-simplifier.md +31 -0
  114. package/.opencode/agent/agent-dmitri-activity-crud.md +40 -0
  115. package/.opencode/agent/agent-giuseppe-app-builder.md +37 -0
  116. package/.opencode/agent/agent-gunther-mcp-tools.md +39 -0
  117. package/.opencode/agent/agent-helga-workflow-config.md +204 -0
  118. package/.opencode/agent/agent-igor-activity-mover-automation.md +46 -0
  119. package/.opencode/agent/agent-ingrid-doc-templates.md +39 -0
  120. package/.opencode/agent/agent-ivan-monolith.md +46 -0
  121. package/.opencode/agent/agent-kenji-data-reader.md +53 -0
  122. package/.opencode/agent/agent-lars-code-inspector.md +28 -0
  123. package/.opencode/agent/agent-marco-mockup-builder.md +42 -0
  124. package/.opencode/agent/agent-marcus-api-documenter.md +53 -0
  125. package/.opencode/agent/agent-marketplace-publisher.md +44 -0
  126. package/.opencode/agent/agent-marketplace-reviewer.md +42 -0
  127. package/.opencode/agent/agent-permissions-handler.md +50 -0
  128. package/.opencode/agent/agent-simple-writer.md +45 -0
  129. package/.opencode/agent/agent-svetlana-code-review.md +39 -0
  130. package/.opencode/agent/agent-tanya-test-runner.md +57 -0
  131. package/.opencode/agent/agent-ui-designer.md +56 -0
  132. package/.opencode/agent/agent-viktor-sql-insights.md +34 -0
  133. package/.opencode/agent/agent-web-search.md +42 -0
  134. package/.opencode/agent/agent-yevgeni-discussions.md +37 -0
  135. package/.opencode/agent/agent-zara-zapier.md +53 -0
  136. package/.opencode/commands/app-squad.md +135 -0
  137. package/.opencode/commands/audit-squad.md +158 -0
  138. package/.opencode/commands/autoplan.md +563 -0
  139. package/.opencode/commands/cleanup-squad.md +98 -0
  140. package/.opencode/commands/config-squad.md +106 -0
  141. package/.opencode/commands/crud-squad.md +87 -0
  142. package/.opencode/commands/data-squad.md +97 -0
  143. package/.opencode/commands/debug-squad.md +303 -0
  144. package/.opencode/commands/doc-squad.md +65 -0
  145. package/.opencode/commands/handoff.md +137 -0
  146. package/.opencode/commands/health.md +49 -0
  147. package/.opencode/commands/help-agents.md +151 -0
  148. package/.opencode/commands/help-commands.md +32 -0
  149. package/.opencode/commands/help-faq.md +29 -0
  150. package/.opencode/commands/help-plugins.md +28 -0
  151. package/.opencode/commands/help-skills.md +7 -0
  152. package/.opencode/commands/help-tools.md +40 -0
  153. package/.opencode/commands/help.md +28 -0
  154. package/.opencode/commands/hotfix-squad.md +112 -0
  155. package/.opencode/commands/integration-squad.md +82 -0
  156. package/.opencode/commands/janitor-squad.md +167 -0
  157. package/.opencode/commands/learn-auto.md +120 -0
  158. package/.opencode/commands/learn.md +120 -0
  159. package/.opencode/commands/mcp-list.md +27 -0
  160. package/.opencode/commands/onboard-squad.md +140 -0
  161. package/.opencode/commands/plan-workspace.md +732 -0
  162. package/.opencode/commands/prd.md +131 -0
  163. package/.opencode/commands/project-status.md +82 -0
  164. package/.opencode/commands/publish.md +138 -0
  165. package/.opencode/commands/recap.md +69 -0
  166. package/.opencode/commands/restore.md +64 -0
  167. package/.opencode/commands/review-squad.md +152 -0
  168. package/.opencode/commands/save.md +24 -0
  169. package/.opencode/commands/stats.md +19 -0
  170. package/.opencode/commands/swarm.md +210 -0
  171. package/.opencode/commands/tool-builder.md +39 -0
  172. package/.opencode/commands/ws-pull.md +44 -0
  173. package/.opencode/opencode.json +21 -0
  174. package/package.json +1 -1
  175. package/scripts/postinstall.cjs +64 -0
  176. package/scripts/test-hal-tools.ts +154 -0
@@ -0,0 +1,518 @@
1
+ ---
2
+ name: hailer-api-client
3
+ description: Hailer API client patterns using @hailer/cli - authentication, requests, signals, reconnection
4
+ version: 1.1.0
5
+ triggers: Hailer client, API connection, WebSocket, session management, real-time signals
6
+ ---
7
+
8
+ # Hailer API Client
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @hailer/cli
14
+ ```
15
+
16
+ ---
17
+
18
+ ## Basic Setup
19
+
20
+ ```typescript
21
+ import { HailerCli } from '@hailer/cli';
22
+
23
+ const client = new HailerCli({
24
+ host: 'https://api.hailer.com', // or 'https://api.hailer.biz' for staging
25
+ reconnect: true, // Auto-reconnect on disconnect
26
+ reconnectInterval: 5000 // Retry every 5 seconds
27
+ });
28
+ ```
29
+
30
+ ---
31
+
32
+ ## Authentication
33
+
34
+ ### Login with Credentials
35
+
36
+ ```typescript
37
+ async function connect(email: string, password: string) {
38
+ try {
39
+ await client.login(email, password);
40
+ console.log('Connected to Hailer');
41
+ } catch (error) {
42
+ console.error('Login failed:', error.message);
43
+ throw error;
44
+ }
45
+ }
46
+ ```
47
+
48
+ ### Login with Session Token
49
+
50
+ ```typescript
51
+ // If you have an existing session token
52
+ await client.loginWithToken(sessionToken);
53
+ ```
54
+
55
+ ### Logout
56
+
57
+ ```typescript
58
+ await client.request('core.logout', []);
59
+ ```
60
+
61
+ ---
62
+
63
+ ## Making Requests
64
+
65
+ ### Basic Request
66
+
67
+ ```typescript
68
+ const result = await client.request('endpoint.name', [arg1, arg2]);
69
+ ```
70
+
71
+ ### Common Endpoints
72
+
73
+ ```typescript
74
+ // Initialize session (get workspaces, user info)
75
+ const init = await client.request('v2.core.init', []);
76
+
77
+ // List workflows
78
+ const workflows = await client.request('v3.process.list', [workspaceId]);
79
+
80
+ // Get workflow schema
81
+ const schema = await client.request('v3.process.getOne', [workflowId]);
82
+
83
+ // List activities
84
+ const activities = await client.request('v3.activity.list', [{
85
+ processId: workflowId,
86
+ phaseId: phaseId, // Optional
87
+ limit: 100, // Default 50
88
+ offset: 0
89
+ }]);
90
+
91
+ // Create activity
92
+ const created = await client.request('v3.activity.create', [{
93
+ processId: workflowId,
94
+ phaseId: phaseId,
95
+ name: 'Activity Name', // Optional
96
+ fields: {
97
+ fieldId1: 'value1',
98
+ fieldId2: 123
99
+ }
100
+ }]);
101
+
102
+ // Update activity
103
+ await client.request('v3.activity.update', [activityId, {
104
+ fields: { fieldId: 'new value' },
105
+ phaseId: newPhaseId // Optional: move to phase
106
+ }]);
107
+
108
+ // Bulk update
109
+ await client.request('v3.activity.updateMany', [
110
+ [activityId1, activityId2],
111
+ { phaseId: targetPhaseId }
112
+ ]);
113
+
114
+ // Get linked activities
115
+ const linked = await client.request('v3.activity.linkedFrom.overview', [activityId]);
116
+
117
+ // Post to discussion
118
+ await client.request('discussion2.send_message', [{
119
+ targetId: discussionId,
120
+ targetType: 'activity',
121
+ message: 'Hello from integration'
122
+ }]);
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Pagination for Large Datasets
128
+
129
+ The API returns max ~500 activities per request. For workflows with more activities, paginate:
130
+
131
+ ### Fetch All Activities
132
+
133
+ ```typescript
134
+ async function fetchAllActivities(
135
+ client: HailerCli,
136
+ workflowId: string,
137
+ phaseId?: string
138
+ ): Promise<any[]> {
139
+ const allActivities: any[] = [];
140
+ let offset = 0;
141
+ const limit = 500;
142
+
143
+ while (true) {
144
+ const batch = await client.request('v3.activity.list', [{
145
+ processId: workflowId,
146
+ phaseId,
147
+ limit,
148
+ offset
149
+ }]);
150
+
151
+ allActivities.push(...batch);
152
+
153
+ if (batch.length < limit) break; // Last page
154
+ offset += limit;
155
+
156
+ // Rate limiting - avoid hammering API
157
+ await new Promise(r => setTimeout(r, 100));
158
+ }
159
+
160
+ return allActivities;
161
+ }
162
+ ```
163
+
164
+ ### Fetch All from Multiple Phases
165
+
166
+ ```typescript
167
+ async function fetchAllFromWorkflow(
168
+ client: HailerCli,
169
+ workflowId: string,
170
+ phaseIds: string[]
171
+ ): Promise<any[]> {
172
+ // Fetch all phases in parallel
173
+ const results = await Promise.all(
174
+ phaseIds.map(phaseId => fetchAllActivities(client, workflowId, phaseId))
175
+ );
176
+
177
+ return results.flat();
178
+ }
179
+ ```
180
+
181
+ ### Streaming Large Datasets
182
+
183
+ For very large datasets, process in batches to avoid memory issues:
184
+
185
+ ```typescript
186
+ async function* streamActivities(
187
+ client: HailerCli,
188
+ workflowId: string,
189
+ phaseId?: string
190
+ ): AsyncGenerator<any[], void, unknown> {
191
+ let offset = 0;
192
+ const limit = 500;
193
+
194
+ while (true) {
195
+ const batch = await client.request('v3.activity.list', [{
196
+ processId: workflowId,
197
+ phaseId,
198
+ limit,
199
+ offset
200
+ }]);
201
+
202
+ if (batch.length === 0) break;
203
+ yield batch;
204
+
205
+ if (batch.length < limit) break;
206
+ offset += limit;
207
+ await new Promise(r => setTimeout(r, 100));
208
+ }
209
+ }
210
+
211
+ // Usage: process batch by batch
212
+ for await (const batch of streamActivities(client, workflowId)) {
213
+ await processBatch(batch);
214
+ }
215
+ ```
216
+
217
+ ---
218
+
219
+ ## Real-Time Signals
220
+
221
+ ### Listening for Events
222
+
223
+ ```typescript
224
+ // Activity updates
225
+ client.on('activities.updated', (data) => {
226
+ console.log('Activity updated:', data);
227
+ // data: { activityIds: string[], processId: string, phaseId?: string }
228
+ });
229
+
230
+ // Activity created
231
+ client.on('activities.created', (data) => {
232
+ console.log('Activity created:', data);
233
+ });
234
+
235
+ // Activity deleted
236
+ client.on('activities.removed', (data) => {
237
+ console.log('Activity removed:', data);
238
+ });
239
+
240
+ // Discussion message
241
+ client.on('discussion.sync', (data) => {
242
+ console.log('New message:', data);
243
+ });
244
+
245
+ // Generic signal handler
246
+ client.on('rpc-response', (response) => {
247
+ if (response.sig) {
248
+ console.log('Signal:', response.sig, response.meta);
249
+ }
250
+ });
251
+ ```
252
+
253
+ ### Common Signals
254
+
255
+ | Signal | Description | Payload |
256
+ |--------|-------------|---------|
257
+ | `activities.created` | New activities | `{ activityIds, processId, phaseId }` |
258
+ | `activities.updated` | Activities modified | `{ activityIds, processId }` |
259
+ | `activities.removed` | Activities deleted | `{ activityIds, processId }` |
260
+ | `discussion.sync` | New message | `{ targetId, message }` |
261
+ | `process.updated` | Workflow changed | `{ processId }` |
262
+ | `notification.reload` | New notification | `{ userId }` |
263
+
264
+ ---
265
+
266
+ ## Connection Management
267
+
268
+ ### Reconnection Handling
269
+
270
+ ```typescript
271
+ const client = new HailerCli({
272
+ host: 'https://api.hailer.com',
273
+ reconnect: true,
274
+ reconnectInterval: 5000
275
+ });
276
+
277
+ client.on('disconnect', () => {
278
+ console.log('Disconnected from Hailer');
279
+ });
280
+
281
+ client.on('reconnect', () => {
282
+ console.log('Reconnected to Hailer');
283
+ });
284
+
285
+ client.on('error', (error) => {
286
+ console.error('Connection error:', error);
287
+ });
288
+ ```
289
+
290
+ ### Manual Reconnection with Backoff
291
+
292
+ ```typescript
293
+ class HailerConnection {
294
+ private client: HailerCli;
295
+ private reconnectAttempts = 0;
296
+ private maxReconnectAttempts = 10;
297
+ private baseDelay = 1000;
298
+
299
+ async connect(email: string, password: string) {
300
+ try {
301
+ await this.client.login(email, password);
302
+ this.reconnectAttempts = 0;
303
+ console.log('Connected');
304
+ } catch (error) {
305
+ await this.handleConnectionError(email, password, error);
306
+ }
307
+ }
308
+
309
+ private async handleConnectionError(email: string, password: string, error: Error) {
310
+ this.reconnectAttempts++;
311
+
312
+ if (this.reconnectAttempts > this.maxReconnectAttempts) {
313
+ console.error('Max reconnection attempts reached');
314
+ process.exit(1);
315
+ }
316
+
317
+ const delay = this.baseDelay * Math.pow(2, this.reconnectAttempts - 1);
318
+ console.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);
319
+
320
+ await this.sleep(delay);
321
+ await this.connect(email, password);
322
+ }
323
+
324
+ private sleep(ms: number) {
325
+ return new Promise(resolve => setTimeout(resolve, ms));
326
+ }
327
+ }
328
+ ```
329
+
330
+ ---
331
+
332
+ ## Error Handling
333
+
334
+ ### Common Error Codes
335
+
336
+ | Code | Description | Action |
337
+ |------|-------------|--------|
338
+ | `InvalidArguments` | Bad request parameters | Check parameter format |
339
+ | `NotFound` | Resource doesn't exist | Verify IDs |
340
+ | `PermissionDenied` | Insufficient access | Check user permissions |
341
+ | `Failed` | Operation failed | Check error message |
342
+ | `Unauthorized` | Not logged in | Re-authenticate |
343
+
344
+ ### Error Handling Pattern
345
+
346
+ ```typescript
347
+ async function safeRequest<T>(
348
+ client: HailerCli,
349
+ method: string,
350
+ args: any[]
351
+ ): Promise<T | null> {
352
+ try {
353
+ return await client.request(method, args);
354
+ } catch (error) {
355
+ switch (error.code) {
356
+ case 'NotFound':
357
+ console.warn(`Resource not found: ${method}`, args);
358
+ return null;
359
+
360
+ case 'PermissionDenied':
361
+ console.error(`Permission denied: ${method}`);
362
+ throw error;
363
+
364
+ case 'InvalidArguments':
365
+ console.error(`Invalid arguments: ${method}`, error.message);
366
+ throw error;
367
+
368
+ default:
369
+ console.error(`Request failed: ${method}`, error);
370
+ throw error;
371
+ }
372
+ }
373
+ }
374
+ ```
375
+
376
+ ---
377
+
378
+ ## Complete Client Class
379
+
380
+ ```typescript
381
+ import { HailerCli } from '@hailer/cli';
382
+
383
+ interface HailerClientConfig {
384
+ host: string;
385
+ email: string;
386
+ password: string;
387
+ }
388
+
389
+ class HailerClient {
390
+ private client: HailerCli;
391
+ private config: HailerClientConfig;
392
+ private connected = false;
393
+
394
+ constructor(config: HailerClientConfig) {
395
+ this.config = config;
396
+ this.client = new HailerCli({
397
+ host: config.host,
398
+ reconnect: true
399
+ });
400
+
401
+ this.setupEventHandlers();
402
+ }
403
+
404
+ private setupEventHandlers() {
405
+ this.client.on('disconnect', () => {
406
+ this.connected = false;
407
+ console.log('Disconnected');
408
+ });
409
+
410
+ this.client.on('reconnect', async () => {
411
+ await this.client.login(this.config.email, this.config.password);
412
+ this.connected = true;
413
+ console.log('Reconnected');
414
+ });
415
+ }
416
+
417
+ async connect() {
418
+ await this.client.login(this.config.email, this.config.password);
419
+ this.connected = true;
420
+ }
421
+
422
+ async disconnect() {
423
+ await this.client.request('core.logout', []);
424
+ this.connected = false;
425
+ }
426
+
427
+ isConnected() {
428
+ return this.connected;
429
+ }
430
+
431
+ // Activity operations
432
+ async createActivity(workflowId: string, phaseId: string, fields: Record<string, any>) {
433
+ return this.client.request('v3.activity.create', [{
434
+ processId: workflowId,
435
+ phaseId,
436
+ fields
437
+ }]);
438
+ }
439
+
440
+ async updateActivity(activityId: string, updates: { fields?: Record<string, any>; phaseId?: string }) {
441
+ return this.client.request('v3.activity.update', [activityId, updates]);
442
+ }
443
+
444
+ async getActivity(activityId: string) {
445
+ return this.client.request('v3.activity.get', [activityId]);
446
+ }
447
+
448
+ async listActivities(workflowId: string, options: { phaseId?: string; limit?: number } = {}) {
449
+ return this.client.request('v3.activity.list', [{
450
+ processId: workflowId,
451
+ ...options
452
+ }]);
453
+ }
454
+
455
+ async moveToPhase(activityIds: string[], phaseId: string) {
456
+ return this.client.request('v3.activity.updateMany', [activityIds, { phaseId }]);
457
+ }
458
+
459
+ // Signal handling
460
+ onActivityUpdate(callback: (data: any) => void) {
461
+ this.client.on('activities.updated', callback);
462
+ }
463
+
464
+ onActivityCreate(callback: (data: any) => void) {
465
+ this.client.on('activities.created', callback);
466
+ }
467
+
468
+ // Raw request access
469
+ async request(method: string, args: any[]) {
470
+ return this.client.request(method, args);
471
+ }
472
+ }
473
+
474
+ export { HailerClient, HailerClientConfig };
475
+ ```
476
+
477
+ ---
478
+
479
+ ## Environment Configuration
480
+
481
+ ```typescript
482
+ // config.ts
483
+ interface Config {
484
+ hailer: {
485
+ host: string;
486
+ email: string;
487
+ password: string;
488
+ };
489
+ }
490
+
491
+ async function loadConfig(): Promise<Config> {
492
+ if (process.env.NODE_ENV === 'production') {
493
+ // Load from AWS Secrets Manager
494
+ return await loadFromSecretsManager();
495
+ }
496
+
497
+ // Local development
498
+ return {
499
+ hailer: {
500
+ host: process.env.HAILER_HOST || 'https://api.hailer.com',
501
+ email: process.env.HAILER_EMAIL || '',
502
+ password: process.env.HAILER_PASSWORD || ''
503
+ }
504
+ };
505
+ }
506
+ ```
507
+
508
+ ---
509
+
510
+ ## Best Practices
511
+
512
+ 1. **Always handle disconnections** - Use reconnect: true and handle events
513
+ 2. **Use exponential backoff** - Don't hammer the server on failures
514
+ 3. **Log all operations** - Structured logging for debugging
515
+ 4. **Validate before sending** - Check IDs and field formats
516
+ 5. **Use bulk operations** - updateMany instead of multiple updates
517
+ 6. **Cache workflow schemas** - Don't fetch on every request
518
+ 7. **Handle rate limits** - Back off on 429 responses