reflectt-node 0.1.16 → 0.1.18

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 (66) hide show
  1. package/dist/activationEvents.d.ts +3 -1
  2. package/dist/activationEvents.d.ts.map +1 -1
  3. package/dist/activationEvents.js +5 -0
  4. package/dist/activationEvents.js.map +1 -1
  5. package/dist/canvas-auto-state.d.ts +7 -3
  6. package/dist/canvas-auto-state.d.ts.map +1 -1
  7. package/dist/canvas-auto-state.js +33 -5
  8. package/dist/canvas-auto-state.js.map +1 -1
  9. package/dist/canvas-interactive.d.ts +52 -0
  10. package/dist/canvas-interactive.d.ts.map +1 -0
  11. package/dist/canvas-interactive.js +401 -0
  12. package/dist/canvas-interactive.js.map +1 -0
  13. package/dist/canvas-multiplexer.d.ts +3 -0
  14. package/dist/canvas-multiplexer.d.ts.map +1 -1
  15. package/dist/canvas-multiplexer.js +28 -0
  16. package/dist/canvas-multiplexer.js.map +1 -1
  17. package/dist/canvas-push.d.ts +9 -0
  18. package/dist/canvas-push.d.ts.map +1 -0
  19. package/dist/canvas-push.js +169 -0
  20. package/dist/canvas-push.js.map +1 -0
  21. package/dist/canvas-query.d.ts +26 -0
  22. package/dist/canvas-query.d.ts.map +1 -0
  23. package/dist/canvas-query.js +369 -0
  24. package/dist/canvas-query.js.map +1 -0
  25. package/dist/canvas-routes.d.ts +59 -8
  26. package/dist/canvas-routes.d.ts.map +1 -1
  27. package/dist/canvas-routes.js +422 -7
  28. package/dist/canvas-routes.js.map +1 -1
  29. package/dist/canvas-slots.d.ts +1 -1
  30. package/dist/canvas-takeover.d.ts +19 -0
  31. package/dist/canvas-takeover.d.ts.map +1 -0
  32. package/dist/canvas-takeover.js +121 -0
  33. package/dist/canvas-takeover.js.map +1 -0
  34. package/dist/canvas-types.d.ts +1 -1
  35. package/dist/canvas-types.d.ts.map +1 -1
  36. package/dist/canvas-types.js +1 -0
  37. package/dist/canvas-types.js.map +1 -1
  38. package/dist/cloud.d.ts.map +1 -1
  39. package/dist/cloud.js +25 -5
  40. package/dist/cloud.js.map +1 -1
  41. package/dist/ghost-signup-nudge.d.ts +43 -0
  42. package/dist/ghost-signup-nudge.d.ts.map +1 -0
  43. package/dist/ghost-signup-nudge.js +175 -0
  44. package/dist/ghost-signup-nudge.js.map +1 -0
  45. package/dist/preflight.d.ts.map +1 -1
  46. package/dist/preflight.js +7 -0
  47. package/dist/preflight.js.map +1 -1
  48. package/dist/presence.d.ts +1 -0
  49. package/dist/presence.d.ts.map +1 -1
  50. package/dist/presence.js.map +1 -1
  51. package/dist/restart-drift-guard.d.ts +9 -0
  52. package/dist/restart-drift-guard.d.ts.map +1 -0
  53. package/dist/restart-drift-guard.js +80 -0
  54. package/dist/restart-drift-guard.js.map +1 -0
  55. package/dist/server.d.ts.map +1 -1
  56. package/dist/server.js +258 -1307
  57. package/dist/server.js.map +1 -1
  58. package/dist/tasks.d.ts +1 -0
  59. package/dist/tasks.d.ts.map +1 -1
  60. package/dist/tasks.js +95 -18
  61. package/dist/tasks.js.map +1 -1
  62. package/dist/workflow-templates.d.ts.map +1 -1
  63. package/dist/workflow-templates.js +41 -1
  64. package/dist/workflow-templates.js.map +1 -1
  65. package/package.json +2 -2
  66. package/public/docs.md +5 -1
@@ -1,16 +1,29 @@
1
1
  /**
2
- * Canvas Routes (Phase 1) — extracted from server.ts
2
+ * Canvas Routes — extracted from server.ts
3
3
  *
4
- * Fastify plugin that registers a first batch of /canvas/* endpoints.
5
- * Each extracted route is replaced with this plugin in server.ts.
6
- * Remaining routes stay in server.ts for Phase 2+ extraction.
4
+ * Fastify plugin registering /canvas/* read-only + discovery endpoints.
5
+ * Dependencies injected via plugin options.
7
6
  *
8
- * Extraction strategy: start with simple, self-contained routes.
9
- * Complex routes with deep state coupling remain in server.ts.
7
+ * Phase 1: states, slots, slots/all, rejections
8
+ * Phase 2: presence, state, flow-score, team/mood
10
9
  *
11
- * task-1773681272865
10
+ * task-1773681272865, task-1773689755389
12
11
  */
13
12
  import type { FastifyInstance } from 'fastify';
13
+ import type Database from 'better-sqlite3';
14
+ interface TakeoverState {
15
+ agentId: string;
16
+ id: string;
17
+ content: Record<string, unknown>;
18
+ title?: string;
19
+ startedAt: number;
20
+ duration: number;
21
+ transition: string;
22
+ releaseTimer?: ReturnType<typeof setTimeout>;
23
+ }
24
+ /** Exported for server.ts to read/clear if needed during shutdown */
25
+ export declare function getCurrentTakeover(): TakeoverState | null;
26
+ export declare function clearCurrentTakeover(): void;
14
27
  export type CanvasState = 'floor' | 'ambient' | 'thinking' | 'rendering' | 'decision' | 'handoff' | 'urgent' | 'presenting';
