@songsid/agend 2.3.2-beta.9 → 2.3.3-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/README.zh-TW.md +6 -0
- package/dist/agent-cli-instructions.md +2 -2
- package/dist/agent-cli.js +48 -0
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +6 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-whats-new.d.ts +21 -0
- package/dist/agent-whats-new.js +53 -21
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/auth-api.js +2 -0
- package/dist/auth-api.js.map +1 -1
- package/dist/backend/claude-code.d.ts +13 -1
- package/dist/backend/claude-code.js +43 -2
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-session-lookup.d.ts +15 -0
- package/dist/backend/codex-session-lookup.js +58 -0
- package/dist/backend/codex-session-lookup.js.map +1 -1
- package/dist/backend/codex.js +15 -4
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/kiro-classic-archive.d.ts +57 -0
- package/dist/backend/kiro-classic-archive.js +622 -0
- package/dist/backend/kiro-classic-archive.js.map +1 -0
- package/dist/backend/kiro-classic-links.d.ts +24 -0
- package/dist/backend/kiro-classic-links.js +135 -0
- package/dist/backend/kiro-classic-links.js.map +1 -0
- package/dist/backend/kiro-identity.d.ts +100 -1
- package/dist/backend/kiro-identity.js +262 -31
- package/dist/backend/kiro-identity.js.map +1 -1
- package/dist/backend/kiro-migration-verify.d.ts +10 -0
- package/dist/backend/kiro-migration-verify.js +52 -0
- package/dist/backend/kiro-migration-verify.js.map +1 -0
- package/dist/backend/kiro-reconcile-store.d.ts +27 -0
- package/dist/backend/kiro-reconcile-store.js +351 -0
- package/dist/backend/kiro-reconcile-store.js.map +1 -0
- package/dist/backend/kiro-v2-store-worker.js +35 -1
- package/dist/backend/kiro-v2-store-worker.js.map +1 -1
- package/dist/backend/kiro-v2-store.d.ts +31 -1
- package/dist/backend/kiro-v2-store.js +22 -12
- package/dist/backend/kiro-v2-store.js.map +1 -1
- package/dist/backend/kiro.d.ts +124 -6
- package/dist/backend/kiro.js +553 -39
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +109 -4
- package/dist/backend/types.js +9 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/cache-service.d.ts +13 -1
- package/dist/cache-service.js +45 -2
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/ipc-timeouts.js +3 -0
- package/dist/channel/ipc-timeouts.js.map +1 -1
- package/dist/channel/mcp-tools.js +40 -5
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/tool-router.js +2 -1
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/classic-channel-manager.d.ts +6 -0
- package/dist/classic-channel-manager.js +25 -0
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +52 -6
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.d.ts +7 -1
- package/dist/config-validator.js +20 -9
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/cross-instance-envelope.d.ts +10 -5
- package/dist/cross-instance-envelope.js +20 -17
- package/dist/cross-instance-envelope.js.map +1 -1
- package/dist/daemon.d.ts +125 -63
- package/dist/daemon.js +694 -330
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard-permissions.d.ts +15 -4
- package/dist/dashboard-permissions.js +49 -23
- package/dist/dashboard-permissions.js.map +1 -1
- package/dist/delivery-outbox.d.ts +27 -22
- package/dist/delivery-outbox.js +109 -161
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-outbox.test.js +10 -25
- package/dist/delivery-outbox.test.js.map +1 -1
- package/dist/doctor.js +2 -1
- package/dist/doctor.js.map +1 -1
- package/dist/fleet-control-audit.d.ts +1 -1
- package/dist/fleet-control-audit.js +3 -0
- package/dist/fleet-control-audit.js.map +1 -1
- package/dist/fleet-manager.d.ts +94 -15
- package/dist/fleet-manager.js +597 -133
- package/dist/fleet-manager.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +9 -0
- package/dist/forged-envelope-scan.js +30 -5
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/general-instance.d.ts +24 -0
- package/dist/general-instance.js +53 -0
- package/dist/general-instance.js.map +1 -1
- package/dist/general-knowledge/skills/delegation-playbook/SKILL.md +1 -1
- package/dist/general-knowledge/skills/docker-install/SKILL.md +25 -0
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +5 -3
- package/dist/general-knowledge/skills/fleet-restart/SKILL.md +1 -1
- package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +34 -0
- package/dist/general-knowledge/skills/session-management/SKILL.md +2 -2
- package/dist/general-knowledge/skills/tui-effort/SKILL.md +1 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +32 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +32 -0
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +57 -17
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +57 -17
- package/dist/instance-config-impact.js +3 -2
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +4 -0
- package/dist/instance-lifecycle.js +28 -5
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.js +6 -7
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-migrate.d.ts +19 -2
- package/dist/kiro-migrate.js +133 -35
- package/dist/kiro-migrate.js.map +1 -1
- package/dist/kiro-reconcile.d.ts +21 -0
- package/dist/kiro-reconcile.js +88 -0
- package/dist/kiro-reconcile.js.map +1 -0
- package/dist/kiro-session-proof.d.ts +41 -0
- package/dist/kiro-session-proof.js +89 -0
- package/dist/kiro-session-proof.js.map +1 -0
- package/dist/kiro-tui-forensic.d.ts +19 -0
- package/dist/kiro-tui-forensic.js +124 -0
- package/dist/kiro-tui-forensic.js.map +1 -0
- package/dist/locale.js +202 -16
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js +3 -3
- package/dist/log-service.js.map +1 -1
- package/dist/needs-you.d.ts +3 -1
- package/dist/needs-you.js +4 -2
- package/dist/needs-you.js.map +1 -1
- package/dist/office-levels.d.ts +64 -0
- package/dist/office-levels.js +66 -0
- package/dist/office-levels.js.map +1 -0
- package/dist/office-share-page.d.ts +3 -1
- package/dist/office-share-page.js +8 -3
- package/dist/office-share-page.js.map +1 -1
- package/dist/office-share-service.d.ts +6 -3
- package/dist/office-share-service.js +12 -8
- package/dist/office-share-service.js.map +1 -1
- package/dist/office-share.d.ts +45 -8
- package/dist/office-share.js +75 -15
- package/dist/office-share.js.map +1 -1
- package/dist/outbound-handlers.js +21 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +47 -2
- package/dist/outbound-schemas.js +42 -3
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +1 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/quickstart-api.d.ts +39 -1
- package/dist/quickstart-api.js +115 -17
- package/dist/quickstart-api.js.map +1 -1
- package/dist/remote-card-answer.d.ts +83 -0
- package/dist/remote-card-answer.js +208 -0
- package/dist/remote-card-answer.js.map +1 -0
- package/dist/remote-card-prompt.d.ts +38 -0
- package/dist/remote-card-prompt.js +86 -0
- package/dist/remote-card-prompt.js.map +1 -0
- package/dist/scheduler/task-board.d.ts +44 -17
- package/dist/scheduler/task-board.js +95 -36
- package/dist/scheduler/task-board.js.map +1 -1
- package/dist/sd-notify.d.ts +13 -14
- package/dist/sd-notify.js +62 -28
- package/dist/sd-notify.js.map +1 -1
- package/dist/service-installer.d.ts +13 -0
- package/dist/service-installer.js +15 -0
- package/dist/service-installer.js.map +1 -1
- package/dist/service-owner.d.ts +25 -0
- package/dist/service-owner.js +43 -2
- package/dist/service-owner.js.map +1 -1
- package/dist/settings-api.d.ts +2 -1
- package/dist/settings-api.js +19 -26
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +10 -5
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +7 -6
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-instance-patch.js +1 -1
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/setup-form.d.ts +2 -2
- package/dist/setup-form.js +139 -93
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-i18n.d.ts +25 -0
- package/dist/setup-i18n.js +226 -0
- package/dist/setup-i18n.js.map +1 -0
- package/dist/task-board-waker.d.ts +40 -1
- package/dist/task-board-waker.js +115 -9
- package/dist/task-board-waker.js.map +1 -1
- package/dist/tmux-control.d.ts +1 -1
- package/dist/tmux-control.js +3 -2
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.js +18 -16
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.d.ts +2 -0
- package/dist/tmux-read.js +7 -1
- package/dist/tmux-read.js.map +1 -1
- package/dist/tool-permissions.js +18 -0
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +2 -0
- package/dist/topic-commands.js +2 -1
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-sources.d.ts +1 -0
- package/dist/transcript-sources.js +20 -3
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +11 -5
- package/dist/ui/backend-signin.js +4 -3
- package/dist/ui/chat-store.js +3 -2
- package/dist/ui/chat-strings.js +2 -2
- package/dist/ui/fleet-office-card.js +114 -0
- package/dist/ui/fleet-office-editor.js +81 -9
- package/dist/ui/fleet-office-layout.js +56 -11
- package/dist/ui/fleet-office-levels.js +105 -0
- package/dist/ui/fleet-office-model.js +9 -1
- package/dist/ui/fleet-office-pack.d.ts +15 -3
- package/dist/ui/fleet-office-pack.js +177 -23
- package/dist/ui/fleet-office-skin.js +39 -3
- package/dist/ui/fleet-office-store.js +74 -3
- package/dist/ui/fleet-office-view.js +8 -0
- package/dist/ui/fleet-office-zones.js +102 -19
- package/dist/ui/fleet-office.js +308 -44
- package/dist/ui/fleet-org.js +2 -0
- package/dist/ui/fleet-task-card.js +2 -2
- package/dist/ui/fleet-task-common.js +30 -7
- package/dist/ui/fleet-task-work.js +2 -2
- package/dist/ui/fleet-tasks.js +10 -11
- package/dist/ui/office-share-dialog.js +31 -7
- package/dist/ui/office-share-page.js +1 -0
- package/dist/ui/panel-chat.js +14 -2
- package/dist/ui/panel-log.js +6 -6
- package/dist/ui/panel-needs.js +1 -1
- package/dist/ui/panel-settings.js +16 -8
- package/dist/ui/settings-appearance.js +3 -35
- package/dist/ui/settings-discord.js +3 -2
- package/dist/ui/settings-guests.js +17 -7
- package/dist/ui/settings-model.js +17 -9
- package/dist/ui/settings-registry.js +1 -1
- package/dist/ui/settings-strings.js +18 -6
- package/dist/ui/settings-token.js +3 -2
- package/dist/ui/settings-wizard.js +25 -9
- package/dist/ui/shared/app-i18n.js +2 -2
- package/dist/ui/shared/app-stream.js +1 -1
- package/dist/ui/shared/app.css +70 -2
- package/dist/ui/shared/setup-host-text.js +107 -0
- package/dist/ui/structured-signin.js +89 -38
- package/dist/update-check.d.ts +13 -4
- package/dist/update-check.js +17 -4
- package/dist/update-check.js.map +1 -1
- package/dist/usage-rollup.d.ts +34 -3
- package/dist/usage-rollup.js +56 -3
- package/dist/usage-rollup.js.map +1 -1
- package/dist/web-api.d.ts +10 -1
- package/dist/web-api.js +207 -17
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.js +1 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-experimental.d.ts +6 -2
- package/dist/web-experimental.js +8 -4
- package/dist/web-experimental.js.map +1 -1
- package/dist/web-office-acts.d.ts +5 -2
- package/dist/web-office-acts.js +9 -4
- package/dist/web-office-acts.js.map +1 -1
- package/dist/web-office-pack-read.d.ts +35 -0
- package/dist/web-office-pack-read.js +252 -0
- package/dist/web-office-pack-read.js.map +1 -0
- package/dist/web-office-pack-tools.d.ts +241 -0
- package/dist/web-office-pack-tools.js +785 -0
- package/dist/web-office-pack-tools.js.map +1 -0
- package/dist/web-office-skins.d.ts +68 -4
- package/dist/web-office-skins.js +324 -33
- package/dist/web-office-skins.js.map +1 -1
- package/dist/web-office-store.d.ts +47 -4
- package/dist/web-office-store.js +124 -23
- package/dist/web-office-store.js.map +1 -1
- package/dist/web-settings-patch.d.ts +3 -2
- package/dist/web-settings-patch.js +7 -5
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/workflow-templates/default.md +3 -3
- package/dist/working-recovery.d.ts +0 -2
- package/dist/working-recovery.js +2 -23
- package/dist/working-recovery.js.map +1 -1
- package/package.json +2 -2
- package/templates/windows-shortcuts.ps1 +18 -17
- package/dist/upgrade-notices.d.ts +0 -17
- package/dist/upgrade-notices.js +0 -93
- package/dist/upgrade-notices.js.map +0 -1
package/dist/setup-form.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SETUP_CODE_STRINGS, SETUP_FORM_STRINGS, setupI18nRuntime } from "./setup-i18n.js";
|
|
1
2
|
/**
|
|
2
3
|
* The pre-fleet form, inline.
|
|
3
4
|
*
|
|
@@ -33,27 +34,35 @@ export const SETUP_CODE_PAGE_HTML = `<!DOCTYPE html>
|
|
|
33
34
|
button { width: 100%; margin-top: 12px; padding: 12px; border: 1px solid #2563eb; border-radius: 6px; background: #2563eb; color: #fff; font-size: 15px; cursor: pointer; }
|
|
34
35
|
button:disabled { opacity: .5; cursor: default; }
|
|
35
36
|
.err { color: #dc2626; font-size: 13px; margin-top: 12px; min-height: 18px; }
|
|
37
|
+
.lang { display: flex; justify-content: flex-end; }
|
|
38
|
+
.lang button { width: auto; margin: 0; padding: 4px 10px; border-color: #e5e7eb; background: #fff; color: #111827; font-size: 13px; }
|
|
36
39
|
</style>
|
|
37
40
|
</head>
|
|
38
41
|
<body>
|
|
39
42
|
<main>
|
|
40
|
-
<
|
|
41
|
-
<
|
|
43
|
+
<div class="lang"><button id="lang" type="button" data-i18n="otherLang" data-i18n-label="langTitle">中文</button></div>
|
|
44
|
+
<h1 data-i18n="title">Set up AgEnD</h1>
|
|
45
|
+
<p id="lead">Enter the setup code shown in the terminal where you ran <code>agend setup</code>.</p>
|
|
42
46
|
<form id="f">
|
|
43
47
|
<input id="code" autocomplete="off" autocapitalize="characters" spellcheck="false" placeholder="ABCD-EFGH" maxlength="12" autofocus>
|
|
44
|
-
<button id="go" type="submit">Continue</button>
|
|
48
|
+
<button id="go" type="submit" data-i18n="continue">Continue</button>
|
|
45
49
|
</form>
|
|
46
50
|
<div class="err" id="msg"></div>
|
|
47
51
|
</main>
|
|
48
52
|
<script>
|
|
49
53
|
(() => {
|
|
50
54
|
"use strict";
|
|
55
|
+
${setupI18nRuntime(SETUP_CODE_STRINGS)}
|
|
56
|
+
show(document.getElementById("lead"), el => {
|
|
57
|
+
const [before, after] = tr("lead").split("{0}"), command = document.createElement("code");
|
|
58
|
+
command.textContent = "agend setup"; el.replaceChildren(before, command, after ?? "");
|
|
59
|
+
});
|
|
51
60
|
const msg = document.getElementById("msg");
|
|
52
61
|
const go = document.getElementById("go");
|
|
53
62
|
document.getElementById("f").addEventListener("submit", async (event) => {
|
|
54
63
|
event.preventDefault();
|
|
55
64
|
go.disabled = true;
|
|
56
|
-
msg.textContent = "";
|
|
65
|
+
show(msg, el => { el.textContent = ""; });
|
|
57
66
|
let res;
|
|
58
67
|
try {
|
|
59
68
|
res = await fetch("open", {
|
|
@@ -62,13 +71,14 @@ export const SETUP_CODE_PAGE_HTML = `<!DOCTYPE html>
|
|
|
62
71
|
body: JSON.stringify({ code: document.getElementById("code").value }),
|
|
63
72
|
});
|
|
64
73
|
} catch {
|
|
65
|
-
msg
|
|
74
|
+
show(msg, el => { el.textContent = tr("unreachable"); });
|
|
66
75
|
go.disabled = false;
|
|
67
76
|
return;
|
|
68
77
|
}
|
|
69
78
|
if (res.ok) { location.reload(); return; }
|
|
70
79
|
let body = null; try { body = await res.json(); } catch {}
|
|
71
|
-
|
|
80
|
+
const error = body && body.error;
|
|
81
|
+
show(msg, el => { el.textContent = error ? trHost(error) : tr("notAccepted"); });
|
|
72
82
|
// A spent budget ends the page; there is nothing useful left to type into.
|
|
73
83
|
if (res.status !== 410) go.disabled = false;
|
|
74
84
|
});
|
|
@@ -100,51 +110,55 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
100
110
|
.msg { font-size: 13px; }
|
|
101
111
|
.ok { color: #059669; } .err { color: #dc2626; }
|
|
102
112
|
pre { background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 6px; padding: 12px; font-size: 12px; overflow: auto; }
|
|
113
|
+
.top { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
|
|
114
|
+
#lang { padding: 4px 10px; font-size: 13px; flex: none; }
|
|
103
115
|
</style>
|
|
104
116
|
</head>
|
|
105
117
|
<body>
|
|
106
118
|
<main>
|
|
107
|
-
<h1>Set up AgEnD</h1>
|
|
108
|
-
<div class="sub" id="intro">This page is open only while setup is running. It closes itself when you finish, or after 15 minutes.</div>
|
|
119
|
+
<div class="top"><h1 data-i18n="title">Set up AgEnD</h1><button id="lang" type="button" data-i18n="otherLang" data-i18n-label="langTitle">中文</button></div>
|
|
120
|
+
<div class="sub" id="intro" data-i18n="intro">This page is open only while setup is running. It closes itself when you finish, or after 15 minutes.</div>
|
|
109
121
|
<div class="sub msg" id="ttlMsg" role="status"></div>
|
|
110
122
|
|
|
111
|
-
<div class="step" id="setupSignins" aria-label="AI backend sign-ins"></div>
|
|
123
|
+
<div class="step" id="setupSignins" aria-label="AI backend sign-ins" data-i18n-label="signinsLabel"></div>
|
|
112
124
|
|
|
113
125
|
<div class="step">
|
|
114
|
-
<h2>1 · Agent</h2>
|
|
115
|
-
<label for="backend">Backend</label>
|
|
126
|
+
<h2 data-i18n="stepAgent">1 · Agent</h2>
|
|
127
|
+
<label for="backend" data-i18n="backend">Backend</label>
|
|
116
128
|
<select id="backend"></select>
|
|
117
129
|
<div class="sub" id="backendHint"></div>
|
|
118
|
-
<label for="dir">Working directory (
|
|
119
|
-
<input id="dir" placeholder="/home/you/projects/app">
|
|
120
|
-
<
|
|
121
|
-
<
|
|
130
|
+
<label for="dir" data-i18n="dir">Working directory (optional)</label>
|
|
131
|
+
<input id="dir" placeholder="/home/you/projects/app" data-i18n-placeholder="dirPlaceholder" aria-describedby="dirHint">
|
|
132
|
+
<div class="sub" id="dirHint"></div>
|
|
133
|
+
<label for="name" data-i18n="name">First agent name</label>
|
|
134
|
+
<input id="name" value="general" aria-describedby="generalNote">
|
|
135
|
+
<div class="sub" id="generalNote" data-i18n="generalNote" hidden>This agent is the General: it answers in the chat's own General topic and hands work to the agents you add later.</div>
|
|
122
136
|
</div>
|
|
123
137
|
|
|
124
138
|
<div class="step">
|
|
125
|
-
<h2>2 · Platform</h2>
|
|
139
|
+
<h2 data-i18n="stepPlatform">2 · Platform</h2>
|
|
126
140
|
<div class="row">
|
|
127
141
|
<button id="pickTelegram" class="primary">Telegram</button>
|
|
128
142
|
<button id="pickDiscord">Discord</button>
|
|
129
|
-
<button id="pickWeb">Web only (no bot)</button>
|
|
143
|
+
<button id="pickWeb" data-i18n="webOnly">Web only (no bot)</button>
|
|
130
144
|
</div>
|
|
131
145
|
<div class="sub" id="platformHint">Create a bot with @BotFather, then add it to a group.</div>
|
|
132
146
|
</div>
|
|
133
147
|
|
|
134
148
|
<div class="step" id="credStep">
|
|
135
|
-
<h2>3 · Credentials</h2>
|
|
136
|
-
<label for="token">Bot token</label>
|
|
149
|
+
<h2 data-i18n="stepCredentials">3 · Credentials</h2>
|
|
150
|
+
<label for="token" data-i18n="token">Bot token</label>
|
|
137
151
|
<input id="token" type="password" placeholder="123456:ABC-DEF…">
|
|
138
|
-
<div class="sub">Written to ~/.agend/.env and never shown again.</div>
|
|
139
|
-
<label for="tokenEnv">Environment variable</label>
|
|
152
|
+
<div class="sub" data-i18n="tokenNote">Written to ~/.agend/.env and never shown again.</div>
|
|
153
|
+
<label for="tokenEnv" data-i18n="tokenEnv">Environment variable</label>
|
|
140
154
|
<input id="tokenEnv" value="AGEND_BOT_TOKEN">
|
|
141
|
-
<div class="row"><button id="verify">Verify</button><span class="msg" id="verifyMsg"></span></div>
|
|
155
|
+
<div class="row"><button id="verify" data-i18n="verify">Verify</button><span class="msg" id="verifyMsg"></span></div>
|
|
142
156
|
<div id="platformFields"></div>
|
|
143
157
|
</div>
|
|
144
158
|
|
|
145
159
|
<div class="step">
|
|
146
|
-
<h2>4 · Review and start</h2>
|
|
147
|
-
<div class="row"><button id="preview">Show what will be written</button></div>
|
|
160
|
+
<h2 data-i18n="stepReview">4 · Review and start</h2>
|
|
161
|
+
<div class="row"><button id="preview" data-i18n="preview">Show what will be written</button></div>
|
|
148
162
|
<pre id="planOut" hidden></pre>
|
|
149
163
|
<div class="row"><button id="finish" class="primary" disabled>Create and start AgEnD</button><span class="msg" id="finishMsg"></span></div>
|
|
150
164
|
</div>
|
|
@@ -152,8 +166,10 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
152
166
|
<script>
|
|
153
167
|
(() => {
|
|
154
168
|
"use strict";
|
|
169
|
+
${setupI18nRuntime(SETUP_FORM_STRINGS)}
|
|
155
170
|
const $ = (id) => document.getElementById(id);
|
|
156
|
-
|
|
171
|
+
// M-2069: firstGeneral — a chat setup's new agent is the fleet's General, named "general" until the name is typed.
|
|
172
|
+
const state = { platform: "telegram", identity: null, guilds: [], offset: 0, plan: null, workspaces: null, firstGeneral: true, nameTyped: false };
|
|
157
173
|
// Relative to the page's own directory, which is /s/<sid>/. An absolute path
|
|
158
174
|
// would leave that namespace and 404 — the sid is where this page lives, not
|
|
159
175
|
// a prefix bolted on to it.
|
|
@@ -162,31 +178,48 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
162
178
|
let body = null; try { body = await res.json(); } catch {}
|
|
163
179
|
return { ok: res.ok, status: res.status, body };
|
|
164
180
|
};
|
|
181
|
+
// A line of this page in its language: a key and its values, or (host) the host's own words, translated when known.
|
|
182
|
+
const say = (id, key, ...values) => show($(id), el => { el.textContent = tr(key, ...values); });
|
|
183
|
+
const sayHost = (id, text, fallback) => show($(id), el => { el.textContent = text ? trHost(text) : tr(fallback); });
|
|
184
|
+
|
|
185
|
+
// #2726: no directory is the agent's own workspace, <AGEND_HOME>/workspaces/<name> — said under the field, by name.
|
|
186
|
+
const showDirHint = () => show($("dirHint"), el => {
|
|
187
|
+
const name = $("name").value.trim();
|
|
188
|
+
el.textContent = state.workspaces && name ? tr("dirDefault", state.workspaces + "/" + name) : tr("dirDefaultName");
|
|
189
|
+
});
|
|
165
190
|
|
|
166
191
|
async function loadEnvironment() {
|
|
167
192
|
const res = await api("api/settings/quickstart/environment");
|
|
168
193
|
if (formFrozen) return;
|
|
169
194
|
const backends = res.body?.backends || [];
|
|
195
|
+
if (typeof res.body?.workspaces_dir === "string") { state.workspaces = res.body.workspaces_dir; showDirHint(); }
|
|
196
|
+
if (typeof res.body?.first_general === "boolean") { state.firstGeneral = res.body.first_general; showGeneral(); }
|
|
170
197
|
$("backend").innerHTML = "";
|
|
171
198
|
for (const name of backends.length ? backends : ["claude-code"]) {
|
|
172
199
|
const opt = document.createElement("option"); opt.value = name; opt.textContent = name; $("backend").append(opt);
|
|
173
200
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
201
|
+
if (backends.length) say("backendHint", "backendFound", backends.join(", "));
|
|
202
|
+
else say("backendHint", "backendNone");
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// M-2069: on a chat platform, with no directory typed, the first agent is the General ("general"); web only has no
|
|
206
|
+
// General, and a typed directory makes a worker ("agent-1"). A name the user typed is kept.
|
|
207
|
+
function showGeneral() {
|
|
208
|
+
// #2744 review: only with no directory — the General works in its own folder, never in a project of the user's.
|
|
209
|
+
const general = state.firstGeneral && state.platform !== "web" && !$("dir").value.trim();
|
|
210
|
+
$("generalNote").hidden = !general;
|
|
211
|
+
if (!state.nameTyped) { $("name").value = general ? "general" : "agent-1"; showDirHint(); }
|
|
177
212
|
}
|
|
178
213
|
|
|
179
214
|
function setPlatform(platform) {
|
|
180
215
|
if (formFrozen) return;
|
|
181
216
|
state.platform = platform;
|
|
182
|
-
|
|
217
|
+
showGeneral();
|
|
218
|
+
state.identity = null; say("verifyMsg", "");
|
|
183
219
|
$("pickTelegram").className = platform === "telegram" ? "primary" : "";
|
|
184
220
|
$("pickDiscord").className = platform === "discord" ? "primary" : "";
|
|
185
221
|
$("pickWeb").className = platform === "web" ? "primary" : "";
|
|
186
|
-
|
|
187
|
-
? "Create a bot with @BotFather, then add it to a group."
|
|
188
|
-
: platform === "discord" ? "Create an application in the Discord developer portal and invite the bot to your server."
|
|
189
|
-
: "No bot: you use AgEnD from its web dashboard (chat, sign-ins, settings). Discord or Telegram can be added later in Settings.";
|
|
222
|
+
say("platformHint", platform === "telegram" ? "hintTelegram" : platform === "discord" ? "hintDiscord" : "hintWeb");
|
|
190
223
|
// #2233: web only has no credentials step — no token, no admin id, nothing to verify.
|
|
191
224
|
$("credStep").hidden = platform === "web";
|
|
192
225
|
state.plan = null; $("planOut").hidden = true; $("finish").disabled = true;
|
|
@@ -198,47 +231,48 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
198
231
|
if (formFrozen) return;
|
|
199
232
|
const host = $("platformFields"); host.innerHTML = "";
|
|
200
233
|
if (state.platform === "web") return;
|
|
201
|
-
const field = (id,
|
|
202
|
-
const label = document.createElement("label"); label.
|
|
234
|
+
const field = (id, labelKey, hintKey) => {
|
|
235
|
+
const label = document.createElement("label"); label.htmlFor = id; show(label, el => { el.textContent = tr(labelKey); });
|
|
203
236
|
const input = document.createElement("input"); input.id = id;
|
|
204
237
|
host.append(label, input);
|
|
205
|
-
if (
|
|
238
|
+
if (hintKey) { const h = document.createElement("div"); h.className = "sub"; show(h, el => { el.textContent = tr(hintKey); }); host.append(h); }
|
|
206
239
|
return input;
|
|
207
240
|
};
|
|
208
241
|
if (state.platform === "discord") {
|
|
209
242
|
const guild = document.createElement("select"); guild.id = "guild";
|
|
210
|
-
const label = document.createElement("label"); label.
|
|
243
|
+
const label = document.createElement("label"); label.htmlFor = "guild"; show(label, el => { el.textContent = tr("guild"); });
|
|
211
244
|
host.append(label, guild);
|
|
212
245
|
for (const g of state.guilds) { const opt = document.createElement("option"); opt.value = g.id; opt.textContent = g.name + " (" + g.id + ")"; guild.append(opt); }
|
|
213
|
-
field("general", "
|
|
214
|
-
field("admin", "
|
|
246
|
+
field("general", "general");
|
|
247
|
+
field("admin", "discordAdmin", "firstAllowed");
|
|
215
248
|
} else {
|
|
216
|
-
field("group", "
|
|
249
|
+
field("group", "group", "groupHint");
|
|
217
250
|
const row = document.createElement("div"); row.className = "row";
|
|
218
|
-
const detect = document.createElement("button"); detect.id = "detect"; detect.textContent = "
|
|
251
|
+
const detect = document.createElement("button"); detect.id = "detect"; show(detect, el => { el.textContent = tr("detect"); });
|
|
219
252
|
detect.onclick = detectGroup; row.append(detect);
|
|
220
253
|
const msg = document.createElement("span"); msg.className = "msg"; msg.id = "detectMsg"; row.append(msg);
|
|
221
254
|
host.append(row);
|
|
222
|
-
field("admin", "
|
|
255
|
+
field("admin", "telegramAdmin", "firstAllowed");
|
|
223
256
|
}
|
|
224
257
|
}
|
|
225
258
|
|
|
226
259
|
async function detectGroup() {
|
|
227
260
|
if (formFrozen) return;
|
|
228
|
-
|
|
261
|
+
say("detectMsg", "detectWaiting");
|
|
229
262
|
const res = await api("api/settings/quickstart/probe", { method: "POST", body: JSON.stringify({ action: "await-telegram-start", token: $("token").value.trim(), offset: state.offset }) });
|
|
230
263
|
if (formFrozen) return;
|
|
231
|
-
if (!res.ok) {
|
|
264
|
+
if (!res.ok) { sayHost("detectMsg", res.body?.error, "failed"); return; }
|
|
232
265
|
state.offset = res.body.offset;
|
|
233
266
|
if (res.body.found) {
|
|
234
267
|
$("group").value = String(res.body.found.groupId);
|
|
235
268
|
$("admin").value = String(res.body.found.userId);
|
|
236
|
-
|
|
237
|
-
} else
|
|
269
|
+
say("detectMsg", "detectFound");
|
|
270
|
+
} else say("detectMsg", "detectNone");
|
|
238
271
|
}
|
|
239
272
|
|
|
240
273
|
function input() {
|
|
241
274
|
// #2233: the agent alone; a web-only setup carries no connection field at all.
|
|
275
|
+
// #2726: an empty directory is sent as it is — the host gives the agent its own workspace.
|
|
242
276
|
if (state.platform === "web") return { web_only: true, backend: $("backend").value, working_directory: $("dir").value.trim(), instance_name: $("name").value.trim() };
|
|
243
277
|
return {
|
|
244
278
|
platform: state.platform,
|
|
@@ -255,14 +289,16 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
255
289
|
|
|
256
290
|
$("verify").onclick = async () => {
|
|
257
291
|
if (formFrozen) return;
|
|
258
|
-
|
|
292
|
+
say("verifyMsg", "verifying");
|
|
259
293
|
const token = $("token").value.trim();
|
|
260
294
|
const res = await api("api/settings/quickstart/probe", { method: "POST", body: JSON.stringify({ action: "verify", platform: state.platform, token }) });
|
|
261
295
|
if (formFrozen) return;
|
|
262
|
-
state.identity = res.body?.identity || { valid: false };
|
|
263
|
-
$("verifyMsg")
|
|
264
|
-
|
|
265
|
-
|
|
296
|
+
const identity = state.identity = res.body?.identity || { valid: false };
|
|
297
|
+
show($("verifyMsg"), el => {
|
|
298
|
+
el.className = "msg " + (identity.valid ? "ok" : "err");
|
|
299
|
+
el.textContent = identity.valid ? "✓ " + (identity.username || tr("verified")) : "✗ " + (identity.reason ? trHost(identity.reason) : tr("rejected"));
|
|
300
|
+
});
|
|
301
|
+
if (identity.valid && state.platform === "discord") {
|
|
266
302
|
const guilds = await api("api/settings/quickstart/probe", { method: "POST", body: JSON.stringify({ action: "guilds", token }) });
|
|
267
303
|
if (formFrozen) return;
|
|
268
304
|
state.guilds = guilds.body?.guilds || [];
|
|
@@ -274,10 +310,10 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
274
310
|
if (formFrozen) return;
|
|
275
311
|
const res = await api("api/settings/quickstart/plan", { method: "POST", body: JSON.stringify(input()) });
|
|
276
312
|
if (formFrozen) return;
|
|
277
|
-
if (!res.ok) { $("planOut").hidden = false;
|
|
313
|
+
if (!res.ok) { $("planOut").hidden = false; sayHost("planOut", res.body?.error, "failed"); return; }
|
|
278
314
|
state.plan = res.body;
|
|
279
315
|
$("planOut").hidden = false;
|
|
280
|
-
$("planOut").textContent = JSON.stringify(res.body, null, 2);
|
|
316
|
+
show($("planOut"), el => { el.textContent = JSON.stringify(res.body, null, 2); });
|
|
281
317
|
$("finish").disabled = !(state.platform === "web" || state.identity?.valid);
|
|
282
318
|
};
|
|
283
319
|
|
|
@@ -287,13 +323,16 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
287
323
|
let pollGeneration = 0;
|
|
288
324
|
// #2650 item 10: how long this page has left, counted here from the host's own remaining time (no polling: a request
|
|
289
325
|
// would keep an idle page open). After it, the page says it has closed and how to reopen it, instead of freezing.
|
|
290
|
-
const REOPEN = "Reopen it where you started setup: in the Windows installer, press Enter in its window; otherwise run agend setup again on the computer running AgEnD.";
|
|
291
326
|
let closesAt = null, handedOver = false, pageClosed = false;
|
|
327
|
+
const setFinishLabel = (key) => show($("finish"), el => { el.textContent = tr(key); });
|
|
328
|
+
// finishMsg: a key of this page, or the host's words; with its colour.
|
|
329
|
+
const finishSay = (cls, key, ...values) => show($("finishMsg"), el => { el.className = cls; el.textContent = tr(key, ...values); });
|
|
330
|
+
const finishHost = (text, fallback) => show($("finishMsg"), el => { el.className = "msg err"; el.textContent = text ? trHost(text) : tr(fallback); });
|
|
292
331
|
const closePage = () => {
|
|
293
332
|
if (handedOver || pageClosed) return;
|
|
294
333
|
pageClosed = true; pollGeneration++; freezeFields(true); $("finish").disabled = true;
|
|
295
|
-
$("ttlMsg").className = "sub msg err";
|
|
296
|
-
$("finishMsg").className = "msg err";
|
|
334
|
+
show($("ttlMsg"), el => { el.className = "sub msg err"; el.textContent = tr("closed"); });
|
|
335
|
+
show($("finishMsg"), el => { el.className = "msg err"; el.textContent = tr("closedFinish", tr("reopen")); });
|
|
297
336
|
};
|
|
298
337
|
const showRemaining = () => {
|
|
299
338
|
if (closesAt === null || handedOver || pageClosed) return;
|
|
@@ -301,9 +340,10 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
301
340
|
if (left <= 0) { closePage(); return; }
|
|
302
341
|
const total = Math.ceil(left / 1000), text = Math.floor(total / 60) + ":" + String(total % 60).padStart(2, "0");
|
|
303
342
|
const soon = left <= 3 * 60_000;
|
|
304
|
-
$("ttlMsg")
|
|
305
|
-
|
|
306
|
-
|
|
343
|
+
show($("ttlMsg"), el => {
|
|
344
|
+
el.className = soon ? "sub msg err" : "sub msg";
|
|
345
|
+
el.textContent = soon ? tr("closesSoon", tr("closesIn", text), tr("reopen")) : tr("closesIn", text);
|
|
346
|
+
});
|
|
307
347
|
setTimeout(showRemaining, 1000);
|
|
308
348
|
};
|
|
309
349
|
const trackRemaining = (status) => {
|
|
@@ -316,39 +356,45 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
316
356
|
formFrozen = frozen;
|
|
317
357
|
for (const field of document.querySelectorAll("main input, main select, #verify, #preview, #pickTelegram, #pickDiscord, #pickWeb, #detect")) field.disabled = frozen;
|
|
318
358
|
};
|
|
319
|
-
const restoreEditing = (
|
|
359
|
+
const restoreEditing = (render) => {
|
|
320
360
|
if (pageClosed) return; // a late answer never reopens a closed page (#2653 review)
|
|
321
361
|
pollGeneration++; approvedSetup = false; submission = null; state.identity = null;
|
|
322
|
-
freezeFields(false); $("finish").disabled = true;
|
|
323
|
-
|
|
362
|
+
freezeFields(false); $("finish").disabled = true; setFinishLabel("finish");
|
|
363
|
+
render();
|
|
324
364
|
};
|
|
325
365
|
for (const field of document.querySelectorAll("main input, main select")) field.addEventListener("input", () => {
|
|
326
|
-
approvedSetup = false; submission = null;
|
|
366
|
+
approvedSetup = false; submission = null; setFinishLabel("finish");
|
|
327
367
|
});
|
|
368
|
+
// A host confirmation that did not apply: its outcome in this page's language (by its reason), else the host's words.
|
|
369
|
+
const outcomeText = (pending) => {
|
|
370
|
+
const reason = pending.outcome?.reason_code;
|
|
371
|
+
if (reason && I18N.en["outcome_" + reason]) return tr("outcome_" + reason);
|
|
372
|
+
return pending.outcome?.message ? trHost(pending.outcome.message) : tr("notApplied");
|
|
373
|
+
};
|
|
328
374
|
const watchPending = (pendingId) => {
|
|
329
375
|
if (pageClosed) return; // a late pending list or commit answer: the page stays closed
|
|
330
376
|
const generation = ++pollGeneration;
|
|
331
377
|
freezeFields(true); $("finish").disabled = true;
|
|
332
378
|
// #2650 item 1: the page asks; a person at the computer running AgEnD approves. Nothing on this page can.
|
|
333
|
-
const ask =
|
|
334
|
-
|
|
379
|
+
const ask = () => finishSay("msg", "approveHost", pendingId);
|
|
380
|
+
ask();
|
|
335
381
|
let misses = 0;
|
|
336
382
|
const poll = async () => {
|
|
337
383
|
if (generation !== pollGeneration) return;
|
|
338
384
|
try {
|
|
339
385
|
const result = await api("api/settings/pending/" + pendingId);
|
|
340
386
|
if (generation !== pollGeneration) return;
|
|
341
|
-
if (misses) { misses = 0;
|
|
342
|
-
if (!result.ok) { restoreEditing(
|
|
387
|
+
if (misses) { misses = 0; ask(); }
|
|
388
|
+
if (!result.ok) { restoreEditing(() => finishSay("msg err", "confirmGone")); return; }
|
|
343
389
|
const pending = result.body;
|
|
344
390
|
if (pending.state === "pending" || pending.state === "applying") { setTimeout(poll, 1000); return; }
|
|
345
|
-
if (pending.state !== "applied") { restoreEditing(
|
|
346
|
-
approvedSetup = true; submission = null; $("finish").disabled = false;
|
|
347
|
-
|
|
391
|
+
if (pending.state !== "applied") { restoreEditing(() => show($("finishMsg"), el => { el.className = "msg err"; el.textContent = outcomeText(pending); })); return; }
|
|
392
|
+
approvedSetup = true; submission = null; $("finish").disabled = false; setFinishLabel("start");
|
|
393
|
+
finishSay("msg", "confirmed");
|
|
348
394
|
} catch {
|
|
349
395
|
if (generation !== pollGeneration) return;
|
|
350
396
|
// #2650 item 10: a lost connection is said, not waited out silently; the pending confirmation keeps its id.
|
|
351
|
-
if (++misses === 5)
|
|
397
|
+
if (++misses === 5) show($("finishMsg"), el => { el.className = "msg err"; el.textContent = tr("lostContact", tr("reopen")); });
|
|
352
398
|
setTimeout(poll, misses < 5 ? 1000 : 3000);
|
|
353
399
|
}
|
|
354
400
|
};
|
|
@@ -357,15 +403,15 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
357
403
|
$("finish").onclick = async () => {
|
|
358
404
|
if (pageClosed) return;
|
|
359
405
|
if ($("setupSignins").dataset.ready === "false") {
|
|
360
|
-
$("finishMsg").
|
|
406
|
+
finishSay($("finishMsg").className, "finishSignins"); return;
|
|
361
407
|
}
|
|
362
408
|
$("finish").disabled = true;
|
|
363
409
|
try {
|
|
364
410
|
if (approvedSetup) {
|
|
365
411
|
const finished = await api("setup/finish", { method: "POST" });
|
|
366
|
-
if (!finished.ok) { restoreEditing(finished.body?.error
|
|
367
|
-
handedOver = true; $("ttlMsg").textContent = "";
|
|
368
|
-
$("finishMsg").
|
|
412
|
+
if (!finished.ok) { restoreEditing(() => finishHost(finished.body?.error, "notCurrent")); return; }
|
|
413
|
+
handedOver = true; show($("ttlMsg"), el => { el.textContent = ""; });
|
|
414
|
+
finishSay($("finishMsg").className, state.platform === "web" ? "startingWeb" : "startingChat");
|
|
369
415
|
if (finished.body?.watch !== false) waitForFleet();
|
|
370
416
|
return;
|
|
371
417
|
}
|
|
@@ -373,13 +419,13 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
373
419
|
// a terminal outcome receives a new key and requires secret reentry.
|
|
374
420
|
submission ||= { key: crypto.randomUUID(), body: JSON.stringify(state.platform === "web" ? input() : Object.assign({}, input(), { token: $("token").value.trim() })) };
|
|
375
421
|
freezeFields(true);
|
|
376
|
-
$("finishMsg").
|
|
422
|
+
finishSay($("finishMsg").className, "requesting");
|
|
377
423
|
const commit = await api("api/settings/quickstart/commit", { method: "POST", headers: { "Content-Type": "application/json", "Idempotency-Key": submission.key }, body: submission.body });
|
|
378
|
-
if (!commit.ok) { restoreEditing(commit.body?.error
|
|
379
|
-
if (commit.body?.result !== "pending_confirmation" || !commit.body.pending_change?.id) { restoreEditing(
|
|
424
|
+
if (!commit.ok) { restoreEditing(() => finishHost(commit.body?.error, "failed")); return; }
|
|
425
|
+
if (commit.body?.result !== "pending_confirmation" || !commit.body.pending_change?.id) { restoreEditing(() => finishSay("msg err", "expectedPending")); return; }
|
|
380
426
|
$("token").value = ""; submission = null;
|
|
381
427
|
watchPending(commit.body.pending_change.id);
|
|
382
|
-
} catch { if (pageClosed) return; $("finishMsg").
|
|
428
|
+
} catch { if (pageClosed) return; finishSay($("finishMsg").className, "connectionFailed"); $("finish").disabled = false; }
|
|
383
429
|
};
|
|
384
430
|
// Same-cookie reloads rediscover an unresolved consent request without a secret.
|
|
385
431
|
const status = api("setup/status").then(result => { if (result.ok) trackRemaining(result.body); return result; });
|
|
@@ -389,8 +435,8 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
389
435
|
if (pending) { watchPending(pending.id); return; }
|
|
390
436
|
status.then(current => {
|
|
391
437
|
if (pageClosed || !current.ok || !current.body?.finish_ready || submission || pollGeneration) return;
|
|
392
|
-
approvedSetup = true; freezeFields(true); $("finish").disabled = false;
|
|
393
|
-
$("finishMsg").
|
|
438
|
+
approvedSetup = true; freezeFields(true); $("finish").disabled = false; setFinishLabel("start");
|
|
439
|
+
finishSay($("finishMsg").className, "confirmed");
|
|
394
440
|
}).catch(() => {});
|
|
395
441
|
}).catch(() => {});
|
|
396
442
|
|
|
@@ -402,23 +448,19 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
402
448
|
try {
|
|
403
449
|
const res = await fetch("/health", { cache: "no-store" });
|
|
404
450
|
if (res.status) {
|
|
405
|
-
$("finishMsg").className = "msg ok";
|
|
406
451
|
// #1519 P7: the fleet answers on this address now — its dashboard is here too.
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
$("finishMsg").textContent = "AgEnD is up. Talk to it in the channel you just set up, or open its dashboard: ";
|
|
415
|
-
$("finishMsg").append(link, " (sign in with agend web --code on the machine running AgEnD, or send /web to your bot).");
|
|
452
|
+
// #2233: with no bot, the dashboard is where AgEnD is used; its sign-in code comes from the machine.
|
|
453
|
+
show($("finishMsg"), el => {
|
|
454
|
+
el.className = "msg ok";
|
|
455
|
+
const link = document.createElement("a"); link.href = "/"; link.textContent = location.origin + "/";
|
|
456
|
+
const [before, after] = tr(state.platform === "web" ? "upWeb" : "upChat").split("{0}");
|
|
457
|
+
el.textContent = before; el.append(link, after ?? "");
|
|
458
|
+
});
|
|
416
459
|
return;
|
|
417
460
|
}
|
|
418
461
|
} catch { /* not listening yet */ }
|
|
419
462
|
if (Date.now() > deadline) {
|
|
420
|
-
|
|
421
|
-
$("finishMsg").textContent = "AgEnD has not come up within 60 seconds. Run \`agend start\` on the machine itself and check fleet.log — this page cannot tell you any more.";
|
|
463
|
+
finishSay("msg err", "notUp");
|
|
422
464
|
return;
|
|
423
465
|
}
|
|
424
466
|
setTimeout(tick, 1000);
|
|
@@ -429,6 +471,10 @@ export const SETUP_FORM_HTML = `<!DOCTYPE html>
|
|
|
429
471
|
$("pickTelegram").onclick = () => setPlatform("telegram");
|
|
430
472
|
$("pickDiscord").onclick = () => setPlatform("discord");
|
|
431
473
|
$("pickWeb").onclick = () => setPlatform("web");
|
|
474
|
+
$("name").addEventListener("input", () => { state.nameTyped = true; showDirHint(); });
|
|
475
|
+
$("dir").addEventListener("input", showGeneral);
|
|
476
|
+
setFinishLabel("finish");
|
|
477
|
+
showDirHint();
|
|
432
478
|
loadEnvironment();
|
|
433
479
|
setPlatform("telegram");
|
|
434
480
|
})();
|
package/dist/setup-form.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-form.js","sourceRoot":"","sources":["../src/setup-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG
|
|
1
|
+
{"version":3,"file":"setup-form.js","sourceRoot":"","sources":["../src/setup-form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE3F;;;;;;;;GAQG;AACH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAqChC,gBAAgB,CAAC,kBAAkB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCvC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+E3B,gBAAgB,CAAC,kBAAkB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4TvC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,KAAa;IACtD,OAAO;QACL,oBAAoB;QACpB,qBAAqB,KAAK,GAAG;QAC7B,oBAAoB,KAAK,GAAG;QAC5B,sBAAsB;QACtB,oBAAoB;QACpB,iBAAiB;QACjB,oBAAoB;QACpB,wBAAwB;KACzB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,+GAA+G;AAC/G,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,KAAa;IACnD,OAAO,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,kBAAkB,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,iBAAiB,KAAK,IAAI,CAAC,CAAC;AACvH,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #2726: the setup pages in English and 繁體中文.
|
|
3
|
+
*
|
|
4
|
+
* Both pages are inline (setup-form.ts) and run before any fleet — no dashboard, no /assets — so they carry their own
|
|
5
|
+
* small dictionary and the few lines that use it (SETUP_I18N_RUNTIME). The choice works as the dashboard's does
|
|
6
|
+
* (src/ui/shared/app-i18n.js): the language chosen in this browser (`agend_lang`, the dashboard's own key, so the
|
|
7
|
+
* dashboard opened afterwards on this address keeps it), else the browser's language; a toggle on the page changes it.
|
|
8
|
+
* The wording is the dashboard's where it already says the same thing (settings-strings.js wizard*).
|
|
9
|
+
*
|
|
10
|
+
* What the host says (its errors) is English, or a code: src/ui/shared/setup-host-text.js says each one the page can show
|
|
11
|
+
* in both languages — the same module the dashboard's Setup wizard uses. One it does not know is shown as it came.
|
|
12
|
+
*/
|
|
13
|
+
export type SetupLang = "en" | "zh-TW";
|
|
14
|
+
type Table = Record<string, string>;
|
|
15
|
+
/** The code-entry page: before the code, nothing about this machine (setup-form.ts SETUP_CODE_PAGE_HTML). */
|
|
16
|
+
export declare const SETUP_CODE_STRINGS: Record<SetupLang, Table>;
|
|
17
|
+
/** The setup form (setup-form.ts SETUP_FORM_HTML). */
|
|
18
|
+
export declare const SETUP_FORM_STRINGS: Record<SetupLang, Table>;
|
|
19
|
+
/**
|
|
20
|
+
* The few lines both pages run first: the dictionary (JSON, `<` escaped so no string can end the script), the language,
|
|
21
|
+
* `tr` (a key in it), `trHost` (a host message in it), `show` (a text that follows the language when it changes) and
|
|
22
|
+
* `applyLang`. Plain script, no `${` and no template literal: it is pasted into the pages' own template strings.
|
|
23
|
+
*/
|
|
24
|
+
export declare function setupI18nRuntime(strings: Record<SetupLang, Table>): string;
|
|
25
|
+
export {};
|