@imenam/mcp-organizer 1.0.2 → 1.0.7

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 (50) hide show
  1. package/README.md +609 -548
  2. package/dist/shared/schemas/admin-api.schema.d.ts +101 -0
  3. package/dist/shared/schemas/admin-api.schema.js +39 -0
  4. package/dist/shared/schemas/agent-api.schema.d.ts +2 -0
  5. package/dist/shared/schemas/agent-api.schema.js +4 -0
  6. package/dist/shared/schemas/agent-tools.schema.d.ts +40 -1
  7. package/dist/shared/schemas/agent-tools.schema.js +8 -1
  8. package/dist/shared/schemas/api.schema.d.ts +2 -0
  9. package/dist/shared/schemas/api.schema.js +2 -0
  10. package/dist/shared/schemas/entities.schema.d.ts +27 -1
  11. package/dist/shared/schemas/entities.schema.js +21 -2
  12. package/dist/shared/schemas/notifications-api.schema.d.ts +31 -0
  13. package/dist/shared/schemas/notifications-api.schema.js +22 -1
  14. package/dist/src/agent-api/notifications.js +1 -0
  15. package/dist/src/agent-api/requests.js +2 -1
  16. package/dist/src/cli/set-admin.d.ts +1 -0
  17. package/dist/src/cli/set-admin.js +45 -0
  18. package/dist/src/cli/watch.d.ts +0 -3
  19. package/dist/src/cli/watch.js +1 -9
  20. package/dist/src/core/accounts.js +2 -1
  21. package/dist/src/core/admin.d.ts +24 -0
  22. package/dist/src/core/admin.js +85 -0
  23. package/dist/src/core/agent-tokens.d.ts +9 -1
  24. package/dist/src/core/agent-tokens.js +25 -2
  25. package/dist/src/core/agent.d.ts +5 -0
  26. package/dist/src/core/agent.js +23 -0
  27. package/dist/src/core/migrations.js +369 -344
  28. package/dist/src/core/notifications.d.ts +7 -1
  29. package/dist/src/core/notifications.js +32 -1
  30. package/dist/src/core/requests.d.ts +1 -1
  31. package/dist/src/core/requests.js +4 -4
  32. package/dist/src/core/store.d.ts +38 -2
  33. package/dist/src/core/store.js +161 -38
  34. package/dist/src/gui-api.d.ts +6 -0
  35. package/dist/src/gui-api.js +25 -4
  36. package/dist/src/index.js +8 -1
  37. package/dist/src/mcp/notifications.d.ts +22 -5
  38. package/dist/src/mcp/notifications.js +95 -9
  39. package/dist/src/mcp/start.d.ts +1 -1
  40. package/dist/src/mcp/start.js +39 -32
  41. package/dist/src/mcp/tools.js +1 -1
  42. package/dist/src/server/runner.d.ts +51 -0
  43. package/dist/src/server/runner.js +222 -0
  44. package/dist/src/server/start.js +8 -0
  45. package/gui/dist/assets/index-DuoSNpBr.js +70 -0
  46. package/gui/dist/assets/index-duxL0fvO.css +1 -0
  47. package/gui/dist/index.html +2 -2
  48. package/package.json +3 -2
  49. package/gui/dist/assets/index-BVN0agCc.css +0 -1
  50. package/gui/dist/assets/index-DI1_kr81.js +0 -70
