@cortexkit/opencode-magic-context 0.1.2 → 0.1.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,aAAa,EAClB,KAAK,cAAc,EACtB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAOvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAMxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AASxD,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAiBnF,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,yBAAyB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,iBAAiB,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;IAC9D,MAAM,EAAE;QACJ,cAAc,EAAE,MAAM,CAAC;QACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,4BAA4B,CAAC,EAAE,MAAM,GAAG;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC;QACxF,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3C,uBAAuB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE9C,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,MAAM,CAAC,EAAE;YACL,OAAO,EAAE,OAAO,CAAC;YACjB,uBAAuB,EAAE,MAAM,CAAC;SACnC,CAAC;QACF,QAAQ,CAAC,EAAE,cAAc,CAAC;QAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;KAC3B,CAAC;CACL;AAqCD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB;;;;;iBArF7B,CAAC;;;;;;;;;;;;iBA0BM,CAAC;eAAiB,CAAC;;mBA+P7B;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,UAAU,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE;;;SAY7E"}
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,aAAa,EAClB,KAAK,cAAc,EACtB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAOvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAMxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAUxD,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAiBnF,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,yBAAyB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,iBAAiB,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;IAC9D,MAAM,EAAE;QACJ,cAAc,EAAE,MAAM,CAAC;QACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,4BAA4B,CAAC,EAAE,MAAM,GAAG;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC;QACxF,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3C,uBAAuB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE9C,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,MAAM,CAAC,EAAE;YACL,OAAO,EAAE,OAAO,CAAC;YACjB,uBAAuB,EAAE,MAAM,CAAC;SACnC,CAAC;QACF,QAAQ,CAAC,EAAE,cAAc,CAAC;QAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;KAC3B,CAAC;CACL;AAqCD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB;;;;;iBAtF7B,CAAC;;;;;;;;;;;;iBA0B7B,CAAC;eAAiB,CAAC;;mBAmQM;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,UAAU,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE;;;SAY7E"}
@@ -4,11 +4,13 @@ import type { MessageLike } from "./tag-messages";
4
4
  export interface PreparedCompartmentInjection {
5
5
  block: string;
6
6
  compartmentEndMessage: number;
7
+ compartmentEndMessageId: string;
7
8
  compartmentCount: number;
8
9
  skippedVisibleMessages: number;
9
10
  factCount: number;
10
11
  memoryCount: number;
11
12
  }
