aura-basetools-dsh 0.13.3 → 0.14.0

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 CHANGED
@@ -1,4 +1,4 @@
1
- # aura-basetools-dsh 0.13.3
1
+ # aura-basetools-dsh 0.14.0
2
2
 
3
3
  DeepSeek Harness adapter for `aura-basetools`. The core package is DSH-free; this package adds the `aura_basetools_*` tools and the hook executor.
4
4
 
@@ -11,9 +11,9 @@ DeepSeek Harness adapter for `aura-basetools`. The core package is DSH-free; thi
11
11
  ### Install
12
12
 
13
13
  ```bash
14
- npm i aura-basetools-dsh@0.13.3
14
+ npm i aura-basetools-dsh@0.14.0
15
15
  # or:
16
- dsh plugin --profile web add aura-basetools-dsh@0.13.3
16
+ dsh plugin --profile web add aura-basetools-dsh@0.14.0
17
17
  ```
18
18
 
19
19
  Requires a DSH host that provides `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-shell`, and `@deepseek-ai/schemastery`. These peers are declared optional so a plain npm install does not try to fetch private packages; a missing peer fails loudly when the module is imported.
@@ -48,9 +48,9 @@ This package is only the DSH adapter. Core behavior, CLI, MCP, byte-fidelity gua
48
48
  ### 安装
49
49
 
50
50
  ```bash
51
- npm i aura-basetools-dsh@0.13.3
51
+ npm i aura-basetools-dsh@0.14.0
52
52
  # 或:
53
- dsh plugin --profile web add aura-basetools-dsh@0.13.3
53
+ dsh plugin --profile web add aura-basetools-dsh@0.14.0
54
54
  ```
55
55
 
56
56
  需要 DSH 宿主提供 `@deepseek-ai/dsh-tools`、`@deepseek-ai/dsh-shell`、`@deepseek-ai/schemastery`。这些 peer 标为 optional,避免普通 npm 安装去解析私有包;缺 peer 时在 import 阶段明确失败。
@@ -104,18 +104,6 @@ const HUNK_PROPERTIES = {
104
104
  description:
105
105
  'Symbol to replace, e.g. `toTodoList`, `function:apply`, `Outer/Inner`, `name#2`. Skips all text matching, so it is immune to misremembered content.',
106
106
  },
107
- /**
108
- * 意图地址(T16):调用方给一段**模糊**的意图串,引擎确定性地落到一个精确区间。
109
- *
110
- * 这是比 `target` 更弱、比 `anchor` 更自由的一层:它先当符号名解析(含 `name#n` 等写法),
111
- * 再按符号名子串匹配,最后落到文本匹配。落不下来就报歧义并给候选,**不猜**。
112
- * 它与其余地址字段互斥(`PATCH_INTENT_CONFLICT`):同时给两个地址时谁说了算没有正确答案。
113
- */
114
- intent: {
115
- type: 'string',
116
- description:
117
- 'Fuzzy intent address: a symbol-name fragment, a phrase, or approximate text (e.g. `parseConfig`, `config loader`, `// retry the upload`). Resolved deterministically to one exact region; an ambiguous intent is refused with candidates. Use it alone (not with target/lines/line_cue/anchor/old/context/handle); `near` and `expect` are allowed.',
118
- },
119
107
  // 与 aura_basetools_read 同一套宽容声明:模型把区间写成 `4, 6` 时那不是合法 JSON(宿主在参数层就拒),
120
108
  // 写成 `"4,6"` / `4` 则是合法 JSON 但形状不对——声明宽一点,能容的都容下来。
