@stackmemoryai/stackmemory 0.3.8 → 0.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +53 -0
  2. package/dist/agents/core/agent-task-manager.js +12 -1
  3. package/dist/agents/core/agent-task-manager.js.map +3 -3
  4. package/dist/agents/testing-agent.js +610 -0
  5. package/dist/agents/testing-agent.js.map +7 -0
  6. package/dist/cli/claude-sm.js +2 -2
  7. package/dist/cli/claude-sm.js.map +2 -2
  8. package/dist/cli/codex-sm.js +2 -2
  9. package/dist/cli/codex-sm.js.map +2 -2
  10. package/dist/cli/commands/handoff.js +65 -18
  11. package/dist/cli/commands/handoff.js.map +3 -3
  12. package/dist/cli/commands/onboard.js +3 -3
  13. package/dist/cli/commands/onboard.js.map +2 -2
  14. package/dist/cli/commands/quality.js +2 -2
  15. package/dist/cli/commands/quality.js.map +2 -2
  16. package/dist/cli/commands/skills.js +113 -28
  17. package/dist/cli/commands/skills.js.map +2 -2
  18. package/dist/cli/commands/test.js +282 -0
  19. package/dist/cli/commands/test.js.map +7 -0
  20. package/dist/cli/commands/worktree.js +28 -10
  21. package/dist/cli/commands/worktree.js.map +2 -2
  22. package/dist/cli/index.js +2 -0
  23. package/dist/cli/index.js.map +2 -2
  24. package/dist/core/config/config-manager.js +26 -0
  25. package/dist/core/config/config-manager.js.map +3 -3
  26. package/dist/core/context/frame-manager.js +139 -0
  27. package/dist/core/context/frame-manager.js.map +2 -2
  28. package/dist/core/context/recursive-context-manager.js +582 -0
  29. package/dist/core/context/recursive-context-manager.js.map +7 -0
  30. package/dist/core/context/refactored-frame-manager.js +180 -1
  31. package/dist/core/context/refactored-frame-manager.js.map +2 -2
  32. package/dist/core/execution/parallel-executor.js +254 -0
  33. package/dist/core/execution/parallel-executor.js.map +7 -0
  34. package/dist/core/utils/update-checker.js +2 -2
  35. package/dist/core/utils/update-checker.js.map +2 -2
  36. package/dist/integrations/anthropic/client.js +259 -0
  37. package/dist/integrations/anthropic/client.js.map +7 -0
  38. package/dist/integrations/claude-code/subagent-client-stub.js +16 -0
  39. package/dist/integrations/claude-code/subagent-client-stub.js.map +7 -0
  40. package/dist/integrations/claude-code/subagent-client.js +404 -0
  41. package/dist/integrations/claude-code/subagent-client.js.map +7 -0
  42. package/dist/skills/claude-skills.js +191 -0
  43. package/dist/skills/claude-skills.js.map +2 -2
  44. package/dist/skills/recursive-agent-orchestrator.js +559 -0
  45. package/dist/skills/recursive-agent-orchestrator.js.map +7 -0
  46. package/dist/skills/security-secrets-scanner.js +280 -0
  47. package/dist/skills/security-secrets-scanner.js.map +7 -0
  48. package/dist/skills/unified-rlm-orchestrator.js +400 -0
  49. package/dist/skills/unified-rlm-orchestrator.js.map +7 -0
  50. package/package.json +3 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/core/config/config-manager.ts"],
