@warlock.js/context 5.28.0 → 5.30.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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ All notable changes to `@warlock.js/context` are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
6
 
7
+ ## 5.30.0 - 2026-10-16
8
+
9
+ ### Changed
10
+
11
+ - Lockstep release; package APIs are unchanged.
12
+
13
+ ## 5.29.0 - 2026-10-01
14
+
15
+ ### Changed
16
+
17
+ - Lockstep release; package APIs are unchanged. Skills refer to other topics by name instead of file paths, so cross-references keep working after `agent-kit` copies them into an app.
18
+
7
19
  ## 5.28.0 - 2026-10-01
8
20
 
9
21
  ### Changed
package/cjs/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  let async_hooks = require("async_hooks");
3
3
 
4
- //#region ../context/src/base-context.ts
4
+ //#region ../../packages/context/src/base-context.ts
5
5
  /**
6
6
  * Keys that reach `Object.prototype` instead of the store when assigned.
7
7
  *
@@ -153,7 +153,7 @@ var Context = class {
153
153
  };
154
154
 
155
155
  //#endregion
156
- //#region ../context/src/context-manager.ts
156
+ //#region ../../packages/context/src/context-manager.ts
157
157
  /**
158
158
  * Context Manager - Orchestrates multiple contexts together
159
159
  *
package/cjs/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["AsyncLocalStorage"],"sources":["../../../../../../context/src/base-context.ts","../../../../../../context/src/context-manager.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"async_hooks\";\n\n/**\n * Keys that reach `Object.prototype` instead of the store when assigned.\n *\n * `Object.assign(store, { __proto__: {...} })` does not create a property — it\n * invokes the inherited `__proto__` setter and reparents the store, which for a\n * shared context store means every later property lookup in the process can\n * resolve through attacker-supplied data. `constructor` / `prototype` are the\n * neighbouring rungs of the same ladder.\n */\nconst DANGEROUS_KEYS = [\"__proto__\", \"constructor\", \"prototype\"] as const;\n\n/**\n * Drop prototype-poisoning keys from a merge payload.\n *\n * Contexts are frequently fed request-shaped data (`context.update(req.body)`,\n * `context.set(key, value)` with a caller-supplied key), so the merge path is\n * treated as an untrusted boundary: dangerous keys are dropped rather than\n * throwing, since a request that trips this must not be able to take the\n * process down, and the store simply never carries them.\n *\n * The common case allocates nothing — a copy is made only when a dangerous key\n * is actually present. The copy is built by spread (which defines properties\n * rather than assigning them, so it cannot trigger the setter itself) and\n * preserves symbol keys, which `Object.assign` would have copied.\n */\nfunction withoutDangerousKeys<T>(updates: T): T {\n if (!updates || typeof updates !== \"object\") return updates;\n\n const hasDangerousKey = DANGEROUS_KEYS.some(key =>\n Object.prototype.hasOwnProperty.call(updates, key),\n );\n\n if (!hasDangerousKey) return updates;\n\n const safe: Record<string, any> = { ...(updates as Record<string, any>) };\n\n for (const key of DANGEROUS_KEYS) {\n delete safe[key];\n }\n\n return safe as T;\n}\n\n/**\n * Base class for all AsyncLocalStorage-based contexts\n *\n * Provides a consistent API for managing context across async operations.\n * All framework contexts (request, storage, database) extend this class.\n *\n * @template TStore - The type of data stored in context\n *\n * @example\n * ```typescript\n * interface MyContextStore {\n * userId: string;\n * tenant: string;\n * }\n *\n * class MyContext extends Context<MyContextStore> {}\n * const myContext = new MyContext();\n *\n * // Use it\n * await myContext.run({ userId: '123', tenant: 'acme' }, async () => {\n * const userId = myContext.get('userId'); // '123'\n * });\n * ```\n */\nexport abstract class Context<TStore extends Record<string, any>> {\n protected readonly storage: AsyncLocalStorage<TStore> = new AsyncLocalStorage<TStore>();\n\n /**\n * Run a callback within a new context\n *\n * Creates a new async context with the provided store data.\n * All operations within the callback will have access to this context.\n *\n * @param store - Initial context data\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public run<T>(store: TStore, callback: () => Promise<T>): Promise<T> {\n return this.storage.run(store, callback);\n }\n\n /**\n * Enter a new context without a callback\n *\n * Useful for middleware where you want to set context for the rest of the request.\n * Unlike `run()`, this doesn't require a callback.\n *\n * @param store - Context data to set\n */\n public enter(store: TStore): void {\n this.storage.enterWith(store);\n }\n\n /**\n * Update the current context\n *\n * Merges new data into existing context, or enters new context if none exists.\n *\n * Keys named `__proto__`, `constructor`, or `prototype` are dropped: the\n * merge target is a store shared by everything running in this async chain,\n * so letting those through would let one caller's payload change property\n * resolution for the whole process. Passing unvalidated input here is still\n * discouraged — this guard closes the prototype vector, not the \"an attacker\n * chose what your context says\" one.\n *\n * @param updates - Partial context data to merge\n */\n public update(updates: Partial<TStore>): void {\n const safeUpdates = withoutDangerousKeys(updates);\n\n const current = this.storage.getStore();\n\n if (current) {\n Object.assign(current, safeUpdates);\n } else {\n this.enter(safeUpdates as TStore);\n }\n }\n\n /**\n * Get the current context store\n *\n * @returns Current context or undefined if not in context\n */\n public getStore(): TStore | undefined {\n return this.storage.getStore();\n }\n\n /**\n * Get a specific value from context\n *\n * @param key - Key to retrieve\n * @returns Value or undefined\n */\n public get<K extends keyof TStore>(key: K): TStore[K] | undefined {\n return this.storage.getStore()?.[key];\n }\n\n /**\n * Set a specific value in context\n *\n * Goes through `update()`, so a caller-supplied `key` of `__proto__` /\n * `constructor` / `prototype` is dropped rather than reparenting the store.\n *\n * @param key - Key to set\n * @param value - Value to store\n */\n public set<K extends keyof TStore>(key: K, value: TStore[K]): void {\n this.update({ [key]: value } as any);\n }\n\n /**\n * Clear the context\n */\n public clear(): void {\n this.storage.enterWith({} as TStore);\n }\n\n /**\n * Check if currently in a context\n */\n public hasContext(): boolean {\n return this.storage.getStore() !== undefined;\n }\n\n /**\n * Build the initial store for this context\n *\n * Override this method to provide custom initialization logic.\n * Called by ContextManager.buildStores() for each registered context.\n *\n * @param payload - Generic payload (e.g., { request, response } for HTTP contexts)\n * @returns Initial store data\n */\n public abstract buildStore(payload?: Record<string, any>): TStore;\n}\n","import type { Context } from \"./base-context\";\n\n/**\n * Context Manager - Orchestrates multiple contexts together\n *\n * Allows running multiple AsyncLocalStorage contexts in a single operation,\n * making it easy to link request, storage, database, and other contexts.\n *\n * @example\n * ```typescript\n * // Register contexts\n * contextManager\n * .register('request', requestContext)\n * .register('storage', storageDriverContext)\n * .register('database', databaseDataSourceContext);\n *\n * // Run all contexts together\n * await contextManager.runAll({\n * request: { request, response, user },\n * storage: { driver, metadata: { tenantId: '123' } },\n * database: { dataSource: 'primary' },\n * }, async () => {\n * // All contexts active!\n * await handleRequest();\n * });\n * ```\n */\nexport class ContextManager {\n private contexts = new Map<string, Context<any>>();\n\n /**\n * Register a context\n *\n * @param name - Unique context name\n * @param context - Context instance\n * @returns This instance for chaining\n */\n public register(name: string, context: Context<any>): this {\n this.contexts.set(name, context);\n return this;\n }\n\n /**\n * Run all registered contexts together\n *\n * Nests all context.run() calls, ensuring all contexts are active\n * for the duration of the callback.\n *\n * @param stores - Context stores keyed by context name\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public async runAll<T>(stores: Record<string, any>, callback: () => Promise<T>): Promise<T> {\n const entries = Array.from(this.contexts.entries());\n\n // Build nested context runners\n const runner = entries.reduceRight((next, [name, context]) => {\n return () => context.run(stores[name] || {}, next);\n }, callback);\n\n return runner();\n }\n\n /**\n * Enter all contexts at once (for middleware)\n *\n * @param stores - Context stores keyed by context name\n */\n public enterAll(stores: Record<string, any>): void {\n for (const [name, context] of this.contexts.entries()) {\n if (stores[name]) {\n context.enter(stores[name]);\n }\n }\n }\n\n /**\n * Clear all contexts\n */\n public clearAll(): void {\n for (const context of this.contexts.values()) {\n context.clear();\n }\n }\n\n /**\n * Get a specific registered context\n *\n * @param name - Context name\n * @returns Context instance or undefined\n */\n public getContext<T extends Context<any>>(name: string): T | undefined {\n return this.contexts.get(name) as T | undefined;\n }\n\n /**\n * Check if a context is registered\n *\n * @param name - Context name\n * @returns True if context is registered\n */\n public hasContext(name: string): boolean {\n return this.contexts.has(name);\n }\n\n /**\n * Build all context stores by calling each context's buildStore() method\n *\n * This is the immutable pattern - returns a new record of stores.\n * Each context defines its own initialization logic.\n *\n * @param payload - Payload passed to each buildStore() (e.g., { request, response })\n * @returns Record of context name -> store data\n *\n * @example\n * ```typescript\n * const httpContextStore = contextManager.buildStores({ request, response });\n * await contextManager.runAll(httpContextStore, async () => { ... });\n * ```\n */\n public buildStores(payload?: Record<string, any>): Record<string, any> {\n const stores: Record<string, any> = {};\n\n for (const [name, context] of this.contexts.entries()) {\n stores[name] = context.buildStore(payload) ?? {};\n }\n\n return stores;\n }\n\n /**\n * Unregister a context\n *\n * @param name - Context name to remove\n * @returns True if context was removed\n */\n public unregister(name: string): boolean {\n return this.contexts.delete(name);\n }\n}\n\n/**\n * Global context manager instance\n *\n * Use this singleton to register and manage all framework contexts.\n */\nexport const contextManager = new ContextManager();\n"],"mappings":";;;;;;;;;;;;;AAWA,MAAM,iBAAiB;CAAC;CAAa;CAAe;AAAW;;;;;;;;;;;;;;;AAgB/D,SAAS,qBAAwB,SAAe;CAC9C,IAAI,CAAC,WAAW,OAAO,YAAY,UAAU,OAAO;CAMpD,IAAI,CAJoB,eAAe,MAAK,QAC1C,OAAO,UAAU,eAAe,KAAK,SAAS,GAAG,CAGhC,GAAG,OAAO;CAE7B,MAAM,OAA4B,EAAE,GAAI,QAAgC;CAExE,KAAK,MAAM,OAAO,gBAChB,OAAO,KAAK;CAGd,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAsB,UAAtB,MAAkE;;iBACR,IAAIA,8BAA0B;;;;;;;;;;;;CAYtF,AAAO,IAAO,OAAe,UAAwC;EACnE,OAAO,KAAK,QAAQ,IAAI,OAAO,QAAQ;CACzC;;;;;;;;;CAUA,AAAO,MAAM,OAAqB;EAChC,KAAK,QAAQ,UAAU,KAAK;CAC9B;;;;;;;;;;;;;;;CAgBA,AAAO,OAAO,SAAgC;EAC5C,MAAM,cAAc,qBAAqB,OAAO;EAEhD,MAAM,UAAU,KAAK,QAAQ,SAAS;EAEtC,IAAI,SACF,OAAO,OAAO,SAAS,WAAW;OAElC,KAAK,MAAM,WAAqB;CAEpC;;;;;;CAOA,AAAO,WAA+B;EACpC,OAAO,KAAK,QAAQ,SAAS;CAC/B;;;;;;;CAQA,AAAO,IAA4B,KAA+B;EAChE,OAAO,KAAK,QAAQ,SAAS,CAAC,GAAG;CACnC;;;;;;;;;;CAWA,AAAO,IAA4B,KAAQ,OAAwB;EACjE,KAAK,OAAO,GAAG,MAAM,MAAM,CAAQ;CACrC;;;;CAKA,AAAO,QAAc;EACnB,KAAK,QAAQ,UAAU,CAAC,CAAW;CACrC;;;;CAKA,AAAO,aAAsB;EAC3B,OAAO,KAAK,QAAQ,SAAS,MAAM;CACrC;AAYF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzJA,IAAa,iBAAb,MAA4B;;kCACP,IAAI,IAA0B;;;;;;;;;CASjD,AAAO,SAAS,MAAc,SAA6B;EACzD,KAAK,SAAS,IAAI,MAAM,OAAO;EAC/B,OAAO;CACT;;;;;;;;;;;CAYA,MAAa,OAAU,QAA6B,UAAwC;EAQ1F,OAPgB,MAAM,KAAK,KAAK,SAAS,QAAQ,CAG5B,CAAC,CAAC,aAAa,MAAM,CAAC,MAAM,aAAa;GAC5D,aAAa,QAAQ,IAAI,OAAO,SAAS,CAAC,GAAG,IAAI;EACnD,GAAG,QAES,CAAC,CAAC;CAChB;;;;;;CAOA,AAAO,SAAS,QAAmC;EACjD,KAAK,MAAM,CAAC,MAAM,YAAY,KAAK,SAAS,QAAQ,GAClD,IAAI,OAAO,OACT,QAAQ,MAAM,OAAO,KAAK;CAGhC;;;;CAKA,AAAO,WAAiB;EACtB,KAAK,MAAM,WAAW,KAAK,SAAS,OAAO,GACzC,QAAQ,MAAM;CAElB;;;;;;;CAQA,AAAO,WAAmC,MAA6B;EACrE,OAAO,KAAK,SAAS,IAAI,IAAI;CAC/B;;;;;;;CAQA,AAAO,WAAW,MAAuB;EACvC,OAAO,KAAK,SAAS,IAAI,IAAI;CAC/B;;;;;;;;;;;;;;;;CAiBA,AAAO,YAAY,SAAoD;EACrE,MAAM,SAA8B,CAAC;EAErC,KAAK,MAAM,CAAC,MAAM,YAAY,KAAK,SAAS,QAAQ,GAClD,OAAO,QAAQ,QAAQ,WAAW,OAAO,KAAK,CAAC;EAGjD,OAAO;CACT;;;;;;;CAQA,AAAO,WAAW,MAAuB;EACvC,OAAO,KAAK,SAAS,OAAO,IAAI;CAClC;AACF;;;;;;AAOA,MAAa,iBAAiB,IAAI,eAAe"}
1
+ {"version":3,"file":"index.cjs","names":["AsyncLocalStorage"],"sources":["../../../../../../../packages/context/src/base-context.ts","../../../../../../../packages/context/src/context-manager.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"async_hooks\";\n\n/**\n * Keys that reach `Object.prototype` instead of the store when assigned.\n *\n * `Object.assign(store, { __proto__: {...} })` does not create a property — it\n * invokes the inherited `__proto__` setter and reparents the store, which for a\n * shared context store means every later property lookup in the process can\n * resolve through attacker-supplied data. `constructor` / `prototype` are the\n * neighbouring rungs of the same ladder.\n */\nconst DANGEROUS_KEYS = [\"__proto__\", \"constructor\", \"prototype\"] as const;\n\n/**\n * Drop prototype-poisoning keys from a merge payload.\n *\n * Contexts are frequently fed request-shaped data (`context.update(req.body)`,\n * `context.set(key, value)` with a caller-supplied key), so the merge path is\n * treated as an untrusted boundary: dangerous keys are dropped rather than\n * throwing, since a request that trips this must not be able to take the\n * process down, and the store simply never carries them.\n *\n * The common case allocates nothing — a copy is made only when a dangerous key\n * is actually present. The copy is built by spread (which defines properties\n * rather than assigning them, so it cannot trigger the setter itself) and\n * preserves symbol keys, which `Object.assign` would have copied.\n */\nfunction withoutDangerousKeys<T>(updates: T): T {\n if (!updates || typeof updates !== \"object\") return updates;\n\n const hasDangerousKey = DANGEROUS_KEYS.some(key =>\n Object.prototype.hasOwnProperty.call(updates, key),\n );\n\n if (!hasDangerousKey) return updates;\n\n const safe: Record<string, any> = { ...(updates as Record<string, any>) };\n\n for (const key of DANGEROUS_KEYS) {\n delete safe[key];\n }\n\n return safe as T;\n}\n\n/**\n * Base class for all AsyncLocalStorage-based contexts\n *\n * Provides a consistent API for managing context across async operations.\n * All framework contexts (request, storage, database) extend this class.\n *\n * @template TStore - The type of data stored in context\n *\n * @example\n * ```typescript\n * interface MyContextStore {\n * userId: string;\n * tenant: string;\n * }\n *\n * class MyContext extends Context<MyContextStore> {}\n * const myContext = new MyContext();\n *\n * // Use it\n * await myContext.run({ userId: '123', tenant: 'acme' }, async () => {\n * const userId = myContext.get('userId'); // '123'\n * });\n * ```\n */\nexport abstract class Context<TStore extends Record<string, any>> {\n protected readonly storage: AsyncLocalStorage<TStore> = new AsyncLocalStorage<TStore>();\n\n /**\n * Run a callback within a new context\n *\n * Creates a new async context with the provided store data.\n * All operations within the callback will have access to this context.\n *\n * @param store - Initial context data\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public run<T>(store: TStore, callback: () => Promise<T>): Promise<T> {\n return this.storage.run(store, callback);\n }\n\n /**\n * Enter a new context without a callback\n *\n * Useful for middleware where you want to set context for the rest of the request.\n * Unlike `run()`, this doesn't require a callback.\n *\n * @param store - Context data to set\n */\n public enter(store: TStore): void {\n this.storage.enterWith(store);\n }\n\n /**\n * Update the current context\n *\n * Merges new data into existing context, or enters new context if none exists.\n *\n * Keys named `__proto__`, `constructor`, or `prototype` are dropped: the\n * merge target is a store shared by everything running in this async chain,\n * so letting those through would let one caller's payload change property\n * resolution for the whole process. Passing unvalidated input here is still\n * discouraged — this guard closes the prototype vector, not the \"an attacker\n * chose what your context says\" one.\n *\n * @param updates - Partial context data to merge\n */\n public update(updates: Partial<TStore>): void {\n const safeUpdates = withoutDangerousKeys(updates);\n\n const current = this.storage.getStore();\n\n if (current) {\n Object.assign(current, safeUpdates);\n } else {\n this.enter(safeUpdates as TStore);\n }\n }\n\n /**\n * Get the current context store\n *\n * @returns Current context or undefined if not in context\n */\n public getStore(): TStore | undefined {\n return this.storage.getStore();\n }\n\n /**\n * Get a specific value from context\n *\n * @param key - Key to retrieve\n * @returns Value or undefined\n */\n public get<K extends keyof TStore>(key: K): TStore[K] | undefined {\n return this.storage.getStore()?.[key];\n }\n\n /**\n * Set a specific value in context\n *\n * Goes through `update()`, so a caller-supplied `key` of `__proto__` /\n * `constructor` / `prototype` is dropped rather than reparenting the store.\n *\n * @param key - Key to set\n * @param value - Value to store\n */\n public set<K extends keyof TStore>(key: K, value: TStore[K]): void {\n this.update({ [key]: value } as any);\n }\n\n /**\n * Clear the context\n */\n public clear(): void {\n this.storage.enterWith({} as TStore);\n }\n\n /**\n * Check if currently in a context\n */\n public hasContext(): boolean {\n return this.storage.getStore() !== undefined;\n }\n\n /**\n * Build the initial store for this context\n *\n * Override this method to provide custom initialization logic.\n * Called by ContextManager.buildStores() for each registered context.\n *\n * @param payload - Generic payload (e.g., { request, response } for HTTP contexts)\n * @returns Initial store data\n */\n public abstract buildStore(payload?: Record<string, any>): TStore;\n}\n","import type { Context } from \"./base-context\";\n\n/**\n * Context Manager - Orchestrates multiple contexts together\n *\n * Allows running multiple AsyncLocalStorage contexts in a single operation,\n * making it easy to link request, storage, database, and other contexts.\n *\n * @example\n * ```typescript\n * // Register contexts\n * contextManager\n * .register('request', requestContext)\n * .register('storage', storageDriverContext)\n * .register('database', databaseDataSourceContext);\n *\n * // Run all contexts together\n * await contextManager.runAll({\n * request: { request, response, user },\n * storage: { driver, metadata: { tenantId: '123' } },\n * database: { dataSource: 'primary' },\n * }, async () => {\n * // All contexts active!\n * await handleRequest();\n * });\n * ```\n */\nexport class ContextManager {\n private contexts = new Map<string, Context<any>>();\n\n /**\n * Register a context\n *\n * @param name - Unique context name\n * @param context - Context instance\n * @returns This instance for chaining\n */\n public register(name: string, context: Context<any>): this {\n this.contexts.set(name, context);\n return this;\n }\n\n /**\n * Run all registered contexts together\n *\n * Nests all context.run() calls, ensuring all contexts are active\n * for the duration of the callback.\n *\n * @param stores - Context stores keyed by context name\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public async runAll<T>(stores: Record<string, any>, callback: () => Promise<T>): Promise<T> {\n const entries = Array.from(this.contexts.entries());\n\n // Build nested context runners\n const runner = entries.reduceRight((next, [name, context]) => {\n return () => context.run(stores[name] || {}, next);\n }, callback);\n\n return runner();\n }\n\n /**\n * Enter all contexts at once (for middleware)\n *\n * @param stores - Context stores keyed by context name\n */\n public enterAll(stores: Record<string, any>): void {\n for (const [name, context] of this.contexts.entries()) {\n if (stores[name]) {\n context.enter(stores[name]);\n }\n }\n }\n\n /**\n * Clear all contexts\n */\n public clearAll(): void {\n for (const context of this.contexts.values()) {\n context.clear();\n }\n }\n\n /**\n * Get a specific registered context\n *\n * @param name - Context name\n * @returns Context instance or undefined\n */\n public getContext<T extends Context<any>>(name: string): T | undefined {\n return this.contexts.get(name) as T | undefined;\n }\n\n /**\n * Check if a context is registered\n *\n * @param name - Context name\n * @returns True if context is registered\n */\n public hasContext(name: string): boolean {\n return this.contexts.has(name);\n }\n\n /**\n * Build all context stores by calling each context's buildStore() method\n *\n * This is the immutable pattern - returns a new record of stores.\n * Each context defines its own initialization logic.\n *\n * @param payload - Payload passed to each buildStore() (e.g., { request, response })\n * @returns Record of context name -> store data\n *\n * @example\n * ```typescript\n * const httpContextStore = contextManager.buildStores({ request, response });\n * await contextManager.runAll(httpContextStore, async () => { ... });\n * ```\n */\n public buildStores(payload?: Record<string, any>): Record<string, any> {\n const stores: Record<string, any> = {};\n\n for (const [name, context] of this.contexts.entries()) {\n stores[name] = context.buildStore(payload) ?? {};\n }\n\n return stores;\n }\n\n /**\n * Unregister a context\n *\n * @param name - Context name to remove\n * @returns True if context was removed\n */\n public unregister(name: string): boolean {\n return this.contexts.delete(name);\n }\n}\n\n/**\n * Global context manager instance\n *\n * Use this singleton to register and manage all framework contexts.\n */\nexport const contextManager = new ContextManager();\n"],"mappings":";;;;;;;;;;;;;AAWA,MAAM,iBAAiB;CAAC;CAAa;CAAe;AAAW;;;;;;;;;;;;;;;AAgB/D,SAAS,qBAAwB,SAAe;CAC9C,IAAI,CAAC,WAAW,OAAO,YAAY,UAAU,OAAO;CAMpD,IAAI,CAJoB,eAAe,MAAK,QAC1C,OAAO,UAAU,eAAe,KAAK,SAAS,GAAG,CAGhC,GAAG,OAAO;CAE7B,MAAM,OAA4B,EAAE,GAAI,QAAgC;CAExE,KAAK,MAAM,OAAO,gBAChB,OAAO,KAAK;CAGd,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAsB,UAAtB,MAAkE;;iBACR,IAAIA,8BAA0B;;;;;;;;;;;;CAYtF,AAAO,IAAO,OAAe,UAAwC;EACnE,OAAO,KAAK,QAAQ,IAAI,OAAO,QAAQ;CACzC;;;;;;;;;CAUA,AAAO,MAAM,OAAqB;EAChC,KAAK,QAAQ,UAAU,KAAK;CAC9B;;;;;;;;;;;;;;;CAgBA,AAAO,OAAO,SAAgC;EAC5C,MAAM,cAAc,qBAAqB,OAAO;EAEhD,MAAM,UAAU,KAAK,QAAQ,SAAS;EAEtC,IAAI,SACF,OAAO,OAAO,SAAS,WAAW;OAElC,KAAK,MAAM,WAAqB;CAEpC;;;;;;CAOA,AAAO,WAA+B;EACpC,OAAO,KAAK,QAAQ,SAAS;CAC/B;;;;;;;CAQA,AAAO,IAA4B,KAA+B;EAChE,OAAO,KAAK,QAAQ,SAAS,CAAC,GAAG;CACnC;;;;;;;;;;CAWA,AAAO,IAA4B,KAAQ,OAAwB;EACjE,KAAK,OAAO,GAAG,MAAM,MAAM,CAAQ;CACrC;;;;CAKA,AAAO,QAAc;EACnB,KAAK,QAAQ,UAAU,CAAC,CAAW;CACrC;;;;CAKA,AAAO,aAAsB;EAC3B,OAAO,KAAK,QAAQ,SAAS,MAAM;CACrC;AAYF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzJA,IAAa,iBAAb,MAA4B;;kCACP,IAAI,IAA0B;;;;;;;;;CASjD,AAAO,SAAS,MAAc,SAA6B;EACzD,KAAK,SAAS,IAAI,MAAM,OAAO;EAC/B,OAAO;CACT;;;;;;;;;;;CAYA,MAAa,OAAU,QAA6B,UAAwC;EAQ1F,OAPgB,MAAM,KAAK,KAAK,SAAS,QAAQ,CAG5B,CAAC,CAAC,aAAa,MAAM,CAAC,MAAM,aAAa;GAC5D,aAAa,QAAQ,IAAI,OAAO,SAAS,CAAC,GAAG,IAAI;EACnD,GAAG,QAES,CAAC,CAAC;CAChB;;;;;;CAOA,AAAO,SAAS,QAAmC;EACjD,KAAK,MAAM,CAAC,MAAM,YAAY,KAAK,SAAS,QAAQ,GAClD,IAAI,OAAO,OACT,QAAQ,MAAM,OAAO,KAAK;CAGhC;;;;CAKA,AAAO,WAAiB;EACtB,KAAK,MAAM,WAAW,KAAK,SAAS,OAAO,GACzC,QAAQ,MAAM;CAElB;;;;;;;CAQA,AAAO,WAAmC,MAA6B;EACrE,OAAO,KAAK,SAAS,IAAI,IAAI;CAC/B;;;;;;;CAQA,AAAO,WAAW,MAAuB;EACvC,OAAO,KAAK,SAAS,IAAI,IAAI;CAC/B;;;;;;;;;;;;;;;;CAiBA,AAAO,YAAY,SAAoD;EACrE,MAAM,SAA8B,CAAC;EAErC,KAAK,MAAM,CAAC,MAAM,YAAY,KAAK,SAAS,QAAQ,GAClD,OAAO,QAAQ,QAAQ,WAAW,OAAO,KAAK,CAAC;EAGjD,OAAO;CACT;;;;;;;CAQA,AAAO,WAAW,MAAuB;EACvC,OAAO,KAAK,SAAS,OAAO,IAAI;CAClC;AACF;;;;;;AAOA,MAAa,iBAAiB,IAAI,eAAe"}
@@ -1,6 +1,6 @@
1
1
  import { AsyncLocalStorage } from "async_hooks";
