daodou-command 1.4.6 → 1.4.8
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/lib/commands/build.js +157 -161
- package/lib/utils/browser.js +236 -25
- package/package.json +1 -1
- package/.claude/settings.local.json +0 -20
- package/.idea/UniappTool.xml +0 -10
- package/.idea/copilot.data.migration.agent.xml +0 -6
- package/.idea/copilot.data.migration.ask.xml +0 -6
- package/.idea/copilot.data.migration.ask2agent.xml +0 -6
- package/.idea/copilot.data.migration.edit.xml +0 -6
- package/.idea/daodou-command.iml +0 -12
- package/.idea/editorJumperProjectSettings.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/.idea/workspace.xml +0 -84
- package/AI_QUICK_REFERENCE.md +0 -202
- package/CHANGELOG.md +0 -201
- package/COMMAND_DEVELOPMENT_GUIDE.md +0 -504
package/lib/utils/browser.js
CHANGED
|
@@ -3,6 +3,8 @@ const chalk = require('chalk');
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const os = require('os');
|
|
6
|
+
const axios = require('axios');
|
|
7
|
+
const ora = require('ora');
|
|
6
8
|
const { ConfigManager } = require('./config');
|
|
7
9
|
|
|
8
10
|
// 配置管理器
|
|
@@ -14,24 +16,23 @@ class BrowserAuth {
|
|
|
14
16
|
this.jenkinsUrl = this.config.jenkinsUrl;
|
|
15
17
|
this.username = this.config.jenkinsUsername;
|
|
16
18
|
this.password = this.config.jenkinsPassword;
|
|
17
|
-
this.cookies = null;
|
|
19
|
+
this.cookies = null; // Jenkins 域名的 cookies
|
|
20
|
+
this.allCookies = null; // 所有域名的 cookies(含 Casdoor)
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
/**
|
|
21
24
|
* 启动浏览器并登录Jenkins
|
|
22
25
|
*/
|
|
23
26
|
async login() {
|
|
27
|
+
const spinner = ora({ text: '正在登录 Jenkins...', indent: 2 }).start();
|
|
24
28
|
try {
|
|
25
|
-
console.log(chalk.blue('🌐 启动浏览器...'));
|
|
26
|
-
|
|
27
29
|
// 验证 Jenkins URL
|
|
28
30
|
if (!this.jenkinsUrl || this.jenkinsUrl === 'your-jenkins-url') {
|
|
29
31
|
throw new Error('Jenkins URL 未配置或为模板值,请检查 .daodourc 文件');
|
|
30
32
|
}
|
|
31
|
-
|
|
32
|
-
this.browser = await puppeteer.launch({
|
|
33
|
+
|
|
34
|
+
this.browser = await puppeteer.launch({
|
|
33
35
|
headless: true,
|
|
34
|
-
// 移除硬编码路径,让 Puppeteer 自动查找
|
|
35
36
|
args: [
|
|
36
37
|
'--no-sandbox',
|
|
37
38
|
'--disable-setuid-sandbox',
|
|
@@ -44,44 +45,53 @@ class BrowserAuth {
|
|
|
44
45
|
});
|
|
45
46
|
this.page = await this.browser.newPage();
|
|
46
47
|
await this.page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36');
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
|
|
49
|
+
spinner.text = '正在访问 Jenkins...';
|
|
49
50
|
await this.page.goto(this.jenkinsUrl, { waitUntil: 'networkidle2', timeout: 30000 });
|
|
50
|
-
console.log(chalk.green(`✅ 当前页面: ${this.page.url()}`));
|
|
51
51
|
|
|
52
52
|
// 检查是否跳转到Casdoor登录页
|
|
53
53
|
if (this.page.url().includes('casdoor')) {
|
|
54
|
-
|
|
55
|
-
// 等待用户名输入框
|
|
54
|
+
spinner.text = '正在通过 Casdoor 认证...';
|
|
56
55
|
await this.page.waitForSelector('input[name="username"], input[type="text"]', { timeout: 10000 });
|
|
57
|
-
// 填写用户名
|
|
58
56
|
await this.page.type('input[name="username"], input[type="text"]', this.username, {delay: 50});
|
|
59
|
-
// 填写密码
|
|
60
57
|
await this.page.type('input[name="password"], input[type="password"]', this.password, {delay: 50});
|
|
61
|
-
//
|
|
58
|
+
// 勾选"记住我",延长 session 有效期
|
|
59
|
+
try {
|
|
60
|
+
const rememberCheckbox = await this.page.$('input[name="autoSignin"], input[name="remember"], input[name="rememberMe"], .ant-checkbox-input, input[type="checkbox"]');
|
|
61
|
+
if (rememberCheckbox) {
|
|
62
|
+
const isChecked = await rememberCheckbox.evaluate(el => el.checked);
|
|
63
|
+
if (!isChecked) {
|
|
64
|
+
await rememberCheckbox.click();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
} catch (e) {
|
|
68
|
+
// 找不到记住我选项不影响登录
|
|
69
|
+
}
|
|
62
70
|
await Promise.all([
|
|
63
71
|
this.page.click('button[type="submit"], input[type="submit"], .login-button'),
|
|
64
72
|
this.page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 30000 })
|
|
65
73
|
]);
|
|
66
|
-
console.log(chalk.green(`✅ 登录表单已提交,当前页面: ${this.page.url()}`));
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
// 检查是否成功跳转到Jenkins
|
|
70
77
|
if (this.page.url().includes(this.jenkinsUrl)) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
// 通过 CDP 获取所有域名的 cookies(含 Casdoor 的长期 cookie)
|
|
79
|
+
const client = await this.page.target().createCDPSession();
|
|
80
|
+
const { cookies: allCookies } = await client.send('Network.getAllCookies');
|
|
81
|
+
this.allCookies = allCookies;
|
|
82
|
+
const jenkinsHost = new URL(this.jenkinsUrl).hostname;
|
|
83
|
+
this.cookies = allCookies.filter(c => c.domain.includes(jenkinsHost));
|
|
74
84
|
await this.saveCookies();
|
|
75
85
|
await this.browser.close();
|
|
86
|
+
spinner.succeed('登录成功');
|
|
76
87
|
return true;
|
|
77
88
|
} else {
|
|
78
|
-
console.log(chalk.red('❌ 登录失败,当前页面:'), this.page.url());
|
|
79
89
|
await this.browser.close();
|
|
80
|
-
throw new Error('
|
|
90
|
+
throw new Error('登录失败,未跳转回 Jenkins');
|
|
81
91
|
}
|
|
82
92
|
} catch (error) {
|
|
83
|
-
console.error(chalk.red('Jenkins自动登录失败:'), error.message);
|
|
84
93
|
if (this.browser) await this.browser.close();
|
|
94
|
+
spinner.fail('登录失败 ' + chalk.dim(error.message));
|
|
85
95
|
throw error;
|
|
86
96
|
}
|
|
87
97
|
}
|
|
@@ -92,8 +102,12 @@ class BrowserAuth {
|
|
|
92
102
|
async saveCookies() {
|
|
93
103
|
const dir = path.join(os.homedir(), '.daodou');
|
|
94
104
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir);
|
|
105
|
+
// 保存所有域名的 cookies
|
|
95
106
|
const file = path.join(dir, 'cookies.json');
|
|
96
|
-
fs.writeFileSync(file, JSON.stringify(
|
|
107
|
+
fs.writeFileSync(file, JSON.stringify({
|
|
108
|
+
jenkins: this.cookies,
|
|
109
|
+
all: this.allCookies || this.cookies
|
|
110
|
+
}, null, 2));
|
|
97
111
|
}
|
|
98
112
|
|
|
99
113
|
/**
|
|
@@ -102,18 +116,215 @@ class BrowserAuth {
|
|
|
102
116
|
loadCookies() {
|
|
103
117
|
const file = path.join(os.homedir(), '.daodou', 'cookies.json');
|
|
104
118
|
if (fs.existsSync(file)) {
|
|
105
|
-
|
|
119
|
+
const data = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
120
|
+
// 兼容旧格式(纯数组)
|
|
121
|
+
if (Array.isArray(data)) {
|
|
122
|
+
this.cookies = data;
|
|
123
|
+
this.allCookies = data;
|
|
124
|
+
} else {
|
|
125
|
+
this.cookies = data.jenkins || [];
|
|
126
|
+
this.allCookies = data.all || data.jenkins || [];
|
|
127
|
+
}
|
|
106
128
|
return true;
|
|
107
129
|
}
|
|
108
130
|
return false;
|
|
109
131
|
}
|
|
110
132
|
|
|
111
133
|
/**
|
|
112
|
-
*
|
|
134
|
+
* 从 set-cookie 更新 cookies
|
|
135
|
+
* @param {Array<string>} setCookies 响应头中的 set-cookie 数组
|
|
136
|
+
*/
|
|
137
|
+
async updateCookiesFromSetCookie(setCookies) {
|
|
138
|
+
if (!setCookies || !Array.isArray(setCookies)) return;
|
|
139
|
+
|
|
140
|
+
if (!this.cookies) this.cookies = [];
|
|
141
|
+
|
|
142
|
+
let changed = false;
|
|
143
|
+
const jenkinsHost = new URL(this.jenkinsUrl).hostname;
|
|
144
|
+
setCookies.forEach(str => {
|
|
145
|
+
// 简单解析:取第一个分号前的部分作为 name=value
|
|
146
|
+
const firstPart = str.split(';')[0];
|
|
147
|
+
const [rawName, ...valueParts] = firstPart.split('=');
|
|
148
|
+
const name = rawName.trim();
|
|
149
|
+
const value = valueParts.join('=').trim();
|
|
150
|
+
|
|
151
|
+
if (name && value) {
|
|
152
|
+
// 更新 jenkins cookies
|
|
153
|
+
const index = this.cookies.findIndex(c => c.name === name);
|
|
154
|
+
if (index !== -1) {
|
|
155
|
+
if (this.cookies[index].value !== value) {
|
|
156
|
+
this.cookies[index].value = value;
|
|
157
|
+
changed = true;
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
this.cookies.push({ name, value, domain: jenkinsHost, path: '/' });
|
|
161
|
+
changed = true;
|
|
162
|
+
}
|
|
163
|
+
// 同步更新 allCookies 中对应的 Jenkins cookie
|
|
164
|
+
if (this.allCookies) {
|
|
165
|
+
const allIdx = this.allCookies.findIndex(c => c.name === name && c.domain.includes(jenkinsHost));
|
|
166
|
+
if (allIdx !== -1) {
|
|
167
|
+
this.allCookies[allIdx].value = value;
|
|
168
|
+
} else {
|
|
169
|
+
this.allCookies.push({ name, value, domain: jenkinsHost, path: '/' });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
if (changed) {
|
|
176
|
+
await this.saveCookies();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* 获取 Cookie 字符串(Jenkins 域名)
|
|
182
|
+
*/
|
|
183
|
+
getCookieString() {
|
|
184
|
+
if (!this.cookies) return '';
|
|
185
|
+
return this.cookies.map(c => `${c.name}=${c.value}`).join('; ');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* 获取指定域名的 Cookie 字符串
|
|
190
|
+
*/
|
|
191
|
+
getCookieStringForDomain(domain) {
|
|
192
|
+
if (!this.allCookies) return '';
|
|
193
|
+
return this.allCookies
|
|
194
|
+
.filter(c => domain.includes(c.domain.replace(/^\./, '')))
|
|
195
|
+
.map(c => `${c.name}=${c.value}`)
|
|
196
|
+
.join('; ');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* 用 Casdoor cookie 走 SSO 重定向刷新 Jenkins session(无需启动浏览器)
|
|
201
|
+
* @returns {boolean} 是否刷新成功
|
|
202
|
+
*/
|
|
203
|
+
async refreshSessionViaCasdoor() {
|
|
204
|
+
if (!this.allCookies || this.allCookies.length === 0) return false;
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
// 1. 访问 Jenkins,期望 302 跳转到 Casdoor
|
|
208
|
+
const resp1 = await axios.get(this.jenkinsUrl, {
|
|
209
|
+
maxRedirects: 0,
|
|
210
|
+
validateStatus: s => s === 302 || s === 301,
|
|
211
|
+
headers: {
|
|
212
|
+
Cookie: this.getCookieString(),
|
|
213
|
+
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36'
|
|
214
|
+
}
|
|
215
|
+
}).catch(e => e.response);
|
|
216
|
+
|
|
217
|
+
if (!resp1 || !resp1.headers.location) return false;
|
|
218
|
+
const casdoorUrl = resp1.headers.location;
|
|
219
|
+
if (!casdoorUrl.includes('casdoor')) return false;
|
|
220
|
+
|
|
221
|
+
// 2. 带 Casdoor cookie 访问授权页,期望自动跳回 Jenkins
|
|
222
|
+
const casdoorDomain = new URL(casdoorUrl).hostname;
|
|
223
|
+
const casdoorCookieStr = this.getCookieStringForDomain(casdoorDomain);
|
|
224
|
+
if (!casdoorCookieStr) return false;
|
|
225
|
+
|
|
226
|
+
const resp2 = await axios.get(casdoorUrl, {
|
|
227
|
+
maxRedirects: 0,
|
|
228
|
+
validateStatus: s => s === 302 || s === 301,
|
|
229
|
+
headers: {
|
|
230
|
+
Cookie: casdoorCookieStr,
|
|
231
|
+
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36'
|
|
232
|
+
}
|
|
233
|
+
}).catch(e => e.response);
|
|
234
|
+
|
|
235
|
+
if (!resp2 || !resp2.headers.location) return false;
|
|
236
|
+
const callbackUrl = resp2.headers.location;
|
|
237
|
+
|
|
238
|
+
// 收集 Casdoor 返回的 set-cookie
|
|
239
|
+
const casdoorSetCookies = resp2.headers['set-cookie'] || [];
|
|
240
|
+
|
|
241
|
+
// 3. 跟随回调 URL 到 Jenkins,收集所有重定向中的 Set-Cookie
|
|
242
|
+
let currentUrl = callbackUrl;
|
|
243
|
+
let allSetCookies = [];
|
|
244
|
+
for (let i = 0; i < 5; i++) { // 最多跟随 5 次重定向
|
|
245
|
+
const resp = await axios.get(currentUrl, {
|
|
246
|
+
maxRedirects: 0,
|
|
247
|
+
validateStatus: s => s < 400 || s === 302 || s === 301,
|
|
248
|
+
headers: {
|
|
249
|
+
Cookie: this.getCookieString(),
|
|
250
|
+
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36'
|
|
251
|
+
}
|
|
252
|
+
}).catch(e => e.response);
|
|
253
|
+
|
|
254
|
+
if (!resp) return false;
|
|
255
|
+
if (resp.headers['set-cookie']) {
|
|
256
|
+
allSetCookies = allSetCookies.concat(resp.headers['set-cookie']);
|
|
257
|
+
// 实时更新 cookies,后续重定向用新 cookie
|
|
258
|
+
await this.updateCookiesFromSetCookie(resp.headers['set-cookie']);
|
|
259
|
+
}
|
|
260
|
+
if ((resp.status === 302 || resp.status === 301) && resp.headers.location) {
|
|
261
|
+
currentUrl = resp.headers.location;
|
|
262
|
+
// 相对路径补全
|
|
263
|
+
if (currentUrl.startsWith('/')) {
|
|
264
|
+
const base = new URL(this.jenkinsUrl);
|
|
265
|
+
currentUrl = `${base.protocol}//${base.host}${currentUrl}`;
|
|
266
|
+
}
|
|
267
|
+
} else {
|
|
268
|
+
break; // 非重定向,结束
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (allSetCookies.length === 0) return false;
|
|
273
|
+
|
|
274
|
+
// 4. 更新 Casdoor cookies
|
|
275
|
+
if (casdoorSetCookies.length > 0) {
|
|
276
|
+
this._updateAllCookiesFromSetCookie(casdoorSetCookies, casdoorDomain);
|
|
277
|
+
}
|
|
278
|
+
// 同步 Jenkins cookie 到 allCookies 并持久化
|
|
279
|
+
await this._syncAndSave();
|
|
280
|
+
|
|
281
|
+
return true;
|
|
282
|
+
} catch (e) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* 更新 allCookies 中指定域名的 cookie
|
|
113
289
|
*/
|
|
290
|
+
_updateAllCookiesFromSetCookie(setCookies, domain) {
|
|
291
|
+
if (!setCookies || !this.allCookies) return;
|
|
292
|
+
setCookies.forEach(str => {
|
|
293
|
+
const firstPart = str.split(';')[0];
|
|
294
|
+
const [rawName, ...valueParts] = firstPart.split('=');
|
|
295
|
+
const name = rawName.trim();
|
|
296
|
+
const value = valueParts.join('=').trim();
|
|
297
|
+
if (name && value) {
|
|
298
|
+
const index = this.allCookies.findIndex(c => c.name === name && c.domain.includes(domain));
|
|
299
|
+
if (index !== -1) {
|
|
300
|
+
this.allCookies[index].value = value;
|
|
301
|
+
} else {
|
|
302
|
+
this.allCookies.push({ name, value, domain, path: '/' });
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* 将 jenkins cookies 同步到 allCookies 并持久化
|
|
310
|
+
*/
|
|
311
|
+
async _syncAndSave() {
|
|
312
|
+
if (!this.allCookies) this.allCookies = [];
|
|
313
|
+
const jenkinsHost = new URL(this.jenkinsUrl).hostname;
|
|
314
|
+
// 用最新的 jenkins cookies 覆盖 allCookies 中对应的条目
|
|
315
|
+
for (const jc of this.cookies) {
|
|
316
|
+
const idx = this.allCookies.findIndex(c => c.name === jc.name && c.domain.includes(jenkinsHost));
|
|
317
|
+
if (idx !== -1) {
|
|
318
|
+
this.allCookies[idx] = jc;
|
|
319
|
+
} else {
|
|
320
|
+
this.allCookies.push(jc);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
await this.saveCookies();
|
|
324
|
+
}
|
|
325
|
+
|
|
114
326
|
async ensureLogin() {
|
|
115
327
|
if (this.loadCookies()) {
|
|
116
|
-
console.log(chalk.green('✅ 已加载保存的cookies'));
|
|
117
328
|
return;
|
|
118
329
|
}
|
|
119
330
|
await this.login();
|
package/package.json
CHANGED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"permissions": {
|
|
3
|
-
"allow": [
|
|
4
|
-
"Bash(tree:*)",
|
|
5
|
-
"Bash(git add:*)",
|
|
6
|
-
"Bash(git commit:*)",
|
|
7
|
-
"Bash(npm whoami:*)",
|
|
8
|
-
"Bash(npm publish)",
|
|
9
|
-
"Bash(git push:*)",
|
|
10
|
-
"Bash(npm view:*)",
|
|
11
|
-
"Bash(npm deprecate:*)",
|
|
12
|
-
"Bash(npm unlink:*)",
|
|
13
|
-
"Bash(npm install:*)",
|
|
14
|
-
"Bash(dao:*)",
|
|
15
|
-
"Bash(npm link)"
|
|
16
|
-
],
|
|
17
|
-
"deny": [],
|
|
18
|
-
"ask": []
|
|
19
|
-
}
|
|
20
|
-
}
|
package/.idea/UniappTool.xml
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="cn.fjdmy.uniapp.UniappProjectDataService">
|
|
4
|
-
<option name="generalBasePath" value="$PROJECT_DIR$" />
|
|
5
|
-
<option name="manifestPath" value="$PROJECT_DIR$/manifest.json" />
|
|
6
|
-
<option name="pagesPath" value="$PROJECT_DIR$/pages.json" />
|
|
7
|
-
<option name="scanNum" value="1" />
|
|
8
|
-
<option name="type" value="store" />
|
|
9
|
-
</component>
|
|
10
|
-
</project>
|
package/.idea/daodou-command.iml
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<module type="WEB_MODULE" version="4">
|
|
3
|
-
<component name="NewModuleRootManager">
|
|
4
|
-
<content url="file://$MODULE_DIR$">
|
|
5
|
-
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
6
|
-
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
7
|
-
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
8
|
-
</content>
|
|
9
|
-
<orderEntry type="inheritedJdk" />
|
|
10
|
-
<orderEntry type="sourceFolder" forTests="false" />
|
|
11
|
-
</component>
|
|
12
|
-
</module>
|
package/.idea/modules.xml
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectModuleManager">
|
|
4
|
-
<modules>
|
|
5
|
-
<module fileurl="file://$PROJECT_DIR$/.idea/daodou-command.iml" filepath="$PROJECT_DIR$/.idea/daodou-command.iml" />
|
|
6
|
-
</modules>
|
|
7
|
-
</component>
|
|
8
|
-
</project>
|
package/.idea/vcs.xml
DELETED
package/.idea/workspace.xml
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="AutoImportSettings">
|
|
4
|
-
<option name="autoReloadType" value="SELECTIVE" />
|
|
5
|
-
</component>
|
|
6
|
-
<component name="ChangeListManager">
|
|
7
|
-
<list default="true" id="1537cb23-f918-4011-a0ed-24da46bf53bc" name="更改" comment="" />
|
|
8
|
-
<option name="SHOW_DIALOG" value="false" />
|
|
9
|
-
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
10
|
-
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
11
|
-
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
12
|
-
</component>
|
|
13
|
-
<component name="Git.Settings">
|
|
14
|
-
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
|
15
|
-
</component>
|
|
16
|
-
<component name="GitHubPullRequestSearchHistory">{
|
|
17
|
-
"lastFilter": {
|
|
18
|
-
"state": "OPEN",
|
|
19
|
-
"assignee": "h025"
|
|
20
|
-
}
|
|
21
|
-
}</component>
|
|
22
|
-
<component name="GithubPullRequestsUISettings">{
|
|
23
|
-
"selectedUrlAndAccountId": {
|
|
24
|
-
"url": "https://github.com/h025/daodou-command.git",
|
|
25
|
-
"accountId": "c8b4f74c-2e36-4aad-b608-940f73fc88db"
|
|
26
|
-
}
|
|
27
|
-
}</component>
|
|
28
|
-
<component name="ProjectColorInfo">{
|
|
29
|
-
"associatedIndex": 6
|
|
30
|
-
}</component>
|
|
31
|
-
<component name="ProjectId" id="33EP70DuHXVnueD9LcTKpn8t7Vr" />
|
|
32
|
-
<component name="ProjectViewState">
|
|
33
|
-
<option name="hideEmptyMiddlePackages" value="true" />
|
|
34
|
-
<option name="showLibraryContents" value="true" />
|
|
35
|
-
</component>
|
|
36
|
-
<component name="PropertiesComponent">{
|
|
37
|
-
"keyToString": {
|
|
38
|
-
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
|
39
|
-
"RunOnceActivity.ShowReadmeOnStart": "true",
|
|
40
|
-
"RunOnceActivity.git.unshallow": "true",
|
|
41
|
-
"git-widget-placeholder": "main",
|
|
42
|
-
"last_opened_file_path": "/Users/summermr/daodou/daodou-command",
|
|
43
|
-
"node.js.detected.package.eslint": "true",
|
|
44
|
-
"node.js.detected.package.tslint": "true",
|
|
45
|
-
"node.js.selected.package.eslint": "(autodetect)",
|
|
46
|
-
"node.js.selected.package.tslint": "(autodetect)",
|
|
47
|
-
"nodejs_package_manager_path": "npm",
|
|
48
|
-
"vue.rearranger.settings.migration": "true"
|
|
49
|
-
}
|
|
50
|
-
}</component>
|
|
51
|
-
<component name="SharedIndexes">
|
|
52
|
-
<attachedChunks>
|
|
53
|
-
<set>
|
|
54
|
-
<option value="bundled-js-predefined-d6986cc7102b-3aa1da707db6-JavaScript-WS-252.27397.92" />
|
|
55
|
-
</set>
|
|
56
|
-
</attachedChunks>
|
|
57
|
-
</component>
|
|
58
|
-
<component name="TaskManager">
|
|
59
|
-
<task active="true" id="Default" summary="默认任务">
|
|
60
|
-
<changelist id="1537cb23-f918-4011-a0ed-24da46bf53bc" name="更改" comment="" />
|
|
61
|
-
<created>1758879086844</created>
|
|
62
|
-
<option name="number" value="Default" />
|
|
63
|
-
<option name="presentableId" value="Default" />
|
|
64
|
-
<updated>1758879086844</updated>
|
|
65
|
-
<workItem from="1758879088110" duration="1336000" />
|
|
66
|
-
<workItem from="1763003382850" duration="4466000" />
|
|
67
|
-
</task>
|
|
68
|
-
<servers />
|
|
69
|
-
</component>
|
|
70
|
-
<component name="TypeScriptGeneratedFilesManager">
|
|
71
|
-
<option name="version" value="3" />
|
|
72
|
-
</component>
|
|
73
|
-
<component name="Vcs.Log.Tabs.Properties">
|
|
74
|
-
<option name="TAB_STATES">
|
|
75
|
-
<map>
|
|
76
|
-
<entry key="MAIN">
|
|
77
|
-
<value>
|
|
78
|
-
<State />
|
|
79
|
-
</value>
|
|
80
|
-
</entry>
|
|
81
|
-
</map>
|
|
82
|
-
</option>
|
|
83
|
-
</component>
|
|
84
|
-
</project>
|