@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.
Files changed (271) hide show
  1. package/CHANGELOG.md +0 -7
  2. package/{.claude → dist}/CLAUDE.md +2 -2
  3. package/dist/app.js +18 -5
  4. package/dist/bot/bot-config.d.ts +10 -1
  5. package/dist/bot/bot-config.js +64 -3
  6. package/dist/bot/bot-manager.d.ts +2 -0
  7. package/dist/bot/bot-manager.js +9 -2
  8. package/dist/bot/bot.d.ts +33 -0
  9. package/dist/bot/bot.js +461 -160
  10. package/dist/bot/services/message-classifier.js +17 -0
  11. package/dist/bot/services/permission-guard.d.ts +52 -0
  12. package/dist/bot/services/permission-guard.js +149 -0
  13. package/dist/bot/services/types.d.ts +5 -0
  14. package/dist/bot/services/typing-indicator.d.ts +6 -1
  15. package/dist/bot/services/typing-indicator.js +19 -3
  16. package/dist/cli.js +0 -0
  17. package/dist/config.d.ts +6 -1
  18. package/dist/config.js +43 -0
  19. package/dist/core.js +3 -6
  20. package/dist/lib/discussion-lock.d.ts +42 -0
  21. package/dist/lib/discussion-lock.js +110 -0
  22. package/dist/mcp/UserContextCache.d.ts +5 -0
  23. package/dist/mcp/UserContextCache.js +51 -19
  24. package/dist/mcp/hailer-clients.d.ts +19 -1
  25. package/dist/mcp/hailer-clients.js +158 -24
  26. package/dist/mcp/session-store.d.ts +68 -0
  27. package/dist/mcp/session-store.js +169 -0
  28. package/dist/mcp/signal-handler.js +2 -0
  29. package/dist/mcp/tool-registry.d.ts +17 -4
  30. package/dist/mcp/tool-registry.js +37 -7
  31. package/dist/mcp/tools/activity.js +99 -7
  32. package/dist/mcp/tools/app-scaffold.js +304 -336
  33. package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
  34. package/dist/mcp/tools/bot-config/constants.js +94 -0
  35. package/dist/mcp/tools/bot-config/core.d.ts +253 -0
  36. package/dist/mcp/tools/bot-config/core.js +2456 -0
  37. package/dist/mcp/tools/bot-config/index.d.ts +10 -0
  38. package/dist/mcp/tools/bot-config/index.js +59 -0
  39. package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
  40. package/dist/mcp/tools/bot-config/tools.js +15 -0
  41. package/dist/mcp/tools/bot-config/types.d.ts +50 -0
  42. package/dist/mcp/tools/bot-config/types.js +6 -0
  43. package/dist/mcp/tools/bug-fixer-tools.d.ts +45 -0
  44. package/dist/mcp/tools/bug-fixer-tools.js +1096 -0
  45. package/dist/mcp/tools/company.d.ts +9 -0
  46. package/dist/mcp/tools/company.js +88 -0
  47. package/dist/mcp/tools/discussion.js +68 -0
  48. package/dist/mcp/tools/document.d.ts +11 -0
  49. package/dist/mcp/tools/document.js +741 -0
  50. package/dist/mcp/tools/investigate.d.ts +9 -0
  51. package/dist/mcp/tools/investigate.js +254 -0
  52. package/dist/mcp/tools/workflow-permissions.d.ts +15 -0
  53. package/dist/mcp/tools/workflow-permissions.js +204 -0
  54. package/dist/mcp/tools/workflow.js +57 -18
  55. package/dist/mcp/utils/index.d.ts +2 -0
  56. package/dist/mcp/utils/index.js +12 -1
  57. package/dist/mcp/utils/role-utils.d.ts +74 -0
  58. package/dist/mcp/utils/role-utils.js +151 -0
  59. package/dist/mcp/utils/types.d.ts +43 -1
  60. package/dist/mcp/utils/types.js +14 -0
  61. package/dist/mcp/webhook-handler.d.ts +4 -0
  62. package/dist/mcp/webhook-handler.js +8 -0
  63. package/dist/mcp-server.d.ts +23 -2
  64. package/dist/mcp-server.js +639 -127
  65. package/dist/plugins/vipunen/client.d.ts +150 -0
  66. package/dist/plugins/vipunen/client.js +535 -0
  67. package/dist/plugins/vipunen/config/schema-config.json +19 -0
  68. package/dist/plugins/vipunen/config/schema-doc.json +22 -0
  69. package/dist/plugins/vipunen/index.d.ts +41 -0
  70. package/dist/plugins/vipunen/index.js +88 -0
  71. package/dist/plugins/vipunen/tools.d.ts +26 -0
  72. package/dist/plugins/vipunen/tools.js +501 -0
  73. package/dist/stdio-server.d.ts +14 -0
  74. package/dist/stdio-server.js +101 -0
  75. package/package.json +2 -1
  76. package/.claude/agents/agent-ada-skill-builder.md +0 -94
  77. package/.claude/agents/agent-alejandro-function-fields.md +0 -342
  78. package/.claude/agents/agent-bjorn-config-audit.md +0 -103
  79. package/.claude/agents/agent-builder-agent-creator.md +0 -130
  80. package/.claude/agents/agent-code-simplifier.md +0 -53
  81. package/.claude/agents/agent-dmitri-activity-crud.md +0 -159
  82. package/.claude/agents/agent-giuseppe-app-builder.md +0 -247
  83. package/.claude/agents/agent-gunther-mcp-tools.md +0 -39
  84. package/.claude/agents/agent-helga-workflow-config.md +0 -204
  85. package/.claude/agents/agent-igor-activity-mover-automation.md +0 -125
  86. package/.claude/agents/agent-ingrid-doc-templates.md +0 -261
  87. package/.claude/agents/agent-ivan-monolith.md +0 -154
  88. package/.claude/agents/agent-kenji-data-reader.md +0 -86
  89. package/.claude/agents/agent-lars-code-inspector.md +0 -102
  90. package/.claude/agents/agent-marco-mockup-builder.md +0 -110
  91. package/.claude/agents/agent-marcus-api-documenter.md +0 -323
  92. package/.claude/agents/agent-marketplace-publisher.md +0 -280
  93. package/.claude/agents/agent-marketplace-reviewer.md +0 -309
  94. package/.claude/agents/agent-permissions-handler.md +0 -208
  95. package/.claude/agents/agent-simple-writer.md +0 -48
  96. package/.claude/agents/agent-svetlana-code-review.md +0 -171
  97. package/.claude/agents/agent-tanya-test-runner.md +0 -333
  98. package/.claude/agents/agent-ui-designer.md +0 -100
  99. package/.claude/agents/agent-viktor-sql-insights.md +0 -212
  100. package/.claude/agents/agent-web-search.md +0 -55
  101. package/.claude/agents/agent-yevgeni-discussions.md +0 -45
  102. package/.claude/agents/agent-zara-zapier.md +0 -159
  103. package/.claude/commands/app-squad.md +0 -135
  104. package/.claude/commands/audit-squad.md +0 -158
  105. package/.claude/commands/autoplan.md +0 -563
  106. package/.claude/commands/cleanup-squad.md +0 -98
  107. package/.claude/commands/config-squad.md +0 -106
  108. package/.claude/commands/crud-squad.md +0 -87
  109. package/.claude/commands/data-squad.md +0 -97
  110. package/.claude/commands/debug-squad.md +0 -303
  111. package/.claude/commands/doc-squad.md +0 -65
  112. package/.claude/commands/handoff.md +0 -137
  113. package/.claude/commands/health.md +0 -49
  114. package/.claude/commands/help.md +0 -29
  115. package/.claude/commands/help:agents.md +0 -151
  116. package/.claude/commands/help:commands.md +0 -78
  117. package/.claude/commands/help:faq.md +0 -79
  118. package/.claude/commands/help:plugins.md +0 -50
  119. package/.claude/commands/help:skills.md +0 -93
  120. package/.claude/commands/help:tools.md +0 -75
  121. package/.claude/commands/hotfix-squad.md +0 -112
  122. package/.claude/commands/integration-squad.md +0 -82
  123. package/.claude/commands/janitor-squad.md +0 -167
  124. package/.claude/commands/learn-auto.md +0 -120
  125. package/.claude/commands/learn.md +0 -120
  126. package/.claude/commands/mcp-list.md +0 -27
  127. package/.claude/commands/onboard-squad.md +0 -140
  128. package/.claude/commands/plan-workspace.md +0 -732
  129. package/.claude/commands/prd.md +0 -130
  130. package/.claude/commands/project-status.md +0 -82
  131. package/.claude/commands/publish.md +0 -138
  132. package/.claude/commands/recap.md +0 -69
  133. package/.claude/commands/restore.md +0 -64
  134. package/.claude/commands/review-squad.md +0 -152
  135. package/.claude/commands/save.md +0 -24
  136. package/.claude/commands/stats.md +0 -19
  137. package/.claude/commands/swarm.md +0 -210
  138. package/.claude/commands/tool-builder.md +0 -39
  139. package/.claude/commands/ws-pull.md +0 -44
  140. package/.claude/hooks/_shared-memory.cjs +0 -305
  141. package/.claude/hooks/_utils.cjs +0 -108
  142. package/.claude/hooks/agent-failure-detector.cjs +0 -383
  143. package/.claude/hooks/agent-usage-logger.cjs +0 -204
  144. package/.claude/hooks/app-edit-guard.cjs +0 -494
  145. package/.claude/hooks/auto-learn.cjs +0 -304
  146. package/.claude/hooks/bash-guard.cjs +0 -272
  147. package/.claude/hooks/builder-mode-manager.cjs +0 -354
  148. package/.claude/hooks/bulk-activity-guard.cjs +0 -271
  149. package/.claude/hooks/context-watchdog.cjs +0 -230
  150. package/.claude/hooks/delegation-reminder.cjs +0 -465
  151. package/.claude/hooks/design-system-lint.cjs +0 -271
  152. package/.claude/hooks/post-scaffold-hook.cjs +0 -181
  153. package/.claude/hooks/prompt-guard.cjs +0 -354
  154. package/.claude/hooks/publish-template-guard.cjs +0 -147
  155. package/.claude/hooks/session-start.cjs +0 -35
  156. package/.claude/hooks/shared-memory-writer.cjs +0 -147
  157. package/.claude/hooks/skill-injector.cjs +0 -140
  158. package/.claude/hooks/skill-usage-logger.cjs +0 -258
  159. package/.claude/hooks/src-edit-guard.cjs +0 -240
  160. package/.claude/hooks/sync-marketplace-agents.cjs +0 -346
  161. package/.claude/settings.json +0 -257
  162. package/.claude/skills/SDK-activity-patterns/SKILL.md +0 -428
  163. package/.claude/skills/SDK-document-templates/SKILL.md +0 -1033
  164. package/.claude/skills/SDK-function-fields/SKILL.md +0 -542
  165. package/.claude/skills/SDK-generate-skill/SKILL.md +0 -92
  166. package/.claude/skills/SDK-init-skill/SKILL.md +0 -127
  167. package/.claude/skills/SDK-insight-queries/SKILL.md +0 -787
  168. package/.claude/skills/SDK-ws-config-skill/SKILL.md +0 -1139
  169. package/.claude/skills/agent-structure/SKILL.md +0 -98
  170. package/.claude/skills/api-documentation-patterns/SKILL.md +0 -474
  171. package/.claude/skills/chrome-mcp-reference/SKILL.md +0 -370
  172. package/.claude/skills/delegation-routing/SKILL.md +0 -202
  173. package/.claude/skills/frontend-design/SKILL.md +0 -254
  174. package/.claude/skills/hailer-activity-mover/SKILL.md +0 -213
  175. package/.claude/skills/hailer-api-client/SKILL.md +0 -518
  176. package/.claude/skills/hailer-app-builder/SKILL.md +0 -1434
  177. package/.claude/skills/hailer-apps-pictures/SKILL.md +0 -269
  178. package/.claude/skills/hailer-design-system/SKILL.md +0 -235
  179. package/.claude/skills/hailer-monolith-automations/SKILL.md +0 -686
  180. package/.claude/skills/hailer-permissions-system/SKILL.md +0 -121
  181. package/.claude/skills/hailer-project-protocol/SKILL.md +0 -488
  182. package/.claude/skills/hailer-rest-api/SKILL.md +0 -61
  183. package/.claude/skills/hailer-rest-api/hailer-activities.md +0 -184
  184. package/.claude/skills/hailer-rest-api/hailer-admin.md +0 -473
  185. package/.claude/skills/hailer-rest-api/hailer-calendar.md +0 -256
  186. package/.claude/skills/hailer-rest-api/hailer-feed.md +0 -249
  187. package/.claude/skills/hailer-rest-api/hailer-insights.md +0 -195
  188. package/.claude/skills/hailer-rest-api/hailer-messaging.md +0 -276
  189. package/.claude/skills/hailer-rest-api/hailer-workflows.md +0 -283
  190. package/.claude/skills/insight-join-patterns/SKILL.md +0 -174
  191. package/.claude/skills/integration-patterns/SKILL.md +0 -421
  192. package/.claude/skills/json-only-output/SKILL.md +0 -72
  193. package/.claude/skills/lsp-setup/SKILL.md +0 -160
  194. package/.claude/skills/mcp-direct-tools/SKILL.md +0 -153
  195. package/.claude/skills/optional-parameters/SKILL.md +0 -72
  196. package/.claude/skills/publish-hailer-app/SKILL.md +0 -244
  197. package/.claude/skills/testing-patterns/SKILL.md +0 -630
  198. package/.claude/skills/tool-builder/SKILL.md +0 -250
  199. package/.claude/skills/tool-parameter-usage/SKILL.md +0 -126
  200. package/.claude/skills/tool-response-verification/SKILL.md +0 -92
  201. package/.claude/skills/zapier-hailer-patterns/SKILL.md +0 -581
  202. package/.mcp.json +0 -13
  203. package/.opencode/agent/agent-ada-skill-builder.md +0 -35
  204. package/.opencode/agent/agent-alejandro-function-fields.md +0 -39
  205. package/.opencode/agent/agent-bjorn-config-audit.md +0 -36
  206. package/.opencode/agent/agent-builder-agent-creator.md +0 -39
  207. package/.opencode/agent/agent-code-simplifier.md +0 -31
  208. package/.opencode/agent/agent-dmitri-activity-crud.md +0 -40
  209. package/.opencode/agent/agent-giuseppe-app-builder.md +0 -37
  210. package/.opencode/agent/agent-gunther-mcp-tools.md +0 -39
  211. package/.opencode/agent/agent-helga-workflow-config.md +0 -203
  212. package/.opencode/agent/agent-igor-activity-mover-automation.md +0 -46
  213. package/.opencode/agent/agent-ingrid-doc-templates.md +0 -39
  214. package/.opencode/agent/agent-ivan-monolith.md +0 -46
  215. package/.opencode/agent/agent-kenji-data-reader.md +0 -53
  216. package/.opencode/agent/agent-lars-code-inspector.md +0 -28
  217. package/.opencode/agent/agent-marco-mockup-builder.md +0 -42
  218. package/.opencode/agent/agent-marcus-api-documenter.md +0 -53
  219. package/.opencode/agent/agent-marketplace-publisher.md +0 -44
  220. package/.opencode/agent/agent-marketplace-reviewer.md +0 -42
  221. package/.opencode/agent/agent-permissions-handler.md +0 -50
  222. package/.opencode/agent/agent-simple-writer.md +0 -45
  223. package/.opencode/agent/agent-svetlana-code-review.md +0 -39
  224. package/.opencode/agent/agent-tanya-test-runner.md +0 -57
  225. package/.opencode/agent/agent-ui-designer.md +0 -56
  226. package/.opencode/agent/agent-viktor-sql-insights.md +0 -34
  227. package/.opencode/agent/agent-web-search.md +0 -42
  228. package/.opencode/agent/agent-yevgeni-discussions.md +0 -37
  229. package/.opencode/agent/agent-zara-zapier.md +0 -53
  230. package/.opencode/commands/app-squad.md +0 -135
  231. package/.opencode/commands/audit-squad.md +0 -158
  232. package/.opencode/commands/autoplan.md +0 -563
  233. package/.opencode/commands/cleanup-squad.md +0 -98
  234. package/.opencode/commands/config-squad.md +0 -106
  235. package/.opencode/commands/crud-squad.md +0 -87
  236. package/.opencode/commands/data-squad.md +0 -97
  237. package/.opencode/commands/debug-squad.md +0 -303
  238. package/.opencode/commands/doc-squad.md +0 -65
  239. package/.opencode/commands/handoff.md +0 -137
  240. package/.opencode/commands/health.md +0 -49
  241. package/.opencode/commands/help-agents.md +0 -151
  242. package/.opencode/commands/help-commands.md +0 -32
  243. package/.opencode/commands/help-faq.md +0 -29
  244. package/.opencode/commands/help-plugins.md +0 -28
  245. package/.opencode/commands/help-skills.md +0 -7
  246. package/.opencode/commands/help-tools.md +0 -40
  247. package/.opencode/commands/help.md +0 -28
  248. package/.opencode/commands/hotfix-squad.md +0 -112
  249. package/.opencode/commands/integration-squad.md +0 -82
  250. package/.opencode/commands/janitor-squad.md +0 -167
  251. package/.opencode/commands/learn-auto.md +0 -120
  252. package/.opencode/commands/learn.md +0 -120
  253. package/.opencode/commands/mcp-list.md +0 -27
  254. package/.opencode/commands/onboard-squad.md +0 -140
  255. package/.opencode/commands/plan-workspace.md +0 -732
  256. package/.opencode/commands/prd.md +0 -131
  257. package/.opencode/commands/project-status.md +0 -82
  258. package/.opencode/commands/publish.md +0 -138
  259. package/.opencode/commands/recap.md +0 -69
  260. package/.opencode/commands/restore.md +0 -64
  261. package/.opencode/commands/review-squad.md +0 -152
  262. package/.opencode/commands/save.md +0 -24
  263. package/.opencode/commands/stats.md +0 -19
  264. package/.opencode/commands/swarm.md +0 -210
  265. package/.opencode/commands/tool-builder.md +0 -39
  266. package/.opencode/commands/ws-pull.md +0 -44
  267. package/.opencode/opencode.json +0 -28
  268. package/SESSION-HANDOFF.md +0 -68
  269. package/inbox/2026-03-04-bot-config-patterns.md +0 -24
  270. package/scripts/postinstall.cjs +0 -64
  271. package/scripts/test-hal-tools.ts +0 -154
