|
| 1 | +#!/bin/sh |
| 2 | +# Atmosphere CLI Import Plugin: JavaClaw |
| 3 | +# Generates a JavaClaw-compatible Gradle plugin project from a skill file. |
| 4 | +# |
| 5 | +# Install: cp import-javaclaw.sh ~/.atmosphere/plugins/ |
| 6 | +# Use: atmosphere import --target javaclaw <skill> |
| 7 | +# |
| 8 | +# Contract: $1=skill_file $2=project_name $3=skill_name $4=skill_desc $5=headless |
| 9 | + |
| 10 | +set -e |
| 11 | + |
| 12 | +SKILL_FILE="$1" |
| 13 | +PROJECT_NAME="$2" |
| 14 | +SKILL_NAME="$3" |
| 15 | +SKILL_DESC="$4" |
| 16 | +HEADLESS="${5:-false}" |
| 17 | + |
| 18 | +[ -z "$SKILL_FILE" ] && echo "error: no skill file provided" && exit 1 |
| 19 | +[ -z "$PROJECT_NAME" ] && PROJECT_NAME="$SKILL_NAME" |
| 20 | + |
| 21 | +PROJECT_DIR="$PROJECT_NAME" |
| 22 | +[ -d "$PROJECT_DIR" ] && echo "error: directory '$PROJECT_DIR' already exists" && exit 1 |
| 23 | + |
| 24 | +# Generate class name: "weather-bot" → "WeatherBot" |
| 25 | +AGENT_CLASS=$(echo "$SKILL_NAME" | sed 's/[^a-zA-Z0-9]/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1' | tr -d ' ') |
| 26 | +SAFE_PKG=$(echo "$SKILL_NAME" | tr '-' '_' | sed 's/[^a-z0-9_]//g') |
| 27 | +PACKAGE="ai.javaclaw.plugins.${SAFE_PKG}" |
| 28 | +PACKAGE_DIR=$(echo "$PACKAGE" | tr '.' '/') |
| 29 | + |
| 30 | +# Extract tools from ## Tools section |
| 31 | +SKILL_CONTENT=$(cat "$SKILL_FILE") |
| 32 | +TOOLS_SECTION=$(echo "$SKILL_CONTENT" | sed -n '/^## Tools/,/^## /p' | grep '^\- ' | sed 's/^- //') |
| 33 | + |
| 34 | +# Create project structure |
| 35 | +mkdir -p "$PROJECT_DIR/src/main/java/$PACKAGE_DIR" |
| 36 | +mkdir -p "$PROJECT_DIR/src/main/resources/prompts" |
| 37 | + |
| 38 | +# Copy skill file |
| 39 | +cp "$SKILL_FILE" "$PROJECT_DIR/src/main/resources/prompts/skill.md" |
| 40 | + |
| 41 | +# Generate Spring AI @Tool methods from ## Tools |
| 42 | +TOOL_METHODS="" |
| 43 | +if [ -n "$TOOLS_SECTION" ]; then |
| 44 | + while IFS= read -r tool_line; do |
| 45 | + if echo "$tool_line" | grep -q ':'; then |
| 46 | + tool_name=$(echo "$tool_line" | cut -d: -f1 | tr -d ' ' | tr '[:upper:]' '[:lower:]') |
| 47 | + tool_desc=$(echo "$tool_line" | cut -d: -f2- | sed 's/^ *//') |
| 48 | + else |
| 49 | + tool_name=$(echo "$tool_line" | tr '[:upper:]' '[:lower:]' | tr ' ' '_' | sed 's/[^a-z0-9_]//g') |
| 50 | + tool_desc="$tool_line" |
| 51 | + fi |
| 52 | + method_name=$(echo "$tool_name" | awk -F_ '{for(i=1;i<=NF;i++){if(i==1)printf "%s",$i;else printf "%s",toupper(substr($i,1,1))substr($i,2)}print ""}') |
| 53 | + |
| 54 | + TOOL_METHODS="${TOOL_METHODS} |
| 55 | +
|
| 56 | + @Tool(description = \"${tool_desc}\") |
| 57 | + public String ${method_name}(String input) { |
| 58 | + // TODO: implement |
| 59 | + return \"${tool_name} result for: \" + input; |
| 60 | + }" |
| 61 | + done <<< "$TOOLS_SECTION" |
| 62 | +fi |
| 63 | + |
| 64 | +TOOL_IMPORT="" |
| 65 | +[ -n "$TOOL_METHODS" ] && TOOL_IMPORT=" |
| 66 | +import org.springframework.ai.tool.annotation.Tool;" |
| 67 | + |
| 68 | +# Generate JavaClaw tool class (Spring AI @Tool, auto-discovered by JavaClaw) |
| 69 | +cat > "$PROJECT_DIR/src/main/java/$PACKAGE_DIR/${AGENT_CLASS}Tools.java" <<JAVAEOF |
| 70 | +package $PACKAGE; |
| 71 | +${TOOL_IMPORT} |
| 72 | +import ai.javaclaw.tools.AutoDiscoveredTool; |
| 73 | +import org.springframework.context.annotation.Bean; |
| 74 | +import org.springframework.context.annotation.Configuration; |
| 75 | +
|
| 76 | +/** |
| 77 | + * ${SKILL_DESC} |
| 78 | + * Auto-discovered by JavaClaw when this plugin is on the classpath. |
| 79 | + * Generated by: atmosphere import --target javaclaw |
| 80 | + */ |
| 81 | +@Configuration |
| 82 | +public class ${AGENT_CLASS}Tools { |
| 83 | +
|
| 84 | + @Bean |
| 85 | + public AutoDiscoveredTool<${AGENT_CLASS}Skills> ${SAFE_PKG}Tool() { |
| 86 | + return new AutoDiscoveredTool<>(new ${AGENT_CLASS}Skills()); |
| 87 | + } |
| 88 | +} |
| 89 | +JAVAEOF |
| 90 | + |
| 91 | +cat > "$PROJECT_DIR/src/main/java/$PACKAGE_DIR/${AGENT_CLASS}Skills.java" <<JAVAEOF |
| 92 | +package $PACKAGE; |
| 93 | +${TOOL_IMPORT} |
| 94 | +/** |
| 95 | + * ${SKILL_DESC} |
| 96 | + * These tools are available to JavaClaw's ChatClient (with all advisors and memory). |
| 97 | + * They are also auto-exposed via Atmosphere's MCP and A2A protocols when |
| 98 | + * javaclaw-atmosphere is on the classpath. |
| 99 | + */ |
| 100 | +public class ${AGENT_CLASS}Skills { |
| 101 | +${TOOL_METHODS} |
| 102 | +} |
| 103 | +JAVAEOF |
| 104 | + |
| 105 | +# Generate build.gradle |
| 106 | +cat > "$PROJECT_DIR/build.gradle" <<GRADLEEOF |
| 107 | +plugins { |
| 108 | + id 'java-library' |
| 109 | +} |
| 110 | +
|
| 111 | +repositories { |
| 112 | + mavenCentral() |
| 113 | + maven { url = 'https://repo.spring.io/milestone' } |
| 114 | +} |
| 115 | +
|
| 116 | +dependencies { |
| 117 | + compileOnly 'ai.javaclaw:base:1.0.0-SNAPSHOT' |
| 118 | + compileOnly 'org.springframework.ai:spring-ai-client-chat' |
| 119 | + compileOnly 'org.springframework.boot:spring-boot-autoconfigure' |
| 120 | +} |
| 121 | +
|
| 122 | +dependencyManagement { |
| 123 | + imports { |
| 124 | + mavenBom "org.springframework.boot:spring-boot-dependencies:4.0.3" |
| 125 | + mavenBom "org.springframework.ai:spring-ai-bom:2.0.0-SNAPSHOT" |
| 126 | + } |
| 127 | +} |
| 128 | +GRADLEEOF |
| 129 | + |
| 130 | +# Generate auto-configuration registration |
| 131 | +mkdir -p "$PROJECT_DIR/src/main/resources/META-INF/spring" |
| 132 | +echo "$PACKAGE.${AGENT_CLASS}Tools" > "$PROJECT_DIR/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports" |
| 133 | + |
| 134 | +TOOL_COUNT=$(echo "$TOOLS_SECTION" | grep -c . 2>/dev/null || echo "0") |
| 135 | +echo "" |
| 136 | +echo " JavaClaw plugin scaffolded at ./$PROJECT_DIR" |
| 137 | +echo "" |
| 138 | +echo " Tools: $TOOL_COUNT Spring AI @Tool methods" |
| 139 | +echo " Class: $PACKAGE.${AGENT_CLASS}Skills" |
| 140 | +echo "" |
| 141 | +echo " To use in JavaClaw:" |
| 142 | +echo " 1. Build: cd $PROJECT_DIR && gradle build" |
| 143 | +echo " 2. Copy JAR to JavaClaw's plugins/ directory" |
| 144 | +echo " 3. Restart JavaClaw — tools auto-discovered" |
| 145 | +echo "" |
| 146 | +echo " With Atmosphere (adds MCP + A2A):" |
| 147 | +echo " Tools also available in Claude Desktop, Cursor, VS Code" |
0 commit comments