15
28
  export interface CanvasStateEntry {
16
29
  state: CanvasState;
@@ -20,17 +33,55 @@ export interface CanvasStateEntry {
20
33
  }
21
34
  /**
22
35
  * Dependencies injected from server.ts.
23
- * Each dep is a narrow interface — no coupling to the full module.
24
36
  */
25
37
  export interface CanvasRouteDeps {
38
+ canvasStateMap: Map<string, CanvasStateEntry>;
26
39
  canvasSlots: {
27
40
  getActive: () => unknown[];
28
41
  getAll: () => unknown[];
29
42
  getStats: () => unknown;
30
43
  };
44
+ agentIdentityColors: Record<string, string>;
45
+ getDb: () => Database.Database;
31
46
  getRecentRejections: () => unknown[];
47
+ /** Expression log for flow-score velocity calculation */
48
+ flowExpressionLog: Array<{
49
+ t: number;
50
+ }>;
32
51
  }
33
52
  export declare const CANVAS_STATES: string[];
34
53
  export declare const SENSOR_VALUES: string[];
54
+ export declare function formatRecency(updatedAt: number): string;
35
55
  export declare function canvasReadRoutes(app: FastifyInstance, deps: CanvasRouteDeps): Promise<void>;
56
+ /**
57
+ * Phase 2 dependencies — heavier state coupling than Phase 1.
58
+ */
59
+ export interface CanvasPhase2Deps {
60
+ eventBus: {
61
+ emit: (event: {
62
+ id: string;
63
+ type: string;
64
+ timestamp: number;
65
+ data: unknown;
66
+ }) => void;
67
+ };
68
+ queueCanvasPushEvent: (event: Record<string, unknown>) => void;
69
+ taskManager: {
70
+ listTasks: (filter: {
71
+ status: string;
72
+ }) => any[];
73
+ };
74
+ getDb: () => any;
75
+ activityRingBuffer: any[];
76
+ activityStreamSubscribers: Map<string, {
77
+ closed: boolean;
78
+ send: (data: string) => void;
79
+ }>;
80
+ }
81
+ /**
82
+ * Phase 2 canvas routes — takeover, attention, activity-stream.
83
+ * task-1773689755389-ux4bbn1lo
84
+ */
85
+ export declare function canvasPhase2Routes(app: FastifyInstance, deps: CanvasPhase2Deps): Promise<void>;
86
+ export {};
36
87
  //# sourceMappingURL=canvas-routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvas-routes.d.ts","sourceRoot":"","sources":["../src/canvas-routes.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAK9C,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,CAAA;AAE3H,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,WAAW,CAAA;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE;QACX,SAAS,EAAE,MAAM,OAAO,EAAE,CAAA;QAC1B,MAAM,EAAE,MAAM,OAAO,EAAE,CAAA;QACvB,QAAQ,EAAE,MAAM,OAAO,CAAA;KACxB,CAAA;IACD,mBAAmB,EAAE,MAAM,OAAO,EAAE,CAAA;CACrC;AAID,eAAO,MAAM,aAAa,UAEzB,CAAA;AACD,eAAO,MAAM,aAAa,UAEzB,CAAA;AAID,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,eAAe,iBAsCjF"}
1
+ {"version":3,"file":"canvas-routes.d.ts","sourceRoot":"","sources":["../src/canvas-routes.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAA;AAE9D,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAqB1C,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAA;CAC7C;AAID,qEAAqE;AACrE,wBAAgB,kBAAkB,yBAA6B;AAC/D,wBAAgB,oBAAoB,SAA6B;AAIjE,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,CAAA;AAE3H,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,WAAW,CAAA;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IAC7C,WAAW,EAAE;QACX,SAAS,EAAE,MAAM,OAAO,EAAE,CAAA;QAC1B,MAAM,EAAE,MAAM,OAAO,EAAE,CAAA;QACvB,QAAQ,EAAE,MAAM,OAAO,CAAA;KACxB,CAAA;IACD,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,KAAK,EAAE,MAAM,QAAQ,CAAC,QAAQ,CAAA;IAC9B,mBAAmB,EAAE,MAAM,OAAO,EAAE,CAAA;IACpC,yDAAyD;IACzD,iBAAiB,EAAE,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACxC;AAID,eAAO,MAAM,aAAa,UAEzB,CAAA;AACD,eAAO,MAAM,aAAa,UAEzB,CAAA;AAID,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMvD;AAID,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,eAAe,iBAiOjF;AAID;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE;QACR,IAAI,EAAE,CAAC,KAAK,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,OAAO,CAAA;SAAE,KAAK,IAAI,CAAA;KACtF,CAAA;IACD,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;IAC9D,WAAW,EAAE;QACX,SAAS,EAAE,CAAC,MAAM,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,KAAK,GAAG,EAAE,CAAA;KACjD,CAAA;IACD,KAAK,EAAE,MAAM,GAAG,CAAA;IAChB,kBAAkB,EAAE,GAAG,EAAE,CAAA;IACzB,yBAAyB,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC,CAAA;CAC1F;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,gBAAgB,iBA6PpF"}
@@ -1,23 +1,98 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright (c) Reflectt AI
3
3
  import { emitActivationEvent } from './activationEvents.js';
4
- // ── Constants (moved from server.ts) ──
4
+ /**
5
+ * Resolve userId for activation event attribution.
6
+ * Priority: ?userId= query param → x-user-id header → 'anonymous'
7
+ *
8
+ * Cloud dashboard should always pass ?userId= or X-User-Id on authenticated
9
+ * canvas requests so events are cohoratable per user.
10
+ * task-1773692468958-k9zkr0hz9
11
+ */
12
+ function resolveUserId(request) {
13
+ const query = request.query;
14
+ if (typeof query.userId === 'string' && query.userId.trim())
15
+ return query.userId.trim();
16
+ const header = request.headers['x-user-id'];
17
+ if (typeof header === 'string' && header.trim())
18
+ return header.trim();
19
+ return 'anonymous';
20
+ }
21
+ let currentTakeover = null;
22
+ /** Exported for server.ts to read/clear if needed during shutdown */
23
+ export function getCurrentTakeover() { return currentTakeover; }
24
+ export function clearCurrentTakeover() { currentTakeover = null; }
25
+ // ── Constants ──
5
26
  export const CANVAS_STATES = [
6
27
  'floor', 'listening', 'thinking', 'rendering', 'ambient', 'decision', 'urgent', 'handoff', 'presenting',
7
28
  ];
8
29
  export const SENSOR_VALUES = [
9
30
  'voice_active', 'screen_share', 'camera', 'typing', 'idle', 'scroll', 'hover', 'focus',
10
31
  ];
32
+ // ── Helpers ──
33
+ export function formatRecency(updatedAt) {
34
+ const diff = Date.now() - updatedAt;
35
+ if (diff < 60_000)
36
+ return 'just now';
37
+ if (diff < 3_600_000)
38
+ return `${Math.floor(diff / 60_000)}m ago`;
39
+ if (diff < 86_400_000)
40
+ return `${Math.floor(diff / 3_600_000)}h ago`;
41
+ return `${Math.floor(diff / 86_400_000)}d ago`;
42
+ }
11
43
  // ── Plugin ──
12
44
  export async function canvasReadRoutes(app, deps) {
45
+ // GET /canvas/presence — all agents as AgentPresence[]
46
+ // Also fires canvas_opened for the visiting user — this is the primary dashboard canvas entry.
47
+ app.get('/canvas/presence', async (request) => {
48
+ const userId = resolveUserId(request);
49
+ emitActivationEvent('canvas_opened', userId).catch(() => { });
50
+ const agents = [];
51
+ for (const [agentId, entry] of deps.canvasStateMap) {
52
+ const presenceState = entry.payload?.presenceState ||
53
+ (entry.state === 'decision' || entry.state === 'urgent' ? 'blocked' :
54
+ entry.state === 'thinking' || entry.state === 'rendering' ? 'working' : 'idle');
55
+ agents.push({
56
+ name: agentId,
57
+ identityColor: deps.agentIdentityColors[agentId] || '#9ca3af',
58
+ state: presenceState,
59
+ activeTask: entry.payload?.activeTask,
60
+ recency: formatRecency(entry.updatedAt),
61
+ attention: entry.payload?.attention,
62
+ });
63
+ }
64
+ return { agents, count: agents.length };
65
+ });
66
+ // GET /canvas/state — current state for all agents (or one)
67
+ app.get('/canvas/state', async (request) => {
68
+ const query = request.query;
69
+ function getLastMessage(agentId) {
70
+ try {
71
+ const db = deps.getDb();
72
+ const row = db.prepare(`SELECT content, timestamp FROM chat_messages WHERE "from" = ? AND "to" IS NULL ORDER BY timestamp DESC LIMIT 1`).get(agentId);
73
+ return row ?? null;
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ }
79
+ if (query.agentId) {
80
+ const entry = deps.canvasStateMap.get(query.agentId);
81
+ const base = entry ?? { state: 'floor', sensors: null, payload: {}, updatedAt: null };
82
+ return { ...base, lastMessage: getLastMessage(query.agentId) };
83
+ }
84
+ const all = {};
85
+ for (const [id, entry] of deps.canvasStateMap) {
86
+ all[id] = { ...entry, lastMessage: getLastMessage(id) };
87
+ }
88
+ return { agents: all, count: deps.canvasStateMap.size };
89
+ });
13
90
  // GET /canvas/states — valid state + sensor values (discovery)
91
+ // Secondary canvas entry path — also fires canvas_opened.
14
92
  app.get('/canvas/states', async (request) => {
15
- const query = request.query;
16
- const userId = typeof query.userId === 'string' && query.userId.trim()
17
- ? query.userId.trim()
18
- : 'anonymous';
93
+ const userId = resolveUserId(request);
19
94
  emitActivationEvent('canvas_opened', userId).catch(() => { });
20
- return ({
95
+ return {
21
96
  states: CANVAS_STATES,
22
97
  sensors: SENSOR_VALUES,
23
98
  schema: {
@@ -26,7 +101,7 @@ export async function canvasReadRoutes(app, deps) {
26
101
  agentId: 'required — which agent is driving the canvas',
27
102
  payload: 'optional — text, media, decision, agents, summary',
28
103
  },
29
- });
104
+ };
30
105
  });
31
106
  // GET /canvas/slots — current active slots
32
107
  app.get('/canvas/slots', async () => {
@@ -39,9 +114,349 @@ export async function canvasReadRoutes(app, deps) {
39
114
  app.get('/canvas/slots/all', async () => {
40
115
  return { slots: deps.canvasSlots.getAll() };
41
116
  });
117
+ // GET /canvas/flow-score — real-time team flow metric (0–1)
118
+ app.get('/canvas/flow-score', async () => {
119
+ const now = Date.now();
120
+ const STALE_MS = 10 * 60 * 1000;
121
+ const WINDOW_5M = 5 * 60 * 1000;
122
+ const activeEntries = [...deps.canvasStateMap.entries()].filter(([, e]) => now - e.updatedAt < STALE_MS);
123
+ const agentScore = Math.min(1.0, activeEntries.length / 4);
124
+ const HIGH_FLOW_STATES = new Set(['working', 'rendering', 'thinking', 'decision']);
125
+ const flowingCount = activeEntries.filter(([, e]) => HIGH_FLOW_STATES.has(e.state)).length;
126
+ const velocityFromStates = activeEntries.length > 0 ? flowingCount / activeEntries.length : 0;
127
+ const recent = deps.flowExpressionLog.filter(e => e.t > now - WINDOW_5M).length;
128
+ const expressionScore = Math.min(1.0, recent / 20);
129
+ const hour = new Date(now).getHours();
130
+ const timeScore = hour >= 9 && hour <= 22 ? 1.0 : hour >= 6 && hour <= 8 ? 0.5 : 0.2;
131
+ const score = Math.round((agentScore * 0.30 +
132
+ velocityFromStates * 0.35 +
133
+ expressionScore * 0.25 +
134
+ timeScore * 0.10) * 100) / 100;
135
+ const label = score >= 0.8 ? 'surge' :
136
+ score >= 0.6 ? 'flow' :
137
+ score >= 0.4 ? 'grinding' :
138
+ score >= 0.2 ? 'quiet' : 'idle';
139
+ return {
140
+ score,
141
+ label,
142
+ factors: {
143
+ agents: Math.round(agentScore * 100) / 100,
144
+ velocity: Math.round(velocityFromStates * 100) / 100,
145
+ expressions: Math.round(expressionScore * 100) / 100,
146
+ timeOfDay: timeScore,
147
+ },
148
+ activeAgents: activeEntries.length,
149
+ expressionsLast5m: recent,
150
+ };
151
+ });
152
+ // GET /canvas/team/mood — derived collective mood of all active agents
153
+ app.get('/canvas/team/mood', async () => {
154
+ const now = Date.now();
155
+ const STALE_MS = 10 * 60 * 1000;
156
+ const states = [];
157
+ const agentNames = [];
158
+ for (const [agentId, entry] of deps.canvasStateMap) {
159
+ if (now - entry.updatedAt > STALE_MS)
160
+ continue;
161
+ states.push(entry.state);
162
+ agentNames.push(agentId);
163
+ }
164
+ const activeCount = states.length;
165
+ const urgentCount = states.filter(s => s === 'urgent').length;
166
+ const decisionCount = states.filter(s => s === 'decision').length;
167
+ const renderingCount = states.filter(s => s === 'rendering').length;
168
+ const thinkingCount = states.filter(s => s === 'thinking').length;
169
+ const idleCount = states.filter(s => s === 'floor' || s === 'ambient').length;
170
+ const workingCount = activeCount - idleCount;
171
+ let blockedTasks = 0;
172
+ let pendingDecisions = 0;
173
+ try {
174
+ const db = deps.getDb();
175
+ const row = db.prepare(`SELECT COUNT(*) as n FROM tasks WHERE status = 'blocked'`).get();
176
+ blockedTasks = row?.n ?? 0;
177
+ const drow = db.prepare(`SELECT COUNT(*) as n FROM tasks WHERE status = 'doing' AND priority IN ('P0','P1')`).get();
178
+ pendingDecisions = decisionCount + (drow?.n ?? 0);
179
+ }
180
+ catch { /* non-fatal */ }
181
+ const tensionRaw = (urgentCount * 0.35) +
182
+ (decisionCount * 0.25) +
183
+ (Math.min(blockedTasks, 5) * 0.08) +
184
+ (activeCount > 0 ? (1 - idleCount / activeCount) * 0.10 : 0);
185
+ const tension = Math.min(1.0, tensionRaw);
186
+ const teamRhythm = urgentCount > 0 ? 'surge' :
187
+ activeCount === 0 || idleCount === activeCount ? 'quiet' :
188
+ decisionCount > 0 && workingCount > 0 ? 'tense' :
189
+ renderingCount + thinkingCount >= Math.max(1, activeCount * 0.6) ? 'flow' :
190
+ 'grinding';
191
+ const dominantState = urgentCount > 0 ? 'urgent' :
192
+ decisionCount > 0 ? 'decision' :
193
+ renderingCount > 0 ? 'rendering' :
194
+ thinkingCount > 0 ? 'thinking' :
195
+ workingCount > 0 ? 'working' :
196
+ 'idle';
197
+ const ambientPulse = teamRhythm === 'surge' ? 'fast' :
198
+ teamRhythm === 'flow' ? 'normal' :
199
+ teamRhythm === 'tense' ? 'slow' :
200
+ 'slow';
201
+ let dominantColor = '#60a5fa';
202
+ for (const [agentId, entry] of deps.canvasStateMap) {
203
+ if (entry.state !== 'floor' && entry.state !== 'ambient') {
204
+ dominantColor = deps.agentIdentityColors[agentId] ?? dominantColor;
205
+ break;
206
+ }
207
+ }
208
+ return {
209
+ mood: {
210
+ teamRhythm,
211
+ dominantState,
212
+ tension,
213
+ ambientPulse,
214
+ dominantColor,
215
+ activeAgents: agentNames,
216
+ counts: { active: activeCount, urgent: urgentCount, rendering: renderingCount, thinking: thinkingCount, decision: decisionCount, idle: idleCount, blocked: blockedTasks },
217
+ },
218
+ generated_at: new Date(now).toISOString(),
219
+ };
220
+ });
42
221
  // GET /canvas/rejections — recent render rejections (debug)
43
222
  app.get('/canvas/rejections', async () => {
44
223
  return { rejections: deps.getRecentRejections() };
45
224
  });
46
225
  }
226
+ /**
227
+ * Phase 2 canvas routes — takeover, attention, activity-stream.
228
+ * task-1773689755389-ux4bbn1lo
229
+ */
230
+ export async function canvasPhase2Routes(app, deps) {
231
+ // ── Takeover ──
232
+ // POST /canvas/takeover — agent claims full screen
233
+ app.post('/canvas/takeover', async (request, reply) => {
234
+ const body = request.body;
235
+ const agentId = typeof body.agentId === 'string' ? body.agentId.trim().toLowerCase() : '';
236
+ if (!agentId) {
237
+ reply.status(400);
238
+ return { success: false, message: 'agentId is required' };
239
+ }
240
+ const content = body.content;
241
+ if (!content || typeof content !== 'object') {
242
+ reply.status(400);
243
+ return { success: false, message: 'content object is required' };
244
+ }
245
+ // Sanitize content fields
246
+ const safeContent = {};
247
+ if (typeof content.html === 'string')
248
+ safeContent.html = content.html.slice(0, 50_000);
249
+ if (typeof content.markdown === 'string')
250
+ safeContent.markdown = content.markdown.slice(0, 20_000);
251
+ if (typeof content.code === 'string')
252
+ safeContent.code = content.code.slice(0, 20_000);
253
+ if (typeof content.language === 'string')
254
+ safeContent.language = content.language.slice(0, 30);
255
+ if (typeof content.image === 'string')
256
+ safeContent.image = content.image.slice(0, 2000);
257
+ if (typeof content.svg === 'string')
258
+ safeContent.svg = content.svg.slice(0, 100_000);
259
+ if (typeof content.video === 'string')
260
+ safeContent.video = content.video.slice(0, 2000);
261
+ if (typeof content.threejs === 'string')
262
+ safeContent.threejs = content.threejs.slice(0, 100_000);
263
+ if (typeof content.title === 'string')
264
+ safeContent.title = content.title.slice(0, 200);
265
+ const duration = typeof body.duration === 'number' && body.duration > 0
266
+ ? Math.min(body.duration, 120_000) : 30_000;
267
+ const transition = typeof body.transition === 'string' && ['fade', 'slide', 'instant'].includes(body.transition)
268
+ ? body.transition : 'fade';
269
+ const title = typeof body.title === 'string' ? body.title.slice(0, 200) : undefined;
270
+ // Release previous takeover if any
271
+ if (currentTakeover?.releaseTimer)
272
+ clearTimeout(currentTakeover.releaseTimer);
273
+ const id = `takeover-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
274
+ const now = Date.now();
275
+ currentTakeover = { agentId, id, content: safeContent, title, startedAt: now, duration, transition };
276
+ // Auto-release after duration
277
+ currentTakeover.releaseTimer = setTimeout(() => {
278
+ if (currentTakeover?.id === id) {
279
+ deps.eventBus.emit({
280
+ id: `takeover-release-${Date.now()}`,
281
+ type: 'canvas_takeover',
282
+ timestamp: Date.now(),
283
+ data: { action: 'release', agentId, transition: 'fade', reason: 'timeout' },
284
+ });
285
+ currentTakeover = null;
286
+ }
287
+ }, duration);
288
+ // Emit takeover event
289
+ const takeoverEventData = { action: 'claim', agentId, content: safeContent, title, duration, transition };
290
+ deps.eventBus.emit({
291
+ id,
292
+ type: 'canvas_takeover',
293
+ timestamp: now,
294
+ data: takeoverEventData,
295
+ });
296
+ // Also queue for cloud relay
297
+ deps.queueCanvasPushEvent({ type: 'canvas_takeover', ...takeoverEventData, t: now });
298
+ // Track canvas_first_action activation event
299
+ emitActivationEvent('canvas_first_action', agentId, { action: 'canvas_takeover' }).catch(() => { });
300
+ return { success: true, id, expiresAt: now + duration };
301
+ });
302
+ // POST /canvas/takeover/release — agent releases takeover
303
+ app.post('/canvas/takeover/release', async (request, reply) => {
304
+ const body = request.body;
305
+ const agentId = typeof body.agentId === 'string' ? body.agentId.trim().toLowerCase() : '';
306
+ if (!agentId) {
307
+ reply.status(400);
308
+ return { success: false, message: 'agentId is required' };
309
+ }
310
+ if (!currentTakeover || currentTakeover.agentId !== agentId) {
311
+ return { success: true, message: 'no active takeover by this agent' };
312
+ }
313
+ if (currentTakeover.releaseTimer)
314
+ clearTimeout(currentTakeover.releaseTimer);
315
+ const transition = typeof body.transition === 'string' && ['fade', 'slide', 'instant'].includes(body.transition)
316
+ ? body.transition : 'fade';
317
+ const releaseNow = Date.now();
318
+ const releaseData = { action: 'release', agentId, transition, reason: 'agent_released' };
319
+ deps.eventBus.emit({
320
+ id: `takeover-release-${releaseNow}`,
321
+ type: 'canvas_takeover',
322
+ timestamp: releaseNow,
323
+ data: releaseData,
324
+ });
325
+ deps.queueCanvasPushEvent({ type: 'canvas_takeover', ...releaseData, t: releaseNow });
326
+ currentTakeover = null;
327
+ return { success: true };
328
+ });
329
+ // GET /canvas/takeover — check current takeover state
330
+ app.get('/canvas/takeover', async () => {
331
+ if (!currentTakeover)
332
+ return { active: false };
333
+ return {
334
+ active: true,
335
+ agentId: currentTakeover.agentId,
336
+ id: currentTakeover.id,
337
+ title: currentTakeover.title,
338
+ content: currentTakeover.content,
339
+ startedAt: currentTakeover.startedAt,
340
+ expiresAt: currentTakeover.startedAt + currentTakeover.duration,
341
+ remainingMs: Math.max(0, (currentTakeover.startedAt + currentTakeover.duration) - Date.now()),
342
+ };
343
+ });
344
+ // ── Attention ──
345
+ // GET /canvas/attention — highest-priority actionable item
346
+ app.get('/canvas/attention', async (request) => {
347
+ const query = request.query;
348
+ const viewer = typeof query.viewer === 'string' ? query.viewer.trim() : 'human';
349
+ const notifModule = await import('./agent-notifications.js');
350
+ const notifResult = notifModule.getNotifications(deps.getDb(), viewer, { status: 'pending', limit: 1 });
351
+ const topNotif = notifResult.notifications[0];
352
+ const validatingTasks = deps.taskManager.listTasks({ status: 'validating' });
353
+ const reviewable = validatingTasks.find((t) => t.assignee !== viewer && t.reviewers?.includes(viewer)) ?? validatingTasks[0];
354
+ const blockedTasks = deps.taskManager.listTasks({ status: 'blocked' });
355
+ const viewerBlocked = blockedTasks.find((t) => t.assignee === viewer);
356
+ let item = null;
357
+ if (topNotif && (topNotif.priority === 'critical' || topNotif.priority === 'high')) {
358
+ item = {
359
+ source: 'notification',
360
+ priority: topNotif.priority,
361
+ title: topNotif.title,
362
+ detail: topNotif.body ?? undefined,
363
+ taskId: topNotif.task_id ?? undefined,
364
+ agentId: topNotif.source_agent ?? undefined,
365
+ actionLabel: topNotif.type === 'review' ? 'Review' : 'Acknowledge',
366
+ actionType: 'ack',
367
+ notificationId: topNotif.id,
368
+ };
369
+ }
370
+ else if (reviewable) {
371
+ const t = reviewable;
372
+ item = {
373
+ source: 'review',
374
+ priority: 'high',
375
+ title: t.title ?? 'Task needs review',
376
+ detail: `Assigned to ${t.assignee ?? 'unassigned'}`,
377
+ taskId: t.id,
378
+ agentId: t.assignee ?? undefined,
379
+ actionLabel: 'Review',
380
+ actionType: 'review',
381
+ };
382
+ }
383
+ else if (viewerBlocked) {
384
+ const t = viewerBlocked;
385
+ item = {
386
+ source: 'blocked',
387
+ priority: 'medium',
388
+ title: t.title ?? 'Task is blocked',
389
+ detail: t.metadata?.blocked_reason ?? 'Needs attention',
390
+ taskId: t.id,
391
+ agentId: t.assignee ?? undefined,
392
+ actionLabel: 'Unblock',
393
+ actionType: 'unblock',
394
+ };
395
+ }
396
+ else if (topNotif) {
397
+ item = {
398
+ source: 'notification',
399
+ priority: topNotif.priority ?? 'low',
400
+ title: topNotif.title,
401
+ detail: topNotif.body ?? undefined,
402
+ taskId: topNotif.task_id ?? undefined,
403
+ agentId: topNotif.source_agent ?? undefined,
404
+ actionLabel: 'View',
405
+ actionType: 'ack',
406
+ notificationId: topNotif.id,
407
+ };
408
+ }
409
+ return { item, pendingNotifications: notifResult.total };
410
+ });
411
+ // ── Activity Stream ──
412
+ // GET /canvas/activity-stream — SSE stream with backfill
413
+ app.get('/canvas/activity-stream', async (request, reply) => {
414
+ reply.raw.setHeader('Content-Type', 'text/event-stream');
415
+ reply.raw.setHeader('Cache-Control', 'no-cache');
416
+ reply.raw.setHeader('Connection', 'keep-alive');
417
+ reply.raw.setHeader('X-Accel-Buffering', 'no');
418
+ reply.raw.flushHeaders?.();
419
+ let closed = false;
420
+ const subId = `asub-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
421
+ // Replay backfill — last 20 events with stagger hint for animated replay
422
+ const backfill = deps.activityRingBuffer.slice(-20);
423
+ for (let i = 0; i < backfill.length; i++) {
424
+ if (closed)
425
+ break;
426
+ try {
427
+ const entry = { ...backfill[i], _backfill: true, _staggerMs: i * 50 };
428
+ reply.raw.write(`event: backfill\ndata: ${JSON.stringify(entry)}\n\n`);
429
+ }
430
+ catch {
431
+ break;
432
+ }
433
+ }
434
+ // Signal backfill complete
435
+ if (!closed) {
436
+ try {
437
+ reply.raw.write(`event: backfill_done\ndata: {}\n\n`);
438
+ }
439
+ catch { /* */ }
440
+ }
441
+ // Register for live events via shared subscriber map
442
+ deps.activityStreamSubscribers.set(subId, {
443
+ closed: false,
444
+ send: (data) => {
445
+ if (closed)
446
+ return;
447
+ try {
448
+ reply.raw.write(`event: activity\ndata: ${data}\n\n`);
449
+ }
450
+ catch {
451
+ closed = true;
452
+ }
453
+ },
454
+ });
455
+ request.raw.on('close', () => {
456
+ closed = true;
457
+ deps.activityStreamSubscribers.delete(subId);
458
+ });
459
+ return new Promise(() => { });
460
+ });
461
+ }
47
462
  //# sourceMappingURL=canvas-routes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvas-routes.js","sourceRoot":"","sources":["../src/canvas-routes.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,4BAA4B;AAgB5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AA0B3D,yCAAyC;AAEzC,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY;CACxG,CAAA;AACD,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO;CACvF,CAAA;AAED,eAAe;AAEf,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAoB,EAAE,IAAqB;IAEhF,+DAA+D;IAC/D,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAgC,CAAA;QACtD,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE;YACpE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE;YACrB,CAAC,CAAC,WAAW,CAAA;QACf,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAC5D,OAAO,CAAC;YACR,MAAM,EAAE,aAAa;YACrB,OAAO,EAAE,aAAa;YACtB,MAAM,EAAE;gBACN,KAAK,EAAE,kFAAkF;gBACzF,OAAO,EAAE,oEAAoE;gBAC7E,OAAO,EAAE,8CAA8C;gBACvD,OAAO,EAAE,mDAAmD;aAC7D;SACF,CAAC,CAAA;IACF,CAAC,CAAC,CAAA;IAEF,2CAA2C;IAC3C,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;QAClC,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE;YACnC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE;SACnC,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,4DAA4D;IAC5D,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;QACtC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAA;IAC7C,CAAC,CAAC,CAAA;IAEF,4DAA4D;IAC5D,GAAG,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;QACvC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAA;IACnD,CAAC,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"canvas-routes.js","sourceRoot":"","sources":["../src/canvas-routes.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,4BAA4B;AAiB5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAE3D;;;;;;;GAOG;AACH,SAAS,aAAa,CAAC,OAAuB;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAgC,CAAA;IACtD,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE;QAAE,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;IACvF,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IAC3C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;IACrE,OAAO,WAAW,CAAA;AACpB,CAAC;AAeD,IAAI,eAAe,GAAyB,IAAI,CAAA;AAEhD,qEAAqE;AACrE,MAAM,UAAU,kBAAkB,KAAK,OAAO,eAAe,CAAA,CAAC,CAAC;AAC/D,MAAM,UAAU,oBAAoB,KAAK,eAAe,GAAG,IAAI,CAAA,CAAC,CAAC;AA8BjE,kBAAkB;AAElB,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY;CACxG,CAAA;AACD,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO;CACvF,CAAA;AAED,gBAAgB;AAEhB,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;IACnC,IAAI,IAAI,GAAG,MAAM;QAAE,OAAO,UAAU,CAAA;IACpC,IAAI,IAAI,GAAG,SAAS;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAA;IAChE,IAAI,IAAI,GAAG,UAAU;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,OAAO,CAAA;IACpE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC,OAAO,CAAA;AAChD,CAAC;AAED,eAAe;AAEf,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAoB,EAAE,IAAqB;IAEhF,uDAAuD;IACvD,+FAA+F;IAC/F,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QACrC,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAC5D,MAAM,MAAM,GAOP,EAAE,CAAA;QAEP,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACnD,MAAM,aAAa,GAChB,KAAK,CAAC,OAAe,EAAE,aAAa;gBACrC,CAAC,KAAK,CAAC,KAAK,KAAK,UAAU,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;oBACpE,KAAK,CAAC,KAAK,KAAK,UAAU,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;YAElF,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,OAAO;gBACb,aAAa,EAAE,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,SAAS;gBAC7D,KAAK,EAAE,aAAa;gBACpB,UAAU,EAAG,KAAK,CAAC,OAAe,EAAE,UAAU;gBAC9C,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC;gBACvC,SAAS,EAAG,KAAK,CAAC,OAAe,EAAE,SAAS;aAC7C,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,4DAA4D;IAC5D,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAA6B,CAAA;QAEnD,SAAS,cAAc,CAAC,OAAe;YACrC,IAAI,CAAC;gBACH,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;gBACvB,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CACpB,gHAAgH,CACjH,CAAC,GAAG,CAAC,OAAO,CAAuD,CAAA;gBACpE,OAAO,GAAG,IAAI,IAAI,CAAA;YACpB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACpD,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;YACrF,OAAO,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAA;QAChE,CAAC;QACD,MAAM,GAAG,GAA4B,EAAE,CAAA;QACvC,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YAC9C,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE,CAAC,EAAE,CAAA;QACzD,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAA;IACzD,CAAC,CAAC,CAAA;IAEF,+DAA+D;IAC/D,0DAA0D;IAC1D,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QACrC,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAC5D,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,OAAO,EAAE,aAAa;YACtB,MAAM,EAAE;gBACN,KAAK,EAAE,kFAAkF;gBACzF,OAAO,EAAE,oEAAoE;gBAC7E,OAAO,EAAE,8CAA8C;gBACvD,OAAO,EAAE,mDAAmD;aAC7D;SACF,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,2CAA2C;IAC3C,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;QAClC,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE;YACnC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE;SACnC,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,4DAA4D;IAC5D,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;QACtC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAA;IAC7C,CAAC,CAAC,CAAA;IAEF,4DAA4D;IAC5D,GAAG,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;QAC/B,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA;QAE/B,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAA;QACxG,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAE1D,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAA;QAClF,MAAM,YAAY,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAA;QAC1F,MAAM,kBAAkB,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QAE7F,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,SAAS,CAAC,CAAC,MAAM,CAAA;QAC/E,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC,CAAA;QAElD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;QACrC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;QAEpF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CACvB,UAAU,GAAW,IAAI;YACzB,kBAAkB,GAAG,IAAI;YACzB,eAAe,GAAM,IAAI;YACzB,SAAS,GAAY,IAAI,CAC1B,GAAG,GAAG,CAAC,GAAG,GAAG,CAAA;QAEd,MAAM,KAAK,GACT,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YACxB,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBACvB,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;oBAC3B,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAA;QAEjC,OAAO;YACL,KAAK;YACL,KAAK;YACL,OAAO,EAAE;gBACP,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG;gBAC1C,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,kBAAkB,GAAG,GAAG,CAAC,GAAG,GAAG;gBACpD,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,GAAG,CAAC,GAAG,GAAG;gBACpD,SAAS,EAAE,SAAS;aACrB;YACD,YAAY,EAAE,aAAa,CAAC,MAAM;YAClC,iBAAiB,EAAE,MAAM;SAC1B,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,uEAAuE;IACvE,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;QAE/B,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,MAAM,UAAU,GAAa,EAAE,CAAA;QAE/B,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACnD,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,GAAG,QAAQ;gBAAE,SAAQ;YAC9C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YACxB,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC1B,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAA;QACjC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAA;QAC7D,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,MAAM,CAAA;QACjE,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,MAAM,CAAA;QACnE,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,MAAM,CAAA;QACjE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,MAAM,CAAA;QAC7E,MAAM,YAAY,GAAG,WAAW,GAAG,SAAS,CAAA;QAE5C,IAAI,YAAY,GAAG,CAAC,CAAA;QACpB,IAAI,gBAAgB,GAAG,CAAC,CAAA;QACxB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;YACvB,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,0DAA0D,CAAC,CAAC,GAAG,EAAmB,CAAA;YACzG,YAAY,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;YAC1B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,oFAAoF,CAAC,CAAC,GAAG,EAAmB,CAAA;YACpI,gBAAgB,GAAG,aAAa,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;QACnD,CAAC;QAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;QAE3B,MAAM,UAAU,GACd,CAAC,WAAW,GAAG,IAAI,CAAC;YACpB,CAAC,aAAa,GAAG,IAAI,CAAC;YACtB,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;YAClC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QAEzC,MAAM,UAAU,GACd,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAC3B,WAAW,KAAK,CAAC,IAAI,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBAC1D,aAAa,GAAG,CAAC,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;oBACjD,cAAc,GAAG,aAAa,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;wBAC3E,UAAU,CAAA;QAEZ,MAAM,aAAa,GACjB,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC5B,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;gBAChC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;oBAClC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;wBAChC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;4BAC9B,MAAM,CAAA;QAER,MAAM,YAAY,GAChB,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACjC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBAClC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;oBACjC,MAAM,CAAA;QAER,IAAI,aAAa,GAAG,SAAS,CAAA;QAC7B,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACnD,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBACzD,aAAa,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,aAAa,CAAA;gBAClE,MAAK;YACP,CAAC;QACH,CAAC;QAED,OAAO;YACL,IAAI,EAAE;gBACJ,UAAU;gBACV,aAAa;gBACb,OAAO;gBACP,YAAY;gBACZ,aAAa;gBACb,YAAY,EAAE,UAAU;gBACxB,MAAM,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE;aAC1K;YACD,YAAY,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;SAC1C,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,4DAA4D;IAC5D,GAAG,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;QACvC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAA;IACnD,CAAC,CAAC,CAAA;AACJ,CAAC;AAoBD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,GAAoB,EAAE,IAAsB;IAEnF,iBAAiB;IAEjB,mDAAmD;IACnD,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACpD,MAAM,IAAI,GAAG,OAAO,CAAC,IAA+B,CAAA;QACpD,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACzF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAA;QAC3D,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAA8C,CAAA;QACnE,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC5C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAA;QAClE,CAAC;QAED,0BAA0B;QAC1B,MAAM,WAAW,GAA4B,EAAE,CAAA;QAC/C,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ;YAAE,WAAW,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;QACtF,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAAE,WAAW,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;QAClG,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ;YAAE,WAAW,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;QACtF,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAAE,WAAW,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAC9F,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ;YAAE,WAAW,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;QACvF,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ;YAAE,WAAW,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;QACpF,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ;YAAE,WAAW,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;QACvF,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ;YAAE,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;QAChG,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ;YAAE,WAAW,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAEtF,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC;YACrE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;QAC7C,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC;YAC9G,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAA;QAC5B,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAEnF,mCAAmC;QACnC,IAAI,eAAe,EAAE,YAAY;YAAE,YAAY,CAAC,eAAe,CAAC,YAAY,CAAC,CAAA;QAE7E,MAAM,EAAE,GAAG,YAAY,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;QAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEtB,eAAe,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAA;QAEpG,8BAA8B;QAC9B,eAAe,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;YAC7C,IAAI,eAAe,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC/B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACjB,EAAE,EAAE,oBAAoB,IAAI,CAAC,GAAG,EAAE,EAAE;oBACpC,IAAI,EAAE,iBAA0B;oBAChC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;oBACrB,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE;iBAC5E,CAAC,CAAA;gBACF,eAAe,GAAG,IAAI,CAAA;YACxB,CAAC;QACH,CAAC,EAAE,QAAQ,CAAC,CAAA;QAEZ,sBAAsB;QACtB,MAAM,iBAAiB,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAA;QACzG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,EAAE;YACF,IAAI,EAAE,iBAA0B;YAChC,SAAS,EAAE,GAAG;YACd,IAAI,EAAE,iBAAiB;SACxB,CAAC,CAAA;QAEF,6BAA6B;QAC7B,IAAI,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAA;QAEpF,6CAA6C;QAC7C,mBAAmB,CAAC,qBAAqB,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAElG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,GAAG,QAAQ,EAAE,CAAA;IACzD,CAAC,CAAC,CAAA;IAEF,0DAA0D;IAC1D,GAAG,CAAC,IAAI,CAAC,0BAA0B,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,IAA+B,CAAA;QACpD,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACzF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAA;QAC3D,CAAC;QAED,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC5D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,kCAAkC,EAAE,CAAA;QACvE,CAAC;QAED,IAAI,eAAe,CAAC,YAAY;YAAE,YAAY,CAAC,eAAe,CAAC,YAAY,CAAC,CAAA;QAC5E,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC;YAC9G,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAA;QAE5B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC7B,MAAM,WAAW,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAA;QACxF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,EAAE,EAAE,oBAAoB,UAAU,EAAE;YACpC,IAAI,EAAE,iBAA0B;YAChC,SAAS,EAAE,UAAU;YACrB,IAAI,EAAE,WAAW;SAClB,CAAC,CAAA;QACF,IAAI,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,WAAW,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAA;QAErF,eAAe,GAAG,IAAI,CAAA;QACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEF,sDAAsD;IACtD,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QACrC,IAAI,CAAC,eAAe;YAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;QAC9C,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,EAAE,EAAE,eAAe,CAAC,EAAE;YACtB,KAAK,EAAE,eAAe,CAAC,KAAK;YAC5B,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,SAAS,EAAE,eAAe,CAAC,SAAS;YACpC,SAAS,EAAE,eAAe,CAAC,SAAS,GAAG,eAAe,CAAC,QAAQ;YAC/D,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,GAAG,eAAe,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;SAC9F,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,kBAAkB;IAElB,2DAA2D;IAC3D,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,KAA+B,CAAA;QACrD,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;QAE/E,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAA;QAC5D,MAAM,WAAW,GAAG,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;QACvG,MAAM,QAAQ,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;QAE7C,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAA;QAC5E,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CACjD,CAAC,CAAC,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,CACvD,IAAI,eAAe,CAAC,CAAC,CAAC,CAAA;QAEvB,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;QACtE,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAA;QAe1E,IAAI,IAAI,GAAyB,IAAI,CAAA;QAErC,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,KAAK,UAAU,IAAI,QAAQ,CAAC,QAAQ,KAAK,MAAM,CAAC,EAAE,CAAC;YACnF,IAAI,GAAG;gBACL,MAAM,EAAE,cAAc;gBACtB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,MAAM,EAAE,QAAQ,CAAC,IAAI,IAAI,SAAS;gBAClC,MAAM,EAAE,QAAQ,CAAC,OAAO,IAAI,SAAS;gBACrC,OAAO,EAAE,QAAQ,CAAC,YAAY,IAAI,SAAS;gBAC3C,WAAW,EAAE,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa;gBAClE,UAAU,EAAE,KAAK;gBACjB,cAAc,EAAE,QAAQ,CAAC,EAAE;aAC5B,CAAA;QACH,CAAC;aAAM,IAAI,UAAU,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,UAAiB,CAAA;YAC3B,IAAI,GAAG;gBACL,MAAM,EAAE,QAAQ;gBAChB,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,mBAAmB;gBACrC,MAAM,EAAE,eAAe,CAAC,CAAC,QAAQ,IAAI,YAAY,EAAE;gBACnD,MAAM,EAAE,CAAC,CAAC,EAAE;gBACZ,OAAO,EAAE,CAAC,CAAC,QAAQ,IAAI,SAAS;gBAChC,WAAW,EAAE,QAAQ;gBACrB,UAAU,EAAE,QAAQ;aACrB,CAAA;QACH,CAAC;aAAM,IAAI,aAAa,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,aAAoB,CAAA;YAC9B,IAAI,GAAG;gBACL,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,iBAAiB;gBACnC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,cAAc,IAAI,iBAAiB;gBACvD,MAAM,EAAE,CAAC,CAAC,EAAE;gBACZ,OAAO,EAAE,CAAC,CAAC,QAAQ,IAAI,SAAS;gBAChC,WAAW,EAAE,SAAS;gBACtB,UAAU,EAAE,SAAS;aACtB,CAAA;QACH,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACpB,IAAI,GAAG;gBACL,MAAM,EAAE,cAAc;gBACtB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,KAAK;gBACpC,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,MAAM,EAAE,QAAQ,CAAC,IAAI,IAAI,SAAS;gBAClC,MAAM,EAAE,QAAQ,CAAC,OAAO,IAAI,SAAS;gBACrC,OAAO,EAAE,QAAQ,CAAC,YAAY,IAAI,SAAS;gBAC3C,WAAW,EAAE,MAAM;gBACnB,UAAU,EAAE,KAAK;gBACjB,cAAc,EAAE,QAAQ,CAAC,EAAE;aAC5B,CAAA;QACH,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,CAAC,KAAK,EAAE,CAAA;IAC1D,CAAC,CAAC,CAAA;IAEF,wBAAwB;IAExB,yDAAyD;IACzD,GAAG,CAAC,GAAG,CAAC,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC1D,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAA;QACxD,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;QAChD,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;QAC/C,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAA;QAC9C,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,CAAA;QAE1B,IAAI,MAAM,GAAG,KAAK,CAAA;QAClB,MAAM,KAAK,GAAG,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;QAE5E,yEAAyE;QACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAA;QACnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,MAAM;gBAAE,MAAK;YACjB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAA;gBACrE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,0BAA0B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YACxE,CAAC;YAAC,MAAM,CAAC;gBAAC,MAAK;YAAC,CAAC;QACnB,CAAC;QAED,2BAA2B;QAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC;gBAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;QAC/E,CAAC;QAED,qDAAqD;QACrD,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,KAAK,EAAE;YACxC,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE;gBACrB,IAAI,MAAM;oBAAE,OAAM;gBAClB,IAAI,CAAC;oBAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,0BAA0B,IAAI,MAAM,CAAC,CAAA;gBAAC,CAAC;gBAAC,MAAM,CAAC;oBAAC,MAAM,GAAG,IAAI,CAAA;gBAAC,CAAC;YACvF,CAAC;SACF,CAAC,CAAA;QAEF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAC3B,MAAM,GAAG,IAAI,CAAA;YACb,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC9C,CAAC,CAAC,CAAA;QAEF,OAAO,IAAI,OAAO,CAAO,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -67,7 +67,7 @@ declare class SlotManager {
67
67
  slots: {
68
68
  slot: SlotType;
69
69
  agent: string;
70
- content_type: "chat.message" | "text.brief" | "text.list" | "metric.single" | "metric.delta" | "task.card" | "code.diff.summary" | "state.badge" | "cta.button" | "evidence.link" | "timeline.event";
70
+ content_type: "chat.message" | "text.brief" | "text.list" | "metric.single" | "metric.delta" | "task.card" | "code.diff.summary" | "state.badge" | "cta.button" | "evidence.link" | "timeline.event" | "rich";
71
71
  priority: "normal" | "background" | "dominant";
72
72
  age_ms: number;
73
73
  version: number;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Canvas Takeover Routes — extracted from server.ts
3
+ *
4
+ * When an agent has something to show, they take over the canvas.
5
+ * Orbs fade to ambient. The agent's content IS the canvas.
6
+ * Release returns to constellation view.
7
+ *
8
+ * task-1773689755389 (Phase 2 extraction)
9
+ */
10
+ import type { FastifyInstance } from 'fastify';
11
+ import { eventBus as _eventBusInstance } from './events.js';
12
+ type EventBus = typeof _eventBusInstance;
13
+ export interface TakeoverDeps {
14
+ eventBus: EventBus;
15
+ queueCanvasPushEvent: (event: Record<string, unknown>) => void;
16
+ }
17
+ export declare function canvasTakeoverRoutes(app: FastifyInstance, deps: TakeoverDeps): Promise<void>;
18
+ export {};
19
+ //# sourceMappingURL=canvas-takeover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas-takeover.d.ts","sourceRoot":"","sources":["../src/canvas-takeover.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAG3D,KAAK,QAAQ,GAAG,OAAO,iBAAiB,CAAA;AAexC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,QAAQ,CAAA;IAClB,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;CAC/D;AAQD,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,YAAY,iBAuHlF"}