bailian-cli 0.1.2 → 1.0.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",
4
- "description": "CLI for Alibaba Cloud Bailian (DashScope) AI Platform",
5
- "author": "ali-pizza",
3
+ "version": "1.0.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",
18
- "scripts/postinstall.js",
19
- "scripts/preuninstall.js"
13
+ "dist",
14
+ "skill",
15
+ "scripts/postinstall.js"
20
16
  ],
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"
17
+ "type": "module",
18
+ "exports": {
19
+ ".": "./dist/bailian.mjs",
20
+ "./package.json": "./package.json"
21
+ },
22
+ "publishConfig": {
23
+ "registry": "https://registry.npmjs.org/"
32
24
  },
33
25
  "dependencies": {
34
- "@clack/prompts": "^0.7.0"
26
+ "bailian-cli-core": "1.0.0"
35
27
  },
36
28
  "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"
29
+ "@clack/prompts": "^0.7.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
+ "generate:reference": "node --experimental-strip-types scripts/generate-reference.ts",
46
+ "build": "pnpm run generate:reference && vp pack",
47
+ "dev": "node src/main.ts",
48
+ "test": "vp test",
49
+ "check": "vp check",
50
+ "postinstall": "node scripts/postinstall.js"
45
51
  }
46
- }
52
+ }
@@ -3,30 +3,28 @@
3
3
  /**
4
4
  * Postinstall script: automatically install SKILL.md to all detected AI coding tools.
5
5
  *
6
- * Supported platforms:
7
- * - Qoder → ~/.qoder/skills/bailian-cli/SKILL.md
8
- * - Claude Code → ~/.claude/skills/bailian-cli/SKILL.md
9
- * - Cline → ~/.cline/skills/bailian-cli/SKILL.md
10
- * - QwenCode → ~/.qwen/skills/bailian-cli/SKILL.md
11
- * - Cursor → ~/.cursor/skills/bailian-cli/SKILL.md
12
- * - Windsurf → ~/.windsurf/skills/bailian-cli/SKILL.md
13
- * - Trae → ~/.trae/skills/bailian-cli/SKILL.md
14
- * - QoderWork → ~/.qoderwork/skills/bailian-cli/SKILL.md
15
- * - Kiro → ~/.kiro/skills/bailian-cli/SKILL.md
16
- * - Wukong → ~/Library/Application Support/iDingTalk/wukong/skills/bailian-cli/SKILL.md
17
- *
18
- * Only installs when the tool's root directory already exists.
6
+ * For each tool whose root dir exists, writes SKILL.md to <root>/skills/bailian-cli/.
7
+ * See `targets` below for the full list.
19
8
  */
20
9
 
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';
10
+ import {
11
+ existsSync,
12
+ mkdirSync,
13
+ copyFileSync,
14
+ cpSync,
15
+ openSync,
16
+ writeSync,
17
+ closeSync,
18
+ readFileSync,
19
+ } from "fs";
20
+ import { join, dirname } from "path";
21
+ import { homedir } from "os";
22
+ import { fileURLToPath } from "url";
23
+ import { execSync } from "child_process";
26
24
 
27
25
  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');
26
+ const skillSource = join(__dirname, "..", "skill", "SKILL.md");
27
+ const referenceDirSource = join(__dirname, "..", "skill", "reference");
30
28
 
