dsh-pi-bridge 0.1.0 → 0.1.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/README.md CHANGED
@@ -127,10 +127,17 @@ captures but registers nothing.
127
127
  ## Develop
128
128
 
129
129
  ```bash
130
- npm test # 34 offline checks: both directions, mock hosts, no network
131
- npm run test:entries # loads both real entries and asserts the host-facing surface
132
- npm run test:all # the above plus the real-package cases (needs network)
133
- npm run e2e # just the published-package probes
130
+ ```bash
131
+ npm test # offline suites: 40 checks + both host entries + self-bridge
132
+ npm run test:offline # just the pipeline self-test
133
+ npm run test:entries # both real entries and the host-facing surface
134
+ npm run test:host # acceptance against an installed DSH build (see note)
135
+ npm run test:network # real published packages from npm and GitHub
136
+ ```
137
+
138
+ `test:host` reads the installed host's own `@deepseek-ai/dsh-tools` from inside its asar, which only
139
+ an Electron-patched fs can reach. Run it from a host process (or the harness); under plain Node it
140
+ reports an explicit SKIP rather than pretending the host refused us.
134
141
  ```
135
142
 
136
143
  The self-test builds fixtures by hand — a TypeScript pi extension using the TypeBox builder, and a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-pi-bridge",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "description": "One plugin, two hosts: installs into the pi coding agent and into DeepSeek Harness, and bridges the ecosystems. In DSH a pi_install tool turns pi packages into native DSH tools, commands and skills; in pi a /dsh-install command turns DSH plugin bundles into pi tools and commands. Same code, both entry conventions, published on npm so both plugin markets find it.",
6
6
  "main": "./index.js",
@@ -10,11 +10,12 @@
10
10
  "./package.json": "./package.json"
11
11
  },
12
12
  "scripts": {
13
- "test": "node scripts/selftest.mjs",
14
- "test:entries": "node scripts/entry-check.mjs && node scripts/selfhost-check.mjs",
15
- "test:host": "node scripts/realhost-check.mjs",
16
- "test:all": "node scripts/selftest.mjs && node scripts/entry-check.mjs && node scripts/selfhost-check.mjs && node scripts/realhost-check.mjs && node scripts/e2e-preview.mjs && node scripts/edge-cases.mjs",
17
- "e2e": "node scripts/e2e-preview.mjs && node scripts/edge-cases.mjs"
13
+ "test": "node scripts/run-all.mjs",
14
+ "test:offline": "node scripts/selftest.mjs",
15
+ "test:entries": "node scripts/entry-check.mjs",
16
+ "test:host": "node tools/realhost-check.mjs",
17
+ "test:network": "node tools/e2e-preview.mjs && node tools/edge-cases.mjs",
18
+ "test:all": "node scripts/run-all.mjs"
18
19
  },
19
20
  "keywords": [
20
21
  "dsh",
@@ -43,10 +44,17 @@
43
44
  },
