yuangs 1.3.22 → 1.3.25
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/.github/workflows/publish.yml +6 -6
- package/README.md +57 -0
- package/cli.js +33 -4
- package/index.js +74 -4
- package/package.json +4 -3
- package/test/index.test.js +10 -0
- package/yuangs.config.example.json +8 -0
- package/yuangs.config.example.yaml +18 -0
|
@@ -3,7 +3,7 @@ name: Auto Bump & Publish
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
branches:
|
|
6
|
-
- main
|
|
6
|
+
- main # 如果你的默认分支不是 main,记得改成对应名字
|
|
7
7
|
|
|
8
8
|
jobs:
|
|
9
9
|
publish:
|
|
@@ -19,13 +19,13 @@ jobs:
|
|
|
19
19
|
uses: actions/checkout@v4
|
|
20
20
|
with:
|
|
21
21
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
22
|
-
fetch-depth: 0
|
|
22
|
+
fetch-depth: 0 # 完整历史,方便推 tag
|
|
23
23
|
|
|
24
24
|
- name: Set up Node.js
|
|
25
25
|
uses: actions/setup-node@v4
|
|
26
26
|
with:
|
|
27
|
-
node-version:
|
|
28
|
-
registry-url:
|
|
27
|
+
node-version: "18"
|
|
28
|
+
registry-url: "https://registry.npmjs.org/"
|
|
29
29
|
|
|
30
30
|
- name: Configure Git
|
|
31
31
|
run: |
|
|
@@ -36,7 +36,7 @@ jobs:
|
|
|
36
36
|
# [skip ci] 防止这个 commit 再次触发 workflow 形成死循环
|
|
37
37
|
- name: Bump version
|
|
38
38
|
run: |
|
|
39
|
-
npm version patch -m "
|
|
39
|
+
npm version patch -m "苑广山注:自动升版本号%s[skip ci]"
|
|
40
40
|
|
|
41
41
|
# 推送 commit + tag 回 GitHub
|
|
42
42
|
- name: Push changes
|
|
@@ -51,4 +51,4 @@ jobs:
|
|
|
51
51
|
- name: Publish to npm
|
|
52
52
|
run: npm publish --provenance
|
|
53
53
|
env:
|
|
54
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
54
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/README.md
CHANGED
|
@@ -63,8 +63,65 @@ yuangs ai
|
|
|
63
63
|
|
|
64
64
|
Pong 游戏: https://wealth.want.biz/pages/pong.html
|
|
65
65
|
|
|
66
|
+
## 配置自定义应用 (v1.3.24)
|
|
67
|
+
|
|
68
|
+
从 v1.3.24 版本开始,您可以自定义应用列表,而无需修改源代码。
|
|
69
|
+
|
|
70
|
+
### 配置文件格式
|
|
71
|
+
|
|
72
|
+
创建一个 JSON 或 YAML 配置文件,支持以下格式之一:
|
|
73
|
+
|
|
74
|
+
1. `yuangs.config.json` - 项目级别的 JSON 配置文件
|
|
75
|
+
2. `.yuangs.json` - 项目级或用户主目录的 JSON 隐藏配置文件
|
|
76
|
+
3. `yuangs.config.yaml` - 项目级别的 YAML 配置文件
|
|
77
|
+
4. `yuangs.config.yml` - 项目级别的 YAML 配置文件
|
|
78
|
+
5. `.yuangs.yaml` - 项目级或用户主目录的 YAML 隐藏配置文件
|
|
79
|
+
6. `.yuangs.yml` - 项目级或用户主目录的 YAML 隐藏配置文件
|
|
80
|
+
7. `~/.yuangs.json` - 全局用户 JSON 配置文件
|
|
81
|
+
8. `~/.yuangs.yaml` - 全局用户 YAML 配置文件
|
|
82
|
+
9. `~/.yuangs.yml` - 全局用户 YAML 配置文件
|
|
83
|
+
|
|
84
|
+
配置文件示例:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"shici": "https://wealth.want.biz/shici/index.html",
|
|
89
|
+
"dict": "https://wealth.want.biz/pages/dict.html",
|
|
90
|
+
"pong": "https://wealth.want.biz/pages/pong.html",
|
|
91
|
+
"github": "https://github.com",
|
|
92
|
+
"calendar": "https://calendar.google.com",
|
|
93
|
+
"mail": "https://mail.google.com"
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 配置文件优先级
|
|
98
|
+
|
|
99
|
+
配置文件按以下优先级顺序查找(高到低):
|
|
100
|
+
|
|
101
|
+
1. 当前工作目录下的 `yuangs.config.json`
|
|
102
|
+
2. 当前工作目录下的 `.yuangs.json`
|
|
103
|
+
3. 用户主目录下的 `.yuangs.json`
|
|
104
|
+
4. 项目目录下的 `yuangs.config.json`
|
|
105
|
+
5. 项目目录下的 `.yuangs.json`
|
|
106
|
+
6. 如果没有配置文件,则使用默认应用列表
|
|
107
|
+
|
|
108
|
+
### 使用自定义应用
|
|
109
|
+
|
|
110
|
+
创建配置文件后,您可以使用任何定义的应用名称作为命令:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
yuangs github # 打开 GitHub
|
|
114
|
+
yuangs calendar # 打开日历
|
|
115
|
+
yuangs mail # 打开邮箱
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
使用 `yuangs list` 命令查看当前加载的所有应用。
|
|
119
|
+
|
|
66
120
|
## 近期主要更新日志
|
|
67
121
|
|
|
122
|
+
### v1.3.22 (2025-11-30)
|
|
123
|
+
- **新增** AI 命令支持 `-p` `-f` `-l` 简写,快速选择gemini默认模型
|
|
124
|
+
|
|
68
125
|
### v1.3.6 (2025-11-29)
|
|
69
126
|
|
|
70
127
|
- **新增** AI 命令交互模式:直接输入 `yuangs ai` 即可进入一问一答模式,无需每次输入问题,quit 或 exit 可退出。
|
package/cli.js
CHANGED
|
@@ -13,10 +13,24 @@ function printHelp() {
|
|
|
13
13
|
console.log(chalk.gray('仓库地址: https://www.npmjs.com/package/yuangs?activeTab=readme\n'));
|
|
14
14
|
console.log(chalk.white('使用方法:') + chalk.gray(' yuangs <命令> [参数]\n'));
|
|
15
15
|
console.log(chalk.bold('命令列表:'));
|
|
16
|
+
|
|
17
|
+
// Show default commands
|
|
16
18
|
console.log(` ${chalk.green('shici')} 打开古诗词 PWA`);
|
|
17
19
|
console.log(` ${chalk.green('dict')} 打开英语词典`);
|
|
18
20
|
console.log(` ${chalk.green('pong')} 打开 Pong 游戏`);
|
|
19
21
|
console.log(` ${chalk.green('list')} 列出所有应用链接`);
|
|
22
|
+
|
|
23
|
+
// Show dynamically configured apps
|
|
24
|
+
const dynamicApps = Object.keys(yuangs.urls).filter(key =>
|
|
25
|
+
!['shici', 'dict', 'pong'].includes(key)
|
|
26
|
+
);
|
|
27
|
+
if (dynamicApps.length > 0) {
|
|
28
|
+
console.log(chalk.bold('\n自定义应用:'));
|
|
29
|
+
dynamicApps.forEach(app => {
|
|
30
|
+
console.log(` ${chalk.green(app)} 打开 ${app} 应用`);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
20
34
|
console.log(` ${chalk.green('ai')} "<问题>" 向 AI 提问(不写问题进入交互模式)`);
|
|
21
35
|
console.log(` ${chalk.gray('--model, -m <模型名称>')} 指定 AI 模型 (可选)`);
|
|
22
36
|
console.log(` ${chalk.gray('-p -f -l')} 指定 pro,flash,lite 模型 (可选)`);
|
|
@@ -26,6 +40,7 @@ function printHelp() {
|
|
|
26
40
|
console.log(` ${chalk.gray('/history')} 查看对话历史\n`);
|
|
27
41
|
console.log(chalk.gray('AI 示例: yuangs ai "你好" --model gemini-pro-latest'));
|
|
28
42
|
console.log(chalk.gray('普通示例: yuangs shici\n'));
|
|
43
|
+
console.log(chalk.gray('配置文件: 您可以通过创建 yuangs.config.json 或 ~/.yuangs.json 来自定义应用列表\n'));
|
|
29
44
|
}
|
|
30
45
|
|
|
31
46
|
function printSuccess(app, url) {
|
|
@@ -185,17 +200,20 @@ async function handleAICommand() {
|
|
|
185
200
|
await askOnce(question, model);
|
|
186
201
|
}
|
|
187
202
|
|
|
203
|
+
// Check if the command matches one of the configured apps
|
|
204
|
+
const isAppCommand = Object.keys(yuangs.urls).includes(command);
|
|
205
|
+
|
|
188
206
|
switch (command) {
|
|
189
207
|
case 'shici':
|
|
190
|
-
printSuccess('古诗词应用', yuangs.urls.shici);
|
|
208
|
+
printSuccess('古诗词应用', yuangs.urls.shici || 'N/A');
|
|
191
209
|
yuangs.openShici();
|
|
192
210
|
break;
|
|
193
211
|
case 'dict':
|
|
194
|
-
printSuccess('英语词典', yuangs.urls.dict);
|
|
212
|
+
printSuccess('英语词典', yuangs.urls.dict || 'N/A');
|
|
195
213
|
yuangs.openDict();
|
|
196
214
|
break;
|
|
197
215
|
case 'pong':
|
|
198
|
-
printSuccess('Pong 游戏', yuangs.urls.pong);
|
|
216
|
+
printSuccess('Pong 游戏', yuangs.urls.pong || 'N/A');
|
|
199
217
|
yuangs.openPong();
|
|
200
218
|
break;
|
|
201
219
|
case 'list':
|
|
@@ -212,7 +230,18 @@ switch (command) {
|
|
|
212
230
|
case 'help':
|
|
213
231
|
case '--help':
|
|
214
232
|
case '-h':
|
|
215
|
-
default:
|
|
216
233
|
printHelp();
|
|
217
234
|
break;
|
|
235
|
+
default:
|
|
236
|
+
// If it's an app command but not one of the named ones, handle it with the dynamic function
|
|
237
|
+
if (isAppCommand) {
|
|
238
|
+
printSuccess(command, yuangs.urls[command]);
|
|
239
|
+
yuangs.openApp(command);
|
|
240
|
+
} else if (command) {
|
|
241
|
+
console.log(chalk.red(`\n错误: 未知命令 '${command}'\n`));
|
|
242
|
+
printHelp();
|
|
243
|
+
} else {
|
|
244
|
+
printHelp();
|
|
245
|
+
}
|
|
246
|
+
break;
|
|
218
247
|
}
|
package/index.js
CHANGED
|
@@ -1,15 +1,74 @@
|
|
|
1
1
|
const { exec } = require('child_process');
|
|
2
2
|
const axios = require('axios');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
3
5
|
|
|
4
6
|
// Store conversation history
|
|
5
7
|
let conversationHistory = [];
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
// Default apps (fallback if no config file exists)
|
|
10
|
+
const DEFAULT_APPS = {
|
|
8
11
|
shici: 'https://wealth.want.biz/shici/index.html',
|
|
9
12
|
dict: 'https://wealth.want.biz/pages/dict.html',
|
|
10
13
|
pong: 'https://wealth.want.biz/pages/pong.html'
|
|
11
14
|
};
|
|
12
15
|
|
|
16
|
+
// Load apps from configuration file
|
|
17
|
+
function loadAppsConfig() {
|
|
18
|
+
// Define possible config file locations (JSON and YAML)
|
|
19
|
+
const configPaths = [
|
|
20
|
+
path.join(process.cwd(), 'yuangs.config.json'), // Current working directory
|
|
21
|
+
path.join(process.cwd(), '.yuangs.json'), // Current working directory dot file
|
|
22
|
+
path.join(process.cwd(), 'yuangs.config.yaml'), // Current working directory YAML
|
|
23
|
+
path.join(process.cwd(), 'yuangs.config.yml'), // Current working directory YAML
|
|
24
|
+
path.join(process.cwd(), '.yuangs.yaml'), // Current working directory dot YAML
|
|
25
|
+
path.join(process.cwd(), '.yuangs.yml'), // Current working directory dot YAML
|
|
26
|
+
path.join(require('os').homedir(), '.yuangs.json'), // User home directory
|
|
27
|
+
path.join(require('os').homedir(), '.yuangs.yaml'), // User home directory YAML
|
|
28
|
+
path.join(require('os').homedir(), '.yuangs.yml'), // User home directory YAML
|
|
29
|
+
path.join(__dirname, 'yuangs.config.json'), // Project directory
|
|
30
|
+
path.join(__dirname, '.yuangs.json'), // Project directory dot file
|
|
31
|
+
path.join(__dirname, 'yuangs.config.yaml'), // Project directory YAML
|
|
32
|
+
path.join(__dirname, 'yuangs.config.yml') // Project directory YAML
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
for (const configPath of configPaths) {
|
|
36
|
+
if (fs.existsSync(configPath)) {
|
|
37
|
+
try {
|
|
38
|
+
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
39
|
+
|
|
40
|
+
// Determine if it's JSON or YAML based on file extension
|
|
41
|
+
let config;
|
|
42
|
+
if (configPath.endsWith('.json')) {
|
|
43
|
+
config = JSON.parse(configContent);
|
|
44
|
+
} else {
|
|
45
|
+
// For YAML files, we need to require the yaml parser
|
|
46
|
+
let yaml;
|
|
47
|
+
try {
|
|
48
|
+
yaml = require('js-yaml');
|
|
49
|
+
} catch (yamlError) {
|
|
50
|
+
console.warn(`Warning: js-yaml not installed, skipping YAML file ${configPath}`);
|
|
51
|
+
console.warn('Install js-yaml with: npm install js-yaml');
|
|
52
|
+
continue; // Skip this file and try the next config file
|
|
53
|
+
}
|
|
54
|
+
config = yaml.load(configContent);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// If config has an 'apps' property, use it, otherwise use the whole config as apps
|
|
58
|
+
return config.apps || config;
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.warn(`Warning: Could not parse config file at ${configPath}:`, error.message);
|
|
61
|
+
// Continue to next config file
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// If no config file is found, use default apps
|
|
67
|
+
return DEFAULT_APPS;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const APPS = loadAppsConfig();
|
|
71
|
+
|
|
13
72
|
function openUrl(url) {
|
|
14
73
|
let command;
|
|
15
74
|
switch (process.platform) {
|
|
@@ -91,9 +150,20 @@ async function getAIAnswer(question, model, includeHistory = true) {
|
|
|
91
150
|
|
|
92
151
|
module.exports = {
|
|
93
152
|
urls: APPS,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
153
|
+
// Dynamic function to open any app by key
|
|
154
|
+
openApp: (appKey) => {
|
|
155
|
+
const url = APPS[appKey];
|
|
156
|
+
if (url) {
|
|
157
|
+
openUrl(url);
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
console.error(`App '${appKey}' not found`);
|
|
161
|
+
return false;
|
|
162
|
+
},
|
|
163
|
+
// Specific functions for default apps (for backward compatibility)
|
|
164
|
+
openShici: () => openUrl(APPS.shici || DEFAULT_APPS.shici),
|
|
165
|
+
openDict: () => openUrl(APPS.dict || DEFAULT_APPS.dict),
|
|
166
|
+
openPong: () => openUrl(APPS.pong || DEFAULT_APPS.pong),
|
|
97
167
|
listApps: () => {
|
|
98
168
|
console.log('--- YGS Apps ---');
|
|
99
169
|
Object.entries(APPS).forEach(([key, url]) => console.log(`${key}: ${url}`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yuangs",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.25",
|
|
4
4
|
"description": "苑广山的个人应用集合 CLI(彩色版)",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"tools",
|
|
16
16
|
"colorful"
|
|
17
17
|
],
|
|
18
|
-
"homepage": "https://github.com/
|
|
18
|
+
"homepage": "https://github.com/yauangshan/npm_yuangs#readme",
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
21
|
"url": "git+https://github.com/yuanguangshan/npm_yuangs.git"
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"license": "ISC",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"axios": "^1.13.2",
|
|
30
|
-
"chalk": "^4.1.2"
|
|
30
|
+
"chalk": "^4.1.2",
|
|
31
|
+
"js-yaml": "^4.1.0"
|
|
31
32
|
},
|
|
32
33
|
"devDependencies": {
|
|
33
34
|
"jest": "^29.7.0"
|
package/test/index.test.js
CHANGED
|
@@ -14,6 +14,16 @@ describe('Module: index.js', () => {
|
|
|
14
14
|
expect(yuangs.urls.shici).toContain('shici/index.html');
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
+
test('should have openApp function', () => {
|
|
18
|
+
expect(typeof yuangs.openApp).toBe('function');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('should have backward compatibility functions', () => {
|
|
22
|
+
expect(typeof yuangs.openShici).toBe('function');
|
|
23
|
+
expect(typeof yuangs.openDict).toBe('function');
|
|
24
|
+
expect(typeof yuangs.openPong).toBe('function');
|
|
25
|
+
});
|
|
26
|
+
|
|
17
27
|
test('should manage conversation history correctly', () => {
|
|
18
28
|
yuangs.addToConversationHistory('user', 'hello');
|
|
19
29
|
let history = yuangs.getConversationHistory();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"shici": "https://wealth.want.biz/shici/index.html",
|
|
3
|
+
"dict": "https://wealth.want.biz/pages/dict.html",
|
|
4
|
+
"pong": "https://wealth.want.biz/pages/pong.html",
|
|
5
|
+
"github": "https://github.com",
|
|
6
|
+
"calendar": "https://calendar.google.com",
|
|
7
|
+
"mail": "https://mail.google.com"
|
|
8
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Example configuration file for yuangs CLI
|
|
2
|
+
# Add your custom applications here
|
|
3
|
+
|
|
4
|
+
shici: "https://wealth.want.biz/shici/index.html"
|
|
5
|
+
dict: "https://wealth.want.biz/pages/dict.html"
|
|
6
|
+
pong: "https://wealth.want.biz/pages/pong.html"
|
|
7
|
+
github: "https://github.com"
|
|
8
|
+
calendar: "https://calendar.google.com"
|
|
9
|
+
mail: "https://mail.google.com"
|
|
10
|
+
|
|
11
|
+
# You can also use the apps property if you prefer to group them
|
|
12
|
+
# apps:
|
|
13
|
+
# shici: "https://wealth.want.biz/shici/index.html"
|
|
14
|
+
# dict: "https://wealth.want.biz/pages/dict.html"
|
|
15
|
+
# pong: "https://wealth.want.biz/pages/pong.html"
|
|
16
|
+
# github: "https://github.com"
|
|
17
|
+
# calendar: "https://calendar.google.com"
|
|
18
|
+
# mail: "https://mail.google.com"
|