deadbyte-mcp 0.15.8 → 0.15.9

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.
@@ -0,0 +1,5 @@
1
+ @echo off
2
+ setlocal EnableExtensions DisableDelayedExpansion
3
+ set "HERE=%~dp0"
4
+ "%HERE%controller\DEADBYTE-MCP.cmd" %*
5
+ exit /b %ERRORLEVEL%
package/README.txt CHANGED
@@ -7,12 +7,12 @@ NPX PRIMARY OPERATOR UX
7
7
  ------------------------
8
8
  Use the npm CLI entry point instead of the legacy CMD convenience wrapper:
9
9
 
10
- npx -y deadbyte-mcp@0.15.5 mcp
11
- npx -y deadbyte-mcp@0.15.5 remote
12
- npx -y deadbyte-mcp@0.15.5 remote status
13
- npx -y deadbyte-mcp@0.15.5 remote restart
14
- npx -y deadbyte-mcp@0.15.5 audit status
15
- npx -y deadbyte-mcp@0.15.5 audit verify
10
+ npx -y deadbyte-mcp@0.15.9 mcp
11
+ npx -y deadbyte-mcp@0.15.9 remote
12
+ npx -y deadbyte-mcp@0.15.9 remote status
13
+ npx -y deadbyte-mcp@0.15.9 remote restart
14
+ npx -y deadbyte-mcp@0.15.9 audit status
15
+ npx -y deadbyte-mcp@0.15.9 audit verify
16
16
 
17
17
  The `mcp` command is the quiet stdio server entry for local MCP clients; stdout is reserved for MCP.
18
18
  The remote CLI invokes the stable active-release PowerShell launcher directly with shell=false.
package/RELEASE.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema": "deadbyte.release.v1",
3
3
  "name": "deadbyte-mcp",
4
- "version": "0.15.8",
4
+ "version": "0.15.9",
5
5
  "train": "R46",
6
6
  "label": "FILELESS POWERSHELL PRODUCT BASELINE",
7
7
  "protocol_revision": "2026-07-28",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deadbyte-mcp",
