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.
- package/DEADBYTE-MCP.cmd +5 -0
- package/README.txt +6 -6
- package/RELEASE.json +1 -1
- package/package.json +1 -1
- package/src/skill-plane-r44.mjs +12 -7
- package/src/version.mjs +1 -1
- package/test/cli-entrypoint.test.mjs +4 -3
- package/test/core.test.mjs +2 -1
- package/test/release-version.test.mjs +5 -4
- package/test/skill-plane-r44.test.mjs +20 -0
package/DEADBYTE-MCP.cmd
ADDED
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.
|
|
11
|
-
npx -y deadbyte-mcp@0.15.
|
|
12
|
-
npx -y deadbyte-mcp@0.15.
|
|
13
|
-
npx -y deadbyte-mcp@0.15.
|
|
14
|
-
npx -y deadbyte-mcp@0.15.
|
|
15
|
-
npx -y deadbyte-mcp@0.15.
|
|
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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deadbyte-mcp",
|
|
3
|
-
"version": "0.15.
|
|
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.",
|
package/src/skill-plane-r44.mjs
CHANGED
|
@@ -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
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
@@ -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(),
|
|
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
|
|
54
|
-
assert.match(readme
|
|
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
|
});
|
package/test/core.test.mjs
CHANGED
|
@@ -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,
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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{
|