acp-kernel 0.0.78 → 0.0.79-pr.332.197

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/dist/absorb.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type LatestProtected } from "./protected.js";
1
2
  import type { AbsorbConfig, Config, CompressionState, CoreMessage } from "./types.js";
2
3
  /**
3
4
  * Instant tool-result absorption ("absorb") — the middle layer between
@@ -17,7 +18,7 @@ export declare function buildAbsorbPrompt(ref: string, tokens: number, toolName?
17
18
  export declare function buildAbsorbSystemPrompt(toolName?: string): string;
18
19
  /** True when a tool-result message is in scope for absorption prompting:
19
20
  * a tool-result of a non-ACP, non-excluded, non-protected tool. */
20
- export declare function isAbsorbCandidate(msg: CoreMessage, config: Config): boolean;
21
+ export declare function isAbsorbCandidate(msg: CoreMessage, config: Config, latest?: LatestProtected): boolean;
21
22
  /** Drop tool-call + tool-result pairs recorded in state.absorbed. Both halves
22
23
  * go together so the provider-visible conversation stays structurally valid;
23
24
  * prune's orphan stripping cleans up any straddling leftovers. */
@@ -1 +1 @@
1
- {"version":3,"file":"absorb.d.ts","sourceRoot":"","sources":["../src/absorb.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EAEZ,MAAM,EACN,gBAAgB,EAChB,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;GASG;AAEH,eAAO,MAAM,oBAAoB,iBAAiB,CAAC;AAEnD,eAAO,MAAM,qBAAqB,EAAE,YAMnC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAEhE;AAQD,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAyB,GAClC,MAAM,CAQR;AAED,8DAA8D;AAC9D,wBAAgB,uBAAuB,CACrC,QAAQ,GAAE,MAAyB,GAClC,MAAM,CAIR;AAWD;oEACoE;AACpE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAS3E;AAED;;mEAEmE;AACnE,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,gBAAgB,GACtB,WAAW,EAAE,CASf;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;sEAGsE;AACtE,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACpC,yBAAyB,CAmC3B;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;4DAE4D;AAC5D,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACjC,YAAY,GAAG,IAAI,CA+BrB;AAaD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,gBAAgB,CAAC;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;0DAE0D;AAC1D,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAsG7D"}
1
+ {"version":3,"file":"absorb.d.ts","sourceRoot":"","sources":["../src/absorb.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACV,YAAY,EAEZ,MAAM,EACN,gBAAgB,EAChB,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;GASG;AAEH,eAAO,MAAM,oBAAoB,iBAAiB,CAAC;AAEnD,eAAO,MAAM,qBAAqB,EAAE,YAMnC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAEhE;AAQD,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAyB,GAClC,MAAM,CAQR;AAED,8DAA8D;AAC9D,wBAAgB,uBAAuB,CACrC,QAAQ,GAAE,MAAyB,GAClC,MAAM,CAIR;AAWD;oEACoE;AACpE,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAUT;AAED;;mEAEmE;AACnE,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,gBAAgB,GACtB,WAAW,EAAE,CASf;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;sEAGsE;AACtE,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACpC,yBAAyB,CAoC3B;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;4DAE4D;AAC5D,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACjC,YAAY,GAAG,IAAI,CA+BrB;AAaD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,gBAAgB,CAAC;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;0DAE0D;AAC1D,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CA4G7D"}
@@ -13,6 +13,8 @@ function createInitialState() {
13
13
  },
14
14
  stats: { tokensCompressed: 0, compressionCount: 0, absorbedTokens: 0 },
15
15
  absorbed: [],
16
+ rules: [],
17
+ nextRuleId: 1,
16
18
  nextBlockId: 1,
17
19
  nextRunId: 1
18
20
  };
@@ -68,4 +70,4 @@ export {
68
70
  highestActiveTier,
69
71
  advanceSurvival
70
72
  };
71
- //# sourceMappingURL=chunk-UX4LINT7.js.map
73
+ //# sourceMappingURL=chunk-5TQA7ZQM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/state.ts"],"sourcesContent":["import type { CompressionBlock, CompressionState } from \"./types.js\";\n\nexport function createInitialState(): CompressionState {\n return {\n blocks: [],\n messageRefs: { byRaw: {}, byRef: {} },\n tokenSnapshot: {},\n nudge: {\n lastPerMessageNudgeTokens: 0,\n lastNudgeShownTokens: 0,\n baselineTokens: 0,\n anchors: {},\n lastShownByTier: {},\n },\n stats: { tokensCompressed: 0, compressionCount: 0, absorbedTokens: 0 },\n absorbed: [],\n rules: [],\n nextRuleId: 1,\n nextBlockId: 1,\n nextRunId: 1,\n };\n}\n\nexport function allocateBlockId(state: CompressionState): string {\n const id = state.nextBlockId;\n state.nextBlockId = Math.max(1, id) + 1;\n return `b${id}`;\n}\n\nexport function allocateRunId(state: CompressionState): string {\n const id = state.nextRunId;\n state.nextRunId = Math.max(1, id) + 1;\n return `r${id}`;\n}\n\nexport function blockById(\n state: CompressionState,\n blockId: string,\n): CompressionBlock | undefined {\n return state.blocks.find((block) => block.blockId === blockId);\n}\n\nexport function activeBlocks(state: CompressionState): CompressionBlock[] {\n return state.blocks.filter((block) => block.active);\n}\n\nexport function coveredMessageIds(state: CompressionState): Set<string> {\n const covered = new Set<string>();\n for (const block of state.blocks) {\n if (!block.active) continue;\n for (const id of block.effectiveMessageIds) covered.add(id);\n }\n return covered;\n}\n\nexport function highestActiveTier(state: CompressionState): 0 | 1 | 2 | 3 {\n let highest: 0 | 1 | 2 | 3 = 0;\n for (const block of state.blocks) {\n if (block.active && block.tier > highest) highest = block.tier;\n }\n return highest;\n}\n\nexport function advanceSurvival(\n state: CompressionState,\n promotionThreshold: number,\n): void {\n for (const block of state.blocks) {\n if (!block.active) continue;\n block.survivedCount += 1;\n if (block.survivedCount >= promotionThreshold) {\n block.generation = \"old\";\n }\n }\n}\n"],"mappings":";AAEO,SAAS,qBAAuC;AACrD,SAAO;AAAA,IACL,QAAQ,CAAC;AAAA,IACT,aAAa,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,EAAE;AAAA,IACpC,eAAe,CAAC;AAAA,IAChB,OAAO;AAAA,MACL,2BAA2B;AAAA,MAC3B,sBAAsB;AAAA,MACtB,gBAAgB;AAAA,MAChB,SAAS,CAAC;AAAA,MACV,iBAAiB,CAAC;AAAA,IACpB;AAAA,IACA,OAAO,EAAE,kBAAkB,GAAG,kBAAkB,GAAG,gBAAgB,EAAE;AAAA,IACrE,UAAU,CAAC;AAAA,IACX,OAAO,CAAC;AAAA,IACR,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,WAAW;AAAA,EACb;AACF;AAEO,SAAS,gBAAgB,OAAiC;AAC/D,QAAM,KAAK,MAAM;AACjB,QAAM,cAAc,KAAK,IAAI,GAAG,EAAE,IAAI;AACtC,SAAO,IAAI,EAAE;AACf;AAEO,SAAS,cAAc,OAAiC;AAC7D,QAAM,KAAK,MAAM;AACjB,QAAM,YAAY,KAAK,IAAI,GAAG,EAAE,IAAI;AACpC,SAAO,IAAI,EAAE;AACf;AAEO,SAAS,UACd,OACA,SAC8B;AAC9B,SAAO,MAAM,OAAO,KAAK,CAAC,UAAU,MAAM,YAAY,OAAO;AAC/D;AAEO,SAAS,aAAa,OAA6C;AACxE,SAAO,MAAM,OAAO,OAAO,CAAC,UAAU,MAAM,MAAM;AACpD;AAEO,SAAS,kBAAkB,OAAsC;AACtE,QAAM,UAAU,oBAAI,IAAY;AAChC,aAAW,SAAS,MAAM,QAAQ;AAChC,QAAI,CAAC,MAAM,OAAQ;AACnB,eAAW,MAAM,MAAM,oBAAqB,SAAQ,IAAI,EAAE;AAAA,EAC5D;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,OAAwC;AACxE,MAAI,UAAyB;AAC7B,aAAW,SAAS,MAAM,QAAQ;AAChC,QAAI,MAAM,UAAU,MAAM,OAAO,QAAS,WAAU,MAAM;AAAA,EAC5D;AACA,SAAO;AACT;AAEO,SAAS,gBACd,OACA,oBACM;AACN,aAAW,SAAS,MAAM,QAAQ;AAChC,QAAI,CAAC,MAAM,OAAQ;AACnB,UAAM,iBAAiB;AACvB,QAAI,MAAM,iBAAiB,oBAAoB;AAC7C,YAAM,aAAa;AAAA,IACrB;AAAA,EACF;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkC,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAgBhF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAUvD,OAAO,EAGL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAEhB,MAAM,EAEN,WAAW,EAGX,iBAAiB,EAEjB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,KAAK;IACpB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;IACxD,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CAAC;IACvE,YAAY,IAAI,YAAY,EAAE,CAAC;IAC/B,UAAU,CACR,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,gBAAgB,GACtB,gBAAgB,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;IACnE,MAAM,CACJ,KAAK,EAAE,gBAAgB,EACvB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,YAAY,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,EAAE,CAAC;IACJ,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnC;AA2DD,wBAAgB,UAAU,CAAC,KAAK,GAAE,KAAU,GAAG,eAAe,CA+U7D;AA0jCD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkC,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAgBhF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAcvD,OAAO,EAGL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAEhB,MAAM,EAEN,WAAW,EAGX,iBAAiB,EAEjB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,KAAK;IACpB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;IACxD,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CAAC;IACvE,YAAY,IAAI,YAAY,EAAE,CAAC;IAC/B,UAAU,CACR,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,gBAAgB,GACtB,gBAAgB,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;IACnE,MAAM,CACJ,KAAK,EAAE,gBAAgB,EACvB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,YAAY,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,EAAE,CAAC;IACJ,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnC;AA2DD,wBAAgB,UAAU,CAAC,KAAK,GAAE,KAAU,GAAG,eAAe,CA+U7D;AAwkCD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,MAAM,EACzB,SAAS,GAAE,OAAO,CAAC,MAAM,CAAM,GAC9B,MAAM,CA+CR;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA8DvD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,MAAM,EACzB,SAAS,GAAE,OAAO,CAAC,MAAM,CAAM,GAC9B,MAAM,CAgDR;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA4EvD"}
package/dist/index.d.ts CHANGED
@@ -35,6 +35,8 @@ export type { HideConsumedResult } from "./hide-consumed.js";
35
35
  export { ABSORB_TOOL_NAME, ABSORB_TOOL, ABSORB_TOOL_OPENAI, } from "./compress-tools.js";
36
36
  export { ABSORB_PROMPT_MARKER, DEFAULT_ABSORB_CONFIG, resolveAbsorbConfig, buildAbsorbPrompt, buildAbsorbSystemPrompt, isAbsorbCandidate, hideAbsorbedMessages, appendAbsorbPrompts, parseAbsorbInput, applyAbsorb, } from "./absorb.js";
37
37
  export type { AbsorbInput, AbsorbOutcome, ParsedAbsorb, AppendAbsorbPromptsResult, } from "./absorb.js";
38
+ export { RULE_TOOL_NAME, DEFAULT_RULE_LIMITS, RULES_USAGE_PROMPT, listRules, allocateRuleId, resolveRuleLimits, addRule, removeRule, clearRules, formatRulesForPrompt, formatRulesList, } from "./rules.js";
39
+ export type { RuleLimits, AddRuleResult, RemoveRuleResult, ClearRulesResult, } from "./rules.js";
38
40
  export { rebuildCompressionState } from "./rebuild.js";
39
41
  export type { RebuildResult, RebuildPorts } from "./rebuild.js";
40
42
  export { parseCompressArgs } from "./parse-compress-input.js";
@@ -47,7 +49,7 @@ export { searchBlocks, searchBlocksAsync, blockDocs, messageDocs, } from "./sear
47
49
  export { clearDocFeatures, docCacheInfo, docFeatures, setDocCacheCap, } from "./search.js";
48
50
  export type { SearchResult, SearchOptions, SearchAlgorithm, AsyncSearchAlgorithm, AnySearchAlgorithm, SearchDoc, SearchDocKind, ScoredBlock, MessageRole, RoleWeights, MessageInput, } from "./search.js";
49
51
  export { DEFAULT_ALGORITHM, DEFAULT_ROLE_WEIGHTS, registerSearchAlgorithm, getSearchAlgorithm, listSearchAlgorithms, } from "./search.js";
50
- export { isMessageProtected, matchToolPattern } from "./protected.js";
52
+ export { collectLatestProtected, isMessageLatestProtected, isMessageProtected, matchToolPattern, type LatestProtected, } from "./protected.js";
51
53
  export { runPipeline, makeIO, type PipelineNode, type PipelineContext, type NodeIO, type NodeEffects, } from "./pipeline.js";
52
54
  export * from "./filter/index.js";
53
55
  export { VIABLE_RANGE_MIN_TOKENS, viableRanges } from "./viable.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EACV,KAAK,EACL,eAAe,EACf,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5D,cAAc,qBAAqB,CAAC;AACpC,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,SAAS,EACT,WAAW,GACZ,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,KAAK,EACL,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAChE,YAAY,EACV,UAAU,EACV,aAAa,EACb,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,YAAY,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,WAAW,EACX,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,QAAQ,EACR,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,cAAc,EACd,WAAW,EACX,IAAI,EACJ,UAAU,EACV,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EACL,eAAe,EACf,6BAA6B,EAC7B,kBAAkB,EAClB,eAAe,EACf,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC5D,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,WAAW,EACX,SAAS,EACT,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1E,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChF,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,GACZ,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,WAAW,EACX,aAAa,EACb,YAAY,EACZ,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,YAAY,EACV,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,WAAW,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,YAAY,EACZ,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,SAAS,EACT,aAAa,EACb,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EACL,WAAW,EACX,MAAM,EACN,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,KAAK,WAAW,GACjB,MAAM,eAAe,CAAC;AACvB,cAAc,mBAAmB,CAAC;AAElC,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  coveredMessageIds,
27
27
  createInitialState,
28
28
  highestActiveTier
29
- } from "./chunk-UX4LINT7.js";
29
+ } from "./chunk-5TQA7ZQM.js";
30
30
 
