@bunshin-cc/bunshin 0.4.0 → 0.4.1
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 +33 -2
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -8037,7 +8037,7 @@ async function handleV2(event, ctx) {
|
|
|
8037
8037
|
case "session-start":
|
|
8038
8038
|
return onSessionStart(ctx);
|
|
8039
8039
|
case "user-prompt-submit":
|
|
8040
|
-
return onPrompt(ctx);
|
|
8040
|
+
return await onPrompt(ctx);
|
|
8041
8041
|
case "pre-tool-use":
|
|
8042
8042
|
return onPreToolUse(ctx);
|
|
8043
8043
|
case "stop":
|
|
@@ -8117,12 +8117,28 @@ function liveUpdate(v2, ctx, session) {
|
|
|
8117
8117
|
return "";
|
|
8118
8118
|
}
|
|
8119
8119
|
}
|
|
8120
|
+
function skillHint(sec, others) {
|
|
8121
|
+
const also = others.length ? ` Also possibly relevant: ${others.map((t) => `"${t}"`).join(", ")}.` : "";
|
|
8122
|
+
return `Bunshin: the \`${sec.skill.name}\` skill may apply: ${sec.skill.description.replace(/\s+/g, " ").trim()} If it does, invoke it (Skill tool, or \`/${sec.skill.name}\`) before doing this by hand.${also}`;
|
|
8123
|
+
}
|
|
8124
|
+
async function remoteAuto(ctx, prompt, exclude) {
|
|
8125
|
+
const config = ctx.store.config();
|
|
8126
|
+
if (!canCall(config) || !config.recall.useMothership) return null;
|
|
8127
|
+
const budget = Math.min(2500, ctx.deadline - Date.now() - 600);
|
|
8128
|
+
if (budget < 300) return null;
|
|
8129
|
+
try {
|
|
8130
|
+
const res = await v2api(config, "POST", "/recall/auto", { prompt: prompt.slice(0, 8e3), exclude }, { timeoutMs: budget });
|
|
8131
|
+
return res.available ? res : null;
|
|
8132
|
+
} catch {
|
|
8133
|
+
return null;
|
|
8134
|
+
}
|
|
8135
|
+
}
|
|
8120
8136
|
function hintLine(titles, harness) {
|
|
8121
8137
|
const quoted = titles.map((t) => `"${t}"`).join(", ");
|
|
8122
8138
|
const how = harness === "claude-code" ? "If one could change your approach, call the bunshin_recall tool (describe the task abstractly) and load only what you need." : 'If one could change your approach, run `bunshin recall "<the task, abstractly>" --hypothetical "<the lesson you would want>"` and `bunshin load <id>`.';
|
|
8123
8139
|
return `Bunshin: possibly relevant library sections: ${quoted}. ${how}`;
|
|
8124
8140
|
}
|
|
8125
|
-
function onPrompt(ctx) {
|
|
8141
|
+
async function onPrompt(ctx) {
|
|
8126
8142
|
const prompt = ctx.input.prompt ?? "";
|
|
8127
8143
|
if (prompt.trimStart().startsWith(REFLECT_MARKER)) return {};
|
|
8128
8144
|
const v2 = new V2Store(ctx.store);
|
|
@@ -8143,6 +8159,19 @@ function onPrompt(ctx) {
|
|
|
8143
8159
|
const view = localView(v2, config, ctx.cwd);
|
|
8144
8160
|
const injected = [...session.loaded, ...session.pushed];
|
|
8145
8161
|
const res = auto(view.sections, view.reader, prompt, { exclude: injected });
|
|
8162
|
+
const remote = await remoteAuto(ctx, prompt, injected);
|
|
8163
|
+
if (remote) {
|
|
8164
|
+
const local = (id) => view.sections.find((s) => s.id === id);
|
|
8165
|
+
if (remote.section) {
|
|
8166
|
+
res.section = local(remote.section.id) ?? remote.section;
|
|
8167
|
+
res.anchor = void 0;
|
|
8168
|
+
res.reason = `dense ${remote.reason ?? ""}`.trim();
|
|
8169
|
+
} else {
|
|
8170
|
+
res.section = void 0;
|
|
8171
|
+
res.hint = (remote.hint ?? []).map((h) => ({ id: h.id, title: local(h.id)?.title ?? h.title }));
|
|
8172
|
+
res.reason = `dense ${remote.reason ?? ""}`.trim();
|
|
8173
|
+
}
|
|
8174
|
+
}
|
|
8146
8175
|
if (res.section) {
|
|
8147
8176
|
const sec = res.section;
|
|
8148
8177
|
v2.updateSession(session.sessionId, ctx.cwd, (s) => {
|
|
@@ -8159,6 +8188,8 @@ function onPrompt(ctx) {
|
|
|
8159
8188
|
addUnique(s.hinted, ...fresh.map((h) => h.id));
|
|
8160
8189
|
addUnique(s.served, ...fresh.map((h) => h.id));
|
|
8161
8190
|
});
|
|
8191
|
+
const topSkill = view.sections.find((s) => s.id === fresh[0].id && s.skill);
|
|
8192
|
+
if (topSkill && deployEnabled(config, view.ctx)) return withLive(additional("UserPromptSubmit", skillHint(topSkill, fresh.slice(1).map((h) => h.title))));
|
|
8162
8193
|
return withLive(additional("UserPromptSubmit", hintLine(fresh.map((h) => h.title), config.harness)));
|
|
8163
8194
|
}
|
|
8164
8195
|
function toolPaths(input) {
|