44
45
  "files": [
45
46
  "index.js",
46
- "src",
47
- "extensions",
48
- "skills",
49
- "scripts",
47
+ "src/*.js",
48
+ "extensions/index.js",
49
+ "skills/dsh-pi-bridge/SKILL.md",
50
+ "scripts/selftest.mjs",
51
+ "scripts/entry-check.mjs",
52
+ "scripts/run-all.mjs",
53
+ "scripts/fixtures/**",
54
+ "tools/selfhost-check.mjs",
55
+ "tools/realhost-check.mjs",
56
+ "tools/e2e-preview.mjs",
57
+ "tools/edge-cases.mjs",
50
58
  "cordis.patch.yml",
51
59
  "README.md",
52
60
  "LICENSE"
@@ -10,7 +10,7 @@ import path from 'node:path'
10
10
 
11
11
  const HERE = path.dirname(fileURLToPath(import.meta.url))
12
12
  const ROOT = path.resolve(HERE, '..')
13
- process.env.DSH_PI_BRIDGE_HOME = path.join(ROOT, 'scripts', '.entry-cache')
13
+ process.env.DSH_PI_BRIDGE_HOME = path.join(ROOT, '.tmp', '.entry-cache')
14
14
 
15
15
  let failures = 0
16
16
  function check (label, cond, detail) {
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Published test entry. Runs everything that needs no network: the pipeline
3
+ * self-test and both host entry checks. Real-host and network regression cases
4
+ * live in tools/ and are run from the repository, not from the tarball.
5
+ * Run: npm test
6
+ */
7
+ import { spawnSync } from "node:child_process"
8
+ import { fileURLToPath } from "node:url"
9
+ import path from "node:path"
10
+
11
+ const HERE = path.dirname(fileURLToPath(import.meta.url))
12
+ const ROOT = path.resolve(HERE, "..")
13
+ const SUITES = [
14
+ ["offline pipeline", ["scripts/selftest.mjs"]],
15
+ ["host entries", ["scripts/entry-check.mjs"]],
16
+ ["self-bridge", ["tools/selfhost-check.mjs"]],
17
+ ]
18
+
19
+ // A missing suite file is a packaging bug, not an optional skip: fail loudly.
20
+ const { existsSync } = await import('node:fs')
21
+ let missing = 0
22
+ for (const [label, args] of SUITES) {
23
+ for (const a of args) {
24
+ if (!existsSync(path.join(ROOT, a))) { console.log(label + ': MISSING ' + a); missing++ }
25
+ }
26
+ }
27
+ if (missing) { console.log(missing + ' suite file(s) missing from this install'); process.exit(1) }
28
+
29
+ let failed = 0
30
+ for (const [label, args] of SUITES) {
31
+ const r = spawnSync(process.execPath, args.map(a => path.join(ROOT, a)), { stdio: ["ignore", "inherit", "inherit"], cwd: ROOT })
32
+ if (r.status === 0) console.log(label + ": PASS")
33
+ else { console.log(label + ": FAIL (exit " + r.status + ")"); failed++ }
34
+ }
35
+ console.log(failed ? failed + " suite(s) failed" : "all suites passed")
36
+ process.exit(failed ? 1 : 0)
@@ -295,6 +295,22 @@ async function main () {
295
295
  } finally { globalThis.fetch = origFetch }
296
296
  }
297
297
 
298
+ console.log('caches stay outside the published tree')
299
+ {
300
+ // A 1.9 GB npm-install tree once landed under scripts/: files:["scripts"] would
301
+ // have shipped it. Published directories must never hold a bridge cache.
302
+ const { readdir } = await import('node:fs/promises')
303
+ const published = ['src', 'scripts', 'extensions', 'skills', 'tools']
304
+ const offenders = []
305
+ for (const dir of published) {
306
+ let names = []
307
+ try { names = await readdir(path.join(ROOT, dir)) } catch { continue }
308
+ for (const n of names) if (/^\.[\w-]*cache$/.test(n) || /\bcleanroom\b/.test(n) || n.endsWith('.log') || n.endsWith('.tgz')) offenders.push(dir + '/' + n)
309
+ }
310
+ check('no cache or scratch tree inside published dirs', offenders.length === 0, offenders.join(', '))
311
+ check('bridge cache root is outside published dirs', !String(process.env.DSH_PI_BRIDGE_HOME || '').includes(path.join(ROOT, 'scripts')), String(process.env.DSH_PI_BRIDGE_HOME))
312
+ }
313
+
298
314
  console.log('dual-host self detection')
299
315
  const self = await loadForeign(ROOT, { host: 'auto' })
300
316
  check('self detected for both hosts', !!(self.info.pi && self.info.dsh), JSON.stringify(self.info.signals))
@@ -15,7 +15,7 @@ import path from 'node:path'
15
15
 
16
16
  const HERE = path.dirname(fileURLToPath(import.meta.url))
17
17
  const ROOT = path.resolve(HERE, '..')
18
- process.env.DSH_PI_BRIDGE_HOME = path.join(ROOT, 'scripts', '.e2e-cache')
18
+ process.env.DSH_PI_BRIDGE_HOME = path.join(ROOT, '.tmp', '.e2e-cache')
19
19
 
20
20
  const { loadForeign } = await import('../src/load.js')
21
21
  const { replayIntoDsh } = await import('../src/replay-dsh.js')
@@ -9,7 +9,7 @@ import path from 'node:path'
9
9
 
10
10
  const HERE = path.dirname(fileURLToPath(import.meta.url))
11
11
  const ROOT = path.resolve(HERE, '..')
12
- process.env.DSH_PI_BRIDGE_HOME = path.join(ROOT, 'scripts', '.edge-cache')
12
+ process.env.DSH_PI_BRIDGE_HOME = path.join(ROOT, '.tmp', '.edge-cache')
13
13
 
14
14
  const { loadForeign } = await import('../src/load.js')
15
15
  const { parseSpec } = await import('../src/resolve.js')
@@ -15,7 +15,7 @@ import fs from 'node:fs'
15
15
 
16
16
  const HERE = path.dirname(fileURLToPath(import.meta.url))
17
17
  const ROOT = path.resolve(HERE, '..')
18
- process.env.DSH_PI_BRIDGE_HOME = path.join(ROOT, 'scripts', '.realhost-cache')
18
+ process.env.DSH_PI_BRIDGE_HOME = path.join(ROOT, '.tmp', '.realhost-cache')
19
19
 
20
20
  /**
21
21
  * Candidate locations of an installed DSH build's tools package.
@@ -11,7 +11,7 @@ import path from 'node:path'
11
11
 
12
12
  const HERE = path.dirname(fileURLToPath(import.meta.url))
13
13
  const ROOT = path.resolve(HERE, '..')
14
- process.env.DSH_PI_BRIDGE_HOME = path.join(ROOT, 'scripts', '.selfhost-cache')
14
+ process.env.DSH_PI_BRIDGE_HOME = path.join(ROOT, '.tmp', '.selfhost-cache')
15
15
 
16
16
  const { loadForeign } = await import('../src/load.js')
17
17
  const { replayIntoPi } = await import('../src/replay-pi.js')