2
2
 
3
- //#region ../context/src/base-context.d.ts
3
+ //#region ../../packages/context/src/base-context.d.ts
4
4
  /**
5
5
  * Base class for all AsyncLocalStorage-based contexts
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"base-context.d.mts","names":[],"sources":["../../../../../../context/src/base-context.ts"],"mappings":";;;;;AAqEA;;;;;;;;;;;;;;;;;;;;;;uBAAsB,OAAA,gBAAuB,MAAA;EAAA,mBACxB,OAAA,EAAS,iBAAA,CAAkB,MAAA;EA6Ga;;;;;;;;;;EAjGpD,GAAA,IAAO,KAAA,EAAO,MAAA,EAAQ,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAApD;;;;;;;;EAYP,KAAA,CAAM,KAAA,EAAO,MAAA;EAkBb;;;;;;;;;;;;;;EAAA,MAAA,CAAO,OAAA,EAAS,OAAA,CAAQ,MAAA;EAwCJ;;;;;EAvBpB,QAAA,IAAY,MAAA;EA8BZ;;;;;;EApBA,GAAA,iBAAoB,MAAA,EAAQ,GAAA,EAAK,CAAA,GAAI,MAAA,CAAO,CAAA;EAwCc;;;;;;;;;EA3B1D,GAAA,iBAAoB,MAAA,EAAQ,GAAA,EAAK,CAAA,EAAG,KAAA,EAAO,MAAA,CAAO,CAAA;;;;EAOlD,KAAA;;;;EAOA,UAAA;;;;;;;;;;WAaS,UAAA,CAAW,OAAA,GAAU,MAAA,gBAAsB,MAAA;AAAA"}
1
+ {"version":3,"file":"base-context.d.mts","names":[],"sources":["../../../../../../../packages/context/src/base-context.ts"],"mappings":";;;;;AAqEA;;;;;;;;;;;;;;;;;;;;;;uBAAsB,OAAA,gBAAuB,MAAA;EAAA,mBACxB,OAAA,EAAS,iBAAA,CAAkB,MAAA;EA6Ga;;;;;;;;;;EAjGpD,GAAA,IAAO,KAAA,EAAO,MAAA,EAAQ,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAApD;;;;;;;;EAYP,KAAA,CAAM,KAAA,EAAO,MAAA;EAkBb;;;;;;;;;;;;;;EAAA,MAAA,CAAO,OAAA,EAAS,OAAA,CAAQ,MAAA;EAwCJ;;;;;EAvBpB,QAAA,IAAY,MAAA;EA8BZ;;;;;;EApBA,GAAA,iBAAoB,MAAA,EAAQ,GAAA,EAAK,CAAA,GAAI,MAAA,CAAO,CAAA;EAwCc;;;;;;;;;EA3B1D,GAAA,iBAAoB,MAAA,EAAQ,GAAA,EAAK,CAAA,EAAG,KAAA,EAAO,MAAA,CAAO,CAAA;;;;EAOlD,KAAA;;;;EAOA,UAAA;;;;;;;;;;WAaS,UAAA,CAAW,OAAA,GAAU,MAAA,gBAAsB,MAAA;AAAA"}
@@ -1,6 +1,6 @@
1
1
  import { AsyncLocalStorage } from "async_hooks";
2
2
 
3
- //#region ../context/src/base-context.ts
3
+ //#region ../../packages/context/src/base-context.ts
4
4
  /**
5
5
  * Keys that reach `Object.prototype` instead of the store when assigned.
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"base-context.mjs","names":[],"sources":["../../../../../../context/src/base-context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"async_hooks\";\n\n/**\n * Keys that reach `Object.prototype` instead of the store when assigned.\n *\n * `Object.assign(store, { __proto__: {...} })` does not create a property — it\n * invokes the inherited `__proto__` setter and reparents the store, which for a\n * shared context store means every later property lookup in the process can\n * resolve through attacker-supplied data. `constructor` / `prototype` are the\n * neighbouring rungs of the same ladder.\n */\nconst DANGEROUS_KEYS = [\"__proto__\", \"constructor\", \"prototype\"] as const;\n\n/**\n * Drop prototype-poisoning keys from a merge payload.\n *\n * Contexts are frequently fed request-shaped data (`context.update(req.body)`,\n * `context.set(key, value)` with a caller-supplied key), so the merge path is\n * treated as an untrusted boundary: dangerous keys are dropped rather than\n * throwing, since a request that trips this must not be able to take the\n * process down, and the store simply never carries them.\n *\n * The common case allocates nothing — a copy is made only when a dangerous key\n * is actually present. The copy is built by spread (which defines properties\n * rather than assigning them, so it cannot trigger the setter itself) and\n * preserves symbol keys, which `Object.assign` would have copied.\n */\nfunction withoutDangerousKeys<T>(updates: T): T {\n if (!updates || typeof updates !== \"object\") return updates;\n\n const hasDangerousKey = DANGEROUS_KEYS.some(key =>\n Object.prototype.hasOwnProperty.call(updates, key),\n );\n\n if (!hasDangerousKey) return updates;\n\n const safe: Record<string, any> = { ...(updates as Record<string, any>) };\n\n for (const key of DANGEROUS_KEYS) {\n delete safe[key];\n }\n\n return safe as T;\n}\n\n/**\n * Base class for all AsyncLocalStorage-based contexts\n *\n * Provides a consistent API for managing context across async operations.\n * All framework contexts (request, storage, database) extend this class.\n *\n * @template TStore - The type of data stored in context\n *\n * @example\n * ```typescript\n * interface MyContextStore {\n * userId: string;\n * tenant: string;\n * }\n *\n * class MyContext extends Context<MyContextStore> {}\n * const myContext = new MyContext();\n *\n * // Use it\n * await myContext.run({ userId: '123', tenant: 'acme' }, async () => {\n * const userId = myContext.get('userId'); // '123'\n * });\n * ```\n */\nexport abstract class Context<TStore extends Record<string, any>> {\n protected readonly storage: AsyncLocalStorage<TStore> = new AsyncLocalStorage<TStore>();\n\n /**\n * Run a callback within a new context\n *\n * Creates a new async context with the provided store data.\n * All operations within the callback will have access to this context.\n *\n * @param store - Initial context data\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public run<T>(store: TStore, callback: () => Promise<T>): Promise<T> {\n return this.storage.run(store, callback);\n }\n\n /**\n * Enter a new context without a callback\n *\n * Useful for middleware where you want to set context for the rest of the request.\n * Unlike `run()`, this doesn't require a callback.\n *\n * @param store - Context data to set\n */\n public enter(store: TStore): void {\n this.storage.enterWith(store);\n }\n\n /**\n * Update the current context\n *\n * Merges new data into existing context, or enters new context if none exists.\n *\n * Keys named `__proto__`, `constructor`, or `prototype` are dropped: the\n * merge target is a store shared by everything running in this async chain,\n * so letting those through would let one caller's payload change property\n * resolution for the whole process. Passing unvalidated input here is still\n * discouraged — this guard closes the prototype vector, not the \"an attacker\n * chose what your context says\" one.\n *\n * @param updates - Partial context data to merge\n */\n public update(updates: Partial<TStore>): void {\n const safeUpdates = withoutDangerousKeys(updates);\n\n const current = this.storage.getStore();\n\n if (current) {\n Object.assign(current, safeUpdates);\n } else {\n this.enter(safeUpdates as TStore);\n }\n }\n\n /**\n * Get the current context store\n *\n * @returns Current context or undefined if not in context\n */\n public getStore(): TStore | undefined {\n return this.storage.getStore();\n }\n\n /**\n * Get a specific value from context\n *\n * @param key - Key to retrieve\n * @returns Value or undefined\n */\n public get<K extends keyof TStore>(key: K): TStore[K] | undefined {\n return this.storage.getStore()?.[key];\n }\n\n /**\n * Set a specific value in context\n *\n * Goes through `update()`, so a caller-supplied `key` of `__proto__` /\n * `constructor` / `prototype` is dropped rather than reparenting the store.\n *\n * @param key - Key to set\n * @param value - Value to store\n */\n public set<K extends keyof TStore>(key: K, value: TStore[K]): void {\n this.update({ [key]: value } as any);\n }\n\n /**\n * Clear the context\n */\n public clear(): void {\n this.storage.enterWith({} as TStore);\n }\n\n /**\n * Check if currently in a context\n */\n public hasContext(): boolean {\n return this.storage.getStore() !== undefined;\n }\n\n /**\n * Build the initial store for this context\n *\n * Override this method to provide custom initialization logic.\n * Called by ContextManager.buildStores() for each registered context.\n *\n * @param payload - Generic payload (e.g., { request, response } for HTTP contexts)\n * @returns Initial store data\n */\n public abstract buildStore(payload?: Record<string, any>): TStore;\n}\n"],"mappings":";;;;;;;;;;;;AAWA,MAAM,iBAAiB;CAAC;CAAa;CAAe;AAAW;;;;;;;;;;;;;;;AAgB/D,SAAS,qBAAwB,SAAe;CAC9C,IAAI,CAAC,WAAW,OAAO,YAAY,UAAU,OAAO;CAMpD,IAAI,CAJoB,eAAe,MAAK,QAC1C,OAAO,UAAU,eAAe,KAAK,SAAS,GAAG,CAGhC,GAAG,OAAO;CAE7B,MAAM,OAA4B,EAAE,GAAI,QAAgC;CAExE,KAAK,MAAM,OAAO,gBAChB,OAAO,KAAK;CAGd,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAsB,UAAtB,MAAkE;;iBACR,IAAI,kBAA0B;;;;;;;;;;;;CAYtF,AAAO,IAAO,OAAe,UAAwC;EACnE,OAAO,KAAK,QAAQ,IAAI,OAAO,QAAQ;CACzC;;;;;;;;;CAUA,AAAO,MAAM,OAAqB;EAChC,KAAK,QAAQ,UAAU,KAAK;CAC9B;;;;;;;;;;;;;;;CAgBA,AAAO,OAAO,SAAgC;EAC5C,MAAM,cAAc,qBAAqB,OAAO;EAEhD,MAAM,UAAU,KAAK,QAAQ,SAAS;EAEtC,IAAI,SACF,OAAO,OAAO,SAAS,WAAW;OAElC,KAAK,MAAM,WAAqB;CAEpC;;;;;;CAOA,AAAO,WAA+B;EACpC,OAAO,KAAK,QAAQ,SAAS;CAC/B;;;;;;;CAQA,AAAO,IAA4B,KAA+B;EAChE,OAAO,KAAK,QAAQ,SAAS,CAAC,GAAG;CACnC;;;;;;;;;;CAWA,AAAO,IAA4B,KAAQ,OAAwB;EACjE,KAAK,OAAO,GAAG,MAAM,MAAM,CAAQ;CACrC;;;;CAKA,AAAO,QAAc;EACnB,KAAK,QAAQ,UAAU,CAAC,CAAW;CACrC;;;;CAKA,AAAO,aAAsB;EAC3B,OAAO,KAAK,QAAQ,SAAS,MAAM;CACrC;AAYF"}
1
+ {"version":3,"file":"base-context.mjs","names":[],"sources":["../../../../../../../packages/context/src/base-context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"async_hooks\";\n\n/**\n * Keys that reach `Object.prototype` instead of the store when assigned.\n *\n * `Object.assign(store, { __proto__: {...} })` does not create a property — it\n * invokes the inherited `__proto__` setter and reparents the store, which for a\n * shared context store means every later property lookup in the process can\n * resolve through attacker-supplied data. `constructor` / `prototype` are the\n * neighbouring rungs of the same ladder.\n */\nconst DANGEROUS_KEYS = [\"__proto__\", \"constructor\", \"prototype\"] as const;\n\n/**\n * Drop prototype-poisoning keys from a merge payload.\n *\n * Contexts are frequently fed request-shaped data (`context.update(req.body)`,\n * `context.set(key, value)` with a caller-supplied key), so the merge path is\n * treated as an untrusted boundary: dangerous keys are dropped rather than\n * throwing, since a request that trips this must not be able to take the\n * process down, and the store simply never carries them.\n *\n * The common case allocates nothing — a copy is made only when a dangerous key\n * is actually present. The copy is built by spread (which defines properties\n * rather than assigning them, so it cannot trigger the setter itself) and\n * preserves symbol keys, which `Object.assign` would have copied.\n */\nfunction withoutDangerousKeys<T>(updates: T): T {\n if (!updates || typeof updates !== \"object\") return updates;\n\n const hasDangerousKey = DANGEROUS_KEYS.some(key =>\n Object.prototype.hasOwnProperty.call(updates, key),\n );\n\n if (!hasDangerousKey) return updates;\n\n const safe: Record<string, any> = { ...(updates as Record<string, any>) };\n\n for (const key of DANGEROUS_KEYS) {\n delete safe[key];\n }\n\n return safe as T;\n}\n\n/**\n * Base class for all AsyncLocalStorage-based contexts\n *\n * Provides a consistent API for managing context across async operations.\n * All framework contexts (request, storage, database) extend this class.\n *\n * @template TStore - The type of data stored in context\n *\n * @example\n * ```typescript\n * interface MyContextStore {\n * userId: string;\n * tenant: string;\n * }\n *\n * class MyContext extends Context<MyContextStore> {}\n * const myContext = new MyContext();\n *\n * // Use it\n * await myContext.run({ userId: '123', tenant: 'acme' }, async () => {\n * const userId = myContext.get('userId'); // '123'\n * });\n * ```\n */\nexport abstract class Context<TStore extends Record<string, any>> {\n protected readonly storage: AsyncLocalStorage<TStore> = new AsyncLocalStorage<TStore>();\n\n /**\n * Run a callback within a new context\n *\n * Creates a new async context with the provided store data.\n * All operations within the callback will have access to this context.\n *\n * @param store - Initial context data\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public run<T>(store: TStore, callback: () => Promise<T>): Promise<T> {\n return this.storage.run(store, callback);\n }\n\n /**\n * Enter a new context without a callback\n *\n * Useful for middleware where you want to set context for the rest of the request.\n * Unlike `run()`, this doesn't require a callback.\n *\n * @param store - Context data to set\n */\n public enter(store: TStore): void {\n this.storage.enterWith(store);\n }\n\n /**\n * Update the current context\n *\n * Merges new data into existing context, or enters new context if none exists.\n *\n * Keys named `__proto__`, `constructor`, or `prototype` are dropped: the\n * merge target is a store shared by everything running in this async chain,\n * so letting those through would let one caller's payload change property\n * resolution for the whole process. Passing unvalidated input here is still\n * discouraged — this guard closes the prototype vector, not the \"an attacker\n * chose what your context says\" one.\n *\n * @param updates - Partial context data to merge\n */\n public update(updates: Partial<TStore>): void {\n const safeUpdates = withoutDangerousKeys(updates);\n\n const current = this.storage.getStore();\n\n if (current) {\n Object.assign(current, safeUpdates);\n } else {\n this.enter(safeUpdates as TStore);\n }\n }\n\n /**\n * Get the current context store\n *\n * @returns Current context or undefined if not in context\n */\n public getStore(): TStore | undefined {\n return this.storage.getStore();\n }\n\n /**\n * Get a specific value from context\n *\n * @param key - Key to retrieve\n * @returns Value or undefined\n */\n public get<K extends keyof TStore>(key: K): TStore[K] | undefined {\n return this.storage.getStore()?.[key];\n }\n\n /**\n * Set a specific value in context\n *\n * Goes through `update()`, so a caller-supplied `key` of `__proto__` /\n * `constructor` / `prototype` is dropped rather than reparenting the store.\n *\n * @param key - Key to set\n * @param value - Value to store\n */\n public set<K extends keyof TStore>(key: K, value: TStore[K]): void {\n this.update({ [key]: value } as any);\n }\n\n /**\n * Clear the context\n */\n public clear(): void {\n this.storage.enterWith({} as TStore);\n }\n\n /**\n * Check if currently in a context\n */\n public hasContext(): boolean {\n return this.storage.getStore() !== undefined;\n }\n\n /**\n * Build the initial store for this context\n *\n * Override this method to provide custom initialization logic.\n * Called by ContextManager.buildStores() for each registered context.\n *\n * @param payload - Generic payload (e.g., { request, response } for HTTP contexts)\n * @returns Initial store data\n */\n public abstract buildStore(payload?: Record<string, any>): TStore;\n}\n"],"mappings":";;;;;;;;;;;;AAWA,MAAM,iBAAiB;CAAC;CAAa;CAAe;AAAW;;;;;;;;;;;;;;;AAgB/D,SAAS,qBAAwB,SAAe;CAC9C,IAAI,CAAC,WAAW,OAAO,YAAY,UAAU,OAAO;CAMpD,IAAI,CAJoB,eAAe,MAAK,QAC1C,OAAO,UAAU,eAAe,KAAK,SAAS,GAAG,CAGhC,GAAG,OAAO;CAE7B,MAAM,OAA4B,EAAE,GAAI,QAAgC;CAExE,KAAK,MAAM,OAAO,gBAChB,OAAO,KAAK;CAGd,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAsB,UAAtB,MAAkE;;iBACR,IAAI,kBAA0B;;;;;;;;;;;;CAYtF,AAAO,IAAO,OAAe,UAAwC;EACnE,OAAO,KAAK,QAAQ,IAAI,OAAO,QAAQ;CACzC;;;;;;;;;CAUA,AAAO,MAAM,OAAqB;EAChC,KAAK,QAAQ,UAAU,KAAK;CAC9B;;;;;;;;;;;;;;;CAgBA,AAAO,OAAO,SAAgC;EAC5C,MAAM,cAAc,qBAAqB,OAAO;EAEhD,MAAM,UAAU,KAAK,QAAQ,SAAS;EAEtC,IAAI,SACF,OAAO,OAAO,SAAS,WAAW;OAElC,KAAK,MAAM,WAAqB;CAEpC;;;;;;CAOA,AAAO,WAA+B;EACpC,OAAO,KAAK,QAAQ,SAAS;CAC/B;;;;;;;CAQA,AAAO,IAA4B,KAA+B;EAChE,OAAO,KAAK,QAAQ,SAAS,CAAC,GAAG;CACnC;;;;;;;;;;CAWA,AAAO,IAA4B,KAAQ,OAAwB;EACjE,KAAK,OAAO,GAAG,MAAM,MAAM,CAAQ;CACrC;;;;CAKA,AAAO,QAAc;EACnB,KAAK,QAAQ,UAAU,CAAC,CAAW;CACrC;;;;CAKA,AAAO,aAAsB;EAC3B,OAAO,KAAK,QAAQ,SAAS,MAAM;CACrC;AAYF"}
@@ -1,6 +1,6 @@
1
1
  import { Context } from "./base-context.mjs";
