@circuitwall/jarela 1.10.4 → 1.10.5

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 (44) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +2 -2
  3. package/.next/standalone/.next/build-manifest.json +2 -2
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/.next/standalone/.next/server/app/api/v1/page-capture/route.js +10 -3
  24. package/.next/standalone/.next/server/app/api/v1/page-capture/route.js.map +1 -1
  25. package/.next/standalone/.next/server/app/page.js +22 -0
  26. package/.next/standalone/.next/server/app/page.js.map +1 -1
  27. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  28. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  29. package/.next/standalone/.next/server/app-paths-manifest.json +2 -2
  30. package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
  31. package/.next/standalone/.next/server/pages/404.html +1 -1
  32. package/.next/standalone/.next/server/pages/500.html +1 -1
  33. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  34. package/.next/standalone/.next/static/chunks/app/{page-0366858d51dcb010.js → page-cd9a49afddd6b235.js} +23 -1
  35. package/.next/standalone/.next/static/chunks/app/page-cd9a49afddd6b235.js.map +1 -0
  36. package/.next/standalone/package.json +1 -1
  37. package/CHANGELOG.md +30 -0
  38. package/hooks/useUrlSync.ts +12 -0
  39. package/lib/api/page-capture.test.ts +25 -0
  40. package/lib/api/page-capture.ts +12 -3
  41. package/package.json +1 -1
  42. package/.next/standalone/.next/static/chunks/app/page-0366858d51dcb010.js.map +0 -1
  43. /package/.next/standalone/.next/static/{7U96FzR9cJGMv_4BS_gE2 → AhDiI5iITDaU_AJBer8wi}/_buildManifest.js +0 -0
  44. /package/.next/standalone/.next/static/{7U96FzR9cJGMv_4BS_gE2 → AhDiI5iITDaU_AJBer8wi}/_ssgManifest.js +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@circuitwall/jarela",
3
- "version": "1.10.4",
3
+ "version": "1.10.5",
4
4
  "description": "Jarela — local chat interface for LangGraph agents (multi-provider, single-process, SQLite-backed).",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Andrew Ge Wu",
package/CHANGELOG.md CHANGED
@@ -7,6 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.10.5] - 2026-06-14
11
+
12
+ ### Fixed
13
+
14
+ - **Picker ignored the popup's selected agent.** Clicking "Pick
15
+ element" with a non-default agent selected in the browser
16
+ extension popup used to drop the captured element into the
17
+ default agent's last-active thread. The picker's
18
+ `jarela-capture` payload now goes through `withSelectedAgent`,
19
+ and the `/api/v1/page-capture` endpoint accepts an optional
20
+ `agent_id` and honours it (falling back to the default agent if
21
+ the requested id is unknown).
22
+ - **Open Jarela ignored the popup's selected agent.** The popup's
23
+ side-panel opener, the options-page button, and the panel
24
+ iframe all now forward the selected agent id via `?agent=<id>`;
25
+ `useUrlSync` consumes it on initial mount and on popstate so
26
+ the app lands directly on the picked agent's chat.
27
+ - **Agent-control banner flickered between commands.** During a
28
+ multi-step agent run the overlay used to fade out at the end of
29
+ every single command and back in at the start of the next,
30
+ making it look like the agent kept losing control. The hide
31
+ is now debounced by 5s — a new command in the chain cancels
32
+ the pending hide so the banner stays put while the agent is
33
+ actively driving the tab.
34
+ - **Pinning a tab while another was pinned required three
35
+ clicks** (Unpin → switch → Pin). The "Pin this tab" button now
36
+ stays visible when the foreground differs from the pinned tab
37
+ (labelled "Pin this tab instead") and atomically replaces the
38
+ existing pin in one click.
39
+
10
40
  ## [1.10.4] - 2026-06-14
11
41
 
12
42
  ### Added
@@ -36,6 +36,18 @@ export function useUrlSync() {
36
36
  tab = "tools";
37
37
  item = "packages";
38
38
  }
