@chroxify/eunoe 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +139 -2
  2. package/dist/core/index.js +2235 -0
  3. package/dist/types/context/content.d.ts +31 -0
  4. package/dist/types/context/fold/evidence.d.ts +20 -0
  5. package/dist/types/context/fold/index.d.ts +11 -0
  6. package/dist/types/context/fold/strategies.d.ts +20 -0
  7. package/dist/types/context/fold/turns.d.ts +14 -0
  8. package/dist/types/context/prompts.d.ts +24 -0
  9. package/dist/types/context/recall/index.d.ts +44 -0
  10. package/dist/types/context/recall/rerank.d.ts +3 -0
  11. package/dist/types/core/compaction.d.ts +32 -0
  12. package/dist/types/core/config.d.ts +33 -0
  13. package/dist/types/core/estimate.d.ts +9 -0
  14. package/dist/types/core/fingerprint.d.ts +10 -0
  15. package/dist/types/core/fold.d.ts +18 -0
  16. package/dist/types/core/forward.d.ts +24 -0
  17. package/dist/types/core/handoff.d.ts +10 -0
  18. package/dist/types/core/index.d.ts +14 -0
  19. package/dist/types/core/recall.d.ts +8 -0
  20. package/dist/types/core/rewrite.d.ts +63 -0
  21. package/dist/types/core/state.d.ts +22 -0
  22. package/dist/types/core/subagents.d.ts +10 -0
  23. package/dist/types/core/transcript.d.ts +9 -0
  24. package/dist/types/core/usage.d.ts +7 -0
  25. package/dist/types/core/window.d.ts +5 -0
  26. package/dist/types/transcript/format.d.ts +16 -0
  27. package/dist/types/transcript/parse.d.ts +45 -0
  28. package/package.json +15 -2
  29. package/src/cli/commands/mode.ts +2 -1
  30. package/src/cli/commands/status.ts +1 -1
  31. package/src/cli/proxy/stats.ts +1 -1
  32. package/src/cli/replay/index.ts +3 -3
  33. package/src/cli/sessions/index.ts +2 -2
  34. package/src/config/index.ts +4 -27
  35. package/src/context/content.ts +64 -1
  36. package/src/context/fold/strategies.ts +55 -10
  37. package/src/context/fold/turns.ts +22 -2
  38. package/src/context/prompts.ts +4 -3
  39. package/src/context/recall/index.ts +2 -3
  40. package/src/context/recall/rerank.ts +0 -8
  41. package/src/{proxy → core}/compaction.ts +56 -24
  42. package/src/core/config.ts +31 -0
  43. package/src/core/fold.ts +69 -0
  44. package/src/core/forward.ts +192 -0
  45. package/src/{proxy → core}/handoff.ts +23 -23
  46. package/src/core/index.ts +14 -0
  47. package/src/{proxy → core}/recall.ts +18 -20
  48. package/src/core/rewrite.ts +189 -0
  49. package/src/core/state.ts +40 -0
  50. package/src/core/subagents.ts +28 -0
  51. package/src/core/transcript.ts +44 -0
  52. package/src/{proxy → core}/usage.ts +34 -1
  53. package/src/core/window.ts +39 -0
  54. package/src/proxy/rewrite.ts +22 -139
  55. package/src/proxy/server.ts +21 -159
  56. package/src/proxy/sessions.ts +1 -1
  57. package/src/proxy/sources.ts +35 -0
  58. package/src/proxy/state.ts +2 -20
  59. package/src/proxy/window.ts +3 -33
  60. package/src/transcript/format.ts +1 -2
  61. package/src/transcript/subagents.ts +3 -3
  62. /package/src/{proxy → core}/estimate.ts +0 -0
  63. /package/src/{proxy → core}/fingerprint.ts +0 -0
