@sideboard-ai/core 0.1.262 → 0.1.263

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 (55) hide show
  1. package/dist/{abletime-OQ4PC52L.js → abletime-6AOJI2YZ.js} +4 -4
  2. package/dist/{abletime-CDGINDXG.js → abletime-U75ZGDIX.js} +5 -5
  3. package/dist/{abletime-oauth-KX2TDFTE.js → abletime-oauth-LOAHGG4X.js} +3 -3
  4. package/dist/{abletime-oauth-5A5EOH2A.js → abletime-oauth-TA2YDCYX.js} +4 -4
  5. package/dist/{abletime-rest-UEHOBLXD.js → abletime-rest-CTA5WV26.js} +4 -4
  6. package/dist/{abletime-rest-PUGKYTRR.js → abletime-rest-YZPFM6IY.js} +3 -3
  7. package/dist/agents/claude-runner.cjs +463 -0
  8. package/dist/agents/claude-runner.d.cts +1 -0
  9. package/dist/agents/claude-runner.d.ts +1 -0
  10. package/dist/agents/claude-runner.js +134 -0
  11. package/dist/agents/cursor-runner.cjs +388 -7
  12. package/dist/agents/cursor-runner.js +34 -7
  13. package/dist/{agents-J2P4KNEY.js → agents-3TUMFSMH.js} +10 -9
  14. package/dist/{agents-IKVUGW5H.js → agents-6FWDRVA2.js} +4 -4
  15. package/dist/{app-settings-OM7H64YM.js → app-settings-MVZPM6WW.js} +1 -1
  16. package/dist/{app-settings-VQEUCONM.js → app-settings-RKFFUIFQ.js} +2 -2
  17. package/dist/{chunk-6PFZ6XO7.js → chunk-2QUQH2SZ.js} +81 -6
  18. package/dist/{chunk-VIC6TDYT.js → chunk-36FOBJBF.js} +76 -3
  19. package/dist/{chunk-ABPNIYRS.js → chunk-3H7O27X2.js} +389 -102
  20. package/dist/{chunk-FSZ7YYFQ.js → chunk-4ALDX5IO.js} +5 -3
  21. package/dist/{chunk-5OKJDCBK.js → chunk-5PK53SAP.js} +5 -5
  22. package/dist/{chunk-U3AOJLH3.js → chunk-5ZPT5YAV.js} +8 -6
  23. package/dist/{chunk-YFTO7U2A.js → chunk-6YOXQVJ7.js} +3 -3
  24. package/dist/{chunk-J6ONZP74.js → chunk-6YY7XPPL.js} +5 -5
  25. package/dist/{chunk-WV7KJH2E.js → chunk-A5SAYFJ4.js} +1 -0
  26. package/dist/{chunk-B6XFBNYM.js → chunk-BOMSJUXW.js} +2 -2
  27. package/dist/{chunk-S7VDDJ34.js → chunk-CEOTK5GZ.js} +3 -3
  28. package/dist/{chunk-4F7J6UWD.js → chunk-EK3KVT7I.js} +515 -139
  29. package/dist/{chunk-HHEKVR6C.js → chunk-F5MFNUAA.js} +40 -2
  30. package/dist/{chunk-KVQX62XI.js → chunk-K7B25HO4.js} +3 -3
  31. package/dist/{chunk-JTNY5CK4.js → chunk-L5WGAIL2.js} +46 -46
  32. package/dist/chunk-NYBFYFK7.js +415 -0
  33. package/dist/{chunk-GIZQAOHZ.js → chunk-QX6QUZVD.js} +121 -91
  34. package/dist/{chunk-X2OTZ36G.js → chunk-RKPBIB2U.js} +52 -52
  35. package/dist/{chunk-W5PWGEKS.js → chunk-T3AYRQJZ.js} +107 -77
  36. package/dist/{chunk-D554YCHG.js → chunk-YKYEHDMX.js} +2 -2
  37. package/dist/connected-teams-RU6VATCM.js +1 -1
  38. package/dist/{coordinator-prompt-VQHQ3RIX.js → coordinator-prompt-HZCQZ6C5.js} +6 -6
  39. package/dist/{coordinator-prompt-TU6656OK.js → coordinator-prompt-J7DKHOCH.js} +3 -3
  40. package/dist/{global-workspace-PHF2MOGW.js → global-workspace-6LDUZ2NF.js} +3 -3
  41. package/dist/{global-workspace-47NZVA44.js → global-workspace-TI26K25J.js} +6 -6
  42. package/dist/index.cjs +1712 -721
  43. package/dist/index.d.cts +181 -41
  44. package/dist/index.d.ts +181 -41
  45. package/dist/index.js +693 -285
  46. package/dist/mcp/run-stdio.cjs +10469 -9896
  47. package/dist/mcp/run-stdio.js +193 -168
  48. package/dist/{orchestrator-VLTO5JBR.js → orchestrator-4JSG7BWC.js} +5 -5
  49. package/dist/{orchestrator-OCG4QVA5.js → orchestrator-5YU46YNS.js} +11 -10
  50. package/dist/{workspaces-I7TWFTJM.js → workspaces-QJ3XIPUJ.js} +6 -6
  51. package/dist/{workspaces-2XTDS7N2.js → workspaces-WOQHJFRQ.js} +3 -3
  52. package/dist/{worktree-DDDF3WHV.js → worktree-6U2FA5LO.js} +2 -2
  53. package/dist/{worktree-YASFE65H.js → worktree-KQA4ON2G.js} +5 -5
  54. package/package.json +4 -3
  55. /package/dist/{chunk-LDXSAVWO.js → chunk-GWFVCCJZ.js} +0 -0
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ AGENT_RPC_CLAUDE_SDK_SERVER,
4
+ PILOT_TOOL_DESCRIPTIONS,
5
+ createPilotRpcExecutors
6
+ } from "../chunk-NYBFYFK7.js";
7
+ import {
8
+ dropNestedElectronEnvFromProcess
9
+ } from "../chunk-4TR3HZFT.js";
10
+ import "../chunk-EHT2DRT4.js";
11
+
12
+ // src/agents/claude-runner.ts
13
+ import { createInterface } from "readline";
14
+
15
+ // src/agents/claude-sdk-tools.ts
16
+ import { z } from "zod";
17
+ function textResult(text) {
18
+ return { content: [{ type: "text", text }] };
19
+ }
20
+ function createClaudePilotSdkServer(createSdkMcpServer, tool, opts) {
21
+ const exec = createPilotRpcExecutors(opts);
22
+ const server = createSdkMcpServer({
23
+ name: AGENT_RPC_CLAUDE_SDK_SERVER,
24
+ version: "1.0.0",
25
+ timeout: 18e4,
26
+ tools: [
27
+ tool(
28
+ "present_artifact",
29
+ PILOT_TOOL_DESCRIPTIONS.present_artifact,
30
+ {
31
+ title: z.string(),
32
+ type: z.enum(["html", "svg", "markdown", "react", "log"]),
33
+ content: z.string(),
34
+ artifact_id: z.string().optional(),
35
+ status: z.enum(["running", "ok", "failed", "idle"]).optional(),
36
+ phase: z.string().optional(),
37
+ mode: z.enum(["append", "replace"]).optional()
38
+ },
39
+ async (args) => textResult(await exec.present_artifact(args))
40
+ ),
41
+ tool(
42
+ "wait_for_job",
43
+ PILOT_TOOL_DESCRIPTIONS.wait_for_job,
44
+ { id: z.string() },
45
+ async (args) => textResult(await exec.wait_for_job(args))
46
+ ),
47
+ tool(
48
+ "stop_job",
49
+ PILOT_TOOL_DESCRIPTIONS.stop_job,
50
+ { id: z.string(), reason: z.string().optional() },
51
+ async (args) => textResult(await exec.stop_job(args))
52
+ )
53
+ ]
54
+ });
55
+ return { server, exec };
56
+ }
57
+
58
+ // src/agents/claude-runner.ts
59
+ dropNestedElectronEnvFromProcess();
60
+ function emit(value) {
61
+ process.stdout.write(`${JSON.stringify(value)}
62
+ `);
63
+ }
64
+ async function readStdin() {
65
+ const rl = createInterface({ input: process.stdin, crlfDelay: Infinity });
66
+ const chunks = [];
67
+ for await (const line of rl) chunks.push(line);
68
+ return chunks.join("\n").trim();
69
+ }
70
+ async function main() {
71
+ const raw = await readStdin();
72
+ if (!raw) {
73
+ emit({ type: "stderr", data: "claude-runner: empty stdin" });
74
+ process.exitCode = 1;
75
+ return;
76
+ }
77
+ const req = JSON.parse(raw);
78
+ if (!req.prompt || !req.cwd || !req.agentRpc || !req.claudePath) {
79
+ emit({ type: "stderr", data: "claude-runner: prompt, cwd, claudePath, and agentRpc are required" });
80
+ process.exitCode = 1;
81
+ return;
82
+ }
83
+ let sdk;
84
+ try {
85
+ sdk = await import("@anthropic-ai/claude-agent-sdk");
86
+ } catch (err) {
87
+ const message = err instanceof Error ? err.message : String(err);
88
+ emit({
89
+ type: "stderr",
90
+ data: `claude-runner: @anthropic-ai/claude-agent-sdk is required (${message})`
91
+ });
92
+ process.exitCode = 1;
93
+ return;
94
+ }
95
+ const { server, exec } = createClaudePilotSdkServer(
96
+ sdk.createSdkMcpServer,
97
+ sdk.tool,
98
+ { cwd: req.cwd, rpc: req.agentRpc }
99
+ );
100
+ const mcpServers = {
101
+ [AGENT_RPC_CLAUDE_SDK_SERVER]: server
102
+ };
103
+ for (const [name, spec] of Object.entries(req.mcpServers ?? {})) {
104
+ mcpServers[name] = spec;
105
+ }
106
+ try {
107
+ const options = {
108
+ cwd: req.cwd,
109
+ pathToClaudeCodeExecutable: req.claudePath,
110
+ permissionMode: req.permissionMode,
111
+ allowedTools: req.allowedTools,
112
+ mcpServers,
113
+ includePartialMessages: true
114
+ };
115
+ if (req.sessionId) options.resume = req.sessionId;
116
+ if (req.model) options.model = req.model;
117
+ if (req.systemPrompt) options.appendSystemPrompt = req.systemPrompt;
118
+ if (req.effort) options.effort = req.effort;
119
+ if (req.chrome) options.chrome = true;
120
+ options.settingSources = [];
121
+ for await (const message of sdk.query({ prompt: req.prompt, options })) {
122
+ emit(message);
123
+ }
124
+ } finally {
125
+ exec.close();
126
+ }
127
+ }
128
+ main().catch((err) => {
129
+ emit({
130
+ type: "stderr",
131
+ data: err instanceof Error ? err.message : String(err)
132
+ });
133
+ process.exitCode = 1;
134
+ });
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/agents/cursor-runner.ts
27
- var import_node_fs16 = require("fs");
27
+ var import_node_fs17 = require("fs");
28
28
  var import_node_readline2 = require("readline");