4
- "sourcesContent": ["/**\n * Configuration Manager for StackMemory\n * Handles loading, validation, and management of configuration\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport {\n StackMemoryConfig,\n ProfileConfig,\n DEFAULT_CONFIG,\n PRESET_PROFILES,\n ScoringWeights,\n} from './types.js';\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n suggestions: string[];\n}\n\nexport class ConfigManager {\n private config: StackMemoryConfig;\n private configPath: string;\n private fileWatcher?: fs.FSWatcher;\n private onChangeCallbacks: Array<(config: StackMemoryConfig) => void> = [];\n\n constructor(configPath?: string) {\n this.configPath =\n configPath || path.join(process.cwd(), '.stackmemory', 'config.yaml');\n this.config = this.loadConfig();\n }\n\n /**\n * Load configuration from file or use defaults\n */\n private loadConfig(): StackMemoryConfig {\n try {\n if (fs.existsSync(this.configPath)) {\n const content = fs.readFileSync(this.configPath, 'utf-8');\n const loaded = yaml.load(content) as Partial<StackMemoryConfig>;\n return this.mergeWithDefaults(loaded);\n }\n } catch (error: unknown) {\n console.warn(`Failed to load config from ${this.configPath}:`, error);\n }\n // Deep clone to prevent mutation of DEFAULT_CONFIG\n return this.mergeWithDefaults({});\n }\n\n /**\n * Merge loaded config with defaults\n */\n private mergeWithDefaults(\n loaded: Partial<StackMemoryConfig>\n ): StackMemoryConfig {\n const config: StackMemoryConfig = {\n version: loaded.version || DEFAULT_CONFIG.version,\n profile: loaded.profile,\n scoring: {\n weights: {\n ...DEFAULT_CONFIG.scoring.weights,\n ...loaded.scoring?.weights,\n },\n tool_scores: {\n ...DEFAULT_CONFIG.scoring.tool_scores,\n ...loaded.scoring?.tool_scores,\n },\n },\n retention: {\n local: {\n ...DEFAULT_CONFIG.retention.local,\n ...loaded.retention?.local,\n },\n remote: {\n ...DEFAULT_CONFIG.retention.remote,\n ...loaded.retention?.remote,\n },\n generational_gc: {\n ...DEFAULT_CONFIG.retention.generational_gc,\n ...loaded.retention?.generational_gc,\n },\n },\n performance: { ...DEFAULT_CONFIG.performance, ...loaded.performance },\n profiles: { ...PRESET_PROFILES, ...loaded.profiles },\n };\n\n // Apply active profile if specified\n if (config.profile && config.profiles?.[config.profile]) {\n this.applyProfile(config, config.profiles[config.profile]);\n }\n\n return config;\n }\n\n /**\n * Apply a profile to the configuration\n */\n private applyProfile(\n config: StackMemoryConfig,\n profile: ProfileConfig\n ): void {\n if (profile.scoring) {\n if (profile.scoring.weights) {\n config.scoring.weights = {\n ...config.scoring.weights,\n ...profile.scoring.weights,\n };\n }\n if (profile.scoring.tool_scores) {\n config.scoring.tool_scores = {\n ...config.scoring.tool_scores,\n ...profile.scoring.tool_scores,\n };\n }\n }\n\n if (profile.retention) {\n if (profile.retention.local) {\n config.retention.local = {\n ...config.retention.local,\n ...profile.retention.local,\n };\n }\n if (profile.retention.remote) {\n config.retention.remote = {\n ...config.retention.remote,\n ...profile.retention.remote,\n };\n }\n if (profile.retention.generational_gc) {\n config.retention.generational_gc = {\n ...config.retention.generational_gc,\n ...profile.retention.generational_gc,\n };\n }\n }\n\n if (profile.performance) {\n config.performance = { ...config.performance, ...profile.performance };\n }\n }\n\n /**\n * Validate configuration\n */\n validate(): ValidationResult {\n const result: ValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n suggestions: [],\n };\n\n // Validate weights sum to 1.0\n const weights = this.config.scoring.weights;\n const weightSum =\n weights.base + weights.impact + weights.persistence + weights.reference;\n if (Math.abs(weightSum - 1.0) > 0.001) {\n result.errors.push(\n `Weights must sum to 1.0 (current: ${weightSum.toFixed(3)})`\n );\n result.valid = false;\n }\n\n // Validate weight ranges\n Object.entries(weights).forEach(([key, value]) => {\n if (value < 0 || value > 1) {\n result.errors.push(\n `Weight ${key} must be between 0 and 1 (current: ${value})`\n );\n result.valid = false;\n }\n });\n\n // Validate tool scores\n Object.entries(this.config.scoring.tool_scores).forEach(([tool, score]) => {\n if (score !== undefined && (score < 0 || score > 1)) {\n result.errors.push(\n `Tool score for ${tool} must be between 0 and 1 (current: ${score})`\n );\n result.valid = false;\n }\n });\n\n // Validate retention periods are ordered\n const youngMs = this.parseDuration(this.config.retention.local.young);\n const matureMs = this.parseDuration(this.config.retention.local.mature);\n const oldMs = this.parseDuration(this.config.retention.local.old);\n\n if (youngMs >= matureMs) {\n result.errors.push(\n 'Young retention period must be less than mature period'\n );\n result.valid = false;\n }\n if (matureMs >= oldMs) {\n result.errors.push(\n 'Mature retention period must be less than old period'\n );\n result.valid = false;\n }\n\n // Validate max size\n const maxSize = this.parseSize(this.config.retention.local.max_size);\n const availableSpace = this.getAvailableDiskSpace();\n if (availableSpace > 0 && maxSize > availableSpace) {\n result.warnings.push(\n `max_size (${this.config.retention.local.max_size}) exceeds available disk space`\n );\n }\n\n // Performance warnings\n if (this.config.performance.retrieval_timeout_ms < 100) {\n result.warnings.push(\n 'retrieval_timeout_ms < 100ms may be too aggressive'\n );\n }\n\n if (this.config.performance.max_stack_depth > 10000) {\n result.warnings.push('max_stack_depth > 10000 may impact performance');\n }\n\n // Suggestions\n if (!this.config.profile) {\n result.suggestions.push('Consider using a profile for your use case');\n }\n\n if (\n this.config?.scoring?.tool_scores?.search &&\n this.config.scoring.tool_scores.search < 0.5\n ) {\n result.suggestions.push(\n 'Search tool score seems low - consider increasing for better discovery'\n );\n }\n\n return result;\n }\n\n /**\n * Parse duration string to milliseconds\n */\n private parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)([hdwm])$/);\n if (!match) return 0;\n\n const value = parseInt(match[1]);\n const unit = match[2];\n\n const multipliers: Record<string, number> = {\n h: 3600000, // hours\n d: 86400000, // days\n w: 604800000, // weeks\n m: 2592000000, // months (30 days)\n };\n\n return value * (multipliers[unit] || 0);\n }\n\n /**\n * Parse size string to bytes\n */\n private parseSize(size: string): number {\n const match = size.match(/^(\\d+(?:\\.\\d+)?)([KMGT]B)?$/i);\n if (!match) return 0;\n\n const value = parseFloat(match[1]);\n const unit = match[2]?.toUpperCase() || 'B';\n\n const multipliers: Record<string, number> = {\n B: 1,\n KB: 1024,\n MB: 1024 * 1024,\n GB: 1024 * 1024 * 1024,\n TB: 1024 * 1024 * 1024 * 1024,\n };\n\n return value * (multipliers[unit] || 1);\n }\n\n /**\n * Get available disk space (simplified)\n */\n private getAvailableDiskSpace(): number {\n // This would need platform-specific implementation\n // For now, return 0 to skip validation\n return 0;\n }\n\n /**\n * Save configuration to file\n */\n save(): void {\n const dir = path.dirname(this.configPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n const content = yaml.dump(this.config, {\n indent: 2,\n lineWidth: 120,\n noRefs: true,\n });\n\n fs.writeFileSync(this.configPath, content, 'utf-8');\n }\n\n /**\n * Get current configuration\n */\n getConfig(): StackMemoryConfig {\n return { ...this.config };\n }\n\n /**\n * Set active profile\n */\n setProfile(profileName: string): boolean {\n const allProfiles = { ...PRESET_PROFILES, ...this.config.profiles };\n if (!allProfiles[profileName]) {\n return false;\n }\n\n // Apply the profile to current config\n this.config.profile = profileName;\n this.applyProfile(this.config, allProfiles[profileName]);\n this.notifyChange();\n return true;\n }\n\n /**\n * Update weights\n */\n updateWeights(weights: Partial<ScoringWeights>): void {\n this.config.scoring.weights = {\n ...this.config.scoring.weights,\n ...weights,\n };\n this.notifyChange();\n }\n\n /**\n * Update tool scores\n */\n updateToolScores(scores: Record<string, number>): void {\n this.config.scoring.tool_scores = {\n ...this.config.scoring.tool_scores,\n ...scores,\n };\n this.notifyChange();\n }\n\n /**\n * Enable hot reload\n */\n enableHotReload(): void {\n if (this.fileWatcher) return;\n\n if (fs.existsSync(this.configPath)) {\n this.fileWatcher = fs.watch(this.configPath, (eventType) => {\n if (eventType === 'change') {\n const newConfig = this.loadConfig();\n const validation = this.validate();\n\n if (validation.valid) {\n this.config = newConfig;\n this.notifyChange();\n console.log('Configuration reloaded');\n } else {\n console.error(\n 'Invalid configuration, keeping previous:',\n validation.errors\n );\n }\n }\n });\n }\n }\n\n /**\n * Disable hot reload\n */\n disableHotReload(): void {\n if (this.fileWatcher) {\n this.fileWatcher.close();\n this.fileWatcher = undefined;\n }\n }\n\n /**\n * Register change callback\n */\n onChange(callback: (config: StackMemoryConfig) => void): void {\n this.onChangeCallbacks.push(callback);\n }\n\n /**\n * Notify all change callbacks\n */\n private notifyChange(): void {\n const config = this.getConfig();\n this.onChangeCallbacks.forEach((cb) => cb(config));\n }\n\n /**\n * Calculate importance score for a tool\n */\n calculateScore(\n tool: string,\n additionalFactors?: {\n filesAffected?: number;\n isPermanent?: boolean;\n referenceCount?: number;\n }\n ): number {\n const baseScore = this.config.scoring.tool_scores[tool] || 0.5;\n const weights = this.config.scoring.weights;\n\n let score = baseScore * weights.base;\n\n if (additionalFactors) {\n // Impact multiplier (files affected)\n if (additionalFactors.filesAffected !== undefined) {\n const impactMultiplier = Math.min(\n additionalFactors.filesAffected / 10,\n 1\n );\n score += impactMultiplier * weights.impact;\n }\n\n // Persistence bonus\n if (additionalFactors.isPermanent) {\n score += 0.2 * weights.persistence;\n }\n\n // Reference count\n if (additionalFactors.referenceCount !== undefined) {\n const refMultiplier = Math.min(\n additionalFactors.referenceCount / 100,\n 1\n );\n score += refMultiplier * weights.reference;\n }\n }\n\n return Math.min(Math.max(score, 0), 1); // Clamp to [0, 1]\n }\n\n /**\n * Get available profiles\n */\n getProfiles(): Record<string, ProfileConfig> {\n return { ...PRESET_PROFILES, ...this.config.profiles };\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
4
+ "sourcesContent": ["/**\n * Configuration Manager for StackMemory\n * Handles loading, validation, and management of configuration\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport {\n StackMemoryConfig,\n ProfileConfig,\n DEFAULT_CONFIG,\n PRESET_PROFILES,\n ScoringWeights,\n} from './types.js';\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n suggestions: string[];\n}\n\nexport class ConfigManager {\n private static instance: ConfigManager | null = null;\n private config: StackMemoryConfig;\n private configPath: string;\n private fileWatcher?: fs.FSWatcher;\n private onChangeCallbacks: Array<(config: StackMemoryConfig) => void> = [];\n\n constructor(configPath?: string) {\n this.configPath =\n configPath || path.join(process.cwd(), '.stackmemory', 'config.yaml');\n this.config = this.loadConfig();\n }\n\n /**\n * Get singleton instance of ConfigManager\n */\n public static getInstance(configPath?: string): ConfigManager {\n if (!ConfigManager.instance) {\n ConfigManager.instance = new ConfigManager(configPath);\n }\n return ConfigManager.instance;\n }\n\n /**\n * Load configuration from file or use defaults\n */\n private loadConfig(): StackMemoryConfig {\n try {\n if (fs.existsSync(this.configPath)) {\n const content = fs.readFileSync(this.configPath, 'utf-8');\n const loaded = yaml.load(content) as Partial<StackMemoryConfig>;\n return this.mergeWithDefaults(loaded);\n }\n } catch (error: unknown) {\n console.warn(`Failed to load config from ${this.configPath}:`, error);\n }\n // Deep clone to prevent mutation of DEFAULT_CONFIG\n return this.mergeWithDefaults({});\n }\n\n /**\n * Merge loaded config with defaults\n */\n private mergeWithDefaults(\n loaded: Partial<StackMemoryConfig>\n ): StackMemoryConfig {\n const config: StackMemoryConfig = {\n version: loaded.version || DEFAULT_CONFIG.version,\n profile: loaded.profile,\n scoring: {\n weights: {\n ...DEFAULT_CONFIG.scoring.weights,\n ...loaded.scoring?.weights,\n },\n tool_scores: {\n ...DEFAULT_CONFIG.scoring.tool_scores,\n ...loaded.scoring?.tool_scores,\n },\n },\n retention: {\n local: {\n ...DEFAULT_CONFIG.retention.local,\n ...loaded.retention?.local,\n },\n remote: {\n ...DEFAULT_CONFIG.retention.remote,\n ...loaded.retention?.remote,\n },\n generational_gc: {\n ...DEFAULT_CONFIG.retention.generational_gc,\n ...loaded.retention?.generational_gc,\n },\n },\n performance: { ...DEFAULT_CONFIG.performance, ...loaded.performance },\n profiles: { ...PRESET_PROFILES, ...loaded.profiles },\n };\n\n // Apply active profile if specified\n if (config.profile && config.profiles?.[config.profile]) {\n this.applyProfile(config, config.profiles[config.profile]);\n }\n\n return config;\n }\n\n /**\n * Apply a profile to the configuration\n */\n private applyProfile(\n config: StackMemoryConfig,\n profile: ProfileConfig\n ): void {\n if (profile.scoring) {\n if (profile.scoring.weights) {\n config.scoring.weights = {\n ...config.scoring.weights,\n ...profile.scoring.weights,\n };\n }\n if (profile.scoring.tool_scores) {\n config.scoring.tool_scores = {\n ...config.scoring.tool_scores,\n ...profile.scoring.tool_scores,\n };\n }\n }\n\n if (profile.retention) {\n if (profile.retention.local) {\n config.retention.local = {\n ...config.retention.local,\n ...profile.retention.local,\n };\n }\n if (profile.retention.remote) {\n config.retention.remote = {\n ...config.retention.remote,\n ...profile.retention.remote,\n };\n }\n if (profile.retention.generational_gc) {\n config.retention.generational_gc = {\n ...config.retention.generational_gc,\n ...profile.retention.generational_gc,\n };\n }\n }\n\n if (profile.performance) {\n config.performance = { ...config.performance, ...profile.performance };\n }\n }\n\n /**\n * Validate configuration\n */\n validate(): ValidationResult {\n const result: ValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n suggestions: [],\n };\n\n // Validate weights sum to 1.0\n const weights = this.config.scoring.weights;\n const weightSum =\n weights.base + weights.impact + weights.persistence + weights.reference;\n if (Math.abs(weightSum - 1.0) > 0.001) {\n result.errors.push(\n `Weights must sum to 1.0 (current: ${weightSum.toFixed(3)})`\n );\n result.valid = false;\n }\n\n // Validate weight ranges\n Object.entries(weights).forEach(([key, value]) => {\n if (value < 0 || value > 1) {\n result.errors.push(\n `Weight ${key} must be between 0 and 1 (current: ${value})`\n );\n result.valid = false;\n }\n });\n\n // Validate tool scores\n Object.entries(this.config.scoring.tool_scores).forEach(([tool, score]) => {\n if (score !== undefined && (score < 0 || score > 1)) {\n result.errors.push(\n `Tool score for ${tool} must be between 0 and 1 (current: ${score})`\n );\n result.valid = false;\n }\n });\n\n // Validate retention periods are ordered\n const youngMs = this.parseDuration(this.config.retention.local.young);\n const matureMs = this.parseDuration(this.config.retention.local.mature);\n const oldMs = this.parseDuration(this.config.retention.local.old);\n\n if (youngMs >= matureMs) {\n result.errors.push(\n 'Young retention period must be less than mature period'\n );\n result.valid = false;\n }\n if (matureMs >= oldMs) {\n result.errors.push(\n 'Mature retention period must be less than old period'\n );\n result.valid = false;\n }\n\n // Validate max size\n const maxSize = this.parseSize(this.config.retention.local.max_size);\n const availableSpace = this.getAvailableDiskSpace();\n if (availableSpace > 0 && maxSize > availableSpace) {\n result.warnings.push(\n `max_size (${this.config.retention.local.max_size}) exceeds available disk space`\n );\n }\n\n // Performance warnings\n if (this.config.performance.retrieval_timeout_ms < 100) {\n result.warnings.push(\n 'retrieval_timeout_ms < 100ms may be too aggressive'\n );\n }\n\n if (this.config.performance.max_stack_depth > 10000) {\n result.warnings.push('max_stack_depth > 10000 may impact performance');\n }\n\n // Suggestions\n if (!this.config.profile) {\n result.suggestions.push('Consider using a profile for your use case');\n }\n\n if (\n this.config?.scoring?.tool_scores?.search &&\n this.config.scoring.tool_scores.search < 0.5\n ) {\n result.suggestions.push(\n 'Search tool score seems low - consider increasing for better discovery'\n );\n }\n\n return result;\n }\n\n /**\n * Parse duration string to milliseconds\n */\n private parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)([hdwm])$/);\n if (!match) return 0;\n\n const value = parseInt(match[1]);\n const unit = match[2];\n\n const multipliers: Record<string, number> = {\n h: 3600000, // hours\n d: 86400000, // days\n w: 604800000, // weeks\n m: 2592000000, // months (30 days)\n };\n\n return value * (multipliers[unit] || 0);\n }\n\n /**\n * Parse size string to bytes\n */\n private parseSize(size: string): number {\n const match = size.match(/^(\\d+(?:\\.\\d+)?)([KMGT]B)?$/i);\n if (!match) return 0;\n\n const value = parseFloat(match[1]);\n const unit = match[2]?.toUpperCase() || 'B';\n\n const multipliers: Record<string, number> = {\n B: 1,\n KB: 1024,\n MB: 1024 * 1024,\n GB: 1024 * 1024 * 1024,\n TB: 1024 * 1024 * 1024 * 1024,\n };\n\n return value * (multipliers[unit] || 1);\n }\n\n /**\n * Get available disk space (simplified)\n */\n private getAvailableDiskSpace(): number {\n // This would need platform-specific implementation\n // For now, return 0 to skip validation\n return 0;\n }\n\n /**\n * Save configuration to file\n */\n save(): void {\n const dir = path.dirname(this.configPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n const content = yaml.dump(this.config, {\n indent: 2,\n lineWidth: 120,\n noRefs: true,\n });\n\n fs.writeFileSync(this.configPath, content, 'utf-8');\n }\n\n /**\n * Get current configuration\n */\n getConfig(): StackMemoryConfig {\n return { ...this.config };\n }\n\n /**\n * Get a specific configuration value by path\n * Example: config.get('project.id') returns config.project.id\n */\n get(path: string): any {\n const keys = path.split('.');\n let value: any = this.config;\n \n for (const key of keys) {\n if (value && typeof value === 'object' && key in value) {\n value = value[key];\n } else {\n return undefined;\n }\n }\n \n return value;\n }\n\n /**\n * Set active profile\n */\n setProfile(profileName: string): boolean {\n const allProfiles = { ...PRESET_PROFILES, ...this.config.profiles };\n if (!allProfiles[profileName]) {\n return false;\n }\n\n // Apply the profile to current config\n this.config.profile = profileName;\n this.applyProfile(this.config, allProfiles[profileName]);\n this.notifyChange();\n return true;\n }\n\n /**\n * Update weights\n */\n updateWeights(weights: Partial<ScoringWeights>): void {\n this.config.scoring.weights = {\n ...this.config.scoring.weights,\n ...weights,\n };\n this.notifyChange();\n }\n\n /**\n * Update tool scores\n */\n updateToolScores(scores: Record<string, number>): void {\n this.config.scoring.tool_scores = {\n ...this.config.scoring.tool_scores,\n ...scores,\n };\n this.notifyChange();\n }\n\n /**\n * Enable hot reload\n */\n enableHotReload(): void {\n if (this.fileWatcher) return;\n\n if (fs.existsSync(this.configPath)) {\n this.fileWatcher = fs.watch(this.configPath, (eventType) => {\n if (eventType === 'change') {\n const newConfig = this.loadConfig();\n const validation = this.validate();\n\n if (validation.valid) {\n this.config = newConfig;\n this.notifyChange();\n console.log('Configuration reloaded');\n } else {\n console.error(\n 'Invalid configuration, keeping previous:',\n validation.errors\n );\n }\n }\n });\n }\n }\n\n /**\n * Disable hot reload\n */\n disableHotReload(): void {\n if (this.fileWatcher) {\n this.fileWatcher.close();\n this.fileWatcher = undefined;\n }\n }\n\n /**\n * Register change callback\n */\n onChange(callback: (config: StackMemoryConfig) => void): void {\n this.onChangeCallbacks.push(callback);\n }\n\n /**\n * Notify all change callbacks\n */\n private notifyChange(): void {\n const config = this.getConfig();\n this.onChangeCallbacks.forEach((cb) => cb(config));\n }\n\n /**\n * Calculate importance score for a tool\n */\n calculateScore(\n tool: string,\n additionalFactors?: {\n filesAffected?: number;\n isPermanent?: boolean;\n referenceCount?: number;\n }\n ): number {\n const baseScore = this.config.scoring.tool_scores[tool] || 0.5;\n const weights = this.config.scoring.weights;\n\n let score = baseScore * weights.base;\n\n if (additionalFactors) {\n // Impact multiplier (files affected)\n if (additionalFactors.filesAffected !== undefined) {\n const impactMultiplier = Math.min(\n additionalFactors.filesAffected / 10,\n 1\n );\n score += impactMultiplier * weights.impact;\n }\n\n // Persistence bonus\n if (additionalFactors.isPermanent) {\n score += 0.2 * weights.persistence;\n }\n\n // Reference count\n if (additionalFactors.referenceCount !== undefined) {\n const refMultiplier = Math.min(\n additionalFactors.referenceCount / 100,\n 1\n );\n score += refMultiplier * weights.reference;\n }\n }\n\n return Math.min(Math.max(score, 0), 1); // Clamp to [0, 1]\n }\n\n /**\n * Get available profiles\n */\n getProfiles(): Record<string, ProfileConfig> {\n return { ...PRESET_PROFILES, ...this.config.profiles };\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["path"]
7
7
  }
@@ -8,6 +8,8 @@ import {
8
8
  } from "../errors/index.js";
9
9
  import { sessionManager, FrameQueryMode } from "../session/index.js";
10
10
  import { contextBridge } from "./context-bridge.js";
11
+ const MAX_FRAME_DEPTH = 100;
12
+ const DEFAULT_MAX_DEPTH = 100;
11
13
  function getEnv(key, defaultValue) {
12
14
  const value = process.env[key];
13
15
  if (value === void 0) {
@@ -27,6 +29,7 @@ class FrameManager {
27
29
  activeStack = [];
28
30
  // Stack of active frame IDs
29
31
  queryMode = FrameQueryMode.PROJECT_ACTIVE;
32
+ maxFrameDepth = DEFAULT_MAX_DEPTH;
30
33
  constructor(db, projectId, runIdOrOptions) {
31
34
  this.db = db;
32
35
  this.projectId = projectId;
@@ -37,6 +40,7 @@ class FrameManager {
37
40
  } else if (runIdOrOptions) {
38
41
  runId = runIdOrOptions.runId;
39
42
  skipContextBridge = runIdOrOptions.skipContextBridge || false;
43
+ this.maxFrameDepth = runIdOrOptions.maxFrameDepth || DEFAULT_MAX_DEPTH;
40
44
  }
41
45
  const session = sessionManager.getCurrentSession();
42
46
  if (session) {
@@ -258,6 +262,34 @@ class FrameManager {
258
262
  const frameId = uuidv4();
259
263
  const parentFrameId = options.parentFrameId || this.getCurrentFrameId();
260
264
  const depth = parentFrameId ? this.getFrameDepth(parentFrameId) + 1 : 0;
265
+ if (depth > this.maxFrameDepth) {
266
+ throw new FrameError(
267
+ `Maximum frame depth exceeded: ${depth} > ${this.maxFrameDepth}`,
268
+ ErrorCode.FRAME_STACK_OVERFLOW,
269
+ {
270
+ currentDepth: depth,
271
+ maxDepth: this.maxFrameDepth,
272
+ frameId,
273
+ parentFrameId,
274
+ frameName: options.name
275
+ }
276
+ );
277
+ }
278
+ if (parentFrameId) {
279
+ const cycle = this.detectCycle(frameId, parentFrameId);
280
+ if (cycle) {
281
+ throw new FrameError(
282
+ `Circular reference detected in frame hierarchy`,
283
+ ErrorCode.FRAME_CYCLE_DETECTED,
284
+ {
285
+ frameId,
286
+ parentFrameId,
287
+ cycle,
288
+ frameName: options.name
289
+ }
290
+ );
291
+ }
292
+ }
261
293
  const frame = {
262
294
  frame_id: frameId,
263
295
  run_id: this.currentRunId,
@@ -815,6 +847,113 @@ Activity: ${eventCount} events, ${structured.tool_calls_count} tool calls`;
815
847
  const artifacts = this.getFrameEvents(frameId).filter((e) => e.event_type === "artifact").map((e) => e.payload.ref).filter(Boolean);
816
848
  return artifacts;
817
849
  }
850
+ /**
851
+ * Detect if setting a parent frame would create a cycle in the frame hierarchy.
852
+ * Returns the cycle path if detected, or null if no cycle.
853
+ * @param childFrameId - The frame that would be the child
854
+ * @param parentFrameId - The proposed parent frame
855
+ * @returns Array of frame IDs forming the cycle, or null if no cycle
856
+ */
857
+ detectCycle(childFrameId, parentFrameId) {
858
+ const visited = /* @__PURE__ */ new Set();
859
+ const path = [];
860
+ let currentId = parentFrameId;
861
+ while (currentId) {
862
+ if (visited.has(currentId)) {
863
+ const cycleStart = path.indexOf(currentId);
864
+ return path.slice(cycleStart).concat(currentId);
865
+ }
866
+ if (currentId === childFrameId) {
867
+ return path.concat([currentId, childFrameId]);
868
+ }
869
+ visited.add(currentId);
870
+ path.push(currentId);
871
+ const frame = this.getFrame(currentId);
872
+ if (!frame) {
873
+ break;
874
+ }
875
+ currentId = frame.parent_frame_id;
876
+ if (path.length > this.maxFrameDepth) {
877
+ throw new FrameError(
878
+ `Frame hierarchy traversal exceeded maximum depth during cycle detection`,
879
+ ErrorCode.FRAME_STACK_OVERFLOW,
880
+ {
881
+ depth: path.length,
882
+ maxDepth: this.maxFrameDepth,
883
+ path
884
+ }
885
+ );
886
+ }
887
+ }
888
+ return null;
889
+ }
890
+ /**
891
+ * Update parent frame of an existing frame (with cycle detection)
892
+ * @param frameId - The frame to update
893
+ * @param newParentFrameId - The new parent frame ID
894
+ */
895
+ updateParentFrame(frameId, newParentFrameId) {
896
+ const frame = this.getFrame(frameId);
897
+ if (!frame) {
898
+ throw new FrameError(
899
+ `Frame not found: ${frameId}`,
900
+ ErrorCode.FRAME_NOT_FOUND,
901
+ { frameId }
902
+ );
903
+ }
904
+ if (newParentFrameId) {
905
+ const cycle = this.detectCycle(frameId, newParentFrameId);
906
+ if (cycle) {
907
+ throw new FrameError(
908
+ `Cannot set parent: would create circular reference`,
909
+ ErrorCode.FRAME_CYCLE_DETECTED,
910
+ {
911
+ frameId,
912
+ newParentFrameId,
913
+ cycle,
914
+ currentParentId: frame.parent_frame_id
915
+ }
916
+ );
917
+ }
918
+ const newParentFrame = this.getFrame(newParentFrameId);
919
+ if (newParentFrame) {
920
+ const newDepth = newParentFrame.depth + 1;
921
+ if (newDepth > this.maxFrameDepth) {
922
+ throw new FrameError(
923
+ `Cannot set parent: would exceed maximum frame depth`,
924
+ ErrorCode.FRAME_STACK_OVERFLOW,
925
+ {
926
+ frameId,
927
+ newParentFrameId,
928
+ newDepth,
929
+ maxDepth: this.maxFrameDepth
930
+ }
931
+ );
932
+ }
933
+ }
934
+ }
935
+ try {
936
+ this.db.prepare(
937
+ `UPDATE frames SET parent_frame_id = ? WHERE frame_id = ?`
938
+ ).run(newParentFrameId, frameId);
939
+ logger.info("Updated parent frame", {
940
+ frameId,
941
+ oldParentId: frame.parent_frame_id,
942
+ newParentId: newParentFrameId
943
+ });
944
+ } catch (error) {
945
+ throw new DatabaseError(
946
+ `Failed to update parent frame`,
947
+ ErrorCode.DB_UPDATE_FAILED,
948
+ {
949
+ frameId,
950
+ newParentFrameId,
951
+ operation: "updateParentFrame"
952
+ },
953
+ error instanceof Error ? error : void 0
954
+ );
955
+ }
956
+ }
818
957
  }
819
958
  export {
820
959
  FrameManager
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/core/context/frame-manager.ts"],
4
- "sourcesContent": ["/**\n * StackMemory Frame Manager - Call Stack Implementation\n * Manages nested frames representing the call stack of work\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 DatabaseError,\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';\nimport { contextBridge } from './context-bridge.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// Frame types based on architecture\nexport type FrameType =\n | 'task'\n | 'subtask'\n | 'tool_scope'\n | 'review'\n | 'write'\n | 'debug';\nexport type FrameState = 'active' | 'closed';\n\nexport interface Frame {\n frame_id: string;\n run_id: string;\n project_id: string;\n parent_frame_id?: string;\n depth: number;\n type: FrameType;\n name: string;\n state: FrameState;\n inputs: Record<string, any>;\n outputs: Record<string, any>;\n digest_text?: string;\n digest_json: Record<string, any>;\n created_at: number;\n closed_at?: number;\n}\n\nexport interface FrameContext {\n frameId: string;\n header: {\n goal: string;\n constraints?: string[];\n definitions?: Record<string, string>;\n };\n anchors: Anchor[];\n recentEvents: Event[];\n activeArtifacts: string[];\n}\n\nexport interface Anchor {\n anchor_id: string;\n frame_id: string;\n type:\n | 'FACT'\n | 'DECISION'\n | 'CONSTRAINT'\n | 'INTERFACE_CONTRACT'\n | 'TODO'\n | 'RISK';\n text: string;\n priority: number;\n metadata: Record<string, any>;\n}\n\nexport interface Event {\n event_id: string;\n frame_id: string;\n run_id: string;\n seq: number;\n event_type:\n | 'user_message'\n | 'assistant_message'\n | 'tool_call'\n | 'tool_result'\n | 'decision'\n | 'constraint'\n | 'artifact'\n | 'observation';\n payload: Record<string, any>;\n ts: number;\n}\n\nexport interface FrameManagerOptions {\n skipContextBridge?: boolean;\n runId?: string;\n}\n\nexport class FrameManager {\n private db: Database.Database;\n private currentRunId: string;\n private sessionId: string;\n private projectId: string;\n private activeStack: string[] = []; // Stack of active frame IDs\n private queryMode: FrameQueryMode = FrameQueryMode.PROJECT_ACTIVE;\n\n constructor(\n db: Database.Database,\n projectId: string,\n runIdOrOptions?: string | FrameManagerOptions\n ) {\n this.db = db;\n this.projectId = projectId;\n\n // Handle both legacy string runId and new options object\n let runId: string | undefined;\n let skipContextBridge = false;\n\n if (typeof runIdOrOptions === 'string') {\n runId = runIdOrOptions;\n } else if (runIdOrOptions) {\n runId = runIdOrOptions.runId;\n skipContextBridge = runIdOrOptions.skipContextBridge || false;\n }\n\n // Use session manager for run ID if available\n const session = sessionManager.getCurrentSession();\n if (session) {\n this.currentRunId = session.runId;\n this.sessionId = session.sessionId;\n } else {\n this.currentRunId = runId || uuidv4();\n this.sessionId = this.currentRunId; // Fallback for legacy behavior\n }\n\n this.initializeSchema();\n this.loadActiveStack();\n\n // Initialize context bridge for automatic shared context\n // Skip in test environment, when explicitly requested, or for CLI usage\n const shouldInitializeBridge =\n !skipContextBridge &&\n process.env['NODE_ENV'] !== 'test' &&\n !process.env['VITEST'] &&\n !process.env['STACKMEMORY_CLI'];\n\n if (shouldInitializeBridge) {\n contextBridge\n .initialize(this, {\n autoSync: true,\n syncInterval: 60000, // 1 minute\n minFrameScore: 0.5, // Sync frames above 0.5 score\n importantTags: ['decision', 'error', 'milestone', 'learning'],\n })\n .catch((error) => {\n logger.warn('Failed to initialize context bridge', { error });\n });\n }\n }\n\n setQueryMode(mode: FrameQueryMode): void {\n this.queryMode = mode;\n this.loadActiveStack(); // Reload with new mode\n }\n\n private initializeSchema() {\n const errorHandler = createErrorHandler({\n operation: 'initializeSchema',\n projectId: this.projectId,\n runId: this.currentRunId,\n });\n\n try {\n // Enhanced frames table matching architecture\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS frames (\n frame_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n parent_frame_id TEXT REFERENCES frames(frame_id),\n depth INTEGER NOT NULL DEFAULT 0,\n type TEXT NOT NULL,\n name TEXT NOT NULL,\n state TEXT DEFAULT 'active',\n inputs TEXT DEFAULT '{}',\n outputs TEXT DEFAULT '{}',\n digest_text TEXT,\n digest_json TEXT DEFAULT '{}',\n created_at INTEGER DEFAULT (unixepoch()),\n closed_at INTEGER\n );\n\n CREATE TABLE IF NOT EXISTS events (\n event_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n frame_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n event_type TEXT NOT NULL,\n payload TEXT NOT NULL,\n ts INTEGER DEFAULT (unixepoch()),\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id)\n );\n\n CREATE TABLE IF NOT EXISTS anchors (\n anchor_id TEXT PRIMARY KEY,\n frame_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n type TEXT NOT NULL,\n text TEXT NOT NULL,\n priority INTEGER DEFAULT 0,\n created_at INTEGER DEFAULT (unixepoch()),\n metadata TEXT DEFAULT '{}',\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id)\n );\n\n CREATE TABLE IF NOT EXISTS handoff_requests (\n request_id TEXT PRIMARY KEY,\n source_stack_id TEXT NOT NULL,\n target_stack_id TEXT NOT NULL,\n frame_ids TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n created_at INTEGER DEFAULT (unixepoch()),\n expires_at INTEGER,\n target_user_id TEXT,\n message TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_frames_run ON frames(run_id);\n CREATE INDEX IF NOT EXISTS idx_frames_parent ON frames(parent_frame_id);\n CREATE INDEX IF NOT EXISTS idx_frames_state ON frames(state);\n CREATE INDEX IF NOT EXISTS idx_events_frame ON events(frame_id);\n CREATE INDEX IF NOT EXISTS idx_events_seq ON events(frame_id, seq);\n CREATE INDEX IF NOT EXISTS idx_anchors_frame ON anchors(frame_id);\n CREATE INDEX IF NOT EXISTS idx_handoff_requests_status ON handoff_requests(status);\n CREATE INDEX IF NOT EXISTS idx_handoff_requests_target ON handoff_requests(target_stack_id);\n `);\n } catch (error: unknown) {\n const dbError = errorHandler(error, {\n operation: 'initializeSchema',\n schema: 'frames',\n });\n\n if (dbError instanceof DatabaseError) {\n throw new DatabaseError(\n 'Failed to initialize frame database schema',\n ErrorCode.DB_MIGRATION_FAILED,\n {\n projectId: this.projectId,\n operation: 'initializeSchema',\n originalError: error,\n },\n error instanceof Error ? error : undefined\n );\n }\n throw dbError;\n }\n }\n\n private loadActiveStack() {\n const errorHandler = createErrorHandler({\n operation: 'loadActiveStack',\n runId: this.currentRunId,\n projectId: this.projectId,\n });\n\n try {\n let query: string;\n let params: any[];\n\n // Build query based on query mode\n switch (this.queryMode) {\n case FrameQueryMode.ALL_ACTIVE:\n query = `\n SELECT frame_id, parent_frame_id, depth\n FROM frames\n WHERE state = 'active'\n ORDER BY created_at DESC, depth ASC\n `;\n params = [];\n break;\n\n case FrameQueryMode.PROJECT_ACTIVE:\n query = `\n SELECT frame_id, parent_frame_id, depth, run_id\n FROM frames\n WHERE state = 'active' AND project_id = ?\n ORDER BY created_at DESC, depth ASC\n `;\n params = [this.projectId];\n break;\n\n case FrameQueryMode.HISTORICAL:\n query = `\n SELECT frame_id, parent_frame_id, depth\n FROM frames\n WHERE project_id = ?\n ORDER BY created_at DESC, depth ASC\n `;\n params = [this.projectId];\n break;\n\n case FrameQueryMode.CURRENT_SESSION:\n default:\n query = `\n SELECT frame_id, parent_frame_id, depth\n FROM frames\n WHERE run_id = ? AND state = 'active'\n ORDER BY depth ASC\n `;\n params = [this.currentRunId];\n break;\n }\n\n const activeFrames = this.db.prepare(query).all(...params) as Frame[];\n\n // Rebuild stack order\n this.activeStack = this.buildStackOrder(activeFrames);\n\n logger.info('Loaded active stack', {\n runId: this.currentRunId,\n stackDepth: this.activeStack.length,\n activeFrames: this.activeStack,\n queryMode: this.queryMode,\n });\n } catch (error: unknown) {\n const dbError = errorHandler(error, {\n query: 'Frame loading query',\n runId: this.currentRunId,\n queryMode: this.queryMode,\n });\n\n if (dbError instanceof DatabaseError) {\n throw new DatabaseError(\n 'Failed to load active frame stack',\n ErrorCode.DB_QUERY_FAILED,\n {\n runId: this.currentRunId,\n projectId: this.projectId,\n operation: 'loadActiveStack',\n },\n error instanceof Error ? error : undefined\n );\n }\n throw dbError;\n }\n }\n\n private buildStackOrder(\n frames: Pick<Frame, 'frame_id' | 'parent_frame_id' | 'depth'>[]\n ): string[] {\n const stack: string[] = [];\n\n // Find root frame (no parent)\n const rootFrame = frames.find((f) => !f.parent_frame_id);\n if (!rootFrame) return [];\n\n // Build stack by following parent-child relationships\n let currentFrame = rootFrame;\n stack.push(currentFrame.frame_id);\n\n while (currentFrame) {\n const childFrame = frames.find(\n (f) => f.parent_frame_id === currentFrame.frame_id\n );\n if (!childFrame) break;\n stack.push(childFrame.frame_id);\n currentFrame = childFrame;\n }\n\n return stack;\n }\n\n /**\n * Create a new frame and push to stack\n */\n public createFrame(options: {\n type: FrameType;\n name: string;\n inputs?: Record<string, any>;\n parentFrameId?: string;\n }): string {\n return this._createFrame(options);\n }\n\n private _createFrame(options: {\n type: FrameType;\n name: string;\n inputs?: Record<string, any>;\n parentFrameId?: string;\n }): string {\n const frameId = uuidv4();\n const parentFrameId = options.parentFrameId || this.getCurrentFrameId();\n const depth = parentFrameId ? this.getFrameDepth(parentFrameId) + 1 : 0;\n\n const frame: Omit<\n Frame,\n 'outputs' | 'digest_text' | 'digest_json' | 'closed_at'\n > = {\n frame_id: frameId,\n run_id: this.currentRunId,\n project_id: this.projectId,\n parent_frame_id: parentFrameId,\n depth,\n type: options.type,\n name: options.name,\n state: 'active',\n inputs: options.inputs || {},\n created_at: Math.floor(Date.now() / 1000),\n };\n\n try {\n this.db\n .prepare(\n `\n INSERT INTO frames (\n frame_id, run_id, project_id, parent_frame_id, depth, type, name, state, inputs, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n frame.frame_id,\n frame.run_id,\n frame.project_id,\n frame.parent_frame_id,\n frame.depth,\n frame.type,\n frame.name,\n frame.state,\n JSON.stringify(frame.inputs),\n frame.created_at\n );\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to create frame: ${options.name}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId,\n frameType: options.type,\n frameName: options.name,\n parentFrameId,\n depth,\n operation: 'createFrame',\n },\n error instanceof Error ? error : undefined\n );\n }\n\n // Push to active stack\n this.activeStack.push(frameId);\n\n logger.info('Created frame', {\n frameId,\n type: options.type,\n name: options.name,\n depth,\n parentFrameId,\n stackDepth: this.activeStack.length,\n });\n\n return frameId;\n }\n\n /**\n * Close the current frame and generate digest\n */\n public closeFrame(frameId?: string, outputs?: Record<string, any>): void {\n this._closeFrame(frameId, outputs);\n }\n\n private _closeFrame(frameId?: string, outputs?: Record<string, any>): void {\n const targetFrameId = frameId || this.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame to close',\n ErrorCode.FRAME_INVALID_STATE,\n {\n operation: 'closeFrame',\n activeStack: this.activeStack,\n stackDepth: this.activeStack.length,\n }\n );\n }\n\n // Get frame details\n const frame = this.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.generateDigest(targetFrameId);\n const finalOutputs = { ...outputs, ...digest.structured };\n\n try {\n // Update frame to closed state\n this.db\n .prepare(\n `\n UPDATE frames\n SET state = 'closed',\n outputs = ?,\n digest_text = ?,\n digest_json = ?,\n closed_at = unixepoch()\n WHERE frame_id = ?\n `\n )\n .run(\n JSON.stringify(finalOutputs),\n digest.text,\n JSON.stringify(digest.structured),\n targetFrameId\n );\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to close frame: ${targetFrameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId: targetFrameId,\n frameName: frame.name,\n operation: 'closeFrame',\n },\n error instanceof Error ? error : undefined\n );\n }\n\n // Remove from active stack\n this.activeStack = this.activeStack.filter((id) => id !== 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.activeStack.length,\n });\n }\n\n /**\n * Delete a frame completely from the database (used in handoffs)\n */\n deleteFrame(frameId: string): void {\n try {\n // First delete related data\n this.db.prepare('DELETE FROM events WHERE frame_id = ?').run(frameId);\n this.db.prepare('DELETE FROM anchors WHERE frame_id = ?').run(frameId);\n\n // Remove from active stack if present\n this.activeStack = this.activeStack.filter((id) => id !== frameId);\n\n // Delete the frame itself\n this.db.prepare('DELETE FROM frames WHERE frame_id = ?').run(frameId);\n\n logger.debug('Deleted frame completely', { frameId });\n } catch (error: unknown) {\n logger.error('Failed to delete frame', { frameId, error });\n throw error;\n }\n }\n\n private closeChildFrames(parentFrameId: string) {\n try {\n const children = this.db\n .prepare(\n `\n SELECT frame_id FROM frames\n WHERE parent_frame_id = ? AND state = 'active'\n `\n )\n .all(parentFrameId) as { frame_id: string }[];\n\n children.forEach((child) => {\n try {\n this.closeFrame(child.frame_id);\n } catch (error: unknown) {\n logger.error(\n 'Failed to close child frame',\n error instanceof Error ? error : new Error(String(error)),\n {\n parentFrameId,\n childFrameId: child.frame_id,\n }\n );\n }\n });\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to close child frames for parent: ${parentFrameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n parentFrameId,\n operation: 'closeChildFrames',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Generate digest for a frame\n */\n private generateDigest(frameId: string): {\n text: string;\n structured: Record<string, any>;\n } {\n const frame = this.getFrame(frameId);\n const events = this.getFrameEvents(frameId);\n const anchors = this.getFrameAnchors(frameId);\n\n if (!frame) {\n throw new FrameError(\n `Cannot generate digest: frame not found ${frameId}`,\n ErrorCode.FRAME_NOT_FOUND,\n {\n frameId,\n operation: 'generateDigest',\n runId: this.currentRunId,\n }\n );\n }\n\n // Extract key information\n const decisions = anchors.filter((a) => a.type === 'DECISION');\n const constraints = anchors.filter((a) => a.type === 'CONSTRAINT');\n const risks = anchors.filter((a) => a.type === 'RISK');\n\n const toolCalls = events.filter((e) => e.event_type === 'tool_call');\n const artifacts = events.filter((e) => e.event_type === 'artifact');\n\n // Generate structured digest\n const structured = {\n result: frame.name,\n decisions: decisions.map((d) => ({ id: d.anchor_id, text: d.text })),\n constraints: constraints.map((c) => ({ id: c.anchor_id, text: c.text })),\n risks: risks.map((r) => ({ id: r.anchor_id, text: r.text })),\n artifacts: artifacts.map((a) => ({\n kind: a.payload.kind || 'unknown',\n ref: a.payload.ref,\n })),\n tool_calls_count: toolCalls.length,\n duration_seconds: frame.closed_at\n ? frame.closed_at - frame.created_at\n : 0,\n };\n\n // Generate text summary\n const text = this.generateDigestText(frame, structured, events.length);\n\n return { text, structured };\n }\n\n private generateDigestText(\n frame: Frame,\n structured: any,\n eventCount: number\n ): string {\n let summary = `Completed: ${frame.name}\\n`;\n\n if (structured.decisions.length > 0) {\n summary += `\\nDecisions made:\\n${structured.decisions.map((d: any) => `- ${d.text}`).join('\\n')}`;\n }\n\n if (structured.constraints.length > 0) {\n summary += `\\nConstraints established:\\n${structured.constraints.map((c: any) => `- ${c.text}`).join('\\n')}`;\n }\n\n if (structured.risks.length > 0) {\n summary += `\\nRisks identified:\\n${structured.risks.map((r: any) => `- ${r.text}`).join('\\n')}`;\n }\n\n summary += `\\nActivity: ${eventCount} events, ${structured.tool_calls_count} tool calls`;\n\n if (structured.duration_seconds > 0) {\n summary += `, ${Math.floor(structured.duration_seconds / 60)}m ${structured.duration_seconds % 60}s duration`;\n }\n\n return summary;\n }\n\n /**\n * Add event to current frame\n */\n public addEvent(\n eventType: Event['event_type'],\n payload: Record<string, any>,\n frameId?: string\n ): string {\n const targetFrameId = frameId || this.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame for event',\n ErrorCode.FRAME_INVALID_STATE,\n {\n operation: 'addEvent',\n eventType,\n activeStack: this.activeStack,\n }\n );\n }\n\n const eventId = uuidv4();\n const seq = this.getNextEventSequence(targetFrameId);\n\n try {\n this.db\n .prepare(\n `\n INSERT INTO events (event_id, run_id, frame_id, seq, event_type, payload)\n VALUES (?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n eventId,\n this.currentRunId,\n targetFrameId,\n seq,\n eventType,\n JSON.stringify(payload)\n );\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to add event to frame: ${targetFrameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n eventId,\n frameId: targetFrameId,\n eventType,\n seq,\n operation: 'addEvent',\n },\n error instanceof Error ? error : undefined\n );\n }\n\n return eventId;\n }\n\n /**\n * Add anchor to frame\n */\n public addAnchor(\n type: Anchor['type'],\n text: string,\n priority: number = 0,\n metadata: Record<string, any> = {},\n frameId?: string\n ): string {\n const targetFrameId = frameId || this.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame for anchor',\n ErrorCode.FRAME_INVALID_STATE,\n {\n operation: 'addAnchor',\n anchorType: type,\n text: text.substring(0, 100),\n activeStack: this.activeStack,\n }\n );\n }\n\n const anchorId = uuidv4();\n\n try {\n this.db\n .prepare(\n `\n INSERT INTO anchors (anchor_id, frame_id, project_id, type, text, priority, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n anchorId,\n targetFrameId,\n this.projectId,\n type,\n text,\n priority,\n JSON.stringify(metadata)\n );\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to add anchor to frame: ${targetFrameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n anchorId,\n frameId: targetFrameId,\n anchorType: type,\n operation: 'addAnchor',\n },\n error instanceof Error ? error : undefined\n );\n }\n\n return anchorId;\n }\n\n /**\n * Get hot stack context for current active frames\n */\n public getHotStackContext(maxEvents: number = 20): FrameContext[] {\n return this.activeStack\n .map((frameId) => {\n const frame = this.getFrame(frameId);\n if (!frame) return null;\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: this.getFrameAnchors(frameId),\n recentEvents: this.getFrameEvents(frameId, maxEvents),\n activeArtifacts: this.getActiveArtifacts(frameId),\n };\n })\n .filter(Boolean) as FrameContext[];\n }\n\n /**\n * Get active frame path (root to current)\n */\n public getActiveFramePath(): Frame[] {\n return this.activeStack\n .map((frameId) => this.getFrame(frameId))\n .filter(Boolean) as Frame[];\n }\n\n // Utility methods\n public getCurrentFrameId(): string | undefined {\n return this.activeStack[this.activeStack.length - 1];\n }\n\n public getStackDepth(): number {\n return this.activeStack.length;\n }\n\n /**\n * Get recent frames for context sharing\n */\n public async getRecentFrames(limit: number = 100): Promise<Frame[]> {\n try {\n const rows = this.db\n .prepare(\n `\n SELECT * FROM frames \n WHERE project_id = ?\n ORDER BY created_at DESC\n LIMIT ?\n `\n )\n .all(this.projectId, limit) as any[];\n\n return rows.map((row) => ({\n ...row,\n frameId: row.frame_id,\n runId: row.run_id,\n projectId: row.project_id,\n parentFrameId: row.parent_frame_id,\n title: row.name,\n timestamp: row.created_at,\n metadata: {\n tags: this.extractTagsFromFrame(row),\n importance: this.calculateFrameImportance(row),\n },\n data: {\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest: JSON.parse(row.digest_json || '{}'),\n },\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest_json: JSON.parse(row.digest_json || '{}'),\n }));\n } catch (error: unknown) {\n logger.error('Failed to get recent frames', error as Error);\n return [];\n }\n }\n\n /**\n * Add context metadata to the current frame\n */\n public async addContext(key: string, value: any): Promise<void> {\n const currentFrameId = this.getCurrentFrameId();\n if (!currentFrameId) return;\n\n try {\n const frame = this.getFrame(currentFrameId);\n if (!frame) return;\n\n const metadata = frame.outputs || {};\n metadata[key] = value;\n\n this.db\n .prepare(`UPDATE frames SET outputs = ? WHERE frame_id = ?`)\n .run(JSON.stringify(metadata), currentFrameId);\n } catch (error: unknown) {\n logger.warn('Failed to add context to frame', { error, key });\n }\n }\n\n private extractTagsFromFrame(frame: any): string[] {\n const tags: string[] = [];\n\n // Add type as tag\n if (frame.type) tags.push(frame.type);\n\n // Extract tags from name\n if (frame.name) {\n if (frame.name.toLowerCase().includes('error')) tags.push('error');\n if (frame.name.toLowerCase().includes('fix')) tags.push('resolution');\n if (frame.name.toLowerCase().includes('decision')) tags.push('decision');\n if (frame.name.toLowerCase().includes('milestone'))\n tags.push('milestone');\n }\n\n // Extract from digest\n try {\n const digest = JSON.parse(frame.digest_json || '{}');\n if (digest.tags) tags.push(...digest.tags);\n } catch {}\n\n return [...new Set(tags)];\n }\n\n private calculateFrameImportance(frame: any): 'high' | 'medium' | 'low' {\n // Milestones and decisions are high importance\n if (frame.type === 'milestone' || frame.name?.includes('decision'))\n return 'high';\n\n // Errors and resolutions are medium importance\n if (frame.type === 'error' || frame.type === 'resolution') return 'medium';\n\n // Long-running frames are potentially important\n if (frame.closed_at && frame.created_at) {\n const duration = frame.closed_at - frame.created_at;\n if (duration > 300) return 'medium'; // More than 5 minutes\n }\n\n return 'low';\n }\n\n private getFrameDepth(frameId: string): number {\n const frame = this.getFrame(frameId);\n return frame?.depth || 0;\n }\n\n public getFrame(frameId: string): Frame | undefined {\n try {\n const row = this.db\n .prepare(\n `\n SELECT * FROM frames WHERE frame_id = ?\n `\n )\n .get(frameId) as any;\n\n if (!row) return undefined;\n\n return {\n ...row,\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest_json: JSON.parse(row.digest_json || '{}'),\n };\n } catch (error: unknown) {\n // Log the error but return undefined instead of throwing\n logger.warn(`Failed to get frame: ${frameId}`, {\n error: error instanceof Error ? error.message : String(error),\n frameId,\n operation: 'getFrame',\n });\n return undefined;\n }\n }\n\n public getFrameEvents(frameId: string, limit?: number): Event[] {\n try {\n const query = limit\n ? `SELECT * FROM events WHERE frame_id = ? ORDER BY seq DESC LIMIT ?`\n : `SELECT * FROM events WHERE frame_id = ? ORDER BY seq ASC`;\n\n const params = limit ? [frameId, limit] : [frameId];\n const rows = this.db.prepare(query).all(...params) as any[];\n\n return rows.map((row) => ({\n ...row,\n payload: JSON.parse(row.payload),\n }));\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to get frame events: ${frameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId,\n limit,\n operation: 'getFrameEvents',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private getFrameAnchors(frameId: string): Anchor[] {\n try {\n const rows = this.db\n .prepare(\n `\n SELECT * FROM anchors WHERE frame_id = ? ORDER BY priority DESC, created_at ASC\n `\n )\n .all(frameId) as any[];\n\n return rows.map((row) => ({\n ...row,\n metadata: JSON.parse(row.metadata || '{}'),\n }));\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to get frame anchors: ${frameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId,\n operation: 'getFrameAnchors',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private getNextEventSequence(frameId: string): number {\n try {\n const result = this.db\n .prepare(\n `\n SELECT MAX(seq) as max_seq FROM events WHERE frame_id = ?\n `\n )\n .get(frameId) as { max_seq: number | null };\n\n return (result.max_seq || 0) + 1;\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to get next event sequence for frame: ${frameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId,\n operation: 'getNextEventSequence',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private extractConstraints(\n inputs: Record<string, any>\n ): string[] | undefined {\n return inputs.constraints;\n }\n\n private getActiveArtifacts(frameId: string): string[] {\n const artifacts = this.getFrameEvents(frameId)\n .filter((e) => e.event_type === 'artifact')\n .map((e) => e.payload.ref)\n .filter(Boolean);\n\n return artifacts;\n }\n}\n"],
5
- "mappings": "AAMA,SAAS,MAAM,cAAc;AAC7B,SAAS,cAAc;AAEvB;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EAEA;AAAA,OACK;AAEP,SAAS,gBAAgB,sBAAsB;AAC/C,SAAS,qBAAqB;AAE9B,SAAS,OAAO,KAAa,cAA+B;AAC1D,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,MAAI,UAAU,QAAW;AACvB,QAAI,iBAAiB,OAAW,QAAO;AACvC,UAAM,IAAI,MAAM,wBAAwB,GAAG,cAAc;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,eAAe,KAAiC;AACvD,SAAO,QAAQ,IAAI,GAAG;AACxB;AA+EO,MAAM,aAAa;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAwB,CAAC;AAAA;AAAA,EACzB,YAA4B,eAAe;AAAA,EAEnD,YACE,IACA,WACA,gBACA;AACA,SAAK,KAAK;AACV,SAAK,YAAY;AAGjB,QAAI;AACJ,QAAI,oBAAoB;AAExB,QAAI,OAAO,mBAAmB,UAAU;AACtC,cAAQ;AAAA,IACV,WAAW,gBAAgB;AACzB,cAAQ,eAAe;AACvB,0BAAoB,eAAe,qBAAqB;AAAA,IAC1D;AAGA,UAAM,UAAU,eAAe,kBAAkB;AACjD,QAAI,SAAS;AACX,WAAK,eAAe,QAAQ;AAC5B,WAAK,YAAY,QAAQ;AAAA,IAC3B,OAAO;AACL,WAAK,eAAe,SAAS,OAAO;AACpC,WAAK,YAAY,KAAK;AAAA,IACxB;AAEA,SAAK,iBAAiB;AACtB,SAAK,gBAAgB;AAIrB,UAAM,yBACJ,CAAC,qBACD,QAAQ,IAAI,UAAU,MAAM,UAC5B,CAAC,QAAQ,IAAI,QAAQ,KACrB,CAAC,QAAQ,IAAI,iBAAiB;AAEhC,QAAI,wBAAwB;AAC1B,oBACG,WAAW,MAAM;AAAA,QAChB,UAAU;AAAA,QACV,cAAc;AAAA;AAAA,QACd,eAAe;AAAA;AAAA,QACf,eAAe,CAAC,YAAY,SAAS,aAAa,UAAU;AAAA,MAC9D,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,eAAO,KAAK,uCAAuC,EAAE,MAAM,CAAC;AAAA,MAC9D,CAAC;AAAA,IACL;AAAA,EACF;AAAA,EAEA,aAAa,MAA4B;AACvC,SAAK,YAAY;AACjB,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEQ,mBAAmB;AACzB,UAAM,eAAe,mBAAmB;AAAA,MACtC,WAAW;AAAA,MACX,WAAW,KAAK;AAAA,MAChB,OAAO,KAAK;AAAA,IACd,CAAC;AAED,QAAI;AAEF,WAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OA6DZ;AAAA,IACH,SAAS,OAAgB;AACvB,YAAM,UAAU,aAAa,OAAO;AAAA,QAClC,WAAW;AAAA,QACX,QAAQ;AAAA,MACV,CAAC;AAED,UAAI,mBAAmB,eAAe;AACpC,cAAM,IAAI;AAAA,UACR;AAAA,UACA,UAAU;AAAA,UACV;AAAA,YACE,WAAW,KAAK;AAAA,YAChB,WAAW;AAAA,YACX,eAAe;AAAA,UACjB;AAAA,UACA,iBAAiB,QAAQ,QAAQ;AAAA,QACnC;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,kBAAkB;AACxB,UAAM,eAAe,mBAAmB;AAAA,MACtC,WAAW;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK;AAAA,IAClB,CAAC;AAED,QAAI;AACF,UAAI;AACJ,UAAI;AAGJ,cAAQ,KAAK,WAAW;AAAA,QACtB,KAAK,eAAe;AAClB,kBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAMR,mBAAS,CAAC;AACV;AAAA,QAEF,KAAK,eAAe;AAClB,kBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAMR,mBAAS,CAAC,KAAK,SAAS;AACxB;AAAA,QAEF,KAAK,eAAe;AAClB,kBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAMR,mBAAS,CAAC,KAAK,SAAS;AACxB;AAAA,QAEF,KAAK,eAAe;AAAA,QACpB;AACE,kBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAMR,mBAAS,CAAC,KAAK,YAAY;AAC3B;AAAA,MACJ;AAEA,YAAM,eAAe,KAAK,GAAG,QAAQ,KAAK,EAAE,IAAI,GAAG,MAAM;AAGzD,WAAK,cAAc,KAAK,gBAAgB,YAAY;AAEpD,aAAO,KAAK,uBAAuB;AAAA,QACjC,OAAO,KAAK;AAAA,QACZ,YAAY,KAAK,YAAY;AAAA,QAC7B,cAAc,KAAK;AAAA,QACnB,WAAW,KAAK;AAAA,MAClB,CAAC;AAAA,IACH,SAAS,OAAgB;AACvB,YAAM,UAAU,aAAa,OAAO;AAAA,QAClC,OAAO;AAAA,QACP,OAAO,KAAK;AAAA,QACZ,WAAW,KAAK;AAAA,MAClB,CAAC;AAED,UAAI,mBAAmB,eAAe;AACpC,cAAM,IAAI;AAAA,UACR;AAAA,UACA,UAAU;AAAA,UACV;AAAA,YACE,OAAO,KAAK;AAAA,YACZ,WAAW,KAAK;AAAA,YAChB,WAAW;AAAA,UACb;AAAA,UACA,iBAAiB,QAAQ,QAAQ;AAAA,QACnC;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,gBACN,QACU;AACV,UAAM,QAAkB,CAAC;AAGzB,UAAM,YAAY,OAAO,KAAK,CAAC,MAAM,CAAC,EAAE,eAAe;AACvD,QAAI,CAAC,UAAW,QAAO,CAAC;AAGxB,QAAI,eAAe;AACnB,UAAM,KAAK,aAAa,QAAQ;AAEhC,WAAO,cAAc;AACnB,YAAM,aAAa,OAAO;AAAA,QACxB,CAAC,MAAM,EAAE,oBAAoB,aAAa;AAAA,MAC5C;AACA,UAAI,CAAC,WAAY;AACjB,YAAM,KAAK,WAAW,QAAQ;AAC9B,qBAAe;AAAA,IACjB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,YAAY,SAKR;AACT,WAAO,KAAK,aAAa,OAAO;AAAA,EAClC;AAAA,EAEQ,aAAa,SAKV;AACT,UAAM,UAAU,OAAO;AACvB,UAAM,gBAAgB,QAAQ,iBAAiB,KAAK,kBAAkB;AACtE,UAAM,QAAQ,gBAAgB,KAAK,cAAc,aAAa,IAAI,IAAI;AAEtE,UAAM,QAGF;AAAA,MACF,UAAU;AAAA,MACV,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK;AAAA,MACjB,iBAAiB;AAAA,MACjB;AAAA,MACA,MAAM,QAAQ;AAAA,MACd,MAAM,QAAQ;AAAA,MACd,OAAO;AAAA,MACP,QAAQ,QAAQ,UAAU,CAAC;AAAA,MAC3B,YAAY,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,IAC1C;AAEA,QAAI;AACF,WAAK,GACF;AAAA,QACC;AAAA;AAAA;AAAA;AAAA;AAAA,MAKF,EACC;AAAA,QACC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,KAAK,UAAU,MAAM,MAAM;AAAA,QAC3B,MAAM;AAAA,MACR;AAAA,IACJ,SAAS,OAAgB;AACvB,YAAM,IAAI;AAAA,QACR,2BAA2B,QAAQ,IAAI;AAAA,QACvC,UAAU;AAAA,QACV;AAAA,UACE;AAAA,UACA,WAAW,QAAQ;AAAA,UACnB,WAAW,QAAQ;AAAA,UACnB;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb;AAAA,QACA,iBAAiB,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF;AAGA,SAAK,YAAY,KAAK,OAAO;AAE7B,WAAO,KAAK,iBAAiB;AAAA,MAC3B;AAAA,MACA,MAAM,QAAQ;AAAA,MACd,MAAM,QAAQ;AAAA,MACd;AAAA,MACA;AAAA,MACA,YAAY,KAAK,YAAY;AAAA,IAC/B,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,WAAW,SAAkB,SAAqC;AACvE,SAAK,YAAY,SAAS,OAAO;AAAA,EACnC;AAAA,EAEQ,YAAY,SAAkB,SAAqC;AACzE,UAAM,gBAAgB,WAAW,KAAK,kBAAkB;AACxD,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,UAAU;AAAA,QACV;AAAA,UACE,WAAW;AAAA,UACX,aAAa,KAAK;AAAA,UAClB,YAAY,KAAK,YAAY;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAGA,UAAM,QAAQ,KAAK,SAAS,aAAa;AACzC,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,oBAAoB,aAAa;AAAA,QACjC,UAAU;AAAA,QACV;AAAA,UACE,SAAS;AAAA,UACT,WAAW;AAAA,UACX,OAAO,KAAK;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAEA,QAAI,MAAM,UAAU,UAAU;AAC5B,aAAO,KAAK,2CAA2C;AAAA,QACrD,SAAS;AAAA,MACX,CAAC;AACD;AAAA,IACF;AAGA,UAAM,SAAS,KAAK,eAAe,aAAa;AAChD,UAAM,eAAe,EAAE,GAAG,SAAS,GAAG,OAAO,WAAW;AAExD,QAAI;AAEF,WAAK,GACF;AAAA,QACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASF,EACC;AAAA,QACC,KAAK,UAAU,YAAY;AAAA,QAC3B,OAAO;AAAA,QACP,KAAK,UAAU,OAAO,UAAU;AAAA,QAChC;AAAA,MACF;AAAA,IACJ,SAAS,OAAgB;AACvB,YAAM,IAAI;AAAA,QACR,0BAA0B,aAAa;AAAA,QACvC,UAAU;AAAA,QACV;AAAA,UACE,SAAS;AAAA,UACT,WAAW,MAAM;AAAA,UACjB,WAAW;AAAA,QACb;AAAA,QACA,iBAAiB,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF;AAGA,SAAK,cAAc,KAAK,YAAY,OAAO,CAAC,OAAO,OAAO,aAAa;AAGvE,SAAK,iBAAiB,aAAa;AAEnC,WAAO,KAAK,gBAAgB;AAAA,MAC1B,SAAS;AAAA,MACT,MAAM,MAAM;AAAA,MACZ,UAAU,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAAI,MAAM;AAAA,MAChD,cAAc,OAAO,KAAK;AAAA,MAC1B,YAAY,KAAK,YAAY;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,SAAuB;AACjC,QAAI;AAEF,WAAK,GAAG,QAAQ,uCAAuC,EAAE,IAAI,OAAO;AACpE,WAAK,GAAG,QAAQ,wCAAwC,EAAE,IAAI,OAAO;AAGrE,WAAK,cAAc,KAAK,YAAY,OAAO,CAAC,OAAO,OAAO,OAAO;AAGjE,WAAK,GAAG,QAAQ,uCAAuC,EAAE,IAAI,OAAO;AAEpE,aAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC;AAAA,IACtD,SAAS,OAAgB;AACvB,aAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,CAAC;AACzD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,iBAAiB,eAAuB;AAC9C,QAAI;AACF,YAAM,WAAW,KAAK,GACnB;AAAA,QACC;AAAA;AAAA;AAAA;AAAA,MAIF,EACC,IAAI,aAAa;AAEpB,eAAS,QAAQ,CAAC,UAAU;AAC1B,YAAI;AACF,eAAK,WAAW,MAAM,QAAQ;AAAA,QAChC,SAAS,OAAgB;AACvB,iBAAO;AAAA,YACL;AAAA,YACA,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,YACxD;AAAA,cACE;AAAA,cACA,cAAc,MAAM;AAAA,YACtB;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAgB;AACvB,YAAM,IAAI;AAAA,QACR,4CAA4C,aAAa;AAAA,QACzD,UAAU;AAAA,QACV;AAAA,UACE;AAAA,UACA,WAAW;AAAA,QACb;AAAA,QACA,iBAAiB,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,SAGrB;AACA,UAAM,QAAQ,KAAK,SAAS,OAAO;AACnC,UAAM,SAAS,KAAK,eAAe,OAAO;AAC1C,UAAM,UAAU,KAAK,gBAAgB,OAAO;AAE5C,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,2CAA2C,OAAO;AAAA,QAClD,UAAU;AAAA,QACV;AAAA,UACE;AAAA,UACA,WAAW;AAAA,UACX,OAAO,KAAK;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,UAAU;AAC7D,UAAM,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY;AACjE,UAAM,QAAQ,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM;AAErD,UAAM,YAAY,OAAO,OAAO,CAAC,MAAM,EAAE,eAAe,WAAW;AACnE,UAAM,YAAY,OAAO,OAAO,CAAC,MAAM,EAAE,eAAe,UAAU;AAGlE,UAAM,aAAa;AAAA,MACjB,QAAQ,MAAM;AAAA,MACd,WAAW,UAAU,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,MAAM,EAAE,KAAK,EAAE;AAAA,MACnE,aAAa,YAAY,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,MAAM,EAAE,KAAK,EAAE;AAAA,MACvE,OAAO,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,MAAM,EAAE,KAAK,EAAE;AAAA,MAC3D,WAAW,UAAU,IAAI,CAAC,OAAO;AAAA,QAC/B,MAAM,EAAE,QAAQ,QAAQ;AAAA,QACxB,KAAK,EAAE,QAAQ;AAAA,MACjB,EAAE;AAAA,MACF,kBAAkB,UAAU;AAAA,MAC5B,kBAAkB,MAAM,YACpB,MAAM,YAAY,MAAM,aACxB;AAAA,IACN;AAGA,UAAM,OAAO,KAAK,mBAAmB,OAAO,YAAY,OAAO,MAAM;AAErE,WAAO,EAAE,MAAM,WAAW;AAAA,EAC5B;AAAA,EAEQ,mBACN,OACA,YACA,YACQ;AACR,QAAI,UAAU,cAAc,MAAM,IAAI;AAAA;AAEtC,QAAI,WAAW,UAAU,SAAS,GAAG;AACnC,iBAAW;AAAA;AAAA,EAAsB,WAAW,UAAU,IAAI,CAAC,MAAW,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,IACjG;AAEA,QAAI,WAAW,YAAY,SAAS,GAAG;AACrC,iBAAW;AAAA;AAAA,EAA+B,WAAW,YAAY,IAAI,CAAC,MAAW,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,IAC5G;AAEA,QAAI,WAAW,MAAM,SAAS,GAAG;AAC/B,iBAAW;AAAA;AAAA,EAAwB,WAAW,MAAM,IAAI,CAAC,MAAW,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,IAC/F;AAEA,eAAW;AAAA,YAAe,UAAU,YAAY,WAAW,gBAAgB;AAE3E,QAAI,WAAW,mBAAmB,GAAG;AACnC,iBAAW,KAAK,KAAK,MAAM,WAAW,mBAAmB,EAAE,CAAC,KAAK,WAAW,mBAAmB,EAAE;AAAA,IACnG;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,SACL,WACA,SACA,SACQ;AACR,UAAM,gBAAgB,WAAW,KAAK,kBAAkB;AACxD,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,UAAU;AAAA,QACV;AAAA,UACE,WAAW;AAAA,UACX;AAAA,UACA,aAAa,KAAK;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,OAAO;AACvB,UAAM,MAAM,KAAK,qBAAqB,aAAa;AAEnD,QAAI;AACF,WAAK,GACF;AAAA,QACC;AAAA;AAAA;AAAA;AAAA,MAIF,EACC;AAAA,QACC;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,KAAK,UAAU,OAAO;AAAA,MACxB;AAAA,IACJ,SAAS,OAAgB;AACvB,YAAM,IAAI;AAAA,QACR,iCAAiC,aAAa;AAAA,QAC9C,UAAU;AAAA,QACV;AAAA,UACE;AAAA,UACA,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb;AAAA,QACA,iBAAiB,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,UACL,MACA,MACA,WAAmB,GACnB,WAAgC,CAAC,GACjC,SACQ;AACR,UAAM,gBAAgB,WAAW,KAAK,kBAAkB;AACxD,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,UAAU;AAAA,QACV;AAAA,UACE,WAAW;AAAA,UACX,YAAY;AAAA,UACZ,MAAM,KAAK,UAAU,GAAG,GAAG;AAAA,UAC3B,aAAa,KAAK;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,OAAO;AAExB,QAAI;AACF,WAAK,GACF;AAAA,QACC;AAAA;AAAA;AAAA;AAAA,MAIF,EACC;AAAA,QACC;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,KAAK,UAAU,QAAQ;AAAA,MACzB;AAAA,IACJ,SAAS,OAAgB;AACvB,YAAM,IAAI;AAAA,QACR,kCAAkC,aAAa;AAAA,QAC/C,UAAU;AAAA,QACV;AAAA,UACE;AAAA,UACA,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,WAAW;AAAA,QACb;AAAA,QACA,iBAAiB,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,mBAAmB,YAAoB,IAAoB;AAChE,WAAO,KAAK,YACT,IAAI,CAAC,YAAY;AAChB,YAAM,QAAQ,KAAK,SAAS,OAAO;AACnC,UAAI,CAAC,MAAO,QAAO;AAEnB,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,UACN,MAAM,MAAM;AAAA,UACZ,aAAa,KAAK,mBAAmB,MAAM,MAAM;AAAA,UACjD,aAAa,MAAM,OAAO;AAAA,QAC5B;AAAA,QACA,SAAS,KAAK,gBAAgB,OAAO;AAAA,QACrC,cAAc,KAAK,eAAe,SAAS,SAAS;AAAA,QACpD,iBAAiB,KAAK,mBAAmB,OAAO;AAAA,MAClD;AAAA,IACF,CAAC,EACA,OAAO,OAAO;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKO,qBAA8B;AACnC,WAAO,KAAK,YACT,IAAI,CAAC,YAAY,KAAK,SAAS,OAAO,CAAC,EACvC,OAAO,OAAO;AAAA,EACnB;AAAA;AAAA,EAGO,oBAAwC;AAC7C,WAAO,KAAK,YAAY,KAAK,YAAY,SAAS,CAAC;AAAA,EACrD;AAAA,EAEO,gBAAwB;AAC7B,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,gBAAgB,QAAgB,KAAuB;AAClE,QAAI;AACF,YAAM,OAAO,KAAK,GACf;AAAA,QACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMF,EACC,IAAI,KAAK,WAAW,KAAK;AAE5B,aAAO,KAAK,IAAI,CAAC,SAAS;AAAA,QACxB,GAAG;AAAA,QACH,SAAS,IAAI;AAAA,QACb,OAAO,IAAI;AAAA,QACX,WAAW,IAAI;AAAA,QACf,eAAe,IAAI;AAAA,QACnB,OAAO,IAAI;AAAA,QACX,WAAW,IAAI;AAAA,QACf,UAAU;AAAA,UACR,MAAM,KAAK,qBAAqB,GAAG;AAAA,UACnC,YAAY,KAAK,yBAAyB,GAAG;AAAA,QAC/C;AAAA,QACA,MAAM;AAAA,UACJ,QAAQ,KAAK,MAAM,IAAI,UAAU,IAAI;AAAA,UACrC,SAAS,KAAK,MAAM,IAAI,WAAW,IAAI;AAAA,UACvC,QAAQ,KAAK,MAAM,IAAI,eAAe,IAAI;AAAA,QAC5C;AAAA,QACA,QAAQ,KAAK,MAAM,IAAI,UAAU,IAAI;AAAA,QACrC,SAAS,KAAK,MAAM,IAAI,WAAW,IAAI;AAAA,QACvC,aAAa,KAAK,MAAM,IAAI,eAAe,IAAI;AAAA,MACjD,EAAE;AAAA,IACJ,SAAS,OAAgB;AACvB,aAAO,MAAM,+BAA+B,KAAc;AAC1D,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,WAAW,KAAa,OAA2B;AAC9D,UAAM,iBAAiB,KAAK,kBAAkB;AAC9C,QAAI,CAAC,eAAgB;AAErB,QAAI;AACF,YAAM,QAAQ,KAAK,SAAS,cAAc;AAC1C,UAAI,CAAC,MAAO;AAEZ,YAAM,WAAW,MAAM,WAAW,CAAC;AACnC,eAAS,GAAG,IAAI;AAEhB,WAAK,GACF,QAAQ,kDAAkD,EAC1D,IAAI,KAAK,UAAU,QAAQ,GAAG,cAAc;AAAA,IACjD,SAAS,OAAgB;AACvB,aAAO,KAAK,kCAAkC,EAAE,OAAO,IAAI,CAAC;AAAA,IAC9D;AAAA,EACF;AAAA,EAEQ,qBAAqB,OAAsB;AACjD,UAAM,OAAiB,CAAC;AAGxB,QAAI,MAAM,KAAM,MAAK,KAAK,MAAM,IAAI;AAGpC,QAAI,MAAM,MAAM;AACd,UAAI,MAAM,KAAK,YAAY,EAAE,SAAS,OAAO,EAAG,MAAK,KAAK,OAAO;AACjE,UAAI,MAAM,KAAK,YAAY,EAAE,SAAS,KAAK,EAAG,MAAK,KAAK,YAAY;AACpE,UAAI,MAAM,KAAK,YAAY,EAAE,SAAS,UAAU,EAAG,MAAK,KAAK,UAAU;AACvE,UAAI,MAAM,KAAK,YAAY,EAAE,SAAS,WAAW;AAC/C,aAAK,KAAK,WAAW;AAAA,IACzB;AAGA,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,MAAM,eAAe,IAAI;AACnD,UAAI,OAAO,KAAM,MAAK,KAAK,GAAG,OAAO,IAAI;AAAA,IAC3C,QAAQ;AAAA,IAAC;AAET,WAAO,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC;AAAA,EAC1B;AAAA,EAEQ,yBAAyB,OAAuC;AAEtE,QAAI,MAAM,SAAS,eAAe,MAAM,MAAM,SAAS,UAAU;AAC/D,aAAO;AAGT,QAAI,MAAM,SAAS,WAAW,MAAM,SAAS,aAAc,QAAO;AAGlE,QAAI,MAAM,aAAa,MAAM,YAAY;AACvC,YAAM,WAAW,MAAM,YAAY,MAAM;AACzC,UAAI,WAAW,IAAK,QAAO;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,SAAyB;AAC7C,UAAM,QAAQ,KAAK,SAAS,OAAO;AACnC,WAAO,OAAO,SAAS;AAAA,EACzB;AAAA,EAEO,SAAS,SAAoC;AAClD,QAAI;AACF,YAAM,MAAM,KAAK,GACd;AAAA,QACC;AAAA;AAAA;AAAA,MAGF,EACC,IAAI,OAAO;AAEd,UAAI,CAAC,IAAK,QAAO;AAEjB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,QAAQ,KAAK,MAAM,IAAI,UAAU,IAAI;AAAA,QACrC,SAAS,KAAK,MAAM,IAAI,WAAW,IAAI;AAAA,QACvC,aAAa,KAAK,MAAM,IAAI,eAAe,IAAI;AAAA,MACjD;AAAA,IACF,SAAS,OAAgB;AAEvB,aAAO,KAAK,wBAAwB,OAAO,IAAI;AAAA,QAC7C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D;AAAA,QACA,WAAW;AAAA,MACb,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEO,eAAe,SAAiB,OAAyB;AAC9D,QAAI;AACF,YAAM,QAAQ,QACV,sEACA;AAEJ,YAAM,SAAS,QAAQ,CAAC,SAAS,KAAK,IAAI,CAAC,OAAO;AAClD,YAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,EAAE,IAAI,GAAG,MAAM;AAEjD,aAAO,KAAK,IAAI,CAAC,SAAS;AAAA,QACxB,GAAG;AAAA,QACH,SAAS,KAAK,MAAM,IAAI,OAAO;AAAA,MACjC,EAAE;AAAA,IACJ,SAAS,OAAgB;AACvB,YAAM,IAAI;AAAA,QACR,+BAA+B,OAAO;AAAA,QACtC,UAAU;AAAA,QACV;AAAA,UACE;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb;AAAA,QACA,iBAAiB,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,gBAAgB,SAA2B;AACjD,QAAI;AACF,YAAM,OAAO,KAAK,GACf;AAAA,QACC;AAAA;AAAA;AAAA,MAGF,EACC,IAAI,OAAO;AAEd,aAAO,KAAK,IAAI,CAAC,SAAS;AAAA,QACxB,GAAG;AAAA,QACH,UAAU,KAAK,MAAM,IAAI,YAAY,IAAI;AAAA,MAC3C,EAAE;AAAA,IACJ,SAAS,OAAgB;AACvB,YAAM,IAAI;AAAA,QACR,gCAAgC,OAAO;AAAA,QACvC,UAAU;AAAA,QACV;AAAA,UACE;AAAA,UACA,WAAW;AAAA,QACb;AAAA,QACA,iBAAiB,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,qBAAqB,SAAyB;AACpD,QAAI;AACF,YAAM,SAAS,KAAK,GACjB;AAAA,QACC;AAAA;AAAA;AAAA,MAGF,EACC,IAAI,OAAO;AAEd,cAAQ,OAAO,WAAW,KAAK;AAAA,IACjC,SAAS,OAAgB;AACvB,YAAM,IAAI;AAAA,QACR,gDAAgD,OAAO;AAAA,QACvD,UAAU;AAAA,QACV;AAAA,UACE;AAAA,UACA,WAAW;AAAA,QACb;AAAA,QACA,iBAAiB,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,mBACN,QACsB;AACtB,WAAO,OAAO;AAAA,EAChB;AAAA,EAEQ,mBAAmB,SAA2B;AACpD,UAAM,YAAY,KAAK,eAAe,OAAO,EAC1C,OAAO,CAAC,MAAM,EAAE,eAAe,UAAU,EACzC,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,EACxB,OAAO,OAAO;AAEjB,WAAO;AAAA,EACT;AACF;",
4
+ "sourcesContent": ["/**\n * StackMemory Frame Manager - Call Stack Implementation\n * Manages nested frames representing the call stack of work\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 DatabaseError,\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';\nimport { contextBridge } from './context-bridge.js';\n\n// Constants for frame validation\nconst MAX_FRAME_DEPTH = 100; // Maximum allowed frame depth\nconst DEFAULT_MAX_DEPTH = 100; // Default if not configured\n\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// Frame types based on architecture\nexport type FrameType =\n | 'task'\n | 'subtask'\n | 'tool_scope'\n | 'review'\n | 'write'\n | 'debug';\nexport type FrameState = 'active' | 'closed';\n\nexport interface Frame {\n frame_id: string;\n run_id: string;\n project_id: string;\n parent_frame_id?: string;\n depth: number;\n type: FrameType;\n name: string;\n state: FrameState;\n inputs: Record<string, any>;\n outputs: Record<string, any>;\n digest_text?: string;\n digest_json: Record<string, any>;\n created_at: number;\n closed_at?: number;\n}\n\nexport interface FrameContext {\n frameId: string;\n header: {\n goal: string;\n constraints?: string[];\n definitions?: Record<string, string>;\n };\n anchors: Anchor[];\n recentEvents: Event[];\n activeArtifacts: string[];\n}\n\nexport interface Anchor {\n anchor_id: string;\n frame_id: string;\n type:\n | 'FACT'\n | 'DECISION'\n | 'CONSTRAINT'\n | 'INTERFACE_CONTRACT'\n | 'TODO'\n | 'RISK';\n text: string;\n priority: number;\n metadata: Record<string, any>;\n}\n\nexport interface Event {\n event_id: string;\n frame_id: string;\n run_id: string;\n seq: number;\n event_type:\n | 'user_message'\n | 'assistant_message'\n | 'tool_call'\n | 'tool_result'\n | 'decision'\n | 'constraint'\n | 'artifact'\n | 'observation';\n payload: Record<string, any>;\n ts: number;\n}\n\nexport interface FrameManagerOptions {\n skipContextBridge?: boolean;\n runId?: string;\n maxFrameDepth?: number; // Maximum allowed frame depth (default: 100)\n}\n\nexport class FrameManager {\n private db: Database.Database;\n private currentRunId: string;\n private sessionId: string;\n private projectId: string;\n private activeStack: string[] = []; // Stack of active frame IDs\n private queryMode: FrameQueryMode = FrameQueryMode.PROJECT_ACTIVE;\n private maxFrameDepth: number = DEFAULT_MAX_DEPTH;\n\n constructor(\n db: Database.Database,\n projectId: string,\n runIdOrOptions?: string | FrameManagerOptions\n ) {\n this.db = db;\n this.projectId = projectId;\n\n // Handle both legacy string runId and new options object\n let runId: string | undefined;\n let skipContextBridge = false;\n\n if (typeof runIdOrOptions === 'string') {\n runId = runIdOrOptions;\n } else if (runIdOrOptions) {\n runId = runIdOrOptions.runId;\n skipContextBridge = runIdOrOptions.skipContextBridge || false;\n this.maxFrameDepth = runIdOrOptions.maxFrameDepth || DEFAULT_MAX_DEPTH;\n }\n\n // Use session manager for run ID if available\n const session = sessionManager.getCurrentSession();\n if (session) {\n this.currentRunId = session.runId;\n this.sessionId = session.sessionId;\n } else {\n this.currentRunId = runId || uuidv4();\n this.sessionId = this.currentRunId; // Fallback for legacy behavior\n }\n\n this.initializeSchema();\n this.loadActiveStack();\n\n // Initialize context bridge for automatic shared context\n // Skip in test environment, when explicitly requested, or for CLI usage\n const shouldInitializeBridge =\n !skipContextBridge &&\n process.env['NODE_ENV'] !== 'test' &&\n !process.env['VITEST'] &&\n !process.env['STACKMEMORY_CLI'];\n\n if (shouldInitializeBridge) {\n contextBridge\n .initialize(this, {\n autoSync: true,\n syncInterval: 60000, // 1 minute\n minFrameScore: 0.5, // Sync frames above 0.5 score\n importantTags: ['decision', 'error', 'milestone', 'learning'],\n })\n .catch((error) => {\n logger.warn('Failed to initialize context bridge', { error });\n });\n }\n }\n\n setQueryMode(mode: FrameQueryMode): void {\n this.queryMode = mode;\n this.loadActiveStack(); // Reload with new mode\n }\n\n private initializeSchema() {\n const errorHandler = createErrorHandler({\n operation: 'initializeSchema',\n projectId: this.projectId,\n runId: this.currentRunId,\n });\n\n try {\n // Enhanced frames table matching architecture\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS frames (\n frame_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n parent_frame_id TEXT REFERENCES frames(frame_id),\n depth INTEGER NOT NULL DEFAULT 0,\n type TEXT NOT NULL,\n name TEXT NOT NULL,\n state TEXT DEFAULT 'active',\n inputs TEXT DEFAULT '{}',\n outputs TEXT DEFAULT '{}',\n digest_text TEXT,\n digest_json TEXT DEFAULT '{}',\n created_at INTEGER DEFAULT (unixepoch()),\n closed_at INTEGER\n );\n\n CREATE TABLE IF NOT EXISTS events (\n event_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n frame_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n event_type TEXT NOT NULL,\n payload TEXT NOT NULL,\n ts INTEGER DEFAULT (unixepoch()),\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id)\n );\n\n CREATE TABLE IF NOT EXISTS anchors (\n anchor_id TEXT PRIMARY KEY,\n frame_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n type TEXT NOT NULL,\n text TEXT NOT NULL,\n priority INTEGER DEFAULT 0,\n created_at INTEGER DEFAULT (unixepoch()),\n metadata TEXT DEFAULT '{}',\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id)\n );\n\n CREATE TABLE IF NOT EXISTS handoff_requests (\n request_id TEXT PRIMARY KEY,\n source_stack_id TEXT NOT NULL,\n target_stack_id TEXT NOT NULL,\n frame_ids TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n created_at INTEGER DEFAULT (unixepoch()),\n expires_at INTEGER,\n target_user_id TEXT,\n message TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_frames_run ON frames(run_id);\n CREATE INDEX IF NOT EXISTS idx_frames_parent ON frames(parent_frame_id);\n CREATE INDEX IF NOT EXISTS idx_frames_state ON frames(state);\n CREATE INDEX IF NOT EXISTS idx_events_frame ON events(frame_id);\n CREATE INDEX IF NOT EXISTS idx_events_seq ON events(frame_id, seq);\n CREATE INDEX IF NOT EXISTS idx_anchors_frame ON anchors(frame_id);\n CREATE INDEX IF NOT EXISTS idx_handoff_requests_status ON handoff_requests(status);\n CREATE INDEX IF NOT EXISTS idx_handoff_requests_target ON handoff_requests(target_stack_id);\n `);\n } catch (error: unknown) {\n const dbError = errorHandler(error, {\n operation: 'initializeSchema',\n schema: 'frames',\n });\n\n if (dbError instanceof DatabaseError) {\n throw new DatabaseError(\n 'Failed to initialize frame database schema',\n ErrorCode.DB_MIGRATION_FAILED,\n {\n projectId: this.projectId,\n operation: 'initializeSchema',\n originalError: error,\n },\n error instanceof Error ? error : undefined\n );\n }\n throw dbError;\n }\n }\n\n private loadActiveStack() {\n const errorHandler = createErrorHandler({\n operation: 'loadActiveStack',\n runId: this.currentRunId,\n projectId: this.projectId,\n });\n\n try {\n let query: string;\n let params: any[];\n\n // Build query based on query mode\n switch (this.queryMode) {\n case FrameQueryMode.ALL_ACTIVE:\n query = `\n SELECT frame_id, parent_frame_id, depth\n FROM frames\n WHERE state = 'active'\n ORDER BY created_at DESC, depth ASC\n `;\n params = [];\n break;\n\n case FrameQueryMode.PROJECT_ACTIVE:\n query = `\n SELECT frame_id, parent_frame_id, depth, run_id\n FROM frames\n WHERE state = 'active' AND project_id = ?\n ORDER BY created_at DESC, depth ASC\n `;\n params = [this.projectId];\n break;\n\n case FrameQueryMode.HISTORICAL:\n query = `\n SELECT frame_id, parent_frame_id, depth\n FROM frames\n WHERE project_id = ?\n ORDER BY created_at DESC, depth ASC\n `;\n params = [this.projectId];\n break;\n\n case FrameQueryMode.CURRENT_SESSION:\n default:\n query = `\n SELECT frame_id, parent_frame_id, depth\n FROM frames\n WHERE run_id = ? AND state = 'active'\n ORDER BY depth ASC\n `;\n params = [this.currentRunId];\n break;\n }\n\n const activeFrames = this.db.prepare(query).all(...params) as Frame[];\n\n // Rebuild stack order\n this.activeStack = this.buildStackOrder(activeFrames);\n\n logger.info('Loaded active stack', {\n runId: this.currentRunId,\n stackDepth: this.activeStack.length,\n activeFrames: this.activeStack,\n queryMode: this.queryMode,\n });\n } catch (error: unknown) {\n const dbError = errorHandler(error, {\n query: 'Frame loading query',\n runId: this.currentRunId,\n queryMode: this.queryMode,\n });\n\n if (dbError instanceof DatabaseError) {\n throw new DatabaseError(\n 'Failed to load active frame stack',\n ErrorCode.DB_QUERY_FAILED,\n {\n runId: this.currentRunId,\n projectId: this.projectId,\n operation: 'loadActiveStack',\n },\n error instanceof Error ? error : undefined\n );\n }\n throw dbError;\n }\n }\n\n private buildStackOrder(\n frames: Pick<Frame, 'frame_id' | 'parent_frame_id' | 'depth'>[]\n ): string[] {\n const stack: string[] = [];\n\n // Find root frame (no parent)\n const rootFrame = frames.find((f) => !f.parent_frame_id);\n if (!rootFrame) return [];\n\n // Build stack by following parent-child relationships\n let currentFrame = rootFrame;\n stack.push(currentFrame.frame_id);\n\n while (currentFrame) {\n const childFrame = frames.find(\n (f) => f.parent_frame_id === currentFrame.frame_id\n );\n if (!childFrame) break;\n stack.push(childFrame.frame_id);\n currentFrame = childFrame;\n }\n\n return stack;\n }\n\n /**\n * Create a new frame and push to stack\n */\n public createFrame(options: {\n type: FrameType;\n name: string;\n inputs?: Record<string, any>;\n parentFrameId?: string;\n }): string {\n return this._createFrame(options);\n }\n\n private _createFrame(options: {\n type: FrameType;\n name: string;\n inputs?: Record<string, any>;\n parentFrameId?: string;\n }): string {\n const frameId = uuidv4();\n const parentFrameId = options.parentFrameId || this.getCurrentFrameId();\n const depth = parentFrameId ? this.getFrameDepth(parentFrameId) + 1 : 0;\n\n // Check for depth limit\n if (depth > this.maxFrameDepth) {\n throw new FrameError(\n `Maximum frame depth exceeded: ${depth} > ${this.maxFrameDepth}`,\n ErrorCode.FRAME_STACK_OVERFLOW,\n {\n currentDepth: depth,\n maxDepth: this.maxFrameDepth,\n frameId,\n parentFrameId,\n frameName: options.name,\n }\n );\n }\n\n // Check for circular reference before creating frame\n if (parentFrameId) {\n const cycle = this.detectCycle(frameId, parentFrameId);\n if (cycle) {\n throw new FrameError(\n `Circular reference detected in frame hierarchy`,\n ErrorCode.FRAME_CYCLE_DETECTED,\n {\n frameId,\n parentFrameId,\n cycle,\n frameName: options.name,\n }\n );\n }\n }\n\n const frame: Omit<\n Frame,\n 'outputs' | 'digest_text' | 'digest_json' | 'closed_at'\n > = {\n frame_id: frameId,\n run_id: this.currentRunId,\n project_id: this.projectId,\n parent_frame_id: parentFrameId,\n depth,\n type: options.type,\n name: options.name,\n state: 'active',\n inputs: options.inputs || {},\n created_at: Math.floor(Date.now() / 1000),\n };\n\n try {\n this.db\n .prepare(\n `\n INSERT INTO frames (\n frame_id, run_id, project_id, parent_frame_id, depth, type, name, state, inputs, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n frame.frame_id,\n frame.run_id,\n frame.project_id,\n frame.parent_frame_id,\n frame.depth,\n frame.type,\n frame.name,\n frame.state,\n JSON.stringify(frame.inputs),\n frame.created_at\n );\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to create frame: ${options.name}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId,\n frameType: options.type,\n frameName: options.name,\n parentFrameId,\n depth,\n operation: 'createFrame',\n },\n error instanceof Error ? error : undefined\n );\n }\n\n // Push to active stack\n this.activeStack.push(frameId);\n\n logger.info('Created frame', {\n frameId,\n type: options.type,\n name: options.name,\n depth,\n parentFrameId,\n stackDepth: this.activeStack.length,\n });\n\n return frameId;\n }\n\n /**\n * Close the current frame and generate digest\n */\n public closeFrame(frameId?: string, outputs?: Record<string, any>): void {\n this._closeFrame(frameId, outputs);\n }\n\n private _closeFrame(frameId?: string, outputs?: Record<string, any>): void {\n const targetFrameId = frameId || this.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame to close',\n ErrorCode.FRAME_INVALID_STATE,\n {\n operation: 'closeFrame',\n activeStack: this.activeStack,\n stackDepth: this.activeStack.length,\n }\n );\n }\n\n // Get frame details\n const frame = this.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.generateDigest(targetFrameId);\n const finalOutputs = { ...outputs, ...digest.structured };\n\n try {\n // Update frame to closed state\n this.db\n .prepare(\n `\n UPDATE frames\n SET state = 'closed',\n outputs = ?,\n digest_text = ?,\n digest_json = ?,\n closed_at = unixepoch()\n WHERE frame_id = ?\n `\n )\n .run(\n JSON.stringify(finalOutputs),\n digest.text,\n JSON.stringify(digest.structured),\n targetFrameId\n );\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to close frame: ${targetFrameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId: targetFrameId,\n frameName: frame.name,\n operation: 'closeFrame',\n },\n error instanceof Error ? error : undefined\n );\n }\n\n // Remove from active stack\n this.activeStack = this.activeStack.filter((id) => id !== 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.activeStack.length,\n });\n }\n\n /**\n * Delete a frame completely from the database (used in handoffs)\n */\n deleteFrame(frameId: string): void {\n try {\n // First delete related data\n this.db.prepare('DELETE FROM events WHERE frame_id = ?').run(frameId);\n this.db.prepare('DELETE FROM anchors WHERE frame_id = ?').run(frameId);\n\n // Remove from active stack if present\n this.activeStack = this.activeStack.filter((id) => id !== frameId);\n\n // Delete the frame itself\n this.db.prepare('DELETE FROM frames WHERE frame_id = ?').run(frameId);\n\n logger.debug('Deleted frame completely', { frameId });\n } catch (error: unknown) {\n logger.error('Failed to delete frame', { frameId, error });\n throw error;\n }\n }\n\n private closeChildFrames(parentFrameId: string) {\n try {\n const children = this.db\n .prepare(\n `\n SELECT frame_id FROM frames\n WHERE parent_frame_id = ? AND state = 'active'\n `\n )\n .all(parentFrameId) as { frame_id: string }[];\n\n children.forEach((child) => {\n try {\n this.closeFrame(child.frame_id);\n } catch (error: unknown) {\n logger.error(\n 'Failed to close child frame',\n error instanceof Error ? error : new Error(String(error)),\n {\n parentFrameId,\n childFrameId: child.frame_id,\n }\n );\n }\n });\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to close child frames for parent: ${parentFrameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n parentFrameId,\n operation: 'closeChildFrames',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Generate digest for a frame\n */\n private generateDigest(frameId: string): {\n text: string;\n structured: Record<string, any>;\n } {\n const frame = this.getFrame(frameId);\n const events = this.getFrameEvents(frameId);\n const anchors = this.getFrameAnchors(frameId);\n\n if (!frame) {\n throw new FrameError(\n `Cannot generate digest: frame not found ${frameId}`,\n ErrorCode.FRAME_NOT_FOUND,\n {\n frameId,\n operation: 'generateDigest',\n runId: this.currentRunId,\n }\n );\n }\n\n // Extract key information\n const decisions = anchors.filter((a) => a.type === 'DECISION');\n const constraints = anchors.filter((a) => a.type === 'CONSTRAINT');\n const risks = anchors.filter((a) => a.type === 'RISK');\n\n const toolCalls = events.filter((e) => e.event_type === 'tool_call');\n const artifacts = events.filter((e) => e.event_type === 'artifact');\n\n // Generate structured digest\n const structured = {\n result: frame.name,\n decisions: decisions.map((d) => ({ id: d.anchor_id, text: d.text })),\n constraints: constraints.map((c) => ({ id: c.anchor_id, text: c.text })),\n risks: risks.map((r) => ({ id: r.anchor_id, text: r.text })),\n artifacts: artifacts.map((a) => ({\n kind: a.payload.kind || 'unknown',\n ref: a.payload.ref,\n })),\n tool_calls_count: toolCalls.length,\n duration_seconds: frame.closed_at\n ? frame.closed_at - frame.created_at\n : 0,\n };\n\n // Generate text summary\n const text = this.generateDigestText(frame, structured, events.length);\n\n return { text, structured };\n }\n\n private generateDigestText(\n frame: Frame,\n structured: any,\n eventCount: number\n ): string {\n let summary = `Completed: ${frame.name}\\n`;\n\n if (structured.decisions.length > 0) {\n summary += `\\nDecisions made:\\n${structured.decisions.map((d: any) => `- ${d.text}`).join('\\n')}`;\n }\n\n if (structured.constraints.length > 0) {\n summary += `\\nConstraints established:\\n${structured.constraints.map((c: any) => `- ${c.text}`).join('\\n')}`;\n }\n\n if (structured.risks.length > 0) {\n summary += `\\nRisks identified:\\n${structured.risks.map((r: any) => `- ${r.text}`).join('\\n')}`;\n }\n\n summary += `\\nActivity: ${eventCount} events, ${structured.tool_calls_count} tool calls`;\n\n if (structured.duration_seconds > 0) {\n summary += `, ${Math.floor(structured.duration_seconds / 60)}m ${structured.duration_seconds % 60}s duration`;\n }\n\n return summary;\n }\n\n /**\n * Add event to current frame\n */\n public addEvent(\n eventType: Event['event_type'],\n payload: Record<string, any>,\n frameId?: string\n ): string {\n const targetFrameId = frameId || this.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame for event',\n ErrorCode.FRAME_INVALID_STATE,\n {\n operation: 'addEvent',\n eventType,\n activeStack: this.activeStack,\n }\n );\n }\n\n const eventId = uuidv4();\n const seq = this.getNextEventSequence(targetFrameId);\n\n try {\n this.db\n .prepare(\n `\n INSERT INTO events (event_id, run_id, frame_id, seq, event_type, payload)\n VALUES (?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n eventId,\n this.currentRunId,\n targetFrameId,\n seq,\n eventType,\n JSON.stringify(payload)\n );\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to add event to frame: ${targetFrameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n eventId,\n frameId: targetFrameId,\n eventType,\n seq,\n operation: 'addEvent',\n },\n error instanceof Error ? error : undefined\n );\n }\n\n return eventId;\n }\n\n /**\n * Add anchor to frame\n */\n public addAnchor(\n type: Anchor['type'],\n text: string,\n priority: number = 0,\n metadata: Record<string, any> = {},\n frameId?: string\n ): string {\n const targetFrameId = frameId || this.getCurrentFrameId();\n if (!targetFrameId) {\n throw new FrameError(\n 'No active frame for anchor',\n ErrorCode.FRAME_INVALID_STATE,\n {\n operation: 'addAnchor',\n anchorType: type,\n text: text.substring(0, 100),\n activeStack: this.activeStack,\n }\n );\n }\n\n const anchorId = uuidv4();\n\n try {\n this.db\n .prepare(\n `\n INSERT INTO anchors (anchor_id, frame_id, project_id, type, text, priority, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n anchorId,\n targetFrameId,\n this.projectId,\n type,\n text,\n priority,\n JSON.stringify(metadata)\n );\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to add anchor to frame: ${targetFrameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n anchorId,\n frameId: targetFrameId,\n anchorType: type,\n operation: 'addAnchor',\n },\n error instanceof Error ? error : undefined\n );\n }\n\n return anchorId;\n }\n\n /**\n * Get hot stack context for current active frames\n */\n public getHotStackContext(maxEvents: number = 20): FrameContext[] {\n return this.activeStack\n .map((frameId) => {\n const frame = this.getFrame(frameId);\n if (!frame) return null;\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: this.getFrameAnchors(frameId),\n recentEvents: this.getFrameEvents(frameId, maxEvents),\n activeArtifacts: this.getActiveArtifacts(frameId),\n };\n })\n .filter(Boolean) as FrameContext[];\n }\n\n /**\n * Get active frame path (root to current)\n */\n public getActiveFramePath(): Frame[] {\n return this.activeStack\n .map((frameId) => this.getFrame(frameId))\n .filter(Boolean) as Frame[];\n }\n\n // Utility methods\n public getCurrentFrameId(): string | undefined {\n return this.activeStack[this.activeStack.length - 1];\n }\n\n public getStackDepth(): number {\n return this.activeStack.length;\n }\n\n /**\n * Get recent frames for context sharing\n */\n public async getRecentFrames(limit: number = 100): Promise<Frame[]> {\n try {\n const rows = this.db\n .prepare(\n `\n SELECT * FROM frames \n WHERE project_id = ?\n ORDER BY created_at DESC\n LIMIT ?\n `\n )\n .all(this.projectId, limit) as any[];\n\n return rows.map((row) => ({\n ...row,\n frameId: row.frame_id,\n runId: row.run_id,\n projectId: row.project_id,\n parentFrameId: row.parent_frame_id,\n title: row.name,\n timestamp: row.created_at,\n metadata: {\n tags: this.extractTagsFromFrame(row),\n importance: this.calculateFrameImportance(row),\n },\n data: {\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest: JSON.parse(row.digest_json || '{}'),\n },\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest_json: JSON.parse(row.digest_json || '{}'),\n }));\n } catch (error: unknown) {\n logger.error('Failed to get recent frames', error as Error);\n return [];\n }\n }\n\n /**\n * Add context metadata to the current frame\n */\n public async addContext(key: string, value: any): Promise<void> {\n const currentFrameId = this.getCurrentFrameId();\n if (!currentFrameId) return;\n\n try {\n const frame = this.getFrame(currentFrameId);\n if (!frame) return;\n\n const metadata = frame.outputs || {};\n metadata[key] = value;\n\n this.db\n .prepare(`UPDATE frames SET outputs = ? WHERE frame_id = ?`)\n .run(JSON.stringify(metadata), currentFrameId);\n } catch (error: unknown) {\n logger.warn('Failed to add context to frame', { error, key });\n }\n }\n\n private extractTagsFromFrame(frame: any): string[] {\n const tags: string[] = [];\n\n // Add type as tag\n if (frame.type) tags.push(frame.type);\n\n // Extract tags from name\n if (frame.name) {\n if (frame.name.toLowerCase().includes('error')) tags.push('error');\n if (frame.name.toLowerCase().includes('fix')) tags.push('resolution');\n if (frame.name.toLowerCase().includes('decision')) tags.push('decision');\n if (frame.name.toLowerCase().includes('milestone'))\n tags.push('milestone');\n }\n\n // Extract from digest\n try {\n const digest = JSON.parse(frame.digest_json || '{}');\n if (digest.tags) tags.push(...digest.tags);\n } catch {}\n\n return [...new Set(tags)];\n }\n\n private calculateFrameImportance(frame: any): 'high' | 'medium' | 'low' {\n // Milestones and decisions are high importance\n if (frame.type === 'milestone' || frame.name?.includes('decision'))\n return 'high';\n\n // Errors and resolutions are medium importance\n if (frame.type === 'error' || frame.type === 'resolution') return 'medium';\n\n // Long-running frames are potentially important\n if (frame.closed_at && frame.created_at) {\n const duration = frame.closed_at - frame.created_at;\n if (duration > 300) return 'medium'; // More than 5 minutes\n }\n\n return 'low';\n }\n\n private getFrameDepth(frameId: string): number {\n const frame = this.getFrame(frameId);\n return frame?.depth || 0;\n }\n\n public getFrame(frameId: string): Frame | undefined {\n try {\n const row = this.db\n .prepare(\n `\n SELECT * FROM frames WHERE frame_id = ?\n `\n )\n .get(frameId) as any;\n\n if (!row) return undefined;\n\n return {\n ...row,\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest_json: JSON.parse(row.digest_json || '{}'),\n };\n } catch (error: unknown) {\n // Log the error but return undefined instead of throwing\n logger.warn(`Failed to get frame: ${frameId}`, {\n error: error instanceof Error ? error.message : String(error),\n frameId,\n operation: 'getFrame',\n });\n return undefined;\n }\n }\n\n public getFrameEvents(frameId: string, limit?: number): Event[] {\n try {\n const query = limit\n ? `SELECT * FROM events WHERE frame_id = ? ORDER BY seq DESC LIMIT ?`\n : `SELECT * FROM events WHERE frame_id = ? ORDER BY seq ASC`;\n\n const params = limit ? [frameId, limit] : [frameId];\n const rows = this.db.prepare(query).all(...params) as any[];\n\n return rows.map((row) => ({\n ...row,\n payload: JSON.parse(row.payload),\n }));\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to get frame events: ${frameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId,\n limit,\n operation: 'getFrameEvents',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private getFrameAnchors(frameId: string): Anchor[] {\n try {\n const rows = this.db\n .prepare(\n `\n SELECT * FROM anchors WHERE frame_id = ? ORDER BY priority DESC, created_at ASC\n `\n )\n .all(frameId) as any[];\n\n return rows.map((row) => ({\n ...row,\n metadata: JSON.parse(row.metadata || '{}'),\n }));\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to get frame anchors: ${frameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId,\n operation: 'getFrameAnchors',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private getNextEventSequence(frameId: string): number {\n try {\n const result = this.db\n .prepare(\n `\n SELECT MAX(seq) as max_seq FROM events WHERE frame_id = ?\n `\n )\n .get(frameId) as { max_seq: number | null };\n\n return (result.max_seq || 0) + 1;\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to get next event sequence for frame: ${frameId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId,\n operation: 'getNextEventSequence',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private extractConstraints(\n inputs: Record<string, any>\n ): string[] | undefined {\n return inputs.constraints;\n }\n\n private getActiveArtifacts(frameId: string): string[] {\n const artifacts = this.getFrameEvents(frameId)\n .filter((e) => e.event_type === 'artifact')\n .map((e) => e.payload.ref)\n .filter(Boolean);\n\n return artifacts;\n }\n\n /**\n * Detect if setting a parent frame would create a cycle in the frame hierarchy.\n * Returns the cycle path if detected, or null if no cycle.\n * @param childFrameId - The frame that would be the child\n * @param parentFrameId - The proposed parent frame\n * @returns Array of frame IDs forming the cycle, or null if no cycle\n */\n private detectCycle(\n childFrameId: string,\n parentFrameId: string\n ): string[] | null {\n const visited = new Set<string>();\n const path: string[] = [];\n\n // Start from the proposed parent and traverse up the hierarchy\n let currentId: string | undefined = parentFrameId;\n \n while (currentId) {\n // If we've seen this frame before, we have a cycle\n if (visited.has(currentId)) {\n // Build the cycle path\n const cycleStart = path.indexOf(currentId);\n return path.slice(cycleStart).concat(currentId);\n }\n\n // If the current frame is the child we're trying to add, it's a cycle\n if (currentId === childFrameId) {\n return path.concat([currentId, childFrameId]);\n }\n\n visited.add(currentId);\n path.push(currentId);\n\n // Move to the parent of current frame\n const frame = this.getFrame(currentId);\n if (!frame) {\n // Frame not found, no cycle possible through this path\n break;\n }\n currentId = frame.parent_frame_id;\n\n // Safety check: if we've traversed too many levels, something is wrong\n if (path.length > this.maxFrameDepth) {\n throw new FrameError(\n `Frame hierarchy traversal exceeded maximum depth during cycle detection`,\n ErrorCode.FRAME_STACK_OVERFLOW,\n {\n depth: path.length,\n maxDepth: this.maxFrameDepth,\n path,\n }\n );\n }\n }\n\n return null; // No cycle detected\n }\n\n /**\n * Update parent frame of an existing frame (with cycle detection)\n * @param frameId - The frame to update\n * @param newParentFrameId - The new parent frame ID\n */\n public updateParentFrame(frameId: string, newParentFrameId: string | null): void {\n // Check if frame exists\n const frame = this.getFrame(frameId);\n if (!frame) {\n throw new FrameError(\n `Frame not found: ${frameId}`,\n ErrorCode.FRAME_NOT_FOUND,\n { frameId }\n );\n }\n\n // If setting a parent, check for cycles\n if (newParentFrameId) {\n const cycle = this.detectCycle(frameId, newParentFrameId);\n if (cycle) {\n throw new FrameError(\n `Cannot set parent: would create circular reference`,\n ErrorCode.FRAME_CYCLE_DETECTED,\n {\n frameId,\n newParentFrameId,\n cycle,\n currentParentId: frame.parent_frame_id,\n }\n );\n }\n\n // Check depth after parent change\n const newParentFrame = this.getFrame(newParentFrameId);\n if (newParentFrame) {\n const newDepth = newParentFrame.depth + 1;\n if (newDepth > this.maxFrameDepth) {\n throw new FrameError(\n `Cannot set parent: would exceed maximum frame depth`,\n ErrorCode.FRAME_STACK_OVERFLOW,\n {\n frameId,\n newParentFrameId,\n newDepth,\n maxDepth: this.maxFrameDepth,\n }\n );\n }\n }\n }\n\n try {\n // Update the parent frame\n this.db\n .prepare(\n `UPDATE frames SET parent_frame_id = ? WHERE frame_id = ?`\n )\n .run(newParentFrameId, frameId);\n\n logger.info('Updated parent frame', {\n frameId,\n oldParentId: frame.parent_frame_id,\n newParentId: newParentFrameId,\n });\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to update parent frame`,\n ErrorCode.DB_UPDATE_FAILED,\n {\n frameId,\n newParentFrameId,\n operation: 'updateParentFrame',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }