dsh-code-index 0.10.0 → 0.10.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-code-index",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
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",
@@ -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"
55
55
  },
56
56
  "peerDependenciesMeta": {
57
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
 
@@ -65,6 +66,10 @@ function parseJsonArrayOutput(output, command) {
65
66
 
66
67
  // A release gate can reuse one immutable candidate across Node versions.
67
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')
68
73
  const packed = suppliedTarball ? null : parseJsonArrayOutput(run(npm, ['pack', '--ignore-scripts', '--json'], root), 'npm pack')
69
74
  if (packed) assert.equal(packed.length, 1, 'npm pack must produce exactly one artifact')
70
75
  const tarball = suppliedTarball ?? path.resolve(root, packed[0].filename)
@@ -92,7 +97,7 @@ for (const file of expectedFiles) assert.ok(listed.has(file), `tarball is missin
92
97
  const smokeDir = mkdtempSync(path.join(os.tmpdir(), 'dsh-code-index-release-'))
93
98
  try {
94
99
  run(npm, ['init', '--yes'], smokeDir)
95
- run(npm, ['install', '--ignore-scripts', '--no-save', tarball], smokeDir)
100
+ run(npm, ['install', '--ignore-scripts', '--no-save', tarball, `@deepseek-ai/dsh-tools@${toolsVersion}`], smokeDir)
96
101
 
97
102
  const installedPackage = JSON.parse(
98
103
  readFileSync(path.join(smokeDir, 'node_modules', packageJson.name, 'package.json'), 'utf8'),
@@ -103,7 +108,7 @@ try {
103
108
  assert.match(installedPackage.engines.node, />=22/)
104
109
  assert.equal(installedPackage.license, 'MIT')
105
110
  const installedTools = JSON.parse(readFileSync(path.join(smokeDir, 'node_modules', '@deepseek-ai', 'dsh-tools', 'package.json'), 'utf8'))
106
- assert.equal(installedTools.version, '0.2.0-rc.2', 'fresh consumers must resolve the verified matching RC')
111
+ assert.equal(installedTools.version, toolsVersion, 'consumer must use the selected matching RC group')
107
112
 
108
113
  const plugin = await import(
109
114
  pathToFileURL(path.join(smokeDir, 'node_modules', packageJson.name, 'dist', 'index.js')).href,
@@ -214,6 +219,23 @@ try {
214
219
  writeFileSync(path.join(arkRoot, 'Broken.ets'), '@Component\nstruct Broken { build() {')
215
220
  assert.match(await invoke('code_index', { repoRoot: arkRoot }), /index incomplete:/)
216
221
 
222
+ // Issue #5: exercise actual installed Rust signatures, not source imports.
223
+ const rustRoot = path.join(smokeDir, 'rust-repo')
224
+ mkdirSync(path.join(rustRoot, '.git'), { recursive: true })
225
+ writeFileSync(path.join(rustRoot, 'repro.rs'), [
226
+ 'pub struct PublicOne { pub field: u32 }',
227
+ 'struct PrivateOne { field: u32 }',
228
+ 'pub enum PublicEnum { A }',
229
+ 'enum PrivateEnum { A }',
230
+ 'pub trait PublicTrait { fn run(&self); }',
231
+ 'trait PrivateTrait { fn run(&self); }',
232
+ 'pub fn public_function(a: u32) -> u32 { a }',
233
+ 'fn private_function(a: u32) -> u32 { a }',
234
+ 'pub(crate) struct CrateOnly;',
235
+ 'pub(in crate) enum Restricted { A }',
236
+ 'fn caller() { let value = PublicOne { field: public_function(1) }; }',
237
+ ].join('\n'))
238
+
217
239
  for (const dispose of disposers.reverse()) dispose()
218
240
 
219
241
  const compactRegistered = []
@@ -236,7 +258,66 @@ try {
236
258
  )
237
259
  assert.deepEqual(compactRegistered, ['code_index', 'code_context', 'code_health'])
238
260
  for (const dispose of compactDisposers.reverse()) dispose()
239
- console.log(`release smoke passed for ${packageJson.name}@${packageJson.version}`)
261
+
262
+ // Direct handlers above verify package behavior; this separate check runs
263
+ // through the selected RC's real schema/dispatch/rendering pipeline.
264
+ const consumerRequire = createRequire(path.join(smokeDir, 'package.json'))
265
+ const { Context } = await import(pathToFileURL(consumerRequire.resolve('@deepseek-ai/cordis')).href)
266
+ const { default: ToolRuntime } = await import(pathToFileURL(consumerRequire.resolve('@deepseek-ai/dsh-tools')).href)
267
+ const nativeContext = new Context()
268
+ nativeContext.provide('systemPrompt', { tools: () => () => {}, section: () => () => {} })
269
+ const runtime = new ToolRuntime(nativeContext)
270
+ const nativeDisposers = plugin.tools.map(tool => runtime.register(tool))
271
+ try {
272
+ const nativeInvoke = async (name, args) => {
273
+ const result = await runtime.execute({
274
+ callId: `release:${name}`, name, arguments: args,
275
+ signal: new AbortController().signal,
276
+ })
277
+ assert.equal(result.isError, false, JSON.stringify(result.content))
278
+ return result
279
+ }
280
+ await nativeInvoke('code_index', { action: 'build', repoRoot: arkRoot })
281
+ const search = await nativeInvoke('code_search', { query: 'PackageCard', repoRoot: arkRoot })
282
+ assert.equal(search.value[0]?.file, 'Card.ets')
283
+ assert.ok(search.meta, 'search presentation metadata must survive runtime dispatch')
284
+ for (const outputFormat of ['text', 'pack']) {
285
+ const result = await nativeInvoke('code_context', {
286
+ task: 'Explain PackageCard in Card.ets', repoRoot: arkRoot, outputFormat, budgetChars: 5000,
287
+ })
288
+ assert.match(JSON.stringify(result.content), /@ComponentV2/)
289
+ assert.equal(typeof result.value, outputFormat === 'pack' ? 'object' : 'string')
290
+ if (outputFormat === 'pack') assert.ok(JSON.stringify(result.value).length <= 5000)
291
+ }
292
+ await nativeInvoke('code_index', { action: 'build', repoRoot: rustRoot })
293
+ const rustSymbols = await nativeInvoke('code_symbols', { repoRoot: rustRoot })
294
+ assert.ok(rustSymbols.value.some(symbol => symbol.name === 'CrateOnly' && symbol.signature === 'CrateOnly' && !symbol.exported))
295
+ assert.ok(rustSymbols.value.some(symbol => symbol.name === 'Restricted' && symbol.signature === 'Restricted' && !symbol.exported))
296
+ const rustMap = await nativeInvoke('code_map', { repoRoot: rustRoot })
297
+ for (const name of ['PublicOne', 'PublicEnum', 'PublicTrait']) {
298
+ const search = await nativeInvoke('code_search', { query: name, repoRoot: rustRoot })
299
+ assert.equal(search.value[0]?.name, name)
300
+ assert.equal(search.value[0]?.signature, name)
301
+ assert.match(JSON.stringify(search.content), new RegExp(name))
302
+ assert.match(rustMap.value, new RegExp(name))
303
+ const refs = await nativeInvoke('code_refs', { symbol: name, repoRoot: rustRoot })
304
+ assert.match(refs.value, new RegExp(`${name} — repro.rs:`))
305
+ assert.match(refs.value, /callers \(0\)/) // no invented struct-literal/type-use edges
306
+ }
307
+ const rustFunction = await nativeInvoke('code_refs', { symbol: 'public_function', repoRoot: rustRoot })
308
+ assert.match(rustFunction.value, /callers \(1\)/)
309
+ for (const outputFormat of ['text', 'pack']) {
310
+ const result = await nativeInvoke('code_context', {
311
+ task: 'Explain PublicOne', repoRoot: rustRoot, outputFormat, budgetChars: 5000,
312
+ })
313
+ assert.match(JSON.stringify(result.content), /PublicOne/)
314
+ if (outputFormat === 'pack') assert.ok(result.value.items.some(item => item.name === 'PublicOne' && item.code?.includes('pub struct PublicOne')))
315
+ }
316
+ } finally {
317
+ for (const dispose of nativeDisposers.reverse()) dispose()
318
+ await nativeContext.fiber.dispose()
319
+ }
320
+ console.log(`release smoke passed for ${packageJson.name}@${packageJson.version} with dsh-tools@${toolsVersion}`)
240
321
  } finally {
241
322
  rmSync(smokeDir, { recursive: true, force: true })
242
323
  if (!suppliedTarball) rmSync(tarball, { force: true })