@atlashub/smartstack-cli 4.1.0 → 4.3.0

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.
@@ -0,0 +1,528 @@
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.0">
6
+ <title>Licence - SmartStack CLI</title>
7
+ <link rel="stylesheet" href="css/styles.css">
8
+ </head>
9
+ <body>
10
+ <div class="app-container">
11
+ <!-- Global Header -->
12
+ <header class="global-header">
13
+ <div class="logo">SS</div>
14
+ <span class="site-title">SmartStack CLI</span>
15
+ <span class="version-badge">v4.1.0</span>
16
+ <div class="header-divider"></div>
17
+ <span class="page-title">
18
+ <span data-lang="fr">Licence</span>
19
+ <span data-lang="en">License</span>
20
+ </span>
21
+ <nav class="breadcrumb">
22
+ <a href="index.html">
23
+ <span data-lang="fr">Accueil</span>
24
+ <span data-lang="en">Home</span>
25
+ </a>
26
+ <span class="breadcrumb-separator">&#8250;</span>
27
+ <span class="breadcrumb-current">
28
+ <span data-lang="fr">Licence</span>
29
+ <span data-lang="en">License</span>
30
+ </span>
31
+ </nav>
32
+ <!-- Language Select -->
33
+ <select class="lang-select" id="lang-select" onchange="setLanguage(this.value); localStorage.setItem('doc-language', this.value);">
34
+ <option value="fr">&#127467;&#127479; FR</option>
35
+ <option value="en">&#127468;&#127463; EN</option>
36
+ </select>
37
+ <!-- Search -->
38
+ <div class="header-search">
39
+ <div class="search-input-wrapper">
40
+ <span class="search-icon">&#128269;</span>
41
+ <input type="text" id="search-input" class="search-input" placeholder="Rechercher..." data-placeholder-fr="Rechercher..." data-placeholder-en="Search..." autocomplete="off">
42
+ <span class="search-shortcut">Ctrl+K</span>
43
+ </div>
44
+ <div id="search-results" class="search-results"></div>
45
+ </div>
46
+ </header>
47
+
48
+ <!-- App Body -->
49
+ <div class="app-body">
50
+ <!-- Sidebar -->
51
+ <aside class="sidebar">
52
+ <button class="sidebar-toggle" title="Toggle sidebar">
53
+ <span class="toggle-icon-collapse">&#171;</span>
54
+ <span class="toggle-icon-expand">&#187;</span>
55
+ </button>
56
+
57
+ <nav class="sidebar-nav">
58
+ <div class="nav-section">
59
+ <div class="nav-section-title">
60
+ <span data-lang="fr">Demarrage</span>
61
+ <span data-lang="en">Getting Started</span>
62
+ </div>
63
+ <a href="index.html" class="nav-item">
64
+ <span class="icon">&#127968;</span>
65
+ <span class="nav-text" data-lang="fr">Accueil</span>
66
+ <span class="nav-text" data-lang="en">Home</span>
67
+ </a>
68
+ <a href="installation.html" class="nav-item">
69
+ <span class="icon">&#128230;</span>
70
+ <span class="nav-text">Installation</span>
71
+ </a>
72
+ <a href="license.html" class="nav-item active">
73
+ <span class="icon">&#128274;</span>
74
+ <span class="nav-text" data-lang="fr">Licence</span>
75
+ <span class="nav-text" data-lang="en">License</span>
76
+ </a>
77
+ <a href="init.html" class="nav-item">
78
+ <span class="icon">&#128640;</span>
79
+ <span class="nav-text" data-lang="fr">Projet Client</span>
80
+ <span class="nav-text" data-lang="en">Client Project</span>
81
+ </a>
82
+ </div>
83
+
84
+ <div class="nav-section">
85
+ <div class="nav-section-title">Workflows</div>
86
+ <a href="gitflow.html" class="nav-item">
87
+ <span class="icon">&#128256;</span>
88
+ <span class="nav-text">GitFlow</span>
89
+ </a>
90
+ <a href="efcore.html" class="nav-item">
91
+ <span class="icon">&#128452;</span>
92
+ <span class="nav-text">EF Core</span>
93
+ </a>
94
+ <a href="business-analyse.html" class="nav-item">
95
+ <span class="icon">&#128202;</span>
96
+ <span class="nav-text">Business Analyse</span>
97
+ </a>
98
+ <a href="ralph-loop.html" class="nav-item">
99
+ <span class="icon">&#128260;</span>
100
+ <span class="nav-text">Ralph Loop</span>
101
+ </a>
102
+ <a href="apex.html" class="nav-item">
103
+ <span class="icon">&#9881;</span>
104
+ <span class="nav-text">APEX</span>
105
+ </a>
106
+ </div>
107
+
108
+ <div class="nav-section">
109
+ <div class="nav-section-title">
110
+ <span data-lang="fr">Outils</span>
111
+ <span data-lang="en">Tools</span>
112
+ </div>
113
+ <a href="cli-commands.html" class="nav-item">
114
+ <span class="icon">&#128187;</span>
115
+ <span class="nav-text" data-lang="fr">CLI SmartStack</span>
116
+ <span class="nav-text" data-lang="en">SmartStack CLI</span>
117
+ </a>
118
+ <a href="agents.html" class="nav-item">
119
+ <span class="icon">&#129302;</span>
120
+ <span class="nav-text">Agents</span>
121
+ </a>
122
+ <a href="commands.html" class="nav-item">
123
+ <span class="icon">&#9889;</span>
124
+ <span class="nav-text" data-lang="fr">Commandes Claude</span>
125
+ <span class="nav-text" data-lang="en">Claude Commands</span>
126
+ </a>
127
+ <a href="hooks.html" class="nav-item">
128
+ <span class="icon">&#128279;</span>
129
+ <span class="nav-text">Hooks</span>
130
+ </a>
131
+ <a href="test-web.html" class="nav-item">
132
+ <span class="icon">&#127760;</span>
133
+ <span class="nav-text">Test Web</span>
134
+ </a>
135
+ </div>
136
+ </nav>
137
+
138
+ </aside>
139
+
140
+ <!-- Main Content -->
141
+ <main class="main-content">
142
+ <div class="content-full">
143
+
144
+ <!-- ============================================
145
+ 1. OVERVIEW / VUE D'ENSEMBLE
146
+ ============================================ -->
147
+ <section id="overview">
148
+ <h2>
149
+ <span data-lang="fr">Vue d'ensemble</span>
150
+ <span data-lang="en">Overview</span>
151
+ </h2>
152
+
153
+ <p data-lang="fr">
154
+ SmartStack CLI necessite une licence valide pour fonctionner. Vous avez deux options : demarrer avec un <strong>essai gratuit de 14 jours</strong> sans engagement, ou activer une <strong>licence achetee</strong> obtenue via votre compte administrateur ou votre organisation.
155
+ </p>
156
+ <p data-lang="en">
157
+ SmartStack CLI requires a valid license to operate. You have two options: start with a <strong>free 14-day trial</strong> with no commitment, or activate a <strong>purchased license</strong> obtained from your admin account or organization.
158
+ </p>
159
+
160
+ <div class="alert alert-info">
161
+ <span class="alert-icon">&#128161;</span>
162
+ <div class="alert-content">
163
+ <h5 data-lang="fr">Comment fonctionnent les licences</h5>
164
+ <h5 data-lang="en">How licenses work</h5>
165
+ <p data-lang="fr">
166
+ Les licences sont basees sur <strong>JWT (JSON Web Tokens)</strong> signes cryptographiquement. Le CLI verifie localement la signature et l'expiration. Tous les 7 jours, le CLI effectue un heartbeat securise avec le serveur de licences pour verifier la validite et recevoir les mises a jour.
167
+ </p>
168
+ <p data-lang="en">
169
+ Licenses are based on <strong>JWT (JSON Web Tokens)</strong> cryptographically signed. The CLI verifies the signature and expiration locally. Every 7 days, the CLI performs a secure heartbeat with the license server to verify validity and receive updates.
170
+ </p>
171
+ </div>
172
+ </div>
173
+ </section>
174
+
175
+ <!-- ============================================
176
+ 2. FREE TRIAL / ESSAI GRATUIT
177
+ ============================================ -->
178
+ <section id="free-trial">
179
+ <h2>
180
+ <span data-lang="fr">Essai gratuit</span>
181
+ <span data-lang="en">Free Trial</span>
182
+ </h2>
183
+
184
+ <p data-lang="fr">
185
+ Lancez un essai gratuit de <strong>14 jours</strong> sans avoir besoin d'une licence achetee. L'essai est enregistre avec votre nom, email et informations d'organisation.
186
+ </p>
187
+ <p data-lang="en">
188
+ Start a <strong>14-day free trial</strong> without needing a purchased license. The trial is registered with your name, email and organization information.
189
+ </p>
190
+
191
+ <div class="tutorial-section">
192
+ <h3 data-lang="fr">Commande</h3>
193
+ <h3 data-lang="en">Command</h3>
194
+
195
+ <pre><code class="code-block">smartstack license trial</code></pre>
196
+
197
+ <h3 data-lang="fr">Processus</h3>
198
+ <h3 data-lang="en">Process</h3>
199
+
200
+ <ol>
201
+ <li data-lang="fr">Le CLI vous demande votre nom, email, entreprise et taille d'equipe</li>
202
+ <li data-lang="en">The CLI asks for your name, email, company and team size</li>
203
+ <li data-lang="fr">Les informations sont envoyees au serveur de licences</li>
204
+ <li data-lang="en">Information is sent to the license server</li>
205
+ <li data-lang="fr">Une licence d'essai JWT valide pour 14 jours est generee et activee localement</li>
206
+ <li data-lang="en">A trial JWT license valid for 14 days is generated and activated locally</li>
207
+ <li data-lang="fr">Le CLI confirme : essai actif jusqu'au [date d'expiration]</li>
208
+ <li data-lang="en">The CLI confirms: trial active until [expiration date]</li>
209
+ </ol>
210
+
211
+ <div class="tutorial-note">
212
+ <span class="note-icon">&#128161;</span>
213
+ <div>
214
+ <p data-lang="fr">
215
+ Apres 14 jours, vous devrez soit acheter une licence, soit relancer un nouvel essai (une seule fois par email).
216
+ </p>
217
+ <p data-lang="en">
218
+ After 14 days, you'll need to either purchase a license or start a new trial (once per email).
219
+ </p>
220
+ </div>
221
+ </div>
222
+ </div>
223
+ </section>
224
+
225
+ <!-- ============================================
226
+ 3. ACTIVATE LICENSE / ACTIVER UNE LICENCE
227
+ ============================================ -->
228
+ <section id="activate-license">
229
+ <h2>
230
+ <span data-lang="fr">Activer une licence</span>
231
+ <span data-lang="en">Activate a License</span>
232
+ </h2>
233
+
234
+ <p data-lang="fr">
235
+ Quand vous achetez ou recevez une licence, vous obtenez un <strong>JWT token</strong> unique. Ce token est votre clé d'activation. Vous ne devez jamais le partager.
236
+ </p>
237
+ <p data-lang="en">
238
+ When you purchase or receive a license, you get a unique <strong>JWT token</strong>. This token is your activation key. Never share it.
239
+ </p>
240
+
241
+ <div class="tutorial-section">
242
+ <h3 data-lang="fr">Commande</h3>
243
+ <h3 data-lang="en">Command</h3>
244
+
245
+ <pre><code class="code-block">smartstack license activate &lt;jwt-token&gt;</code></pre>
246
+
247
+ <h4 data-lang="fr">Exemple</h4>
248
+ <h4 data-lang="en">Example</h4>
249
+
250
+ <pre><code class="code-block">smartstack license activate eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9...</code></pre>
251
+
252
+ <h3 data-lang="fr">Flux d'activation</h3>
253
+ <h3 data-lang="en">Activation Flow</h3>
254
+
255
+ <ol>
256
+ <li data-lang="fr"><strong>Dev reçoit le token</strong> : Par email, depuis le portail d'achat ou par l'admin</li>
257
+ <li data-lang="en"><strong>Dev receives the token</strong>: By email, from the purchase portal or from the admin</li>
258
+ <li data-lang="fr"><strong>Lance l'activation</strong> : <code>smartstack license activate &lt;token&gt;</code></li>
259
+ <li data-lang="en"><strong>Launch activation</strong>: <code>smartstack license activate &lt;token&gt;</code></li>
260
+ <li data-lang="fr"><strong>CLI verifie le token</strong> : Signature RS512, date d'expiration, validite</li>
261
+ <li data-lang="en"><strong>CLI verifies token</strong>: RS512 signature, expiration date, validity</li>
262
+ <li data-lang="fr"><strong>CLI stocke le JWT</strong> : En cache local (~/.smartstack/license.jwt)</li>
263
+ <li data-lang="en"><strong>CLI stores JWT</strong>: In local cache (~/.smartstack/license.jwt)</li>
264
+ <li data-lang="fr"><strong>Premier heartbeat</strong> : POST /machine/activate avec fingerprint + instanceId</li>
265
+ <li data-lang="en"><strong>First heartbeat</strong>: POST /machine/activate with fingerprint + instanceId</li>
266
+ <li data-lang="fr"><strong>Confirmation</strong> : Licence activee pour [edition], expire le [date]</li>
267
+ <li data-lang="en"><strong>Confirmation</strong>: License activated for [edition], expires on [date]</li>
268
+ </ol>
269
+
270
+ <div class="tutorial-note">
271
+ <span class="note-icon">&#128161;</span>
272
+ <div>
273
+ <p data-lang="fr">
274
+ La licence est liee a votre machine via un <strong>fingerprint</strong> (empreinte hardware). Une licence ne peut etre active que sur une seule machine a la fois.
275
+ </p>
276
+ <p data-lang="en">
277
+ The license is tied to your machine via a <strong>fingerprint</strong> (hardware signature). A license can only be active on one machine at a time.
278
+ </p>
279
+ </div>
280
+ </div>
281
+ </div>
282
+ </section>
283
+
284
+ <!-- ============================================
285
+ 4. CHECK STATUS / VERIFIER LE STATUT
286
+ ============================================ -->
287
+ <section id="check-status">
288
+ <h2>
289
+ <span data-lang="fr">Verifier le statut</span>
290
+ <span data-lang="en">Check Status</span>
291
+ </h2>
292
+
293
+ <p data-lang="fr">
294
+ Verifiez a tout moment l'etat de votre licence : edition, date d'expiration, environnement (en ligne ou offline).
295
+ </p>
296
+ <p data-lang="en">
297
+ Check your license status at any time: edition, expiration date, environment (online or offline).
298
+ </p>
299
+
300
+ <div class="tutorial-section">
301
+ <h3 data-lang="fr">Commande</h3>
302
+ <h3 data-lang="en">Command</h3>
303
+
304
+ <pre><code class="code-block">smartstack license status</code></pre>
305
+
306
+ <h3 data-lang="fr">Exemple de sortie</h3>
307
+ <h3 data-lang="en">Example output</h3>
308
+
309
+ <pre><code class="code-block">License Status
310
+ ==============
311
+ Edition: Professional
312
+ Status: Active
313
+ Expires: 2026-12-15
314
+ Fingerprint: abc123def456...
315
+ Source: Online (last heartbeat 2 hours ago)
316
+
317
+ Valid until: 287 days</code></pre>
318
+
319
+ <h3 data-lang="fr">Sources possibles</h3>
320
+ <h3 data-lang="en">Possible sources</h3>
321
+
322
+ <ul>
323
+ <li data-lang="fr"><strong>Online</strong> : Licence verifiee aupres du serveur. Informations a jour.</li>
324
+ <li data-lang="en"><strong>Online</strong>: License verified with the server. Information up to date.</li>
325
+ <li data-lang="fr"><strong>Cache</strong> : Derniere verification < 7 jours. Utilisation offline possible.</li>
326
+ <li data-lang="en"><strong>Cache</strong>: Last verification < 7 days. Offline usage possible.</li>
327
+ <li data-lang="fr"><strong>Offline</strong> : Pas de connexion au serveur depuis 7+ jours. Mode offline limite.</li>
328
+ <li data-lang="en"><strong>Offline</strong>: No server connection for 7+ days. Limited offline mode.</li>
329
+ </ul>
330
+ </div>
331
+ </section>
332
+
333
+ <!-- ============================================
334
+ 5. DAILY OPERATION / FONCTIONNEMENT AU QUOTIDIEN
335
+ ============================================ -->
336
+ <section id="daily-operation">
337
+ <h2>
338
+ <span data-lang="fr">Fonctionnement au quotidien</span>
339
+ <span data-lang="en">Daily Operation</span>
340
+ </h2>
341
+
342
+ <p data-lang="fr">
343
+ Vous n'avez rien a faire. Le CLI gere la licence automatiquement a chaque lancement. Voici ce qui se passe en coulisses :
344
+ </p>
345
+ <p data-lang="en">
346
+ You don't need to do anything. The CLI manages the license automatically on each launch. Here's what happens behind the scenes:
347
+ </p>
348
+
349
+ <div class="tutorial-section">
350
+ <h3 data-lang="fr">Au lancement du CLI</h3>
351
+ <h3 data-lang="en">On CLI launch</h3>
352
+
353
+ <ol>
354
+ <li data-lang="fr">
355
+ <strong>Verification locale</strong> : Le CLI verifie la signature RS512 du JWT stocke localement
356
+ </li>
357
+ <li data-lang="en">
358
+ <strong>Local verification</strong>: The CLI verifies the RS512 signature of the locally stored JWT
359
+ </li>
360
+ <li data-lang="fr">
361
+ <strong>Verifier l'expiration</strong> : Si le JWT est expire → licence refusee, CLI s'arrete
362
+ </li>
363
+ <li data-lang="en">
364
+ <strong>Check expiration</strong>: If the JWT is expired → license denied, CLI stops
365
+ </li>
366
+ <li data-lang="fr">
367
+ <strong>Verifier le heartbeat</strong> : Y a-t-il un heartbeat a faire ? (tous les 7 jours par defaut)
368
+ </li>
369
+ <li data-lang="en">
370
+ <strong>Check heartbeat</strong>: Is a heartbeat due? (every 7 days by default)
371
+ </li>
372
+ <li data-lang="fr">
373
+ <strong>Si heartbeat requis</strong> : POST /machine/heartbeat avec fingerprint + instanceId
374
+ </li>
375
+ <li data-lang="en">
376
+ <strong>If heartbeat needed</strong>: POST /machine/heartbeat with fingerprint + instanceId
377
+ </li>
378
+ <li data-lang="fr">
379
+ <strong>Mise a jour du token</strong> : Si le serveur retourne un newJwtToken → remplacer le local
380
+ </li>
381
+ <li data-lang="en">
382
+ <strong>Token update</strong>: If the server returns a newJwtToken → replace the local one
383
+ </li>
384
+ <li data-lang="fr">
385
+ <strong>Continuer</strong> : CLI autorise, votre projet continue normalement
386
+ </li>
387
+ <li data-lang="en">
388
+ <strong>Continue</strong>: CLI authorized, your project continues normally
389
+ </li>
390
+ </ol>
391
+
392
+ <div class="tutorial-note">
393
+ <span class="note-icon">&#128161;</span>
394
+ <div>
395
+ <p data-lang="fr">
396
+ Si la licence expire ou est revoquee, vous recevez un message d'erreur clair et le CLI s'arrete. Vous devez mettre a jour ou reactiver votre licence.
397
+ </p>
398
+ <p data-lang="en">
399
+ If the license expires or is revoked, you receive a clear error message and the CLI stops. You must update or reactivate your license.
400
+ </p>
401
+ </div>
402
+ </div>
403
+ </div>
404
+ </section>
405
+
406
+ <!-- ============================================
407
+ 6. DEACTIVATE / DESACTIVER
408
+ ============================================ -->
409
+ <section id="deactivate">
410
+ <h2>
411
+ <span data-lang="fr">Desactiver une licence</span>
412
+ <span data-lang="en">Deactivate a License</span>
413
+ </h2>
414
+
415
+ <p data-lang="fr">
416
+ Supprimez la licence de votre machine locale. Vous aurez besoin de reactiver une licence pour utiliser le CLI a nouveau.
417
+ </p>
418
+ <p data-lang="en">
419
+ Remove the license from your local machine. You'll need to reactivate a license to use the CLI again.
420
+ </p>
421
+
422
+ <div class="tutorial-section">
423
+ <h3 data-lang="fr">Commande</h3>
424
+ <h3 data-lang="en">Command</h3>
425
+
426
+ <pre><code class="code-block">smartstack license deactivate</code></pre>
427
+
428
+ <h3 data-lang="fr">Processus</h3>
429
+ <h3 data-lang="en">Process</h3>
430
+
431
+ <ol>
432
+ <li data-lang="fr">Le CLI vous demande une confirmation</li>
433
+ <li data-lang="en">The CLI asks for confirmation</li>
434
+ <li data-lang="fr">La licence JWT locale est supprimee</li>
435
+ <li data-lang="en">The local JWT license is deleted</li>
436
+ <li data-lang="fr">POST /machine/deactivate est envoye au serveur (si possible)</li>
437
+ <li data-lang="en">POST /machine/deactivate is sent to the server (if possible)</li>
438
+ <li data-lang="fr">Confirmation : licence desactivee sur cette machine</li>
439
+ <li data-lang="en">Confirmation: license deactivated on this machine</li>
440
+ </ol>
441
+
442
+ <div class="tutorial-note">
443
+ <span class="note-icon">&#128161;</span>
444
+ <div>
445
+ <p data-lang="fr">
446
+ Apres desactivation, vous pouvez reactiver la meme licence sur une autre machine, ou en lancer un nouvel essai.
447
+ </p>
448
+ <p data-lang="en">
449
+ After deactivation, you can reactivate the same license on another machine, or start a new trial.
450
+ </p>
451
+ </div>
452
+ </div>
453
+ </div>
454
+ </section>
455
+
456
+ <!-- ============================================
457
+ 7. COMMAND SUMMARY / RESUME DES COMMANDES
458
+ ============================================ -->
459
+ <section id="command-summary">
460
+ <h2>
461
+ <span data-lang="fr">Résumé des commandes</span>
462
+ <span data-lang="en">Command Summary</span>
463
+ </h2>
464
+
465
+ <p data-lang="fr">
466
+ Voici un apercu rapide de toutes les commandes de licence disponibles :
467
+ </p>
468
+ <p data-lang="en">
469
+ Here's a quick overview of all available license commands:
470
+ </p>
471
+
472
+ <div class="table-container">
473
+ <table>
474
+ <thead>
475
+ <tr>
476
+ <th>
477
+ <span data-lang="fr">Commande</span>
478
+ <span data-lang="en">Command</span>
479
+ </th>
480
+ <th>
481
+ <span data-lang="fr">Description</span>
482
+ <span data-lang="en">Description</span>
483
+ </th>
484
+ </tr>
485
+ </thead>
486
+ <tbody>
487
+ <tr>
488
+ <td><code>smartstack license trial</code></td>
489
+ <td data-lang="fr">Enregistrer pour un essai gratuit de 14 jours</td>
490
+ <td data-lang="en">Register for a free 14-day trial</td>
491
+ </tr>
492
+ <tr>
493
+ <td><code>smartstack license activate &lt;token&gt;</code></td>
494
+ <td data-lang="fr">Activer une licence achetee sur cette machine</td>
495
+ <td data-lang="en">Activate a purchased license on this machine</td>
496
+ </tr>
497
+ <tr>
498
+ <td><code>smartstack license status</code></td>
499
+ <td data-lang="fr">Afficher le statut actuel de la licence</td>
500
+ <td data-lang="en">Show current license status</td>
501
+ </tr>
502
+ <tr>
503
+ <td><code>smartstack license verify &lt;token&gt;</code></td>
504
+ <td data-lang="fr">Verifier la validite d'un token sans l'activer</td>
505
+ <td data-lang="en">Verify a token's validity without activating it</td>
506
+ </tr>
507
+ <tr>
508
+ <td><code>smartstack license deactivate</code></td>
509
+ <td data-lang="fr">Supprimer la licence de cette machine</td>
510
+ <td data-lang="en">Remove the license from this machine</td>
511
+ </tr>
512
+ </tbody>
513
+ </table>
514
+ </div>
515
+ </section>
516
+
517
+ </div>
518
+ </main>
519
+ </div>
520
+ </div>
521
+
522
+ <!-- Mobile Menu Button -->
523
+ <button class="mobile-menu-btn">&#9776;</button>
524
+ <div class="overlay"></div>
525
+
526
+ <script src="js/app.js"></script>
527
+ </body>
528
+ </html>
@@ -66,6 +66,11 @@
66
66
  <span class="icon">&#128230;</span>