2
2
 
3
- //#region ../context/src/context-manager.d.ts
3
+ //#region ../../packages/context/src/context-manager.d.ts
4
4
  /**
5
5
  * Context Manager - Orchestrates multiple contexts together
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"context-manager.d.mts","names":[],"sources":["../../../../../../context/src/context-manager.ts"],"mappings":";;;;;AA2BA;;;;;;;;;;;;;;;;;;;;;;;cAAa,cAAA;EAAA,QACH,QAAA;EAwB4D;;;;;;;EAf7D,QAAA,CAAS,IAAA,UAAc,OAAA,EAAS,OAAA;EA0ChC;;;;;;;;;;EA3BM,MAAA,IAAU,MAAA,EAAQ,MAAA,eAAqB,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAoEtC;;;;AAgBrB;EApEvB,QAAA,CAAS,MAAA,EAAQ,MAAA;EA8EwB;;;EAnEzC,QAAA;;;;;;;EAYA,UAAA,WAAqB,OAAA,OAAc,IAAA,WAAe,CAAA;;;;;;;EAUlD,UAAA,CAAW,IAAA;;;;;;;;;;;;;;;;EAmBX,WAAA,CAAY,OAAA,GAAU,MAAA,gBAAsB,MAAA;;;;;;;EAgB5C,UAAA,CAAW,IAAA;AAAA;;;;;;cAUP,cAAA,EAAc,cAAuB"}
1
+ {"version":3,"file":"context-manager.d.mts","names":[],"sources":["../../../../../../../packages/context/src/context-manager.ts"],"mappings":";;;;;AA2BA;;;;;;;;;;;;;;;;;;;;;;;cAAa,cAAA;EAAA,QACH,QAAA;EAwB4D;;;;;;;EAf7D,QAAA,CAAS,IAAA,UAAc,OAAA,EAAS,OAAA;EA0ChC;;;;;;;;;;EA3BM,MAAA,IAAU,MAAA,EAAQ,MAAA,eAAqB,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAoEtC;;;;AAgBrB;EApEvB,QAAA,CAAS,MAAA,EAAQ,MAAA;EA8EwB;;;EAnEzC,QAAA;;;;;;;EAYA,UAAA,WAAqB,OAAA,OAAc,IAAA,WAAe,CAAA;;;;;;;EAUlD,UAAA,CAAW,IAAA;;;;;;;;;;;;;;;;EAmBX,WAAA,CAAY,OAAA,GAAU,MAAA,gBAAsB,MAAA;;;;;;;EAgB5C,UAAA,CAAW,IAAA;AAAA;;;;;;cAUP,cAAA,EAAc,cAAuB"}
@@ -1,4 +1,4 @@
1
- //#region ../context/src/context-manager.ts
1
+ //#region ../../packages/context/src/context-manager.ts
2
2
  /**
3
3
  * Context Manager - Orchestrates multiple contexts together
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"context-manager.mjs","names":[],"sources":["../../../../../../context/src/context-manager.ts"],"sourcesContent":["import type { Context } from \"./base-context\";\n\n/**\n * Context Manager - Orchestrates multiple contexts together\n *\n * Allows running multiple AsyncLocalStorage contexts in a single operation,\n * making it easy to link request, storage, database, and other contexts.\n *\n * @example\n * ```typescript\n * // Register contexts\n * contextManager\n * .register('request', requestContext)\n * .register('storage', storageDriverContext)\n * .register('database', databaseDataSourceContext);\n *\n * // Run all contexts together\n * await contextManager.runAll({\n * request: { request, response, user },\n * storage: { driver, metadata: { tenantId: '123' } },\n * database: { dataSource: 'primary' },\n * }, async () => {\n * // All contexts active!\n * await handleRequest();\n * });\n * ```\n */\nexport class ContextManager {\n private contexts = new Map<string, Context<any>>();\n\n /**\n * Register a context\n *\n * @param name - Unique context name\n * @param context - Context instance\n * @returns This instance for chaining\n */\n public register(name: string, context: Context<any>): this {\n this.contexts.set(name, context);\n return this;\n }\n\n /**\n * Run all registered contexts together\n *\n * Nests all context.run() calls, ensuring all contexts are active\n * for the duration of the callback.\n *\n * @param stores - Context stores keyed by context name\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public async runAll<T>(stores: Record<string, any>, callback: () => Promise<T>): Promise<T> {\n const entries = Array.from(this.contexts.entries());\n\n // Build nested context runners\n const runner = entries.reduceRight((next, [name, context]) => {\n return () => context.run(stores[name] || {}, next);\n }, callback);\n\n return runner();\n }\n\n /**\n * Enter all contexts at once (for middleware)\n *\n * @param stores - Context stores keyed by context name\n */\n public enterAll(stores: Record<string, any>): void {\n for (const [name, context] of this.contexts.entries()) {\n if (stores[name]) {\n context.enter(stores[name]);\n }\n }\n }\n\n /**\n * Clear all contexts\n */\n public clearAll(): void {\n for (const context of this.contexts.values()) {\n context.clear();\n }\n }\n\n /**\n * Get a specific registered context\n *\n * @param name - Context name\n * @returns Context instance or undefined\n */\n public getContext<T extends Context<any>>(name: string): T | undefined {\n return this.contexts.get(name) as T | undefined;\n }\n\n /**\n * Check if a context is registered\n *\n * @param name - Context name\n * @returns True if context is registered\n */\n public hasContext(name: string): boolean {\n return this.contexts.has(name);\n }\n\n /**\n * Build all context stores by calling each context's buildStore() method\n *\n * This is the immutable pattern - returns a new record of stores.\n * Each context defines its own initialization logic.\n *\n * @param payload - Payload passed to each buildStore() (e.g., { request, response })\n * @returns Record of context name -> store data\n *\n * @example\n * ```typescript\n * const httpContextStore = contextManager.buildStores({ request, response });\n * await contextManager.runAll(httpContextStore, async () => { ... });\n * ```\n */\n public buildStores(payload?: Record<string, any>): Record<string, any> {\n const stores: Record<string, any> = {};\n\n for (const [name, context] of this.contexts.entries()) {\n stores[name] = context.buildStore(payload) ?? {};\n }\n\n return stores;\n }\n\n /**\n * Unregister a context\n *\n * @param name - Context name to remove\n * @returns True if context was removed\n */\n public unregister(name: string): boolean {\n return this.contexts.delete(name);\n }\n}\n\n/**\n * Global context manager instance\n *\n * Use this singleton to register and manage all framework contexts.\n */\nexport const contextManager = new ContextManager();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAa,iBAAb,MAA4B;;kCACP,IAAI,IAA0B;;;;;;;;;CASjD,AAAO,SAAS,MAAc,SAA6B;EACzD,KAAK,SAAS,IAAI,MAAM,OAAO;EAC/B,OAAO;CACT;;;;;;;;;;;CAYA,MAAa,OAAU,QAA6B,UAAwC;EAQ1F,OAPgB,MAAM,KAAK,KAAK,SAAS,QAAQ,CAG5B,CAAC,CAAC,aAAa,MAAM,CAAC,MAAM,aAAa;GAC5D,aAAa,QAAQ,IAAI,OAAO,SAAS,CAAC,GAAG,IAAI;EACnD,GAAG,QAES,CAAC,CAAC;CAChB;;;;;;CAOA,AAAO,SAAS,QAAmC;EACjD,KAAK,MAAM,CAAC,MAAM,YAAY,KAAK,SAAS,QAAQ,GAClD,IAAI,OAAO,OACT,QAAQ,MAAM,OAAO,KAAK;CAGhC;;;;CAKA,AAAO,WAAiB;EACtB,KAAK,MAAM,WAAW,KAAK,SAAS,OAAO,GACzC,QAAQ,MAAM;CAElB;;;;;;;CAQA,AAAO,WAAmC,MAA6B;EACrE,OAAO,KAAK,SAAS,IAAI,IAAI;CAC/B;;;;;;;CAQA,AAAO,WAAW,MAAuB;EACvC,OAAO,KAAK,SAAS,IAAI,IAAI;CAC/B;;;;;;;;;;;;;;;;CAiBA,AAAO,YAAY,SAAoD;EACrE,MAAM,SAA8B,CAAC;EAErC,KAAK,MAAM,CAAC,MAAM,YAAY,KAAK,SAAS,QAAQ,GAClD,OAAO,QAAQ,QAAQ,WAAW,OAAO,KAAK,CAAC;EAGjD,OAAO;CACT;;;;;;;CAQA,AAAO,WAAW,MAAuB;EACvC,OAAO,KAAK,SAAS,OAAO,IAAI;CAClC;AACF;;;;;;AAOA,MAAa,iBAAiB,IAAI,eAAe"}
1
+ {"version":3,"file":"context-manager.mjs","names":[],"sources":["../../../../../../../packages/context/src/context-manager.ts"],"sourcesContent":["import type { Context } from \"./base-context\";\n\n/**\n * Context Manager - Orchestrates multiple contexts together\n *\n * Allows running multiple AsyncLocalStorage contexts in a single operation,\n * making it easy to link request, storage, database, and other contexts.\n *\n * @example\n * ```typescript\n * // Register contexts\n * contextManager\n * .register('request', requestContext)\n * .register('storage', storageDriverContext)\n * .register('database', databaseDataSourceContext);\n *\n * // Run all contexts together\n * await contextManager.runAll({\n * request: { request, response, user },\n * storage: { driver, metadata: { tenantId: '123' } },\n * database: { dataSource: 'primary' },\n * }, async () => {\n * // All contexts active!\n * await handleRequest();\n * });\n * ```\n */\nexport class ContextManager {\n private contexts = new Map<string, Context<any>>();\n\n /**\n * Register a context\n *\n * @param name - Unique context name\n * @param context - Context instance\n * @returns This instance for chaining\n */\n public register(name: string, context: Context<any>): this {\n this.contexts.set(name, context);\n return this;\n }\n\n /**\n * Run all registered contexts together\n *\n * Nests all context.run() calls, ensuring all contexts are active\n * for the duration of the callback.\n *\n * @param stores - Context stores keyed by context name\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public async runAll<T>(stores: Record<string, any>, callback: () => Promise<T>): Promise<T> {\n const entries = Array.from(this.contexts.entries());\n\n // Build nested context runners\n const runner = entries.reduceRight((next, [name, context]) => {\n return () => context.run(stores[name] || {}, next);\n }, callback);\n\n return runner();\n }\n\n /**\n * Enter all contexts at once (for middleware)\n *\n * @param stores - Context stores keyed by context name\n */\n public enterAll(stores: Record<string, any>): void {\n for (const [name, context] of this.contexts.entries()) {\n if (stores[name]) {\n context.enter(stores[name]);\n }\n }\n }\n\n /**\n * Clear all contexts\n */\n public clearAll(): void {\n for (const context of this.contexts.values()) {\n context.clear();\n }\n }\n\n /**\n * Get a specific registered context\n *\n * @param name - Context name\n * @returns Context instance or undefined\n */\n public getContext<T extends Context<any>>(name: string): T | undefined {\n return this.contexts.get(name) as T | undefined;\n }\n\n /**\n * Check if a context is registered\n *\n * @param name - Context name\n * @returns True if context is registered\n */\n public hasContext(name: string): boolean {\n return this.contexts.has(name);\n }\n\n /**\n * Build all context stores by calling each context's buildStore() method\n *\n * This is the immutable pattern - returns a new record of stores.\n * Each context defines its own initialization logic.\n *\n * @param payload - Payload passed to each buildStore() (e.g., { request, response })\n * @returns Record of context name -> store data\n *\n * @example\n * ```typescript\n * const httpContextStore = contextManager.buildStores({ request, response });\n * await contextManager.runAll(httpContextStore, async () => { ... });\n * ```\n */\n public buildStores(payload?: Record<string, any>): Record<string, any> {\n const stores: Record<string, any> = {};\n\n for (const [name, context] of this.contexts.entries()) {\n stores[name] = context.buildStore(payload) ?? {};\n }\n\n return stores;\n }\n\n /**\n * Unregister a context\n *\n * @param name - Context name to remove\n * @returns True if context was removed\n */\n public unregister(name: string): boolean {\n return this.contexts.delete(name);\n }\n}\n\n/**\n * Global context manager instance\n *\n * Use this singleton to register and manage all framework contexts.\n */\nexport const contextManager = new ContextManager();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAa,iBAAb,MAA4B;;kCACP,IAAI,IAA0B;;;;;;;;;CASjD,AAAO,SAAS,MAAc,SAA6B;EACzD,KAAK,SAAS,IAAI,MAAM,OAAO;EAC/B,OAAO;CACT;;;;;;;;;;;CAYA,MAAa,OAAU,QAA6B,UAAwC;EAQ1F,OAPgB,MAAM,KAAK,KAAK,SAAS,QAAQ,CAG5B,CAAC,CAAC,aAAa,MAAM,CAAC,MAAM,aAAa;GAC5D,aAAa,QAAQ,IAAI,OAAO,SAAS,CAAC,GAAG,IAAI;EACnD,GAAG,QAES,CAAC,CAAC;CAChB;;;;;;CAOA,AAAO,SAAS,QAAmC;EACjD,KAAK,MAAM,CAAC,MAAM,YAAY,KAAK,SAAS,QAAQ,GAClD,IAAI,OAAO,OACT,QAAQ,MAAM,OAAO,KAAK;CAGhC;;;;CAKA,AAAO,WAAiB;EACtB,KAAK,MAAM,WAAW,KAAK,SAAS,OAAO,GACzC,QAAQ,MAAM;CAElB;;;;;;;CAQA,AAAO,WAAmC,MAA6B;EACrE,OAAO,KAAK,SAAS,IAAI,IAAI;CAC/B;;;;;;;CAQA,AAAO,WAAW,MAAuB;EACvC,OAAO,KAAK,SAAS,IAAI,IAAI;CAC/B;;;;;;;;;;;;;;;;CAiBA,AAAO,YAAY,SAAoD;EACrE,MAAM,SAA8B,CAAC;EAErC,KAAK,MAAM,CAAC,MAAM,YAAY,KAAK,SAAS,QAAQ,GAClD,OAAO,QAAQ,QAAQ,WAAW,OAAO,KAAK,CAAC;EAGjD,OAAO;CACT;;;;;;;CAQA,AAAO,WAAW,MAAuB;EACvC,OAAO,KAAK,SAAS,OAAO,IAAI;CAClC;AACF;;;;;;AAOA,MAAa,iBAAiB,IAAI,eAAe"}
package/llms-full.txt CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  ---
10
10
  name: define-context
11
- description: 'Extend Context<TStore> to define an AsyncLocalStorage-backed typed context — implement buildStore, use run / enter / update / get / set / getStore / clear / hasContext. Triggers: `Context`, `Context<TStore>`, `buildStore`, `run`, `enter`, `update`, `get`, `set`, `getStore`, `clear`, `hasContext`; "share user/tenant/trace id across async calls", "AsyncLocalStorage typed wrapper", "request-scoped store without thread-through"; typical import `import { Context } from "@warlock.js/context"`. Skip: orchestrating multiple contexts — `@warlock.js/context/orchestrate-contexts/SKILL.md`; native `AsyncLocalStorage`, `cls-hooked`, `nest-context`, React Context.'
11
+ description: 'Extend Context<TStore> to define an AsyncLocalStorage-backed typed context — implement buildStore, use run / enter / update / get / set / getStore / clear / hasContext. Triggers: `Context`, `Context<TStore>`, `buildStore`, `run`, `enter`, `update`, `get`, `set`, `getStore`, `clear`, `hasContext`; "share user/tenant/trace id across async calls", "AsyncLocalStorage typed wrapper", "request-scoped store without thread-through"; typical import `import { Context } from "@warlock.js/context"`. Skip: orchestrating multiple contexts — the `orchestrate-contexts` topic; native `AsyncLocalStorage`, `cls-hooked`, `nest-context`, React Context.'
12
12
  ---
13
13
 
14
14
  # Define a context
@@ -158,7 +158,7 @@ Now `tenantContext.tenantId` reads better than `tenantContext.get("tenantId")` a
158
158
 
159
159
  ## See also
160
160
 
161
- - [`@warlock.js/context/orchestrate-contexts/SKILL.md`](@warlock.js/context/orchestrate-contexts/SKILL.md) — running multiple contexts together via the `contextManager` singleton.
161
+ - The `orchestrate-contexts` topic — running multiple contexts together via the `contextManager` singleton.
162
162
 
163
163
  ## Things NOT to do
164
164
 
@@ -172,7 +172,7 @@ Now `tenantContext.tenantId` reads better than `tenantContext.get("tenantId")` a
172
172
 
173
173
  ---
174
174
  name: orchestrate-contexts
175
- description: 'Orchestrate multiple Context<TStore> instances via the contextManager singleton — register, buildStores, runAll, enterAll, clearAll. Triggers: `contextManager`, `register`, `buildStores`, `runAll`, `enterAll`, `clearAll`, `unregister`, `getContext`, `hasContext`; "run multiple contexts active for the same scope", "register contexts at boot", "avoid nested run() calls for request + database + tenant"; typical import `import { contextManager } from "@warlock.js/context"`. Skip: defining a single context class — `@warlock.js/context/define-context/SKILL.md`; native `AsyncLocalStorage` nesting, `cls-hooked` namespaces.'
175
+ description: 'Orchestrate multiple Context<TStore> instances via the contextManager singleton — register, buildStores, runAll, enterAll, clearAll. Triggers: `contextManager`, `register`, `buildStores`, `runAll`, `enterAll`, `clearAll`, `unregister`, `getContext`, `hasContext`; "run multiple contexts active for the same scope", "register contexts at boot", "avoid nested run() calls for request + database + tenant"; typical import `import { contextManager } from "@warlock.js/context"`. Skip: defining a single context class — the `define-context` topic; native `AsyncLocalStorage` nesting, `cls-hooked` namespaces.'
176
176
  ---
177
177
 
178
178
  # Orchestrate contexts — `contextManager`
@@ -229,7 +229,7 @@ app.use(async (req, res, next) => {
229
229
  });
230
230
  ```
231
231
 
232
- `buildStores(payload)` calls each registered context's `buildStore(payload)` (the abstract method on `Context<TStore>` — see [`@warlock.js/context/define-context/SKILL.md`](@warlock.js/context/define-context/SKILL.md)) and returns `{ [contextName]: store }`.
232
+ `buildStores(payload)` calls each registered context's `buildStore(payload)` (the abstract method on `Context<TStore>` — see the `define-context` topic) and returns `{ [contextName]: store }`.
233
233
 
234
234
  `runAll(stores, fn)` nests every context's `run()` in registration order, then invokes `fn` at the innermost layer. All contexts are active inside `fn`.
235
235
 
@@ -360,7 +360,7 @@ Each `Context<TStore>` subclass declares a typed store shape and what payload bu
360
360
 
361
361
  Two task skills cover everything. The first one is the daily-use one; the second is for when you have multiple contexts active at the same time.
362
362
 
363
- ### [`define-context/`](../define-context/SKILL.md)
363
+ ### `define-context`
364
364
 
365
365
  Extend `Context<TStore>` to declare what your context stores and how it's
366
366
  built. Implement `buildStore(payload?)`; use `run` / `enter` / `update` /
@@ -371,7 +371,7 @@ Load when sharing data (user, tenant, trace id) across async calls
371
371
  without threading it through every function — i.e. ~90% of the time you
372
372
  use this package.
373
373
 
374
- ### [`orchestrate-contexts/`](../orchestrate-contexts/SKILL.md)
374
+ ### `orchestrate-contexts`
375
375
 
376
376
  Register multiple `Context<TStore>` instances on the `contextManager`
377
377
  singleton and run them all together with a single call. Covers
@@ -400,7 +400,7 @@ Load when several contexts apply to the same scope (request + database
400
400
 
401
401
  ## See also
402
402
 
403
- - [`@warlock.js/core/overview/SKILL.md`](@warlock.js/core/overview/SKILL.md) — the parent framework; `context` is one of its foundation packages.
404
- - `mongez-agent-kit-authoring-skills` (load via agent-kit sync) — how this `overview/SKILL.md` becomes the front-door skill in `.claude/skills/warlock-js-context-overview/`.
403
+ - The `overview` topic of the `warlock-js-core` skill — the parent framework; `context` is one of its foundation packages.
404
+ - `mongez-agent-kit-authoring-skills` (load via agent-kit sync) — how this `overview` topic becomes the front-door skill in `.claude/skills/warlock-js-context-overview/`.
405
405
 
406
406
 
package/llms.txt CHANGED
@@ -6,6 +6,6 @@
6
6
 
7
7
  ## Skills
8
8
 
9
- - [define-context](@warlock.js/context/define-context/SKILL.md): Extend Context<TStore> to define an AsyncLocalStorage-backed typed context — implement buildStore, use run / enter / update / get / set / getStore / clear / hasContext. Triggers: `Context`, `Context<TStore>`, `buildStore`, `run`, `enter`, `update`, `get`, `set`, `getStore`, `clear`, `hasContext`; "share user/tenant/trace id across async calls", "AsyncLocalStorage typed wrapper", "request-scoped store without thread-through"; typical import `import { Context } from "@warlock.js/context"`. Skip: orchestrating multiple contexts — `@warlock.js/context/orchestrate-contexts/SKILL.md`; native `AsyncLocalStorage`, `cls-hooked`, `nest-context`, React Context.
10
- - [orchestrate-contexts](@warlock.js/context/orchestrate-contexts/SKILL.md): Orchestrate multiple Context<TStore> instances via the contextManager singleton — register, buildStores, runAll, enterAll, clearAll. Triggers: `contextManager`, `register`, `buildStores`, `runAll`, `enterAll`, `clearAll`, `unregister`, `getContext`, `hasContext`; "run multiple contexts active for the same scope", "register contexts at boot", "avoid nested run() calls for request + database + tenant"; typical import `import { contextManager } from "@warlock.js/context"`. Skip: defining a single context class — `@warlock.js/context/define-context/SKILL.md`; native `AsyncLocalStorage` nesting, `cls-hooked` namespaces.
9
+ - [define-context](@warlock.js/context/define-context/SKILL.md): Extend Context<TStore> to define an AsyncLocalStorage-backed typed context — implement buildStore, use run / enter / update / get / set / getStore / clear / hasContext. Triggers: `Context`, `Context<TStore>`, `buildStore`, `run`, `enter`, `update`, `get`, `set`, `getStore`, `clear`, `hasContext`; "share user/tenant/trace id across async calls", "AsyncLocalStorage typed wrapper", "request-scoped store without thread-through"; typical import `import { Context } from "@warlock.js/context"`. Skip: orchestrating multiple contexts — the `orchestrate-contexts` topic; native `AsyncLocalStorage`, `cls-hooked`, `nest-context`, React Context.
10
+ - [orchestrate-contexts](@warlock.js/context/orchestrate-contexts/SKILL.md): Orchestrate multiple Context<TStore> instances via the contextManager singleton — register, buildStores, runAll, enterAll, clearAll. Triggers: `contextManager`, `register`, `buildStores`, `runAll`, `enterAll`, `clearAll`, `unregister`, `getContext`, `hasContext`; "run multiple contexts active for the same scope", "register contexts at boot", "avoid nested run() calls for request + database + tenant"; typical import `import { contextManager } from "@warlock.js/context"`. Skip: defining a single context class — the `define-context` topic; native `AsyncLocalStorage` nesting, `cls-hooked` namespaces.
11
11
  - [overview](@warlock.js/context/overview/SKILL.md): @warlock.js/context overview for orientation and choosing the focused skill for the task.
package/package.json CHANGED
@@ -15,16 +15,17 @@
15
15
  "license": "MIT",
16
16
  "repository": {
17
17
  "type": "git",
18
- "url": "git+https://github.com/warlockjs/context.git"
18
+ "url": "git+https://github.com/warlockjs/framework.git",
19
+ "directory": "packages/context"
19
20
  },
20
21
  "bugs": {
21
- "url": "https://github.com/warlockjs/context/issues"
22
+ "url": "https://github.com/warlockjs/framework/issues"
22
23
  },
23
- "homepage": "https://github.com/warlockjs/context#readme",
24
+ "homepage": "https://warlock.js.org",
24
25
  "engines": {
25
26
  "node": ">=18.0.0"
26
27
  },
27
- "version": "5.28.0",
28
+ "version": "5.30.0",
28
29
  "main": "./cjs/index.cjs",
29
30
  "module": "./esm/index.mjs",
30
31
  "types": "./esm/index.d.mts",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: define-context
3
- description: 'Extend Context<TStore> to define an AsyncLocalStorage-backed typed context — implement buildStore, use run / enter / update / get / set / getStore / clear / hasContext. Triggers: `Context`, `Context<TStore>`, `buildStore`, `run`, `enter`, `update`, `get`, `set`, `getStore`, `clear`, `hasContext`; "share user/tenant/trace id across async calls", "AsyncLocalStorage typed wrapper", "request-scoped store without thread-through"; typical import `import { Context } from "@warlock.js/context"`. Skip: orchestrating multiple contexts — `@warlock.js/context/orchestrate-contexts/SKILL.md`; native `AsyncLocalStorage`, `cls-hooked`, `nest-context`, React Context.'
3
+ description: 'Extend Context<TStore> to define an AsyncLocalStorage-backed typed context — implement buildStore, use run / enter / update / get / set / getStore / clear / hasContext. Triggers: `Context`, `Context<TStore>`, `buildStore`, `run`, `enter`, `update`, `get`, `set`, `getStore`, `clear`, `hasContext`; "share user/tenant/trace id across async calls", "AsyncLocalStorage typed wrapper", "request-scoped store without thread-through"; typical import `import { Context } from "@warlock.js/context"`. Skip: orchestrating multiple contexts — the `orchestrate-contexts` topic; native `AsyncLocalStorage`, `cls-hooked`, `nest-context`, React Context.'
4
4
  ---
5
5
 
6
6
  # Define a context
@@ -150,7 +150,7 @@ Now `tenantContext.tenantId` reads better than `tenantContext.get("tenantId")` a
150
150
 
151
151
  ## See also
152
152
 
153
- - [`@warlock.js/context/orchestrate-contexts/SKILL.md`](@warlock.js/context/orchestrate-contexts/SKILL.md) — running multiple contexts together via the `contextManager` singleton.
153
+ - The `orchestrate-contexts` topic — running multiple contexts together via the `contextManager` singleton.
154
154
 
155
155
  ## Things NOT to do
156
156
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: orchestrate-contexts
3
- description: 'Orchestrate multiple Context<TStore> instances via the contextManager singleton — register, buildStores, runAll, enterAll, clearAll. Triggers: `contextManager`, `register`, `buildStores`, `runAll`, `enterAll`, `clearAll`, `unregister`, `getContext`, `hasContext`; "run multiple contexts active for the same scope", "register contexts at boot", "avoid nested run() calls for request + database + tenant"; typical import `import { contextManager } from "@warlock.js/context"`. Skip: defining a single context class — `@warlock.js/context/define-context/SKILL.md`; native `AsyncLocalStorage` nesting, `cls-hooked` namespaces.'
3
+ description: 'Orchestrate multiple Context<TStore> instances via the contextManager singleton — register, buildStores, runAll, enterAll, clearAll. Triggers: `contextManager`, `register`, `buildStores`, `runAll`, `enterAll`, `clearAll`, `unregister`, `getContext`, `hasContext`; "run multiple contexts active for the same scope", "register contexts at boot", "avoid nested run() calls for request + database + tenant"; typical import `import { contextManager } from "@warlock.js/context"`. Skip: defining a single context class — the `define-context` topic; native `AsyncLocalStorage` nesting, `cls-hooked` namespaces.'
4
4
  ---
5
5
 
6
6
  # Orchestrate contexts — `contextManager`
@@ -57,7 +57,7 @@ app.use(async (req, res, next) => {
57
57
  });
58
58
  ```
59
59
 
60
- `buildStores(payload)` calls each registered context's `buildStore(payload)` (the abstract method on `Context<TStore>` — see [`@warlock.js/context/define-context/SKILL.md`](@warlock.js/context/define-context/SKILL.md)) and returns `{ [contextName]: store }`.
60
+ `buildStores(payload)` calls each registered context's `buildStore(payload)` (the abstract method on `Context<TStore>` — see the `define-context` topic) and returns `{ [contextName]: store }`.
61
61
 
62
62
  `runAll(stores, fn)` nests every context's `run()` in registration order, then invokes `fn` at the innermost layer. All contexts are active inside `fn`.
63
63
 
@@ -23,7 +23,7 @@ Each `Context<TStore>` subclass declares a typed store shape and what payload bu
23
23
 
24
24
  Two task skills cover everything. The first one is the daily-use one; the second is for when you have multiple contexts active at the same time.
25
25
 
26
- ### [`define-context/`](../define-context/SKILL.md)
26
+ ### `define-context`
27
27
 
28
28
  Extend `Context<TStore>` to declare what your context stores and how it's
29
29
  built. Implement `buildStore(payload?)`; use `run` / `enter` / `update` /
@@ -34,7 +34,7 @@ Load when sharing data (user, tenant, trace id) across async calls
34
34
  without threading it through every function — i.e. ~90% of the time you
35
35
  use this package.
36
36
 
37
- ### [`orchestrate-contexts/`](../orchestrate-contexts/SKILL.md)
37
+ ### `orchestrate-contexts`
38
38
 
39
39
  Register multiple `Context<TStore>` instances on the `contextManager`
40
40
  singleton and run them all together with a single call. Covers
@@ -63,5 +63,5 @@ Load when several contexts apply to the same scope (request + database
63
63
 
64
64
  ## See also
65
65
 
66
- - [`@warlock.js/core/overview/SKILL.md`](@warlock.js/core/overview/SKILL.md) — the parent framework; `context` is one of its foundation packages.
67
- - `mongez-agent-kit-authoring-skills` (load via agent-kit sync) — how this `overview/SKILL.md` becomes the front-door skill in `.claude/skills/warlock-js-context-overview/`.
66
+ - The `overview` topic of the `warlock-js-core` skill — the parent framework; `context` is one of its foundation packages.
67
+ - `mongez-agent-kit-authoring-skills` (load via agent-kit sync) — how this `overview` topic becomes the front-door skill in `.claude/skills/warlock-js-context-overview/`.