@koda-sl/baker-bridge 0.149.0-dev.74f6c7937 → 0.154.0-dev.db7cf2f5d
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/README.md +38 -10
- package/dist/hono/agent-session.d.ts +1 -0
- package/dist/hono/agent-session.d.ts.map +1 -1
- package/dist/hono/agent-session.js +7 -0
- package/dist/hono/agent-session.js.map +1 -1
- package/dist/hono/agent-session.test.js +7 -1
- package/dist/hono/agent-session.test.js.map +1 -1
- package/dist/hono/agent.d.ts.map +1 -1
- package/dist/hono/agent.js +15 -2
- package/dist/hono/agent.js.map +1 -1
- package/dist/hono/bridge-job.d.ts +18 -1
- package/dist/hono/bridge-job.d.ts.map +1 -1
- package/dist/hono/bridge-job.js +38 -34
- package/dist/hono/bridge-job.js.map +1 -1
- package/dist/hono/bridge-job.test.js +190 -17
- package/dist/hono/bridge-job.test.js.map +1 -1
- package/dist/hono/cli-sync.d.ts +6 -0
- package/dist/hono/cli-sync.d.ts.map +1 -0
- package/dist/hono/cli-sync.js +108 -0
- package/dist/hono/cli-sync.js.map +1 -0
- package/dist/hono/cli-sync.test.d.ts +2 -0
- package/dist/hono/cli-sync.test.d.ts.map +1 -0
- package/dist/hono/cli-sync.test.js +122 -0
- package/dist/hono/cli-sync.test.js.map +1 -0
- package/dist/hono/main-sync.d.ts +20 -0
- package/dist/hono/main-sync.d.ts.map +1 -0
- package/dist/hono/main-sync.js +163 -0
- package/dist/hono/main-sync.js.map +1 -0
- package/dist/hono/main-sync.test.d.ts +2 -0
- package/dist/hono/main-sync.test.d.ts.map +1 -0
- package/dist/hono/main-sync.test.js +145 -0
- package/dist/hono/main-sync.test.js.map +1 -0
- package/dist/hono/session-continuity.d.ts +6 -24
- package/dist/hono/session-continuity.d.ts.map +1 -1
- package/dist/hono/session-continuity.integration.test.js +5 -156
- package/dist/hono/session-continuity.integration.test.js.map +1 -1
- package/dist/hono/session-continuity.js +12 -92
- package/dist/hono/session-continuity.js.map +1 -1
- package/dist/hono/session-store.d.ts +0 -2
- package/dist/hono/session-store.d.ts.map +1 -1
- package/dist/hono/session-store.js +0 -6
- package/dist/hono/session-store.js.map +1 -1
- package/dist/hono/turn-events.d.ts +1 -1
- package/dist/hono/turn-events.d.ts.map +1 -1
- package/dist/hono/turn-events.js.map +1 -1
- package/dist/hono/types.d.ts +6 -0
- package/dist/hono/types.d.ts.map +1 -1
- package/package.json +3 -1
|
@@ -241,6 +241,8 @@ function createExecutor(options) {
|
|
|
241
241
|
stalledCliExitMs: 0,
|
|
242
242
|
prepareAttachments: options.prepareAttachments,
|
|
243
243
|
...(options.inFlightTurns ? { inFlightTurns: options.inFlightTurns } : {}),
|
|
244
|
+
...(options.catchUpWithMain ? { catchUpWithMain: options.catchUpWithMain } : {}),
|
|
245
|
+
...(options.keepCliInStep ? { keepCliInStep: options.keepCliInStep } : {}),
|
|
244
246
|
});
|
|
245
247
|
}
|
|
246
248
|
function memoryInFlightTurns(initial) {
|
|
@@ -1345,6 +1347,38 @@ describe("BridgeJobExecutor", () => {
|
|
|
1345
1347
|
}, activeControls());
|
|
1346
1348
|
expect(queryInputs[0]?.prompt).toBe("/audit-google-ads-account 3865083115");
|
|
1347
1349
|
});
|
|
1350
|
+
it("keeps a skill command leading when catching up with main is what brought the skill in", async () => {
|
|
1351
|
+
const workspace = await mkdtemp(join(tmpdir(), "baker-job-skill-caught-up-"));
|
|
1352
|
+
await mkdir(join(workspace, ".claude", "skills", "landing"), { recursive: true });
|
|
1353
|
+
projectRootMock.value = workspace;
|
|
1354
|
+
const queryInputs = [];
|
|
1355
|
+
let told = 0;
|
|
1356
|
+
const executor = createExecutor({
|
|
1357
|
+
queryInputs,
|
|
1358
|
+
queryResults: [scriptedMessages(resultMessage(0, "session_skill_caught_up"))],
|
|
1359
|
+
catchUpWithMain: async () => {
|
|
1360
|
+
await mkdir(join(workspace, ".claude", "skills", "audit-google-ads-account"), { recursive: true });
|
|
1361
|
+
return {
|
|
1362
|
+
inWorkspace: true,
|
|
1363
|
+
changed: [".claude/skills/audit-google-ads-account/SKILL.md"],
|
|
1364
|
+
told: () => {
|
|
1365
|
+
told += 1;
|
|
1366
|
+
return Promise.resolve();
|
|
1367
|
+
},
|
|
1368
|
+
};
|
|
1369
|
+
},
|
|
1370
|
+
});
|
|
1371
|
+
await executor.execute({
|
|
1372
|
+
threadId: "thread_skill_caught_up",
|
|
1373
|
+
turnId: "turn_skill_caught_up",
|
|
1374
|
+
prompt: "/audit-google-ads-account 3865083115",
|
|
1375
|
+
history: history([]),
|
|
1376
|
+
currentSender: { name: "Dana", userId: "user_dana" },
|
|
1377
|
+
}, activeControls());
|
|
1378
|
+
expect(queryInputs[0]?.prompt).toBe("/audit-google-ads-account 3865083115");
|
|
1379
|
+
expect(queryInputs[0]?.reminder).toBeUndefined();
|
|
1380
|
+
expect(told).toBe(0);
|
|
1381
|
+
});
|
|
1348
1382
|
it("passes per-turn MCP servers into Agent SDK query options with the acting user", async () => {
|
|
1349
1383
|
const queryInputs = [];
|
|
1350
1384
|
const calls = [];
|
|
@@ -1668,6 +1702,132 @@ describe("BridgeJobExecutor", () => {
|
|
|
1668
1702
|
expect(queryInputs[0]?.prompt).toBe("/publish");
|
|
1669
1703
|
expect(queryInputs[0]?.reminder).toBeUndefined();
|
|
1670
1704
|
});
|
|
1705
|
+
it("tells the agent which files another chat's publish just brought into its workspace", async () => {
|
|
1706
|
+
const queryInputs = [];
|
|
1707
|
+
let told = 0;
|
|
1708
|
+
const executor = createExecutor({
|
|
1709
|
+
queryInputs,
|
|
1710
|
+
catchUpWithMain: async () => ({
|
|
1711
|
+
inWorkspace: true,
|
|
1712
|
+
changed: ["src/pages/home/hero.md"],
|
|
1713
|
+
told: () => {
|
|
1714
|
+
told += 1;
|
|
1715
|
+
return Promise.resolve();
|
|
1716
|
+
},
|
|
1717
|
+
}),
|
|
1718
|
+
});
|
|
1719
|
+
await executor.execute({
|
|
1720
|
+
threadId: "thread_caught_up",
|
|
1721
|
+
turnId: "turn_caught_up",
|
|
1722
|
+
prompt: "Cambia el subtítulo del hero a «Sin entrada, paga en 24 meses».",
|
|
1723
|
+
history: history([
|
|
1724
|
+
{ role: "user", text: "¿Qué pone ahora el hero de la home?", createdAt: 1 },
|
|
1725
|
+
{
|
|
1726
|
+
role: "assistant",
|
|
1727
|
+
text: "El titular dice «Paneles solares para tu casa» y el subtítulo «Instala hoy y paga en 12 meses».",
|
|
1728
|
+
createdAt: 2,
|
|
1729
|
+
},
|
|
1730
|
+
]),
|
|
1731
|
+
}, activeControls());
|
|
1732
|
+
expect(queryInputs[0]?.prompt).toContain("Sin entrada, paga en 24 meses");
|
|
1733
|
+
expect(queryInputs[0]?.reminder).toContain("Read again any of them you work on");
|
|
1734
|
+
expect(queryInputs[0]?.reminder).toContain("- src/pages/home/hero.md");
|
|
1735
|
+
expect(told).toBe(1);
|
|
1736
|
+
});
|
|
1737
|
+
it("keeps the note for the next turn when the user stops this one while the workspace catches up", async () => {
|
|
1738
|
+
const queryInputs = [];
|
|
1739
|
+
const controls = activeControls();
|
|
1740
|
+
let told = 0;
|
|
1741
|
+
const executor = createExecutor({
|
|
1742
|
+
queryInputs,
|
|
1743
|
+
catchUpWithMain: () => {
|
|
1744
|
+
controls.deactivate();
|
|
1745
|
+
return Promise.resolve({
|
|
1746
|
+
inWorkspace: false,
|
|
1747
|
+
changed: ["src/pages/home/hero.md"],
|
|
1748
|
+
told: () => {
|
|
1749
|
+
told += 1;
|
|
1750
|
+
return Promise.resolve();
|
|
1751
|
+
},
|
|
1752
|
+
});
|
|
1753
|
+
},
|
|
1754
|
+
});
|
|
1755
|
+
const outcome = await executor.execute({ threadId: "thread_stopped", turnId: "turn_stopped", prompt: "Cambia el hero", history: history([]) }, controls);
|
|
1756
|
+
expect(outcome.kind).toBe("cancelled");
|
|
1757
|
+
expect(queryInputs).toHaveLength(0);
|
|
1758
|
+
expect(told).toBe(0);
|
|
1759
|
+
});
|
|
1760
|
+
it("keeps the note for the next turn when the user stops this one before its prompt goes out", async () => {
|
|
1761
|
+
const queryInputs = [];
|
|
1762
|
+
const controls = activeControls();
|
|
1763
|
+
let told = 0;
|
|
1764
|
+
const executor = createExecutor({
|
|
1765
|
+
queryInputs,
|
|
1766
|
+
mcpServersProvider: () => {
|
|
1767
|
+
controls.deactivate();
|
|
1768
|
+
return Promise.resolve(undefined);
|
|
1769
|
+
},
|
|
1770
|
+
catchUpWithMain: () => Promise.resolve({
|
|
1771
|
+
inWorkspace: true,
|
|
1772
|
+
changed: ["src/pages/home/hero.md"],
|
|
1773
|
+
told: () => {
|
|
1774
|
+
told += 1;
|
|
1775
|
+
return Promise.resolve();
|
|
1776
|
+
},
|
|
1777
|
+
}),
|
|
1778
|
+
});
|
|
1779
|
+
await executor.execute({ threadId: "thread_stopped_late", turnId: "turn_stopped_late", prompt: "Cambia el hero", history: history([]) }, controls);
|
|
1780
|
+
expect(told).toBe(0);
|
|
1781
|
+
});
|
|
1782
|
+
it("leaves the workspace of a finished Session alone while it is reviewed", async () => {
|
|
1783
|
+
let caughtUp = false;
|
|
1784
|
+
const executor = createExecutor({
|
|
1785
|
+
catchUpWithMain: () => {
|
|
1786
|
+
caughtUp = true;
|
|
1787
|
+
return Promise.resolve(undefined);
|
|
1788
|
+
},
|
|
1789
|
+
});
|
|
1790
|
+
await executor.execute({
|
|
1791
|
+
threadId: "thread_review_sync",
|
|
1792
|
+
turnId: "turn_review_sync",
|
|
1793
|
+
prompt: "review",
|
|
1794
|
+
history: history([]),
|
|
1795
|
+
review: { threadIds: [], chatFacts: { chatId: "chat_1" }, outputRepair: true },
|
|
1796
|
+
}, activeControls());
|
|
1797
|
+
expect(caughtUp).toBe(false);
|
|
1798
|
+
});
|
|
1799
|
+
it("brings the CLI to the release Convex sent before the turn starts", async () => {
|
|
1800
|
+
const queryInputs = [];
|
|
1801
|
+
const requested = [];
|
|
1802
|
+
const executor = createExecutor({
|
|
1803
|
+
queryInputs,
|
|
1804
|
+
keepCliInStep: (wanted) => {
|
|
1805
|
+
requested.push({ wanted, turnStarted: queryInputs.length > 0 });
|
|
1806
|
+
return Promise.resolve();
|
|
1807
|
+
},
|
|
1808
|
+
});
|
|
1809
|
+
await executor.execute({ threadId: "thread_cli", turnId: "turn_cli", prompt: "Hola", cliVersion: "0.412.0", history: history([]) }, activeControls());
|
|
1810
|
+
expect(requested).toEqual([{ wanted: "0.412.0", turnStarted: false }]);
|
|
1811
|
+
expect(queryInputs).toHaveLength(1);
|
|
1812
|
+
});
|
|
1813
|
+
it("keeps the Session's CLI while it is reviewed", async () => {
|
|
1814
|
+
const wanted = [];
|
|
1815
|
+
const executor = createExecutor({
|
|
1816
|
+
keepCliInStep: (version) => {
|
|
1817
|
+
wanted.push(version);
|
|
1818
|
+
return Promise.resolve();
|
|
1819
|
+
},
|
|
1820
|
+
});
|
|
1821
|
+
await executor.execute({
|
|
1822
|
+
threadId: "thread_review_cli",
|
|
1823
|
+
turnId: "turn_review_cli",
|
|
1824
|
+
prompt: "review",
|
|
1825
|
+
cliVersion: "0.412.0",
|
|
1826
|
+
history: history([]),
|
|
1827
|
+
review: { threadIds: [], chatFacts: { chatId: "chat_1" }, outputRepair: true },
|
|
1828
|
+
}, activeControls());
|
|
1829
|
+
expect(wanted).toEqual([]);
|
|
1830
|
+
});
|
|
1671
1831
|
it("keeps the viewing-reference context beside the message when a stale session falls back to rehydration", async () => {
|
|
1672
1832
|
const queryInputs = [];
|
|
1673
1833
|
const executor = createExecutor({
|
|
@@ -1771,6 +1931,36 @@ describe("BridgeJobExecutor", () => {
|
|
|
1771
1931
|
expect(queryInputs[0]?.options).toMatchObject({ resume: "session_interrupted", forkSession: true });
|
|
1772
1932
|
expect(relay.contextSources.map((entry) => entry.source)).toEqual(["interrupted_resume"]);
|
|
1773
1933
|
});
|
|
1934
|
+
it("tells a turn sent again after a restart what another chat published while it was down", async () => {
|
|
1935
|
+
const queryInputs = [];
|
|
1936
|
+
let told = 0;
|
|
1937
|
+
const executor = createExecutor({
|
|
1938
|
+
loadedBoundary: cleanBoundary("session_clean"),
|
|
1939
|
+
queryInputs,
|
|
1940
|
+
inFlightTurns: memoryInFlightTurns({
|
|
1941
|
+
version: 1,
|
|
1942
|
+
turnId: "turn_interrupted_sync",
|
|
1943
|
+
sessionId: "session_interrupted",
|
|
1944
|
+
updatedAtMs: 1,
|
|
1945
|
+
}),
|
|
1946
|
+
catchUpWithMain: () => Promise.resolve({
|
|
1947
|
+
inWorkspace: false,
|
|
1948
|
+
changed: ["src/pages/home/hero.md"],
|
|
1949
|
+
told: () => {
|
|
1950
|
+
told += 1;
|
|
1951
|
+
return Promise.resolve();
|
|
1952
|
+
},
|
|
1953
|
+
}),
|
|
1954
|
+
});
|
|
1955
|
+
await executor.execute({
|
|
1956
|
+
threadId: "thread_interrupted_sync",
|
|
1957
|
+
turnId: "turn_interrupted_sync",
|
|
1958
|
+
prompt: "Rebuild the five pages",
|
|
1959
|
+
}, activeControls());
|
|
1960
|
+
expect(queryInputs[0]?.prompt).toBe(INTERRUPTED_RESUME_PROMPT);
|
|
1961
|
+
expect(queryInputs[0]?.reminder).toContain("- src/pages/home/hero.md");
|
|
1962
|
+
expect(told).toBe(1);
|
|
1963
|
+
});
|
|
1774
1964
|
it("runs the turn the ordinary way when the interrupted session cannot be resumed", async () => {
|
|
1775
1965
|
const relay = recordingRelay();
|
|
1776
1966
|
const queryInputs = [];
|
|
@@ -1799,23 +1989,6 @@ describe("BridgeJobExecutor", () => {
|
|
|
1799
1989
|
expect(clearCalls).toEqual([]);
|
|
1800
1990
|
expect(relay.contextSources.map((entry) => entry.source)).toEqual(["interrupted_resume", "local_resume"]);
|
|
1801
1991
|
});
|
|
1802
|
-
it("keeps the chat's conversation when an interrupted publish that cannot be resumed is run again", async () => {
|
|
1803
|
-
const executor = createExecutor({
|
|
1804
|
-
loadedBoundary: cleanBoundary("session_clean"),
|
|
1805
|
-
inFlightTurns: memoryInFlightTurns({
|
|
1806
|
-
version: 1,
|
|
1807
|
-
turnId: "turn_publish",
|
|
1808
|
-
sessionId: "session_never_written",
|
|
1809
|
-
updatedAtMs: 1,
|
|
1810
|
-
}),
|
|
1811
|
-
queryResults: [
|
|
1812
|
-
scriptedError(new Error("No conversation found with session ID: session_never_written")),
|
|
1813
|
-
scriptedMessages(assistantMessage("assistant_published", "Published", "session_publish_only"), resultMessage(0.2, "session_publish_only")),
|
|
1814
|
-
],
|
|
1815
|
-
});
|
|
1816
|
-
const outcome = await executor.execute({ threadId: "thread_publish", turnId: "turn_publish", prompt: "/publish" }, activeControls());
|
|
1817
|
-
expect(outcome).toMatchObject({ kind: "completed", cleanBoundary: undefined });
|
|
1818
|
-
});
|
|
1819
1992
|
it("keeps the running turn's session on record until the turn ends", async () => {
|
|
1820
1993
|
const recorded = [];
|
|
1821
1994
|
const inFlightTurns = memoryInFlightTurns();
|