67
67
  <span class="nav-text">Installation</span>
68
68
  </a>
69
+ <a href="license.html" class="nav-item">
70
+ <span class="icon">&#128274;</span>
71
+ <span class="nav-text" data-lang="fr">Licence</span>
72
+ <span class="nav-text" data-lang="en">License</span>
73
+ </a>
69
74
  <a href="init.html" class="nav-item">
70
75
  <span class="icon">&#128640;</span>
71
76
  <span class="nav-text">Projet Client</span>
@@ -66,6 +66,11 @@
66
66
  <span class="icon">&#128230;</span>
67
67
  <span class="nav-text">Installation</span>
68
68
  </a>
69
+ <a href="license.html" class="nav-item">
70
+ <span class="icon">&#128274;</span>
71
+ <span class="nav-text" data-lang="fr">Licence</span>
72
+ <span class="nav-text" data-lang="en">License</span>
73
+ </a>
69
74
  <a href="init.html" class="nav-item">
70
75
  <span class="icon">&#128640;</span>
71
76
  <span class="nav-text">Projet Client</span>
package/dist/index.js CHANGED
@@ -125829,9 +125829,10 @@ csxveQKoRdG8wCb3BY4//8F0qLz21lqwPIM+cGZhUM1+ycYvC7HEke5xMxy6cCAS
125829
125829
  GwIDAQAB
