javi-forge 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/ci-local/ci-local.sh +38 -10
  2. package/ci-local/hooks/pre-commit +10 -155
  3. package/ci-local/hooks/pre-push +12 -29
  4. package/dist/commands/ci.d.ts +33 -0
  5. package/dist/commands/ci.js +341 -0
  6. package/dist/commands/init.js +5 -0
  7. package/dist/index.js +39 -5
  8. package/dist/lib/docker.d.ts +43 -0
  9. package/dist/lib/docker.js +223 -0
  10. package/dist/ui/CI.d.ts +9 -0
  11. package/dist/ui/CI.js +91 -0
  12. package/package.json +9 -1
  13. package/ai-config/.skillignore +0 -15
  14. package/ai-config/AUTO_INVOKE.md +0 -300
  15. package/ai-config/agents/_TEMPLATE.md +0 -93
  16. package/ai-config/agents/business/api-designer.md +0 -1657
  17. package/ai-config/agents/business/business-analyst.md +0 -1331
  18. package/ai-config/agents/business/product-strategist.md +0 -206
  19. package/ai-config/agents/business/project-manager.md +0 -178
  20. package/ai-config/agents/business/requirements-analyst.md +0 -1277
  21. package/ai-config/agents/business/technical-writer.md +0 -1679
  22. package/ai-config/agents/creative/ux-designer.md +0 -205
  23. package/ai-config/agents/data-ai/ai-engineer.md +0 -487
  24. package/ai-config/agents/data-ai/analytics-engineer.md +0 -953
  25. package/ai-config/agents/data-ai/data-engineer.md +0 -173
  26. package/ai-config/agents/data-ai/data-scientist.md +0 -672
  27. package/ai-config/agents/data-ai/mlops-engineer.md +0 -814
  28. package/ai-config/agents/data-ai/prompt-engineer.md +0 -772
  29. package/ai-config/agents/development/angular-expert.md +0 -620
  30. package/ai-config/agents/development/backend-architect.md +0 -795
  31. package/ai-config/agents/development/database-specialist.md +0 -212
  32. package/ai-config/agents/development/frontend-specialist.md +0 -686
  33. package/ai-config/agents/development/fullstack-engineer.md +0 -668
  34. package/ai-config/agents/development/golang-pro.md +0 -338
  35. package/ai-config/agents/development/java-enterprise.md +0 -400
  36. package/ai-config/agents/development/javascript-pro.md +0 -422
  37. package/ai-config/agents/development/nextjs-pro.md +0 -474
  38. package/ai-config/agents/development/python-pro.md +0 -570
  39. package/ai-config/agents/development/react-pro.md +0 -487
  40. package/ai-config/agents/development/rust-pro.md +0 -246
  41. package/ai-config/agents/development/spring-boot-4-expert.md +0 -326
  42. package/ai-config/agents/development/typescript-pro.md +0 -336
  43. package/ai-config/agents/development/vue-specialist.md +0 -605
  44. package/ai-config/agents/infrastructure/cloud-architect.md +0 -472
  45. package/ai-config/agents/infrastructure/deployment-manager.md +0 -358
  46. package/ai-config/agents/infrastructure/devops-engineer.md +0 -455
  47. package/ai-config/agents/infrastructure/incident-responder.md +0 -519
  48. package/ai-config/agents/infrastructure/kubernetes-expert.md +0 -705
  49. package/ai-config/agents/infrastructure/monitoring-specialist.md +0 -674
  50. package/ai-config/agents/infrastructure/performance-engineer.md +0 -658
  51. package/ai-config/agents/orchestrator.md +0 -241
  52. package/ai-config/agents/quality/accessibility-auditor.md +0 -1204
  53. package/ai-config/agents/quality/code-reviewer-compact.md +0 -123
  54. package/ai-config/agents/quality/code-reviewer.md +0 -363
  55. package/ai-config/agents/quality/dependency-manager.md +0 -743
  56. package/ai-config/agents/quality/e2e-test-specialist.md +0 -1005
  57. package/ai-config/agents/quality/performance-tester.md +0 -1086
  58. package/ai-config/agents/quality/security-auditor.md +0 -133
  59. package/ai-config/agents/quality/test-engineer.md +0 -453
  60. package/ai-config/agents/specialists/api-designer.md +0 -87
  61. package/ai-config/agents/specialists/backend-architect.md +0 -73
  62. package/ai-config/agents/specialists/code-reviewer.md +0 -77
  63. package/ai-config/agents/specialists/db-optimizer.md +0 -75
  64. package/ai-config/agents/specialists/devops-engineer.md +0 -83
  65. package/ai-config/agents/specialists/documentation-writer.md +0 -78
  66. package/ai-config/agents/specialists/frontend-developer.md +0 -75
  67. package/ai-config/agents/specialists/performance-analyst.md +0 -82
  68. package/ai-config/agents/specialists/refactor-specialist.md +0 -74
  69. package/ai-config/agents/specialists/security-auditor.md +0 -74
  70. package/ai-config/agents/specialists/test-engineer.md +0 -81
  71. package/ai-config/agents/specialists/ux-consultant.md +0 -76
  72. package/ai-config/agents/specialized/agent-generator.md +0 -1190
  73. package/ai-config/agents/specialized/blockchain-developer.md +0 -149
  74. package/ai-config/agents/specialized/code-migrator.md +0 -892
  75. package/ai-config/agents/specialized/context-manager.md +0 -978
  76. package/ai-config/agents/specialized/documentation-writer.md +0 -1078
  77. package/ai-config/agents/specialized/ecommerce-expert.md +0 -1756
  78. package/ai-config/agents/specialized/embedded-engineer.md +0 -1714
  79. package/ai-config/agents/specialized/error-detective.md +0 -1034
  80. package/ai-config/agents/specialized/fintech-specialist.md +0 -1659
  81. package/ai-config/agents/specialized/freelance-project-planner-v2.md +0 -1988
  82. package/ai-config/agents/specialized/freelance-project-planner-v3.md +0 -2136
  83. package/ai-config/agents/specialized/freelance-project-planner-v4.md +0 -4503
  84. package/ai-config/agents/specialized/freelance-project-planner.md +0 -722
  85. package/ai-config/agents/specialized/game-developer.md +0 -1963
  86. package/ai-config/agents/specialized/healthcare-dev.md +0 -1620
  87. package/ai-config/agents/specialized/mobile-developer.md +0 -188
  88. package/ai-config/agents/specialized/parallel-plan-executor.md +0 -506
  89. package/ai-config/agents/specialized/plan-executor.md +0 -485
  90. package/ai-config/agents/specialized/solo-dev-planner-modular/00-INDEX.md +0 -485
  91. package/ai-config/agents/specialized/solo-dev-planner-modular/01-CORE.md +0 -3493
  92. package/ai-config/agents/specialized/solo-dev-planner-modular/02-SELF-CORRECTION.md +0 -778
  93. package/ai-config/agents/specialized/solo-dev-planner-modular/03-PROGRESSIVE-SETUP.md +0 -918
  94. package/ai-config/agents/specialized/solo-dev-planner-modular/04-DEPLOYMENT.md +0 -1537
  95. package/ai-config/agents/specialized/solo-dev-planner-modular/05-TESTING.md +0 -2633
  96. package/ai-config/agents/specialized/solo-dev-planner-modular/06-OPERATIONS.md +0 -5610
  97. package/ai-config/agents/specialized/solo-dev-planner-modular/INSTALL.md +0 -335
  98. package/ai-config/agents/specialized/solo-dev-planner-modular/QUICK-REFERENCE.txt +0 -215
  99. package/ai-config/agents/specialized/solo-dev-planner-modular/README.md +0 -260
  100. package/ai-config/agents/specialized/solo-dev-planner-modular/START-HERE.md +0 -379
  101. package/ai-config/agents/specialized/solo-dev-planner-modular/WORKFLOW-DIAGRAM.md +0 -355
  102. package/ai-config/agents/specialized/solo-dev-planner-modular/solo-dev-planner.md +0 -279
  103. package/ai-config/agents/specialized/template-writer.md +0 -347
  104. package/ai-config/agents/specialized/test-runner.md +0 -99
  105. package/ai-config/agents/specialized/vibekanban-smart-worker.md +0 -244
  106. package/ai-config/agents/specialized/wave-executor.md +0 -138
  107. package/ai-config/agents/specialized/workflow-optimizer.md +0 -1114
  108. package/ai-config/commands/git/changelog.md +0 -32
  109. package/ai-config/commands/git/ci-local.md +0 -70
  110. package/ai-config/commands/git/commit.md +0 -35
  111. package/ai-config/commands/git/fix-issue.md +0 -23
  112. package/ai-config/commands/git/pr-create.md +0 -42
  113. package/ai-config/commands/git/pr-review.md +0 -50
  114. package/ai-config/commands/git/worktree.md +0 -39
  115. package/ai-config/commands/refactoring/cleanup.md +0 -24
  116. package/ai-config/commands/refactoring/dead-code.md +0 -40
  117. package/ai-config/commands/refactoring/extract.md +0 -31
  118. package/ai-config/commands/testing/e2e.md +0 -30
  119. package/ai-config/commands/testing/tdd.md +0 -36
  120. package/ai-config/commands/testing/test-coverage.md +0 -30
  121. package/ai-config/commands/testing/test-fix.md +0 -24
  122. package/ai-config/commands/workflow/generate-agents-md.md +0 -85
  123. package/ai-config/commands/workflow/planning.md +0 -47
  124. package/ai-config/commands/workflows/compound.md +0 -89
  125. package/ai-config/commands/workflows/diagnose.md +0 -70
  126. package/ai-config/commands/workflows/discover.md +0 -86
  127. package/ai-config/commands/workflows/plan.md +0 -77
  128. package/ai-config/commands/workflows/review.md +0 -78
  129. package/ai-config/commands/workflows/work.md +0 -75
  130. package/ai-config/config.yaml +0 -18
  131. package/ai-config/hooks/_TEMPLATE.md +0 -96
  132. package/ai-config/hooks/block-dangerous-commands.md +0 -75
  133. package/ai-config/hooks/commit-guard.md +0 -90
  134. package/ai-config/hooks/context-loader.md +0 -73
  135. package/ai-config/hooks/improve-prompt.md +0 -91
  136. package/ai-config/hooks/learning-log.md +0 -72
  137. package/ai-config/hooks/model-router.md +0 -86
  138. package/ai-config/hooks/secret-scanner.md +0 -64
  139. package/ai-config/hooks/skill-validator.md +0 -102
  140. package/ai-config/hooks/task-artifact.md +0 -114
  141. package/ai-config/hooks/validate-workflow.md +0 -100
  142. package/ai-config/prompts/base.md +0 -71
  143. package/ai-config/prompts/modes/debug.md +0 -34
  144. package/ai-config/prompts/modes/deploy.md +0 -40
  145. package/ai-config/prompts/modes/research.md +0 -32
  146. package/ai-config/prompts/modes/review.md +0 -33
  147. package/ai-config/prompts/review-policy.md +0 -79
  148. package/ai-config/skills/_TEMPLATE.md +0 -157
  149. package/ai-config/skills/backend/api-gateway/SKILL.md +0 -254
  150. package/ai-config/skills/backend/bff-concepts/SKILL.md +0 -239
  151. package/ai-config/skills/backend/bff-spring/SKILL.md +0 -364
  152. package/ai-config/skills/backend/chi-router/SKILL.md +0 -396
  153. package/ai-config/skills/backend/error-handling/SKILL.md +0 -255
  154. package/ai-config/skills/backend/exceptions-spring/SKILL.md +0 -323
  155. package/ai-config/skills/backend/fastapi/SKILL.md +0 -302
  156. package/ai-config/skills/backend/gateway-spring/SKILL.md +0 -390
  157. package/ai-config/skills/backend/go-backend/SKILL.md +0 -457
  158. package/ai-config/skills/backend/gradle-multimodule/SKILL.md +0 -274
  159. package/ai-config/skills/backend/graphql-concepts/SKILL.md +0 -352
  160. package/ai-config/skills/backend/graphql-spring/SKILL.md +0 -398
  161. package/ai-config/skills/backend/grpc-concepts/SKILL.md +0 -283
  162. package/ai-config/skills/backend/grpc-spring/SKILL.md +0 -445
  163. package/ai-config/skills/backend/jwt-auth/SKILL.md +0 -412
  164. package/ai-config/skills/backend/notifications-concepts/SKILL.md +0 -259
  165. package/ai-config/skills/backend/recommendations-concepts/SKILL.md +0 -261
  166. package/ai-config/skills/backend/search-concepts/SKILL.md +0 -263
  167. package/ai-config/skills/backend/search-spring/SKILL.md +0 -375
  168. package/ai-config/skills/backend/spring-boot-4/SKILL.md +0 -172
  169. package/ai-config/skills/backend/websockets/SKILL.md +0 -532
  170. package/ai-config/skills/data-ai/ai-ml/SKILL.md +0 -423
  171. package/ai-config/skills/data-ai/analytics-concepts/SKILL.md +0 -195
  172. package/ai-config/skills/data-ai/analytics-spring/SKILL.md +0 -340
  173. package/ai-config/skills/data-ai/duckdb-analytics/SKILL.md +0 -440
  174. package/ai-config/skills/data-ai/langchain/SKILL.md +0 -238
  175. package/ai-config/skills/data-ai/mlflow/SKILL.md +0 -302
  176. package/ai-config/skills/data-ai/onnx-inference/SKILL.md +0 -290
  177. package/ai-config/skills/data-ai/powerbi/SKILL.md +0 -352
  178. package/ai-config/skills/data-ai/pytorch/SKILL.md +0 -274
  179. package/ai-config/skills/data-ai/scikit-learn/SKILL.md +0 -321
  180. package/ai-config/skills/data-ai/vector-db/SKILL.md +0 -301
  181. package/ai-config/skills/database/graph-databases/SKILL.md +0 -218
  182. package/ai-config/skills/database/graph-spring/SKILL.md +0 -361
  183. package/ai-config/skills/database/pgx-postgres/SKILL.md +0 -512
  184. package/ai-config/skills/database/redis-cache/SKILL.md +0 -343
  185. package/ai-config/skills/database/sqlite-embedded/SKILL.md +0 -388
  186. package/ai-config/skills/database/timescaledb/SKILL.md +0 -320
  187. package/ai-config/skills/docs/api-documentation/SKILL.md +0 -293
  188. package/ai-config/skills/docs/docs-spring/SKILL.md +0 -377
  189. package/ai-config/skills/docs/mustache-templates/SKILL.md +0 -190
  190. package/ai-config/skills/docs/technical-docs/SKILL.md +0 -447
  191. package/ai-config/skills/frontend/astro-ssr/SKILL.md +0 -441
  192. package/ai-config/skills/frontend/frontend-design/SKILL.md +0 -54
  193. package/ai-config/skills/frontend/frontend-web/SKILL.md +0 -368
  194. package/ai-config/skills/frontend/mantine-ui/SKILL.md +0 -396
  195. package/ai-config/skills/frontend/tanstack-query/SKILL.md +0 -439
  196. package/ai-config/skills/frontend/zod-validation/SKILL.md +0 -417
  197. package/ai-config/skills/frontend/zustand-state/SKILL.md +0 -350
  198. package/ai-config/skills/infrastructure/chaos-engineering/SKILL.md +0 -244
  199. package/ai-config/skills/infrastructure/chaos-spring/SKILL.md +0 -378
  200. package/ai-config/skills/infrastructure/devops-infra/SKILL.md +0 -435
  201. package/ai-config/skills/infrastructure/docker-containers/SKILL.md +0 -420
  202. package/ai-config/skills/infrastructure/kubernetes/SKILL.md +0 -456
  203. package/ai-config/skills/infrastructure/opentelemetry/SKILL.md +0 -546
  204. package/ai-config/skills/infrastructure/traefik-proxy/SKILL.md +0 -474
  205. package/ai-config/skills/infrastructure/woodpecker-ci/SKILL.md +0 -315
  206. package/ai-config/skills/mobile/ionic-capacitor/SKILL.md +0 -504
  207. package/ai-config/skills/mobile/mobile-ionic/SKILL.md +0 -448
  208. package/ai-config/skills/prompt-improver/SKILL.md +0 -125
  209. package/ai-config/skills/quality/ghagga-review/SKILL.md +0 -216
  210. package/ai-config/skills/references/hooks-patterns/SKILL.md +0 -238
  211. package/ai-config/skills/references/mcp-servers/SKILL.md +0 -275
  212. package/ai-config/skills/references/plugins-reference/SKILL.md +0 -110
  213. package/ai-config/skills/references/skills-reference/SKILL.md +0 -420
  214. package/ai-config/skills/references/subagent-templates/SKILL.md +0 -193
  215. package/ai-config/skills/systems-iot/modbus-protocol/SKILL.md +0 -410
  216. package/ai-config/skills/systems-iot/mqtt-rumqttc/SKILL.md +0 -408
  217. package/ai-config/skills/systems-iot/rust-systems/SKILL.md +0 -386
  218. package/ai-config/skills/systems-iot/tokio-async/SKILL.md +0 -324
  219. package/ai-config/skills/testing/playwright-e2e/SKILL.md +0 -289
  220. package/ai-config/skills/testing/testcontainers/SKILL.md +0 -299
  221. package/ai-config/skills/testing/vitest-testing/SKILL.md +0 -381
  222. package/ai-config/skills/workflow/ci-local-guide/SKILL.md +0 -118
  223. package/ai-config/skills/workflow/claude-automation-recommender/SKILL.md +0 -299
  224. package/ai-config/skills/workflow/claude-md-improver/SKILL.md +0 -158
  225. package/ai-config/skills/workflow/finishing-a-development-branch/SKILL.md +0 -117
  226. package/ai-config/skills/workflow/git-github/SKILL.md +0 -334
  227. package/ai-config/skills/workflow/git-github/references/examples.md +0 -160
  228. package/ai-config/skills/workflow/git-workflow/SKILL.md +0 -214
  229. package/ai-config/skills/workflow/ide-plugins/SKILL.md +0 -277
  230. package/ai-config/skills/workflow/ide-plugins-intellij/SKILL.md +0 -401
  231. package/ai-config/skills/workflow/obsidian-brain-workflow/SKILL.md +0 -199
  232. package/ai-config/skills/workflow/using-git-worktrees/SKILL.md +0 -100
  233. package/ai-config/skills/workflow/verification-before-completion/SKILL.md +0 -73
  234. package/ai-config/skills/workflow/wave-workflow/SKILL.md +0 -178
  235. package/schemas/agent.schema.json +0 -34
  236. package/schemas/ai-config.schema.json +0 -28
  237. package/schemas/plugin.schema.json +0 -62
  238. package/schemas/skill.schema.json +0 -44
