@songsid/agend 2.1.6-beta.1 → 2.1.6-beta.3

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 (100) hide show
  1. package/dist/apply-job.d.ts +114 -0
  2. package/dist/apply-job.js +214 -0
  3. package/dist/apply-job.js.map +1 -0
  4. package/dist/backend/codex.d.ts +24 -0
  5. package/dist/backend/codex.js +102 -0
  6. package/dist/backend/codex.js.map +1 -1
  7. package/dist/backend/credential-profile.d.ts +159 -0
  8. package/dist/backend/credential-profile.js +340 -0
  9. package/dist/backend/credential-profile.js.map +1 -0
  10. package/dist/backend/kiro-auth-store.d.ts +25 -0
  11. package/dist/backend/kiro-auth-store.js +61 -0
  12. package/dist/backend/kiro-auth-store.js.map +1 -0
  13. package/dist/backend/kiro.d.ts +8 -0
  14. package/dist/backend/kiro.js +31 -2
  15. package/dist/backend/kiro.js.map +1 -1
  16. package/dist/cli.js +113 -0
  17. package/dist/cli.js.map +1 -1
  18. package/dist/config-validator.js +21 -0
  19. package/dist/config-validator.js.map +1 -1
  20. package/dist/daemon.d.ts +10 -0
  21. package/dist/daemon.js +27 -1
  22. package/dist/daemon.js.map +1 -1
  23. package/dist/fleet-level-config.d.ts +42 -0
  24. package/dist/fleet-level-config.js +78 -0
  25. package/dist/fleet-level-config.js.map +1 -0
  26. package/dist/fleet-lock.d.ts +21 -0
  27. package/dist/fleet-lock.js +42 -8
  28. package/dist/fleet-lock.js.map +1 -1
  29. package/dist/fleet-manager.d.ts +122 -1
  30. package/dist/fleet-manager.js +537 -83
  31. package/dist/fleet-manager.js.map +1 -1
  32. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +145 -0
  33. package/dist/instance-config-impact.d.ts +55 -0
  34. package/dist/instance-config-impact.js +152 -0
  35. package/dist/instance-config-impact.js.map +1 -0
  36. package/dist/locale.js +2 -0
  37. package/dist/locale.js.map +1 -1
  38. package/dist/outbound-handlers.d.ts +5 -1
  39. package/dist/outbound-handlers.js +199 -1
  40. package/dist/outbound-handlers.js.map +1 -1
  41. package/dist/outbound-schemas.d.ts +6 -5
  42. package/dist/outbound-schemas.js +1 -0
  43. package/dist/outbound-schemas.js.map +1 -1
  44. package/dist/provider-probe.d.ts +45 -0
  45. package/dist/provider-probe.js +111 -0
  46. package/dist/provider-probe.js.map +1 -0
  47. package/dist/quickstart-api.d.ts +161 -0
  48. package/dist/quickstart-api.js +340 -0
  49. package/dist/quickstart-api.js.map +1 -0
  50. package/dist/quickstart.js +23 -50
  51. package/dist/quickstart.js.map +1 -1
  52. package/dist/self-restart-limit.d.ts +21 -0
  53. package/dist/self-restart-limit.js +129 -0
  54. package/dist/self-restart-limit.js.map +1 -0
  55. package/dist/settings-api.d.ts +15 -0
  56. package/dist/settings-api.js +126 -1
  57. package/dist/settings-api.js.map +1 -1
  58. package/dist/setup-auth.d.ts +113 -0
  59. package/dist/setup-auth.js +181 -0
  60. package/dist/setup-auth.js.map +1 -0
  61. package/dist/setup-form.d.ts +18 -0
  62. package/dist/setup-form.js +315 -0
  63. package/dist/setup-form.js.map +1 -0
  64. package/dist/setup-host.d.ts +162 -0
  65. package/dist/setup-host.js +496 -0
  66. package/dist/setup-host.js.map +1 -0
  67. package/dist/setup-marker.d.ts +8 -0
  68. package/dist/setup-marker.js +39 -0
  69. package/dist/setup-marker.js.map +1 -0
  70. package/dist/setup-tunnel-consent.d.ts +53 -0
  71. package/dist/setup-tunnel-consent.js +82 -0
  72. package/dist/setup-tunnel-consent.js.map +1 -0
  73. package/dist/tips.js +1 -1
  74. package/dist/tips.js.map +1 -1
  75. package/dist/transcript-sources.d.ts +12 -1
  76. package/dist/transcript-sources.js +19 -3
  77. package/dist/transcript-sources.js.map +1 -1
  78. package/dist/tunnel/cloudflared.d.ts +71 -0
  79. package/dist/tunnel/cloudflared.js +447 -0
  80. package/dist/tunnel/cloudflared.js.map +1 -0
  81. package/dist/tunnel/lease.d.ts +75 -0
  82. package/dist/tunnel/lease.js +209 -0
  83. package/dist/tunnel/lease.js.map +1 -0
  84. package/dist/tunnel/manager.d.ts +56 -0
  85. package/dist/tunnel/manager.js +167 -0
  86. package/dist/tunnel/manager.js.map +1 -0
  87. package/dist/tunnel/types.d.ts +119 -0
  88. package/dist/tunnel/types.js +33 -0
  89. package/dist/tunnel/types.js.map +1 -0
  90. package/dist/ui/dashboard.html +4 -3
  91. package/dist/ui/settings.html +640 -153
  92. package/dist/usage/providers.d.ts +17 -14
  93. package/dist/usage/providers.js +87 -55
  94. package/dist/usage/providers.js.map +1 -1
  95. package/dist/web-api.js +6 -4
  96. package/dist/web-api.js.map +1 -1
  97. package/dist/web-auth.d.ts +75 -0
  98. package/dist/web-auth.js +208 -2
  99. package/dist/web-auth.js.map +1 -1
  100. package/package.json +1 -1
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Which fleet settings only a fresh process can adopt.
3
+ *
4
+ * The test is mechanical, not intuitive: **read once at construction and never
5
+ * re-read by `reconcileInstances`**. "Feels fleet-level" is not the test —
6
+ * `defaults.backend` feels fleet-level and is absorbed entirely by restarting
7
+ * the agents.
8
+ *
9
+ * Getting this set wrong in the *narrow* direction is worse than not narrowing
10
+ * at all. A startup-only key left out is saved to disk, produces no instance
11
+ * restart and no fleet row, and therefore never takes effect and never tells
12
+ * anyone — where an over-broad set only asks for a restart that was not needed.
13
+ * `tests/fleet-level-config.test.ts` asserts both sides of the line so a new
14
+ * key has to be classified deliberately.
15
+ */
16
+ import type { FleetConfig } from "./types.js";
17
+ /**
18
+ * Startup-only, with the construction site that consumes each one.
19
+ *
20
+ * `timezone` is deliberately absent: `detectLocale()` reads only
21
+ * `defaults.locale` plus the host clock, and the configurable timezone lives
22
+ * inside `defaults.cost_guard`, which is covered whole.
23
+ */
24
+ export declare const STARTUP_ONLY_FLEET_KEYS: readonly ["channel", "channels", "health_port", "defaults.locale", "defaults.cost_guard", "defaults.webhooks", "defaults.daily_summary", "defaults.scheduler.max_schedules", "defaults.scheduler.default_timezone"];
25
+ /**
26
+ * Verified to be read at the point of use, so they must NOT be in the set above.
27
+ *
28
+ * Listed rather than implied: the enumeration test asserts their absence, which
29
+ * is what stops the set from quietly growing back into "every cold default".
30
+ */
31
+ export declare const RUNTIME_READ_FLEET_KEYS: readonly ["defaults.backend", "defaults.model", "defaults.tool_set", "defaults.agent_mode", "defaults.hang_detector", "defaults.startup.concurrency", "defaults.startup.stagger_delay_ms", "defaults.max_cross_instance_message_bytes", "defaults.tips", "defaults.progress_min_elapsed", "defaults.scheduler.retry_count", "defaults.scheduler.retry_interval_ms", "web", "hostname", "login", "web_terminal"];
32
+ /**
33
+ * The fleet-level configuration as one comparable string.
34
+ *
35
+ * Built by walking a fixed key list, so the output is stable regardless of the
36
+ * order keys appear in the YAML — two configs that differ only in key order
37
+ * must not look like a pending restart.
38
+ */
39
+ export declare function fleetLevelSignature(config: FleetConfig | null): string;
40
+ /** The keys whose values differ between two configs — for the log line that
41
+ * explains why a restart is being asked for, or why two signatures disagree. */
42
+ export declare function fleetLevelDifferences(a: FleetConfig | null, b: FleetConfig | null): string[];
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Startup-only, with the construction site that consumes each one.
3
+ *
4
+ * `timezone` is deliberately absent: `detectLocale()` reads only
5
+ * `defaults.locale` plus the host clock, and the configurable timezone lives
6
+ * inside `defaults.cost_guard`, which is covered whole.
7
+ */
8
+ export const STARTUP_ONLY_FLEET_KEYS = [
9
+ "channel", // createAdapter() at startup
10
+ "channels", // createAdapter() at startup
11
+ "health_port", // startHealthServer(), once
12
+ "defaults.locale", // setLocale(detectLocale(fleet)), once
13
+ "defaults.cost_guard", // new CostGuard(...)
14
+ "defaults.webhooks", // new WebhookEmitter(...)
15
+ "defaults.daily_summary", // new DailySummary(...)
16
+ "defaults.scheduler.max_schedules", // Scheduler ctor config
17
+ "defaults.scheduler.default_timezone", // Scheduler ctor config
18
+ ];
19
+ /**
20
+ * Verified to be read at the point of use, so they must NOT be in the set above.
21
+ *
22
+ * Listed rather than implied: the enumeration test asserts their absence, which
23
+ * is what stops the set from quietly growing back into "every cold default".
24
+ */
25
+ export const RUNTIME_READ_FLEET_KEYS = [
26
+ // Absorbed by restarting the agent.
27
+ "defaults.backend",
28
+ "defaults.model",
29
+ "defaults.tool_set",
30
+ "defaults.agent_mode",
31
+ "defaults.hang_detector",
32
+ // Read per spawn by the SpawnGate closures.
33
+ "defaults.startup.concurrency",
34
+ "defaults.startup.stagger_delay_ms",
35
+ // Read per message / per post / per tick.
36
+ "defaults.max_cross_instance_message_bytes",
37
+ "defaults.tips",
38
+ "defaults.progress_min_elapsed",
39
+ // Read on every schedule trigger, unlike the two Scheduler ctor keys.
40
+ "defaults.scheduler.retry_count",
41
+ "defaults.scheduler.retry_interval_ms",
42
+ // Read when the value is used; no construction captures them.
43
+ "web",
44
+ "hostname",
45
+ "login",
46
+ "web_terminal",
47
+ ];
48
+ function pick(source, path) {
49
+ let value = source;
50
+ for (const segment of path.split(".")) {
51
+ if (value === null || typeof value !== "object")
52
+ return undefined;
53
+ value = value[segment];
54
+ }
55
+ return value;
56
+ }
57
+ /**
58
+ * The fleet-level configuration as one comparable string.
59
+ *
60
+ * Built by walking a fixed key list, so the output is stable regardless of the
61
+ * order keys appear in the YAML — two configs that differ only in key order
62
+ * must not look like a pending restart.
63
+ */
64
+ export function fleetLevelSignature(config) {
65
+ const snapshot = {};
66
+ for (const path of STARTUP_ONLY_FLEET_KEYS) {
67
+ const value = pick(config, path);
68
+ if (value !== undefined)
69
+ snapshot[path] = value;
70
+ }
71
+ return JSON.stringify(snapshot);
72
+ }
73
+ /** The keys whose values differ between two configs — for the log line that
74
+ * explains why a restart is being asked for, or why two signatures disagree. */
75
+ export function fleetLevelDifferences(a, b) {
76
+ return STARTUP_ONLY_FLEET_KEYS.filter(path => JSON.stringify(pick(a, path) ?? null) !== JSON.stringify(pick(b, path) ?? null));
77
+ }
78
+ //# sourceMappingURL=fleet-level-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fleet-level-config.js","sourceRoot":"","sources":["../src/fleet-level-config.ts"],"names":[],"mappings":"AAiBA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,SAAS,EAA+B,6BAA6B;IACrE,UAAU,EAA8B,6BAA6B;IACrE,aAAa,EAA2B,4BAA4B;IACpE,iBAAiB,EAAuB,uCAAuC;IAC/E,qBAAqB,EAAmB,qBAAqB;IAC7D,mBAAmB,EAAqB,0BAA0B;IAClE,wBAAwB,EAAgB,wBAAwB;IAChE,kCAAkC,EAAM,wBAAwB;IAChE,qCAAqC,EAAG,wBAAwB;CACxD,CAAC;AAEX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,oCAAoC;IACpC,kBAAkB;IAClB,gBAAgB;IAChB,mBAAmB;IACnB,qBAAqB;IACrB,wBAAwB;IACxB,4CAA4C;IAC5C,8BAA8B;IAC9B,mCAAmC;IACnC,0CAA0C;IAC1C,2CAA2C;IAC3C,eAAe;IACf,+BAA+B;IAC/B,sEAAsE;IACtE,gCAAgC;IAChC,sCAAsC;IACtC,8DAA8D;IAC9D,KAAK;IACL,UAAU;IACV,OAAO;IACP,cAAc;CACN,CAAC;AAEX,SAAS,IAAI,CAAC,MAAe,EAAE,IAAY;IACzC,IAAI,KAAK,GAAY,MAAM,CAAC;IAC5B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACtC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAClE,KAAK,GAAI,KAAiC,CAAC,OAAO,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA0B;IAC5D,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,KAAK,MAAM,IAAI,IAAI,uBAAuB,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACjC,IAAI,KAAK,KAAK,SAAS;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IAClD,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;AAClC,CAAC;AAED;gFACgF;AAChF,MAAM,UAAU,qBAAqB,CAAC,CAAqB,EAAE,CAAqB;IAChF,OAAO,uBAAuB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAC3C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;AACrF,CAAC"}
@@ -1,7 +1,16 @@
1
+ /**
2
+ * What kind of process holds the lock.
3
+ *
4
+ * A record written before this field existed has no role; it can only have been
5
+ * a fleet, so that is what a missing value means. Never widen that default —
6
+ * "unknown" must not become "safe to take from".
7
+ */
8
+ export type FleetLockRole = "fleet" | "setup-host";
1
9
  interface FleetLockRecord {
2
10
  pid: number;
3
11
  nonce: string;
4
12
  createdAt: string;
13
+ role?: FleetLockRole;
5
14
  }
