lume-dsh-plugin 0.7.3 → 0.7.4
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/lib/core/ledger.js +11 -4
- package/lib/host/methods.js +2 -1
- package/lib/host/protocol.js +10 -1
- package/lib/host/session-runtime.js +1 -0
- package/lib/host/triggers.js +5 -5
- package/lib/index.js +60 -11
- package/package.json +5 -2
package/lib/core/ledger.js
CHANGED
|
@@ -48,11 +48,18 @@ function asCount(value) {
|
|
|
48
48
|
const n = typeof value === "number" ? value : Number.parseInt(String(value ?? ""), 10);
|
|
49
49
|
return Number.isFinite(n) && n >= 0 ? Math.trunc(n) : null;
|
|
50
50
|
}
|
|
51
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* 项目键:跨会话共享的项目知识按工作目录归属(同一仓库的多个会话共用一份)。
|
|
53
|
+
*
|
|
54
|
+
* 拿不到工作目录时返回 **null**,不返回 "unknown"——实测踩过:写入口(工具 exec / 会话事件)
|
|
55
|
+
* 里的 session 视图不一定带 cwd,回落成 "unknown" 会把**所有项目**的知识塞进同一个桶,
|
|
56
|
+
* 跨会话隔离直接失效(现场取证:facts 表的键就是 "unknown")。调用方拿到 null 必须
|
|
57
|
+
* 「不写跨会话表」,宁可不记也不要串味。
|
|
58
|
+
*/
|
|
52
59
|
export function projectKeyOf(cwd) {
|
|
53
60
|
const normalized = clip(cwd, 240).replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
54
61
|
if (!normalized)
|
|
55
|
-
return
|
|
62
|
+
return null;
|
|
56
63
|
return fnv1a32(normalized).toString(16).padStart(8, "0");
|
|
57
64
|
}
|
|
58
65
|
/** 从工具入参归一化契约(截断 + 去重 + 上限)。 */
|
|
@@ -143,8 +150,8 @@ export function renderContract(contract, delivery = false) {
|
|
|
143
150
|
lines.push(`目标:${contract.goal}`);
|
|
144
151
|
if (contract.scope.length > 0)
|
|
145
152
|
lines.push(`范围:${contract.scope.join(";")}`);
|
|
146
|
-
if (
|
|
147
|
-
const expect = contract.expectCount === null ? "
|
|
153
|
+
if (true) {
|
|
154
|
+
const expect = contract.expectCount === null ? "未估" : contract.expectCount;
|
|
148
155
|
const actual = contract.actualCount === null ? "未回填" : contract.actualCount;
|
|
149
156
|
lines.push(`数量:预计 ${expect} → 实际 ${actual}`);
|
|
150
157
|
}
|
package/lib/host/methods.js
CHANGED
|
@@ -15,7 +15,7 @@ export function buildContractMethodDirective() {
|
|
|
15
15
|
"〔先量化后动手〕本轮是任务型请求。开工前先写任务契约(lume_contract):",
|
|
16
16
|
"- 目标:一句话,可观察的结果(不是「优化一下」这种动词)",
|
|
17
17
|
"- 范围:精确到路径 / 模块 / 章节 / 表",
|
|
18
|
-
"-
|
|
18
|
+
"- 数量:必填,先估一个数,探索后回填实际值(实在无法估时传 0 并说明理由)——交付时要用实际数量对账",
|
|
19
19
|
"- 完成判据:可执行、可核对(命令 / 回读 / 对照),不是「改完」",
|
|
20
20
|
"- 非目标:明确不动什么,防止范围蔓延",
|
|
21
21
|
"- 待确认:只列真正阻塞的(≤2 个);不阻塞的按默认假设前进并写明假设",
|
|
@@ -36,6 +36,7 @@ export function buildImpactDirective() {
|
|
|
36
36
|
return [
|
|
37
37
|
"〔改动影响面〕动手前列出:要改的符号 → 谁调用它、它实现或被实现于谁、配置或 SQL 映射、前端/模板引用;并标出「不打算改但需一并确认」的位置。",
|
|
38
38
|
"每处改动写明验证方式;同一文件的相关改动一次做完,不要反复回来改同一个文件。",
|
|
39
|
+
"每改完一处就用 lume_change 记一条(target=文件/符号、change=改了什么、verify=怎么验、status=done),验完推进到 verified;台账积着未验证项时会有提醒。",
|
|
39
40
|
].join("\n");
|
|
40
41
|
}
|
|
41
42
|
/** 环境里有结构分析/符号工具时的一句提示:用符号级定位替代通篇 read。 */
|
package/lib/host/protocol.js
CHANGED
|
@@ -8,6 +8,15 @@ const MODE_RULES = {
|
|
|
8
8
|
// 显式请求标记后必须紧跟一个动作动词,且限制在同一小句内(旧版用 `.*` 贪婪跨越
|
|
9
9
|
// 整句,导致「是什么驱动你去这么做的」也被判成执行)。句首祈使不再放行「做」:
|
|
10
10
|
// 「做一件事…」这类名词化表述是讨论而非执行。
|
|
11
|
+
/**
|
|
12
|
+
* 执行动词的补充表(0.7.4)。
|
|
13
|
+
*
|
|
14
|
+
* 现场实测:`EXECUTE_RE` 不含「重构 / 梳理 / 删掉 / 合并 / 迁移」等常见动词,于是
|
|
15
|
+
* 「帮我重构订单退费链路」被判成**问答**——方法层(影响面清单)与阶段门控都不生效,
|
|
16
|
+
* 而那次会话确实改了 11 个文件。这里只补「对产物动手」的动作,**不含诊断类动词**
|
|
17
|
+
* (分析/诊断/排查属于 diagnosis,混进来会把讨论与排查误判成执行)。
|
|
18
|
+
*/
|
|
19
|
+
const EXECUTE_EXTRA_RE = /重构|重写|梳理|清理|删掉|删除|去掉|移除|合并|合入|迁移|替换|收口|落地|接入|适配|升级|降级|补上|补齐|加上|改成|改为|换成|拆开|拆出/;
|
|
11
20
|
const EXECUTE_RE = new RegExp([
|
|
12
21
|
"(?:请|帮我|帮忙|直接|把|给我|替我|麻烦|需要你)\\s*[^,。!?;\\n]{0,24}?(?:做|改|修|写|加|删|建|跑|执行|完成|实现|优化|更新|部署|安装|迁移|提交|发布|检查|核对|补|替换|重命名|合并|回滚|加上)",
|
|
13
22
|
"^(?:改|修|写|加|删|建|跑|执行|完成|实现|优化|更新|部署|安装|迁移|提交|发布|检查|补|替换|重命名|合并|回滚)",
|
|
@@ -23,7 +32,7 @@ export function classifyInteraction(text) {
|
|
|
23
32
|
const query = String(text ?? "").trim();
|
|
24
33
|
if (!query)
|
|
25
34
|
return "question";
|
|
26
|
-
if (EXECUTE_RE.test(query))
|
|
35
|
+
if ((EXECUTE_RE.test(query) || EXECUTE_EXTRA_RE.test(query)))
|
|
27
36
|
return "execute";
|
|
28
37
|
if (DIAGNOSIS_RE.test(query))
|
|
29
38
|
return "diagnosis";
|
package/lib/host/triggers.js
CHANGED
|
@@ -58,7 +58,7 @@ export function applyVerifyOutcome(counters, kind, signals) {
|
|
|
58
58
|
}
|
|
59
59
|
export const DEFAULT_TRIGGER_THRESHOLDS = {
|
|
60
60
|
inspectStreak: 12,
|
|
61
|
-
changeStreak:
|
|
61
|
+
changeStreak: 4,
|
|
62
62
|
deadPathFails: 3,
|
|
63
63
|
knowledgeSteps: 20,
|
|
64
64
|
};
|
|
@@ -74,7 +74,7 @@ export function evaluateToolTrigger(counters, ctx, thresholds = DEFAULT_TRIGGER_
|
|
|
74
74
|
if (dead === "env") {
|
|
75
75
|
return {
|
|
76
76
|
id: "dead-path",
|
|
77
|
-
text: `〔验证降级〕同一环境已连续 ${n} 次验证失败,其中 ${m} 次是环境或依赖不可用(不是代码问题)。停止重复同一条命令,换降级阶梯:① 能用的编译器/测试 → ② 语法检查(parser / typecheck)→ ③ 静态交叉引用(谁调用它、它调用谁、配置与 SQL 绑定)→ ④
|
|
77
|
+
text: `〔验证降级〕同一环境已连续 ${n} 次验证失败,其中 ${m} 次是环境或依赖不可用(不是代码问题)。停止重复同一条命令,换降级阶梯:① 能用的编译器/测试 → ② 语法检查(parser / typecheck)→ ③ 静态交叉引用(谁调用它、它调用谁、配置与 SQL 绑定)→ ④ 手工走读并列出风险点。同时用 lume_project_note(kind=deadend)把这条环境死路记进项目知识——下次会话不必重踩。交付时明确写「本环境无法完成构建验证」。`,
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
return {
|
|
@@ -82,10 +82,10 @@ export function evaluateToolTrigger(counters, ctx, thresholds = DEFAULT_TRIGGER_
|
|
|
82
82
|
text: `〔死路提醒〕同一验证已连续失败 ${n} 次。先归因(输入 / 逻辑 / 接口 / 环境 / 权限),把结论写进假设台账:证实的标 confirmed、排除的标 excluded(用 lume_hypothesis)——已排除的假设不要再试。换一个方案再动手。`,
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
if (counters.mutateStreak >= thresholds.changeStreak) {
|
|
85
|
+
if (counters.mutateStreak >= thresholds.changeStreak || ctx.unverifiedChanges >= thresholds.changeStreak) {
|
|
86
86
|
return {
|
|
87
87
|
id: "verify-as-you-go",
|
|
88
|
-
text: `〔增量验证〕已连续 ${counters.mutateStreak}
|
|
88
|
+
text: `〔增量验证〕已连续 ${counters.mutateStreak} 次改动、台账里还有 ${ctx.unverifiedChanges} 项未验证。改一处验一处:现在先跑一次最小验证(编译 / 语法检查 / 回读改动区域),确认前一批改动真的生效;验完用 lume_change 把对应条目推进到 verified(只传 target + status 即可)。一大批改完再验,失败时无法定位是哪一处的问题。`,
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
if (!ctx.hasContract && ctx.isTask && counters.mutations > 0) {
|
|
@@ -100,7 +100,7 @@ export function evaluateToolTrigger(counters, ctx, thresholds = DEFAULT_TRIGGER_
|
|
|
100
100
|
text: `〔收敛提醒〕已连续 ${counters.inspectStreak} 次只读探查,还没有产出契约或改动台账。停止撒网式通读,先把链路复述出来——入口 → 数据流 → 影响面(谁调用、被谁调用、配置与 SQL 绑定)——写成改动台账(lume_change)并回填实际数量,然后带着这份清单回去读缺口。`,
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
-
if (counters.verifyFailStreak > 0 && ctx.diagnosing &&
|
|
103
|
+
if (counters.verifyFailStreak > 0 && ctx.diagnosing && !ctx.hypothesesTouched) {
|
|
104
104
|
return {
|
|
105
105
|
id: "hypothesis-stale",
|
|
106
106
|
text: "〔假设台账〕本轮出现了验证失败,但假设状态没有更新。把这次失败归因写进 lume_hypothesis(证实 / 排除 / 新假设),并标出下一步要验的是哪一条——否则同一个假设会被反复试。",
|
package/lib/index.js
CHANGED
|
@@ -434,8 +434,10 @@ function applyInner(ctx, config = {}) {
|
|
|
434
434
|
return;
|
|
435
435
|
const prompt = buildExtractionPrompt(userText, assistantText, existing.map((f) => f.text));
|
|
436
436
|
const output = await callLlm(resolveAuxRoute(extractionRouteOverride, llmRoute), prompt.system, prompt.userText, 800);
|
|
437
|
-
if (output === null)
|
|
437
|
+
if (output === null) {
|
|
438
|
+
ctx.logger?.warn?.(`lume: 反思跳过(${sid})模型无输出`);
|
|
438
439
|
return;
|
|
440
|
+
}
|
|
439
441
|
st.lastExtractionAt = Date.now();
|
|
440
442
|
const fresh = mergeNewFacts(parseFacts(output), identity.getMemory(personaName));
|
|
441
443
|
for (const fact of fresh) {
|
|
@@ -566,6 +568,16 @@ function applyInner(ctx, config = {}) {
|
|
|
566
568
|
// 行为类别在调用阶段记账(连击),成败到结果阶段才结算。
|
|
567
569
|
st.toolKind = classifyTool(event.data?.name);
|
|
568
570
|
applyToolSignal(st.triggerCounters, st.toolKind, null);
|
|
571
|
+
// 自动改动台账:mutate 类工具一被调用就先记一条——实测模型几乎不会主动调 lume_change
|
|
572
|
+
// (4 个会话里 0 次),而 edit/write 每次会话几十次。载具必须由插件自己落账,
|
|
573
|
+
// 否则「改动台账」永远空着(这正是上一版没生效的地方)。
|
|
574
|
+
if (projectMemoryOn && st.toolKind === "mutate") {
|
|
575
|
+
const target = targetPathFromToolEvent(event.data);
|
|
576
|
+
if (target) {
|
|
577
|
+
const toolName = String(event.data?.name ?? "tool");
|
|
578
|
+
void projectReady.then((store) => store?.upsertChange(sid, { target, change: `(自动)由 ${toolName} 修改`, why: "", verify: "", status: "done", at: Date.now() }));
|
|
579
|
+
}
|
|
580
|
+
}
|
|
569
581
|
break;
|
|
570
582
|
}
|
|
571
583
|
case "tool/result": {
|
|
@@ -591,7 +603,7 @@ function applyInner(ctx, config = {}) {
|
|
|
591
603
|
isTask: isTaskQuery(st),
|
|
592
604
|
diagnosing: st.interactionMode === "diagnosis",
|
|
593
605
|
hasContract: contractOf(sid) !== null,
|
|
594
|
-
|
|
606
|
+
unverifiedChanges: changesOf(sid).filter((item) => item.status !== "verified" && item.status !== "skipped").length,
|
|
595
607
|
hypothesesTouched: st.hypothesesTouched,
|
|
596
608
|
}, triggerThresholds);
|
|
597
609
|
if (fire && cooldownOk(st.triggerFiredAt[fire.id], st.turnIndex)) {
|
|
@@ -601,7 +613,8 @@ function applyInner(ctx, config = {}) {
|
|
|
601
613
|
// 环境性死路自动落成项目知识:下次会话不必重踩。
|
|
602
614
|
if (fire.id === "dead-path" && signals.env && project) {
|
|
603
615
|
const key = projectKeyFor(sid, session);
|
|
604
|
-
|
|
616
|
+
if (key)
|
|
617
|
+
void project.addFact(key, normalizeProjectFact({ kind: "deadend", text: `本环境验证受阻(${st.triggerCounters.verifyFailStreak} 次连续失败,环境/依赖类):换降级阶梯,不要重复同一命令` }, Date.now()), (candidate, existing) => existing.some((fact) => fact.text === candidate));
|
|
605
618
|
}
|
|
606
619
|
}
|
|
607
620
|
}
|
|
@@ -716,12 +729,22 @@ function applyInner(ctx, config = {}) {
|
|
|
716
729
|
void projectReady.then((store) => store?.clearSession(sid));
|
|
717
730
|
// 反思日志:会话结束后空闲时间跑一次小模型,零用户感知 token。
|
|
718
731
|
// 历史不够长(< 4 条消息)或路由不可用时静默跳过。
|
|
732
|
+
if (reflectionEnabled && turns.length < 4)
|
|
733
|
+
ctx.logger?.warn?.(`lume: 反思跳过(${sid})历史不足:${turns.length} < 4 条消息`);
|
|
719
734
|
if (reflectionEnabled && turns.length >= 4) {
|
|
720
735
|
void (async () => {
|
|
721
736
|
const store = await reflectionReady;
|
|
737
|
+
if (!store) {
|
|
738
|
+
ctx.logger?.warn?.(`lume: 反思跳过(${sid})reflection 域不可用`);
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
722
741
|
if (!store)
|
|
723
742
|
return;
|
|
724
743
|
const route = resolveAuxRoute({}, llmRoute);
|
|
744
|
+
if (!route) {
|
|
745
|
+
ctx.logger?.warn?.(`lume: 反思跳过(${sid})无可用小模型路由`);
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
725
748
|
if (!route)
|
|
726
749
|
return;
|
|
727
750
|
const prompt = buildReflectionPrompt(turns);
|
|
@@ -729,8 +752,10 @@ function applyInner(ctx, config = {}) {
|
|
|
729
752
|
if (output === null)
|
|
730
753
|
return;
|
|
731
754
|
const score = parseReflectionScore(output);
|
|
732
|
-
if (!score)
|
|
755
|
+
if (!score) {
|
|
756
|
+
ctx.logger?.warn?.(`lume: 反思跳过(${sid})评分解析失败`);
|
|
733
757
|
return;
|
|
758
|
+
}
|
|
734
759
|
await store.log(sid, score);
|
|
735
760
|
ctx.logger?.warn?.(`lume: 反思日志 ${sid} context=${score.context} planning=${score.planning} verification=${score.verification} review=${score.review} diagnosis=${score.diagnosis}「${score.note}」`);
|
|
736
761
|
})();
|
|
@@ -745,12 +770,24 @@ function applyInner(ctx, config = {}) {
|
|
|
745
770
|
// 三种调用来源:提示词 context({agent:{session}})、工具 exec({agent:{session}})、
|
|
746
771
|
// 会话事件(session 本身)。统一取到 session 再读 cwd。
|
|
747
772
|
const session = source?.agent?.session ?? source?.session ?? source;
|
|
748
|
-
const cwd = session?.cwd
|
|
773
|
+
const cwd = String(session?.cwd || st.cwd || "");
|
|
749
774
|
const key = projectKeyOf(cwd);
|
|
750
775
|
// 只有拿到真实工作目录才缓存:否则一次无 cwd 的调用会把 "unknown" 固化下来。
|
|
751
|
-
if (cwd)
|
|
776
|
+
if (cwd && key)
|
|
752
777
|
st.projectKey = key;
|
|
753
|
-
return key;
|
|
778
|
+
return st.projectKey ?? key;
|
|
779
|
+
}
|
|
780
|
+
/** 从工具入参里取目标路径(自动改动台账用):兼容常见字段名,取不到返回 null——宁可少记,不要记错。 */
|
|
781
|
+
function targetPathFromToolEvent(data) {
|
|
782
|
+
const args = data?.args ?? data?.input ?? data?.parameters ?? data?.arguments;
|
|
783
|
+
if (!args || typeof args !== "object")
|
|
784
|
+
return null;
|
|
785
|
+
for (const key of ["path", "file_path", "filePath", "file", "filename", "target", "notebook_path"]) {
|
|
786
|
+
const value = args[key];
|
|
787
|
+
if (typeof value === "string" && value.trim())
|
|
788
|
+
return value.trim().slice(0, 120);
|
|
789
|
+
}
|
|
790
|
+
return null;
|
|
754
791
|
}
|
|
755
792
|
function isTaskQuery(st) {
|
|
756
793
|
return TASK_SIGNAL_RE.test(st.intent?.text ?? st.userText ?? "");
|
|
@@ -765,7 +802,8 @@ function applyInner(ctx, config = {}) {
|
|
|
765
802
|
return project?.getHypotheses(sid) ?? [];
|
|
766
803
|
}
|
|
767
804
|
function factsOf(sid, context) {
|
|
768
|
-
|
|
805
|
+
const projectKey = projectKeyFor(sid, context);
|
|
806
|
+
return project && projectKey ? project.getFacts(projectKey) : [];
|
|
769
807
|
}
|
|
770
808
|
/** 环境里是否有符号级结构分析工具:有就让模型用它替代通篇 read。 */
|
|
771
809
|
function structureToolName(context) {
|
|
@@ -794,7 +832,7 @@ function applyInner(ctx, config = {}) {
|
|
|
794
832
|
function carrierBlocks(sid, context, st, query, mode) {
|
|
795
833
|
if (!projectMemoryOn)
|
|
796
834
|
return [];
|
|
797
|
-
const isTask = TASK_SIGNAL_RE.test(query);
|
|
835
|
+
const isTask = mode !== "question" || TASK_SIGNAL_RE.test(query);
|
|
798
836
|
const contract = contractOf(sid);
|
|
799
837
|
const changes = changesOf(sid);
|
|
800
838
|
const docDirective = buildDocumentDirective({ query, capabilities: probeDocumentCapabilities(ctx.get("tools"), context?.agent) });
|
|
@@ -900,7 +938,7 @@ function applyInner(ctx, config = {}) {
|
|
|
900
938
|
parameters: {
|
|
901
939
|
goal: { type: "string", description: "目标:一句话、可观察的结果" },
|
|
902
940
|
scope: { type: "string", description: "范围:路径/模块/章节,分号或换行分隔" },
|
|
903
|
-
expectCount: { type: "number", description: "预计数量(探索前先估)" },
|
|
941
|
+
expectCount: { type: "number", required: true, description: "预计数量(探索前先估)" },
|
|
904
942
|
actualCount: { type: "number", description: "实际数量(探索后回填)" },
|
|
905
943
|
criteria: { type: "string", description: "完成判据:可执行、可核对,分号或换行分隔" },
|
|
906
944
|
nonGoals: { type: "string", description: "非目标:明确不动的东西,分号分隔" },
|
|
@@ -1026,7 +1064,13 @@ function applyInner(ctx, config = {}) {
|
|
|
1026
1064
|
const fact = normalizeProjectFact({ kind: args.kind, text: args.text }, Date.now());
|
|
1027
1065
|
if (!fact)
|
|
1028
1066
|
throw new Error("lume_project_note requires text");
|
|
1029
|
-
|
|
1067
|
+
const projectKey = projectKeyFor(sid, { agent: exec?.agent });
|
|
1068
|
+
if (!projectKey) {
|
|
1069
|
+
// 拿不到工作目录:不写跨会话表——写一次就会把不同项目的知识串进同一个键(现场事故:facts 的键曾是 "unknown")
|
|
1070
|
+
ctx.logger?.warn?.(`lume: [${sid}] 项目知识未落盘(无法确定工作目录)`);
|
|
1071
|
+
return { ok: true };
|
|
1072
|
+
}
|
|
1073
|
+
await project.addFact(projectKey, fact, (candidate, existing) => existing.some((entry) => jaccard(entry.text, candidate) >= 0.7));
|
|
1030
1074
|
return { ok: true };
|
|
1031
1075
|
},
|
|
1032
1076
|
}));
|
|
@@ -1043,6 +1087,8 @@ function applyInner(ctx, config = {}) {
|
|
|
1043
1087
|
*/
|
|
1044
1088
|
function resolveIntent(context, st) {
|
|
1045
1089
|
const session = context?.agent?.session;
|
|
1090
|
+
if (typeof session?.cwd === "string" && session.cwd)
|
|
1091
|
+
st.cwd = session.cwd;
|
|
1046
1092
|
const messages = typeof session?.deriveMessages === "function" ? session.deriveMessages() : [];
|
|
1047
1093
|
let text = null;
|
|
1048
1094
|
let messageId = "";
|
|
@@ -1090,6 +1136,9 @@ function applyInner(ctx, config = {}) {
|
|
|
1090
1136
|
// 交付复核、压缩重锚、文档能力指引、失败纠偏、反思提醒——全部每步可变。
|
|
1091
1137
|
// 载具与方法块(契约/台账/假设/项目知识/影响面/文档方法/触发器提醒)排在最后:
|
|
1092
1138
|
// 它们是「此刻最该看的」,紧贴尾部注意力最强位;超预算时先丢可丢块(composeBlocks)。
|
|
1139
|
+
// 记录工作目录:工具 exec / 会话事件里可能拿不到 cwd,项目键靠这里缓存兜住(实测项目知识曾落到 unknown)
|
|
1140
|
+
if (typeof context?.agent?.session?.cwd === "string" && context.agent.session.cwd)
|
|
1141
|
+
st.cwd = context.agent.session.cwd;
|
|
1093
1142
|
const thinkingRuntime = composeBlocks([
|
|
1094
1143
|
{ text: buildInteractionDirective(mode) },
|
|
1095
1144
|
{ text: buildTaskPhaseDirective(st.taskPhase) },
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lume-dsh-plugin",
|
|
3
3
|
"description": "微光 (Lume) — DSH Desktop 增强插件:给会话装上工程纪律与真实关系。纪律层约束「如何正确完成任务」——意图路由、阶段门控、真实工具证据、交付前复核、文档能力感知;方法层把量化需求、改动台账、假设台账与项目知识变成可检查的产出,并用行为触发器在轨迹上纠偏(撒网不收敛 / 连写不验 / 死路重撞);人设层塑造「以何种风格表达」——从聊天记录、小说、剧本、设定文档蒸馏具名角色,长期记忆与风格随对话演进。约束按需注入,闲聊不额外付 token。",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -65,7 +65,10 @@
|
|
|
65
65
|
"build": "tsc -p tsconfig.build.json && tsdown",
|
|
66
66
|
"bundle": "tsdown",
|
|
67
67
|
"watch": "tsdown --watch",
|
|
68
|
-
"test": "vitest run"
|
|
68
|
+
"test": "vitest run",
|
|
69
|
+
"release:check": "npm run build && node scripts/release-check.mjs",
|
|
70
|
+
"release:publish": "node scripts/publish.mjs",
|
|
71
|
+
"release:audit": "node scripts/release-check.mjs --published"
|
|
69
72
|
},
|
|
70
73
|
"devDependencies": {
|
|
71
74
|
"@deepseek-ai/cordis": "^4.0.1",
|