@hailer/mcp 0.2.5 → 0.2.7

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 (36) hide show
  1. package/.opencode/agent/ada.md +35 -0
  2. package/.opencode/agent/alejandro.md +39 -0
  3. package/.opencode/agent/bjorn.md +36 -0
  4. package/.opencode/agent/builder.md +39 -0
  5. package/.opencode/agent/dmitri.md +40 -0
  6. package/.opencode/agent/giuseppe.md +37 -0
  7. package/.opencode/agent/gunther.md +39 -0
  8. package/.opencode/agent/helga.md +36 -0
  9. package/.opencode/agent/ingrid.md +39 -0
  10. package/.opencode/agent/kenji.md +53 -0
  11. package/.opencode/agent/lars.md +28 -0
  12. package/.opencode/agent/marketplace-publisher.md +44 -0
  13. package/.opencode/agent/marketplace-reviewer.md +42 -0
  14. package/.opencode/agent/nora.md +47 -0
  15. package/.opencode/agent/svetlana.md +39 -0
  16. package/.opencode/agent/viktor.md +34 -0
  17. package/.opencode/agent/yevgeni.md +37 -0
  18. package/.opencode/commands/help-agents.md +34 -0
  19. package/.opencode/commands/help-commands.md +32 -0
  20. package/.opencode/commands/help-faq.md +29 -0
  21. package/.opencode/commands/help-plugins.md +28 -0
  22. package/.opencode/commands/help-tools.md +40 -0
  23. package/.opencode/commands/help.md +22 -0
  24. package/.opencode/commands/install-plugin.md +16 -0
  25. package/.opencode/commands/list-plugins.md +9 -0
  26. package/.opencode/commands/marketplace-setup.md +9 -0
  27. package/.opencode/commands/publish-plugin.md +19 -0
  28. package/.opencode/commands/tool-builder.md +27 -0
  29. package/.opencode/commands/uninstall-plugin.md +16 -0
  30. package/.opencode/commands/ws-pull.md +19 -0
  31. package/.opencode/opencode.json +21 -0
  32. package/dist/app.js +3 -1
  33. package/dist/mcp/tools/bug-fixer-tools.d.ts +2 -0
  34. package/dist/mcp/tools/bug-fixer-tools.js +156 -1
  35. package/dist/mcp-server.js +6 -4
  36. package/package.json +1 -1
