clay-server 2.27.0-beta.9 → 2.27.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 (71) hide show
  1. package/README.md +10 -0
  2. package/lib/daemon-projects.js +164 -0
  3. package/lib/daemon.js +13 -126
  4. package/lib/mates-identity.js +132 -0
  5. package/lib/mates-knowledge.js +113 -0
  6. package/lib/mates-prompts.js +398 -0
  7. package/lib/mates.js +40 -599
  8. package/lib/project-connection.js +2 -0
  9. package/lib/project-http.js +4 -2
  10. package/lib/project-loop.js +110 -48
  11. package/lib/project-mate-interaction.js +4 -0
  12. package/lib/project-notifications.js +210 -0
  13. package/lib/project-sessions.js +5 -2
  14. package/lib/project-user-message.js +2 -1
  15. package/lib/project.js +26 -2
  16. package/lib/public/app.js +1193 -8517
  17. package/lib/public/css/command-palette.css +14 -0
  18. package/lib/public/css/loop.css +301 -0
  19. package/lib/public/css/notifications-center.css +190 -0
  20. package/lib/public/css/rewind.css +6 -0
  21. package/lib/public/index.html +89 -35
  22. package/lib/public/modules/app-connection.js +160 -0
  23. package/lib/public/modules/app-cursors.js +473 -0
  24. package/lib/public/modules/app-debate-ui.js +389 -0
  25. package/lib/public/modules/app-dm.js +627 -0
  26. package/lib/public/modules/app-favicon.js +212 -0
  27. package/lib/public/modules/app-header.js +229 -0
  28. package/lib/public/modules/app-home-hub.js +600 -0
  29. package/lib/public/modules/app-loop-ui.js +589 -0
  30. package/lib/public/modules/app-loop-wizard.js +439 -0
  31. package/lib/public/modules/app-messages.js +1560 -0
  32. package/lib/public/modules/app-misc.js +299 -0
  33. package/lib/public/modules/app-notifications.js +372 -0
  34. package/lib/public/modules/app-panels.js +888 -0
  35. package/lib/public/modules/app-projects.js +798 -0
  36. package/lib/public/modules/app-rate-limit.js +451 -0
  37. package/lib/public/modules/app-rendering.js +597 -0
  38. package/lib/public/modules/app-skills-install.js +234 -0
  39. package/lib/public/modules/command-palette.js +27 -4
  40. package/lib/public/modules/input.js +31 -20
  41. package/lib/public/modules/scheduler-config.js +1532 -0
  42. package/lib/public/modules/scheduler-history.js +79 -0
  43. package/lib/public/modules/scheduler.js +33 -1554
  44. package/lib/public/modules/session-search.js +13 -1
  45. package/lib/public/modules/sidebar-mates.js +812 -0
  46. package/lib/public/modules/sidebar-mobile.js +1269 -0
  47. package/lib/public/modules/sidebar-projects.js +1449 -0
  48. package/lib/public/modules/sidebar-sessions.js +986 -0
  49. package/lib/public/modules/sidebar.js +232 -4591
  50. package/lib/public/modules/store.js +27 -0
  51. package/lib/public/modules/ws-ref.js +7 -0
  52. package/lib/public/style.css +1 -0
  53. package/lib/sdk-bridge.js +96 -717
  54. package/lib/sdk-message-processor.js +587 -0
  55. package/lib/sdk-message-queue.js +42 -0
  56. package/lib/sdk-skill-discovery.js +131 -0
  57. package/lib/server-admin.js +712 -0
  58. package/lib/server-auth.js +737 -0
  59. package/lib/server-dm.js +221 -0
  60. package/lib/server-mates.js +281 -0
  61. package/lib/server-palette.js +110 -0
  62. package/lib/server-settings.js +479 -0
  63. package/lib/server-skills.js +280 -0
  64. package/lib/server.js +246 -2755
  65. package/lib/sessions.js +11 -4
  66. package/lib/users-auth.js +146 -0
  67. package/lib/users-permissions.js +118 -0
  68. package/lib/users-preferences.js +210 -0
  69. package/lib/users.js +48 -398
  70. package/lib/ws-schema.js +498 -0
  71. package/package.json +1 -1
