@deveye/types 0.15.2 → 0.16.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.
Files changed (73) hide show
  1. package/package.json +6 -6
  2. package/src/domain/device.ts +4 -29
  3. package/src/domain/featureRegistry.ts +40 -108
  4. package/src/domain/home.ts +40 -101
  5. package/src/domain/live.ts +36 -87
  6. package/src/domain/metrics.ts +10 -14
  7. package/src/domain/notifications.ts +39 -110
  8. package/src/domain/project.ts +3 -162
  9. package/src/domain/report.ts +46 -95
  10. package/src/domain/secrecy.ts +3 -5
  11. package/src/domain/sharing.ts +33 -70
  12. package/src/domain/syncProtocol.ts +5 -12
  13. package/src/domain/user.ts +8 -14
  14. package/src/domain/workspace.ts +0 -3
  15. package/src/domain/workspaceRole.ts +34 -82
  16. package/src/features/agent.ts +306 -0
  17. package/src/features/live.ts +17 -37
  18. package/src/features/notify.ts +19 -57
  19. package/src/features/registry.ts +7 -44
  20. package/src/features/secrecy.ts +4 -9
  21. package/src/features/sharing.ts +12 -26
  22. package/src/features/user.ts +6 -11
  23. package/src/features/workspace.ts +6 -11
  24. package/src/http/auth.ts +6 -13
  25. package/src/http/device.ts +13 -17
  26. package/src/http/status.ts +6 -10
  27. package/src/index.ts +29 -932
  28. package/src/protocol/agent.ts +40 -70
  29. package/src/protocol/envelope.ts +3 -10
  30. package/src/sdk/client-ambient.d.ts +228 -21
  31. package/src/sdk/client.ts +277 -17
  32. package/src/sdk/devb.ts +120 -0
  33. package/src/sdk/manifest.test.ts +0 -1
  34. package/src/sdk/manifest.ts +94 -25
  35. package/src/sdk/providers.ts +310 -5
  36. package/src/sdk/server.ts +483 -19
  37. package/src/sdk/testing.test.ts +2 -2
  38. package/src/sdk/testing.ts +302 -26
  39. package/src/utils/version.ts +5 -8
  40. package/src/domain/audience.ts +0 -549
  41. package/src/domain/backup.ts +0 -355
  42. package/src/domain/credential.ts +0 -55
  43. package/src/domain/database.ts +0 -467
  44. package/src/domain/deploy.ts +0 -231
  45. package/src/domain/finance.ts +0 -477
  46. package/src/domain/git.ts +0 -419
  47. package/src/domain/mail.ts +0 -394
  48. package/src/domain/note.ts +0 -202
  49. package/src/domain/password.ts +0 -36
  50. package/src/domain/projectBoard.ts +0 -130
  51. package/src/domain/projectChat.ts +0 -46
  52. package/src/domain/projectHistory.ts +0 -82
  53. package/src/domain/projectLink.ts +0 -87
  54. package/src/domain/projectPlan.ts +0 -68
  55. package/src/domain/sentinel.ts +0 -623
  56. package/src/domain/uptime.ts +0 -216
  57. package/src/features/audience.ts +0 -275
  58. package/src/features/backup.ts +0 -230
  59. package/src/features/database.ts +0 -461
  60. package/src/features/deploy.ts +0 -245
  61. package/src/features/device.ts +0 -292
  62. package/src/features/deviceFiles.ts +0 -83
  63. package/src/features/deviceLogs.ts +0 -36
  64. package/src/features/deviceTerminal.ts +0 -57
  65. package/src/features/finance.ts +0 -360
  66. package/src/features/git.ts +0 -368
  67. package/src/features/mail.ts +0 -374
  68. package/src/features/metrics.ts +0 -185
  69. package/src/features/note.ts +0 -189
  70. package/src/features/password.ts +0 -67
  71. package/src/features/project.ts +0 -709
  72. package/src/features/sentinel.ts +0 -233
  73. package/src/features/uptime.ts +0 -186
@@ -1,28 +1,12 @@
1
1
  import { z } from 'zod';
2
- import { audienceCommands } from './audience';
3
- import { backupCommands } from './backup';
4
- import { deviceCommands } from './device';
5
- import { deviceFilesCommands } from './deviceFiles';
6
- import { deviceLogCommands } from './deviceLogs';
7
- import { deviceTerminalCommands } from './deviceTerminal';
8
- import { databaseCommands } from './database';
9
- import { deployCommands } from './deploy';
10
- import { financeCommands } from './finance';
11
- import { gitCommands } from './git';
2
+ import { agentCommands } from './agent';
12
3
  import { homeCommands } from './home';
