chore(build): centralize Maven revision management

This commit is contained in:
matevip 2026-05-18 10:01:11 +08:00
parent ea00b2aa25
commit 55af602f67
5 changed files with 536 additions and 305 deletions

View File

@ -4,36 +4,21 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>vip.mate</groupId> <parent>
<groupId>vip.mate</groupId>
<artifactId>mateclaw</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>mateclaw-plugin-api</artifactId> <artifactId>mateclaw-plugin-api</artifactId>
<version>1.1.0-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>MateClaw Plugin API</name> <name>MateClaw Plugin API</name>
<description>Plugin SDK contract for MateClaw — external plugins depend only on this module</description> <description>Plugin SDK contract for MateClaw - external plugins depend only on this module</description>
<properties>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-ai.version>1.1.4</spring-ai.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies> <dependencies>
<!-- Spring AI core — for ToolCallback, ChatModel --> <!-- Spring AI core for ToolCallback and ChatModel. -->
<dependency> <dependency>
<groupId>org.springframework.ai</groupId> <groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-model</artifactId> <artifactId>spring-ai-model</artifactId>
@ -44,7 +29,6 @@
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>2.0.16</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
@ -52,16 +36,7 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.18.3</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<repositories>
<repository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
</project> </project>

View File

@ -4,40 +4,24 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>vip.mate</groupId> <parent>
<groupId>vip.mate</groupId>
<artifactId>mateclaw</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>mateclaw-plugin-sample</artifactId> <artifactId>mateclaw-plugin-sample</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>MateClaw Sample Plugin</name> <name>MateClaw Sample Plugin</name>
<description>A sample plugin demonstrating the MateClaw Plugin SDK</description> <description>A sample plugin demonstrating the MateClaw Plugin SDK</description>
<properties>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-ai.version>1.1.4</spring-ai.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies> <dependencies>
<!-- MateClaw Plugin API --> <!-- MateClaw Plugin API -->
<dependency> <dependency>
<groupId>vip.mate</groupId> <groupId>vip.mate</groupId>
<artifactId>mateclaw-plugin-api</artifactId> <artifactId>mateclaw-plugin-api</artifactId>
<version>1.1.0-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
@ -52,16 +36,7 @@
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>2.0.16</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<repositories>
<repository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
</project> </project>

View File

