@songsid/agend 2.1.12-beta.9 → 2.2.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/README.zh-TW.md +2 -2
- package/dist/auth/one-time-code.d.ts +19 -0
- package/dist/auth/one-time-code.js +49 -0
- package/dist/auth/one-time-code.js.map +1 -0
- package/dist/auth-api.d.ts +52 -0
- package/dist/auth-api.js +346 -0
- package/dist/auth-api.js.map +1 -0
- package/dist/backend/claude-code.d.ts +4 -0
- package/dist/backend/claude-code.js +97 -0
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex.js +59 -30
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/kiro-agent.d.ts +66 -0
- package/dist/backend/kiro-agent.js +302 -0
- package/dist/backend/kiro-agent.js.map +1 -0
- package/dist/backend/kiro-identity.d.ts +80 -0
- package/dist/backend/kiro-identity.js +537 -0
- package/dist/backend/kiro-identity.js.map +1 -0
- package/dist/backend/kiro-v2-store-worker.d.ts +1 -0
- package/dist/backend/kiro-v2-store-worker.js +87 -0
- package/dist/backend/kiro-v2-store-worker.js.map +1 -0
- package/dist/backend/kiro-v2-store.d.ts +54 -0
- package/dist/backend/kiro-v2-store.js +131 -0
- package/dist/backend/kiro-v2-store.js.map +1 -0
- package/dist/backend/kiro-v3-identity.d.ts +5 -0
- package/dist/backend/kiro-v3-identity.js +22 -0
- package/dist/backend/kiro-v3-identity.js.map +1 -1
- package/dist/backend/kiro.d.ts +83 -7
- package/dist/backend/kiro.js +418 -91
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +45 -3
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +1 -0
- package/dist/channel/adapters/discord.js +29 -10
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +1 -0
- package/dist/channel/adapters/telegram.js +13 -1
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/types.d.ts +9 -1
- package/dist/classic-channel-manager.d.ts +18 -10
- package/dist/classic-channel-manager.js +45 -18
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +225 -127
- package/dist/cli.js.map +1 -1
- package/dist/command-table.d.ts +5 -3
- package/dist/command-table.js +29 -27
- package/dist/command-table.js.map +1 -1
- package/dist/config-validator.js +46 -0
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -1
- package/dist/connection-secrets.d.ts +6 -0
- package/dist/connection-secrets.js +4 -0
- package/dist/connection-secrets.js.map +1 -1
- package/dist/daemon.d.ts +89 -4
- package/dist/daemon.js +661 -77
- package/dist/daemon.js.map +1 -1
- package/dist/darwin-memory.d.ts +6 -1
- package/dist/darwin-memory.js +17 -6
- package/dist/darwin-memory.js.map +1 -1
- package/dist/delivery-consumed-watch.d.ts +85 -0
- package/dist/delivery-consumed-watch.js +244 -0
- package/dist/delivery-consumed-watch.js.map +1 -0
- package/dist/delivery-outbox.d.ts +61 -0
- package/dist/delivery-outbox.js +120 -2
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-reconciliation.d.ts +14 -5
- package/dist/delivery-reconciliation.js +27 -4
- package/dist/delivery-reconciliation.js.map +1 -1
- package/dist/delivery-reconciliation.test.js +35 -1
- package/dist/delivery-reconciliation.test.js.map +1 -1
- package/dist/event-loop-watch.d.ts +28 -0
- package/dist/event-loop-watch.js +75 -3
- package/dist/event-loop-watch.js.map +1 -1
- package/dist/fleet-context.d.ts +22 -2
- package/dist/fleet-level-config.d.ts +2 -2
- package/dist/fleet-level-config.js +6 -1
- package/dist/fleet-level-config.js.map +1 -1
- package/dist/fleet-manager.d.ts +293 -12
- package/dist/fleet-manager.js +2364 -449
- package/dist/fleet-manager.js.map +1 -1
- package/dist/host-memory.d.ts +4 -0
- package/dist/host-memory.js.map +1 -1
- package/dist/instance-config-impact.js +5 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +10 -5
- package/dist/instance-lifecycle.js +162 -53
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +150 -16
- package/dist/locale.js.map +1 -1
- package/dist/login-controller.d.ts +2 -0
- package/dist/login-controller.js +17 -5
- package/dist/login-controller.js.map +1 -1
- package/dist/memory-pressure.d.ts +7 -8
- package/dist/memory-pressure.js +76 -15
- package/dist/memory-pressure.js.map +1 -1
- package/dist/monotonic-budget.d.ts +2 -0
- package/dist/monotonic-budget.js +28 -0
- package/dist/monotonic-budget.js.map +1 -0
- package/dist/needs-you-hub.d.ts +114 -0
- package/dist/needs-you-hub.js +370 -0
- package/dist/needs-you-hub.js.map +1 -0
- package/dist/needs-you-live.d.ts +116 -0
- package/dist/needs-you-live.js +228 -0
- package/dist/needs-you-live.js.map +1 -0
- package/dist/needs-you.d.ts +132 -0
- package/dist/needs-you.js +164 -0
- package/dist/needs-you.js.map +1 -0
- package/dist/node-version-guard.d.ts +30 -0
- package/dist/node-version-guard.js +50 -0
- package/dist/node-version-guard.js.map +1 -0
- package/dist/operator-control-paths.d.ts +4 -0
- package/dist/operator-control-paths.js +24 -0
- package/dist/operator-control-paths.js.map +1 -0
- package/dist/outbound-handlers.d.ts +2 -0
- package/dist/outbound-handlers.js +9 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +5 -5
- package/dist/profile-control.js +4 -20
- package/dist/profile-control.js.map +1 -1
- package/dist/public-web-gateway.d.ts +18 -0
- package/dist/public-web-gateway.js +141 -0
- package/dist/public-web-gateway.js.map +1 -0
- package/dist/public-web-link.d.ts +53 -0
- package/dist/public-web-link.js +175 -0
- package/dist/public-web-link.js.map +1 -0
- package/dist/quickstart-api.d.ts +8 -1
- package/dist/quickstart-api.js +86 -48
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +1 -0
- package/dist/quickstart.js +6 -2
- package/dist/quickstart.js.map +1 -1
- package/dist/scheduler/db.d.ts +7 -1
- package/dist/scheduler/db.js +38 -0
- package/dist/scheduler/db.js.map +1 -1
- package/dist/scheduler/index.d.ts +1 -1
- package/dist/scheduler/retry-label.d.ts +11 -0
- package/dist/scheduler/retry-label.js +24 -0
- package/dist/scheduler/retry-label.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +55 -2
- package/dist/scheduler/scheduler.js +220 -8
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/scheduler/types.d.ts +22 -0
- package/dist/scheduler/types.js.map +1 -1
- package/dist/secret-store.d.ts +5 -0
- package/dist/secret-store.js +20 -0
- package/dist/secret-store.js.map +1 -1
- package/dist/service-activation.d.ts +110 -0
- package/dist/service-activation.js +302 -0
- package/dist/service-activation.js.map +1 -0
- package/dist/service-installer.d.ts +7 -0
- package/dist/service-installer.js +7 -4
- package/dist/service-installer.js.map +1 -1
- package/dist/service-restart-selection.d.ts +6 -5
- package/dist/service-restart-selection.js +6 -5
- package/dist/service-restart-selection.js.map +1 -1
- package/dist/settings-api.d.ts +10 -2
- package/dist/settings-api.js +175 -72
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-baseline.d.ts +20 -0
- package/dist/settings-baseline.js +104 -0
- package/dist/settings-baseline.js.map +1 -0
- package/dist/settings-change.d.ts +21 -0
- package/dist/settings-change.js +133 -0
- package/dist/settings-change.js.map +1 -0
- package/dist/settings-confirmation.d.ts +105 -0
- package/dist/settings-confirmation.js +232 -0
- package/dist/settings-confirmation.js.map +1 -0
- package/dist/settings-control.d.ts +41 -0
- package/dist/settings-control.js +294 -0
- package/dist/settings-control.js.map +1 -0
- package/dist/settings-effect.d.ts +24 -0
- package/dist/settings-effect.js +169 -0
- package/dist/settings-effect.js.map +1 -0
- package/dist/settings-http-confirmation.d.ts +29 -0
- package/dist/settings-http-confirmation.js +123 -0
- package/dist/settings-http-confirmation.js.map +1 -0
- package/dist/settings-instance-patch.d.ts +4 -0
- package/dist/settings-instance-patch.js +26 -0
- package/dist/settings-instance-patch.js.map +1 -0
- package/dist/settings-request-capability.d.ts +16 -0
- package/dist/settings-request-capability.js +32 -0
- package/dist/settings-request-capability.js.map +1 -0
- package/dist/settings-transaction.d.ts +65 -0
- package/dist/settings-transaction.js +223 -0
- package/dist/settings-transaction.js.map +1 -0
- package/dist/setup-auth.d.ts +10 -18
- package/dist/setup-auth.js +14 -38
- package/dist/setup-auth.js.map +1 -1
- package/dist/setup-form.d.ts +1 -1
- package/dist/setup-form.js +75 -18
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-guide.d.ts +13 -0
- package/dist/setup-guide.js +25 -0
- package/dist/setup-guide.js.map +1 -0
- package/dist/setup-host.d.ts +16 -0
- package/dist/setup-host.js +197 -32
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +3 -0
- package/dist/setup-wizard.js.map +1 -1
- package/dist/slash-authz.d.ts +17 -3
- package/dist/slash-authz.js +5 -0
- package/dist/slash-authz.js.map +1 -1
- package/dist/spawn-gate.js +3 -3
- package/dist/spawn-gate.js.map +1 -1
- package/dist/statusline-watcher.d.ts +5 -0
- package/dist/statusline-watcher.js +2 -0
- package/dist/statusline-watcher.js.map +1 -1
- package/dist/steer-capability.d.ts +6 -0
- package/dist/steer-capability.js +8 -0
- package/dist/steer-capability.js.map +1 -1
- package/dist/sync-work-attribution.d.ts +14 -0
- package/dist/sync-work-attribution.js +43 -8
- package/dist/sync-work-attribution.js.map +1 -1
- package/dist/tips.js +10 -5
- package/dist/tips.js.map +1 -1
- package/dist/tmux-control.d.ts +35 -5
- package/dist/tmux-control.js +291 -57
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.d.ts +20 -6
- package/dist/tmux-manager.js +90 -47
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.d.ts +59 -0
- package/dist/tmux-read.js +213 -0
- package/dist/tmux-read.js.map +1 -0
- package/dist/topic-commands.d.ts +21 -10
- package/dist/topic-commands.js +191 -58
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-delta-reader.js +2 -1
- package/dist/transcript-delta-reader.js.map +1 -1
- package/dist/tunnel/cloudflared-install.d.ts +2 -0
- package/dist/tunnel/cloudflared-install.js +1 -1
- package/dist/tunnel/cloudflared-install.js.map +1 -1
- package/dist/tunnel/purpose-lane.d.ts +14 -0
- package/dist/tunnel/purpose-lane.js +43 -0
- package/dist/tunnel/purpose-lane.js.map +1 -0
- package/dist/turn-reply-guard.d.ts +2 -0
- package/dist/turn-reply-guard.js +10 -1
- package/dist/turn-reply-guard.js.map +1 -1
- package/dist/types.d.ts +33 -0
- package/dist/ui/app.html +18 -0
- package/dist/ui/chat-render.js +478 -0
- package/dist/ui/chat-store.js +289 -0
- package/dist/ui/chat-strings.js +69 -0
- package/dist/ui/chat-thread.js +209 -0
- package/dist/ui/chat-tour.js +116 -0
- package/dist/ui/fleet-org.js +142 -0
- package/dist/ui/panel-chat.js +418 -0
- package/dist/ui/panel-fleet.js +413 -0
- package/dist/ui/panel-needs.js +202 -0
- package/dist/ui/panel-settings.js +750 -0
- package/dist/ui/preview.js +266 -0
- package/dist/ui/settings-apply.js +239 -0
- package/dist/ui/settings-confirm.js +186 -0
- package/dist/ui/settings-dialogs.js +546 -0
- package/dist/ui/settings-model.js +277 -0
- package/dist/ui/settings-strings.js +652 -0
- package/dist/ui/settings-wizard.js +140 -0
- package/dist/ui/shared/agend-auth.js +93 -0
- package/dist/ui/shared/app-ctx.js +80 -0
- package/dist/ui/shared/app-html.js +9 -0
- package/dist/ui/shared/app-i18n.js +95 -0
- package/dist/ui/shared/app-nav.js +73 -0
- package/dist/ui/shared/app-needs.js +114 -0
- package/dist/ui/shared/app-route.js +73 -0
- package/dist/ui/shared/app-session.js +66 -0
- package/dist/ui/shared/app-shell.js +344 -0
- package/dist/ui/shared/app-store.js +51 -0
- package/dist/ui/shared/app-stream.js +201 -0
- package/dist/ui/shared/app.css +676 -0
- package/dist/ui/shared/app.js +88 -0
- package/dist/ui/shared/fonts/OFL.txt +92 -0
- package/dist/ui/shared/fonts/README.md +21 -0
- package/dist/ui/shared/fonts/inter.woff2 +0 -0
- package/dist/ui/shared/htm.module.js +1 -0
- package/dist/ui/shared/panel-view.js +655 -0
- package/dist/ui/shared/preact-hooks.module.js +2 -0
- package/dist/ui/shared/preact.module.js +2 -0
- package/dist/ui/shared/signin.js +130 -0
- package/dist/ui/shared/theme.js +29 -0
- package/dist/ui/shared/tokens.css +153 -0
- package/dist/ui/shared/ui-confirm.js +43 -0
- package/dist/ui/shared/ui-dialog.js +45 -0
- package/dist/ui/shared/ui-icons.js +61 -0
- package/dist/ui/shared/ui-menu.js +39 -0
- package/dist/ui/shared/ui-states.js +20 -0
- package/dist/ui/shared/ui-toast.js +18 -0
- package/dist/ui/shared/vendor/htm.LICENSE +202 -0
- package/dist/ui/shared/vendor/preact.LICENSE +21 -0
- package/dist/ui/shared/vendor/vendor.json +39 -0
- package/dist/ui/shared/view-strings.js +309 -0
- package/dist/ui/signin.html +51 -0
- package/dist/update-check.d.ts +6 -2
- package/dist/update-check.js +12 -3
- package/dist/update-check.js.map +1 -1
- package/dist/update-install.d.ts +71 -0
- package/dist/update-install.js +162 -0
- package/dist/update-install.js.map +1 -0
- package/dist/upgrade-notices.d.ts +17 -0
- package/dist/upgrade-notices.js +93 -0
- package/dist/upgrade-notices.js.map +1 -0
- package/dist/usage/statusline-usage.d.ts +2 -0
- package/dist/usage/statusline-usage.js +14 -10
- package/dist/usage/statusline-usage.js.map +1 -1
- package/dist/view-api.d.ts +6 -1
- package/dist/view-api.js +62 -51
- package/dist/view-api.js.map +1 -1
- package/dist/web-api.d.ts +71 -14
- package/dist/web-api.js +492 -77
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.d.ts +71 -27
- package/dist/web-auth.js +169 -69
- package/dist/web-auth.js.map +1 -1
- package/dist/web-body.d.ts +3 -0
- package/dist/web-body.js +55 -0
- package/dist/web-body.js.map +1 -0
- package/dist/web-channel-echo.d.ts +9 -0
- package/dist/web-channel-echo.js +55 -0
- package/dist/web-channel-echo.js.map +1 -0
- package/dist/web-chat-history.d.ts +125 -0
- package/dist/web-chat-history.js +184 -0
- package/dist/web-chat-history.js.map +1 -0
- package/dist/web-continuation.d.ts +7 -0
- package/dist/web-continuation.js +22 -0
- package/dist/web-continuation.js.map +1 -0
- package/dist/web-host-guard.d.ts +34 -0
- package/dist/web-host-guard.js +57 -1
- package/dist/web-host-guard.js.map +1 -1
- package/dist/web-login.d.ts +72 -0
- package/dist/web-login.js +132 -0
- package/dist/web-login.js.map +1 -0
- package/dist/web-org.d.ts +55 -0
- package/dist/web-org.js +67 -0
- package/dist/web-org.js.map +1 -0
- package/dist/web-preview.d.ts +77 -0
- package/dist/web-preview.js +240 -0
- package/dist/web-preview.js.map +1 -0
- package/dist/web-request-context.d.ts +10 -0
- package/dist/web-request-context.js +13 -0
- package/dist/web-request-context.js.map +1 -0
- package/dist/web-session.d.ts +167 -0
- package/dist/web-session.js +389 -0
- package/dist/web-session.js.map +1 -0
- package/dist/web-shell-routes.d.ts +59 -0
- package/dist/web-shell-routes.js +96 -0
- package/dist/web-shell-routes.js.map +1 -0
- package/dist/web-upload.d.ts +183 -0
- package/dist/web-upload.js +468 -0
- package/dist/web-upload.js.map +1 -0
- package/dist/website-tips-renderer.d.ts +2 -2
- package/dist/website-tips-renderer.js +3 -3
- package/dist/website-tips-renderer.js.map +1 -1
- package/package.json +8 -5
- package/scripts/preinstall-guard.cjs +36 -0
- package/dist/ui/dashboard.html +0 -774
- package/dist/ui/settings.html +0 -2165
- package/dist/ui/view.html +0 -1139
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// #1366: the first sign-in tour, in the app shell (#1408). Shown once on this device (agend_tour_done), dismissed by
|
|
2
|
+
// Got it, Skip or Esc, and replayed from Tour in the sidebar. A card that outlines one thing at a time: no overlay,
|
|
3
|
+
// nothing blocked, and no style attribute — the outline is a class (#1300). When this browser's storage cannot be read
|
|
4
|
+
// it is not shown at all: a tour that comes back on every load is worse than none.
|
|
5
|
+
//
|
|
6
|
+
// Esc order: the phone drawer covers the card, so it closes first (the shell); then the tour; only then may Esc reach
|
|
7
|
+
// the chat and stop a reply. The Esc that closed the tour is spent: its key repeats (a held key) must not go on to stop
|
|
8
|
+
// the agent (#1369 review).
|
|
9
|
+
import { t, onLang } from "/assets/app-i18n.js";
|
|
10
|
+
import { shellStore, closeDrawer } from "/assets/app-shell.js";
|
|
11
|
+
import "./chat-strings.js";
|
|
12
|
+
|
|
13
|
+
const TOUR_KEY = "agend_tour_done";
|
|
14
|
+
const byId = (id) => document.getElementById(id);
|
|
15
|
+
// On a phone the instance list is in the closed drawer: the tour outlines what opens it (☰), and for "needs you" the
|
|
16
|
+
// bottom tab's badge (#1408 step 5: retargeted to the app's shell).
|
|
17
|
+
const narrow = () => typeof matchMedia === "function" && matchMedia("(max-width: 899px)").matches;
|
|
18
|
+
const STEPS = [
|
|
19
|
+
{ text: "chat.tour1", spot: () => (narrow() ? byId("sbOpen") : byId("instanceList")) },
|
|
20
|
+
{ text: "chat.tour2", spot: () => byId("main") },
|
|
21
|
+
{ text: "chat.tour3", spot: () => byId("attachBtn") },
|
|
22
|
+
{ text: "chat.tour4", spot: () => { const stop = byId("stopBtn"); return stop && !stop.hidden ? stop : byId("sendBtn"); } },
|
|
23
|
+
{ text: "chat.tour5", spot: () => (narrow() ? document.querySelector(".tabs .tab-badge") || byId("sbOpen")
|
|
24
|
+
: document.querySelector(".badge-await") || byId("instanceList")) },
|
|
25
|
+
];
|
|
26
|
+
let at = -1, spot = null, returnTo = null, escHeld = false, installed = false;
|
|
27
|
+
|
|
28
|
+
export function tourDone() { try { return localStorage.getItem(TOUR_KEY) === "1"; } catch { return true; } }
|
|
29
|
+
export function tourStep() { return at; }
|
|
30
|
+
|
|
31
|
+
export function startTour() {
|
|
32
|
+
// Replayed from the drawer: the drawer closes first (focus goes back to ☰), so the card is seen.
|
|
33
|
+
closeDrawer();
|
|
34
|
+
if (at < 0) returnTo = document.activeElement;
|
|
35
|
+
show(0);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** The current step's outline follows a redraw (a new badge, Send swapped for Stop reply) — same card, same focus. */
|
|
39
|
+
export function refreshTourSpot() {
|
|
40
|
+
if (at < 0) return;
|
|
41
|
+
const next = STEPS[at].spot() || null;
|
|
42
|
+
if (next === spot && (!next || next.classList.contains("tour-spot"))) return;
|
|
43
|
+
if (spot) spot.classList.remove("tour-spot");
|
|
44
|
+
spot = next;
|
|
45
|
+
if (spot) spot.classList.add("tour-spot");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function show(i) {
|
|
49
|
+
if (i < 0 || i >= STEPS.length) return;
|
|
50
|
+
at = i;
|
|
51
|
+
if (spot) spot.classList.remove("tour-spot");
|
|
52
|
+
spot = STEPS[i].spot() || null;
|
|
53
|
+
if (spot) spot.classList.add("tour-spot");
|
|
54
|
+
let card = byId("tour");
|
|
55
|
+
if (!card) {
|
|
56
|
+
card = document.createElement("section"); card.id = "tour"; card.className = "tour";
|
|
57
|
+
card.setAttribute("role", "dialog"); card.setAttribute("aria-labelledby", "tourTitle");
|
|
58
|
+
card.addEventListener("click", onCardClick);
|
|
59
|
+
document.body.appendChild(card);
|
|
60
|
+
}
|
|
61
|
+
card.textContent = "";
|
|
62
|
+
const title = document.createElement("h2"); title.id = "tourTitle"; title.textContent = t("chat.tourTitle");
|
|
63
|
+
const text = document.createElement("p"); text.className = "tour-text"; text.setAttribute("aria-live", "polite"); text.textContent = t(STEPS[i].text);
|
|
64
|
+
const foot = document.createElement("div"); foot.className = "tour-foot";
|
|
65
|
+
const count = document.createElement("span"); count.className = "tour-count"; count.textContent = t("chat.tourStep", i + 1, STEPS.length);
|
|
66
|
+
const button = (label, act, arg, cls) => {
|
|
67
|
+
const b = document.createElement("button"); b.type = "button"; b.className = `btn btn-sm ${cls}`; b.dataset.tour = act;
|
|
68
|
+
if (arg != null) b.dataset.arg = String(arg);
|
|
69
|
+
b.textContent = t(label); return b;
|
|
70
|
+
};
|
|
71
|
+
foot.append(count);
|
|
72
|
+
if (i < STEPS.length - 1) foot.append(button("chat.tourSkip", "end", null, "btn-ghost"));
|
|
73
|
+
if (i > 0) foot.append(button("chat.tourBack", "move", -1, "btn-ghost"));
|
|
74
|
+
const next = i < STEPS.length - 1 ? button("chat.tourNext", "move", 1, "btn-primary") : button("chat.tourDone", "end", null, "btn-primary");
|
|
75
|
+
foot.append(next);
|
|
76
|
+
card.append(title, text, foot);
|
|
77
|
+
next.focus();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function onCardClick(e) {
|
|
81
|
+
const b = e.target && e.target.closest ? e.target.closest("[data-tour]") : null;
|
|
82
|
+
if (!b) return;
|
|
83
|
+
if (b.dataset.tour === "move") show(at + Number(b.dataset.arg));
|
|
84
|
+
else endTour();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function endTour() {
|
|
88
|
+
try { localStorage.setItem(TOUR_KEY, "1"); } catch { /* this page only */ }
|
|
89
|
+
at = -1;
|
|
90
|
+
if (spot) spot.classList.remove("tour-spot");
|
|
91
|
+
spot = null;
|
|
92
|
+
const card = byId("tour"); if (card) card.remove();
|
|
93
|
+
if (returnTo && document.contains(returnTo) && typeof returnTo.focus === "function") returnTo.focus();
|
|
94
|
+
returnTo = null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Capture-phase Esc: it runs before the shell's own key handling, so a tour Esc never reaches the chat. */
|
|
98
|
+
export function onTourKey(e) {
|
|
99
|
+
if (e.key !== "Escape" || e.isComposing) return;
|
|
100
|
+
if (escHeld) {
|
|
101
|
+
if (e.repeat) { e.preventDefault(); e.stopPropagation(); return; }
|
|
102
|
+
escHeld = false;
|
|
103
|
+
}
|
|
104
|
+
if (shellStore.get().drawer) return; // the drawer is on top: the shell closes it first
|
|
105
|
+
if (at >= 0) { e.preventDefault(); e.stopPropagation(); endTour(); escHeld = true; }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Once per page: the key handler, the language follow-up, and the first showing on a device that has not seen it. */
|
|
109
|
+
export function installTour() {
|
|
110
|
+
if (installed) return;
|
|
111
|
+
installed = true;
|
|
112
|
+
document.addEventListener("keydown", onTourKey, true);
|
|
113
|
+
onLang(() => { if (at >= 0) show(at); });
|
|
114
|
+
// Shown first on the chat (it points at the chat's own controls), never over View or another panel.
|
|
115
|
+
if (!tourDone() && /^\/ui(\/chat\/|$)/.test(location.pathname)) setTimeout(startTour, 0);
|
|
116
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// #1389: Fleet → Org chart (/ui/fleet/org) — General at the top, then the teams fleet.yaml defines, then their
|
|
2
|
+
// instances; each node names the instance, says what it does, which backend and model it runs, how it is doing now,
|
|
3
|
+
// and links to its thread. Behind the session gate (/ui/js/), imported by the Fleet panel.
|
|
4
|
+
//
|
|
5
|
+
// Presentation only (the user's Discord-first rule): nothing is edited here, and nothing here is a source of truth.
|
|
6
|
+
// The structure is GET /ui/org (read when the tab is opened — a person's navigation); the live state is the app store
|
|
7
|
+
// the shell already keeps from the stream (status, activity, `needs`), so the chart moves with it and reads nothing
|
|
8
|
+
// on a timer (#1374).
|
|
9
|
+
import { html } from "/assets/app-html.js";
|
|
10
|
+
import { t, register } from "/assets/app-i18n.js";
|
|
11
|
+
import { chatPath } from "/assets/app-route.js";
|
|
12
|
+
import { Empty, Skeleton } from "/assets/ui-states.js";
|
|
13
|
+
import { Icon } from "/assets/ui-icons.js";
|
|
14
|
+
|
|
15
|
+
register("org", {
|
|
16
|
+
en: {
|
|
17
|
+
title: "Org chart", general: "General", unteamed: "Not in a team", members: "{0} members", member: "1 member", instances: "{0} instances", instance: "1 instance",
|
|
18
|
+
needs: "Needs you", working: "Working", idle: "Idle", stuck: "Looks stuck", paused: "Paused", stopped: "Stopped", crashed: "Crashed",
|
|
19
|
+
missing: "Not in the fleet", thread_discord: "Discord thread", thread_telegram: "Telegram topic", openChat: "Open chat",
|
|
20
|
+
classic: "ClassicBot room", empty: "No instances yet", emptyHint: "Instances and teams show here once the fleet has them.",
|
|
21
|
+
noTeams: "No teams yet — define them in Fleet → Teams to group the chart.", newTab: "(opens in a new tab)",
|
|
22
|
+
},
|
|
23
|
+
"zh-TW": {
|
|
24
|
+
title: "組織圖", general: "General", unteamed: "未加入 team", members: "{0} 名成員", member: "1 名成員", instances: "{0} 個 instance", instance: "1 個 instance",
|
|
25
|
+
needs: "等你回應", working: "工作中", idle: "閒置", stuck: "似乎卡住", paused: "已暫停", stopped: "已停止", crashed: "已當掉",
|
|
26
|
+
missing: "不在 fleet 中", thread_discord: "Discord 討論串", thread_telegram: "Telegram topic", openChat: "開啟聊天",
|
|
27
|
+
classic: "ClassicBot 頻道", empty: "還沒有 instance", emptyHint: "fleet 有 instance 和 team 後會顯示在這裡。",
|
|
28
|
+
noTeams: "還沒有 team——到 Fleet → Teams 定義後,組織圖會依 team 分組。", newTab: "(在新分頁開啟)",
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
const to = (k, ...v) => t(`org.${k}`, ...v);
|
|
32
|
+
const count = (one, many, n) => (n === 1 ? to(one) : to(many, n));
|
|
33
|
+
|
|
34
|
+
/** The states a node can show, most pressing first (a team's summary lists them in this order). */
|
|
35
|
+
export const ORG_STATES = ["needs", "crashed", "stuck", "working", "idle", "paused", "stopped", "missing"];
|
|
36
|
+
const DOT = { needs: "warn", crashed: "bad", stuck: "warn", working: "busy", idle: "ok", paused: "off", stopped: "off", missing: "off" };
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* One instance's live state, from the app store: `i` its status entry (null: the fleet does not list it), `exec` the
|
|
40
|
+
* raw execution state, `awaiting` what it waits on at its terminal (null: nothing), `needs` how many "Needs you" items
|
|
41
|
+
* name it (#1398's registry, over the stream).
|
|
42
|
+
*/
|
|
43
|
+
export function orgState(i, exec, awaiting, needs) {
|
|
44
|
+
if (!i) return "missing";
|
|
45
|
+
if (awaiting != null || needs > 0) return "needs";
|
|
46
|
+
if (i.status === "crashed") return "crashed";
|
|
47
|
+
if (i.status === "paused") return "paused";
|
|
48
|
+
if (i.status !== "running") return "stopped";
|
|
49
|
+
if (exec === "stuck") return "stuck";
|
|
50
|
+
if (exec === "working") return "working";
|
|
51
|
+
return "idle";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The chart: the structure from /ui/org, the nodes and their states from the app store. General on top; each team with
|
|
56
|
+
* its members in fleet.yaml's order (an instance in two teams shows in both: that is its place in each); then the
|
|
57
|
+
* instances in no team, in the dashboard's order. General is not repeated there.
|
|
58
|
+
*/
|
|
59
|
+
export function buildOrgView(org, app) {
|
|
60
|
+
const live = new Map((app.instances || []).map((i) => [i.name, i]));
|
|
61
|
+
const needs = new Map();
|
|
62
|
+
for (const item of Array.isArray(app.needs) ? app.needs : []) needs.set(item.instance, (needs.get(item.instance) || 0) + 1);
|
|
63
|
+
const awaiting = app.awaiting || {};
|
|
64
|
+
const info = (org && org.instances) || {};
|
|
65
|
+
const node = (name) => {
|
|
66
|
+
const i = live.get(name) || null;
|
|
67
|
+
const waits = Object.prototype.hasOwnProperty.call(awaiting, name) ? awaiting[name] : null;
|
|
68
|
+
return { name, i, info: info[name] || {}, state: orgState(i, (app.exec || {})[name], waits, needs.get(name) || 0) };
|
|
69
|
+
};
|
|
70
|
+
const counts = (nodes) => {
|
|
71
|
+
const c = {};
|
|
72
|
+
for (const n of nodes) c[n.state] = (c[n.state] || 0) + 1;
|
|
73
|
+
return ORG_STATES.filter((s) => c[s]).map((s) => [s, c[s]]);
|
|
74
|
+
};
|
|
75
|
+
const general = ((org && org.general) || []).filter((n) => live.has(n));
|
|
76
|
+
const teams = ((org && org.teams) || []).map((team) => {
|
|
77
|
+
const nodes = (team.members || []).map(node);
|
|
78
|
+
return { name: team.name, description: team.description || "", nodes, counts: counts(nodes) };
|
|
79
|
+
});
|
|
80
|
+
const placed = new Set([...general, ...teams.flatMap((team) => team.nodes.map((n) => n.name))]);
|
|
81
|
+
const rest = (app.instances || []).filter((i) => !placed.has(i.name)).map((i) => node(i.name));
|
|
82
|
+
const all = (app.instances || []).map((i) => node(i.name));
|
|
83
|
+
return { top: general.map(node), teams, rest: { nodes: rest, counts: counts(rest) }, total: all.length, counts: counts(all) };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function Summary({ counts }) {
|
|
87
|
+
return html`<ul class="org-counts">${counts.map(([s, n]) => html`<li key=${s} class=${`org-count st-${s}`}>
|
|
88
|
+
<span class=${`dot ${DOT[s]}`} aria-hidden="true"></span>${n} ${to(s)}</li>`)}</ul>`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function Node({ n }) {
|
|
92
|
+
const alias = n.i && typeof n.i.display_name === "string" && n.i.display_name.trim() && n.i.display_name.trim() !== n.name ? n.i.display_name.trim() : "";
|
|
93
|
+
const thread = n.info.thread;
|
|
94
|
+
const model = n.i && n.i.model ? n.i.model : "";
|
|
95
|
+
return html`<li class=${`org-node st-${n.state}`}>
|
|
96
|
+
<div class="org-node-head">
|
|
97
|
+
<span class=${`dot ${DOT[n.state]}`} aria-hidden="true"></span>
|
|
98
|
+
<span class="org-names">${alias ? html`<strong class="org-alias">${alias}</strong><span class="org-name mono">${n.name}</span>`
|
|
99
|
+
: html`<strong class="org-name mono">${n.name}</strong>`}</span>
|
|
100
|
+
<span class=${`org-state st-${n.state}`}>${to(n.state)}</span>
|
|
101
|
+
</div>
|
|
102
|
+
${n.info.description ? html`<p class="org-desc" title=${n.info.description}>${n.info.description}</p>` : null}
|
|
103
|
+
${n.i ? html`<div class="org-meta">${n.i.backend ? html`<span class="org-chip">${n.i.backend}</span>` : null}
|
|
104
|
+
${model ? html`<span class="org-model mono" title=${model}>${model}</span>` : null}
|
|
105
|
+
${n.info.classic ? html`<span class="org-chip">${to("classic")}</span>` : null}</div>` : null}
|
|
106
|
+
${n.i || thread ? html`<div class="org-links">
|
|
107
|
+
${thread ? html`<a class="org-link" href=${thread.url} target="_blank" rel="noopener noreferrer">
|
|
108
|
+
<${Icon} name="external" size=${14} />${to(`thread_${thread.platform}`)}<span class="sr-only"> ${to("newTab")}</span></a>` : null}
|
|
109
|
+
${n.i ? html`<a class="org-link" href=${chatPath(n.name)}><${Icon} name="chat" size=${14} />${to("openChat")}</a>` : null}
|
|
110
|
+
</div>` : null}
|
|
111
|
+
</li>`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function Team({ id, name, description, nodes, counts, icon }) {
|
|
115
|
+
return html`<section class="org-team" aria-labelledby=${id}>
|
|
116
|
+
<header class="org-team-head">
|
|
117
|
+
<h3 id=${id}><${Icon} name=${icon} size=${16} /><span>${name}</span></h3>
|
|
118
|
+
${description ? html`<p class="org-team-desc">${description}</p>` : null}
|
|
119
|
+
<div class="org-team-sub"><span class="muted">${count("member", "members", nodes.length)}</span><${Summary} counts=${counts} /></div>
|
|
120
|
+
</header>
|
|
121
|
+
<ul class="org-nodes">${nodes.map((n) => html`<${Node} key=${n.name} n=${n} />`)}</ul>
|
|
122
|
+
</section>`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** The tab's body. `org`: what /ui/org answered (the Fleet panel's loader); `app`: the app store. */
|
|
126
|
+
export function OrgChart({ org, app }) {
|
|
127
|
+
if (!app.ready) return html`<${Skeleton} lines=${4} />`;
|
|
128
|
+
const view = buildOrgView(org, app);
|
|
129
|
+
if (!view.total) return html`<${Empty} icon="team" title=${to("empty")} hint=${to("emptyHint")} />`;
|
|
130
|
+
return html`<div class="org">
|
|
131
|
+
<div class="list-head org-head"><span>${count("instance", "instances", view.total)}</span><${Summary} counts=${view.counts} /></div>
|
|
132
|
+
${view.top.length ? html`<section class="org-top" aria-labelledby="org-general">
|
|
133
|
+
<h3 id="org-general" class="sr-only">${to("general")}</h3>
|
|
134
|
+
<ul class="org-nodes">${view.top.map((n) => html`<${Node} key=${n.name} n=${n} />`)}</ul>
|
|
135
|
+
</section>` : null}
|
|
136
|
+
${view.teams.length ? null : html`<p class="note org-note">${to("noTeams")}</p>`}
|
|
137
|
+
<div class="org-teams">
|
|
138
|
+
${view.teams.map((team, k) => html`<${Team} key=${team.name} id=${`org-team-${k}`} icon="team" ...${team} />`)}
|
|
139
|
+
${view.rest.nodes.length ? html`<${Team} id="org-rest" icon="fleet" name=${to("unteamed")} description="" ...${view.rest} />` : null}
|
|
140
|
+
</div>
|
|
141
|
+
</div>`;
|
|
142
|
+
}
|