@hailer/mcp 0.0.1
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/.claude/commands/tool-builder.md +37 -0
- package/.claude/commands/ws-pull.md +44 -0
- package/.claude/settings.json +8 -0
- package/.claude/settings.local.json +49 -0
- package/.claude/skills/activity-api/SKILL.md +96 -0
- package/.claude/skills/activity-api/references/activity-endpoints.md +845 -0
- package/.claude/skills/add-app-member-skill/SKILL.md +977 -0
- package/.claude/skills/agent-building/SKILL.md +243 -0
- package/.claude/skills/agent-building/references/architecture-patterns.md +446 -0
- package/.claude/skills/agent-building/references/code-examples.md +587 -0
- package/.claude/skills/agent-building/references/implementation-guide.md +619 -0
- package/.claude/skills/app-api/SKILL.md +219 -0
- package/.claude/skills/app-api/references/app-endpoints.md +759 -0
- package/.claude/skills/building-hailer-apps-skill/SKILL.md +548 -0
- package/.claude/skills/create-app-skill/SKILL.md +1101 -0
- package/.claude/skills/create-insight-skill/SKILL.md +1317 -0
- package/.claude/skills/get-insight-data-skill/SKILL.md +1053 -0
- package/.claude/skills/hailer-api/SKILL.md +283 -0
- package/.claude/skills/hailer-api/references/activities.md +620 -0
- package/.claude/skills/hailer-api/references/authentication.md +216 -0
- package/.claude/skills/hailer-api/references/datasets.md +437 -0
- package/.claude/skills/hailer-api/references/files.md +301 -0
- package/.claude/skills/hailer-api/references/insights.md +469 -0
- package/.claude/skills/hailer-api/references/workflows.md +720 -0
- package/.claude/skills/hailer-api/references/workspaces-users.md +445 -0
- package/.claude/skills/insight-api/SKILL.md +185 -0
- package/.claude/skills/insight-api/references/insight-endpoints.md +514 -0
- package/.claude/skills/install-workflow-skill/SKILL.md +1056 -0
- package/.claude/skills/list-apps-skill/SKILL.md +1010 -0
- package/.claude/skills/list-workflows-minimal-skill/SKILL.md +992 -0
- package/.claude/skills/local-first-skill/SKILL.md +570 -0
- package/.claude/skills/mcp-tools/SKILL.md +419 -0
- package/.claude/skills/mcp-tools/references/api-endpoints.md +499 -0
- package/.claude/skills/mcp-tools/references/data-structures.md +554 -0
- package/.claude/skills/mcp-tools/references/implementation-patterns.md +717 -0
- package/.claude/skills/preview-insight-skill/SKILL.md +1290 -0
- package/.claude/skills/publish-hailer-app-skill/SKILL.md +453 -0
- package/.claude/skills/remove-app-member-skill/SKILL.md +671 -0
- package/.claude/skills/remove-app-skill/SKILL.md +985 -0
- package/.claude/skills/remove-insight-skill/SKILL.md +1011 -0
- package/.claude/skills/remove-workflow-skill/SKILL.md +920 -0
- package/.claude/skills/scaffold-hailer-app-skill/SKILL.md +1034 -0
- package/.claude/skills/skill-testing/README.md +137 -0
- package/.claude/skills/skill-testing/SKILL.md +348 -0
- package/.claude/skills/skill-testing/references/test-patterns.md +705 -0
- package/.claude/skills/skill-testing/references/testing-guide.md +603 -0
- package/.claude/skills/skill-testing/references/validation-checklist.md +537 -0
- package/.claude/skills/tool-builder/SKILL.md +328 -0
- package/.claude/skills/update-app-skill/SKILL.md +970 -0
- package/.claude/skills/update-workflow-field-skill/SKILL.md +1098 -0
- package/.env.example +81 -0
- package/.mcp.json +13 -0
- package/README.md +297 -0
- package/dist/app.d.ts +4 -0
- package/dist/app.js +74 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +5 -0
- package/dist/client/adaptive-documentation-bot.d.ts +108 -0
- package/dist/client/adaptive-documentation-bot.js +475 -0
- package/dist/client/adaptive-documentation-types.d.ts +66 -0
- package/dist/client/adaptive-documentation-types.js +9 -0
- package/dist/client/agent-activity-bot.d.ts +51 -0
- package/dist/client/agent-activity-bot.js +166 -0
- package/dist/client/agent-tracker.d.ts +499 -0
- package/dist/client/agent-tracker.js +659 -0
- package/dist/client/description-updater.d.ts +56 -0
- package/dist/client/description-updater.js +259 -0
- package/dist/client/log-parser.d.ts +72 -0
- package/dist/client/log-parser.js +387 -0
- package/dist/client/mcp-client.d.ts +50 -0
- package/dist/client/mcp-client.js +532 -0
- package/dist/client/message-processor.d.ts +35 -0
- package/dist/client/message-processor.js +352 -0
- package/dist/client/multi-bot-manager.d.ts +24 -0
- package/dist/client/multi-bot-manager.js +74 -0
- package/dist/client/providers/anthropic-provider.d.ts +19 -0
- package/dist/client/providers/anthropic-provider.js +631 -0
- package/dist/client/providers/llm-provider.d.ts +47 -0
- package/dist/client/providers/llm-provider.js +367 -0
- package/dist/client/providers/openai-provider.d.ts +23 -0
- package/dist/client/providers/openai-provider.js +621 -0
- package/dist/client/simple-llm-caller.d.ts +19 -0
- package/dist/client/simple-llm-caller.js +100 -0
- package/dist/client/skill-generator.d.ts +81 -0
- package/dist/client/skill-generator.js +386 -0
- package/dist/client/test-adaptive-bot.d.ts +9 -0
- package/dist/client/test-adaptive-bot.js +82 -0
- package/dist/client/token-pricing.d.ts +38 -0
- package/dist/client/token-pricing.js +127 -0
- package/dist/client/token-tracker.d.ts +232 -0
- package/dist/client/token-tracker.js +457 -0
- package/dist/client/token-usage-bot.d.ts +53 -0
- package/dist/client/token-usage-bot.js +153 -0
- package/dist/client/tool-executor.d.ts +69 -0
- package/dist/client/tool-executor.js +159 -0
- package/dist/client/tool-schema-loader.d.ts +60 -0
- package/dist/client/tool-schema-loader.js +178 -0
- package/dist/client/types.d.ts +69 -0
- package/dist/client/types.js +7 -0
- package/dist/config.d.ts +162 -0
- package/dist/config.js +296 -0
- package/dist/core.d.ts +26 -0
- package/dist/core.js +147 -0
- package/dist/lib/context-manager.d.ts +111 -0
- package/dist/lib/context-manager.js +431 -0
- package/dist/lib/logger.d.ts +74 -0
- package/dist/lib/logger.js +277 -0
- package/dist/lib/materialize.d.ts +3 -0
- package/dist/lib/materialize.js +101 -0
- package/dist/lib/normalizedName.d.ts +7 -0
- package/dist/lib/normalizedName.js +48 -0
- package/dist/lib/prompt-length-manager.d.ts +81 -0
- package/dist/lib/prompt-length-manager.js +457 -0
- package/dist/lib/terminal-prompt.d.ts +9 -0
- package/dist/lib/terminal-prompt.js +108 -0
- package/dist/mcp/UserContextCache.d.ts +56 -0
- package/dist/mcp/UserContextCache.js +163 -0
- package/dist/mcp/auth.d.ts +2 -0
- package/dist/mcp/auth.js +29 -0
- package/dist/mcp/hailer-clients.d.ts +42 -0
- package/dist/mcp/hailer-clients.js +246 -0
- package/dist/mcp/signal-handler.d.ts +45 -0
- package/dist/mcp/signal-handler.js +317 -0
- package/dist/mcp/tool-registry.d.ts +100 -0
- package/dist/mcp/tool-registry.js +306 -0
- package/dist/mcp/tools/activity.d.ts +15 -0
- package/dist/mcp/tools/activity.js +955 -0
- package/dist/mcp/tools/app.d.ts +20 -0
- package/dist/mcp/tools/app.js +1488 -0
- package/dist/mcp/tools/discussion.d.ts +19 -0
- package/dist/mcp/tools/discussion.js +950 -0
- package/dist/mcp/tools/file.d.ts +15 -0
- package/dist/mcp/tools/file.js +119 -0
- package/dist/mcp/tools/insight.d.ts +17 -0
- package/dist/mcp/tools/insight.js +806 -0
- package/dist/mcp/tools/skill.d.ts +10 -0
- package/dist/mcp/tools/skill.js +279 -0
- package/dist/mcp/tools/user.d.ts +10 -0
- package/dist/mcp/tools/user.js +108 -0
- package/dist/mcp/tools/workflow-template.d.ts +19 -0
- package/dist/mcp/tools/workflow-template.js +822 -0
- package/dist/mcp/tools/workflow.d.ts +18 -0
- package/dist/mcp/tools/workflow.js +1362 -0
- package/dist/mcp/utils/api-errors.d.ts +45 -0
- package/dist/mcp/utils/api-errors.js +160 -0
- package/dist/mcp/utils/data-transformers.d.ts +102 -0
- package/dist/mcp/utils/data-transformers.js +194 -0
- package/dist/mcp/utils/file-upload.d.ts +33 -0
- package/dist/mcp/utils/file-upload.js +148 -0
- package/dist/mcp/utils/hailer-api-client.d.ts +120 -0
- package/dist/mcp/utils/hailer-api-client.js +323 -0
- package/dist/mcp/utils/index.d.ts +13 -0
- package/dist/mcp/utils/index.js +39 -0
- package/dist/mcp/utils/logger.d.ts +42 -0
- package/dist/mcp/utils/logger.js +103 -0
- package/dist/mcp/utils/types.d.ts +286 -0
- package/dist/mcp/utils/types.js +7 -0
- package/dist/mcp/workspace-cache.d.ts +42 -0
- package/dist/mcp/workspace-cache.js +97 -0
- package/dist/mcp-server.d.ts +42 -0
- package/dist/mcp-server.js +280 -0
- package/package.json +56 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,1056 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Installing Hailer Workflows
|
|
3
|
+
description: Complete guide for installing and designing Hailer workflows - use when creating database schemas or workflow structures
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Installing Hailer Workflows - Complete Guide
|
|
7
|
+
|
|
8
|
+
Complete reference for designing, installing, and managing Hailer workflows using the `install_workflow` MCP tool.
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
1. [Quick Reference](#quick-reference)
|
|
12
|
+
2. [Overview](#overview)
|
|
13
|
+
3. [Core Concepts](#core-concepts)
|
|
14
|
+
4. [Field Types Reference](#field-types-reference)
|
|
15
|
+
5. [ID Patterns and Naming](#id-patterns-and-naming)
|
|
16
|
+
6. [Basic Examples](#basic-examples)
|
|
17
|
+
7. [Advanced Patterns](#advanced-patterns)
|
|
18
|
+
8. [Relationships Between Workflows](#relationships-between-workflows)
|
|
19
|
+
9. [Best Practices](#best-practices)
|
|
20
|
+
10. [Troubleshooting](#troubleshooting)
|
|
21
|
+
|
|
22
|
+
## Quick Reference
|
|
23
|
+
|
|
24
|
+
**Basic Workflow Installation:**
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
install_workflow({
|
|
28
|
+
workflowTemplates: [{
|
|
29
|
+
_id: '_0001',
|
|
30
|
+
name: 'Tasks',
|
|
31
|
+
fields: {
|
|
32
|
+
_1000: { label: 'Title', type: 'text', key: 'title', required: true },
|
|
33
|
+
_1001: { label: 'Priority', type: 'textpredefinedoptions', key: 'priority',
|
|
34
|
+
data: ['Low', 'Medium', 'High'] }
|
|
35
|
+
},
|
|
36
|
+
phases: {
|
|
37
|
+
_2000: { name: 'To Do', isInitial: true },
|
|
38
|
+
_2001: { name: 'Done' }
|
|
39
|
+
}
|
|
40
|
+
}]
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Key Rules:**
|
|
45
|
+
- ALL IDs follow pattern: underscore + 4 digits (`_0001`, `_1000`, `_2000`)
|
|
46
|
+
- Workflow IDs: `_0001`, `_0002`, `_0003`, etc.
|
|
47
|
+
- Field IDs: `_1000`, `_1001`, `_1002`, etc.
|
|
48
|
+
- Phase IDs: `_2000`, `_2001`, `_2002`, etc.
|
|
49
|
+
- 🚨 **CRITICAL:** Phase IDs MUST be unique across ALL workflows (e.g., Teams uses _2000, Players uses _2001-2004, Matches uses _2005-2007)
|
|
50
|
+
- Always set `key` on fields for readable API responses
|
|
51
|
+
- User must be workspace administrator
|
|
52
|
+
|
|
53
|
+
## ❌ Common Mistakes (CRITICAL - READ THIS FIRST!)
|
|
54
|
+
|
|
55
|
+
Based on actual API validation failures, avoid these mistakes:
|
|
56
|
+
|
|
57
|
+
### 1. Wrong Property Names in Fields
|
|
58
|
+
|
|
59
|
+
**❌ DON'T use `name` in field definitions:**
|
|
60
|
+
```javascript
|
|
61
|
+
fields: {
|
|
62
|
+
_1000: {
|
|
63
|
+
name: "task_name", // ❌ WRONG - API rejects "name"
|
|
64
|
+
label: "Task Name",
|
|
65
|
+
type: "text"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**✅ DO use only `label` and optionally `key`:**
|
|
71
|
+
```javascript
|
|
72
|
+
fields: {
|
|
73
|
+
_1000: {
|
|
74
|
+
label: "Task Name", // ✅ CORRECT - Required
|
|
75
|
+
key: "taskName", // ✅ CORRECT - Optional but recommended
|
|
76
|
+
type: "text"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 2. Wrong Property Names for Dropdown Options
|
|
82
|
+
|
|
83
|
+
**❌ DON'T use `options`:**
|
|
84
|
+
```javascript
|
|
85
|
+
_1001: {
|
|
86
|
+
label: "Priority",
|
|
87
|
+
type: "textpredefinedoptions",
|
|
88
|
+
options: ["Low", "High"] // ❌ WRONG - Use "data" not "options"
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**✅ DO use `data`:**
|
|
93
|
+
```javascript
|
|
94
|
+
_1001: {
|
|
95
|
+
label: "Priority",
|
|
96
|
+
type: "textpredefinedoptions",
|
|
97
|
+
data: ["Low", "High"] // ✅ CORRECT
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 3. Arrays Instead of Objects
|
|
102
|
+
|
|
103
|
+
**❌ DON'T use arrays for fields and phases:**
|
|
104
|
+
```javascript
|
|
105
|
+
workflowTemplates: [{
|
|
106
|
+
fields: [ // ❌ WRONG - Array
|
|
107
|
+
{ _id: "_1000", label: "Title", type: "text" }
|
|
108
|
+
],
|
|
109
|
+
phases: [ // ❌ WRONG - Array
|
|
110
|
+
{ _id: "_2000", name: "To Do" }
|
|
111
|
+
]
|
|
112
|
+
}]
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**✅ DO use objects with IDs as keys:**
|
|
116
|
+
```javascript
|
|
117
|
+
workflowTemplates: [{
|
|
118
|
+
fields: { // ✅ CORRECT - Object
|
|
119
|
+
_1000: { label: "Title", type: "text" }
|
|
120
|
+
},
|
|
121
|
+
phases: { // ✅ CORRECT - Object
|
|
122
|
+
_2000: { name: "To Do", isInitial: true }
|
|
123
|
+
}
|
|
124
|
+
}]
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 4. Missing Required Wrapper
|
|
128
|
+
|
|
129
|
+
**❌ DON'T pass fields directly:**
|
|
130
|
+
```javascript
|
|
131
|
+
install_workflow({
|
|
132
|
+
name: "My Workflow", // ❌ WRONG - Missing workflowTemplates wrapper
|
|
133
|
+
fields: {...}
|
|
134
|
+
})
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**✅ DO use `workflowTemplates` array:**
|
|
138
|
+
```javascript
|
|
139
|
+
install_workflow({
|
|
140
|
+
workflowTemplates: [{ // ✅ CORRECT - Required wrapper
|
|
141
|
+
name: "My Workflow",
|
|
142
|
+
fields: {...}
|
|
143
|
+
}]
|
|
144
|
+
})
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 5. Field Property Summary
|
|
148
|
+
|
|
149
|
+
**Only these properties are allowed in field definitions:**
|
|
150
|
+
- ✅ `label` (required) - Display name
|
|
151
|
+
- ✅ `type` (required) - Field type (text, date, etc.)
|
|
152
|
+
- ✅ `key` (optional but recommended) - API key name
|
|
153
|
+
- ✅ `data` (for activitylink, textpredefinedoptions) - Options or links
|
|
154
|
+
- ✅ `required` (optional) - Boolean for required fields
|
|
155
|
+
- ✅ `placeholder` (optional) - Placeholder text
|
|
156
|
+
- ✅ `unit` (for numeric/text with units) - Unit string
|
|
157
|
+
- ❌ `name` - NOT ALLOWED (API will reject)
|
|
158
|
+
- ❌ `options` - NOT ALLOWED (use `data` instead)
|
|
159
|
+
|
|
160
|
+
### 6. 🚨 CRITICAL: Phase IDs Must Be Unique Across ALL Workflows
|
|
161
|
+
|
|
162
|
+
**⚠️ THIS IS THE #1 CAUSE OF DATA CORRUPTION ⚠️**
|
|
163
|
+
|
|
164
|
+
When installing multiple workflows in a single call, **each workflow MUST use unique phase IDs**. Reusing phase IDs across workflows causes them to **share the same phases**, resulting in activities appearing in multiple workflows.
|
|
165
|
+
|
|
166
|
+
**❌ WRONG - Workflows share phase IDs (causes data corruption):**
|
|
167
|
+
```javascript
|
|
168
|
+
install_workflow({
|
|
169
|
+
workflowTemplates: [
|
|
170
|
+
{
|
|
171
|
+
_id: '_0001',
|
|
172
|
+
name: 'Teams',
|
|
173
|
+
phases: {
|
|
174
|
+
_2000: { name: 'Active', isInitial: true } // ❌ Uses _2000
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
_id: '_0002',
|
|
179
|
+
name: 'Players',
|
|
180
|
+
phases: {
|
|
181
|
+
_2000: { name: 'Active Squad', isInitial: true } // ❌ REUSES _2000!
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
})
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Result:** Both workflows share phase `_2000` → Activities created in Teams appear in Players and vice versa!
|
|
189
|
+
|
|
190
|
+
**✅ CORRECT - Each workflow has unique phase IDs:**
|
|
191
|
+
```javascript
|
|
192
|
+
install_workflow({
|
|
193
|
+
workflowTemplates: [
|
|
194
|
+
{
|
|
195
|
+
_id: '_0001',
|
|
196
|
+
name: 'Teams',
|
|
197
|
+
phases: {
|
|
198
|
+
_2000: { name: 'Active', isInitial: true } // ✅ Teams: _2000
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
_id: '_0002',
|
|
203
|
+
name: 'Players',
|
|
204
|
+
phases: {
|
|
205
|
+
_2001: { name: 'Active Squad', isInitial: true }, // ✅ Players: _2001-2004
|
|
206
|
+
_2002: { name: 'On Loan' },
|
|
207
|
+
_2003: { name: 'Injured' },
|
|
208
|
+
_2004: { name: 'Inactive' }
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
_id: '_0003',
|
|
213
|
+
name: 'Matches',
|
|
214
|
+
phases: {
|
|
215
|
+
_2005: { name: 'Scheduled', isInitial: true }, // ✅ Matches: _2005-2007
|
|
216
|
+
_2006: { name: 'Completed' },
|
|
217
|
+
_2007: { name: 'Cancelled' }
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
})
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Phase ID Allocation Strategy:**
|
|
225
|
+
- Workflow 1: `_2000` - `_2009` (reserve 10 IDs)
|
|
226
|
+
- Workflow 2: `_2010` - `_2019` (reserve 10 IDs)
|
|
227
|
+
- Workflow 3: `_2020` - `_2029` (reserve 10 IDs)
|
|
228
|
+
- etc.
|
|
229
|
+
|
|
230
|
+
**Why this happens:**
|
|
231
|
+
- Template phase IDs (_2000, _2001, etc.) are used to generate real phase IDs
|
|
232
|
+
- If two workflows use the same template phase ID, the API creates ONE real phase ID
|
|
233
|
+
- Both workflows then reference the same physical phase in the database
|
|
234
|
+
- Activities in that phase appear in BOTH workflows
|
|
235
|
+
|
|
236
|
+
**How to detect:**
|
|
237
|
+
```javascript
|
|
238
|
+
// If two workflows return the same phase ID, they're sharing phases!
|
|
239
|
+
list_workflow_phases({ workflowId: 'teams-id' }) // Returns: _2000 → 691f2e1aec05d1dc1dafbee6
|
|
240
|
+
list_workflow_phases({ workflowId: 'players-id' }) // Returns: _2000 → 691f2e1aec05d1dc1dafbee6 ❌ SAME ID!
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**How to fix:**
|
|
244
|
+
1. Remove corrupted workflows: `remove_workflow({ workflowId: 'xxx' })`
|
|
245
|
+
2. Reinstall with unique phase IDs as shown above
|
|
246
|
+
3. Verify with `list_workflow_phases` for each workflow
|
|
247
|
+
|
|
248
|
+
## Overview
|
|
249
|
+
|
|
250
|
+
**Think of workflows as database tables:**
|
|
251
|
+
- **Workflows** = Database tables
|
|
252
|
+
- **Fields** = Columns
|
|
253
|
+
- **Activities** = Rows
|
|
254
|
+
- **ActivityLinks** = Foreign keys
|
|
255
|
+
- **Phases** = Status/state columns
|
|
256
|
+
|
|
257
|
+
Workflows define the structure for your data in Hailer. Once installed, you can create activities (records) within these workflows using the `create_activity` tool.
|
|
258
|
+
|
|
259
|
+
## Core Concepts
|
|
260
|
+
|
|
261
|
+
### Workflow Structure
|
|
262
|
+
|
|
263
|
+
A workflow consists of:
|
|
264
|
+
|
|
265
|
+
1. **Workflow Definition**: Name, description, and template ID
|
|
266
|
+
2. **Fields**: Define what data each activity can hold
|
|
267
|
+
3. **Phases**: Define the lifecycle states of activities
|
|
268
|
+
4. **Field Order**: Controls display order (auto-generated if omitted)
|
|
269
|
+
5. **Phase Order**: Controls phase sequence (auto-generated if omitted)
|
|
270
|
+
|
|
271
|
+
### Template IDs vs Real IDs
|
|
272
|
+
|
|
273
|
+
When you install workflows, you use **template IDs** (like `_0001`, `_1000`) to reference workflows and fields. The API returns **real IDs** (like `68446dc05b30685f67c6fcd4`) which you use for subsequent operations.
|
|
274
|
+
|
|
275
|
+
**Example mapping:**
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"_0001": "68446dc05b30685f67c6fcd4", // Workflow ID
|
|
279
|
+
"_1000": "6901ebb64fd57ff171f43338", // Field ID
|
|
280
|
+
"_1001": "6901ebb64fd57ff171f43339" // Field ID
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Use real IDs when:
|
|
285
|
+
- Creating activities: `create_activity({ workflowId: "68446dc05b30685f67c6fcd4", ... })`
|
|
286
|
+
- Listing activities: `list_activities({ workflowId: "68446dc05b30685f67c6fcd4" })`
|
|
287
|
+
- Setting field values: `fields: { "6901ebb64fd57ff171f43338": "value" }`
|
|
288
|
+
|
|
289
|
+
### The `key` Field
|
|
290
|
+
|
|
291
|
+
The `key` field provides readable names for fields in API responses when using `returnFlat: true`:
|
|
292
|
+
|
|
293
|
+
**Without key:**
|
|
294
|
+
```javascript
|
|
295
|
+
fields: {
|
|
296
|
+
"6901ebb64fd57ff171f43338": "My Task Title",
|
|
297
|
+
"6901ebb64fd57ff171f43339": "High"
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**With key:**
|
|
302
|
+
```javascript
|
|
303
|
+
fields: {
|
|
304
|
+
"title": "My Task Title",
|
|
305
|
+
"priority": "High"
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Always set keys** for better API ergonomics.
|
|
310
|
+
|
|
311
|
+
## Field Types Reference
|
|
312
|
+
|
|
313
|
+
### Text Fields
|
|
314
|
+
|
|
315
|
+
**text** - Single-line text input
|
|
316
|
+
```javascript
|
|
317
|
+
{ label: 'Title', type: 'text', key: 'title', required: true }
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**textarea** - Multi-line text input
|
|
321
|
+
```javascript
|
|
322
|
+
{ label: 'Description', type: 'textarea', key: 'description' }
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**textunit** - Text with unit (e.g., "5 kg", "10 meters")
|
|
326
|
+
```javascript
|
|
327
|
+
{ label: 'Weight', type: 'textunit', key: 'weight', unit: 'kg' }
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**textpredefinedoptions** - Dropdown/select with predefined options
|
|
331
|
+
```javascript
|
|
332
|
+
{
|
|
333
|
+
label: 'Priority',
|
|
334
|
+
type: 'textpredefinedoptions',
|
|
335
|
+
key: 'priority',
|
|
336
|
+
data: ['Low', 'Medium', 'High']
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Numeric Fields
|
|
341
|
+
|
|
342
|
+
**numeric** - Number input
|
|
343
|
+
```javascript
|
|
344
|
+
{ label: 'Quantity', type: 'numeric', key: 'quantity' }
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**numericunit** - Number with unit
|
|
348
|
+
```javascript
|
|
349
|
+
{ label: 'Distance', type: 'numericunit', key: 'distance', unit: 'km' }
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Date/Time Fields
|
|
353
|
+
|
|
354
|
+
**date** - Date picker
|
|
355
|
+
```javascript
|
|
356
|
+
{ label: 'Due Date', type: 'date', key: 'dueDate' }
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**time** - Time picker
|
|
360
|
+
```javascript
|
|
361
|
+
{ label: 'Start Time', type: 'time', key: 'startTime' }
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**datetime** - Date and time picker
|
|
365
|
+
```javascript
|
|
366
|
+
{ label: 'Created At', type: 'datetime', key: 'createdAt' }
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**daterange** - Start and end dates
|
|
370
|
+
```javascript
|
|
371
|
+
{ label: 'Project Duration', type: 'daterange', key: 'duration' }
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
**timerange** - Start and end times
|
|
375
|
+
```javascript
|
|
376
|
+
{ label: 'Working Hours', type: 'timerange', key: 'hours' }
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**datetimerange** - Start and end date/times
|
|
380
|
+
```javascript
|
|
381
|
+
{ label: 'Event Period', type: 'datetimerange', key: 'eventPeriod' }
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Relation Fields
|
|
385
|
+
|
|
386
|
+
**activitylink** - Link to other workflow activities (foreign key)
|
|
387
|
+
```javascript
|
|
388
|
+
{
|
|
389
|
+
label: 'Project',
|
|
390
|
+
type: 'activitylink',
|
|
391
|
+
key: 'project',
|
|
392
|
+
data: ['_0001'] // Links to workflow _0001
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**teams** - Select team from workspace
|
|
397
|
+
```javascript
|
|
398
|
+
{ label: 'Owner Team', type: 'teams', key: 'ownerTeam' }
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
**users** - Select user from workspace
|
|
402
|
+
```javascript
|
|
403
|
+
{ label: 'Assigned To', type: 'users', key: 'assignedTo' }
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Layout Fields
|
|
407
|
+
|
|
408
|
+
**subheader** - Group fields into collapsible sections
|
|
409
|
+
```javascript
|
|
410
|
+
{ label: 'Contact Information', type: 'subheader' }
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Other Fields
|
|
414
|
+
|
|
415
|
+
**country** - Country selector
|
|
416
|
+
```javascript
|
|
417
|
+
{ label: 'Country', type: 'country', key: 'country' }
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## ID Patterns and Naming
|
|
421
|
+
|
|
422
|
+
### Pattern Rules
|
|
423
|
+
|
|
424
|
+
All IDs must follow: **underscore + 4 digits**
|
|
425
|
+
|
|
426
|
+
**Workflow IDs:**
|
|
427
|
+
- Start from `_0001`
|
|
428
|
+
- Increment: `_0002`, `_0003`, etc.
|
|
429
|
+
- Used in activitylink `data` field to reference workflows
|
|
430
|
+
|
|
431
|
+
**Field IDs:**
|
|
432
|
+
- Start from `_1000`
|
|
433
|
+
- Increment: `_1001`, `_1002`, etc.
|
|
434
|
+
- No gaps required - can skip numbers
|
|
435
|
+
|
|
436
|
+
**Phase IDs:**
|
|
437
|
+
- Start from `_2000`
|
|
438
|
+
- Increment: `_2001`, `_2002`, etc.
|
|
439
|
+
- At least one phase with `isInitial: true` required
|
|
440
|
+
|
|
441
|
+
### Key Naming Conventions
|
|
442
|
+
|
|
443
|
+
Use camelCase for keys:
|
|
444
|
+
- `title`, `description`, `projectName`
|
|
445
|
+
- `startDate`, `endDate`, `dueDate`
|
|
446
|
+
- `assignedTo`, `ownedBy`, `relatedTo`
|
|
447
|
+
- `priority`, `status`, `category`
|
|
448
|
+
|
|
449
|
+
## Basic Examples
|
|
450
|
+
|
|
451
|
+
### Example 1: Simple Task List
|
|
452
|
+
|
|
453
|
+
```javascript
|
|
454
|
+
install_workflow({
|
|
455
|
+
workflowTemplates: [{
|
|
456
|
+
_id: '_0001',
|
|
457
|
+
name: 'Tasks',
|
|
458
|
+
description: 'Simple task tracking',
|
|
459
|
+
fields: {
|
|
460
|
+
_1000: {
|
|
461
|
+
label: 'Title',
|
|
462
|
+
type: 'text',
|
|
463
|
+
key: 'title',
|
|
464
|
+
required: true,
|
|
465
|
+
placeholder: 'Enter task title'
|
|
466
|
+
},
|
|
467
|
+
_1001: {
|
|
468
|
+
label: 'Priority',
|
|
469
|
+
type: 'textpredefinedoptions',
|
|
470
|
+
key: 'priority',
|
|
471
|
+
data: ['Low', 'Medium', 'High']
|
|
472
|
+
},
|
|
473
|
+
_1002: {
|
|
474
|
+
label: 'Due Date',
|
|
475
|
+
type: 'date',
|
|
476
|
+
key: 'dueDate'
|
|
477
|
+
},
|
|
478
|
+
_1003: {
|
|
479
|
+
label: 'Description',
|
|
480
|
+
type: 'textarea',
|
|
481
|
+
key: 'description'
|
|
482
|
+
}
|
|
483
|
+
},
|
|
484
|
+
phases: {
|
|
485
|
+
_2000: { name: 'To Do', isInitial: true },
|
|
486
|
+
_2001: { name: 'In Progress' },
|
|
487
|
+
_2002: { name: 'Done' }
|
|
488
|
+
}
|
|
489
|
+
}]
|
|
490
|
+
})
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Example 2: Customer Database
|
|
494
|
+
|
|
495
|
+
```javascript
|
|
496
|
+
install_workflow({
|
|
497
|
+
workflowTemplates: [{
|
|
498
|
+
_id: '_0001',
|
|
499
|
+
name: 'Customers',
|
|
500
|
+
fields: {
|
|
501
|
+
_1000: { label: 'Company Name', type: 'text', key: 'companyName', required: true },
|
|
502
|
+
_1001: { label: 'Contact Person', type: 'text', key: 'contactPerson' },
|
|
503
|
+
_1002: { label: 'Email', type: 'text', key: 'email' },
|
|
504
|
+
_1003: { label: 'Phone', type: 'text', key: 'phone' },
|
|
505
|
+
_1004: { label: 'Country', type: 'country', key: 'country' },
|
|
506
|
+
_1005: { label: 'Status', type: 'textpredefinedoptions', key: 'status',
|
|
507
|
+
data: ['Lead', 'Active', 'Inactive'] }
|
|
508
|
+
},
|
|
509
|
+
phases: {
|
|
510
|
+
_2000: { name: 'Active', isInitial: true }
|
|
511
|
+
}
|
|
512
|
+
}]
|
|
513
|
+
})
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### Example 3: Using Subheaders for Organization
|
|
517
|
+
|
|
518
|
+
```javascript
|
|
519
|
+
install_workflow({
|
|
520
|
+
workflowTemplates: [{
|
|
521
|
+
_id: '_0001',
|
|
522
|
+
name: 'Contacts',
|
|
523
|
+
fields: {
|
|
524
|
+
// Basic Info Section
|
|
525
|
+
_1000: { label: 'Basic Information', type: 'subheader' },
|
|
526
|
+
_1001: { label: 'Full Name', type: 'text', key: 'fullName', required: true },
|
|
527
|
+
_1002: { label: 'Company', type: 'text', key: 'company' },
|
|
528
|
+
_1003: { label: 'Position', type: 'text', key: 'position' },
|
|
529
|
+
|
|
530
|
+
// Contact Details Section
|
|
531
|
+
_1004: { label: 'Contact Details', type: 'subheader' },
|
|
532
|
+
_1005: { label: 'Email', type: 'text', key: 'email' },
|
|
533
|
+
_1006: { label: 'Phone', type: 'text', key: 'phone' },
|
|
534
|
+
|
|
535
|
+
// Address Section
|
|
536
|
+
_1007: { label: 'Address', type: 'subheader' },
|
|
537
|
+
_1008: { label: 'Street', type: 'text', key: 'street' },
|
|
538
|
+
_1009: { label: 'City', type: 'text', key: 'city' },
|
|
539
|
+
_1010: { label: 'Country', type: 'country', key: 'country' }
|
|
540
|
+
},
|
|
541
|
+
phases: {
|
|
542
|
+
_2000: { name: 'Active', isInitial: true }
|
|
543
|
+
}
|
|
544
|
+
}]
|
|
545
|
+
})
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
## Advanced Patterns
|
|
549
|
+
|
|
550
|
+
### Date Range Tracking
|
|
551
|
+
|
|
552
|
+
```javascript
|
|
553
|
+
{
|
|
554
|
+
workflowTemplates: [{
|
|
555
|
+
_id: '_0001',
|
|
556
|
+
name: 'Projects',
|
|
557
|
+
fields: {
|
|
558
|
+
_1000: { label: 'Project Name', type: 'text', key: 'projectName', required: true },
|
|
559
|
+
_1001: { label: 'Duration', type: 'daterange', key: 'duration' },
|
|
560
|
+
_1002: { label: 'Budget', type: 'numericunit', key: 'budget', unit: 'USD' },
|
|
561
|
+
_1003: { label: 'Status', type: 'textpredefinedoptions', key: 'status',
|
|
562
|
+
data: ['Planning', 'Active', 'On Hold', 'Completed'] }
|
|
563
|
+
},
|
|
564
|
+
phases: {
|
|
565
|
+
_2000: { name: 'Planning', isInitial: true },
|
|
566
|
+
_2001: { name: 'Execution' },
|
|
567
|
+
_2002: { name: 'Completed' }
|
|
568
|
+
}
|
|
569
|
+
}]
|
|
570
|
+
}
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
### Multiple Predefined Options
|
|
574
|
+
|
|
575
|
+
```javascript
|
|
576
|
+
{
|
|
577
|
+
workflowTemplates: [{
|
|
578
|
+
_id: '_0001',
|
|
579
|
+
name: 'Support Tickets',
|
|
580
|
+
fields: {
|
|
581
|
+
_1000: { label: 'Title', type: 'text', key: 'title', required: true },
|
|
582
|
+
_1001: { label: 'Priority', type: 'textpredefinedoptions', key: 'priority',
|
|
583
|
+
data: ['Low', 'Normal', 'High', 'Urgent'] },
|
|
584
|
+
_1002: { label: 'Category', type: 'textpredefinedoptions', key: 'category',
|
|
585
|
+
data: ['Technical', 'Billing', 'General', 'Bug Report'] },
|
|
586
|
+
_1003: { label: 'Assigned To', type: 'users', key: 'assignedTo' },
|
|
587
|
+
_1004: { label: 'Description', type: 'textarea', key: 'description' }
|
|
588
|
+
},
|
|
589
|
+
phases: {
|
|
590
|
+
_2000: { name: 'Open', isInitial: true },
|
|
591
|
+
_2001: { name: 'In Progress' },
|
|
592
|
+
_2002: { name: 'Resolved' },
|
|
593
|
+
_2003: { name: 'Closed' }
|
|
594
|
+
}
|
|
595
|
+
}]
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
## Relationships Between Workflows
|
|
600
|
+
|
|
601
|
+
### One-to-Many: Projects and Tasks
|
|
602
|
+
|
|
603
|
+
```javascript
|
|
604
|
+
install_workflow({
|
|
605
|
+
workflowTemplates: [
|
|
606
|
+
// Parent workflow: Projects
|
|
607
|
+
{
|
|
608
|
+
_id: '_0001',
|
|
609
|
+
name: 'Projects',
|
|
610
|
+
fields: {
|
|
611
|
+
_1000: { label: 'Project Name', type: 'text', key: 'projectName', required: true },
|
|
612
|
+
_1001: { label: 'Start Date', type: 'date', key: 'startDate' },
|
|
613
|
+
_1002: { label: 'Budget', type: 'numericunit', key: 'budget', unit: 'USD' }
|
|
614
|
+
},
|
|
615
|
+
phases: {
|
|
616
|
+
_2000: { name: 'Active', isInitial: true }
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
|
|
620
|
+
// Child workflow: Tasks (links to Projects)
|
|
621
|
+
{
|
|
622
|
+
_id: '_0002',
|
|
623
|
+
name: 'Tasks',
|
|
624
|
+
fields: {
|
|
625
|
+
_1000: { label: 'Task Title', type: 'text', key: 'title', required: true },
|
|
626
|
+
_1001: {
|
|
627
|
+
label: 'Project',
|
|
628
|
+
type: 'activitylink',
|
|
629
|
+
key: 'project',
|
|
630
|
+
data: ['_0001'] // Links to Projects workflow
|
|
631
|
+
},
|
|
632
|
+
_1002: { label: 'Due Date', type: 'date', key: 'dueDate' },
|
|
633
|
+
_1003: { label: 'Assigned To', type: 'users', key: 'assignedTo' }
|
|
634
|
+
},
|
|
635
|
+
phases: {
|
|
636
|
+
_2001: { name: 'To Do', isInitial: true }, // ✅ Unique phase IDs (_2001-2003)
|
|
637
|
+
_2002: { name: 'In Progress' },
|
|
638
|
+
_2003: { name: 'Done' }
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
]
|
|
642
|
+
})
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
**Usage after installation:**
|
|
646
|
+
```javascript
|
|
647
|
+
// 1. Get real IDs from installation response
|
|
648
|
+
// {
|
|
649
|
+
// "_0001": "project-workflow-real-id",
|
|
650
|
+
// "_0002": "task-workflow-real-id",
|
|
651
|
+
// "_1001": "project-link-field-real-id"
|
|
652
|
+
// }
|
|
653
|
+
|
|
654
|
+
// 2. Create a project
|
|
655
|
+
create_activity({
|
|
656
|
+
workflowId: "project-workflow-real-id",
|
|
657
|
+
name: "Website Redesign",
|
|
658
|
+
fields: { "projectName": "Website Redesign", "budget": "50000" }
|
|
659
|
+
})
|
|
660
|
+
// Returns: { _id: "project-activity-id", ... }
|
|
661
|
+
|
|
662
|
+
// 3. Create tasks linked to project
|
|
663
|
+
create_activity({
|
|
664
|
+
workflowId: "task-workflow-real-id",
|
|
665
|
+
name: "Design mockups",
|
|
666
|
+
fields: {
|
|
667
|
+
"title": "Design mockups",
|
|
668
|
+
"project": "project-activity-id", // Link to project activity
|
|
669
|
+
"dueDate": "2024-12-31"
|
|
670
|
+
}
|
|
671
|
+
})
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### Three-Level Hierarchy: Projects → Topics → Tasks
|
|
675
|
+
|
|
676
|
+
```javascript
|
|
677
|
+
install_workflow({
|
|
678
|
+
workflowTemplates: [
|
|
679
|
+
// Level 1: Projects
|
|
680
|
+
{
|
|
681
|
+
_id: '_0001',
|
|
682
|
+
name: 'Projects',
|
|
683
|
+
fields: {
|
|
684
|
+
_1000: { label: 'Project Name', type: 'text', key: 'projectName', required: true },
|
|
685
|
+
_1001: { label: 'Description', type: 'textarea', key: 'description' }
|
|
686
|
+
},
|
|
687
|
+
phases: {
|
|
688
|
+
_2000: { name: 'Active', isInitial: true }
|
|
689
|
+
}
|
|
690
|
+
},
|
|
691
|
+
|
|
692
|
+
// Level 2: Topics (links to Projects)
|
|
693
|
+
{
|
|
694
|
+
_id: '_0002',
|
|
695
|
+
name: 'Topics',
|
|
696
|
+
fields: {
|
|
697
|
+
_1000: { label: 'Topic Name', type: 'text', key: 'topicName', required: true },
|
|
698
|
+
_1001: {
|
|
699
|
+
label: 'Project',
|
|
700
|
+
type: 'activitylink',
|
|
701
|
+
key: 'project',
|
|
702
|
+
data: ['_0001']
|
|
703
|
+
}
|
|
704
|
+
},
|
|
705
|
+
phases: {
|
|
706
|
+
_2001: { name: 'Active', isInitial: true } // ✅ Unique phase ID (_2001)
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
|
|
710
|
+
// Level 3: Tasks (links to Topics)
|
|
711
|
+
{
|
|
712
|
+
_id: '_0003',
|
|
713
|
+
name: 'Tasks',
|
|
714
|
+
fields: {
|
|
715
|
+
_1000: { label: 'Task Title', type: 'text', key: 'title', required: true },
|
|
716
|
+
_1001: {
|
|
717
|
+
label: 'Topic',
|
|
718
|
+
type: 'activitylink',
|
|
719
|
+
key: 'topic',
|
|
720
|
+
data: ['_0002']
|
|
721
|
+
},
|
|
722
|
+
_1002: { label: 'Priority', type: 'textpredefinedoptions', key: 'priority',
|
|
723
|
+
data: ['Low', 'Medium', 'High'] }
|
|
724
|
+
},
|
|
725
|
+
phases: {
|
|
726
|
+
_2002: { name: 'To Do', isInitial: true }, // ✅ Unique phase IDs (_2002-2003)
|
|
727
|
+
_2003: { name: 'Done' }
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
]
|
|
731
|
+
})
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
### Many-to-Many: Using Multiple ActivityLinks
|
|
735
|
+
|
|
736
|
+
```javascript
|
|
737
|
+
{
|
|
738
|
+
workflowTemplates: [{
|
|
739
|
+
_id: '_0003',
|
|
740
|
+
name: 'Tasks',
|
|
741
|
+
fields: {
|
|
742
|
+
_1000: { label: 'Task Title', type: 'text', key: 'title', required: true },
|
|
743
|
+
_1001: {
|
|
744
|
+
label: 'Related Items',
|
|
745
|
+
type: 'activitylink',
|
|
746
|
+
key: 'relatedItems',
|
|
747
|
+
data: ['_0001', '_0002'] // Can link to Projects OR Topics
|
|
748
|
+
}
|
|
749
|
+
},
|
|
750
|
+
phases: {
|
|
751
|
+
_2004: { name: 'To Do', isInitial: true } // ✅ Use _2004+ (assuming _0001, _0002 used _2000-2003)
|
|
752
|
+
}
|
|
753
|
+
}]
|
|
754
|
+
}
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
## Best Practices
|
|
758
|
+
|
|
759
|
+
### 1. Always Use Keys
|
|
760
|
+
|
|
761
|
+
**Bad:**
|
|
762
|
+
```javascript
|
|
763
|
+
fields: {
|
|
764
|
+
_1000: { label: 'Customer Name', type: 'text' } // No key
|
|
765
|
+
}
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
**Good:**
|
|
769
|
+
```javascript
|
|
770
|
+
fields: {
|
|
771
|
+
_1000: { label: 'Customer Name', type: 'text', key: 'customerName' }
|
|
772
|
+
}
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
### 2. Use Descriptive Names
|
|
776
|
+
|
|
777
|
+
**Bad:**
|
|
778
|
+
```javascript
|
|
779
|
+
{ label: 'Name', type: 'text', key: 'name' } // Ambiguous
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
**Good:**
|
|
783
|
+
```javascript
|
|
784
|
+
{ label: 'Customer Name', type: 'text', key: 'customerName' } // Clear
|
|
785
|
+
{ label: 'Project Name', type: 'text', key: 'projectName' } // Clear
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
### 3. Set Required Fields Appropriately
|
|
789
|
+
|
|
790
|
+
```javascript
|
|
791
|
+
fields: {
|
|
792
|
+
_1000: { label: 'Title', type: 'text', key: 'title', required: true }, // Essential
|
|
793
|
+
_1001: { label: 'Description', type: 'textarea', key: 'description' } // Optional
|
|
794
|
+
}
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
### 4. Use Subheaders for Long Forms
|
|
798
|
+
|
|
799
|
+
For workflows with many fields (>5), organize with subheaders:
|
|
800
|
+
|
|
801
|
+
```javascript
|
|
802
|
+
fields: {
|
|
803
|
+
_1000: { label: 'Basic Info', type: 'subheader' },
|
|
804
|
+
_1001: { label: 'Name', type: 'text', key: 'name' },
|
|
805
|
+
_1002: { label: 'Email', type: 'text', key: 'email' },
|
|
806
|
+
|
|
807
|
+
_1003: { label: 'Additional Details', type: 'subheader' },
|
|
808
|
+
_1004: { label: 'Notes', type: 'textarea', key: 'notes' }
|
|
809
|
+
}
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
### 5. Choose Appropriate Field Types
|
|
813
|
+
|
|
814
|
+
**For limited options:** Use `textpredefinedoptions`
|
|
815
|
+
```javascript
|
|
816
|
+
{ label: 'Status', type: 'textpredefinedoptions', key: 'status',
|
|
817
|
+
data: ['Draft', 'Review', 'Published'] }
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
**For measurements:** Use numeric fields with units
|
|
821
|
+
```javascript
|
|
822
|
+
{ label: 'Weight', type: 'numericunit', key: 'weight', unit: 'kg' }
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
**For relationships:** Use activitylink with clear labels
|
|
826
|
+
```javascript
|
|
827
|
+
{ label: 'Parent Project', type: 'activitylink', key: 'parentProject', data: ['_0001'] }
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
### 6. Phase Design
|
|
831
|
+
|
|
832
|
+
**Minimum viable:**
|
|
833
|
+
```javascript
|
|
834
|
+
phases: {
|
|
835
|
+
_2000: { name: 'Active', isInitial: true }
|
|
836
|
+
}
|
|
837
|
+
```
|
|
838
|
+
|
|
839
|
+
**Status workflow:**
|
|
840
|
+
```javascript
|
|
841
|
+
phases: {
|
|
842
|
+
_2000: { name: 'To Do', isInitial: true },
|
|
843
|
+
_2001: { name: 'In Progress' },
|
|
844
|
+
_2002: { name: 'Done' }
|
|
845
|
+
}
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
**Approval workflow:**
|
|
849
|
+
```javascript
|
|
850
|
+
phases: {
|
|
851
|
+
_2000: { name: 'Draft', isInitial: true },
|
|
852
|
+
_2001: { name: 'Pending Review' },
|
|
853
|
+
_2002: { name: 'Approved' },
|
|
854
|
+
_2003: { name: 'Rejected' }
|
|
855
|
+
}
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
### 7. Install Related Workflows Together
|
|
859
|
+
|
|
860
|
+
When workflows reference each other via activitylink, install them in a single call:
|
|
861
|
+
|
|
862
|
+
**Good:**
|
|
863
|
+
```javascript
|
|
864
|
+
install_workflow({
|
|
865
|
+
workflowTemplates: [
|
|
866
|
+
{ _id: '_0001', name: 'Projects', ... },
|
|
867
|
+
{ _id: '_0002', name: 'Tasks', fields: {
|
|
868
|
+
_1001: { type: 'activitylink', data: ['_0001'] } // References _0001
|
|
869
|
+
}}
|
|
870
|
+
]
|
|
871
|
+
})
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
**Bad:**
|
|
875
|
+
```javascript
|
|
876
|
+
// First call
|
|
877
|
+
install_workflow({ workflowTemplates: [{ _id: '_0001', name: 'Projects' }] })
|
|
878
|
+
// Second call - must use real ID from first call
|
|
879
|
+
install_workflow({ workflowTemplates: [{ _id: '_0002', name: 'Tasks',
|
|
880
|
+
fields: { _1001: { type: 'activitylink', data: ['real-id-from-first-call'] }}}]})
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
## Troubleshooting
|
|
884
|
+
|
|
885
|
+
### Error: "Permission Denied"
|
|
886
|
+
|
|
887
|
+
**Problem:** User must be workspace administrator.
|
|
888
|
+
|
|
889
|
+
**Solution:**
|
|
890
|
+
- Contact workspace admin to grant permissions
|
|
891
|
+
- Verify you're logged in with correct account
|
|
892
|
+
- Check `get_current_workspace` to confirm permissions
|
|
893
|
+
|
|
894
|
+
### Error: "Workflow _id must match pattern _0001"
|
|
895
|
+
|
|
896
|
+
**Problem:** Invalid workflow ID format.
|
|
897
|
+
|
|
898
|
+
**Solution:**
|
|
899
|
+
- Use pattern: `_0001`, `_0002`, `_0003` (underscore + 4 digits)
|
|
900
|
+
- Must start with underscore
|
|
901
|
+
- Must be exactly 4 digits
|
|
902
|
+
|
|
903
|
+
### Error: "Field IDs must match pattern _1000"
|
|
904
|
+
|
|
905
|
+
**Problem:** Invalid field ID format.
|
|
906
|
+
|
|
907
|
+
**Solution:**
|
|
908
|
+
- Use pattern: `_1000`, `_1001`, `_1002` (underscore + 4 digits)
|
|
909
|
+
- Start from `_1000` or higher
|
|
910
|
+
- Can skip numbers (e.g., `_1000`, `_1005`, `_1010`)
|
|
911
|
+
|
|
912
|
+
### Error: "Phase IDs must match pattern _2000"
|
|
913
|
+
|
|
914
|
+
**Problem:** Invalid phase ID format.
|
|
915
|
+
|
|
916
|
+
**Solution:**
|
|
917
|
+
- Use pattern: `_2000`, `_2001`, `_2002` (underscore + 4 digits)
|
|
918
|
+
- Start from `_2000` or higher
|
|
919
|
+
|
|
920
|
+
### Error: "At least one phase with isInitial: true required"
|
|
921
|
+
|
|
922
|
+
**Problem:** No initial phase defined.
|
|
923
|
+
|
|
924
|
+
**Solution:**
|
|
925
|
+
```javascript
|
|
926
|
+
phases: {
|
|
927
|
+
_2000: { name: 'Active', isInitial: true } // Must have isInitial: true
|
|
928
|
+
}
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
### Installation Succeeds But Can't Find Workflow
|
|
932
|
+
|
|
933
|
+
**Problem:** Need to use real IDs, not template IDs.
|
|
934
|
+
|
|
935
|
+
**Solution:**
|
|
936
|
+
1. Installation returns mapping:
|
|
937
|
+
```json
|
|
938
|
+
{ "_0001": "68446dc05b30685f67c6fcd4" }
|
|
939
|
+
```
|
|
940
|
+
2. Use real ID in subsequent calls:
|
|
941
|
+
```javascript
|
|
942
|
+
list_activities({ workflowId: "68446dc05b30685f67c6fcd4" })
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
### ActivityLink Not Working
|
|
946
|
+
|
|
947
|
+
**Problem:** Wrong workflow ID in `data` field.
|
|
948
|
+
|
|
949
|
+
**Solution:**
|
|
950
|
+
|
|
951
|
+
**During installation** (use template ID):
|
|
952
|
+
```javascript
|
|
953
|
+
{
|
|
954
|
+
_id: '_0002',
|
|
955
|
+
fields: {
|
|
956
|
+
_1001: { type: 'activitylink', data: ['_0001'] } // Template ID
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
**After installation** (when updating field):
|
|
962
|
+
```javascript
|
|
963
|
+
update_workflow_field({
|
|
964
|
+
workflowId: "real-workflow-id",
|
|
965
|
+
fieldId: "real-field-id",
|
|
966
|
+
fieldData: {
|
|
967
|
+
data: ["target-real-workflow-id"] // Real ID
|
|
968
|
+
}
|
|
969
|
+
})
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
### Fields Not Showing in Expected Order
|
|
973
|
+
|
|
974
|
+
**Problem:** Field order not specified.
|
|
975
|
+
|
|
976
|
+
**Solution:**
|
|
977
|
+
```javascript
|
|
978
|
+
{
|
|
979
|
+
fields: { _1000: {...}, _1005: {...}, _1002: {...} },
|
|
980
|
+
fieldsOrder: ['_1000', '_1002', '_1005'] // Explicit order
|
|
981
|
+
}
|
|
982
|
+
```
|
|
983
|
+
|
|
984
|
+
### Can't Create Activities in Phase
|
|
985
|
+
|
|
986
|
+
**Problem:** Phase doesn't have `isInitial: true`.
|
|
987
|
+
|
|
988
|
+
**Solution:** At least one phase must have `isInitial: true`. Activities can only be created in initial phases:
|
|
989
|
+
```javascript
|
|
990
|
+
phases: {
|
|
991
|
+
_2000: { name: 'New', isInitial: true }, // Can create activities here
|
|
992
|
+
_2001: { name: 'Done' } // Can't create, only move here
|
|
993
|
+
}
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
## Integration with Other Tools
|
|
997
|
+
|
|
998
|
+
### After Installation: Create Activities
|
|
999
|
+
|
|
1000
|
+
```javascript
|
|
1001
|
+
// 1. Install workflow
|
|
1002
|
+
const result = install_workflow({...});
|
|
1003
|
+
// Returns: { "_0001": "workflow-real-id", "_1000": "field-real-id" }
|
|
1004
|
+
|
|
1005
|
+
// 2. Create activity
|
|
1006
|
+
create_activity({
|
|
1007
|
+
workflowId: "workflow-real-id",
|
|
1008
|
+
name: "Activity Name",
|
|
1009
|
+
fields: {
|
|
1010
|
+
"field-real-id": "value"
|
|
1011
|
+
}
|
|
1012
|
+
})
|
|
1013
|
+
```
|
|
1014
|
+
|
|
1015
|
+
### Use with Insights
|
|
1016
|
+
|
|
1017
|
+
After installing workflows, create insights (SQL reports) over the data:
|
|
1018
|
+
|
|
1019
|
+
```javascript
|
|
1020
|
+
create_insight({
|
|
1021
|
+
name: 'Task Report',
|
|
1022
|
+
sources: [{
|
|
1023
|
+
name: 'tasks',
|
|
1024
|
+
workflowId: 'workflow-real-id',
|
|
1025
|
+
fields: [
|
|
1026
|
+
{ name: 'title', meta: 'name' },
|
|
1027
|
+
{ name: 'dueDate', fieldId: 'field-real-id' }
|
|
1028
|
+
]
|
|
1029
|
+
}],
|
|
1030
|
+
query: 'SELECT title, dueDate FROM tasks WHERE dueDate > "2024-01-01"'
|
|
1031
|
+
})
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
### Update Fields Later
|
|
1035
|
+
|
|
1036
|
+
Use `update_workflow_field` to modify field properties after installation:
|
|
1037
|
+
|
|
1038
|
+
```javascript
|
|
1039
|
+
update_workflow_field({
|
|
1040
|
+
workflowId: "workflow-real-id",
|
|
1041
|
+
fieldId: "field-real-id",
|
|
1042
|
+
fieldData: {
|
|
1043
|
+
label: "New Label",
|
|
1044
|
+
key: "newKey",
|
|
1045
|
+
data: ["updated-options"]
|
|
1046
|
+
}
|
|
1047
|
+
})
|
|
1048
|
+
```
|
|
1049
|
+
|
|
1050
|
+
## Additional Resources
|
|
1051
|
+
|
|
1052
|
+
- Use `list_workflows` to view installed workflows
|
|
1053
|
+
- Use `get_workflow_schema` to inspect workflow structure
|
|
1054
|
+
- Use `list_workflow_phases` to view available phases
|
|
1055
|
+
- See `hailer-api` skill for comprehensive API documentation
|
|
1056
|
+
- See `mcp-tools` skill for implementation patterns
|