ds-harness-remote 0.4.3 → 0.4.5
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/README.md +57 -9
- package/bin/ds-harness-remote.js +11 -0
- package/cordis.patch.yml +22 -0
- package/dist/cli.d.ts +31 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +283 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.github.js +31 -15
- package/dist/client.js +31 -15
- package/dist/client.js.map +1 -1
- package/dist/codex/domain.d.ts +6 -2
- package/dist/codex/domain.d.ts.map +1 -1
- package/dist/codex/domain.js +279 -68
- package/dist/codex/domain.js.map +1 -1
- package/dist/codex/method-policy.d.ts +14 -7
- package/dist/codex/method-policy.d.ts.map +1 -1
- package/dist/codex/method-policy.js +3 -0
- package/dist/codex/method-policy.js.map +1 -1
- package/dist/codex/virtual-harness.d.ts +6 -0
- package/dist/codex/virtual-harness.d.ts.map +1 -1
- package/dist/codex/virtual-harness.js +161 -23
- package/dist/codex/virtual-harness.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/harness-api-bridge.d.ts.map +1 -1
- package/dist/harness-api-bridge.js +14 -6
- package/dist/harness-api-bridge.js.map +1 -1
- package/dist/harness-remote-bridge.d.ts +1 -1
- package/dist/harness-remote-bridge.d.ts.map +1 -1
- package/dist/harness-remote-bridge.js +1 -0
- package/dist/harness-remote-bridge.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1342 -270
- package/dist/index.js.map +4 -4
- package/dist/server-api.d.ts.map +1 -1
- package/dist/server-api.js +15 -2
- package/dist/server-api.js.map +1 -1
- package/dist/server-credentials.d.ts +2 -2
- package/dist/service.d.ts +4 -1
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +34 -2
- package/dist/service.js.map +1 -1
- package/dist/tui-command.d.ts +13 -0
- package/dist/tui-command.d.ts.map +1 -0
- package/dist/tui-command.js +378 -0
- package/dist/tui-command.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dsh-plugin.json +41 -0
- package/package.json +6 -1
- package/public.d.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -538,18 +538,18 @@ var ParseStatus = class _ParseStatus {
|
|
|
538
538
|
if (this.value !== "aborted")
|
|
539
539
|
this.value = "aborted";
|
|
540
540
|
}
|
|
541
|
-
static mergeArray(
|
|
541
|
+
static mergeArray(status2, results) {
|
|
542
542
|
const arrayValue = [];
|
|
543
543
|
for (const s2 of results) {
|
|
544
544
|
if (s2.status === "aborted")
|
|
545
545
|
return INVALID;
|
|
546
546
|
if (s2.status === "dirty")
|
|
547
|
-
|
|
547
|
+
status2.dirty();
|
|
548
548
|
arrayValue.push(s2.value);
|
|
549
549
|
}
|
|
550
|
-
return { status:
|
|
550
|
+
return { status: status2.value, value: arrayValue };
|
|
551
551
|
}
|
|
552
|
-
static async mergeObjectAsync(
|
|
552
|
+
static async mergeObjectAsync(status2, pairs) {
|
|
553
553
|
const syncPairs = [];
|
|
554
554
|
for (const pair of pairs) {
|
|
555
555
|
const key = await pair.key;
|
|
@@ -559,9 +559,9 @@ var ParseStatus = class _ParseStatus {
|
|
|
559
559
|
value
|
|
560
560
|
});
|
|
561
561
|
}
|
|
562
|
-
return _ParseStatus.mergeObjectSync(
|
|
562
|
+
return _ParseStatus.mergeObjectSync(status2, syncPairs);
|
|
563
563
|
}
|
|
564
|
-
static mergeObjectSync(
|
|
564
|
+
static mergeObjectSync(status2, pairs) {
|
|
565
565
|
const finalObject = {};
|
|
566
566
|
for (const pair of pairs) {
|
|
567
567
|
const { key, value } = pair;
|
|
@@ -570,14 +570,14 @@ var ParseStatus = class _ParseStatus {
|
|
|
570
570
|
if (value.status === "aborted")
|
|
571
571
|
return INVALID;
|
|
572
572
|
if (key.status === "dirty")
|
|
573
|
-
|
|
573
|
+
status2.dirty();
|
|
574
574
|
if (value.status === "dirty")
|
|
575
|
-
|
|
575
|
+
status2.dirty();
|
|
576
576
|
if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {
|
|
577
577
|
finalObject[key.value] = value.value;
|
|
578
578
|
}
|
|
579
579
|
}
|
|
580
|
-
return { status:
|
|
580
|
+
return { status: status2.value, value: finalObject };
|
|
581
581
|
}
|
|
582
582
|
};
|
|
583
583
|
var INVALID = Object.freeze({
|
|
@@ -1037,7 +1037,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1037
1037
|
});
|
|
1038
1038
|
return INVALID;
|
|
1039
1039
|
}
|
|
1040
|
-
const
|
|
1040
|
+
const status2 = new ParseStatus();
|
|
1041
1041
|
let ctx = void 0;
|
|
1042
1042
|
for (const check of this._def.checks) {
|
|
1043
1043
|
if (check.kind === "min") {
|
|
@@ -1051,7 +1051,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1051
1051
|
exact: false,
|
|
1052
1052
|
message: check.message
|
|
1053
1053
|
});
|
|
1054
|
-
|
|
1054
|
+
status2.dirty();
|
|
1055
1055
|
}
|
|
1056
1056
|
} else if (check.kind === "max") {
|
|
1057
1057
|
if (input2.data.length > check.value) {
|
|
@@ -1064,7 +1064,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1064
1064
|
exact: false,
|
|
1065
1065
|
message: check.message
|
|
1066
1066
|
});
|
|
1067
|
-
|
|
1067
|
+
status2.dirty();
|
|
1068
1068
|
}
|
|
1069
1069
|
} else if (check.kind === "length") {
|
|
1070
1070
|
const tooBig = input2.data.length > check.value;
|
|
@@ -1090,7 +1090,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1090
1090
|
message: check.message
|
|
1091
1091
|
});
|
|
1092
1092
|
}
|
|
1093
|
-
|
|
1093
|
+
status2.dirty();
|
|
1094
1094
|
}
|
|
1095
1095
|
} else if (check.kind === "email") {
|
|
1096
1096
|
if (!emailRegex.test(input2.data)) {
|
|
@@ -1100,7 +1100,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1100
1100
|
code: ZodIssueCode.invalid_string,
|
|
1101
1101
|
message: check.message
|
|
1102
1102
|
});
|
|
1103
|
-
|
|
1103
|
+
status2.dirty();
|
|
1104
1104
|
}
|
|
1105
1105
|
} else if (check.kind === "emoji") {
|
|
1106
1106
|
if (!emojiRegex) {
|
|
@@ -1113,7 +1113,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1113
1113
|
code: ZodIssueCode.invalid_string,
|
|
1114
1114
|
message: check.message
|
|
1115
1115
|
});
|
|
1116
|
-
|
|
1116
|
+
status2.dirty();
|
|
1117
1117
|
}
|
|
1118
1118
|
} else if (check.kind === "uuid") {
|
|
1119
1119
|
if (!uuidRegex.test(input2.data)) {
|
|
@@ -1123,7 +1123,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1123
1123
|
code: ZodIssueCode.invalid_string,
|
|
1124
1124
|
message: check.message
|
|
1125
1125
|
});
|
|
1126
|
-
|
|
1126
|
+
status2.dirty();
|
|
1127
1127
|
}
|
|
1128
1128
|
} else if (check.kind === "nanoid") {
|
|
1129
1129
|
if (!nanoidRegex.test(input2.data)) {
|
|
@@ -1133,7 +1133,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1133
1133
|
code: ZodIssueCode.invalid_string,
|
|
1134
1134
|
message: check.message
|
|
1135
1135
|
});
|
|
1136
|
-
|
|
1136
|
+
status2.dirty();
|
|
1137
1137
|
}
|
|
1138
1138
|
} else if (check.kind === "cuid") {
|
|
1139
1139
|
if (!cuidRegex.test(input2.data)) {
|
|
@@ -1143,7 +1143,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1143
1143
|
code: ZodIssueCode.invalid_string,
|
|
1144
1144
|
message: check.message
|
|
1145
1145
|
});
|
|
1146
|
-
|
|
1146
|
+
status2.dirty();
|
|
1147
1147
|
}
|
|
1148
1148
|
} else if (check.kind === "cuid2") {
|
|
1149
1149
|
if (!cuid2Regex.test(input2.data)) {
|
|
@@ -1153,7 +1153,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1153
1153
|
code: ZodIssueCode.invalid_string,
|
|
1154
1154
|
message: check.message
|
|
1155
1155
|
});
|
|
1156
|
-
|
|
1156
|
+
status2.dirty();
|
|
1157
1157
|
}
|
|
1158
1158
|
} else if (check.kind === "ulid") {
|
|
1159
1159
|
if (!ulidRegex.test(input2.data)) {
|
|
@@ -1163,7 +1163,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1163
1163
|
code: ZodIssueCode.invalid_string,
|
|
1164
1164
|
message: check.message
|
|
1165
1165
|
});
|
|
1166
|
-
|
|
1166
|
+
status2.dirty();
|
|
1167
1167
|
}
|
|
1168
1168
|
} else if (check.kind === "url") {
|
|
1169
1169
|
try {
|
|
@@ -1175,7 +1175,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1175
1175
|
code: ZodIssueCode.invalid_string,
|
|
1176
1176
|
message: check.message
|
|
1177
1177
|
});
|
|
1178
|
-
|
|
1178
|
+
status2.dirty();
|
|
1179
1179
|
}
|
|
1180
1180
|
} else if (check.kind === "regex") {
|
|
1181
1181
|
check.regex.lastIndex = 0;
|
|
@@ -1187,7 +1187,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1187
1187
|
code: ZodIssueCode.invalid_string,
|
|
1188
1188
|
message: check.message
|
|
1189
1189
|
});
|
|
1190
|
-
|
|
1190
|
+
status2.dirty();
|
|
1191
1191
|
}
|
|
1192
1192
|
} else if (check.kind === "trim") {
|
|
1193
1193
|
input2.data = input2.data.trim();
|
|
@@ -1199,7 +1199,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1199
1199
|
validation: { includes: check.value, position: check.position },
|
|
1200
1200
|
message: check.message
|
|
1201
1201
|
});
|
|
1202
|
-
|
|
1202
|
+
status2.dirty();
|
|
1203
1203
|
}
|
|
1204
1204
|
} else if (check.kind === "toLowerCase") {
|
|
1205
1205
|
input2.data = input2.data.toLowerCase();
|
|
@@ -1213,7 +1213,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1213
1213
|
validation: { startsWith: check.value },
|
|
1214
1214
|
message: check.message
|
|
1215
1215
|
});
|
|
1216
|
-
|
|
1216
|
+
status2.dirty();
|
|
1217
1217
|
}
|
|
1218
1218
|
} else if (check.kind === "endsWith") {
|
|
1219
1219
|
if (!input2.data.endsWith(check.value)) {
|
|
@@ -1223,7 +1223,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1223
1223
|
validation: { endsWith: check.value },
|
|
1224
1224
|
message: check.message
|
|
1225
1225
|
});
|
|
1226
|
-
|
|
1226
|
+
status2.dirty();
|
|
1227
1227
|
}
|
|
1228
1228
|
} else if (check.kind === "datetime") {
|
|
1229
1229
|
const regex = datetimeRegex(check);
|
|
@@ -1234,7 +1234,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1234
1234
|
validation: "datetime",
|
|
1235
1235
|
message: check.message
|
|
1236
1236
|
});
|
|
1237
|
-
|
|
1237
|
+
status2.dirty();
|
|
1238
1238
|
}
|
|
1239
1239
|
} else if (check.kind === "date") {
|
|
1240
1240
|
const regex = dateRegex;
|
|
@@ -1245,7 +1245,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1245
1245
|
validation: "date",
|
|
1246
1246
|
message: check.message
|
|
1247
1247
|
});
|
|
1248
|
-
|
|
1248
|
+
status2.dirty();
|
|
1249
1249
|
}
|
|
1250
1250
|
} else if (check.kind === "time") {
|
|
1251
1251
|
const regex = timeRegex(check);
|
|
@@ -1256,7 +1256,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1256
1256
|
validation: "time",
|
|
1257
1257
|
message: check.message
|
|
1258
1258
|
});
|
|
1259
|
-
|
|
1259
|
+
status2.dirty();
|
|
1260
1260
|
}
|
|
1261
1261
|
} else if (check.kind === "duration") {
|
|
1262
1262
|
if (!durationRegex.test(input2.data)) {
|
|
@@ -1266,7 +1266,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1266
1266
|
code: ZodIssueCode.invalid_string,
|
|
1267
1267
|
message: check.message
|
|
1268
1268
|
});
|
|
1269
|
-
|
|
1269
|
+
status2.dirty();
|
|
1270
1270
|
}
|
|
1271
1271
|
} else if (check.kind === "ip") {
|
|
1272
1272
|
if (!isValidIP(input2.data, check.version)) {
|
|
@@ -1276,7 +1276,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1276
1276
|
code: ZodIssueCode.invalid_string,
|
|
1277
1277
|
message: check.message
|
|
1278
1278
|
});
|
|
1279
|
-
|
|
1279
|
+
status2.dirty();
|
|
1280
1280
|
}
|
|
1281
1281
|
} else if (check.kind === "jwt") {
|
|
1282
1282
|
if (!isValidJWT(input2.data, check.alg)) {
|
|
@@ -1286,7 +1286,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1286
1286
|
code: ZodIssueCode.invalid_string,
|
|
1287
1287
|
message: check.message
|
|
1288
1288
|
});
|
|
1289
|
-
|
|
1289
|
+
status2.dirty();
|
|
1290
1290
|
}
|
|
1291
1291
|
} else if (check.kind === "cidr") {
|
|
1292
1292
|
if (!isValidCidr(input2.data, check.version)) {
|
|
@@ -1296,7 +1296,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1296
1296
|
code: ZodIssueCode.invalid_string,
|
|
1297
1297
|
message: check.message
|
|
1298
1298
|
});
|
|
1299
|
-
|
|
1299
|
+
status2.dirty();
|
|
1300
1300
|
}
|
|
1301
1301
|
} else if (check.kind === "base64") {
|
|
1302
1302
|
if (!base64Regex.test(input2.data)) {
|
|
@@ -1306,7 +1306,7 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1306
1306
|
code: ZodIssueCode.invalid_string,
|
|
1307
1307
|
message: check.message
|
|
1308
1308
|
});
|
|
1309
|
-
|
|
1309
|
+
status2.dirty();
|
|
1310
1310
|
}
|
|
1311
1311
|
} else if (check.kind === "base64url") {
|
|
1312
1312
|
if (!base64urlRegex.test(input2.data)) {
|
|
@@ -1316,13 +1316,13 @@ var ZodString = class _ZodString extends ZodType {
|
|
|
1316
1316
|
code: ZodIssueCode.invalid_string,
|
|
1317
1317
|
message: check.message
|
|
1318
1318
|
});
|
|
1319
|
-
|
|
1319
|
+
status2.dirty();
|
|
1320
1320
|
}
|
|
1321
1321
|
} else {
|
|
1322
1322
|
util.assertNever(check);
|
|
1323
1323
|
}
|
|
1324
1324
|
}
|
|
1325
|
-
return { status:
|
|
1325
|
+
return { status: status2.value, value: input2.data };
|
|
1326
1326
|
}
|
|
1327
1327
|
_regex(regex, validation, message) {
|
|
1328
1328
|
return this.refinement((data) => regex.test(data), {
|
|
@@ -1598,7 +1598,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
1598
1598
|
return INVALID;
|
|
1599
1599
|
}
|
|
1600
1600
|
let ctx = void 0;
|
|
1601
|
-
const
|
|
1601
|
+
const status2 = new ParseStatus();
|
|
1602
1602
|
for (const check of this._def.checks) {
|
|
1603
1603
|
if (check.kind === "int") {
|
|
1604
1604
|
if (!util.isInteger(input2.data)) {
|
|
@@ -1609,7 +1609,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
1609
1609
|
received: "float",
|
|
1610
1610
|
message: check.message
|
|
1611
1611
|
});
|
|
1612
|
-
|
|
1612
|
+
status2.dirty();
|
|
1613
1613
|
}
|
|
1614
1614
|
} else if (check.kind === "min") {
|
|
1615
1615
|
const tooSmall = check.inclusive ? input2.data < check.value : input2.data <= check.value;
|
|
@@ -1623,7 +1623,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
1623
1623
|
exact: false,
|
|
1624
1624
|
message: check.message
|
|
1625
1625
|
});
|
|
1626
|
-
|
|
1626
|
+
status2.dirty();
|
|
1627
1627
|
}
|
|
1628
1628
|
} else if (check.kind === "max") {
|
|
1629
1629
|
const tooBig = check.inclusive ? input2.data > check.value : input2.data >= check.value;
|
|
@@ -1637,7 +1637,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
1637
1637
|
exact: false,
|
|
1638
1638
|
message: check.message
|
|
1639
1639
|
});
|
|
1640
|
-
|
|
1640
|
+
status2.dirty();
|
|
1641
1641
|
}
|
|
1642
1642
|
} else if (check.kind === "multipleOf") {
|
|
1643
1643
|
if (floatSafeRemainder(input2.data, check.value) !== 0) {
|
|
@@ -1647,7 +1647,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
1647
1647
|
multipleOf: check.value,
|
|
1648
1648
|
message: check.message
|
|
1649
1649
|
});
|
|
1650
|
-
|
|
1650
|
+
status2.dirty();
|
|
1651
1651
|
}
|
|
1652
1652
|
} else if (check.kind === "finite") {
|
|
1653
1653
|
if (!Number.isFinite(input2.data)) {
|
|
@@ -1656,13 +1656,13 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
1656
1656
|
code: ZodIssueCode.not_finite,
|
|
1657
1657
|
message: check.message
|
|
1658
1658
|
});
|
|
1659
|
-
|
|
1659
|
+
status2.dirty();
|
|
1660
1660
|
}
|
|
1661
1661
|
} else {
|
|
1662
1662
|
util.assertNever(check);
|
|
1663
1663
|
}
|
|
1664
1664
|
}
|
|
1665
|
-
return { status:
|
|
1665
|
+
return { status: status2.value, value: input2.data };
|
|
1666
1666
|
}
|
|
1667
1667
|
gte(value, message) {
|
|
1668
1668
|
return this.setLimit("min", value, true, errorUtil.toString(message));
|
|
@@ -1827,7 +1827,7 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
|
|
|
1827
1827
|
return this._getInvalidInput(input2);
|
|
1828
1828
|
}
|
|
1829
1829
|
let ctx = void 0;
|
|
1830
|
-
const
|
|
1830
|
+
const status2 = new ParseStatus();
|
|
1831
1831
|
for (const check of this._def.checks) {
|
|
1832
1832
|
if (check.kind === "min") {
|
|
1833
1833
|
const tooSmall = check.inclusive ? input2.data < check.value : input2.data <= check.value;
|
|
@@ -1840,7 +1840,7 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
|
|
|
1840
1840
|
inclusive: check.inclusive,
|
|
1841
1841
|
message: check.message
|
|
1842
1842
|
});
|
|
1843
|
-
|
|
1843
|
+
status2.dirty();
|
|
1844
1844
|
}
|
|
1845
1845
|
} else if (check.kind === "max") {
|
|
1846
1846
|
const tooBig = check.inclusive ? input2.data > check.value : input2.data >= check.value;
|
|
@@ -1853,7 +1853,7 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
|
|
|
1853
1853
|
inclusive: check.inclusive,
|
|
1854
1854
|
message: check.message
|
|
1855
1855
|
});
|
|
1856
|
-
|
|
1856
|
+
status2.dirty();
|
|
1857
1857
|
}
|
|
1858
1858
|
} else if (check.kind === "multipleOf") {
|
|
1859
1859
|
if (input2.data % check.value !== BigInt(0)) {
|
|
@@ -1863,13 +1863,13 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
|
|
|
1863
1863
|
multipleOf: check.value,
|
|
1864
1864
|
message: check.message
|
|
1865
1865
|
});
|
|
1866
|
-
|
|
1866
|
+
status2.dirty();
|
|
1867
1867
|
}
|
|
1868
1868
|
} else {
|
|
1869
1869
|
util.assertNever(check);
|
|
1870
1870
|
}
|
|
1871
1871
|
}
|
|
1872
|
-
return { status:
|
|
1872
|
+
return { status: status2.value, value: input2.data };
|
|
1873
1873
|
}
|
|
1874
1874
|
_getInvalidInput(input2) {
|
|
1875
1875
|
const ctx = this._getOrReturnCtx(input2);
|
|
@@ -2027,7 +2027,7 @@ var ZodDate = class _ZodDate extends ZodType {
|
|
|
2027
2027
|
});
|
|
2028
2028
|
return INVALID;
|
|
2029
2029
|
}
|
|
2030
|
-
const
|
|
2030
|
+
const status2 = new ParseStatus();
|
|
2031
2031
|
let ctx = void 0;
|
|
2032
2032
|
for (const check of this._def.checks) {
|
|
2033
2033
|
if (check.kind === "min") {
|
|
@@ -2041,7 +2041,7 @@ var ZodDate = class _ZodDate extends ZodType {
|
|
|
2041
2041
|
minimum: check.value,
|
|
2042
2042
|
type: "date"
|
|
2043
2043
|
});
|
|
2044
|
-
|
|
2044
|
+
status2.dirty();
|
|
2045
2045
|
}
|
|
2046
2046
|
} else if (check.kind === "max") {
|
|
2047
2047
|
if (input2.data.getTime() > check.value) {
|
|
@@ -2054,14 +2054,14 @@ var ZodDate = class _ZodDate extends ZodType {
|
|
|
2054
2054
|
maximum: check.value,
|
|
2055
2055
|
type: "date"
|
|
2056
2056
|
});
|
|
2057
|
-
|
|
2057
|
+
status2.dirty();
|
|
2058
2058
|
}
|
|
2059
2059
|
} else {
|
|
2060
2060
|
util.assertNever(check);
|
|
2061
2061
|
}
|
|
2062
2062
|
}
|
|
2063
2063
|
return {
|
|
2064
|
-
status:
|
|
2064
|
+
status: status2.value,
|
|
2065
2065
|
value: new Date(input2.data.getTime())
|
|
2066
2066
|
};
|
|
2067
2067
|
}
|
|
@@ -2247,7 +2247,7 @@ ZodVoid.create = (params) => {
|
|
|
2247
2247
|
};
|
|
2248
2248
|
var ZodArray = class _ZodArray extends ZodType {
|
|
2249
2249
|
_parse(input2) {
|
|
2250
|
-
const { ctx, status } = this._processInputParams(input2);
|
|
2250
|
+
const { ctx, status: status2 } = this._processInputParams(input2);
|
|
2251
2251
|
const def = this._def;
|
|
2252
2252
|
if (ctx.parsedType !== ZodParsedType.array) {
|
|
2253
2253
|
addIssueToContext(ctx, {
|
|
@@ -2270,7 +2270,7 @@ var ZodArray = class _ZodArray extends ZodType {
|
|
|
2270
2270
|
exact: true,
|
|
2271
2271
|
message: def.exactLength.message
|
|
2272
2272
|
});
|
|
2273
|
-
|
|
2273
|
+
status2.dirty();
|
|
2274
2274
|
}
|
|
2275
2275
|
}
|
|
2276
2276
|
if (def.minLength !== null) {
|
|
@@ -2283,7 +2283,7 @@ var ZodArray = class _ZodArray extends ZodType {
|
|
|
2283
2283
|
exact: false,
|
|
2284
2284
|
message: def.minLength.message
|
|
2285
2285
|
});
|
|
2286
|
-
|
|
2286
|
+
status2.dirty();
|
|
2287
2287
|
}
|
|
2288
2288
|
}
|
|
2289
2289
|
if (def.maxLength !== null) {
|
|
@@ -2296,20 +2296,20 @@ var ZodArray = class _ZodArray extends ZodType {
|
|
|
2296
2296
|
exact: false,
|
|
2297
2297
|
message: def.maxLength.message
|
|
2298
2298
|
});
|
|
2299
|
-
|
|
2299
|
+
status2.dirty();
|
|
2300
2300
|
}
|
|
2301
2301
|
}
|
|
2302
2302
|
if (ctx.common.async) {
|
|
2303
2303
|
return Promise.all([...ctx.data].map((item, i) => {
|
|
2304
2304
|
return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));
|
|
2305
2305
|
})).then((result2) => {
|
|
2306
|
-
return ParseStatus.mergeArray(
|
|
2306
|
+
return ParseStatus.mergeArray(status2, result2);
|
|
2307
2307
|
});
|
|
2308
2308
|
}
|
|
2309
2309
|
const result = [...ctx.data].map((item, i) => {
|
|
2310
2310
|
return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));
|
|
2311
2311
|
});
|
|
2312
|
-
return ParseStatus.mergeArray(
|
|
2312
|
+
return ParseStatus.mergeArray(status2, result);
|
|
2313
2313
|
}
|
|
2314
2314
|
get element() {
|
|
2315
2315
|
return this._def.type;
|
|
@@ -2398,7 +2398,7 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
2398
2398
|
});
|
|
2399
2399
|
return INVALID;
|
|
2400
2400
|
}
|
|
2401
|
-
const { status, ctx } = this._processInputParams(input2);
|
|
2401
|
+
const { status: status2, ctx } = this._processInputParams(input2);
|
|
2402
2402
|
const { shape, keys: shapeKeys } = this._getCached();
|
|
2403
2403
|
const extraKeys = [];
|
|
2404
2404
|
if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
|
|
@@ -2433,7 +2433,7 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
2433
2433
|
code: ZodIssueCode.unrecognized_keys,
|
|
2434
2434
|
keys: extraKeys
|
|
2435
2435
|
});
|
|
2436
|
-
|
|
2436
|
+
status2.dirty();
|
|
2437
2437
|
}
|
|
2438
2438
|
} else if (unknownKeys === "strip") {
|
|
2439
2439
|
} else {
|
|
@@ -2467,10 +2467,10 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
2467
2467
|
}
|
|
2468
2468
|
return syncPairs;
|
|
2469
2469
|
}).then((syncPairs) => {
|
|
2470
|
-
return ParseStatus.mergeObjectSync(
|
|
2470
|
+
return ParseStatus.mergeObjectSync(status2, syncPairs);
|
|
2471
2471
|
});
|
|
2472
2472
|
} else {
|
|
2473
|
-
return ParseStatus.mergeObjectSync(
|
|
2473
|
+
return ParseStatus.mergeObjectSync(status2, pairs);
|
|
2474
2474
|
}
|
|
2475
2475
|
}
|
|
2476
2476
|
get shape() {
|
|
@@ -2948,7 +2948,7 @@ function mergeValues(a, b) {
|
|
|
2948
2948
|
}
|
|
2949
2949
|
var ZodIntersection = class extends ZodType {
|
|
2950
2950
|
_parse(input2) {
|
|
2951
|
-
const { status, ctx } = this._processInputParams(input2);
|
|
2951
|
+
const { status: status2, ctx } = this._processInputParams(input2);
|
|
2952
2952
|
const handleParsed = (parsedLeft, parsedRight) => {
|
|
2953
2953
|
if (isAborted(parsedLeft) || isAborted(parsedRight)) {
|
|
2954
2954
|
return INVALID;
|
|
@@ -2961,9 +2961,9 @@ var ZodIntersection = class extends ZodType {
|
|
|
2961
2961
|
return INVALID;
|
|
2962
2962
|
}
|
|
2963
2963
|
if (isDirty(parsedLeft) || isDirty(parsedRight)) {
|
|
2964
|
-
|
|
2964
|
+
status2.dirty();
|
|
2965
2965
|
}
|
|
2966
|
-
return { status:
|
|
2966
|
+
return { status: status2.value, value: merged.data };
|
|
2967
2967
|
};
|
|
2968
2968
|
if (ctx.common.async) {
|
|
2969
2969
|
return Promise.all([
|
|
@@ -3001,7 +3001,7 @@ ZodIntersection.create = (left, right, params) => {
|
|
|
3001
3001
|
};
|
|
3002
3002
|
var ZodTuple = class _ZodTuple extends ZodType {
|
|
3003
3003
|
_parse(input2) {
|
|
3004
|
-
const { status, ctx } = this._processInputParams(input2);
|
|
3004
|
+
const { status: status2, ctx } = this._processInputParams(input2);
|
|
3005
3005
|
if (ctx.parsedType !== ZodParsedType.array) {
|
|
3006
3006
|
addIssueToContext(ctx, {
|
|
3007
3007
|
code: ZodIssueCode.invalid_type,
|
|
@@ -3029,7 +3029,7 @@ var ZodTuple = class _ZodTuple extends ZodType {
|
|
|
3029
3029
|
exact: false,
|
|
3030
3030
|
type: "array"
|
|
3031
3031
|
});
|
|
3032
|
-
|
|
3032
|
+
status2.dirty();
|
|
3033
3033
|
}
|
|
3034
3034
|
const items = [...ctx.data].map((item, itemIndex) => {
|
|
3035
3035
|
const schema = this._def.items[itemIndex] || this._def.rest;
|
|
@@ -3039,10 +3039,10 @@ var ZodTuple = class _ZodTuple extends ZodType {
|
|
|
3039
3039
|
}).filter((x) => !!x);
|
|
3040
3040
|
if (ctx.common.async) {
|
|
3041
3041
|
return Promise.all(items).then((results) => {
|
|
3042
|
-
return ParseStatus.mergeArray(
|
|
3042
|
+
return ParseStatus.mergeArray(status2, results);
|
|
3043
3043
|
});
|
|
3044
3044
|
} else {
|
|
3045
|
-
return ParseStatus.mergeArray(
|
|
3045
|
+
return ParseStatus.mergeArray(status2, items);
|
|
3046
3046
|
}
|
|
3047
3047
|
}
|
|
3048
3048
|
get items() {
|
|
@@ -3074,7 +3074,7 @@ var ZodRecord = class _ZodRecord extends ZodType {
|
|
|
3074
3074
|
return this._def.valueType;
|
|
3075
3075
|
}
|
|
3076
3076
|
_parse(input2) {
|
|
3077
|
-
const { status, ctx } = this._processInputParams(input2);
|
|
3077
|
+
const { status: status2, ctx } = this._processInputParams(input2);
|
|
3078
3078
|
if (ctx.parsedType !== ZodParsedType.object) {
|
|
3079
3079
|
addIssueToContext(ctx, {
|
|
3080
3080
|
code: ZodIssueCode.invalid_type,
|
|
@@ -3094,9 +3094,9 @@ var ZodRecord = class _ZodRecord extends ZodType {
|
|
|
3094
3094
|
});
|
|
3095
3095
|
}
|
|
3096
3096
|
if (ctx.common.async) {
|
|
3097
|
-
return ParseStatus.mergeObjectAsync(
|
|
3097
|
+
return ParseStatus.mergeObjectAsync(status2, pairs);
|
|
3098
3098
|
} else {
|
|
3099
|
-
return ParseStatus.mergeObjectSync(
|
|
3099
|
+
return ParseStatus.mergeObjectSync(status2, pairs);
|
|
3100
3100
|
}
|
|
3101
3101
|
}
|
|
3102
3102
|
get element() {
|
|
@@ -3127,7 +3127,7 @@ var ZodMap = class extends ZodType {
|
|
|
3127
3127
|
return this._def.valueType;
|
|
3128
3128
|
}
|
|
3129
3129
|
_parse(input2) {
|
|
3130
|
-
const { status, ctx } = this._processInputParams(input2);
|
|
3130
|
+
const { status: status2, ctx } = this._processInputParams(input2);
|
|
3131
3131
|
if (ctx.parsedType !== ZodParsedType.map) {
|
|
3132
3132
|
addIssueToContext(ctx, {
|
|
3133
3133
|
code: ZodIssueCode.invalid_type,
|
|
@@ -3154,11 +3154,11 @@ var ZodMap = class extends ZodType {
|
|
|
3154
3154
|
return INVALID;
|
|
3155
3155
|
}
|
|
3156
3156
|
if (key.status === "dirty" || value.status === "dirty") {
|
|
3157
|
-
|
|
3157
|
+
status2.dirty();
|
|
3158
3158
|
}
|
|
3159
3159
|
finalMap.set(key.value, value.value);
|
|
3160
3160
|
}
|
|
3161
|
-
return { status:
|
|
3161
|
+
return { status: status2.value, value: finalMap };
|
|
3162
3162
|
});
|
|
3163
3163
|
} else {
|
|
3164
3164
|
const finalMap = /* @__PURE__ */ new Map();
|
|
@@ -3169,11 +3169,11 @@ var ZodMap = class extends ZodType {
|
|
|
3169
3169
|
return INVALID;
|
|
3170
3170
|
}
|
|
3171
3171
|
if (key.status === "dirty" || value.status === "dirty") {
|
|
3172
|
-
|
|
3172
|
+
status2.dirty();
|
|
3173
3173
|
}
|
|
3174
3174
|
finalMap.set(key.value, value.value);
|
|
3175
3175
|
}
|
|
3176
|
-
return { status:
|
|
3176
|
+
return { status: status2.value, value: finalMap };
|
|
3177
3177
|
}
|
|
3178
3178
|
}
|
|
3179
3179
|
};
|
|
@@ -3187,7 +3187,7 @@ ZodMap.create = (keyType, valueType, params) => {
|
|
|
3187
3187
|
};
|
|
3188
3188
|
var ZodSet = class _ZodSet extends ZodType {
|
|
3189
3189
|
_parse(input2) {
|
|
3190
|
-
const { status, ctx } = this._processInputParams(input2);
|
|
3190
|
+
const { status: status2, ctx } = this._processInputParams(input2);
|
|
3191
3191
|
if (ctx.parsedType !== ZodParsedType.set) {
|
|
3192
3192
|
addIssueToContext(ctx, {
|
|
3193
3193
|
code: ZodIssueCode.invalid_type,
|
|
@@ -3207,7 +3207,7 @@ var ZodSet = class _ZodSet extends ZodType {
|
|
|
3207
3207
|
exact: false,
|
|
3208
3208
|
message: def.minSize.message
|
|
3209
3209
|
});
|
|
3210
|
-
|
|
3210
|
+
status2.dirty();
|
|
3211
3211
|
}
|
|
3212
3212
|
}
|
|
3213
3213
|
if (def.maxSize !== null) {
|
|
@@ -3220,7 +3220,7 @@ var ZodSet = class _ZodSet extends ZodType {
|
|
|
3220
3220
|
exact: false,
|
|
3221
3221
|
message: def.maxSize.message
|
|
3222
3222
|
});
|
|
3223
|
-
|
|
3223
|
+
status2.dirty();
|
|
3224
3224
|
}
|
|
3225
3225
|
}
|
|
3226
3226
|
const valueType = this._def.valueType;
|
|
@@ -3230,10 +3230,10 @@ var ZodSet = class _ZodSet extends ZodType {
|
|
|
3230
3230
|
if (element.status === "aborted")
|
|
3231
3231
|
return INVALID;
|
|
3232
3232
|
if (element.status === "dirty")
|
|
3233
|
-
|
|
3233
|
+
status2.dirty();
|
|
3234
3234
|
parsedSet.add(element.value);
|
|
3235
3235
|
}
|
|
3236
|
-
return { status:
|
|
3236
|
+
return { status: status2.value, value: parsedSet };
|
|
3237
3237
|
}
|
|
3238
3238
|
const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));
|
|
3239
3239
|
if (ctx.common.async) {
|
|
@@ -3564,15 +3564,15 @@ var ZodEffects = class extends ZodType {
|
|
|
3564
3564
|
return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects ? this._def.schema.sourceType() : this._def.schema;
|
|
3565
3565
|
}
|
|
3566
3566
|
_parse(input2) {
|
|
3567
|
-
const { status, ctx } = this._processInputParams(input2);
|
|
3567
|
+
const { status: status2, ctx } = this._processInputParams(input2);
|
|
3568
3568
|
const effect = this._def.effect || null;
|
|
3569
3569
|
const checkCtx = {
|
|
3570
3570
|
addIssue: (arg) => {
|
|
3571
3571
|
addIssueToContext(ctx, arg);
|
|
3572
3572
|
if (arg.fatal) {
|
|
3573
|
-
|
|
3573
|
+
status2.abort();
|
|
3574
3574
|
} else {
|
|
3575
|
-
|
|
3575
|
+
status2.dirty();
|
|
3576
3576
|
}
|
|
3577
3577
|
},
|
|
3578
3578
|
get path() {
|
|
@@ -3584,7 +3584,7 @@ var ZodEffects = class extends ZodType {
|
|
|
3584
3584
|
const processed = effect.transform(ctx.data, checkCtx);
|
|
3585
3585
|
if (ctx.common.async) {
|
|
3586
3586
|
return Promise.resolve(processed).then(async (processed2) => {
|
|
3587
|
-
if (
|
|
3587
|
+
if (status2.value === "aborted")
|
|
3588
3588
|
return INVALID;
|
|
3589
3589
|
const result = await this._def.schema._parseAsync({
|
|
3590
3590
|
data: processed2,
|
|
@@ -3595,12 +3595,12 @@ var ZodEffects = class extends ZodType {
|
|
|
3595
3595
|
return INVALID;
|
|
3596
3596
|
if (result.status === "dirty")
|
|
3597
3597
|
return DIRTY(result.value);
|
|
3598
|
-
if (
|
|
3598
|
+
if (status2.value === "dirty")
|
|
3599
3599
|
return DIRTY(result.value);
|
|
3600
3600
|
return result;
|
|
3601
3601
|
});
|
|
3602
3602
|
} else {
|
|
3603
|
-
if (
|
|
3603
|
+
if (status2.value === "aborted")
|
|
3604
3604
|
return INVALID;
|
|
3605
3605
|
const result = this._def.schema._parseSync({
|
|
3606
3606
|
data: processed,
|
|
@@ -3611,7 +3611,7 @@ var ZodEffects = class extends ZodType {
|
|
|
3611
3611
|
return INVALID;
|
|
3612
3612
|
if (result.status === "dirty")
|
|
3613
3613
|
return DIRTY(result.value);
|
|
3614
|
-
if (
|
|
3614
|
+
if (status2.value === "dirty")
|
|
3615
3615
|
return DIRTY(result.value);
|
|
3616
3616
|
return result;
|
|
3617
3617
|
}
|
|
@@ -3636,17 +3636,17 @@ var ZodEffects = class extends ZodType {
|
|
|
3636
3636
|
if (inner.status === "aborted")
|
|
3637
3637
|
return INVALID;
|
|
3638
3638
|
if (inner.status === "dirty")
|
|
3639
|
-
|
|
3639
|
+
status2.dirty();
|
|
3640
3640
|
executeRefinement(inner.value);
|
|
3641
|
-
return { status:
|
|
3641
|
+
return { status: status2.value, value: inner.value };
|
|
3642
3642
|
} else {
|
|
3643
3643
|
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => {
|
|
3644
3644
|
if (inner.status === "aborted")
|
|
3645
3645
|
return INVALID;
|
|
3646
3646
|
if (inner.status === "dirty")
|
|
3647
|
-
|
|
3647
|
+
status2.dirty();
|
|
3648
3648
|
return executeRefinement(inner.value).then(() => {
|
|
3649
|
-
return { status:
|
|
3649
|
+
return { status: status2.value, value: inner.value };
|
|
3650
3650
|
});
|
|
3651
3651
|
});
|
|
3652
3652
|
}
|
|
@@ -3664,13 +3664,13 @@ var ZodEffects = class extends ZodType {
|
|
|
3664
3664
|
if (result instanceof Promise) {
|
|
3665
3665
|
throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
|
|
3666
3666
|
}
|
|
3667
|
-
return { status:
|
|
3667
|
+
return { status: status2.value, value: result };
|
|
3668
3668
|
} else {
|
|
3669
3669
|
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
|
|
3670
3670
|
if (!isValid(base))
|
|
3671
3671
|
return INVALID;
|
|
3672
3672
|
return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
|
|
3673
|
-
status:
|
|
3673
|
+
status: status2.value,
|
|
3674
3674
|
value: result
|
|
3675
3675
|
}));
|
|
3676
3676
|
});
|
|
@@ -3849,7 +3849,7 @@ var ZodBranded = class extends ZodType {
|
|
|
3849
3849
|
};
|
|
3850
3850
|
var ZodPipeline = class _ZodPipeline extends ZodType {
|
|
3851
3851
|
_parse(input2) {
|
|
3852
|
-
const { status, ctx } = this._processInputParams(input2);
|
|
3852
|
+
const { status: status2, ctx } = this._processInputParams(input2);
|
|
3853
3853
|
if (ctx.common.async) {
|
|
3854
3854
|
const handleAsync = async () => {
|
|
3855
3855
|
const inResult = await this._def.in._parseAsync({
|
|
@@ -3860,7 +3860,7 @@ var ZodPipeline = class _ZodPipeline extends ZodType {
|
|
|
3860
3860
|
if (inResult.status === "aborted")
|
|
3861
3861
|
return INVALID;
|
|
3862
3862
|
if (inResult.status === "dirty") {
|
|
3863
|
-
|
|
3863
|
+
status2.dirty();
|
|
3864
3864
|
return DIRTY(inResult.value);
|
|
3865
3865
|
} else {
|
|
3866
3866
|
return this._def.out._parseAsync({
|
|
@@ -3880,7 +3880,7 @@ var ZodPipeline = class _ZodPipeline extends ZodType {
|
|
|
3880
3880
|
if (inResult.status === "aborted")
|
|
3881
3881
|
return INVALID;
|
|
3882
3882
|
if (inResult.status === "dirty") {
|
|
3883
|
-
|
|
3883
|
+
status2.dirty();
|
|
3884
3884
|
return {
|
|
3885
3885
|
status: "dirty",
|
|
3886
3886
|
value: inResult.value
|
|
@@ -4631,6 +4631,39 @@ function projectCodexThread(value) {
|
|
|
4631
4631
|
...typeof value.isPinned === "boolean" ? { pinned: value.isPinned } : {}
|
|
4632
4632
|
};
|
|
4633
4633
|
}
|
|
4634
|
+
function deriveCodexCwdWorkspaces(values) {
|
|
4635
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
4636
|
+
const usedIds = /* @__PURE__ */ new Set();
|
|
4637
|
+
for (const value of values) {
|
|
4638
|
+
const session = projectCodexThread(value);
|
|
4639
|
+
if (session === void 0 || session.cwd === void 0 || session.cwd.length === 0)
|
|
4640
|
+
continue;
|
|
4641
|
+
const path = session.cwd;
|
|
4642
|
+
if (!isAbsoluteWorkspacePath(path))
|
|
4643
|
+
continue;
|
|
4644
|
+
const key = normalizeWorkspacePath(path);
|
|
4645
|
+
const existing = byPath.get(key);
|
|
4646
|
+
if (existing !== void 0) {
|
|
4647
|
+
existing.createdAt = earliestTimestamp(existing.createdAt, session.createdAt);
|
|
4648
|
+
existing.updatedAt = Math.max(existing.updatedAt, session.updatedAt);
|
|
4649
|
+
continue;
|
|
4650
|
+
}
|
|
4651
|
+
const baseId = `cwd-${hashWorkspacePath(key)}`;
|
|
4652
|
+
let id2 = baseId;
|
|
4653
|
+
for (let suffix = 2; usedIds.has(id2); suffix += 1)
|
|
4654
|
+
id2 = `${baseId}-${suffix}`;
|
|
4655
|
+
usedIds.add(id2);
|
|
4656
|
+
byPath.set(key, {
|
|
4657
|
+
id: id2,
|
|
4658
|
+
name: workspaceBasename(path),
|
|
4659
|
+
path,
|
|
4660
|
+
position: byPath.size,
|
|
4661
|
+
createdAt: session.createdAt,
|
|
4662
|
+
updatedAt: session.updatedAt
|
|
4663
|
+
});
|
|
4664
|
+
}
|
|
4665
|
+
return [...byPath.values()];
|
|
4666
|
+
}
|
|
4634
4667
|
function projectCodexHistory(thread) {
|
|
4635
4668
|
if (!isRecord(thread) || typeof thread.id !== "string" || !Array.isArray(thread.turns))
|
|
4636
4669
|
return [];
|
|
@@ -4884,6 +4917,31 @@ function boundedText(value) {
|
|
|
4884
4917
|
return value.length <= MAX_DISPLAY_ITEM_TEXT ? value : `${value.slice(0, MAX_DISPLAY_ITEM_TEXT)}
|
|
4885
4918
|
\u2026`;
|
|
4886
4919
|
}
|
|
4920
|
+
function normalizeWorkspacePath(value) {
|
|
4921
|
+
return value.replace(/[\\/]+$/u, "") || value;
|
|
4922
|
+
}
|
|
4923
|
+
function isAbsoluteWorkspacePath(value) {
|
|
4924
|
+
return value.startsWith("/") || /^\\\\[^\\]+\\[^\\]+/u.test(value) || /^[A-Za-z]:[\\/]/u.test(value);
|
|
4925
|
+
}
|
|
4926
|
+
function workspaceBasename(value) {
|
|
4927
|
+
const normalized = normalizeWorkspacePath(value);
|
|
4928
|
+
return normalized.split(/[\\/]/u).at(-1) || value;
|
|
4929
|
+
}
|
|
4930
|
+
function earliestTimestamp(left, right) {
|
|
4931
|
+
if (left <= 0)
|
|
4932
|
+
return right;
|
|
4933
|
+
if (right <= 0)
|
|
4934
|
+
return left;
|
|
4935
|
+
return Math.min(left, right);
|
|
4936
|
+
}
|
|
4937
|
+
function hashWorkspacePath(value) {
|
|
4938
|
+
let hash = 2166136261;
|
|
4939
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
4940
|
+
hash ^= value.charCodeAt(index);
|
|
4941
|
+
hash = Math.imul(hash, 16777619);
|
|
4942
|
+
}
|
|
4943
|
+
return (hash >>> 0).toString(36);
|
|
4944
|
+
}
|
|
4887
4945
|
function normalizeTimestamp(value) {
|
|
4888
4946
|
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0)
|
|
4889
4947
|
return 0;
|
|
@@ -4976,13 +5034,13 @@ var RemoteClientCore = class {
|
|
|
4976
5034
|
if (signal?.aborted)
|
|
4977
5035
|
throw rpcAbortedError(method, signal.reason);
|
|
4978
5036
|
const request = createRpcRequest(method, params);
|
|
4979
|
-
const result = new Promise((
|
|
5037
|
+
const result = new Promise((resolve3, reject) => {
|
|
4980
5038
|
const timer = setTimeout(() => {
|
|
4981
5039
|
this.rejectPending(request.id, new RemoteClientError("RPC_TIMEOUT", `RPC ${method} timed out after ${this.timeoutMs}ms`));
|
|
4982
5040
|
}, this.timeoutMs);
|
|
4983
5041
|
const pending = {
|
|
4984
5042
|
method,
|
|
4985
|
-
resolve:
|
|
5043
|
+
resolve: resolve3,
|
|
4986
5044
|
reject,
|
|
4987
5045
|
timer
|
|
4988
5046
|
};
|
|
@@ -5546,8 +5604,8 @@ var RtcDataChannelTransport = class {
|
|
|
5546
5604
|
if (this.connectPromise !== void 0)
|
|
5547
5605
|
return this.connectPromise;
|
|
5548
5606
|
this.armAbort(signal);
|
|
5549
|
-
this.connectPromise = new Promise((
|
|
5550
|
-
this.openResolve =
|
|
5607
|
+
this.connectPromise = new Promise((resolve3, reject) => {
|
|
5608
|
+
this.openResolve = resolve3;
|
|
5551
5609
|
this.openReject = reject;
|
|
5552
5610
|
this.negotiateTimer = setTimeout(() => {
|
|
5553
5611
|
void this.failOpenAfterStats(new RtcConnectError("RTC_CONNECT_TIMEOUT", `WebRTC negotiation timed out after ${this.negotiateTimeoutMs}ms.`));
|
|
@@ -5762,9 +5820,9 @@ var RtcDataChannelTransport = class {
|
|
|
5762
5820
|
if (this.closed || this.opened)
|
|
5763
5821
|
return;
|
|
5764
5822
|
this.opened = true;
|
|
5765
|
-
const
|
|
5823
|
+
const resolve3 = this.openResolve;
|
|
5766
5824
|
this.clearNegotiation();
|
|
5767
|
-
void this.resolveSelectedTransport().then(() =>
|
|
5825
|
+
void this.resolveSelectedTransport().then(() => resolve3?.());
|
|
5768
5826
|
};
|
|
5769
5827
|
channel.onmessage = (event) => {
|
|
5770
5828
|
if (this.closed || !this.opened)
|
|
@@ -6158,7 +6216,7 @@ function asError(error) {
|
|
|
6158
6216
|
return error instanceof Error ? error : new RtcConnectError("RTC_FAILED", "WebRTC negotiation failed.");
|
|
6159
6217
|
}
|
|
6160
6218
|
function sleep(ms) {
|
|
6161
|
-
return new Promise((
|
|
6219
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
6162
6220
|
}
|
|
6163
6221
|
|
|
6164
6222
|
// ../webrtc/dist/adaptive-transport.js
|
|
@@ -6196,8 +6254,8 @@ var AdaptiveTransport = class extends BaseTransport {
|
|
|
6196
6254
|
this.socket = new WebSocket(this.url);
|
|
6197
6255
|
this.controlFrameLimits = {};
|
|
6198
6256
|
this.socket.binaryType = "arraybuffer";
|
|
6199
|
-
await new Promise((
|
|
6200
|
-
this.readyResolve =
|
|
6257
|
+
await new Promise((resolve3, reject) => {
|
|
6258
|
+
this.readyResolve = resolve3;
|
|
6201
6259
|
this.readyReject = reject;
|
|
6202
6260
|
this.handshakeTimer = setTimeout(() => this.failConnection(new Error("Adaptive control handshake timed out")), this.options.handshakeTimeoutMs ?? 15e3);
|
|
6203
6261
|
const socket = this.socket;
|
|
@@ -13774,7 +13832,7 @@ var ClientSecureTransport = class {
|
|
|
13774
13832
|
}
|
|
13775
13833
|
};
|
|
13776
13834
|
async function waitForResponder(inner, noise) {
|
|
13777
|
-
await new Promise((
|
|
13835
|
+
await new Promise((resolve3, reject) => {
|
|
13778
13836
|
let settled = false;
|
|
13779
13837
|
const timer = setTimeout(() => finish(new Error("Noise IK handshake timed out.")), 1e4);
|
|
13780
13838
|
const unsubscribe = inner.onHandshake((step, data) => {
|
|
@@ -13793,7 +13851,7 @@ async function waitForResponder(inner, noise) {
|
|
|
13793
13851
|
settled = true;
|
|
13794
13852
|
clearTimeout(timer);
|
|
13795
13853
|
unsubscribe();
|
|
13796
|
-
if (error === void 0)
|
|
13854
|
+
if (error === void 0) resolve3();
|
|
13797
13855
|
else reject(error);
|
|
13798
13856
|
};
|
|
13799
13857
|
void inner.sendHandshake(1, noise.writeHandshake()).catch((error) => {
|
|
@@ -14051,7 +14109,7 @@ var AsyncFrameQueue = class {
|
|
|
14051
14109
|
continue;
|
|
14052
14110
|
}
|
|
14053
14111
|
if (this.closed) return;
|
|
14054
|
-
const next = await new Promise((
|
|
14112
|
+
const next = await new Promise((resolve3) => this.waiters.push(resolve3));
|
|
14055
14113
|
if (next.done) return;
|
|
14056
14114
|
yield next.value;
|
|
14057
14115
|
}
|
|
@@ -14239,7 +14297,7 @@ var AsyncValueQueue = class {
|
|
|
14239
14297
|
if (this.error !== void 0) throw this.error;
|
|
14240
14298
|
return;
|
|
14241
14299
|
}
|
|
14242
|
-
const next = await new Promise((
|
|
14300
|
+
const next = await new Promise((resolve3) => this.waiters.push(resolve3));
|
|
14243
14301
|
if (next.done) {
|
|
14244
14302
|
if (this.error !== void 0) throw this.error;
|
|
14245
14303
|
return;
|
|
@@ -14471,15 +14529,21 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14471
14529
|
case "session/selectModel":
|
|
14472
14530
|
return business(await this.selectModel(requestArg(args), signal));
|
|
14473
14531
|
case "session/canOpenWorkspacePath":
|
|
14474
|
-
return business(
|
|
14532
|
+
return business(this.selectedWorkspaceId !== void 0);
|
|
14475
14533
|
case "session/openWorkspacePath":
|
|
14476
14534
|
return business(failure("bad-request", "Opening Host paths is unavailable in CodeX mode."));
|
|
14535
|
+
case "host/describe":
|
|
14536
|
+
return business(success(await this.describeHost(signal)));
|
|
14537
|
+
case "host/listDirectory":
|
|
14538
|
+
return business(await this.listDirectory(requestArg(args), signal));
|
|
14539
|
+
case "directoryPicker/list":
|
|
14540
|
+
return business(await this.listDirectory(requestArg(args), signal));
|
|
14477
14541
|
case "skills/list":
|
|
14478
14542
|
return business(success({ items: [] }));
|
|
14479
14543
|
case "commands/list":
|
|
14480
14544
|
return ok(this.commandList(args));
|
|
14481
14545
|
case "commands/execute":
|
|
14482
|
-
return ok(this.executeCommand(args));
|
|
14546
|
+
return ok(await this.executeCommand(args, signal));
|
|
14483
14547
|
default:
|
|
14484
14548
|
return fail("method-not-found", `CodeX virtual Harness does not implement ${endpoint}.`);
|
|
14485
14549
|
}
|
|
@@ -14553,6 +14617,10 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14553
14617
|
permissionSelection(sessionId) {
|
|
14554
14618
|
return this.selectedPermissions.get(sessionId) ?? CODEX_DEFAULT_PERMISSION;
|
|
14555
14619
|
}
|
|
14620
|
+
setPermissionSelection(sessionId, preset) {
|
|
14621
|
+
this.selectedPermissions.set(sessionId, preset);
|
|
14622
|
+
this.publishProjection(sessionId, "permissions", codexPermissionsProjection(preset), this.nextProjectionSeq());
|
|
14623
|
+
}
|
|
14556
14624
|
commandList(args) {
|
|
14557
14625
|
nativeThreadId(requiredString(args.agentId, "agentId"));
|
|
14558
14626
|
return [{
|
|
@@ -14561,9 +14629,9 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14561
14629
|
input: { hint: "<preset>" }
|
|
14562
14630
|
}];
|
|
14563
14631
|
}
|
|
14564
|
-
executeCommand(args) {
|
|
14632
|
+
async executeCommand(args, signal) {
|
|
14565
14633
|
const sessionId = requiredString(args.agentId, "agentId");
|
|
14566
|
-
nativeThreadId(sessionId);
|
|
14634
|
+
const threadId = nativeThreadId(sessionId);
|
|
14567
14635
|
const line = requiredString(args.line, "command line").trim();
|
|
14568
14636
|
if (!Array.isArray(args.images)) throw new Error("The CodeX command image list is required.");
|
|
14569
14637
|
const match = /^\/permission(?:\s+([\s\S]*))?$/u.exec(line);
|
|
@@ -14582,9 +14650,10 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14582
14650
|
commandId,
|
|
14583
14651
|
result: { kind: "error", text: `unknown preset "${requested}" (available: workspace-write, danger-full-access)` }
|
|
14584
14652
|
};
|
|
14585
|
-
this.
|
|
14586
|
-
|
|
14587
|
-
|
|
14653
|
+
const result = await this.client.request("thread/resume", { threadId, permissionPreset: requested }, signal);
|
|
14654
|
+
const effective = codexPermissionPresetFromResponse(result) ?? requested;
|
|
14655
|
+
this.setPermissionSelection(sessionId, effective);
|
|
14656
|
+
return { commandId, result: { kind: "success", text: `preset ${effective}` } };
|
|
14588
14657
|
}
|
|
14589
14658
|
sessionTitle(sessionId) {
|
|
14590
14659
|
const session = this.catalog?.sessions.find((item) => item.id === sessionId);
|
|
@@ -14728,7 +14797,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14728
14797
|
queue,
|
|
14729
14798
|
nextSeq: history.cursor + 1,
|
|
14730
14799
|
turn: history.nextTurn,
|
|
14731
|
-
stepOpen:
|
|
14800
|
+
stepOpen: history.activeTurnId !== void 0,
|
|
14732
14801
|
startedItems: /* @__PURE__ */ new Set(),
|
|
14733
14802
|
completedItems: /* @__PURE__ */ new Set(),
|
|
14734
14803
|
streamedBlocks: /* @__PURE__ */ new Map(),
|
|
@@ -14737,7 +14806,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14737
14806
|
liveItems: /* @__PURE__ */ new Map(),
|
|
14738
14807
|
liveToolOutput: /* @__PURE__ */ new Map(),
|
|
14739
14808
|
liveToolResultSeq: /* @__PURE__ */ new Map(),
|
|
14740
|
-
requestId: this.pendingRequestIds.get(sessionId)
|
|
14809
|
+
requestId: this.pendingRequestIds.get(sessionId),
|
|
14810
|
+
...history.activeTurnId === void 0 ? {} : { activeTurnId: history.activeTurnId }
|
|
14741
14811
|
};
|
|
14742
14812
|
this.follows.add(follow);
|
|
14743
14813
|
queue.push({
|
|
@@ -14786,6 +14856,11 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14786
14856
|
this.publishProjection(follow.sessionId, "title", title, seq);
|
|
14787
14857
|
return;
|
|
14788
14858
|
}
|
|
14859
|
+
if (frame.method === "thread/settings/updated") {
|
|
14860
|
+
const preset = codexPermissionPresetFromResponse(params);
|
|
14861
|
+
if (preset !== void 0) this.setPermissionSelection(follow.sessionId, preset);
|
|
14862
|
+
return;
|
|
14863
|
+
}
|
|
14789
14864
|
if (frame.method === "turn/started") {
|
|
14790
14865
|
const turn = record(params.turn);
|
|
14791
14866
|
this.resetLiveTurn(follow);
|
|
@@ -14840,8 +14915,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14840
14915
|
const item = record(value);
|
|
14841
14916
|
const content = string(item.step);
|
|
14842
14917
|
if (content === void 0) return [];
|
|
14843
|
-
const
|
|
14844
|
-
return [{ content, status }];
|
|
14918
|
+
const status2 = item.status === "inProgress" ? "in_progress" : item.status === "completed" ? "completed" : "pending";
|
|
14919
|
+
return [{ content, status: status2 }];
|
|
14845
14920
|
});
|
|
14846
14921
|
this.pushEvent(follow, "todo/write", { todos });
|
|
14847
14922
|
return;
|
|
@@ -14871,10 +14946,10 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14871
14946
|
return;
|
|
14872
14947
|
}
|
|
14873
14948
|
if (frame.method === "thread/status/changed") {
|
|
14874
|
-
const
|
|
14875
|
-
const running =
|
|
14949
|
+
const status2 = record(params.status);
|
|
14950
|
+
const running = status2.type === "active";
|
|
14876
14951
|
this.emitRemoteEvent("api-session/status", [follow.sessionId, running]);
|
|
14877
|
-
if (
|
|
14952
|
+
if (status2.type === "systemError") {
|
|
14878
14953
|
this.broadcastRcHost({
|
|
14879
14954
|
type: "host/agent-error",
|
|
14880
14955
|
sessionId: follow.sessionId,
|
|
@@ -15154,6 +15229,46 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15154
15229
|
const workspace = catalog.workspaces.find((item) => sessionId !== void 0 && item.sessionIds.includes(sessionId));
|
|
15155
15230
|
return workspace === void 0 ? failure("workspace-not-found", "The CodeX virtual Workspace was not found.") : success({ workspace: nativeWorkspace(workspace) });
|
|
15156
15231
|
}
|
|
15232
|
+
selectedWorkspace(catalog) {
|
|
15233
|
+
return this.selectedWorkspaceId === void 0 ? void 0 : catalog.workspaces.find((item) => item.workspaceId === this.selectedWorkspaceId);
|
|
15234
|
+
}
|
|
15235
|
+
async describeHost(signal) {
|
|
15236
|
+
const catalog = await this.currentCatalog(signal);
|
|
15237
|
+
const workspace = this.selectedWorkspace(catalog);
|
|
15238
|
+
const models = await this.models(signal).catch(() => void 0);
|
|
15239
|
+
return {
|
|
15240
|
+
version: "CodeX Remote",
|
|
15241
|
+
cwd: workspace?.path ?? "",
|
|
15242
|
+
home: workspace?.path ?? "",
|
|
15243
|
+
provider: "CodeX",
|
|
15244
|
+
...models === void 0 ? {} : { model: models.default.model },
|
|
15245
|
+
attachedSessions: catalog.sessions.length,
|
|
15246
|
+
canOpenPath: workspace !== void 0
|
|
15247
|
+
};
|
|
15248
|
+
}
|
|
15249
|
+
async listDirectory(request, signal) {
|
|
15250
|
+
const catalog = await this.currentCatalog(signal);
|
|
15251
|
+
const workspace = this.selectedWorkspace(catalog);
|
|
15252
|
+
if (workspace === void 0) return failure("workspace-not-found", "The CodeX virtual Workspace was not found.");
|
|
15253
|
+
const path = string(request.path) ?? workspace.path;
|
|
15254
|
+
if (!containsPath(workspace.path, path)) {
|
|
15255
|
+
return failure("workspace-not-found", "The selected directory is outside the current CodeX virtual Workspace.");
|
|
15256
|
+
}
|
|
15257
|
+
const listing = record(await this.client.request("dsh/directoryList", { path }, signal));
|
|
15258
|
+
if (!isCodexDirectoryListing(listing)) {
|
|
15259
|
+
return failure("internal", "CodeX Remote returned an invalid directory listing.");
|
|
15260
|
+
}
|
|
15261
|
+
const listedPaths = [
|
|
15262
|
+
listing.path,
|
|
15263
|
+
listing.home,
|
|
15264
|
+
...listing.crumbs.map((item) => item.path),
|
|
15265
|
+
...listing.entries.map((item) => item.path)
|
|
15266
|
+
];
|
|
15267
|
+
if (listedPaths.some((path2) => !containsPath(workspace.path, path2))) {
|
|
15268
|
+
return failure("internal", "CodeX Remote returned a directory outside the current Workspace.");
|
|
15269
|
+
}
|
|
15270
|
+
return success(listing);
|
|
15271
|
+
}
|
|
15157
15272
|
async archiveSession(request, signal) {
|
|
15158
15273
|
const sessionId = requiredString(request.sessionId, "sessionId");
|
|
15159
15274
|
await this.client.request("thread/archive", { threadId: nativeThreadId(sessionId) }, signal);
|
|
@@ -15164,16 +15279,21 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15164
15279
|
async createSession(request, signal) {
|
|
15165
15280
|
const catalog = await this.currentCatalog(signal);
|
|
15166
15281
|
const workspaceId = string(request.workspaceId) ?? this.selectedWorkspaceId;
|
|
15167
|
-
const
|
|
15282
|
+
const workspace = workspaceId === void 0 ? void 0 : catalog.workspaces.find((item) => item.workspaceId === workspaceId);
|
|
15283
|
+
const cwd = string(request.cwd) ?? workspace?.path;
|
|
15168
15284
|
if (cwd === void 0) return failure("workspace-not-found", "The CodeX virtual Workspace was not found.");
|
|
15285
|
+
if (workspace !== void 0 && !containsPath(workspace.path, cwd)) {
|
|
15286
|
+
return failure("workspace-not-found", "The selected directory is outside the current CodeX virtual Workspace.");
|
|
15287
|
+
}
|
|
15169
15288
|
const directory = await this.models(signal);
|
|
15170
15289
|
const selection = directory.default;
|
|
15171
|
-
const
|
|
15290
|
+
const requestedPreset = CODEX_DEFAULT_PERMISSION;
|
|
15172
15291
|
const result = record(await this.client.request("thread/start", {
|
|
15173
15292
|
cwd,
|
|
15174
15293
|
model: selection.model,
|
|
15175
|
-
permissionPreset:
|
|
15294
|
+
permissionPreset: requestedPreset
|
|
15176
15295
|
}, signal));
|
|
15296
|
+
const permissionPreset2 = codexPermissionPresetFromResponse(result) ?? requestedPreset;
|
|
15177
15297
|
const thread = { ...record(result.thread), cwd, turns: array(record(result.thread).turns) };
|
|
15178
15298
|
const projected = projectCodexThread(thread);
|
|
15179
15299
|
if (projected === void 0) return failure("internal", "CodeX returned an invalid Thread.");
|
|
@@ -15194,11 +15314,12 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15194
15314
|
}
|
|
15195
15315
|
async forkSession(request, signal) {
|
|
15196
15316
|
const sessionId = requiredString(request.sessionId, "sessionId");
|
|
15197
|
-
|
|
15317
|
+
let permissionPreset2 = this.selectedPermissions.get(sessionId);
|
|
15198
15318
|
const result = record(await this.client.request("thread/fork", {
|
|
15199
15319
|
threadId: nativeThreadId(sessionId),
|
|
15200
|
-
permissionPreset: permissionPreset2
|
|
15320
|
+
...permissionPreset2 === void 0 ? {} : { permissionPreset: permissionPreset2 }
|
|
15201
15321
|
}, signal));
|
|
15322
|
+
permissionPreset2 = codexPermissionPresetFromResponse(result) ?? permissionPreset2 ?? CODEX_DEFAULT_PERMISSION;
|
|
15202
15323
|
const projected = projectCodexThread(record(result.thread));
|
|
15203
15324
|
if (projected === void 0) return failure("internal", "CodeX returned an invalid forked Thread.");
|
|
15204
15325
|
this.selectedModels.set(projected.id, this.modelSelection(sessionId, await this.models(signal)));
|
|
@@ -15215,14 +15336,20 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15215
15336
|
if (input2 === void 0) return failure("attachment-error", "CodeX virtual Sessions accept text and pasted PNG, JPEG, WebP, or GIF images only.");
|
|
15216
15337
|
const threadId = nativeThreadId(sessionId);
|
|
15217
15338
|
const selection = this.modelSelection(sessionId, await this.models(signal));
|
|
15218
|
-
|
|
15339
|
+
let permissionPreset2 = this.selectedPermissions.get(sessionId);
|
|
15219
15340
|
const isFreshBlankThread = this.blankThreads.has(threadId) || this.pendingThreads.has(threadId);
|
|
15220
15341
|
await this.ensureRcFollow(sessionId);
|
|
15221
|
-
if (!isFreshBlankThread)
|
|
15222
|
-
|
|
15223
|
-
|
|
15224
|
-
|
|
15225
|
-
|
|
15342
|
+
if (!isFreshBlankThread) {
|
|
15343
|
+
const resumeResult = await this.client.request("thread/resume", {
|
|
15344
|
+
threadId,
|
|
15345
|
+
model: selection.model
|
|
15346
|
+
}, signal);
|
|
15347
|
+
const serverPreset = codexPermissionPresetFromResponse(resumeResult);
|
|
15348
|
+
if (permissionPreset2 === void 0 && serverPreset !== void 0) {
|
|
15349
|
+
permissionPreset2 = serverPreset;
|
|
15350
|
+
this.setPermissionSelection(sessionId, serverPreset);
|
|
15351
|
+
}
|
|
15352
|
+
}
|
|
15226
15353
|
this.pendingRequestIds.set(sessionId, string(request.requestId) ?? "");
|
|
15227
15354
|
const mode = request.mode === "steer" ? "turn/steer" : "turn/start";
|
|
15228
15355
|
if (mode === "turn/steer") {
|
|
@@ -15234,7 +15361,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15234
15361
|
threadId,
|
|
15235
15362
|
input: input2,
|
|
15236
15363
|
...codexModelParams(selection),
|
|
15237
|
-
permissionPreset: permissionPreset2
|
|
15364
|
+
...permissionPreset2 === void 0 ? {} : { permissionPreset: permissionPreset2 }
|
|
15238
15365
|
}, signal);
|
|
15239
15366
|
}
|
|
15240
15367
|
this.blankThreads.delete(threadId);
|
|
@@ -15376,7 +15503,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15376
15503
|
queue: new AsyncValueQueue2(controller.signal),
|
|
15377
15504
|
nextSeq: history.cursor + 1,
|
|
15378
15505
|
turn: history.nextTurn,
|
|
15379
|
-
stepOpen:
|
|
15506
|
+
stepOpen: history.activeTurnId !== void 0,
|
|
15380
15507
|
startedItems: /* @__PURE__ */ new Set(),
|
|
15381
15508
|
completedItems: /* @__PURE__ */ new Set(),
|
|
15382
15509
|
streamedBlocks: /* @__PURE__ */ new Map(),
|
|
@@ -15386,7 +15513,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15386
15513
|
liveToolOutput: /* @__PURE__ */ new Map(),
|
|
15387
15514
|
liveToolResultSeq: /* @__PURE__ */ new Map(),
|
|
15388
15515
|
requestId: this.pendingRequestIds.get(sessionId),
|
|
15389
|
-
rcOnly: true
|
|
15516
|
+
rcOnly: true,
|
|
15517
|
+
...history.activeTurnId === void 0 ? {} : { activeTurnId: history.activeTurnId }
|
|
15390
15518
|
};
|
|
15391
15519
|
this.follows.add(follow);
|
|
15392
15520
|
try {
|
|
@@ -15462,7 +15590,10 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15462
15590
|
archiveSession: call("workspace.archiveSession")
|
|
15463
15591
|
},
|
|
15464
15592
|
subagents: {},
|
|
15465
|
-
host: {
|
|
15593
|
+
host: {
|
|
15594
|
+
describe: call("host.describe"),
|
|
15595
|
+
listDirectory: call("host.listDirectory")
|
|
15596
|
+
},
|
|
15466
15597
|
skills: { list: call("skills.list") },
|
|
15467
15598
|
agentPresets: {},
|
|
15468
15599
|
goals: {},
|
|
@@ -15520,7 +15651,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15520
15651
|
}
|
|
15521
15652
|
};
|
|
15522
15653
|
async function loadCatalog(client, signal, pendingThreads) {
|
|
15523
|
-
|
|
15654
|
+
let projects = await loadCodexProjects(client, signal);
|
|
15524
15655
|
const threads = [];
|
|
15525
15656
|
let cursor2;
|
|
15526
15657
|
for (let page = 0; page < MAX_CODEX_PAGES; page += 1) {
|
|
@@ -15545,6 +15676,16 @@ async function loadCatalog(client, signal, pendingThreads) {
|
|
|
15545
15676
|
else threads.unshift(thread);
|
|
15546
15677
|
}
|
|
15547
15678
|
}
|
|
15679
|
+
if (projects.length === 0) {
|
|
15680
|
+
projects = deriveCodexCwdWorkspaces(threads).map((workspace) => ({
|
|
15681
|
+
id: workspace.id,
|
|
15682
|
+
name: workspace.name,
|
|
15683
|
+
roots: [{ path: workspace.path }],
|
|
15684
|
+
position: workspace.position,
|
|
15685
|
+
createdAt: workspace.createdAt,
|
|
15686
|
+
updatedAt: workspace.updatedAt
|
|
15687
|
+
}));
|
|
15688
|
+
}
|
|
15548
15689
|
const projected = threads.map((thread) => {
|
|
15549
15690
|
const session = projectCodexThread(thread);
|
|
15550
15691
|
return session === void 0 ? void 0 : { thread, session };
|
|
@@ -15653,6 +15794,7 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15653
15794
|
const entries = [];
|
|
15654
15795
|
let seq = 0;
|
|
15655
15796
|
let turnNumber = 0;
|
|
15797
|
+
const active = activeTurnId(thread.turns);
|
|
15656
15798
|
const append = (type, data, time = Date.now(), view, sourceEventSeqs) => {
|
|
15657
15799
|
const eventSeq = seq++;
|
|
15658
15800
|
entries.push({
|
|
@@ -15672,6 +15814,7 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15672
15814
|
for (const rawTurn of array(thread.turns)) {
|
|
15673
15815
|
const turn = record(rawTurn);
|
|
15674
15816
|
turnNumber += 1;
|
|
15817
|
+
const turnActive = isActiveCodexTurn(turn);
|
|
15675
15818
|
const time = normalizeTime(turn.createdAt) || normalizeTime(turn.startedAt) || normalizeTime(thread.createdAt) || Date.now();
|
|
15676
15819
|
append("turn/start", { turn: turnNumber }, time);
|
|
15677
15820
|
append("step/start", { turn: turnNumber, step: 1 }, time);
|
|
@@ -15689,6 +15832,7 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15689
15832
|
if (event.type === "tool/call") toolCallSeq = eventSeq;
|
|
15690
15833
|
}
|
|
15691
15834
|
}
|
|
15835
|
+
if (turnActive) continue;
|
|
15692
15836
|
append("step/end", { turn: turnNumber, step: 1 }, normalizeTime(turn.updatedAt) || normalizeTime(turn.completedAt) || time);
|
|
15693
15837
|
append("turn/end", {
|
|
15694
15838
|
turn: turnNumber,
|
|
@@ -15705,7 +15849,8 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15705
15849
|
},
|
|
15706
15850
|
entries,
|
|
15707
15851
|
lastSeq: seq - 1,
|
|
15708
|
-
nextTurn: turnNumber
|
|
15852
|
+
nextTurn: turnNumber,
|
|
15853
|
+
...active === void 0 ? {} : { activeTurnId: active }
|
|
15709
15854
|
};
|
|
15710
15855
|
}
|
|
15711
15856
|
function paginateCodexNativeHistory(history, request) {
|
|
@@ -15729,7 +15874,8 @@ function paginateCodexNativeHistory(history, request) {
|
|
|
15729
15874
|
cursor: history.lastSeq,
|
|
15730
15875
|
nextTurn: history.nextTurn,
|
|
15731
15876
|
records: window.filter((entry) => entry.event.seq >= cut),
|
|
15732
|
-
hasMore: window.some((entry) => entry.event.seq < cut)
|
|
15877
|
+
hasMore: window.some((entry) => entry.event.seq < cut),
|
|
15878
|
+
...history.activeTurnId === void 0 ? {} : { activeTurnId: history.activeTurnId }
|
|
15733
15879
|
};
|
|
15734
15880
|
}
|
|
15735
15881
|
function itemEvents(item, turn, step, requestId, selection = modelSelection(), sessionId = CODEX_SESSION_PREFIX) {
|
|
@@ -16242,6 +16388,22 @@ function codexImageLimitsProjection() {
|
|
|
16242
16388
|
function isCodexPermissionPreset(value) {
|
|
16243
16389
|
return value === "workspace-write" || value === "danger-full-access";
|
|
16244
16390
|
}
|
|
16391
|
+
function codexPermissionPresetFromResponse(value) {
|
|
16392
|
+
const root = record(value);
|
|
16393
|
+
return codexPermissionPresetFromPolicyRecord(root) ?? codexPermissionPresetFromPolicyRecord(record(root.threadSettings));
|
|
16394
|
+
}
|
|
16395
|
+
function codexPermissionPresetFromPolicyRecord(value) {
|
|
16396
|
+
const sandbox = value.sandbox ?? value.sandboxPolicy;
|
|
16397
|
+
if (value.approvalPolicy === "never" && isDangerFullAccessSandbox(sandbox)) return "danger-full-access";
|
|
16398
|
+
if (value.approvalPolicy === "on-request" && isWorkspaceWriteSandbox(sandbox)) return "workspace-write";
|
|
16399
|
+
return void 0;
|
|
16400
|
+
}
|
|
16401
|
+
function isDangerFullAccessSandbox(value) {
|
|
16402
|
+
return value === "danger-full-access" || record(value).type === "dangerFullAccess";
|
|
16403
|
+
}
|
|
16404
|
+
function isWorkspaceWriteSandbox(value) {
|
|
16405
|
+
return value === "workspace-write" || record(value).type === "workspaceWrite";
|
|
16406
|
+
}
|
|
16245
16407
|
function modelCatalog(directory) {
|
|
16246
16408
|
return {
|
|
16247
16409
|
default: directory.default,
|
|
@@ -16382,6 +16544,17 @@ function nativeThreadId(sessionId) {
|
|
|
16382
16544
|
}
|
|
16383
16545
|
return sessionId.slice(CODEX_SESSION_PREFIX.length);
|
|
16384
16546
|
}
|
|
16547
|
+
function activeTurnId(value) {
|
|
16548
|
+
if (!Array.isArray(value)) return void 0;
|
|
16549
|
+
for (let index = value.length - 1; index >= 0; index -= 1) {
|
|
16550
|
+
const turn = record(value[index]);
|
|
16551
|
+
if (isActiveCodexTurn(turn) && typeof turn.id === "string" && turn.id.length > 0) return turn.id;
|
|
16552
|
+
}
|
|
16553
|
+
return void 0;
|
|
16554
|
+
}
|
|
16555
|
+
function isActiveCodexTurn(turn) {
|
|
16556
|
+
return turn.status === "inProgress" || turn.status === "running";
|
|
16557
|
+
}
|
|
16385
16558
|
function carrierArgs(payload) {
|
|
16386
16559
|
return record(record(payload).args);
|
|
16387
16560
|
}
|
|
@@ -16410,6 +16583,14 @@ function business(value) {
|
|
|
16410
16583
|
}
|
|
16411
16584
|
return ok(value);
|
|
16412
16585
|
}
|
|
16586
|
+
function isCodexDirectoryListing(value) {
|
|
16587
|
+
const listing = record(value);
|
|
16588
|
+
return typeof listing.path === "string" && typeof listing.home === "string" && Array.isArray(listing.crumbs) && listing.crumbs.every(isCodexDirectoryEntry) && Array.isArray(listing.entries) && listing.entries.every(isCodexDirectoryEntry) && typeof listing.truncated === "boolean";
|
|
16589
|
+
}
|
|
16590
|
+
function isCodexDirectoryEntry(value) {
|
|
16591
|
+
const entry = record(value);
|
|
16592
|
+
return typeof entry.name === "string" && typeof entry.path === "string" && typeof entry.hidden === "boolean";
|
|
16593
|
+
}
|
|
16413
16594
|
function fail(code, message, details = {}) {
|
|
16414
16595
|
return { ok: false, error: { code, message, details } };
|
|
16415
16596
|
}
|
|
@@ -16464,7 +16645,7 @@ function optionalPositiveInteger(value) {
|
|
|
16464
16645
|
function isCodexNativeHistoryPage(value, sessionId) {
|
|
16465
16646
|
const page = record(value);
|
|
16466
16647
|
const header = record(page.header);
|
|
16467
|
-
return header.id === sessionId && integer(page.cursor) !== void 0 && integer(page.nextTurn) !== void 0 && Array.isArray(page.records) && typeof page.hasMore === "boolean";
|
|
16648
|
+
return header.id === sessionId && integer(page.cursor) !== void 0 && integer(page.nextTurn) !== void 0 && Array.isArray(page.records) && typeof page.hasMore === "boolean" && (page.activeTurnId === void 0 || typeof page.activeTurnId === "string");
|
|
16468
16649
|
}
|
|
16469
16650
|
function truncateCodePoints(value, maximum) {
|
|
16470
16651
|
return [...value].slice(0, maximum).join("");
|
|
@@ -16541,7 +16722,7 @@ var AsyncValueQueue2 = class {
|
|
|
16541
16722
|
continue;
|
|
16542
16723
|
}
|
|
16543
16724
|
if (this.closed) return;
|
|
16544
|
-
const next = await new Promise((
|
|
16725
|
+
const next = await new Promise((resolve3) => this.waiters.push(resolve3));
|
|
16545
16726
|
if (next.done) return;
|
|
16546
16727
|
yield next.value;
|
|
16547
16728
|
}
|
|
@@ -16554,6 +16735,7 @@ import { platform } from "node:os";
|
|
|
16554
16735
|
// src/config.ts
|
|
16555
16736
|
import { hostname } from "node:os";
|
|
16556
16737
|
import s from "@deepseek-ai/schemastery";
|
|
16738
|
+
var DEFAULT_REMOTE_SERVER_URL = "https://dsh.r2049.cn";
|
|
16557
16739
|
var Config = s.object({
|
|
16558
16740
|
enabled: s.boolean(),
|
|
16559
16741
|
role: s.union(["host", "client", "both"]),
|
|
@@ -16643,9 +16825,10 @@ function normalizeServerUrl(value) {
|
|
|
16643
16825
|
}
|
|
16644
16826
|
|
|
16645
16827
|
// src/version.ts
|
|
16646
|
-
var PLUGIN_VERSION = "0.4.
|
|
16828
|
+
var PLUGIN_VERSION = "0.4.5";
|
|
16647
16829
|
|
|
16648
16830
|
// src/server-api.ts
|
|
16831
|
+
var TERMINAL_CONTROL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f]/u;
|
|
16649
16832
|
var HostServerApi = class {
|
|
16650
16833
|
constructor(serverUrl, store, fetchImplementation = fetch, role = "host") {
|
|
16651
16834
|
this.store = store;
|
|
@@ -16694,20 +16877,20 @@ var HostServerApi = class {
|
|
|
16694
16877
|
if (account.length === 0 || password.length === 0) {
|
|
16695
16878
|
throw new ServerApiError("INVALID_MESSAGE", "Email and password are required.", false);
|
|
16696
16879
|
}
|
|
16697
|
-
const
|
|
16880
|
+
const login2 = validateWebLogin(await this.publicRequest("/api/v1/auth/login", {
|
|
16698
16881
|
method: "POST",
|
|
16699
16882
|
body: JSON.stringify({ email: account, password })
|
|
16700
16883
|
}));
|
|
16701
16884
|
await this.register(identity, {
|
|
16702
|
-
accountToken:
|
|
16703
|
-
account:
|
|
16885
|
+
accountToken: login2.token,
|
|
16886
|
+
account: login2.account,
|
|
16704
16887
|
authorizationMethod: "account"
|
|
16705
16888
|
});
|
|
16706
16889
|
return {
|
|
16707
16890
|
method: "account",
|
|
16708
|
-
account:
|
|
16709
|
-
expiresAt:
|
|
16710
|
-
isAdmin:
|
|
16891
|
+
account: login2.account,
|
|
16892
|
+
expiresAt: login2.expiresAt,
|
|
16893
|
+
isAdmin: login2.isAdmin
|
|
16711
16894
|
};
|
|
16712
16895
|
}
|
|
16713
16896
|
async startOAuthQrLogin(provider = "zhihu") {
|
|
@@ -16715,10 +16898,11 @@ var HostServerApi = class {
|
|
|
16715
16898
|
method: "POST",
|
|
16716
16899
|
body: "{}"
|
|
16717
16900
|
}), "QR login");
|
|
16718
|
-
|
|
16901
|
+
const scanUrl = normalizeOAuthScanUrl(value.scanUrl, this.baseUrl);
|
|
16902
|
+
if (typeof value.qrId !== "string" || value.qrId.length < 20 || scanUrl === void 0 || !Number.isSafeInteger(value.expiresIn) || provider === "github" && value.provider !== "github" || value.provider !== void 0 && value.provider !== provider) {
|
|
16719
16903
|
throw new ServerApiError("INVALID_MESSAGE", "The Server returned an invalid QR login session.", false);
|
|
16720
16904
|
}
|
|
16721
|
-
return { qrId: value.qrId, scanUrl
|
|
16905
|
+
return { qrId: value.qrId, scanUrl, expiresIn: value.expiresIn };
|
|
16722
16906
|
}
|
|
16723
16907
|
async pollOAuthQrLogin(identity, qrId, recoverIdentity) {
|
|
16724
16908
|
this.bindIdentity(identity);
|
|
@@ -16933,17 +17117,26 @@ var HostServerApi = class {
|
|
|
16933
17117
|
return this.identity;
|
|
16934
17118
|
}
|
|
16935
17119
|
};
|
|
17120
|
+
function normalizeOAuthScanUrl(value, baseUrl) {
|
|
17121
|
+
if (typeof value !== "string" || TERMINAL_CONTROL_CHARACTERS.test(value)) return void 0;
|
|
17122
|
+
try {
|
|
17123
|
+
const normalized = new URL(value).href;
|
|
17124
|
+
return normalized.startsWith(`${baseUrl}/`) ? normalized : void 0;
|
|
17125
|
+
} catch {
|
|
17126
|
+
return void 0;
|
|
17127
|
+
}
|
|
17128
|
+
}
|
|
16936
17129
|
var ClientServerApi = class extends HostServerApi {
|
|
16937
17130
|
constructor(serverUrl, store, fetchImplementation = fetch) {
|
|
16938
17131
|
super(serverUrl, store, fetchImplementation, "client");
|
|
16939
17132
|
}
|
|
16940
17133
|
};
|
|
16941
17134
|
var ServerApiError = class extends Error {
|
|
16942
|
-
constructor(code, message, retryable,
|
|
17135
|
+
constructor(code, message, retryable, status2) {
|
|
16943
17136
|
super(message);
|
|
16944
17137
|
this.code = code;
|
|
16945
17138
|
this.retryable = retryable;
|
|
16946
|
-
this.status =
|
|
17139
|
+
this.status = status2;
|
|
16947
17140
|
}
|
|
16948
17141
|
};
|
|
16949
17142
|
function validateTokens(value) {
|
|
@@ -16974,12 +17167,12 @@ async function parseBody(response) {
|
|
|
16974
17167
|
throw new ServerApiError("INVALID_MESSAGE", "The Server returned invalid JSON.", false, response.status);
|
|
16975
17168
|
}
|
|
16976
17169
|
}
|
|
16977
|
-
function mapStatus(
|
|
16978
|
-
if (
|
|
16979
|
-
if (
|
|
16980
|
-
if (
|
|
16981
|
-
if (
|
|
16982
|
-
return
|
|
17170
|
+
function mapStatus(status2) {
|
|
17171
|
+
if (status2 === 401) return "AUTH_INVALID";
|
|
17172
|
+
if (status2 === 403) return "AUTH_REQUIRED";
|
|
17173
|
+
if (status2 === 404) return "DEVICE_NOT_FOUND";
|
|
17174
|
+
if (status2 === 429) return "RATE_LIMITED";
|
|
17175
|
+
return status2 >= 500 ? "CONNECTION_FAILED" : "INVALID_MESSAGE";
|
|
16983
17176
|
}
|
|
16984
17177
|
function parseHostDevice(value) {
|
|
16985
17178
|
const item = requireRecord(value, "host device");
|
|
@@ -17281,10 +17474,10 @@ function isUsableExternalNode(candidate, requireFrom) {
|
|
|
17281
17474
|
}
|
|
17282
17475
|
function isExecutableFile(candidate) {
|
|
17283
17476
|
try {
|
|
17284
|
-
const
|
|
17285
|
-
if (!
|
|
17477
|
+
const stat6 = statSync(candidate);
|
|
17478
|
+
if (!stat6.isFile()) return false;
|
|
17286
17479
|
if (process.platform === "win32") return true;
|
|
17287
|
-
return (
|
|
17480
|
+
return (stat6.mode & 73) !== 0;
|
|
17288
17481
|
} catch {
|
|
17289
17482
|
return false;
|
|
17290
17483
|
}
|
|
@@ -17373,8 +17566,8 @@ var ExternalNativePeerConnection = class {
|
|
|
17373
17566
|
request(method, payload) {
|
|
17374
17567
|
if (this.closed) return Promise.reject(new Error("native rtc helper is closed"));
|
|
17375
17568
|
const id2 = this.nextRequestId++;
|
|
17376
|
-
const promise = new Promise((
|
|
17377
|
-
this.pending.set(id2, { resolve:
|
|
17569
|
+
const promise = new Promise((resolve3, reject) => {
|
|
17570
|
+
this.pending.set(id2, { resolve: resolve3, reject });
|
|
17378
17571
|
});
|
|
17379
17572
|
this.write({ id: id2, method, payload });
|
|
17380
17573
|
return promise;
|
|
@@ -18168,10 +18361,10 @@ function parseRouteTarget(value) {
|
|
|
18168
18361
|
async function detectRouteHostIpv4(target, timeoutMs) {
|
|
18169
18362
|
const socket = createSocket("udp4");
|
|
18170
18363
|
try {
|
|
18171
|
-
return await new Promise((
|
|
18364
|
+
return await new Promise((resolve3, reject) => {
|
|
18172
18365
|
const timer = setTimeout(() => {
|
|
18173
18366
|
cleanup();
|
|
18174
|
-
|
|
18367
|
+
resolve3(void 0);
|
|
18175
18368
|
}, timeoutMs);
|
|
18176
18369
|
const cleanup = () => {
|
|
18177
18370
|
clearTimeout(timer);
|
|
@@ -18185,7 +18378,7 @@ async function detectRouteHostIpv4(target, timeoutMs) {
|
|
|
18185
18378
|
socket.connect(target.port, target.host, () => {
|
|
18186
18379
|
cleanup();
|
|
18187
18380
|
const address = socket.address();
|
|
18188
|
-
|
|
18381
|
+
resolve3(typeof address === "string" ? void 0 : address.address);
|
|
18189
18382
|
});
|
|
18190
18383
|
});
|
|
18191
18384
|
} finally {
|
|
@@ -19139,7 +19332,7 @@ async function probeRemoteHostFeatures(client, clientVersion) {
|
|
|
19139
19332
|
}
|
|
19140
19333
|
async function waitForCodexFrames(stream, signal) {
|
|
19141
19334
|
if (signal?.aborted) throw new ClientModeError("RPC_ABORTED", "The Codex event poll was cancelled.");
|
|
19142
|
-
await new Promise((
|
|
19335
|
+
await new Promise((resolve3, reject) => {
|
|
19143
19336
|
const previousWake = stream.wake;
|
|
19144
19337
|
const timer = setTimeout(done, 25e3);
|
|
19145
19338
|
const onAbort = () => {
|
|
@@ -19153,7 +19346,7 @@ async function waitForCodexFrames(stream, signal) {
|
|
|
19153
19346
|
}
|
|
19154
19347
|
function done() {
|
|
19155
19348
|
cleanup();
|
|
19156
|
-
|
|
19349
|
+
resolve3();
|
|
19157
19350
|
}
|
|
19158
19351
|
stream.wake = () => {
|
|
19159
19352
|
previousWake();
|
|
@@ -20368,7 +20561,7 @@ var HostServerConnection = class {
|
|
|
20368
20561
|
this.controlFrameLimits = {};
|
|
20369
20562
|
let acknowledged = false;
|
|
20370
20563
|
let messageQueue = Promise.resolve();
|
|
20371
|
-
await new Promise((
|
|
20564
|
+
await new Promise((resolve3, reject) => {
|
|
20372
20565
|
let settled = false;
|
|
20373
20566
|
const helloTimer = setTimeout(() => socket.close(4001, "hello timeout"), 1e4);
|
|
20374
20567
|
const finish = (error) => {
|
|
@@ -20377,7 +20570,7 @@ var HostServerConnection = class {
|
|
|
20377
20570
|
clearTimeout(helloTimer);
|
|
20378
20571
|
this.online = false;
|
|
20379
20572
|
if (this.socket === socket) this.socket = void 0;
|
|
20380
|
-
void this.dropTunnels().finally(() => error === void 0 ?
|
|
20573
|
+
void this.dropTunnels().finally(() => error === void 0 ? resolve3() : reject(error));
|
|
20381
20574
|
};
|
|
20382
20575
|
socket.onopen = () => {
|
|
20383
20576
|
this.sendControl("hello", {
|
|
@@ -20895,14 +21088,14 @@ var HostServerConnection = class {
|
|
|
20895
21088
|
waitBeforeRetry(baseDelay) {
|
|
20896
21089
|
const spread = baseDelay * this.config.reconnect.jitter;
|
|
20897
21090
|
const delay = Math.max(0, Math.round(baseDelay - spread + Math.random() * spread * 2));
|
|
20898
|
-
return new Promise((
|
|
21091
|
+
return new Promise((resolve3) => {
|
|
20899
21092
|
const timer = setTimeout(() => {
|
|
20900
21093
|
this.retryWake = void 0;
|
|
20901
|
-
|
|
21094
|
+
resolve3();
|
|
20902
21095
|
}, delay);
|
|
20903
21096
|
this.retryWake = () => {
|
|
20904
21097
|
clearTimeout(timer);
|
|
20905
|
-
|
|
21098
|
+
resolve3();
|
|
20906
21099
|
};
|
|
20907
21100
|
});
|
|
20908
21101
|
}
|
|
@@ -21353,7 +21546,9 @@ var HarnessApiBridge = class {
|
|
|
21353
21546
|
const value = await listRemoteDirectory(typeof payload.path === "string" ? payload.path : void 0, signal);
|
|
21354
21547
|
response = { rpcId: params.rpcId, result: { ok: true, value } };
|
|
21355
21548
|
}
|
|
21356
|
-
if (params.method === "host.describe")
|
|
21549
|
+
if (params.method === "host.describe") {
|
|
21550
|
+
response = normalizeHostDescribe(response, this.harnessVersion, this.methods.has("host.listDirectory"));
|
|
21551
|
+
}
|
|
21357
21552
|
this.logger?.debug("harness api call ok", {
|
|
21358
21553
|
method: params.method,
|
|
21359
21554
|
durationMs: Math.round(performance.now() - startedAt)
|
|
@@ -21584,8 +21779,8 @@ function needsRemoteDirectoryFallback(response) {
|
|
|
21584
21779
|
const result = response.result;
|
|
21585
21780
|
return typeof result === "object" && result !== null && "ok" in result && result.ok === false && "error" in result && typeof result.error === "object" && result.error !== null && "code" in result.error && result.error.code === "directory-picker-unavailable";
|
|
21586
21781
|
}
|
|
21587
|
-
function
|
|
21588
|
-
if (!response.result.ok
|
|
21782
|
+
function normalizeHostDescribe(response, harnessVersion, canListDirectory) {
|
|
21783
|
+
if (!response.result.ok) return response;
|
|
21589
21784
|
const value = response.result.value;
|
|
21590
21785
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return response;
|
|
21591
21786
|
const description = value;
|
|
@@ -21593,12 +21788,19 @@ function normalizeHostDescribeVersion(response, harnessVersion) {
|
|
|
21593
21788
|
normalizeHarnessVersion(description.version),
|
|
21594
21789
|
harnessVersion
|
|
21595
21790
|
);
|
|
21596
|
-
|
|
21791
|
+
const versionChanged = selectedVersion !== void 0 && description.version !== selectedVersion;
|
|
21792
|
+
const canOpenPathChanged = canListDirectory && description.canOpenPath !== true;
|
|
21793
|
+
if (!versionChanged && !canOpenPathChanged) return response;
|
|
21794
|
+
const normalized = {
|
|
21795
|
+
...description,
|
|
21796
|
+
...versionChanged ? { version: selectedVersion } : {},
|
|
21797
|
+
...canOpenPathChanged ? { canOpenPath: true } : {}
|
|
21798
|
+
};
|
|
21597
21799
|
return {
|
|
21598
21800
|
...response,
|
|
21599
21801
|
result: {
|
|
21600
21802
|
...response.result,
|
|
21601
|
-
value:
|
|
21803
|
+
value: normalized
|
|
21602
21804
|
}
|
|
21603
21805
|
};
|
|
21604
21806
|
}
|
|
@@ -21868,7 +22070,7 @@ function historyRequestPayload(payload, maxMessages) {
|
|
|
21868
22070
|
return { ...payload, maxMessages };
|
|
21869
22071
|
}
|
|
21870
22072
|
function withTimeout(promise, ms, message) {
|
|
21871
|
-
return new Promise((
|
|
22073
|
+
return new Promise((resolve3, reject) => {
|
|
21872
22074
|
const timer = setTimeout(() => {
|
|
21873
22075
|
reject(new RpcError("TIMEOUT", message, void 0, true));
|
|
21874
22076
|
}, ms);
|
|
@@ -21876,7 +22078,7 @@ function withTimeout(promise, ms, message) {
|
|
|
21876
22078
|
promise.then(
|
|
21877
22079
|
(value) => {
|
|
21878
22080
|
clearTimeout(timer);
|
|
21879
|
-
|
|
22081
|
+
resolve3(value);
|
|
21880
22082
|
},
|
|
21881
22083
|
(error) => {
|
|
21882
22084
|
clearTimeout(timer);
|
|
@@ -21961,6 +22163,7 @@ var HARNESS_REMOTE_ALLOWLIST = [
|
|
|
21961
22163
|
"pluginInventory/list",
|
|
21962
22164
|
"session/attachment",
|
|
21963
22165
|
"session/cancel",
|
|
22166
|
+
"session/canOpenWorkspacePath",
|
|
21964
22167
|
"session/control",
|
|
21965
22168
|
"session/create",
|
|
21966
22169
|
"session/follow",
|
|
@@ -22206,8 +22409,9 @@ function concatChunks2(chunks, totalBytes) {
|
|
|
22206
22409
|
|
|
22207
22410
|
// src/codex/domain.ts
|
|
22208
22411
|
import { randomUUID } from "node:crypto";
|
|
22412
|
+
import { readdir as readdir2, realpath, stat as stat4 } from "node:fs/promises";
|
|
22209
22413
|
import { homedir as homedir3 } from "node:os";
|
|
22210
|
-
import { isAbsolute as isAbsolute3, join as join5 } from "node:path";
|
|
22414
|
+
import { basename as basename3, isAbsolute as isAbsolute3, join as join5, relative, resolve as resolve2 } from "node:path";
|
|
22211
22415
|
|
|
22212
22416
|
// src/codex/app-server.ts
|
|
22213
22417
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -22280,15 +22484,15 @@ var CodexAppServerClient = class {
|
|
|
22280
22484
|
const child = this.process;
|
|
22281
22485
|
this.process = void 0;
|
|
22282
22486
|
if (child === void 0 || child.exitCode !== null || child.killed) return;
|
|
22283
|
-
await new Promise((
|
|
22487
|
+
await new Promise((resolve3) => {
|
|
22284
22488
|
const timer = setTimeout(() => {
|
|
22285
22489
|
child.kill("SIGKILL");
|
|
22286
|
-
|
|
22490
|
+
resolve3();
|
|
22287
22491
|
}, 2e3);
|
|
22288
22492
|
timer.unref?.();
|
|
22289
22493
|
child.once("exit", () => {
|
|
22290
22494
|
clearTimeout(timer);
|
|
22291
|
-
|
|
22495
|
+
resolve3();
|
|
22292
22496
|
});
|
|
22293
22497
|
child.kill("SIGTERM");
|
|
22294
22498
|
});
|
|
@@ -22344,13 +22548,13 @@ var CodexAppServerClient = class {
|
|
|
22344
22548
|
}
|
|
22345
22549
|
request(method, params, timeoutMs) {
|
|
22346
22550
|
const id2 = this.nextId++;
|
|
22347
|
-
const result = new Promise((
|
|
22551
|
+
const result = new Promise((resolve3, reject) => {
|
|
22348
22552
|
const timer = setTimeout(() => {
|
|
22349
22553
|
this.pending.delete(id2);
|
|
22350
22554
|
reject(new CodexAppServerError("CODEX_REQUEST_TIMEOUT", "Codex App Server request timed out."));
|
|
22351
22555
|
}, timeoutMs);
|
|
22352
22556
|
timer.unref?.();
|
|
22353
|
-
this.pending.set(id2, { resolve:
|
|
22557
|
+
this.pending.set(id2, { resolve: resolve3, reject, timer });
|
|
22354
22558
|
});
|
|
22355
22559
|
try {
|
|
22356
22560
|
this.write({ id: id2, method, params });
|
|
@@ -22496,6 +22700,9 @@ var schemas = {
|
|
|
22496
22700
|
throughSeq: external_exports.number().int().min(-1).optional(),
|
|
22497
22701
|
maxMessages: external_exports.number().int().min(1).max(200).optional()
|
|
22498
22702
|
}).strict(),
|
|
22703
|
+
"dsh/directoryList": external_exports.object({
|
|
22704
|
+
path: external_exports.string().min(1).max(4096)
|
|
22705
|
+
}).strict(),
|
|
22499
22706
|
"thread/start": external_exports.object({
|
|
22500
22707
|
cwd: external_exports.string().min(1).max(4096),
|
|
22501
22708
|
model: external_exports.string().min(1).max(128).optional(),
|
|
@@ -22825,8 +23032,11 @@ function concatChunks3(chunks, totalBytes) {
|
|
|
22825
23032
|
// src/codex/domain.ts
|
|
22826
23033
|
var APPROVAL_TTL_MS = 5 * 6e4;
|
|
22827
23034
|
var DEFAULT_RESTART_DELAYS_MS = [1e3, 2e3, 4e3, 8e3, 15e3];
|
|
23035
|
+
var CODEX_PAGE_LIMIT2 = 100;
|
|
23036
|
+
var MAX_CODEX_PAGES2 = 32;
|
|
22828
23037
|
var CODEX_HISTORY_PAGE_LIMIT = 25;
|
|
22829
23038
|
var MAX_CODEX_HISTORY_PAGES = 64;
|
|
23039
|
+
var CODEX_DIRECTORY_ENTRY_LIMIT = 500;
|
|
22830
23040
|
var CodexRemoteDomain = class {
|
|
22831
23041
|
constructor(config, logger, createAppServer = (binary, targetLogger) => new CodexAppServerClient(binary, targetLogger), restartDelaysMs = DEFAULT_RESTART_DELAYS_MS) {
|
|
22832
23042
|
this.config = config;
|
|
@@ -22838,6 +23048,7 @@ var CodexRemoteDomain = class {
|
|
|
22838
23048
|
unsubscribeInbound;
|
|
22839
23049
|
unsubscribeUnavailable;
|
|
22840
23050
|
peers = /* @__PURE__ */ new Map();
|
|
23051
|
+
peerDeviceIds = /* @__PURE__ */ new Map();
|
|
22841
23052
|
turnOwners = /* @__PURE__ */ new Map();
|
|
22842
23053
|
approvals = /* @__PURE__ */ new Map();
|
|
22843
23054
|
approvalExpiryTimer;
|
|
@@ -22877,6 +23088,7 @@ var CodexRemoteDomain = class {
|
|
|
22877
23088
|
if (!this.config.enabled) return void 0;
|
|
22878
23089
|
const bridge = new CodexPeerBridge(this, context, publish, this.logger);
|
|
22879
23090
|
this.peers.set(context.connectionId, bridge);
|
|
23091
|
+
this.peerDeviceIds.set(context.connectionId, context.peerDeviceId);
|
|
22880
23092
|
return bridge;
|
|
22881
23093
|
}
|
|
22882
23094
|
async call(connectionId, input2) {
|
|
@@ -22890,19 +23102,19 @@ var CodexRemoteDomain = class {
|
|
|
22890
23102
|
return sanitizeProjectList(await this.callUpstream(call.method, call.params));
|
|
22891
23103
|
}
|
|
22892
23104
|
if (call.method === "thread/list") {
|
|
22893
|
-
|
|
22894
|
-
|
|
22895
|
-
|
|
23105
|
+
const result = sanitizeThreadList(await this.callUpstream(call.method, call.params));
|
|
23106
|
+
return filterThreadListByWorkspaceAuthority(
|
|
23107
|
+
result,
|
|
23108
|
+
await this.readWorkspaceAuthority(result.data)
|
|
22896
23109
|
);
|
|
22897
23110
|
}
|
|
22898
23111
|
if (call.method === "thread/start") {
|
|
22899
23112
|
const cwd = await this.requireCodexWorkspacePath(call.params.cwd);
|
|
22900
|
-
const permission = codexPermission(call.params);
|
|
23113
|
+
const permission = codexPermission(call.params, "workspace-write");
|
|
22901
23114
|
const result = await this.callUpstream(call.method, {
|
|
22902
23115
|
...permission.params,
|
|
22903
23116
|
cwd,
|
|
22904
|
-
|
|
22905
|
-
sandbox: permission.sandbox,
|
|
23117
|
+
...codexThreadPermissionParams(permission),
|
|
22906
23118
|
serviceName: "deepseek_harness_remote"
|
|
22907
23119
|
});
|
|
22908
23120
|
if (extractThread(result)?.id === void 0) {
|
|
@@ -22913,7 +23125,7 @@ var CodexRemoteDomain = class {
|
|
|
22913
23125
|
const threadId = threadIdFromParams(call.params);
|
|
22914
23126
|
if (call.method === "dsh/sessionHistory") {
|
|
22915
23127
|
const thread = await this.readThreadForHistory(connectionId, threadId);
|
|
22916
|
-
|
|
23128
|
+
const page = paginateCodexNativeHistory(
|
|
22917
23129
|
projectCodexNativeHistory(thread, `codex:${threadId}`),
|
|
22918
23130
|
{
|
|
22919
23131
|
beforeSeq: optionalInteger2(call.params.beforeSeq),
|
|
@@ -22921,6 +23133,11 @@ var CodexRemoteDomain = class {
|
|
|
22921
23133
|
maxMessages: optionalInteger2(call.params.maxMessages)
|
|
22922
23134
|
}
|
|
22923
23135
|
);
|
|
23136
|
+
const activeTurnId2 = typeof page.activeTurnId === "string" ? page.activeTurnId : this.turnOwners.get(threadId)?.turnId;
|
|
23137
|
+
return activeTurnId2 === void 0 ? page : { ...page, activeTurnId: activeTurnId2 };
|
|
23138
|
+
}
|
|
23139
|
+
if (call.method === "dsh/directoryList") {
|
|
23140
|
+
return this.listCodexDirectory(call.params.path);
|
|
22924
23141
|
}
|
|
22925
23142
|
const allowedThread = threadId === void 0 ? void 0 : await this.readKnownThread(threadId);
|
|
22926
23143
|
if (call.method === "thread/read") {
|
|
@@ -22933,39 +23150,38 @@ var CodexRemoteDomain = class {
|
|
|
22933
23150
|
return this.callUpstream(call.method, call.params);
|
|
22934
23151
|
}
|
|
22935
23152
|
let claimed = false;
|
|
23153
|
+
let previousOwner;
|
|
22936
23154
|
if (isThreadMutation(call.method) && threadId !== void 0) {
|
|
22937
|
-
|
|
23155
|
+
const claim = this.claimTurn(
|
|
23156
|
+
threadId,
|
|
23157
|
+
connectionId,
|
|
23158
|
+
call.method,
|
|
23159
|
+
typeof call.params.turnId === "string" ? call.params.turnId : void 0
|
|
23160
|
+
);
|
|
23161
|
+
claimed = claim.claimed;
|
|
23162
|
+
previousOwner = claim.previous;
|
|
22938
23163
|
}
|
|
22939
23164
|
try {
|
|
22940
23165
|
const permission = codexPermission(call.params);
|
|
22941
23166
|
const upstreamParams = call.method === "thread/resume" && allowedThread !== void 0 ? {
|
|
22942
23167
|
...permission.params,
|
|
22943
23168
|
...allowedThread.cwd === void 0 ? {} : { cwd: allowedThread.cwd },
|
|
22944
|
-
|
|
22945
|
-
sandbox: permission.sandbox,
|
|
23169
|
+
...codexThreadPermissionParams(permission),
|
|
22946
23170
|
excludeTurns: true
|
|
22947
23171
|
} : call.method === "thread/fork" && allowedThread !== void 0 ? {
|
|
22948
23172
|
...permission.params,
|
|
22949
23173
|
...allowedThread.cwd === void 0 ? {} : { cwd: allowedThread.cwd },
|
|
22950
|
-
|
|
22951
|
-
sandbox: permission.sandbox
|
|
23174
|
+
...codexThreadPermissionParams(permission)
|
|
22952
23175
|
} : call.method === "turn/start" ? {
|
|
22953
23176
|
...permission.params,
|
|
22954
23177
|
...allowedThread?.cwd === void 0 ? {} : { cwd: allowedThread.cwd },
|
|
22955
|
-
|
|
22956
|
-
sandboxPolicy: permission.sandbox === "danger-full-access" ? { type: "dangerFullAccess" } : {
|
|
22957
|
-
type: "workspaceWrite",
|
|
22958
|
-
writableRoots: allowedThread?.cwd === void 0 ? [] : [allowedThread.cwd],
|
|
22959
|
-
networkAccess: false,
|
|
22960
|
-
excludeTmpdirEnvVar: false,
|
|
22961
|
-
excludeSlashTmp: false
|
|
22962
|
-
}
|
|
23178
|
+
...codexTurnPermissionParams(permission, allowedThread?.cwd)
|
|
22963
23179
|
} : permission.params;
|
|
22964
23180
|
let result;
|
|
22965
23181
|
try {
|
|
22966
23182
|
result = await this.callUpstream(call.method, upstreamParams);
|
|
22967
23183
|
} catch (error) {
|
|
22968
|
-
if (call.method === "thread/resume" && allowedThread !== void 0 && error instanceof RpcError && error.code === "CODEX_UPSTREAM_ERROR") {
|
|
23184
|
+
if (call.method === "thread/resume" && allowedThread !== void 0 && error instanceof RpcError && error.code === "CODEX_UPSTREAM_ERROR" && call.params.permissionPreset === void 0) {
|
|
22969
23185
|
return { thread: allowedThread.thread };
|
|
22970
23186
|
}
|
|
22971
23187
|
throw error;
|
|
@@ -22973,9 +23189,15 @@ var CodexRemoteDomain = class {
|
|
|
22973
23189
|
if (call.method === "thread/resume" || call.method === "thread/fork" || call.method === "thread/unarchive") {
|
|
22974
23190
|
await this.assertResultThreadAllowed(result);
|
|
22975
23191
|
}
|
|
23192
|
+
if (call.method === "turn/start" && threadId !== void 0) {
|
|
23193
|
+
this.rememberTurnId(threadId, connectionId, extractTurnId(result));
|
|
23194
|
+
}
|
|
22976
23195
|
return result;
|
|
22977
23196
|
} catch (error) {
|
|
22978
|
-
if (claimed && threadId !== void 0)
|
|
23197
|
+
if (claimed && threadId !== void 0) {
|
|
23198
|
+
if (previousOwner === void 0) this.turnOwners.delete(threadId);
|
|
23199
|
+
else this.turnOwners.set(threadId, previousOwner);
|
|
23200
|
+
}
|
|
22979
23201
|
throw mapAppServerError(error);
|
|
22980
23202
|
}
|
|
22981
23203
|
}
|
|
@@ -22994,8 +23216,9 @@ var CodexRemoteDomain = class {
|
|
|
22994
23216
|
async detachPeer(connectionId) {
|
|
22995
23217
|
const bridge = this.peers.get(connectionId);
|
|
22996
23218
|
if (bridge !== void 0) this.peers.delete(connectionId);
|
|
23219
|
+
this.peerDeviceIds.delete(connectionId);
|
|
22997
23220
|
for (const [threadId, owner] of this.turnOwners) {
|
|
22998
|
-
if (owner === connectionId) this.turnOwners.delete(threadId);
|
|
23221
|
+
if (owner.connectionId === connectionId) this.turnOwners.delete(threadId);
|
|
22999
23222
|
}
|
|
23000
23223
|
const appServer = this.appServer;
|
|
23001
23224
|
const pending = [...this.approvals.entries()].filter(([, approval]) => approval.connectionId === connectionId);
|
|
@@ -23014,6 +23237,7 @@ var CodexRemoteDomain = class {
|
|
|
23014
23237
|
this.restartTimer = void 0;
|
|
23015
23238
|
for (const bridge of [...this.peers.values()]) await bridge.closeAll();
|
|
23016
23239
|
this.peers.clear();
|
|
23240
|
+
this.peerDeviceIds.clear();
|
|
23017
23241
|
this.turnOwners.clear();
|
|
23018
23242
|
if (this.approvalExpiryTimer !== void 0) clearTimeout(this.approvalExpiryTimer);
|
|
23019
23243
|
this.approvalExpiryTimer = void 0;
|
|
@@ -23133,6 +23357,13 @@ var CodexRemoteDomain = class {
|
|
|
23133
23357
|
}
|
|
23134
23358
|
const threadId = extractThreadId(message.params);
|
|
23135
23359
|
if (message.method === "turn/completed" && threadId !== void 0) this.turnOwners.delete(threadId);
|
|
23360
|
+
if (message.method === "turn/started" && threadId !== void 0) {
|
|
23361
|
+
const owner = this.turnOwners.get(threadId);
|
|
23362
|
+
const turnId = extractTurnId(message.params);
|
|
23363
|
+
if (owner !== void 0) {
|
|
23364
|
+
this.turnOwners.set(threadId, { ...owner, ...turnId === void 0 ? {} : { turnId } });
|
|
23365
|
+
}
|
|
23366
|
+
}
|
|
23136
23367
|
if (message.method === "serverRequest/resolved") this.resolveUpstreamApproval(message.params);
|
|
23137
23368
|
if (threadId === void 0) return;
|
|
23138
23369
|
await Promise.all([...this.peers.values()].map((peer) => peer.publishInbound(threadId, {
|
|
@@ -23149,7 +23380,7 @@ var CodexRemoteDomain = class {
|
|
|
23149
23380
|
}
|
|
23150
23381
|
const threadId = extractThreadId(message.params);
|
|
23151
23382
|
const owner = threadId === void 0 ? void 0 : this.turnOwners.get(threadId);
|
|
23152
|
-
const peer = owner === void 0 ? void 0 : this.peers.get(owner);
|
|
23383
|
+
const peer = owner === void 0 ? void 0 : this.peers.get(owner.connectionId);
|
|
23153
23384
|
if (threadId === void 0 || owner === void 0 || peer === void 0 || !peer.hasThreadSubscription(threadId)) {
|
|
23154
23385
|
await appServer.respond(message.id, { decision: "decline" });
|
|
23155
23386
|
return;
|
|
@@ -23157,7 +23388,7 @@ var CodexRemoteDomain = class {
|
|
|
23157
23388
|
const requestHandle = randomUUID();
|
|
23158
23389
|
this.approvals.set(requestHandle, {
|
|
23159
23390
|
upstreamId: message.id,
|
|
23160
|
-
connectionId: owner,
|
|
23391
|
+
connectionId: owner.connectionId,
|
|
23161
23392
|
threadId,
|
|
23162
23393
|
method: message.method,
|
|
23163
23394
|
expiresAt: Date.now() + APPROVAL_TTL_MS
|
|
@@ -23176,7 +23407,7 @@ var CodexRemoteDomain = class {
|
|
|
23176
23407
|
}
|
|
23177
23408
|
}
|
|
23178
23409
|
async readKnownThread(threadId) {
|
|
23179
|
-
const authority = await this.
|
|
23410
|
+
const authority = await this.readWorkspaceAuthority();
|
|
23180
23411
|
let result;
|
|
23181
23412
|
try {
|
|
23182
23413
|
result = await this.callUpstream("thread/read", { threadId, includeTurns: false });
|
|
@@ -23189,7 +23420,7 @@ var CodexRemoteDomain = class {
|
|
|
23189
23420
|
return { thread: listed, ...typeof listed.cwd === "string" && listed.cwd.length > 0 ? { cwd: listed.cwd } : {} };
|
|
23190
23421
|
}
|
|
23191
23422
|
const thread = extractThread(result);
|
|
23192
|
-
if (thread === void 0 || thread.id !== threadId || !
|
|
23423
|
+
if (thread === void 0 || thread.id !== threadId || !isThreadAllowedByWorkspaceAuthority(thread, authority)) {
|
|
23193
23424
|
throw new RpcError("CODEX_THREAD_NOT_ALLOWED", "The Codex thread is not available through this Remote Host.");
|
|
23194
23425
|
}
|
|
23195
23426
|
return { thread, ...typeof thread.cwd === "string" && thread.cwd.length > 0 ? { cwd: thread.cwd } : {} };
|
|
@@ -23282,26 +23513,41 @@ var CodexRemoteDomain = class {
|
|
|
23282
23513
|
if (thread === void 0 || typeof thread.id !== "string") {
|
|
23283
23514
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread.");
|
|
23284
23515
|
}
|
|
23285
|
-
if (!
|
|
23516
|
+
if (!isThreadAllowedByWorkspaceAuthority(thread, await this.readWorkspaceAuthority())) {
|
|
23286
23517
|
throw new RpcError("CODEX_THREAD_NOT_ALLOWED", "The Codex thread is not available through this Remote Host.");
|
|
23287
23518
|
}
|
|
23288
23519
|
}
|
|
23289
|
-
claimTurn(threadId, connectionId, method) {
|
|
23520
|
+
claimTurn(threadId, connectionId, method, turnId) {
|
|
23290
23521
|
const owner = this.turnOwners.get(threadId);
|
|
23522
|
+
const peerDeviceId = this.peerDeviceIds.get(connectionId) ?? connectionId;
|
|
23523
|
+
const nextOwner = { connectionId, peerDeviceId, ...turnId === void 0 ? {} : { turnId } };
|
|
23291
23524
|
if (method === "turn/interrupt") {
|
|
23292
23525
|
if (owner === void 0) {
|
|
23293
|
-
this.turnOwners.set(threadId,
|
|
23294
|
-
return true;
|
|
23526
|
+
this.turnOwners.set(threadId, nextOwner);
|
|
23527
|
+
return { claimed: true };
|
|
23295
23528
|
}
|
|
23296
|
-
if (owner !== connectionId
|
|
23297
|
-
|
|
23529
|
+
if (owner.connectionId !== connectionId && owner.peerDeviceId !== peerDeviceId) {
|
|
23530
|
+
throw new RpcError("CODEX_TURN_OWNED", "Only the connection that started this Codex turn can interrupt it.");
|
|
23531
|
+
}
|
|
23532
|
+
if (owner.connectionId !== connectionId) {
|
|
23533
|
+
this.turnOwners.set(threadId, { ...owner, connectionId, peerDeviceId, ...turnId === void 0 ? {} : { turnId } });
|
|
23534
|
+
return { claimed: true, previous: owner };
|
|
23535
|
+
}
|
|
23536
|
+
if (turnId !== void 0 && owner.turnId === void 0) this.turnOwners.set(threadId, { ...owner, turnId });
|
|
23537
|
+
return { claimed: false };
|
|
23298
23538
|
}
|
|
23299
|
-
if (owner !== void 0 && owner !== connectionId) {
|
|
23539
|
+
if (owner !== void 0 && owner.connectionId !== connectionId && owner.peerDeviceId !== peerDeviceId) {
|
|
23300
23540
|
throw new RpcError("CODEX_TURN_OWNED", "Another Remote connection owns the active Codex turn.");
|
|
23301
23541
|
}
|
|
23302
|
-
if (owner === connectionId) return false;
|
|
23303
|
-
this.turnOwners.set(threadId, connectionId);
|
|
23304
|
-
return true;
|
|
23542
|
+
if (owner?.connectionId === connectionId) return { claimed: false };
|
|
23543
|
+
this.turnOwners.set(threadId, owner === void 0 ? nextOwner : { ...owner, connectionId, peerDeviceId });
|
|
23544
|
+
return { claimed: true, previous: owner };
|
|
23545
|
+
}
|
|
23546
|
+
rememberTurnId(threadId, connectionId, turnId) {
|
|
23547
|
+
if (turnId === void 0) return;
|
|
23548
|
+
const owner = this.turnOwners.get(threadId);
|
|
23549
|
+
if (owner === void 0 || owner.connectionId !== connectionId) return;
|
|
23550
|
+
this.turnOwners.set(threadId, { ...owner, turnId });
|
|
23305
23551
|
}
|
|
23306
23552
|
hasSubscriber(threadId) {
|
|
23307
23553
|
return [...this.peers.values()].some((peer) => peer.hasThreadSubscription(threadId));
|
|
@@ -23348,29 +23594,53 @@ var CodexRemoteDomain = class {
|
|
|
23348
23594
|
throw mapAppServerError(error);
|
|
23349
23595
|
}
|
|
23350
23596
|
}
|
|
23351
|
-
async
|
|
23597
|
+
async readWorkspaceAuthority(listedThreads) {
|
|
23352
23598
|
const projectIds = /* @__PURE__ */ new Set();
|
|
23353
23599
|
const roots = [];
|
|
23354
23600
|
let cursor2;
|
|
23355
|
-
|
|
23356
|
-
|
|
23357
|
-
|
|
23358
|
-
|
|
23359
|
-
|
|
23360
|
-
|
|
23361
|
-
const
|
|
23362
|
-
|
|
23363
|
-
|
|
23364
|
-
|
|
23601
|
+
try {
|
|
23602
|
+
for (let page = 0; page < MAX_CODEX_PAGES2; page += 1) {
|
|
23603
|
+
const result = sanitizeProjectList(await this.callUpstream("project/list", {
|
|
23604
|
+
limit: CODEX_PAGE_LIMIT2,
|
|
23605
|
+
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
23606
|
+
}));
|
|
23607
|
+
for (const project of result.data) {
|
|
23608
|
+
const projectRoots = project.roots.map((root) => root.path).filter((path) => isAbsolute3(path));
|
|
23609
|
+
if (projectRoots.length === 0) continue;
|
|
23610
|
+
projectIds.add(project.id);
|
|
23611
|
+
roots.push(...projectRoots);
|
|
23612
|
+
}
|
|
23613
|
+
cursor2 = typeof result.nextCursor === "string" && result.nextCursor.length > 0 ? result.nextCursor : void 0;
|
|
23614
|
+
if (cursor2 === void 0) break;
|
|
23365
23615
|
}
|
|
23366
|
-
|
|
23367
|
-
if (
|
|
23616
|
+
} catch (error) {
|
|
23617
|
+
if (!isProjectListFallbackError(error)) throw error;
|
|
23618
|
+
}
|
|
23619
|
+
if (roots.length > 0) return { projectIds, roots };
|
|
23620
|
+
const threads = listedThreads === void 0 ? [] : [...listedThreads];
|
|
23621
|
+
if (listedThreads === void 0) {
|
|
23622
|
+
cursor2 = void 0;
|
|
23623
|
+
for (let page = 0; page < MAX_CODEX_PAGES2; page += 1) {
|
|
23624
|
+
const result = sanitizeThreadList(await this.callUpstream("thread/list", {
|
|
23625
|
+
limit: CODEX_PAGE_LIMIT2,
|
|
23626
|
+
sortKey: "updated_at",
|
|
23627
|
+
sortDirection: "desc",
|
|
23628
|
+
archived: false,
|
|
23629
|
+
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
23630
|
+
}));
|
|
23631
|
+
threads.push(...result.data);
|
|
23632
|
+
cursor2 = typeof result.nextCursor === "string" && result.nextCursor.length > 0 ? result.nextCursor : void 0;
|
|
23633
|
+
if (cursor2 === void 0) break;
|
|
23634
|
+
}
|
|
23635
|
+
}
|
|
23636
|
+
for (const workspace of deriveCodexCwdWorkspaces(threads)) {
|
|
23637
|
+
if (isAbsolute3(workspace.path)) roots.push(workspace.path);
|
|
23368
23638
|
}
|
|
23369
23639
|
return { projectIds, roots };
|
|
23370
23640
|
}
|
|
23371
23641
|
async findKnownThreadInList(threadId, authority) {
|
|
23372
23642
|
let cursor2;
|
|
23373
|
-
for (let page = 0; page <
|
|
23643
|
+
for (let page = 0; page < MAX_CODEX_PAGES2; page += 1) {
|
|
23374
23644
|
const result = sanitizeThreadList(await this.callUpstream("thread/list", {
|
|
23375
23645
|
limit: 100,
|
|
23376
23646
|
sortKey: "updated_at",
|
|
@@ -23380,7 +23650,7 @@ var CodexRemoteDomain = class {
|
|
|
23380
23650
|
}));
|
|
23381
23651
|
const thread = result.data.find((item) => item.id === threadId);
|
|
23382
23652
|
if (thread !== void 0) {
|
|
23383
|
-
return
|
|
23653
|
+
return isThreadAllowedByWorkspaceAuthority(thread, authority) ? thread : void 0;
|
|
23384
23654
|
}
|
|
23385
23655
|
cursor2 = typeof result.nextCursor === "string" && result.nextCursor.length > 0 ? result.nextCursor : void 0;
|
|
23386
23656
|
if (cursor2 === void 0) break;
|
|
@@ -23391,16 +23661,90 @@ var CodexRemoteDomain = class {
|
|
|
23391
23661
|
if (!isAbsolute3(path)) {
|
|
23392
23662
|
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX working directory is not available as a Workspace.");
|
|
23393
23663
|
}
|
|
23394
|
-
const paths = await this.
|
|
23395
|
-
const
|
|
23396
|
-
|
|
23664
|
+
const paths = await this.listCodexWorkspacePaths();
|
|
23665
|
+
const lexicalCandidate = resolve2(path);
|
|
23666
|
+
let candidate;
|
|
23667
|
+
try {
|
|
23668
|
+
candidate = await realpath(path);
|
|
23669
|
+
if (!(await stat4(candidate)).isDirectory()) throw new Error("not a directory");
|
|
23670
|
+
} catch {
|
|
23671
|
+
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX working directory is not available as a Workspace.");
|
|
23672
|
+
}
|
|
23673
|
+
for (const root of paths.values()) {
|
|
23674
|
+
try {
|
|
23675
|
+
if (!containsCodexPath(resolve2(root), lexicalCandidate)) continue;
|
|
23676
|
+
const canonicalRoot = await realpath(root);
|
|
23677
|
+
if (containsCodexPath(canonicalRoot, candidate)) return lexicalCandidate;
|
|
23678
|
+
} catch {
|
|
23679
|
+
}
|
|
23680
|
+
}
|
|
23681
|
+
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX working directory is not available as a Workspace.");
|
|
23682
|
+
}
|
|
23683
|
+
async listCodexDirectory(path) {
|
|
23684
|
+
const target = await this.resolveCodexDirectory(path);
|
|
23685
|
+
const rows = await readdir2(target.path, { withFileTypes: true }).catch(() => void 0);
|
|
23686
|
+
if (rows === void 0) {
|
|
23687
|
+
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX working directory is not available as a Workspace.");
|
|
23688
|
+
}
|
|
23689
|
+
const entries = [];
|
|
23690
|
+
for (const row of rows) {
|
|
23691
|
+
const child = resolve2(target.path, row.name);
|
|
23692
|
+
let directory = row.isDirectory();
|
|
23693
|
+
if (!directory && row.isSymbolicLink()) {
|
|
23694
|
+
directory = await stat4(child).then((value) => value.isDirectory()).catch(() => false);
|
|
23695
|
+
}
|
|
23696
|
+
if (!directory) continue;
|
|
23697
|
+
try {
|
|
23698
|
+
const canonicalChild = await realpath(child);
|
|
23699
|
+
if (!(await stat4(canonicalChild)).isDirectory()) continue;
|
|
23700
|
+
if (!containsCodexPath(target.canonicalRoot, canonicalChild)) continue;
|
|
23701
|
+
} catch {
|
|
23702
|
+
continue;
|
|
23703
|
+
}
|
|
23704
|
+
entries.push({
|
|
23705
|
+
name: row.name,
|
|
23706
|
+
path: child,
|
|
23707
|
+
hidden: process.platform !== "win32" && row.name.startsWith(".")
|
|
23708
|
+
});
|
|
23709
|
+
}
|
|
23710
|
+
entries.sort((left, right) => left.name.localeCompare(right.name, void 0, { sensitivity: "base" }));
|
|
23711
|
+
return {
|
|
23712
|
+
path: target.path,
|
|
23713
|
+
home: target.root,
|
|
23714
|
+
crumbs: codexDirectoryCrumbs(target.root, target.path),
|
|
23715
|
+
entries: entries.slice(0, CODEX_DIRECTORY_ENTRY_LIMIT),
|
|
23716
|
+
truncated: entries.length > CODEX_DIRECTORY_ENTRY_LIMIT
|
|
23717
|
+
};
|
|
23718
|
+
}
|
|
23719
|
+
async resolveCodexDirectory(path) {
|
|
23720
|
+
if (!isAbsolute3(path)) {
|
|
23721
|
+
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX working directory is not available as a Workspace.");
|
|
23722
|
+
}
|
|
23723
|
+
const authority = await this.readWorkspaceAuthority();
|
|
23724
|
+
const lexicalCandidate = resolve2(path);
|
|
23725
|
+
let canonicalCandidate;
|
|
23726
|
+
try {
|
|
23727
|
+
canonicalCandidate = await realpath(path);
|
|
23728
|
+
if (!(await stat4(canonicalCandidate)).isDirectory()) throw new Error("not a directory");
|
|
23729
|
+
} catch {
|
|
23397
23730
|
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX working directory is not available as a Workspace.");
|
|
23398
23731
|
}
|
|
23399
|
-
|
|
23732
|
+
for (const root of authority.roots) {
|
|
23733
|
+
try {
|
|
23734
|
+
const lexicalRoot = resolve2(root);
|
|
23735
|
+
if (!containsCodexPath(lexicalRoot, lexicalCandidate)) continue;
|
|
23736
|
+
const canonicalRoot = await realpath(root);
|
|
23737
|
+
if (containsCodexPath(canonicalRoot, canonicalCandidate)) {
|
|
23738
|
+
return { path: lexicalCandidate, root: lexicalRoot, canonicalRoot };
|
|
23739
|
+
}
|
|
23740
|
+
} catch {
|
|
23741
|
+
}
|
|
23742
|
+
}
|
|
23743
|
+
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX working directory is not available as a Workspace.");
|
|
23400
23744
|
}
|
|
23401
|
-
async
|
|
23745
|
+
async listCodexWorkspacePaths() {
|
|
23402
23746
|
const paths = /* @__PURE__ */ new Map();
|
|
23403
|
-
const authority = await this.
|
|
23747
|
+
const authority = await this.readWorkspaceAuthority();
|
|
23404
23748
|
for (const root of authority.roots) paths.set(normalizeCodexPathForCompare(root), root);
|
|
23405
23749
|
return paths;
|
|
23406
23750
|
}
|
|
@@ -23469,13 +23813,13 @@ function sanitizeThreadList(result) {
|
|
|
23469
23813
|
...typeof result.backwardsCursor === "string" && result.backwardsCursor.length > 0 ? { backwardsCursor: result.backwardsCursor } : {}
|
|
23470
23814
|
};
|
|
23471
23815
|
}
|
|
23472
|
-
function
|
|
23816
|
+
function filterThreadListByWorkspaceAuthority(result, authority) {
|
|
23473
23817
|
if (!isRecord9(result) || !Array.isArray(result.data)) {
|
|
23474
23818
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
23475
23819
|
}
|
|
23476
23820
|
return {
|
|
23477
23821
|
...result,
|
|
23478
|
-
data: result.data.map((record4) => isRecord9(record4) ? record4 : void 0).filter((thread) => thread !== void 0 &&
|
|
23822
|
+
data: result.data.map((record4) => isRecord9(record4) ? record4 : void 0).filter((thread) => thread !== void 0 && isThreadAllowedByWorkspaceAuthority(thread, authority))
|
|
23479
23823
|
};
|
|
23480
23824
|
}
|
|
23481
23825
|
function sanitizeProjectList(result) {
|
|
@@ -23503,7 +23847,7 @@ function sanitizeProjectList(result) {
|
|
|
23503
23847
|
...typeof result.nextCursor === "string" && result.nextCursor.length > 0 ? { nextCursor: result.nextCursor } : { nextCursor: null }
|
|
23504
23848
|
};
|
|
23505
23849
|
}
|
|
23506
|
-
function
|
|
23850
|
+
function isThreadAllowedByWorkspaceAuthority(thread, authority) {
|
|
23507
23851
|
const projectId = typeof thread.projectId === "string" ? thread.projectId : void 0;
|
|
23508
23852
|
if (projectId !== void 0 && authority.projectIds.has(projectId)) return true;
|
|
23509
23853
|
const cwd = typeof thread.cwd === "string" ? thread.cwd : void 0;
|
|
@@ -23517,9 +23861,26 @@ function containsCodexPath(root, candidate) {
|
|
|
23517
23861
|
function normalizeCodexPathForCompare(path) {
|
|
23518
23862
|
return path.replace(/[\\/]+$/u, "") || path;
|
|
23519
23863
|
}
|
|
23864
|
+
function codexDirectoryCrumbs(root, path) {
|
|
23865
|
+
const crumbs2 = [{ name: basename3(root) || root, path: root, hidden: false }];
|
|
23866
|
+
const remainder = relative(root, path);
|
|
23867
|
+
if (remainder === "") return crumbs2;
|
|
23868
|
+
let current = root;
|
|
23869
|
+
for (const segment of remainder.split(/[\\/]+/u).filter(Boolean)) {
|
|
23870
|
+
current = resolve2(current, segment);
|
|
23871
|
+
crumbs2.push({ name: segment, path: current, hidden: false });
|
|
23872
|
+
}
|
|
23873
|
+
return crumbs2;
|
|
23874
|
+
}
|
|
23520
23875
|
function extractThread(result) {
|
|
23521
23876
|
return isRecord9(result) && isRecord9(result.thread) ? result.thread : void 0;
|
|
23522
23877
|
}
|
|
23878
|
+
function extractTurnId(result) {
|
|
23879
|
+
if (!isRecord9(result)) return void 0;
|
|
23880
|
+
if (typeof result.turnId === "string" && result.turnId.length > 0) return result.turnId;
|
|
23881
|
+
if (isRecord9(result.turn) && typeof result.turn.id === "string" && result.turn.id.length > 0) return result.turn.id;
|
|
23882
|
+
return void 0;
|
|
23883
|
+
}
|
|
23523
23884
|
function extractThreadId(params) {
|
|
23524
23885
|
if (!isRecord9(params)) return void 0;
|
|
23525
23886
|
if (typeof params.threadId === "string") return params.threadId;
|
|
@@ -23530,15 +23891,37 @@ function extractThreadId(params) {
|
|
|
23530
23891
|
function optionalInteger2(value) {
|
|
23531
23892
|
return typeof value === "number" && Number.isSafeInteger(value) ? value : void 0;
|
|
23532
23893
|
}
|
|
23533
|
-
function codexPermission(params) {
|
|
23894
|
+
function codexPermission(params, fallbackPreset) {
|
|
23534
23895
|
const { permissionPreset: permissionPreset2, ...rest } = params;
|
|
23535
|
-
const
|
|
23896
|
+
const preset = permissionPreset2 === "workspace-write" || permissionPreset2 === "danger-full-access" ? permissionPreset2 : fallbackPreset;
|
|
23897
|
+
if (preset === void 0) return { params: mapCodexImageInputs(rest) };
|
|
23898
|
+
const fullAccess = preset === "danger-full-access";
|
|
23536
23899
|
return {
|
|
23537
23900
|
params: mapCodexImageInputs(rest),
|
|
23538
23901
|
approvalPolicy: fullAccess ? "never" : "on-request",
|
|
23539
23902
|
sandbox: fullAccess ? "danger-full-access" : "workspace-write"
|
|
23540
23903
|
};
|
|
23541
23904
|
}
|
|
23905
|
+
function codexThreadPermissionParams(permission) {
|
|
23906
|
+
if (permission.approvalPolicy === void 0 || permission.sandbox === void 0) return {};
|
|
23907
|
+
return {
|
|
23908
|
+
approvalPolicy: permission.approvalPolicy,
|
|
23909
|
+
sandbox: permission.sandbox
|
|
23910
|
+
};
|
|
23911
|
+
}
|
|
23912
|
+
function codexTurnPermissionParams(permission, cwd) {
|
|
23913
|
+
if (permission.approvalPolicy === void 0 || permission.sandbox === void 0) return {};
|
|
23914
|
+
return {
|
|
23915
|
+
approvalPolicy: permission.approvalPolicy,
|
|
23916
|
+
sandboxPolicy: permission.sandbox === "danger-full-access" ? { type: "dangerFullAccess" } : {
|
|
23917
|
+
type: "workspaceWrite",
|
|
23918
|
+
writableRoots: cwd === void 0 ? [] : [cwd],
|
|
23919
|
+
networkAccess: false,
|
|
23920
|
+
excludeTmpdirEnvVar: false,
|
|
23921
|
+
excludeSlashTmp: false
|
|
23922
|
+
}
|
|
23923
|
+
};
|
|
23924
|
+
}
|
|
23542
23925
|
function mapCodexImageInputs(params) {
|
|
23543
23926
|
if (!Array.isArray(params.input)) return params;
|
|
23544
23927
|
return {
|
|
@@ -23575,6 +23958,9 @@ function errorCode3(error) {
|
|
|
23575
23958
|
function isHistoryReadRecoverable(error) {
|
|
23576
23959
|
return error instanceof RpcError && ["METHOD_NOT_ALLOWED", "METHOD_NOT_FOUND", "CODEX_UPSTREAM_ERROR", "CODEX_REQUEST_TIMEOUT", "CODEX_THREAD_BUSY"].includes(error.code);
|
|
23577
23960
|
}
|
|
23961
|
+
function isProjectListFallbackError(error) {
|
|
23962
|
+
return error instanceof RpcError && ["METHOD_NOT_ALLOWED", "METHOD_NOT_FOUND", "CODEX_UPSTREAM_ERROR"].includes(error.code);
|
|
23963
|
+
}
|
|
23578
23964
|
function canTryNextBinary(error) {
|
|
23579
23965
|
return !(error instanceof RpcError) || !["CODEX_AUTH_REQUIRED", "CODEX_CLOSED"].includes(error.code);
|
|
23580
23966
|
}
|
|
@@ -23693,13 +24079,42 @@ var HostPluginRuntime = class {
|
|
|
23693
24079
|
}
|
|
23694
24080
|
this.serverConnection.reconnect();
|
|
23695
24081
|
}
|
|
24082
|
+
async startHostOAuthQrLogin(provider) {
|
|
24083
|
+
if (this.serverApi === void 0) {
|
|
24084
|
+
throw new ServerApiError("SERVER_NOT_CONFIGURED", "Remote Host Server is unavailable.", false);
|
|
24085
|
+
}
|
|
24086
|
+
return this.serverApi.startOAuthQrLogin(provider);
|
|
24087
|
+
}
|
|
24088
|
+
async pollHostOAuthQrLogin(qrId) {
|
|
24089
|
+
if (this.serverApi === void 0) {
|
|
24090
|
+
throw new ServerApiError("SERVER_NOT_CONFIGURED", "Remote Host Server is unavailable.", false);
|
|
24091
|
+
}
|
|
24092
|
+
const result = await this.serverApi.pollOAuthQrLogin(this.currentIdentity(), qrId, async () => {
|
|
24093
|
+
await this.serverConnection?.stop();
|
|
24094
|
+
this.identity = await this.identities.reset(this.config.deviceName);
|
|
24095
|
+
this.serverApi.bindIdentity(this.identity);
|
|
24096
|
+
this.serverConnection = this.createServerConnection(this.identity);
|
|
24097
|
+
return this.identity;
|
|
24098
|
+
});
|
|
24099
|
+
if (result.status === "complete") {
|
|
24100
|
+
this.serverConnection?.reconnect();
|
|
24101
|
+
this.logger.info("Host account authorized through OAuth QR login");
|
|
24102
|
+
}
|
|
24103
|
+
return result;
|
|
24104
|
+
}
|
|
23696
24105
|
async clearHostAuthorization() {
|
|
23697
24106
|
await this.serverConnection?.stop();
|
|
23698
|
-
|
|
24107
|
+
let revokeFailure;
|
|
24108
|
+
try {
|
|
24109
|
+
await this.serverApi?.revokeCurrentDevice();
|
|
24110
|
+
} catch (error) {
|
|
24111
|
+
revokeFailure = error;
|
|
24112
|
+
}
|
|
23699
24113
|
this.identity = await this.identities.reset(this.config.deviceName);
|
|
23700
24114
|
this.serverApi?.bindIdentity(this.identity);
|
|
23701
24115
|
if (this.serverApi !== void 0) this.serverConnection = this.createServerConnection(this.identity);
|
|
23702
24116
|
this.logger.info("Host authorization cleared");
|
|
24117
|
+
if (revokeFailure !== void 0) throw revokeFailure;
|
|
23703
24118
|
}
|
|
23704
24119
|
async authorizeHostAsOwned(accessToken, account) {
|
|
23705
24120
|
if (this.serverApi === void 0) {
|
|
@@ -23787,6 +24202,7 @@ var HostPluginRuntime = class {
|
|
|
23787
24202
|
peerDeviceId: this.connections.peerDeviceId() === void 0 ? void 0 : shortId5(this.connections.peerDeviceId()),
|
|
23788
24203
|
peerDeviceIds: this.connections.peerDeviceIds().map(shortId5),
|
|
23789
24204
|
trustedPeers: this.identities.listTrustedPeers().length,
|
|
24205
|
+
capabilities: this.hostCapabilities(),
|
|
23790
24206
|
codex: this.codex.status()
|
|
23791
24207
|
};
|
|
23792
24208
|
}
|
|
@@ -23806,12 +24222,12 @@ var HostPluginRuntime = class {
|
|
|
23806
24222
|
}
|
|
23807
24223
|
async readHarnessVersion() {
|
|
23808
24224
|
let reportedVersion;
|
|
23809
|
-
let
|
|
24225
|
+
let errorCode5;
|
|
23810
24226
|
try {
|
|
23811
24227
|
const response = await this.apiProxy?.host.describe({ rpcId: randomUUID2(), payload: {} });
|
|
23812
24228
|
if (response === void 0) throw new Error("ApiProxy is unavailable");
|
|
23813
24229
|
if (!response.result.ok) {
|
|
23814
|
-
|
|
24230
|
+
errorCode5 = response.result.error.code;
|
|
23815
24231
|
} else {
|
|
23816
24232
|
reportedVersion = normalizeHarnessVersion(response.result.value.version);
|
|
23817
24233
|
}
|
|
@@ -23820,7 +24236,7 @@ var HostPluginRuntime = class {
|
|
|
23820
24236
|
const distributionVersion = reportedVersion === void 0 || reportedVersion === "0.0.1" ? await readHarnessDistributionVersion() : void 0;
|
|
23821
24237
|
const version = selectHarnessVersion(reportedVersion, distributionVersion);
|
|
23822
24238
|
if (version !== void 0) return version;
|
|
23823
|
-
this.logger.warn("Harness version is unavailable",
|
|
24239
|
+
this.logger.warn("Harness version is unavailable", errorCode5 === void 0 ? void 0 : { code: errorCode5 });
|
|
23824
24240
|
return void 0;
|
|
23825
24241
|
}
|
|
23826
24242
|
hostCapabilities() {
|
|
@@ -23857,6 +24273,618 @@ function isPlainRecord(value) {
|
|
|
23857
24273
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23858
24274
|
}
|
|
23859
24275
|
|
|
24276
|
+
// src/cli.ts
|
|
24277
|
+
import { stat as stat5 } from "node:fs/promises";
|
|
24278
|
+
import { hostname as hostname3 } from "node:os";
|
|
24279
|
+
import { join as join6 } from "node:path";
|
|
24280
|
+
var QR_POLL_INTERVAL_MS = 2e3;
|
|
24281
|
+
var TERMINAL_QR_MARGIN = 4;
|
|
24282
|
+
async function runCli(args = process.argv.slice(2), dependencies = {}) {
|
|
24283
|
+
const runtime = resolveDependencies(dependencies);
|
|
24284
|
+
const [command, ...rest] = args;
|
|
24285
|
+
try {
|
|
24286
|
+
if (command === "login") return await login(rest, runtime);
|
|
24287
|
+
if (command === "status") return await status(rest, runtime);
|
|
24288
|
+
if (command === "logout") return await logout(rest, runtime);
|
|
24289
|
+
if (command === "help" || command === "--help" || command === "-h" || command === void 0) {
|
|
24290
|
+
write(runtime.stdout, helpText());
|
|
24291
|
+
return 0;
|
|
24292
|
+
}
|
|
24293
|
+
throw new CliUsageError(`Unknown command: ${command}`);
|
|
24294
|
+
} catch (error) {
|
|
24295
|
+
write(runtime.stderr, `${cliErrorMessage(error)}
|
|
24296
|
+
`);
|
|
24297
|
+
if (error instanceof CliUsageError) write(runtime.stderr, `
|
|
24298
|
+
${helpText()}`);
|
|
24299
|
+
return error instanceof CliUsageError ? 2 : 1;
|
|
24300
|
+
}
|
|
24301
|
+
}
|
|
24302
|
+
async function login(args, runtime) {
|
|
24303
|
+
if (args.length > 1) throw new CliUsageError("Usage: ds-harness-remote login [github|zhihu]");
|
|
24304
|
+
const provider = args[0] ?? "zhihu";
|
|
24305
|
+
if (provider !== "github" && provider !== "zhihu") {
|
|
24306
|
+
throw new CliUsageError("Login provider must be github or zhihu.");
|
|
24307
|
+
}
|
|
24308
|
+
const context = await hostContext(runtime);
|
|
24309
|
+
const session = await context.api.startOAuthQrLogin(provider);
|
|
24310
|
+
const qr = await runtime.renderQr(session.scanUrl);
|
|
24311
|
+
const providerName = provider === "github" ? "GitHub" : "Zhihu";
|
|
24312
|
+
write(runtime.stdout, `Using ${providerName} QR login. ${alternativeProviderHint(provider)}
|
|
24313
|
+
`);
|
|
24314
|
+
write(runtime.stdout, "Scan this QR code to authorize this Host:\n\n");
|
|
24315
|
+
write(runtime.stdout, `${qr.trimEnd()}
|
|
24316
|
+
`);
|
|
24317
|
+
write(runtime.stdout, `Authorization URL: ${terminalLink(session.scanUrl, runtime.stdout)}
|
|
24318
|
+
|
|
24319
|
+
Waiting for authorization...
|
|
24320
|
+
`);
|
|
24321
|
+
const deadline = runtime.now() + session.expiresIn * 1e3;
|
|
24322
|
+
let identity = context.identity;
|
|
24323
|
+
while (runtime.now() < deadline) {
|
|
24324
|
+
let result;
|
|
24325
|
+
try {
|
|
24326
|
+
result = await context.api.pollOAuthQrLogin(identity, session.qrId, async () => {
|
|
24327
|
+
identity = await context.identities.reset(context.deviceName);
|
|
24328
|
+
return identity;
|
|
24329
|
+
});
|
|
24330
|
+
} catch (error) {
|
|
24331
|
+
if (!(error instanceof ServerApiError) || !error.retryable) throw error;
|
|
24332
|
+
await runtime.wait(Math.min(QR_POLL_INTERVAL_MS, Math.max(1, deadline - runtime.now())));
|
|
24333
|
+
continue;
|
|
24334
|
+
}
|
|
24335
|
+
if (result.status === "complete") {
|
|
24336
|
+
write(runtime.stdout, `${authorizedMessage(result.authorization)} Restart dsh-tui to bring the Remote Host online.
|
|
24337
|
+
`);
|
|
24338
|
+
return 0;
|
|
24339
|
+
}
|
|
24340
|
+
if (result.status === "expired") break;
|
|
24341
|
+
await runtime.wait(Math.min(QR_POLL_INTERVAL_MS, Math.max(1, deadline - runtime.now())));
|
|
24342
|
+
}
|
|
24343
|
+
write(runtime.stderr, "The QR login expired. Run the login command again to generate a new code.\n");
|
|
24344
|
+
return 1;
|
|
24345
|
+
}
|
|
24346
|
+
async function status(args, runtime) {
|
|
24347
|
+
if (args.length !== 0) throw new CliUsageError("Usage: ds-harness-remote status");
|
|
24348
|
+
const serverUrl = selectedServer();
|
|
24349
|
+
const root = new IdentityStore({ env: runtime.env }).directory;
|
|
24350
|
+
const directory = serverStorageDirectory(root, serverUrl, "host");
|
|
24351
|
+
const lines = [
|
|
24352
|
+
"Remote Host status",
|
|
24353
|
+
`Server: ${serverUrl}`,
|
|
24354
|
+
"Host control: enabled (dsh-TUI default)"
|
|
24355
|
+
];
|
|
24356
|
+
if (!await exists3(join6(directory, "device.json"))) {
|
|
24357
|
+
lines.push("Device: not initialized", "Authorization: logged out", "Credential: unavailable");
|
|
24358
|
+
write(runtime.stdout, `${lines.join("\n")}
|
|
24359
|
+
|
|
24360
|
+
Run "ds-harness-remote login" or use "/remote login" in dsh-TUI.
|
|
24361
|
+
`);
|
|
24362
|
+
return 0;
|
|
24363
|
+
}
|
|
24364
|
+
const identities = runtime.createIdentityStore({ directory, env: runtime.env });
|
|
24365
|
+
const identity = await identities.loadOrCreate(hostname3());
|
|
24366
|
+
const store = new ServerCredentialStore(directory);
|
|
24367
|
+
const stored = await store.load(serverUrl, identity.deviceId);
|
|
24368
|
+
lines.push(`Device: ${identity.name} (${identity.deviceId})`);
|
|
24369
|
+
if (stored === void 0) {
|
|
24370
|
+
lines.push("Authorization: logged out", "Credential: unavailable");
|
|
24371
|
+
write(runtime.stdout, `${lines.join("\n")}
|
|
24372
|
+
|
|
24373
|
+
Run "ds-harness-remote login" or use "/remote login" in dsh-TUI.
|
|
24374
|
+
`);
|
|
24375
|
+
return 0;
|
|
24376
|
+
}
|
|
24377
|
+
lines.push(`Authorization: logged in (${authorizationLabel(stored.authorizationMethod)})`);
|
|
24378
|
+
if (stored.account !== void 0) lines.push(`Account: ${stored.account}`);
|
|
24379
|
+
const api = runtime.createHostApi(serverUrl, store);
|
|
24380
|
+
api.bindIdentity(identity);
|
|
24381
|
+
try {
|
|
24382
|
+
await api.authenticate(identity);
|
|
24383
|
+
lines.push("Credential: ready");
|
|
24384
|
+
lines.push("Presence: published while dsh-tui is running");
|
|
24385
|
+
write(runtime.stdout, `${lines.join("\n")}
|
|
24386
|
+
`);
|
|
24387
|
+
return 0;
|
|
24388
|
+
} catch (error) {
|
|
24389
|
+
lines.push(`Credential: unavailable (${statusErrorCode(error)})`);
|
|
24390
|
+
write(runtime.stdout, `${lines.join("\n")}
|
|
24391
|
+
`);
|
|
24392
|
+
return 1;
|
|
24393
|
+
}
|
|
24394
|
+
}
|
|
24395
|
+
async function logout(args, runtime) {
|
|
24396
|
+
if (args.length !== 0) throw new CliUsageError("Usage: ds-harness-remote logout");
|
|
24397
|
+
const serverUrl = selectedServer();
|
|
24398
|
+
const root = new IdentityStore({ env: runtime.env }).directory;
|
|
24399
|
+
const directory = serverStorageDirectory(root, serverUrl, "host");
|
|
24400
|
+
if (!await exists3(join6(directory, "device.json"))) {
|
|
24401
|
+
await new ServerCredentialStore(directory).clear();
|
|
24402
|
+
write(runtime.stdout, "This Host is already logged out.\n");
|
|
24403
|
+
return 0;
|
|
24404
|
+
}
|
|
24405
|
+
const deviceName = hostname3();
|
|
24406
|
+
const identities = runtime.createIdentityStore({ directory, env: runtime.env });
|
|
24407
|
+
const identity = await identities.loadOrCreate(deviceName);
|
|
24408
|
+
const api = runtime.createHostApi(serverUrl, new ServerCredentialStore(directory));
|
|
24409
|
+
api.bindIdentity(identity);
|
|
24410
|
+
let revokeFailure;
|
|
24411
|
+
try {
|
|
24412
|
+
await api.revokeCurrentDevice();
|
|
24413
|
+
} catch (error) {
|
|
24414
|
+
revokeFailure = error;
|
|
24415
|
+
}
|
|
24416
|
+
await identities.reset(deviceName);
|
|
24417
|
+
if (revokeFailure !== void 0) {
|
|
24418
|
+
throw new Error(`Local Host credentials were cleared, but Server revocation failed: ${cliErrorMessage(revokeFailure)}`);
|
|
24419
|
+
}
|
|
24420
|
+
write(runtime.stdout, "Remote Host logged out and its local device identity was rotated. Restart dsh-tui.\n");
|
|
24421
|
+
return 0;
|
|
24422
|
+
}
|
|
24423
|
+
async function hostContext(runtime) {
|
|
24424
|
+
const serverUrl = selectedServer();
|
|
24425
|
+
const root = new IdentityStore({ env: runtime.env }).directory;
|
|
24426
|
+
const directory = serverStorageDirectory(root, serverUrl, "host");
|
|
24427
|
+
const deviceName = hostname3();
|
|
24428
|
+
const identities = runtime.createIdentityStore({ directory, env: runtime.env });
|
|
24429
|
+
const identity = await identities.loadOrCreate(deviceName);
|
|
24430
|
+
const api = runtime.createHostApi(serverUrl, new ServerCredentialStore(directory));
|
|
24431
|
+
return { api, identities, identity, deviceName };
|
|
24432
|
+
}
|
|
24433
|
+
function selectedServer() {
|
|
24434
|
+
return normalizeServerUrl(DEFAULT_REMOTE_SERVER_URL);
|
|
24435
|
+
}
|
|
24436
|
+
function resolveDependencies(input2) {
|
|
24437
|
+
return {
|
|
24438
|
+
env: input2.env ?? process.env,
|
|
24439
|
+
stdout: input2.stdout ?? process.stdout,
|
|
24440
|
+
stderr: input2.stderr ?? process.stderr,
|
|
24441
|
+
now: input2.now ?? Date.now,
|
|
24442
|
+
wait: input2.wait ?? ((milliseconds) => new Promise((resolve3) => setTimeout(resolve3, milliseconds))),
|
|
24443
|
+
renderQr: input2.renderQr ?? renderTerminalQr,
|
|
24444
|
+
createIdentityStore: input2.createIdentityStore ?? ((options) => new IdentityStore(options)),
|
|
24445
|
+
createHostApi: input2.createHostApi ?? ((serverUrl, store) => new HostServerApi(serverUrl, store))
|
|
24446
|
+
};
|
|
24447
|
+
}
|
|
24448
|
+
async function renderTerminalQr(url) {
|
|
24449
|
+
const { default: QRCode } = await import("qrcode");
|
|
24450
|
+
const modules = QRCode.create(url, { errorCorrectionLevel: "M" }).modules;
|
|
24451
|
+
const width = modules.size + TERMINAL_QR_MARGIN * 2;
|
|
24452
|
+
const quietLine = `\x1B[47m${" ".repeat(width * 2)}\x1B[0m`;
|
|
24453
|
+
const lines = Array.from({ length: TERMINAL_QR_MARGIN }, () => quietLine);
|
|
24454
|
+
for (let row = 0; row < modules.size; row += 1) {
|
|
24455
|
+
let line = `\x1B[47m${" ".repeat(TERMINAL_QR_MARGIN * 2)}`;
|
|
24456
|
+
for (let column = 0; column < modules.size; column += 1) {
|
|
24457
|
+
line += modules.get(row, column) === 1 ? "\x1B[40m " : "\x1B[47m ";
|
|
24458
|
+
}
|
|
24459
|
+
line += `\x1B[47m${" ".repeat(TERMINAL_QR_MARGIN * 2)}\x1B[0m`;
|
|
24460
|
+
lines.push(line);
|
|
24461
|
+
}
|
|
24462
|
+
lines.push(...Array.from({ length: TERMINAL_QR_MARGIN }, () => quietLine));
|
|
24463
|
+
return lines.join("\n");
|
|
24464
|
+
}
|
|
24465
|
+
async function renderCompactTerminalQr(url) {
|
|
24466
|
+
const { default: QRCode } = await import("qrcode");
|
|
24467
|
+
const modules = QRCode.create(url, { errorCorrectionLevel: "M" }).modules;
|
|
24468
|
+
const size = modules.size + TERMINAL_QR_MARGIN * 2;
|
|
24469
|
+
const lines = [];
|
|
24470
|
+
const isBlack = (row, column) => {
|
|
24471
|
+
const qrRow = row - TERMINAL_QR_MARGIN;
|
|
24472
|
+
const qrColumn = column - TERMINAL_QR_MARGIN;
|
|
24473
|
+
return qrRow >= 0 && qrRow < modules.size && qrColumn >= 0 && qrColumn < modules.size && modules.get(qrRow, qrColumn) === 1;
|
|
24474
|
+
};
|
|
24475
|
+
for (let row = 0; row < size; row += 2) {
|
|
24476
|
+
let line = "\x1B[30;47m";
|
|
24477
|
+
for (let column = 0; column < size; column += 1) {
|
|
24478
|
+
const top = isBlack(row, column);
|
|
24479
|
+
const bottom = isBlack(row + 1, column);
|
|
24480
|
+
line += top ? bottom ? "\u2588" : "\u2580" : bottom ? "\u2584" : " ";
|
|
24481
|
+
}
|
|
24482
|
+
lines.push(`${line}\x1B[0m`);
|
|
24483
|
+
}
|
|
24484
|
+
return lines.join("\n");
|
|
24485
|
+
}
|
|
24486
|
+
function authorizedMessage(authorization) {
|
|
24487
|
+
return authorization.account === void 0 ? "Remote Host login complete." : `Remote Host login complete for ${authorization.account}.`;
|
|
24488
|
+
}
|
|
24489
|
+
function alternativeProviderHint(provider) {
|
|
24490
|
+
return provider === "zhihu" ? "GitHub is also supported: ds-harness-remote login github" : "Zhihu is also supported: ds-harness-remote login zhihu";
|
|
24491
|
+
}
|
|
24492
|
+
function authorizationLabel(method) {
|
|
24493
|
+
if (method === "host_registration_code") return "Host registration code";
|
|
24494
|
+
if (method === "owned_device") return "owned device";
|
|
24495
|
+
return "account";
|
|
24496
|
+
}
|
|
24497
|
+
function statusErrorCode(error) {
|
|
24498
|
+
return error instanceof ServerApiError ? error.code : "CONNECTION_FAILED";
|
|
24499
|
+
}
|
|
24500
|
+
function cliErrorMessage(error) {
|
|
24501
|
+
const message = error instanceof Error ? error.message : "The Remote command failed.";
|
|
24502
|
+
const code = error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
24503
|
+
return code === void 0 ? message : `${message} (${code})`;
|
|
24504
|
+
}
|
|
24505
|
+
function helpText() {
|
|
24506
|
+
return [
|
|
24507
|
+
"Usage:",
|
|
24508
|
+
" ds-harness-remote login [github|zhihu]",
|
|
24509
|
+
" ds-harness-remote status",
|
|
24510
|
+
" ds-harness-remote logout",
|
|
24511
|
+
"",
|
|
24512
|
+
"Inside dsh-TUI, use /remote login, /remote status, or /remote logout.",
|
|
24513
|
+
"login defaults to Zhihu and authorizes this computer as a Remote Host with a terminal QR code.",
|
|
24514
|
+
`The Server is ${DEFAULT_REMOTE_SERVER_URL}.`,
|
|
24515
|
+
"Host configuration is not exposed by this CLI yet. Restart dsh-tui after login or logout.",
|
|
24516
|
+
""
|
|
24517
|
+
].join("\n");
|
|
24518
|
+
}
|
|
24519
|
+
function write(target, value) {
|
|
24520
|
+
target.write(value);
|
|
24521
|
+
}
|
|
24522
|
+
function terminalLink(url, target) {
|
|
24523
|
+
if (target.isTTY !== true) return url;
|
|
24524
|
+
return `\x1B]8;;${url}\x07${url}\x1B]8;;\x07`;
|
|
24525
|
+
}
|
|
24526
|
+
async function exists3(path) {
|
|
24527
|
+
try {
|
|
24528
|
+
await stat5(path);
|
|
24529
|
+
return true;
|
|
24530
|
+
} catch (error) {
|
|
24531
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return false;
|
|
24532
|
+
throw error;
|
|
24533
|
+
}
|
|
24534
|
+
}
|
|
24535
|
+
var CliUsageError = class extends Error {
|
|
24536
|
+
};
|
|
24537
|
+
|
|
24538
|
+
// src/tui-command.ts
|
|
24539
|
+
var QR_POLL_INTERVAL_MS2 = 2e3;
|
|
24540
|
+
var REMOTE_LOGIN_SCENE_ID = "remote-login";
|
|
24541
|
+
var REMOTE_STATUS_SCENE_ID = "remote-status";
|
|
24542
|
+
function installTuiRemoteCommand(ctx, resolveTarget) {
|
|
24543
|
+
const tuiContext = ctx;
|
|
24544
|
+
const commands = tuiContext.get("commands", false);
|
|
24545
|
+
if (commands === void 0) return;
|
|
24546
|
+
const pluginHost = tuiContext.get("tuiPluginHost", false);
|
|
24547
|
+
const trees = tuiContext.get("tuiCommandTrees", false);
|
|
24548
|
+
const scenes = tuiContext.get("tuiScenes", false);
|
|
24549
|
+
const login2 = new RemoteLoginController(resolveTarget);
|
|
24550
|
+
const LoginScene = createRemoteLoginScene(login2);
|
|
24551
|
+
const StatusScene = createRemoteStatusScene(resolveTarget);
|
|
24552
|
+
tuiContext.effect(() => {
|
|
24553
|
+
const definition = {
|
|
24554
|
+
name: "remote",
|
|
24555
|
+
description: "Manage Remote Host login and connection status",
|
|
24556
|
+
input: { hint: "[status | login [github|zhihu] | logout]" },
|
|
24557
|
+
recordInput: false,
|
|
24558
|
+
handler: async ({ rawInput }) => {
|
|
24559
|
+
const args = rawInput.trim().split(/\s+/u).filter(Boolean);
|
|
24560
|
+
const command = args[0] ?? "status";
|
|
24561
|
+
if (command === "status" && args.length <= 1) {
|
|
24562
|
+
if (scenes?.open(REMOTE_STATUS_SCENE_ID) === true) return { kind: "success" };
|
|
24563
|
+
return { kind: "success", text: formatRemoteStatusInline(resolveTarget()) };
|
|
24564
|
+
}
|
|
24565
|
+
if (command === "login" && args.length <= 2) {
|
|
24566
|
+
const provider = args[1] ?? "zhihu";
|
|
24567
|
+
if (provider !== "github" && provider !== "zhihu") {
|
|
24568
|
+
return { kind: "error", text: "Usage: /remote login [github|zhihu]" };
|
|
24569
|
+
}
|
|
24570
|
+
if (scenes === void 0) {
|
|
24571
|
+
return {
|
|
24572
|
+
kind: "error",
|
|
24573
|
+
text: `The Remote login screen is unavailable. Run "ds-harness-remote login ${provider}" outside dsh-TUI, then restart it.`
|
|
24574
|
+
};
|
|
24575
|
+
}
|
|
24576
|
+
login2.start(provider);
|
|
24577
|
+
if (!scenes.open(REMOTE_LOGIN_SCENE_ID)) {
|
|
24578
|
+
login2.cancel();
|
|
24579
|
+
return { kind: "error", text: "The Remote login screen is unavailable." };
|
|
24580
|
+
}
|
|
24581
|
+
return { kind: "success" };
|
|
24582
|
+
}
|
|
24583
|
+
if (command === "logout" && args.length === 1) {
|
|
24584
|
+
const target = resolveTarget();
|
|
24585
|
+
if (target === void 0) return remoteNotReady();
|
|
24586
|
+
try {
|
|
24587
|
+
await target.runtime.clearHostAuthorization();
|
|
24588
|
+
return {
|
|
24589
|
+
kind: "success",
|
|
24590
|
+
text: "Remote Host logged out and its local device identity was rotated."
|
|
24591
|
+
};
|
|
24592
|
+
} catch (error) {
|
|
24593
|
+
return {
|
|
24594
|
+
kind: "error",
|
|
24595
|
+
text: `Local Remote Host credentials were cleared, but Server revocation failed (${errorCode4(error)}).`
|
|
24596
|
+
};
|
|
24597
|
+
}
|
|
24598
|
+
}
|
|
24599
|
+
if (command === "config") {
|
|
24600
|
+
return { kind: "error", text: "Host configuration is not supported yet." };
|
|
24601
|
+
}
|
|
24602
|
+
return { kind: "error", text: remoteCommandUsage() };
|
|
24603
|
+
}
|
|
24604
|
+
};
|
|
24605
|
+
const disposeCommand = registerRemoteCommand(tuiContext, commands, pluginHost, definition);
|
|
24606
|
+
const disposeTree = registerOptional(tuiContext, "command completion", () => trees?.register({
|
|
24607
|
+
root: "remote",
|
|
24608
|
+
descriptions: {
|
|
24609
|
+
en: "Manage Remote Host login and connection status",
|
|
24610
|
+
zh: "\u7BA1\u7406 Remote Host \u767B\u5F55\u548C\u8FDE\u63A5\u72B6\u6001"
|
|
24611
|
+
},
|
|
24612
|
+
children: remoteCommandChildren
|
|
24613
|
+
}));
|
|
24614
|
+
const disposeScene = registerOptional(tuiContext, "login scene", () => scenes?.register({
|
|
24615
|
+
id: REMOTE_LOGIN_SCENE_ID,
|
|
24616
|
+
title: "Remote Host login",
|
|
24617
|
+
component: LoginScene
|
|
24618
|
+
}, tuiContext));
|
|
24619
|
+
const disposeStatusScene = registerOptional(tuiContext, "status scene", () => scenes?.register({
|
|
24620
|
+
id: REMOTE_STATUS_SCENE_ID,
|
|
24621
|
+
title: "Remote Host status",
|
|
24622
|
+
component: StatusScene
|
|
24623
|
+
}, tuiContext));
|
|
24624
|
+
return () => {
|
|
24625
|
+
login2.cancel();
|
|
24626
|
+
disposeCommand();
|
|
24627
|
+
disposeTree();
|
|
24628
|
+
disposeScene();
|
|
24629
|
+
disposeStatusScene();
|
|
24630
|
+
};
|
|
24631
|
+
}, "ds-harness-remote: dsh-tui /remote command");
|
|
24632
|
+
}
|
|
24633
|
+
function registerRemoteCommand(ctx, commands, pluginHost, definition) {
|
|
24634
|
+
if (pluginHost === void 0) return commands.register(definition);
|
|
24635
|
+
try {
|
|
24636
|
+
return pluginHost.registerCommand(ctx, definition);
|
|
24637
|
+
} catch (error) {
|
|
24638
|
+
if (!hasErrorCode2(error, "COMPONENT_NOT_ADMITTED")) throw error;
|
|
24639
|
+
ctx.logger.debug("dsh-TUI Remote command is using the legacy command registry because Component admission is unavailable");
|
|
24640
|
+
return commands.register(definition);
|
|
24641
|
+
}
|
|
24642
|
+
}
|
|
24643
|
+
function hasErrorCode2(error, code) {
|
|
24644
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
24645
|
+
}
|
|
24646
|
+
function registerOptional(ctx, feature, register) {
|
|
24647
|
+
try {
|
|
24648
|
+
return register() ?? (() => {
|
|
24649
|
+
});
|
|
24650
|
+
} catch (error) {
|
|
24651
|
+
ctx.logger.warn(`dsh-TUI Remote ${feature} is unavailable`, { code: errorCode4(error) });
|
|
24652
|
+
return () => {
|
|
24653
|
+
};
|
|
24654
|
+
}
|
|
24655
|
+
}
|
|
24656
|
+
function remoteCommandChildren(canonicalPath) {
|
|
24657
|
+
if (canonicalPath.length === 1 && canonicalPath[0] === "remote") {
|
|
24658
|
+
return [
|
|
24659
|
+
{
|
|
24660
|
+
name: "status",
|
|
24661
|
+
description: "Show Remote Host authorization and connection status",
|
|
24662
|
+
descriptions: { zh: "\u67E5\u770B Remote Host \u6388\u6743\u548C\u8FDE\u63A5\u72B6\u6001" }
|
|
24663
|
+
},
|
|
24664
|
+
{
|
|
24665
|
+
name: "login",
|
|
24666
|
+
description: "Authorize this Host with a GitHub or Zhihu QR code",
|
|
24667
|
+
descriptions: { zh: "\u4F7F\u7528 GitHub \u6216\u77E5\u4E4E\u4E8C\u7EF4\u7801\u6388\u6743\u5F53\u524D Host" }
|
|
24668
|
+
},
|
|
24669
|
+
{
|
|
24670
|
+
name: "logout",
|
|
24671
|
+
description: "Revoke this Host and rotate its local identity",
|
|
24672
|
+
descriptions: { zh: "\u64A4\u9500\u5F53\u524D Host \u5E76\u8F6E\u6362\u672C\u5730\u8EAB\u4EFD" }
|
|
24673
|
+
}
|
|
24674
|
+
];
|
|
24675
|
+
}
|
|
24676
|
+
if (canonicalPath.length === 2 && canonicalPath[0] === "remote" && canonicalPath[1] === "login") {
|
|
24677
|
+
return [
|
|
24678
|
+
{ name: "zhihu", description: "Sign in with Zhihu (default)", descriptions: { zh: "\u4F7F\u7528\u77E5\u4E4E\u767B\u5F55\uFF08\u9ED8\u8BA4\uFF09" } },
|
|
24679
|
+
{ name: "github", description: "Sign in with GitHub", descriptions: { zh: "\u4F7F\u7528 GitHub \u767B\u5F55" } }
|
|
24680
|
+
];
|
|
24681
|
+
}
|
|
24682
|
+
return [];
|
|
24683
|
+
}
|
|
24684
|
+
function remoteStatusLines(target) {
|
|
24685
|
+
if (target === void 0) {
|
|
24686
|
+
return ["Remote Host is disabled or still starting. Check the ds-harness-remote settings and retry."];
|
|
24687
|
+
}
|
|
24688
|
+
const { runtime, config } = target;
|
|
24689
|
+
const status2 = runtime.hostStatus();
|
|
24690
|
+
const diagnostics = runtime.diagnostics();
|
|
24691
|
+
const codex = runtime.codexStatus();
|
|
24692
|
+
const capabilities = new Set(diagnostics.capabilities);
|
|
24693
|
+
const connection = status2.online ? "online" : status2.reconnecting ? "reconnecting" : status2.accountRequired ? "authorization required" : "offline";
|
|
24694
|
+
return [
|
|
24695
|
+
`Server: ${config.serverUrl ?? "not configured"}`,
|
|
24696
|
+
"Host control: enabled",
|
|
24697
|
+
`Device: ${status2.deviceId ?? "not initialized"}`,
|
|
24698
|
+
`Authorization: ${status2.authorized ? status2.account === void 0 ? "logged in" : `logged in (${status2.account})` : "logged out"}`,
|
|
24699
|
+
`Server connection: ${connection}`,
|
|
24700
|
+
`Harness Remote API: ${capabilities.has("harness.api.v1") ? "available (ApiProxy)" : capabilities.has("harness.remote.v1") ? "available (Typert Remote)" : "unavailable"}`,
|
|
24701
|
+
`Remote clients: ${diagnostics.activeConnections}`,
|
|
24702
|
+
`Codex Remote: ${codex.enabled ? codex.state : "disabled"}`,
|
|
24703
|
+
"",
|
|
24704
|
+
"Commands: /remote login [github|zhihu] \xB7 /remote status \xB7 /remote logout"
|
|
24705
|
+
];
|
|
24706
|
+
}
|
|
24707
|
+
function formatRemoteStatusInline(target) {
|
|
24708
|
+
return remoteStatusLines(target).filter(Boolean).join(" \xB7 ");
|
|
24709
|
+
}
|
|
24710
|
+
function remoteCommandUsage() {
|
|
24711
|
+
return [
|
|
24712
|
+
"Usage:",
|
|
24713
|
+
" /remote",
|
|
24714
|
+
" /remote status",
|
|
24715
|
+
" /remote login [github|zhihu]",
|
|
24716
|
+
" /remote logout"
|
|
24717
|
+
].join("\n");
|
|
24718
|
+
}
|
|
24719
|
+
function remoteNotReady() {
|
|
24720
|
+
return {
|
|
24721
|
+
kind: "error",
|
|
24722
|
+
text: "Remote Host is disabled or still starting. Check the ds-harness-remote settings and retry."
|
|
24723
|
+
};
|
|
24724
|
+
}
|
|
24725
|
+
var RemoteLoginController = class {
|
|
24726
|
+
constructor(resolveTarget) {
|
|
24727
|
+
this.resolveTarget = resolveTarget;
|
|
24728
|
+
}
|
|
24729
|
+
current = { phase: "idle", provider: "zhihu" };
|
|
24730
|
+
listeners = /* @__PURE__ */ new Set();
|
|
24731
|
+
attempt = 0;
|
|
24732
|
+
snapshot = () => this.current;
|
|
24733
|
+
subscribe = (listener) => {
|
|
24734
|
+
this.listeners.add(listener);
|
|
24735
|
+
return () => {
|
|
24736
|
+
this.listeners.delete(listener);
|
|
24737
|
+
};
|
|
24738
|
+
};
|
|
24739
|
+
start(provider) {
|
|
24740
|
+
const attempt = ++this.attempt;
|
|
24741
|
+
this.update({ phase: "loading", provider });
|
|
24742
|
+
void this.run(attempt, provider);
|
|
24743
|
+
}
|
|
24744
|
+
cancel() {
|
|
24745
|
+
this.attempt += 1;
|
|
24746
|
+
}
|
|
24747
|
+
async run(attempt, provider) {
|
|
24748
|
+
try {
|
|
24749
|
+
const target = this.resolveTarget();
|
|
24750
|
+
if (target === void 0) throw new Error("REMOTE_NOT_READY");
|
|
24751
|
+
const session = await target.runtime.startHostOAuthQrLogin(provider);
|
|
24752
|
+
const [qr, compactQr] = await Promise.all([
|
|
24753
|
+
renderTerminalQr(session.scanUrl),
|
|
24754
|
+
renderCompactTerminalQr(session.scanUrl)
|
|
24755
|
+
]);
|
|
24756
|
+
if (attempt !== this.attempt) return;
|
|
24757
|
+
this.update({ phase: "waiting", provider, qr, compactQr, scanUrl: session.scanUrl });
|
|
24758
|
+
await this.poll(attempt, provider, session, target.runtime);
|
|
24759
|
+
} catch (error) {
|
|
24760
|
+
if (attempt !== this.attempt) return;
|
|
24761
|
+
this.update({ phase: "error", provider, error: errorCode4(error) });
|
|
24762
|
+
}
|
|
24763
|
+
}
|
|
24764
|
+
async poll(attempt, provider, session, runtime) {
|
|
24765
|
+
const deadline = Date.now() + session.expiresIn * 1e3;
|
|
24766
|
+
while (attempt === this.attempt && Date.now() < deadline) {
|
|
24767
|
+
try {
|
|
24768
|
+
const result = await runtime.pollHostOAuthQrLogin(session.qrId);
|
|
24769
|
+
if (attempt !== this.attempt) return;
|
|
24770
|
+
if (result.status === "complete") {
|
|
24771
|
+
this.update({ phase: "complete", provider, account: result.authorization.account });
|
|
24772
|
+
return;
|
|
24773
|
+
}
|
|
24774
|
+
if (result.status === "expired") break;
|
|
24775
|
+
} catch (error) {
|
|
24776
|
+
if (!(error instanceof ServerApiError) || !error.retryable) throw error;
|
|
24777
|
+
}
|
|
24778
|
+
await wait(Math.min(QR_POLL_INTERVAL_MS2, Math.max(1, deadline - Date.now())));
|
|
24779
|
+
}
|
|
24780
|
+
if (attempt === this.attempt) this.update({ phase: "expired", provider });
|
|
24781
|
+
}
|
|
24782
|
+
update(snapshot) {
|
|
24783
|
+
this.current = snapshot;
|
|
24784
|
+
for (const listener of this.listeners) listener(snapshot);
|
|
24785
|
+
}
|
|
24786
|
+
};
|
|
24787
|
+
function createRemoteLoginScene(controller) {
|
|
24788
|
+
return function RemoteLoginScene({ React, ui, close }) {
|
|
24789
|
+
const [snapshot, setSnapshot] = React.useState(controller.snapshot());
|
|
24790
|
+
const terminal = ui.useTerminalSize();
|
|
24791
|
+
React.useEffect(() => {
|
|
24792
|
+
const unsubscribe = controller.subscribe(setSnapshot);
|
|
24793
|
+
return () => {
|
|
24794
|
+
unsubscribe();
|
|
24795
|
+
controller.cancel();
|
|
24796
|
+
};
|
|
24797
|
+
}, []);
|
|
24798
|
+
ui.useInput((input2, key) => {
|
|
24799
|
+
if (key.escape === true || input2.toLowerCase() === "q") {
|
|
24800
|
+
controller.cancel();
|
|
24801
|
+
close();
|
|
24802
|
+
}
|
|
24803
|
+
});
|
|
24804
|
+
const provider = snapshot.provider === "github" ? "GitHub" : "Zhihu";
|
|
24805
|
+
const other = snapshot.provider === "github" ? "/remote login zhihu" : "/remote login github";
|
|
24806
|
+
const children = [
|
|
24807
|
+
React.createElement(ui.Text, { key: "title", bold: true, color: "accent" }, "Remote Host login"),
|
|
24808
|
+
React.createElement(ui.Text, { key: "provider" }, `Provider: ${provider} \xB7 You can also use ${other}`)
|
|
24809
|
+
];
|
|
24810
|
+
if (snapshot.phase === "loading") {
|
|
24811
|
+
children.push(React.createElement(ui.Text, { key: "loading", color: "subtle" }, "Creating authorization QR code\u2026"));
|
|
24812
|
+
} else if (snapshot.phase === "waiting" && snapshot.qr !== void 0 && snapshot.scanUrl !== void 0) {
|
|
24813
|
+
const fullRows = snapshot.qr.split("\n").length;
|
|
24814
|
+
const fullColumns = printableWidth(snapshot.qr.split("\n")[0] ?? "");
|
|
24815
|
+
const useFullQr = terminal.rows >= fullRows + 7 && terminal.columns >= fullColumns + 4;
|
|
24816
|
+
const qr = useFullQr || snapshot.compactQr === void 0 ? snapshot.qr : snapshot.compactQr;
|
|
24817
|
+
const qrRows = qr.split("\n").length;
|
|
24818
|
+
const qrColumns = printableWidth(qr.split("\n")[0] ?? "");
|
|
24819
|
+
if (terminal.rows < qrRows + 7 || terminal.columns < qrColumns + 4) {
|
|
24820
|
+
children.push(React.createElement(
|
|
24821
|
+
ui.Text,
|
|
24822
|
+
{ key: "size-warning", color: "warning" },
|
|
24823
|
+
`Resize the terminal to at least ${qrColumns + 4} \xD7 ${qrRows + 7} if the QR code is clipped.`
|
|
24824
|
+
));
|
|
24825
|
+
}
|
|
24826
|
+
children.push(
|
|
24827
|
+
React.createElement(ui.Text, { key: "scan" }, "Scan this QR code to authorize this Host:"),
|
|
24828
|
+
React.createElement(ui.Text, { key: "qr", wrap: "truncate" }, qr),
|
|
24829
|
+
React.createElement(ui.Text, { key: "url", color: "link", underline: true }, terminalLink2(snapshot.scanUrl)),
|
|
24830
|
+
React.createElement(ui.Text, { key: "waiting", color: "subtle" }, "Waiting for authorization\u2026")
|
|
24831
|
+
);
|
|
24832
|
+
} else if (snapshot.phase === "complete") {
|
|
24833
|
+
children.push(React.createElement(
|
|
24834
|
+
ui.Text,
|
|
24835
|
+
{ key: "complete", color: "success" },
|
|
24836
|
+
snapshot.account === void 0 ? "Remote Host login complete. The Host is reconnecting now." : `Remote Host login complete for ${snapshot.account}. The Host is reconnecting now.`
|
|
24837
|
+
));
|
|
24838
|
+
} else if (snapshot.phase === "expired") {
|
|
24839
|
+
children.push(React.createElement(ui.Text, { key: "expired", color: "warning" }, "The QR code expired. Close this screen and run /remote login again."));
|
|
24840
|
+
} else if (snapshot.phase === "error") {
|
|
24841
|
+
children.push(React.createElement(ui.Text, { key: "error", color: "error" }, `Remote Host login failed (${snapshot.error ?? "UNKNOWN"}).`));
|
|
24842
|
+
}
|
|
24843
|
+
children.push(React.createElement(ui.Text, { key: "close", color: "subtle" }, "Press Esc or q to return."));
|
|
24844
|
+
return React.createElement(ui.Box, {
|
|
24845
|
+
flexDirection: "column",
|
|
24846
|
+
gap: 1,
|
|
24847
|
+
paddingX: Math.max(0, Math.min(2, Math.floor((terminal.columns - 1) / 2)))
|
|
24848
|
+
}, ...children);
|
|
24849
|
+
};
|
|
24850
|
+
}
|
|
24851
|
+
function createRemoteStatusScene(resolveTarget) {
|
|
24852
|
+
return function RemoteStatusScene({ React, ui, close }) {
|
|
24853
|
+
const terminal = ui.useTerminalSize();
|
|
24854
|
+
ui.useInput((input2, key) => {
|
|
24855
|
+
if (key.escape === true || input2.toLowerCase() === "q") close();
|
|
24856
|
+
});
|
|
24857
|
+
const children = [
|
|
24858
|
+
React.createElement(ui.Text, { key: "title", bold: true, color: "accent" }, "Remote Host status"),
|
|
24859
|
+
...remoteStatusLines(resolveTarget()).map((line, index) => React.createElement(
|
|
24860
|
+
ui.Text,
|
|
24861
|
+
{ key: `status-${index}`, color: line === "" ? "subtle" : void 0 },
|
|
24862
|
+
line === "" ? " " : line
|
|
24863
|
+
)),
|
|
24864
|
+
React.createElement(ui.Text, { key: "close", color: "subtle" }, "Press Esc or q to return.")
|
|
24865
|
+
];
|
|
24866
|
+
return React.createElement(ui.Box, {
|
|
24867
|
+
flexDirection: "column",
|
|
24868
|
+
gap: 1,
|
|
24869
|
+
paddingX: Math.max(0, Math.min(2, Math.floor((terminal.columns - 1) / 2)))
|
|
24870
|
+
}, ...children);
|
|
24871
|
+
};
|
|
24872
|
+
}
|
|
24873
|
+
function terminalLink2(url) {
|
|
24874
|
+
return `\x1B]8;;${url}\x07${url}\x1B]8;;\x07`;
|
|
24875
|
+
}
|
|
24876
|
+
function printableWidth(value) {
|
|
24877
|
+
return value.replace(/\u001B\[[0-9;]*m/gu, "").length;
|
|
24878
|
+
}
|
|
24879
|
+
function errorCode4(error) {
|
|
24880
|
+
if (error instanceof ServerApiError) return error.code;
|
|
24881
|
+
if (error instanceof Error && "code" in error && typeof error.code === "string") return error.code;
|
|
24882
|
+
return "CONNECTION_FAILED";
|
|
24883
|
+
}
|
|
24884
|
+
function wait(milliseconds) {
|
|
24885
|
+
return new Promise((resolve3) => setTimeout(resolve3, milliseconds));
|
|
24886
|
+
}
|
|
24887
|
+
|
|
23860
24888
|
// src/remote-file-content-provider.ts
|
|
23861
24889
|
var REMOTE_FILE_SAVE_AS_MAX_BYTES = 100 * 1024 * 1024;
|
|
23862
24890
|
var REMOTE_FILE_FAST_SAVE_AS_MAX_BYTES = 1024 * 1024 * 1024;
|
|
@@ -23936,15 +24964,44 @@ var legacyLoaderModuleNames = /* @__PURE__ */ new Set(["dsh-remote", "@dsh-remot
|
|
|
23936
24964
|
var pluginSettingsNamespace = "ds-harness-remote";
|
|
23937
24965
|
var legacySettingsNamespace = "dsh-remote";
|
|
23938
24966
|
function apply(ctx, input2 = {}) {
|
|
23939
|
-
ctx.
|
|
24967
|
+
const tuiCommandsAvailable = ctx.get("commands", false) !== void 0 && ctx.get("tuiScenes", false) !== void 0;
|
|
24968
|
+
const tuiBinding = tuiCommandsAvailable ? {} : void 0;
|
|
24969
|
+
if (tuiBinding !== void 0) installTuiRemoteCommand(ctx, () => tuiBinding.target);
|
|
24970
|
+
const activateWhenCarrierReady = (runtimeContext) => {
|
|
23940
24971
|
const gateway = runtimeContext.get("typertGateway");
|
|
23941
|
-
|
|
23942
|
-
|
|
24972
|
+
const connection = runtimeContext.get("connection");
|
|
24973
|
+
let disposePendingControl;
|
|
24974
|
+
const installPendingControl = () => {
|
|
24975
|
+
if (connection === void 0 || disposePendingControl !== void 0) return;
|
|
24976
|
+
disposePendingControl = runtimeContext.effect(() => {
|
|
24977
|
+
const control = new PluginControlRuntime(
|
|
24978
|
+
resolveConfig(input2),
|
|
24979
|
+
new IdentityStore().directory,
|
|
24980
|
+
void 0,
|
|
24981
|
+
void 0,
|
|
24982
|
+
void 0
|
|
24983
|
+
);
|
|
24984
|
+
return control.register(connection);
|
|
24985
|
+
}, "dsh-remote pending control");
|
|
24986
|
+
};
|
|
24987
|
+
const startActiveRuntime = async (activeContext) => {
|
|
24988
|
+
await disposePendingControl?.();
|
|
24989
|
+
disposePendingControl = void 0;
|
|
24990
|
+
await activate(activeContext, input2, tuiBinding);
|
|
24991
|
+
};
|
|
24992
|
+
if (tuiCommandsAvailable || runtimeContext.get("apiProxy") !== void 0 || new TypertGatewaySwitch(gateway).supportsCarrier()) {
|
|
24993
|
+
return startActiveRuntime(runtimeContext);
|
|
23943
24994
|
}
|
|
23944
|
-
|
|
23945
|
-
|
|
24995
|
+
installPendingControl();
|
|
24996
|
+
runtimeContext.inject(["apiProxy"], (legacyContext) => startActiveRuntime(legacyContext));
|
|
24997
|
+
};
|
|
24998
|
+
if (tuiCommandsAvailable) {
|
|
24999
|
+
ctx.inject(["settings", "typertGateway"], activateWhenCarrierReady);
|
|
25000
|
+
} else {
|
|
25001
|
+
ctx.inject(["settings", "connection", "typertGateway"], activateWhenCarrierReady);
|
|
25002
|
+
}
|
|
23946
25003
|
}
|
|
23947
|
-
async function activate(ctx, input2) {
|
|
25004
|
+
async function activate(ctx, input2, tuiBinding) {
|
|
23948
25005
|
const settings = ctx.get("settings");
|
|
23949
25006
|
const settingsScope = settings?.register(pluginSettingsNamespace, Config, {
|
|
23950
25007
|
base: input2,
|
|
@@ -23954,12 +25011,20 @@ async function activate(ctx, input2) {
|
|
|
23954
25011
|
}
|
|
23955
25012
|
});
|
|
23956
25013
|
if (settings !== void 0 && settingsScope !== void 0) {
|
|
23957
|
-
const migration =
|
|
23958
|
-
|
|
23959
|
-
|
|
25014
|
+
const migration = migrateLegacySettings(settings, settingsScope);
|
|
25015
|
+
reportSettingsMigration(ctx, await migration);
|
|
25016
|
+
}
|
|
25017
|
+
const connection = ctx.get("connection");
|
|
25018
|
+
const resolvedConfig = resolveConfig(settingsScope?.get() ?? input2);
|
|
25019
|
+
const config = connection === void 0 && resolvedConfig.serverUrl === void 0 ? { ...resolvedConfig, serverUrl: DEFAULT_REMOTE_SERVER_URL } : resolvedConfig;
|
|
25020
|
+
const defaultIdentityDirectory = new IdentityStore().directory;
|
|
25021
|
+
if (!config.enabled) {
|
|
25022
|
+
if (connection !== void 0) {
|
|
25023
|
+
const controlRuntime2 = new PluginControlRuntime(config, defaultIdentityDirectory, settingsScope, void 0, void 0);
|
|
25024
|
+
ctx.effect(() => controlRuntime2.register(connection), "dsh-remote disabled control");
|
|
25025
|
+
}
|
|
25026
|
+
return;
|
|
23960
25027
|
}
|
|
23961
|
-
const config = resolveConfig(settingsScope?.get() ?? input2);
|
|
23962
|
-
if (!config.enabled) return;
|
|
23963
25028
|
const logger = new SafeLogger({
|
|
23964
25029
|
debug: (message) => {
|
|
23965
25030
|
ctx.logger.debug(message);
|
|
@@ -23978,13 +25043,10 @@ async function activate(ctx, input2) {
|
|
|
23978
25043
|
console.error(message);
|
|
23979
25044
|
}
|
|
23980
25045
|
}, config.logLevel);
|
|
23981
|
-
await disableLegacyLoaderEntries(ctx, logger);
|
|
23982
|
-
const defaultIdentityDirectory = new IdentityStore().directory;
|
|
23983
25046
|
const hostIdentities = new IdentityStore({
|
|
23984
25047
|
directory: config.serverUrl === void 0 ? defaultIdentityDirectory : serverStorageDirectory(defaultIdentityDirectory, config.serverUrl, "host")
|
|
23985
25048
|
});
|
|
23986
25049
|
const apiProxy = ctx.get("apiProxy");
|
|
23987
|
-
const connection = ctx.get("connection");
|
|
23988
25050
|
const nativeTypertGateway = ctx.get("typertGateway");
|
|
23989
25051
|
const localTypertGateway = new TypertGatewaySwitch(nativeTypertGateway).local();
|
|
23990
25052
|
const runtime = new HostPluginRuntime(
|
|
@@ -24014,6 +25076,9 @@ async function activate(ctx, input2) {
|
|
|
24014
25076
|
const controlRuntime = connection === void 0 ? void 0 : new PluginControlRuntime(config, defaultIdentityDirectory, settingsScope, clientRuntime, hostControl);
|
|
24015
25077
|
ctx.provide("dshRemote", runtime);
|
|
24016
25078
|
if (clientRuntime !== void 0) ctx.provide("dshRemoteClient", clientRuntime);
|
|
25079
|
+
const tuiTarget = { runtime, config };
|
|
25080
|
+
if (tuiBinding !== void 0) tuiBinding.target = tuiTarget;
|
|
25081
|
+
await disableLegacyLoaderEntries(ctx, logger);
|
|
24017
25082
|
await ctx.effect(async () => {
|
|
24018
25083
|
const disposeControl = controlRuntime?.register(connection);
|
|
24019
25084
|
try {
|
|
@@ -24029,18 +25094,24 @@ async function activate(ctx, input2) {
|
|
|
24029
25094
|
});
|
|
24030
25095
|
}
|
|
24031
25096
|
} catch (error) {
|
|
25097
|
+
if (tuiBinding?.target === tuiTarget) tuiBinding.target = void 0;
|
|
24032
25098
|
await disposeControl?.();
|
|
24033
25099
|
await clientRuntime?.close();
|
|
24034
25100
|
await runtime.close();
|
|
24035
25101
|
throw error;
|
|
24036
25102
|
}
|
|
24037
25103
|
return async () => {
|
|
25104
|
+
if (tuiBinding?.target === tuiTarget) tuiBinding.target = void 0;
|
|
24038
25105
|
await disposeControl?.();
|
|
24039
25106
|
await clientRuntime?.close();
|
|
24040
25107
|
await runtime.close();
|
|
24041
25108
|
};
|
|
24042
25109
|
}, "dsh-remote lifecycle");
|
|
24043
25110
|
}
|
|
25111
|
+
function reportSettingsMigration(ctx, migration) {
|
|
25112
|
+
if (migration === "migrated") ctx.logger.info("migrated legacy Remote settings namespace");
|
|
25113
|
+
if (migration === "failed") ctx.logger.warn("failed to migrate legacy Remote settings namespace");
|
|
25114
|
+
}
|
|
24044
25115
|
async function migrateLegacySettings(settings, currentScope) {
|
|
24045
25116
|
if (typeof settings.describe !== "function") return "skipped";
|
|
24046
25117
|
try {
|
|
@@ -24131,6 +25202,7 @@ export {
|
|
|
24131
25202
|
migrateLegacySettings,
|
|
24132
25203
|
name,
|
|
24133
25204
|
resolveConfig,
|
|
25205
|
+
runCli,
|
|
24134
25206
|
serverStorageDirectory
|
|
24135
25207
|
};
|
|
24136
25208
|
/*! Bundled license information:
|