@hailer/mcp 0.1.8 → 0.1.9

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 (135) hide show
  1. package/.claude/agents/agent-dmitri-activity-crud.md +3 -1
  2. package/.claude/agents/agent-giuseppe-app-builder.md +11 -12
  3. package/.claude/agents/agent-kenji-data-reader.md +5 -3
  4. package/.claude/skills/hailer-app-builder/SKILL.md +506 -0
  5. package/.claude/skills/publish-hailer-app/SKILL.md +169 -0
  6. package/.claude/skills/tool-parameter-usage/SKILL.md +112 -0
  7. package/CLAUDE.md +6 -2
  8. package/REFACTOR_STATUS.md +127 -0
  9. package/dist/cli.js +0 -0
  10. package/dist/client/agents/base.d.ts +202 -0
  11. package/dist/client/agents/base.js +737 -0
  12. package/dist/client/agents/definitions.d.ts +53 -0
  13. package/dist/client/agents/definitions.js +178 -0
  14. package/dist/client/agents/orchestrator.d.ts +119 -0
  15. package/dist/client/agents/orchestrator.js +760 -0
  16. package/dist/client/agents/specialist.d.ts +86 -0
  17. package/dist/client/agents/specialist.js +340 -0
  18. package/dist/client/bot-manager.d.ts +44 -0
  19. package/dist/client/bot-manager.js +173 -0
  20. package/dist/client/chat-agent-daemon.d.ts +464 -0
  21. package/dist/client/chat-agent-daemon.js +1774 -0
  22. package/dist/client/daemon-factory.d.ts +106 -0
  23. package/dist/client/daemon-factory.js +301 -0
  24. package/dist/client/factory.d.ts +107 -0
  25. package/dist/client/factory.js +304 -0
  26. package/dist/client/index.d.ts +17 -0
  27. package/dist/client/index.js +38 -0
  28. package/dist/client/multi-bot-manager.d.ts +18 -0
  29. package/dist/client/multi-bot-manager.js +88 -1
  30. package/dist/client/orchestrator-daemon.d.ts +87 -0
  31. package/dist/client/orchestrator-daemon.js +444 -0
  32. package/dist/client/services/agent-registry.d.ts +108 -0
  33. package/dist/client/services/agent-registry.js +630 -0
  34. package/dist/client/services/conversation-manager.d.ts +50 -0
  35. package/dist/client/services/conversation-manager.js +136 -0
  36. package/dist/client/services/mcp-client.d.ts +48 -0
  37. package/dist/client/services/mcp-client.js +105 -0
  38. package/dist/client/services/message-classifier.d.ts +37 -0
  39. package/dist/client/services/message-classifier.js +187 -0
  40. package/dist/client/services/message-formatter.d.ts +84 -0
  41. package/dist/client/services/message-formatter.js +353 -0
  42. package/dist/client/services/session-logger.d.ts +106 -0
  43. package/dist/client/services/session-logger.js +446 -0
  44. package/dist/client/services/tool-executor.d.ts +41 -0
  45. package/dist/client/services/tool-executor.js +169 -0
  46. package/dist/client/services/workspace-schema-cache.d.ts +149 -0
  47. package/dist/client/services/workspace-schema-cache.js +732 -0
  48. package/dist/client/specialist-daemon.d.ts +77 -0
  49. package/dist/client/specialist-daemon.js +197 -0
  50. package/dist/client/specialists.d.ts +53 -0
  51. package/dist/client/specialists.js +178 -0
  52. package/dist/client/tool-schema-loader.d.ts +4 -3
  53. package/dist/client/tool-schema-loader.js +54 -8
  54. package/dist/client/types.d.ts +283 -55
  55. package/dist/client/types.js +113 -2
  56. package/dist/config.d.ts +1 -1
  57. package/dist/config.js +1 -1
  58. package/dist/core.d.ts +10 -2
  59. package/dist/core.js +43 -27
  60. package/dist/lib/logger.js +15 -3
  61. package/dist/mcp/UserContextCache.js +2 -2
  62. package/dist/mcp/hailer-clients.js +5 -5
  63. package/dist/mcp/signal-handler.js +27 -5
  64. package/dist/mcp/tools/activity.js +137 -65
  65. package/dist/mcp/tools/app-core.js +4 -140
  66. package/dist/mcp/tools/app-marketplace.js +15 -260
  67. package/dist/mcp/tools/app-member.js +2 -73
  68. package/dist/mcp/tools/app-scaffold.js +146 -87
  69. package/dist/mcp/tools/discussion.js +348 -73
  70. package/dist/mcp/tools/insight.js +74 -190
  71. package/dist/mcp/tools/workflow.js +20 -94
  72. package/dist/mcp/utils/hailer-api-client.d.ts +4 -2
  73. package/dist/mcp/utils/hailer-api-client.js +24 -10
  74. package/dist/mcp-server.d.ts +4 -0
  75. package/dist/mcp-server.js +24 -4
  76. package/dist/routes/agents.d.ts +44 -0
  77. package/dist/routes/agents.js +311 -0
  78. package/dist/services/agent-credential-store.d.ts +73 -0
  79. package/dist/services/agent-credential-store.js +212 -0
  80. package/lineup-manager/dist/assets/index-8ce6041d.css +1 -0
  81. package/lineup-manager/dist/assets/index-e168f265.js +600 -0
  82. package/lineup-manager/dist/index.html +15 -0
  83. package/lineup-manager/dist/manifest.json +17 -0
  84. package/lineup-manager/dist/vite.svg +1 -0
  85. package/package.json +1 -1
  86. package/dist/client/adaptive-documentation-bot.d.ts +0 -106
  87. package/dist/client/adaptive-documentation-bot.js +0 -464
  88. package/dist/client/adaptive-documentation-types.d.ts +0 -66
  89. package/dist/client/adaptive-documentation-types.js +0 -9
  90. package/dist/client/agent-activity-bot.d.ts +0 -51
  91. package/dist/client/agent-activity-bot.js +0 -166
  92. package/dist/client/agent-tracker.d.ts +0 -499
  93. package/dist/client/agent-tracker.js +0 -659
  94. package/dist/client/description-updater.d.ts +0 -56
  95. package/dist/client/description-updater.js +0 -259
  96. package/dist/client/log-parser.d.ts +0 -72
  97. package/dist/client/log-parser.js +0 -387
  98. package/dist/client/mcp-assistant.d.ts +0 -21
  99. package/dist/client/mcp-assistant.js +0 -58
  100. package/dist/client/mcp-client.d.ts +0 -50
  101. package/dist/client/mcp-client.js +0 -538
  102. package/dist/client/message-processor.d.ts +0 -35
  103. package/dist/client/message-processor.js +0 -357
  104. package/dist/client/providers/anthropic-provider.d.ts +0 -19
  105. package/dist/client/providers/anthropic-provider.js +0 -645
  106. package/dist/client/providers/assistant-provider.d.ts +0 -17
  107. package/dist/client/providers/assistant-provider.js +0 -51
  108. package/dist/client/providers/llm-provider.d.ts +0 -47
  109. package/dist/client/providers/llm-provider.js +0 -367
  110. package/dist/client/providers/openai-provider.d.ts +0 -23
  111. package/dist/client/providers/openai-provider.js +0 -630
  112. package/dist/client/simple-llm-caller.d.ts +0 -19
  113. package/dist/client/simple-llm-caller.js +0 -100
  114. package/dist/client/skill-generator.d.ts +0 -81
  115. package/dist/client/skill-generator.js +0 -386
  116. package/dist/client/test-adaptive-bot.d.ts +0 -9
  117. package/dist/client/test-adaptive-bot.js +0 -82
  118. package/dist/client/token-pricing.d.ts +0 -38
  119. package/dist/client/token-pricing.js +0 -127
  120. package/dist/client/token-tracker.d.ts +0 -232
  121. package/dist/client/token-tracker.js +0 -457
  122. package/dist/client/token-usage-bot.d.ts +0 -53
  123. package/dist/client/token-usage-bot.js +0 -153
  124. package/dist/client/tool-executor.d.ts +0 -69
  125. package/dist/client/tool-executor.js +0 -159
  126. package/dist/lib/materialize.d.ts +0 -3
  127. package/dist/lib/materialize.js +0 -101
  128. package/dist/lib/normalizedName.d.ts +0 -7
  129. package/dist/lib/normalizedName.js +0 -48
  130. package/dist/lib/terminal-prompt.d.ts +0 -9
  131. package/dist/lib/terminal-prompt.js +0 -108
  132. package/dist/mcp/tools/skill.d.ts +0 -10
  133. package/dist/mcp/tools/skill.js +0 -279
  134. package/dist/mcp/tools/workflow-template.d.ts +0 -19
  135. package/dist/mcp/tools/workflow-template.js +0 -822
