@runweave/server-linux-x64 0.1.19 → 0.1.20
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.json +21 -21
- package/native.tar.gz +0 -0
- package/package.json +1 -1
- package/payload/app-server/build-info.json +4 -4
- package/payload/app-server/index.cjs +30 -8
- package/payload/app-server/index.cjs.map +1 -1
- package/payload/backend/activity-sqlite-worker.cjs +29 -7
- package/payload/backend/build-info.json +4 -4
- package/payload/backend/dev-resources/control.cjs +29 -7
- package/payload/backend/index.cjs +193 -48
- package/payload/frontend/dist/build-info.json +3 -3
- package/payload/frontend/dist/companion.html +1 -1
- package/payload/frontend/dist/index.html +1 -1
- package/payload/pty-host/index.cjs +126 -17
- package/payload/server/index.cjs +29 -7
|
@@ -12017,27 +12017,49 @@ function assertWindowsPrivatePath(file) {
|
|
|
12017
12017
|
if (process.platform !== "win32") return;
|
|
12018
12018
|
const script = `
|
|
12019
12019
|
$ErrorActionPreference = 'Stop'
|
|
12020
|
+
try {
|
|
12020
12021
|
# Use .NET directly: a parent pwsh may export a PSModulePath incompatible with Windows PowerShell.
|
|
12021
12022
|
$acl = if ([IO.Directory]::Exists($env:RUNWEAVE_PRIVATE_PATH)) {
|
|
12022
12023
|
[IO.Directory]::GetAccessControl($env:RUNWEAVE_PRIVATE_PATH)
|
|
12023
12024
|
} else { [IO.File]::GetAccessControl($env:RUNWEAVE_PRIVATE_PATH) }
|
|
12024
12025
|
$sid = [Security.Principal.WindowsIdentity]::GetCurrent().User
|
|
12025
12026
|
$allowed = @($sid.Value, 'S-1-5-18', 'S-1-5-32-544')
|
|
12026
|
-
if ($acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -notin $allowed) {
|
|
12027
|
+
if ($acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -notin $allowed) { [Console]::Write('owner'); exit 0 }
|
|
12027
12028
|
foreach ($rule in $acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier])) {
|
|
12028
|
-
if ($rule.AccessControlType -eq 'Allow' -and $rule.IdentityReference.Value -notin $allowed) {
|
|
12029
|
+
if ($rule.AccessControlType -eq 'Allow' -and $rule.IdentityReference.Value -notin $allowed) { [Console]::Write('access'); exit 0 }
|
|
12030
|
+
}
|
|
12031
|
+
[Console]::Write('private')
|
|
12032
|
+
} catch {
|
|
12033
|
+
[Console]::Write('check-failed:' + $_.Exception.GetType().FullName + ':' + $_.Exception.HResult)
|
|
12029
12034
|
}
|
|
12030
12035
|
`;
|
|
12036
|
+
const startedAt = performance.now();
|
|
12037
|
+
let result;
|
|
12031
12038
|
try {
|
|
12032
|
-
(0, import_node_child_process.execFileSync)("powershell.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], {
|
|
12039
|
+
result = (0, import_node_child_process.execFileSync)("powershell.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], {
|
|
12033
12040
|
env: { ...process.env, RUNWEAVE_PRIVATE_PATH: file },
|
|
12034
|
-
stdio: "ignore",
|
|
12041
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
12042
|
+
encoding: "utf8",
|
|
12043
|
+
maxBuffer: 64 * 1024,
|
|
12035
12044
|
timeout: 1e4,
|
|
12036
12045
|
windowsHide: true
|
|
12037
|
-
});
|
|
12038
|
-
} catch {
|
|
12039
|
-
|
|
12046
|
+
}).trim();
|
|
12047
|
+
} catch (cause) {
|
|
12048
|
+
const error = cause;
|
|
12049
|
+
throw new ConfigurationError(
|
|
12050
|
+
error.code === "ETIMEDOUT" ? "CONFIG_WINDOWS_ACL_CHECK_TIMEOUT" : "CONFIG_WINDOWS_ACL_CHECK_FAILED",
|
|
12051
|
+
[
|
|
12052
|
+
file,
|
|
12053
|
+
`exit=${error.status ?? "none"}`,
|
|
12054
|
+
`signal=${error.signal ?? "none"}`,
|
|
12055
|
+
`code=${error.code ?? "none"}`,
|
|
12056
|
+
`elapsedMs=${Math.round(performance.now() - startedAt)}`
|
|
12057
|
+
]
|
|
12058
|
+
);
|
|
12040
12059
|
}
|
|
12060
|
+
if (result === "owner" || result === "access") throw new ConfigurationError("CONFIG_WINDOWS_ACL_NOT_PRIVATE", [file, result]);
|
|
12061
|
+
if (/^check-failed:[A-Za-z0-9_.]+:-?\d+$/.test(result)) throw new ConfigurationError("CONFIG_WINDOWS_ACL_CHECK_FAILED", [file, result]);
|
|
12062
|
+
if (result !== "private") throw new ConfigurationError("CONFIG_WINDOWS_ACL_CHECK_FAILED", [file, "invalid-result"]);
|
|
12041
12063
|
}
|
|
12042
12064
|
|
|
12043
12065
|
// packages/config-node/src/context.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.1.0",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"sourceRevision": "
|
|
3
|
+
"buildId": "20261113T041834470Z-7289d6d4",
|
|
4
|
+
"sourceRevision": "7289d6d41760456521e48793f92114e9f047689d",
|
|
5
5
|
"sourceDirty": false,
|
|
6
|
-
"builtAt": "2026-11-
|
|
7
|
-
"contentSha256": "
|
|
6
|
+
"builtAt": "2026-11-13T04:18:34.470Z",
|
|
7
|
+
"contentSha256": "a2a209ffb4c5a5426ca35007a72264dac6cc81c8a2c0935afc0896e9a89ed809"
|
|
8
8
|
}
|
|
@@ -8483,27 +8483,49 @@ function assertWindowsPrivatePath(file) {
|
|
|
8483
8483
|
if (process.platform !== "win32") return;
|
|
8484
8484
|
const script = `
|
|
8485
8485
|
$ErrorActionPreference = 'Stop'
|
|
8486
|
+
try {
|
|
8486
8487
|
# Use .NET directly: a parent pwsh may export a PSModulePath incompatible with Windows PowerShell.
|
|
8487
8488
|
$acl = if ([IO.Directory]::Exists($env:RUNWEAVE_PRIVATE_PATH)) {
|
|
8488
8489
|
[IO.Directory]::GetAccessControl($env:RUNWEAVE_PRIVATE_PATH)
|
|
8489
8490
|
} else { [IO.File]::GetAccessControl($env:RUNWEAVE_PRIVATE_PATH) }
|
|
8490
8491
|
$sid = [Security.Principal.WindowsIdentity]::GetCurrent().User
|
|
8491
8492
|
$allowed = @($sid.Value, 'S-1-5-18', 'S-1-5-32-544')
|
|
8492
|
-
if ($acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -notin $allowed) {
|
|
8493
|
+
if ($acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -notin $allowed) { [Console]::Write('owner'); exit 0 }
|
|
8493
8494
|
foreach ($rule in $acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier])) {
|
|
8494
|
-
if ($rule.AccessControlType -eq 'Allow' -and $rule.IdentityReference.Value -notin $allowed) {
|
|
8495
|
+
if ($rule.AccessControlType -eq 'Allow' -and $rule.IdentityReference.Value -notin $allowed) { [Console]::Write('access'); exit 0 }
|
|
8496
|
+
}
|
|
8497
|
+
[Console]::Write('private')
|
|
8498
|
+
} catch {
|
|
8499
|
+
[Console]::Write('check-failed:' + $_.Exception.GetType().FullName + ':' + $_.Exception.HResult)
|
|
8495
8500
|
}
|
|
8496
8501
|
`;
|
|
8502
|
+
const startedAt = performance.now();
|
|
8503
|
+
let result;
|
|
8497
8504
|
try {
|
|
8498
|
-
(0, import_node_child_process2.execFileSync)("powershell.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], {
|
|
8505
|
+
result = (0, import_node_child_process2.execFileSync)("powershell.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], {
|
|
8499
8506
|
env: { ...process.env, RUNWEAVE_PRIVATE_PATH: file },
|
|
8500
|
-
stdio: "ignore",
|
|
8507
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
8508
|
+
encoding: "utf8",
|
|
8509
|
+
maxBuffer: 64 * 1024,
|
|
8501
8510
|
timeout: 1e4,
|
|
8502
8511
|
windowsHide: true
|
|
8503
|
-
});
|
|
8504
|
-
} catch {
|
|
8505
|
-
|
|
8512
|
+
}).trim();
|
|
8513
|
+
} catch (cause) {
|
|
8514
|
+
const error = cause;
|
|
8515
|
+
throw new ConfigurationError(
|
|
8516
|
+
error.code === "ETIMEDOUT" ? "CONFIG_WINDOWS_ACL_CHECK_TIMEOUT" : "CONFIG_WINDOWS_ACL_CHECK_FAILED",
|
|
8517
|
+
[
|
|
8518
|
+
file,
|
|
8519
|
+
`exit=${error.status ?? "none"}`,
|
|
8520
|
+
`signal=${error.signal ?? "none"}`,
|
|
8521
|
+
`code=${error.code ?? "none"}`,
|
|
8522
|
+
`elapsedMs=${Math.round(performance.now() - startedAt)}`
|
|
8523
|
+
]
|
|
8524
|
+
);
|
|
8506
8525
|
}
|
|
8526
|
+
if (result === "owner" || result === "access") throw new ConfigurationError("CONFIG_WINDOWS_ACL_NOT_PRIVATE", [file, result]);
|
|
8527
|
+
if (/^check-failed:[A-Za-z0-9_.]+:-?\d+$/.test(result)) throw new ConfigurationError("CONFIG_WINDOWS_ACL_CHECK_FAILED", [file, result]);
|
|
8528
|
+
if (result !== "private") throw new ConfigurationError("CONFIG_WINDOWS_ACL_CHECK_FAILED", [file, "invalid-result"]);
|
|
8507
8529
|
}
|
|
8508
8530
|
|
|
8509
8531
|
// packages/config-node/src/private-file.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* runweave:build-info */var __RUNWEAVE_BUILD_INFO__={"version":"0.1.0","buildId":"
|
|
1
|
+
/* runweave:build-info */var __RUNWEAVE_BUILD_INFO__={"version":"0.1.0","buildId":"20261113T041834470Z-7289d6d4","sourceRevision":"7289d6d41760456521e48793f92114e9f047689d","sourceDirty":false,"builtAt":"2026-11-13T04:18:34.470Z","contentSha256":"a2a209ffb4c5a5426ca35007a72264dac6cc81c8a2c0935afc0896e9a89ed809"};
|
|
2
2
|
const __IMPORT_META_URL__ = require('url').pathToFileURL(__filename).href;
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -63498,27 +63498,49 @@ function assertWindowsPrivatePath(file) {
|
|
|
63498
63498
|
if (process.platform !== "win32") return;
|
|
63499
63499
|
const script = `
|
|
63500
63500
|
$ErrorActionPreference = 'Stop'
|
|
63501
|
+
try {
|
|
63501
63502
|
# Use .NET directly: a parent pwsh may export a PSModulePath incompatible with Windows PowerShell.
|
|
63502
63503
|
$acl = if ([IO.Directory]::Exists($env:RUNWEAVE_PRIVATE_PATH)) {
|
|
63503
63504
|
[IO.Directory]::GetAccessControl($env:RUNWEAVE_PRIVATE_PATH)
|
|
63504
63505
|
} else { [IO.File]::GetAccessControl($env:RUNWEAVE_PRIVATE_PATH) }
|
|
63505
63506
|
$sid = [Security.Principal.WindowsIdentity]::GetCurrent().User
|
|
63506
63507
|
$allowed = @($sid.Value, 'S-1-5-18', 'S-1-5-32-544')
|
|
63507
|
-
if ($acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -notin $allowed) {
|
|
63508
|
+
if ($acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -notin $allowed) { [Console]::Write('owner'); exit 0 }
|
|
63508
63509
|
foreach ($rule in $acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier])) {
|
|
63509
|
-
if ($rule.AccessControlType -eq 'Allow' -and $rule.IdentityReference.Value -notin $allowed) {
|
|
63510
|
+
if ($rule.AccessControlType -eq 'Allow' -and $rule.IdentityReference.Value -notin $allowed) { [Console]::Write('access'); exit 0 }
|
|
63511
|
+
}
|
|
63512
|
+
[Console]::Write('private')
|
|
63513
|
+
} catch {
|
|
63514
|
+
[Console]::Write('check-failed:' + $_.Exception.GetType().FullName + ':' + $_.Exception.HResult)
|
|
63510
63515
|
}
|
|
63511
63516
|
`;
|
|
63517
|
+
const startedAt = performance.now();
|
|
63518
|
+
let result;
|
|
63512
63519
|
try {
|
|
63513
|
-
(0, import_node_child_process.execFileSync)("powershell.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], {
|
|
63520
|
+
result = (0, import_node_child_process.execFileSync)("powershell.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], {
|
|
63514
63521
|
env: { ...process.env, RUNWEAVE_PRIVATE_PATH: file },
|
|
63515
|
-
stdio: "ignore",
|
|
63522
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
63523
|
+
encoding: "utf8",
|
|
63524
|
+
maxBuffer: 64 * 1024,
|
|
63516
63525
|
timeout: 1e4,
|
|
63517
63526
|
windowsHide: true
|
|
63518
|
-
});
|
|
63519
|
-
} catch {
|
|
63520
|
-
|
|
63527
|
+
}).trim();
|
|
63528
|
+
} catch (cause) {
|
|
63529
|
+
const error2 = cause;
|
|
63530
|
+
throw new ConfigurationError(
|
|
63531
|
+
error2.code === "ETIMEDOUT" ? "CONFIG_WINDOWS_ACL_CHECK_TIMEOUT" : "CONFIG_WINDOWS_ACL_CHECK_FAILED",
|
|
63532
|
+
[
|
|
63533
|
+
file,
|
|
63534
|
+
`exit=${error2.status ?? "none"}`,
|
|
63535
|
+
`signal=${error2.signal ?? "none"}`,
|
|
63536
|
+
`code=${error2.code ?? "none"}`,
|
|
63537
|
+
`elapsedMs=${Math.round(performance.now() - startedAt)}`
|
|
63538
|
+
]
|
|
63539
|
+
);
|
|
63521
63540
|
}
|
|
63541
|
+
if (result === "owner" || result === "access") throw new ConfigurationError("CONFIG_WINDOWS_ACL_NOT_PRIVATE", [file, result]);
|
|
63542
|
+
if (/^check-failed:[A-Za-z0-9_.]+:-?\d+$/.test(result)) throw new ConfigurationError("CONFIG_WINDOWS_ACL_CHECK_FAILED", [file, result]);
|
|
63543
|
+
if (result !== "private") throw new ConfigurationError("CONFIG_WINDOWS_ACL_CHECK_FAILED", [file, "invalid-result"]);
|
|
63522
63544
|
}
|
|
63523
63545
|
|
|
63524
63546
|
// packages/config-node/src/private-file.ts
|
|
@@ -72000,12 +72022,20 @@ function readHost(scope) {
|
|
|
72000
72022
|
}
|
|
72001
72023
|
|
|
72002
72024
|
// packages/pty-host/src/transport.ts
|
|
72025
|
+
var HostTransportError = class extends Error {
|
|
72026
|
+
constructor(code, bufferedBytes, limitBytes = 4 * 1024 * 1024) {
|
|
72027
|
+
super(code);
|
|
72028
|
+
this.code = code;
|
|
72029
|
+
this.bufferedBytes = bufferedBytes;
|
|
72030
|
+
this.limitBytes = limitBytes;
|
|
72031
|
+
}
|
|
72032
|
+
};
|
|
72003
72033
|
function receiveJsonLines(socket, onMessage) {
|
|
72004
72034
|
let source2 = "";
|
|
72005
72035
|
socket.setEncoding("utf8");
|
|
72006
72036
|
socket.on("data", (data) => {
|
|
72007
72037
|
source2 += data;
|
|
72008
|
-
if (Buffer.byteLength(source2) > 4 * 1024 * 1024) return socket.destroy(new
|
|
72038
|
+
if (Buffer.byteLength(source2) > 4 * 1024 * 1024) return socket.destroy(new HostTransportError("HOST_MESSAGE_TOO_LARGE", Buffer.byteLength(source2)));
|
|
72009
72039
|
let end;
|
|
72010
72040
|
while ((end = source2.indexOf("\n")) !== -1) {
|
|
72011
72041
|
const line = source2.slice(0, end);
|
|
@@ -72022,35 +72052,76 @@ function receiveJsonLines(socket, onMessage) {
|
|
|
72022
72052
|
function sendJson(socket, message2) {
|
|
72023
72053
|
if (socket.destroyed) return false;
|
|
72024
72054
|
if (socket.writableLength > 4 * 1024 * 1024) {
|
|
72025
|
-
socket.destroy(new
|
|
72055
|
+
socket.destroy(new HostTransportError("HOST_OUTPUT_GAP", socket.writableLength));
|
|
72026
72056
|
return false;
|
|
72027
72057
|
}
|
|
72028
72058
|
socket.write(JSON.stringify(message2) + "\n");
|
|
72029
72059
|
return true;
|
|
72030
72060
|
}
|
|
72031
72061
|
|
|
72062
|
+
// packages/pty-host/src/diagnostics.ts
|
|
72063
|
+
function hostErrorCode(error2) {
|
|
72064
|
+
if (!(error2 instanceof Error)) return "HOST_OPERATION_FAILED";
|
|
72065
|
+
const code = error2.code;
|
|
72066
|
+
if (code && /^(?:E[A-Z0-9_]+|HOST_[A-Z0-9_]+)$/.test(code)) return code;
|
|
72067
|
+
return /^HOST_[A-Z0-9_]+$/.test(error2.message) ? error2.message : "HOST_OPERATION_FAILED";
|
|
72068
|
+
}
|
|
72069
|
+
var actions = /* @__PURE__ */ new Set([
|
|
72070
|
+
"hello",
|
|
72071
|
+
"claimWriter",
|
|
72072
|
+
"listSessions",
|
|
72073
|
+
"createSession",
|
|
72074
|
+
"setUpstreams",
|
|
72075
|
+
"freeze",
|
|
72076
|
+
"stop",
|
|
72077
|
+
"writeInput",
|
|
72078
|
+
"getInputOperation",
|
|
72079
|
+
"getSnapshot",
|
|
72080
|
+
"readOutput",
|
|
72081
|
+
"resize",
|
|
72082
|
+
"signal",
|
|
72083
|
+
"closeSession",
|
|
72084
|
+
"attachSession"
|
|
72085
|
+
]);
|
|
72086
|
+
function diagnosticAction(action) {
|
|
72087
|
+
return actions.has(action) ? action : "unknown";
|
|
72088
|
+
}
|
|
72089
|
+
function writeHostDiagnostic(diagnostic) {
|
|
72090
|
+
process.stderr.write(JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...diagnostic }) + "\n");
|
|
72091
|
+
}
|
|
72092
|
+
function reportHostDiagnostic(sink, diagnostic) {
|
|
72093
|
+
try {
|
|
72094
|
+
sink(diagnostic);
|
|
72095
|
+
} catch {
|
|
72096
|
+
}
|
|
72097
|
+
}
|
|
72098
|
+
|
|
72032
72099
|
// packages/pty-host/src/client.ts
|
|
72033
72100
|
var PtyHostClient = class _PtyHostClient {
|
|
72034
|
-
|
|
72035
|
-
|
|
72036
|
-
events = /* @__PURE__ */ new Set();
|
|
72037
|
-
disconnected = /* @__PURE__ */ new Set();
|
|
72038
|
-
pending = /* @__PURE__ */ new Map();
|
|
72039
|
-
socket;
|
|
72040
|
-
token;
|
|
72041
|
-
connected = false;
|
|
72042
|
-
constructor(scope) {
|
|
72101
|
+
constructor(scope, diagnostic) {
|
|
72102
|
+
this.diagnostic = diagnostic;
|
|
72043
72103
|
const discovery = readHost(scope);
|
|
72044
72104
|
this.descriptor = discovery.descriptor;
|
|
72045
72105
|
this.token = discovery.token;
|
|
72046
72106
|
this.socket = (0, import_node_net2.createConnection)(this.descriptor.endpoint);
|
|
72047
|
-
this.socket.on("error", () => {
|
|
72107
|
+
this.socket.on("error", (error2) => {
|
|
72108
|
+
this.disconnectError = error2;
|
|
72048
72109
|
});
|
|
72049
72110
|
this.socket.on("close", () => {
|
|
72050
72111
|
this.connected = false;
|
|
72051
|
-
|
|
72112
|
+
const error2 = this.disconnectError ?? new Error("HOST_CONNECTION_LOST");
|
|
72113
|
+
reportHostDiagnostic(this.diagnostic, {
|
|
72114
|
+
event: "pty-host.connection.closed",
|
|
72115
|
+
hostInstanceId: this.descriptor.hostInstanceId,
|
|
72116
|
+
connectionId: this.connectionId,
|
|
72117
|
+
code: hostErrorCode(error2),
|
|
72118
|
+
pendingRequests: this.pending.size,
|
|
72119
|
+
writableBytes: this.socket.writableLength,
|
|
72120
|
+
...error2 instanceof HostTransportError ? { bufferedBytes: error2.bufferedBytes, limitBytes: error2.limitBytes } : {}
|
|
72121
|
+
});
|
|
72122
|
+
for (const request2 of this.pending.values()) request2.reject(error2);
|
|
72052
72123
|
this.pending.clear();
|
|
72053
|
-
for (const listener of this.disconnected) listener();
|
|
72124
|
+
for (const listener of this.disconnected) listener(error2);
|
|
72054
72125
|
});
|
|
72055
72126
|
receiveJsonLines(this.socket, (value) => {
|
|
72056
72127
|
const message2 = value;
|
|
@@ -72062,13 +72133,28 @@ var PtyHostClient = class _PtyHostClient {
|
|
|
72062
72133
|
} else if (message2.type) for (const listener of this.events) listener(value);
|
|
72063
72134
|
});
|
|
72064
72135
|
}
|
|
72065
|
-
|
|
72066
|
-
|
|
72136
|
+
descriptor;
|
|
72137
|
+
generation = 0;
|
|
72138
|
+
events = /* @__PURE__ */ new Set();
|
|
72139
|
+
disconnected = /* @__PURE__ */ new Set();
|
|
72140
|
+
pending = /* @__PURE__ */ new Map();
|
|
72141
|
+
socket;
|
|
72142
|
+
token;
|
|
72143
|
+
connected = false;
|
|
72144
|
+
connectionId = (0, import_node_crypto15.randomUUID)();
|
|
72145
|
+
disconnectError;
|
|
72146
|
+
get isConnected() {
|
|
72147
|
+
return this.connected && !this.socket.destroyed;
|
|
72148
|
+
}
|
|
72149
|
+
static async connect(scope, ownerId2, expectedGeneration, expectedHostInstanceId, diagnostic = writeHostDiagnostic) {
|
|
72150
|
+
const client = new _PtyHostClient(scope, diagnostic);
|
|
72067
72151
|
try {
|
|
72068
72152
|
await new Promise((resolve, reject) => {
|
|
72069
72153
|
const timer = setTimeout(() => {
|
|
72070
|
-
|
|
72071
|
-
|
|
72154
|
+
const error2 = new Error("HOST_CONNECT_TIMEOUT");
|
|
72155
|
+
client.disconnectError = error2;
|
|
72156
|
+
client.socket.destroy(error2);
|
|
72157
|
+
reject(error2);
|
|
72072
72158
|
}, 5e3);
|
|
72073
72159
|
client.socket.once("error", (error2) => {
|
|
72074
72160
|
clearTimeout(timer);
|
|
@@ -72091,8 +72177,9 @@ var PtyHostClient = class _PtyHostClient {
|
|
|
72091
72177
|
/** Aborting only releases this caller's wait; it does not cancel or replay Host operations. */
|
|
72092
72178
|
request(action, body2 = {}, signal) {
|
|
72093
72179
|
if (signal?.aborted) return Promise.reject(new Error("HOST_REQUEST_ABORTED"));
|
|
72094
|
-
if (!this.
|
|
72180
|
+
if (!this.isConnected) return Promise.reject(this.socket.errored ?? this.disconnectError ?? new Error("HOST_CONNECTION_LOST"));
|
|
72095
72181
|
const requestId = (0, import_node_crypto15.randomUUID)();
|
|
72182
|
+
const startedAt = performance.now();
|
|
72096
72183
|
return new Promise((resolve, reject) => {
|
|
72097
72184
|
const cleanup = () => {
|
|
72098
72185
|
clearTimeout(timer);
|
|
@@ -72105,6 +72192,17 @@ var PtyHostClient = class _PtyHostClient {
|
|
|
72105
72192
|
resolve(value);
|
|
72106
72193
|
},
|
|
72107
72194
|
reject: (error2) => {
|
|
72195
|
+
reportHostDiagnostic(this.diagnostic, {
|
|
72196
|
+
event: "pty-host.request.failed",
|
|
72197
|
+
hostInstanceId: this.descriptor.hostInstanceId,
|
|
72198
|
+
connectionId: this.connectionId,
|
|
72199
|
+
requestId,
|
|
72200
|
+
action: diagnosticAction(action),
|
|
72201
|
+
code: hostErrorCode(error2),
|
|
72202
|
+
elapsedMs: Math.round(performance.now() - startedAt),
|
|
72203
|
+
pendingRequests: this.pending.size,
|
|
72204
|
+
writableBytes: this.socket.writableLength
|
|
72205
|
+
});
|
|
72108
72206
|
cleanup();
|
|
72109
72207
|
reject(error2);
|
|
72110
72208
|
}
|
|
@@ -72115,7 +72213,7 @@ var PtyHostClient = class _PtyHostClient {
|
|
|
72115
72213
|
signal?.addEventListener("abort", abort, { once: true });
|
|
72116
72214
|
try {
|
|
72117
72215
|
if (!sendJson(this.socket, { requestId, token: this.token, hostInstanceId: this.descriptor.hostInstanceId, action, body: body2 })) {
|
|
72118
|
-
request2.reject(new Error("HOST_CONNECTION_LOST"));
|
|
72216
|
+
request2.reject(this.socket.errored ?? new Error("HOST_CONNECTION_LOST"));
|
|
72119
72217
|
}
|
|
72120
72218
|
} catch (error2) {
|
|
72121
72219
|
request2.reject(error2);
|
|
@@ -72123,11 +72221,13 @@ var PtyHostClient = class _PtyHostClient {
|
|
|
72123
72221
|
});
|
|
72124
72222
|
}
|
|
72125
72223
|
close() {
|
|
72224
|
+
this.disconnectError ??= new Error("HOST_CLIENT_CLOSED");
|
|
72126
72225
|
this.socket.destroy();
|
|
72127
72226
|
}
|
|
72128
72227
|
};
|
|
72129
72228
|
|
|
72130
72229
|
// backend/src/terminal/runtime/pty-host-client.ts
|
|
72230
|
+
var hostLogger = logger.child({ component: "pty-host" });
|
|
72131
72231
|
var ownerId = (0, import_node_crypto16.randomUUID)();
|
|
72132
72232
|
var connection;
|
|
72133
72233
|
var generation;
|
|
@@ -72139,7 +72239,13 @@ function usesPtyHost() {
|
|
|
72139
72239
|
}
|
|
72140
72240
|
async function getPtyHost() {
|
|
72141
72241
|
if (stopped) throw new Error("HOST_CLIENT_STOPPED");
|
|
72142
|
-
connection ??= PtyHostClient.connect(
|
|
72242
|
+
connection ??= PtyHostClient.connect(
|
|
72243
|
+
configuration().context,
|
|
72244
|
+
ownerId,
|
|
72245
|
+
generation,
|
|
72246
|
+
hostInstanceId,
|
|
72247
|
+
({ event, ...fields2 }) => hostLogger.warn(event, fields2)
|
|
72248
|
+
).then(async (client) => {
|
|
72143
72249
|
generation = client.generation;
|
|
72144
72250
|
hostInstanceId = client.descriptor.hostInstanceId;
|
|
72145
72251
|
client.disconnected.add(() => {
|
|
@@ -72174,7 +72280,7 @@ async function createHostedPty(options) {
|
|
|
72174
72280
|
const dataListeners = /* @__PURE__ */ new Set();
|
|
72175
72281
|
const frameListeners = /* @__PURE__ */ new Set();
|
|
72176
72282
|
const exitListeners = /* @__PURE__ */ new Set();
|
|
72177
|
-
const
|
|
72283
|
+
const failureListeners = /* @__PURE__ */ new Set();
|
|
72178
72284
|
const resizeListeners = /* @__PURE__ */ new Set();
|
|
72179
72285
|
const pending2 = [];
|
|
72180
72286
|
let exited;
|
|
@@ -72187,6 +72293,8 @@ async function createHostedPty(options) {
|
|
|
72187
72293
|
for (const listener of frameListeners) listener(frame);
|
|
72188
72294
|
};
|
|
72189
72295
|
let initializing = true;
|
|
72296
|
+
let disposed = false;
|
|
72297
|
+
let failed = false;
|
|
72190
72298
|
const early = [];
|
|
72191
72299
|
const receive = (event) => {
|
|
72192
72300
|
if (event.terminalSessionId !== options.terminalSessionId) return;
|
|
@@ -72194,7 +72302,7 @@ async function createHostedPty(options) {
|
|
|
72194
72302
|
early.push(event);
|
|
72195
72303
|
return;
|
|
72196
72304
|
}
|
|
72197
|
-
if (event.type === "launch" && options.onLaunch) void options.onLaunch(event.launch).catch(
|
|
72305
|
+
if (event.type === "launch" && options.onLaunch) void options.onLaunch(event.launch).catch((error2) => notifyFailure("launch", error2));
|
|
72198
72306
|
if (event.type === "output") emitFrame(event);
|
|
72199
72307
|
if (event.type === "resize") {
|
|
72200
72308
|
grid = { cols: event.cols, rows: event.rows };
|
|
@@ -72205,9 +72313,12 @@ async function createHostedPty(options) {
|
|
|
72205
72313
|
for (const listener of exitListeners) listener({ exitCode: exited });
|
|
72206
72314
|
}
|
|
72207
72315
|
};
|
|
72208
|
-
const
|
|
72209
|
-
|
|
72316
|
+
const fail3 = (failure3) => {
|
|
72317
|
+
if (disposed || failed) return;
|
|
72318
|
+
failed = true;
|
|
72319
|
+
for (const listener of failureListeners) listener(failure3);
|
|
72210
72320
|
};
|
|
72321
|
+
const disconnected = (error2) => fail3({ kind: "host-disconnected", code: hostErrorCode(error2) });
|
|
72211
72322
|
client.events.add(receive);
|
|
72212
72323
|
client.disconnected.add(disconnected);
|
|
72213
72324
|
let attached;
|
|
@@ -72254,7 +72365,19 @@ async function createHostedPty(options) {
|
|
|
72254
72365
|
});
|
|
72255
72366
|
return job;
|
|
72256
72367
|
};
|
|
72257
|
-
const notifyFailure = () =>
|
|
72368
|
+
const notifyFailure = (action, error2) => {
|
|
72369
|
+
if (disposed || failed) return;
|
|
72370
|
+
const code = hostErrorCode(error2);
|
|
72371
|
+
hostLogger.warn("terminal.host.operation.failed", {
|
|
72372
|
+
terminalSessionId: options.terminalSessionId,
|
|
72373
|
+
hostInstanceId: client.descriptor.hostInstanceId,
|
|
72374
|
+
action,
|
|
72375
|
+
code,
|
|
72376
|
+
pendingInputs,
|
|
72377
|
+
pendingBytes
|
|
72378
|
+
});
|
|
72379
|
+
fail3({ kind: client.isConnected ? "host-operation-failed" : "host-disconnected", action, code });
|
|
72380
|
+
};
|
|
72258
72381
|
return {
|
|
72259
72382
|
pid: attached.session.pid,
|
|
72260
72383
|
onData(listener) {
|
|
@@ -72265,15 +72388,16 @@ async function createHostedPty(options) {
|
|
|
72265
72388
|
if (exited !== void 0) listener({ exitCode: exited });
|
|
72266
72389
|
},
|
|
72267
72390
|
write(data) {
|
|
72268
|
-
void writeSteps([{ type: "text", data }], void 0, true).catch(notifyFailure);
|
|
72391
|
+
void writeSteps([{ type: "text", data }], void 0, true).catch((error2) => notifyFailure("writeInput", error2));
|
|
72269
72392
|
},
|
|
72270
72393
|
resize(cols, rows) {
|
|
72271
|
-
void client.request("resize", { ...target2, cols, rows }).catch(notifyFailure);
|
|
72394
|
+
void client.request("resize", { ...target2, cols, rows }).catch((error2) => notifyFailure("resize", error2));
|
|
72272
72395
|
},
|
|
72273
72396
|
signal(signal) {
|
|
72274
|
-
void client.request("signal", { ...target2, signal }).catch(notifyFailure);
|
|
72397
|
+
void client.request("signal", { ...target2, signal }).catch((error2) => notifyFailure("signal", error2));
|
|
72275
72398
|
},
|
|
72276
72399
|
dispose() {
|
|
72400
|
+
disposed = true;
|
|
72277
72401
|
client.events.delete(receive);
|
|
72278
72402
|
client.disconnected.delete(disconnected);
|
|
72279
72403
|
},
|
|
@@ -72289,8 +72413,8 @@ async function createHostedPty(options) {
|
|
|
72289
72413
|
frameListeners.add(listener);
|
|
72290
72414
|
for (const frame of pending2.splice(0)) listener(frame);
|
|
72291
72415
|
},
|
|
72292
|
-
|
|
72293
|
-
|
|
72416
|
+
onFailure(listener) {
|
|
72417
|
+
failureListeners.add(listener);
|
|
72294
72418
|
},
|
|
72295
72419
|
onResize(listener) {
|
|
72296
72420
|
resizeListeners.add(listener);
|
|
@@ -114183,6 +114307,11 @@ function getLiveTerminalScrollback(scrollback) {
|
|
|
114183
114307
|
}
|
|
114184
114308
|
|
|
114185
114309
|
// backend/src/ws/terminal-server-connection-helpers.ts
|
|
114310
|
+
var TERMINAL_RECOVERY_CLOSE_REASONS = {
|
|
114311
|
+
"mirror-limit": "Terminal mirror output limit",
|
|
114312
|
+
"host-disconnected": "Terminal host connection lost",
|
|
114313
|
+
"host-operation-failed": "Terminal host operation failed"
|
|
114314
|
+
};
|
|
114186
114315
|
var TMUX_INITIAL_REPAINT_SETTLE_MS = 50;
|
|
114187
114316
|
var TMUX_METADATA_SYNC_DELAY_MS = 100;
|
|
114188
114317
|
var TERMINAL_WS_MAX_PENDING_BYTES = 4 * 1024 * 1024;
|
|
@@ -114979,7 +115108,10 @@ function attachTerminalWebSocketServer(upgradeRouter, terminalSessionManager, ru
|
|
|
114979
115108
|
unsubscribe = runtimeRegistry.subscribe(runtimeId, {
|
|
114980
115109
|
onOutputFrame: (frame) => outputRecovery?.onFrame(frame),
|
|
114981
115110
|
onResize: (cols2, rows2) => outputRecovery?.onResize(cols2, rows2),
|
|
114982
|
-
onRecoveryError: () =>
|
|
115111
|
+
onRecoveryError: (failure3) => {
|
|
115112
|
+
terminalWsLogger5.warn("terminal.runtime.recovery.failed", { terminalSessionId, ...failure3 });
|
|
115113
|
+
closeSlowTerminalSocket(socket, TERMINAL_RECOVERY_CLOSE_REASONS[failure3.kind]);
|
|
115114
|
+
},
|
|
114983
115115
|
onData(data) {
|
|
114984
115116
|
runtimeOutputSequence += 1;
|
|
114985
115117
|
logTerminalPerf("terminal.runtime.output", {
|
|
@@ -124604,7 +124736,7 @@ var ExperienceLearningAnalysis = class {
|
|
|
124604
124736
|
triggers,
|
|
124605
124737
|
applicability,
|
|
124606
124738
|
avoid,
|
|
124607
|
-
actions,
|
|
124739
|
+
actions: actions2,
|
|
124608
124740
|
verification,
|
|
124609
124741
|
state
|
|
124610
124742
|
}) => ({
|
|
@@ -124613,7 +124745,7 @@ var ExperienceLearningAnalysis = class {
|
|
|
124613
124745
|
triggers,
|
|
124614
124746
|
applicability,
|
|
124615
124747
|
avoid,
|
|
124616
|
-
actions,
|
|
124748
|
+
actions: actions2,
|
|
124617
124749
|
verification,
|
|
124618
124750
|
state
|
|
124619
124751
|
})
|
|
@@ -126703,8 +126835,14 @@ var TerminalOutputScreen = class _TerminalOutputScreen {
|
|
|
126703
126835
|
if (this.disposed) return;
|
|
126704
126836
|
this.pendingBytes += frame.range.toOffset - frame.range.fromOffset;
|
|
126705
126837
|
if (this.pendingBytes > RESUME_MAX_BYTES || this.queue.length >= 8192) {
|
|
126838
|
+
const failure3 = {
|
|
126839
|
+
code: this.pendingBytes > RESUME_MAX_BYTES ? "HOST_MIRROR_PENDING_LIMIT" : "HOST_MIRROR_QUEUE_LIMIT",
|
|
126840
|
+
bufferedBytes: this.pendingBytes,
|
|
126841
|
+
limitBytes: RESUME_MAX_BYTES,
|
|
126842
|
+
queuedOperations: this.queue.length
|
|
126843
|
+
};
|
|
126706
126844
|
this.dispose();
|
|
126707
|
-
this.onFailure();
|
|
126845
|
+
this.onFailure(failure3);
|
|
126708
126846
|
return;
|
|
126709
126847
|
}
|
|
126710
126848
|
this.queue.push({ frame });
|
|
@@ -126809,8 +126947,14 @@ var TerminalOutputScreen = class _TerminalOutputScreen {
|
|
|
126809
126947
|
this.writing = false;
|
|
126810
126948
|
this.partialControlBytes = screenParserIsIdle(this.terminal) ? 0 : this.partialControlBytes + frame.range.toOffset - frame.range.fromOffset;
|
|
126811
126949
|
if (this.partialControlBytes > RESUME_MAX_BYTES) {
|
|
126950
|
+
const failure3 = {
|
|
126951
|
+
code: "HOST_MIRROR_CONTROL_LIMIT",
|
|
126952
|
+
bufferedBytes: this.partialControlBytes,
|
|
126953
|
+
limitBytes: RESUME_MAX_BYTES,
|
|
126954
|
+
queuedOperations: this.queue.length
|
|
126955
|
+
};
|
|
126812
126956
|
this.dispose();
|
|
126813
|
-
this.onFailure();
|
|
126957
|
+
this.onFailure(failure3);
|
|
126814
126958
|
return;
|
|
126815
126959
|
}
|
|
126816
126960
|
this.completeSnapshot?.();
|
|
@@ -126923,9 +127067,10 @@ var TerminalRuntimeRegistry = class _TerminalRuntimeRegistry {
|
|
|
126923
127067
|
if (entry.outputRecovery && !runtime.hosted) {
|
|
126924
127068
|
entry.outputScreen = new TerminalOutputScreen(
|
|
126925
127069
|
entry.outputRecovery.cursor,
|
|
126926
|
-
() => {
|
|
127070
|
+
(failure3) => {
|
|
127071
|
+
logger.warn("terminal.mirror.failed", { terminalSessionId, ...failure3 });
|
|
126927
127072
|
for (const subscriber of entry.subscribers)
|
|
126928
|
-
subscriber.onRecoveryError?.();
|
|
127073
|
+
subscriber.onRecoveryError?.({ kind: "mirror-limit", code: failure3.code });
|
|
126929
127074
|
void this.disposeRuntime(runtimeId);
|
|
126930
127075
|
}
|
|
126931
127076
|
);
|
|
@@ -126957,8 +127102,8 @@ var TerminalRuntimeRegistry = class _TerminalRuntimeRegistry {
|
|
|
126957
127102
|
runtime.hosted.onFrame((frame) => {
|
|
126958
127103
|
for (const subscriber of entry.subscribers) subscriber.onOutputFrame?.(frame);
|
|
126959
127104
|
});
|
|
126960
|
-
runtime.hosted.
|
|
126961
|
-
for (const subscriber of entry.subscribers) subscriber.onRecoveryError?.();
|
|
127105
|
+
runtime.hosted.onFailure((failure3) => {
|
|
127106
|
+
for (const subscriber of entry.subscribers) subscriber.onRecoveryError?.(failure3);
|
|
126962
127107
|
void this.disposeRuntime(runtimeId);
|
|
126963
127108
|
});
|
|
126964
127109
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.1.0",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"sourceRevision": "
|
|
3
|
+
"buildId": "20261113T041718790Z-7289d6d4",
|
|
4
|
+
"sourceRevision": "7289d6d41760456521e48793f92114e9f047689d",
|
|
5
5
|
"sourceDirty": false,
|
|
6
|
-
"builtAt": "2026-11-
|
|
6
|
+
"builtAt": "2026-11-13T04:17:18.790Z",
|
|
7
7
|
"contentSha256": "d2d11639ddf01ae9a680379b210bcb5c0834fb854959fb57d44d0e3cc9080487"
|
|
8
8
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="zh-CN">
|
|
3
|
-
<head><script data-runweave-build-info>var __RUNWEAVE_BUILD_INFO__={"version":"0.1.0","buildId":"
|
|
3
|
+
<head><script data-runweave-build-info>var __RUNWEAVE_BUILD_INFO__={"version":"0.1.0","buildId":"20261113T041718790Z-7289d6d4","sourceRevision":"7289d6d41760456521e48793f92114e9f047689d","sourceDirty":false,"builtAt":"2026-11-13T04:17:18.790Z","contentSha256":"d2d11639ddf01ae9a680379b210bcb5c0834fb854959fb57d44d0e3cc9080487"};</script>
|
|
4
4
|
|
|
5
5
|
<meta charset="UTF-8" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
|
-
<head><script data-runweave-build-info>var __RUNWEAVE_BUILD_INFO__={"version":"0.1.0","buildId":"
|
|
3
|
+
<head><script data-runweave-build-info>var __RUNWEAVE_BUILD_INFO__={"version":"0.1.0","buildId":"20261113T041718790Z-7289d6d4","sourceRevision":"7289d6d41760456521e48793f92114e9f047689d","sourceDirty":false,"builtAt":"2026-11-13T04:17:18.790Z","contentSha256":"d2d11639ddf01ae9a680379b210bcb5c0834fb854959fb57d44d0e3cc9080487"};</script>
|
|
4
4
|
|
|
5
5
|
<meta charset="UTF-8" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|