@songsid/agend 2.3.0-beta.12 → 2.3.0-beta.13

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 (82) hide show
  1. package/README.md +6 -0
  2. package/README.zh-TW.md +6 -0
  3. package/dist/config.d.ts +12 -0
  4. package/dist/config.js +13 -4
  5. package/dist/config.js.map +1 -1
  6. package/dist/fleet-manager.d.ts +36 -1
  7. package/dist/fleet-manager.js +128 -30
  8. package/dist/fleet-manager.js.map +1 -1
  9. package/dist/general-knowledge/skills/fleet-config/SKILL.md +2 -0
  10. package/dist/general-knowledge/skills/web-appearance/SKILL.md +20 -3
  11. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +23 -5
  12. package/dist/outbound-schemas.d.ts +14 -1
  13. package/dist/outbound-schemas.js +8 -2
  14. package/dist/outbound-schemas.js.map +1 -1
  15. package/dist/public-web-gateway.js +4 -0
  16. package/dist/public-web-gateway.js.map +1 -1
  17. package/dist/restart-progress.d.ts +16 -1
  18. package/dist/restart-progress.js +74 -15
  19. package/dist/restart-progress.js.map +1 -1
  20. package/dist/settings-api.js +4 -1
  21. package/dist/settings-api.js.map +1 -1
  22. package/dist/settings-confirmation.d.ts +3 -1
  23. package/dist/settings-confirmation.js +2 -0
  24. package/dist/settings-confirmation.js.map +1 -1
  25. package/dist/settings-effect.js +2 -1
  26. package/dist/settings-effect.js.map +1 -1
  27. package/dist/settings-http-confirmation.d.ts +11 -0
  28. package/dist/settings-http-confirmation.js +10 -0
  29. package/dist/settings-http-confirmation.js.map +1 -1
  30. package/dist/ui/chat-effects.js +10 -3
  31. package/dist/ui/chat-strings.js +2 -0
  32. package/dist/ui/effects-waker.js +70 -0
  33. package/dist/ui/fleet-canvas-layout.js +10 -4
  34. package/dist/ui/fleet-canvas.js +32 -2
  35. package/dist/ui/fleet-route-scene.js +207 -0
  36. package/dist/ui/fleet-route-worker.js +21 -0
  37. package/dist/ui/fleet-route.js +88 -0
  38. package/dist/ui/fleet-traffic.js +27 -11
  39. package/dist/ui/fleet-usage.js +35 -1
  40. package/dist/ui/panel-chat.js +43 -23
  41. package/dist/ui/panel-fleet.js +3 -3
  42. package/dist/ui/settings-appearance.js +2 -1
  43. package/dist/ui/settings-apply.js +3 -3
  44. package/dist/ui/settings-confirm.js +7 -2
  45. package/dist/ui/settings-owner-effects.js +6 -4
  46. package/dist/ui/shared/app-i18n.js +4 -0
  47. package/dist/ui/shared/app-prefs.js +12 -0
  48. package/dist/ui/shared/app-shell.js +38 -2
  49. package/dist/ui/shared/app-themes.js +116 -1
  50. package/dist/ui/shared/app.css +47 -3
  51. package/dist/ui/shared/card-strings.js +4 -0
  52. package/dist/ui/shared/identity-card.js +24 -6
  53. package/dist/ui/shared/identity-color.js +11 -7
  54. package/dist/ui/shared/ui-icons.js +2 -0
  55. package/dist/ui/shared/ui-menu.js +9 -3
  56. package/dist/ui/shared/web-authorize.js +47 -0
  57. package/dist/web-api.js +18 -1
  58. package/dist/web-api.js.map +1 -1
  59. package/dist/web-appearance.js +3 -1
  60. package/dist/web-appearance.js.map +1 -1
  61. package/dist/web-effect.d.ts +1 -1
  62. package/dist/web-host-guard.d.ts +11 -0
  63. package/dist/web-host-guard.js +11 -0
  64. package/dist/web-host-guard.js.map +1 -1
  65. package/dist/web-libavoid.d.ts +14 -0
  66. package/dist/web-libavoid.js +46 -0
  67. package/dist/web-libavoid.js.map +1 -0
  68. package/dist/web-owner-css-store.d.ts +3 -2
  69. package/dist/web-owner-css-store.js +9 -4
  70. package/dist/web-owner-css-store.js.map +1 -1
  71. package/dist/web-prefs.js +13 -0
  72. package/dist/web-prefs.js.map +1 -1
  73. package/dist/web-settings-tools.d.ts +5 -0
  74. package/dist/web-settings-tools.js +34 -6
  75. package/dist/web-settings-tools.js.map +1 -1
  76. package/dist/web-theme.d.ts +29 -0
  77. package/dist/web-theme.js +89 -1
  78. package/dist/web-theme.js.map +1 -1
  79. package/dist/yaml-shared-nodes.d.ts +25 -0
  80. package/dist/yaml-shared-nodes.js +185 -0
  81. package/dist/yaml-shared-nodes.js.map +1 -0
  82. package/package.json +2 -1