29
29
 
30
30
  // src/hook/nested-electron-env.ts
@@ -716,9 +716,365 @@ function slicedReadCustomToolConfig(cwd) {
716
716
  };
717
717
  }
718
718
 
719
- // src/agents/tool-result-clip.ts
719
+ // src/agent-rpc/client.ts
720
+ var import_ws = require("ws");
721
+
722
+ // src/agent-rpc/protocol.ts
723
+ var AGENT_RPC_PROTOCOL_VERSION = 1;
724
+ var AGENT_RPC_TOKEN_QUERY = "authToken";
725
+ function isJsonRpcNotification(value) {
726
+ if (!value || typeof value !== "object") return false;
727
+ const rec = value;
728
+ if (rec.jsonrpc !== "2.0") return false;
729
+ if (typeof rec.method !== "string" || !rec.method.trim()) return false;
730
+ if ("id" in rec && rec.id !== void 0) return false;
731
+ if ("error" in rec || "result" in rec) return false;
732
+ return true;
733
+ }
734
+ function parseRpcFrame(raw) {
735
+ try {
736
+ return JSON.parse(raw);
737
+ } catch {
738
+ return void 0;
739
+ }
740
+ }
741
+
742
+ // src/agent-rpc/metadata.ts
720
743
  var import_node_fs15 = require("fs");