3
- "version": "0.15.8",
3
+ "version": "0.15.9",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Authenticated MCP agentic runtime with signed skills, persistent model backends, identity-bound remote devices, durable job supervision, immutable release slots, and separately revocable machine authority.",
@@ -170,19 +170,24 @@ export async function createSkillPlane({root,verifyKeyPath}={}){
170
170
  async function list(){
171
171
  const names=(await readdir(rootReal)).sort((a,b)=>a.localeCompare(b,'en'));
172
172
  const skills=[];
173
+ const invalid_skills=[];
173
174
  for(const name of names){
174
175
  const full=path.join(rootReal,name);
175
176
  const st=await lstat(full);
176
177
  insist(st.isDirectory()&&!st.isSymbolicLink(),`skill registry contains non-directory entry: ${name}`);
177
- const item=await verified(name);
178
- skills.push({
179
- name:item.body.name,version:item.body.version,description:item.body.description,audience:item.body.audience,
180
- manifest_sha256:item.envelope.manifest_sha256,required_capabilities:item.requiredCapabilities,
181
- authority_planes:item.authorityPlanes,resource_count:item.resources.length,provenance:item.body.provenance,verified:true
182
- });
178
+ try{
179
+ const item=await verified(name);
180
+ skills.push({
181
+ name:item.body.name,version:item.body.version,description:item.body.description,audience:item.body.audience,
182
+ manifest_sha256:item.envelope.manifest_sha256,required_capabilities:item.requiredCapabilities,
183
+ authority_planes:item.authorityPlanes,resource_count:item.resources.length,provenance:item.body.provenance,verified:true
184
+ });
185
+ }catch(error){
186
+ invalid_skills.push({name,error:String(error),verified:false});
187
+ }
183
188
  }
184
189
  const registrySha=sha(Buffer.from(canonicalJson(skills.map(item=>({name:item.name,manifest_sha256:item.manifest_sha256}))),'utf8'));
185
- return {status:'ok',skills,registry_sha256:registrySha,verify_key_id:keyId};
190
+ return {status:'ok',skills,invalid_skills,registry_sha256:registrySha,verify_key_id:keyId};
186
191
  }
187
192
  async function load({name}={}){
188
193
  const item=await verified(name);
package/src/version.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export const DEADBYTE_VERSION = '0.15.8';
1
+ export const DEADBYTE_VERSION = '0.15.9';
2
2
  export const MCP_PROTOCOL_VERSION = '2026-07-28';
3
3
  export const RECEIPT_SCHEMA_V1 = 'deadbyte.receipt.v1';
4
4
  export const RECEIPT_SCHEMA_V2 = 'deadbyte.receipt.v2';
@@ -4,6 +4,7 @@ import { readFile } from 'node:fs/promises';
4
4
  import { spawnSync } from 'node:child_process';
5
5
  import path from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
+ import { DEADBYTE_VERSION } from '../src/version.mjs';
7
8
 
8
9
  const root=path.resolve(fileURLToPath(new URL('..',import.meta.url)));
9
10
  const packagePath=path.join(root,'package.json');
@@ -21,7 +22,7 @@ test('npx CLI reports the canonical package version through --version, -v and ve
21
22
  for(const arg of ['--version','-v','version']){
22
23
  const result=spawnSync(process.execPath,[cliPath,arg],{cwd:root,encoding:'utf8',windowsHide:true});
23
24
  assert.equal(result.status,0,result.stderr);
24
- assert.equal(result.stdout.trim(),'0.15.5');
25
+ assert.equal(result.stdout.trim(),DEADBYTE_VERSION);
25
26
  }
26
27
  });
27
28
 
@@ -50,6 +51,6 @@ test('npx CLI exposes local supervisor lifecycle without any supervisor arm comm
50
51
 
51
52
  test('README makes npx the primary operator UX',async()=>{
52
53
  const readme=await readFile(path.join(root,'README.txt'),'utf8');
53
- assert.match(readme,/npx -y deadbyte-mcp@0\.15\.5 remote/);
54
- assert.match(readme,/npx -y deadbyte-mcp@0\.15\.5 audit verify/);
54
+ assert.match(readme,new RegExp(`npx -y deadbyte-mcp@${DEADBYTE_VERSION.replace(/\./g,'\\.')} remote`));
55
+ assert.match(readme,new RegExp(`npx -y deadbyte-mcp@${DEADBYTE_VERSION.replace(/\./g,'\\.')} audit verify`));
55
56
  });
@@ -14,6 +14,7 @@ import { PROOF_EXECUTION_POLICY } from '../src/operation-policy.mjs';
14
14
  import { createRequestIdentity, validateRequestIdentity } from '../src/request-identity.mjs';
15
15
  import { generateTrustKeypair } from '../src/trust.mjs';
16
16
  import { verifyReceipt } from '../src/verifier.mjs';
17
+ import { DEADBYTE_VERSION } from '../src/version.mjs';
17
18
 
18
19
  const verifierCli = fileURLToPath(new URL('../src/verifier-cli.mjs', import.meta.url));
19
20
 
@@ -105,7 +106,7 @@ test('proof execution creates deterministic output and signed verifiable receipt
105
106
  assert.equal(result.receipt.request.schema, 'deadbyte.request.v1');
106
107
  assert.match(result.receipt.request.nonce, /^[0-9a-f]{64}$/);
107
108
  assert.match(result.receipt.request.sha256, /^[0-9a-f]{64}$/);
108
- assert.equal(result.receipt.runtime.package_version, '0.15.5');
109
+ assert.equal(result.receipt.runtime.package_version, DEADBYTE_VERSION);
109
110
  assert.match(result.receipt.runtime.mcp_ingress_adapter, /^(?:none|tunnel-stdio-probe-compat-v1)$/);
110
111
  assert.match(result.receipt.runtime.mcp_ingress_adapter_sha256, /^[0-9a-f]{64}$/);
111
112
  assert.match(result.receipt.runtime.mcp_ingress_mode_source_sha256, /^[0-9a-f]{64}$/);
@@ -2,6 +2,7 @@ import test from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
3
  import { readFile } from 'node:fs/promises';
4
4
  import { createHash } from 'node:crypto';
5
+ import { DEADBYTE_VERSION } from '../src/version.mjs';
5
6
 
6
7
  const root=new URL('../',import.meta.url);
7
8
  const text=rel=>readFile(new URL(rel,root),'utf8');
@@ -9,7 +10,7 @@ const PARENT_RELEASE='v0.15.2-0fb46542f6a4345f';
9
10
  const PARENT_MANIFEST='0fb46542f6a4345f1c527565d06bf6e9b8e283260e47bf684fb70a60308fcf34';
10
11
  const PARENT_GENERATION='00cde7bf540cc2804d679a39040d5b07193c5f8a0d49cac3b882402f8f4e6ad8';
11
12
 
12
- test('R46 current authority agrees on V0.15.5 and preserves exact V0.15.2 parent identity',async()=>{
13
+ test('R46 current authority agrees on the package release version and preserves exact V0.15.2 parent identity',async()=>{
13
14
  const pkg=JSON.parse(await text('package.json'));
14
15
  const release=JSON.parse(await text('RELEASE.json'));
15
16
  const [version,controller,gate,readme,architecture,controllerReadme,deferred,parity,closure,closureVerify,windowsGate,processPolicy]=await Promise.all([
@@ -27,7 +28,7 @@ test('R46 current authority agrees on V0.15.5 and preserves exact V0.15.2 parent
27
28
  text('controller/deadbyte-process-policy.json')
28
29
  ]);
29
30
 
30
- assert.equal(pkg.version,'0.15.5');
31
+ assert.equal(pkg.version,DEADBYTE_VERSION);
31
32
  assert.equal(pkg.scripts['gate:windows'],'powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r46.ps1');
32
33
  assert.equal(pkg.scripts['self-update:deferred'],'node scripts/deferred-slot-operation-r46.mjs');
33
34
  assert.equal(pkg.scripts['release:parity'],'node scripts/release-parity-r46.mjs');
@@ -36,7 +37,7 @@ test('R46 current authority agrees on V0.15.5 and preserves exact V0.15.2 parent
36
37
  assert.equal(pkg.scripts['r46:fileless:test'],"node --test --test-concurrency=1 test/process-policy.test.mjs test/process-policy-refresh.test.mjs test/release-generation.test.mjs test/process-runtime.test.mjs test/process-mcp-tools.test.mjs test/compact-gateway-r36.test.mjs test/capability-ledger-r36.test.mjs test/remote-device-r44.test.mjs test/observation-runtime.test.mjs test/observation-mcp-tools.test.mjs");
37
38
  assert.equal(pkg.scripts['r46:full:test'],'node scripts/full-regression-r46.mjs');
38
39
 
39
- assert.match(version,/DEADBYTE_VERSION = '0\.15\.5'/);
40
+ assert.match(version,new RegExp(`DEADBYTE_VERSION = '${DEADBYTE_VERSION.replace(/\./g,'\\.')}'`));
40
41
  assert.match(controller,/CONTROLLER V0\.15\.5 \/ R46/);
41
42
  assert.match(gate,/DEADBYTE V0\.15\.5 \/ R46 FILELESS POWERSHELL WINDOWS BATCH GATE: PASS/);
42
43
  assert.match(readme,/^DEADBYTE MCP V0\.15\.5 \/ R46 FILELESS POWERSHELL PRODUCT BASELINE$/m);
@@ -59,7 +60,7 @@ test('R46 current authority agrees on V0.15.5 and preserves exact V0.15.2 parent
59
60
  assert.match(closureVerify,/DEADBYTE-R46-FINAL-CLOSURE-V1/);
60
61
  assert.match(windowsGate,/deadbyte\.r46-windows-gate\.v1/);
61
62
 
62
- assert.equal(release.version,'0.15.5');
63
+ assert.equal(release.version,DEADBYTE_VERSION);
63
64
  assert.equal(release.train,'R46');
64
65
  assert.equal(release.label,'FILELESS POWERSHELL PRODUCT BASELINE');
65
66
  assert.equal(release.parent.release_id,PARENT_RELEASE);
@@ -61,6 +61,26 @@ test('R44 skill catalog is metadata-only and load is signature/content bound',as
61
61
  }finally{await rm(f.root,{recursive:true,force:true});}
62
62
  });
63
63
 
64
+ test('R44 skill plane reports malformed registry entries without hiding valid skills',async()=>{
65
+ const f=await fixture();
66
+ try{
67
+ await installSkill(f,{name:'good-skill'});
68
+ await installSkill(f,{name:'broken-skill'});
69
+ const broken=path.join(f.registry,'broken-skill','skill.json');
70
+ const envelope=JSON.parse(await readFile(broken,'utf8'));
71
+ envelope.body.description='tampered without resigning';
72
+ await writeFile(broken,JSON.stringify(envelope,null,2)+'\n','utf8');
73
+ const plane=await createSkillPlane({root:f.registry,verifyKeyPath:f.keys.publicKeyPath});
74
+ const listed=await plane.list();
75
+ assert.equal(listed.status,'ok');
76
+ assert.deepEqual(listed.skills.map(item=>item.name),['good-skill']);
77
+ assert.equal(listed.invalid_skills.length,1);
78
+ assert.equal(listed.invalid_skills[0].name,'broken-skill');
79
+ assert.match(listed.invalid_skills[0].error,/body hash mismatch/);
80
+ assert.equal(listed.invalid_skills[0].verified,false);
81
+ }finally{await rm(f.root,{recursive:true,force:true});}
82
+ });
83
+
64
84
  test('R44 skill plane fails closed on SKILL.md and resource tampering',async()=>{
65
85
  const f=await fixture();
66
86
  try{