add-coder 0.3.12 → 0.3.14
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.
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# DPS 评分全参数 —— caijuehub 驱动,后续调优只需改此 TOML
|
|
2
|
+
|
|
3
|
+
# ═══════════════ 维度一:语义相关性 ═══════════════
|
|
4
|
+
[semantic]
|
|
5
|
+
# 子权重:Jaccard Plan↔Specs / Cosine Plan↔Specs / Jaccard Plan↔Review / Cosine Plan↔Review
|
|
6
|
+
weights = [0.35, 0.45, 0.08, 0.12]
|
|
7
|
+
# Review 缺失时的惩罚系数(0.0=不惩罚,0.4=打六折,即得分×0.6)
|
|
8
|
+
missing_review_penalty = 0.0
|
|
9
|
+
|
|
10
|
+
# ═══════════════ 维度二:信息熵匹配 ═══════════════
|
|
11
|
+
[entropy]
|
|
12
|
+
# 熵差距乘数(entropyGap × multiplier,越小越不敏感)
|
|
13
|
+
gap_multiplier = 10
|
|
14
|
+
# Deng 不确定性惩罚:每个标记扣分,上限
|
|
15
|
+
deng_per_marker = 0.05
|
|
16
|
+
deng_max_penalty = 0.3
|
|
17
|
+
# Specs 缺失时的熵差距(无 Specs 时 gap 设为此值)
|
|
18
|
+
missing_specs_gap = 10
|
|
19
|
+
|
|
20
|
+
# ═══════════════ 维度三:CPM 关键路径 ═══════════════
|
|
21
|
+
[cpm]
|
|
22
|
+
# 子权重:原子化 / 注意力匹配 / 依赖完整性
|
|
23
|
+
sub_weights = [0.4, 0.35, 0.25]
|
|
24
|
+
# 业务原子化:Jaccard 重叠乘数(overlap × multiplier → penalty)
|
|
25
|
+
overlap_multiplier = 2
|
|
26
|
+
# Task 数超过此阈值时随机采样配对(避免 O(N²) 爆炸,0 = 不限制)
|
|
27
|
+
max_task_pairs = 200
|
|
28
|
+
# 注意力匹配:文件/Task 阈值
|
|
29
|
+
file_per_task_low = 3 # ≤3 → 100
|
|
30
|
+
file_per_task_mid = 5 # 3~5 → 70,>5 → 40
|
|
31
|
+
# 注意力匹配:描述熵阈值(bits)
|
|
32
|
+
entropy_low = 6 # <6 → 100
|
|
33
|
+
entropy_mid = 8 # 6~8 → 75,>8 → 50
|
|
34
|
+
# 注意力匹配:子权重(文件耦合 / 描述熵)
|
|
35
|
+
attention_weights = [0.5, 0.5]
|
|
36
|
+
# 依赖完整性:子权重(覆盖率 / Task Dependencies 章节存在)
|
|
37
|
+
dep_weights = [0.6, 0.4]
|
|
38
|
+
|
|
39
|
+
# ═══════════════ 维度四:结构完整度 ═══════════════
|
|
40
|
+
[structure]
|
|
41
|
+
# 扣分项
|
|
42
|
+
placeholder_penalty = 15
|
|
43
|
+
missing_specs_penalty = 30
|
|
44
|
+
missing_tasks_penalty = 15
|
|
45
|
+
missing_checklist_penalty = 15
|
|
46
|
+
# 子权重:结构分 / 回流分
|
|
47
|
+
sub_weights = [0.6, 0.4]
|
|
48
|
+
|
|
49
|
+
# ═══════════════ FFT 自适应权重 ═══════════════
|
|
50
|
+
[fft]
|
|
51
|
+
cold_start_threshold = 5
|
|
52
|
+
history_limit = 50
|
|
53
|
+
default_weights = [0.25, 0.25, 0.25, 0.25]
|
|
54
|
+
|
|
55
|
+
# ═══════════════ DPS 阈值 ═══════════════
|
|
56
|
+
[thresholds]
|
|
57
|
+
pass = 80
|
|
58
|
+
warn = 65
|
|
59
|
+
|
|
60
|
+
# ═══════════════ Embedding 模型(@xenova/transformers ONNX)═══════════════
|
|
61
|
+
[embedding]
|
|
62
|
+
# 首次 DPS 调用自动下载并缓存到本地 ~/.cache/huggingface/hub/
|
|
63
|
+
# 可选值(注释掉的前两个是备选方案):
|
|
64
|
+
# "Xenova/all-MiniLM-L6-v2" 英文为主,80MB,速度快
|
|
65
|
+
# "Xenova/multilingual-e5-small" 多语言,118MB,平衡选择
|
|
66
|
+
model = "Xenova/bge-small-zh-v1.5"
|
package/dist/index.js
CHANGED
|
@@ -400,7 +400,7 @@ function diffPrisma(basePath, targetPath) {
|
|
|
400
400
|
}
|
|
401
401
|
|
|
402
402
|
// src/core/renderer.ts
|
|
403
|
-
import { readFileSync as readFileSync4, readdirSync, statSync } from "fs";
|
|
403
|
+
import { readFileSync as readFileSync4, readdirSync, statSync, existsSync as existsSync5 } from "fs";
|
|
404
404
|
import { join as join4, relative, dirname as dirname2 } from "path";
|
|
405
405
|
import { fileURLToPath } from "url";
|
|
406
406
|
import { parse } from "smol-toml";
|
|
@@ -420,10 +420,15 @@ var PLACEHOLDERS = {
|
|
|
420
420
|
};
|
|
421
421
|
function loadDpsThresholds() {
|
|
422
422
|
try {
|
|
423
|
-
const
|
|
424
|
-
__dirname,
|
|
425
|
-
"
|
|
426
|
-
|
|
423
|
+
const candidates = [
|
|
424
|
+
join4(__dirname, "../caijuehub/dps-scoring-rules.toml"),
|
|
425
|
+
join4(__dirname, "caijuehub/dps-scoring-rules.toml"),
|
|
426
|
+
join4(__dirname, "../../caijuehub/dps-scoring-rules.toml")
|
|
427
|
+
];
|
|
428
|
+
const tomlPath = candidates.find(existsSync5);
|
|
429
|
+
if (!tomlPath) {
|
|
430
|
+
throw new Error(`\u5019\u9009\u8DEF\u5F84\u5747\u4E0D\u5B58\u5728: ${candidates.join(" | ")}`);
|
|
431
|
+
}
|
|
427
432
|
const doc = parse(readFileSync4(tomlPath, "utf-8"));
|
|
428
433
|
if (doc.thresholds && typeof doc.thresholds.pass === "number") {
|
|
429
434
|
return {
|
|
@@ -539,7 +544,7 @@ function renderAdapter5(config, targetDir, dryRun, magicDir) {
|
|
|
539
544
|
|
|
540
545
|
// src/lib/utils.ts
|
|
541
546
|
import { createInterface as createInterface2 } from "readline";
|
|
542
|
-
import { existsSync as
|
|
547
|
+
import { existsSync as existsSync6 } from "fs";
|
|
543
548
|
import { resolve as resolve2 } from "path";
|
|
544
549
|
function ask(q) {
|
|
545
550
|
const rl = createInterface2({ input: process.stdin, output: process.stdout });
|
|
@@ -551,7 +556,7 @@ function ask(q) {
|
|
|
551
556
|
});
|
|
552
557
|
}
|
|
553
558
|
function detectPm(projectRoot) {
|
|
554
|
-
return
|
|
559
|
+
return existsSync6(resolve2(projectRoot, "pnpm-lock.yaml")) ? "pnpm" : "npm";
|
|
555
560
|
}
|
|
556
561
|
|
|
557
562
|
// src/cli/prisma-injector.ts
|
|
@@ -560,7 +565,7 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
560
565
|
|
|
561
566
|
// src/caijuehub/strategies/prisma.strategy.ts
|
|
562
567
|
import { spawnSync } from "child_process";
|
|
563
|
-
import { copyFileSync, existsSync as
|
|
568
|
+
import { copyFileSync, existsSync as existsSync7, readFileSync as readFileSync5, unlinkSync, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
564
569
|
import { resolve as resolve3 } from "path";
|
|
565
570
|
var PRISMA_CONFIG = {
|
|
566
571
|
onMissing: "ask",
|
|
@@ -613,10 +618,10 @@ function runPrismaInit(projectRoot, provider, schemaPath) {
|
|
|
613
618
|
stdio: "inherit",
|
|
614
619
|
shell: false
|
|
615
620
|
});
|
|
616
|
-
if (initResult.status !== 0 || !
|
|
621
|
+
if (initResult.status !== 0 || !existsSync7(schemaPath)) {
|
|
617
622
|
console.log("prisma init \u5931\u8D25\uFF0C\u624B\u52A8\u521B\u5EFA schema.prisma ...");
|
|
618
623
|
const prismaDir = resolve3(projectRoot, "prisma");
|
|
619
|
-
if (!
|
|
624
|
+
if (!existsSync7(prismaDir)) mkdirSync2(prismaDir, { recursive: true });
|
|
620
625
|
const content = `generator client {
|
|
621
626
|
provider = "prisma-client-js"
|
|
622
627
|
}
|
|
@@ -627,7 +632,7 @@ datasource db {
|
|
|
627
632
|
`;
|
|
628
633
|
writeFileSync2(schemaPath, content, "utf-8");
|
|
629
634
|
const devEnvPath = resolve3(projectRoot, ".env.development");
|
|
630
|
-
if (!
|
|
635
|
+
if (!existsSync7(devEnvPath)) {
|
|
631
636
|
const defaultUrl = provider === "sqlite" ? 'DATABASE_URL="file:./data/dev.db"' : '# \u8BF7\u7F16\u8F91\u4E3A\u4F60\u7684\u6570\u636E\u5E93\u8FDE\u63A5\u4FE1\u606F\nDATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DB?schema=public"';
|
|
632
637
|
writeFileSync2(devEnvPath, defaultUrl + "\n", "utf-8");
|
|
633
638
|
console.log("\u5DF2\u521B\u5EFA .env.development");
|
|
@@ -639,16 +644,16 @@ datasource db {
|
|
|
639
644
|
function postInitSetup(projectRoot, schemaPath, addPrismaTemplate, destPath) {
|
|
640
645
|
const envPath = resolve3(projectRoot, ".env");
|
|
641
646
|
const devEnvPath = resolve3(projectRoot, ".env.development");
|
|
642
|
-
if (
|
|
647
|
+
if (existsSync7(envPath)) {
|
|
643
648
|
const envContent = readFileSync5(envPath, "utf-8");
|
|
644
649
|
const dbUrl = envContent.match(/DATABASE_URL=.*/);
|
|
645
650
|
if (dbUrl) {
|
|
646
|
-
const existing =
|
|
651
|
+
const existing = existsSync7(devEnvPath) ? readFileSync5(devEnvPath, "utf-8") : "";
|
|
647
652
|
if (!existing.includes("DATABASE_URL=")) {
|
|
648
653
|
writeFileSync2(devEnvPath, `${existing}${existing ? "\n" : ""}${dbUrl[0]}
|
|
649
654
|
`, "utf-8");
|
|
650
655
|
}
|
|
651
|
-
if (
|
|
656
|
+
if (existsSync7(envPath)) unlinkSync(envPath);
|
|
652
657
|
console.log("\u5DF2\u5C06 DATABASE_URL \u8FC1\u79FB\u5230 .env.development");
|
|
653
658
|
}
|
|
654
659
|
}
|
|
@@ -661,7 +666,7 @@ async function injectPrisma(projectRoot, addPrismaTemplate, options = {}) {
|
|
|
661
666
|
const schemaPath = resolve3(prismaDir, "schema.prisma");
|
|
662
667
|
const destPath = resolve3(prismaDir, "add.prisma");
|
|
663
668
|
let justInited = false;
|
|
664
|
-
if (!
|
|
669
|
+
if (!existsSync7(prismaDir) || !existsSync7(schemaPath)) {
|
|
665
670
|
if (C.onMissing === "skip") {
|
|
666
671
|
console.log("\u8DF3\u8FC7\uFF1A\u7F3A\u5C11 Prisma");
|
|
667
672
|
return true;
|
|
@@ -680,7 +685,7 @@ async function injectPrisma(projectRoot, addPrismaTemplate, options = {}) {
|
|
|
680
685
|
postInitSetup(projectRoot, schemaPath, addPrismaTemplate, destPath);
|
|
681
686
|
justInited = true;
|
|
682
687
|
}
|
|
683
|
-
if (
|
|
688
|
+
if (existsSync7(destPath) && !justInited) {
|
|
684
689
|
if (options.dryRun) {
|
|
685
690
|
console.log("[dry-run] \u5DF2\u6709 add.prisma");
|
|
686
691
|
return true;
|
|
@@ -753,7 +758,7 @@ async function injectPrisma2(projectRoot, options = {}) {
|
|
|
753
758
|
}
|
|
754
759
|
|
|
755
760
|
// src/cli/commands/init.ts
|
|
756
|
-
import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as
|
|
761
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as existsSync8, mkdirSync as mkdirSync3, copyFileSync as copyFileSync2, readdirSync as readdirSync2 } from "fs";
|
|
757
762
|
import { createHash } from "crypto";
|
|
758
763
|
import { resolve as resolve5 } from "path";
|
|
759
764
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
@@ -933,13 +938,13 @@ main().catch((e) => { console.error(e); process.exit(1); });
|
|
|
933
938
|
console.log(`[dry-run] \u5C06\u5199\u5165 ${scriptPath}`);
|
|
934
939
|
return;
|
|
935
940
|
}
|
|
936
|
-
if (!
|
|
941
|
+
if (!existsSync8(scriptsDir)) mkdirSync3(scriptsDir, { recursive: true });
|
|
937
942
|
writeFileSync3(scriptPath, content, "utf-8");
|
|
938
943
|
console.log("\u5DF2\u751F\u6210 scripts/export-db.ts");
|
|
939
944
|
}
|
|
940
945
|
function injectDbExportScript(projectRoot, dryRun) {
|
|
941
946
|
const pkgPath = resolve5(projectRoot, "package.json");
|
|
942
|
-
if (!
|
|
947
|
+
if (!existsSync8(pkgPath)) return;
|
|
943
948
|
if (dryRun) {
|
|
944
949
|
console.log("[dry-run] \u5C06\u6CE8\u5165 db:export");
|
|
945
950
|
return;
|
|
@@ -974,13 +979,13 @@ function writeComposeEnv(ctx) {
|
|
|
974
979
|
if (!db.reuseExisting) {
|
|
975
980
|
const composeName = db.container === "podman" ? "podman-compose.add.yml" : "docker-compose.add.yml";
|
|
976
981
|
const composePath = resolve5(projectRoot, composeName);
|
|
977
|
-
if (!options.dryRun && (!
|
|
982
|
+
if (!options.dryRun && (!existsSync8(composePath) || options.force)) {
|
|
978
983
|
writeFileSync3(composePath, composeContent(config.projectName || "add-project"), "utf-8");
|
|
979
984
|
console.log(`\u5DF2\u521B\u5EFA ${composeName}`);
|
|
980
985
|
}
|
|
981
986
|
}
|
|
982
987
|
const devEnvPath = resolve5(projectRoot, ".env.development");
|
|
983
|
-
if (!options.dryRun &&
|
|
988
|
+
if (!options.dryRun && existsSync8(devEnvPath)) {
|
|
984
989
|
const existing = readFileSync6(devEnvPath, "utf-8");
|
|
985
990
|
if (!/^DATABASE_USER=/m.test(existing)) {
|
|
986
991
|
writeFileSync3(devEnvPath, existing + `
|
|
@@ -1021,7 +1026,7 @@ async function renderAndWrite(ctx) {
|
|
|
1021
1026
|
}
|
|
1022
1027
|
for (const d of [".add", magicDir]) {
|
|
1023
1028
|
const reviewsDir = resolve5(projectRoot, d, "reviews");
|
|
1024
|
-
if (!
|
|
1029
|
+
if (!existsSync8(reviewsDir)) {
|
|
1025
1030
|
if (dry) {
|
|
1026
1031
|
console.log(`[dry-run] \u5C06\u521B\u5EFA ${reviewsDir}/`);
|
|
1027
1032
|
} else {
|
|
@@ -1065,7 +1070,7 @@ async function deployDatabase(ctx) {
|
|
|
1065
1070
|
}
|
|
1066
1071
|
if (db.engine === "postgresql" && db.container === "manual") {
|
|
1067
1072
|
const dbScript = resolve5(projectRoot, magicDir, "scripts", "db-ensure.sh");
|
|
1068
|
-
if (
|
|
1073
|
+
if (existsSync8(dbScript)) spawnSync2("bash", [dbScript, "postgresql", "manual"], { cwd: projectRoot, stdio: "inherit" });
|
|
1069
1074
|
console.log([
|
|
1070
1075
|
"",
|
|
1071
1076
|
"\u2501".repeat(30),
|
|
@@ -1106,12 +1111,12 @@ function deployDocs(ctx) {
|
|
|
1106
1111
|
for (const d of ["00-\u9700\u6C42", "01-\u67B6\u6784", "02-\u89C4\u8303"]) {
|
|
1107
1112
|
const srcDir = resolve5(groundingSrc, d);
|
|
1108
1113
|
const destDir = resolve5(docsBase, d);
|
|
1109
|
-
if (!
|
|
1110
|
-
if (!
|
|
1114
|
+
if (!existsSync8(destDir)) mkdirSync3(destDir, { recursive: true });
|
|
1115
|
+
if (!existsSync8(srcDir)) continue;
|
|
1111
1116
|
for (const f of readdirSync2(srcDir)) {
|
|
1112
1117
|
const src = resolve5(srcDir, f);
|
|
1113
1118
|
const dest = resolve5(destDir, f);
|
|
1114
|
-
if (
|
|
1119
|
+
if (existsSync8(dest)) continue;
|
|
1115
1120
|
try {
|
|
1116
1121
|
copyFileSync2(src, dest);
|
|
1117
1122
|
} catch {
|
|
@@ -1139,7 +1144,7 @@ function finalize(ctx, result) {
|
|
|
1139
1144
|
}
|
|
1140
1145
|
|
|
1141
1146
|
// src/cli/commands/sync.ts
|
|
1142
|
-
import { existsSync as
|
|
1147
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4 } from "fs";
|
|
1143
1148
|
import { resolve as resolve6, dirname as dirname4 } from "path";
|
|
1144
1149
|
import { createHash as createHash2 } from "crypto";
|
|
1145
1150
|
|
|
@@ -1277,7 +1282,7 @@ async function syncCommand(options = {}) {
|
|
|
1277
1282
|
let sameCount = 0;
|
|
1278
1283
|
for (const [relPath, content] of candidates) {
|
|
1279
1284
|
const absPath = resolve6(projectRoot, relPath);
|
|
1280
|
-
if (!
|
|
1285
|
+
if (!existsSync9(absPath)) {
|
|
1281
1286
|
missingFiles.set(relPath, content);
|
|
1282
1287
|
} else if (establishBaseline) {
|
|
1283
1288
|
missingFiles.set(relPath, content);
|
|
@@ -1315,7 +1320,7 @@ async function syncCommand(options = {}) {
|
|
|
1315
1320
|
}
|
|
1316
1321
|
const missing = /* @__PURE__ */ new Map();
|
|
1317
1322
|
for (const [relPath, content] of allFiles) {
|
|
1318
|
-
if (!
|
|
1323
|
+
if (!existsSync9(resolve6(projectRoot, relPath))) {
|
|
1319
1324
|
missing.set(relPath, content);
|
|
1320
1325
|
}
|
|
1321
1326
|
}
|
|
@@ -1337,7 +1342,7 @@ async function syncCommand(options = {}) {
|
|
|
1337
1342
|
}
|
|
1338
1343
|
function printMigrateGuidance(targetPath, changed) {
|
|
1339
1344
|
const g = SYNC_PRISMA_CONFIG.POST_SYNC;
|
|
1340
|
-
const isManaged =
|
|
1345
|
+
const isManaged = existsSync9(resolve6(dirname4(targetPath), "migrations"));
|
|
1341
1346
|
const actions = isManaged ? g.MANAGED_ACTIONS : g.UNMANAGED_ACTIONS;
|
|
1342
1347
|
console.log(` \u25B6 \u5DF2\u5199\u5165 ${changed} \u5904\u53D8\u66F4\uFF0C${g.HEADER}`);
|
|
1343
1348
|
for (const a of actions) {
|
|
@@ -1361,7 +1366,7 @@ async function checkPrismaDiff(projectRoot, options) {
|
|
|
1361
1366
|
if (!options.patch) return;
|
|
1362
1367
|
const basePath = resolve6(projectRoot, SYNC_PRISMA_CONFIG.BASE_SCHEMA);
|
|
1363
1368
|
const targetPath = resolve6(projectRoot, SYNC_PRISMA_CONFIG.TARGET_PATTERN);
|
|
1364
|
-
if (!
|
|
1369
|
+
if (!existsSync9(basePath)) {
|
|
1365
1370
|
console.log(`
|
|
1366
1371
|
\u26A0\uFE0F \u57FA\u51C6 schema \u4E0D\u5B58\u5728: ${basePath}`);
|
|
1367
1372
|
console.log(` \u8BF7\u786E\u4FDD add-coder \u5DF2\u6B63\u786E\u5B89\u88C5\u3002`);
|
|
@@ -1373,7 +1378,7 @@ async function checkPrismaDiff(projectRoot, options) {
|
|
|
1373
1378
|
\u2705 Prisma schema \u4E0E add-coder \u6807\u51C6\u4E00\u81F4\uFF0C\u65E0\u9700\u540C\u6B65\u3002`);
|
|
1374
1379
|
return;
|
|
1375
1380
|
}
|
|
1376
|
-
const targetExists =
|
|
1381
|
+
const targetExists = existsSync9(targetPath);
|
|
1377
1382
|
let modifiedCount = 0;
|
|
1378
1383
|
console.log(`
|
|
1379
1384
|
\u26A0\uFE0F Prisma schema \u5DEE\u5F02\u68C0\u6D4B:`);
|
|
@@ -1560,13 +1565,12 @@ function injectFieldLines(targetPath, basePath, modelName, fieldKeys) {
|
|
|
1560
1565
|
const fieldName = key.split(":")[0];
|
|
1561
1566
|
const fieldLine = baseFields[fieldName];
|
|
1562
1567
|
if (!fieldLine) continue;
|
|
1563
|
-
|
|
1564
|
-
const modelRegex = new RegExp(`(model\\s+${modelName}\\s*\\{[^}]*?)\\n(\\s*\\})`, "m");
|
|
1568
|
+
const modelRegex = new RegExp(`(model\\s+${modelName}\\s*\\{)([^}]*?)(\\n\\s*\\})`, "m");
|
|
1565
1569
|
const m = content.match(modelRegex);
|
|
1566
1570
|
if (!m) continue;
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
$
|
|
1571
|
+
if (new RegExp(`^\\s*${fieldName}\\s+`, "m").test(m[2])) continue;
|
|
1572
|
+
content = content.replace(modelRegex, `$1$2
|
|
1573
|
+
${fieldLine}$3`);
|
|
1570
1574
|
count++;
|
|
1571
1575
|
}
|
|
1572
1576
|
if (count > 0) writeFileSync4(targetPath, content, "utf-8");
|
|
@@ -1591,7 +1595,7 @@ function overwriteFieldLines(targetPath, basePath, modelName, conflicts) {
|
|
|
1591
1595
|
}
|
|
1592
1596
|
|
|
1593
1597
|
// src/cli/commands/status.ts
|
|
1594
|
-
import { existsSync as
|
|
1598
|
+
import { existsSync as existsSync10 } from "fs";
|
|
1595
1599
|
import { resolve as resolve7 } from "path";
|
|
1596
1600
|
async function statusCommand() {
|
|
1597
1601
|
const projectRoot = process.cwd();
|
|
@@ -1601,7 +1605,7 @@ async function statusCommand() {
|
|
|
1601
1605
|
const missing = [];
|
|
1602
1606
|
const present = [];
|
|
1603
1607
|
for (const [relPath] of coreFiles) {
|
|
1604
|
-
if (
|
|
1608
|
+
if (existsSync10(resolve7(projectRoot, relPath))) {
|
|
1605
1609
|
present.push(relPath);
|
|
1606
1610
|
} else {
|
|
1607
1611
|
missing.push(relPath);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "add-coder",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.14",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "[codein2027](https://github.com/xiaomingming92/codein2027) - A complete scaffolding for building the ADD programming paradigm, the implementation layer for AI code governance. Core principle: Audit as Infrastructure. Breaks the black-box programming process and cross-session amnesia, evolving programming paradigms into an auditable, traceable, and convergent new era. npx-ready.\n\n[codein2027](https://github.com/xiaomingming92/codein2027) 快速构建 ADD 编程范式的完整脚手架——AI 代码治理的落地方案。以「审计即基础设施」为核心,彻底打破编程过程黑盒与跨轮失忆,让编程范式进化为可审计、可追溯、可收敛的新时代。npx 即用,人人可体验。",
|
|
6
6
|
"repository": {
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"email": "wujixmm@gmail.com",
|
|
41
41
|
"license": "AGPL-3.0-only",
|
|
42
42
|
"dependencies": {
|
|
43
|
+
"@huggingface/transformers": "^3.8.1",
|
|
43
44
|
"@modelcontextprotocol/server": "2.0.0",
|
|
44
|
-
"@xenova/transformers": "^2.17.2",
|
|
45
45
|
"commander": "^13.1.0",
|
|
46
46
|
"smol-toml": "^1.7.0",
|
|
47
47
|
"vector-cosine-similarity": "^1.8.0",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"prisma": "^7.0.0",
|
|
55
55
|
"tsx": ">=4",
|
|
56
56
|
"vector-cosine-similarity": "^1.8.0",
|
|
57
|
-
"@
|
|
57
|
+
"@huggingface/transformers": "^3.8.1"
|
|
58
58
|
},
|
|
59
59
|
"peerDependenciesMeta": {
|
|
60
60
|
"@prisma/client": {
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@prisma/adapter-pg": {
|
|
73
73
|
"optional": false
|
|
74
74
|
},
|
|
75
|
-
"@
|
|
75
|
+
"@huggingface/transformers": {
|
|
76
76
|
"optional": false
|
|
77
77
|
}
|
|
78
78
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_version": "0.3.
|
|
2
|
+
"_version": "0.3.14",
|
|
3
3
|
"adapters/claude/hooks/doc-format-guard.sh": "ec59ad3f",
|
|
4
4
|
"adapters/claude/hooks/lib/common.sh": "4f3e64ad",
|
|
5
5
|
"adapters/claude/hooks/lib/context-inject.sh": "cfc8c65e",
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
"core/plans/2026-07/08/add-coder-npm-package-add-route-v1.md": "b05fce99",
|
|
167
167
|
"core/plans/2026-07/08/add-coder-npm-package-handoff-v1.md": "1bd40a4a",
|
|
168
168
|
"core/plans/2026-07/08/add-coder-npm-package-plan-v1.md": "a678d98e",
|
|
169
|
-
"core/prisma/add.prisma": "
|
|
169
|
+
"core/prisma/add.prisma": "fa818acf",
|
|
170
170
|
"core/reports/REPORT-WORKFLOW.md": "03d39b21",
|
|
171
171
|
"core/reports/boundary-runtime-report.md": "6fd8053f",
|
|
172
172
|
"core/reports/code-review-combined-report.md": "195d52aa",
|
|
@@ -211,7 +211,7 @@
|
|
|
211
211
|
"core/scripts/mcp-server/tools/gateway/check_dps.ts": "cea4cb8b",
|
|
212
212
|
"core/scripts/mcp-server/tools/gateway/check_rahs.ts": "c37f6810",
|
|
213
213
|
"core/scripts/mcp-server/tools/gateway/check_spec_sync.ts": "a683697f",
|
|
214
|
-
"core/scripts/mcp-server/tools/gateway/helpers.ts": "
|
|
214
|
+
"core/scripts/mcp-server/tools/gateway/helpers.ts": "690d7891",
|
|
215
215
|
"core/scripts/mcp-server/tools/gateway/index.ts": "5a9fd5ed",
|
|
216
216
|
"core/scripts/mcp-server/tools/gateway.backup": "65eae393",
|
|
217
217
|
"core/scripts/mcp-server/tools/hitl.ts": "80093743",
|
|
@@ -94,6 +94,12 @@ model PlanRecord {
|
|
|
94
94
|
checklistTDone Int @default(0)
|
|
95
95
|
checklistR Int @default(0)
|
|
96
96
|
planKeyword String?
|
|
97
|
+
// DPS 四维评分历史(check_dps 调用后回写,供 FFT 自适应权重消费)
|
|
98
|
+
dpsSemScore Int? // 语义相关性 0-100
|
|
99
|
+
dpsEntropyScore Int? // 信息熵匹配 0-100
|
|
100
|
+
dpsCpmScore Int? // CPM 关键路径 0-100
|
|
101
|
+
dpsStructScore Int? // 结构完整度 0-100
|
|
102
|
+
dpsComposite Int? // 加权 DPS 总分 0-100
|
|
97
103
|
hitls HitlRecord[]
|
|
98
104
|
reviews ReviewRecord[]
|
|
99
105
|
createdAt DateTime @default(now())
|
|
@@ -105,7 +105,7 @@ let _embedPipeline: { embed: (texts: string[]) => Promise<number[][]> } | null =
|
|
|
105
105
|
|
|
106
106
|
export async function getEmbeddings(texts: string[]): Promise<number[][]> {
|
|
107
107
|
if (!_embedPipeline) {
|
|
108
|
-
const { pipeline, env } = await import("@
|
|
108
|
+
const { pipeline, env } = await import("@huggingface/transformers");
|
|
109
109
|
env.remoteHost = "https://hf-mirror.com";
|
|
110
110
|
env.remotePathTemplate = "{model}/resolve/{revision}/";
|
|
111
111
|
const extractor = await pipeline("feature-extraction", CFG.EMBEDDING_MODEL);
|