@@ -0,0 +1,101 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * API d'administration (`/api/admin/*`), réservée aux administrateurs du
4
+ * site : tous les comptes avec leurs espaces, et l'autorisation du runner par
5
+ * espace.
6
+ */
7
+ export declare const AdminSpaceViewSchema: z.ZodObject<{
8
+ id: z.ZodString;
9
+ name: z.ZodString;
10
+ kind: z.ZodEnum<{
11
+ personal: "personal";
12
+ shared: "shared";
13
+ }>;
14
+ keyPrefix: z.ZodString;
15
+ runnerAllowed: z.ZodBoolean;
16
+ members: z.ZodArray<z.ZodObject<{
17
+ id: z.ZodString;
18
+ name: z.ZodString;
19
+ email: z.ZodPipe<z.ZodString, z.ZodEmail>;
20
+ }, z.core.$strip>>;
21
+ }, z.core.$strip>;
22
+ export type AdminSpaceView = z.infer<typeof AdminSpaceViewSchema>;
23
+ export declare const AdminUserViewSchema: z.ZodObject<{
24
+ id: z.ZodString;
25
+ email: z.ZodPipe<z.ZodString, z.ZodEmail>;
26
+ displayName: z.ZodNullable<z.ZodString>;
27
+ status: z.ZodEnum<{
28
+ active: "active";
29
+ disabled: "disabled";
30
+ invited: "invited";
31
+ }>;
32
+ isAdmin: z.ZodBoolean;
33
+ spaces: z.ZodArray<z.ZodObject<{
34
+ id: z.ZodString;
35
+ name: z.ZodString;
36
+ kind: z.ZodEnum<{
37
+ personal: "personal";
38
+ shared: "shared";
39
+ }>;
40
+ keyPrefix: z.ZodString;
41
+ runnerAllowed: z.ZodBoolean;
42
+ members: z.ZodArray<z.ZodObject<{
43
+ id: z.ZodString;
44
+ name: z.ZodString;
45
+ email: z.ZodPipe<z.ZodString, z.ZodEmail>;
46
+ }, z.core.$strip>>;
47
+ }, z.core.$strip>>;
48
+ }, z.core.$strip>;
49
+ export type AdminUserView = z.infer<typeof AdminUserViewSchema>;
50
+ /** État du runner du site : actif, ou désactivé avec la raison (en français). */
51
+ export declare const RunnerStatusSchema: z.ZodObject<{
52
+ enabled: z.ZodBoolean;
53
+ disabledReason: z.ZodNullable<z.ZodString>;
54
+ }, z.core.$strip>;
55
+ export type RunnerStatus = z.infer<typeof RunnerStatusSchema>;
56
+ /** `GET /admin/spaces` : comptes du plus ancien au plus récent, décompte des espaces autorisés et état du runner. */
57
+ export declare const AdminSpacesResponseSchema: z.ZodObject<{
58
+ users: z.ZodArray<z.ZodObject<{
59
+ id: z.ZodString;
60
+ email: z.ZodPipe<z.ZodString, z.ZodEmail>;
61
+ displayName: z.ZodNullable<z.ZodString>;
62
+ status: z.ZodEnum<{
63
+ active: "active";
64
+ disabled: "disabled";
65
+ invited: "invited";
66
+ }>;
67
+ isAdmin: z.ZodBoolean;
68
+ spaces: z.ZodArray<z.ZodObject<{
69
+ id: z.ZodString;
70
+ name: z.ZodString;
71
+ kind: z.ZodEnum<{
72
+ personal: "personal";
73
+ shared: "shared";
74
+ }>;
75
+ keyPrefix: z.ZodString;
76
+ runnerAllowed: z.ZodBoolean;
77
+ members: z.ZodArray<z.ZodObject<{
78
+ id: z.ZodString;
79
+ name: z.ZodString;
80
+ email: z.ZodPipe<z.ZodString, z.ZodEmail>;
81
+ }, z.core.$strip>>;
82
+ }, z.core.$strip>>;
83
+ }, z.core.$strip>>;
84
+ allowedCount: z.ZodNumber;
85
+ spaceCount: z.ZodNumber;
86
+ runner: z.ZodObject<{
87
+ enabled: z.ZodBoolean;
88
+ disabledReason: z.ZodNullable<z.ZodString>;
89
+ }, z.core.$strip>;
90
+ }, z.core.$strip>;
91
+ export type AdminSpacesResponse = z.infer<typeof AdminSpacesResponseSchema>;
92
+ /** `POST /spaces/:spaceId/runner/run` : session lancée pour traiter les demandes en attente. */
93
+ export declare const RunQueueResponseSchema: z.ZodObject<{
94
+ pendingCount: z.ZodNumber;
95
+ }, z.core.$strip>;
96
+ export type RunQueueResponse = z.infer<typeof RunQueueResponseSchema>;
97
+ /** `PUT /admin/spaces/:spaceId/runner` */
98
+ export declare const SetRunnerAllowedRequestSchema: z.ZodObject<{
99
+ allowed: z.ZodBoolean;
100
+ }, z.core.$strict>;
101
+ export type SetRunnerAllowedRequest = z.infer<typeof SetRunnerAllowedRequestSchema>;
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+ import { SpaceKindSchema, UserStatusSchema } from "./enums.schema.js";
3
+ import { EmailSchema, IdSchema } from "./entities.schema.js";
4
+ /**
5
+ * API d'administration (`/api/admin/*`), réservée aux administrateurs du
6
+ * site : tous les comptes avec leurs espaces, et l'autorisation du runner par
7
+ * espace.
8
+ */
9
+ export const AdminSpaceViewSchema = z.object({
10
+ id: IdSchema,
11
+ name: z.string(),
12
+ kind: SpaceKindSchema,
13
+ keyPrefix: z.string(),
14
+ runnerAllowed: z.boolean(),
15
+ /** Membres de l'espace, propriétaire compris, dans l'ordre d'arrivée. */
16
+ members: z.array(z.object({ id: IdSchema, name: z.string(), email: EmailSchema })),
17
+ });
18
+ export const AdminUserViewSchema = z.object({
19
+ id: IdSchema,
20
+ email: EmailSchema,
21
+ displayName: z.string().nullable(),
22
+ status: UserStatusSchema,
23
+ isAdmin: z.boolean(),
24
+ /** Espaces dont le compte est propriétaire : son espace personnel d'abord, puis ses espaces communs par nom. */
25
+ spaces: z.array(AdminSpaceViewSchema),
26
+ });
27
+ /** État du runner du site : actif, ou désactivé avec la raison (en français). */
28
+ export const RunnerStatusSchema = z.object({ enabled: z.boolean(), disabledReason: z.string().nullable() });
29
+ /** `GET /admin/spaces` : comptes du plus ancien au plus récent, décompte des espaces autorisés et état du runner. */
30
+ export const AdminSpacesResponseSchema = z.object({
31
+ users: z.array(AdminUserViewSchema),
32
+ allowedCount: z.number().int().min(0),
33
+ spaceCount: z.number().int().min(0),
34
+ runner: RunnerStatusSchema,
35
+ });
36
+ /** `POST /spaces/:spaceId/runner/run` : session lancée pour traiter les demandes en attente. */
37
+ export const RunQueueResponseSchema = z.object({ pendingCount: z.number().int().min(1) });
38
+ /** `PUT /admin/spaces/:spaceId/runner` */
39
+ export const SetRunnerAllowedRequestSchema = z.object({ allowed: z.boolean() }).strict();
@@ -236,6 +236,8 @@ export declare const RequestListResponseSchema: z.ZodObject<{
236
236
  lastUsedAt: z.ZodNullable<z.ZodISODateTime>;
237
237
  listening: z.ZodBoolean;
238
238
  }, z.core.$strip>>;
