ds-harness-remote 0.4.3 → 0.4.4
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/codex/domain.d.ts +4 -2
- package/dist/codex/domain.d.ts.map +1 -1
- package/dist/codex/domain.js +192 -68
- package/dist/codex/domain.js.map +1 -1
- package/dist/codex/method-policy.d.ts +7 -7
- package/dist/codex/virtual-harness.d.ts +3 -0
- package/dist/codex/virtual-harness.d.ts.map +1 -1
- package/dist/codex/virtual-harness.js +89 -20
- 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/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1147 -258
- 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;
|
|
@@ -14479,7 +14537,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14479
14537
|
case "commands/list":
|
|
14480
14538
|
return ok(this.commandList(args));
|
|
14481
14539
|
case "commands/execute":
|
|
14482
|
-
return ok(this.executeCommand(args));
|
|
14540
|
+
return ok(await this.executeCommand(args, signal));
|
|
14483
14541
|
default:
|
|
14484
14542
|
return fail("method-not-found", `CodeX virtual Harness does not implement ${endpoint}.`);
|
|
14485
14543
|
}
|
|
@@ -14553,6 +14611,10 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14553
14611
|
permissionSelection(sessionId) {
|
|
14554
14612
|
return this.selectedPermissions.get(sessionId) ?? CODEX_DEFAULT_PERMISSION;
|
|
14555
14613
|
}
|
|
14614
|
+
setPermissionSelection(sessionId, preset) {
|
|
14615
|
+
this.selectedPermissions.set(sessionId, preset);
|
|
14616
|
+
this.publishProjection(sessionId, "permissions", codexPermissionsProjection(preset), this.nextProjectionSeq());
|
|
14617
|
+
}
|
|
14556
14618
|
commandList(args) {
|
|
14557
14619
|
nativeThreadId(requiredString(args.agentId, "agentId"));
|
|
14558
14620
|
return [{
|
|
@@ -14561,9 +14623,9 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14561
14623
|
input: { hint: "<preset>" }
|
|
14562
14624
|
}];
|
|
14563
14625
|
}
|
|
14564
|
-
executeCommand(args) {
|
|
14626
|
+
async executeCommand(args, signal) {
|
|
14565
14627
|
const sessionId = requiredString(args.agentId, "agentId");
|
|
14566
|
-
nativeThreadId(sessionId);
|
|
14628
|
+
const threadId = nativeThreadId(sessionId);
|
|
14567
14629
|
const line = requiredString(args.line, "command line").trim();
|
|
14568
14630
|
if (!Array.isArray(args.images)) throw new Error("The CodeX command image list is required.");
|
|
14569
14631
|
const match = /^\/permission(?:\s+([\s\S]*))?$/u.exec(line);
|
|
@@ -14582,9 +14644,10 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14582
14644
|
commandId,
|
|
14583
14645
|
result: { kind: "error", text: `unknown preset "${requested}" (available: workspace-write, danger-full-access)` }
|
|
14584
14646
|
};
|
|
14585
|
-
this.
|
|
14586
|
-
|
|
14587
|
-
|
|
14647
|
+
const result = await this.client.request("thread/resume", { threadId, permissionPreset: requested }, signal);
|
|
14648
|
+
const effective = codexPermissionPresetFromResponse(result) ?? requested;
|
|
14649
|
+
this.setPermissionSelection(sessionId, effective);
|
|
14650
|
+
return { commandId, result: { kind: "success", text: `preset ${effective}` } };
|
|
14588
14651
|
}
|
|
14589
14652
|
sessionTitle(sessionId) {
|
|
14590
14653
|
const session = this.catalog?.sessions.find((item) => item.id === sessionId);
|
|
@@ -14728,7 +14791,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14728
14791
|
queue,
|
|
14729
14792
|
nextSeq: history.cursor + 1,
|
|
14730
14793
|
turn: history.nextTurn,
|
|
14731
|
-
stepOpen:
|
|
14794
|
+
stepOpen: history.activeTurnId !== void 0,
|
|
14732
14795
|
startedItems: /* @__PURE__ */ new Set(),
|
|
14733
14796
|
completedItems: /* @__PURE__ */ new Set(),
|
|
14734
14797
|
streamedBlocks: /* @__PURE__ */ new Map(),
|
|
@@ -14737,7 +14800,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14737
14800
|
liveItems: /* @__PURE__ */ new Map(),
|
|
14738
14801
|
liveToolOutput: /* @__PURE__ */ new Map(),
|
|
14739
14802
|
liveToolResultSeq: /* @__PURE__ */ new Map(),
|
|
14740
|
-
requestId: this.pendingRequestIds.get(sessionId)
|
|
14803
|
+
requestId: this.pendingRequestIds.get(sessionId),
|
|
14804
|
+
...history.activeTurnId === void 0 ? {} : { activeTurnId: history.activeTurnId }
|
|
14741
14805
|
};
|
|
14742
14806
|
this.follows.add(follow);
|
|
14743
14807
|
queue.push({
|
|
@@ -14786,6 +14850,11 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14786
14850
|
this.publishProjection(follow.sessionId, "title", title, seq);
|
|
14787
14851
|
return;
|
|
14788
14852
|
}
|
|
14853
|
+
if (frame.method === "thread/settings/updated") {
|
|
14854
|
+
const preset = codexPermissionPresetFromResponse(params);
|
|
14855
|
+
if (preset !== void 0) this.setPermissionSelection(follow.sessionId, preset);
|
|
14856
|
+
return;
|
|
14857
|
+
}
|
|
14789
14858
|
if (frame.method === "turn/started") {
|
|
14790
14859
|
const turn = record(params.turn);
|
|
14791
14860
|
this.resetLiveTurn(follow);
|
|
@@ -14840,8 +14909,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14840
14909
|
const item = record(value);
|
|
14841
14910
|
const content = string(item.step);
|
|
14842
14911
|
if (content === void 0) return [];
|
|
14843
|
-
const
|
|
14844
|
-
return [{ content, status }];
|
|
14912
|
+
const status2 = item.status === "inProgress" ? "in_progress" : item.status === "completed" ? "completed" : "pending";
|
|
14913
|
+
return [{ content, status: status2 }];
|
|
14845
14914
|
});
|
|
14846
14915
|
this.pushEvent(follow, "todo/write", { todos });
|
|
14847
14916
|
return;
|
|
@@ -14871,10 +14940,10 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14871
14940
|
return;
|
|
14872
14941
|
}
|
|
14873
14942
|
if (frame.method === "thread/status/changed") {
|
|
14874
|
-
const
|
|
14875
|
-
const running =
|
|
14943
|
+
const status2 = record(params.status);
|
|
14944
|
+
const running = status2.type === "active";
|
|
14876
14945
|
this.emitRemoteEvent("api-session/status", [follow.sessionId, running]);
|
|
14877
|
-
if (
|
|
14946
|
+
if (status2.type === "systemError") {
|
|
14878
14947
|
this.broadcastRcHost({
|
|
14879
14948
|
type: "host/agent-error",
|
|
14880
14949
|
sessionId: follow.sessionId,
|
|
@@ -15168,12 +15237,13 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15168
15237
|
if (cwd === void 0) return failure("workspace-not-found", "The CodeX virtual Workspace was not found.");
|
|
15169
15238
|
const directory = await this.models(signal);
|
|
15170
15239
|
const selection = directory.default;
|
|
15171
|
-
const
|
|
15240
|
+
const requestedPreset = CODEX_DEFAULT_PERMISSION;
|
|
15172
15241
|
const result = record(await this.client.request("thread/start", {
|
|
15173
15242
|
cwd,
|
|
15174
15243
|
model: selection.model,
|
|
15175
|
-
permissionPreset:
|
|
15244
|
+
permissionPreset: requestedPreset
|
|
15176
15245
|
}, signal));
|
|
15246
|
+
const permissionPreset2 = codexPermissionPresetFromResponse(result) ?? requestedPreset;
|
|
15177
15247
|
const thread = { ...record(result.thread), cwd, turns: array(record(result.thread).turns) };
|
|
15178
15248
|
const projected = projectCodexThread(thread);
|
|
15179
15249
|
if (projected === void 0) return failure("internal", "CodeX returned an invalid Thread.");
|
|
@@ -15194,11 +15264,12 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15194
15264
|
}
|
|
15195
15265
|
async forkSession(request, signal) {
|
|
15196
15266
|
const sessionId = requiredString(request.sessionId, "sessionId");
|
|
15197
|
-
|
|
15267
|
+
let permissionPreset2 = this.selectedPermissions.get(sessionId);
|
|
15198
15268
|
const result = record(await this.client.request("thread/fork", {
|
|
15199
15269
|
threadId: nativeThreadId(sessionId),
|
|
15200
|
-
permissionPreset: permissionPreset2
|
|
15270
|
+
...permissionPreset2 === void 0 ? {} : { permissionPreset: permissionPreset2 }
|
|
15201
15271
|
}, signal));
|
|
15272
|
+
permissionPreset2 = codexPermissionPresetFromResponse(result) ?? permissionPreset2 ?? CODEX_DEFAULT_PERMISSION;
|
|
15202
15273
|
const projected = projectCodexThread(record(result.thread));
|
|
15203
15274
|
if (projected === void 0) return failure("internal", "CodeX returned an invalid forked Thread.");
|
|
15204
15275
|
this.selectedModels.set(projected.id, this.modelSelection(sessionId, await this.models(signal)));
|
|
@@ -15215,14 +15286,20 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15215
15286
|
if (input2 === void 0) return failure("attachment-error", "CodeX virtual Sessions accept text and pasted PNG, JPEG, WebP, or GIF images only.");
|
|
15216
15287
|
const threadId = nativeThreadId(sessionId);
|
|
15217
15288
|
const selection = this.modelSelection(sessionId, await this.models(signal));
|
|
15218
|
-
|
|
15289
|
+
let permissionPreset2 = this.selectedPermissions.get(sessionId);
|
|
15219
15290
|
const isFreshBlankThread = this.blankThreads.has(threadId) || this.pendingThreads.has(threadId);
|
|
15220
15291
|
await this.ensureRcFollow(sessionId);
|
|
15221
|
-
if (!isFreshBlankThread)
|
|
15222
|
-
|
|
15223
|
-
|
|
15224
|
-
|
|
15225
|
-
|
|
15292
|
+
if (!isFreshBlankThread) {
|
|
15293
|
+
const resumeResult = await this.client.request("thread/resume", {
|
|
15294
|
+
threadId,
|
|
15295
|
+
model: selection.model
|
|
15296
|
+
}, signal);
|
|
15297
|
+
const serverPreset = codexPermissionPresetFromResponse(resumeResult);
|
|
15298
|
+
if (permissionPreset2 === void 0 && serverPreset !== void 0) {
|
|
15299
|
+
permissionPreset2 = serverPreset;
|
|
15300
|
+
this.setPermissionSelection(sessionId, serverPreset);
|
|
15301
|
+
}
|
|
15302
|
+
}
|
|
15226
15303
|
this.pendingRequestIds.set(sessionId, string(request.requestId) ?? "");
|
|
15227
15304
|
const mode = request.mode === "steer" ? "turn/steer" : "turn/start";
|
|
15228
15305
|
if (mode === "turn/steer") {
|
|
@@ -15234,7 +15311,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15234
15311
|
threadId,
|
|
15235
15312
|
input: input2,
|
|
15236
15313
|
...codexModelParams(selection),
|
|
15237
|
-
permissionPreset: permissionPreset2
|
|
15314
|
+
...permissionPreset2 === void 0 ? {} : { permissionPreset: permissionPreset2 }
|
|
15238
15315
|
}, signal);
|
|
15239
15316
|
}
|
|
15240
15317
|
this.blankThreads.delete(threadId);
|
|
@@ -15376,7 +15453,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15376
15453
|
queue: new AsyncValueQueue2(controller.signal),
|
|
15377
15454
|
nextSeq: history.cursor + 1,
|
|
15378
15455
|
turn: history.nextTurn,
|
|
15379
|
-
stepOpen:
|
|
15456
|
+
stepOpen: history.activeTurnId !== void 0,
|
|
15380
15457
|
startedItems: /* @__PURE__ */ new Set(),
|
|
15381
15458
|
completedItems: /* @__PURE__ */ new Set(),
|
|
15382
15459
|
streamedBlocks: /* @__PURE__ */ new Map(),
|
|
@@ -15386,7 +15463,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15386
15463
|
liveToolOutput: /* @__PURE__ */ new Map(),
|
|
15387
15464
|
liveToolResultSeq: /* @__PURE__ */ new Map(),
|
|
15388
15465
|
requestId: this.pendingRequestIds.get(sessionId),
|
|
15389
|
-
rcOnly: true
|
|
15466
|
+
rcOnly: true,
|
|
15467
|
+
...history.activeTurnId === void 0 ? {} : { activeTurnId: history.activeTurnId }
|
|
15390
15468
|
};
|
|
15391
15469
|
this.follows.add(follow);
|
|
15392
15470
|
try {
|
|
@@ -15520,7 +15598,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15520
15598
|
}
|
|
15521
15599
|
};
|
|
15522
15600
|
async function loadCatalog(client, signal, pendingThreads) {
|
|
15523
|
-
|
|
15601
|
+
let projects = await loadCodexProjects(client, signal);
|
|
15524
15602
|
const threads = [];
|
|
15525
15603
|
let cursor2;
|
|
15526
15604
|
for (let page = 0; page < MAX_CODEX_PAGES; page += 1) {
|
|
@@ -15545,6 +15623,16 @@ async function loadCatalog(client, signal, pendingThreads) {
|
|
|
15545
15623
|
else threads.unshift(thread);
|
|
15546
15624
|
}
|
|
15547
15625
|
}
|
|
15626
|
+
if (projects.length === 0) {
|
|
15627
|
+
projects = deriveCodexCwdWorkspaces(threads).map((workspace) => ({
|
|
15628
|
+
id: workspace.id,
|
|
15629
|
+
name: workspace.name,
|
|
15630
|
+
roots: [{ path: workspace.path }],
|
|
15631
|
+
position: workspace.position,
|
|
15632
|
+
createdAt: workspace.createdAt,
|
|
15633
|
+
updatedAt: workspace.updatedAt
|
|
15634
|
+
}));
|
|
15635
|
+
}
|
|
15548
15636
|
const projected = threads.map((thread) => {
|
|
15549
15637
|
const session = projectCodexThread(thread);
|
|
15550
15638
|
return session === void 0 ? void 0 : { thread, session };
|
|
@@ -15653,6 +15741,7 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15653
15741
|
const entries = [];
|
|
15654
15742
|
let seq = 0;
|
|
15655
15743
|
let turnNumber = 0;
|
|
15744
|
+
const active = activeTurnId(thread.turns);
|
|
15656
15745
|
const append = (type, data, time = Date.now(), view, sourceEventSeqs) => {
|
|
15657
15746
|
const eventSeq = seq++;
|
|
15658
15747
|
entries.push({
|
|
@@ -15672,6 +15761,7 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15672
15761
|
for (const rawTurn of array(thread.turns)) {
|
|
15673
15762
|
const turn = record(rawTurn);
|
|
15674
15763
|
turnNumber += 1;
|
|
15764
|
+
const turnActive = isActiveCodexTurn(turn);
|
|
15675
15765
|
const time = normalizeTime(turn.createdAt) || normalizeTime(turn.startedAt) || normalizeTime(thread.createdAt) || Date.now();
|
|
15676
15766
|
append("turn/start", { turn: turnNumber }, time);
|
|
15677
15767
|
append("step/start", { turn: turnNumber, step: 1 }, time);
|
|
@@ -15689,6 +15779,7 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15689
15779
|
if (event.type === "tool/call") toolCallSeq = eventSeq;
|
|
15690
15780
|
}
|
|
15691
15781
|
}
|
|
15782
|
+
if (turnActive) continue;
|
|
15692
15783
|
append("step/end", { turn: turnNumber, step: 1 }, normalizeTime(turn.updatedAt) || normalizeTime(turn.completedAt) || time);
|
|
15693
15784
|
append("turn/end", {
|
|
15694
15785
|
turn: turnNumber,
|
|
@@ -15705,7 +15796,8 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15705
15796
|
},
|
|
15706
15797
|
entries,
|
|
15707
15798
|
lastSeq: seq - 1,
|
|
15708
|
-
nextTurn: turnNumber
|
|
15799
|
+
nextTurn: turnNumber,
|
|
15800
|
+
...active === void 0 ? {} : { activeTurnId: active }
|
|
15709
15801
|
};
|
|
15710
15802
|
}
|
|
15711
15803
|
function paginateCodexNativeHistory(history, request) {
|
|
@@ -15729,7 +15821,8 @@ function paginateCodexNativeHistory(history, request) {
|
|
|
15729
15821
|
cursor: history.lastSeq,
|
|
15730
15822
|
nextTurn: history.nextTurn,
|
|
15731
15823
|
records: window.filter((entry) => entry.event.seq >= cut),
|
|
15732
|
-
hasMore: window.some((entry) => entry.event.seq < cut)
|
|
15824
|
+
hasMore: window.some((entry) => entry.event.seq < cut),
|
|
15825
|
+
...history.activeTurnId === void 0 ? {} : { activeTurnId: history.activeTurnId }
|
|
15733
15826
|
};
|
|
15734
15827
|
}
|
|
15735
15828
|
function itemEvents(item, turn, step, requestId, selection = modelSelection(), sessionId = CODEX_SESSION_PREFIX) {
|
|
@@ -16242,6 +16335,22 @@ function codexImageLimitsProjection() {
|
|
|
16242
16335
|
function isCodexPermissionPreset(value) {
|
|
16243
16336
|
return value === "workspace-write" || value === "danger-full-access";
|
|
16244
16337
|
}
|
|
16338
|
+
function codexPermissionPresetFromResponse(value) {
|
|
16339
|
+
const root = record(value);
|
|
16340
|
+
return codexPermissionPresetFromPolicyRecord(root) ?? codexPermissionPresetFromPolicyRecord(record(root.threadSettings));
|
|
16341
|
+
}
|
|
16342
|
+
function codexPermissionPresetFromPolicyRecord(value) {
|
|
16343
|
+
const sandbox = value.sandbox ?? value.sandboxPolicy;
|
|
16344
|
+
if (value.approvalPolicy === "never" && isDangerFullAccessSandbox(sandbox)) return "danger-full-access";
|
|
16345
|
+
if (value.approvalPolicy === "on-request" && isWorkspaceWriteSandbox(sandbox)) return "workspace-write";
|
|
16346
|
+
return void 0;
|
|
16347
|
+
}
|
|
16348
|
+
function isDangerFullAccessSandbox(value) {
|
|
16349
|
+
return value === "danger-full-access" || record(value).type === "dangerFullAccess";
|
|
16350
|
+
}
|
|
16351
|
+
function isWorkspaceWriteSandbox(value) {
|
|
16352
|
+
return value === "workspace-write" || record(value).type === "workspaceWrite";
|
|
16353
|
+
}
|
|
16245
16354
|
function modelCatalog(directory) {
|
|
16246
16355
|
return {
|
|
16247
16356
|
default: directory.default,
|
|
@@ -16382,6 +16491,17 @@ function nativeThreadId(sessionId) {
|
|
|
16382
16491
|
}
|
|
16383
16492
|
return sessionId.slice(CODEX_SESSION_PREFIX.length);
|
|
16384
16493
|
}
|
|
16494
|
+
function activeTurnId(value) {
|
|
16495
|
+
if (!Array.isArray(value)) return void 0;
|
|
16496
|
+
for (let index = value.length - 1; index >= 0; index -= 1) {
|
|
16497
|
+
const turn = record(value[index]);
|
|
16498
|
+
if (isActiveCodexTurn(turn) && typeof turn.id === "string" && turn.id.length > 0) return turn.id;
|
|
16499
|
+
}
|
|
16500
|
+
return void 0;
|
|
16501
|
+
}
|
|
16502
|
+
function isActiveCodexTurn(turn) {
|
|
16503
|
+
return turn.status === "inProgress" || turn.status === "running";
|
|
16504
|
+
}
|
|
16385
16505
|
function carrierArgs(payload) {
|
|
16386
16506
|
return record(record(payload).args);
|
|
16387
16507
|
}
|
|
@@ -16464,7 +16584,7 @@ function optionalPositiveInteger(value) {
|
|
|
16464
16584
|
function isCodexNativeHistoryPage(value, sessionId) {
|
|
16465
16585
|
const page = record(value);
|
|
16466
16586
|
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";
|
|
16587
|
+
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
16588
|
}
|
|
16469
16589
|
function truncateCodePoints(value, maximum) {
|
|
16470
16590
|
return [...value].slice(0, maximum).join("");
|
|
@@ -16541,7 +16661,7 @@ var AsyncValueQueue2 = class {
|
|
|
16541
16661
|
continue;
|
|
16542
16662
|
}
|
|
16543
16663
|
if (this.closed) return;
|
|
16544
|
-
const next = await new Promise((
|
|
16664
|
+
const next = await new Promise((resolve3) => this.waiters.push(resolve3));
|
|
16545
16665
|
if (next.done) return;
|
|
16546
16666
|
yield next.value;
|
|
16547
16667
|
}
|
|
@@ -16554,6 +16674,7 @@ import { platform } from "node:os";
|
|
|
16554
16674
|
// src/config.ts
|
|
16555
16675
|
import { hostname } from "node:os";
|
|
16556
16676
|
import s from "@deepseek-ai/schemastery";
|
|
16677
|
+
var DEFAULT_REMOTE_SERVER_URL = "https://dsh.r2049.cn";
|
|
16557
16678
|
var Config = s.object({
|
|
16558
16679
|
enabled: s.boolean(),
|
|
16559
16680
|
role: s.union(["host", "client", "both"]),
|
|
@@ -16643,9 +16764,10 @@ function normalizeServerUrl(value) {
|
|
|
16643
16764
|
}
|
|
16644
16765
|
|
|
16645
16766
|
// src/version.ts
|
|
16646
|
-
var PLUGIN_VERSION = "0.4.
|
|
16767
|
+
var PLUGIN_VERSION = "0.4.4";
|
|
16647
16768
|
|
|
16648
16769
|
// src/server-api.ts
|
|
16770
|
+
var TERMINAL_CONTROL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f]/u;
|
|
16649
16771
|
var HostServerApi = class {
|
|
16650
16772
|
constructor(serverUrl, store, fetchImplementation = fetch, role = "host") {
|
|
16651
16773
|
this.store = store;
|
|
@@ -16694,20 +16816,20 @@ var HostServerApi = class {
|
|
|
16694
16816
|
if (account.length === 0 || password.length === 0) {
|
|
16695
16817
|
throw new ServerApiError("INVALID_MESSAGE", "Email and password are required.", false);
|
|
16696
16818
|
}
|
|
16697
|
-
const
|
|
16819
|
+
const login2 = validateWebLogin(await this.publicRequest("/api/v1/auth/login", {
|
|
16698
16820
|
method: "POST",
|
|
16699
16821
|
body: JSON.stringify({ email: account, password })
|
|
16700
16822
|
}));
|
|
16701
16823
|
await this.register(identity, {
|
|
16702
|
-
accountToken:
|
|
16703
|
-
account:
|
|
16824
|
+
accountToken: login2.token,
|
|
16825
|
+
account: login2.account,
|
|
16704
16826
|
authorizationMethod: "account"
|
|
16705
16827
|
});
|
|
16706
16828
|
return {
|
|
16707
16829
|
method: "account",
|
|
16708
|
-
account:
|
|
16709
|
-
expiresAt:
|
|
16710
|
-
isAdmin:
|
|
16830
|
+
account: login2.account,
|
|
16831
|
+
expiresAt: login2.expiresAt,
|
|
16832
|
+
isAdmin: login2.isAdmin
|
|
16711
16833
|
};
|
|
16712
16834
|
}
|
|
16713
16835
|
async startOAuthQrLogin(provider = "zhihu") {
|
|
@@ -16715,10 +16837,11 @@ var HostServerApi = class {
|
|
|
16715
16837
|
method: "POST",
|
|
16716
16838
|
body: "{}"
|
|
16717
16839
|
}), "QR login");
|
|
16718
|
-
|
|
16840
|
+
const scanUrl = normalizeOAuthScanUrl(value.scanUrl, this.baseUrl);
|
|
16841
|
+
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
16842
|
throw new ServerApiError("INVALID_MESSAGE", "The Server returned an invalid QR login session.", false);
|
|
16720
16843
|
}
|
|
16721
|
-
return { qrId: value.qrId, scanUrl
|
|
16844
|
+
return { qrId: value.qrId, scanUrl, expiresIn: value.expiresIn };
|
|
16722
16845
|
}
|
|
16723
16846
|
async pollOAuthQrLogin(identity, qrId, recoverIdentity) {
|
|
16724
16847
|
this.bindIdentity(identity);
|
|
@@ -16933,17 +17056,26 @@ var HostServerApi = class {
|
|
|
16933
17056
|
return this.identity;
|
|
16934
17057
|
}
|
|
16935
17058
|
};
|
|
17059
|
+
function normalizeOAuthScanUrl(value, baseUrl) {
|
|
17060
|
+
if (typeof value !== "string" || TERMINAL_CONTROL_CHARACTERS.test(value)) return void 0;
|
|
17061
|
+
try {
|
|
17062
|
+
const normalized = new URL(value).href;
|
|
17063
|
+
return normalized.startsWith(`${baseUrl}/`) ? normalized : void 0;
|
|
17064
|
+
} catch {
|
|
17065
|
+
return void 0;
|
|
17066
|
+
}
|
|
17067
|
+
}
|
|
16936
17068
|
var ClientServerApi = class extends HostServerApi {
|
|
16937
17069
|
constructor(serverUrl, store, fetchImplementation = fetch) {
|
|
16938
17070
|
super(serverUrl, store, fetchImplementation, "client");
|
|
16939
17071
|
}
|
|
16940
17072
|
};
|
|
16941
17073
|
var ServerApiError = class extends Error {
|
|
16942
|
-
constructor(code, message, retryable,
|
|
17074
|
+
constructor(code, message, retryable, status2) {
|
|
16943
17075
|
super(message);
|
|
16944
17076
|
this.code = code;
|
|
16945
17077
|
this.retryable = retryable;
|
|
16946
|
-
this.status =
|
|
17078
|
+
this.status = status2;
|
|
16947
17079
|
}
|
|
16948
17080
|
};
|
|
16949
17081
|
function validateTokens(value) {
|
|
@@ -16974,12 +17106,12 @@ async function parseBody(response) {
|
|
|
16974
17106
|
throw new ServerApiError("INVALID_MESSAGE", "The Server returned invalid JSON.", false, response.status);
|
|
16975
17107
|
}
|
|
16976
17108
|
}
|
|
16977
|
-
function mapStatus(
|
|
16978
|
-
if (
|
|
16979
|
-
if (
|
|
16980
|
-
if (
|
|
16981
|
-
if (
|
|
16982
|
-
return
|
|
17109
|
+
function mapStatus(status2) {
|
|
17110
|
+
if (status2 === 401) return "AUTH_INVALID";
|
|
17111
|
+
if (status2 === 403) return "AUTH_REQUIRED";
|
|
17112
|
+
if (status2 === 404) return "DEVICE_NOT_FOUND";
|
|
17113
|
+
if (status2 === 429) return "RATE_LIMITED";
|
|
17114
|
+
return status2 >= 500 ? "CONNECTION_FAILED" : "INVALID_MESSAGE";
|
|
16983
17115
|
}
|
|
16984
17116
|
function parseHostDevice(value) {
|
|
16985
17117
|
const item = requireRecord(value, "host device");
|
|
@@ -17281,10 +17413,10 @@ function isUsableExternalNode(candidate, requireFrom) {
|
|
|
17281
17413
|
}
|
|
17282
17414
|
function isExecutableFile(candidate) {
|
|
17283
17415
|
try {
|
|
17284
|
-
const
|
|
17285
|
-
if (!
|
|
17416
|
+
const stat6 = statSync(candidate);
|
|
17417
|
+
if (!stat6.isFile()) return false;
|
|
17286
17418
|
if (process.platform === "win32") return true;
|
|
17287
|
-
return (
|
|
17419
|
+
return (stat6.mode & 73) !== 0;
|
|
17288
17420
|
} catch {
|
|
17289
17421
|
return false;
|
|
17290
17422
|
}
|
|
@@ -17373,8 +17505,8 @@ var ExternalNativePeerConnection = class {
|
|
|
17373
17505
|
request(method, payload) {
|
|
17374
17506
|
if (this.closed) return Promise.reject(new Error("native rtc helper is closed"));
|
|
17375
17507
|
const id2 = this.nextRequestId++;
|
|
17376
|
-
const promise = new Promise((
|
|
17377
|
-
this.pending.set(id2, { resolve:
|
|
17508
|
+
const promise = new Promise((resolve3, reject) => {
|
|
17509
|
+
this.pending.set(id2, { resolve: resolve3, reject });
|
|
17378
17510
|
});
|
|
17379
17511
|
this.write({ id: id2, method, payload });
|
|
17380
17512
|
return promise;
|
|
@@ -18168,10 +18300,10 @@ function parseRouteTarget(value) {
|
|
|
18168
18300
|
async function detectRouteHostIpv4(target, timeoutMs) {
|
|
18169
18301
|
const socket = createSocket("udp4");
|
|
18170
18302
|
try {
|
|
18171
|
-
return await new Promise((
|
|
18303
|
+
return await new Promise((resolve3, reject) => {
|
|
18172
18304
|
const timer = setTimeout(() => {
|
|
18173
18305
|
cleanup();
|
|
18174
|
-
|
|
18306
|
+
resolve3(void 0);
|
|
18175
18307
|
}, timeoutMs);
|
|
18176
18308
|
const cleanup = () => {
|
|
18177
18309
|
clearTimeout(timer);
|
|
@@ -18185,7 +18317,7 @@ async function detectRouteHostIpv4(target, timeoutMs) {
|
|
|
18185
18317
|
socket.connect(target.port, target.host, () => {
|
|
18186
18318
|
cleanup();
|
|
18187
18319
|
const address = socket.address();
|
|
18188
|
-
|
|
18320
|
+
resolve3(typeof address === "string" ? void 0 : address.address);
|
|
18189
18321
|
});
|
|
18190
18322
|
});
|
|
18191
18323
|
} finally {
|
|
@@ -19139,7 +19271,7 @@ async function probeRemoteHostFeatures(client, clientVersion) {
|
|
|
19139
19271
|
}
|
|
19140
19272
|
async function waitForCodexFrames(stream, signal) {
|
|
19141
19273
|
if (signal?.aborted) throw new ClientModeError("RPC_ABORTED", "The Codex event poll was cancelled.");
|
|
19142
|
-
await new Promise((
|
|
19274
|
+
await new Promise((resolve3, reject) => {
|
|
19143
19275
|
const previousWake = stream.wake;
|
|
19144
19276
|
const timer = setTimeout(done, 25e3);
|
|
19145
19277
|
const onAbort = () => {
|
|
@@ -19153,7 +19285,7 @@ async function waitForCodexFrames(stream, signal) {
|
|
|
19153
19285
|
}
|
|
19154
19286
|
function done() {
|
|
19155
19287
|
cleanup();
|
|
19156
|
-
|
|
19288
|
+
resolve3();
|
|
19157
19289
|
}
|
|
19158
19290
|
stream.wake = () => {
|
|
19159
19291
|
previousWake();
|
|
@@ -20368,7 +20500,7 @@ var HostServerConnection = class {
|
|
|
20368
20500
|
this.controlFrameLimits = {};
|
|
20369
20501
|
let acknowledged = false;
|
|
20370
20502
|
let messageQueue = Promise.resolve();
|
|
20371
|
-
await new Promise((
|
|
20503
|
+
await new Promise((resolve3, reject) => {
|
|
20372
20504
|
let settled = false;
|
|
20373
20505
|
const helloTimer = setTimeout(() => socket.close(4001, "hello timeout"), 1e4);
|
|
20374
20506
|
const finish = (error) => {
|
|
@@ -20377,7 +20509,7 @@ var HostServerConnection = class {
|
|
|
20377
20509
|
clearTimeout(helloTimer);
|
|
20378
20510
|
this.online = false;
|
|
20379
20511
|
if (this.socket === socket) this.socket = void 0;
|
|
20380
|
-
void this.dropTunnels().finally(() => error === void 0 ?
|
|
20512
|
+
void this.dropTunnels().finally(() => error === void 0 ? resolve3() : reject(error));
|
|
20381
20513
|
};
|
|
20382
20514
|
socket.onopen = () => {
|
|
20383
20515
|
this.sendControl("hello", {
|
|
@@ -20895,14 +21027,14 @@ var HostServerConnection = class {
|
|
|
20895
21027
|
waitBeforeRetry(baseDelay) {
|
|
20896
21028
|
const spread = baseDelay * this.config.reconnect.jitter;
|
|
20897
21029
|
const delay = Math.max(0, Math.round(baseDelay - spread + Math.random() * spread * 2));
|
|
20898
|
-
return new Promise((
|
|
21030
|
+
return new Promise((resolve3) => {
|
|
20899
21031
|
const timer = setTimeout(() => {
|
|
20900
21032
|
this.retryWake = void 0;
|
|
20901
|
-
|
|
21033
|
+
resolve3();
|
|
20902
21034
|
}, delay);
|
|
20903
21035
|
this.retryWake = () => {
|
|
20904
21036
|
clearTimeout(timer);
|
|
20905
|
-
|
|
21037
|
+
resolve3();
|
|
20906
21038
|
};
|
|
20907
21039
|
});
|
|
20908
21040
|
}
|
|
@@ -21868,7 +22000,7 @@ function historyRequestPayload(payload, maxMessages) {
|
|
|
21868
22000
|
return { ...payload, maxMessages };
|
|
21869
22001
|
}
|
|
21870
22002
|
function withTimeout(promise, ms, message) {
|
|
21871
|
-
return new Promise((
|
|
22003
|
+
return new Promise((resolve3, reject) => {
|
|
21872
22004
|
const timer = setTimeout(() => {
|
|
21873
22005
|
reject(new RpcError("TIMEOUT", message, void 0, true));
|
|
21874
22006
|
}, ms);
|
|
@@ -21876,7 +22008,7 @@ function withTimeout(promise, ms, message) {
|
|
|
21876
22008
|
promise.then(
|
|
21877
22009
|
(value) => {
|
|
21878
22010
|
clearTimeout(timer);
|
|
21879
|
-
|
|
22011
|
+
resolve3(value);
|
|
21880
22012
|
},
|
|
21881
22013
|
(error) => {
|
|
21882
22014
|
clearTimeout(timer);
|
|
@@ -22206,8 +22338,9 @@ function concatChunks2(chunks, totalBytes) {
|
|
|
22206
22338
|
|
|
22207
22339
|
// src/codex/domain.ts
|
|
22208
22340
|
import { randomUUID } from "node:crypto";
|
|
22341
|
+
import { realpath, stat as stat4 } from "node:fs/promises";
|
|
22209
22342
|
import { homedir as homedir3 } from "node:os";
|
|
22210
|
-
import { isAbsolute as isAbsolute3, join as join5 } from "node:path";
|
|
22343
|
+
import { isAbsolute as isAbsolute3, join as join5, resolve as resolve2 } from "node:path";
|
|
22211
22344
|
|
|
22212
22345
|
// src/codex/app-server.ts
|
|
22213
22346
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -22280,15 +22413,15 @@ var CodexAppServerClient = class {
|
|
|
22280
22413
|
const child = this.process;
|
|
22281
22414
|
this.process = void 0;
|
|
22282
22415
|
if (child === void 0 || child.exitCode !== null || child.killed) return;
|
|
22283
|
-
await new Promise((
|
|
22416
|
+
await new Promise((resolve3) => {
|
|
22284
22417
|
const timer = setTimeout(() => {
|
|
22285
22418
|
child.kill("SIGKILL");
|
|
22286
|
-
|
|
22419
|
+
resolve3();
|
|
22287
22420
|
}, 2e3);
|
|
22288
22421
|
timer.unref?.();
|
|
22289
22422
|
child.once("exit", () => {
|
|
22290
22423
|
clearTimeout(timer);
|
|
22291
|
-
|
|
22424
|
+
resolve3();
|
|
22292
22425
|
});
|
|
22293
22426
|
child.kill("SIGTERM");
|
|
22294
22427
|
});
|
|
@@ -22344,13 +22477,13 @@ var CodexAppServerClient = class {
|
|
|
22344
22477
|
}
|
|
22345
22478
|
request(method, params, timeoutMs) {
|
|
22346
22479
|
const id2 = this.nextId++;
|
|
22347
|
-
const result = new Promise((
|
|
22480
|
+
const result = new Promise((resolve3, reject) => {
|
|
22348
22481
|
const timer = setTimeout(() => {
|
|
22349
22482
|
this.pending.delete(id2);
|
|
22350
22483
|
reject(new CodexAppServerError("CODEX_REQUEST_TIMEOUT", "Codex App Server request timed out."));
|
|
22351
22484
|
}, timeoutMs);
|
|
22352
22485
|
timer.unref?.();
|
|
22353
|
-
this.pending.set(id2, { resolve:
|
|
22486
|
+
this.pending.set(id2, { resolve: resolve3, reject, timer });
|
|
22354
22487
|
});
|
|
22355
22488
|
try {
|
|
22356
22489
|
this.write({ id: id2, method, params });
|
|
@@ -22825,6 +22958,8 @@ function concatChunks3(chunks, totalBytes) {
|
|
|
22825
22958
|
// src/codex/domain.ts
|
|
22826
22959
|
var APPROVAL_TTL_MS = 5 * 6e4;
|
|
22827
22960
|
var DEFAULT_RESTART_DELAYS_MS = [1e3, 2e3, 4e3, 8e3, 15e3];
|
|
22961
|
+
var CODEX_PAGE_LIMIT2 = 100;
|
|
22962
|
+
var MAX_CODEX_PAGES2 = 32;
|
|
22828
22963
|
var CODEX_HISTORY_PAGE_LIMIT = 25;
|
|
22829
22964
|
var MAX_CODEX_HISTORY_PAGES = 64;
|
|
22830
22965
|
var CodexRemoteDomain = class {
|
|
@@ -22838,6 +22973,7 @@ var CodexRemoteDomain = class {
|
|
|
22838
22973
|
unsubscribeInbound;
|
|
22839
22974
|
unsubscribeUnavailable;
|
|
22840
22975
|
peers = /* @__PURE__ */ new Map();
|
|
22976
|
+
peerDeviceIds = /* @__PURE__ */ new Map();
|
|
22841
22977
|
turnOwners = /* @__PURE__ */ new Map();
|
|
22842
22978
|
approvals = /* @__PURE__ */ new Map();
|
|
22843
22979
|
approvalExpiryTimer;
|
|
@@ -22877,6 +23013,7 @@ var CodexRemoteDomain = class {
|
|
|
22877
23013
|
if (!this.config.enabled) return void 0;
|
|
22878
23014
|
const bridge = new CodexPeerBridge(this, context, publish, this.logger);
|
|
22879
23015
|
this.peers.set(context.connectionId, bridge);
|
|
23016
|
+
this.peerDeviceIds.set(context.connectionId, context.peerDeviceId);
|
|
22880
23017
|
return bridge;
|
|
22881
23018
|
}
|
|
22882
23019
|
async call(connectionId, input2) {
|
|
@@ -22890,19 +23027,19 @@ var CodexRemoteDomain = class {
|
|
|
22890
23027
|
return sanitizeProjectList(await this.callUpstream(call.method, call.params));
|
|
22891
23028
|
}
|
|
22892
23029
|
if (call.method === "thread/list") {
|
|
22893
|
-
|
|
22894
|
-
|
|
22895
|
-
|
|
23030
|
+
const result = sanitizeThreadList(await this.callUpstream(call.method, call.params));
|
|
23031
|
+
return filterThreadListByWorkspaceAuthority(
|
|
23032
|
+
result,
|
|
23033
|
+
await this.readWorkspaceAuthority(result.data)
|
|
22896
23034
|
);
|
|
22897
23035
|
}
|
|
22898
23036
|
if (call.method === "thread/start") {
|
|
22899
23037
|
const cwd = await this.requireCodexWorkspacePath(call.params.cwd);
|
|
22900
|
-
const permission = codexPermission(call.params);
|
|
23038
|
+
const permission = codexPermission(call.params, "workspace-write");
|
|
22901
23039
|
const result = await this.callUpstream(call.method, {
|
|
22902
23040
|
...permission.params,
|
|
22903
23041
|
cwd,
|
|
22904
|
-
|
|
22905
|
-
sandbox: permission.sandbox,
|
|
23042
|
+
...codexThreadPermissionParams(permission),
|
|
22906
23043
|
serviceName: "deepseek_harness_remote"
|
|
22907
23044
|
});
|
|
22908
23045
|
if (extractThread(result)?.id === void 0) {
|
|
@@ -22913,7 +23050,7 @@ var CodexRemoteDomain = class {
|
|
|
22913
23050
|
const threadId = threadIdFromParams(call.params);
|
|
22914
23051
|
if (call.method === "dsh/sessionHistory") {
|
|
22915
23052
|
const thread = await this.readThreadForHistory(connectionId, threadId);
|
|
22916
|
-
|
|
23053
|
+
const page = paginateCodexNativeHistory(
|
|
22917
23054
|
projectCodexNativeHistory(thread, `codex:${threadId}`),
|
|
22918
23055
|
{
|
|
22919
23056
|
beforeSeq: optionalInteger2(call.params.beforeSeq),
|
|
@@ -22921,6 +23058,8 @@ var CodexRemoteDomain = class {
|
|
|
22921
23058
|
maxMessages: optionalInteger2(call.params.maxMessages)
|
|
22922
23059
|
}
|
|
22923
23060
|
);
|
|
23061
|
+
const activeTurnId2 = typeof page.activeTurnId === "string" ? page.activeTurnId : this.turnOwners.get(threadId)?.turnId;
|
|
23062
|
+
return activeTurnId2 === void 0 ? page : { ...page, activeTurnId: activeTurnId2 };
|
|
22924
23063
|
}
|
|
22925
23064
|
const allowedThread = threadId === void 0 ? void 0 : await this.readKnownThread(threadId);
|
|
22926
23065
|
if (call.method === "thread/read") {
|
|
@@ -22933,39 +23072,38 @@ var CodexRemoteDomain = class {
|
|
|
22933
23072
|
return this.callUpstream(call.method, call.params);
|
|
22934
23073
|
}
|
|
22935
23074
|
let claimed = false;
|
|
23075
|
+
let previousOwner;
|
|
22936
23076
|
if (isThreadMutation(call.method) && threadId !== void 0) {
|
|
22937
|
-
|
|
23077
|
+
const claim = this.claimTurn(
|
|
23078
|
+
threadId,
|
|
23079
|
+
connectionId,
|
|
23080
|
+
call.method,
|
|
23081
|
+
typeof call.params.turnId === "string" ? call.params.turnId : void 0
|
|
23082
|
+
);
|
|
23083
|
+
claimed = claim.claimed;
|
|
23084
|
+
previousOwner = claim.previous;
|
|
22938
23085
|
}
|
|
22939
23086
|
try {
|
|
22940
23087
|
const permission = codexPermission(call.params);
|
|
22941
23088
|
const upstreamParams = call.method === "thread/resume" && allowedThread !== void 0 ? {
|
|
22942
23089
|
...permission.params,
|
|
22943
23090
|
...allowedThread.cwd === void 0 ? {} : { cwd: allowedThread.cwd },
|
|
22944
|
-
|
|
22945
|
-
sandbox: permission.sandbox,
|
|
23091
|
+
...codexThreadPermissionParams(permission),
|
|
22946
23092
|
excludeTurns: true
|
|
22947
23093
|
} : call.method === "thread/fork" && allowedThread !== void 0 ? {
|
|
22948
23094
|
...permission.params,
|
|
22949
23095
|
...allowedThread.cwd === void 0 ? {} : { cwd: allowedThread.cwd },
|
|
22950
|
-
|
|
22951
|
-
sandbox: permission.sandbox
|
|
23096
|
+
...codexThreadPermissionParams(permission)
|
|
22952
23097
|
} : call.method === "turn/start" ? {
|
|
22953
23098
|
...permission.params,
|
|
22954
23099
|
...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
|
-
}
|
|
23100
|
+
...codexTurnPermissionParams(permission, allowedThread?.cwd)
|
|
22963
23101
|
} : permission.params;
|
|
22964
23102
|
let result;
|
|
22965
23103
|
try {
|
|
22966
23104
|
result = await this.callUpstream(call.method, upstreamParams);
|
|
22967
23105
|
} catch (error) {
|
|
22968
|
-
if (call.method === "thread/resume" && allowedThread !== void 0 && error instanceof RpcError && error.code === "CODEX_UPSTREAM_ERROR") {
|
|
23106
|
+
if (call.method === "thread/resume" && allowedThread !== void 0 && error instanceof RpcError && error.code === "CODEX_UPSTREAM_ERROR" && call.params.permissionPreset === void 0) {
|
|
22969
23107
|
return { thread: allowedThread.thread };
|
|
22970
23108
|
}
|
|
22971
23109
|
throw error;
|
|
@@ -22973,9 +23111,15 @@ var CodexRemoteDomain = class {
|
|
|
22973
23111
|
if (call.method === "thread/resume" || call.method === "thread/fork" || call.method === "thread/unarchive") {
|
|
22974
23112
|
await this.assertResultThreadAllowed(result);
|
|
22975
23113
|
}
|
|
23114
|
+
if (call.method === "turn/start" && threadId !== void 0) {
|
|
23115
|
+
this.rememberTurnId(threadId, connectionId, extractTurnId(result));
|
|
23116
|
+
}
|
|
22976
23117
|
return result;
|
|
22977
23118
|
} catch (error) {
|
|
22978
|
-
if (claimed && threadId !== void 0)
|
|
23119
|
+
if (claimed && threadId !== void 0) {
|
|
23120
|
+
if (previousOwner === void 0) this.turnOwners.delete(threadId);
|
|
23121
|
+
else this.turnOwners.set(threadId, previousOwner);
|
|
23122
|
+
}
|
|
22979
23123
|
throw mapAppServerError(error);
|
|
22980
23124
|
}
|
|
22981
23125
|
}
|
|
@@ -22994,8 +23138,9 @@ var CodexRemoteDomain = class {
|
|
|
22994
23138
|
async detachPeer(connectionId) {
|
|
22995
23139
|
const bridge = this.peers.get(connectionId);
|
|
22996
23140
|
if (bridge !== void 0) this.peers.delete(connectionId);
|
|
23141
|
+
this.peerDeviceIds.delete(connectionId);
|
|
22997
23142
|
for (const [threadId, owner] of this.turnOwners) {
|
|
22998
|
-
if (owner === connectionId) this.turnOwners.delete(threadId);
|
|
23143
|
+
if (owner.connectionId === connectionId) this.turnOwners.delete(threadId);
|
|
22999
23144
|
}
|
|
23000
23145
|
const appServer = this.appServer;
|
|
23001
23146
|
const pending = [...this.approvals.entries()].filter(([, approval]) => approval.connectionId === connectionId);
|
|
@@ -23014,6 +23159,7 @@ var CodexRemoteDomain = class {
|
|
|
23014
23159
|
this.restartTimer = void 0;
|
|
23015
23160
|
for (const bridge of [...this.peers.values()]) await bridge.closeAll();
|
|
23016
23161
|
this.peers.clear();
|
|
23162
|
+
this.peerDeviceIds.clear();
|
|
23017
23163
|
this.turnOwners.clear();
|
|
23018
23164
|
if (this.approvalExpiryTimer !== void 0) clearTimeout(this.approvalExpiryTimer);
|
|
23019
23165
|
this.approvalExpiryTimer = void 0;
|
|
@@ -23133,6 +23279,13 @@ var CodexRemoteDomain = class {
|
|
|
23133
23279
|
}
|
|
23134
23280
|
const threadId = extractThreadId(message.params);
|
|
23135
23281
|
if (message.method === "turn/completed" && threadId !== void 0) this.turnOwners.delete(threadId);
|
|
23282
|
+
if (message.method === "turn/started" && threadId !== void 0) {
|
|
23283
|
+
const owner = this.turnOwners.get(threadId);
|
|
23284
|
+
const turnId = extractTurnId(message.params);
|
|
23285
|
+
if (owner !== void 0) {
|
|
23286
|
+
this.turnOwners.set(threadId, { ...owner, ...turnId === void 0 ? {} : { turnId } });
|
|
23287
|
+
}
|
|
23288
|
+
}
|
|
23136
23289
|
if (message.method === "serverRequest/resolved") this.resolveUpstreamApproval(message.params);
|
|
23137
23290
|
if (threadId === void 0) return;
|
|
23138
23291
|
await Promise.all([...this.peers.values()].map((peer) => peer.publishInbound(threadId, {
|
|
@@ -23149,7 +23302,7 @@ var CodexRemoteDomain = class {
|
|
|
23149
23302
|
}
|
|
23150
23303
|
const threadId = extractThreadId(message.params);
|
|
23151
23304
|
const owner = threadId === void 0 ? void 0 : this.turnOwners.get(threadId);
|
|
23152
|
-
const peer = owner === void 0 ? void 0 : this.peers.get(owner);
|
|
23305
|
+
const peer = owner === void 0 ? void 0 : this.peers.get(owner.connectionId);
|
|
23153
23306
|
if (threadId === void 0 || owner === void 0 || peer === void 0 || !peer.hasThreadSubscription(threadId)) {
|
|
23154
23307
|
await appServer.respond(message.id, { decision: "decline" });
|
|
23155
23308
|
return;
|
|
@@ -23157,7 +23310,7 @@ var CodexRemoteDomain = class {
|
|
|
23157
23310
|
const requestHandle = randomUUID();
|
|
23158
23311
|
this.approvals.set(requestHandle, {
|
|
23159
23312
|
upstreamId: message.id,
|
|
23160
|
-
connectionId: owner,
|
|
23313
|
+
connectionId: owner.connectionId,
|
|
23161
23314
|
threadId,
|
|
23162
23315
|
method: message.method,
|
|
23163
23316
|
expiresAt: Date.now() + APPROVAL_TTL_MS
|
|
@@ -23176,7 +23329,7 @@ var CodexRemoteDomain = class {
|
|
|
23176
23329
|
}
|
|
23177
23330
|
}
|
|
23178
23331
|
async readKnownThread(threadId) {
|
|
23179
|
-
const authority = await this.
|
|
23332
|
+
const authority = await this.readWorkspaceAuthority();
|
|
23180
23333
|
let result;
|
|
23181
23334
|
try {
|
|
23182
23335
|
result = await this.callUpstream("thread/read", { threadId, includeTurns: false });
|
|
@@ -23189,7 +23342,7 @@ var CodexRemoteDomain = class {
|
|
|
23189
23342
|
return { thread: listed, ...typeof listed.cwd === "string" && listed.cwd.length > 0 ? { cwd: listed.cwd } : {} };
|
|
23190
23343
|
}
|
|
23191
23344
|
const thread = extractThread(result);
|
|
23192
|
-
if (thread === void 0 || thread.id !== threadId || !
|
|
23345
|
+
if (thread === void 0 || thread.id !== threadId || !isThreadAllowedByWorkspaceAuthority(thread, authority)) {
|
|
23193
23346
|
throw new RpcError("CODEX_THREAD_NOT_ALLOWED", "The Codex thread is not available through this Remote Host.");
|
|
23194
23347
|
}
|
|
23195
23348
|
return { thread, ...typeof thread.cwd === "string" && thread.cwd.length > 0 ? { cwd: thread.cwd } : {} };
|
|
@@ -23282,26 +23435,41 @@ var CodexRemoteDomain = class {
|
|
|
23282
23435
|
if (thread === void 0 || typeof thread.id !== "string") {
|
|
23283
23436
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread.");
|
|
23284
23437
|
}
|
|
23285
|
-
if (!
|
|
23438
|
+
if (!isThreadAllowedByWorkspaceAuthority(thread, await this.readWorkspaceAuthority())) {
|
|
23286
23439
|
throw new RpcError("CODEX_THREAD_NOT_ALLOWED", "The Codex thread is not available through this Remote Host.");
|
|
23287
23440
|
}
|
|
23288
23441
|
}
|
|
23289
|
-
claimTurn(threadId, connectionId, method) {
|
|
23442
|
+
claimTurn(threadId, connectionId, method, turnId) {
|
|
23290
23443
|
const owner = this.turnOwners.get(threadId);
|
|
23444
|
+
const peerDeviceId = this.peerDeviceIds.get(connectionId) ?? connectionId;
|
|
23445
|
+
const nextOwner = { connectionId, peerDeviceId, ...turnId === void 0 ? {} : { turnId } };
|
|
23291
23446
|
if (method === "turn/interrupt") {
|
|
23292
23447
|
if (owner === void 0) {
|
|
23293
|
-
this.turnOwners.set(threadId,
|
|
23294
|
-
return true;
|
|
23448
|
+
this.turnOwners.set(threadId, nextOwner);
|
|
23449
|
+
return { claimed: true };
|
|
23295
23450
|
}
|
|
23296
|
-
if (owner !== connectionId
|
|
23297
|
-
|
|
23451
|
+
if (owner.connectionId !== connectionId && owner.peerDeviceId !== peerDeviceId) {
|
|
23452
|
+
throw new RpcError("CODEX_TURN_OWNED", "Only the connection that started this Codex turn can interrupt it.");
|
|
23453
|
+
}
|
|
23454
|
+
if (owner.connectionId !== connectionId) {
|
|
23455
|
+
this.turnOwners.set(threadId, { ...owner, connectionId, peerDeviceId, ...turnId === void 0 ? {} : { turnId } });
|
|
23456
|
+
return { claimed: true, previous: owner };
|
|
23457
|
+
}
|
|
23458
|
+
if (turnId !== void 0 && owner.turnId === void 0) this.turnOwners.set(threadId, { ...owner, turnId });
|
|
23459
|
+
return { claimed: false };
|
|
23298
23460
|
}
|
|
23299
|
-
if (owner !== void 0 && owner !== connectionId) {
|
|
23461
|
+
if (owner !== void 0 && owner.connectionId !== connectionId && owner.peerDeviceId !== peerDeviceId) {
|
|
23300
23462
|
throw new RpcError("CODEX_TURN_OWNED", "Another Remote connection owns the active Codex turn.");
|
|
23301
23463
|
}
|
|
23302
|
-
if (owner === connectionId) return false;
|
|
23303
|
-
this.turnOwners.set(threadId, connectionId);
|
|
23304
|
-
return true;
|
|
23464
|
+
if (owner?.connectionId === connectionId) return { claimed: false };
|
|
23465
|
+
this.turnOwners.set(threadId, owner === void 0 ? nextOwner : { ...owner, connectionId, peerDeviceId });
|
|
23466
|
+
return { claimed: true, previous: owner };
|
|
23467
|
+
}
|
|
23468
|
+
rememberTurnId(threadId, connectionId, turnId) {
|
|
23469
|
+
if (turnId === void 0) return;
|
|
23470
|
+
const owner = this.turnOwners.get(threadId);
|
|
23471
|
+
if (owner === void 0 || owner.connectionId !== connectionId) return;
|
|
23472
|
+
this.turnOwners.set(threadId, { ...owner, turnId });
|
|
23305
23473
|
}
|
|
23306
23474
|
hasSubscriber(threadId) {
|
|
23307
23475
|
return [...this.peers.values()].some((peer) => peer.hasThreadSubscription(threadId));
|
|
@@ -23348,29 +23516,53 @@ var CodexRemoteDomain = class {
|
|
|
23348
23516
|
throw mapAppServerError(error);
|
|
23349
23517
|
}
|
|
23350
23518
|
}
|
|
23351
|
-
async
|
|
23519
|
+
async readWorkspaceAuthority(listedThreads) {
|
|
23352
23520
|
const projectIds = /* @__PURE__ */ new Set();
|
|
23353
23521
|
const roots = [];
|
|
23354
23522
|
let cursor2;
|
|
23355
|
-
|
|
23356
|
-
|
|
23357
|
-
|
|
23358
|
-
|
|
23359
|
-
|
|
23360
|
-
|
|
23361
|
-
const
|
|
23362
|
-
|
|
23363
|
-
|
|
23364
|
-
|
|
23523
|
+
try {
|
|
23524
|
+
for (let page = 0; page < MAX_CODEX_PAGES2; page += 1) {
|
|
23525
|
+
const result = sanitizeProjectList(await this.callUpstream("project/list", {
|
|
23526
|
+
limit: CODEX_PAGE_LIMIT2,
|
|
23527
|
+
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
23528
|
+
}));
|
|
23529
|
+
for (const project of result.data) {
|
|
23530
|
+
const projectRoots = project.roots.map((root) => root.path).filter((path) => isAbsolute3(path));
|
|
23531
|
+
if (projectRoots.length === 0) continue;
|
|
23532
|
+
projectIds.add(project.id);
|
|
23533
|
+
roots.push(...projectRoots);
|
|
23534
|
+
}
|
|
23535
|
+
cursor2 = typeof result.nextCursor === "string" && result.nextCursor.length > 0 ? result.nextCursor : void 0;
|
|
23536
|
+
if (cursor2 === void 0) break;
|
|
23365
23537
|
}
|
|
23366
|
-
|
|
23367
|
-
if (
|
|
23538
|
+
} catch (error) {
|
|
23539
|
+
if (!isProjectListFallbackError(error)) throw error;
|
|
23540
|
+
}
|
|
23541
|
+
if (roots.length > 0) return { projectIds, roots };
|
|
23542
|
+
const threads = listedThreads === void 0 ? [] : [...listedThreads];
|
|
23543
|
+
if (listedThreads === void 0) {
|
|
23544
|
+
cursor2 = void 0;
|
|
23545
|
+
for (let page = 0; page < MAX_CODEX_PAGES2; page += 1) {
|
|
23546
|
+
const result = sanitizeThreadList(await this.callUpstream("thread/list", {
|
|
23547
|
+
limit: CODEX_PAGE_LIMIT2,
|
|
23548
|
+
sortKey: "updated_at",
|
|
23549
|
+
sortDirection: "desc",
|
|
23550
|
+
archived: false,
|
|
23551
|
+
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
23552
|
+
}));
|
|
23553
|
+
threads.push(...result.data);
|
|
23554
|
+
cursor2 = typeof result.nextCursor === "string" && result.nextCursor.length > 0 ? result.nextCursor : void 0;
|
|
23555
|
+
if (cursor2 === void 0) break;
|
|
23556
|
+
}
|
|
23557
|
+
}
|
|
23558
|
+
for (const workspace of deriveCodexCwdWorkspaces(threads)) {
|
|
23559
|
+
if (isAbsolute3(workspace.path)) roots.push(workspace.path);
|
|
23368
23560
|
}
|
|
23369
23561
|
return { projectIds, roots };
|
|
23370
23562
|
}
|
|
23371
23563
|
async findKnownThreadInList(threadId, authority) {
|
|
23372
23564
|
let cursor2;
|
|
23373
|
-
for (let page = 0; page <
|
|
23565
|
+
for (let page = 0; page < MAX_CODEX_PAGES2; page += 1) {
|
|
23374
23566
|
const result = sanitizeThreadList(await this.callUpstream("thread/list", {
|
|
23375
23567
|
limit: 100,
|
|
23376
23568
|
sortKey: "updated_at",
|
|
@@ -23380,7 +23572,7 @@ var CodexRemoteDomain = class {
|
|
|
23380
23572
|
}));
|
|
23381
23573
|
const thread = result.data.find((item) => item.id === threadId);
|
|
23382
23574
|
if (thread !== void 0) {
|
|
23383
|
-
return
|
|
23575
|
+
return isThreadAllowedByWorkspaceAuthority(thread, authority) ? thread : void 0;
|
|
23384
23576
|
}
|
|
23385
23577
|
cursor2 = typeof result.nextCursor === "string" && result.nextCursor.length > 0 ? result.nextCursor : void 0;
|
|
23386
23578
|
if (cursor2 === void 0) break;
|
|
@@ -23391,16 +23583,28 @@ var CodexRemoteDomain = class {
|
|
|
23391
23583
|
if (!isAbsolute3(path)) {
|
|
23392
23584
|
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX working directory is not available as a Workspace.");
|
|
23393
23585
|
}
|
|
23394
|
-
const paths = await this.
|
|
23395
|
-
const
|
|
23396
|
-
|
|
23586
|
+
const paths = await this.listCodexWorkspacePaths();
|
|
23587
|
+
const lexicalCandidate = resolve2(path);
|
|
23588
|
+
let candidate;
|
|
23589
|
+
try {
|
|
23590
|
+
candidate = await realpath(path);
|
|
23591
|
+
if (!(await stat4(candidate)).isDirectory()) throw new Error("not a directory");
|
|
23592
|
+
} catch {
|
|
23397
23593
|
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX working directory is not available as a Workspace.");
|
|
23398
23594
|
}
|
|
23399
|
-
|
|
23595
|
+
for (const root of paths.values()) {
|
|
23596
|
+
try {
|
|
23597
|
+
if (!containsCodexPath(resolve2(root), lexicalCandidate)) continue;
|
|
23598
|
+
const canonicalRoot = await realpath(root);
|
|
23599
|
+
if (containsCodexPath(canonicalRoot, candidate)) return lexicalCandidate;
|
|
23600
|
+
} catch {
|
|
23601
|
+
}
|
|
23602
|
+
}
|
|
23603
|
+
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX working directory is not available as a Workspace.");
|
|
23400
23604
|
}
|
|
23401
|
-
async
|
|
23605
|
+
async listCodexWorkspacePaths() {
|
|
23402
23606
|
const paths = /* @__PURE__ */ new Map();
|
|
23403
|
-
const authority = await this.
|
|
23607
|
+
const authority = await this.readWorkspaceAuthority();
|
|
23404
23608
|
for (const root of authority.roots) paths.set(normalizeCodexPathForCompare(root), root);
|
|
23405
23609
|
return paths;
|
|
23406
23610
|
}
|
|
@@ -23469,13 +23673,13 @@ function sanitizeThreadList(result) {
|
|
|
23469
23673
|
...typeof result.backwardsCursor === "string" && result.backwardsCursor.length > 0 ? { backwardsCursor: result.backwardsCursor } : {}
|
|
23470
23674
|
};
|
|
23471
23675
|
}
|
|
23472
|
-
function
|
|
23676
|
+
function filterThreadListByWorkspaceAuthority(result, authority) {
|
|
23473
23677
|
if (!isRecord9(result) || !Array.isArray(result.data)) {
|
|
23474
23678
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
23475
23679
|
}
|
|
23476
23680
|
return {
|
|
23477
23681
|
...result,
|
|
23478
|
-
data: result.data.map((record4) => isRecord9(record4) ? record4 : void 0).filter((thread) => thread !== void 0 &&
|
|
23682
|
+
data: result.data.map((record4) => isRecord9(record4) ? record4 : void 0).filter((thread) => thread !== void 0 && isThreadAllowedByWorkspaceAuthority(thread, authority))
|
|
23479
23683
|
};
|
|
23480
23684
|
}
|
|
23481
23685
|
function sanitizeProjectList(result) {
|
|
@@ -23503,7 +23707,7 @@ function sanitizeProjectList(result) {
|
|
|
23503
23707
|
...typeof result.nextCursor === "string" && result.nextCursor.length > 0 ? { nextCursor: result.nextCursor } : { nextCursor: null }
|
|
23504
23708
|
};
|
|
23505
23709
|
}
|
|
23506
|
-
function
|
|
23710
|
+
function isThreadAllowedByWorkspaceAuthority(thread, authority) {
|
|
23507
23711
|
const projectId = typeof thread.projectId === "string" ? thread.projectId : void 0;
|
|
23508
23712
|
if (projectId !== void 0 && authority.projectIds.has(projectId)) return true;
|
|
23509
23713
|
const cwd = typeof thread.cwd === "string" ? thread.cwd : void 0;
|
|
@@ -23520,6 +23724,12 @@ function normalizeCodexPathForCompare(path) {
|
|
|
23520
23724
|
function extractThread(result) {
|
|
23521
23725
|
return isRecord9(result) && isRecord9(result.thread) ? result.thread : void 0;
|
|
23522
23726
|
}
|
|
23727
|
+
function extractTurnId(result) {
|
|
23728
|
+
if (!isRecord9(result)) return void 0;
|
|
23729
|
+
if (typeof result.turnId === "string" && result.turnId.length > 0) return result.turnId;
|
|
23730
|
+
if (isRecord9(result.turn) && typeof result.turn.id === "string" && result.turn.id.length > 0) return result.turn.id;
|
|
23731
|
+
return void 0;
|
|
23732
|
+
}
|
|
23523
23733
|
function extractThreadId(params) {
|
|
23524
23734
|
if (!isRecord9(params)) return void 0;
|
|
23525
23735
|
if (typeof params.threadId === "string") return params.threadId;
|
|
@@ -23530,15 +23740,37 @@ function extractThreadId(params) {
|
|
|
23530
23740
|
function optionalInteger2(value) {
|
|
23531
23741
|
return typeof value === "number" && Number.isSafeInteger(value) ? value : void 0;
|
|
23532
23742
|
}
|
|
23533
|
-
function codexPermission(params) {
|
|
23743
|
+
function codexPermission(params, fallbackPreset) {
|
|
23534
23744
|
const { permissionPreset: permissionPreset2, ...rest } = params;
|
|
23535
|
-
const
|
|
23745
|
+
const preset = permissionPreset2 === "workspace-write" || permissionPreset2 === "danger-full-access" ? permissionPreset2 : fallbackPreset;
|
|
23746
|
+
if (preset === void 0) return { params: mapCodexImageInputs(rest) };
|
|
23747
|
+
const fullAccess = preset === "danger-full-access";
|
|
23536
23748
|
return {
|
|
23537
23749
|
params: mapCodexImageInputs(rest),
|
|
23538
23750
|
approvalPolicy: fullAccess ? "never" : "on-request",
|
|
23539
23751
|
sandbox: fullAccess ? "danger-full-access" : "workspace-write"
|
|
23540
23752
|
};
|
|
23541
23753
|
}
|
|
23754
|
+
function codexThreadPermissionParams(permission) {
|
|
23755
|
+
if (permission.approvalPolicy === void 0 || permission.sandbox === void 0) return {};
|
|
23756
|
+
return {
|
|
23757
|
+
approvalPolicy: permission.approvalPolicy,
|
|
23758
|
+
sandbox: permission.sandbox
|
|
23759
|
+
};
|
|
23760
|
+
}
|
|
23761
|
+
function codexTurnPermissionParams(permission, cwd) {
|
|
23762
|
+
if (permission.approvalPolicy === void 0 || permission.sandbox === void 0) return {};
|
|
23763
|
+
return {
|
|
23764
|
+
approvalPolicy: permission.approvalPolicy,
|
|
23765
|
+
sandboxPolicy: permission.sandbox === "danger-full-access" ? { type: "dangerFullAccess" } : {
|
|
23766
|
+
type: "workspaceWrite",
|
|
23767
|
+
writableRoots: cwd === void 0 ? [] : [cwd],
|
|
23768
|
+
networkAccess: false,
|
|
23769
|
+
excludeTmpdirEnvVar: false,
|
|
23770
|
+
excludeSlashTmp: false
|
|
23771
|
+
}
|
|
23772
|
+
};
|
|
23773
|
+
}
|
|
23542
23774
|
function mapCodexImageInputs(params) {
|
|
23543
23775
|
if (!Array.isArray(params.input)) return params;
|
|
23544
23776
|
return {
|
|
@@ -23575,6 +23807,9 @@ function errorCode3(error) {
|
|
|
23575
23807
|
function isHistoryReadRecoverable(error) {
|
|
23576
23808
|
return error instanceof RpcError && ["METHOD_NOT_ALLOWED", "METHOD_NOT_FOUND", "CODEX_UPSTREAM_ERROR", "CODEX_REQUEST_TIMEOUT", "CODEX_THREAD_BUSY"].includes(error.code);
|
|
23577
23809
|
}
|
|
23810
|
+
function isProjectListFallbackError(error) {
|
|
23811
|
+
return error instanceof RpcError && ["METHOD_NOT_ALLOWED", "METHOD_NOT_FOUND", "CODEX_UPSTREAM_ERROR"].includes(error.code);
|
|
23812
|
+
}
|
|
23578
23813
|
function canTryNextBinary(error) {
|
|
23579
23814
|
return !(error instanceof RpcError) || !["CODEX_AUTH_REQUIRED", "CODEX_CLOSED"].includes(error.code);
|
|
23580
23815
|
}
|
|
@@ -23693,13 +23928,42 @@ var HostPluginRuntime = class {
|
|
|
23693
23928
|
}
|
|
23694
23929
|
this.serverConnection.reconnect();
|
|
23695
23930
|
}
|
|
23931
|
+
async startHostOAuthQrLogin(provider) {
|
|
23932
|
+
if (this.serverApi === void 0) {
|
|
23933
|
+
throw new ServerApiError("SERVER_NOT_CONFIGURED", "Remote Host Server is unavailable.", false);
|
|
23934
|
+
}
|
|
23935
|
+
return this.serverApi.startOAuthQrLogin(provider);
|
|
23936
|
+
}
|
|
23937
|
+
async pollHostOAuthQrLogin(qrId) {
|
|
23938
|
+
if (this.serverApi === void 0) {
|
|
23939
|
+
throw new ServerApiError("SERVER_NOT_CONFIGURED", "Remote Host Server is unavailable.", false);
|
|
23940
|
+
}
|
|
23941
|
+
const result = await this.serverApi.pollOAuthQrLogin(this.currentIdentity(), qrId, async () => {
|
|
23942
|
+
await this.serverConnection?.stop();
|
|
23943
|
+
this.identity = await this.identities.reset(this.config.deviceName);
|
|
23944
|
+
this.serverApi.bindIdentity(this.identity);
|
|
23945
|
+
this.serverConnection = this.createServerConnection(this.identity);
|
|
23946
|
+
return this.identity;
|
|
23947
|
+
});
|
|
23948
|
+
if (result.status === "complete") {
|
|
23949
|
+
this.serverConnection?.reconnect();
|
|
23950
|
+
this.logger.info("Host account authorized through OAuth QR login");
|
|
23951
|
+
}
|
|
23952
|
+
return result;
|
|
23953
|
+
}
|
|
23696
23954
|
async clearHostAuthorization() {
|
|
23697
23955
|
await this.serverConnection?.stop();
|
|
23698
|
-
|
|
23956
|
+
let revokeFailure;
|
|
23957
|
+
try {
|
|
23958
|
+
await this.serverApi?.revokeCurrentDevice();
|
|
23959
|
+
} catch (error) {
|
|
23960
|
+
revokeFailure = error;
|
|
23961
|
+
}
|
|
23699
23962
|
this.identity = await this.identities.reset(this.config.deviceName);
|
|
23700
23963
|
this.serverApi?.bindIdentity(this.identity);
|
|
23701
23964
|
if (this.serverApi !== void 0) this.serverConnection = this.createServerConnection(this.identity);
|
|
23702
23965
|
this.logger.info("Host authorization cleared");
|
|
23966
|
+
if (revokeFailure !== void 0) throw revokeFailure;
|
|
23703
23967
|
}
|
|
23704
23968
|
async authorizeHostAsOwned(accessToken, account) {
|
|
23705
23969
|
if (this.serverApi === void 0) {
|
|
@@ -23787,6 +24051,7 @@ var HostPluginRuntime = class {
|
|
|
23787
24051
|
peerDeviceId: this.connections.peerDeviceId() === void 0 ? void 0 : shortId5(this.connections.peerDeviceId()),
|
|
23788
24052
|
peerDeviceIds: this.connections.peerDeviceIds().map(shortId5),
|
|
23789
24053
|
trustedPeers: this.identities.listTrustedPeers().length,
|
|
24054
|
+
capabilities: this.hostCapabilities(),
|
|
23790
24055
|
codex: this.codex.status()
|
|
23791
24056
|
};
|
|
23792
24057
|
}
|
|
@@ -23806,12 +24071,12 @@ var HostPluginRuntime = class {
|
|
|
23806
24071
|
}
|
|
23807
24072
|
async readHarnessVersion() {
|
|
23808
24073
|
let reportedVersion;
|
|
23809
|
-
let
|
|
24074
|
+
let errorCode5;
|
|
23810
24075
|
try {
|
|
23811
24076
|
const response = await this.apiProxy?.host.describe({ rpcId: randomUUID2(), payload: {} });
|
|
23812
24077
|
if (response === void 0) throw new Error("ApiProxy is unavailable");
|
|
23813
24078
|
if (!response.result.ok) {
|
|
23814
|
-
|
|
24079
|
+
errorCode5 = response.result.error.code;
|
|
23815
24080
|
} else {
|
|
23816
24081
|
reportedVersion = normalizeHarnessVersion(response.result.value.version);
|
|
23817
24082
|
}
|
|
@@ -23820,7 +24085,7 @@ var HostPluginRuntime = class {
|
|
|
23820
24085
|
const distributionVersion = reportedVersion === void 0 || reportedVersion === "0.0.1" ? await readHarnessDistributionVersion() : void 0;
|
|
23821
24086
|
const version = selectHarnessVersion(reportedVersion, distributionVersion);
|
|
23822
24087
|
if (version !== void 0) return version;
|
|
23823
|
-
this.logger.warn("Harness version is unavailable",
|
|
24088
|
+
this.logger.warn("Harness version is unavailable", errorCode5 === void 0 ? void 0 : { code: errorCode5 });
|
|
23824
24089
|
return void 0;
|
|
23825
24090
|
}
|
|
23826
24091
|
hostCapabilities() {
|
|
@@ -23857,6 +24122,618 @@ function isPlainRecord(value) {
|
|
|
23857
24122
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23858
24123
|
}
|
|
23859
24124
|
|
|
24125
|
+
// src/cli.ts
|
|
24126
|
+
import { stat as stat5 } from "node:fs/promises";
|
|
24127
|
+
import { hostname as hostname3 } from "node:os";
|
|
24128
|
+
import { join as join6 } from "node:path";
|
|
24129
|
+
var QR_POLL_INTERVAL_MS = 2e3;
|
|
24130
|
+
var TERMINAL_QR_MARGIN = 4;
|
|
24131
|
+
async function runCli(args = process.argv.slice(2), dependencies = {}) {
|
|
24132
|
+
const runtime = resolveDependencies(dependencies);
|
|
24133
|
+
const [command, ...rest] = args;
|
|
24134
|
+
try {
|
|
24135
|
+
if (command === "login") return await login(rest, runtime);
|
|
24136
|
+
if (command === "status") return await status(rest, runtime);
|
|
24137
|
+
if (command === "logout") return await logout(rest, runtime);
|
|
24138
|
+
if (command === "help" || command === "--help" || command === "-h" || command === void 0) {
|
|
24139
|
+
write(runtime.stdout, helpText());
|
|
24140
|
+
return 0;
|
|
24141
|
+
}
|
|
24142
|
+
throw new CliUsageError(`Unknown command: ${command}`);
|
|
24143
|
+
} catch (error) {
|
|
24144
|
+
write(runtime.stderr, `${cliErrorMessage(error)}
|
|
24145
|
+
`);
|
|
24146
|
+
if (error instanceof CliUsageError) write(runtime.stderr, `
|
|
24147
|
+
${helpText()}`);
|
|
24148
|
+
return error instanceof CliUsageError ? 2 : 1;
|
|
24149
|
+
}
|
|
24150
|
+
}
|
|
24151
|
+
async function login(args, runtime) {
|
|
24152
|
+
if (args.length > 1) throw new CliUsageError("Usage: ds-harness-remote login [github|zhihu]");
|
|
24153
|
+
const provider = args[0] ?? "zhihu";
|
|
24154
|
+
if (provider !== "github" && provider !== "zhihu") {
|
|
24155
|
+
throw new CliUsageError("Login provider must be github or zhihu.");
|
|
24156
|
+
}
|
|
24157
|
+
const context = await hostContext(runtime);
|
|
24158
|
+
const session = await context.api.startOAuthQrLogin(provider);
|
|
24159
|
+
const qr = await runtime.renderQr(session.scanUrl);
|
|
24160
|
+
const providerName = provider === "github" ? "GitHub" : "Zhihu";
|
|
24161
|
+
write(runtime.stdout, `Using ${providerName} QR login. ${alternativeProviderHint(provider)}
|
|
24162
|
+
`);
|
|
24163
|
+
write(runtime.stdout, "Scan this QR code to authorize this Host:\n\n");
|
|
24164
|
+
write(runtime.stdout, `${qr.trimEnd()}
|
|
24165
|
+
`);
|
|
24166
|
+
write(runtime.stdout, `Authorization URL: ${terminalLink(session.scanUrl, runtime.stdout)}
|
|
24167
|
+
|
|
24168
|
+
Waiting for authorization...
|
|
24169
|
+
`);
|
|
24170
|
+
const deadline = runtime.now() + session.expiresIn * 1e3;
|
|
24171
|
+
let identity = context.identity;
|
|
24172
|
+
while (runtime.now() < deadline) {
|
|
24173
|
+
let result;
|
|
24174
|
+
try {
|
|
24175
|
+
result = await context.api.pollOAuthQrLogin(identity, session.qrId, async () => {
|
|
24176
|
+
identity = await context.identities.reset(context.deviceName);
|
|
24177
|
+
return identity;
|
|
24178
|
+
});
|
|
24179
|
+
} catch (error) {
|
|
24180
|
+
if (!(error instanceof ServerApiError) || !error.retryable) throw error;
|
|
24181
|
+
await runtime.wait(Math.min(QR_POLL_INTERVAL_MS, Math.max(1, deadline - runtime.now())));
|
|
24182
|
+
continue;
|
|
24183
|
+
}
|
|
24184
|
+
if (result.status === "complete") {
|
|
24185
|
+
write(runtime.stdout, `${authorizedMessage(result.authorization)} Restart dsh-tui to bring the Remote Host online.
|
|
24186
|
+
`);
|
|
24187
|
+
return 0;
|
|
24188
|
+
}
|
|
24189
|
+
if (result.status === "expired") break;
|
|
24190
|
+
await runtime.wait(Math.min(QR_POLL_INTERVAL_MS, Math.max(1, deadline - runtime.now())));
|
|
24191
|
+
}
|
|
24192
|
+
write(runtime.stderr, "The QR login expired. Run the login command again to generate a new code.\n");
|
|
24193
|
+
return 1;
|
|
24194
|
+
}
|
|
24195
|
+
async function status(args, runtime) {
|
|
24196
|
+
if (args.length !== 0) throw new CliUsageError("Usage: ds-harness-remote status");
|
|
24197
|
+
const serverUrl = selectedServer();
|
|
24198
|
+
const root = new IdentityStore({ env: runtime.env }).directory;
|
|
24199
|
+
const directory = serverStorageDirectory(root, serverUrl, "host");
|
|
24200
|
+
const lines = [
|
|
24201
|
+
"Remote Host status",
|
|
24202
|
+
`Server: ${serverUrl}`,
|
|
24203
|
+
"Host control: enabled (dsh-TUI default)"
|
|
24204
|
+
];
|
|
24205
|
+
if (!await exists3(join6(directory, "device.json"))) {
|
|
24206
|
+
lines.push("Device: not initialized", "Authorization: logged out", "Credential: unavailable");
|
|
24207
|
+
write(runtime.stdout, `${lines.join("\n")}
|
|
24208
|
+
|
|
24209
|
+
Run "ds-harness-remote login" or use "/remote login" in dsh-TUI.
|
|
24210
|
+
`);
|
|
24211
|
+
return 0;
|
|
24212
|
+
}
|
|
24213
|
+
const identities = runtime.createIdentityStore({ directory, env: runtime.env });
|
|
24214
|
+
const identity = await identities.loadOrCreate(hostname3());
|
|
24215
|
+
const store = new ServerCredentialStore(directory);
|
|
24216
|
+
const stored = await store.load(serverUrl, identity.deviceId);
|
|
24217
|
+
lines.push(`Device: ${identity.name} (${identity.deviceId})`);
|
|
24218
|
+
if (stored === void 0) {
|
|
24219
|
+
lines.push("Authorization: logged out", "Credential: unavailable");
|
|
24220
|
+
write(runtime.stdout, `${lines.join("\n")}
|
|
24221
|
+
|
|
24222
|
+
Run "ds-harness-remote login" or use "/remote login" in dsh-TUI.
|
|
24223
|
+
`);
|
|
24224
|
+
return 0;
|
|
24225
|
+
}
|
|
24226
|
+
lines.push(`Authorization: logged in (${authorizationLabel(stored.authorizationMethod)})`);
|
|
24227
|
+
if (stored.account !== void 0) lines.push(`Account: ${stored.account}`);
|
|
24228
|
+
const api = runtime.createHostApi(serverUrl, store);
|
|
24229
|
+
api.bindIdentity(identity);
|
|
24230
|
+
try {
|
|
24231
|
+
await api.authenticate(identity);
|
|
24232
|
+
lines.push("Credential: ready");
|
|
24233
|
+
lines.push("Presence: published while dsh-tui is running");
|
|
24234
|
+
write(runtime.stdout, `${lines.join("\n")}
|
|
24235
|
+
`);
|
|
24236
|
+
return 0;
|
|
24237
|
+
} catch (error) {
|
|
24238
|
+
lines.push(`Credential: unavailable (${statusErrorCode(error)})`);
|
|
24239
|
+
write(runtime.stdout, `${lines.join("\n")}
|
|
24240
|
+
`);
|
|
24241
|
+
return 1;
|
|
24242
|
+
}
|
|
24243
|
+
}
|
|
24244
|
+
async function logout(args, runtime) {
|
|
24245
|
+
if (args.length !== 0) throw new CliUsageError("Usage: ds-harness-remote logout");
|
|
24246
|
+
const serverUrl = selectedServer();
|
|
24247
|
+
const root = new IdentityStore({ env: runtime.env }).directory;
|
|
24248
|
+
const directory = serverStorageDirectory(root, serverUrl, "host");
|
|
24249
|
+
if (!await exists3(join6(directory, "device.json"))) {
|
|
24250
|
+
await new ServerCredentialStore(directory).clear();
|
|
24251
|
+
write(runtime.stdout, "This Host is already logged out.\n");
|
|
24252
|
+
return 0;
|
|
24253
|
+
}
|
|
24254
|
+
const deviceName = hostname3();
|
|
24255
|
+
const identities = runtime.createIdentityStore({ directory, env: runtime.env });
|
|
24256
|
+
const identity = await identities.loadOrCreate(deviceName);
|
|
24257
|
+
const api = runtime.createHostApi(serverUrl, new ServerCredentialStore(directory));
|
|
24258
|
+
api.bindIdentity(identity);
|
|
24259
|
+
let revokeFailure;
|
|
24260
|
+
try {
|
|
24261
|
+
await api.revokeCurrentDevice();
|
|
24262
|
+
} catch (error) {
|
|
24263
|
+
revokeFailure = error;
|
|
24264
|
+
}
|
|
24265
|
+
await identities.reset(deviceName);
|
|
24266
|
+
if (revokeFailure !== void 0) {
|
|
24267
|
+
throw new Error(`Local Host credentials were cleared, but Server revocation failed: ${cliErrorMessage(revokeFailure)}`);
|
|
24268
|
+
}
|
|
24269
|
+
write(runtime.stdout, "Remote Host logged out and its local device identity was rotated. Restart dsh-tui.\n");
|
|
24270
|
+
return 0;
|
|
24271
|
+
}
|
|
24272
|
+
async function hostContext(runtime) {
|
|
24273
|
+
const serverUrl = selectedServer();
|
|
24274
|
+
const root = new IdentityStore({ env: runtime.env }).directory;
|
|
24275
|
+
const directory = serverStorageDirectory(root, serverUrl, "host");
|
|
24276
|
+
const deviceName = hostname3();
|
|
24277
|
+
const identities = runtime.createIdentityStore({ directory, env: runtime.env });
|
|
24278
|
+
const identity = await identities.loadOrCreate(deviceName);
|
|
24279
|
+
const api = runtime.createHostApi(serverUrl, new ServerCredentialStore(directory));
|
|
24280
|
+
return { api, identities, identity, deviceName };
|
|
24281
|
+
}
|
|
24282
|
+
function selectedServer() {
|
|
24283
|
+
return normalizeServerUrl(DEFAULT_REMOTE_SERVER_URL);
|
|
24284
|
+
}
|
|
24285
|
+
function resolveDependencies(input2) {
|
|
24286
|
+
return {
|
|
24287
|
+
env: input2.env ?? process.env,
|
|
24288
|
+
stdout: input2.stdout ?? process.stdout,
|
|
24289
|
+
stderr: input2.stderr ?? process.stderr,
|
|
24290
|
+
now: input2.now ?? Date.now,
|
|
24291
|
+
wait: input2.wait ?? ((milliseconds) => new Promise((resolve3) => setTimeout(resolve3, milliseconds))),
|
|
24292
|
+
renderQr: input2.renderQr ?? renderTerminalQr,
|
|
24293
|
+
createIdentityStore: input2.createIdentityStore ?? ((options) => new IdentityStore(options)),
|
|
24294
|
+
createHostApi: input2.createHostApi ?? ((serverUrl, store) => new HostServerApi(serverUrl, store))
|
|
24295
|
+
};
|
|
24296
|
+
}
|
|
24297
|
+
async function renderTerminalQr(url) {
|
|
24298
|
+
const { default: QRCode } = await import("qrcode");
|
|
24299
|
+
const modules = QRCode.create(url, { errorCorrectionLevel: "M" }).modules;
|
|
24300
|
+
const width = modules.size + TERMINAL_QR_MARGIN * 2;
|
|
24301
|
+
const quietLine = `\x1B[47m${" ".repeat(width * 2)}\x1B[0m`;
|
|
24302
|
+
const lines = Array.from({ length: TERMINAL_QR_MARGIN }, () => quietLine);
|
|
24303
|
+
for (let row = 0; row < modules.size; row += 1) {
|
|
24304
|
+
let line = `\x1B[47m${" ".repeat(TERMINAL_QR_MARGIN * 2)}`;
|
|
24305
|
+
for (let column = 0; column < modules.size; column += 1) {
|
|
24306
|
+
line += modules.get(row, column) === 1 ? "\x1B[40m " : "\x1B[47m ";
|
|
24307
|
+
}
|
|
24308
|
+
line += `\x1B[47m${" ".repeat(TERMINAL_QR_MARGIN * 2)}\x1B[0m`;
|
|
24309
|
+
lines.push(line);
|
|
24310
|
+
}
|
|
24311
|
+
lines.push(...Array.from({ length: TERMINAL_QR_MARGIN }, () => quietLine));
|
|
24312
|
+
return lines.join("\n");
|
|
24313
|
+
}
|
|
24314
|
+
async function renderCompactTerminalQr(url) {
|
|
24315
|
+
const { default: QRCode } = await import("qrcode");
|
|
24316
|
+
const modules = QRCode.create(url, { errorCorrectionLevel: "M" }).modules;
|
|
24317
|
+
const size = modules.size + TERMINAL_QR_MARGIN * 2;
|
|
24318
|
+
const lines = [];
|
|
24319
|
+
const isBlack = (row, column) => {
|
|
24320
|
+
const qrRow = row - TERMINAL_QR_MARGIN;
|
|
24321
|
+
const qrColumn = column - TERMINAL_QR_MARGIN;
|
|
24322
|
+
return qrRow >= 0 && qrRow < modules.size && qrColumn >= 0 && qrColumn < modules.size && modules.get(qrRow, qrColumn) === 1;
|
|
24323
|
+
};
|
|
24324
|
+
for (let row = 0; row < size; row += 2) {
|
|
24325
|
+
let line = "\x1B[30;47m";
|
|
24326
|
+
for (let column = 0; column < size; column += 1) {
|
|
24327
|
+
const top = isBlack(row, column);
|
|
24328
|
+
const bottom = isBlack(row + 1, column);
|
|
24329
|
+
line += top ? bottom ? "\u2588" : "\u2580" : bottom ? "\u2584" : " ";
|
|
24330
|
+
}
|
|
24331
|
+
lines.push(`${line}\x1B[0m`);
|
|
24332
|
+
}
|
|
24333
|
+
return lines.join("\n");
|
|
24334
|
+
}
|
|
24335
|
+
function authorizedMessage(authorization) {
|
|
24336
|
+
return authorization.account === void 0 ? "Remote Host login complete." : `Remote Host login complete for ${authorization.account}.`;
|
|
24337
|
+
}
|
|
24338
|
+
function alternativeProviderHint(provider) {
|
|
24339
|
+
return provider === "zhihu" ? "GitHub is also supported: ds-harness-remote login github" : "Zhihu is also supported: ds-harness-remote login zhihu";
|
|
24340
|
+
}
|
|
24341
|
+
function authorizationLabel(method) {
|
|
24342
|
+
if (method === "host_registration_code") return "Host registration code";
|
|
24343
|
+
if (method === "owned_device") return "owned device";
|
|
24344
|
+
return "account";
|
|
24345
|
+
}
|
|
24346
|
+
function statusErrorCode(error) {
|
|
24347
|
+
return error instanceof ServerApiError ? error.code : "CONNECTION_FAILED";
|
|
24348
|
+
}
|
|
24349
|
+
function cliErrorMessage(error) {
|
|
24350
|
+
const message = error instanceof Error ? error.message : "The Remote command failed.";
|
|
24351
|
+
const code = error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
24352
|
+
return code === void 0 ? message : `${message} (${code})`;
|
|
24353
|
+
}
|
|
24354
|
+
function helpText() {
|
|
24355
|
+
return [
|
|
24356
|
+
"Usage:",
|
|
24357
|
+
" ds-harness-remote login [github|zhihu]",
|
|
24358
|
+
" ds-harness-remote status",
|
|
24359
|
+
" ds-harness-remote logout",
|
|
24360
|
+
"",
|
|
24361
|
+
"Inside dsh-TUI, use /remote login, /remote status, or /remote logout.",
|
|
24362
|
+
"login defaults to Zhihu and authorizes this computer as a Remote Host with a terminal QR code.",
|
|
24363
|
+
`The Server is ${DEFAULT_REMOTE_SERVER_URL}.`,
|
|
24364
|
+
"Host configuration is not exposed by this CLI yet. Restart dsh-tui after login or logout.",
|
|
24365
|
+
""
|
|
24366
|
+
].join("\n");
|
|
24367
|
+
}
|
|
24368
|
+
function write(target, value) {
|
|
24369
|
+
target.write(value);
|
|
24370
|
+
}
|
|
24371
|
+
function terminalLink(url, target) {
|
|
24372
|
+
if (target.isTTY !== true) return url;
|
|
24373
|
+
return `\x1B]8;;${url}\x07${url}\x1B]8;;\x07`;
|
|
24374
|
+
}
|
|
24375
|
+
async function exists3(path) {
|
|
24376
|
+
try {
|
|
24377
|
+
await stat5(path);
|
|
24378
|
+
return true;
|
|
24379
|
+
} catch (error) {
|
|
24380
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return false;
|
|
24381
|
+
throw error;
|
|
24382
|
+
}
|
|
24383
|
+
}
|
|
24384
|
+
var CliUsageError = class extends Error {
|
|
24385
|
+
};
|
|
24386
|
+
|
|
24387
|
+
// src/tui-command.ts
|
|
24388
|
+
var QR_POLL_INTERVAL_MS2 = 2e3;
|
|
24389
|
+
var REMOTE_LOGIN_SCENE_ID = "remote-login";
|
|
24390
|
+
var REMOTE_STATUS_SCENE_ID = "remote-status";
|
|
24391
|
+
function installTuiRemoteCommand(ctx, resolveTarget) {
|
|
24392
|
+
const tuiContext = ctx;
|
|
24393
|
+
const commands = tuiContext.get("commands", false);
|
|
24394
|
+
if (commands === void 0) return;
|
|
24395
|
+
const pluginHost = tuiContext.get("tuiPluginHost", false);
|
|
24396
|
+
const trees = tuiContext.get("tuiCommandTrees", false);
|
|
24397
|
+
const scenes = tuiContext.get("tuiScenes", false);
|
|
24398
|
+
const login2 = new RemoteLoginController(resolveTarget);
|
|
24399
|
+
const LoginScene = createRemoteLoginScene(login2);
|
|
24400
|
+
const StatusScene = createRemoteStatusScene(resolveTarget);
|
|
24401
|
+
tuiContext.effect(() => {
|
|
24402
|
+
const definition = {
|
|
24403
|
+
name: "remote",
|
|
24404
|
+
description: "Manage Remote Host login and connection status",
|
|
24405
|
+
input: { hint: "[status | login [github|zhihu] | logout]" },
|
|
24406
|
+
recordInput: false,
|
|
24407
|
+
handler: async ({ rawInput }) => {
|
|
24408
|
+
const args = rawInput.trim().split(/\s+/u).filter(Boolean);
|
|
24409
|
+
const command = args[0] ?? "status";
|
|
24410
|
+
if (command === "status" && args.length <= 1) {
|
|
24411
|
+
if (scenes?.open(REMOTE_STATUS_SCENE_ID) === true) return { kind: "success" };
|
|
24412
|
+
return { kind: "success", text: formatRemoteStatusInline(resolveTarget()) };
|
|
24413
|
+
}
|
|
24414
|
+
if (command === "login" && args.length <= 2) {
|
|
24415
|
+
const provider = args[1] ?? "zhihu";
|
|
24416
|
+
if (provider !== "github" && provider !== "zhihu") {
|
|
24417
|
+
return { kind: "error", text: "Usage: /remote login [github|zhihu]" };
|
|
24418
|
+
}
|
|
24419
|
+
if (scenes === void 0) {
|
|
24420
|
+
return {
|
|
24421
|
+
kind: "error",
|
|
24422
|
+
text: `The Remote login screen is unavailable. Run "ds-harness-remote login ${provider}" outside dsh-TUI, then restart it.`
|
|
24423
|
+
};
|
|
24424
|
+
}
|
|
24425
|
+
login2.start(provider);
|
|
24426
|
+
if (!scenes.open(REMOTE_LOGIN_SCENE_ID)) {
|
|
24427
|
+
login2.cancel();
|
|
24428
|
+
return { kind: "error", text: "The Remote login screen is unavailable." };
|
|
24429
|
+
}
|
|
24430
|
+
return { kind: "success" };
|
|
24431
|
+
}
|
|
24432
|
+
if (command === "logout" && args.length === 1) {
|
|
24433
|
+
const target = resolveTarget();
|
|
24434
|
+
if (target === void 0) return remoteNotReady();
|
|
24435
|
+
try {
|
|
24436
|
+
await target.runtime.clearHostAuthorization();
|
|
24437
|
+
return {
|
|
24438
|
+
kind: "success",
|
|
24439
|
+
text: "Remote Host logged out and its local device identity was rotated."
|
|
24440
|
+
};
|
|
24441
|
+
} catch (error) {
|
|
24442
|
+
return {
|
|
24443
|
+
kind: "error",
|
|
24444
|
+
text: `Local Remote Host credentials were cleared, but Server revocation failed (${errorCode4(error)}).`
|
|
24445
|
+
};
|
|
24446
|
+
}
|
|
24447
|
+
}
|
|
24448
|
+
if (command === "config") {
|
|
24449
|
+
return { kind: "error", text: "Host configuration is not supported yet." };
|
|
24450
|
+
}
|
|
24451
|
+
return { kind: "error", text: remoteCommandUsage() };
|
|
24452
|
+
}
|
|
24453
|
+
};
|
|
24454
|
+
const disposeCommand = registerRemoteCommand(tuiContext, commands, pluginHost, definition);
|
|
24455
|
+
const disposeTree = registerOptional(tuiContext, "command completion", () => trees?.register({
|
|
24456
|
+
root: "remote",
|
|
24457
|
+
descriptions: {
|
|
24458
|
+
en: "Manage Remote Host login and connection status",
|
|
24459
|
+
zh: "\u7BA1\u7406 Remote Host \u767B\u5F55\u548C\u8FDE\u63A5\u72B6\u6001"
|
|
24460
|
+
},
|
|
24461
|
+
children: remoteCommandChildren
|
|
24462
|
+
}));
|
|
24463
|
+
const disposeScene = registerOptional(tuiContext, "login scene", () => scenes?.register({
|
|
24464
|
+
id: REMOTE_LOGIN_SCENE_ID,
|
|
24465
|
+
title: "Remote Host login",
|
|
24466
|
+
component: LoginScene
|
|
24467
|
+
}, tuiContext));
|
|
24468
|
+
const disposeStatusScene = registerOptional(tuiContext, "status scene", () => scenes?.register({
|
|
24469
|
+
id: REMOTE_STATUS_SCENE_ID,
|
|
24470
|
+
title: "Remote Host status",
|
|
24471
|
+
component: StatusScene
|
|
24472
|
+
}, tuiContext));
|
|
24473
|
+
return () => {
|
|
24474
|
+
login2.cancel();
|
|
24475
|
+
disposeCommand();
|
|
24476
|
+
disposeTree();
|
|
24477
|
+
disposeScene();
|
|
24478
|
+
disposeStatusScene();
|
|
24479
|
+
};
|
|
24480
|
+
}, "ds-harness-remote: dsh-tui /remote command");
|
|
24481
|
+
}
|
|
24482
|
+
function registerRemoteCommand(ctx, commands, pluginHost, definition) {
|
|
24483
|
+
if (pluginHost === void 0) return commands.register(definition);
|
|
24484
|
+
try {
|
|
24485
|
+
return pluginHost.registerCommand(ctx, definition);
|
|
24486
|
+
} catch (error) {
|
|
24487
|
+
if (!hasErrorCode2(error, "COMPONENT_NOT_ADMITTED")) throw error;
|
|
24488
|
+
ctx.logger.debug("dsh-TUI Remote command is using the legacy command registry because Component admission is unavailable");
|
|
24489
|
+
return commands.register(definition);
|
|
24490
|
+
}
|
|
24491
|
+
}
|
|
24492
|
+
function hasErrorCode2(error, code) {
|
|
24493
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
24494
|
+
}
|
|
24495
|
+
function registerOptional(ctx, feature, register) {
|
|
24496
|
+
try {
|
|
24497
|
+
return register() ?? (() => {
|
|
24498
|
+
});
|
|
24499
|
+
} catch (error) {
|
|
24500
|
+
ctx.logger.warn(`dsh-TUI Remote ${feature} is unavailable`, { code: errorCode4(error) });
|
|
24501
|
+
return () => {
|
|
24502
|
+
};
|
|
24503
|
+
}
|
|
24504
|
+
}
|
|
24505
|
+
function remoteCommandChildren(canonicalPath) {
|
|
24506
|
+
if (canonicalPath.length === 1 && canonicalPath[0] === "remote") {
|
|
24507
|
+
return [
|
|
24508
|
+
{
|
|
24509
|
+
name: "status",
|
|
24510
|
+
description: "Show Remote Host authorization and connection status",
|
|
24511
|
+
descriptions: { zh: "\u67E5\u770B Remote Host \u6388\u6743\u548C\u8FDE\u63A5\u72B6\u6001" }
|
|
24512
|
+
},
|
|
24513
|
+
{
|
|
24514
|
+
name: "login",
|
|
24515
|
+
description: "Authorize this Host with a GitHub or Zhihu QR code",
|
|
24516
|
+
descriptions: { zh: "\u4F7F\u7528 GitHub \u6216\u77E5\u4E4E\u4E8C\u7EF4\u7801\u6388\u6743\u5F53\u524D Host" }
|
|
24517
|
+
},
|
|
24518
|
+
{
|
|
24519
|
+
name: "logout",
|
|
24520
|
+
description: "Revoke this Host and rotate its local identity",
|
|
24521
|
+
descriptions: { zh: "\u64A4\u9500\u5F53\u524D Host \u5E76\u8F6E\u6362\u672C\u5730\u8EAB\u4EFD" }
|
|
24522
|
+
}
|
|
24523
|
+
];
|
|
24524
|
+
}
|
|
24525
|
+
if (canonicalPath.length === 2 && canonicalPath[0] === "remote" && canonicalPath[1] === "login") {
|
|
24526
|
+
return [
|
|
24527
|
+
{ name: "zhihu", description: "Sign in with Zhihu (default)", descriptions: { zh: "\u4F7F\u7528\u77E5\u4E4E\u767B\u5F55\uFF08\u9ED8\u8BA4\uFF09" } },
|
|
24528
|
+
{ name: "github", description: "Sign in with GitHub", descriptions: { zh: "\u4F7F\u7528 GitHub \u767B\u5F55" } }
|
|
24529
|
+
];
|
|
24530
|
+
}
|
|
24531
|
+
return [];
|
|
24532
|
+
}
|
|
24533
|
+
function remoteStatusLines(target) {
|
|
24534
|
+
if (target === void 0) {
|
|
24535
|
+
return ["Remote Host is disabled or still starting. Check the ds-harness-remote settings and retry."];
|
|
24536
|
+
}
|
|
24537
|
+
const { runtime, config } = target;
|
|
24538
|
+
const status2 = runtime.hostStatus();
|
|
24539
|
+
const diagnostics = runtime.diagnostics();
|
|
24540
|
+
const codex = runtime.codexStatus();
|
|
24541
|
+
const capabilities = new Set(diagnostics.capabilities);
|
|
24542
|
+
const connection = status2.online ? "online" : status2.reconnecting ? "reconnecting" : status2.accountRequired ? "authorization required" : "offline";
|
|
24543
|
+
return [
|
|
24544
|
+
`Server: ${config.serverUrl ?? "not configured"}`,
|
|
24545
|
+
"Host control: enabled",
|
|
24546
|
+
`Device: ${status2.deviceId ?? "not initialized"}`,
|
|
24547
|
+
`Authorization: ${status2.authorized ? status2.account === void 0 ? "logged in" : `logged in (${status2.account})` : "logged out"}`,
|
|
24548
|
+
`Server connection: ${connection}`,
|
|
24549
|
+
`Harness Remote API: ${capabilities.has("harness.api.v1") ? "available (ApiProxy)" : capabilities.has("harness.remote.v1") ? "available (Typert Remote)" : "unavailable"}`,
|
|
24550
|
+
`Remote clients: ${diagnostics.activeConnections}`,
|
|
24551
|
+
`Codex Remote: ${codex.enabled ? codex.state : "disabled"}`,
|
|
24552
|
+
"",
|
|
24553
|
+
"Commands: /remote login [github|zhihu] \xB7 /remote status \xB7 /remote logout"
|
|
24554
|
+
];
|
|
24555
|
+
}
|
|
24556
|
+
function formatRemoteStatusInline(target) {
|
|
24557
|
+
return remoteStatusLines(target).filter(Boolean).join(" \xB7 ");
|
|
24558
|
+
}
|
|
24559
|
+
function remoteCommandUsage() {
|
|
24560
|
+
return [
|
|
24561
|
+
"Usage:",
|
|
24562
|
+
" /remote",
|
|
24563
|
+
" /remote status",
|
|
24564
|
+
" /remote login [github|zhihu]",
|
|
24565
|
+
" /remote logout"
|
|
24566
|
+
].join("\n");
|
|
24567
|
+
}
|
|
24568
|
+
function remoteNotReady() {
|
|
24569
|
+
return {
|
|
24570
|
+
kind: "error",
|
|
24571
|
+
text: "Remote Host is disabled or still starting. Check the ds-harness-remote settings and retry."
|
|
24572
|
+
};
|
|
24573
|
+
}
|
|
24574
|
+
var RemoteLoginController = class {
|
|
24575
|
+
constructor(resolveTarget) {
|
|
24576
|
+
this.resolveTarget = resolveTarget;
|
|
24577
|
+
}
|
|
24578
|
+
current = { phase: "idle", provider: "zhihu" };
|
|
24579
|
+
listeners = /* @__PURE__ */ new Set();
|
|
24580
|
+
attempt = 0;
|
|
24581
|
+
snapshot = () => this.current;
|
|
24582
|
+
subscribe = (listener) => {
|
|
24583
|
+
this.listeners.add(listener);
|
|
24584
|
+
return () => {
|
|
24585
|
+
this.listeners.delete(listener);
|
|
24586
|
+
};
|
|
24587
|
+
};
|
|
24588
|
+
start(provider) {
|
|
24589
|
+
const attempt = ++this.attempt;
|
|
24590
|
+
this.update({ phase: "loading", provider });
|
|
24591
|
+
void this.run(attempt, provider);
|
|
24592
|
+
}
|
|
24593
|
+
cancel() {
|
|
24594
|
+
this.attempt += 1;
|
|
24595
|
+
}
|
|
24596
|
+
async run(attempt, provider) {
|
|
24597
|
+
try {
|
|
24598
|
+
const target = this.resolveTarget();
|
|
24599
|
+
if (target === void 0) throw new Error("REMOTE_NOT_READY");
|
|
24600
|
+
const session = await target.runtime.startHostOAuthQrLogin(provider);
|
|
24601
|
+
const [qr, compactQr] = await Promise.all([
|
|
24602
|
+
renderTerminalQr(session.scanUrl),
|
|
24603
|
+
renderCompactTerminalQr(session.scanUrl)
|
|
24604
|
+
]);
|
|
24605
|
+
if (attempt !== this.attempt) return;
|
|
24606
|
+
this.update({ phase: "waiting", provider, qr, compactQr, scanUrl: session.scanUrl });
|
|
24607
|
+
await this.poll(attempt, provider, session, target.runtime);
|
|
24608
|
+
} catch (error) {
|
|
24609
|
+
if (attempt !== this.attempt) return;
|
|
24610
|
+
this.update({ phase: "error", provider, error: errorCode4(error) });
|
|
24611
|
+
}
|
|
24612
|
+
}
|
|
24613
|
+
async poll(attempt, provider, session, runtime) {
|
|
24614
|
+
const deadline = Date.now() + session.expiresIn * 1e3;
|
|
24615
|
+
while (attempt === this.attempt && Date.now() < deadline) {
|
|
24616
|
+
try {
|
|
24617
|
+
const result = await runtime.pollHostOAuthQrLogin(session.qrId);
|
|
24618
|
+
if (attempt !== this.attempt) return;
|
|
24619
|
+
if (result.status === "complete") {
|
|
24620
|
+
this.update({ phase: "complete", provider, account: result.authorization.account });
|
|
24621
|
+
return;
|
|
24622
|
+
}
|
|
24623
|
+
if (result.status === "expired") break;
|
|
24624
|
+
} catch (error) {
|
|
24625
|
+
if (!(error instanceof ServerApiError) || !error.retryable) throw error;
|
|
24626
|
+
}
|
|
24627
|
+
await wait(Math.min(QR_POLL_INTERVAL_MS2, Math.max(1, deadline - Date.now())));
|
|
24628
|
+
}
|
|
24629
|
+
if (attempt === this.attempt) this.update({ phase: "expired", provider });
|
|
24630
|
+
}
|
|
24631
|
+
update(snapshot) {
|
|
24632
|
+
this.current = snapshot;
|
|
24633
|
+
for (const listener of this.listeners) listener(snapshot);
|
|
24634
|
+
}
|
|
24635
|
+
};
|
|
24636
|
+
function createRemoteLoginScene(controller) {
|
|
24637
|
+
return function RemoteLoginScene({ React, ui, close }) {
|
|
24638
|
+
const [snapshot, setSnapshot] = React.useState(controller.snapshot());
|
|
24639
|
+
const terminal = ui.useTerminalSize();
|
|
24640
|
+
React.useEffect(() => {
|
|
24641
|
+
const unsubscribe = controller.subscribe(setSnapshot);
|
|
24642
|
+
return () => {
|
|
24643
|
+
unsubscribe();
|
|
24644
|
+
controller.cancel();
|
|
24645
|
+
};
|
|
24646
|
+
}, []);
|
|
24647
|
+
ui.useInput((input2, key) => {
|
|
24648
|
+
if (key.escape === true || input2.toLowerCase() === "q") {
|
|
24649
|
+
controller.cancel();
|
|
24650
|
+
close();
|
|
24651
|
+
}
|
|
24652
|
+
});
|
|
24653
|
+
const provider = snapshot.provider === "github" ? "GitHub" : "Zhihu";
|
|
24654
|
+
const other = snapshot.provider === "github" ? "/remote login zhihu" : "/remote login github";
|
|
24655
|
+
const children = [
|
|
24656
|
+
React.createElement(ui.Text, { key: "title", bold: true, color: "accent" }, "Remote Host login"),
|
|
24657
|
+
React.createElement(ui.Text, { key: "provider" }, `Provider: ${provider} \xB7 You can also use ${other}`)
|
|
24658
|
+
];
|
|
24659
|
+
if (snapshot.phase === "loading") {
|
|
24660
|
+
children.push(React.createElement(ui.Text, { key: "loading", color: "subtle" }, "Creating authorization QR code\u2026"));
|
|
24661
|
+
} else if (snapshot.phase === "waiting" && snapshot.qr !== void 0 && snapshot.scanUrl !== void 0) {
|
|
24662
|
+
const fullRows = snapshot.qr.split("\n").length;
|
|
24663
|
+
const fullColumns = printableWidth(snapshot.qr.split("\n")[0] ?? "");
|
|
24664
|
+
const useFullQr = terminal.rows >= fullRows + 7 && terminal.columns >= fullColumns + 4;
|
|
24665
|
+
const qr = useFullQr || snapshot.compactQr === void 0 ? snapshot.qr : snapshot.compactQr;
|
|
24666
|
+
const qrRows = qr.split("\n").length;
|
|
24667
|
+
const qrColumns = printableWidth(qr.split("\n")[0] ?? "");
|
|
24668
|
+
if (terminal.rows < qrRows + 7 || terminal.columns < qrColumns + 4) {
|
|
24669
|
+
children.push(React.createElement(
|
|
24670
|
+
ui.Text,
|
|
24671
|
+
{ key: "size-warning", color: "warning" },
|
|
24672
|
+
`Resize the terminal to at least ${qrColumns + 4} \xD7 ${qrRows + 7} if the QR code is clipped.`
|
|
24673
|
+
));
|
|
24674
|
+
}
|
|
24675
|
+
children.push(
|
|
24676
|
+
React.createElement(ui.Text, { key: "scan" }, "Scan this QR code to authorize this Host:"),
|
|
24677
|
+
React.createElement(ui.Text, { key: "qr", wrap: "truncate" }, qr),
|
|
24678
|
+
React.createElement(ui.Text, { key: "url", color: "link", underline: true }, terminalLink2(snapshot.scanUrl)),
|
|
24679
|
+
React.createElement(ui.Text, { key: "waiting", color: "subtle" }, "Waiting for authorization\u2026")
|
|
24680
|
+
);
|
|
24681
|
+
} else if (snapshot.phase === "complete") {
|
|
24682
|
+
children.push(React.createElement(
|
|
24683
|
+
ui.Text,
|
|
24684
|
+
{ key: "complete", color: "success" },
|
|
24685
|
+
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.`
|
|
24686
|
+
));
|
|
24687
|
+
} else if (snapshot.phase === "expired") {
|
|
24688
|
+
children.push(React.createElement(ui.Text, { key: "expired", color: "warning" }, "The QR code expired. Close this screen and run /remote login again."));
|
|
24689
|
+
} else if (snapshot.phase === "error") {
|
|
24690
|
+
children.push(React.createElement(ui.Text, { key: "error", color: "error" }, `Remote Host login failed (${snapshot.error ?? "UNKNOWN"}).`));
|
|
24691
|
+
}
|
|
24692
|
+
children.push(React.createElement(ui.Text, { key: "close", color: "subtle" }, "Press Esc or q to return."));
|
|
24693
|
+
return React.createElement(ui.Box, {
|
|
24694
|
+
flexDirection: "column",
|
|
24695
|
+
gap: 1,
|
|
24696
|
+
paddingX: Math.max(0, Math.min(2, Math.floor((terminal.columns - 1) / 2)))
|
|
24697
|
+
}, ...children);
|
|
24698
|
+
};
|
|
24699
|
+
}
|
|
24700
|
+
function createRemoteStatusScene(resolveTarget) {
|
|
24701
|
+
return function RemoteStatusScene({ React, ui, close }) {
|
|
24702
|
+
const terminal = ui.useTerminalSize();
|
|
24703
|
+
ui.useInput((input2, key) => {
|
|
24704
|
+
if (key.escape === true || input2.toLowerCase() === "q") close();
|
|
24705
|
+
});
|
|
24706
|
+
const children = [
|
|
24707
|
+
React.createElement(ui.Text, { key: "title", bold: true, color: "accent" }, "Remote Host status"),
|
|
24708
|
+
...remoteStatusLines(resolveTarget()).map((line, index) => React.createElement(
|
|
24709
|
+
ui.Text,
|
|
24710
|
+
{ key: `status-${index}`, color: line === "" ? "subtle" : void 0 },
|
|
24711
|
+
line === "" ? " " : line
|
|
24712
|
+
)),
|
|
24713
|
+
React.createElement(ui.Text, { key: "close", color: "subtle" }, "Press Esc or q to return.")
|
|
24714
|
+
];
|
|
24715
|
+
return React.createElement(ui.Box, {
|
|
24716
|
+
flexDirection: "column",
|
|
24717
|
+
gap: 1,
|
|
24718
|
+
paddingX: Math.max(0, Math.min(2, Math.floor((terminal.columns - 1) / 2)))
|
|
24719
|
+
}, ...children);
|
|
24720
|
+
};
|
|
24721
|
+
}
|
|
24722
|
+
function terminalLink2(url) {
|
|
24723
|
+
return `\x1B]8;;${url}\x07${url}\x1B]8;;\x07`;
|
|
24724
|
+
}
|
|
24725
|
+
function printableWidth(value) {
|
|
24726
|
+
return value.replace(/\u001B\[[0-9;]*m/gu, "").length;
|
|
24727
|
+
}
|
|
24728
|
+
function errorCode4(error) {
|
|
24729
|
+
if (error instanceof ServerApiError) return error.code;
|
|
24730
|
+
if (error instanceof Error && "code" in error && typeof error.code === "string") return error.code;
|
|
24731
|
+
return "CONNECTION_FAILED";
|
|
24732
|
+
}
|
|
24733
|
+
function wait(milliseconds) {
|
|
24734
|
+
return new Promise((resolve3) => setTimeout(resolve3, milliseconds));
|
|
24735
|
+
}
|
|
24736
|
+
|
|
23860
24737
|
// src/remote-file-content-provider.ts
|
|
23861
24738
|
var REMOTE_FILE_SAVE_AS_MAX_BYTES = 100 * 1024 * 1024;
|
|
23862
24739
|
var REMOTE_FILE_FAST_SAVE_AS_MAX_BYTES = 1024 * 1024 * 1024;
|
|
@@ -23936,15 +24813,18 @@ var legacyLoaderModuleNames = /* @__PURE__ */ new Set(["dsh-remote", "@dsh-remot
|
|
|
23936
24813
|
var pluginSettingsNamespace = "ds-harness-remote";
|
|
23937
24814
|
var legacySettingsNamespace = "dsh-remote";
|
|
23938
24815
|
function apply(ctx, input2 = {}) {
|
|
23939
|
-
ctx.
|
|
24816
|
+
const tuiCommandsAvailable = ctx.get("commands", false) !== void 0 && ctx.get("tuiScenes", false) !== void 0;
|
|
24817
|
+
const tuiBinding = tuiCommandsAvailable ? {} : void 0;
|
|
24818
|
+
if (tuiBinding !== void 0) installTuiRemoteCommand(ctx, () => tuiBinding.target);
|
|
24819
|
+
ctx.inject(["settings", "typertGateway"], (runtimeContext) => {
|
|
23940
24820
|
const gateway = runtimeContext.get("typertGateway");
|
|
23941
|
-
if (runtimeContext.get("apiProxy") !== void 0 || new TypertGatewaySwitch(gateway).supportsCarrier()) {
|
|
23942
|
-
return activate(runtimeContext, input2);
|
|
24821
|
+
if (tuiCommandsAvailable || runtimeContext.get("apiProxy") !== void 0 || new TypertGatewaySwitch(gateway).supportsCarrier()) {
|
|
24822
|
+
return activate(runtimeContext, input2, tuiBinding);
|
|
23943
24823
|
}
|
|
23944
24824
|
runtimeContext.inject(["apiProxy"], (legacyContext) => activate(legacyContext, input2));
|
|
23945
24825
|
});
|
|
23946
24826
|
}
|
|
23947
|
-
async function activate(ctx, input2) {
|
|
24827
|
+
async function activate(ctx, input2, tuiBinding) {
|
|
23948
24828
|
const settings = ctx.get("settings");
|
|
23949
24829
|
const settingsScope = settings?.register(pluginSettingsNamespace, Config, {
|
|
23950
24830
|
base: input2,
|
|
@@ -23954,11 +24834,12 @@ async function activate(ctx, input2) {
|
|
|
23954
24834
|
}
|
|
23955
24835
|
});
|
|
23956
24836
|
if (settings !== void 0 && settingsScope !== void 0) {
|
|
23957
|
-
const migration =
|
|
23958
|
-
|
|
23959
|
-
if (migration === "failed") ctx.logger.warn("failed to migrate legacy Remote settings namespace");
|
|
24837
|
+
const migration = migrateLegacySettings(settings, settingsScope);
|
|
24838
|
+
reportSettingsMigration(ctx, await migration);
|
|
23960
24839
|
}
|
|
23961
|
-
const
|
|
24840
|
+
const connection = ctx.get("connection");
|
|
24841
|
+
const resolvedConfig = resolveConfig(settingsScope?.get() ?? input2);
|
|
24842
|
+
const config = connection === void 0 && resolvedConfig.serverUrl === void 0 ? { ...resolvedConfig, serverUrl: DEFAULT_REMOTE_SERVER_URL } : resolvedConfig;
|
|
23962
24843
|
if (!config.enabled) return;
|
|
23963
24844
|
const logger = new SafeLogger({
|
|
23964
24845
|
debug: (message) => {
|
|
@@ -23978,13 +24859,11 @@ async function activate(ctx, input2) {
|
|
|
23978
24859
|
console.error(message);
|
|
23979
24860
|
}
|
|
23980
24861
|
}, config.logLevel);
|
|
23981
|
-
await disableLegacyLoaderEntries(ctx, logger);
|
|
23982
24862
|
const defaultIdentityDirectory = new IdentityStore().directory;
|
|
23983
24863
|
const hostIdentities = new IdentityStore({
|
|
23984
24864
|
directory: config.serverUrl === void 0 ? defaultIdentityDirectory : serverStorageDirectory(defaultIdentityDirectory, config.serverUrl, "host")
|
|
23985
24865
|
});
|
|
23986
24866
|
const apiProxy = ctx.get("apiProxy");
|
|
23987
|
-
const connection = ctx.get("connection");
|
|
23988
24867
|
const nativeTypertGateway = ctx.get("typertGateway");
|
|
23989
24868
|
const localTypertGateway = new TypertGatewaySwitch(nativeTypertGateway).local();
|
|
23990
24869
|
const runtime = new HostPluginRuntime(
|
|
@@ -24014,6 +24893,9 @@ async function activate(ctx, input2) {
|
|
|
24014
24893
|
const controlRuntime = connection === void 0 ? void 0 : new PluginControlRuntime(config, defaultIdentityDirectory, settingsScope, clientRuntime, hostControl);
|
|
24015
24894
|
ctx.provide("dshRemote", runtime);
|
|
24016
24895
|
if (clientRuntime !== void 0) ctx.provide("dshRemoteClient", clientRuntime);
|
|
24896
|
+
const tuiTarget = { runtime, config };
|
|
24897
|
+
if (tuiBinding !== void 0) tuiBinding.target = tuiTarget;
|
|
24898
|
+
await disableLegacyLoaderEntries(ctx, logger);
|
|
24017
24899
|
await ctx.effect(async () => {
|
|
24018
24900
|
const disposeControl = controlRuntime?.register(connection);
|
|
24019
24901
|
try {
|
|
@@ -24029,18 +24911,24 @@ async function activate(ctx, input2) {
|
|
|
24029
24911
|
});
|
|
24030
24912
|
}
|
|
24031
24913
|
} catch (error) {
|
|
24914
|
+
if (tuiBinding?.target === tuiTarget) tuiBinding.target = void 0;
|
|
24032
24915
|
await disposeControl?.();
|
|
24033
24916
|
await clientRuntime?.close();
|
|
24034
24917
|
await runtime.close();
|
|
24035
24918
|
throw error;
|
|
24036
24919
|
}
|
|
24037
24920
|
return async () => {
|
|
24921
|
+
if (tuiBinding?.target === tuiTarget) tuiBinding.target = void 0;
|
|
24038
24922
|
await disposeControl?.();
|
|
24039
24923
|
await clientRuntime?.close();
|
|
24040
24924
|
await runtime.close();
|
|
24041
24925
|
};
|
|
24042
24926
|
}, "dsh-remote lifecycle");
|
|
24043
24927
|
}
|
|
24928
|
+
function reportSettingsMigration(ctx, migration) {
|
|
24929
|
+
if (migration === "migrated") ctx.logger.info("migrated legacy Remote settings namespace");
|
|
24930
|
+
if (migration === "failed") ctx.logger.warn("failed to migrate legacy Remote settings namespace");
|
|
24931
|
+
}
|
|
24044
24932
|
async function migrateLegacySettings(settings, currentScope) {
|
|
24045
24933
|
if (typeof settings.describe !== "function") return "skipped";
|
|
24046
24934
|
try {
|
|
@@ -24131,6 +25019,7 @@ export {
|
|
|
24131
25019
|
migrateLegacySettings,
|
|
24132
25020
|
name,
|
|
24133
25021
|
resolveConfig,
|
|
25022
|
+
runCli,
|
|
24134
25023
|
serverStorageDirectory
|
|
24135
25024
|
};
|
|
24136
25025
|
/*! Bundled license information:
|