@songsid/agend 2.3.0 → 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.
Files changed (201) hide show
  1. package/README.md +1 -1
  2. package/README.zh-TW.md +1 -1
  3. package/dist/authority/authority-state.d.ts +4 -0
  4. package/dist/authority/authority-state.js +16 -10
  5. package/dist/authority/authority-state.js.map +1 -1
  6. package/dist/authority/session-authorizations.d.ts +7 -1
  7. package/dist/authority/session-authorizations.js +6 -4
  8. package/dist/authority/session-authorizations.js.map +1 -1
  9. package/dist/authority/web-authority.d.ts +19 -6
  10. package/dist/authority/web-authority.js +22 -8
  11. package/dist/authority/web-authority.js.map +1 -1
  12. package/dist/backend/muse.d.ts +20 -2
  13. package/dist/backend/muse.js +154 -16
  14. package/dist/backend/muse.js.map +1 -1
  15. package/dist/channel/adapters/discord.d.ts +2 -0
  16. package/dist/channel/adapters/discord.js +33 -3
  17. package/dist/channel/adapters/discord.js.map +1 -1
  18. package/dist/channel/adapters/telegram.d.ts +1 -1
  19. package/dist/channel/adapters/telegram.js +3 -35
  20. package/dist/channel/adapters/telegram.js.map +1 -1
  21. package/dist/channel/mcp-tools.js +5 -5
  22. package/dist/channel/mcp-tools.js.map +1 -1
  23. package/dist/channel/types.d.ts +11 -0
  24. package/dist/cli.js +6 -3
  25. package/dist/cli.js.map +1 -1
  26. package/dist/config-validator.js +42 -5
  27. package/dist/config-validator.js.map +1 -1
  28. package/dist/daemon.d.ts +47 -3
  29. package/dist/daemon.js +380 -60
  30. package/dist/daemon.js.map +1 -1
  31. package/dist/delivery-outbox.d.ts +23 -1
  32. package/dist/delivery-outbox.js +114 -17
  33. package/dist/delivery-outbox.js.map +1 -1
  34. package/dist/doctor.d.ts +3 -0
  35. package/dist/doctor.js +9 -0
  36. package/dist/doctor.js.map +1 -1
  37. package/dist/event-log.d.ts +5 -0
  38. package/dist/event-log.js +13 -0
  39. package/dist/event-log.js.map +1 -1
  40. package/dist/fleet-context.d.ts +1 -1
  41. package/dist/fleet-lock.d.ts +6 -0
  42. package/dist/fleet-lock.js +19 -0
  43. package/dist/fleet-lock.js.map +1 -1
  44. package/dist/fleet-manager.d.ts +174 -2
  45. package/dist/fleet-manager.js +678 -68
  46. package/dist/fleet-manager.js.map +1 -1
  47. package/dist/fleet-process-handlers.d.ts +1 -0
  48. package/dist/fleet-process-handlers.js +9 -1
  49. package/dist/fleet-process-handlers.js.map +1 -1
  50. package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +11 -0
  51. package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +4 -4
  52. package/dist/general-knowledge/skills/web-appearance/SKILL.md +7 -7
  53. package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +109 -57
  54. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +110 -58
  55. package/dist/guest-seen-people.d.ts +38 -0
  56. package/dist/guest-seen-people.js +78 -0
  57. package/dist/guest-seen-people.js.map +1 -0
  58. package/dist/instance-config-impact.js +4 -1
  59. package/dist/instance-config-impact.js.map +1 -1
  60. package/dist/instance-lifecycle.d.ts +2 -0
  61. package/dist/instance-lifecycle.js +27 -1
  62. package/dist/instance-lifecycle.js.map +1 -1
  63. package/dist/locale.js +62 -12
  64. package/dist/locale.js.map +1 -1
  65. package/dist/log-service.js +1 -0
  66. package/dist/log-service.js.map +1 -1
  67. package/dist/mac-auto-restore.d.ts +117 -0
  68. package/dist/mac-auto-restore.js +294 -0
  69. package/dist/mac-auto-restore.js.map +1 -0
  70. package/dist/needs-you.js +1 -0
  71. package/dist/needs-you.js.map +1 -1
  72. package/dist/outbound-handlers.d.ts +2 -2
  73. package/dist/outbound-handlers.js +5 -5
  74. package/dist/outbound-handlers.js.map +1 -1
  75. package/dist/outbound-schemas.d.ts +2 -0
  76. package/dist/outbound-schemas.js +2 -0
  77. package/dist/outbound-schemas.js.map +1 -1
  78. package/dist/public-web-gateway.js +9 -1
  79. package/dist/public-web-gateway.js.map +1 -1
  80. package/dist/search/search-index.d.ts +10 -2
  81. package/dist/search/search-index.js +17 -4
  82. package/dist/search/search-index.js.map +1 -1
  83. package/dist/service-installer.d.ts +23 -1
  84. package/dist/service-installer.js +40 -11
  85. package/dist/service-installer.js.map +1 -1
  86. package/dist/session-oom-stop.d.ts +45 -0
  87. package/dist/session-oom-stop.js +259 -0
  88. package/dist/session-oom-stop.js.map +1 -0
  89. package/dist/session-oom.d.ts +13 -0
  90. package/dist/session-oom.js +119 -7
  91. package/dist/session-oom.js.map +1 -1
  92. package/dist/settings-api.d.ts +27 -1
  93. package/dist/settings-api.js +108 -2
  94. package/dist/settings-api.js.map +1 -1
  95. package/dist/settings-change.js +37 -3
  96. package/dist/settings-change.js.map +1 -1
  97. package/dist/settings-effect.js +5 -2
  98. package/dist/settings-effect.js.map +1 -1
  99. package/dist/spawn-gate.d.ts +2 -0
  100. package/dist/spawn-gate.js +17 -4
  101. package/dist/spawn-gate.js.map +1 -1
  102. package/dist/start-attempt.d.ts +15 -1
  103. package/dist/start-attempt.js +35 -5
  104. package/dist/start-attempt.js.map +1 -1
  105. package/dist/start-failure-chat.d.ts +41 -0
  106. package/dist/start-failure-chat.js +159 -0
  107. package/dist/start-failure-chat.js.map +1 -0
  108. package/dist/start-failure-notice.d.ts +4 -0
  109. package/dist/start-failure-notice.js +8 -0
  110. package/dist/start-failure-notice.js.map +1 -1
  111. package/dist/start-failure.d.ts +49 -0
  112. package/dist/start-failure.js +141 -1
  113. package/dist/start-failure.js.map +1 -1
  114. package/dist/telegram-api-root.d.ts +1 -0
  115. package/dist/telegram-api-root.js +40 -0
  116. package/dist/telegram-api-root.js.map +1 -0
  117. package/dist/turn-reply-guard.d.ts +25 -0
  118. package/dist/turn-reply-guard.js +111 -12
  119. package/dist/turn-reply-guard.js.map +1 -1
  120. package/dist/types.d.ts +21 -3
  121. package/dist/ui/backend-signin.js +5 -2
  122. package/dist/ui/chat-ambient.js +1 -1
  123. package/dist/ui/chat-effects.js +4 -4
  124. package/dist/ui/chat-render.js +5 -2
  125. package/dist/ui/chat-strings.js +2 -2
  126. package/dist/ui/chat-thread.js +2 -2
  127. package/dist/ui/first-run.js +2 -2
  128. package/dist/ui/fleet-canvas-view.js +114 -0
  129. package/dist/ui/fleet-canvas.js +15 -77
  130. package/dist/ui/fleet-office-editor.js +80 -5
  131. package/dist/ui/fleet-office-layout.js +197 -0
  132. package/dist/ui/fleet-office-model.js +6 -3
  133. package/dist/ui/fleet-office-pack.d.ts +39 -0
  134. package/dist/ui/fleet-office-pack.js +240 -29
  135. package/dist/ui/fleet-office-skin.js +130 -21
  136. package/dist/ui/fleet-office-store.js +75 -4
  137. package/dist/ui/fleet-office-view.js +154 -0
  138. package/dist/ui/fleet-office-zones.js +95 -33
  139. package/dist/ui/fleet-office.js +530 -94
  140. package/dist/ui/fleet-usage.js +7 -6
  141. package/dist/ui/panel-chat.js +20 -7
  142. package/dist/ui/panel-details.js +2 -2
  143. package/dist/ui/panel-fleet.js +11 -77
  144. package/dist/ui/panel-log.js +5 -5
  145. package/dist/ui/panel-settings.js +586 -164
  146. package/dist/ui/search-dialog.js +26 -7
  147. package/dist/ui/settings-appearance.js +82 -29
  148. package/dist/ui/settings-apply.js +42 -7
  149. package/dist/ui/settings-dialogs.js +68 -22
  150. package/dist/ui/settings-draft.js +51 -0
  151. package/dist/ui/settings-guests.js +244 -78
  152. package/dist/ui/settings-learn.js +2 -2
  153. package/dist/ui/settings-model.js +2 -0
  154. package/dist/ui/settings-registry.js +142 -0
  155. package/dist/ui/settings-strings.js +108 -44
  156. package/dist/ui/settings-web-authority.js +34 -23
  157. package/dist/ui/shared/app-i18n.js +14 -0
  158. package/dist/ui/shared/app-nav.js +10 -5
  159. package/dist/ui/shared/app-prefs.js +80 -2
  160. package/dist/ui/shared/app-route.js +39 -5
  161. package/dist/ui/shared/app-shell.js +80 -8
  162. package/dist/ui/shared/app-stream.js +2 -1
  163. package/dist/ui/shared/app.css +251 -20
  164. package/dist/ui/shared/app.js +3 -0
  165. package/dist/ui/shared/effect-stock-trust.js +1 -1
  166. package/dist/ui/shared/identity-color.js +4 -4
  167. package/dist/ui/shared/signin.js +2 -2
  168. package/dist/ui/shared/ui-dialog.js +6 -1
  169. package/dist/ui/shared/ui-icons.js +2 -0
  170. package/dist/ui/shared/usage-dialog.js +21 -11
  171. package/dist/ui/shared/view-strings.js +2 -0
  172. package/dist/ui/shared/web-authorize.js +13 -12
  173. package/dist/web-api.d.ts +9 -3
  174. package/dist/web-api.js +161 -6
  175. package/dist/web-api.js.map +1 -1
  176. package/dist/web-auth.js +7 -1
  177. package/dist/web-auth.js.map +1 -1
  178. package/dist/web-experimental.d.ts +1 -1
  179. package/dist/web-experimental.js +1 -1
  180. package/dist/web-experimental.js.map +1 -1
  181. package/dist/web-mod-agent.js +2 -2
  182. package/dist/web-mod-agent.js.map +1 -1
  183. package/dist/web-office-skins.d.ts +108 -0
  184. package/dist/web-office-skins.js +298 -0
  185. package/dist/web-office-skins.js.map +1 -0
  186. package/dist/web-office-store.d.ts +8 -2
  187. package/dist/web-office-store.js +37 -7
  188. package/dist/web-office-store.js.map +1 -1
  189. package/dist/web-settings-patch.d.ts +6 -0
  190. package/dist/web-settings-patch.js +61 -4
  191. package/dist/web-settings-patch.js.map +1 -1
  192. package/dist/web-shell-routes.d.ts +4 -2
  193. package/dist/web-shell-routes.js +17 -7
  194. package/dist/web-shell-routes.js.map +1 -1
  195. package/dist/working-recovery.d.ts +104 -0
  196. package/dist/working-recovery.js +263 -0
  197. package/dist/working-recovery.js.map +1 -0
  198. package/dist/working-state-journal.d.ts +70 -0
  199. package/dist/working-state-journal.js +106 -0
  200. package/dist/working-state-journal.js.map +1 -0
  201. package/package.json +1 -1