@@ -0,0 +1,398 @@
1
+ /**
2
+ * Mates prompts module -- System section enforcers for mate CLAUDE.md files.
3
+ *
4
+ * Each enforcer manages a specific system-managed section (team awareness,
5
+ * session memory, sticky notes, project registry, debate awareness).
6
+ * Extracted from mates.js to keep module sizes manageable.
7
+ */
8
+
9
+ var fs = require("fs");
10
+ var path = require("path");
11
+ var crisisSafety = require("./crisis-safety");
12
+
13
+ // --- Marker constants ---
14
+
15
+ var TEAM_MARKER = "<!-- TEAM_AWARENESS_MANAGED_BY_SYSTEM -->";
16
+
17
+ var TEAM_SECTION =
18
+ "\n\n" + TEAM_MARKER + "\n" +
19
+ "## Your Team\n\n" +
20
+ "**This section is managed by the system and cannot be removed.**\n\n" +
21
+ "You are one of several AI Mates in this workspace. Your teammates and their profiles are listed in `../mates.json`. " +
22
+ "Each teammate's identity and working style is described in their own directory:\n\n" +
23
+ "- `../{mate_id}/CLAUDE.md` -- their identity, personality, and working style\n" +
24
+ "- `../{mate_id}/mate.yaml` -- their metadata (name, role, status, activities)\n" +
25
+ "- `../common-knowledge.json` -- shared knowledge registry; files listed here are readable by all mates\n\n" +
26
+ "Check the team registry when it would be relevant to know who else is available or what they do. " +
27
+ "You cannot message other Mates directly yet, but knowing your team helps you work with the user more effectively.\n";
28
+
29
+ var SESSION_MEMORY_MARKER = "<!-- SESSION_MEMORY_MANAGED_BY_SYSTEM -->";
30
+
31
+ var SESSION_MEMORY_SECTION =
32
+ "\n\n" + SESSION_MEMORY_MARKER + "\n" +
33
+ "## Session Memory\n\n" +
34
+ "**This section is managed by the system and cannot be removed.**\n\n" +
35
+ "Your `knowledge/memory-summary.md` file contains your compressed long-term memory, " +
36
+ "automatically maintained across sessions. Refer to it for context about past " +
37
+ "interactions, decisions, and patterns.\n\n" +
38
+ "Your `knowledge/session-digests.jsonl` file contains raw session logs as an archive. " +
39
+ "You do not need to read it routinely. Only access it when you need to look up " +
40
+ "specific details from a past session that are not in the summary.\n";
41
+
42
+ var STICKY_NOTES_MARKER = "<!-- STICKY_NOTES_MANAGED_BY_SYSTEM -->";
43
+
44
+ var STICKY_NOTES_SECTION =
45
+ "\n\n" + STICKY_NOTES_MARKER + "\n" +
46
+ "## Sticky Notes\n\n" +
47
+ "**This section is managed by the system and cannot be removed.**\n\n" +
48
+ "Your `knowledge/sticky-notes.md` file contains sticky notes left by the user. " +
49
+ "Read this file when starting a conversation for important context. " +
50
+ "These notes are read-only. You cannot create, update, or delete them.\n";
51
+
52
+ var PROJECT_REGISTRY_MARKER = "<!-- PROJECT_REGISTRY_MANAGED_BY_SYSTEM -->";
53
+
54
+ var DEBATE_AWARENESS_MARKER = "<!-- DEBATE_AWARENESS_MANAGED_BY_SYSTEM -->";
55
+
56
+ var DEBATE_AWARENESS_SECTION =
57
+ "\n\n" + DEBATE_AWARENESS_MARKER + "\n" +
58
+ "## Proposing Debates\n\n" +
59
+ "**This section is managed by the system and cannot be removed.**\n\n" +
60
+ "When the user suggests a debate, you MUST use the `propose_debate` tool. " +
61
+ "NEVER write debate files to disk. NEVER mkdir for debates. NEVER use Write/Bash for debate setup. " +
62
+ "The ONLY way to propose a debate is the `propose_debate` tool.\n\n" +
63
+ "**How to propose a debate:**\n" +
64
+ "Call the `propose_debate` tool with these parameters:\n" +
65
+ "- `topic` (required): The refined debate topic\n" +
66
+ "- `format`: Debate format, default \"free_discussion\"\n" +
67
+ "- `context`: Key context from the conversation that panelists should know\n" +
68
+ "- `specialRequests`: Any special instructions\n" +
69
+ "- `panelists` (required): A JSON string array of panelist objects:\n" +
70
+ " `[{\"mateId\": \"<mate UUID from team roster>\", \"role\": \"perspective\", \"brief\": \"guidance\"}]`\n\n" +
71
+ "The user will see an inline approval card. The tool blocks until they approve or cancel.\n\n" +
72
+ "**Rules:**\n" +
73
+ "- Choose 2-4 panelists from the team roster. Pick mates whose expertise fits the topic.\n" +
74
+ "- Do NOT include yourself as a panelist. You will moderate the debate.\n" +
75
+ "- Only propose a debate when the user explicitly asks for one.\n" +
76
+ "- Do NOT write files to disk for debate proposals. Always use the propose_debate tool.\n";
77
+
78
+ var ALL_SYSTEM_MARKERS = [TEAM_MARKER, PROJECT_REGISTRY_MARKER, "<!-- PRIMARY_CAPABILITIES_MANAGED_BY_SYSTEM -->", SESSION_MEMORY_MARKER, STICKY_NOTES_MARKER, DEBATE_AWARENESS_MARKER, crisisSafety.MARKER];
79
+
80
+ // --- Team awareness ---
81
+
82
+ /**
83
+ * Build a dynamic team section with current mate roster.
84
+ * @param {object} ctx - user context for loading mates
85
+ * @param {string} currentMateId - this mate's ID (excluded from the roster)
86
+ * @param {function} loadMates - function to load mates data
87
+ * @returns {string} Team section string, or static TEAM_SECTION as fallback
88
+ */
89
+ function buildTeamSection(ctx, currentMateId, loadMates) {
90
+ var data;
91
+ try { data = loadMates(ctx); } catch (e) { return TEAM_SECTION; }
92
+ if (!data || !data.mates || data.mates.length < 2) return TEAM_SECTION;
93
+
94
+ var mates = data.mates.filter(function (m) {
95
+ return m.id !== currentMateId && m.status === "ready";
96
+ });
97
+ if (mates.length === 0) return TEAM_SECTION;
98
+
99
+ var section = "\n\n" + TEAM_MARKER + "\n" +
100
+ "## Your Team\n\n" +
101
+ "**This section is managed by the system and updated automatically.**\n\n" +
102
+ "You are one of " + (mates.length + 1) + " AI Mates in this workspace. " +
103
+ "Here is your current team roster:\n\n" +
104
+ "| Name | ID | Bio |\n" +
105
+ "|------|-----|-----|\n";
106
+
107
+ for (var i = 0; i < mates.length; i++) {
108
+ var m = mates[i];
109
+ var name = (m.profile && m.profile.displayName) || m.name || "Unnamed";
110
+ var bio = (m.bio || "").replace(/\|/g, "/").replace(/\n/g, " ");
111
+ if (bio.length > 120) bio = bio.substring(0, 117) + "...";
112
+ section += "| " + name + " | `" + m.id + "` | " + bio + " |\n";
113
+ }
114
+
115
+ section += "\n" +
116
+ "Each teammate's full identity is in their own directory:\n\n" +
117
+ "- `../{mate_id}/CLAUDE.md` -- identity, personality, working style\n" +
118
+ "- `../{mate_id}/mate.yaml` -- metadata (name, role, status, activities)\n" +
119
+ "- `../common-knowledge.json` -- shared knowledge readable by all mates\n\n" +
120
+ "Use the **ID** (not the name) when referencing teammates in structured data. " +
121
+ "Names can change, IDs are permanent.\n";
122
+
123
+ return section;
124
+ }
125
+
126
+ function hasTeamSection(content) {
127
+ return content.indexOf(TEAM_MARKER) !== -1;
128
+ }
129
+
130
+ function enforceTeamAwareness(filePath) {
131
+ if (!fs.existsSync(filePath)) return false;
132
+
133
+ var content = fs.readFileSync(filePath, "utf8");
134
+
135
+ var teamIdx = content.indexOf(TEAM_MARKER);
136
+ if (teamIdx !== -1) {
137
+ var afterTeam = content.substring(teamIdx);
138
+ var nextMarkerIdx = -1;
139
+ var projIdx = afterTeam.indexOf(PROJECT_REGISTRY_MARKER);
140
+ var memIdx = afterTeam.indexOf(SESSION_MEMORY_MARKER);
141
+ var crisisIdx = afterTeam.indexOf(crisisSafety.MARKER);
142
+ var teamNextCandidates = [projIdx, memIdx, crisisIdx];
143
+ for (var tn = 0; tn < teamNextCandidates.length; tn++) {
144
+ if (teamNextCandidates[tn] !== -1 && (nextMarkerIdx === -1 || teamNextCandidates[tn] < nextMarkerIdx)) {
145
+ nextMarkerIdx = teamNextCandidates[tn];
146
+ }
147
+ }
148
+ var existing;
149
+ if (nextMarkerIdx !== -1) {
150
+ existing = afterTeam.substring(0, nextMarkerIdx).trimEnd();
151
+ } else {
152
+ existing = afterTeam.trimEnd();
153
+ }
154
+ if (existing === TEAM_SECTION.trimStart().trimEnd()) return false;
155
+
156
+ var endOfTeam = nextMarkerIdx !== -1 ? teamIdx + nextMarkerIdx : content.length;
157
+ content = content.substring(0, teamIdx).trimEnd() + content.substring(endOfTeam);
158
+ }
159
+
160
+ var insertBefore = -1;
161
+ var teamInsertCandidates = [PROJECT_REGISTRY_MARKER, SESSION_MEMORY_MARKER, STICKY_NOTES_MARKER, DEBATE_AWARENESS_MARKER, crisisSafety.MARKER];
162
+ for (var ti = 0; ti < teamInsertCandidates.length; ti++) {
163
+ var tip = content.indexOf(teamInsertCandidates[ti]);
164
+ if (tip !== -1) { insertBefore = tip; break; }
165
+ }
166
+ if (insertBefore !== -1) {
167
+ content = content.substring(0, insertBefore).trimEnd() + TEAM_SECTION + "\n\n" + content.substring(insertBefore);
168
+ } else {
169
+ content = content.trimEnd() + TEAM_SECTION;
170
+ }
171
+
172
+ fs.writeFileSync(filePath, content, "utf8");
173
+ return true;
174
+ }
175
+
176
+ // --- Project registry ---
177
+
178
+ function buildProjectRegistrySection(projects) {
179
+ if (!projects || projects.length === 0) return "";
180
+ var section = "\n\n" + PROJECT_REGISTRY_MARKER + "\n" +
181
+ "## Available Projects\n\n" +
182
+ "**This section is managed by the system and cannot be removed.**\n\n" +
183
+ "The following projects are registered in this workspace. " +
184
+ "Use this information when the user references a project by name, " +
185
+ "so you do not need to ask for the path.\n\n" +
186
+ "| Project | Path |\n" +
187
+ "|---------|------|\n";
188
+ for (var i = 0; i < projects.length; i++) {
189
+ var p = projects[i];
190
+ var name = (p.icon ? p.icon + " " : "") + (p.title || p.slug || path.basename(p.path));
191
+ section += "| " + name + " | `" + p.path + "` |\n";
192
+ }
193
+ return section;
194
+ }
195
+
196
+ function enforceProjectRegistry(filePath, projects) {
197
+ if (!fs.existsSync(filePath)) return false;
198
+
199
+ var content = fs.readFileSync(filePath, "utf8");
200
+ var newSection = buildProjectRegistrySection(projects);
201
+
202
+ var markerIdx = content.indexOf(PROJECT_REGISTRY_MARKER);
203
+ if (markerIdx !== -1) {
204
+ var afterMarker = content.substring(markerIdx);
205
+ var nextIdx = -1;
206
+ var candidates = [SESSION_MEMORY_MARKER, STICKY_NOTES_MARKER, DEBATE_AWARENESS_MARKER, crisisSafety.MARKER];
207
+ for (var c = 0; c < candidates.length; c++) {
208
+ var ci = afterMarker.indexOf(candidates[c]);
209
+ if (ci !== -1 && (nextIdx === -1 || ci < nextIdx)) nextIdx = ci;
210
+ }
211
+
212
+ if (nextIdx !== -1) {
213
+ var existing = afterMarker.substring(0, nextIdx).trimEnd();
214
+ if (existing === newSection.trimStart().trimEnd()) return false;
215
+ content = content.substring(0, markerIdx).trimEnd() + content.substring(markerIdx + nextIdx);
216
+ } else {
217
+ var existing = afterMarker.trimEnd();
218
+ if (existing === newSection.trimStart().trimEnd()) return false;
219
+ content = content.substring(0, markerIdx).trimEnd();
220
+ }
221
+ }
222
+
223
+ if (!newSection) {
224
+ if (markerIdx !== -1) {
225
+ fs.writeFileSync(filePath, content, "utf8");
226
+ return true;
227
+ }
228
+ return false;
229
+ }
230
+
231
+ var insertBefore = -1;
232
+ var insertCandidates = [SESSION_MEMORY_MARKER, STICKY_NOTES_MARKER, DEBATE_AWARENESS_MARKER, crisisSafety.MARKER];
233
+ for (var ic = 0; ic < insertCandidates.length; ic++) {
234
+ var pos = content.indexOf(insertCandidates[ic]);
235
+ if (pos !== -1) { insertBefore = pos; break; }
236
+ }
237
+ if (insertBefore !== -1) {
238
+ content = content.substring(0, insertBefore).trimEnd() + newSection + "\n\n" + content.substring(insertBefore);
239
+ } else {
240
+ content = content.trimEnd() + newSection;
241
+ }
242
+
243
+ fs.writeFileSync(filePath, content, "utf8");
244
+ return true;
245
+ }
246
+
247
+ // --- Session memory ---
248
+
249
+ function hasSessionMemory(content) {
250
+ return content.indexOf(SESSION_MEMORY_MARKER) !== -1;
251
+ }
252
+
253
+ function enforceSessionMemory(filePath) {
254
+ if (!fs.existsSync(filePath)) return false;
255
+
256
+ var content = fs.readFileSync(filePath, "utf8");
257
+
258
+ var memIdx = content.indexOf(SESSION_MEMORY_MARKER);
259
+ if (memIdx !== -1) {
260
+ var afterMem = content.substring(memIdx);
261
+ var nextMemIdx = -1;
262
+ var memNextCandidates = [STICKY_NOTES_MARKER, DEBATE_AWARENESS_MARKER, crisisSafety.MARKER];
263
+ for (var mn = 0; mn < memNextCandidates.length; mn++) {
264
+ var mni = afterMem.indexOf(memNextCandidates[mn]);
265
+ if (mni !== -1 && (nextMemIdx === -1 || mni < nextMemIdx)) nextMemIdx = mni;
266
+ }
267
+ var existing;
268
+ if (nextMemIdx !== -1) {
269
+ existing = afterMem.substring(0, nextMemIdx).trimEnd();
270
+ } else {
271
+ existing = afterMem.trimEnd();
272
+ }
273
+ if (existing === SESSION_MEMORY_SECTION.trimStart().trimEnd()) return false;
274
+
275
+ var endOfMem = nextMemIdx !== -1 ? memIdx + nextMemIdx : content.length;
276
+ content = content.substring(0, memIdx).trimEnd() + content.substring(endOfMem);
277
+ }
278
+
279
+ var memInsertBefore = -1;
280
+ var memInsertCandidates = [STICKY_NOTES_MARKER, DEBATE_AWARENESS_MARKER, crisisSafety.MARKER];
281
+ for (var mi = 0; mi < memInsertCandidates.length; mi++) {
282
+ var mip = content.indexOf(memInsertCandidates[mi]);
283
+ if (mip !== -1) { memInsertBefore = mip; break; }
284
+ }
285
+ if (memInsertBefore !== -1) {
286
+ content = content.substring(0, memInsertBefore).trimEnd() + SESSION_MEMORY_SECTION + "\n\n" + content.substring(memInsertBefore);
287
+ } else {
288
+ content = content.trimEnd() + SESSION_MEMORY_SECTION;
289
+ }
290
+
291
+ fs.writeFileSync(filePath, content, "utf8");
292
+ return true;
293
+ }
294
+
295
+ // --- Sticky notes ---
296
+
297
+ function hasStickyNotesSection(content) {
298
+ return content.indexOf(STICKY_NOTES_MARKER) !== -1;
299
+ }
300
+
301
+ function enforceStickyNotes(filePath) {
302
+ if (!fs.existsSync(filePath)) return false;
303
+
304
+ var content = fs.readFileSync(filePath, "utf8");
305
+
306
+ var markerIdx = content.indexOf(STICKY_NOTES_MARKER);
307
+ if (markerIdx !== -1) {
308
+ var afterMarker = content.substring(markerIdx);
309
+ var stickyNextIdx = -1;
310
+ var stickyNextCandidates = [DEBATE_AWARENESS_MARKER, crisisSafety.MARKER];
311
+ for (var sn = 0; sn < stickyNextCandidates.length; sn++) {
312
+ var sni = afterMarker.indexOf(stickyNextCandidates[sn]);
313
+ if (sni !== -1 && (stickyNextIdx === -1 || sni < stickyNextIdx)) stickyNextIdx = sni;
314
+ }
315
+ var existing;
316
+ if (stickyNextIdx !== -1) {
317
+ existing = afterMarker.substring(0, stickyNextIdx).trimEnd();
318
+ } else {
319
+ existing = afterMarker.trimEnd();
320
+ }
321
+ if (existing === STICKY_NOTES_SECTION.trimStart().trimEnd()) return false;
322
+
323
+ var endOfSection = stickyNextIdx !== -1 ? markerIdx + stickyNextIdx : content.length;
324
+ content = content.substring(0, markerIdx).trimEnd() + content.substring(endOfSection);
325
+ }
326
+
327
+ var stickyInsertBefore = -1;
328
+ var stickyInsertCandidates = [DEBATE_AWARENESS_MARKER, crisisSafety.MARKER];
329
+ for (var si = 0; si < stickyInsertCandidates.length; si++) {
330
+ var sip = content.indexOf(stickyInsertCandidates[si]);
331
+ if (sip !== -1) { stickyInsertBefore = sip; break; }
332
+ }
333
+ if (stickyInsertBefore !== -1) {
334
+ content = content.substring(0, stickyInsertBefore).trimEnd() + STICKY_NOTES_SECTION + "\n\n" + content.substring(stickyInsertBefore);
335
+ } else {
336
+ content = content.trimEnd() + STICKY_NOTES_SECTION;
337
+ }
338
+
339
+ fs.writeFileSync(filePath, content, "utf8");
340
+ return true;
341
+ }
342
+
343
+ // --- Debate awareness ---
344
+
345
+ function enforceDebateAwareness(filePath) {
346
+ if (!fs.existsSync(filePath)) return false;
347
+
348
+ var content = fs.readFileSync(filePath, "utf8");
349
+
350
+ var markerIdx = content.indexOf(DEBATE_AWARENESS_MARKER);
351
+ if (markerIdx !== -1) {
352
+ var afterMarker = content.substring(markerIdx);
353
+ var crisisIdx = afterMarker.indexOf(crisisSafety.MARKER);
354
+ var existing;
355
+ if (crisisIdx !== -1) {
356
+ existing = afterMarker.substring(0, crisisIdx).trimEnd();
357
+ } else {
358
+ existing = afterMarker.trimEnd();
359
+ }
360
+ if (existing === DEBATE_AWARENESS_SECTION.trimStart().trimEnd()) return false;
361
+
362
+ var endOfSection = crisisIdx !== -1 ? markerIdx + crisisIdx : content.length;
363
+ content = content.substring(0, markerIdx).trimEnd() + content.substring(endOfSection);
364
+ }
365
+
366
+ var crisisPos = content.indexOf(crisisSafety.MARKER);
367
+ if (crisisPos !== -1) {
368
+ content = content.substring(0, crisisPos).trimEnd() + DEBATE_AWARENESS_SECTION + "\n\n" + content.substring(crisisPos);
369
+ } else {
370
+ content = content.trimEnd() + DEBATE_AWARENESS_SECTION;
371
+ }
372
+
373
+ fs.writeFileSync(filePath, content, "utf8");
374
+ return true;
375
+ }
376
+
377
+ module.exports = {
378
+ TEAM_MARKER: TEAM_MARKER,
379
+ TEAM_SECTION: TEAM_SECTION,
380
+ SESSION_MEMORY_MARKER: SESSION_MEMORY_MARKER,
381
+ SESSION_MEMORY_SECTION: SESSION_MEMORY_SECTION,
382
+ STICKY_NOTES_MARKER: STICKY_NOTES_MARKER,
383
+ STICKY_NOTES_SECTION: STICKY_NOTES_SECTION,
384
+ PROJECT_REGISTRY_MARKER: PROJECT_REGISTRY_MARKER,
385
+ DEBATE_AWARENESS_MARKER: DEBATE_AWARENESS_MARKER,
386
+ DEBATE_AWARENESS_SECTION: DEBATE_AWARENESS_SECTION,
387
+ ALL_SYSTEM_MARKERS: ALL_SYSTEM_MARKERS,
388
+ buildTeamSection: buildTeamSection,
389
+ hasTeamSection: hasTeamSection,
390
+ enforceTeamAwareness: enforceTeamAwareness,
391
+ buildProjectRegistrySection: buildProjectRegistrySection,
392
+ enforceProjectRegistry: enforceProjectRegistry,
393
+ hasSessionMemory: hasSessionMemory,
394
+ enforceSessionMemory: enforceSessionMemory,
395
+ hasStickyNotesSection: hasStickyNotesSection,
396
+ enforceStickyNotes: enforceStickyNotes,
397
+ enforceDebateAwareness: enforceDebateAwareness,
398
+ };