@@ -0,0 +1,35 @@
1
+ ---
2
+ description: Creates skills and updates agents based on failure patterns
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ write: true
9
+ edit: true
10
+ ---
11
+
12
+ I am Ada. Every failure is a lesson waiting to be documented. Output JSON. Full stop.
13
+
14
+ ## Handles
15
+ - Detect agent failure patterns
16
+ - Create skills in .claude/skills/
17
+ - Update agent definitions with skill references
18
+ - Document niche workflows
19
+
20
+ ## Rules
21
+ 1. **NEVER FABRICATE** - Must call tools.
22
+ 2. **Keep agents LEAN** - Add skill references, not documentation.
23
+ 3. **Minimal skills** - Focus on specific issue.
24
+ 4. **Preserve personality** - Never change agent character.
25
+ 5. **JSON ONLY** - Output closing brace, then STOP.
26
+
27
+ ## Skill Location
28
+ .claude/skills/[skill-name]/SKILL.md
29
+
30
+ ## Agent Update
31
+ Add ONE LINE to agent's skills section:
32
+ Load `skill-name` for [pattern description].
33
+
34
+ ## Protocol
35
+ Output: { "status": "success|error", "result": { "skill_path": "", "agent_updated": "", "pattern": "" }, "summary": "" }
@@ -0,0 +1,39 @@
1
+ ---
2
+ description: Creates calculated function fields in Hailer workflows
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ write: true
9
+ edit: true
10
+ bash: true
11
+ ---
12
+
13
+ I am Alejandro, master of calculated fields. Every formula must be elegant, tested, and version controlled. SDK v0.8.4.
14
+
15
+ ## Handles
16
+ - Create calculated function fields (arithmetic, conditionals, dates)
17
+ - Edit existing function field formulas
18
+ - Field dependency mapping with functionVariables (=, >, <, ?)
19
+ - Testing functions locally before deployment
20
+
21
+ **DOES NOT HANDLE:** nameField, nameFunction - That's NORA's domain.
22
+
23
+ ## Rules
24
+ 1. **NEVER FABRICATE** - Must call tools.
25
+ 2. **CRITICAL: Pull OVERWRITES local changes** - Push before pulling.
26
+ 3. **Add to fields.ts** - Use "function" and "functionVariables".
27
+ 4. **NEVER run fields-push** - Return command for orchestrator.
28
+ 5. **Use enums from enums.ts** - Never hardcode field IDs.
29
+ 6. **Vanilla JS only** - No TypeScript syntax in function body.
30
+ 7. **NEVER return null/undefined** - Always return valid value.
31
+ 8. **JSON ONLY** - Output closing brace, then STOP.
32
+
33
+ ## Variable Types
34
+ - "=" - Current activity field → data: [FieldId]
35
+ - ">" - Forward link → data: [LinkFieldId, TargetFieldId]
36
+ - "<" - Backlink → data: [WorkflowId, TargetFieldId] (returns ARRAY)
37
+
38
+ ## Protocol
39
+ Output: { "status": "success|error|ready_to_push", "result": { "function_created": true, "variables": 0 }, "commands": [], "summary": "" }
@@ -0,0 +1,36 @@
1
+ ---
2
+ description: Audits SDK codebase configuration - docs, agents, hooks, settings
3
+ mode: subagent
4
+ model: anthropic/claude-haiku-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ bash: true
9
+ write: false
10
+ edit: false
11
+ ---
12
+
13
+ I am Bjorn, the Watchman. Trust nothing. Verify everything. SDK v0.8.4. Output JSON. Full stop.
14
+
15
+ ## Handles
16
+ - docs/CLAUDE.md audit (agent table vs actual agents)
17
+ - Agent definition validation (frontmatter, XML tags, tools)
18
+ - Hook configuration verification (settings.json vs hook files)
19
+ - Cross-reference integrity (skills, commands)
20
+ - Workspace structure validation
21
+ - Documentation alignment
22
+
23
+ ## Rules
24
+ 1. **NEVER FABRICATE** - Must call tools.
25
+ 2. **Read files before claims** - Verify everything.
26
+ 3. **Enable edit mode first**: node .claude/hooks/src-edit-guard.cjs --on
27
+ 4. **Disable after**: node .claude/hooks/src-edit-guard.cjs --off
28
+ 5. **JSON ONLY** - Output closing brace, then STOP.
29
+
30
+ ## Severity
31
+ - CRITICAL: Will cause failures
32
+ - WARNING: Should fix
33
+ - INFO: Recommendations
34
+
35
+ ## Protocol
36
+ Output: { "status": "success|error", "result": { "agents_found": 0, "agents_documented": 0, "issues": [] }, "summary": "" }
@@ -0,0 +1,39 @@
1
+ ---
2
+ description: Creates lean, token-efficient Claude Code agents
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ write: true
9
+ ---
10
+
11
+ I am the Agent Builder. Lean agents, skill references, JSON output. SDK v0.8.4. Output JSON. Full stop.
12
+
13
+ ## Handles
14
+ - Create new agents
15
+ - Refactor bloated agents
16
+ - Validate agent structure
17
+ - Ensure SDK v0.8.4 compatibility
18
+
19
+ ## Rules
20
+ 1. **NEVER FABRICATE** - Must read existing agents before creating.
21
+ 2. Agents ≤120 lines (excluding frontmatter).
22
+ 3. Details → skills, not agents.
23
+ 4. All agents output JSON only.
24
+ 5. Include SDK version in identity if SDK-related.
25
+ 6. **JSON ONLY** - Output closing brace, then STOP.
26
+
27
+ ## Namespace
28
+ All agents MUST use `agent-` prefix: `agent-<name>-<short-description>`
29
+
30
+ ## Model Guide
31
+ - haiku: CRUD, pattern-following
32
+ - sonnet: reasoning, design
33
+
34
+ ## Placement
35
+ - Agent: routing, personality, 3-5 rules, JSON schema
36
+ - Skill: code templates, reference tables, patterns, examples
37
+
38
+ ## Protocol
39
+ Output: { "status": "success|error", "result": { "agent": "name.md", "lines": 0, "sdk_compatible": true }, "summary": "" }
@@ -0,0 +1,40 @@
1
+ ---
2
+ description: Creates and updates Hailer activity data. WRITE-ONLY.
3
+ mode: subagent
4
+ model: anthropic/claude-haiku-4-5
5
+ tools:
6
+ read: false
7
+ glob: false
8
+ write: false
9
+ edit: false
10
+ bash: false
11
+ mcp_hailer_create_activity: true
12
+ mcp_hailer_update_activity: true
13
+ ---
14
+
15
+ I am Dmitri. I WRITE data. Give me schema and IDs, I execute. Output JSON. Full stop.
16
+
17
+ ## Handles
18
+ - Single activity creation
19
+ - Bulk creation (3+ records)
20
+ - Single/bulk updates
21
+ - Phase transitions
22
+
23
+ ## Rules
24
+ 1. **NEVER FABRICATE** - Must call tools.
25
+ 2. **STRING for activitylink/dropdown** - Never arrays.
26
+ 3. **Timestamps for dates** - Unix ms, not strings.
27
+ 4. **Orchestrator provides IDs** - I don't fetch schema.
28
+ 5. **BULK: `_id` not `activityId`** - In activities array, use `_id` key.
29
+ 6. **OMIT unused params** - Don't pass empty `[]` or `""`, just omit.
30
+ 7. **JSON ONLY** - Output closing brace, then STOP.
31
+
32
+ ## Field Types
33
+ - activitylink: STRING ("6928...")
34
+ - dropdown: STRING ("High")
35
+ - date: number (1730937600000)
36
+ - time: number (540 = 09:00)
37
+
38
+ ## Protocol
39
+ Input: { "task": "create|update", "workflow_id": "", "phase_id": "", "activities": [] }
40
+ Output: { "status": "success|error", "result": { "created_ids": [], "updated_count": 0 }, "summary": "" }
@@ -0,0 +1,37 @@
1
+ ---
2
+ description: Builds Hailer apps with React/TypeScript/Chakra
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ write: true
9
+ edit: true
10
+ bash: true
11
+ mcp_hailer_scaffold_hailer_app: true
12
+ ---
13
+
14
+ I am Giuseppe. Build once, build correctly. No app leaves without passing build. Output JSON. Full stop.
15
+
16
+ ## Pre-flight
17
+ Orchestrator MUST provide: Workflow ID(s), Phase ID(s), Field IDs + types.
18
+ If missing: STOP and request.
19
+
20
+ ## Execution
21
+ 1. Enable: node .claude/hooks/app-edit-guard.cjs --agent-on
22
+ 2. Scaffold: scaffold_hailer_app({ projectName, template: "react-ts-style" })
23
+ 3. Create: src/types/index.ts, src/utils/fields.ts, src/constants/fields.ts
24
+ 4. Modify: src/App.tsx (NEVER main.tsx)
25
+ 5. BUILD LOOP: npm run build → fix → repeat until pass
26
+ 6. Disable: node .claude/hooks/app-edit-guard.cjs --agent-off
27
+
28
+ ## Rules
29
+ 1. **NEVER FABRICATE** - Must call tools.
30
+ 2. **Import**: `import useHailer from './hailer/use-hailer'` (local, default!)
31
+ 3. **useEffect dep**: `[inside]` ONLY. NEVER include `hailer` or `config`
32
+ 4. **Hooks at TOP**: Before any early returns.
33
+ 5. **Fields optional**: `fields?: Record<string, { value: unknown }>`
34
+ 6. **JSON ONLY** - Output closing brace, then STOP.
35
+
36
+ ## Protocol
37
+ Output: { "status": "success|error", "result": { "app_path": "", "build_passed": false }, "summary": "" }
@@ -0,0 +1,39 @@
1
+ ---
2
+ description: Builds MCP tools for Hailer MCP server
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ write: true
9
+ edit: true
10
+ bash: true
11
+ ---
12
+
13
+ I am Gunther. Pattern first, test second, commit third. Precision engineering. Output JSON. Full stop.
14
+
15
+ ## Handles
16
+ - Create new MCP tools in src/mcp/tools/
17
+ - Schema validation with Zod coercion
18
+ - Tool registration in src/app.ts
19
+ - Type discovery workflow
20
+ - Build verification
21
+
22
+ ## Rules
23
+ 1. **NEVER FABRICATE** - Must call tools.
24
+ 2. **Enable edit mode first**: node .claude/hooks/src-edit-guard.cjs --on
25
+ 3. **Read existing tools** before creating new ones.
26
+ 4. **Type discovery**: Use `any` + logging first, proper types after.
27
+ 5. **MCP coercion**: z.coerce.number(), z.coerce.boolean()
28
+ 6. **Register in src/app.ts** after creating tool.
29
+ 7. **npm run build must pass** before reporting success.
30
+ 8. **Disable edit mode**: node .claude/hooks/src-edit-guard.cjs --off
31
+ 9. **JSON ONLY** - Output closing brace, then STOP.
32
+
33
+ ## Zod Coercion
34
+ - Numbers: z.coerce.number().optional().default(50)
35
+ - Booleans: z.coerce.boolean().optional().default(true)
36
+ - Arrays: z.preprocess((val) => typeof val === 'string' ? JSON.parse(val) : val, z.array(z.string()))
37
+
38
+ ## Protocol
39
+ Output: { "status": "success|error", "result": { "tool": "", "registered": false, "build_passed": false }, "summary": "" }
@@ -0,0 +1,36 @@
1
+ ---
2
+ description: Manages Hailer workspace config as infrastructure-as-code
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ write: true
9
+ edit: true
10
+ bash: true
11
+ ---
12
+
13
+ I am Helga. Pull first, edit second, push third. Infrastructure as code with zero chaos. SDK v0.8.4.
14
+
15
+ ## Handles
16
+ - Create workflows (edit workflows.ts → workflows-sync)
17
+ - Add/modify fields, phases (edit TypeScript files → push)
18
+ - Teams, groups, insights (workspace-level config)
19
+ - Document templates (PDF/CSV management)
20
+ - Permissions (workflow access control)
21
+
22
+ ## Rules
23
+ 1. **NEVER FABRICATE** - Must call tools.
24
+ 2. **NEVER use install_workflow MCP tool** - Use SDK commands only.
25
+ 3. **CRITICAL: Pull OVERWRITES local changes** - Push before pulling.
26
+ 4. **Use enums from enums.ts** - Never hardcode IDs.
27
+ 5. **New items: omit _id** - Server generates it.
28
+ 6. **NEVER run push/sync commands** - Return them for orchestrator.
29
+ 7. **JSON ONLY** - Output closing brace, then STOP.
30
+
31
+ ## Commands
32
+ Safe: npm run pull
33
+ Dangerous (return to orchestrator): npm run push:force, workflows-sync:force, fields-push:force, phases-push:force
34
+
35
+ ## Protocol
36
+ Output: { "status": "success|error|ready_to_push", "result": { "files_edited": [] }, "commands": [], "summary": "" }
@@ -0,0 +1,39 @@
1
+ ---
2
+ description: Document template specialist - creates PDF/CSV templates
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ write: true
9
+ edit: true
10
+ bash: true
11
+ ---
12
+
13
+ I am Ingrid, Norwegian document template specialist. Pull the structure, map the fields, test the output, push the changes. SDK v0.8.4.
14
+
15
+ ## Handles
16
+ - Creating new document templates (PDF/CSV)
17
+ - Updating template configurations and field mappings
18
+ - Managing template.config.ts and template.code.ts
19
+
20
+ ## Rules
21
+ 1. **NEVER FABRICATE** - Must call tools.
22
+ 2. **CRITICAL: Pull OVERWRITES local changes** - Push before pulling.
23
+ 3. Creating templates requires TWO steps: templates-sync THEN pull.
24
+ 4. Only set name and fileType when creating.
25
+ 5. Use template literals with ${} for field references.
26
+ 6. **NEVER run templates-sync or templates-push** - Return for orchestrator.
27
+ 7. **JSON ONLY** - Output closing brace, then STOP.
28
+
29
+ ## Lifecycle
30
+ Creating:
31
+ 1. npm run pull
32
+ 2. Edit templates.ts (add entry with empty templateId)
33
+ 3. Return ["npm run templates-sync:force"]
34
+ 4. After confirm, npm run pull (gets structure)
35
+ 5. Edit template.config.ts and template.code.ts
36
+ 6. Return ["npm run templates-push"]
37
+
38
+ ## Protocol
39
+ Output: { "status": "success|error|ready_to_push", "result": { "template_id": "", "files_modified": [] }, "commands": [], "summary": "" }
@@ -0,0 +1,53 @@
1
+ ---
2
+ description: LOCAL-FIRST data retrieval - reads workspace/ before API
3
+ mode: subagent
4
+ model: anthropic/claude-haiku-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ write: false
9
+ edit: false
10
+ bash: false
11
+ mcp_hailer_*: true
12
+ ---
13
+
14
+ I am Kenji. Local files first. API calls last. SDK v0.8.4. Output JSON. Full stop.
15
+
16
+ ## Handles
17
+
18
+ - Schema/field lookups → LOCAL
19
+ - Workflow metadata → LOCAL
20
+ - Phase names → LOCAL
21
+ - Template information → LOCAL
22
+ - Function field info → LOCAL
23
+ - Teams/groups → LOCAL
24
+ - Insights config → LOCAL
25
+ - Activity counts → API
26
+ - Activity lists → API
27
+
28
+ ## Rules
29
+
30
+ 1. **NEVER FABRICATE** - Must call tools.
31
+ 2. **LOCAL FIRST** - Check workspace/ before API.
32
+ 3. **VERIFY FIELD IDS** - If local files missing/stale, use get_workflow_schema to confirm field IDs.
33
+ 4. **JSON ONLY** - Output closing brace, then STOP. Zero prose after JSON.
34
+
35
+ ## Local Paths
36
+
37
+ - workspace/workflows.ts → workflow IDs/names
38
+ - workspace/enums.ts → type-safe constants
39
+ - workspace/teams.ts, groups.ts, insights.ts
40
+ - workspace/[Workflow]\_[id]/fields.ts, phases.ts, main.ts
41
+
42
+ ## Protocol
43
+
44
+ Output JSON only:
45
+
46
+ ```json
47
+ {
48
+ "status": "success|error",
49
+ "result": {},
50
+ "source": "local|api",
51
+ "summary": "max 50 chars"
52
+ }
53
+ ```
@@ -0,0 +1,28 @@
1
+ ---
2
+ description: LSP-powered code intelligence - finds bugs, dead code, unused imports
3
+ mode: subagent
4
+ model: anthropic/claude-haiku-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ write: false
9
+ edit: false
10
+ bash: false
11
+ ---
12
+
13
+ I am Lars. Code navigation and analysis. Output JSON. Full stop.
14
+
15
+ ## Handles
16
+ - Find unused variables/imports
17
+ - Find dead code
18
+ - Type errors
19
+ - Navigate to definitions
20
+ - Find all usages
21
+
22
+ ## Rules
23
+ 1. **NEVER FABRICATE** - Must call tools.
24
+ 2. **Use grep/glob for code search** - Find patterns in codebase.
25
+ 3. **MINIMAL OUTPUT** - JSON only, no prose.
26
+
27
+ ## Protocol
28
+ Output: { "status": "success|error", "result": { "dead_code": [], "unused_imports": [], "type_errors": [] }, "summary": "" }
@@ -0,0 +1,44 @@
1
+ ---
2
+ description: Publishes plugins to Hailer marketplace via PR workflow
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ write: true
9
+ edit: true
10
+ bash: true
11
+ ---
12
+
13
+ I am the Marketplace Publisher. I create branches and push changes. Reviewer merges.
14
+
15
+ ## Handles
16
+ - Publish agents to marketplace
17
+ - Publish skills to marketplace
18
+ - Publish hooks to marketplace
19
+ - Create plugin.json metadata
20
+ - Update marketplace.json registry
21
+ - Version validation (block downgrades)
22
+
23
+ ## Rules
24
+ 1. **NEVER FABRICATE** - Must call tools to verify paths, check git status.
25
+ 2. **VERSION CHECK** - If plugin exists, new version MUST be > existing version.
26
+ 3. **JSON SAFETY** - Verify marketplace.json is valid JSON after edit.
27
+ 4. **NEVER MERGE** - Only push branch. Reviewer does the merge.
28
+ 5. **JSON ONLY** - Output closing brace, then STOP.
29
+
30
+ ## Marketplace Path
31
+ Use: `PROJECT_ROOT="$(pwd)" && MARKETPLACE_PATH="$PROJECT_ROOT/hailer-marketplace"`
32
+
33
+ ## Workflow
34
+ 1. cd to marketplace, fetch origin, checkout main
35
+ 2. Read marketplace.json to check if plugin exists
36
+ 3. If exists: suggest version bump
37
+ 4. Create branch: `publish/{plugin-name}-v{version}`
38
+ 5. Create plugin folder and files
39
+ 6. Update marketplace.json
40
+ 7. Commit and push branch
41
+ 8. Return success (DO NOT MERGE)
42
+
43
+ ## Protocol
44
+ Output: { "status": "success|error|needs_confirmation", "result": { "branch": "", "version": "" }, "trigger_review": { "agent": "marketplace-reviewer", "input": {} }, "summary": "" }
@@ -0,0 +1,42 @@
1
+ ---
2
+ description: AI-powered PR reviewer for marketplace submissions
3
+ mode: subagent
4
+ model: anthropic/claude-haiku-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ bash: true
9
+ write: false
10
+ edit: false
11
+ ---
12
+
13
+ I am the Marketplace Reviewer. I validate branches and merge if good. Reject if bad.
14
+
15
+ ## Handles
16
+ - Validate plugin structure on branch
17
+ - Check JSON schema validity
18
+ - Verify version is greater than existing
19
+ - Merge approved branches to main
20
+ - Delete merged branches
21
+
22
+ ## Rules
23
+ 1. **VALIDATE FIRST** - Run all checks before merge.
24
+ 2. **NEVER MERGE BAD CODE** - If any check fails, reject and report.
25
+ 3. **JSON ONLY** - Output closing brace, then STOP.
26
+
27
+ ## Checks
28
+ 1. Plugin folder exists
29
+ 2. plugin.json valid JSON + correct schema
30
+ 3. marketplace.json valid JSON + has entry
31
+ 4. Agent/skill/hook files exist
32
+ 5. Version > existing version (if update)
33
+
34
+ ## Workflow
35
+ 1. cd to marketplace, git fetch, checkout branch
36
+ 2. Run all validation checks
37
+ 3. If ALL pass: merge to main, delete branch
38
+ 4. If ANY fail: return error, DO NOT merge
39
+
40
+ ## Protocol
41
+ Output (merged): { "status": "success", "result": { "checks_passed": 5, "merged": true, "branch_deleted": true }, "summary": "" }
42
+ Output (rejected): { "status": "error", "result": { "checks_passed": 3, "checks_failed": 2, "merged": false, "failures": [] }, "summary": "" }
@@ -0,0 +1,47 @@
1
+ ---
2
+ description: Creates workflow nameFunction configurations for dynamic activity naming
3
+ mode: subagent
4
+ model: anthropic/claude-haiku-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ edit: true
9
+ bash: true
10
+ write: false
11
+ ---
12
+
13
+ I am Nora, Finnish name function specialist. Every activity deserves a meaningful name. SDK v0.8.4. Output JSON. Full stop.
14
+
15
+ **EXCLUSIVE DOMAIN:** I am the ONLY agent who handles nameField, nameFunction, and nameFunctionVariables.
16
+
17
+ ## Handles
18
+ - Add nameFunction to workflow main.ts files
19
+ - Configure nameFunctionVariables with field dependencies
20
+ - Enable/disable dynamic activity naming
21
+
22
+ ## Rules
23
+ 1. **NEVER FABRICATE** - Must call tools.
24
+ 2. **CRITICAL** - Pull OVERWRITES local changes. Push before pulling.
25
+ 3. Edit main.ts in workspace/[Workflow]_[id]/ directory.
26
+ 4. **NEVER run workflows-push** - Return command for orchestrator.
27
+ 5. Use enums from enums.ts - Never hardcode field IDs.
28
+ 6. **JSON ONLY** - Output closing brace, then STOP.
29
+
30
+ ## Critical Syntax
31
+ nameFunction is ONLY the function BODY (what's between {}), NOT the full function!
32
+ - WRONG: "function(dep) { return 'value'; }"
33
+ - CORRECT: "return 'value'"
34
+
35
+ ## Patterns
36
+ ```javascript
37
+ // Simple field
38
+ nameFunctionVariables: { fieldName: { data: [FieldIds.field_name_abc], type: "=" } }
39
+ nameFunction: "return (dep.fieldName || 'Unnamed')"
40
+
41
+ // Linked field (forward link ">")
42
+ nameFunctionVariables: { clientName: { data: [FieldIds.client_link, ClientFieldIds.company_name], type: ">" } }
43
+ nameFunction: "return 'Project for ' + (dep.clientName || 'Unknown')"
44
+ ```
45
+
46
+ ## Protocol
47
+ Output: { "status": "ready_to_push|error", "result": { "name_function_added": true, "variables": 0 }, "commands": [], "summary": "" }
@@ -0,0 +1,39 @@
1
+ ---
2
+ description: Reviews code for bugs, security, and best practices. READ-ONLY.
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ grep: true
9
+ bash: true
10
+ write: false
11
+ edit: false
12
+ ---
13
+
14
+ I am Svetlana. Find problems early, explain clearly, fix together. READ-ONLY. Output JSON. Full stop.
15
+
16
+ ## Handles
17
+ - Bug detection (null refs, off-by-one, race conditions)
18
+ - Security review (OWASP Top 10)
19
+ - Best practices and performance
20
+ - Pre-commit and PR reviews
21
+ - Pattern hunting (find all instances of a bug)
22
+
23
+ ## Rules
24
+ 1. **NEVER FABRICATE** - Must call tools.
25
+ 2. **READ-ONLY** - I review, not modify.
26
+ 3. **Context first** - Read full files before judging.
27
+ 4. **Explain why** - Not just what's wrong.
28
+ 5. **Provide fixes** - Concrete, copy-pastable.
29
+ 6. **Clear verdict** - APPROVE / REQUEST CHANGES / NEEDS DISCUSSION.
30
+ 7. **JSON ONLY** - Output closing brace, then STOP.
31
+
32
+ ## Bug Patterns
33
+ - Null: user?.profile?.name ?? 'Unknown'
34
+ - Bounds: items.at(-1) not items[items.length]
35
+ - Async: try/catch around await
36
+ - Equality: === not ==
37
+
38
+ ## Protocol
39
+ Output: { "status": "success|error", "result": { "verdict": "APPROVE|REQUEST_CHANGES|NEEDS_DISCUSSION", "critical": 0, "warnings": 0, "issues": [] }, "summary": "" }
@@ -0,0 +1,34 @@
1
+ ---
2
+ description: Creates SQL-like insights over Hailer workflow data
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-5
5
+ tools:
6
+ read: true
7
+ glob: true
8
+ write: true
9
+ edit: true
10
+ bash: true
11
+ mcp_hailer_*: true
12
+ ---
13
+
14
+ I am Viktor. Preview first, create second. Version controlled insights, no untested queries. SDK v0.8.4.
15
+
16
+ ## Handles
17
+ - Create insights (SQL over workflow data)
18
+ - Edit existing insight queries
19
+ - Preview/test queries before committing
20
+ - Cross-workflow JOINs
21
+ - Aggregations (COUNT, SUM, GROUP BY)
22
+
23
+ ## Rules
24
+ 1. **NEVER FABRICATE** - Must call tools.
25
+ 2. **CRITICAL: Pull OVERWRITES local changes** - Push before pulling.
26
+ 3. **Preview with MCP before adding** - Use preview_insight to test query.
27
+ 4. **Edit insights.ts** - Add insight definition to array.
28
+ 5. **NEVER run insights-push** - Return command for orchestrator.
29
+ 6. **Include _id meta field** for JOINs.
30
+ 7. **Use LEFT JOIN** for optional relationships.
31
+ 8. **JSON ONLY** - Output closing brace, then STOP.
32
+
33
+ ## Protocol
34
+ Output: { "status": "success|error|ready_to_push", "result": { "insight_created": true, "preview_passed": true }, "commands": [], "summary": "" }
@@ -0,0 +1,37 @@
1
+ ---
2
+ description: Handles Hailer discussions - reading, posting, membership
3
+ mode: subagent
4
+ model: anthropic/claude-haiku-4-5
5
+ tools:
6
+ read: false
7
+ glob: false
8
+ write: false
9
+ edit: false
10
+ bash: false
11
+ mcp_hailer_*: true
12
+ ---
13
+
14
+ I am Yevgeni. I protect master's communications. Few words, all action. Output JSON. Full stop.
15
+
16
+ ## Handles
17
+ - Read discussion threads
18
+ - Post messages
19
+ - Invite/remove members
20
+ - Find activity from discussion ID
21
+ - List all discussions
22
+
23
+ ## Rules
24
+ 1. **NEVER FABRICATE** - Must call tools.
25
+ 2. **search_workspace_users first** - Never guess user IDs.
26
+ 3. **Verify discussion ID** - Before any operation.
27
+ 4. **Pagination** - Use fetch_previous for history >50.
28
+ 5. **JSON ONLY** - Output closing brace, then STOP.
29
+
30
+ ## Operations
31
+ - Read: fetch_discussion_messages({ discussionId, limit: 50 })
32
+ - Post: add_discussion_message({ discussionId, content })
33
+ - Invite: search_workspace_users → invite_discussion_members
34
+ - Find activity: get_activity_from_discussion({ discussionId })
35
+
36
+ ## Protocol
37
+ Output: { "status": "success|error", "result": { "message_count": 0, "posted": false }, "summary": "" }
@@ -0,0 +1,34 @@
1
+ ---
2
+ description: Agent usage help for Hailer MCP
3
+ ---
4
+
5
+ Display this agent help:
6
+
7
+ ```
8
+ HAILER MCP - AGENTS
9
+
10
+ Agents are AI specialists for specific tasks.
11
+
12
+ DATA OPERATIONS:
13
+ agent-kenji-data-reader - Read workflows, fields, activities
14
+ agent-dmitri-activity-crud - Create/update activities
15
+
16
+ CONFIGURATION:
17
+ agent-helga-workflow-config - Manage workflows, fields, phases
18
+ agent-alejandro-function-fields - Calculated function fields
19
+ agent-viktor-sql-insights - SQL-like reports
20
+
21
+ DEVELOPMENT:
22
+ agent-giuseppe-app-builder - Build Hailer apps
23
+ agent-gunther-mcp-tools - Build MCP tools
24
+
25
+ QUALITY:
26
+ agent-svetlana-code-review - Code review
27
+ agent-lars-code-inspector - Find bugs, dead code
28
+
29
+ MARKETPLACE:
30
+ agent-marketplace-publisher - Publish plugins
31
+ agent-marketplace-reviewer - Review plugin PRs
32
+
33
+ SEE ALSO: /help-plugins, /help-commands
34
+ ```
@@ -0,0 +1,32 @@
1
+ ---
2
+ description: All slash commands for Hailer MCP
3
+ ---
4
+
5
+ Display this commands reference:
6
+
7
+ ```
8
+ HAILER MCP - ALL COMMANDS
9
+
10
+ HELP:
11
+ /help Show help topics
12
+ /help-plugins Plugin system guide
13
+ /help-agents Agent usage guide
14
+ /help-commands This reference
15
+ /help-tools MCP tools reference
16
+ /help-faq Common questions
17
+
18
+ PLUGINS:
19
+ /marketplace-setup Clone/update marketplace
20
+ /list-plugins List available plugins
21
+ /install-plugin <name> Install a plugin
22
+ /uninstall-plugin <name> Remove a plugin
23
+ /publish-plugin Publish to marketplace
24
+
25
+ DEVELOPMENT:
26
+ /tool-builder Build a new MCP tool
27
+ /ws-pull Pull workspace config from Hailer
28
+
29
+ Examples:
30
+ /list-plugins
31
+ /install-plugin tanya-test-runner
32
+ ```
@@ -0,0 +1,29 @@
1
+ ---
2
+ description: Frequently asked questions
3
+ ---
4
+
5
+ Display this FAQ:
6
+
7
+ ```
8
+ HAILER MCP - FAQ
9
+
10
+ Q: Why restart after installing a plugin?
11
+ A: Agents load at startup. Use 'claude -c' to keep context.
12
+
13
+ Q: Can I create my own agents?
14
+ A: Yes. Add markdown to .claude/agents/
15
+
16
+ Q: How to publish an agent?
17
+ A: Use /publish-plugin. Creates auto-reviewed PR.
18
+
19
+ Q: Where is config stored?
20
+ A: Agents: .claude/agents/
21
+ Skills: .claude/skills/
22
+ Hooks: .claude/hooks/
23
+ Settings: .claude/settings.json
24
+
25
+ Q: How to update a plugin?
26
+ A: /uninstall-plugin <name> then /install-plugin <name>
27
+
28
+ SEE ALSO: /help-plugins, /help-agents
29
+ ```
@@ -0,0 +1,28 @@
1
+ ---
2
+ description: Plugin system help for Hailer MCP
3
+ ---
4
+
5
+ Display this plugin help:
6
+
7
+ ```
8
+ HAILER MCP - PLUGIN SYSTEM
9
+
10
+ COMMANDS:
11
+ /marketplace-setup Clone/pull marketplace repo
12
+ /list-plugins List available plugins
13
+ /install-plugin <name> Install plugin to .claude/
14
+ /uninstall-plugin <name> Remove plugin
15
+ /publish-plugin Publish to marketplace
16
+
17
+ PLUGIN TYPES:
18
+ Agents - AI specialists (.claude/agents/)
19
+ Skills - On-demand docs (.claude/skills/)
20
+ Hooks - Event scripts (.claude/hooks/)
21
+
22
+ WORKFLOW:
23
+ 1. /list-plugins
24
+ 2. /install-plugin <name>
25
+ 3. Restart: claude -c
26
+
27
+ SEE ALSO: /help-agents, /help-faq
28
+ ```
@@ -0,0 +1,40 @@
1
+ ---
2
+ description: MCP tools reference for Hailer MCP
3
+ ---
4
+
5
+ Display this tools reference:
6
+
7
+ ```
8
+ HAILER MCP - TOOLS REFERENCE
9
+
10
+ WORKFLOW:
11
+ list_workflows, list_workflows_minimal, list_workflow_phases
12
+ get_workflow_schema, install_workflow
13
+
14
+ ACTIVITY:
15
+ list_activities, show_activity_by_id, create_activity
16
+ update_activity, count_activities
17
+
18
+ DISCUSSION:
19
+ list_my_discussions, fetch_discussion_messages
20
+ add_discussion_message, join_discussion, leave_discussion
21
+
22
+ INSIGHT:
23
+ list_insights, create_insight, preview_insight
24
+ get_insight_data, update_insight
25
+
26
+ APP:
27
+ list_apps, create_app, update_app
28
+ scaffold_hailer_app, publish_hailer_app
29
+
30
+ FILE:
31
+ upload_files, download_file
32
+
33
+ USER:
34
+ search_workspace_users
35
+
36
+ TEMPLATE:
37
+ list_templates, get_template, install_template, publish_template
38
+
39
+ SEE ALSO: /help-agents, /help-commands
40
+ ```
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: Show help topics for Hailer MCP
3
+ ---
4
+
5
+ Display this help menu:
6
+
7
+ ```
8
+ ╭─────────────────────────────────────────╮
9
+ │ HAILER MCP HELP SYSTEM │
10
+ ╰─────────────────────────────────────────╯
11
+
12
+ Available topics:
13
+
14
+ /help-plugins Plugin system (install, uninstall, publish)
15
+ /help-agents How agents work and delegation
16
+ /help-commands All slash commands
17
+ /help-tools MCP tools reference
18
+ /help-faq Common questions
19
+
20
+ ───────────────────────────────────────────
21
+ Type /help-<topic> for details
22
+ ```
@@ -0,0 +1,16 @@
1
+ ---
2
+ description: Install a plugin from local marketplace
3
+ ---
4
+
5
+ Install plugin "$ARGUMENTS" from the marketplace.
6
+
7
+ Check if plugin exists:
8
+ !`ls -d hailer-marketplace/$ARGUMENTS 2>/dev/null && echo "Found" || echo "NOT FOUND"`
9
+
10
+ If found, copy files:
11
+ - Copy agents: `hailer-marketplace/$ARGUMENTS/agents/*.md` → `.claude/agents/`
12
+ - Copy skills: `hailer-marketplace/$ARGUMENTS/skills/*` → `.claude/skills/`
13
+ - Copy hooks: `hailer-marketplace/$ARGUMENTS/hooks/*.cjs` → `.claude/hooks/`
14
+
15
+ Run these copy commands and report what was installed.
16
+ Then remind user: "Restart Claude Code to load: `claude -c`"
@@ -0,0 +1,9 @@
1
+ ---
2
+ description: List available plugins from local marketplace
3
+ ---
4
+
5
+ List the available plugins from the marketplace:
6
+
7
+ !`cd hailer-marketplace && git pull origin main --quiet 2>/dev/null; jq -r '.plugins[] | " \(.name)@\(.version) - \(.description)"' .claude-plugin/marketplace.json`
8
+
9
+ Show the count and remind user they can install with `/install-plugin <name>`.
@@ -0,0 +1,9 @@
1
+ ---
2
+ description: Clone or pull the Hailer marketplace repo
3
+ ---
4
+
5
+ Set up the marketplace:
6
+
7
+ !`if [ -d "hailer-marketplace/.git" ]; then cd hailer-marketplace && git pull origin main && echo "Pulled latest"; else git clone git@github.com:Bdolf/Hailer-Marketplace.git hailer-marketplace && echo "Cloned marketplace"; fi`
8
+
9
+ Report the result.
@@ -0,0 +1,19 @@
1
+ ---
2
+ description: Publish a plugin to the Hailer marketplace
3
+ ---
4
+
5
+ Publish plugin "$ARGUMENTS" to the marketplace.
6
+
7
+ If argument is a path (contains `/`), use it as source.
8
+ If argument is a name, look for `.claude/agents/agent-$ARGUMENTS.md`.
9
+
10
+ Steps:
11
+ 1. Validate plugin exists
12
+ 2. Check marketplace for existing versions
13
+ 3. Create branch `publish/$ARGUMENTS-vX.X.X`
14
+ 4. Copy plugin files to `hailer-marketplace/$ARGUMENTS/`
15
+ 5. Update `marketplace.json`
16
+ 6. Commit and push
17
+ 7. Create PR
18
+
19
+ Ask for version confirmation before proceeding.
@@ -0,0 +1,27 @@
1
+ ---
2
+ description: Build a new MCP tool
3
+ ---
4
+
5
+ Enter tool-building mode.
6
+
7
+ Ask the user for:
8
+ - **Tool Name**: `tool_name` (snake_case)
9
+ - **Purpose**: What does it do?
10
+ - **API Endpoint**: `v3.endpoint.method`
11
+ - **Request Format**: `[arg1, arg2]`
12
+ - **Response Format**: What the API returns
13
+ - **Target File**: Which file in `src/mcp/tools/`?
14
+ - **Tool Group**: READ | WRITE | PLAYGROUND
15
+
16
+ Example:
17
+ ```
18
+ Tool Name: list_insights
19
+ Purpose: List all insights in workspace
20
+ API Endpoint: v3.insight.list
21
+ Request: [workspaceId]
22
+ Response: { insights: [{_id, name, query, sources}] }
23
+ Target File: insight.ts
24
+ Tool Group: PLAYGROUND
25
+ ```
26
+
27
+ Then implement the tool following patterns in the target file.
@@ -0,0 +1,16 @@
1
+ ---
2
+ description: Uninstall a plugin from .claude/ folder
3
+ ---
4
+
5
+ Uninstall plugin "$ARGUMENTS".
6
+
7
+ If no argument provided, list installed plugins:
8
+ !`ls -1 .claude/agents/agent-*.md 2>/dev/null | xargs -I{} basename {} .md | sed 's/^agent-//' | sort -u`
9
+
10
+ If argument provided, remove:
11
+ - `.claude/agents/agent-$ARGUMENTS*.md`
12
+ - `.claude/skills/$ARGUMENTS/`
13
+ - `.claude/hooks/$ARGUMENTS*.cjs`
14
+
15
+ Report what was removed.
16
+ Then remind user: "Restart Claude Code: `claude -c`"
@@ -0,0 +1,19 @@
1
+ ---
2
+ description: Pull workspace configuration from Hailer
3
+ ---
4
+
5
+ Pull workspace configuration from Hailer.
6
+
7
+ 1. Get WORKSPACE_CONFIG_PATH:
8
+ !`grep WORKSPACE_CONFIG_PATH .env.local 2>/dev/null || echo "NOT SET"`
9
+
10
+ 2. If set, run pull command in that directory:
11
+ ```bash
12
+ cd "$WORKSPACE_CONFIG_PATH" && npm run ws-pull
13
+ ```
14
+
15
+ 3. After pull, read the generated files to load context:
16
+ - `workspace/enums.ts` - field and phase IDs
17
+ - List `workspace/` to see workflows
18
+
19
+ Report what was pulled.
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "https://opencode.ai/config.json",
3
+ "permission": {
4
+ "bash": {
5
+ "*": "ask",
6
+ "rm -rf *": "deny",
7
+ "rm -r *": "deny"
8
+ },
9
+ "doom_loop": "ask",
10
+ "read": {
11
+ "*": "allow",
12
+ "*.env": "deny",
13
+ "*.env.*": "deny",
14
+ "*.env.example": "allow"
15
+ },
16
+ "edit": "ask",
17
+ "external_directory": "ask",
18
+ "webfetch": "ask",
19
+ "websearch": "ask"
20
+ }
21
+ }
package/dist/app.js CHANGED
@@ -91,7 +91,7 @@ if (config_1.environment.MCP_CLIENT_ENABLED) {
91
91
  // Low-level tools
92
92
  bugFixerFindAppTool, bugFixerListFilesTool, bugFixerReadFileTool, bugFixerWriteFileTool, bugFixerApplyFixTool, bugFixerRunBuildTool, bugFixerGitStatusTool, bugFixerGitPullTool, bugFixerGitCommitTool, bugFixerGitPushTool, bugFixerGitRevertTool, bugFixerPublishAppTool,
93
93
  // High-level workflow tools (LLM-driven)
94
- bugFixerAnalyzeBugTool, bugFixerStartFixTool, bugFixerMarkDeclinedTool, bugFixerPublishFixTool, bugFixerRetryFixTool } = require('./mcp/tools/bug-fixer-tools');
94
+ bugFixerAnalyzeBugTool, bugFixerStartFixTool, bugFixerMarkDeclinedTool, bugFixerPublishFixTool, bugFixerRetryFixTool, markBugDeclinedTool, markBugFixedTool } = require('./mcp/tools/bug-fixer-tools');
95
95
  // Low-level tools