39
+ // Browser-extension "Open Jarela" passes ?agent=<id> (and optionally
40
+ // ?thread=<id>) so the app lands on the user's currently-picked
41
+ // target agent instead of whichever chat was last open. The agent
42
+ // hint is one-shot — the SET_AGENT / SELECT_THREAD dispatch below
43
+ // triggers the second effect, which rewrites the URL via buildHref
44
+ // and drops the hint.
45
+ if (parsed.thread && parsed.agent) {
46
+ dispatch({ type: "SELECT_THREAD", threadId: parsed.thread, agentId: parsed.agent });
47
+ } else if (parsed.agent) {
48
+ dispatch({ type: "SET_AGENT", agentId: parsed.agent });
49
+ dispatch({ type: "SET_TAB", tab: "chat" });
50
+ }
39
51
  if (TABS.includes(tab)) {
40
52
  dispatch({ type: "SET_TAB", tab });
41
53
  dispatch({ type: "SET_SELECTION", tab, itemId: item });
@@ -171,6 +171,31 @@ describe("handlePageCapture — thread targeting", () => {
171
171
  expect(res.status).toBe(503);
172
172
  expect(createThreadMock).not.toHaveBeenCalled();
173
173
  });
174
+
175
+ it("honors an explicit agent_id over the default", async () => {
176
+ getDefaultAgentConfigMock.mockReturnValue({ id: "default-agent", name: "Default" });
177
+ listAgentConfigsMock.mockReturnValue([
178
+ { id: "default-agent", name: "Default" },
179
+ { id: "picked-agent", name: "Picked" },
180
+ ]);
181
+ listThreadsByAgentMock.mockImplementation((agent_id: string) =>
182
+ agent_id === "picked-agent"
183
+ ? [{ thread_id: "picked-thread", title: "Picked recent" }]
184
+ : [{ thread_id: "default-thread", title: "Default recent" }]
185
+ );
186
+
187
+ const res = await handlePageCapture(makeReq({ ...validBody, agent_id: "picked-agent" }));
188
+ expect(res.status).toBe(200);
189
+ expect(listThreadsByAgentMock).toHaveBeenCalledWith("picked-agent", 1);
190
+ expect(addMessageMock).toHaveBeenCalledWith("picked-thread", "user", expect.any(String), undefined, "page_capture");
191
+ });
192
+
193
+ it("falls back to the default agent when the explicit agent_id is unknown", async () => {
194
+ listAgentConfigsMock.mockReturnValue([{ id: "default-agent", name: "Default" }]);
195
+ const res = await handlePageCapture(makeReq({ ...validBody, agent_id: "never-existed" }));
196
+ expect(res.status).toBe(200);
197
+ expect(listThreadsByAgentMock).toHaveBeenCalledWith("default-agent", 1);
198
+ });
174
199
  });
175
200
 
176
201
  describe("handlePageCapture — message body", () => {
@@ -44,6 +44,11 @@ const Body = z.object({
44
44
  tagName: z.string().max(64).optional(),
45
45
  text: z.string(),
46
46
  capturedAt: z.string().datetime(),
47
+ // Optional explicit agent target. When the browser extension has a
48
+ // "send to" agent picked in its popup, the SW forwards that id here so
49
+ // the capture lands in *that* agent's chat instead of silently routing
50
+ // to the system default.
51
+ agent_id: z.string().min(1).max(200).optional(),
47
52
  // Optional base64-encoded PNG of just the picked element (no data: URL
48
53
  // prefix). The content script crops `chrome.tabs.captureVisibleTab`
49
54
  // to the element bounding box before sending. When present, it is
@@ -84,9 +89,13 @@ interface PickResult {
84
89
  created: boolean;
85
90
  }
86
91
 
87
- function pickThread(): PickResult | { error: "no-agent" } {
92
+ function pickThread(explicitAgentId?: string): PickResult | { error: "no-agent" } {
93
+ const requested = typeof explicitAgentId === "string" ? explicitAgentId.trim() : "";
94
+ const explicit: AgentConfigRow | null = requested
95
+ ? listAgentConfigs().find((a) => a.id === requested) ?? null
96
+ : null;
88
97
  const def: AgentConfigRow | null = getDefaultAgentConfig();
89
- const agent: AgentConfigRow | null = def ?? listAgentConfigs()[0] ?? null;
98
+ const agent: AgentConfigRow | null = explicit ?? def ?? listAgentConfigs()[0] ?? null;
90
99
  if (!agent) return { error: "no-agent" };
91
100
 
92
101
  const recent: ThreadRow[] = listThreadsByAgent(agent.id, 1);
@@ -157,7 +166,7 @@ export async function handlePageCapture(req: Request): Promise<Response> {
157
166
  }
158
167
  const input = parsed.data;
159
168
 
160
- const picked = pickThread();
169
+ const picked = pickThread(input.agent_id);
161
170
  if ("error" in picked) {
162
171
  return new Response(JSON.stringify({ error: "no agent configured" }), {
163
172
  status: 503,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@circuitwall/jarela",
3
- "version": "1.10.4",
3
+ "version": "1.10.5",
4
4
  "description": "Jarela — local chat interface for LangGraph agents (multi-provider, single-process, SQLite-backed).",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Andrew Ge Wu",