@songsid/agend 2.2.0-beta.17 → 2.2.0-beta.19
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/README.md +18 -18
- package/README.zh-TW.md +18 -18
- package/dist/agent-whats-new.js +3 -1
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/backend/kiro.d.ts +2 -0
- package/dist/backend/kiro.js +4 -0
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +5 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/compact-watch.d.ts +9 -1
- package/dist/compact-watch.js +47 -6
- package/dist/compact-watch.js.map +1 -1
- package/dist/config-validator.js +26 -1
- package/dist/config-validator.js.map +1 -1
- package/dist/daemon.d.ts +8 -0
- package/dist/daemon.js +65 -5
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.js +49 -20
- package/dist/fleet-manager.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +4 -3
- package/dist/forged-envelope-scan.js +4 -3
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/install-lock.d.ts +18 -1
- package/dist/install-lock.js +30 -3
- package/dist/install-lock.js.map +1 -1
- package/dist/kiro-compact-pane.d.ts +38 -0
- package/dist/kiro-compact-pane.js +57 -0
- package/dist/kiro-compact-pane.js.map +1 -0
- package/dist/locale.js +4 -4
- package/dist/locale.js.map +1 -1
- package/dist/outbound-schemas.js +1 -1
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.d.ts +2 -0
- package/dist/public-web-gateway.js +6 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/ui/chat-render.js +31 -6
- package/dist/ui/chat-store.js +5 -5
- package/dist/ui/chat-strings.js +6 -2
- package/dist/ui/chat-thread.js +15 -2
- package/dist/ui/panel-chat.js +1 -1
- package/dist/ui/panel-settings.js +1 -1
- package/dist/ui/shared/app.css +7 -0
- package/dist/update-launch.d.ts +3 -1
- package/dist/update-launch.js +6 -1
- package/dist/update-launch.js.map +1 -1
- package/dist/web-api.d.ts +4 -0
- package/dist/web-api.js +135 -43
- package/dist/web-api.js.map +1 -1
- package/dist/web-chat-history.d.ts +14 -0
- package/dist/web-chat-history.js +18 -1
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-upload.d.ts +112 -1
- package/dist/web-upload.js +237 -36
- package/dist/web-upload.js.map +1 -1
- package/launcher/install-admission.cjs +61 -6
- package/package.json +3 -3
package/dist/fleet-manager.js
CHANGED
|
@@ -7,7 +7,7 @@ import { SettingsExecution, settingsRevision, noteSettingsWrite, settingsFileRes
|
|
|
7
7
|
import { performance } from "node:perf_hooks";
|
|
8
8
|
import { withSpawnHoldReply } from "./spawn-hold-reply.js";
|
|
9
9
|
import { gatewayRequestContext } from "./web-request-context.js";
|
|
10
|
-
import { createPublicWebGateway } from "./public-web-gateway.js";
|
|
10
|
+
import { createPublicWebGateway, PUBLIC_GATEWAY_RECEIVE_MS } from "./public-web-gateway.js";
|
|
11
11
|
import { handleWebIconRequest } from "./web-icons.js";
|
|
12
12
|
import { trackWebServer } from "./web-server-drain.js";
|
|
13
13
|
import { renderPublicLinkProgress, ThrottledMessageEditor } from "./public-link-progress.js";
|
|
@@ -144,7 +144,7 @@ import { WEB_NAME_FALLBACK, safeWebName, validateWebName, webNameInUse, webPerso
|
|
|
144
144
|
import { ReplyButtonStore, parseReplyButtons, replyButtonClickText, replyButtonsFallbackText, REPLY_BUTTON_PREFIX } from "./reply-buttons.js";
|
|
145
145
|
import { ReplyButtonsController } from "./reply-buttons-controller.js";
|
|
146
146
|
import { parsePoll } from "./reply-polls.js";
|
|
147
|
-
import { publicAttachment, sweepOrphanedUploads, WebFileLedger } from "./web-upload.js";
|
|
147
|
+
import { isUploadRequest, limitRequestReceive, publicAttachment, sweepOrphanedUploads, UPLOAD_REQUEST_TIMEOUT_MS, uploadLimits, WebFileLedger } from "./web-upload.js";
|
|
148
148
|
import { REPLY_FILES_MAX_BYTES, snapshotReplyFile, sweepReplySnapshots, webFilesDir } from "./web-reply-files.js";
|
|
149
149
|
import { handleViewRequest, isViewPath, profileIdentities, resolveInstanceIdentity } from "./view-api.js";
|
|
150
150
|
import { downloadStickerImage } from "./channel/sticker-download.js";
|
|
@@ -162,7 +162,7 @@ import { tightenInstanceDirs } from "./private-dir.js";
|
|
|
162
162
|
import { decideSlash } from "./slash-authz.js";
|
|
163
163
|
import { canonicalCommand, commandSpec, decideCommand, ruleFor } from "./command-table.js";
|
|
164
164
|
import { runVisibilityCommand } from "./cross-instance-notice.js";
|
|
165
|
-
import { installedChannel,
|
|
165
|
+
import { installedChannel, updateNoticeKey } from "./update-check.js";
|
|
166
166
|
import { resolveInstalledAgend } from "./update-dispatch.js";
|
|
167
167
|
import { resolveUpdateLaunch, openUpdateLog, updateLogPath, watchUpdateLaunch } from "./update-launch.js";
|
|
168
168
|
import { admitProfileLogin, LoginController, LOGIN_TOKEN_RESEND_PREFIX, POST_LOGIN_RECOVERY_DEADLINE_MS } from "./login-controller.js";
|
|
@@ -802,7 +802,8 @@ export class FleetManager {
|
|
|
802
802
|
/** #1565: the web chat history's files (set at fleet start, once the home and the instances are known). */
|
|
803
803
|
webChatStore = null;
|
|
804
804
|
/** Uploaded files and the files the dashboard may fetch back (uploads, reply attachments). */
|
|
805
|
-
|
|
805
|
+
// #1937: the upload limits are the config's, read on each use (agend reload applies a change to the next upload).
|
|
806
|
+
webFiles = new WebFileLedger({ limits: () => uploadLimits(this.fleetConfig?.web) });
|
|
806
807
|
/** #1770: per instance, its last web reply still copying its files — the next one is shown after it, in order. */
|
|
807
808
|
webReplyOrder = new Map();
|
|
808
809
|
/** #1770: an instance's web-files byte cap (a field, so a test can make it small). */
|
|
@@ -1319,8 +1320,10 @@ export class FleetManager {
|
|
|
1319
1320
|
return false;
|
|
1320
1321
|
reactions.consume();
|
|
1321
1322
|
this.afterUserInboundDelivered(set.instance, inbound, deliveryEpoch);
|
|
1323
|
+
// The web chat shows the click as its button's label (a chip); `text` stays what the agent was given.
|
|
1322
1324
|
this.emitSseEvent("message", {
|
|
1323
1325
|
instance: set.instance, sender: by.username, role: "user", text: content, ts, ...(web ? { messageId } : {}),
|
|
1326
|
+
click: { label: button.label, of: set.id },
|
|
1324
1327
|
});
|
|
1325
1328
|
return true;
|
|
1326
1329
|
}
|
|
@@ -2828,6 +2831,14 @@ export class FleetManager {
|
|
|
2828
2831
|
return null;
|
|
2829
2832
|
}
|
|
2830
2833
|
},
|
|
2834
|
+
paneFollow: (name) => {
|
|
2835
|
+
try {
|
|
2836
|
+
return this.lifecycle.daemons.get(name)?.compactPaneUi() != null;
|
|
2837
|
+
}
|
|
2838
|
+
catch {
|
|
2839
|
+
return false;
|
|
2840
|
+
}
|
|
2841
|
+
},
|
|
2831
2842
|
changed: () => this.emitSseEvent("status", this.getUiStatus()),
|
|
2832
2843
|
});
|
|
2833
2844
|
}
|
|
@@ -7280,7 +7291,12 @@ export class FleetManager {
|
|
|
7280
7291
|
else if (msg.type === "raw_paste_written") {
|
|
7281
7292
|
// Board 003648ac: a web /compact's paste reached the pane (or never will): its watch starts, or ends as lost.
|
|
7282
7293
|
if (typeof msg.id === "string")
|
|
7283
|
-
this.compactWatchService?.pasted(name, msg.id, msg.outcome === "written", { owner: msg.owner, checkpoint: msg.checkpoint });
|
|
7294
|
+
this.compactWatchService?.pasted(name, msg.id, msg.outcome === "written", { owner: msg.owner, checkpoint: msg.checkpoint, pane: msg.pane });
|
|
7295
|
+
}
|
|
7296
|
+
else if (msg.type === "compact_pane_result") {
|
|
7297
|
+
// Board 907c7899: kiro's pane said how that /compact ended.
|
|
7298
|
+
if (typeof msg.id === "string")
|
|
7299
|
+
this.compactWatchService?.paneResult(name, msg.id, msg.owner, msg.outcome);
|
|
7284
7300
|
}
|
|
7285
7301
|
else if (msg.type === "runtime_switch_result") {
|
|
7286
7302
|
// #1690: what our own runtime /model came to (the daemon answered claude's "Switch model?" or saw the result).
|
|
@@ -14609,6 +14625,7 @@ export class FleetManager {
|
|
|
14609
14625
|
messageId: typeof m.messageId === "string" ? m.messageId : undefined,
|
|
14610
14626
|
role: typeof m.role === "string" ? m.role : undefined,
|
|
14611
14627
|
buttons: m.buttons,
|
|
14628
|
+
click: m.click,
|
|
14612
14629
|
});
|
|
14613
14630
|
broadcastSseEvent(this.sseClients, event, recorded, onError, this.webChatHistory.cursorOf(recorded));
|
|
14614
14631
|
return;
|
|
@@ -19371,37 +19388,41 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
19371
19388
|
const currentVersion = JSON.parse(readFileSync(pkgPath, "utf-8")).version ?? "0.0.0";
|
|
19372
19389
|
const latest = await npmVersion("@songsid/agend");
|
|
19373
19390
|
let target = latest;
|
|
19391
|
+
let fromChannel = false;
|
|
19374
19392
|
// The same channel rule as `agend update` (#1259): an alpha follows @alpha, any other prerelease @beta.
|
|
19375
19393
|
const channel = installedChannel(currentVersion);
|
|
19376
19394
|
if (channel !== "latest") {
|
|
19377
|
-
// Prerelease users track their own channel (never fall back to @latest,
|
|
19378
|
-
// which is older, and an alpha is never offered @beta), but should also
|
|
19379
|
-
// hear when a newer STABLE ships — pick whichever is the newest.
|
|
19380
19395
|
let pre = "";
|
|
19381
19396
|
try {
|
|
19382
19397
|
pre = await npmVersion(`@songsid/agend@${channel}`);
|
|
19383
19398
|
}
|
|
19384
19399
|
catch { /* no such tag */ }
|
|
19385
|
-
|
|
19386
|
-
|
|
19400
|
+
// #1926: a beta install hears about @beta only: beta users stay on the beta line after a stable ships, so
|
|
19401
|
+
// @latest is not their target. Taking the higher of the two made a same-core stable (2.2.0 over beta.16) the
|
|
19402
|
+
// target, which the same-core guard then dropped, so the newer beta.17 was never announced.
|
|
19403
|
+
target = pre;
|
|
19404
|
+
fromChannel = true;
|
|
19405
|
+
// An alpha is still told about a stable that passed its own minor (with --stable, #1259): only a stable of
|
|
19406
|
+
// another core that is newer than its channel's release. A same-core @latest (2.2.0 for 2.2.0-alpha.3) is not
|
|
19407
|
+
// taken from @latest and no longer hides a newer alpha; once the release points @alpha at it, it comes from
|
|
19408
|
+
// @alpha like any channel release.
|
|
19409
|
+
const core = (v) => v.replace(/^v/, "").split("-")[0];
|
|
19410
|
+
if (channel === "alpha" && latest && core(latest) !== core(currentVersion) && (!pre || this.semverGt(latest, pre))) {
|
|
19387
19411
|
target = latest;
|
|
19412
|
+
fromChannel = false;
|
|
19413
|
+
}
|
|
19388
19414
|
}
|
|
19389
|
-
// A beta already at/ahead of its matching stable must NOT be told to
|
|
19390
|
-
// "update" to that stable — e.g. 2.0.11-beta.41 already contains everything
|
|
19391
|
-
// in stable 2.0.11, so semverGt(2.0.11, 2.0.11-beta.41) being true (a stable
|
|
19392
|
-
// outranks a prerelease of the same core) is a false positive here. Suppress
|
|
19393
|
-
// only that same-core stable-vs-my-beta case; a higher stable core (2.0.12)
|
|
19394
|
-
// or a newer beta (2.0.11-beta.50) still notifies via semverGt below.
|
|
19395
|
-
const core = (v) => v.replace(/^v/, "").split("-")[0];
|
|
19396
|
-
const betaSupersedesStable = isPrereleaseVersion(currentVersion) && !isPrereleaseVersion(target) && core(target) === core(currentVersion);
|
|
19397
19415
|
// Only notify when target is genuinely newer (semver), so a beta user on
|
|
19398
19416
|
// 2.0.8-beta.16 is never told that stable 2.0.7 is "available".
|
|
19399
|
-
if (target &&
|
|
19417
|
+
if (target && this.semverGt(target, currentVersion)) {
|
|
19400
19418
|
const generalId = this.findGeneralInstance();
|
|
19401
19419
|
if (generalId) {
|
|
19402
19420
|
// No release URL — Discord's SuppressEmbeds proved unreliable and the
|
|
19403
19421
|
// link preview looked bad. Version + /update instruction is enough.
|
|
19404
|
-
|
|
19422
|
+
// From the install's own channel tag, this is what /update installs — even a stable the release pointed the
|
|
19423
|
+
// tag at (2.2.0 on @alpha / @beta): the plain /update text, never "/update stays on … use --stable" (#1928).
|
|
19424
|
+
const key = fromChannel ? "update.available_current" : updateNoticeKey(currentVersion, target);
|
|
19425
|
+
this.notifyInstanceTopic(generalId, t(key, `v${target}`, `v${currentVersion}`));
|
|
19405
19426
|
}
|
|
19406
19427
|
}
|
|
19407
19428
|
}
|
|
@@ -19468,6 +19489,10 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
19468
19489
|
/** Shared handler dispatcher; gateway admission is enforced by its separate listener. */
|
|
19469
19490
|
dispatchWebHttp(req, res, port, closing = false) {
|
|
19470
19491
|
try {
|
|
19492
|
+
// #1937: the listeners allow an upload long enough for a slow link; every other request keeps its old bound on
|
|
19493
|
+
// arriving whole — 10 s through the public link's gateway, Node's 300 s here.
|
|
19494
|
+
if (!isUploadRequest(req))
|
|
19495
|
+
limitRequestReceive(req, gatewayRequestContext(req) ? PUBLIC_GATEWAY_RECEIVE_MS : 300_000);
|
|
19471
19496
|
res.setHeader("Content-Type", "application/json");
|
|
19472
19497
|
// No Referer to a tunnel host, an upstream proxy, or any page linked from
|
|
19473
19498
|
// the panel — the dashboard URL is itself a credential-bearing address.
|
|
@@ -19809,6 +19834,10 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
19809
19834
|
if (!this.webToken || !this.webSessions)
|
|
19810
19835
|
this.initializeWebAuthTokens();
|
|
19811
19836
|
const server = createServer((req, res) => this.dispatchWebHttp(req, res, port, drain.closing));
|
|
19837
|
+
// #1937: Node's default (300 s to receive a request) would cut a large upload on a slow link. The listener allows
|
|
19838
|
+
// more; the upload route keeps its own clocks (no byte for a minute, or 30 minutes in all), and every other request
|
|
19839
|
+
// keeps the old 300 s (limitRequestReceive in dispatchWebHttp).
|
|
19840
|
+
server.requestTimeout = UPLOAD_REQUEST_TIMEOUT_MS;
|
|
19812
19841
|
const drain = trackWebServer(server);
|
|
19813
19842
|
this.healthServer = server;
|
|
19814
19843
|
this.healthServerDrain = drain;
|