13
4
  import { liveCommands } from './live';
14
5
  import { logsCommands } from './logs';
15
- import { mailCommands } from './mail';
16
- import { metricsCommands } from './metrics';
17
- import { noteCommands } from './note';
18
6
  import { notifyCommands } from './notify';
19
7
  import { sharingCommands } from './sharing';
20
- import { passwordCommands } from './password';
21
- import { projectCommands } from './project';
22
8
  import { secrecyCommands } from './secrecy';
23
- import { sentinelCommands } from './sentinel';
24
9
  import { twoFactorCommands } from './twoFactor';
25
- import { uptimeCommands } from './uptime';
26
10
  import { userCommands } from './user';
27
11
  import { adminCommands } from './admin';
28
12
  import { workspaceCommands } from './workspace';
@@ -37,27 +21,11 @@ export const featureCommands = [
37
21
  ...workspaceCommands,
38
22
  ...adminCommands,
39
23
  ...userCommands,
40
- ...passwordCommands,
41
- ...noteCommands,
42
- ...projectCommands,
43
- ...gitCommands,
44
- ...deployCommands,
45
- ...backupCommands,
46
- ...databaseCommands,
47
- ...financeCommands,
48
- ...audienceCommands,
49
- ...deviceCommands,
50
- ...deviceLogCommands,
51
- ...deviceTerminalCommands,
52
- ...deviceFilesCommands,
53
- ...metricsCommands,
54
- ...sentinelCommands,
55
- ...uptimeCommands,
24
+ ...agentCommands,
56
25
  ...twoFactorCommands,
57
26
  ...secrecyCommands,
58
27
  ...logsCommands,
59
28
  ...homeCommands,
60
- ...mailCommands,
61
29
  ...notifyCommands,
62
30
  ...sharingCommands,
63
31
  ...liveCommands
@@ -68,16 +36,11 @@ export const featureCommandRegistry: Record<string, FeatureCommandDescriptor> =
68
36
  );
69
37
 
70
38
  /**
71
- * Verse les contrats d'un module installé dans le registre des commandes,
72
- * celui que le `ws.send` du client consulte avant tout envoi. Sans cet
73
- * enregistrement, chaque commande d'un module serait refusée côté client
74
- * Unknown command ») avant même d'atteindre la socket, et son interface
75
- * resterait en chargement pour toujours.
76
- *
77
- * Une native rapatriée déclare les MÊMES objets que le registre publié : la
78
- * réinscription à l'identique est un no-op. Deux contrats différents sous le
79
- * même nom, en revanche, sont une collision de config, et le chargement doit
80
- * le dire plutôt que d'en servir un des deux au hasard.
39
+ * Verse les contrats d'un module installé dans le registre des commandes, que
40
+ * le `ws.send` du client consulte avant tout envoi ; sans cela, chaque commande
41
+ * du module serait refusée côté client (« Unknown command »). Réinscrire les
42
+ * mêmes objets est un no-op ; deux contrats différents sous le même nom sont
43
+ * une collision de config, et le chargement doit le dire.
81
44
  */