721
744
  var import_node_path17 = require("path");
745
+ function agentRuntimeMetadataPath() {
746
+ return (0, import_node_path17.join)(appDataDir(), "agent-runtime.json");
747
+ }
748
+ function readAgentRuntimeMetadata() {
749
+ try {
750
+ const raw = JSON.parse((0, import_node_fs15.readFileSync)(agentRuntimeMetadataPath(), "utf8"));
751
+ if (!raw || typeof raw !== "object") return null;
752
+ const rec = raw;
753
+ if (typeof rec.runtimeId !== "string" || !rec.runtimeId.trim()) return null;
754
+ if (typeof rec.authToken !== "string" || !rec.authToken.trim()) return null;
755
+ const pid = Number(rec.pid);
756
+ if (!Number.isInteger(pid) || pid <= 0) return null;
757
+ const transports = Array.isArray(rec.transports) ? rec.transports : [];
758
+ const ws = transports.filter((t) => {
759
+ if (!t || typeof t !== "object") return false;
760
+ const row = t;
761
+ return row.kind === "websocket" && typeof row.url === "string" && Boolean(row.url.trim());
762
+ });
763
+ return {
764
+ runtimeId: rec.runtimeId.trim(),
765
+ pid,
766
+ protocolVersion: Number(rec.protocolVersion) || AGENT_RPC_PROTOCOL_VERSION,
767
+ authToken: rec.authToken,
768
+ startedAt: Number(rec.startedAt) || 0,
769
+ transports: ws
770
+ };
771
+ } catch {
772
+ return null;
773
+ }
774
+ }
775
+ function websocketUrlFromMetadata(meta) {
776
+ const url = meta?.transports.find((t) => t.kind === "websocket")?.url?.trim();
777
+ return url || null;
778
+ }
779
+ function agentRpcConnectFromMetadata(meta = readAgentRuntimeMetadata()) {
780
+ if (!agentRuntimeLooksLive(meta)) return null;
781
+ const url = websocketUrlFromMetadata(meta);
782
+ const authToken = meta?.authToken;
783
+ if (!url || !authToken) return null;
784
+ return { url, authToken };
785
+ }
786
+ function pidAlive(pid) {
787
+ try {
788
+ process.kill(pid, 0);
789
+ return true;
790
+ } catch {
791
+ return false;
792
+ }
793
+ }
794
+ function agentRuntimeLooksLive(meta = readAgentRuntimeMetadata()) {
795
+ if (!meta) return false;
796
+ return pidAlive(meta.pid);
797
+ }
798
+
799
+ // src/agent-rpc/client.ts
800
+ var AgentRpcClient = class {
801
+ ws = null;
802
+ pending = /* @__PURE__ */ new Map();
803
+ nextId = 1;
804
+ url;
805
+ authToken;
806
+ notifyListeners = /* @__PURE__ */ new Set();
807
+ constructor(opts = {}) {
808
+ const connect = opts.url && opts.authToken ? { url: opts.url, authToken: opts.authToken } : agentRpcConnectFromMetadata();
809
+ if (!connect) throw new Error("Agent RPC runtime is not running (no live agent-runtime.json)");
810
+ this.url = connect.url;
811
+ this.authToken = connect.authToken;
812
+ }
813
+ onNotify(fn) {
814
+ this.notifyListeners.add(fn);
815
+ return () => this.notifyListeners.delete(fn);
816
+ }
817
+ async call(method, params) {
818
+ const ws = await this.ensureSocket();
819
+ const id = this.nextId;
820
+ this.nextId += 1;
821
+ const key = String(id);
822
+ const payload = {
823
+ jsonrpc: "2.0",
824
+ id,
825
+ method,
826
+ params,
827
+ authToken: this.authToken
828
+ };
829
+ return new Promise((resolve2, reject) => {
830
+ this.pending.set(key, { resolve: resolve2, reject });
831
+ try {
832
+ ws.send(JSON.stringify(payload));
833
+ } catch (err) {
834
+ this.pending.delete(key);
835
+ reject(err instanceof Error ? err : new Error(String(err)));
836
+ }
837
+ });
838
+ }
839
+ socketUrl() {
840
+ const url = new URL(this.url);
841
+ url.searchParams.set(AGENT_RPC_TOKEN_QUERY, this.authToken);
842
+ return url.toString();
843
+ }
844
+ async ensureSocket() {
845
+ if (this.ws && this.ws.readyState === import_ws.WebSocket.OPEN) return this.ws;
846
+ const ws = new import_ws.WebSocket(this.socketUrl());
847
+ this.ws = ws;
848
+ ws.on("message", (data) => this.onFrame(data.toString()));
849
+ ws.on("error", (err) => this.drop(ws, err));
850
+ ws.on("close", () => this.drop(ws, new Error("Agent RPC socket closed")));
851
+ ws.on("unexpected-response", (_req, res) => {
852
+ res.resume();
853
+ this.drop(
854
+ ws,
855
+ new Error(
856
+ res.statusCode === 401 ? "Unauthorized" : `Unexpected server response: ${res.statusCode}`
857
+ )
858
+ );
859
+ });
860
+ await new Promise((resolve2, reject) => {
861
+ const fail = (err) => {
862
+ const message = err.message.includes("401") ? "Unauthorized" : err.message;
863
+ reject(message === err.message ? err : new Error(message));
864
+ };
865
+ ws.once("unexpected-response", (_req, res) => {
866
+ fail(
867
+ new Error(
868
+ res.statusCode === 401 ? "Unauthorized" : `Unexpected server response: ${res.statusCode}`
869
+ )
870
+ );
871
+ });
872
+ ws.once("error", fail);
873
+ ws.once("open", () => {
874
+ ws.off("error", fail);
875
+ resolve2();
876
+ });
877
+ });
878
+ return ws;
879
+ }
880
+ drop(ws, err) {
881
+ if (this.ws === ws) this.ws = null;
882
+ if (this.pending.size === 0) return;
883
+ this.failAll(err);
884
+ }
885
+ onFrame(raw) {
886
+ const parsed = parseRpcFrame(raw);
887
+ if (parsed === void 0) return;
888
+ if (isJsonRpcNotification(parsed)) {
889
+ for (const fn of this.notifyListeners) fn(parsed);
890
+ return;
891
+ }
892
+ if (!parsed || typeof parsed !== "object") return;
893
+ const rec = parsed;
894
+ if (rec.id === void 0 || rec.id === null) return;
895
+ const key = String(rec.id);
896
+ const waiter = this.pending.get(key);
897
+ if (!waiter) return;
898
+ this.pending.delete(key);
899
+ if (rec.error && typeof rec.error === "object") {
900
+ const err = rec.error;
901
+ waiter.reject(new Error(err.message || "Agent RPC error"));
902
+ return;
903
+ }
904
+ waiter.resolve(rec.result);
905
+ }
906
+ failAll(err) {
907
+ for (const waiter of this.pending.values()) waiter.reject(err);
908
+ this.pending.clear();
909
+ }
910
+ close() {
911
+ const ws = this.ws;
912
+ this.ws = null;
913
+ this.failAll(new Error("Agent RPC client closed"));
914
+ if (ws) {
915
+ try {
916
+ ws.close();
917
+ } catch {
918
+ }
919
+ }
920
+ }
921
+ };
922
+
923
+ // src/agent-rpc/pilot-tools.ts
924
+ var PILOT_TOOL_DESCRIPTIONS = {
925
+ present_artifact: "Show a document or live log in Sideboard\u2019s side column. For html/svg/markdown/react, pass the FULL document and do not also fence that same body in chat. For type=log, pass only NEW lines (same artifact_id appends). Prefer type=log for long-running job output \u2014 do not resend HTML. type=react is a single default-export component (JSX/TSX); only react/react-dom imports.",
926
+ wait_for_job: "Wait until a detached long job (tests, pack, deploy, connector CLI) finishes. This call stays open for up to ~2 minutes. stillRunning true means the runtime hit the max hold; call wait_for_job again immediately. If the job is hanging, producing no useful output, or doing the wrong thing, call stop_job instead. Do not end the turn or tell the user you will let them know later.",
927
+ stop_job: "Stop a detached job you started with detached-job.cjs when it is hanging, producing no useful output, buffering forever, or doing the wrong thing (wrong project, infinite watch, huge dump). Do not stop a pack/test/deploy that is clearly making progress."
928
+ };
929
+ var WAIT_FOR_TURN_DESCRIPTION = "Wait until the chat finishes its current/queued turn, or return early with a live progress snapshot. This call stays open for up to ~2 minutes. taskState is the A2A-style lifecycle: submitted (queued, not started), working, input-required (ask_user), completed, failed, canceled. stillRunning is true only for submitted/working. If stillRunning, text and usage are empty (they would be the previous turn) \u2014 read progress and call wait_for_turn again. Do not send_to_chat a check-in (that steers / interrupts). On failed, lastError/text is the failure. On canceled, the child did not finish \u2014 resume with send_to_chat or tell the user. On input-required, wait for the user in that chat. When finished, text is this turn\u2019s assistant reply and usage is that turn\u2019s tokens + costUsd (this turn, not the Claude session total; sessionCostUsd is the provider session total when present). lastActivityAt is the latest transcript/live stamp \u2014 present after the turn completes, not only while it is running.";
930
+ var WAIT_FOR_TURN_SCHEMA = {
931
+ type: "object",
932
+ properties: {
933
+ ref: {
934
+ type: "string",
935
+ description: "Worktree thread id or ref to wait on (not the orchestrator)"
936
+ },
937
+ timeoutMs: {
938
+ type: "number",
939
+ description: "Optional cap for this hold (ms). Ignored above the runtime max (~2 minutes)."
940
+ }
941
+ },
942
+ required: ["ref"]
943
+ };
944
+ var PILOT_TOOL_SCHEMAS = {
945
+ present_artifact: {
946
+ type: "object",
947
+ properties: {
948
+ title: {
949
+ type: "string",
950
+ description: "Short title shown in the artifact pane header"
951
+ },
952
+ type: {
953
+ type: "string",
954
+ enum: ["html", "svg", "markdown", "react", "log"],
955
+ description: "html/svg/markdown/react replace the pane. log appends content to the same artifact_id (new lines only)."
956
+ },
957
+ content: {
958
+ type: "string",
959
+ description: "html/svg/markdown/react: full document. log: only the new lines since the last call (empty is ok for a status-only update)."
960
+ },
961
+ artifact_id: {
962
+ type: "string",
963
+ description: "Stable id. Required for type=log so later calls append to the same pane."
964
+ },
965
+ status: {
966
+ type: "string",
967
+ enum: ["running", "ok", "failed", "idle"]
968
+ },
969
+ phase: { type: "string" },
970
+ mode: { type: "string", enum: ["append", "replace"] }
971
+ },
972
+ required: ["title", "type", "content"]
973
+ },
974
+ wait_for_job: {
975
+ type: "object",
976
+ properties: {
977
+ id: {
978
+ type: "string",
979
+ description: "Detached job id (same kebab-case id passed to detached-job.cjs start)"
980
+ }
981
+ },
982
+ required: ["id"]
983
+ },
984
+ stop_job: {
985
+ type: "object",
986
+ properties: {
987
+ id: {
988
+ type: "string",
989
+ description: "Detached job id (same kebab-case id passed to detached-job.cjs start)"
990
+ },
991
+ reason: { type: "string" }
992
+ },
993
+ required: ["id"]
994
+ }
995
+ };
996
+ function jsonToolResult(value) {
997
+ return JSON.stringify(value);
998
+ }
999
+ function jsonToolError(err) {
1000
+ const message = err instanceof Error ? err.message : String(err);
1001
+ return jsonToolResult({ ok: false, error: message });
1002
+ }
1003
+ function createPilotRpcExecutors(opts) {
1004
+ const client = new AgentRpcClient(opts.rpc);
1005
+ let waitToolCallId;
1006
+ if (opts.onProgress) {
1007
+ const onProgress = opts.onProgress;
1008
+ client.onNotify((msg) => {
1009
+ if (msg.method === "runtime.progress") onProgress(msg.params, waitToolCallId);
1010
+ });
1011
+ }
1012
+ const call = async (method, args) => {
1013
+ try {
1014
+ return jsonToolResult(await client.call(method, args));
1015
+ } catch (err) {
1016
+ return jsonToolError(err);
1017
+ }
1018
+ };
1019
+ const callJob = (method, args) => call(method, { ...args, cwd: opts.cwd });
1020
+ return {
1021
+ present_artifact: (args) => call("ui.presentArtifact", args),
1022
+ wait_for_job: async (args, context) => {
1023
+ const prev = waitToolCallId;
1024
+ waitToolCallId = typeof context?.toolCallId === "string" ? context.toolCallId : void 0;
1025
+ try {
1026
+ return await callJob("job.wait", args);
1027
+ } finally {
1028
+ waitToolCallId = prev;
1029
+ }
1030
+ },
1031
+ stop_job: (args) => callJob("job.stop", args),
1032
+ wait_for_turn: async (args, context) => {
1033
+ const prev = waitToolCallId;
1034
+ waitToolCallId = typeof context?.toolCallId === "string" ? context.toolCallId : void 0;
1035
+ try {
1036
+ return await call("turn.wait", args);
1037
+ } finally {
1038
+ waitToolCallId = prev;
1039
+ }
1040
+ },
1041
+ close: () => client.close()
1042
+ };
1043
+ }
1044
+
1045
+ // src/agent-rpc/cursor-tools.ts
1046
+ function sideboardCursorRpcTools(opts) {
1047
+ const exec = createPilotRpcExecutors(opts);
1048
+ const tools = {
1049
+ present_artifact: {
1050
+ description: PILOT_TOOL_DESCRIPTIONS.present_artifact,
1051
+ inputSchema: PILOT_TOOL_SCHEMAS.present_artifact,
1052
+ execute: exec.present_artifact
1053
+ },
1054
+ wait_for_job: {
1055
+ description: PILOT_TOOL_DESCRIPTIONS.wait_for_job,
1056
+ inputSchema: PILOT_TOOL_SCHEMAS.wait_for_job,
1057
+ execute: exec.wait_for_job
1058
+ },
1059
+ stop_job: {
1060
+ description: PILOT_TOOL_DESCRIPTIONS.stop_job,
1061
+ inputSchema: PILOT_TOOL_SCHEMAS.stop_job,
1062
+ execute: exec.stop_job
1063
+ }
1064
+ };
1065
+ if (opts.includeWaitForTurn) {
1066
+ tools.wait_for_turn = {
1067
+ description: WAIT_FOR_TURN_DESCRIPTION,
1068
+ inputSchema: WAIT_FOR_TURN_SCHEMA,
1069
+ execute: exec.wait_for_turn
1070
+ };
1071
+ }
1072
+ return tools;
1073
+ }
1074
+
1075
+ // src/agents/tool-result-clip.ts
1076
+ var import_node_fs16 = require("fs");
1077
+ var import_node_path18 = require("path");
722
1078
 