31
31
  // src/refs.ts
32
32
  var REF_WIDTH = 5;
@@ -298,6 +298,8 @@ function syncBlocks(messages, state) {
298
298
  nudge: { ...state.nudge, anchors: { ...state.nudge.anchors } },
299
299
  stats: { ...state.stats },
300
300
  absorbed: (state.absorbed ?? []).map((record) => ({ ...record })),
301
+ rules: (state.rules ?? []).map((rule) => ({ ...rule })),
302
+ nextRuleId: state.nextRuleId,
301
303
  terminalStreak: state.terminalStreak,
302
304
  nextBlockId: state.nextBlockId,
303
305
  nextRunId: state.nextRunId
@@ -363,6 +365,7 @@ function defaultConfig(modelContextLimit, overrides = {}) {
363
365
  minSummaryLength: 50
364
366
  },
365
367
  protectedTools: [],
368
+ protectedLatestTools: [],
366
369
  preserveRecentMessages: 5,
367
370
  preserveRecentTokens: 5e3,
368
371
  modelContextLimit,
@@ -428,6 +431,14 @@ function validateConfig(config) {
428
431
  errors.push("absorb.contextThresholdPct must be in [0, 1]");
429
432
  }
430
433
  }
434
+ if (config.rules) {
435
+ if (config.rules.maxRules !== void 0 && (!Number.isFinite(config.rules.maxRules) || config.rules.maxRules < 1)) {
436
+ errors.push("rules.maxRules must be >= 1");
437
+ }
438
+ if (config.rules.maxRuleChars !== void 0 && (!Number.isFinite(config.rules.maxRuleChars) || config.rules.maxRuleChars < 1)) {
439
+ errors.push("rules.maxRuleChars must be >= 1");
440
+ }
441
+ }
431
442
  return errors;
