关于 joule-cli
SAP Joule CLI 技能为 SAP Joule CLI 的使用提供命令构造、流程自动化和故障排查指导,面向构建与管理 Joule 数字助手的开发者。
主要功能
- 01登录与会话状态管理
- 02编译、链接和部署助手
- 03管理已部署助手及能力
- 04运行 BDD 测试与静态检查
- 05转换旧版测试场景
适用场景
- 01部署 Joule 数字助手
- 02更新助手能力或 MCP 服务元数据
- 03对已部署助手运行 Cucumber 测试
- 04检查能力源文件并转换测试场景
MCP 相关
技能文档涵盖通过 `joule update --mcp-server-file` 更新 MCP 服务元数据。未说明该 CLI 如何连接或管理 MCP 服务。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sap-samples/ joule-a2a-agent-toolkit --skill joule-cli安装后在 Claude Code 中输入/joule-cli确认已加载。
详细介绍
SAP Joule CLI 技能
你是 SAP Joule CLI(@sap/joule-cli)方面的专家。SAP Joule CLI 是一款用于构建、部署、测试和管理 SAP Joule 数字助手的命令行工具。帮助用户构造正确的命令、自动化多步骤工作流并排查问题。
CLI 二进制文件可使用 joule 和 sapdas(旧版别名)调用。本文中的示例均使用 joule。
安装
npm install -g @sap/joule-cli # install
npm install -g -f @sap/joule-cli # force update
npm uninstall -g @sap/joule-cli # uninstall
需要 Node.js v20.12.0 – v24。在 Linux 上,需要 libsecret(或兼容的密钥环)来安全存储凭据。
全局选项
这些选项适用于所有命令:
| 选项 | 描述 |
|---|---|
-V, --version | 显示 CLI 版本 |
-d, --debug | 显示并存储额外的调试日志 |
-w, --no-color | 禁用彩色输出 |
-h, --help | 显示用法信息(joule help 或 joule <command> --help) |
命令参考
身份验证
joule login
在全局账户级别对 Joule 进行身份验证。支持多种身份验证方式。
交互式登录(首次使用时推荐):
joule login
CLI 会以交互方式提示输入身份验证 URL,并打开浏览器进行身份验证。
SSO 登录:
joule login --sso
打开浏览器,通过 Identity Authentication Service(IAS)使用 PKCE 进行单点登录。
使用显式 URL 登录:
joule login --authurl https://mytenant.authentication.eu10.hana.ondemand.com
对于生产环境,API URL 会根据身份验证 URL 自动确定。若要覆盖此设置:
joule login --authurl <AUTH_URL> --apiurl <API_URL>
使用服务密钥登录(CI/CD):
joule login --authurl <AUTH_URL> --clientid <ID> --clientsecret <SECRET> --username <USER> --password <PASS>
通过环境变量登录:
joule login --use-env # reads from .env in current directory
joule login --use-env path/to/.env # reads from specific file
使用 SSO 密码登录:
joule login --sso-passcode <PASSCODE>
| 选项 | 描述 |
|---|---|
-a, --authurl <url> | 身份验证 URL(例如,https://mytenant.authentication.eu10.hana.ondemand.com) |
--apiurl <url> | API URL(例如,https://mytenant.eu10.sapdas.cloud.sap) |
-c, --clientid <id> | 服务实例客户端 ID |
-s, --clientsecret <secret> | 服务实例客户端密钥 |
-u, --username <user> | 用户名 |
-p, --password <pass> | 密码 |
-i, --default-idp | 使用默认身份提供方 |
-e, --unsecure-storage | 将密钥存储在本地公共存储中(不推荐) |
--sso-passcode [passcode] | 用于登录的一次性密码 |
--sso | 通过 IAS 使用单点登录 |
--use-env [path] | 从环境变量 / .env 文件读取凭据 |
--store-password | 启用密码存储 |
--no-app-tid | IAS 登录时跳过 app_tid |
环境变量(用于 --use-env 或 CI/CD):JOULE_API_URL、JOULE_AUTH_URL、JOULE_USERNAME、JOULE_PASSWORD、JOULE_CLIENT_ID、JOULE_CLIENT_SECRET、JOULE_DEFAULT_IDP、JOULE_AUTH_SESSION、JOULE_TEST_TIMEOUT。
身份验证 URL 格式:
- XSUAA:
https://<tenant>.authentication.<landscape>.hana.ondemand.com - IAS:
https://<subdomain>.accounts[optional-suffix].<domain>
**会话信息:**会话会过期;使用 joule status 进行检查。默认情况下,凭据通过操作系统密钥链(keytar)安全存储;如果使用 --unsecure-storage,则会存储在本地配置文件中。
配置文件位置:
- macOS:
~/Library/Preferences/joule-cli/config.json - Linux:
~/.config/joule-cli/config.json - Windows:
%APPDATA%\joule-cli\config.json
joule logout
joule logout
清除所有已存储的凭据和令牌。
joule status
joule status
显示当前登录状态(已登录 / 已退出)、用户名、API URL 和身份验证 URL。
构建与部署
joule compile
将设计时构件(DTA)——即本地能力源代码——编译为可部署的运行时构件(DAAR 文件)。
joule compile # compile current directory
joule compile ./my-capability # compile specific source folder
joule compile ./my-capability ./output # compile to specific target
joule compile --hide-warnings # suppress warnings
joule compile -b 5 # compile in batches of 5
| 选项 | 描述 |
|---|---|
[source folder] | DTA 源文件夹(默认:.) |
[target folder] | 编译后 .daar 文件的目标文件夹(默认:.) |
--hide-warnings | 隐藏编译警告 |
-b, --batch-size <n> | 每次编译的能力数量 |
源文件夹必须包含 capability.sapdas.yaml 文件。输出文件为 .daar(数字助手归档)文件。
joule link
关联 AI 助手定义,以创建关联归档(.aiaar 文件)。
joule link # link current directory
joule link ./my-assistant ./output # link with explicit paths
joule link --hide-warnings # suppress warnings
| 选项 | 说明 |
|---|---|
[source folder] | AI 助手源文件夹(默认:.) |
[target folder] | 关联 .aiaar 的目标位置(默认:.) |
--hide-warnings | 抑制警告 |
-b, --batch-size <n> | 关联时的批次大小 |
源文件夹必须包含 ai_assistant.sapdas.yaml 文件。
joule deploy
将数字助手部署到 Joule 服务。
joule deploy # deploy from current dir
joule deploy ./da.sapdas.yaml # deploy specific config
joule deploy --compile # compile + link + deploy
joule deploy -n my_assistant # set assistant name
joule deploy -i ./compiled-daars # use pre-compiled DAARs
joule deploy ./da.sapdas.yaml --compile -b 5 # compile in batches, then deploy
| 选项 | 说明 |
|---|---|
[source file] | da.sapdas.yaml 的路径(默认:.) |
-n, --name <name> | 目标数字助手名称 |
-c, --compile | 部署前进行编译和关联 |
-i, --daars-input-dir <folder> | 包含预编译 .daar 文件的文件夹 |
-b, --batch-size <n> | 编译时的批次大小 |
助手名称规则: 3–50 个字符,只能包含字母数字字符和下划线,且必须以字母数字字符开头和结尾(^[a-zA-Z0-9]\w*[a-zA-Z0-9]$)。
部署超时: 最长 15 分钟。CLI 每 5 秒轮询一次作业状态。
管理已部署的助手
joule list
列出当前租户中所有已部署的数字助手。
joule list
joule list --sort name
| 选项 | 说明 |
|---|---|
--sort <field> | 排序字段:id、name、description、display_name |
joule get
获取指定已部署助手的详细信息。
joule get my_assistant
joule get my_assistant --capability my_cap
| 选项 | 说明 |
|---|---|
<assistant name> | 已部署助手的名称 |
-c, --capability <name> | 显示指定能力的详细信息 |
joule launch
在默认浏览器中打开 Joule Web 客户端中的已部署助手。
joule launch my_assistant
joule delete
删除已部署的数字助手。
joule delete my_assistant
joule update
使用新增或修改的能力更新已部署助手(需要启用模块化功能标志)。
joule update my_assistant --capability-file ./my-cap.daar
joule update my_assistant --capability-file ./capability.sapdas.yaml -b 3
joule update my_assistant --mcp-server-file ./mcp-server.json
| 选项 | 说明 |
|---|---|
<assistant name> | 已部署助手的名称 |
--capability-file <path> | .daar 或 capability.sapdas.yaml 的路径(可重复指定) |
--mcp-server-file <path> | MCP 服务元数据 JSON 的路径(可重复指定,测试版) |
--hide-warnings | 抑制警告 |
-b, --batch-size <n> | 编译时的批次大小 |
joule remove
从已部署助手中移除指定能力(需要启用模块化功能标志)。
joule remove my_assistant --capability com.example:my_capability
| 选项 | 说明 |
|---|---|
<assistant name> | 已部署助手的名称 |
--capability <namespace:name> | 要移除的能力(可重复指定) |
测试与质量
joule test
针对已部署助手执行 BDD(Cucumber)测试场景。
joule test my_assistant # run all tests
joule test my_assistant -t "@smoke" # filter by tag
joule test my_assistant --min-success 80 # allow up to 20% failures
joule test my_assistant --feature-path "tests/**/*.feature"
joule test my_assistant --use-env # auth from .env
joule test my_assistant -i ./my-cap.daar # include DAAR files
joule test my_assistant --timeout 60000 # 60s timeout
joule test --init # scaffold test setup
| 选项 | 说明 |
|---|---|
[assistant name] | 已部署助手的名称 |
--init | 初始化测试设置脚手架 |
-f, --format <fmt> | 结果格式化程序:pretty(默认)、json、html |
-t, --tags <expr> | 用于筛选场景的 Cucumber 标签表达式 |
--use-env [path] | 从 env / .env 文件读取凭据 |
-i, --daar-input-file <files...> | 要包含的 DAAR 文件 |
--profile <profile...> | 用于测试执行的用户配置文件 |
--config <file> | Cucumber 配置文件的路径 |
--min-success <pct> | 最低通过率(0–100,默认:100) |
--feature-path [globs...] | .feature 文件的 Glob 模式(默认:tests/features/**/*.feature) |
--published-capabilities | 从已部署助手下载远程 DAAR 文件 |
--timeout <ms> | 测试执行超时时间(也可通过 JOULE_TEST_TIMEOUT 环境变量设置) |
--joule-language <lang> | 测试执行所用语言 |
Cucumber 配置按以下顺序查找:cucumber.json、cucumber.yaml、cucumber.yml、cucumber.js、cucumber.cjs、cucumber.mjs。
测试步骤示例(Gherkin 语法):
Given I am user "[email protected]"
And I log in
And I start a new conversation
When I say "Show my leave balance"
Then first message has type text
And first message content contains "balance"
And response has 2 messages
joule lint
对功能源文件运行静态检查。
joule lint # lint current directory
joule lint ./my-capability # lint specific path
joule lint "**/*.yaml" # lint with glob
joule lint -f json # JSON output
joule lint --severity-level error # only show errors
| 选项 | 说明 |
|---|---|
[file/dir/glob] | 要检查的路径或 glob 模式(默认:当前目录) |
-f, --format <fmt> | 输出格式:pretty(默认)、json、html、combined |
--severity-level <level> | 最低严重性级别:info、warning(默认)、error |
如果发现错误,则以代码 1 退出。Lint 规则会检查场景描述是否唯一、是否使用硬编码 URL、注解用法、OData 分页等内容。
joule scenario-testing-to-feature
将旧版 YAML 测试场景文件转换为适用于 Cucumber 测试框架的 Gherkin .feature 文件。
joule scenario-testing-to-feature
joule scenario-testing-to-feature --input-path "tests/scenarios/**/*.yaml"
| 选项 | 说明 |
|---|---|
--input-path <glob> | YAML 场景文件的 glob(默认:tests/scenarios/**/*.yaml) |
配置文件
da.sapdas.yaml(数字助理定义)
这是主要部署描述符,用于定义构成助手的功能。
schema_version: "3.4.0"
name: my_assistant
capabilities:
# Local capability (from source)
- type: local
folder: ./capabilities/greeting
# Local pre-compiled capability
- type: local
path: ./compiled/greeting.daar
# Released capability from registry
- type: release
namespace: com.sap.example
name: greeting
version: "1.0.0"
# Milestone (pre-release) capability
- type: milestone
namespace: com.sap.example
name: greeting
version: "1.0.0-SNAPSHOT"
名称约束: 3–50 个字符,模式为 ^[a-zA-Z0-9]\w*[a-zA-Z0-9]$。
命名空间模式: ^(?!\.)[a-zA-Z0-9.]+$(开头和结尾不能有句点)。
版本模式: ^([0-9]+)\.([0-9]+)\.([0-9]+)(-)?( SNAPSHOT)?$
ai_assistant.sapdas.yaml(AI 助手定义)
与 joule link 配合使用,用于定义负责协调各项功能的 AI 助手。
schema_version: "1.0.0"
metadata:
namespace: com.example
name: my_ai_assistant
version: "1.0.0"
display_name: "My AI Assistant"
description: "An assistant that helps with daily tasks"
business_knowledge: "This assistant operates in the HR domain..."
capabilities:
- namespace: com.example
name: leave_management
scenarios:
- check_balance
- request_leave
capability.sapdas.yaml
每项功能都位于各自的文件夹中,并且必须包含此文件。文件中包含定义功能可执行操作的场景定义、对话函数、钩子和 Agent。
常见工作流
完整开发周期
# 1. Log in
joule login --sso
# 2. Compile your capability
joule compile ./capabilities/my-cap ./output
# 3. Deploy the assistant
joule deploy ./da.sapdas.yaml --compile
# 4. Launch in browser to verify
joule launch my_assistant
# 5. Run automated tests
joule test my_assistant -t "@smoke"
# 6. Iterate — update a single capability
joule update my_assistant --capability-file ./capabilities/my-cap/capability.sapdas.yaml
CI/CD 管道
# Login via env vars (no interactive prompts)
joule login --use-env
# Lint first
joule lint ./capabilities/ --severity-level error
# Compile + deploy in one step
joule deploy ./da.sapdas.yaml --compile -n my_assistant
# Run tests with a minimum pass threshold
joule test my_assistant --min-success 90 -f json --use-env
在不重新部署所有内容的情况下更新单项功能
joule update my_assistant --capability-file ./capabilities/updated-cap.daar
从已部署的助手中移除功能
joule remove my_assistant --capability com.example:old_capability
故障排除
登录问题
| 症状 | 可能原因 | 解决方法 |
|---|---|---|
| 登录无提示失败 | 身份验证 URL 错误 | 仔细检查 URL 模式 — XSUAA 使用 .authentication.<landscape>.hana.ondemand.com,IAS 使用 .accounts.<domain> |
AUTH_LOGIN_TIMEOUT(错误 17) | 浏览器未完成 SSO | 使用 joule login --sso-passcode 重试,或使用用户名/密码流程 |
AUTH_FETCH_TOKEN_FAILED(错误 14) | 客户端凭据无效 | 检查服务密钥中的客户端 ID 和密钥 |
AUTH_UNSUPPORTED_AUTH_TYPE(错误 16) | 无法识别的身份验证 URL 格式 | 确保身份验证 URL 符合 XSUAA 或 IAS 模式 |
| Linux 上的 Keytar 错误 | 缺少 libsecret | 安装 libsecret-1-dev(Debian/Ubuntu)或 libsecret-devel(RHEL),或使用 --unsecure-storage |
编译/部署问题
| 症状 | 可能原因 | 解决方法 |
|---|---|---|
COMPILE_INVALID_SOURCE(错误 22) | 文件夹中没有 capability.sapdas.yaml | 检查指定的目录是否正确 |
DEPLOY_INVALID_SOURCE(错误 32) | 未找到 da.sapdas.yaml | 确保该文件存在于指定路径 |
INVALID_ASSISTANT_NAME(错误 36) | 名称不符合模式 | 使用 3–50 个字符,包含字母数字字符和下划线,且必须以字母数字字符开头和结尾 |
JOB_MAX_WAITING_TIME_EXCEEDED(错误 40) | 部署耗时超过 15 分钟 | 重试;如果问题持续存在,请检查服务运行状况或减少功能数量 |
LINK_INVALID_SOURCE(错误 172) | 没有 ai_assistant.sapdas.yaml | 确认 AI 助手定义文件存在 |
测试问题
| 症状 | 可能原因 | 解决方法 |
|---|---|---|
| 未找到测试 | 功能文件路径错误 | 使用 --feature-path 指定正确的 glob(默认:tests/features/**/*.feature) |
| 测试超时 | 场景运行时间过长 | 使用 --timeout <ms> 或 JOULE_TEST_TIMEOUT 环境变量延长超时时间 |
CUCUMBER_CONFIGURATION_ERROR(错误 120) | Cucumber 配置错误 | 检查 cucumber.json / cucumber.yaml 语法 |
| 测试在本地通过但在 CI 中失败 | 缺少身份验证 | 添加 --use-env 并设置 JOULE_* 环境变量 |
常规调试
- 在任意命令中添加
-d(调试)以输出详细日志——调试文件会写入当前目录 - 运行
joule status,确认已登录,并检查目标 API/身份验证 URL - 使用
joule get <assistant>检查实际部署的内容 - 检查 Node.js 版本(
node -v)——必须为 v20.12.0 – v24
关键概念
| 术语 | 含义 |
|---|---|
| DTA | 设计时构件(Design Time Artifact)——你的能力源代码(YAML、对话、场景、钩子) |
| DAAR | 数字助手归档(Digital Assistant Archive)——已编译的能力(joule compile 的输出) |
| AIAAR | AI 助手归档(AI Assistant Archive)——已关联的 AI 助手(joule link 的输出) |
| RTA | 运行时构件(Runtime Artifact)——在 joule deploy 期间上传的完整部署包 |
| 能力 | 在 capability.sapdas.yaml 中定义的单一功能单元 |
| 数字助手 | 将多个能力打包在一起的已部署实例,在 da.sapdas.yaml 中定义 |
| AI 助手 | 具备业务知识的编排层,在 ai_assistant.sapdas.yaml 中定义 |