@hailer/mcp 1.1.12 → 1.1.13
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/CHANGELOG.md +0 -7
- package/{.claude → dist}/CLAUDE.md +2 -2
- package/dist/app.js +18 -5
- package/dist/bot/bot-config.d.ts +10 -1
- package/dist/bot/bot-config.js +64 -3
- package/dist/bot/bot-manager.d.ts +2 -0
- package/dist/bot/bot-manager.js +9 -2
- package/dist/bot/bot.d.ts +33 -0
- package/dist/bot/bot.js +461 -160
- package/dist/bot/services/message-classifier.js +17 -0
- package/dist/bot/services/permission-guard.d.ts +52 -0
- package/dist/bot/services/permission-guard.js +149 -0
- package/dist/bot/services/types.d.ts +5 -0
- package/dist/bot/services/typing-indicator.d.ts +6 -1
- package/dist/bot/services/typing-indicator.js +19 -3
- package/dist/cli.js +0 -0
- package/dist/config.d.ts +6 -1
- package/dist/config.js +43 -0
- package/dist/core.js +3 -6
- package/dist/lib/discussion-lock.d.ts +42 -0
- package/dist/lib/discussion-lock.js +110 -0
- package/dist/mcp/UserContextCache.d.ts +5 -0
- package/dist/mcp/UserContextCache.js +51 -19
- package/dist/mcp/hailer-clients.d.ts +19 -1
- package/dist/mcp/hailer-clients.js +158 -24
- package/dist/mcp/session-store.d.ts +68 -0
- package/dist/mcp/session-store.js +169 -0
- package/dist/mcp/signal-handler.js +2 -0
- package/dist/mcp/tool-registry.d.ts +17 -4
- package/dist/mcp/tool-registry.js +37 -7
- package/dist/mcp/tools/activity.js +99 -7
- package/dist/mcp/tools/app-scaffold.js +304 -336
- package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
- package/dist/mcp/tools/bot-config/constants.js +94 -0
- package/dist/mcp/tools/bot-config/core.d.ts +253 -0
- package/dist/mcp/tools/bot-config/core.js +2456 -0
- package/dist/mcp/tools/bot-config/index.d.ts +10 -0
- package/dist/mcp/tools/bot-config/index.js +59 -0
- package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
- package/dist/mcp/tools/bot-config/tools.js +15 -0
- package/dist/mcp/tools/bot-config/types.d.ts +50 -0
- package/dist/mcp/tools/bot-config/types.js +6 -0
- package/dist/mcp/tools/bug-fixer-tools.d.ts +45 -0
- package/dist/mcp/tools/bug-fixer-tools.js +1096 -0
- package/dist/mcp/tools/company.d.ts +9 -0
- package/dist/mcp/tools/company.js +88 -0
- package/dist/mcp/tools/discussion.js +68 -0
- package/dist/mcp/tools/document.d.ts +11 -0
- package/dist/mcp/tools/document.js +741 -0
- package/dist/mcp/tools/investigate.d.ts +9 -0
- package/dist/mcp/tools/investigate.js +254 -0
- package/dist/mcp/tools/workflow-permissions.d.ts +15 -0
- package/dist/mcp/tools/workflow-permissions.js +204 -0
- package/dist/mcp/tools/workflow.js +57 -18
- package/dist/mcp/utils/index.d.ts +2 -0
- package/dist/mcp/utils/index.js +12 -1
- package/dist/mcp/utils/role-utils.d.ts +74 -0
- package/dist/mcp/utils/role-utils.js +151 -0
- package/dist/mcp/utils/types.d.ts +43 -1
- package/dist/mcp/utils/types.js +14 -0
- package/dist/mcp/webhook-handler.d.ts +4 -0
- package/dist/mcp/webhook-handler.js +8 -0
- package/dist/mcp-server.d.ts +23 -2
- package/dist/mcp-server.js +639 -127
- package/dist/plugins/vipunen/client.d.ts +150 -0
- package/dist/plugins/vipunen/client.js +535 -0
- package/dist/plugins/vipunen/config/schema-config.json +19 -0
- package/dist/plugins/vipunen/config/schema-doc.json +22 -0
- package/dist/plugins/vipunen/index.d.ts +41 -0
- package/dist/plugins/vipunen/index.js +88 -0
- package/dist/plugins/vipunen/tools.d.ts +26 -0
- package/dist/plugins/vipunen/tools.js +501 -0
- package/dist/stdio-server.d.ts +14 -0
- package/dist/stdio-server.js +101 -0
- package/package.json +2 -1
- package/.claude/agents/agent-ada-skill-builder.md +0 -94
- package/.claude/agents/agent-alejandro-function-fields.md +0 -342
- package/.claude/agents/agent-bjorn-config-audit.md +0 -103
- package/.claude/agents/agent-builder-agent-creator.md +0 -130
- package/.claude/agents/agent-code-simplifier.md +0 -53
- package/.claude/agents/agent-dmitri-activity-crud.md +0 -159
- package/.claude/agents/agent-giuseppe-app-builder.md +0 -247
- package/.claude/agents/agent-gunther-mcp-tools.md +0 -39
- package/.claude/agents/agent-helga-workflow-config.md +0 -204
- package/.claude/agents/agent-igor-activity-mover-automation.md +0 -125
- package/.claude/agents/agent-ingrid-doc-templates.md +0 -261
- package/.claude/agents/agent-ivan-monolith.md +0 -154
- package/.claude/agents/agent-kenji-data-reader.md +0 -86
- package/.claude/agents/agent-lars-code-inspector.md +0 -102
- package/.claude/agents/agent-marco-mockup-builder.md +0 -110
- package/.claude/agents/agent-marcus-api-documenter.md +0 -323
- package/.claude/agents/agent-marketplace-publisher.md +0 -280
- package/.claude/agents/agent-marketplace-reviewer.md +0 -309
- package/.claude/agents/agent-permissions-handler.md +0 -208
- package/.claude/agents/agent-simple-writer.md +0 -48
- package/.claude/agents/agent-svetlana-code-review.md +0 -171
- package/.claude/agents/agent-tanya-test-runner.md +0 -333
- package/.claude/agents/agent-ui-designer.md +0 -100
- package/.claude/agents/agent-viktor-sql-insights.md +0 -212
- package/.claude/agents/agent-web-search.md +0 -55
- package/.claude/agents/agent-yevgeni-discussions.md +0 -45
- package/.claude/agents/agent-zara-zapier.md +0 -159
- package/.claude/commands/app-squad.md +0 -135
- package/.claude/commands/audit-squad.md +0 -158
- package/.claude/commands/autoplan.md +0 -563
- package/.claude/commands/cleanup-squad.md +0 -98
- package/.claude/commands/config-squad.md +0 -106
- package/.claude/commands/crud-squad.md +0 -87
- package/.claude/commands/data-squad.md +0 -97
- package/.claude/commands/debug-squad.md +0 -303
- package/.claude/commands/doc-squad.md +0 -65
- package/.claude/commands/handoff.md +0 -137
- package/.claude/commands/health.md +0 -49
- package/.claude/commands/help.md +0 -29
- package/.claude/commands/help:agents.md +0 -151
- package/.claude/commands/help:commands.md +0 -78
- package/.claude/commands/help:faq.md +0 -79
- package/.claude/commands/help:plugins.md +0 -50
- package/.claude/commands/help:skills.md +0 -93
- package/.claude/commands/help:tools.md +0 -75
- package/.claude/commands/hotfix-squad.md +0 -112
- package/.claude/commands/integration-squad.md +0 -82
- package/.claude/commands/janitor-squad.md +0 -167
- package/.claude/commands/learn-auto.md +0 -120
- package/.claude/commands/learn.md +0 -120
- package/.claude/commands/mcp-list.md +0 -27
- package/.claude/commands/onboard-squad.md +0 -140
- package/.claude/commands/plan-workspace.md +0 -732
- package/.claude/commands/prd.md +0 -130
- package/.claude/commands/project-status.md +0 -82
- package/.claude/commands/publish.md +0 -138
- package/.claude/commands/recap.md +0 -69
- package/.claude/commands/restore.md +0 -64
- package/.claude/commands/review-squad.md +0 -152
- package/.claude/commands/save.md +0 -24
- package/.claude/commands/stats.md +0 -19
- package/.claude/commands/swarm.md +0 -210
- package/.claude/commands/tool-builder.md +0 -39
- package/.claude/commands/ws-pull.md +0 -44
- package/.claude/hooks/_shared-memory.cjs +0 -305
- package/.claude/hooks/_utils.cjs +0 -108
- package/.claude/hooks/agent-failure-detector.cjs +0 -383
- package/.claude/hooks/agent-usage-logger.cjs +0 -204
- package/.claude/hooks/app-edit-guard.cjs +0 -494
- package/.claude/hooks/auto-learn.cjs +0 -304
- package/.claude/hooks/bash-guard.cjs +0 -272
- package/.claude/hooks/builder-mode-manager.cjs +0 -354
- package/.claude/hooks/bulk-activity-guard.cjs +0 -271
- package/.claude/hooks/context-watchdog.cjs +0 -230
- package/.claude/hooks/delegation-reminder.cjs +0 -465
- package/.claude/hooks/design-system-lint.cjs +0 -271
- package/.claude/hooks/post-scaffold-hook.cjs +0 -181
- package/.claude/hooks/prompt-guard.cjs +0 -354
- package/.claude/hooks/publish-template-guard.cjs +0 -147
- package/.claude/hooks/session-start.cjs +0 -35
- package/.claude/hooks/shared-memory-writer.cjs +0 -147
- package/.claude/hooks/skill-injector.cjs +0 -140
- package/.claude/hooks/skill-usage-logger.cjs +0 -258
- package/.claude/hooks/src-edit-guard.cjs +0 -240
- package/.claude/hooks/sync-marketplace-agents.cjs +0 -346
- package/.claude/settings.json +0 -257
- package/.claude/skills/SDK-activity-patterns/SKILL.md +0 -428
- package/.claude/skills/SDK-document-templates/SKILL.md +0 -1033
- package/.claude/skills/SDK-function-fields/SKILL.md +0 -542
- package/.claude/skills/SDK-generate-skill/SKILL.md +0 -92
- package/.claude/skills/SDK-init-skill/SKILL.md +0 -127
- package/.claude/skills/SDK-insight-queries/SKILL.md +0 -787
- package/.claude/skills/SDK-ws-config-skill/SKILL.md +0 -1139
- package/.claude/skills/agent-structure/SKILL.md +0 -98
- package/.claude/skills/api-documentation-patterns/SKILL.md +0 -474
- package/.claude/skills/chrome-mcp-reference/SKILL.md +0 -370
- package/.claude/skills/delegation-routing/SKILL.md +0 -202
- package/.claude/skills/frontend-design/SKILL.md +0 -254
- package/.claude/skills/hailer-activity-mover/SKILL.md +0 -213
- package/.claude/skills/hailer-api-client/SKILL.md +0 -518
- package/.claude/skills/hailer-app-builder/SKILL.md +0 -1434
- package/.claude/skills/hailer-apps-pictures/SKILL.md +0 -269
- package/.claude/skills/hailer-design-system/SKILL.md +0 -235
- package/.claude/skills/hailer-monolith-automations/SKILL.md +0 -686
- package/.claude/skills/hailer-permissions-system/SKILL.md +0 -121
- package/.claude/skills/hailer-project-protocol/SKILL.md +0 -488
- package/.claude/skills/hailer-rest-api/SKILL.md +0 -61
- package/.claude/skills/hailer-rest-api/hailer-activities.md +0 -184
- package/.claude/skills/hailer-rest-api/hailer-admin.md +0 -473
- package/.claude/skills/hailer-rest-api/hailer-calendar.md +0 -256
- package/.claude/skills/hailer-rest-api/hailer-feed.md +0 -249
- package/.claude/skills/hailer-rest-api/hailer-insights.md +0 -195
- package/.claude/skills/hailer-rest-api/hailer-messaging.md +0 -276
- package/.claude/skills/hailer-rest-api/hailer-workflows.md +0 -283
- package/.claude/skills/insight-join-patterns/SKILL.md +0 -174
- package/.claude/skills/integration-patterns/SKILL.md +0 -421
- package/.claude/skills/json-only-output/SKILL.md +0 -72
- package/.claude/skills/lsp-setup/SKILL.md +0 -160
- package/.claude/skills/mcp-direct-tools/SKILL.md +0 -153
- package/.claude/skills/optional-parameters/SKILL.md +0 -72
- package/.claude/skills/publish-hailer-app/SKILL.md +0 -244
- package/.claude/skills/testing-patterns/SKILL.md +0 -630
- package/.claude/skills/tool-builder/SKILL.md +0 -250
- package/.claude/skills/tool-parameter-usage/SKILL.md +0 -126
- package/.claude/skills/tool-response-verification/SKILL.md +0 -92
- package/.claude/skills/zapier-hailer-patterns/SKILL.md +0 -581
- package/.mcp.json +0 -13
- package/.opencode/agent/agent-ada-skill-builder.md +0 -35
- package/.opencode/agent/agent-alejandro-function-fields.md +0 -39
- package/.opencode/agent/agent-bjorn-config-audit.md +0 -36
- package/.opencode/agent/agent-builder-agent-creator.md +0 -39
- package/.opencode/agent/agent-code-simplifier.md +0 -31
- package/.opencode/agent/agent-dmitri-activity-crud.md +0 -40
- package/.opencode/agent/agent-giuseppe-app-builder.md +0 -37
- package/.opencode/agent/agent-gunther-mcp-tools.md +0 -39
- package/.opencode/agent/agent-helga-workflow-config.md +0 -203
- package/.opencode/agent/agent-igor-activity-mover-automation.md +0 -46
- package/.opencode/agent/agent-ingrid-doc-templates.md +0 -39
- package/.opencode/agent/agent-ivan-monolith.md +0 -46
- package/.opencode/agent/agent-kenji-data-reader.md +0 -53
- package/.opencode/agent/agent-lars-code-inspector.md +0 -28
- package/.opencode/agent/agent-marco-mockup-builder.md +0 -42
- package/.opencode/agent/agent-marcus-api-documenter.md +0 -53
- package/.opencode/agent/agent-marketplace-publisher.md +0 -44
- package/.opencode/agent/agent-marketplace-reviewer.md +0 -42
- package/.opencode/agent/agent-permissions-handler.md +0 -50
- package/.opencode/agent/agent-simple-writer.md +0 -45
- package/.opencode/agent/agent-svetlana-code-review.md +0 -39
- package/.opencode/agent/agent-tanya-test-runner.md +0 -57
- package/.opencode/agent/agent-ui-designer.md +0 -56
- package/.opencode/agent/agent-viktor-sql-insights.md +0 -34
- package/.opencode/agent/agent-web-search.md +0 -42
- package/.opencode/agent/agent-yevgeni-discussions.md +0 -37
- package/.opencode/agent/agent-zara-zapier.md +0 -53
- package/.opencode/commands/app-squad.md +0 -135
- package/.opencode/commands/audit-squad.md +0 -158
- package/.opencode/commands/autoplan.md +0 -563
- package/.opencode/commands/cleanup-squad.md +0 -98
- package/.opencode/commands/config-squad.md +0 -106
- package/.opencode/commands/crud-squad.md +0 -87
- package/.opencode/commands/data-squad.md +0 -97
- package/.opencode/commands/debug-squad.md +0 -303
- package/.opencode/commands/doc-squad.md +0 -65
- package/.opencode/commands/handoff.md +0 -137
- package/.opencode/commands/health.md +0 -49
- package/.opencode/commands/help-agents.md +0 -151
- package/.opencode/commands/help-commands.md +0 -32
- package/.opencode/commands/help-faq.md +0 -29
- package/.opencode/commands/help-plugins.md +0 -28
- package/.opencode/commands/help-skills.md +0 -7
- package/.opencode/commands/help-tools.md +0 -40
- package/.opencode/commands/help.md +0 -28
- package/.opencode/commands/hotfix-squad.md +0 -112
- package/.opencode/commands/integration-squad.md +0 -82
- package/.opencode/commands/janitor-squad.md +0 -167
- package/.opencode/commands/learn-auto.md +0 -120
- package/.opencode/commands/learn.md +0 -120
- package/.opencode/commands/mcp-list.md +0 -27
- package/.opencode/commands/onboard-squad.md +0 -140
- package/.opencode/commands/plan-workspace.md +0 -732
- package/.opencode/commands/prd.md +0 -131
- package/.opencode/commands/project-status.md +0 -82
- package/.opencode/commands/publish.md +0 -138
- package/.opencode/commands/recap.md +0 -69
- package/.opencode/commands/restore.md +0 -64
- package/.opencode/commands/review-squad.md +0 -152
- package/.opencode/commands/save.md +0 -24
- package/.opencode/commands/stats.md +0 -19
- package/.opencode/commands/swarm.md +0 -210
- package/.opencode/commands/tool-builder.md +0 -39
- package/.opencode/commands/ws-pull.md +0 -44
- package/.opencode/opencode.json +0 -28
- package/SESSION-HANDOFF.md +0 -68
- package/inbox/2026-03-04-bot-config-patterns.md +0 -24
- package/scripts/postinstall.cjs +0 -64
- package/scripts/test-hal-tools.ts +0 -154
|
@@ -1,518 +0,0 @@
|
|
|
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
|