@songsid/agend 2.3.1 → 2.3.2-beta.1
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/authority/authority-state.d.ts +4 -0
- package/dist/authority/authority-state.js +16 -10
- package/dist/authority/authority-state.js.map +1 -1
- package/dist/authority/session-authorizations.d.ts +7 -1
- package/dist/authority/session-authorizations.js +6 -4
- package/dist/authority/session-authorizations.js.map +1 -1
- package/dist/authority/web-authority.d.ts +19 -6
- package/dist/authority/web-authority.js +22 -8
- package/dist/authority/web-authority.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +2 -0
- package/dist/channel/adapters/discord.js +33 -3
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/mcp-tools.js +5 -5
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/types.d.ts +11 -0
- package/dist/config-validator.js +40 -3
- package/dist/config-validator.js.map +1 -1
- package/dist/daemon.d.ts +34 -3
- package/dist/daemon.js +227 -46
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-outbox.d.ts +12 -1
- package/dist/delivery-outbox.js +67 -15
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/doctor.d.ts +3 -0
- package/dist/doctor.js +9 -0
- package/dist/doctor.js.map +1 -1
- package/dist/event-log.d.ts +5 -0
- package/dist/event-log.js +13 -0
- package/dist/event-log.js.map +1 -1
- package/dist/fleet-manager.d.ts +140 -0
- package/dist/fleet-manager.js +414 -29
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-process-handlers.d.ts +1 -0
- package/dist/fleet-process-handlers.js +9 -1
- package/dist/fleet-process-handlers.js.map +1 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +4 -4
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +7 -7
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +106 -55
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +107 -56
- package/dist/guest-seen-people.d.ts +38 -0
- package/dist/guest-seen-people.js +78 -0
- package/dist/guest-seen-people.js.map +1 -0
- package/dist/instance-config-impact.js +4 -1
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +1 -0
- package/dist/instance-lifecycle.js +16 -1
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +38 -10
- package/dist/locale.js.map +1 -1
- package/dist/mac-auto-restore.d.ts +117 -0
- package/dist/mac-auto-restore.js +294 -0
- package/dist/mac-auto-restore.js.map +1 -0
- package/dist/outbound-schemas.d.ts +2 -0
- package/dist/outbound-schemas.js +2 -0
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +9 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/settings-api.d.ts +26 -0
- package/dist/settings-api.js +107 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +37 -3
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +5 -2
- package/dist/settings-effect.js.map +1 -1
- package/dist/start-attempt.d.ts +9 -5
- package/dist/start-attempt.js +27 -8
- package/dist/start-attempt.js.map +1 -1
- package/dist/start-failure-chat.d.ts +4 -0
- package/dist/start-failure-chat.js +23 -6
- package/dist/start-failure-chat.js.map +1 -1
- package/dist/start-failure-notice.d.ts +4 -0
- package/dist/start-failure-notice.js +8 -0
- package/dist/start-failure-notice.js.map +1 -1
- package/dist/start-failure.d.ts +25 -0
- package/dist/start-failure.js +75 -2
- package/dist/start-failure.js.map +1 -1
- package/dist/turn-reply-guard.d.ts +25 -0
- package/dist/turn-reply-guard.js +111 -12
- package/dist/turn-reply-guard.js.map +1 -1
- package/dist/types.d.ts +18 -1
- package/dist/ui/backend-signin.js +5 -2
- package/dist/ui/chat-ambient.js +1 -1
- package/dist/ui/chat-effects.js +4 -4
- package/dist/ui/chat-render.js +5 -2
- package/dist/ui/chat-strings.js +2 -2
- package/dist/ui/chat-thread.js +2 -2
- package/dist/ui/first-run.js +2 -2
- package/dist/ui/fleet-canvas-view.js +114 -0
- package/dist/ui/fleet-canvas.js +15 -77
- package/dist/ui/fleet-office-editor.js +80 -5
- package/dist/ui/fleet-office-layout.js +197 -0
- package/dist/ui/fleet-office-model.js +6 -3
- package/dist/ui/fleet-office-pack.d.ts +39 -0
- package/dist/ui/fleet-office-pack.js +240 -29
- package/dist/ui/fleet-office-skin.js +130 -21
- package/dist/ui/fleet-office-store.js +75 -4
- package/dist/ui/fleet-office-view.js +154 -0
- package/dist/ui/fleet-office-zones.js +95 -33
- package/dist/ui/fleet-office.js +530 -94
- package/dist/ui/fleet-usage.js +7 -6
- package/dist/ui/panel-chat.js +1 -1
- package/dist/ui/panel-details.js +2 -2
- package/dist/ui/panel-fleet.js +11 -77
- package/dist/ui/panel-log.js +2 -2
- package/dist/ui/panel-settings.js +578 -163
- package/dist/ui/search-dialog.js +26 -7
- package/dist/ui/settings-appearance.js +82 -29
- package/dist/ui/settings-apply.js +42 -7
- package/dist/ui/settings-dialogs.js +68 -22
- package/dist/ui/settings-draft.js +51 -0
- package/dist/ui/settings-guests.js +244 -78
- package/dist/ui/settings-learn.js +2 -2
- package/dist/ui/settings-model.js +2 -0
- package/dist/ui/settings-registry.js +142 -0
- package/dist/ui/settings-strings.js +102 -44
- package/dist/ui/settings-web-authority.js +34 -23
- package/dist/ui/shared/app-i18n.js +14 -0
- package/dist/ui/shared/app-nav.js +10 -5
- package/dist/ui/shared/app-prefs.js +80 -2
- package/dist/ui/shared/app-route.js +39 -5
- package/dist/ui/shared/app-shell.js +59 -4
- package/dist/ui/shared/app-stream.js +2 -1
- package/dist/ui/shared/app.css +242 -17
- package/dist/ui/shared/app.js +3 -0
- package/dist/ui/shared/effect-stock-trust.js +1 -1
- package/dist/ui/shared/identity-color.js +4 -4
- package/dist/ui/shared/signin.js +2 -2
- package/dist/ui/shared/ui-dialog.js +6 -1
- package/dist/ui/shared/ui-icons.js +2 -0
- package/dist/ui/shared/web-authorize.js +13 -12
- package/dist/web-api.d.ts +8 -2
- package/dist/web-api.js +160 -5
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.js +7 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-experimental.d.ts +1 -1
- package/dist/web-experimental.js +1 -1
- package/dist/web-experimental.js.map +1 -1
- package/dist/web-mod-agent.js +2 -2
- package/dist/web-mod-agent.js.map +1 -1
- package/dist/web-office-skins.d.ts +108 -0
- package/dist/web-office-skins.js +298 -0
- package/dist/web-office-skins.js.map +1 -0
- package/dist/web-office-store.d.ts +8 -2
- package/dist/web-office-store.js +37 -7
- package/dist/web-office-store.js.map +1 -1
- package/dist/web-settings-patch.d.ts +6 -0
- package/dist/web-settings-patch.js +61 -4
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-shell-routes.d.ts +4 -2
- package/dist/web-shell-routes.js +17 -7
- package/dist/web-shell-routes.js.map +1 -1
- package/dist/working-recovery.d.ts +104 -0
- package/dist/working-recovery.js +263 -0
- package/dist/working-recovery.js.map +1 -0
- package/dist/working-state-journal.d.ts +3 -1
- package/dist/working-state-journal.js +15 -2
- package/dist/working-state-journal.js.map +1 -1
- package/package.json +1 -1
|
@@ -5,10 +5,14 @@ export interface AuthorityState {
|
|
|
5
5
|
loopbackOnly: boolean;
|
|
6
6
|
/** §0.2 (#2453): sessions over the admin's named tunnel may qualify (false while the state cannot be written). */
|
|
7
7
|
namedLink: boolean;
|
|
8
|
+
/** §0.3: sessions over the temporary public link may qualify (false while the state cannot be written). */
|
|
9
|
+
quickLink: boolean;
|
|
8
10
|
/** The current revocation epoch: authority granted under an older one reads as none. */
|
|
9
11
|
epoch: number;
|
|
10
12
|
/** #2453: this read saw the named-link option go off (the fleet then drops the named-link sessions' authorizations). */
|
|
11
13
|
namedLinkClosed?: true;
|
|
14
|
+
/** §0.3: this read saw the quick-link option go off (the fleet then drops the quick-link sessions' authorizations). */
|
|
15
|
+
quickLinkClosed?: true;
|
|
12
16
|
}
|
|
13
17
|
export interface AuthorityStateIo {
|
|
14
18
|
read(path: string): string;
|
|
@@ -16,8 +16,11 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { readFileSync } from "node:fs";
|
|
18
18
|
import { atomicWriteFileSync } from "../atomic-write.js";
|
|
19
|
+
import { quickLinkEffective } from "./web-authority.js";
|
|
19
20
|
const same = (a, b) => a.epoch === b.epoch && a.enabled === b.enabled && a.loopback_only === b.loopback_only
|
|
20
|
-
&& !!a.named_link === !!b.named_link && !!a.named_link_seen === !!b.named_link_seen
|
|
21
|
+
&& !!a.named_link === !!b.named_link && !!a.named_link_seen === !!b.named_link_seen
|
|
22
|
+
&& !!a.quick_link === !!b.quick_link;
|
|
23
|
+
const optional = (v) => v === undefined || typeof v === "boolean";
|
|
21
24
|
const fileIo = { read: p => readFileSync(p, "utf8"), write: (p, d) => atomicWriteFileSync(p, d, { mode: 0o600 }) };
|
|
22
25
|
export class AuthorityStateStore {
|
|
23
26
|
path;
|
|
@@ -63,9 +66,10 @@ export class AuthorityStateStore {
|
|
|
63
66
|
try {
|
|
64
67
|
const v = JSON.parse(raw ?? "");
|
|
65
68
|
if (v.v === 1 && Number.isSafeInteger(v.epoch) && v.epoch >= floor && typeof v.enabled === "boolean" && typeof v.loopback_only === "boolean"
|
|
66
|
-
&& (v.named_link
|
|
69
|
+
&& optional(v.named_link) && optional(v.named_link_seen) && optional(v.quick_link)) {
|
|
67
70
|
this.want = { v: 1, epoch: v.epoch, enabled: v.enabled, loopback_only: v.loopback_only,
|
|
68
|
-
...(v.named_link ? { named_link: true } : {}), ...(v.named_link || v.named_link_seen ? { named_link_seen: true } : {})
|
|
71
|
+
...(v.named_link ? { named_link: true } : {}), ...(v.named_link || v.named_link_seen ? { named_link_seen: true } : {}),
|
|
72
|
+
...(v.quick_link ? { quick_link: true } : {}) };
|
|
69
73
|
this.disk = { ...this.want };
|
|
70
74
|
return this.want;
|
|
71
75
|
}
|
|
@@ -100,18 +104,20 @@ export class AuthorityStateStore {
|
|
|
100
104
|
const s = this.load();
|
|
101
105
|
const enabled = config?.enabled !== false, loopbackOnly = config?.loopback_only === true; // §0.1: on by default
|
|
102
106
|
const namedLink = config?.named_link === true; // §0.2: off by default
|
|
103
|
-
const
|
|
104
|
-
const
|
|
107
|
+
const quickLink = quickLinkEffective(config); // §0.3: off by default
|
|
108
|
+
const reopened = (namedLink && !s.named_link && !!s.named_link_seen) || (quickLink && !s.quick_link); // §0.3: every widening
|
|
109
|
+
const closed = !!s.named_link && !namedLink, quickClosed = !!s.quick_link && !quickLink;
|
|
105
110
|
const revokes = s.enabled !== enabled || (s.loopback_only && !loopbackOnly) || reopened;
|
|
106
|
-
if (revokes || s.loopback_only !== loopbackOnly || !!s.named_link !== namedLink) {
|
|
111
|
+
if (revokes || s.loopback_only !== loopbackOnly || !!s.named_link !== namedLink || !!s.quick_link !== quickLink) {
|
|
107
112
|
this.want = { v: 1, epoch: s.epoch + (revokes ? 1 : 0), enabled, loopback_only: loopbackOnly,
|
|
108
|
-
...(namedLink ? { named_link: true } : {}), ...(namedLink || s.named_link_seen ? { named_link_seen: true } : {})
|
|
113
|
+
...(namedLink ? { named_link: true } : {}), ...(namedLink || s.named_link_seen ? { named_link_seen: true } : {}),
|
|
114
|
+
...(quickLink ? { quick_link: true } : {}) };
|
|
109
115
|
}
|
|
110
116
|
const durable = this.flush();
|
|
111
117
|
// Not written: off, and still "only this computer" if it was (a loosening that did not stick does not apply).
|
|
112
|
-
const seenClosed = closed ? { namedLinkClosed: true } : {};
|
|
113
|
-
return durable ? { enabled, loopbackOnly, namedLink, epoch: this.want.epoch, ...seenClosed }
|
|
114
|
-
: { enabled: false, loopbackOnly: loopbackOnly || (this.disk?.loopback_only ?? true), namedLink: false, epoch: this.want.epoch, ...seenClosed };
|
|
118
|
+
const seenClosed = { ...(closed ? { namedLinkClosed: true } : {}), ...(quickClosed ? { quickLinkClosed: true } : {}) };
|
|
119
|
+
return durable ? { enabled, loopbackOnly, namedLink, quickLink, epoch: this.want.epoch, ...seenClosed }
|
|
120
|
+
: { enabled: false, loopbackOnly: loopbackOnly || (this.disk?.loopback_only ?? true), namedLink: false, quickLink: false, epoch: this.want.epoch, ...seenClosed };
|
|
115
121
|
}
|
|
116
122
|
/** An explicit revocation: every web authority given so far reads as none. `durable`: it is on disk. */
|
|
117
123
|
revoke() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authority-state.js","sourceRoot":"","sources":["../../src/authority/authority-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"authority-state.js","sourceRoot":"","sources":["../../src/authority/authority-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { WebPeer } from "./web-authority.js";
|
|
1
2
|
export interface SessionAuthorization {
|
|
2
3
|
readonly handle: string;
|
|
3
4
|
readonly owner: {
|
|
@@ -9,6 +10,11 @@ export interface SessionAuthorization {
|
|
|
9
10
|
/** §0.1: the end it was given with (authorizedAt + max_session_hours then): a longer setting later never stretches it. */
|
|
10
11
|
readonly until: number;
|
|
11
12
|
readonly epoch: number;
|
|
13
|
+
/**
|
|
14
|
+
* §0.3: where the session was when its account confirmed it — so a link's option turned off drops only that link's
|
|
15
|
+
* authorizations. Absent on records written before §0.3 (then only a local session or a named-link one could be).
|
|
16
|
+
*/
|
|
17
|
+
readonly peer?: WebPeer;
|
|
12
18
|
}
|
|
13
19
|
/** At most this many kept: one per signed-in session (the store's own caps are far lower). */
|
|
14
20
|
export declare const SESSION_AUTHORIZATIONS_MAX = 256;
|
|
@@ -33,7 +39,7 @@ export declare class SessionAuthorizations {
|
|
|
33
39
|
authorize(handle: string, owner: {
|
|
34
40
|
adapterId: string;
|
|
35
41
|
userId: string;
|
|
36
|
-
}, authorizedAt: number, epoch: number, until: number): {
|
|
42
|
+
}, authorizedAt: number, epoch: number, until: number, peer?: WebPeer): {
|
|
37
43
|
authorization: SessionAuthorization;
|
|
38
44
|
durable: boolean;
|
|
39
45
|
};
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { readFileSync } from "node:fs";
|
|
9
9
|
import { atomicWriteFileSync } from "../atomic-write.js";
|
|
10
|
+
const PEERS = ["loopback", "lan", "named_link", "quick_link"];
|
|
10
11
|
/** At most this many kept: one per signed-in session (the store's own caps are far lower). */
|
|
11
12
|
export const SESSION_AUTHORIZATIONS_MAX = 256;
|
|
12
13
|
const HANDLE = /^[0-9a-f]{16}$/;
|
|
@@ -17,7 +18,8 @@ function valid(v) {
|
|
|
17
18
|
const a = v;
|
|
18
19
|
return typeof a.handle === "string" && HANDLE.test(a.handle) && !!a.owner && typeof a.owner.adapterId === "string" && !!a.owner.adapterId
|
|
19
20
|
&& typeof a.owner.userId === "string" && !!a.owner.userId && Number.isSafeInteger(a.authorizedAt) && a.authorizedAt > 0
|
|
20
|
-
&& Number.isSafeInteger(a.until) && a.until > a.authorizedAt && Number.isSafeInteger(a.epoch) && a.epoch >= 0
|
|
21
|
+
&& Number.isSafeInteger(a.until) && a.until > a.authorizedAt && Number.isSafeInteger(a.epoch) && a.epoch >= 0
|
|
22
|
+
&& (a.peer === undefined || PEERS.includes(a.peer));
|
|
21
23
|
}
|
|
22
24
|
export class SessionAuthorizations {
|
|
23
25
|
path;
|
|
@@ -48,7 +50,7 @@ export class SessionAuthorizations {
|
|
|
48
50
|
if (v.v === 1 && Array.isArray(v.authorizations))
|
|
49
51
|
for (const a of v.authorizations.slice(0, SESSION_AUTHORIZATIONS_MAX)) {
|
|
50
52
|
if (valid(a))
|
|
51
|
-
this.byHandle.set(a.handle, Object.freeze({ handle: a.handle, owner: Object.freeze({ adapterId: a.owner.adapterId, userId: a.owner.userId }), authorizedAt: a.authorizedAt, until: a.until, epoch: a.epoch }));
|
|
53
|
+
this.byHandle.set(a.handle, Object.freeze({ handle: a.handle, owner: Object.freeze({ adapterId: a.owner.adapterId, userId: a.owner.userId }), authorizedAt: a.authorizedAt, until: a.until, epoch: a.epoch, ...(a.peer ? { peer: a.peer } : {}) }));
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
catch {
|
|
@@ -72,8 +74,8 @@ export class SessionAuthorizations {
|
|
|
72
74
|
}
|
|
73
75
|
get(handle) { return this.load().get(handle) ?? null; }
|
|
74
76
|
/** §0: this session is authorized by its account, from now until `until`, under `epoch` (it replaces an earlier one). */
|
|
75
|
-
authorize(handle, owner, authorizedAt, epoch, until) {
|
|
76
|
-
const a = Object.freeze({ handle, owner: Object.freeze({ adapterId: owner.adapterId, userId: owner.userId }), authorizedAt, until, epoch });
|
|
77
|
+
authorize(handle, owner, authorizedAt, epoch, until, peer) {
|
|
78
|
+
const a = Object.freeze({ handle, owner: Object.freeze({ adapterId: owner.adapterId, userId: owner.userId }), authorizedAt, until, epoch, ...(peer ? { peer } : {}) });
|
|
77
79
|
if (!valid(a))
|
|
78
80
|
throw new Error("invalid session authorization");
|
|
79
81
|
const map = this.load();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-authorizations.js","sourceRoot":"","sources":["../../src/authority/session-authorizations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-authorizations.js","sourceRoot":"","sources":["../../src/authority/session-authorizations.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,9 +11,10 @@ import type { SessionAuthorization } from "./session-authorizations.js";
|
|
|
11
11
|
/**
|
|
12
12
|
* Where one request came from (§3.4): `loopback` is this machine naming a loopback host; `lan` is only "not loopback".
|
|
13
13
|
* §0.2 (#2453): `named_link` is the admin's own named tunnel, known only from the public gateway's provenance (its exact
|
|
14
|
-
* configured hostname) — never from the TCP peer (cloudflared is local) or a header.
|
|
14
|
+
* configured hostname) — never from the TCP peer (cloudflared is local) or a header. §0.3: `quick_link` is every other
|
|
15
|
+
* request over the public gateway (the temporary quick-tunnel link), likewise from provenance only.
|
|
15
16
|
*/
|
|
16
|
-
export type WebPeer = "loopback" | "lan" | "named_link";
|
|
17
|
+
export type WebPeer = "loopback" | "lan" | "named_link" | "quick_link";
|
|
17
18
|
/** The account behind a human receipt, written by AgEnD at admission — nothing in a message can set it (§4). */
|
|
18
19
|
export interface HumanAuthority {
|
|
19
20
|
kind: "platform" | "web-verified" | "none";
|
|
@@ -35,9 +36,9 @@ export interface HumanAuthority {
|
|
|
35
36
|
downgraded?: AuthorityDowngrade;
|
|
36
37
|
}
|
|
37
38
|
/** §10: what turned a web-verified receipt into none after it was written. */
|
|
38
|
-
export type AuthorityDowngrade = "disabled" | "revoked" | "loopback_only" | "named_link_off";
|
|
39
|
+
export type AuthorityDowngrade = "disabled" | "revoked" | "loopback_only" | "named_link_off" | "quick_link_off";
|
|
39
40
|
/** Why a web request carries no authority — the first §3 check it failed. */
|
|
40
|
-
export type WebAuthorityRefusal = "disabled" | "public_link" | "named_link_off" | "not_session" | "not_admin_session" | "token_rotated" | "no_account" | "not_admin" | "other_namespace" | "loopback_only" | "not_authorized" | "authorization_expired" | "session_changed";
|
|
41
|
+
export type WebAuthorityRefusal = "disabled" | "public_link" | "named_link_off" | "quick_link_off" | "not_session" | "not_admin_session" | "token_rotated" | "no_account" | "not_admin" | "other_namespace" | "loopback_only" | "not_authorized" | "authorization_expired" | "session_changed";
|
|
41
42
|
export interface WebAuthorityResult {
|
|
42
43
|
authority: HumanAuthority;
|
|
43
44
|
refusal: WebAuthorityRefusal | null;
|
|
@@ -54,10 +55,21 @@ export interface WebAuthorityPolicy {
|
|
|
54
55
|
loopbackOnly: boolean;
|
|
55
56
|
/** §0.2: sessions over the admin's own named tunnel may qualify (web.verified_authority.named_link; off by default). */
|
|
56
57
|
namedLink: boolean;
|
|
58
|
+
/** §0.3: sessions over the temporary public link may qualify (web.verified_authority.quick_link; quickLinkEffective). */
|
|
59
|
+
quickLink: boolean;
|
|
57
60
|
maxSessionMs: number;
|
|
58
61
|
}
|
|
59
62
|
/** The policy in fleet.yaml; a value the validator refuses never loosens it (a bad number is the 48 h default, clamped). */
|
|
60
63
|
export declare function webAuthorityPolicy(web: WebConfig | undefined): WebAuthorityPolicy;
|
|
64
|
+
/** §0.3: the release default of `web.verified_authority.quick_link` — off (the user's decision, 2026-10-23). */
|
|
65
|
+
export declare const QUICK_LINK_DEFAULT = false;
|
|
66
|
+
/**
|
|
67
|
+
* §0.3: the quick-link option as in force — its explicit value, else the release default. Every widening is judged on
|
|
68
|
+
* this (settings-change.ts, settings-effect.ts), never on the raw key: a key removed to inherit is a change of value too.
|
|
69
|
+
*/
|
|
70
|
+
export declare function quickLinkEffective(v: {
|
|
71
|
+
quick_link?: unknown;
|
|
72
|
+
} | undefined | null, fallback?: boolean): boolean;
|
|
61
73
|
/**
|
|
62
74
|
* §3.4, from this request alone: `loopback` only when its TCP peer is a loopback address, its Host names a loopback host,
|
|
63
75
|
* and it carries no forwarding header. It does not prove who sits at the machine (a local proxy that strips forwarding
|
|
@@ -99,14 +111,15 @@ export declare function evaluateWebAuthority(i: WebAuthorityInput): WebAuthority
|
|
|
99
111
|
export declare function confirmAfterBody(arrival: WebAuthorityResult, now: WebAuthorityResult): WebAuthorityResult;
|
|
100
112
|
/**
|
|
101
113
|
* §10: a receipt's authority as it reads NOW. A web-verified one reads as none, saying why, while the switch is off, once
|
|
102
|
-
* the epoch has moved past the one it was granted under, (
|
|
103
|
-
* on, or (named_link, §0.2) while
|
|
114
|
+
* the epoch has moved past the one it was granted under, (every peer but loopback) while "Only this computer can
|
|
115
|
+
* authorize" is on, or (named_link, §0.2; quick_link, §0.3) while that link's option is off.
|
|
104
116
|
* Platform and none are unchanged. The receiver applies the rule to this, never to the stored value.
|
|
105
117
|
*/
|
|
106
118
|
export declare function authorityNow(stored: HumanAuthority, state: {
|
|
107
119
|
enabled: boolean;
|
|
108
120
|
loopbackOnly: boolean;
|
|
109
121
|
namedLink: boolean;
|
|
122
|
+
quickLink: boolean;
|
|
110
123
|
epoch: number;
|
|
111
124
|
}): HumanAuthority;
|
|
112
125
|
/** A Discord or Telegram message or click: its sender, from the platform's own event. */
|
|
@@ -7,7 +7,17 @@ export function webAuthorityPolicy(web) {
|
|
|
7
7
|
const hours = typeof v?.max_session_hours === "number" && Number.isFinite(v.max_session_hours)
|
|
8
8
|
? Math.min(VERIFIED_SESSION_HOURS.max, Math.max(VERIFIED_SESSION_HOURS.min, v.max_session_hours)) : VERIFIED_SESSION_HOURS.default;
|
|
9
9
|
// §0.1: the switch is on unless fleet.yaml says false (nothing carries authority until its account confirms anyway).
|
|
10
|
-
return { enabled: v?.enabled !== false, loopbackOnly: v?.loopback_only === true, namedLink: v?.named_link === true,
|
|
10
|
+
return { enabled: v?.enabled !== false, loopbackOnly: v?.loopback_only === true, namedLink: v?.named_link === true,
|
|
11
|
+
quickLink: quickLinkEffective(v), maxSessionMs: hours * 3_600_000 };
|
|
12
|
+
}
|
|
13
|
+
/** §0.3: the release default of `web.verified_authority.quick_link` — off (the user's decision, 2026-10-23). */
|
|
14
|
+
export const QUICK_LINK_DEFAULT = false;
|
|
15
|
+
/**
|
|
16
|
+
* §0.3: the quick-link option as in force — its explicit value, else the release default. Every widening is judged on
|
|
17
|
+
* this (settings-change.ts, settings-effect.ts), never on the raw key: a key removed to inherit is a change of value too.
|
|
18
|
+
*/
|
|
19
|
+
export function quickLinkEffective(v, fallback = QUICK_LINK_DEFAULT) {
|
|
20
|
+
return typeof v?.quick_link === "boolean" ? v.quick_link : fallback;
|
|
11
21
|
}
|
|
12
22
|
/** Headers a proxy adds; any one of them makes a request `lan`, whatever its peer address (§3.4). */
|
|
13
23
|
const FORWARDING_HEADERS = ["forwarded", "x-forwarded-for", "x-forwarded-host", "x-real-ip", "cf-connecting-ip", "via"];
|
|
@@ -40,15 +50,16 @@ export function evaluateWebAuthority(i) {
|
|
|
40
50
|
return refuse("disabled");
|
|
41
51
|
// §3.5 / §0.2: the public link never qualifies — except the admin's own named tunnel (provenance, exact hostname)
|
|
42
52
|
// while the option is on and "Only this computer can authorize" is off. A peer that says named off the gateway is not.
|
|
53
|
+
// §0.3: the temporary public link (a gateway request that is not named) likewise, by its own option.
|
|
43
54
|
if (i.gateway) {
|
|
44
|
-
if (i.peer !== "named_link")
|
|
55
|
+
if (i.peer !== "named_link" && i.peer !== "quick_link")
|
|
45
56
|
return refuse("public_link");
|
|
46
57
|
if (i.policy.loopbackOnly)
|
|
47
58
|
return refuse("loopback_only");
|
|
48
|
-
if (!i.policy.namedLink)
|
|
49
|
-
return refuse("named_link_off");
|
|
59
|
+
if (i.peer === "named_link" ? !i.policy.namedLink : !i.policy.quickLink)
|
|
60
|
+
return refuse(i.peer === "named_link" ? "named_link_off" : "quick_link_off");
|
|
50
61
|
}
|
|
51
|
-
else if (i.peer === "named_link")
|
|
62
|
+
else if (i.peer === "named_link" || i.peer === "quick_link")
|
|
52
63
|
return refuse("public_link");
|
|
53
64
|
if (!s)
|
|
54
65
|
return refuse("not_session");
|
|
@@ -98,8 +109,8 @@ export function confirmAfterBody(arrival, now) {
|
|
|
98
109
|
}
|
|
99
110
|
/**
|
|
100
111
|
* §10: a receipt's authority as it reads NOW. A web-verified one reads as none, saying why, while the switch is off, once
|
|
101
|
-
* the epoch has moved past the one it was granted under, (
|
|
102
|
-
* on, or (named_link, §0.2) while
|
|
112
|
+
* the epoch has moved past the one it was granted under, (every peer but loopback) while "Only this computer can
|
|
113
|
+
* authorize" is on, or (named_link, §0.2; quick_link, §0.3) while that link's option is off.
|
|
103
114
|
* Platform and none are unchanged. The receiver applies the rule to this, never to the stored value.
|
|
104
115
|
*/
|
|
105
116
|
export function authorityNow(stored, state) {
|
|
@@ -115,6 +126,9 @@ export function authorityNow(stored, state) {
|
|
|
115
126
|
// §0.2: the named-link option off — every receipt from a session over it reads as none at once.
|
|
116
127
|
if (!state.namedLink && stored.session?.peer === "named_link")
|
|
117
128
|
return down("named_link_off");
|
|
129
|
+
// §0.3: the quick-link option off — likewise for every receipt from a session over the temporary public link.
|
|
130
|
+
if (!state.quickLink && stored.session?.peer === "quick_link")
|
|
131
|
+
return down("quick_link_off");
|
|
118
132
|
return stored;
|
|
119
133
|
}
|
|
120
134
|
/** A Discord or Telegram message or click: its sender, from the platform's own event. */
|
|
@@ -143,7 +157,7 @@ export function isHumanAuthority(v) {
|
|
|
143
157
|
if (a.kind !== "web-verified" || !actorOk)
|
|
144
158
|
return false;
|
|
145
159
|
const s = a.session;
|
|
146
|
-
return !!s && typeof s === "object" && typeof s.handle === "string" && !!s.handle && (s.peer === "loopback" || s.peer === "lan" || s.peer === "named_link")
|
|
160
|
+
return !!s && typeof s === "object" && typeof s.handle === "string" && !!s.handle && (s.peer === "loopback" || s.peer === "lan" || s.peer === "named_link" || s.peer === "quick_link")
|
|
147
161
|
&& typeof s.signed_in_at === "string" && typeof s.authorized_at === "string";
|
|
148
162
|
}
|
|
149
163
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-authority.js","sourceRoot":"","sources":["../../src/authority/web-authority.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"web-authority.js","sourceRoot":"","sources":["../../src/authority/web-authority.ts"],"names":[],"mappings":"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"}
|
|
@@ -118,6 +118,8 @@ export declare class DiscordAdapter extends EventEmitter implements ChannelAdapt
|
|
|
118
118
|
private queue;
|
|
119
119
|
private lastChatId;
|
|
120
120
|
private attachmentUrls;
|
|
121
|
+
/** #2551: recent messages a bot wrote (ids), so a reply to one pings its author explicitly (repliedUser). */
|
|
122
|
+
private botAuthored;
|
|
121
123
|
private categoryIdPromise?;
|
|
122
124
|
constructor(opts: DiscordAdapterOptions);
|
|
123
125
|
private buildClient;
|
|
@@ -213,6 +213,8 @@ export class DiscordAdapter extends EventEmitter {
|
|
|
213
213
|
queue;
|
|
214
214
|
lastChatId = null;
|
|
215
215
|
attachmentUrls = new Map();
|
|
216
|
+
/** #2551: recent messages a bot wrote (ids), so a reply to one pings its author explicitly (repliedUser). */
|
|
217
|
+
botAuthored = new Set();
|
|
216
218
|
categoryIdPromise;
|
|
217
219
|
constructor(opts) {
|
|
218
220
|
super();
|
|
@@ -550,11 +552,27 @@ export class DiscordAdapter extends EventEmitter {
|
|
|
550
552
|
// the reply rather than reducing the reference to text alone. Keep this
|
|
551
553
|
// limited to real attachments: ordinary URL auto-embeds must not become
|
|
552
554
|
// downloads (the same policy as the outer message above).
|
|
553
|
-
let replyToText;
|
|
555
|
+
let replyToText, replyToAuthorId, replyToChain = false;
|
|
554
556
|
if (msg.reference?.messageId) {
|
|
555
557
|
try {
|
|
556
558
|
const ref = await msg.fetchReference();
|
|
557
559
|
replyToText = ref.content || ref.embeds?.[0]?.description || undefined;
|
|
560
|
+
// #2551: who the reply answers (a bot's reply to our bot's message is addressed to it), and whether that
|
|
561
|
+
// message itself answered a bot or this sender — then this is a chain of bots answering each other, not one
|
|
562
|
+
// hop. Its own reply target: the user it pinged, else read once (a reply to a deleted message: not a chain).
|
|
563
|
+
replyToAuthorId = ref.author?.id || undefined;
|
|
564
|
+
if (ref.reference?.messageId) {
|
|
565
|
+
let parent = ref.mentions?.repliedUser ?? null;
|
|
566
|
+
if (!parent) {
|
|
567
|
+
try {
|
|
568
|
+
parent = (await ref.fetchReference()).author ?? null;
|
|
569
|
+
}
|
|
570
|
+
catch {
|
|
571
|
+
parent = null;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
replyToChain = !!parent && (parent.bot === true || parent.id === userId);
|
|
575
|
+
}
|
|
558
576
|
for (const att of ref.attachments?.values() ?? []) {
|
|
559
577
|
if (!att.contentType?.startsWith("image/"))
|
|
560
578
|
continue;
|
|
@@ -589,6 +607,11 @@ export class DiscordAdapter extends EventEmitter {
|
|
|
589
607
|
});
|
|
590
608
|
this.attachmentUrls.set(fileId, url);
|
|
591
609
|
});
|
|
610
|
+
if (isBotMessage) {
|
|
611
|
+
this.botAuthored.add(messageId);
|
|
612
|
+
while (this.botAuthored.size > 1000)
|
|
613
|
+
this.botAuthored.delete(this.botAuthored.values().next().value);
|
|
614
|
+
}
|
|
592
615
|
// Store attachment URLs for later download
|
|
593
616
|
for (const att of msg.attachments.values()) {
|
|
594
617
|
this.attachmentUrls.set(att.id, att.url);
|
|
@@ -616,6 +639,8 @@ export class DiscordAdapter extends EventEmitter {
|
|
|
616
639
|
attachments: attachments.length > 0 ? attachments : undefined,
|
|
617
640
|
replyTo: msg.reference?.messageId ?? undefined,
|
|
618
641
|
replyToText,
|
|
642
|
+
...(replyToAuthorId ? { replyToAuthorId } : {}),
|
|
643
|
+
...(replyToChain ? { replyToChain: true } : {}),
|
|
619
644
|
});
|
|
620
645
|
}
|
|
621
646
|
catch (err) {
|
|
@@ -1501,11 +1526,16 @@ export class DiscordAdapter extends EventEmitter {
|
|
|
1501
1526
|
// #2281: `replyTo` makes the first part a native reply (a Discord snowflake only). failIfNotExists: false — a reply
|
|
1502
1527
|
// to a message deleted since is sent as a plain message by Discord itself.
|
|
1503
1528
|
const replyTo = opts?.replyTo && /^\d{15,25}$/.test(opts.replyTo) ? opts.replyTo : undefined;
|
|
1529
|
+
// #2551: a reply to a bot's message pings that bot explicitly (repliedUser), with the caller's mentions or Discord's
|
|
1530
|
+
// defaults otherwise unchanged — a parse list given without it would leave the replied bot unpinged.
|
|
1531
|
+
const allowedMentions = replyTo && this.botAuthored.has(replyTo)
|
|
1532
|
+
? { ...(opts?.allowedMentions ?? { parse: ["users", "roles", "everyone"] }), repliedUser: true }
|
|
1533
|
+
: opts?.allowedMentions;
|
|
1504
1534
|
for (const [i, chunk] of chunks.entries()) {
|
|
1505
1535
|
const components = replyRows && i === chunks.length - 1 ? { components: replyRows } : {};
|
|
1506
1536
|
const reply = replyTo && i === 0 ? { reply: { messageReference: replyTo, failIfNotExists: false } } : {};
|
|
1507
|
-
const payload = (withReply) => opts?.disablePreview ||
|
|
1508
|
-
? { content: chunk, ...(opts?.disablePreview ? { flags: MessageFlags.SuppressEmbeds } : {}), ...(
|
|
1537
|
+
const payload = (withReply) => opts?.disablePreview || allowedMentions || replyRows || (withReply && replyTo && i === 0)
|
|
1538
|
+
? { content: chunk, ...(opts?.disablePreview ? { flags: MessageFlags.SuppressEmbeds } : {}), ...(allowedMentions ? { allowedMentions } : {}), ...components, ...(withReply ? reply : {}) }
|
|
1509
1539
|
: chunk;
|
|
1510
1540
|
let sent;
|
|
1511
1541
|
try {
|