bailian-cli 0.1.2-beta.0 → 1.0.0-beta.0

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/package.json CHANGED
@@ -1,46 +1,52 @@
1
1
  {
2
2
  "name": "bailian-cli",
3
- "version": "0.1.2-beta.0",
4
- "description": "CLI for Alibaba Cloud Bailian (DashScope) AI Platform",
5
- "author": "ali-pizza",
3
+ "version": "1.0.0-beta.0",
4
+ "description": "CLI for Aliyun Model Studio (DashScope) AI Platform.",
5
+ "homepage": "https://bailian.console.aliyun.com/cli",
6
6
  "license": "Apache-2.0",
7
- "type": "module",
8
- "engines": {
9
- "node": ">=18"
10
- },
7
+ "author": "Aliyun Model Studio",
11
8
  "bin": {
9
+ "bailian": "dist/bailian.mjs",
12
10
  "bl": "dist/bailian.mjs"
13
11
  },
14
12
  "files": [
15
- "dist/bailian.mjs",
16
- "skill/SKILL.md",
17
- "skill/BAILIAN_API_DOC_REFER.md",
13
+ "dist",
14
+ "skill",
18
15
  "scripts/postinstall.js",
19
16
  "scripts/preuninstall.js"
20
17
  ],
21
- "scripts": {
22
- "dev": "bun run src/main.ts",
23
- "build": "bun run build.ts",
24
- "build:dev": "bun build src/main.ts --outfile dist/bailian.mjs --target node --define \"process.env.CLI_VERSION='$(node -p \"require('./package.json').version\")'\" && printf '#!/usr/bin/env node\\n' | cat - dist/bailian.mjs > dist/tmp && mv dist/tmp dist/bailian.mjs && chmod +x dist/bailian.mjs",
25
- "postinstall": "node scripts/postinstall.js",
26
- "preuninstall": "node scripts/preuninstall.js",
27
- "prepublishOnly": "bun run build",
28
- "lint": "eslint src/ test/",
29
- "typecheck": "tsc --noEmit",
30
- "test": "bun test",
31
- "test:watch": "bun test --watch"
18
+ "type": "module",
19
+ "exports": {
20
+ ".": "./dist/bailian.mjs",
21
+ "./package.json": "./package.json"
22
+ },
23
+ "publishConfig": {
24
+ "registry": "https://registry.npmjs.org/"
32
25
  },
33
26
  "dependencies": {
34
- "@clack/prompts": "^0.7.0"
27
+ "bailian-cli-core": "1.0.0-beta.0"
35
28
  },
36
29
  "devDependencies": {
37
- "@eslint/js": "^9.0.0",
38
- "@types/bun": "latest",
39
- "eslint": "^9.24.0",
40
- "typescript": "^5.8.3",
41
- "typescript-eslint": "^8.58.0"
30
+ "@types/node": "^24",
31
+ "@typescript/native-preview": "7.0.0-dev.20260328.1",
32
+ "typescript": "^6.0.2",
33
+ "vite-plus": "latest"
42
34
  },
43
- "publishConfig": {
44
- "registry": "https://registry.npmjs.org/"
35
+ "engines": {
36
+ "node": ">=22.12.0"
37
+ },
38
+ "inlinedDependencies": {
39
+ "@clack/core": "0.3.5",
40
+ "@clack/prompts": "0.7.0",
41
+ "picocolors": "1.1.1",
42
+ "sisteransi": "1.0.5"
43
+ },
44
+ "scripts": {
45
+ "build": "vp pack",
46
+ "dev": "node src/main.ts",
47
+ "test": "vp test",
48
+ "check": "vp check",
49
+ "postinstall": "node scripts/postinstall.js",
50
+ "preuninstall": "node scripts/preuninstall.js"
45
51
  }
46
- }
52
+ }
@@ -18,15 +18,23 @@
18
18
  * Only installs when the tool's root directory already exists.
19
19
  */
20
20
 
21
- import { existsSync, mkdirSync, copyFileSync, openSync, writeSync, closeSync, readFileSync } from 'fs';
22
- import { join, dirname } from 'path';
23
- import { homedir } from 'os';
24
- import { fileURLToPath } from 'url';
25
- import { execSync } from 'child_process';
21
+ import {
22
+ existsSync,
23
+ mkdirSync,
24
+ copyFileSync,
25
+ openSync,
26
+ writeSync,
27
+ closeSync,
28
+ readFileSync,
29
+ } from "fs";
30
+ import { join, dirname } from "path";
31
+ import { homedir } from "os";
32
+ import { fileURLToPath } from "url";
33
+ import { execSync } from "child_process";
26
34
 
27
35
  const __dirname = dirname(fileURLToPath(import.meta.url));
28
- const skillSource = join(__dirname, '..', 'skill', 'SKILL.md');
29
- const apiSkillSource = join(__dirname, '..', 'skill', 'BAILIAN_API_DOC_REFER.md');
36
+ const skillSource = join(__dirname, "..", "skill", "SKILL.md");
37
+ const apiSkillSource = join(__dirname, "..", "skill", "BAILIAN_API_DOC_REFER.md");
30
38
 
31
39
  if (!existsSync(skillSource)) {
32
40
  process.exit(0);
@@ -37,25 +45,25 @@ const home = homedir();
37
45
  // Targets: each entry is { root: absolute path to tool's root dir, label: display name }
38
46
  // Pattern 1: ~/.xxx/skills/bailian-cli/SKILL.md (most tools)
39
47
  const dotDirTargets = [
40
- '.qoder',
41
- '.claude',
42
- '.cline',
43
- '.qwen',
44
- '.cursor',
45
- '.windsurf',
46
- '.trae',
47
- '.qoderwork',
48
- '.kiro',
48
+ ".qoder",
49
+ ".claude",
50
+ ".cline",
51
+ ".qwen",
52
+ ".cursor",
53
+ ".windsurf",
54
+ ".trae",
55
+ ".qoderwork",
56
+ ".kiro",
49
57
  ];
50
58
 
51
59
  // Pattern 2: Non-standard paths
52
60
  const customTargets = [
53
- { root: join(home, 'Library', 'Application Support', 'iDingTalk', 'wukong'), label: 'Wukong' },
61
+ { root: join(home, "Library", "Application Support", "iDingTalk", "wukong"), label: "Wukong" },
54
62
  ];
55
63
 
56
64
  // Build unified target list
57
65
  const targets = [
58
- ...dotDirTargets.map(d => ({ root: join(home, d), label: d })),
66
+ ...dotDirTargets.map((d) => ({ root: join(home, d), label: d })),
59
67
  ...customTargets,
60
68
  ];
61
69
 
@@ -69,7 +77,7 @@ if (available.length === 0) {
69
77
  // Write directly to /dev/tty to bypass npm output suppression
70
78
  let ttyFd;
71
79
  try {
72
- ttyFd = openSync('/dev/tty', 'w');
80
+ ttyFd = openSync("/dev/tty", "w");
73
81
  } catch {
74
82
  // No TTY (CI, etc.) — skip display, still install silently
75
83
  ttyFd = null;
@@ -77,31 +85,31 @@ try {
77
85
 
78
86
  function ttyPrint(msg) {
79
87
  if (ttyFd != null) {
80
- writeSync(ttyFd, msg + '\n');
88
+ writeSync(ttyFd, msg + "\n");
81
89
  }
82
90
  }
83
91
 
84
92
  // Show capabilities
85
93
  const capabilities = [
86
- ['Text Chat', 'Chat with Qwen LLMs', 'qwen3.6-plus'],
87
- ['Omni Chat', 'Multimodal chat (text+audio+image)', 'qwen3.5-omni-plus'],
88
- ['Image Generate', 'AI image generation', 'qwen-image-2.0'],
89
- ['Image Edit', 'AI image editing & multi-image merge', 'qwen-image-2.0'],
90
- ['Video Generate', 'AI video generation', 'happyhorse-1.0-t2v'],
91
- ['Video Edit', 'AI video editing', 'happyhorse-1.0-video-edit'],
92
- ['Vision', 'Image understanding & description', 'qwen-vl-max'],
93
- ['Speech Synthesize', 'Text-to-speech (TTS)', 'cosyvoice-v3-flash'],
94
- ['Speech Recognize', 'Speech-to-text (ASR)', 'fun-asr'],
95
- ['File Upload', 'Upload files to temp OSS storage', ''],
96
- ['App Call', 'Call Bailian agent / workflow apps', ''],
97
- ['Memory', 'Long-term memory management', ''],
98
- ['Knowledge', 'RAG knowledge base retrieval', ''],
99
- ['Web Search', 'Real-time web search powered by AI', ''],
94
+ ["Text Chat", "Chat with Qwen LLMs", "qwen3.6-plus"],
95
+ ["Omni Chat", "Multimodal chat (text+audio+image)", "qwen3.5-omni-plus"],
96
+ ["Image Generate", "AI image generation", "qwen-image-2.0"],
97
+ ["Image Edit", "AI image editing & multi-image merge", "qwen-image-2.0"],
98
+ ["Video Generate", "AI video generation", "happyhorse-1.0-t2v"],
99
+ ["Video Edit", "AI video editing", "happyhorse-1.0-video-edit"],
100
+ ["Vision", "Image understanding & description", "qwen-vl-max"],
101
+ ["Speech Synthesize", "Text-to-speech (TTS)", "cosyvoice-v3-flash"],
102
+ ["Speech Recognize", "Speech-to-text (ASR)", "fun-asr"],
103
+ ["File Upload", "Upload files to temp OSS storage", ""],
104
+ ["App Call", "Call Bailian agent / workflow apps", ""],
105
+ ["Memory", "Long-term memory management", ""],
106
+ ["Knowledge", "RAG knowledge base retrieval", ""],
107
+ ["Web Search", "Real-time web search powered by AI", ""],
100
108
  ];
101
109
 
102
110
  ttyPrint(`\n🚀 Bailian CLI provides ${capabilities.length} AI tools:\n`);
103
- ttyPrint(` ${'Capability'.padEnd(18)} ${'Description'.padEnd(38)} Default Model`);
104
- ttyPrint(` ${''.repeat(18)} ${''.repeat(38)} ${''.repeat(20)}`);
111
+ ttyPrint(` ${"Capability".padEnd(18)} ${"Description".padEnd(38)} Default Model`);
112
+ ttyPrint(` ${"".repeat(18)} ${"".repeat(38)} ${"".repeat(20)}`);
105
113
  for (const [name, desc, model] of capabilities) {
106
114
  ttyPrint(` ${name.padEnd(18)} ${desc.padEnd(38)} ${model}`);
107
115
  }
@@ -111,11 +119,11 @@ let installed = 0;
111
119
 
112
120
  for (const { root, label } of available) {
113
121
  try {
114
- const targetDir = join(root, 'skills', 'bailian-cli');
122
+ const targetDir = join(root, "skills", "bailian-cli");
115
123
  mkdirSync(targetDir, { recursive: true });
116
- copyFileSync(skillSource, join(targetDir, 'SKILL.md'));
124
+ copyFileSync(skillSource, join(targetDir, "SKILL.md"));
117
125
  if (existsSync(apiSkillSource)) {
118
- copyFileSync(apiSkillSource, join(targetDir, 'BAILIAN_API_DOC_REFER.md'));
126
+ copyFileSync(apiSkillSource, join(targetDir, "BAILIAN_API_DOC_REFER.md"));
119
127
  }
120
128
  installed++;
121
129
  ttyPrint(` ✓ ${label}`);
@@ -129,8 +137,8 @@ if (installed > 0) {
129
137
  }
130
138
 
131
139
  // ── API Key configuration guidance ──
132
- const API_KEY_URL = 'https://bailian.console.aliyun.com/cn-beijing/?source_channel=aliway&tab=app#/api-key';
133
- const configPath = join(home, '.bailian', 'config.json');
140
+ const API_KEY_URL = "https://bailian.console.aliyun.com/cn-beijing/?tab=app#/api-key";
141
+ const configPath = join(home, ".bailian", "config.json");
134
142
  let hasApiKey = false;
135
143
 
136
144
  // Check environment variable
@@ -140,56 +148,70 @@ if (process.env.DASHSCOPE_API_KEY) {
140
148
  // Check config file
141
149
  if (!hasApiKey && existsSync(configPath)) {
142
150
  try {
143
- const cfg = JSON.parse(readFileSync(configPath, 'utf-8'));
144
- if (typeof cfg.api_key === 'string' && cfg.api_key.length > 0) hasApiKey = true;
145
- } catch { /* ignore */ }
151
+ const cfg = JSON.parse(readFileSync(configPath, "utf-8"));
152
+ if (typeof cfg.api_key === "string" && cfg.api_key.length > 0) hasApiKey = true;
153
+ } catch {
154
+ /* ignore */
155
+ }
146
156
  }
147
157
 
148
158
  if (hasApiKey) {
149
159
  // Already configured — show usage examples
150
- ttyPrint('');
151
- ttyPrint(' \ud83c\udfaf Try these with your AI coding assistant:');
152
- ttyPrint('');
153
- ttyPrint(' 1 \u5e2e\u6211\u751f\u6210\u4e00\u5957\u9e2d\u820c\u5e3d\u7684\u4e9a\u9a6c\u900a\u7535\u5546\u4e3b\u56fe\uff08\u767d\u5e95 + \u573a\u666f\u56fe + \u6a21\u7279\u4e0a\u8eab\u56fe\uff09');
154
- ttyPrint(' 2 \u5e2e\u6211\u751f\u6210\u4e00\u6bb5 3 \u5206\u949f\u7684\u5e7d\u9ed8\u76f8\u58f0\u97f3\u9891');
155
- ttyPrint(' 3 \u5e2e\u6211\u751f\u6210\u4e00\u5957\u5c0f\u7ea2\u5e3d\u6545\u4e8b\u7ed8\u672c PDF\uff08\u542b\u63d2\u56fe\uff09');
156
- ttyPrint(' 4 \u5e2e\u6211\u5206\u6790\u8fd9\u4e2a\u89c6\u9891\u7684\u5185\u5bb9\u5e76\u5199\u4e00\u7bc7\u5c0f\u7ea2\u4e66\u6587\u6848');
157
- ttyPrint('');
160
+ ttyPrint("");
161
+ ttyPrint(" \ud83c\udfaf Try these with your AI coding assistant:");
162
+ ttyPrint("");
163
+ ttyPrint(
164
+ " 1 \u5e2e\u6211\u751f\u6210\u4e00\u5957\u9e2d\u820c\u5e3d\u7684\u4e9a\u9a6c\u900a\u7535\u5546\u4e3b\u56fe\uff08\u767d\u5e95 + \u573a\u666f\u56fe + \u6a21\u7279\u4e0a\u8eab\u56fe\uff09",
165
+ );
166
+ ttyPrint(
167
+ " 2 \u5e2e\u6211\u751f\u6210\u4e00\u6bb5 3 \u5206\u949f\u7684\u5e7d\u9ed8\u76f8\u58f0\u97f3\u9891",
168
+ );
169
+ ttyPrint(
170
+ " 3 \u5e2e\u6211\u751f\u6210\u4e00\u5957\u5c0f\u7ea2\u5e3d\u6545\u4e8b\u7ed8\u672c PDF\uff08\u542b\u63d2\u56fe\uff09",
171
+ );
172
+ ttyPrint(
173
+ " 4 \u5e2e\u6211\u5206\u6790\u8fd9\u4e2a\u89c6\u9891\u7684\u5185\u5bb9\u5e76\u5199\u4e00\u7bc7\u5c0f\u7ea2\u4e66\u6587\u6848",
174
+ );
175
+ ttyPrint("");
158
176
  } else {
159
177
  // Not configured — guide user to set up API Key
160
- ttyPrint('');
161
- ttyPrint(' \u26a0\ufe0f \u5c1a\u672a\u914d\u7f6e API Key\uff0c\u8bf7\u5148\u5b8c\u6210\u914d\u7f6e\u624d\u80fd\u4f7f\u7528\u5168\u90e8\u80fd\u529b\u3002');
162
- ttyPrint('');
163
- ttyPrint(' \u2460 \u83b7\u53d6 API Key\uff08\u514d\u8d39\u521b\u5efa\uff09:');
178
+ ttyPrint("");
179
+ ttyPrint(
180
+ " \u26a0\ufe0f \u5c1a\u672a\u914d\u7f6e API Key\uff0c\u8bf7\u5148\u5b8c\u6210\u914d\u7f6e\u624d\u80fd\u4f7f\u7528\u5168\u90e8\u80fd\u529b\u3002",
181
+ );
182
+ ttyPrint("");
183
+ ttyPrint(" \u2460 \u83b7\u53d6 API Key\uff08\u514d\u8d39\u521b\u5efa\uff09:");
164
184
  ttyPrint(` ${API_KEY_URL}`);
165
- ttyPrint('');
166
- ttyPrint(' \u2461 \u914d\u7f6e\u65b9\u5f0f\uff08\u4efb\u9009\u5176\u4e00\uff09:');
167
- ttyPrint('');
168
- ttyPrint(' # \u65b9\u5f0f A: CLI \u767b\u5f55\uff08\u63a8\u8350\uff09');
169
- ttyPrint(' bl auth login --api-key sk-xxxxx');
170
- ttyPrint('');
171
- ttyPrint(' # \u65b9\u5f0f B: \u73af\u5883\u53d8\u91cf');
172
- ttyPrint(' export DASHSCOPE_API_KEY=sk-xxxxx');
173
- ttyPrint('');
174
- ttyPrint(' \u2462 \u914d\u7f6e\u6210\u529f\u540e\uff0c\u5728 Agent \u4e2d\u76f4\u63a5\u8bf4:');
175
- ttyPrint(' \u201c\u5e2e\u6211\u751f\u6210\u4e00\u5f20\u592a\u7a7a\u732b\u7684\u56fe\u7247\u201d');
176
- ttyPrint(' \u201c\u5e2e\u6211\u628a\u8fd9\u6bb5\u6587\u5b57\u8f6c\u6210\u8bed\u97f3\u201d');
177
- ttyPrint('');
185
+ ttyPrint("");
186
+ ttyPrint(" \u2461 \u914d\u7f6e\u65b9\u5f0f\uff08\u4efb\u9009\u5176\u4e00\uff09:");
187
+ ttyPrint("");
188
+ ttyPrint(" # \u65b9\u5f0f A: CLI \u767b\u5f55\uff08\u63a8\u8350\uff09");
189
+ ttyPrint(" bl auth login --api-key sk-xxxxx");
190
+ ttyPrint("");
191
+ ttyPrint(" # \u65b9\u5f0f B: \u73af\u5883\u53d8\u91cf");
192
+ ttyPrint(" export DASHSCOPE_API_KEY=sk-xxxxx");
193
+ ttyPrint("");
194
+ ttyPrint(" \u2462 \u914d\u7f6e\u6210\u529f\u540e\uff0c\u5728 Agent \u4e2d\u76f4\u63a5\u8bf4:");
195
+ ttyPrint(
196
+ " \u201c\u5e2e\u6211\u751f\u6210\u4e00\u5f20\u592a\u7a7a\u732b\u7684\u56fe\u7247\u201d",
197
+ );
198
+ ttyPrint(" \u201c\u5e2e\u6211\u628a\u8fd9\u6bb5\u6587\u5b57\u8f6c\u6210\u8bed\u97f3\u201d");
199
+ ttyPrint("");
178
200
  }
179
201
 
180
202
  // Check if 'bl' bin is reachable via PATH
181
203
  try {
182
- execSync('which bl', { stdio: 'ignore' });
204
+ execSync("which bl", { stdio: "ignore" });
183
205
  } catch {
184
206
  // bin not in PATH — npm global prefix likely not on PATH
185
- ttyPrint('');
207
+ ttyPrint("");
186
208
  ttyPrint('\u26a0\ufe0f Command "bl" not found in PATH.');
187
- ttyPrint(' Your npm global bin directory may not be on PATH.');
188
- ttyPrint(' Run `npm config get prefix` and add its `bin/` to your PATH,');
189
- ttyPrint(' or reinstall with:');
190
- ttyPrint('');
191
- ttyPrint(' npm install -g bailian-cli');
192
- ttyPrint('');
209
+ ttyPrint(" Your npm global bin directory may not be on PATH.");
210
+ ttyPrint(" Run `npm config get prefix` and add its `bin/` to your PATH,");
211
+ ttyPrint(" or reinstall with:");
212
+ ttyPrint("");
213
+ ttyPrint(" npm install -g bailian-cli");
214
+ ttyPrint("");
193
215
  }
194
216
 
195
217
  if (ttyFd != null) {
@@ -4,44 +4,44 @@
4
4
  * Preuninstall script: remove SKILL.md from all AI coding tools on uninstall.
5
5
  */
6
6
 
7
- import { existsSync, rmSync, openSync, writeSync, closeSync } from 'fs';
8
- import { join } from 'path';
9
- import { homedir } from 'os';
7
+ import { existsSync, rmSync, openSync, writeSync, closeSync } from "fs";
8
+ import { join } from "path";
9
+ import { homedir } from "os";
10
10
 
11
11
  const home = homedir();
12
12
 
13
13
  // Write directly to /dev/tty to bypass npm output suppression
14
14
  let ttyFd;
15
15
  try {
16
- ttyFd = openSync('/dev/tty', 'w');
16
+ ttyFd = openSync("/dev/tty", "w");
17
17
  } catch {
18
18
  ttyFd = null;
19
19
  }
20
20
 
21
21
  function ttyPrint(msg) {
22
22
  if (ttyFd != null) {
23
- writeSync(ttyFd, msg + '\n');
23
+ writeSync(ttyFd, msg + "\n");
24
24
  }
25
25
  }
26
26
 
27
27
  const dotDirTargets = [
28
- '.qoder',
29
- '.claude',
30
- '.cline',
31
- '.qwen',
32
- '.cursor',
33
- '.windsurf',
34
- '.trae',
35
- '.qoderwork',
36
- '.kiro',
28
+ ".qoder",
29
+ ".claude",
30
+ ".cline",
31
+ ".qwen",
32
+ ".cursor",
33
+ ".windsurf",
34
+ ".trae",
35
+ ".qoderwork",
36
+ ".kiro",
37
37
  ];
38
38
 
39
39
  const customTargets = [
40
- { root: join(home, 'Library', 'Application Support', 'iDingTalk', 'wukong'), label: 'Wukong' },
40
+ { root: join(home, "Library", "Application Support", "iDingTalk", "wukong"), label: "Wukong" },
41
41
  ];
42
42
 
43
43
  const targets = [
44
- ...dotDirTargets.map(d => ({ root: join(home, d), label: d })),
44
+ ...dotDirTargets.map((d) => ({ root: join(home, d), label: d })),
45
45
  ...customTargets,
46
46
  ];
47
47
 
@@ -49,7 +49,7 @@ let removed = 0;
49
49
 
50
50
  for (const { root, label } of targets) {
51
51
  try {
52
- const skillDir = join(root, 'skills', 'bailian-cli');
52
+ const skillDir = join(root, "skills", "bailian-cli");
53
53
  if (!existsSync(skillDir)) continue;
54
54
 
55
55
  rmSync(skillDir, { recursive: true });