@dtd-dev/agent-kb 0.1.0 → 0.1.1
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 +3 -1
- package/bin/cli.js +83 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,7 +36,9 @@ Không cài global, không cần clone. Zero-dependency nên `npx` chạy tức
|
|
|
36
36
|
| `help` | Trợ giúp |
|
|
37
37
|
|
|
38
38
|
Chạy tương tác sẽ hỏi: **tên dự án, backend, database, frontend, CI/CD, lệnh deploy, tool phụ**
|
|
39
|
-
(Enter để giữ gợi ý). agent-kb **tự đọc `package.json`/`go.mod`/… để gợi ý stack & database sẵn
|
|
39
|
+
(Enter để giữ gợi ý). agent-kb **tự đọc `package.json`/`go.mod`/… để gợi ý stack & database sẵn**
|
|
40
|
+
— quét cả **thư mục con tới 3 cấp** nên hỗ trợ **monorepo** (vd `apps/web`, `services/api`). Nếu
|
|
41
|
+
không thấy manifest nào, nó **báo rõ** và để bạn nhập tay (hoặc dùng cờ `--backend/--frontend/--database`).
|
|
40
42
|
Các phần còn lại (cache, state, UI lib, container, URL môi trường, rollback…) là placeholder
|
|
41
43
|
`<!-- vd: ... -->` trong file để bạn điền tay sau.
|
|
42
44
|
|
package/bin/cli.js
CHANGED
|
@@ -167,38 +167,86 @@ function substituteTokens(values) {
|
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
170
|
+
// Thư mục rác/sinh ra — không quét để khỏi nhận diện nhầm & cho nhanh.
|
|
171
|
+
const IGNORE_DIRS = new Set([
|
|
172
|
+
"node_modules", ".git", ".ai", ".claude", "dist", "build", "out",
|
|
173
|
+
".next", ".nuxt", "coverage", "vendor", "target", ".gradle", ".venv", "venv", "__pycache__",
|
|
174
|
+
]);
|
|
175
|
+
const MANIFEST_NAMES = [
|
|
176
|
+
"package.json", "go.mod", "requirements.txt", "pyproject.toml", "Pipfile",
|
|
177
|
+
"pom.xml", "build.gradle", "build.gradle.kts", "Cargo.toml", "composer.json",
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
// Tìm các thư mục có manifest, quét tối đa maxDepth cấp từ root (bỏ thư mục rác/dotdir).
|
|
181
|
+
function findProjectRoots(root, maxDepth) {
|
|
182
|
+
const roots = [];
|
|
183
|
+
const walk = (dir, depth) => {
|
|
184
|
+
let entries;
|
|
185
|
+
try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }
|
|
186
|
+
if (entries.some((e) => e.isFile() && MANIFEST_NAMES.includes(e.name))) roots.push(dir);
|
|
187
|
+
if (depth >= maxDepth) return;
|
|
188
|
+
for (const e of entries) {
|
|
189
|
+
if (e.isDirectory() && !e.name.startsWith(".") && !IGNORE_DIRS.has(e.name)) {
|
|
190
|
+
walk(path.join(dir, e.name), depth + 1);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
175
193
|
};
|
|
194
|
+
walk(root, 0);
|
|
195
|
+
return roots;
|
|
196
|
+
}
|
|
176
197
|
|
|
177
|
-
|
|
198
|
+
// Nhận diện stack trong MỘT thư mục, gộp vào `out` (chỉ điền chỗ còn trống → root thắng subfolder).
|
|
199
|
+
function detectInDir(dir, out, addStack) {
|
|
200
|
+
const exists = (f) => fs.existsSync(path.join(dir, f));
|
|
201
|
+
const pkg = readJSONSafe(path.join(dir, "package.json"));
|
|
178
202
|
if (pkg) {
|
|
179
203
|
const deps = Object.assign({}, pkg.dependencies, pkg.devDependencies);
|
|
180
204
|
const has = (n) => Object.prototype.hasOwnProperty.call(deps, n);
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
else if (has("
|
|
184
|
-
else if (has("
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
else if (has("
|
|
189
|
-
else if (
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
205
|
+
let fe = null, be = null;
|
|
206
|
+
if (has("next")) { fe = "Next.js + React"; addStack("react"); }
|
|
207
|
+
else if (has("react")) { fe = "React" + (has("vite") ? " + Vite" : ""); addStack("react"); }
|
|
208
|
+
else if (has("vue")) fe = "Vue";
|
|
209
|
+
else if (has("svelte") || has("@sveltejs/kit")) fe = "Svelte";
|
|
210
|
+
|
|
211
|
+
if (has("@nestjs/core")) { be = "Node.js + NestJS"; addStack("node"); }
|
|
212
|
+
else if (has("express")) { be = "Node.js + Express"; addStack("node"); }
|
|
213
|
+
else if (has("fastify")) { be = "Node.js + Fastify"; addStack("node"); }
|
|
214
|
+
else if (!fe) { out._node = true; addStack("node"); } // Node "trơn": ưu tiên thấp nhất, quyết ở cuối
|
|
215
|
+
|
|
216
|
+
if (fe && !out.frontend) out.frontend = fe;
|
|
217
|
+
if (be && !out.backend) out.backend = be;
|
|
218
|
+
|
|
219
|
+
if (!out.database) {
|
|
220
|
+
if (has("pg") || has("postgres") || has("postgresql")) out.database = "PostgreSQL";
|
|
221
|
+
else if (has("mysql") || has("mysql2")) out.database = "MySQL";
|
|
222
|
+
else if (has("mongoose") || has("mongodb")) out.database = "MongoDB";
|
|
223
|
+
else if (has("firebase") || has("firebase-admin")) out.database = "Firebase/Firestore";
|
|
224
|
+
}
|
|
225
|
+
if ((has("redis") || has("ioredis")) && !(out.database || "").includes("Redis")) {
|
|
226
|
+
out.database = out.database ? out.database + " + Redis" : "Redis";
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (exists("go.mod")) { out.backend = out.backend || "Go"; addStack("go"); }
|
|
230
|
+
if (exists("requirements.txt") || exists("pyproject.toml") || exists("Pipfile")) { out.backend = out.backend || "Python"; addStack("python"); }
|
|
231
|
+
if (exists("pom.xml") || exists("build.gradle") || exists("build.gradle.kts")) { out.backend = out.backend || "Java"; addStack("java"); }
|
|
232
|
+
if (exists("Cargo.toml")) { out.backend = out.backend || "Rust"; addStack("rust"); }
|
|
233
|
+
if (exists("composer.json")) { out.backend = out.backend || "PHP"; addStack("php"); }
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Đọc dự án để gợi ý stack — chỉ đọc file, không đổi gì. Quét cả thư mục con (monorepo).
|
|
237
|
+
function detectStack() {
|
|
238
|
+
const out = { backend: null, frontend: null, database: null, cicd: null, stacks: [], roots: [], _node: false };
|
|
239
|
+
const addStack = (s) => {
|
|
240
|
+
if (!out.stacks.includes(s)) out.stacks.push(s);
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// Root (CWD) trước, rồi tới subfolder nông→sâu, để stack của thư mục gốc được ưu tiên.
|
|
244
|
+
const roots = findProjectRoots(CWD, 3).sort((a, b) => a.length - b.length);
|
|
245
|
+
for (const dir of roots) {
|
|
246
|
+
detectInDir(dir, out, addStack);
|
|
247
|
+
out.roots.push(path.relative(CWD, dir) || ".");
|
|
248
|
+
}
|
|
249
|
+
if (!out.backend && out._node) out.backend = "Node.js"; // fallback Node sau khi đã xét hết
|
|
202
250
|
|
|
203
251
|
if (fs.existsSync(path.join(CWD, ".github", "workflows"))) out.cicd = "GitHub Actions";
|
|
204
252
|
else if (hasFile(".gitlab-ci.yml")) out.cicd = "GitLab CI";
|
|
@@ -259,6 +307,14 @@ async function init() {
|
|
|
259
307
|
|
|
260
308
|
if (det.backend || det.frontend || det.cicd) {
|
|
261
309
|
console.log(`\nℹ Nhận diện stack: ${[det.backend, det.frontend, det.database, det.cicd].filter(Boolean).join(" · ") || "—"}`);
|
|
310
|
+
if (det.roots.length > 1 || (det.roots.length === 1 && det.roots[0] !== ".")) {
|
|
311
|
+
console.log(` (manifest tại: ${det.roots.join(", ")})`);
|
|
312
|
+
}
|
|
313
|
+
} else {
|
|
314
|
+
console.log("\n⚠ Không tự nhận diện được stack — không thấy manifest");
|
|
315
|
+
console.log(" (package.json / go.mod / requirements.txt / pyproject.toml / pom.xml / Cargo.toml / composer.json)");
|
|
316
|
+
console.log(" trong thư mục này hay các thư mục con (quét tối đa 3 cấp).");
|
|
317
|
+
console.log(" → Chạy ở đúng thư mục gốc dự án, hoặc nhập tay / dùng cờ --backend --frontend --database.");
|
|
262
318
|
}
|
|
263
319
|
|
|
264
320
|
if (!YES) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dtd-dev/agent-kb",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Bộ agent skill chuẩn hoá cho doanh nghiệp: scaffold knowledge base .ai/ tiết kiệm token, tăng độ chính xác khi viết code, và cá nhân hoá theo nghiệp vụ công ty để tái dùng cho nhiều dự án cùng nghiệp vụ (AGENTS.md, CLAUDE.md, GEMINI.md, Copilot).",
|
|
5
5
|
"bin": {
|
|
6
6
|
"agent-kb": "bin/cli.js"
|