@@ -0,0 +1,169 @@
1
+ ---
2
+ name: publish-hailer-app
3
+ description: Guide for publishing Hailer apps to production
4
+ ---
5
+
6
+ # Publish Hailer App Skill
7
+
8
+ Guide for publishing Hailer apps to production using MCP tools.
9
+
10
+ <critical>
11
+ ## MANDATORY: Validate Before Publishing
12
+
13
+ The `publish_hailer_app` tool will SILENTLY FAIL if manifest.json is misconfigured.
14
+
15
+ **YOU MUST validate these before calling publish_hailer_app:**
16
+
17
+ 1. Read `public/manifest.json` in the project
18
+ 2. Check `appId` exists and is 24 characters
19
+ 3. Check `version` exists and is NOT empty (e.g., "1.0.0")
20
+ 4. Check `versionDescription` exists and is NOT empty
21
+
22
+ If ANY are missing/empty, FIX THEM FIRST before publishing.
23
+ </critical>
24
+
25
+ <validation-code>
26
+ ## Validation Steps (DO THIS FIRST)
27
+
28
+ ```
29
+ 1. Read({file_path: "{projectDir}/public/manifest.json"})
30
+
31
+ 2. Verify JSON contains:
32
+ - "appId": "24-char-id" ← If missing: use create_app first
33
+ - "version": "1.0.0" ← If empty: set to "1.0.0"
34
+ - "versionDescription": "..." ← If empty: set to "Initial release"
35
+
36
+ 3. If any field missing/empty → Edit manifest.json to fix
37
+
38
+ 4. ONLY THEN call publish_hailer_app
39
+ ```
40
+ </validation-code>
41
+
42
+ <workflow>
43
+ ## Full Publishing Workflow
44
+
45
+ ### Step 1: Check if Production App Exists
46
+
47
+ ```javascript
48
+ list_apps()
49
+ ```
50
+ Look for your app with a `https://apps.hailer.com/...` URL (NOT localhost).
51
+
52
+ ### Step 2: Create Production App (if needed)
53
+
54
+ If app doesn't exist or only has localhost URL:
55
+ ```javascript
56
+ create_app({
57
+ name: "My App Name",
58
+ description: "What the app does"
59
+ })
60
+ ```
61
+ Returns new appId with production URL.
62
+
63
+ ### Step 3: Validate & Fix manifest.json
64
+
65
+ Read the manifest:
66
+ ```javascript
67
+ Read({file_path: "{projectDir}/public/manifest.json"})
68
+ ```
69
+
70
+ Required structure:
71
+ ```json
72
+ {
73
+ "appId": "695816e2ba1d8bef3af7e018",
74
+ "version": "1.0.0",
75
+ "versionDescription": "Initial production release"
76
+ }
77
+ ```
78
+
79
+ **If appId missing:** Add the ID from Step 2
80
+ **If version empty:** Set to "1.0.0"
81
+ **If versionDescription empty:** Set to "Initial release"
82
+
83
+ ### Step 4: Publish
84
+
85
+ ```javascript
86
+ publish_hailer_app({
87
+ projectDirectory: "/path/to/app"
88
+ })
89
+ ```
90
+
91
+ ### Step 5: Verify
92
+
93
+ ```javascript
94
+ list_apps()
95
+ ```
96
+ Confirm URL is `https://apps.hailer.com/...` (not localhost).
97
+ </workflow>
98
+
99
+ <silent-failure>
100
+ ## Why Silent Failures Happen
101
+
102
+ The SDK publish script requires `version` and `versionDescription` in manifest.json.
103
+ If missing/empty, the tool returns "Success" but files are NOT uploaded.
104
+
105
+ **Symptoms of silent failure:**
106
+ - Tool says "App Published Successfully!"
107
+ - But app URL is still `http://localhost:3000`
108
+ - Or production URL returns 403/404
109
+
110
+ **Always validate manifest BEFORE publishing.**
111
+ </silent-failure>
112
+
113
+ <dev-vs-prod>
114
+ ## Dev vs Production Apps
115
+
116
+ | Type | URL | Created By | Can Publish To |
117
+ |------|-----|------------|----------------|
118
+ | Dev | `http://localhost:3000` | `scaffold_hailer_app` | NO - stays localhost |
119
+ | Prod | `https://apps.hailer.com/...` | `create_app` | YES |
120
+
121
+ **Key insight:** Dev apps (scaffolded) will ALWAYS use localhost.
122
+ To deploy to production, create a NEW app with `create_app`.
123
+ </dev-vs-prod>
124
+
125
+ <updating>
126
+ ## Updating Published Apps
127
+
128
+ 1. Bump version in manifest.json:
129
+ ```json
130
+ {
131
+ "version": "1.0.1",
132
+ "versionDescription": "Fixed data loading bug"
133
+ }
134
+ ```
135
+
136
+ 2. Publish:
137
+ ```javascript
138
+ publish_hailer_app({
139
+ projectDirectory: "/path/to/app"
140
+ })
141
+ ```
142
+
143
+ New version replaces old at same URL.
144
+ </updating>
145
+
146
+ <sharing>
147
+ ## Sharing Apps
148
+
149
+ ```javascript
150
+ // Entire workspace
151
+ add_app_member({ appId: "...", member: "network_{workspaceId}" })
152
+
153
+ // Team
154
+ add_app_member({ appId: "...", member: "team_{teamId}" })
155
+
156
+ // User
157
+ add_app_member({ appId: "...", member: "user_{userId}" })
158
+ ```
159
+ </sharing>
160
+
161
+ <checklist>
162
+ ## Pre-Publish Checklist
163
+
164
+ - [ ] Production app exists (`create_app`, not scaffold)
165
+ - [ ] manifest.json `appId` is 24 chars (not empty)
166
+ - [ ] manifest.json `version` is set (e.g., "1.0.0")
167
+ - [ ] manifest.json `versionDescription` is set (not empty)
168
+ - [ ] node_modules exists (dependencies installed)
169
+ </checklist>
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: tool-parameter-usage
3
+ description: Extract IDs from context and use correct parameter formats for Hailer tools
4
+ triggers: Tool validation failed with "Required" error, empty receivedArgs, or field format errors
5
+ ---
6
+
7
+ <problem>
8
+ LLM calls tools with empty parameters `{}` even when context contains required IDs, or uses wrong parameter names/formats.
9
+ </problem>
10
+
11
+ <context-extraction>
12
+ The `<incoming>` tag in messages contains critical IDs. ALWAYS extract and use them:
13
+
14
+ ```xml
15
+ <incoming activityId="69384669b7826c5d9ec4e07c" discussionId="69384669b7826c5d9ec4e07d">
16
+ User message here
17
+ </incoming>
18
+ ```
19
+
20
+ **Extract before calling tools:**
21
+ - `activityId` → use for `show_activity_by_id`, `update_activity`
22
+ - `discussionId` → use for `get_activity_from_discussion`, `add_discussion_message`
23
+ </context-extraction>
24
+
25
+ <correct>
26
+ ```typescript
27
+ // Context: <incoming activityId="69384669b7826c5d9ec4e07c" discussionId="69384669b7826c5d9ec4e07d">
28
+
29
+ // ✅ CORRECT - Extract activityId from context
30
+ show_activity_by_id({
31
+ activityId: "69384669b7826c5d9ec4e07c"
32
+ });
33
+
34
+ // ✅ CORRECT - Single update mode uses activityId
35
+ update_activity({
36
+ activityId: "69384669b7826c5d9ec4e07c",
37
+ fields: { "fieldId123": 78 }
38
+ });
39
+
40
+ // ✅ CORRECT - Bulk update mode uses _id (NOT activityId)
41
+ update_activity({
42
+ activities: [{
43
+ _id: "69384669b7826c5d9ec4e07c",
44
+ fields: { "fieldId123": 78 }
45
+ }]
46
+ });
47
+
48
+ // ✅ CORRECT - numericunit field = plain number
49
+ update_activity({
50
+ activityId: "69384669b7826c5d9ec4e07c",
51
+ fields: { "weightFieldId": 78 }
52
+ });
53
+
54
+ // ✅ CORRECT - Get activity from discussion
55
+ get_activity_from_discussion({
56
+ discussionId: "69384669b7826c5d9ec4e07d"
57
+ });
58
+ ```
59
+ </correct>
60
+
61
+ <wrong>
62
+ ```typescript
63
+ // ❌ WRONG - Empty parameters (ignoring context)
64
+ show_activity_by_id({});
65
+ // Error: activityId: Required, receivedArgs={}
66
+
67
+ // ❌ WRONG - Using activityId in bulk mode (should be _id)
68
+ update_activity({
69
+ activities: [{
70
+ activityId: "69384669b7826c5d9ec4e07c", // WRONG KEY
71
+ fields: { "fieldId123": 78 }
72
+ }]
73
+ });
74
+ // Error: activities.0._id: Required
75
+
76
+ // ❌ WRONG - Passing object for numericunit field
77
+ update_activity({
78
+ activityId: "69384669b7826c5d9ec4e07c",
79
+ fields: {
80
+ "weightFieldId": { "type": "numericunit", "value": 78 } // WRONG FORMAT
81
+ }
82
+ });
83
+ // Error: "Weight" must be a number
84
+
85
+ // ❌ WRONG - Empty list_activities call
86
+ list_activities({});
87
+ // Error: workflowId: Required, phaseId: Required
88
+ ```
89
+ </wrong>
90
+
91
+ <fix>
92
+ **Before calling ANY tool:**
93
+ 1. Check `<incoming>` tag for `activityId` and `discussionId`
94
+ 2. Extract these values and pass them to tools
95
+
96
+ **Parameter rules:**
97
+ | Tool | Single mode | Bulk mode |
98
+ |------|-------------|-----------|
99
+ | `update_activity` | `activityId` | `activities[].\_id` |
100
+ | `show_activity_by_id` | `activityId` | N/A |
101
+ | `get_activity_from_discussion` | `discussionId` | N/A |
102
+
103
+ **Field value formats:**
104
+ | Field type | Value format |
105
+ |------------|--------------|
106
+ | `numericunit` | Plain number: `78` |
107
+ | `text` | Plain string: `"hello"` |
108
+ | `activitylink` | Activity ID string: `"abc123..."` |
109
+ | `select` | Option key: `"option_key"` |
110
+
111
+ **Never pass objects with `type` metadata** - Hailer API expects plain values.
112
+ </fix>
package/CLAUDE.md CHANGED
@@ -163,6 +163,7 @@ Community agents are shared via the Hailer Agent Marketplace (separate git repo)
163
163
  **Installed marketplace agents:**
