dsh-code-index 0.11.2 → 0.12.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/CHANGELOG.md +12 -0
- package/README.md +18 -5
- package/README.zh.md +18 -5
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +760 -20
- package/dist/index.js +433 -100
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/scripts/release-smoke.mjs +45 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-code-index",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Impact X-Ray for DSH: inspect potential code-change impact, provenance and real source evidence before AI edits.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
54
|
-
"@deepseek-ai/dsh-tools": ">=0.2.0-rc.2"
|
|
54
|
+
"@deepseek-ai/dsh-tools": ">=0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2 || >=0.2.2-rc.1 <0.2.3"
|
|
55
55
|
},
|
|
56
56
|
"peerDependenciesMeta": {
|
|
57
57
|
"@deepseek-ai/cordis": {
|
|
@@ -6,6 +6,7 @@ import { createRequire } from 'node:module'
|
|
|
6
6
|
import path from 'node:path'
|
|
7
7
|
import semver from 'semver'
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
9
|
+
import { createHash } from 'node:crypto'
|
|
9
10
|
|
|
10
11
|
const root = path.resolve(fileURLToPath(new URL('..', import.meta.url)))
|
|
11
12
|
const packageJson = JSON.parse(readFileSync(path.join(root, 'package.json'), 'utf8'))
|
|
@@ -16,6 +17,9 @@ function shellQuote(value) {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
function run(command, args, cwd) {
|
|
20
|
+
if (command === npm && process.env.CIX_NPM_CLI) return execFileSync(process.execPath, [process.env.CIX_NPM_CLI, ...args], {
|
|
21
|
+
cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'inherit'],
|
|
22
|
+
})
|
|
19
23
|
const invocation = [command, ...args].map(shellQuote).join(' ')
|
|
20
24
|
const commandArgs = process.platform === 'win32'
|
|
21
25
|
? ['/d', '/s', '/c', invocation]
|
|
@@ -71,6 +75,7 @@ const suppliedTarball = process.argv[2] ? path.resolve(process.argv[2]) : null
|
|
|
71
75
|
const toolsVersion = process.argv[3] ?? '0.2.1-rc.3'
|
|
72
76
|
const toolsRange = packageJson.peerDependencies['@deepseek-ai/dsh-tools']
|
|
73
77
|
assert.ok(semver.satisfies(toolsVersion, toolsRange, { includePrerelease: true }), 'smoke requires a DSH tools version matching the peer range')
|
|
78
|
+
assert.ok(semver.satisfies(toolsVersion, toolsRange), 'smoke requires normal npm prerelease peer compatibility')
|
|
74
79
|
const packed = suppliedTarball ? null : parseJsonArrayOutput(run(npm, ['pack', '--ignore-scripts', '--json'], root), 'npm pack')
|
|
75
80
|
if (packed) assert.equal(packed.length, 1, 'npm pack must produce exactly one artifact')
|
|
76
81
|
const tarball = suppliedTarball ?? path.resolve(root, packed[0].filename)
|
|
@@ -96,13 +101,11 @@ const expectedFiles = [
|
|
|
96
101
|
for (const file of expectedFiles) assert.ok(listed.has(file), `tarball is missing ${file}`)
|
|
97
102
|
|
|
98
103
|
const smokeDir = mkdtempSync(path.join(os.tmpdir(), 'dsh-code-index-release-'))
|
|
104
|
+
let nativeCalls = 0
|
|
99
105
|
try {
|
|
100
106
|
run(npm, ['init', '--yes'], smokeDir)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// normal npm peer resolution. The range assertion above uses DSH's rules.
|
|
104
|
-
console.log('smoke fixture: npm --force bypasses peer resolution; validating DSH range and runtime only')
|
|
105
|
-
run(npm, ['install', '--ignore-scripts', '--no-save', '--force', tarball, `@deepseek-ai/dsh-tools@${toolsVersion}`], smokeDir)
|
|
107
|
+
console.log('smoke fixture: normal npm peer resolution; no force or legacy-peer-deps')
|
|
108
|
+
run(npm, ['install', '--ignore-scripts', '--no-save', tarball, `@deepseek-ai/dsh-tools@${toolsVersion}`], smokeDir)
|
|
106
109
|
|
|
107
110
|
const installedPackage = JSON.parse(
|
|
108
111
|
readFileSync(path.join(smokeDir, 'node_modules', packageJson.name, 'package.json'), 'utf8'),
|
|
@@ -173,6 +176,26 @@ try {
|
|
|
173
176
|
assert.ok(contextPack.items.some(item => item.kind === 'primary' && item.name === 'buildIndex'))
|
|
174
177
|
assert.ok(contextPack.items.some(item => item.code !== undefined))
|
|
175
178
|
assert.ok(JSON.stringify(contextPack).length <= 5000)
|
|
179
|
+
const evidenceRoot = path.join(smokeDir, 'evidence')
|
|
180
|
+
mkdirSync(path.join(evidenceRoot, '.git'), { recursive: true })
|
|
181
|
+
writeFileSync(path.join(evidenceRoot, 'core.ts'), 'export function lonelyMarker() { return 7 }\n')
|
|
182
|
+
for (const budgetChars of [300, 500, 5000]) {
|
|
183
|
+
const args = { repoRoot: evidenceRoot, task: '定位 lonelyMarker 的实现,不要修改代码', budgetChars }
|
|
184
|
+
const pack = await invoke('code_context', { ...args, outputFormat: 'pack' })
|
|
185
|
+
const text = await invoke('code_context', args)
|
|
186
|
+
assert.equal(pack.version, 1)
|
|
187
|
+
assert.ok(JSON.stringify(pack).length <= budgetChars)
|
|
188
|
+
assert.ok(text.length <= budgetChars)
|
|
189
|
+
assert.equal(text, plugin.renderContextPack(pack))
|
|
190
|
+
if (budgetChars === 5000) {
|
|
191
|
+
assert.equal(pack.evidence.scope, 'indexed-static-only')
|
|
192
|
+
assert.equal(pack.evidence.tests.verification, 'not-run')
|
|
193
|
+
assert.equal(pack.evidence.callers.zero[0].name, 'lonelyMarker')
|
|
194
|
+
assert.match(text, /not proof of no callers/)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
assert.match(await invoke('code_refs', { repoRoot: evidenceRoot, symbol: 'lonelyMarker' }), /not proof of no callers/)
|
|
198
|
+
assert.match(await invoke('code_change_context', { repoRoot: evidenceRoot, files: ['core.ts'] }), /Evidence \(indexed static scope/)
|
|
176
199
|
assert.match(await invoke('code_health', { repoRoot: root }), /repo health/)
|
|
177
200
|
|
|
178
201
|
// Issue #2 must also be fixed in the installed tarball, not just TS sources.
|
|
@@ -280,6 +303,7 @@ try {
|
|
|
280
303
|
signal: new AbortController().signal,
|
|
281
304
|
})
|
|
282
305
|
assert.equal(result.isError, false, JSON.stringify(result.content))
|
|
306
|
+
nativeCalls++
|
|
283
307
|
return result
|
|
284
308
|
}
|
|
285
309
|
await nativeInvoke('code_index', { action: 'build', repoRoot: arkRoot })
|
|
@@ -323,6 +347,8 @@ try {
|
|
|
323
347
|
assert.equal(xray.meta.edges.filter(e => e.kind === 'call').length, 6)
|
|
324
348
|
assert.equal(xray.meta.edges.filter(e => e.kind === 'import').length, 3)
|
|
325
349
|
assert.equal(xray.meta.tests.length, 1)
|
|
350
|
+
assert.equal(xray.meta.evidence.scope, 'indexed-static-only')
|
|
351
|
+
assert.equal(xray.meta.evidence.tests.verification, 'not-run')
|
|
326
352
|
assert.deepEqual(new Set(xray.meta.edges.map(e => e.resolution)), new Set(['exact', 'import-scoped', 'name-only']))
|
|
327
353
|
assert.ok(xray.meta.paths.some(p => p.edgeIds.length === 2 && p.resolution === 'exact' && !p.omitted))
|
|
328
354
|
assert.ok(Buffer.byteLength(JSON.stringify(xray.meta)) <= plugin.XRAY_LIMITS.metadataBytes)
|
|
@@ -344,8 +370,20 @@ try {
|
|
|
344
370
|
for (const dispose of nativeDisposers.reverse()) dispose()
|
|
345
371
|
await nativeContext.fiber.dispose()
|
|
346
372
|
}
|
|
347
|
-
console.log(`release smoke passed (
|
|
373
|
+
console.log(`release smoke passed (normal npm peer resolution and DSH runtime) for ${packageJson.name}@${packageJson.version} with dsh-tools@${toolsVersion}`)
|
|
374
|
+
if (process.env.CIX_SMOKE_RECORD) writeFileSync(process.env.CIX_SMOKE_RECORD, JSON.stringify({
|
|
375
|
+
node: process.version, version: installedPackage.version, toolsVersion, nativeCalls,
|
|
376
|
+
tarball, sha256: createHash('sha256').update(readFileSync(tarball)).digest('hex'),
|
|
377
|
+
installedRoot: path.join(smokeDir, 'node_modules', packageJson.name),
|
|
378
|
+
methods: ['clean npm install --ignore-scripts; normal peer resolution', 'plugin apply/dispose', 'real ToolRuntime dispatch'],
|
|
379
|
+
evidence: true, budgets: [300, 500, 5000], passed: true,
|
|
380
|
+
}, null, 2) + '\n')
|
|
348
381
|
} finally {
|
|
349
|
-
|
|
382
|
+
if (process.env.CIX_SMOKE_KEEP === '1') console.log(`retained isolated smoke directory: ${smokeDir}`)
|
|
383
|
+
else {
|
|
384
|
+
assert.equal(path.dirname(path.resolve(smokeDir)), path.resolve(os.tmpdir()))
|
|
385
|
+
assert.ok(path.basename(smokeDir).startsWith('dsh-code-index-release-'))
|
|
386
|
+
rmSync(smokeDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 })
|
|
387
|
+
}
|
|
350
388
|
if (!suppliedTarball) rmSync(tarball, { force: true })
|
|
351
389
|
}
|