aura-basetools 0.16.0 → 0.17.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 +5 -5
- package/bin/aura-mcp.mjs +31 -0
- package/lib/ops.mjs +5 -0
- package/package.json +1 -1
- package/test/standalone-test.mjs +1 -1
- package/test/write-test.mjs +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# aura-basetools 0.
|
|
1
|
+
# aura-basetools 0.17.0
|
|
2
2
|
|
|
3
3
|
Byte-exact file tools for coding agents: read by intent, edit by address, and write whole files without corrupting bytes. One engine shared by a standalone CLI and an MCP server.
|
|
4
4
|
|
|
@@ -21,7 +21,7 @@ The engine is intentionally not a general file manager: it reads and edits UTF-8
|
|
|
21
21
|
### Install
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
npm i -g aura-basetools@0.
|
|
24
|
+
npm i -g aura-basetools@0.17.0
|
|
25
25
|
aura --version
|
|
26
26
|
```
|
|
27
27
|
|
|
@@ -91,7 +91,7 @@ Compared with the DSH built-in `dsh-tool-fs` tools, the differences are delibera
|
|
|
91
91
|
- **Edits refuse stale bases.** A region-level gate rejects an edit when the addressed region changed after the read that authorized it, and points at the lines to re-read; `expect` makes the intended text explicit.
|
|
92
92
|
- **Writes are verified, not assumed.** Every write goes through a temp file, flush, rename, and a byte-for-byte read-back; multi-target edits plan first and write nothing if any target fails.
|
|
93
93
|
- **Changes can prove themselves.** `edit` / `write` accept an explicit `verify` command; a non-zero exit or timeout rolls the transaction back and returns the command output plus the rollback state. No auto-discovery of repo scripts.
|
|
94
|
-
- **Changes can span calls.** `tx begin` opens a transaction; `edit` / `write` with `--tx <id>` append to it; `tx commit` checks files were not changed externally (`TX_STALE`) and can run `verify`; `tx rollback` restores all of them.
|
|
94
|
+
- **Changes can span calls.** `tx begin` opens a transaction; `edit` / `write` with `--tx <id>` append to it; `tx commit` checks files were not changed externally (`TX_STALE`) and can run `verify`; `tx rollback` restores all of them. MCP exposes the same lifecycle as `aura_basetools_tx` plus the `transaction` field on edit/write.
|
|
95
95
|
- **Addressing is structural.** `target` / `lines` / `old` / `expect` / handles replace "copy the literal text exactly"; failure receipts include ready-to-use retry addresses.
|
|
96
96
|
- **The core is DSH-free.** `aura-basetools` has no runtime dependencies and no DSH imports; the DSH adapter is a separate optional package.
|
|
97
97
|
|
|
@@ -136,7 +136,7 @@ MIT.
|
|
|
136
136
|
### 安装
|
|
137
137
|
|
|
138
138
|
```bash
|
|
139
|
-
npm i -g aura-basetools@0.
|
|
139
|
+
npm i -g aura-basetools@0.17.0
|
|
140
140
|
aura --version
|
|
141
141
|
```
|
|
142
142
|
|
|
@@ -206,7 +206,7 @@ npx -y --package aura-basetools aura basetools mcp
|
|
|
206
206
|
- **依据过期就拒绝。** 区域级陈旧闸门在“授权读取之后该区域被改过”时拒绝,并指出重读哪几行;`expect` 让目标原文显式化。
|
|
207
207
|
- **写完要验,不靠相信。** 每次写盘走临时文件、flush、rename,再做逐字节回读;多目标先全量规划,任一失败则一个字节都不写。
|
|
208
208
|
- **变更可以自证。** `edit` / `write` 接受显式 `verify` 命令;非零退出或超时会把整个事务回滚,回执带命令输出与回滚状态。不自动发现仓库脚本。
|
|
209
|
-
- **变更可以跨调用。** `tx begin` 开事务;`edit` / `write --tx <id>` 追加;`tx commit` 先检查文件没被外部改过(`TX_STALE`),可带 `verify`;`tx rollback` 恢复全部。
|
|
209
|
+
- **变更可以跨调用。** `tx begin` 开事务;`edit` / `write --tx <id>` 追加;`tx commit` 先检查文件没被外部改过(`TX_STALE`),可带 `verify`;`tx rollback` 恢复全部。MCP 用同一个生命周期:`aura_basetools_tx` + edit/write 的 `transaction` 字段。
|
|
210
210
|
- **寻址是结构化的。** `target` / `lines` / `old` / `expect` / 句柄替代“把原文一字不差抄对”;失败回执带可直接用的重试地址。
|
|
211
211
|
- **核心不依赖 DSH。** `aura-basetools` 零运行时依赖、无 DSH import;DSH 适配器是独立可选包。
|
|
212
212
|
|
package/bin/aura-mcp.mjs
CHANGED
|
@@ -30,6 +30,10 @@ import {
|
|
|
30
30
|
// 多目标(fs-contract-v2)的引擎绑定:与单目标同一处(`lib/ops.mjs`),bin 里不另找引擎。
|
|
31
31
|
readManyWith,
|
|
32
32
|
editManyEnvelope,
|
|
33
|
+
beginTransactionEnvelope,
|
|
34
|
+
commitTransactionEnvelope,
|
|
35
|
+
rollbackTransactionEnvelope,
|
|
36
|
+
statusTransactionEnvelope,
|
|
33
37
|
assertReadTargets,
|
|
34
38
|
assertEditTargets,
|
|
35
39
|
assertTargetShape,
|
|
@@ -204,6 +208,7 @@ const TOOLS = [
|
|
|
204
208
|
type: 'string',
|
|
205
209
|
description: '写后验证命令(显式给出才执行;在 workspace 根下、受超时/输出上限约束)。非零退出 ⇒ 自动回滚并返回 PATCH_VERIFY_FAILED。不自动发现/执行仓库脚本。',
|
|
206
210
|
},
|
|
211
|
+
transaction: { type: 'string', description: '跨调用事务 id(tx begin 返回);本次修改追加到该事务,不立即 commit' },
|
|
207
212
|
create: { type: 'string', description: '文件不存在时用它创建(整份内容)' },
|
|
208
213
|
targets: TARGETS_SCHEMA,
|
|
209
214
|
},
|
|
@@ -245,10 +250,25 @@ const TOOLS = [
|
|
|
245
250
|
type: 'string',
|
|
246
251
|
description: '写后验证命令(显式给出才执行;非零退出 ⇒ 自动回滚并返回 PATCH_VERIFY_FAILED)。',
|
|
247
252
|
},
|
|
253
|
+
transaction: { type: 'string', description: '跨调用事务 id(tx begin 返回);本次修改追加到该事务,不立即 commit' },
|
|
248
254
|
},
|
|
249
255
|
required: ['file_path', 'content'],
|
|
250
256
|
},
|
|
251
257
|
},
|
|
258
|
+
{
|
|
259
|
+
name: 'aura_basetools_tx',
|
|
260
|
+
description:
|
|
261
|
+
'Begin, commit, rollback, or inspect a cross-call transaction. Begin returns an id; pass it to edit/write `transaction` to append changes; commit checks each written file was not changed externally and can run `verify`; rollback restores all files.',
|
|
262
|
+
inputSchema: {
|
|
263
|
+
type: 'object',
|
|
264
|
+
properties: {
|
|
265
|
+
action: { type: 'string', enum: ['begin', 'commit', 'rollback', 'status'] },
|
|
266
|
+
transaction: { type: 'string', description: 'tx begin 返回的事务 id(begin 时不需要)' },
|
|
267
|
+
verify: { type: 'string', description: 'commit 时的写后验证命令;失败 ⇒ 整个事务回滚' },
|
|
268
|
+
},
|
|
269
|
+
required: ['action'],
|
|
270
|
+
},
|
|
271
|
+
},
|
|
252
272
|
]
|
|
253
273
|
|
|
254
274
|
/**
|
|
@@ -333,6 +353,7 @@ async function editTargetsCall(provider, args) {
|
|
|
333
353
|
dryRun: args.dry_run === true,
|
|
334
354
|
...(args.require_observation === true ? { requireObservation: true } : {}),
|
|
335
355
|
...(typeof args.verify === 'string' ? { verify: args.verify } : {}),
|
|
356
|
+
...(typeof args.transaction === 'string' ? { transaction: args.transaction } : {}),
|
|
336
357
|
})
|
|
337
358
|
}
|
|
338
359
|
|
|
@@ -383,6 +404,14 @@ async function callTool(provider, name, args = {}) {
|
|
|
383
404
|
}
|
|
384
405
|
}
|
|
385
406
|
}
|
|
407
|
+
if (name === 'aura_basetools_tx') {
|
|
408
|
+
const action = args.action
|
|
409
|
+
if (action === 'begin') return beginTransactionEnvelope(provider)
|
|
410
|
+
if (action === 'commit') return await commitTransactionEnvelope(provider, { id: args.transaction, verify: args.verify })
|
|
411
|
+
if (action === 'rollback') return await rollbackTransactionEnvelope(provider, { id: args.transaction })
|
|
412
|
+
if (action === 'status') return statusTransactionEnvelope(provider, { id: args.transaction })
|
|
413
|
+
return { ok: false, error: 'aura_basetools_tx needs action = begin | commit | rollback | status', code: 'BAD_ARGS' }
|
|
414
|
+
}
|
|
386
415
|
if (name === 'aura_basetools_read') {
|
|
387
416
|
if (multi) return await readTargetsCall(provider, args)
|
|
388
417
|
const noShape = noShapeRefusal(args, 'aura_basetools_read')
|
|
@@ -418,6 +447,7 @@ async function callTool(provider, name, args = {}) {
|
|
|
418
447
|
create: creating ? args.create : undefined,
|
|
419
448
|
...(args.require_observation === true ? { requireObservation: true } : {}),
|
|
420
449
|
...(typeof args.verify === 'string' ? { verify: args.verify } : {}),
|
|
450
|
+
...(typeof args.transaction === 'string' ? { transaction: args.transaction } : {}),
|
|
421
451
|
})
|
|
422
452
|
}
|
|
423
453
|
if (name === 'aura_basetools_write') {
|
|
@@ -429,6 +459,7 @@ async function callTool(provider, name, args = {}) {
|
|
|
429
459
|
allowUnobserved: args.allow_unobserved === true,
|
|
430
460
|
...(typeof args.eol === 'string' ? { eol: args.eol } : {}),
|
|
431
461
|
...(typeof args.verify === 'string' ? { verify: args.verify } : {}),
|
|
462
|
+
...(typeof args.transaction === 'string' ? { transaction: args.transaction } : {}),
|
|
432
463
|
})
|
|
433
464
|
}
|
|
434
465
|
return { ok: false, error: `unknown tool ${JSON.stringify(name)}`, code: 'UNKNOWN_TOOL' }
|
package/lib/ops.mjs
CHANGED
|
@@ -99,6 +99,11 @@ export function capabilitiesEnvelope() {
|
|
|
99
99
|
dsh: ['stale-region-gate', 'byte-verify'],
|
|
100
100
|
},
|
|
101
101
|
},
|
|
102
|
+
{
|
|
103
|
+
name: 'aura_basetools_tx',
|
|
104
|
+
actions: ['begin', 'commit', 'rollback', 'status'],
|
|
105
|
+
options: ['verify'],
|
|
106
|
+
},
|
|
102
107
|
{
|
|
103
108
|
name: 'aura_basetools_write',
|
|
104
109
|
operations: ['create', 'overwrite'],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aura-basetools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Byte-exact read, edit and write tools for coding agents. Standalone CLI and MCP server; no DSH required. 面向 coding agent 的逐字节读写工具;独立 CLI / MCP,可选 DSH 适配器。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/test/standalone-test.mjs
CHANGED
|
@@ -385,7 +385,7 @@ say('F MCP:initialize / tools/list / tools/call')
|
|
|
385
385
|
})()
|
|
386
386
|
if (manifest !== null) check(byId.get(1)?.result?.serverInfo?.version === manifest.version, `serverInfo.version 跟包一致(${manifest.version})`, String(byId.get(1)?.result?.serverInfo?.version))
|
|
387
387
|
const tools = byId.get(2)?.result?.tools ?? []
|
|
388
|
-
check(tools.length ===
|
|
388
|
+
check(tools.length === 4 && tools.some((t) => t.name === 'aura_basetools_read') && tools.some((t) => t.name === 'aura_basetools_edit') && tools.some((t) => t.name === 'aura_basetools_write') && tools.some((t) => t.name === 'aura_basetools_tx'), `tools/list 四个工具(${tools.map((t) => t.name).join(',')}`)
|
|
389
389
|
const readEnv = JSON.parse(byId.get(3)?.result?.content?.[0]?.text ?? '{}')
|
|
390
390
|
check(readEnv.ok === true && Array.isArray(readEnv.symbols ?? []), 'aura_basetools_read 经 MCP 可用', JSON.stringify(readEnv).slice(0, 120))
|
|
391
391
|
const editEnv = JSON.parse(byId.get(4)?.result?.content?.[0]?.text ?? '{}')
|
package/test/write-test.mjs
CHANGED
|
@@ -210,7 +210,7 @@ say('C MCP:aura_basetools_write 声明面与调用面')
|
|
|
210
210
|
|
|
211
211
|
const tools = byId.get(2)?.result?.tools ?? []
|
|
212
212
|
const writeTool = tools.find((tool) => tool.name === 'aura_basetools_write')
|
|
213
|
-
check(tools.length ===
|
|
213
|
+
check(tools.length === 4 && writeTool !== undefined, `C1 tools/list 四个工具且含 aura_basetools_write(${tools.map((tool) => tool.name).join(',')})`)
|
|
214
214
|
check(JSON.stringify(writeTool?.inputSchema?.required) === JSON.stringify(['file_path', 'content']), 'C2 aura_basetools_write schema 必填 file_path + content', JSON.stringify(writeTool?.inputSchema?.required))
|
|
215
215
|
check(envOf(3).ok === true && envOf(3).result?.operation === 'create', 'C3 经 MCP 新建成功', JSON.stringify(envOf(3)).slice(0, 160))
|
|
216
216
|
check(fs.readFileSync(file('mcp-created.txt'), 'utf8') === 'mcp\ncreate\n', 'C4 MCP 新建的内容真的落盘')
|