deadbyte-mcp 0.11.3 → 0.13.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/MANIFEST.SHA256 +126 -54
- package/R41-PARENT.json +15 -0
- package/README.txt +5 -4
- package/acceptance/r40/desktop-live-drift.mjs +106 -0
- package/acceptance/r40/desktop-live-ground.mjs +110 -0
- package/acceptance/r40/desktop-live-input.mjs +128 -0
- package/acceptance/r40/desktop-live-observe.mjs +100 -0
- package/acceptance/r40/desktop-live-uia.mjs +121 -0
- package/bin/appcontainer-stage.obj +0 -0
- package/bin/bootstrap-advapi32.obj +0 -0
- package/bin/bootstrap-exitcode.obj +0 -0
- package/bin/bootstrap-kernel32.obj +0 -0
- package/bin/child-control-probe.obj +0 -0
- package/bin/child-control-stage.obj +0 -0
- package/bin/contained-reverse-worker.obj +0 -0
- package/bin/contained-transform-worker.obj +0 -0
- package/bin/containment-probe.obj +0 -0
- package/bin/deadbyte-contain.obj +0 -0
- package/bin/deadbyte-desktop-input-r40.exe +0 -0
- package/bin/deadbyte-desktop-input-r40.obj +0 -0
- package/bin/deadbyte-desktop-observer-r40.exe +0 -0
- package/bin/deadbyte-desktop-observer-r40.obj +0 -0
- package/bin/deadbyte-desktop-uia-r40.exe +0 -0
- package/bin/deadbyte-desktop-uia-r40.obj +0 -0
- package/bin/deadbyte-exec.obj +0 -0
- package/bin/deadbyte-process-host.obj +0 -0
- package/bin/deadbyte-tunnel-host.obj +0 -0
- package/controller/README.TXT +7 -5
- package/controller/deadbyte-controller.config.psd1.example +3 -0
- package/controller/deadbyte-controller.ps1 +149 -4
- package/controller/deadbyte-desktop-policy.json +41 -0
- package/controller/deadbyte-process-policy.json +4 -4
- package/docs/ARCHITECTURE.md +6 -1
- package/docs/superpowers/specs/2026-09-19-r40-desktop-computer-use-design.md +214 -0
- package/docs/superpowers/specs/2026-09-20-r41-deterministic-memory-design.md +132 -0
- package/native/deadbyte-desktop-input.cpp +455 -0
- package/native/deadbyte-desktop-observer.cpp +253 -0
- package/native/deadbyte-desktop-uia.cpp +307 -0
- package/package.json +12 -8
- package/proof/CONTAINMENT-BUILD.txt +6 -6
- package/scripts/build-containment.ps1 +24 -14
- package/scripts/build-desktop-r40.ps1 +112 -0
- package/scripts/deferred-slot-operation-r40.mjs +126 -0
- package/scripts/deferred-slot-operation-r41.mjs +127 -0
- package/scripts/final-closure-r40.mjs +114 -0
- package/scripts/final-closure-r41.mjs +116 -0
- package/scripts/final-closure-verify-r40.mjs +212 -0
- package/scripts/final-closure-verify-r41.mjs +215 -0
- package/scripts/gate-windows-r40.ps1 +43 -0
- package/scripts/gate-windows-r41.ps1 +48 -0
- package/scripts/init-desktop-policy-r40.ps1 +85 -0
- package/scripts/r40-compact-ledger-probe.mjs +4 -0
- package/scripts/release-parity-r40.mjs +212 -0
- package/scripts/release-parity-r41.mjs +221 -0
- package/scripts/release-parity-tests-r40.ps1 +9 -0
- package/scripts/release-parity-tests-r41.ps1 +9 -0
- package/scripts/verify-memory-r41.mjs +88 -0
- package/scripts/verify-r41-parent.mjs +61 -0
- package/scripts/windows-gate-evidence-r40.mjs +52 -0
- package/scripts/windows-gate-evidence-r41.mjs +53 -0
- package/src/autonomous-context-engine.mjs +3 -1
- package/src/autonomous-planner-contracts.mjs +19 -1
- package/src/autonomous-planner.mjs +24 -0
- package/src/autonomous-runtime.mjs +164 -25
- package/src/capability-ledger.mjs +6 -1
- package/src/compact-gateway-mcp-tools.mjs +14 -2
- package/src/deadbyte-cli.mjs +72 -44
- package/src/desktop-contract.mjs +263 -0
- package/src/desktop-input-r40.mjs +148 -0
- package/src/desktop-mcp-tools-r40.mjs +126 -0
- package/src/desktop-memory-r40.mjs +272 -0
- package/src/desktop-observer-r40.mjs +231 -0
- package/src/desktop-policy-r40.mjs +110 -0
- package/src/desktop-runtime-r40.mjs +318 -0
- package/src/desktop-uia-r40.mjs +123 -0
- package/src/mcp-server.mjs +87 -19
- package/src/memory-r41.mjs +692 -0
- package/src/r40-compact-disarmed-probe.mjs +71 -0
- package/src/r40-full-surface-probe.mjs +34 -0
- package/src/release-generation.mjs +38 -5
- package/src/remote-console.mjs +41 -0
- package/src/remote-live-log.mjs +208 -45
- package/src/remote-mcp-desktop-r40-smoke-client.mjs +70 -0
- package/src/remote-mcp-r40-parity-client.mjs +200 -0
- package/src/remote-mcp-smoke-client.mjs +20 -6
- package/src/remote-result-journal.mjs +10 -2
- package/src/runtime-update.mjs +55 -17
- package/src/tool-audit.mjs +29 -2
- package/src/version.mjs +1 -1
- package/test/autonomous-capability-r36.test.mjs +43 -1
- package/test/autonomous-desktop-r40.test.mjs +188 -0
- package/test/capability-ledger-r36.test.mjs +1 -0
- package/test/cli-entrypoint.test.mjs +1 -1
- package/test/compact-catalog-r36.test.mjs +2 -2
- package/test/compact-gateway-r36.test.mjs +56 -4
- package/test/compact-max-catalog-r40.test.mjs +95 -0
- package/test/controller-desktop-r40.test.mjs +86 -0
- package/test/core.test.mjs +1 -1
- package/test/desktop-adversarial-r40.test.mjs +62 -0
- package/test/desktop-contract-r40.test.mjs +200 -0
- package/test/desktop-input-r40.test.mjs +63 -0
- package/test/desktop-mcp-tools-r40.test.mjs +61 -0
- package/test/desktop-memory-r40.test.mjs +141 -0
- package/test/desktop-observer-r40.test.mjs +119 -0
- package/test/desktop-policy-r40.test.mjs +111 -0
- package/test/desktop-runtime-r40.test.mjs +278 -0
- package/test/desktop-uia-r40.test.mjs +42 -0
- package/test/full-max-catalog-r40.test.mjs +91 -0
- package/test/helpers/autonomous-r34-fixture.mjs +3 -3
- package/test/memory-autonomous-integration-r41.test.mjs +31 -0
- package/test/memory-history-r41.test.mjs +126 -0
- package/test/memory-projections-r41.test.mjs +92 -0
- package/test/memory-retrieval-r41.test.mjs +124 -0
- package/test/memory-snapshot-r41.test.mjs +106 -0
- package/test/r33-closeout-regression.test.mjs +7 -7
- package/test/r33-finalization.test.mjs +15 -15
- package/test/r37-remote-tool-call-timeline.test.mjs +6 -5
- package/test/r40-finalization.test.mjs +118 -0
- package/test/r41-finalization.test.mjs +38 -0
- package/test/release-generation.test.mjs +41 -9
- package/test/release-version.test.mjs +20 -61
- package/test/remote-console-r40.test.mjs +38 -0
- package/test/remote-live-log-r37.test.mjs +89 -32
- package/test/remote-r24-catalog.test.mjs +12 -3
- package/test/remote-result-journal.test.mjs +15 -0
- package/test/remote-session-cli.test.mjs +69 -46
- package/test/runtime-self-update.test.mjs +44 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
|
|
6
|
+
export const DESKTOP_UIA_GROUND_SCHEMA='deadbyte.desktop-uia-ground.v1';
|
|
7
|
+
const HEX64=/^[0-9a-f]{64}$/;
|
|
8
|
+
const HWND=/^0x[0-9a-f]{1,16}$/;
|
|
9
|
+
const QUERY_KINDS=new Set(['root','name_exact','name_contains','automation_id_exact','control_type']);
|
|
10
|
+
const sha256Bytes=value=>createHash('sha256').update(value).digest('hex');
|
|
11
|
+
|
|
12
|
+
function insist(c,m){if(!c)throw new Error(m);}
|
|
13
|
+
function integer(v,label,{min=Number.MIN_SAFE_INTEGER,max=Number.MAX_SAFE_INTEGER}={}){
|
|
14
|
+
insist(Number.isSafeInteger(v)&&v>=min&&v<=max,label+' invalid');return v;
|
|
15
|
+
}
|
|
16
|
+
function hwnd(v){const s=String(v??'').toLowerCase();insist(HWND.test(s),'desktop UIA hwnd invalid');return s;}
|
|
17
|
+
function queryInput(query){
|
|
18
|
+
insist(query&&typeof query==='object'&&!Array.isArray(query),'desktop UIA query invalid');
|
|
19
|
+
const kind=String(query.kind??'');
|
|
20
|
+
insist(QUERY_KINDS.has(kind),'desktop UIA query kind invalid');
|
|
21
|
+
const value=query.value??'';
|
|
22
|
+
insist(typeof value==='string'&&!value.includes('\0'),'desktop UIA query value invalid');
|
|
23
|
+
const bytes=Buffer.from(value,'utf8');
|
|
24
|
+
if(kind==='root') insist(bytes.length===0,'desktop UIA root query cannot carry value');
|
|
25
|
+
else insist(bytes.length>=1&&bytes.length<=512,'desktop UIA query value bytes invalid');
|
|
26
|
+
const maxResults=integer(query.max_results??8,'desktop UIA max_results',{min:1,max:16});
|
|
27
|
+
const ordinal=integer(query.ordinal??0,'desktop UIA ordinal',{min:0,max:maxResults-1});
|
|
28
|
+
const querySha256=sha256Bytes(Buffer.from(JSON.stringify({kind,value,max_results:maxResults,ordinal}),'utf8'));
|
|
29
|
+
return {kind,value,bytes,maxResults,ordinal,querySha256};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function serializeDesktopUiaRequest({expectedWindow,query}={}){
|
|
33
|
+
insist(expectedWindow&&typeof expectedWindow==='object','desktop UIA expected window missing');
|
|
34
|
+
const expectedHwnd=hwnd(expectedWindow.hwnd);
|
|
35
|
+
const expectedPid=integer(expectedWindow.pid,'desktop UIA expected pid',{min:1,max:0x7fffffff});
|
|
36
|
+
const q=queryInput(query);
|
|
37
|
+
const header=Buffer.from([
|
|
38
|
+
'DEADBYTE_DESKTOP_UIA_V1',
|
|
39
|
+
'expected_hwnd='+expectedHwnd,
|
|
40
|
+
'expected_pid='+expectedPid,
|
|
41
|
+
'query_kind='+q.kind,
|
|
42
|
+
'max_results='+q.maxResults,
|
|
43
|
+
'query_bytes='+q.bytes.length,
|
|
44
|
+
''
|
|
45
|
+
].join('\n'),'utf8');
|
|
46
|
+
const request=Buffer.concat([header,q.bytes]);
|
|
47
|
+
insist(request.length<=8192,'desktop UIA request exceeds bound');
|
|
48
|
+
return {request,query:q};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function parseDesktopUiaResponse(bytes,{expectedWindow,query,expectedBounds}={}){
|
|
52
|
+
insist(Buffer.isBuffer(bytes)&&bytes.length>=2&&bytes.length<=256*1024,'desktop UIA response invalid');
|
|
53
|
+
let raw;try{raw=JSON.parse(bytes.toString('utf8').trim());}catch{throw new Error('desktop UIA response JSON invalid');}
|
|
54
|
+
insist(raw?.schema===DESKTOP_UIA_GROUND_SCHEMA,'desktop UIA response schema mismatch');
|
|
55
|
+
const q=queryInput(query);
|
|
56
|
+
insist(String(raw.query_kind)===q.kind,'desktop UIA response query mismatch');
|
|
57
|
+
insist(hwnd(raw.foreground_hwnd)===hwnd(expectedWindow.hwnd),'desktop UIA response hwnd mismatch');
|
|
58
|
+
insist(integer(raw.foreground_pid,'desktop UIA response pid',{min:1,max:0x7fffffff})===expectedWindow.pid,'desktop UIA response pid mismatch');
|
|
59
|
+
integer(raw.visited,'desktop UIA visited',{min:0,max:2048});
|
|
60
|
+
insist(typeof raw.truncated==='boolean','desktop UIA truncated invalid');
|
|
61
|
+
insist(Array.isArray(raw.matches)&&raw.matches.length<=q.maxResults,'desktop UIA matches invalid');
|
|
62
|
+
const left=integer(expectedBounds.left,'desktop UIA bounds left',{min:-131072,max:131072});
|
|
63
|
+
const top=integer(expectedBounds.top,'desktop UIA bounds top',{min:-131072,max:131072});
|
|
64
|
+
const width=integer(expectedBounds.width,'desktop UIA bounds width',{min:1,max:131072});
|
|
65
|
+
const height=integer(expectedBounds.height,'desktop UIA bounds height',{min:1,max:131072});
|
|
66
|
+
const matches=[];
|
|
67
|
+
for(const item of raw.matches){
|
|
68
|
+
const rect={
|
|
69
|
+
left:integer(item.left,'desktop UIA rect left',{min:-131072,max:131072}),
|
|
70
|
+
top:integer(item.top,'desktop UIA rect top',{min:-131072,max:131072}),
|
|
71
|
+
width:integer(item.width,'desktop UIA rect width',{min:1,max:131072}),
|
|
72
|
+
height:integer(item.height,'desktop UIA rect height',{min:1,max:131072})
|
|
73
|
+
};
|
|
74
|
+
const inside=rect.left>=left&&rect.top>=top&&rect.left+rect.width<=left+width&&rect.top+rect.height<=top+height;
|
|
75
|
+
if(!inside) continue;
|
|
76
|
+
matches.push(Object.freeze({
|
|
77
|
+
rect:Object.freeze(rect),
|
|
78
|
+
control_type:integer(item.control_type,'desktop UIA control_type',{min:0,max:100000}),
|
|
79
|
+
enabled:item.enabled===true,offscreen:item.offscreen===true
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
return Object.freeze({
|
|
83
|
+
status:'ok',query_sha256:q.querySha256,query_kind:q.kind,ordinal:q.ordinal,
|
|
84
|
+
visited:raw.visited,truncated:raw.truncated,matches:Object.freeze(matches),
|
|
85
|
+
provider_receipt_sha256:sha256Bytes(bytes)
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function invokeNativeDesktopGrounder({grounderPath,expectedGrounderSha256,timeoutMs=5000,expectedWindow,expectedBounds,query}={}){
|
|
90
|
+
insist(typeof grounderPath==='string'&&path.isAbsolute(grounderPath),'desktop grounderPath must be absolute');
|
|
91
|
+
insist(HEX64.test(expectedGrounderSha256??''),'desktop expectedGrounderSha256 invalid');
|
|
92
|
+
integer(timeoutMs,'desktop UIA timeoutMs',{min:100,max:30000});
|
|
93
|
+
const exe=await readFile(grounderPath);
|
|
94
|
+
insist(exe.length>0&&exe.length<=4*1024*1024,'desktop UIA binary size invalid');
|
|
95
|
+
insist(sha256Bytes(exe)===expectedGrounderSha256,'desktop UIA executable hash mismatch');
|
|
96
|
+
const packed=serializeDesktopUiaRequest({expectedWindow,query});
|
|
97
|
+
return await new Promise((resolve,reject)=>{
|
|
98
|
+
const child=spawn(grounderPath,[],{shell:false,windowsHide:true,stdio:['pipe','pipe','pipe']});
|
|
99
|
+
const stdout=[];let bytes=0,stderr='',done=false,timer=null;
|
|
100
|
+
const finish=(error,value)=>{if(done)return;done=true;if(timer!==null)clearTimeout(timer);error?reject(error):resolve(value);};
|
|
101
|
+
child.stdout.on('data',chunk=>{bytes+=chunk.length;if(bytes>256*1024){try{child.kill('SIGKILL');}catch{};return finish(new Error('desktop UIA stdout exceeds bound'));}stdout.push(Buffer.from(chunk));});
|
|
102
|
+
child.stderr.on('data',chunk=>{stderr+=chunk.toString('utf8');if(Buffer.byteLength(stderr,'utf8')>64*1024){try{child.kill('SIGKILL');}catch{};finish(new Error('desktop UIA stderr exceeds bound'));}});
|
|
103
|
+
child.once('error',error=>finish(error));
|
|
104
|
+
child.once('exit',(code,signal)=>{
|
|
105
|
+
if(code!==0)return finish(new Error('desktop UIA exit='+code+' signal='+(signal??'none')+' stderr='+stderr.slice(-8192)));
|
|
106
|
+
try{finish(null,parseDesktopUiaResponse(Buffer.concat(stdout),{expectedWindow,query,expectedBounds}));}
|
|
107
|
+
catch(error){finish(error);}
|
|
108
|
+
});
|
|
109
|
+
child.stdin.on('error',error=>finish(error));
|
|
110
|
+
child.stdin.end(packed.request);
|
|
111
|
+
timer=setTimeout(()=>{try{child.kill('SIGKILL');}catch{};finish(new Error('desktop UIA timed out after '+timeoutMs+'ms'));},timeoutMs);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function createNativeDesktopGrounder({grounderPath,expectedGrounderSha256,timeoutMs=5000}={}){
|
|
116
|
+
return async({frame,query}={})=>{
|
|
117
|
+
insist(frame?.active_window,'desktop UIA grounding requires foreground window');
|
|
118
|
+
return invokeNativeDesktopGrounder({
|
|
119
|
+
grounderPath,expectedGrounderSha256,timeoutMs,
|
|
120
|
+
expectedWindow:frame.active_window,expectedBounds:frame.bounds,query
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
}
|
package/src/mcp-server.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
import { access, readFile } from 'node:fs/promises';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import os from 'node:os';
|
|
@@ -9,7 +10,7 @@ import { executeProof } from './executor.mjs';
|
|
|
9
10
|
import { CONTAINED_TRANSFORM_OPERATIONS, executeContainedTransform } from './contained-executor.mjs';
|
|
10
11
|
import { resolveExistingInside, resolveWorkspace } from './path-policy.mjs';
|
|
11
12
|
import { verifyReceipt } from './verifier.mjs';
|
|
12
|
-
import { defaultPrivateKeyPath, defaultPublicKeyPath } from './trust.mjs';
|
|
13
|
+
import { defaultPrivateKeyPath, defaultPublicKeyPath, loadPrivateSigningKey, loadPublicVerifyKey } from './trust.mjs';
|
|
13
14
|
import { DEADBYTE_VERSION } from './version.mjs';
|
|
14
15
|
import { currentIngressAdapterMode, TUNNEL_STDIO_PROBE_COMPAT_MODE } from './ingress-mode.mjs';
|
|
15
16
|
import { installTunnelStdioProbeCompat } from './tunnel-stdio-compat.mjs';
|
|
@@ -31,6 +32,14 @@ import { createMachineFsRuntime } from './machine-fs.mjs';
|
|
|
31
32
|
import { registerMachineFsTools } from './machine-fs-mcp-tools.mjs';
|
|
32
33
|
import { createObservationRuntime } from './observation-runtime.mjs';
|
|
33
34
|
import { registerObservationTools } from './observation-mcp-tools.mjs';
|
|
35
|
+
import { loadDesktopPolicy } from './desktop-policy-r40.mjs';
|
|
36
|
+
import { createDesktopObserverRuntime } from './desktop-observer-r40.mjs';
|
|
37
|
+
import { createNativeDesktopInputProvider } from './desktop-input-r40.mjs';
|
|
38
|
+
import { createNativeDesktopGrounder } from './desktop-uia-r40.mjs';
|
|
39
|
+
import { createDesktopRuntime } from './desktop-runtime-r40.mjs';
|
|
40
|
+
import { createDesktopMemoryProvider } from './desktop-memory-r40.mjs';
|
|
41
|
+
import { createR41MemoryProvider } from './memory-r41.mjs';
|
|
42
|
+
import { registerDesktopTools } from './desktop-mcp-tools-r40.mjs';
|
|
34
43
|
import { loadAutonomousPolicy } from './autonomous-policy.mjs';
|
|
35
44
|
import { createNativeDiffRuntime } from './native-diff.mjs';
|
|
36
45
|
import { createAutonomousRuntime } from './autonomous-runtime.mjs';
|
|
@@ -54,6 +63,7 @@ import {
|
|
|
54
63
|
} from './output-contracts.mjs';
|
|
55
64
|
|
|
56
65
|
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
66
|
+
const packageManifestSha256=createHash('sha256').update(await readFile(path.join(packageRoot,'MANIFEST.SHA256'))).digest('hex');
|
|
57
67
|
const workspaceRoot = path.resolve(process.env.DEADBYTE_WORKSPACE_ROOT ?? path.join(packageRoot, 'workspaces'));
|
|
58
68
|
const signingKeyPath = process.env.DEADBYTE_SIGNING_KEY ?? defaultPrivateKeyPath();
|
|
59
69
|
const verifyKeyPath = process.env.DEADBYTE_VERIFY_KEY ?? defaultPublicKeyPath();
|
|
@@ -125,6 +135,44 @@ const observationRuntime = observationRuntimeMode === '1'
|
|
|
125
135
|
stateRoot: runtimeStateRoot })
|
|
126
136
|
: null;
|
|
127
137
|
|
|
138
|
+
const desktopRuntimeMode=process.env.DEADBYTE_DESKTOP_RUNTIME??'0';
|
|
139
|
+
if(!['0','1'].includes(desktopRuntimeMode)) throw new Error('DEADBYTE_DESKTOP_RUNTIME must be 0 or 1');
|
|
140
|
+
const localDesktopPolicyPath=path.join(packageRoot,'controller','deadbyte-desktop-policy.json');
|
|
141
|
+
let desktopPolicyPath=process.env.DEADBYTE_DESKTOP_POLICY??'';
|
|
142
|
+
if(desktopRuntimeMode==='1'&&!desktopPolicyPath){
|
|
143
|
+
try{await access(localDesktopPolicyPath);desktopPolicyPath=localDesktopPolicyPath;}
|
|
144
|
+
catch(error){if(error?.code!=='ENOENT')throw error;}
|
|
145
|
+
}
|
|
146
|
+
if(desktopRuntimeMode==='1'&&!desktopPolicyPath) throw new Error('DEADBYTE_DESKTOP_RUNTIME=1 requires a desktop policy');
|
|
147
|
+
const desktopPolicy=desktopRuntimeMode==='1'?await loadDesktopPolicy(desktopPolicyPath):null;
|
|
148
|
+
const desktopObserverRuntime=desktopPolicy?createDesktopObserverRuntime({
|
|
149
|
+
observerPath:desktopPolicy.observer.executable,expectedObserverSha256:desktopPolicy.observer.sha256,
|
|
150
|
+
maxFrameBytes:desktopPolicy.limits.max_frame_bytes,timeoutMs:desktopPolicy.limits.capture_timeout_ms,
|
|
151
|
+
allowInputDesktops:desktopPolicy.allowed_input_desktops
|
|
152
|
+
}):null;
|
|
153
|
+
const desktopInputProvider=desktopPolicy?createNativeDesktopInputProvider({
|
|
154
|
+
inputPath:desktopPolicy.input.executable,expectedInputSha256:desktopPolicy.input.sha256,
|
|
155
|
+
timeoutMs:desktopPolicy.limits.input_timeout_ms
|
|
156
|
+
}):null;
|
|
157
|
+
const desktopGrounderProvider=desktopPolicy?createNativeDesktopGrounder({
|
|
158
|
+
grounderPath:desktopPolicy.grounder.executable,expectedGrounderSha256:desktopPolicy.grounder.sha256,
|
|
159
|
+
timeoutMs:desktopPolicy.limits.ground_timeout_ms
|
|
160
|
+
}):null;
|
|
161
|
+
const desktopSigningKey=desktopPolicy?await loadPrivateSigningKey(signingKeyPath):null;
|
|
162
|
+
const desktopVerifyKey=desktopPolicy?await loadPublicVerifyKey(verifyKeyPath):null;
|
|
163
|
+
if(desktopPolicy&&desktopSigningKey.keyId!==desktopVerifyKey.keyId) throw new Error('Desktop signing/verify key mismatch');
|
|
164
|
+
const desktopRuntime=desktopPolicy?createDesktopRuntime({
|
|
165
|
+
policy:desktopPolicy,observerRuntime:desktopObserverRuntime,inputProvider:desktopInputProvider,
|
|
166
|
+
grounderProvider:desktopGrounderProvider,
|
|
167
|
+
privateKey:desktopSigningKey.privateKey,publicKey:desktopVerifyKey.publicKey,keyId:desktopSigningKey.keyId
|
|
168
|
+
}):null;
|
|
169
|
+
const desktopMemoryProvider=desktopPolicy?createDesktopMemoryProvider({
|
|
170
|
+
evidenceDir:desktopPolicy.evidence_dir,
|
|
171
|
+
snapshotPath:path.join(desktopPolicy.evidence_dir,'desktop-memory.json'),
|
|
172
|
+
policySha256:desktopPolicy.policy_sha256,
|
|
173
|
+
privateKey:desktopSigningKey.privateKey,publicKey:desktopVerifyKey.publicKey,keyId:desktopSigningKey.keyId
|
|
174
|
+
}):null;
|
|
175
|
+
|
|
128
176
|
const autonomousRuntimeMode = process.env.DEADBYTE_AUTONOMOUS_RUNTIME ?? '0';
|
|
129
177
|
if (!['0','1'].includes(autonomousRuntimeMode)) throw new Error('DEADBYTE_AUTONOMOUS_RUNTIME must be 0 or 1');
|
|
130
178
|
const autonomousSupervisorMode = process.env.DEADBYTE_AUTONOMOUS_SUPERVISOR_MODE ?? 'in_process';
|
|
@@ -142,8 +190,18 @@ if (autonomousRuntimeMode === '1' && !autonomousPolicyPath) throw new Error('DEA
|
|
|
142
190
|
const autonomousPolicy = autonomousRuntimeMode === '1' ? await loadAutonomousPolicy(autonomousPolicyPath,codingPolicy) : null;
|
|
143
191
|
const nativeDiffRuntime = autonomousPolicy ? createNativeDiffRuntime({ policy:autonomousPolicy,codingRuntime,machineFsRuntime,signingKeyPath,verifyKeyPath }) : null;
|
|
144
192
|
semanticRuntime = codingRuntime ? createSemanticCodeRuntime({ codingRuntime, backends: semanticLsp.backends, nativeDiffRuntime }) : null;
|
|
193
|
+
const autonomousMemorySigningKey=autonomousPolicy?await loadPrivateSigningKey(signingKeyPath):null;
|
|
194
|
+
const autonomousMemoryVerifyKey=autonomousPolicy?await loadPublicVerifyKey(verifyKeyPath):null;
|
|
195
|
+
if(autonomousPolicy&&autonomousMemorySigningKey.keyId!==autonomousMemoryVerifyKey.keyId) throw new Error('R41 memory signing/verify key mismatch');
|
|
196
|
+
const memoryProvider=autonomousPolicy?createR41MemoryProvider({
|
|
197
|
+
memoryRoot:path.join(autonomousPolicy.evidence_dir,'memory-r41',packageManifestSha256),sourceReleaseManifest:packageManifestSha256,
|
|
198
|
+
journalRoot:path.join(autonomousPolicy.evidence_dir,'goals'),
|
|
199
|
+
writerVersion:DEADBYTE_VERSION,privateKey:autonomousMemorySigningKey.privateKey,
|
|
200
|
+
publicKey:autonomousMemoryVerifyKey.publicKey,keyId:autonomousMemorySigningKey.keyId,
|
|
201
|
+
byteBudget:Math.min(262144,Math.max(65536,Math.floor(autonomousPolicy.limits.max_context_bytes/2))),semantic:{enabled:false}
|
|
202
|
+
}):null;
|
|
145
203
|
const autonomousRuntime = autonomousPolicy ? createAutonomousRuntime({ policy:autonomousPolicy,codingRuntime,nativeDiffRuntime,
|
|
146
|
-
machineFsRuntime,observationRuntime,processRuntime,semanticRuntime,signingKeyPath,verifyKeyPath }) : null;
|
|
204
|
+
machineFsRuntime,observationRuntime,processRuntime,semanticRuntime,desktopRuntime,desktopMemoryProvider,memoryProvider,signingKeyPath,verifyKeyPath }) : null;
|
|
147
205
|
const autonomousSupervisor = autonomousRuntime && autonomousPolicy.planner.backend === 'openai_compatible' &&
|
|
148
206
|
autonomousSupervisorMode === 'in_process'
|
|
149
207
|
? startAutonomousSupervisor({ runtime: autonomousRuntime, policy: autonomousPolicy })
|
|
@@ -185,11 +243,17 @@ function filteredToolServer(server,allowed){
|
|
|
185
243
|
|
|
186
244
|
serveStdio(() => {
|
|
187
245
|
const server = new McpServer({ name: 'deadbyte-mcp', version: DEADBYTE_VERSION });
|
|
246
|
+
const registeredToolNames=new Set();
|
|
247
|
+
const toolServer={registerTool(name,...args){
|
|
248
|
+
if(registeredToolNames.has(name)) throw new Error(`duplicate tool registration: ${name}`);
|
|
249
|
+
registeredToolNames.add(name);
|
|
250
|
+
return server.registerTool(name,...args);
|
|
251
|
+
}};
|
|
188
252
|
registerOperatorSurface(server,{packageRoot,surfaceProfile,compactToolLimit:COMPACT_SURFACE_TOOL_LIMIT});
|
|
189
253
|
if (toolAudit) installToolAudit(server,toolAudit);
|
|
190
254
|
|
|
191
255
|
if (surfaceProfile === 'full') {
|
|
192
|
-
|
|
256
|
+
toolServer.registerTool(
|
|
193
257
|
'workspace_open',
|
|
194
258
|
{
|
|
195
259
|
description: 'Open a named workspace below the configured DEADBYTE workspace root.',
|
|
@@ -206,7 +270,7 @@ serveStdio(() => {
|
|
|
206
270
|
}
|
|
207
271
|
);
|
|
208
272
|
|
|
209
|
-
|
|
273
|
+
toolServer.registerTool(
|
|
210
274
|
'file_read',
|
|
211
275
|
{
|
|
212
276
|
description: 'Read one UTF-8 file inside a named workspace. Path traversal and symlink escape are denied.',
|
|
@@ -229,7 +293,7 @@ serveStdio(() => {
|
|
|
229
293
|
}
|
|
230
294
|
);
|
|
231
295
|
|
|
232
|
-
|
|
296
|
+
toolServer.registerTool(
|
|
233
297
|
'proof_execute',
|
|
234
298
|
{
|
|
235
299
|
description: 'Run the fixed DEADBYTE V0 proof worker inside one workspace and produce an Ed25519-signed hashed receipt. This is not a general shell.',
|
|
@@ -263,7 +327,7 @@ serveStdio(() => {
|
|
|
263
327
|
}
|
|
264
328
|
);
|
|
265
329
|
|
|
266
|
-
|
|
330
|
+
toolServer.registerTool(
|
|
267
331
|
'contained_transform',
|
|
268
332
|
{
|
|
269
333
|
description: 'Run one compile-time allowlisted ASCII transform inside the proven Windows AppContainer + atomic Job boundary. Input is copied into a private sandbox profile; the host workspace is never mounted. This is not a shell and does not accept an executable path.',
|
|
@@ -306,7 +370,7 @@ serveStdio(() => {
|
|
|
306
370
|
|
|
307
371
|
}
|
|
308
372
|
|
|
309
|
-
|
|
373
|
+
toolServer.registerTool(
|
|
310
374
|
'evidence_verify',
|
|
311
375
|
{
|
|
312
376
|
description: 'Independently verify Ed25519 receipt authenticity and recompute file, stream, and worker hashes.',
|
|
@@ -327,7 +391,7 @@ serveStdio(() => {
|
|
|
327
391
|
);
|
|
328
392
|
|
|
329
393
|
if (machineRuntime) {
|
|
330
|
-
registerMachineTools(
|
|
394
|
+
registerMachineTools(toolServer, {
|
|
331
395
|
runtime: machineRuntime,
|
|
332
396
|
assertRevokeAuthority: async () => {
|
|
333
397
|
if (!hostPolicy) throw new Error('privileged host plane is not configured');
|
|
@@ -337,37 +401,41 @@ serveStdio(() => {
|
|
|
337
401
|
}
|
|
338
402
|
|
|
339
403
|
if (agentRuntime && surfaceProfile === 'full') {
|
|
340
|
-
registerAgentTools(
|
|
404
|
+
registerAgentTools(toolServer, { runtime: agentRuntime, workspacePathFromId });
|
|
341
405
|
}
|
|
342
406
|
|
|
343
407
|
if (processRuntime && surfaceProfile === 'full') {
|
|
344
|
-
registerProcessTools(
|
|
408
|
+
registerProcessTools(toolServer, { runtime: processRuntime });
|
|
345
409
|
}
|
|
346
410
|
|
|
347
411
|
if (codingRuntime && codingTaskRuntime && semanticRuntime) {
|
|
348
|
-
const codingServer=surfaceProfile==='full'?
|
|
412
|
+
const codingServer=surfaceProfile==='full'?toolServer:filteredToolServer(toolServer,COMPACT_CODING_DIRECT_TOOLS);
|
|
349
413
|
registerCodingTools(codingServer, { codingRuntime, taskRuntime: codingTaskRuntime, semanticRuntime });
|
|
350
414
|
}
|
|
351
415
|
|
|
352
416
|
if (machineFsRuntime && surfaceProfile === 'full') {
|
|
353
|
-
registerMachineFsTools(
|
|
417
|
+
registerMachineFsTools(toolServer, { runtime: machineFsRuntime });
|
|
354
418
|
}
|
|
355
419
|
|
|
356
420
|
if (observationRuntime && surfaceProfile === 'full') {
|
|
357
|
-
registerObservationTools(
|
|
421
|
+
registerObservationTools(toolServer, { runtime: observationRuntime });
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if (desktopRuntime && surfaceProfile === 'full') {
|
|
425
|
+
registerDesktopTools(toolServer,{runtime:desktopRuntime});
|
|
358
426
|
}
|
|
359
427
|
|
|
360
428
|
if (autonomousRuntime && nativeDiffRuntime) {
|
|
361
|
-
registerAutonomousTools(
|
|
429
|
+
registerAutonomousTools(toolServer, { autonomousRuntime, nativeDiffRuntime });
|
|
362
430
|
}
|
|
363
431
|
|
|
364
|
-
registerCompactGatewayTools(
|
|
432
|
+
registerCompactGatewayTools(toolServer,{
|
|
365
433
|
profile:surfaceProfile,ledger:R36_CAPABILITY_LEDGER,codingRuntime,semanticRuntime,machineFsRuntime,
|
|
366
|
-
processRuntime,observationRuntime,machineRuntime
|
|
434
|
+
processRuntime,observationRuntime,machineRuntime,desktopRuntime,catalogProvider:()=>[...registeredToolNames]
|
|
367
435
|
});
|
|
368
436
|
|
|
369
437
|
if (hostPolicy) {
|
|
370
|
-
|
|
438
|
+
toolServer.registerTool(
|
|
371
439
|
'host_file_read',
|
|
372
440
|
{
|
|
373
441
|
description: 'Privileged host-plane read from a locally allowlisted root. Requires a live local arm lease; path traversal and symlink escape are denied.',
|
|
@@ -388,7 +456,7 @@ serveStdio(() => {
|
|
|
388
456
|
}
|
|
389
457
|
);
|
|
390
458
|
|
|
391
|
-
|
|
459
|
+
toolServer.registerTool(
|
|
392
460
|
'host_file_write',
|
|
393
461
|
{
|
|
394
462
|
description: 'Privileged host-plane hash-precondition file write inside a locally allowlisted root. Commit is same-directory atomic rename and post-commit SHA-256 verified. Requires a live local arm lease.',
|
|
@@ -417,7 +485,7 @@ serveStdio(() => {
|
|
|
417
485
|
}
|
|
418
486
|
);
|
|
419
487
|
|
|
420
|
-
|
|
488
|
+
toolServer.registerTool(
|
|
421
489
|
'host_exec',
|
|
422
490
|
{
|
|
423
491
|
description: 'Privileged host-plane script execution through a locally allowlisted and SHA-256-pinned executable. No raw shell command string is accepted. Requires a live local arm lease.',
|