openmates 0.27.0-alpha.20 → 0.27.0-alpha.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-VFPYXPEU.js → chunk-XVGLSNRM.js} +883 -553
- package/dist/{cli-D6LLx3BR.d.ts → cli-C2G3DpGo.d.ts} +32 -11
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/fixtures/privacy-runtime/linux-arm64/libggml-base.so +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-base.so.0 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-base.so.0.15.1 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-cpu.so +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-cpu.so.0 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-cpu.so.0.15.1 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml.so +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml.so.0 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml.so.0.15.1 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/manifest.json +9 -9
- package/package.json +1 -1
|
@@ -194,8 +194,8 @@ import { chmodSync, closeSync, fsyncSync, mkdirSync, openSync, readFileSync, ren
|
|
|
194
194
|
import { join } from "path";
|
|
195
195
|
var digest = (value) => createHash("sha256").update(value).digest("hex");
|
|
196
196
|
var shortenTaskText = (value, length) => {
|
|
197
|
-
const
|
|
198
|
-
return
|
|
197
|
+
const text6 = value.replace(/\s+/g, " ").trim();
|
|
198
|
+
return text6.length <= length ? text6 : `${text6.slice(0, length - 1)}\u2026`;
|
|
199
199
|
};
|
|
200
200
|
function atomicPrivateFile(path2, content) {
|
|
201
201
|
const temporary = `${path2}.${randomUUID()}.tmp`;
|
|
@@ -403,7 +403,7 @@ async function lockTaskDeliveryRecord(directory, id) {
|
|
|
403
403
|
}
|
|
404
404
|
|
|
405
405
|
// src/taskMutationDelivery.ts
|
|
406
|
-
var digest2 = (
|
|
406
|
+
var digest2 = (text6) => createHash3("sha256").update(text6).digest("hex");
|
|
407
407
|
var stable = (value) => JSON.stringify(value, (_key, item) => item && !Array.isArray(item) && typeof item === "object" ? Object.fromEntries(Object.entries(item).sort(([a], [b]) => a.localeCompare(b))) : item);
|
|
408
408
|
function reconcileMutation(mutation, current) {
|
|
409
409
|
if (mutation.kind === "delete") {
|
|
@@ -576,9 +576,9 @@ function collectGeneratedFiles(value) {
|
|
|
576
576
|
const filename = suppliedName ? safeName(suppliedName) : `openmates-${safeName(assetId ?? "generated")}.${extension}`;
|
|
577
577
|
files.push({ url, filename, assetId });
|
|
578
578
|
};
|
|
579
|
-
const
|
|
579
|
+
const visit2 = (node) => {
|
|
580
580
|
if (Array.isArray(node)) {
|
|
581
|
-
node.forEach(
|
|
581
|
+
node.forEach(visit2);
|
|
582
582
|
return;
|
|
583
583
|
}
|
|
584
584
|
const data = record(node);
|
|
@@ -596,9 +596,9 @@ function collectGeneratedFiles(value) {
|
|
|
596
596
|
if (meta && text(meta.download_url)) add(meta, data, text(meta.variant) ?? "original");
|
|
597
597
|
}
|
|
598
598
|
}
|
|
599
|
-
for (const field of RESULT_FIELDS) if (data[field] !== void 0)
|
|
599
|
+
for (const field of RESULT_FIELDS) if (data[field] !== void 0) visit2(data[field]);
|
|
600
600
|
};
|
|
601
|
-
|
|
601
|
+
visit2(value);
|
|
602
602
|
return files;
|
|
603
603
|
}
|
|
604
604
|
function fetchGeneratedFile(url) {
|
|
@@ -766,10 +766,10 @@ function assertCodexClaimCaller(threadId, currentThread = process.env.CODEX_THRE
|
|
|
766
766
|
}
|
|
767
767
|
|
|
768
768
|
// ../secret-scanner/src/identifierRanges.ts
|
|
769
|
-
function codingIdentifierRanges(
|
|
769
|
+
function codingIdentifierRanges(text6) {
|
|
770
770
|
const ranges = [];
|
|
771
771
|
const identifiers2 = /\b[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}\b|\b[\da-f]{40,64}\b|\[[A-Z][A-Z\d_]*\]/gi;
|
|
772
|
-
for (const match of Array.from(
|
|
772
|
+
for (const match of Array.from(text6.matchAll(identifiers2))) {
|
|
773
773
|
ranges.push({ start: match.index, end: match.index + match[0].length });
|
|
774
774
|
}
|
|
775
775
|
return ranges;
|
|
@@ -1247,16 +1247,16 @@ var PII_TYPE_TO_CATEGORY = {
|
|
|
1247
1247
|
USER_AT_HOSTNAME: "user_at_hostname",
|
|
1248
1248
|
MAC_ADDRESS: "mac_addresses"
|
|
1249
1249
|
};
|
|
1250
|
-
function detectPII(
|
|
1250
|
+
function detectPII(text6, excludedIdsOrOptions = /* @__PURE__ */ new Set()) {
|
|
1251
1251
|
const options = excludedIdsOrOptions instanceof Set ? { excludedIds: excludedIdsOrOptions } : excludedIdsOrOptions;
|
|
1252
1252
|
const excludedIds = options.excludedIds ?? /* @__PURE__ */ new Set();
|
|
1253
1253
|
const disabledCategories = options.disabledCategories ?? /* @__PURE__ */ new Set();
|
|
1254
1254
|
const personalEntries = options.personalDataEntries ?? [];
|
|
1255
|
-
if (!
|
|
1255
|
+
if (!text6 || text6.length < MIN_PII_TEXT_LENGTH && personalEntries.length === 0)
|
|
1256
1256
|
return [];
|
|
1257
1257
|
const matches2 = [];
|
|
1258
1258
|
const coveredRanges = [];
|
|
1259
|
-
const identifierRanges = codingIdentifierRanges(
|
|
1259
|
+
const identifierRanges = codingIdentifierRanges(text6);
|
|
1260
1260
|
const typeCounts = {};
|
|
1261
1261
|
const hasExclusions = excludedIds.size > 0;
|
|
1262
1262
|
const hasDisabledCategories = disabledCategories.size > 0;
|
|
@@ -1264,14 +1264,14 @@ function detectPII(text5, excludedIdsOrOptions = /* @__PURE__ */ new Set()) {
|
|
|
1264
1264
|
const urlExclusionZones = [];
|
|
1265
1265
|
URL_EXCLUSION_REGEX.lastIndex = 0;
|
|
1266
1266
|
let urlMatch;
|
|
1267
|
-
while ((urlMatch = URL_EXCLUSION_REGEX.exec(
|
|
1267
|
+
while ((urlMatch = URL_EXCLUSION_REGEX.exec(text6)) !== null) {
|
|
1268
1268
|
urlExclusionZones.push({
|
|
1269
1269
|
start: urlMatch.index,
|
|
1270
1270
|
end: urlMatch.index + urlMatch[0].length
|
|
1271
1271
|
});
|
|
1272
1272
|
}
|
|
1273
1273
|
const hasUrlExclusions = urlExclusionZones.length > 0;
|
|
1274
|
-
if (
|
|
1274
|
+
if (text6.length >= MIN_PII_TEXT_LENGTH) {
|
|
1275
1275
|
for (const pattern of PII_PATTERNS) {
|
|
1276
1276
|
if (hasDisabledCategories) {
|
|
1277
1277
|
const category = PII_TYPE_TO_CATEGORY[pattern.type];
|
|
@@ -1279,7 +1279,7 @@ function detectPII(text5, excludedIdsOrOptions = /* @__PURE__ */ new Set()) {
|
|
|
1279
1279
|
}
|
|
1280
1280
|
pattern.regex.lastIndex = 0;
|
|
1281
1281
|
let regexMatch;
|
|
1282
|
-
while ((regexMatch = pattern.regex.exec(
|
|
1282
|
+
while ((regexMatch = pattern.regex.exec(text6)) !== null) {
|
|
1283
1283
|
const matchText = regexMatch[0];
|
|
1284
1284
|
const startIndex = regexMatch.index;
|
|
1285
1285
|
const endIndex = startIndex + matchText.length;
|
|
@@ -1325,7 +1325,7 @@ function detectPII(text5, excludedIdsOrOptions = /* @__PURE__ */ new Set()) {
|
|
|
1325
1325
|
}
|
|
1326
1326
|
}
|
|
1327
1327
|
for (const searchText of textsToSearch) {
|
|
1328
|
-
const lowerText =
|
|
1328
|
+
const lowerText = text6.toLowerCase();
|
|
1329
1329
|
const lowerSearch = searchText.toLowerCase();
|
|
1330
1330
|
let searchFrom = 0;
|
|
1331
1331
|
while (searchFrom < lowerText.length) {
|
|
@@ -1337,7 +1337,7 @@ function detectPII(text5, excludedIdsOrOptions = /* @__PURE__ */ new Set()) {
|
|
|
1337
1337
|
(range) => startIndex >= range.start && startIndex < range.end || endIndex > range.start && endIndex <= range.end || startIndex <= range.start && endIndex >= range.end
|
|
1338
1338
|
);
|
|
1339
1339
|
if (!overlaps) {
|
|
1340
|
-
const matchText =
|
|
1340
|
+
const matchText = text6.substring(startIndex, endIndex);
|
|
1341
1341
|
const matchId = `pii-PERSONAL_DATA-${entry.id}-${startIndex}`;
|
|
1342
1342
|
if (!hasExclusions || !excludedIds.has(matchId)) {
|
|
1343
1343
|
const placeholder = entry.replaceWith.startsWith("[") ? entry.replaceWith : `[${entry.replaceWith}]`;
|
|
@@ -1438,8 +1438,8 @@ var ProjectFilePrivacy = class {
|
|
|
1438
1438
|
}
|
|
1439
1439
|
if (this.values.size + this.conflicts.length > 1e4) fail("pii_mapping_limit");
|
|
1440
1440
|
}
|
|
1441
|
-
restoreText(
|
|
1442
|
-
return
|
|
1441
|
+
restoreText(text6) {
|
|
1442
|
+
return text6.replace(TOKEN, (token) => {
|
|
1443
1443
|
if (this.ambiguous.has(token)) fail("pii_mapping_ambiguous");
|
|
1444
1444
|
const mapping = this.values.get(token);
|
|
1445
1445
|
const customToken = this.options.detection?.personalDataEntries?.some((entry) => (entry.replaceWith.startsWith("[") ? entry.replaceWith : `[${entry.replaceWith}]`) === token);
|
|
@@ -1477,28 +1477,28 @@ var ProjectFilePrivacy = class {
|
|
|
1477
1477
|
this.addMappings([{ placeholder, original, type }]);
|
|
1478
1478
|
return placeholder;
|
|
1479
1479
|
}
|
|
1480
|
-
redactText(
|
|
1480
|
+
redactText(text6, enhanced = []) {
|
|
1481
1481
|
const ranges = [];
|
|
1482
|
-
const tokens = Array.from(
|
|
1482
|
+
const tokens = Array.from(text6.matchAll(TOKEN)).map((match) => ({ start: match.index, end: match.index + match[0].length }));
|
|
1483
1483
|
for (const range of tokens) {
|
|
1484
|
-
const literal =
|
|
1484
|
+
const literal = text6.slice(range.start, range.end);
|
|
1485
1485
|
if (!(this.options.preserveMappedTokens && this.values.has(literal)) && (this.values.has(literal) || GENERATED_TOKEN.test(literal) || legacyToken(literal))) ranges.push(range);
|
|
1486
1486
|
}
|
|
1487
1487
|
const overlaps = (start, end) => [...tokens, ...ranges].some((r) => start < r.end && end > r.start);
|
|
1488
1488
|
for (const mapping of Array.from(this.values.values()).sort((a, b) => b.original.length - a.original.length)) {
|
|
1489
|
-
let start =
|
|
1489
|
+
let start = text6.indexOf(mapping.original);
|
|
1490
1490
|
while (start !== -1) {
|
|
1491
1491
|
const end = start + mapping.original.length;
|
|
1492
1492
|
if (!overlaps(start, end)) ranges.push({ start, end, type: mapping.type });
|
|
1493
|
-
start =
|
|
1493
|
+
start = text6.indexOf(mapping.original, end);
|
|
1494
1494
|
}
|
|
1495
1495
|
}
|
|
1496
1496
|
if (this.options.enabled !== false) {
|
|
1497
|
-
for (const match of detectPII(
|
|
1497
|
+
for (const match of detectPII(text6, this.options.detection)) {
|
|
1498
1498
|
if (!overlaps(match.startIndex, match.endIndex)) ranges.push({ start: match.startIndex, end: match.endIndex, type: match.type });
|
|
1499
1499
|
}
|
|
1500
1500
|
for (const range of enhanced) {
|
|
1501
|
-
if (!Number.isInteger(range.start) || !Number.isInteger(range.end) || range.start < 0 || range.end <= range.start || range.end >
|
|
1501
|
+
if (!Number.isInteger(range.start) || !Number.isInteger(range.end) || range.start < 0 || range.end <= range.start || range.end > text6.length) fail("pii_invalid_semantic_range");
|
|
1502
1502
|
let fragments = [{ ...range }];
|
|
1503
1503
|
for (const shield of [...tokens, ...ranges]) fragments = fragments.flatMap((part) => {
|
|
1504
1504
|
if (part.start >= shield.end || part.end <= shield.start) return [part];
|
|
@@ -1513,30 +1513,30 @@ var ProjectFilePrivacy = class {
|
|
|
1513
1513
|
let cursor = 0;
|
|
1514
1514
|
let result = "";
|
|
1515
1515
|
for (const range of ranges.sort((a, b) => a.start - b.start)) {
|
|
1516
|
-
result +=
|
|
1517
|
-
result +=
|
|
1516
|
+
result += text6.slice(cursor, range.start);
|
|
1517
|
+
result += text6.slice(range.start, range.end).split(/(\r?\n)/).map((part) => !part || /^(?:\r?\n)$/.test(part) ? part : this.token(part, range.type)).join("");
|
|
1518
1518
|
cursor = range.end;
|
|
1519
1519
|
}
|
|
1520
|
-
return result +
|
|
1520
|
+
return result + text6.slice(cursor);
|
|
1521
1521
|
}
|
|
1522
1522
|
async redactResult(value) {
|
|
1523
|
-
const
|
|
1523
|
+
const visit2 = async (item) => {
|
|
1524
1524
|
if (typeof item === "string") return this.redactText(item, this.options.enabled !== false && this.options.detectEnhanced ? await this.options.detectEnhanced(item) : []);
|
|
1525
1525
|
if (Array.isArray(item)) {
|
|
1526
1526
|
const result2 = [];
|
|
1527
|
-
for (const child of item) result2.push(await
|
|
1527
|
+
for (const child of item) result2.push(await visit2(child));
|
|
1528
1528
|
return result2;
|
|
1529
1529
|
}
|
|
1530
1530
|
if (item && typeof item === "object") {
|
|
1531
1531
|
const result2 = {};
|
|
1532
1532
|
for (const [key, child] of Object.entries(item)) {
|
|
1533
|
-
result2[key] = ["expected_base", "content_hash", "proposal_commitment"].includes(key) ? child : await
|
|
1533
|
+
result2[key] = ["expected_base", "content_hash", "proposal_commitment"].includes(key) ? child : await visit2(child);
|
|
1534
1534
|
}
|
|
1535
1535
|
return result2;
|
|
1536
1536
|
}
|
|
1537
1537
|
return item;
|
|
1538
1538
|
};
|
|
1539
|
-
const result = await
|
|
1539
|
+
const result = await visit2(value);
|
|
1540
1540
|
const save = this.savePending.catch(() => {
|
|
1541
1541
|
}).then(() => this.options.save([...Array.from(this.values.values()), ...this.conflicts]));
|
|
1542
1542
|
this.savePending = save;
|
|
@@ -1556,26 +1556,26 @@ var LABELS = {
|
|
|
1556
1556
|
private_date: { type: "OTHER", category: "birthdays" },
|
|
1557
1557
|
private_url: { type: "OTHER", category: "private_urls" }
|
|
1558
1558
|
};
|
|
1559
|
-
function convertNativePrivacyRanges(
|
|
1559
|
+
function convertNativePrivacyRanges(text6, spans, disabled = /* @__PURE__ */ new Set()) {
|
|
1560
1560
|
const offsets = /* @__PURE__ */ new Map([[0, 0]]);
|
|
1561
1561
|
let bytes2 = 0;
|
|
1562
1562
|
let units = 0;
|
|
1563
|
-
for (const character of
|
|
1563
|
+
for (const character of text6) {
|
|
1564
1564
|
if (character.length === 1 && /[\uD800-\uDFFF]/.test(character)) throw privacyError("privacy_invalid_unicode");
|
|
1565
1565
|
bytes2 += Buffer.byteLength(character);
|
|
1566
1566
|
units += character.length;
|
|
1567
1567
|
offsets.set(bytes2, units);
|
|
1568
1568
|
}
|
|
1569
|
-
const protectedRanges = codingIdentifierRanges(
|
|
1569
|
+
const protectedRanges = codingIdentifierRanges(text6);
|
|
1570
1570
|
const result = [];
|
|
1571
1571
|
for (const span of spans) {
|
|
1572
1572
|
const label3 = LABELS[span.label];
|
|
1573
1573
|
const start = offsets.get(span.start), end = offsets.get(span.end);
|
|
1574
1574
|
if (!label3 || !Number.isInteger(span.start) || !Number.isInteger(span.end) || start === void 0 || end === void 0 || end <= start) throw privacyError("privacy_invalid_semantic_range");
|
|
1575
1575
|
if (disabled.has(label3.category) || span.label === "secret" && disabled.has("api_keys")) continue;
|
|
1576
|
-
const context =
|
|
1576
|
+
const context = text6.slice(Math.max(0, start - 60), Math.min(text6.length, end + 60));
|
|
1577
1577
|
const explicitSecret = /\b(?:password|secret|credential|api[_ -]?key|token)\b/i.test(context);
|
|
1578
|
-
if (protectedRanges.some((r) => start < r.end && end > r.start) && !(span.label === "secret" && explicitSecret && !
|
|
1578
|
+
if (protectedRanges.some((r) => start < r.end && end > r.start) && !(span.label === "secret" && explicitSecret && !text6.slice(start, end).startsWith("["))) continue;
|
|
1579
1579
|
if ((span.label === "private_date" || span.label === "account_number") && /\b(?:commit|sha|hash|build|release|branch|timestamp|version)\b/i.test(context) && !/\b(?:birth|birthday|born|dob|account|iban)\b/i.test(context)) continue;
|
|
1580
1580
|
result.push({ start, end, type: label3.type });
|
|
1581
1581
|
}
|
|
@@ -1591,30 +1591,30 @@ function privacyDetectionOptions(memories) {
|
|
|
1591
1591
|
})
|
|
1592
1592
|
} };
|
|
1593
1593
|
}
|
|
1594
|
-
async function scanEnhancedText(
|
|
1594
|
+
async function scanEnhancedText(text6, scope2, disabled = /* @__PURE__ */ new Set(), progress) {
|
|
1595
1595
|
const preferences = await readPrivacyPreferences();
|
|
1596
|
-
if (!
|
|
1596
|
+
if (!text6 || !enhancedScopeEnabled(preferences, scope2)) return [];
|
|
1597
1597
|
try {
|
|
1598
1598
|
await ensurePrivacyDaemon();
|
|
1599
1599
|
const ranges = [];
|
|
1600
|
-
for (let start = 0; start <
|
|
1601
|
-
let from = Math.max(0, start - 1024), end = Math.min(
|
|
1602
|
-
if (from > 0 && /[\uDC00-\uDFFF]/.test(
|
|
1603
|
-
if (end <
|
|
1604
|
-
progress?.(start,
|
|
1605
|
-
const window =
|
|
1600
|
+
for (let start = 0; start < text6.length; start += 8192) {
|
|
1601
|
+
let from = Math.max(0, start - 1024), end = Math.min(text6.length, start + 9216);
|
|
1602
|
+
if (from > 0 && /[\uDC00-\uDFFF]/.test(text6[from])) from--;
|
|
1603
|
+
if (end < text6.length && /[\uDC00-\uDFFF]/.test(text6[end])) end++;
|
|
1604
|
+
progress?.(start, text6.length);
|
|
1605
|
+
const window = text6.slice(from, end);
|
|
1606
1606
|
const result = await privacyRpc({ op: "scan", text: window, scope: privacyProfile(), idleSeconds: preferences.idleSeconds });
|
|
1607
1607
|
if (!Array.isArray(result.spans)) throw privacyError("privacy_worker_protocol_failed");
|
|
1608
1608
|
ranges.push(...convertNativePrivacyRanges(window, result.spans, disabled).map((r) => ({ ...r, start: r.start + from, end: r.end + from })));
|
|
1609
1609
|
}
|
|
1610
|
-
progress?.(
|
|
1610
|
+
progress?.(text6.length, text6.length);
|
|
1611
1611
|
return ranges;
|
|
1612
1612
|
} catch (error) {
|
|
1613
1613
|
await stopPrivacyDaemon();
|
|
1614
1614
|
throw error;
|
|
1615
1615
|
}
|
|
1616
1616
|
}
|
|
1617
|
-
async function prepareCliMessagePrivacy(
|
|
1617
|
+
async function prepareCliMessagePrivacy(text6, memories, existing = [], scope2 = { kind: "message" }, progress) {
|
|
1618
1618
|
const options = privacyDetectionOptions(memories);
|
|
1619
1619
|
let mappings = existing;
|
|
1620
1620
|
const privacy = new ProjectFilePrivacy({
|
|
@@ -1626,7 +1626,7 @@ async function prepareCliMessagePrivacy(text5, memories, existing = [], scope2 =
|
|
|
1626
1626
|
},
|
|
1627
1627
|
detectEnhanced: (value) => scanEnhancedText(value, scope2, options.detection.disabledCategories, progress)
|
|
1628
1628
|
});
|
|
1629
|
-
const message = await privacy.redactResult(
|
|
1629
|
+
const message = await privacy.redactResult(text6);
|
|
1630
1630
|
return { message, mappings: mappings.map((mapping) => ({ ...mapping, type: mapping.type ?? "OTHER" })) };
|
|
1631
1631
|
}
|
|
1632
1632
|
|
|
@@ -1646,9 +1646,9 @@ function buildMemoryRequestMessage(params) {
|
|
|
1646
1646
|
if (!params.requestId || !params.userMessageId) {
|
|
1647
1647
|
throw new Error("Memory requests require stable request and user-message identities");
|
|
1648
1648
|
}
|
|
1649
|
-
const
|
|
1649
|
+
const keys2 = Array.from(new Set(params.requestedKeys)).sort();
|
|
1650
1650
|
const categories = [];
|
|
1651
|
-
for (const key of
|
|
1651
|
+
for (const key of keys2) {
|
|
1652
1652
|
const separator = key.indexOf("-");
|
|
1653
1653
|
if (separator <= 0 || separator === key.length - 1) {
|
|
1654
1654
|
throw new Error(`Invalid memory category key: ${key}`);
|
|
@@ -1664,7 +1664,7 @@ function buildMemoryRequestMessage(params) {
|
|
|
1664
1664
|
type: REQUEST_TYPE,
|
|
1665
1665
|
user_message_id: params.userMessageId,
|
|
1666
1666
|
request_id: params.requestId,
|
|
1667
|
-
requested_keys:
|
|
1667
|
+
requested_keys: keys2,
|
|
1668
1668
|
categories,
|
|
1669
1669
|
count_semantics_version: COUNT_SEMANTICS_VERSION
|
|
1670
1670
|
};
|
|
@@ -1733,6 +1733,227 @@ function coalesceMemoryRequestMessages(messages) {
|
|
|
1733
1733
|
return result;
|
|
1734
1734
|
}
|
|
1735
1735
|
|
|
1736
|
+
// ../ui/src/utils/projectFilePatch.ts
|
|
1737
|
+
var ProjectFilePatchError = class extends Error {
|
|
1738
|
+
constructor(message) {
|
|
1739
|
+
super(message);
|
|
1740
|
+
this.name = "ProjectFilePatchError";
|
|
1741
|
+
}
|
|
1742
|
+
};
|
|
1743
|
+
var HEADER = /^(---|\+\+\+) ([^\t]+)(?:\t.*)?$/;
|
|
1744
|
+
var HUNK = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(?: .*)?$/;
|
|
1745
|
+
function applyProjectFilePatch(original, unifiedDiff, expectedPath) {
|
|
1746
|
+
if (!unifiedDiff || unifiedDiff.includes("\0") || unifiedDiff.includes("\r")) {
|
|
1747
|
+
throw new ProjectFilePatchError("Patch must be a non-empty LF unified diff");
|
|
1748
|
+
}
|
|
1749
|
+
const rows2 = unifiedDiff.split("\n");
|
|
1750
|
+
if (rows2.at(-1) === "") rows2.pop();
|
|
1751
|
+
if (rows2.length < 3) throw new ProjectFilePatchError("Patch is missing file headers or hunks");
|
|
1752
|
+
const oldHeader = HEADER.exec(rows2[0] ?? "");
|
|
1753
|
+
const newHeader = HEADER.exec(rows2[1] ?? "");
|
|
1754
|
+
if (!oldHeader || oldHeader[1] !== "---" || !newHeader || newHeader[1] !== "+++") {
|
|
1755
|
+
throw new ProjectFilePatchError("Patch must start with one old and one new file header");
|
|
1756
|
+
}
|
|
1757
|
+
const oldPath = normalizeHeaderPath(oldHeader[2] ?? "");
|
|
1758
|
+
const newPath = normalizeHeaderPath(newHeader[2] ?? "");
|
|
1759
|
+
if (oldPath === "/dev/null" || newPath === "/dev/null") {
|
|
1760
|
+
throw new ProjectFilePatchError("Update patches cannot create or delete files");
|
|
1761
|
+
}
|
|
1762
|
+
if (expectedPath && (oldPath !== expectedPath || newPath !== expectedPath)) {
|
|
1763
|
+
throw new ProjectFilePatchError("Patch file headers do not match the requested path");
|
|
1764
|
+
}
|
|
1765
|
+
const hunks = [];
|
|
1766
|
+
let row = 2;
|
|
1767
|
+
while (row < rows2.length) {
|
|
1768
|
+
const match = HUNK.exec(rows2[row] ?? "");
|
|
1769
|
+
if (!match) throw new ProjectFilePatchError("Patch contains data outside a valid hunk");
|
|
1770
|
+
const hunk = {
|
|
1771
|
+
oldStart: parseCoordinate(match[1]),
|
|
1772
|
+
oldCount: match[2] === void 0 ? 1 : parseCoordinate(match[2]),
|
|
1773
|
+
newStart: parseCoordinate(match[3]),
|
|
1774
|
+
newCount: match[4] === void 0 ? 1 : parseCoordinate(match[4]),
|
|
1775
|
+
lines: []
|
|
1776
|
+
};
|
|
1777
|
+
row += 1;
|
|
1778
|
+
let oldSeen = 0;
|
|
1779
|
+
let newSeen = 0;
|
|
1780
|
+
while (row < rows2.length && !rows2[row]?.startsWith("@@ ")) {
|
|
1781
|
+
const value = rows2[row] ?? "";
|
|
1782
|
+
if (value === "\") {
|
|
1783
|
+
const previous = hunk.lines.at(-1);
|
|
1784
|
+
if (!previous || !previous.line.hasNewline) {
|
|
1785
|
+
throw new ProjectFilePatchError("Misplaced no-newline marker");
|
|
1786
|
+
}
|
|
1787
|
+
previous.line.hasNewline = false;
|
|
1788
|
+
row += 1;
|
|
1789
|
+
continue;
|
|
1790
|
+
}
|
|
1791
|
+
const prefix = value[0];
|
|
1792
|
+
if (prefix !== " " && prefix !== "-" && prefix !== "+") {
|
|
1793
|
+
throw new ProjectFilePatchError("Every hunk line must have a unified-diff prefix");
|
|
1794
|
+
}
|
|
1795
|
+
const kind = prefix === " " ? "context" : prefix === "-" ? "remove" : "add";
|
|
1796
|
+
hunk.lines.push({ kind, line: { value: value.slice(1), hasNewline: true } });
|
|
1797
|
+
if (kind !== "add") oldSeen += 1;
|
|
1798
|
+
if (kind !== "remove") newSeen += 1;
|
|
1799
|
+
row += 1;
|
|
1800
|
+
}
|
|
1801
|
+
if (oldSeen !== hunk.oldCount || newSeen !== hunk.newCount) {
|
|
1802
|
+
throw new ProjectFilePatchError("Hunk line counts do not match its header");
|
|
1803
|
+
}
|
|
1804
|
+
hunks.push(hunk);
|
|
1805
|
+
}
|
|
1806
|
+
if (hunks.length === 0) throw new ProjectFilePatchError("Patch has no hunks");
|
|
1807
|
+
const source = splitContentLines(original);
|
|
1808
|
+
const output = [];
|
|
1809
|
+
let sourceIndex = 0;
|
|
1810
|
+
let outputLine = 1;
|
|
1811
|
+
for (const hunk of hunks) {
|
|
1812
|
+
const expectedSourceIndex = hunk.oldCount === 0 ? hunk.oldStart : hunk.oldStart - 1;
|
|
1813
|
+
const expectedOutputLine = hunk.newCount === 0 ? hunk.newStart + 1 : hunk.newStart;
|
|
1814
|
+
if (expectedSourceIndex < sourceIndex || expectedSourceIndex > source.length) {
|
|
1815
|
+
throw new ProjectFilePatchError("Patch hunks overlap or are outside the source");
|
|
1816
|
+
}
|
|
1817
|
+
while (sourceIndex < expectedSourceIndex) {
|
|
1818
|
+
output.push(source[sourceIndex]);
|
|
1819
|
+
sourceIndex += 1;
|
|
1820
|
+
outputLine += 1;
|
|
1821
|
+
}
|
|
1822
|
+
if (outputLine !== expectedOutputLine) {
|
|
1823
|
+
throw new ProjectFilePatchError("Patch new-file coordinates are inconsistent");
|
|
1824
|
+
}
|
|
1825
|
+
for (const item of hunk.lines) {
|
|
1826
|
+
if (item.kind !== "add") {
|
|
1827
|
+
const actual = source[sourceIndex];
|
|
1828
|
+
if (!actual || actual.value !== item.line.value || actual.hasNewline !== item.line.hasNewline) {
|
|
1829
|
+
throw new ProjectFilePatchError("Patch context does not match the source exactly");
|
|
1830
|
+
}
|
|
1831
|
+
sourceIndex += 1;
|
|
1832
|
+
}
|
|
1833
|
+
if (item.kind !== "remove") {
|
|
1834
|
+
output.push({ ...item.line });
|
|
1835
|
+
outputLine += 1;
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
output.push(...source.slice(sourceIndex));
|
|
1840
|
+
validateNewlinePlacement(output);
|
|
1841
|
+
return {
|
|
1842
|
+
content: output.map((line) => line.value + (line.hasNewline ? "\n" : "")).join(""),
|
|
1843
|
+
appliedDiff: unifiedDiff,
|
|
1844
|
+
oldPath,
|
|
1845
|
+
newPath
|
|
1846
|
+
};
|
|
1847
|
+
}
|
|
1848
|
+
function parseCoordinate(value) {
|
|
1849
|
+
const number = Number(value);
|
|
1850
|
+
if (!Number.isSafeInteger(number) || number < 0) throw new ProjectFilePatchError("Invalid hunk coordinate");
|
|
1851
|
+
return number;
|
|
1852
|
+
}
|
|
1853
|
+
function normalizeHeaderPath(value) {
|
|
1854
|
+
if (value === "/dev/null") return value;
|
|
1855
|
+
if (value.startsWith("a/") || value.startsWith("b/")) return value.slice(2);
|
|
1856
|
+
return value;
|
|
1857
|
+
}
|
|
1858
|
+
function splitContentLines(content) {
|
|
1859
|
+
if (content === "") return [];
|
|
1860
|
+
const lines = [];
|
|
1861
|
+
let start = 0;
|
|
1862
|
+
for (let index = 0; index < content.length; index += 1) {
|
|
1863
|
+
if (content[index] !== "\n") continue;
|
|
1864
|
+
lines.push({ value: content.slice(start, index), hasNewline: true });
|
|
1865
|
+
start = index + 1;
|
|
1866
|
+
}
|
|
1867
|
+
if (start < content.length) lines.push({ value: content.slice(start), hasNewline: false });
|
|
1868
|
+
return lines;
|
|
1869
|
+
}
|
|
1870
|
+
function validateNewlinePlacement(lines) {
|
|
1871
|
+
for (let index = 0; index < lines.length - 1; index += 1) {
|
|
1872
|
+
if (!lines[index]?.hasNewline) throw new ProjectFilePatchError("No-newline marker is only valid at end of file");
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
// ../ui/src/utils/embedVersionReconstruction.ts
|
|
1877
|
+
async function reconstructVersionRows(rows2, decrypt) {
|
|
1878
|
+
const sorted2 = [...rows2].sort((a, b) => a.version_number - b.version_number);
|
|
1879
|
+
let content = null;
|
|
1880
|
+
let expected = sorted2[0]?.version_number ?? 1;
|
|
1881
|
+
for (const row of sorted2) {
|
|
1882
|
+
if (!Number.isSafeInteger(row.version_number) || row.version_number < 1 || row.version_number !== expected) {
|
|
1883
|
+
throw new Error("Version chain is incomplete");
|
|
1884
|
+
}
|
|
1885
|
+
expected += 1;
|
|
1886
|
+
if (row.encrypted_snapshot) {
|
|
1887
|
+
content = await decrypt(row.encrypted_snapshot);
|
|
1888
|
+
if (content === null) throw new Error("Version snapshot could not be decrypted");
|
|
1889
|
+
} else {
|
|
1890
|
+
if (content === null) throw new Error("Version history is missing the initial snapshot");
|
|
1891
|
+
if (!row.encrypted_patch) throw new Error("Version patch is missing");
|
|
1892
|
+
const patch = await decrypt(row.encrypted_patch);
|
|
1893
|
+
if (patch === null) throw new Error("Version patch could not be decrypted");
|
|
1894
|
+
content = applyVersionPatch(content, patch);
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
if (content === null) throw new Error("Version history is missing the initial snapshot");
|
|
1898
|
+
return content;
|
|
1899
|
+
}
|
|
1900
|
+
function applyVersionPatch(content, patch) {
|
|
1901
|
+
if (patch.includes("\")) {
|
|
1902
|
+
const withHeaders = patch.startsWith("@@ ") ? `--- version
|
|
1903
|
+
+++ version
|
|
1904
|
+
${patch}` : patch;
|
|
1905
|
+
return applyProjectFilePatch(content, withHeaders).content;
|
|
1906
|
+
}
|
|
1907
|
+
const source = content === "" ? [] : content.split("\n");
|
|
1908
|
+
const lines = patch.split("\n");
|
|
1909
|
+
if (lines.at(-1) === "") lines.pop();
|
|
1910
|
+
let index = 0;
|
|
1911
|
+
if (lines[0]?.startsWith("--- ") && lines[1]?.startsWith("+++ ")) index = 2;
|
|
1912
|
+
const output = [];
|
|
1913
|
+
let sourceIndex = 0;
|
|
1914
|
+
let hunkCount = 0;
|
|
1915
|
+
while (index < lines.length) {
|
|
1916
|
+
const header2 = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(?: .*)?$/.exec(lines[index] ?? "");
|
|
1917
|
+
if (!header2) throw new Error("Version patch contains an invalid hunk");
|
|
1918
|
+
const oldStart = Number(header2[1]);
|
|
1919
|
+
const oldCount = header2[2] === void 0 ? 1 : Number(header2[2]);
|
|
1920
|
+
const newStart = Number(header2[3]);
|
|
1921
|
+
const newCount = header2[4] === void 0 ? 1 : Number(header2[4]);
|
|
1922
|
+
const start = oldCount === 0 ? oldStart : oldStart - 1;
|
|
1923
|
+
const outputStart = newCount === 0 ? newStart : newStart - 1;
|
|
1924
|
+
if (![oldStart, oldCount, newStart, newCount].every(Number.isSafeInteger) || start < sourceIndex || start > source.length) throw new Error("Version patch hunks overlap or exceed content");
|
|
1925
|
+
output.push(...source.slice(sourceIndex, start));
|
|
1926
|
+
if (output.length !== outputStart) throw new Error("Version patch coordinates do not match content");
|
|
1927
|
+
sourceIndex = start;
|
|
1928
|
+
let removed = 0;
|
|
1929
|
+
let added = 0;
|
|
1930
|
+
index += 1;
|
|
1931
|
+
while (index < lines.length && !lines[index]?.startsWith("@@ ")) {
|
|
1932
|
+
const line = lines[index] ?? "";
|
|
1933
|
+
if (line === "\") {
|
|
1934
|
+
index += 1;
|
|
1935
|
+
continue;
|
|
1936
|
+
}
|
|
1937
|
+
if (![" ", "-", "+"].includes(line[0] ?? "")) throw new Error("Version patch has an invalid line");
|
|
1938
|
+
if (line[0] !== "+") {
|
|
1939
|
+
if (source[sourceIndex] !== line.slice(1)) throw new Error("Version patch context does not match local content");
|
|
1940
|
+
sourceIndex += 1;
|
|
1941
|
+
removed += 1;
|
|
1942
|
+
}
|
|
1943
|
+
if (line[0] !== "-") {
|
|
1944
|
+
output.push(line.slice(1));
|
|
1945
|
+
added += 1;
|
|
1946
|
+
}
|
|
1947
|
+
index += 1;
|
|
1948
|
+
}
|
|
1949
|
+
if (removed !== oldCount || added !== newCount) throw new Error("Version patch line counts do not match its header");
|
|
1950
|
+
hunkCount += 1;
|
|
1951
|
+
}
|
|
1952
|
+
if (hunkCount === 0) throw new Error("Version patch has no hunks");
|
|
1953
|
+
output.push(...source.slice(sourceIndex));
|
|
1954
|
+
return output.join("\n");
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1736
1957
|
// src/accountImport.ts
|
|
1737
1958
|
import { createDecipheriv, createHash as createHash4, scryptSync } from "crypto";
|
|
1738
1959
|
import JSZip from "jszip";
|
|
@@ -2025,7 +2246,7 @@ async function parseOpenCodeImportBuffer(payload, sourceName = "opencode-session
|
|
|
2025
2246
|
if (role !== "user" && role !== "assistant") continue;
|
|
2026
2247
|
const parts = Array.isArray(message.parts) ? message.parts.filter((part) => Boolean(part && typeof part === "object")) : [];
|
|
2027
2248
|
const textParts = parts.filter((part) => part.type === "text" && part.ignored !== true && typeof part.text === "string");
|
|
2028
|
-
const content = textParts.map((part) => String(part.text)).filter((
|
|
2249
|
+
const content = textParts.map((part) => String(part.text)).filter((text6) => text6.trim()).join("\n");
|
|
2029
2250
|
if (content.trim()) {
|
|
2030
2251
|
const time2 = messageInfo.time && typeof messageInfo.time === "object" ? messageInfo.time : {};
|
|
2031
2252
|
messages.push({
|
|
@@ -2863,146 +3084,6 @@ function createProjectFileJobExecutor(options) {
|
|
|
2863
3084
|
} };
|
|
2864
3085
|
}
|
|
2865
3086
|
|
|
2866
|
-
// ../ui/src/utils/projectFilePatch.ts
|
|
2867
|
-
var ProjectFilePatchError = class extends Error {
|
|
2868
|
-
constructor(message) {
|
|
2869
|
-
super(message);
|
|
2870
|
-
this.name = "ProjectFilePatchError";
|
|
2871
|
-
}
|
|
2872
|
-
};
|
|
2873
|
-
var HEADER = /^(---|\+\+\+) ([^\t]+)(?:\t.*)?$/;
|
|
2874
|
-
var HUNK = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(?: .*)?$/;
|
|
2875
|
-
function applyProjectFilePatch(original, unifiedDiff, expectedPath) {
|
|
2876
|
-
if (!unifiedDiff || unifiedDiff.includes("\0") || unifiedDiff.includes("\r")) {
|
|
2877
|
-
throw new ProjectFilePatchError("Patch must be a non-empty LF unified diff");
|
|
2878
|
-
}
|
|
2879
|
-
const rows2 = unifiedDiff.split("\n");
|
|
2880
|
-
if (rows2.at(-1) === "") rows2.pop();
|
|
2881
|
-
if (rows2.length < 3) throw new ProjectFilePatchError("Patch is missing file headers or hunks");
|
|
2882
|
-
const oldHeader = HEADER.exec(rows2[0] ?? "");
|
|
2883
|
-
const newHeader = HEADER.exec(rows2[1] ?? "");
|
|
2884
|
-
if (!oldHeader || oldHeader[1] !== "---" || !newHeader || newHeader[1] !== "+++") {
|
|
2885
|
-
throw new ProjectFilePatchError("Patch must start with one old and one new file header");
|
|
2886
|
-
}
|
|
2887
|
-
const oldPath = normalizeHeaderPath(oldHeader[2] ?? "");
|
|
2888
|
-
const newPath = normalizeHeaderPath(newHeader[2] ?? "");
|
|
2889
|
-
if (oldPath === "/dev/null" || newPath === "/dev/null") {
|
|
2890
|
-
throw new ProjectFilePatchError("Update patches cannot create or delete files");
|
|
2891
|
-
}
|
|
2892
|
-
if (expectedPath && (oldPath !== expectedPath || newPath !== expectedPath)) {
|
|
2893
|
-
throw new ProjectFilePatchError("Patch file headers do not match the requested path");
|
|
2894
|
-
}
|
|
2895
|
-
const hunks = [];
|
|
2896
|
-
let row = 2;
|
|
2897
|
-
while (row < rows2.length) {
|
|
2898
|
-
const match = HUNK.exec(rows2[row] ?? "");
|
|
2899
|
-
if (!match) throw new ProjectFilePatchError("Patch contains data outside a valid hunk");
|
|
2900
|
-
const hunk = {
|
|
2901
|
-
oldStart: parseCoordinate(match[1]),
|
|
2902
|
-
oldCount: match[2] === void 0 ? 1 : parseCoordinate(match[2]),
|
|
2903
|
-
newStart: parseCoordinate(match[3]),
|
|
2904
|
-
newCount: match[4] === void 0 ? 1 : parseCoordinate(match[4]),
|
|
2905
|
-
lines: []
|
|
2906
|
-
};
|
|
2907
|
-
row += 1;
|
|
2908
|
-
let oldSeen = 0;
|
|
2909
|
-
let newSeen = 0;
|
|
2910
|
-
while (row < rows2.length && !rows2[row]?.startsWith("@@ ")) {
|
|
2911
|
-
const value = rows2[row] ?? "";
|
|
2912
|
-
if (value === "\") {
|
|
2913
|
-
const previous = hunk.lines.at(-1);
|
|
2914
|
-
if (!previous || !previous.line.hasNewline) {
|
|
2915
|
-
throw new ProjectFilePatchError("Misplaced no-newline marker");
|
|
2916
|
-
}
|
|
2917
|
-
previous.line.hasNewline = false;
|
|
2918
|
-
row += 1;
|
|
2919
|
-
continue;
|
|
2920
|
-
}
|
|
2921
|
-
const prefix = value[0];
|
|
2922
|
-
if (prefix !== " " && prefix !== "-" && prefix !== "+") {
|
|
2923
|
-
throw new ProjectFilePatchError("Every hunk line must have a unified-diff prefix");
|
|
2924
|
-
}
|
|
2925
|
-
const kind = prefix === " " ? "context" : prefix === "-" ? "remove" : "add";
|
|
2926
|
-
hunk.lines.push({ kind, line: { value: value.slice(1), hasNewline: true } });
|
|
2927
|
-
if (kind !== "add") oldSeen += 1;
|
|
2928
|
-
if (kind !== "remove") newSeen += 1;
|
|
2929
|
-
row += 1;
|
|
2930
|
-
}
|
|
2931
|
-
if (oldSeen !== hunk.oldCount || newSeen !== hunk.newCount) {
|
|
2932
|
-
throw new ProjectFilePatchError("Hunk line counts do not match its header");
|
|
2933
|
-
}
|
|
2934
|
-
hunks.push(hunk);
|
|
2935
|
-
}
|
|
2936
|
-
if (hunks.length === 0) throw new ProjectFilePatchError("Patch has no hunks");
|
|
2937
|
-
const source = splitContentLines(original);
|
|
2938
|
-
const output = [];
|
|
2939
|
-
let sourceIndex = 0;
|
|
2940
|
-
let outputLine = 1;
|
|
2941
|
-
for (const hunk of hunks) {
|
|
2942
|
-
const expectedSourceIndex = hunk.oldCount === 0 ? hunk.oldStart : hunk.oldStart - 1;
|
|
2943
|
-
const expectedOutputLine = hunk.newCount === 0 ? hunk.newStart + 1 : hunk.newStart;
|
|
2944
|
-
if (expectedSourceIndex < sourceIndex || expectedSourceIndex > source.length) {
|
|
2945
|
-
throw new ProjectFilePatchError("Patch hunks overlap or are outside the source");
|
|
2946
|
-
}
|
|
2947
|
-
while (sourceIndex < expectedSourceIndex) {
|
|
2948
|
-
output.push(source[sourceIndex]);
|
|
2949
|
-
sourceIndex += 1;
|
|
2950
|
-
outputLine += 1;
|
|
2951
|
-
}
|
|
2952
|
-
if (outputLine !== expectedOutputLine) {
|
|
2953
|
-
throw new ProjectFilePatchError("Patch new-file coordinates are inconsistent");
|
|
2954
|
-
}
|
|
2955
|
-
for (const item of hunk.lines) {
|
|
2956
|
-
if (item.kind !== "add") {
|
|
2957
|
-
const actual = source[sourceIndex];
|
|
2958
|
-
if (!actual || actual.value !== item.line.value || actual.hasNewline !== item.line.hasNewline) {
|
|
2959
|
-
throw new ProjectFilePatchError("Patch context does not match the source exactly");
|
|
2960
|
-
}
|
|
2961
|
-
sourceIndex += 1;
|
|
2962
|
-
}
|
|
2963
|
-
if (item.kind !== "remove") {
|
|
2964
|
-
output.push({ ...item.line });
|
|
2965
|
-
outputLine += 1;
|
|
2966
|
-
}
|
|
2967
|
-
}
|
|
2968
|
-
}
|
|
2969
|
-
output.push(...source.slice(sourceIndex));
|
|
2970
|
-
validateNewlinePlacement(output);
|
|
2971
|
-
return {
|
|
2972
|
-
content: output.map((line) => line.value + (line.hasNewline ? "\n" : "")).join(""),
|
|
2973
|
-
appliedDiff: unifiedDiff,
|
|
2974
|
-
oldPath,
|
|
2975
|
-
newPath
|
|
2976
|
-
};
|
|
2977
|
-
}
|
|
2978
|
-
function parseCoordinate(value) {
|
|
2979
|
-
const number = Number(value);
|
|
2980
|
-
if (!Number.isSafeInteger(number) || number < 0) throw new ProjectFilePatchError("Invalid hunk coordinate");
|
|
2981
|
-
return number;
|
|
2982
|
-
}
|
|
2983
|
-
function normalizeHeaderPath(value) {
|
|
2984
|
-
if (value === "/dev/null") return value;
|
|
2985
|
-
if (value.startsWith("a/") || value.startsWith("b/")) return value.slice(2);
|
|
2986
|
-
return value;
|
|
2987
|
-
}
|
|
2988
|
-
function splitContentLines(content) {
|
|
2989
|
-
if (content === "") return [];
|
|
2990
|
-
const lines = [];
|
|
2991
|
-
let start = 0;
|
|
2992
|
-
for (let index = 0; index < content.length; index += 1) {
|
|
2993
|
-
if (content[index] !== "\n") continue;
|
|
2994
|
-
lines.push({ value: content.slice(start, index), hasNewline: true });
|
|
2995
|
-
start = index + 1;
|
|
2996
|
-
}
|
|
2997
|
-
if (start < content.length) lines.push({ value: content.slice(start), hasNewline: false });
|
|
2998
|
-
return lines;
|
|
2999
|
-
}
|
|
3000
|
-
function validateNewlinePlacement(lines) {
|
|
3001
|
-
for (let index = 0; index < lines.length - 1; index += 1) {
|
|
3002
|
-
if (!lines[index]?.hasNewline) throw new ProjectFilePatchError("No-newline marker is only valid at end of file");
|
|
3003
|
-
}
|
|
3004
|
-
}
|
|
3005
|
-
|
|
3006
3087
|
// ../ui/src/utils/projectSearchProtocol.ts
|
|
3007
3088
|
var ProjectSearchProtocolError = class extends Error {
|
|
3008
3089
|
code;
|
|
@@ -3102,7 +3183,7 @@ function matchesProjectSearchQuery(value, request) {
|
|
|
3102
3183
|
function matchesProjectSearchGlob(path2, glob) {
|
|
3103
3184
|
if (!glob) return true;
|
|
3104
3185
|
const memo = /* @__PURE__ */ new Map();
|
|
3105
|
-
const
|
|
3186
|
+
const visit2 = (pathIndex, globIndex) => {
|
|
3106
3187
|
const key = `${pathIndex}:${globIndex}`;
|
|
3107
3188
|
const cached = memo.get(key);
|
|
3108
3189
|
if (cached !== void 0) return cached;
|
|
@@ -3110,23 +3191,23 @@ function matchesProjectSearchGlob(path2, glob) {
|
|
|
3110
3191
|
if (globIndex === glob.length) {
|
|
3111
3192
|
matched = pathIndex === path2.length;
|
|
3112
3193
|
} else if (glob.startsWith("**/", globIndex)) {
|
|
3113
|
-
matched =
|
|
3194
|
+
matched = visit2(pathIndex, globIndex + 3);
|
|
3114
3195
|
for (let index = pathIndex; !matched && index < path2.length; index += 1) {
|
|
3115
|
-
if (path2[index] === "/") matched =
|
|
3196
|
+
if (path2[index] === "/") matched = visit2(index + 1, globIndex + 3);
|
|
3116
3197
|
}
|
|
3117
3198
|
} else if (glob.startsWith("**", globIndex)) {
|
|
3118
|
-
matched =
|
|
3199
|
+
matched = visit2(pathIndex, globIndex + 2) || pathIndex < path2.length && visit2(pathIndex + 1, globIndex);
|
|
3119
3200
|
} else if (glob[globIndex] === "*") {
|
|
3120
|
-
matched =
|
|
3201
|
+
matched = visit2(pathIndex, globIndex + 1) || pathIndex < path2.length && path2[pathIndex] !== "/" && visit2(pathIndex + 1, globIndex);
|
|
3121
3202
|
} else if (glob[globIndex] === "?") {
|
|
3122
|
-
matched = pathIndex < path2.length && path2[pathIndex] !== "/" &&
|
|
3203
|
+
matched = pathIndex < path2.length && path2[pathIndex] !== "/" && visit2(pathIndex + 1, globIndex + 1);
|
|
3123
3204
|
} else {
|
|
3124
|
-
matched = pathIndex < path2.length && path2[pathIndex] === glob[globIndex] &&
|
|
3205
|
+
matched = pathIndex < path2.length && path2[pathIndex] === glob[globIndex] && visit2(pathIndex + 1, globIndex + 1);
|
|
3125
3206
|
}
|
|
3126
3207
|
memo.set(key, matched);
|
|
3127
3208
|
return matched;
|
|
3128
3209
|
};
|
|
3129
|
-
return
|
|
3210
|
+
return visit2(0, 0);
|
|
3130
3211
|
}
|
|
3131
3212
|
function isProtectedProjectReadPath(value) {
|
|
3132
3213
|
const normalized = value.replace(/\\/g, "/").replace(/^\.\//, "").toLowerCase();
|
|
@@ -3832,8 +3913,8 @@ async function activateCliProjectFocus(client2, projectId, chatId, teamId, activ
|
|
|
3832
3913
|
const key = await client2.decryptProjectKey(detail.project, context);
|
|
3833
3914
|
if (!settings.encrypted_settings || settings.selection_required) throw new Error("Choose this Project's write policy in Project settings before starting work.");
|
|
3834
3915
|
if (isCurrent && !isCurrent()) return;
|
|
3835
|
-
const
|
|
3836
|
-
const focus =
|
|
3916
|
+
const text6 = await decryptWithAesGcmCombined(settings.encrypted_settings, key);
|
|
3917
|
+
const focus = text6 ? JSON.parse(text6).default_focus : void 0;
|
|
3837
3918
|
if (!focus?.focus_id || typeof focus.instructions !== "string") throw new Error("The Project's default focus is unavailable.");
|
|
3838
3919
|
if (isCurrent && !isCurrent()) return;
|
|
3839
3920
|
await client2.activateProjectFocus(projectId, {
|
|
@@ -3898,7 +3979,7 @@ function registerCliProjectFileExecutor(options) {
|
|
|
3898
3979
|
key: options.chatKey,
|
|
3899
3980
|
mappings: [...history.messages.flatMap((message) => message.piiMappings ?? []), ...options.piiMappings ?? []],
|
|
3900
3981
|
...detection,
|
|
3901
|
-
detectEnhanced: (
|
|
3982
|
+
detectEnhanced: (text6) => scanEnhancedText(text6, { kind: "project", projectId: job.project_id }, detection.detection.disabledCategories),
|
|
3902
3983
|
read: async () => {
|
|
3903
3984
|
try {
|
|
3904
3985
|
return await readFile(path2, "utf8");
|
|
@@ -4351,13 +4432,13 @@ var RemoteCommandOutputAccumulator = class {
|
|
|
4351
4432
|
return { text: this.#text, coverage: "full", sequence_gap: false, upstream_truncated: false, omitted_chars: 0 };
|
|
4352
4433
|
}
|
|
4353
4434
|
const half = Math.max(0, Math.floor((MAX_COMPLETION_CHARS - OMISSION_MARKER.length) / 2));
|
|
4354
|
-
const
|
|
4435
|
+
const text6 = this.#text.length <= MAX_COMPLETION_CHARS ? this.#text : `${this.#text.slice(0, half)}${OMISSION_MARKER}${this.#text.slice(-half)}`;
|
|
4355
4436
|
return {
|
|
4356
|
-
text:
|
|
4437
|
+
text: text6,
|
|
4357
4438
|
coverage: "selected_excerpt",
|
|
4358
4439
|
sequence_gap: this.#sequenceGap,
|
|
4359
4440
|
upstream_truncated: true,
|
|
4360
|
-
omitted_chars: Math.max(0, this.#inputChars -
|
|
4441
|
+
omitted_chars: Math.max(0, this.#inputChars - text6.length + (text6.includes(OMISSION_MARKER) ? OMISSION_MARKER.length : 0))
|
|
4361
4442
|
};
|
|
4362
4443
|
}
|
|
4363
4444
|
};
|
|
@@ -4884,6 +4965,7 @@ var OpenMatesWsClient = class {
|
|
|
4884
4965
|
const clientCapabilities = [
|
|
4885
4966
|
"canonical_embed_receipts_v1",
|
|
4886
4967
|
"typed_recovery_outputs_v2",
|
|
4968
|
+
"agentic-storage-v2",
|
|
4887
4969
|
...options.taskUpdateJobs !== false ? ["task_update_jobs"] : [],
|
|
4888
4970
|
...options.projectFileJobs === true ? ["project_file_jobs"] : [],
|
|
4889
4971
|
...options.remoteCommandJobs === true ? ["remote_command_jobs"] : []
|
|
@@ -5372,8 +5454,8 @@ var OpenMatesWsClient = class {
|
|
|
5372
5454
|
if (!content || typeof content !== "object") return "";
|
|
5373
5455
|
try {
|
|
5374
5456
|
const root = content;
|
|
5375
|
-
const
|
|
5376
|
-
return typeof
|
|
5457
|
+
const text6 = root.content?.[0]?.content?.[0]?.text;
|
|
5458
|
+
return typeof text6 === "string" ? text6 : "";
|
|
5377
5459
|
} catch {
|
|
5378
5460
|
return "";
|
|
5379
5461
|
}
|
|
@@ -6025,21 +6107,98 @@ function registerChatContextEvents(options) {
|
|
|
6025
6107
|
}
|
|
6026
6108
|
|
|
6027
6109
|
// src/cliJevContext.ts
|
|
6028
|
-
import {
|
|
6110
|
+
import { parseDocument as parseDocument2, isAlias, visit } from "yaml";
|
|
6111
|
+
|
|
6112
|
+
// ../projectFocusDocument.ts
|
|
6113
|
+
function invalid() {
|
|
6114
|
+
throw new Error("invalid_focus_document");
|
|
6115
|
+
}
|
|
6116
|
+
function object(value) {
|
|
6117
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return invalid();
|
|
6118
|
+
return value;
|
|
6119
|
+
}
|
|
6120
|
+
function keys(value, allowed) {
|
|
6121
|
+
if (Object.keys(value).some((key) => !allowed.includes(key))) invalid();
|
|
6122
|
+
}
|
|
6123
|
+
function text4(value, limit) {
|
|
6124
|
+
if (typeof value !== "string" || !value.trim() || value.length > limit) return invalid();
|
|
6125
|
+
return value;
|
|
6126
|
+
}
|
|
6127
|
+
function identifier3(value, canonical) {
|
|
6128
|
+
const result = text4(value, canonical ? 64 : 80);
|
|
6129
|
+
if (!(canonical ? /^[a-z][a-z0-9_-]{0,63}$/ : /^[a-zA-Z0-9_-]{1,80}$/).test(result)) invalid();
|
|
6130
|
+
return result;
|
|
6131
|
+
}
|
|
6132
|
+
function unique(ids) {
|
|
6133
|
+
if (new Set(ids).size !== ids.length) invalid();
|
|
6134
|
+
}
|
|
6135
|
+
function projectFocusDocumentFromMetadata(metadata, body) {
|
|
6136
|
+
const header2 = object(metadata);
|
|
6137
|
+
keys(header2, ["name", "title", "description", "when_to_use", "preprocessor_hint", "preprocessor-hint", "phases_version", "phases"]);
|
|
6138
|
+
const names = [header2.name, header2.title].filter((value) => value !== void 0);
|
|
6139
|
+
const hints = [header2.when_to_use, header2.preprocessor_hint, header2["preprocessor-hint"]].filter((value) => value !== void 0);
|
|
6140
|
+
if (names.length !== 1 || hints.length !== 1) invalid();
|
|
6141
|
+
const common = {
|
|
6142
|
+
name: text4(names[0], 200),
|
|
6143
|
+
description: text4(header2.description, 2e3),
|
|
6144
|
+
when_to_use: text4(hints[0], 2e3),
|
|
6145
|
+
instructions: text4(body.trim(), 64e3)
|
|
6146
|
+
};
|
|
6147
|
+
const phases = header2.phases === void 0 ? [] : header2.phases;
|
|
6148
|
+
if (!Array.isArray(phases) || phases.length > 16) invalid();
|
|
6149
|
+
if (Object.prototype.hasOwnProperty.call(header2, "phases_version")) {
|
|
6150
|
+
if (header2.phases_version !== 1 || !phases.length) invalid();
|
|
6151
|
+
const canonical = phases.map((raw) => {
|
|
6152
|
+
const phase = object(raw);
|
|
6153
|
+
keys(phase, ["id", "title", "instructions", "requirements"]);
|
|
6154
|
+
const requirements = phase.requirements;
|
|
6155
|
+
if (!Array.isArray(requirements) || !requirements.length || requirements.length > 24) invalid();
|
|
6156
|
+
const gates = requirements.map((rawRequirement) => {
|
|
6157
|
+
const requirement = object(rawRequirement);
|
|
6158
|
+
keys(requirement, ["id", "text", "type"]);
|
|
6159
|
+
if (requirement.type !== void 0 && (typeof requirement.type !== "string" || !["semantic", "user_confirmation"].includes(requirement.type))) invalid();
|
|
6160
|
+
return {
|
|
6161
|
+
id: identifier3(requirement.id, true),
|
|
6162
|
+
text: text4(requirement.text, 4e3),
|
|
6163
|
+
...requirement.type === void 0 ? {} : { type: requirement.type }
|
|
6164
|
+
};
|
|
6165
|
+
});
|
|
6166
|
+
unique(gates.map((gate) => gate.id));
|
|
6167
|
+
return {
|
|
6168
|
+
id: identifier3(phase.id, true),
|
|
6169
|
+
title: text4(phase.title, 200),
|
|
6170
|
+
instructions: text4(phase.instructions, 16e3),
|
|
6171
|
+
requirements: gates
|
|
6172
|
+
};
|
|
6173
|
+
});
|
|
6174
|
+
unique(canonical.map((phase) => phase.id));
|
|
6175
|
+
return { ...common, phases_version: 1, phases: canonical };
|
|
6176
|
+
}
|
|
6177
|
+
const legacy = phases.map((raw) => {
|
|
6178
|
+
const phase = object(raw);
|
|
6179
|
+
keys(phase, ["id", "name", "instructions"]);
|
|
6180
|
+
return { id: identifier3(phase.id, false), name: text4(phase.name, 120), instructions: text4(phase.instructions, 16e3) };
|
|
6181
|
+
});
|
|
6182
|
+
unique(legacy.map((phase) => phase.id));
|
|
6183
|
+
return { ...common, phases: legacy };
|
|
6184
|
+
}
|
|
6185
|
+
|
|
6186
|
+
// src/cliJevContext.ts
|
|
6029
6187
|
import { createHash as createHash8 } from "crypto";
|
|
6030
6188
|
function parseFocusAuthoringDocument(document) {
|
|
6031
|
-
if (document.length > 96e3) throw new Error("
|
|
6032
|
-
const match = /^---\r?\n([\s\S]*?)\r?\n
|
|
6033
|
-
if (!match) throw new Error("
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
return {
|
|
6041
|
-
}
|
|
6042
|
-
|
|
6189
|
+
if (document.length > 96e3) throw new Error("invalid_focus_document");
|
|
6190
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)([\s\S]*)$/.exec(document);
|
|
6191
|
+
if (!match) throw new Error("invalid_focus_document");
|
|
6192
|
+
try {
|
|
6193
|
+
const parsed = parseDocument2(match[1], { schema: "core", uniqueKeys: true });
|
|
6194
|
+
if (parsed.errors.length) throw new Error("invalid_focus_document");
|
|
6195
|
+
visit(parsed, (_key, node) => {
|
|
6196
|
+
if (isAlias(node)) throw new Error("invalid_focus_document");
|
|
6197
|
+
});
|
|
6198
|
+
return projectFocusDocumentFromMetadata(parsed.toJS({ maxAliasCount: 0 }), match[2]);
|
|
6199
|
+
} catch {
|
|
6200
|
+
throw new Error("invalid_focus_document");
|
|
6201
|
+
}
|
|
6043
6202
|
}
|
|
6044
6203
|
async function discoverCliProjectCandidates(client2, options) {
|
|
6045
6204
|
const records = (await client2.listProjects(options)).filter((record8) => !record8.archived).slice(0, 40);
|
|
@@ -6057,7 +6216,7 @@ async function discoverCliProjectCandidates(client2, options) {
|
|
|
6057
6216
|
}));
|
|
6058
6217
|
return entries.filter((entry) => entry !== null);
|
|
6059
6218
|
}
|
|
6060
|
-
async function loadActiveCliProjectContext(client2, chatId,
|
|
6219
|
+
async function loadActiveCliProjectContext(client2, chatId, text6) {
|
|
6061
6220
|
const active = await client2.getActiveProjectFocus(chatId);
|
|
6062
6221
|
if (!active) return {};
|
|
6063
6222
|
const options = { teamId: active.team_id, personal: !active.team_id };
|
|
@@ -6113,9 +6272,9 @@ async function loadActiveCliProjectContext(client2, chatId, text5) {
|
|
|
6113
6272
|
if (title && description) candidates.push({ kind: "folder", id: folder.folder_id, title: title.slice(0, 200), description: description.slice(0, 640), when_to_use: "", revision: revision(folder) });
|
|
6114
6273
|
}
|
|
6115
6274
|
let selected = [];
|
|
6116
|
-
if (
|
|
6275
|
+
if (text6?.trim() && candidates.length) selected = await client2.selectProjectContext(
|
|
6117
6276
|
active.project_id,
|
|
6118
|
-
{ chat_id: chatId, text:
|
|
6277
|
+
{ chat_id: chatId, text: text6.slice(0, 8e3), candidates: candidates.slice(0, 24) },
|
|
6119
6278
|
options
|
|
6120
6279
|
);
|
|
6121
6280
|
const specialistId = active.specialist_focus_id?.startsWith(`project-focus:${active.project_id}:`) ? active.specialist_focus_id.split(":")[2] : active.specialist_focus_id;
|
|
@@ -6260,7 +6419,7 @@ async function collectRelatedCliTaskContext(client2, chatId, options, records, n
|
|
|
6260
6419
|
}
|
|
6261
6420
|
return candidates;
|
|
6262
6421
|
}
|
|
6263
|
-
async function prepareCliJevContext(client2, chatId, options, supplied = {},
|
|
6422
|
+
async function prepareCliJevContext(client2, chatId, options, supplied = {}, text6) {
|
|
6264
6423
|
let candidates = [];
|
|
6265
6424
|
let active = {};
|
|
6266
6425
|
let tasks = [];
|
|
@@ -6271,7 +6430,7 @@ async function prepareCliJevContext(client2, chatId, options, supplied = {}, tex
|
|
|
6271
6430
|
candidates = value;
|
|
6272
6431
|
}).catch(() => {
|
|
6273
6432
|
}),
|
|
6274
|
-
loadActiveCliProjectContext(client2, chatId,
|
|
6433
|
+
loadActiveCliProjectContext(client2, chatId, text6).then((value) => {
|
|
6275
6434
|
active = value;
|
|
6276
6435
|
}).catch(() => {
|
|
6277
6436
|
}),
|
|
@@ -6476,8 +6635,8 @@ async function startCliProjectAuthoring(client2, recommendation, history) {
|
|
|
6476
6635
|
const key = await client2.decryptProjectKey(detail.project, options);
|
|
6477
6636
|
for (const item of detail.items.filter((item2) => item2.item_type === "workflow" && !item2.deleted_target_state)) {
|
|
6478
6637
|
if (await decryptWithAesGcmCombined(item.target_id_encrypted, key) !== recommendation.target_id) continue;
|
|
6479
|
-
const
|
|
6480
|
-
const metadata =
|
|
6638
|
+
const text6 = item.encrypted_metadata ? await decryptWithAesGcmCombined(item.encrypted_metadata, key) : null;
|
|
6639
|
+
const metadata = text6 ? JSON.parse(text6) : {};
|
|
6481
6640
|
if (metadata.remote_workflow_file && typeof metadata.remote_workflow_file === "object") remoteBinding = metadata.remote_workflow_file;
|
|
6482
6641
|
break;
|
|
6483
6642
|
}
|
|
@@ -7151,8 +7310,8 @@ function parseDelimitedLine(line, delimiter) {
|
|
|
7151
7310
|
cells2.push(current);
|
|
7152
7311
|
return cells2;
|
|
7153
7312
|
}
|
|
7154
|
-
function delimitedTextToMarkdownTable(
|
|
7155
|
-
const rows2 =
|
|
7313
|
+
function delimitedTextToMarkdownTable(text6, delimiter) {
|
|
7314
|
+
const rows2 = text6.split(/\r?\n/).map((line) => line.trimEnd()).filter((line) => line.length > 0).map((line) => parseDelimitedLine(line, delimiter));
|
|
7156
7315
|
if (rows2.length === 0) return "";
|
|
7157
7316
|
const maxCols = Math.max(...rows2.map((row) => row.length));
|
|
7158
7317
|
const normalized = rows2.map((row) => {
|
|
@@ -7199,7 +7358,7 @@ async function docxBufferToHtml(buffer) {
|
|
|
7199
7358
|
const zip = await JSZip2.loadAsync(buffer);
|
|
7200
7359
|
const documentXml = await zip.file("word/document.xml")?.async("string");
|
|
7201
7360
|
if (!documentXml) return "";
|
|
7202
|
-
const paragraphs = getXmlBlocks(documentXml, "p").map(getTextFromDocxParagraph).map((
|
|
7361
|
+
const paragraphs = getXmlBlocks(documentXml, "p").map(getTextFromDocxParagraph).map((text6) => text6.trim()).filter(Boolean);
|
|
7203
7362
|
return paragraphs.map((paragraph) => `<p>${escapeHtml(paragraph)}</p>`).join("\n");
|
|
7204
7363
|
}
|
|
7205
7364
|
function columnLettersToIndex(letters) {
|
|
@@ -8038,8 +8197,8 @@ function splitLongParagraph(paragraph) {
|
|
|
8038
8197
|
if (remainder) chunks.push(remainder);
|
|
8039
8198
|
return chunks;
|
|
8040
8199
|
}
|
|
8041
|
-
function fallback(
|
|
8042
|
-
if (!language.toLowerCase().startsWith("de")) return
|
|
8200
|
+
function fallback(text6, language) {
|
|
8201
|
+
if (!language.toLowerCase().startsWith("de")) return text6;
|
|
8043
8202
|
const german = {
|
|
8044
8203
|
"Search results are available.": "Suchergebnisse sind verf\xFCgbar.",
|
|
8045
8204
|
"I used the News Search skill.": "Ich habe die News-Suche verwendet.",
|
|
@@ -8048,7 +8207,7 @@ function fallback(text5, language) {
|
|
|
8048
8207
|
"A code example is available.": "Ein Codebeispiel ist verf\xFCgbar.",
|
|
8049
8208
|
"A table is available.": "Eine Tabelle ist verf\xFCgbar."
|
|
8050
8209
|
};
|
|
8051
|
-
return german[
|
|
8210
|
+
return german[text6] ?? text6;
|
|
8052
8211
|
}
|
|
8053
8212
|
function projectFence(markdown, language) {
|
|
8054
8213
|
const body = markdown.replace(/^```[^\n]*\n|\n?```$/g, "").trim();
|
|
@@ -8130,8 +8289,8 @@ function rejectProtonCredentialFlags(argsOrFlags) {
|
|
|
8130
8289
|
throw new Error(`${rejected.split("=")[0]} is not allowed. Bridge credentials must be read privately from Proton Bridge or a hidden prompt.`);
|
|
8131
8290
|
}
|
|
8132
8291
|
}
|
|
8133
|
-
function redactProtonBridgeSecrets(
|
|
8134
|
-
return
|
|
8292
|
+
function redactProtonBridgeSecrets(text6) {
|
|
8293
|
+
return text6.replace(CREDENTIAL_VALUE_RE, "$1<redacted>");
|
|
8135
8294
|
}
|
|
8136
8295
|
function containsCredentialLikeField(value) {
|
|
8137
8296
|
return containsCredentialLikeKey(value);
|
|
@@ -8528,7 +8687,7 @@ async function searchProtonBridgeImap(credentials, arguments_) {
|
|
|
8528
8687
|
const limit = clampLimit(arguments_.limit);
|
|
8529
8688
|
const imap = await openTextSocket(credentials.imapHost, credentials.imapPort, IMAP_COMMAND_TIMEOUT_MS);
|
|
8530
8689
|
try {
|
|
8531
|
-
await imap.readUntil((
|
|
8690
|
+
await imap.readUntil((text6) => /^\* OK/im.test(text6));
|
|
8532
8691
|
await imap.command(`LOGIN ${quoteImap(credentials.imapUsername)} ${quoteImap(credentials.imapPassword)}`);
|
|
8533
8692
|
await imap.command(`SELECT ${quoteImap(mailbox)}`);
|
|
8534
8693
|
const searchResponse = await imap.command(buildImapSearchCommand({ query, startDate, endDate }));
|
|
@@ -8576,22 +8735,22 @@ async function sendProtonBridgeSmtp(credentials, payload) {
|
|
|
8576
8735
|
const messageId = `<om-${randomUUID7()}@local.openmates>`;
|
|
8577
8736
|
const smtp = await openTextSocket(credentials.smtpHost, credentials.smtpPort, SMTP_COMMAND_TIMEOUT_MS);
|
|
8578
8737
|
try {
|
|
8579
|
-
await smtp.readUntil((
|
|
8580
|
-
await smtp.rawCommand("EHLO openmates.local", (
|
|
8738
|
+
await smtp.readUntil((text6) => /^220[ -]/m.test(text6));
|
|
8739
|
+
await smtp.rawCommand("EHLO openmates.local", (text6) => /^250\s/m.test(text6), /^250[ -]/m);
|
|
8581
8740
|
const auth = Buffer.from(`\0${credentials.smtpUsername || credentials.imapUsername}\0${credentials.smtpPassword || credentials.imapPassword}`).toString("base64");
|
|
8582
8741
|
try {
|
|
8583
|
-
await smtp.rawCommand(`AUTH PLAIN ${auth}`, (
|
|
8742
|
+
await smtp.rawCommand(`AUTH PLAIN ${auth}`, (text6) => /^235[ -]/m.test(text6), /^235[ -]/m);
|
|
8584
8743
|
} catch {
|
|
8585
8744
|
throw new Error("Local SMTP authentication failed.");
|
|
8586
8745
|
}
|
|
8587
|
-
await smtp.rawCommand(`MAIL FROM:<${from}>`, (
|
|
8746
|
+
await smtp.rawCommand(`MAIL FROM:<${from}>`, (text6) => /^250[ -]/m.test(text6), /^250[ -]/m);
|
|
8588
8747
|
for (const recipient of to) {
|
|
8589
|
-
await smtp.rawCommand(`RCPT TO:<${recipient}>`, (
|
|
8748
|
+
await smtp.rawCommand(`RCPT TO:<${recipient}>`, (text6) => /^250[ -]/m.test(text6), /^250[ -]/m);
|
|
8590
8749
|
}
|
|
8591
|
-
await smtp.rawCommand("DATA", (
|
|
8750
|
+
await smtp.rawCommand("DATA", (text6) => /^354[ -]/m.test(text6), /^354[ -]/m);
|
|
8592
8751
|
await smtp.rawCommand(`${buildSmtpMessage({ from, to, subject, bodyText, messageId })}\r
|
|
8593
|
-
.`, (
|
|
8594
|
-
await smtp.rawCommand("QUIT", (
|
|
8752
|
+
.`, (text6) => /^250[ -]/m.test(text6), /^250[ -]/m);
|
|
8753
|
+
await smtp.rawCommand("QUIT", (text6) => /^221[ -]/m.test(text6), /^221[ -]/m).catch(() => void 0);
|
|
8595
8754
|
return { provider: PROTON_BRIDGE_PROVIDER_ID, message_id: messageId, delivered: true };
|
|
8596
8755
|
} finally {
|
|
8597
8756
|
smtp.close();
|
|
@@ -8703,7 +8862,7 @@ async function openTextSocket(host, port, timeoutMs) {
|
|
|
8703
8862
|
buffer = "";
|
|
8704
8863
|
socket.write(`${tag} ${command}\r
|
|
8705
8864
|
`);
|
|
8706
|
-
const response = await waitForSocketText(socket, () => buffer, (
|
|
8865
|
+
const response = await waitForSocketText(socket, () => buffer, (text6) => marker.test(text6), timeoutMs);
|
|
8707
8866
|
if (expected && !expected.test(response)) {
|
|
8708
8867
|
throw new Error(`Local mail command failed: ${redactProtonBridgeSecrets(response.split(/\r?\n/).slice(-2).join(" "))}`);
|
|
8709
8868
|
}
|
|
@@ -8729,8 +8888,8 @@ async function waitForSocketText(socket, getBuffer, done, timeoutMs) {
|
|
|
8729
8888
|
return await new Promise((resolve17, reject) => {
|
|
8730
8889
|
const timer = setTimeout(() => cleanup(() => reject(new Error("Timed out waiting for local mail server response."))), timeoutMs);
|
|
8731
8890
|
const check = () => {
|
|
8732
|
-
const
|
|
8733
|
-
if (done(
|
|
8891
|
+
const text6 = getBuffer();
|
|
8892
|
+
if (done(text6)) cleanup(() => resolve17(text6));
|
|
8734
8893
|
};
|
|
8735
8894
|
const onData = () => check();
|
|
8736
8895
|
const onError = (error) => cleanup(() => reject(error));
|
|
@@ -8809,8 +8968,8 @@ function splitBridgeInfoSections(output) {
|
|
|
8809
8968
|
}
|
|
8810
8969
|
return sections;
|
|
8811
8970
|
}
|
|
8812
|
-
function firstValue(map, ...
|
|
8813
|
-
for (const key of
|
|
8971
|
+
function firstValue(map, ...keys2) {
|
|
8972
|
+
for (const key of keys2) {
|
|
8814
8973
|
const value = map.get(normalizeKey(key));
|
|
8815
8974
|
if (value) return value;
|
|
8816
8975
|
}
|
|
@@ -8907,8 +9066,8 @@ async function promptHidden(prompt) {
|
|
|
8907
9066
|
return await new Promise((resolve17, reject) => {
|
|
8908
9067
|
let value = "";
|
|
8909
9068
|
const onData = (chunk) => {
|
|
8910
|
-
const
|
|
8911
|
-
for (const char of
|
|
9069
|
+
const text6 = chunk.toString("utf8");
|
|
9070
|
+
for (const char of text6) {
|
|
8912
9071
|
if (char === "") {
|
|
8913
9072
|
cleanup();
|
|
8914
9073
|
reject(new Error("Bridge credential prompt cancelled."));
|
|
@@ -10610,8 +10769,8 @@ var MATE_NAMES = {
|
|
|
10610
10769
|
general_knowledge: "George",
|
|
10611
10770
|
onboarding_support: "Suki"
|
|
10612
10771
|
};
|
|
10613
|
-
function stripLegacySuggestionPrefix(
|
|
10614
|
-
return
|
|
10772
|
+
function stripLegacySuggestionPrefix(text6) {
|
|
10773
|
+
return text6.replace(/^\s*\[[^\]]+\]\s*/, "").trim();
|
|
10615
10774
|
}
|
|
10616
10775
|
var CLOUD_API_URL = "https://api.openmates.org";
|
|
10617
10776
|
var DEFAULT_API_URL = process.env.OPENMATES_API_URL ?? CLOUD_API_URL;
|
|
@@ -10672,45 +10831,13 @@ var BLOCKED_SETTINGS_MUTATE_PATHS = /* @__PURE__ */ new Set([
|
|
|
10672
10831
|
"/v1/settings/verify-action-code",
|
|
10673
10832
|
"/v1/settings/user/disable-2fa"
|
|
10674
10833
|
]);
|
|
10675
|
-
function applyUnifiedDiffForEmbedVersion(content, patch) {
|
|
10676
|
-
const contentLines = content.split("\n");
|
|
10677
|
-
const lines = patch.split("\n");
|
|
10678
|
-
const hunks = [];
|
|
10679
|
-
let current = null;
|
|
10680
|
-
for (const line of lines) {
|
|
10681
|
-
const match = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(line);
|
|
10682
|
-
if (match) {
|
|
10683
|
-
if (current) hunks.push(current);
|
|
10684
|
-
current = { start: Number(match[1]) - 1, oldLines: [], newLines: [] };
|
|
10685
|
-
continue;
|
|
10686
|
-
}
|
|
10687
|
-
if (!current) continue;
|
|
10688
|
-
if (line.startsWith(" ")) {
|
|
10689
|
-
current.oldLines.push(line.slice(1));
|
|
10690
|
-
current.newLines.push(line.slice(1));
|
|
10691
|
-
} else if (line.startsWith("-")) {
|
|
10692
|
-
current.oldLines.push(line.slice(1));
|
|
10693
|
-
} else if (line.startsWith("+")) {
|
|
10694
|
-
current.newLines.push(line.slice(1));
|
|
10695
|
-
}
|
|
10696
|
-
}
|
|
10697
|
-
if (current) hunks.push(current);
|
|
10698
|
-
for (const hunk of hunks.sort((a, b) => b.start - a.start)) {
|
|
10699
|
-
const actual = contentLines.slice(hunk.start, hunk.start + hunk.oldLines.length);
|
|
10700
|
-
if (actual.join("\n") !== hunk.oldLines.join("\n")) {
|
|
10701
|
-
throw new Error("Version patch context does not match local content");
|
|
10702
|
-
}
|
|
10703
|
-
contentLines.splice(hunk.start, hunk.oldLines.length, ...hunk.newLines);
|
|
10704
|
-
}
|
|
10705
|
-
return contentLines.join("\n");
|
|
10706
|
-
}
|
|
10707
10834
|
function buildUnifiedDiffForEmbedRestore(currentContent, restoredContent, currentVersion, newVersion) {
|
|
10708
|
-
const currentLines = currentContent.split("\n");
|
|
10709
|
-
const restoredLines = restoredContent.split("\n");
|
|
10835
|
+
const currentLines = currentContent ? currentContent.split("\n") : [];
|
|
10836
|
+
const restoredLines = restoredContent ? restoredContent.split("\n") : [];
|
|
10710
10837
|
return [
|
|
10711
10838
|
`--- v${currentVersion}`,
|
|
10712
10839
|
`+++ v${newVersion}`,
|
|
10713
|
-
`@@
|
|
10840
|
+
`@@ -${currentLines.length ? 1 : 0},${currentLines.length} +${restoredLines.length ? 1 : 0},${restoredLines.length} @@`,
|
|
10714
10841
|
...currentLines.map((line) => `-${line}`),
|
|
10715
10842
|
...restoredLines.map((line) => `+${line}`)
|
|
10716
10843
|
].join("\n");
|
|
@@ -11311,7 +11438,11 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
11311
11438
|
artifact,
|
|
11312
11439
|
imported_at: Math.floor(Date.now() / 1e3)
|
|
11313
11440
|
}, this.getCliRequestHeaders());
|
|
11314
|
-
if (!response.ok)
|
|
11441
|
+
if (!response.ok) {
|
|
11442
|
+
const detail = response.data?.detail;
|
|
11443
|
+
const explanation = typeof detail === "string" && detail.length <= 500 ? `: ${detail}` : "";
|
|
11444
|
+
throw new Error(`Team import failed with HTTP ${response.status}${explanation}`);
|
|
11445
|
+
}
|
|
11315
11446
|
return response.data;
|
|
11316
11447
|
}
|
|
11317
11448
|
async updateTeamMemberRole(teamId, memberUserId, role) {
|
|
@@ -14184,7 +14315,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
14184
14315
|
historicalContent = await decryptWithAesGcmCombined(versionRow.encrypted_snapshot, embedKey);
|
|
14185
14316
|
} else if (typeof versionRow.encrypted_patch === "string" && historicalContent !== null) {
|
|
14186
14317
|
const patch = await decryptWithAesGcmCombined(versionRow.encrypted_patch, embedKey);
|
|
14187
|
-
historicalContent =
|
|
14318
|
+
historicalContent = applyVersionPatch(historicalContent, patch ?? "");
|
|
14188
14319
|
} else {
|
|
14189
14320
|
throw new Error("Canonical recovery embed history lacks a starting snapshot.");
|
|
14190
14321
|
}
|
|
@@ -14314,7 +14445,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
14314
14445
|
return types;
|
|
14315
14446
|
};
|
|
14316
14447
|
const existingTypes = await verifiedKeyTypes(keyPage.data?.embed_keys ?? []);
|
|
14317
|
-
const
|
|
14448
|
+
const keys2 = [
|
|
14318
14449
|
{
|
|
14319
14450
|
hashed_embed_id: hashedKeySubject,
|
|
14320
14451
|
key_type: "master",
|
|
@@ -14332,7 +14463,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
14332
14463
|
created_at: now
|
|
14333
14464
|
}
|
|
14334
14465
|
].filter((key) => !existingTypes.has(key.key_type));
|
|
14335
|
-
if (
|
|
14466
|
+
if (keys2.length > 0) {
|
|
14336
14467
|
const requestId = randomUUID9();
|
|
14337
14468
|
const receipt = ws.waitForMessage("store_embed_keys_confirmed", (value) => value.request_id === requestId, 3e4);
|
|
14338
14469
|
void receipt.catch(() => {
|
|
@@ -14340,10 +14471,10 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
14340
14471
|
await ws.sendAsync("store_embed_keys", {
|
|
14341
14472
|
request_id: requestId,
|
|
14342
14473
|
recovery_record_id: output.record_id,
|
|
14343
|
-
keys
|
|
14474
|
+
keys: keys2
|
|
14344
14475
|
});
|
|
14345
14476
|
const result2 = (await receipt).payload;
|
|
14346
|
-
if (result2.failed_count !== 0 || result2.created_count !==
|
|
14477
|
+
if (result2.failed_count !== 0 || result2.created_count !== keys2.length || result2.requested_count !== keys2.length) {
|
|
14347
14478
|
throw new Error("Recovery embed key wrappers were not exactly confirmed.");
|
|
14348
14479
|
}
|
|
14349
14480
|
const durable = await this.http.get(
|
|
@@ -16034,7 +16165,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
16034
16165
|
embedKey
|
|
16035
16166
|
);
|
|
16036
16167
|
const encryptedTextPreview = embed.text_preview ? await encryptWithAesGcmCombined(embed.text_preview, embedKey) : void 0;
|
|
16037
|
-
const
|
|
16168
|
+
const keys2 = !isChild ? [
|
|
16038
16169
|
{
|
|
16039
16170
|
hashed_embed_id: hashedEmbedId,
|
|
16040
16171
|
key_type: "master",
|
|
@@ -16087,7 +16218,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
16087
16218
|
updated_at: updatedAt
|
|
16088
16219
|
});
|
|
16089
16220
|
await storeConfirmed;
|
|
16090
|
-
if (
|
|
16221
|
+
if (keys2.length > 0) {
|
|
16091
16222
|
const keysRequestId = randomUUID9();
|
|
16092
16223
|
const keysConfirmed = params.ws.waitForMessage(
|
|
16093
16224
|
"store_embed_keys_confirmed",
|
|
@@ -16097,9 +16228,9 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
16097
16228
|
},
|
|
16098
16229
|
3e4
|
|
16099
16230
|
);
|
|
16100
|
-
await params.ws.sendAsync("store_embed_keys", { request_id: keysRequestId, keys });
|
|
16231
|
+
await params.ws.sendAsync("store_embed_keys", { request_id: keysRequestId, keys: keys2 });
|
|
16101
16232
|
const keysReceipt = (await keysConfirmed).payload;
|
|
16102
|
-
if (keysReceipt.failed_count !== 0 || keysReceipt.created_count !==
|
|
16233
|
+
if (keysReceipt.failed_count !== 0 || keysReceipt.created_count !== keys2.length) {
|
|
16103
16234
|
throw new Error(`Embed ${embed.embed_id} key wrappers were not durably stored.`);
|
|
16104
16235
|
}
|
|
16105
16236
|
}
|
|
@@ -17166,11 +17297,11 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
17166
17297
|
}
|
|
17167
17298
|
return response.data.events ?? [];
|
|
17168
17299
|
}
|
|
17169
|
-
async followUpWorkflowInput(sessionId,
|
|
17300
|
+
async followUpWorkflowInput(sessionId, text6) {
|
|
17170
17301
|
this.requireSession();
|
|
17171
17302
|
const response = await this.http.post(
|
|
17172
17303
|
`/v1/workflows/input/${encodeURIComponent(sessionId)}/follow-up`,
|
|
17173
|
-
{ text:
|
|
17304
|
+
{ text: text6 },
|
|
17174
17305
|
this.getCliRequestHeaders()
|
|
17175
17306
|
);
|
|
17176
17307
|
if (!response.ok || !response.data.session) {
|
|
@@ -19539,8 +19670,12 @@ Required: ${schema.required.join(", ")}`
|
|
|
19539
19670
|
if (!response.ok || !response.data) {
|
|
19540
19671
|
throw new Error(this.formatEmbedVersionError(response.data, `Failed to load embed version ${version} (HTTP ${response.status})`));
|
|
19541
19672
|
}
|
|
19542
|
-
if (
|
|
19543
|
-
|
|
19673
|
+
if (response.data.embed_id !== embedId || response.data.version_number !== version) {
|
|
19674
|
+
throw new Error("Version response does not match the selected version");
|
|
19675
|
+
}
|
|
19676
|
+
if (typeof response.data.content === "string") return response.data;
|
|
19677
|
+
if (!Array.isArray(response.data.rows) || response.data.rows.at(-1)?.version_number !== version) {
|
|
19678
|
+
throw new Error("Version response does not match the selected version");
|
|
19544
19679
|
}
|
|
19545
19680
|
const content = await this.reconstructEncryptedEmbedVersion(embedId, response.data.rows, context);
|
|
19546
19681
|
if (response.data.rows.length > 32 && response.data.readonly === false) {
|
|
@@ -19693,22 +19828,7 @@ Required: ${schema.required.join(", ")}`
|
|
|
19693
19828
|
if (!embedKey) {
|
|
19694
19829
|
throw new Error("Could not resolve embed encryption key for version history.");
|
|
19695
19830
|
}
|
|
19696
|
-
|
|
19697
|
-
let content = null;
|
|
19698
|
-
for (const row of sortedRows) {
|
|
19699
|
-
if (row.encrypted_snapshot) {
|
|
19700
|
-
content = await decryptWithAesGcmCombined(row.encrypted_snapshot, embedKey);
|
|
19701
|
-
continue;
|
|
19702
|
-
}
|
|
19703
|
-
if (row.encrypted_patch && content !== null) {
|
|
19704
|
-
const patch = await decryptWithAesGcmCombined(row.encrypted_patch, embedKey);
|
|
19705
|
-
content = applyUnifiedDiffForEmbedVersion(content, patch ?? "");
|
|
19706
|
-
}
|
|
19707
|
-
}
|
|
19708
|
-
if (content === null) {
|
|
19709
|
-
throw new Error("Version history is missing the initial snapshot");
|
|
19710
|
-
}
|
|
19711
|
-
return content;
|
|
19831
|
+
return reconstructVersionRows(rows2, (ciphertext) => decryptWithAesGcmCombined(ciphertext, embedKey));
|
|
19712
19832
|
}
|
|
19713
19833
|
async resolveVersionEmbedKey(embedId, context) {
|
|
19714
19834
|
if (context?.projectId) {
|
|
@@ -20623,6 +20743,7 @@ Required: ${schema.required.join(", ")}`
|
|
|
20623
20743
|
return {
|
|
20624
20744
|
"User-Agent": this.getCliUserAgent(),
|
|
20625
20745
|
"X-OpenMates-SDK": "cli",
|
|
20746
|
+
"X-OpenMates-Client-Capabilities": "agentic-storage-v2",
|
|
20626
20747
|
"X-OpenMates-Device-Identity": this.getCliApiKeyDeviceIdentity(),
|
|
20627
20748
|
Origin: deriveAppUrl(this.apiUrl)
|
|
20628
20749
|
};
|
|
@@ -27727,6 +27848,7 @@ var OpenMates = class {
|
|
|
27727
27848
|
Authorization: `Bearer ${splitApiKeyCredential(this.apiKey ?? "").bearer}`,
|
|
27728
27849
|
Origin: sdkOrigin(this.apiUrl),
|
|
27729
27850
|
"X-OpenMates-SDK": this.sdkName,
|
|
27851
|
+
"X-OpenMates-Client-Capabilities": "agentic-storage-v2",
|
|
27730
27852
|
"X-OpenMates-Device-Identity": this.deviceId
|
|
27731
27853
|
};
|
|
27732
27854
|
if (hasBody) {
|
|
@@ -27738,6 +27860,7 @@ var OpenMates = class {
|
|
|
27738
27860
|
return {
|
|
27739
27861
|
Accept: "application/json",
|
|
27740
27862
|
"X-OpenMates-SDK": this.sdkName,
|
|
27863
|
+
"X-OpenMates-Client-Capabilities": "agentic-storage-v2",
|
|
27741
27864
|
"X-OpenMates-Device-Identity": this.deviceId
|
|
27742
27865
|
};
|
|
27743
27866
|
}
|
|
@@ -30806,8 +30929,8 @@ var OpenMatesWorkflows = class {
|
|
|
30806
30929
|
const response = await this.client.get(`/v1/workflows/input/${encodeURIComponent(sessionId)}/events?after_event_id=${encodeURIComponent(String(afterEventId))}`);
|
|
30807
30930
|
return response.events ?? [];
|
|
30808
30931
|
}
|
|
30809
|
-
async followUpInput(sessionId,
|
|
30810
|
-
const response = await this.client.request(`/v1/workflows/input/${encodeURIComponent(sessionId)}/follow-up`, { text:
|
|
30932
|
+
async followUpInput(sessionId, text6) {
|
|
30933
|
+
const response = await this.client.request(`/v1/workflows/input/${encodeURIComponent(sessionId)}/follow-up`, { text: text6 });
|
|
30811
30934
|
if (!response.session) throw new OpenMatesApiError(500, { detail: "Workflow input response missing session" });
|
|
30812
30935
|
return response.session;
|
|
30813
30936
|
}
|
|
@@ -31131,8 +31254,8 @@ var OpenMatesEmbeds = class {
|
|
|
31131
31254
|
}
|
|
31132
31255
|
async share(embedId, options = {}) {
|
|
31133
31256
|
const shown = await this.show(embedId);
|
|
31134
|
-
const
|
|
31135
|
-
const embedKey = await this.client.resolveEmbedKeyForShare(
|
|
31257
|
+
const keys2 = Array.isArray(shown.embed_keys) ? shown.embed_keys : [];
|
|
31258
|
+
const embedKey = await this.client.resolveEmbedKeyForShare(keys2, embedId);
|
|
31136
31259
|
if (!embedKey) throw new OpenMatesConfigError("Unable to resolve embed key for share link");
|
|
31137
31260
|
const blob = await generateEmbedShareBlob(embedId, embedKey, options.expires ?? 0, options.password);
|
|
31138
31261
|
return { url: buildEmbedShareUrl(this.client.webOrigin(), embedId, blob) };
|
|
@@ -31552,7 +31675,7 @@ import { fileURLToPath as fileURLToPath4 } from "url";
|
|
|
31552
31675
|
import { basename as basename9, dirname as dirname17, join as join28 } from "path";
|
|
31553
31676
|
import { createHash as createHash29, randomBytes as randomBytes13, randomUUID as randomUUID23 } from "crypto";
|
|
31554
31677
|
import { arch as arch2, platform as platform2 } from "os";
|
|
31555
|
-
import { parse as
|
|
31678
|
+
import { parse as parseYaml, parseDocument as parseYamlDocument, stringify as stringifyYaml } from "yaml";
|
|
31556
31679
|
|
|
31557
31680
|
// ../workflowFile.ts
|
|
31558
31681
|
var WORKFLOW_FILE_MAX_BYTES = 1048576;
|
|
@@ -31630,15 +31753,15 @@ var CREDENTIAL_SUFFIXES = [
|
|
|
31630
31753
|
function record4(value) {
|
|
31631
31754
|
return value !== null && typeof value === "object" && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
31632
31755
|
}
|
|
31633
|
-
function onlyKeys(value,
|
|
31756
|
+
function onlyKeys(value, keys2, path2) {
|
|
31634
31757
|
for (const key of Object.keys(value)) {
|
|
31635
|
-
if (!
|
|
31758
|
+
if (!keys2.includes(key)) throw new Error(`Unsupported Workflow file field: ${path2}.${key}.`);
|
|
31636
31759
|
}
|
|
31637
31760
|
}
|
|
31638
31761
|
function assertPortable(value) {
|
|
31639
31762
|
let remaining = 5e4;
|
|
31640
31763
|
const active = /* @__PURE__ */ new Set();
|
|
31641
|
-
function
|
|
31764
|
+
function visit2(item, path2, depth) {
|
|
31642
31765
|
if (--remaining < 0 || depth > 64) throw new Error("Workflow file is too complex.");
|
|
31643
31766
|
if (typeof item === "number" && !Number.isFinite(item)) throw new Error("Workflow file contains an invalid number.");
|
|
31644
31767
|
if (item === null || ["string", "boolean", "number"].includes(typeof item)) return;
|
|
@@ -31646,32 +31769,32 @@ function assertPortable(value) {
|
|
|
31646
31769
|
if (active.has(item)) throw new Error("Workflow file contains a circular reference.");
|
|
31647
31770
|
active.add(item);
|
|
31648
31771
|
if (Array.isArray(item)) {
|
|
31649
|
-
item.forEach((child, i) =>
|
|
31772
|
+
item.forEach((child, i) => visit2(child, `${path2}[${i}]`, depth + 1));
|
|
31650
31773
|
} else {
|
|
31651
31774
|
for (const [key, child] of Object.entries(item)) {
|
|
31652
31775
|
const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
31653
31776
|
if (["__proto__", "constructor", "prototype"].includes(key) || FORBIDDEN_KEYS.has(normalized) || CREDENTIAL_SUFFIXES.some((suffix) => normalized.endsWith(suffix))) {
|
|
31654
31777
|
throw new Error(`Workflow file contains an account-specific or private field at ${path2}.${key}.`);
|
|
31655
31778
|
}
|
|
31656
|
-
|
|
31779
|
+
visit2(child, `${path2}.${key}`, depth + 1);
|
|
31657
31780
|
}
|
|
31658
31781
|
}
|
|
31659
31782
|
active.delete(item);
|
|
31660
31783
|
}
|
|
31661
|
-
|
|
31784
|
+
visit2(value, "$", 0);
|
|
31662
31785
|
}
|
|
31663
31786
|
function remapGraph(graph, ids) {
|
|
31664
31787
|
const escaped = Array.from(ids.keys()).sort((a, b) => b.length - a.length).map((id) => id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
31665
31788
|
const references = escaped.length ? new RegExp(`(\\$nodes\\.|\\{\\{\\s*steps\\.|\\$items\\.|\\{\\{\\s*items\\.)(${escaped.join("|")})(?=[.}\\s]|$)`, "g") : null;
|
|
31666
|
-
function
|
|
31789
|
+
function visit2(value) {
|
|
31667
31790
|
if (typeof value === "string") return references ? value.replace(references, (_match, prefix, id) => prefix + ids.get(id)) : value;
|
|
31668
|
-
if (Array.isArray(value)) return value.map((item) =>
|
|
31669
|
-
if (record4(value)) return Object.fromEntries(Object.entries(value).map(([key, child]) => [key,
|
|
31791
|
+
if (Array.isArray(value)) return value.map((item) => visit2(item));
|
|
31792
|
+
if (record4(value)) return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, visit2(child)]));
|
|
31670
31793
|
return value;
|
|
31671
31794
|
}
|
|
31672
|
-
const mapped =
|
|
31795
|
+
const mapped = visit2(graph);
|
|
31673
31796
|
if (graph.ui_layout) mapped.ui_layout = Object.fromEntries(
|
|
31674
|
-
Object.entries(graph.ui_layout).map(([key, child]) => [ids.get(key) ?? key,
|
|
31797
|
+
Object.entries(graph.ui_layout).map(([key, child]) => [ids.get(key) ?? key, visit2(child)])
|
|
31675
31798
|
);
|
|
31676
31799
|
mapped.trigger_node_id = graph.trigger_node_id ? ids.get(graph.trigger_node_id) ?? graph.trigger_node_id : null;
|
|
31677
31800
|
mapped.nodes.forEach((node, i) => {
|
|
@@ -32077,27 +32200,27 @@ var SecretRegistry = class {
|
|
|
32077
32200
|
textsToAdd.push(entry.textToHide);
|
|
32078
32201
|
}
|
|
32079
32202
|
if (entry.additionalTexts) {
|
|
32080
|
-
for (const
|
|
32081
|
-
if (
|
|
32082
|
-
textsToAdd.push(
|
|
32203
|
+
for (const text6 of entry.additionalTexts) {
|
|
32204
|
+
if (text6 && text6.trim().length > 0) {
|
|
32205
|
+
textsToAdd.push(text6);
|
|
32083
32206
|
}
|
|
32084
32207
|
}
|
|
32085
32208
|
}
|
|
32086
|
-
for (const
|
|
32209
|
+
for (const text6 of textsToAdd) {
|
|
32087
32210
|
const placeholder = entry.replaceWith.startsWith("[") ? entry.replaceWith : `[${entry.replaceWith}]`;
|
|
32088
32211
|
const regEntry = {
|
|
32089
|
-
value:
|
|
32212
|
+
value: text6,
|
|
32090
32213
|
token: placeholder,
|
|
32091
32214
|
source: "settings",
|
|
32092
32215
|
name: entry.id,
|
|
32093
32216
|
type: "PERSONAL_DATA",
|
|
32094
|
-
length:
|
|
32217
|
+
length: text6.length
|
|
32095
32218
|
};
|
|
32096
|
-
this.entries.set(
|
|
32097
|
-
this.usedPlaceholders.set(placeholder,
|
|
32098
|
-
const lower =
|
|
32099
|
-
if (lower !==
|
|
32100
|
-
this.variantToOriginal.set(lower,
|
|
32219
|
+
this.entries.set(text6, regEntry);
|
|
32220
|
+
this.usedPlaceholders.set(placeholder, text6);
|
|
32221
|
+
const lower = text6.toLowerCase();
|
|
32222
|
+
if (lower !== text6) {
|
|
32223
|
+
this.variantToOriginal.set(lower, text6);
|
|
32101
32224
|
}
|
|
32102
32225
|
}
|
|
32103
32226
|
this.automaton = null;
|
|
@@ -32151,12 +32274,12 @@ var SecretRegistry = class {
|
|
|
32151
32274
|
* @param text Text to scan
|
|
32152
32275
|
* @returns Array of secret mappings for all matches found
|
|
32153
32276
|
*/
|
|
32154
|
-
findAll(
|
|
32277
|
+
findAll(text6) {
|
|
32155
32278
|
if (this.entries.size === 0) return [];
|
|
32156
32279
|
if (!this.automaton) {
|
|
32157
32280
|
this.buildAutomaton();
|
|
32158
32281
|
}
|
|
32159
|
-
const results = this.automaton.search(
|
|
32282
|
+
const results = this.automaton.search(text6);
|
|
32160
32283
|
const mappings = [];
|
|
32161
32284
|
const coveredRanges = [];
|
|
32162
32285
|
const sortedResults = [];
|
|
@@ -32361,17 +32484,17 @@ var SecretScanner = class {
|
|
|
32361
32484
|
* @param text Text to scan and redact
|
|
32362
32485
|
* @returns Object with redacted text and mappings for restoration
|
|
32363
32486
|
*/
|
|
32364
|
-
redact(
|
|
32365
|
-
if (!
|
|
32487
|
+
redact(text6) {
|
|
32488
|
+
if (!text6) return { redacted: text6, mappings: [] };
|
|
32366
32489
|
const allMappings = [];
|
|
32367
32490
|
const coveredRanges = [];
|
|
32368
|
-
const urlExclusionZones = getUrlExclusionZones(
|
|
32369
|
-
const identifierRanges = codingIdentifierRanges(
|
|
32491
|
+
const urlExclusionZones = getUrlExclusionZones(text6);
|
|
32492
|
+
const identifierRanges = codingIdentifierRanges(text6);
|
|
32370
32493
|
if (this.options.enableRegistryDetection && this.registry.size > 0) {
|
|
32371
|
-
const registryMappings = this.registry.findAll(
|
|
32494
|
+
const registryMappings = this.registry.findAll(text6);
|
|
32372
32495
|
for (const mapping of registryMappings) {
|
|
32373
32496
|
let searchFrom = 0;
|
|
32374
|
-
const searchText =
|
|
32497
|
+
const searchText = text6.toLowerCase();
|
|
32375
32498
|
const matchLower = mapping.original.toLowerCase();
|
|
32376
32499
|
while (searchFrom < searchText.length) {
|
|
32377
32500
|
const idx = searchText.indexOf(matchLower, searchFrom);
|
|
@@ -32387,7 +32510,7 @@ var SecretScanner = class {
|
|
|
32387
32510
|
for (const pattern of [...SECRET_PATTERNS, ...GENERAL_PII_PATTERNS]) {
|
|
32388
32511
|
pattern.regex.lastIndex = 0;
|
|
32389
32512
|
let match;
|
|
32390
|
-
while ((match = pattern.regex.exec(
|
|
32513
|
+
while ((match = pattern.regex.exec(text6)) !== null) {
|
|
32391
32514
|
const matchText = match[0];
|
|
32392
32515
|
const startIndex = match.index;
|
|
32393
32516
|
const endIndex = startIndex + matchText.length;
|
|
@@ -32418,7 +32541,7 @@ var SecretScanner = class {
|
|
|
32418
32541
|
}
|
|
32419
32542
|
}
|
|
32420
32543
|
}
|
|
32421
|
-
let redacted =
|
|
32544
|
+
let redacted = text6;
|
|
32422
32545
|
const sortedMappings = [...allMappings].sort(
|
|
32423
32546
|
(a, b) => b.original.length - a.original.length
|
|
32424
32547
|
);
|
|
@@ -32447,9 +32570,9 @@ var SecretScanner = class {
|
|
|
32447
32570
|
* @param mappings Mappings from a previous redact() call
|
|
32448
32571
|
* @returns Text with placeholders replaced by original values
|
|
32449
32572
|
*/
|
|
32450
|
-
restore(
|
|
32451
|
-
if (!
|
|
32452
|
-
let result =
|
|
32573
|
+
restore(text6, mappings) {
|
|
32574
|
+
if (!text6 || !mappings || mappings.length === 0) return text6;
|
|
32575
|
+
let result = text6;
|
|
32453
32576
|
for (const mapping of mappings) {
|
|
32454
32577
|
result = result.split(mapping.placeholder).join(mapping.original);
|
|
32455
32578
|
}
|
|
@@ -32468,11 +32591,11 @@ var SecretScanner = class {
|
|
|
32468
32591
|
function escapeRegExp2(string3) {
|
|
32469
32592
|
return string3.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
32470
32593
|
}
|
|
32471
|
-
function getUrlExclusionZones(
|
|
32594
|
+
function getUrlExclusionZones(text6) {
|
|
32472
32595
|
const urlExclusionRegex = /https?:\/\/[^\s]+/g;
|
|
32473
32596
|
const zones = [];
|
|
32474
32597
|
let match;
|
|
32475
|
-
while ((match = urlExclusionRegex.exec(
|
|
32598
|
+
while ((match = urlExclusionRegex.exec(text6)) !== null) {
|
|
32476
32599
|
zones.push({ start: match.index, end: match.index + match[0].length });
|
|
32477
32600
|
}
|
|
32478
32601
|
return zones;
|
|
@@ -32549,18 +32672,18 @@ var OutputRedactor = class {
|
|
|
32549
32672
|
* @param text Text to scan
|
|
32550
32673
|
* @returns Redacted text with placeholders
|
|
32551
32674
|
*/
|
|
32552
|
-
redact(
|
|
32553
|
-
return this.redactWithMappings(
|
|
32675
|
+
redact(text6) {
|
|
32676
|
+
return this.redactWithMappings(text6).redacted;
|
|
32554
32677
|
}
|
|
32555
32678
|
/**
|
|
32556
32679
|
* Redact and return both redacted text and mappings.
|
|
32557
32680
|
* Used when we need to store mappings alongside message data.
|
|
32558
32681
|
*/
|
|
32559
|
-
redactWithMappings(
|
|
32560
|
-
if (!
|
|
32561
|
-
return { redacted:
|
|
32682
|
+
redactWithMappings(text6) {
|
|
32683
|
+
if (!text6 || !this.initialized || !this.privacyEnabled) {
|
|
32684
|
+
return { redacted: text6, mappings: [] };
|
|
32562
32685
|
}
|
|
32563
|
-
const result = this.scanner.redact(
|
|
32686
|
+
const result = this.scanner.redact(text6);
|
|
32564
32687
|
const excluded = result.mappings.filter((m) => this.disabledCategories.has(PII_TYPE_TO_CATEGORY[m.type] ?? ""));
|
|
32565
32688
|
if (excluded.length) {
|
|
32566
32689
|
result.redacted = this.scanner.restore(result.redacted, excluded);
|
|
@@ -32575,9 +32698,9 @@ var OutputRedactor = class {
|
|
|
32575
32698
|
* Restore placeholders back to original values.
|
|
32576
32699
|
* Only uses mappings from this session (never from external sources).
|
|
32577
32700
|
*/
|
|
32578
|
-
restore(
|
|
32579
|
-
if (!
|
|
32580
|
-
return this.scanner.restore(
|
|
32701
|
+
restore(text6) {
|
|
32702
|
+
if (!text6 || this.sessionMappings.size === 0) return text6;
|
|
32703
|
+
return this.scanner.restore(text6, Array.from(this.sessionMappings.values()));
|
|
32581
32704
|
}
|
|
32582
32705
|
/** Mappings accumulated while preparing attachments and this message. */
|
|
32583
32706
|
getMappings() {
|
|
@@ -32636,8 +32759,8 @@ function createWebsiteEmbed(url) {
|
|
|
32636
32759
|
status: "finished"
|
|
32637
32760
|
};
|
|
32638
32761
|
}
|
|
32639
|
-
function replaceUrlsInText(
|
|
32640
|
-
return
|
|
32762
|
+
function replaceUrlsInText(text6, embeds) {
|
|
32763
|
+
return text6.replace(URL_PATTERN, (rawUrl) => {
|
|
32641
32764
|
const { url, suffix } = trimTrailingUrlPunctuation(rawUrl);
|
|
32642
32765
|
if (!url) return rawUrl;
|
|
32643
32766
|
try {
|
|
@@ -33637,12 +33760,12 @@ function renderAudioTranscribePreview(c, ln) {
|
|
|
33637
33760
|
const language = str(c.language) ?? "";
|
|
33638
33761
|
if (duration) ln(`\x1B[2mDuration: ${duration}\x1B[0m`);
|
|
33639
33762
|
if (language) ln(`\x1B[2mLanguage: ${language}\x1B[0m`);
|
|
33640
|
-
const
|
|
33641
|
-
if (
|
|
33763
|
+
const text6 = str(c.text) ?? str(c.transcript) ?? "";
|
|
33764
|
+
if (text6) ln(trunc(text6, 60));
|
|
33642
33765
|
}
|
|
33643
33766
|
function renderAudioTranscribeFullscreen(c) {
|
|
33644
|
-
const
|
|
33645
|
-
if (
|
|
33767
|
+
const text6 = str(c.text) ?? str(c.transcript) ?? "";
|
|
33768
|
+
if (text6) console.log(text6);
|
|
33646
33769
|
else console.log("No transcript available.");
|
|
33647
33770
|
}
|
|
33648
33771
|
function renderByDirectType(embed, c, ln) {
|
|
@@ -33875,8 +33998,8 @@ function renderDirectTypeFullscreen(embed, c) {
|
|
|
33875
33998
|
|
|
33876
33999
|
`);
|
|
33877
34000
|
if (html) {
|
|
33878
|
-
const
|
|
33879
|
-
console.log(
|
|
34001
|
+
const text6 = html.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
34002
|
+
console.log(text6);
|
|
33880
34003
|
}
|
|
33881
34004
|
break;
|
|
33882
34005
|
}
|
|
@@ -33887,8 +34010,8 @@ function renderDirectTypeFullscreen(embed, c) {
|
|
|
33887
34010
|
|
|
33888
34011
|
`);
|
|
33889
34012
|
if (html) {
|
|
33890
|
-
const
|
|
33891
|
-
console.log(
|
|
34013
|
+
const text6 = html.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
34014
|
+
console.log(text6);
|
|
33892
34015
|
}
|
|
33893
34016
|
break;
|
|
33894
34017
|
}
|
|
@@ -34039,18 +34162,18 @@ function mindMapOutline(document, maxNodes = 100) {
|
|
|
34039
34162
|
}
|
|
34040
34163
|
const lines = [];
|
|
34041
34164
|
const visited = /* @__PURE__ */ new Set();
|
|
34042
|
-
const
|
|
34165
|
+
const visit2 = (nodeId, depth) => {
|
|
34043
34166
|
if (visited.size >= maxNodes || visited.has(nodeId)) return;
|
|
34044
34167
|
const node = nodesById.get(nodeId);
|
|
34045
34168
|
if (!node) return;
|
|
34046
34169
|
visited.add(nodeId);
|
|
34047
34170
|
lines.push(`${" ".repeat(depth)}- ${node.label}`);
|
|
34048
|
-
for (const childId of node.children ?? [])
|
|
34171
|
+
for (const childId of node.children ?? []) visit2(childId, depth + 1);
|
|
34049
34172
|
};
|
|
34050
|
-
|
|
34173
|
+
visit2(document.rootId, 0);
|
|
34051
34174
|
for (const node of document.nodes) {
|
|
34052
34175
|
if (visited.size >= maxNodes) break;
|
|
34053
|
-
if (!visited.has(node.id))
|
|
34176
|
+
if (!visited.has(node.id)) visit2(node.id, 0);
|
|
34054
34177
|
}
|
|
34055
34178
|
return lines.join("\n");
|
|
34056
34179
|
}
|
|
@@ -34435,13 +34558,13 @@ function unsetEnvValue(content, key) {
|
|
|
34435
34558
|
}).join("\n").replace(/\n*$/, "")}
|
|
34436
34559
|
`;
|
|
34437
34560
|
}
|
|
34438
|
-
function
|
|
34561
|
+
function unique2(items) {
|
|
34439
34562
|
return [...new Set(items.map((item) => item.trim()).filter(Boolean))];
|
|
34440
34563
|
}
|
|
34441
34564
|
function csv(value) {
|
|
34442
34565
|
if (value === void 0) return [];
|
|
34443
|
-
if (Array.isArray(value)) return
|
|
34444
|
-
return
|
|
34566
|
+
if (Array.isArray(value)) return unique2(value.flatMap((item) => item.split(",")));
|
|
34567
|
+
return unique2(value.split(","));
|
|
34445
34568
|
}
|
|
34446
34569
|
function parseServerRole(value) {
|
|
34447
34570
|
if (!value) return "core";
|
|
@@ -34515,7 +34638,7 @@ function planServerRuntime(input) {
|
|
|
34515
34638
|
const profileServices = role === "core" ? [...CORE_OBSERVABILITY_BY_PROFILE[coreProfile]] : [];
|
|
34516
34639
|
if (role === "core" && input.withAlerts) profileServices.push("alertmanager");
|
|
34517
34640
|
const webappServices = input.includeWebapp === false ? [] : ["webapp"];
|
|
34518
|
-
const defaultServices = role === "core" ?
|
|
34641
|
+
const defaultServices = role === "core" ? unique2([...definition.requiredServices, ...CORE_WORKER_SERVICES, "admin-sidecar", ...profileServices, ...webappServices]) : unique2([...definition.requiredServices, ...definition.optionalServices]);
|
|
34519
34642
|
return {
|
|
34520
34643
|
role,
|
|
34521
34644
|
profile,
|
|
@@ -34803,7 +34926,7 @@ function planRuntimeMonitoringServices(input) {
|
|
|
34803
34926
|
"",
|
|
34804
34927
|
"[Timer]",
|
|
34805
34928
|
"OnBootSec=2min",
|
|
34806
|
-
"OnUnitActiveSec=
|
|
34929
|
+
"OnUnitActiveSec=1min",
|
|
34807
34930
|
"Persistent=true",
|
|
34808
34931
|
`Unit=${serviceName}`,
|
|
34809
34932
|
"",
|
|
@@ -34863,6 +34986,60 @@ function validateServerEnvironmentTarget(command, environment) {
|
|
|
34863
34986
|
throw new Error("Unknown server environment target; use shared-dev for explicit server administration.");
|
|
34864
34987
|
}
|
|
34865
34988
|
|
|
34989
|
+
// src/serverStorageMigration.ts
|
|
34990
|
+
function parseStorageMigrationOutcome(value) {
|
|
34991
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
34992
|
+
return { status: "paused", reason: "migration_coordinator_response_invalid" };
|
|
34993
|
+
}
|
|
34994
|
+
const row = value;
|
|
34995
|
+
if (!["pending", "paused", "reader_enabled", "prune_enabled", "not_applicable"].includes(String(row.status))) {
|
|
34996
|
+
return { status: "paused", reason: "migration_coordinator_response_invalid" };
|
|
34997
|
+
}
|
|
34998
|
+
const result = { status: row.status };
|
|
34999
|
+
if (typeof row.reason === "string" && /^[a-z_]{1,80}$/.test(row.reason)) result.reason = row.reason;
|
|
35000
|
+
if (typeof row.source_commit === "string" && /^[a-f0-9]{40}$/.test(row.source_commit)) result.source_commit = row.source_commit;
|
|
35001
|
+
if (Number.isInteger(row.retry_seconds) && Number(row.retry_seconds) > 0 && Number(row.retry_seconds) <= 86400) {
|
|
35002
|
+
result.retry_seconds = Number(row.retry_seconds);
|
|
35003
|
+
}
|
|
35004
|
+
return result;
|
|
35005
|
+
}
|
|
35006
|
+
function parseStorageMigrationProgress(value) {
|
|
35007
|
+
const row = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
35008
|
+
const result = { automatic: parseStorageMigrationOutcome(row.automatic) };
|
|
35009
|
+
if (row.legacy_full_graph !== void 0) result.legacy_full_graph = parseStorageMigrationOutcome(row.legacy_full_graph);
|
|
35010
|
+
const fields = {
|
|
35011
|
+
message_segments: ["copying", "verified", "reader_active"],
|
|
35012
|
+
message_pages: ["read_enabled", "pruned"],
|
|
35013
|
+
version_rows: ["copied", "reader_active", "pruned", "stale"]
|
|
35014
|
+
};
|
|
35015
|
+
for (const [name, names] of Object.entries(fields)) {
|
|
35016
|
+
const counts = row[name];
|
|
35017
|
+
if (!counts || typeof counts !== "object" || Array.isArray(counts)) continue;
|
|
35018
|
+
const selected = {};
|
|
35019
|
+
for (const key of names) {
|
|
35020
|
+
const count = counts[key];
|
|
35021
|
+
if (typeof count === "number" && Number.isSafeInteger(count) && count >= 0) selected[key] = count;
|
|
35022
|
+
}
|
|
35023
|
+
result[name] = selected;
|
|
35024
|
+
}
|
|
35025
|
+
return result;
|
|
35026
|
+
}
|
|
35027
|
+
function storageMigrationCommand(composePrefix, operation, sourceRevision) {
|
|
35028
|
+
if (sourceRevision !== void 0 && !/^[a-f0-9]{40}$/i.test(sourceRevision)) {
|
|
35029
|
+
throw new Error("source_revision_unavailable");
|
|
35030
|
+
}
|
|
35031
|
+
return [
|
|
35032
|
+
...composePrefix,
|
|
35033
|
+
"exec",
|
|
35034
|
+
"-T",
|
|
35035
|
+
...sourceRevision ? ["-e", `BUILD_COMMIT_SHA=${sourceRevision.toLowerCase()}`] : [],
|
|
35036
|
+
"api",
|
|
35037
|
+
"python",
|
|
35038
|
+
"/app/scripts/storage_rollout.py",
|
|
35039
|
+
operation
|
|
35040
|
+
];
|
|
35041
|
+
}
|
|
35042
|
+
|
|
34866
35043
|
// src/serverBackupArchive.ts
|
|
34867
35044
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
34868
35045
|
import { chmodSync as chmodSync4, lstatSync as lstatSync2, readdirSync as readdirSync4, renameSync as renameSync3, rmSync as rmSync4 } from "fs";
|
|
@@ -34898,7 +35075,7 @@ import { createHash as createHash16 } from "crypto";
|
|
|
34898
35075
|
import { accessSync, constants as constants2, existsSync as existsSync9, mkdirSync as mkdirSync9, mkdtempSync, readFileSync as readFileSync10, renameSync as renameSync4, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
34899
35076
|
import { tmpdir } from "os";
|
|
34900
35077
|
import { dirname as dirname7, join as join12 } from "path";
|
|
34901
|
-
var hash2 = (
|
|
35078
|
+
var hash2 = (text6) => createHash16("sha256").update(text6).digest("hex");
|
|
34902
35079
|
function resolveCaddyProfile(role, explicit, previous) {
|
|
34903
35080
|
if (explicit === void 0) return previous ?? "self-host";
|
|
34904
35081
|
if (role !== "upload" || explicit !== "official-upload") throw new Error("caddy_profile_unsupported");
|
|
@@ -37301,6 +37478,100 @@ function sourceUpdateMetadata(installPath) {
|
|
|
37301
37478
|
}
|
|
37302
37479
|
};
|
|
37303
37480
|
}
|
|
37481
|
+
function runAutomaticStorageMigration(installPath, role, installMode, withOverrides) {
|
|
37482
|
+
if (role !== "core") return { status: "not_applicable" };
|
|
37483
|
+
if (!shouldAutoInstallRuntimeMonitoringServices(process.env)) {
|
|
37484
|
+
return { status: "paused", reason: "inventory_refresh_service_disabled", retry_seconds: 60 };
|
|
37485
|
+
}
|
|
37486
|
+
if (!refreshStorageRuntimeInventory(installPath, role, installMode, withOverrides)) {
|
|
37487
|
+
return { status: "paused", reason: "runtime_inventory_refresh_unavailable", retry_seconds: 60 };
|
|
37488
|
+
}
|
|
37489
|
+
let sourceRevision;
|
|
37490
|
+
if (installMode === "source") {
|
|
37491
|
+
if (exec("git status --porcelain", installPath).trim()) {
|
|
37492
|
+
return { status: "pending", reason: "source_worktree_unverified" };
|
|
37493
|
+
}
|
|
37494
|
+
const revision = exec("git rev-parse HEAD", installPath).trim();
|
|
37495
|
+
if (!/^[a-f0-9]{40}$/i.test(revision)) {
|
|
37496
|
+
return { status: "pending", reason: "source_revision_unavailable" };
|
|
37497
|
+
}
|
|
37498
|
+
sourceRevision = revision;
|
|
37499
|
+
}
|
|
37500
|
+
const args = storageMigrationCommand(composeArgs(installPath, withOverrides, installMode, role), "auto", sourceRevision);
|
|
37501
|
+
const result = spawnSync("docker", args, {
|
|
37502
|
+
cwd: installPath,
|
|
37503
|
+
encoding: "utf8",
|
|
37504
|
+
timeout: 45e3,
|
|
37505
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
37506
|
+
maxBuffer: 64 * 1024
|
|
37507
|
+
});
|
|
37508
|
+
if (result.error || result.status !== 0) {
|
|
37509
|
+
return { status: "paused", reason: "migration_coordinator_unavailable" };
|
|
37510
|
+
}
|
|
37511
|
+
try {
|
|
37512
|
+
return parseStorageMigrationOutcome(JSON.parse(result.stdout.trim()));
|
|
37513
|
+
} catch {
|
|
37514
|
+
}
|
|
37515
|
+
return { status: "paused", reason: "migration_coordinator_response_invalid" };
|
|
37516
|
+
}
|
|
37517
|
+
function refreshStorageRuntimeInventory(installPath, role, installMode, withOverrides) {
|
|
37518
|
+
if (role !== "core") return true;
|
|
37519
|
+
if (installMode === "source" && exec("git status --porcelain", installPath).trim()) return false;
|
|
37520
|
+
try {
|
|
37521
|
+
const containers = execFileSync4(
|
|
37522
|
+
"docker",
|
|
37523
|
+
[...composeArgs(installPath, withOverrides, installMode, role), "ps", "--all", "-q", "api"],
|
|
37524
|
+
{ cwd: installPath, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], timeout: 15e3 }
|
|
37525
|
+
).trim().split(/\s+/).filter(Boolean);
|
|
37526
|
+
if (containers.length < 1 || containers.length > 128 || new Set(containers).size !== containers.length || containers.some((id) => !/^[a-f0-9]{12,64}$/.test(id))) return false;
|
|
37527
|
+
const cohort = [];
|
|
37528
|
+
for (const container of containers) {
|
|
37529
|
+
const output = execFileSync4(
|
|
37530
|
+
"docker",
|
|
37531
|
+
["exec", container, "python", "/app/scripts/storage_runtime_inventory.py", "inspect"],
|
|
37532
|
+
{ cwd: installPath, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], timeout: 15e3, maxBuffer: 64 * 1024 }
|
|
37533
|
+
);
|
|
37534
|
+
cohort.push(JSON.parse(output.trim()));
|
|
37535
|
+
}
|
|
37536
|
+
const result = spawnSync(
|
|
37537
|
+
"docker",
|
|
37538
|
+
["exec", "-i", containers[0], "python", "/app/scripts/storage_runtime_inventory.py", "publish"],
|
|
37539
|
+
{
|
|
37540
|
+
cwd: installPath,
|
|
37541
|
+
encoding: "utf8",
|
|
37542
|
+
input: JSON.stringify(cohort),
|
|
37543
|
+
timeout: 45e3,
|
|
37544
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
37545
|
+
maxBuffer: 64 * 1024
|
|
37546
|
+
}
|
|
37547
|
+
);
|
|
37548
|
+
if (result.error || result.status !== 0) return false;
|
|
37549
|
+
const published = JSON.parse(result.stdout.trim());
|
|
37550
|
+
return published.status === "published";
|
|
37551
|
+
} catch {
|
|
37552
|
+
return false;
|
|
37553
|
+
}
|
|
37554
|
+
}
|
|
37555
|
+
function readStorageMigrationProgress(installPath, role, installMode, withOverrides) {
|
|
37556
|
+
if (role !== "core") return { automatic: { status: "not_applicable" } };
|
|
37557
|
+
const result = spawnSync("docker", storageMigrationCommand(
|
|
37558
|
+
composeArgs(installPath, withOverrides, installMode, role),
|
|
37559
|
+
"status"
|
|
37560
|
+
), {
|
|
37561
|
+
cwd: installPath,
|
|
37562
|
+
encoding: "utf8",
|
|
37563
|
+
timeout: 45e3,
|
|
37564
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
37565
|
+
maxBuffer: 64 * 1024
|
|
37566
|
+
});
|
|
37567
|
+
if (!result.error && result.status === 0) {
|
|
37568
|
+
try {
|
|
37569
|
+
return parseStorageMigrationProgress(JSON.parse(result.stdout.trim()));
|
|
37570
|
+
} catch {
|
|
37571
|
+
}
|
|
37572
|
+
}
|
|
37573
|
+
return { automatic: { status: "paused", reason: "migration_coordinator_unavailable", retry_seconds: 60 } };
|
|
37574
|
+
}
|
|
37304
37575
|
function copyIfExists(source, destination) {
|
|
37305
37576
|
if (!existsSync11(source)) return;
|
|
37306
37577
|
mkdirSync12(dirname9(destination), { recursive: true });
|
|
@@ -37810,8 +38081,31 @@ async function serverStatus(flags) {
|
|
|
37810
38081
|
args.push("--format", "json");
|
|
37811
38082
|
}
|
|
37812
38083
|
if (selection.requested) args.push(...selection.services);
|
|
38084
|
+
if (flags.json === true) {
|
|
38085
|
+
const output = execFileSync4("docker", args, { cwd: installPath, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
38086
|
+
const containers = [];
|
|
38087
|
+
if (output) {
|
|
38088
|
+
if (output.startsWith("[")) containers.push(...JSON.parse(output));
|
|
38089
|
+
else for (const line of output.split("\n")) containers.push(JSON.parse(line));
|
|
38090
|
+
}
|
|
38091
|
+
printJson({
|
|
38092
|
+
command: "status",
|
|
38093
|
+
path: installPath,
|
|
38094
|
+
role,
|
|
38095
|
+
containers,
|
|
38096
|
+
storageMigration: readStorageMigrationProgress(installPath, role, getInstallMode(installPath, config), withOverrides)
|
|
38097
|
+
});
|
|
38098
|
+
return;
|
|
38099
|
+
}
|
|
37813
38100
|
const code = await runInteractive("docker", args, installPath);
|
|
37814
38101
|
if (code !== 0) process.exit(code);
|
|
38102
|
+
const migration = readStorageMigrationProgress(installPath, role, getInstallMode(installPath, config), withOverrides);
|
|
38103
|
+
const outcome = migration.automatic;
|
|
38104
|
+
console.log(`Storage migration: ${outcome.status}${outcome.reason ? ` (${outcome.reason})` : ""}${outcome.retry_seconds ? `; retry in ${outcome.retry_seconds}s` : ""}`);
|
|
38105
|
+
if (migration.legacy_full_graph) console.log(`Legacy full graph migration: ${migration.legacy_full_graph.status} (${migration.legacy_full_graph.reason ?? "policy_pending"})`);
|
|
38106
|
+
if (migration.message_segments) console.log(`Message segments: ${JSON.stringify(migration.message_segments)}`);
|
|
38107
|
+
if (migration.message_pages) console.log(`Message pages: ${JSON.stringify(migration.message_pages)}`);
|
|
38108
|
+
if (migration.version_rows) console.log(`Version rows: ${JSON.stringify(migration.version_rows)}`);
|
|
37815
38109
|
}
|
|
37816
38110
|
async function serverStart(flags) {
|
|
37817
38111
|
requireDocker();
|
|
@@ -38485,6 +38779,8 @@ async function installRuntimeMonitoringServices(installPath, role) {
|
|
|
38485
38779
|
execSync("systemctl daemon-reload", { stdio: "pipe" });
|
|
38486
38780
|
const timers = files.filter(([name]) => name.endsWith(".timer")).map(([name]) => name);
|
|
38487
38781
|
execSync(`systemctl enable --now ${timers.map(shellQuote).join(" ")}`, { stdio: "pipe" });
|
|
38782
|
+
execFileSync4("systemctl", ["restart", plan.timerName], { stdio: "pipe" });
|
|
38783
|
+
execFileSync4("systemctl", ["--no-block", "try-restart", plan.serviceName], { stdio: "pipe" });
|
|
38488
38784
|
for (const timer of timers) execFileSync4("systemctl", ["is-active", "--quiet", timer], { stdio: "pipe" });
|
|
38489
38785
|
}
|
|
38490
38786
|
async function autoInstallRuntimeMonitoringServices(installPath, role) {
|
|
@@ -38856,6 +39152,8 @@ async function serverUpdate(client2, rest, flags) {
|
|
|
38856
39152
|
await runInteractive("docker", [...composeArgs(installPath, withOverrides, installMode, role), "ps"], installPath);
|
|
38857
39153
|
throw error;
|
|
38858
39154
|
}
|
|
39155
|
+
const automaticStorageMigration2 = runAutomaticStorageMigration(installPath, role, installMode, withOverrides);
|
|
39156
|
+
console.error(`Storage migration: ${automaticStorageMigration2.status}${automaticStorageMigration2.reason ? ` (${automaticStorageMigration2.reason})` : ""}`);
|
|
38859
39157
|
if (config) {
|
|
38860
39158
|
saveServerConfig({ ...config, imageTag: target.tag, imageChannel: target.channel });
|
|
38861
39159
|
}
|
|
@@ -38893,6 +39191,7 @@ async function serverUpdate(client2, rest, flags) {
|
|
|
38893
39191
|
checks: successfulRuntimeOutput2?.checks ?? [],
|
|
38894
39192
|
runtimeCompletedAt: successfulRuntimeOutput2?.completed_at,
|
|
38895
39193
|
quickTest: quickTest2,
|
|
39194
|
+
automaticStorageMigration: automaticStorageMigration2,
|
|
38896
39195
|
completionEmailDelivery: completion3.delivery
|
|
38897
39196
|
});
|
|
38898
39197
|
if (flags.json === true) {
|
|
@@ -38922,6 +39221,7 @@ async function serverUpdate(client2, rest, flags) {
|
|
|
38922
39221
|
checks: successfulRuntimeOutput2?.checks ?? [],
|
|
38923
39222
|
runtimeCompletedAt: successfulRuntimeOutput2?.completed_at,
|
|
38924
39223
|
quickTest: quickTest2,
|
|
39224
|
+
automaticStorageMigration: automaticStorageMigration2,
|
|
38925
39225
|
completionEmailDelivery: completion2.delivery,
|
|
38926
39226
|
completionEmailDeliveryId: completion2.deliveryId,
|
|
38927
39227
|
completionEmailPendingAt: completion2.deliveryPendingAt,
|
|
@@ -38937,6 +39237,7 @@ async function serverUpdate(client2, rest, flags) {
|
|
|
38937
39237
|
runtimeVerification: successfulRuntimeOutput2,
|
|
38938
39238
|
caddy: caddy2,
|
|
38939
39239
|
quickTest: quickTest2,
|
|
39240
|
+
automaticStorageMigration: automaticStorageMigration2,
|
|
38940
39241
|
completionEmailDelivery: completion2.delivery,
|
|
38941
39242
|
completedAt: completion2.completedAt
|
|
38942
39243
|
});
|
|
@@ -39001,8 +39302,16 @@ async function serverUpdate(client2, rest, flags) {
|
|
|
39001
39302
|
);
|
|
39002
39303
|
}
|
|
39003
39304
|
}
|
|
39305
|
+
let sourceBuildRevision = "";
|
|
39306
|
+
try {
|
|
39307
|
+
if (!exec("git status --porcelain", installPath).trim()) {
|
|
39308
|
+
const revision = exec("git rev-parse HEAD", installPath).trim();
|
|
39309
|
+
if (/^[a-f0-9]{40}$/i.test(revision)) sourceBuildRevision = revision.toLowerCase();
|
|
39310
|
+
}
|
|
39311
|
+
} catch {
|
|
39312
|
+
}
|
|
39004
39313
|
const buildArgs = appendSelectedServices(
|
|
39005
|
-
[...composeArgs(installPath, withOverrides, installMode, role), "build"],
|
|
39314
|
+
[...composeArgs(installPath, withOverrides, installMode, role), "build", "--build-arg", `BUILD_COMMIT_SHA=${sourceBuildRevision}`],
|
|
39006
39315
|
coreSetupPlan.pullOrBuildServices,
|
|
39007
39316
|
filterRequested
|
|
39008
39317
|
);
|
|
@@ -39069,6 +39378,8 @@ async function serverUpdate(client2, rest, flags) {
|
|
|
39069
39378
|
await runInteractive("docker", [...composeArgs(installPath, withOverrides, installMode, role), "ps"], installPath);
|
|
39070
39379
|
throw error;
|
|
39071
39380
|
}
|
|
39381
|
+
const automaticStorageMigration = runAutomaticStorageMigration(installPath, role, installMode, withOverrides);
|
|
39382
|
+
console.error(`Storage migration: ${automaticStorageMigration.status}${automaticStorageMigration.reason ? ` (${automaticStorageMigration.reason})` : ""}`);
|
|
39072
39383
|
try {
|
|
39073
39384
|
await autoInstallRuntimeMonitoringServices(installPath, role);
|
|
39074
39385
|
} catch (error) {
|
|
@@ -39095,6 +39406,7 @@ async function serverUpdate(client2, rest, flags) {
|
|
|
39095
39406
|
checks: successfulRuntimeOutput?.checks ?? [],
|
|
39096
39407
|
runtimeCompletedAt: successfulRuntimeOutput?.completed_at,
|
|
39097
39408
|
quickTest,
|
|
39409
|
+
automaticStorageMigration,
|
|
39098
39410
|
completionEmailDelivery: completion2.delivery
|
|
39099
39411
|
});
|
|
39100
39412
|
if (flags.json === true) {
|
|
@@ -39122,6 +39434,7 @@ async function serverUpdate(client2, rest, flags) {
|
|
|
39122
39434
|
checks: successfulRuntimeOutput?.checks ?? [],
|
|
39123
39435
|
runtimeCompletedAt: successfulRuntimeOutput?.completed_at,
|
|
39124
39436
|
quickTest,
|
|
39437
|
+
automaticStorageMigration,
|
|
39125
39438
|
completionEmailDelivery: completion.delivery,
|
|
39126
39439
|
completionEmailDeliveryId: completion.deliveryId,
|
|
39127
39440
|
completionEmailPendingAt: completion.deliveryPendingAt,
|
|
@@ -39138,6 +39451,7 @@ async function serverUpdate(client2, rest, flags) {
|
|
|
39138
39451
|
runtimeVerification: successfulRuntimeOutput,
|
|
39139
39452
|
caddy,
|
|
39140
39453
|
quickTest,
|
|
39454
|
+
automaticStorageMigration,
|
|
39141
39455
|
completionEmailDelivery: completion.delivery,
|
|
39142
39456
|
completedAt: completion.completedAt
|
|
39143
39457
|
});
|
|
@@ -39294,7 +39608,23 @@ async function serverMonitoring(rest, flags) {
|
|
|
39294
39608
|
let output;
|
|
39295
39609
|
try {
|
|
39296
39610
|
requireDocker();
|
|
39611
|
+
const inventoryRefreshed = refreshStorageRuntimeInventory(
|
|
39612
|
+
installPath,
|
|
39613
|
+
role,
|
|
39614
|
+
getInstallMode(installPath, config),
|
|
39615
|
+
config?.composeProfile === "full"
|
|
39616
|
+
);
|
|
39297
39617
|
output = runRuntimeVerification(installPath, role, config);
|
|
39618
|
+
if (!inventoryRefreshed) {
|
|
39619
|
+
output.checks.push({
|
|
39620
|
+
id: "core.storage_migration_inventory",
|
|
39621
|
+
status: "failed",
|
|
39622
|
+
required: false,
|
|
39623
|
+
duration_ms: 0,
|
|
39624
|
+
failureClass: "configuration",
|
|
39625
|
+
sanitized_reason: "runtime_inventory_refresh_unavailable"
|
|
39626
|
+
});
|
|
39627
|
+
}
|
|
39298
39628
|
} catch (error) {
|
|
39299
39629
|
console.error(`Runtime verifier unavailable: ${error instanceof Error ? error.name : "UnknownError"}`);
|
|
39300
39630
|
output = {
|
|
@@ -40016,8 +40346,8 @@ ${entry.category}:`);
|
|
|
40016
40346
|
if (action === "edit") {
|
|
40017
40347
|
const category = rest[1];
|
|
40018
40348
|
if (category) {
|
|
40019
|
-
const
|
|
40020
|
-
console.error(
|
|
40349
|
+
const keys2 = entries.filter((entry) => entry.category === category).map((entry) => entry.key);
|
|
40350
|
+
console.error(keys2.length ? `Focused ${category} keys: ${keys2.join(", ")}` : `No existing ${category} keys found; opening canonical .env.`);
|
|
40021
40351
|
}
|
|
40022
40352
|
const backupPath = backupEnvFile(installPath);
|
|
40023
40353
|
if (backupPath) console.error(`Backup: ${backupPath}`);
|
|
@@ -40327,10 +40657,10 @@ async function buildCodeRunRequestsFromFlags(flags) {
|
|
|
40327
40657
|
for (const url of toList(flags.url)) {
|
|
40328
40658
|
const response = await fetch(url);
|
|
40329
40659
|
if (!response.ok) throw new Error(`Failed to download Code Run URL ${redactUrl(url)} (HTTP ${response.status})`);
|
|
40330
|
-
const
|
|
40660
|
+
const text6 = await response.text();
|
|
40331
40661
|
const urlPath = new URL(url).pathname;
|
|
40332
40662
|
const sandboxPath = normalizeCodeRunPath(entry || basename3(urlPath) || "main.txt");
|
|
40333
|
-
const buffer = Buffer.from(
|
|
40663
|
+
const buffer = Buffer.from(text6, "utf8");
|
|
40334
40664
|
addFile({
|
|
40335
40665
|
path: sandboxPath,
|
|
40336
40666
|
content_base64: buffer.toString("base64"),
|
|
@@ -40340,9 +40670,9 @@ async function buildCodeRunRequestsFromFlags(flags) {
|
|
|
40340
40670
|
}, buffer.byteLength);
|
|
40341
40671
|
}
|
|
40342
40672
|
if (flags.repo) {
|
|
40343
|
-
await addGithubRepoFiles(flags.repo, toList(flags.include), async (path2,
|
|
40673
|
+
await addGithubRepoFiles(flags.repo, toList(flags.include), async (path2, text6) => {
|
|
40344
40674
|
const sandboxPath = normalizeCodeRunPath(path2);
|
|
40345
|
-
const buffer = Buffer.from(
|
|
40675
|
+
const buffer = Buffer.from(text6, "utf8");
|
|
40346
40676
|
addFile({
|
|
40347
40677
|
path: sandboxPath,
|
|
40348
40678
|
content_base64: buffer.toString("base64"),
|
|
@@ -57970,8 +58300,8 @@ function decodeEmbedContent(content) {
|
|
|
57970
58300
|
}
|
|
57971
58301
|
return parseFlatToonFields(content);
|
|
57972
58302
|
}
|
|
57973
|
-
function stringField3(record8,
|
|
57974
|
-
for (const key of
|
|
58303
|
+
function stringField3(record8, keys2) {
|
|
58304
|
+
for (const key of keys2) {
|
|
57975
58305
|
const value = cleanString(record8[key]);
|
|
57976
58306
|
if (value) return value;
|
|
57977
58307
|
}
|
|
@@ -84359,8 +84689,8 @@ function parseSuites(value) {
|
|
|
84359
84689
|
const suites = value.split(",").map((suite) => suite.trim()).filter(Boolean);
|
|
84360
84690
|
if (suites.includes("all")) return ["quick", "extensive"];
|
|
84361
84691
|
const allowed = /* @__PURE__ */ new Set(["quick", "extensive"]);
|
|
84362
|
-
const
|
|
84363
|
-
if (
|
|
84692
|
+
const invalid2 = suites.filter((suite) => !allowed.has(suite));
|
|
84693
|
+
if (invalid2.length > 0 || suites.length === 0) {
|
|
84364
84694
|
throw new Error("Invalid --suite. Use quick, extensive, or all.");
|
|
84365
84695
|
}
|
|
84366
84696
|
return [...new Set(suites)];
|
|
@@ -84933,13 +85263,13 @@ function parseJudgment(answer) {
|
|
|
84933
85263
|
return { score: null, reason: null };
|
|
84934
85264
|
}
|
|
84935
85265
|
}
|
|
84936
|
-
function extractJsonObject(
|
|
84937
|
-
const fenced =
|
|
85266
|
+
function extractJsonObject(text6) {
|
|
85267
|
+
const fenced = text6.match(/```(?:json)?\s*([\s\S]*?)\s*```/i);
|
|
84938
85268
|
if (fenced) return fenced[1];
|
|
84939
|
-
const start =
|
|
84940
|
-
const end =
|
|
85269
|
+
const start = text6.indexOf("{");
|
|
85270
|
+
const end = text6.lastIndexOf("}");
|
|
84941
85271
|
if (start === -1 || end === -1 || end <= start) return null;
|
|
84942
|
-
return
|
|
85272
|
+
return text6.slice(start, end + 1);
|
|
84943
85273
|
}
|
|
84944
85274
|
function loadPricingForModels(models) {
|
|
84945
85275
|
const availablePricing = loadProviderPricing();
|
|
@@ -84968,21 +85298,21 @@ function loadProviderPricing() {
|
|
|
84968
85298
|
for (const fileName of readdirSync6(providersDir)) {
|
|
84969
85299
|
if (!fileName.endsWith(".yml")) continue;
|
|
84970
85300
|
const filePath = join16(providersDir, fileName);
|
|
84971
|
-
const
|
|
84972
|
-
const provider = parseProviderId(
|
|
84973
|
-
for (const modelPricing of parseModelPricing(
|
|
85301
|
+
const text6 = readFileSync13(filePath, "utf-8");
|
|
85302
|
+
const provider = parseProviderId(text6) ?? fileName.replace(/\.yml$/, "");
|
|
85303
|
+
for (const modelPricing of parseModelPricing(text6, provider)) {
|
|
84974
85304
|
pricing.set(`${modelPricing.provider}/${modelPricing.modelId}`, modelPricing);
|
|
84975
85305
|
pricing.set(modelPricing.modelId, modelPricing);
|
|
84976
85306
|
}
|
|
84977
85307
|
}
|
|
84978
85308
|
return pricing;
|
|
84979
85309
|
}
|
|
84980
|
-
function parseProviderId(
|
|
84981
|
-
const match =
|
|
85310
|
+
function parseProviderId(text6) {
|
|
85311
|
+
const match = text6.match(/^provider_id:\s*["']?([^"'\n]+)["']?/m);
|
|
84982
85312
|
return match?.[1]?.trim() ?? null;
|
|
84983
85313
|
}
|
|
84984
|
-
function parseModelPricing(
|
|
84985
|
-
const lines =
|
|
85314
|
+
function parseModelPricing(text6, provider) {
|
|
85315
|
+
const lines = text6.split("\n");
|
|
84986
85316
|
const results = [];
|
|
84987
85317
|
let modelId = null;
|
|
84988
85318
|
let inModel = false;
|
|
@@ -85544,10 +85874,10 @@ var TuiTerminal = class {
|
|
|
85544
85874
|
const tail = rows2.length < this.height ? `\x1B[${rows2.length + 1};1H\x1B[J` : "";
|
|
85545
85875
|
this.output.write(`\x1B[?2026h${body}${tail}\x1B[?2026l`);
|
|
85546
85876
|
}
|
|
85547
|
-
receiveInput(
|
|
85877
|
+
receiveInput(text6) {
|
|
85548
85878
|
if (this.inputTimer) clearTimeout(this.inputTimer);
|
|
85549
85879
|
this.inputTimer = null;
|
|
85550
|
-
this.pendingInput +=
|
|
85880
|
+
this.pendingInput += text6;
|
|
85551
85881
|
const marker = this.paste ? "\x1B[201~" : "\x1B[200~";
|
|
85552
85882
|
const found = this.pendingInput.indexOf(marker);
|
|
85553
85883
|
if (found >= 0) {
|
|
@@ -85575,10 +85905,10 @@ var TuiTerminal = class {
|
|
|
85575
85905
|
}, 30);
|
|
85576
85906
|
}
|
|
85577
85907
|
/** Consume SGR mouse reports without letting clicks become composer text. */
|
|
85578
|
-
dispatchInput(
|
|
85908
|
+
dispatchInput(text6) {
|
|
85579
85909
|
if (this.mouseTimer) clearTimeout(this.mouseTimer);
|
|
85580
85910
|
this.mouseTimer = null;
|
|
85581
|
-
const input = this.pendingMouse +
|
|
85911
|
+
const input = this.pendingMouse + text6;
|
|
85582
85912
|
this.pendingMouse = "";
|
|
85583
85913
|
let offset = 0;
|
|
85584
85914
|
while (offset < input.length) {
|
|
@@ -85977,25 +86307,25 @@ function wrapCells(value, width) {
|
|
|
85977
86307
|
width = Math.max(1, width);
|
|
85978
86308
|
const result = [];
|
|
85979
86309
|
for (const line of terminalText(value).split("\n")) {
|
|
85980
|
-
let
|
|
86310
|
+
let text6 = "", used = 0;
|
|
85981
86311
|
for (const { segment } of segments.segment(line)) {
|
|
85982
86312
|
const size = graphemeWidth(segment);
|
|
85983
86313
|
if (size > width) {
|
|
85984
|
-
if (
|
|
86314
|
+
if (text6) result.push(text6);
|
|
85985
86315
|
result.push("?");
|
|
85986
|
-
|
|
86316
|
+
text6 = "";
|
|
85987
86317
|
used = 0;
|
|
85988
86318
|
continue;
|
|
85989
86319
|
}
|
|
85990
86320
|
if (used + size > width) {
|
|
85991
|
-
result.push(
|
|
85992
|
-
|
|
86321
|
+
result.push(text6);
|
|
86322
|
+
text6 = "";
|
|
85993
86323
|
used = 0;
|
|
85994
86324
|
}
|
|
85995
|
-
|
|
86325
|
+
text6 += segment;
|
|
85996
86326
|
used += size;
|
|
85997
86327
|
}
|
|
85998
|
-
result.push(
|
|
86328
|
+
result.push(text6);
|
|
85999
86329
|
}
|
|
86000
86330
|
return result;
|
|
86001
86331
|
}
|
|
@@ -86649,8 +86979,8 @@ var NODE_FIELDS = {
|
|
|
86649
86979
|
custom_code: ["code"]
|
|
86650
86980
|
};
|
|
86651
86981
|
function compact(value, max = 80) {
|
|
86652
|
-
const
|
|
86653
|
-
const oneLine3 =
|
|
86982
|
+
const text6 = typeof value === "string" ? value : Array.isArray(value) ? value.map((item) => compact(item, max)).join(", ") : value && typeof value === "object" ? Object.entries(value).map(([key, item]) => `${key.replaceAll("_", " ")}: ${compact(item, max)}`).join(" \xB7 ") : String(value);
|
|
86983
|
+
const oneLine3 = text6.replace(/\s+/g, " ");
|
|
86654
86984
|
return truncateCells(oneLine3, max);
|
|
86655
86985
|
}
|
|
86656
86986
|
function label2(node) {
|
|
@@ -86845,7 +87175,7 @@ function buildWorkflowNodeForm(workflow, node, kind = "workflow-node") {
|
|
|
86845
87175
|
}
|
|
86846
87176
|
return [key];
|
|
86847
87177
|
});
|
|
86848
|
-
const
|
|
87178
|
+
const keys2 = [.../* @__PURE__ */ new Set([...schemaKeys, ...currentKeys])];
|
|
86849
87179
|
return {
|
|
86850
87180
|
kind,
|
|
86851
87181
|
title: `Edit ${label2(node)}`,
|
|
@@ -86853,7 +87183,7 @@ function buildWorkflowNodeForm(workflow, node, kind = "workflow-node") {
|
|
|
86853
87183
|
fieldIndex: 0,
|
|
86854
87184
|
fields: [
|
|
86855
87185
|
{ name: "title", label: "Node title", value: node.title ?? "" },
|
|
86856
|
-
...
|
|
87186
|
+
...keys2.map((key) => {
|
|
86857
87187
|
const value = valueAt(config, key);
|
|
86858
87188
|
return { name: `config.${key}`, label: key.replaceAll("_", " "), value: fieldValue(value), multiline: typeof value === "object" || /(?:message|body|prompt|code)$/i.test(key) };
|
|
86859
87189
|
})
|
|
@@ -87218,8 +87548,8 @@ function tuiChatSidebarRows(state) {
|
|
|
87218
87548
|
group.push(chat);
|
|
87219
87549
|
groups2.set(key, group);
|
|
87220
87550
|
}
|
|
87221
|
-
const
|
|
87222
|
-
for (const key of
|
|
87551
|
+
const keys2 = [...CHAT_TIME_GROUPS.filter((key) => groups2.has(key)), ...[...groups2.keys()].filter((key) => !CHAT_TIME_GROUPS.some((standard) => standard === key))];
|
|
87552
|
+
for (const key of keys2) {
|
|
87223
87553
|
const label3 = { today: "Today", yesterday: "Yesterday", previous_7_days: "Previous 7 days", previous_30_days: "Previous 30 days" }[key] ?? new Date(Number(key.split("_")[1]), Number(key.split("_")[2]) - 1).toLocaleDateString("en", { month: "long", year: "numeric" });
|
|
87224
87554
|
rows2.push({ kind: "section", label: label3 });
|
|
87225
87555
|
rows2.push(...groups2.get(key).map((chat) => ({
|
|
@@ -87413,7 +87743,7 @@ function renderWorkspaceFrame(state, rawWidth, rawHeight, body, options = {}) {
|
|
|
87413
87743
|
const title = state.activeChat?.title && state.workspace === "chats" ? ` \xB7 ${state.activeChat.title}` : "";
|
|
87414
87744
|
const nav = contentWidth >= 90 ? `OpenMates ${labels}${title}` : `OpenMates [${titleCase(state.workspace)}] ${state.sidebarOpen ? "Sidebar open" : "Ctrl+B sidebar"}${title}`;
|
|
87415
87745
|
const inputWidth = Math.max(1, contentWidth - 6);
|
|
87416
|
-
const inputLines = state.input.split("\n").flatMap((
|
|
87746
|
+
const inputLines = state.input.split("\n").flatMap((text6) => wrapCells(text6, inputWidth));
|
|
87417
87747
|
const showComposer = state.workspace !== "apps" || state.focus === "composer" || Boolean(state.input);
|
|
87418
87748
|
const composerRows = showComposer ? Math.min(3, Math.max(1, inputLines.length)) : 0;
|
|
87419
87749
|
const bodyHeight = Math.max(1, height - 2 - (showComposer ? composerRows + 3 : 1));
|
|
@@ -87468,8 +87798,8 @@ function renderWorkspaceFrame(state, rawWidth, rawHeight, body, options = {}) {
|
|
|
87468
87798
|
let remaining = span;
|
|
87469
87799
|
rendered = "";
|
|
87470
87800
|
for (const part of style.spans) {
|
|
87471
|
-
const
|
|
87472
|
-
rendered += part.background ? backgroundLine(
|
|
87801
|
+
const text6 = truncateCells(terminalText(part.text).replace(/\n/g, " "), remaining), size = cells(text6);
|
|
87802
|
+
rendered += part.background ? backgroundLine(text6, size, part.background, mode, part.bold) : text6;
|
|
87473
87803
|
remaining -= size;
|
|
87474
87804
|
if (!remaining) break;
|
|
87475
87805
|
}
|
|
@@ -87486,12 +87816,12 @@ function renderWorkspaceFrame(state, rawWidth, rawHeight, body, options = {}) {
|
|
|
87486
87816
|
const hintColor = state.focus === "composer" ? "#a0a0a0" : "#ff553b";
|
|
87487
87817
|
const composer = [];
|
|
87488
87818
|
if (showComposer) {
|
|
87489
|
-
const inputRows = inputLines.slice(-composerRows).map((
|
|
87490
|
-
if (contentWidth < 6) composer.push(...inputRows.map((
|
|
87819
|
+
const inputRows = inputLines.slice(-composerRows).map((text6, i) => `${i ? " " : "> "}${text6 || (!state.input ? placeholder : "")}`);
|
|
87820
|
+
if (contentWidth < 6) composer.push(...inputRows.map((text6) => place(padCells(text6, contentWidth))), place(foreground(padCells(hint, contentWidth), hintColor, mode)), place(" ".repeat(contentWidth)), place(" ".repeat(contentWidth)));
|
|
87491
87821
|
else {
|
|
87492
87822
|
const edge = (left, right) => place(foreground(left + line.repeat(contentWidth - 2) + right, "#6b6b6b", mode));
|
|
87493
|
-
const inputRow = (
|
|
87494
|
-
composer.push(edge(ascii ? "+" : "\u256D", ascii ? "+" : "\u256E"), ...inputRows.map((
|
|
87823
|
+
const inputRow = (text6, color) => place(foreground(vertical, "#6b6b6b", mode) + " " + foreground(padCells(text6, contentWidth - 4), color ?? "#e6e6e6", mode) + " " + foreground(vertical, "#6b6b6b", mode));
|
|
87824
|
+
composer.push(edge(ascii ? "+" : "\u256D", ascii ? "+" : "\u256E"), ...inputRows.map((text6) => inputRow(text6)), inputRow(hint, hintColor), edge(ascii ? "+" : "\u2570", ascii ? "+" : "\u256F"));
|
|
87495
87825
|
}
|
|
87496
87826
|
}
|
|
87497
87827
|
const frame = [
|
|
@@ -87543,8 +87873,8 @@ function renderCardCarousel(cards, width, selectedIndex, focused) {
|
|
|
87543
87873
|
return { text: spans.map((span) => span.text).join(""), spans };
|
|
87544
87874
|
});
|
|
87545
87875
|
}
|
|
87546
|
-
function centeredCarouselText(
|
|
87547
|
-
const value = truncateCells(
|
|
87876
|
+
function centeredCarouselText(text6, width) {
|
|
87877
|
+
const value = truncateCells(text6, width);
|
|
87548
87878
|
return " ".repeat(Math.max(0, Math.floor((width - cells(value)) / 2))) + value;
|
|
87549
87879
|
}
|
|
87550
87880
|
|
|
@@ -87824,7 +88154,7 @@ function homeHeader(state, width, height) {
|
|
|
87824
88154
|
const title = inspiration?.feature?.title || inspiration?.title || "Daily inspiration";
|
|
87825
88155
|
const banner = [centered2(`DAILY INSPIRATION ${state.focus === "inspiration" ? "\u2039 Enter open \u203A" : "\u2039 Ctrl+O explore \u203A"}`, width), "", ...parts.map((line) => centered2(line, width)), centered2(title, width)];
|
|
87826
88156
|
while (banner.length < rows2) banner.push("");
|
|
87827
|
-
banner.forEach((
|
|
88157
|
+
banner.forEach((text6) => result.push({ text: text6, background: gradient.start }));
|
|
87828
88158
|
result.push("", { text: centered2(state.workspace === "apps" ? prompts.apps : state.username ? `Hey ${state.username}!` : "Hey there!", width), bold: true });
|
|
87829
88159
|
if (state.workspace !== "chats" || !homeChatItems(state).length) result.push({ text: centered2(state.workspace === "apps" ? "Use your apps directly and return to saved results." : prompts[state.workspace], width), color: "#cfcfcf" });
|
|
87830
88160
|
result.push("");
|
|
@@ -87860,14 +88190,14 @@ function renderHomeChatCards(state, width, height) {
|
|
|
87860
88190
|
import { randomBytes as randomBytes10, randomUUID as randomUUID18 } from "crypto";
|
|
87861
88191
|
|
|
87862
88192
|
// ../ui/src/components/apps/appsSkillFormUtils.ts
|
|
87863
|
-
var
|
|
88193
|
+
var object2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
87864
88194
|
var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
87865
88195
|
var pathParts = (path2) => path2.split(".").filter(Boolean).map((part) => part.endsWith("[]") ? part.slice(0, -2) : part);
|
|
87866
88196
|
function resolveSkillSchema(schema, root, seen = /* @__PURE__ */ new Set()) {
|
|
87867
88197
|
if (schema.$ref) {
|
|
87868
88198
|
const reference = schema.$ref;
|
|
87869
88199
|
if (!reference.startsWith("#/") || seen.has(reference)) return schema;
|
|
87870
|
-
const resolved = reference.slice(2).split("/").reduce((value, part) =>
|
|
88200
|
+
const resolved = reference.slice(2).split("/").reduce((value, part) => object2(value)[part.replace(/~1/g, "/").replace(/~0/g, "~")], root);
|
|
87871
88201
|
if (!resolved || typeof resolved !== "object") return schema;
|
|
87872
88202
|
return resolveSkillSchema({ ...resolved, ...schema, $ref: void 0 }, root, /* @__PURE__ */ new Set([...Array.from(seen), reference]));
|
|
87873
88203
|
}
|
|
@@ -87881,7 +88211,7 @@ function resolveSkillSchema(schema, root, seen = /* @__PURE__ */ new Set()) {
|
|
|
87881
88211
|
function getSkillPath(input, path2) {
|
|
87882
88212
|
let cursor = input;
|
|
87883
88213
|
for (const part of path2.split(".").filter(Boolean)) {
|
|
87884
|
-
cursor =
|
|
88214
|
+
cursor = object2(cursor)[part.replace(/\[\]$/, "")];
|
|
87885
88215
|
if (part.endsWith("[]")) cursor = Array.isArray(cursor) ? cursor[0] : void 0;
|
|
87886
88216
|
}
|
|
87887
88217
|
return cursor;
|
|
@@ -87892,7 +88222,7 @@ function setSkillPath(input, path2, value) {
|
|
|
87892
88222
|
if (index === parts.length) return value;
|
|
87893
88223
|
const part = parts[index];
|
|
87894
88224
|
const key = part.replace(/\[\]$/, "");
|
|
87895
|
-
const parent = { ...
|
|
88225
|
+
const parent = { ...object2(current) };
|
|
87896
88226
|
if (part.endsWith("[]")) {
|
|
87897
88227
|
const entries = Array.isArray(parent[key]) ? [...parent[key]] : [];
|
|
87898
88228
|
entries[0] = update(entries[0], index + 1);
|
|
@@ -87915,17 +88245,17 @@ function prepareSkillInput(schema, input, timezone, now = /* @__PURE__ */ new Da
|
|
|
87915
88245
|
const isoDate = (ordinal) => new Date(ordinal * 864e5).toISOString().slice(0, 10);
|
|
87916
88246
|
function walk(node, value) {
|
|
87917
88247
|
const resolved = resolveSkillSchema(node, schema);
|
|
87918
|
-
const token =
|
|
88248
|
+
const token = object2(value).$date;
|
|
87919
88249
|
if (typeof token === "string") {
|
|
87920
88250
|
const weekday = (new Date(today * 864e5).getUTCDay() + 6) % 7;
|
|
87921
88251
|
const ordinal = token === "today" || token === "today_end" || token === "next_seven_days_start" ? today : token === "next_seven_days_end" ? today + 6 : token === "next_week_start" ? today + 7 - weekday : token === "next_week_end" ? today + 13 - weekday : null;
|
|
87922
88252
|
if (ordinal === null) return value;
|
|
87923
88253
|
const date = isoDate(ordinal);
|
|
87924
|
-
return
|
|
88254
|
+
return object2(value).format === "datetime" || resolved.format === "date-time" ? `${date}T${token.endsWith("_end") ? "23:59:59" : "00:00:00"}[${timezone}]` : date;
|
|
87925
88255
|
}
|
|
87926
88256
|
if (resolved.type === "array" && Array.isArray(value)) return value.map((item) => walk(resolved.items ?? {}, item));
|
|
87927
88257
|
if ((resolved.type === "object" || resolved.properties) && value && typeof value === "object" && !Array.isArray(value)) {
|
|
87928
|
-
const prepared = { ...
|
|
88258
|
+
const prepared = { ...object2(value) };
|
|
87929
88259
|
for (const [name, child] of Object.entries(resolved.properties ?? {})) {
|
|
87930
88260
|
if (own(prepared, name)) prepared[name] = walk(child, prepared[name]);
|
|
87931
88261
|
}
|
|
@@ -87958,7 +88288,7 @@ function validateSkillInput(schema, input) {
|
|
|
87958
88288
|
issues.push({ path: path2, code: "type" });
|
|
87959
88289
|
return;
|
|
87960
88290
|
}
|
|
87961
|
-
for (const [name, child] of Object.entries(field.properties ?? {})) walk(child,
|
|
88291
|
+
for (const [name, child] of Object.entries(field.properties ?? {})) walk(child, object2(value)[name], path2 ? `${path2}.${name}` : name, (field.required ?? []).includes(name));
|
|
87962
88292
|
} else if (field.type === "array") {
|
|
87963
88293
|
if (!Array.isArray(value)) {
|
|
87964
88294
|
issues.push({ path: path2, code: "type" });
|
|
@@ -88505,21 +88835,21 @@ function embedPreview(embedId, type, content, appId, skillId, action, width) {
|
|
|
88505
88835
|
}
|
|
88506
88836
|
function readableFields(value, width) {
|
|
88507
88837
|
const lines = [];
|
|
88508
|
-
function
|
|
88838
|
+
function visit2(label3, item, indent) {
|
|
88509
88839
|
if (Array.isArray(item)) {
|
|
88510
88840
|
lines.push(`${indent}${label3} (${item.length})`);
|
|
88511
|
-
item.forEach((entry, index) =>
|
|
88841
|
+
item.forEach((entry, index) => visit2(`${index + 1}.`, entry, `${indent} `));
|
|
88512
88842
|
} else if (item && typeof item === "object") {
|
|
88513
88843
|
lines.push(`${indent}${label3}`);
|
|
88514
|
-
for (const [key, entry] of Object.entries(item))
|
|
88844
|
+
for (const [key, entry] of Object.entries(item)) visit2(readableLabel(key), entry, `${indent} `);
|
|
88515
88845
|
} else {
|
|
88516
|
-
const
|
|
88517
|
-
const [first = "", ...rest] =
|
|
88846
|
+
const text6 = item === null ? "None" : typeof item === "boolean" ? item ? "Yes" : "No" : String(item);
|
|
88847
|
+
const [first = "", ...rest] = text6.split("\n");
|
|
88518
88848
|
lines.push(`${indent}${label3} ${first}`);
|
|
88519
88849
|
lines.push(...rest.map((line) => `${indent} ${line}`));
|
|
88520
88850
|
}
|
|
88521
88851
|
}
|
|
88522
|
-
for (const [key, item] of Object.entries(value))
|
|
88852
|
+
for (const [key, item] of Object.entries(value)) visit2(`${readableLabel(key)}:`, item, "");
|
|
88523
88853
|
return lines.flatMap((line) => textLines(line, width));
|
|
88524
88854
|
}
|
|
88525
88855
|
function readableLabel(key) {
|
|
@@ -88714,7 +89044,7 @@ function renderTuiFrame(state, width, height, options = {}) {
|
|
|
88714
89044
|
return renderWorkspaceFrame(state, width, height, renderBody(state, bodyWidth, height), { ...options, stickyRows, headerRows: state.screen === "chat" || state.screen === "example" ? renderChatHeader(state, bodyWidth).length : void 0 });
|
|
88715
89045
|
}
|
|
88716
89046
|
function coloredHero(lines, rows2, gradient = PRIMARY_GRADIENT) {
|
|
88717
|
-
return lines.map((
|
|
89047
|
+
return lines.map((text6, index) => index < rows2 ? { text: text6, background: gradient.start } : text6);
|
|
88718
89048
|
}
|
|
88719
89049
|
var blueHero = (lines, rows2) => coloredHero(lines, rows2);
|
|
88720
89050
|
function homeCards(lines, width, gradients) {
|
|
@@ -88726,7 +89056,7 @@ function homeCards(lines, width, gradients) {
|
|
|
88726
89056
|
}
|
|
88727
89057
|
return groups.filter((group) => group.length).flatMap((group, index) => {
|
|
88728
89058
|
const cardWidth = Math.min(width, Math.max(...group.map(cells))), inset = Math.max(0, Math.floor((width - cardWidth) / 2));
|
|
88729
|
-
return [...group.map((
|
|
89059
|
+
return [...group.map((text6) => ({ text: text6, background: (gradients[index] ?? PRIMARY_GRADIENT).start, inset })), ""];
|
|
88730
89060
|
});
|
|
88731
89061
|
}
|
|
88732
89062
|
function renderBody(state, width, height) {
|
|
@@ -89080,9 +89410,9 @@ function required(value) {
|
|
|
89080
89410
|
return value;
|
|
89081
89411
|
}
|
|
89082
89412
|
function authoringReplacementPatch(path2, original, content) {
|
|
89083
|
-
const lines = (
|
|
89084
|
-
if (!
|
|
89085
|
-
const parts =
|
|
89413
|
+
const lines = (text6, prefix) => {
|
|
89414
|
+
if (!text6) return { count: 0, rows: [] };
|
|
89415
|
+
const parts = text6.split("\n");
|
|
89086
89416
|
const newline = parts.at(-1) === "";
|
|
89087
89417
|
if (newline) parts.pop();
|
|
89088
89418
|
const rows2 = parts.map((line) => prefix + line);
|
|
@@ -89187,8 +89517,8 @@ async function persistCliProjectAuthoringJob(client2, job, approvedDigest) {
|
|
|
89187
89517
|
for (const row of detail.items) {
|
|
89188
89518
|
if (!["embed", "upload"].includes(row.item_type) || row.deleted_target_state) continue;
|
|
89189
89519
|
const target = await decryptWithAesGcmCombined(row.target_id_encrypted, projectKey);
|
|
89190
|
-
const
|
|
89191
|
-
const meta =
|
|
89520
|
+
const text6 = row.encrypted_metadata ? await decryptWithAesGcmCombined(row.encrypted_metadata, projectKey) : null;
|
|
89521
|
+
const meta = text6 ? record6(JSON.parse(text6)) : {};
|
|
89192
89522
|
const filePath = meta.path ?? meta.file_path ?? meta.filename ?? meta.display_path;
|
|
89193
89523
|
if (target && typeof filePath === "string") files.push({ embedId: target, path: filePath });
|
|
89194
89524
|
}
|
|
@@ -89869,8 +90199,8 @@ async function handleWorkspaceCommand(context, command) {
|
|
|
89869
90199
|
if (request !== state.routeVersion) return true;
|
|
89870
90200
|
state.detailTitle = embed.textPreview || (embed.appId ? `${embed.appId}${embed.skillId ? `/${embed.skillId}` : ""}` : embed.type?.replaceAll("_", " ")) || "Embed";
|
|
89871
90201
|
const body = embed.content;
|
|
89872
|
-
const
|
|
89873
|
-
state.detailLines = typeof
|
|
90202
|
+
const text6 = ["code", "markdown", "content", "text", "transcript"].map((key) => body?.[key]).find((value) => typeof value === "string");
|
|
90203
|
+
state.detailLines = typeof text6 === "string" ? text6.split("\n") : formatEmbedPreviewLines(embed, 100);
|
|
89874
90204
|
}
|
|
89875
90205
|
render();
|
|
89876
90206
|
return true;
|
|
@@ -90369,10 +90699,10 @@ async function handleWorkspaceKey(context, chunk, key) {
|
|
|
90369
90699
|
state.filter = "";
|
|
90370
90700
|
}
|
|
90371
90701
|
} else if (file) {
|
|
90372
|
-
const
|
|
90702
|
+
const text6 = await readTuiProjectFile(context.client, project, file);
|
|
90373
90703
|
if (request === state.routeVersion && state.activeProject?.id === project.id) {
|
|
90374
90704
|
state.detailTitle = file.name;
|
|
90375
|
-
state.detailLines =
|
|
90705
|
+
state.detailLines = text6.split("\n");
|
|
90376
90706
|
state.screen = "embed";
|
|
90377
90707
|
state.scrollOffset = 0;
|
|
90378
90708
|
}
|
|
@@ -90457,9 +90787,9 @@ async function handleWorkspaceKey(context, chunk, key) {
|
|
|
90457
90787
|
return true;
|
|
90458
90788
|
}
|
|
90459
90789
|
if (key.name === "return" && state.screen === "chats" && state.input.trim()) {
|
|
90460
|
-
const
|
|
90790
|
+
const text6 = state.input.trim();
|
|
90461
90791
|
newChat(state);
|
|
90462
|
-
await context.send(
|
|
90792
|
+
await context.send(text6);
|
|
90463
90793
|
return true;
|
|
90464
90794
|
}
|
|
90465
90795
|
const cursor = state.inputCursor ?? state.input.length;
|
|
@@ -90501,9 +90831,9 @@ async function handleWorkspaceKey(context, chunk, key) {
|
|
|
90501
90831
|
return true;
|
|
90502
90832
|
}
|
|
90503
90833
|
if (key.name === "paste" || !key.ctrl && !key.meta && chunk && chunk >= " ") {
|
|
90504
|
-
const
|
|
90505
|
-
state.input = state.input.slice(0, cursor) +
|
|
90506
|
-
state.inputCursor = cursor +
|
|
90834
|
+
const text6 = terminalText(chunk);
|
|
90835
|
+
state.input = state.input.slice(0, cursor) + text6 + state.input.slice(cursor);
|
|
90836
|
+
state.inputCursor = cursor + text6.length;
|
|
90507
90837
|
rememberDraft(state);
|
|
90508
90838
|
render();
|
|
90509
90839
|
return true;
|
|
@@ -90884,13 +91214,13 @@ async function handleEnter(params) {
|
|
|
90884
91214
|
render();
|
|
90885
91215
|
return;
|
|
90886
91216
|
}
|
|
90887
|
-
const
|
|
90888
|
-
if (!
|
|
90889
|
-
if (
|
|
90890
|
-
await handleCommand({ command:
|
|
91217
|
+
const text6 = state.input.trim();
|
|
91218
|
+
if (!text6) return;
|
|
91219
|
+
if (text6.startsWith("/")) {
|
|
91220
|
+
await handleCommand({ command: text6, state, client: client2, terminal, render, finish });
|
|
90891
91221
|
return;
|
|
90892
91222
|
}
|
|
90893
|
-
await sendTuiMessage({ message:
|
|
91223
|
+
await sendTuiMessage({ message: text6, state, client: client2, render });
|
|
90894
91224
|
}
|
|
90895
91225
|
async function handleCommand(params) {
|
|
90896
91226
|
const { command, state, client: client2, terminal, render, finish } = params;
|
|
@@ -95138,11 +95468,11 @@ function validateSummary(value) {
|
|
|
95138
95468
|
if (item.protocol_version !== 1) throw new Error("Invalid remote command protocol version");
|
|
95139
95469
|
return {
|
|
95140
95470
|
protocol_version: 1,
|
|
95141
|
-
execution_id:
|
|
95142
|
-
chat_id:
|
|
95143
|
-
project_id:
|
|
95144
|
-
source_id:
|
|
95145
|
-
state:
|
|
95471
|
+
execution_id: identifier4(item.execution_id, "execution_id"),
|
|
95472
|
+
chat_id: identifier4(item.chat_id, "chat_id"),
|
|
95473
|
+
project_id: identifier4(item.project_id, "project_id"),
|
|
95474
|
+
source_id: identifier4(item.source_id, "source_id"),
|
|
95475
|
+
state: text5(item.state, "state"),
|
|
95146
95476
|
last_sequence: integer3(item.last_sequence ?? -1, "last_sequence", -1),
|
|
95147
95477
|
lease_expires_at: integer3(item.lease_expires_at ?? 0, "lease_expires_at", 0)
|
|
95148
95478
|
};
|
|
@@ -95154,16 +95484,16 @@ function validateClaimedRequest(value, summary, binding, sourceSessionId) {
|
|
|
95154
95484
|
return {
|
|
95155
95485
|
...item,
|
|
95156
95486
|
protocol_version: 1,
|
|
95157
|
-
execution_id:
|
|
95158
|
-
chat_id:
|
|
95159
|
-
project_id:
|
|
95160
|
-
source_id:
|
|
95161
|
-
state:
|
|
95162
|
-
encrypted_request:
|
|
95163
|
-
request_digest:
|
|
95487
|
+
execution_id: identifier4(item.execution_id, "execution_id"),
|
|
95488
|
+
chat_id: identifier4(item.chat_id, "chat_id"),
|
|
95489
|
+
project_id: identifier4(item.project_id, "project_id"),
|
|
95490
|
+
source_id: identifier4(item.source_id, "source_id"),
|
|
95491
|
+
state: text5(item.state, "state"),
|
|
95492
|
+
encrypted_request: text5(item.encrypted_request, "encrypted_request"),
|
|
95493
|
+
request_digest: text5(item.request_digest, "request_digest"),
|
|
95164
95494
|
approval,
|
|
95165
95495
|
key_epoch: integer3(item.key_epoch, "key_epoch", 1),
|
|
95166
|
-
lease_token:
|
|
95496
|
+
lease_token: text5(item.lease_token, "lease_token"),
|
|
95167
95497
|
lease_generation: integer3(item.lease_generation, "lease_generation", 1),
|
|
95168
95498
|
lease_expires_at: integer3(item.lease_expires_at, "lease_expires_at", 1),
|
|
95169
95499
|
last_sequence: integer3(item.last_sequence ?? -1, "last_sequence", -1),
|
|
@@ -95176,7 +95506,7 @@ function validateLeaseResponse(value, executionId) {
|
|
|
95176
95506
|
return {
|
|
95177
95507
|
...item,
|
|
95178
95508
|
execution_id: executionId,
|
|
95179
|
-
lease_token:
|
|
95509
|
+
lease_token: text5(item.lease_token, "lease_token"),
|
|
95180
95510
|
lease_generation: integer3(item.lease_generation, "lease_generation", 1),
|
|
95181
95511
|
lease_expires_at: integer3(item.lease_expires_at, "lease_expires_at", 1),
|
|
95182
95512
|
last_sequence: integer3(item.last_sequence ?? -1, "last_sequence", -1),
|
|
@@ -95191,10 +95521,10 @@ function parsePortableRequest(plaintext) {
|
|
|
95191
95521
|
const policy = parsePolicy(item.policy);
|
|
95192
95522
|
const request = {
|
|
95193
95523
|
protocol_version: 1,
|
|
95194
|
-
execution_id:
|
|
95195
|
-
chat_id:
|
|
95196
|
-
project_id:
|
|
95197
|
-
source_id:
|
|
95524
|
+
execution_id: identifier4(item.execution_id, "execution_id"),
|
|
95525
|
+
chat_id: identifier4(item.chat_id, "chat_id"),
|
|
95526
|
+
project_id: identifier4(item.project_id, "project_id"),
|
|
95527
|
+
source_id: identifier4(item.source_id, "source_id"),
|
|
95198
95528
|
policy,
|
|
95199
95529
|
approval: parseApproval(item.approval)
|
|
95200
95530
|
};
|
|
@@ -95220,12 +95550,12 @@ function parsePolicy(value) {
|
|
|
95220
95550
|
if (!Array.isArray(policy.credential_profiles) || policy.credential_profiles.some((item) => typeof item !== "string")) throw new Error("Invalid credential profiles");
|
|
95221
95551
|
return {
|
|
95222
95552
|
argv: [...policy.argv],
|
|
95223
|
-
cwd:
|
|
95553
|
+
cwd: text5(policy.cwd, "cwd"),
|
|
95224
95554
|
mode: oneOf3(policy.mode, ["foreground", "background"], "mode"),
|
|
95225
95555
|
source_access: oneOf3(policy.source_access, ["read_only", "read_write"], "source_access"),
|
|
95226
95556
|
deadline_ms: integer3(policy.deadline_ms, "deadline_ms", 100),
|
|
95227
95557
|
writable_profiles: [...policy.writable_profiles],
|
|
95228
|
-
network_profile: policy.network_profile === null ? null :
|
|
95558
|
+
network_profile: policy.network_profile === null ? null : text5(policy.network_profile, "network_profile"),
|
|
95229
95559
|
credential_profiles: [...policy.credential_profiles]
|
|
95230
95560
|
};
|
|
95231
95561
|
}
|
|
@@ -95239,7 +95569,7 @@ function parseApproval(value) {
|
|
|
95239
95569
|
if (approval.kind !== "preset" || typeof approval.definition_digest !== "string" || !/^[a-f0-9]{64}$/i.test(approval.definition_digest)) throw new Error("Invalid preset approval");
|
|
95240
95570
|
return {
|
|
95241
95571
|
kind: "preset",
|
|
95242
|
-
preset_id:
|
|
95572
|
+
preset_id: identifier4(approval.preset_id, "preset_id"),
|
|
95243
95573
|
definition_digest: approval.definition_digest
|
|
95244
95574
|
};
|
|
95245
95575
|
}
|
|
@@ -95254,16 +95584,16 @@ function validateTrustedGrants(value) {
|
|
|
95254
95584
|
}
|
|
95255
95585
|
const result = {
|
|
95256
95586
|
writable_targets: value.writable_targets.map((item) => ({
|
|
95257
|
-
profile_id:
|
|
95258
|
-
host_path:
|
|
95587
|
+
profile_id: identifier4(item.profile_id, "writable profile"),
|
|
95588
|
+
host_path: text5(item.host_path, "writable host path")
|
|
95259
95589
|
})),
|
|
95260
95590
|
network_profiles: value.network_profiles.map((item) => {
|
|
95261
95591
|
if (!Array.isArray(item.destinations) || item.destinations.some((destination) => typeof destination !== "string")) {
|
|
95262
95592
|
throw new RemoteCommandError("resource_not_granted", "Trusted network grant is invalid");
|
|
95263
95593
|
}
|
|
95264
95594
|
return {
|
|
95265
|
-
profile_id:
|
|
95266
|
-
destinations: item.destinations.map((destination) =>
|
|
95595
|
+
profile_id: identifier4(item.profile_id, "network profile"),
|
|
95596
|
+
destinations: item.destinations.map((destination) => text5(destination, "network destination"))
|
|
95267
95597
|
};
|
|
95268
95598
|
}),
|
|
95269
95599
|
credential_profiles: value.credential_profiles.map((item) => {
|
|
@@ -95271,7 +95601,7 @@ function validateTrustedGrants(value) {
|
|
|
95271
95601
|
throw new RemoteCommandError("credential_unavailable", "Trusted credential grant is invalid");
|
|
95272
95602
|
}
|
|
95273
95603
|
return {
|
|
95274
|
-
profile_id:
|
|
95604
|
+
profile_id: identifier4(item.profile_id, "credential profile"),
|
|
95275
95605
|
environment: { ...item.environment }
|
|
95276
95606
|
};
|
|
95277
95607
|
})
|
|
@@ -95347,14 +95677,14 @@ function record7(value, context) {
|
|
|
95347
95677
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`Invalid ${context}`);
|
|
95348
95678
|
return value;
|
|
95349
95679
|
}
|
|
95350
|
-
function exactKeys2(value,
|
|
95351
|
-
if (Object.keys(value).length !==
|
|
95680
|
+
function exactKeys2(value, keys2) {
|
|
95681
|
+
if (Object.keys(value).length !== keys2.length || Object.keys(value).some((key) => !keys2.includes(key))) throw new Error("Remote command request contains unexpected fields");
|
|
95352
95682
|
}
|
|
95353
|
-
function
|
|
95683
|
+
function identifier4(value, context) {
|
|
95354
95684
|
if (typeof value !== "string" || !IDENTIFIER3.test(value)) throw new Error(`Invalid ${context}`);
|
|
95355
95685
|
return value;
|
|
95356
95686
|
}
|
|
95357
|
-
function
|
|
95687
|
+
function text5(value, context) {
|
|
95358
95688
|
if (typeof value !== "string" || !value || value.length > 1048576 || value.includes("\0")) throw new Error(`Invalid ${context}`);
|
|
95359
95689
|
return value;
|
|
95360
95690
|
}
|
|
@@ -95436,7 +95766,7 @@ function resolveRemoteAccessRoots(pathFlag, cwd = process.cwd()) {
|
|
|
95436
95766
|
function discoverRemoteAccessRepositories(roots) {
|
|
95437
95767
|
const repositoryRoots = /* @__PURE__ */ new Set();
|
|
95438
95768
|
const permissionDenied = [];
|
|
95439
|
-
const
|
|
95769
|
+
const visit2 = (directory, approvedRoot) => {
|
|
95440
95770
|
let entries;
|
|
95441
95771
|
try {
|
|
95442
95772
|
entries = readdirSync12(directory, { withFileTypes: true });
|
|
@@ -95453,10 +95783,10 @@ function discoverRemoteAccessRepositories(roots) {
|
|
|
95453
95783
|
}
|
|
95454
95784
|
for (const entry of entries) {
|
|
95455
95785
|
if (entry.name === ".git" || entry.isSymbolicLink() || !entry.isDirectory()) continue;
|
|
95456
|
-
|
|
95786
|
+
visit2(join25(directory, entry.name), approvedRoot);
|
|
95457
95787
|
}
|
|
95458
95788
|
};
|
|
95459
|
-
for (const root of roots)
|
|
95789
|
+
for (const root of roots) visit2(root, root);
|
|
95460
95790
|
return {
|
|
95461
95791
|
repositories: [...repositoryRoots].sort().map((rootPath) => ({ rootPath, displayName: rootPath.split(/[\\/]/).filter(Boolean).pop() ?? rootPath })),
|
|
95462
95792
|
permissionDenied: permissionDenied.sort()
|
|
@@ -97178,15 +97508,15 @@ function validateWorkRecoveryDocument(value) {
|
|
|
97178
97508
|
}
|
|
97179
97509
|
const visiting = /* @__PURE__ */ new Set();
|
|
97180
97510
|
const visited = /* @__PURE__ */ new Set();
|
|
97181
|
-
const
|
|
97511
|
+
const visit2 = (node) => {
|
|
97182
97512
|
if (visiting.has(node)) throw new Error(`Work recovery dependency cycle includes ${node}.`);
|
|
97183
97513
|
if (visited.has(node)) return;
|
|
97184
97514
|
visiting.add(node);
|
|
97185
|
-
for (const next of graph.get(node) ?? [])
|
|
97515
|
+
for (const next of graph.get(node) ?? []) visit2(next);
|
|
97186
97516
|
visiting.delete(node);
|
|
97187
97517
|
visited.add(node);
|
|
97188
97518
|
};
|
|
97189
|
-
for (const node of graph.keys())
|
|
97519
|
+
for (const node of graph.keys()) visit2(node);
|
|
97190
97520
|
}
|
|
97191
97521
|
function findRecoveryConflicts(document, projectId, current) {
|
|
97192
97522
|
if (document.project.project_id !== projectId) return [{ kind: "plan", id: document.project.project_id, reason: "wrong_project" }];
|
|
@@ -99364,10 +99694,10 @@ async function handlePlans(client2, subcommand, rest, flags, redactor) {
|
|
|
99364
99694
|
else console.log(`Plan success criterion updated: ${updated.criterion_id}`);
|
|
99365
99695
|
return;
|
|
99366
99696
|
}
|
|
99367
|
-
const
|
|
99697
|
+
const text6 = requiredStringFlag(flags.text ?? rest.slice(2).join(" "), "--text <criterion>");
|
|
99368
99698
|
const criterion = await buildCreatePlanCriterionInput(plan, masterKey, {
|
|
99369
99699
|
criterionId: typeof flags.id === "string" ? flags.id : void 0,
|
|
99370
|
-
text:
|
|
99700
|
+
text: text6,
|
|
99371
99701
|
type: typeof flags.type === "string" ? flags.type : void 0,
|
|
99372
99702
|
status: typeof flags.status === "string" ? flags.status : void 0,
|
|
99373
99703
|
required: flags.required === true ? true : flags.optional === true ? false : void 0,
|
|
@@ -99642,7 +99972,7 @@ async function handleWorkRecovery(client2, subcommand, rest, flags) {
|
|
|
99642
99972
|
if (subcommand === "validate" || subcommand === "restore") {
|
|
99643
99973
|
const path2 = requiredStringFlag(flags.file ?? rest[0], "--file <projection.yml>");
|
|
99644
99974
|
if (!existsSync24(path2)) throw new Error(`Recovery projection does not exist: ${path2}`);
|
|
99645
|
-
const document =
|
|
99975
|
+
const document = parseYaml(readFileSync22(path2, "utf8"));
|
|
99646
99976
|
validateWorkRecoveryDocument(document);
|
|
99647
99977
|
if (subcommand === "validate") {
|
|
99648
99978
|
if (flags.json === true) printJson2({ valid: true });
|
|
@@ -101130,8 +101460,8 @@ function taskAssignFlag(flags) {
|
|
|
101130
101460
|
return typeof flags.assign === "string" ? flags.assign : typeof flags.assignee === "string" ? flags.assignee : void 0;
|
|
101131
101461
|
}
|
|
101132
101462
|
function labelFlags(flags, ...names) {
|
|
101133
|
-
const
|
|
101134
|
-
return normalizeLabels(
|
|
101463
|
+
const keys2 = names.length > 0 ? names : ["label", "labels", "tag", "tags"];
|
|
101464
|
+
return normalizeLabels(keys2.flatMap((key) => splitCsvFlag(flags[key])));
|
|
101135
101465
|
}
|
|
101136
101466
|
async function handleRemoteAccess(client2, subcommand, rest, flags) {
|
|
101137
101467
|
if (!subcommand || subcommand === "help" || flags.help === true) {
|
|
@@ -101540,11 +101870,11 @@ async function handleIdeaBucket(client2, subcommand, rest, flags) {
|
|
|
101540
101870
|
return;
|
|
101541
101871
|
}
|
|
101542
101872
|
if (subcommand === "add") {
|
|
101543
|
-
const
|
|
101544
|
-
if (!
|
|
101873
|
+
const text6 = rest.join(" ").trim();
|
|
101874
|
+
if (!text6) throw new Error("Missing IdeaBucket text for add.");
|
|
101545
101875
|
const scheduledSendAt = typeof flags["scheduled-at"] === "string" ? parseUnixSecondsFlag(flags["scheduled-at"], "--scheduled-at") : void 0;
|
|
101546
101876
|
printJson2(await client2.addIdeaBucketText({
|
|
101547
|
-
text:
|
|
101877
|
+
text: text6,
|
|
101548
101878
|
chatId: typeof flags.chat === "string" ? flags.chat : void 0,
|
|
101549
101879
|
bucketId: typeof flags.bucket === "string" ? flags.bucket : void 0,
|
|
101550
101880
|
scheduledSendAt,
|
|
@@ -101638,11 +101968,11 @@ function renderRemoteCommandEvent(event) {
|
|
|
101638
101968
|
if (event.event_kind === "output") {
|
|
101639
101969
|
const raw = typeof event.payload.text === "string" ? event.payload.text : "";
|
|
101640
101970
|
const limit = 24e3;
|
|
101641
|
-
const
|
|
101971
|
+
const text6 = escapeTerminalControls(raw.slice(0, limit));
|
|
101642
101972
|
const omitted = raw.length > limit ? `
|
|
101643
101973
|
[${raw.length - limit} characters omitted from this display]` : "";
|
|
101644
101974
|
return `Unreviewed command output (inert) ${identity2}:
|
|
101645
|
-
${
|
|
101975
|
+
${text6}${omitted}`;
|
|
101646
101976
|
}
|
|
101647
101977
|
if (event.event_kind === "output_truncated") {
|
|
101648
101978
|
return `Command output was truncated upstream (${identity2}); displayed output does not cover the full process transcript.`;
|
|
@@ -101656,9 +101986,9 @@ ${text5}${omitted}`;
|
|
|
101656
101986
|
var EXPLICIT_PROJECT_MENTION = /@project:([A-Za-z0-9](?:[A-Za-z0-9_-]|\.(?=[A-Za-z0-9]))*)/gi;
|
|
101657
101987
|
function extractExplicitProjectMentions(message) {
|
|
101658
101988
|
const matches2 = Array.from(message.matchAll(EXPLICIT_PROJECT_MENTION), (match) => match[1]);
|
|
101659
|
-
const
|
|
101660
|
-
for (const target of matches2)
|
|
101661
|
-
return [...
|
|
101989
|
+
const unique3 = /* @__PURE__ */ new Map();
|
|
101990
|
+
for (const target of matches2) unique3.set(target.toLocaleLowerCase("en-US"), target);
|
|
101991
|
+
return [...unique3.values()];
|
|
101662
101992
|
}
|
|
101663
101993
|
async function resolveExplicitChatProject(client2, masterKey, message, flags, context) {
|
|
101664
101994
|
const mentions = extractExplicitProjectMentions(message);
|
|
@@ -102321,19 +102651,19 @@ ${deleted}/${resolved.length} chat(s) deleted.`);
|
|
|
102321
102651
|
if (embed.type === "app_skill_use" && embed.appId === "videos" && (embed.skillId === "get_transcript" || embed.skillId === "get-transcript") && embed.content) {
|
|
102322
102652
|
const results = embed.content.results ?? embed.content.data ?? [];
|
|
102323
102653
|
if (Array.isArray(results) && results.length > 0) {
|
|
102324
|
-
let
|
|
102654
|
+
let text6 = "";
|
|
102325
102655
|
for (const r of results) {
|
|
102326
102656
|
const meta = r.metadata;
|
|
102327
|
-
if (meta?.title)
|
|
102657
|
+
if (meta?.title) text6 += `# ${meta.title}
|
|
102328
102658
|
|
|
102329
102659
|
`;
|
|
102330
|
-
if (r.url)
|
|
102660
|
+
if (r.url) text6 += `Source: ${r.url}
|
|
102331
102661
|
|
|
102332
102662
|
`;
|
|
102333
|
-
|
|
102663
|
+
text6 += String(
|
|
102334
102664
|
r.transcript ?? r.formatted_transcript ?? r.text ?? r.content ?? ""
|
|
102335
102665
|
);
|
|
102336
|
-
|
|
102666
|
+
text6 += "\n\n---\n\n";
|
|
102337
102667
|
}
|
|
102338
102668
|
let fname = `${eid.slice(0, 8)}_transcript.md`;
|
|
102339
102669
|
const firstMeta = results[0]?.metadata;
|
|
@@ -102343,7 +102673,7 @@ ${deleted}/${resolved.length} chat(s) deleted.`);
|
|
|
102343
102673
|
transcriptEmbeds.push({
|
|
102344
102674
|
embedId: eid,
|
|
102345
102675
|
filename: fname,
|
|
102346
|
-
content:
|
|
102676
|
+
content: text6
|
|
102347
102677
|
});
|
|
102348
102678
|
}
|
|
102349
102679
|
}
|
|
@@ -103026,8 +103356,8 @@ async function syncCliBoundWorkflowFiles(client2, workflow, flags) {
|
|
|
103026
103356
|
const contents = await client2.listProjectItems(project.projectId, context);
|
|
103027
103357
|
for (const item of contents.items.filter((item2) => item2.item_type === "workflow")) {
|
|
103028
103358
|
if (await decryptOptionalProjectField2(item.target_id_encrypted, project.projectKey) !== workflow.id) continue;
|
|
103029
|
-
const
|
|
103030
|
-
const metadata =
|
|
103359
|
+
const text6 = await decryptOptionalProjectField2(item.encrypted_metadata, project.projectKey);
|
|
103360
|
+
const metadata = text6 ? JSON.parse(text6) : {};
|
|
103031
103361
|
const binding = metadata.remote_workflow_file;
|
|
103032
103362
|
if (!binding) continue;
|
|
103033
103363
|
const source = (await client2.listProjectSources(project.projectId, context)).find((item2) => item2.source_id === binding.source_id);
|
|
@@ -103317,10 +103647,10 @@ async function handleWorkflows(client2, subcommand, rest, flags, redactor) {
|
|
|
103317
103647
|
return;
|
|
103318
103648
|
}
|
|
103319
103649
|
if (subcommand === "input") {
|
|
103320
|
-
const
|
|
103321
|
-
if (!
|
|
103650
|
+
const text6 = typeof flags.text === "string" ? flags.text : rest.join(" ").trim();
|
|
103651
|
+
if (!text6) throw new Error('Missing workflow input text. Example: openmates workflows ask "alert me if it rains"');
|
|
103322
103652
|
const session = await client2.startWorkflowInput({
|
|
103323
|
-
text:
|
|
103653
|
+
text: text6,
|
|
103324
103654
|
selectedWorkflowId: typeof flags["workflow-id"] === "string" ? flags["workflow-id"] : void 0,
|
|
103325
103655
|
selectedProjectId: typeof flags["project-id"] === "string" ? flags["project-id"] : void 0,
|
|
103326
103656
|
timezone: typeof flags.timezone === "string" ? flags.timezone : Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
@@ -103367,9 +103697,9 @@ async function handleWorkflows(client2, subcommand, rest, flags, redactor) {
|
|
|
103367
103697
|
}
|
|
103368
103698
|
if (subcommand === "input-follow-up") {
|
|
103369
103699
|
const sessionId = rest[0];
|
|
103370
|
-
const
|
|
103371
|
-
if (!sessionId || !
|
|
103372
|
-
const session = await client2.followUpWorkflowInput(sessionId,
|
|
103700
|
+
const text6 = typeof flags.text === "string" ? flags.text : rest.slice(1).join(" ").trim();
|
|
103701
|
+
if (!sessionId || !text6) throw new Error('Missing session ID or text. Example: openmates workflows input-follow-up <session-id> "make it weekdays only"');
|
|
103702
|
+
const session = await client2.followUpWorkflowInput(sessionId, text6);
|
|
103373
103703
|
if (flags.json === true) {
|
|
103374
103704
|
printJson2(session);
|
|
103375
103705
|
} else {
|
|
@@ -104562,10 +104892,10 @@ async function streamCodeRunToTerminal(url, jsonMode) {
|
|
|
104562
104892
|
const payload = message.payload ?? {};
|
|
104563
104893
|
if (message.type === "code_run_event") {
|
|
104564
104894
|
const kind = String(payload.kind ?? "status");
|
|
104565
|
-
const
|
|
104895
|
+
const text6 = String(payload.text ?? "");
|
|
104566
104896
|
if (!jsonMode) {
|
|
104567
|
-
if (kind === "stdout") process.stdout.write(
|
|
104568
|
-
else process.stderr.write(
|
|
104897
|
+
if (kind === "stdout") process.stdout.write(text6);
|
|
104898
|
+
else process.stderr.write(text6);
|
|
104569
104899
|
}
|
|
104570
104900
|
} else if (message.type === "code_run_update") {
|
|
104571
104901
|
lastStatus = { ...lastStatus, ...payload };
|
|
@@ -105354,8 +105684,8 @@ function parseChatImportPayload(raw) {
|
|
|
105354
105684
|
return parsed;
|
|
105355
105685
|
}
|
|
105356
105686
|
if (parsed && typeof parsed === "object") {
|
|
105357
|
-
const
|
|
105358
|
-
if (
|
|
105687
|
+
const object3 = parsed;
|
|
105688
|
+
if (object3.chat || object3.messages) return { chats: [normalizeImportedChat(object3)] };
|
|
105359
105689
|
}
|
|
105360
105690
|
throw new Error("JSON import must contain a chats array, a chat object, or messages.");
|
|
105361
105691
|
}
|
|
@@ -107038,8 +107368,8 @@ function resolveApiKey(flags) {
|
|
|
107038
107368
|
function printJson2(value) {
|
|
107039
107369
|
console.log(JSON.stringify(value, null, 2));
|
|
107040
107370
|
}
|
|
107041
|
-
function header(
|
|
107042
|
-
process.stdout.write(`\x1B[1m${
|
|
107371
|
+
function header(text6) {
|
|
107372
|
+
process.stdout.write(`\x1B[1m${text6}\x1B[0m
|
|
107043
107373
|
`);
|
|
107044
107374
|
}
|
|
107045
107375
|
function kv(key, value, keyWidth = 16) {
|
|
@@ -107805,15 +108135,15 @@ async function acceptChatTaskProposals(client2, chatId, proposals, fallbackText)
|
|
|
107805
108135
|
}
|
|
107806
108136
|
return accepted;
|
|
107807
108137
|
}
|
|
107808
|
-
function buildTaskProposalFallbackText(
|
|
108138
|
+
function buildTaskProposalFallbackText(text6) {
|
|
107809
108139
|
const seen = /* @__PURE__ */ new Set();
|
|
107810
|
-
const bulletLines =
|
|
108140
|
+
const bulletLines = text6.split("\n").map((line) => line.trim()).filter((line) => /^[-*•]\s+/.test(line)).map((line) => line.replace(/^([-*•]\s*)\[[ xX]\]\s*/, "$1")).filter((line) => {
|
|
107811
108141
|
const key = line.replace(/^[-*•]\s+/, "").trim().toLowerCase();
|
|
107812
108142
|
if (seen.has(key)) return false;
|
|
107813
108143
|
seen.add(key);
|
|
107814
108144
|
return true;
|
|
107815
108145
|
});
|
|
107816
|
-
return bulletLines.length > 0 ? bulletLines.join("\n") :
|
|
108146
|
+
return bulletLines.length > 0 ? bulletLines.join("\n") : text6;
|
|
107817
108147
|
}
|
|
107818
108148
|
function printIncognitoNoHistoryNotice(json) {
|
|
107819
108149
|
const message = "Incognito chats are not stored. There is no incognito history to show or clear.";
|
|
@@ -107847,8 +108177,8 @@ function renderEmbedFromMeta(embedId, meta) {
|
|
|
107847
108177
|
process.stdout.write(`\x1B[2m\u2514\u2500 openmates embeds show ${shortId}\x1B[0m
|
|
107848
108178
|
`);
|
|
107849
108179
|
}
|
|
107850
|
-
async function renderMessageText(
|
|
107851
|
-
const lines =
|
|
108180
|
+
async function renderMessageText(text6, embedRefIndex, client2) {
|
|
108181
|
+
const lines = text6.split("\n");
|
|
107852
108182
|
const outputLines = [];
|
|
107853
108183
|
for (const line of lines) {
|
|
107854
108184
|
const blockMatch = line.match(/^\s*\[!?\]\(embed:([^)]+)\)\s*$/);
|
|
@@ -108272,8 +108602,8 @@ No example chats are linked to ${label3} yet.`);
|
|
|
108272
108602
|
console.log(`All examples: openmates apps examples ${appId}${skillId ? ` ${skillId}` : ""}`);
|
|
108273
108603
|
}
|
|
108274
108604
|
}
|
|
108275
|
-
function wrapText(
|
|
108276
|
-
const words =
|
|
108605
|
+
function wrapText(text6, width) {
|
|
108606
|
+
const words = text6.split(" ");
|
|
108277
108607
|
const lines = [];
|
|
108278
108608
|
let current = "";
|
|
108279
108609
|
for (const w of words) {
|