@@ -2,6 +2,32 @@
2
2
  import { execFile } from "./child-process.js";
3
3
  import { readFile, readlink } from "node:fs/promises";
4
4
  import { basename } from "node:path";
5
+ import { t } from "./locale.js";
6
+ /** Positive dominance proof only. A selected victim is not necessarily the allocator. */
7
+ function validOomEvidence(value) {
8
+ const e = value;
9
+ if (!e || e.policy !== 2 || e.scope !== "global"
10
+ || ![e.ramPages, e.victimRssPages, e.victimAnonKiB, e.victimTotalRssKiB, e.largestOtherRssPages]
11
+ .every(n => Number.isSafeInteger(n) && n >= 0)
12
+ || !e.ramPages || !e.victimRssPages || !e.victimTotalRssKiB
13
+ || e.victimRssPages > e.ramPages || e.victimAnonKiB > e.victimTotalRssKiB)
14
+ return false;
15
+ const pageKiB = e.victimTotalRssKiB / e.victimRssPages;
16
+ return [4, 16, 64].some(unit => Math.abs(pageKiB - unit) <= unit * 0.05);
17
+ }
18
+ export function selfOomEvidence(value) {
19
+ if (!validOomEvidence(value))
20
+ return false;
21
+ const e = value;
22
+ // Both table and RAM use pages. Scaling by the kill-line anonymous fraction
23
+ // avoids assuming 4-KiB pages on arm64, or mistaking file RSS for anon RSS.
24
+ const anonPages = e.victimRssPages * (e.victimAnonKiB / e.victimTotalRssKiB);
25
+ return anonPages >= e.ramPages / 2 && anonPages >= 2 * e.largestOtherRssPages;
26
+ }
27
+ export function describeSelfOom(e) {
28
+ const anonPages = e.victimRssPages * (e.victimAnonKiB / e.victimTotalRssKiB);
29
+ return t("inst.session_oom_proof", Math.floor(100 * anonPages / e.ramPages), e.largestOtherRssPages ? (anonPages / e.largestOtherRssPages).toFixed(1) : "∞");
30
+ }
5
31
  const MAX_PROC_BYTES = 16_384;