239
+ runnerAllowed: z.ZodBoolean;
240
+ runnerDisabledReason: z.ZodNullable<z.ZodString>;
239
241
  }, z.core.$strip>;
240
242
  export type RequestListResponse = z.infer<typeof RequestListResponseSchema>;
241
243
  /** Version d'une tâche dans son historique. */
@@ -80,6 +80,10 @@ export const RequestListResponseSchema = z.object({
80
80
  * récemment ; `listening` : un veilleur de notifications de ce jeton est armé.
81
81
  */
82
82
  agents: z.array(AgentRefSchema.extend({ lastUsedAt: TimestampSchema.nullable(), listening: z.boolean() })),
83
+ /** Le runner traite les demandes de l'espace (décidé par un administrateur). */
84
+ runnerAllowed: z.boolean(),
85
+ /** Raison pour laquelle le runner du site est désactivé (en français), null quand il est actif. */
86
+ runnerDisabledReason: z.string().nullable(),
83
87
  });
84
88
  /** Version d'une tâche dans son historique. */
85
89
  export const TaskVersionViewSchema = z.object({
@@ -361,6 +361,40 @@ export declare const ClaimRequestDataSchema: z.ZodObject<{
361
361
  reply: z.ZodNullable<z.ZodString>;
362
362
  failureReason: z.ZodNullable<z.ZodString>;
363
363
  }, z.core.$strip>;
364
+ history: z.ZodArray<z.ZodObject<{
365
+ id: z.ZodString;
366
+ kind: z.ZodEnum<{
367
+ idea: "idea";
368
+ idea_promotion: "idea_promotion";
369
+ message: "message";
370
+ remark: "remark";
371
+ test_review: "test_review";
372
+ }>;
373
+ status: z.ZodEnum<{
374
+ cancelled: "cancelled";
375
+ done: "done";
376
+ failed: "failed";
377
+ pending: "pending";
378
+ processing: "processing";
379
+ }>;
380
+ text: z.ZodString;
381
+ author: z.ZodObject<{
382
+ id: z.ZodString;
383
+ name: z.ZodString;
384
+ email: z.ZodString;
385
+ }, z.core.$strip>;
386
+ contextTask: z.ZodNullable<z.ZodObject<{
387
+ id: z.ZodString;
388
+ key: z.ZodString;
389
+ title: z.ZodString;
390
+ }, z.core.$strip>>;
391
+ contextIdeaId: z.ZodNullable<z.ZodString>;
392
+ createdAt: z.ZodISODateTime;
393
+ claimedAt: z.ZodNullable<z.ZodISODateTime>;
394
+ claimedByThisToken: z.ZodBoolean;
395
+ reply: z.ZodNullable<z.ZodString>;
396
+ failureReason: z.ZodNullable<z.ZodString>;
397
+ }, z.core.$strip>>;
364
398
  space: z.ZodObject<{
365
399
  id: z.ZodString;
366
400
  name: z.ZodString;
@@ -742,7 +776,11 @@ export declare const AgentWatcherSchema: z.ZodObject<{
742
776
  since: z.ZodNullable<z.ZodISODateTime>;
743
777
  lastSeen: z.ZodNullable<z.ZodISODateTime>;
744
778
  }, z.core.$strip>;
745
- /** `GET notifications` : jeton et espace de l'agent, demandes en attente et veilleur du jeton. */
779
+ /**
780
+ * `GET notifications` : jeton et espace de l'agent, demandes en attente,
781
+ * veilleur du jeton et curseur de départ d'une veille (`since` de la
782
+ * première attente : seules les demandes passées en attente ensuite sont rendues).
783
+ */
746
784
  export declare const NotificationsDataSchema: z.ZodObject<{
747
785
  token: z.ZodObject<{
748
786
  id: z.ZodString;
@@ -763,6 +801,7 @@ export declare const NotificationsDataSchema: z.ZodObject<{
763
801
  since: z.ZodNullable<z.ZodISODateTime>;
764
802
  lastSeen: z.ZodNullable<z.ZodISODateTime>;
765
803
  }, z.core.$strip>;
804
+ cursor: z.ZodISODateTime;
766
805
  }, z.core.$strip>;
767
806
  /**
768
807
  * `GET requests/wait` : demandes passées en attente (vide à l'expiration) et
@@ -145,6 +145,8 @@ export const AgentIdeaSchema = z.object({ id: IdSchema, text: z.string(), archiv
145
145
  export const ListRequestsDataSchema = z.object({ space: AgentSpaceSchema, requests: z.array(AgentRequestSummarySchema) });
146
146
  export const ClaimRequestDataSchema = z.object({
147
147
  request: AgentRequestSummarySchema,
148
+ /** Échanges précédents de l'auteur dans l'espace, du plus ancien au plus récent, pour une demande de type message. */
149
+ history: z.array(AgentRequestSummarySchema),
148
150
  space: AgentSpaceSchema,
149
151
  members: z.array(AgentMemberSchema),
150
152
  tasks: z.array(AgentTaskSummarySchema),
@@ -179,12 +181,17 @@ export const IdeaDataSchema = z.object({ idea: AgentIdeaSchema });
179
181
  export const PromoteIdeaDataSchema = z.object({ idea: AgentIdeaSchema, task: AgentTaskSummarySchema });
180
182
  /** Présence d'un veilleur de notifications pour le jeton. */
181
183
  export const AgentWatcherSchema = z.object({ armed: z.boolean(), since: TimestampSchema.nullable(), lastSeen: TimestampSchema.nullable() });
182
- /** `GET notifications` : jeton et espace de l'agent, demandes en attente et veilleur du jeton. */
184
+ /**
185
+ * `GET notifications` : jeton et espace de l'agent, demandes en attente,
186
+ * veilleur du jeton et curseur de départ d'une veille (`since` de la
187
+ * première attente : seules les demandes passées en attente ensuite sont rendues).
188
+ */
183
189
  export const NotificationsDataSchema = z.object({
184
190
  token: z.object({ id: IdSchema, name: z.string() }),
185
191
  space: AgentSpaceSchema,
186
192
  pendingCount: z.number().int().min(0),
187
193
  watcher: AgentWatcherSchema,
194
+ cursor: TimestampSchema,
188
195
  });
189
196
  /**
190
197
  * `GET requests/wait` : demandes passées en attente (vide à l'expiration) et
@@ -17,6 +17,7 @@ export declare const PublicUserSchema: z.ZodObject<{
17
17
  disabled: "disabled";
18
18
  invited: "invited";
19
19
  }>;
20
+ isAdmin: z.ZodBoolean;
20
21
  }, z.core.$strip>;
21
22
  export type PublicUser = z.infer<typeof PublicUserSchema>;
22
23
  export declare const LoginRequestSchema: z.ZodObject<{
@@ -34,6 +35,7 @@ export declare const MeResponseSchema: z.ZodObject<{
34
35
  disabled: "disabled";
35
36
  invited: "invited";
36
37
  }>;
38
+ isAdmin: z.ZodBoolean;
37
39
  }, z.core.$strip>;
38
40
  }, z.core.$strip>;
39
41
  export type MeResponse = z.infer<typeof MeResponseSchema>;
@@ -15,6 +15,8 @@ export const PublicUserSchema = z.object({
15
15
  email: EmailSchema,
16
16
  displayName: z.string().nullable(),
17
17
  status: UserStatusSchema,
18
+ /** Administrateur du site : voit la page Administration. */
19
+ isAdmin: z.boolean(),
18
20
  });
19
21
  // --- Authentification ---
20
22
  export const LoginRequestSchema = z.object({
@@ -18,6 +18,7 @@ export declare const UserSchema: z.ZodObject<{
18
18
  disabled: "disabled";
19
19
  invited: "invited";
20
20
  }>;
21
+ isAdmin: z.ZodBoolean;
21
22
  createdAt: z.ZodISODateTime;
22
23
  }, z.core.$strip>;
23
24
  export type User = z.infer<typeof UserSchema>;
@@ -58,16 +59,40 @@ export declare const AgentTokenSchema: z.ZodObject<{
58
59
  lastUsedAt: z.ZodNullable<z.ZodISODateTime>;
59
60
  expiresAt: z.ZodNullable<z.ZodISODateTime>;
60
61
  revokedAt: z.ZodNullable<z.ZodISODateTime>;
62
+ isRunner: z.ZodBoolean;
61
63
  }, z.core.$strip>;
62
64
  export type AgentToken = z.infer<typeof AgentTokenSchema>;
65
+ /** Bornes du nombre d'échanges précédents de l'auteur transmis à l'agent avec un message. */
66
+ export declare const MIN_ASSISTANT_HISTORY = 5;
67
+ export declare const MAX_ASSISTANT_HISTORY = 20;
68
+ export declare const AssistantHistorySchema: z.ZodNumber;
69
+ /** Préférences de notification : assignation et commentaire, dans l'application et par e-mail. */
70
+ export declare const NotificationPreferencesSchema: z.ZodObject<{
71
+ notifyAssignApp: z.ZodBoolean;
72
+ notifyAssignEmail: z.ZodBoolean;
73
+ notifyCommentApp: z.ZodBoolean;
74
+ notifyCommentEmail: z.ZodBoolean;
75
+ }, z.core.$strip>;
76
+ export type NotificationPreferences = z.infer<typeof NotificationPreferencesSchema>;
63
77
  export declare const UserSettingsSchema: z.ZodObject<{
64
- userId: z.ZodString;
65
78
  notifyAssignApp: z.ZodBoolean;
66
79
  notifyAssignEmail: z.ZodBoolean;
67
80
  notifyCommentApp: z.ZodBoolean;
68
81
  notifyCommentEmail: z.ZodBoolean;
82
+ userId: z.ZodString;
83
+ assistantHistory: z.ZodNumber;
69
84
  }, z.core.$strip>;
70
85
  export type UserSettings = z.infer<typeof UserSettingsSchema>;
86
+ /** Préférences de notification d'un utilisateur propres à un espace ; elles remplacent celles du compte dans cet espace. */
87
+ export declare const SpaceNotificationSettingsSchema: z.ZodObject<{
88
+ notifyAssignApp: z.ZodBoolean;
89
+ notifyAssignEmail: z.ZodBoolean;
90
+ notifyCommentApp: z.ZodBoolean;
91
+ notifyCommentEmail: z.ZodBoolean;
92
+ userId: z.ZodString;
93
+ spaceId: z.ZodString;
94
+ }, z.core.$strip>;
95
+ export type SpaceNotificationSettings = z.infer<typeof SpaceNotificationSettingsSchema>;
71
96
  export declare const SpaceSchema: z.ZodObject<{
72
97
  id: z.ZodString;
73
98
  name: z.ZodString;
@@ -78,6 +103,7 @@ export declare const SpaceSchema: z.ZodObject<{
78
103
  ownerId: z.ZodString;
79
104
  keyPrefix: z.ZodString;
80
105
  nextTaskNumber: z.ZodNumber;
106
+ runnerAllowed: z.ZodBoolean;
81
107
  createdAt: z.ZodISODateTime;
82
108
  }, z.core.$strip>;
83
109
  export type Space = z.infer<typeof SpaceSchema>;
@@ -20,6 +20,8 @@ export const UserSchema = z.object({
20
20
  displayName: z.string().min(1).nullable(),
21
21
  passwordHash: z.string().min(1).nullable(),
22
22
  status: UserStatusSchema,
23
+ /** Administrateur du site : accède à la page Administration. */
24
+ isAdmin: z.boolean(),
23
25
  createdAt: TimestampSchema,
24
26
  });
25
27
  export const AccessLinkSchema = z.object({
@@ -55,14 +57,29 @@ export const AgentTokenSchema = z.object({
55
57
  lastUsedAt: TimestampSchema.nullable(),
56
58
  expiresAt: TimestampSchema.nullable(),
57
59
  revokedAt: TimestampSchema.nullable(),
60
+ /** Jeton du runner de l'espace : absent des Paramètres, sa valeur change à chaque session. */
61
+ isRunner: z.boolean(),
58
62
  });
59
- export const UserSettingsSchema = z.object({
60
- userId: IdSchema,
63
+ /** Bornes du nombre d'échanges précédents de l'auteur transmis à l'agent avec un message. */
64
+ export const MIN_ASSISTANT_HISTORY = 5;
65
+ export const MAX_ASSISTANT_HISTORY = 20;
66
+ export const AssistantHistorySchema = z.number().int().min(MIN_ASSISTANT_HISTORY).max(MAX_ASSISTANT_HISTORY);
67
+ /** Préférences de notification : assignation et commentaire, dans l'application et par e-mail. */
68
+ export const NotificationPreferencesSchema = z.object({
61
69
  notifyAssignApp: z.boolean(),
62
70
  notifyAssignEmail: z.boolean(),
63
71
  notifyCommentApp: z.boolean(),
64
72
  notifyCommentEmail: z.boolean(),
65
73
  });
74
+ export const UserSettingsSchema = NotificationPreferencesSchema.extend({
75
+ userId: IdSchema,
76
+ assistantHistory: AssistantHistorySchema,
77
+ });
78
+ /** Préférences de notification d'un utilisateur propres à un espace ; elles remplacent celles du compte dans cet espace. */
79
+ export const SpaceNotificationSettingsSchema = NotificationPreferencesSchema.extend({
80
+ userId: IdSchema,
81
+ spaceId: IdSchema,
82
+ });
66
83
  export const SpaceSchema = z.object({
67
84
  id: IdSchema,
68
85
  name: z.string().trim().min(1),
@@ -70,6 +87,8 @@ export const SpaceSchema = z.object({
70
87
  ownerId: IdSchema,
71
88
  keyPrefix: KeyPrefixSchema,
72
89
  nextTaskNumber: z.number().int().min(1),
90
+ /** Le runner traite les demandes de l'espace ; décidé par un administrateur. */
91
+ runnerAllowed: z.boolean(),
73
92
  createdAt: TimestampSchema,
74
93
  });
75
94
  export const MembershipSchema = z.object({
@@ -68,6 +68,7 @@ export declare const SettingsResponseSchema: z.ZodObject<{
68
68
  notifyAssignEmail: z.ZodBoolean;
69
69
  notifyCommentApp: z.ZodBoolean;
70
70
  notifyCommentEmail: z.ZodBoolean;
71
+ assistantHistory: z.ZodNumber;
71
72
  email: z.ZodObject<{
72
73
  enabled: z.ZodBoolean;
73
74
  reason: z.ZodNullable<z.ZodString>;
@@ -83,5 +84,35 @@ export declare const UpdateSettingsRequestSchema: z.ZodObject<{
83
84
  notifyAssignEmail: z.ZodOptional<z.ZodBoolean>;
84
85
  notifyCommentApp: z.ZodOptional<z.ZodBoolean>;
85
86
  notifyCommentEmail: z.ZodOptional<z.ZodBoolean>;
87
+ assistantHistory: z.ZodOptional<z.ZodNumber>;
86
88
  }, z.core.$strict>;
87
89
  export type UpdateSettingsRequest = z.infer<typeof UpdateSettingsRequestSchema>;
90
+ /**
91
+ * Notifications de l'utilisateur dans un espace : `custom` dit si l'espace a ses
92
+ * propres préférences ; sinon, les valeurs renvoyées sont celles du compte.
93
+ */
94
+ export declare const SpaceNotificationSettingsResponseSchema: z.ZodObject<{
95
+ notifyAssignApp: z.ZodBoolean;
96
+ notifyAssignEmail: z.ZodBoolean;
97
+ notifyCommentApp: z.ZodBoolean;
98
+ notifyCommentEmail: z.ZodBoolean;
99
+ custom: z.ZodBoolean;
100
+ email: z.ZodObject<{
101
+ enabled: z.ZodBoolean;
102
+ reason: z.ZodNullable<z.ZodString>;
103
+ }, z.core.$strip>;
104
+ }, z.core.$strip>;
105
+ export type SpaceNotificationSettingsResponse = z.infer<typeof SpaceNotificationSettingsResponseSchema>;
106
+ /**
107
+ * Personnalise les notifications d'un espace (`custom: true`, avec les préférences
108
+ * à changer ; les autres partent des préférences en vigueur) ou revient à celles
109
+ * du compte (`custom: false`, sans préférence).
110
+ */
111
+ export declare const UpdateSpaceNotificationSettingsRequestSchema: z.ZodObject<{
112
+ notifyAssignApp: z.ZodOptional<z.ZodBoolean>;
113
+ notifyAssignEmail: z.ZodOptional<z.ZodBoolean>;
114
+ notifyCommentApp: z.ZodOptional<z.ZodBoolean>;
115
+ notifyCommentEmail: z.ZodOptional<z.ZodBoolean>;
116
+ custom: z.ZodBoolean;
117
+ }, z.core.$strict>;
118
+ export type UpdateSpaceNotificationSettingsRequest = z.infer<typeof UpdateSpaceNotificationSettingsRequestSchema>;
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { ActorTypeSchema, NotificationTypeSchema } from "./enums.schema.js";
3
- import { IdSchema, TimestampSchema } from "./entities.schema.js";
3
+ import { AssistantHistorySchema, IdSchema, NotificationPreferencesSchema, TimestampSchema } from "./entities.schema.js";
4
4
  /** Corps des requêtes et des réponses des notifications et des paramètres de la GUI. */
5
5
  /** Nombre de notifications renvoyées par défaut, et au plus, par page. */
6
6
  export const NOTIFICATIONS_PAGE_SIZE = 20;
@@ -42,6 +42,8 @@ export const SettingsResponseSchema = z.object({
42
42
  notifyAssignEmail: z.boolean(),
43
43
  notifyCommentApp: z.boolean(),
44
44
  notifyCommentEmail: z.boolean(),
45
+ /** Nombre d'échanges précédents transmis à l'agent avec un message de l'assistant. */
46
+ assistantHistory: AssistantHistorySchema,
45
47
  /** Envoi des e-mails de notification : `reason` dit pourquoi il n'a pas lieu. */
46
48
  email: z.object({ enabled: z.boolean(), reason: z.string().nullable() }),
47
49
  /** Dictée vocale : `reason` dit pourquoi elle est indisponible. */
@@ -53,6 +55,25 @@ export const UpdateSettingsRequestSchema = z
53
55
  notifyAssignEmail: z.boolean().optional(),
54
56
  notifyCommentApp: z.boolean().optional(),
55
57
  notifyCommentEmail: z.boolean().optional(),
58
+ assistantHistory: AssistantHistorySchema.optional(),
56
59
  })
57
60
  .strict()
58
61
  .refine((patch) => Object.values(patch).some((value) => value !== undefined), "Aucune modification demandée.");
62
+ /**
63
+ * Notifications de l'utilisateur dans un espace : `custom` dit si l'espace a ses
64
+ * propres préférences ; sinon, les valeurs renvoyées sont celles du compte.
65
+ */
66
+ export const SpaceNotificationSettingsResponseSchema = NotificationPreferencesSchema.extend({
67
+ custom: z.boolean(),
68
+ /** Envoi des e-mails de notification : `reason` dit pourquoi il n'a pas lieu. */
69
+ email: z.object({ enabled: z.boolean(), reason: z.string().nullable() }),
70
+ });
71
+ /**
72
+ * Personnalise les notifications d'un espace (`custom: true`, avec les préférences
73
+ * à changer ; les autres partent des préférences en vigueur) ou revient à celles
74
+ * du compte (`custom: false`, sans préférence).
75
+ */
76
+ export const UpdateSpaceNotificationSettingsRequestSchema = NotificationPreferencesSchema.partial()
77
+ .extend({ custom: z.boolean() })
78
+ .strict()
79
+ .refine((patch) => patch.custom || [patch.notifyAssignApp, patch.notifyAssignEmail, patch.notifyCommentApp, patch.notifyCommentEmail].every((value) => value === undefined), "Un espace qui suit les préférences du compte n'a pas de préférences propres.");
@@ -21,6 +21,7 @@ export const notificationRoutes = [
21
21
  space: spaceData(agent.space),
22
22
  pendingCount,
23
23
  watcher,
24
+ cursor: new Date().toISOString(),
24
25
  });
25
26
  },
26
27
  },
@@ -1,5 +1,5 @@
1
1
  import { ClaimRequestBodySchema, ClaimRequestDataSchema, CompleteRequestBodySchema, FailRequestBodySchema, FinishRequestDataSchema, ListRequestsDataSchema, ListRequestsQuerySchema, } from "../../shared/schemas/agent-tools.schema.js";
2
- import { agentActor, ideaData, memberData, recentIdeas, requestContext, requestData, requestLine, requestOfSpace, spaceData, treeData } from "../core/agent.js";
2
+ import { agentActor, ideaData, memberData, recentIdeas, requestContext, requestData, requestHistory, requestLine, requestOfSpace, spaceData, treeData } from "../core/agent.js";
3
3
  import { parseInput, respond } from "./types.js";
4
4
  /** Demandes de l'espace du jeton : liste, prise, fin (réussie ou en échec). */
5
5
  export const requestRoutes = [
@@ -28,6 +28,7 @@ export const requestRoutes = [
28
28
  const request = store.mutate(agentActor(agent, params.requestId), (tx) => tx.claimAgentRequest());
29
29
  return respond(ClaimRequestDataSchema, requestContext(store, agent, request), {
30
30
  request: requestData(store, agent, request),
31
+ history: requestHistory(store, request).map((previous) => requestData(store, agent, previous)),
31
32
  space: spaceData(agent.space),
32
33
  members: memberData(store, agent.space),
33
34
  tasks: treeData(store, agent.space),
@@ -0,0 +1 @@
1
+ export declare function runSetAdmin(argv: string[], dataDir: string): Promise<number>;
@@ -0,0 +1,45 @@
1
+ import { setAdmin } from "../core/admin.js";
2
+ import { Store } from "../core/store.js";
3
+ /**
4
+ * Commande `--set-admin <email> [--revoke]` : accorde le rôle
5
+ * d'administrateur du site à un compte actif, ou le lui retire avec
6
+ * `--revoke`. Le dernier administrateur ne peut pas perdre son rôle.
7
+ */
8
+ const USAGE = "Usage : mcp-organizer --set-admin <email> [--revoke]";
9
+ class UsageError extends Error {
10
+ }
11
+ function parseArgs(argv) {
12
+ const rest = argv.slice(argv.indexOf("--set-admin") + 1);
13
+ const unknown = rest.filter((arg) => arg.startsWith("-") && arg !== "--revoke");
14
+ if (unknown.length > 0)
15
+ throw new UsageError(`Option inconnue : ${unknown.join(", ")}.`);
16
+ const positional = rest.filter((arg) => !arg.startsWith("-"));
17
+ if (positional.length === 0)
18
+ throw new UsageError("--set-admin attend l'adresse e-mail du compte.");
19
+ if (positional.length > 1)
20
+ throw new UsageError(`Une seule adresse à la fois (reçu : ${positional.join(", ")}).`);
21
+ return { email: positional[0], revoke: rest.includes("--revoke") };
22
+ }
23
+ export async function runSetAdmin(argv, dataDir) {
24
+ let args;
25
+ try {
26
+ args = parseArgs(argv);
27
+ }
28
+ catch (err) {
29
+ process.stderr.write(`${err?.message ?? err}\n${USAGE}\n`);
30
+ return 1;
31
+ }
32
+ const store = Store.open(dataDir);
33
+ try {
34
+ const user = setAdmin(store, args.email, !args.revoke);
35
+ process.stdout.write(args.revoke ? `${user.email} n'est plus administrateur du site.\n` : `${user.email} (${user.displayName}) est administrateur du site.\n`);
36
+ return 0;
37
+ }
38
+ catch (err) {
39
+ process.stderr.write(`${err?.message ?? err}\n`);
40
+ return 1;
41
+ }
42
+ finally {
43
+ store.close();
44
+ }
45
+ }
@@ -1,4 +1 @@
1
- import { type AgentRequestSummary } from "../../shared/schemas/agent-tools.schema.js";
2
- /** Ligne d'une demande : une seule ligne, lisible telle quelle dans la notification. */
3
- export declare function formatRequestEvent(request: AgentRequestSummary): string;
4
1
  export declare function runWatchMode(tokenId: string | undefined): Promise<number>;
@@ -1,6 +1,7 @@
1
1
  import { MAX_WAIT_SECONDS } from "../../shared/schemas/agent-tools.schema.js";
2
2
  import { ConfigError } from "../core/errors.js";
3
3
  import { OrganizerSiteClient, SiteError } from "../mcp/client.js";
4
+ import { formatRequestEvent } from "../mcp/notifications.js";
4
5
  import { readHandoff } from "../mcp/watch-handoff.js";
5
6
  /**
6
7
  * Mode veilleur (`--watch <identifiant du jeton>`).
@@ -15,15 +16,6 @@ import { readHandoff } from "../mcp/watch-handoff.js";
15
16
  */
16
17
  const BACKOFF_MIN_MS = 1_000;
17
18
  const BACKOFF_MAX_MS = 30_000;
18
- /** Longueur maximale de l'extrait du texte de la demande. */
19
- const EXCERPT_LENGTH = 120;
20
- /** Ligne d'une demande : une seule ligne, lisible telle quelle dans la notification. */
21
- export function formatRequestEvent(request) {
22
- const text = request.text.replace(/\s+/g, " ").trim();
23
- const excerpt = text.length > EXCERPT_LENGTH ? `${text.slice(0, EXCERPT_LENGTH - 1)}…` : text;
24
- const context = request.contextTask ? ` · ${request.contextTask.key}` : "";
25
- return `[organizer] ${request.kind} · ${request.author.name} — "${excerpt}"${context} (${request.id})`;
26
- }
27
19
  /** Refus définitif du site : un nouvel essai donnerait la même réponse. */
28
20
  function isRefusal(error) {
29
21
  return error instanceof SiteError && error.status !== undefined && error.status >= 400 && error.status < 500 && error.status !== 408 && error.status !== 429;
@@ -147,7 +147,8 @@ export async function setAccount(store, input) {
147
147
  tx.discardUnusedAccessLinks(user.id);
148
148
  return { created: false, user };
149
149
  }
150
- const created = tx.createUser({ id: userId, email: normalized, displayName: name, passwordHash, status: "active" });
150
+ // Le premier compte du site en est l'administrateur.
151
+ const created = tx.createUser({ id: userId, email: normalized, displayName: name, passwordHash, status: "active", isAdmin: tx.store.countUsers() === 0 });
151
152
  ensurePersonalSpace(tx, created.id);
152
153
  return { created: true, user: created };
153
154
  });
@@ -0,0 +1,24 @@
1
+ import type { AdminSpaceView, AdminSpacesResponse, RunQueueResponse, RunnerStatus } from "../../shared/schemas/admin-api.schema.js";
2
+ import type { User } from "../../shared/schemas/entities.schema.js";
3
+ import type { Store } from "./store.js";
4
+ /**
5
+ * Administration du site : rôle d'administrateur des comptes, et
6
+ * autorisation du runner par espace. Seul un administrateur voit tous les
7
+ * comptes et tous les espaces, et décide des espaces où le runner travaille.
8
+ */
9
+ /** L'utilisateur est administrateur ; sinon, refus. */
10
+ export declare function requireAdmin(store: Store, userId: string): User;
11
+ /** Tous les comptes, chacun avec les espaces dont il est propriétaire, et l'état du runner. */
12
+ export declare function listAdminSpaces(store: Store, userId: string, runner: RunnerStatus): AdminSpacesResponse;
13
+ /** Autorise ou interdit le runner sur un espace. */
14
+ export declare function setRunnerAllowed(store: Store, userId: string, spaceId: string, allowed: boolean): AdminSpaceView;
15
+ /**
16
+ * Fait traiter une fois la file d'un espace par le runner, qu'il y soit
17
+ * autorisé ou non ; refus quand aucune demande n'y attend.
18
+ */
19
+ export declare function processQueueNow(store: Store, userId: string, spaceId: string, runNow: (spaceId: string) => void): RunQueueResponse;
20
+ /**
21
+ * Accorde ou retire le rôle d'administrateur au compte actif `email`. Le
22
+ * dernier administrateur garde son rôle : le site n'en reste jamais dépourvu.
23
+ */
24
+ export declare function setAdmin(store: Store, email: string, isAdmin: boolean): User;