@bunshin-cc/bunshin 0.4.5 → 0.4.6
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/bin.js +100 -26
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -431,9 +431,11 @@ var init_store = __esm({
|
|
|
431
431
|
function emptyStats() {
|
|
432
432
|
return { served: 0, loaded: 0, helped: 0, hurt: 0, byContext: {} };
|
|
433
433
|
}
|
|
434
|
+
var LEARNING_SIGNALS;
|
|
434
435
|
var init_types = __esm({
|
|
435
436
|
"../core/src/v2/types.ts"() {
|
|
436
437
|
"use strict";
|
|
438
|
+
LEARNING_SIGNALS = ["steering", "environment", "knowledge", "capability", "approach"];
|
|
437
439
|
}
|
|
438
440
|
});
|
|
439
441
|
|
|
@@ -1521,7 +1523,8 @@ function renderSection(s, trigger, opts = {}) {
|
|
|
1521
1523
|
const label2 = s.kind === "guardrail" ? "GUARDRAIL" : s.kind.toUpperCase();
|
|
1522
1524
|
const src = sourceLabel(s);
|
|
1523
1525
|
const why = trigger ? `_Why you are seeing this: ${trigger}. Id: ${s.id}_` : `_Id: ${s.id}_`;
|
|
1524
|
-
const
|
|
1526
|
+
const trial = s.localTrial?.length ? [`_Includes ${s.localTrial.length === 1 ? "an edit" : `${s.localTrial.length} edits`} learned on this machine and not yet reviewed: treat ${s.localTrial.length === 1 ? "it" : "them"} as provisional._`] : [];
|
|
1527
|
+
const head = [`### ${label2} (${src}): ${s.title}`, why, ...trial];
|
|
1525
1528
|
const max = opts.maxChars ?? 6e3;
|
|
1526
1529
|
if (s.skill && opts.deployed) {
|
|
1527
1530
|
const part2 = opts.anchor ? (s.outline ?? []).find((h) => h.anchor === opts.anchor) : void 0;
|
|
@@ -1726,9 +1729,20 @@ Lessons already taken from it. Never propose these again, nor a rewording of the
|
|
|
1726
1729
|
${lessons}
|
|
1727
1730
|
`;
|
|
1728
1731
|
}
|
|
1732
|
+
function stampLesson(op, signal, at) {
|
|
1733
|
+
const day = at.slice(0, 10);
|
|
1734
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(day)) return op;
|
|
1735
|
+
const recheck = signal === "environment" ? `; recheck after ${new Date(Date.parse(day) + ENVIRONMENT_RECHECK_DAYS * 864e5).toISOString().slice(0, 10)}` : "";
|
|
1736
|
+
const stamp = `_(learned ${day}${signal ? ` from ${SIGNAL_WORDS[signal]}` : ""}${recheck})_`;
|
|
1737
|
+
if (op.op === "append") return /_\(learned \d{4}-/.test(op.text) ? op : { ...op, text: `${op.text.trimEnd()} ${stamp}` };
|
|
1738
|
+
if (op.op === "create") return /_\(learned \d{4}-/.test(op.section.body) ? op : { ...op, section: { ...op.section, body: `${op.section.body.trimEnd()}
|
|
1739
|
+
|
|
1740
|
+
${stamp}` } };
|
|
1741
|
+
return op;
|
|
1742
|
+
}
|
|
1729
1743
|
function summarizeOp(op) {
|
|
1730
1744
|
const clip2 = (s) => {
|
|
1731
|
-
const one = s.replace(/\s+/g, " ").trim();
|
|
1745
|
+
const one = s.replace(/\s*_\(learned \d{4}-\d{2}-\d{2}[^)]*\)_/g, "").replace(/\s+/g, " ").trim();
|
|
1732
1746
|
return one.length > 100 ? `${one.slice(0, 97)}\u2026` : one;
|
|
1733
1747
|
};
|
|
1734
1748
|
switch (op.op) {
|
|
@@ -1783,8 +1797,14 @@ Capture only what would change how a future agent acts, and is recorded nowhere
|
|
|
1783
1797
|
b. the environment corrected the agent (a command, test, API, motion or grasp failed, then
|
|
1784
1798
|
another approach worked): record the trap AND what worked;
|
|
1785
1799
|
c. knowledge owned by another team surfaced (a process, policy or manual step);
|
|
1786
|
-
d. a capability worked for the first time, or a task was done unusually efficiently
|
|
1800
|
+
d. a capability worked for the first time, or a task was done unusually efficiently;
|
|
1801
|
+
e. looking back over the whole session, the approach itself was the problem (it took many
|
|
1802
|
+
rounds of fixes, it was over-built, it verified too late) and a different way of working
|
|
1803
|
+
would have avoided it. This has no direct ground truth: say what you would do differently
|
|
1804
|
+
next time, as generally as it truly holds, and where it does not hold.
|
|
1787
1805
|
"Nothing new" is the expected outcome for most sessions. Never invent a lesson.
|
|
1806
|
+
Label each suggestion with its "signal": a \u2192 "steering", b \u2192 "environment", c \u2192 "knowledge",
|
|
1807
|
+
d \u2192 "capability", e \u2192 "approach".
|
|
1788
1808
|
|
|
1789
1809
|
## Where it goes
|
|
1790
1810
|
|
|
@@ -1797,7 +1817,10 @@ ${index}
|
|
|
1797
1817
|
Already captured this session (do not repeat): ${input.captured.length ? input.captured.join(", ") : "none"}
|
|
1798
1818
|
|
|
1799
1819
|
Layers you may target: ${input.layers.join(", ")}.
|
|
1800
|
-
|
|
1820
|
+
${input.profileId ? `- How THIS person works, prefers or wants things done (a steering or approach lesson about them,
|
|
1821
|
+
not about the task) \u2192 op "append" to their profile ${input.profileId}, anchor "how-i-work".
|
|
1822
|
+
A lesson for anyone doing the task belongs in the task's document instead.
|
|
1823
|
+
` : ""}- Knowledge about one repo that its team owns \u2192 that repo's section (repo:... ids).
|
|
1801
1824
|
- Cross-repo facts, another team's rules, non-code processes \u2192 a Bunshin section at the right layer.
|
|
1802
1825
|
- If it only holds in some contexts, use op "append" with a "condition" (e.g. "objects over 50 g").
|
|
1803
1826
|
${robot ? `- Values that belong to THIS robot or cell (calibration, pixel columns, colour thresholds under this
|
|
@@ -1824,7 +1847,8 @@ At most ${max} suggestions. Schema:
|
|
|
1824
1847
|
"paths"?: string[], "entities"?: string[], "skills"?: string[]}}
|
|
1825
1848
|
| {"op": "param", "key": string, "value": string|number|boolean}
|
|
1826
1849
|
| {"op": "situation", "text": string},
|
|
1827
|
-
"rationale": string, "urgency": "normal"|"urgent"
|
|
1850
|
+
"rationale": string, "urgency": "normal"|"urgent",
|
|
1851
|
+
"signal": "steering"|"environment"|"knowledge"|"capability"|"approach"}]}`;
|
|
1828
1852
|
}
|
|
1829
1853
|
function extractJson(text2) {
|
|
1830
1854
|
const fenced = text2.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
@@ -1900,7 +1924,8 @@ function parseReflection(raw, opts = { layers: [] }) {
|
|
|
1900
1924
|
target: { ...sectionId ? { sectionId } : {}, ...layer ? { layer } : {} },
|
|
1901
1925
|
op,
|
|
1902
1926
|
rationale: clean(it.rationale) || "captured from session",
|
|
1903
|
-
urgency: it.urgency === "urgent" ? "urgent" : "normal"
|
|
1927
|
+
urgency: it.urgency === "urgent" ? "urgent" : "normal",
|
|
1928
|
+
...LEARNING_SIGNALS.includes(it.signal) ? { signal: it.signal } : {}
|
|
1904
1929
|
});
|
|
1905
1930
|
if (out.length >= (opts.max ?? 4)) break;
|
|
1906
1931
|
}
|
|
@@ -1913,8 +1938,9 @@ function toSuggestion(p, base) {
|
|
|
1913
1938
|
contextId: base.contextId,
|
|
1914
1939
|
authorUserId: base.authorUserId,
|
|
1915
1940
|
target: p.target,
|
|
1916
|
-
op: p.op,
|
|
1941
|
+
op: stampLesson(p.op, p.signal, base.createdAt),
|
|
1917
1942
|
rationale: p.rationale,
|
|
1943
|
+
...p.signal ? { signal: p.signal } : {},
|
|
1918
1944
|
evidenceEpisodeIds: base.episodeId ? [base.episodeId] : [],
|
|
1919
1945
|
trial: { uses: 0, successes: 0, failures: 0 },
|
|
1920
1946
|
origin: base.origin,
|
|
@@ -1923,12 +1949,21 @@ function toSuggestion(p, base) {
|
|
|
1923
1949
|
createdAt: base.createdAt
|
|
1924
1950
|
};
|
|
1925
1951
|
}
|
|
1926
|
-
var REFLECT_MARKER, REFLECT_SCHEMA, KINDS, anchorOf, clean, strList;
|
|
1952
|
+
var REFLECT_MARKER, ENVIRONMENT_RECHECK_DAYS, SIGNAL_WORDS, REFLECT_SCHEMA, KINDS, anchorOf, clean, strList;
|
|
1927
1953
|
var init_reflect = __esm({
|
|
1928
1954
|
"../core/src/v2/reflect.ts"() {
|
|
1929
1955
|
"use strict";
|
|
1930
1956
|
init_redact();
|
|
1957
|
+
init_types();
|
|
1931
1958
|
REFLECT_MARKER = "BUNSHIN:reflect";
|
|
1959
|
+
ENVIRONMENT_RECHECK_DAYS = 90;
|
|
1960
|
+
SIGNAL_WORDS = {
|
|
1961
|
+
steering: "a person's correction",
|
|
1962
|
+
environment: "the environment",
|
|
1963
|
+
knowledge: "another team's knowledge",
|
|
1964
|
+
capability: "a first success",
|
|
1965
|
+
approach: "reflection on the approach"
|
|
1966
|
+
};
|
|
1932
1967
|
REFLECT_SCHEMA = {
|
|
1933
1968
|
type: "object",
|
|
1934
1969
|
additionalProperties: false,
|
|
@@ -1944,7 +1979,8 @@ var init_reflect = __esm({
|
|
|
1944
1979
|
target: { type: "object", properties: { sectionId: { type: "string" }, layer: { type: "string" } } },
|
|
1945
1980
|
op: { type: "object" },
|
|
1946
1981
|
rationale: { type: "string" },
|
|
1947
|
-
urgency: { type: "string", enum: ["normal", "urgent"] }
|
|
1982
|
+
urgency: { type: "string", enum: ["normal", "urgent"] },
|
|
1983
|
+
signal: { type: "string", enum: ["steering", "environment", "knowledge", "capability", "approach"] }
|
|
1948
1984
|
}
|
|
1949
1985
|
}
|
|
1950
1986
|
}
|
|
@@ -2003,6 +2039,14 @@ var init_research = __esm({
|
|
|
2003
2039
|
}
|
|
2004
2040
|
});
|
|
2005
2041
|
|
|
2042
|
+
// ../core/src/v2/profile.ts
|
|
2043
|
+
var init_profile = __esm({
|
|
2044
|
+
"../core/src/v2/profile.ts"() {
|
|
2045
|
+
"use strict";
|
|
2046
|
+
init_types();
|
|
2047
|
+
}
|
|
2048
|
+
});
|
|
2049
|
+
|
|
2006
2050
|
// ../core/src/v2/index.ts
|
|
2007
2051
|
var init_v2 = __esm({
|
|
2008
2052
|
"../core/src/v2/index.ts"() {
|
|
@@ -2019,6 +2063,7 @@ var init_v2 = __esm({
|
|
|
2019
2063
|
init_reconcile();
|
|
2020
2064
|
init_release();
|
|
2021
2065
|
init_research();
|
|
2066
|
+
init_profile();
|
|
2022
2067
|
}
|
|
2023
2068
|
});
|
|
2024
2069
|
|
|
@@ -2682,7 +2727,7 @@ function planDeploy(bundle, p, harnesses) {
|
|
|
2682
2727
|
if (!prev || (LAYER_RANK[layerKind(s.layer)] ?? 0) > (LAYER_RANK[layerKind(prev.layer)] ?? 0)) byName.set(s.skill.name, s);
|
|
2683
2728
|
}
|
|
2684
2729
|
const skills = [...byName.values()].sort((a, b) => a.skill.name.localeCompare(b.skill.name));
|
|
2685
|
-
const instructions = active.filter((s) => s.delivery === "always" && !s.skill).sort((a, b) => (a.packPath ?? a.title).localeCompare(b.packPath ?? b.title));
|
|
2730
|
+
const instructions = active.filter((s) => s.delivery === "always" && !s.skill && !s.profileOf).sort((a, b) => (a.packPath ?? a.title).localeCompare(b.packPath ?? b.title));
|
|
2686
2731
|
const plan = { docs: /* @__PURE__ */ new Map(), instructions, skills };
|
|
2687
2732
|
const roots = [...harnesses.has("claude-code") ? [p.claudeSkills] : [], ...harnesses.has("codex") ? [p.codexSkills] : []];
|
|
2688
2733
|
for (const s of skills) {
|
|
@@ -3197,13 +3242,25 @@ function baselineOf(bundle) {
|
|
|
3197
3242
|
}
|
|
3198
3243
|
function renderInstructions(bundle) {
|
|
3199
3244
|
const docs = instructionDocs(bundle);
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3245
|
+
const profiles = docs.filter((d) => d.profileOf);
|
|
3246
|
+
const standing = docs.filter((d) => !d.profileOf);
|
|
3247
|
+
const parts = [];
|
|
3248
|
+
if (profiles.length) {
|
|
3249
|
+
parts.push(
|
|
3250
|
+
["## Who you work for (Bunshin profile)", "Bunshin keeps this current from their sessions and corrections, and tells you when it changes.", "", ...profiles.map((d) => d.body.trim())].join("\n")
|
|
3251
|
+
);
|
|
3252
|
+
}
|
|
3253
|
+
if (standing.length) {
|
|
3254
|
+
parts.push(
|
|
3255
|
+
[
|
|
3256
|
+
`## Standing instructions (your organization, from Bunshin ${lib(bundle?.libraryVersion)})`,
|
|
3257
|
+
"Follow these as you would CLAUDE.md. Bunshin re-delivers them after /clear and compaction, and tells you when they change.",
|
|
3258
|
+
"",
|
|
3259
|
+
...standing.map((d) => d.body.trim())
|
|
3260
|
+
].join("\n")
|
|
3261
|
+
);
|
|
3262
|
+
}
|
|
3263
|
+
return parts.join("\n\n");
|
|
3207
3264
|
}
|
|
3208
3265
|
function lineDiff(before, after, max = MAX_DIFF_LINES) {
|
|
3209
3266
|
const a = before.split("\n");
|
|
@@ -3237,11 +3294,11 @@ function changesSince(base, bundle, skillPath) {
|
|
|
3237
3294
|
const old = base.instructions[d.id];
|
|
3238
3295
|
if (old === d.body) continue;
|
|
3239
3296
|
if (old === void 0) {
|
|
3240
|
-
lines.push(`New standing instructions ("${d.title}"):`, d.body.trim(), "");
|
|
3297
|
+
lines.push(d.profileOf ? `The profile of the person you work for ("${d.title}"):` : `New standing instructions ("${d.title}"):`, d.body.trim(), "");
|
|
3241
3298
|
continue;
|
|
3242
3299
|
}
|
|
3243
3300
|
const diff = lineDiff(old, d.body);
|
|
3244
|
-
if (diff.length) lines.push(`Standing instructions changed ("${d.title}"); follow the new text:`, ...diff, "");
|
|
3301
|
+
if (diff.length) lines.push(d.profileOf ? `The profile of the person you work for changed ("${d.title}"):` : `Standing instructions changed ("${d.title}"); follow the new text:`, ...diff, "");
|
|
3245
3302
|
}
|
|
3246
3303
|
for (const id of Object.keys(base.instructions)) if (!now.some((d) => d.id === id)) lines.push(`Standing instructions withdrawn (${id}): stop following them.`, "");
|
|
3247
3304
|
const skillLines = [];
|
|
@@ -3707,13 +3764,13 @@ function applyOverlays(sections, overlays, ctx) {
|
|
|
3707
3764
|
if (!ACTIVE_OVERLAY.has(o.status) || o.kind !== "local-section") continue;
|
|
3708
3765
|
if (o.op.op === "create") {
|
|
3709
3766
|
const id = o.sectionId || localSectionId(o.suggestionId);
|
|
3710
|
-
sections.set(id, draftToSection(id, o.op.section, ctx, ownLayer(ctx), o.appliedAt));
|
|
3767
|
+
sections.set(id, { ...draftToSection(id, o.op.section, ctx, ownLayer(ctx), o.appliedAt), localTrial: [o.suggestionId] });
|
|
3711
3768
|
continue;
|
|
3712
3769
|
}
|
|
3713
3770
|
const base = o.sectionId ? sections.get(o.sectionId) : void 0;
|
|
3714
3771
|
if (!base) continue;
|
|
3715
3772
|
const res = applyOpToBody(base.body, o.op);
|
|
3716
|
-
if (res.ok && res.text !== base.body) sections.set(base.id, { ...base, body: res.text, updatedAt: o.appliedAt });
|
|
3773
|
+
if (res.ok && res.text !== base.body) sections.set(base.id, { ...base, body: res.text, updatedAt: o.appliedAt, localTrial: [...base.localTrial ?? [], o.suggestionId] });
|
|
3717
3774
|
}
|
|
3718
3775
|
}
|
|
3719
3776
|
function localView(v2, config, cwd, opts = {}) {
|
|
@@ -4482,14 +4539,18 @@ async function runReflectionV2(store, opts) {
|
|
|
4482
4539
|
const episodeId = episodeIdFor(view.ctx.id, opts.sessionId);
|
|
4483
4540
|
const prior = session.suggestionIds.map((id) => v2.readSuggestion(id)).filter((s) => !!s);
|
|
4484
4541
|
const captured = [.../* @__PURE__ */ new Set([...session.captured, ...prior.map((s) => s.target.sectionId ?? localSectionId(s.id))])];
|
|
4485
|
-
const
|
|
4542
|
+
const profile = view.sections.find((s) => s.profileOf && s.profileOf === config.userId && s.status === "active");
|
|
4543
|
+
const index = [
|
|
4544
|
+
...profile ? [{ id: profile.id, kind: profile.kind, layer: profile.layer, title: profile.title, when: "how the person you work for works", ...profile.outline?.length ? { outline: profile.outline } : {} }] : [],
|
|
4545
|
+
...reflectionIndex(view, [...session.loaded, ...session.pushed, ...session.served], session.task, opts.focus, humanTurnsOf(session.transcriptPath)).filter((s) => s.id !== profile?.id)
|
|
4546
|
+
];
|
|
4486
4547
|
const harness = session.harness ?? config.harness;
|
|
4487
4548
|
const facts = readFacts(session.transcriptPath);
|
|
4488
4549
|
const turns = facts?.turns.length ?? 0;
|
|
4489
4550
|
const from = reflectCursor(session, turns);
|
|
4490
4551
|
const lessons = [.../* @__PURE__ */ new Set([...prior.map(lessonLine), ...session.serverLessons ?? []])].slice(0, 40);
|
|
4491
4552
|
const earlier = from > 0 || lessons.length ? { ...from > 0 && facts ? { from: anchorAt(facts, from) } : {}, lessons } : void 0;
|
|
4492
|
-
const promptBase = { contextKind: view.ctx.kind, layers: view.layers, index, captured, ...opts.focus ? { focus: opts.focus } : {}, ...earlier ? { earlier } : {} };
|
|
4553
|
+
const promptBase = { contextKind: view.ctx.kind, layers: view.layers, index, captured, ...opts.focus ? { focus: opts.focus } : {}, ...earlier ? { earlier } : {}, ...profile ? { profileId: profile.id } : {} };
|
|
4493
4554
|
let raw = null;
|
|
4494
4555
|
if (harness === "claude-code") {
|
|
4495
4556
|
const fork = await runClaudeFork(opts.sessionId, buildReflectPrompt(promptBase), { cwd: session.cwd });
|
|
@@ -4784,6 +4845,13 @@ var init_uicmd = __esm({
|
|
|
4784
4845
|
// src/v2/hooks.ts
|
|
4785
4846
|
import fs14 from "node:fs";
|
|
4786
4847
|
import path11 from "node:path";
|
|
4848
|
+
function inContext(s) {
|
|
4849
|
+
return s.inContext ?? [...s.loaded, ...s.pushed];
|
|
4850
|
+
}
|
|
4851
|
+
function markInContext(s, ...ids) {
|
|
4852
|
+
s.inContext = s.inContext ?? [...s.loaded, ...s.pushed];
|
|
4853
|
+
addUnique(s.inContext, ...ids);
|
|
4854
|
+
}
|
|
4787
4855
|
function touch(v2, ctx, patch = () => {
|
|
4788
4856
|
}) {
|
|
4789
4857
|
const id = ctx.input.session_id || "no-session";
|
|
@@ -4852,6 +4920,7 @@ function liveSummary(text2) {
|
|
|
4852
4920
|
for (const m of text2.matchAll(/- `([^`]+)` updated \((v\d+ → v\d+)\)/g)) items.push(`${m[1]} ${m[2]}`);
|
|
4853
4921
|
for (const m of text2.matchAll(/- `([^`]+)` was retired/g)) items.push(`${m[1]} retired`);
|
|
4854
4922
|
if (/Standing instructions (changed|withdrawn)|New standing instructions/.test(text2)) items.push("standing instructions changed");
|
|
4923
|
+
if (/The profile of the person you work for/.test(text2)) items.push("your profile");
|
|
4855
4924
|
return `library updated${range ? ` (${range[2]})` : ""}: ${items.join(", ") || "changes delivered to the agent"}`;
|
|
4856
4925
|
}
|
|
4857
4926
|
async function dispatch(event, ctx) {
|
|
@@ -4996,7 +5065,7 @@ async function onPrompt(ctx) {
|
|
|
4996
5065
|
if (!prompt.trim()) return withLive({});
|
|
4997
5066
|
const config = ctx.store.config();
|
|
4998
5067
|
const view = localView(v2, config, ctx.cwd);
|
|
4999
|
-
const injected =
|
|
5068
|
+
const injected = inContext(session);
|
|
5000
5069
|
const res = auto(view.sections, view.reader, prompt, { exclude: injected });
|
|
5001
5070
|
const remote = await remoteAuto(ctx, prompt, injected);
|
|
5002
5071
|
if (remote) {
|
|
@@ -5016,6 +5085,7 @@ async function onPrompt(ctx) {
|
|
|
5016
5085
|
v2.updateSession(session.sessionId, ctx.cwd, (s) => {
|
|
5017
5086
|
addUnique(s.served, sec.id);
|
|
5018
5087
|
addUnique(s.loaded, sec.id);
|
|
5088
|
+
markInContext(s, sec.id);
|
|
5019
5089
|
});
|
|
5020
5090
|
v2.log("v2-auto", { session: session.sessionId, section: sec.id, reason: res.reason });
|
|
5021
5091
|
updateFeed(v2, session.sessionId, (f) => {
|
|
@@ -5069,13 +5139,14 @@ function onPreToolUse(ctx) {
|
|
|
5069
5139
|
const paths = raw.map((p) => relativeToRoot(view.root, p, ctx.cwd)).filter((p) => !!p);
|
|
5070
5140
|
const text2 = [session.task, session.lastPrompt].filter(Boolean).join("\n");
|
|
5071
5141
|
if (!paths.length && !text2) return withLive({});
|
|
5072
|
-
const seen =
|
|
5142
|
+
const seen = new Set(inContext(session));
|
|
5073
5143
|
const hits = push(view.sections, view.reader, { paths, text: text2 }).filter((h) => !seen.has(h.section.id)).slice(0, MAX_PUSH);
|
|
5074
5144
|
if (!hits.length) return withLive({});
|
|
5075
5145
|
const ids = hits.map((h) => h.section.id);
|
|
5076
5146
|
v2.updateSession(session.sessionId, ctx.cwd, (s) => {
|
|
5077
5147
|
addUnique(s.pushed, ...ids);
|
|
5078
5148
|
addUnique(s.loaded, ...ids);
|
|
5149
|
+
markInContext(s, ...ids);
|
|
5079
5150
|
addUnique(s.served, ...ids);
|
|
5080
5151
|
});
|
|
5081
5152
|
v2.log("v2-push", { session: session.sessionId, tool: ctx.input.tool_name, hits: hits.map((h) => `${h.section.id} ${h.trigger}`) });
|
|
@@ -5278,7 +5349,10 @@ function onSessionEnd(ctx) {
|
|
|
5278
5349
|
function onPreCompact(ctx) {
|
|
5279
5350
|
const v2 = new V2Store(ctx.store);
|
|
5280
5351
|
const config = ctx.store.config();
|
|
5281
|
-
const session = touch(v2, ctx)
|
|
5352
|
+
const session = touch(v2, ctx, (s) => {
|
|
5353
|
+
s.inContext = [];
|
|
5354
|
+
s.hinted = [];
|
|
5355
|
+
});
|
|
5282
5356
|
if (!config.reflect.enabled) return {};
|
|
5283
5357
|
const scan = scanTranscript(ctx.input.transcript_path ?? session.transcriptPath);
|
|
5284
5358
|
const from = reflectCursor(session, scan.facts.turns.length);
|