@hailer/mcp 1.0.29 → 1.1.2
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/.session-checked +1 -0
- package/.claude/agents/agent-ada-skill-builder.md +10 -2
- package/.claude/agents/agent-alejandro-function-fields.md +104 -37
- package/.claude/agents/agent-bjorn-config-audit.md +41 -21
- package/.claude/agents/agent-builder-agent-creator.md +13 -3
- package/.claude/agents/agent-code-simplifier.md +53 -0
- package/.claude/agents/agent-dmitri-activity-crud.md +126 -11
- package/.claude/agents/agent-giuseppe-app-builder.md +212 -22
- package/.claude/agents/agent-gunther-mcp-tools.md +7 -36
- package/.claude/agents/agent-helga-workflow-config.md +75 -10
- package/.claude/agents/agent-igor-activity-mover-automation.md +125 -0
- package/.claude/agents/agent-ingrid-doc-templates.md +164 -36
- package/.claude/agents/agent-ivan-monolith.md +154 -0
- package/.claude/agents/agent-kenji-data-reader.md +15 -8
- package/.claude/agents/agent-lars-code-inspector.md +56 -8
- package/.claude/agents/agent-marco-mockup-builder.md +110 -0
- package/.claude/agents/agent-marcus-api-documenter.md +323 -0
- package/.claude/agents/agent-marketplace-publisher.md +232 -72
- package/.claude/agents/agent-marketplace-reviewer.md +255 -79
- package/.claude/agents/agent-permissions-handler.md +208 -0
- package/.claude/agents/agent-simple-writer.md +48 -0
- package/.claude/agents/agent-svetlana-code-review.md +127 -14
- package/.claude/agents/agent-tanya-test-runner.md +333 -0
- package/.claude/agents/agent-ui-designer.md +100 -0
- package/.claude/agents/agent-viktor-sql-insights.md +19 -6
- package/.claude/agents/agent-web-search.md +55 -0
- package/.claude/agents/agent-yevgeni-discussions.md +7 -1
- package/.claude/agents/agent-zara-zapier.md +159 -0
- package/.claude/commands/app-squad.md +135 -0
- package/.claude/commands/audit-squad.md +158 -0
- package/.claude/commands/autoplan.md +563 -0
- package/.claude/commands/cleanup-squad.md +98 -0
- package/.claude/commands/config-squad.md +106 -0
- package/.claude/commands/crud-squad.md +87 -0
- package/.claude/commands/data-squad.md +97 -0
- package/.claude/commands/debug-squad.md +303 -0
- package/.claude/commands/doc-squad.md +65 -0
- package/.claude/commands/handoff.md +137 -0
- package/.claude/commands/health.md +49 -0
- package/.claude/commands/help.md +2 -1
- package/.claude/commands/help:agents.md +96 -16
- package/.claude/commands/help:commands.md +55 -11
- package/.claude/commands/help:faq.md +16 -1
- package/.claude/commands/help:skills.md +93 -0
- package/.claude/commands/hotfix-squad.md +112 -0
- package/.claude/commands/integration-squad.md +82 -0
- package/.claude/commands/janitor-squad.md +167 -0
- package/.claude/commands/learn-auto.md +120 -0
- package/.claude/commands/learn.md +120 -0
- package/.claude/commands/mcp-list.md +27 -0
- package/.claude/commands/onboard-squad.md +140 -0
- package/.claude/commands/plan-workspace.md +732 -0
- package/.claude/commands/prd.md +131 -0
- package/.claude/commands/project-status.md +82 -0
- package/.claude/commands/publish.md +138 -0
- package/.claude/commands/recap.md +69 -0
- package/.claude/commands/restore.md +64 -0
- package/.claude/commands/review-squad.md +152 -0
- package/.claude/commands/save.md +24 -0
- package/.claude/commands/stats.md +19 -0
- package/.claude/commands/swarm.md +210 -0
- package/.claude/commands/tool-builder.md +3 -1
- package/.claude/commands/ws-pull.md +1 -1
- package/.claude/commands/yolo-off.md +17 -0
- package/.claude/commands/yolo.md +82 -0
- package/.claude/hooks/_shared-memory.cjs +305 -0
- package/.claude/hooks/_utils.cjs +134 -0
- package/.claude/hooks/agent-failure-detector.cjs +164 -79
- package/.claude/hooks/agent-usage-logger.cjs +204 -0
- package/.claude/hooks/app-edit-guard.cjs +20 -4
- package/.claude/hooks/auto-learn.cjs +316 -0
- package/.claude/hooks/bash-guard.cjs +282 -0
- package/.claude/hooks/builder-mode-manager.cjs +183 -54
- package/.claude/hooks/bulk-activity-guard.cjs +283 -0
- package/.claude/hooks/context-watchdog.cjs +292 -0
- package/.claude/hooks/delegation-reminder.cjs +478 -0
- package/.claude/hooks/design-system-lint.cjs +283 -0
- package/.claude/hooks/post-scaffold-hook.cjs +16 -3
- package/.claude/hooks/prompt-guard.cjs +366 -0
- package/.claude/hooks/publish-template-guard.cjs +16 -0
- package/.claude/hooks/session-start.cjs +35 -0
- package/.claude/hooks/shared-memory-writer.cjs +147 -0
- package/.claude/hooks/skill-injector.cjs +140 -0
- package/.claude/hooks/skill-usage-logger.cjs +258 -0
- package/.claude/hooks/src-edit-guard.cjs +16 -1
- package/.claude/hooks/sync-marketplace-agents.cjs +53 -8
- package/.claude/scripts/yolo-toggle.cjs +142 -0
- package/.claude/settings.json +141 -14
- package/.claude/skills/SDK-activity-patterns/SKILL.md +428 -0
- package/.claude/skills/SDK-document-templates/SKILL.md +1033 -0
- package/.claude/skills/SDK-function-fields/SKILL.md +542 -0
- package/.claude/skills/SDK-generate-skill/SKILL.md +92 -0
- package/.claude/skills/SDK-init-skill/SKILL.md +127 -0
- package/.claude/skills/SDK-insight-queries/SKILL.md +787 -0
- package/.claude/skills/SDK-ws-config-skill/SKILL.md +1139 -0
- package/.claude/skills/agent-structure/SKILL.md +98 -0
- package/.claude/skills/api-documentation-patterns/SKILL.md +474 -0
- package/.claude/skills/chrome-mcp-reference/SKILL.md +370 -0
- package/.claude/skills/delegation-routing/SKILL.md +202 -0
- package/.claude/skills/frontend-design/SKILL.md +254 -0
- package/.claude/skills/hailer-activity-mover/SKILL.md +213 -0
- package/.claude/skills/hailer-api-client/SKILL.md +518 -0
- package/.claude/skills/hailer-app-builder/SKILL.md +939 -11
- package/.claude/skills/hailer-apps-pictures/SKILL.md +269 -0
- package/.claude/skills/hailer-design-system/SKILL.md +235 -0
- package/.claude/skills/hailer-monolith-automations/SKILL.md +686 -0
- package/.claude/skills/hailer-permissions-system/SKILL.md +121 -0
- package/.claude/skills/hailer-project-protocol/SKILL.md +488 -0
- package/.claude/skills/hailer-rest-api/SKILL.md +61 -0
- package/.claude/skills/hailer-rest-api/hailer-activities.md +184 -0
- package/.claude/skills/hailer-rest-api/hailer-admin.md +473 -0
- package/.claude/skills/hailer-rest-api/hailer-calendar.md +256 -0
- package/.claude/skills/hailer-rest-api/hailer-feed.md +249 -0
- package/.claude/skills/hailer-rest-api/hailer-insights.md +195 -0
- package/.claude/skills/hailer-rest-api/hailer-messaging.md +276 -0
- package/.claude/skills/hailer-rest-api/hailer-workflows.md +283 -0
- package/.claude/skills/insight-join-patterns/SKILL.md +3 -0
- package/.claude/skills/integration-patterns/SKILL.md +421 -0
- package/.claude/skills/json-only-output/SKILL.md +52 -12
- package/.claude/skills/lsp-setup/SKILL.md +160 -0
- package/.claude/skills/mcp-direct-tools/SKILL.md +153 -0
- package/.claude/skills/optional-parameters/SKILL.md +32 -23
- package/.claude/skills/publish-hailer-app/SKILL.md +76 -12
- package/.claude/skills/testing-patterns/SKILL.md +630 -0
- package/.claude/skills/tool-builder/SKILL.md +250 -0
- package/.claude/skills/tool-parameter-usage/SKILL.md +59 -45
- package/.claude/skills/tool-response-verification/SKILL.md +82 -48
- package/.claude/skills/zapier-hailer-patterns/SKILL.md +581 -0
- package/.env.example +26 -7
- package/CLAUDE.md +290 -224
- package/dist/CLAUDE.md +370 -0
- package/dist/app.d.ts +1 -1
- package/dist/app.js +101 -101
- package/dist/bot/bot-config.d.ts +26 -0
- package/dist/bot/bot-config.js +135 -0
- package/dist/bot/bot-manager.d.ts +40 -0
- package/dist/bot/bot-manager.js +137 -0
- package/dist/bot/bot.d.ts +127 -0
- package/dist/bot/bot.js +1328 -0
- package/dist/bot/operation-logger.d.ts +28 -0
- package/dist/bot/operation-logger.js +132 -0
- package/dist/bot/services/conversation-manager.d.ts +60 -0
- package/dist/bot/services/conversation-manager.js +246 -0
- package/dist/bot/services/index.d.ts +9 -0
- package/dist/bot/services/index.js +18 -0
- package/dist/bot/services/message-classifier.d.ts +42 -0
- package/dist/bot/services/message-classifier.js +228 -0
- package/dist/bot/services/message-formatter.d.ts +88 -0
- package/dist/bot/services/message-formatter.js +411 -0
- package/dist/bot/services/session-logger.d.ts +162 -0
- package/dist/bot/services/session-logger.js +724 -0
- package/dist/bot/services/token-billing.d.ts +78 -0
- package/dist/bot/services/token-billing.js +233 -0
- package/dist/bot/services/types.d.ts +169 -0
- package/dist/bot/services/types.js +12 -0
- package/dist/bot/services/typing-indicator.d.ts +23 -0
- package/dist/bot/services/typing-indicator.js +60 -0
- package/dist/bot/services/workspace-schema-cache.d.ts +122 -0
- package/dist/bot/services/workspace-schema-cache.js +506 -0
- package/dist/bot/tool-executor.d.ts +28 -0
- package/dist/bot/tool-executor.js +48 -0
- package/dist/bot/workspace-overview.d.ts +12 -0
- package/dist/bot/workspace-overview.js +94 -0
- package/dist/cli.d.ts +1 -8
- package/dist/cli.js +1 -253
- package/dist/config.d.ts +96 -3
- package/dist/config.js +148 -37
- package/dist/core.d.ts +5 -0
- package/dist/core.js +61 -8
- package/dist/lib/discussion-lock.d.ts +42 -0
- package/dist/lib/discussion-lock.js +110 -0
- package/dist/lib/logger.d.ts +0 -1
- package/dist/lib/logger.js +39 -23
- package/dist/lib/request-logger.d.ts +77 -0
- package/dist/lib/request-logger.js +147 -0
- package/dist/mcp/UserContextCache.js +16 -13
- package/dist/mcp/hailer-clients.js +18 -17
- package/dist/mcp/signal-handler.js +29 -13
- package/dist/mcp/tool-registry.d.ts +4 -15
- package/dist/mcp/tool-registry.js +94 -32
- package/dist/mcp/tools/activity.js +28 -69
- package/dist/mcp/tools/app-core.js +9 -4
- package/dist/mcp/tools/app-marketplace.js +22 -12
- package/dist/mcp/tools/app-member.js +5 -2
- package/dist/mcp/tools/app-scaffold.js +32 -18
- package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
- package/dist/mcp/tools/bot-config/constants.js +94 -0
- package/dist/mcp/tools/bot-config/core.d.ts +253 -0
- package/dist/mcp/tools/bot-config/core.js +2456 -0
- package/dist/mcp/tools/bot-config/index.d.ts +10 -0
- package/dist/mcp/tools/bot-config/index.js +59 -0
- package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
- package/dist/mcp/tools/bot-config/tools.js +15 -0
- package/dist/mcp/tools/bot-config/types.d.ts +50 -0
- package/dist/mcp/tools/bot-config/types.js +6 -0
- package/dist/mcp/tools/discussion.js +107 -77
- package/dist/mcp/tools/document.d.ts +11 -0
- package/dist/mcp/tools/document.js +741 -0
- package/dist/mcp/tools/file.js +5 -2
- package/dist/mcp/tools/insight.js +36 -12
- package/dist/mcp/tools/investigate.d.ts +9 -0
- package/dist/mcp/tools/investigate.js +254 -0
- package/dist/mcp/tools/user.d.ts +2 -4
- package/dist/mcp/tools/user.js +9 -50
- package/dist/mcp/tools/workflow.d.ts +1 -0
- package/dist/mcp/tools/workflow.js +164 -52
- package/dist/mcp/utils/hailer-api-client.js +26 -17
- package/dist/mcp/webhook-handler.d.ts +64 -3
- package/dist/mcp/webhook-handler.js +219 -9
- package/dist/mcp-server.d.ts +4 -0
- package/dist/mcp-server.js +237 -25
- package/dist/plugins/bug-fixer/index.d.ts +2 -0
- package/dist/plugins/bug-fixer/index.js +18 -0
- package/dist/plugins/bug-fixer/tools.d.ts +45 -0
- package/dist/plugins/bug-fixer/tools.js +1096 -0
- package/package.json +10 -10
- package/scripts/test-hal-tools.ts +154 -0
- package/.claude/agents/agent-nora-name-functions.md +0 -123
- package/.claude/assistant-knowledge.md +0 -23
- package/.claude/commands/install-plugin.md +0 -261
- package/.claude/commands/list-plugins.md +0 -42
- package/.claude/commands/marketplace-setup.md +0 -33
- package/.claude/commands/publish-plugin.md +0 -55
- package/.claude/commands/uninstall-plugin.md +0 -87
- package/.claude/hooks/interactive-mode.cjs +0 -87
- package/.claude/hooks/mcp-server-guard.cjs +0 -108
- package/.claude/skills/marketplace-publishing.md +0 -155
- package/dist/bot/chat-bot.d.ts +0 -31
- package/dist/bot/chat-bot.js +0 -357
- package/dist/mcp/tools/metrics.d.ts +0 -13
- package/dist/mcp/tools/metrics.js +0 -546
- package/dist/stdio-server.d.ts +0 -14
- package/dist/stdio-server.js +0 -114
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hailer/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"config": {
|
|
5
5
|
"docker": {
|
|
6
6
|
"registry": "registry.gitlab.com/hailer-repos/hailer-mcp"
|
|
@@ -10,25 +10,26 @@
|
|
|
10
10
|
"dev": "tsx watch src/app.ts",
|
|
11
11
|
"claude-code-mcp": "DISABLE_CLIENT=true tsx src/app.ts",
|
|
12
12
|
"start-mcp-only": "DISABLE_CLIENT=true tsx src/app.ts",
|
|
13
|
+
"start-client-only": "DISABLE_MCP_SERVER=true tsx src/app.ts",
|
|
13
14
|
"build": "tsc",
|
|
14
15
|
"start": "node dist/app.js",
|
|
15
16
|
"lint": "eslint src/",
|
|
16
|
-
"build-dev-push": "rm -rf build/docker-dev && docker build --target artifacts --output build/docker-dev . -f Dockerfile.build-dev && docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-dev -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):dev -f ./Dockerfile.dev .",
|
|
17
|
-
"build-debug-push": "docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-debug -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):debug -f ./Dockerfile.debug .",
|
|
18
|
-
"build-prod-push": "rm -rf build/docker-prod && docker build --target artifacts --output build/docker-prod . -f Dockerfile.build-prod && docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs) -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):prod -f ./Dockerfile.prod .",
|
|
19
|
-
"build-k3d": "docker build -f Dockerfile.debug . -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs) && k3d image import $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs) -c hailer",
|
|
20
|
-
"build-k3d-dummy": "docker build --target artifacts --output build/docker-dev . -f Dockerfile.build-dev && docker build -f Dockerfile.dev . -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-dev && k3d image import $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-dev -c hailer",
|
|
17
|
+
"build-dev-push": "rm -rf build/docker-dev && docker build --target artifacts --output build/docker-dev . -f Dockerfile.build-dev && docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs)-dev -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):dev -f ./Dockerfile.dev .",
|
|
18
|
+
"build-debug-push": "docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs)-debug -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):debug -f ./Dockerfile.debug .",
|
|
19
|
+
"build-prod-push": "rm -rf build/docker-prod && docker build --target artifacts --output build/docker-prod . -f Dockerfile.build-prod && docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs) -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):prod -f ./Dockerfile.prod .",
|
|
20
|
+
"build-k3d": "docker build -f Dockerfile.debug . -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs) && k3d image import $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs) -c hailer",
|
|
21
|
+
"build-k3d-dummy": "docker build --target artifacts --output build/docker-dev . -f Dockerfile.build-dev && docker build -f Dockerfile.dev . -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs)-dev && k3d image import $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs)-dev -c hailer",
|
|
21
22
|
"mcp-server": "hailer-mcp",
|
|
23
|
+
"server": "tsx src/client/server.ts",
|
|
24
|
+
"server:prod": "node dist/client/server.js",
|
|
22
25
|
"release:patch": "npm version patch -m 'chore: release v%s' && git push && git push --tags && npm run build && npm publish --access public",
|
|
23
26
|
"release:minor": "npm version minor -m 'chore: release v%s' && git push && git push --tags && npm run build && npm publish --access public",
|
|
24
27
|
"release:major": "npm version major -m 'chore: release v%s' && git push && git push --tags && npm run build && npm publish --access public",
|
|
25
|
-
"seed-config": "tsx src/commands/seed-config.ts"
|
|
26
|
-
"bot": "tsx src/bot/chat-bot.ts"
|
|
28
|
+
"seed-config": "tsx src/commands/seed-config.ts"
|
|
27
29
|
},
|
|
28
30
|
"dependencies": {
|
|
29
31
|
"@anthropic-ai/sdk": "^0.54.0",
|
|
30
32
|
"@hailer/cli": "^1.1.10",
|
|
31
|
-
"@hailer/mcp": "^1.0.24",
|
|
32
33
|
"@modelcontextprotocol/sdk": "^1.11.5",
|
|
33
34
|
"@opentelemetry/api-logs": "^0.57.0",
|
|
34
35
|
"@opentelemetry/exporter-logs-otlp-proto": "^0.57.0",
|
|
@@ -36,7 +37,6 @@
|
|
|
36
37
|
"@opentelemetry/sdk-logs": "^0.57.0",
|
|
37
38
|
"@opentelemetry/sdk-node": "^0.57.0",
|
|
38
39
|
"@opentelemetry/semantic-conventions": "^1.36.0",
|
|
39
|
-
"axios": "^1.13.4",
|
|
40
40
|
"cors": "^2.8.5",
|
|
41
41
|
"dotenv": "^16.5.0",
|
|
42
42
|
"express": "^4.21.2",
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env npx ts-node
|
|
2
|
+
/**
|
|
3
|
+
* HAL Tools Test - Simple version
|
|
4
|
+
* Just calls each tool and shows the result. No magic.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as dotenv from 'dotenv';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
|
|
10
|
+
dotenv.config({ path: path.join(__dirname, '..', '.env.local') });
|
|
11
|
+
|
|
12
|
+
const MCP_URL = process.env.MCP_SERVER_URL || 'http://localhost:3030/api/mcp';
|
|
13
|
+
|
|
14
|
+
async function call(apiKey: string, tool: string, args: Record<string, unknown> = {}) {
|
|
15
|
+
console.log(`\n>>> ${tool}`);
|
|
16
|
+
console.log(` args: ${JSON.stringify(args)}`);
|
|
17
|
+
|
|
18
|
+
const res = await fetch(`${MCP_URL}?apiKey=${apiKey}`, {
|
|
19
|
+
method: 'POST',
|
|
20
|
+
headers: { 'Content-Type': 'application/json' },
|
|
21
|
+
body: JSON.stringify({
|
|
22
|
+
jsonrpc: '2.0',
|
|
23
|
+
id: '1',
|
|
24
|
+
method: 'tools/call',
|
|
25
|
+
params: { name: tool, arguments: args },
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const text = await res.text();
|
|
30
|
+
for (const line of text.split('\n')) {
|
|
31
|
+
if (line.startsWith('data: ')) {
|
|
32
|
+
const data = JSON.parse(line.substring(6));
|
|
33
|
+
if (data.error) {
|
|
34
|
+
console.log(`<<< ERROR: ${data.error.message}`);
|
|
35
|
+
return { error: true, data: null };
|
|
36
|
+
}
|
|
37
|
+
const content = data.result?.content?.[0]?.text || '';
|
|
38
|
+
// Show first 500 chars
|
|
39
|
+
console.log(`<<< ${content.substring(0, 500)}${content.length > 500 ? '...' : ''}`);
|
|
40
|
+
return { error: false, content };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
console.log('<<< NO RESPONSE');
|
|
44
|
+
return { error: true, data: null };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function main() {
|
|
48
|
+
const apiKey = process.env.MCP_CLIENT_API_KEY;
|
|
49
|
+
if (!apiKey) {
|
|
50
|
+
console.error('Set MCP_CLIENT_API_KEY in .env.local');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
console.log('=== HAL TOOLS TEST ===\n');
|
|
55
|
+
|
|
56
|
+
// Get a workflow to work with
|
|
57
|
+
const wf = await call(apiKey, 'list_workflows_minimal', {});
|
|
58
|
+
const wfMatch = wf.content?.match(/`([a-f0-9]{24})`/);
|
|
59
|
+
const workflowId = wfMatch?.[1];
|
|
60
|
+
console.log(`\n[Using workflowId: ${workflowId}]`);
|
|
61
|
+
|
|
62
|
+
if (!workflowId) {
|
|
63
|
+
console.log('No workflow found, stopping');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Get phase
|
|
68
|
+
const ph = await call(apiKey, 'list_workflow_phases', { workflowId });
|
|
69
|
+
const phMatch = ph.content?.match(/`([a-f0-9]{24})`/);
|
|
70
|
+
const phaseId = phMatch?.[1];
|
|
71
|
+
console.log(`\n[Using phaseId: ${phaseId}]`);
|
|
72
|
+
|
|
73
|
+
// Schema
|
|
74
|
+
await call(apiKey, 'get_workflow_schema', { workflowId, phaseId });
|
|
75
|
+
|
|
76
|
+
// List activities
|
|
77
|
+
await call(apiKey, 'list_activities', { workflowId, phaseId, fields: '[]' });
|
|
78
|
+
|
|
79
|
+
// Count
|
|
80
|
+
await call(apiKey, 'count_activities', { workflowId });
|
|
81
|
+
|
|
82
|
+
// Create activity
|
|
83
|
+
const created = await call(apiKey, 'create_activity', {
|
|
84
|
+
workflowId,
|
|
85
|
+
name: `TEST_${Date.now()}`
|
|
86
|
+
});
|
|
87
|
+
const actMatch = created.content?.match(/\*\*ID\*\*:\s*([a-f0-9]{24})/);
|
|
88
|
+
const activityId = actMatch?.[1];
|
|
89
|
+
console.log(`\n[Created activityId: ${activityId}]`);
|
|
90
|
+
|
|
91
|
+
if (activityId) {
|
|
92
|
+
// Show it
|
|
93
|
+
await call(apiKey, 'show_activity_by_id', { activityId });
|
|
94
|
+
|
|
95
|
+
// Update it
|
|
96
|
+
await call(apiKey, 'update_activity', { activityId, name: `UPDATED_${Date.now()}` });
|
|
97
|
+
|
|
98
|
+
// Delete it (this tool doesn't exist yet)
|
|
99
|
+
await call(apiKey, 'delete_activity', { activityId });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Insights
|
|
103
|
+
await call(apiKey, 'list_insights', {});
|
|
104
|
+
|
|
105
|
+
const sources = [{
|
|
106
|
+
name: 'src',
|
|
107
|
+
workflowId,
|
|
108
|
+
fields: [{ meta: 'name', name: 'Name', as: 'name' }]
|
|
109
|
+
}];
|
|
110
|
+
|
|
111
|
+
await call(apiKey, 'preview_insight', { sources, query: 'SELECT * FROM src LIMIT 3' });
|
|
112
|
+
|
|
113
|
+
const ins = await call(apiKey, 'create_insight', {
|
|
114
|
+
name: `TEST_${Date.now()}`,
|
|
115
|
+
sources,
|
|
116
|
+
query: 'SELECT * FROM src LIMIT 3'
|
|
117
|
+
});
|
|
118
|
+
const insMatch = ins.content?.match(/`([a-f0-9]{24})`/);
|
|
119
|
+
const insightId = insMatch?.[1];
|
|
120
|
+
|
|
121
|
+
if (insightId) {
|
|
122
|
+
await call(apiKey, 'get_insight_data', { insightId });
|
|
123
|
+
await call(apiKey, 'remove_insight', { insightId });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Discussions
|
|
127
|
+
await call(apiKey, 'list_my_discussions', {});
|
|
128
|
+
|
|
129
|
+
if (activityId) {
|
|
130
|
+
await call(apiKey, 'join_discussion', { activityId });
|
|
131
|
+
// Get discussion from activity
|
|
132
|
+
const act = await call(apiKey, 'show_activity_by_id', { activityId });
|
|
133
|
+
const discMatch = act.content?.match(/discussion.*?([a-f0-9]{24})/i);
|
|
134
|
+
const discussionId = discMatch?.[1];
|
|
135
|
+
|
|
136
|
+
if (discussionId) {
|
|
137
|
+
await call(apiKey, 'fetch_discussion_messages', { discussionId });
|
|
138
|
+
await call(apiKey, 'add_discussion_message', { discussionId, content: 'TEST' });
|
|
139
|
+
await call(apiKey, 'get_activity_from_discussion', { discussionId });
|
|
140
|
+
await call(apiKey, 'leave_discussion', { discussionId });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Other
|
|
145
|
+
await call(apiKey, 'list_workflows', {});
|
|
146
|
+
await call(apiKey, 'list_apps', {});
|
|
147
|
+
await call(apiKey, 'list_templates', {});
|
|
148
|
+
await call(apiKey, 'get_workspace_balance', {});
|
|
149
|
+
await call(apiKey, 'search_workspace_users', { query: 'test' });
|
|
150
|
+
|
|
151
|
+
console.log('\n=== DONE ===');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
main().catch(console.error);
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: agent-nora-name-functions
|
|
3
|
-
description: Creates and manages workflow nameFunction configurations via SDK v0.8.4. Designs JavaScript name generation functions with field dependencies for dynamic activity naming.\n\n<example>\nuser: "Add name function to Employees workflow"\nassistant: {"status":"ready_to_push","result":{"name_function_added":true,"variables":1},"commands":["npm run workflows-push"],"summary":"Added name function to Employees"}\n</example>
|
|
4
|
-
model: haiku
|
|
5
|
-
tools: Bash, Read, Edit, Glob
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
<identity>
|
|
9
|
-
I am Nora, Finnish name function specialist. Every activity deserves a meaningful name. SDK v0.8.4. Output JSON. Full stop.
|
|
10
|
-
|
|
11
|
-
⚠️ EXCLUSIVE DOMAIN: I am the ONLY agent who handles nameField, nameFunction, and nameFunctionVariables. Alejandro does NOT touch these.
|
|
12
|
-
</identity>
|
|
13
|
-
|
|
14
|
-
<handles>
|
|
15
|
-
- Add nameFunction to workflow main.ts files (inline JavaScript, not separate file)
|
|
16
|
-
- Configure nameFunctionVariables with field dependencies (same format as field functions)
|
|
17
|
-
- Enable/disable dynamic activity naming
|
|
18
|
-
- Test name function syntax before deployment
|
|
19
|
-
- EVERYTHING related to nameField and nameFieldFunctions (sole responsibility)
|
|
20
|
-
</handles>
|
|
21
|
-
|
|
22
|
-
<function-rules>
|
|
23
|
-
nameFunction follows SAME rules as Alejandro's field functions:
|
|
24
|
-
- Vanilla JS only (no TypeScript syntax, no imports, no async)
|
|
25
|
-
- NEVER return null/undefined - always return valid string
|
|
26
|
-
- Helper functions MUST be inside main function body
|
|
27
|
-
- Stability required - same inputs = same outputs
|
|
28
|
-
- Safe handling: var x = dep.field || 'default'
|
|
29
|
-
- Division by zero: check denominator > 0
|
|
30
|
-
- Arrays: var arr = dep.arr || []
|
|
31
|
-
- JSON: try/catch with fallback
|
|
32
|
-
|
|
33
|
-
⚠️ CRITICAL SYNTAX: nameFunction is ONLY the function BODY (what's between {}), NOT the full function declaration!
|
|
34
|
-
❌ WRONG: "function(dep) { return 'value'; }"
|
|
35
|
-
✅ CORRECT: "return 'value'"
|
|
36
|
-
</function-rules>
|
|
37
|
-
|
|
38
|
-
<rules>
|
|
39
|
-
1. **NEVER FABRICATE** - Must call tools.
|
|
40
|
-
2. **CRITICAL** - Pull OVERWRITES local changes. Workflow: pull → edit → push → verify success.
|
|
41
|
-
3. Edit main.ts in workspace/[Workflow]_[id]/ directory.
|
|
42
|
-
4. **NEVER run workflows-push** - Return command for orchestrator.
|
|
43
|
-
5. nameFunctionVariables uses field functionVariables format: {varName: {data: [FieldId], type: '='}}.
|
|
44
|
-
6. Set nameFunctionEnabled: true when adding nameFunction.
|
|
45
|
-
7. Use enums from enums.ts - Never hardcode field IDs.
|
|
46
|
-
8. **JSON ONLY** - Output closing brace, then STOP. Zero prose after JSON.
|
|
47
|
-
</rules>
|
|
48
|
-
|
|
49
|
-
<patterns>
|
|
50
|
-
Simple field (current activity):
|
|
51
|
-
nameFunctionVariables: {
|
|
52
|
-
fieldName: { data: [FieldIds.field_name_abc], type: "=" }
|
|
53
|
-
}
|
|
54
|
-
nameFunction: "return (dep.fieldName || 'Unnamed')"
|
|
55
|
-
|
|
56
|
-
Multiple fields:
|
|
57
|
-
nameFunctionVariables: {
|
|
58
|
-
firstName: { data: [FieldIds.first_name], type: "=" },
|
|
59
|
-
lastName: { data: [FieldIds.last_name], type: "=" }
|
|
60
|
-
}
|
|
61
|
-
nameFunction: "return (dep.firstName || '') + ' ' + (dep.lastName || '')"
|
|
62
|
-
|
|
63
|
-
Linked field (forward link ">"):
|
|
64
|
-
nameFunctionVariables: {
|
|
65
|
-
clientName: { data: [FieldIds.client_link, ClientFieldIds.company_name], type: ">" }
|
|
66
|
-
}
|
|
67
|
-
nameFunction: "return 'Project for ' + (dep.clientName || 'Unknown')"
|
|
68
|
-
|
|
69
|
-
With safe number handling:
|
|
70
|
-
nameFunctionVariables: {
|
|
71
|
-
invoiceNum: { data: [FieldIds.invoice_number], type: "=" }
|
|
72
|
-
}
|
|
73
|
-
nameFunction: "var num = Number(dep.invoiceNum) || 0; return 'INV-' + num"
|
|
74
|
-
|
|
75
|
-
With helper function inside:
|
|
76
|
-
nameFunction: "function safe(val) { return val || 'N/A'; } return safe(dep.name) + ' - ' + safe(dep.code)"
|
|
77
|
-
</patterns>
|
|
78
|
-
|
|
79
|
-
<dependency-types>
|
|
80
|
-
"=" - Current activity field → data: [FieldId]
|
|
81
|
-
">" - Forward link (THIS → other) → data: [LinkFieldId, TargetFieldId]
|
|
82
|
-
"<" - Backlink (others → THIS) → data: [WorkflowId, TargetFieldId] (returns array)
|
|
83
|
-
|
|
84
|
-
CRITICAL: Forward links use LinkFieldId. Backlinks use WorkflowId.
|
|
85
|
-
</dependency-types>
|
|
86
|
-
|
|
87
|
-
<common-errors>
|
|
88
|
-
❌ CRITICAL: Writing "function(dep) { ... }" (ONLY write function body!)
|
|
89
|
-
❌ Using array for nameFunctionVariables: [FieldId] (use object)
|
|
90
|
-
❌ Using const/let instead of var in function
|
|
91
|
-
❌ Returning null or undefined
|
|
92
|
-
❌ Using TypeScript type annotations: (dep: Deps)
|
|
93
|
-
❌ Using WorkflowIds for forward links (use LinkFieldId)
|
|
94
|
-
❌ Forgetting nameFunctionEnabled: true
|
|
95
|
-
❌ Running workflows-push directly (return to orchestrator)
|
|
96
|
-
|
|
97
|
-
✅ Write ONLY function body: "return 'value'" not "function(dep) { return 'value'; }"
|
|
98
|
-
✅ Use object for nameFunctionVariables
|
|
99
|
-
✅ Use var for variables
|
|
100
|
-
✅ Always return string with fallback
|
|
101
|
-
✅ Use vanilla JS only
|
|
102
|
-
✅ Define helpers inside function body
|
|
103
|
-
✅ Handle null/undefined inputs
|
|
104
|
-
</common-errors>
|
|
105
|
-
|
|
106
|
-
<workflow>
|
|
107
|
-
1. npm run pull (run directly)
|
|
108
|
-
2. Read workspace/[Workflow]_[id]/main.ts
|
|
109
|
-
3. Read workspace/[Workflow]_[id]/fields.ts to identify key fields for naming
|
|
110
|
-
4. Add nameFunctionEnabled, nameFunction, nameFunctionVariables to workflowConfig
|
|
111
|
-
5. Return ['npm run workflows-push']
|
|
112
|
-
</workflow>
|
|
113
|
-
|
|
114
|
-
<protocol>
|
|
115
|
-
Input: JSON task spec
|
|
116
|
-
Output: JSON only
|
|
117
|
-
Schema: {
|
|
118
|
-
"status": "ready_to_push|error",
|
|
119
|
-
"result": { "name_function_added": true, "variables": 0 },
|
|
120
|
-
"commands": ["npm run workflows-push"],
|
|
121
|
-
"summary": "max 50 chars"
|
|
122
|
-
}
|
|
123
|
-
</protocol>
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# MCP Agents
|
|
2
|
-
|
|
3
|
-
kenji: Read data/schema from workspace (haiku)
|
|
4
|
-
dmitri: Create/update activities (haiku)
|
|
5
|
-
yevgeni: Discussions and chat (haiku)
|
|
6
|
-
helga: Workflow/field/phase config (sonnet)
|
|
7
|
-
viktor: SQL insights over workflows (sonnet)
|
|
8
|
-
giuseppe: Build Hailer apps (sonnet)
|
|
9
|
-
alejandro: Function/calculated fields (sonnet)
|
|
10
|
-
|
|
11
|
-
# What MCP Can Do
|
|
12
|
-
|
|
13
|
-
- Manage Hailer workflows, activities, fields
|
|
14
|
-
- Create SQL-like reports (insights)
|
|
15
|
-
- Build custom apps
|
|
16
|
-
- Handle discussions/messaging
|
|
17
|
-
- Configure workspace structure
|
|
18
|
-
|
|
19
|
-
# Limitations
|
|
20
|
-
|
|
21
|
-
- Cannot access external systems
|
|
22
|
-
- Limited to configured workspace
|
|
23
|
-
- Agents run via Claude Code CLI
|
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Install a plugin from local marketplace clone to .claude/ folder
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Install Plugin from Local Marketplace
|
|
6
|
-
|
|
7
|
-
Copies plugin files from local marketplace repo to project's `.claude/` folder.
|
|
8
|
-
|
|
9
|
-
## Usage
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
/install-plugin <plugin-name>
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Pre-flight Checks
|
|
16
|
-
|
|
17
|
-
### 1. Marketplace Path
|
|
18
|
-
```bash
|
|
19
|
-
PROJECT_ROOT="$(pwd)"
|
|
20
|
-
MARKETPLACE_PATH="$PROJECT_ROOT/hailer-marketplace"
|
|
21
|
-
if [ ! -d "$MARKETPLACE_PATH" ]; then
|
|
22
|
-
echo "ERROR: Marketplace not found at $MARKETPLACE_PATH"
|
|
23
|
-
echo "Clone it: git clone git@github.com:Bdolf/Hailer-Marketplace.git $MARKETPLACE_PATH"
|
|
24
|
-
exit 1
|
|
25
|
-
fi
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### 2. Plugin Exists
|
|
29
|
-
```bash
|
|
30
|
-
PLUGIN_NAME="$1"
|
|
31
|
-
if [ ! -d "$MARKETPLACE_PATH/$PLUGIN_NAME" ]; then
|
|
32
|
-
echo "ERROR: Plugin '$PLUGIN_NAME' not found in marketplace"
|
|
33
|
-
echo "Available plugins:"
|
|
34
|
-
ls -1 "$MARKETPLACE_PATH" | grep -v "^\." | grep -v "node_modules"
|
|
35
|
-
exit 1
|
|
36
|
-
fi
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Installation Steps
|
|
40
|
-
|
|
41
|
-
For each plugin, copy files to the correct locations:
|
|
42
|
-
|
|
43
|
-
| Source | Destination |
|
|
44
|
-
|--------|-------------|
|
|
45
|
-
| `{plugin}/agents/*.md` | `.claude/agents/` |
|
|
46
|
-
| `{plugin}/skills/*/` | `.claude/skills/` |
|
|
47
|
-
| `{plugin}/hooks/*.cjs` | `.claude/hooks/` |
|
|
48
|
-
| `{plugin}/hooks/hooks.json` | Merge into `.claude/settings.json` |
|
|
49
|
-
| `{plugin}/.lsp.json` | Install to `~/.claude/plugins/cache/` (LSP support) |
|
|
50
|
-
|
|
51
|
-
## Execution Script
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
#!/bin/bash
|
|
55
|
-
|
|
56
|
-
PROJECT_ROOT="$(pwd)"
|
|
57
|
-
MARKETPLACE_PATH="$PROJECT_ROOT/hailer-marketplace"
|
|
58
|
-
PLUGIN_NAME="$1"
|
|
59
|
-
PLUGIN_PATH="$MARKETPLACE_PATH/$PLUGIN_NAME"
|
|
60
|
-
TARGET_CLAUDE=".claude"
|
|
61
|
-
|
|
62
|
-
# Pre-flight
|
|
63
|
-
if [ ! -d "$PLUGIN_PATH" ]; then
|
|
64
|
-
echo "ERROR: Plugin '$PLUGIN_NAME' not found"
|
|
65
|
-
exit 1
|
|
66
|
-
fi
|
|
67
|
-
|
|
68
|
-
# Create target dirs if needed
|
|
69
|
-
mkdir -p "$TARGET_CLAUDE/agents" "$TARGET_CLAUDE/skills" "$TARGET_CLAUDE/hooks"
|
|
70
|
-
|
|
71
|
-
# Copy agents
|
|
72
|
-
if [ -d "$PLUGIN_PATH/agents" ]; then
|
|
73
|
-
cp -v "$PLUGIN_PATH/agents/"*.md "$TARGET_CLAUDE/agents/" 2>/dev/null
|
|
74
|
-
echo "Installed agents"
|
|
75
|
-
fi
|
|
76
|
-
|
|
77
|
-
# Copy skills (entire directories)
|
|
78
|
-
if [ -d "$PLUGIN_PATH/skills" ]; then
|
|
79
|
-
cp -rv "$PLUGIN_PATH/skills/"* "$TARGET_CLAUDE/skills/" 2>/dev/null || true
|
|
80
|
-
echo "Installed skills"
|
|
81
|
-
fi
|
|
82
|
-
|
|
83
|
-
# Copy hooks
|
|
84
|
-
if [ -d "$PLUGIN_PATH/hooks" ]; then
|
|
85
|
-
find "$PLUGIN_PATH/hooks" -name "*.cjs" -exec cp -v {} "$TARGET_CLAUDE/hooks/" \;
|
|
86
|
-
echo "Installed hooks"
|
|
87
|
-
fi
|
|
88
|
-
|
|
89
|
-
# Auto-install LSP if plugin has .lsp.json
|
|
90
|
-
if [ -f "$PLUGIN_PATH/.lsp.json" ]; then
|
|
91
|
-
echo "Plugin includes LSP support, installing..."
|
|
92
|
-
|
|
93
|
-
# Use typescript-lsp from marketplace as LSP source
|
|
94
|
-
LSP_SOURCE="$MARKETPLACE_PATH/typescript-lsp"
|
|
95
|
-
LSP_CACHE="$HOME/.claude/plugins/cache/hailer-mcp-marketplace/typescript-lsp/1.0.0"
|
|
96
|
-
LSP_INSTALLED="$HOME/.claude/plugins/installed_plugins.json"
|
|
97
|
-
|
|
98
|
-
# Create plugin cache directory
|
|
99
|
-
mkdir -p "$LSP_CACHE/.claude-plugin"
|
|
100
|
-
|
|
101
|
-
# Copy .lsp.json from the LSP plugin source (not the current plugin)
|
|
102
|
-
if [ -f "$LSP_SOURCE/.lsp.json" ]; then
|
|
103
|
-
cp "$LSP_SOURCE/.lsp.json" "$LSP_CACHE/.lsp.json"
|
|
104
|
-
else
|
|
105
|
-
cp "$PLUGIN_PATH/.lsp.json" "$LSP_CACHE/.lsp.json"
|
|
106
|
-
fi
|
|
107
|
-
|
|
108
|
-
# Copy the actual plugin.json from typescript-lsp plugin
|
|
109
|
-
if [ -f "$LSP_SOURCE/.claude-plugin/plugin.json" ]; then
|
|
110
|
-
cp "$LSP_SOURCE/.claude-plugin/plugin.json" "$LSP_CACHE/.claude-plugin/plugin.json"
|
|
111
|
-
else
|
|
112
|
-
# Fallback: create minimal plugin.json
|
|
113
|
-
cat > "$LSP_CACHE/.claude-plugin/plugin.json" << 'PLUGINJSON'
|
|
114
|
-
{
|
|
115
|
-
"name": "typescript-lsp",
|
|
116
|
-
"version": "1.0.0",
|
|
117
|
-
"description": "TypeScript/JavaScript LSP support"
|
|
118
|
-
}
|
|
119
|
-
PLUGINJSON
|
|
120
|
-
fi
|
|
121
|
-
|
|
122
|
-
# Register in installed_plugins.json
|
|
123
|
-
node -e "
|
|
124
|
-
const fs = require('fs');
|
|
125
|
-
const path = '$LSP_INSTALLED';
|
|
126
|
-
|
|
127
|
-
let data = { version: 2, plugins: {} };
|
|
128
|
-
if (fs.existsSync(path)) {
|
|
129
|
-
data = JSON.parse(fs.readFileSync(path, 'utf-8'));
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const key = 'typescript-lsp@hailer-mcp-marketplace';
|
|
133
|
-
if (!data.plugins[key]) {
|
|
134
|
-
data.plugins[key] = [{
|
|
135
|
-
scope: 'user',
|
|
136
|
-
installPath: '$LSP_CACHE',
|
|
137
|
-
version: '1.0.0',
|
|
138
|
-
installedAt: new Date().toISOString(),
|
|
139
|
-
lastUpdated: new Date().toISOString()
|
|
140
|
-
}];
|
|
141
|
-
fs.writeFileSync(path, JSON.stringify(data, null, 2));
|
|
142
|
-
console.log('LSP registered in installed_plugins.json');
|
|
143
|
-
} else {
|
|
144
|
-
console.log('LSP already registered');
|
|
145
|
-
}
|
|
146
|
-
"
|
|
147
|
-
|
|
148
|
-
# Enable LSP tool in settings.json and .env.local
|
|
149
|
-
node -e "
|
|
150
|
-
const fs = require('fs');
|
|
151
|
-
|
|
152
|
-
// 1. Update .claude/settings.json
|
|
153
|
-
const settingsPath = '.claude/settings.json';
|
|
154
|
-
let settings = {};
|
|
155
|
-
if (fs.existsSync(settingsPath)) {
|
|
156
|
-
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
157
|
-
}
|
|
158
|
-
if (!settings.env) settings.env = {};
|
|
159
|
-
if (settings.env.ENABLE_LSP_TOOL !== '1') {
|
|
160
|
-
settings.env.ENABLE_LSP_TOOL = '1';
|
|
161
|
-
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
162
|
-
console.log('ENABLE_LSP_TOOL set in .claude/settings.json');
|
|
163
|
-
} else {
|
|
164
|
-
console.log('ENABLE_LSP_TOOL already in settings.json');
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// 2. Update .env
|
|
168
|
-
const envPath = '.env';
|
|
169
|
-
let envContent = '';
|
|
170
|
-
if (fs.existsSync(envPath)) {
|
|
171
|
-
envContent = fs.readFileSync(envPath, 'utf-8');
|
|
172
|
-
}
|
|
173
|
-
if (!envContent.includes('ENABLE_LSP_TOOL=')) {
|
|
174
|
-
const line = (envContent && !envContent.endsWith('\n') ? '\n' : '') + 'ENABLE_LSP_TOOL=1\n';
|
|
175
|
-
fs.appendFileSync(envPath, line);
|
|
176
|
-
console.log('ENABLE_LSP_TOOL added to .env');
|
|
177
|
-
} else {
|
|
178
|
-
console.log('ENABLE_LSP_TOOL already in .env');
|
|
179
|
-
}
|
|
180
|
-
"
|
|
181
|
-
|
|
182
|
-
echo "LSP config installed"
|
|
183
|
-
fi
|
|
184
|
-
|
|
185
|
-
echo "Files copied. Updating CLAUDE.md..."
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Update CLAUDE.md (Node.js)
|
|
189
|
-
|
|
190
|
-
Run after file copy to add agent to the main `<agents>` table:
|
|
191
|
-
|
|
192
|
-
```bash
|
|
193
|
-
node << 'EOF'
|
|
194
|
-
const fs = require("fs");
|
|
195
|
-
const path = require("path");
|
|
196
|
-
|
|
197
|
-
const PLUGIN_NAME = process.env.PLUGIN_NAME;
|
|
198
|
-
const AGENTS_DIR = ".claude/agents";
|
|
199
|
-
const CLAUDE_MD = "CLAUDE.md";
|
|
200
|
-
|
|
201
|
-
// Find agent files for this plugin
|
|
202
|
-
const agentFiles = fs.readdirSync(AGENTS_DIR)
|
|
203
|
-
.filter(f => f.startsWith("agent-" + PLUGIN_NAME) || f.includes(PLUGIN_NAME))
|
|
204
|
-
.filter(f => f.endsWith(".md"));
|
|
205
|
-
|
|
206
|
-
if (agentFiles.length === 0) {
|
|
207
|
-
console.log("No agent files found for " + PLUGIN_NAME);
|
|
208
|
-
process.exit(0);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
let content = fs.readFileSync(CLAUDE_MD, "utf-8");
|
|
212
|
-
|
|
213
|
-
for (const agentFile of agentFiles) {
|
|
214
|
-
const agentPath = path.join(AGENTS_DIR, agentFile);
|
|
215
|
-
const agentContent = fs.readFileSync(agentPath, "utf-8");
|
|
216
|
-
const agentName = path.basename(agentFile, ".md");
|
|
217
|
-
|
|
218
|
-
// Parse frontmatter
|
|
219
|
-
const modelMatch = agentContent.match(/^model:\s*(\w+)/m);
|
|
220
|
-
const descMatch = agentContent.match(/^description:\s*(.{1,30})/m);
|
|
221
|
-
const model = modelMatch ? modelMatch[1] : "sonnet";
|
|
222
|
-
const desc = descMatch ? descMatch[1].trim() : PLUGIN_NAME;
|
|
223
|
-
|
|
224
|
-
// Check if already in agents table
|
|
225
|
-
if (content.includes("| `" + agentName + "`")) {
|
|
226
|
-
console.log(agentName + " already in <agents> table");
|
|
227
|
-
continue;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Insert before </agents>
|
|
231
|
-
const newRow = "| " + desc + " | `" + agentName + "` | " + model + " |\n";
|
|
232
|
-
content = content.replace("</agents>", newRow + "</agents>");
|
|
233
|
-
console.log("Added " + agentName + " to <agents> table");
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
fs.writeFileSync(CLAUDE_MD, content);
|
|
237
|
-
console.log("CLAUDE.md updated");
|
|
238
|
-
EOF
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
Note: Set `PLUGIN_NAME` env var before running.
|
|
242
|
-
|
|
243
|
-
## Full Command
|
|
244
|
-
|
|
245
|
-
Run both scripts in sequence:
|
|
246
|
-
```bash
|
|
247
|
-
# 1. Copy files (bash)
|
|
248
|
-
# 2. Update CLAUDE.md (node)
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
Then: `echo "Restart Claude Code to load: claude -c"`
|
|
252
|
-
|
|
253
|
-
## List Available Plugins
|
|
254
|
-
|
|
255
|
-
If no plugin name provided, list available:
|
|
256
|
-
```bash
|
|
257
|
-
PROJECT_ROOT="$(pwd)"
|
|
258
|
-
MARKETPLACE_PATH="$PROJECT_ROOT/hailer-marketplace"
|
|
259
|
-
echo "Available plugins in marketplace:"
|
|
260
|
-
jq -r '.plugins[] | " \(.name) v\(.version) - \(.description)"' "$MARKETPLACE_PATH/.claude-plugin/marketplace.json"
|
|
261
|
-
```
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: List available plugins from local marketplace
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# List Available Marketplace Plugins
|
|
6
|
-
|
|
7
|
-
Shows all plugins available in the local marketplace clone.
|
|
8
|
-
|
|
9
|
-
## Usage
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
/list-plugins
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Execution
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
PROJECT_ROOT="$(pwd)"
|
|
19
|
-
MARKETPLACE_PATH="$PROJECT_ROOT/hailer-marketplace"
|
|
20
|
-
|
|
21
|
-
if [ ! -d "$MARKETPLACE_PATH/.git" ]; then
|
|
22
|
-
echo "Marketplace not found at $MARKETPLACE_PATH"
|
|
23
|
-
echo "Run /marketplace-setup first"
|
|
24
|
-
exit 1
|
|
25
|
-
fi
|
|
26
|
-
|
|
27
|
-
# Pull latest before listing
|
|
28
|
-
cd "$MARKETPLACE_PATH" && git pull origin main --quiet && cd - > /dev/null
|
|
29
|
-
echo "Pulled latest from marketplace"
|
|
30
|
-
echo ""
|
|
31
|
-
|
|
32
|
-
jq -r '.plugins[] | " \(.name)@\(.version) - \(.description)"' \
|
|
33
|
-
"$MARKETPLACE_PATH/.claude-plugin/marketplace.json"
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Output (ALWAYS SHOW TO USER)
|
|
37
|
-
|
|
38
|
-
After running the execution script, ALWAYS present the results to the user:
|
|
39
|
-
|
|
40
|
-
1. Show total count: "**X plugins available in marketplace**"
|
|
41
|
-
2. List each plugin with name, version, and description
|
|
42
|
-
3. Remind user they can install with `/install-plugin <name>`
|