6
32
  const LAUNCHERS = new Set(["bash", "dash", "sh", "zsh", "fish", "env", "busybox"]);
7
33
  async function text(path) {
@@ -76,19 +102,102 @@ export async function observeCliOomIdentity(panePid, binaryName, proc = "/proc")
76
102
  }
77
103
  export function parseKernelOoms(output) {
78
104
  const records = [];
105
+ let beganAt = 0, ramPages = 0, table = false, header = null, invalid = false;
106
+ let tasks = new Map();
107
+ let context = "";
108
+ const reset = () => { beganAt = ramPages = 0; table = invalid = false; header = null; tasks = new Map(); context = ""; };
79
109
  for (const line of output.split("\n")) {
80
110
  if (!line.trim())
81
111
  continue;
82
112
  try {
83
113
  const row = JSON.parse(line);
84
- if (row._TRANSPORT !== "kernel" || typeof row.MESSAGE !== "string")
114
+ if (row._TRANSPORT !== "kernel")
115
+ continue;
116
+ if (typeof row.MESSAGE !== "string") {
117
+ invalid = true;
85
118
  continue;
86
- const victim = /(?:Out of memory|Memory cgroup out of memory): Killed process (\d+) \(([^)]+)\)/.exec(row.MESSAGE);
119
+ }
87
120
  const at = Number(row.__REALTIME_TIMESTAMP) / 1000;
88
- if (victim && Number.isFinite(at) && at > 0)
89
- records.push({ pid: Number(victim[1]), comm: victim[2], at });
121
+ if (!Number.isFinite(at) || at <= 0) {
122
+ reset();
123
+ continue;
124
+ }
125
+ const msg = row.MESSAGE;
126
+ if (msg.includes("invoked oom-killer:")) {
127
+ reset();
128
+ beganAt = at;
129
+ }
130
+ const ram = /^\s*(\d+) pages RAM\s*$/.exec(msg);
131
+ if (ram) {
132
+ if (ramPages && ramPages !== Number(ram[1]))
133
+ invalid = true;
134
+ ramPages = Number(ram[1]);
135
+ }
136
+ if (msg === "Tasks state (memory values in pages):") {
137
+ if (table)
138
+ invalid = true;
139
+ table = true;
140
+ }
141
+ // Linux 6.8 added per-kind RSS columns. Match the declared layout before
142
+ // reading rows; unknown/reordered columns must not hide a larger task.
143
+ if (/^\[\s*pid\s*\]/.test(msg)) {
144
+ const columns = /^\[\s*pid\s*\]\s+uid\s+tgid\s+total_vm\s+rss\s+(rss_anon\s+rss_file\s+rss_shmem\s+)?pgtables_bytes\s+swapents\s+oom_score_adj\s+name\s*$/.exec(msg);
145
+ if (!table || header || !columns)
146
+ invalid = true;
147
+ else
148
+ header = columns[1] ? "rss-columns" : "legacy";
149
+ }
150
+ if (table && /^\[\s*\d/.test(msg)) {
151
+ // comm is the rest of the line, not a word (e.g. "tmux: server").
152
+ const task = (header === "rss-columns"
153
+ ? /^\[\s*(\d+)\]\s+\d+\s+\d+\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+-?\d+\s+(.+?)\s*$/
154
+ : /^\[\s*(\d+)\]\s+\d+\s+\d+\s+\d+\s+(\d+)\s+\d+\s+\d+\s+-?\d+\s+(.+?)\s*$/).exec(msg);
155
+ if (!header || !task)
156
+ invalid = true;
157
+ else {
158
+ const pid = Number(task[1]), rss = Number(task[2]), comm = task[3];
159
+ const old = tasks.get(pid);
160
+ if (old && (old.rss !== rss || old.comm !== comm))
161
+ invalid = true;
162
+ if (!Number.isSafeInteger(rss) || (!old && tasks.size >= 4096))
163
+ invalid = true;
164
+ else
165
+ tasks.set(pid, { rss, comm });
166
+ }
167
+ }
168
+ if (msg.startsWith("oom-kill:")) {
169
+ if (context)
170
+ invalid = true;
171
+ context = msg;
172
+ }
173
+ const victim = /^(Out of memory|Memory cgroup out of memory): Killed process (\d+) \(([^)]+)\)/.exec(msg);
174
+ if (!victim)
175
+ continue;
176
+ const pid = Number(victim[2]), comm = victim[3];
177
+ const record = { pid, comm, at, attribution: "unknown" };
178
+ const own = tasks.get(pid);
179
+ const rss = /anon-rss:(\d+)kB, file-rss:(\d+)kB, shmem-rss:(\d+)kB/.exec(msg);
180
+ // Only one complete, unconstrained report. Shared fleet/container memcg
181
+ // exhaustion cannot identify an individual instance as the cause.
182
+ if (beganAt && at >= beganAt && at - beganAt <= 10_000 && !invalid && ramPages && table && header && own?.comm === comm && rss
183
+ && context.startsWith("oom-kill:constraint=CONSTRAINT_NONE,") && context.includes(",global_oom,")
184
+ && context.includes(`,task=${comm},pid=${pid},`) && victim[1] === "Out of memory") {
185
+ const evidence = { policy: 2, scope: "global", ramPages, victimRssPages: own.rss,
186
+ victimAnonKiB: Number(rss[1]), victimTotalRssKiB: Number(rss[1]) + Number(rss[2]) + Number(rss[3]),
187
+ largestOtherRssPages: Math.max(0, ...[...tasks].filter(([other]) => other !== pid).map(([, task]) => task.rss)) };
188
+ if (validOomEvidence(evidence) && evidence.largestOtherRssPages >= 2 * own.rss)
189
+ record.attribution = "collateral";
190
+ if (selfOomEvidence(evidence)) {
191
+ record.attribution = "self";
192
+ record.evidence = evidence;
193
+ }
194
+ }
195
+ records.push(record);
196
+ reset();
197
+ }
198
+ catch {
199
+ invalid = true; /* a lost task row may hide the actual hog */
90
200
  }
91
- catch { /* unreadable or incomplete evidence is not proof */ }
92
201
  }
