@thincoder/core 0.10.3 → 0.10.5
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 +62 -0
- package/README.md +1 -1
- package/advisor/citations.mjs +29 -3
- package/advisor/compaction.mjs +31 -7
- package/advisor/history.mjs +8 -6
- package/advisor/loop.mjs +29 -27
- package/advisor/messages.mjs +2 -1
- package/advisor/run.mjs +9 -5
- package/advisor/timeline.mjs +26 -0
- package/advisor.mjs +4 -2
- package/agent/assemble.mjs +1 -1
- package/agent/chat-call.mjs +1 -1
- package/agent/child-marks.mjs +2 -2
- package/agent/completion.mjs +3 -1
- package/agent/digest-account.mjs +189 -0
- package/agent/dispatch-gates.mjs +8 -0
- package/agent/dispatch.mjs +39 -18
- package/agent/family-tools.mjs +27 -16
- package/agent/helpers.mjs +12 -3
- package/agent/light-round.mjs +66 -0
- package/agent/post-turn.mjs +8 -4
- package/agent/record-results.mjs +4 -0
- package/agent/run-stages.mjs +32 -7
- package/agent/run-start.mjs +50 -3
- package/agent/setup-reminders.mjs +1 -1
- package/agent/setup.mjs +18 -3
- package/agent/subagent-event.mjs +1 -1
- package/agent/suspension.mjs +37 -12
- package/agent/timers.mjs +56 -5
- package/agent/turn-loop.mjs +30 -5
- package/agent/write-gate.mjs +20 -32
- package/agent-tools/advisor-async.mjs +15 -7
- package/agent-tools/advisor-settle.mjs +2 -2
- package/agent-tools/advisor.mjs +34 -33
- package/agent-tools/async-discard.mjs +34 -0
- package/agent-tools/async-settle.mjs +32 -7
- package/agent-tools/audit-block.mjs +1 -1
- package/agent-tools/bash-async.mjs +1 -1
- package/agent-tools/batch-lifecycle.mjs +59 -17
- package/agent-tools/batch-paths.mjs +24 -4
- package/agent-tools/batch-skeleton.mjs +59 -43
- package/agent-tools/batch.mjs +39 -18
- 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/design-token.mjs +20 -0
- package/agent-tools/digest-budget.mjs +1 -1
- package/agent-tools/escalate-async.mjs +4 -2
- package/agent-tools/manifest.mjs +193 -0
- package/agent-tools/parent-channel.mjs +7 -4
- package/agent-tools/review-facts.mjs +143 -16
- package/agent-tools/settings.mjs +1 -1
- package/agent-tools/skill.mjs +1 -1
- package/agent-tools/subagent-actions-query.mjs +13 -6
- package/agent-tools/subagent-async.mjs +31 -15
- package/agent-tools/subagent-panel.mjs +2 -1
- package/agent-tools/subagent-scheduler.mjs +8 -5
- package/agent-tools/subagent-spawn.mjs +30 -56
- package/agent-tools/subagent.mjs +21 -8
- package/agent-tools/timer.mjs +186 -12
- package/agent-tools/zero-write-watch.mjs +77 -0
- package/agent-tools.mjs +2 -1
- package/agent.mjs +2 -2
- package/attachments.mjs +1 -1
- 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 +28 -8
- package/declaration.mjs +18 -2
- package/escape.mjs +1 -1
- package/file-links.mjs +1 -1
- package/file-refs.mjs +1 -1
- package/history-window.mjs +1 -1
- package/i18n.mjs +7 -0
- package/ledger-cmd.mjs +62 -16
- package/ledger-db.mjs +6 -0
- package/ledger-surface.mjs +49 -5
- package/ledger-tools.mjs +158 -87
- package/ledger-variant-notice.mjs +47 -0
- package/ledger.mjs +11 -18
- package/log.mjs +1 -1
- package/manifest-discovery.mjs +1 -1
- package/manifest-schema.mjs +7 -5
- package/manifest.mjs +5 -3
- 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 +1 -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 +38 -4
- 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 +18 -9
- package/prompts/persona-normal.md +2 -0
- package/prompts/subagent-base.md +3 -0
- package/provider/anthropic.mjs +14 -2
- package/provider/core.mjs +6 -0
- package/provider/errors.mjs +28 -3
- package/provider/google.mjs +22 -10
- package/provider/list-models.mjs +3 -2
- package/provider/responses-request.mjs +3 -1
- package/provider/responses.mjs +38 -4
- 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/shell-identity.mjs +107 -0
- package/team-ledger.mjs +282 -0
- package/team.mjs +223 -0
- package/tool-docs/advisor.md +1 -1
- package/tool-docs/bash.md +2 -1
- package/tool-docs/batch.md +1 -1
- package/tool-docs/browser.md +48 -0
- package/tool-docs/delete.md +7 -5
- package/tool-docs/ledger.md +6 -0
- 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 +14 -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/bash.mjs +9 -4
- package/tools/browser.mjs +161 -0
- package/tools/git.mjs +1 -1
- package/tools/index.mjs +4 -4
- package/tools/ops.mjs +26 -10
- package/tools/patch.mjs +8 -2
- package/tools/repomap.mjs +1 -1
- package/tools/write-path.mjs +8 -6
- package/traces/trace-cleanup.mjs +1 -1
- package/traces/trace-store.mjs +1 -1
- package/vision-reader.mjs +10 -16
- package/tool-docs/ledger_add.md +0 -1
- package/tool-docs/ledger_close.md +0 -1
- package/tool-docs/ledger_count.md +0 -1
- package/tool-docs/ledger_query.md +0 -1
- package/tool-docs/ledger_update.md +0 -1
package/ledger.mjs
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* 锁死、COUNT 单源计数、事务保证收口原子、归档 = 软删除。行龄源 = SQLite 时间戳(无 git blame)。
|
|
7
7
|
*
|
|
8
8
|
* 面:① 命令族(查询 = 只读全角色 / 写 = 仅主 agent——核函数 `ledger-cmd.mjs` + 工具定义 `ledger-tools.mjs`
|
|
9
|
-
* 两源,接线见
|
|
9
|
+
* 两源,接线见 `agent/family-tools.mjs`——统一入口 `ledger` 两变体,2026-10-05 统一入口批)
|
|
10
10
|
* ② 族发现(findProject / discoverFamily——标记 = ledger.db)③ scan 组装(buildScan——行集 + ledgerCount
|
|
11
11
|
* → scan 对象,形状契约 = pool/tech/aged/thresholdReached/actionable/root/name/ledger)
|
|
12
12
|
* ④ 格式 helper(L1 标记 ∥ L2 明细行逐字契约——含标记范围归约 `scopeMarkerOf`,§7.2)。
|
|
@@ -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,9 +177,10 @@ 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
|
-
export { ledgerAddTool, ledgerCloseTool, ledgerCountTool, ledgerQueryTool, ledgerUpdateTool } from "./ledger-tools.mjs"
|
|
184
|
+
export { ledgerTool, ledgerReadTool, ledgerAddTool, ledgerCloseTool, ledgerCountTool, ledgerQueryTool, ledgerUpdateTool } from "./ledger-tools.mjs"
|
|
192
185
|
export { runLedgerAudit, runLedgerMigrate } from "./ledger-migrate.mjs"
|
|
193
186
|
export { resolveExecutorStates, executorTail, _setExecutorProbeTtlForTest } from "./ledger-executors.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
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* `docRoot` 子键**值形态判据**(F7 / KD-M1-6 / KD-M1-8——判据单源):非空字符串(`trim` 后
|
|
15
|
-
* 非空),或非空数组且元素皆非空字符串(**同款口径**:元素 `trim`
|
|
16
|
-
* 空白串 / 空数组 / 数组含非串 / 空串 /
|
|
15
|
+
* 非空),或非空数组且元素皆非空字符串(**同款口径**:元素 `trim` 后非空),或 `null`
|
|
16
|
+
* (**「本面无」合法哨兵**——KD-M1-37);其余(空串 / 空白串 / 空数组 / 数组含非串 / 空串 /
|
|
17
|
+
* 空白串元素 / 非串非数组)为非法。
|
|
17
18
|
* @param {unknown} value docRoot 某子键的值
|
|
18
19
|
* @returns {boolean}
|
|
19
20
|
*/
|
|
20
21
|
export function isValidDocRootValue(value) {
|
|
22
|
+
if (value === null) return true
|
|
21
23
|
if (typeof value === "string") return value.trim() !== ""
|
|
22
24
|
if (!Array.isArray(value) || value.length === 0) return false
|
|
23
25
|
return value.every((p) => typeof p === "string" && p.trim() !== "")
|
|
@@ -78,7 +80,7 @@ function isLineCountsValue(v) {
|
|
|
78
80
|
|
|
79
81
|
/**
|
|
80
82
|
* 形状校验(模块设计 §2.2)——枚举 / version 数值恒做;**纯函数、零 fs**(原 `{ cwd }`
|
|
81
|
-
*
|
|
83
|
+
* 指针分支已随字段整链裁撤——KD-M1-5 墓志);不落盘。键存在性入 missingKeys(非拒):
|
|
82
84
|
* 缺键 = 便利 fallback(补默认值),不是错(与整档缺失两分——KD-M1-2)。
|
|
83
85
|
* 未知键(#802 / KD-M1-36):顶层 + 四嵌套层产 `unknownKeys`(非拒——ok 定性零变;产线恰 =
|
|
84
86
|
* fillDefaults 丢弃面;嵌套键用点形路径——同 missingKeys 口径)。
|
|
@@ -110,9 +112,9 @@ export function validateManifest(obj) {
|
|
|
110
112
|
}
|
|
111
113
|
for (const sub of subkeys) {
|
|
112
114
|
if (!(sub in value)) { missingKeys.push(`${nested}.${sub}`); continue } // 子键路径(AC-3 / T3b)
|
|
113
|
-
// docRoot 子键值形态(F7 / KD-M1-7):串 |
|
|
115
|
+
// docRoot 子键值形态(F7 / KD-M1-7 / KD-M1-37):串 | 非空串数组 | null(本面无);非法 → 拒(不静默跳过)。
|
|
114
116
|
if (nested === "docRoot" && !isValidDocRootValue(value[sub])) {
|
|
115
|
-
errors.push(`docRoot.${sub} 值形态非法:${JSON.stringify(value[sub])}
|
|
117
|
+
errors.push(`docRoot.${sub} 值形态非法:${JSON.stringify(value[sub])}(须为非空字符串 / 非空字符串数组 / null(本面无)——KD-M1-6 / KD-M1-7 / KD-M1-37)`)
|
|
116
118
|
}
|
|
117
119
|
// checkConfig.lineCounts 元素层形态(#546):数组,元素 = { doc, section } 非空串;非法 → 拒(不静默跳过)。
|
|
118
120
|
if (nested === "checkConfig" && sub === "lineCounts" && !isLineCountsValue(value[sub])) {
|
package/manifest.mjs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* 未知键(#802 / KD-M1-36)→ 产 unknownKeys + 一行可见告警(console.warn + logEvent;
|
|
11
11
|
* 同档同键集去重、读到零未知键清该档 memo)——非拒定性零变。
|
|
12
12
|
* - validateManifest(obj) → { ok, errors, missingKeys, unknownKeys }:枚举 / version 数值 /
|
|
13
|
-
* docRoot 子键值形态(串 |
|
|
13
|
+
* docRoot 子键值形态(串 | 数组 | null(本面无——KD-M1-37),F7)+ checkConfig.lineCounts 元素层形态——**纯函数、零 fs**;不落盘。
|
|
14
14
|
* - 三族声明键(`codePaths` / `index.{codeExtensions,docExtensions,publicRepos}` / `advisor.{docMap,standardsDoc}`——
|
|
15
15
|
* KD-M1-31 / M1-32):缺键补默认;形态错 = 档非法(fail-closed,与 docRoot 子键同款);
|
|
16
16
|
* 读向 = `declaration.mjs`(2026-10-01 自 `conventions.mjs` 迁出——经其转口可达)经 `readManifest` /
|
|
@@ -101,13 +101,15 @@ export function docRootBase(cwd) {
|
|
|
101
101
|
* `docRoot` 子键值 → **绝对路径数组**(F7 / §2.7 解析管线——全在本模块一处):展开(串 /
|
|
102
102
|
* 数组统一成列表)→ 逐元素 `trim` + `\` 归一 → `resolve(docRootBase(cwd), p)`(基数 =
|
|
103
103
|
* 项目根,不回退原始 cwd)→ 去重(保序)。非法形态 → `[]`(零根——拒面在 `validateManifest`,
|
|
104
|
-
* 本函数不判错;两处共用 `isValidDocRootValue
|
|
105
|
-
*
|
|
104
|
+
* 本函数不判错;两处共用 `isValidDocRootValue`,判据单源)。`null`(本面无)⇒ `[]`(**合法
|
|
105
|
+
* 零根——非错**;#944 / KD-M1-37)。
|
|
106
|
+
* @param {unknown} value docRoot 某子键的值(串 | 数组 | `null`)
|
|
106
107
|
* @param {string} [cwd] 会话锚(基数由 docRootBase 解析为项目根)
|
|
107
108
|
* @returns {string[]} 绝对路径(去重保序)
|
|
108
109
|
*/
|
|
109
110
|
export function docRootPaths(value, cwd) {
|
|
110
111
|
if (!isValidDocRootValue(value)) return []
|
|
112
|
+
if (value === null) return [] // 「本面无」(#944):合法零根——非错(不展开、不报错)
|
|
111
113
|
const base = docRootBase(cwd)
|
|
112
114
|
const list = (Array.isArray(value) ? value : [value]).map((p) => resolve(base, p.trim().replace(/\\/g, "/")))
|
|
113
115
|
return [...new Set(list)]
|
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. */
|