@stackmemoryai/stackmemory 0.3.7 → 0.3.8

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 (190) hide show
  1. package/dist/agents/core/agent-task-manager.js +5 -5
  2. package/dist/agents/core/agent-task-manager.js.map +2 -2
  3. package/dist/agents/verifiers/base-verifier.js +2 -2
  4. package/dist/agents/verifiers/base-verifier.js.map +2 -2
  5. package/dist/cli/claude-sm.js +0 -11
  6. package/dist/cli/claude-sm.js.map +2 -2
  7. package/dist/cli/codex-sm.js +0 -11
  8. package/dist/cli/codex-sm.js.map +2 -2
  9. package/dist/cli/commands/chromadb.js +64 -34
  10. package/dist/cli/commands/chromadb.js.map +2 -2
  11. package/dist/cli/commands/clear.js +9 -13
  12. package/dist/cli/commands/clear.js.map +2 -2
  13. package/dist/cli/commands/config.js +43 -33
  14. package/dist/cli/commands/config.js.map +2 -2
  15. package/dist/cli/commands/context.js.map +2 -2
  16. package/dist/cli/commands/dashboard.js +41 -13
  17. package/dist/cli/commands/dashboard.js.map +2 -2
  18. package/dist/cli/commands/gc.js +69 -20
  19. package/dist/cli/commands/gc.js.map +2 -2
  20. package/dist/cli/commands/handoff.js.map +2 -2
  21. package/dist/cli/commands/infinite-storage.js +60 -19
  22. package/dist/cli/commands/infinite-storage.js.map +2 -2
  23. package/dist/cli/commands/linear-create.js +36 -8
  24. package/dist/cli/commands/linear-create.js.map +2 -2
  25. package/dist/cli/commands/linear-list.js +33 -10
  26. package/dist/cli/commands/linear-list.js.map +2 -2
  27. package/dist/cli/commands/linear-migrate.js +17 -4
  28. package/dist/cli/commands/linear-migrate.js.map +2 -2
  29. package/dist/cli/commands/linear-test.js +14 -6
  30. package/dist/cli/commands/linear-test.js.map +2 -2
  31. package/dist/cli/commands/linear-unified.js +123 -35
  32. package/dist/cli/commands/linear-unified.js.map +2 -2
  33. package/dist/cli/commands/linear.js.map +2 -2
  34. package/dist/cli/commands/monitor.js.map +2 -2
  35. package/dist/cli/commands/onboard.js +35 -8
  36. package/dist/cli/commands/onboard.js.map +2 -2
  37. package/dist/cli/commands/quality.js +2 -7
  38. package/dist/cli/commands/quality.js.map +2 -2
  39. package/dist/cli/commands/session.js +23 -6
  40. package/dist/cli/commands/session.js.map +2 -2
  41. package/dist/cli/commands/skills.js +72 -27
  42. package/dist/cli/commands/skills.js.map +2 -2
  43. package/dist/cli/commands/storage.js +108 -38
  44. package/dist/cli/commands/storage.js.map +2 -2
  45. package/dist/cli/commands/tui.js.map +2 -2
  46. package/dist/cli/commands/webhook.js +57 -18
  47. package/dist/cli/commands/webhook.js.map +2 -2
  48. package/dist/cli/commands/workflow.js +8 -15
  49. package/dist/cli/commands/workflow.js.map +2 -2
  50. package/dist/cli/commands/worktree.js +34 -13
  51. package/dist/cli/commands/worktree.js.map +2 -2
  52. package/dist/cli/index.js +0 -11
  53. package/dist/cli/index.js.map +2 -2
  54. package/dist/core/config/types.js.map +1 -1
  55. package/dist/core/context/auto-context.js +10 -6
  56. package/dist/core/context/auto-context.js.map +2 -2
  57. package/dist/core/context/context-bridge.js.map +2 -2
  58. package/dist/core/context/frame-database.js +13 -3
  59. package/dist/core/context/frame-database.js.map +2 -2
  60. package/dist/core/context/frame-digest.js +7 -5
  61. package/dist/core/context/frame-digest.js.map +2 -2
  62. package/dist/core/context/frame-manager.js.map +2 -2
  63. package/dist/core/context/frame-stack.js +16 -5
  64. package/dist/core/context/frame-stack.js.map +2 -2
  65. package/dist/core/context/incremental-gc.js +10 -3
  66. package/dist/core/context/incremental-gc.js.map +2 -2
  67. package/dist/core/context/index.js.map +1 -1
  68. package/dist/core/context/permission-manager.js.map +2 -2
  69. package/dist/core/context/refactored-frame-manager.js +12 -3
  70. package/dist/core/context/refactored-frame-manager.js.map +2 -2
  71. package/dist/core/context/shared-context-layer.js +4 -2
  72. package/dist/core/context/shared-context-layer.js.map +2 -2
  73. package/dist/core/database/batch-operations.js +112 -86
  74. package/dist/core/database/batch-operations.js.map +2 -2
  75. package/dist/core/database/query-cache.js +19 -9
  76. package/dist/core/database/query-cache.js.map +2 -2
  77. package/dist/core/database/sqlite-adapter.js +1 -1
  78. package/dist/core/database/sqlite-adapter.js.map +2 -2
  79. package/dist/core/digest/enhanced-hybrid-digest.js +8 -2
  80. package/dist/core/digest/enhanced-hybrid-digest.js.map +2 -2
  81. package/dist/core/errors/recovery.js +9 -2
  82. package/dist/core/errors/recovery.js.map +2 -2
  83. package/dist/core/frame/workflow-templates-stub.js.map +1 -1
  84. package/dist/core/frame/workflow-templates.js +40 -1
  85. package/dist/core/frame/workflow-templates.js.map +2 -2
  86. package/dist/core/monitoring/logger.js +6 -1
  87. package/dist/core/monitoring/logger.js.map +2 -2
  88. package/dist/core/monitoring/metrics.js.map +2 -2
  89. package/dist/core/monitoring/progress-tracker.js.map +2 -2
  90. package/dist/core/performance/context-cache.js.map +2 -2
  91. package/dist/core/performance/lazy-context-loader.js +24 -20
  92. package/dist/core/performance/lazy-context-loader.js.map +2 -2
  93. package/dist/core/performance/optimized-frame-context.js +27 -12
  94. package/dist/core/performance/optimized-frame-context.js.map +2 -2
  95. package/dist/core/performance/performance-benchmark.js +10 -6
  96. package/dist/core/performance/performance-benchmark.js.map +2 -2
  97. package/dist/core/performance/performance-profiler.js +51 -14
  98. package/dist/core/performance/performance-profiler.js.map +2 -2
  99. package/dist/core/performance/streaming-jsonl-parser.js +5 -1
  100. package/dist/core/performance/streaming-jsonl-parser.js.map +2 -2
  101. package/dist/core/projects/project-manager.js +14 -20
  102. package/dist/core/projects/project-manager.js.map +2 -2
  103. package/dist/core/retrieval/context-retriever.js.map +1 -1
  104. package/dist/core/retrieval/llm-context-retrieval.js.map +2 -2
  105. package/dist/core/session/clear-survival-stub.js +5 -1
  106. package/dist/core/session/clear-survival-stub.js.map +2 -2
  107. package/dist/core/session/clear-survival.js +35 -0
  108. package/dist/core/session/clear-survival.js.map +2 -2
  109. package/dist/core/session/index.js.map +1 -1
  110. package/dist/core/session/session-manager.js.map +2 -2
  111. package/dist/core/storage/chromadb-adapter.js +6 -2
  112. package/dist/core/storage/chromadb-adapter.js.map +2 -2
  113. package/dist/core/storage/chromadb-simple.js +17 -5
  114. package/dist/core/storage/chromadb-simple.js.map +2 -2
  115. package/dist/core/storage/infinite-storage.js +109 -46
  116. package/dist/core/storage/infinite-storage.js.map +2 -2
  117. package/dist/core/storage/railway-optimized-storage.js +48 -22
  118. package/dist/core/storage/railway-optimized-storage.js.map +2 -2
  119. package/dist/core/storage/remote-storage.js +41 -23
  120. package/dist/core/storage/remote-storage.js.map +2 -2
  121. package/dist/core/trace/cli-trace-wrapper.js +9 -2
  122. package/dist/core/trace/cli-trace-wrapper.js.map +2 -2
  123. package/dist/core/trace/db-trace-wrapper.js +96 -68
  124. package/dist/core/trace/db-trace-wrapper.js.map +2 -2
  125. package/dist/core/trace/debug-trace.js +25 -8
  126. package/dist/core/trace/debug-trace.js.map +2 -2
  127. package/dist/core/trace/index.js +6 -2
  128. package/dist/core/trace/index.js.map +2 -2
  129. package/dist/core/trace/linear-api-wrapper.js +10 -5
  130. package/dist/core/trace/linear-api-wrapper.js.map +2 -2
  131. package/dist/core/trace/trace-demo.js +14 -10
  132. package/dist/core/trace/trace-demo.js.map +2 -2
  133. package/dist/core/trace/trace-detector.js +9 -2
  134. package/dist/core/trace/trace-detector.js.map +2 -2
  135. package/dist/core/trace/types.js.map +1 -1
  136. package/dist/core/utils/compression.js.map +1 -1
  137. package/dist/core/utils/update-checker.js.map +1 -1
  138. package/dist/core/worktree/worktree-manager.js +18 -7
  139. package/dist/core/worktree/worktree-manager.js.map +2 -2
  140. package/dist/features/analytics/core/analytics-service.js.map +2 -2
  141. package/dist/features/analytics/queries/metrics-queries.js +1 -1
  142. package/dist/features/analytics/queries/metrics-queries.js.map +2 -2
  143. package/dist/features/tasks/pebbles-task-store.js.map +1 -1
  144. package/dist/features/tui/components/analytics-panel.js +36 -15
  145. package/dist/features/tui/components/analytics-panel.js.map +2 -2
  146. package/dist/features/tui/components/pr-tracker.js +19 -7
  147. package/dist/features/tui/components/pr-tracker.js.map +2 -2
  148. package/dist/features/tui/components/session-monitor.js +22 -9
  149. package/dist/features/tui/components/session-monitor.js.map +2 -2
  150. package/dist/features/tui/components/subagent-fleet.js +20 -13
  151. package/dist/features/tui/components/subagent-fleet.js.map +2 -2
  152. package/dist/features/tui/components/task-board.js +26 -10
  153. package/dist/features/tui/components/task-board.js.map +2 -2
  154. package/dist/features/tui/index.js.map +2 -2
  155. package/dist/features/tui/services/data-service.js +6 -2
  156. package/dist/features/tui/services/data-service.js.map +2 -2
  157. package/dist/features/tui/services/linear-task-reader.js +3 -1
  158. package/dist/features/tui/services/linear-task-reader.js.map +2 -2
  159. package/dist/features/tui/services/websocket-client.js +3 -1
  160. package/dist/features/tui/services/websocket-client.js.map +2 -2
  161. package/dist/features/tui/terminal-compat.js +6 -2
  162. package/dist/features/tui/terminal-compat.js.map +2 -2
  163. package/dist/features/web/client/stores/task-store.js.map +2 -2
  164. package/dist/features/web/server/index.js +18 -10
  165. package/dist/features/web/server/index.js.map +2 -2
  166. package/dist/integrations/linear/sync-service.js +12 -13
  167. package/dist/integrations/linear/sync-service.js.map +2 -2
  168. package/dist/integrations/linear/sync.js +174 -12
  169. package/dist/integrations/linear/sync.js.map +2 -2
  170. package/dist/integrations/linear/unified-sync.js +1 -1
  171. package/dist/integrations/linear/unified-sync.js.map +1 -1
  172. package/dist/integrations/linear/webhook-server.js +15 -16
  173. package/dist/integrations/linear/webhook-server.js.map +2 -2
  174. package/dist/mcp/stackmemory-mcp-server.js +0 -11
  175. package/dist/mcp/stackmemory-mcp-server.js.map +2 -2
  176. package/dist/servers/production/auth-middleware.js.map +2 -2
  177. package/dist/servers/railway/index.js.map +2 -2
  178. package/dist/services/config-service.js +6 -7
  179. package/dist/services/config-service.js.map +2 -2
  180. package/dist/services/context-service.js +11 -12
  181. package/dist/services/context-service.js.map +2 -2
  182. package/dist/skills/claude-skills.js +4 -2
  183. package/dist/skills/claude-skills.js.map +2 -2
  184. package/dist/skills/dashboard-launcher.js.map +2 -2
  185. package/dist/skills/repo-ingestion-skill.js.map +2 -2
  186. package/dist/utils/env.js +46 -0
  187. package/dist/utils/env.js.map +7 -0
  188. package/dist/utils/logger.js +0 -11
  189. package/dist/utils/logger.js.map +2 -2
  190. package/package.json +1 -1