164
164
  No marketplace agents installed.
165
165
 
166
+
166
167
  **Use plugin agents:**
167
168
  ```
168
169
  Task(subagent_type="plugin:agent-name", prompt="...", model="haiku|sonnet")
@@ -182,11 +183,14 @@ When user asks to install plugins or set up the marketplace:
182
183
  /plugin install <plugin-name>
183
184
  ```
184
185
 
185
- 2. Tell user: "Restart Claude Code to load the new agents."
186
+ 2. Tell user: "Restart Claude Code to load the plugin. Use `claude -c` to keep your conversation context."
186
187
 
187
- Available plugins: `permissions-handler`, `hailer-agents`
188
+ Available plugins: `permissions-handler`, `voice-notifications`
188
189
 
189
190
  After restart, sync hook updates this file automatically with installed agents.
191
+
192
+ **IMPORTANT:** After installing OR uninstalling plugins, always tell the user:
193
+ > "Restart required for changes to take effect. Run `claude -c` to restart while keeping your conversation context."
190
194
  </plugin-setup>
191
195
 
192
196
  <plugin-contributing>
@@ -0,0 +1,127 @@
1
+ # Client Refactor Status
2
+
3
+ ## Completed
4
+
5
+ ### Services Created (src/client/services/)
6
+ 1. **message-formatter.ts** - Tag formatting, mention resolution, activity linking
7
+ 2. **mcp-client.ts** - MCP server communication, tool schema loading
8
+ 3. **session-logger.ts** - Activity session tracking, idle detection, session flushing
9
+ 4. **agent-registry.ts** - Agent Directory, Positions, Teams, Tool Registry, MCP Config
10
+
11
+ ### Files Moved (src/client/agents/)
12
+ 1. **definitions.ts** (was specialists.ts) - Specialist definitions
13
+ 2. **orchestrator.ts** (was orchestrator-daemon.ts) - Updated imports ✓
14
+ 3. **specialist.ts** (was specialist-daemon.ts) - Updated imports ✓
15
+
16
+ ### Files Renamed (src/client/)
17
+ 1. **factory.ts** (was daemon-factory.ts) - Needs import updates
18
+ 2. **bot-manager.ts** (was multi-bot-manager.ts) - Needs import updates
19
+
20
+ ### Types Extracted
21
+ - **types.ts** - Already complete with all interfaces and constants
22
+
23
+ ## Remaining Work
24
+
25
+ ### 1. Create agents/base.ts
26
+ Extract from chat-agent-daemon.ts (2109 lines):
27
+ - Core LLM loop (~500 lines target)
28
+ - Message queue management
29
+ - Abstract getSystemPrompt()
30
+ - Inject services via constructor:
31
+ - MessageFormatterService
32
+ - McpClientService
33
+ - SessionLoggerService
34
+ - AgentRegistryService
35
+
36
+ ### 2. Update factory.ts imports
37
+ ```typescript
38
+ // Change:
39
+ import { ChatAgentDaemon } from "./chat-agent-daemon";
40
+ import { OrchestratorDaemon } from "./orchestrator-daemon";
41
+ import { SpecialistDaemon } from "./specialist-daemon";
42
+ import { SPECIALISTS } from "./specialists";
43
+ import { MultiBotManager, BotClient } from "./multi-bot-manager";
44
+
45
+ // To:
46
+ import { ChatAgentDaemon } from "./agents/base";
47
+ import { OrchestratorDaemon } from "./agents/orchestrator";
48
+ import { SpecialistDaemon } from "./agents/specialist";
49
+ import { SPECIALISTS } from "./agents/definitions";
50
+ import { MultiBotManager, BotClient } from "./bot-manager";
51
+ ```
52
+
53
+ ### 3. Create index.ts (public exports)
54
+ ```typescript
55
+ export * from "./types";
56
+ export * from "./bot-manager";
57
+ export * from "./factory";
58
+ export * from "./agents/base";
59
+ export * from "./agents/orchestrator";
60
+ export * from "./agents/specialist";
61
+ export * from "./agents/definitions";
62
+ export * from "./services/message-formatter";
63
+ export * from "./services/mcp-client";
64
+ export * from "./services/session-logger";
65
+ export * from "./services/agent-registry";
66
+ ```
67
+
68
+ ### 4. Update all imports in codebase
69
+ Files that import from src/client/:
70
+ - src/core.ts
71
+ - src/config.ts
72
+ - Any test files
73
+
74
+ ### 5. Delete old files
75
+ After verifying build:
76
+ - src/client/chat-agent-daemon.ts (replaced by agents/base.ts)
77
+
78
+ ### 6. Verify build
79
+ ```bash
80
+ npm run build
81
+ ```
82
+
83
+ ## Architecture
84
+
85
+ ### Before
86
+ ```
87
+ src/client/
88
+ ├── chat-agent-daemon.ts (2109 lines - BLOATED)
89
+ ├── orchestrator-daemon.ts
90
+ ├── specialist-daemon.ts
91
+ ├── specialists.ts
92
+ ├── daemon-factory.ts
93
+ ├── multi-bot-manager.ts
94
+ └── types.ts
95
+ ```
96
+
97
+ ### After
98
+ ```
99
+ src/client/
100
+ ├── index.ts # Public exports
101
+ ├── factory.ts # DaemonManager
102
+ ├── bot-manager.ts # MultiBotManager
103
+ ├── types.ts # All interfaces
104
+
105
+ ├── agents/
106
+ │ ├── base.ts # Core LLM loop (~500 lines)
107
+ │ ├── orchestrator.ts # HAL orchestrator ✓
108
+ │ ├── specialist.ts # Domain experts ✓
109
+ │ └── definitions.ts # SPECIALISTS config ✓
110
+
111
+ └── services/
112
+ ├── message-formatter.ts # Tags, mentions, links ✓
113
+ ├── mcp-client.ts # Tool calling ✓
114
+ ├── session-logger.ts # Session logging ✓
115
+ └── agent-registry.ts # Agent Directory registration ✓
116
+ ```
117
+
118
+ ## Next Steps
119
+
120
+ 1. Create agents/base.ts with service injection
121
+ 2. Update factory.ts imports
122
+ 3. Update bot-manager.ts imports (if any internal references)
123
+ 4. Create index.ts
124
+ 5. Update imports in src/core.ts and other files
125
+ 6. Run npm run build
126
+ 7. Delete chat-agent-daemon.ts
127
+ 8. Test the refactored code
package/dist/cli.js CHANGED
File without changes
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Chat Agent Daemon
3
+ *
4
+ * A persistent LLM conversation that monitors all workspace chats.
5
+ * The LLM maintains context across messages and decides what to respond to.
6
+ *
7
+ * Architecture:
8
+ * - One daemon per bot client
9
+ * - Subscribes to ALL messenger.new signals (not filtered)
10
+ * - LLM sees every message with priority markers
11
+ * - LLM decides: RESPOND / IGNORE / ACTION
12
+ */
13
+ import Anthropic from "@anthropic-ai/sdk";
14
+ import { BotClient } from "../bot-manager";
15
+ import { HailerSignal } from "../../mcp/signal-handler";
16
+ import { Logger } from "../../lib/logger";
17
+ import { ToolSchemaLoader, ToolIndexEntry } from "../tool-schema-loader";
18
+ import { ToolInput, McpToolResult } from "../types";
19
+ import { AgentRegistryService } from "../services/agent-registry";
20
+ import { ConversationManager, ConversationMessage } from "../services/conversation-manager";
21
+ import { McpClientService } from "../services/mcp-client";
22
+ import { MessageFormatterService } from "../services/message-formatter";
23
+ import { MessageClassifier } from "../services/message-classifier";
24
+ import { SessionLoggerService } from "../services/session-logger";
25
+ import { ToolExecutor } from "../services/tool-executor";
26
+ import { WorkspaceSchemaCacheService } from "../services/workspace-schema-cache";
27
+ import { SessionMetrics, ActivitySession, MessagePriority, IncomingMessage, ConversationState } from "../types";
28
+ export type { IncomingMessage, MessagePriority, SessionMetrics, ActivitySession };
29
+ export interface ChatAgentDaemonConfig {
30
+ botClient: BotClient;
31
+ mcpServerUrl: string;
32
+ anthropicApiKey: string;
33
+ model?: string;
34
+ maxContextMessages?: number;
35
+ }
36
+ export declare class ChatAgentDaemon {
37
+ protected logger: Logger;
38
+ protected client: Anthropic;
39
+ protected botClient: BotClient;
40
+ protected config: ChatAgentDaemonConfig;
41
+ protected toolSchemaLoader: ToolSchemaLoader;
42
+ protected isProcessing: boolean;
43
+ protected messageQueue: IncomingMessage[];
44
+ protected processedMessageIds: Set<string>;
45
+ private typingInterval;
46
+ private typingDiscussionId;
47
+ private static TYPING_REFRESH_MS;
48
+ protected toolIndex: ToolIndexEntry[];
49
+ protected minimalTools: Anthropic.Tool[];
50
+ /** Message classifier - handles message extraction and priority classification */
51
+ protected messageClassifier: MessageClassifier | null;
52
+ /** Conversation manager - handles per-discussion context and LRU cache */
53
+ protected conversationManager: ConversationManager | null;
54
+ /** MCP client service - handles tool schema loading and execution */
55
+ protected mcpClient: McpClientService | null;
56
+ /** Tool executor - handles tool execution and write tracking */
57
+ protected toolExecutor: ToolExecutor | null;
58
+ /** Agent registration service - handles Agent Directory, Position, Team, etc. */
59
+ protected registryService: AgentRegistryService | null;
60
+ /** Message formatting service - handles tag resolution and formatting */
61
+ protected messageFormatter: MessageFormatterService | null;
62
+ /** Session logging service - handles activity session tracking */
63
+ protected sessionLogger: SessionLoggerService | null;
64
+ /** Workspace schema cache - dynamic workflow/field ID lookup */
65
+ protected schemaCache: WorkspaceSchemaCacheService | null;
66
+ /** Current discussion context for tracking */
67
+ protected currentDiscussionId: string | null;
68
+ protected currentLinkedActivityId: string | null;
69
+ constructor(config: ChatAgentDaemonConfig);
70
+ /**
71
+ * Initialize the daemon - load tools and subscribe to signals
72
+ */
73
+ initialize(): Promise<void>;
74
+ /**
75
+ * Extract and classify incoming message from signal
76
+ * Can be overridden in subclasses to customize filtering
77
+ */
78
+ protected extractIncomingMessage(signal: HailerSignal): Promise<IncomingMessage | null>;
79
+ /**
80
+ * Handle incoming signal from Hailer
81
+ */
82
+ private handleSignal;
83
+ /**
84
+ * Process queued messages through the LLM
85
+ * Note: Uses flag-first pattern to prevent race conditions
86
+ */
87
+ private processQueue;
88
+ /**
89
+ * Process a single message through the persistent LLM conversation
90
+ */
91
+ private processMessage;
92
+ /**
93
+ * Format incoming message for LLM consumption
94
+ */
95
+ private formatIncomingMessage;
96
+ /**
97
+ * Load and inject memory for an activity into conversation context
98
+ * Called when entering a new discussion that's linked to an activity
99
+ */
100
+ private injectMemoryForActivity;
101
+ /**
102
+ * Execute tool calls and continue the conversation
103
+ * Simple passthrough - just execute tools and return results to LLM
104
+ */
105
+ protected executeToolsAndContinue(toolUseBlocks: Anthropic.ToolUseBlock[], originalMessage: IncomingMessage): Promise<void>;
106
+ /**
107
+ * Handle LLM response
108
+ * Override in subclasses to customize response handling
109
+ */
110
+ protected handleLlmResponse(response: Anthropic.Message, originalMessage: IncomingMessage): Promise<void>;
111
+ /**
112
+ * Start typing indicator with auto-refresh interval
113
+ * Keeps refreshing every 3 seconds until stopTypingIndicator is called
114
+ */
115
+ protected startTypingIndicator(discussionId: string): void;
116
+ /**
117
+ * Stop typing indicator and clear refresh interval
118
+ */
119
+ protected stopTypingIndicator(): void;
120
+ /**
121
+ * Send typing signal to Hailer API
122
+ * API: messenger.set_discussion_typing_state(discussionId, typingState)
123
+ */
124
+ private sendTypingSignal;
125
+ /**
126
+ * Post a response to a discussion
127
+ * Automatically converts @mentions and #activity tags to Hailer tags
128
+ * Includes links metadata required for tags to work
129
+ */
130
+ protected postResponse(discussionId: string, content: string): Promise<void>;
131
+ /**
132
+ * Get the system prompt for the daemon
133
+ * MUST be overridden in subclasses
134
+ */
135
+ protected getSystemPrompt(): string;
136
+ /**
137
+ * Get tool whitelist for this agent
138
+ * Override in subclass to limit which tools are available
139
+ * Return null for all tools, or array of tool names
140
+ */
141
+ protected getToolWhitelist(): string[] | null;
142
+ /**
143
+ * Preprocess tool input before execution
144
+ * Override in subclass to inject context (e.g., sourceActivityId)
145
+ * @param toolName - Name of the tool being called
146
+ * @param input - Original tool input from LLM
147
+ * @returns Processed input (may be modified)
148
+ */
149
+ protected preprocessToolInput(toolName: string, input: ToolInput): ToolInput;
150
+ /**
151
+ * Call MCP tool (delegates to McpClientService)
152
+ * Protected for subclass access
153
+ */
154
+ protected callMcpTool(name: string, args: ToolInput): Promise<McpToolResult>;
155
+ /**
156
+ * Stop the daemon
157
+ * Flushes all pending activity sessions before stopping
158
+ */
159
+ stop(): Promise<void>;
160
+ /**
161
+ * Get current conversation state (for debugging)
162
+ */
163
+ getConversationState(): ConversationState;
164
+ /**
165
+ * Get full conversation for a specific discussion (for debugging)
166
+ */
167
+ getFullConversation(discussionId?: string): ConversationMessage[];
168
+ /**
169
+ * Get agent's display name (override in subclass for custom names)
170
+ * Default implementation uses the actual Hailer user name from BotClient
171
+ */
172
+ protected getAgentName(): {
173
+ firstName: string;
174
+ lastName: string;
175
+ };
176
+ /**
177
+ * Get agent's description/system prompt (override in subclass)
178
+ */
179
+ protected getAgentDescription(): string;
180
+ /**
181
+ * Get default team ID from workspace cache
182
+ * Returns the first available team, or undefined if no teams exist
183
+ *
184
+ * Teams structure in init is: { teams: { workspaceId: { teamId: teamData, ... } } }
185
+ */
186
+ protected getDefaultTeamId(): string | undefined;
187
+ /**
188
+ * Get agent's Position details (override in subclass for custom positions)
189
+ */
190
+ protected getPositionDetails(): {
191
+ name: string;
192
+ purpose: string;
193
+ personaTone: string;
194
+ coreCapabilities: string;
195
+ boundaries: string;
196
+ };
197
+ /**
198
+ * Get agent directory ID
199
+ */
200
+ getAgentDirectoryId(): string | null;
201
+ }
202
+ //# sourceMappingURL=base.d.ts.map