bailian-cli 0.1.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 ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "bailian-cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI for Alibaba Cloud Bailian (DashScope) AI Platform",
5
+ "author": "ali-pizza",
6
+ "license": "Apache-2.0",
7
+ "type": "module",
8
+ "engines": {
9
+ "node": ">=18"
10
+ },
11
+ "bin": {
12
+ "bl": "dist/bailian.mjs"
13
+ },
14
+ "files": [
15
+ "dist/bailian.mjs",
16
+ "skill/SKILL.md",
17
+ "skill/BAILIAN_API_DOC_REFER.md",
18
+ "scripts/postinstall.js",
19
+ "scripts/preuninstall.js"
20
+ ],
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"
32
+ },
33
+ "dependencies": {
34
+ "@clack/prompts": "^0.7.0"
35
+ },
36
+ "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"
42
+ },
43
+ "publishConfig": {
44
+ "registry": "https://registry.npmjs.org/"
45
+ }
46
+ }
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Postinstall script: automatically install SKILL.md to all detected AI coding tools.
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.
19
+ */
20
+
21
+ import { existsSync, mkdirSync, copyFileSync, openSync, writeSync, closeSync } from 'fs';
22
+ import { join, dirname } from 'path';
23
+ import { homedir } from 'os';
24
+ import { fileURLToPath } from 'url';
25
+ import { execSync } from 'child_process';
26
+
27
+ 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');
30
+
31
+ if (!existsSync(skillSource)) {
32
+ process.exit(0);
33
+ }
34
+
35
+ const home = homedir();
36
+
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
57
+ const targets = [
58
+ ...dotDirTargets.map(d => ({ root: join(home, d), label: d })),
59
+ ...customTargets,
60
+ ];
61
+
62
+ // Detect which tools are available
63
+ const available = targets.filter(({ root }) => existsSync(root));
64
+
65
+ if (available.length === 0) {
66
+ process.exit(0);
67
+ }
68
+
69
+ // Write directly to /dev/tty to bypass npm output suppression
70
+ let ttyFd;
71
+ try {
72
+ ttyFd = openSync('/dev/tty', 'w');
73
+ } catch {
74
+ // No TTY (CI, etc.) — skip display, still install silently
75
+ ttyFd = null;
76
+ }
77
+
78
+ function ttyPrint(msg) {
79
+ if (ttyFd != null) {
80
+ writeSync(ttyFd, msg + '\n');
81
+ }
82
+ }
83
+
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', 'wan2.7-t2v'],
91
+ ['Video Edit', 'AI video editing', 'wan2.7-videoedit'],
92
+ ['Vision', 'Image understanding & description', 'qwen-vl-max'],
93
+ ['Speech Synthesize', 'Text-to-speech (TTS)', 'qwen3-tts-flash'],
94
+ ['Speech Recognize', 'Speech-to-text (ASR)', 'qwen3-asr-flash'],
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;
111
+
112
+ for (const { root, label } of available) {
113
+ try {
114
+ const targetDir = join(root, 'skills', 'bailian-cli');
115
+ 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'));
119
+ }
120
+ installed++;
121
+ ttyPrint(` ✓ ${label}`);
122
+ } catch {
123
+ // Silent fail — don't block npm install
124
+ }
125
+ }
126
+
127
+ if (installed > 0) {
128
+ ttyPrint(`\n\u2705 Bailian CLI skill installed for ${installed} AI coding tool(s).`);
129
+ }
130
+
131
+ ttyPrint('');
132
+ ttyPrint(' \ud83c\udfaf Try these with your AI coding assistant:');
133
+ ttyPrint('');
134
+ 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');
135
+ ttyPrint(' 2 \u5e2e\u6211\u751f\u6210\u4e00\u6bb5 3 \u5206\u949f\u7684\u5e7d\u9ed8\u76f8\u58f0\u97f3\u9891');
136
+ ttyPrint(' 3 \u5e2e\u6211\u751f\u6210\u4e00\u5957\u5c0f\u7ea2\u5e3d\u6545\u4e8b\u7ed8\u672c PDF\uff08\u542b\u63d2\u56fe\uff09');
137
+ ttyPrint(' 4 \u5e2e\u6211\u5206\u6790\u8fd9\u4e2a\u89c6\u9891\u7684\u5185\u5bb9\u5e76\u5199\u4e00\u7bc7\u5c0f\u7ea2\u4e66\u6587\u6848');
138
+ ttyPrint('');
139
+
140
+ // Check if 'bl' bin is reachable via PATH
141
+ try {
142
+ execSync('which bl', { stdio: 'ignore' });
143
+ } catch {
144
+ // bin not in PATH — npm global prefix likely not on PATH
145
+ ttyPrint('');
146
+ ttyPrint('\u26a0\ufe0f Command "bl" not found in PATH.');
147
+ ttyPrint(' Your npm global bin directory may not be on PATH.');
148
+ ttyPrint(' Run `npm config get prefix` and add its `bin/` to your PATH,');
149
+ ttyPrint(' or reinstall with:');
150
+ ttyPrint('');
151
+ ttyPrint(' npm install -g bailian-cli');
152
+ ttyPrint('');
153
+ }
154
+
155
+ if (ttyFd != null) {
156
+ closeSync(ttyFd);
157
+ }
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Preuninstall script: remove SKILL.md from all AI coding tools on uninstall.
5
+ */
6
+
7
+ import { existsSync, rmSync, openSync, writeSync, closeSync } from 'fs';
8
+ import { join } from 'path';
9
+ import { homedir } from 'os';
10
+
11
+ const home = homedir();
12
+
13
+ // Write directly to /dev/tty to bypass npm output suppression
14
+ let ttyFd;
15
+ try {
16
+ ttyFd = openSync('/dev/tty', 'w');
17
+ } catch {
18
+ ttyFd = null;
19
+ }
20
+
21
+ function ttyPrint(msg) {
22
+ if (ttyFd != null) {
23
+ writeSync(ttyFd, msg + '\n');
24
+ }
25
+ }
26
+
27
+ const dotDirTargets = [
28
+ '.qoder',
29
+ '.claude',
30
+ '.cline',
31
+ '.qwen',
32
+ '.cursor',
33
+ '.windsurf',
34
+ '.trae',
35
+ '.qoderwork',
36
+ '.kiro',
37
+ ];
38
+
39
+ const customTargets = [
40
+ { root: join(home, 'Library', 'Application Support', 'iDingTalk', 'wukong'), label: 'Wukong' },
41
+ ];
42
+
43
+ const targets = [
44
+ ...dotDirTargets.map(d => ({ root: join(home, d), label: d })),
45
+ ...customTargets,
46
+ ];
47
+
48
+ let removed = 0;
49
+
50
+ for (const { root, label } of targets) {
51
+ try {
52
+ const skillDir = join(root, 'skills', 'bailian-cli');
53
+ if (!existsSync(skillDir)) continue;
54
+
55
+ rmSync(skillDir, { recursive: true });
56
+ removed++;
57
+ ttyPrint(` \u2717 ${label}`);
58
+ } catch {
59
+ // Silent fail — don't block npm uninstall
60
+ }
61
+ }
62
+
63
+ if (removed > 0) {
64
+ ttyPrint(`Bailian CLI skill removed from ${removed} AI coding tool(s).`);
65
+ }
66
+
67
+ if (ttyFd != null) {
68
+ closeSync(ttyFd);
69
+ }