wjplus-cli
v0.2.15
Published
问卷加加/问卷管家命令行工具 - 专供大模型 Agent 使用
Maintainers
Readme
wjplus-cli
问卷加加 / 问卷管家命令行工具 — 专供大模型 Agent 使用的问卷管理 CLI。
概述
wjplus-cli 同时支持问卷加加和问卷管家两个产品,面向大模型 Agent(非人类直接使用),提供问卷/考试/测评的数据结构规范、本地校验、创建、查看、统计分析等全流程能力。两个产品共享同一套代码,通过不同的命令入口自动切换产品身份,配置、凭证完全隔离。
| 产品 | 命令 | AppId | 配置目录 |
| ---- | ----------- | -------------------- | --------------- |
| 问卷加加 | wjplus | wx771820531f2d9634 | ~/.wjplus/ |
| 问卷管家 | wjguanjia | wx970228cfffbc37d2 | ~/.wjguanjia/ |
核心特性
- 双产品支持:同一套代码,
wjplus和wjguanjia两个命令入口,自动切换 appId 和配置 - 三类型覆盖:支持问卷(type=1)、考试(type=2)、测评(type=3)三种项目的完整创建流程
- 51 种题型:覆盖单选/多选/填空/判断/问答/NPS/矩阵/图片选择/完形填空/测评权重评分/测评NPS/测评矩阵单选等全部题型
- 双模式鉴权:API Key(自动化场景)+ 微信扫码授权(交互式场景)
- JSON Schema 规范:内置完整的问卷数据结构定义,另提供
docs/cli-generation-spec.md供 Agent 阅读 - 本地校验:基于 Ajv 一次性返回所有校验错误,方便 Agent 快速修正
- 纯 JSON 输出:
--json模式下 stdout 仅输出纯 JSON,无颜色/动画干扰 - 标准退出码:成功 Exit Code 0,失败 Exit Code 非 0
- CLI 创建标识:通过 CLI 创建的项目自动标记
remark="cli",便于区分来源
技术栈
| 依赖 | 用途 | | -------------------- | ---------------- | | Node.js + TypeScript | 运行时与开发语言 | | commander | 命令行参数解析 | | ajv + ajv-formats | JSON Schema 校验引擎 | | axios | HTTP 请求 | | qrcode-terminal | 终端二维码渲染 | | chalk | 终端彩色输出 | | ora | 加载动画 |
项目结构
wjplus-cli/
├── src/
│ ├── index.ts # CLI 入口(双产品共用,自动识别)
│ ├── wjguanjia.ts # 问卷管家入口(设置 WJ_PRODUCT 环境变量)
│ ├── commands/
│ │ ├── auth.ts # 鉴权命令(动态产品名)
│ │ ├── config.ts # 配置管理命令
│ │ ├── spec.ts # 规范输出与校验命令
│ │ ├── questionnaire.ts # 问卷/考试/测评 CRUD 命令
│ │ ├── analysis.ts # 统计分析命令
│ │ └── user.ts # 用户信息命令
│ ├── schemas/
│ │ └── survey.schema.json # 问卷 JSON Schema
│ ├── api/
│ │ ├── client.ts # axios 封装(自动注入 token + appId)
│ │ ├── auth.ts # 鉴权 API
│ │ ├── questionnaire.ts # 问卷 CRUD API(含 cliCreate 接口)
│ │ ├── analysis.ts # 统计分析 API
│ │ └── user.ts # 用户信息 API
│ ├── auth/
│ │ ├── store.ts # Token 缓存与过期管理
│ │ ├── apikey.ts # API Key 认证策略(支持不同前缀)
│ │ └── qrcode.ts # 扫码授权策略
│ └── utils/
│ ├── config.ts # 产品注册表 + 配置文件读写
│ ├── output.ts # JSON / 格式化双模式输出
│ └── error.ts # 错误类与统一处理
├── docs/
│ └── cli-generation-spec.md # CLI 生成规范(供 Agent 阅读,覆盖51种题型+考试/测评完整流程)
├── skill/
│ ├── SKILL.md # Agent 技能描述文件(触发条件+角色设定+命令规范+数据脱敏)
│ ├── references/
│ │ ├── command-reference.md # CLI 命令完整参考
│ │ └── data-masking-guide.md # 数据脱敏详细指南
│ └── assets/
│ └── response-template.md # 标准回复话术模板
├── test-survey.json # 问卷测试数据(6种题型)
├── test-exam.json # 考试测试数据(7种题型)
├── test-assessment.json # 测评测试数据(6种题型+测评结果区间)
├── test-e2e.ps1 # E2E 测试脚本
├── package.json # 双 bin 入口(wjplus + wjguanjia)
├── tsconfig.json
├── .traerules
├── SPEC.md
└── TODO.md本地开发
环境要求
- Node.js >= 16
- npm >= 8
安装依赖
npm install编译
npm run build编译产物输出到 dist/ 目录。
调试命令
# 问卷加加
node dist/index.js --help
node dist/index.js auth status --json
node dist/index.js config list --json
# 问卷管家
node dist/wjguanjia.js --help
node dist/wjguanjia.js auth status --json
node dist/wjguanjia.js config list --json
# 校验
node dist/index.js validate --file test-survey.json --json
# 创建问卷
node dist/index.js create --file test-survey.json --json
# 创建考试
node dist/index.js create --file test-exam.json --json
# 创建测评
node dist/index.js create --file test-assessment.json --json注意:
dist/wjguanjia.js通过process.env.WJ_PRODUCT='wjguanjia'标识产品身份,不再依赖文件名识别。
类型检查
npm run typecheck清理编译产物
Remove-Item -Recurse -Force distE2E 测试
# 连接测试环境
powershell -ExecutionPolicy Bypass -File test-e2e.ps1
# 连接本地后端
powershell -ExecutionPolicy Bypass -File test-e2e.ps1 local部署与发布
前置条件:npm 账号
发布到 npm 需要一个 npm 账号:
- 注册:访问 https://www.npmjs.com/signup
- 登录:
npm login(按提示输入用户名、密码、邮箱、OTP) - 验证:
npm whoami确认登录状态
如果发布到组织 scope(如
@wenjuan/wjplus-cli),需先创建组织或加入已有组织。
1. 编译发布版本
npm run build2. 创建 wjguanjia 入口
发布前需确保 dist/wjguanjia.js 存在(通过 src/wjguanjia.ts 编译生成):
npm run build3. 本地全局安装(测试)
方式 A:npm link(需管理员权限)
Windows 下需以管理员身份运行终端:
npm link方式 B:.cmd 包装脚本(无需管理员权限)
项目根目录已提供 wjplus.cmd 和 wjguanjia.cmd,双击或直接运行即可:
.\wjplus.cmd --help
.\wjguanjia.cmd auth status --json卸载 npm link:
npm unlink -g wjplus-cli发布前先执行 Agent 本地回归,确认 CLI/skill/npm 包契约没有被破坏:
npm run test:agent4. 发布到 npm(公开)
# 首次发布
npm publish --access public
# 后续更新版本
npm version patch # 0.2.0 → 0.2.1(修复)
npm version minor # 0.2.0 → 0.3.0(新功能)
npm version major # 0.2.0 → 1.0.0(破坏性变更)
npm publish发布后用户可通过 npm install -g wjplus-cli 安装,同时获得 wjplus 和 wjguanjia 两个命令。
5. 发布到 npm(私有包)
如果不想公开源码,可发布为私有包(需 npm 付费账号):
# package.json 中添加
# "name": "@wenjuan/wjplus-cli",
# "publishConfig": { "access": "restricted" }
npm publish用户安装时:
npm install -g @wenjuan/wjplus-cli6. 发布到私有 Registry(企业推荐)
适合企业内部使用,不暴露到公网:
# 方式 A:通过 .npmrc 配置
echo @wenjuan:registry=https://your-registry.com/ > .npmrc
npm publish
# 方式 B:命令行指定
npm publish --registry=https://your-registry.com用户安装时:
npm install -g wjplus-cli --registry=https://your-registry.com7. 直接分发(无需 npm)
将 dist/ 目录与 node_modules/ 一起打包:
Compress-Archive -Path dist, node_modules, package.json -DestinationPath wjplus-cli.zip用户解压后通过 .cmd 脚本或直接 node dist/index.js 运行。
版本管理规范
| 命令 | 版本变化 | 适用场景 |
| ------------------- | ------------- | ---------- |
| npm version patch | 0.2.0 → 0.2.1 | Bug 修复 |
| npm version minor | 0.2.0 → 0.3.0 | 新增功能(向后兼容) |
| npm version major | 0.2.0 → 1.0.0 | 破坏性变更 |
用户安装与使用
安装
方式一:npx 零安装(推荐 Agent 使用)
无需安装,直接通过 npx 执行:
npx wjplus-cli --version # 问卷加加
npx wjplus-cli --product wjguanjia --version # 问卷管家npx 会自动下载最新版本,无需管理员权限,适合 Agent 沙箱环境。
方式二:全局安装
npm install -g wjplus-cli验证安装:
wjplus --version # 问卷加加
wjguanjia --version # 问卷管家产品切换
npx 方式:通过 --product 参数切换
npx wjplus-cli auth status --json # 问卷加加(默认)
npx wjplus-cli --product wjguanjia auth status --json # 问卷管家全局安装方式:通过不同的命令名切换
wjplus auth status --json # 问卷加加
wjguanjia auth status --json # 问卷管家鉴权
CLI 提供两种鉴权方式,任选其一即可。
方式一:API Key(推荐 Agent 自动化场景)
- 打开对应小程序 → 我的 → 设置 → API 密钥 → 生成密钥
- 在终端配置 API Key:
# 问卷加加
wjplus auth login --api-key wjk_live_your_api_key_here_32chars
# 问卷管家
wjguanjia auth login --api-key wjg_live_your_api_key_here_32chars- 验证鉴权状态:
wjplus auth status --json
wjguanjia auth status --jsonAPI Key 格式对照:
| 产品 | 正式环境前缀 | 测试环境前缀 |
| ---- | ----------- | ----------- |
| 问卷加加 | wjk_live_ | wjk_test_ |
| 问卷管家 | wjg_live_ | wjg_test_ |
方式二:微信扫码授权(交互式场景)
wjplus auth login # 问卷加加扫码
wjguanjia auth login # 问卷管家扫码终端将显示二维码,使用微信扫码授权即可。Token 有效期 3 天,过期后需重新扫码。
Agent 平台推荐使用二维码信息模式,避免长进程中间输出导致解析不稳定:
# 1. 获取二维码信息,一段 JSON 输出后立即退出
wjplus auth login --qr-only --json
# 2. 用户扫码后,用上一步返回的 loginKey 等待确认并保存 Token
wjplus auth check <loginKey> --wait --json--qr-only --json 输出包含 loginKey、qrCodeImage、qrCodeDataUrl、qrCodeUrl、nextCommand 和 localCommand。Agent 应优先展示 qrCodeImage,不支持本地图片的平台可降级展示 qrCodeDataUrl 或 qrCodeUrl;零安装场景执行 nextCommand,全局安装场景可执行 localCommand。
create --json 和 qrcode <uuid> --json 同样输出 qrCodeImage、qrCodeDataUrl、qrCodeUrl。Agent 应优先把 qrCodeImage 作为图片展示,不能把二维码 URL 仅作为普通文本返回。
查看鉴权状态
wjplus auth status --json
wjguanjia auth status --json输出示例:
{
"authenticated": false,
"product": "wjplus",
"productDisplayName": "问卷加加",
"hasApiKey": false,
"hasToken": false,
"tokenExpiresAt": null,
"baseUrl": "https://www.wjguanjia.com/prod-api",
"appId": "wx771820531f2d9634"
}登出
wjplus auth logout
wjguanjia auth logout配置管理
# 切换环境(默认 production;Agent 调试推荐 test)
wjplus config set env production
wjplus config set env test
wjplus config set env local
# 设置配置项
wjplus config set apiKey wjk_live_xxx
wjguanjia config set apiKey wjg_live_xxx
# 获取配置项
wjplus config get env
wjplus config get baseUrl
# 列出所有配置
wjplus config list --json
wjguanjia config list --json配置文件路径:
| 产品 | 路径 |
| ---- | -------------------------- |
| 问卷加加 | ~/.wjplus/config.json |
| 问卷管家 | ~/.wjguanjia/config.json |
| 配置项 | 说明 | 问卷加加默认值 | 问卷管家默认值 |
| --------- | --------- | ------------------------------------ | ------------------------------------ |
| baseUrl | 服务端地址 | https://www.wjguanjia.com/prod-api | https://www.wjguanjia.com/prod-api |
| appId | 小程序 AppId | wx771820531f2d9634 | wx970228cfffbc37d2 |
| product | 产品标识 | wjplus | wjguanjia |
| env | 当前环境 | production | production |
| apiKey | API 密钥 | — | — |
环境对照:
| env | baseUrl | 说明 |
|-----|---------|------|
| production | https://www.wjguanjia.com/prod-api | 默认生产环境,适合正式用户和已发布 Agent |
| test | https://wenjuantest.kuaikaoshi.top/prod-api | 测试环境,适合多平台调试和测试 API Key |
| local | http://localhost:9040 | 本地后端联调 |
| custom | 用户手动设置的 baseUrl/loginUrl | 自定义环境 |
手动执行 config set baseUrl <url> 会将环境标记为 custom;如果 <url> 是内置环境地址,CLI 会自动识别对应环境并同步 loginUrl。自定义地址会自动从 baseUrl 推导 loginUrl,如需覆盖可执行 config set loginUrl <url>。
命令参考
所有命令均支持 --json 参数,启用后 stdout 仅输出纯 JSON,适合 Agent 解析。以下以 wjplus 为例,wjguanjia 命令完全相同。
鉴权
| 命令 | 说明 | 需要鉴权 |
| ----------------------------------- | ---------- | ---- |
| wjplus auth login | 扫码登录 | 否 |
| wjplus auth login --api-key <key> | API Key 登录 | 否 |
| wjplus auth check <loginKey> | 检查扫码登录状态 | 否 |
| wjplus auth status | 查看鉴权状态 | 否 |
| wjplus auth logout | 登出 | 否 |
问卷规范与校验
| 命令 | 说明 | 需要鉴权 |
| ------------------------------- | ------------------- | ---- |
| wjplus spec | 输出问卷 JSON Schema 规范 | 否 |
| wjplus validate --file <path> | 校验问卷 JSON 文件 | 否 |
问卷/考试/测评操作
| 命令 | 说明 | 需要鉴权 |
| ------------------------------------ | ----------- | ---- |
| wjplus create --file <path> | 创建问卷/考试/测评 | 是 |
| wjplus list [--page 1] [--size 10] | 问卷列表 | 是 |
| wjplus detail <uuid> | 问卷详情(含题目列表) | 是 |
| wjplus update <uuid> --file <path> | 修改问卷 | 是 |
| wjplus close <uuid> | 关闭问卷 | 是 |
| wjplus delete <uuid> | 删除问卷(移至回收站) | 是 |
| wjplus copy <uuid> | 复制问卷 | 是 |
| wjplus qrcode <uuid> | 获取问卷二维码 | 是 |
统计分析
| 命令 | 说明 | 需要鉴权 |
| ---------------------------------------------------- | ------ | ---- |
| wjplus stats <uuid> | 统计概览 | 是 |
| wjplus stats <uuid> --trend | 回收趋势 | 是 |
| wjplus analyze <uuid> | 题目分析 | 是 |
| wjplus analyze <uuid> --cross --question-ids <ids> | 交叉分析 | 是 |
| wjplus records <uuid> [--page 1] [--size 10] | 答题记录 | 是 |
| wjplus export <uuid> | 导出数据 | 是 |
| wjplus export <uuid> --analysis | 导出分析数据 | 是 |
用户信息
| 命令 | 说明 | 需要鉴权 |
| ------------------------- | ------ | ---- |
| wjplus whoami | 当前用户信息 | 是 |
| wjplus balance | 余额查询 | 是 |
| wjplus balance --ledger | 余额流水 | 是 |
配置
| 命令 | 说明 | 需要鉴权 |
| --------------------------------- | ------ | ---- |
| wjplus config set <key> <value> | 设置配置项 | 否 |
| wjplus config get <key> | 获取配置项 | 否 |
| wjplus config list | 列出所有配置 | 否 |
问卷/考试/测评 JSON 规范
CLI 通过 questionnaireType 字段区分三种项目类型,使用 wjplus create --file <path> 统一创建。
完整的 51 种题型参考表、字段说明和 JSON 示例详见 docs/cli-generation-spec.md,供 Agent 阅读参考。
三种类型对照
| 类型 | questionnaireType | 说明 | 特有字段 |
|------|-------------------|------|---------|
| 问卷 | "1" | 收集信息的标准问卷 | — |
| 考试 | "2" | 带评分和正确答案的考试 | questionScore, chooseAnswer, scoringMethod, keyword, analysis |
| 测评 | "3" | 带分数区间和测评结果的评估 | questionScore, optionScore, assessmentResults, ifAssessmentResult |
问卷 JSON 基本结构
{
"questionnaireType": "1",
"questionnaireName": "客户满意度调查",
"questionnaireDescribe": "感谢您参与本次调查",
"questionList": [
{
"questionType": "1",
"questionTitle": "您对我们的服务整体满意吗?",
"isRequired": true,
"questionOptions": [
{ "optionContent": "非常满意" },
{ "optionContent": "满意" },
{ "optionContent": "一般" },
{ "optionContent": "不满意" }
]
},
{
"questionType": "2",
"questionTitle": "您认为哪些方面需要改进?",
"isRequired": true,
"questionOptions": [
{ "optionContent": "服务态度" },
{ "optionContent": "响应速度" },
{ "optionContent": "专业水平" }
]
},
{
"questionType": "3",
"questionTitle": "请填写您的建议 ____",
"isRequired": false,
"fillSymbol": 3
}
]
}考试 JSON 基本结构
{
"questionnaireType": "2",
"questionnaireName": "Java基础知识考试",
"questionnaireDescribe": "测试Java基础掌握程度",
"questionList": [
{
"questionType": "1",
"questionTitle": "以下哪个是Java的基本数据类型?",
"isRequired": true,
"questionOptions": [
{ "optionContent": "String" },
{ "optionContent": "int" },
{ "optionContent": "ArrayList" }
],
"questionScore": 10,
"chooseAnswer": "B",
"analysis": "int是Java的8种基本数据类型之一"
},
{
"questionType": "22",
"questionTitle": "Java是一种解释型语言",
"isRequired": true,
"questionOptions": [
{ "optionContent": "正确" },
{ "optionContent": "错误" }
],
"questionScore": 5,
"chooseAnswer": "B",
"analysis": "Java是半编译半解释型语言"
},
{
"questionType": "3",
"questionTitle": "Java中____是所有类的根类",
"isRequired": true,
"fillSymbol": 2,
"questionScore": 10,
"chooseAnswer": "Object",
"scoringMethod": 1,
"analysis": "Object是Java类层次结构的根类"
},
{
"questionType": "11",
"questionTitle": "请简述JVM的工作原理",
"isRequired": true,
"questionScore": 20,
"chooseAnswer": "JVM负责将字节码转换为机器码执行",
"keyword": "字节码;虚拟机;编译;运行",
"scoringMethod": 2,
"analysis": "JVM是Java平台的核心"
}
]
}考试特有字段说明:
| 字段 | 类型 | 说明 | |------|------|------| | questionScore | Integer | 题目分数 | | chooseAnswer | String | 正确答案(单选/判断: "A",多选: "A;C;D",填空: "答案1;答案2") | | scoringMethod | Integer | 评分方式(0=全部答对得分, 1=部分答对得分, 2=对比关键字, 3=答对一个关键字给全部分) | | keyword | String | 关键词(问答题型,多个用";"分隔) | | analysis | String | 题目解析 |
考试自动创建的设置:
- 自动创建 3 条自定义登录设置(姓名/手机号/邮箱)
- 自动设置封面默认值
- 自动计算总分(所有题目 questionScore 之和)
测评 JSON 基本结构
{
"questionnaireType": "3",
"questionnaireName": "员工能力测评",
"questionnaireDescribe": "评估员工综合能力",
"questionList": [
{
"questionType": "43",
"questionTitle": "您对当前工作环境的满意度如何?",
"isRequired": true,
"questionOptions": [
{ "optionContent": "非常满意", "optionScore": 5 },
{ "optionContent": "满意", "optionScore": 4 },
{ "optionContent": "一般", "optionScore": 3 },
{ "optionContent": "不满意", "optionScore": 2 },
{ "optionContent": "非常不满意", "optionScore": 1 }
],
"questionScore": 5
},
{
"questionType": "45",
"questionTitle": "请对以下能力进行评分",
"isRequired": true,
"questionOptions": [
{ "optionContent": "专业能力", "optionScore": 10 },
{ "optionContent": "沟通能力", "optionScore": 10 }
],
"questionScore": 20
},
{
"questionType": "47",
"questionTitle": "请对整体表现进行评价",
"isRequired": true,
"scoreNum": 5,
"minScore": 1,
"questionScore": 5
}
],
"assessmentResults": [
{ "minScore": 0, "maxScore": 15, "resultTitle": "待提升", "resultContent": "有较大提升空间", "resultDetail": "建议制定发展计划" },
{ "minScore": 16, "maxScore": 25, "resultTitle": "良好", "resultContent": "整体表现良好", "resultDetail": "建议关注薄弱环节" },
{ "minScore": 26, "maxScore": 30, "resultTitle": "优秀", "resultContent": "综合表现优秀", "resultDetail": "建议探索更高目标" }
],
"ifAssessmentResult": "1",
"ifShowAssessmentScore": "1"
}测评特有字段说明:
| 字段 | 类型 | 说明 | |------|------|------| | questionScore | Integer | 题目总分(测评单选/多选/权重评分/分数评定) | | optionScore | Integer | 选项分数(测评单选/多选选项) | | assessmentResults | Array | 测评结果区间(minScore, maxScore, resultTitle, resultContent, resultDetail, mediaUrls) | | ifAssessmentResult | String | 是否测评结果设置("1"=是) | | ifShowAssessmentScore | String | 是否显示测评分数("1"=是) |
测评自动创建的设置:
- 自动设置封面默认值
- 自动设置 ifAssessmentResult="1"
支持的题目类型(51种)
| type | 题型 | 问卷 | 考试 | 测评 | |------|------|:----:|:----:|:----:| | 1 | 单选 | ✓ | ✓ | | | 2 | 多选 | ✓ | ✓ | | | 3 | 填空 | ✓ | ✓ | | | 4 | 多项填空 | ✓ | ✓ | | | 5 | 下拉 | ✓ | | | | 6 | NPS | ✓ | | | | 7 | 投票 | ✓ | | | | 8 | 排序 | ✓ | | | | 9 | 备注说明 | ✓ | ✓ | | | 10 | 分数评定 | ✓ | | | | 11 | 问答 | ✓ | ✓ | | | 12 | 权重评分 | ✓ | | | | 13 | 评星 | ✓ | | | | 14 | 姓名 | ✓ | ✓ | ✓ | | 15 | 性别 | ✓ | ✓ | ✓ | | 16 | 年龄 | ✓ | ✓ | ✓ | | 17 | 手机号 | ✓ | ✓ | ✓ | | 18 | 邮箱 | ✓ | ✓ | ✓ | | 19 | 日期 | ✓ | ✓ | ✓ | | 20 | 时间 | ✓ | ✓ | ✓ | | 21 | 地址 | ✓ | ✓ | ✓ | | 22 | 判断 | ✓ | ✓ | | | 23 | 上传图片 | ✓ | ✓ | | | 25 | 上传文件 | ✓ | | | | 29 | 出生日期 | ✓ | ✓ | ✓ | | 30 | 身份证号 | ✓ | ✓ | ✓ | | 31 | 学历 | ✓ | ✓ | ✓ | | 32 | 微信号 | ✓ | ✓ | ✓ | | 33 | 标题 | ✓ | | | | 34 | 分页线 | ✓ | | | | 35 | 矩阵单选 | ✓ | | | | 36 | 矩阵多选 | ✓ | | | | 37 | 图片单选 | ✓ | | | | 38 | 图片多选 | ✓ | | | | 39 | 图片/视频 | ✓ | | ✓ | | 40 | 签名 | ✓ | | | | 41 | 行业 | ✓ | | | | 42 | 职业 | ✓ | | | | 43 | 测评单选 | | | ✓ | | 44 | 测评多选 | | | ✓ | | 45 | 测评权重评分 | | | ✓ | | 46 | 测评NPS | | | ✓ | | 47 | 测评分数评定 | | | ✓ | | 48 | 文本描述 | | | ✓ | | 49 | 自定义 | ✓ | ✓ | ✓ | | 50 | 测评矩阵单选 | | | ✓ | | 51 | 测评音频 | | | ✓ |
每种题型的 chooseList 格式、必填/可选字段详见 docs/cli-generation-spec.md。
输出规范
成功时
- Exit Code:
0 - 结果输出到
stdout --json模式下输出格式化 JSON
$ wjplus validate --file survey.json --json
{"valid":true}$ wjplus auth status --json
{
"authenticated": true,
"product": "wjplus",
"productDisplayName": "问卷加加",
"hasApiKey": true,
"hasToken": true,
"tokenExpiresAt": "2026-05-30T10:00:00.000Z",
"baseUrl": "https://www.wjguanjia.com/prod-api"
}失败时
- Exit Code: 非
0(鉴权失败为401,校验失败为1) - 错误详情以 JSON 格式输出到
stderr
$ wjplus list --json
# stderr: {"error":"未登录,请先执行 wjplus auth login","code":401}
$ wjguanjia list --json
# stderr: {"error":"未登录,请先执行 wjguanjia auth login","code":401}鉴权机制
自动鉴权优先级
CLI 在每次请求时按以下顺序自动获取有效凭证:
- 缓存 Token:检查本地缓存的 Token 是否有效(5 分钟缓冲期)
- API Key 换取:若配置了 API Key,自动调用后端换取临时 Token
- 提示登录:以上均无时,返回 401 错误,提示执行对应产品的
auth login
Token 生命周期
| 项目 | 说明 |
| ---- | ----------------------------------------------------------- |
| 格式 | Mini_{userKey}_{32位随机字符串} |
| 传递方式 | HTTP Header token |
| 有效期 | 3 天 |
| 存储 | 按产品隔离(~/.wjplus/config.json 或 ~/.wjguanjia/config.json) |
| 刷新 | API Key 模式自动刷新;扫码模式需重新扫码 |
请求头注入
所有 API 请求自动注入以下 Header(用户不可见,无需手动配置):
| Header | 说明 |
| -------------- | ------------------ |
| appId | 根据产品自动选择,不对外暴露 |
| token | 鉴权后自动注入,不对外暴露 |
| Content-Type | 固定 application/json |
安全设计
敏感信息保护
CLI 在所有输出中自动遮蔽以下敏感字段,防止 Agent 日志或终端截图中泄露:
| 字段 | 遮蔽方式 | 涉及命令 |
| --------------- | ---- | -------------------------- |
| appId | *** | config list、config get |
| apiKey | *** | config list、config get |
| token | *** | config list、config get |
| tokenExpiresAt | *** | config list、config get |
auth status --json不输出 appId、apiKey、token,仅输出布尔值(hasApiKey、hasToken)config set不允许设置appId(已从允许列表中移除)config get appId返回***
配置文件安全
| 措施 | 说明 |
| ---- | ----------------------------------------------- |
| 文件权限 | 配置文件保存时自动设置 0600(仅用户可读写) |
| 存储位置 | ~/.wjplus/config.json / ~/.wjguanjia/config.json(用户主目录下) |
| 产品隔离 | 两个产品的配置、Token、API Key 完全隔离存储 |
Agent 使用安全建议
- API Key 优先:Agent 应使用 API Key 鉴权,避免扫码流程中暴露二维码给不可信方
- 最小权限:为 Agent 生成专用的 API Key,设置合理的过期时间
- 定期轮换:通过小程序撤销旧 Key、生成新 Key
- 日志脱敏:
--json模式下所有敏感字段已遮蔽,但建议 Agent 额外过滤token、apiKey等关键词 - 环境隔离:不同环境(开发/测试/生产)使用不同的 API Key
Agent 集成示例
问卷加加 — 问卷工作流
wjplus auth login --api-key wjk_live_xxx --json
wjplus spec > survey-schema.json
wjplus validate --file survey.json --json
wjplus create --file survey.json --json
wjplus list --page 1 --size 10 --json
wjplus stats <uuid> --json
wjplus export <uuid> --json问卷加加 — 考试工作流
wjplus auth login --api-key wjk_live_xxx --json
wjplus create --file exam.json --json
wjplus detail <uuid> --json
wjplus stats <uuid> --json问卷加加 — 测评工作流
wjplus auth login --api-key wjk_live_xxx --json
wjplus create --file assessment.json --json
wjplus detail <uuid> --json
wjplus stats <uuid> --json问卷管家工作流
wjguanjia auth login --api-key wjg_live_xxx --json
wjguanjia create --file survey.json --json
wjguanjia list --page 1 --size 10 --json
wjguanjia stats <uuid> --json
wjguanjia export <uuid> --jsonAgent 生成规范
Agent 生成问卷/考试/测评内容时,应参考 docs/cli-generation-spec.md 中的完整规范,该文档包含:
- 51 种题型的 questionType 编号、字段要求、chooseList 格式
- 考试类型特有字段(questionScore/chooseAnswer/scoringMethod/keyword/analysis)
- 测评类型特有字段(questionScore/optionScore/assessmentResults)
- 三种类型的完整 JSON 示例
- 从 wenjuan_creator_skill 文本格式到 JSON 的映射规则
Agent Skill 技能文件
项目根目录的 skill/ 文件夹包含了供 Agent 安装使用的技能文件,Agent 通过这些文件了解如何安装、使用 wenjuan_cli,以及如何与用户交互。
文件结构
skill/
├── SKILL.md # 技能描述文件(触发条件+角色设定+命令规范+数据脱敏)
├── references/
│ ├── command-reference.md # CLI 命令完整参考
│ └── data-masking-guide.md # 数据脱敏详细指南
└── assets/
└── response-template.md # 标准回复话术模板核心设计
- CLI = 工具,Skill = 说明书:CLI 是 Agent 操作问卷平台的唯一工具,Skill 教会 Agent 如何使用
- 不重复:生成规范由 CLI 内置提供(
wjplus spec),Skill 中不重复定义,避免维护多份规范 - 自动化优先:Agent 自行完成安装、鉴权等操作,不要求用户手动执行命令
- 数据脱敏:Agent 不得将 CLI 返回的原始 JSON 直接暴露给用户,必须经过人友好的格式化处理
- 敏感信息保护:绝不暴露 appId、apiKey、token、内部字段名等技术细节
- 分阶段触发:生成内容 → 用户确认 → 调用创建 → 展示结果
- 标准话术:统一使用
assets/response-template.md中的回复模板
Agent 安装使用
将 skill/ 文件夹安装到 Agent 的技能目录中,Agent 即可自动识别触发条件并执行相应流程。
如果目标平台要求 zip 上传,使用固定脚本打包,确保 SKILL.md 位于 zip 根目录且文件不带 UTF-8 BOM:
npm run pack:skill输出文件为 dist/wjplus-skill.zip。不要直接压缩外层 skill/ 文件夹,否则部分平台会把 SKILL.md 放在二级目录,导致 frontmatter 解析失败。
后端配合要求
CLI 的鉴权和创建功能依赖后端提供以下接口:
鉴权接口
| 接口 | 说明 | 状态 |
| -------------------------- | ---------------- | ----- |
| POST /wj/apiKey/generate | 生成 API Key | ✅ 已完成 |
| POST /wj/apiKey/exchange | API Key 换取 Token | ✅ 已完成 |
| GET /wj/apiKey/list | 查询 API Key 列表 | ✅ 已完成 |
| POST /wj/apiKey/revoke | 撤销 API Key | ✅ 已完成 |
| POST /wj/cli/auth/qrcode | 生成 CLI 授权二维码 | ✅ 已完成 |
| GET /wj/cli/auth/check | 轮询授权状态 | ✅ 已完成 |
| GET /wj/cli/auth/confirm | 小程序端确认授权 | ✅ 已完成 |
创建接口
| 接口 | 说明 | 状态 |
| --------------------------------- | --------------------------------- | ----- |
| POST /wj/questionnaire/cliCreate | CLI 创建问卷/考试/测评(含题目列表,remark="cli") | ✅ 已完成 |
| GET /wj/questionnaire/getUuid | 获取问卷 UUID | ✅ 已完成 |
| GET /wj/questionnaire/questionnaireDetail | 问卷详情(含题目列表) | ✅ 已完成 |
后端
cliCreate接口根据questionnaireType自动区分三种类型:
- type=1(问卷):调用
createQuestion逐题写入- type=2(考试):自动创建登录设置+封面,调用
createKaoshi逐题写入,自动计算总分- type=3(测评):自动设置封面+测评结果标识,调用
createQuestion逐题写入,保存 assessmentResults,自动计算总分
小程序端需新增:
- 问卷加加:API Key 管理页面 + CLI 授权确认页面
- 问卷管家:API Key 管理页面 + CLI 授权确认页面
详见 TODO.md 中 TB.1 - TB.6 任务。
测试数据
| 文件 | 类型 | 覆盖题型 |
|------|------|---------|
| test-survey.json | 问卷(type=1) | 单选/多选/填空/分数评定/问答/判断(6种) |
| test-exam.json | 考试(type=2) | 单选/多选/判断/填空/多项填空/问答/完形填空(7种) |
| test-assessment.json | 测评(type=3) | 测评单选/测评多选/测评权重评分/测评分数评定/测评NPS/文本描述(6种)+ 3档测评结果区间 |
License
MIT