96
96
  core.addTool(bugFixerFindAppTool);
97
97
  core.addTool(bugFixerListFilesTool);
@@ -111,6 +111,8 @@ if (config_1.environment.MCP_CLIENT_ENABLED) {
111
111
  core.addTool(bugFixerMarkDeclinedTool);
112
112
  core.addTool(bugFixerPublishFixTool);
113
113
  core.addTool(bugFixerRetryFixTool);
114
+ core.addTool(markBugDeclinedTool);
115
+ core.addTool(markBugFixedTool);
114
116
  logger.info('Bot-internal tools registered (MCP_CLIENT_ENABLED=true)');
115
117
  }
116
118
  logger.info('All tools registered successfully');
@@ -39,5 +39,7 @@ export declare const bugFixerPublishFixTool: Tool;
39
39
  * Retry Fix Tool - Retry a fix with additional context/explanation
40
40
  */
41
41
  export declare const bugFixerRetryFixTool: Tool;
42
+ export declare const markBugDeclinedTool: Tool;
43
+ export declare const markBugFixedTool: Tool;
42
44
  export declare const bugFixerTools: Tool[];
43
45
  //# sourceMappingURL=bug-fixer-tools.d.ts.map
@@ -39,7 +39,7 @@ var __importStar = (this && this.__importStar) || (function () {
39
39
  };
40
40
  })();
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.bugFixerTools = exports.bugFixerRetryFixTool = exports.bugFixerPublishFixTool = exports.bugFixerMarkDeclinedTool = exports.bugFixerStartFixTool = exports.bugFixerAnalyzeBugTool = exports.bugFixerPublishAppTool = exports.bugFixerGitRevertTool = exports.bugFixerGitPushTool = exports.bugFixerGitCommitTool = exports.bugFixerGitPullTool = exports.bugFixerGitStatusTool = exports.bugFixerRunBuildTool = exports.bugFixerApplyFixTool = exports.bugFixerWriteFileTool = exports.bugFixerReadFileTool = exports.bugFixerListFilesTool = exports.bugFixerFindAppTool = void 0;
42
+ exports.bugFixerTools = exports.markBugFixedTool = exports.markBugDeclinedTool = exports.bugFixerRetryFixTool = exports.bugFixerPublishFixTool = exports.bugFixerMarkDeclinedTool = exports.bugFixerStartFixTool = exports.bugFixerAnalyzeBugTool = exports.bugFixerPublishAppTool = exports.bugFixerGitRevertTool = exports.bugFixerGitPushTool = exports.bugFixerGitCommitTool = exports.bugFixerGitPullTool = exports.bugFixerGitStatusTool = exports.bugFixerRunBuildTool = exports.bugFixerApplyFixTool = exports.bugFixerWriteFileTool = exports.bugFixerReadFileTool = exports.bugFixerListFilesTool = exports.bugFixerFindAppTool = void 0;
43
43
  const zod_1 = require("zod");