@@ -12,7 +12,10 @@ class FrameStack {
12
12
  */
13
13
  async initialize() {
14
14
  try {
15
- const activeFrames = this.frameDb.getFramesByProject(this.projectId, "active");
15
+ const activeFrames = this.frameDb.getFramesByProject(
16
+ this.projectId,
17
+ "active"
18
+ );
16
19
  this.activeStack = this.buildStackFromFrames(activeFrames);
17
20
  logger.info("Frame stack initialized", {
18
21
  stackDepth: this.activeStack.length,
@@ -153,7 +156,9 @@ class FrameStack {
153
156
  continue;
154
157
  }
155
158
  if (frame.state !== "active") {
156
- errors.push(`Frame on stack is not active: ${frameId} (state: ${frame.state})`);
159
+ errors.push(
160
+ `Frame on stack is not active: ${frameId} (state: ${frame.state})`
161
+ );
157
162
  }
158
163
  if (frame.project_id !== this.projectId) {
159
164
  errors.push(`Frame belongs to different project: ${frameId}`);
@@ -164,7 +169,9 @@ class FrameStack {
164
169
  const expectedParentId = this.activeStack[i - 1];
165
170
  const currentFrame = this.frameDb.getFrame(currentFrameId);
166
171
  if (currentFrame?.parent_frame_id !== expectedParentId) {
167
- errors.push(`Frame parent mismatch: ${currentFrameId} parent should be ${expectedParentId} but is ${currentFrame?.parent_frame_id}`);
172
+ errors.push(
173
+ `Frame parent mismatch: ${currentFrameId} parent should be ${expectedParentId} but is ${currentFrame?.parent_frame_id}`
174
+ );
168
175
  }
169
176
  }
170
177
  return {
@@ -251,10 +258,14 @@ class FrameStack {
251
258
  });
252
259
  }
253
260
  const stack = [];
254
- let currentFrame = rootFrames.sort((a, b) => a.created_at - b.created_at)[0];
261
+ let currentFrame = rootFrames.sort(
262
+ (a, b) => a.created_at - b.created_at
263
+ )[0];
255
264
  while (currentFrame) {
256
265
  stack.push(currentFrame.frame_id);
257
- const childFrame = frames.find((f) => f.parent_frame_id === currentFrame.frame_id);
266
+ const childFrame = frames.find(
267
+ (f) => f.parent_frame_id === currentFrame.frame_id
268
+ );
258
269
  if (childFrame) {
259
270
  currentFrame = childFrame;
260
271
  } else {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/core/context/frame-stack.ts"],
4
- "sourcesContent": ["/**\n * Frame Stack Management\n * Handles the call stack of active frames\n */\n\nimport { Frame, FrameContext, FrameType } from './frame-types.js';\nimport { FrameDatabase } from './frame-database.js';\nimport { logger } from '../monitoring/logger.js';\nimport { FrameError, ErrorCode } from '../errors/index.js';\n\nexport class FrameStack {\n private activeStack: string[] = [];\n\n constructor(\n private frameDb: FrameDatabase,\n private projectId: string,\n private runId: string\n ) {}\n\n /**\n * Initialize stack by loading active frames\n */\n async initialize(): Promise<void> {\n try {\n const activeFrames = this.frameDb.getFramesByProject(this.projectId, 'active');\n \n // Rebuild stack from database\n this.activeStack = this.buildStackFromFrames(activeFrames);\n \n logger.info('Frame stack initialized', { \n stackDepth: this.activeStack.length,\n projectId: this.projectId,\n });\n } catch (error: unknown) {\n logger.error('Failed to initialize frame stack', {\n error: error instanceof Error ? error.message : String(error),\n projectId: this.projectId,\n runId: this.runId,\n });\n throw new FrameError(\n 'Failed to initialize frame stack',\n ErrorCode.FRAME_INIT_FAILED,\n { \n projectId: this.projectId, \n runId: this.runId,\n originalError: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n /**\n * Push new frame onto stack\n */\n pushFrame(frameId: string): void {\n if (this.activeStack.includes(frameId)) {\n logger.warn('Frame already on stack', { frameId });\n return;\n }\n\n this.activeStack.push(frameId);\n \n logger.debug('Pushed frame to stack', { \n frameId, \n stackDepth: this.activeStack.length \n });\n }\n\n /**\n * Pop frame from stack\n */\n popFrame(frameId?: string): string | undefined {\n if (this.activeStack.length === 0) {\n return undefined;\n }\n\n let poppedFrameId: string | undefined;\n\n if (frameId) {\n // Pop specific frame (and all frames above it)\n const index = this.activeStack.indexOf(frameId);\n if (index === -1) {\n logger.warn('Frame not found on stack', { frameId });\n return undefined;\n }\n\n // Remove the target frame and all frames above it\n const removed = this.activeStack.splice(index);\n poppedFrameId = removed[0];\n\n if (removed.length > 1) {\n logger.info('Popped multiple frames due to stack unwinding', {\n targetFrame: frameId,\n removedFrames: removed,\n });\n }\n } else {\n // Pop top frame\n poppedFrameId = this.activeStack.pop();\n }\n\n if (poppedFrameId) {\n logger.debug('Popped frame from stack', { \n frameId: poppedFrameId, \n stackDepth: this.activeStack.length \n });\n }\n\n return poppedFrameId;\n }\n\n /**\n * Get current (top) frame ID\n */\n getCurrentFrameId(): string | undefined {\n return this.activeStack[this.activeStack.length - 1];\n }\n\n /**\n * Get stack depth\n */\n getDepth(): number {\n return this.activeStack.length;\n }\n\n /**\n * Get complete stack\n */\n getStack(): string[] {\n return [...this.activeStack];\n }\n\n /**\n * Get stack as frame objects\n */\n getStackFrames(): Frame[] {\n return this.activeStack\n .map((frameId: any) => this.frameDb.getFrame(frameId))\n .filter(Boolean) as Frame[];\n }\n\n /**\n * Get frame context for the hot stack\n */\n getHotStackContext(maxEvents: number = 20): FrameContext[] {\n return this.activeStack\n .map((frameId: any) => this.buildFrameContext(frameId, maxEvents))\n .filter(Boolean) as FrameContext[];\n }\n\n /**\n * Check if frame is on stack\n */\n isFrameActive(frameId: string): boolean {\n return this.activeStack.includes(frameId);\n }\n\n /**\n * Get parent frame ID for current frame\n */\n getParentFrameId(): string | undefined {\n if (this.activeStack.length < 2) {\n return undefined;\n }\n return this.activeStack[this.activeStack.length - 2];\n }\n\n /**\n * Get frame depth on stack (0-based)\n */\n getFrameStackDepth(frameId: string): number {\n return this.activeStack.indexOf(frameId);\n }\n\n /**\n * Clear entire stack\n */\n clear(): void {\n const previousDepth = this.activeStack.length;\n this.activeStack = [];\n \n logger.info('Cleared frame stack', { previousDepth });\n }\n\n /**\n * Validate stack consistency\n */\n validateStack(): { isValid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Check if all frames in stack exist and are active\n for (const frameId of this.activeStack) {\n const frame = this.frameDb.getFrame(frameId);\n \n if (!frame) {\n errors.push(`Frame not found in database: ${frameId}`);\n continue;\n }\n\n if (frame.state !== 'active') {\n errors.push(`Frame on stack is not active: ${frameId} (state: ${frame.state})`);\n }\n\n if (frame.project_id !== this.projectId) {\n errors.push(`Frame belongs to different project: ${frameId}`);\n }\n }\n\n // Check for parent-child consistency\n for (let i = 1; i < this.activeStack.length; i++) {\n const currentFrameId = this.activeStack[i];\n const expectedParentId = this.activeStack[i - 1];\n const currentFrame = this.frameDb.getFrame(currentFrameId);\n\n if (currentFrame?.parent_frame_id !== expectedParentId) {\n errors.push(`Frame parent mismatch: ${currentFrameId} parent should be ${expectedParentId} but is ${currentFrame?.parent_frame_id}`);\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Build frame context for a specific frame\n */\n private buildFrameContext(frameId: string, maxEvents: number): FrameContext | null {\n try {\n const frame = this.frameDb.getFrame(frameId);\n if (!frame) {\n logger.warn('Frame not found for context building', { frameId });\n return null;\n }\n\n const anchors = this.frameDb.getFrameAnchors(frameId);\n const recentEvents = this.frameDb.getFrameEvents(frameId, maxEvents);\n const activeArtifacts = this.extractActiveArtifacts(recentEvents);\n\n return {\n frameId,\n header: {\n goal: frame.name,\n constraints: this.extractConstraints(frame.inputs),\n definitions: frame.inputs.definitions,\n },\n anchors,\n recentEvents,\n activeArtifacts,\n };\n } catch (error: unknown) {\n logger.warn('Failed to build frame context', { frameId, error });\n return null;\n }\n }\n\n /**\n * Extract constraints from frame inputs\n */\n private extractConstraints(inputs: Record<string, any>): string[] {\n const constraints: string[] = [];\n \n if (inputs.constraints && Array.isArray(inputs.constraints)) {\n constraints.push(...inputs.constraints);\n }\n \n return constraints;\n }\n\n /**\n * Extract active artifacts from events\n */\n private extractActiveArtifacts(events: any[]): string[] {\n const artifacts: string[] = [];\n \n for (const event of events) {\n if (event.event_type === 'artifact' && event.payload?.path) {\n artifacts.push(event.payload.path);\n }\n }\n \n // Return unique artifacts\n return [...new Set(artifacts)];\n }\n\n /**\n * Build stack order from database frames\n */\n private buildStackFromFrames(frames: Frame[]): string[] {\n if (frames.length === 0) {\n return [];\n }\n\n // Create parent-child map\n const parentMap = new Map<string, string>();\n const frameMap = new Map<string, Frame>();\n \n for (const frame of frames) {\n frameMap.set(frame.frame_id, frame);\n if (frame.parent_frame_id) {\n parentMap.set(frame.frame_id, frame.parent_frame_id);\n }\n }\n\n // Find root frames (no parent or parent not in active set)\n const rootFrames = frames.filter((f: any) => \n !f.parent_frame_id || !frameMap.has(f.parent_frame_id)\n );\n\n if (rootFrames.length === 0) {\n logger.warn('No root frames found in active set');\n return [];\n }\n\n if (rootFrames.length > 1) {\n logger.warn('Multiple root frames found, using most recent', {\n rootFrames: rootFrames.map((f: any) => f.frame_id),\n });\n }\n\n // Build stack from root to leaves\n const stack: string[] = [];\n let currentFrame = rootFrames.sort((a, b) => a.created_at - b.created_at)[0];\n\n while (currentFrame) {\n stack.push(currentFrame.frame_id);\n \n // Find child frame\n const childFrame = frames.find((f: any) => f.parent_frame_id === currentFrame.frame_id);\n if (childFrame) {\n currentFrame = childFrame;\n } else {\n break;\n }\n }\n\n return stack;\n }\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Frame Stack Management\n * Handles the call stack of active frames\n */\n\nimport { Frame, FrameContext, FrameType } from './frame-types.js';\nimport { FrameDatabase } from './frame-database.js';\nimport { logger } from '../monitoring/logger.js';\nimport { FrameError, ErrorCode } from '../errors/index.js';\n\nexport class FrameStack {\n private activeStack: string[] = [];\n\n constructor(\n private frameDb: FrameDatabase,\n private projectId: string,\n private runId: string\n ) {}\n\n /**\n * Initialize stack by loading active frames\n */\n async initialize(): Promise<void> {\n try {\n const activeFrames = this.frameDb.getFramesByProject(\n this.projectId,\n 'active'\n );\n\n // Rebuild stack from database\n this.activeStack = this.buildStackFromFrames(activeFrames);\n\n logger.info('Frame stack initialized', {\n stackDepth: this.activeStack.length,\n projectId: this.projectId,\n });\n } catch (error: unknown) {\n logger.error('Failed to initialize frame stack', {\n error: error instanceof Error ? error.message : String(error),\n projectId: this.projectId,\n runId: this.runId,\n });\n throw new FrameError(\n 'Failed to initialize frame stack',\n ErrorCode.FRAME_INIT_FAILED,\n {\n projectId: this.projectId,\n runId: this.runId,\n originalError: error instanceof Error ? error.message : String(error),\n }\n );\n }\n }\n\n /**\n * Push new frame onto stack\n */\n pushFrame(frameId: string): void {\n if (this.activeStack.includes(frameId)) {\n logger.warn('Frame already on stack', { frameId });\n return;\n }\n\n this.activeStack.push(frameId);\n\n logger.debug('Pushed frame to stack', {\n frameId,\n stackDepth: this.activeStack.length,\n });\n }\n\n /**\n * Pop frame from stack\n */\n popFrame(frameId?: string): string | undefined {\n if (this.activeStack.length === 0) {\n return undefined;\n }\n\n let poppedFrameId: string | undefined;\n\n if (frameId) {\n // Pop specific frame (and all frames above it)\n const index = this.activeStack.indexOf(frameId);\n if (index === -1) {\n logger.warn('Frame not found on stack', { frameId });\n return undefined;\n }\n\n // Remove the target frame and all frames above it\n const removed = this.activeStack.splice(index);\n poppedFrameId = removed[0];\n\n if (removed.length > 1) {\n logger.info('Popped multiple frames due to stack unwinding', {\n targetFrame: frameId,\n removedFrames: removed,\n });\n }\n } else {\n // Pop top frame\n poppedFrameId = this.activeStack.pop();\n }\n\n if (poppedFrameId) {\n logger.debug('Popped frame from stack', {\n frameId: poppedFrameId,\n stackDepth: this.activeStack.length,\n });\n }\n\n return poppedFrameId;\n }\n\n /**\n * Get current (top) frame ID\n */\n getCurrentFrameId(): string | undefined {\n return this.activeStack[this.activeStack.length - 1];\n }\n\n /**\n * Get stack depth\n */\n getDepth(): number {\n return this.activeStack.length;\n }\n\n /**\n * Get complete stack\n */\n getStack(): string[] {\n return [...this.activeStack];\n }\n\n /**\n * Get stack as frame objects\n */\n getStackFrames(): Frame[] {\n return this.activeStack\n .map((frameId: any) => this.frameDb.getFrame(frameId))\n .filter(Boolean) as Frame[];\n }\n\n /**\n * Get frame context for the hot stack\n */\n getHotStackContext(maxEvents: number = 20): FrameContext[] {\n return this.activeStack\n .map((frameId: any) => this.buildFrameContext(frameId, maxEvents))\n .filter(Boolean) as FrameContext[];\n }\n\n /**\n * Check if frame is on stack\n */\n isFrameActive(frameId: string): boolean {\n return this.activeStack.includes(frameId);\n }\n\n /**\n * Get parent frame ID for current frame\n */\n getParentFrameId(): string | undefined {\n if (this.activeStack.length < 2) {\n return undefined;\n }\n return this.activeStack[this.activeStack.length - 2];\n }\n\n /**\n * Get frame depth on stack (0-based)\n */\n getFrameStackDepth(frameId: string): number {\n return this.activeStack.indexOf(frameId);\n }\n\n /**\n * Clear entire stack\n */\n clear(): void {\n const previousDepth = this.activeStack.length;\n this.activeStack = [];\n\n logger.info('Cleared frame stack', { previousDepth });\n }\n\n /**\n * Validate stack consistency\n */\n validateStack(): { isValid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Check if all frames in stack exist and are active\n for (const frameId of this.activeStack) {\n const frame = this.frameDb.getFrame(frameId);\n\n if (!frame) {\n errors.push(`Frame not found in database: ${frameId}`);\n continue;\n }\n\n if (frame.state !== 'active') {\n errors.push(\n `Frame on stack is not active: ${frameId} (state: ${frame.state})`\n );\n }\n\n if (frame.project_id !== this.projectId) {\n errors.push(`Frame belongs to different project: ${frameId}`);\n }\n }\n\n // Check for parent-child consistency\n for (let i = 1; i < this.activeStack.length; i++) {\n const currentFrameId = this.activeStack[i];\n const expectedParentId = this.activeStack[i - 1];\n const currentFrame = this.frameDb.getFrame(currentFrameId);\n\n if (currentFrame?.parent_frame_id !== expectedParentId) {\n errors.push(\n `Frame parent mismatch: ${currentFrameId} parent should be ${expectedParentId} but is ${currentFrame?.parent_frame_id}`\n );\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Build frame context for a specific frame\n */\n private buildFrameContext(\n frameId: string,\n maxEvents: number\n ): FrameContext | null {\n try {\n const frame = this.frameDb.getFrame(frameId);\n if (!frame) {\n logger.warn('Frame not found for context building', { frameId });\n return null;\n }\n\n const anchors = this.frameDb.getFrameAnchors(frameId);\n const recentEvents = this.frameDb.getFrameEvents(frameId, maxEvents);\n const activeArtifacts = this.extractActiveArtifacts(recentEvents);\n\n return {\n frameId,\n header: {\n goal: frame.name,\n constraints: this.extractConstraints(frame.inputs),\n definitions: frame.inputs.definitions,\n },\n anchors,\n recentEvents,\n activeArtifacts,\n };\n } catch (error: unknown) {\n logger.warn('Failed to build frame context', { frameId, error });\n return null;\n }\n }\n\n /**\n * Extract constraints from frame inputs\n */\n private extractConstraints(inputs: Record<string, any>): string[] {\n const constraints: string[] = [];\n\n if (inputs.constraints && Array.isArray(inputs.constraints)) {\n constraints.push(...inputs.constraints);\n }\n\n return constraints;\n }\n\n /**\n * Extract active artifacts from events\n */\n private extractActiveArtifacts(events: any[]): string[] {\n const artifacts: string[] = [];\n\n for (const event of events) {\n if (event.event_type === 'artifact' && event.payload?.path) {\n artifacts.push(event.payload.path);\n }\n }\n\n // Return unique artifacts\n return [...new Set(artifacts)];\n }\n\n /**\n * Build stack order from database frames\n */\n private buildStackFromFrames(frames: Frame[]): string[] {\n if (frames.length === 0) {\n return [];\n }\n\n // Create parent-child map\n const parentMap = new Map<string, string>();\n const frameMap = new Map<string, Frame>();\n\n for (const frame of frames) {\n frameMap.set(frame.frame_id, frame);\n if (frame.parent_frame_id) {\n parentMap.set(frame.frame_id, frame.parent_frame_id);\n }\n }\n\n // Find root frames (no parent or parent not in active set)\n const rootFrames = frames.filter(\n (f: any) => !f.parent_frame_id || !frameMap.has(f.parent_frame_id)\n );\n\n if (rootFrames.length === 0) {\n logger.warn('No root frames found in active set');\n return [];\n }\n\n if (rootFrames.length > 1) {\n logger.warn('Multiple root frames found, using most recent', {\n rootFrames: rootFrames.map((f: any) => f.frame_id),\n });\n }\n\n // Build stack from root to leaves\n const stack: string[] = [];\n let currentFrame = rootFrames.sort(\n (a, b) => a.created_at - b.created_at\n )[0];\n\n while (currentFrame) {\n stack.push(currentFrame.frame_id);\n\n // Find child frame\n const childFrame = frames.find(\n (f: any) => f.parent_frame_id === currentFrame.frame_id\n );\n if (childFrame) {\n currentFrame = childFrame;\n } else {\n break;\n }\n }\n\n return stack;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -43,7 +43,9 @@ class IncrementalGarbageCollector {
43
43
  return;
44
44
  }
45
45
  this.isRunning = true;
46
- this.logger.info(`Starting incremental GC with ${this.config.cycleInterval}ms intervals`);
46
+ this.logger.info(
47
+ `Starting incremental GC with ${this.config.cycleInterval}ms intervals`
48
+ );
47
49
  this.cycleTimer = setInterval(() => {
48
50
  this.runCycle().catch((error) => {
49
51
  this.logger.error("GC cycle failed", error);
@@ -66,7 +68,9 @@ class IncrementalGarbageCollector {
66
68
  */
67
69
  async runCycle() {
68
70
  const startTime = Date.now();
69
- this.logger.debug("Starting GC cycle", { cycle: this.stats.cycleCount + 1 });
71
+ this.logger.debug("Starting GC cycle", {
72
+ cycle: this.stats.cycleCount + 1
73
+ });
70
74
  try {
71
75
  const allFrames = await this.frameManager.getAllFrames();
72
76
  this.stats.totalFrames = allFrames.length;
@@ -151,7 +155,10 @@ class IncrementalGarbageCollector {
151
155
  const orphaned = [...categorized.mature, ...categorized.old].filter(
152
156
  (f) => this.isOrphaned(f)
153
157
  );
154
- const duplicates = this.findDuplicateTraces([...categorized.mature, ...categorized.old]);
158
+ const duplicates = this.findDuplicateTraces([
159
+ ...categorized.mature,
160
+ ...categorized.old
161
+ ]);
155
162
  const oldMature = categorized.mature.filter((f) => {
156
163
  const age = Date.now() - f.created_at;
157
164
  return age > this.config.generations.mature * 0.8;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/core/context/incremental-gc.ts"],
4
- "sourcesContent": ["/**\n * Incremental Garbage Collection System (STA-288)\n * \n * Implements incremental GC strategy to avoid stop-the-world pauses\n * with generational aging and priority-based collection.\n */\n\nimport { Frame, FrameManager } from './frame-manager.js';\nimport { Logger } from '../monitoring/logger.js';\n\ninterface GCConfig {\n framesPerCycle: number; // Process in chunks (default: 100)\n cycleInterval: number; // Every minute (default: 60s)\n maxAge: number; // Max age before eligible for collection (30 days)\n generations: {\n young: number; // < 1 day\n mature: number; // 1-7 days \n old: number; // 7-30 days\n };\n}\n\ninterface GCStats {\n totalFrames: number;\n collectedFrames: number;\n lastRunTime: number;\n cycleCount: number;\n avgCycleTime: number;\n protectedFrames: number;\n}\n\nexport class IncrementalGarbageCollector {\n private logger: Logger;\n private config: GCConfig;\n private stats: GCStats;\n private isRunning: boolean = false;\n private cycleTimer: NodeJS.Timer | null = null;\n private frameManager: FrameManager;\n\n constructor(frameManager: FrameManager, config: Partial<GCConfig> = {}) {\n this.frameManager = frameManager;\n this.logger = new Logger('IncrementalGC');\n \n this.config = {\n framesPerCycle: config.framesPerCycle || 100,\n cycleInterval: config.cycleInterval || 60000, // 60 seconds\n maxAge: config.maxAge || 30 * 24 * 60 * 60 * 1000, // 30 days\n generations: {\n young: config.generations?.young || 24 * 60 * 60 * 1000, // 1 day\n mature: config.generations?.mature || 7 * 24 * 60 * 60 * 1000, // 7 days\n old: config.generations?.old || 30 * 24 * 60 * 60 * 1000, // 30 days\n }\n };\n\n this.stats = {\n totalFrames: 0,\n collectedFrames: 0,\n lastRunTime: 0,\n cycleCount: 0,\n avgCycleTime: 0,\n protectedFrames: 0\n };\n\n this.logger.info('Incremental GC initialized', this.config);\n }\n\n /**\n * Start the garbage collection cycle\n */\n start(): void {\n if (this.isRunning) {\n this.logger.warn('GC already running');\n return;\n }\n\n this.isRunning = true;\n this.logger.info(`Starting incremental GC with ${this.config.cycleInterval}ms intervals`);\n \n this.cycleTimer = setInterval(() => {\n this.runCycle().catch(error => {\n this.logger.error('GC cycle failed', error);\n });\n }, this.config.cycleInterval);\n }\n\n /**\n * Stop the garbage collection cycle\n */\n stop(): void {\n if (this.cycleTimer) {\n clearInterval(this.cycleTimer);\n this.cycleTimer = null;\n }\n this.isRunning = false;\n this.logger.info('Incremental GC stopped');\n }\n\n /**\n * Run a single GC cycle\n */\n async runCycle(): Promise<void> {\n const startTime = Date.now();\n this.logger.debug('Starting GC cycle', { cycle: this.stats.cycleCount + 1 });\n\n try {\n // Get all frames for analysis\n const allFrames = await this.frameManager.getAllFrames();\n this.stats.totalFrames = allFrames.length;\n\n if (allFrames.length === 0) {\n this.logger.debug('No frames to collect');\n return;\n }\n\n // Categorize frames by generation and protection status\n const categorized = this.categorizeFrames(allFrames);\n \n // Select candidates for collection (prioritized)\n const candidates = this.selectCollectionCandidates(categorized);\n \n // Process in chunks to avoid blocking\n const collected = await this.collectFramesIncremental(candidates);\n \n // Update statistics\n this.updateStats(startTime, collected.length);\n \n this.logger.info('GC cycle completed', {\n cycle: this.stats.cycleCount,\n collected: collected.length,\n protected: this.stats.protectedFrames,\n duration: Date.now() - startTime\n });\n\n } catch (error: unknown) {\n this.logger.error('GC cycle error', error);\n }\n }\n\n /**\n * Categorize frames by generation and protection status\n */\n private categorizeFrames(frames: Frame[]): {\n young: Frame[];\n mature: Frame[];\n old: Frame[];\n protected: Frame[];\n } {\n const now = Date.now();\n const categories = { young: [], mature: [], old: [], protected: [] };\n\n for (const frame of frames) {\n const age = now - frame.created_at;\n \n // Check if frame is protected\n if (this.isProtected(frame)) {\n categories.protected.push(frame);\n continue;\n }\n\n // Categorize by age\n if (age < this.config.generations.young) {\n categories.young.push(frame);\n } else if (age < this.config.generations.mature) {\n categories.mature.push(frame);\n } else {\n categories.old.push(frame);\n }\n }\n\n this.stats.protectedFrames = categories.protected.length;\n \n this.logger.debug('Frame categorization', {\n young: categories.young.length,\n mature: categories.mature.length,\n old: categories.old.length,\n protected: categories.protected.length\n });\n\n return categories;\n }\n\n /**\n * Check if a frame should be protected from collection\n */\n private isProtected(frame: Frame): boolean {\n // Protect current session/run frames\n const currentRunId = this.frameManager.getCurrentRunId?.();\n if (frame.run_id === currentRunId) {\n return true;\n }\n\n // Protect active frames\n if (frame.state === 'active') {\n return true;\n }\n\n // Protect recent frames (< 1 hour old)\n const recentThreshold = Date.now() - (60 * 60 * 1000); // 1 hour\n if (frame.created_at > recentThreshold) {\n return true;\n }\n\n // Protect frames with important outputs\n if (frame.outputs && Object.keys(frame.outputs).length > 0) {\n return true;\n }\n\n // Protect parent frames (have children)\n if (frame.depth === 0) { // Root frames\n return true;\n }\n\n return false;\n }\n\n /**\n * Select collection candidates with priority ordering\n */\n private selectCollectionCandidates(categorized: any): Frame[] {\n const candidates: Frame[] = [];\n \n // Priority 1: Closed frames without outputs\n const emptyClosedFrames = categorized.old.filter((f: Frame) => \n f.state === 'closed' && (!f.outputs || Object.keys(f.outputs).length === 0)\n );\n \n // Priority 2: Orphaned frames (no dependencies) \n const orphaned = [...categorized.mature, ...categorized.old].filter((f: Frame) =>\n this.isOrphaned(f)\n );\n \n // Priority 3: Duplicate traces\n const duplicates = this.findDuplicateTraces([...categorized.mature, ...categorized.old]);\n \n // Priority 4: Old mature frames\n const oldMature = categorized.mature.filter((f: Frame) => {\n const age = Date.now() - f.created_at;\n return age > this.config.generations.mature * 0.8; // 80% of mature threshold\n });\n\n // Combine with priority ordering\n candidates.push(...emptyClosedFrames);\n candidates.push(...orphaned);\n candidates.push(...duplicates);\n candidates.push(...oldMature);\n\n // Remove duplicates and limit to cycle size\n const uniqueCandidates = Array.from(new Set(candidates));\n return uniqueCandidates.slice(0, this.config.framesPerCycle);\n }\n\n /**\n * Check if frame is orphaned (no dependencies)\n */\n private isOrphaned(frame: Frame): boolean {\n // Check if frame has any references from other frames \n // This is a simplified check - in practice, would analyze actual dependencies\n return !frame.parent_frame_id && frame.depth > 0 && frame.state === 'closed';\n }\n\n /**\n * Find duplicate trace signatures\n */\n private findDuplicateTraces(frames: Frame[]): Frame[] {\n const signatureMap = new Map<string, Frame[]>();\n \n for (const frame of frames) {\n // Create a signature from trace content\n const signature = this.createTraceSignature(frame);\n if (!signatureMap.has(signature)) {\n signatureMap.set(signature, []);\n }\n signatureMap.get(signature)!.push(frame);\n }\n\n // Return duplicates (keep newest, mark older for collection)\n const duplicates: Frame[] = [];\n for (const [signature, frameList] of signatureMap) {\n if (frameList.length > 1) {\n // Sort by timestamp, keep newest\n frameList.sort((a, b) => b.timestamp - a.timestamp);\n duplicates.push(...frameList.slice(1)); // Mark older ones for collection\n }\n }\n\n return duplicates;\n }\n\n /**\n * Create a signature for duplicate detection\n */\n private createTraceSignature(frame: Frame): string {\n // Create signature from key frame properties\n const type = frame.type;\n const name = frame.name;\n const outputs = JSON.stringify(frame.outputs || {});\n const digestText = frame.digest_text || '';\n return `${type}:${name}:${outputs}:${digestText}`.toLowerCase();\n }\n\n /**\n * Collect frames incrementally to avoid blocking\n */\n private async collectFramesIncremental(candidates: Frame[]): Promise<Frame[]> {\n const collected: Frame[] = [];\n const chunkSize = Math.min(10, Math.ceil(candidates.length / 10)); // Process in small chunks\n\n for (let i = 0; i < candidates.length; i += chunkSize) {\n const chunk = candidates.slice(i, i + chunkSize);\n \n for (const frame of chunk) {\n try {\n await this.frameManager.deleteFrame(frame.frame_id);\n collected.push(frame);\n \n this.logger.debug(`Collected frame ${frame.frame_id}`, {\n age: Date.now() - frame.created_at,\n type: frame.type,\n reason: this.getCollectionReason(frame)\n });\n \n } catch (error: unknown) {\n this.logger.warn(`Failed to collect frame ${frame.frame_id}`, error);\n }\n }\n\n // Yield control to avoid blocking\n await new Promise(resolve => setImmediate(resolve));\n }\n\n return collected;\n }\n\n /**\n * Get human-readable collection reason\n */\n private getCollectionReason(frame: Frame): string {\n const age = Date.now() - frame.created_at;\n const ageHours = Math.floor(age / (60 * 60 * 1000));\n \n if (frame.state === 'closed' && (!frame.outputs || Object.keys(frame.outputs).length === 0)) {\n return 'empty-closed';\n }\n if (this.isOrphaned(frame)) return 'orphaned'; \n if (ageHours > 24 * 30) return `old (${ageHours}h)`;\n return 'duplicate';\n }\n\n /**\n * Update GC statistics\n */\n private updateStats(startTime: number, collectedCount: number): void {\n const cycleTime = Date.now() - startTime;\n \n this.stats.cycleCount++;\n this.stats.collectedFrames += collectedCount;\n this.stats.lastRunTime = startTime;\n this.stats.avgCycleTime = \n (this.stats.avgCycleTime * (this.stats.cycleCount - 1) + cycleTime) / this.stats.cycleCount;\n }\n\n /**\n * Get GC statistics\n */\n getStats(): GCStats {\n return { ...this.stats };\n }\n\n /**\n * Force a manual GC cycle\n */\n async forceCollection(): Promise<void> {\n this.logger.info('Forcing manual GC cycle');\n await this.runCycle();\n }\n\n /**\n * Update GC configuration\n */\n updateConfig(newConfig: Partial<GCConfig>): void {\n this.config = { ...this.config, ...newConfig };\n this.logger.info('GC configuration updated', this.config);\n \n // Restart with new interval if running\n if (this.isRunning && newConfig.cycleInterval) {\n this.stop();\n this.start();\n }\n }\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Incremental Garbage Collection System (STA-288)\n *\n * Implements incremental GC strategy to avoid stop-the-world pauses\n * with generational aging and priority-based collection.\n */\n\nimport { Frame, FrameManager } from './frame-manager.js';\nimport { Logger } from '../monitoring/logger.js';\n\ninterface GCConfig {\n framesPerCycle: number; // Process in chunks (default: 100)\n cycleInterval: number; // Every minute (default: 60s)\n maxAge: number; // Max age before eligible for collection (30 days)\n generations: {\n young: number; // < 1 day\n mature: number; // 1-7 days\n old: number; // 7-30 days\n };\n}\n\ninterface GCStats {\n totalFrames: number;\n collectedFrames: number;\n lastRunTime: number;\n cycleCount: number;\n avgCycleTime: number;\n protectedFrames: number;\n}\n\nexport class IncrementalGarbageCollector {\n private logger: Logger;\n private config: GCConfig;\n private stats: GCStats;\n private isRunning: boolean = false;\n private cycleTimer: NodeJS.Timer | null = null;\n private frameManager: FrameManager;\n\n constructor(frameManager: FrameManager, config: Partial<GCConfig> = {}) {\n this.frameManager = frameManager;\n this.logger = new Logger('IncrementalGC');\n\n this.config = {\n framesPerCycle: config.framesPerCycle || 100,\n cycleInterval: config.cycleInterval || 60000, // 60 seconds\n maxAge: config.maxAge || 30 * 24 * 60 * 60 * 1000, // 30 days\n generations: {\n young: config.generations?.young || 24 * 60 * 60 * 1000, // 1 day\n mature: config.generations?.mature || 7 * 24 * 60 * 60 * 1000, // 7 days\n old: config.generations?.old || 30 * 24 * 60 * 60 * 1000, // 30 days\n },\n };\n\n this.stats = {\n totalFrames: 0,\n collectedFrames: 0,\n lastRunTime: 0,\n cycleCount: 0,\n avgCycleTime: 0,\n protectedFrames: 0,\n };\n\n this.logger.info('Incremental GC initialized', this.config);\n }\n\n /**\n * Start the garbage collection cycle\n */\n start(): void {\n if (this.isRunning) {\n this.logger.warn('GC already running');\n return;\n }\n\n this.isRunning = true;\n this.logger.info(\n `Starting incremental GC with ${this.config.cycleInterval}ms intervals`\n );\n\n this.cycleTimer = setInterval(() => {\n this.runCycle().catch((error) => {\n this.logger.error('GC cycle failed', error);\n });\n }, this.config.cycleInterval);\n }\n\n /**\n * Stop the garbage collection cycle\n */\n stop(): void {\n if (this.cycleTimer) {\n clearInterval(this.cycleTimer);\n this.cycleTimer = null;\n }\n this.isRunning = false;\n this.logger.info('Incremental GC stopped');\n }\n\n /**\n * Run a single GC cycle\n */\n async runCycle(): Promise<void> {\n const startTime = Date.now();\n this.logger.debug('Starting GC cycle', {\n cycle: this.stats.cycleCount + 1,\n });\n\n try {\n // Get all frames for analysis\n const allFrames = await this.frameManager.getAllFrames();\n this.stats.totalFrames = allFrames.length;\n\n if (allFrames.length === 0) {\n this.logger.debug('No frames to collect');\n return;\n }\n\n // Categorize frames by generation and protection status\n const categorized = this.categorizeFrames(allFrames);\n\n // Select candidates for collection (prioritized)\n const candidates = this.selectCollectionCandidates(categorized);\n\n // Process in chunks to avoid blocking\n const collected = await this.collectFramesIncremental(candidates);\n\n // Update statistics\n this.updateStats(startTime, collected.length);\n\n this.logger.info('GC cycle completed', {\n cycle: this.stats.cycleCount,\n collected: collected.length,\n protected: this.stats.protectedFrames,\n duration: Date.now() - startTime,\n });\n } catch (error: unknown) {\n this.logger.error('GC cycle error', error);\n }\n }\n\n /**\n * Categorize frames by generation and protection status\n */\n private categorizeFrames(frames: Frame[]): {\n young: Frame[];\n mature: Frame[];\n old: Frame[];\n protected: Frame[];\n } {\n const now = Date.now();\n const categories = { young: [], mature: [], old: [], protected: [] };\n\n for (const frame of frames) {\n const age = now - frame.created_at;\n\n // Check if frame is protected\n if (this.isProtected(frame)) {\n categories.protected.push(frame);\n continue;\n }\n\n // Categorize by age\n if (age < this.config.generations.young) {\n categories.young.push(frame);\n } else if (age < this.config.generations.mature) {\n categories.mature.push(frame);\n } else {\n categories.old.push(frame);\n }\n }\n\n this.stats.protectedFrames = categories.protected.length;\n\n this.logger.debug('Frame categorization', {\n young: categories.young.length,\n mature: categories.mature.length,\n old: categories.old.length,\n protected: categories.protected.length,\n });\n\n return categories;\n }\n\n /**\n * Check if a frame should be protected from collection\n */\n private isProtected(frame: Frame): boolean {\n // Protect current session/run frames\n const currentRunId = this.frameManager.getCurrentRunId?.();\n if (frame.run_id === currentRunId) {\n return true;\n }\n\n // Protect active frames\n if (frame.state === 'active') {\n return true;\n }\n\n // Protect recent frames (< 1 hour old)\n const recentThreshold = Date.now() - 60 * 60 * 1000; // 1 hour\n if (frame.created_at > recentThreshold) {\n return true;\n }\n\n // Protect frames with important outputs\n if (frame.outputs && Object.keys(frame.outputs).length > 0) {\n return true;\n }\n\n // Protect parent frames (have children)\n if (frame.depth === 0) {\n // Root frames\n return true;\n }\n\n return false;\n }\n\n /**\n * Select collection candidates with priority ordering\n */\n private selectCollectionCandidates(categorized: any): Frame[] {\n const candidates: Frame[] = [];\n\n // Priority 1: Closed frames without outputs\n const emptyClosedFrames = categorized.old.filter(\n (f: Frame) =>\n f.state === 'closed' &&\n (!f.outputs || Object.keys(f.outputs).length === 0)\n );\n\n // Priority 2: Orphaned frames (no dependencies)\n const orphaned = [...categorized.mature, ...categorized.old].filter(\n (f: Frame) => this.isOrphaned(f)\n );\n\n // Priority 3: Duplicate traces\n const duplicates = this.findDuplicateTraces([\n ...categorized.mature,\n ...categorized.old,\n ]);\n\n // Priority 4: Old mature frames\n const oldMature = categorized.mature.filter((f: Frame) => {\n const age = Date.now() - f.created_at;\n return age > this.config.generations.mature * 0.8; // 80% of mature threshold\n });\n\n // Combine with priority ordering\n candidates.push(...emptyClosedFrames);\n candidates.push(...orphaned);\n candidates.push(...duplicates);\n candidates.push(...oldMature);\n\n // Remove duplicates and limit to cycle size\n const uniqueCandidates = Array.from(new Set(candidates));\n return uniqueCandidates.slice(0, this.config.framesPerCycle);\n }\n\n /**\n * Check if frame is orphaned (no dependencies)\n */\n private isOrphaned(frame: Frame): boolean {\n // Check if frame has any references from other frames\n // This is a simplified check - in practice, would analyze actual dependencies\n return (\n !frame.parent_frame_id && frame.depth > 0 && frame.state === 'closed'\n );\n }\n\n /**\n * Find duplicate trace signatures\n */\n private findDuplicateTraces(frames: Frame[]): Frame[] {\n const signatureMap = new Map<string, Frame[]>();\n\n for (const frame of frames) {\n // Create a signature from trace content\n const signature = this.createTraceSignature(frame);\n if (!signatureMap.has(signature)) {\n signatureMap.set(signature, []);\n }\n signatureMap.get(signature)!.push(frame);\n }\n\n // Return duplicates (keep newest, mark older for collection)\n const duplicates: Frame[] = [];\n for (const [signature, frameList] of signatureMap) {\n if (frameList.length > 1) {\n // Sort by timestamp, keep newest\n frameList.sort((a, b) => b.timestamp - a.timestamp);\n duplicates.push(...frameList.slice(1)); // Mark older ones for collection\n }\n }\n\n return duplicates;\n }\n\n /**\n * Create a signature for duplicate detection\n */\n private createTraceSignature(frame: Frame): string {\n // Create signature from key frame properties\n const type = frame.type;\n const name = frame.name;\n const outputs = JSON.stringify(frame.outputs || {});\n const digestText = frame.digest_text || '';\n return `${type}:${name}:${outputs}:${digestText}`.toLowerCase();\n }\n\n /**\n * Collect frames incrementally to avoid blocking\n */\n private async collectFramesIncremental(\n candidates: Frame[]\n ): Promise<Frame[]> {\n const collected: Frame[] = [];\n const chunkSize = Math.min(10, Math.ceil(candidates.length / 10)); // Process in small chunks\n\n for (let i = 0; i < candidates.length; i += chunkSize) {\n const chunk = candidates.slice(i, i + chunkSize);\n\n for (const frame of chunk) {\n try {\n await this.frameManager.deleteFrame(frame.frame_id);\n collected.push(frame);\n\n this.logger.debug(`Collected frame ${frame.frame_id}`, {\n age: Date.now() - frame.created_at,\n type: frame.type,\n reason: this.getCollectionReason(frame),\n });\n } catch (error: unknown) {\n this.logger.warn(`Failed to collect frame ${frame.frame_id}`, error);\n }\n }\n\n // Yield control to avoid blocking\n await new Promise((resolve) => setImmediate(resolve));\n }\n\n return collected;\n }\n\n /**\n * Get human-readable collection reason\n */\n private getCollectionReason(frame: Frame): string {\n const age = Date.now() - frame.created_at;\n const ageHours = Math.floor(age / (60 * 60 * 1000));\n\n if (\n frame.state === 'closed' &&\n (!frame.outputs || Object.keys(frame.outputs).length === 0)\n ) {\n return 'empty-closed';\n }\n if (this.isOrphaned(frame)) return 'orphaned';\n if (ageHours > 24 * 30) return `old (${ageHours}h)`;\n return 'duplicate';\n }\n\n /**\n * Update GC statistics\n */\n private updateStats(startTime: number, collectedCount: number): void {\n const cycleTime = Date.now() - startTime;\n\n this.stats.cycleCount++;\n this.stats.collectedFrames += collectedCount;\n this.stats.lastRunTime = startTime;\n this.stats.avgCycleTime =\n (this.stats.avgCycleTime * (this.stats.cycleCount - 1) + cycleTime) /\n this.stats.cycleCount;\n }\n\n /**\n * Get GC statistics\n */\n getStats(): GCStats {\n return { ...this.stats };\n }\n\n /**\n * Force a manual GC cycle\n */\n async forceCollection(): Promise<void> {\n this.logger.info('Forcing manual GC cycle');\n await this.runCycle();\n }\n\n /**\n * Update GC configuration\n */\n updateConfig(newConfig: Partial<GCConfig>): void {\n this.config = { ...this.config, ...newConfig };\n this.logger.info('GC configuration updated', this.config);\n\n // Restart with new interval if running\n if (this.isRunning && newConfig.cycleInterval) {\n this.stop();\n this.start();\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/core/context/index.ts"],
4
- "sourcesContent": ["/**\n * Context Module Exports\n * Maintains compatibility while providing access to refactored components\n */\n\n// Export refactored components as primary\nexport { RefactoredFrameManager as FrameManager } from './refactored-frame-manager.js';\n\n// Export types\nexport {\n Frame,\n FrameContext,\n Anchor,\n Event,\n FrameType,\n FrameState,\n FrameCreationOptions,\n FrameManagerConfig,\n DigestResult,\n} from './frame-types.js';\n\n// Export focused modules for direct access\nexport { FrameDatabase } from './frame-database.js';\nexport { FrameStack } from './frame-stack.js';\nexport { FrameDigestGenerator } from './frame-digest.js';\n\n// Re-export from old frame-manager for backwards compatibility\n// This allows existing code to continue working without changes\nexport { FrameManager as LegacyFrameManager } from './frame-manager.js';"],
4
+ "sourcesContent": ["/**\n * Context Module Exports\n * Maintains compatibility while providing access to refactored components\n */\n\n// Export refactored components as primary\nexport { RefactoredFrameManager as FrameManager } from './refactored-frame-manager.js';\n\n// Export types\nexport {\n Frame,\n FrameContext,\n Anchor,\n Event,\n FrameType,\n FrameState,\n FrameCreationOptions,\n FrameManagerConfig,\n DigestResult,\n} from './frame-types.js';\n\n// Export focused modules for direct access\nexport { FrameDatabase } from './frame-database.js';\nexport { FrameStack } from './frame-stack.js';\nexport { FrameDigestGenerator } from './frame-digest.js';\n\n// Re-export from old frame-manager for backwards compatibility\n// This allows existing code to continue working without changes\nexport { FrameManager as LegacyFrameManager } from './frame-manager.js';\n"],
5
5
  "mappings": "AAMA,SAAmC,8BAAoB;AAGvD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,SAAS,4BAA4B;AAIrC,SAAyB,oBAA0B;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/core/context/permission-manager.ts"],
4
- "sourcesContent": ["/**\n * Permission Management for Collaboration Layer\n */\n\nimport { ValidationError, ErrorCode } from '../errors/index.js';\nimport type { StackPermissions, StackContext } from './dual-stack-manager.js';\nimport { logger } from '../monitoring/logger.js';\n// Type-safe environment variable access\nfunction getEnv(key: string, defaultValue?: string): string {\n const value = process.env[key];\n if (value === undefined) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${key} is required`);\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\n\nexport type Operation = 'read' | 'write' | 'handoff' | 'merge' | 'administer';\n\nexport interface PermissionContext {\n userId: string;\n operation: Operation;\n resourceType: 'stack' | 'frame' | 'handoff' | 'merge';\n resourceId: string;\n stackContext?: StackContext;\n}\n\nexport class PermissionManager {\n private userPermissions = new Map<string, Map<string, StackPermissions>>();\n private adminUsers = new Set<string>();\n\n constructor() {\n this.initializeDefaultPermissions();\n }\n\n /**\n * Check if user has permission for specific operation\n */\n async checkPermission(context: PermissionContext): Promise<boolean> {\n try {\n // Super admin always has access\n if (this.adminUsers.has(context.userId)) {\n return true;\n }\n\n // Get stack permissions for user\n const stackPermissions = this.getStackPermissions(\n context.userId,\n context.stackContext?.stackId || context.resourceId\n );\n\n if (!stackPermissions) {\n logger.warn('No permissions found for user', {\n userId: context.userId,\n stackId: context.stackContext?.stackId,\n operation: context.operation,\n });\n return false;\n }\n\n // Check operation-specific permissions\n switch (context.operation) {\n case 'read':\n return stackPermissions.canRead;\n\n case 'write':\n return stackPermissions.canWrite;\n\n case 'handoff':\n return stackPermissions.canHandoff;\n\n case 'merge':\n return stackPermissions.canMerge;\n\n case 'administer':\n return stackPermissions.canAdminister;\n\n default:\n logger.error('Unknown operation type', {\n operation: context.operation,\n });\n return false;\n }\n } catch (error: unknown) {\n logger.error('Permission check failed', error);\n return false;\n }\n }\n\n /**\n * Enforce permission check - throws if access denied\n */\n async enforcePermission(context: PermissionContext): Promise<void> {\n const hasPermission = await this.checkPermission(context);\n\n if (!hasPermission) {\n throw new ValidationError(\n `Access denied: User ${context.userId} lacks ${context.operation} permission for ${context.resourceType} ${context.resourceId}`,\n ErrorCode.PERMISSION_VIOLATION,\n {\n userId: context.userId,\n operation: context.operation,\n resourceType: context.resourceType,\n resourceId: context.resourceId,\n }\n );\n }\n\n logger.debug('Permission granted', {\n userId: context.userId,\n operation: context.operation,\n resourceType: context.resourceType,\n resourceId: context.resourceId,\n });\n }\n\n /**\n * Set permissions for user on specific stack\n */\n setStackPermissions(\n userId: string,\n stackId: string,\n permissions: StackPermissions\n ): void {\n if (!this.userPermissions.has(userId)) {\n this.userPermissions.set(userId, new Map());\n }\n\n this.userPermissions.get(userId)!.set(stackId, permissions);\n\n logger.info('Updated stack permissions', {\n userId,\n stackId,\n permissions,\n });\n }\n\n /**\n * Get permissions for user on specific stack\n */\n getStackPermissions(\n userId: string,\n stackId: string\n ): StackPermissions | null {\n const userPerms = this.userPermissions.get(userId);\n if (!userPerms) return null;\n\n return userPerms.get(stackId) || null;\n }\n\n /**\n * Grant admin privileges to user\n */\n grantAdminAccess(userId: string): void {\n this.adminUsers.add(userId);\n logger.info('Granted admin access', { userId });\n }\n\n /**\n * Revoke admin privileges from user\n */\n revokeAdminAccess(userId: string): void {\n this.adminUsers.delete(userId);\n logger.info('Revoked admin access', { userId });\n }\n\n /**\n * Check if user is admin\n */\n isAdmin(userId: string): boolean {\n return this.adminUsers.has(userId);\n }\n\n /**\n * Get all permissions for user\n */\n getUserPermissions(userId: string): Map<string, StackPermissions> {\n return this.userPermissions.get(userId) || new Map();\n }\n\n /**\n * Remove all permissions for user\n */\n removeUserPermissions(userId: string): void {\n this.userPermissions.delete(userId);\n this.adminUsers.delete(userId);\n logger.info('Removed all permissions for user', { userId });\n }\n\n /**\n * Initialize default permissions\n */\n private initializeDefaultPermissions(): void {\n // Set up default admin user if needed\n const defaultAdmin = process.env['STACKMEMORY_DEFAULT_ADMIN'];\n if (defaultAdmin) {\n this.grantAdminAccess(defaultAdmin);\n }\n }\n\n /**\n * Create permission context helper\n */\n createContext(\n userId: string,\n operation: Operation,\n resourceType: PermissionContext['resourceType'],\n resourceId: string,\n stackContext?: StackContext\n ): PermissionContext {\n return {\n userId,\n operation,\n resourceType,\n resourceId,\n stackContext,\n };\n }\n\n /**\n * Bulk permission update for multiple stacks\n */\n setBulkStackPermissions(\n userId: string,\n stackPermissions: Record<string, StackPermissions>\n ): void {\n if (!this.userPermissions.has(userId)) {\n this.userPermissions.set(userId, new Map());\n }\n\n const userPerms = this.userPermissions.get(userId)!;\n\n Object.entries(stackPermissions).forEach(([stackId, permissions]) => {\n userPerms.set(stackId, permissions);\n });\n\n logger.info('Updated bulk stack permissions', {\n userId,\n stackCount: Object.keys(stackPermissions).length,\n });\n }\n\n /**\n * Get permission summary for debugging\n */\n getPermissionSummary(userId: string): {\n isAdmin: boolean;\n stackPermissions: Record<string, StackPermissions>;\n } {\n return {\n isAdmin: this.isAdmin(userId),\n stackPermissions: Object.fromEntries(this.getUserPermissions(userId)),\n };\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Permission Management for Collaboration Layer\n */\n\nimport { ValidationError, ErrorCode } from '../errors/index.js';\nimport type { StackPermissions, StackContext } from './dual-stack-manager.js';\nimport { logger } from '../monitoring/logger.js';\n// Type-safe environment variable access\nfunction getEnv(key: string, defaultValue?: string): string {\n const value = process.env[key];\n if (value === undefined) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${key} is required`);\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\nexport type Operation = 'read' | 'write' | 'handoff' | 'merge' | 'administer';\n\nexport interface PermissionContext {\n userId: string;\n operation: Operation;\n resourceType: 'stack' | 'frame' | 'handoff' | 'merge';\n resourceId: string;\n stackContext?: StackContext;\n}\n\nexport class PermissionManager {\n private userPermissions = new Map<string, Map<string, StackPermissions>>();\n private adminUsers = new Set<string>();\n\n constructor() {\n this.initializeDefaultPermissions();\n }\n\n /**\n * Check if user has permission for specific operation\n */\n async checkPermission(context: PermissionContext): Promise<boolean> {\n try {\n // Super admin always has access\n if (this.adminUsers.has(context.userId)) {\n return true;\n }\n\n // Get stack permissions for user\n const stackPermissions = this.getStackPermissions(\n context.userId,\n context.stackContext?.stackId || context.resourceId\n );\n\n if (!stackPermissions) {\n logger.warn('No permissions found for user', {\n userId: context.userId,\n stackId: context.stackContext?.stackId,\n operation: context.operation,\n });\n return false;\n }\n\n // Check operation-specific permissions\n switch (context.operation) {\n case 'read':\n return stackPermissions.canRead;\n\n case 'write':\n return stackPermissions.canWrite;\n\n case 'handoff':\n return stackPermissions.canHandoff;\n\n case 'merge':\n return stackPermissions.canMerge;\n\n case 'administer':\n return stackPermissions.canAdminister;\n\n default:\n logger.error('Unknown operation type', {\n operation: context.operation,\n });\n return false;\n }\n } catch (error: unknown) {\n logger.error('Permission check failed', error);\n return false;\n }\n }\n\n /**\n * Enforce permission check - throws if access denied\n */\n async enforcePermission(context: PermissionContext): Promise<void> {\n const hasPermission = await this.checkPermission(context);\n\n if (!hasPermission) {\n throw new ValidationError(\n `Access denied: User ${context.userId} lacks ${context.operation} permission for ${context.resourceType} ${context.resourceId}`,\n ErrorCode.PERMISSION_VIOLATION,\n {\n userId: context.userId,\n operation: context.operation,\n resourceType: context.resourceType,\n resourceId: context.resourceId,\n }\n );\n }\n\n logger.debug('Permission granted', {\n userId: context.userId,\n operation: context.operation,\n resourceType: context.resourceType,\n resourceId: context.resourceId,\n });\n }\n\n /**\n * Set permissions for user on specific stack\n */\n setStackPermissions(\n userId: string,\n stackId: string,\n permissions: StackPermissions\n ): void {\n if (!this.userPermissions.has(userId)) {\n this.userPermissions.set(userId, new Map());\n }\n\n this.userPermissions.get(userId)!.set(stackId, permissions);\n\n logger.info('Updated stack permissions', {\n userId,\n stackId,\n permissions,\n });\n }\n\n /**\n * Get permissions for user on specific stack\n */\n getStackPermissions(\n userId: string,\n stackId: string\n ): StackPermissions | null {\n const userPerms = this.userPermissions.get(userId);\n if (!userPerms) return null;\n\n return userPerms.get(stackId) || null;\n }\n\n /**\n * Grant admin privileges to user\n */\n grantAdminAccess(userId: string): void {\n this.adminUsers.add(userId);\n logger.info('Granted admin access', { userId });\n }\n\n /**\n * Revoke admin privileges from user\n */\n revokeAdminAccess(userId: string): void {\n this.adminUsers.delete(userId);\n logger.info('Revoked admin access', { userId });\n }\n\n /**\n * Check if user is admin\n */\n isAdmin(userId: string): boolean {\n return this.adminUsers.has(userId);\n }\n\n /**\n * Get all permissions for user\n */\n getUserPermissions(userId: string): Map<string, StackPermissions> {\n return this.userPermissions.get(userId) || new Map();\n }\n\n /**\n * Remove all permissions for user\n */\n removeUserPermissions(userId: string): void {\n this.userPermissions.delete(userId);\n this.adminUsers.delete(userId);\n logger.info('Removed all permissions for user', { userId });\n }\n\n /**\n * Initialize default permissions\n */\n private initializeDefaultPermissions(): void {\n // Set up default admin user if needed\n const defaultAdmin = process.env['STACKMEMORY_DEFAULT_ADMIN'];\n if (defaultAdmin) {\n this.grantAdminAccess(defaultAdmin);\n }\n }\n\n /**\n * Create permission context helper\n */\n createContext(\n userId: string,\n operation: Operation,\n resourceType: PermissionContext['resourceType'],\n resourceId: string,\n stackContext?: StackContext\n ): PermissionContext {\n return {\n userId,\n operation,\n resourceType,\n resourceId,\n stackContext,\n };\n }\n\n /**\n * Bulk permission update for multiple stacks\n */\n setBulkStackPermissions(\n userId: string,\n stackPermissions: Record<string, StackPermissions>\n ): void {\n if (!this.userPermissions.has(userId)) {\n this.userPermissions.set(userId, new Map());\n }\n\n const userPerms = this.userPermissions.get(userId)!;\n\n Object.entries(stackPermissions).forEach(([stackId, permissions]) => {\n userPerms.set(stackId, permissions);\n });\n\n logger.info('Updated bulk stack permissions', {\n userId,\n stackCount: Object.keys(stackPermissions).length,\n });\n }\n\n /**\n * Get permission summary for debugging\n */\n getPermissionSummary(userId: string): {\n isAdmin: boolean;\n stackPermissions: Record<string, StackPermissions>;\n } {\n return {\n isAdmin: this.isAdmin(userId),\n stackPermissions: Object.fromEntries(this.getUserPermissions(userId)),\n };\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -30,7 +30,11 @@ class RefactoredFrameManager {
30
30
  this.currentRunId = this.config.runId;
31
31
  this.sessionId = this.config.sessionId;
32
32
  this.frameDb = new FrameDatabase(db);
33
- this.frameStack = new FrameStack(this.frameDb, projectId, this.currentRunId);
33
+ this.frameStack = new FrameStack(
34
+ this.frameDb,
35
+ projectId,
36
+ this.currentRunId
37
+ );
34
38
  this.digestGenerator = new FrameDigestGenerator(this.frameDb);
35
39
  this.frameDb.initSchema();
36
40
  logger.info("RefactoredFrameManager initialized", {
@@ -326,8 +330,13 @@ class RefactoredFrameManager {
326
330
  */
327
331
  closeChildFrames(parentFrameId) {
328
332
  try {
329
- const activeFrames = this.frameDb.getFramesByProject(this.projectId, "active");
330
- const childFrames = activeFrames.filter((f) => f.parent_frame_id === parentFrameId);
333
+ const activeFrames = this.frameDb.getFramesByProject(
334
+ this.projectId,
335
+ "active"
336
+ );
337
+ const childFrames = activeFrames.filter(
338
+ (f) => f.parent_frame_id === parentFrameId
339
+ );
331
340
  for (const childFrame of childFrames) {
332
341
  if (this.frameStack.isFrameActive(childFrame.frame_id)) {
333
342
  this.closeFrame(childFrame.frame_id);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/core/context/refactored-frame-manager.ts"],
4
- "sourcesContent": ["/**\n * Refactored Frame Manager - Modular Implementation\n * Main orchestrator that uses focused modules for frame management\n */\n\nimport Database from 'better-sqlite3';\nimport { v4 as uuidv4 } from 'uuid';\nimport { logger } from '../monitoring/logger.js';\nimport { trace } from '../trace/index.js';\nimport {\n FrameError,\n SystemError,\n ErrorCode,\n wrapError,\n createErrorHandler,\n} from '../errors/index.js';\nimport { retry, withTimeout } from '../errors/recovery.js';\nimport { sessionManager, FrameQueryMode } from '../session/index.js';\n\n// Import refactored modules\nimport {\n Frame,\n FrameContext,\n Anchor,\n Event,\n FrameType,\n FrameState,\n FrameCreationOptions,\n FrameManagerConfig,\n DigestResult,\n} from './frame-types.js';\nimport { FrameDatabase } from './frame-database.js';\nimport { FrameStack } from './frame-stack.js';\nimport { FrameDigestGenerator } from './frame-digest.js';\n\nexport class RefactoredFrameManager {\n private frameDb: FrameDatabase;\n private frameStack: FrameStack;\n private digestGenerator: FrameDigestGenerator;\n \n private currentRunId: string;\n private sessionId: string;\n private projectId: string;\n private queryMode: FrameQueryMode = FrameQueryMode.PROJECT_ACTIVE;\n private config: FrameManagerConfig;\n\n constructor(db: Database.Database, projectId: string, config?: Partial<FrameManagerConfig>) {\n this.projectId = projectId;\n this.config = {\n projectId,\n runId: config?.runId || uuidv4(),\n sessionId: config?.sessionId || uuidv4(),\n maxStackDepth: config?.maxStackDepth || 50,\n };\n\n this.currentRunId = this.config.runId!;\n this.sessionId = this.config.sessionId!;\n\n // Initialize modules\n this.frameDb = new FrameDatabase(db);\n this.frameStack = new FrameStack(this.frameDb, projectId, this.currentRunId);\n this.digestGenerator = new FrameDigestGenerator(this.frameDb);\n\n // Initialize database schema\n this.frameDb.initSchema();\n\n logger.info('RefactoredFrameManager initialized', {\n projectId: this.projectId,\n runId: this.currentRunId,\n sessionId: this.sessionId,\n });\n }\n\n /**\n * Initialize the frame manager\n */\n async initialize(): Promise<void> {\n try {\n await this.frameStack.initialize();\n \n logger.info('Frame manager initialization completed', {\n stackDepth: this.frameStack.getDepth(),\n });\n } catch (error: unknown) {\n throw new SystemError(\n 'Failed to initialize frame manager',\n ErrorCode.SYSTEM_INIT_FAILED,\n { projectId: this.projectId },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Create a new frame\n */\n createFrame(options: FrameCreationOptions): string;\n createFrame(\n type: FrameType,\n name: string,\n inputs?: Record<string, any>,\n parentFrameId?: string\n ): string;\n createFrame(\n typeOrOptions: FrameType | FrameCreationOptions,\n name?: string,\n inputs?: Record<string, any>,\n parentFrameId?: string\n ): string {\n return trace.traceSync('function', 'FrameManager.createFrame', { typeOrOptions, name }, () =>\n this._createFrame(typeOrOptions, name, inputs, parentFrameId)\n );\n }\n\n private _createFrame(\n typeOrOptions: FrameType | FrameCreationOptions,\n name?: string,\n inputs?: Record<string, any>,\n parentFrameId?: string\n ): string {\n let frameOptions: FrameCreationOptions;\n\n // Handle both function signatures\n if (typeof typeOrOptions === 'string') {\n frameOptions = {\n type: typeOrOptions,\n name: name!,\n inputs: inputs || {},\n parentFrameId,\n };\n } else {\n frameOptions = typeOrOptions;\n }\n\n // Validate inputs\n if (!frameOptions.name || frameOptions.name.trim().length === 0) {\n throw new FrameError(\n 'Frame name is required',\n ErrorCode.FRAME_INVALID_INPUT,\n { frameOptions }\n );\n }\n\n // Check stack depth limit\n if (this.frameStack.getDepth() >= this.config.maxStackDepth!) {\n throw new FrameError(\n `Maximum stack depth reached: ${this.config.maxStackDepth}`,\n ErrorCode.FRAME_STACK_OVERFLOW,\n { currentDepth: this.frameStack.getDepth() }\n );\n }\n\n // Determine parent frame\n const resolvedParentId = frameOptions.parentFrameId || this.frameStack.getCurrentFrameId();\n const depth = resolvedParentId \n ? this.frameStack.getFrameStackDepth(resolvedParentId) + 1 \n : 0;\n\n // Create frame data\n const frameId = uuidv4();\n const frame: Omit<Frame, 'created_at' | 'closed_at'> = {\n frame_id: frameId,\n run_id: this.currentRunId,\n project_id: this.projectId,\n parent_frame_id: resolvedParentId,\n depth,\n type: frameOptions.type,\n name: frameOptions.name,\n state: 'active',\n inputs: frameOptions.inputs || {},\n outputs: {},\n digest_json: {},\n };\n\n // Insert into database\n const createdFrame = this.frameDb.insertFrame(frame);\n\n // Add to stack\n this.frameStack.pushFrame(frameId);\n\n logger.info('Created frame', {\n frameId,\n name: frameOptions.name,\n type: frameOptions.type,\n parentFrameId: resolvedParentId,\n stackDepth: this.frameStack.getDepth(),\n });\n\n return frameId;\n }\n\n /**\n * Close a frame and generate digest\n */\n closeFrame(frameId?: string, outputs?: Record<string, any>): void {\n trace.traceSync('function', 'FrameManager.closeFrame', { frameId, outputs }, () =>\n this._closeFrame(frameId, outputs)\n );\n }\n\n private _closeFrame(frameId?: string, outputs?: Record<string, any>): void {\n const targetFrameId = frameId || this.frameStack.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame to close',\n ErrorCode.FRAME_INVALID_STATE,\n {\n operation: 'closeFrame',\n stackDepth: this.frameStack.getDepth(),\n }\n );\n }\n\n // Get frame details\n const frame = this.frameDb.getFrame(targetFrameId);\n if (!frame) {\n throw new FrameError(\n `Frame not found: ${targetFrameId}`,\n ErrorCode.FRAME_NOT_FOUND,\n {\n frameId: targetFrameId,\n operation: 'closeFrame',\n runId: this.currentRunId,\n }\n );\n }\n\n if (frame.state === 'closed') {\n logger.warn('Attempted to close already closed frame', {\n frameId: targetFrameId,\n });\n return;\n }\n\n // Generate digest before closing\n const digest = this.digestGenerator.generateDigest(targetFrameId);\n const finalOutputs = { ...outputs, ...digest.structured };\n\n // Update frame to closed state\n this.frameDb.updateFrame(targetFrameId, {\n state: 'closed',\n outputs: finalOutputs,\n digest_text: digest.text,\n digest_json: digest.structured,\n closed_at: Math.floor(Date.now() / 1000),\n });\n\n // Remove from stack (this will also remove any child frames)\n this.frameStack.popFrame(targetFrameId);\n\n // Close all child frames recursively\n this.closeChildFrames(targetFrameId);\n\n logger.info('Closed frame', {\n frameId: targetFrameId,\n name: frame.name,\n duration: Math.floor(Date.now() / 1000) - frame.created_at,\n digestLength: digest.text.length,\n stackDepth: this.frameStack.getDepth(),\n });\n }\n\n /**\n * Add an event to the current frame\n */\n addEvent(\n eventType: Event['event_type'],\n payload: Record<string, any>,\n frameId?: string\n ): string {\n return trace.traceSync('function', 'FrameManager.addEvent', { eventType, frameId }, () =>\n this._addEvent(eventType, payload, frameId)\n );\n }\n\n private _addEvent(\n eventType: Event['event_type'],\n payload: Record<string, any>,\n frameId?: string\n ): string {\n const targetFrameId = frameId || this.frameStack.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame for event',\n ErrorCode.FRAME_INVALID_STATE,\n {\n eventType,\n operation: 'addEvent',\n }\n );\n }\n\n const eventId = uuidv4();\n const sequence = this.frameDb.getNextEventSequence(targetFrameId);\n\n const event: Omit<Event, 'ts'> = {\n event_id: eventId,\n frame_id: targetFrameId,\n run_id: this.currentRunId,\n seq: sequence,\n event_type: eventType,\n payload,\n };\n\n const createdEvent = this.frameDb.insertEvent(event);\n\n logger.debug('Added event', {\n eventId,\n frameId: targetFrameId,\n eventType,\n sequence,\n });\n\n return eventId;\n }\n\n /**\n * Add an anchor (important fact) to current frame\n */\n addAnchor(\n type: Anchor['type'],\n text: string,\n priority: number = 5,\n metadata: Record<string, any> = {},\n frameId?: string\n ): string {\n return trace.traceSync('function', 'FrameManager.addAnchor', { type, frameId }, () =>\n this._addAnchor(type, text, priority, metadata, frameId)\n );\n }\n\n private _addAnchor(\n type: Anchor['type'],\n text: string,\n priority: number,\n metadata: Record<string, any>,\n frameId?: string\n ): string {\n const targetFrameId = frameId || this.frameStack.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame for anchor',\n ErrorCode.FRAME_INVALID_STATE,\n {\n anchorType: type,\n operation: 'addAnchor',\n }\n );\n }\n\n const anchorId = uuidv4();\n const anchor: Omit<Anchor, 'created_at'> = {\n anchor_id: anchorId,\n frame_id: targetFrameId,\n type,\n text,\n priority,\n metadata,\n };\n\n const createdAnchor = this.frameDb.insertAnchor(anchor);\n\n logger.debug('Added anchor', {\n anchorId,\n frameId: targetFrameId,\n type,\n priority,\n });\n\n return anchorId;\n }\n\n /**\n * Get hot stack context\n */\n getHotStackContext(maxEvents: number = 20): FrameContext[] {\n return this.frameStack.getHotStackContext(maxEvents);\n }\n\n /**\n * Get active frame path (root to current)\n */\n getActiveFramePath(): Frame[] {\n return this.frameStack.getStackFrames();\n }\n\n /**\n * Get current frame ID\n */\n getCurrentFrameId(): string | undefined {\n return this.frameStack.getCurrentFrameId();\n }\n\n /**\n * Get stack depth\n */\n getStackDepth(): number {\n return this.frameStack.getDepth();\n }\n\n /**\n * Get frame by ID\n */\n getFrame(frameId: string): Frame | undefined {\n return this.frameDb.getFrame(frameId);\n }\n\n /**\n * Get frame events\n */\n getFrameEvents(frameId: string, limit?: number): Event[] {\n return this.frameDb.getFrameEvents(frameId, limit);\n }\n\n /**\n * Get frame anchors\n */\n getFrameAnchors(frameId: string): Anchor[] {\n return this.frameDb.getFrameAnchors(frameId);\n }\n\n /**\n * Generate digest for a frame\n */\n generateDigest(frameId: string): DigestResult {\n return this.digestGenerator.generateDigest(frameId);\n }\n\n /**\n * Validate stack consistency\n */\n validateStack(): { isValid: boolean; errors: string[] } {\n return this.frameStack.validateStack();\n }\n\n /**\n * Get database statistics\n */\n getStatistics(): Record<string, number> {\n return this.frameDb.getStatistics();\n }\n\n /**\n * Close all child frames recursively\n */\n private closeChildFrames(parentFrameId: string): void {\n try {\n const activeFrames = this.frameDb.getFramesByProject(this.projectId, 'active');\n const childFrames = activeFrames.filter((f: any) => f.parent_frame_id === parentFrameId);\n\n for (const childFrame of childFrames) {\n if (this.frameStack.isFrameActive(childFrame.frame_id)) {\n this.closeFrame(childFrame.frame_id);\n }\n }\n } catch (error: unknown) {\n logger.warn('Failed to close child frames', { parentFrameId, error });\n }\n }\n\n /**\n * Extract active artifacts from frame events\n */\n getActiveArtifacts(frameId: string): string[] {\n const events = this.frameDb.getFrameEvents(frameId);\n const artifacts: string[] = [];\n\n for (const event of events) {\n if (event.event_type === 'artifact' && event.payload.path) {\n artifacts.push(event.payload.path);\n }\n }\n\n return [...new Set(artifacts)];\n }\n\n /**\n * Extract constraints from frame inputs\n */\n extractConstraints(inputs: Record<string, any>): string[] {\n const constraints: string[] = [];\n \n if (inputs.constraints && Array.isArray(inputs.constraints)) {\n constraints.push(...inputs.constraints);\n }\n \n if (inputs.requirements && Array.isArray(inputs.requirements)) {\n constraints.push(...inputs.requirements);\n }\n \n if (inputs.limitations && Array.isArray(inputs.limitations)) {\n constraints.push(...inputs.limitations);\n }\n\n return constraints;\n }\n}\n\n// Re-export types for compatibility\nexport {\n Frame,\n FrameContext,\n Anchor,\n Event,\n FrameType,\n FrameState,\n FrameCreationOptions,\n FrameManagerConfig,\n DigestResult,\n} from './frame-types.js';"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Refactored Frame Manager - Modular Implementation\n * Main orchestrator that uses focused modules for frame management\n */\n\nimport Database from 'better-sqlite3';\nimport { v4 as uuidv4 } from 'uuid';\nimport { logger } from '../monitoring/logger.js';\nimport { trace } from '../trace/index.js';\nimport {\n FrameError,\n SystemError,\n ErrorCode,\n wrapError,\n createErrorHandler,\n} from '../errors/index.js';\nimport { retry, withTimeout } from '../errors/recovery.js';\nimport { sessionManager, FrameQueryMode } from '../session/index.js';\n\n// Import refactored modules\nimport {\n Frame,\n FrameContext,\n Anchor,\n Event,\n FrameType,\n FrameState,\n FrameCreationOptions,\n FrameManagerConfig,\n DigestResult,\n} from './frame-types.js';\nimport { FrameDatabase } from './frame-database.js';\nimport { FrameStack } from './frame-stack.js';\nimport { FrameDigestGenerator } from './frame-digest.js';\n\nexport class RefactoredFrameManager {\n private frameDb: FrameDatabase;\n private frameStack: FrameStack;\n private digestGenerator: FrameDigestGenerator;\n\n private currentRunId: string;\n private sessionId: string;\n private projectId: string;\n private queryMode: FrameQueryMode = FrameQueryMode.PROJECT_ACTIVE;\n private config: FrameManagerConfig;\n\n constructor(\n db: Database.Database,\n projectId: string,\n config?: Partial<FrameManagerConfig>\n ) {\n this.projectId = projectId;\n this.config = {\n projectId,\n runId: config?.runId || uuidv4(),\n sessionId: config?.sessionId || uuidv4(),\n maxStackDepth: config?.maxStackDepth || 50,\n };\n\n this.currentRunId = this.config.runId!;\n this.sessionId = this.config.sessionId!;\n\n // Initialize modules\n this.frameDb = new FrameDatabase(db);\n this.frameStack = new FrameStack(\n this.frameDb,\n projectId,\n this.currentRunId\n );\n this.digestGenerator = new FrameDigestGenerator(this.frameDb);\n\n // Initialize database schema\n this.frameDb.initSchema();\n\n logger.info('RefactoredFrameManager initialized', {\n projectId: this.projectId,\n runId: this.currentRunId,\n sessionId: this.sessionId,\n });\n }\n\n /**\n * Initialize the frame manager\n */\n async initialize(): Promise<void> {\n try {\n await this.frameStack.initialize();\n\n logger.info('Frame manager initialization completed', {\n stackDepth: this.frameStack.getDepth(),\n });\n } catch (error: unknown) {\n throw new SystemError(\n 'Failed to initialize frame manager',\n ErrorCode.SYSTEM_INIT_FAILED,\n { projectId: this.projectId },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Create a new frame\n */\n createFrame(options: FrameCreationOptions): string;\n createFrame(\n type: FrameType,\n name: string,\n inputs?: Record<string, any>,\n parentFrameId?: string\n ): string;\n createFrame(\n typeOrOptions: FrameType | FrameCreationOptions,\n name?: string,\n inputs?: Record<string, any>,\n parentFrameId?: string\n ): string {\n return trace.traceSync(\n 'function',\n 'FrameManager.createFrame',\n { typeOrOptions, name },\n () => this._createFrame(typeOrOptions, name, inputs, parentFrameId)\n );\n }\n\n private _createFrame(\n typeOrOptions: FrameType | FrameCreationOptions,\n name?: string,\n inputs?: Record<string, any>,\n parentFrameId?: string\n ): string {\n let frameOptions: FrameCreationOptions;\n\n // Handle both function signatures\n if (typeof typeOrOptions === 'string') {\n frameOptions = {\n type: typeOrOptions,\n name: name!,\n inputs: inputs || {},\n parentFrameId,\n };\n } else {\n frameOptions = typeOrOptions;\n }\n\n // Validate inputs\n if (!frameOptions.name || frameOptions.name.trim().length === 0) {\n throw new FrameError(\n 'Frame name is required',\n ErrorCode.FRAME_INVALID_INPUT,\n { frameOptions }\n );\n }\n\n // Check stack depth limit\n if (this.frameStack.getDepth() >= this.config.maxStackDepth!) {\n throw new FrameError(\n `Maximum stack depth reached: ${this.config.maxStackDepth}`,\n ErrorCode.FRAME_STACK_OVERFLOW,\n { currentDepth: this.frameStack.getDepth() }\n );\n }\n\n // Determine parent frame\n const resolvedParentId =\n frameOptions.parentFrameId || this.frameStack.getCurrentFrameId();\n const depth = resolvedParentId\n ? this.frameStack.getFrameStackDepth(resolvedParentId) + 1\n : 0;\n\n // Create frame data\n const frameId = uuidv4();\n const frame: Omit<Frame, 'created_at' | 'closed_at'> = {\n frame_id: frameId,\n run_id: this.currentRunId,\n project_id: this.projectId,\n parent_frame_id: resolvedParentId,\n depth,\n type: frameOptions.type,\n name: frameOptions.name,\n state: 'active',\n inputs: frameOptions.inputs || {},\n outputs: {},\n digest_json: {},\n };\n\n // Insert into database\n const createdFrame = this.frameDb.insertFrame(frame);\n\n // Add to stack\n this.frameStack.pushFrame(frameId);\n\n logger.info('Created frame', {\n frameId,\n name: frameOptions.name,\n type: frameOptions.type,\n parentFrameId: resolvedParentId,\n stackDepth: this.frameStack.getDepth(),\n });\n\n return frameId;\n }\n\n /**\n * Close a frame and generate digest\n */\n closeFrame(frameId?: string, outputs?: Record<string, any>): void {\n trace.traceSync(\n 'function',\n 'FrameManager.closeFrame',\n { frameId, outputs },\n () => this._closeFrame(frameId, outputs)\n );\n }\n\n private _closeFrame(frameId?: string, outputs?: Record<string, any>): void {\n const targetFrameId = frameId || this.frameStack.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame to close',\n ErrorCode.FRAME_INVALID_STATE,\n {\n operation: 'closeFrame',\n stackDepth: this.frameStack.getDepth(),\n }\n );\n }\n\n // Get frame details\n const frame = this.frameDb.getFrame(targetFrameId);\n if (!frame) {\n throw new FrameError(\n `Frame not found: ${targetFrameId}`,\n ErrorCode.FRAME_NOT_FOUND,\n {\n frameId: targetFrameId,\n operation: 'closeFrame',\n runId: this.currentRunId,\n }\n );\n }\n\n if (frame.state === 'closed') {\n logger.warn('Attempted to close already closed frame', {\n frameId: targetFrameId,\n });\n return;\n }\n\n // Generate digest before closing\n const digest = this.digestGenerator.generateDigest(targetFrameId);\n const finalOutputs = { ...outputs, ...digest.structured };\n\n // Update frame to closed state\n this.frameDb.updateFrame(targetFrameId, {\n state: 'closed',\n outputs: finalOutputs,\n digest_text: digest.text,\n digest_json: digest.structured,\n closed_at: Math.floor(Date.now() / 1000),\n });\n\n // Remove from stack (this will also remove any child frames)\n this.frameStack.popFrame(targetFrameId);\n\n // Close all child frames recursively\n this.closeChildFrames(targetFrameId);\n\n logger.info('Closed frame', {\n frameId: targetFrameId,\n name: frame.name,\n duration: Math.floor(Date.now() / 1000) - frame.created_at,\n digestLength: digest.text.length,\n stackDepth: this.frameStack.getDepth(),\n });\n }\n\n /**\n * Add an event to the current frame\n */\n addEvent(\n eventType: Event['event_type'],\n payload: Record<string, any>,\n frameId?: string\n ): string {\n return trace.traceSync(\n 'function',\n 'FrameManager.addEvent',\n { eventType, frameId },\n () => this._addEvent(eventType, payload, frameId)\n );\n }\n\n private _addEvent(\n eventType: Event['event_type'],\n payload: Record<string, any>,\n frameId?: string\n ): string {\n const targetFrameId = frameId || this.frameStack.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame for event',\n ErrorCode.FRAME_INVALID_STATE,\n {\n eventType,\n operation: 'addEvent',\n }\n );\n }\n\n const eventId = uuidv4();\n const sequence = this.frameDb.getNextEventSequence(targetFrameId);\n\n const event: Omit<Event, 'ts'> = {\n event_id: eventId,\n frame_id: targetFrameId,\n run_id: this.currentRunId,\n seq: sequence,\n event_type: eventType,\n payload,\n };\n\n const createdEvent = this.frameDb.insertEvent(event);\n\n logger.debug('Added event', {\n eventId,\n frameId: targetFrameId,\n eventType,\n sequence,\n });\n\n return eventId;\n }\n\n /**\n * Add an anchor (important fact) to current frame\n */\n addAnchor(\n type: Anchor['type'],\n text: string,\n priority: number = 5,\n metadata: Record<string, any> = {},\n frameId?: string\n ): string {\n return trace.traceSync(\n 'function',\n 'FrameManager.addAnchor',\n { type, frameId },\n () => this._addAnchor(type, text, priority, metadata, frameId)\n );\n }\n\n private _addAnchor(\n type: Anchor['type'],\n text: string,\n priority: number,\n metadata: Record<string, any>,\n frameId?: string\n ): string {\n const targetFrameId = frameId || this.frameStack.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame for anchor',\n ErrorCode.FRAME_INVALID_STATE,\n {\n anchorType: type,\n operation: 'addAnchor',\n }\n );\n }\n\n const anchorId = uuidv4();\n const anchor: Omit<Anchor, 'created_at'> = {\n anchor_id: anchorId,\n frame_id: targetFrameId,\n type,\n text,\n priority,\n metadata,\n };\n\n const createdAnchor = this.frameDb.insertAnchor(anchor);\n\n logger.debug('Added anchor', {\n anchorId,\n frameId: targetFrameId,\n type,\n priority,\n });\n\n return anchorId;\n }\n\n /**\n * Get hot stack context\n */\n getHotStackContext(maxEvents: number = 20): FrameContext[] {\n return this.frameStack.getHotStackContext(maxEvents);\n }\n\n /**\n * Get active frame path (root to current)\n */\n getActiveFramePath(): Frame[] {\n return this.frameStack.getStackFrames();\n }\n\n /**\n * Get current frame ID\n */\n getCurrentFrameId(): string | undefined {\n return this.frameStack.getCurrentFrameId();\n }\n\n /**\n * Get stack depth\n */\n getStackDepth(): number {\n return this.frameStack.getDepth();\n }\n\n /**\n * Get frame by ID\n */\n getFrame(frameId: string): Frame | undefined {\n return this.frameDb.getFrame(frameId);\n }\n\n /**\n * Get frame events\n */\n getFrameEvents(frameId: string, limit?: number): Event[] {\n return this.frameDb.getFrameEvents(frameId, limit);\n }\n\n /**\n * Get frame anchors\n */\n getFrameAnchors(frameId: string): Anchor[] {\n return this.frameDb.getFrameAnchors(frameId);\n }\n\n /**\n * Generate digest for a frame\n */\n generateDigest(frameId: string): DigestResult {\n return this.digestGenerator.generateDigest(frameId);\n }\n\n /**\n * Validate stack consistency\n */\n validateStack(): { isValid: boolean; errors: string[] } {\n return this.frameStack.validateStack();\n }\n\n /**\n * Get database statistics\n */\n getStatistics(): Record<string, number> {\n return this.frameDb.getStatistics();\n }\n\n /**\n * Close all child frames recursively\n */\n private closeChildFrames(parentFrameId: string): void {\n try {\n const activeFrames = this.frameDb.getFramesByProject(\n this.projectId,\n 'active'\n );\n const childFrames = activeFrames.filter(\n (f: any) => f.parent_frame_id === parentFrameId\n );\n\n for (const childFrame of childFrames) {\n if (this.frameStack.isFrameActive(childFrame.frame_id)) {\n this.closeFrame(childFrame.frame_id);\n }\n }\n } catch (error: unknown) {\n logger.warn('Failed to close child frames', { parentFrameId, error });\n }\n }\n\n /**\n * Extract active artifacts from frame events\n */\n getActiveArtifacts(frameId: string): string[] {\n const events = this.frameDb.getFrameEvents(frameId);\n const artifacts: string[] = [];\n\n for (const event of events) {\n if (event.event_type === 'artifact' && event.payload.path) {\n artifacts.push(event.payload.path);\n }\n }\n\n return [...new Set(artifacts)];\n }\n\n /**\n * Extract constraints from frame inputs\n */\n extractConstraints(inputs: Record<string, any>): string[] {\n const constraints: string[] = [];\n\n if (inputs.constraints && Array.isArray(inputs.constraints)) {\n constraints.push(...inputs.constraints);\n }\n\n if (inputs.requirements && Array.isArray(inputs.requirements)) {\n constraints.push(...inputs.requirements);\n }\n\n if (inputs.limitations && Array.isArray(inputs.limitations)) {\n constraints.push(...inputs.limitations);\n }\n\n return constraints;\n }\n}\n\n// Re-export types for compatibility\nexport {\n Frame,\n FrameContext,\n Anchor,\n Event,\n FrameType,\n FrameState,\n FrameCreationOptions,\n FrameManagerConfig,\n DigestResult,\n} from './frame-types.js';\n"],
5
+ "mappings": "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",
6
6
  "names": ["Frame", "FrameContext", "Anchor", "Event", "FrameType", "FrameState", "FrameCreationOptions", "FrameManagerConfig", "DigestResult"]
7
7
  }
@@ -272,7 +272,8 @@ class SharedContextLayer {
272
272
  const frameWithData = frame;
273
273
  if (frameWithData.data) score += 0.2;
274
274
  if (frame.outputs && Object.keys(frame.outputs).length > 0) score += 0.2;
275
- if (frame.digest_text || frame.digest_json && Object.keys(frame.digest_json).length > 0) score += 0.1;
275
+ if (frame.digest_text || frame.digest_json && Object.keys(frame.digest_json).length > 0)
276
+ score += 0.1;
276
277
  if (frame.created_at) {
277
278
  const age = Date.now() - frame.created_at;
278
279
  const daysSinceCreation = age / (24 * 60 * 60 * 1e3);
@@ -297,7 +298,8 @@ class SharedContextLayer {
297
298
  if (frame.type) parts.push(`[${frame.type}]`);
298
299
  if (frame.name) parts.push(frame.name);
299
300
  if (frameWithData.title) parts.push(frameWithData.title);
300
- if (frameWithData.data?.error) parts.push(`Error: ${frameWithData.data.error}`);
301
+ if (frameWithData.data?.error)
302
+ parts.push(`Error: ${frameWithData.data.error}`);
301
303
  if (frameWithData.data?.resolution)
302
304
  parts.push(`Resolution: ${frameWithData.data.resolution}`);
303
305
  return parts.join(" - ").slice(0, 200);