@songsid/agend 2.1.8-beta.7 → 2.1.8-beta.8
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/cross-instance-envelope.d.ts +7 -0
- package/dist/cross-instance-envelope.js +19 -1
- package/dist/cross-instance-envelope.js.map +1 -1
- package/dist/fleet-manager.d.ts +8 -1
- package/dist/fleet-manager.js +37 -10
- package/dist/fleet-manager.js.map +1 -1
- package/dist/locale.js +2 -2
- package/dist/locale.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,5 +2,12 @@
|
|
|
2
2
|
export declare const MAX_ASSEMBLED_CROSS_INSTANCE_MESSAGE_BYTES = 16000;
|
|
3
3
|
/** Render metadata carried in a cross-instance handoff. */
|
|
4
4
|
export declare function renderCrossInstanceHandoffMetadata(meta: Record<string, string>): string;
|
|
5
|
+
/**
|
|
6
|
+
* A task_summary that merely echoes the body is noise in the injected block
|
|
7
|
+
* (#1037): senders auto-derive it from the first 200 chars when none is
|
|
8
|
+
* given. It is redundant iff the body already opens with it — an explicit
|
|
9
|
+
* summary carrying anything beyond the body is still shown.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isRedundantTaskSummary(content: string, taskSummary: string | undefined): boolean;
|
|
5
12
|
/** Exact cross-instance block pasted by the receiving daemon. */
|
|
6
13
|
export declare function formatCrossInstanceInboundMessage(content: string, meta: Record<string, string>): string;
|
|
@@ -16,12 +16,30 @@ export function renderCrossInstanceHandoffMetadata(meta) {
|
|
|
16
16
|
add("attachment_file_id", meta.attachment_file_id);
|
|
17
17
|
return rows.length ? `\n(${rows.join(" | ")})` : "";
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* A task_summary that merely echoes the body is noise in the injected block
|
|
21
|
+
* (#1037): senders auto-derive it from the first 200 chars when none is
|
|
22
|
+
* given. It is redundant iff the body already opens with it — an explicit
|
|
23
|
+
* summary carrying anything beyond the body is still shown.
|
|
24
|
+
*/
|
|
25
|
+
export function isRedundantTaskSummary(content, taskSummary) {
|
|
26
|
+
const summary = (taskSummary ?? "").trim();
|
|
27
|
+
if (!summary)
|
|
28
|
+
return false;
|
|
29
|
+
const body = (content ?? "").trim();
|
|
30
|
+
return body.length > 0 && body.startsWith(summary);
|
|
31
|
+
}
|
|
19
32
|
/** Exact cross-instance block pasted by the receiving daemon. */
|
|
20
33
|
export function formatCrossInstanceInboundMessage(content, meta) {
|
|
21
34
|
const fromInstance = meta.from_instance || "unknown";
|
|
22
35
|
const fromLabel = meta.from_display ? `${meta.from_display} (${fromInstance})` : fromInstance;
|
|
23
36
|
let formatted = `[from:${fromLabel}] ${content}`;
|
|
24
|
-
|
|
37
|
+
// Dedup only the injected block — logs and Telegram labels keep the raw
|
|
38
|
+
// task_summary exactly as the sender provided it.
|
|
39
|
+
const renderMeta = isRedundantTaskSummary(content, meta.task_summary)
|
|
40
|
+
? { ...meta, task_summary: "" }
|
|
41
|
+
: meta;
|
|
42
|
+
formatted += renderCrossInstanceHandoffMetadata(renderMeta);
|
|
25
43
|
formatted += meta.requires_reply === "true"
|
|
26
44
|
? "\n(A reply IS required: use report_result with the correlation_id above — or send_to_instance. Not direct text.)"
|
|
27
45
|
: "\n(If you need to reply, use send_to_instance tool, NOT direct text. If there is nothing to add, you may stay silent.)";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cross-instance-envelope.js","sourceRoot":"","sources":["../src/cross-instance-envelope.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,MAAM,CAAC,MAAM,0CAA0C,GAAG,MAAM,CAAC;AAEjE,2DAA2D;AAC3D,MAAM,UAAU,kCAAkC,CAAC,IAA4B;IAC7E,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,KAAyB,EAAE,EAAE;QACvD,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC,CAAC;IACF,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3C,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACvC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACvC,GAAG,CAAC,mBAAmB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjD,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,GAAG,CAAC,oBAAoB,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;AACtD,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,iCAAiC,CAAC,OAAe,EAAE,IAA4B;IAC7F,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,IAAI,SAAS,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC;IAC9F,IAAI,SAAS,GAAG,SAAS,SAAS,KAAK,OAAO,EAAE,CAAC;IACjD,SAAS,IAAI,kCAAkC,CAAC,
|
|
1
|
+
{"version":3,"file":"cross-instance-envelope.js","sourceRoot":"","sources":["../src/cross-instance-envelope.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,MAAM,CAAC,MAAM,0CAA0C,GAAG,MAAM,CAAC;AAEjE,2DAA2D;AAC3D,MAAM,UAAU,kCAAkC,CAAC,IAA4B;IAC7E,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,KAAyB,EAAE,EAAE;QACvD,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC,CAAC;IACF,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3C,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACvC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACvC,GAAG,CAAC,mBAAmB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjD,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,GAAG,CAAC,oBAAoB,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe,EAAE,WAA+B;IACrF,MAAM,OAAO,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AACrD,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,iCAAiC,CAAC,OAAe,EAAE,IAA4B;IAC7F,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,IAAI,SAAS,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC;IAC9F,IAAI,SAAS,GAAG,SAAS,SAAS,KAAK,OAAO,EAAE,CAAC;IACjD,wEAAwE;IACxE,kDAAkD;IAClD,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC;QACnE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE;QAC/B,CAAC,CAAC,IAAI,CAAC;IACT,SAAS,IAAI,kCAAkC,CAAC,UAAU,CAAC,CAAC;IAC5D,SAAS,IAAI,IAAI,CAAC,cAAc,KAAK,MAAM;QACzC,CAAC,CAAC,kHAAkH;QACpH,CAAC,CAAC,wHAAwH,CAAC;IAC7H,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/fleet-manager.d.ts
CHANGED
|
@@ -1674,7 +1674,14 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
|
|
|
1674
1674
|
/** `/install-cli cancel` — abort the active install and remove its window. */
|
|
1675
1675
|
cancelInstallSession(): Promise<string>;
|
|
1676
1676
|
/** `command -v` on a login shell, so PATH additions from rc files count. */
|
|
1677
|
-
|
|
1677
|
+
/**
|
|
1678
|
+
* The absolute path a fresh login shell resolves `binary` to, or null. Only
|
|
1679
|
+
* a real executable file counts: `command -v` also answers with an alias
|
|
1680
|
+
* definition or a function name, neither of which a spawn could run.
|
|
1681
|
+
*/
|
|
1682
|
+
private locateBinaryOnLoginShell;
|
|
1683
|
+
/** Put an installed binary's directory on the fleet's PATH (#1059), once. */
|
|
1684
|
+
private adoptBinaryDirectory;
|
|
1678
1685
|
/** "Sign in now?" button after a successful install. */
|
|
1679
1686
|
private handleInstallLoginConfirm;
|
|
1680
1687
|
/** Discord native `/login` slash — shared by every adapter dispatch block. */
|
package/dist/fleet-manager.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { existsSync, readFileSync, mkdirSync, writeFileSync, unlinkSync, rmSync, readdirSync, renameSync, copyFileSync, chmodSync, statSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync, unlinkSync, rmSync, readdirSync, renameSync, copyFileSync, chmodSync, statSync, accessSync, constants as fsConstants } from "node:fs";
|
|
2
2
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
4
|
import { freemem, totalmem, cpus } from "node:os";
|
|
5
5
|
import { createServer } from "node:http";
|
|
6
6
|
import { Worker } from "node:worker_threads";
|
|
7
|
-
import { join, dirname, basename } from "node:path";
|
|
7
|
+
import { join, dirname, basename, delimiter, isAbsolute } from "node:path";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import { getAgendHome, ensureWorkspaceGit } from "./paths.js";
|
|
10
10
|
import { beginFullRestartProgress as persistFullRestartProgress, beginUpdateProgress as persistUpdateProgress, clearUpdateMarker, isUpdateInProgress, readUpdateProgress, setUpdateProgressStage, updateProgressOperation, } from "./update-marker.js";
|
|
@@ -7115,7 +7115,7 @@ export class FleetManager {
|
|
|
7115
7115
|
* An empty emoji removes that status's override.
|
|
7116
7116
|
*/
|
|
7117
7117
|
async setPersonaEmoji(instanceName, args) {
|
|
7118
|
-
const self = this.
|
|
7118
|
+
const self = this.ownInstanceConfig(instanceName);
|
|
7119
7119
|
if (!self)
|
|
7120
7120
|
return { error: this.personaEmojiMissing(instanceName) };
|
|
7121
7121
|
const status = (args.status ?? "delivered");
|
|
@@ -7160,8 +7160,9 @@ export class FleetManager {
|
|
|
7160
7160
|
// Re-read after the validation above, which may have waited on Discord:
|
|
7161
7161
|
// another set_persona_emoji or a Settings save can have changed another
|
|
7162
7162
|
// status, or replaced this instance's config object, meanwhile. Change
|
|
7163
|
-
// only this one key on what is there now.
|
|
7164
|
-
|
|
7163
|
+
// only this one key on what is there now. Ownership must still hold:
|
|
7164
|
+
// removal during the await must not fall through to an inherited entry.
|
|
7165
|
+
const current = this.ownInstanceConfig(instanceName);
|
|
7165
7166
|
if (!current)
|
|
7166
7167
|
return { error: this.personaEmojiMissing(instanceName) };
|
|
7167
7168
|
const map = { ...(current.status_emojis ?? {}) };
|
|
@@ -9688,10 +9689,16 @@ export class FleetManager {
|
|
|
9688
9689
|
}
|
|
9689
9690
|
// The installer may only have added the binary to a profile PATH; a
|
|
9690
9691
|
// fresh login shell sees that, the fleet process's PATH may not.
|
|
9691
|
-
|
|
9692
|
+
const installedAt = this.locateBinaryOnLoginShell(info.binary);
|
|
9693
|
+
if (!installedAt) {
|
|
9692
9694
|
await chat.adapter.sendText(chat.chatId, t("install.verify_failed", backend, info.binary), { threadId: chat.threadId }).catch(() => { });
|
|
9693
9695
|
return;
|
|
9694
9696
|
}
|
|
9697
|
+
// #1059: make it reachable from this process too. `/login` lists what
|
|
9698
|
+
// `which` finds on the fleet's own PATH, and instances resolve their
|
|
9699
|
+
// binary the same way, so a binary only a login shell could see was
|
|
9700
|
+
// installed, reported as verified, and then offered nowhere.
|
|
9701
|
+
this.adoptBinaryDirectory(installedAt, backend);
|
|
9695
9702
|
if (!LOGIN_FLOWS[backend]) {
|
|
9696
9703
|
await chat.adapter.sendText(chat.chatId, t("install.success_no_login", backend), { threadId: chat.threadId }).catch(() => { });
|
|
9697
9704
|
return;
|
|
@@ -9751,15 +9758,35 @@ export class FleetManager {
|
|
|
9751
9758
|
return t("install.cancelled", backend);
|
|
9752
9759
|
}
|
|
9753
9760
|
/** `command -v` on a login shell, so PATH additions from rc files count. */
|
|
9754
|
-
|
|
9761
|
+
/**
|
|
9762
|
+
* The absolute path a fresh login shell resolves `binary` to, or null. Only
|
|
9763
|
+
* a real executable file counts: `command -v` also answers with an alias
|
|
9764
|
+
* definition or a function name, neither of which a spawn could run.
|
|
9765
|
+
*/
|
|
9766
|
+
locateBinaryOnLoginShell(binary) {
|
|
9755
9767
|
try {
|
|
9756
|
-
const result = spawnSync("bash", ["-lc", `command -v ${binary}`], { timeout: 10_000, stdio: "pipe" });
|
|
9757
|
-
|
|
9768
|
+
const result = spawnSync("bash", ["-lc", `command -v ${binary}`], { timeout: 10_000, stdio: "pipe", encoding: "utf8" });
|
|
9769
|
+
if (result.status !== 0)
|
|
9770
|
+
return null;
|
|
9771
|
+
const path = String(result.stdout ?? "").trim().split("\n").pop()?.trim() ?? "";
|
|
9772
|
+
if (!isAbsolute(path))
|
|
9773
|
+
return null;
|
|
9774
|
+
accessSync(path, fsConstants.X_OK);
|
|
9775
|
+
return statSync(path).isFile() ? path : null;
|
|
9758
9776
|
}
|
|
9759
9777
|
catch {
|
|
9760
|
-
return
|
|
9778
|
+
return null;
|
|
9761
9779
|
}
|
|
9762
9780
|
}
|
|
9781
|
+
/** Put an installed binary's directory on the fleet's PATH (#1059), once. */
|
|
9782
|
+
adoptBinaryDirectory(binaryPath, backend) {
|
|
9783
|
+
const dir = dirname(binaryPath);
|
|
9784
|
+
const entries = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
|
|
9785
|
+
if (entries.includes(dir))
|
|
9786
|
+
return;
|
|
9787
|
+
process.env.PATH = [dir, ...entries].join(delimiter);
|
|
9788
|
+
this.logger.info({ backend, dir }, "Added the installed CLI's directory to the fleet PATH");
|
|
9789
|
+
}
|
|
9763
9790
|
/** "Sign in now?" button after a successful install. */
|
|
9764
9791
|
async handleInstallLoginConfirm(data, callbackAdapterId, receivingAdapter) {
|
|
9765
9792
|
const claimed = this.consumeNonceCallback(INSTALL_LOGIN_CALLBACK_PREFIX, /^install-login:([0-9a-f]+):(go|later)$/, data, callbackAdapterId, receivingAdapter);
|