432
443
  }
433
444
 
@@ -1466,7 +1477,7 @@ var ABSORB_TOOL_GOOGLE = {
1466
1477
  };
1467
1478
 
1468
1479
  // src/protected.ts
1469
- var ALWAYS_PROTECTED_TOOLS = ["compress"];
1480
+ var ALWAYS_PROTECTED_TOOLS = ["compress", "acp_rule"];
1470
1481
  var NEVER_PRESERVE_RECENT_TOOLS = [
1471
1482
  "decompress",
1472
1483
  "search_context",
@@ -1515,6 +1526,31 @@ function isMessageProtectedWithPairing(msg, config, protectedCallIds) {
1515
1526
  }
1516
1527
  return false;
1517
1528
  }
1529
+ function collectLatestProtected(messages, config) {
1530
+ const callIds = /* @__PURE__ */ new Set();
1531
+ const msgIds = /* @__PURE__ */ new Set();
1532
+ const patterns = config.protectedLatestTools ?? [];
1533
+ if (patterns.length === 0) return { callIds, msgIds };
1534
+ for (const pattern of patterns) {
1535
+ let last;
1536
+ for (const m of messages) {
1537
+ if (m.contentType === "tool-call" && m.toolName && matchToolPattern(m.toolName, pattern)) {
1538
+ last = m;
1539
+ }
1540
+ }
1541
+ if (!last) continue;
1542
+ if (last.toolCallId) callIds.add(last.toolCallId);
1543
+ else msgIds.add(last.id);
1544
+ }
1545
+ return { callIds, msgIds };
1546
+ }
1547
+ function isMessageLatestProtected(msg, latest) {
1548
+ if (msg.contentType === "tool-call" && latest.msgIds.has(msg.id)) return true;
1549
+ if ((msg.contentType === "tool-call" || msg.contentType === "tool-result") && msg.toolCallId && latest.callIds.has(msg.toolCallId)) {
1550
+ return true;
1551
+ }
1552
+ return false;
1553
+ }
1518
1554
 
