@qinsilk/scm-agent-tools 0.0.0-stage → 0.2.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/README.md +48 -2
- package/cli/api.js +114 -0
- package/cli/commands/data.js +112 -0
- package/cli/commands/docs.js +121 -0
- package/cli/commands/log.js +152 -0
- package/cli/commands/query.js +285 -0
- package/cli/commands/report.js +213 -0
- package/cli/commands/staff.js +505 -0
- package/cli/config.js +46 -0
- package/cli/datasets.js +541 -0
- package/cli/scm-agent.js +110 -0
- package/cli/skills.js +89 -0
- package/cli/table.js +43 -0
- package/docs/api.md +2067 -0
- package/docs/cli.md +252 -0
- package/package.json +27 -4
- package/reports/excel.js +107 -0
- package/reports/factoryEvaluation.js +128 -0
- package/reports/goodsBom.js +648 -0
- package/reports/goodsFirstOrder.js +409 -0
- package/reports/goodsInventory.js +220 -0
- package/reports/goodsSize.js +440 -0
- package/reports/image.js +216 -0
- package/reports/leakCheck.js +694 -0
- package/reports/materialPurchaseExport.js +393 -0
- package/reports/materialTransit.js +593 -0
- package/reports/processFollowup.js +312 -0
- package/reports/produceBoard.js +353 -0
- package/reports/produceCost.js +366 -0
- package/reports/produceCostDetail.js +622 -0
- package/reports/produceDaily.js +485 -0
- package/reports/storeInGoods.js +276 -0
- package/reports/supplierBalance.js +671 -0
- package/reports/ticketStatistics.js +289 -0
- package/reports/util.js +83 -0
- package/skills/bom/345/225/206/345/223/201/344/277/241/346/201/257/SKILL.md +40 -0
- package/skills/qinsilk-scm/SKILL.md +126 -0
- package/skills//344/276/233/345/272/224/345/225/206/345/257/271/350/264/246/345/257/274/345/207/272/SKILL.md +38 -0
- package/skills//345/225/206/345/223/201/345/260/272/345/257/270/344/277/241/346/201/257/SKILL.md +40 -0
- package/skills//345/225/206/345/223/201/351/246/226/345/215/225/351/235/242/346/226/231/345/267/245/345/272/217/345/215/225/344/273/267/SKILL.md +39 -0
- package/skills//345/267/245/345/216/202/350/257/204/344/274/260/346/212/245/350/241/250/SKILL.md +39 -0
- package/skills//346/210/220/345/223/201/345/205/245/345/272/223/346/212/245/350/241/250/SKILL.md +40 -0
- package/skills//346/234/215/350/243/205/346/210/220/345/223/201/347/233/230/345/255/230/350/241/250/SKILL.md +39 -0
- package/skills//346/274/217/346/226/231/346/243/200/346/265/213/346/227/245/346/212/245/SKILL.md +40 -0
- package/skills//347/211/251/346/226/231/345/234/250/351/200/224/347/212/266/346/200/201/346/212/245/350/241/250/SKILL.md +40 -0
- package/skills//347/211/251/346/226/231/351/207/207/350/264/255/345/257/274/345/207/272/SKILL.md +39 -0
- package/skills//347/224/237/344/272/247/345/215/225/345/267/245/345/272/217/350/267/237/350/277/233/350/241/250/SKILL.md +39 -0
- package/skills//347/224/237/344/272/247/346/210/220/346/234/254/346/212/245/350/241/250/SKILL.md +41 -0
- package/skills//347/224/237/344/272/247/346/210/220/346/234/254/346/212/245/350/241/250/346/230/216/347/273/206/SKILL.md +40 -0
- package/skills//347/224/237/344/272/247/346/227/245/346/212/245/SKILL.md +42 -0
- package/skills//347/224/237/344/272/247/347/212/266/345/206/265/347/273/237/350/256/241/350/241/250/SKILL.md +39 -0
- package/skills//347/224/237/344/272/247/350/212/202/347/202/271/347/234/213/346/235/277/SKILL.md +39 -0
package/cli/skills.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// 技能安装:把包内 skills/ 目录下的全部官方技能(qinsilk-scm 与 16 个报表技能)
|
|
2
|
+
// 逐个以链接方式登记到各家 AI 助手共同扫描的 ~/.agents/skills 目录。
|
|
3
|
+
// 链接指向 npm 全局安装位置内部,因此包升级即技能更新;
|
|
4
|
+
// 链接失败时降级为整目录复制(复制版不会随升级更新,输出中如实说明)。
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
|
|
9
|
+
function packageSkillsRoot() {
|
|
10
|
+
return path.join(__dirname, '..', 'skills');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** 包内全部官方技能名:skills/ 下含 SKILL.md 的一级子目录 */
|
|
14
|
+
function packagedSkillNames(sourceRoot = packageSkillsRoot()) {
|
|
15
|
+
return fs
|
|
16
|
+
.readdirSync(sourceRoot, { withFileTypes: true })
|
|
17
|
+
.filter((entry) => entry.isDirectory() && fs.existsSync(path.join(sourceRoot, entry.name, 'SKILL.md')))
|
|
18
|
+
.map((entry) => entry.name);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** 各家 AI 助手的技能目录;--all 时追加 Claude/Cursor 的专属目录 */
|
|
22
|
+
function skillTargetDirs({ all = false, home = os.homedir() } = {}) {
|
|
23
|
+
const dirs = [path.join(home, '.agents', 'skills')];
|
|
24
|
+
if (all) {
|
|
25
|
+
dirs.push(path.join(home, '.claude', 'skills'));
|
|
26
|
+
dirs.push(path.join(home, '.cursor', 'skills'));
|
|
27
|
+
}
|
|
28
|
+
return dirs;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function isLink(p) {
|
|
32
|
+
try {
|
|
33
|
+
return fs.lstatSync(p).isSymbolicLink();
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function copyDir(src, dest) {
|
|
40
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
41
|
+
for (const name of fs.readdirSync(src)) {
|
|
42
|
+
const s = path.join(src, name);
|
|
43
|
+
const d = path.join(dest, name);
|
|
44
|
+
if (fs.statSync(s).isDirectory()) {
|
|
45
|
+
copyDir(s, d);
|
|
46
|
+
} else {
|
|
47
|
+
fs.copyFileSync(s, d);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** 安装单个技能目录,返回动作描述 */
|
|
53
|
+
function installOne(sourceRoot, destRoot, skillName) {
|
|
54
|
+
const src = path.join(sourceRoot, skillName);
|
|
55
|
+
const dest = path.join(destRoot, skillName);
|
|
56
|
+
if (fs.existsSync(dest) || isLink(dest)) {
|
|
57
|
+
if (!isLink(dest)) {
|
|
58
|
+
return `skipped(${dest} 已存在且不是本工具的链接,未覆盖)`;
|
|
59
|
+
}
|
|
60
|
+
// 旧链接重建,保证指向当前包位置
|
|
61
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
// Windows 用 junction 不需要管理员权限;其他系统用符号链接
|
|
65
|
+
fs.symlinkSync(src, dest, process.platform === 'win32' ? 'junction' : 'dir');
|
|
66
|
+
return `linked(升级自动更新)`;
|
|
67
|
+
} catch (e) {
|
|
68
|
+
copyDir(src, dest);
|
|
69
|
+
return `copied(降级为复制,升级后需重新安装技能)`;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 安装全部官方技能。返回每个目标目录的安装结果:
|
|
75
|
+
* [{ dir, skills: [{ name, action }] }]
|
|
76
|
+
*/
|
|
77
|
+
function installSkills({ all = false, home = os.homedir() } = {}) {
|
|
78
|
+
const sourceRoot = packageSkillsRoot();
|
|
79
|
+
const names = packagedSkillNames(sourceRoot);
|
|
80
|
+
return skillTargetDirs({ all, home }).map((dir) => {
|
|
81
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
82
|
+
return {
|
|
83
|
+
dir,
|
|
84
|
+
skills: names.map((name) => ({ name, action: installOne(sourceRoot, dir, name) })),
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = { packagedSkillNames, installSkills };
|
package/cli/table.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// 表格输出:无第三方依赖的简易对齐表格,供人类可读输出。
|
|
2
|
+
function printTable(rows, columns) {
|
|
3
|
+
if (!rows || !rows.length) {
|
|
4
|
+
console.log('(无数据)');
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const headers = columns.map((c) => c.label);
|
|
8
|
+
const lines = rows.map((row) => columns.map((c) => stringify(row[c.field])));
|
|
9
|
+
const widths = headers.map((h, i) => Math.max(displayWidth(h), ...lines.map((line) => displayWidth(line[i]))));
|
|
10
|
+
|
|
11
|
+
const print = (cells) => {
|
|
12
|
+
console.log(cells.map((cell, i) => pad(cell, widths[i])).join(' '));
|
|
13
|
+
};
|
|
14
|
+
print(headers);
|
|
15
|
+
console.log(widths.map((w) => '-'.repeat(w)).join(' '));
|
|
16
|
+
lines.forEach(print);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** 中文字符按 2 列宽计算,保证对齐 */
|
|
20
|
+
function displayWidth(text) {
|
|
21
|
+
let width = 0;
|
|
22
|
+
for (const ch of String(text)) {
|
|
23
|
+
width += ch.charCodeAt(0) > 0xff ? 2 : 1;
|
|
24
|
+
}
|
|
25
|
+
return width;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function pad(text, width) {
|
|
29
|
+
const padding = width - displayWidth(text);
|
|
30
|
+
return text + ' '.repeat(Math.max(0, padding));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function stringify(value) {
|
|
34
|
+
if (value === null || value === undefined) {
|
|
35
|
+
return '-';
|
|
36
|
+
}
|
|
37
|
+
if (Array.isArray(value)) {
|
|
38
|
+
return value.join(',');
|
|
39
|
+
}
|
|
40
|
+
return String(value);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = { printTable };
|