82
45
  export function registerFeatureCommands(commands: readonly FeatureCommandDescriptor[]): void {
83
46
  for (const c of commands) {
@@ -55,15 +55,10 @@ export const secrecySetReauth = {
55
55
  };
56
56
 
57
57
  /**
58
- * Hold (or release) the cached DEK for the duration of an open action popup.
59
- *
60
- * `active: true` is a heartbeat: it pins the DEK so the sliding grace window
61
- * cannot flush it while the user composes a long action, and must be re-sent
62
- * periodically — the server only honours the hold for a short lease, so if the
63
- * popup vanishes for *any* reason (close, navigation, crash, disconnect) the
64
- * heartbeats stop and the DEK reverts to a normal countdown. `active: false`
65
- * releases the hold and restarts a fresh grace window. The DEK can therefore
66
- * never linger indefinitely: only a genuinely-still-open popup keeps it alive.
58
+ * Hold (or release) the cached DEK while an action popup is open. `active:
59
+ * true` is a heartbeat: the server honours the hold for a short lease only, so
60
+ * if the popup vanishes for any reason the DEK reverts to a normal countdown.
61
+ * `active: false` releases the hold and restarts a fresh grace window.
67
62
  */
68
63
  export const secrecyHold = {
69
64
  command: 'secrecy.hold' as const,
@@ -8,16 +8,10 @@ import {
8
8
  } from '../domain/sharing';
9
9
 
10
10
  /**
11
- * Le partage d'un élément et ses restrictions par rôle.
12
- *
13
- * Un module transversal plutôt qu'un jeu de commandes par fonctionnalité : ce
14
- * que ces commandes prennent est toujours le même couple `(feature, itemId)`, et
15
- * les recopier par émetteur aurait reproduit exactement ce que l'unification des
16
- * notifications vient de défaire.
17
- *
18
- * L'autorisation ne peut pas être déclarative — la fonctionnalité visée est une
19
- * **donnée d'entrée**. Elle est vérifiée en tête de handler, comme pour
20
- * `notify.route*` et `device.setConfig`.
11
+ * Le partage d'un élément et ses restrictions par rôle. Un module transversal :
12
+ * ces commandes prennent toujours le même couple `(feature, itemId)`.
13
+ * L'autorisation ne peut pas être déclarative, la fonctionnalité visée étant
14
+ * une donnée d'entrée : elle est vérifiée en tête de handler.
21
15
  */
22
16
 
23
17
  /** Où cet élément est visible, et pourquoi il ne pourrait pas l'être. */
@@ -28,10 +22,8 @@ export const shareGet = {
28
22
  };
29
23
 
30
24
  /**
31
- * Projette (ou retire) l'élément dans un espace.
32
- *
33
- * Un seul espace par appel : la case de l'écran est la commande, ce qui rend
34
- * l'échec lisible — cocher une case qui échoue ne laisse pas les autres dans un
25
+ * Projette (ou retire) l'élément dans un espace. Un seul espace par appel : la
26
+ * case de l'écran est la commande, et un échec ne laisse pas les autres dans un
35
27
  * état incertain.
36
28
  */
37
29
  export const shareSet = {
@@ -44,13 +36,10 @@ export const shareSet = {
44
36
  };
45
37
 
46
38
  /**
47
- * Ce que chaque rôle d'un espace voit de cet élément l'hérité et l'exception.
48
- *
49
- * `workspaceId` absent = l'espace actif. Renseigné, il vise n'importe quel
50
- * espace où l'élément est visible : c'est ce qui permet de régler, depuis
51
- * l'onglet Partage du domicile, ce que chaque fenêtre montre — sans changer
52
- * d'espace. L'appelant doit être membre de l'espace visé ; y **écrire** exige
53
- * d'y tenir `workspace.roles`.
39
+ * Ce que chaque rôle d'un espace voit de cet élément (l'hérité et l'exception).
40
+ * `workspaceId` absent = l'espace actif ; renseigné, n'importe quel espace où
41
+ * l'élément est visible. L'appelant doit en être membre ; y écrire exige
42
+ * `workspace.roles`.
54
43
  */
55
44
  export const itemGrantList = {
56
45
  command: 'share.grantList' as const,
@@ -60,11 +49,8 @@ export const itemGrantList = {
60
49
 
61
50
  /**
62
51
  * Abaisse (ou rétablit) ce qu'un rôle peut faire sur cet élément, dans l'espace
63
- * visé (`workspaceId` absent = l'actif).
64
- *
65
- * `access: null` **retire** la restriction : le rôle reprend ce que la
66
- * fonctionnalité lui donne. C'est l'absence de ligne qui exprime « rien de
67
- * particulier », pas une valeur.
52
+ * visé (`workspaceId` absent = l'actif). `access: null` retire la restriction :
53
+ * le rôle reprend ce que la fonctionnalité lui donne.
68
54
  */
69
55
  export const itemGrantSet = {
70
56
  command: 'share.grantSet' as const,
@@ -31,10 +31,9 @@ export const THEME_IMAGE_MAX_LENGTH = 4_200_000;
31
31
  export const THEME_SLOT_COUNT = 5;
32
32
 
33
33
  /**
34
- * Upper bound on one saved slot value. Slots hold *compressed* data URLs (the
35
- * client downscales before saving) or a short raw URL, so this is a safety cap,
36
- * not the typical size it keeps the whole theme JSON (5 slots + active image)
37
- * within the browser's localStorage budget and the `users.theme` column.
34
+ * Upper bound on one saved slot value (a compressed data URL or a short raw
35
+ * URL): a safety cap keeping the whole theme JSON (5 slots + active image)
36
+ * within the browser's localStorage budget and the theme column.
38
37
  */
39
38
  export const THEME_SLOT_IMAGE_MAX_LENGTH = 1_500_000;
40
39
 
@@ -74,13 +73,9 @@ export const userSetColor = {
74
73
  };
75
74
 
76
75
  /**
77
- * Pose ou retire un drapeau de compte. Une commande unique pour tous les
78
- * drapeaux plutôt qu'une par réglage : le serveur n'a alors qu'un seul chemin de
79
- * lecture-modification-écriture sur `users.settings`, et un nouveau drapeau ne
80
- * coûte qu'une entrée dans `userSettingFlagSchema`.
81
- *
82
- * La sortie renvoie le sac **complet** tel qu'il vient d'être écrit : le client
83
- * peut s'aligner dessus au lieu de rejouer sa propre arithmétique.
76
+ * Pose ou retire un drapeau de compte. Une commande pour tous les drapeaux :
77
+ * un seul chemin lecture-modification-écriture sur `users.settings`. La sortie
78
+ * renvoie le sac complet tel qu'il vient d'être écrit.
84
79
  */
85
80
  export const userSetSetting = {
86
81
  command: 'user.setSetting' as const,
@@ -24,12 +24,9 @@ export const workspaceDelete = {
24
24
 
25
25
  /**
26
26
  * Bascule vers un espace : renvoie son apparence et sa disposition d'accueil.
27
- *
28
- * L'espace visé n'apparaît pas dans l'entrée — il voyage sur l'enveloppe, et le
29
- * dispatcheur a déjà vérifié l'appartenance avant d'appeler le handler. Passer
30
- * par `/api/auth/me` ne conviendrait pas : cette route recalcule l'espace actif à
31
- * partir du favori et renverrait l'apparence de l'espace qu'*elle* choisit, pas
32
- * de celui vers lequel on bascule.
27
+ * L'espace visé voyage sur l'enveloppe, appartenance vérifiée par le
28
+ * dispatcheur. `/api/auth/me` ne conviendrait pas : il recalcule l'espace actif
29
+ * à partir du favori.
33
30
  */
34
31
  export const workspaceActivate = {
35
32
  command: 'workspace.activate' as const,
@@ -77,11 +74,9 @@ export const workspaceRemoveMember = {
77
74
  };
78
75
 
79
76
  /**
80
- * Ajoute un membre à l'espace actif, désigné par son adresse.
81
- *
82
- * Pas de lien, pas d'acceptation : le compte existe déjà (l'inscription est sur
83
- * invitation d'un administrateur), donc le désigner suffit. Un lien serait un
84
- * détour — et un secret transmissible de plus à surveiller.
77
+ * Ajoute un membre à l'espace actif, désigné par son adresse. Pas de lien ni
78
+ * d'acceptation : le compte existe déjà (inscription sur invitation), et un
79
+ * lien serait un secret transmissible de plus.
85
80
  */
86
81
  export const workspaceAddMember = {
87
82
  command: 'workspace.addMember' as const,
package/src/http/auth.ts CHANGED
@@ -6,13 +6,11 @@ import { workspacePermissionsSchema } from '../domain/workspaceRole';
6
6
  import { themeStateSchema } from '../features/user';
7
7
 
8
8
  /**
9
- * Contenu commun à `/login`, `/refresh` et `/me` : le compte, les espaces
10
- * auxquels il a accès, et **l'espace actif seul** son thème et sa disposition
11
- * d'accueil.
12
- *
13
- * Le thème des autres espaces n'est délibérément pas embarqué : `bgImages` peut
14
- * contenir plusieurs data URLs, et les livrer tous multiplierait la charge utile
15
- * par le nombre d'espaces. Basculer d'espace va chercher les siens.
9
+ * Contenu commun à `/login`, `/refresh` et `/me` : le compte, ses espaces, et
10
+ * le thème et la disposition d'accueil de l'espace actif seul. Les thèmes des
11
+ * autres espaces ne sont pas embarqués : `bgImages` peut porter plusieurs data
12
+ * URLs, et les livrer tous multiplierait la charge utile par le nombre
13
+ * d'espaces.
16
14
  */
17
15
  export const sessionBundleSchema = z.object({
18
16
  user: userSchema,
@@ -34,12 +32,7 @@ export const loginRequestSchema = z.object({
34
32
 
35
33
  export type LoginRequest = z.infer<typeof loginRequestSchema>;
36
34
 
37
- /**
38
- * L'inscription n'est plus libre : elle exige un jeton d'invitation émis par un
39
- * administrateur. La route existait déjà, ouverte à tous et connectant
40
- * automatiquement — simplement inatteignable depuis l'interface, ce qui n'est
41
- * pas une protection.
42
- */
35
+ /** L'inscription exige un jeton d'invitation émis par un administrateur. */
43
36
  export const registerRequestSchema = z.object({
44
37
  inviteToken: z.string().min(1),
45
38
  username: z
@@ -23,15 +23,14 @@ export const LINK_CODE_TTL_MAX_SECONDS = 30 * 24 * 60 * 60;
23
23
  export const linkCodeRequestSchema = z.object({
24
24
  ttlSeconds: z.number().int().positive().max(LINK_CODE_TTL_MAX_SECONDS).nullable().optional(),
25
25
  /**
26
- * Approve the device automatically the moment it enrols with this code,
27
- * instead of leaving it `pending` for manual approval. Defaults to `false`
28
- * (manual approval stays the safe default).
26
+ * Approve the device the moment it enrols with this code, instead of
27
+ * leaving it `pending` for manual approval. Defaults to `false`.
29
28
  */
30
29
  autoApprove: z.boolean().default(false),
31
30
  /**
32
31
  * Espace dans lequel la machine sera rangée à l'enrôlement. Omis → l'espace
33
- * personnel de l'émetteur. L'émetteur doit en être membre : appairer une
34
- * machine dans un espace où l'on n'entre pas n'aurait aucun sens.
32
+ * actif de l'émetteur. Explicite (n'importe quel espace existant) : réservé
33
+ * à l'administrateur global.
35
34
  */
36
35
  workspaceId: z.number().int().positive().optional()
37
36
  });
@@ -84,13 +83,11 @@ export const enrollDeviceResponseSchema = z.object({
84
83
  export type EnrollDeviceResponse = z.infer<typeof enrollDeviceResponseSchema>;
85
84
 
86
85
  /**
87
- * Agent download matrix the **single source of truth** for the set of
88
- * platform binaries shipped with a release. Consumed by:
89
- * - the web UI (the "Télécharger l'agent" two-step picker), and
90
- * - the server (validates the `:target` param and resolves the file on disk).
91
- *
92
- * The CI release workflow and `agent/build-all.sh` mirror the same labels (they
93
- * can't import TS) — keep all three in sync when adding/removing a target.
86
+ * Agent download matrix: the single source of truth for the platform binaries
87
+ * shipped with a release, consumed by the web UI picker and the server
88
+ * (`:target` validation, file lookup). The CI release workflow and
89
+ * `agent/build-all.sh` mirror the same labels: keep all three in sync when
90
+ * adding or removing a target.
94
91
  */
95
92
  export const agentTargetSchema = z.enum([
96
93
  'linux-x86_64',
@@ -203,11 +200,10 @@ export const agentManifestTargetSchema = z.object({
203
200
  sha256: z.string().regex(/^[a-f0-9]{64}$/),
204
201
  size: z.number().int().nonnegative(),
205
202
  /**
206
- * Base64 ed25519 signature over the 32 raw bytes of `sha256`, produced by the
207
- * CI release with the dedicated update-signing key. The agent verifies it with
208
- * its embedded public key before self-replacing. **Optional**: a target with no
209
- * signature stays manually downloadable but can never drive a self-update — so a
210
- * pre-signing build degrades cleanly instead of being rejected outright.
203
+ * Base64 ed25519 signature over the 32 raw bytes of `sha256`, made by the CI
204
+ * release with the update-signing key; the agent verifies it with its
205
+ * embedded public key before self-replacing. Optional: an unsigned target
206
+ * stays downloadable but can never drive a self-update.
211
207
  */
212
208
  signature: z.string().min(1).optional()
213
209
  });
@@ -1,19 +1,15 @@
1
1
  import { z } from 'zod';
2
2
 
3
3
  /**
4
- * Server readiness / boot status (HTTP, `GET /api/status`).
5
- *
6
- * Surfaces the deployment/startup tasks the server runs before it is "100%
7
- * ready" — today just the agent-binary reconcile, but the shape is a generic
8
- * task list so more steps can be added later. The web client shows a discreet
9
- * topbar zone while `ready` is false, then hides it for good.
4
+ * Server readiness / boot status (HTTP, `GET /api/status`): the startup tasks
5
+ * the server runs before it is fully ready, as a generic task list. The web
6
+ * client shows a topbar zone while `ready` is false.
10
7
  */
11
8
 
12
9
  /**
13
- * `warning` is a terminal-but-visible outcome: the step finished without fully
14
- * succeeding, yet the app is usable (e.g. the agent reconcile served an older set
15
- * because this deploy's build never landed). It keeps the topbar zone shown — like
16
- * `error` — but reads as a non-blocking caution rather than a hard failure.
10
+ * `warning` is terminal but visible: the step finished without fully succeeding
11
+ * (e.g. the agent reconcile served an older set), the app is usable, and the
12
+ * topbar zone stays shown as a non-blocking caution.
17
13
  */
18
14
  export const bootTaskStateSchema = z.enum(['pending', 'running', 'done', 'warning', 'error']);
19
15
  export type BootTaskState = z.infer<typeof bootTaskStateSchema>;