@hailer/mcp 0.1.2 → 0.1.4
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/agents/ada.md +71 -112
- package/.claude/agents/agent-builder.md +69 -136
- package/.claude/agents/alejandro.md +38 -52
- package/.claude/agents/bjorn.md +49 -300
- package/.claude/agents/dmitri.md +31 -50
- package/.claude/agents/giuseppe.md +45 -54
- package/.claude/agents/gunther.md +63 -350
- package/.claude/agents/helga.md +48 -91
- package/.claude/agents/ingrid.md +48 -99
- package/.claude/agents/kenji.md +44 -52
- package/.claude/agents/svetlana.md +53 -389
- package/.claude/agents/viktor.md +41 -51
- package/.claude/agents/yevgeni.md +27 -48
- package/.claude/assistant-knowledge.md +23 -0
- package/.claude/hooks/agent-failure-detector.cjs +27 -3
- package/.claude/hooks/app-edit-guard.cjs +33 -10
- package/.claude/hooks/builder-mode-manager.cjs +237 -0
- package/.claude/hooks/interactive-mode.cjs +29 -3
- package/.claude/hooks/mcp-server-guard.cjs +20 -4
- package/.claude/hooks/post-scaffold-hook.cjs +23 -4
- package/.claude/hooks/publish-template-guard.cjs +29 -11
- package/.claude/hooks/src-edit-guard.cjs +30 -6
- package/.claude/settings.json +13 -3
- package/.claude/skills/insight-join-patterns/SKILL.md +50 -88
- package/.claude/skills/json-only-output/SKILL.md +32 -0
- package/.claude/skills/optional-parameters/SKILL.md +63 -0
- package/.claude/skills/tool-response-verification/SKILL.md +58 -0
- package/CLAUDE.md +114 -111
- package/dist/client/mcp-assistant.d.ts +21 -0
- package/dist/client/mcp-assistant.js +58 -0
- package/dist/client/mcp-client.js +8 -2
- package/dist/client/providers/assistant-provider.d.ts +17 -0
- package/dist/client/providers/assistant-provider.js +51 -0
- package/dist/client/providers/openai-provider.js +10 -1
- package/dist/client/tool-schema-loader.d.ts +1 -0
- package/dist/client/tool-schema-loader.js +9 -1
- package/dist/client/types.d.ts +2 -1
- package/dist/config.d.ts +5 -1
- package/dist/config.js +11 -5
- package/mcp-system-prompt.txt +127 -0
- package/package.json +1 -1
- package/.claude/hooks/sdk-delete-guard.cjs +0 -119
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
name: insight-join-patterns
|
|
3
|
+
description: Correct JOIN syntax for Hailer insights with ActivityLink fields
|
|
4
|
+
triggers: JOIN query errors, missing columns, NULL results in insight queries
|
|
5
|
+
---
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
<problem>
|
|
4
8
|
When joining workflows with ActivityLink fields in Hailer insights, you must:
|
|
5
9
|
1. Include `_id` meta field in BOTH source definitions
|
|
6
10
|
2. Join ON the activitylink field value equals target _id
|
|
7
11
|
3. Use the activitylink fieldId (NOT the key) for the JOIN condition
|
|
12
|
+
</problem>
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
**Always Required:**
|
|
14
|
+
<rules>
|
|
12
15
|
- Both workflows need `{ name: 'id', meta: '_id' }` in their fields array
|
|
13
16
|
- JOIN condition: `source1.activityLinkFieldName = source2.id`
|
|
14
17
|
- Use LEFT JOIN for optional relationships (activitylink can be null)
|
|
15
18
|
- Use INNER JOIN only when relationship must exist
|
|
19
|
+
</rules>
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
### Basic ActivityLink JOIN
|
|
21
|
+
<correct>
|
|
20
22
|
```javascript
|
|
21
23
|
// Players workflow has "club" field (activitylink to Clubs workflow)
|
|
22
24
|
{
|
|
@@ -42,7 +44,38 @@ When joining workflows with ActivityLink fields in Hailer insights, you must:
|
|
|
42
44
|
query: 'SELECT p.player_name, c.club_name FROM p LEFT JOIN c ON p.club = c.id'
|
|
43
45
|
}
|
|
44
46
|
```
|
|
47
|
+
</correct>
|
|
48
|
+
|
|
49
|
+
<wrong>
|
|
50
|
+
```javascript
|
|
51
|
+
// ❌ WRONG - Missing _id in clubs source
|
|
52
|
+
{
|
|
53
|
+
sources: [
|
|
54
|
+
{
|
|
55
|
+
name: 'p',
|
|
56
|
+
workflowId: 'players-id',
|
|
57
|
+
fields: [
|
|
58
|
+
{ name: 'player_name', meta: 'name' },
|
|
59
|
+
{ name: 'id', meta: '_id' },
|
|
60
|
+
{ name: 'club', fieldId: 'club-field-id' }
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'c',
|
|
65
|
+
workflowId: 'clubs-id',
|
|
66
|
+
fields: [
|
|
67
|
+
{ name: 'club_name', meta: 'name' }
|
|
68
|
+
// Missing: { name: 'id', meta: '_id' }
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
query: 'SELECT p.player_name, c.club_name FROM p LEFT JOIN c ON p.club = c.id'
|
|
73
|
+
}
|
|
74
|
+
// Error: "no such column: c.id"
|
|
75
|
+
```
|
|
76
|
+
</wrong>
|
|
45
77
|
|
|
78
|
+
<examples>
|
|
46
79
|
### Three-Way JOIN (Tasks -> Topics -> Projects)
|
|
47
80
|
```javascript
|
|
48
81
|
{
|
|
@@ -53,7 +86,7 @@ When joining workflows with ActivityLink fields in Hailer insights, you must:
|
|
|
53
86
|
fields: [
|
|
54
87
|
{ name: 'task_name', meta: 'name' },
|
|
55
88
|
{ name: 'id', meta: '_id' },
|
|
56
|
-
{ name: 'topic', fieldId: 'topic-field-id' }
|
|
89
|
+
{ name: 'topic', fieldId: 'topic-field-id' }
|
|
57
90
|
]
|
|
58
91
|
},
|
|
59
92
|
{
|
|
@@ -62,7 +95,7 @@ When joining workflows with ActivityLink fields in Hailer insights, you must:
|
|
|
62
95
|
fields: [
|
|
63
96
|
{ name: 'topic_name', meta: 'name' },
|
|
64
97
|
{ name: 'id', meta: '_id' },
|
|
65
|
-
{ name: 'project', fieldId: 'project-field-id' }
|
|
98
|
+
{ name: 'project', fieldId: 'project-field-id' }
|
|
66
99
|
]
|
|
67
100
|
},
|
|
68
101
|
{
|
|
@@ -75,10 +108,7 @@ When joining workflows with ActivityLink fields in Hailer insights, you must:
|
|
|
75
108
|
}
|
|
76
109
|
],
|
|
77
110
|
query: `
|
|
78
|
-
SELECT
|
|
79
|
-
t.task_name,
|
|
80
|
-
top.topic_name,
|
|
81
|
-
p.project_name
|
|
111
|
+
SELECT t.task_name, top.topic_name, p.project_name
|
|
82
112
|
FROM t
|
|
83
113
|
LEFT JOIN top ON t.topic = top.id
|
|
84
114
|
LEFT JOIN p ON top.project = p.id
|
|
@@ -109,76 +139,16 @@ When joining workflows with ActivityLink fields in Hailer insights, you must:
|
|
|
109
139
|
}
|
|
110
140
|
],
|
|
111
141
|
query: `
|
|
112
|
-
SELECT
|
|
113
|
-
teams.team_name,
|
|
114
|
-
COUNT(*) as match_count
|
|
142
|
+
SELECT teams.team_name, COUNT(*) as match_count
|
|
115
143
|
FROM matches
|
|
116
144
|
LEFT JOIN teams ON matches.home_team = teams.id
|
|
117
145
|
GROUP BY teams.team_name
|
|
118
146
|
`
|
|
119
147
|
}
|
|
120
148
|
```
|
|
149
|
+
</examples>
|
|
121
150
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
### Missing _id Field
|
|
125
|
-
```javascript
|
|
126
|
-
// ❌ WRONG - Missing _id in clubs source
|
|
127
|
-
{
|
|
128
|
-
sources: [
|
|
129
|
-
{
|
|
130
|
-
name: 'p',
|
|
131
|
-
workflowId: 'players-id',
|
|
132
|
-
fields: [
|
|
133
|
-
{ name: 'player_name', meta: 'name' },
|
|
134
|
-
{ name: 'id', meta: '_id' },
|
|
135
|
-
{ name: 'club', fieldId: 'club-field-id' }
|
|
136
|
-
]
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
name: 'c',
|
|
140
|
-
workflowId: 'clubs-id',
|
|
141
|
-
fields: [
|
|
142
|
-
{ name: 'club_name', meta: 'name' }
|
|
143
|
-
// Missing: { name: 'id', meta: '_id' }
|
|
144
|
-
]
|
|
145
|
-
}
|
|
146
|
-
],
|
|
147
|
-
query: 'SELECT p.player_name, c.club_name FROM p LEFT JOIN c ON p.club = c.id'
|
|
148
|
-
}
|
|
149
|
-
// Error: "no such column: c.id"
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Using Key Instead of FieldId
|
|
153
|
-
```javascript
|
|
154
|
-
// ❌ WRONG - Using field key instead of fieldId
|
|
155
|
-
{
|
|
156
|
-
sources: [
|
|
157
|
-
{
|
|
158
|
-
name: 'p',
|
|
159
|
-
workflowId: 'players-id',
|
|
160
|
-
fields: [
|
|
161
|
-
{ name: 'player_name', meta: 'name' },
|
|
162
|
-
{ name: 'id', meta: '_id' },
|
|
163
|
-
{ name: 'club', key: 'club' } // Wrong! Use fieldId
|
|
164
|
-
]
|
|
165
|
-
}
|
|
166
|
-
]
|
|
167
|
-
}
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Wrong JOIN Syntax
|
|
171
|
-
```javascript
|
|
172
|
-
// ❌ WRONG - Trying to join on name instead of id
|
|
173
|
-
query: 'SELECT p.player_name, c.club_name FROM p LEFT JOIN c ON p.club = c.club_name'
|
|
174
|
-
|
|
175
|
-
// ❌ WRONG - Using field key in JOIN instead of column name
|
|
176
|
-
query: 'SELECT p.player_name, c.club_name FROM p LEFT JOIN c ON p.clubId = c.id'
|
|
177
|
-
// (Should use column name from sources definition: p.club = c.id)
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## Troubleshooting
|
|
181
|
-
|
|
151
|
+
<troubleshooting>
|
|
182
152
|
**Error: "no such column: c.id"**
|
|
183
153
|
- Missing `{ name: 'id', meta: '_id' }` in target workflow source
|
|
184
154
|
|
|
@@ -189,21 +159,13 @@ query: 'SELECT p.player_name, c.club_name FROM p LEFT JOIN c ON p.clubId = c.id'
|
|
|
189
159
|
**NULL results for joined data**
|
|
190
160
|
- ActivityLink field is empty/null for some activities (expected with LEFT JOIN)
|
|
191
161
|
- Use INNER JOIN if you only want activities with relationships
|
|
162
|
+
</troubleshooting>
|
|
192
163
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
1. Get schema: `get_workflow_schema({ workflowId, phaseId })`
|
|
196
|
-
2. Find ActivityLink field ID and target workflow ID
|
|
197
|
-
3. Build sources with BOTH _id fields
|
|
198
|
-
4. Preview query: `preview_insight({ sources, query })`
|
|
199
|
-
5. Fix errors, re-preview
|
|
200
|
-
6. Create insight when preview succeeds
|
|
201
|
-
|
|
202
|
-
## Quick Checklist
|
|
203
|
-
|
|
164
|
+
<checklist>
|
|
204
165
|
Before creating an insight with JOINs:
|
|
205
166
|
- [ ] Both workflow sources include `{ name: 'id', meta: '_id' }`
|
|
206
167
|
- [ ] ActivityLink field uses `fieldId` (NOT `key`)
|
|
207
168
|
- [ ] JOIN condition uses column names from sources (e.g., `p.club = c.id`)
|
|
208
169
|
- [ ] Using LEFT JOIN (unless relationship required)
|
|
209
170
|
- [ ] Tested with `preview_insight` first
|
|
171
|
+
</checklist>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: json-only-output
|
|
3
|
+
description: Fix agents adding prose after JSON responses
|
|
4
|
+
triggers: Agent outputs explanation text after valid JSON
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<problem>
|
|
8
|
+
Agents violate JSON-only protocol by adding prose explanations AFTER their JSON response.
|
|
9
|
+
</problem>
|
|
10
|
+
|
|
11
|
+
<correct>
|
|
12
|
+
```json
|
|
13
|
+
{"status":"success","result":{"fields":["taskName","priority"]},"summary":"Read 2 fields"}
|
|
14
|
+
```
|
|
15
|
+
**STOP HERE. Nothing after closing brace.**
|
|
16
|
+
</correct>
|
|
17
|
+
|
|
18
|
+
<wrong>
|
|
19
|
+
```json
|
|
20
|
+
{"status":"success","result":{"fields":["taskName","priority"]},"summary":"Read 2 fields"}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The workflow has 2 fields defined in workspace/Tasks_123/fields.ts. You can now use these field IDs with dmitri for activity creation.
|
|
24
|
+
|
|
25
|
+
**Action Required**: Run `npm run pull` to refresh.
|
|
26
|
+
</wrong>
|
|
27
|
+
|
|
28
|
+
<fix>
|
|
29
|
+
1. Add to `<identity>`: "Output JSON. Full stop."
|
|
30
|
+
2. Add to `<rules>`: **JSON ONLY** - Output closing brace, then STOP. Zero prose after JSON.
|
|
31
|
+
3. Protocol section is NOT enough - agents ignore it without identity/rules reinforcement.
|
|
32
|
+
</fix>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: optional-parameters
|
|
3
|
+
description: Omit optional parameters instead of passing empty values
|
|
4
|
+
triggers: Tool error about empty array/string when parameter should be omitted
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<problem>
|
|
8
|
+
Tool parameter is required in schema but should be OMITTED (not passed at all) when not needed, rather than passed as empty array/string.
|
|
9
|
+
</problem>
|
|
10
|
+
|
|
11
|
+
<correct>
|
|
12
|
+
```typescript
|
|
13
|
+
// Update insight - only changing public flag
|
|
14
|
+
// sources parameter exists in schema but NOT needed for this update
|
|
15
|
+
update_insight({
|
|
16
|
+
insightId: "abc123",
|
|
17
|
+
public: false
|
|
18
|
+
// sources: NOT included - omit entirely
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Update insight - changing sources
|
|
22
|
+
update_insight({
|
|
23
|
+
insightId: "abc123",
|
|
24
|
+
sources: [{
|
|
25
|
+
name: 'tasks',
|
|
26
|
+
workflowId: 'wf123',
|
|
27
|
+
fields: [{ name: 'title', meta: 'name' }]
|
|
28
|
+
}]
|
|
29
|
+
// Include sources when actually updating them
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
</correct>
|
|
33
|
+
|
|
34
|
+
<wrong>
|
|
35
|
+
```typescript
|
|
36
|
+
// ❌ WRONG - Passing empty array when parameter should be omitted
|
|
37
|
+
update_insight({
|
|
38
|
+
insightId: "abc123",
|
|
39
|
+
public: false,
|
|
40
|
+
sources: [] // Error: sources must contain at least 1 items
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// ❌ WRONG - Passing empty string
|
|
44
|
+
update_activity({
|
|
45
|
+
activityId: "xyz",
|
|
46
|
+
name: "" // Error: name cannot be empty
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
</wrong>
|
|
50
|
+
|
|
51
|
+
<fix>
|
|
52
|
+
**Key distinction:**
|
|
53
|
+
- **OMIT parameter**: Don't include it in the function call at all
|
|
54
|
+
- **NOT same as empty value**: `[]`, `""`, `null`, `undefined` are NOT valid replacements for omission
|
|
55
|
+
|
|
56
|
+
**When to omit:**
|
|
57
|
+
- Updating insight public/name but NOT sources → omit sources
|
|
58
|
+
- Updating activity field but NOT name → omit name
|
|
59
|
+
- Any "required" schema parameter that's not relevant to current operation
|
|
60
|
+
|
|
61
|
+
**Rule of thumb:**
|
|
62
|
+
If you're not changing/using a value, OMIT the parameter entirely rather than passing empty/null.
|
|
63
|
+
</fix>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tool-response-verification
|
|
3
|
+
description: Ensure agents verify tool execution before claiming success
|
|
4
|
+
triggers: Agent returns success without checking tool result
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<problem>
|
|
8
|
+
Agent fabricates success response without verifying actual tool execution result.
|
|
9
|
+
</problem>
|
|
10
|
+
|
|
11
|
+
<correct>
|
|
12
|
+
```typescript
|
|
13
|
+
// Call tool
|
|
14
|
+
const result = await update_insight({
|
|
15
|
+
insightId: "abc123",
|
|
16
|
+
public: false
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Verify tool response before returning to orchestrator
|
|
20
|
+
if (result.error) {
|
|
21
|
+
return {
|
|
22
|
+
status: "error",
|
|
23
|
+
error: result.error,
|
|
24
|
+
summary: "Update failed"
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
status: "success",
|
|
30
|
+
result: { updated: true, insight_id: result.id },
|
|
31
|
+
summary: "Updated insight"
|
|
32
|
+
};
|
|
33
|
+
```
|
|
34
|
+
</correct>
|
|
35
|
+
|
|
36
|
+
<wrong>
|
|
37
|
+
```typescript
|
|
38
|
+
// Call tool (that might fail)
|
|
39
|
+
update_insight({ insightId: "abc123", public: false });
|
|
40
|
+
|
|
41
|
+
// Immediately return success WITHOUT checking tool result
|
|
42
|
+
return {
|
|
43
|
+
status: "success",
|
|
44
|
+
result: { updated: true },
|
|
45
|
+
summary: "Updated insight"
|
|
46
|
+
};
|
|
47
|
+
```
|
|
48
|
+
</wrong>
|
|
49
|
+
|
|
50
|
+
<fix>
|
|
51
|
+
1. **NEVER assume tool success** - Always capture and check tool response
|
|
52
|
+
2. **Return actual error messages** - If tool fails, return error status with real error message
|
|
53
|
+
3. **Verify before claiming success** - Only return success after confirming tool execution succeeded
|
|
54
|
+
4. **Test error paths** - If unsure about tool behavior, preview/test first
|
|
55
|
+
|
|
56
|
+
This is a violation of Rule 1: "NEVER FABRICATE - Must call tools."
|
|
57
|
+
Fabricating a success response when tool failed is the same as not calling the tool.
|
|
58
|
+
</fix>
|
package/CLAUDE.md
CHANGED
|
@@ -2,163 +2,166 @@
|
|
|
2
2
|
|
|
3
3
|
MCP tools for Hailer workspaces: workflows, activities, insights, and apps.
|
|
4
4
|
|
|
5
|
-
**Core features:**
|
|
6
|
-
- MCP Tools: Direct Hailer API access
|
|
7
|
-
- Local Config: Synced workspace in `workspace/` directory
|
|
8
|
-
- Type Generation: TypeScript enums for IDs
|
|
9
|
-
|
|
10
5
|
---
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Ships with pre-configured agents. **These are defaults - modify, replace, or remove them.**
|
|
15
|
-
|
|
16
|
-
| Action | How |
|
|
17
|
-
|--------|-----|
|
|
18
|
-
| Create custom | `agent-builder` or add to `.claude/agents/` |
|
|
19
|
-
| Modify defaults | Edit `.claude/agents/*.md` |
|
|
20
|
-
| Disable agents | Move to `docs/agents/`, update this file |
|
|
21
|
-
|
|
22
|
-
## You Are The Orchestrator
|
|
7
|
+
<identity>
|
|
8
|
+
YOU ARE THE ORCHESTRATOR.
|
|
23
9
|
|
|
24
|
-
|
|
10
|
+
You route tasks to specialized agents. You run commands they return. You summarize results for users.
|
|
25
11
|
|
|
26
|
-
|
|
27
|
-
|
|
12
|
+
NEVER forget: You delegate, agents execute, you report back.
|
|
13
|
+
</identity>
|
|
28
14
|
|
|
29
|
-
|
|
15
|
+
<orchestrator-rules>
|
|
16
|
+
DO DIRECTLY: Answer from context, summarize agent results, run push/sync commands
|
|
17
|
+
DELEGATE TO AGENTS: File reads, API calls, data creation/updates, complex reasoning
|
|
30
18
|
|
|
31
|
-
|
|
19
|
+
Agents return JSON. You interpret it for the user.
|
|
20
|
+
</orchestrator-rules>
|
|
32
21
|
|
|
22
|
+
<agents>
|
|
33
23
|
| Pattern | Agent | Model |
|
|
34
24
|
|---------|-------|-------|
|
|
35
|
-
| Read data/schema | `kenji` |
|
|
36
|
-
| Activity CRUD | `dmitri` |
|
|
37
|
-
| Discussions/chat | `yevgeni` |
|
|
38
|
-
| Config audit | `bjorn` |
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
25
|
+
| Read data/schema | `kenji` | haiku |
|
|
26
|
+
| Activity CRUD | `dmitri` | haiku |
|
|
27
|
+
| Discussions/chat | `yevgeni` | haiku |
|
|
28
|
+
| Config audit | `bjorn` | haiku |
|
|
29
|
+
| Workflows, fields, phases | `helga` | sonnet |
|
|
30
|
+
| SQL insights | `viktor` | sonnet |
|
|
31
|
+
| Function fields | `alejandro` | sonnet |
|
|
32
|
+
| MCP tools | `gunther` | sonnet |
|
|
33
|
+
| Hailer apps | `giuseppe` | sonnet |
|
|
34
|
+
| Code review | `svetlana` | sonnet |
|
|
35
|
+
| New agents | `agent-builder` | sonnet |
|
|
36
|
+
| Skills, agent improvements | `ada` | sonnet |
|
|
37
|
+
| Document templates | `ingrid` | sonnet |
|
|
38
|
+
</agents>
|
|
39
|
+
|
|
40
|
+
<delegation-protocol>
|
|
52
41
|
```
|
|
53
|
-
Task(subagent_type="agent-name", prompt="JSON task spec", model="haiku")
|
|
42
|
+
Task(subagent_type="agent-name", prompt="JSON task spec", model="haiku|sonnet")
|
|
54
43
|
```
|
|
55
44
|
|
|
56
|
-
|
|
45
|
+
INPUT:
|
|
57
46
|
```json
|
|
58
|
-
{ "task": "action", "context": { "workflow_id": "...", "field_ids": {} }, "
|
|
47
|
+
{ "task": "action", "context": { "workflow_id": "...", "field_ids": {} }, "output": [] }
|
|
59
48
|
```
|
|
60
49
|
|
|
61
|
-
|
|
50
|
+
OUTPUT (JSON only, no prose):
|
|
62
51
|
```json
|
|
63
|
-
{ "status": "success", "result": {}, "summary": "max 50 chars" }
|
|
52
|
+
{ "status": "success|error|ready_to_push|needs_confirmation", "result": {}, "summary": "max 50 chars" }
|
|
64
53
|
```
|
|
65
54
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
## Handling Push/Sync Commands
|
|
69
|
-
|
|
70
|
-
**Safety hooks only trigger for YOUR (Claude Code) tool calls, not subagent tool calls.**
|
|
55
|
+
FLOW: Get IDs first (kenji) → pass to execution agents (dmitri, helga, etc.)
|
|
56
|
+
</delegation-protocol>
|
|
71
57
|
|
|
58
|
+
<push-commands>
|
|
72
59
|
When agents return `"status": "ready_to_push"`:
|
|
73
|
-
|
|
74
60
|
```json
|
|
75
61
|
{ "status": "ready_to_push", "commands": ["npm run fields-push"], "summary": "..." }
|
|
76
62
|
```
|
|
77
63
|
|
|
78
|
-
|
|
64
|
+
YOU run these commands via Bash tool. This triggers safety hooks.
|
|
65
|
+
Do NOT ask user to run them manually.
|
|
66
|
+
</push-commands>
|
|
79
67
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
68
|
+
<needs-confirmation>
|
|
69
|
+
When agents return `"status": "needs_confirmation"`:
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"status": "needs_confirmation",
|
|
73
|
+
"result": {
|
|
74
|
+
"pending_command": "npm run fields-push",
|
|
75
|
+
"safe_command": "yes | npm run fields-push",
|
|
76
|
+
"reason": "May delete resources"
|
|
77
|
+
},
|
|
78
|
+
"summary": "Needs user confirmation"
|
|
79
|
+
}
|
|
80
|
+
```
|
|
93
81
|
|
|
94
|
-
|
|
82
|
+
YOU must:
|
|
83
|
+
1. Use AskUserQuestion to confirm with user
|
|
84
|
+
2. If confirmed: run the `safe_command` via Bash
|
|
85
|
+
3. If declined: report cancellation to user
|
|
86
|
+
</needs-confirmation>
|
|
95
87
|
|
|
96
88
|
---
|
|
97
89
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
**Check local files BEFORE API calls.**
|
|
90
|
+
<local-first>
|
|
91
|
+
Check workspace/ BEFORE API calls.
|
|
101
92
|
|
|
102
|
-
After `npm run pull`:
|
|
103
93
|
```
|
|
104
94
|
workspace/
|
|
105
|
-
├── workflows.ts
|
|
106
|
-
├── enums.ts # Type-safe ID constants
|
|
107
|
-
├── teams.ts, groups.ts # Team/group definitions
|
|
95
|
+
├── workflows.ts, enums.ts, teams.ts, groups.ts
|
|
108
96
|
└── [Workflow]_[id]/
|
|
109
|
-
├── fields.ts
|
|
110
|
-
└── phases.ts
|
|
97
|
+
├── fields.ts
|
|
98
|
+
└── phases.ts
|
|
111
99
|
```
|
|
112
100
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
| Workflow/field/phase IDs | Activity data (live) |
|
|
116
|
-
| Field types, labels, options | Activity counts |
|
|
117
|
-
| Team/group definitions | Discussion messages |
|
|
101
|
+
LOCAL: Workflow/field/phase IDs, field types, labels, options
|
|
102
|
+
API: Activity data, counts, discussion messages
|
|
118
103
|
|
|
119
|
-
|
|
104
|
+
REFRESH: `npm run pull`
|
|
105
|
+
</local-first>
|
|
120
106
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
107
|
+
<safety>
|
|
108
|
+
PROTECTED (hooks confirm): npm run push, *-push, *-sync
|
|
109
|
+
SAFE: npm run pull, npm run generate
|
|
110
|
+
</safety>
|
|
124
111
|
|
|
125
|
-
|
|
126
|
-
**Safe:** `npm run pull`, `npm run generate`
|
|
112
|
+
---
|
|
127
113
|
|
|
114
|
+
<agent-structure>
|
|
115
|
+
```markdown
|
|
116
|
+
---
|
|
117
|
+
name: lowercase-name
|
|
118
|
+
description: What it does.\n\n<example>\nuser: "request"\nassistant: { "status": "success", "result": {}, "summary": "" }\n</example>
|
|
119
|
+
model: haiku|sonnet
|
|
120
|
+
tools: tool_1, tool_2
|
|
128
121
|
---
|
|
129
122
|
|
|
130
|
-
|
|
123
|
+
<identity>
|
|
124
|
+
I am [Name]. [Philosophy].
|
|
125
|
+
</identity>
|
|
126
|
+
|
|
127
|
+
<handles>
|
|
128
|
+
- Task 1
|
|
129
|
+
- Task 2
|
|
130
|
+
</handles>
|
|
131
|
+
|
|
132
|
+
<skills>
|
|
133
|
+
Load `skill-name` before complex tasks.
|
|
134
|
+
</skills>
|
|
135
|
+
|
|
136
|
+
<rules>
|
|
137
|
+
1. **NEVER FABRICATE** - Must call tools.
|
|
138
|
+
2. Rule 2
|
|
139
|
+
3. Rule 3
|
|
140
|
+
</rules>
|
|
141
|
+
|
|
142
|
+
<protocol>
|
|
143
|
+
Input: JSON task spec
|
|
144
|
+
Output: JSON only
|
|
145
|
+
Schema: { "status": "success|error", "result": {}, "summary": "" }
|
|
146
|
+
</protocol>
|
|
147
|
+
```
|
|
148
|
+
</agent-structure>
|
|
149
|
+
|
|
150
|
+
<customization>
|
|
151
|
+
CREATE: Add to `.claude/agents/` following structure above
|
|
152
|
+
MODIFY: Edit `.claude/agents/*.md`
|
|
153
|
+
DISABLE: Move to `docs/agents/`
|
|
154
|
+
WITHOUT AGENTS: Use MCP tools directly
|
|
155
|
+
</customization>
|
|
131
156
|
|
|
157
|
+
<directory>
|
|
132
158
|
```
|
|
133
159
|
workspace/ # Local config (check FIRST)
|
|
134
160
|
.claude/
|
|
135
|
-
agents/ # Agent definitions
|
|
161
|
+
agents/ # Agent definitions (XML tags, JSON output)
|
|
136
162
|
hooks/ # Safety hooks
|
|
137
|
-
skills/ #
|
|
163
|
+
skills/ # On-demand documentation
|
|
138
164
|
commands/ # Slash commands
|
|
139
165
|
settings.json # Permissions
|
|
140
166
|
```
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
|
|
144
|
-
# Customization
|
|
145
|
-
|
|
146
|
-
## Create Agent
|
|
147
|
-
```yaml
|
|
148
|
-
# .claude/agents/your-agent.md
|
|
149
|
-
---
|
|
150
|
-
name: your-agent
|
|
151
|
-
description: What it does.\n\n<example>...</example>
|
|
152
|
-
model: haiku
|
|
153
|
-
---
|
|
154
|
-
[Agent body with responsibilities]
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Modify Agents
|
|
158
|
-
Edit `.claude/agents/*.md` - change personality, responsibilities, model, tools.
|
|
159
|
-
|
|
160
|
-
## Disable Agents
|
|
161
|
-
Move from `.claude/agents/` to `docs/agents/`, remove from delegation table.
|
|
162
|
-
|
|
163
|
-
## Without Agents
|
|
164
|
-
Use MCP tools directly: `list_workflows`, `create_activity`, `get_workflow_schema`, etc.
|
|
167
|
+
</directory>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Assistant (Lightweight)
|
|
3
|
+
*
|
|
4
|
+
* Pure pass-through chatbot. System prompt is loaded on AI PC side.
|
|
5
|
+
* Just forwards user messages, no local processing.
|
|
6
|
+
*/
|
|
7
|
+
export declare class McpAssistant {
|
|
8
|
+
private client;
|
|
9
|
+
constructor(config: {
|
|
10
|
+
apiKey: string;
|
|
11
|
+
baseURL?: string;
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* Chat - pure pass-through to local LLM
|
|
15
|
+
*/
|
|
16
|
+
chat(userMessage: string, conversationHistory?: Array<{
|
|
17
|
+
role: 'user' | 'assistant';
|
|
18
|
+
content: string;
|
|
19
|
+
}>): Promise<string>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=mcp-assistant.d.ts.map
|