@ -35,28 +35,29 @@ FROM maven:3.9-eclipse-temurin-21 AS builder
# Optional Maven extra flags passed at build time. # Optional Maven extra flags passed at build time.
# Set MAVEN_FLAGS=-Paliyun-first in .env (or via --build-arg) to put Aliyun # Set MAVEN_FLAGS=-Paliyun-first in .env (or via --build-arg) to put Aliyun
# repos first — speeds up builds dramatically inside mainland China. # repos first. This speeds up builds inside mainland China.
ARG MAVEN_FLAGS="" ARG MAVEN_FLAGS=""
# Inject mirror settings to avoid Maven Central timeouts in restricted networks # Inject mirror settings to avoid Maven Central timeouts in restricted networks
COPY mateclaw-server/settings.xml /root/.m2/settings.xml COPY mateclaw-server/settings.xml /root/.m2/settings.xml
# Build and install plugin-api into the local Maven cache first # Copy the root parent plus module POMs first for Docker layer caching.
WORKDIR /plugin-api
COPY mateclaw-plugin-api/pom.xml ./pom.xml
COPY mateclaw-plugin-api/src ./src
RUN mvn install -Dmaven.test.skip=true -q ${MAVEN_FLAGS}
# Pre-fetch mateclaw-server dependencies (uses mirror, so this won't hang)
WORKDIR /build WORKDIR /build
COPY mateclaw-server/pom.xml . COPY pom.xml ./pom.xml
RUN mvn dependency:go-offline -q ${MAVEN_FLAGS} COPY mateclaw-plugin-api/pom.xml mateclaw-plugin-api/pom.xml
COPY mateclaw-server/pom.xml mateclaw-server/pom.xml
COPY mateclaw-plugin-sample/pom.xml mateclaw-plugin-sample/pom.xml
# Pre-fetch backend dependencies through the reactor so the parent POM,
# dependencyManagement, and internal module versions all resolve consistently.
RUN mvn -pl mateclaw-server -am dependency:go-offline -q ${MAVEN_FLAGS}
# Copy backend source and inject pre-built frontend into the right classpath location # Copy backend source and inject pre-built frontend into the right classpath location
COPY mateclaw-server/src ./src COPY mateclaw-plugin-api/src mateclaw-plugin-api/src
COPY --from=frontend-builder /static ./src/main/resources/static COPY mateclaw-server/src mateclaw-server/src
COPY --from=frontend-builder /static mateclaw-server/src/main/resources/static
RUN mvn package -Dmaven.test.skip=true -q ${MAVEN_FLAGS} RUN mvn -pl mateclaw-server -am package -Dmaven.test.skip=true -q ${MAVEN_FLAGS}
# Stage 3 — Runtime # Stage 3 — Runtime
# #
@ -65,11 +66,11 @@ RUN mvn package -Dmaven.test.skip=true -q ${MAVEN_FLAGS}
# pre-installed. This avoids the `playwright install` step and the Alpine/musl # pre-installed. This avoids the `playwright install` step and the Alpine/musl
# incompatibility that blocks browser_use on minimal images. # incompatibility that blocks browser_use on minimal images.
# #
# We pin to the exact Playwright version declared in pom.xml (1.52.0). If you # We pin to the exact Playwright version declared in the root pom.xml. If you
# bump the Java dependency, bump this tag in lockstep — Microsoft rebuilds each # bump the Java dependency, bump this tag in lockstep — Microsoft rebuilds each
# tag with the matching driver, so mismatched versions cause the java driver to # tag with the matching driver, so mismatched versions cause the java driver to
# re-download browsers at runtime (defeating the whole point of this image). # re-download browsers at runtime (defeating the whole point of this image).
FROM mcr.microsoft.com/playwright:v1.52.0-noble FROM mcr.microsoft.com/playwright:v1.59.0-noble
WORKDIR /app WORKDIR /app
# JDK 21 is NOT part of the base image (it ships Node for the JS driver). # JDK 21 is NOT part of the base image (it ships Node for the JS driver).
@ -106,7 +107,7 @@ ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright \
TZ=Asia/Shanghai \ TZ=Asia/Shanghai \
JAVA_TOOL_OPTIONS="-Duser.timezone=Asia/Shanghai" JAVA_TOOL_OPTIONS="-Duser.timezone=Asia/Shanghai"
COPY --from=builder /build/target/*.jar app.jar COPY --from=builder /build/mateclaw-server/target/*.jar app.jar
EXPOSE 18088 EXPOSE 18088
EXPOSE 1455 EXPOSE 1455
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=mysql", "app.jar"] ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=mysql", "app.jar"]

View File

@ -4,70 +4,33 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>vip.mate</groupId> <parent>
<groupId>vip.mate</groupId>
<artifactId>mateclaw</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>mateclaw-server</artifactId> <artifactId>mateclaw-server</artifactId>
<version>1.4.0-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>MateClaw Server</name> <name>MateClaw Server</name>
<description>MateClaw - Java+Vue Personal AI Assistant powered by Spring AI Alibaba</description> <description>MateClaw - Java+Vue Personal AI Assistant powered by Spring AI Alibaba</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.14</version>
<relativePath/>
</parent>
<properties>
<java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Spring AI 1.1.6 正式版patch upgrade from 1.1.5 -->
<spring-ai.version>1.1.6</spring-ai.version>
<!-- Spring AI Alibaba 1.1.2.3(对应 Spring AI 1.1.x -->
<spring-ai-alibaba.version>1.1.2.3</spring-ai-alibaba.version>
<mybatis-plus.version>3.5.16</mybatis-plus.version>
<hutool.version>5.8.26</hutool.version>
<springdoc.version>2.8.16</springdoc.version>
<jjwt.version>0.12.6</jjwt.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring AI BOM统一管理 spring-ai-* 版本) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringDoc OpenAPI BOM统一管理 springdoc-* 版本) -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-bom</artifactId>
<version>${springdoc.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies> <dependencies>
<!-- ===== MateClaw Plugin API ===== --> <!-- ===== MateClaw Plugin API ===== -->
<dependency> <dependency>
<groupId>vip.mate</groupId> <groupId>vip.mate</groupId>
<artifactId>mateclaw-plugin-api</artifactId> <artifactId>mateclaw-plugin-api</artifactId>
<version>1.1.0-SNAPSHOT</version>
</dependency> </dependency>
<!-- ===== Web MVC(不引入 WebFlux避免自动切换为响应式模式 ===== --> <!-- ===== Web MVC, excluding WebFlux to keep servlet mode ===== -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<!-- ===== Actuator exposes Spring AI observation metrics (gen_ai.*) ===== --> <!-- ===== Actuator - exposes Spring AI observation metrics (gen_ai.*) ===== -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
@ -75,14 +38,13 @@
<!-- ===== Spring AI Alibaba DashScope ===== --> <!-- ===== Spring AI Alibaba DashScope ===== -->
<!-- <!--
1.1.2.2 需单独指定版本,不在 BOM 中 Version is managed centrally because this artifact is outside the Spring AI BOM.
内置 DashScope ChatModel / EmbeddingModel / ImageModel Provides DashScope ChatModel, EmbeddingModel, and ImageModel support.
--> -->
<dependency> <dependency>
<groupId>com.alibaba.cloud.ai</groupId> <groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId> <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
<version>${spring-ai-alibaba.version}</version> <!-- Exclude the transitive WebFlux starter to keep MVC mode. -->
<!-- 排除 webflux 传递依赖,保持 MVC 模式 -->
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -91,11 +53,10 @@
</exclusions> </exclusions>
</dependency> </dependency>
<!-- ===== Spring AI Alibaba Graph CoreStateGraph 工作流引擎) ===== --> <!-- ===== Spring AI Alibaba Graph Core (StateGraph workflow engine) ===== -->
<dependency> <dependency>
<groupId>com.alibaba.cloud.ai</groupId> <groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-graph-core</artifactId> <artifactId>spring-ai-alibaba-graph-core</artifactId>
<version>${spring-ai-alibaba.version}</version>
</dependency> </dependency>
<!-- ===== Spring AI OpenAI Compatible ===== --> <!-- ===== Spring AI OpenAI Compatible ===== -->
@ -104,16 +65,15 @@
<artifactId>spring-ai-openai</artifactId> <artifactId>spring-ai-openai</artifactId>
</dependency> </dependency>
<!-- ===== Spring AI AnthropicClaude 模型支持) ===== --> <!-- ===== Spring AI Anthropic (Claude model support) ===== -->
<dependency> <dependency>
<groupId>org.springframework.ai</groupId> <groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-anthropic</artifactId> <artifactId>spring-ai-anthropic</artifactId>
</dependency> </dependency>
<!-- ===== Spring AI MCP Client(动态 MCP server 连接管理) ===== --> <!-- ===== Spring AI MCP Client (dynamic MCP server connection management) ===== -->
<!-- <!--
使用 spring-ai-mcp-client-spring-boot-starter 引入 MCP 核心库, Pulls in the MCP core library while application code owns the McpSyncClient lifecycle.
但禁用自动配置(我们自己管理 McpSyncClient 生命周期)
--> -->
<dependency> <dependency>
<groupId>org.springframework.ai</groupId> <groupId>org.springframework.ai</groupId>
@ -126,31 +86,29 @@
</exclusions> </exclusions>
</dependency> </dependency>
<!-- ===== H2 内嵌数据库(开发环境) ===== --> <!-- ===== H2 embedded database (development) ===== -->
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<!-- ===== MySQL 驱动(生产环境) ===== --> <!-- ===== MySQL driver (production) ===== -->
<dependency> <dependency>
<groupId>com.mysql</groupId> <groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId> <artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<!-- ===== MyBatis Plus(不引入 JPA避免双 ORM 冲突) ===== --> <!-- ===== MyBatis Plus, without JPA to avoid dual ORM conflicts ===== -->
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId> <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency> </dependency>
<!-- MyBatis Plus 分页插件3.5.16 拆分为独立模块) --> <!-- MyBatis Plus pagination support is split into a separate module. -->
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId> <artifactId>mybatis-plus-jsqlparser</artifactId>
<version>${mybatis-plus.version}</version>
</dependency> </dependency>
<!-- ===== Spring Security ===== --> <!-- ===== Spring Security ===== -->
@ -163,55 +121,49 @@
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId> <artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId> <artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId> <artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<!-- ===== SpringDoc OpenAPISwagger UI for Spring MVC ===== --> <!-- ===== SpringDoc OpenAPI (Swagger UI for Spring MVC) ===== -->
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency> </dependency>
<!-- ===== Hutool 工具库 ===== --> <!-- ===== Hutool utilities ===== -->
<dependency> <dependency>
<groupId>cn.hutool</groupId> <groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId> <artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency> </dependency>
<!-- ===== 钉钉 Stream SDKWebSocket 长连接,无需公网 IP ===== --> <!-- ===== DingTalk Stream SDK (WebSocket long connection, no public IP required) ===== -->
<dependency> <dependency>
<groupId>com.dingtalk.open</groupId> <groupId>com.dingtalk.open</groupId>
<artifactId>dingtalk-stream</artifactId> <artifactId>dingtalk-stream</artifactId>
<version>1.3.12</version>
</dependency> </dependency>
<!-- ===== 飞书 / Lark Open API SDKWebSocket 长连接 + 事件分发) ===== --> <!-- ===== Lark Open API SDK (WebSocket long connection and event dispatch) ===== -->
<dependency> <dependency>
<groupId>com.larksuite.oapi</groupId> <groupId>com.larksuite.oapi</groupId>
<artifactId>oapi-sdk</artifactId> <artifactId>oapi-sdk</artifactId>
<version>2.6.1</version>
</dependency> </dependency>
<!-- ===== Caffeine Cache用于 skill runtime 缓存) ===== --> <!-- ===== Caffeine cache for skill runtime caching ===== -->
<dependency> <dependency>
<groupId>com.github.ben-manes.caffeine</groupId> <groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId> <artifactId>caffeine</artifactId>
</dependency> </dependency>
<!-- ===== SnakeYAML(用于 SKILL.md frontmatter 解析) ===== --> <!-- ===== SnakeYAML for SKILL.md frontmatter parsing ===== -->
<dependency> <dependency>
<groupId>org.yaml</groupId> <groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId> <artifactId>snakeyaml</artifactId>
@ -228,28 +180,24 @@
<dependency> <dependency>
<groupId>com.google.zxing</groupId> <groupId>com.google.zxing</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>3.5.4</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.zxing</groupId> <groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId> <artifactId>javase</artifactId>
<version>3.5.4</version>
</dependency> </dependency>
<!-- ===== Playwright (Browser Automation) ===== --> <!-- ===== Playwright (Browser Automation) ===== -->
<dependency> <dependency>
<groupId>com.microsoft.playwright</groupId> <groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId> <artifactId>playwright</artifactId>
<version>1.59.0</version>
</dependency> </dependency>
<!-- ===== JDADiscord Bot Gateway WebSocket 长连接) ===== --> <!-- ===== JDA (Discord Bot Gateway WebSocket long connection) ===== -->
<dependency> <dependency>
<groupId>net.dv8tion</groupId> <groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId> <artifactId>JDA</artifactId>
<version>6.4.1</version>
<exclusions> <exclusions>
<!-- 排除 audio 相关依赖MateClaw 不需要语音功能) --> <!-- Exclude audio dependencies because voice features are not used. -->
<exclusion> <exclusion>
<groupId>club.minnced</groupId> <groupId>club.minnced</groupId>
<artifactId>opus-java</artifactId> <artifactId>opus-java</artifactId>
@ -257,27 +205,24 @@
</exclusions> </exclusions>
</dependency> </dependency>
<!-- ===== Spring WebSocketTalk Mode ===== --> <!-- ===== Spring WebSocket (Talk Mode) ===== -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId> <artifactId>spring-boot-starter-websocket</artifactId>
</dependency> </dependency>
<!-- ===== Slack SDKSocket Mode + Web API ===== --> <!-- ===== Slack SDK (Socket Mode and Web API) ===== -->
<dependency> <dependency>
<groupId>com.slack.api</groupId> <groupId>com.slack.api</groupId>
<artifactId>slack-api-client</artifactId> <artifactId>slack-api-client</artifactId>
<version>1.48.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.slack.api</groupId> <groupId>com.slack.api</groupId>
<artifactId>bolt-socket-mode</artifactId> <artifactId>bolt-socket-mode</artifactId>
<version>1.48.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.glassfish.tyrus.bundles</groupId> <groupId>org.glassfish.tyrus.bundles</groupId>
<artifactId>tyrus-standalone-client</artifactId> <artifactId>tyrus-standalone-client</artifactId>
<version>2.2.2</version>
</dependency> </dependency>
<!-- ===== Apache POI (in-process .docx generation) ===== --> <!-- ===== Apache POI (in-process .docx generation) ===== -->
@ -288,7 +233,6 @@
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId> <artifactId>poi-ooxml</artifactId>
<version>5.4.1</version>
</dependency> </dependency>
<!-- ===== Apache Batik (SVG rasterization for docx image embedding) ===== --> <!-- ===== Apache Batik (SVG rasterization for docx image embedding) ===== -->
@ -302,53 +246,47 @@
<dependency> <dependency>
<groupId>org.apache.xmlgraphics</groupId> <groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-transcoder</artifactId> <artifactId>batik-transcoder</artifactId>
<version>1.19</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.xmlgraphics</groupId> <groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-codec</artifactId> <artifactId>batik-codec</artifactId>
<version>1.19</version>
</dependency> </dependency>
<!-- ===== jsoup (HTML cleanup for Wiki ingest, RFC-051 PR-1c) ===== --> <!-- ===== jsoup (HTML cleanup for Wiki ingest) ===== -->
<!-- <!--
Used by WikiContentNormalizer to strip nav/footer/script/style/aside Used by WikiContentNormalizer to strip nav/footer/script/style/aside
and ad-class nodes from URL/HTML uploads before chunking. Small and ad-class nodes from URL/HTML uploads before chunking. Small
(~430KB), no transitive deps, JVM-only safe for the desktop bundle. (~430KB), no transitive deps, JVM-only, and safe for the desktop bundle.
--> -->
<dependency> <dependency>
<groupId>org.jsoup</groupId> <groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId> <artifactId>jsoup</artifactId>
<version>1.22.2</version>
</dependency> </dependency>
<!-- ===== Apache Tika (RFC-051 PR-?: Java-side last-resort extractor) ===== --> <!-- ===== Apache Tika (Java-side last-resort document extractor) ===== -->
<!-- <!--
Wired as the FINAL fallback in DocumentExtractTool's PDF/DOCX/XLSX/PPTX Wired as the FINAL fallback in DocumentExtractTool's PDF/DOCX/XLSX/PPTX
chains, after every system command + Python + POI-based path has failed. chains, after every system command + Python + POI-based path has failed.
Used in production primarily by Windows users without Python or poppler Used in production primarily by Windows users without Python or poppler
installed; otherwise idle. installed; otherwise idle.
Pinned to the precise format modules called out in RFC-051 §5.2 — we Pinned to the precise format modules the extractor calls directly. This
deliberately avoid `tika-parsers-standard-package`, which pulls in mail, deliberately avoids `tika-parsers-standard-package`, which pulls in mail,
audio, archive, RTF / ODT, scientific, etc. (~80MB). Current footprint: audio, archive, RTF / ODT, scientific, etc. (~80MB). Current footprint:
tika-core (~700KB) + tika-parser-pdf-module (PDFBox ~5MB) + tika-core (~700KB) + tika-parser-pdf-module (PDFBox ~5MB) +
tika-parser-microsoft-module (POI-scratchpad ~10MB) 16MB. tika-parser-microsoft-module (POI-scratchpad ~10MB) is about 16MB.
--> -->
<dependency> <dependency>
<groupId>org.apache.tika</groupId> <groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId> <artifactId>tika-core</artifactId>
<version>3.3.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.tika</groupId> <groupId>org.apache.tika</groupId>
<artifactId>tika-parser-pdf-module</artifactId> <artifactId>tika-parser-pdf-module</artifactId>
<version>3.3.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.tika</groupId> <groupId>org.apache.tika</groupId>
<artifactId>tika-parser-microsoft-module</artifactId> <artifactId>tika-parser-microsoft-module</artifactId>
<version>3.3.0</version>
</dependency> </dependency>
<!-- ===== Markdown -> PDF rendering ===== <!-- ===== Markdown -> PDF rendering =====
@ -368,32 +306,26 @@
<dependency> <dependency>
<groupId>org.xhtmlrenderer</groupId> <groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId> <artifactId>flying-saucer-pdf</artifactId>
<version>10.2.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.commonmark</groupId> <groupId>org.commonmark</groupId>
<artifactId>commonmark</artifactId> <artifactId>commonmark</artifactId>
<version>0.28.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.commonmark</groupId> <groupId>org.commonmark</groupId>
<artifactId>commonmark-ext-gfm-tables</artifactId> <artifactId>commonmark-ext-gfm-tables</artifactId>
<version>0.28.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.commonmark</groupId> <groupId>org.commonmark</groupId>
<artifactId>commonmark-ext-yaml-front-matter</artifactId> <artifactId>commonmark-ext-yaml-front-matter</artifactId>
<version>0.28.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.commonmark</groupId> <groupId>org.commonmark</groupId>
<artifactId>commonmark-ext-gfm-strikethrough</artifactId> <artifactId>commonmark-ext-gfm-strikethrough</artifactId>
<version>0.28.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.commonmark</groupId> <groupId>org.commonmark</groupId>
<artifactId>commonmark-ext-autolink</artifactId> <artifactId>commonmark-ext-autolink</artifactId>
<version>0.28.0</version>
</dependency> </dependency>
<!-- ===== Database Migration (Flyway) ===== --> <!-- ===== Database Migration (Flyway) ===== -->
@ -413,33 +345,30 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- ===== ArchUnit (RFC-063r §2.3 / §5.2 architecture invariants) ===== <!-- ===== ArchUnit architecture invariants =====
test-scope only guards: test-scope only, guards:
- every ToolCallback implementation overrides call(String, ToolContext) - every ToolCallback implementation overrides call(String, ToolContext)
so decorators (LocaleAwareToolCallback) cannot silently drop ChatOrigin so decorators (LocaleAwareToolCallback) cannot silently drop ChatOrigin
- CronJobRunner (introduced in PR-3) must not carry @Transactional - CronJobRunner must not carry @Transactional
(would silently fail under self-invocation; see RFC §5.2) because it would silently fail under self-invocation
--> -->
<dependency> <dependency>
<groupId>com.tngtech.archunit</groupId> <groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId> <artifactId>archunit-junit5</artifactId>
<version>1.3.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- ShedLock: distributed lock for the cron scheduler so a <!-- ShedLock: distributed lock for the cron scheduler so a
multi-instance deployment doesn't fire the same job N times. multi-instance deployment doesn't fire the same job N times.
JDBC mode reuses the existing DataSource no Redis dependency JDBC mode reuses the existing DataSource, so there is no Redis dependency
on the desktop / single-node footprint. --> on the desktop / single-node footprint. -->
<dependency> <dependency>
<groupId>net.javacrumbs.shedlock</groupId> <groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId> <artifactId>shedlock-spring</artifactId>
<version>7.7.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.javacrumbs.shedlock</groupId> <groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-jdbc-template</artifactId> <artifactId>shedlock-provider-jdbc-template</artifactId>
<version>7.7.0</version>
</dependency> </dependency>
<!-- Graph algorithms (community detection, shortest path, centrality) <!-- Graph algorithms (community detection, shortest path, centrality)
@ -447,7 +376,6 @@
<dependency> <dependency>
<groupId>org.jgrapht</groupId> <groupId>org.jgrapht</groupId>
<artifactId>jgrapht-core</artifactId> <artifactId>jgrapht-core</artifactId>
<version>1.5.3</version>
</dependency> </dependency>
<!-- PDF parsing for inline image extraction (wiki vision-in pipeline). <!-- PDF parsing for inline image extraction (wiki vision-in pipeline).
@ -456,7 +384,6 @@
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId> <artifactId>pdfbox</artifactId>
<version>3.0.7</version>
</dependency> </dependency>
<!-- Expression language used by the workflow compiler to evaluate <!-- Expression language used by the workflow compiler to evaluate
@ -467,7 +394,6 @@
<dependency> <dependency>
<groupId>io.pebbletemplates</groupId> <groupId>io.pebbletemplates</groupId>
<artifactId>pebble</artifactId> <artifactId>pebble</artifactId>
<version>4.1.1</version>
</dependency> </dependency>
</dependencies> </dependencies>
@ -515,115 +441,7 @@
</plugins> </plugins>
</build> </build>
<!--
Dependency repositories, with US + CN mirrors listed side by side so builds
are reasonable on either continent. Maven tries repositories in the order
they are declared — the first one that resolves an artifact wins.
IDs are deliberately distinct from the super-POM's `central` id so that
mirror rules in settings.xml (if any) don't silently redirect them. Keep
the fastest-by-default first; switch order via a local ~/.m2/settings.xml
or pass `-Paliyun-first` when building from inside China.
-->
<repositories>
<!-- Primary: Maven Central direct — fast from US/EU backbones. -->
<repository>
<id>maven-central</id>
<name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<!-- Fallback 1: Google Cloud's Maven Central mirror (global CDN edge). -->
<repository>
<id>google-maven-central</id>
<name>Google Maven Central Mirror</name>
<url>https://maven-central.storage-download.googleapis.com/maven2</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<!-- Fallback 2: Aliyun public — fast from China, full Central mirror. -->
<repository>
<id>aliyun-public</id>
<name>Aliyun Public</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<!-- Spring milestones / snapshots — direct from Spring (US). -->
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<!-- Aliyun Spring mirror — fallback for CN builds. -->
<repository>
<id>aliyun-spring</id>
<name>Aliyun Spring Mirror</name>
<url>https://maven.aliyun.com/repository/spring</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
<!-- Plugin lookups follow the same multi-region fallback. -->
<pluginRepositories>
<pluginRepository>
<id>maven-central</id>
<name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</pluginRepository>
<pluginRepository>
<id>google-maven-central</id>
<name>Google Maven Central Mirror</name>
<url>https://maven-central.storage-download.googleapis.com/maven2</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</pluginRepository>
<pluginRepository>
<id>aliyun-public</id>
<name>Aliyun Public</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
<!--
Profile: swap the primary repo order when building from China so Aliyun
is tried first. Activate with `mvn -Paliyun-first ...`.
-->
<profiles> <profiles>
<profile>
<id>aliyun-first</id>
<repositories>
<repository>
<id>aliyun-public-first</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>aliyun-spring-first</id>
<url>https://maven.aliyun.com/repository/spring</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun-public-first</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<!-- <!--
Profile: focused test run for image / video generation features. Profile: focused test run for image / video generation features.
Activate with `mvn test -P media-gen` (or `mvn verify -P media-gen`). Activate with `mvn test -P media-gen` (or `mvn verify -P media-gen`).

462
pom.xml Normal file
View File

@ -0,0 +1,462 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>vip.mate</groupId>
<artifactId>mateclaw</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
<name>MateClaw</name>
<description>MateClaw monorepo reactor and Maven parent</description>
<!-- Reactor modules. Keep plugin-api before consumers for predictable local builds. -->
<modules>
<module>mateclaw-plugin-api</module>
<module>mateclaw-server</module>
<module>mateclaw-plugin-sample</module>
</modules>
<properties>
<!-- MateClaw release version shared by all Maven modules. -->
<revision>1.4.0-SNAPSHOT</revision>
<!-- Java -->
<java.version>21</java.version>
<maven.compiler.release>${java.version}</maven.compiler.release>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Spring ecosystem -->
<spring-boot.version>3.5.14</spring-boot.version>
<spring-ai.version>1.1.6</spring-ai.version>
<spring-ai-alibaba.version>1.1.2.3</spring-ai-alibaba.version>
<springdoc.version>2.8.16</springdoc.version>
<!-- Persistence and core utilities -->
<mybatis-plus.version>3.5.16</mybatis-plus.version>
<hutool.version>5.8.26</hutool.version>
<jjwt.version>0.12.6</jjwt.version>
<slf4j.version>2.0.16</slf4j.version>
<jackson.version>2.18.3</jackson.version>
<!-- Channel and platform SDKs -->
<dingtalk-stream.version>1.3.12</dingtalk-stream.version>
<lark-oapi.version>2.6.1</lark-oapi.version>
<jda.version>6.4.1</jda.version>
<slack.version>1.48.1</slack.version>
<!-- Browser automation and WebSocket runtime -->
<zxing.version>3.5.4</zxing.version>
<playwright.version>1.59.0</playwright.version>
<tyrus.version>2.2.2</tyrus.version>
<!-- Document, wiki, and rendering toolchain -->
<poi.version>5.4.1</poi.version>
<batik.version>1.19</batik.version>
<jsoup.version>1.22.2</jsoup.version>
<tika.version>3.3.0</tika.version>
<flying-saucer.version>10.2.0</flying-saucer.version>
<commonmark.version>0.28.0</commonmark.version>
<archunit.version>1.3.0</archunit.version>
<shedlock.version>7.7.0</shedlock.version>
<jgrapht.version>1.5.3</jgrapht.version>
<pdfbox.version>3.0.7</pdfbox.version>
<pebble.version>4.1.1</pebble.version>
<!-- Build plugin versions -->
<maven-compiler-plugin.version>3.14.1</maven-compiler-plugin.version>
<maven-dependency-plugin.version>3.8.1</maven-dependency-plugin.version>
<maven-surefire-plugin.version>3.5.5</maven-surefire-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- ==================== BOM Imports ==================== -->
<!-- Spring Boot replaces spring-boot-starter-parent while this root POM stays the project parent. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-bom</artifactId>
<version>${springdoc.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- ==================== MateClaw Modules ==================== -->
<!-- Internal module dependencies share the same revision-controlled version. -->
<dependency>
<groupId>vip.mate</groupId>
<artifactId>mateclaw-plugin-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>vip.mate</groupId>
<artifactId>mateclaw-server</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>vip.mate</groupId>
<artifactId>mateclaw-plugin-sample</artifactId>
<version>${revision}</version>
</dependency>
<!-- ==================== Spring AI Alibaba ==================== -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
<version>${spring-ai-alibaba.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-graph-core</artifactId>
<version>${spring-ai-alibaba.version}</version>
</dependency>
<!-- ==================== Persistence ==================== -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- ==================== Utilities and Security ==================== -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- ==================== Channel and Automation SDKs ==================== -->
<dependency>
<groupId>com.dingtalk.open</groupId>
<artifactId>dingtalk-stream</artifactId>
<version>${dingtalk-stream.version}</version>
</dependency>
<dependency>
<groupId>com.larksuite.oapi</groupId>
<artifactId>oapi-sdk</artifactId>
<version>${lark-oapi.version}</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>${zxing.version}</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>${zxing.version}</version>
</dependency>
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>${playwright.version}</version>
</dependency>
<dependency>
<groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>${jda.version}</version>
</dependency>
<dependency>
<groupId>com.slack.api</groupId>
<artifactId>slack-api-client</artifactId>
<version>${slack.version}</version>
</dependency>
<dependency>
<groupId>com.slack.api</groupId>
<artifactId>bolt-socket-mode</artifactId>
<version>${slack.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.tyrus.bundles</groupId>
<artifactId>tyrus-standalone-client</artifactId>
<version>${tyrus.version}</version>
</dependency>
<!-- ==================== Document and Rendering Toolchain ==================== -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-transcoder</artifactId>
<version>${batik.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-codec</artifactId>
<version>${batik.version}</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>${tika.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parser-pdf-module</artifactId>
<version>${tika.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parser-microsoft-module</artifactId>
<version>${tika.version}</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>${flying-saucer.version}</version>
</dependency>
<dependency>
<groupId>org.commonmark</groupId>
<artifactId>commonmark</artifactId>
<version>${commonmark.version}</version>
</dependency>
<dependency>
<groupId>org.commonmark</groupId>
<artifactId>commonmark-ext-gfm-tables</artifactId>
<version>${commonmark.version}</version>
</dependency>
<dependency>
<groupId>org.commonmark</groupId>
<artifactId>commonmark-ext-yaml-front-matter</artifactId>
<version>${commonmark.version}</version>
</dependency>
<dependency>
<groupId>org.commonmark</groupId>
<artifactId>commonmark-ext-gfm-strikethrough</artifactId>
<version>${commonmark.version}</version>
</dependency>
<dependency>
<groupId>org.commonmark</groupId>
<artifactId>commonmark-ext-autolink</artifactId>
<version>${commonmark.version}</version>
</dependency>
<!-- ==================== Test and Scheduler Support ==================== -->
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId>
<version>${archunit.version}</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>${shedlock.version}</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-jdbc-template</artifactId>
<version>${shedlock.version}</version>
</dependency>
<!-- ==================== Graph, PDF, and Workflow Helpers ==================== -->
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-core</artifactId>
<version>${jgrapht.version}</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>${pdfbox.version}</version>
</dependency>
<dependency>
<groupId>io.pebbletemplates</groupId>
<artifactId>pebble</artifactId>
<version>${pebble.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<!-- Central plugin versions for child modules. -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
<!-- Shared compiler defaults for all Maven modules. -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>${maven.compiler.release}</release>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
<!--
Dependency repositories are declared with direct and mirrored endpoints.
Keep distinct IDs from Maven's built-in central repository so user-level
mirror rules do not silently collapse the fallback order.
-->
<repositories>
<repository>
<id>maven-central</id>
<name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>google-maven-central</id>
<name>Google Maven Central Mirror</name>
<url>https://maven-central.storage-download.googleapis.com/maven2</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>aliyun-public</id>
<name>Aliyun Public</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>aliyun-spring</id>
<name>Aliyun Spring Mirror</name>
<url>https://maven.aliyun.com/repository/spring</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
<!-- Plugin lookups follow the same multi-region fallback strategy. -->
<pluginRepositories>
<pluginRepository>
<id>maven-central</id>
<name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</pluginRepository>
<pluginRepository>
<id>google-maven-central</id>
<name>Google Maven Central Mirror</name>
<url>https://maven-central.storage-download.googleapis.com/maven2</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</pluginRepository>
<pluginRepository>
<id>aliyun-public</id>
<name>Aliyun Public</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
<!-- Optional profile for faster Maven resolution from mainland China. -->
<profiles>
<profile>
<id>aliyun-first</id>
<repositories>
<repository>
<id>aliyun-public-first</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>aliyun-spring-first</id>
<url>https://maven.aliyun.com/repository/spring</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun-public-first</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
</project>