723
1079
  // src/paths/workspace-scratch.ts
724
1080
  var CLI_DIR = ".context/cli";
@@ -727,15 +1083,15 @@ var CLI_DIR = ".context/cli";
727
1083
  function spillPath(cwd, prefix) {
728
1084
  const stamp = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
729
1085
  const safe = prefix.replace(/[^a-zA-Z0-9_-]+/g, "-").slice(0, 40) || "tool";
730
- return (0, import_node_path17.join)(cwd, CLI_DIR, `${safe}-${stamp}.txt`);
1086
+ return (0, import_node_path18.join)(cwd, CLI_DIR, `${safe}-${stamp}.txt`);
731
1087
  }
732
1088
  function spillToolResultToCli(content, opts) {
733
1089
  const cwd = opts?.cwd?.trim();
734
1090
  if (!cwd || !content) return null;
735
1091
  const file = spillPath(cwd, opts?.prefix ?? "tool-result");
736
1092
  try {
737
- (0, import_node_fs15.mkdirSync)((0, import_node_path17.join)(cwd, CLI_DIR), { recursive: true });
738
- (0, import_node_fs15.writeFileSync)(file, content, "utf8");
1093
+ (0, import_node_fs16.mkdirSync)((0, import_node_path18.join)(cwd, CLI_DIR), { recursive: true });
1094
+ (0, import_node_fs16.writeFileSync)(file, content, "utf8");
739
1095
  return file;
740
1096
  } catch {
741
1097
  return null;
@@ -1063,6 +1419,9 @@ function buildCursorModelSelection(model, opts) {
1063
1419
  const raw = model && model.trim() || "";
1064
1420
  const id = !raw || raw.toLowerCase() === "auto" || raw.toLowerCase() === "default" ? "default" : raw;
1065
1421
  const params = [];
1422
+ if (/^grok-4\.7(?:$|-)/i.test(id)) {
1423
+ params.push({ id: "context", value: "256k" });
1424
+ }
1066
1425
  const effort = (opts.effort ?? "").trim().toLowerCase();
1067
1426
  const normalized = effort === "normal" ? "medium" : effort === "low" || effort === "medium" || effort === "high" || effort === "xhigh" || effort === "max" ? effort : "";
1068
1427
  if (normalized) {
@@ -1139,7 +1498,7 @@ function emit(event) {
1139
1498
  }
1140
1499
  function localAgentStore(Store, threadId) {
1141
1500
  const root = cursorSdkStoreDir(threadId);
1142
- (0, import_node_fs16.mkdirSync)(root, { recursive: true });
1501
+ (0, import_node_fs17.mkdirSync)(root, { recursive: true });
1143
1502
  return new Store(root);
1144
1503
  }
1145
1504
  async function cancelStaleLocalRuns(Agent, agentId, opts) {
@@ -1210,8 +1569,29 @@ async function main() {
1210
1569
  const mode = req.planMode ? "plan" : "agent";
1211
1570
  const store = localAgentStore(JsonlLocalAgentStore, req.threadId);
1212
1571
  const isolateSources = [];
1572
+ let onRpcProgress = () => {
1573
+ };
1574
+ const rpcTools = req.agentRpc ? sideboardCursorRpcTools({
1575
+ cwd: req.cwd,
1576
+ rpc: req.agentRpc,
1577
+ includeWaitForTurn: Boolean(req.rpcWaitForTurn),
1578
+ onProgress: (params, toolCallId) => {
1579
+ onRpcProgress();
1580
+ if (!toolCallId) return;
1581
+ try {
1582
+ emit({
1583
+ type: "tool_result",
1584
+ id: toolCallId,
1585
+ content: JSON.stringify(params),
1586
+ partial: true
1587
+ });
1588
+ } catch {
1589
+ }
1590
+ }
1591
+ }) : {};
1213
1592
  const customTools = {
1214
- read: slicedReadCustomToolConfig(req.cwd)
1593
+ read: slicedReadCustomToolConfig(req.cwd),
1594
+ ...rpcTools
1215
1595
  };
1216
1596
  const local = withCursorLocalHangGuards({
1217
1597
  cwd: req.cwd,
@@ -1306,6 +1686,7 @@ async function main() {
1306
1686
  const bump = () => {
1307
1687
  activity.at = Date.now();
1308
1688
  };
1689
+ onRpcProgress = bump;
1309
1690
  let usageBefore = null;
1310
1691
  try {
1311
1692
  usageBefore = await agent.getUsage();
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- clipAgentEventForEmit
4
- } from "../chunk-HHEKVR6C.js";
3
+ clipAgentEventForEmit,
4
+ sideboardCursorRpcTools
5
+ } from "../chunk-F5MFNUAA.js";
5
6
  import {
6
7
  createAgentStreamCoalescer
7
8
  } from "../chunk-AXQ4ZWHK.js";
@@ -19,15 +20,16 @@ import {
19
20
  importCursorSdk,
20
21
  looksLikeCursorHttp2StreamClose,
21
22
  resolveCursorSdkRoot
22
- } from "../chunk-WV7KJH2E.js";
23
+ } from "../chunk-A5SAYFJ4.js";
23
24
  import "../chunk-6K64FJDD.js";
25
+ import {
26
+ cursorSdkStoreDir
27
+ } from "../chunk-UWQ6UCIB.js";
24
28
  import "../chunk-QVN2WOKJ.js";
29
+ import "../chunk-NYBFYFK7.js";
25
30
  import {
26
31
  dropNestedElectronEnvFromProcess
27
32
  } from "../chunk-4TR3HZFT.js";
28
- import {
29
- cursorSdkStoreDir
30
- } from "../chunk-UWQ6UCIB.js";
31
33
  import "../chunk-EHT2DRT4.js";
32
34
 
33
35
  // src/agents/cursor-runner.ts
@@ -276,6 +278,9 @@ function buildCursorModelSelection(model, opts) {
276
278
  const raw = model && model.trim() || "";
277
279
  const id = !raw || raw.toLowerCase() === "auto" || raw.toLowerCase() === "default" ? "default" : raw;
278
280
  const params = [];
281
+ if (/^grok-4\.7(?:$|-)/i.test(id)) {
282
+ params.push({ id: "context", value: "256k" });
283
+ }
279
284
  const effort = (opts.effort ?? "").trim().toLowerCase();
280
285
  const normalized = effort === "normal" ? "medium" : effort === "low" || effort === "medium" || effort === "high" || effort === "xhigh" || effort === "max" ? effort : "";
281
286
  if (normalized) {
@@ -364,8 +369,29 @@ async function main() {
364
369
  const mode = req.planMode ? "plan" : "agent";
365
370
  const store = localAgentStore(JsonlLocalAgentStore, req.threadId);
366
371
  const isolateSources = [];
372
+ let onRpcProgress = () => {
373
+ };
374
+ const rpcTools = req.agentRpc ? sideboardCursorRpcTools({
375
+ cwd: req.cwd,
376
+ rpc: req.agentRpc,
377
+ includeWaitForTurn: Boolean(req.rpcWaitForTurn),
378
+ onProgress: (params, toolCallId) => {
379
+ onRpcProgress();
380
+ if (!toolCallId) return;
381
+ try {
382
+ emit({
383
+ type: "tool_result",
384
+ id: toolCallId,
385
+ content: JSON.stringify(params),
386
+ partial: true
387
+ });
388
+ } catch {
389
+ }
390
+ }
391
+ }) : {};
367
392
  const customTools = {
368
- read: slicedReadCustomToolConfig(req.cwd)
393
+ read: slicedReadCustomToolConfig(req.cwd),
394
+ ...rpcTools
369
395
  };
370
396
  const local = withCursorLocalHangGuards({
371
397
  cwd: req.cwd,
@@ -460,6 +486,7 @@ async function main() {
460
486
  const bump = () => {
461
487
  activity.at = Date.now();
462
488
  };
489
+ onRpcProgress = bump;
463
490
  let usageBefore = null;
464
491
  try {
465
492
  usageBefore = await agent.getUsage();