@@ -1,542 +0,0 @@
1
- ---
2
- name: SDK-function-fields
3
- description: Complete guide to creating calculated function fields in Hailer - workflow, variable types, patterns
4
- version: 1.2.0
5
- triggers:
6
- - function field
7
- - calculated field
8
- - formula field
9
- - backlinks
10
- - phase filtering
11
- - Data metadata
12
- ---
13
-
14
- # Function Fields
15
-
16
- Complete guide for creating calculated fields that auto-update when dependencies change.
17
-
18
- ---
19
-
20
- ## Overview
21
-
22
- Function fields compute values from other fields. Examples:
23
- - Total = Quantity × Unit Price
24
- - Days Until Due = Due Date - Today
25
- - Invoice Total = Sum of line item prices (filtered by phase)
26
-
27
- ---
28
-
29
- ## Step-by-Step Workflow
30
-
31
- ### 1. Pull Latest
32
- ```bash
33
- npm run pull
34
- ```
35
-
36
- ### 2. Add Field Definition (fields.ts)
37
-
38
- ```typescript
39
- // workspace/[Workflow]_[id]/fields.ts
40
- {
41
- label: "Total Cost",
42
- type: "number",
43
- key: "total_cost",
44
- function: "@function:totalCost",
45
- functionEnabled: true,
46
- editable: false,
47
- functionVariables: {
48
- quantity: {
49
- type: "=",
50
- data: [FieldIds.quantity]
51
- },
52
- unitPrice: {
53
- type: "=",
54
- data: [FieldIds.unit_price]
55
- }
56
- }
57
- }
58
- ```
59
-
60
- ### 3. Create Function File
61
-
62
- Create `workspace/[Workflow]_[id]/functions/totalCost.ts`:
63
-
64
- ```typescript
65
- export function totalCost(dep: {
66
- quantity: number | null;
67
- unitPrice: number | null;
68
- }): number {
69
- const qty = Number(dep.quantity) || 0;
70
- const price = Number(dep.unitPrice) || 0;
71
- return qty * price;
72
- }
73
- ```
74
-
75
- ### 4. Export Function
76
-
77
- Edit `workspace/[Workflow]_[id]/functions/index.ts`:
78
-
79
- ```typescript
80
- export { totalCost } from './totalCost';
81
- ```
82
-
83
- ### 5. Test
84
-
85
- ```typescript
86
- // workspace/[Workflow]_[id]/main.test.ts
87
- import { totalCost } from './functions';
88
-
89
- describe('totalCost', () => {
90
- it('multiplies quantity by unit price', () => {
91
- expect(totalCost({ quantity: 5, unitPrice: 10 })).toBe(50);
92
- });
93
-
94
- it('handles null values', () => {
95
- expect(totalCost({ quantity: null, unitPrice: 10 })).toBe(0);
96
- });
97
- });
98
- ```
99
-
100
- Run: `npm test`
101
-
102
- ### 6. Push
103
-
104
- ```bash
105
- npm run fields-push:force
106
- ```
107
-
108
- ---
109
-
110
- ## Variable Types Reference
111
-
112
- | Type | Name | data Array | Returns |
113
- |------|------|------------|---------|
114
- | `=` | Current field | `[FieldId]` | Single value |
115
- | `>` | Forward link | `[LinkFieldId, TargetFieldId]` | Single value |
116
- | `<` | Backlink | `[WorkflowId, TargetFieldId]` | **Array** |
117
- | `?` | Static | `[WorkflowId, PhaseId]` | Phase ID string |
118
-
119
- ---
120
-
121
- ## Field Data Formats in Functions
122
-
123
- What format does each field type return when used as a dependency variable?
124
-
125
- | Field Type | Returns | Example |
126
- |------------|---------|---------|
127
- | `text`, `textarea` | `string` | `"Hello world"` |
128
- | `numeric`, `numericunit` | `number` | `42.5` |
129
- | `date`, `datetime` | `number` (ms timestamp) | `1730937600000` |
130
- | `daterange`, `datetimerange` | `{ start: number, end: number }` | `{ start: 1730937600000, end: 1731024000000 }` |
131
- | `time` | `number` (ms timestamp, includes date!) | `1765863000000` |
132
- | `timerange` | `{ start: number, end: number }` | `{ start: 1765863000000, end: 1765915200000 }` (ms timestamps, includes date!) |
133
- | `textpredefinedoptions` | `string` | `"High"` |
134
- | `users`, `teams` | `string` (ID) | `"5f8a1b2c3d4e5f6a7b8c9d0e"` |
135
- | `activitylink` | `string` (activity ID) | `"692abc123def456"` |
136
- | `country` | `string` (ISO code) | `"FI"` |
137
- | `numeric` + `modifier.checkbox` | `number` | `1` (true) or `0` (false) |
138
-
139
- **Examples:**
140
-
141
- ```javascript
142
- // Date field (milliseconds timestamp)
143
- const dueDate = dep.dueDate; // 1730937600000
144
- const isOverdue = dueDate < Date.now();
145
-
146
- // Daterange field (object with start/end)
147
- const period = dep.eventPeriod; // { start: 1730937600000, end: 1731024000000 }
148
- const startDate = period ? period.start : null;
149
- const endDate = period ? period.end : null;
150
- const durationMs = (endDate && startDate) ? (endDate - startDate) : 0;
151
- const durationDays = Math.ceil(durationMs / 86400000);
152
-
153
- // Time field (ms timestamp - includes date!)
154
- const startTime = dep.startTime; // 1765863000000
155
- // To extract just the time, use Date methods:
156
- const date = new Date(startTime);
157
- const hours = date.getUTCHours();
158
- const minutes = date.getUTCMinutes();
159
-
160
- // Timerange field (object with start/end as ms timestamps - includes date!)
161
- const workHours = dep.workingHours; // { start: 1765863000000, end: 1765915200000 }
162
- const durationMs = workHours ? (workHours.end - workHours.start) : 0;
163
- const durationMinutes = durationMs / 60000;
164
-
165
- // IMPORTANT: When to convert vs keep raw:
166
- // - Display only (text output) → use Date methods to extract time
167
- // - Write to another date/time field → keep as Unix milliseconds (no conversion!)
168
-
169
- // Checkbox field (1 or 0)
170
- const isActive = dep.isActive; // 1 or 0
171
- if (isActive === 1) { /* checked */ }
172
- ```
173
-
174
- ---
175
-
176
- ## Backlink Arrays (`<`)
177
-
178
- Backlinks return **arrays** because multiple activities can link to this one.
179
-
180
- ```javascript
181
- // functionVariables config
182
- {
183
- prices: {
184
- type: "<",
185
- data: [WorkflowIds.invoice_rows, InvoiceRows_FieldIds.total_price]
186
- }
187
- }
188
-
189
- // In function - ALWAYS default to empty array
190
- const prices = dep.prices || [];
191
- let total = 0;
192
- for (let i = 0; i < prices.length; i++) {
193
- total += Number(prices[i]) || 0;
194
- }
195
- return total;
196
- ```
197
-
198
- ---
199
-
200
- ## Activity Metadata (`"meta"`)
201
-
202
- The special `"meta"` value returns activity metadata. It works with **all variable types**:
203
-
204
- ### Current Activity Metadata (`=`)
205
-
206
- ```javascript
207
- // Get metadata of THIS activity
208
- {
209
- myMeta: {
210
- type: "=",
211
- data: ["meta"]
212
- }
213
- }
214
-
215
- // In function
216
- const myPhase = dep.myMeta ? dep.myMeta.phase : null;
217
- const myCreated = dep.myMeta ? dep.myMeta.created : 0;
218
- ```
219
-
220
- ### Forward Link Metadata (`>`)
221
-
222
- ```javascript
223
- // Get metadata of LINKED activity (this → other)
224
- {
225
- customerMeta: {
226
- type: ">",
227
- data: [FieldIds.customer_link, "meta"]
228
- }
229
- }
230
-
231
- // In function
232
- const customerPhase = dep.customerMeta ? dep.customerMeta.phaseName : 'Unknown';
233
- ```
234
-
235
- ### Backlink Metadata (`<`)
236
-
237
- ```javascript
238
- // Get metadata of activities linking TO this (others → this)
239
- {
240
- rowsMeta: {
241
- type: "<",
242
- data: [WorkflowIds.invoice_rows, "meta"]
243
- }
244
- }
245
-
246
- // In function - returns ARRAY
247
- const rows = dep.rowsMeta || [];
248
- for (let i = 0; i < rows.length; i++) {
249
- const phaseName = rows[i] ? rows[i].phaseName : 'Unknown';
250
- }
251
- ```
252
-
253
- ### Metadata Structure
254
-
255
- ```javascript
256
- {
257
- "_id": "694c9536acfa30f6df13201b", // Activity ID
258
- "name": "Invoice row name", // Activity name
259
- "process": "67dc1b7d3d2c9f6cf9a5468d", // Workflow ID
260
- "phase": "67dc1b7d3d2c9f6cf9a546c4", // Phase ID
261
- "processName": "Invoice Rows", // Workflow name
262
- "phaseName": "Active", // Phase name
263
- "created": 1766626614031, // Created timestamp (ms)
264
- "updated": 1766626614031, // Updated timestamp (ms)
265
- "completed": null, // Completed timestamp or null
266
- "sequence": 1649, // Activity sequence number
267
- "active": true // Is activity active
268
- }
269
- ```
270
-
271
- ---
272
-
273
- ## Parallel Array Guarantee
274
-
275
- **CRITICAL INSIGHT:** When you have multiple `<` (backlink) variables from the **SAME source workflow**, they are guaranteed to be:
276
- - Same length
277
- - Same order (index 0 in all arrays = same activity)
278
-
279
- **This is a core Hailer feature that enables safe parallel iteration.**
280
-
281
- ```javascript
282
- const prices = dep['Total price'] || []; // [41.76, 26.1, 153.47]
283
- const data = dep['Data'] || []; // [{...}, {...}, {...}]
284
-
285
- // Index 0 in both = same Invoice Row activity
286
- for (let i = 0; i < prices.length; i++) {
287
- const price = Number(prices[i]) || 0;
288
- const phaseName = data[i] ? data[i].phaseName : 'Unknown';
289
- // price and phaseName are from the SAME activity
290
- }
291
- ```
292
-
293
- **Arrays from DIFFERENT workflows** are independent.
294
-
295
- ---
296
-
297
- ## Static Variables (`?`)
298
-
299
- Static variables provide phase IDs for comparison in your function logic.
300
-
301
- ```javascript
302
- // Get specific phase IDs to compare against
303
- {
304
- donePhase: {
305
- type: "?",
306
- data: [WorkflowIds.sales_activities, PhaseIds.done]
307
- },
308
- archivePhase: {
309
- type: "?",
310
- data: [WorkflowIds.sales_activities, PhaseIds.archive]
311
- }
312
- }
313
-
314
- // In function - compare against metadata phase
315
- const donePhase = dep.donePhase; // "627d14339381d6077ab90ce9"
316
- const archivePhase = dep.archivePhase; // "639b49617a4413c20f15ac12"
317
-
318
- if (item.phase === donePhase || item.phase === archivePhase) {
319
- // Activity is in done or archive phase
320
- }
321
- ```
322
-
323
- **Note:** To get `process` and `phase` IDs from activities, use `"meta"` (not `?`). Static `?` is only for providing known phase IDs for comparison.
324
-
325
- ---
326
-
327
- ## Common Patterns
328
-
329
- ### Sum from Backlinks
330
-
331
- ```javascript
332
- function total(dep) {
333
- const prices = dep.prices || [];
334
- let sum = 0;
335
- for (let i = 0; i < prices.length; i++) {
336
- sum += Number(prices[i]) || 0;
337
- }
338
- return sum;
339
- }
340
- ```
341
-
342
- ### Filter by Phase (Complete Example)
343
-
344
- **functionVariables config:**
345
- ```javascript
346
- {
347
- Data: {
348
- type: "<",
349
- data: [WorkflowIds.sales_activities, "meta"]
350
- },
351
- dl: {
352
- type: "<",
353
- data: [WorkflowIds.sales_activities, FieldIds.deadline]
354
- },
355
- done: {
356
- type: "?",
357
- data: [WorkflowIds.sales_activities, PhaseIds.done]
358
- },
359
- archive: {
360
- type: "?",
361
- data: [WorkflowIds.sales_activities, PhaseIds.archive]
362
- }
363
- }
364
- ```
365
-
366
- **Function (find latest deadline from done/archived activities):**
367
- ```javascript
368
- function latestCompletedDeadline(dep) {
369
- const data = dep.Data || [];
370
- const deadlines = dep.dl || [];
371
- const donePhase = dep.done;
372
- const archivePhase = dep.archive;
373
-
374
- const arr = [];
375
- for (let i = 0; i < data.length; i++) {
376
- const item = data[i];
377
- if ((item.phase === donePhase || item.phase === archivePhase) && deadlines[i]) {
378
- arr.push(deadlines[i]);
379
- }
380
- }
381
-
382
- if (arr.length === 0) return null;
383
- return Math.max(...arr);
384
- }
385
- ```
386
-
387
- ### Sum Active Only
388
-
389
- ```javascript
390
- function sumActiveOnly(dep) {
391
- const prices = dep['Total price'] || [];
392
- const data = dep['Data'] || [];
393
- const activePhase = dep['Active'];
394
-
395
- let total = 0;
396
- for (let i = 0; i < prices.length; i++) {
397
- if (data[i] && data[i].phase === activePhase) {
398
- total += Number(prices[i]) || 0;
399
- }
400
- }
401
- return total;
402
- }
403
- ```
404
-
405
- ### Group by Phase
406
-
407
- ```javascript
408
- function groupByPhase(dep) {
409
- const prices = dep['Total price'] || [];
410
- const data = dep['Data'] || [];
411
-
412
- const result = {};
413
- for (let i = 0; i < prices.length; i++) {
414
- const phaseName = data[i] ? data[i].phaseName : 'Unknown';
415
- const price = Number(prices[i]) || 0;
416
- result[phaseName] = (result[phaseName] || 0) + price;
417
- }
418
- return JSON.stringify(result);
419
- }
420
- ```
421
-
422
- ### Exclude Multiple Phases
423
-
424
- ```javascript
425
- function sumExcludingCancelled(dep) {
426
- const prices = dep['Total price'] || [];
427
- const data = dep['Data'] || [];
428
- const cancelledPhase = dep['Cancelled'];
429
- const deletedPhase = dep['Deleted'];
430
-
431
- let total = 0;
432
- for (let i = 0; i < prices.length; i++) {
433
- const phase = data[i] ? data[i].phase : null;
434
- if (phase === cancelledPhase || phase === deletedPhase) continue;
435
- total += Number(prices[i]) || 0;
436
- }
437
- return total;
438
- }
439
- ```
440
-
441
- ### Conditional Text
442
-
443
- ```javascript
444
- function status(dep) {
445
- if (!dep.dueDate) return "No due date";
446
- if (dep.dueDate < Date.now()) return "Overdue";
447
- return "On track";
448
- }
449
- ```
450
-
451
- ### Forward Link Value
452
-
453
- ```javascript
454
- // Get value from linked activity
455
- functionVariables: {
456
- customerName: {
457
- type: ">",
458
- data: [FieldIds.customer_link, Customers_FieldIds.name]
459
- }
460
- }
461
- ```
462
-
463
- ### Emoji Based on Own Phase
464
-
465
- ```javascript
466
- // In name function: use activity's own phase, not parent workflow phase
467
- functionVariables: {
468
- myMeta: {
469
- type: "=",
470
- data: ["meta"] // Returns this activity's metadata
471
- },
472
- donePhase: {
473
- type: "?",
474
- data: [WorkflowIds.this_workflow, PhaseIds.done]
475
- }
476
- }
477
-
478
- // In name function
479
- function nameWithEmoji(dep) {
480
- const myPhase = dep.myMeta ? dep.myMeta.phase : null;
481
- const donePhase = dep.donePhase;
482
-
483
- const prefix = (myPhase === donePhase) ? "✅ " : "🔄 ";
484
- return prefix + dep.activityName;
485
- }
486
- ```
487
-
488
- **Key:** Compare against the activity's OWN phase (from `"data"` metadata), not the parent workflow's phase.
489
-
490
- ---
491
-
492
- ## Code Style
493
-
494
- **Use `const` and `let`** - NOT `var`:
495
- ```javascript
496
- // Correct
497
- const prices = dep.prices || [];
498
- let total = 0;
499
-
500
- // Wrong
501
- var prices = dep.prices || [];
502
- ```
503
-
504
- ---
505
-
506
- ## Critical Rules
507
-
508
- 1. **ES6 JavaScript only** - No TypeScript syntax in function body
509
- 2. **Never return null/undefined** - Always return valid typed value
510
- 3. **Handle null inputs** - Use `|| 0` or `|| ""` defaults
511
- 4. **Same inputs = same outputs** - No randomness, deterministic
512
- 5. **Helpers inside function** - Define helper functions in function body
513
- 6. **Use enums** - Never hardcode field/workflow IDs
514
- 7. **updateMany single-workflow rule** - `v3.activity.updateMany` targets one workflow per call. For cascading updates across multiple workflows, create separate function fields per target workflow. Don't mix activities from different workflows in one payload
515
- 8. **Double-wrapped array for generic CRUD** - When outputting a payload for the monolith `POST /api/update-activities` handler, use `[[{_id, phaseId}, ...]]` (double-wrapped). The handler spreads parsed JSON as `updateMany(...args)`, so the first arg must be the array. Single-wrapped `[{_id, phaseId}]` causes "must be an array" validation error
516
- 9. **Empty string validation** - Hailer rejects empty string `''` with "value is not allowed to be empty". Always return `'[]'` or a valid non-empty string as default from function fields
517
- 10. **Data metadata shorthand** - `type: "="` with `data: ["data"]` returns this activity's metadata object (same as `data: ["meta"]`). Similarly, `type: "<"` with `data: [workflowId, "data"]` returns array of metadata objects for linked activities
518
-
519
- ---
520
-
521
- ## Common Mistakes
522
-
523
- | Wrong | Right |
524
- |-------|-------|
525
- | `var arr = dep.arr` | `const arr = dep.arr \|\| []` |
526
- | `arr[i] * 2` | `(Number(arr[i]) \|\| 0) * 2` |
527
- | `data[i].phase` | `data[i] ? data[i].phase : null` |
528
- | Assuming arrays match across workflows | Only same-workflow arrays are parallel |
529
- | Hardcoding phase IDs | Use `?` static variables with enums |
530
-
531
- ---
532
-
533
- ## Checklist
534
-
535
- Before creating a function with backlinks:
536
-
537
- - [ ] All `<` arrays have `|| []` default
538
- - [ ] Individual array values use `Number(x) || 0`
539
- - [ ] Data metadata access has null check
540
- - [ ] Phase comparisons use `?` static variables
541
- - [ ] Using enums from workspace for all IDs
542
- - [ ] Tested with Vitest before push
@@ -1,92 +0,0 @@
1
- ---
2
- name: SDK-generate-skill
3
- description: TypeScript type generation from Hailer workspace
4
- version: 1.0.0
5
- triggers: Generate types, TypeScript generation, update types, enums
6
- ---
7
-
8
- # SDK Type Generation
9
-
10
- Generate TypeScript types from your Hailer workspace configuration.
11
-
12
- ## Overview
13
-
14
- The SDK generates TypeScript types and enums from your workspace configuration, providing type-safe access to:
15
- - Workflow IDs
16
- - Field IDs
17
- - Phase IDs
18
- - Team IDs
19
- - Group IDs
20
- - Member IDs
21
-
22
- ---
23
-
24
- ## Generated Files
25
-
26
- After `npm run pull`, these files are auto-generated:
27
-
28
- ```
29
- workspace/
30
- ├── enums.ts # Type-safe ID constants (DO NOT EDIT)
31
- ├── hailer.d.ts # TypeScript definitions (DO NOT EDIT)
32
- ```
33
-
34
- ---
35
-
36
- ## Using Enums
37
-
38
- ```typescript
39
- import {
40
- WorkflowIds,
41
- Tasks_FieldIds,
42
- Tasks_PhaseIds,
43
- TeamIds,
44
- WorkspaceMembers
45
- } from './workspace/enums';
46
-
47
- // Reference workflow
48
- const workflowId = WorkflowIds.tasks;
49
-
50
- // Reference field
51
- const fieldId = Tasks_FieldIds.due_date;
52
-
53
- // Reference phase
54
- const phaseId = Tasks_PhaseIds.in_progress;
55
- ```
56
-
57
- ---
58
-
59
- ## Regenerating Types
60
-
61
- Types are regenerated automatically when you run:
62
-
63
- ```bash
64
- npm run pull
65
- ```
66
-
67
- **When to regenerate:**
68
- - After pushing new fields/phases/workflows
69
- - After team/group changes
70
- - When enums seem out of date
71
-
72
- ---
73
-
74
- ## Important Notes
75
-
76
- 1. **Never edit enums.ts manually** - It's auto-generated
77
- 2. **Pull after push** - Get new IDs into enums after adding items
78
- 3. **Use enums everywhere** - Never hardcode IDs as strings
79
- 4. **Type safety** - TypeScript will catch invalid ID references
80
-
81
- ---
82
-
83
- ## Troubleshooting
84
-
85
- **Enum not found after adding field:**
86
- 1. Ensure you ran `npm run fields-push:force`
87
- 2. Run `npm run pull` to regenerate enums
88
- 3. Check that the field was actually created in Hailer
89
-
90
- **Type errors after changes:**
91
- 1. Run `npm run pull` to sync
92
- 2. Restart TypeScript server in your IDE