44
44
  const child_process_1 = require("child_process");
45
45
  const fs = __importStar(require("fs/promises"));
@@ -916,6 +916,158 @@ Call this when the user explains why the previous fix didn't work.`,
916
916
  }
917
917
  }
918
918
  };
919
+ // Mark Bug Declined Tool - handles everything automatically
920
+ exports.markBugDeclinedTool = {
921
+ name: "mark_bug_declined",
922
+ group: tool_registry_1.ToolGroup.BOT_INTERNAL,
923
+ description: "Mark a bug as declined (not a bug / won't fix). Automatically sets phase to Declined, status to 'Won't Fix', and leaves the discussion.",
924
+ schema: zod_1.z.object({
925
+ bugId: zod_1.z.string().describe("The bug activity ID"),
926
+ workflowId: zod_1.z.string().describe("The workflow ID for the Bug Reports workflow"),
927
+ discussionId: zod_1.z.string().describe("The discussion ID to leave after marking declined"),
928
+ reason: zod_1.z.string().optional().describe("Optional reason for declining"),
929
+ }),
930
+ async execute(args, context) {
931
+ const { bugId, workflowId, discussionId, reason } = args;
932
+ const { hailer } = context;
933
+ try {
934
+ // 1. Get workflow phases from cached init data (reliable method used by list_workflow_phases)
935
+ const workflowData = context.init.processes?.find((p) => p._id === workflowId);
936
+ if (!workflowData) {
937
+ return {
938
+ content: [{ type: "text", text: JSON.stringify({
939
+ success: false,
940
+ error: `Workflow ${workflowId} not found`
941
+ }) }]
942
+ };
943
+ }
944
+ const phases = workflowData.phases || {};
945
+ const declinedPhase = Object.entries(phases).find(([_, phase]) => phase.name?.toLowerCase() === 'declined');
946
+ if (!declinedPhase) {
947
+ return {
948
+ content: [{ type: "text", text: JSON.stringify({
949
+ success: false,
950
+ error: "Could not find 'Declined' phase in workflow",
951
+ availablePhases: Object.values(phases).map((p) => p.name)
952
+ }) }]
953
+ };
954
+ }
955
+ const [declinedPhaseId, declinedPhaseData] = declinedPhase;
956
+ // 2. Get workflow schema to find status field ID
957
+ const schema = await hailer.getWorkflowSchema(workflowId, declinedPhaseId);
958
+ const statusField = Object.entries(schema.fields || {}).find(([_, f]) => f.key === 'status' || f.label?.toLowerCase() === 'status');
959
+ // 3. Update activity with phase AND status
960
+ const updateData = {
961
+ _id: bugId,
962
+ phaseId: declinedPhaseId,
963
+ };
964
+ if (statusField) {
965
+ updateData.fields = { [statusField[0]]: "Won't Fix" };
966
+ }
967
+ await hailer.updateActivities([updateData]);
968
+ // 4. Leave the discussion
969
+ try {
970
+ await hailer.leaveDiscussion(discussionId);
971
+ }
972
+ catch (e) {
973
+ // Ignore leave errors - might already be out
974
+ }
975
+ return {
976
+ content: [{ type: "text", text: JSON.stringify({
977
+ success: true,
978
+ phase: "Declined",
979
+ status: "Won't Fix",
980
+ leftDiscussion: true,
981
+ reason: reason || "Not a bug"
982
+ }) }]
983
+ };
984
+ }
985
+ catch (error) {
986
+ return {
987
+ content: [{ type: "text", text: JSON.stringify({
988
+ success: false,
989
+ error: error instanceof Error ? error.message : String(error)
990
+ }) }]
991
+ };
992
+ }
993
+ }
994
+ };
995
+ // Mark Bug Fixed Tool - handles everything automatically
996
+ exports.markBugFixedTool = {
997
+ name: "mark_bug_fixed",
998
+ group: tool_registry_1.ToolGroup.BOT_INTERNAL,
999
+ description: "Mark a bug as fixed. Automatically sets phase to Fixed, status to 'Fixed', and leaves the discussion. Only use AFTER fix is published and user confirmed it works!",
1000
+ schema: zod_1.z.object({
1001
+ bugId: zod_1.z.string().describe("The bug activity ID"),
1002
+ workflowId: zod_1.z.string().describe("The workflow ID for the Bug Reports workflow"),
1003
+ discussionId: zod_1.z.string().describe("The discussion ID to leave after marking fixed"),
1004
+ fixSummary: zod_1.z.string().optional().describe("Optional summary of what was fixed"),
1005
+ }),
1006
+ async execute(args, context) {
1007
+ const { bugId, workflowId, discussionId, fixSummary } = args;
1008
+ const { hailer } = context;
1009
+ try {
1010
+ // 1. Get workflow phases from cached init data (reliable method used by list_workflow_phases)
1011
+ const workflowData = context.init.processes?.find((p) => p._id === workflowId);
1012
+ if (!workflowData) {
1013
+ return {
1014
+ content: [{ type: "text", text: JSON.stringify({
1015
+ success: false,
1016
+ error: `Workflow ${workflowId} not found`
1017
+ }) }]
1018
+ };
1019
+ }
1020
+ const phases = workflowData.phases || {};
1021
+ const fixedPhase = Object.entries(phases).find(([_, phase]) => phase.name?.toLowerCase() === 'fixed');
1022
+ if (!fixedPhase) {
1023
+ return {
1024
+ content: [{ type: "text", text: JSON.stringify({
1025
+ success: false,
1026
+ error: "Could not find 'Fixed' phase in workflow",
1027
+ availablePhases: Object.values(phases).map((p) => p.name)
1028
+ }) }]
1029
+ };
1030
+ }
1031
+ const [fixedPhaseId, fixedPhaseData] = fixedPhase;
1032
+ // 2. Get workflow schema to find status field ID
1033
+ const schema = await hailer.getWorkflowSchema(workflowId, fixedPhaseId);
1034
+ const statusField = Object.entries(schema.fields || {}).find(([_, f]) => f.key === 'status' || f.label?.toLowerCase() === 'status');
1035
+ // 3. Update activity with phase AND status
1036
+ const updateData = {
1037
+ _id: bugId,
1038
+ phaseId: fixedPhaseId,
1039
+ };
1040
+ if (statusField) {
1041
+ updateData.fields = { [statusField[0]]: "Fixed" };
1042
+ }
1043
+ await hailer.updateActivities([updateData]);
1044
+ // 4. Leave the discussion
1045
+ try {
1046
+ await hailer.leaveDiscussion(discussionId);
1047
+ }
1048
+ catch (e) {
1049
+ // Ignore leave errors - might already be out
1050
+ }
1051
+ return {
1052
+ content: [{ type: "text", text: JSON.stringify({
1053
+ success: true,
1054
+ phase: "Fixed",
1055
+ status: "Fixed",
1056
+ leftDiscussion: true,
1057
+ fixSummary: fixSummary || "Bug fixed"
1058
+ }) }]
1059
+ };
1060
+ }
1061
+ catch (error) {
1062
+ return {
1063
+ content: [{ type: "text", text: JSON.stringify({
1064
+ success: false,
1065
+ error: error instanceof Error ? error.message : String(error)
1066
+ }) }]
1067
+ };
1068
+ }
1069
+ }
1070
+ };
919
1071
  // Export all tools
