wjx-cli 0.1.0 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -42
- package/dist/commands/diagnostics.js +31 -16
- package/dist/commands/diagnostics.js.map +1 -1
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +77 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/auth.d.ts +1 -1
- package/dist/lib/auth.js +5 -4
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/config.d.ts +13 -0
- package/dist/lib/config.js +42 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/stdin.js +1 -1
- package/dist/lib/stdin.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://nodejs.org/)
|
|
7
|
+
[](https://www.npmjs.com/package/wjx-cli)
|
|
7
8
|
[](__tests__/cli.test.mjs)
|
|
8
9
|
|
|
9
10
|
wjx-cli 是 [`wjx-ai-kit`](../) monorepo 的命令行入口,将 [wjx-api-sdk](../wjx-api-sdk/) 的 50+ 函数直接暴露为终端命令。设计目标:**让 AI Agent 和人类开发者都能用一行命令操作问卷星 OpenAPI**。
|
|
@@ -13,7 +14,7 @@ wjx-cli 是 [`wjx-ai-kit`](../) monorepo 的命令行入口,将 [wjx-api-sdk](
|
|
|
13
14
|
## 目录
|
|
14
15
|
|
|
15
16
|
- [特性](#特性)
|
|
16
|
-
- [
|
|
17
|
+
- [**快速开始**](#快速开始)
|
|
17
18
|
- [安装](#安装)
|
|
18
19
|
- [认证](#认证)
|
|
19
20
|
- [架构](#架构)
|
|
@@ -48,22 +49,37 @@ wjx-cli 是 [`wjx-ai-kit`](../) monorepo 的命令行入口,将 [wjx-api-sdk](
|
|
|
48
49
|
- **stdin pipe** — `echo '{"vid":123}' | wjx --stdin survey get`,参数通过管道传入
|
|
49
50
|
- **表格输出** — `--table` 切换为人类可读的 `console.table` 格式
|
|
50
51
|
- **56 个子命令** — 覆盖问卷、答卷、通讯录、部门、管理员、标签、用户体系、子账号、SSO、数据分析
|
|
51
|
-
- **9 个本地命令** — SSO URL 生成和 analytics 计算无需 API
|
|
52
|
+
- **9 个本地命令** — SSO URL 生成和 analytics 计算无需 API Key,离线可用
|
|
52
53
|
- **基于 wjx-api-sdk** — 直接调用 SDK 函数,类型安全,行为与 API 一致
|
|
53
54
|
|
|
54
55
|
---
|
|
55
56
|
|
|
57
|
+
## 快速开始
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install -g wjx-cli
|
|
61
|
+
export WJX_API_KEY=你的ApiKey
|
|
62
|
+
wjx survey list
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
> **新手?** 阅读 [快速开始教程](docs/getting-started.md),含 [Node.js 安装指引](docs/install-nodejs.md)。
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
56
69
|
## 前置条件
|
|
57
70
|
|
|
58
|
-
- **Node.js >= 20
|
|
59
|
-
-
|
|
60
|
-
- **问卷星 OpenAPI Token**([申请方式](https://www.wjx.cn/openapi/))
|
|
71
|
+
- **Node.js >= 20**([安装指引](docs/install-nodejs.md))
|
|
72
|
+
- **问卷星 OpenAPI API Key**([申请方式](https://www.wjx.cn/openapi/))
|
|
61
73
|
|
|
62
74
|
---
|
|
63
75
|
|
|
64
76
|
## 安装
|
|
65
77
|
|
|
66
|
-
|
|
78
|
+
```bash
|
|
79
|
+
npm install -g wjx-cli
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 从源码安装(开发者)
|
|
67
83
|
|
|
68
84
|
```bash
|
|
69
85
|
git clone <your-repo-url>
|
|
@@ -71,36 +87,24 @@ cd wjx-ai-kit
|
|
|
71
87
|
npm install
|
|
72
88
|
npm run build --workspace=wjx-api-sdk
|
|
73
89
|
npm run build --workspace=wjx-cli
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### 全局可用(可选)
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
90
|
npm link --workspace=wjx-cli
|
|
80
|
-
wjx --help
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### 直接运行(无需全局安装)
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
node wjx-cli/dist/index.js --help
|
|
87
91
|
```
|
|
88
92
|
|
|
89
93
|
---
|
|
90
94
|
|
|
91
95
|
## 认证
|
|
92
96
|
|
|
93
|
-
大多数命令需要问卷星 API
|
|
97
|
+
大多数命令需要问卷星 API Key(SSO 和 analytics 命令除外)。
|
|
94
98
|
|
|
95
99
|
```bash
|
|
96
100
|
# 方式 1:环境变量(推荐)
|
|
97
|
-
export
|
|
101
|
+
export WJX_API_KEY=your_api_key
|
|
98
102
|
|
|
99
103
|
# 方式 2:命令行参数
|
|
100
|
-
wjx --
|
|
104
|
+
wjx --api-key your_api_key survey list
|
|
101
105
|
|
|
102
106
|
# 方式 3:.env 文件(SDK 自动读取)
|
|
103
|
-
echo "
|
|
107
|
+
echo "WJX_API_KEY=your_api_key" >> .env
|
|
104
108
|
```
|
|
105
109
|
|
|
106
110
|
---
|
|
@@ -123,12 +127,12 @@ wjx-ai-kit/ # monorepo root
|
|
|
123
127
|
│ │ ├── tag.ts # 4 subcommands
|
|
124
128
|
│ │ ├── user-system.ts # 6 subcommands
|
|
125
129
|
│ │ ├── account.ts # 5 subcommands
|
|
126
|
-
│ │ ├── sso.ts # 3 subcommands(无需
|
|
127
|
-
│ │ ├── analytics.ts # 6 subcommands(本地计算,无需
|
|
130
|
+
│ │ ├── sso.ts # 3 subcommands(无需 API Key)
|
|
131
|
+
│ │ ├── analytics.ts # 6 subcommands(本地计算,无需 API Key)
|
|
128
132
|
│ │ └── diagnostics.ts # 2 subcommands(whoami + doctor)
|
|
129
133
|
│ └── lib/
|
|
130
134
|
│ ├── command-helpers.ts # executeCommand + strictInt + requireField
|
|
131
|
-
│ ├── auth.ts #
|
|
135
|
+
│ ├── auth.ts # API Key 获取(env > --api-key)
|
|
132
136
|
│ ├── output.ts # JSON / table 格式化
|
|
133
137
|
│ ├── errors.ts # CliError + exit code 路由
|
|
134
138
|
│ └── stdin.ts # stdin JSON 读取 + source-aware merge
|
|
@@ -144,7 +148,7 @@ wjx-ai-kit/ # monorepo root
|
|
|
144
148
|
|
|
145
149
|
| 选项 | 说明 |
|
|
146
150
|
|------|------|
|
|
147
|
-
| `--
|
|
151
|
+
| `--api-key <apiKey>` | WJX API Key(或设置 `WJX_API_KEY` 环境变量) |
|
|
148
152
|
| `--json` | JSON 输出(默认) |
|
|
149
153
|
| `--table` | 表格输出(`console.table` 格式) |
|
|
150
154
|
| `--verbose` | 详细输出 |
|
|
@@ -466,7 +470,7 @@ wjx account restore --subuser test1
|
|
|
466
470
|
|
|
467
471
|
### sso — 单点登录
|
|
468
472
|
|
|
469
|
-
> **无需
|
|
473
|
+
> **无需 API Key** — SSO 命令在本地生成 URL,不调用 API。
|
|
470
474
|
|
|
471
475
|
```bash
|
|
472
476
|
wjx sso subaccount-url --subuser test1 # 子账号 SSO 链接
|
|
@@ -503,7 +507,7 @@ wjx sso partner-url --username partner1 # 代理商 SSO 链接
|
|
|
503
507
|
|
|
504
508
|
### analytics — 数据分析
|
|
505
509
|
|
|
506
|
-
> **无需
|
|
510
|
+
> **无需 API Key** — analytics 命令在本地执行计算,不调用 API。
|
|
507
511
|
|
|
508
512
|
```bash
|
|
509
513
|
wjx analytics decode --submitdata "1$2}2$hello" # 解码答卷提交数据
|
|
@@ -532,8 +536,8 @@ wjx analytics decode-push --payload "..." --app_key "key"
|
|
|
532
536
|
### 诊断工具
|
|
533
537
|
|
|
534
538
|
```bash
|
|
535
|
-
wjx whoami # 验证
|
|
536
|
-
wjx doctor # 环境诊断(Node 版本、
|
|
539
|
+
wjx whoami # 验证 API Key 并显示账号信息(调用 listSurveys 检测)
|
|
540
|
+
wjx doctor # 环境诊断(Node 版本、API Key、API 连接、SDK 版本)
|
|
537
541
|
```
|
|
538
542
|
|
|
539
543
|
---
|
|
@@ -626,15 +630,15 @@ wjx-cli 使用结构化 JSON 错误输出,方便 AI Agent 和自动化脚本
|
|
|
626
630
|
|:------:|--------|------|----------|
|
|
627
631
|
| **0** | — | 成功 | 命令正常完成 |
|
|
628
632
|
| **1** | `API_ERROR` | API 错误 | 网络错误、API 返回失败 |
|
|
629
|
-
| **1** | `AUTH_ERROR` | 认证错误 |
|
|
633
|
+
| **1** | `AUTH_ERROR` | 认证错误 | API Key 缺失或无效 |
|
|
630
634
|
| **2** | `INPUT_ERROR` | 输入错误 | 缺少必填参数、无效整数、JSON 解析失败 |
|
|
631
635
|
|
|
632
636
|
### 示例
|
|
633
637
|
|
|
634
638
|
```bash
|
|
635
|
-
# 缺少
|
|
639
|
+
# 缺少 API Key → exit 1, AUTH_ERROR
|
|
636
640
|
$ wjx survey list 2>&1 >/dev/null
|
|
637
|
-
{"error":true,"message":"
|
|
641
|
+
{"error":true,"message":"WJX_API_KEY 未设置。请通过 --api-key 参数或 WJX_API_KEY 环境变量提供。","code":"AUTH_ERROR","exitCode":1}
|
|
638
642
|
|
|
639
643
|
# 缺少必填参数 → exit 2, INPUT_ERROR
|
|
640
644
|
$ wjx survey get 2>&1 >/dev/null
|
|
@@ -660,7 +664,7 @@ elif result.returncode == 2:
|
|
|
660
664
|
err = json.loads(result.stderr)
|
|
661
665
|
print(f"Bad input: {err['message']}")
|
|
662
666
|
elif result.returncode == 1:
|
|
663
|
-
# API/认证错误 — 检查
|
|
667
|
+
# API/认证错误 — 检查 API Key 或稍后重试
|
|
664
668
|
err = json.loads(result.stderr)
|
|
665
669
|
print(f"API error: {err['message']}")
|
|
666
670
|
```
|
|
@@ -730,10 +734,11 @@ echo '{"title":"调查","type":0,"questions":"[]"}' | wjx --stdin survey create
|
|
|
730
734
|
|
|
731
735
|
| 变量 | 必填 | 说明 | 默认值 |
|
|
732
736
|
|------|:----:|------|--------|
|
|
733
|
-
| `
|
|
737
|
+
| `WJX_API_KEY` | 是* | 问卷星 OpenAPI API Key | — |
|
|
738
|
+
| `WJX_CORP_ID` | 否 | 企业通讯录 ID(通讯录相关操作需要) | — |
|
|
734
739
|
| `WJX_BASE_URL` | 否 | 自定义 API 基础域名 | `https://www.wjx.cn` |
|
|
735
740
|
|
|
736
|
-
\* SSO 和 analytics 命令不需要
|
|
741
|
+
\* SSO 和 analytics 命令不需要 API Key。
|
|
737
742
|
|
|
738
743
|
---
|
|
739
744
|
|
|
@@ -749,7 +754,7 @@ npm run clean # 清理 dist/
|
|
|
749
754
|
# 手动测试
|
|
750
755
|
node dist/index.js --help
|
|
751
756
|
node dist/index.js survey url --mode create
|
|
752
|
-
|
|
757
|
+
WJX_API_KEY=xxx node dist/index.js survey list
|
|
753
758
|
```
|
|
754
759
|
|
|
755
760
|
### 项目结构
|
|
@@ -761,7 +766,7 @@ src/
|
|
|
761
766
|
│ └── *.ts # 每个文件导出 register*Commands(program)
|
|
762
767
|
└── lib/
|
|
763
768
|
├── command-helpers.ts # executeCommand / strictInt / requireField
|
|
764
|
-
├── auth.ts #
|
|
769
|
+
├── auth.ts # API Key 获取
|
|
765
770
|
├── output.ts # JSON / table 输出
|
|
766
771
|
├── errors.ts # CliError + 退出码路由
|
|
767
772
|
└── stdin.ts # stdin 读取 + source-aware merge
|
|
@@ -779,14 +784,14 @@ src/
|
|
|
779
784
|
|
|
780
785
|
## 常见问题
|
|
781
786
|
|
|
782
|
-
### `AUTH_ERROR:
|
|
787
|
+
### `AUTH_ERROR: WJX_API_KEY 未设置`
|
|
783
788
|
|
|
784
|
-
确保设置了
|
|
789
|
+
确保设置了 API Key:
|
|
785
790
|
|
|
786
791
|
```bash
|
|
787
|
-
export
|
|
792
|
+
export WJX_API_KEY=your_api_key
|
|
788
793
|
# 或
|
|
789
|
-
wjx --
|
|
794
|
+
wjx --api-key your_api_key survey list
|
|
790
795
|
```
|
|
791
796
|
|
|
792
797
|
### `INPUT_ERROR: Invalid integer: "abc"`
|
|
@@ -2,18 +2,19 @@ import { listSurveys } from "wjx-api-sdk";
|
|
|
2
2
|
import { getCredentials } from "../lib/auth.js";
|
|
3
3
|
import { formatOutput } from "../lib/output.js";
|
|
4
4
|
import { handleError } from "../lib/errors.js";
|
|
5
|
+
import { loadConfig, CONFIG_PATH } from "../lib/config.js";
|
|
5
6
|
export function registerDiagnosticCommands(program) {
|
|
6
7
|
// --- whoami ---
|
|
7
8
|
program
|
|
8
9
|
.command("whoami")
|
|
9
|
-
.description("验证
|
|
10
|
+
.description("验证 ApiKey 并显示账号信息")
|
|
10
11
|
.action(async () => {
|
|
11
12
|
try {
|
|
12
13
|
const creds = getCredentials(program.opts());
|
|
13
14
|
const result = await listSurveys({ page_index: 1, page_size: 1 }, creds);
|
|
14
15
|
if (result.result === false) {
|
|
15
16
|
// Token invalid or API error
|
|
16
|
-
formatOutput({ authenticated: false, error: result.errormsg || "
|
|
17
|
+
formatOutput({ authenticated: false, error: result.errormsg || "ApiKey 无效" }, program.opts());
|
|
17
18
|
process.exit(1);
|
|
18
19
|
}
|
|
19
20
|
// Extract useful info from the response
|
|
@@ -30,10 +31,17 @@ export function registerDiagnosticCommands(program) {
|
|
|
30
31
|
// --- doctor ---
|
|
31
32
|
program
|
|
32
33
|
.command("doctor")
|
|
33
|
-
.description("环境诊断(
|
|
34
|
+
.description("环境诊断(ApiKey、网络、SDK 版本)")
|
|
34
35
|
.action(async () => {
|
|
35
36
|
try {
|
|
36
37
|
const checks = [];
|
|
38
|
+
// 0. Config file
|
|
39
|
+
const config = loadConfig();
|
|
40
|
+
checks.push({
|
|
41
|
+
check: "配置文件",
|
|
42
|
+
status: config ? "ok" : "info",
|
|
43
|
+
detail: config ? CONFIG_PATH : `未找到 (运行 wjx init 创建)`,
|
|
44
|
+
});
|
|
37
45
|
// 1. Node version
|
|
38
46
|
const nodeVersion = process.version;
|
|
39
47
|
const major = parseInt(nodeVersion.slice(1), 10);
|
|
@@ -42,24 +50,31 @@ export function registerDiagnosticCommands(program) {
|
|
|
42
50
|
status: major >= 20 ? "ok" : "warn",
|
|
43
51
|
detail: `${nodeVersion}${major < 20 ? " (建议 >= 20)" : ""}`,
|
|
44
52
|
});
|
|
45
|
-
// 2.
|
|
46
|
-
const
|
|
53
|
+
// 2. WJX_API_KEY set?
|
|
54
|
+
const apiKey = program.opts().apiKey || process.env.WJX_API_KEY || config?.apiKey;
|
|
55
|
+
checks.push({
|
|
56
|
+
check: "WJX_API_KEY",
|
|
57
|
+
status: apiKey ? "ok" : "fail",
|
|
58
|
+
detail: apiKey ? `已设置 (${apiKey.slice(0, 8)}...)` : "未设置",
|
|
59
|
+
});
|
|
60
|
+
// 3. WJX_CORP_ID
|
|
61
|
+
const corpId = process.env.WJX_CORP_ID || config?.corpId;
|
|
47
62
|
checks.push({
|
|
48
|
-
check: "
|
|
49
|
-
status:
|
|
50
|
-
detail:
|
|
63
|
+
check: "WJX_CORP_ID",
|
|
64
|
+
status: corpId ? "ok" : "info",
|
|
65
|
+
detail: corpId ? `已设置 (${corpId})` : "未设置(通讯录功能需要)",
|
|
51
66
|
});
|
|
52
|
-
//
|
|
53
|
-
const baseUrl = process.env.WJX_BASE_URL || "https://www.wjx.cn";
|
|
67
|
+
// 4. WJX_BASE_URL
|
|
68
|
+
const baseUrl = process.env.WJX_BASE_URL || config?.baseUrl || "https://www.wjx.cn";
|
|
54
69
|
checks.push({
|
|
55
70
|
check: "WJX_BASE_URL",
|
|
56
71
|
status: "ok",
|
|
57
72
|
detail: baseUrl,
|
|
58
73
|
});
|
|
59
|
-
//
|
|
60
|
-
if (
|
|
74
|
+
// 5. API connectivity
|
|
75
|
+
if (apiKey) {
|
|
61
76
|
try {
|
|
62
|
-
const creds = {
|
|
77
|
+
const creds = { apiKey };
|
|
63
78
|
const result = await listSurveys({ page_index: 1, page_size: 1 }, creds);
|
|
64
79
|
if (result.result === false) {
|
|
65
80
|
checks.push({
|
|
@@ -88,16 +103,16 @@ export function registerDiagnosticCommands(program) {
|
|
|
88
103
|
checks.push({
|
|
89
104
|
check: "API 连接",
|
|
90
105
|
status: "skip",
|
|
91
|
-
detail: "
|
|
106
|
+
detail: "ApiKey 未设置,跳过",
|
|
92
107
|
});
|
|
93
108
|
}
|
|
94
|
-
//
|
|
109
|
+
// 6. SDK version
|
|
95
110
|
checks.push({
|
|
96
111
|
check: "wjx-api-sdk",
|
|
97
112
|
status: "ok",
|
|
98
113
|
detail: "v1.0.0",
|
|
99
114
|
});
|
|
100
|
-
const allOk = checks.every((c) => c.status === "ok" || c.status === "skip");
|
|
115
|
+
const allOk = checks.every((c) => c.status === "ok" || c.status === "skip" || c.status === "info");
|
|
101
116
|
formatOutput({ ok: allOk, checks }, program.opts());
|
|
102
117
|
if (!allOk)
|
|
103
118
|
process.exit(1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/commands/diagnostics.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/commands/diagnostics.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE3D,MAAM,UAAU,0BAA0B,CAAC,OAAgB;IACzD,iBAAiB;IACjB,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,mBAAmB,CAAC;SAChC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,EAC/B,KAAK,CACN,CAAC;YAEF,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;gBAC5B,6BAA6B;gBAC7B,YAAY,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,IAAI,WAAW,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC9F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,wCAAwC;YACxC,MAAM,IAAI,GAAG,MAA4C,CAAC;YAC1D,YAAY,CAAC;gBACX,aAAa,EAAE,IAAI;gBACnB,aAAa,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI;aAChD,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,WAAW,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,iBAAiB;IACjB,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,wBAAwB,CAAC;SACrC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,MAAM,GAA6D,EAAE,CAAC;YAE5E,iBAAiB;YACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;gBAC9B,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,sBAAsB;aACtD,CAAC,CAAC;YAEH,kBAAkB;YAClB,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;YACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjD,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;gBACnC,MAAM,EAAE,GAAG,WAAW,GAAG,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE;aAC3D,CAAC,CAAC;YAEH,sBAAsB;YACtB,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,MAAM,EAAE,MAAM,CAAC;YAClF,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,aAAa;gBACpB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;gBAC9B,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;aAC1D,CAAC,CAAC;YAEH,iBAAiB;YACjB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,MAAM,EAAE,MAAM,CAAC;YACzD,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,aAAa;gBACpB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;gBAC9B,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,MAAM,GAAG,CAAC,CAAC,CAAC,cAAc;aACpD,CAAC,CAAC;YAEH,kBAAkB;YAClB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM,EAAE,OAAO,IAAI,oBAAoB,CAAC;YACpF,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,cAAc;gBACrB,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,OAAO;aAChB,CAAC,CAAC;YAEH,sBAAsB;YACtB,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,EAAE,MAAM,EAAE,CAAC;oBACzB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;oBACzE,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;wBAC5B,MAAM,CAAC,IAAI,CAAC;4BACV,KAAK,EAAE,QAAQ;4BACf,MAAM,EAAE,MAAM;4BACd,MAAM,EAAE,MAAM,CAAC,QAAQ,IAAI,UAAU;yBACtC,CAAC,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,IAAI,CAAC;4BACV,KAAK,EAAE,QAAQ;4BACf,MAAM,EAAE,IAAI;4BACZ,MAAM,EAAE,IAAI;yBACb,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,IAAI,CAAC;wBACV,KAAK,EAAE,QAAQ;wBACf,MAAM,EAAE,MAAM;wBACd,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;qBACzD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC;oBACV,KAAK,EAAE,QAAQ;oBACf,MAAM,EAAE,MAAM;oBACd,MAAM,EAAE,eAAe;iBACxB,CAAC,CAAC;YACL,CAAC;YAED,iBAAiB;YACjB,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,aAAa;gBACpB,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,QAAQ;aACjB,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;YACnG,YAAY,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAEpD,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,WAAW,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { createInterface } from "node:readline/promises";
|
|
2
|
+
import { stdin, stderr } from "node:process";
|
|
3
|
+
import { listSurveys } from "wjx-api-sdk";
|
|
4
|
+
import { loadConfig, saveConfig, CONFIG_PATH } from "../lib/config.js";
|
|
5
|
+
export function registerInitCommands(program) {
|
|
6
|
+
program
|
|
7
|
+
.command("init")
|
|
8
|
+
.description("初始化配置(交互式设置 API Key、Base URL、Corp ID)")
|
|
9
|
+
.action(async () => {
|
|
10
|
+
const rl = createInterface({ input: stdin, output: stderr });
|
|
11
|
+
try {
|
|
12
|
+
// Check existing config
|
|
13
|
+
const existing = loadConfig();
|
|
14
|
+
if (existing) {
|
|
15
|
+
const masked = existing.apiKey.length > 8
|
|
16
|
+
? existing.apiKey.slice(0, 8) + "..."
|
|
17
|
+
: "***";
|
|
18
|
+
stderr.write(`已存在配置文件: ${CONFIG_PATH}\n`);
|
|
19
|
+
stderr.write(` apiKey: ${masked}\n`);
|
|
20
|
+
if (existing.baseUrl)
|
|
21
|
+
stderr.write(` baseUrl: ${existing.baseUrl}\n`);
|
|
22
|
+
if (existing.corpId)
|
|
23
|
+
stderr.write(` corpId: ${existing.corpId}\n`);
|
|
24
|
+
const overwrite = await rl.question("\n覆盖现有配置?(y/N) ");
|
|
25
|
+
if (overwrite.trim().toLowerCase() !== "y") {
|
|
26
|
+
stderr.write("已取消。\n");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
stderr.write("\n");
|
|
30
|
+
}
|
|
31
|
+
// Prompt API Key (required)
|
|
32
|
+
let apiKey = "";
|
|
33
|
+
while (!apiKey) {
|
|
34
|
+
const input = await rl.question("WJX_API_KEY (必填): ");
|
|
35
|
+
apiKey = input.trim();
|
|
36
|
+
if (!apiKey) {
|
|
37
|
+
stderr.write("API Key 不能为空。\n");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Prompt Base URL (optional)
|
|
41
|
+
const baseUrlInput = await rl.question("WJX_BASE_URL (可选, 默认 https://www.wjx.cn): ");
|
|
42
|
+
const baseUrl = baseUrlInput.trim() || undefined;
|
|
43
|
+
// Prompt Corp ID (optional)
|
|
44
|
+
const corpIdInput = await rl.question("WJX_CORP_ID (可选, 通讯录功能需要): ");
|
|
45
|
+
const corpId = corpIdInput.trim() || undefined;
|
|
46
|
+
// Validate API Key
|
|
47
|
+
stderr.write("\n正在验证 API Key...\n");
|
|
48
|
+
try {
|
|
49
|
+
const result = await listSurveys({ page_index: 1, page_size: 1 }, { apiKey });
|
|
50
|
+
if (result.result === false) {
|
|
51
|
+
stderr.write(`! API Key 验证失败: ${result.errormsg}\n`);
|
|
52
|
+
stderr.write(" 配置仍将保存,请检查 Key 是否正确。\n");
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
stderr.write("OK API Key 验证成功。\n");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
stderr.write(`! 无法连接 API: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
60
|
+
stderr.write(" 配置仍将保存。\n");
|
|
61
|
+
}
|
|
62
|
+
// Save config
|
|
63
|
+
const config = { apiKey };
|
|
64
|
+
if (baseUrl)
|
|
65
|
+
config.baseUrl = baseUrl;
|
|
66
|
+
if (corpId)
|
|
67
|
+
config.corpId = corpId;
|
|
68
|
+
saveConfig(config);
|
|
69
|
+
stderr.write(`\nOK 配置已保存到 ${CONFIG_PATH}\n`);
|
|
70
|
+
stderr.write("提示: 你也可以直接编辑该文件来修改配置。\n");
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
rl.close();
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -11,14 +11,18 @@ import { registerUserSystemCommands } from "./commands/user-system.js";
|
|
|
11
11
|
import { registerAccountCommands } from "./commands/account.js";
|
|
12
12
|
import { registerSsoCommands } from "./commands/sso.js";
|
|
13
13
|
import { registerAnalyticsCommands } from "./commands/analytics.js";
|
|
14
|
+
import { registerInitCommands } from "./commands/init.js";
|
|
14
15
|
import { readStdin } from "./lib/stdin.js";
|
|
15
16
|
import { handleError } from "./lib/errors.js";
|
|
17
|
+
import { applyConfigToEnv } from "./lib/config.js";
|
|
18
|
+
// Load ~/.wjxrc config into process.env (env vars take precedence)
|
|
19
|
+
applyConfigToEnv();
|
|
16
20
|
const program = new Command();
|
|
17
21
|
program
|
|
18
22
|
.name("wjx")
|
|
19
23
|
.description("问卷星 (Wenjuanxing) CLI — AI Agent 原生命令行工具")
|
|
20
24
|
.version("0.1.0")
|
|
21
|
-
.option("--
|
|
25
|
+
.option("--api-key <apiKey>", "WJX API Key(或设置 WJX_API_KEY 环境变量)")
|
|
22
26
|
.option("--json", "JSON 输出(默认)")
|
|
23
27
|
.option("--table", "表格输出")
|
|
24
28
|
.option("--verbose", "详细输出")
|
|
@@ -47,6 +51,7 @@ registerUserSystemCommands(program);
|
|
|
47
51
|
registerAccountCommands(program);
|
|
48
52
|
registerSsoCommands(program);
|
|
49
53
|
registerAnalyticsCommands(program);
|
|
54
|
+
registerInitCommands(program);
|
|
50
55
|
(async () => {
|
|
51
56
|
try {
|
|
52
57
|
await program.parseAsync();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,SAAS,EAAsB,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/auth.d.ts
CHANGED
package/dist/lib/auth.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { CliError } from "./errors.js";
|
|
2
|
+
import { loadConfig } from "./config.js";
|
|
2
3
|
export function getCredentials(globalOpts) {
|
|
3
|
-
const
|
|
4
|
-
if (!
|
|
5
|
-
throw new CliError("AUTH_ERROR", "
|
|
4
|
+
const apiKey = globalOpts.apiKey || process.env.WJX_API_KEY || loadConfig()?.apiKey;
|
|
5
|
+
if (!apiKey) {
|
|
6
|
+
throw new CliError("AUTH_ERROR", "WJX_API_KEY 未设置。请通过 --api-key 参数、WJX_API_KEY 环境变量、或运行 wjx init 配置。");
|
|
6
7
|
}
|
|
7
|
-
return {
|
|
8
|
+
return { apiKey };
|
|
8
9
|
}
|
|
9
10
|
//# sourceMappingURL=auth.js.map
|
package/dist/lib/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,cAAc,CAAC,UAA+B;IAC5D,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,UAAU,EAAE,EAAE,MAAM,CAAC;IACpF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAChB,YAAY,EACZ,oEAAoE,CACrE,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface WjxConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
corpId?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const CONFIG_PATH: string;
|
|
7
|
+
export declare function loadConfig(): WjxConfig | null;
|
|
8
|
+
export declare function saveConfig(config: WjxConfig): void;
|
|
9
|
+
/**
|
|
10
|
+
* Apply config values to process.env where env vars are not already set.
|
|
11
|
+
* This makes SDK layer (which reads process.env) automatically use config values.
|
|
12
|
+
*/
|
|
13
|
+
export declare function applyConfigToEnv(): void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
export const CONFIG_PATH = process.env.WJX_CONFIG_PATH || join(homedir(), ".wjxrc");
|
|
5
|
+
export function loadConfig() {
|
|
6
|
+
try {
|
|
7
|
+
const raw = readFileSync(CONFIG_PATH, "utf8");
|
|
8
|
+
const parsed = JSON.parse(raw);
|
|
9
|
+
if (typeof parsed === "object" && parsed !== null && typeof parsed.apiKey === "string") {
|
|
10
|
+
return parsed;
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function saveConfig(config) {
|
|
19
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", {
|
|
20
|
+
encoding: "utf8",
|
|
21
|
+
mode: 0o600,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Apply config values to process.env where env vars are not already set.
|
|
26
|
+
* This makes SDK layer (which reads process.env) automatically use config values.
|
|
27
|
+
*/
|
|
28
|
+
export function applyConfigToEnv() {
|
|
29
|
+
const config = loadConfig();
|
|
30
|
+
if (!config)
|
|
31
|
+
return;
|
|
32
|
+
if (!process.env.WJX_API_KEY && config.apiKey) {
|
|
33
|
+
process.env.WJX_API_KEY = config.apiKey;
|
|
34
|
+
}
|
|
35
|
+
if (!process.env.WJX_BASE_URL && config.baseUrl) {
|
|
36
|
+
process.env.WJX_BASE_URL = config.baseUrl;
|
|
37
|
+
}
|
|
38
|
+
if (!process.env.WJX_CORP_ID && config.corpId) {
|
|
39
|
+
process.env.WJX_CORP_ID = config.corpId;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAQlC,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AAEpF,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACvF,OAAO,MAAmB,CAAC;QAC7B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE;QACjE,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC;IAC5C,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,CAAC;AACH,CAAC"}
|
package/dist/lib/stdin.js
CHANGED
|
@@ -37,7 +37,7 @@ export function mergeStdinWithOpts(stdinData, command) {
|
|
|
37
37
|
const merged = { ...stdinData };
|
|
38
38
|
for (const key of Object.keys(opts)) {
|
|
39
39
|
// Skip internal flags
|
|
40
|
-
if (key === "stdin" || key === "
|
|
40
|
+
if (key === "stdin" || key === "apiKey" || key === "json" || key === "table" || key === "verbose") {
|
|
41
41
|
continue;
|
|
42
42
|
}
|
|
43
43
|
const source = command.getOptionValueSource(key);
|
package/dist/lib/stdin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdin.js","sourceRoot":"","sources":["../../src/lib/stdin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,4CAA4C;IAC5C,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;IAC/B,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAE1D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,QAAQ,CAAC,aAAa,EAAE,oCAAoC,GAAG,OAAO,MAAM,CAAC,CAAC;QAC1F,CAAC;QACD,OAAO,MAAiC,CAAC;IAC3C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,QAAQ;YAAE,MAAM,CAAC,CAAC;QACnC,MAAM,IAAI,QAAQ,CAChB,aAAa,EACb,2BAA2B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACxE,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,SAAkC,EAClC,OAAgB;IAEhB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,MAAM,GAA4B,EAAE,GAAG,SAAS,EAAE,CAAC;IAEzD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,sBAAsB;QACtB,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,
|
|
1
|
+
{"version":3,"file":"stdin.js","sourceRoot":"","sources":["../../src/lib/stdin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,4CAA4C;IAC5C,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;IAC/B,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAE1D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,QAAQ,CAAC,aAAa,EAAE,oCAAoC,GAAG,OAAO,MAAM,CAAC,CAAC;QAC1F,CAAC;QACD,OAAO,MAAiC,CAAC;IAC3C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,QAAQ;YAAE,MAAM,CAAC,CAAC;QACnC,MAAM,IAAI,QAAQ,CAChB,aAAa,EACb,2BAA2B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACxE,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,SAAkC,EAClC,OAAgB;IAEhB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,MAAM,GAA4B,EAAE,GAAG,SAAS,EAAE,CAAC;IAEzD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,sBAAsB;QACtB,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAClG,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACjD,wEAAwE;QACxE,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wjx-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "问卷星 (Wenjuanxing) CLI — AI Agent 原生命令行工具",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"commander": "^14.0.3",
|
|
37
|
-
"wjx-api-sdk": "
|
|
37
|
+
"wjx-api-sdk": "*"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^25.5.0",
|