@@ -0,0 +1,31 @@
1
+ export type Block = {
2
+ type: string;
3
+ [key: string]: any;
4
+ };
5
+ export type Message = {
6
+ role: string;
7
+ content: string | Block[];
8
+ };
9
+ export type Body = {
10
+ model?: string;
11
+ system?: string | Block[];
12
+ messages: Message[];
13
+ tools?: unknown[];
14
+ metadata?: {
15
+ user_id?: string;
16
+ };
17
+ [key: string]: any;
18
+ };
19
+ export declare function contentBlocks(content: unknown): Block[];
20
+ export declare function blocks(message: Message): Block[];
21
+ export declare function textOf(message: Message): string;
22
+ export declare function resultText(block: Block): string;
23
+ export declare function withoutCacheControl(block: Block): Block;
24
+ export declare function clean(message: Message): Message;
25
+ export declare function sha256(text: string): string;
26
+ export declare function shortHash(json: string, chars: number): string;
27
+ export declare function quickHash(text: string): string;
28
+ export declare function truncate(text: string, max: number): string;
29
+ export declare function clip(value: unknown, max: number): string;
30
+ export declare function wellFormed(_key: string, value: unknown): unknown;
31
+ export declare function describeToolCall(block: Block): string;
@@ -0,0 +1,20 @@
1
+ import { type Block, type Message } from "../content.js";
2
+ export interface EvidenceOptions {
3
+ linesPerCall?: number;
4
+ lineChars?: number;
5
+ turnChars?: number;
6
+ scanLines?: number;
7
+ minScore?: number;
8
+ allTools?: boolean;
9
+ ranked?: boolean;
10
+ labels?: boolean;
11
+ callFloor?: number;
12
+ }
13
+ export declare const REREADABLE_TOOLS: Set<string>;
14
+ export declare function isSalient(line: string): boolean;
15
+ export declare function salientLines(text: string, options?: EvidenceOptions): string[];
16
+ export declare function toolPairs(turn: Message[]): Array<{
17
+ call: Block;
18
+ result: Block;
19
+ }>;
20
+ export declare function turnEvidence(turn: Message[], options?: EvidenceOptions): string | null;
@@ -0,0 +1,11 @@
1
+ import { type Message } from "../content.js";
2
+ import { type RecallChunk } from "../recall/index.js";
3
+ export interface FoldedTurn {
4
+ user: string;
5
+ evidence: string;
6
+ reply: string;
7
+ }
8
+ export declare const FOLD_CAP_CHARS = 400000;
9
+ export declare function foldedTurns(messages: Message[]): FoldedTurn[];
10
+ export declare function foldedView(messages: Message[], cap?: number): string;
11
+ export declare function sourceChunks(messages: Message[], from: string, users?: boolean): RecallChunk[];
@@ -0,0 +1,20 @@
1
+ import { type Block, type Body, type Message } from "../content.js";
2
+ import { type ReduceOptions } from "./turns.js";
3
+ export interface CompactOptions extends ReduceOptions {
4
+ keepTurns: number;
5
+ capChars?: number;
6
+ guide: string | null;
7
+ omittedBefore?: number;
8
+ reduce?: (turn: Message[], options: ReduceOptions) => Message[];
9
+ pinned?: ReadonlySet<string>;
10
+ }
11
+ export declare const countPinned: (turns: Message[][], pinned: ReadonlySet<string>) => number;
12
+ export declare function trimMessages(messages: Message[], options?: ReduceOptions): Message[];
13
+ export declare const CARRIED_CHARS = 80000;
14
+ export declare const foldsOpening: (opening: Message[], keptFrom: number) => boolean;
15
+ export declare function compactMessages(messages: Message[], cutIndex: number, options: CompactOptions): Message[];
16
+ export declare function capTurns(messages: Message[], options: CompactOptions): Message[];
17
+ export declare function tailMessages(messages: Message[], from: number, guide: string | null): Message[];
18
+ export declare function countToolResults(messages: Message[], from: number): number;
19
+ export declare function clearToolResults(messages: Message[], from: number, count: number, placeholder: string): Message[];
20
+ export declare function appendSystem(system: Body["system"], text: string): Block[];
@@ -0,0 +1,14 @@
1
+ import { type Message } from "../content.js";
2
+ export interface ReduceOptions {
3
+ evidence?: boolean;
4
+ }
5
+ export declare const isStaleNote: (text: unknown) => boolean;
6
+ export declare function isPrompt(message: Message): boolean;
7
+ export declare function splitTurns(messages: Message[]): {
8
+ preamble: Message[];
9
+ turns: Message[][];
10
+ };
11
+ export declare function turnFingerprint(turn: Message[]): string;
12
+ export declare function isHarness(message: Message): boolean;
13
+ export declare function hasContent(message: Message): boolean;
14
+ export declare function reduceTurn(turn: Message[], options?: ReduceOptions): Message[];
@@ -0,0 +1,24 @@
1
+ interface NoticeCounts {
2
+ omitted: number;
3
+ kept: number;
4
+ pinned?: number;
5
+ guide: string | null;
6
+ }
7
+ export declare const SYSTEM_PROMPT: string;
8
+ export declare function handoffBlock(label: string, text: string): string;
9
+ export declare function recalledContext(entries: string[], fromEarlierSessions: boolean): string;
10
+ export declare function rerankQuestion(query: string): string;
11
+ export declare function toolEvidence(entries: string[]): string;
12
+ export declare function interruptedReply(lastWords: string | undefined, calls: string[]): string;
13
+ export declare function clearedOutput(dir: string | null): string;
14
+ export declare function clearedInput(kept: string, cleared: number): string;
15
+ export declare function compactionNotice({ omitted, kept, pinned, guide }: NoticeCounts): string;
16
+ export declare function truncationNotice({ omitted, kept, guide }: NoticeCounts): string;
17
+ export declare function trimInstructions(guide: string | null): string;
18
+ export declare function searchOnlyInstructions(guide: string): string;
19
+ export declare function searchGuide(ref: {
20
+ mode: string;
21
+ jsonl: string;
22
+ dir: string;
23
+ }): string;
24
+ export {};
@@ -0,0 +1,44 @@
1
+ import { type Message } from "../content.js";
2
+ export interface RecallChunk {
3
+ turn: number;
4
+ from?: string;
5
+ call: string;
6
+ lines: string[];
7
+ terms: string[];
8
+ }
9
+ export interface RecallOptions {
10
+ windowLines?: number;
11
+ perQuery?: number;
12
+ minTerms?: number;
13
+ maxChars?: number;
14
+ maxCharsMulti?: number;
15
+ narrative?: boolean;
16
+ callWeight?: number;
17
+ salientExcerpt?: boolean;
18
+ candidates?: number;
19
+ }
20
+ export interface RecallPick {
21
+ index: number;
22
+ query: Set<string>;
23
+ }
24
+ export type Reranker = (query: string, chunks: RecallChunk[], candidates: number[]) => Promise<number[]>;
25
+ export declare function terms(text: string): string[];
26
+ export declare function recallChunks(messages: Message[], keptIds: Map<string, string>, options?: RecallOptions): RecallChunk[];
27
+ interface RankedChunk {
28
+ index: number;
29
+ score: number;
30
+ matched: number;
31
+ }
32
+ export declare function warmIndex(chunks: RecallChunk[], until: number): boolean;
33
+ export declare function rank(query: string[], chunks: RecallChunk[], minTerms?: number): RankedChunk[];
34
+ export declare const identityReranker: Reranker;
35
+ export declare function pickRecallWith(prompt: string, chunks: RecallChunk[], rerank: Reranker, options?: RecallOptions): Promise<RecallPick[]>;
36
+ export declare function renderRecall(prompt: string, chunks: RecallChunk[], picks: RecallPick[], options?: RecallOptions): string | null;
37
+ export declare function recallFor(prompt: string, chunks: RecallChunk[], options?: RecallOptions): string | null;
38
+ export declare function recallForWith(prompt: string, chunks: RecallChunk[], rerank: Reranker, options?: RecallOptions): Promise<string | null>;
39
+ export declare function livePrompt(messages: Message[]): {
40
+ index: number;
41
+ text: string;
42
+ } | null;
43
+ export declare function withRecall(messages: Message[], fingerprint: (message: Message) => string, recalls: Record<string, string>): Message[];
44
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { Reranker } from "./index.js";
2
+ export declare function orderByProbability(candidates: number[], probabilities: Record<string, number>): number[];
3
+ export declare function jevReranker(model: string, key: string, endpoint?: string, onError?: (reason: string) => void): Reranker;
@@ -0,0 +1,32 @@
1
+ import { type Body, type Message } from "../context/content.js";
2
+ import { type CompactOptions } from "../context/fold/strategies.js";
3
+ import type { CoreConfig } from "./config.js";
4
+ import { type Estimator } from "./estimate.js";
5
+ import type { RewriteNote } from "./rewrite.js";
6
+ import { type ThreadState } from "./state.js";
7
+ export interface CompactInput {
8
+ body: Body;
9
+ config: CoreConfig;
10
+ state: ThreadState;
11
+ window: number | null;
12
+ guide: string | null;
13
+ transcriptDir?: string | null;
14
+ mayCompact: boolean;
15
+ omittedBefore?: number;
16
+ decorate?: (messages: Message[]) => Message[];
17
+ reduce?: CompactOptions["reduce"];
18
+ }
19
+ export interface CompactResult {
20
+ messages: Message[];
21
+ stateChanged: boolean;
22
+ note: RewriteNote;
23
+ }
24
+ export type StuckSizes = ReturnType<typeof stuckSizes>;
25
+ declare function stuckSizes(messages: Message[], headEnd: number, liveFrom: number, size: Estimator): {
26
+ fixed: number;
27
+ head: number;
28
+ folded: number;
29
+ live: number;
30
+ };
31
+ export declare function compact({ body, config, state, window, guide, transcriptDir, mayCompact, omittedBefore, decorate, reduce }: CompactInput): CompactResult;
32
+ export {};
@@ -0,0 +1,33 @@
1
+ export type Mode = "off" | "compact" | "default";
2
+ interface EvalConfig {
3
+ recallOptions?: {
4
+ maxChars?: number;
5
+ maxCharsMulti?: number;
6
+ perQuery?: number;
7
+ };
8
+ strategy?: "tail" | "guide" | "trim";
9
+ rolling?: {
10
+ keep: number;
11
+ budget: number;
12
+ };
13
+ forceCut?: boolean;
14
+ trustHeaders?: boolean;
15
+ evidence?: boolean;
16
+ recall?: boolean;
17
+ rerank?: {
18
+ model: string;
19
+ candidates?: number;
20
+ endpoint?: string;
21
+ };
22
+ }
23
+ export interface CoreConfig {
24
+ mode: Mode;
25
+ compactAt: number;
26
+ keepTurns: number | "all";
27
+ keep: number;
28
+ budget: number;
29
+ turnCap: number | "off";
30
+ eval?: EvalConfig;
31
+ }
32
+ export declare const CORE_DEFAULTS: CoreConfig;
33
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { Body, Message } from "../context/content.js";
2
+ export interface Estimator {
3
+ of: (messages: Message[]) => number;
4
+ fixed: number;
5
+ }
6
+ export declare const DEFAULT_RATIO: number;
7
+ export declare function sizeOf(body: Pick<Body, "system" | "tools" | "messages">): number;
8
+ export declare function estimator(body: Body, ratio: number): Estimator;
9
+ export declare function targetSize(size: Estimator, window: number): number;
@@ -0,0 +1,10 @@
1
+ import { type Body, type Message } from "../context/content.js";
2
+ export interface ContextFingerprint {
3
+ system: string;
4
+ tools: string;
5
+ skills: string[];
6
+ given?: ContextFingerprint;
7
+ }
8
+ export declare const isInjected: (text: unknown) => boolean;
9
+ export declare function messageFingerprint(message: Message): string;
10
+ export declare function contextFingerprint(body: Body): ContextFingerprint;
@@ -0,0 +1,18 @@
1
+ import type { Message } from "../context/content.js";
2
+ import { type ThreadStore } from "./state.js";
3
+ export interface FoldTarget {
4
+ store: ThreadStore;
5
+ threadId: string;
6
+ messages: Message[];
7
+ }
8
+ export interface FoldOptions {
9
+ at?: number | "latest";
10
+ pin?: number[];
11
+ }
12
+ export interface Folded {
13
+ threadKey: string;
14
+ cutTurn: number | null;
15
+ pinned: number[];
16
+ }
17
+ export declare function foldThread(target: FoldTarget, { at, pin }?: FoldOptions): Folded;
18
+ export declare function pinTurns(target: FoldTarget, indices: number[], pinned?: boolean): Folded;
@@ -0,0 +1,24 @@
1
+ import { type Body } from "../context/content.js";
2
+ import type { Reranker } from "../context/recall/index.js";
3
+ import { type CoreConfig } from "./config.js";
4
+ import { type Rewrite, type RewriteNote, type ThreadSources } from "./rewrite.js";
5
+ import type { ThreadStore } from "./state.js";
6
+ import { type WindowLookup } from "./window.js";
7
+ export type ForwardNote = RewriteNote | Record<string, unknown>;
8
+ export type Prepared = Omit<Rewrite, "note"> & {
9
+ note: ForwardNote;
10
+ };
11
+ export interface ForwarderOptions {
12
+ store: ThreadStore;
13
+ upstream?: string;
14
+ config?: CoreConfig;
15
+ window?: number | null | WindowLookup;
16
+ threadIdOf?: (request: Request, body: Body) => string | null;
17
+ sources?: (threadId: string, request: Request, body: Body) => ThreadSources | undefined;
18
+ reranker?: Reranker;
19
+ prepare?: (request: Request, body: Body, mayCompact: boolean) => Promise<Prepared>;
20
+ record?: (entry: Record<string, unknown>) => void;
21
+ countTokensTimeoutMs?: number;
22
+ }
23
+ export declare function claudeCodeSessionId(headers: Headers, body: Body): string | null;
24
+ export declare function createForwarder(options: ForwarderOptions): (request: Request) => Promise<Response>;
@@ -0,0 +1,10 @@
1
+ import { type Message } from "../context/content.js";
2
+ import type { RecallChunk } from "../context/recall/index.js";
3
+ import type { ThreadSources } from "./rewrite.js";
4
+ import type { Handoff, ThreadState } from "./state.js";
5
+ export declare const continueToken: (id: string) => string;
6
+ export declare function continueIdOf(message: Message): string | null;
7
+ export declare function activeHandoffs(handoffs?: Record<string, Handoff | null>): Record<string, Handoff>;
8
+ export declare function attachHandoffs(messages: Message[], sources: ThreadSources, state: ThreadState): boolean;
9
+ export declare function withHandoffs(messages: Message[], handoffs: Record<string, Handoff>): Message[];
10
+ export declare function handoffChunks(handoffs: Record<string, Handoff>, sources: ThreadSources): RecallChunk[];
@@ -0,0 +1,14 @@
1
+ export type { Block, Body, Message } from "../context/content.js";
2
+ export type { RecallChunk, Reranker } from "../context/recall/index.js";
3
+ export { jevReranker } from "../context/recall/rerank.js";
4
+ export type { StuckSizes } from "./compaction.js";
5
+ export { CORE_DEFAULTS, type CoreConfig, type Mode } from "./config.js";
6
+ export { type Folded, type FoldOptions, type FoldTarget, foldThread, pinTurns } from "./fold.js";
7
+ export { claudeCodeSessionId, createForwarder, type ForwarderOptions, type ForwardNote, type Prepared } from "./forward.js";
8
+ export { continueToken } from "./handoff.js";
9
+ export { type Rewrite, type RewriteInput, type RewriteNote, rewrite, rewriteAsync, type ThreadSources, threadKeyOf } from "./rewrite.js";
10
+ export { memoryStore, type ThreadState, type ThreadStore } from "./state.js";
11
+ export { listSubagentRecall, type Subagent } from "./subagents.js";
12
+ export { renderTranscriptFiles, type TranscriptOptions, transcriptGuide } from "./transcript.js";
13
+ export { inputTokens, recordOverflow, recordUsage, type Usage, watchUsage } from "./usage.js";
14
+ export { createWindowLookup, type WindowLookup } from "./window.js";
@@ -0,0 +1,8 @@
1
+ import { type Reranker } from "../context/recall/index.js";
2
+ import type { Rewrite, RewriteInput } from "./rewrite.js";
3
+ export declare const wantsRecall: (input: RewriteInput) => boolean;
4
+ export declare const activeRecalls: (recalls?: Record<string, string>) => {
5
+ [k: string]: string;
6
+ };
7
+ export declare function applyRecall(input: RewriteInput, result: Rewrite): Rewrite;
8
+ export declare function prefetchFor(input: RewriteInput, result: Rewrite, rerank: Reranker): Promise<number | null>;
@@ -0,0 +1,63 @@
1
+ import type { Body, Message } from "../context/content.js";
2
+ import { type RecallChunk, type Reranker } from "../context/recall/index.js";
3
+ import { type StuckSizes } from "./compaction.js";
4
+ import type { CoreConfig } from "./config.js";
5
+ import type { ThreadStore } from "./state.js";
6
+ export interface ThreadSources {
7
+ guide?: string | null;
8
+ transcriptDir?: string | null;
9
+ readHistory?: () => Message[];
10
+ listSubagentChunks?: () => RecallChunk[];
11
+ findHandoff?: (id: string) => {
12
+ label: string;
13
+ source: string;
14
+ } | null;
15
+ readHandoff?: (source: string) => Message[];
16
+ }
17
+ export interface RewriteInput {
18
+ body: Body;
19
+ threadId: string | null;
20
+ config: CoreConfig;
21
+ store: ThreadStore;
22
+ sources?: ThreadSources;
23
+ window: number | null;
24
+ mayCompact: boolean;
25
+ omittedBefore?: number;
26
+ }
27
+ export type RewriteNote = {
28
+ action: "pass" | "full" | "compact" | "guide" | "trim" | "tail";
29
+ compacted?: boolean;
30
+ actions?: string[];
31
+ cutTurn?: number | null;
32
+ omitted?: number;
33
+ folded?: number;
34
+ pinned?: number;
35
+ host?: boolean;
36
+ keep?: number;
37
+ cleared?: number;
38
+ stuck?: StuckSizes;
39
+ turns?: number;
40
+ keptTurns?: number;
41
+ messagesIn?: number;
42
+ messagesOut?: number;
43
+ estimate?: number;
44
+ window?: number | null;
45
+ fit?: "recut" | "bare" | "over";
46
+ fitEstimate?: number;
47
+ recalled?: number;
48
+ handoff?: number;
49
+ handoffFrom?: string;
50
+ };
51
+ export interface Rewrite {
52
+ body: Body;
53
+ threadKey: string | null;
54
+ note: RewriteNote;
55
+ }
56
+ export declare function threadKeyOf(threadId: string, messages: Message[]): string | null;
57
+ export declare function rewrite(input: RewriteInput, before?: Rewrite): Rewrite;
58
+ export declare function prefetchRecall(input: RewriteInput, rerank: Reranker): Promise<{
59
+ reranked: boolean;
60
+ rerankError: null;
61
+ recalled: number;
62
+ } | null>;
63
+ export declare function rewriteAsync(input: RewriteInput, rerank?: Reranker): Promise<Rewrite>;
@@ -0,0 +1,22 @@
1
+ export interface Handoff {
2
+ label: string;
3
+ source: string;
4
+ text: string;
5
+ }
6
+ export interface ThreadState {
7
+ handoffs?: Record<string, Handoff | null>;
8
+ cut?: string;
9
+ keep?: number;
10
+ cleared?: number;
11
+ stuck?: number;
12
+ host?: boolean;
13
+ pins?: string[];
14
+ ratio?: number;
15
+ recalls?: Record<string, string>;
16
+ }
17
+ export interface ThreadStore {
18
+ read: (key: string) => ThreadState;
19
+ save: (key: string, state: ThreadState) => void;
20
+ }
21
+ export declare function memoryStore(initial?: Record<string, ThreadState>): ThreadStore;
22
+ export declare function resetCut(state: ThreadState): void;
@@ -0,0 +1,10 @@
1
+ import { type Message } from "../context/content.js";
2
+ import { type RecallChunk } from "../context/recall/index.js";
3
+ export interface Subagent {
4
+ description: string;
5
+ messages: Message[];
6
+ toolUseId?: string;
7
+ }
8
+ export declare function launchTurnOf(parentMessages: Message[], toolUseId: string | undefined): number;
9
+ export declare function subagentRecall(messages: Message[], description: string, parentTurn: number): RecallChunk[];
10
+ export declare function listSubagentRecall(parentMessages: Message[], subagents: Subagent[]): RecallChunk[];
@@ -0,0 +1,9 @@
1
+ import { type Message } from "../context/content.js";
2
+ import { type TranscriptFormat } from "../transcript/parse.js";
3
+ import { type Subagent } from "./subagents.js";
4
+ export interface TranscriptOptions {
5
+ format?: TranscriptFormat;
6
+ subagents?: Subagent[];
7
+ }
8
+ export declare function renderTranscriptFiles(messages: Message[], { format, subagents }?: TranscriptOptions): Record<string, string>;
9
+ export declare const transcriptGuide: (dir: string, format?: TranscriptFormat) => string;
@@ -0,0 +1,7 @@
1
+ import type { Body } from "../context/content.js";
2
+ import type { ThreadStore } from "./state.js";
3
+ export type Usage = Record<string, number>;
4
+ export declare function watchUsage(response: Response, onUsage: (usage: Usage) => void): Response;
5
+ export declare function inputTokens(usage: Usage): number;
6
+ export declare function recordUsage(store: ThreadStore, threadKey: string, sent: Body | number, usage: Usage): boolean;
7
+ export declare function recordOverflow(store: ThreadStore, threadKey: string, sent: Body | number, errorText: string): number | null;
@@ -0,0 +1,5 @@
1
+ export type WindowLookup = (model: unknown, requestHeaders: Headers, upstream?: string) => Promise<number | null>;
2
+ export declare function createWindowLookup({ known, onLearn }?: {
3
+ known?: Map<string, number>;
4
+ onLearn?: (windows: Map<string, number>) => void;
5
+ }): WindowLookup;
@@ -0,0 +1,16 @@
1
+ import type { TranscriptFormat, Turn } from "./parse.js";
2
+ export interface SubagentRecord {
3
+ run: {
4
+ description: string;
5
+ };
6
+ turns: Turn[];
7
+ parentTurn: number;
8
+ file: string;
9
+ }
10
+ export declare function turnFile(turn: Turn, format: TranscriptFormat): string;
11
+ export declare function subagentFile(parentTurn: number, k: number, format: TranscriptFormat): string;
12
+ export declare function renderMarkdown(turn: Turn): string;
13
+ export declare function renderXml(turn: Turn): string;
14
+ export declare function renderIndex(turns: Turn[], format: TranscriptFormat, records?: SubagentRecord[]): string;
15
+ export declare function renderSubagentMarkdown(record: SubagentRecord): string;
16
+ export declare function renderSubagentXml(record: SubagentRecord): string;
@@ -0,0 +1,45 @@
1
+ import { type Block, type Message } from "../context/content.js";
2
+ export interface SessionEntry {
3
+ type?: string;
4
+ subtype?: string;
5
+ isSidechain?: boolean;
6
+ isMeta?: boolean;
7
+ isCompactSummary?: boolean;
8
+ agentId?: string;
9
+ timestamp?: string;
10
+ cwd?: string;
11
+ aiTitle?: string;
12
+ message?: {
13
+ role: string;
14
+ content: string | Block[];
15
+ };
16
+ }
17
+ export type TranscriptFormat = "markdown" | "xml";
18
+ export interface ToolPart {
19
+ kind: "tool";
20
+ n: number;
21
+ id: string;
22
+ name: string;
23
+ prompt?: string;
24
+ record?: string;
25
+ call: string;
26
+ body: string;
27
+ output: string;
28
+ error: boolean;
29
+ }
30
+ type TurnPart = {
31
+ kind: "say";
32
+ text: string;
33
+ } | ToolPart;
34
+ export interface Turn {
35
+ number: number;
36
+ time: string;
37
+ prompt: string;
38
+ parts: TurnPart[];
39
+ final: string;
40
+ calls: number;
41
+ }
42
+ export declare function parseJsonl<T = SessionEntry>(text: string): T[];
43
+ export declare function entryMessages(entries: SessionEntry[]): Message[];
44
+ export declare function parseTurns(entries: SessionEntry[], sidechain?: boolean | "any"): Turn[];
45
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chroxify/eunoe",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "Context management for Claude Code that never forgets what matters.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -18,12 +18,21 @@
18
18
  "proxy"
