deadbyte-mcp 0.9.0 → 0.10.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 +119 -91
- package/README.txt +16 -11
- package/bench/fixtures/corpus.json +32 -13
- package/bench/fixtures/r36/case-map.json +8 -0
- package/bin/WORKER-REGISTRY.txt +3 -3
- package/bin/appcontainer-stage.exe +0 -0
- package/bin/appcontainer-stage.obj +0 -0
- package/bin/bootstrap-advapi32.exe +0 -0
- package/bin/bootstrap-advapi32.obj +0 -0
- package/bin/bootstrap-exitcode.exe +0 -0
- package/bin/bootstrap-exitcode.obj +0 -0
- package/bin/bootstrap-kernel32.exe +0 -0
- package/bin/bootstrap-kernel32.obj +0 -0
- package/bin/child-control-probe.exe +0 -0
- package/bin/child-control-probe.obj +0 -0
- package/bin/child-control-stage.exe +0 -0
- package/bin/child-control-stage.obj +0 -0
- package/bin/contained-reverse-worker.exe +0 -0
- package/bin/contained-reverse-worker.obj +0 -0
- package/bin/contained-transform-worker.exe +0 -0
- package/bin/contained-transform-worker.obj +0 -0
- package/bin/containment-probe.exe +0 -0
- package/bin/containment-probe.obj +0 -0
- package/bin/deadbyte-contain.exe +0 -0
- package/bin/deadbyte-contain.obj +0 -0
- package/bin/deadbyte-exec.exe +0 -0
- package/bin/deadbyte-exec.obj +0 -0
- package/bin/deadbyte-process-host.exe +0 -0
- package/bin/deadbyte-process-host.obj +0 -0
- package/bin/deadbyte-tunnel-host.exe +0 -0
- package/bin/deadbyte-tunnel-host.obj +0 -0
- package/controller/README.TXT +8 -6
- package/controller/deadbyte-controller.ps1 +48 -2
- package/controller/deadbyte-process-policy.json +5 -5
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/R36-CAPABILITY-EVIDENCE.md +43 -0
- package/docs/superpowers/plans/2026-09-18-r36-zero-loss-autonomy.md +739 -0
- package/docs/superpowers/specs/2026-09-18-r36-zero-loss-autonomy-design.md +640 -0
- package/package.json +1 -1
- package/proof/CONTAINMENT-BUILD.txt +6 -6
- package/scripts/deferred-slot-operation.mjs +53 -15
- package/scripts/final-closure-verify.mjs +88 -39
- package/scripts/final-closure.mjs +63 -56
- package/scripts/gate-windows.ps1 +3 -3
- package/scripts/release-parity-tests.ps1 +9 -0
- package/scripts/release-parity.mjs +149 -139
- package/scripts/windows-gate-evidence.mjs +5 -5
- package/src/autonomous-context-engine.mjs +2 -1
- package/src/autonomous-mcp-tools.mjs +5 -1
- package/src/autonomous-output-contracts.mjs +4 -4
- package/src/autonomous-planner-contracts.mjs +36 -1
- package/src/autonomous-planner.mjs +25 -3
- package/src/autonomous-runtime.mjs +191 -21
- package/src/capability-benchmark-runner.mjs +86 -1
- package/src/capability-benchmark.mjs +45 -0
- package/src/capability-ledger.mjs +158 -0
- package/src/coding-mcp-tools.mjs +31 -17
- package/src/coding-output-contracts.mjs +48 -10
- package/src/coding-plane.mjs +45 -9
- package/src/coding-search.mjs +130 -47
- package/src/compact-gateway-mcp-tools.mjs +128 -0
- package/src/compact-gateway-output-contracts.mjs +16 -0
- package/src/deadbyte-cli.mjs +51 -28
- package/src/machine-fs-smoke-client.mjs +1 -1
- package/src/machine-fs.mjs +51 -8
- package/src/mcp-server.mjs +32 -9
- package/src/native-diff-v2.mjs +337 -0
- package/src/native-diff.mjs +50 -2
- package/src/observation-smoke-client.mjs +1 -1
- package/src/operator-surface.mjs +7 -1
- package/src/process-runtime.mjs +98 -11
- package/src/process-smoke-client.mjs +11 -3
- package/src/r36-compact-disarmed-probe.mjs +50 -0
- package/src/r36-full-surface-probe.mjs +56 -0
- package/src/remote-live-log.mjs +76 -0
- package/src/remote-mcp-autonomous-smoke-client.mjs +7 -3
- package/src/remote-mcp-coding-smoke-client.mjs +1 -1
- package/src/remote-mcp-r36-parity-client.mjs +175 -0
- package/src/remote-mcp-smoke-client.mjs +112 -56
- package/src/runtime-update.mjs +51 -1
- package/src/search-cursor.mjs +45 -0
- package/src/semantic-code.mjs +72 -5
- package/src/semantic-lsp-backend.mjs +39 -3
- package/src/version.mjs +1 -1
- package/test/autonomous-capability-r36.test.mjs +151 -0
- package/test/autonomous-runtime.test.mjs +2 -2
- package/test/capability-benchmark-r36.test.mjs +107 -0
- package/test/capability-benchmark-semantic-r36.test.mjs +52 -0
- package/test/capability-claims-r36.test.mjs +23 -0
- package/test/capability-ledger-r36.test.mjs +102 -0
- package/test/coding-catalog-consistency.test.mjs +2 -2
- package/test/coding-plane.test.mjs +2 -2
- package/test/coding-runtime.test.mjs +16 -0
- package/test/coding-search-r36.test.mjs +90 -0
- package/test/compact-catalog-r36.test.mjs +37 -0
- package/test/compact-gateway-r36.test.mjs +66 -0
- package/test/contained.test.mjs +1 -1
- package/test/core.test.mjs +1 -1
- package/test/deferred-slot-operation.test.mjs +9 -0
- package/test/fixtures/lsp-framed-server.mjs +2 -0
- package/test/helpers/autonomous-r34-fixture.mjs +5 -3
- package/test/multi-file-read.test.mjs +3 -0
- package/test/native-diff-topology-r36.test.mjs +105 -0
- package/test/package-boundary.test.mjs +6 -0
- package/test/process-longrun-r36.test.mjs +82 -0
- package/test/process-release-gate.test.mjs +9 -0
- package/test/production-docs.test.mjs +3 -3
- package/test/prompts-resources.test.mjs +7 -1
- package/test/r33-closeout-regression.test.mjs +4 -3
- package/test/r33-finalization.test.mjs +14 -9
- package/test/r36-finalization.test.mjs +104 -0
- package/test/r36-release-identity.test.mjs +52 -0
- package/test/release-version.test.mjs +18 -15
- package/test/remote-live-log-r36.test.mjs +37 -0
- package/test/remote-live-log-recovery-r36.test.mjs +41 -0
- package/test/remote-r24-catalog.test.mjs +13 -0
- package/test/remote-session-cli.test.mjs +40 -30
- package/test/runtime-self-update.test.mjs +58 -1
- package/test/semantic-lsp-backend.test.mjs +9 -0
- package/test/semantic-r36-rename.test.mjs +82 -0
- package/deadbyte-mcp-0.8.9.tgz +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import * as z from 'zod/v4';
|
|
2
|
+
import { compactGatewayOutputSchema, compactGatewayResult } from './compact-gateway-output-contracts.mjs';
|
|
3
|
+
|
|
4
|
+
const id=z.string().regex(/^[A-Za-z0-9._-]{1,64}$/);
|
|
5
|
+
const rel=z.string().min(1).max(2048);
|
|
6
|
+
const rel512=z.string().min(1).max(512);
|
|
7
|
+
const hex64=z.string().regex(/^[0-9a-f]{64}$/);
|
|
8
|
+
const cursor=z.string().max(4096).nullable().default(null);
|
|
9
|
+
const nonneg=z.number().int().nonnegative();
|
|
10
|
+
const symbolName=z.string().regex(/^[A-Za-z_$][A-Za-z0-9_$]{0,127}$/);
|
|
11
|
+
|
|
12
|
+
export const codingInspectInputSchema=z.discriminatedUnion('op',[
|
|
13
|
+
z.strictObject({op:z.literal('stat'),root_id:id,path:rel512.default('.'),hash:z.boolean().default(false)}),
|
|
14
|
+
z.strictObject({op:z.literal('search'),root_id:id,path:rel512.default('.'),pattern:z.string().min(1).max(256),target:z.enum(['content','path']).default('content'),mode:z.enum(['literal','regex']).default('literal'),case_sensitive:z.boolean().default(false),max_results:z.number().int().min(1).max(1000).default(200),max_file_bytes:z.number().int().min(1).max(4*1024*1024).default(262144),max_scan_bytes:z.number().int().min(1).max(64*1024*1024).default(4*1024*1024),page_size:z.number().int().min(1).max(500).default(100),cursor}),
|
|
15
|
+
z.strictObject({op:z.literal('files_read'),root_id:id,files:z.array(z.strictObject({path:rel512,encoding:z.enum(['utf8','base64']).default('utf8')})).min(1).max(32),max_total_bytes:z.number().int().min(1).max(2097152).default(1048576)}),
|
|
16
|
+
z.strictObject({op:z.literal('symbol_outline'),root_id:id,path:rel512,max_symbols:z.number().int().min(1).max(500).default(200)}),
|
|
17
|
+
z.strictObject({op:z.literal('symbol_definition'),root_id:id,path:rel512,line:nonneg,column:nonneg,max_results:z.number().int().min(1).max(200).default(50)}),
|
|
18
|
+
z.strictObject({op:z.literal('symbol_references'),root_id:id,path:rel512,line:nonneg,column:nonneg,max_results:z.number().int().min(1).max(500).default(200)}),
|
|
19
|
+
z.strictObject({op:z.literal('symbol_diagnostics'),root_id:id,path:rel512,max_results:z.number().int().min(1).max(500).default(200)}),
|
|
20
|
+
z.strictObject({op:z.literal('symbol_implementations'),root_id:id,path:rel512,line:nonneg,column:nonneg,max_results:z.number().int().min(1).max(500).default(200)}),
|
|
21
|
+
z.strictObject({op:z.literal('symbol_rename_preview'),root_id:id,path:rel512,line:nonneg,column:nonneg,new_name:symbolName})
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
export const machineFsGatewayInputSchema=z.discriminatedUnion('op',[
|
|
25
|
+
z.strictObject({op:z.literal('stat'),root_id:id,path:rel.default('.'),hash:z.boolean().default(false)}),
|
|
26
|
+
z.strictObject({op:z.literal('list'),root_id:id,path:rel.default('.'),cursor,limit:z.number().int().min(1).max(1000).default(100),hash_files:z.boolean().default(false)}),
|
|
27
|
+
z.strictObject({op:z.literal('read'),root_id:id,path:rel,offset:nonneg.default(0),max_bytes:z.number().int().min(1).max(4*1024*1024).default(65536),hash_file:z.boolean().default(false)}),
|
|
28
|
+
z.strictObject({op:z.literal('write'),root_id:id,path:rel,content:z.string().max(12*1024*1024),encoding:z.enum(['utf8','base64']).default('utf8'),expected_sha256:z.string().regex(/^(?:absent|[0-9a-f]{64})$/)}),
|
|
29
|
+
z.strictObject({op:z.literal('edit_exact'),root_id:id,path:rel,expected_sha256:hex64,old_string:z.string().min(1).max(262144),new_string:z.string().max(524288),expected_replacements:z.number().int().min(1).max(64).default(1)}),
|
|
30
|
+
z.strictObject({op:z.literal('mkdir'),root_id:id,path:rel}),
|
|
31
|
+
z.strictObject({op:z.literal('move'),root_id:id,source_path:rel,destination_path:rel,expected_source_identity:hex64}),
|
|
32
|
+
z.strictObject({op:z.literal('delete'),root_id:id,path:rel,expected_source_identity:hex64})
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
export const processSessionGatewayInputSchema=z.discriminatedUnion('op',[
|
|
36
|
+
z.strictObject({op:z.literal('start'),profile_id:id,root_id:id,cwd:rel.default('.'),args:z.array(z.string().max(8192)).max(64).default([])}),
|
|
37
|
+
z.strictObject({op:z.literal('read'),session_id:hex64,offset:nonneg.default(0),max_bytes:z.number().int().min(1).max(262144).default(65536)}),
|
|
38
|
+
z.strictObject({op:z.literal('status'),session_id:hex64}),
|
|
39
|
+
z.strictObject({op:z.literal('list')}),
|
|
40
|
+
z.strictObject({op:z.literal('action'),session_id:hex64,action_id:id}),
|
|
41
|
+
z.strictObject({op:z.literal('terminate'),session_id:hex64})
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
export const machineObserveInputSchema=z.discriminatedUnion('op',[
|
|
45
|
+
z.strictObject({op:z.literal('machine_list')}),
|
|
46
|
+
z.strictObject({op:z.literal('machine_status')}),
|
|
47
|
+
z.strictObject({op:z.literal('machine_ping'),nonce:z.string().min(1).max(256)}),
|
|
48
|
+
z.strictObject({op:z.literal('search_start'),root_id:id,path:rel512.default('.'),pattern:z.string().min(1).max(256),case_sensitive:z.boolean().default(false),max_results:z.number().int().min(1).max(1000).default(200),max_files:z.number().int().min(1).max(10000).default(2000),max_bytes:z.number().int().min(1).max(64*1024*1024).default(4*1024*1024),max_file_bytes:z.number().int().min(1).max(4*1024*1024).default(262144)}),
|
|
49
|
+
z.strictObject({op:z.literal('search_page'),search_id:hex64,limit:z.number().int().min(1).max(500).default(100),cursor:z.string().max(512).nullable().default(null)}),
|
|
50
|
+
z.strictObject({op:z.literal('search_status'),search_id:hex64}),
|
|
51
|
+
z.strictObject({op:z.literal('search_cancel'),search_id:hex64}),
|
|
52
|
+
z.strictObject({op:z.literal('process_list'),limit:z.number().int().min(1).max(256).default(100),include_external:z.boolean().default(false),cursor:z.string().max(512).nullable().default(null)}),
|
|
53
|
+
z.strictObject({op:z.literal('system_status')})
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
const capabilityManifestInputSchema=z.strictObject({});
|
|
57
|
+
|
|
58
|
+
function unavailable(op,name){return compactGatewayResult({status:'unavailable',op,error:`${name} runtime unavailable`},true);}
|
|
59
|
+
async function invoke(op,runtime,name,call){
|
|
60
|
+
if(!runtime) return unavailable(op,name);
|
|
61
|
+
try{return compactGatewayResult({status:'ok',op,result:await call(runtime)},false);}
|
|
62
|
+
catch(error){return compactGatewayResult({status:'denied',op,error:String(error)},true);}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function codingInspect(args,codingRuntime,semanticRuntime){
|
|
66
|
+
switch(args.op){
|
|
67
|
+
case 'stat': return invoke(args.op,codingRuntime,'coding',r=>r.stat({rootId:args.root_id,relativePath:args.path,hash:args.hash}));
|
|
68
|
+
case 'search': return invoke(args.op,codingRuntime,'coding',r=>r.search({rootId:args.root_id,path:args.path,pattern:args.pattern,target:args.target,mode:args.mode,caseSensitive:args.case_sensitive,maxResults:args.max_results,maxFileBytes:args.max_file_bytes,maxScanBytes:args.max_scan_bytes,pageSize:args.page_size,cursor:args.cursor}));
|
|
69
|
+
case 'files_read': return invoke(args.op,codingRuntime,'coding',r=>r.filesRead({rootId:args.root_id,files:args.files,maxTotalBytes:args.max_total_bytes}));
|
|
70
|
+
case 'symbol_outline': return invoke(args.op,semanticRuntime,'semantic',r=>r.outline({rootId:args.root_id,relativePath:args.path,maxSymbols:args.max_symbols}));
|
|
71
|
+
case 'symbol_definition': return invoke(args.op,semanticRuntime,'semantic',r=>r.definition({rootId:args.root_id,relativePath:args.path,line:args.line,column:args.column,maxResults:args.max_results}));
|
|
72
|
+
case 'symbol_references': return invoke(args.op,semanticRuntime,'semantic',r=>r.references({rootId:args.root_id,relativePath:args.path,line:args.line,column:args.column,maxResults:args.max_results}));
|
|
73
|
+
case 'symbol_diagnostics': return invoke(args.op,semanticRuntime,'semantic',r=>r.diagnostics({rootId:args.root_id,relativePath:args.path,maxResults:args.max_results}));
|
|
74
|
+
case 'symbol_implementations': return invoke(args.op,semanticRuntime,'semantic',r=>{if(typeof r.implementations!=='function') throw new Error('semantic implementations unavailable');return r.implementations({rootId:args.root_id,relativePath:args.path,line:args.line,column:args.column,maxResults:args.max_results});});
|
|
75
|
+
case 'symbol_rename_preview': return invoke(args.op,semanticRuntime,'semantic',r=>{if(typeof r.renamePreview!=='function') throw new Error('semantic rename preview unavailable');return r.renamePreview({rootId:args.root_id,relativePath:args.path,line:args.line,column:args.column,newName:args.new_name});});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function machineFs(args,runtime){
|
|
80
|
+
const map={
|
|
81
|
+
stat:r=>r.stat({rootId:args.root_id,relativePath:args.path,hash:args.hash}),
|
|
82
|
+
list:r=>r.list({rootId:args.root_id,relativePath:args.path,cursor:args.cursor,limit:args.limit,hashFiles:args.hash_files}),
|
|
83
|
+
read:r=>r.read({rootId:args.root_id,relativePath:args.path,offset:args.offset,maxBytes:args.max_bytes,hashFile:args.hash_file}),
|
|
84
|
+
write:r=>r.write({rootId:args.root_id,relativePath:args.path,content:args.content,encoding:args.encoding,expectedSha256:args.expected_sha256}),
|
|
85
|
+
edit_exact:r=>r.editExact({rootId:args.root_id,relativePath:args.path,expectedSha256:args.expected_sha256,oldString:args.old_string,newString:args.new_string,expectedReplacements:args.expected_replacements}),
|
|
86
|
+
mkdir:r=>r.mkdir({rootId:args.root_id,relativePath:args.path}),
|
|
87
|
+
move:r=>r.move({rootId:args.root_id,sourcePath:args.source_path,destinationPath:args.destination_path,expectedSourceIdentity:args.expected_source_identity}),
|
|
88
|
+
delete:r=>r.delete({rootId:args.root_id,relativePath:args.path,expectedSourceIdentity:args.expected_source_identity})
|
|
89
|
+
};
|
|
90
|
+
return invoke(args.op,runtime,'machine_fs',map[args.op]);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function processSession(args,runtime){
|
|
94
|
+
const map={
|
|
95
|
+
start:r=>r.start({profileId:args.profile_id,rootId:args.root_id,cwd:args.cwd,args:args.args}),
|
|
96
|
+
read:r=>r.read({sessionId:args.session_id,offset:args.offset,maxBytes:args.max_bytes}),
|
|
97
|
+
status:r=>r.status({sessionId:args.session_id}),
|
|
98
|
+
list:r=>r.list(),
|
|
99
|
+
action:r=>r.action({sessionId:args.session_id,actionId:args.action_id}),
|
|
100
|
+
terminate:r=>r.terminate({sessionId:args.session_id})
|
|
101
|
+
};
|
|
102
|
+
return invoke(args.op,runtime,'process',map[args.op]);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function machineObserve(args,machineRuntime,observationRuntime){
|
|
106
|
+
if(args.op==='machine_list') return invoke(args.op,machineRuntime,'machine',r=>r.list());
|
|
107
|
+
if(args.op==='machine_status') return invoke(args.op,machineRuntime,'machine',r=>r.status());
|
|
108
|
+
if(args.op==='machine_ping') return invoke(args.op,machineRuntime,'machine',r=>r.ping({nonce:args.nonce}));
|
|
109
|
+
const map={
|
|
110
|
+
search_start:r=>r.searchStart({rootId:args.root_id,relativePath:args.path,pattern:args.pattern,caseSensitive:args.case_sensitive,maxResults:args.max_results,maxFiles:args.max_files,maxBytes:args.max_bytes,maxFileBytes:args.max_file_bytes}),
|
|
111
|
+
search_page:r=>r.searchPage({searchId:args.search_id,limit:args.limit,cursor:args.cursor}),
|
|
112
|
+
search_status:r=>r.searchStatus({searchId:args.search_id}),
|
|
113
|
+
search_cancel:r=>r.searchCancel({searchId:args.search_id}),
|
|
114
|
+
process_list:r=>r.processList({limit:args.limit,includeExternal:args.include_external,cursor:args.cursor}),
|
|
115
|
+
system_status:r=>r.systemStatus()
|
|
116
|
+
};
|
|
117
|
+
return invoke(args.op,observationRuntime,'observation',map[args.op]);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function registerCompactGatewayTools(server,{profile,ledger,codingRuntime,semanticRuntime,machineFsRuntime,processRuntime,observationRuntime,machineRuntime}){
|
|
121
|
+
if(!server) throw new Error('compact gateway registration requires server');
|
|
122
|
+
if(profile!=='compact') return;
|
|
123
|
+
server.registerTool('capability_manifest',{description:'Read the canonical R36 capability ledger and active compact profile.',inputSchema:capabilityManifestInputSchema,outputSchema:compactGatewayOutputSchema},async()=>compactGatewayResult({status:'ok',op:'manifest',result:{schema:'deadbyte.capability-manifest.v1',profile,ledger_sha256:ledger?.ledger_sha256??null,capabilities:ledger?.entries??[]}},false));
|
|
124
|
+
server.registerTool('coding_inspect',{description:'Typed compact coding inspection and semantic navigation gateway. No arbitrary tool dispatch.',inputSchema:codingInspectInputSchema,outputSchema:compactGatewayOutputSchema},args=>codingInspect(args,codingRuntime,semanticRuntime));
|
|
125
|
+
server.registerTool('machine_fs',{description:'Typed compact machine filesystem gateway preserving root policy and mutation preconditions.',inputSchema:machineFsGatewayInputSchema,outputSchema:compactGatewayOutputSchema},args=>machineFs(args,machineFsRuntime));
|
|
126
|
+
server.registerTool('process_session',{description:'Typed compact DEADBYTE-owned process session gateway. No raw stdin or PID authority.',inputSchema:processSessionGatewayInputSchema,outputSchema:compactGatewayOutputSchema},args=>processSession(args,processRuntime));
|
|
127
|
+
server.registerTool('machine_observe',{description:'Typed compact machine identity and read-only observation gateway. Revoke is intentionally excluded.',inputSchema:machineObserveInputSchema,outputSchema:compactGatewayOutputSchema},args=>machineObserve(args,machineRuntime,observationRuntime));
|
|
128
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as z from 'zod/v4';
|
|
2
|
+
import { structuredToolResult } from './output-contracts.mjs';
|
|
3
|
+
|
|
4
|
+
export const compactGatewayOutputSchema=z.strictObject({
|
|
5
|
+
status:z.enum(['ok','denied','failed','unavailable']),
|
|
6
|
+
op:z.string().min(1).max(64),
|
|
7
|
+
result:z.json().optional(),
|
|
8
|
+
error:z.string().max(4096).optional()
|
|
9
|
+
}).superRefine((value,ctx)=>{
|
|
10
|
+
if(value.status==='ok'&&value.result===undefined) ctx.addIssue({code:'custom',path:['result'],message:'result is required for status=ok'});
|
|
11
|
+
if(value.status!=='ok'&&value.error===undefined) ctx.addIssue({code:'custom',path:['error'],message:'error is required for non-ok status'});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export function compactGatewayResult(value,isError=false){
|
|
15
|
+
return structuredToolResult(compactGatewayOutputSchema,value,isError);
|
|
16
|
+
}
|
package/src/deadbyte-cli.mjs
CHANGED
|
@@ -9,18 +9,19 @@ import { fileURLToPath } from 'node:url';
|
|
|
9
9
|
import { defaultPublicKeyPath } from './trust.mjs';
|
|
10
10
|
import { verifyAuditChain } from './audit-verify.mjs';
|
|
11
11
|
import { openRemoteResultJournal, parseRemoteResultCursor } from './remote-result-journal.mjs';
|
|
12
|
+
import { createLiveActivityTracker, formatCompactAuditEvent, formatRemoteLifecycle } from './remote-live-log.mjs';
|
|
12
13
|
|
|
13
14
|
const REMOTE_COMMANDS=new Set([
|
|
14
15
|
'menu','start','resume','park','stop','restart','status','url','test','fulltest','toggle','clean','machinetest',
|
|
15
16
|
'armprocess','disarmprocess','processstatus','armhost','disarmhost','hoststatus','hosttest',
|
|
16
17
|
'armcoding','disarmcoding','codingstatus','codingtest','armautonomous','disarmautonomous','autonomousstatus','autonomoustest'
|
|
17
18
|
]);
|
|
18
|
-
const SESSION_START=['start','armprocess','armcoding','armautonomous'
|
|
19
|
+
const SESSION_START=['start','armprocess','armcoding','armautonomous'];
|
|
19
20
|
const SESSION_STATUS=[
|
|
20
21
|
['processstatus',/^Process plane\s*:\s*ARMED\b/m],
|
|
21
22
|
['codingstatus',/^Coding plane\s*:\s*ARMED\b/m],
|
|
22
23
|
['autonomousstatus',/^Autonomous\s*:\s*ARMED\b/m],
|
|
23
|
-
['hoststatus',/^Host plane\s*:\s*
|
|
24
|
+
['hoststatus',/^Host plane\s*:\s*DISARMED\b/m]
|
|
24
25
|
];
|
|
25
26
|
const SESSION_CLEANUP=['disarmautonomous','disarmcoding','disarmprocess','disarmhost','park'];
|
|
26
27
|
const SUPERVISOR_COMMANDS=Object.freeze({
|
|
@@ -77,16 +78,12 @@ async function listLogFiles(root){
|
|
|
77
78
|
}
|
|
78
79
|
return files;
|
|
79
80
|
}
|
|
80
|
-
function formatLogLine(file,line,{verbose=false}={}){
|
|
81
|
+
function formatLogLine(file,line,{verbose=false,activityTracker=null}={}){
|
|
81
82
|
if(!line) return null;
|
|
82
83
|
if(/^segment-\d{8}\.jsonl$/.test(path.basename(file))){
|
|
83
84
|
try{
|
|
84
85
|
const event=JSON.parse(line);
|
|
85
|
-
if(!verbose)
|
|
86
|
-
if(event.event_type!=='tool.result') return null;
|
|
87
|
-
const tool=typeof event.tool==='string'&&event.tool?event.tool:'tool';
|
|
88
|
-
return `${event.outcome?.is_error===true?'[ERR]':'[OK]'} ${tool}`;
|
|
89
|
-
}
|
|
86
|
+
if(!verbose) return activityTracker?activityTracker.observe(event):formatCompactAuditEvent(event);
|
|
90
87
|
const seq=Number.isInteger(event.seq)?`#${event.seq}`:'#?';
|
|
91
88
|
const request=typeof event.request_id==='string'?` ${event.request_id.slice(0,8)}`:'';
|
|
92
89
|
const tool=typeof event.tool==='string'?` ${event.tool}`:'';
|
|
@@ -147,25 +144,29 @@ async function readAppend(file,offset){
|
|
|
147
144
|
try{await handle.read(buffer,0,length,start);}finally{await handle.close();}
|
|
148
145
|
return {offset:info.size,text:buffer.toString('utf8')};
|
|
149
146
|
}
|
|
150
|
-
async function
|
|
147
|
+
async function snapshotRemoteLogOffsets(root){
|
|
151
148
|
const offsets=new Map();
|
|
152
149
|
for(const file of await listLogFiles(root)){
|
|
153
150
|
try{offsets.set(file,(await stat(file)).size);}catch{}
|
|
154
151
|
}
|
|
152
|
+
return offsets;
|
|
153
|
+
}
|
|
154
|
+
async function tailRemoteLogs(root,signal,{verbose=false,journal=null,offsets=null,activityTracker=null}={}){
|
|
155
155
|
process.stdout.write(verbose
|
|
156
156
|
?'📜 [LOG] Live logs active. Press Ctrl+C to disconnect and revoke authority.\n'
|
|
157
|
-
:'[LOG] Live
|
|
157
|
+
:'[LOG] Live activity. Ctrl+C disconnects and revokes authority.\n');
|
|
158
|
+
const activeOffsets=offsets??await snapshotRemoteLogOffsets(root);
|
|
158
159
|
while(!signal.aborted){
|
|
159
160
|
for(const file of await listLogFiles(root)){
|
|
160
|
-
const prior=
|
|
161
|
+
const prior=activeOffsets.has(file)?activeOffsets.get(file):0;
|
|
161
162
|
const next=await readAppend(file,prior);
|
|
162
|
-
|
|
163
|
+
activeOffsets.set(file,next.offset);
|
|
163
164
|
for(const line of next.text.split(/\r?\n/)){
|
|
164
165
|
const terminal=auditTerminalResult(file,line);
|
|
165
166
|
let recorded=null;
|
|
166
167
|
if(terminal&&journal) recorded=await journal.recordTerminal(terminal);
|
|
167
168
|
if(recorded?.duplicate&&!verbose) continue;
|
|
168
|
-
const formatted=formatLogLine(file,line,{verbose});
|
|
169
|
+
const formatted=formatLogLine(file,line,{verbose,activityTracker});
|
|
169
170
|
if(!formatted) continue;
|
|
170
171
|
if(!verbose&&recorded) process.stdout.write(`${formatted} [cursor ${recorded.cursor}]\n`);
|
|
171
172
|
else process.stdout.write(`${formatted}\n`);
|
|
@@ -266,39 +267,61 @@ async function runRemoteSession({verbose=false,resumeCursor=null}={}){
|
|
|
266
267
|
const resultJournal=await openRemoteResultJournal({
|
|
267
268
|
filePath:remoteResultJournalPath(ctx.root,marker.result_session_id),sessionId:marker.result_session_id,maxEntries:2048
|
|
268
269
|
});
|
|
270
|
+
const activityTracker=createLiveActivityTracker();
|
|
269
271
|
const aborter=new AbortController();
|
|
270
272
|
const abort=()=>aborter.abort();
|
|
271
273
|
const watchStdin=!process.stdin.isTTY;
|
|
272
274
|
process.once('SIGINT',abort);process.once('SIGTERM',abort);
|
|
273
275
|
if(watchStdin){process.stdin.once('end',abort);process.stdin.once('close',abort);process.stdin.resume();}
|
|
274
276
|
let ready=false;
|
|
277
|
+
let logTask=null;
|
|
275
278
|
try{
|
|
276
|
-
if(verbose)
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
279
|
+
if(verbose) process.stdout.write('DEADBYTE MCP DEVICE SESSION\n');
|
|
280
|
+
else process.stdout.write('DEADBYTE MCP\n');
|
|
281
|
+
process.stdout.write(`${formatRemoteLifecycle('device_start')}\n`);
|
|
282
|
+
process.stdout.write(`${formatRemoteLifecycle(resumeCursor!==null?'session_restored':'session_new')}\n`);
|
|
283
|
+
const logOffsets=await snapshotRemoteLogOffsets(ctx.root);
|
|
284
|
+
logTask=tailRemoteLogs(ctx.root,aborter.signal,{verbose,journal:resultJournal,offsets:logOffsets,activityTracker});
|
|
285
|
+
if(verbose) process.stdout.write('[INFO] Starting local + remote runtime...\n');
|
|
286
|
+
else process.stdout.write('[BOOT] Starting local + remote runtime...\n');
|
|
287
|
+
const started=[];
|
|
288
|
+
for(const command of SESSION_START){
|
|
289
|
+
if(!verbose){
|
|
290
|
+
if(command==='start') process.stdout.write('[BOOT] Starting bridge/runtime...\n');
|
|
291
|
+
else process.stdout.write(`🔐 [AUTH] Arming ${command.slice(3)}...\n`);
|
|
292
|
+
}
|
|
293
|
+
const controllerResult=invokeController(ctx,command,verbose?{}:{capture:true,echoCaptured:false});
|
|
294
|
+
started.push(controllerResult);
|
|
295
|
+
if(command==='start'){
|
|
296
|
+
process.stdout.write(`${formatRemoteLifecycle('bridge_connected')}\n`);
|
|
297
|
+
process.stdout.write(`${formatRemoteLifecycle('cloud_connected')}\n`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if(!verbose){
|
|
285
301
|
const startText=started[0]?.stdout||'';
|
|
286
302
|
const url=startText.match(/^URL\s*:\s*(\S+)/m)?.[1]||'';
|
|
287
303
|
process.stdout.write('[OK] ONLINE\n');
|
|
304
|
+
process.stdout.write(`${formatRemoteLifecycle('ready')}\n`);
|
|
288
305
|
if(url) process.stdout.write(`URL: ${url}\n`);
|
|
289
|
-
|
|
306
|
+
process.stdout.write('🔐 [AUTH] Verifying process, coding, autonomous; host must stay DISARMED...\n');
|
|
307
|
+
}else process.stdout.write('🛡️ [AUTHORITY] Verifying runtime planes; host must stay DISARMED...\n');
|
|
290
308
|
for(const [command,pattern] of SESSION_STATUS){
|
|
291
309
|
const result=invokeController(ctx,command,{capture:true,echoCaptured:verbose});
|
|
292
|
-
if(!pattern.test(result.stdout)) throw new Error(`remote session authority verification failed: ${command}
|
|
310
|
+
if(!pattern.test(result.stdout)) throw new Error(`remote session authority verification failed: ${command} state mismatch`);
|
|
293
311
|
}
|
|
294
312
|
ready=true;
|
|
295
|
-
if(verbose) process.stdout.write('[DEVICE] DEADBYTE MCP online;
|
|
296
|
-
else process.stdout.write('[
|
|
297
|
-
await
|
|
313
|
+
if(verbose) process.stdout.write('[DEVICE] DEADBYTE MCP online; process/coding/autonomous ARMED; host DISARMED.\n');
|
|
314
|
+
else process.stdout.write('🔐 [AUTH] ARMED: process, coding, autonomous | host DISARMED\n');
|
|
315
|
+
await logTask;
|
|
298
316
|
}finally{
|
|
317
|
+
const wasAborted=aborter.signal.aborted;
|
|
318
|
+
aborter.abort();
|
|
319
|
+
if(logTask) await logTask.catch(()=>{});
|
|
320
|
+
if(!verbose){for(const line of activityTracker.reconcileInterrupted('session_end')) process.stdout.write(`${line}\n`);}
|
|
299
321
|
process.removeListener('SIGINT',abort);process.removeListener('SIGTERM',abort);
|
|
300
322
|
if(watchStdin){process.stdin.removeListener('end',abort);process.stdin.removeListener('close',abort);process.stdin.pause();}
|
|
301
|
-
|
|
323
|
+
process.stdout.write(`${formatRemoteLifecycle('cleanup')}\n`);
|
|
324
|
+
if(ready||!wasAborted) process.stdout.write(verbose?'[INFO] Closing remote device session and revoking authority...\n':'[INFO] Disconnecting; revoking authority...\n');
|
|
302
325
|
await cleanupRemoteSession(ctx,{verbose});
|
|
303
326
|
await releaseRemoteSession(ctx,marker);
|
|
304
327
|
}
|
|
@@ -60,7 +60,7 @@ const baseTools = ['contained_transform','evidence_verify','file_read','proof_ex
|
|
|
60
60
|
const codingTools = [
|
|
61
61
|
'coding_benchmark_run','coding_command_run','coding_file_read','coding_file_write','coding_files_read',
|
|
62
62
|
'coding_receipt_verify','coding_search','coding_session_status','coding_stat',
|
|
63
|
-
'coding_symbol_definition','coding_symbol_outline','coding_symbol_references','coding_symbol_replace',
|
|
63
|
+
'coding_symbol_definition','coding_symbol_diagnostics','coding_symbol_implementations','coding_symbol_outline','coding_symbol_references','coding_symbol_rename_preview','coding_symbol_replace',
|
|
64
64
|
'coding_task_approve','coding_task_cancel','coding_task_events','coding_task_run',
|
|
65
65
|
'coding_task_status','coding_task_submit','coding_task_verify','coding_text_replace','coding_tree'
|
|
66
66
|
];
|
package/src/machine-fs.mjs
CHANGED
|
@@ -168,9 +168,10 @@ function decodeCursor(cursor) {
|
|
|
168
168
|
|
|
169
169
|
function encodeCursor(name) { return Buffer.from(name, 'utf8').toString('base64url'); }
|
|
170
170
|
|
|
171
|
-
async function signReceipt(policy, signingKeyPath, grant, operation, requestSha256, body) {
|
|
171
|
+
async function signReceipt(policy, signingKeyPath, grant, operation, requestSha256, body, requestedReceiptId = null) {
|
|
172
172
|
await fsMkdir(path.join(policy.evidence_dir, 'machine-fs'), { recursive: true });
|
|
173
|
-
const receiptId = randomBytes(12).toString('hex');
|
|
173
|
+
const receiptId = requestedReceiptId ?? randomBytes(12).toString('hex');
|
|
174
|
+
if (!RECEIPT_ID_RE.test(receiptId)) throw new Error('machine fs receipt id must be 24 lowercase hex characters');
|
|
174
175
|
const core = {
|
|
175
176
|
schema: MACHINE_FS_RECEIPT_SCHEMA, receipt_id: receiptId,
|
|
176
177
|
policy_sha256: policy.policy_sha256, grant_instance_nonce: grant.instance_nonce,
|
|
@@ -311,7 +312,7 @@ export function createMachineFsRuntime({ policy, signingKeyPath, verifyKeyPath }
|
|
|
311
312
|
};
|
|
312
313
|
}
|
|
313
314
|
|
|
314
|
-
async function writePath({ rootId, relativePath, content, encoding = 'utf8', expectedSha256 }) {
|
|
315
|
+
async function writePath({ rootId, relativePath, content, encoding = 'utf8', expectedSha256, receiptId = null }) {
|
|
315
316
|
const grant = await assertCodingArmed(policy, rootId);
|
|
316
317
|
const target = await resolveTarget(policy, grant, rootId, relativePath, 'write');
|
|
317
318
|
const bytes = decodeContent(content, encoding);
|
|
@@ -325,7 +326,7 @@ export function createMachineFsRuntime({ policy, signingKeyPath, verifyKeyPath }
|
|
|
325
326
|
const signed = await signReceipt(policy, signingKeyPath, grant, 'machine_fs_write', request, {
|
|
326
327
|
root_id: rootId, path: target.relative, started_at_utc: started, completed_at_utc: nowUtc(),
|
|
327
328
|
before_sha256: before.sha256, after_sha256: after.sha256, bytes: after.bytes
|
|
328
|
-
});
|
|
329
|
+
}, receiptId);
|
|
329
330
|
return {
|
|
330
331
|
status: 'committed', root_id: rootId, path: target.relative,
|
|
331
332
|
previous_sha256: before.sha256, sha256: after.sha256, bytes: after.bytes,
|
|
@@ -368,7 +369,7 @@ export function createMachineFsRuntime({ policy, signingKeyPath, verifyKeyPath }
|
|
|
368
369
|
receipt_id: signed.receipt.receipt_id, receipt_sha256: signed.receipt.receipt_sha256, request_sha256: request
|
|
369
370
|
};
|
|
370
371
|
}
|
|
371
|
-
async function mkdirPath({ rootId, relativePath }) {
|
|
372
|
+
async function mkdirPath({ rootId, relativePath, receiptId = null }) {
|
|
372
373
|
const grant = await assertCodingArmed(policy, rootId);
|
|
373
374
|
const target = await resolveTarget(policy, grant, rootId, relativePath, 'write');
|
|
374
375
|
try { await lstat(target.lexical); throw new Error('machine fs mkdir precondition mismatch: expected absent'); }
|
|
@@ -382,7 +383,7 @@ export function createMachineFsRuntime({ policy, signingKeyPath, verifyKeyPath }
|
|
|
382
383
|
const signed = await signReceipt(policy, signingKeyPath, grant, 'machine_fs_mkdir', request, {
|
|
383
384
|
root_id: rootId, path: target.relative, started_at_utc: started, completed_at_utc: nowUtc(),
|
|
384
385
|
before_identity_sha256: null, after_identity_sha256: identity.identity_sha256
|
|
385
|
-
});
|
|
386
|
+
}, receiptId);
|
|
386
387
|
return {
|
|
387
388
|
status: 'committed', root_id: rootId, path: target.relative, identity_sha256: identity.identity_sha256,
|
|
388
389
|
receipt_id: signed.receipt.receipt_id, receipt_sha256: signed.receipt.receipt_sha256, request_sha256: request
|
|
@@ -392,7 +393,7 @@ export function createMachineFsRuntime({ policy, signingKeyPath, verifyKeyPath }
|
|
|
392
393
|
throw error;
|
|
393
394
|
}
|
|
394
395
|
}
|
|
395
|
-
async function movePath({ rootId, sourcePath, destinationPath, expectedSourceIdentity }) {
|
|
396
|
+
async function movePath({ rootId, sourcePath, destinationPath, expectedSourceIdentity, receiptId = null }) {
|
|
396
397
|
if (!SHA256_RE.test(expectedSourceIdentity ?? '')) throw new Error('machine fs expected_source_identity must be lowercase SHA-256');
|
|
397
398
|
const grant = await assertCodingArmed(policy, rootId);
|
|
398
399
|
const source = await resolveExisting(policy, grant, rootId, sourcePath, 'write', false);
|
|
@@ -415,7 +416,7 @@ export function createMachineFsRuntime({ policy, signingKeyPath, verifyKeyPath }
|
|
|
415
416
|
const signed = await signReceipt(policy, signingKeyPath, grant, 'machine_fs_move', request, {
|
|
416
417
|
root_id: rootId, source_path: source.relative, destination_path: destination.relative,
|
|
417
418
|
started_at_utc: started, completed_at_utc: nowUtc(), source_identity_sha256: expectedSourceIdentity
|
|
418
|
-
});
|
|
419
|
+
}, receiptId);
|
|
419
420
|
return {
|
|
420
421
|
status: 'committed', root_id: rootId, source_path: source.relative, destination_path: destination.relative,
|
|
421
422
|
identity_sha256: expectedSourceIdentity, receipt_id: signed.receipt.receipt_id,
|
|
@@ -460,6 +461,46 @@ export function createMachineFsRuntime({ policy, signingKeyPath, verifyKeyPath }
|
|
|
460
461
|
}
|
|
461
462
|
}
|
|
462
463
|
|
|
464
|
+
async function statePath({ rootId, relativePath }) {
|
|
465
|
+
try {
|
|
466
|
+
const value = await statPath({ rootId, relativePath, hash: true });
|
|
467
|
+
return { exists: true, root_id: rootId, path: value.path, kind: value.kind, bytes: value.bytes,
|
|
468
|
+
sha256: value.sha256, identity_sha256: value.identity_sha256 };
|
|
469
|
+
} catch (error) {
|
|
470
|
+
if (error?.code === 'ENOENT') return { exists: false, root_id: rootId, path: relativePath, kind: null, bytes: 0, sha256: null, identity_sha256: null };
|
|
471
|
+
throw error;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
async function removeEmptyDir({ rootId, relativePath, expectedSourceIdentity, receiptId = null }) {
|
|
476
|
+
if (!SHA256_RE.test(expectedSourceIdentity ?? '')) throw new Error('machine fs expected_source_identity must be lowercase SHA-256');
|
|
477
|
+
const grant = await assertCodingArmed(policy, rootId);
|
|
478
|
+
const source = await resolveExisting(policy, grant, rootId, relativePath, 'write', false);
|
|
479
|
+
const before = await objectIdentity(source.resolved);
|
|
480
|
+
if (before.kind !== 'directory' || before.entries.length !== 0) throw new Error('machine fs rmdir requires an empty directory');
|
|
481
|
+
if (before.identity_sha256 !== expectedSourceIdentity) throw new Error(`machine fs source identity mismatch: expected ${expectedSourceIdentity}, found ${before.identity_sha256}`);
|
|
482
|
+
const request = requestSha('machine_fs_rmdir_empty', { root_id: rootId, path: source.relative, expected_source_identity: expectedSourceIdentity });
|
|
483
|
+
const started = nowUtc();
|
|
484
|
+
const race = await objectIdentity(source.resolved);
|
|
485
|
+
if (race.kind !== 'directory' || race.entries.length !== 0 || race.identity_sha256 !== expectedSourceIdentity) {
|
|
486
|
+
throw new Error('machine fs rmdir precondition changed before commit');
|
|
487
|
+
}
|
|
488
|
+
await rmdir(source.lexical);
|
|
489
|
+
try {
|
|
490
|
+
try { await lstat(source.lexical); throw new Error('machine fs rmdir post-commit path still exists'); }
|
|
491
|
+
catch (error) { if (error?.code !== 'ENOENT') throw error; }
|
|
492
|
+
const signed = await signReceipt(policy, signingKeyPath, grant, 'machine_fs_rmdir_empty', request, {
|
|
493
|
+
root_id: rootId, path: source.relative, started_at_utc: started, completed_at_utc: nowUtc(),
|
|
494
|
+
before_identity_sha256: expectedSourceIdentity, after_identity_sha256: null
|
|
495
|
+
}, receiptId);
|
|
496
|
+
return { status: 'committed', root_id: rootId, path: source.relative, identity_sha256: expectedSourceIdentity,
|
|
497
|
+
receipt_id: signed.receipt.receipt_id, receipt_sha256: signed.receipt.receipt_sha256, request_sha256: request };
|
|
498
|
+
} catch (error) {
|
|
499
|
+
await fsMkdir(source.lexical, { recursive: false }).catch(() => {});
|
|
500
|
+
throw error;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
463
504
|
return Object.freeze({
|
|
464
505
|
policy,
|
|
465
506
|
stat: statPath,
|
|
@@ -470,6 +511,8 @@ export function createMachineFsRuntime({ policy, signingKeyPath, verifyKeyPath }
|
|
|
470
511
|
move: movePath,
|
|
471
512
|
mkdir: mkdirPath,
|
|
472
513
|
delete: deletePath,
|
|
514
|
+
state: statePath,
|
|
515
|
+
removeEmptyDir,
|
|
473
516
|
verifyReceipt: receiptId => verifyMachineFsReceiptFile({ policy, verifyKeyPath, receiptId })
|
|
474
517
|
});
|
|
475
518
|
}
|
package/src/mcp-server.mjs
CHANGED
|
@@ -39,6 +39,8 @@ import { registerAutonomousTools } from './autonomous-mcp-tools.mjs';
|
|
|
39
39
|
import { createToolAudit, installToolAudit } from './tool-audit.mjs';
|
|
40
40
|
import { createAuditContextProvider } from './audit-context.mjs';
|
|
41
41
|
import { registerOperatorSurface } from './operator-surface.mjs';
|
|
42
|
+
import { capabilityProfileFromEnv, COMPACT_SURFACE_TOOL_LIMIT, R36_CAPABILITY_LEDGER } from './capability-ledger.mjs';
|
|
43
|
+
import { registerCompactGatewayTools } from './compact-gateway-mcp-tools.mjs';
|
|
42
44
|
import {
|
|
43
45
|
containedTransformOutputSchema,
|
|
44
46
|
evidenceVerifyOutputSchema,
|
|
@@ -58,6 +60,7 @@ const verifyKeyPath = process.env.DEADBYTE_VERIFY_KEY ?? defaultPublicKeyPath();
|
|
|
58
60
|
const auditRuntimeMode = process.env.DEADBYTE_AUDIT_RUNTIME ?? '0';
|
|
59
61
|
if (!['0','1'].includes(auditRuntimeMode)) throw new Error('DEADBYTE_AUDIT_RUNTIME must be 0 or 1');
|
|
60
62
|
const runtimeStateRoot = path.resolve(process.env.DEADBYTE_STATE_ROOT || path.join(os.homedir(),'.deadbyte-mcp'));
|
|
63
|
+
const surfaceProfile = capabilityProfileFromEnv(process.env);
|
|
61
64
|
const localPrivilegedPolicyPath = path.join(packageRoot, 'controller', 'deadbyte-host-policy.json');
|
|
62
65
|
let privilegedPolicyPath = process.env.DEADBYTE_PRIVILEGED_POLICY ?? '';
|
|
63
66
|
if (!privilegedPolicyPath) {
|
|
@@ -106,7 +109,7 @@ const semanticLspBinding = semanticConfigBindingFromEnv(process.env);
|
|
|
106
109
|
const semanticLsp = codingRuntime && semanticLspBinding
|
|
107
110
|
? await loadSemanticLspBackends({ ...semanticLspBinding, codingRuntime })
|
|
108
111
|
: { backends: [], required_ids: [] };
|
|
109
|
-
|
|
112
|
+
let semanticRuntime = null;
|
|
110
113
|
const machineFsRuntimeMode = process.env.DEADBYTE_MACHINE_FS_RUNTIME ?? '0';
|
|
111
114
|
if (!['0','1'].includes(machineFsRuntimeMode)) throw new Error('DEADBYTE_MACHINE_FS_RUNTIME must be 0 or 1');
|
|
112
115
|
if (machineFsRuntimeMode === '1' && !codingPolicy) throw new Error('DEADBYTE_MACHINE_FS_RUNTIME=1 requires DEADBYTE_CODING_RUNTIME=1');
|
|
@@ -137,9 +140,10 @@ if (autonomousRuntimeMode === '1' && !autonomousPolicyPath) {
|
|
|
137
140
|
}
|
|
138
141
|
if (autonomousRuntimeMode === '1' && !autonomousPolicyPath) throw new Error('DEADBYTE_AUTONOMOUS_RUNTIME=1 requires an autonomous policy');
|
|
139
142
|
const autonomousPolicy = autonomousRuntimeMode === '1' ? await loadAutonomousPolicy(autonomousPolicyPath,codingPolicy) : null;
|
|
140
|
-
const nativeDiffRuntime = autonomousPolicy ? createNativeDiffRuntime({ policy:autonomousPolicy,codingRuntime,signingKeyPath,verifyKeyPath }) : null;
|
|
143
|
+
const nativeDiffRuntime = autonomousPolicy ? createNativeDiffRuntime({ policy:autonomousPolicy,codingRuntime,machineFsRuntime,signingKeyPath,verifyKeyPath }) : null;
|
|
144
|
+
semanticRuntime = codingRuntime ? createSemanticCodeRuntime({ codingRuntime, backends: semanticLsp.backends, nativeDiffRuntime }) : null;
|
|
141
145
|
const autonomousRuntime = autonomousPolicy ? createAutonomousRuntime({ policy:autonomousPolicy,codingRuntime,nativeDiffRuntime,
|
|
142
|
-
machineFsRuntime,observationRuntime,processRuntime,signingKeyPath,verifyKeyPath }) : null;
|
|
146
|
+
machineFsRuntime,observationRuntime,processRuntime,semanticRuntime,signingKeyPath,verifyKeyPath }) : null;
|
|
143
147
|
const autonomousSupervisor = autonomousRuntime && autonomousPolicy.planner.backend === 'openai_compatible' &&
|
|
144
148
|
autonomousSupervisorMode === 'in_process'
|
|
145
149
|
? startAutonomousSupervisor({ runtime: autonomousRuntime, policy: autonomousPolicy })
|
|
@@ -169,11 +173,22 @@ function textResult(schema, object, isError = false) {
|
|
|
169
173
|
return structuredToolResult(schema, object, isError);
|
|
170
174
|
}
|
|
171
175
|
|
|
176
|
+
const COMPACT_CODING_DIRECT_TOOLS=new Set([
|
|
177
|
+
'coding_session_status','coding_tree','coding_symbol_replace','coding_file_read','coding_file_write',
|
|
178
|
+
'coding_text_replace','coding_command_run','coding_benchmark_run','coding_receipt_verify',
|
|
179
|
+
'coding_task_submit','coding_task_run','coding_task_status','coding_task_events','coding_task_cancel',
|
|
180
|
+
'coding_task_approve','coding_task_verify'
|
|
181
|
+
]);
|
|
182
|
+
function filteredToolServer(server,allowed){
|
|
183
|
+
return {registerTool(name,...args){if(allowed.has(name)) return server.registerTool(name,...args);}};
|
|
184
|
+
}
|
|
185
|
+
|
|
172
186
|
serveStdio(() => {
|
|
173
187
|
const server = new McpServer({ name: 'deadbyte-mcp', version: DEADBYTE_VERSION });
|
|
174
|
-
registerOperatorSurface(server,{packageRoot});
|
|
188
|
+
registerOperatorSurface(server,{packageRoot,surfaceProfile,compactToolLimit:COMPACT_SURFACE_TOOL_LIMIT});
|
|
175
189
|
if (toolAudit) installToolAudit(server,toolAudit);
|
|
176
190
|
|
|
191
|
+
if (surfaceProfile === 'full') {
|
|
177
192
|
server.registerTool(
|
|
178
193
|
'workspace_open',
|
|
179
194
|
{
|
|
@@ -289,6 +304,8 @@ serveStdio(() => {
|
|
|
289
304
|
}
|
|
290
305
|
);
|
|
291
306
|
|
|
307
|
+
}
|
|
308
|
+
|
|
292
309
|
server.registerTool(
|
|
293
310
|
'evidence_verify',
|
|
294
311
|
{
|
|
@@ -319,23 +336,24 @@ serveStdio(() => {
|
|
|
319
336
|
});
|
|
320
337
|
}
|
|
321
338
|
|
|
322
|
-
if (agentRuntime) {
|
|
339
|
+
if (agentRuntime && surfaceProfile === 'full') {
|
|
323
340
|
registerAgentTools(server, { runtime: agentRuntime, workspacePathFromId });
|
|
324
341
|
}
|
|
325
342
|
|
|
326
|
-
if (processRuntime) {
|
|
343
|
+
if (processRuntime && surfaceProfile === 'full') {
|
|
327
344
|
registerProcessTools(server, { runtime: processRuntime });
|
|
328
345
|
}
|
|
329
346
|
|
|
330
347
|
if (codingRuntime && codingTaskRuntime && semanticRuntime) {
|
|
331
|
-
|
|
348
|
+
const codingServer=surfaceProfile==='full'?server:filteredToolServer(server,COMPACT_CODING_DIRECT_TOOLS);
|
|
349
|
+
registerCodingTools(codingServer, { codingRuntime, taskRuntime: codingTaskRuntime, semanticRuntime });
|
|
332
350
|
}
|
|
333
351
|
|
|
334
|
-
if (machineFsRuntime) {
|
|
352
|
+
if (machineFsRuntime && surfaceProfile === 'full') {
|
|
335
353
|
registerMachineFsTools(server, { runtime: machineFsRuntime });
|
|
336
354
|
}
|
|
337
355
|
|
|
338
|
-
if (observationRuntime) {
|
|
356
|
+
if (observationRuntime && surfaceProfile === 'full') {
|
|
339
357
|
registerObservationTools(server, { runtime: observationRuntime });
|
|
340
358
|
}
|
|
341
359
|
|
|
@@ -343,6 +361,11 @@ serveStdio(() => {
|
|
|
343
361
|
registerAutonomousTools(server, { autonomousRuntime, nativeDiffRuntime });
|
|
344
362
|
}
|
|
345
363
|
|
|
364
|
+
registerCompactGatewayTools(server,{
|
|
365
|
+
profile:surfaceProfile,ledger:R36_CAPABILITY_LEDGER,codingRuntime,semanticRuntime,machineFsRuntime,
|
|
366
|
+
processRuntime,observationRuntime,machineRuntime
|
|
367
|
+
});
|
|
368
|
+
|
|
346
369
|
if (hostPolicy) {
|
|
347
370
|
server.registerTool(
|
|
348
371
|
'host_file_read',
|