local-operator-ui 0.41.2 → 0.42.0
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/out/main/index.js +877 -225
- package/out/preload/index.js +83 -4
- package/out/renderer/assets/{_basePickBy-BgapP5T6.js → _basePickBy-KfApUmWE.js} +1 -1
- package/out/renderer/assets/{_baseUniq-B9rnfho3.js → _baseUniq-DXd1h_x3.js} +1 -1
- package/out/renderer/assets/{agent-details-page-CKRUVtjJ.js → agent-details-page-D-oKoyjm.js} +2 -2
- package/out/renderer/assets/{agent-hub-page-5qLVOZEV.js → agent-hub-page-CMbCN_Bg.js} +2 -2
- package/out/renderer/assets/agents-page-COpZu9CS.js +7 -0
- package/out/renderer/assets/{arc-Feq-cl9G.js → arc-Dim07OWx.js} +1 -1
- package/out/renderer/assets/{architectureDiagram-IEHRJDOE-BmZeJuzA.js → architectureDiagram-IEHRJDOE-BdwEpGi5.js} +1 -1
- package/out/renderer/assets/{blockDiagram-JOT3LUYC-DEqkKuOE.js → blockDiagram-JOT3LUYC-BcLFfkMT.js} +1 -1
- package/out/renderer/assets/{book-open-C1uak1LZ.js → book-open-C2DZijqP.js} +1 -1
- package/out/renderer/assets/browser-page-DzwNid1n.js +1 -0
- package/out/renderer/assets/{browser-webauthn-prompt-CKUBOIHd.js → browser-webauthn-prompt-C4aaSeT0.js} +1 -1
- package/out/renderer/assets/{building-2-Bpz1qaDa.js → building-2-DfFTqKaJ.js} +1 -1
- package/out/renderer/assets/{c4Diagram-VJAJSXHY-EbhUbSdf.js → c4Diagram-VJAJSXHY-Dm38eTOl.js} +1 -1
- package/out/renderer/assets/channel-CefUnWw7.js +1 -0
- package/out/renderer/assets/{chunk-4BMEZGHF-DIk7XDrx.js → chunk-4BMEZGHF-94enK1_-.js} +1 -1
- package/out/renderer/assets/{chunk-A2AXSNBT-D_MflthZ.js → chunk-A2AXSNBT-YiigwCRa.js} +1 -1
- package/out/renderer/assets/{chunk-AEK57VVT-C0iLgwbv.js → chunk-AEK57VVT-Bo9PQDfg.js} +1 -1
- package/out/renderer/assets/{chunk-D6G4REZN-BbFuFCzc.js → chunk-D6G4REZN-vwOZoeTn.js} +1 -1
- package/out/renderer/assets/{chunk-RZ5BOZE2-BxQo8VeZ.js → chunk-RZ5BOZE2-BY9NQkOq.js} +1 -1
- package/out/renderer/assets/{chunk-XZIHB7SX-DnNtYGsR.js → chunk-XZIHB7SX-D31wKKrQ.js} +1 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-BKByQj4B.js +1 -0
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-BKByQj4B.js +1 -0
- package/out/renderer/assets/clone-DpeVXG90.js +1 -0
- package/out/renderer/assets/{console-mirror-Bxl6t4e9.js → console-mirror-ClsQ7RUr.js} +1 -1
- package/out/renderer/assets/{consoleCapture-BzSftKjg.js → consoleCapture-DHR2J1Z2.js} +1 -1
- package/out/renderer/assets/{conversation-input-sync-MZPvyAzc.js → conversation-input-sync-CxT2etWK.js} +271 -251
- package/out/renderer/assets/{dagre-OKDRZEBW-qejdp-TF.js → dagre-OKDRZEBW-DV8UoEV8.js} +1 -1
- package/out/renderer/assets/{diagram-SSKATNLV-qHrLhzXc.js → diagram-SSKATNLV-KF8nQEWd.js} +1 -1
- package/out/renderer/assets/{diagram-VNBRO52H-q0teJTmh.js → diagram-VNBRO52H-P7VEv-Kl.js} +1 -1
- package/out/renderer/assets/{erDiagram-Q7BY3M3F-DI6rp9FR.js → erDiagram-Q7BY3M3F-B17XYgVW.js} +1 -1
- package/out/renderer/assets/{error-boundary-ZYkSCpZC.js → error-boundary-DBgLhXDJ.js} +1 -1
- package/out/renderer/assets/{flowDiagram-4HSFHLVR-xVi21DAI.js → flowDiagram-4HSFHLVR-BuuUG-g9.js} +1 -1
- package/out/renderer/assets/{ganttDiagram-APWFNJXF-BUKGBOB_.js → ganttDiagram-APWFNJXF-D8R9R-AO.js} +1 -1
- package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-CdE3ZeMn.js → gitGraphDiagram-7IBYFJ6S-fr4ArrNz.js} +1 -1
- package/out/renderer/assets/{graph-CRaHrZRK.js → graph-nV36Izm2.js} +1 -1
- package/out/renderer/assets/{hash-BN0ECl3H.js → hash-0qLX32ng.js} +1 -1
- package/out/renderer/assets/{heart-tKYqMVIH.js → heart-DFAcW-lm.js} +1 -1
- package/out/renderer/assets/{index-FsaxlHdZ.js → index-BKg4FYjW.js} +1 -1
- package/out/renderer/assets/index-BlshO0D3.css +1 -0
- package/out/renderer/assets/{index-B9E-fwX4.js → index-BmixXvR4.js} +1 -1
- package/out/renderer/assets/index-D6Di-Q2H.js +57 -0
- package/out/renderer/assets/index-DQKtrmMo.js +830 -0
- package/out/renderer/assets/{infoDiagram-PH2N3AL5-pOK9P20l.js → infoDiagram-PH2N3AL5-DmrijSS0.js} +1 -1
- package/out/renderer/assets/{installer-Dw1P6j8q.js → installer-4TSvERLS.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-U35MCT3I-D5Sg1JPA.js → journeyDiagram-U35MCT3I-BwwXu0up.js} +1 -1
- package/out/renderer/assets/{kanban-definition-NDS4AKOZ-BfhWqBCl.js → kanban-definition-NDS4AKOZ-CDbDK3QO.js} +1 -1
- package/out/renderer/assets/{layout-IqsTm240.js → layout-B7RIhnQw.js} +1 -1
- package/out/renderer/assets/{legacy-agents-page-bdH6oKjE.js → legacy-agents-page-DFGXD5LW.js} +6 -6
- package/out/renderer/assets/library-page-DPid0cmw.js +157 -0
- package/out/renderer/assets/{mermaid.core-D0YPuNli.js → mermaid.core-DcMJPeY9.js} +5 -5
- package/out/renderer/assets/{mesh-page-DYFNof_0.js → mesh-page-CIV9irJF.js} +1 -1
- package/out/renderer/assets/{mindmap-definition-ALO5MXBD-Tx5iMDRU.js → mindmap-definition-ALO5MXBD-aLvI45Tt.js} +1 -1
- package/out/renderer/assets/mini-leTyoKhc.js +1 -0
- package/out/renderer/assets/{notebook-pen-C3CwzwGA.js → notebook-pen-ClukfLau.js} +1 -1
- package/out/renderer/assets/{org-access-DoZK5gF3.js → org-access-BmjQJdOO.js} +1 -1
- package/out/renderer/assets/{org-surface-gate-Dy0B7mtt.js → org-surface-gate-B66nUFl-.js} +1 -1
- package/out/renderer/assets/{page-header-6mrV9W-E.js → page-header-C8bsR5wI.js} +1 -1
- package/out/renderer/assets/path-utils-DbnynqGJ.js +58 -0
- package/out/renderer/assets/{pieDiagram-IB7DONF6-D0rED3_3.js → pieDiagram-IB7DONF6-DvzUPikw.js} +1 -1
- package/out/renderer/assets/projects-page-4Cv9HMNh.js +45 -0
- package/out/renderer/assets/{publication-validation-CLbFS0n9.js → publication-validation-BlKeNjlY.js} +1 -1
- package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-D8jKSQt5.js → quadrantDiagram-7GDLP6J5-DFsFogdr.js} +1 -1
- package/out/renderer/assets/{radar-MK3ICKWK-Co2EJbaJ.js → radar-MK3ICKWK-YGPF88zl.js} +1 -1
- package/out/renderer/assets/{radient-auth-buttons-B11cdRmS.js → radient-auth-buttons-syGP58Ed.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-KVF5MWMF-BI13h11j.js → requirementDiagram-KVF5MWMF-x2D5VXdu.js} +1 -1
- package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-D4hZ6_ML.js → sankeyDiagram-QLVOVGJD-DA4pKMXD.js} +1 -1
- package/out/renderer/assets/{schedules-page-DFfDDHYC.js → schedules-page-CLrwsPcv.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-U6CqBtco.js → sequenceDiagram-X6HHIX6F-BUX2Yk2J.js} +1 -1
- package/out/renderer/assets/{settings-page-CZ7NUDoe.js → settings-page-BAVKJQXi.js} +1 -1
- package/out/renderer/assets/{smartart-BVm_cEaq.js → smartart-ipuU9VIr.js} +1 -1
- package/out/renderer/assets/{stateDiagram-DGXRK772-DBg11bkx.js → stateDiagram-DGXRK772-BsVvaiaW.js} +1 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-BvVuptXT.js +1 -0
- package/out/renderer/assets/{team-bridge-page-u_OqiZGS.js → team-bridge-page-DU_d4Yfc.js} +2 -2
- package/out/renderer/assets/{timeline-definition-BDJGKUSR-WQ6aYia6.js → timeline-definition-BDJGKUSR-Doja7siy.js} +1 -1
- package/out/renderer/assets/{use-download-agent-mutation-ZoivWizY.js → use-download-agent-mutation-CH4V_o78.js} +1 -1
- package/out/renderer/assets/{use-session-snapshot-CdYiirKJ.js → use-session-snapshot-7A4rQnOH.js} +1 -1
- package/out/renderer/assets/{xychartDiagram-VJFVF3MP-f11BpHer.js → xychartDiagram-VJFVF3MP-D2e6wZz8.js} +1 -1
- package/out/renderer/console-capture.html +5 -5
- package/out/renderer/index.html +7 -7
- package/out/renderer/installer.html +4 -4
- package/out/renderer/mini.html +7 -7
- package/package.json +2 -2
- package/out/renderer/assets/agents-page-tQooOOKH.js +0 -7
- package/out/renderer/assets/browser-page-CB-_usY1.js +0 -1
- package/out/renderer/assets/channel-CPGK3lub.js +0 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-hDc6ku-l.js +0 -1
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-hDc6ku-l.js +0 -1
- package/out/renderer/assets/clone--PuuOIog.js +0 -1
- package/out/renderer/assets/index-BDzV3bGH.js +0 -57
- package/out/renderer/assets/index-DknTGnAk.js +0 -835
- package/out/renderer/assets/index-ZovyVTxQ.css +0 -1
- package/out/renderer/assets/library-page-DDvrG_aA.js +0 -157
- package/out/renderer/assets/mini-BoZCnSK9.js +0 -1
- package/out/renderer/assets/path-utils-CRYGE4mK.js +0 -58
- package/out/renderer/assets/projects-page-D7j1GOvI.js +0 -45
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-jmaink9i.js +0 -1
package/out/main/index.js
CHANGED
|
@@ -200,6 +200,8 @@ zod.z.object({
|
|
|
200
200
|
}).passthrough()
|
|
201
201
|
}).passthrough()
|
|
202
202
|
}).passthrough();
|
|
203
|
+
const MAX_ATTACHMENT_UPLOAD_BYTES = 32 * 1024 * 1024;
|
|
204
|
+
const DESKTOP_MESSAGE_MAX_FILES = 8;
|
|
203
205
|
const SIDEBAR_DESTINATION_IDS = [
|
|
204
206
|
"aida",
|
|
205
207
|
"library",
|
|
@@ -213,9 +215,9 @@ const SIDEBAR_DESTINATION_IDS = [
|
|
|
213
215
|
];
|
|
214
216
|
const JOURNAL_ORDER_QUERY_BYTES = 6 * 1024;
|
|
215
217
|
const JOURNAL_ORDER_ID_LIMIT = 512;
|
|
216
|
-
function appendJournalOrderIds(
|
|
218
|
+
function appendJournalOrderIds(query2, path2, ids) {
|
|
217
219
|
let bytes = new TextEncoder().encode(
|
|
218
|
-
`${path2}${
|
|
220
|
+
`${path2}${query2.size ? `?${query2}` : ""}`
|
|
219
221
|
).length;
|
|
220
222
|
const selected = [];
|
|
221
223
|
for (const id2 of ids) {
|
|
@@ -223,7 +225,7 @@ function appendJournalOrderIds(query, path2, ids) {
|
|
|
223
225
|
const encoded = new URLSearchParams({ order_ids: id2 }).toString();
|
|
224
226
|
const extra = encoded.length + 1;
|
|
225
227
|
if (bytes + extra > JOURNAL_ORDER_QUERY_BYTES) break;
|
|
226
|
-
|
|
228
|
+
query2.append("order_ids", id2);
|
|
227
229
|
selected.push(id2);
|
|
228
230
|
bytes += extra;
|
|
229
231
|
}
|
|
@@ -251,7 +253,21 @@ const libraryAssetId = zod.z.string().regex(/^la_[0-9a-f]{16}$/);
|
|
|
251
253
|
const libraryTagId = zod.z.string().min(1).max(128).regex(/^[A-Za-z0-9_.:-]+$/);
|
|
252
254
|
const sessionImage = zod.z.object({
|
|
253
255
|
data_b64: zod.z.string().min(1).max(1e6),
|
|
254
|
-
mime_type: zod.z.enum(["image/png", "image/jpeg", "image/gif", "image/webp"])
|
|
256
|
+
mime_type: zod.z.enum(["image/png", "image/jpeg", "image/gif", "image/webp"]),
|
|
257
|
+
/**
|
|
258
|
+
* Where the image came from, when it came from disk. Provenance only: the
|
|
259
|
+
* daemon carries it to `ImageContent.path` and every provider serializer
|
|
260
|
+
* ignores it (attachment contract v1 §1.3). Absent on pasted images, which
|
|
261
|
+
* have no path.
|
|
262
|
+
*/
|
|
263
|
+
origin_path: zod.z.string().max(4096).optional()
|
|
264
|
+
}).strict();
|
|
265
|
+
const sessionFile = zod.z.object({
|
|
266
|
+
digest: zod.z.string().regex(/^[0-9a-f]{32}$/),
|
|
267
|
+
name: zod.z.string().max(1024).optional(),
|
|
268
|
+
mime_type: zod.z.string().max(255).optional(),
|
|
269
|
+
bytes: zod.z.number().int().min(0).optional(),
|
|
270
|
+
path: zod.z.string().max(4096).optional()
|
|
255
271
|
}).strict();
|
|
256
272
|
const DESKTOP_MESSAGE_MAX_CHARS = 2e5;
|
|
257
273
|
const DESKTOP_MESSAGE_MAX_IMAGES = 8;
|
|
@@ -1222,6 +1238,13 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
1222
1238
|
requestId,
|
|
1223
1239
|
text: zod.z.string().max(DESKTOP_MESSAGE_MAX_CHARS),
|
|
1224
1240
|
images: zod.z.array(sessionImage).max(DESKTOP_MESSAGE_MAX_IMAGES).optional(),
|
|
1241
|
+
/**
|
|
1242
|
+
* Uploaded files this message references, bounded to the backend's
|
|
1243
|
+
* `Prompt.files` ceiling. Absent rather than empty when the send carries
|
|
1244
|
+
* none, so an older harness's `extra=forbid` sees a legacy body - the same
|
|
1245
|
+
* rule the optional fields below follow.
|
|
1246
|
+
*/
|
|
1247
|
+
files: zod.z.array(sessionFile).max(DESKTOP_MESSAGE_MAX_FILES).optional(),
|
|
1225
1248
|
mode: zod.z.enum(["prompt", "steer"]).optional(),
|
|
1226
1249
|
/*
|
|
1227
1250
|
* HOW THE MESSAGE WAS PRODUCED (arch §4.2), and the harness gate is what
|
|
@@ -1318,7 +1341,28 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
1318
1341
|
* its own sentence once the response row exists; this client does not
|
|
1319
1342
|
* pre-judge that, it renders the owner's refusal.
|
|
1320
1343
|
*/
|
|
1321
|
-
revise: zod.z.boolean().optional()
|
|
1344
|
+
revise: zod.z.boolean().optional(),
|
|
1345
|
+
/**
|
|
1346
|
+
* PUT AN OPEN ASK AWAY instead of answering it (harness PR #2833, SA-D5).
|
|
1347
|
+
*
|
|
1348
|
+
* A modifier on the SAME `{ask_id}` body rather than a fourth op: a dismissal
|
|
1349
|
+
* is the same epoch-free queued-ask door an answer is, addressed by an id that
|
|
1350
|
+
* outlives any owner. Only `true` selects the shape — `false` is the same
|
|
1351
|
+
* statement as omitting it — and the shape rules below refuse it beside
|
|
1352
|
+
* answers/decline/revise, because no single body may answer and dismiss one ask.
|
|
1353
|
+
*
|
|
1354
|
+
* GATED ON `features.ask_dismiss` at the surface that offers the control: the
|
|
1355
|
+
* backend's `Answer` is `extra="forbid"`, so an older daemon answers 422 to this
|
|
1356
|
+
* field rather than ignoring it.
|
|
1357
|
+
*/
|
|
1358
|
+
dismiss: zod.z.boolean().optional(),
|
|
1359
|
+
/**
|
|
1360
|
+
* Why the operator put it away: `answered_in_chat` (the conversation already
|
|
1361
|
+
* answered it) or `moot` (no longer needed). Optional; the ask log records
|
|
1362
|
+
* `moot` when absent. Refused without `dismiss: true` — the same no-op rule
|
|
1363
|
+
* `revise` follows above.
|
|
1364
|
+
*/
|
|
1365
|
+
reason: zod.z.enum(["answered_in_chat", "moot"]).optional()
|
|
1322
1366
|
}).strict(),
|
|
1323
1367
|
zod.z.object({
|
|
1324
1368
|
op: zod.z.literal("sessions.seen"),
|
|
@@ -3166,7 +3210,22 @@ const desktopRequestSchema = desktopRequestUnion.superRefine(
|
|
|
3166
3210
|
message: "ask_id must be a non-empty string",
|
|
3167
3211
|
path: ["askId"]
|
|
3168
3212
|
});
|
|
3169
|
-
if (request.
|
|
3213
|
+
if (request.dismiss === true) {
|
|
3214
|
+
if (request.answers !== void 0 || request.decline === true || request.revise === true)
|
|
3215
|
+
ctx.addIssue({
|
|
3216
|
+
code: zod.z.ZodIssueCode.custom,
|
|
3217
|
+
message: "A dismissal carries no answers, decline or revise",
|
|
3218
|
+
path: ["dismiss"]
|
|
3219
|
+
});
|
|
3220
|
+
return;
|
|
3221
|
+
}
|
|
3222
|
+
if (request.reason !== void 0)
|
|
3223
|
+
ctx.addIssue({
|
|
3224
|
+
code: zod.z.ZodIssueCode.custom,
|
|
3225
|
+
message: "A reason applies to a dismissal",
|
|
3226
|
+
path: ["reason"]
|
|
3227
|
+
});
|
|
3228
|
+
else if (request.decline !== true && !request.answers)
|
|
3170
3229
|
ctx.addIssue({
|
|
3171
3230
|
code: zod.z.ZodIssueCode.custom,
|
|
3172
3231
|
message: "A queued-ask answer needs answers or decline",
|
|
@@ -3210,6 +3269,18 @@ const desktopRequestSchema = desktopRequestUnion.superRefine(
|
|
|
3210
3269
|
message: "revise applies to a queued ask",
|
|
3211
3270
|
path: ["revise"]
|
|
3212
3271
|
});
|
|
3272
|
+
if (request.dismiss === true)
|
|
3273
|
+
ctx.addIssue({
|
|
3274
|
+
code: zod.z.ZodIssueCode.custom,
|
|
3275
|
+
message: "dismiss applies to a queued ask",
|
|
3276
|
+
path: ["dismiss"]
|
|
3277
|
+
});
|
|
3278
|
+
if (request.reason !== void 0)
|
|
3279
|
+
ctx.addIssue({
|
|
3280
|
+
code: zod.z.ZodIssueCode.custom,
|
|
3281
|
+
message: "reason applies to a queued ask",
|
|
3282
|
+
path: ["reason"]
|
|
3283
|
+
});
|
|
3213
3284
|
return;
|
|
3214
3285
|
}
|
|
3215
3286
|
if (request.op === "sessions.create" && request.purpose === void 0) {
|
|
@@ -3651,11 +3722,11 @@ function harnessImportBody(request) {
|
|
|
3651
3722
|
};
|
|
3652
3723
|
}
|
|
3653
3724
|
function conversationOwnerQuery(request) {
|
|
3654
|
-
const
|
|
3655
|
-
if (request.tenant_id)
|
|
3725
|
+
const query2 = new URLSearchParams();
|
|
3726
|
+
if (request.tenant_id) query2.set("tenant_id", request.tenant_id);
|
|
3656
3727
|
if (request.expected_account_id)
|
|
3657
|
-
|
|
3658
|
-
return
|
|
3728
|
+
query2.set("expected_account_id", request.expected_account_id);
|
|
3729
|
+
return query2.size ? `?${query2.toString()}` : "";
|
|
3659
3730
|
}
|
|
3660
3731
|
function tenantQuery(tenantId) {
|
|
3661
3732
|
return tenantId === void 0 ? "" : `?tenant_id=${encodeURIComponent(tenantId)}`;
|
|
@@ -3758,10 +3829,10 @@ function desktopEndpoint(request) {
|
|
|
3758
3829
|
case "imports.sources":
|
|
3759
3830
|
return { path: "/v1/desktop/imports/sources", method: "GET" };
|
|
3760
3831
|
case "imports.sessions": {
|
|
3761
|
-
const
|
|
3762
|
-
if (request.includeSubagents)
|
|
3832
|
+
const query2 = new URLSearchParams({ source: request.source });
|
|
3833
|
+
if (request.includeSubagents) query2.set("include_subagents", "true");
|
|
3763
3834
|
return {
|
|
3764
|
-
path: `/v1/desktop/imports/sessions?${
|
|
3835
|
+
path: `/v1/desktop/imports/sessions?${query2.toString()}`,
|
|
3765
3836
|
method: "GET"
|
|
3766
3837
|
};
|
|
3767
3838
|
}
|
|
@@ -4026,13 +4097,13 @@ function desktopEndpoint(request) {
|
|
|
4026
4097
|
method: "POST"
|
|
4027
4098
|
};
|
|
4028
4099
|
case "sessions.search": {
|
|
4029
|
-
const
|
|
4100
|
+
const query2 = new URLSearchParams({
|
|
4030
4101
|
q: request.q,
|
|
4031
4102
|
limit: String(request.limit ?? SESSION_SEARCH_DEFAULT_LIMIT)
|
|
4032
4103
|
});
|
|
4033
|
-
if (request.include_archived)
|
|
4104
|
+
if (request.include_archived) query2.set("include_archived", "true");
|
|
4034
4105
|
return {
|
|
4035
|
-
path: `/v1/desktop/sessions/search?${
|
|
4106
|
+
path: `/v1/desktop/sessions/search?${query2}`,
|
|
4036
4107
|
method: "GET"
|
|
4037
4108
|
};
|
|
4038
4109
|
}
|
|
@@ -4112,23 +4183,23 @@ function desktopEndpoint(request) {
|
|
|
4112
4183
|
}
|
|
4113
4184
|
};
|
|
4114
4185
|
case "sessions.get": {
|
|
4115
|
-
const
|
|
4186
|
+
const query2 = new URLSearchParams();
|
|
4116
4187
|
if (request.journalOrder) {
|
|
4117
|
-
|
|
4118
|
-
if (request.peerJournalSource)
|
|
4188
|
+
query2.set("journal_order", "1");
|
|
4189
|
+
if (request.peerJournalSource) query2.set("peer_journal_source", "1");
|
|
4119
4190
|
appendJournalOrderIds(
|
|
4120
|
-
|
|
4191
|
+
query2,
|
|
4121
4192
|
`/v1/desktop/sessions/${request.sessionId}`,
|
|
4122
4193
|
request.orderIds ?? []
|
|
4123
4194
|
);
|
|
4124
4195
|
}
|
|
4125
4196
|
return {
|
|
4126
|
-
path: `/v1/desktop/sessions/${request.sessionId}${
|
|
4197
|
+
path: `/v1/desktop/sessions/${request.sessionId}${query2.size ? `?${query2}` : ""}`,
|
|
4127
4198
|
method: "GET"
|
|
4128
4199
|
};
|
|
4129
4200
|
}
|
|
4130
4201
|
case "sessions.files": {
|
|
4131
|
-
const
|
|
4202
|
+
const query2 = new URLSearchParams({
|
|
4132
4203
|
limit: String(request.limit ?? 200)
|
|
4133
4204
|
});
|
|
4134
4205
|
for (const key of [
|
|
@@ -4140,10 +4211,10 @@ function desktopEndpoint(request) {
|
|
|
4140
4211
|
"cursor"
|
|
4141
4212
|
]) {
|
|
4142
4213
|
const value = request[key];
|
|
4143
|
-
if (value !== void 0)
|
|
4214
|
+
if (value !== void 0) query2.set(key, value);
|
|
4144
4215
|
}
|
|
4145
4216
|
return {
|
|
4146
|
-
path: `/v1/desktop/sessions/${encodeURIComponent(request.sessionId)}/files?${
|
|
4217
|
+
path: `/v1/desktop/sessions/${encodeURIComponent(request.sessionId)}/files?${query2}`,
|
|
4147
4218
|
method: "GET"
|
|
4148
4219
|
};
|
|
4149
4220
|
}
|
|
@@ -4153,34 +4224,34 @@ function desktopEndpoint(request) {
|
|
|
4153
4224
|
method: "POST"
|
|
4154
4225
|
};
|
|
4155
4226
|
case "sessions.history": {
|
|
4156
|
-
const
|
|
4227
|
+
const query2 = new URLSearchParams({
|
|
4157
4228
|
limit: String(request.limit ?? 100)
|
|
4158
4229
|
});
|
|
4159
|
-
if (request.beforeId)
|
|
4230
|
+
if (request.beforeId) query2.set("before_id", request.beforeId);
|
|
4160
4231
|
if (request.openFrame) {
|
|
4161
|
-
|
|
4162
|
-
|
|
4232
|
+
query2.set("open_frame", "1");
|
|
4233
|
+
query2.set("supplements", "1");
|
|
4163
4234
|
}
|
|
4164
4235
|
if (request.journalOrder) {
|
|
4165
|
-
|
|
4166
|
-
if (request.peerJournalSource)
|
|
4236
|
+
query2.set("journal_order", "1");
|
|
4237
|
+
if (request.peerJournalSource) query2.set("peer_journal_source", "1");
|
|
4167
4238
|
if (request.sourceRead === "metadata")
|
|
4168
|
-
|
|
4239
|
+
query2.set("source_read", "metadata");
|
|
4169
4240
|
else if (request.sourceRead === "payload" && request.expectedJournalGeneration)
|
|
4170
|
-
|
|
4241
|
+
query2.set("source_read", "payload");
|
|
4171
4242
|
if (request.expectedJournalGeneration)
|
|
4172
|
-
|
|
4243
|
+
query2.set(
|
|
4173
4244
|
"expected_journal_generation",
|
|
4174
4245
|
request.expectedJournalGeneration
|
|
4175
4246
|
);
|
|
4176
4247
|
appendJournalOrderIds(
|
|
4177
|
-
|
|
4248
|
+
query2,
|
|
4178
4249
|
`/v1/desktop/sessions/${request.sessionId}/history`,
|
|
4179
4250
|
request.orderIds ?? []
|
|
4180
4251
|
);
|
|
4181
4252
|
}
|
|
4182
4253
|
return {
|
|
4183
|
-
path: `/v1/desktop/sessions/${request.sessionId}/history?${
|
|
4254
|
+
path: `/v1/desktop/sessions/${request.sessionId}/history?${query2}`,
|
|
4184
4255
|
method: "GET"
|
|
4185
4256
|
};
|
|
4186
4257
|
}
|
|
@@ -4205,22 +4276,22 @@ function desktopEndpoint(request) {
|
|
|
4205
4276
|
}
|
|
4206
4277
|
};
|
|
4207
4278
|
case "sessions.find": {
|
|
4208
|
-
const
|
|
4279
|
+
const query2 = new URLSearchParams({
|
|
4209
4280
|
q: request.q,
|
|
4210
4281
|
limit: String(request.limit ?? THREAD_FIND_DEFAULT_LIMIT)
|
|
4211
4282
|
});
|
|
4212
4283
|
return {
|
|
4213
|
-
path: `/v1/desktop/sessions/${request.sessionId}/find?${
|
|
4284
|
+
path: `/v1/desktop/sessions/${request.sessionId}/find?${query2}`,
|
|
4214
4285
|
method: "GET"
|
|
4215
4286
|
};
|
|
4216
4287
|
}
|
|
4217
4288
|
case "subagents.transcript": {
|
|
4218
|
-
const
|
|
4289
|
+
const query2 = new URLSearchParams({
|
|
4219
4290
|
limit: String(request.limit ?? 100)
|
|
4220
4291
|
});
|
|
4221
|
-
if (request.beforeId)
|
|
4292
|
+
if (request.beforeId) query2.set("before_id", request.beforeId);
|
|
4222
4293
|
return {
|
|
4223
|
-
path: `/v1/desktop/sessions/${request.sessionId}/children/${request.childId}/transcript?${
|
|
4294
|
+
path: `/v1/desktop/sessions/${request.sessionId}/children/${request.childId}/transcript?${query2}`,
|
|
4224
4295
|
method: "GET"
|
|
4225
4296
|
};
|
|
4226
4297
|
}
|
|
@@ -4232,6 +4303,7 @@ function desktopEndpoint(request) {
|
|
|
4232
4303
|
request_id: request.requestId,
|
|
4233
4304
|
text: request.text,
|
|
4234
4305
|
images: request.images ?? [],
|
|
4306
|
+
...request.files?.length ? { files: request.files } : {},
|
|
4235
4307
|
mode: request.mode ?? "prompt",
|
|
4236
4308
|
/*
|
|
4237
4309
|
* ABSENT, not empty, when the app has nothing to say: an older harness
|
|
@@ -4272,7 +4344,16 @@ function desktopEndpoint(request) {
|
|
|
4272
4344
|
* body that carried `revise: false` on every ordinary submit would be
|
|
4273
4345
|
* asserting an intent it does not have.
|
|
4274
4346
|
*/
|
|
4275
|
-
...request.revise === true ? { revise: true } : {}
|
|
4347
|
+
...request.revise === true ? { revise: true } : {},
|
|
4348
|
+
/*
|
|
4349
|
+
* The dismissal modifier and its reason, on the same absent-when-not-
|
|
4350
|
+
* asked-for rule: an older harness refuses the field outright
|
|
4351
|
+
* (`extra="forbid"`), so an ordinary answer must not carry it.
|
|
4352
|
+
*/
|
|
4353
|
+
...request.dismiss === true ? {
|
|
4354
|
+
dismiss: true,
|
|
4355
|
+
...request.reason !== void 0 ? { reason: request.reason } : {}
|
|
4356
|
+
} : {}
|
|
4276
4357
|
}
|
|
4277
4358
|
};
|
|
4278
4359
|
return {
|
|
@@ -4450,12 +4531,12 @@ function desktopEndpoint(request) {
|
|
|
4450
4531
|
method: "DELETE"
|
|
4451
4532
|
};
|
|
4452
4533
|
case "legacy.models": {
|
|
4453
|
-
const
|
|
4454
|
-
if (request.provider)
|
|
4455
|
-
if (request.sort)
|
|
4456
|
-
if (request.direction)
|
|
4534
|
+
const query2 = new URLSearchParams();
|
|
4535
|
+
if (request.provider) query2.set("provider", request.provider);
|
|
4536
|
+
if (request.sort) query2.set("sort", request.sort);
|
|
4537
|
+
if (request.direction) query2.set("direction", request.direction);
|
|
4457
4538
|
return {
|
|
4458
|
-
path:
|
|
4539
|
+
path: query2.size > 0 ? `/v1/models?${query2}` : "/v1/models",
|
|
4459
4540
|
method: "GET"
|
|
4460
4541
|
};
|
|
4461
4542
|
}
|
|
@@ -4470,12 +4551,12 @@ function desktopEndpoint(request) {
|
|
|
4470
4551
|
return { path: `/v1/agents/${request.agentId}/upload`, method: "POST" };
|
|
4471
4552
|
case "agent.publish": {
|
|
4472
4553
|
assertPairedPublicationTarget(request);
|
|
4473
|
-
const
|
|
4554
|
+
const query2 = new URLSearchParams();
|
|
4474
4555
|
if (request.visibility === "org" && request.tenantId) {
|
|
4475
|
-
|
|
4476
|
-
|
|
4556
|
+
query2.set("visibility", "org");
|
|
4557
|
+
query2.set("tenant_id", request.tenantId);
|
|
4477
4558
|
}
|
|
4478
|
-
const search =
|
|
4559
|
+
const search = query2.toString();
|
|
4479
4560
|
return {
|
|
4480
4561
|
path: `/v1/agents/${request.agentId}/publish${search ? `?${search}` : ""}`,
|
|
4481
4562
|
method: "POST",
|
|
@@ -4492,12 +4573,12 @@ function desktopEndpoint(request) {
|
|
|
4492
4573
|
}
|
|
4493
4574
|
case "agent.republish": {
|
|
4494
4575
|
assertPairedPublicationTarget(request);
|
|
4495
|
-
const
|
|
4576
|
+
const query2 = new URLSearchParams();
|
|
4496
4577
|
if (request.visibility === "org" && request.tenantId) {
|
|
4497
|
-
|
|
4498
|
-
|
|
4578
|
+
query2.set("visibility", "org");
|
|
4579
|
+
query2.set("tenant_id", request.tenantId);
|
|
4499
4580
|
}
|
|
4500
|
-
const search =
|
|
4581
|
+
const search = query2.toString();
|
|
4501
4582
|
return {
|
|
4502
4583
|
path: `/v1/agents/${request.agentId}/publish${search ? `?${search}` : ""}`,
|
|
4503
4584
|
method: "PUT",
|
|
@@ -4511,49 +4592,49 @@ function desktopEndpoint(request) {
|
|
|
4511
4592
|
}
|
|
4512
4593
|
case "team.publish": {
|
|
4513
4594
|
assertPairedPublicationTarget(request);
|
|
4514
|
-
const
|
|
4595
|
+
const query2 = new URLSearchParams();
|
|
4515
4596
|
if (request.visibility === "org" && request.tenantId) {
|
|
4516
|
-
|
|
4517
|
-
|
|
4597
|
+
query2.set("visibility", "org");
|
|
4598
|
+
query2.set("tenant_id", request.tenantId);
|
|
4518
4599
|
}
|
|
4519
4600
|
return {
|
|
4520
|
-
path: `/v1/teams/${request.teamId}/publish${
|
|
4601
|
+
path: `/v1/teams/${request.teamId}/publish${query2.size ? `?${query2}` : ""}`,
|
|
4521
4602
|
method: "POST",
|
|
4522
4603
|
body: publicationPolicyBody(request)
|
|
4523
4604
|
};
|
|
4524
4605
|
}
|
|
4525
4606
|
case "team.pull": {
|
|
4526
|
-
const
|
|
4527
|
-
if (request.tenantId)
|
|
4528
|
-
const search =
|
|
4607
|
+
const query2 = new URLSearchParams();
|
|
4608
|
+
if (request.tenantId) query2.set("tenant_id", request.tenantId);
|
|
4609
|
+
const search = query2.toString();
|
|
4529
4610
|
return {
|
|
4530
4611
|
path: `/v1/teams/pull/${request.teamId}${search ? `?${search}` : ""}`,
|
|
4531
4612
|
method: "GET"
|
|
4532
4613
|
};
|
|
4533
4614
|
}
|
|
4534
4615
|
case "agent.nameAvailability": {
|
|
4535
|
-
const
|
|
4536
|
-
return { path: `/v1/agent-name-availability?${
|
|
4616
|
+
const query2 = new URLSearchParams({ name: request.name });
|
|
4617
|
+
return { path: `/v1/agent-name-availability?${query2}`, method: "GET" };
|
|
4537
4618
|
}
|
|
4538
4619
|
case "legacy.agents.list": {
|
|
4539
|
-
const
|
|
4620
|
+
const query2 = new URLSearchParams({
|
|
4540
4621
|
page: String(request.page ?? 1),
|
|
4541
4622
|
per_page: String(request.perPage ?? 10)
|
|
4542
4623
|
});
|
|
4543
|
-
if (request.name)
|
|
4544
|
-
if (request.sort)
|
|
4545
|
-
if (request.direction)
|
|
4546
|
-
return { path: `/v1/agents?${
|
|
4624
|
+
if (request.name) query2.set("name", request.name);
|
|
4625
|
+
if (request.sort) query2.set("sort", request.sort);
|
|
4626
|
+
if (request.direction) query2.set("direction", request.direction);
|
|
4627
|
+
return { path: `/v1/agents?${query2}`, method: "GET" };
|
|
4547
4628
|
}
|
|
4548
4629
|
case "legacy.agent.get":
|
|
4549
4630
|
return { path: `/v1/agents/${request.agentId}`, method: "GET" };
|
|
4550
4631
|
case "legacy.agent.history": {
|
|
4551
|
-
const
|
|
4632
|
+
const query2 = new URLSearchParams({
|
|
4552
4633
|
page: String(request.page ?? 1),
|
|
4553
4634
|
per_page: String(request.perPage ?? 10)
|
|
4554
4635
|
});
|
|
4555
4636
|
return {
|
|
4556
|
-
path: `/v1/agents/${request.agentId}/history?${
|
|
4637
|
+
path: `/v1/agents/${request.agentId}/history?${query2}`,
|
|
4557
4638
|
method: "GET"
|
|
4558
4639
|
};
|
|
4559
4640
|
}
|
|
@@ -4563,13 +4644,13 @@ function desktopEndpoint(request) {
|
|
|
4563
4644
|
* what the backend's models declare.
|
|
4564
4645
|
*/
|
|
4565
4646
|
case "wakes.list": {
|
|
4566
|
-
const
|
|
4647
|
+
const query2 = new URLSearchParams();
|
|
4567
4648
|
if (request.limit !== void 0)
|
|
4568
|
-
|
|
4649
|
+
query2.set("limit", String(request.limit));
|
|
4569
4650
|
if (request.includeDormant !== void 0)
|
|
4570
|
-
|
|
4651
|
+
query2.set("include_dormant", String(request.includeDormant));
|
|
4571
4652
|
return {
|
|
4572
|
-
path:
|
|
4653
|
+
path: query2.size > 0 ? `/v1/desktop/wakes?${query2}` : "/v1/desktop/wakes",
|
|
4573
4654
|
method: "GET"
|
|
4574
4655
|
};
|
|
4575
4656
|
}
|
|
@@ -4626,30 +4707,30 @@ function desktopEndpoint(request) {
|
|
|
4626
4707
|
method: "POST"
|
|
4627
4708
|
};
|
|
4628
4709
|
case "legacy.jobs.list": {
|
|
4629
|
-
const
|
|
4630
|
-
if (request.agentId)
|
|
4631
|
-
if (request.status)
|
|
4710
|
+
const query2 = new URLSearchParams();
|
|
4711
|
+
if (request.agentId) query2.set("agent_id", request.agentId);
|
|
4712
|
+
if (request.status) query2.set("status", request.status);
|
|
4632
4713
|
return {
|
|
4633
|
-
path:
|
|
4714
|
+
path: query2.size > 0 ? `/v1/jobs?${query2}` : "/v1/jobs",
|
|
4634
4715
|
method: "GET"
|
|
4635
4716
|
};
|
|
4636
4717
|
}
|
|
4637
4718
|
case "legacy.job.get":
|
|
4638
4719
|
return { path: `/v1/jobs/${request.jobId}`, method: "GET" };
|
|
4639
4720
|
case "legacy.schedules.list": {
|
|
4640
|
-
const
|
|
4721
|
+
const query2 = new URLSearchParams({
|
|
4641
4722
|
page: String(request.page ?? 1),
|
|
4642
4723
|
per_page: String(request.perPage ?? 10)
|
|
4643
4724
|
});
|
|
4644
|
-
return { path: `/v1/schedules?${
|
|
4725
|
+
return { path: `/v1/schedules?${query2}`, method: "GET" };
|
|
4645
4726
|
}
|
|
4646
4727
|
case "legacy.agent.schedules.list": {
|
|
4647
|
-
const
|
|
4728
|
+
const query2 = new URLSearchParams({
|
|
4648
4729
|
page: String(request.page ?? 1),
|
|
4649
4730
|
per_page: String(request.perPage ?? 10)
|
|
4650
4731
|
});
|
|
4651
4732
|
return {
|
|
4652
|
-
path: `/v1/agents/${request.agentId}/schedules?${
|
|
4733
|
+
path: `/v1/agents/${request.agentId}/schedules?${query2}`,
|
|
4653
4734
|
method: "GET"
|
|
4654
4735
|
};
|
|
4655
4736
|
}
|
|
@@ -4714,29 +4795,29 @@ function desktopEndpoint(request) {
|
|
|
4714
4795
|
};
|
|
4715
4796
|
}
|
|
4716
4797
|
case "usage.get": {
|
|
4717
|
-
const
|
|
4798
|
+
const query2 = new URLSearchParams({
|
|
4718
4799
|
live: String(request.live ?? false),
|
|
4719
4800
|
refresh: String(request.refresh ?? false)
|
|
4720
4801
|
});
|
|
4721
|
-
if (request.provider)
|
|
4722
|
-
return { path: `/v1/desktop/usage?${
|
|
4802
|
+
if (request.provider) query2.set("provider", request.provider);
|
|
4803
|
+
return { path: `/v1/desktop/usage?${query2}`, method: "GET" };
|
|
4723
4804
|
}
|
|
4724
4805
|
case "quota.notice": {
|
|
4725
|
-
const
|
|
4806
|
+
const query2 = new URLSearchParams({
|
|
4726
4807
|
refresh: String(request.refresh ?? false)
|
|
4727
4808
|
});
|
|
4728
|
-
if (request.provider)
|
|
4729
|
-
if (request.model)
|
|
4730
|
-
return { path: `/v1/desktop/quota-notice?${
|
|
4809
|
+
if (request.provider) query2.set("provider", request.provider);
|
|
4810
|
+
if (request.model) query2.set("model", request.model);
|
|
4811
|
+
return { path: `/v1/desktop/quota-notice?${query2}`, method: "GET" };
|
|
4731
4812
|
}
|
|
4732
4813
|
case "analytics.get": {
|
|
4733
|
-
const
|
|
4734
|
-
if (request.sessionId)
|
|
4814
|
+
const query2 = new URLSearchParams({ days: String(request.days ?? 30) });
|
|
4815
|
+
if (request.sessionId) query2.set("session_id", request.sessionId);
|
|
4735
4816
|
if (request.sinceMs !== void 0)
|
|
4736
|
-
|
|
4817
|
+
query2.set("since_ms", String(request.sinceMs));
|
|
4737
4818
|
if (request.untilMs !== void 0)
|
|
4738
|
-
|
|
4739
|
-
return { path: `/v1/desktop/analytics?${
|
|
4819
|
+
query2.set("until_ms", String(request.untilMs));
|
|
4820
|
+
return { path: `/v1/desktop/analytics?${query2}`, method: "GET" };
|
|
4740
4821
|
}
|
|
4741
4822
|
/*
|
|
4742
4823
|
* `/analytics/models`, NOT `/analytics?models=1`.
|
|
@@ -4749,31 +4830,31 @@ function desktopEndpoint(request) {
|
|
|
4749
4830
|
* the server resolves one window from either.
|
|
4750
4831
|
*/
|
|
4751
4832
|
case "analytics.models": {
|
|
4752
|
-
const
|
|
4753
|
-
if (request.sessionId)
|
|
4833
|
+
const query2 = new URLSearchParams({ days: String(request.days ?? 30) });
|
|
4834
|
+
if (request.sessionId) query2.set("session_id", request.sessionId);
|
|
4754
4835
|
if (request.sinceMs !== void 0)
|
|
4755
|
-
|
|
4836
|
+
query2.set("since_ms", String(request.sinceMs));
|
|
4756
4837
|
if (request.untilMs !== void 0)
|
|
4757
|
-
|
|
4758
|
-
return { path: `/v1/desktop/analytics/models?${
|
|
4838
|
+
query2.set("until_ms", String(request.untilMs));
|
|
4839
|
+
return { path: `/v1/desktop/analytics/models?${query2}`, method: "GET" };
|
|
4759
4840
|
}
|
|
4760
4841
|
case "info.get":
|
|
4761
4842
|
return { path: "/v1/desktop/info", method: "GET" };
|
|
4762
4843
|
case "sessions.report": {
|
|
4763
|
-
const
|
|
4844
|
+
const query2 = new URLSearchParams({
|
|
4764
4845
|
recent_limit: String(request.recentLimit ?? 12)
|
|
4765
4846
|
});
|
|
4766
4847
|
return {
|
|
4767
|
-
path: `/v1/desktop/sessions/${request.sessionId}/report?${
|
|
4848
|
+
path: `/v1/desktop/sessions/${request.sessionId}/report?${query2}`,
|
|
4768
4849
|
method: "GET"
|
|
4769
4850
|
};
|
|
4770
4851
|
}
|
|
4771
4852
|
case "skills.list": {
|
|
4772
|
-
const
|
|
4773
|
-
if (request.sessionId)
|
|
4774
|
-
if (request.cwd)
|
|
4775
|
-
if (request.name)
|
|
4776
|
-
const encoded =
|
|
4853
|
+
const query2 = new URLSearchParams();
|
|
4854
|
+
if (request.sessionId) query2.set("session_id", request.sessionId);
|
|
4855
|
+
if (request.cwd) query2.set("cwd", request.cwd);
|
|
4856
|
+
if (request.name) query2.set("name", request.name);
|
|
4857
|
+
const encoded = query2.toString();
|
|
4777
4858
|
return {
|
|
4778
4859
|
path: `/v1/desktop/skills${encoded ? `?${encoded}` : ""}`,
|
|
4779
4860
|
method: "GET"
|
|
@@ -4878,10 +4959,10 @@ function desktopEndpoint(request) {
|
|
|
4878
4959
|
body: request.control
|
|
4879
4960
|
};
|
|
4880
4961
|
case "mcp.catalog": {
|
|
4881
|
-
const
|
|
4882
|
-
if (request.cwd)
|
|
4883
|
-
if (request.sessionId)
|
|
4884
|
-
const suffix =
|
|
4962
|
+
const query2 = new URLSearchParams();
|
|
4963
|
+
if (request.cwd) query2.set("cwd", request.cwd);
|
|
4964
|
+
if (request.sessionId) query2.set("session_id", request.sessionId);
|
|
4965
|
+
const suffix = query2.toString();
|
|
4885
4966
|
return {
|
|
4886
4967
|
path: suffix ? `/v1/desktop/mcp?${suffix}` : "/v1/desktop/mcp",
|
|
4887
4968
|
method: "GET"
|
|
@@ -5029,14 +5110,14 @@ function desktopEndpoint(request) {
|
|
|
5029
5110
|
}
|
|
5030
5111
|
};
|
|
5031
5112
|
case "team_bridge.conversations.list": {
|
|
5032
|
-
const
|
|
5033
|
-
if (request.scope === "account")
|
|
5034
|
-
if (request.tenant_id)
|
|
5113
|
+
const query2 = new URLSearchParams();
|
|
5114
|
+
if (request.scope === "account") query2.set("scope", "account");
|
|
5115
|
+
if (request.tenant_id) query2.set("tenant_id", request.tenant_id);
|
|
5035
5116
|
if (request.limit !== void 0)
|
|
5036
|
-
|
|
5037
|
-
if (request.cursor)
|
|
5038
|
-
if (request.before)
|
|
5039
|
-
const suffix =
|
|
5117
|
+
query2.set("limit", String(request.limit));
|
|
5118
|
+
if (request.cursor) query2.set("cursor", request.cursor);
|
|
5119
|
+
if (request.before) query2.set("before", request.before);
|
|
5120
|
+
const suffix = query2.size > 0 ? `?${query2.toString()}` : "";
|
|
5040
5121
|
return {
|
|
5041
5122
|
path: `/v1/desktop/team-bridge/conversations${suffix}`,
|
|
5042
5123
|
method: "GET"
|
|
@@ -5097,11 +5178,11 @@ function desktopEndpoint(request) {
|
|
|
5097
5178
|
}
|
|
5098
5179
|
};
|
|
5099
5180
|
case "team_bridge.conversations.members.add": {
|
|
5100
|
-
const
|
|
5101
|
-
if (request.tenant_id)
|
|
5181
|
+
const query2 = new URLSearchParams();
|
|
5182
|
+
if (request.tenant_id) query2.set("tenant_id", request.tenant_id);
|
|
5102
5183
|
if (request.expected_account_id)
|
|
5103
|
-
|
|
5104
|
-
const suffix =
|
|
5184
|
+
query2.set("expected_account_id", request.expected_account_id);
|
|
5185
|
+
const suffix = query2.size > 0 ? `?${query2.toString()}` : "";
|
|
5105
5186
|
return {
|
|
5106
5187
|
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/members${suffix}`,
|
|
5107
5188
|
method: "POST",
|
|
@@ -5125,14 +5206,14 @@ function desktopEndpoint(request) {
|
|
|
5125
5206
|
}
|
|
5126
5207
|
};
|
|
5127
5208
|
case "team_bridge.messages.list": {
|
|
5128
|
-
const
|
|
5129
|
-
if (request.tenant_id)
|
|
5209
|
+
const query2 = new URLSearchParams();
|
|
5210
|
+
if (request.tenant_id) query2.set("tenant_id", request.tenant_id);
|
|
5130
5211
|
if (request.limit !== void 0)
|
|
5131
|
-
|
|
5212
|
+
query2.set("limit", String(request.limit));
|
|
5132
5213
|
if (request.before_seq !== void 0)
|
|
5133
|
-
|
|
5134
|
-
if (request.endpoint_id)
|
|
5135
|
-
const suffix =
|
|
5214
|
+
query2.set("before_seq", String(request.before_seq));
|
|
5215
|
+
if (request.endpoint_id) query2.set("endpoint_id", request.endpoint_id);
|
|
5216
|
+
const suffix = query2.size > 0 ? `?${query2.toString()}` : "";
|
|
5136
5217
|
return {
|
|
5137
5218
|
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/messages${suffix}`,
|
|
5138
5219
|
method: "GET"
|
|
@@ -5163,13 +5244,13 @@ function desktopEndpoint(request) {
|
|
|
5163
5244
|
}
|
|
5164
5245
|
};
|
|
5165
5246
|
case "team_bridge.messages.replies": {
|
|
5166
|
-
const
|
|
5167
|
-
if (request.tenant_id)
|
|
5247
|
+
const query2 = new URLSearchParams();
|
|
5248
|
+
if (request.tenant_id) query2.set("tenant_id", request.tenant_id);
|
|
5168
5249
|
if (request.limit !== void 0)
|
|
5169
|
-
|
|
5250
|
+
query2.set("limit", String(request.limit));
|
|
5170
5251
|
if (request.after_seq !== void 0)
|
|
5171
|
-
|
|
5172
|
-
const suffix =
|
|
5252
|
+
query2.set("after_seq", String(request.after_seq));
|
|
5253
|
+
const suffix = query2.size > 0 ? `?${query2.toString()}` : "";
|
|
5173
5254
|
return {
|
|
5174
5255
|
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/messages/${encodeURIComponent(request.message_id)}/replies${suffix}`,
|
|
5175
5256
|
method: "GET"
|
|
@@ -5187,10 +5268,10 @@ function desktopEndpoint(request) {
|
|
|
5187
5268
|
}
|
|
5188
5269
|
};
|
|
5189
5270
|
case "team_bridge.unread": {
|
|
5190
|
-
const
|
|
5191
|
-
if (request.scope === "account")
|
|
5192
|
-
else if (request.tenant_id)
|
|
5193
|
-
const suffix =
|
|
5271
|
+
const query2 = new URLSearchParams();
|
|
5272
|
+
if (request.scope === "account") query2.set("scope", "account");
|
|
5273
|
+
else if (request.tenant_id) query2.set("tenant_id", request.tenant_id);
|
|
5274
|
+
const suffix = query2.size > 0 ? `?${query2.toString()}` : "";
|
|
5194
5275
|
return {
|
|
5195
5276
|
path: `/v1/desktop/team-bridge/unread${suffix}`,
|
|
5196
5277
|
method: "GET"
|
|
@@ -5218,9 +5299,9 @@ function desktopEndpoint(request) {
|
|
|
5218
5299
|
* op would emit for a missing value.
|
|
5219
5300
|
*/
|
|
5220
5301
|
case "team_bridge.status": {
|
|
5221
|
-
const
|
|
5222
|
-
if (request.boundary)
|
|
5223
|
-
const suffix =
|
|
5302
|
+
const query2 = new URLSearchParams();
|
|
5303
|
+
if (request.boundary) query2.set("boundary", request.boundary);
|
|
5304
|
+
const suffix = query2.size > 0 ? `?${query2.toString()}` : "";
|
|
5224
5305
|
return {
|
|
5225
5306
|
path: `/v1/desktop/team-bridge/status${suffix}`,
|
|
5226
5307
|
method: "GET"
|
|
@@ -5279,29 +5360,29 @@ function desktopEndpoint(request) {
|
|
|
5279
5360
|
* `op` because that key already names the desktop operation.
|
|
5280
5361
|
*/
|
|
5281
5362
|
case "library.list": {
|
|
5282
|
-
const
|
|
5283
|
-
if (request.scope)
|
|
5284
|
-
if (request.q)
|
|
5285
|
-
if (request.category)
|
|
5286
|
-
if (request.kind)
|
|
5287
|
-
if (request.origin_group)
|
|
5288
|
-
if (request.origin)
|
|
5289
|
-
if (request.tag)
|
|
5290
|
-
if (request.tag_mode)
|
|
5363
|
+
const query2 = new URLSearchParams();
|
|
5364
|
+
if (request.scope) query2.set("scope", request.scope);
|
|
5365
|
+
if (request.q) query2.set("q", request.q);
|
|
5366
|
+
if (request.category) query2.set("category", request.category);
|
|
5367
|
+
if (request.kind) query2.set("kind", request.kind);
|
|
5368
|
+
if (request.origin_group) query2.set("origin_group", request.origin_group);
|
|
5369
|
+
if (request.origin) query2.set("origin", request.origin);
|
|
5370
|
+
if (request.tag) query2.set("tag", request.tag);
|
|
5371
|
+
if (request.tag_mode) query2.set("tag_mode", request.tag_mode);
|
|
5291
5372
|
if (request.highlighted !== void 0)
|
|
5292
|
-
|
|
5373
|
+
query2.set("highlighted", request.highlighted ? "1" : "0");
|
|
5293
5374
|
if (request.organized !== void 0)
|
|
5294
|
-
|
|
5375
|
+
query2.set("organized", request.organized ? "1" : "0");
|
|
5295
5376
|
if (request.favorite !== void 0)
|
|
5296
|
-
|
|
5297
|
-
if (request.session)
|
|
5298
|
-
if (request.session_id)
|
|
5299
|
-
if (request.sort)
|
|
5300
|
-
if (request.order)
|
|
5377
|
+
query2.set("favorite", request.favorite ? "1" : "0");
|
|
5378
|
+
if (request.session) query2.set("session", request.session);
|
|
5379
|
+
if (request.session_id) query2.set("session_id", request.session_id);
|
|
5380
|
+
if (request.sort) query2.set("sort", request.sort);
|
|
5381
|
+
if (request.order) query2.set("order", request.order);
|
|
5301
5382
|
if (request.limit !== void 0)
|
|
5302
|
-
|
|
5303
|
-
if (request.cursor)
|
|
5304
|
-
const suffix =
|
|
5383
|
+
query2.set("limit", String(request.limit));
|
|
5384
|
+
if (request.cursor) query2.set("cursor", request.cursor);
|
|
5385
|
+
const suffix = query2.toString();
|
|
5305
5386
|
return {
|
|
5306
5387
|
path: `/v1/desktop/library/assets${suffix ? `?${suffix}` : ""}`,
|
|
5307
5388
|
method: "GET"
|
|
@@ -5462,12 +5543,12 @@ function desktopEndpoint(request) {
|
|
|
5462
5543
|
method: "POST"
|
|
5463
5544
|
};
|
|
5464
5545
|
case "projects.search": {
|
|
5465
|
-
const
|
|
5546
|
+
const query2 = new URLSearchParams({
|
|
5466
5547
|
q: request.q,
|
|
5467
5548
|
limit: String(request.limit ?? PROJECTS_SEARCH_DEFAULT_LIMIT)
|
|
5468
5549
|
});
|
|
5469
5550
|
return {
|
|
5470
|
-
path: `/v1/desktop/projects/search?${
|
|
5551
|
+
path: `/v1/desktop/projects/search?${query2}`,
|
|
5471
5552
|
method: "GET"
|
|
5472
5553
|
};
|
|
5473
5554
|
}
|
|
@@ -5867,6 +5948,187 @@ function windowGlassArgument(state2, scheme) {
|
|
|
5867
5948
|
const { settings, capability } = state2;
|
|
5868
5949
|
return `${WINDOW_GLASS_ARG}=${capability.mechanism}:${settings.coverage}:${settings.intensity}:${settings.material}:${scheme}`;
|
|
5869
5950
|
}
|
|
5951
|
+
const UPLOAD_DEADLINE_MS = 5 * 6e4;
|
|
5952
|
+
const DIGEST_SHAPE = /^[0-9a-f]{32}$/;
|
|
5953
|
+
const PATH_SEPARATOR = /[/\\]/;
|
|
5954
|
+
const basenameOf = (filePath) => filePath.split(PATH_SEPARATOR).pop() || filePath;
|
|
5955
|
+
function bytesFromDataUrl(dataUrl) {
|
|
5956
|
+
const comma = dataUrl.indexOf(",");
|
|
5957
|
+
if (comma < 0 || !dataUrl.startsWith("data:")) return null;
|
|
5958
|
+
const header = dataUrl.slice(5, comma);
|
|
5959
|
+
const payload = dataUrl.slice(comma + 1);
|
|
5960
|
+
try {
|
|
5961
|
+
if (header.endsWith(";base64"))
|
|
5962
|
+
return new Uint8Array(Buffer.from(payload, "base64"));
|
|
5963
|
+
return new Uint8Array(Buffer.from(decodeURIComponent(payload), "utf8"));
|
|
5964
|
+
} catch {
|
|
5965
|
+
return null;
|
|
5966
|
+
}
|
|
5967
|
+
}
|
|
5968
|
+
function readRecord(payload) {
|
|
5969
|
+
if (payload === null || typeof payload !== "object") return null;
|
|
5970
|
+
const body = payload;
|
|
5971
|
+
const inner = body.result;
|
|
5972
|
+
if (inner !== null && typeof inner === "object")
|
|
5973
|
+
return inner;
|
|
5974
|
+
return body;
|
|
5975
|
+
}
|
|
5976
|
+
function toAttachment(payload) {
|
|
5977
|
+
const record = readRecord(payload);
|
|
5978
|
+
if (!record) return null;
|
|
5979
|
+
const digest = record.digest;
|
|
5980
|
+
const mime = record.mime_type;
|
|
5981
|
+
const bytes = record.bytes;
|
|
5982
|
+
if (typeof digest !== "string" || !DIGEST_SHAPE.test(digest)) return null;
|
|
5983
|
+
if (typeof mime !== "string" || mime.length === 0) return null;
|
|
5984
|
+
if (typeof bytes !== "number" || !Number.isFinite(bytes) || bytes < 0)
|
|
5985
|
+
return null;
|
|
5986
|
+
return {
|
|
5987
|
+
digest,
|
|
5988
|
+
name: typeof record.name === "string" ? record.name : null,
|
|
5989
|
+
mime_type: mime,
|
|
5990
|
+
bytes,
|
|
5991
|
+
path: typeof record.path === "string" ? record.path : null,
|
|
5992
|
+
stored_path: typeof record.stored_path === "string" ? record.stored_path : null
|
|
5993
|
+
};
|
|
5994
|
+
}
|
|
5995
|
+
function refusalDetail(payload) {
|
|
5996
|
+
if (payload === null || typeof payload !== "object") return null;
|
|
5997
|
+
const detail = payload.detail;
|
|
5998
|
+
if (typeof detail === "string" && detail.trim()) return detail;
|
|
5999
|
+
if (detail !== null && typeof detail === "object") {
|
|
6000
|
+
const message = detail.message;
|
|
6001
|
+
if (typeof message === "string" && message.trim()) return message;
|
|
6002
|
+
}
|
|
6003
|
+
return null;
|
|
6004
|
+
}
|
|
6005
|
+
async function uploadAttachment(input) {
|
|
6006
|
+
const cap = input.maxBytes ?? MAX_ATTACHMENT_UPLOAD_BYTES;
|
|
6007
|
+
const source = input.source;
|
|
6008
|
+
const displayName = source.name?.trim() || (source.kind === "path" ? basenameOf(source.path) : "pasted-file");
|
|
6009
|
+
let originPath = null;
|
|
6010
|
+
let size;
|
|
6011
|
+
if (source.kind === "path") {
|
|
6012
|
+
const filePath = source.path;
|
|
6013
|
+
originPath = filePath;
|
|
6014
|
+
try {
|
|
6015
|
+
const stat = fs.statSync(filePath, { throwIfNoEntry: false });
|
|
6016
|
+
if (!stat) {
|
|
6017
|
+
return {
|
|
6018
|
+
success: false,
|
|
6019
|
+
code: "not-found",
|
|
6020
|
+
error: `No file at ${filePath}`
|
|
6021
|
+
};
|
|
6022
|
+
}
|
|
6023
|
+
if (!stat.isFile()) {
|
|
6024
|
+
return {
|
|
6025
|
+
success: false,
|
|
6026
|
+
code: "not-a-file",
|
|
6027
|
+
error: `${filePath} is not a regular file`
|
|
6028
|
+
};
|
|
6029
|
+
}
|
|
6030
|
+
size = stat.size;
|
|
6031
|
+
} catch (error) {
|
|
6032
|
+
return {
|
|
6033
|
+
success: false,
|
|
6034
|
+
code: "unreadable",
|
|
6035
|
+
error: error instanceof Error ? error.message : String(error)
|
|
6036
|
+
};
|
|
6037
|
+
}
|
|
6038
|
+
} else {
|
|
6039
|
+
const decoded = bytesFromDataUrl(source.dataUrl);
|
|
6040
|
+
if (!decoded) {
|
|
6041
|
+
return {
|
|
6042
|
+
success: false,
|
|
6043
|
+
code: "unreadable",
|
|
6044
|
+
error: `${displayName} did not carry usable bytes`
|
|
6045
|
+
};
|
|
6046
|
+
}
|
|
6047
|
+
size = decoded.byteLength;
|
|
6048
|
+
}
|
|
6049
|
+
if (size === 0) {
|
|
6050
|
+
return {
|
|
6051
|
+
success: false,
|
|
6052
|
+
code: "refused",
|
|
6053
|
+
error: `${displayName} is empty`,
|
|
6054
|
+
sizeBytes: 0
|
|
6055
|
+
};
|
|
6056
|
+
}
|
|
6057
|
+
if (size > cap) {
|
|
6058
|
+
return {
|
|
6059
|
+
success: false,
|
|
6060
|
+
code: "too-large",
|
|
6061
|
+
error: `${displayName} is ${size} bytes, over the ${cap}-byte attachment limit`,
|
|
6062
|
+
sizeBytes: size
|
|
6063
|
+
};
|
|
6064
|
+
}
|
|
6065
|
+
let bytes;
|
|
6066
|
+
try {
|
|
6067
|
+
bytes = source.kind === "path" ? new Uint8Array(fs.readFileSync(source.path)) : bytesFromDataUrl(source.dataUrl);
|
|
6068
|
+
} catch (error) {
|
|
6069
|
+
return {
|
|
6070
|
+
success: false,
|
|
6071
|
+
code: "unreadable",
|
|
6072
|
+
error: error instanceof Error ? error.message : String(error)
|
|
6073
|
+
};
|
|
6074
|
+
}
|
|
6075
|
+
const form = new FormData();
|
|
6076
|
+
form.append(
|
|
6077
|
+
"file",
|
|
6078
|
+
new Blob([bytes], {
|
|
6079
|
+
type: "application/octet-stream"
|
|
6080
|
+
}),
|
|
6081
|
+
displayName
|
|
6082
|
+
);
|
|
6083
|
+
form.append("name", displayName);
|
|
6084
|
+
if (originPath) form.append("origin_path", originPath);
|
|
6085
|
+
let response;
|
|
6086
|
+
try {
|
|
6087
|
+
const doFetch = input.fetchImpl ?? fetch;
|
|
6088
|
+
response = await doFetch(
|
|
6089
|
+
new URL("/v1/desktop/attachments", input.backendUrl),
|
|
6090
|
+
{
|
|
6091
|
+
method: "POST",
|
|
6092
|
+
headers: {
|
|
6093
|
+
Accept: "application/json",
|
|
6094
|
+
...input.token ? { Authorization: `Bearer ${input.token}` } : {}
|
|
6095
|
+
},
|
|
6096
|
+
body: form,
|
|
6097
|
+
redirect: "error",
|
|
6098
|
+
signal: AbortSignal.timeout(UPLOAD_DEADLINE_MS)
|
|
6099
|
+
}
|
|
6100
|
+
);
|
|
6101
|
+
} catch (error) {
|
|
6102
|
+
return {
|
|
6103
|
+
success: false,
|
|
6104
|
+
code: "unreachable",
|
|
6105
|
+
error: error instanceof Error ? error.message : "The daemon did not answer the upload."
|
|
6106
|
+
};
|
|
6107
|
+
}
|
|
6108
|
+
let payload = null;
|
|
6109
|
+
try {
|
|
6110
|
+
payload = await response.json();
|
|
6111
|
+
} catch {
|
|
6112
|
+
}
|
|
6113
|
+
if (response.status < 200 || response.status >= 300) {
|
|
6114
|
+
return {
|
|
6115
|
+
success: false,
|
|
6116
|
+
code: "refused",
|
|
6117
|
+
error: refusalDetail(payload) ?? `The daemon refused the upload (HTTP ${response.status}).`,
|
|
6118
|
+
sizeBytes: size
|
|
6119
|
+
};
|
|
6120
|
+
}
|
|
6121
|
+
const attachment = toAttachment(payload);
|
|
6122
|
+
if (!attachment) {
|
|
6123
|
+
return {
|
|
6124
|
+
success: false,
|
|
6125
|
+
code: "refused",
|
|
6126
|
+
error: `${displayName} was uploaded but the daemon's answer carried no attachment record.`,
|
|
6127
|
+
sizeBytes: size
|
|
6128
|
+
};
|
|
6129
|
+
}
|
|
6130
|
+
return { success: true, attachment };
|
|
6131
|
+
}
|
|
5870
6132
|
const SERVE_RUN_DIRNAME = "run/serve";
|
|
5871
6133
|
const REAPED_DIRNAME = "reaped";
|
|
5872
6134
|
const REAPED_MAX_FILES = 200;
|
|
@@ -9466,25 +9728,25 @@ class DesktopStreamRelay {
|
|
|
9466
9728
|
const streamId = node_crypto.randomBytes(16).toString("hex");
|
|
9467
9729
|
const controller = new AbortController();
|
|
9468
9730
|
this.streams.set(streamId, controller);
|
|
9469
|
-
const
|
|
9470
|
-
if (args.epoch)
|
|
9731
|
+
const query2 = new URLSearchParams();
|
|
9732
|
+
if (args.epoch) query2.set("epoch", args.epoch);
|
|
9471
9733
|
if (args.afterSeq !== void 0)
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
if (args.openFrame === true)
|
|
9734
|
+
query2.set("after_seq", String(args.afterSeq));
|
|
9735
|
+
query2.set("frontend_replace", "1");
|
|
9736
|
+
if (args.openFrame === true) query2.set("open_frame", "1");
|
|
9475
9737
|
if (args.journalOrder === true) {
|
|
9476
|
-
|
|
9738
|
+
query2.set("journal_order", "1");
|
|
9477
9739
|
if (args.peerJournalSource === true)
|
|
9478
|
-
|
|
9740
|
+
query2.set("peer_journal_source", "1");
|
|
9479
9741
|
}
|
|
9480
|
-
|
|
9742
|
+
query2.set("supplements", "1");
|
|
9481
9743
|
if (args.journalOrder === true)
|
|
9482
9744
|
appendJournalOrderIds(
|
|
9483
|
-
|
|
9745
|
+
query2,
|
|
9484
9746
|
`/v1/desktop/sessions/${args.sessionId}/events`,
|
|
9485
9747
|
args.orderIds ?? []
|
|
9486
9748
|
);
|
|
9487
|
-
const suffix =
|
|
9749
|
+
const suffix = query2.size > 0 ? `?${query2}` : "";
|
|
9488
9750
|
const url = new URL(
|
|
9489
9751
|
`/v1/desktop/sessions/${args.sessionId}/events${suffix}`,
|
|
9490
9752
|
this.backendUrl
|
|
@@ -14738,6 +15000,20 @@ class BackendServiceManager {
|
|
|
14738
15000
|
getBackendUrl() {
|
|
14739
15001
|
return this.backendUrl;
|
|
14740
15002
|
}
|
|
15003
|
+
/**
|
|
15004
|
+
* The bearer token this app presents to THAT daemon, or null while none has
|
|
15005
|
+
* been minted/adopted yet.
|
|
15006
|
+
*
|
|
15007
|
+
* Exposed for the one request that does not travel through the op plane: the
|
|
15008
|
+
* attachment UPLOAD (attachment contract v1 §1.1). It carries raw bytes in a
|
|
15009
|
+
* multipart body, which the op plane's JSON schemas cannot describe, so it
|
|
15010
|
+
* goes over `fetch` from main and has to present the same credential the
|
|
15011
|
+
* plane would. Kept a getter rather than a public field so the token's
|
|
15012
|
+
* lifecycle stays owned here (`mintDesktopToken`, adoption, persistence).
|
|
15013
|
+
*/
|
|
15014
|
+
getDesktopToken() {
|
|
15015
|
+
return this.desktopToken;
|
|
15016
|
+
}
|
|
14741
15017
|
/**
|
|
14742
15018
|
* Check if the backend service is using an external backend
|
|
14743
15019
|
* @returns True if using an external backend, false if we started our own
|
|
@@ -14883,12 +15159,12 @@ const REASON_LIMIT = 240;
|
|
|
14883
15159
|
function installFailureReason(stdout, stderr) {
|
|
14884
15160
|
const lines = `${stderr}
|
|
14885
15161
|
${stdout}`.split(/\r?\n/);
|
|
14886
|
-
const pick = (
|
|
15162
|
+
const pick = (accept2) => {
|
|
14887
15163
|
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
14888
15164
|
const line = lines[index].trim();
|
|
14889
15165
|
if (line.length === 0) continue;
|
|
14890
15166
|
if (NOISE.some((pattern) => pattern.test(line))) continue;
|
|
14891
|
-
if (!
|
|
15167
|
+
if (!accept2(line)) continue;
|
|
14892
15168
|
return line.length > REASON_LIMIT ? `${line.slice(0, REASON_LIMIT - 1).trimEnd()}…` : line;
|
|
14893
15169
|
}
|
|
14894
15170
|
return null;
|
|
@@ -16769,6 +17045,10 @@ const METHODS$1 = [
|
|
|
16769
17045
|
"styles",
|
|
16770
17046
|
"hit_test",
|
|
16771
17047
|
"ancestors",
|
|
17048
|
+
// The read-only DOM query: CSS in, element descriptors out. A read by
|
|
17049
|
+
// construction (no write, no navigation, no caller-supplied code), served by
|
|
17050
|
+
// every non-cmux host like the structured reads above.
|
|
17051
|
+
"query",
|
|
16772
17052
|
"request_access",
|
|
16773
17053
|
"await_access",
|
|
16774
17054
|
"cancel_access",
|
|
@@ -16833,6 +17113,7 @@ const HOST_CAPABILITIES = [
|
|
|
16833
17113
|
"styles",
|
|
16834
17114
|
"hit_test",
|
|
16835
17115
|
"ancestors",
|
|
17116
|
+
"query",
|
|
16836
17117
|
"download",
|
|
16837
17118
|
"upload"
|
|
16838
17119
|
];
|
|
@@ -28133,7 +28414,7 @@ function nativeCapacityProbe(trustedPython) {
|
|
|
28133
28414
|
let ptyMax = null;
|
|
28134
28415
|
let stopped = false;
|
|
28135
28416
|
const children = /* @__PURE__ */ new Set();
|
|
28136
|
-
function readNumber(executable, args,
|
|
28417
|
+
function readNumber(executable, args, accept2) {
|
|
28137
28418
|
const child = node_child_process.execFile(
|
|
28138
28419
|
executable,
|
|
28139
28420
|
args,
|
|
@@ -28148,7 +28429,7 @@ function nativeCapacityProbe(trustedPython) {
|
|
|
28148
28429
|
children.delete(child);
|
|
28149
28430
|
if (stopped || error) return;
|
|
28150
28431
|
const value = Number(stdout.trim());
|
|
28151
|
-
if (Number.isSafeInteger(value) && value > 0)
|
|
28432
|
+
if (Number.isSafeInteger(value) && value > 0) accept2(value);
|
|
28152
28433
|
}
|
|
28153
28434
|
);
|
|
28154
28435
|
children.add(child);
|
|
@@ -35734,6 +36015,34 @@ const enUiChatAnalytics = {
|
|
|
35734
36015
|
"ui.chat.analytics.toolbar.refreshing": "Refreshing",
|
|
35735
36016
|
"ui.chat.analytics.toolbar.this_session_only": "This session only"
|
|
35736
36017
|
};
|
|
36018
|
+
const enUiChatAsks = {
|
|
36019
|
+
"ui.chat.asks.context.messages_since": "{count, plural, one {# message from you since this was asked} other {# messages from you since this was asked}} (last message {time})",
|
|
36020
|
+
"ui.chat.asks.dismiss.answered_in_chat.note": "you already replied in the conversation",
|
|
36021
|
+
"ui.chat.asks.dismiss.answered_in_chat.title": "Answered in chat",
|
|
36022
|
+
"ui.chat.asks.dismiss.cancel": "Cancel",
|
|
36023
|
+
"ui.chat.asks.dismiss.heading": "Dismiss this ask",
|
|
36024
|
+
"ui.chat.asks.dismiss.in_flight": "Dismissing…",
|
|
36025
|
+
"ui.chat.asks.dismiss.moot.note": "stop waiting on it",
|
|
36026
|
+
"ui.chat.asks.dismiss.moot.title": "No longer needed",
|
|
36027
|
+
"ui.chat.asks.dismiss.receipt.answered_in_chat": "Dismissed — settled in chat",
|
|
36028
|
+
"ui.chat.asks.dismiss.receipt.moot": "Dismissed — no longer needed",
|
|
36029
|
+
"ui.chat.asks.dismiss.refused": "Couldn't dismiss this ask — nothing was sent.",
|
|
36030
|
+
"ui.chat.asks.dismiss.trigger": "Dismiss…"
|
|
36031
|
+
};
|
|
36032
|
+
const enUiChatAttachments = {
|
|
36033
|
+
"ui.chat.attachments.pending_caption": "Not sent yet",
|
|
36034
|
+
"ui.chat.attachments.file_meta": "{type} · {size}",
|
|
36035
|
+
"ui.chat.attachments.file_missing": "Moved or deleted",
|
|
36036
|
+
"ui.chat.attachments.file_retained": "Still retained in the attachment store ({digest})",
|
|
36037
|
+
"ui.chat.attachments.file_unnamed": "Attached file",
|
|
36038
|
+
"ui.chat.attachments.copy_path": "Copy path",
|
|
36039
|
+
"ui.chat.attachments.path_copied": "Path copied",
|
|
36040
|
+
"ui.chat.attachments.file_missing_recovery": "The file is no longer at this path.",
|
|
36041
|
+
"ui.chat.attachments.file_type_unknown": "File",
|
|
36042
|
+
"ui.chat.attachments.copy_saved_path": "Copy saved copy path",
|
|
36043
|
+
"ui.chat.attachments.saved_path_copied": "Saved copy path copied",
|
|
36044
|
+
"ui.chat.attachments.saved_copy_label": "Saved copy"
|
|
36045
|
+
};
|
|
35737
36046
|
const enUiChatCanonical = {
|
|
35738
36047
|
"ui.chat.canonical.sound.batch_attachment_unavailable": "Audio attachment unavailable.",
|
|
35739
36048
|
"ui.chat.canonical.sound.player_failed": "This sound could not be played",
|
|
@@ -39514,6 +39823,34 @@ const esUiCanvas = {
|
|
|
39514
39823
|
"ui.canvas.files.prepareError": "No se pudo preparar una copia local para esta acción",
|
|
39515
39824
|
"ui.canvas.files.pathCopyNote": "Las acciones de abrir, carpeta y ruta crean una copia local en el scratchpad de esta conversación."
|
|
39516
39825
|
};
|
|
39826
|
+
const esUiChatAsks = {
|
|
39827
|
+
"ui.chat.asks.context.messages_since": "{count, plural, one {# mensaje tuyo desde que se hizo esta consulta (último mensaje: {time})} many {# de mensajes tuyos desde que se hizo esta consulta (último mensaje: {time})} other {# mensajes tuyos desde que se hizo esta consulta (último mensaje: {time})}}",
|
|
39828
|
+
"ui.chat.asks.dismiss.answered_in_chat.note": "ya respondiste en la conversación",
|
|
39829
|
+
"ui.chat.asks.dismiss.answered_in_chat.title": "Respondida en la conversación",
|
|
39830
|
+
"ui.chat.asks.dismiss.cancel": "Cancelar",
|
|
39831
|
+
"ui.chat.asks.dismiss.heading": "Descartar esta consulta",
|
|
39832
|
+
"ui.chat.asks.dismiss.in_flight": "Descartando…",
|
|
39833
|
+
"ui.chat.asks.dismiss.moot.note": "el agente dejará de esperar respuesta",
|
|
39834
|
+
"ui.chat.asks.dismiss.moot.title": "Ya no hace falta",
|
|
39835
|
+
"ui.chat.asks.dismiss.receipt.answered_in_chat": "Descartada — resuelta en la conversación",
|
|
39836
|
+
"ui.chat.asks.dismiss.receipt.moot": "Descartada — ya no hace falta",
|
|
39837
|
+
"ui.chat.asks.dismiss.refused": "No se pudo descartar esta consulta: no se envió nada.",
|
|
39838
|
+
"ui.chat.asks.dismiss.trigger": "Descartar…"
|
|
39839
|
+
};
|
|
39840
|
+
const esUiChatAttachments = {
|
|
39841
|
+
"ui.chat.attachments.pending_caption": "Aún no enviado",
|
|
39842
|
+
"ui.chat.attachments.file_meta": "{type} · {size}",
|
|
39843
|
+
"ui.chat.attachments.file_missing": "Movido o eliminado",
|
|
39844
|
+
"ui.chat.attachments.file_retained": "Todavía se conserva en el almacén de adjuntos ({digest})",
|
|
39845
|
+
"ui.chat.attachments.file_unnamed": "Archivo adjunto",
|
|
39846
|
+
"ui.chat.attachments.copy_path": "Copiar ruta",
|
|
39847
|
+
"ui.chat.attachments.path_copied": "Ruta copiada",
|
|
39848
|
+
"ui.chat.attachments.file_missing_recovery": "El archivo ya no está en esta ruta.",
|
|
39849
|
+
"ui.chat.attachments.file_type_unknown": "Archivo",
|
|
39850
|
+
"ui.chat.attachments.copy_saved_path": "Copiar ruta de la copia guardada",
|
|
39851
|
+
"ui.chat.attachments.saved_path_copied": "Ruta de la copia guardada copiada",
|
|
39852
|
+
"ui.chat.attachments.saved_copy_label": "Copia guardada"
|
|
39853
|
+
};
|
|
39517
39854
|
const esUiChatComposer = {
|
|
39518
39855
|
"ui.chat.composer.clear_message": "Borrar mensaje",
|
|
39519
39856
|
"ui.chat.composer.message": "Mensaje",
|
|
@@ -43155,6 +43492,34 @@ const frUiCanvas = {
|
|
|
43155
43492
|
"ui.canvas.files.prepareError": "Impossible de préparer une copie locale pour cette action",
|
|
43156
43493
|
"ui.canvas.files.pathCopyNote": "Les actions Ouvrir, Dossier et Chemin créent une copie locale dans le dossier de travail de cette conversation."
|
|
43157
43494
|
};
|
|
43495
|
+
const frUiChatAsks = {
|
|
43496
|
+
"ui.chat.asks.context.messages_since": "{count, plural, one {# message de votre part depuis cette demande (dernier message à {time})} many {# de messages de votre part depuis cette demande (dernier message à {time})} other {# messages de votre part depuis cette demande (dernier message à {time})}}",
|
|
43497
|
+
"ui.chat.asks.dismiss.answered_in_chat.note": "vous avez déjà répondu dans la conversation",
|
|
43498
|
+
"ui.chat.asks.dismiss.answered_in_chat.title": "Répondu dans la conversation",
|
|
43499
|
+
"ui.chat.asks.dismiss.cancel": "Annuler",
|
|
43500
|
+
"ui.chat.asks.dismiss.heading": "Ignorer cette demande",
|
|
43501
|
+
"ui.chat.asks.dismiss.in_flight": "En cours…",
|
|
43502
|
+
"ui.chat.asks.dismiss.moot.note": "l’agent n’attendra plus de réponse",
|
|
43503
|
+
"ui.chat.asks.dismiss.moot.title": "Plus nécessaire",
|
|
43504
|
+
"ui.chat.asks.dismiss.receipt.answered_in_chat": "Ignorée — réglée dans la conversation",
|
|
43505
|
+
"ui.chat.asks.dismiss.receipt.moot": "Ignorée — plus nécessaire",
|
|
43506
|
+
"ui.chat.asks.dismiss.refused": "Impossible d’ignorer cette demande : rien n’a été envoyé.",
|
|
43507
|
+
"ui.chat.asks.dismiss.trigger": "Ignorer…"
|
|
43508
|
+
};
|
|
43509
|
+
const frUiChatAttachments = {
|
|
43510
|
+
"ui.chat.attachments.pending_caption": "Pas encore envoyé",
|
|
43511
|
+
"ui.chat.attachments.file_meta": "{type} · {size}",
|
|
43512
|
+
"ui.chat.attachments.file_missing": "Déplacé ou supprimé",
|
|
43513
|
+
"ui.chat.attachments.file_retained": "Toujours conservé dans le stockage des pièces jointes ({digest})",
|
|
43514
|
+
"ui.chat.attachments.file_unnamed": "Pièce jointe",
|
|
43515
|
+
"ui.chat.attachments.copy_path": "Copier le chemin",
|
|
43516
|
+
"ui.chat.attachments.path_copied": "Chemin copié",
|
|
43517
|
+
"ui.chat.attachments.file_missing_recovery": "Le fichier n'est plus à cet emplacement.",
|
|
43518
|
+
"ui.chat.attachments.file_type_unknown": "Fichier",
|
|
43519
|
+
"ui.chat.attachments.copy_saved_path": "Copier le chemin de la copie conservée",
|
|
43520
|
+
"ui.chat.attachments.saved_path_copied": "Chemin de la copie conservée copié",
|
|
43521
|
+
"ui.chat.attachments.saved_copy_label": "Copie conservée"
|
|
43522
|
+
};
|
|
43158
43523
|
const frUiChatComposer = {
|
|
43159
43524
|
"ui.chat.composer.clear_message": "Effacer le message",
|
|
43160
43525
|
"ui.chat.composer.message": "Message",
|
|
@@ -46796,6 +47161,34 @@ const hiUiCanvas = {
|
|
|
46796
47161
|
"ui.canvas.files.prepareError": "इस कार्रवाई के लिए स्थानीय कॉपी तैयार नहीं हो सकी",
|
|
46797
47162
|
"ui.canvas.files.pathCopyNote": "खोलने, फ़ोल्डर और पाथ की कार्रवाइयाँ इस बातचीत के स्क्रैचपैड में एक स्थानीय कॉपी बनाती हैं।"
|
|
46798
47163
|
};
|
|
47164
|
+
const hiUiChatAsks = {
|
|
47165
|
+
"ui.chat.asks.context.messages_since": "{count, plural, one {इस सवाल के बाद से आपका # संदेश} other {इस सवाल के बाद से आपके # संदेश}} (अंतिम संदेश {time})",
|
|
47166
|
+
"ui.chat.asks.dismiss.answered_in_chat.note": "आप बातचीत में पहले ही जवाब दे चुके हैं",
|
|
47167
|
+
"ui.chat.asks.dismiss.answered_in_chat.title": "चैट में जवाब दिया गया",
|
|
47168
|
+
"ui.chat.asks.dismiss.cancel": "रद्द करें",
|
|
47169
|
+
"ui.chat.asks.dismiss.heading": "यह सवाल हटाएँ",
|
|
47170
|
+
"ui.chat.asks.dismiss.in_flight": "हटाया जा रहा है…",
|
|
47171
|
+
"ui.chat.asks.dismiss.moot.note": "एजेंट अब जवाब का इंतज़ार नहीं करेगा",
|
|
47172
|
+
"ui.chat.asks.dismiss.moot.title": "अब ज़रूरत नहीं",
|
|
47173
|
+
"ui.chat.asks.dismiss.receipt.answered_in_chat": "हटाया गया — चैट में तय हो गया",
|
|
47174
|
+
"ui.chat.asks.dismiss.receipt.moot": "हटाया गया — अब ज़रूरत नहीं",
|
|
47175
|
+
"ui.chat.asks.dismiss.refused": "यह सवाल हटाया नहीं जा सका — कुछ भी नहीं भेजा गया।",
|
|
47176
|
+
"ui.chat.asks.dismiss.trigger": "हटाएँ…"
|
|
47177
|
+
};
|
|
47178
|
+
const hiUiChatAttachments = {
|
|
47179
|
+
"ui.chat.attachments.pending_caption": "अभी तक नहीं भेजा गया",
|
|
47180
|
+
"ui.chat.attachments.file_meta": "{type} · {size}",
|
|
47181
|
+
"ui.chat.attachments.file_missing": "स्थानांतरित या हटाया गया",
|
|
47182
|
+
"ui.chat.attachments.file_retained": "अभी भी अनुलग्नक स्टोर में सुरक्षित है ({digest})",
|
|
47183
|
+
"ui.chat.attachments.file_unnamed": "अनुलग्नक फ़ाइल",
|
|
47184
|
+
"ui.chat.attachments.copy_path": "पाथ कॉपी करें",
|
|
47185
|
+
"ui.chat.attachments.path_copied": "पाथ कॉपी हो गया",
|
|
47186
|
+
"ui.chat.attachments.file_missing_recovery": "फ़ाइल अब इस पाथ पर नहीं है।",
|
|
47187
|
+
"ui.chat.attachments.file_type_unknown": "फ़ाइल",
|
|
47188
|
+
"ui.chat.attachments.copy_saved_path": "सहेजी गई प्रति का पाथ कॉपी करें",
|
|
47189
|
+
"ui.chat.attachments.saved_path_copied": "सहेजी गई प्रति का पाथ कॉपी हो गया",
|
|
47190
|
+
"ui.chat.attachments.saved_copy_label": "सहेजी गई प्रति"
|
|
47191
|
+
};
|
|
46799
47192
|
const hiUiChatComposer = {
|
|
46800
47193
|
"ui.chat.composer.clear_message": "संदेश मिटाएँ",
|
|
46801
47194
|
"ui.chat.composer.message": "संदेश",
|
|
@@ -50395,6 +50788,34 @@ const ruUiCanvas = {
|
|
|
50395
50788
|
"ui.canvas.files.videos": "Видео",
|
|
50396
50789
|
"ui.canvas.files.working": "Рабочие файлы"
|
|
50397
50790
|
};
|
|
50791
|
+
const ruUiChatAsks = {
|
|
50792
|
+
"ui.chat.asks.context.messages_since": "{count, plural, one {# сообщение от вас с момента этого запроса} few {# сообщения от вас с момента этого запроса} many {# сообщений от вас с момента этого запроса} other {# сообщения от вас с момента этого запроса}} (последнее сообщение: {time})",
|
|
50793
|
+
"ui.chat.asks.dismiss.answered_in_chat.note": "вы уже ответили в чате",
|
|
50794
|
+
"ui.chat.asks.dismiss.answered_in_chat.title": "Ответ дан в чате",
|
|
50795
|
+
"ui.chat.asks.dismiss.cancel": "Отмена",
|
|
50796
|
+
"ui.chat.asks.dismiss.heading": "Убрать этот запрос",
|
|
50797
|
+
"ui.chat.asks.dismiss.in_flight": "Убираем…",
|
|
50798
|
+
"ui.chat.asks.dismiss.moot.note": "агент больше не будет ждать ответа",
|
|
50799
|
+
"ui.chat.asks.dismiss.moot.title": "Больше не нужно",
|
|
50800
|
+
"ui.chat.asks.dismiss.receipt.answered_in_chat": "Убрано — решено в чате",
|
|
50801
|
+
"ui.chat.asks.dismiss.receipt.moot": "Убрано — больше не нужно",
|
|
50802
|
+
"ui.chat.asks.dismiss.refused": "Не удалось убрать этот запрос — ничего не отправлено.",
|
|
50803
|
+
"ui.chat.asks.dismiss.trigger": "Убрать…"
|
|
50804
|
+
};
|
|
50805
|
+
const ruUiChatAttachments = {
|
|
50806
|
+
"ui.chat.attachments.pending_caption": "Ещё не отправлено",
|
|
50807
|
+
"ui.chat.attachments.file_meta": "{type} · {size}",
|
|
50808
|
+
"ui.chat.attachments.file_missing": "Перемещено или удалено",
|
|
50809
|
+
"ui.chat.attachments.file_retained": "Всё ещё хранится в хранилище вложений ({digest})",
|
|
50810
|
+
"ui.chat.attachments.file_unnamed": "Вложенный файл",
|
|
50811
|
+
"ui.chat.attachments.copy_path": "Скопировать путь",
|
|
50812
|
+
"ui.chat.attachments.path_copied": "Путь скопирован",
|
|
50813
|
+
"ui.chat.attachments.file_missing_recovery": "Файла по этому пути больше нет.",
|
|
50814
|
+
"ui.chat.attachments.file_type_unknown": "Файл",
|
|
50815
|
+
"ui.chat.attachments.copy_saved_path": "Скопировать путь сохранённой копии",
|
|
50816
|
+
"ui.chat.attachments.saved_path_copied": "Путь сохранённой копии скопирован",
|
|
50817
|
+
"ui.chat.attachments.saved_copy_label": "Сохранённая копия"
|
|
50818
|
+
};
|
|
50398
50819
|
const ruUiChatComposer = {
|
|
50399
50820
|
"ui.chat.composer.ask_aside": "Спросить отдельно",
|
|
50400
50821
|
"ui.chat.composer.attach_file": "Прикрепить файл",
|
|
@@ -54014,6 +54435,34 @@ const urUiCanvas = {
|
|
|
54014
54435
|
"ui.canvas.files.prepareError": "اس عمل کے لیے مقامی نقل تیار نہیں ہو سکی",
|
|
54015
54436
|
"ui.canvas.files.pathCopyNote": "کھولنے، فولڈر اور راستے کے اعمال اس گفتگو کے اسکریچ پیڈ میں مقامی نقل بناتے ہیں۔"
|
|
54016
54437
|
};
|
|
54438
|
+
const urUiChatAsks = {
|
|
54439
|
+
"ui.chat.asks.context.messages_since": "{count, plural, one {اس سوال کے بعد سے آپ کا # پیغام} other {اس سوال کے بعد سے آپ کے # پیغامات}} (آخری پیغام {time})",
|
|
54440
|
+
"ui.chat.asks.dismiss.answered_in_chat.note": "آپ گفتگو میں پہلے ہی جواب دے چکے ہیں",
|
|
54441
|
+
"ui.chat.asks.dismiss.answered_in_chat.title": "چیٹ میں جواب دیا گیا",
|
|
54442
|
+
"ui.chat.asks.dismiss.cancel": "منسوخ کریں",
|
|
54443
|
+
"ui.chat.asks.dismiss.heading": "یہ سوال ہٹائیں",
|
|
54444
|
+
"ui.chat.asks.dismiss.in_flight": "ہٹایا جا رہا ہے…",
|
|
54445
|
+
"ui.chat.asks.dismiss.moot.note": "ایجنٹ اب جواب کا انتظار نہیں کرے گا",
|
|
54446
|
+
"ui.chat.asks.dismiss.moot.title": "اب ضرورت نہیں",
|
|
54447
|
+
"ui.chat.asks.dismiss.receipt.answered_in_chat": "ہٹا دیا — چیٹ میں طے ہو گیا",
|
|
54448
|
+
"ui.chat.asks.dismiss.receipt.moot": "ہٹا دیا — اب ضرورت نہیں",
|
|
54449
|
+
"ui.chat.asks.dismiss.refused": "یہ سوال ہٹایا نہیں جا سکا — کچھ نہیں بھیجا گیا۔",
|
|
54450
|
+
"ui.chat.asks.dismiss.trigger": "ہٹائیں…"
|
|
54451
|
+
};
|
|
54452
|
+
const urUiChatAttachments = {
|
|
54453
|
+
"ui.chat.attachments.pending_caption": "ابھی نہیں بھیجا گیا",
|
|
54454
|
+
"ui.chat.attachments.file_meta": "{type} · {size}",
|
|
54455
|
+
"ui.chat.attachments.file_missing": "منتقل یا حذف شدہ",
|
|
54456
|
+
"ui.chat.attachments.file_retained": "اب بھی منسلکات کے ذخیرے میں محفوظ ہے ({digest})",
|
|
54457
|
+
"ui.chat.attachments.file_unnamed": "منسلک فائل",
|
|
54458
|
+
"ui.chat.attachments.copy_path": "راستہ نقل کریں",
|
|
54459
|
+
"ui.chat.attachments.path_copied": "راستہ نقل ہو گیا",
|
|
54460
|
+
"ui.chat.attachments.file_missing_recovery": "فائل اب اس راستے پر موجود نہیں ہے۔",
|
|
54461
|
+
"ui.chat.attachments.file_type_unknown": "فائل",
|
|
54462
|
+
"ui.chat.attachments.copy_saved_path": "محفوظ شدہ نقل کا راستہ نقل کریں",
|
|
54463
|
+
"ui.chat.attachments.saved_path_copied": "محفوظ شدہ نقل کا راستہ نقل ہو گیا",
|
|
54464
|
+
"ui.chat.attachments.saved_copy_label": "محفوظ شدہ نقل"
|
|
54465
|
+
};
|
|
54017
54466
|
const urUiChatComposer = {
|
|
54018
54467
|
"ui.chat.composer.clear_message": "پیغام صاف کریں",
|
|
54019
54468
|
"ui.chat.composer.message": "پیغام",
|
|
@@ -57633,6 +58082,34 @@ const viUiCanvas = {
|
|
|
57633
58082
|
"ui.canvas.files.prepareError": "Không chuẩn bị được bản sao cục bộ cho thao tác này",
|
|
57634
58083
|
"ui.canvas.files.pathCopyNote": "Các thao tác mở tệp, mở thư mục và thao tác với đường dẫn sẽ tạo bản sao cục bộ trong thư mục nháp của cuộc trò chuyện này."
|
|
57635
58084
|
};
|
|
58085
|
+
const viUiChatAsks = {
|
|
58086
|
+
"ui.chat.asks.context.messages_since": "{count, plural, other {# tin nhắn của bạn kể từ khi câu hỏi này được đưa ra}} (tin nhắn gần nhất lúc {time})",
|
|
58087
|
+
"ui.chat.asks.dismiss.answered_in_chat.note": "bạn đã trả lời trong cuộc trò chuyện",
|
|
58088
|
+
"ui.chat.asks.dismiss.answered_in_chat.title": "Đã trả lời trong cuộc trò chuyện",
|
|
58089
|
+
"ui.chat.asks.dismiss.cancel": "Hủy",
|
|
58090
|
+
"ui.chat.asks.dismiss.heading": "Bỏ qua câu hỏi này",
|
|
58091
|
+
"ui.chat.asks.dismiss.in_flight": "Đang bỏ qua…",
|
|
58092
|
+
"ui.chat.asks.dismiss.moot.note": "tác nhân sẽ không chờ câu trả lời nữa",
|
|
58093
|
+
"ui.chat.asks.dismiss.moot.title": "Không còn cần nữa",
|
|
58094
|
+
"ui.chat.asks.dismiss.receipt.answered_in_chat": "Đã bỏ qua — đã giải quyết trong cuộc trò chuyện",
|
|
58095
|
+
"ui.chat.asks.dismiss.receipt.moot": "Đã bỏ qua — không còn cần nữa",
|
|
58096
|
+
"ui.chat.asks.dismiss.refused": "Không thể bỏ qua câu hỏi này — không có gì được gửi đi.",
|
|
58097
|
+
"ui.chat.asks.dismiss.trigger": "Bỏ qua…"
|
|
58098
|
+
};
|
|
58099
|
+
const viUiChatAttachments = {
|
|
58100
|
+
"ui.chat.attachments.pending_caption": "Chưa được gửi",
|
|
58101
|
+
"ui.chat.attachments.file_meta": "{type} · {size}",
|
|
58102
|
+
"ui.chat.attachments.file_missing": "Đã di chuyển hoặc bị xóa",
|
|
58103
|
+
"ui.chat.attachments.file_retained": "Vẫn được lưu trong kho tệp đính kèm ({digest})",
|
|
58104
|
+
"ui.chat.attachments.file_unnamed": "Tệp đính kèm",
|
|
58105
|
+
"ui.chat.attachments.copy_path": "Sao chép đường dẫn",
|
|
58106
|
+
"ui.chat.attachments.path_copied": "Đã sao chép đường dẫn",
|
|
58107
|
+
"ui.chat.attachments.file_missing_recovery": "Tệp không còn ở đường dẫn này.",
|
|
58108
|
+
"ui.chat.attachments.file_type_unknown": "Tệp",
|
|
58109
|
+
"ui.chat.attachments.copy_saved_path": "Sao chép đường dẫn bản sao đã lưu",
|
|
58110
|
+
"ui.chat.attachments.saved_path_copied": "Đã sao chép đường dẫn bản sao đã lưu",
|
|
58111
|
+
"ui.chat.attachments.saved_copy_label": "Bản sao đã lưu"
|
|
58112
|
+
};
|
|
57636
58113
|
const viUiChatComposer = {
|
|
57637
58114
|
"ui.chat.composer.clear_message": "Xóa tin nhắn",
|
|
57638
58115
|
"ui.chat.composer.message": "Tin nhắn",
|
|
@@ -61061,6 +61538,34 @@ const zhCNUiCanvas = {
|
|
|
61061
61538
|
"ui.canvas.files.prepareError": "无法为此操作准备本地副本",
|
|
61062
61539
|
"ui.canvas.files.pathCopyNote": "打开文件、打开文件夹及路径相关操作会在此对话的暂存区中创建本地副本。"
|
|
61063
61540
|
};
|
|
61541
|
+
const zhCNUiChatAsks = {
|
|
61542
|
+
"ui.chat.asks.context.messages_since": "{count, plural, other {自提出这个请求以来你发来了#条消息}}(最后一条消息于{time})",
|
|
61543
|
+
"ui.chat.asks.dismiss.answered_in_chat.note": "你已在对话中回复过",
|
|
61544
|
+
"ui.chat.asks.dismiss.answered_in_chat.title": "已在对话中回答",
|
|
61545
|
+
"ui.chat.asks.dismiss.cancel": "取消",
|
|
61546
|
+
"ui.chat.asks.dismiss.heading": "关闭此请求",
|
|
61547
|
+
"ui.chat.asks.dismiss.in_flight": "正在关闭……",
|
|
61548
|
+
"ui.chat.asks.dismiss.moot.note": "无需继续等待",
|
|
61549
|
+
"ui.chat.asks.dismiss.moot.title": "不再需要",
|
|
61550
|
+
"ui.chat.asks.dismiss.receipt.answered_in_chat": "已关闭——已在对话中解决",
|
|
61551
|
+
"ui.chat.asks.dismiss.receipt.moot": "已关闭——不再需要",
|
|
61552
|
+
"ui.chat.asks.dismiss.refused": "无法关闭此请求——未发送任何内容。",
|
|
61553
|
+
"ui.chat.asks.dismiss.trigger": "关闭……"
|
|
61554
|
+
};
|
|
61555
|
+
const zhCNUiChatAttachments = {
|
|
61556
|
+
"ui.chat.attachments.pending_caption": "尚未发送",
|
|
61557
|
+
"ui.chat.attachments.file_meta": "{type} · {size}",
|
|
61558
|
+
"ui.chat.attachments.file_missing": "已移动或删除",
|
|
61559
|
+
"ui.chat.attachments.file_retained": "仍保留在附件存储中({digest})",
|
|
61560
|
+
"ui.chat.attachments.file_unnamed": "附件",
|
|
61561
|
+
"ui.chat.attachments.copy_path": "复制路径",
|
|
61562
|
+
"ui.chat.attachments.path_copied": "路径已复制",
|
|
61563
|
+
"ui.chat.attachments.file_missing_recovery": "该文件已不在这个路径。",
|
|
61564
|
+
"ui.chat.attachments.file_type_unknown": "文件",
|
|
61565
|
+
"ui.chat.attachments.copy_saved_path": "复制已保存副本的路径",
|
|
61566
|
+
"ui.chat.attachments.saved_path_copied": "已复制保存副本的路径",
|
|
61567
|
+
"ui.chat.attachments.saved_copy_label": "保存的副本"
|
|
61568
|
+
};
|
|
61064
61569
|
const zhCNUiChatComposer = {
|
|
61065
61570
|
"ui.chat.composer.clear_message": "清空消息",
|
|
61066
61571
|
"ui.chat.composer.message": "消息",
|
|
@@ -64091,6 +64596,8 @@ const bundledEnglish = {
|
|
|
64091
64596
|
...enUiBrowser,
|
|
64092
64597
|
...enUiCanvas,
|
|
64093
64598
|
...enUiChatAnalytics,
|
|
64599
|
+
...enUiChatAsks,
|
|
64600
|
+
...enUiChatAttachments,
|
|
64094
64601
|
...enUiChatCanonical,
|
|
64095
64602
|
...enUiChatCommentaryActions,
|
|
64096
64603
|
...enUiChatComposer,
|
|
@@ -64165,6 +64672,8 @@ const bundledCatalogues = {
|
|
|
64165
64672
|
...esUiBrowserChrome,
|
|
64166
64673
|
...esUiBrowser,
|
|
64167
64674
|
...esUiCanvas,
|
|
64675
|
+
...esUiChatAsks,
|
|
64676
|
+
...esUiChatAttachments,
|
|
64168
64677
|
...esUiChatComposer,
|
|
64169
64678
|
...esUiChatComposerMedia,
|
|
64170
64679
|
...esUiChatDialogs,
|
|
@@ -64229,6 +64738,8 @@ const bundledCatalogues = {
|
|
|
64229
64738
|
...frUiBrowserChrome,
|
|
64230
64739
|
...frUiBrowser,
|
|
64231
64740
|
...frUiCanvas,
|
|
64741
|
+
...frUiChatAsks,
|
|
64742
|
+
...frUiChatAttachments,
|
|
64232
64743
|
...frUiChatComposer,
|
|
64233
64744
|
...frUiChatComposerMedia,
|
|
64234
64745
|
...frUiChatDialogs,
|
|
@@ -64293,6 +64804,8 @@ const bundledCatalogues = {
|
|
|
64293
64804
|
...hiUiBrowserChrome,
|
|
64294
64805
|
...hiUiBrowser,
|
|
64295
64806
|
...hiUiCanvas,
|
|
64807
|
+
...hiUiChatAsks,
|
|
64808
|
+
...hiUiChatAttachments,
|
|
64296
64809
|
...hiUiChatComposer,
|
|
64297
64810
|
...hiUiChatComposerMedia,
|
|
64298
64811
|
...hiUiChatDialogs,
|
|
@@ -64354,6 +64867,8 @@ const bundledCatalogues = {
|
|
|
64354
64867
|
...ruUiBrowserChrome,
|
|
64355
64868
|
...ruUiBrowser,
|
|
64356
64869
|
...ruUiCanvas,
|
|
64870
|
+
...ruUiChatAsks,
|
|
64871
|
+
...ruUiChatAttachments,
|
|
64357
64872
|
...ruUiChatComposer,
|
|
64358
64873
|
...ruUiChatComposerMedia,
|
|
64359
64874
|
...ruUiChatDialogs,
|
|
@@ -64416,6 +64931,8 @@ const bundledCatalogues = {
|
|
|
64416
64931
|
...urUiBrowserChrome,
|
|
64417
64932
|
...urUiBrowser,
|
|
64418
64933
|
...urUiCanvas,
|
|
64934
|
+
...urUiChatAsks,
|
|
64935
|
+
...urUiChatAttachments,
|
|
64419
64936
|
...urUiChatComposer,
|
|
64420
64937
|
...urUiChatComposerMedia,
|
|
64421
64938
|
...urUiChatDialogs,
|
|
@@ -64478,6 +64995,8 @@ const bundledCatalogues = {
|
|
|
64478
64995
|
...viUiBrowserChrome,
|
|
64479
64996
|
...viUiBrowser,
|
|
64480
64997
|
...viUiCanvas,
|
|
64998
|
+
...viUiChatAsks,
|
|
64999
|
+
...viUiChatAttachments,
|
|
64481
65000
|
...viUiChatComposer,
|
|
64482
65001
|
...viUiChatComposerMedia,
|
|
64483
65002
|
...viUiChatDialogs,
|
|
@@ -64539,6 +65058,8 @@ const bundledCatalogues = {
|
|
|
64539
65058
|
...zhCNUiBrowserChrome,
|
|
64540
65059
|
...zhCNUiBrowser,
|
|
64541
65060
|
...zhCNUiCanvas,
|
|
65061
|
+
...zhCNUiChatAsks,
|
|
65062
|
+
...zhCNUiChatAttachments,
|
|
64542
65063
|
...zhCNUiChatComposer,
|
|
64543
65064
|
...zhCNUiChatComposerMedia,
|
|
64544
65065
|
...zhCNUiChatDialogs,
|
|
@@ -64929,6 +65450,7 @@ function matches(haystack, needle, substring) {
|
|
|
64929
65450
|
if (!right) return false;
|
|
64930
65451
|
return substring ? left.includes(right) : left === right;
|
|
64931
65452
|
}
|
|
65453
|
+
const NEVER_TARGETED = /* @__PURE__ */ new Set(["StaticText", "InlineTextBox", "none", "generic"]);
|
|
64932
65454
|
function candidateNodes(nodes) {
|
|
64933
65455
|
return nodes.filter((node) => !node.ignored && node.backendDOMNodeId !== void 0);
|
|
64934
65456
|
}
|
|
@@ -64943,11 +65465,11 @@ function resolveLocator(nodes, locator) {
|
|
|
64943
65465
|
}
|
|
64944
65466
|
return matches(name, locator.name, locator.substring);
|
|
64945
65467
|
};
|
|
64946
|
-
const collect = (
|
|
65468
|
+
const collect = (accept2) => {
|
|
64947
65469
|
for (const node of pool) {
|
|
64948
65470
|
const role = String(node.role?.value ?? "");
|
|
64949
65471
|
const name = normalise(node.name?.value);
|
|
64950
|
-
if (!
|
|
65472
|
+
if (!accept2(role)) continue;
|
|
64951
65473
|
if (!consider(role, name)) continue;
|
|
64952
65474
|
hits.push({ backendNodeId: node.backendDOMNodeId, role, name, matched: 0 });
|
|
64953
65475
|
}
|
|
@@ -64965,9 +65487,9 @@ function resolveLocator(nodes, locator) {
|
|
|
64965
65487
|
if (!first) return null;
|
|
64966
65488
|
return { ...first, matched: hits.length };
|
|
64967
65489
|
}
|
|
64968
|
-
function locatorSuggestions(nodes,
|
|
64969
|
-
const wanted = normalise(
|
|
64970
|
-
const parsed = parseLocator(
|
|
65490
|
+
function locatorSuggestions(nodes, query2, limit = 5) {
|
|
65491
|
+
const wanted = normalise(query2).toLowerCase();
|
|
65492
|
+
const parsed = parseLocator(query2);
|
|
64971
65493
|
const term = parsed ? parsed.name.toLowerCase() : wanted;
|
|
64972
65494
|
const words = term.split(/[^a-z0-9]+/).filter((word) => word.length > 1);
|
|
64973
65495
|
const wantedRole = parsed && parsed.kind === "role" ? parsed.role : "";
|
|
@@ -64976,13 +65498,14 @@ function locatorSuggestions(nodes, query, limit = 5) {
|
|
|
64976
65498
|
const role = String(node.role?.value ?? "");
|
|
64977
65499
|
const name = normalise(node.name?.value);
|
|
64978
65500
|
if (!name) continue;
|
|
65501
|
+
if (NEVER_TARGETED.has(role)) continue;
|
|
64979
65502
|
const lowerName = name.toLowerCase();
|
|
64980
65503
|
let score = 0;
|
|
64981
65504
|
if (term && lowerName === term) score += 100;
|
|
64982
65505
|
else if (term && lowerName.includes(term)) score += 60;
|
|
64983
65506
|
for (const word of words) if (lowerName.includes(word)) score += 8;
|
|
64984
65507
|
if (wantedRole && role.toLowerCase() === wantedRole) score += 25;
|
|
64985
|
-
if (CLICKABLE.has(role)) score +=
|
|
65508
|
+
if (CLICKABLE.has(role)) score += 12;
|
|
64986
65509
|
if (!score) continue;
|
|
64987
65510
|
scored.push({ score, role, name });
|
|
64988
65511
|
}
|
|
@@ -65876,11 +66399,32 @@ async function nodeIdForSelector(ctx, view, selector) {
|
|
|
65876
66399
|
if (!queried?.nodeId) {
|
|
65877
66400
|
throw new BridgeCommandError(
|
|
65878
66401
|
"element_not_found",
|
|
65879
|
-
`selector ${selector} matched nothing
|
|
66402
|
+
`selector ${selector} matched nothing`,
|
|
66403
|
+
{ candidates: await missCandidates(ctx, view, selector) }
|
|
65880
66404
|
);
|
|
65881
66405
|
}
|
|
65882
66406
|
return queried.nodeId;
|
|
65883
66407
|
}
|
|
66408
|
+
async function readAccessibilityTree(ctx, contents) {
|
|
66409
|
+
await ctx.cdp.send(contents, "Accessibility.enable", {});
|
|
66410
|
+
try {
|
|
66411
|
+
const tree = await ctx.cdp.send(
|
|
66412
|
+
contents,
|
|
66413
|
+
"Accessibility.getFullAXTree",
|
|
66414
|
+
{}
|
|
66415
|
+
);
|
|
66416
|
+
return Array.isArray(tree?.nodes) ? tree.nodes : [];
|
|
66417
|
+
} finally {
|
|
66418
|
+
await ctx.cdp.send(contents, "Accessibility.disable", {}).catch(() => {
|
|
66419
|
+
});
|
|
66420
|
+
}
|
|
66421
|
+
}
|
|
66422
|
+
async function missCandidates(ctx, view, selector) {
|
|
66423
|
+
const nodes = await readAccessibilityTree(ctx, view.webContents).catch(
|
|
66424
|
+
() => []
|
|
66425
|
+
);
|
|
66426
|
+
return locatorSuggestions(nodes, selector);
|
|
66427
|
+
}
|
|
65884
66428
|
async function backendNodeIdForSelector(ctx, view, selector) {
|
|
65885
66429
|
const nodeId = await nodeIdForSelector(ctx, view, selector);
|
|
65886
66430
|
const described = await ctx.cdp.send(
|
|
@@ -66008,20 +66552,6 @@ function resolvedFields(node) {
|
|
|
66008
66552
|
function frameFields(node) {
|
|
66009
66553
|
return node.frame ? { frame_origin: node.frame.origin ?? "" } : {};
|
|
66010
66554
|
}
|
|
66011
|
-
async function readAccessibilityTree(ctx, contents) {
|
|
66012
|
-
await ctx.cdp.send(contents, "Accessibility.enable", {});
|
|
66013
|
-
try {
|
|
66014
|
-
const tree = await ctx.cdp.send(
|
|
66015
|
-
contents,
|
|
66016
|
-
"Accessibility.getFullAXTree",
|
|
66017
|
-
{}
|
|
66018
|
-
);
|
|
66019
|
-
return Array.isArray(tree?.nodes) ? tree.nodes : [];
|
|
66020
|
-
} finally {
|
|
66021
|
-
await ctx.cdp.send(contents, "Accessibility.disable", {}).catch(() => {
|
|
66022
|
-
});
|
|
66023
|
-
}
|
|
66024
|
-
}
|
|
66025
66555
|
async function resolveNode(ctx, record, target2) {
|
|
66026
66556
|
const view = record.view;
|
|
66027
66557
|
const contents = view.webContents;
|
|
@@ -66455,6 +66985,7 @@ function clampTimeout(requested) {
|
|
|
66455
66985
|
const READ_STYLES_SOURCE = '(selector, properties) => {\n const DEFAULTS = [\n "display",\n "position",\n "visibility",\n "opacity",\n "z-index",\n "transform",\n "transform-origin",\n "top",\n "right",\n "bottom",\n "left",\n "width",\n "height",\n "contain",\n "filter",\n "will-change",\n "overflow",\n "overflow-x",\n "overflow-y",\n "pointer-events"\n ];\n const MAX_MATCHES = 5;\n const MAX_STYLES = 30;\n const MAX_INLINE = 30;\n const MAX_IDENTITY = 120;\n const MAX_VALUE = 200;\n const all = document.querySelectorAll(selector);\n if (!all || all.length === 0) return null;\n const names = DEFAULTS.slice();\n if (Array.isArray(properties)) {\n for (let i = 0; i < properties.length && names.length < MAX_STYLES; i++) {\n const name = String(properties[i] ?? "").trim();\n if (name && names.indexOf(name) === -1) names.push(name);\n }\n }\n const round2 = (value) => {\n const rounded = Math.round(value * 100) / 100;\n return rounded === 0 ? 0 : rounded;\n };\n const clip = (value, limit) => value.length > limit ? value.slice(0, limit - 1) + "\\u2026" : value;\n const rectOf = (el) => {\n const r = el.getBoundingClientRect();\n return {\n x: round2(r.x),\n y: round2(r.y),\n top: round2(r.top),\n right: round2(r.right),\n bottom: round2(r.bottom),\n width: round2(r.width),\n height: round2(r.height)\n };\n };\n const attrOf = (el, name) => clip(el.getAttribute(name) || "", MAX_IDENTITY);\n const matches = [];\n const first = Array.from(all).slice(0, MAX_MATCHES);\n for (const el of first) {\n const computed = getComputedStyle(el);\n const styles = {};\n for (const name of names) {\n styles[name] = clip(String(computed.getPropertyValue(name) || "").trim(), MAX_VALUE);\n }\n const inline = {};\n const declaration = el.style;\n let inlineCount = 0;\n for (let j = 0; j < declaration.length && inlineCount < MAX_INLINE; j++) {\n const name = declaration.item(j);\n if (name && name.indexOf("--") === 0) {\n const key = clip(name, MAX_IDENTITY);\n if (!(key in inline)) {\n inline[key] = clip(\n String(declaration.getPropertyValue(name) || "").trim(),\n MAX_VALUE\n );\n inlineCount += 1;\n }\n }\n }\n matches.push({\n tag: clip(el.tagName.toLowerCase(), MAX_IDENTITY),\n id: attrOf(el, "id"),\n role: attrOf(el, "role"),\n className: attrOf(el, "class"),\n rect: rectOf(el),\n styles,\n inline\n });\n }\n return { count: matches.length, matches, truncated: all.length > matches.length };\n}';
|
|
66456
66986
|
const HIT_TEST_SOURCE = '(x, y) => {\n const PROPS = ["display", "position", "visibility", "opacity", "z-index", "pointer-events"];\n const MAX_ELEMENTS = 8;\n const MAX_IDENTITY = 120;\n const MAX_VALUE = 200;\n const px = Number(x);\n const py = Number(y);\n if (!Number.isFinite(px) || !Number.isFinite(py)) return null;\n const stack = document.elementsFromPoint(px, py);\n if (!stack || stack.length === 0) return null;\n const round2 = (value) => {\n const rounded = Math.round(value * 100) / 100;\n return rounded === 0 ? 0 : rounded;\n };\n const clip = (value, limit) => value.length > limit ? value.slice(0, limit - 1) + "\\u2026" : value;\n const attrOf = (el, name) => clip(el.getAttribute(name) || "", MAX_IDENTITY);\n const elements = [];\n for (const el of stack.slice(0, MAX_ELEMENTS)) {\n const computed = getComputedStyle(el);\n const styles = {};\n for (const name of PROPS) {\n styles[name] = clip(String(computed.getPropertyValue(name) || "").trim(), MAX_VALUE);\n }\n const r = el.getBoundingClientRect();\n elements.push({\n tag: clip(el.tagName.toLowerCase(), MAX_IDENTITY),\n id: attrOf(el, "id"),\n role: attrOf(el, "role"),\n className: attrOf(el, "class"),\n rect: {\n x: round2(r.x),\n y: round2(r.y),\n top: round2(r.top),\n right: round2(r.right),\n bottom: round2(r.bottom),\n width: round2(r.width),\n height: round2(r.height)\n },\n styles\n });\n }\n return { count: elements.length, elements };\n}';
|
|
66457
66987
|
const ANCESTORS_SOURCE = '(selector, depth) => {\n const PROPS = [\n "display",\n "position",\n "visibility",\n "overflow",\n "overflow-x",\n "overflow-y",\n "transform",\n "transform-origin",\n "contain",\n "filter",\n "will-change",\n "z-index",\n "isolation",\n "top",\n "left"\n ];\n const DEFAULT_DEPTH = 12;\n const MAX_DEPTH = 16;\n const MAX_IDENTITY = 120;\n const MAX_VALUE = 200;\n const el = document.querySelector(selector);\n if (!el) return null;\n const wanted = typeof depth === "number" && Number.isFinite(depth) ? Math.floor(depth) : DEFAULT_DEPTH;\n const bound = Math.max(1, Math.min(MAX_DEPTH, wanted));\n const round2 = (value) => {\n const rounded = Math.round(value * 100) / 100;\n return rounded === 0 ? 0 : rounded;\n };\n const clip = (value, limit) => value.length > limit ? value.slice(0, limit - 1) + "\\u2026" : value;\n const attrOf = (el2, name) => clip(el2.getAttribute(name) || "", MAX_IDENTITY);\n const chain = [];\n let node = el;\n while (node && chain.length < bound) {\n const computed = getComputedStyle(node);\n const styles = {};\n for (const name of PROPS) {\n styles[name] = clip(String(computed.getPropertyValue(name) || "").trim(), MAX_VALUE);\n }\n const r = node.getBoundingClientRect();\n chain.push({\n tag: clip(node.tagName.toLowerCase(), MAX_IDENTITY),\n id: attrOf(node, "id"),\n role: attrOf(node, "role"),\n className: attrOf(node, "class"),\n rect: {\n x: round2(r.x),\n y: round2(r.y),\n top: round2(r.top),\n right: round2(r.right),\n bottom: round2(r.bottom),\n width: round2(r.width),\n height: round2(r.height)\n },\n styles\n });\n if (node === document.documentElement) break;\n node = node.parentElement;\n }\n return { count: chain.length, chain };\n}';
|
|
66988
|
+
const QUERY_SOURCE = '(selector, limit) => {\n const MAX_ELEMENTS = 50;\n const MAX_IDENTITY = 120;\n const MAX_TEXT = 120;\n const MAX_VALUE = 120;\n if (typeof selector !== "string" || !selector.trim()) return null;\n const wanted = typeof limit === "number" && Number.isFinite(limit) ? Math.floor(limit) : 20;\n const bound = Math.max(1, Math.min(MAX_ELEMENTS, wanted));\n const round2 = (value) => {\n const rounded = Math.round(value * 100) / 100;\n return rounded === 0 ? 0 : rounded;\n };\n const clip = (value, cap) => value.length > cap ? `${value.slice(0, cap - 1)}\\u2026` : value;\n const attrOf = (el, name) => clip(String(el.getAttribute(name) || ""), MAX_IDENTITY);\n const visibleOf = (el, rect) => {\n if (rect.width <= 0 || rect.height <= 0) return false;\n const computed = getComputedStyle(el);\n if (computed.display === "none" || computed.visibility === "hidden") return false;\n return computed.contentVisibility !== "hidden";\n };\n let nodes;\n try {\n nodes = Array.from(document.querySelectorAll(selector));\n } catch {\n return { count: 0, truncated: false, matches: [], error: "invalid_selector" };\n }\n const viewport = {\n width: document.documentElement.clientWidth || window.innerWidth || 0,\n height: document.documentElement.clientHeight || window.innerHeight || 0\n };\n const matches = [];\n for (const el of nodes.slice(0, bound)) {\n const rect = el.getBoundingClientRect();\n const tag = clip(String(el.tagName || "").toLowerCase(), MAX_IDENTITY);\n const type = attrOf(el, "type").toLowerCase();\n const isPassword = tag === "input" && type === "password";\n const rawValue = el.value;\n const checkable = tag === "input" && (type === "checkbox" || type === "radio");\n const checked = checkable ? Boolean(el.checked) : null;\n matches.push({\n tag,\n id: attrOf(el, "id"),\n name: attrOf(el, "name"),\n role: attrOf(el, "role"),\n ariaLabel: attrOf(el, "aria-label"),\n // `innerText` is the RENDERED text (a hidden node reports ""), which is\n // what an agent reading a page means by "the text"; `textContent` would\n // report text nobody can see, including inside a collapsed section.\n text: clip(String(el.innerText || "").replace(/\\s+/g, " ").trim(), MAX_TEXT),\n type,\n visible: visibleOf(el, rect),\n inView: rect.top < viewport.height && rect.bottom > 0 && rect.left < viewport.width && rect.right > 0,\n disabled: el.hasAttribute("disabled") || el.disabled === true,\n checked,\n value: isPassword || rawValue === void 0 || rawValue === null ? "" : clip(String(rawValue), MAX_VALUE),\n rect: {\n x: round2(rect.x),\n y: round2(rect.y),\n width: round2(rect.width),\n height: round2(rect.height)\n }\n });\n }\n return { count: nodes.length, truncated: nodes.length > matches.length, matches };\n}';
|
|
66458
66989
|
const MAX_REQUESTED_PROPERTIES = 20;
|
|
66459
66990
|
const DEFAULT_DEPTH = 12;
|
|
66460
66991
|
const MAX_DEPTH = 16;
|
|
@@ -66581,6 +67112,51 @@ async function ancestors(ctx, params) {
|
|
|
66581
67112
|
...pageOf(record.view)
|
|
66582
67113
|
};
|
|
66583
67114
|
}
|
|
67115
|
+
const DEFAULT_LIMIT = 20;
|
|
67116
|
+
const MAX_LIMIT = 50;
|
|
67117
|
+
async function query(ctx, params) {
|
|
67118
|
+
const record = ctx.registry.requireSurface(params.tab);
|
|
67119
|
+
const selector = stringParam(params, "selector");
|
|
67120
|
+
if (!selector) {
|
|
67121
|
+
throw new BridgeCommandError("element_not_found", "selector is required");
|
|
67122
|
+
}
|
|
67123
|
+
const requested = numberParam(params, "limit") ?? DEFAULT_LIMIT;
|
|
67124
|
+
const limit = Math.max(1, Math.min(MAX_LIMIT, Math.floor(requested)));
|
|
67125
|
+
const code = `(${QUERY_SOURCE})(${JSON.stringify(selector)}, ${JSON.stringify(limit)})`;
|
|
67126
|
+
let result;
|
|
67127
|
+
try {
|
|
67128
|
+
result = await deadline(
|
|
67129
|
+
record.view.webContents.executeJavaScriptInIsolatedWorld(
|
|
67130
|
+
ISOLATED_WORLD_ID,
|
|
67131
|
+
[{ code }]
|
|
67132
|
+
),
|
|
67133
|
+
SCRIPTING_DEADLINE_MS,
|
|
67134
|
+
`query(${record.tabId})`
|
|
67135
|
+
);
|
|
67136
|
+
} catch (error) {
|
|
67137
|
+
if (error instanceof Error && INVALID_SELECTOR.test(error.message)) {
|
|
67138
|
+
throw new BridgeCommandError(
|
|
67139
|
+
"element_not_found",
|
|
67140
|
+
`selector ${selector} is not valid`
|
|
67141
|
+
);
|
|
67142
|
+
}
|
|
67143
|
+
throw error;
|
|
67144
|
+
}
|
|
67145
|
+
if (typeof result !== "object" || result === null) {
|
|
67146
|
+
throw new BridgeCommandError(
|
|
67147
|
+
"internal",
|
|
67148
|
+
"the page returned no structured query result"
|
|
67149
|
+
);
|
|
67150
|
+
}
|
|
67151
|
+
if (result.error === "invalid_selector") {
|
|
67152
|
+
throw new BridgeCommandError(
|
|
67153
|
+
"element_not_found",
|
|
67154
|
+
`selector ${selector} is not valid`
|
|
67155
|
+
);
|
|
67156
|
+
}
|
|
67157
|
+
ctx.registry.touch(record);
|
|
67158
|
+
return { ...result, ...pageOf(record.view) };
|
|
67159
|
+
}
|
|
66584
67160
|
const MAX_AGENT_TABS = 8;
|
|
66585
67161
|
const BACKGROUND_VIEWPORT = {
|
|
66586
67162
|
x: 0,
|
|
@@ -67468,7 +68044,7 @@ async function upload(ctx, params) {
|
|
|
67468
68044
|
{ selector, frame_origin: node.frame.origin ?? "" }
|
|
67469
68045
|
);
|
|
67470
68046
|
}
|
|
67471
|
-
const
|
|
68047
|
+
const accept2 = await acceptsOf(ctx, record, node.nodeId);
|
|
67472
68048
|
await ctx.cdp.send(contents, "DOM.setFileInputFiles", {
|
|
67473
68049
|
files: paths,
|
|
67474
68050
|
nodeId: node.nodeId
|
|
@@ -67476,7 +68052,7 @@ async function upload(ctx, params) {
|
|
|
67476
68052
|
if (!/not a file input/i.test(String(error))) throw error;
|
|
67477
68053
|
throw new BridgeCommandError("element_not_found", NOT_A_FILE_INPUT, {
|
|
67478
68054
|
selector,
|
|
67479
|
-
accept
|
|
68055
|
+
accept: accept2
|
|
67480
68056
|
});
|
|
67481
68057
|
});
|
|
67482
68058
|
let held = null;
|
|
@@ -67490,10 +68066,10 @@ async function upload(ctx, params) {
|
|
|
67490
68066
|
if (!held) {
|
|
67491
68067
|
throw new BridgeCommandError("element_not_found", NOT_A_FILE_INPUT, {
|
|
67492
68068
|
selector,
|
|
67493
|
-
accept
|
|
68069
|
+
accept: accept2
|
|
67494
68070
|
});
|
|
67495
68071
|
}
|
|
67496
|
-
assertHolds(paths, held, selector,
|
|
68072
|
+
assertHolds(paths, held, selector, accept2);
|
|
67497
68073
|
}
|
|
67498
68074
|
ctx.registry.touch(record);
|
|
67499
68075
|
const facts = paths.map(factOf);
|
|
@@ -67574,7 +68150,7 @@ async function readBack(ctx, record, objectId) {
|
|
|
67574
68150
|
});
|
|
67575
68151
|
return answer?.result?.value ?? null;
|
|
67576
68152
|
}
|
|
67577
|
-
function assertHolds(paths, held, selector,
|
|
68153
|
+
function assertHolds(paths, held, selector, accept2) {
|
|
67578
68154
|
const expected = paths.map((path2) => path$1.basename(path2));
|
|
67579
68155
|
const mismatch = held.count !== expected.length || expected.some((name, index) => held.names[index] !== name) || paths.some((path2, index) => sizeOf(path2) !== held.sizes[index]);
|
|
67580
68156
|
if (!mismatch) return;
|
|
@@ -67585,7 +68161,7 @@ function assertHolds(paths, held, selector, accept) {
|
|
|
67585
68161
|
selector,
|
|
67586
68162
|
attached: expected,
|
|
67587
68163
|
held: held.names,
|
|
67588
|
-
accept,
|
|
68164
|
+
accept: accept2,
|
|
67589
68165
|
reason: "read_back_mismatch"
|
|
67590
68166
|
}
|
|
67591
68167
|
);
|
|
@@ -67740,7 +68316,7 @@ function collectAddressHistory(tabs2, activeTabId) {
|
|
|
67740
68316
|
function foldAscii(value) {
|
|
67741
68317
|
return value.replace(/[A-Z]/g, (letter) => letter.toLowerCase());
|
|
67742
68318
|
}
|
|
67743
|
-
function mergeAddressHistory(tabEntries, historyEntries,
|
|
68319
|
+
function mergeAddressHistory(tabEntries, historyEntries, query2, limit) {
|
|
67744
68320
|
const cap = Math.max(0, Math.floor(limit));
|
|
67745
68321
|
if (cap === 0) return [];
|
|
67746
68322
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -67758,7 +68334,7 @@ function mergeAddressHistory(tabEntries, historyEntries, query, limit) {
|
|
|
67758
68334
|
source: "history"
|
|
67759
68335
|
});
|
|
67760
68336
|
}
|
|
67761
|
-
const needle = foldAscii(
|
|
68337
|
+
const needle = foldAscii(query2.trim());
|
|
67762
68338
|
for (const entry of tabEntries) {
|
|
67763
68339
|
if (merged.length >= cap) break;
|
|
67764
68340
|
if (seen.has(entry.url)) continue;
|
|
@@ -68192,25 +68768,25 @@ class PageControls {
|
|
|
68192
68768
|
};
|
|
68193
68769
|
active.view.webContents.on("found-in-page", this.listener);
|
|
68194
68770
|
}
|
|
68195
|
-
search(active,
|
|
68771
|
+
search(active, query2, forward, next) {
|
|
68196
68772
|
this.open(active);
|
|
68197
68773
|
if (!this.find || this.record !== active) return;
|
|
68198
68774
|
this.stopTimer();
|
|
68199
|
-
const same = this.find.query ===
|
|
68775
|
+
const same = this.find.query === query2;
|
|
68200
68776
|
const continuing = same && next && this.requestId !== null && !this.find.unreported;
|
|
68201
68777
|
this.requestId = null;
|
|
68202
68778
|
this.find = {
|
|
68203
68779
|
...this.find,
|
|
68204
|
-
query,
|
|
68205
|
-
pending:
|
|
68780
|
+
query: query2,
|
|
68781
|
+
pending: query2.length > 0,
|
|
68206
68782
|
unreported: false,
|
|
68207
68783
|
...same ? {} : { ordinal: 0, matches: 0 }
|
|
68208
68784
|
};
|
|
68209
|
-
if (!
|
|
68785
|
+
if (!query2) {
|
|
68210
68786
|
active.view.webContents.stopFindInPage?.("clearSelection");
|
|
68211
68787
|
return;
|
|
68212
68788
|
}
|
|
68213
|
-
this.requestId = active.view.webContents.findInPage?.(
|
|
68789
|
+
this.requestId = active.view.webContents.findInPage?.(query2, {
|
|
68214
68790
|
forward,
|
|
68215
68791
|
// Electron's misleading name means NEW SESSION (44.3 native maps
|
|
68216
68792
|
// it to options->new_session), not "advance". Initial/changed/retry
|
|
@@ -68365,6 +68941,12 @@ const DOCUMENT_SCOPED = /* @__PURE__ */ new Set([
|
|
|
68365
68941
|
"hit_test",
|
|
68366
68942
|
"ancestors",
|
|
68367
68943
|
"snapshot",
|
|
68944
|
+
// `query` is a read of the CURRENT document's DOM (CSS in, descriptors out),
|
|
68945
|
+
// so it is authorized against that document on entry and again on the result
|
|
68946
|
+
// exactly as `read` is: an answer that raced a navigation it did not cause
|
|
68947
|
+
// must be discarded, not reported as the new page's (agent review round 2 on
|
|
68948
|
+
// the query slice — the action was missing from BOTH sets).
|
|
68949
|
+
"query",
|
|
68368
68950
|
"screenshot",
|
|
68369
68951
|
"click",
|
|
68370
68952
|
"type",
|
|
@@ -68395,6 +68977,7 @@ const TAB_SCOPED = /* @__PURE__ */ new Set([
|
|
|
68395
68977
|
"hit_test",
|
|
68396
68978
|
"ancestors",
|
|
68397
68979
|
"snapshot",
|
|
68980
|
+
"query",
|
|
68398
68981
|
"screenshot",
|
|
68399
68982
|
"click",
|
|
68400
68983
|
"type",
|
|
@@ -68612,6 +69195,8 @@ class BrowserHost {
|
|
|
68612
69195
|
return hitTest(this, params);
|
|
68613
69196
|
case "ancestors":
|
|
68614
69197
|
return ancestors(this, params);
|
|
69198
|
+
case "query":
|
|
69199
|
+
return query(this, params);
|
|
68615
69200
|
case "snapshot":
|
|
68616
69201
|
return snapshot(this, params);
|
|
68617
69202
|
case "scroll":
|
|
@@ -69023,7 +69608,7 @@ class BrowserHost {
|
|
|
69023
69608
|
onChordFocusChanged;
|
|
69024
69609
|
/** An explicit tab id fences queued chrome intents: a switch between key
|
|
69025
69610
|
* delivery and IPC must never search/zoom the newly active tab instead. */
|
|
69026
|
-
async controlPage(tabId, action,
|
|
69611
|
+
async controlPage(tabId, action, query2 = "", forward = true, next = false) {
|
|
69027
69612
|
return this.registry.lane(tabId, async () => {
|
|
69028
69613
|
const active = this.registry.activeTab;
|
|
69029
69614
|
if (!active || active.tabId !== tabId || !active.presented || active.view.webContents.isDestroyed())
|
|
@@ -69032,7 +69617,7 @@ class BrowserHost {
|
|
|
69032
69617
|
else if (action === "print") this.pageControls.print(active);
|
|
69033
69618
|
else if (action === "close") this.pageControls.clear();
|
|
69034
69619
|
else if (action === "search")
|
|
69035
|
-
this.pageControls.search(active,
|
|
69620
|
+
this.pageControls.search(active, query2, forward, next);
|
|
69036
69621
|
else this.pageControls.zoom(active, action);
|
|
69037
69622
|
this.onChanged();
|
|
69038
69623
|
return this.chromeState();
|
|
@@ -70682,18 +71267,18 @@ function registerBrowserIpc(options) {
|
|
|
70682
71267
|
});
|
|
70683
71268
|
electron.ipcMain.handle(
|
|
70684
71269
|
"browser-page-control",
|
|
70685
|
-
(event, tabId, action,
|
|
71270
|
+
(event, tabId, action, query2, forward, next) => {
|
|
70686
71271
|
const host = authorize(event);
|
|
70687
71272
|
if (typeof action !== "string" || !["open", "close", "search", "print", "in", "out", "reset"].includes(
|
|
70688
71273
|
action
|
|
70689
71274
|
))
|
|
70690
71275
|
throw new Error("Invalid page control action.");
|
|
70691
|
-
if (typeof
|
|
71276
|
+
if (typeof query2 !== "string" || query2.length > 4096 || typeof forward !== "boolean" || typeof next !== "boolean")
|
|
70692
71277
|
throw new Error("Invalid page search input.");
|
|
70693
71278
|
return host.controlPage(
|
|
70694
71279
|
numberOrThrow(tabId, "tabId"),
|
|
70695
71280
|
action,
|
|
70696
|
-
|
|
71281
|
+
query2,
|
|
70697
71282
|
forward,
|
|
70698
71283
|
next
|
|
70699
71284
|
);
|
|
@@ -70903,14 +71488,14 @@ function addressHistoryRequestOrThrow(value) {
|
|
|
70903
71488
|
if (typeof request.query !== "string") {
|
|
70904
71489
|
throw new Error("The address history query must be a string.");
|
|
70905
71490
|
}
|
|
70906
|
-
const
|
|
70907
|
-
if (
|
|
71491
|
+
const query2 = request.query;
|
|
71492
|
+
if (query2.length > ADDRESS_HISTORY_MAX_QUERY_LENGTH || CONTROL_CHARS.test(query2)) {
|
|
70908
71493
|
throw new Error("The address history query is invalid.");
|
|
70909
71494
|
}
|
|
70910
71495
|
if (typeof request.limit !== "number" || !Number.isSafeInteger(request.limit) || request.limit < 1 || request.limit > ADDRESS_HISTORY_MAX_LIMIT) {
|
|
70911
71496
|
throw new Error("The address history limit is invalid.");
|
|
70912
71497
|
}
|
|
70913
|
-
return { requestId: requestId2, expectedTabId, query, limit: request.limit };
|
|
71498
|
+
return { requestId: requestId2, expectedTabId, query: query2, limit: request.limit };
|
|
70914
71499
|
}
|
|
70915
71500
|
function closeTabsIntentOrThrow(value) {
|
|
70916
71501
|
if (!value || typeof value !== "object") {
|
|
@@ -74744,6 +75329,41 @@ class DesktopNotifier {
|
|
|
74744
75329
|
notification.show();
|
|
74745
75330
|
}
|
|
74746
75331
|
}
|
|
75332
|
+
const ATTACH_FLAG = "--attach";
|
|
75333
|
+
function readAttachArguments(argv) {
|
|
75334
|
+
const paths = [];
|
|
75335
|
+
const problems = [];
|
|
75336
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
75337
|
+
const argument = argv[index];
|
|
75338
|
+
if (argument === ATTACH_FLAG) {
|
|
75339
|
+
const value = argv[index + 1];
|
|
75340
|
+
if (!value || value.startsWith("--")) {
|
|
75341
|
+
problems.push(`${ATTACH_FLAG} needs an absolute path`);
|
|
75342
|
+
continue;
|
|
75343
|
+
}
|
|
75344
|
+
index += 1;
|
|
75345
|
+
accept(value, paths, problems);
|
|
75346
|
+
continue;
|
|
75347
|
+
}
|
|
75348
|
+
if (argument.startsWith(`${ATTACH_FLAG}=`)) {
|
|
75349
|
+
accept(argument.slice(ATTACH_FLAG.length + 1), paths, problems);
|
|
75350
|
+
}
|
|
75351
|
+
}
|
|
75352
|
+
return { paths, problems };
|
|
75353
|
+
}
|
|
75354
|
+
function accept(value, paths, problems) {
|
|
75355
|
+
if (!value.trim()) {
|
|
75356
|
+
problems.push(`${ATTACH_FLAG} needs an absolute path`);
|
|
75357
|
+
return;
|
|
75358
|
+
}
|
|
75359
|
+
if (!path$1.isAbsolute(value)) {
|
|
75360
|
+
problems.push(
|
|
75361
|
+
`${ATTACH_FLAG} takes an absolute path (got ${JSON.stringify(value)})`
|
|
75362
|
+
);
|
|
75363
|
+
return;
|
|
75364
|
+
}
|
|
75365
|
+
paths.push(value);
|
|
75366
|
+
}
|
|
74747
75367
|
const FRAME_LABEL = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
74748
75368
|
function registerDevDriverIPC(options) {
|
|
74749
75369
|
const { window, expectedUrl, outDir, identity: identity2 } = options;
|
|
@@ -84260,18 +84880,18 @@ function frameNavigationVerdict(input, trustedRendererUrls) {
|
|
|
84260
84880
|
return ALLOW;
|
|
84261
84881
|
return deny(`a child frame may not navigate to ${url.protocol}`);
|
|
84262
84882
|
}
|
|
84263
|
-
function permissionVerdict(
|
|
84264
|
-
if (!
|
|
84883
|
+
function permissionVerdict(query2, trustedRendererUrls) {
|
|
84884
|
+
if (!query2.isMainFrame) return false;
|
|
84265
84885
|
if (!trustedRendererUrls.some(
|
|
84266
|
-
(trusted) => trustedDesktopFrame(
|
|
84886
|
+
(trusted) => trustedDesktopFrame(query2.requestingUrl, trusted)
|
|
84267
84887
|
))
|
|
84268
84888
|
return false;
|
|
84269
|
-
if (
|
|
84889
|
+
if (query2.permission === "clipboard-sanitized-write" || query2.permission === "fullscreen")
|
|
84270
84890
|
return true;
|
|
84271
|
-
if (
|
|
84272
|
-
if (
|
|
84273
|
-
return
|
|
84274
|
-
return
|
|
84891
|
+
if (query2.permission !== "media") return false;
|
|
84892
|
+
if (query2.mediaTypes)
|
|
84893
|
+
return query2.mediaTypes.length > 0 && query2.mediaTypes.every((type2) => type2 === "audio");
|
|
84894
|
+
return query2.mediaType === "audio";
|
|
84275
84895
|
}
|
|
84276
84896
|
function decodedPathname(pathname) {
|
|
84277
84897
|
let current = pathname;
|
|
@@ -85089,6 +85709,13 @@ const devDriverArming = resolveDevDriverArming({
|
|
|
85089
85709
|
});
|
|
85090
85710
|
const devDriverLine = describeDevDriverArming(devDriverArming);
|
|
85091
85711
|
if (devDriverLine) console.log(devDriverLine);
|
|
85712
|
+
const attachQueue = devDriverArming.armed ? readAttachArguments(process.argv) : { paths: [], problems: [] };
|
|
85713
|
+
for (const problem of attachQueue.problems)
|
|
85714
|
+
console.error(`[dev-driver] ${problem}`);
|
|
85715
|
+
if (devDriverArming.armed && attachQueue.paths.length > 0)
|
|
85716
|
+
console.log(
|
|
85717
|
+
`[dev-driver] attach queue: ${attachQueue.paths.length} path(s) will answer the next file dialog`
|
|
85718
|
+
);
|
|
85092
85719
|
const addressOverlayGate = resolveAddressOverlayGate({
|
|
85093
85720
|
env: launchEnv,
|
|
85094
85721
|
devDriverArmed: devDriverArming.armed,
|
|
@@ -85914,6 +86541,24 @@ electron.app.whenReady().then(async () => {
|
|
|
85914
86541
|
}
|
|
85915
86542
|
}
|
|
85916
86543
|
);
|
|
86544
|
+
electron.ipcMain.handle(
|
|
86545
|
+
"upload-attachment",
|
|
86546
|
+
async (event, source) => {
|
|
86547
|
+
if (!isAdmittedSender(event, trustedLocalFileSenders())) {
|
|
86548
|
+
return {
|
|
86549
|
+
success: false,
|
|
86550
|
+
code: "unreadable",
|
|
86551
|
+
error: "This window cannot read local files."
|
|
86552
|
+
};
|
|
86553
|
+
}
|
|
86554
|
+
const resolved = source.kind === "path" ? { ...source, path: resolveUserPath(source.path) } : source;
|
|
86555
|
+
return uploadAttachment({
|
|
86556
|
+
source: resolved,
|
|
86557
|
+
backendUrl: backendService.getBackendUrl(),
|
|
86558
|
+
token: backendService.getDesktopToken()
|
|
86559
|
+
});
|
|
86560
|
+
}
|
|
86561
|
+
);
|
|
85917
86562
|
electron.ipcMain.handle("open-external", async (_, url) => openExternalVetted(url));
|
|
85918
86563
|
electron.ipcMain.handle(
|
|
85919
86564
|
"show-item-in-folder",
|
|
@@ -85959,6 +86604,13 @@ electron.app.whenReady().then(async () => {
|
|
|
85959
86604
|
}
|
|
85960
86605
|
});
|
|
85961
86606
|
electron.ipcMain.handle("show-open-dialog", async (event, options) => {
|
|
86607
|
+
if (attachQueue.paths.length > 0) {
|
|
86608
|
+
const filePaths = attachQueue.paths.splice(0);
|
|
86609
|
+
console.log(
|
|
86610
|
+
`[dev-driver] answered the file dialog with ${filePaths.length} queued path(s)`
|
|
86611
|
+
);
|
|
86612
|
+
return { canceled: false, filePaths };
|
|
86613
|
+
}
|
|
85962
86614
|
const parent = electron.BrowserWindow.fromWebContents(event.sender) ?? mainWindow;
|
|
85963
86615
|
if (!parent) {
|
|
85964
86616
|
logger.error(
|