@dashup/connector 0.1.9 → 0.1.11
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 +277 -65
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -2728,11 +2728,16 @@ var PROTOCOL_VERSION = 1;
|
|
|
2728
2728
|
var MAX_ENVELOPE_BYTES = 8 * 1024 * 1024;
|
|
2729
2729
|
var HISTORY_PAGE_ITEMS = 30;
|
|
2730
2730
|
var HISTORY_TEXT_CHARS = 4e3;
|
|
2731
|
+
var HISTORY_TOOL_CHARS = 500;
|
|
2731
2732
|
var HISTORY_PAGE_BYTES = 256 * 1024;
|
|
2732
2733
|
var HISTORY_BATCH_ITEMS = 50;
|
|
2733
2734
|
var HISTORY_BATCH_BYTES = HISTORY_PAGE_BYTES;
|
|
2734
2735
|
var HISTORY_RECORD_BYTES = 32 * 1024;
|
|
2735
2736
|
var HISTORY_RECORD_CIPHERTEXT_BYTES = HISTORY_RECORD_BYTES + 16;
|
|
2737
|
+
var OUTPUT_PREVIEW = { lines: 12, chars: 2e3 };
|
|
2738
|
+
var HISTORY_ATTACHMENTS = 16;
|
|
2739
|
+
var MAX_ATTACHMENT_BYTES = 8 * 1024 * 1024;
|
|
2740
|
+
var ATTACHMENT_NAME_CHARS = 100;
|
|
2736
2741
|
var MESSAGE_ROLES = ["user", "assistant", "system", "tool"];
|
|
2737
2742
|
var HARNESSES = {
|
|
2738
2743
|
claude: "Claude Code",
|
|
@@ -2875,6 +2880,21 @@ function complexOverlapBytes(input, output) {
|
|
|
2875
2880
|
if (overlapBytes(input, output) && input.byteOffset < output.byteOffset)
|
|
2876
2881
|
throw new Error("complex overlap of input and output is not supported");
|
|
2877
2882
|
}
|
|
2883
|
+
function concatBytes(...arrays) {
|
|
2884
|
+
let sum = 0;
|
|
2885
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
2886
|
+
const a = arrays[i];
|
|
2887
|
+
abytes(a);
|
|
2888
|
+
sum += a.length;
|
|
2889
|
+
}
|
|
2890
|
+
const res = new Uint8Array(sum);
|
|
2891
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
2892
|
+
const a = arrays[i];
|
|
2893
|
+
res.set(a, pad);
|
|
2894
|
+
pad += a.length;
|
|
2895
|
+
}
|
|
2896
|
+
return res;
|
|
2897
|
+
}
|
|
2878
2898
|
function checkOpts(defaults, opts) {
|
|
2879
2899
|
aobject(defaults, "defaults");
|
|
2880
2900
|
aobject(opts, "opts");
|
|
@@ -3589,6 +3609,12 @@ function decryptContent(key, associatedData, sealed) {
|
|
|
3589
3609
|
).decrypt(ciphertextBytes(sealed.ciphertext));
|
|
3590
3610
|
return JSON.parse(bytesToUtf8(cleartext));
|
|
3591
3611
|
}
|
|
3612
|
+
var attachmentData = (pairing, id) => utf8ToBytes(JSON.stringify([PROTOCOL_VERSION, "attachment", pairing, id]));
|
|
3613
|
+
function sealAttachment(key, pairing, id, bytes, random) {
|
|
3614
|
+
const nonce = random(NONCE_BYTES);
|
|
3615
|
+
const cipher = xchacha20poly1305(hexToBytes(key), nonce, attachmentData(pairing, id));
|
|
3616
|
+
return concatBytes(nonce, cipher.encrypt(bytes));
|
|
3617
|
+
}
|
|
3592
3618
|
var PAIRING_CODE = new RegExp(
|
|
3593
3619
|
`^DASHUP:${PROTOCOL_VERSION}:([0-9A-F]{64}):([0-9A-F]{16}):([0-9A-F]{64}):(.+)$`
|
|
3594
3620
|
);
|
|
@@ -3641,10 +3667,14 @@ function saveConfig(config2) {
|
|
|
3641
3667
|
}
|
|
3642
3668
|
}
|
|
3643
3669
|
async function api(config2, path, body2, method = body2 ? "POST" : "GET") {
|
|
3670
|
+
const bytes = body2 instanceof Uint8Array;
|
|
3644
3671
|
const response = await fetch(`${config2.api}/v1${path}`, {
|
|
3645
3672
|
method,
|
|
3646
|
-
headers: {
|
|
3647
|
-
|
|
3673
|
+
headers: {
|
|
3674
|
+
"Content-Type": bytes ? "application/octet-stream" : "application/json",
|
|
3675
|
+
Authorization: `Bearer ${config2.secret}`
|
|
3676
|
+
},
|
|
3677
|
+
body: bytes ? new Uint8Array(body2) : body2 ? JSON.stringify(body2) : void 0
|
|
3648
3678
|
});
|
|
3649
3679
|
const value2 = await response.json();
|
|
3650
3680
|
if (!response.ok || !value2.success)
|
|
@@ -4016,7 +4046,7 @@ import * as ui from "@clack/prompts";
|
|
|
4016
4046
|
import { z } from "zod";
|
|
4017
4047
|
|
|
4018
4048
|
// package.json
|
|
4019
|
-
var version = "0.1.
|
|
4049
|
+
var version = "0.1.11";
|
|
4020
4050
|
|
|
4021
4051
|
// src/pair.ts
|
|
4022
4052
|
var Invitation = z.object({
|
|
@@ -4173,6 +4203,13 @@ function agentHarness(name) {
|
|
|
4173
4203
|
if (/opencode/i.test(name)) return "opencode";
|
|
4174
4204
|
return void 0;
|
|
4175
4205
|
}
|
|
4206
|
+
var attached = (id, mime, data, name) => ({
|
|
4207
|
+
id,
|
|
4208
|
+
mime,
|
|
4209
|
+
bytes: Buffer.byteLength(data, "base64"),
|
|
4210
|
+
...name ? { name: name.slice(-ATTACHMENT_NAME_CHARS) } : {},
|
|
4211
|
+
read: () => Buffer.from(data, "base64")
|
|
4212
|
+
});
|
|
4176
4213
|
var MAX_PREVIEW = 64 * 1024;
|
|
4177
4214
|
var NO_PREVIEW = "Review the full request on your computer before approving.";
|
|
4178
4215
|
|
|
@@ -4332,15 +4369,28 @@ function text(value2) {
|
|
|
4332
4369
|
const part = object(value2);
|
|
4333
4370
|
return part ? typeof part.text === "string" ? part.text : text(part.content) : "";
|
|
4334
4371
|
}
|
|
4372
|
+
var DATA_URL = /^data:([^;,]+);base64,/;
|
|
4373
|
+
function attachments(id, content) {
|
|
4374
|
+
return list(content).flatMap((part, index) => {
|
|
4375
|
+
const key = `${id}:${index}`;
|
|
4376
|
+
const name = [part?.title, part?.filename].find((value2) => typeof value2 === "string");
|
|
4377
|
+
const source = object(part?.source);
|
|
4378
|
+
if (source?.type === "base64" && typeof source.data === "string")
|
|
4379
|
+
return [attached(key, String(source.media_type), source.data, name)];
|
|
4380
|
+
const url2 = String(part?.image_url ?? part?.url ?? "");
|
|
4381
|
+
const data = DATA_URL.exec(url2);
|
|
4382
|
+
return data ? [attached(key, data[1], url2.slice(data[0].length), name)] : [];
|
|
4383
|
+
});
|
|
4384
|
+
}
|
|
4335
4385
|
function prose(id, role, content) {
|
|
4336
4386
|
const value2 = text(
|
|
4337
4387
|
Array.isArray(content) ? content.filter(
|
|
4338
4388
|
(part) => typeof part === "string" || ["text", "input_text", "output_text"].includes(part?.type)
|
|
4339
4389
|
) : content
|
|
4340
4390
|
);
|
|
4341
|
-
|
|
4391
|
+
const files2 = attachments(id, content);
|
|
4392
|
+
return value2 || files2.length ? [{ id, role, text: value2, ...files2.length ? { attachments: files2 } : {} }] : [];
|
|
4342
4393
|
}
|
|
4343
|
-
var SUMMARY_LIMIT = 200;
|
|
4344
4394
|
var SUMMARY_FIELDS = [
|
|
4345
4395
|
"command",
|
|
4346
4396
|
"cmd",
|
|
@@ -4357,13 +4407,17 @@ 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
|
-
|
|
4366
|
-
|
|
4415
|
+
return (paths || value2.trim()).slice(0, HISTORY_TOOL_CHARS) || void 0;
|
|
4416
|
+
}
|
|
4417
|
+
function said(input, summary) {
|
|
4418
|
+
const value2 = object(input)?.description;
|
|
4419
|
+
const line = typeof value2 === "string" ? value2.trim().split("\n")[0] : "";
|
|
4420
|
+
return line && line !== summary ? line.slice(0, HISTORY_TOOL_CHARS) : void 0;
|
|
4367
4421
|
}
|
|
4368
4422
|
function elapsed(start, end) {
|
|
4369
4423
|
const ms = instant(end) - instant(start);
|
|
@@ -4378,20 +4432,26 @@ function added(path, content) {
|
|
|
4378
4432
|
...lines.map((line) => `+${line}`)
|
|
4379
4433
|
].join("\n");
|
|
4380
4434
|
}
|
|
4381
|
-
|
|
4435
|
+
var binary = (diff) => diff.slice(0, 8e3).includes("\0");
|
|
4436
|
+
function step(id, name, input, result, started) {
|
|
4382
4437
|
const summary = describe(input);
|
|
4383
|
-
const
|
|
4438
|
+
const label = said(input, summary);
|
|
4439
|
+
const at = instant(started);
|
|
4440
|
+
const diff = result?.status === "ok" && result.diff && !binary(result.diff) ? result.diff : void 0;
|
|
4384
4441
|
return {
|
|
4385
4442
|
id,
|
|
4386
4443
|
role: "tool",
|
|
4387
4444
|
text: diff || result?.text || "",
|
|
4388
4445
|
tool: {
|
|
4389
|
-
name: typeof name === "string" && name ? name.slice(0,
|
|
4446
|
+
name: typeof name === "string" && name ? name.slice(0, HISTORY_TOOL_CHARS) : "Tool",
|
|
4447
|
+
...label ? { label } : {},
|
|
4390
4448
|
...summary ? { summary } : {},
|
|
4391
4449
|
...result?.status ? { status: result.status } : {},
|
|
4392
4450
|
...result?.status && result.ms !== void 0 ? { ms: result.ms } : {},
|
|
4451
|
+
...!result?.status && Number.isFinite(at) ? { at: new Date(at).toISOString() } : {},
|
|
4393
4452
|
...diff ? { diff: true } : {}
|
|
4394
|
-
}
|
|
4453
|
+
},
|
|
4454
|
+
...result?.attachments?.length ? { attachments: result.attachments } : {}
|
|
4395
4455
|
};
|
|
4396
4456
|
}
|
|
4397
4457
|
var claudeHome = () => process.env.CLAUDE_CONFIG_DIR ?? join2(homedir2(), ".claude");
|
|
@@ -4447,17 +4507,20 @@ function claudeConversation(conversation, rows) {
|
|
|
4447
4507
|
...list(content).flatMap((part, position) => {
|
|
4448
4508
|
if (part?.type !== "tool_use") return [];
|
|
4449
4509
|
const result = results.get(part.id);
|
|
4510
|
+
const call = String(part.id ?? `${id}:${position}`);
|
|
4450
4511
|
return [
|
|
4451
4512
|
step(
|
|
4452
|
-
|
|
4513
|
+
call,
|
|
4453
4514
|
part.name,
|
|
4454
4515
|
part.input,
|
|
4455
4516
|
result && {
|
|
4456
4517
|
text: text(result.part.content),
|
|
4457
4518
|
status: result.part.is_error ? "error" : "ok",
|
|
4458
4519
|
ms: elapsed(row.timestamp, result.row.timestamp),
|
|
4459
|
-
diff: claudeChange(object(result.row.toolUseResult))
|
|
4460
|
-
|
|
4520
|
+
diff: claudeChange(object(result.row.toolUseResult)),
|
|
4521
|
+
attachments: attachments(call, result.part.content)
|
|
4522
|
+
},
|
|
4523
|
+
row.timestamp
|
|
4461
4524
|
)
|
|
4462
4525
|
];
|
|
4463
4526
|
})
|
|
@@ -4471,7 +4534,7 @@ function claude(root, scan) {
|
|
|
4471
4534
|
const latest = [...rows].reverse();
|
|
4472
4535
|
const owner = rows.find((row) => typeof row.sessionId === "string" && canonical(row.cwd));
|
|
4473
4536
|
if (!owner) return void 0;
|
|
4474
|
-
const
|
|
4537
|
+
const named2 = latest.find((row) => row.type === "custom-title" || row.type === "ai-title");
|
|
4475
4538
|
const first = rows.find(
|
|
4476
4539
|
(row) => row.type === "user" && !row.isMeta && !row.isSidechain && !injected(row.message?.content)
|
|
4477
4540
|
);
|
|
@@ -4479,7 +4542,7 @@ function claude(root, scan) {
|
|
|
4479
4542
|
id: String(owner.sessionId),
|
|
4480
4543
|
cwd: canonical(owner.cwd),
|
|
4481
4544
|
title: title(
|
|
4482
|
-
|
|
4545
|
+
named2?.customTitle ?? named2?.aiTitle ?? text(first?.message?.content),
|
|
4483
4546
|
"Claude Code thread"
|
|
4484
4547
|
),
|
|
4485
4548
|
updatedAt: date(latest.find(claudeMessage)?.timestamp, stamp.mtimeMs)
|
|
@@ -4535,16 +4598,19 @@ function codexMessages(path) {
|
|
|
4535
4598
|
const input = item.type === "function_call" ? parse(String(item.arguments)) ?? item.arguments : item.input;
|
|
4536
4599
|
const output = outputs.get(item.call_id);
|
|
4537
4600
|
const patch = item.name === "apply_patch" && typeof input === "string" ? input : "";
|
|
4601
|
+
const call = String(item.call_id ?? id);
|
|
4538
4602
|
return [
|
|
4539
4603
|
step(
|
|
4540
|
-
|
|
4604
|
+
call,
|
|
4541
4605
|
item.name,
|
|
4542
4606
|
input,
|
|
4543
4607
|
output && {
|
|
4544
4608
|
...codexResult(text(output.payload.output)),
|
|
4545
4609
|
ms: elapsed(row.timestamp, output.timestamp),
|
|
4546
|
-
diff: patch && applyPatch(patch)
|
|
4547
|
-
|
|
4610
|
+
diff: patch && applyPatch(patch),
|
|
4611
|
+
attachments: attachments(call, output.payload.output)
|
|
4612
|
+
},
|
|
4613
|
+
row.timestamp
|
|
4548
4614
|
)
|
|
4549
4615
|
];
|
|
4550
4616
|
});
|
|
@@ -4625,6 +4691,10 @@ function openCodeParts(id, role, parts2) {
|
|
|
4625
4691
|
const key = String(part.id ?? `${id}:${index}`);
|
|
4626
4692
|
if (part.type === "text" && typeof part.text === "string")
|
|
4627
4693
|
return [{ id: key, role, text: part.text }];
|
|
4694
|
+
if (part.type === "file") {
|
|
4695
|
+
const files2 = attachments(key, [part]);
|
|
4696
|
+
return files2.length ? [{ id: key, role, text: "", attachments: files2 }] : [];
|
|
4697
|
+
}
|
|
4628
4698
|
if (part.type !== "tool") return [];
|
|
4629
4699
|
const state = object(part.state) ?? {};
|
|
4630
4700
|
const status2 = state.status === "completed" ? "ok" : state.status === "error" ? "error" : void 0;
|
|
@@ -4637,8 +4707,10 @@ function openCodeParts(id, role, parts2) {
|
|
|
4637
4707
|
text: text(state.output ?? state.error),
|
|
4638
4708
|
status: status2,
|
|
4639
4709
|
ms: elapsed(state.time?.start, state.time?.end),
|
|
4640
|
-
diff: openCodeChange(state)
|
|
4641
|
-
|
|
4710
|
+
diff: openCodeChange(state),
|
|
4711
|
+
attachments: attachments(key, state.attachments)
|
|
4712
|
+
},
|
|
4713
|
+
state.time?.start
|
|
4642
4714
|
)
|
|
4643
4715
|
];
|
|
4644
4716
|
});
|
|
@@ -4999,6 +5071,7 @@ var Discovery = class {
|
|
|
4999
5071
|
read: true,
|
|
5000
5072
|
send: Boolean(session.send),
|
|
5001
5073
|
stop: Boolean(session.stop),
|
|
5074
|
+
now: Boolean(session.now),
|
|
5002
5075
|
approve: Boolean(session.approve)
|
|
5003
5076
|
}
|
|
5004
5077
|
});
|
|
@@ -5148,12 +5221,12 @@ var Discovery = class {
|
|
|
5148
5221
|
}
|
|
5149
5222
|
}
|
|
5150
5223
|
}
|
|
5151
|
-
read(thread,
|
|
5224
|
+
read(thread, attached2) {
|
|
5152
5225
|
const location2 = this.locations.get(thread.id);
|
|
5153
5226
|
if (!location2) throw new Error("Thread is no longer available");
|
|
5154
5227
|
if (location2.history) return location2.history.read();
|
|
5155
5228
|
if (location2.live) return location2.live.messages;
|
|
5156
|
-
if (
|
|
5229
|
+
if (attached2) return attached2;
|
|
5157
5230
|
if (location2.editor === "vscode") {
|
|
5158
5231
|
const state = chatSession(location2.path);
|
|
5159
5232
|
return (state.requests ?? []).flatMap((request2, index) => [
|
|
@@ -16110,13 +16183,19 @@ import { createHmac as createHmac2, randomBytes as randomBytes3 } from "node:cry
|
|
|
16110
16183
|
var ID = /^[a-f0-9]{64}$/;
|
|
16111
16184
|
var ROLES = new Set(MESSAGE_ROLES);
|
|
16112
16185
|
var ROUTING_FIELDS = ["pairing", "sender", "recipient", "project", "thread"];
|
|
16113
|
-
var
|
|
16186
|
+
var MIME = /^[\w.+-]{1,64}\/[\w.+-]{1,64}$/;
|
|
16187
|
+
function validAttachment(value2) {
|
|
16188
|
+
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);
|
|
16189
|
+
}
|
|
16114
16190
|
function validTool(value2) {
|
|
16115
|
-
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2) && typeof value2.name === "string" && value2.name.length <=
|
|
16191
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2) && typeof value2.name === "string" && value2.name.length <= HISTORY_TOOL_CHARS && [value2.label, value2.summary].every(
|
|
16192
|
+
(text3) => text3 === void 0 || typeof text3 === "string" && text3.length <= HISTORY_TOOL_CHARS
|
|
16193
|
+
) && (value2.at === void 0 || typeof value2.at === "string" && !Number.isNaN(Date.parse(value2.at))) && (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
16194
|
}
|
|
16117
16195
|
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));
|
|
16196
|
+
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
16197
|
}
|
|
16198
|
+
var preview = (text3) => text3.split("\n", OUTPUT_PREVIEW.lines).join("\n").slice(0, OUTPUT_PREVIEW.chars);
|
|
16120
16199
|
function splitHistoryMessages(messages5, opaqueId2) {
|
|
16121
16200
|
return messages5.flatMap((message) => {
|
|
16122
16201
|
const text3 = [];
|
|
@@ -16135,7 +16214,9 @@ function splitHistoryMessages(messages5, opaqueId2) {
|
|
|
16135
16214
|
text: part,
|
|
16136
16215
|
part: index,
|
|
16137
16216
|
parts: text3.length,
|
|
16138
|
-
...index === 0 && message.tool ? { tool: message.tool } : {}
|
|
16217
|
+
...index === 0 && message.tool ? { tool: message.tool } : {},
|
|
16218
|
+
...index === 0 && message.full ? { full: message.full } : {},
|
|
16219
|
+
...index === 0 && message.attachments?.length ? { attachments: message.attachments } : {}
|
|
16139
16220
|
}));
|
|
16140
16221
|
});
|
|
16141
16222
|
}
|
|
@@ -16177,7 +16258,21 @@ function sealHistory(key, routing, message, random) {
|
|
|
16177
16258
|
var HISTORY_PATH = "/dashup/history";
|
|
16178
16259
|
var HISTORY_KEPT = 300;
|
|
16179
16260
|
var opaque = (key, value2) => createHmac2("sha256", Buffer.from(key, "hex")).update(JSON.stringify(value2)).digest("hex");
|
|
16180
|
-
|
|
16261
|
+
function historyMessages(key, project, thread, messages5) {
|
|
16262
|
+
const name = (attachment) => named(key, project, thread, attachment);
|
|
16263
|
+
return splitHistoryMessages(
|
|
16264
|
+
messages5.map((message) => {
|
|
16265
|
+
const { full, attachments: attachments2, ...rest } = kept(message);
|
|
16266
|
+
const files2 = attachments2?.map(name).filter(validAttachment).slice(0, HISTORY_ATTACHMENTS);
|
|
16267
|
+
return {
|
|
16268
|
+
...rest,
|
|
16269
|
+
...full ? { full: name(full) } : {},
|
|
16270
|
+
...files2?.length ? { attachments: files2 } : {}
|
|
16271
|
+
};
|
|
16272
|
+
}),
|
|
16273
|
+
(id) => opaque(key, ["history-message", project, thread, id])
|
|
16274
|
+
);
|
|
16275
|
+
}
|
|
16181
16276
|
var copy = (messages5) => new Map(
|
|
16182
16277
|
messages5.slice(-HISTORY_PAGE_ITEMS).map((message) => [message.id, JSON.stringify(message)])
|
|
16183
16278
|
);
|
|
@@ -16253,6 +16348,51 @@ async function publishHistory(config2, pair, project, thread, messages5) {
|
|
|
16253
16348
|
throw new Error("The encrypted history snapshot was not published");
|
|
16254
16349
|
return summary;
|
|
16255
16350
|
}
|
|
16351
|
+
var ATTACHMENTS_PATH = "/dashup/attachments";
|
|
16352
|
+
var PASTED = new RegExp(
|
|
16353
|
+
`data:([\\w.+-]+/[\\w.+-]+);base64,([A-Za-z0-9+/]{${OUTPUT_PREVIEW.chars},}={0,2})`,
|
|
16354
|
+
"g"
|
|
16355
|
+
);
|
|
16356
|
+
function kept(message) {
|
|
16357
|
+
const files2 = [...message.attachments ?? []];
|
|
16358
|
+
const text3 = message.role === "tool" ? message.text : message.text.replace(PASTED, (_, mime, data, at) => {
|
|
16359
|
+
files2.push(attached(`${message.id}@${at}`, mime, data));
|
|
16360
|
+
return "";
|
|
16361
|
+
});
|
|
16362
|
+
const start = message.role === "tool" && !message.tool?.diff ? preview(text3) : text3;
|
|
16363
|
+
const full = start.length < text3.length ? {
|
|
16364
|
+
id: `${message.id}:full`,
|
|
16365
|
+
mime: "text/plain",
|
|
16366
|
+
bytes: Buffer.byteLength(text3),
|
|
16367
|
+
read: () => Buffer.from(text3)
|
|
16368
|
+
} : void 0;
|
|
16369
|
+
return {
|
|
16370
|
+
...message,
|
|
16371
|
+
text: start,
|
|
16372
|
+
...full ? { full } : {},
|
|
16373
|
+
...files2.length ? { attachments: files2 } : {}
|
|
16374
|
+
};
|
|
16375
|
+
}
|
|
16376
|
+
var named = (key, project, thread, attachment) => ({
|
|
16377
|
+
id: opaque(key, ["history-attachment", project, thread, attachment.id, attachment.bytes]),
|
|
16378
|
+
mime: attachment.mime,
|
|
16379
|
+
bytes: attachment.bytes,
|
|
16380
|
+
...attachment.name ? { name: attachment.name } : {}
|
|
16381
|
+
});
|
|
16382
|
+
var readable = (attachment) => "read" in attachment;
|
|
16383
|
+
async function shareAttachment(config2, pair, project, thread, messages5, id) {
|
|
16384
|
+
if (!activePair(config2, pair)) throw new Error("Pairing is no longer available");
|
|
16385
|
+
const key = config2.pairs[pair.id].key;
|
|
16386
|
+
const found = messages5.flatMap((message) => {
|
|
16387
|
+
const { full, attachments: attachments2 = [] } = kept(message);
|
|
16388
|
+
return full ? [full, ...attachments2] : attachments2;
|
|
16389
|
+
}).find((attachment) => named(key, project, thread, attachment).id === id);
|
|
16390
|
+
if (!found || !readable(found)) throw new Error("This attachment is no longer on your computer");
|
|
16391
|
+
if (found.bytes > MAX_ATTACHMENT_BYTES)
|
|
16392
|
+
throw new Error("This attachment is too large to open on your phone");
|
|
16393
|
+
const sealed = sealAttachment(key, pair.id, id, found.read(), randomBytes3);
|
|
16394
|
+
await api(config2, `${ATTACHMENTS_PATH}/${pair.id}/${id}`, sealed);
|
|
16395
|
+
}
|
|
16256
16396
|
|
|
16257
16397
|
// src/harness/live.ts
|
|
16258
16398
|
import { promisify as promisify5 } from "node:util";
|
|
@@ -16367,6 +16507,8 @@ var Client = class {
|
|
|
16367
16507
|
pending = /* @__PURE__ */ new Map();
|
|
16368
16508
|
approvals = /* @__PURE__ */ new Map();
|
|
16369
16509
|
requests = /* @__PURE__ */ new Map();
|
|
16510
|
+
// The reply each thread is writing, as far as it has streamed, and the item it belongs to.
|
|
16511
|
+
typing = /* @__PURE__ */ new Map();
|
|
16370
16512
|
async connect() {
|
|
16371
16513
|
if (this.socket?.readyState === WebSocket2.OPEN) return;
|
|
16372
16514
|
if (this.connecting) return this.connecting;
|
|
@@ -16401,13 +16543,20 @@ var Client = class {
|
|
|
16401
16543
|
return;
|
|
16402
16544
|
}
|
|
16403
16545
|
if (typeof message.method !== "string") return;
|
|
16546
|
+
const params = message.params;
|
|
16547
|
+
if (message.method === "item/agentMessage/delta" && typeof params?.threadId === "string" && typeof params.delta === "string") {
|
|
16548
|
+
const known = this.typing.get(params.threadId);
|
|
16549
|
+
this.typing.set(params.threadId, {
|
|
16550
|
+
item: params.itemId,
|
|
16551
|
+
text: (known && known.item === params.itemId ? known.text : "") + params.delta
|
|
16552
|
+
});
|
|
16553
|
+
}
|
|
16404
16554
|
if (message.method === "serverRequest/resolved") {
|
|
16405
16555
|
for (const [id, pending] of this.approvals)
|
|
16406
16556
|
if (pending.requestId === message.params?.requestId) this.approvals.delete(id);
|
|
16407
16557
|
}
|
|
16408
16558
|
if ((message.method === "item/commandExecution/requestApproval" || message.method === "item/fileChange/requestApproval") && (typeof message.id === "string" || typeof message.id === "number") && typeof message.params?.threadId === "string") {
|
|
16409
16559
|
const id = randomUUID2();
|
|
16410
|
-
const params = message.params;
|
|
16411
16560
|
this.approvals.set(id, {
|
|
16412
16561
|
requestId: message.id,
|
|
16413
16562
|
threadId: params.threadId,
|
|
@@ -16517,6 +16666,7 @@ var Client = class {
|
|
|
16517
16666
|
updatedAt: new Date(Number(thread.updatedAt ?? 0) * 1e3).toISOString(),
|
|
16518
16667
|
status: approvals.length ? "attention" : status(thread),
|
|
16519
16668
|
messages: messages2(thread),
|
|
16669
|
+
typing: this.typing.get(id)?.text,
|
|
16520
16670
|
approvals,
|
|
16521
16671
|
// An interrupt for a finished turn is never answered, so the active turn is read first.
|
|
16522
16672
|
stop: this.controls ? (requestId) => this.once(requestId, async () => {
|
|
@@ -16724,12 +16874,21 @@ var Session = class {
|
|
|
16724
16874
|
turn;
|
|
16725
16875
|
// Messages written to this turn's process that Claude Code has not finished answering.
|
|
16726
16876
|
open = 0;
|
|
16877
|
+
// The text Claude Code is writing, as far as it has streamed.
|
|
16878
|
+
typing = "";
|
|
16727
16879
|
approvals = /* @__PURE__ */ new Map();
|
|
16728
16880
|
requests = /* @__PURE__ */ new Map();
|
|
16729
16881
|
write(value2) {
|
|
16730
16882
|
this.turn?.stdin.write(`${JSON.stringify(value2)}
|
|
16731
16883
|
`);
|
|
16732
16884
|
}
|
|
16885
|
+
interrupt() {
|
|
16886
|
+
this.write({
|
|
16887
|
+
type: "control_request",
|
|
16888
|
+
request_id: randomUUID3(),
|
|
16889
|
+
request: { subtype: "interrupt" }
|
|
16890
|
+
});
|
|
16891
|
+
}
|
|
16733
16892
|
once(id, action) {
|
|
16734
16893
|
const known = this.requests.get(id);
|
|
16735
16894
|
if (known) return known;
|
|
@@ -16739,13 +16898,16 @@ var Session = class {
|
|
|
16739
16898
|
this.requests.set(id, result);
|
|
16740
16899
|
return result;
|
|
16741
16900
|
}
|
|
16742
|
-
// Resolves once Claude Code takes the message, or says why it could not start.
|
|
16743
|
-
|
|
16901
|
+
// Resolves once Claude Code takes the message, or says why it could not start. `now` stops the
|
|
16902
|
+
// turn under way, so Claude Code takes the message at once.
|
|
16903
|
+
say(text3, now = false) {
|
|
16744
16904
|
this.messages.push({ id: randomUUID3(), role: "user", text: text3 });
|
|
16905
|
+
this.typing = "";
|
|
16745
16906
|
this.status = "working";
|
|
16746
16907
|
this.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
16747
16908
|
const message = { type: "user", message: { role: "user", content: text3 } };
|
|
16748
16909
|
if (this.turn) {
|
|
16910
|
+
if (now) this.interrupt();
|
|
16749
16911
|
this.open++;
|
|
16750
16912
|
this.write(message);
|
|
16751
16913
|
this.changed();
|
|
@@ -16760,6 +16922,7 @@ var Session = class {
|
|
|
16760
16922
|
"--output-format",
|
|
16761
16923
|
"stream-json",
|
|
16762
16924
|
"--verbose",
|
|
16925
|
+
"--include-partial-messages",
|
|
16763
16926
|
"--permission-prompt-tool",
|
|
16764
16927
|
"stdio",
|
|
16765
16928
|
...this.saved ? ["--resume", this.id] : ["--session-id", this.id]
|
|
@@ -16817,6 +16980,14 @@ var Session = class {
|
|
|
16817
16980
|
this.status = "attention";
|
|
16818
16981
|
} else if (message.type === "result") {
|
|
16819
16982
|
if (--this.open <= 0) this.turn?.stdin.end();
|
|
16983
|
+
} else if (message.type === "stream_event" && !message.parent_tool_use_id) {
|
|
16984
|
+
const event = message.event;
|
|
16985
|
+
if (event?.type === "content_block_start") this.typing = "";
|
|
16986
|
+
else if (event?.type === "content_block_delta" && event.delta?.type === "text_delta")
|
|
16987
|
+
this.typing += String(event.delta.text ?? "");
|
|
16988
|
+
else return false;
|
|
16989
|
+
this.changed();
|
|
16990
|
+
return false;
|
|
16820
16991
|
} else return false;
|
|
16821
16992
|
this.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
16822
16993
|
this.changed();
|
|
@@ -16831,15 +17002,13 @@ var Session = class {
|
|
|
16831
17002
|
updatedAt: this.updatedAt,
|
|
16832
17003
|
status: this.status,
|
|
16833
17004
|
messages: [...this.messages],
|
|
17005
|
+
typing: this.typing,
|
|
16834
17006
|
approvals: [...this.approvals.values()].map((pending) => pending.approval),
|
|
16835
|
-
send: (requestId, text3) => this.once(requestId, () => this.say(text3)),
|
|
17007
|
+
send: (requestId, text3, now) => this.once(requestId, () => this.say(text3, now)),
|
|
17008
|
+
now: true,
|
|
16836
17009
|
stop: this.turn ? (requestId) => this.once(requestId, async () => {
|
|
16837
17010
|
if (!this.turn) throw new Error("Nothing is running in this Claude Code session");
|
|
16838
|
-
this.
|
|
16839
|
-
type: "control_request",
|
|
16840
|
-
request_id: randomUUID3(),
|
|
16841
|
-
request: { subtype: "interrupt" }
|
|
16842
|
-
});
|
|
17011
|
+
this.interrupt();
|
|
16843
17012
|
}) : void 0,
|
|
16844
17013
|
approve: this.approvals.size ? (requestId, approvalId, choice) => this.once(requestId, async () => {
|
|
16845
17014
|
const pending = this.approvals.get(approvalId);
|
|
@@ -16917,6 +17086,7 @@ import { join as join5 } from "node:path";
|
|
|
16917
17086
|
import { connect as connect2 } from "node:net";
|
|
16918
17087
|
import { watch as watch2 } from "node:fs";
|
|
16919
17088
|
import { lstat, readdir as readdir2, readFile as readFile2 } from "node:fs/promises";
|
|
17089
|
+
var STOP = "Stop here, and wait for my next message.";
|
|
16920
17090
|
var PEER_PROTOCOL = 1;
|
|
16921
17091
|
var MAX_SESSIONS2 = 100;
|
|
16922
17092
|
var REQUEST_MS2 = 4e3;
|
|
@@ -16946,7 +17116,7 @@ async function registrations() {
|
|
|
16946
17116
|
);
|
|
16947
17117
|
return found.flat();
|
|
16948
17118
|
}
|
|
16949
|
-
async function post(session, path, text3) {
|
|
17119
|
+
async function post(session, path, text3, priority) {
|
|
16950
17120
|
const file = await lstat(path);
|
|
16951
17121
|
if (!file.isSocket() || process.getuid && file.uid !== process.getuid())
|
|
16952
17122
|
throw new Error("Claude Code inbox is not owned by this user");
|
|
@@ -16954,7 +17124,7 @@ async function post(session, path, text3) {
|
|
|
16954
17124
|
const line = JSON.stringify({
|
|
16955
17125
|
type: "user",
|
|
16956
17126
|
session_id: session.sessionId,
|
|
16957
|
-
priority
|
|
17127
|
+
priority,
|
|
16958
17128
|
message: { role: "user", content: `<${ENVELOPE} from-name="Dashup">
|
|
16959
17129
|
${body2}
|
|
16960
17130
|
</${ENVELOPE}>` }
|
|
@@ -16987,7 +17157,9 @@ var Claude = class {
|
|
|
16987
17157
|
status: STATUS[session.status ?? ""] ?? "unknown",
|
|
16988
17158
|
messages: [],
|
|
16989
17159
|
approvals: [],
|
|
16990
|
-
send: path ? (requestId, text3) => this.once(requestId, () => post(session, path, text3)) : void 0
|
|
17160
|
+
send: path ? (requestId, text3, now) => this.once(requestId, () => post(session, path, text3, now ? "now" : "next")) : void 0,
|
|
17161
|
+
stop: path ? (requestId) => this.once(requestId, () => post(session, path, STOP, "now")) : void 0,
|
|
17162
|
+
now: Boolean(path)
|
|
16991
17163
|
};
|
|
16992
17164
|
});
|
|
16993
17165
|
}
|
|
@@ -17405,12 +17577,12 @@ var Host = class {
|
|
|
17405
17577
|
for (const pending of Array.isArray(session.inputNeeded) ? session.inputNeeded : []) {
|
|
17406
17578
|
if (pending.kind !== "toolConfirmation" || pending.chat !== item.resource || pending.toolCall?.status !== "pending-confirmation")
|
|
17407
17579
|
continue;
|
|
17408
|
-
const
|
|
17580
|
+
const preview2 = confirmation(pending.toolCall);
|
|
17409
17581
|
approvals.push({
|
|
17410
17582
|
id: pending.id,
|
|
17411
17583
|
title: text2(pending.toolCall.confirmationTitle) || pending.toolCall.displayName || "Native agent approval",
|
|
17412
|
-
detail:
|
|
17413
|
-
choices:
|
|
17584
|
+
detail: preview2.detail,
|
|
17585
|
+
choices: preview2.choices.map(({ id: id2, label }) => ({ id: id2, label }))
|
|
17414
17586
|
});
|
|
17415
17587
|
}
|
|
17416
17588
|
const id = `vscode-ahp:${createHash3("sha256").update(this.entry.root).digest("hex").slice(0, 16)}:${item.resource}`;
|
|
@@ -18528,7 +18700,7 @@ var NativeQueue = class {
|
|
|
18528
18700
|
// src/connector.ts
|
|
18529
18701
|
var EPHEMERAL_TTL_MS = 6e4;
|
|
18530
18702
|
var HOME_RECENT = 20;
|
|
18531
|
-
var FOLLOW_MS =
|
|
18703
|
+
var FOLLOW_MS = 2 * 6e4;
|
|
18532
18704
|
var RESCAN_MS = 1e3;
|
|
18533
18705
|
var Command = z2.object({
|
|
18534
18706
|
type: z2.literal("command"),
|
|
@@ -18538,10 +18710,16 @@ var Command = z2.object({
|
|
|
18538
18710
|
action: z2.discriminatedUnion("kind", [
|
|
18539
18711
|
z2.object({ kind: z2.literal("projects.refresh") }).strict(),
|
|
18540
18712
|
z2.object({ kind: z2.literal("thread.read") }).strict(),
|
|
18541
|
-
z2.object({ kind: z2.literal("thread.
|
|
18713
|
+
z2.object({ kind: z2.literal("thread.follow") }).strict(),
|
|
18714
|
+
z2.object({
|
|
18715
|
+
kind: z2.literal("thread.send"),
|
|
18716
|
+
text: z2.string().min(1).max(1e5),
|
|
18717
|
+
now: z2.boolean().optional()
|
|
18718
|
+
}).strict(),
|
|
18542
18719
|
z2.object({ kind: z2.literal("thread.queue"), text: z2.string().min(1).max(1e5) }).strict(),
|
|
18543
18720
|
z2.object({ kind: z2.literal("thread.stop") }).strict(),
|
|
18544
18721
|
z2.object({ kind: z2.literal("approval.respond"), approvalId: z2.string(), choice: z2.string() }).strict(),
|
|
18722
|
+
z2.object({ kind: z2.literal("attachment.read"), id: z2.string().regex(/^[a-f0-9]{64}$/) }).strict(),
|
|
18545
18723
|
z2.object({
|
|
18546
18724
|
kind: z2.literal("session.start"),
|
|
18547
18725
|
harness: z2.enum(["claude", "codex", "opencode"]),
|
|
@@ -18931,6 +19109,27 @@ var Connector = class {
|
|
|
18931
19109
|
for (const pair of this.activePairs()) await this.listProjects(pair);
|
|
18932
19110
|
await this.publishQueueReceipts();
|
|
18933
19111
|
}
|
|
19112
|
+
// Publishes a conversation for the phone, which then gets what changes in it.
|
|
19113
|
+
async read(pair, project, thread) {
|
|
19114
|
+
const messages5 = this.discovery.read(thread, this.attached(thread)?.messages);
|
|
19115
|
+
const history = await publishHistory(this.config, pair, project.id, thread, messages5);
|
|
19116
|
+
this.follows.set(`${pair.id}:${thread.id}`, {
|
|
19117
|
+
pair,
|
|
19118
|
+
project: project.id,
|
|
19119
|
+
thread: thread.id,
|
|
19120
|
+
until: Date.now() + FOLLOW_MS,
|
|
19121
|
+
copy: copy(messages5),
|
|
19122
|
+
updatedAt: thread.updatedAt,
|
|
19123
|
+
typing: ""
|
|
19124
|
+
});
|
|
19125
|
+
return this.thread(pair, project, thread, history);
|
|
19126
|
+
}
|
|
19127
|
+
// The reply an agent this computer runs is still writing, until the conversation holds it.
|
|
19128
|
+
typing(thread, messages5) {
|
|
19129
|
+
const typing = this.discovery.locations.get(thread.id)?.live?.typing ?? "";
|
|
19130
|
+
const last = messages5.filter((message) => message.role === "assistant").at(-1);
|
|
19131
|
+
return typing && !last?.text.startsWith(typing) ? typing : "";
|
|
19132
|
+
}
|
|
18934
19133
|
// A phone reading a conversation gets its messages as they change, before anything that says the
|
|
18935
19134
|
// conversation changed, so it never asks for a copy it already has.
|
|
18936
19135
|
async stream() {
|
|
@@ -18939,18 +19138,19 @@ var Connector = class {
|
|
|
18939
19138
|
let messages5;
|
|
18940
19139
|
try {
|
|
18941
19140
|
if (thread && follow.until > Date.now() && activePair(this.config, follow.pair))
|
|
18942
|
-
messages5 =
|
|
18943
|
-
follow.copy,
|
|
18944
|
-
this.discovery.read(thread, this.attached(thread)?.messages)
|
|
18945
|
-
);
|
|
19141
|
+
messages5 = this.discovery.read(thread, this.attached(thread)?.messages);
|
|
18946
19142
|
} catch {
|
|
18947
19143
|
}
|
|
18948
19144
|
if (!thread || !messages5) {
|
|
18949
19145
|
this.follows.delete(key);
|
|
18950
19146
|
continue;
|
|
18951
19147
|
}
|
|
18952
|
-
|
|
19148
|
+
const changed = changes(follow.copy, messages5);
|
|
19149
|
+
const typing = this.typing(thread, messages5);
|
|
19150
|
+
if (!changed.length && thread.updatedAt === follow.updatedAt && typing === follow.typing)
|
|
19151
|
+
continue;
|
|
18953
19152
|
follow.updatedAt = thread.updatedAt;
|
|
19153
|
+
follow.typing = typing;
|
|
18954
19154
|
await this.send(follow.pair, {
|
|
18955
19155
|
type: "thread-tail",
|
|
18956
19156
|
projectId: follow.project,
|
|
@@ -18960,8 +19160,9 @@ var Connector = class {
|
|
|
18960
19160
|
this.config.pairs[follow.pair.id].key,
|
|
18961
19161
|
follow.project,
|
|
18962
19162
|
follow.thread,
|
|
18963
|
-
|
|
18964
|
-
)
|
|
19163
|
+
changed
|
|
19164
|
+
),
|
|
19165
|
+
...typing ? { typing } : {}
|
|
18965
19166
|
});
|
|
18966
19167
|
}
|
|
18967
19168
|
}
|
|
@@ -19036,6 +19237,7 @@ var Connector = class {
|
|
|
19036
19237
|
throw new Error("Command expired. Try again while this computer is online.");
|
|
19037
19238
|
const outcome = await this.command(pair, content);
|
|
19038
19239
|
delete this.config.unconfirmed[content.requestId];
|
|
19240
|
+
if (content.action.kind === "thread.follow") return;
|
|
19039
19241
|
if (outcome && "state" in outcome) {
|
|
19040
19242
|
queue = outcome;
|
|
19041
19243
|
await this.queueResult(pair, content.requestId, content.projectId, queue);
|
|
@@ -19049,6 +19251,7 @@ var Connector = class {
|
|
|
19049
19251
|
);
|
|
19050
19252
|
} catch (error) {
|
|
19051
19253
|
delete this.config.unconfirmed[content.requestId];
|
|
19254
|
+
if (content.action.kind === "thread.follow") return;
|
|
19052
19255
|
if (queue) {
|
|
19053
19256
|
await this.queueResult(pair, content.requestId, content.projectId, queue);
|
|
19054
19257
|
return;
|
|
@@ -19181,19 +19384,27 @@ var Connector = class {
|
|
|
19181
19384
|
if (!project) throw new Error("Project is no longer open on this computer");
|
|
19182
19385
|
const thread = project.threads.find((item) => item.id === command2.threadId);
|
|
19183
19386
|
switch (command2.action.kind) {
|
|
19184
|
-
case "thread.read":
|
|
19387
|
+
case "thread.read":
|
|
19388
|
+
if (!thread) throw new Error("Thread not found");
|
|
19389
|
+
return this.read(pair, project, thread);
|
|
19390
|
+
case "thread.follow": {
|
|
19391
|
+
if (!thread) throw new Error("Thread not found");
|
|
19392
|
+
const follow = this.follows.get(`${pair.id}:${thread.id}`);
|
|
19393
|
+
if (!follow) return this.read(pair, project, thread);
|
|
19394
|
+
follow.until = Date.now() + FOLLOW_MS;
|
|
19395
|
+
return;
|
|
19396
|
+
}
|
|
19397
|
+
case "attachment.read": {
|
|
19185
19398
|
if (!thread) throw new Error("Thread not found");
|
|
19186
19399
|
const messages5 = this.discovery.read(thread, this.attached(thread)?.messages);
|
|
19187
|
-
|
|
19188
|
-
|
|
19400
|
+
return shareAttachment(
|
|
19401
|
+
this.config,
|
|
19189
19402
|
pair,
|
|
19190
|
-
project
|
|
19191
|
-
thread
|
|
19192
|
-
|
|
19193
|
-
|
|
19194
|
-
|
|
19195
|
-
});
|
|
19196
|
-
return this.thread(pair, project, thread, history);
|
|
19403
|
+
project.id,
|
|
19404
|
+
thread.id,
|
|
19405
|
+
messages5,
|
|
19406
|
+
command2.action.id
|
|
19407
|
+
);
|
|
19197
19408
|
}
|
|
19198
19409
|
case "thread.send": {
|
|
19199
19410
|
if (!thread || !thread.capabilities.send)
|
|
@@ -19201,7 +19412,8 @@ var Connector = class {
|
|
|
19201
19412
|
"This session has no live reply connection. Use the existing agent on your computer."
|
|
19202
19413
|
);
|
|
19203
19414
|
const location2 = this.discovery.locations.get(thread.id);
|
|
19204
|
-
if (location2?.live?.send)
|
|
19415
|
+
if (location2?.live?.send)
|
|
19416
|
+
return location2.live.send(command2.requestId, command2.action.text, command2.action.now);
|
|
19205
19417
|
const agent = this.attached(thread);
|
|
19206
19418
|
const saved = thread.agent;
|
|
19207
19419
|
if (!agent && location2?.history && saved && saved.harness !== "other") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dashup/connector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"dashup": "dist/index.js"
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"tsx": "^4.22.4",
|
|
31
31
|
"typescript": "^5.9.3",
|
|
32
32
|
"@dashup/models": "0.1.0",
|
|
33
|
-
"@dashup/protocol": "0.1.0",
|
|
34
33
|
"@dashup/typescript-config": "0.0.0",
|
|
34
|
+
"@parcae/lynx": "0.1.0",
|
|
35
35
|
"@parcae/sdk": "0.8.1",
|
|
36
|
-
"@
|
|
36
|
+
"@dashup/protocol": "0.1.0"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
39
|
"dashup": "tsx src/index.ts",
|