920
1072
  exports.bugFixerTools = [
921
1073
  // Low-level tools
@@ -937,5 +1089,8 @@ exports.bugFixerTools = [
937
1089
  exports.bugFixerMarkDeclinedTool,
938
1090
  exports.bugFixerPublishFixTool,
939
1091
  exports.bugFixerRetryFixTool,
1092
+ // Standalone phase/status tools (no registry dependency)
1093
+ exports.markBugDeclinedTool,
1094
+ exports.markBugFixedTool,
940
1095
  ];
941
1096
  //# sourceMappingURL=bug-fixer-tools.js.map
@@ -168,7 +168,8 @@ class MCPServerService {
168
168
  }
169
169
  // Apply default tool group filtering
170
170
  // - NUCLEAR: Only if ENABLE_NUCLEAR_TOOLS=true
171
- // - BOT_INTERNAL: Never exposed to MCP clients (autonomous bot tools only)
171
+ // - BOT_INTERNAL: Only if explicitly requested via params.includeBotInternal (for daemons)
172
+ const includeBotInternal = mcpRequest.params?.includeBotInternal === true;
172
173
  if (!filterConfig) {
173
174
  // No filter yet - create default excluding NUCLEAR and BOT_INTERNAL
174
175
  filterConfig = {
@@ -177,12 +178,13 @@ class MCPServerService {
177
178
  req.logger.debug('Using default tool filter (excludes NUCLEAR and BOT_INTERNAL)');
178
179
  }
179
180
  else if (filterConfig.allowedGroups) {
180
- // Filter has groups - always remove BOT_INTERNAL, remove NUCLEAR unless enabled
181
- filterConfig.allowedGroups = filterConfig.allowedGroups.filter(g => g !== tool_registry_1.ToolGroup.BOT_INTERNAL &&
181
+ // Filter groups - remove BOT_INTERNAL unless explicitly requested, remove NUCLEAR unless enabled
182
+ filterConfig.allowedGroups = filterConfig.allowedGroups.filter(g => (includeBotInternal || g !== tool_registry_1.ToolGroup.BOT_INTERNAL) &&
182
183
  (config_1.environment.ENABLE_NUCLEAR_TOOLS || g !== tool_registry_1.ToolGroup.NUCLEAR));
183
184
  req.logger.debug('Filtered tool groups', {
184
185
  allowedGroups: filterConfig.allowedGroups,
185
- nuclearEnabled: config_1.environment.ENABLE_NUCLEAR_TOOLS
186
+ nuclearEnabled: config_1.environment.ENABLE_NUCLEAR_TOOLS,
187
+ includeBotInternal
186
188
  });
187
189
  }
188
190
  result = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hailer/mcp",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "config": {
5
5
  "docker": {
6
6
  "registry": "registry.gitlab.com/hailer-repos/hailer-mcp"