13
+ export declare function clearInjectionCache(sessionId: string): void;
12
14
  export interface CompartmentInjectionResult {
13
15
  injected: boolean;
14
16
  compartmentEndMessage: number;
@@ -16,6 +18,6 @@ export interface CompartmentInjectionResult {
16
18
  skippedVisibleMessages: number;
17
19
  }
18
20
  export declare function renderMemoryBlock(memories: Memory[]): string | null;
19
- export declare function prepareCompartmentInjection(db: Database, sessionId: string, messages: MessageLike[], projectPath?: string, injectionBudgetTokens?: number): PreparedCompartmentInjection | null;
21
+ export declare function prepareCompartmentInjection(db: Database, sessionId: string, messages: MessageLike[], isCacheBusting: boolean, projectPath?: string, injectionBudgetTokens?: number): PreparedCompartmentInjection | null;
20
22
  export declare function renderCompartmentInjection(sessionId: string, messages: MessageLike[], prepared: PreparedCompartmentInjection): CompartmentInjectionResult;
21
23
  //# sourceMappingURL=inject-compartments.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inject-compartments.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/inject-compartments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAS3C,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,2CAA2C,CAAC;AAExF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,4BAA4B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACvC,QAAQ,EAAE,OAAO,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;CAClC;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CA6BnE;AA4CD,wBAAgB,2BAA2B,CACvC,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,EAAE,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,qBAAqB,CAAC,EAAE,MAAM,GAC/B,4BAA4B,GAAG,IAAI,CAgFrC;AAED,wBAAgB,0BAA0B,CACtC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,EAAE,EACvB,QAAQ,EAAE,4BAA4B,GACvC,0BAA0B,CAyB5B"}
1
+ {"version":3,"file":"inject-compartments.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/inject-compartments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAS3C,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,2CAA2C,CAAC;AAExF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,4BAA4B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB,EAAE,MAAM,CAAC;IAC9B,uBAAuB,EAAE,MAAM,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACvB;AAUD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE3D;AAED,MAAM,WAAW,0BAA0B;IACvC,QAAQ,EAAE,OAAO,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;CAClC;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CA6BnE;AA4CD,wBAAgB,2BAA2B,CACvC,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,EAAE,EACvB,cAAc,EAAE,OAAO,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,qBAAqB,CAAC,EAAE,MAAM,GAC/B,4BAA4B,GAAG,IAAI,CAwGrC;AAED,wBAAgB,0BAA0B,CACtC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,EAAE,EACvB,QAAQ,EAAE,4BAA4B,GACvC,0BAA0B,CAyB5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"transform-compartment-phase.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/transform-compartment-phase.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,eAAe,EAAqB,MAAM,sCAAsC,CAAC;AAC/F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMxD,OAAO,EACH,KAAK,4BAA4B,EAEpC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,UAAU,uBAAuB;IAC7B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE;QAAE,qBAAqB,EAAE,OAAO,CAAA;KAAE,CAAC;IAChD,YAAY,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,EAAE,EAAE,eAAe,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,2BAA2B,EAAE,4BAA4B,GAAG,IAAI,CAAC;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,OAAO,6BAA6B,EAAE,kBAAkB,CAAC;IACvF,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC;IAC9E,2BAA2B,EAAE,4BAA4B,GAAG,IAAI,CAAC;IACjE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,EAAE,OAAO,CAAC;CAClC,CAAC,CAiKD"}
1
+ {"version":3,"file":"transform-compartment-phase.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/transform-compartment-phase.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,eAAe,EAAqB,MAAM,sCAAsC,CAAC;AAC/F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMxD,OAAO,EACH,KAAK,4BAA4B,EAEpC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,UAAU,uBAAuB;IAC7B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE;QAAE,qBAAqB,EAAE,OAAO,CAAA;KAAE,CAAC;IAChD,YAAY,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,EAAE,EAAE,eAAe,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,2BAA2B,EAAE,4BAA4B,GAAG,IAAI,CAAC;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,OAAO,6BAA6B,EAAE,kBAAkB,CAAC;IACvF,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC;IAC9E,2BAA2B,EAAE,4BAA4B,GAAG,IAAI,CAAC;IACjE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,EAAE,OAAO,CAAC;CAClC,CAAC,CAkKD"}
@@ -1 +1 @@
1
- {"version":3,"file":"transform-postprocess-phase.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/transform-postprocess-phase.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,eAAe,EAIpB,aAAa,EAGhB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAOhF,OAAO,EACH,KAAK,4BAA4B,EAEpC,MAAM,uBAAuB,CAAC;AAM/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAa7C,OAAO,EAEH,KAAK,WAAW,EAGnB,MAAM,wBAAwB,CAAC;AAGhC,UAAU,yBAAyB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,eAAe,CAAC;IACpB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE,CAAC,CAAC;IACnE,kBAAkB,EAAE,GAAG,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;IAC3F,iBAAiB,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC5C,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACvC,YAAY,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,iBAAiB,EAAE,SAAS,GAAG,OAAO,CAAC;IACvC,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,mBAAmB,CAAC;IACrC,MAAM,EAAE,CACJ,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EACzD,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,OAAO,aAAa,EAC5B,aAAa,CAAC,EAAE,QAAQ,EAAE,EAC1B,qBAAqB,CAAC,EAAE,MAAM,EAC9B,oBAAoB,CAAC,EAAE,WAAW,KACjC,YAAY,GAAG,IAAI,CAAC;IACzB,2BAA2B,EAAE,4BAA4B,GAAG,IAAI,CAAC;IACjE,4BAA4B,EAAE,OAAO,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B,EAAE,MAAM,CAAC;IACvC,mBAAmB,EAAE,OAAO,CAAC;CAChC;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,CAgS3E"}
1
+ {"version":3,"file":"transform-postprocess-phase.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/transform-postprocess-phase.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,eAAe,EAIpB,aAAa,EAGhB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAOhF,OAAO,EACH,KAAK,4BAA4B,EAEpC,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAa7C,OAAO,EAEH,KAAK,WAAW,EAGnB,MAAM,wBAAwB,CAAC;AAGhC,UAAU,yBAAyB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,eAAe,CAAC;IACpB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE,CAAC,CAAC;IACnE,kBAAkB,EAAE,GAAG,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;IAC3F,iBAAiB,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC5C,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACvC,YAAY,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,iBAAiB,EAAE,SAAS,GAAG,OAAO,CAAC;IACvC,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,mBAAmB,CAAC;IACrC,MAAM,EAAE,CACJ,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EACzD,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,OAAO,aAAa,EAC5B,aAAa,CAAC,EAAE,QAAQ,EAAE,EAC1B,qBAAqB,CAAC,EAAE,MAAM,EAC9B,oBAAoB,CAAC,EAAE,WAAW,KACjC,YAAY,GAAG,IAAI,CAAC;IACzB,2BAA2B,EAAE,4BAA4B,GAAG,IAAI,CAAC;IACjE,4BAA4B,EAAE,OAAO,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B,EAAE,MAAM,CAAC;IACvC,mBAAmB,EAAE,OAAO,CAAC;CAChC;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,CAiT3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/transform.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAExE,OAAO,EACH,KAAK,eAAe,EAGpB,KAAK,aAAa,EACrB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAQxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAc7C,OAAO,EAAE,yBAAyB,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9F,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,YAAY,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzE,MAAM,EAAE,CACJ,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,OAAO,aAAa,EAC5B,aAAa,CAAC,EAAE,QAAQ,EAAE,EAC1B,qBAAqB,CAAC,EAAE,MAAM,EAC9B,oBAAoB,CAAC,EAAE,OAAO,oCAAoC,EAAE,WAAW,KAC9E,YAAY,GAAG,IAAI,CAAC;IACzB,EAAE,EAAE,eAAe,CAAC;IACpB,eAAe,EAAE,mBAAmB,CAAC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,qBAAqB,EAAE,MAAM,CAAC;KACjC,CAAC;IACF,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,CACpB,SAAS,EAAE,MAAM,KAChB,OAAO,6BAA6B,EAAE,kBAAkB,CAAC;CACjE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,IAE3C,QAAQ,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAC7B,QAAQ;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,KAChC,OAAO,CAAC,IAAI,CAAC,CA4MnB"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/transform.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAExE,OAAO,EACH,KAAK,eAAe,EAGpB,KAAK,aAAa,EACrB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAQxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAc7C,OAAO,EAAE,yBAAyB,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9F,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,YAAY,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzE,MAAM,EAAE,CACJ,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,OAAO,aAAa,EAC5B,aAAa,CAAC,EAAE,QAAQ,EAAE,EAC1B,qBAAqB,CAAC,EAAE,MAAM,EAC9B,oBAAoB,CAAC,EAAE,OAAO,oCAAoC,EAAE,WAAW,KAC9E,YAAY,GAAG,IAAI,CAAC;IACzB,EAAE,EAAE,eAAe,CAAC;IACpB,eAAe,EAAE,mBAAmB,CAAC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,qBAAqB,EAAE,MAAM,CAAC;KACjC,CAAC;IACF,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,CACpB,SAAS,EAAE,MAAM,KAChB,OAAO,6BAA6B,EAAE,kBAAkB,CAAC;CACjE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,IAE3C,QAAQ,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAC7B,QAAQ;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,KAChC,OAAO,CAAC,IAAI,CAAC,CAoNnB"}
package/dist/index.js CHANGED
@@ -17287,187 +17287,6 @@ function createEventHandler2(deps) {
17287
17287
  };
17288
17288
  }
17289
17289
 
17290
- // src/hooks/magic-context/nudger.ts
17291
- var RECENT_CTX_REDUCE_WINDOW_MS = 2 * 60 * 1000;
17292
- function formatLargestTags(tags) {
17293
- if (tags.length === 0) {
17294
- return "none";
17295
- }
17296
- return tags.map((tag) => `\xA7${tag.tagNumber}\xA7`).join(", ");
17297
- }
17298
- function formatOldToolTags(activeTags, protectedCount, count) {
17299
- const sortedByNumber = [...activeTags].sort((a, b) => a.tagNumber - b.tagNumber);
17300
- const protectedThreshold = protectedCount > 0 && sortedByNumber.length > protectedCount ? sortedByNumber[sortedByNumber.length - protectedCount].tagNumber : Infinity;
17301
- const midpoint = Math.floor(sortedByNumber.length / 2);
17302
- const earlyHalf = sortedByNumber.slice(0, midpoint);
17303
- const earlyToolTags = earlyHalf.filter((t) => t.type === "tool" && t.tagNumber < protectedThreshold);
17304
- if (earlyToolTags.length === 0)
17305
- return "";
17306
- const selected = earlyToolTags.sort((a, b) => b.byteSize - a.byteSize).slice(0, count);
17307
- const formatted = selected.sort((a, b) => a.tagNumber - b.tagNumber).map((t) => `\xA7${t.tagNumber}\xA7(${formatBytes(t.byteSize)})`).join(", ");
17308
- return ` Old tool outputs worth dropping: ${formatted}`;
17309
- }
17310
- function createNudger(config2) {
17311
- const lastReduceAtBySession = config2.recentReduceBySession ?? new Map;
17312
- return (sessionId, contextUsage, db, topNFn, preloadedTags, messagesSinceLastUser, preloadedSessionMeta) => {
17313
- const sessionMeta = preloadedSessionMeta ?? getOrCreateSessionMeta(db, sessionId);
17314
- const now = config2.now?.() ?? Date.now();
17315
- const lastReduceAt = lastReduceAtBySession.get(sessionId);
17316
- if (lastReduceAt !== undefined && now - lastReduceAt > RECENT_CTX_REDUCE_WINDOW_MS) {
17317
- lastReduceAtBySession.delete(sessionId);
17318
- }
17319
- if (contextUsage.inputTokens < sessionMeta.lastNudgeTokens) {
17320
- sessionMeta.lastNudgeTokens = contextUsage.inputTokens;
17321
- updateSessionMeta(db, sessionId, { lastNudgeTokens: contextUsage.inputTokens });
17322
- }
17323
- if (lastReduceAt !== undefined && now - lastReduceAt <= RECENT_CTX_REDUCE_WINDOW_MS) {
17324
- sessionLog(sessionId, `nudge: suppressed at ${contextUsage.percentage.toFixed(1)}% because ctx_reduce ran recently (${now - lastReduceAt}ms ago)`);
17325
- return null;
17326
- }
17327
- const projectedPercentage = estimateProjectedPercentage(db, sessionId, contextUsage, preloadedTags);
17328
- const executeThreshold = resolveExecuteThreshold(config2.execute_threshold_percentage, undefined, 65);
17329
- const currentBand = getRollingNudgeBand(contextUsage.percentage, executeThreshold);
17330
- const currentInterval = getRollingNudgeIntervalTokens(config2.nudge_interval_tokens, currentBand);
17331
- const lastBand = sessionMeta.lastNudgeBand;
17332
- if (getRollingNudgeBandPriority(currentBand) < getRollingNudgeBandPriority(lastBand)) {
17333
- sessionMeta.lastNudgeBand = currentBand;
17334
- updateSessionMeta(db, sessionId, { lastNudgeBand: currentBand });
17335
- }
17336
- const largest = formatLargestTags(topNFn(db, sessionId, 3));
17337
- const protectedCount = config2.protected_tags;
17338
- const activeTags = (preloadedTags ?? getTagsBySession(db, sessionId)).filter((t) => t.status === "active");
17339
- const highestProtected = activeTags.map((t) => t.tagNumber).sort((a, b) => b - a).slice(0, protectedCount)[0];
17340
- const protectedHint = highestProtected ? ` Tags \xA7${highestProtected}\xA7 and above are protected (last ${protectedCount}) \u2014 You MUST NOT try to reduce those.` : "";
17341
- const oldToolHint = formatOldToolTags(activeTags, protectedCount, 5);
17342
- const iterationThreshold = config2.iteration_nudge_threshold;
17343
- if (messagesSinceLastUser !== undefined && messagesSinceLastUser >= iterationThreshold && contextUsage.percentage >= 35 && contextUsage.percentage < executeThreshold && contextUsage.inputTokens - sessionMeta.lastNudgeTokens >= currentInterval) {
17344
- sessionLog(sessionId, `nudge fired: iteration_nudge at ${contextUsage.percentage.toFixed(1)}% (${messagesSinceLastUser} messages since user, interval: ${contextUsage.inputTokens - sessionMeta.lastNudgeTokens}/${currentInterval} tokens)`);
17345
- updateSessionMeta(db, sessionId, { lastNudgeTokens: contextUsage.inputTokens });
17346
- return {
17347
- type: "assistant",
17348
- text: [
17349
- `
17350
-
17351
- <instruction name="context_iteration">`,
17352
- `CONTEXT ITERATION NOTICE \u2014 ~${Math.round(contextUsage.percentage)}%`,
17353
- `You have been executing ${messagesSinceLastUser}+ tool calls without clearing old context.`,
17354
- `Consider using \`ctx_reduce\` to drop old tool outputs you have already processed.`,
17355
- ``,
17356
- `Largest: ${largest}.${oldToolHint}${protectedHint}`,
17357
- `Tags are marked with \xA7N\xA7 identifiers (e.g., \xA71\xA7, \xA742\xA7).`,
17358
- ``,
17359
- `Actions:`,
17360
- `- drop: Remove content entirely. Best for old tool outputs you already acted on.`,
17361
- `- Syntax: "3-5", "1,2,9", or "1-5,8,12-15" (bare integers).`,
17362
- `- Only drop what you have already processed. NEVER drop large ranges blindly.`,
17363
- `</instruction>`
17364
- ].join(`
17365
- `)
17366
- };
17367
- }
17368
- const intervalReached = contextUsage.inputTokens - sessionMeta.lastNudgeTokens >= currentInterval;
17369
- const bandEscalated = lastBand !== null && getRollingNudgeBandPriority(currentBand) > getRollingNudgeBandPriority(lastBand);
17370
- if (bandEscalated || intervalReached) {
17371
- const reason = bandEscalated ? `band escalation (${formatRollingNudgeBand(lastBand)} -> ${currentBand})` : `interval ${contextUsage.inputTokens - sessionMeta.lastNudgeTokens}/${currentInterval} tokens`;
17372
- sessionLog(sessionId, `nudge fired: rolling_${currentBand} at ${contextUsage.percentage.toFixed(1)}% (${reason})`);
17373
- updateSessionMeta(db, sessionId, {
17374
- lastNudgeTokens: contextUsage.inputTokens,
17375
- lastNudgeBand: currentBand
17376
- });
17377
- return {
17378
- type: "assistant",
17379
- text: buildRollingNudgeText(currentBand, contextUsage.percentage, largest, oldToolHint, protectedHint)
17380
- };
17381
- }
17382
- sessionLog(sessionId, `nudge: none fired at ${contextUsage.percentage.toFixed(1)}% (band=${currentBand} lastBand=${formatRollingNudgeBand(lastBand)} lastNudge=${sessionMeta.lastNudgeTokens} current=${contextUsage.inputTokens} interval=${currentInterval} projected=${projectedPercentage?.toFixed(1) ?? "none"})`);
17383
- return null;
17384
- };
17385
- }
17386
- function buildRollingNudgeText(band, percentage, largest, oldToolHint, protectedHint) {
17387
- const titleByBand = {
17388
- far: "CONTEXT REMINDER",
17389
- near: "CONTEXT WARNING",
17390
- urgent: "CONTEXT URGENT",
17391
- critical: "CONTEXT CRITICAL"
17392
- };
17393
- const instructionByBand = {
17394
- far: "You should use `ctx_reduce` to drop old tool outputs before continuing.",
17395
- near: "You should call `ctx_reduce` soon to free space before more heavy reads or tool output.",
17396
- urgent: "You should call `ctx_reduce` before doing more reads or tool-heavy work.",
17397
- critical: "You MUST call `ctx_reduce` RIGHT NOW before doing ANYTHING else."
17398
- };
17399
- const cautionByBand = {
17400
- far: "- Only drop what you have already processed. NEVER drop large ranges blindly.",
17401
- near: "- Review what each tag contains. Drop processed outputs, keep anything you might need soon.",
17402
- urgent: "- Review each tag before deciding. Avoid broad drops that could remove active context.",
17403
- critical: '- NEVER drop large ranges blindly (e.g., "1-50"). Review each tag before deciding.'
17404
- };
17405
- return [
17406
- `
17407
-
17408
- <instruction name="context_${band}">`,
17409
- `${titleByBand[band]} \u2014 ~${Math.round(percentage)}%`,
17410
- instructionByBand[band],
17411
- ``,
17412
- `Largest: ${largest}.${oldToolHint}${protectedHint}`,
17413
- `Tags are marked with \xA7N\xA7 identifiers (e.g., \xA71\xA7, \xA742\xA7).`,
17414
- ``,
17415
- `Actions:`,
17416
- `- drop: Remove content entirely. Best for old tool outputs you already acted on.`,
17417
- `- Syntax: "3-5", "1,2,9", or "1-5,8,12-15" (bare integers).`,
17418
- cautionByBand[band],
17419
- `</instruction>`
17420
- ].join(`
17421
- `);
17422
- }
17423
- function estimateProjectedPercentage(db, sessionId, contextUsage, preloadedTags) {
17424
- const pendingOps = getPendingOps(db, sessionId);
17425
- const pendingDrops = pendingOps.filter((op) => op.operation === "drop");
17426
- if (pendingDrops.length === 0) {
17427
- return null;
17428
- }
17429
- const activeTags = (preloadedTags ?? getTagsBySession(db, sessionId)).filter((t) => t.status === "active");
17430
- const totalActiveBytes = activeTags.reduce((sum, t) => sum + t.byteSize, 0);
17431
- if (totalActiveBytes === 0) {
17432
- return null;
17433
- }
17434
- const pendingDropTagIds = new Set(pendingDrops.map((op) => op.tagId));
17435
- const pendingDropBytes = activeTags.filter((t) => pendingDropTagIds.has(t.tagNumber)).reduce((sum, t) => sum + t.byteSize, 0);
17436
- const dropRatio = pendingDropBytes / totalActiveBytes;
17437
- return contextUsage.percentage * (1 - dropRatio);
17438
- }
17439
- function generateEmergencyNudgeText(db, sessionId, contextUsage, config2) {
17440
- const largest = formatLargestTags(getTopNBySize(db, sessionId, 3));
17441
- const protectedCount = config2.protected_tags;
17442
- const activeTags = getTagsBySession(db, sessionId).filter((t) => t.status === "active");
17443
- const highestProtected = activeTags.map((t) => t.tagNumber).sort((a, b) => b - a).slice(0, protectedCount)[0];
17444
- const protectedHint = highestProtected ? ` Tags \xA7${highestProtected}\xA7 and above are protected (last ${protectedCount}) \u2014 You MUST NOT try to reduce those.` : "";
17445
- const oldToolHint = formatOldToolTags(activeTags, protectedCount, 5);
17446
- return [
17447
- `<instruction name="context_emergency">`,
17448
- `CONTEXT EMERGENCY \u2014 ~${Math.round(contextUsage.percentage)}%. STOP all current work immediately.`,
17449
- ``,
17450
- `You MUST use \`ctx_reduce\` RIGHT NOW to free space. If context overflows, you lose all work.`,
17451
- ``,
17452
- `Steps:`,
17453
- `1. Find OLD tool outputs (grep results, file reads, build logs) you already processed \u2014 look at \xA7N\xA7 tags`,
17454
- `2. Drop those specifically: e.g. drop="3,7,12" \u2014 NEVER drop large ranges like "1-50"`,
17455
- `3. KEEP anything related to current task, recent errors, or decisions`,
17456
- ``,
17457
- `Largest tags: ${largest}.${oldToolHint}${protectedHint}`,
17458
- `</instruction>`
17459
- ].join(`
17460
- `);
17461
- }
17462
-
17463
- // src/hooks/magic-context/text-complete.ts
17464
- var TAG_PREFIX_REGEX2 = /^(\u00a7\d+\u00a7\s*)+/;
17465
- function createTextCompleteHandler() {
17466
- return async (_input, output) => {
17467
- output.text = output.text.replace(TAG_PREFIX_REGEX2, "");
17468
- };
17469
- }
17470
-
17471
17290
  // src/features/magic-context/memory/constants.ts
17472
17291
  var PROMOTABLE_CATEGORIES = [
17473
17292
  "ARCHITECTURE_DECISIONS",
@@ -17809,6 +17628,10 @@ function archiveMemory(db, id, reason) {
17809
17628
  }
17810
17629
 
17811
17630
  // src/hooks/magic-context/inject-compartments.ts
17631
+ var injectionCache = new Map;
17632
+ function clearInjectionCache(sessionId) {
17633
+ injectionCache.delete(sessionId);
17634
+ }
17812
17635
  function renderMemoryBlock(memories) {
17813
17636
  const byCategory = new Map;
17814
17637
  for (const m of memories) {
@@ -17859,19 +17682,31 @@ function trimMemoriesToBudget(sessionId, memories, budgetTokens) {
17859
17682
  }
17860
17683
  return result;
17861
17684
  }
17862
- function prepareCompartmentInjection(db, sessionId, messages, projectPath, injectionBudgetTokens) {
17685
+ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, projectPath, injectionBudgetTokens) {
17686
+ const cached2 = injectionCache.get(sessionId);
17687
+ if (!isCacheBusting && cached2) {
17688
+ if (cached2.compartmentEndMessageId.length > 0) {
17689
+ const cutoffIndex2 = messages.findIndex((message) => message.info.id === cached2.compartmentEndMessageId);
17690
+ if (cutoffIndex2 >= 0) {
17691
+ const remaining = messages.slice(cutoffIndex2 + 1);
17692
+ messages.splice(0, messages.length, ...remaining);
17693
+ }
17694
+ }
17695
+ return cached2;
17696
+ }
17863
17697
  const compartments = getCompartments(db, sessionId);
17864
17698
  if (compartments.length === 0) {
17699
+ injectionCache.delete(sessionId);
17865
17700
  return null;
17866
17701
  }
17867
17702
  const facts = getSessionFacts(db, sessionId);
17868
17703
  let memoryBlock;
17869
17704
  let memoryCount = 0;
17870
17705
  if (projectPath) {
17871
- const cached2 = db.prepare("SELECT memory_block_cache, memory_block_count FROM session_meta WHERE session_id = ?").get(sessionId);
17872
- if (cached2?.memory_block_cache) {
17873
- memoryBlock = cached2.memory_block_cache;
17874
- memoryCount = cached2.memory_block_count;
17706
+ const cachedMemory = db.prepare("SELECT memory_block_cache, memory_block_count FROM session_meta WHERE session_id = ?").get(sessionId);
17707
+ if (cachedMemory?.memory_block_cache) {
17708
+ memoryBlock = cachedMemory.memory_block_cache;
17709
+ memoryCount = cachedMemory.memory_block_count;
17875
17710
  } else {
17876
17711
  let memories = getMemoriesByProject(db, projectPath, ["active", "permanent"]);
17877
17712
  if (injectionBudgetTokens && memories.length > 0) {
@@ -17891,14 +17726,17 @@ function prepareCompartmentInjection(db, sessionId, messages, projectPath, injec
17891
17726
  compartmentCount: compartments.length,
17892
17727
  compartmentEndMessage: lastEnd
17893
17728
  });
17894
- return {
17729
+ const result2 = {
17895
17730
  block,
17896
17731
  compartmentEndMessage: lastEnd,
17732
+ compartmentEndMessageId: "",
17897
17733
  compartmentCount: compartments.length,
17898
17734
  skippedVisibleMessages: 0,
17899
17735
  factCount: facts.length,
17900
17736
  memoryCount
17901
17737
  };
17738
+ injectionCache.set(sessionId, result2);
17739
+ return result2;
17902
17740
  }
17903
17741
  let skippedVisibleMessages = 0;
17904
17742
  const cutoffIndex = messages.findIndex((message) => message.info.id === lastEndMessageId);
@@ -17907,14 +17745,17 @@ function prepareCompartmentInjection(db, sessionId, messages, projectPath, injec
17907
17745
  const remaining = messages.slice(cutoffIndex + 1);
17908
17746
  messages.splice(0, messages.length, ...remaining);
17909
17747
  }
17910
- return {
17748
+ const result = {
17911
17749
  block,
17912
17750
  compartmentEndMessage: lastEnd,
17751
+ compartmentEndMessageId: lastEndMessageId,
17913
17752
  compartmentCount: compartments.length,
17914
17753
  skippedVisibleMessages,
17915
17754
  factCount: facts.length,
17916
17755
  memoryCount
17917
17756
  };
17757
+ injectionCache.set(sessionId, result);
17758
+ return result;
17918
17759
  }
17919
17760
  function renderCompartmentInjection(sessionId, messages, prepared) {
17920
17761
  const historyBlock = `<session-history>
@@ -17956,6 +17797,187 @@ function isDroppedPlaceholder(text) {
17956
17797
  return /^\[dropped \u00A7\d+\u00A7\]$/.test(text.trim());
17957
17798
  }
17958
17799
 
17800
+ // src/hooks/magic-context/nudger.ts
17801
+ var RECENT_CTX_REDUCE_WINDOW_MS = 2 * 60 * 1000;
17802
+ function formatLargestTags(tags) {
17803
+ if (tags.length === 0) {
17804
+ return "none";
17805
+ }
17806
+ return tags.map((tag) => `\xA7${tag.tagNumber}\xA7`).join(", ");
17807
+ }
17808
+ function formatOldToolTags(activeTags, protectedCount, count) {
17809
+ const sortedByNumber = [...activeTags].sort((a, b) => a.tagNumber - b.tagNumber);
17810
+ const protectedThreshold = protectedCount > 0 && sortedByNumber.length > protectedCount ? sortedByNumber[sortedByNumber.length - protectedCount].tagNumber : Infinity;
17811
+ const midpoint = Math.floor(sortedByNumber.length / 2);
17812
+ const earlyHalf = sortedByNumber.slice(0, midpoint);
17813
+ const earlyToolTags = earlyHalf.filter((t) => t.type === "tool" && t.tagNumber < protectedThreshold);
17814
+ if (earlyToolTags.length === 0)
17815
+ return "";
17816
+ const selected = earlyToolTags.sort((a, b) => b.byteSize - a.byteSize).slice(0, count);
17817
+ const formatted = selected.sort((a, b) => a.tagNumber - b.tagNumber).map((t) => `\xA7${t.tagNumber}\xA7(${formatBytes(t.byteSize)})`).join(", ");
17818
+ return ` Old tool outputs worth dropping: ${formatted}`;
17819
+ }
17820
+ function createNudger(config2) {
17821
+ const lastReduceAtBySession = config2.recentReduceBySession ?? new Map;
17822
+ return (sessionId, contextUsage, db, topNFn, preloadedTags, messagesSinceLastUser, preloadedSessionMeta) => {
17823
+ const sessionMeta = preloadedSessionMeta ?? getOrCreateSessionMeta(db, sessionId);
17824
+ const now = config2.now?.() ?? Date.now();
17825
+ const lastReduceAt = lastReduceAtBySession.get(sessionId);
17826
+ if (lastReduceAt !== undefined && now - lastReduceAt > RECENT_CTX_REDUCE_WINDOW_MS) {
17827
+ lastReduceAtBySession.delete(sessionId);
17828
+ }
17829
+ if (contextUsage.inputTokens < sessionMeta.lastNudgeTokens) {
17830
+ sessionMeta.lastNudgeTokens = contextUsage.inputTokens;
17831
+ updateSessionMeta(db, sessionId, { lastNudgeTokens: contextUsage.inputTokens });
17832
+ }
17833
+ if (lastReduceAt !== undefined && now - lastReduceAt <= RECENT_CTX_REDUCE_WINDOW_MS) {
17834
+ sessionLog(sessionId, `nudge: suppressed at ${contextUsage.percentage.toFixed(1)}% because ctx_reduce ran recently (${now - lastReduceAt}ms ago)`);
17835
+ return null;
17836
+ }
17837
+ const projectedPercentage = estimateProjectedPercentage(db, sessionId, contextUsage, preloadedTags);
17838
+ const executeThreshold = resolveExecuteThreshold(config2.execute_threshold_percentage, undefined, 65);
17839
+ const currentBand = getRollingNudgeBand(contextUsage.percentage, executeThreshold);
17840
+ const currentInterval = getRollingNudgeIntervalTokens(config2.nudge_interval_tokens, currentBand);
17841
+ const lastBand = sessionMeta.lastNudgeBand;
17842
+ if (getRollingNudgeBandPriority(currentBand) < getRollingNudgeBandPriority(lastBand)) {
17843
+ sessionMeta.lastNudgeBand = currentBand;
17844
+ updateSessionMeta(db, sessionId, { lastNudgeBand: currentBand });
17845
+ }
17846
+ const largest = formatLargestTags(topNFn(db, sessionId, 3));
17847
+ const protectedCount = config2.protected_tags;
17848
+ const activeTags = (preloadedTags ?? getTagsBySession(db, sessionId)).filter((t) => t.status === "active");
17849
+ const highestProtected = activeTags.map((t) => t.tagNumber).sort((a, b) => b - a).slice(0, protectedCount)[0];
17850
+ const protectedHint = highestProtected ? ` Tags \xA7${highestProtected}\xA7 and above are protected (last ${protectedCount}) \u2014 You MUST NOT try to reduce those.` : "";
17851
+ const oldToolHint = formatOldToolTags(activeTags, protectedCount, 5);
17852
+ const iterationThreshold = config2.iteration_nudge_threshold;
17853
+ if (messagesSinceLastUser !== undefined && messagesSinceLastUser >= iterationThreshold && contextUsage.percentage >= 35 && contextUsage.percentage < executeThreshold && contextUsage.inputTokens - sessionMeta.lastNudgeTokens >= currentInterval) {
17854
+ sessionLog(sessionId, `nudge fired: iteration_nudge at ${contextUsage.percentage.toFixed(1)}% (${messagesSinceLastUser} messages since user, interval: ${contextUsage.inputTokens - sessionMeta.lastNudgeTokens}/${currentInterval} tokens)`);
17855
+ updateSessionMeta(db, sessionId, { lastNudgeTokens: contextUsage.inputTokens });
17856
+ return {
17857
+ type: "assistant",
17858
+ text: [
17859
+ `
17860
+
17861
+ <instruction name="context_iteration">`,
17862
+ `CONTEXT ITERATION NOTICE \u2014 ~${Math.round(contextUsage.percentage)}%`,
17863
+ `You have been executing ${messagesSinceLastUser}+ tool calls without clearing old context.`,
17864
+ `Consider using \`ctx_reduce\` to drop old tool outputs you have already processed.`,
17865
+ ``,
17866
+ `Largest: ${largest}.${oldToolHint}${protectedHint}`,
17867
+ `Tags are marked with \xA7N\xA7 identifiers (e.g., \xA71\xA7, \xA742\xA7).`,
17868
+ ``,
17869
+ `Actions:`,
17870
+ `- drop: Remove content entirely. Best for old tool outputs you already acted on.`,
17871
+ `- Syntax: "3-5", "1,2,9", or "1-5,8,12-15" (bare integers).`,
17872
+ `- Only drop what you have already processed. NEVER drop large ranges blindly.`,
17873
+ `</instruction>`
17874
+ ].join(`
17875
+ `)
17876
+ };
17877
+ }
17878
+ const intervalReached = contextUsage.inputTokens - sessionMeta.lastNudgeTokens >= currentInterval;
17879
+ const bandEscalated = lastBand !== null && getRollingNudgeBandPriority(currentBand) > getRollingNudgeBandPriority(lastBand);
17880
+ if (bandEscalated || intervalReached) {
17881
+ const reason = bandEscalated ? `band escalation (${formatRollingNudgeBand(lastBand)} -> ${currentBand})` : `interval ${contextUsage.inputTokens - sessionMeta.lastNudgeTokens}/${currentInterval} tokens`;
17882
+ sessionLog(sessionId, `nudge fired: rolling_${currentBand} at ${contextUsage.percentage.toFixed(1)}% (${reason})`);
17883
+ updateSessionMeta(db, sessionId, {
17884
+ lastNudgeTokens: contextUsage.inputTokens,
17885
+ lastNudgeBand: currentBand
17886
+ });
17887
+ return {
17888
+ type: "assistant",
17889
+ text: buildRollingNudgeText(currentBand, contextUsage.percentage, largest, oldToolHint, protectedHint)
17890
+ };
17891
+ }
17892
+ sessionLog(sessionId, `nudge: none fired at ${contextUsage.percentage.toFixed(1)}% (band=${currentBand} lastBand=${formatRollingNudgeBand(lastBand)} lastNudge=${sessionMeta.lastNudgeTokens} current=${contextUsage.inputTokens} interval=${currentInterval} projected=${projectedPercentage?.toFixed(1) ?? "none"})`);
17893
+ return null;
17894
+ };
17895
+ }
17896
+ function buildRollingNudgeText(band, percentage, largest, oldToolHint, protectedHint) {
17897
+ const titleByBand = {
17898
+ far: "CONTEXT REMINDER",
17899
+ near: "CONTEXT WARNING",
17900
+ urgent: "CONTEXT URGENT",
17901
+ critical: "CONTEXT CRITICAL"
17902
+ };
17903
+ const instructionByBand = {
17904
+ far: "You should use `ctx_reduce` to drop old tool outputs before continuing.",
17905
+ near: "You should call `ctx_reduce` soon to free space before more heavy reads or tool output.",
17906
+ urgent: "You should call `ctx_reduce` before doing more reads or tool-heavy work.",
17907
+ critical: "You MUST call `ctx_reduce` RIGHT NOW before doing ANYTHING else."
17908
+ };
17909
+ const cautionByBand = {
17910
+ far: "- Only drop what you have already processed. NEVER drop large ranges blindly.",
17911
+ near: "- Review what each tag contains. Drop processed outputs, keep anything you might need soon.",
17912
+ urgent: "- Review each tag before deciding. Avoid broad drops that could remove active context.",
17913
+ critical: '- NEVER drop large ranges blindly (e.g., "1-50"). Review each tag before deciding.'
17914
+ };
17915
+ return [
17916
+ `
17917
+
17918
+ <instruction name="context_${band}">`,
17919
+ `${titleByBand[band]} \u2014 ~${Math.round(percentage)}%`,
17920
+ instructionByBand[band],
17921
+ ``,
17922
+ `Largest: ${largest}.${oldToolHint}${protectedHint}`,
17923
+ `Tags are marked with \xA7N\xA7 identifiers (e.g., \xA71\xA7, \xA742\xA7).`,
17924
+ ``,
17925
+ `Actions:`,
17926
+ `- drop: Remove content entirely. Best for old tool outputs you already acted on.`,
17927
+ `- Syntax: "3-5", "1,2,9", or "1-5,8,12-15" (bare integers).`,
17928
+ cautionByBand[band],
17929
+ `</instruction>`
17930
+ ].join(`
17931
+ `);
17932
+ }
17933
+ function estimateProjectedPercentage(db, sessionId, contextUsage, preloadedTags) {
17934
+ const pendingOps = getPendingOps(db, sessionId);
17935
+ const pendingDrops = pendingOps.filter((op) => op.operation === "drop");
17936
+ if (pendingDrops.length === 0) {
17937
+ return null;
17938
+ }
17939
+ const activeTags = (preloadedTags ?? getTagsBySession(db, sessionId)).filter((t) => t.status === "active");
17940
+ const totalActiveBytes = activeTags.reduce((sum, t) => sum + t.byteSize, 0);
17941
+ if (totalActiveBytes === 0) {
17942
+ return null;
17943
+ }
17944
+ const pendingDropTagIds = new Set(pendingDrops.map((op) => op.tagId));
17945
+ const pendingDropBytes = activeTags.filter((t) => pendingDropTagIds.has(t.tagNumber)).reduce((sum, t) => sum + t.byteSize, 0);
17946
+ const dropRatio = pendingDropBytes / totalActiveBytes;
17947
+ return contextUsage.percentage * (1 - dropRatio);
17948
+ }
17949
+ function generateEmergencyNudgeText(db, sessionId, contextUsage, config2) {
17950
+ const largest = formatLargestTags(getTopNBySize(db, sessionId, 3));
17951
+ const protectedCount = config2.protected_tags;
17952
+ const activeTags = getTagsBySession(db, sessionId).filter((t) => t.status === "active");
17953
+ const highestProtected = activeTags.map((t) => t.tagNumber).sort((a, b) => b - a).slice(0, protectedCount)[0];
17954
+ const protectedHint = highestProtected ? ` Tags \xA7${highestProtected}\xA7 and above are protected (last ${protectedCount}) \u2014 You MUST NOT try to reduce those.` : "";
17955
+ const oldToolHint = formatOldToolTags(activeTags, protectedCount, 5);
17956
+ return [
17957
+ `<instruction name="context_emergency">`,
17958
+ `CONTEXT EMERGENCY \u2014 ~${Math.round(contextUsage.percentage)}%. STOP all current work immediately.`,
17959
+ ``,
17960
+ `You MUST use \`ctx_reduce\` RIGHT NOW to free space. If context overflows, you lose all work.`,
17961
+ ``,
17962
+ `Steps:`,
17963
+ `1. Find OLD tool outputs (grep results, file reads, build logs) you already processed \u2014 look at \xA7N\xA7 tags`,
17964
+ `2. Drop those specifically: e.g. drop="3,7,12" \u2014 NEVER drop large ranges like "1-50"`,
17965
+ `3. KEEP anything related to current task, recent errors, or decisions`,
17966
+ ``,
17967
+ `Largest tags: ${largest}.${oldToolHint}${protectedHint}`,
17968
+ `</instruction>`
17969
+ ].join(`
17970
+ `);
17971
+ }
17972
+
17973
+ // src/hooks/magic-context/text-complete.ts
17974
+ var TAG_PREFIX_REGEX2 = /^(\u00a7\d+\u00a7\s*)+/;
17975
+ function createTextCompleteHandler() {
17976
+ return async (_input, output) => {
17977
+ output.text = output.text.replace(TAG_PREFIX_REGEX2, "");
17978
+ };
17979
+ }
17980
+
17959
17981
  // src/hooks/magic-context/note-nudger.ts
17960
17982
  var stateBySession = new Map;
17961
17983
  function getState(sessionId) {
@@ -19724,7 +19746,7 @@ async function runCompartmentPhase(args) {
19724
19746
  sessionLog(args.sessionId, reason);
19725
19747
  await activeRun;
19726
19748
  sessionLog(args.sessionId, "transform: compartment agent completed, refreshing compartment coverage");
19727
- pendingCompartmentInjection = prepareCompartmentInjection(args.db, args.resolvedSessionId, args.messages, args.projectPath, args.injectionBudgetTokens);
19749
+ pendingCompartmentInjection = prepareCompartmentInjection(args.db, args.resolvedSessionId, args.messages, args.cacheAlreadyBusting ?? false, args.projectPath, args.injectionBudgetTokens);
19728
19750
  }
19729
19751
  if (args.canRunCompartments && args.sessionMeta.compartmentInProgress && !getActiveCompartmentRun(args.sessionId)) {
19730
19752
  if (!hasEligibleHistoryForCompartment()) {
@@ -20406,7 +20428,6 @@ function tagMessages(sessionId, messages, tagger, db) {
20406
20428
  }
20407
20429
  // src/hooks/magic-context/nudge-injection.ts
20408
20430
  var TRAILING_CONTEXT_NUDGE_PATTERN = /(?:\s*<instruction name="(?:context_[^"]+|deferred_notes)">[\s\S]*?<\/instruction>\s*)+$/;
20409
- var TRAILING_DEFERRED_NOTES_PATTERN = /(?:\s*<instruction name="deferred_notes">[\s\S]*?<\/instruction>\s*)+$/;
20410
20431
  function isToolProtocolPart(part) {
20411
20432
  if (part === null || typeof part !== "object")
20412
20433
  return false;
@@ -20428,12 +20449,6 @@ function stripTrailingExactNudge(text, nudgeText) {
20428
20449
  function stripTrailingContextNudges(text) {
20429
20450
  return text.replace(TRAILING_CONTEXT_NUDGE_PATTERN, "");
20430
20451
  }
20431
- function stripTrailingDeferredNotes(text) {
20432
- return text.replace(TRAILING_DEFERRED_NOTES_PATTERN, "");
20433
- }
20434
- function isAppendableAssistantMessage(message) {
20435
- return message.info.role === "assistant" && !hasToolProtocolParts(message) && !isMessageDropped(message);
20436
- }
20437
20452
  function mergeNudgeText(text, currentNudgeText, nextNudgeText) {
20438
20453
  const withoutCurrentNudge = stripTrailingExactNudge(text, currentNudgeText);
20439
20454
  const withoutManagedNudges = stripTrailingContextNudges(withoutCurrentNudge);
@@ -20511,40 +20526,6 @@ function appendNudgeToAssistant(messages, nudge, nudgePlacements, sessionId) {
20511
20526
  }
20512
20527
  sessionLog(sessionId, `nudge placement failed: no suitable assistant message found (${messages.length} messages)`);
20513
20528
  }
20514
- function appendSupplementalNudgeToAssistant(messages, nudge, nudgePlacements, sessionId) {
20515
- const appendToMessage = (message) => {
20516
- if (!isAppendableAssistantMessage(message))
20517
- return false;
20518
- for (let j = message.parts.length - 1;j >= 0; j--) {
20519
- const part = message.parts[j];
20520
- if (isTextPart(part)) {
20521
- const nextText = `${stripTrailingDeferredNotes(part.text)}${nudge}`;
20522
- if (nextText !== part.text) {
20523
- part.text = nextText;
20524
- }
20525
- return true;
20526
- }
20527
- }
20528
- message.parts.push({ type: "text", text: nudge });
20529
- return true;
20530
- };
20531
- const placement = nudgePlacements.get(sessionId);
20532
- if (!placement)
20533
- return false;
20534
- for (const message of messages) {
20535
- if (message.info.id !== placement.messageId)
20536
- continue;
20537
- return appendToMessage(message);
20538
- }
20539
- return false;
20540
- }
20541
- function canAppendSupplementalNudgeToAssistant(messages, nudgePlacements, sessionId) {
20542
- const placement = nudgePlacements.get(sessionId);
20543
- if (!placement)
20544
- return false;
20545
- const anchoredMessage = messages.find((message) => message.info.id === placement.messageId);
20546
- return anchoredMessage ? isAppendableAssistantMessage(anchoredMessage) : false;
20547
- }
20548
20529
 
20549
20530
  // src/hooks/magic-context/apply-context-nudge.ts
20550
20531
  function applyContextNudge(messages, nudge, nudgePlacements, sessionId) {
@@ -20789,6 +20770,7 @@ function runPostTransformPhase(args) {
20789
20770
  const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
20790
20771
  const hasPendingUserOps = pendingOps.length > 0;
20791
20772
  const shouldApplyPendingOps = (args.schedulerDecision === "execute" || isExplicitFlush) && !compartmentRunning;
20773
+ const isCacheBustingPass = isExplicitFlush || shouldApplyPendingOps;
20792
20774
  const shouldRunHeuristics = args.fullFeatureMode && !compartmentRunning && (isExplicitFlush || forceMaterialization || hasPendingUserOps && args.schedulerDecision === "execute" && !alreadyRanThisTurn);
20793
20775
  if (shouldRunHeuristics) {
20794
20776
  const reason = isExplicitFlush ? "explicit_flush" : forceMaterialization ? `force_materialization (${args.contextUsage.percentage.toFixed(1)}% >= ${args.forceMaterializationPercentage}%)` : `pending_ops_execute (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})`;
@@ -20854,9 +20836,10 @@ function runPostTransformPhase(args) {
20854
20836
  } catch (error48) {
20855
20837
  sessionLog(args.sessionId, "transform failed applying pending operations:", error48);
20856
20838
  updateSessionMeta(args.db, args.sessionId, { lastTransformError: getErrorMessage(error48) });
20857
- args.nudgePlacements.clear(args.sessionId);
20839
+ if (isCacheBustingPass)
20840
+ args.nudgePlacements.clear(args.sessionId);
20858
20841
  }
20859
- if (didMutateFromPendingOperations) {
20842
+ if (didMutateFromPendingOperations && isCacheBustingPass) {
20860
20843
  args.nudgePlacements.clear(args.sessionId);
20861
20844
  }
20862
20845
  if (shouldRunHeuristics && (args.didMutateFromFlushedStatuses || didMutateFromPendingOperations)) {
@@ -20878,16 +20861,18 @@ function runPostTransformPhase(args) {
20878
20861
  if (strippedDropped > 0) {
20879
20862
  sessionLog(args.sessionId, `stripped ${strippedDropped} empty dropped-placeholder messages`);
20880
20863
  }
20881
- const protectedTailStart = Math.max(0, args.messages.length - args.protectedTags * 2);
20882
- const strippedSystemInjected = stripSystemInjectedMessages(args.messages, protectedTailStart);
20883
- if (strippedSystemInjected > 0) {
20884
- sessionLog(args.sessionId, `stripped ${strippedSystemInjected} system-injected messages (notifications/reminders)`);
20864
+ if (isCacheBustingPass) {
20865
+ const protectedTailStart = Math.max(0, args.messages.length - args.protectedTags * 2);
20866
+ const strippedSystemInjected = stripSystemInjectedMessages(args.messages, protectedTailStart);
20867
+ if (strippedSystemInjected > 0) {
20868
+ sessionLog(args.sessionId, `stripped ${strippedSystemInjected} system-injected messages (notifications/reminders)`);
20869
+ }
20885
20870
  }
20886
20871
  const pendingUserTurnReminder = getPersistedStickyTurnReminder(args.db, args.sessionId);
20887
20872
  if (pendingUserTurnReminder) {
20888
- if (args.hasRecentReduceCall) {
20873
+ if (args.hasRecentReduceCall && isCacheBustingPass) {
20889
20874
  clearPersistedStickyTurnReminder(args.db, args.sessionId);
20890
- sessionLog(args.sessionId, "sticky turn reminder cleared \u2014 ctx_reduce found in recent messages");
20875
+ sessionLog(args.sessionId, "sticky turn reminder cleared \u2014 ctx_reduce found in recent messages (cache-busting pass)");
20891
20876
  } else {
20892
20877
  if (pendingUserTurnReminder.messageId) {
20893
20878
  const reinjected = appendReminderToUserMessageById(args.messages, pendingUserTurnReminder.messageId, pendingUserTurnReminder.text);
@@ -20914,15 +20899,20 @@ function runPostTransformPhase(args) {
20914
20899
  const t9 = performance.now();
20915
20900
  applyContextNudge(args.messages, nudge, args.nudgePlacements, args.sessionId);
20916
20901
  logTransformTiming(args.sessionId, "applyContextNudge", t9);
20917
- } else {
20902
+ } else if (isCacheBustingPass) {
20918
20903
  args.nudgePlacements.clear(args.sessionId);
20904
+ } else {
20905
+ const existing = args.nudgePlacements.get(args.sessionId);
20906
+ if (existing) {
20907
+ reinjectNudgeAtAnchor(args.messages, existing.nudgeText, args.nudgePlacements, args.sessionId);
20908
+ }
20919
20909
  }
20920
- const canInjectDeferredNoteNudge = canAppendSupplementalNudgeToAssistant(args.messages, args.nudgePlacements, args.sessionId);
20921
20910
  const deferredNoteText = getNoteNudgeText(args.db, args.sessionId);
20922
- if (deferredNoteText && canInjectDeferredNoteNudge) {
20923
- appendSupplementalNudgeToAssistant(args.messages, `
20911
+ if (deferredNoteText) {
20912
+ const noteInstruction = `
20924
20913
 
20925
- <instruction name="deferred_notes">${deferredNoteText}</instruction>`, args.nudgePlacements, args.sessionId);
20914
+ <instruction name="deferred_notes">${deferredNoteText}</instruction>`;
20915
+ appendReminderToLatestUserMessage(args.messages, noteInstruction);
20926
20916
  }
20927
20917
  } else {
20928
20918
  args.nudgePlacements.clear(args.sessionId);
@@ -20989,10 +20979,13 @@ function createTransform(deps) {
20989
20979
  const fullFeatureMode = !reducedMode;
20990
20980
  const compartmentDirectory = deps.directory ?? "";
20991
20981
  const canRunCompartments = fullFeatureMode && deps.client !== undefined && compartmentDirectory.length > 0;
20982
+ const contextUsageEarly = loadContextUsage(deps.contextUsageMap, db, sessionId);
20983
+ const schedulerDecisionEarly = resolveSchedulerDecision(deps.scheduler, sessionMeta, contextUsageEarly, sessionId);
20984
+ const isCacheBusting = deps.flushedSessions.has(sessionId) || schedulerDecisionEarly === "execute";
20992
20985
  let pendingCompartmentInjection = null;
20993
20986
  if (fullFeatureMode) {
20994
20987
  const projectPath = deps.memoryConfig?.enabled ? resolveProjectIdentity(deps.directory ?? process.cwd()) : undefined;
20995
- pendingCompartmentInjection = prepareCompartmentInjection(db, sessionId, messages, projectPath, deps.memoryConfig?.injectionBudgetTokens);
20988
+ pendingCompartmentInjection = prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, projectPath, deps.memoryConfig?.injectionBudgetTokens);
20996
20989
  }
20997
20990
  let targets = new Map;
20998
20991
  let reasoningByMessage = new Map;
@@ -21029,9 +21022,10 @@ function createTransform(deps) {
21029
21022
  logTransformTiming(sessionId, "batchFinalize:flushed", t2);
21030
21023
  } catch (error48) {
21031
21024
  sessionLog(sessionId, "transform failed applying flushed statuses:", error48);
21032
- deps.nudgePlacements.clear(sessionId);
21025
+ if (isCacheBusting)
21026
+ deps.nudgePlacements.clear(sessionId);
21033
21027
  }
21034
- if (didMutateFromFlushedStatuses) {
21028
+ if (didMutateFromFlushedStatuses && isCacheBusting) {
21035
21029
  deps.nudgePlacements.clear(sessionId);
21036
21030
  }
21037
21031
  const t3 = performance.now();
@@ -21046,9 +21040,8 @@ function createTransform(deps) {
21046
21040
  watermark = tag.tagNumber;
21047
21041
  }
21048
21042
  }
21049
- const contextUsage = loadContextUsage(deps.contextUsageMap, db, sessionId);
21050
- const schedulerDecision = resolveSchedulerDecision(deps.scheduler, sessionMeta, contextUsage, sessionId);
21051
- const isCacheBusting = deps.flushedSessions.has(sessionId) || schedulerDecision === "execute";
21043
+ const contextUsage = contextUsageEarly;
21044
+ const schedulerDecision = schedulerDecisionEarly;
21052
21045
  const rawGetNotifParams = deps.getNotificationParams;
21053
21046
  const compartmentPhase = await runCompartmentPhase({
21054
21047
  canRunCompartments,
@@ -21525,7 +21518,10 @@ function createMagicContextHook(deps) {
21525
21518
  tagger: deps.tagger,
21526
21519
  db,
21527
21520
  nudgePlacements,
21528
- onSessionCacheInvalidated: deps.onSessionCacheInvalidated
21521
+ onSessionCacheInvalidated: (sessionId) => {
21522
+ clearInjectionCache(sessionId);
21523
+ deps.onSessionCacheInvalidated?.(sessionId);
21524
+ }
21529
21525
  });
21530
21526
  const runDreamQueueInBackground = () => {
21531
21527
  const dreaming = deps.config.dreamer;
@@ -1 +1 @@
1
- {"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAU7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;CAC1C;;;;;;qBAgBW,CAAH;;;;;;;;;;;;qBAkBqC,CAAC;mBAAiB,CAAC;;;;;0BAQ4pS,CAAC;;;;;;EAD7tS"}
1
+ {"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAU7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;CAC1C;;;;;;qBAgBW,CAAH;;;;;;;;;;;;qBAkBqC,CAAC;mBAAiB,CAAC;;;;;0BAQk0S,CAAC;;;;;;EADn4S"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-magic-context",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",