@dashup/connector 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +163 -23
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -2733,6 +2733,10 @@ var HISTORY_BATCH_ITEMS = 50;
|
|
|
2733
2733
|
var HISTORY_BATCH_BYTES = HISTORY_PAGE_BYTES;
|
|
2734
2734
|
var HISTORY_RECORD_BYTES = 32 * 1024;
|
|
2735
2735
|
var HISTORY_RECORD_CIPHERTEXT_BYTES = HISTORY_RECORD_BYTES + 16;
|
|
2736
|
+
var OUTPUT_PREVIEW = { lines: 12, chars: 2e3 };
|
|
2737
|
+
var HISTORY_ATTACHMENTS = 16;
|
|
2738
|
+
var MAX_ATTACHMENT_BYTES = 8 * 1024 * 1024;
|
|
2739
|
+
var ATTACHMENT_NAME_CHARS = 100;
|
|
2736
2740
|
var MESSAGE_ROLES = ["user", "assistant", "system", "tool"];
|
|
2737
2741
|
var HARNESSES = {
|
|
2738
2742
|
claude: "Claude Code",
|
|
@@ -2875,6 +2879,21 @@ function complexOverlapBytes(input, output) {
|
|
|
2875
2879
|
if (overlapBytes(input, output) && input.byteOffset < output.byteOffset)
|
|
2876
2880
|
throw new Error("complex overlap of input and output is not supported");
|
|
2877
2881
|
}
|
|
2882
|
+
function concatBytes(...arrays) {
|
|
2883
|
+
let sum = 0;
|
|
2884
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
2885
|
+
const a = arrays[i];
|
|
2886
|
+
abytes(a);
|
|
2887
|
+
sum += a.length;
|
|
2888
|
+
}
|
|
2889
|
+
const res = new Uint8Array(sum);
|
|
2890
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
2891
|
+
const a = arrays[i];
|
|
2892
|
+
res.set(a, pad);
|
|
2893
|
+
pad += a.length;
|
|
2894
|
+
}
|
|
2895
|
+
return res;
|
|
2896
|
+
}
|
|
2878
2897
|
function checkOpts(defaults, opts) {
|
|
2879
2898
|
aobject(defaults, "defaults");
|
|
2880
2899
|
aobject(opts, "opts");
|
|
@@ -3589,6 +3608,12 @@ function decryptContent(key, associatedData, sealed) {
|
|
|
3589
3608
|
).decrypt(ciphertextBytes(sealed.ciphertext));
|
|
3590
3609
|
return JSON.parse(bytesToUtf8(cleartext));
|
|
3591
3610
|
}
|
|
3611
|
+
var attachmentData = (pairing, id) => utf8ToBytes(JSON.stringify([PROTOCOL_VERSION, "attachment", pairing, id]));
|
|
3612
|
+
function sealAttachment(key, pairing, id, bytes, random) {
|
|
3613
|
+
const nonce = random(NONCE_BYTES);
|
|
3614
|
+
const cipher = xchacha20poly1305(hexToBytes(key), nonce, attachmentData(pairing, id));
|
|
3615
|
+
return concatBytes(nonce, cipher.encrypt(bytes));
|
|
3616
|
+
}
|
|
3592
3617
|
var PAIRING_CODE = new RegExp(
|
|
3593
3618
|
`^DASHUP:${PROTOCOL_VERSION}:([0-9A-F]{64}):([0-9A-F]{16}):([0-9A-F]{64}):(.+)$`
|
|
3594
3619
|
);
|
|
@@ -3641,10 +3666,14 @@ function saveConfig(config2) {
|
|
|
3641
3666
|
}
|
|
3642
3667
|
}
|
|
3643
3668
|
async function api(config2, path, body2, method = body2 ? "POST" : "GET") {
|
|
3669
|
+
const bytes = body2 instanceof Uint8Array;
|
|
3644
3670
|
const response = await fetch(`${config2.api}/v1${path}`, {
|
|
3645
3671
|
method,
|
|
3646
|
-
headers: {
|
|
3647
|
-
|
|
3672
|
+
headers: {
|
|
3673
|
+
"Content-Type": bytes ? "application/octet-stream" : "application/json",
|
|
3674
|
+
Authorization: `Bearer ${config2.secret}`
|
|
3675
|
+
},
|
|
3676
|
+
body: bytes ? new Uint8Array(body2) : body2 ? JSON.stringify(body2) : void 0
|
|
3648
3677
|
});
|
|
3649
3678
|
const value2 = await response.json();
|
|
3650
3679
|
if (!response.ok || !value2.success)
|
|
@@ -4016,7 +4045,7 @@ import * as ui from "@clack/prompts";
|
|
|
4016
4045
|
import { z } from "zod";
|
|
4017
4046
|
|
|
4018
4047
|
// package.json
|
|
4019
|
-
var version = "0.1.
|
|
4048
|
+
var version = "0.1.10";
|
|
4020
4049
|
|
|
4021
4050
|
// src/pair.ts
|
|
4022
4051
|
var Invitation = z.object({
|
|
@@ -4173,6 +4202,13 @@ function agentHarness(name) {
|
|
|
4173
4202
|
if (/opencode/i.test(name)) return "opencode";
|
|
4174
4203
|
return void 0;
|
|
4175
4204
|
}
|
|
4205
|
+
var attached = (id, mime, data, name) => ({
|
|
4206
|
+
id,
|
|
4207
|
+
mime,
|
|
4208
|
+
bytes: Buffer.byteLength(data, "base64"),
|
|
4209
|
+
...name ? { name: name.slice(-ATTACHMENT_NAME_CHARS) } : {},
|
|
4210
|
+
read: () => Buffer.from(data, "base64")
|
|
4211
|
+
});
|
|
4176
4212
|
var MAX_PREVIEW = 64 * 1024;
|
|
4177
4213
|
var NO_PREVIEW = "Review the full request on your computer before approving.";
|
|
4178
4214
|
|
|
@@ -4332,13 +4368,27 @@ function text(value2) {
|
|
|
4332
4368
|
const part = object(value2);
|
|
4333
4369
|
return part ? typeof part.text === "string" ? part.text : text(part.content) : "";
|
|
4334
4370
|
}
|
|
4371
|
+
var DATA_URL = /^data:([^;,]+);base64,/;
|
|
4372
|
+
function attachments(id, content) {
|
|
4373
|
+
return list(content).flatMap((part, index) => {
|
|
4374
|
+
const key = `${id}:${index}`;
|
|
4375
|
+
const name = [part?.title, part?.filename].find((value2) => typeof value2 === "string");
|
|
4376
|
+
const source = object(part?.source);
|
|
4377
|
+
if (source?.type === "base64" && typeof source.data === "string")
|
|
4378
|
+
return [attached(key, String(source.media_type), source.data, name)];
|
|
4379
|
+
const url2 = String(part?.image_url ?? part?.url ?? "");
|
|
4380
|
+
const data = DATA_URL.exec(url2);
|
|
4381
|
+
return data ? [attached(key, data[1], url2.slice(data[0].length), name)] : [];
|
|
4382
|
+
});
|
|
4383
|
+
}
|
|
4335
4384
|
function prose(id, role, content) {
|
|
4336
4385
|
const value2 = text(
|
|
4337
4386
|
Array.isArray(content) ? content.filter(
|
|
4338
4387
|
(part) => typeof part === "string" || ["text", "input_text", "output_text"].includes(part?.type)
|
|
4339
4388
|
) : content
|
|
4340
4389
|
);
|
|
4341
|
-
|
|
4390
|
+
const files2 = attachments(id, content);
|
|
4391
|
+
return value2 || files2.length ? [{ id, role, text: value2, ...files2.length ? { attachments: files2 } : {} }] : [];
|
|
4342
4392
|
}
|
|
4343
4393
|
var SUMMARY_LIMIT = 200;
|
|
4344
4394
|
var SUMMARY_FIELDS = [
|
|
@@ -4357,10 +4407,10 @@ var SUMMARY_FIELDS = [
|
|
|
4357
4407
|
var PATCH_FILE = /^\*\*\* (Add|Update|Delete) File: (.+)$/gm;
|
|
4358
4408
|
function describe(input) {
|
|
4359
4409
|
const fields = object(input);
|
|
4360
|
-
const
|
|
4410
|
+
const named2 = SUMMARY_FIELDS.map((key) => fields?.[key]).find(
|
|
4361
4411
|
(value3) => typeof value3 === "string" && value3.trim() !== ""
|
|
4362
4412
|
);
|
|
4363
|
-
const value2 = typeof input === "string" ? input :
|
|
4413
|
+
const value2 = typeof input === "string" ? input : named2 ?? (fields && Object.keys(fields).length ? JSON.stringify(fields) : "");
|
|
4364
4414
|
const paths = [...value2.matchAll(PATCH_FILE)].map((match) => match[2]).join(", ");
|
|
4365
4415
|
const first = value2.split("\n").find((line) => line.trim());
|
|
4366
4416
|
return (paths || first?.trim())?.slice(0, SUMMARY_LIMIT);
|
|
@@ -4378,9 +4428,10 @@ function added(path, content) {
|
|
|
4378
4428
|
...lines.map((line) => `+${line}`)
|
|
4379
4429
|
].join("\n");
|
|
4380
4430
|
}
|
|
4431
|
+
var binary = (diff) => diff.slice(0, 8e3).includes("\0");
|
|
4381
4432
|
function step(id, name, input, result) {
|
|
4382
4433
|
const summary = describe(input);
|
|
4383
|
-
const diff = result?.status === "ok" ? result.diff : void 0;
|
|
4434
|
+
const diff = result?.status === "ok" && result.diff && !binary(result.diff) ? result.diff : void 0;
|
|
4384
4435
|
return {
|
|
4385
4436
|
id,
|
|
4386
4437
|
role: "tool",
|
|
@@ -4391,7 +4442,8 @@ function step(id, name, input, result) {
|
|
|
4391
4442
|
...result?.status ? { status: result.status } : {},
|
|
4392
4443
|
...result?.status && result.ms !== void 0 ? { ms: result.ms } : {},
|
|
4393
4444
|
...diff ? { diff: true } : {}
|
|
4394
|
-
}
|
|
4445
|
+
},
|
|
4446
|
+
...result?.attachments?.length ? { attachments: result.attachments } : {}
|
|
4395
4447
|
};
|
|
4396
4448
|
}
|
|
4397
4449
|
var claudeHome = () => process.env.CLAUDE_CONFIG_DIR ?? join2(homedir2(), ".claude");
|
|
@@ -4447,16 +4499,18 @@ function claudeConversation(conversation, rows) {
|
|
|
4447
4499
|
...list(content).flatMap((part, position) => {
|
|
4448
4500
|
if (part?.type !== "tool_use") return [];
|
|
4449
4501
|
const result = results.get(part.id);
|
|
4502
|
+
const call = String(part.id ?? `${id}:${position}`);
|
|
4450
4503
|
return [
|
|
4451
4504
|
step(
|
|
4452
|
-
|
|
4505
|
+
call,
|
|
4453
4506
|
part.name,
|
|
4454
4507
|
part.input,
|
|
4455
4508
|
result && {
|
|
4456
4509
|
text: text(result.part.content),
|
|
4457
4510
|
status: result.part.is_error ? "error" : "ok",
|
|
4458
4511
|
ms: elapsed(row.timestamp, result.row.timestamp),
|
|
4459
|
-
diff: claudeChange(object(result.row.toolUseResult))
|
|
4512
|
+
diff: claudeChange(object(result.row.toolUseResult)),
|
|
4513
|
+
attachments: attachments(call, result.part.content)
|
|
4460
4514
|
}
|
|
4461
4515
|
)
|
|
4462
4516
|
];
|
|
@@ -4471,7 +4525,7 @@ function claude(root, scan) {
|
|
|
4471
4525
|
const latest = [...rows].reverse();
|
|
4472
4526
|
const owner = rows.find((row) => typeof row.sessionId === "string" && canonical(row.cwd));
|
|
4473
4527
|
if (!owner) return void 0;
|
|
4474
|
-
const
|
|
4528
|
+
const named2 = latest.find((row) => row.type === "custom-title" || row.type === "ai-title");
|
|
4475
4529
|
const first = rows.find(
|
|
4476
4530
|
(row) => row.type === "user" && !row.isMeta && !row.isSidechain && !injected(row.message?.content)
|
|
4477
4531
|
);
|
|
@@ -4479,7 +4533,7 @@ function claude(root, scan) {
|
|
|
4479
4533
|
id: String(owner.sessionId),
|
|
4480
4534
|
cwd: canonical(owner.cwd),
|
|
4481
4535
|
title: title(
|
|
4482
|
-
|
|
4536
|
+
named2?.customTitle ?? named2?.aiTitle ?? text(first?.message?.content),
|
|
4483
4537
|
"Claude Code thread"
|
|
4484
4538
|
),
|
|
4485
4539
|
updatedAt: date(latest.find(claudeMessage)?.timestamp, stamp.mtimeMs)
|
|
@@ -4535,15 +4589,17 @@ function codexMessages(path) {
|
|
|
4535
4589
|
const input = item.type === "function_call" ? parse(String(item.arguments)) ?? item.arguments : item.input;
|
|
4536
4590
|
const output = outputs.get(item.call_id);
|
|
4537
4591
|
const patch = item.name === "apply_patch" && typeof input === "string" ? input : "";
|
|
4592
|
+
const call = String(item.call_id ?? id);
|
|
4538
4593
|
return [
|
|
4539
4594
|
step(
|
|
4540
|
-
|
|
4595
|
+
call,
|
|
4541
4596
|
item.name,
|
|
4542
4597
|
input,
|
|
4543
4598
|
output && {
|
|
4544
4599
|
...codexResult(text(output.payload.output)),
|
|
4545
4600
|
ms: elapsed(row.timestamp, output.timestamp),
|
|
4546
|
-
diff: patch && applyPatch(patch)
|
|
4601
|
+
diff: patch && applyPatch(patch),
|
|
4602
|
+
attachments: attachments(call, output.payload.output)
|
|
4547
4603
|
}
|
|
4548
4604
|
)
|
|
4549
4605
|
];
|
|
@@ -4625,6 +4681,10 @@ function openCodeParts(id, role, parts2) {
|
|
|
4625
4681
|
const key = String(part.id ?? `${id}:${index}`);
|
|
4626
4682
|
if (part.type === "text" && typeof part.text === "string")
|
|
4627
4683
|
return [{ id: key, role, text: part.text }];
|
|
4684
|
+
if (part.type === "file") {
|
|
4685
|
+
const files2 = attachments(key, [part]);
|
|
4686
|
+
return files2.length ? [{ id: key, role, text: "", attachments: files2 }] : [];
|
|
4687
|
+
}
|
|
4628
4688
|
if (part.type !== "tool") return [];
|
|
4629
4689
|
const state = object(part.state) ?? {};
|
|
4630
4690
|
const status2 = state.status === "completed" ? "ok" : state.status === "error" ? "error" : void 0;
|
|
@@ -4637,7 +4697,8 @@ function openCodeParts(id, role, parts2) {
|
|
|
4637
4697
|
text: text(state.output ?? state.error),
|
|
4638
4698
|
status: status2,
|
|
4639
4699
|
ms: elapsed(state.time?.start, state.time?.end),
|
|
4640
|
-
diff: openCodeChange(state)
|
|
4700
|
+
diff: openCodeChange(state),
|
|
4701
|
+
attachments: attachments(key, state.attachments)
|
|
4641
4702
|
}
|
|
4642
4703
|
)
|
|
4643
4704
|
];
|
|
@@ -5148,12 +5209,12 @@ var Discovery = class {
|
|
|
5148
5209
|
}
|
|
5149
5210
|
}
|
|
5150
5211
|
}
|
|
5151
|
-
read(thread,
|
|
5212
|
+
read(thread, attached2) {
|
|
5152
5213
|
const location2 = this.locations.get(thread.id);
|
|
5153
5214
|
if (!location2) throw new Error("Thread is no longer available");
|
|
5154
5215
|
if (location2.history) return location2.history.read();
|
|
5155
5216
|
if (location2.live) return location2.live.messages;
|
|
5156
|
-
if (
|
|
5217
|
+
if (attached2) return attached2;
|
|
5157
5218
|
if (location2.editor === "vscode") {
|
|
5158
5219
|
const state = chatSession(location2.path);
|
|
5159
5220
|
return (state.requests ?? []).flatMap((request2, index) => [
|
|
@@ -16110,13 +16171,18 @@ import { createHmac as createHmac2, randomBytes as randomBytes3 } from "node:cry
|
|
|
16110
16171
|
var ID = /^[a-f0-9]{64}$/;
|
|
16111
16172
|
var ROLES = new Set(MESSAGE_ROLES);
|
|
16112
16173
|
var ROUTING_FIELDS = ["pairing", "sender", "recipient", "project", "thread"];
|
|
16174
|
+
var MIME = /^[\w.+-]{1,64}\/[\w.+-]{1,64}$/;
|
|
16113
16175
|
var TOOL_TEXT = 500;
|
|
16176
|
+
function validAttachment(value2) {
|
|
16177
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2) && typeof value2.id === "string" && ID.test(value2.id) && typeof value2.mime === "string" && MIME.test(value2.mime) && Number.isSafeInteger(value2.bytes) && value2.bytes >= 0 && (value2.name === void 0 || typeof value2.name === "string" && value2.name.length <= ATTACHMENT_NAME_CHARS);
|
|
16178
|
+
}
|
|
16114
16179
|
function validTool(value2) {
|
|
16115
16180
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2) && typeof value2.name === "string" && value2.name.length <= TOOL_TEXT && (value2.summary === void 0 || typeof value2.summary === "string" && value2.summary.length <= TOOL_TEXT) && (value2.status === void 0 || value2.status === "ok" || value2.status === "error") && (value2.ms === void 0 || Number.isSafeInteger(value2.ms) && value2.ms >= 0) && (value2.diff === void 0 || typeof value2.diff === "boolean");
|
|
16116
16181
|
}
|
|
16117
16182
|
function validMessage(value2) {
|
|
16118
|
-
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2) && typeof value2.id === "string" && ID.test(value2.id) && ROLES.has(value2.role) && typeof value2.text === "string" && value2.text.length <= HISTORY_TEXT_CHARS && Number.isSafeInteger(value2.part) && Number.isSafeInteger(value2.parts) && value2.part >= 0 && value2.parts > value2.part && (value2.tool === void 0 || value2.part === 0 && validTool(value2.tool));
|
|
16183
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2) && typeof value2.id === "string" && ID.test(value2.id) && ROLES.has(value2.role) && typeof value2.text === "string" && value2.text.length <= HISTORY_TEXT_CHARS && Number.isSafeInteger(value2.part) && Number.isSafeInteger(value2.parts) && value2.part >= 0 && value2.parts > value2.part && (value2.tool === void 0 || value2.part === 0 && validTool(value2.tool)) && (value2.full === void 0 || value2.part === 0 && validAttachment(value2.full)) && (value2.attachments === void 0 || value2.part === 0 && Array.isArray(value2.attachments) && value2.attachments.length <= HISTORY_ATTACHMENTS && value2.attachments.every(validAttachment));
|
|
16119
16184
|
}
|
|
16185
|
+
var preview = (text3) => text3.split("\n", OUTPUT_PREVIEW.lines).join("\n").slice(0, OUTPUT_PREVIEW.chars);
|
|
16120
16186
|
function splitHistoryMessages(messages5, opaqueId2) {
|
|
16121
16187
|
return messages5.flatMap((message) => {
|
|
16122
16188
|
const text3 = [];
|
|
@@ -16135,7 +16201,9 @@ function splitHistoryMessages(messages5, opaqueId2) {
|
|
|
16135
16201
|
text: part,
|
|
16136
16202
|
part: index,
|
|
16137
16203
|
parts: text3.length,
|
|
16138
|
-
...index === 0 && message.tool ? { tool: message.tool } : {}
|
|
16204
|
+
...index === 0 && message.tool ? { tool: message.tool } : {},
|
|
16205
|
+
...index === 0 && message.full ? { full: message.full } : {},
|
|
16206
|
+
...index === 0 && message.attachments?.length ? { attachments: message.attachments } : {}
|
|
16139
16207
|
}));
|
|
16140
16208
|
});
|
|
16141
16209
|
}
|
|
@@ -16177,7 +16245,21 @@ function sealHistory(key, routing, message, random) {
|
|
|
16177
16245
|
var HISTORY_PATH = "/dashup/history";
|
|
16178
16246
|
var HISTORY_KEPT = 300;
|
|
16179
16247
|
var opaque = (key, value2) => createHmac2("sha256", Buffer.from(key, "hex")).update(JSON.stringify(value2)).digest("hex");
|
|
16180
|
-
|
|
16248
|
+
function historyMessages(key, project, thread, messages5) {
|
|
16249
|
+
const name = (attachment) => named(key, project, thread, attachment);
|
|
16250
|
+
return splitHistoryMessages(
|
|
16251
|
+
messages5.map((message) => {
|
|
16252
|
+
const { full, attachments: attachments2, ...rest } = kept(message);
|
|
16253
|
+
const files2 = attachments2?.map(name).filter(validAttachment).slice(0, HISTORY_ATTACHMENTS);
|
|
16254
|
+
return {
|
|
16255
|
+
...rest,
|
|
16256
|
+
...full ? { full: name(full) } : {},
|
|
16257
|
+
...files2?.length ? { attachments: files2 } : {}
|
|
16258
|
+
};
|
|
16259
|
+
}),
|
|
16260
|
+
(id) => opaque(key, ["history-message", project, thread, id])
|
|
16261
|
+
);
|
|
16262
|
+
}
|
|
16181
16263
|
var copy = (messages5) => new Map(
|
|
16182
16264
|
messages5.slice(-HISTORY_PAGE_ITEMS).map((message) => [message.id, JSON.stringify(message)])
|
|
16183
16265
|
);
|
|
@@ -16253,6 +16335,51 @@ async function publishHistory(config2, pair, project, thread, messages5) {
|
|
|
16253
16335
|
throw new Error("The encrypted history snapshot was not published");
|
|
16254
16336
|
return summary;
|
|
16255
16337
|
}
|
|
16338
|
+
var ATTACHMENTS_PATH = "/dashup/attachments";
|
|
16339
|
+
var PASTED = new RegExp(
|
|
16340
|
+
`data:([\\w.+-]+/[\\w.+-]+);base64,([A-Za-z0-9+/]{${OUTPUT_PREVIEW.chars},}={0,2})`,
|
|
16341
|
+
"g"
|
|
16342
|
+
);
|
|
16343
|
+
function kept(message) {
|
|
16344
|
+
const files2 = [...message.attachments ?? []];
|
|
16345
|
+
const text3 = message.role === "tool" ? message.text : message.text.replace(PASTED, (_, mime, data, at) => {
|
|
16346
|
+
files2.push(attached(`${message.id}@${at}`, mime, data));
|
|
16347
|
+
return "";
|
|
16348
|
+
});
|
|
16349
|
+
const start = message.role === "tool" && !message.tool?.diff ? preview(text3) : text3;
|
|
16350
|
+
const full = start.length < text3.length ? {
|
|
16351
|
+
id: `${message.id}:full`,
|
|
16352
|
+
mime: "text/plain",
|
|
16353
|
+
bytes: Buffer.byteLength(text3),
|
|
16354
|
+
read: () => Buffer.from(text3)
|
|
16355
|
+
} : void 0;
|
|
16356
|
+
return {
|
|
16357
|
+
...message,
|
|
16358
|
+
text: start,
|
|
16359
|
+
...full ? { full } : {},
|
|
16360
|
+
...files2.length ? { attachments: files2 } : {}
|
|
16361
|
+
};
|
|
16362
|
+
}
|
|
16363
|
+
var named = (key, project, thread, attachment) => ({
|
|
16364
|
+
id: opaque(key, ["history-attachment", project, thread, attachment.id, attachment.bytes]),
|
|
16365
|
+
mime: attachment.mime,
|
|
16366
|
+
bytes: attachment.bytes,
|
|
16367
|
+
...attachment.name ? { name: attachment.name } : {}
|
|
16368
|
+
});
|
|
16369
|
+
var readable = (attachment) => "read" in attachment;
|
|
16370
|
+
async function shareAttachment(config2, pair, project, thread, messages5, id) {
|
|
16371
|
+
if (!activePair(config2, pair)) throw new Error("Pairing is no longer available");
|
|
16372
|
+
const key = config2.pairs[pair.id].key;
|
|
16373
|
+
const found = messages5.flatMap((message) => {
|
|
16374
|
+
const { full, attachments: attachments2 = [] } = kept(message);
|
|
16375
|
+
return full ? [full, ...attachments2] : attachments2;
|
|
16376
|
+
}).find((attachment) => named(key, project, thread, attachment).id === id);
|
|
16377
|
+
if (!found || !readable(found)) throw new Error("This attachment is no longer on your computer");
|
|
16378
|
+
if (found.bytes > MAX_ATTACHMENT_BYTES)
|
|
16379
|
+
throw new Error("This attachment is too large to open on your phone");
|
|
16380
|
+
const sealed = sealAttachment(key, pair.id, id, found.read(), randomBytes3);
|
|
16381
|
+
await api(config2, `${ATTACHMENTS_PATH}/${pair.id}/${id}`, sealed);
|
|
16382
|
+
}
|
|
16256
16383
|
|
|
16257
16384
|
// src/harness/live.ts
|
|
16258
16385
|
import { promisify as promisify5 } from "node:util";
|
|
@@ -17405,12 +17532,12 @@ var Host = class {
|
|
|
17405
17532
|
for (const pending of Array.isArray(session.inputNeeded) ? session.inputNeeded : []) {
|
|
17406
17533
|
if (pending.kind !== "toolConfirmation" || pending.chat !== item.resource || pending.toolCall?.status !== "pending-confirmation")
|
|
17407
17534
|
continue;
|
|
17408
|
-
const
|
|
17535
|
+
const preview2 = confirmation(pending.toolCall);
|
|
17409
17536
|
approvals.push({
|
|
17410
17537
|
id: pending.id,
|
|
17411
17538
|
title: text2(pending.toolCall.confirmationTitle) || pending.toolCall.displayName || "Native agent approval",
|
|
17412
|
-
detail:
|
|
17413
|
-
choices:
|
|
17539
|
+
detail: preview2.detail,
|
|
17540
|
+
choices: preview2.choices.map(({ id: id2, label }) => ({ id: id2, label }))
|
|
17414
17541
|
});
|
|
17415
17542
|
}
|
|
17416
17543
|
const id = `vscode-ahp:${createHash3("sha256").update(this.entry.root).digest("hex").slice(0, 16)}:${item.resource}`;
|
|
@@ -18542,6 +18669,7 @@ var Command = z2.object({
|
|
|
18542
18669
|
z2.object({ kind: z2.literal("thread.queue"), text: z2.string().min(1).max(1e5) }).strict(),
|
|
18543
18670
|
z2.object({ kind: z2.literal("thread.stop") }).strict(),
|
|
18544
18671
|
z2.object({ kind: z2.literal("approval.respond"), approvalId: z2.string(), choice: z2.string() }).strict(),
|
|
18672
|
+
z2.object({ kind: z2.literal("attachment.read"), id: z2.string().regex(/^[a-f0-9]{64}$/) }).strict(),
|
|
18545
18673
|
z2.object({
|
|
18546
18674
|
kind: z2.literal("session.start"),
|
|
18547
18675
|
harness: z2.enum(["claude", "codex", "opencode"]),
|
|
@@ -19195,6 +19323,18 @@ var Connector = class {
|
|
|
19195
19323
|
});
|
|
19196
19324
|
return this.thread(pair, project, thread, history);
|
|
19197
19325
|
}
|
|
19326
|
+
case "attachment.read": {
|
|
19327
|
+
if (!thread) throw new Error("Thread not found");
|
|
19328
|
+
const messages5 = this.discovery.read(thread, this.attached(thread)?.messages);
|
|
19329
|
+
return shareAttachment(
|
|
19330
|
+
this.config,
|
|
19331
|
+
pair,
|
|
19332
|
+
project.id,
|
|
19333
|
+
thread.id,
|
|
19334
|
+
messages5,
|
|
19335
|
+
command2.action.id
|
|
19336
|
+
);
|
|
19337
|
+
}
|
|
19198
19338
|
case "thread.send": {
|
|
19199
19339
|
if (!thread || !thread.capabilities.send)
|
|
19200
19340
|
throw new Error(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dashup/connector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"dashup": "dist/index.js"
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"tsup": "^8.5.1",
|
|
30
30
|
"tsx": "^4.22.4",
|
|
31
31
|
"typescript": "^5.9.3",
|
|
32
|
-
"@dashup/models": "0.1.0",
|
|
33
|
-
"@dashup/protocol": "0.1.0",
|
|
34
32
|
"@dashup/typescript-config": "0.0.0",
|
|
33
|
+
"@dashup/protocol": "0.1.0",
|
|
34
|
+
"@parcae/lynx": "0.1.0",
|
|
35
35
|
"@parcae/sdk": "0.8.1",
|
|
36
|
-
"@
|
|
36
|
+
"@dashup/models": "0.1.0"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
39
|
"dashup": "tsx src/index.ts",
|