newmark-agent 0.4.4 → 0.4.6
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/dist/cli-commands.d.ts +1 -1
- package/dist/cli-commands.js +89 -7
- package/dist/cli-discovery.js +8 -0
- package/dist/conversation-utility-host.bundle.cjs +860 -688
- package/dist/core/agent.d.ts +19 -0
- package/dist/core/agent.js +72 -8
- package/dist/core/config.js +3 -0
- package/dist/core/dshCompatibility.d.ts +23 -6
- package/dist/core/dshCompatibility.js +99 -1
- package/dist/core/installUpdate.d.ts +67 -0
- package/dist/core/installUpdate.js +265 -0
- package/dist/core/mobilePairing.d.ts +46 -0
- package/dist/core/mobilePairing.js +207 -0
- package/dist/core/toolPolicy.js +28 -13
- package/dist/core/workspace.d.ts +6 -0
- package/dist/core/workspace.js +14 -0
- package/dist/main.js +49 -0
- package/dist/preload.js +5 -0
- package/dist/server.js +195 -3
- package/dist/tools/index.d.ts +14 -0
- package/dist/tools/index.js +143 -17
- package/dist/tui/src/adapters/core-runtime-adapter.js +17 -1
- package/dist/tui/src/app.js +41 -0
- package/dist/tui/src/data.js +1 -0
- package/dist/tui/src/render.js +11 -0
- package/dist/tui/src/settings-schema.js +3 -1
- package/dist/tui/src/state.js +21 -1
- package/dist/ui/index.html +455 -13
- package/dist/ui/lucide-sprite.svg +10 -0
- package/dist/wsl-agent-host.bundle.cjs +860 -688
- package/package.json +15 -8
package/dist/main.js
CHANGED
|
@@ -55,6 +55,7 @@ const cli_discovery_1 = require("./cli-discovery");
|
|
|
55
55
|
const config_1 = require("./core/config");
|
|
56
56
|
const memoryLab_1 = require("./core/memoryLab");
|
|
57
57
|
const installUpdate_1 = require("./core/installUpdate");
|
|
58
|
+
const mobilePairing_1 = require("./core/mobilePairing");
|
|
58
59
|
const terminalTakeover_1 = require("./tools/terminalTakeover");
|
|
59
60
|
const nativeBash_1 = require("./core/nativeBash");
|
|
60
61
|
const nativeTools_1 = require("./tools/nativeTools");
|
|
@@ -3472,6 +3473,7 @@ else {
|
|
|
3472
3473
|
},
|
|
3473
3474
|
configuredAgentBackend: agent.config.getBool('agent', 'run_in_wsl') ? 'wsl' : 'windows',
|
|
3474
3475
|
agentBackendRestartRequired: (agent.config.getBool('agent', 'run_in_wsl') ? 'wsl' : 'windows') !== activeAgentBackendMode,
|
|
3476
|
+
remoteTouchEnabled: agent.config.getBool('remote', 'touch_enabled'),
|
|
3475
3477
|
wslAvailable: wslDistros.length > 0,
|
|
3476
3478
|
wslDistros,
|
|
3477
3479
|
};
|
|
@@ -4784,6 +4786,15 @@ else {
|
|
|
4784
4786
|
return { servers: mcpManager.list(), discovered };
|
|
4785
4787
|
});
|
|
4786
4788
|
electron_1.ipcMain.handle('dsh:discover', async () => (0, dshCompatibility_1.discoverDshCompatibility)(root));
|
|
4789
|
+
electron_1.ipcMain.handle('dsh:installBundle', async (_event, manifestPath) => {
|
|
4790
|
+
return (0, dshCompatibility_1.installDshBundle)(root, String(manifestPath || ''));
|
|
4791
|
+
});
|
|
4792
|
+
electron_1.ipcMain.handle('dsh:uninstallBundle', async (_event, name) => {
|
|
4793
|
+
return (0, dshCompatibility_1.uninstallDshBundle)(root, String(name || ''));
|
|
4794
|
+
});
|
|
4795
|
+
electron_1.ipcMain.handle('dsh:setBundleEnabled', async (_event, name, enabled) => {
|
|
4796
|
+
return (0, dshCompatibility_1.setDshBundleEnabled)(root, String(name || ''), enabled === true);
|
|
4797
|
+
});
|
|
4787
4798
|
electron_1.ipcMain.handle('mcp:upsert', async (_event, input) => {
|
|
4788
4799
|
if (!mcpManager)
|
|
4789
4800
|
return { ok: false, error: 'MCP manager is unavailable.' };
|
|
@@ -4855,6 +4866,21 @@ else {
|
|
|
4855
4866
|
electron_1.ipcMain.handle('update:version', async () => {
|
|
4856
4867
|
return { ok: true, version: (0, installUpdate_1.currentAppVersion)(), root };
|
|
4857
4868
|
});
|
|
4869
|
+
electron_1.ipcMain.handle('mobile:pairingQr', async () => {
|
|
4870
|
+
const qr = await (0, mobilePairing_1.pairingQrDataUrl)(root);
|
|
4871
|
+
return {
|
|
4872
|
+
ok: true,
|
|
4873
|
+
url: qr.session.url,
|
|
4874
|
+
dataUrl: qr.dataUrl,
|
|
4875
|
+
pairingId: qr.session.pairingId,
|
|
4876
|
+
expiresAt: qr.session.expiresAt,
|
|
4877
|
+
tokenFile: (0, mobilePairing_1.pairingTokenPath)(root),
|
|
4878
|
+
tailscaleIpv4: (0, mobilePairing_1.tailscaleIpv4)(),
|
|
4879
|
+
};
|
|
4880
|
+
});
|
|
4881
|
+
electron_1.ipcMain.handle('mobile:pairingStatus', async () => {
|
|
4882
|
+
return { ok: true, status: (0, mobilePairing_1.pairingStatus)(root) };
|
|
4883
|
+
});
|
|
4858
4884
|
electron_1.ipcMain.handle('update:checkGithub', async (_event, input = {}) => {
|
|
4859
4885
|
return (0, installUpdate_1.checkGitHubUpdate)(String(input.repo || ''), String(input.tag || ''), String(input.asset || ''));
|
|
4860
4886
|
});
|
|
@@ -4884,6 +4910,29 @@ else {
|
|
|
4884
4910
|
setTimeout(() => electron_1.app.quit(), 150);
|
|
4885
4911
|
return result;
|
|
4886
4912
|
});
|
|
4913
|
+
electron_1.ipcMain.handle('update:planMsi', async (_event, input = {}) => {
|
|
4914
|
+
return (0, installUpdate_1.planManagedMsiInstall)(String(input.msiPath || ''), {
|
|
4915
|
+
stopConfirmed: input.stopConfirmed === true,
|
|
4916
|
+
removeLegacyConfirmed: input.removeLegacyConfirmed === true,
|
|
4917
|
+
uninstallPrevious: input.uninstallPrevious !== false,
|
|
4918
|
+
allowElevate: input.allowElevate !== false,
|
|
4919
|
+
excludeRoots: Array.isArray(input.excludeRoots) ? input.excludeRoots.map(String) : undefined,
|
|
4920
|
+
logDir: typeof input.logDir === 'string' ? input.logDir : undefined,
|
|
4921
|
+
});
|
|
4922
|
+
});
|
|
4923
|
+
electron_1.ipcMain.handle('update:executeMsi', async (_event, input = {}) => {
|
|
4924
|
+
const result = (0, installUpdate_1.executeManagedMsiInstall)(String(input.msiPath || ''), {
|
|
4925
|
+
stopConfirmed: input.stopConfirmed === true,
|
|
4926
|
+
removeLegacyConfirmed: input.removeLegacyConfirmed === true,
|
|
4927
|
+
uninstallPrevious: input.uninstallPrevious !== false,
|
|
4928
|
+
allowElevate: input.allowElevate !== false,
|
|
4929
|
+
excludeRoots: Array.isArray(input.excludeRoots) ? input.excludeRoots.map(String) : undefined,
|
|
4930
|
+
logDir: typeof input.logDir === 'string' ? input.logDir : undefined,
|
|
4931
|
+
});
|
|
4932
|
+
if (result.ok)
|
|
4933
|
+
setTimeout(() => electron_1.app.quit(), 150);
|
|
4934
|
+
return result;
|
|
4935
|
+
});
|
|
4887
4936
|
electron_1.ipcMain.handle('github:gh', async (_event, argv = []) => {
|
|
4888
4937
|
const safeArgs = Array.isArray(argv) ? argv.map(String).filter(a => a.length < 400) : [];
|
|
4889
4938
|
try {
|
package/dist/preload.js
CHANGED
|
@@ -124,6 +124,9 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
124
124
|
refreshSkills: () => ipcRenderer.invoke('skills:refresh'),
|
|
125
125
|
listMcpServers: () => ipcRenderer.invoke('mcp:list'),
|
|
126
126
|
discoverDshCompatibility: () => ipcRenderer.invoke('dsh:discover'),
|
|
127
|
+
installDshBundle: (manifestPath) => ipcRenderer.invoke('dsh:installBundle', manifestPath),
|
|
128
|
+
uninstallDshBundle: (name) => ipcRenderer.invoke('dsh:uninstallBundle', name),
|
|
129
|
+
setDshBundleEnabled: (name, enabled) => ipcRenderer.invoke('dsh:setBundleEnabled', name, enabled),
|
|
127
130
|
upsertMcpServer: (input) => ipcRenderer.invoke('mcp:upsert', input),
|
|
128
131
|
setMcpServerEnabled: (id, enabled) => ipcRenderer.invoke('mcp:setEnabled', id, enabled),
|
|
129
132
|
removeMcpServer: (id) => ipcRenderer.invoke('mcp:remove', id),
|
|
@@ -134,6 +137,8 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
134
137
|
memoryLabUpdate: (input) => ipcRenderer.invoke('memoryLab:update', input),
|
|
135
138
|
memoryLabReindex: () => ipcRenderer.invoke('memoryLab:reindex'),
|
|
136
139
|
updateVersion: () => ipcRenderer.invoke('update:version'),
|
|
140
|
+
mobilePairingQr: () => ipcRenderer.invoke('mobile:pairingQr'),
|
|
141
|
+
mobilePairingStatus: () => ipcRenderer.invoke('mobile:pairingStatus'),
|
|
137
142
|
updateCheckGithub: (input) => ipcRenderer.invoke('update:checkGithub', input),
|
|
138
143
|
updateApplyGithub: (input) => ipcRenderer.invoke('update:applyGithub', input),
|
|
139
144
|
updateInstallLocal: (input) => ipcRenderer.invoke('update:installLocal', input),
|
package/dist/server.js
CHANGED
|
@@ -37,6 +37,7 @@ exports.runServer = runServer;
|
|
|
37
37
|
const http = __importStar(require("http"));
|
|
38
38
|
const fs = __importStar(require("fs"));
|
|
39
39
|
const path = __importStar(require("path"));
|
|
40
|
+
const os = __importStar(require("os"));
|
|
40
41
|
const uiPreferences_1 = require("./core/uiPreferences");
|
|
41
42
|
const child_process_1 = require("child_process");
|
|
42
43
|
const agent_1 = require("./core/agent");
|
|
@@ -45,10 +46,76 @@ const config_1 = require("./core/config");
|
|
|
45
46
|
const flow_1 = require("./core/flow");
|
|
46
47
|
const workspaceFileRouter_1 = require("./core/workspaceFileRouter");
|
|
47
48
|
const nativeBash_1 = require("./core/nativeBash");
|
|
49
|
+
const installUpdate_1 = require("./core/installUpdate");
|
|
50
|
+
const mobilePairing_1 = require("./core/mobilePairing");
|
|
48
51
|
const PORT = 47890;
|
|
49
52
|
let agent = null;
|
|
50
53
|
let automation = null;
|
|
51
54
|
let workspaceFileRouter = null;
|
|
55
|
+
let mobileToken = '';
|
|
56
|
+
let appRoot = '';
|
|
57
|
+
function mobileAuthorized(req) {
|
|
58
|
+
if (!mobileToken)
|
|
59
|
+
return false;
|
|
60
|
+
const bearer = String(req.headers.authorization || '');
|
|
61
|
+
if (bearer.startsWith('Bearer '))
|
|
62
|
+
return bearer.slice('Bearer '.length).trim() === mobileToken;
|
|
63
|
+
try {
|
|
64
|
+
const url = new URL(req.url || '/', `http://localhost:${PORT}`);
|
|
65
|
+
const queryToken = url.searchParams.get('token') || '';
|
|
66
|
+
return queryToken === mobileToken;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function mobileJson(res, data, code = 200) {
|
|
73
|
+
const body = JSON.stringify(data);
|
|
74
|
+
res.writeHead(code, {
|
|
75
|
+
'Content-Type': 'application/json; charset=utf-8',
|
|
76
|
+
'Access-Control-Allow-Origin': '*',
|
|
77
|
+
});
|
|
78
|
+
res.end(body);
|
|
79
|
+
}
|
|
80
|
+
function handleMobileEvents(req, res) {
|
|
81
|
+
if (agent && !agent.config.getBool('remote', 'touch_enabled')) {
|
|
82
|
+
mobileJson(res, { error: 'Remote touch disabled' }, 403);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (!mobileAuthorized(req)) {
|
|
86
|
+
mobileJson(res, { error: 'Unauthorized' }, 401);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (!agent) {
|
|
90
|
+
mobileJson(res, { error: 'Agent not initialized' }, 500);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
res.writeHead(200, {
|
|
94
|
+
'Content-Type': 'text/event-stream; charset=utf-8',
|
|
95
|
+
'Cache-Control': 'no-cache',
|
|
96
|
+
'Connection': 'keep-alive',
|
|
97
|
+
'Access-Control-Allow-Origin': '*',
|
|
98
|
+
});
|
|
99
|
+
res.write('retry: 3000\n\n');
|
|
100
|
+
const unsubscribe = agent.subscribeWorkEvents(event => {
|
|
101
|
+
try {
|
|
102
|
+
res.write(`event: work\ndata: ${JSON.stringify(event)}\n\n`);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// socket is gone; the close handler will clean up
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
const heartbeat = setInterval(() => {
|
|
109
|
+
try {
|
|
110
|
+
res.write(': ping\n\n');
|
|
111
|
+
}
|
|
112
|
+
catch { }
|
|
113
|
+
}, 15000);
|
|
114
|
+
req.on('close', () => {
|
|
115
|
+
clearInterval(heartbeat);
|
|
116
|
+
unsubscribe();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
52
119
|
function resolveAppPath(root, targetPath) {
|
|
53
120
|
if (!targetPath)
|
|
54
121
|
return root;
|
|
@@ -214,6 +281,16 @@ function jsonResponse(res, data, code = 200) {
|
|
|
214
281
|
async function handleApi(req, res, body) {
|
|
215
282
|
const url = new URL(req.url || '/', `http://localhost:${PORT}`);
|
|
216
283
|
const pathname = url.pathname;
|
|
284
|
+
if (pathname.startsWith('/api/mobile/')) {
|
|
285
|
+
if (agent && !agent.config.getBool('remote', 'touch_enabled')) {
|
|
286
|
+
mobileJson(res, { error: 'Remote touch disabled' }, 403);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (!mobileAuthorized(req)) {
|
|
290
|
+
mobileJson(res, { error: 'Unauthorized' }, 401);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
217
294
|
if (!agent) {
|
|
218
295
|
jsonResponse(res, { error: 'Agent not initialized' }, 500);
|
|
219
296
|
return;
|
|
@@ -603,15 +680,114 @@ async function handleApi(req, res, body) {
|
|
|
603
680
|
jsonResponse(res, { content: agent.readArchive(aName2) });
|
|
604
681
|
return;
|
|
605
682
|
}
|
|
683
|
+
case '/api/mobile/pair-confirm': {
|
|
684
|
+
let pairingId = url.searchParams.get('pairingId') || '';
|
|
685
|
+
if (!pairingId) {
|
|
686
|
+
try {
|
|
687
|
+
pairingId = String(JSON.parse(body || '{}').pairingId || '');
|
|
688
|
+
}
|
|
689
|
+
catch { }
|
|
690
|
+
}
|
|
691
|
+
const result = (0, mobilePairing_1.confirmPairing)(appRoot, pairingId, mobileToken);
|
|
692
|
+
mobileJson(res, result.ok
|
|
693
|
+
? { ok: true, status: result.status }
|
|
694
|
+
: { ok: false, error: result.error, status: result.status }, result.ok ? 200 : 401);
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
case '/api/mobile/pair-status': {
|
|
698
|
+
mobileJson(res, { ok: true, status: (0, mobilePairing_1.pairingStatus)(appRoot) });
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
case '/api/mobile/hello': {
|
|
702
|
+
mobileJson(res, {
|
|
703
|
+
ok: true,
|
|
704
|
+
version: (0, installUpdate_1.currentAppVersion)(),
|
|
705
|
+
hostname: os.hostname(),
|
|
706
|
+
platform: process.platform,
|
|
707
|
+
tailscaleIpv4: (0, mobilePairing_1.tailscaleIpv4)(),
|
|
708
|
+
workspace: agent.workspace.current ? {
|
|
709
|
+
id: agent.workspace.current.id,
|
|
710
|
+
name: agent.workspace.current.name,
|
|
711
|
+
path: agent.workspace.current.path,
|
|
712
|
+
} : null,
|
|
713
|
+
conversationCount: agent.listConversationStates().length,
|
|
714
|
+
activeConversationId: agent.activeConversationId,
|
|
715
|
+
});
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
case '/api/mobile/state': {
|
|
719
|
+
const active = agent.getConversationSnapshot(agent.activeConversationId, { window: 200 });
|
|
720
|
+
mobileJson(res, {
|
|
721
|
+
mode: agent.mode,
|
|
722
|
+
model: agent.modelSelectionValue(),
|
|
723
|
+
status: agent.status,
|
|
724
|
+
activeConversationId: agent.activeConversationId,
|
|
725
|
+
conversations: agent.listConversationStates(),
|
|
726
|
+
workspaces: { internal: agent.workspace.internal, external: agent.workspace.external, current: agent.workspace.current },
|
|
727
|
+
pendingOptions: agent.pendingOptions,
|
|
728
|
+
contextWindow: agent.contextWindow(),
|
|
729
|
+
chatMessages: active.chatMessages,
|
|
730
|
+
totalMessages: active.totalMessages,
|
|
731
|
+
conversationLocked: agent.isConversationLocked(),
|
|
732
|
+
});
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
case '/api/mobile/conversations': {
|
|
736
|
+
mobileJson(res, agent.listConversationStates());
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
case '/api/mobile/conversation': {
|
|
740
|
+
const conversationId = url.searchParams.get('conversationId') || agent.activeConversationId;
|
|
741
|
+
const windowParam = url.searchParams.get('window');
|
|
742
|
+
const beforeParam = url.searchParams.get('before');
|
|
743
|
+
const windowSize = windowParam ? Math.max(1, Math.min(500, Number(windowParam) || 200)) : 200;
|
|
744
|
+
const before = beforeParam ? Math.max(0, Number(beforeParam) || 0) : undefined;
|
|
745
|
+
const snapshot = agent.getConversationSnapshot(String(conversationId), { window: windowSize, before });
|
|
746
|
+
mobileJson(res, snapshot);
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
case '/api/mobile/workspaces': {
|
|
750
|
+
mobileJson(res, { internal: agent.workspace.internal, external: agent.workspace.external, current: agent.workspace.current });
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
case '/api/mobile/send': {
|
|
754
|
+
const params = JSON.parse(body || '{}');
|
|
755
|
+
const message = String(params.message || '');
|
|
756
|
+
if (!message) {
|
|
757
|
+
mobileJson(res, { error: 'No message' }, 400);
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
if (params.conversationId)
|
|
761
|
+
agent.setConversation(String(params.conversationId));
|
|
762
|
+
const tokens = await agent.process(message);
|
|
763
|
+
const snapshot = agent.getConversationSnapshot(agent.activeConversationId, { window: 200 });
|
|
764
|
+
mobileJson(res, {
|
|
765
|
+
ok: true,
|
|
766
|
+
conversationId: agent.activeConversationId,
|
|
767
|
+
response: tokens.map(token => token.text).join(''),
|
|
768
|
+
tokens: tokens.map(token => ({ type: token.type, text: token.text })),
|
|
769
|
+
options: agent.pendingOptions,
|
|
770
|
+
status: agent.status,
|
|
771
|
+
conversations: agent.listConversationStates(),
|
|
772
|
+
chatMessages: snapshot.chatMessages,
|
|
773
|
+
totalMessages: snapshot.totalMessages,
|
|
774
|
+
});
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
606
777
|
default:
|
|
607
778
|
jsonResponse(res, { error: 'Unknown API' }, 404);
|
|
608
779
|
}
|
|
609
780
|
}
|
|
610
781
|
catch (e) {
|
|
611
|
-
|
|
782
|
+
if (pathname.startsWith('/api/mobile/'))
|
|
783
|
+
mobileJson(res, { error: e.message }, 500);
|
|
784
|
+
else
|
|
785
|
+
jsonResponse(res, { error: e.message }, 500);
|
|
612
786
|
}
|
|
613
787
|
}
|
|
614
788
|
function startServer(root) {
|
|
789
|
+
mobileToken = (0, mobilePairing_1.ensureMobileToken)(root);
|
|
790
|
+
appRoot = root;
|
|
615
791
|
agent = new agent_1.Agent(root);
|
|
616
792
|
workspaceFileRouter = new workspaceFileRouter_1.WorkspaceFileRouter(() => path.resolve(agent?.workspace.current?.path || root));
|
|
617
793
|
automation = new automation_1.AutomationManager(agent.config, async (prompt, model, item) => {
|
|
@@ -645,11 +821,19 @@ function startServer(root) {
|
|
|
645
821
|
const uiDir = path.join(__dirname, 'ui');
|
|
646
822
|
const server = http.createServer(async (req, res) => {
|
|
647
823
|
if (req.method === 'OPTIONS') {
|
|
648
|
-
res.writeHead(204
|
|
824
|
+
res.writeHead(204, {
|
|
825
|
+
'Access-Control-Allow-Origin': '*',
|
|
826
|
+
'Access-Control-Allow-Headers': 'Authorization, Content-Type',
|
|
827
|
+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
828
|
+
});
|
|
649
829
|
res.end();
|
|
650
830
|
return;
|
|
651
831
|
}
|
|
652
832
|
const url = new URL(req.url || '/', `http://localhost:${PORT}`);
|
|
833
|
+
if (url.pathname === '/api/mobile/events') {
|
|
834
|
+
handleMobileEvents(req, res);
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
653
837
|
if (req.method === 'POST' && url.pathname.startsWith('/api/')) {
|
|
654
838
|
let body = '';
|
|
655
839
|
req.on('data', chunk => body += chunk);
|
|
@@ -667,9 +851,17 @@ function startServer(root) {
|
|
|
667
851
|
const fullPath = path.join(uiDir, filePath);
|
|
668
852
|
serveFile(res, fullPath);
|
|
669
853
|
});
|
|
670
|
-
|
|
854
|
+
const bindHost = process.env.NEWMARK_BIND_HOST || '0.0.0.0';
|
|
855
|
+
const tailscale = (0, mobilePairing_1.tailscaleIpv4)();
|
|
856
|
+
const tokenPath = path.join(root, '.newmark-mobile-token');
|
|
857
|
+
server.listen(PORT, bindHost, () => {
|
|
671
858
|
console.log(`\n Newmark Agent v1.0 - Server Mode`);
|
|
859
|
+
console.log(` Bind: ${bindHost}:${PORT}`);
|
|
672
860
|
console.log(` GUI: http://localhost:${PORT}`);
|
|
861
|
+
console.log(` Tailscale IPv4: ${tailscale || 'not detected (install/start Tailscale)'}`);
|
|
862
|
+
console.log(` Mobile endpoint: http://${tailscale || '<tailscale-ip>'}:${PORT}/api/mobile/hello?token=<token>`);
|
|
863
|
+
console.log(` Mobile token file: ${tokenPath}`);
|
|
864
|
+
console.log(` Mobile events (SSE): http://${tailscale || '<tailscale-ip>'}:${PORT}/api/mobile/events?token=<token>`);
|
|
673
865
|
console.log(` Press Ctrl+C to stop\n`);
|
|
674
866
|
});
|
|
675
867
|
}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -91,13 +91,27 @@ export declare class ToolExecutor {
|
|
|
91
91
|
private parseGitHubRepo;
|
|
92
92
|
private githubFileAudit;
|
|
93
93
|
private repoSecurityAudit;
|
|
94
|
+
private collectRepositoryFiles;
|
|
94
95
|
private scanRepositorySecrets;
|
|
96
|
+
/**
|
|
97
|
+
* 扫描隐私地址类高危信息:带凭据的 URL(user:pass@)、私网 IP、本地用户目录
|
|
98
|
+
* 绝对路径(C:\Users\<user>、/home/<user>、/Users/<user>)。这些内容泄露个人
|
|
99
|
+
* 账号、内网拓扑或本地机器结构,进入公开 remote 即构成隐私暴露,需与密钥同级
|
|
100
|
+
* 硬性阻挡并在 Agent 二轮审查确认后放行。
|
|
101
|
+
*/
|
|
102
|
+
private scanRepositoryPrivacyLeaks;
|
|
95
103
|
private releaseExcludedPathFindings;
|
|
96
104
|
private ghJson;
|
|
97
105
|
private gbranch;
|
|
98
106
|
private ghFork;
|
|
99
107
|
private ghPrCreate;
|
|
100
108
|
private withRemoteSecurityPreamble;
|
|
109
|
+
/**
|
|
110
|
+
* 硬性阻挡远程写:当密钥或隐私地址类高危信息存在且 Agent 尚未二轮审查确认时,
|
|
111
|
+
* 返回明确的阻挡结果(脱敏 findings),要求处理/确认后再以
|
|
112
|
+
* security_review_confirmed=true 重试放行。
|
|
113
|
+
*/
|
|
114
|
+
private formatRemoteSecurityBlock;
|
|
101
115
|
private gstat;
|
|
102
116
|
private gpull;
|
|
103
117
|
private gpush;
|