dsh-code-index 0.9.1 → 0.10.1
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 +26 -0
- package/README.md +49 -8
- package/README.zh.md +41 -8
- package/dist/index.d.ts +25 -6
- package/dist/index.js +205 -28
- package/dist/index.js.map +1 -1
- package/grammars/ARKTS-LICENSE +43 -0
- package/grammars/README.md +25 -0
- package/grammars/tree-sitter-arkts.wasm +0 -0
- package/package.json +3 -2
- package/scripts/release-smoke.mjs +81 -8
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026-present richerfu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
The MIT License (MIT)
|
|
24
|
+
|
|
25
|
+
Copyright (c) 2017 Max Brunsfeld
|
|
26
|
+
|
|
27
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
28
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
29
|
+
in the Software without restriction, including without limitation the rights
|
|
30
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
31
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
32
|
+
furnished to do so, subject to the following conditions:
|
|
33
|
+
|
|
34
|
+
The above copyright notice and this permission notice shall be included in all
|
|
35
|
+
copies or substantial portions of the Software.
|
|
36
|
+
|
|
37
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
38
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
39
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
40
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
41
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
42
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
43
|
+
SOFTWARE.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# ArkTS grammar asset
|
|
2
|
+
|
|
3
|
+
`tree-sitter-arkts.wasm` and `ARKTS-LICENSE` are copied unchanged from the
|
|
4
|
+
published **harmony-contrib/tree-sitter-arkts 0.3.0** npm archive, not compiled
|
|
5
|
+
from an unpinned branch. MIT notices for richerfu and Max Brunsfeld are retained.
|
|
6
|
+
|
|
7
|
+
- Source: https://github.com/harmony-contrib/tree-sitter-arkts
|
|
8
|
+
- npm: https://registry.npmjs.org/tree-sitter-arkts/-/tree-sitter-arkts-0.3.0.tgz
|
|
9
|
+
- Registry `gitHead`: `9a97c1e6ac93bc07732c15050a0e560bc63c8d78`
|
|
10
|
+
- Archive SHA1: `a02e2d883821af6036e1f9efc80f3f1e65227652`
|
|
11
|
+
- Archive integrity: `sha512-3mY013x1rWm8LLeuPp+kFLrl4vbQCfTEferO3GUwUhKHbQHzIT2ppjGARI3vNXIsuvQy/J8xJt2cIOlpfphlXQ==`
|
|
12
|
+
- WASM SHA256: `a5fbf24b2eeab43cf60e9fcdbde99e9089f7ceae43134d24e1d5cc166d285446`
|
|
13
|
+
- Size: 2,430,659 bytes; grammar ABI: 14.
|
|
14
|
+
|
|
15
|
+
Upstream publication regenerates with Tree-sitter CLI 0.24.4 / ABI 14 and builds
|
|
16
|
+
WASM with `tree-sitter build --wasm`. The upstream pipeline permits WASM build
|
|
17
|
+
failure; this specific archive was checked to contain the binary above. The
|
|
18
|
+
plugin vendors only this binary and license, and never imports upstream Node
|
|
19
|
+
bindings or runs `node-gyp-build`. No native compilation or network fetch occurs
|
|
20
|
+
when installing/loading the plugin. The package `files` list includes this directory.
|
|
21
|
+
|
|
22
|
+
To recover the exact asset, download the pinned archive, verify its integrity,
|
|
23
|
+
extract `package/tree-sitter-arkts.wasm` and `package/LICENSE`, then verify the
|
|
24
|
+
binary hash. `tests/arkts.spec.ts` checks the hash and actual runtime parsing;
|
|
25
|
+
`release:smoke` checks installed archive contents and `.ets` extraction.
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-code-index",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Edit-ready Context Packs for DSH agents: bounded source excerpts, changes, related tests, and inclusion evidence — local-first.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"./package.json": "./package.json"
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
|
+
"grammars",
|
|
19
20
|
"dist",
|
|
20
21
|
"scripts",
|
|
21
22
|
"cordis.patch.yml",
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
},
|
|
51
52
|
"peerDependencies": {
|
|
52
53
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
53
|
-
"@deepseek-ai/dsh-tools": "0.2.0-rc.2"
|
|
54
|
+
"@deepseek-ai/dsh-tools": "0.2.0-rc.2 || 0.2.1-rc.2"
|
|
54
55
|
},
|
|
55
56
|
"peerDependenciesMeta": {
|
|
56
57
|
"@deepseek-ai/cordis": {
|
|
@@ -2,6 +2,7 @@ import assert from 'node:assert/strict'
|
|
|
2
2
|
import { execFileSync } from 'node:child_process'
|
|
3
3
|
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
4
4
|
import os from 'node:os'
|
|
5
|
+
import { createRequire } from 'node:module'
|
|
5
6
|
import path from 'node:path'
|
|
6
7
|
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
7
8
|
|
|
@@ -63,10 +64,18 @@ function parseJsonArrayOutput(output, command) {
|
|
|
63
64
|
throw new Error(`${command} did not return a JSON array`)
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const
|
|
67
|
+
// A release gate can reuse one immutable candidate across Node versions.
|
|
68
|
+
const suppliedTarball = process.argv[2] ? path.resolve(process.argv[2]) : null
|
|
69
|
+
// Exercise each supported host group against the same immutable candidate.
|
|
70
|
+
const toolsVersion = process.argv[3] ?? '0.2.1-rc.2'
|
|
71
|
+
const supportedToolsVersions = packageJson.peerDependencies['@deepseek-ai/dsh-tools'].split(' || ')
|
|
72
|
+
assert.ok(supportedToolsVersions.includes(toolsVersion), 'smoke requires an explicitly supported DSH tools version')
|
|
73
|
+
const packed = suppliedTarball ? null : parseJsonArrayOutput(run(npm, ['pack', '--ignore-scripts', '--json'], root), 'npm pack')
|
|
74
|
+
if (packed) assert.equal(packed.length, 1, 'npm pack must produce exactly one artifact')
|
|
75
|
+
const tarball = suppliedTarball ?? path.resolve(root, packed[0].filename)
|
|
76
|
+
const listed = suppliedTarball
|
|
77
|
+
? new Set(run('tar', ['-tzf', tarball], root).trim().split(/\r?\n/).map(file => file.replace(/^package\//, '')))
|
|
78
|
+
: new Set(packed[0].files.map((file) => file.path))
|
|
70
79
|
const expectedFiles = [
|
|
71
80
|
'package.json',
|
|
72
81
|
'README.md',
|
|
@@ -77,6 +86,9 @@ const expectedFiles = [
|
|
|
77
86
|
'dist/index.js',
|
|
78
87
|
'dist/index.d.ts',
|
|
79
88
|
'dist/client.js',
|
|
89
|
+
'grammars/tree-sitter-arkts.wasm',
|
|
90
|
+
'grammars/ARKTS-LICENSE',
|
|
91
|
+
'grammars/README.md',
|
|
80
92
|
'scripts/fix-wsl-links.mjs',
|
|
81
93
|
'scripts/release-smoke.mjs',
|
|
82
94
|
]
|
|
@@ -85,7 +97,7 @@ for (const file of expectedFiles) assert.ok(listed.has(file), `tarball is missin
|
|
|
85
97
|
const smokeDir = mkdtempSync(path.join(os.tmpdir(), 'dsh-code-index-release-'))
|
|
86
98
|
try {
|
|
87
99
|
run(npm, ['init', '--yes'], smokeDir)
|
|
88
|
-
run(npm, ['install', '--ignore-scripts', '--no-save', tarball], smokeDir)
|
|
100
|
+
run(npm, ['install', '--ignore-scripts', '--no-save', tarball, `@deepseek-ai/dsh-tools@${toolsVersion}`], smokeDir)
|
|
89
101
|
|
|
90
102
|
const installedPackage = JSON.parse(
|
|
91
103
|
readFileSync(path.join(smokeDir, 'node_modules', packageJson.name, 'package.json'), 'utf8'),
|
|
@@ -96,7 +108,7 @@ try {
|
|
|
96
108
|
assert.match(installedPackage.engines.node, />=22/)
|
|
97
109
|
assert.equal(installedPackage.license, 'MIT')
|
|
98
110
|
const installedTools = JSON.parse(readFileSync(path.join(smokeDir, 'node_modules', '@deepseek-ai', 'dsh-tools', 'package.json'), 'utf8'))
|
|
99
|
-
assert.equal(installedTools.version,
|
|
111
|
+
assert.equal(installedTools.version, toolsVersion, 'consumer must use the selected matching RC group')
|
|
100
112
|
|
|
101
113
|
const plugin = await import(
|
|
102
114
|
pathToFileURL(path.join(smokeDir, 'node_modules', packageJson.name, 'dist', 'index.js')).href,
|
|
@@ -181,6 +193,32 @@ try {
|
|
|
181
193
|
rmSync(freshSource)
|
|
182
194
|
assert.deepEqual(await invoke('code_search', { query: 'FRESH_MARKER_fn', repoRoot: whitelistRoot }), [])
|
|
183
195
|
|
|
196
|
+
// ArkTS must work from the actual installed package, without native grammar
|
|
197
|
+
// bindings or the source checkout. Keep the fixture tiny and mixed ETS/TS.
|
|
198
|
+
const arkRoot = path.join(smokeDir, 'arkts-repo')
|
|
199
|
+
mkdirSync(path.join(arkRoot, '.git'), { recursive: true })
|
|
200
|
+
writeFileSync(path.join(arkRoot, 'logic.ts'), 'export function label() { return "package ArkTS" }\n')
|
|
201
|
+
const card = '@ComponentV2\nexport struct PackageCard {\n @Local count: number = 0;\n build() { Column() { Text(label()) } }\n}\n'
|
|
202
|
+
writeFileSync(path.join(arkRoot, 'Card.ets'), "import { label } from './logic'\n" + card)
|
|
203
|
+
const arkIndex = await plugin.buildIndex(arkRoot)
|
|
204
|
+
assert.equal(arkIndex.files.length, 2)
|
|
205
|
+
assert.ok(arkIndex.files.every(file => file.diagnostic.status === 'parsed'))
|
|
206
|
+
assert.equal(arkIndex.files.find(file => file.path === 'Card.ets').lang, 'arkts')
|
|
207
|
+
assert.equal((await invoke('code_search', { query: 'PackageCard', repoRoot: arkRoot }))[0]?.file, 'Card.ets')
|
|
208
|
+
const arkPack = await invoke('code_context', { task: 'Explain PackageCard in Card.ets', repoRoot: arkRoot, outputFormat: 'pack', budgetChars: 5000 })
|
|
209
|
+
assert.ok(arkPack.items.some(item => item.name === 'PackageCard' && item.code?.includes('@ComponentV2')))
|
|
210
|
+
assert.ok(JSON.stringify(arkPack).length <= 5000)
|
|
211
|
+
assert.ok(arkPack.items.some(item => item.name === 'label' && item.provenance === 'explicit-import-binding'))
|
|
212
|
+
const arkFresh = path.join(arkRoot, 'Fresh.ets')
|
|
213
|
+
writeFileSync(arkFresh, 'export function ARK_PACKAGE_ADDED() {}\n')
|
|
214
|
+
assert.equal((await invoke('code_search', { query: 'ARK_PACKAGE_ADDED', repoRoot: arkRoot }))[0]?.name, 'ARK_PACKAGE_ADDED')
|
|
215
|
+
writeFileSync(arkFresh, 'export function ARK_PACKAGE_EDITED() {}\n')
|
|
216
|
+
assert.equal((await invoke('code_search', { query: 'ARK_PACKAGE_EDITED', repoRoot: arkRoot }))[0]?.name, 'ARK_PACKAGE_EDITED')
|
|
217
|
+
rmSync(arkFresh)
|
|
218
|
+
assert.deepEqual(await invoke('code_search', { query: 'ARK_PACKAGE_EDITED', repoRoot: arkRoot }), [])
|
|
219
|
+
writeFileSync(path.join(arkRoot, 'Broken.ets'), '@Component\nstruct Broken { build() {')
|
|
220
|
+
assert.match(await invoke('code_index', { repoRoot: arkRoot }), /index incomplete:/)
|
|
221
|
+
|
|
184
222
|
for (const dispose of disposers.reverse()) dispose()
|
|
185
223
|
|
|
186
224
|
const compactRegistered = []
|
|
@@ -203,8 +241,43 @@ try {
|
|
|
203
241
|
)
|
|
204
242
|
assert.deepEqual(compactRegistered, ['code_index', 'code_context', 'code_health'])
|
|
205
243
|
for (const dispose of compactDisposers.reverse()) dispose()
|
|
206
|
-
|
|
244
|
+
|
|
245
|
+
// Direct handlers above verify package behavior; this separate check runs
|
|
246
|
+
// through the selected RC's real schema/dispatch/rendering pipeline.
|
|
247
|
+
const consumerRequire = createRequire(path.join(smokeDir, 'package.json'))
|
|
248
|
+
const { Context } = await import(pathToFileURL(consumerRequire.resolve('@deepseek-ai/cordis')).href)
|
|
249
|
+
const { default: ToolRuntime } = await import(pathToFileURL(consumerRequire.resolve('@deepseek-ai/dsh-tools')).href)
|
|
250
|
+
const nativeContext = new Context()
|
|
251
|
+
nativeContext.provide('systemPrompt', { tools: () => () => {}, section: () => () => {} })
|
|
252
|
+
const runtime = new ToolRuntime(nativeContext)
|
|
253
|
+
const nativeDisposers = plugin.tools.map(tool => runtime.register(tool))
|
|
254
|
+
try {
|
|
255
|
+
const nativeInvoke = async (name, args) => {
|
|
256
|
+
const result = await runtime.execute({
|
|
257
|
+
callId: `release:${name}`, name, arguments: args,
|
|
258
|
+
signal: new AbortController().signal,
|
|
259
|
+
})
|
|
260
|
+
assert.equal(result.isError, false, JSON.stringify(result.content))
|
|
261
|
+
return result
|
|
262
|
+
}
|
|
263
|
+
await nativeInvoke('code_index', { action: 'build', repoRoot: arkRoot })
|
|
264
|
+
const search = await nativeInvoke('code_search', { query: 'PackageCard', repoRoot: arkRoot })
|
|
265
|
+
assert.equal(search.value[0]?.file, 'Card.ets')
|
|
266
|
+
assert.ok(search.meta, 'search presentation metadata must survive runtime dispatch')
|
|
267
|
+
for (const outputFormat of ['text', 'pack']) {
|
|
268
|
+
const result = await nativeInvoke('code_context', {
|
|
269
|
+
task: 'Explain PackageCard in Card.ets', repoRoot: arkRoot, outputFormat, budgetChars: 5000,
|
|
270
|
+
})
|
|
271
|
+
assert.match(JSON.stringify(result.content), /@ComponentV2/)
|
|
272
|
+
assert.equal(typeof result.value, outputFormat === 'pack' ? 'object' : 'string')
|
|
273
|
+
if (outputFormat === 'pack') assert.ok(JSON.stringify(result.value).length <= 5000)
|
|
274
|
+
}
|
|
275
|
+
} finally {
|
|
276
|
+
for (const dispose of nativeDisposers.reverse()) dispose()
|
|
277
|
+
await nativeContext.fiber.dispose()
|
|
278
|
+
}
|
|
279
|
+
console.log(`release smoke passed for ${packageJson.name}@${packageJson.version} with dsh-tools@${toolsVersion}`)
|
|
207
280
|
} finally {
|
|
208
281
|
rmSync(smokeDir, { recursive: true, force: true })
|
|
209
|
-
rmSync(tarball, { force: true })
|
|
282
|
+
if (!suppliedTarball) rmSync(tarball, { force: true })
|
|
210
283
|
}
|