zigmini 0.9.0-beta.3 → 1.0.0-beta.2
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.ko.md +36 -4
- package/README.md +36 -4
- package/assets/agent/gateway-rules.md +29 -19
- package/assets/android/zigmini.apk +0 -0
- package/assets/android/zigmini.apk.json +3 -3
- package/assets/build.json +1 -1
- package/docs/manual.ko.md +60 -11
- package/docs/manual.md +61 -12
- package/host/omo-bridge/agent-control.ts +274 -0
- package/host/omo-bridge/bridge.ts +1 -1
- package/host/omo-bridge/continuity-control.ts +1 -1
- package/host/omo-bridge/task-control.ts +26 -16
- package/host/omo-check/patches/omo-5.1.51-compaction-long-context.patch +92 -0
- package/host/omo-check/patches/omo-5.1.51-compaction-port.patch +2635 -0
- package/host/omo-check/patches/omo-5.1.51-compaction-recovery.patch +911 -0
- package/host/omo-check/patches/omo-5.1.51-gateway-port.manifest.json +363 -0
- package/host/omo-check/patches/omo-5.1.51-provider-failover.patch +50 -0
- package/host/omo-check/patches/omo-5.1.51-provider-port.patch +441 -0
- package/host/omo-check/patches/omo-5.1.51-rpc-port.patch +799 -0
- package/host/omo-check/patches/omo-5.1.51-runtime-compat.patch +31 -0
- package/package.json +3 -2
- package/src/agent/api.ts +215 -0
- package/src/agent/definition.ts +177 -0
- package/src/agent/fields.ts +42 -0
- package/src/agent/files.ts +192 -0
- package/src/agent/legacy-files.ts +46 -0
- package/src/agent/list.ts +21 -0
- package/src/agent-rules.ts +97 -13
- package/src/approvals.ts +6 -1
- package/src/cli/doctor.ts +7 -0
- package/src/cli/main.ts +38 -0
- package/src/cli/messages.ts +10 -2
- package/src/cli/rotate-main.ts +2 -1
- package/src/cli/rules.ts +70 -0
- package/src/cli/scan.ts +414 -0
- package/src/cli/security-import.ts +155 -0
- package/src/compact.ts +22 -0
- package/src/decisions.ts +6 -4
- package/src/engine/compat.json +3 -3
- package/src/engine/index.ts +1 -0
- package/src/engine/schema-guard.ts +12 -4
- package/src/engine/sdk.ts +8 -0
- package/src/formal-verification.ts +366 -0
- package/src/gc.ts +37 -6
- package/src/hub.ts +339 -79
- package/src/main.ts +95 -9
- package/src/maintenance.ts +1 -1
- package/src/manual.ts +9 -2
- package/src/profile-prompt.ts +73 -0
- package/src/profile.ts +33 -10
- package/src/protocol.ts +11 -2
- package/src/question-notifications.ts +4 -1
- package/src/reply-notifications.ts +7 -1
- package/src/repo-security-setting.ts +33 -0
- package/src/runtime/paths.ts +16 -0
- package/src/security/baseline.ts +172 -0
- package/src/security/dex-strings.ts +242 -0
- package/src/security/repo-scan.ts +369 -0
- package/src/security/revision-probe.ts +144 -0
- package/src/security/terms.ts +97 -0
- package/src/security-allow.ts +1 -0
- package/src/security-baseline.ts +113 -0
- package/src/security-check.ts +91 -16
- package/src/server-text.ts +38 -0
- package/src/store.ts +142 -16
- package/src/transcript.ts +7 -1
- package/src/ui-language.ts +33 -0
- package/src/update/check.ts +7 -3
- package/src/update/handoff-system.ts +24 -16
- package/src/update/handoff.ts +23 -12
- package/src/update/helper.ts +72 -36
- package/src/update/request.ts +46 -30
- package/src/update/state.ts +21 -11
- package/src/update/strategy.ts +12 -5
- package/src/update/target.ts +32 -15
- package/src/usage.ts +43 -20
- package/src/version.ts +39 -16
- package/src/voice/agents.ts +8 -3
- package/src/voice/install.ts +29 -18
- package/src/work-watch.ts +40 -18
- package/web/agent-icon.js +15 -9
- package/web/agents.d.ts +201 -0
- package/web/agents.js +813 -0
- package/web/app-download.js +32 -19
- package/web/app.js +1407 -278
- package/web/autocopy.js +6 -1
- package/web/boot.js +27 -8
- package/web/commands.js +20 -11
- package/web/decisions.js +70 -49
- package/web/devlog.js +25 -19
- package/web/diagram.js +8 -3
- package/web/enroll.js +43 -22
- package/web/gc.js +32 -19
- package/web/i18n/agent-icon.js +24 -0
- package/web/i18n/agents.js +48 -0
- package/web/i18n/app-download.js +26 -0
- package/web/i18n/autocopy.js +5 -0
- package/web/i18n/boot.js +24 -0
- package/web/i18n/commands.js +34 -0
- package/web/i18n/decisions.js +24 -0
- package/web/i18n/devlog.js +60 -0
- package/web/i18n/diagram.js +12 -0
- package/web/i18n/enroll.js +22 -0
- package/web/i18n/gc.js +38 -0
- package/web/i18n/lastsent.js +10 -0
- package/web/i18n/main.d.ts +4 -0
- package/web/i18n/main.js +527 -0
- package/web/i18n/manual.d.ts +4 -0
- package/web/i18n/manual.js +14 -0
- package/web/i18n/memo.js +30 -0
- package/web/i18n/notifications.js +16 -0
- package/web/i18n/profile.js +13 -0
- package/web/i18n/reference.js +26 -0
- package/web/i18n/security-inbox.js +40 -0
- package/web/i18n/slash.js +38 -0
- package/web/i18n/turn-stats.js +5 -0
- package/web/i18n/update.js +42 -0
- package/web/i18n/voice.js +28 -0
- package/web/i18n/wake.js +16 -0
- package/web/i18n/workid.js +10 -0
- package/web/i18n/workstatus.js +20 -0
- package/web/i18n.d.ts +20 -0
- package/web/i18n.js +63 -0
- package/web/index.html +156 -96
- package/web/lastsent.js +9 -4
- package/web/manual.d.ts +1 -1
- package/web/manual.js +11 -5
- package/web/memo.js +18 -13
- package/web/notifications.js +12 -7
- package/web/profile.js +42 -17
- package/web/reference.js +20 -15
- package/web/security-inbox.d.ts +18 -1
- package/web/security-inbox.js +173 -4
- package/web/slash.js +23 -13
- package/web/style.css +132 -3
- package/web/tooltip.js +5 -2
- package/web/turn-stats.js +6 -2
- package/web/update.js +31 -23
- package/web/voice.js +18 -8
- package/web/wake.d.ts +4 -0
- package/web/wake.js +7 -3
- package/web/workid.js +12 -2
- package/web/workstatus.js +36 -32
package/web/index.html
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<html lang="
|
|
2
|
+
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
@@ -11,20 +11,23 @@
|
|
|
11
11
|
<aside class="sidebar">
|
|
12
12
|
<header class="sidebar-head">
|
|
13
13
|
<span class="sidebar-title">zigmini</span>
|
|
14
|
-
<span class="badge" id="omo-status"
|
|
14
|
+
<span class="badge" id="omo-status" data-i18n="side.engine" data-i18n-attr="title:side.engine.tip">Engine</span>
|
|
15
15
|
</header>
|
|
16
16
|
<div class="sidebar-section">
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
<
|
|
17
|
+
<ul class="conv-list main-list" id="conv-list"></ul>
|
|
18
|
+
<div class="agent-group" id="agent-group">
|
|
19
|
+
<div class="section-label">
|
|
20
|
+
<span data-i18n="side.agents">Agents</span>
|
|
21
|
+
<button type="button" class="icon-btn agent-manage" id="agent-manage" data-i18n-attr="title:side.agentManage.tip" aria-haspopup="dialog" aria-controls="agents" aria-expanded="false">⋯</button>
|
|
22
|
+
</div>
|
|
23
|
+
<ul class="conv-list agent-list" id="agent-list" data-i18n-attr="aria-label:side.agentList.label"></ul>
|
|
20
24
|
</div>
|
|
21
|
-
<ul class="conv-list" id="conv-list"></ul>
|
|
22
25
|
</div>
|
|
23
26
|
<section class="work-status" id="work-status" aria-labelledby="work-status-title" tabindex="-1">
|
|
24
27
|
<div class="ws-head">
|
|
25
|
-
<button type="button" class="ws-back" id="status-back" aria-label
|
|
26
|
-
<span class="ws-title" id="work-status-title"
|
|
27
|
-
<button type="button" class="ws-fold" id="work-status-fold" aria-controls="work-status-body" aria-expanded="true" aria-label
|
|
28
|
+
<button type="button" class="ws-back" id="status-back" data-i18n-attr="aria-label:status.backToChat;title:status.backToChat"><img src="zigmini-profile.svg" alt="" width="26" height="26" /></button>
|
|
29
|
+
<span class="ws-title" id="work-status-title" data-i18n="status.title">Work status</span>
|
|
30
|
+
<button type="button" class="ws-fold" id="work-status-fold" aria-controls="work-status-body" aria-expanded="true" data-i18n-attr="aria-label:status.fold;title:status.fold"><svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true" focusable="false"><path d="M4 6l4 4 4-4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg></button>
|
|
28
31
|
</div>
|
|
29
32
|
<div class="ws-body" id="work-status-body">
|
|
30
33
|
<div class="ws-graph" id="work-status-graph"></div>
|
|
@@ -34,193 +37,250 @@
|
|
|
34
37
|
<div class="ws-tip" id="work-status-tip" role="tooltip" hidden></div>
|
|
35
38
|
</section>
|
|
36
39
|
<footer class="sidebar-foot">
|
|
37
|
-
<div class="me" id="owner-profile"
|
|
38
|
-
<div class="avatar me-avatar"
|
|
40
|
+
<div class="me" id="owner-profile" data-i18n-attr="title:profile.editNickname.tip">
|
|
41
|
+
<div class="avatar me-avatar">Me</div>
|
|
39
42
|
<div class="me-text">
|
|
40
|
-
<div class="me-name"
|
|
41
|
-
<div class="me-sub" id="conn-status"
|
|
43
|
+
<div class="me-name">Me</div>
|
|
44
|
+
<div class="me-sub" id="conn-status">Connecting</div>
|
|
42
45
|
</div>
|
|
43
46
|
</div>
|
|
44
|
-
<div class="me agent" id="agent-profile"
|
|
45
|
-
<div class="avatar agent-avatar"
|
|
47
|
+
<div class="me agent" id="agent-profile" data-i18n-attr="title:profile.editAgentName.tip">
|
|
48
|
+
<div class="avatar agent-avatar" data-i18n-attr="title:profile.editAgentIcon.tip"><img src="zigmini-profile.svg" alt="" width="36" height="36" /></div>
|
|
46
49
|
<div class="me-text">
|
|
47
|
-
<div class="me-name agent-name"
|
|
48
|
-
<div class="me-sub"
|
|
50
|
+
<div class="me-name agent-name">Zig</div>
|
|
51
|
+
<div class="me-sub" data-i18n="profile.agent">Default agent</div>
|
|
49
52
|
</div>
|
|
50
53
|
</div>
|
|
51
54
|
</footer>
|
|
52
55
|
</aside>
|
|
53
56
|
<main class="chat">
|
|
54
57
|
<header class="chat-head">
|
|
55
|
-
<button type="button" class="head-track" id="toggle-status" aria-label
|
|
58
|
+
<button type="button" class="head-track" id="toggle-status" data-i18n-attr="aria-label:status.open;title:status.open" aria-controls="work-status" aria-expanded="false"><img class="head-avatar" id="head-avatar" src="zigmini-profile.svg" alt="" width="30" height="30" /></button>
|
|
56
59
|
<span id="conv-title" hidden>main</span>
|
|
60
|
+
<div class="agent-head" id="agent-head" hidden>
|
|
61
|
+
<span class="agent-head-icon" id="agent-head-icon" aria-hidden="true"></span>
|
|
62
|
+
<span class="agent-head-name" id="agent-head-name"></span>
|
|
63
|
+
<button type="button" class="agent-stale" id="agent-stale" data-i18n="agent.staleBadge" hidden>Definition changed · applies from the next session</button>
|
|
64
|
+
</div>
|
|
57
65
|
<span class="chat-sub" id="conv-thread"></span>
|
|
58
|
-
<span class="transition-status" id="session-transition" role="status" aria-live="polite" hidden
|
|
59
|
-
<span class="login-notice" id="login-notice" role="status" hidden
|
|
66
|
+
<span class="transition-status" id="session-transition" role="status" aria-live="polite" data-i18n="head.sessionTransition" hidden>Switching session</span>
|
|
67
|
+
<span class="login-notice" id="login-notice" role="status" data-i18n="head.loginNotice" hidden>Sign in to your model account</span>
|
|
60
68
|
<span class="login-notice" id="schema-notice" role="alert" hidden></span>
|
|
61
|
-
<button type="button" class="update-notice" id="update-notice"
|
|
69
|
+
<button type="button" class="update-notice" id="update-notice" data-i18n-attr="title:head.updateNotice.tip" hidden></button>
|
|
62
70
|
<div class="chat-actions">
|
|
63
|
-
<select class="model-select" id="model-select"
|
|
71
|
+
<select class="model-select" id="model-select" data-i18n-attr="title:model.select.tip" disabled><option data-i18n="model.loading">Loading models</option></select>
|
|
64
72
|
<span class="model-pending" id="model-pending" hidden></span>
|
|
65
|
-
<button class="text-btn" id="rotate-session" data-tip-keep
|
|
66
|
-
<button class="text-btn" id="toggle-voice" data-tip-keep
|
|
67
|
-
<button class="text-btn" id="voice-install" data-tip-keep
|
|
68
|
-
<button class="text-btn" id="toggle-clap" data-tip-keep
|
|
69
|
-
<button class="text-btn" id="toggle-wake" data-tip-keep
|
|
70
|
-
<button class="text-btn" id="toggle-tts" data-tip-keep
|
|
71
|
-
<button type="button" class="text-btn inbox-toggle" id="toggle-inbox" data-tip-keep
|
|
72
|
-
<button type="button" class="text-btn" id="toggle-dev" data-tip-keep
|
|
73
|
-
<button type="button" class="text-btn" id="toggle-
|
|
73
|
+
<button class="text-btn" id="rotate-session" data-tip-keep data-i18n="head.newSession" data-i18n-tip="head.newSession.tip">New session</button>
|
|
74
|
+
<button class="text-btn" id="toggle-voice" data-tip-keep data-i18n-tip="head.voice.tip" aria-pressed="true">Voice on</button>
|
|
75
|
+
<button class="text-btn" id="voice-install" data-tip-keep data-i18n-tip="head.voiceInstall.tip" hidden>Install voice</button>
|
|
76
|
+
<button class="text-btn" id="toggle-clap" data-tip-keep data-i18n-tip="head.clap.tip" aria-pressed="false">Clap detection off</button>
|
|
77
|
+
<button class="text-btn" id="toggle-wake" data-tip-keep data-i18n-tip="head.wake.tip" aria-pressed="false">Wake word off</button>
|
|
78
|
+
<button class="text-btn" id="toggle-tts" data-tip-keep data-i18n-tip="head.tts.tip" aria-pressed="false">Spoken replies off</button>
|
|
79
|
+
<button type="button" class="text-btn inbox-toggle" id="toggle-inbox" data-tip-keep data-i18n-tip="head.inbox.tip" aria-haspopup="dialog" aria-expanded="false" aria-controls="inbox" aria-keyshortcuts="Control+C"><span data-i18n="inbox.title">Inbox</span><span class="inbox-badge" id="inbox-badge" hidden>0</span></button>
|
|
80
|
+
<button type="button" class="text-btn" id="toggle-dev" data-tip-keep data-i18n="dev.title" data-i18n-tip="head.events.tip" aria-expanded="false" aria-controls="dev" aria-keyshortcuts="Control+E">Events</button>
|
|
81
|
+
<button type="button" class="text-btn" id="toggle-agents" data-i18n="side.agents" data-i18n-attr="title:head.agents.tip" aria-haspopup="dialog" aria-expanded="false" aria-controls="agents">Agents</button>
|
|
82
|
+
<button type="button" class="text-btn" id="toggle-settings" data-i18n="settings.title" data-i18n-attr="title:head.settings.tip" aria-haspopup="dialog" aria-expanded="false" aria-controls="settings">Settings</button>
|
|
74
83
|
</div>
|
|
75
84
|
</header>
|
|
76
|
-
<div class="last-sent" id="last-sent" role="button" tabindex="0" aria-expanded="false" aria-label
|
|
85
|
+
<div class="last-sent" id="last-sent" role="button" tabindex="0" aria-expanded="false" data-i18n-attr="aria-label:chat.lastSent.label" hidden></div>
|
|
77
86
|
<div class="device-requests" id="device-requests"></div>
|
|
78
87
|
<div class="messages-wrap">
|
|
79
88
|
<section class="messages" id="messages" aria-live="polite"></section>
|
|
80
89
|
<div class="memo" id="memo" hidden>
|
|
81
|
-
<div class="memo-head"><span
|
|
82
|
-
<textarea class="memo-text" id="memo-text"
|
|
83
|
-
<input id="memo-image-input" type="file" accept="image/png,image/jpeg,image/gif,image/webp" multiple aria-label
|
|
90
|
+
<div class="memo-head"><span data-i18n="memo.title">Memo</span><span id="memo-image-count">0/2</span><button class="text-btn" id="memo-add-image" type="button" data-i18n="memo.addImage">Keep an image</button></div>
|
|
91
|
+
<textarea class="memo-text" id="memo-text" data-i18n-attr="placeholder:memo.placeholder" spellcheck="false"></textarea>
|
|
92
|
+
<input id="memo-image-input" type="file" accept="image/png,image/jpeg,image/gif,image/webp" multiple data-i18n-attr="aria-label:memo.imageInput.label" hidden>
|
|
84
93
|
<div id="memo-images" class="memo-images" hidden></div>
|
|
85
94
|
<div id="memo-status" class="memo-status" role="status" aria-live="polite"></div>
|
|
86
|
-
<div class="memo-resize" id="memo-resize"
|
|
95
|
+
<div class="memo-resize" id="memo-resize" data-i18n-attr="title:memo.resize.tip"></div>
|
|
87
96
|
</div>
|
|
88
97
|
<div class="scroll-nav">
|
|
89
|
-
<button type="button" class="nav-btn" id="nav-prev"
|
|
90
|
-
<button type="button" class="nav-btn" id="nav-next"
|
|
98
|
+
<button type="button" class="nav-btn" id="nav-prev" data-i18n-attr="title:chat.nav.prev;aria-label:chat.nav.prev">▲</button>
|
|
99
|
+
<button type="button" class="nav-btn" id="nav-next" data-i18n-attr="title:chat.nav.next;aria-label:chat.nav.next.label">▼</button>
|
|
91
100
|
</div>
|
|
92
101
|
</div>
|
|
93
102
|
<div class="ref-tray" id="ref-tray" hidden>
|
|
94
|
-
<ul class="ref-list" id="ref-list" aria-label
|
|
103
|
+
<ul class="ref-list" id="ref-list" data-i18n-attr="aria-label:refs.label"></ul>
|
|
95
104
|
<span class="ref-note" id="ref-note" role="status" aria-live="polite"></span>
|
|
96
105
|
</div>
|
|
97
106
|
<div class="attach-tray" id="attach-tray" hidden></div>
|
|
98
107
|
<form class="composer" id="composer">
|
|
99
|
-
<div class="slash-menu" id="slash-menu" role="listbox" aria-label
|
|
100
|
-
<button type="button" class="mic" id="toggle-memo"
|
|
101
|
-
<button type="button" class="mic" id="attach"
|
|
108
|
+
<div class="slash-menu" id="slash-menu" role="listbox" data-i18n-attr="aria-label:slash.label" hidden></div>
|
|
109
|
+
<button type="button" class="mic" id="toggle-memo" data-i18n="memo.title" data-i18n-attr="title:memo.toggle.tip" aria-pressed="false">Memo</button>
|
|
110
|
+
<button type="button" class="mic" id="attach" data-i18n="attach.button" data-i18n-attr="title:attach.tip">Image</button>
|
|
102
111
|
<input type="file" id="attach-input" accept="image/png,image/jpeg,image/gif,image/webp" multiple hidden>
|
|
103
|
-
<button type="button" class="mic" id="mic" data-tip-keep
|
|
104
|
-
<textarea id="input" rows="1"
|
|
105
|
-
<button type="submit" class="send" id="send"
|
|
106
|
-
<button type="button" class="stop" id="interrupt"
|
|
112
|
+
<button type="button" class="mic" id="mic" data-tip-keep data-i18n-tip="composer.mic.tip">Mic</button>
|
|
113
|
+
<textarea id="input" rows="1" data-i18n-attr="placeholder:composer.placeholder;title:composer.input.tip"></textarea>
|
|
114
|
+
<button type="submit" class="send" id="send">Send</button>
|
|
115
|
+
<button type="button" class="stop" id="interrupt" data-i18n="composer.stop" data-i18n-attr="title:composer.stop.tip" hidden>Stop</button>
|
|
107
116
|
</form>
|
|
108
117
|
</main>
|
|
109
118
|
<aside class="inbox" id="inbox" role="dialog" aria-labelledby="inbox-title" hidden>
|
|
110
119
|
<header class="inbox-head">
|
|
111
|
-
<h2 class="inbox-title" id="inbox-title" tabindex="-1"
|
|
120
|
+
<h2 class="inbox-title" id="inbox-title" tabindex="-1" data-i18n="inbox.title">Inbox</h2>
|
|
112
121
|
<span class="inbox-summary" id="inbox-summary"></span>
|
|
113
|
-
<button type="button" class="icon-btn inbox-close" id="inbox-close" aria-label
|
|
122
|
+
<button type="button" class="icon-btn inbox-close" id="inbox-close" data-i18n-attr="aria-label:inbox.close;title:common.closeEsc">×</button>
|
|
114
123
|
</header>
|
|
115
124
|
<div class="inbox-status" id="inbox-status" role="status" aria-live="polite"></div>
|
|
116
|
-
<ul class="inbox-list" id="inbox-list" aria-label
|
|
125
|
+
<ul class="inbox-list" id="inbox-list" data-i18n-attr="aria-label:inbox.list.label"></ul>
|
|
117
126
|
<footer class="inbox-foot" hidden>
|
|
118
|
-
<button type="button" class="text-btn" id="inbox-more"
|
|
127
|
+
<button type="button" class="text-btn" id="inbox-more" data-i18n="common.more">Show more</button>
|
|
119
128
|
</footer>
|
|
120
129
|
</aside>
|
|
121
130
|
<aside class="settings" id="settings" role="dialog" aria-labelledby="settings-title" hidden>
|
|
122
131
|
<div class="settings-card">
|
|
123
132
|
<header class="settings-head">
|
|
124
|
-
<h2 class="settings-title" id="settings-title" tabindex="-1"
|
|
125
|
-
<button type="button" class="text-btn" id="manual-open"
|
|
126
|
-
<button type="button" class="icon-btn settings-close" id="settings-close" aria-label
|
|
133
|
+
<h2 class="settings-title" id="settings-title" tabindex="-1" data-i18n="settings.title">Settings</h2>
|
|
134
|
+
<button type="button" class="text-btn" id="manual-open" data-i18n="manual.title" data-i18n-attr="title:manual.open.tip" aria-haspopup="dialog" aria-expanded="false" aria-controls="manual">Manual</button>
|
|
135
|
+
<button type="button" class="icon-btn settings-close" id="settings-close" data-i18n-attr="aria-label:settings.close;title:common.closeEsc">×</button>
|
|
127
136
|
</header>
|
|
128
137
|
<div class="settings-body">
|
|
138
|
+
<section class="settings-section" id="language-settings" aria-labelledby="language-title">
|
|
139
|
+
<div class="section-label"><label id="language-title" for="ui-language" data-i18n="settings.language.title">Language</label></div>
|
|
140
|
+
<div class="access-form">
|
|
141
|
+
<select class="access-input" id="ui-language" aria-describedby="language-description"></select>
|
|
142
|
+
</div>
|
|
143
|
+
<p class="update-note" id="language-description" data-i18n="settings.language.note">Applies to the web UI and the app of this gateway. The manual opens in this language too.</p>
|
|
144
|
+
</section>
|
|
129
145
|
<section class="settings-section update" id="update" aria-labelledby="update-title">
|
|
130
|
-
<div class="section-label"><span id="update-title"
|
|
146
|
+
<div class="section-label"><span id="update-title" data-i18n="settings.update.title">Update</span></div>
|
|
131
147
|
<p class="update-line" id="update-current"></p>
|
|
132
148
|
<p class="update-line" id="update-latest" role="status" aria-live="polite"></p>
|
|
133
149
|
<p class="update-note" id="update-error" role="status" hidden></p>
|
|
134
150
|
<p class="update-note" id="update-note" hidden></p>
|
|
135
|
-
<a class="update-link" id="update-changelog" target="_blank" rel="noopener noreferrer" hidden
|
|
151
|
+
<a class="update-link" id="update-changelog" target="_blank" rel="noopener noreferrer" data-i18n="settings.update.changelog" hidden>See what changed</a>
|
|
136
152
|
<p class="update-note" id="update-warning" hidden></p>
|
|
137
153
|
<div class="update-ask update-questions" id="update-questions" hidden>
|
|
138
154
|
<p class="update-line" id="update-questions-line" role="status" aria-live="polite"></p>
|
|
139
|
-
<button type="button" class="update-run" id="update-questions-open"
|
|
155
|
+
<button type="button" class="update-run" id="update-questions-open" data-i18n="settings.update.openInbox">Open the inbox</button>
|
|
140
156
|
</div>
|
|
141
157
|
<div class="update-buttons">
|
|
142
|
-
<button type="button" class="update-run" id="update-check"
|
|
143
|
-
<button type="button" class="update-run" id="update-run" hidden
|
|
158
|
+
<button type="button" class="update-run" id="update-check" data-i18n="settings.update.checkNow">Check now</button>
|
|
159
|
+
<button type="button" class="update-run" id="update-run" data-i18n="settings.update.run" hidden>Update</button>
|
|
144
160
|
</div>
|
|
145
161
|
<div class="update-ask" id="update-ask" hidden>
|
|
146
162
|
<p class="update-line" id="update-ask-message"></p>
|
|
147
163
|
<pre class="update-ask-text" id="update-ask-text" hidden></pre>
|
|
148
|
-
<input class="update-ask-input" id="update-ask-input" type="text" autocomplete="off" aria-label
|
|
164
|
+
<input class="update-ask-input" id="update-ask-input" type="text" autocomplete="off" data-i18n-attr="aria-label:settings.update.consentInput.label" hidden>
|
|
149
165
|
<button type="button" class="update-run" id="update-ask-go"></button>
|
|
150
166
|
</div>
|
|
151
167
|
<p class="update-line" id="update-progress" role="status" aria-live="polite" hidden></p>
|
|
152
168
|
</section>
|
|
153
169
|
<section class="settings-section enroll" id="enroll" aria-labelledby="enroll-title">
|
|
154
|
-
<div class="section-label"><span id="enroll-title"
|
|
155
|
-
<div class="enroll-qr" id="enroll-qr" role="img" aria-label
|
|
170
|
+
<div class="section-label"><span id="enroll-title" data-i18n="settings.enroll.title">Device enrollment</span><span class="enroll-left" id="enroll-left" role="timer" aria-live="off"></span></div>
|
|
171
|
+
<div class="enroll-qr" id="enroll-qr" role="img" data-i18n-attr="aria-label:settings.enroll.qrLabel" hidden></div>
|
|
156
172
|
<p class="enroll-message" id="enroll-message" role="status" aria-live="polite"></p>
|
|
157
|
-
<div class="enroll-actions"><button type="button" class="text-btn" id="enroll-renew" hidden
|
|
158
|
-
<div class="section-label"><span
|
|
159
|
-
<ul class="device-list" id="device-list" aria-label
|
|
160
|
-
<div class="section-label"><span id="access-title"
|
|
173
|
+
<div class="enroll-actions"><button type="button" class="text-btn" id="enroll-renew" data-i18n="settings.enroll.renew" hidden>Make a new one</button></div>
|
|
174
|
+
<div class="section-label"><span data-i18n="settings.devices.title">Registered devices</span></div>
|
|
175
|
+
<ul class="device-list" id="device-list" data-i18n-attr="aria-label:settings.devices.title"></ul>
|
|
176
|
+
<div class="section-label"><span id="access-title" data-i18n="settings.access.title">External access</span></div>
|
|
161
177
|
<p class="enroll-message" id="access-current"></p>
|
|
162
178
|
<form class="access-form" id="access-form" aria-labelledby="access-title">
|
|
163
|
-
<select class="access-input" id="access-choice" aria-label
|
|
164
|
-
<option value="lan"
|
|
165
|
-
<option value="tailscale">Tailscale</option>
|
|
166
|
-
<option value="domain"
|
|
179
|
+
<select class="access-input" id="access-choice" data-i18n-attr="aria-label:settings.access.choice.label">
|
|
180
|
+
<option value="lan" data-i18n="settings.access.homeWifi">Home Wi-Fi only</option>
|
|
181
|
+
<option value="tailscale" data-i18n="settings.access.tailscale">Tailscale</option>
|
|
182
|
+
<option value="domain" data-i18n="settings.access.domainOption">Your own domain (https)</option>
|
|
167
183
|
</select>
|
|
168
|
-
<input class="access-input" id="access-domain" type="url"
|
|
169
|
-
<button type="submit" class="text-btn" id="access-save"
|
|
184
|
+
<input class="access-input" id="access-domain" type="url" data-i18n-attr="placeholder:settings.access.domain.placeholder;aria-label:settings.access.domain.label" hidden>
|
|
185
|
+
<button type="submit" class="text-btn" id="access-save" data-i18n="common.change">Change</button>
|
|
170
186
|
</form>
|
|
171
187
|
<p class="enroll-message" id="access-message" role="status" aria-live="polite"></p>
|
|
172
188
|
</section>
|
|
173
189
|
<section class="settings-section enroll app-download" id="app-download" aria-labelledby="apk-title">
|
|
174
|
-
<div class="section-label"><span id="apk-title"
|
|
175
|
-
<div class="enroll-qr" id="apk-qr" role="img" aria-label
|
|
190
|
+
<div class="section-label"><span id="apk-title" data-i18n="settings.apk.title">Download the app</span><span class="enroll-left" id="apk-left" role="timer" aria-live="off"></span></div>
|
|
191
|
+
<div class="enroll-qr" id="apk-qr" role="img" data-i18n-attr="aria-label:settings.apk.qrLabel" hidden></div>
|
|
176
192
|
<p class="apk-version" id="apk-version" hidden></p>
|
|
177
193
|
<p class="enroll-message" id="apk-message" role="status" aria-live="polite"></p>
|
|
178
|
-
<div class="enroll-actions"><button type="button" class="text-btn" id="apk-renew" hidden
|
|
194
|
+
<div class="enroll-actions"><button type="button" class="text-btn" id="apk-renew" data-i18n="settings.enroll.renew" hidden>Make a new one</button></div>
|
|
195
|
+
</section>
|
|
196
|
+
<section class="settings-section formal-verification" id="formal-verification" aria-labelledby="formal-verification-title">
|
|
197
|
+
<div class="section-label"><span id="formal-verification-title" data-i18n="settings.formal.title">Formal verification</span></div>
|
|
198
|
+
<ul class="formal-tools" id="formal-tools" data-i18n-attr="aria-label:settings.formal.tools.label"></ul>
|
|
179
199
|
</section>
|
|
180
200
|
<section class="settings-section security-check" id="security-check" aria-labelledby="security-check-title">
|
|
181
|
-
<div class="section-label"><span id="security-check-title"
|
|
182
|
-
<
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
201
|
+
<div class="section-label"><span id="security-check-title" data-i18n="settings.security.title">Security check</span></div>
|
|
202
|
+
<div class="switch-row">
|
|
203
|
+
<span class="switch-label" id="toggle-security-label" data-i18n="settings.security.message.title">Message check before the engine</span>
|
|
204
|
+
<button type="button" class="info-tip" data-tip-keep data-i18n-tip="settings.security.message.detail" data-i18n-attr="aria-label:common.details">i</button>
|
|
205
|
+
<button type="button" class="switch" id="toggle-security" role="switch" aria-checked="true" aria-labelledby="toggle-security-label" aria-describedby="toggle-security-summary"></button>
|
|
206
|
+
</div>
|
|
207
|
+
<p class="update-note switch-summary" id="toggle-security-summary" data-i18n="settings.security.message.summary">A message that carries a secret, a home folder path or an internal IP is held, and you are asked before it goes to the engine.</p>
|
|
208
|
+
<div class="switch-row">
|
|
209
|
+
<span class="switch-label" id="toggle-repo-security-label" data-i18n="settings.security.repo.title">Output check</span>
|
|
210
|
+
<button type="button" class="info-tip" data-tip-keep data-i18n-tip="settings.security.repo.detail" data-i18n-attr="aria-label:common.details">i</button>
|
|
211
|
+
<button type="button" class="switch" id="toggle-repo-security" role="switch" aria-checked="true" aria-labelledby="toggle-repo-security-label" aria-describedby="toggle-repo-security-summary"></button>
|
|
212
|
+
</div>
|
|
213
|
+
<p class="update-note switch-summary" id="toggle-repo-security-summary" data-i18n="settings.security.repo.summary">zigmini scan finds secrets, personal data and the security baseline values in work output (repositories) before they leave for GitHub.</p>
|
|
214
|
+
<div class="section-label"><span data-i18n="settings.security.allowed.title">Remembered exact values</span></div>
|
|
215
|
+
<p class="update-note" data-i18n="settings.security.allowed.note">Only values approved on this installation are allowed from the next check on. Remove and Delete all drop the values as of that moment; they are held again at the next check, and a transfer already started is not cancelled. Allowing a transfer does not affect the repository and release security checks. Only a value with "Also allowed in repository checks" turned on passes the repository check; a value equal to an automatic item (home folder path, account name) cannot be turned on.</p>
|
|
186
216
|
<div class="update-buttons">
|
|
187
|
-
<button type="button" class="text-btn" id="security-allowed-refresh"
|
|
188
|
-
<button type="button" class="text-btn" id="security-allowed-clear" disabled
|
|
217
|
+
<button type="button" class="text-btn" id="security-allowed-refresh" data-i18n="settings.security.refreshList">Check the list / retry</button>
|
|
218
|
+
<button type="button" class="text-btn" id="security-allowed-clear" disabled data-i18n="settings.security.allowed.clearAll">Delete all</button>
|
|
189
219
|
</div>
|
|
190
220
|
<p class="enroll-message" id="security-allowed-status" role="status" aria-live="polite"></p>
|
|
191
|
-
<ul class="security-allowed-list" id="security-allowed-list" aria-label
|
|
221
|
+
<ul class="security-allowed-list" id="security-allowed-list" data-i18n-attr="aria-label:settings.security.allowed.title"></ul>
|
|
192
222
|
<div class="inbox-dismiss mode-cancel" id="security-allowed-confirm" hidden>
|
|
193
|
-
<p class="inbox-dismiss-text"
|
|
194
|
-
<button type="button" class="text-btn danger" id="security-allowed-remove"
|
|
195
|
-
<button type="button" class="text-btn" id="security-allowed-keep"
|
|
223
|
+
<p class="inbox-dismiss-text" data-i18n="settings.security.allowed.confirmText">Removes the selected value, or every value as of now. They are held again from the next check; a transfer already started is not cancelled.</p>
|
|
224
|
+
<button type="button" class="text-btn danger" id="security-allowed-remove" data-i18n="settings.security.allowed.confirmRemove">Confirm removal</button>
|
|
225
|
+
<button type="button" class="text-btn" id="security-allowed-keep" data-i18n="common.keep">Keep</button>
|
|
226
|
+
</div>
|
|
227
|
+
<div class="section-label"><span id="security-baseline-title" data-i18n="settings.security.baseline.title">Security baseline</span></div>
|
|
228
|
+
<p class="update-note" data-i18n="settings.security.baseline.note">The private strings the repository and release security checks look for. The gateway writes this list out as the baseline file, and `zigmini scan` checks with that file. The home folder path and the account name are automatic items and cannot be removed. The values show only on this screen.</p>
|
|
229
|
+
<form class="access-form" id="security-baseline-form" aria-labelledby="security-baseline-title">
|
|
230
|
+
<input class="access-input" id="security-baseline-input" type="text" autocomplete="off" spellcheck="false" data-i18n-attr="placeholder:settings.security.baseline.input;aria-label:settings.security.baseline.input">
|
|
231
|
+
<button type="submit" class="text-btn" id="security-baseline-add" disabled data-i18n="common.add">Add</button>
|
|
232
|
+
<button type="button" class="text-btn" id="security-baseline-refresh" disabled data-i18n="settings.security.refreshList">Check the list / retry</button>
|
|
233
|
+
</form>
|
|
234
|
+
<p class="enroll-message" id="security-baseline-status" role="status" aria-live="polite"></p>
|
|
235
|
+
<p class="enroll-message" id="security-baseline-export"></p>
|
|
236
|
+
<ul class="security-allowed-list" id="security-baseline-list" data-i18n-attr="aria-label:settings.security.baseline.list.label"></ul>
|
|
237
|
+
<div class="inbox-dismiss mode-cancel" id="security-baseline-confirm" hidden>
|
|
238
|
+
<p class="inbox-dismiss-text" data-i18n="settings.security.baseline.confirmText">Removes this term from the baseline. The next repository check no longer looks for it. A check already started does not change.</p>
|
|
239
|
+
<button type="button" class="text-btn danger" id="security-baseline-remove" data-i18n="settings.security.baseline.confirmRemove">Confirm deletion</button>
|
|
240
|
+
<button type="button" class="text-btn" id="security-baseline-keep" data-i18n="common.keep">Keep</button>
|
|
196
241
|
</div>
|
|
197
242
|
</section>
|
|
198
243
|
<section class="settings-section" id="notification-settings" aria-labelledby="notification-title">
|
|
199
|
-
<div class="section-label"><label id="notification-title" for="notification-mode"
|
|
244
|
+
<div class="section-label"><label id="notification-title" for="notification-mode" data-i18n="settings.notification.title">Notifications</label></div>
|
|
200
245
|
<div class="access-form">
|
|
201
246
|
<select class="access-input" id="notification-mode" aria-describedby="notification-description notification-status" disabled>
|
|
202
|
-
<option value="inbox-only" selected
|
|
203
|
-
<option value="all-replies"
|
|
247
|
+
<option value="inbox-only" selected data-i18n="settings.notification.inboxOnly">Inbox notifications only</option>
|
|
248
|
+
<option value="all-replies" data-i18n="settings.notification.allReplies">All reply notifications</option>
|
|
204
249
|
</select>
|
|
205
250
|
</div>
|
|
206
|
-
<p class="update-note" id="notification-description"
|
|
251
|
+
<p class="update-note" id="notification-description" data-i18n="settings.notification.description">All reply notifications include the inbox notifications and the finished-reply notifications of main and of works. Applies to every device connected to this gateway.</p>
|
|
207
252
|
<p class="enroll-message" id="notification-status" role="status" aria-live="polite"></p>
|
|
208
253
|
</section>
|
|
209
254
|
<section class="settings-section gc" id="gc" aria-labelledby="gc-title">
|
|
210
|
-
<div class="section-label"><span id="gc-title"
|
|
211
|
-
<ul class="gc-list" id="gc-list" aria-label
|
|
255
|
+
<div class="section-label"><span id="gc-title" data-i18n="settings.gc.title">Cleanup</span><span class="gc-head"><span class="gc-summary" id="gc-summary" role="status" aria-live="polite"></span><label class="gc-all" id="gc-all-label" hidden><input type="checkbox" id="gc-all"><span data-i18n="settings.gc.selectAll">Select all</span></label></span></div>
|
|
256
|
+
<ul class="gc-list" id="gc-list" data-i18n-attr="aria-label:settings.gc.list.label"></ul>
|
|
212
257
|
<p class="gc-message" id="gc-message" role="status" aria-live="polite"></p>
|
|
213
|
-
<div class="gc-actions"><button type="button" class="text-btn" id="gc-clean" disabled
|
|
258
|
+
<div class="gc-actions"><button type="button" class="text-btn" id="gc-clean" disabled data-i18n="settings.gc.clean">Clean the selected items</button></div>
|
|
214
259
|
</section>
|
|
215
260
|
</div>
|
|
216
261
|
</div>
|
|
217
262
|
</aside>
|
|
263
|
+
<aside class="settings agents" id="agents" role="dialog" aria-labelledby="agents-title" hidden>
|
|
264
|
+
<div class="settings-card agents-card">
|
|
265
|
+
<header class="settings-head agents-head">
|
|
266
|
+
<h2 class="settings-title" id="agents-title" tabindex="-1" data-i18n="side.agents">Agents</h2>
|
|
267
|
+
<nav class="agents-nav" data-i18n-attr="aria-label:agents.nav.label">
|
|
268
|
+
<button type="button" class="text-btn" id="agents-nav-list" data-view="list" data-i18n="agents.list">List</button>
|
|
269
|
+
<button type="button" class="text-btn" id="agents-nav-defaults" data-view="defaults" data-i18n="agents.defaults">Shared defaults</button>
|
|
270
|
+
<button type="button" class="text-btn" id="agents-nav-trash" data-view="trash" data-i18n="agents.trash">Archive</button>
|
|
271
|
+
</nav>
|
|
272
|
+
<button type="button" class="icon-btn settings-close" id="agents-close" data-i18n-attr="aria-label:agents.close;title:common.closeEsc">×</button>
|
|
273
|
+
</header>
|
|
274
|
+
<p class="agents-status" id="agents-status" role="status" aria-live="polite"></p>
|
|
275
|
+
<div class="settings-body agents-body" id="agents-body"></div>
|
|
276
|
+
</div>
|
|
277
|
+
</aside>
|
|
218
278
|
<aside class="settings manual" id="manual" role="dialog" aria-labelledby="manual-title" hidden>
|
|
219
279
|
<div class="settings-card manual-card">
|
|
220
280
|
<header class="settings-head">
|
|
221
|
-
<h2 class="settings-title" id="manual-title" tabindex="-1"
|
|
281
|
+
<h2 class="settings-title" id="manual-title" tabindex="-1" data-i18n="manual.title">Manual</h2>
|
|
222
282
|
<button type="button" class="text-btn" id="manual-lang">English</button>
|
|
223
|
-
<button type="button" class="icon-btn settings-close" id="manual-close" aria-label
|
|
283
|
+
<button type="button" class="icon-btn settings-close" id="manual-close" data-i18n-attr="aria-label:manual.close;title:common.closeEsc">×</button>
|
|
224
284
|
</header>
|
|
225
285
|
<p class="manual-status" id="manual-status" role="status" aria-live="polite" hidden></p>
|
|
226
286
|
<div class="manual-body msg-text" id="manual-body"></div>
|
|
@@ -228,8 +288,8 @@
|
|
|
228
288
|
</aside>
|
|
229
289
|
<aside class="dev" id="dev">
|
|
230
290
|
<header class="dev-head">
|
|
231
|
-
<span
|
|
232
|
-
<button class="text-btn" id="clear-dev"
|
|
291
|
+
<span data-i18n="dev.title">Events</span>
|
|
292
|
+
<button class="text-btn" id="clear-dev" data-i18n="dev.clear">Clear</button>
|
|
233
293
|
</header>
|
|
234
294
|
<div class="dev-log" id="dev-log"></div>
|
|
235
295
|
</aside>
|
package/web/lastsent.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import dict from "./i18n/lastsent.js";
|
|
2
|
+
import { registerStrings, t } from "./i18n.js";
|
|
3
|
+
|
|
4
|
+
registerStrings(dict);
|
|
5
|
+
|
|
1
6
|
// The one-line strip under the chat header shows the newest message the user sent in the current conversation.
|
|
2
7
|
// History pages arrive newest-first and then older ones on scroll, so only an event with a higher seq replaces it.
|
|
3
8
|
|
|
@@ -22,14 +27,14 @@ export function nextLastSent(prev, event) {
|
|
|
22
27
|
export function lastSentLabel(rec) {
|
|
23
28
|
if (!rec) return "";
|
|
24
29
|
const text = rec.text.replace(/\s+/g, " ").trim();
|
|
25
|
-
const image = rec.images > 0 ?
|
|
26
|
-
const references = rec.references > 0 ?
|
|
30
|
+
const image = rec.images > 0 ? t("lastsent.images", { count: rec.images }) : "";
|
|
31
|
+
const references = rec.references > 0 ? t("lastsent.references", { count: rec.references }) : "";
|
|
27
32
|
return [references, image, text].filter(Boolean).join(" ");
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
export function lastSentTooltip(rec) {
|
|
31
36
|
if (!rec) return "";
|
|
32
|
-
const image = rec.images > 0 ?
|
|
33
|
-
const references = rec.references > 0 ?
|
|
37
|
+
const image = rec.images > 0 ? t("lastsent.images", { count: rec.images }) : "";
|
|
38
|
+
const references = rec.references > 0 ? t("lastsent.references", { count: rec.references }) : "";
|
|
34
39
|
return [references, image, rec.text.trim()].filter(Boolean).join("\n");
|
|
35
40
|
}
|
package/web/manual.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type ManualLang = "ko" | "en";
|
|
2
2
|
export declare const MANUAL_PATH: string;
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const MANUAL_MISSING_KEY: string;
|
|
4
4
|
export declare function manualUrl(lang: string): string;
|
|
5
5
|
export declare function otherLang(lang: string): ManualLang;
|
|
6
6
|
export declare function manualLinkLang(href: string | null | undefined): ManualLang | null;
|
package/web/manual.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
// The user manual view of 설정 "매뉴얼": decisions only, with no DOM, so test/unit/manual.test.ts and the mutation run
|
|
2
|
-
// drive them directly; app.js fetches GET /api/manual and renders the Markdown with the chat renderer.
|
|
2
|
+
// drive them directly; app.js fetches GET /api/manual and renders the Markdown with the chat renderer. The texts follow
|
|
3
|
+
// the UI language (web/i18n.js) from web/i18n/manual.js.
|
|
4
|
+
|
|
5
|
+
import { registerStrings, t } from "./i18n.js";
|
|
6
|
+
import manualStrings from "./i18n/manual.js";
|
|
7
|
+
|
|
8
|
+
registerStrings(manualStrings);
|
|
3
9
|
|
|
4
10
|
export const MANUAL_PATH = "/api/manual";
|
|
5
|
-
export const
|
|
11
|
+
export const MANUAL_MISSING_KEY = "manual.missing";
|
|
6
12
|
|
|
7
13
|
export function manualUrl(lang) {
|
|
8
14
|
return `${MANUAL_PATH}?lang=${lang === "en" ? "en" : "ko"}`;
|
|
@@ -23,7 +29,7 @@ export function manualLinkLang(href) {
|
|
|
23
29
|
|
|
24
30
|
/** The line for a failed load: [status] is the HTTP status, or 0 when the request itself failed. */
|
|
25
31
|
export function manualFailureText(status) {
|
|
26
|
-
if (status === 404) return
|
|
27
|
-
if (status === 0) return "
|
|
28
|
-
return
|
|
32
|
+
if (status === 404) return t(MANUAL_MISSING_KEY);
|
|
33
|
+
if (status === 0) return t("manual.loadFailedOffline");
|
|
34
|
+
return t("manual.loadFailedHttp", { status });
|
|
29
35
|
}
|