@imenam/mcp-messenger 1.0.31 → 1.0.33
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/.env.example +12 -22
- package/README.md +825 -764
- package/dist/src/cli/reset-password.d.ts +12 -0
- package/dist/src/cli/reset-password.js +29 -0
- package/dist/src/cli/setup-mcp.d.ts +5 -1
- package/dist/src/cli/setup-mcp.js +15 -37
- package/dist/src/cli/watch-handoff.d.ts +3 -3
- package/dist/src/cli/watch-handoff.js +2 -2
- package/dist/src/cli/watch.d.ts +1 -1
- package/dist/src/cli/watch.js +3 -3
- package/dist/src/client/messenger-client.d.ts +3 -3
- package/dist/src/client/messenger-client.js +5 -6
- package/dist/src/config.d.ts +13 -8
- package/dist/src/config.js +32 -43
- package/dist/src/core/access-store.d.ts +124 -0
- package/dist/src/core/access-store.js +307 -0
- package/dist/src/core/credentials.d.ts +28 -0
- package/dist/src/core/credentials.js +75 -0
- package/dist/src/core/errors.d.ts +5 -0
- package/dist/src/core/errors.js +9 -0
- package/dist/src/core/store.d.ts +10 -5
- package/dist/src/core/store.js +18 -9
- package/dist/src/core/types.d.ts +1 -1
- package/dist/src/index.js +32 -17
- package/dist/src/mcp/start.js +26 -26
- package/dist/src/mcp/tools.js +2 -2
- package/dist/src/server/app.d.ts +10 -1
- package/dist/src/server/app.js +259 -69
- package/dist/src/server/console-session.d.ts +31 -21
- package/dist/src/server/console-session.js +46 -63
- package/dist/src/server/start.d.ts +3 -0
- package/dist/src/server/start.js +10 -13
- package/dist/src/server/ui/app.js +3997 -2464
- package/dist/src/server/ui/index.html +467 -284
- package/dist/src/server/ui/styles.css +1263 -18
- package/package.json +2 -3
|
@@ -1,284 +1,467 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="fr">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<title>MCP Messenger — supervision</title>
|
|
7
|
-
<link rel="stylesheet" href="./styles.css" />
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<header class="topbar">
|
|
11
|
-
<div class="brand">
|
|
12
|
-
<svg class="brand-mark" viewBox="0 0 24 24" aria-hidden="true">
|
|
13
|
-
<path d="M22 12h-6l-2 3h-4l-2-3H2" />
|
|
14
|
-
<path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" />
|
|
15
|
-
</svg>
|
|
16
|
-
<h1>MCP Messenger</h1>
|
|
17
|
-
<span class="pill pill--idle" id="status">
|
|
18
|
-
<span class="pill-dot"></span>
|
|
19
|
-
<span id="status-label">connexion…</span>
|
|
20
|
-
</span>
|
|
21
|
-
</div>
|
|
22
|
-
|
|
23
|
-
<nav class="tabs" id="tabs" hidden>
|
|
24
|
-
<button type="button" class="tab is-active" data-view="threads">
|
|
25
|
-
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
26
|
-
<path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2z" />
|
|
27
|
-
<path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1" />
|
|
28
|
-
</svg>
|
|
29
|
-
Fils
|
|
30
|
-
</button>
|
|
31
|
-
<button type="button" class="tab" data-view="links">
|
|
32
|
-
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
33
|
-
<path d="M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1" />
|
|
34
|
-
<path d="M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1" />
|
|
35
|
-
</svg>
|
|
36
|
-
Liaisons
|
|
37
|
-
<span class="count count--accent" id="links-badge" hidden></span>
|
|
38
|
-
</button>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
</
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
<path d="
|
|
66
|
-
<path d="
|
|
67
|
-
<path d="
|
|
68
|
-
</svg>
|
|
69
|
-
</button>
|
|
70
|
-
<button type="button" id="
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<div class="
|
|
81
|
-
<
|
|
82
|
-
<
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
</
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
</div>
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
<
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
<
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
</
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
<
|
|
249
|
-
<
|
|
250
|
-
|
|
251
|
-
<
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
<span class="
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="fr">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>MCP Messenger — supervision</title>
|
|
7
|
+
<link rel="stylesheet" href="./styles.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<header class="topbar">
|
|
11
|
+
<div class="brand">
|
|
12
|
+
<svg class="brand-mark" viewBox="0 0 24 24" aria-hidden="true">
|
|
13
|
+
<path d="M22 12h-6l-2 3h-4l-2-3H2" />
|
|
14
|
+
<path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" />
|
|
15
|
+
</svg>
|
|
16
|
+
<h1>MCP Messenger</h1>
|
|
17
|
+
<span class="pill pill--idle" id="status">
|
|
18
|
+
<span class="pill-dot"></span>
|
|
19
|
+
<span id="status-label">connexion…</span>
|
|
20
|
+
</span>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<nav class="tabs" id="tabs" hidden>
|
|
24
|
+
<button type="button" class="tab is-active" data-view="threads">
|
|
25
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
26
|
+
<path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2z" />
|
|
27
|
+
<path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1" />
|
|
28
|
+
</svg>
|
|
29
|
+
Fils
|
|
30
|
+
</button>
|
|
31
|
+
<button type="button" class="tab" data-view="links">
|
|
32
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
33
|
+
<path d="M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1" />
|
|
34
|
+
<path d="M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1" />
|
|
35
|
+
</svg>
|
|
36
|
+
Liaisons
|
|
37
|
+
<span class="count count--accent" id="links-badge" hidden></span>
|
|
38
|
+
</button>
|
|
39
|
+
<button type="button" class="tab" data-view="keys">
|
|
40
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
41
|
+
<path d="M2.6 17.4A2 2 0 0 0 2 18.8V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.2a2 2 0 0 0 1.4-.6l.8-.8a6.5 6.5 0 1 0-4-4z" />
|
|
42
|
+
<path d="M16.5 7.5h.01" />
|
|
43
|
+
</svg>
|
|
44
|
+
Clés API
|
|
45
|
+
</button>
|
|
46
|
+
</nav>
|
|
47
|
+
|
|
48
|
+
<div class="topbar-search" id="search-box">
|
|
49
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
50
|
+
<circle cx="11" cy="11" r="8" />
|
|
51
|
+
<path d="m21 21-4.3-4.3" />
|
|
52
|
+
</svg>
|
|
53
|
+
<input type="search" id="search" placeholder="Rechercher un sujet, un fil, un agent…" />
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div class="topbar-controls" id="controls" hidden>
|
|
57
|
+
<label class="switch">
|
|
58
|
+
<input type="checkbox" id="auto-refresh" checked />
|
|
59
|
+
<span class="switch-track"><span class="switch-knob"></span></span>
|
|
60
|
+
<span class="switch-label">auto · 5 s</span>
|
|
61
|
+
</label>
|
|
62
|
+
<button type="button" id="refresh" class="btn btn--icon" title="Rafraîchir" aria-label="Rafraîchir">
|
|
63
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
64
|
+
<path d="M3 12a9 9 0 0 1 15-6.7L21 8" />
|
|
65
|
+
<path d="M21 3v5h-5" />
|
|
66
|
+
<path d="M21 12a9 9 0 0 1-15 6.7L3 16" />
|
|
67
|
+
<path d="M3 21v-5h5" />
|
|
68
|
+
</svg>
|
|
69
|
+
</button>
|
|
70
|
+
<button type="button" id="purge-open" class="btn btn--icon" title="Purger les boîtes inactives" aria-label="Purger les boîtes inactives">
|
|
71
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
72
|
+
<path d="M3 6h18" />
|
|
73
|
+
<path d="M8 6V4a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2" />
|
|
74
|
+
<path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
|
|
75
|
+
</svg>
|
|
76
|
+
</button>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<!-- Menu du compte : la page « Mon compte », les clés, la déconnexion. -->
|
|
80
|
+
<div class="account" id="account" hidden>
|
|
81
|
+
<button type="button" class="account-button" id="account-button" aria-haspopup="menu" aria-expanded="false">
|
|
82
|
+
<span class="account-avatar" id="account-initial"></span>
|
|
83
|
+
<span class="account-name" id="account-name"></span>
|
|
84
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m6 9 6 6 6-6" /></svg>
|
|
85
|
+
</button>
|
|
86
|
+
<div class="account-menu" id="account-menu" role="menu" hidden>
|
|
87
|
+
<button type="button" class="account-item" role="menuitem" data-view="account">
|
|
88
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
89
|
+
<path d="M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z" />
|
|
90
|
+
<path d="M12 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" />
|
|
91
|
+
<path d="M7 20.7v-.7a3 3 0 0 1 3-3h4a3 3 0 0 1 3 3v.7" />
|
|
92
|
+
</svg>
|
|
93
|
+
Mon compte
|
|
94
|
+
</button>
|
|
95
|
+
<button type="button" class="account-item" role="menuitem" data-view="keys">
|
|
96
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
97
|
+
<path d="M2.6 17.4A2 2 0 0 0 2 18.8V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.2a2 2 0 0 0 1.4-.6l.8-.8a6.5 6.5 0 1 0-4-4z" />
|
|
98
|
+
<path d="M16.5 7.5h.01" />
|
|
99
|
+
</svg>
|
|
100
|
+
Clés API
|
|
101
|
+
</button>
|
|
102
|
+
<div class="account-sep"></div>
|
|
103
|
+
<button type="button" class="account-item" role="menuitem" id="logout">
|
|
104
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
105
|
+
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
|
|
106
|
+
<path d="m16 17 5-5-5-5" />
|
|
107
|
+
<path d="M21 12H9" />
|
|
108
|
+
</svg>
|
|
109
|
+
Se déconnecter
|
|
110
|
+
</button>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</header>
|
|
114
|
+
|
|
115
|
+
<!--
|
|
116
|
+
Purge des boîtes inactives : la seule action de la console qui écrit, et elle
|
|
117
|
+
détruit. Elle se fait donc en deux temps, l'aperçu puis la confirmation, et ne porte
|
|
118
|
+
jamais que sur les boîtes affichées.
|
|
119
|
+
-->
|
|
120
|
+
<dialog class="modal" id="purge">
|
|
121
|
+
<div class="modal-card">
|
|
122
|
+
<div class="modal-head">
|
|
123
|
+
<h2>Nettoyer les boîtes</h2>
|
|
124
|
+
<button type="button" class="btn btn--icon btn--ghost" id="purge-close" aria-label="Fermer">
|
|
125
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
126
|
+
<path d="M18 6 6 18" />
|
|
127
|
+
<path d="m6 6 12 12" />
|
|
128
|
+
</svg>
|
|
129
|
+
</button>
|
|
130
|
+
</div>
|
|
131
|
+
<p class="modal-sub">
|
|
132
|
+
Trois nettoyages, trois critères. La suppression est définitive dans tous les cas, et emporte les messages que
|
|
133
|
+
plus personne ne pourrait lire ; ce que le correspondant a reçu de son côté reste intact. Un agent dont toutes
|
|
134
|
+
les boîtes disparaissent quitte l'annuaire avec elles.
|
|
135
|
+
</p>
|
|
136
|
+
|
|
137
|
+
<!-- Premier critère : la boîte n'a jamais servi. Il ne dépend d'aucune date. -->
|
|
138
|
+
<div class="purge-controls">
|
|
139
|
+
<div class="purge-criterion">
|
|
140
|
+
<span class="field-label">Boîtes vides</span>
|
|
141
|
+
<span class="purge-hint">Rien n'y est jamais passé, ni envoi ni réception, quel que soit leur âge.</span>
|
|
142
|
+
</div>
|
|
143
|
+
<button type="button" class="btn" id="purge-preview-empty">Prévisualiser</button>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
<!-- Second critère : la boîte a servi, mais plus rien ne l'a touchée depuis. -->
|
|
147
|
+
<div class="purge-controls">
|
|
148
|
+
<label class="field">
|
|
149
|
+
<span class="field-label">Boîtes sans activité depuis le</span>
|
|
150
|
+
<span class="field-input"><input type="date" id="purge-before" /></span>
|
|
151
|
+
<span class="purge-hint">Ni connexion, ni message. Une boîte créée après cette date est épargnée.</span>
|
|
152
|
+
</label>
|
|
153
|
+
<button type="button" class="btn" id="purge-preview">Prévisualiser</button>
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<!-- Troisième critère : l'âge de la boîte, que son activité ne rachète pas. -->
|
|
157
|
+
<div class="purge-controls">
|
|
158
|
+
<label class="field">
|
|
159
|
+
<span class="field-label">Boîtes créées avant le</span>
|
|
160
|
+
<span class="field-input"><input type="date" id="purge-created-before" /></span>
|
|
161
|
+
<span class="purge-hint">Sur la seule date d'ouverture : une boîte encore active en fait partie.</span>
|
|
162
|
+
</label>
|
|
163
|
+
<button type="button" class="btn" id="purge-preview-created">Prévisualiser</button>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div class="purge-result" id="purge-result"></div>
|
|
167
|
+
|
|
168
|
+
<div class="modal-foot">
|
|
169
|
+
<button type="button" class="btn btn--link" id="purge-cancel">Fermer</button>
|
|
170
|
+
<button type="button" class="btn btn--danger" id="purge-confirm" disabled>Supprimer</button>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
</dialog>
|
|
174
|
+
|
|
175
|
+
<!--
|
|
176
|
+
Détails d'un message : tout ce que la conversation ne montre pas — adresses, noms de
|
|
177
|
+
boîtes, identifiants, distribution. Une modale, parce que c'est une consultation
|
|
178
|
+
ponctuelle : elle s'ouvre sur demande et rend la place en se fermant.
|
|
179
|
+
-->
|
|
180
|
+
<dialog class="modal" id="details">
|
|
181
|
+
<div class="modal-card" id="details-body"></div>
|
|
182
|
+
</dialog>
|
|
183
|
+
|
|
184
|
+
<!-- Écran de connexion : une carte seule, sans les panneaux vides derrière elle. -->
|
|
185
|
+
<main class="login" id="login" hidden>
|
|
186
|
+
<form class="card" id="login-form">
|
|
187
|
+
<div class="card-badge">
|
|
188
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
189
|
+
<rect x="3" y="11" width="18" height="11" rx="2" />
|
|
190
|
+
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
191
|
+
</svg>
|
|
192
|
+
</div>
|
|
193
|
+
<h2>Console de supervision</h2>
|
|
194
|
+
<p class="card-sub" id="login-origin">MCP Messenger</p>
|
|
195
|
+
|
|
196
|
+
<label class="field field--tight">
|
|
197
|
+
<span class="field-label">Nom d'utilisateur</span>
|
|
198
|
+
<span class="field-input">
|
|
199
|
+
<input type="text" id="login-username" autocomplete="username" autocapitalize="none" spellcheck="false" required />
|
|
200
|
+
</span>
|
|
201
|
+
</label>
|
|
202
|
+
|
|
203
|
+
<label class="field field--tight">
|
|
204
|
+
<span class="field-label">Mot de passe</span>
|
|
205
|
+
<span class="field-input">
|
|
206
|
+
<input type="password" id="login-password" autocomplete="current-password" required />
|
|
207
|
+
<button type="button" class="field-eye" data-reveal="login-password" aria-label="Afficher le mot de passe">
|
|
208
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
209
|
+
<path d="M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z" />
|
|
210
|
+
<circle cx="12" cy="12" r="3" />
|
|
211
|
+
</svg>
|
|
212
|
+
</button>
|
|
213
|
+
</span>
|
|
214
|
+
</label>
|
|
215
|
+
|
|
216
|
+
<label class="check">
|
|
217
|
+
<input type="checkbox" id="login-remember" />
|
|
218
|
+
<span>Rester connecté sur cet appareil (30 jours)</span>
|
|
219
|
+
</label>
|
|
220
|
+
|
|
221
|
+
<p class="form-banner" id="login-error" hidden></p>
|
|
222
|
+
|
|
223
|
+
<button type="submit" class="btn btn--primary btn--block">Se connecter</button>
|
|
224
|
+
<p class="card-note card-note--rule">
|
|
225
|
+
Mot de passe perdu ? Sur le serveur :<br />
|
|
226
|
+
<code>npx @imenam/mcp-messenger --reset-password</code>
|
|
227
|
+
</p>
|
|
228
|
+
</form>
|
|
229
|
+
</main>
|
|
230
|
+
|
|
231
|
+
<!--
|
|
232
|
+
Premier lancement : aucun compte n'existe encore. Le code d'installation, écrit dans le
|
|
233
|
+
journal du serveur, prouve qu'on a accès à la machine.
|
|
234
|
+
-->
|
|
235
|
+
<main class="login" id="setup" hidden>
|
|
236
|
+
<form class="card" id="setup-form">
|
|
237
|
+
<div class="card-badge">
|
|
238
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
239
|
+
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" />
|
|
240
|
+
<path d="M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z" />
|
|
241
|
+
<path d="M19 8v6" />
|
|
242
|
+
<path d="M22 11h-6" />
|
|
243
|
+
</svg>
|
|
244
|
+
</div>
|
|
245
|
+
<h2>Créer le compte administrateur</h2>
|
|
246
|
+
<p class="card-sub">Ce compte ouvre la console et gère les clés API des agents.</p>
|
|
247
|
+
|
|
248
|
+
<label class="field field--tight">
|
|
249
|
+
<span class="field-label">Code d'installation</span>
|
|
250
|
+
<span class="field-input">
|
|
251
|
+
<input type="text" id="setup-code" class="mono" autocomplete="off" autocapitalize="characters" spellcheck="false" required />
|
|
252
|
+
</span>
|
|
253
|
+
<span class="field-hint">Affiché dans le journal du serveur au démarrage. Valable une fois.</span>
|
|
254
|
+
</label>
|
|
255
|
+
|
|
256
|
+
<div class="card-rule"></div>
|
|
257
|
+
|
|
258
|
+
<label class="field field--tight">
|
|
259
|
+
<span class="field-label">Nom d'utilisateur</span>
|
|
260
|
+
<span class="field-input">
|
|
261
|
+
<input type="text" id="setup-username" autocomplete="username" autocapitalize="none" spellcheck="false" required />
|
|
262
|
+
</span>
|
|
263
|
+
</label>
|
|
264
|
+
|
|
265
|
+
<label class="field field--tight">
|
|
266
|
+
<span class="field-label">Mot de passe</span>
|
|
267
|
+
<span class="field-input">
|
|
268
|
+
<input type="password" id="setup-password" autocomplete="new-password" required />
|
|
269
|
+
<button type="button" class="field-eye" data-reveal="setup-password" aria-label="Afficher le mot de passe">
|
|
270
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
271
|
+
<path d="M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z" />
|
|
272
|
+
<circle cx="12" cy="12" r="3" />
|
|
273
|
+
</svg>
|
|
274
|
+
</button>
|
|
275
|
+
</span>
|
|
276
|
+
<span class="meter" id="setup-meter" data-level="0">
|
|
277
|
+
<span></span><span></span><span></span><span></span>
|
|
278
|
+
</span>
|
|
279
|
+
<span class="field-hint" id="setup-meter-label">12 caractères minimum.</span>
|
|
280
|
+
</label>
|
|
281
|
+
|
|
282
|
+
<label class="field field--tight">
|
|
283
|
+
<span class="field-label">Confirmer le mot de passe</span>
|
|
284
|
+
<span class="field-input">
|
|
285
|
+
<input type="password" id="setup-confirm" autocomplete="new-password" required />
|
|
286
|
+
</span>
|
|
287
|
+
</label>
|
|
288
|
+
|
|
289
|
+
<p class="form-banner" id="setup-error" hidden></p>
|
|
290
|
+
|
|
291
|
+
<button type="submit" class="btn btn--primary btn--block" id="setup-submit" disabled>
|
|
292
|
+
Créer le compte et se connecter
|
|
293
|
+
</button>
|
|
294
|
+
<p class="card-note">Le mot de passe est stocké haché (scrypt), jamais en clair.</p>
|
|
295
|
+
</form>
|
|
296
|
+
</main>
|
|
297
|
+
|
|
298
|
+
<!-- Clés API : une par poste ou par agent, montrée en clair une seule fois. -->
|
|
299
|
+
<main class="page" id="keys" hidden>
|
|
300
|
+
<div class="page-head">
|
|
301
|
+
<div>
|
|
302
|
+
<h2>Clés API</h2>
|
|
303
|
+
<p class="muted">
|
|
304
|
+
Une clé par poste ou par agent. Elle ne s'affiche qu'une fois, à sa création ; une clé révoquée est
|
|
305
|
+
refusée dès l'appel suivant.
|
|
306
|
+
</p>
|
|
307
|
+
</div>
|
|
308
|
+
<button type="button" class="btn btn--primary" id="key-new">
|
|
309
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14" /><path d="M12 5v14" /></svg>
|
|
310
|
+
Nouvelle clé
|
|
311
|
+
</button>
|
|
312
|
+
</div>
|
|
313
|
+
<div class="page-tools">
|
|
314
|
+
<div class="chips" id="key-filters">
|
|
315
|
+
<button type="button" class="chip is-active" data-status="active">Actives <span class="chip-count"></span></button>
|
|
316
|
+
<button type="button" class="chip" data-status="expired">Expirées <span class="chip-count"></span></button>
|
|
317
|
+
<button type="button" class="chip" data-status="revoked">Révoquées <span class="chip-count"></span></button>
|
|
318
|
+
</div>
|
|
319
|
+
<label class="page-search">
|
|
320
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
321
|
+
<circle cx="11" cy="11" r="8" />
|
|
322
|
+
<path d="m21 21-4.3-4.3" />
|
|
323
|
+
</svg>
|
|
324
|
+
<input type="search" id="key-search" placeholder="Nom, agent ou début de clé…" />
|
|
325
|
+
</label>
|
|
326
|
+
</div>
|
|
327
|
+
<div class="key-table" id="key-table"></div>
|
|
328
|
+
<p class="page-note">
|
|
329
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
330
|
+
<path d="M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18z" />
|
|
331
|
+
<path d="M12 11v5" />
|
|
332
|
+
<path d="M12 8h.01" />
|
|
333
|
+
</svg>
|
|
334
|
+
Côté agent, la clé se pose dans MESSENGER_API_KEY. Révoquer une clé coupe l'accès de l'agent ; ses boîtes et ses
|
|
335
|
+
messages restent en place.
|
|
336
|
+
</p>
|
|
337
|
+
</main>
|
|
338
|
+
|
|
339
|
+
<!-- Mon compte : identifiant, mot de passe, navigateurs connectés. -->
|
|
340
|
+
<main class="page page--narrow" id="account-page" hidden>
|
|
341
|
+
<div class="page-head">
|
|
342
|
+
<div>
|
|
343
|
+
<h2>Mon compte</h2>
|
|
344
|
+
<p class="muted">Identifiant de la console, mot de passe et appareils connectés.</p>
|
|
345
|
+
</div>
|
|
346
|
+
</div>
|
|
347
|
+
<div id="account-body"></div>
|
|
348
|
+
</main>
|
|
349
|
+
|
|
350
|
+
<!-- Volet des clés : création, clé affichée une fois, détail d'une clé. -->
|
|
351
|
+
<dialog class="drawer" id="key-drawer">
|
|
352
|
+
<div class="drawer-body" id="key-drawer-body"></div>
|
|
353
|
+
</dialog>
|
|
354
|
+
|
|
355
|
+
<!-- Confirmation de révocation : la seule action définitive sur une clé. -->
|
|
356
|
+
<dialog class="modal modal--confirm" id="key-revoke">
|
|
357
|
+
<div class="modal-card" id="key-revoke-body"></div>
|
|
358
|
+
</dialog>
|
|
359
|
+
|
|
360
|
+
<!-- Console : agents, fils, lecteur du fil. -->
|
|
361
|
+
<main class="console" id="console" hidden>
|
|
362
|
+
<aside class="agents" id="agents-pane">
|
|
363
|
+
<div class="agents-head">
|
|
364
|
+
<span class="section-label">Agents</span>
|
|
365
|
+
<button type="button" class="btn btn--icon btn--ghost" id="collapse" title="Replier" aria-label="Replier la liste des agents" aria-expanded="true">
|
|
366
|
+
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
367
|
+
<rect x="3" y="3" width="18" height="18" rx="2" />
|
|
368
|
+
<path d="M9 3v18" />
|
|
369
|
+
</svg>
|
|
370
|
+
</button>
|
|
371
|
+
</div>
|
|
372
|
+
<ul class="agent-list" id="agents"></ul>
|
|
373
|
+
<p class="agents-foot muted" id="agents-foot"></p>
|
|
374
|
+
</aside>
|
|
375
|
+
|
|
376
|
+
<!--
|
|
377
|
+
Séparateurs déplaçables. Chacun redimensionne le panneau qu'il borde, à la souris
|
|
378
|
+
comme aux flèches du clavier ; un double-clic rend sa largeur d'origine.
|
|
379
|
+
-->
|
|
380
|
+
<div
|
|
381
|
+
class="resizer"
|
|
382
|
+
id="resize-agents"
|
|
383
|
+
role="separator"
|
|
384
|
+
aria-orientation="vertical"
|
|
385
|
+
aria-label="Largeur de la colonne des agents"
|
|
386
|
+
tabindex="0"
|
|
387
|
+
></div>
|
|
388
|
+
|
|
389
|
+
<section class="threads">
|
|
390
|
+
<div class="threads-head">
|
|
391
|
+
<!--
|
|
392
|
+
L'en-tête dit sur quoi la liste est filtrée. Quand c'est un agent, il y tient la
|
|
393
|
+
place principale, pastille comprise : c'est le sujet de ce qu'on lit en dessous.
|
|
394
|
+
-->
|
|
395
|
+
<div class="threads-title">
|
|
396
|
+
<span class="threads-avatar" id="threads-avatar" hidden></span>
|
|
397
|
+
<div class="threads-heading">
|
|
398
|
+
<h2 id="threads-name">Fils</h2>
|
|
399
|
+
<p class="muted" id="threads-scope"></p>
|
|
400
|
+
</div>
|
|
401
|
+
</div>
|
|
402
|
+
<div class="chips" id="chips">
|
|
403
|
+
<button type="button" class="chip is-active" data-filter="all">Tous</button>
|
|
404
|
+
<button type="button" class="chip" data-filter="unread">Non lus</button>
|
|
405
|
+
<button type="button" class="chip" data-filter="high">Priorité haute</button>
|
|
406
|
+
</div>
|
|
407
|
+
</div>
|
|
408
|
+
<ul class="thread-list" id="threads"></ul>
|
|
409
|
+
</section>
|
|
410
|
+
|
|
411
|
+
<div
|
|
412
|
+
class="resizer"
|
|
413
|
+
id="resize-threads"
|
|
414
|
+
role="separator"
|
|
415
|
+
aria-orientation="vertical"
|
|
416
|
+
aria-label="Largeur de la liste des fils"
|
|
417
|
+
tabindex="0"
|
|
418
|
+
></div>
|
|
419
|
+
|
|
420
|
+
<section class="reader" id="reader"></section>
|
|
421
|
+
|
|
422
|
+
</main>
|
|
423
|
+
|
|
424
|
+
<!--
|
|
425
|
+
Liaisons : une colonne par agent, la plus récente à gauche ; en hauteur, l'heure de
|
|
426
|
+
création des boîtes, la plus récente en haut. La fenêtre détaillée est réglable ; au-delà,
|
|
427
|
+
les boîtes sont empilées en liste sous leur agent.
|
|
428
|
+
-->
|
|
429
|
+
<main class="links" id="links" hidden>
|
|
430
|
+
<section class="links-map">
|
|
431
|
+
<div class="links-toolbar">
|
|
432
|
+
<div>
|
|
433
|
+
<h2>Liaisons entre boîtes</h2>
|
|
434
|
+
<p class="muted">
|
|
435
|
+
Glissez la poignée d'une boîte vers une autre, ou choisissez-la dans le volet. Chaque agent reçoit la
|
|
436
|
+
liaison à sa prochaine connexion.
|
|
437
|
+
</p>
|
|
438
|
+
</div>
|
|
439
|
+
<label class="links-window">
|
|
440
|
+
<span>Détail sur</span>
|
|
441
|
+
<select id="links-window">
|
|
442
|
+
<option value="5">5 min</option>
|
|
443
|
+
<option value="10">10 min</option>
|
|
444
|
+
<option value="15">15 min</option>
|
|
445
|
+
<option value="30" selected>30 min</option>
|
|
446
|
+
<option value="60">1 h</option>
|
|
447
|
+
<option value="120">2 h</option>
|
|
448
|
+
<option value="240">4 h</option>
|
|
449
|
+
</select>
|
|
450
|
+
</label>
|
|
451
|
+
</div>
|
|
452
|
+
<div class="links-scroll" id="links-scroll">
|
|
453
|
+
<div class="links-canvas" id="links-canvas"></div>
|
|
454
|
+
</div>
|
|
455
|
+
<div class="links-legend">
|
|
456
|
+
<span class="links-legend-item"><span class="links-rank">1</span>rang de création, #1 = la plus récente</span>
|
|
457
|
+
<span class="links-legend-item"><span class="links-legend-line is-new"></span>liaison de la boîte choisie</span>
|
|
458
|
+
<span class="links-legend-item"><span class="links-legend-line"></span>liaison existante</span>
|
|
459
|
+
<span class="links-legend-item muted">Hauteur = heure exacte, à échelle régulière</span>
|
|
460
|
+
</div>
|
|
461
|
+
</section>
|
|
462
|
+
<aside class="links-panel" id="links-panel"></aside>
|
|
463
|
+
</main>
|
|
464
|
+
|
|
465
|
+
<script type="module" src="./app.js"></script>
|
|
466
|
+
</body>
|
|
467
|
+
</html>
|