Skip to content

Commit c5ffd14

Browse files
committed
feat: add import-javaclaw.sh CLI plugin for atmosphere import --target javaclaw
1 parent 16e4167 commit c5ffd14

1 file changed

Lines changed: 147 additions & 0 deletions

File tree

cli-plugin/import-javaclaw.sh

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
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

Comments
 (0)