93
202
  return records;
94
203
  }
@@ -98,9 +207,12 @@ function recentKernelOoms() {
98
207
  if (pending)
99
208
  return pending;
100
209
  pending = new Promise(resolve => {
210
+ // Project away optional machine/host metadata (journal cursors stay).
211
+ // Leave room for all 4096 task rows
212
+ // plus the report's stack/Mem-Info and other recent kernel messages.
101
213
  try {
102
- execFile("journalctl", ["--kernel", "--boot=0", "--since=-5min", "--no-pager", "--output=json", "--lines=256",
103
- "--grep=(Out of memory|Memory cgroup out of memory): Killed process"], { encoding: "utf8", timeout: 1000, maxBuffer: 256 * 1024, killSignal: "SIGKILL" }, (error, stdout) => resolve(error ? null : parseKernelOoms(stdout)));
214
+ execFile("journalctl", ["--kernel", "--boot=0", "--since=-5min", "--no-pager", "--output=json",
215
+ "--output-fields=MESSAGE,_TRANSPORT,__REALTIME_TIMESTAMP", "--lines=8192"], { encoding: "utf8", timeout: 1000, maxBuffer: 8 * 1024 * 1024, killSignal: "SIGKILL" }, (error, stdout) => resolve(error ? null : parseKernelOoms(stdout)));
104
216
  }
105
217
  catch {
106
218
  resolve(null);
@@ -1 +1 @@
1
- {"version":3,"file":"session-oom.js","sourceRoot":"","sources":["../src/session-oom.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-oom.js","sourceRoot":"","sources":["../src/session-oom.ts"],"names":[],"mappings":"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"}
@@ -49,6 +49,27 @@ export interface SettingsApiContext extends AppShellContext {
49
49
  count: number;
50
50
  durable: boolean;
51
51
  };
52
+ /** #2348 delta §5: one audit entry per person whose granted agents changed with a save (event log, the Log tab). */
53
+ noteGuestGrantChange?(change: {
54
+ by: string | null;
55
+ via: "direct" | "confirmed";
56
+ account: string;
57
+ added: string[];
58
+ removed: string[];
59
+ endedSessions: number;
60
+ }): void;
61
+ /** #2348: the people AgEnD has seen in chat (the Guests picker), never a fleet admin or a bot. */
62
+ guestPeople?(): unknown;
63
+ /** #2348: why an account may not be granted (not seen in chat, a fleet admin, an unknown connection), or null. */
64
+ guestGrantRefusal?(adapterId: string, userId: string): string | null;
65
+ /** #2348: an admin's "Send sign-in code": DM only; the outcome as the Settings card shows it. */
66
+ sendGuestCodeByAdmin?(owner: {
67
+ adapterId: string;
68
+ userId: string;
69
+ }, by: string, current?: () => boolean): Promise<{
70
+ status: number;
71
+ body: Record<string, unknown>;
72
+ }>;
52
73
  /** #1939 S2a: Settings → Web → Web authority — what is in force, the actions to pick from, and the revocation. */
53
74
  webAuthorityOverview?(): unknown;
54
75
  revokeWebAuthority?(): {
@@ -75,7 +96,7 @@ export interface SettingsApiContext extends AppShellContext {
75
96
  * and team places dropped, its fleet.yaml entry removed. Absent in unit contexts that only exercise CRUD. */
76
97
  removeInstance?(name: string, authorization: ExplicitInstanceRemoval, execution?: SettingsExecution): Promise<void>;
77
98
  /** Phase 2b: an operator wake that respects the warm hard cap (FleetManager.explicitWake). */
78
- explicitWake?(name: string, timeoutMs?: number): Promise<void>;
99
+ explicitWake?(name: string, timeoutMs?: number, retryStoppedSession?: boolean): Promise<void>;
79
100
  restartClassicInstanceFromSettings?(instanceName: string, changedFields?: string[], execution?: SettingsExecution): Promise<void>;
80
101
  captureClassicSettingsRestoration?(instanceName: string, changedFields: string[], execution?: SettingsExecution): () => Promise<void>;
81
102
  /** Present on a real fleet; absent in unit contexts that only exercise CRUD. */
@@ -90,6 +111,11 @@ export interface SettingsApiContext extends AppShellContext {
90
111
  /** Non-null when the running config and fleet.yaml disagree on a
91
112
  * startup-only key, in which case a restart cannot clear the fleet row. */
92
113
  fleetSignatureMismatchKeys?(): string[] | null;
114
+ /** #2347: saved changes waiting for an AgEnD restart, and the apply job a restart can be asked for. */
115
+ settingsRestartPending?(): {
116
+ keys: string[];
117
+ job_id: string | null;
118
+ } | null;
93
119
  /** #2346: whether a connection added now starts at once (another one is running), or needs AgEnD restarted. */
94
120
  connectionsStartLive?(): boolean;
95
121
  /** #1005/#1021: a Discord connection's server emojis, from each server its
@@ -1,7 +1,7 @@
1
1
  import { PUBLIC_TUNNEL_SECRET_ID, PUBLIC_TUNNEL_TOKEN_HINT } from "./public-tunnel-config.js";
2
2
  import { withSpawnHoldReply } from "./spawn-hold-reply.js";
3
3
  import { normalizeSettingsInstancePatch, removesInstanceOverride } from "./settings-instance-patch.js";
4
- import { settingsRequestExecution, settingsRequestLocalAdmin, settingsWrite } from "./settings-request-capability.js";
4
+ import { isSettingsReplay, settingsRequestExecution, settingsRequestLocalAdmin, settingsWrite } from "./settings-request-capability.js";
5
5
  import { noteSettingsWrite, settingsUndo, undoSettingsPaths } from "./settings-transaction.js";
6
6
  import { readBoundedWebBody } from "./web-body.js";
7
7
  import { gatewayRequestContext } from "./web-request-context.js";
@@ -210,6 +210,12 @@ export function handleSettingsRequest(req, res, url, ctx) {
210
210
  });
211
211
  return true;
212
212
  }
213
+ // #2347: what the app-wide "Restart now" banner reads — small, so every page can ask after a Save settles.
214
+ if (method === "GET" && path === "/api/settings/restart-pending") {
215
+ const pending = ctx.settingsRestartPending?.() ?? null;
216
+ json(res, 200, pending ? { pending: true, keys: pending.keys, job_id: pending.job_id } : { pending: false });
217
+ return true;
218
+ }
213
219
  if (method === "GET" && path === "/api/settings/fleet") {
214
220
  json(res, 200, redactInlineSecrets(ctx.fleetConfig ?? {}));
215
221
  return true;
@@ -703,7 +709,7 @@ export function handleSettingsRequest(req, res, url, ctx) {
703
709
  let held = false;
704
710
  const operation = withSpawnHoldReply(async (message) => { held = true; json(res, 202, { ok: true, held: true, message, name }); }, () => action === "pause"
705
711
  ? ctx.lifecycle.pause(name)
706
- : ctx.explicitWake ? ctx.explicitWake(name, 30_000) : ctx.lifecycle.wake(name, 30_000));
712
+ : ctx.explicitWake ? ctx.explicitWake(name, 30_000, true) : ctx.lifecycle.wake(name, 30_000));
707
713
  operation.then(() => { if (!held)
708
714
  json(res, 200, { ok: true, name, status: action === "pause" ? "paused" : "running" }); })
709
715
  .catch(err => { if (!held)
@@ -727,6 +733,60 @@ export function handleSettingsRequest(req, res, url, ctx) {
727
733
  json(res, 200, ctx.guestOverview());
728
734
  return true;
729
735
  }
736
+ // #2348: the picker's people (GET) and an admin's "Send sign-in code" (POST: a DM to an applied grant's account, once
737
+ // a minute per account — a code is not a settings change: the grant it needs was already confirmed). Never over the
738
+ // public link; the caller asked again after the body, as the sign-out below.
739
+ if (path === "/api/settings/guests/people" && method === "GET") {
740
+ if (gatewayRequestContext(req)) {
741
+ json(res, 403, { error: "guest_settings_not_over_public_link" });
742
+ return true;
743
+ }
744
+ if (!ctx.guestPeople) {
745
+ json(res, 404, { error: "not available" });
746
+ return true;
747
+ }
748
+ if (!guestSettingsCaller(req, url, ctx)) {
749
+ json(res, 401, { error: "not authorized" });
750
+ return true;
751
+ }
752
+ res.setHeader("Cache-Control", "no-store");
753
+ json(res, 200, ctx.guestPeople());
754
+ return true;
755
+ }
756
+ if (path === "/api/settings/guests/send-code" && method === "POST") {
757
+ if (gatewayRequestContext(req)) {
758
+ json(res, 403, { error: "guest_settings_not_over_public_link" });
759
+ return true;
760
+ }
761
+ if (!ctx.sendGuestCodeByAdmin) {
762
+ json(res, 404, { error: "not available" });
763
+ return true;
764
+ }
765
+ const caller = guestSettingsCaller(req, url, ctx);
766
+ if (!caller) {
767
+ json(res, 401, { error: "not authorized" });
768
+ return true;
769
+ }
770
+ readBody(req, 4096).then(async (buf) => {
771
+ if (!permitWebContinuation(req, res, ctx))
772
+ return;
773
+ if (guestSettingsCaller(req, url, ctx) !== caller)
774
+ return json(res, 401, { error: "no longer authorized" });
775
+ let body;
776
+ try {
777
+ body = JSON.parse(buf.toString("utf-8"));
778
+ }
779
+ catch {
780
+ return json(res, 400, { error: "invalid JSON" });
781
+ }
782
+ if (typeof body?.adapterId !== "string" || !body.adapterId || typeof body.userId !== "string" || !body.userId)
783
+ return json(res, 400, { error: "adapterId and userId required" });
784
+ // #2365 review: the initiating admin's session, asked again after every wait inside the issuance.
785
+ const out = await ctx.sendGuestCodeByAdmin({ adapterId: body.adapterId, userId: body.userId }, caller, () => guestSettingsCaller(req, url, ctx) === caller);
786
+ json(res, out.status, out.body);
787
+ }).catch(() => json(res, 400, { error: "bad request" }));
788
+ return true;
789
+ }
730
790
  if (path === "/api/settings/guests/revoke" && method === "POST") {
731
791
  if (gatewayRequestContext(req)) {
732
792
  json(res, 403, { error: "guest_settings_not_over_public_link" });
@@ -835,6 +895,9 @@ export function handleSettingsRequest(req, res, url, ctx) {
835
895
  }
836
896
  }
837
897
  const { session: sessionPatch, terminal: terminalPatch } = parsed;
898
+ // #2499 review: who is saving, asked now, before the save — a session policy saved with it can end this very session
899
+ // (a shorter sign-in time), and the audit must still name who did it. A confirmation's replay is no one's: null.
900
+ const auditBy = parsed.guests?.grants !== undefined && !isSettingsReplay(req) ? guestSettingsCaller(req, url, ctx) : null;
838
901
  const changes = [];
839
902
  const web = { ...cfg.web };
840
903
  let webTerminal = cfg.web_terminal;
@@ -890,6 +953,16 @@ export function handleSettingsRequest(req, res, url, ctx) {
890
953
  }
891
954
  // #1920 phase 3: guest sign-in (Settings → Web sign-ins → Guests); widening it is confirmed (settings-change.ts).
892
955
  if (parsed.guests) {
956
+ // #2348: a new grant names someone AgEnD has seen in chat, on a connection of this fleet, who is not a fleet admin
957
+ // (admins sign in as admins). One already granted may be edited or removed whatever the list says now.
958
+ for (const [key, grant] of Object.entries(parsed.guests.grants ?? {})) {
959
+ if (grant === null || (cfg.web?.guests?.grants && Object.hasOwn(cfg.web.guests.grants, key)))
960
+ continue;
961
+ const at = key.indexOf(":");
962
+ const refused = ctx.guestGrantRefusal ? ctx.guestGrantRefusal(key.slice(0, at), key.slice(at + 1)) : "guest grants are not available";
963
+ if (refused)
964
+ return json(res, 400, { error: refused, key: "guest_grant_refused", account: key });
965
+ }
893
966
  const applied = applyGuestsPatch(cfg.web?.guests, parsed.guests);
894
967
  if (applied.next)
895
968
  web.guests = applied.next;
@@ -934,6 +1007,39 @@ export function handleSettingsRequest(req, res, url, ctx) {
934
1007
  if (parsed.canvasWorker !== undefined && (previous.web?.experimental?.canvas_worker === true) !== parsed.canvasWorker) {
935
1008
  ctx.canvasWorkerSettingChanged?.();
936
1009
  }
1010
+ // #2348: a grant taken away (or emptied) ends that person's guest access now — sessions, an outstanding code, and
1011
+ // remembered browsers — not at their next request. A narrowed grant keeps its sessions; they see less from now on.
1012
+ const ended = new Map();
1013
+ for (const [key, grant] of Object.entries(parsed.guests?.grants ?? {})) {
1014
+ if (grant !== null && grant.instances.length)
1015
+ continue;
1016
+ const at = key.indexOf(":");
1017
+ try {
1018
+ ended.set(key, ctx.revokeGuestWebSessions?.({ adapterId: key.slice(0, at), userId: key.slice(at + 1) })?.count ?? 0);
1019
+ }
1020
+ catch (err) {
1021
+ ctx.logger.warn({ err }, "settings: could not end a removed guest's sessions");
1022
+ }
1023
+ }
1024
+ // #2348 delta §5: every grant change is audited, widening (confirmed in General, replayed here) or narrowing (at
1025
+ // once) alike: who, how, the agents added and taken away. Agent names only; never message content. Shown under
1026
+ // Recent changes in Settings → Guests (guestOverview), never to a guest or over the public link.
1027
+ if (parsed.guests?.grants !== undefined && ctx.noteGuestGrantChange) {
1028
+ const was = previous.web?.guests?.grants ?? {}, now = cfg.web?.guests?.grants ?? {};
1029
+ const by = auditBy, via = isSettingsReplay(req) ? "confirmed" : "direct";
1030
+ for (const key of new Set([...Object.keys(was), ...Object.keys(now)])) {
1031
+ const a = new Set(Object.hasOwn(was, key) ? was[key].instances : []), b = new Set(Object.hasOwn(now, key) ? now[key].instances : []);
1032
+ const added = [...b].filter((n) => !a.has(n)), removed = [...a].filter((n) => !b.has(n));
1033
+ if (!added.length && !removed.length)
1034
+ continue;
1035
+ try {
1036
+ ctx.noteGuestGrantChange({ by, via, account: key, added, removed, endedSessions: ended.get(key) ?? 0 });
1037
+ }
1038
+ catch (err) {
1039
+ ctx.logger.warn({ err }, "settings: could not audit a guest grant change");
1040
+ }
1041
+ }
1042
+ }
937
1043
  json(res, 200, { ok: true, warnings: saveWarnings(before, after) });
938
1044
  }).catch(() => json(res, 400, { error: "bad request" }));
939
1045
  return true;