@liuhange/dsh-data-inventory 1.0.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 +16 -0
- package/lib/index.js +144 -0
- package/lib/invariant.js +5 -0
- package/lib/types/assetListGenerator.d.ts +7 -0
- package/lib/types/directoryScanner.d.ts +9 -0
- package/lib/types/index.d.ts +5 -0
- package/lib/types/invariant.d.ts +3 -0
- package/lib/types/valueAssessor.d.ts +10 -0
- package/package.json +23 -0
package/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-data-inventory
|
|
2
|
+
|
|
3
|
+
Data inventory plugin for DeepSeek Harness. Directory scanning, value assessment, asset list generation.
|
|
4
|
+
|
|
5
|
+
## Tool: inventory_data
|
|
6
|
+
|
|
7
|
+
- **Parameters**: `directory` (required)
|
|
8
|
+
- **Output**: Inventory report with Markdown asset table (filename/size/type/value/description)
|
|
9
|
+
|
|
10
|
+
## Business Rules
|
|
11
|
+
|
|
12
|
+
Value assessment rules (keywords, scores, labels) are read from `config/business-rules.json`.
|
|
13
|
+
|
|
14
|
+
## Known Limitations and Deferred Work
|
|
15
|
+
|
|
16
|
+
- Directory scanning is non-recursive; only top-level data files are inventoried
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { AuditLogger, BusinessRulesLoader, PathValidator, ReportGenerator } from "@deepseek-ai/dsh-data-asset-shared";
|
|
5
|
+
//#region lib/types/directoryScanner.js
|
|
6
|
+
const SUPPORTED_EXTENSIONS = [
|
|
7
|
+
"csv",
|
|
8
|
+
"xlsx",
|
|
9
|
+
"json",
|
|
10
|
+
"txt"
|
|
11
|
+
];
|
|
12
|
+
var DirectoryScanner = class {
|
|
13
|
+
scan(directory) {
|
|
14
|
+
const files = [];
|
|
15
|
+
let skippedFiles = 0;
|
|
16
|
+
if (!fs.existsSync(directory)) return {
|
|
17
|
+
files,
|
|
18
|
+
skippedFiles
|
|
19
|
+
};
|
|
20
|
+
const entries = fs.readdirSync(directory);
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
const fullPath = path.join(directory, entry);
|
|
23
|
+
try {
|
|
24
|
+
const stats = fs.statSync(fullPath);
|
|
25
|
+
if (!stats.isFile()) continue;
|
|
26
|
+
const ext = path.extname(entry).toLowerCase().slice(1);
|
|
27
|
+
if (!SUPPORTED_EXTENSIONS.includes(ext)) continue;
|
|
28
|
+
files.push({
|
|
29
|
+
fileName: entry,
|
|
30
|
+
fullPath,
|
|
31
|
+
size: stats.size,
|
|
32
|
+
format: ext
|
|
33
|
+
});
|
|
34
|
+
} catch {
|
|
35
|
+
skippedFiles++;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
files,
|
|
40
|
+
skippedFiles
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region lib/types/valueAssessor.js
|
|
46
|
+
var ValueAssessor = class {
|
|
47
|
+
assess(fileName, rules) {
|
|
48
|
+
const ruleLevels = [
|
|
49
|
+
rules.highValue,
|
|
50
|
+
rules.mediumValue,
|
|
51
|
+
rules.lowValue
|
|
52
|
+
];
|
|
53
|
+
for (const rule of ruleLevels) for (const keyword of rule.keywords) if (fileName.includes(keyword)) return {
|
|
54
|
+
stars: rule.score,
|
|
55
|
+
label: rule.label,
|
|
56
|
+
recommendation: rule.recommendation
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
stars: rules.defaultValue.score,
|
|
60
|
+
label: rules.defaultValue.label,
|
|
61
|
+
recommendation: rules.defaultValue.recommendation
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region lib/types/assetListGenerator.js
|
|
67
|
+
var AssetListGenerator = class {
|
|
68
|
+
generate(files, valueAssessor, valueRules) {
|
|
69
|
+
return files.map((file) => {
|
|
70
|
+
const assessment = valueAssessor.assess(file.fileName, valueRules);
|
|
71
|
+
return {
|
|
72
|
+
fileName: file.fileName,
|
|
73
|
+
size: this.humanReadableSize(file.size),
|
|
74
|
+
type: file.format,
|
|
75
|
+
valueAssessment: assessment.label,
|
|
76
|
+
description: assessment.recommendation
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
humanReadableSize(bytes) {
|
|
81
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
82
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
83
|
+
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
84
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region lib/types/index.js
|
|
89
|
+
const name = "data-inventory";
|
|
90
|
+
const inject = ["tools"];
|
|
91
|
+
function apply(ctx) {
|
|
92
|
+
const loader = new BusinessRulesLoader();
|
|
93
|
+
const reportGenerator = new ReportGenerator();
|
|
94
|
+
const pathValidator = new PathValidator();
|
|
95
|
+
const auditLogger = new AuditLogger();
|
|
96
|
+
const directoryScanner = new DirectoryScanner();
|
|
97
|
+
const valueAssessor = new ValueAssessor();
|
|
98
|
+
const assetListGenerator = new AssetListGenerator();
|
|
99
|
+
ctx.tools.register(defineTool({
|
|
100
|
+
name: "inventory_data",
|
|
101
|
+
description: "盘点数据资产,生成资产清单和价值评估",
|
|
102
|
+
parameters: { directory: {
|
|
103
|
+
type: "string",
|
|
104
|
+
required: true,
|
|
105
|
+
description: "待盘点的目录路径"
|
|
106
|
+
} },
|
|
107
|
+
output: {
|
|
108
|
+
schema: { type: "string" },
|
|
109
|
+
render: (_args, value) => [{
|
|
110
|
+
type: "text",
|
|
111
|
+
text: value
|
|
112
|
+
}]
|
|
113
|
+
},
|
|
114
|
+
async execute(args) {
|
|
115
|
+
const { config } = loader.load();
|
|
116
|
+
const workingDir = process.cwd();
|
|
117
|
+
try {
|
|
118
|
+
pathValidator.validateDirectory(args.directory, workingDir);
|
|
119
|
+
} catch {
|
|
120
|
+
return `错误:路径不合法 - ${args.directory}`;
|
|
121
|
+
}
|
|
122
|
+
const dir = path.resolve(args.directory);
|
|
123
|
+
if (!fs.existsSync(dir)) return `错误:目录不存在 - ${dir}`;
|
|
124
|
+
const scanResult = directoryScanner.scan(dir);
|
|
125
|
+
const assetItems = assetListGenerator.generate(scanResult.files, valueAssessor, config.valueAssessment);
|
|
126
|
+
const report = reportGenerator.generateInventoryReport({
|
|
127
|
+
directory: dir,
|
|
128
|
+
fileCount: scanResult.files.length,
|
|
129
|
+
assetItems
|
|
130
|
+
});
|
|
131
|
+
auditLogger.log({
|
|
132
|
+
pluginName: "data-inventory",
|
|
133
|
+
operation: "inventory_data",
|
|
134
|
+
inputPath: dir,
|
|
135
|
+
outputPath: "-",
|
|
136
|
+
result: "SUCCESS"
|
|
137
|
+
});
|
|
138
|
+
return report;
|
|
139
|
+
}
|
|
140
|
+
}));
|
|
141
|
+
console.log("[data-inventory] 盘点插件已加载");
|
|
142
|
+
}
|
|
143
|
+
//#endregion
|
|
144
|
+
export { apply, inject, name };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AssetItem, DataFile } from '@deepseek-ai/dsh-data-asset-shared';
|
|
2
|
+
import type { ValueAssessor } from './valueAssessor.js';
|
|
3
|
+
export declare class AssetListGenerator {
|
|
4
|
+
generate(files: DataFile[], valueAssessor: ValueAssessor, valueRules: import('@deepseek-ai/dsh-data-asset-shared').ValueAssessmentRules): AssetItem[];
|
|
5
|
+
humanReadableSize(bytes: number): string;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=assetListGenerator.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DataFile } from '@deepseek-ai/dsh-data-asset-shared';
|
|
2
|
+
export interface DirectoryScanResult {
|
|
3
|
+
files: DataFile[];
|
|
4
|
+
skippedFiles: number;
|
|
5
|
+
}
|
|
6
|
+
export declare class DirectoryScanner {
|
|
7
|
+
scan(directory: string): DirectoryScanResult;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=directoryScanner.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ValueAssessmentRules } from '@deepseek-ai/dsh-data-asset-shared';
|
|
2
|
+
export interface ValueAssessResult {
|
|
3
|
+
stars: number;
|
|
4
|
+
label: string;
|
|
5
|
+
recommendation: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class ValueAssessor {
|
|
8
|
+
assess(fileName: string, rules: ValueAssessmentRules): ValueAssessResult;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=valueAssessor.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@liuhange/dsh-data-inventory",
|
|
3
|
+
"description": "Data inventory plugin: directory scanning, value assessment, asset list generation",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"publishConfig": { "access": "public" },
|
|
6
|
+
"repository": { "type": "git", "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", "directory": "packages/data-asset/data-inventory" },
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "lib/index.js",
|
|
9
|
+
"types": "lib/types/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": { "types": "./lib/types/index.d.ts", "default": "./lib/index.js" },
|
|
12
|
+
"./invariant": { "types": "./lib/types/invariant.d.ts", "default": "./lib/invariant.js" },
|
|
13
|
+
"./src/*": "./src/*",
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"files": ["lib/index.js", "lib/invariant.js", "lib/types/**/*.d.ts"],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"@deepseek-ai/cordis": "^0.1.0",
|
|
20
|
+
"@deepseek-ai/dsh-tools": "^0.1.0",
|
|
21
|
+
"@liuhange/dsh-data-asset-shared": "^1.0.0"
|
|
22
|
+
}
|
|
23
|
+
}
|