@seanhogg/builderforce-memory 2026.10.22 → 2026.10.24

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 (42) hide show
  1. package/dist/handoff/index.d.ts +1 -0
  2. package/dist/handoff/index.d.ts.map +1 -1
  3. package/dist/handoff/index.js +1 -0
  4. package/dist/handoff/index.js.map +1 -1
  5. package/dist/handoff/pack.d.ts.map +1 -1
  6. package/dist/handoff/pack.js +30 -3
  7. package/dist/handoff/pack.js.map +1 -1
  8. package/dist/handoff/volatile.d.ts +32 -0
  9. package/dist/handoff/volatile.d.ts.map +1 -0
  10. package/dist/handoff/volatile.js +42 -0
  11. package/dist/handoff/volatile.js.map +1 -0
  12. package/dist/working/consolidate.d.ts +39 -0
  13. package/dist/working/consolidate.d.ts.map +1 -0
  14. package/dist/working/consolidate.js +179 -0
  15. package/dist/working/consolidate.js.map +1 -0
  16. package/dist/working/index.d.ts +24 -0
  17. package/dist/working/index.d.ts.map +1 -0
  18. package/dist/working/index.js +23 -0
  19. package/dist/working/index.js.map +1 -0
  20. package/dist/working/rank.d.ts +7 -0
  21. package/dist/working/rank.d.ts.map +1 -0
  22. package/dist/working/rank.js +12 -0
  23. package/dist/working/rank.js.map +1 -0
  24. package/dist/working/types.d.ts +33 -0
  25. package/dist/working/types.d.ts.map +1 -0
  26. package/dist/working/types.js +5 -0
  27. package/dist/working/types.js.map +1 -0
  28. package/dist/working/workingMemory.d.ts +45 -0
  29. package/dist/working/workingMemory.d.ts.map +1 -0
  30. package/dist/working/workingMemory.js +103 -0
  31. package/dist/working/workingMemory.js.map +1 -0
  32. package/package.json +7 -3
  33. package/src/handoff/handoff.test.ts +28 -1
  34. package/src/handoff/index.ts +1 -0
  35. package/src/handoff/pack.ts +30 -4
  36. package/src/handoff/volatile.ts +46 -0
  37. package/src/working/consolidate.ts +181 -0
  38. package/src/working/index.ts +24 -0
  39. package/src/working/rank.ts +10 -0
  40. package/src/working/types.ts +32 -0
  41. package/src/working/working.test.ts +120 -0
  42. package/src/working/workingMemory.ts +103 -0
@@ -14,5 +14,6 @@
14
14
  export { packHandoff } from './pack.js';
15
15
  export { handoffBudget, defaultEstimateTokens, messageTokens, tokensOf } from './budget.js';
16
16
  export { handoffLine, elisionMarker } from './note.js';
17
+ export { VOLATILE_TAIL_TAG, volatileTail, isVolatileTail, isVolatileContent } from './volatile.js';
17
18
  export type { HandoffMessage, HandoffPackInput, HandoffPack, HandoffBudgetInput, TokenEstimator, } from './types.js';
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handoff/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvD,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,cAAc,GACf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handoff/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnG,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,cAAc,GACf,MAAM,YAAY,CAAC"}
@@ -14,4 +14,5 @@
14
14
  export { packHandoff } from './pack.js';
15
15
  export { handoffBudget, defaultEstimateTokens, messageTokens, tokensOf } from './budget.js';
16
16
  export { handoffLine, elisionMarker } from './note.js';
17
+ export { VOLATILE_TAIL_TAG, volatileTail, isVolatileTail, isVolatileContent } from './volatile.js';
17
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/handoff/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/handoff/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../src/handoff/pack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAkB,WAAW,EAAE,gBAAgB,EAAkB,MAAM,YAAY,CAAC;AA0FhG,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CA6D/E"}
1
+ {"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../src/handoff/pack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAkB,WAAW,EAAE,gBAAgB,EAAkB,MAAM,YAAY,CAAC;AAkGhG,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAoB/E"}
@@ -25,6 +25,7 @@
25
25
  import { defaultEstimateTokens, handoffBudget, messageTokens, tokensOf } from './budget.js';