package/README.md CHANGED
@@ -112,6 +112,12 @@ One-liner (macOS / Linux — installs Node.js via nvm + tmux + agend, then runs
112
112
  curl -fsSL https://songsid.github.io/AgEnD/install.sh | bash
113
113
  ```
114
114
 
115
+ One-liner (Windows — in PowerShell; sets up WSL 2 + Ubuntu, your AI backend and AgEnD inside it, then your bot. It asks once for Administrator approval; after a restart, run the same line again and it resumes. See the [Windows installation guide](https://songsid.github.io/AgEnD/install-windows/)):
116
+
117
+ ```powershell
118
+ powershell -ExecutionPolicy ByPass -c "irm https://songsid.github.io/AgEnD/install.ps1 | iex"
119
+ ```
120
+
115
121
  Or install manually:
116
122
 
117
123
  ```bash
package/README.zh-TW.md CHANGED
@@ -112,6 +112,12 @@ AgEnD 是住在 Discord、Telegram 和你的瀏覽器裡的 AI 個人助理,
112
112
  curl -fsSL https://songsid.github.io/AgEnD/install.sh | bash
113
113
  ```
114
114
 
115
+ 一行安裝(Windows — 在 PowerShell 執行;裝好 WSL 2 + Ubuntu,在裡面裝 AI 後端和 AgEnD,再串接 bot。會詢問一次系統管理員權限;重新開機後再執行同一行即可接續。詳見 [Windows 安裝指南](https://songsid.github.io/AgEnD/zh-tw/install-windows/)):
116
+
117
+ ```powershell
118
+ powershell -ExecutionPolicy ByPass -c "irm https://songsid.github.io/AgEnD/install.ps1 | iex"
119
+ ```
120
+
115
121
  或手動安裝:
116
122
 
117
123
  ```bash
package/dist/config.d.ts CHANGED
@@ -16,6 +16,18 @@ export declare const DEFAULT_INSTANCE_CONFIG: Omit<InstanceConfig, "working_dire
16
16
  export declare function getEffectiveInstanceDefaults(fleetDefaults?: Partial<InstanceConfig>): Partial<InstanceConfig>;
17
17
  /** Validate IANA timezone string. Throws if invalid. */
18
18
  export declare function validateTimezone(tz: string, field: string): void;
19
+ /**
20
+ * A connection as a load gives it: `id` defaults to its `type`, `mode` to `topic`. Every channels write is judged and
21
+ * kept in this shape too (#2211), so a key the file leaves to its default is never "changed" by being absent.
22
+ */
23
+ export declare function channelWithDefaults<T extends {
24
+ id?: string;
25
+ type?: string;
26
+ mode?: string;
27
+ }>(ch: T): T & {
28
+ id: string | undefined;
29
+ mode: NonNullable<T["mode"]> | "topic";
30
+ };
19
31
  export declare function loadFleetConfig(configPath: string): FleetConfig;
20
32
  /** Read the user-authored config without applying defaults or normalization. */
21
33
  export declare function loadRawFleetConfig(configPath: string): RawFleetConfig;
package/dist/config.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { readFileSync, existsSync, mkdirSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import yaml from "js-yaml";
4
+ import { unshareParsed } from "./yaml-shared-nodes.js";
4
5
  import { getAgendHome, getTmuxSessionName, ensureWorkspaceGit } from "./paths.js";
5
6
  export function deepMergeGeneric(target, source) {
6
7
  const result = { ...target };
@@ -88,6 +89,13 @@ export function validateTimezone(tz, field) {
88
89
  throw new Error(`${field}: invalid timezone "${tz}". Use IANA format (e.g. Asia/Taipei)`);
89
90
  }
90
91
  }
92
+ /**
93
+ * A connection as a load gives it: `id` defaults to its `type`, `mode` to `topic`. Every channels write is judged and
94
+ * kept in this shape too (#2211), so a key the file leaves to its default is never "changed" by being absent.
95
+ */
96
+ export function channelWithDefaults(ch) {
97
+ return { ...ch, id: ch.id ?? ch.type, mode: ch.mode ?? "topic" };
98
+ }
91
99
  export function loadFleetConfig(configPath) {
92
100
  if (!existsSync(configPath)) {
93
101
  return { defaults: {}, instances: {} };
@@ -96,7 +104,8 @@ export function loadFleetConfig(configPath) {
96
104
  // Quote bare 16+ digit integers before parsing to prevent precision loss.
97
105
  // Discord snowflakes and Telegram group IDs are 64-bit and exceed JS MAX_SAFE_INTEGER.
98
106
  const safeRaw = raw.replace(/(?<=:\s+|[-]\s+)(\d{16,})(?=\s*$)/gm, (_, d) => `"${d}"`);
99
- const parsed = yaml.load(safeRaw);
107
+ // #2208: an anchor and its aliases become separate copies, so editing one place never changes another.
108
+ const parsed = unshareParsed(yaml.load(safeRaw), "fleet.yaml");
100
109
  if (!parsed) {
101
110
  return { defaults: {}, instances: {} };
102
111
  }
@@ -125,10 +134,10 @@ export function loadFleetConfig(configPath) {
125
134
  }
126
135
  // Normalize channel → channels (backward compat: single channel auto-wraps into array)
127
136
  const channelSingle = parsed.channel
128
- ? { ...parsed.channel, id: parsed.channel.id ?? parsed.channel.type, mode: parsed.channel.mode ?? "topic" }
137
+ ? channelWithDefaults(parsed.channel)
129
138
  : undefined;
130
139
  const channels = parsed.channels
131
- ? parsed.channels.map(ch => ({ ...ch, id: ch.id ?? ch.type, mode: ch.mode ?? "topic" }))
140
+ ? parsed.channels.map(ch => channelWithDefaults(ch))
132
141
  : channelSingle ? [channelSingle] : undefined;
133
142
  // Always set channel to first entry (fallback for code using fleetConfig.channel)
134
143
  const primaryChannel = channelSingle ?? (channels?.[0] ?? undefined);
@@ -230,7 +239,7 @@ export function loadRawFleetConfig(configPath) {
230
239
  const raw = readFileSync(configPath, "utf-8");
231
240
  // Match loadFleetConfig(): preserve platform IDs that exceed MAX_SAFE_INTEGER.
232
241
  const safeRaw = raw.replace(/(?<=:\s+|[-]\s+)(\d{16,})(?=\s*$)/gm, (_, d) => `"${d}"`);
233
- const parsed = yaml.load(safeRaw);
242
+ const parsed = unshareParsed(yaml.load(safeRaw), "fleet.yaml"); // #2208, as loadFleetConfig
234
243
  return parsed && typeof parsed === "object" && !Array.isArray(parsed)
235
244
  ? parsed
236
245
  : {};
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -245,6 +245,8 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
245
245
  fleetConfig: FleetConfig | null;
246
246
  private rawFleetConfig;
247
247
  private rawFleetDocument;
248
+ /** #2208: the paths a saveFleetConfig() wrote, for its check that nothing else changed. */
249
+ private fleetDocumentWrites;
248
250
  private savedFleetConfigSnapshot;
249
251
  adapter: ChannelAdapter | null;
250
252
  readonly worlds: Map<string, AdapterWorld>;
@@ -624,6 +626,30 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
624
626
  private classicSettingsOwners;
625
627
  private queueSettingsOperation;
626
628
  private settingsGate;
629
+ /**
630
+ * #2170: a held change confirmed by the request itself — only when ALL hold, else the chat card or the host CLI, as
631
+ * before:
632
+ * - the session is web-verified (#1939: its account confirmed this browser on Discord or Telegram), asked now;
633
+ * - the change's effect owners are known and on one platform (settingsChatAuthority — the chat card's own rule), the
634
+ * verified account is on that platform and an admin of every one of them;
635
+ * - a chat card could have been asked: a connected General on that platform the change does not affect (else the
636
+ * change goes to the host CLI, as before) — the General that then hears of it;
637
+ * - and, at execution (store.decide asks `current()` again): still web-verified under the same session and account
638
+ * (not expired, revoked, signed out or the switch turned off), still those owners' admin, still a General a card
639
+ * could go to, the fleet unchanged.
640
+ * What it rests on: the account's one confirmation of this browser (#1939), kept for the session until it is revoked,
641
+ * expires or signs out — not a fresh confirmation per Apply. Whoever uses that verified session (a browser left signed
642
+ * in, its cookie) confirms the same way. A public link never qualifies (evaluateWebAuthority refuses it). General
643
+ * still hears it: a notice, not a step.
644
+ */
645
+ private settingsSelfConfirmation;
646
+ /** #2170: the Generals a chat card could be posted in (promptSettingsChange's rule): connected, on the platform, unaffected. */
647
+ private settingsNoticeGenerals;
648
+ /**
649
+ * #2170: General's notice of a change confirmed from the web — the first General a chat card could have been posted
650
+ * in, plain text, no mentions. Information only: nothing waits on it.
651
+ */
652
+ private settingsWebConfirmedNotice;
627
653
  /** Exact configured effect owners; this does not depend on prompt location. */
628
654
  private settingsChatAuthority;
629
655
  private promptSettingsChange;
@@ -1358,7 +1384,10 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
1358
1384
  * snapshot use the fleet startup/retry state. */
1359
1385
  private readyProgressAdapter;
1360
1386
  /** Last-resort completion after RestartProgress could not deliver to its
1361
- * adopted target. It stays bounded and never wakes a not-ready gateway. */
1387
+ * adopted target (or had no message: a small fleet, a failed first post). It
1388
+ * never wakes a not-ready gateway. #2213: an outage at fleet start no longer
1389
+ * loses it — bounded at startup, then retried in the background once the
1390
+ * adapter is ready again, never posted twice after an uncertain attempt. */
1362
1391
  private sendFleetStartCompletionFallback;
1363
1392
  stopInstance(name: string, transition?: TransitionHandle): Promise<{
1364
1393
  backgroundWorkEnded: boolean;
@@ -2133,6 +2162,12 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
2133
2162
  private slimFleetConfigAtStartup;
2134
2163
  private writeFleetConfigBackup;
2135
2164
  private patchFleetDocument;
2165
+ /**
2166
+ * #2208: before every write to the raw document — the place is unshared first (an alias on the way becomes its own
2167
+ * copy; an anchor's other aliases get theirs), so the write changes that place only; and it is recorded for the
2168
+ * save's check that nothing else changed.
2169
+ */
2170
+ private writingFleetDocument;
2136
2171
  getSettingsConfigPath(): string;
2137
2172
  removeInstance(name: string, authorization: ExplicitInstanceRemoval, execution?: SettingsExecution): Promise<void>;
2138
2173
  private removeInstanceOwned;
@@ -38,6 +38,7 @@ import { readFleetMemory } from "./process-memory.js";
38
38
  import { MemoryPressure } from "./memory-pressure.js";
39
39
  import { replyDedupText, ReplyDeduper } from "./reply-dedup.js";
40
40
  import { isMap, isScalar, parseDocument } from "yaml";
41
+ import { changedOutside, detachForWrite } from "./yaml-shared-nodes.js";
41
42
  import { kiroLogGate } from "./kiro-log-gate.js";
42
43
  const __filename = fileURLToPath(import.meta.url);
43
44
  const __dirname = dirname(__filename);
@@ -227,7 +228,7 @@ import { authorizeSession, decideWebGate, loadOrCreateWebToken, readWebToken } f
227
228
  import { bypassesWebGate, handleAuthRequest, serveSigninPage } from "./auth-api.js";
228
229
  import { isWebPageNavigation } from "./web-shell-routes.js";
229
230
  import { guestSessionPolicy, localSessionPolicy, tokenEpoch, WebSessionStore } from "./web-session.js";
230
- import { authorityNow, evaluateWebAuthority, VERIFIED_SESSION_HOURS, webAuthorityPolicy } from "./authority/web-authority.js";
231
+ import { authorityNow, classifyWebPeer, evaluateWebAuthority, VERIFIED_SESSION_HOURS, webAuthorityPolicy } from "./authority/web-authority.js";
231
232
  import { AuthorityStateStore } from "./authority/authority-state.js";
232
233
  import { SessionAuthorizations } from "./authority/session-authorizations.js";
233
234
  import { SessionAuthorizationRequests } from "./web-session-authorization.js";
@@ -250,7 +251,7 @@ import { CHAT_PROFILE_LOGIN_BACKENDS, credentialHomeSpec, credentialProfileHome,
250
251
  import { carryClaudeConversation } from "./backend/claude-carry.js";
251
252
  import { mergeBackendOptions, profileKey, profileName, profileOf } from "./classic-bindings.js";
252
253
  import { classifyInstanceChange, CLASSIC_HOT_CONFIG_KEYS, HOT_INSTANCE_CONFIG_KEYS, hotConfigUpdate, } from "./instance-config-impact.js";
253
- import { cleanupWatchVerdict, formatRestartProgressCompletion, RESTART_PROGRESS_TERMINAL_TIMEOUT_MS, RestartProgress, } from "./restart-progress.js";
254
+ import { cleanupWatchVerdict, formatRestartProgressCompletion, RestartProgress, } from "./restart-progress.js";
254
255
  import { launchFullRestartHelper } from "./full-restart.js";
255
256
  import { SYSTEMD_RESTART_INDETERMINATE_EXIT_CODE } from "./service-restart-selection.js";
256
257
  import { collectRedundantInstanceDefaultPaths } from "./fleet-yaml-slim.js";
@@ -589,6 +590,8 @@ export class FleetManager {
589
590
  fleetConfig = null;
590
591
  rawFleetConfig = {};
591
592
  rawFleetDocument = null;
593
+ /** #2208: the paths a saveFleetConfig() wrote, for its check that nothing else changed. */
594
+ fleetDocumentWrites = null;
592
595
  savedFleetConfigSnapshot = null;
593
596
  adapter = null;
594
597
  worlds = new Map();
@@ -1284,6 +1287,7 @@ export class FleetManager {
1284
1287
  current: () => current() && sessions === this.webSessions && !!this.webToken
1285
1288
  && sessions.isCurrent(record, tokenEpoch(this.webToken)) && (!exposure || exposure.isCurrent()) };
1286
1289
  }, baseline: () => baselines.read(), snapshot: () => baselines.snapshot(),
1290
+ selfConfirm: (req, id) => this.settingsSelfConfirmation(store, req, id),
1287
1291
  job: async (id) => {
1288
1292
  const settlement = this.settingsJobSettlements.get(id);
1289
1293
  if (!settlement)
@@ -1298,6 +1302,86 @@ export class FleetManager {
1298
1302
  this.settingsConfirmation = gate;
1299
1303
  return gate;
1300
1304
  }
1305
+ /**
1306
+ * #2170: a held change confirmed by the request itself — only when ALL hold, else the chat card or the host CLI, as
1307
+ * before:
1308
+ * - the session is web-verified (#1939: its account confirmed this browser on Discord or Telegram), asked now;
1309
+ * - the change's effect owners are known and on one platform (settingsChatAuthority — the chat card's own rule), the
1310
+ * verified account is on that platform and an admin of every one of them;
1311
+ * - a chat card could have been asked: a connected General on that platform the change does not affect (else the
1312
+ * change goes to the host CLI, as before) — the General that then hears of it;
1313
+ * - and, at execution (store.decide asks `current()` again): still web-verified under the same session and account
1314
+ * (not expired, revoked, signed out or the switch turned off), still those owners' admin, still a General a card
1315
+ * could go to, the fleet unchanged.
1316
+ * What it rests on: the account's one confirmation of this browser (#1939), kept for the session until it is revoked,
1317
+ * expires or signs out — not a fresh confirmation per Apply. Whoever uses that verified session (a browser left signed
1318
+ * in, its cookie) confirms the same way. A public link never qualifies (evaluateWebAuthority refuses it). General
1319
+ * still hears it: a notice, not a step.
1320
+ */
1321
+ settingsSelfConfirmation(store, req, id) {
1322
+ const auth = authorizeSession(req, this.webToken, this.webSessions, { touch: false });
1323
+ if (auth.kind !== "ok")
1324
+ return null;
1325
+ const record = auth.session, gateway = !!gatewayRequestContext(req), peer = classifyWebPeer(req);
1326
+ const verified = () => {
1327
+ const now = this.webAuthority({ session: record, gateway, peer });
1328
+ // A refusal carries no authority (kind "none"); the handle pins the session, and with it its one account.
1329
+ return now.authority.kind === "web-verified" && now.authority.actor && now.authority.session?.handle === record.handle ? now.authority.actor : null;
1330
+ };
1331
+ const actor = verified();
1332
+ if (!actor)
1333
+ return null;
1334
+ const chat = this.settingsChatAuthority(store, id);
1335
+ if (!chat)
1336
+ return null;
1337
+ const channels = this.fleetConfig?.channels ?? (this.fleetConfig?.channel ? [this.fleetConfig.channel] : []);
1338
+ const own = channels.filter(ch => (ch.id ?? ch.type) === actor.adapter_id);
1339
+ if (own.length !== 1 || own[0].type !== chat.platform || !chat.admin(actor.user_id))
1340
+ return null;
1341
+ const affected = [...store.affectedConnections(id)]; // read now: a finished change no longer has them
1342
+ if (!this.settingsNoticeGenerals(affected, chat.platform).length)
1343
+ return null;
1344
+ const name = this.webPerson({ adapterId: actor.adapter_id, userId: actor.user_id }).name;
1345
+ return {
1346
+ label: `${name} (web-verified)`,
1347
+ // admin() asks chat.current() too; a General a card could go to must still be there (else the host CLI's).
1348
+ current: () => !!verified() && chat.admin(actor.user_id) && this.settingsNoticeGenerals(affected, chat.platform).length > 0,
1349
+ done: view => this.settingsWebConfirmedNotice(view, affected, name, chat.platform),
1350
+ };
1351
+ }
1352
+ /** #2170: the Generals a chat card could be posted in (promptSettingsChange's rule): connected, on the platform, unaffected. */
1353
+ settingsNoticeGenerals(affected, platform) {
1354
+ const excluded = new Set(affected), found = [];
1355
+ for (const [name, config] of Object.entries(this.fleetConfig?.instances ?? {})) {
1356
+ if (!config.general_topic || !this.daemons.get(name))
1357
+ continue;
1358
+ const adapterId = this.getInstanceAdapterId(name), adapter = this.getAdapterForInstance(name);
1359
+ if (!adapterId || !adapter || excluded.has(adapterId) || adapter.type !== platform || this.adapterState.get(adapterId)?.status !== "connected")
1360
+ continue;
1361
+ const chatId = this.getGroupIdForInstance(name), topic = String(config.topic_id ?? "");
1362
+ if (chatId && topic)
1363
+ found.push({ adapterId, adapter, chatId, topic });
1364
+ }
1365
+ return found;
1366
+ }
1367
+ /**
1368
+ * #2170: General's notice of a change confirmed from the web — the first General a chat card could have been posted
1369
+ * in, plain text, no mentions. Information only: nothing waits on it.
1370
+ */
1371
+ async settingsWebConfirmedNotice(view, affected, who, platform) {
1372
+ const outcome = view.outcome ? view.outcome.message : view.state;
1373
+ const text = `✅ Settings change confirmed from the web by ${who} (web-verified)\nSource: ${view.source}\nRequester: ${view.requested_by}\n${view.summary.join("\n")}\nOutcome: ${outcome}`;
1374
+ for (const { adapterId, adapter, chatId, topic } of this.settingsNoticeGenerals(affected, platform)) {
1375
+ try {
1376
+ await adapter.sendText(chatId, text, { threadId: topic, allowedMentions: { parse: [] } });
1377
+ return;
1378
+ }
1379
+ catch {
1380
+ this.logger.info({ id: view.id, adapterId }, "Settings web-confirmation notice unavailable; trying another General");
1381
+ }
1382
+ }
1383
+ this.logger.info({ id: view.id }, "Settings change confirmed from the web: no General reachable for the notice");
1384
+ }
1301
1385
  /** Exact configured effect owners; this does not depend on prompt location. */
1302
1386
  settingsChatAuthority(store, id) {
1303
1387
  const scope = store.authorityOf(id);
@@ -5298,34 +5382,18 @@ export class FleetManager {
5298
5382
  return this.adapterState.get(adapterId)?.status === "connected" ? adapter : undefined;
5299
5383
  }
5300
5384
  /** Last-resort completion after RestartProgress could not deliver to its
5301
- * adopted target. It stays bounded and never wakes a not-ready gateway. */
5385
+ * adopted target (or had no message: a small fleet, a failed first post). It
5386
+ * never wakes a not-ready gateway. #2213: an outage at fleet start no longer
5387
+ * loses it — bounded at startup, then retried in the background once the
5388
+ * adapter is ready again, never posted twice after an uncertain attempt. */
5302
5389
  async sendFleetStartCompletionFallback(chatId, text, threadId) {
5303
5390
  const adapterId = this.getPrimaryAdapterId();
5304
- const adapter = adapterId ? this.readyProgressAdapter(adapterId) : undefined;
5305
- if (!adapter) {
5306
- this.logger.error({ adapterId }, "Fleet start completion fallback skipped because the primary adapter is not ready");
5391
+ if (!adapterId) {
5392
+ this.logger.error({ adapterId }, "Fleet start completion fallback skipped because there is no primary adapter");
5307
5393
  return false;
5308
5394
  }
5309
- let timer;
5310
- const timeout = new Promise(resolve => {
5311
- timer = setTimeout(() => resolve({ status: "timeout" }), RESTART_PROGRESS_TERMINAL_TIMEOUT_MS);
5312
- timer.unref?.();
5313
- });
5314
- const delivery = Promise.resolve()
5315
- .then(() => adapter.sendText(chatId, text, { threadId }))
5316
- .then(() => ({ status: "sent" }), err => ({ status: "failed", err }));
5317
- const result = await Promise.race([delivery, timeout]);
5318
- if (timer)
5319
- clearTimeout(timer);
5320
- if (result.status === "sent")
5321
- return true;
5322
- if (result.status === "failed") {
5323
- this.logger.error({ err: result.err }, "Failed to send fleet start completion fallback");
5324
- }
5325
- else {
5326
- this.logger.error({ timeout_ms: RESTART_PROGRESS_TERMINAL_TIMEOUT_MS }, "Timed out sending fleet start completion fallback");
5327
- }
5328
- return false;
5395
+ const poster = new RestartProgress(0, Date.now(), this.logger);
5396
+ return poster.postCompletion({ resolveAdapter: () => this.readyProgressAdapter(adapterId), chatId, threadId }, text);
5329
5397
  }
5330
5398
  async stopInstance(name, transition) {
5331
5399
  this.explicitStopGeneration.set(name, (this.explicitStopGeneration.get(name) ?? 0) + 1);
@@ -11081,6 +11149,10 @@ export class FleetManager {
11081
11149
  throw new Error(`Refusing to overwrite invalid fleet.yaml: ${this.rawFleetDocument.errors[0].message}`);
11082
11150
  }
11083
11151
  this.rawFleetConfig = loadRawFleetConfig(this.configPath);
11152
+ // #2208: what the file says before this save, aliases expanded — every write below is recorded, and anything that
11153
+ // changes outside them (a place sharing a node with one written) refuses the save.
11154
+ const fileBefore = this.rawFleetDocument.toJS({ maxAliasCount: -1 });
11155
+ const writes = this.fleetDocumentWrites = []; // a throw below leaves it to the next save
11084
11156
  this.patchFleetDocument(this.rawFleetDocument, [], this.savedFleetConfigSnapshot, this.fleetConfig);
11085
11157
  // Settings edits are expressed against the raw config, so apply them before
11086
11158
  // canonicalization. A non-identity value equal to its inherited default is
@@ -11091,6 +11163,7 @@ export class FleetManager {
11091
11163
  // (or a legacy scalar occupies that parent). Removing an override which
11092
11164
  // is already absent is an idempotent no-op, not a failed Settings save.
11093
11165
  if (this.rawFleetDocument.hasIn(patch.path)) {
11166
+ this.writingFleetDocument(this.rawFleetDocument, patch.path);
11094
11167
  this.rawFleetDocument.deleteIn(patch.path);
11095
11168
  }
11096
11169
  }
@@ -11102,8 +11175,10 @@ export class FleetManager {
11102
11175
  const rawAfterPatches = this.rawFleetDocument.toJS();
11103
11176
  const redundantPaths = collectRedundantInstanceDefaultPaths(rawAfterPatches);
11104
11177
  for (const path of redundantPaths) {
11105
- if (this.rawFleetDocument.hasIn(path))
11178
+ if (this.rawFleetDocument.hasIn(path)) {
11179
+ this.writingFleetDocument(this.rawFleetDocument, path);
11106
11180
  this.rawFleetDocument.deleteIn(path);
11181
+ }
11107
11182
  // Avoid leaving empty operational maps such as `terminal: {}` while
11108
11183
  // preserving the instance mapping itself and all surrounding comments.
11109
11184
  for (let depth = path.length - 1; depth > 2; depth--) {
@@ -11111,9 +11186,14 @@ export class FleetManager {
11111
11186
  const parent = this.rawFleetDocument.getIn(parentPath, true);
11112
11187
  if (!isMap(parent) || parent.items.length > 0)
11113
11188
  break;
11189
+ this.writingFleetDocument(this.rawFleetDocument, parentPath);
11114
11190
  this.rawFleetDocument.deleteIn(parentPath);
11115
11191
  }
11116
11192
  }
11193
+ this.fleetDocumentWrites = null;
11194
+ const stray = changedOutside(fileBefore, this.rawFleetDocument.toJS({ maxAliasCount: -1 }), writes);
11195
+ if (stray)
11196
+ throw new Error(`Refusing to save fleet.yaml: this change would also change ${stray}, which shares a value with what it edits. Give each its own value in fleet.yaml.`);
11117
11197
  noteSettingsWrite(this.configPath, this.savedFleetConfigSnapshot, this.fleetConfig);
11118
11198
  const output = String(this.rawFleetDocument);
11119
11199
  if (redundantPaths.length > 0)
@@ -11224,11 +11304,15 @@ export class FleetManager {
11224
11304
  // Remove from the end so YAML sequence indexes do not shift underneath us.
11225
11305
  for (let i = before.length - 1; i >= after.length; i--) {
11226
11306
  const itemPath = [...path, i];
11227
- if (document.hasIn(itemPath))
11307
+ if (document.hasIn(itemPath)) {
11308
+ this.writingFleetDocument(document, itemPath);
11228
11309
  document.deleteIn(itemPath);
11310
+ }
11229
11311
  }
11230
- for (let i = shared; i < after.length; i++)
11312
+ for (let i = shared; i < after.length; i++) {
11313
+ this.writingFleetDocument(document, [...path, i]);
11231
11314
  document.setIn([...path, i], after[i]);
11315
+ }
11232
11316
  return;
11233
11317
  }
11234
11318
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -11244,6 +11328,7 @@ export class FleetManager {
11244
11328
  if (isMap(fresh)) {
11245
11329
  const list = document.createNode([]);
11246
11330
  list.items.push(fresh.clone());
11331
+ this.writingFleetDocument(document, ["channels"]);
11247
11332
  document.setIn(["channels"], list);
11248
11333
  }
11249
11334
  }
@@ -11265,13 +11350,17 @@ export class FleetManager {
11265
11350
  // Effective config contains inherited objects that may not exist in the
11266
11351
  // raw YAML at all. yaml.deleteIn() is not idempotent for a missing nested
11267
11352
  // parent, so guard it explicitly.
11268
- if (document.hasIn(path))
11353
+ if (document.hasIn(path)) {
11354
+ this.writingFleetDocument(document, path);
11269
11355
  document.deleteIn(path);
11356
+ }
11270
11357
  }
11271
11358
  else if (path.length === 0) {
11359
+ this.writingFleetDocument(document, path);
11272
11360
  document.contents = document.createNode(after);
11273
11361
  }
11274
11362
  else {
11363
+ this.writingFleetDocument(document, path);
11275
11364
  const currentNode = document.getIn(path, true);
11276
11365
  if (isScalar(currentNode) && (after === null || typeof after !== "object")) {
11277
11366
  currentNode.value = after;
@@ -11286,6 +11375,15 @@ export class FleetManager {
11286
11375
  }
11287
11376
  }
11288
11377
  }
11378
+ /**
11379
+ * #2208: before every write to the raw document — the place is unshared first (an alias on the way becomes its own
11380
+ * copy; an anchor's other aliases get theirs), so the write changes that place only; and it is recorded for the
11381
+ * save's check that nothing else changed.
11382
+ */
11383
+ writingFleetDocument(document, path) {
11384
+ detachForWrite(document, path);
11385
+ this.fleetDocumentWrites?.push([...path]);
11386
+ }
11289
11387
  getSettingsConfigPath() { return this.configPath; }
11290
11388
  async removeInstance(name, authorization, execution) {
11291
11389
  if (execution)