@@ -1,978 +0,0 @@
1
- ---
2
- name: context-manager
3
- description: Advanced session continuity, memory management, context preservation, and intelligent state handling
4
- trigger: >
5
- context window, session state, memory management, context preservation,
6
- long conversation, session continuity, state handling, context compression
7
- category: specialized
8
- color: purple
9
- tools: Write, Read, MultiEdit, Bash, Grep, Glob, Task
10
- config:
11
- model: opus
12
- metadata:
13
- version: "2.0"
14
- updated: "2026-02"
15
- ---
16
-
17
- You are a context management specialist with expertise in session continuity, memory optimization, state preservation, and intelligent context handling for complex workflows.
18
-
19
- ## Core Expertise
20
- - Session state management and persistence
21
- - Context window optimization and compression
22
- - Memory management and garbage collection
23
- - State machine design and implementation
24
- - Distributed session management
25
- - Context switching and restoration
26
- - Cache management and optimization
27
- - Event sourcing and CQRS patterns
28
-
29
- ## Technical Stack
30
- - **State Management**: Redux, MobX, Zustand, XState
31
- - **Persistence**: Redis, Memcached, IndexedDB, LocalStorage
32
- - **Session**: JWT, OAuth, Session cookies, WebSockets
33
- - **Caching**: Varnish, CloudFlare, CDN strategies
34
- - **Databases**: PostgreSQL, MongoDB, DynamoDB, Cassandra
35
- - **Message Queues**: RabbitMQ, Kafka, Redis Pub/Sub
36
- - **Monitoring**: OpenTelemetry, Jaeger, Datadog
37
-
38
- ## Advanced Context Management Framework
39
- ```typescript
40
- // context-manager.ts
41
- import { EventEmitter } from 'events';
42
- import * as crypto from 'crypto';
43
- import { LRUCache } from 'lru-cache';
44
- import { compress, decompress } from 'lz-string';
45
-
46
- interface ContextState {
47
- id: string;
48
- sessionId: string;
49
- userId?: string;
50
- data: Map<string, any>;
51
- metadata: ContextMetadata;
52
- history: ContextHistory[];
53
- checkpoints: Checkpoint[];
54
- created: Date;
55
- lastAccessed: Date;
56
- ttl?: number;
57
- }
58
-
59
- interface ContextMetadata {
60
- version: string;
61
- environment: string;
62
- features: Set<string>;
63
- permissions: Map<string, boolean>;
64
- tags: string[];
65
- priority: number;
66
- compressed: boolean;
67
- }
68
-
69
- interface ContextHistory {
70
- timestamp: Date;
71
- action: string;
72
- changes: Map<string, any>;
73
- userId?: string;
74
- metadata?: any;
75
- }
76
-
77
- interface Checkpoint {
78
- id: string;
79
- timestamp: Date;
80
- state: string; // Compressed state
81
- description?: string;
82
- automatic: boolean;
83
- }
84
-
85
- class ContextManager extends EventEmitter {
86
- private contexts: Map<string, ContextState>;
87
- private cache: LRUCache<string, any>;
88
- private compressionThreshold: number = 1024; // 1KB
89
- private maxHistorySize: number = 100;
90
- private maxCheckpoints: number = 10;
91
- private autoSaveInterval: number = 60000; // 1 minute
92
- private storage: StorageAdapter;
93
-
94
- constructor(options: ContextManagerOptions = {}) {
95
- super();
96
- this.contexts = new Map();
97
- this.cache = new LRUCache({
98
- max: options.maxCacheSize || 500,
99
- ttl: options.cacheTTL || 1000 * 60 * 60, // 1 hour
100
- updateAgeOnGet: true,
101
- updateAgeOnHas: true,
102
- });
103
-
104
- this.storage = options.storage || new InMemoryStorage();
105
- this.compressionThreshold = options.compressionThreshold || this.compressionThreshold;
106
-
107
- if (options.autoSave) {
108
- this.startAutoSave();
109
- }
110
-
111
- this.setupEventHandlers();
112
- }
113
-
114
- async createContext(sessionId: string, initialData?: any): Promise<string> {
115
- const contextId = this.generateContextId();
116
-
117
- const context: ContextState = {
118
- id: contextId,
119
- sessionId,
120
- data: new Map(Object.entries(initialData || {})),
121
- metadata: {
122
- version: '1.0.0',
123
- environment: process.env.NODE_ENV || 'development',
124
- features: new Set(),
125
- permissions: new Map(),
126
- tags: [],
127
- priority: 0,
128
- compressed: false,
129
- },
130
- history: [],
131
- checkpoints: [],
132
- created: new Date(),
133
- lastAccessed: new Date(),
134
- };
135
-
136
- this.contexts.set(contextId, context);
137
- await this.saveContext(contextId);
138
-
139
- this.emit('context:created', { contextId, sessionId });
140
-
141
- return contextId;
142
- }
143
-
144
- async getContext(contextId: string): Promise<ContextState | null> {
145
- // Check in-memory first
146
- let context = this.contexts.get(contextId);
147
-
148
- // Check cache
149
- if (!context) {
150
- context = this.cache.get(contextId);
151
- }
152
-
153
- // Load from storage
154
- if (!context) {
155
- context = await this.loadContext(contextId);
156
- if (context) {
157
- this.contexts.set(contextId, context);
158
- }
159
- }
160
-
161
- if (context) {
162
- context.lastAccessed = new Date();
163
- this.emit('context:accessed', { contextId });
164
- }
165
-
166
- return context;
167
- }
168
-
169
- async updateContext(
170
- contextId: string,
171
- updates: Partial<any>,
172
- options: UpdateOptions = {}
173
- ): Promise<void> {
174
- const context = await this.getContext(contextId);
175
- if (!context) {
176
- throw new Error(`Context ${contextId} not found`);
177
- }
178
-
179
- // Record history
180
- if (!options.skipHistory) {
181
- this.addHistory(context, {
182
- timestamp: new Date(),
183
- action: options.action || 'update',
184
- changes: new Map(Object.entries(updates)),
185
- userId: options.userId,
186
- metadata: options.metadata,
187
- });
188
- }
189
-
190
- // Apply updates
191
- for (const [key, value] of Object.entries(updates)) {
192
- if (value === undefined) {
193
- context.data.delete(key);
194
- } else {
195
- context.data.set(key, value);
196
- }
197
- }
198
-
199
- // Create checkpoint if needed
200
- if (options.checkpoint) {
201
- await this.createCheckpoint(contextId, options.checkpointDescription);
202
- }
203
-
204
- // Save to storage
205
- if (!options.skipSave) {
206
- await this.saveContext(contextId);
207
- }
208
-
209
- this.emit('context:updated', { contextId, updates });
210
- }
211
-
212
- async createCheckpoint(
213
- contextId: string,
214
- description?: string
215
- ): Promise<string> {
216
- const context = await this.getContext(contextId);
217
- if (!context) {
218
- throw new Error(`Context ${contextId} not found`);
219
- }
220
-
221
- const checkpointId = this.generateCheckpointId();
222
- const state = await this.serializeContext(context);
223
-
224
- const checkpoint: Checkpoint = {
225
- id: checkpointId,
226
- timestamp: new Date(),
227
- state: compress(state),
228
- description,
229
- automatic: !description,
230
- };
231
-
232
- context.checkpoints.push(checkpoint);
233
-
234
- // Maintain max checkpoints
235
- if (context.checkpoints.length > this.maxCheckpoints) {
236
- context.checkpoints.shift();
237
- }
238
-
239
- await this.saveContext(contextId);
240
-
241
- this.emit('checkpoint:created', { contextId, checkpointId });
242
-
243
- return checkpointId;
244
- }
245
-
246
- async restoreCheckpoint(
247
- contextId: string,
248
- checkpointId: string
249
- ): Promise<void> {
250
- const context = await this.getContext(contextId);
251
- if (!context) {
252
- throw new Error(`Context ${contextId} not found`);
253
- }
254
-
255
- const checkpoint = context.checkpoints.find(cp => cp.id === checkpointId);
256
- if (!checkpoint) {
257
- throw new Error(`Checkpoint ${checkpointId} not found`);
258
- }
259
-
260
- const restoredState = JSON.parse(decompress(checkpoint.state));
261
-
262
- // Restore data
263
- context.data = new Map(Object.entries(restoredState.data));
264
- context.metadata = restoredState.metadata;
265
-
266
- // Add restoration to history
267
- this.addHistory(context, {
268
- timestamp: new Date(),
269
- action: 'restore_checkpoint',
270
- changes: new Map([['checkpointId', checkpointId]]),
271
- });
272
-
273
- await this.saveContext(contextId);
274
-
275
- this.emit('checkpoint:restored', { contextId, checkpointId });
276
- }
277
-
278
- async mergeContexts(
279
- sourceIds: string[],
280
- strategy: MergeStrategy = 'last-write-wins'
281
- ): Promise<string> {
282
- const contexts = await Promise.all(
283
- sourceIds.map(id => this.getContext(id))
284
- );
285
-
286
- const validContexts = contexts.filter(c => c !== null) as ContextState[];
287
-
288
- if (validContexts.length === 0) {
289
- throw new Error('No valid contexts to merge');
290
- }
291
-
292
- const mergedData = new Map();
293
-
294
- switch (strategy) {
295
- case 'last-write-wins':
296
- for (const context of validContexts) {
297
- for (const [key, value] of context.data) {
298
- mergedData.set(key, value);
299
- }
300
- }
301
- break;
302
-
303
- case 'first-write-wins':
304
- for (const context of validContexts.reverse()) {
305
- for (const [key, value] of context.data) {
306
- if (!mergedData.has(key)) {
307
- mergedData.set(key, value);
308
- }
309
- }
310
- }
311
- break;
312
-
313
- case 'deep-merge':
314
- for (const context of validContexts) {
315
- for (const [key, value] of context.data) {
316
- const existing = mergedData.get(key);
317
- if (existing && typeof existing === 'object' && typeof value === 'object') {
318
- mergedData.set(key, this.deepMerge(existing, value));
319
- } else {
320
- mergedData.set(key, value);
321
- }
322
- }
323
- }
324
- break;
325
- }
326
-
327
- const newContextId = await this.createContext(
328
- validContexts[0].sessionId,
329
- Object.fromEntries(mergedData)
330
- );
331
-
332
- this.emit('contexts:merged', { sourceIds, newContextId });
333
-
334
- return newContextId;
335
- }
336
-
337
- private addHistory(context: ContextState, entry: ContextHistory): void {
338
- context.history.push(entry);
339
-
340
- // Maintain max history size
341
- if (context.history.length > this.maxHistorySize) {
342
- context.history.shift();
343
- }
344
- }
345
-
346
- private async saveContext(contextId: string): Promise<void> {
347
- const context = this.contexts.get(contextId);
348
- if (!context) return;
349
-
350
- const serialized = await this.serializeContext(context);
351
- const shouldCompress = serialized.length > this.compressionThreshold;
352
-
353
- const dataToStore = shouldCompress ? compress(serialized) : serialized;
354
-
355
- await this.storage.set(contextId, {
356
- data: dataToStore,
357
- compressed: shouldCompress,
358
- timestamp: new Date(),
359
- });
360
-
361
- // Update cache
362
- this.cache.set(contextId, context);
363
- }
364
-
365
- private async loadContext(contextId: string): Promise<ContextState | null> {
366
- const stored = await this.storage.get(contextId);
367
- if (!stored) return null;
368
-
369
- const serialized = stored.compressed
370
- ? decompress(stored.data)
371
- : stored.data;
372
-
373
- return this.deserializeContext(serialized);
374
- }
375
-
376
- private async serializeContext(context: ContextState): Promise<string> {
377
- return JSON.stringify({
378
- ...context,
379
- data: Object.fromEntries(context.data),
380
- metadata: {
381
- ...context.metadata,
382
- features: Array.from(context.metadata.features),
383
- permissions: Object.fromEntries(context.metadata.permissions),
384
- },
385
- });
386
- }
387
-
388
- private deserializeContext(serialized: string): ContextState {
389
- const parsed = JSON.parse(serialized);
390
- return {
391
- ...parsed,
392
- data: new Map(Object.entries(parsed.data)),
393
- metadata: {
394
- ...parsed.metadata,
395
- features: new Set(parsed.metadata.features),
396
- permissions: new Map(Object.entries(parsed.metadata.permissions)),
397
- },
398
- created: new Date(parsed.created),
399
- lastAccessed: new Date(parsed.lastAccessed),
400
- };
401
- }
402
-
403
- private generateContextId(): string {
404
- return `ctx_${crypto.randomBytes(16).toString('hex')}`;
405
- }
406
-
407
- private generateCheckpointId(): string {
408
- return `chk_${crypto.randomBytes(8).toString('hex')}`;
409
- }
410
-
411
- private deepMerge(target: any, source: any): any {
412
- const output = { ...target };
413
-
414
- if (isObject(target) && isObject(source)) {
415
- Object.keys(source).forEach(key => {
416
- if (isObject(source[key])) {
417
- if (!(key in target)) {
418
- Object.assign(output, { [key]: source[key] });
419
- } else {
420
- output[key] = this.deepMerge(target[key], source[key]);
421
- }
422
- } else {
423
- Object.assign(output, { [key]: source[key] });
424
- }
425
- });
426
- }
427
-
428
- return output;
429
- }
430
-
431
- private startAutoSave(): void {
432
- setInterval(async () => {
433
- const promises = Array.from(this.contexts.keys()).map(
434
- contextId => this.saveContext(contextId)
435
- );
436
- await Promise.all(promises);
437
- this.emit('autosave:completed', { count: promises.length });
438
- }, this.autoSaveInterval);
439
- }
440
-
441
- private setupEventHandlers(): void {
442
- this.on('error', (error) => {
443
- console.error('ContextManager error:', error);
444
- });
445
-
446
- process.on('SIGINT', async () => {
447
- await this.shutdown();
448
- });
449
-
450
- process.on('SIGTERM', async () => {
451
- await this.shutdown();
452
- });
453
- }
454
-
455
- async shutdown(): Promise<void> {
456
- this.emit('shutdown:started');
457
-
458
- // Save all contexts
459
- const promises = Array.from(this.contexts.keys()).map(
460
- contextId => this.saveContext(contextId)
461
- );
462
- await Promise.all(promises);
463
-
464
- // Clear memory
465
- this.contexts.clear();
466
- this.cache.clear();
467
-
468
- this.emit('shutdown:completed');
469
- }
470
- }
471
-
472
- // Usage interfaces
473
- interface ContextManagerOptions {
474
- maxCacheSize?: number;
475
- cacheTTL?: number;
476
- storage?: StorageAdapter;
477
- compressionThreshold?: number;
478
- autoSave?: boolean;
479
- }
480
-
481
- interface UpdateOptions {
482
- skipHistory?: boolean;
483
- skipSave?: boolean;
484
- checkpoint?: boolean;
485
- checkpointDescription?: string;
486
- action?: string;
487
- userId?: string;
488
- metadata?: any;
489
- }
490
-
491
- type MergeStrategy = 'last-write-wins' | 'first-write-wins' | 'deep-merge';
492
-
493
- function isObject(item: any): boolean {
494
- return item && typeof item === 'object' && !Array.isArray(item);
495
- }
496
- ```
497
-
498
- ## Distributed Session Management
499
- ```typescript
500
- // distributed-session.ts
501
- import { Redis } from 'ioredis';
502
- import { EventEmitter } from 'events';
503
-
504
- class DistributedSessionManager extends EventEmitter {
505
- private redis: Redis;
506
- private pubClient: Redis;
507
- private subClient: Redis;
508
- private localSessions: Map<string, SessionData>;
509
- private heartbeatInterval: number = 30000; // 30 seconds
510
- private sessionTimeout: number = 3600000; // 1 hour
511
- private nodeId: string;
512
-
513
- constructor(redisConfig: RedisConfig) {
514
- super();
515
- this.redis = new Redis(redisConfig);
516
- this.pubClient = new Redis(redisConfig);
517
- this.subClient = new Redis(redisConfig);
518
- this.localSessions = new Map();
519
- this.nodeId = this.generateNodeId();
520
-
521
- this.setupSubscriptions();
522
- this.startHeartbeat();
523
- }
524
-
525
- async createSession(userId: string, metadata?: any): Promise<string> {
526
- const sessionId = this.generateSessionId();
527
- const session: SessionData = {
528
- id: sessionId,
529
- userId,
530
- nodeId: this.nodeId,
531
- data: {},
532
- metadata: metadata || {},
533
- created: Date.now(),
534
- lastAccessed: Date.now(),
535
- expiresAt: Date.now() + this.sessionTimeout,
536
- };
537
-
538
- // Store locally
539
- this.localSessions.set(sessionId, session);
540
-
541
- // Store in Redis
542
- await this.redis.setex(
543
- `session:${sessionId}`,
544
- Math.floor(this.sessionTimeout / 1000),
545
- JSON.stringify(session)
546
- );
547
-
548
- // Publish session creation event
549
- await this.pubClient.publish('session:created', JSON.stringify({
550
- sessionId,
551
- nodeId: this.nodeId,
552
- userId,
553
- }));
554
-
555
- this.emit('session:created', session);
556
-
557
- return sessionId;
558
- }
559
-
560
- async getSession(sessionId: string): Promise<SessionData | null> {
561
- // Check local cache first
562
- let session = this.localSessions.get(sessionId);
563
-
564
- if (!session) {
565
- // Fetch from Redis
566
- const data = await this.redis.get(`session:${sessionId}`);
567
- if (data) {
568
- session = JSON.parse(data);
569
- // Cache locally
570
- this.localSessions.set(sessionId, session);
571
- }
572
- }
573
-
574
- if (session) {
575
- // Update last accessed time
576
- session.lastAccessed = Date.now();
577
- await this.updateSession(sessionId, session);
578
- }
579
-
580
- return session || null;
581
- }
582
-
583
- async updateSession(sessionId: string, updates: Partial<SessionData>): Promise<void> {
584
- const session = await this.getSession(sessionId);
585
- if (!session) {
586
- throw new Error(`Session ${sessionId} not found`);
587
- }
588
-
589
- const updatedSession = { ...session, ...updates };
590
-
591
- // Update locally
592
- this.localSessions.set(sessionId, updatedSession);
593
-
594
- // Update in Redis
595
- const ttl = Math.max(0, updatedSession.expiresAt - Date.now());
596
- await this.redis.setex(
597
- `session:${sessionId}`,
598
- Math.floor(ttl / 1000),
599
- JSON.stringify(updatedSession)
600
- );
601
-
602
- // Publish update event
603
- await this.pubClient.publish('session:updated', JSON.stringify({
604
- sessionId,
605
- nodeId: this.nodeId,
606
- updates,
607
- }));
608
-
609
- this.emit('session:updated', updatedSession);
610
- }
611
-
612
- async destroySession(sessionId: string): Promise<void> {
613
- // Remove locally
614
- this.localSessions.delete(sessionId);
615
-
616
- // Remove from Redis
617
- await this.redis.del(`session:${sessionId}`);
618
-
619
- // Publish destroy event
620
- await this.pubClient.publish('session:destroyed', JSON.stringify({
621
- sessionId,
622
- nodeId: this.nodeId,
623
- }));
624
-
625
- this.emit('session:destroyed', { sessionId });
626
- }
627
-
628
- async transferSession(sessionId: string, targetNodeId: string): Promise<void> {
629
- const session = await this.getSession(sessionId);
630
- if (!session) {
631
- throw new Error(`Session ${sessionId} not found`);
632
- }
633
-
634
- // Update session node ownership
635
- session.nodeId = targetNodeId;
636
- await this.updateSession(sessionId, { nodeId: targetNodeId });
637
-
638
- // Remove from local cache
639
- this.localSessions.delete(sessionId);
640
-
641
- // Publish transfer event
642
- await this.pubClient.publish('session:transferred', JSON.stringify({
643
- sessionId,
644
- fromNodeId: this.nodeId,
645
- toNodeId: targetNodeId,
646
- }));
647
-
648
- this.emit('session:transferred', { sessionId, targetNodeId });
649
- }
650
-
651
- private setupSubscriptions(): void {
652
- this.subClient.subscribe(
653
- 'session:created',
654
- 'session:updated',
655
- 'session:destroyed',
656
- 'session:transferred'
657
- );
658
-
659
- this.subClient.on('message', (channel, message) => {
660
- const data = JSON.parse(message);
661
-
662
- // Skip events from this node
663
- if (data.nodeId === this.nodeId) return;
664
-
665
- switch (channel) {
666
- case 'session:created':
667
- this.handleRemoteSessionCreated(data);
668
- break;
669
- case 'session:updated':
670
- this.handleRemoteSessionUpdated(data);
671
- break;
672
- case 'session:destroyed':
673
- this.handleRemoteSessionDestroyed(data);
674
- break;
675
- case 'session:transferred':
676
- this.handleRemoteSessionTransferred(data);
677
- break;
678
- }
679
- });
680
- }
681
-
682
- private handleRemoteSessionCreated(data: any): void {
683
- // Invalidate local cache if exists
684
- this.localSessions.delete(data.sessionId);
685
- this.emit('remote:session:created', data);
686
- }
687
-
688
- private handleRemoteSessionUpdated(data: any): void {
689
- // Invalidate local cache
690
- this.localSessions.delete(data.sessionId);
691
- this.emit('remote:session:updated', data);
692
- }
693
-
694
- private handleRemoteSessionDestroyed(data: any): void {
695
- this.localSessions.delete(data.sessionId);
696
- this.emit('remote:session:destroyed', data);
697
- }
698
-
699
- private handleRemoteSessionTransferred(data: any): void {
700
- if (data.toNodeId === this.nodeId) {
701
- // Session transferred to this node
702
- this.emit('session:received', data);
703
- } else {
704
- // Invalidate local cache
705
- this.localSessions.delete(data.sessionId);
706
- }
707
- }
708
-
709
- private startHeartbeat(): void {
710
- setInterval(async () => {
711
- const now = Date.now();
712
-
713
- // Clean up expired local sessions
714
- for (const [sessionId, session] of this.localSessions) {
715
- if (session.expiresAt < now) {
716
- await this.destroySession(sessionId);
717
- }
718
- }
719
-
720
- // Update node heartbeat
721
- await this.redis.setex(
722
- `node:${this.nodeId}:heartbeat`,
723
- 60, // 1 minute TTL
724
- JSON.stringify({
725
- nodeId: this.nodeId,
726
- timestamp: now,
727
- sessionCount: this.localSessions.size,
728
- })
729
- );
730
-
731
- this.emit('heartbeat', { nodeId: this.nodeId, sessionCount: this.localSessions.size });
732
- }, this.heartbeatInterval);
733
- }
734
-
735
- private generateSessionId(): string {
736
- return `sess_${crypto.randomBytes(16).toString('hex')}_${Date.now()}`;
737
- }
738
-
739
- private generateNodeId(): string {
740
- return `node_${process.pid}_${crypto.randomBytes(8).toString('hex')}`;
741
- }
742
-
743
- async shutdown(): Promise<void> {
744
- // Transfer all sessions to other nodes
745
- const activeNodes = await this.getActiveNodes();
746
-
747
- if (activeNodes.length > 0) {
748
- const sessions = Array.from(this.localSessions.keys());
749
- for (let i = 0; i < sessions.length; i++) {
750
- const targetNode = activeNodes[i % activeNodes.length];
751
- await this.transferSession(sessions[i], targetNode);
752
- }
753
- }
754
-
755
- // Clean up
756
- await this.redis.del(`node:${this.nodeId}:heartbeat`);
757
- this.redis.disconnect();
758
- this.pubClient.disconnect();
759
- this.subClient.disconnect();
760
- }
761
-
762
- private async getActiveNodes(): Promise<string[]> {
763
- const keys = await this.redis.keys('node:*:heartbeat');
764
- return keys.map(key => key.split(':')[1]).filter(id => id !== this.nodeId);
765
- }
766
- }
767
-
768
- interface SessionData {
769
- id: string;
770
- userId: string;
771
- nodeId: string;
772
- data: any;
773
- metadata: any;
774
- created: number;
775
- lastAccessed: number;
776
- expiresAt: number;
777
- }
778
-
779
- interface RedisConfig {
780
- host: string;
781
- port: number;
782
- password?: string;
783
- db?: number;
784
- }
785
- ```
786
-
787
- ## Memory Optimization Strategies
788
- ```typescript
789
- // memory-optimizer.ts
790
- import { performance } from 'perf_hooks';
791
- import v8 from 'v8';
792
- import { Worker } from 'worker_threads';
793
-
794
- class MemoryOptimizer {
795
- private gcThreshold: number = 0.8; // 80% memory usage
796
- private compressionThreshold: number = 10240; // 10KB
797
- private weakRefs: WeakMap<object, any> = new WeakMap();
798
- private objectPool: Map<string, any[]> = new Map();
799
- private monitoringInterval: number = 5000; // 5 seconds
800
-
801
- constructor() {
802
- this.startMonitoring();
803
- }
804
-
805
- optimizeObject(obj: any): any {
806
- const size = this.getObjectSize(obj);
807
-
808
- if (size > this.compressionThreshold) {
809
- return this.compressObject(obj);
810
- }
811
-
812
- // Use object pooling for frequently created objects
813
- if (this.isPoolableObject(obj)) {
814
- return this.poolObject(obj);
815
- }
816
-
817
- // Use weak references for large objects
818
- if (size > 1024) {
819
- this.weakRefs.set(obj, true);
820
- }
821
-
822
- return obj;
823
- }
824
-
825
- private compressObject(obj: any): CompressedObject {
826
- const json = JSON.stringify(obj);
827
- const buffer = Buffer.from(json);
828
- const compressed = zlib.gzipSync(buffer);
829
-
830
- return {
831
- _compressed: true,
832
- data: compressed.toString('base64'),
833
- originalSize: buffer.length,
834
- compressedSize: compressed.length,
835
- };
836
- }
837
-
838
- decompressObject(compressed: CompressedObject): any {
839
- if (!compressed._compressed) return compressed;
840
-
841
- const buffer = Buffer.from(compressed.data, 'base64');
842
- const decompressed = zlib.gunzipSync(buffer);
843
- return JSON.parse(decompressed.toString());
844
- }
845
-
846
- private isPoolableObject(obj: any): boolean {
847
- // Check if object is suitable for pooling
848
- return obj.constructor &&
849
- obj.constructor.name &&
850
- this.objectPool.has(obj.constructor.name);
851
- }
852
-
853
- private poolObject(obj: any): any {
854
- const className = obj.constructor.name;
855
- let pool = this.objectPool.get(className);
856
-
857
- if (!pool) {
858
- pool = [];
859
- this.objectPool.set(className, pool);
860
- }
861
-
862
- // Reuse from pool if available
863
- if (pool.length > 0) {
864
- const pooled = pool.pop();
865
- Object.assign(pooled, obj);
866
- return pooled;
867
- }
868
-
869
- return obj;
870
- }
871
-
872
- releaseToPool(obj: any): void {
873
- const className = obj.constructor.name;
874
- let pool = this.objectPool.get(className);
875
-
876
- if (!pool) {
877
- pool = [];
878
- this.objectPool.set(className, pool);
879
- }
880
-
881
- // Reset object
882
- for (const key in obj) {
883
- if (obj.hasOwnProperty(key)) {
884
- delete obj[key];
885
- }
886
- }
887
-
888
- pool.push(obj);
889
- }
890
-
891
- private getObjectSize(obj: any): number {
892
- const str = JSON.stringify(obj);
893
- return Buffer.byteLength(str, 'utf8');
894
- }
895
-
896
- private startMonitoring(): void {
897
- setInterval(() => {
898
- const memUsage = process.memoryUsage();
899
- const heapStats = v8.getHeapStatistics();
900
-
901
- const usageRatio = memUsage.heapUsed / heapStats.heap_size_limit;
902
-
903
- if (usageRatio > this.gcThreshold) {
904
- this.triggerGarbageCollection();
905
- }
906
-
907
- this.emit('memory:stats', {
908
- heapUsed: memUsage.heapUsed,
909
- heapTotal: memUsage.heapTotal,
910
- external: memUsage.external,
911
- usageRatio,
912
- });
913
- }, this.monitoringInterval);
914
- }
915
-
916
- private triggerGarbageCollection(): void {
917
- if (global.gc) {
918
- global.gc();
919
- this.emit('gc:triggered');
920
- }
921
- }
922
-
923
- analyzeMemoryLeaks(): MemoryLeakReport {
924
- const snapshot = v8.writeHeapSnapshot();
925
- // Analyze snapshot for potential leaks
926
- // This is a simplified version
927
- return {
928
- potentialLeaks: [],
929
- recommendations: [],
930
- };
931
- }
932
- }
933
-
934
- interface CompressedObject {
935
- _compressed: boolean;
936
- data: string;
937
- originalSize: number;
938
- compressedSize: number;
939
- }
940
-
941
- interface MemoryLeakReport {
942
- potentialLeaks: any[];
943
- recommendations: string[];
944
- }
945
- ```
946
-
947
- ## Best Practices
948
- 1. **State Isolation**: Keep context states isolated and immutable
949
- 2. **Compression**: Automatically compress large context data
950
- 3. **Checkpointing**: Regular automatic checkpoints for recovery
951
- 4. **Distributed Sessions**: Support for horizontal scaling
952
- 5. **Memory Management**: Proactive memory optimization and leak detection
953
- 6. **Event Sourcing**: Complete audit trail of all context changes
954
- 7. **Cache Strategy**: Multi-layer caching with TTL and LRU
955
-
956
- ## Context Preservation Strategies
957
- - Automatic session persistence across restarts
958
- - Checkpoint and restore capabilities
959
- - Context merging and splitting
960
- - Cross-service context propagation
961
- - Intelligent garbage collection
962
- - Memory pressure handling
963
-
964
- ## Approach
965
- - Design robust state management architecture
966
- - Implement efficient serialization and compression
967
- - Create distributed session capabilities
968
- - Build comprehensive monitoring and alerting
969
- - Establish automatic recovery mechanisms
970
- - Optimize for memory and performance
971
-
972
- ## Output Format
973
- - Provide complete context management systems
974
- - Include distributed session handling
975
- - Document memory optimization strategies
976
- - Add monitoring and debugging tools
977
- - Include recovery and backup procedures
978
- - Provide performance benchmarks and metrics