1519
1555
  // src/absorb.ts
1520
1556
  var ABSORB_PROMPT_MARKER = "[ACP absorb]";
@@ -1546,11 +1582,12 @@ function isAcpOrConfiguredTool(toolName, cfg) {
1546
1582
  if (toolName === cfg.toolName) return true;
1547
1583
  return ACP_TOOL_NAMES.has(toolName);
1548
1584
  }
1549
- function isAbsorbCandidate(msg, config) {
1585
+ function isAbsorbCandidate(msg, config, latest) {
1550
1586
  if (msg.contentType !== "tool-result" || !msg.toolCallId) return false;
1551
1587
  const cfg = resolveAbsorbConfig(config);
1552
1588
  if (isAcpOrConfiguredTool(msg.toolName, cfg)) return false;
1553
1589
  if (isMessageProtected(msg, config)) return false;
1590
+ if (latest && isMessageLatestProtected(msg, latest)) return false;
1554
1591
  for (const pattern of cfg.excludeTools) {
1555
1592
  if (msg.toolName && matchToolPattern(msg.toolName, pattern)) return false;
1556
1593
  }
@@ -1578,8 +1615,9 @@ function appendAbsorbPrompts(messages, state, config, tokenCount, countTokens) {
1578
1615
  if (record.resultMessageId) absorbedIds.add(record.resultMessageId);
1579
1616
  }
1580
1617
  let promptedCount = 0;
1618
+ const latest = collectLatestProtected(messages, config);
1581
1619
  const out = messages.map((msg) => {
1582
- if (!isAbsorbCandidate(msg, config)) return msg;
1620
+ if (!isAbsorbCandidate(msg, config, latest)) return msg;
1583
1621
  if (absorbedIds.has(msg.id)) return msg;
1584
1622
  const text = msg.text ?? "";
1585
1623
  if (text.includes(ABSORB_PROMPT_MARKER)) return msg;
@@ -1685,7 +1723,10 @@ function applyAbsorb(input) {
1685
1723
  resultText: `absorb failed: ${target.toolName} is an ACP-managed tool result \u2014 it is not absorbable.`
1686
1724
  };
1687
1725
  }
1688
- if (isMessageProtected(target, input.config)) {
1726
+ if (isMessageProtected(target, input.config) || isMessageLatestProtected(
1727
+ target,
1728
+ collectLatestProtected(input.messages, input.config)
1729
+ )) {
1689
1730
  return {
1690
1731
  state: input.state,
1691
1732
  ok: false,
@@ -2196,6 +2237,8 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
2196
2237
  let compressibleMsgs = [];
2197
2238
  const protectedMsgs = [];
2198
2239
  const protectedCallIds = collectProtectedToolCallIds(messages, config);
2240
+ const latest = collectLatestProtected(messages, config);
2241
+ for (const id of latest.callIds) protectedCallIds.add(id);
2199
2242
  let skipSinceCompressible = false;
2200
2243
  let skipSinceProtected = false;
2201
2244
  let msgIndex = -1;
@@ -2208,7 +2251,7 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
2208
2251
  skipSinceProtected = true;
2209
2252
  continue;
2210
2253
  }
2211
- if (isMessageProtectedWithPairing(msg, config, protectedCallIds)) {
2254
+ if (isMessageProtectedWithPairing(msg, config, protectedCallIds) || isMessageLatestProtected(msg, latest)) {
2212
2255
  protectedMsgs.push({
2213
2256
  ref,
2214
2257
  gapBefore: skipSinceProtected,
@@ -2669,8 +2712,9 @@ function createCore(ports = {}) {
2669
2712
  var assignRefsNode = {
2670
2713
  name: "assign-refs",
2671
2714
  run(io, ctx) {
2672
- const hasProtection = ctx.config.protectedTools.length > 0 || !!ctx.config.isToolProtected;
2673
- const protectedFn = hasProtection ? (m) => isMessageProtected(m, ctx.config) : void 0;
2715
+ const hasProtection = ctx.config.protectedTools.length > 0 || !!ctx.config.isToolProtected || (ctx.config.protectedLatestTools?.length ?? 0) > 0;
2716
+ const latest = hasProtection ? collectLatestProtected(io.messages, ctx.config) : void 0;
2717
+ const protectedFn = hasProtection ? (m) => isMessageProtected(m, ctx.config) || (latest ? isMessageLatestProtected(m, latest) : false) : void 0;
2674
2718
  const refResult = assignRefs(io.messages, {
2675
2719
  existing: io.state.messageRefs,
2676
2720
  nextIndex: highestUsedIndex(io.state.messageRefs) + 1,
@@ -3066,6 +3110,8 @@ function validateCompressionRange(input, directMessageIds, consumedBlockCount) {
3066
3110
  function filterProtectedToolMessages(directMessageIds, messages, config) {
3067
3111
  const protectedCallIds = /* @__PURE__ */ new Set();
3068
3112
  const removedIds = /* @__PURE__ */ new Set();
3113
+ const latest = collectLatestProtected(messages, config);
3114
+ for (const id of latest.callIds) protectedCallIds.add(id);
3069
3115
  for (const msg of messages) {
3070
3116
  if (isMessageProtected(msg, config) && msg.toolCallId) {
3071
3117
  protectedCallIds.add(msg.toolCallId);
@@ -3074,7 +3120,7 @@ function filterProtectedToolMessages(directMessageIds, messages, config) {
3074
3120
  for (const id of directMessageIds) {
3075
3121
  const msg = messages.find((m) => m.id === id);
3076
3122
  if (!msg) continue;
3077
- if (isMessageProtected(msg, config)) {
3123
+ if (isMessageProtected(msg, config) || isMessageLatestProtected(msg, latest)) {
3078
3124
  removedIds.add(id);
3079
3125
  if (msg.toolCallId) protectedCallIds.add(msg.toolCallId);
3080
3126
  }
@@ -3332,6 +3378,8 @@ function cloneState(state) {
3332
3378
  nudge: { ...state.nudge, anchors: { ...state.nudge.anchors } },
3333
3379
  stats: { ...state.stats },
3334
3380
  absorbed: (state.absorbed ?? []).map((record) => ({ ...record })),
3381
+ rules: (state.rules ?? []).map((rule) => ({ ...rule })),
3382
+ nextRuleId: state.nextRuleId,
3335
3383
  terminalStreak: state.terminalStreak,
3336
3384
  nextBlockId: state.nextBlockId,
3337
3385
  nextRunId: state.nextRunId
@@ -4532,6 +4580,96 @@ function matchSession(sessions, selector, labelOf) {
4532
4580
  return sessions.filter((s) => s.id.startsWith(selector) || (labelOf(s) ?? "").startsWith(selector));
4533
4581
  }
4534
4582
 
4583
+ // src/rules.ts
4584
+ var RULE_TOOL_NAME = "acp_rule";
4585
+ var DEFAULT_RULE_LIMITS = Object.freeze({
4586
+ maxRules: 50,
4587
+ maxRuleChars: 300
4588
+ });
4589
+ var RULES_USAGE_PROMPT = [
4590
+ "Use the acp_rule tool to record short, principle-level reminders that must survive context compression:",
4591
+ "- behavioral corrections the user has had to repeat more than once,",
4592
+ "- project invariants the user explicitly asked you to remember,",
4593
+ "- pitfalls you ran into once and must not run into again.",
4594
+ "Rules are re-injected into the system prompt every turn. Omit the text argument to list recorded rules."
4595
+ ].join("\n");
4596
+ function listRules(state) {
4597
+ return state.rules ?? [];
4598
+ }
4599
+ function resolveRuleLimits(config) {
4600
+ return {
4601
+ maxRules: config?.rules?.maxRules ?? DEFAULT_RULE_LIMITS.maxRules,
4602
+ maxRuleChars: config?.rules?.maxRuleChars ?? DEFAULT_RULE_LIMITS.maxRuleChars
4603
+ };
4604
+ }
4605
+ var RULE_ID_RE = /^rule(\d+)$/;
4606
+ function highestRuleNumber(state) {
4607
+ let highest = 0;
4608
+ for (const rule of state.rules ?? []) {
4609
+ const match = RULE_ID_RE.exec(rule.id);
4610
+ if (match) highest = Math.max(highest, Number(match[1]));
4611
+ }
4612
+ return highest;
4613
+ }
4614
+ function allocateRuleId(state) {
4615
+ return `rule${Math.max(state.nextRuleId ?? 1, highestRuleNumber(state) + 1)}`;
4616
+ }
4617
+ function addRule(state, text, limits = {}) {
4618
+ const maxRules = limits.maxRules ?? DEFAULT_RULE_LIMITS.maxRules;
4619
+ const maxRuleChars = limits.maxRuleChars ?? DEFAULT_RULE_LIMITS.maxRuleChars;
4620
+ const trimmed = (text ?? "").trim();
4621
+ if (!trimmed) {
4622
+ return { ok: false, error: "rule text is empty \u2014 provide the reminder to record." };
4623
+ }
4624
+ if (trimmed.length > maxRuleChars) {
4625
+ return {
4626
+ ok: false,
4627
+ error: `${trimmed.length} chars exceeds the ${maxRuleChars}-char limit \u2014 keep rules short and principle-level.`
4628
+ };
4629
+ }
4630
+ const rules = listRules(state);
4631
+ const duplicate = rules.find((rule2) => rule2.text === trimmed);
4632
+ if (duplicate) {
4633
+ return { ok: false, error: `identical rule already exists (${duplicate.id}) \u2014 no change.` };
4634
+ }
4635
+ if (rules.length >= maxRules) {
4636
+ return {
4637
+ ok: false,
4638
+ error: `rule limit reached (${maxRules}) \u2014 remove or clear outdated rules first.`
4639
+ };
4640
+ }
4641
+ const next = Math.max(state.nextRuleId ?? 1, highestRuleNumber(state) + 1);
4642
+ const rule = { id: `rule${next}`, text: trimmed };
4643
+ state.rules = [...rules, rule];
4644
+ state.nextRuleId = next + 1;
4645
+ return { ok: true, rule };
4646
+ }
4647
+ function removeRule(state, id) {
4648
+ const rules = listRules(state);
4649
+ const target = rules.find((rule) => rule.id === id.trim());
4650
+ if (!target) {
4651
+ return { ok: false, error: `no rule with id "${id.trim()}" \u2014 list current rules first (omit the text argument).` };
4652
+ }
4653
+ state.rules = rules.filter((rule) => rule.id !== target.id);
4654
+ return { ok: true, rule: target };
4655
+ }
4656
+ function clearRules(state) {
4657
+ const count = listRules(state).length;
4658
+ state.rules = [];
4659
+ return { ok: true, count };
4660
+ }
4661
+ function formatRulesForPrompt(state) {
4662
+ const rules = listRules(state);
4663
+ if (rules.length === 0) return "";
4664
+ return [
4665
+ "# Persistent rules (recorded via acp_rule \u2014 kept across compression)",
4666
+ ...rules.map((rule) => `- [${rule.id}] ${rule.text}`)
4667
+ ].join("\n");
4668
+ }
4669
+ function formatRulesList(rules) {
4670
+ return rules.map((rule, i) => `${i + 1}. [${rule.id}] ${rule.text}`).join("\n");
4671
+ }
4672
+
4535
4673
  // src/parse-compress-input.ts
4536
4674
  function parseCompressArgs(input, opts) {
4537
4675
  const callId = opts?.callId;
@@ -4678,12 +4816,35 @@ function finishSalvage(entries, callId, diag, truncatedShape) {
4678
4816
  diag.kind = entries.length > 0 || truncatedShape ? "truncated" : "malformed-json";
4679
4817
  return finish(ranges, diag);
4680
4818
  }
4819
+ function coalesceLineEntries(entries) {
4820
+ const out = [];
4821
+ let headerOnlyIdx = -1;
4822
+ for (const e of entries) {
4823
+ if (typeof e === "string") {
4824
+ const nl = e.indexOf("\n");
4825
+ const head = (nl === -1 ? e : e.slice(0, nl)).trim();
4826
+ const hasRef = REF_PAIR_IN_LINE.test(head) || SINGLE_REF_IN_LINE.test(head);
4827
+ if (!hasRef && headerOnlyIdx >= 0) {
4828
+ out[headerOnlyIdx] = `${out[headerOnlyIdx]}
4829
+ ${e}`;
4830
+ continue;
4831
+ }
4832
+ out.push(e);
4833
+ headerOnlyIdx = hasRef && nl === -1 ? out.length - 1 : -1;
4834
+ } else {
4835
+ out.push(e);
4836
+ headerOnlyIdx = -1;
4837
+ }
4838
+ }
4839
+ return out;
4840
+ }
4681
4841
  function validateEntries(entries, callId) {
4682
4842
  const ranges = [];
4683
4843
  const reasons = [];
4684
4844
  let invalid = 0;
4685
- for (let i = 0; i < entries.length; i++) {
4686
- const outcome = validateEntry(entries[i], callId);
4845
+ const items = coalesceLineEntries(entries);
4846
+ for (let i = 0; i < items.length; i++) {
4847
+ const outcome = validateEntry(items[i], callId);
4687
4848
  if ("range" in outcome) ranges.push(outcome.range);
4688
4849
  else {
4689
4850
  invalid++;
@@ -5450,8 +5611,11 @@ export {
5450
5611
  DEFAULT_ABSORB_CONFIG,
5451
5612
  DEFAULT_ALGORITHM,
5452
5613
  DEFAULT_ROLE_WEIGHTS,
5614
+ DEFAULT_RULE_LIMITS,
5453
5615
  HOW_TO_COMPRESS_RULES,
5454
5616
  LEAN_HOW_TO_COMPRESS,
5617
+ RULES_USAGE_PROMPT,
5618
+ RULE_TOOL_NAME,
5455
5619
  SEARCH_CONTEXT_TOOL,
5456
5620
  SEARCH_CONTEXT_TOOL_GOOGLE,
5457
5621
  SEARCH_CONTEXT_TOOL_NAME,
@@ -5463,8 +5627,10 @@ export {
5463
5627
  VIABLE_RANGE_MIN_TOKENS,
5464
5628
  activeBlockSpans,
5465
5629
  activeBlocks,
5630
+ addRule,
5466
5631
  advanceSurvival,
5467
5632
  allocateBlockId,
5633
+ allocateRuleId,
5468
5634
  allocateRunId,
5469
5635
  appendAbsorbPrompts,
5470
5636
  applyAbsorb,
@@ -5487,8 +5653,10 @@ export {
5487
5653
  builtinSource,
5488
5654
  clearDocFeatures,
5489
5655
  clearMessageFilters,
5656
+ clearRules,
5490
5657
  cloneWithDescriptions,
5491
5658
  collectBlockContent,
5659
+ collectLatestProtected,
5492
5660
  computeFoldEconomics,
5493
5661
  countMessageTokens,
5494
5662
  coveredMessageIds,
@@ -5514,6 +5682,8 @@ export {
5514
5682
  formatCacheReport,
5515
5683
  formatCreatedBlocks,
5516
5684
  formatRanges,
5685
+ formatRulesForPrompt,
5686
+ formatRulesList,
5517
5687
  getMessageFilter,
5518
5688
  getSearchAlgorithm,
5519
5689
  hideAbsorbedMessages,
@@ -5522,12 +5692,14 @@ export {
5522
5692
  highestUsedIndex,
5523
5693
  indexToRef,
5524
5694
  isAbsorbCandidate,
5695
+ isMessageLatestProtected,
5525
5696
  isMessageProtected,
5526
5697
  isRenderedSummaryMessage,
5527
5698
  isSummaryMessageId,
5528
5699
  isValidPackName,
5529
5700
  leanPack,
5530
5701
  listMessageFilters,
5702
+ listRules,
5531
5703
  listSearchAlgorithms,
5532
5704
  makeIO,
5533
5705
  matchSession,
@@ -5545,6 +5717,7 @@ export {
5545
5717
  refToIndex,
5546
5718
  registerMessageFilter,
5547
5719
  registerSearchAlgorithm,
5720
+ removeRule,
5548
5721
  renderHandoff,
5549
5722
  renderMessage2 as renderMessage,
5550
5723
  renderNudgeText,
@@ -5554,6 +5727,7 @@ export {
5554
5727
  resolveBlockSpan,
5555
5728
  resolveBoundaries,
5556
5729
  resolvePrompts,
5730
+ resolveRuleLimits,
5557
5731
  resolveTransformChannel,
5558
5732
  runPipeline,
5559
5733
  sanitizePackSurface,