@thincoder/core 0.10.4 → 0.10.6
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/CHANGELOG.md +39 -1
- package/README.md +1 -1
- package/advisor/compaction.mjs +11 -6
- package/advisor/run.mjs +4 -4
- package/agent/assemble.mjs +1 -1
- package/agent/chat-call.mjs +1 -1
- package/agent/child-marks.mjs +2 -2
- package/agent/digest-account.mjs +5 -4
- package/agent/dispatch-gates.mjs +8 -0
- package/agent/dispatch.mjs +39 -18
- package/agent/family-tools.mjs +22 -11
- package/agent/helpers.mjs +4 -3
- package/agent/light-round.mjs +66 -0
- package/agent/post-turn.mjs +8 -4
- package/agent/run-stages.mjs +5 -3
- package/agent/run-start.mjs +3 -2
- package/agent/setup-reminders.mjs +1 -1
- package/agent/setup.mjs +18 -3
- package/agent/subagent-event.mjs +1 -1
- package/agent/suspension.mjs +8 -5
- package/agent/timers.mjs +56 -5
- package/agent/turn-loop.mjs +5 -3
- package/agent/write-gate.mjs +7 -7
- package/agent-tools/advisor-async.mjs +2 -2
- package/agent-tools/advisor-settle.mjs +2 -2
- package/agent-tools/advisor.mjs +1 -1
- package/agent-tools/async-discard.mjs +34 -0
- package/agent-tools/async-settle.mjs +3 -2
- package/agent-tools/audit-block.mjs +1 -1
- package/agent-tools/bash-async.mjs +1 -1
- package/agent-tools/batch-lifecycle.mjs +35 -14
- package/agent-tools/batch-paths.mjs +4 -4
- package/agent-tools/batch-skeleton.mjs +29 -11
- package/agent-tools/batch.mjs +28 -15
- package/agent-tools/browser-async.mjs +198 -0
- package/agent-tools/checkpoint.mjs +1 -1
- package/agent-tools/design-slots.mjs +232 -0
- package/agent-tools/digest-budget.mjs +1 -1
- package/agent-tools/manifest.mjs +193 -0
- package/agent-tools/parent-channel.mjs +7 -4
- package/agent-tools/review-facts.mjs +13 -13
- package/agent-tools/settings.mjs +1 -1
- package/agent-tools/skill.mjs +1 -1
- package/agent-tools/subagent-async.mjs +21 -12
- package/agent-tools/subagent-scheduler.mjs +8 -5
- package/agent-tools/subagent-spawn.mjs +29 -55
- package/agent-tools/subagent.mjs +21 -8
- package/agent-tools/timer.mjs +186 -12
- package/agent-tools/zero-write-watch.mjs +2 -2
- package/agent-tools.mjs +2 -1
- package/agent.mjs +1 -1
- package/attachments.mjs +1 -1
- package/browser/actions.mjs +163 -0
- package/browser/cdp.mjs +161 -0
- package/browser/clipboard.mjs +142 -0
- package/browser/input-actions.mjs +197 -0
- package/browser/input.mjs +256 -0
- package/browser/launch.mjs +143 -0
- package/browser/queue.mjs +171 -0
- package/browser/session.mjs +494 -0
- package/browser/snapshot.mjs +270 -0
- package/config-io.mjs +18 -13
- package/config-migrate.mjs +13 -29
- package/config-presets.mjs +33 -29
- package/config.mjs +68 -25
- package/context-degrade.mjs +1 -1
- package/context-echo.mjs +1 -1
- package/context-push.mjs +2 -2
- package/context.mjs +1 -1
- package/conventions.mjs +2 -2
- package/declaration.mjs +18 -2
- package/file-links.mjs +1 -1
- package/file-refs.mjs +1 -1
- package/history-window.mjs +1 -1
- package/i18n.mjs +2 -0
- package/ledger-cmd.mjs +62 -16
- package/ledger-db.mjs +6 -0
- package/ledger-surface.mjs +49 -5
- package/ledger-tools.mjs +16 -8
- package/ledger.mjs +9 -16
- package/log.mjs +1 -1
- package/manifest-discovery.mjs +1 -1
- package/manifest-schema.mjs +1 -1
- package/mcp/transport-stdio.mjs +1 -1
- package/mcp.mjs +1 -1
- package/memory/code-index.mjs +1 -1
- package/memory/code-search.mjs +1 -1
- package/memory/code-sync.mjs +1 -1
- package/memory/docs.mjs +6 -2
- package/memory/file-list.mjs +1 -1
- package/memory/file-walk.mjs +17 -5
- package/memory/maintain.mjs +410 -0
- package/memory/memory-tool.mjs +21 -6
- package/memory/schema.mjs +19 -7
- package/memory/sweep.mjs +8 -5
- package/memory/sync-tail.mjs +16 -10
- package/model-ref.mjs +16 -13
- package/model-specs.mjs +21 -9
- package/package.json +2 -1
- package/peer-instances.mjs +1 -1
- package/permission.mjs +33 -0
- package/process-probe.mjs +2 -2
- package/prompts/advisor-design.md +4 -2
- package/prompts/advisor-round1.md +1 -1
- package/prompts/advisor-round2.md +1 -1
- package/prompts/advisor-round3.md +1 -1
- package/prompts/common.md +36 -2
- package/prompts/consult-base.md +1 -1
- package/prompts/discipline-engineering.md +32 -15
- package/prompts/discipline-normal.md +46 -2
- package/prompts/persona-eng-designer.md +6 -6
- package/prompts/persona-engineering.md +14 -6
- package/prompts/persona-normal.md +2 -0
- package/prompts/subagent-base.md +3 -0
- package/provider/core.mjs +6 -0
- package/provider/errors.mjs +5 -3
- package/provider/google.mjs +9 -8
- package/provider/list-models.mjs +3 -2
- package/provider/sse.mjs +3 -0
- package/provider-flows.mjs +14 -15
- package/proxy-chunked.mjs +102 -0
- package/proxy-target.mjs +54 -0
- package/proxy-transport.mjs +298 -0
- package/proxy.mjs +17 -248
- package/session-gc.mjs +2 -2
- package/session-lifecycle.mjs +18 -14
- package/session-slot-claims.mjs +2 -2
- package/session-slots-manifest.mjs +1 -1
- package/session-slots.mjs +3 -3
- package/team-ledger.mjs +282 -0
- package/team.mjs +223 -0
- package/tool-docs/bash.md +1 -0
- package/tool-docs/batch.md +1 -1
- package/tool-docs/browser.md +48 -0
- package/tool-docs/ledger.md +3 -3
- package/tool-docs/manifest.md +16 -0
- package/tool-docs/memory.md +1 -0
- package/tool-docs/notify_parent.md +5 -0
- package/tool-docs/process.md +4 -4
- package/tool-docs/question.md +1 -0
- package/tool-docs/subagent.md +4 -3
- package/tool-docs/team_ledger.md +9 -0
- package/tool-docs/timer.md +6 -0
- package/tool-docs/wait_for.md +1 -0
- package/tools/browser.mjs +161 -0
- package/tools/git.mjs +1 -1
- package/tools/index.mjs +3 -0
- package/tools/ops.mjs +26 -10
- package/tools/repomap.mjs +1 -1
- package/tools/write-path.mjs +2 -2
- package/traces/trace-cleanup.mjs +1 -1
- package/traces/trace-store.mjs +1 -1
- package/vision-reader.mjs +10 -16
package/ledger-tools.mjs
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* 全量 = depth-0 五 action ∥ 只读 = depth>0 二 action);旧五名 = code 面弃用壳(不入任何装配面)。
|
|
6
6
|
* 守卫 = **声明派生**(设计档 §3.2 / §11.3:判序① 入参归一 → ② 入口级 action 判(消费 action)→
|
|
7
7
|
* ③ 余键喂该 action 伪工具对象走 P2–P6——声明源 = 前身旧工具 `parameters` 逐字;helper `assertToolArgs`
|
|
8
|
-
*
|
|
8
|
+
* 机制沿用,「零改」面破例 = #1006 批增布尔分支(§13.9));判于核函数之前 ⇒ 非法入参零写、零库动作、
|
|
9
|
+
* 零 SQLite 原文外泄。
|
|
9
10
|
* 接线:族出口 = `ledger.mjs`(re-export——消费面 agent/family-tools.mjs;旧读二装配面已清零);
|
|
10
11
|
* 消费侧一律动态 import(`ledger-db.mjs` 静态 import node:sqlite ⇒ W8 契约②)。
|
|
11
12
|
*/
|
|
@@ -62,6 +63,8 @@ function assertToolArgs(tool, args) {
|
|
|
62
63
|
throw new Error(`${name}:${field} 非法:${argPreview(value)}(应为字符串)`)
|
|
63
64
|
} else if (spec.type === "number" && typeof value !== "number") {
|
|
64
65
|
throw new Error(`${name}:${field} 非法:${argPreview(value)}(应为数字)`)
|
|
66
|
+
} else if (spec.type === "boolean" && typeof value !== "boolean") {
|
|
67
|
+
throw new Error(`${name}:${field} 非法:${argPreview(value)}(应为布尔)`)
|
|
65
68
|
}
|
|
66
69
|
if (field === "title" && typeof value === "string" && value.trim() === "") {
|
|
67
70
|
throw new Error(`${name}:${field} 为空(${required ? "必填;" : ""}非空字符串)`)
|
|
@@ -107,9 +110,10 @@ const ACTION_SPECS = {
|
|
|
107
110
|
board: { type: "string", description: "归属板块(缺省 = 不变)" },
|
|
108
111
|
req_doc: { type: "string", description: "需求档指针(缺省 = 不变)" },
|
|
109
112
|
task_book: { type: "string", description: "任务书指针(缺省 = 不变)" },
|
|
110
|
-
evidence: { type: "string", description: "证据(缺省 =
|
|
113
|
+
evidence: { type: "string", description: "证据(缺省 = 不变;传入 = 追加——旧值非空 ⇒ 拼 `旧|新`(「|」零空格)、旧空直写;新值全空白 ⇒ 拒;覆盖 = 与 `evidenceReplace: true` 同传)" },
|
|
114
|
+
evidenceReplace: { type: "boolean", description: "覆盖旗(布尔):与 evidence 同传 = 整段替换(旧文零保留);缺省 / false = 追加;旗独传(无新文)⇒ 拒" },
|
|
111
115
|
trigger: { type: "string", enum: ["归批", "条件", "认账不排期"], description: "触发(缺省 = 不变)" },
|
|
112
|
-
executor: { type: "string", description: "执行者 sessionId(可选——接手改写归属用;缺省 =
|
|
116
|
+
executor: { type: "string", description: "执行者 sessionId(可选——接手改写归属用;缺省 = 按状态迁移语义:进入待设计 / 在途自动写本会话;出在途 / 撤回清空)" },
|
|
113
117
|
},
|
|
114
118
|
additionalProperties: false,
|
|
115
119
|
},
|
|
@@ -120,6 +124,8 @@ const ACTION_SPECS = {
|
|
|
120
124
|
cwd: { type: "string", description: CWD_DESC },
|
|
121
125
|
id: { type: "number", description: "条目 id" },
|
|
122
126
|
status: { type: "string", enum: ["已核销", "已废弃"], description: "目标态(勾销 / 追认核销 / 撤回)" },
|
|
127
|
+
evidence: { type: "string", description: "最小证据行(可选;传入 = 追加缺省——旧值非空 ⇒ 拼 `旧|新`(「|」零空格)、旧空直写;新值全空白 ⇒ 拒;覆盖 = 与 `evidenceReplace: true` 同传。追认核销面判结果值须非空:缺 / 全空白 ⇒ 拒)" },
|
|
128
|
+
evidenceReplace: { type: "boolean", description: "覆盖旗(布尔):与 evidence 同传 = 整段替换(旧文零保留);缺省 / false = 追加;旗独传(无新文)⇒ 拒" },
|
|
123
129
|
},
|
|
124
130
|
additionalProperties: false,
|
|
125
131
|
},
|
|
@@ -130,6 +136,7 @@ const ACTION_SPECS = {
|
|
|
130
136
|
status: { type: "string", enum: ["待讨论", "待设计", "在途", "待核销", "已核销", "已废弃"], description: "按状态过滤(六态之一,缺省 = 不过滤)" },
|
|
131
137
|
kind: { type: "string", enum: ["requirement", "tech_todo"], description: "按类别过滤" },
|
|
132
138
|
board: { type: "string", description: "按归属板块过滤(需求档文档名)" },
|
|
139
|
+
trigger: { type: "string", enum: ["归批", "条件", "认账不排期"], description: "按技术待办触发过滤(三枚举,缺省 = 不过滤——无触发(NULL)不过滤)" },
|
|
133
140
|
},
|
|
134
141
|
additionalProperties: false,
|
|
135
142
|
},
|
|
@@ -152,11 +159,12 @@ const UNION_PARAMETERS = {
|
|
|
152
159
|
board: { type: "string", description: "归属板块(需求档文档名;add 可空 / update 缺省 = 不变 / query 过滤)" },
|
|
153
160
|
req_doc: { type: "string", description: "需求档指针(add 可空 / update 缺省 = 不变)" },
|
|
154
161
|
task_book: { type: "string", description: "任务书指针(add 可空 / update 缺省 = 不变;在途 / 待核销必填——咬合 CHECK)" },
|
|
155
|
-
evidence: { type: "string", description: "最小证据行(add
|
|
156
|
-
|
|
162
|
+
evidence: { type: "string", description: "最小证据行(add 可空;update / close 传入 = 追加缺省——旧空直写、旧非空拼 `旧|新`(「|」零空格)、新值全空白 ⇒ 拒;覆盖 = 与 `evidenceReplace: true` 同传;update 缺省 = 不变 / close 缺省 = 判行值;追认核销须非空)" },
|
|
163
|
+
evidenceReplace: { type: "boolean", description: "覆盖旗(布尔):与 evidence 同传 = 整段替换;缺省 / false = 追加;旗独传(无新文)⇒ 拒(update / close)" },
|
|
164
|
+
trigger: { type: "string", enum: ["归批", "条件", "认账不排期"], description: "技术待办触发(add / update 可空 / query 过滤)" },
|
|
157
165
|
id: { type: "number", description: "条目 id(update / close 必填)" },
|
|
158
166
|
status: { type: "string", enum: ["待讨论", "待设计", "在途", "待核销", "已核销", "已废弃"], description: "状态(close 必填 ∈ {已核销, 已废弃};update 迁移 / query 过滤——六态之一)" },
|
|
159
|
-
executor: { type: "string", description: "执行者 sessionId(update 可选——接手改写归属;缺省 =
|
|
167
|
+
executor: { type: "string", description: "执行者 sessionId(update 可选——接手改写归属;缺省 = 按状态迁移语义:进入待设计 / 在途自动写本会话;出在途 / 撤回清空)" },
|
|
160
168
|
},
|
|
161
169
|
additionalProperties: false,
|
|
162
170
|
}
|
|
@@ -213,9 +221,9 @@ function makeLedgerTool(actions, { readonly = false, writeFace = false } = {}) {
|
|
|
213
221
|
return JSON.stringify(ledgerUpdate({ cwd: cwd ?? cwdOf(ctx), id, patch, executorSessionId }))
|
|
214
222
|
}
|
|
215
223
|
case "close":
|
|
216
|
-
return JSON.stringify(ledgerClose({ cwd: rest.cwd ?? cwdOf(ctx), id: rest.id, status: rest.status }))
|
|
224
|
+
return JSON.stringify(ledgerClose({ cwd: rest.cwd ?? cwdOf(ctx), id: rest.id, status: rest.status, evidence: rest.evidence, evidenceReplace: rest.evidenceReplace }))
|
|
217
225
|
case "query":
|
|
218
|
-
return JSON.stringify(ledgerQuery({ cwd: rest.cwd ?? cwdOf(ctx), status: rest.status, kind: rest.kind, board: rest.board }), null, 2)
|
|
226
|
+
return JSON.stringify(ledgerQuery({ cwd: rest.cwd ?? cwdOf(ctx), status: rest.status, kind: rest.kind, board: rest.board, trigger: rest.trigger }), null, 2)
|
|
219
227
|
case "count":
|
|
220
228
|
return JSON.stringify({ count: ledgerCount({ cwd: rest.cwd ?? cwdOf(ctx) }) })
|
|
221
229
|
default:
|
package/ledger.mjs
CHANGED
|
@@ -18,12 +18,10 @@
|
|
|
18
18
|
import { opendirSync, statSync } from "node:fs"
|
|
19
19
|
import { basename, dirname, join, resolve } from "node:path"
|
|
20
20
|
import { projectRootView } from "./manifest.mjs"
|
|
21
|
-
import { ledgerDbPath, PENDING_STATUSES } from "./ledger-db.mjs"
|
|
21
|
+
import { ledgerDbPath, PENDING_STATUSES, AGING_DAYS } from "./ledger-db.mjs"
|
|
22
22
|
import { ledgerQuery } from "./ledger-cmd.mjs"
|
|
23
23
|
import { executorTail } from "./ledger-executors.mjs"
|
|
24
24
|
|
|
25
|
-
/** 老化阈值(天——口径 = 需求档;`days` 参数可覆盖)。 */
|
|
26
|
-
export const AGING_DAYS = 30
|
|
27
25
|
/** 「可开批」阈值:同一板块(需求类条目 board 列)未决 ≥ 2。 */
|
|
28
26
|
export const THRESHOLD_BOARD = 2
|
|
29
27
|
/** 「可开批」阈值:需求池未决 ≥ 3。 */
|
|
@@ -65,8 +63,9 @@ export function findProject(anchor) {
|
|
|
65
63
|
/** 同级枚举上限(N2 成本有界:父目录超此规模 = 缓存 / 临时等非仓族形态 → 退化空集,只显当前项目)。 */
|
|
66
64
|
export const MAX_SIBLING_SCAN = 100
|
|
67
65
|
|
|
68
|
-
/** 目录下已注册台账的直接子目录(目录名升序;不可读 → [];**惰性枚举 + 上限**——大目录零全量扫描)。
|
|
69
|
-
|
|
66
|
+
/** 目录下已注册台账的直接子目录(目录名升序;不可读 → [];**惰性枚举 + 上限**——大目录零全量扫描)。
|
|
67
|
+
* 导出面 = 族发现(本档)∥ 轻通道闸候选枚举(`agent/light-round.mjs`——同级判据单源)。 */
|
|
68
|
+
export function ledgerChildren(dir) {
|
|
70
69
|
const out = []
|
|
71
70
|
let handle
|
|
72
71
|
try { handle = opendirSync(dir) } catch { return out }
|
|
@@ -87,7 +86,7 @@ function ledgerChildren(dir) {
|
|
|
87
86
|
}
|
|
88
87
|
|
|
89
88
|
/** 项目族发现:{current, projects}——projects = current + 其同级含台账库目录(**发现序:current 在前**,
|
|
90
|
-
* 其余按目录名升序);current 缺(容器目录,K6)→
|
|
89
|
+
* 其余按目录名升序);current 缺(容器目录,K6)→ 锚本地:取锚自身含台账库的直接子目录(不沿祖先链上找)。
|
|
91
90
|
* **歧义根不充当项目**(轻通道轮 · 2026-10-04):命中锚若项目解析 `ambiguous`(≥2 候选——`projectRootView`)
|
|
92
91
|
* ⇒ 该锚不可扫描(`openLedger` 歧义拒)——其键控库(先于 #828 写门的存量空壳 / 幽灵)不得遮蔽族发现;
|
|
93
92
|
* 按容器形落子目录族(需求:打开容器根 ⇒ 族内合计——标记范围批 §1 原话)。 */
|
|
@@ -99,14 +98,7 @@ export function discoverFamily(anchor) {
|
|
|
99
98
|
const siblings = ledgerChildren(dirname(current.root)).filter((p) => p.root !== current.root)
|
|
100
99
|
return { current, projects: [current, ...siblings] }
|
|
101
100
|
}
|
|
102
|
-
|
|
103
|
-
for (;;) {
|
|
104
|
-
const kids = ledgerChildren(dir)
|
|
105
|
-
if (kids.length) return { current: null, projects: kids }
|
|
106
|
-
const parent = dirname(dir)
|
|
107
|
-
if (parent === dir) return { current: null, projects: [] }
|
|
108
|
-
dir = parent
|
|
109
|
-
}
|
|
101
|
+
return { current: null, projects: ledgerChildren(resolve(anchor)) }
|
|
110
102
|
}
|
|
111
103
|
|
|
112
104
|
/** scan 组装(SQLite 行集 + 计数单源 → scan 对象)——形状契约(设计档 §2.2):pool/tech/aged/
|
|
@@ -185,8 +177,9 @@ export function detailScans(scans, current) {
|
|
|
185
177
|
return out
|
|
186
178
|
}
|
|
187
179
|
|
|
188
|
-
// ── re-export(拆分件接口——命令面接线 = 动态 import 本档,KD-M2-3
|
|
189
|
-
|
|
180
|
+
// ── re-export(拆分件接口——命令面接线 = 动态 import 本档,KD-M2-3;`AGING_DAYS` 常量单源 = `ledger-db.mjs`
|
|
181
|
+
// ——2026-10-07 批 ledger-tool 自本档迁入,公共面零变) ──
|
|
182
|
+
export { AGING_DAYS, ALLOWED_MIGRATIONS, ledgerDbPath, ledgerKey, ledgerDirPath, openLedger, PENDING_STATUSES, _setLedgerDirForTest, _resetLedgerDirForTest, ensureExecutorColumn } from "./ledger-db.mjs"
|
|
190
183
|
export { ledgerAdd, ledgerClose, ledgerCount, ledgerQuery, ledgerUpdate } from "./ledger-cmd.mjs"
|
|
191
184
|
export { ledgerTool, ledgerReadTool, ledgerAddTool, ledgerCloseTool, ledgerCountTool, ledgerQueryTool, ledgerUpdateTool } from "./ledger-tools.mjs"
|
|
192
185
|
export { runLedgerAudit, runLedgerMigrate } from "./ledger-migrate.mjs"
|
package/log.mjs
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* 工具事件不记 args;URL 不入事件(llm/tool 事件从不携带 URL;err 文本经形态扫描)。
|
|
22
22
|
* - 摘要截断(B 方案,2026-09-03 用户裁定):截断处带 "…" 标记(截后仍 ≤上限)。
|
|
23
23
|
* - 测试隔离:node --test 进程(NODE_TEST_CONTEXT)默认不写盘——防测试事件污染真实
|
|
24
|
-
*
|
|
24
|
+
* 诊断日志(两端测试都会跑真实 agent 管线);显式测试缝(_setLogsDirForTest)
|
|
25
25
|
* 强制写入该目录(log.test.mjs 用它隔离临时目录——refinement #6)。
|
|
26
26
|
* - 轮转清理(refinement #3——长驻进程覆盖):非仅启动时——每进程每日**首次写事件**
|
|
27
27
|
* 时顺带清理 >1 天的 agent-*.log(extension host 可长驻数月,启动清理覆盖不到)。
|
package/manifest-discovery.mjs
CHANGED
|
@@ -91,7 +91,7 @@ export function discoverRepos(cwd) {
|
|
|
91
91
|
* 的目录;无 ⇒ `null`(⇒ 调用方走发现兜底)。**嵌套合法**:子内归子、根其余归根。
|
|
92
92
|
* **纯 fs**(只判存在性——不解析档内容 / 不问模式)· **不跨兄弟** · **无全局优先级**。
|
|
93
93
|
* **覆盖位**(`_setProjectRootForTest` 在场)⇒ **头部短路**:直接返回覆盖值(不查档存在性——
|
|
94
|
-
* 保「覆盖即覆盖值」语义,回归守卫 =
|
|
94
|
+
* 保「覆盖即覆盖值」语义,回归守卫 = 本批单元测试档基座用例(`docs/batches/2026-10-02-manifest-resolution-fix.test.mjs`——
|
|
95
95
|
* 基座三态 + 覆盖位 + 薄委托等价逐格)+ `docs/batches/2026-09-29-structure-split-2.test.mjs` 导出枚举探针(`Object.keys` 名面核))。
|
|
96
96
|
* @param {string} [target] 目标路径(目录 / 文件)
|
|
97
97
|
* @returns {string|null} 最近带档祖先目录绝对路径 / null
|
package/manifest-schema.mjs
CHANGED
|
@@ -80,7 +80,7 @@ function isLineCountsValue(v) {
|
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
82
|
* 形状校验(模块设计 §2.2)——枚举 / version 数值恒做;**纯函数、零 fs**(原 `{ cwd }`
|
|
83
|
-
*
|
|
83
|
+
* 指针分支已随字段整链裁撤——KD-M1-5 墓志);不落盘。键存在性入 missingKeys(非拒):
|
|
84
84
|
* 缺键 = 便利 fallback(补默认值),不是错(与整档缺失两分——KD-M1-2)。
|
|
85
85
|
* 未知键(#802 / KD-M1-36):顶层 + 四嵌套层产 `unknownKeys`(非拒——ok 定性零变;产线恰 =
|
|
86
86
|
* fillDefaults 丢弃面;嵌套键用点形路径——同 missingKeys 口径)。
|
package/mcp/transport-stdio.mjs
CHANGED
|
@@ -10,7 +10,7 @@ let exiting = false
|
|
|
10
10
|
process.on("exit", () => { exiting = true })
|
|
11
11
|
|
|
12
12
|
/** 测试缝(先例 `provider/rate.mjs` `_rateHooks`):组杀 / 单进程杀 / 定时器可注入
|
|
13
|
-
* (POSIX 分流在生产 win32 机位的直驱 = 临时覆写 `process.platform
|
|
13
|
+
* (POSIX 分流在生产 win32 机位的直驱 = 临时覆写 `process.platform`——见单元测试档 T-A12–A14)。 */
|
|
14
14
|
export const _killHooks = {
|
|
15
15
|
groupKill: (pid, sig) => process.kill(-pid, sig),
|
|
16
16
|
childKill: (child, sig) => child.kill(sig),
|
package/mcp.mjs
CHANGED
|
@@ -52,7 +52,7 @@ export const _mcpHooks = {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/** initialize 请求参数单源(D-MC18):建连握手(doInitialize)与 transport 内 404 自愈重建共用——
|
|
55
|
-
* 建连时经 `transport.setInitPayload(...)`
|
|
55
|
+
* 建连时经 `transport.setInitPayload(...)` 注入。导出面供单元测试档复用(参数单源不可分叉)。 */
|
|
56
56
|
export function buildInitParams() {
|
|
57
57
|
return {
|
|
58
58
|
protocolVersion: "2024-11-05",
|
package/memory/code-index.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* memory/code-index.mjs — code and document chunking, language detection, symbol extraction
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { segmentCJK,
|
|
5
|
+
import { segmentCJK, BIG_FILE_LINES } from "./schema.mjs"
|
|
6
6
|
|
|
7
7
|
/** Infer file language by extension */
|
|
8
8
|
export function detectLanguage(filename) {
|
package/memory/code-search.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 内容 = `CODE_EMBED_BATCH` ∥ `codeSearch`(FTS5(BM25) + 向量余弦,RRF 合并;无 embedder ⇒ 纯 FTS,
|
|
4
4
|
* ftsQuery 空且有 embedder ⇒ 纯向量)∥ `ensureCodeEmbeddings`(并发锁 + `_runEnsureCodeEmbeddings`)
|
|
5
5
|
* ∥ `codeSearchTool`——迁出块逐字;原档 `memory/code-sync.mjs` 经 `export { … } from` 转口保名
|
|
6
|
-
* (消费面 /
|
|
6
|
+
* (消费面 / 单元测试档 import 面零改)。
|
|
7
7
|
*/
|
|
8
8
|
import { embed, embedTolerant, cosine, toBlob, fromBlob } from "../embedding.mjs"
|
|
9
9
|
import { scanVectors, createTopK } from "./scan.mjs"
|
package/memory/code-sync.mjs
CHANGED
|
@@ -281,6 +281,6 @@ export async function reindexFile(memory, cwd, absPath) {
|
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
// ─── 迁出面(2026-10-01 拆分批 · #755 ∥ #786):检索面 → `memory/code-search.mjs`;清单面 →
|
|
284
|
-
// `memory/file-list.mjs`——经本档转口保名(消费面 /
|
|
284
|
+
// `memory/file-list.mjs`——经本档转口保名(消费面 / 单元测试档 import 面零改),四起效点调用形零改。──────
|
|
285
285
|
export { codeSearch, ensureCodeEmbeddings, codeSearchTool } from "./code-search.mjs"
|
|
286
286
|
export { listProjectFiles, indexExtensions } from "./file-list.mjs"
|
package/memory/docs.mjs
CHANGED
|
@@ -104,13 +104,17 @@ export async function syncDocRoot(memory, dir, { onProgress, yieldFn = yieldTick
|
|
|
104
104
|
/**
|
|
105
105
|
* Doc search: FTS5(BM25) + optional vector cosine, RRF merged.
|
|
106
106
|
* Falls back to pure FTS when no embedder; falls back to pure vector when ftsQuery is empty and embedder is present.
|
|
107
|
+
* `origins`(可选覆盖参 · 2026-10-10 #1100):缺省 `null` ⇒ 现行为(本函数自取 `searchOrigins`)**逐字**;
|
|
108
|
+
* 给定 ⇒ 以其为 origin 集(复用既有单/多 origin SQL 形);空数组 ⇒ 现「不过滤」语义(本设计调用方不产此形)。
|
|
109
|
+
* 消费方 = `thincoder-core/agent/setup.mjs` 注入块两路分取(配额策略 = `docs/core/design/AGENT-LOOP.md` §6.3)。
|
|
107
110
|
*/
|
|
108
|
-
export async function docSearch(memory, query, { limit = 5 } = {}) {
|
|
111
|
+
export async function docSearch(memory, query, { limit = 5, origins: originsOverride = null } = {}) {
|
|
109
112
|
const ftsQuery = buildFtsQuery(query)
|
|
110
113
|
if (!ftsQuery && !memory.embedder) return []
|
|
111
114
|
|
|
112
115
|
// §6.15 读面 origin 集(项目 ∪ 声明公共仓;单 origin ⇒ 逐字零行为——快径 SQL 形零改)
|
|
113
|
-
|
|
116
|
+
// #1100:`origins` 覆盖参在位时以其为集(缺省 `null` ⇒ 原式逐字)
|
|
117
|
+
const origins = originsOverride ?? searchOrigins(memory)
|
|
114
118
|
const ftsOriginFilter = origins.length === 1 ? `AND d.origin = ?` : origins.length > 1 ? `AND d.origin IN (${origins.map(() => "?").join(", ")})` : ""
|
|
115
119
|
const originParams = origins
|
|
116
120
|
|
package/memory/file-list.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* memory/file-list.mjs — 项目文件清单面(自 `memory/code-sync.mjs` 迁出 · 2026-10-01 core 拆分批 #755 ∥ #786)。
|
|
3
3
|
* 内容 = `indexExtensions`(内置扩展名表 ∪ 项目声明并集)∥ `listProjectFiles`(git 列面 + 非 git walk
|
|
4
4
|
* 回退 + unlisted 计数;`index.excludePaths` §6.14 面① 双径过滤:git 列面筛行 ∥ walk 剪枝)——迁出块逐字。
|
|
5
|
-
* 原档 `memory/code-sync.mjs` 经 `export { … } from` 转口保名(消费面 /
|
|
5
|
+
* 原档 `memory/code-sync.mjs` 经 `export { … } from` 转口保名(消费面 / 单元测试档 import 面零改)。
|
|
6
6
|
*/
|
|
7
7
|
import { CODE_EXTS, DOC_EXTS } from "./schema.mjs"
|
|
8
8
|
import { walkProjectFiles, isSkippedRelPath, extensionOf, createUnlistedTally, MAX_WALK_FILES } from "./file-walk.mjs"
|
package/memory/file-walk.mjs
CHANGED
|
@@ -10,20 +10,32 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { readdir } from "node:fs/promises"
|
|
12
12
|
import { join } from "node:path"
|
|
13
|
-
import { SKIP_DIRS } from "./schema.mjs"
|
|
13
|
+
import { SKIP_DIRS, SKIP_DIRS_FOLD, SKIP_DIR_PREFIXES } from "./schema.mjs"
|
|
14
|
+
|
|
15
|
+
/** win32 fold index for the junk/product family (canonical spellings live in `SKIP_DIRS_FOLD`). */
|
|
16
|
+
const SKIP_DIRS_FOLD_LOWER = new Set([...SKIP_DIRS_FOLD].map((n) => n.toLowerCase()))
|
|
14
17
|
|
|
15
18
|
/** Upper guard for the walk: stop after this many matched files (runaway trees). */
|
|
16
19
|
export const MAX_WALK_FILES = 20000
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
|
-
* Shared skip predicate for project-relative paths
|
|
20
|
-
*
|
|
22
|
+
* Shared skip predicate for project-relative paths (§6.14 面④ family split · 台账 #1081): exact
|
|
23
|
+
* basename (`SKIP_DIRS`) ∨ segment prefix (`SKIP_DIR_PREFIXES` — `bazel-*`; POSIX literal ∥ win32
|
|
24
|
+
* folded) ∨ (win32 only) folded junk/product family (`SKIP_DIRS_FOLD`); dot segments via the dot
|
|
25
|
+
* rule. `platform` is a test seam (default `process.platform`; callers keep the one-arg form).
|
|
21
26
|
*/
|
|
22
|
-
export function isSkippedRelPath(rel) {
|
|
27
|
+
export function isSkippedRelPath(rel, platform = process.platform) {
|
|
28
|
+
const fold = platform === "win32"
|
|
23
29
|
return String(rel ?? "")
|
|
24
30
|
.replace(/\\/g, "/")
|
|
25
31
|
.split("/")
|
|
26
|
-
.some((seg) =>
|
|
32
|
+
.some((seg) => {
|
|
33
|
+
if (seg === "") return false
|
|
34
|
+
if (seg.startsWith(".")) return true
|
|
35
|
+
if (SKIP_DIRS.has(seg)) return true
|
|
36
|
+
if (SKIP_DIR_PREFIXES.some((p) => (fold ? seg.toLowerCase() : seg).startsWith(p))) return true
|
|
37
|
+
return fold && SKIP_DIRS_FOLD_LOWER.has(seg.toLowerCase())
|
|
38
|
+
})
|
|
27
39
|
}
|
|
28
40
|
|
|
29
41
|
/** Lower-cased ".ext" of a path, or "" when it has no extension. */
|