31
29
  if (!existsSync(skillSource)) {
32
30
  process.exit(0);
@@ -34,29 +32,21 @@ if (!existsSync(skillSource)) {
34
32
 
35
33
  const home = homedir();
36
34
 
37
- // Targets: each entry is { root: absolute path to tool's root dir, label: display name }
38
- // Pattern 1: ~/.xxx/skills/bailian-cli/SKILL.md (most tools)
39
- const dotDirTargets = [
40
- '.qoder',
41
- '.claude',
42
- '.cline',
43
- '.qwen',
44
- '.cursor',
45
- '.windsurf',
46
- '.trae',
47
- '.qoderwork',
48
- '.kiro',
49
- ];
50
-
51
- // Pattern 2: Non-standard paths
52
- const customTargets = [
53
- { root: join(home, 'Library', 'Application Support', 'iDingTalk', 'wukong'), label: 'Wukong' },
54
- ];
55
-
56
- // Build unified target list
35
+ // Each entry: { root, label }
36
+ // - root: absolute path to the tool's root dir; existence triggers install,
37
+ // and SKILL.md is written to <root>/skills/bailian-cli/
38
+ // - label: display name in install summary
57
39
  const targets = [
58
- ...dotDirTargets.map(d => ({ root: join(home, d), label: d })),
59
- ...customTargets,
40
+ { root: join(home, ".qoder"), label: "Qoder" },
41
+ { root: join(home, ".claude"), label: "ClaudeCode" },
42
+ { root: join(home, ".cline"), label: "Cline" },
43
+ { root: join(home, ".qwen"), label: "QwenCode" },
44
+ { root: join(home, ".cursor"), label: "Cursor" },
45
+ { root: join(home, ".qoderwork"), label: "QoderWork" },
46
+ { root: join(home, ".codex"), label: "Codex" },
47
+ { root: join(home, ".kilo"), label: "Kilo Code" },
48
+ { root: join(home, ".openclaw"), label: "OpenCLaw" },
49
+ { root: join(home, ".config", "opencode"), label: "OpenCode" },
60
50
  ];
61
51
 
62
52
  // Detect which tools are available
@@ -69,7 +59,7 @@ if (available.length === 0) {
69
59
  // Write directly to /dev/tty to bypass npm output suppression
70
60
  let ttyFd;
71
61
  try {
72
- ttyFd = openSync('/dev/tty', 'w');
62
+ ttyFd = openSync("/dev/tty", "w");
73
63
  } catch {
74
64
  // No TTY (CI, etc.) — skip display, still install silently
75
65
  ttyFd = null;
@@ -77,119 +67,83 @@ try {
77
67
 
78
68
  function ttyPrint(msg) {
79
69
  if (ttyFd != null) {
80
- writeSync(ttyFd, msg + '\n');
70
+ writeSync(ttyFd, msg + "\n");
81
71
  }
82
72
  }
83
73
 
84
- // Show capabilities
85
- 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', '—'],
100
- ];
101
-
102
- 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)}`);
105
- for (const [name, desc, model] of capabilities) {
106
- ttyPrint(` ${name.padEnd(18)} ${desc.padEnd(38)} ${model}`);
107
- }
108
- ttyPrint(`\nInstalling skill for ${available.length} AI coding tool(s)...`);
109
-
110
- let installed = 0;
74
+ ttyPrint(`\n🚀 Installing Bailian CLI skill to ${available.length} AI coding tool(s):`);
111
75
 
112
76
  for (const { root, label } of available) {
113
77
  try {
114
- const targetDir = join(root, 'skills', 'bailian-cli');
78
+ const targetDir = join(root, "skills", "bailian-cli");
115
79
  mkdirSync(targetDir, { recursive: true });
116
- copyFileSync(skillSource, join(targetDir, 'SKILL.md'));
117
- if (existsSync(apiSkillSource)) {
118
- copyFileSync(apiSkillSource, join(targetDir, 'BAILIAN_API_DOC_REFER.md'));
80
+ copyFileSync(skillSource, join(targetDir, "SKILL.md"));
81
+ if (existsSync(referenceDirSource)) {
82
+ cpSync(referenceDirSource, join(targetDir, "reference"), { recursive: true });
119
83
  }
120
- installed++;
121
84
  ttyPrint(` ✓ ${label}`);
122
85
  } catch {
123
86
  // Silent fail — don't block npm install
124
87
  }
125
88
  }
126
89
 
127
- if (installed > 0) {
128
- ttyPrint(`\n\u2705 Bailian CLI skill installed for ${installed} AI coding tool(s).`);
129
- }
130
-
131
90
  // ── 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');
91
+ const API_KEY_URL = "https://bailian.console.aliyun.com/cn-beijing/?tab=app#/api-key";
92
+ const configPath = join(home, ".bailian", "config.json");
134
93
  let hasApiKey = false;
135
94
 
136
- // Check environment variable
137
95
  if (process.env.DASHSCOPE_API_KEY) {
138
96
  hasApiKey = true;
139
97
  }
140
- // Check config file
141
98
  if (!hasApiKey && existsSync(configPath)) {
142
99
  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 */ }
100
+ const cfg = JSON.parse(readFileSync(configPath, "utf-8"));
101
+ if (typeof cfg.api_key === "string" && cfg.api_key.length > 0) hasApiKey = true;
102
+ } catch {
103
+ /* ignore */
104
+ }
146
105
  }
147
106
 
107
+ const demoPrompts = [
108
+ "帮我生成一套鸭舌帽的亚马逊电商主图(白底 + 场景图 + 模特上身图)",
109
+ "帮我生成一段 3 分钟的幽默相声音频",
110
+ "帮我生成一套小红帽故事绘本 PDF(含插图)",
111
+ "帮我分析这个视频的内容并写一篇小红书文案",
112
+ ];
113
+
148
114
  if (hasApiKey) {
149
- // 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('');
115
+ ttyPrint("");
116
+ ttyPrint("🎯 Try these with your AI coding assistant:");
117
+ ttyPrint("");
118
+ demoPrompts.forEach((p, i) => ttyPrint(` ${i + 1} ${p}`));
119
+ ttyPrint("");
158
120
  } else {
159
- // 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:');
121
+ ttyPrint("");
122
+ ttyPrint("💡 Set up your API Key to unlock all capabilities:");
123
+ ttyPrint("");
124
+ ttyPrint(" 1️⃣ Get an API Key (free):");
164
125
  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('');
126
+ ttyPrint("");
127
+ ttyPrint(" 2️⃣ Sign in:");
128
+ ttyPrint(" bl auth login --api-key sk-xxxxx");
129
+ ttyPrint("");
130
+ ttyPrint(" 3️⃣ Then try these with your AI coding assistant:");
131
+ demoPrompts.forEach((p, i) => ttyPrint(` ${i + 1} ${p}`));
132
+ ttyPrint("");
178
133
  }
179
134
 
180
135
  // Check if 'bl' bin is reachable via PATH
181
136
  try {
182
- execSync('which bl', { stdio: 'ignore' });
137
+ execSync("which bl", { stdio: "ignore" });
183
138
  } catch {
184
- // bin not in PATH — npm global prefix likely not on PATH
185
- ttyPrint('');
186
- 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('');
139
+ ttyPrint("");
140
+ ttyPrint('⚠️ Command "bl" not found in PATH.');
141
+ ttyPrint(" Your npm global bin directory may not be on PATH.");
142
+ ttyPrint(" Run `npm config get prefix` and add its `bin/` to your PATH,");
143
+ ttyPrint(" or reinstall with:");
144
+ ttyPrint("");
145
+ ttyPrint(" npm install -g bailian-cli");
146
+ ttyPrint("");
193
147
  }
194
148
 
195
149
  if (ttyFd != null) {