125830
125830
  -----END PUBLIC KEY-----`;
125831
125831
  var LEGACY_ISSUER = "atlashub.io";
125832
- var NEW_ISSUER = "license.atlashub.ch";
125832
+ var NEW_ISSUERS = ["license.atlashub.ch", "license.smartstack.com"];
125833
125833
  var LEGACY_PRODUCT_IDS = ["smartstack-cli", "smartstackcli"];
125834
125834
  var NEW_PRODUCT_TIERS = ["standard", "plus", "premium"];
125835
+ var COMPOSITE_PRODUCT_PREFIX = "smartstack-cli-";
125835
125836
  function detectJwtFormat(token) {
125836
125837
  try {
125837
125838
  const headerB64 = token.split(".")[0];
@@ -125973,11 +125974,12 @@ function validateNewLicenseKey(licenseKey, signingKeyPem) {
125973
125974
  try {
125974
125975
  const decoded = jwt.verify(licenseKey, signingKeyPem, {
125975
125976
  algorithms: ["RS512"],
125976
- issuer: NEW_ISSUER
125977
+ issuer: NEW_ISSUERS
125977
125978
  });
125978
125979
  const productId = decoded.prd || decoded.product || decoded.aud;
125979
125980
  const allValid = [...NEW_PRODUCT_TIERS, ...LEGACY_PRODUCT_IDS];
125980
- if (!allValid.includes(productId)) {
125981
+ const isComposite = typeof productId === "string" && productId.startsWith(COMPOSITE_PRODUCT_PREFIX);
125982
+ if (!allValid.includes(productId) && !isComposite) {
125981
125983
  return {
125982
125984
  valid: false,
125983
125985
  error: `Invalid license: unrecognized product "${productId}"`,
@@ -126546,11 +126548,13 @@ function createLicenseCommand() {
126546
126548
  const client = new LicenseClient(baseUrl);
126547
126549
  const response = await client.registerTrial(answers);
126548
126550
  spinner.succeed("Trial registered!");
126551
+ const knownProducts = ["smartstack-cli", "smartstackcli", "standard", "plus", "premium"];
126549
126552
  const cliLicense = response.licenses.find(
126550
- (l) => ["smartstack-cli", "smartstackcli", "SmartStackCli", "standard", "Standard"].includes(l.product)
126551
- );
126553
+ (l) => knownProducts.includes(l.product.toLowerCase())
126554
+ ) || (response.licenses.length === 1 ? response.licenses[0] : void 0);
126552
126555
  if (!cliLicense) {
126553
- logger.error("No CLI license found in trial response");
126556
+ const returned = response.licenses.map((l) => l.product).join(", ");
126557
+ logger.error(`No CLI license found in trial response. Server returned: [${returned}]`);
126554
126558
  process.exit(1);
126555
126559
  }
126556
126560
  logger.info("\nActivating trial license...");
@@ -126577,13 +126581,13 @@ function createLicenseCommand() {
126577
126581
  });
126578
126582
  const apiKeyCmd = license.command("api-key").description("Manage API key for CI/CD authentication");
126579
126583
  apiKeyCmd.command("set <key>").description("Configure an API key for machine-to-machine authentication").action(async (key) => {
126580
- if (!key.startsWith("sslk_")) {
126581
- logger.error('Invalid API key format. Keys should start with "sslk_"');
126584
+ if (!key.startsWith("sk_")) {
126585
+ logger.error('Invalid API key format. Keys should start with "sk_"');
126582
126586
  process.exit(1);
126583
126587
  }
126584
126588
  await saveApiKey(key);
126585
126589
  logger.success("API key configured successfully");
126586
- console.log(source_default.gray(` Key prefix: ${key.substring(0, 12)}...`));
126590
+ console.log(source_default.gray(` Key prefix: ${key.substring(0, 10)}...`));
126587
126591
  });
126588
126592
  apiKeyCmd.command("remove").description("Remove the stored API key").action(async () => {
126589
126593
  const existing = await getApiKey();