26
26
  import { buildNote, composeNote, elisionMarker, handoffLine, noteTokens } from './note.js';
27
27
  import { segmentTranscript } from './segments.js';
28
+ import { isVolatileTail } from './volatile.js';
28
29
  /** Length of the leading run of `system` messages. */
29
30
  function leadingSystemCount(all) {
30
31
  let n = 0;
@@ -36,13 +37,20 @@ function leadingSystemCount(all) {
36
37
  function noteRole(next) {
37
38
  return next === undefined || next.role === 'assistant' ? 'user' : 'assistant';
38
39
  }
39
- /** Index of the last `user` message, or -1. */
40
+ /** Index of the last `user` message that is a real directive (never a volatile tail), or -1. */
40
41
  function latestDirectiveIndex(convo) {
41
42
  for (let i = convo.length - 1; i >= 0; i--)
42
- if (convo[i].role === 'user')
43
+ if (convo[i].role === 'user' && !isVolatileTail(convo[i]))
43
44
  return i;
44
45
  return -1;
45
46
  }
47
+ /** Where the trailing run of volatile tails begins (`messages.length` when there is none). */
48
+ function trailingVolatileStart(messages) {
49
+ let i = messages.length;
50
+ while (i > 0 && isVolatileTail(messages[i - 1]))
51
+ i -= 1;
52
+ return i;
53
+ }
46
54
  /** Convo indices the caller pinned (pinnable roles only), excluding the directive. */
47
55
  function pinnedIndices(convo, prefixLen, directiveIdx, pinned) {
48
56
  if (!pinned)
@@ -94,8 +102,27 @@ function result(messages, dropped, estimate, extra = {}) {
94
102
  export async function packHandoff(input) {
95
103
  const estimate = input.estimateTokens ?? defaultEstimateTokens;
96
104
  const budget = handoffBudget(input);
97
- const all = input.messages;
98
105
  // Under budget: hand the transcript over untouched.
106
+ if (tokensOf(input.messages, estimate) <= budget)
107
+ return result(input.messages.slice(), 0, estimate);
108
+ // The volatile tail (`volatile.ts`) is set aside, the history packed into what is
109
+ // left, and the tail put back LAST — never the directive, never in the middle. When
110
+ // the history needs the whole budget, the tail is what goes: it is a per-turn aid,
111
+ // the history is the work.
112
+ const cut = trailingVolatileStart(input.messages);
113
+ const volatile = input.messages.slice(cut);
114
+ const volatileTokens = tokensOf(volatile, estimate);
115
+ if (volatile.length > 0) {
116
+ const history = input.messages.slice(0, cut);
117
+ const withTail = await packHistory({ ...input, messages: history }, budget - volatileTokens, estimate);
118
+ if (withTail.fits)
119
+ return result([...withTail.messages, ...volatile], withTail.dropped, estimate, withTail);
120
+ return packHistory({ ...input, messages: history }, budget, estimate);
121
+ }
122
+ return packHistory(input, budget, estimate);
123
+ }
124
+ async function packHistory(input, budget, estimate) {
125
+ const all = input.messages;
99
126
  if (tokensOf(all, estimate) <= budget)
100
127
  return result(all.slice(), 0, estimate);
101
128
  const prefixLen = leadingSystemCount(all);
@@ -1 +1 @@
1
- {"version":3,"file":"pack.js","sourceRoot":"","sources":["../../src/handoff/pack.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pack.js","sourceRoot":"","sources":["../../src/handoff/pack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The per-request VOLATILE tail — everything that changes turn to turn (the run's
3
+ * working-memory brief, the affect block, the budget line, task state) in ONE `user`
4
+ * message appended AFTER the history and opened by {@link VOLATILE_TAIL_TAG}.
5
+ *
6
+ * Two readers depend on that one convention, which is why it lives here and every host
7
+ * builds its tail with {@link volatileTail}:
8
+ *
9
+ * - The gateway's prompt caching places the history breakpoint BEFORE a tagged block,
10
+ * so a tail that changes every turn never becomes the cached prefix. An untagged
11
+ * trailing block is where the breakpoint lands — and then every turn re-bills the
12
+ * whole transcript.
13
+ * - {@link packHandoff} never treats a tagged block as "the latest user directive"
14
+ * and keeps it LAST: an untagged one would be protected in place of the user's real
15
+ * request, which could then be dropped into the summarised middle.
16
+ *
17
+ * A trailing user turn is valid after a tool-result turn on both the OpenAI and the
18
+ * Anthropic shape (Anthropic merges it into the tool_result user turn). It is built per
19
+ * request and never persisted into a transcript.
20
+ */
21
+ import type { HandoffMessage } from './types.js';
22
+ export declare const VOLATILE_TAIL_TAG = "<run-state>";
23
+ /** True when `content` (a string or a content-part array) opens with the tag. */
24
+ export declare function isVolatileContent(content: unknown): boolean;
25
+ /** True for a `user` message that is a volatile tail. */
26
+ export declare function isVolatileTail(message: Pick<HandoffMessage, 'role' | 'content'>): boolean;
27
+ /** The ONE tail message for these sections, or null when every section is empty. */
28
+ export declare function volatileTail(sections: readonly (string | null | undefined)[]): {
29
+ role: 'user';
30
+ content: string;
31
+ } | null;
32
+ //# sourceMappingURL=volatile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"volatile.d.ts","sourceRoot":"","sources":["../../src/handoff/volatile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAG/C,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAO3D;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAEzF;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAGvH"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The per-request VOLATILE tail — everything that changes turn to turn (the run's
3
+ * working-memory brief, the affect block, the budget line, task state) in ONE `user`
4
+ * message appended AFTER the history and opened by {@link VOLATILE_TAIL_TAG}.
5
+ *
6
+ * Two readers depend on that one convention, which is why it lives here and every host
7
+ * builds its tail with {@link volatileTail}:
8
+ *
9
+ * - The gateway's prompt caching places the history breakpoint BEFORE a tagged block,
10
+ * so a tail that changes every turn never becomes the cached prefix. An untagged
11
+ * trailing block is where the breakpoint lands — and then every turn re-bills the
12
+ * whole transcript.
13
+ * - {@link packHandoff} never treats a tagged block as "the latest user directive"
14
+ * and keeps it LAST: an untagged one would be protected in place of the user's real
15
+ * request, which could then be dropped into the summarised middle.
16
+ *
17
+ * A trailing user turn is valid after a tool-result turn on both the OpenAI and the
18
+ * Anthropic shape (Anthropic merges it into the tool_result user turn). It is built per
19
+ * request and never persisted into a transcript.
20
+ */
21
+ export const VOLATILE_TAIL_TAG = '<run-state>';
22
+ const VOLATILE_TAIL_CLOSE = '</run-state>';
23
+ /** True when `content` (a string or a content-part array) opens with the tag. */
24
+ export function isVolatileContent(content) {
25
+ if (typeof content === 'string')
26
+ return content.startsWith(VOLATILE_TAIL_TAG);
27
+ if (Array.isArray(content)) {
28
+ const first = content[0];
29
+ return typeof first?.text === 'string' && first.text.startsWith(VOLATILE_TAIL_TAG);
30
+ }
31
+ return false;
32
+ }
33
+ /** True for a `user` message that is a volatile tail. */
34
+ export function isVolatileTail(message) {
35
+ return message.role === 'user' && isVolatileContent(message.content);
36
+ }
37
+ /** The ONE tail message for these sections, or null when every section is empty. */
38
+ export function volatileTail(sections) {
39
+ const body = sections.map((s) => (s ?? '').trim()).filter(Boolean).join('\n\n');
40
+ return body ? { role: 'user', content: `${VOLATILE_TAIL_TAG}\n${body}\n${VOLATILE_TAIL_CLOSE}` } : null;
41
+ }
42
+ //# sourceMappingURL=volatile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"volatile.js","sourceRoot":"","sources":["../../src/handoff/volatile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAC/C,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAE3C,iFAAiF;AACjF,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAC9E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAmC,CAAC;QAC3D,OAAO,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;IACrF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAC,OAAiD;IAC9E,OAAO,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACvE,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,YAAY,CAAC,QAAgD;IAC3E,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChF,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,iBAAiB,KAAK,IAAI,KAAK,mBAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1G,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Consolidation — what survives a run, as ONE long-term memory per code AREA.
3
+ *
4
+ * A run that spends ninety turns locating the code behind a feature leaves with that
5
+ * knowledge in its transcript and nowhere else, so the next run asked about the same
6
+ * area repeats the whole search. {@link consolidate} turns the run's working memory
7
+ * into a map — the files that mattered, changed first, then reads ranked by how much
8
+ * the run leaned on them — under a key per area (the directory most of them share).
9
+ * Deterministic: built from what the run actually opened, it cannot invent a path.
10
+ *
11
+ * {@link mergeConsolidated} is the WRITE-side rule a keyed store applies, so a small run
12
+ * ADDS to an area's map instead of overwriting the twelve files an earlier one found,
13
+ * and a file this run deleted leaves the map.
14
+ */
15
+ import type { ConsolidateOptions, ConsolidatedMemory, WorkingMemorySnapshot } from './types.js';
16
+ /** Key prefix every consolidated code map carries. */
17
+ export declare const CONSOLIDATED_KEY_PREFIX = "codemap:";
18
+ /** Fewer distinct files than this, with nothing changed, is a lookup — not a map worth keeping. */
19
+ export declare const MIN_CONSOLIDATED_FILES = 3;
20
+ /** The key for an area — stable across runs, so consolidations of one area meet in one memory. */
21
+ export declare function consolidatedKey(area: string): string;
22
+ /**
23
+ * The long-term memory for one finished run, or `null` when the run touched too little
24
+ * to be worth keeping. Files the run deleted are carried as `(deleted)` lines, which
25
+ * {@link mergeConsolidated} applies as removals and never stores.
26
+ */
27
+ export declare function consolidate(snapshot: WorkingMemorySnapshot, opts?: ConsolidateOptions): ConsolidatedMemory | null;
28
+ /**
29
+ * The content to STORE when a consolidated map lands on a key that already holds one:
30
+ * the new run's entries first, then the earlier map's entries it did not touch (an
31
+ * earlier run's `changed` is restated as `changed earlier`, so this run is not credited
32
+ * with edits it never made), minus every file this run deleted, capped. Any other key,
33
+ * or no prior, stores `next` without its `(deleted)` lines.
34
+ *
35
+ * The STORE decides whether `prior` is still live — pass it only when the stored memory
36
+ * has not expired or been superseded, or a retired map comes back to life.
37
+ */
38
+ export declare function mergeConsolidated(key: string, prior: string | null | undefined, next: string): string;
39
+ //# sourceMappingURL=consolidate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidate.d.ts","sourceRoot":"","sources":["../../src/working/consolidate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEhG,sDAAsD;AACtD,eAAO,MAAM,uBAAuB,aAAa,CAAC;AAClD,mGAAmG;AACnG,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAoExC,kGAAkG;AAClG,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,qBAAqB,EAAE,IAAI,GAAE,kBAAuB,GAAG,kBAAkB,GAAG,IAAI,CA6BrH;AAqBD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAqBrG"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Consolidation — what survives a run, as ONE long-term memory per code AREA.
3
+ *
4
+ * A run that spends ninety turns locating the code behind a feature leaves with that
5
+ * knowledge in its transcript and nowhere else, so the next run asked about the same
6
+ * area repeats the whole search. {@link consolidate} turns the run's working memory
7
+ * into a map — the files that mattered, changed first, then reads ranked by how much
8
+ * the run leaned on them — under a key per area (the directory most of them share).
9
+ * Deterministic: built from what the run actually opened, it cannot invent a path.
10
+ *
11
+ * {@link mergeConsolidated} is the WRITE-side rule a keyed store applies, so a small run
12
+ * ADDS to an area's map instead of overwriting the twelve files an earlier one found,
13
+ * and a file this run deleted leaves the map.
14
+ */
15
+ import { rankByCount } from './rank.js';
16
+ /** Key prefix every consolidated code map carries. */
17
+ export const CONSOLIDATED_KEY_PREFIX = 'codemap:';
18
+ /** Fewer distinct files than this, with nothing changed, is a lookup — not a map worth keeping. */
19
+ export const MIN_CONSOLIDATED_FILES = 3;
20
+ const MAX_FILES = 12;
21
+ const MIN_AREA_SEGMENTS = 2;
22
+ const MAX_AREA_SEGMENTS = 4;
23
+ const MAX_TASK_CHARS = 200;
24
+ const MAX_KEY_CHARS = 255;
25
+ /** Dependencies, build output and the knowledge tree itself — never "where the code is". */
26
+ const NOISE_SEGMENTS = new Set(['node_modules', 'dist', '.next', '.turbo', 'coverage', '.git', '.builderforce']);
27
+ const NOISE_FILES = new Set(['pnpm-lock.yaml', 'package-lock.json', 'yarn.lock', 'bun.lockb']);
28
+ const DRIVE = /^[a-z]:\//i;
29
+ /** MSYS / Git-Bash spelling of a drive path: `/c/code/x` ≡ `C:/code/x`. */
30
+ const MSYS_DRIVE = /^\/([a-z])\//i;
31
+ function canonical(raw) {
32
+ let p = raw.trim().replace(/\\/g, '/');
33
+ const msys = MSYS_DRIVE.exec(p);
34
+ if (msys)
35
+ p = `${msys[1]}:/${p.slice(3)}`;
36
+ // Collapse `a//b` and `a/./b`; leading `./` too.
37
+ p = p.replace(/\/{2,}/g, '/').replace(/(^|\/)(\.\/)+/g, '$1');
38
+ return p;
39
+ }
40
+ /**
41
+ * A repo-relative path, or undefined when the path is not a repo file worth mapping:
42
+ * outside the root (or absolute with no root to resolve it against), escaping with
43
+ * `..`, dependencies or build output, or a lockfile. Drive paths compare
44
+ * case-insensitively, as the filesystem does.
45
+ */
46
+ function repoPath(raw, root) {
47
+ let p = canonical(raw);
48
+ if (p.startsWith('/') || DRIVE.test(p)) {
49
+ const base = root ? canonical(root).replace(/\/+$/, '') : '';
50
+ if (!base || base === '/')
51
+ return undefined;
52
+ const under = DRIVE.test(base) ? p.toLowerCase().startsWith(`${base.toLowerCase()}/`) : p.startsWith(`${base}/`);
53
+ if (!under)
54
+ return undefined;
55
+ p = p.slice(base.length + 1);
56
+ }
57
+ const segs = p.split('/');
58
+ if (!p || segs.includes('..'))
59
+ return undefined;
60
+ if (segs.some((s) => NOISE_SEGMENTS.has(s)) || NOISE_FILES.has(segs[segs.length - 1]))
61
+ return undefined;
62
+ return p;
63
+ }
64
+ function dirSegments(file) {
65
+ const parts = file.split('/');
66
+ parts.pop();
67
+ return parts;
68
+ }
69
+ /**
70
+ * The area a set of files belongs to: the DEEPEST directory (to a bounded depth, so
71
+ * keys stay stable from run to run) holding a majority of them, else the depth-2
72
+ * directory holding the most. Root-level files (DONE.md, package.json — touched by
73
+ * many unrelated runs) never decide it.
74
+ */
75
+ function areaOf(files) {
76
+ const placed = files.map(dirSegments).filter((d) => d.length > 0);
77
+ if (placed.length === 0)
78
+ return '(root)';
79
+ const prefixes = (depth) => rankByCount(placed.filter((d) => d.length >= depth).map((d) => d.slice(0, depth).join('/')));
80
+ for (let depth = MAX_AREA_SEGMENTS; depth >= MIN_AREA_SEGMENTS; depth--) {
81
+ const [top] = prefixes(depth);
82
+ if (top && top[1] * 2 > placed.length)
83
+ return top[0];
84
+ }
85
+ return prefixes(MIN_AREA_SEGMENTS)[0]?.[0] ?? prefixes(1)[0][0];
86
+ }
87
+ /** The key for an area — stable across runs, so consolidations of one area meet in one memory. */
88
+ export function consolidatedKey(area) {
89
+ return `${CONSOLIDATED_KEY_PREFIX}${area}`.slice(0, MAX_KEY_CHARS);
90
+ }
91
+ /**
92
+ * The long-term memory for one finished run, or `null` when the run touched too little
93
+ * to be worth keeping. Files the run deleted are carried as `(deleted)` lines, which
94
+ * {@link mergeConsolidated} applies as removals and never stores.
95
+ */
96
+ export function consolidate(snapshot, opts = {}) {
97
+ const keep = (raw) => repoPath(raw, opts.root);
98
+ const kept = (list) => list.map(keep).filter((p) => !!p);
99
+ const deleted = [...new Set(kept(snapshot.deleted))];
100
+ const deletedSet = new Set(deleted);
101
+ const changed = [...new Set(kept([...snapshot.created, ...snapshot.edited]))].filter((p) => !deletedSet.has(p));
102
+ const changedSet = new Set(changed);
103
+ const reads = rankByCount(kept(snapshot.read)).filter(([p]) => !changedSet.has(p) && !deletedSet.has(p));
104
+ const readCounts = new Map(reads);
105
+ const ranked = [...changed, ...reads.map(([p]) => p)];
106
+ if (ranked.length === 0 && deleted.length === 0)
107
+ return null;
108
+ if (changed.length === 0 && deleted.length === 0 && ranked.length < MIN_CONSOLIDATED_FILES)
109
+ return null;
110
+ const shown = ranked.slice(0, MAX_FILES);
111
+ const area = areaOf(ranked.length > 0 ? ranked : deleted);
112
+ const at = (opts.at ?? new Date()).toISOString().slice(0, 10);
113
+ const asked = (snapshot.task ?? '').replace(/\s+/g, ' ').trim().slice(0, MAX_TASK_CHARS);
114
+ const lines = [
115
+ `Code map for \`${area}\` (mapped ${at}${asked ? ` by a run asked: "${asked}"` : ''}).`,
116
+ 'Open these first instead of searching:',
117
+ ...shown.map((p) => {
118
+ if (changedSet.has(p))
119
+ return `- ${p} (changed)`;
120
+ const n = readCounts.get(p) ?? 1;
121
+ return `- ${p}${n > 1 ? ` (read ${n}×)` : ''}`;
122
+ }),
123
+ ...deleted.map((p) => `- ${p} (deleted)`),
124
+ ];
125
+ if (ranked.length > shown.length)
126
+ lines.push(`(+${ranked.length - shown.length} more file(s) touched)`);
127
+ return { key: consolidatedKey(area), content: lines.join('\n') };
128
+ }
129
+ /** `- <path> (<note>)` — the path is everything before the trailing parenthesised note. */
130
+ const ENTRY = /^- (.+?)(?: \(([^()]*)\))?$/;
131
+ const MORE = /^\(\+\d+ more file\(s\) touched\)$/;
132
+ function entriesOf(content) {
133
+ const out = [];
134
+ for (const line of content.split('\n')) {
135
+ const m = ENTRY.exec(line);
136
+ if (m)
137
+ out.push({ path: m[1], note: m[2] });
138
+ }
139
+ return out;
140
+ }
141
+ function render(e) {
142
+ return `- ${e.path}${e.note ? ` (${e.note})` : ''}`;
143
+ }
144
+ /**
145
+ * The content to STORE when a consolidated map lands on a key that already holds one:
146
+ * the new run's entries first, then the earlier map's entries it did not touch (an
147
+ * earlier run's `changed` is restated as `changed earlier`, so this run is not credited
148
+ * with edits it never made), minus every file this run deleted, capped. Any other key,
149
+ * or no prior, stores `next` without its `(deleted)` lines.
150
+ *
151
+ * The STORE decides whether `prior` is still live — pass it only when the stored memory
152
+ * has not expired or been superseded, or a retired map comes back to life.
153
+ */
154
+ export function mergeConsolidated(key, prior, next) {
155
+ if (!key.startsWith(CONSOLIDATED_KEY_PREFIX))
156
+ return next;
157
+ const nextLines = next.split('\n');
158
+ const header = nextLines.filter((l) => !ENTRY.test(l) && !MORE.test(l));
159
+ const fresh = entriesOf(next);
160
+ const removed = new Set(fresh.filter((e) => e.note === 'deleted').map((e) => e.path));
161
+ const seen = new Set(removed);
162
+ const merged = [];
163
+ for (const e of fresh) {
164
+ if (seen.has(e.path))
165
+ continue;
166
+ seen.add(e.path);
167
+ merged.push(render(e));
168
+ }
169
+ for (const e of prior?.trim() ? entriesOf(prior) : []) {
170
+ if (seen.has(e.path) || e.note === 'deleted')
171
+ continue;
172
+ seen.add(e.path);
173
+ merged.push(render(e.note === 'changed' ? { ...e, note: 'changed earlier' } : e));
174
+ }
175
+ const shown = merged.slice(0, MAX_FILES);
176
+ const more = merged.length - shown.length;
177
+ return [...header, ...shown, ...(more > 0 ? [`(+${more} more file(s) touched)`] : [])].join('\n');
178
+ }
179
+ //# sourceMappingURL=consolidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidate.js","sourceRoot":"","sources":["../../src/working/consolidate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Working memory — the `@seanhogg/builderforce-memory/working` subpath.
3
+ *
4
+ * A run has two memories, and they do different jobs:
5
+ *
6
+ * - SHORT-TERM: {@link WorkingMemory}, what THIS run has read, searched and changed.
7
+ * Restated before every turn ({@link WorkingMemory.brief}), because a model's own
8
+ * reasoning is not carried into its next turn and old tool results are compacted
9
+ * out of its window — without it a long run re-derives the codebase every turn.
10
+ * - LONG-TERM: {@link consolidate}, what survives the run — a map of where the code
11
+ * for that area lives, keyed per area so the next run on it (any surface) opens the
12
+ * right files first. {@link mergeConsolidated} is the write-side rule that makes
13
+ * consolidations of one area accumulate instead of overwriting each other.
14
+ *
15
+ * The memory knows observations ("read this file", "changed that one"), never tool
16
+ * names — a host maps its own tool vocabulary onto {@link Observation}.
17
+ *
18
+ * Pure: no `node:*`, no I/O — runs in a Cloudflare Worker, a browser page and Node alike.
19
+ */
20
+ export { WorkingMemory } from './workingMemory.js';
21
+ export { consolidate, mergeConsolidated, consolidatedKey, CONSOLIDATED_KEY_PREFIX, MIN_CONSOLIDATED_FILES } from './consolidate.js';
22
+ export { rankByCount } from './rank.js';
23
+ export type { Observation, WorkingMemorySnapshot, ConsolidatedMemory, ConsolidateOptions } from './types.js';
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/working/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,eAAe,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AACpI,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Working memory — the `@seanhogg/builderforce-memory/working` subpath.
3
+ *
4
+ * A run has two memories, and they do different jobs:
5
+ *
6
+ * - SHORT-TERM: {@link WorkingMemory}, what THIS run has read, searched and changed.
7
+ * Restated before every turn ({@link WorkingMemory.brief}), because a model's own
8
+ * reasoning is not carried into its next turn and old tool results are compacted
9
+ * out of its window — without it a long run re-derives the codebase every turn.
10
+ * - LONG-TERM: {@link consolidate}, what survives the run — a map of where the code
11
+ * for that area lives, keyed per area so the next run on it (any surface) opens the
12
+ * right files first. {@link mergeConsolidated} is the write-side rule that makes
13
+ * consolidations of one area accumulate instead of overwriting each other.
14
+ *
15
+ * The memory knows observations ("read this file", "changed that one"), never tool
16
+ * names — a host maps its own tool vocabulary onto {@link Observation}.
17
+ *
18
+ * Pure: no `node:*`, no I/O — runs in a Cloudflare Worker, a browser page and Node alike.
19
+ */
20
+ export { WorkingMemory } from './workingMemory.js';
21
+ export { consolidate, mergeConsolidated, consolidatedKey, CONSOLIDATED_KEY_PREFIX, MIN_CONSOLIDATED_FILES } from './consolidate.js';
22
+ export { rankByCount } from './rank.js';
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/working/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,eAAe,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AACpI,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Each distinct item with how often it occurs, most frequent first, ties by name — the
3
+ * one ranking the brief, the consolidation and its area all use (and that hosts reuse
4
+ * for their own renderings of a run, so a run reads the same everywhere).
5
+ */
6
+ export declare function rankByCount(items: readonly string[]): [string, number][];
7
+ //# sourceMappingURL=rank.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rank.d.ts","sourceRoot":"","sources":["../../src/working/rank.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAIxE"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Each distinct item with how often it occurs, most frequent first, ties by name — the
3
+ * one ranking the brief, the consolidation and its area all use (and that hosts reuse
4
+ * for their own renderings of a run, so a run reads the same everywhere).
5
+ */
6
+ export function rankByCount(items) {
7
+ const counts = new Map();
8
+ for (const i of items)
9
+ counts.set(i, (counts.get(i) ?? 0) + 1);
10
+ return [...counts.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
11
+ }
12
+ //# sourceMappingURL=rank.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rank.js","sourceRoot":"","sources":["../../src/working/rank.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAwB;IAClD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvF,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The working-memory contract — pure data, so the subpath stays Worker/browser/Node safe.
3
+ */
4
+ /** One thing a run did that is worth remembering, in the memory's own terms. */
5
+ export type Observation = {
6
+ kind: 'read' | 'created' | 'edited' | 'deleted';
7
+ path: string;
8
+ } | {
9
+ kind: 'searched';
10
+ query: string;
11
+ };
12
+ /** What a run's working memory holds. Lists keep duplicates — how often is a signal. */
13
+ export interface WorkingMemorySnapshot {
14
+ /** What the run was asked. */
15
+ task?: string;
16
+ created: readonly string[];
17
+ edited: readonly string[];
18
+ deleted: readonly string[];
19
+ read: readonly string[];
20
+ searched: readonly string[];
21
+ }
22
+ /** One long-term memory, ready for a keyed store: the same key replaces (or merges). */
23
+ export interface ConsolidatedMemory {
24
+ key: string;
25
+ content: string;
26
+ }
27
+ export interface ConsolidateOptions {
28
+ /** Dates the memory so a reader can judge its age. */
29
+ at?: Date;
30
+ /** The workspace root — absolute paths under it are kept, made relative. */
31
+ root?: string;
32
+ }
33
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/working/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,gFAAgF;AAChF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,wFAAwF;AACxF,MAAM,WAAW,qBAAqB;IACpC,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,wFAAwF;AACxF,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,EAAE,CAAC,EAAE,IAAI,CAAC;IACV,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * The working-memory contract — pure data, so the subpath stays Worker/browser/Node safe.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/working/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}