19
19
  ],
20
20
  "type": "module",
21
+ "exports": {
22
+ ".": {
23
+ "bun": "./src/core/index.ts",
24
+ "types": "./dist/types/core/index.d.ts",
25
+ "default": "./dist/core/index.js"
26
+ },
27
+ "./package.json": "./package.json"
28
+ },
21
29
  "bin": {
22
30
  "eunoe": "src/cli/main.ts",
23
31
  "ee": "src/cli/main.ts"
24
32
  },
25
33
  "files": [
26
34
  "src",
35
+ "dist",
27
36
  "README.md",
28
37
  "LICENSE"
29
38
  ],
@@ -34,11 +43,14 @@
34
43
  "start": "bun src/cli/main.ts serve",
35
44
  "test": "bun test",
36
45
  "check-types": "tsc --noEmit -p .",
46
+ "build:core": "bun scripts/build-core.ts",
47
+ "smoke:workers": "bun run build:core && bun build examples/durable-object.ts --target=browser --format=esm --outfile dist/workers/durable-object.js && node test/workers-smoke.mjs",
37
48
  "lint": "biome check . && bun lint:conventions",
38
49
  "lint:conventions": "bun scripts/lint-conventions.ts",
39
50
  "format": "biome check .",
40
51
  "format:fix": "biome check . --write",