121
109
  lines: {
@@ -174,7 +162,7 @@ const HUNK_PROPERTIES = {
174
162
  replace_all: {
175
163
  type: 'boolean',
176
164
  description:
177
- 'With `old`: replace every non-overlapping occurrence, not just a unique one. Left-to-right; cannot be combined with target/intent/lines/line_cue/anchor/context/handle/near (those narrow to one place). If the occurrence count changed since your last read, the whole patch is refused.',
165
+ 'With `old`: replace every non-overlapping occurrence, not just a unique one. Left-to-right; cannot be combined with target/lines/line_cue/anchor/context/handle/near (those narrow to one place). If the occurrence count changed since your last read, the whole patch is refused.',
178
166
  },
179
167
  eol: {
180
168
  type: 'string',
@@ -306,7 +294,7 @@ function hunkListOf(args) {
306
294
  * 名单在这里是为了"被忽略的一方"能被逐字点名——不是第二份寻址判据:
307
295
  * 谁真的生效由引擎决定(`write-path.mjs`),这里只报告"调用方还给了这些"。
308
296
  */
309
- const ADDRESS_KEYS_BESIDE_HANDLE = ['old', 'context', 'lines', 'start_line', 'end_line', 'line_cue', 'anchor', 'target', 'intent']
297
+ const ADDRESS_KEYS_BESIDE_HANDLE = ['old', 'context', 'lines', 'start_line', 'end_line', 'line_cue', 'anchor', 'target']
310
298
 
311
299
  /** 这个键这次**真的给了**吗(判据与 `flatHunk` 一致:跳过 undefined / null / 空串 / 空数组)。 */
312
300
  function gaveKey(source, key) {
@@ -571,9 +559,6 @@ const OUTCOME_BY_CODE = new Map([
571
559
  ['PATCH_AMBIGUOUS', 'needs_choice'],
572
560
  ['LOCATOR_AMBIGUOUS', 'needs_choice'],
573
561
  ['LOCATOR_CUE_AMBIGUOUS', 'needs_choice'],
574
- // 意图地址(T16):落不下来时**拒绝并给候选**(不猜),没命中时给可执行的替代地址。
575
- ['LOCATOR_INTENT_AMBIGUOUS', 'needs_choice'],
576
- ['LOCATOR_INTENT_NOT_FOUND', 'not_found'],
577
562
  /**
578
563
  * 句柄路的四种**如实拒绝**(契约 §5 解析次序 / §9 的 D6):句柄过期、身份标签不符、
579
564
  * 段内行号越界、`{handle, old}` 而引文不在该区间内。
@@ -1849,20 +1834,35 @@ function registerTools(ctx, sandbox) {
1849
1834
  exec.signal,
1850
1835
  policy,
1851
1836
  )
1852
- ctx.emit('fs/observed', target, { kind: 'present', version: created.version }, exec)
1837
+ /**
1838
+ * 创建前的 resolve 拿不到 realpath(文件还不存在),targetKey 只能是调用方写法;
1839
+ * 文件落盘后必须**重新 resolve** 一次,拿盘上的真名记观测。macOS 的
1840
+ * `/var/folders/...` 是 `/private/var/...` 的符号链接:不重算,创建记在 `/var`、
1841
+ * 紧接着编辑拿 `/private/var` 查账,就会误报 unverified_region(stale-gate 段I)。
1842
+ */
1843
+ let settled = target
1844
+ try {
1845
+ settled = await ctx.fs.resolve(args.file_path, {
1846
+ ...(cwd === undefined ? {} : { cwd }),
1847
+ signal: exec.signal,
1848
+ })
1849
+ } catch {
1850
+ // 重算失败不改变已落盘的事实;退回创建前的 target,至少行为与旧版一致。
1851
+ }
1852
+ ctx.emit('fs/observed', settled, { kind: 'present', version: created.version }, exec)
1853
1853
  // 建文件也是一次“写成功” ⇒ 同样回读校验(create 被偷偷改写的后果与编辑一样真)。
1854
- const createdVerification = await verifyWriteBack(ctx.fs, target, createContent, target.displayPath, exec.signal)
1854
+ const createdVerification = await verifyWriteBack(ctx.fs, settled, createContent, settled.displayPath ?? target.displayPath, exec.signal)
1855
1855
  // 新建的内容也是“自己刚写过的内容” ⇒ 记成最新观测,随后编辑它不必带 unverified_region。
1856
1856
  // 记账同样取**提供方视角**:内容自带前导 U+FEFF 时,下一次 readText 会剥掉一个,
1857
1857
  // 存原样就会让随后的未断言编辑第 1 行被误拒(F1 就是这条)。
1858
1858
  const createdView = providerView(createContent)
1859
1859
  const createdByteOrderMark = createContent.startsWith(BYTE_ORDER_MARK)
1860
1860
  rememberRead(
1861
- target.displayPath,
1861
+ settled.displayPath ?? target.displayPath,
1862
1862
  contentToken(createdView, createdByteOrderMark),
1863
1863
  createdView,
1864
1864
  createdByteOrderMark,
1865
- target.targetKey,
1865
+ settled.targetKey ?? target.targetKey,
1866
1866
  )
1867
1867
  return {
1868
1868
  path: target.displayPath,
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "aura-basetools-dsh",
3
- "version": "0.13.3",
3
+ "version": "0.14.0",
4
4
  "description": "DeepSeek Harness adapter for aura-basetools: aura_basetools_* tools and hook executor. Depends on the DSH-free core package. / aura-basetools 的 DSH 适配器。",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "dependencies": {
8
- "aura-basetools": "0.13.3"
8
+ "aura-basetools": "0.14.0"
9
9
  },
10
10
  "peerDependencies": {
11
11
  "@deepseek-ai/dsh-tools": "*",