6
15
  export interface FleetLockHandle {
7
16
  path: string;
@@ -11,11 +20,23 @@ export interface FleetLockHandle {
11
20
  export interface FleetLockProbe {
12
21
  pid?: number;
13
22
  nonce?: string;
23
+ /** Defaults to "fleet"; the pre-fleet setup host claims "setup-host". */
24
+ role?: FleetLockRole;
14
25
  isProcessAlive?: (pid: number) => boolean;
15
26
  readCommandLine?: (pid: number) => string;
16
27
  }
28
+ /** Whether a process command line identifies the AgEnD setup page. */
29
+ export declare function isSetupHostCommandLine(commandLine: string): boolean;
17
30
  /** Whether a process command line identifies an AgEnD fleet process. */
18
31
  export declare function isFleetStartCommandLine(commandLine: string): boolean;
32
+ /**
33
+ * A process's command line, or "" when it cannot be read.
34
+ *
35
+ * Exported because the health-port takeover has to answer the same question
36
+ * before it sends a signal: an empty answer means "cannot confirm", and nothing
37
+ * destructive may be done on that.
38
+ */
39
+ export declare function readProcessCommandLine(pid: number): string;
19
40
  /**
20
41
  * Atomically claim one fleet process per AGEND_HOME. O_EXCL is portable and,
21
42
  * unlike fleet.pid, is acquired before FleetManager can mutate tmux or sockets.
@@ -2,6 +2,11 @@ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "
2
2
  import { execFileSync } from "node:child_process";
3
3
  import { randomBytes } from "node:crypto";
4
4
  import { join } from "node:path";
5
+ /** Whether a process command line identifies the AgEnD setup page. */
6
+ export function isSetupHostCommandLine(commandLine) {
7
+ const normalized = commandLine.replace(/\0/g, " ").replace(/\s+/g, " ").trim();
8
+ return /\b(?:agend|(?:cli|daemon-entry)\.(?:js|ts))\b.*\bsetup\b/i.test(normalized);
9
+ }
5
10
  /** Whether a process command line identifies an AgEnD fleet process. */
6
11
  export function isFleetStartCommandLine(commandLine) {
7
12
  const normalized = commandLine.replace(/\0/g, " ").replace(/\s+/g, " ").trim();
@@ -16,7 +21,14 @@ function processAlive(pid) {
16
21
  return false;
17
22
  }
18
23
  }
19
- function processCommandLine(pid) {
24
+ /**
25
+ * A process's command line, or "" when it cannot be read.
26
+ *
27
+ * Exported because the health-port takeover has to answer the same question
28
+ * before it sends a signal: an empty answer means "cannot confirm", and nothing
29
+ * destructive may be done on that.
30
+ */
31
+ export function readProcessCommandLine(pid) {
20
32
  try {
21
33
  return readFileSync(`/proc/${pid}/cmdline`, "utf8").replace(/\0/g, " ").trim();
22
34
  }
@@ -57,10 +69,11 @@ export function acquireFleetLock(dataDir, probe = {}) {
57
69
  pid,
58
70
  nonce: probe.nonce ?? randomBytes(16).toString("hex"),
59
71
  createdAt: new Date().toISOString(),
72
+ role: probe.role ?? "fleet",
60
73
  };
61
74
  const serialized = JSON.stringify(record) + "\n";
62
75
  const isAlive = probe.isProcessAlive ?? processAlive;
63
- const readCommandLine = probe.readCommandLine ?? processCommandLine;
76
+ const readCommandLine = probe.readCommandLine ?? readProcessCommandLine;
64
77
  for (let attempt = 0; attempt < 4; attempt++) {
65
78
  try {
66
79
  writeFileSync(lockPath, serialized, { encoding: "utf8", flag: "wx", mode: 0o600 });
@@ -81,14 +94,35 @@ export function acquireFleetLock(dataDir, probe = {}) {
81
94
  const owner = parseRecord(observed);
82
95
  if (owner && isAlive(owner.pid)) {
83
96
  const commandLine = readCommandLine(owner.pid);
84
- if (isFleetStartCommandLine(commandLine)) {
85
- throw new Error(`Fleet is already running (PID ${owner.pid}, lock: ${lockPath})`);
97
+ // A live setup host is an owner in its own right. Before the role existed
98
+ // its command line did not match the fleet pattern, so a starting fleet
99
+ // read the lock as stale and took it — and then collided with the host on
100
+ // the health port, where the takeover kills whatever fleet.pid names.
101
+ //
102
+ // Symmetric with the fleet case on purpose: the setup page is short-lived
103
+ // and often killed outright, so its pid is a prime candidate for reuse
104
+ // after a reboot. Positive evidence that the pid now belongs to something
105
+ // else makes the record stale; no evidence still refuses, because an
106
+ // unreadable owner must never be assumed absent.
107
+ if (owner.role === "setup-host") {
108
+ if (!commandLine) {
109
+ throw new Error(`Fleet lock is owned by live PID ${owner.pid}; refusing to replace it`);
110
+ }
111
+ if (isSetupHostCommandLine(commandLine)) {
112
+ throw new Error(`Setup is already running (PID ${owner.pid}, lock: ${lockPath})`);
113
+ }
114
+ // The pid was reused by an unrelated process: the lock is stale.
86
115
  }
87
- // An alive PID with an unreadable command line is not safe to steal from.
88
- if (!commandLine) {
89
- throw new Error(`Fleet lock is owned by live PID ${owner.pid}; refusing to replace it`);
116
+ else {
117
+ if (isFleetStartCommandLine(commandLine)) {
118
+ throw new Error(`Fleet is already running (PID ${owner.pid}, lock: ${lockPath})`);
119
+ }
120
+ // An alive PID with an unreadable command line is not safe to steal from.
121
+ if (!commandLine) {
122
+ throw new Error(`Fleet lock is owned by live PID ${owner.pid}; refusing to replace it`);
123
+ }
124
+ // The PID was reused by an unrelated process: the lock is stale.
90
125
  }
91
- // The PID was reused by an unrelated process: the lock is stale.
92
126
  }
93
127
  // Only unlink the exact stale record we inspected. A competing starter may
94
128
  // already have replaced it; in that case leave its lock untouched and retry.
@@ -1 +1 @@
1
- {"version":3,"file":"fleet-lock.js","sourceRoot":"","sources":["../src/fleet-lock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fleet-lock.js","sourceRoot":"","sources":["../src/fleet-lock.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,7 @@ import { type AgentEndpointContext } from "./agent-endpoint.js";
21
21
  import { ClassicChannelManager } from "./classic-channel-manager.js";
22
22
  import { type ExplicitInstanceRemoval } from "./instance-removal.js";
23
23
  import type { InstanceState } from "./backend/types.js";
24
+ import { ApplyJobStore, type ApplyJob, type ApplyTargetKind, type SelfRestartResult } from "./apply-job.js";
24
25
  import { StormWindow } from "./storm-window.js";
25
26
  import { SpawnGate } from "./spawn-gate.js";
26
27
  import { BackendOutageTracker } from "./backend-outage.js";
@@ -262,7 +263,29 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
262
263
  private mirrorBuffer;
263
264
  private mirrorTimer;
264
265
  private sseClients;
265
- private webToken;
266
+ /**
267
+ * Read from disk on every access rather than cached at startup: `agend
268
+ * web-token rotate` runs in a separate process, and a cached copy would keep
269
+ * authorizing revoked links and cookies until the fleet restarted.
270
+ */
271
+ private get webToken();
272
+ /**
273
+ * Set while a Settings apply job is driving the reconcile. The reconcile
274
+ * stays the single doer; it just says out loud what it is doing to whom, so
275
+ * the job's rows are the work rather than a prediction of it.
276
+ */
277
+ private applyJobStoreCache;
278
+ /** The apply that currently owns the reconcile slot, reserved synchronously
279
+ * so a second request cannot slip in before the first one starts working. */
280
+ private activeApplyJobId;
281
+ /** The fleet-level signature this process actually came up on. */
282
+ private appliedFleetLevel;
283
+ /** The config behind that signature, kept so a "needs restart" log can name
284
+ * which keys moved rather than just asserting that something did. */
285
+ private startupFleetConfig;
286
+ /** Set when the file on disk and the in-memory config disagree on a
287
+ * startup-only key at startup. See checkStartupSignatureConsistency(). */
288
+ private fleetSignatureMismatch;
266
289
  private viewToken;
267
290
  private healthServerListening;
268
291
  constructor(dataDir: string);
@@ -273,6 +296,18 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
273
296
  stormSuppressed(kind: string): boolean;
274
297
  private handleSighup;
275
298
  private scheduleReconcile;
299
+ /**
300
+ * Take the reconcile slot, or refuse.
301
+ *
302
+ * Only one reconcile may touch lifecycle and config at a time — two of them
303
+ * stop and start the same instance in parallel. SIGHUP and a Settings apply
304
+ * are the same operation from two entrances, so they share the one slot: the
305
+ * signal coalesces into a pending replay, the apply is told the fleet is busy.
306
+ *
307
+ * The returned promise is the caller's to handle; the stored one is already
308
+ * handled, so a rejection never escapes as an unhandled rejection.
309
+ */
310
+ private startExclusiveReconcile;
276
311
  /**
277
312
  * Is the fleet going down (or coming back up) on purpose?
278
313
  *
@@ -398,6 +433,9 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
398
433
  * Classic channels use their effective backend merge chain, not the raw row.
399
434
  */
400
435
  getActiveUsageProviderIds(): ReadonlySet<string>;
436
+ /** `[instance, effective backend, credential profile]` for everything that is
437
+ * running or paused — the one place both usage views agree on who is live. */
438
+ private activeBackendBindings;
401
439
  /** Effective backends with a running or persisted-paused fleet/Classic instance. */
402
440
  getActiveBackendIds(): ReadonlySet<string>;
403
441
  isClassicInstance(name: string): boolean;
@@ -1584,6 +1622,89 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
1584
1622
  * fields, plus cold fleet-level settings, retain restart semantics.
1585
1623
  */
1586
1624
  private reconcileInstances;
1625
+ /**
1626
+ * `{channel, cold defaults}` as one comparable string — the part of the config
1627
+ * a running fleet process cannot adopt without restarting.
1628
+ */
1629
+ private fleetLevelSignature;
1630
+ /**
1631
+ * The config a reconcile is about to load, not the one held in memory.
1632
+ *
1633
+ * Settings mutates the in-memory object and writes the file; only the file
1634
+ * goes back through defaults expansion. Forecasting from memory therefore
1635
+ * misses every instance that a changed fleet default will restart — the user
1636
+ * is told "restart AgEnD" and not told that five agents are about to go down.
1637
+ */
1638
+ private nextFleetConfig;
1639
+ /**
1640
+ * Does the config this process is running match the one a reconcile would
1641
+ * load off disk?
1642
+ *
1643
+ * If not, every apply reports a fleet-level change that a restart cannot
1644
+ * clear — restart, recompute, disagree again — a self-sustaining loop that
1645
+ * the rate limit can only slow to three naggings an hour. Startup rewrites
1646
+ * the file in three places before this point (slimFleetConfigAtStartup, the
1647
+ * general auto-create, the general fixup), so the two can genuinely diverge.
1648
+ *
1649
+ * An offer to restart that cannot possibly succeed is worse than no offer, so
1650
+ * the panel shows the mismatch instead of a button.
1651
+ */
1652
+ private checkStartupSignatureConsistency;
1653
+ /**
1654
+ * Is a live adapter already long-polling this bot token?
1655
+ *
1656
+ * Telegram's `getUpdates` has exactly one consumer: a second poller takes
1657
+ * turns with the first and both miss messages. The setup wizard's "post in
1658
+ * the group and I'll detect it" step is a second poller, so it has to know
1659
+ * when the answer is "not against this token, not while I'm running".
1660
+ */
1661
+ isBotTokenInUse(token: string): boolean;
1662
+ /** Non-null when startup found the running config and fleet.yaml disagreeing. */
1663
+ fleetSignatureMismatchKeys(): string[] | null;
1664
+ /**
1665
+ * Restart AgEnD itself on behalf of a Settings apply.
1666
+ *
1667
+ * Deliberately a separate action from Apply: the panel is reachable from
1668
+ * outside the LAN, and "restart the whole fleet" must never be something a
1669
+ * single Apply click can carry along with it.
1670
+ *
1671
+ * The order below is the safety envelope, and the order matters:
1672
+ * concurrency and consistency first (cheap, and a restart during a reconcile
1673
+ * is the dangerous one), then the state checks, then the rate limit, then the
1674
+ * audit notice — and only once all of that holds is the attempt written to
1675
+ * disk and fsynced, before anything spawns.
1676
+ */
1677
+ requestSettingsSelfRestart(jobId: string, key: string): Promise<SelfRestartResult>;
1678
+ /** The audit notice, and the message the restart progress will edit. */
1679
+ private postSelfRestartNotice;
1680
+ /** Jobs outlive this process on purpose; see apply-job.ts. */
1681
+ get applyJobs(): ApplyJobStore;
1682
+ /**
1683
+ * What a reconcile is about to do, per target.
1684
+ *
1685
+ * A forecast, not the record: it is built from the same `classifyInstanceChange`
1686
+ * the reconcile decides with, but the rows that end up in the job are the ones
1687
+ * the reconcile reports as it works. A target the forecast missed (a Classic
1688
+ * instance inheriting a changed default) is added when it is first touched.
1689
+ */
1690
+ planConfigApply(): Array<{
1691
+ target: string;
1692
+ kind: ApplyTargetKind;
1693
+ }>;
1694
+ /**
1695
+ * Start (or re-join) a Settings apply.
1696
+ *
1697
+ * The key is the client's. Handing back the existing job for a repeated key is
1698
+ * the whole point: the retry after a lost response must not apply everything a
1699
+ * second time.
1700
+ */
1701
+ startSettingsApply(key: string): {
1702
+ job: ApplyJob;
1703
+ reused: boolean;
1704
+ } | {
1705
+ busy: ApplyJob | null;
1706
+ };
1707
+ private runSettingsApply;
1587
1708
  restartInstances(): Promise<void>;
1588
1709
  private checkForUpdates;
1589
1710
  /**