41
- "prepare": "husky"
52
+ "prepare": "husky",
53
+ "prepublishOnly": "bun run build:core"
42
54
  },
43
55
  "devDependencies": {
44
56
  "@babel/parser": "7.27.0",
@@ -47,6 +59,7 @@
47
59
  "husky": "9.1.7",
48
60
  "knip": "6.41.0",
49
61
  "lint-staged": "16.4.0",
62
+ "miniflare": "4.20260730.0",
50
63
  "typescript": "^7.0.2"
51
64
  },
52
65
  "publishConfig": {
@@ -1,4 +1,5 @@
1
- import { compactionOwner, MODES, type Mode, readConfig, saveConfig } from "../../config"
1
+ import { compactionOwner, MODES, readConfig, saveConfig } from "../../config"
2
+ import type { Mode } from "../../core/config"
2
3
  import type { Command } from "../command"
3
4
  import { editSettings, withCompactionOwner } from "../proxy/claude-settings"
4
5
  import { routedDirs } from "../proxy/inspect"
@@ -1,7 +1,7 @@
1
1
  import path from "node:path"
2
2
  import { type Config, modeFor, overrides, readConfig } from "../../config"
3
3
  import { paths } from "../../config/paths"
4
- import { rerankKey } from "../../context/recall/rerank"
4
+ import { rerankKey } from "../../proxy/rewrite"
5
5
  import type { Health } from "../../proxy/server"
6
6
  import { seenSessions } from "../../proxy/sessions"
7
7
  import { VERSION } from "../../version"
@@ -1,4 +1,4 @@
1
- import { DEFAULT_RATIO } from "../../proxy/estimate"
1
+ import { DEFAULT_RATIO } from "../../core/estimate"
2
2
  import { NATIVE_SUMMARY_CHARS, REPLAY_NATIVE_COMPACT_AT } from "../replay"
3
3
  import type { RequestRecord } from "./inspect"
4
4
 
@@ -1,9 +1,9 @@
1
1
  import type { Config } from "../../config"
2
2
  import type { Body, Message } from "../../context/content"
3
3
  import { isPrompt, type ReduceOptions, reduceTurn, splitTurns, turnFingerprint } from "../../context/fold/turns"
4
- import { compact } from "../../proxy/compaction"
5
- import { DEFAULT_RATIO, sizeOf } from "../../proxy/estimate"
6
- import type { ThreadState } from "../../proxy/state"
4
+ import { compact } from "../../core/compaction"
5
+ import { DEFAULT_RATIO, sizeOf } from "../../core/estimate"
6
+ import type { ThreadState } from "../../core/state"
7
7
 
8
8
  export interface ReplayOptions {
9
9
  config: Config
@@ -2,8 +2,8 @@ import { spawnSync } from "node:child_process"
2
2
  import { claudeConfigDirs, readConfig } from "../../config"
3
3
  import { FOLD_CAP_CHARS, foldedView, sourceChunks } from "../../context/fold"
4
4
  import { recallFor } from "../../context/recall"
5
- import { DEFAULT_RATIO } from "../../proxy/estimate"
6
- import { continueToken } from "../../proxy/handoff"
5
+ import { DEFAULT_RATIO } from "../../core/estimate"
6
+ import { continueToken } from "../../core/handoff"
7
7
  import { seenSessions } from "../../proxy/sessions"
8
8
  import { isSessionId } from "../../transcript/locate"
9
9
  import { subagentChunks } from "../../transcript/subagents"