scan-debug-skill 1.0.0 → 1.0.2
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/LICENSE +21 -0
- package/README.md +1 -1
- package/bin/install.js +23 -9
- package/js/reference/js-ts-best-practices.md +19 -5
- package/js/reference/security-compliance.md +36 -11
- package/package.json +2 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 契机
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
package/bin/install.js
CHANGED
|
@@ -129,33 +129,47 @@ let defaultText = 'Trae';
|
|
|
129
129
|
if (hasCursor && !hasTrae) {
|
|
130
130
|
defaultChoice = '2';
|
|
131
131
|
defaultText = 'Cursor';
|
|
132
|
-
} else if (hasTrae && hasCursor) {
|
|
133
|
-
defaultChoice = '3';
|
|
134
|
-
defaultText = 'Both';
|
|
135
132
|
}
|
|
133
|
+
// 若两者都存在,默认保持为 1 (Trae)
|
|
136
134
|
|
|
137
135
|
console.log('请选择要安装的目标 IDE (Please select target IDE):');
|
|
138
136
|
console.log(`1. Trae (.trae/scan-debug-skill) ${hasTrae ? '[Detected]' : ''}`);
|
|
139
137
|
console.log(`2. Cursor (.cursor/scan-debug-skill) ${hasCursor ? '[Detected]' : ''}`);
|
|
140
|
-
console.log('3.
|
|
138
|
+
console.log('3. Custom (指定目录/Custom Directory)');
|
|
141
139
|
|
|
142
140
|
rl.question(`请输入选项 (1/2/3) [默认: ${defaultChoice} (${defaultText})]: `, (answer) => {
|
|
143
141
|
const choice = answer.trim() || defaultChoice;
|
|
144
142
|
|
|
143
|
+
// 选项 3:自定义目录
|
|
144
|
+
if (choice === '3') {
|
|
145
|
+
rl.question('请输入目标安装目录 (Please enter target directory): ', (inputPath) => {
|
|
146
|
+
const targetDir = inputPath.trim();
|
|
147
|
+
if (targetDir) {
|
|
148
|
+
// 处理相对路径和绝对路径
|
|
149
|
+
const finalPath = path.isAbsolute(targetDir) ? targetDir : path.resolve(cwd, targetDir);
|
|
150
|
+
install(finalPath);
|
|
151
|
+
} else {
|
|
152
|
+
console.log('❌ 未输入路径,已取消 (No path provided, cancelled).');
|
|
153
|
+
}
|
|
154
|
+
rl.close();
|
|
155
|
+
});
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
145
159
|
// 映射选择到目标目录
|
|
146
160
|
const targets = [];
|
|
147
161
|
|
|
148
|
-
// 选项 1
|
|
149
|
-
if (choice === '1'
|
|
162
|
+
// 选项 1:安装到 Trae
|
|
163
|
+
if (choice === '1') {
|
|
150
164
|
targets.push(path.join(cwd, '.trae', 'scan-debug-skill'));
|
|
151
165
|
}
|
|
152
166
|
|
|
153
|
-
// 选项 2
|
|
154
|
-
if (choice === '2'
|
|
167
|
+
// 选项 2:安装到 Cursor
|
|
168
|
+
if (choice === '2') {
|
|
155
169
|
targets.push(path.join(cwd, '.cursor', 'scan-debug-skill'));
|
|
156
170
|
}
|
|
157
171
|
|
|
158
|
-
//
|
|
172
|
+
// 如果没有有效选择(且不是3),回退到默认
|
|
159
173
|
if (targets.length === 0) {
|
|
160
174
|
if (defaultChoice === '2') {
|
|
161
175
|
targets.push(path.join(cwd, '.cursor', 'scan-debug-skill'));
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* **异步处理**:
|
|
9
9
|
* 优先使用 `async/await`。
|
|
10
10
|
* 所有 Promise 链必须以 `.catch()` 结束,或在 `try...catch` 块中处理错误。
|
|
11
|
+
* **冗余条件判断**:当 `if` 和 `else` 分支执行逻辑完全一致时,应移除条件判断,直接执行公共逻辑。
|
|
11
12
|
|
|
12
13
|
## 示例:认知复杂度与魔法数字
|
|
13
14
|
|
|
@@ -37,13 +38,26 @@ function isDateFuture(date) {
|
|
|
37
38
|
}
|
|
38
39
|
```
|
|
39
40
|
|
|
40
|
-
##
|
|
41
|
+
## 示例:冗余条件判断
|
|
41
42
|
|
|
42
|
-
**场景**:Sonar 提示 "
|
|
43
|
+
**场景**:Sonar 提示 "This 'if' block is equivalent to the 'else' block",即 `if` 和 `else` 分支执行了完全相同的逻辑。
|
|
43
44
|
|
|
44
45
|
**修复后代码**:
|
|
45
46
|
```javascript
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
/**
|
|
48
|
+
* 处理页面跳转
|
|
49
|
+
* @description 无论用户是否登录,点击该按钮都跳转到首页
|
|
50
|
+
*/
|
|
51
|
+
function handleRedirect() {
|
|
52
|
+
// Compliant: 移除冗余的条件判断
|
|
53
|
+
// 修复前:
|
|
54
|
+
// if (isLoggedIn) {
|
|
55
|
+
// navigateTo('/home');
|
|
56
|
+
// } else {
|
|
57
|
+
// navigateTo('/home');
|
|
58
|
+
// }
|
|
59
|
+
|
|
60
|
+
// 修复后:直接执行通用逻辑
|
|
61
|
+
navigateTo('/home');
|
|
62
|
+
}
|
|
49
63
|
```
|
|
@@ -5,22 +5,47 @@
|
|
|
5
5
|
* 严禁使用 `eval()`、`new Function()`。
|
|
6
6
|
* 慎用 `v-html` (Vue) 或 `dangerouslySetInnerHTML` (React),必须确保内容已经过 DOMPurify 等库的清洗。
|
|
7
7
|
* **敏感信息**:代码中禁止硬编码密码、Token、密钥(AK/SK)、内网 IP 等敏感信息,应通过环境变量或配置接口获取。
|
|
8
|
+
* **日志安全**:禁止在生产环境日志中输出敏感信息(如密码、Token 等);**若变量名无明确语义化(如 `data`, `info`, `res`),视为潜在敏感信息禁止直接打印**;异常捕获时仅记录错误来源或通用提示,**严禁直接打印 `error.stack` 或完整的 `error` 对象**,防止堆栈信息泄露系统内部结构。
|
|
8
9
|
* **链接安全**:使用 `target="_blank"` 打开外部链接时,必须添加 `rel="noopener noreferrer"` 以防止钓鱼攻击。
|
|
9
|
-
*
|
|
10
|
+
* **正则安全**:确保正则表达式不会导致拒绝服务攻击 (ReDoS)。
|
|
10
11
|
|
|
11
|
-
##
|
|
12
|
+
## 示例:日志安全与异常处理
|
|
12
13
|
|
|
13
|
-
**场景**:Sonar
|
|
14
|
+
**场景**:Sonar/安全扫描提示 "User credentials should not be printed" 或 "Stack traces should not be disclosed"。
|
|
14
15
|
|
|
15
16
|
**修复后代码**:
|
|
16
17
|
```javascript
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
/**
|
|
19
|
+
* 处理用户登录
|
|
20
|
+
* @param {string} username - 用户名
|
|
21
|
+
* @param {string} password - 密码
|
|
22
|
+
*/
|
|
23
|
+
async function handleLogin(username, password) {
|
|
24
|
+
try {
|
|
25
|
+
// 1. 敏感信息禁止打印
|
|
26
|
+
// Non-Compliant (敏感数据): console.log(`Attempting login for ${username} with password ${password}`);
|
|
27
|
+
// Non-Compliant (非语义化变量): console.log('Login info:', info); // info 语义不明确,可能包含敏感字段
|
|
28
|
+
console.log(`Attempting login for user: ${username}`); // Compliant: 仅记录明确的非敏感标识
|
|
29
|
+
|
|
30
|
+
await authService.login(username, password);
|
|
31
|
+
|
|
32
|
+
} catch (error) {
|
|
33
|
+
// 2. 异常捕获禁止泄露堆栈
|
|
34
|
+
// Non-Compliant: console.error(error); 或 console.error(error.stack);
|
|
35
|
+
|
|
36
|
+
// Compliant: 仅记录错误来源,不包含详细堆栈
|
|
37
|
+
console.error('LoginService: 用户登录请求失败');
|
|
38
|
+
}
|
|
25
39
|
}
|
|
26
40
|
```
|
|
41
|
+
|
|
42
|
+
## 示例:正则表达式安全 (ReDoS)
|
|
43
|
+
|
|
44
|
+
**场景**:Sonar 提示 "Make sure the regex used here... cannot lead to denial of service"。
|
|
45
|
+
|
|
46
|
+
**修复后代码**:
|
|
47
|
+
```javascript
|
|
48
|
+
// Compliant: 优化正则结构,避免嵌套量词,防止 ReDoS 攻击
|
|
49
|
+
// 说明:匹配一个或多个 'a' 后跟一个 'b'
|
|
50
|
+
const regex = /a+b/;
|
|
51
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scan-debug-skill",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "ScanDebugSkill for Trae IDE - Easily install debugging skills via npx",
|
|
5
5
|
"bin": {
|
|
6
6
|
"scan-debug-skill": "./bin/install.js"
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"scan"
|
|
16
16
|
],
|
|
17
17
|
"author": "",
|
|
18
|
-
"license": "
|
|
18
|
+
"license": "MIT",
|
|
19
19
|
"files": [
|
|
20
20
|
"bin",
|
|
21
21
|
"css",
|