@songsid/agend 2.3.0-beta.11 → 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.
- package/README.md +6 -0
- package/README.zh-TW.md +6 -0
- package/dist/agent-whats-new.js +14 -9
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/channel/adapters/discord-client-retirement.d.ts +5 -0
- package/dist/channel/adapters/discord-client-retirement.js +57 -0
- package/dist/channel/adapters/discord-client-retirement.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +2 -0
- package/dist/channel/adapters/discord.js +14 -4
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/cli.js +12 -79
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +12 -0
- package/dist/config.js +13 -4
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.js +25 -0
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.d.ts +44 -2
- package/dist/fleet-manager.js +229 -63
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-process-handlers.d.ts +18 -0
- package/dist/fleet-process-handlers.js +69 -0
- package/dist/fleet-process-handlers.js.map +1 -0
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +2 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +20 -3
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +27 -5
- package/dist/instance-lifecycle.d.ts +2 -0
- package/dist/instance-lifecycle.js +11 -6
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/outbound-schemas.d.ts +14 -1
- package/dist/outbound-schemas.js +8 -2
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +4 -0
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/restart-progress.d.ts +16 -1
- package/dist/restart-progress.js +74 -15
- package/dist/restart-progress.js.map +1 -1
- package/dist/settings-api.d.ts +4 -0
- package/dist/settings-api.js +27 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-confirmation.d.ts +3 -1
- package/dist/settings-confirmation.js +2 -0
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-effect.js +2 -1
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.d.ts +11 -0
- package/dist/settings-http-confirmation.js +10 -0
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/ui/app-effects.js +13 -1
- package/dist/ui/chat-effects.js +10 -3
- package/dist/ui/chat-store.js +32 -10
- package/dist/ui/chat-strings.js +18 -0
- package/dist/ui/chat-thread.js +5 -2
- package/dist/ui/effects-waker.js +70 -0
- package/dist/ui/fleet-canvas-layout.js +10 -4
- package/dist/ui/fleet-canvas.js +32 -2
- package/dist/ui/fleet-route-scene.js +207 -0
- package/dist/ui/fleet-route-worker.js +21 -0
- package/dist/ui/fleet-route.js +88 -0
- package/dist/ui/fleet-traffic.js +27 -11
- package/dist/ui/fleet-usage.js +35 -1
- package/dist/ui/panel-chat.js +67 -26
- package/dist/ui/panel-fleet.js +3 -3
- package/dist/ui/panel-settings.js +24 -0
- package/dist/ui/settings-appearance.js +2 -1
- package/dist/ui/settings-apply.js +3 -3
- package/dist/ui/settings-confirm.js +7 -2
- package/dist/ui/settings-owner-effects.js +6 -4
- package/dist/ui/settings-strings.js +2 -0
- package/dist/ui/shared/app-i18n.js +4 -0
- package/dist/ui/shared/app-prefs.js +12 -0
- package/dist/ui/shared/app-shell.js +38 -2
- package/dist/ui/shared/app-themes.js +116 -1
- package/dist/ui/shared/app.css +47 -3
- package/dist/ui/shared/card-strings.js +4 -0
- package/dist/ui/shared/effect-owner-source.js +8 -1
- package/dist/ui/shared/effect-registry.js +10 -2
- package/dist/ui/shared/identity-card.js +24 -6
- package/dist/ui/shared/identity-color.js +11 -7
- package/dist/ui/shared/owner-css.js +30 -1
- package/dist/ui/shared/ui-icons.js +2 -0
- package/dist/ui/shared/ui-menu.js +9 -3
- package/dist/ui/shared/web-authorize.js +47 -0
- package/dist/web-api.d.ts +6 -2
- package/dist/web-api.js +68 -15
- package/dist/web-api.js.map +1 -1
- package/dist/web-appearance.js +3 -1
- package/dist/web-appearance.js.map +1 -1
- package/dist/web-effect.d.ts +1 -1
- package/dist/web-host-guard.d.ts +11 -0
- package/dist/web-host-guard.js +11 -0
- package/dist/web-host-guard.js.map +1 -1
- package/dist/web-libavoid.d.ts +14 -0
- package/dist/web-libavoid.js +46 -0
- package/dist/web-libavoid.js.map +1 -0
- package/dist/web-owner-css-store.d.ts +44 -1
- package/dist/web-owner-css-store.js +70 -9
- package/dist/web-owner-css-store.js.map +1 -1
- package/dist/web-prefs.js +13 -0
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-settings-tools.d.ts +5 -0
- package/dist/web-settings-tools.js +38 -7
- package/dist/web-settings-tools.js.map +1 -1
- package/dist/web-theme.d.ts +29 -0
- package/dist/web-theme.js +89 -1
- package/dist/web-theme.js.map +1 -1
- package/dist/yaml-shared-nodes.d.ts +25 -0
- package/dist/yaml-shared-nodes.js +185 -0
- package/dist/yaml-shared-nodes.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Synchronous evidence before shutdown: neither a network nor logger worker is required. */
|
|
2
|
+
export declare function recordFleetFatal(dataDir: string, error: unknown): void;
|
|
3
|
+
interface FleetProcessOptions {
|
|
4
|
+
dataDir: string;
|
|
5
|
+
manager: {
|
|
6
|
+
stopAll(): Promise<void>;
|
|
7
|
+
notifyFleetError(message: string): void;
|
|
8
|
+
};
|
|
9
|
+
runtime: Pick<NodeJS.Process, "on" | "exit">;
|
|
10
|
+
describeSignal: () => string;
|
|
11
|
+
console?: Pick<Console, "log" | "error">;
|
|
12
|
+
writeFatal?: typeof recordFleetFatal;
|
|
13
|
+
}
|
|
14
|
+
/** Identical process policy for cold start and the legacy in-process reload. */
|
|
15
|
+
export declare function installFleetProcessHandlers(options: FleetProcessOptions): {
|
|
16
|
+
readonly stopping: boolean;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { closeSync, fsyncSync, mkdirSync, openSync, writeSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/** Synchronous evidence before shutdown: neither a network nor logger worker is required. */
|
|
4
|
+
export function recordFleetFatal(dataDir, error) {
|
|
5
|
+
mkdirSync(dataDir, { recursive: true });
|
|
6
|
+
const fd = openSync(join(dataDir, "fleet-fatal.log"), "a", 0o600);
|
|
7
|
+
try {
|
|
8
|
+
writeSync(fd, JSON.stringify({ timestamp: new Date().toISOString(), pid: process.pid,
|
|
9
|
+
argv: process.argv, reason: "uncaughtException", error: String(error),
|
|
10
|
+
stack: error instanceof Error ? error.stack : undefined }) + "\n");
|
|
11
|
+
fsyncSync(fd);
|
|
12
|
+
}
|
|
13
|
+
finally {
|
|
14
|
+
closeSync(fd);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Identical process policy for cold start and the legacy in-process reload. */
|
|
18
|
+
export function installFleetProcessHandlers(options) {
|
|
19
|
+
const { runtime, manager } = options;
|
|
20
|
+
const output = options.console ?? console;
|
|
21
|
+
let stopping = false;
|
|
22
|
+
const shutdown = async () => {
|
|
23
|
+
if (stopping)
|
|
24
|
+
return;
|
|
25
|
+
stopping = true;
|
|
26
|
+
output.log("\nStopping fleet...");
|
|
27
|
+
// stopAll fences new controls and drains CPU profiles before disposal.
|
|
28
|
+
await manager.stopAll().catch(error => output.error("Shutdown error:", error));
|
|
29
|
+
runtime.exit(0);
|
|
30
|
+
};
|
|
31
|
+
runtime.on("SIGINT", shutdown);
|
|
32
|
+
runtime.on("SIGTERM", () => {
|
|
33
|
+
output.log(options.describeSignal());
|
|
34
|
+
return shutdown();
|
|
35
|
+
});
|
|
36
|
+
runtime.on("uncaughtException", async (error) => {
|
|
37
|
+
output.error("Uncaught exception:", error);
|
|
38
|
+
try {
|
|
39
|
+
(options.writeFatal ?? recordFleetFatal)(options.dataDir, error);
|
|
40
|
+
}
|
|
41
|
+
catch (writeError) {
|
|
42
|
+
output.error("Failed to persist fleet fatal reason:", writeError);
|
|
43
|
+
}
|
|
44
|
+
if (stopping)
|
|
45
|
+
return;
|
|
46
|
+
stopping = true;
|
|
47
|
+
// Arbitrary uncaught exceptions still leave unknown state and remain fatal.
|
|
48
|
+
await manager.stopAll().catch(() => { });
|
|
49
|
+
runtime.exit(1);
|
|
50
|
+
});
|
|
51
|
+
runtime.on("unhandledRejection", error => {
|
|
52
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
53
|
+
if (message.includes("409") && message.includes("getUpdates")) {
|
|
54
|
+
output.error("Bot polling conflict (409) — retrying...");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
output.error("Unhandled rejection (fleet continues):", error);
|
|
58
|
+
if (error instanceof Error && error.stack)
|
|
59
|
+
output.error(error.stack);
|
|
60
|
+
try {
|
|
61
|
+
manager.notifyFleetError(`⚠️ Fleet caught an unhandled error and kept running:\n\`${message}\`\nSee fleet.log for the stack trace.`);
|
|
62
|
+
}
|
|
63
|
+
catch (notifyError) {
|
|
64
|
+
output.error("Failed to report unhandled rejection:", notifyError);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return { get stopping() { return stopping; } };
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=fleet-process-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet-process-handlers.js","sourceRoot":"","sources":["../src/fleet-process-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -84,6 +84,8 @@ Fix all errors before `agend reload`; warnings are advisory.
|
|
|
84
84
|
- `topic_id` as string vs number (both work, but be consistent)
|
|
85
85
|
- `backend` typo (valid: `claude-code`, `codex`, `opencode`, `kiro-cli`, `antigravity`, `grok`, `muse`); `gemini-cli` was removed in 2.1.12 — use `antigravity`
|
|
86
86
|
- `model` using wrong format for the backend
|
|
87
|
+
- YAML anchors/aliases (`&x` … `*x`) are fine, but a Settings or tool edit of one place gives that place its own
|
|
88
|
+
value; the others keep theirs (#2208). To change every place, edit fleet.yaml itself.
|
|
87
89
|
|
|
88
90
|
**Common classicBot.yaml mistakes:**
|
|
89
91
|
- `allowed_guilds` values should be quoted strings: numbers are accepted, but a Discord ID above 2^53 loses digits as a YAML integer
|
|
@@ -14,6 +14,7 @@ can shape how you look there — **only your own look, and only on the surfaces
|
|
|
14
14
|
| Your name and role line | display name, description | `set_display_name`, `set_description` |
|
|
15
15
|
| Your status stamp | persona emoji | `set_persona_emoji` (see the `persona-emoji` skill) |
|
|
16
16
|
| Your chat | theme: colours, accent, bubbles, font, background picture, working label | `set_web_theme`, `set_web_theme_asset` |
|
|
17
|
+
| The whole page, while your chat is open | your theme's colours on the sidebar, the header, the usage rail (a phone: the drawer, the header, the tabs) — colours only | `set_web_theme` (`page`) |
|
|
17
18
|
| Your face and ring | theme picture and accent | `set_web_theme`, `set_web_theme_asset` |
|
|
18
19
|
| Your identity card | portrait, banner, tagline, bio | `set_web_theme` (`card.*`), `set_web_theme_asset` |
|
|
19
20
|
| Your identity colour | the colour people find you by in the sidebar, and where it shows (name, bar, ring) | `set_web_theme` (`identity`) |
|
|
@@ -23,7 +24,7 @@ can shape how you look there — **only your own look, and only on the surfaces
|
|
|
23
24
|
| Effects in your chat | Canvas Worker animations, and Try cards an admin outside the public link may start | `upload_web_effect`, `apply_web_effect`, `preview_web_effect`, … (see Effects) |
|
|
24
25
|
|
|
25
26
|
None of these tools takes a target: they always act on you. You can't change another instance, the dashboard's own
|
|
26
|
-
chrome, a person's sidebar widget, or a person's custom CSS.
|
|
27
|
+
chrome (beyond your colours on it while your chat is open), a person's sidebar widget, or a person's custom CSS.
|
|
27
28
|
|
|
28
29
|
## For the user: Settings → Web appearance (General, coordinators, full)
|
|
29
30
|
|
|
@@ -40,10 +41,11 @@ of this skill).
|
|
|
40
41
|
|
|
41
42
|
| `what` | Changes | Example |
|
|
42
43
|
|---|---|---|
|
|
43
|
-
| `host` | `themes_shown`, `card_size` (s/m/l), `card_sizes` ({instance: s/m/l}), `colour_places` (name/bar/ring), `colours_off`, `sidebar_widget` ({spec, data}) — null puts one back to its default | `{ what: "host", set: { colour_places: ["name","ring"] } }` |
|
|
44
|
+
| `host` | `themes_shown`, `card_size` (s/m/l), `card_sizes` ({instance: s/m/l}), `page_colours` ({instance: page/chat}), `colour_places` (name/bar/ring), `colours_off`, `sidebar_widget` ({spec, data}) — null puts one back to its default | `{ what: "host", set: { colour_places: ["name","ring"] } }` |
|
|
44
45
|
| `agent_colour` | one agent's colour (`preset:<name>` or `#rrggbb`) and places; null resets each | `{ what: "agent_colour", instance: "atlas", colour: "preset:teal" }` |
|
|
46
|
+
| `page_colours` | where one agent's theme colours go: `page` (the whole page), `chat` (only its chat) or `agent` (its own `page.on`) — as ⋯ → Page colours sets it | `{ what: "page_colours", instance: "atlas", choice: "chat" }` |
|
|
45
47
|
| `banner_focus` | which part of one agent's cropped card banner stays in view: `focus` 0 (top) … 100 (bottom), 50 the centre; it wins over the agent's own `card.bannerFocus`; null follows the agent's again | `{ what: "banner_focus", instance: "atlas", focus: 20 }` |
|
|
46
|
-
| `custom_css` | `save` (with `text`): goes **on trial
|
|
48
|
+
| `custom_css` | `save` (with `text`): goes **on trial**. It waits until they open the dashboard (up to 10 minutes; never opened, it goes back unseen), then goes back by itself 20 s after it is on their screen unless kept (#2198). `keep` (with `trial`: the id `save` returned — a different trial on now, say one they saved on their page since, is refused with `trial_mismatch`, never kept instead; or, kept after that 20 s ran out, it is put back in force as `use` of it), `revert` (the trial), `use` (with `version`: an earlier saved one, at once), `off` | `{ what: "custom_css", action: "save", text: "…" }`; tell them to open the dashboard and look, then `keep` (with that `trial`) only when they say so — a `keep` that comes too late (`not_on_trial`) means use `use` with the version from `get_web_settings` |
|
|
47
49
|
| `mod` | an agent's proposal: `review` (instance → `stage`, `plan`, `plan_hash`), then `install` (stage, plan_hash, `include`: the parts, `target`: the agent); `cancel`, `dismiss`, `uninstall` (id) | review, show the user the plan, install only what they asked for — never custom CSS unasked. A person has one review open at a time: while theirs is open (`mod_review_open`) ask them to finish it; a mod they imported from a file is theirs to install (`mod_not_from_an_agent`) |
|
|
48
50
|
| `effect` | `apply` (instance, id, params?) or `remove` (instance, id?) an effect on a chat | |
|
|
49
51
|
| `ambient` | one agent's ambient effect, set for the user: `ambient` is the same spec as `set_web_ambient`'s (it replaces the one of its kind, and the agent can't change it after); `ambient: null` clears (`which`: `loop` or `click`, default both) | `{ what: "ambient", instance: "atlas", ambient: { preset: "fall", glyphs: ["🌸","❀","✿"] } }` |
|
|
@@ -107,6 +109,17 @@ Typed values only; anything else is refused with `{ errors: [{ path, problem }]
|
|
|
107
109
|
- `show` is a list of `name`, `bar` and `ring` (`[]` for nowhere). Left out, the host's default applies (name, bar and ring).
|
|
108
110
|
- A person's choice for you in the dashboard always wins, field by field, and their Reset brings yours back.
|
|
109
111
|
`get_web_appearance` says which is in force.
|
|
112
|
+
- `page` (#2196): `{ on?: true | false, sidebar?: { light?, dark? } }` — `on: true` puts your colours (bg, surface, text,
|
|
113
|
+
text2, accent; the sidebar's own colour per mode in `sidebar`, else your `bg`) on **the whole page while your chat,
|
|
114
|
+
View, Log or Details is open**: the sidebar, the header, the usage rail; on a phone the drawer, the header and the
|
|
115
|
+
tabs. Colours only: never fonts, pictures or layout, and **AgEnD's status colours** (the Needs you count, the state
|
|
116
|
+
dots, errors, the focus ring — `get_web_theme`'s `status_colors`) are never yours to change. With `on: true` the
|
|
117
|
+
contrast check adds: `text` and `text2` 4.5:1 and `accent` 3:1 on the sidebar, and every status colour 3:1 on the
|
|
118
|
+
sidebar and on `bg`. A person's choice for you (⋯ → **Page colours**: your choice, the whole page, only your chat)
|
|
119
|
+
wins; viewers with agents' themes off or `?safe=1` see the page's own look.
|
|
120
|
+
- For a person's **custom CSS** (#2199): while an agent's Chat, View, Log or Details is open, `<body>` has
|
|
121
|
+
`data-agent="<instance name>"` (none elsewhere), set in the same render as the page — so a person's stylesheet can
|
|
122
|
+
follow the open agent: `body[data-agent="atlas"] { --bg-sidebar: … }`. It is the person's, not yours to set.
|
|
110
123
|
- `bubble`: `{ radius: 0..24, border: "none" | "thin" | "accent" }`.
|
|
111
124
|
- `font`: `"inter"`, `"system"` or `"mono"`.
|
|
112
125
|
- `background`: `{ image: <asset id>, fit: "cover" | "contain", opacity: 0.05..1 }`.
|
|
@@ -157,6 +170,10 @@ screen and layout. `card.bannerFocus` (0 top … 100 bottom; default 50, the cen
|
|
|
157
170
|
near the top at `bannerFocus: 0`. A person's focus (Edit profile, or General's `set_web_settings { what: "banner_focus" }`)
|
|
158
171
|
wins over yours. `preview_web_appearance` draws the banner cropped at its focus, as the page does (an M card).
|
|
159
172
|
|
|
173
|
+
**In your chat** the card is hidden until the person shows it (a card button in the chat header). Shown, the banner sits
|
|
174
|
+
right under the header and they can fold your portrait, tagline and bio away, keeping only the banner. Their choice,
|
|
175
|
+
kept on their device; you cannot change it. So a banner that says who you are on its own reads well in your chat too.
|
|
176
|
+
|
|
160
177
|
## Your identity colour
|
|
161
178
|
|
|
162
179
|
The colour people find you by in the sidebar, drawn on your name, a bar at your row's left edge and/or the ring around
|
|
@@ -84,10 +84,12 @@ View, Settings or Needs you. To invite someone: turn it on, then tell them to se
|
|
|
84
84
|
Settings over the public link.
|
|
85
85
|
|
|
86
86
|
**Web authority (#1939, 2.3 beta).** A signed-in fleet admin's browser can speak as their own Discord or Telegram
|
|
87
|
-
account.
|
|
87
|
+
account. The one row under the composer (bottom left, before the Enter hint) says **Not verified · Authorize**; the
|
|
88
|
+
session menu says **Not verified · Authorize this browser**. Pressing it
|
|
88
89
|
sends a card to that account's DM, saying which browser (device, on this computer or the network, when, until when), with
|
|
89
90
|
**Confirm** and **Not me**. A card left for 5 minutes is marked expired on the card, and the line offers Authorize
|
|
90
|
-
again. Confirm within 5 minutes and the
|
|
91
|
+
again. Confirm within 5 minutes and the session menu says **Verified · speaks as you until …**; the composer's row says
|
|
92
|
+
just **✓ Verified**, with the until-when in its tooltip, its accessible name and a tap. That
|
|
91
93
|
browser's messages then carry the account's authority in their delivery receipt for `max_session_hours` (default 48).
|
|
92
94
|
Not me signs that browser out, also after Confirm, from the same card. At most one card waits per browser, and 3 an hour
|
|
93
95
|
per account. Never on the public link or for a guest; when a browser can't be authorized, the line says why (with a
|
|
@@ -98,6 +100,8 @@ Agents then see that browser's messages as `via web (verified)` and check their
|
|
|
98
100
|
|
|
99
101
|
## Chat
|
|
100
102
|
|
|
103
|
+
A message to a paused agent wakes it through the same delivery path as Discord/Telegram, including ClassicBot. The composer shows **Waking…**; a refused wake explains why, keeps the draft/files and offers **Retry send**. No automatic resend. Stopped agents still require Start. Upload/history/Cancel do not wake agents. Existing guest/public-link send permissions are unchanged.
|
|
104
|
+
|
|
101
105
|
**Sending.** Type and press Enter. A message sent while the agent works waits its turn; `/steer <text>` goes into
|
|
102
106
|
the current turn, `/btw <question>` asks a side question. **Stop reply** (or Esc) interrupts the reply and drops
|
|
103
107
|
queued messages. Text is capped at 16,384 characters; a paste over 4,000 characters becomes a `pasted-….txt`
|
|
@@ -191,7 +195,11 @@ Colour by kind — task (delegate_task) purple, send/query/update teal, report p
|
|
|
191
195
|
read. "×N" = several messages share a line; failed ones belong in Needs you. A `delegate_task` also draws the work: a
|
|
192
196
|
slow-moving purple line, delegator → worker, **in progress** until the worker's `report_result` with the same
|
|
193
197
|
correlation id comes back (then one pink line returns); none after 4 h fades as **no report yet**. Reloads and the
|
|
194
|
-
public link show the open ones. Every line ends on a card or a folded team's box.
|
|
198
|
+
public link show the open ones. Every line ends on a card or a folded team's box. #2182: lines are routed card to card
|
|
199
|
+
by libavoid (libavoid-js 0.4.5, LGPL) in a worker — around cards, through gaps in team borders, never along a border or
|
|
200
|
+
across a team's name, lines sharing a stretch drawn apart; zoomed out, or where the router can't run (no WebAssembly,
|
|
201
|
+
an old browser), they follow the gaps between teams as before. The worker alone may run WebAssembly and reaches nothing
|
|
202
|
+
(its own CSP); the dashboard's CSP is unchanged. No message
|
|
195
203
|
text is ever shown; instances with `cross_instance_visibility: hidden` are left out. On a public link it refreshes
|
|
196
204
|
every 5 s.
|
|
197
205
|
|
|
@@ -215,8 +223,13 @@ to that instance's Log).
|
|
|
215
223
|
- **Log** — [the Log tab](#the-log-tab).
|
|
216
224
|
- **Details** — Configuration (display name, description, directory, bound to, tags; "Read only — change it in
|
|
217
225
|
Settings." with **Edit in Settings**), Runtime (backend, model, effort, cost, context, 5 h and 7 d rate), Recent
|
|
218
|
-
activity, its identity card and widget. The ⋯ menu: Start / Restart / Stop instance, Pause / Wake, Colour…,
|
|
226
|
+
activity, its identity card and widget. The ⋯ menu: Start / Restart / Stop instance, Pause / Wake, Colour…, **Page
|
|
227
|
+
colours** (#2196: the agent's choice / on the whole page / only its chat — host prefs `theme.pageByInstance`), and
|
|
219
228
|
the theme lock/reset.
|
|
229
|
+
- **Page colours (#2196):** an agent's theme with `page.on` (or a person's "on the whole page") colours the sidebar,
|
|
230
|
+
the header and the usage rail (a phone: drawer, header, tabs) while that agent's Chat/View/Log/Details is open —
|
|
231
|
+
colours only; status colours (Needs you count, state dots, errors, focus ring) never change. The header follows the
|
|
232
|
+
page, not the chat. Off with agents' themes off or `?safe=1`.
|
|
220
233
|
|
|
221
234
|
Phone layout: bottom tabs Chat, Needs you, Fleet, Settings. Chat is current on any of an agent's pages and goes to its
|
|
222
235
|
chat; View, Log and Details are the switch under the header.
|
|
@@ -285,6 +298,8 @@ running; kiro shows fleet events only; other backends say they have no readable
|
|
|
285
298
|
|
|
286
299
|
## Settings
|
|
287
300
|
|
|
301
|
+
**Connections → Retry now** retries a disconnected connection without a fleet restart; a running login is reused. Startup retries continue with a five-minute cap. Local admin only, unavailable over public links. It changes no token or binding; refresh to read the later result.
|
|
302
|
+
|
|
288
303
|
Tabs (`/settings/<tab>`): **Preferences**, **Web appearance**, **Agents**, **Connections**, **ClassicBot**,
|
|
289
304
|
**General**, **Web**, **Developer**. Header: version, **Setup wizard**, **Help**.
|
|
290
305
|
|
|
@@ -292,7 +307,10 @@ Tabs (`/settings/<tab>`): **Preferences**, **Web appearance**, **Agents**, **Con
|
|
|
292
307
|
**Stage change** (General/Web: **Review changes**) adds it to the bar **Changes not applied yet**, which shows the
|
|
293
308
|
cost — **Immediately**, **Restart this Agent** or **Restart AgEnD** — then **Apply changes** or **Discard**.
|
|
294
309
|
Confirmations (e.g. opening access) are asked at Apply. A change that loosens access waits for a fleet admin to confirm
|
|
295
|
-
in the General chat ("Waiting for confirmation", **Withdraw**)
|
|
310
|
+
in the General chat ("Waiting for confirmation", **Withdraw**) — unless the browser is web-verified (#2170): an
|
|
311
|
+
account that is a fleet admin of every connection the change affects, on their platform, confirms it by its own Apply
|
|
312
|
+
("Confirmed by your account"; General gets a notice; every check runs again at execution). Not for a guest, the public
|
|
313
|
+
link, an unverified browser or a change that needs the host CLI. After a failure, unapplied changes are staged again
|
|
296
314
|
(secrets must be re-entered). **Restart AgEnD** restarts every agent. Preferences and Web appearance save directly.
|
|
297
315
|
|
|
298
316
|
**Preferences** — follows you across devices unless marked:
|
|
@@ -472,6 +490,10 @@ fleet.yaml (Developer tab, or the file) and `agend reload`.
|
|
|
472
490
|
|
|
473
491
|
### Canvas Worker playback diagnostics
|
|
474
492
|
|
|
493
|
+
The effect player loads only when there is something to play: the open chat has a placed effect, the person chose a
|
|
494
|
+
personal effect, or a Try card is shown (#2193). Before that, nothing of it is in the page, by design. Ambient effects
|
|
495
|
+
and custom CSS never need it.
|
|
496
|
+
|
|
475
497
|
If an effect cannot play, the Chat notice and Effects dialog show its local refusal code. A failed Try retains its stop
|
|
476
498
|
code on the offer card; the browser console also names refusals. Include the code when reporting a problem. Long chat
|
|
477
499
|
history is checked separately from the bounded set of current paint holes. Moving the pointer away does not stop Try;
|
|
@@ -201,6 +201,8 @@ export interface IncidentEventSource {
|
|
|
201
201
|
/** Real daemons buffer `pty_error` raised by the startup scan until the lifecycle can handle it. */
|
|
202
202
|
holdStartupIncidents?(): void;
|
|
203
203
|
releaseStartupIncidents?(): void;
|
|
204
|
+
/** Reconsider a cooldown-suppressed MCP revival through daemon liveness/idle gates. */
|
|
205
|
+
deferMcpRestart?(delayMs: number): void;
|
|
204
206
|
}
|
|
205
207
|
/** Arguments accepted by handleCreate — mirrors CreateInstanceArgs in outbound-schemas.ts
|
|
206
208
|
* plus internal-only fields forwarded by deploy_template (profile-derived). */
|
|
@@ -696,8 +696,10 @@ export class InstanceLifecycle {
|
|
|
696
696
|
const incident = this.mcpIncident(name);
|
|
697
697
|
const generation = ++incident.gen;
|
|
698
698
|
incident.deathNoticeSent = false;
|
|
699
|
-
this.ctx.eventLog?.insert(name, "mcp_died", { pid: data.pid });
|
|
700
|
-
this.ctx.logger.error({ name, pid: data.pid
|
|
699
|
+
this.ctx.eventLog?.insert(name, "mcp_died", { pid: data.pid, ...(data.neverConnected ? { neverConnected: true } : {}) });
|
|
700
|
+
this.ctx.logger.error({ name, pid: data.pid, neverConnected: data.neverConnected === true }, data.neverConnected
|
|
701
|
+
? "MCP server never connected — instance cannot use agend tools"
|
|
702
|
+
: "MCP server died — instance cannot use agend tools");
|
|
701
703
|
this.ctx.webhookEmit("mcp_died", name, { pid: data.pid });
|
|
702
704
|
// Auth outranks MCP: when the CLI lost authentication, "MCP server died"
|
|
703
705
|
// is a symptom and the fix is /login, not a restart. The daemon flags a
|
|
@@ -804,13 +806,16 @@ export class InstanceLifecycle {
|
|
|
804
806
|
// The daemon object dies with the restart it asks for, so the loop guard
|
|
805
807
|
// lives here: if the previous auto-restart was under the cooldown, the new
|
|
806
808
|
// MCP server evidently died right back (broken install, OOM pressure) and
|
|
807
|
-
// another attempt would just cycle the instance.
|
|
808
|
-
//
|
|
809
|
+
// another immediate attempt would just cycle the instance. Keep a bounded
|
|
810
|
+
// reconsideration on the daemon: a one-shot suppression strands this pid
|
|
811
|
+
// forever because later health ticks dedupe the already reported death.
|
|
809
812
|
const last = this.mcpAutoRestartAt.get(name) ?? 0;
|
|
810
813
|
const now = Date.now();
|
|
811
814
|
if (now - last < InstanceLifecycle.MCP_AUTO_RESTART_COOLDOWN_MS) {
|
|
812
|
-
|
|
813
|
-
this.ctx.
|
|
815
|
+
const retryAfterMs = InstanceLifecycle.MCP_AUTO_RESTART_COOLDOWN_MS - (now - last);
|
|
816
|
+
this.ctx.eventLog?.insert(name, "mcp_auto_restart_suppressed", { trigger: data.trigger, retryAfterMs });
|
|
817
|
+
this.ctx.logger.warn({ name, trigger: data.trigger, retryAfterMs }, "MCP auto-restart deferred — will reconsider after the cooldown with liveness and idle checks");
|
|
818
|
+
daemon.deferMcpRestart?.(retryAfterMs);
|
|
814
819
|
return;
|
|
815
820
|
}
|
|
816
821
|
this.mcpAutoRestartAt.set(name, now);
|