@sideboard-ai/core 0.1.295 → 0.1.297
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/agents/claude-runner.cjs +55 -0
- package/dist/agents/claude-runner.js +57 -1
- package/dist/agents/cursor-runner.js +2 -2
- package/dist/{agents-S55DBAVO.js → agents-DZTPUKVF.js} +4 -4
- package/dist/{agents-EFHYZUZT.js → agents-ICHYDSCD.js} +5 -5
- package/dist/{chunk-ABLHTRRG.js → chunk-2O3ICR77.js} +3 -3
- package/dist/{chunk-KCP6IVRI.js → chunk-67BWWLEB.js} +4 -4
- package/dist/{chunk-RWIYYFID.js → chunk-6GTABVNG.js} +4 -4
- package/dist/{chunk-YEIPPZ5W.js → chunk-BGEECLKH.js} +2 -2
- package/dist/{chunk-ER6BGGME.js → chunk-J54UPHXZ.js} +1 -1
- package/dist/{chunk-ZEP6JIRF.js → chunk-JWXJXEA3.js} +1 -1
- package/dist/{chunk-NYBFYFK7.js → chunk-QDA6NXRA.js} +1 -0
- package/dist/{chunk-YFKAC4LB.js → chunk-QT36F4TD.js} +54 -25
- package/dist/{chunk-YRXV3E7J.js → chunk-TVN4TDFB.js} +9 -0
- package/dist/{chunk-6SGYGYH7.js → chunk-VXNZG4J6.js} +1 -1
- package/dist/{chunk-XXT3C2EF.js → chunk-W2A63ZOK.js} +176 -39
- package/dist/{chunk-E7G7RY6T.js → chunk-WQREAX35.js} +2 -2
- package/dist/{chunk-QB5MDOHL.js → chunk-WZLV4WNS.js} +9 -0
- package/dist/{chunk-HWIIRVYE.js → chunk-ZXWRNA4G.js} +4 -4
- package/dist/{conductor-GURU5XD7.js → conductor-HJFDYIZD.js} +4 -4
- package/dist/{conductor-HT2UANDY.js → conductor-ZXDIA6OF.js} +4 -4
- package/dist/{coordinator-prompt-AROMFCP2.js → coordinator-prompt-ILHSVPOG.js} +3 -3
- package/dist/{coordinator-prompt-K6XHUG3N.js → coordinator-prompt-L3V2CMWX.js} +3 -3
- package/dist/{global-workspace-4WAU4PAL.js → global-workspace-47G453ZU.js} +3 -3
- package/dist/{global-workspace-PX4GUVLW.js → global-workspace-NMRUGGFF.js} +3 -3
- package/dist/index.cjs +1014 -698
- package/dist/index.d.cts +25 -4
- package/dist/index.d.ts +25 -4
- package/dist/index.js +282 -119
- package/dist/mcp/run-stdio.cjs +201 -118
- package/dist/mcp/run-stdio.js +46 -8
- package/dist/{orchestrator-VNSEXL62.js → orchestrator-MR7TCIPP.js} +6 -6
- package/dist/{orchestrator-VDYZSZWY.js → orchestrator-ZQU62CES.js} +7 -7
- package/dist/{thread-store-DPKESDFR.js → thread-store-H6D6MDUM.js} +1 -1
- package/dist/{thread-store-X6S2GIR5.js → thread-store-SADLLKRE.js} +1 -1
- package/dist/{workspaces-MFU3IGAP.js → workspaces-PGY4UWZ3.js} +3 -3
- package/dist/{workspaces-U7SSD27C.js → workspaces-WGZPRQJX.js} +3 -3
- package/dist/{worktree-TQKASYPZ.js → worktree-3MF5J5XZ.js} +2 -2
- package/dist/{worktree-2VSHRI72.js → worktree-JZXDAKQF.js} +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -19,17 +19,20 @@ import {
|
|
|
19
19
|
agentBlockFields,
|
|
20
20
|
agentGitPrompt,
|
|
21
21
|
alignQueueAttachments,
|
|
22
|
+
answerToolPermission,
|
|
22
23
|
appendQueuedItem,
|
|
23
24
|
applyIssueListWindow,
|
|
24
25
|
applyPromptCacheTtlEnv,
|
|
25
26
|
applyThreadIntoMain,
|
|
26
27
|
applyWorkspaceTags,
|
|
27
28
|
armSchedules,
|
|
29
|
+
askToolPermission,
|
|
28
30
|
assembleHomeBoard,
|
|
29
31
|
boardPinIdentity,
|
|
30
32
|
captureTurnBaseline,
|
|
31
33
|
chatBlockedSuffix,
|
|
32
34
|
claimDesktopHost,
|
|
35
|
+
clampBlockReason,
|
|
33
36
|
clampMcpIssueLimit,
|
|
34
37
|
classifyWorktreeColumn,
|
|
35
38
|
classifyWorktreeListBadges,
|
|
@@ -160,6 +163,7 @@ import {
|
|
|
160
163
|
reviewLabelForRepo,
|
|
161
164
|
scheduleNeedsCaffeinate,
|
|
162
165
|
schedulesPath,
|
|
166
|
+
setToolPermissionPublisher,
|
|
163
167
|
shiftQueuedItem,
|
|
164
168
|
shouldNotifyOrchestrator,
|
|
165
169
|
shouldRemoveWorktreeOnTeardown,
|
|
@@ -185,8 +189,9 @@ import {
|
|
|
185
189
|
worktreeAgentBlock,
|
|
186
190
|
worktreeBoardStatus,
|
|
187
191
|
worktreeCleanupSettings,
|
|
192
|
+
writeAgentBlock,
|
|
188
193
|
writeWorktreeFile
|
|
189
|
-
} from "./chunk-
|
|
194
|
+
} from "./chunk-W2A63ZOK.js";
|
|
190
195
|
import {
|
|
191
196
|
LEGACY_PLAN_FILE_REL,
|
|
192
197
|
PLAN_FILE_NAME,
|
|
@@ -282,7 +287,7 @@ import {
|
|
|
282
287
|
userMcpNamesToDisable,
|
|
283
288
|
worktreeMcpToolNames,
|
|
284
289
|
writeInjectedMcpConfig
|
|
285
|
-
} from "./chunk-
|
|
290
|
+
} from "./chunk-6GTABVNG.js";
|
|
286
291
|
import {
|
|
287
292
|
brightsyMcpServerName,
|
|
288
293
|
connectBrightsyTeam,
|
|
@@ -410,7 +415,7 @@ import {
|
|
|
410
415
|
workspaceAgentChatSummaries,
|
|
411
416
|
worktreeRunPortsPath,
|
|
412
417
|
wrapReviewSkillMarkdown
|
|
413
|
-
} from "./chunk-
|
|
418
|
+
} from "./chunk-67BWWLEB.js";
|
|
414
419
|
import {
|
|
415
420
|
STDERR_EVENT_MAX_CHARS,
|
|
416
421
|
STDOUT_EVENT_MAX_CHARS,
|
|
@@ -610,7 +615,7 @@ import {
|
|
|
610
615
|
stageBuffersAsAttachments,
|
|
611
616
|
syncWorkspacesFromThreads,
|
|
612
617
|
takenTeamSlugsForOrchestration
|
|
613
|
-
} from "./chunk-
|
|
618
|
+
} from "./chunk-BGEECLKH.js";
|
|
614
619
|
import {
|
|
615
620
|
GITHUB_PR_BODY_MAX_CHARS,
|
|
616
621
|
GITHUB_PR_BODY_SAFE_CHARS,
|
|
@@ -698,7 +703,7 @@ import {
|
|
|
698
703
|
suggestSlug,
|
|
699
704
|
switchWorktreeBranch,
|
|
700
705
|
warmGithubAgentAuth
|
|
701
|
-
} from "./chunk-
|
|
706
|
+
} from "./chunk-JWXJXEA3.js";
|
|
702
707
|
import {
|
|
703
708
|
FAMOUS_SOCCER_TEAMS,
|
|
704
709
|
allocateTeamName,
|
|
@@ -730,7 +735,7 @@ import {
|
|
|
730
735
|
worktreeNameFromPath,
|
|
731
736
|
worktreeSlugForTicket,
|
|
732
737
|
writeThread
|
|
733
|
-
} from "./chunk-
|
|
738
|
+
} from "./chunk-WZLV4WNS.js";
|
|
734
739
|
import "./chunk-2P4XKWV2.js";
|
|
735
740
|
import {
|
|
736
741
|
BRIGHTSY_OAUTH_CLIENT_ID,
|
|
@@ -754,7 +759,7 @@ import {
|
|
|
754
759
|
import {
|
|
755
760
|
clipMcpToolResult,
|
|
756
761
|
cursorToolErrorText
|
|
757
|
-
} from "./chunk-
|
|
762
|
+
} from "./chunk-J54UPHXZ.js";
|
|
758
763
|
import "./chunk-AXQ4ZWHK.js";
|
|
759
764
|
import {
|
|
760
765
|
AGENT_RUNNER_MAX_OLD_SPACE_MB,
|
|
@@ -819,7 +824,7 @@ import {
|
|
|
819
824
|
rpcNotify,
|
|
820
825
|
rpcResult,
|
|
821
826
|
writeAgentRuntimeMetadata
|
|
822
|
-
} from "./chunk-
|
|
827
|
+
} from "./chunk-QDA6NXRA.js";
|
|
823
828
|
import {
|
|
824
829
|
AGENT_DONE_SOUNDS,
|
|
825
830
|
CHAT_TEXT_SCALES,
|
|
@@ -5049,6 +5054,124 @@ function registerScheduleTools(server) {
|
|
|
5049
5054
|
// src/agent-rpc/handlers.ts
|
|
5050
5055
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
5051
5056
|
import { isAbsolute } from "path";
|
|
5057
|
+
|
|
5058
|
+
// src/remote/phone-permission.ts
|
|
5059
|
+
var PHONE_CONTROL_PREFIX = "\0sb.phone\n";
|
|
5060
|
+
var DECISIONS = /* @__PURE__ */ new Set(["allow", "deny", "allow_session"]);
|
|
5061
|
+
var push = null;
|
|
5062
|
+
function setPhonePermissionPush(next) {
|
|
5063
|
+
push = next;
|
|
5064
|
+
}
|
|
5065
|
+
function notifyPhonePermission(chatId, prompt) {
|
|
5066
|
+
const id = chatId.trim();
|
|
5067
|
+
if (!id) return;
|
|
5068
|
+
push?.(id, prompt);
|
|
5069
|
+
}
|
|
5070
|
+
function permissionViewFromBlock(block) {
|
|
5071
|
+
if (!block || block.source !== "permission") return null;
|
|
5072
|
+
const prompt = block.permission;
|
|
5073
|
+
if (!prompt?.id || !prompt.title) return null;
|
|
5074
|
+
return {
|
|
5075
|
+
id: prompt.id,
|
|
5076
|
+
title: prompt.title,
|
|
5077
|
+
detail: typeof prompt.detail === "string" ? prompt.detail : "",
|
|
5078
|
+
...prompt.path ? { path: prompt.path } : {},
|
|
5079
|
+
allowSession: prompt.allowSession !== false,
|
|
5080
|
+
...prompt.defaultToNo ? { defaultToNo: true } : {}
|
|
5081
|
+
};
|
|
5082
|
+
}
|
|
5083
|
+
function phonePermissionView(chatId) {
|
|
5084
|
+
return permissionViewFromBlock(readThread(chatId)?.agentBlock);
|
|
5085
|
+
}
|
|
5086
|
+
function textField(value, key) {
|
|
5087
|
+
const raw = value[key];
|
|
5088
|
+
return typeof raw === "string" ? raw.trim() : "";
|
|
5089
|
+
}
|
|
5090
|
+
function takePhonePermission(text5) {
|
|
5091
|
+
if (!text5.startsWith(PHONE_CONTROL_PREFIX)) return null;
|
|
5092
|
+
let parsed;
|
|
5093
|
+
try {
|
|
5094
|
+
parsed = JSON.parse(text5.slice(PHONE_CONTROL_PREFIX.length));
|
|
5095
|
+
} catch {
|
|
5096
|
+
return null;
|
|
5097
|
+
}
|
|
5098
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
5099
|
+
if (parsed.op !== "permission") return null;
|
|
5100
|
+
const chatId = textField(parsed, "chatId");
|
|
5101
|
+
const id = textField(parsed, "id");
|
|
5102
|
+
const decision = textField(parsed, "decision");
|
|
5103
|
+
if (!chatId || !id || !DECISIONS.has(decision)) return "invalid";
|
|
5104
|
+
return { op: "permission", chatId, id, decision };
|
|
5105
|
+
}
|
|
5106
|
+
function dispatchPhonePermission(text5, emit) {
|
|
5107
|
+
const cmd = takePhonePermission(text5);
|
|
5108
|
+
if (cmd == null) return false;
|
|
5109
|
+
if (cmd === "invalid") {
|
|
5110
|
+
emit({ op: "error", message: "invalid phone command" });
|
|
5111
|
+
return true;
|
|
5112
|
+
}
|
|
5113
|
+
if (!answerToolPermission(cmd.id, cmd.decision)) {
|
|
5114
|
+
emit({ op: "error", chatId: cmd.chatId, message: "That request already finished." });
|
|
5115
|
+
emit({ op: "permission", chatId: cmd.chatId, prompt: phonePermissionView(cmd.chatId) });
|
|
5116
|
+
}
|
|
5117
|
+
return true;
|
|
5118
|
+
}
|
|
5119
|
+
|
|
5120
|
+
// src/agent-rpc/permission-handler.ts
|
|
5121
|
+
setToolPermissionPublisher({
|
|
5122
|
+
show(item) {
|
|
5123
|
+
const thread = readThread(item.threadId);
|
|
5124
|
+
if (!thread || thread.status === "archived") return false;
|
|
5125
|
+
writeAgentBlock(item.threadId, {
|
|
5126
|
+
source: "permission",
|
|
5127
|
+
reason: clampBlockReason(item.prompt.title),
|
|
5128
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5129
|
+
permission: item.prompt
|
|
5130
|
+
});
|
|
5131
|
+
notifyPhonePermission(item.threadId, item.prompt);
|
|
5132
|
+
return true;
|
|
5133
|
+
},
|
|
5134
|
+
clear(threadId, id) {
|
|
5135
|
+
const thread = readThread(threadId);
|
|
5136
|
+
if (thread?.agentBlock?.source === "permission" && thread.agentBlock.permission?.id === id) {
|
|
5137
|
+
updateThread(threadId, { agentBlock: null });
|
|
5138
|
+
notifyPhonePermission(threadId, null);
|
|
5139
|
+
}
|
|
5140
|
+
}
|
|
5141
|
+
});
|
|
5142
|
+
function asRecord(value) {
|
|
5143
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
5144
|
+
return value;
|
|
5145
|
+
}
|
|
5146
|
+
function str(value) {
|
|
5147
|
+
return typeof value === "string" ? value : "";
|
|
5148
|
+
}
|
|
5149
|
+
function invalidParams(message) {
|
|
5150
|
+
return Object.assign(new Error(message), { rpcCode: -32602 });
|
|
5151
|
+
}
|
|
5152
|
+
var handlePermissionAsk = async (params, _ctx) => {
|
|
5153
|
+
const rec = asRecord(params);
|
|
5154
|
+
const threadId = str(rec.threadId).trim();
|
|
5155
|
+
const toolName = str(rec.toolName).trim();
|
|
5156
|
+
if (!threadId) throw invalidParams("threadId is required");
|
|
5157
|
+
if (!toolName) throw invalidParams("toolName is required");
|
|
5158
|
+
const input = asRecord(rec.input);
|
|
5159
|
+
const ask = {
|
|
5160
|
+
threadId,
|
|
5161
|
+
toolName,
|
|
5162
|
+
input: Object.keys(input).length > 0 ? input : void 0,
|
|
5163
|
+
blockedPath: str(rec.blockedPath).trim() || void 0,
|
|
5164
|
+
title: str(rec.title).trim() || void 0,
|
|
5165
|
+
description: str(rec.description).trim() || void 0,
|
|
5166
|
+
displayName: str(rec.displayName).trim() || void 0,
|
|
5167
|
+
suggestions: rec.suggestions,
|
|
5168
|
+
suppressAlwaysAllow: rec.suppressAlwaysAllow === true,
|
|
5169
|
+
defaultToNo: rec.defaultToNo === true
|
|
5170
|
+
};
|
|
5171
|
+
return askToolPermission(ask);
|
|
5172
|
+
};
|
|
5173
|
+
|
|
5174
|
+
// src/agent-rpc/handlers.ts
|
|
5052
5175
|
function presentArtifactResult(input) {
|
|
5053
5176
|
const id = input.artifact_id?.trim() || `artifact_${Date.now().toString(36)}_${randomUUID3().slice(0, 8)}`;
|
|
5054
5177
|
return {
|
|
@@ -5062,20 +5185,20 @@ function presentArtifactResult(input) {
|
|
|
5062
5185
|
message: input.type === "log" ? "Log accepted. Same artifact_id appends; send only new lines next time." : "Artifact accepted. Sideboard desktop opens it in the side column beside chat."
|
|
5063
5186
|
};
|
|
5064
5187
|
}
|
|
5065
|
-
function
|
|
5188
|
+
function asRecord2(value) {
|
|
5066
5189
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
5067
5190
|
return value;
|
|
5068
5191
|
}
|
|
5069
|
-
function
|
|
5192
|
+
function str2(value) {
|
|
5070
5193
|
return typeof value === "string" ? value : "";
|
|
5071
5194
|
}
|
|
5072
|
-
function
|
|
5195
|
+
function invalidParams2(message) {
|
|
5073
5196
|
return Object.assign(new Error(message), { rpcCode: -32602 });
|
|
5074
5197
|
}
|
|
5075
5198
|
function jobCwd(rec) {
|
|
5076
|
-
const raw =
|
|
5077
|
-
if (!raw) throw
|
|
5078
|
-
if (!isAbsolute(raw)) throw
|
|
5199
|
+
const raw = str2(rec.cwd).trim();
|
|
5200
|
+
if (!raw) throw invalidParams2("cwd is required");
|
|
5201
|
+
if (!isAbsolute(raw)) throw invalidParams2("cwd must be an absolute path");
|
|
5079
5202
|
return raw;
|
|
5080
5203
|
}
|
|
5081
5204
|
async function handleRuntimePing(_params, _ctx) {
|
|
@@ -5086,33 +5209,33 @@ async function handleRuntimePing(_params, _ctx) {
|
|
|
5086
5209
|
};
|
|
5087
5210
|
}
|
|
5088
5211
|
async function handlePresentArtifact(params, _ctx) {
|
|
5089
|
-
const rec =
|
|
5090
|
-
const title =
|
|
5091
|
-
const type =
|
|
5212
|
+
const rec = asRecord2(params);
|
|
5213
|
+
const title = str2(rec.title).trim();
|
|
5214
|
+
const type = str2(rec.type).trim();
|
|
5092
5215
|
const allowed = ["html", "svg", "markdown", "react", "log"];
|
|
5093
|
-
if (!title) throw
|
|
5216
|
+
if (!title) throw invalidParams2("title is required");
|
|
5094
5217
|
if (!allowed.includes(type)) {
|
|
5095
|
-
throw
|
|
5218
|
+
throw invalidParams2("type must be html, svg, markdown, react, or log");
|
|
5096
5219
|
}
|
|
5097
|
-
const statusRaw =
|
|
5220
|
+
const statusRaw = str2(rec.status).trim();
|
|
5098
5221
|
const status = ["running", "ok", "failed", "idle"].includes(
|
|
5099
5222
|
statusRaw
|
|
5100
5223
|
) ? statusRaw : void 0;
|
|
5101
|
-
const modeRaw =
|
|
5224
|
+
const modeRaw = str2(rec.mode).trim();
|
|
5102
5225
|
const mode = modeRaw === "append" || modeRaw === "replace" ? modeRaw : void 0;
|
|
5103
5226
|
return presentArtifactResult({
|
|
5104
5227
|
title,
|
|
5105
5228
|
type,
|
|
5106
|
-
artifact_id:
|
|
5229
|
+
artifact_id: str2(rec.artifact_id) || void 0,
|
|
5107
5230
|
status,
|
|
5108
|
-
phase:
|
|
5231
|
+
phase: str2(rec.phase) || void 0,
|
|
5109
5232
|
mode
|
|
5110
5233
|
});
|
|
5111
5234
|
}
|
|
5112
5235
|
async function handleJobWait(params, ctx, waitFn = waitForDetachedJob) {
|
|
5113
|
-
const rec =
|
|
5114
|
-
const id =
|
|
5115
|
-
if (!id) throw
|
|
5236
|
+
const rec = asRecord2(params);
|
|
5237
|
+
const id = str2(rec.id).trim();
|
|
5238
|
+
if (!id) throw invalidParams2("id is required");
|
|
5116
5239
|
const cwd = jobCwd(rec);
|
|
5117
5240
|
const deadline = Date.now() + AGENT_RPC_JOB_HOLD_MAX_MS;
|
|
5118
5241
|
let last;
|
|
@@ -5134,14 +5257,14 @@ async function handleJobWait(params, ctx, waitFn = waitForDetachedJob) {
|
|
|
5134
5257
|
};
|
|
5135
5258
|
}
|
|
5136
5259
|
async function handleJobStop(params, _ctx) {
|
|
5137
|
-
const rec =
|
|
5138
|
-
const id =
|
|
5139
|
-
if (!id) throw
|
|
5140
|
-
const reason =
|
|
5260
|
+
const rec = asRecord2(params);
|
|
5261
|
+
const id = str2(rec.id).trim();
|
|
5262
|
+
if (!id) throw invalidParams2("id is required");
|
|
5263
|
+
const reason = str2(rec.reason).trim() || void 0;
|
|
5141
5264
|
return stopDetachedJob(jobCwd(rec), id, reason ? { reason } : void 0);
|
|
5142
5265
|
}
|
|
5143
5266
|
async function defaultTurnWait(ref, timeoutMs) {
|
|
5144
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
5267
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-ZQU62CES.js");
|
|
5145
5268
|
const orch = getOrchestrator2();
|
|
5146
5269
|
const thread = await orch.waitForTurn(ref, timeoutMs, {
|
|
5147
5270
|
resolveIfStillRunning: true
|
|
@@ -5162,9 +5285,9 @@ async function defaultTurnWait(ref, timeoutMs) {
|
|
|
5162
5285
|
});
|
|
5163
5286
|
}
|
|
5164
5287
|
async function handleTurnWait(params, ctx, waitFn = defaultTurnWait) {
|
|
5165
|
-
const rec =
|
|
5166
|
-
const ref =
|
|
5167
|
-
if (!ref) throw
|
|
5288
|
+
const rec = asRecord2(params);
|
|
5289
|
+
const ref = str2(rec.ref).trim();
|
|
5290
|
+
if (!ref) throw invalidParams2("ref is required");
|
|
5168
5291
|
const requested = typeof rec.timeoutMs === "number" && Number.isFinite(rec.timeoutMs) ? rec.timeoutMs : void 0;
|
|
5169
5292
|
const holdMax = requested !== void 0 ? Math.min(Math.max(1e3, Math.floor(requested)), AGENT_RPC_JOB_HOLD_MAX_MS) : AGENT_RPC_JOB_HOLD_MAX_MS;
|
|
5170
5293
|
const deadline = Date.now() + holdMax;
|
|
@@ -5197,7 +5320,8 @@ function createAgentRpcDispatcher() {
|
|
|
5197
5320
|
"ui.presentArtifact": handlePresentArtifact,
|
|
5198
5321
|
"job.wait": handleJobWait,
|
|
5199
5322
|
"job.stop": handleJobStop,
|
|
5200
|
-
"turn.wait": handleTurnWait
|
|
5323
|
+
"turn.wait": handleTurnWait,
|
|
5324
|
+
"permission.ask": handlePermissionAsk
|
|
5201
5325
|
};
|
|
5202
5326
|
}
|
|
5203
5327
|
|
|
@@ -8863,7 +8987,7 @@ var BAKED_REMOTE_RELAY_URL = `wss://relay.sideboard.cloud${REMOTE_RELAY_PATH}`;
|
|
|
8863
8987
|
function remoteRelayUrl() {
|
|
8864
8988
|
return process.env.SIDEBOARD_REMOTE_RELAY_URL?.trim() || BAKED_REMOTE_RELAY_URL;
|
|
8865
8989
|
}
|
|
8866
|
-
function
|
|
8990
|
+
function str3(value) {
|
|
8867
8991
|
return typeof value === "string" ? value.trim() : "";
|
|
8868
8992
|
}
|
|
8869
8993
|
function questions(value) {
|
|
@@ -8872,14 +8996,14 @@ function questions(value) {
|
|
|
8872
8996
|
for (const item of value) {
|
|
8873
8997
|
if (!item || typeof item !== "object") return null;
|
|
8874
8998
|
const row2 = item;
|
|
8875
|
-
const question =
|
|
8999
|
+
const question = str3(row2.question);
|
|
8876
9000
|
if (!question || !Array.isArray(row2.options)) return null;
|
|
8877
9001
|
const options = [];
|
|
8878
9002
|
for (const opt of row2.options) {
|
|
8879
9003
|
if (!opt || typeof opt !== "object") return null;
|
|
8880
|
-
const label =
|
|
9004
|
+
const label = str3(opt.label);
|
|
8881
9005
|
if (!label) return null;
|
|
8882
|
-
const description =
|
|
9006
|
+
const description = str3(opt.description);
|
|
8883
9007
|
options.push(description ? { label, description } : { label });
|
|
8884
9008
|
}
|
|
8885
9009
|
if (options.length === 0) return null;
|
|
@@ -8900,11 +9024,11 @@ function parseRemoteClientMessage(raw) {
|
|
|
8900
9024
|
if (msg.type === "host_pair") return { type: "host_pair" };
|
|
8901
9025
|
if (msg.type === "stop") return { type: "stop" };
|
|
8902
9026
|
if (msg.type === "host_register") {
|
|
8903
|
-
const deviceId =
|
|
8904
|
-
const hostSecret =
|
|
8905
|
-
const deviceLabel =
|
|
9027
|
+
const deviceId = str3(parsed.deviceId);
|
|
9028
|
+
const hostSecret = str3(parsed.hostSecret);
|
|
9029
|
+
const deviceLabel = str3(parsed.deviceLabel);
|
|
8906
9030
|
if (!deviceId || !hostSecret || !deviceLabel) return null;
|
|
8907
|
-
const accountToken =
|
|
9031
|
+
const accountToken = str3(parsed.accountToken);
|
|
8908
9032
|
return {
|
|
8909
9033
|
type: "host_register",
|
|
8910
9034
|
deviceId,
|
|
@@ -8914,12 +9038,12 @@ function parseRemoteClientMessage(raw) {
|
|
|
8914
9038
|
};
|
|
8915
9039
|
}
|
|
8916
9040
|
if (msg.type === "pair") {
|
|
8917
|
-
const code =
|
|
9041
|
+
const code = str3(parsed.code).toUpperCase();
|
|
8918
9042
|
if (!code) return null;
|
|
8919
9043
|
return { type: "pair", code };
|
|
8920
9044
|
}
|
|
8921
9045
|
if (msg.type === "resume") {
|
|
8922
|
-
const sessionToken =
|
|
9046
|
+
const sessionToken = str3(parsed.sessionToken);
|
|
8923
9047
|
if (!sessionToken) return null;
|
|
8924
9048
|
return { type: "resume", sessionToken };
|
|
8925
9049
|
}
|
|
@@ -8930,19 +9054,19 @@ function parseRemoteClientMessage(raw) {
|
|
|
8930
9054
|
return { type: "list_hosts", sessionTokens };
|
|
8931
9055
|
}
|
|
8932
9056
|
if (msg.type === "prompt") {
|
|
8933
|
-
const text5 =
|
|
9057
|
+
const text5 = str3(parsed.text);
|
|
8934
9058
|
if (!text5) return null;
|
|
8935
9059
|
return { type: "prompt", text: text5 };
|
|
8936
9060
|
}
|
|
8937
9061
|
if (msg.type === "assistant") {
|
|
8938
|
-
return { type: "assistant", text:
|
|
9062
|
+
return { type: "assistant", text: str3(parsed.text) };
|
|
8939
9063
|
}
|
|
8940
9064
|
if (msg.type === "ask_user") {
|
|
8941
9065
|
const parsedQuestions = questions(parsed.questions);
|
|
8942
9066
|
if (!parsedQuestions?.length) return null;
|
|
8943
9067
|
return {
|
|
8944
9068
|
type: "ask_user",
|
|
8945
|
-
text:
|
|
9069
|
+
text: str3(parsed.text),
|
|
8946
9070
|
questions: parsedQuestions
|
|
8947
9071
|
};
|
|
8948
9072
|
}
|
|
@@ -8968,7 +9092,7 @@ function parseRemoteServerMessage(raw) {
|
|
|
8968
9092
|
for (const item of raw2) {
|
|
8969
9093
|
if (!item || typeof item !== "object") return null;
|
|
8970
9094
|
const row2 = item;
|
|
8971
|
-
const sessionToken =
|
|
9095
|
+
const sessionToken = str3(row2.sessionToken);
|
|
8972
9096
|
if (!sessionToken || typeof row2.deviceId !== "string" || typeof row2.deviceLabel !== "string") return null;
|
|
8973
9097
|
if (typeof row2.online !== "boolean") return null;
|
|
8974
9098
|
hosts.push({
|
|
@@ -8982,43 +9106,43 @@ function parseRemoteServerMessage(raw) {
|
|
|
8982
9106
|
}
|
|
8983
9107
|
if (type === "stop") return { type: "stop" };
|
|
8984
9108
|
if (type === "registered") {
|
|
8985
|
-
const deviceId =
|
|
8986
|
-
const deviceLabel =
|
|
9109
|
+
const deviceId = str3(parsed.deviceId);
|
|
9110
|
+
const deviceLabel = str3(parsed.deviceLabel);
|
|
8987
9111
|
if (!deviceId || !deviceLabel) return null;
|
|
8988
9112
|
return { type: "registered", deviceId, deviceLabel };
|
|
8989
9113
|
}
|
|
8990
9114
|
if (type === "pairing_code") {
|
|
8991
|
-
const code =
|
|
9115
|
+
const code = str3(parsed.code);
|
|
8992
9116
|
const expiresAt = parsed.expiresAt;
|
|
8993
9117
|
if (!code || typeof expiresAt !== "number") return null;
|
|
8994
9118
|
return { type: "pairing_code", code, expiresAt };
|
|
8995
9119
|
}
|
|
8996
9120
|
if (type === "inbound") {
|
|
8997
|
-
const text5 =
|
|
9121
|
+
const text5 = str3(parsed.text);
|
|
8998
9122
|
if (!text5) return null;
|
|
8999
9123
|
return { type: "inbound", text: text5 };
|
|
9000
9124
|
}
|
|
9001
9125
|
if (type === "paired") {
|
|
9002
|
-
const deviceId =
|
|
9003
|
-
const deviceLabel =
|
|
9004
|
-
const sessionToken =
|
|
9126
|
+
const deviceId = str3(parsed.deviceId);
|
|
9127
|
+
const deviceLabel = str3(parsed.deviceLabel);
|
|
9128
|
+
const sessionToken = str3(parsed.sessionToken);
|
|
9005
9129
|
if (!deviceId || !deviceLabel || !sessionToken) return null;
|
|
9006
9130
|
return { type: "paired", deviceId, deviceLabel, sessionToken };
|
|
9007
9131
|
}
|
|
9008
9132
|
if (type === "assistant") {
|
|
9009
|
-
return { type: "assistant", text:
|
|
9133
|
+
return { type: "assistant", text: str3(parsed.text) };
|
|
9010
9134
|
}
|
|
9011
9135
|
if (type === "ask_user") {
|
|
9012
9136
|
const parsedQuestions = questions(parsed.questions);
|
|
9013
9137
|
if (!parsedQuestions?.length) return null;
|
|
9014
9138
|
return {
|
|
9015
9139
|
type: "ask_user",
|
|
9016
|
-
text:
|
|
9140
|
+
text: str3(parsed.text),
|
|
9017
9141
|
questions: parsedQuestions
|
|
9018
9142
|
};
|
|
9019
9143
|
}
|
|
9020
9144
|
if (type === "error") {
|
|
9021
|
-
const message =
|
|
9145
|
+
const message = str3(parsed.message) || "remote error";
|
|
9022
9146
|
return { type: "error", message };
|
|
9023
9147
|
}
|
|
9024
9148
|
return null;
|
|
@@ -9446,10 +9570,10 @@ var MIN_MD_CHARS = 120;
|
|
|
9446
9570
|
function oneLine(value, max) {
|
|
9447
9571
|
return value.replace(/[`\r\n]/g, " ").replace(/\s+/g, " ").trim().slice(0, max);
|
|
9448
9572
|
}
|
|
9449
|
-
function
|
|
9573
|
+
function asRecord3(value) {
|
|
9450
9574
|
if (typeof value === "string") {
|
|
9451
9575
|
try {
|
|
9452
|
-
return
|
|
9576
|
+
return asRecord3(JSON.parse(value));
|
|
9453
9577
|
} catch {
|
|
9454
9578
|
return void 0;
|
|
9455
9579
|
}
|
|
@@ -9457,7 +9581,7 @@ function asRecord2(value) {
|
|
|
9457
9581
|
if (value && typeof value === "object" && !Array.isArray(value)) return value;
|
|
9458
9582
|
return void 0;
|
|
9459
9583
|
}
|
|
9460
|
-
function
|
|
9584
|
+
function str4(value) {
|
|
9461
9585
|
return typeof value === "string" ? value : "";
|
|
9462
9586
|
}
|
|
9463
9587
|
function normalizedBody(content) {
|
|
@@ -9524,7 +9648,7 @@ function toolContent(input) {
|
|
|
9524
9648
|
if (!input) return "";
|
|
9525
9649
|
const direct = input.content;
|
|
9526
9650
|
if (typeof direct === "string") return direct;
|
|
9527
|
-
const nested =
|
|
9651
|
+
const nested = asRecord3(direct);
|
|
9528
9652
|
if (!nested) return "";
|
|
9529
9653
|
for (const key of ["html", "markup", "text", "source", "content", "code"]) {
|
|
9530
9654
|
if (typeof nested[key] === "string") return nested[key];
|
|
@@ -9547,13 +9671,13 @@ function phoneArtifactText(text5, parts, limit = Number.POSITIVE_INFINITY) {
|
|
|
9547
9671
|
const extras = [];
|
|
9548
9672
|
for (const part of parts ?? []) {
|
|
9549
9673
|
if (part.type !== "tool" || part.parentId || !isArtifactTool(part.name)) continue;
|
|
9550
|
-
const input =
|
|
9674
|
+
const input = asRecord3(part.input);
|
|
9551
9675
|
const content = toolContent(input);
|
|
9552
9676
|
const hint = artifactHint(content);
|
|
9553
9677
|
if (hint && hints.has(hint)) continue;
|
|
9554
9678
|
const kind = kindFor("", content);
|
|
9555
|
-
const title = oneLine(
|
|
9556
|
-
if (!
|
|
9679
|
+
const title = oneLine(str4(input?.title), 80) || (kind ? titleFor(kind, content) : "Artifact");
|
|
9680
|
+
if (!str4(input?.title) && content.trim().length < MIN_FENCE_CHARS) continue;
|
|
9557
9681
|
if (hint) hints.add(hint);
|
|
9558
9682
|
extras.push(marker(title, hint));
|
|
9559
9683
|
}
|
|
@@ -9566,11 +9690,11 @@ function phoneArtifactText(text5, parts, limit = Number.POSITIVE_INFINITY) {
|
|
|
9566
9690
|
${tail}` : tail;
|
|
9567
9691
|
}
|
|
9568
9692
|
function parseOpenArtifact(value, chatId) {
|
|
9569
|
-
const record =
|
|
9693
|
+
const record = asRecord3(value);
|
|
9570
9694
|
if (!record) return "invalid";
|
|
9571
|
-
const title = oneLine(
|
|
9695
|
+
const title = oneLine(str4(record.title), 200);
|
|
9572
9696
|
if (!title) return "invalid";
|
|
9573
|
-
const hint = oneLine(
|
|
9697
|
+
const hint = oneLine(str4(record.hint), 200);
|
|
9574
9698
|
return { op: "open-artifact", chatId, title, ...hint ? { hint } : {} };
|
|
9575
9699
|
}
|
|
9576
9700
|
var PHONE_ARTIFACT_MAX_CHARS = 18e4;
|
|
@@ -9589,13 +9713,13 @@ function phoneArtifactDocuments(sources) {
|
|
|
9589
9713
|
}
|
|
9590
9714
|
for (const part of source.parts ?? []) {
|
|
9591
9715
|
if (part.type !== "tool" || part.parentId || !isArtifactTool(part.name)) continue;
|
|
9592
|
-
const input =
|
|
9716
|
+
const input = asRecord3(part.input);
|
|
9593
9717
|
const content = toolContent(input);
|
|
9594
9718
|
const hint = artifactHint(content);
|
|
9595
9719
|
if (hint && hints.has(hint)) continue;
|
|
9596
|
-
const typed = kindFor(
|
|
9597
|
-
const title = oneLine(
|
|
9598
|
-
if (!
|
|
9720
|
+
const typed = kindFor(str4(input?.type), content) ?? kindFor("", content);
|
|
9721
|
+
const title = oneLine(str4(input?.title), 80) || (typed ? titleFor(typed, content) : "Artifact");
|
|
9722
|
+
if (!str4(input?.title) && content.trim().length < MIN_FENCE_CHARS) continue;
|
|
9599
9723
|
if (hint) hints.add(hint);
|
|
9600
9724
|
docs.push({ title, content, kind: typed ?? "text" });
|
|
9601
9725
|
}
|
|
@@ -9640,13 +9764,21 @@ function pickArtifactMatch(items, request) {
|
|
|
9640
9764
|
}
|
|
9641
9765
|
|
|
9642
9766
|
// src/remote/phone-panes.ts
|
|
9767
|
+
var PHONE_CHANGE_SCOPES = ["last_turn", "uncommitted", "staged", "unstaged", "commits"];
|
|
9768
|
+
var PHONE_CHANGE_SCOPE_DEFAULT = "commits";
|
|
9769
|
+
function phoneChangeScope(value) {
|
|
9770
|
+
return typeof value === "string" && PHONE_CHANGE_SCOPES.includes(value) ? value : void 0;
|
|
9771
|
+
}
|
|
9772
|
+
function phoneCommitSha(value) {
|
|
9773
|
+
return typeof value === "string" && /^[0-9a-f]{4,40}$/i.test(value) ? value : void 0;
|
|
9774
|
+
}
|
|
9643
9775
|
var MAX_ROWS = 200;
|
|
9644
9776
|
var MAX_QUERY = 200;
|
|
9645
9777
|
function parsePhonePane(value, chatId) {
|
|
9646
9778
|
const pane = value && typeof value === "object" ? value.pane : void 0;
|
|
9647
9779
|
if (pane !== "files" && pane !== "changes" && pane !== "checks") return "invalid";
|
|
9648
|
-
const
|
|
9649
|
-
const
|
|
9780
|
+
const scope = phoneChangeScope(value.scope);
|
|
9781
|
+
const commitSha = phoneCommitSha(value.commitSha);
|
|
9650
9782
|
const queryRaw = value.query;
|
|
9651
9783
|
const query = typeof queryRaw === "string" ? queryRaw.trim().slice(0, MAX_QUERY) : "";
|
|
9652
9784
|
return {
|
|
@@ -9654,6 +9786,7 @@ function parsePhonePane(value, chatId) {
|
|
|
9654
9786
|
chatId,
|
|
9655
9787
|
pane,
|
|
9656
9788
|
...scope && pane === "changes" ? { scope } : {},
|
|
9789
|
+
...commitSha && pane === "changes" && scope === "commits" ? { commitSha } : {},
|
|
9657
9790
|
...query && pane === "files" ? { query } : {}
|
|
9658
9791
|
};
|
|
9659
9792
|
}
|
|
@@ -9662,10 +9795,10 @@ function filterPhoneFiles(paths, query) {
|
|
|
9662
9795
|
if (!q) return paths;
|
|
9663
9796
|
return paths.filter((path2) => path2.toLowerCase().includes(q));
|
|
9664
9797
|
}
|
|
9665
|
-
async function readPhonePane(thread, pane, scope, query) {
|
|
9798
|
+
async function readPhonePane(thread, pane, scope, query, commitSha) {
|
|
9666
9799
|
try {
|
|
9667
9800
|
if (pane === "files") return await readFiles(thread.id, query);
|
|
9668
|
-
if (pane === "changes") return await readChanges(thread.id, scope ??
|
|
9801
|
+
if (pane === "changes") return await readChanges(thread.id, scope ?? PHONE_CHANGE_SCOPE_DEFAULT, commitSha);
|
|
9669
9802
|
return await readChecks(thread.id);
|
|
9670
9803
|
} catch (err) {
|
|
9671
9804
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -9682,9 +9815,14 @@ async function readFiles(threadId, query) {
|
|
|
9682
9815
|
...note ? { note } : {}
|
|
9683
9816
|
};
|
|
9684
9817
|
}
|
|
9685
|
-
async function readChanges(threadId, scope) {
|
|
9686
|
-
const diff = await getOrchestrator().diff(threadId, {
|
|
9818
|
+
async function readChanges(threadId, scope, commitSha) {
|
|
9819
|
+
const diff = await getOrchestrator().diff(threadId, {
|
|
9820
|
+
includePatches: false,
|
|
9821
|
+
scope,
|
|
9822
|
+
commitSha: scope === "commits" ? commitSha ?? null : null
|
|
9823
|
+
});
|
|
9687
9824
|
const shown = diff.files.slice(0, MAX_ROWS);
|
|
9825
|
+
const selected = diff.commits.find((commit) => commit.sha === commitSha || commit.shortSha === commitSha);
|
|
9688
9826
|
return {
|
|
9689
9827
|
rows: shown.map((file) => {
|
|
9690
9828
|
const detail = changeDetail(file.additions, file.deletions);
|
|
@@ -9695,7 +9833,13 @@ async function readChanges(threadId, scope) {
|
|
|
9695
9833
|
...detail ? { detail } : {}
|
|
9696
9834
|
};
|
|
9697
9835
|
}),
|
|
9698
|
-
...diff.files.length > shown.length ? { note: `${diff.files.length - shown.length} more changed files` } : {}
|
|
9836
|
+
...diff.files.length > shown.length ? { note: `${diff.files.length - shown.length} more changed files` } : {},
|
|
9837
|
+
scope: diff.scope,
|
|
9838
|
+
commitSha: selected?.sha ?? null,
|
|
9839
|
+
...diff.base ? { base: diff.base } : {},
|
|
9840
|
+
hasLastTurnBase: diff.hasLastTurnBase,
|
|
9841
|
+
commits: diff.commits.slice(0, 40),
|
|
9842
|
+
scopeStats: diff.scopeStats
|
|
9699
9843
|
};
|
|
9700
9844
|
}
|
|
9701
9845
|
function changeDetail(additions, deletions) {
|
|
@@ -9704,13 +9848,14 @@ function changeDetail(additions, deletions) {
|
|
|
9704
9848
|
if (add === 0 && del === 0) return void 0;
|
|
9705
9849
|
return `+${add} \u2212${del}`;
|
|
9706
9850
|
}
|
|
9707
|
-
async function readPhoneChangePatch(threadId, path2) {
|
|
9851
|
+
async function readPhoneChangePatch(threadId, path2, scope = PHONE_CHANGE_SCOPE_DEFAULT, commitSha) {
|
|
9708
9852
|
const diff = await getOrchestrator().diff(threadId, {
|
|
9709
9853
|
path: path2,
|
|
9710
|
-
scope
|
|
9854
|
+
scope,
|
|
9855
|
+
commitSha: scope === "commits" ? commitSha ?? null : null,
|
|
9711
9856
|
includePatches: true,
|
|
9712
9857
|
includeMeta: false,
|
|
9713
|
-
includeUntracked:
|
|
9858
|
+
includeUntracked: scope === "uncommitted" || scope === "unstaged" || scope === "last_turn" || scope === "commits" && !commitSha
|
|
9714
9859
|
});
|
|
9715
9860
|
const file = diff.files.find((row2) => row2.path === path2) ?? diff.files[0];
|
|
9716
9861
|
if (!file) return null;
|
|
@@ -10055,7 +10200,7 @@ function listPhoneHistory(opts) {
|
|
|
10055
10200
|
}
|
|
10056
10201
|
|
|
10057
10202
|
// src/remote/phone-chats.ts
|
|
10058
|
-
var
|
|
10203
|
+
var PHONE_CONTROL_PREFIX2 = "\0sb.phone\n";
|
|
10059
10204
|
var PREVIEW_LIMIT2 = 90;
|
|
10060
10205
|
var AGENT_KINDS = /* @__PURE__ */ new Set(["claude", "codex", "opencode", "brightsy", "cursor"]);
|
|
10061
10206
|
var MAX_PHONE_FILES = 8;
|
|
@@ -10063,13 +10208,13 @@ var MAX_PHONE_FILE_CHARS = Math.ceil(8 * 1024 * 1024 * 4 / 3);
|
|
|
10063
10208
|
var MAX_PHONE_FILES_CHARS = Math.ceil(20 * 1024 * 1024 * 4 / 3);
|
|
10064
10209
|
var MAX_DICTATION_CHARS = Math.ceil(12 * 1024 * 1024 * 4 / 3);
|
|
10065
10210
|
function encodePhoneControl(payload) {
|
|
10066
|
-
return
|
|
10211
|
+
return PHONE_CONTROL_PREFIX2 + JSON.stringify(payload);
|
|
10067
10212
|
}
|
|
10068
10213
|
function takePhoneControl(text5) {
|
|
10069
|
-
if (!text5.startsWith(
|
|
10214
|
+
if (!text5.startsWith(PHONE_CONTROL_PREFIX2)) return null;
|
|
10070
10215
|
let parsed;
|
|
10071
10216
|
try {
|
|
10072
|
-
parsed = JSON.parse(text5.slice(
|
|
10217
|
+
parsed = JSON.parse(text5.slice(PHONE_CONTROL_PREFIX2.length));
|
|
10073
10218
|
} catch {
|
|
10074
10219
|
return "invalid";
|
|
10075
10220
|
}
|
|
@@ -10080,14 +10225,14 @@ function parsePhoneControl(value) {
|
|
|
10080
10225
|
const op = value.op;
|
|
10081
10226
|
if (op === "list") return { op: "list" };
|
|
10082
10227
|
if (op === "history") {
|
|
10083
|
-
const query =
|
|
10084
|
-
const after =
|
|
10228
|
+
const query = textField2(value, "query");
|
|
10229
|
+
const after = textField2(value, "after");
|
|
10085
10230
|
return { op: "history", ...query ? { query } : {}, ...after ? { after } : {} };
|
|
10086
10231
|
}
|
|
10087
10232
|
if (op === "sources") {
|
|
10088
|
-
const repoPath =
|
|
10233
|
+
const repoPath = textField2(value, "repoPath");
|
|
10089
10234
|
if (!repoPath || !isProjectPath2(repoPath)) return "invalid";
|
|
10090
|
-
const query =
|
|
10235
|
+
const query = textField2(value, "query");
|
|
10091
10236
|
return { op: "sources", repoPath, ...query ? { query } : {} };
|
|
10092
10237
|
}
|
|
10093
10238
|
if (op === "models") {
|
|
@@ -10096,7 +10241,7 @@ function parsePhoneControl(value) {
|
|
|
10096
10241
|
return { op: "models", agent };
|
|
10097
10242
|
}
|
|
10098
10243
|
if (op === "dictate") {
|
|
10099
|
-
const id =
|
|
10244
|
+
const id = textField2(value, "id");
|
|
10100
10245
|
const audioBase64 = base64Field(value, "audioBase64");
|
|
10101
10246
|
if (!id || !audioBase64 || audioBase64.length > MAX_DICTATION_CHARS) return "invalid";
|
|
10102
10247
|
return { op: "dictate", id, audioBase64 };
|
|
@@ -10108,26 +10253,30 @@ function parsePhoneControl(value) {
|
|
|
10108
10253
|
return { op, chatId };
|
|
10109
10254
|
}
|
|
10110
10255
|
if (op === "git") {
|
|
10111
|
-
const action =
|
|
10256
|
+
const action = textField2(value, "action");
|
|
10112
10257
|
if (!PHONE_HEADER_GIT_ACTIONS.includes(action)) return "invalid";
|
|
10113
10258
|
return { op: "git", chatId, action };
|
|
10114
10259
|
}
|
|
10115
10260
|
if (op === "pane") return parsePhonePane(value, chatId);
|
|
10116
10261
|
if (op === "open-artifact") return parseOpenArtifact(value, chatId);
|
|
10117
10262
|
if (op === "open-file" || op === "media") {
|
|
10118
|
-
const path2 =
|
|
10263
|
+
const path2 = textField2(value, "path");
|
|
10119
10264
|
if (!path2 || path2.length > 2e3) return "invalid";
|
|
10120
10265
|
if (op === "media") return { op, chatId, path: path2 };
|
|
10121
10266
|
const startLine = lineField(value, "startLine");
|
|
10122
10267
|
const endLine = lineField(value, "endLine");
|
|
10123
|
-
const view =
|
|
10268
|
+
const view = textField2(value, "view") === "diff" ? "diff" : void 0;
|
|
10269
|
+
const scope = phoneChangeScope(value.scope);
|
|
10270
|
+
const commitSha = phoneCommitSha(value.commitSha);
|
|
10124
10271
|
return {
|
|
10125
10272
|
op,
|
|
10126
10273
|
chatId,
|
|
10127
10274
|
path: path2,
|
|
10128
10275
|
...startLine != null ? { startLine } : {},
|
|
10129
10276
|
...endLine != null ? { endLine } : {},
|
|
10130
|
-
...view ? { view } : {}
|
|
10277
|
+
...view ? { view } : {},
|
|
10278
|
+
...view && scope ? { scope } : {},
|
|
10279
|
+
...view && scope === "commits" && commitSha ? { commitSha } : {}
|
|
10131
10280
|
};
|
|
10132
10281
|
}
|
|
10133
10282
|
const draft = parsePhoneDraft(value);
|
|
@@ -10141,7 +10290,7 @@ function parsePhoneControl(value) {
|
|
|
10141
10290
|
}
|
|
10142
10291
|
return "invalid";
|
|
10143
10292
|
}
|
|
10144
|
-
function
|
|
10293
|
+
function textField2(value, key) {
|
|
10145
10294
|
const raw = value[key];
|
|
10146
10295
|
return typeof raw === "string" ? raw.trim() : "";
|
|
10147
10296
|
}
|
|
@@ -10151,7 +10300,7 @@ function lineField(value, key) {
|
|
|
10151
10300
|
return raw;
|
|
10152
10301
|
}
|
|
10153
10302
|
function agentField(value) {
|
|
10154
|
-
const agent =
|
|
10303
|
+
const agent = textField2(value, "agent");
|
|
10155
10304
|
if (!agent) return void 0;
|
|
10156
10305
|
return AGENT_KINDS.has(agent) ? agent : void 0;
|
|
10157
10306
|
}
|
|
@@ -10162,7 +10311,7 @@ function base64Field(value, key) {
|
|
|
10162
10311
|
}
|
|
10163
10312
|
function parsePhoneDraft(value) {
|
|
10164
10313
|
const draft = {};
|
|
10165
|
-
if (
|
|
10314
|
+
if (textField2(value, "agent")) {
|
|
10166
10315
|
const agent = agentField(value);
|
|
10167
10316
|
if (!agent) return "invalid";
|
|
10168
10317
|
draft.agent = agent;
|
|
@@ -10202,7 +10351,7 @@ function parsePhoneDraft(value) {
|
|
|
10202
10351
|
const refs = parsePhoneCodeRefs(value.refs);
|
|
10203
10352
|
if (refs === "invalid") return "invalid";
|
|
10204
10353
|
if (refs.length) draft.refs = refs;
|
|
10205
|
-
const prompt =
|
|
10354
|
+
const prompt = textField2(value, "prompt");
|
|
10206
10355
|
if (prompt) draft.prompt = prompt.slice(0, 2e4);
|
|
10207
10356
|
return draft;
|
|
10208
10357
|
}
|
|
@@ -10213,7 +10362,7 @@ function parsePhoneFiles(value) {
|
|
|
10213
10362
|
let total = 0;
|
|
10214
10363
|
for (const item of value) {
|
|
10215
10364
|
if (!item || typeof item !== "object") return "invalid";
|
|
10216
|
-
const name = (
|
|
10365
|
+
const name = (textField2(item, "name").replace(/[/\\]/g, "_") || "file").slice(0, 180);
|
|
10217
10366
|
const dataBase64 = base64Field(item, "dataBase64");
|
|
10218
10367
|
if (!dataBase64 || !/^[A-Za-z0-9+/=]+$/.test(dataBase64)) return "invalid";
|
|
10219
10368
|
if (dataBase64.length > MAX_PHONE_FILE_CHARS) return "invalid";
|
|
@@ -10229,10 +10378,10 @@ function parsePhoneLinks(value) {
|
|
|
10229
10378
|
const links = [];
|
|
10230
10379
|
for (const item of value) {
|
|
10231
10380
|
if (!item || typeof item !== "object") return "invalid";
|
|
10232
|
-
const ref =
|
|
10381
|
+
const ref = textField2(item, "ref").slice(0, 80);
|
|
10233
10382
|
if (!ref) return "invalid";
|
|
10234
|
-
const title = (
|
|
10235
|
-
const url =
|
|
10383
|
+
const title = (textField2(item, "title") || ref).slice(0, 200);
|
|
10384
|
+
const url = textField2(item, "url").slice(0, 500);
|
|
10236
10385
|
links.push({ ref, title, ...url ? { url } : {} });
|
|
10237
10386
|
}
|
|
10238
10387
|
return links;
|
|
@@ -10240,7 +10389,7 @@ function parsePhoneLinks(value) {
|
|
|
10240
10389
|
function parsePhoneCreate(value) {
|
|
10241
10390
|
const draft = parsePhoneDraft(value);
|
|
10242
10391
|
if (draft === "invalid") return "invalid";
|
|
10243
|
-
const goal =
|
|
10392
|
+
const goal = textField2(value, "goal") || draft.prompt || "";
|
|
10244
10393
|
const where = value.where;
|
|
10245
10394
|
if (where == null || where === "orchestration") {
|
|
10246
10395
|
return {
|
|
@@ -10251,20 +10400,20 @@ function parsePhoneCreate(value) {
|
|
|
10251
10400
|
};
|
|
10252
10401
|
}
|
|
10253
10402
|
if (where === "worktree") {
|
|
10254
|
-
const chatId =
|
|
10403
|
+
const chatId = textField2(value, "chatId");
|
|
10255
10404
|
if (!chatId) return "invalid";
|
|
10256
10405
|
return { op: "create", where: "worktree", chatId, ...draft };
|
|
10257
10406
|
}
|
|
10258
10407
|
if (where === "project") {
|
|
10259
|
-
const repoPath =
|
|
10408
|
+
const repoPath = textField2(value, "repoPath");
|
|
10260
10409
|
if (!repoPath || !isProjectPath2(repoPath)) return "invalid";
|
|
10261
|
-
const sourceRaw =
|
|
10410
|
+
const sourceRaw = textField2(value, "sourceType");
|
|
10262
10411
|
let sourceType;
|
|
10263
10412
|
if (sourceRaw === "branch" || sourceRaw === "pr" || sourceRaw === "ticket") sourceType = sourceRaw;
|
|
10264
10413
|
else if (sourceRaw) return "invalid";
|
|
10265
|
-
const sourceRef =
|
|
10414
|
+
const sourceRef = textField2(value, "sourceRef");
|
|
10266
10415
|
if ((sourceType === "pr" || sourceType === "ticket") && !sourceRef) return "invalid";
|
|
10267
|
-
const title =
|
|
10416
|
+
const title = textField2(value, "title").slice(0, 200);
|
|
10268
10417
|
const cowboy = value.cowboy === true;
|
|
10269
10418
|
return {
|
|
10270
10419
|
op: "create",
|
|
@@ -10533,14 +10682,22 @@ function dispatchPhoneWorkspace(cmd, emit, publishOpened) {
|
|
|
10533
10682
|
emit({ op: "error", chatId: cmd.chatId, message: "That agent is not on this Mac." });
|
|
10534
10683
|
return;
|
|
10535
10684
|
}
|
|
10536
|
-
void readPhonePane(thread, cmd.pane, cmd.scope, cmd.query).then((body) => {
|
|
10685
|
+
void readPhonePane(thread, cmd.pane, cmd.scope, cmd.query, cmd.commitSha).then((body) => {
|
|
10537
10686
|
emit({
|
|
10538
10687
|
op: "pane",
|
|
10539
10688
|
chatId: cmd.chatId,
|
|
10540
10689
|
pane: cmd.pane,
|
|
10541
10690
|
rows: body.rows,
|
|
10542
10691
|
...body.note ? { note: body.note } : {},
|
|
10543
|
-
...cmd.pane === "files" ? { query: cmd.query ?? "" } : {}
|
|
10692
|
+
...cmd.pane === "files" ? { query: cmd.query ?? "" } : {},
|
|
10693
|
+
...cmd.pane === "changes" ? {
|
|
10694
|
+
scope: body.scope,
|
|
10695
|
+
commitSha: body.commitSha ?? null,
|
|
10696
|
+
...body.base ? { base: body.base } : {},
|
|
10697
|
+
hasLastTurnBase: body.hasLastTurnBase,
|
|
10698
|
+
commits: body.commits ?? [],
|
|
10699
|
+
...body.scopeStats ? { scopeStats: body.scopeStats } : {}
|
|
10700
|
+
} : {}
|
|
10544
10701
|
});
|
|
10545
10702
|
});
|
|
10546
10703
|
return;
|
|
@@ -10909,7 +11066,7 @@ function beginCoordinatorPrompt(body, opts) {
|
|
|
10909
11066
|
// src/remote/listen.ts
|
|
10910
11067
|
function emitOpened(opts, opened) {
|
|
10911
11068
|
setPhoneOpenChat(opened.chat.id);
|
|
10912
|
-
emitControl(opts, { op: "opened", ...opened });
|
|
11069
|
+
emitControl(opts, { op: "opened", ...opened, permission: phonePermissionView(opened.chat.id) });
|
|
10913
11070
|
}
|
|
10914
11071
|
function publishOpenedChat(opts, chatId) {
|
|
10915
11072
|
const opened = openPhoneChat(chatId);
|
|
@@ -11137,7 +11294,7 @@ function handlePhoneControl(cmd, opts) {
|
|
|
11137
11294
|
return;
|
|
11138
11295
|
}
|
|
11139
11296
|
if (cmd.view === "diff") {
|
|
11140
|
-
void readPhoneChangePatch(thread.id, relative).then((body) => {
|
|
11297
|
+
void readPhoneChangePatch(thread.id, relative, cmd.scope, cmd.commitSha).then((body) => {
|
|
11141
11298
|
if (!body) {
|
|
11142
11299
|
emitControl(opts, { op: "error", chatId: cmd.chatId, message: "That file has no changes to show." });
|
|
11143
11300
|
return;
|
|
@@ -11291,6 +11448,7 @@ function runPhonePrompt(opts, cmd, chatId, generation) {
|
|
|
11291
11448
|
}
|
|
11292
11449
|
function handleRemoteInbound(text5, opts) {
|
|
11293
11450
|
const body = text5.trim();
|
|
11451
|
+
if (dispatchPhonePermission(body, (reply) => emitControl(opts, reply))) return;
|
|
11294
11452
|
const control = takePhoneControl(body);
|
|
11295
11453
|
if (control) {
|
|
11296
11454
|
if (control === "invalid") {
|
|
@@ -11365,7 +11523,7 @@ function startPhoneBoardSync(opts) {
|
|
|
11365
11523
|
let timer = null;
|
|
11366
11524
|
let lastKey = "";
|
|
11367
11525
|
let stopped = false;
|
|
11368
|
-
const
|
|
11526
|
+
const push2 = () => {
|
|
11369
11527
|
timer = null;
|
|
11370
11528
|
if (stopped) return;
|
|
11371
11529
|
let sidebar;
|
|
@@ -11382,7 +11540,7 @@ function startPhoneBoardSync(opts) {
|
|
|
11382
11540
|
const schedule = () => {
|
|
11383
11541
|
if (stopped) return;
|
|
11384
11542
|
if (timer) clearTimeout(timer);
|
|
11385
|
-
timer = setTimeout(
|
|
11543
|
+
timer = setTimeout(push2, debounceMs);
|
|
11386
11544
|
};
|
|
11387
11545
|
const handle = (event) => {
|
|
11388
11546
|
if (isPhoneBoardEvent(event)) schedule();
|
|
@@ -11392,13 +11550,13 @@ function startPhoneBoardSync(opts) {
|
|
|
11392
11550
|
};
|
|
11393
11551
|
const unsubscribe = (opts.subscribe ?? subscribePhoneBoard)(schedule);
|
|
11394
11552
|
const offEvents = (opts.events ?? ((listener) => getOrchestrator().on(listener)))(handle);
|
|
11395
|
-
|
|
11553
|
+
push2();
|
|
11396
11554
|
let loginTimer = null;
|
|
11397
11555
|
const refreshViewerLogin = opts.refreshViewerLogin;
|
|
11398
11556
|
if (refreshViewerLogin) {
|
|
11399
11557
|
const afterLogin = () => {
|
|
11400
11558
|
void refreshViewerLogin().then(() => {
|
|
11401
|
-
if (!stopped)
|
|
11559
|
+
if (!stopped) push2();
|
|
11402
11560
|
});
|
|
11403
11561
|
};
|
|
11404
11562
|
afterLogin();
|
|
@@ -11635,6 +11793,10 @@ function runRemoteHost(opts) {
|
|
|
11635
11793
|
}
|
|
11636
11794
|
send3({ type: "ask_user", text: outbound.text, questions: outbound.questions });
|
|
11637
11795
|
};
|
|
11796
|
+
setPhonePermissionPush((chatId, prompt) => {
|
|
11797
|
+
if (getPhoneOpenChat() !== chatId) return;
|
|
11798
|
+
emitControl({ onOutbound: emit }, { op: "permission", chatId, prompt });
|
|
11799
|
+
});
|
|
11638
11800
|
void loop();
|
|
11639
11801
|
return {
|
|
11640
11802
|
requestPairingCode() {
|
|
@@ -13254,7 +13416,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
13254
13416
|
await continueOnReply(threadId, prompt);
|
|
13255
13417
|
return;
|
|
13256
13418
|
}
|
|
13257
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
13419
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-ZQU62CES.js");
|
|
13258
13420
|
await getOrchestrator2().send(threadId, prompt);
|
|
13259
13421
|
} catch {
|
|
13260
13422
|
}
|
|
@@ -13696,6 +13858,7 @@ export {
|
|
|
13696
13858
|
allocateTeamName,
|
|
13697
13859
|
allocateTeamSlug,
|
|
13698
13860
|
annotateDevAccessRuns,
|
|
13861
|
+
answerToolPermission,
|
|
13699
13862
|
appDataDir,
|
|
13700
13863
|
appSettingsPath,
|
|
13701
13864
|
appendCompactedMessages,
|