@sideboard-ai/core 0.1.290 → 0.1.292

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 (3) hide show
  1. package/dist/index.cjs +154 -60
  2. package/dist/index.js +154 -60
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -40353,6 +40353,98 @@ function pickArtifactMatch(items, request) {
40353
40353
  return null;
40354
40354
  }
40355
40355
 
40356
+ // src/remote/phone-panes.ts
40357
+ init_orchestrator();
40358
+ var MAX_ROWS = 200;
40359
+ var MAX_QUERY = 200;
40360
+ function parsePhonePane(value, chatId) {
40361
+ const pane = value && typeof value === "object" ? value.pane : void 0;
40362
+ if (pane !== "files" && pane !== "changes" && pane !== "checks") return "invalid";
40363
+ const scopeRaw = value.scope;
40364
+ const scope = scopeRaw === "uncommitted" || scopeRaw === "commits" ? scopeRaw : void 0;
40365
+ const queryRaw = value.query;
40366
+ const query = typeof queryRaw === "string" ? queryRaw.trim().slice(0, MAX_QUERY) : "";
40367
+ return {
40368
+ op: "pane",
40369
+ chatId,
40370
+ pane,
40371
+ ...scope && pane === "changes" ? { scope } : {},
40372
+ ...query && pane === "files" ? { query } : {}
40373
+ };
40374
+ }
40375
+ function filterPhoneFiles(paths, query) {
40376
+ const q = query.trim().toLowerCase();
40377
+ if (!q) return paths;
40378
+ return paths.filter((path2) => path2.toLowerCase().includes(q));
40379
+ }
40380
+ async function readPhonePane(thread, pane, scope, query) {
40381
+ try {
40382
+ if (pane === "files") return await readFiles(thread.id, query);
40383
+ if (pane === "changes") return await readChanges(thread.id, scope ?? "commits");
40384
+ return await readChecks(thread.id);
40385
+ } catch (err) {
40386
+ const message = err instanceof Error ? err.message : String(err);
40387
+ return { rows: [], note: message };
40388
+ }
40389
+ }
40390
+ async function readFiles(threadId, query) {
40391
+ const paths = filterPhoneFiles(await getOrchestrator().listFiles(threadId), query ?? "");
40392
+ const shown = paths.slice(0, MAX_ROWS);
40393
+ const extra = paths.length - shown.length;
40394
+ const note = extra > 0 ? query?.trim() ? `${extra} more matching files` : `${extra} more files on the Mac` : void 0;
40395
+ return {
40396
+ rows: shown.map((path2) => ({ label: path2, path: path2 })),
40397
+ ...note ? { note } : {}
40398
+ };
40399
+ }
40400
+ async function readChanges(threadId, scope) {
40401
+ const diff = await getOrchestrator().diff(threadId, { includePatches: false, scope });
40402
+ const shown = diff.files.slice(0, MAX_ROWS);
40403
+ return {
40404
+ rows: shown.map((file) => {
40405
+ const detail = changeDetail(file.additions, file.deletions);
40406
+ return {
40407
+ label: file.path,
40408
+ path: file.path,
40409
+ ...file.status ? { status: file.status } : {},
40410
+ ...detail ? { detail } : {}
40411
+ };
40412
+ }),
40413
+ ...diff.files.length > shown.length ? { note: `${diff.files.length - shown.length} more changed files` } : {}
40414
+ };
40415
+ }
40416
+ function changeDetail(additions, deletions) {
40417
+ const add = additions ?? 0;
40418
+ const del = deletions ?? 0;
40419
+ if (add === 0 && del === 0) return void 0;
40420
+ return `+${add} \u2212${del}`;
40421
+ }
40422
+ async function readPhoneChangePatch(threadId, path2) {
40423
+ const diff = await getOrchestrator().diff(threadId, {
40424
+ path: path2,
40425
+ scope: "commits",
40426
+ includePatches: true,
40427
+ includeMeta: false,
40428
+ includeUntracked: false
40429
+ });
40430
+ const file = diff.files.find((row2) => row2.path === path2) ?? diff.files[0];
40431
+ if (!file) return null;
40432
+ const content = file.patch ?? "";
40433
+ return { content, truncated: content.includes("\u2026 truncated") };
40434
+ }
40435
+ async function readChecks(threadId) {
40436
+ const checks = await getOrchestrator().getPrChecks(threadId);
40437
+ if (!checks) return { rows: [], note: "No pull request on this branch." };
40438
+ const shown = checks.slice(0, MAX_ROWS);
40439
+ return {
40440
+ rows: shown.map((check) => ({
40441
+ label: check.name,
40442
+ detail: check.bucket || check.state,
40443
+ ...check.link ? { href: check.link } : {}
40444
+ }))
40445
+ };
40446
+ }
40447
+
40356
40448
  // src/remote/phone-workspace-ops.ts
40357
40449
  init_orchestrator();
40358
40450
 
@@ -40504,63 +40596,34 @@ function headerAction(pr, diff) {
40504
40596
  return { id: "merge", label: "Merge" };
40505
40597
  }
40506
40598
 
40507
- // src/remote/phone-panes.ts
40508
- init_orchestrator();
40509
- var MAX_ROWS = 200;
40510
- function parsePhonePane(value, chatId) {
40511
- const pane = value && typeof value === "object" ? value.pane : void 0;
40512
- if (pane !== "files" && pane !== "changes" && pane !== "checks") return "invalid";
40513
- const scopeRaw = value.scope;
40514
- const scope = scopeRaw === "uncommitted" || scopeRaw === "commits" ? scopeRaw : void 0;
40515
- return { op: "pane", chatId, pane, ...scope && pane === "changes" ? { scope } : {} };
40599
+ // src/remote/phone-code-refs.ts
40600
+ var MAX_REFS = 8;
40601
+ var MAX_TEXT = 2e4;
40602
+ var MAX_TOTAL = 4e4;
40603
+ function lineNumber(value, key) {
40604
+ const raw = value[key];
40605
+ if (typeof raw !== "number" || !Number.isInteger(raw) || raw < 1 || raw > 1e6) return void 0;
40606
+ return raw;
40516
40607
  }
40517
- async function readPhonePane(thread, pane, scope) {
40518
- try {
40519
- if (pane === "files") return await readFiles(thread.id);
40520
- if (pane === "changes") return await readChanges(thread.id, scope ?? "commits");
40521
- return await readChecks(thread.id);
40522
- } catch (err) {
40523
- const message = err instanceof Error ? err.message : String(err);
40524
- return { rows: [], note: message };
40608
+ function parsePhoneCodeRefs(value) {
40609
+ if (value == null) return [];
40610
+ if (!Array.isArray(value) || value.length > MAX_REFS) return "invalid";
40611
+ const refs = [];
40612
+ let total = 0;
40613
+ for (const item of value) {
40614
+ if (!item || typeof item !== "object") return "invalid";
40615
+ const pathRaw = item.path;
40616
+ const path2 = typeof pathRaw === "string" ? pathRaw.trim().replace(/\\/g, "/").slice(0, 500) : "";
40617
+ const startLine = lineNumber(item, "startLine");
40618
+ const endLine = lineNumber(item, "endLine");
40619
+ const textRaw = item.text;
40620
+ const text7 = typeof textRaw === "string" ? textRaw.replace(/\n$/, "").slice(0, MAX_TEXT) : "";
40621
+ if (!path2 || !startLine || !endLine || endLine < startLine || !text7.trim()) return "invalid";
40622
+ total += text7.length;
40623
+ if (total > MAX_TOTAL) return "invalid";
40624
+ refs.push({ path: path2, startLine, endLine, text: text7 });
40525
40625
  }
40526
- }
40527
- async function readFiles(threadId) {
40528
- const paths = await getOrchestrator().listFiles(threadId);
40529
- const shown = paths.slice(0, MAX_ROWS);
40530
- return {
40531
- rows: shown.map((path2) => ({ label: path2, path: path2 })),
40532
- ...paths.length > shown.length ? { note: `${paths.length - shown.length} more files on the Mac` } : {}
40533
- };
40534
- }
40535
- async function readChanges(threadId, scope) {
40536
- const diff = await getOrchestrator().diff(threadId, { includePatches: false, scope });
40537
- const shown = diff.files.slice(0, MAX_ROWS);
40538
- return {
40539
- rows: shown.map((file) => ({
40540
- label: file.path,
40541
- path: file.path,
40542
- detail: changeDetail(file.additions, file.deletions)
40543
- })),
40544
- ...diff.files.length > shown.length ? { note: `${diff.files.length - shown.length} more changed files` } : {}
40545
- };
40546
- }
40547
- function changeDetail(additions, deletions) {
40548
- const add = additions ?? 0;
40549
- const del = deletions ?? 0;
40550
- if (add === 0 && del === 0) return void 0;
40551
- return `+${add} \u2212${del}`;
40552
- }
40553
- async function readChecks(threadId) {
40554
- const checks = await getOrchestrator().getPrChecks(threadId);
40555
- if (!checks) return { rows: [], note: "No pull request on this branch." };
40556
- const shown = checks.slice(0, MAX_ROWS);
40557
- return {
40558
- rows: shown.map((check) => ({
40559
- label: check.name,
40560
- detail: check.bucket || check.state,
40561
- ...check.link ? { href: check.link } : {}
40562
- }))
40563
- };
40626
+ return refs;
40564
40627
  }
40565
40628
 
40566
40629
  // src/remote/phone-defaults.ts
@@ -40787,12 +40850,14 @@ function parsePhoneControl(value) {
40787
40850
  if (op === "media") return { op, chatId, path: path2 };
40788
40851
  const startLine = lineField(value, "startLine");
40789
40852
  const endLine = lineField(value, "endLine");
40853
+ const view = textField(value, "view") === "diff" ? "diff" : void 0;
40790
40854
  return {
40791
40855
  op,
40792
40856
  chatId,
40793
40857
  path: path2,
40794
40858
  ...startLine != null ? { startLine } : {},
40795
- ...endLine != null ? { endLine } : {}
40859
+ ...endLine != null ? { endLine } : {},
40860
+ ...view ? { view } : {}
40796
40861
  };
40797
40862
  }
40798
40863
  const draft = parsePhoneDraft(value);
@@ -40800,7 +40865,7 @@ function parsePhoneControl(value) {
40800
40865
  if (op === "options") return { op: "options", chatId, ...draft };
40801
40866
  if (op === "prompt") {
40802
40867
  const text7 = typeof value.text === "string" ? value.text.trim() : "";
40803
- const hasPayload = Boolean(text7 || draft.files?.length || draft.links?.length);
40868
+ const hasPayload = Boolean(text7 || draft.files?.length || draft.links?.length || draft.refs?.length);
40804
40869
  if (!hasPayload) return "invalid";
40805
40870
  return { op: "prompt", chatId, text: text7, ...draft };
40806
40871
  }
@@ -40864,6 +40929,9 @@ function parsePhoneDraft(value) {
40864
40929
  const links = parsePhoneLinks(value.links);
40865
40930
  if (links === "invalid") return "invalid";
40866
40931
  if (links.length) draft.links = links;
40932
+ const refs = parsePhoneCodeRefs(value.refs);
40933
+ if (refs === "invalid") return "invalid";
40934
+ if (refs.length) draft.refs = refs;
40867
40935
  const prompt = textField(value, "prompt");
40868
40936
  if (prompt) draft.prompt = prompt.slice(0, 2e4);
40869
40937
  return draft;
@@ -41195,13 +41263,14 @@ function dispatchPhoneWorkspace(cmd, emit, publishOpened) {
41195
41263
  emit({ op: "error", chatId: cmd.chatId, message: "That agent is not on this Mac." });
41196
41264
  return;
41197
41265
  }
41198
- void readPhonePane(thread, cmd.pane, cmd.scope).then((body) => {
41266
+ void readPhonePane(thread, cmd.pane, cmd.scope, cmd.query).then((body) => {
41199
41267
  emit({
41200
41268
  op: "pane",
41201
41269
  chatId: cmd.chatId,
41202
41270
  pane: cmd.pane,
41203
41271
  rows: body.rows,
41204
- ...body.note ? { note: body.note } : {}
41272
+ ...body.note ? { note: body.note } : {},
41273
+ ...cmd.pane === "files" ? { query: cmd.query ?? "" } : {}
41205
41274
  });
41206
41275
  });
41207
41276
  return;
@@ -41611,7 +41680,8 @@ function stagePhoneTurnFiles(worktreePath, draft) {
41611
41680
  worktreePath,
41612
41681
  (draft.files ?? []).map((file) => ({ name: file.name, dataBase64: file.dataBase64 }))
41613
41682
  );
41614
- return [...links, ...files];
41683
+ const refs = (draft.refs ?? []).map((ref) => buildCodeRefAttachment(ref));
41684
+ return [...links, ...files, ...refs];
41615
41685
  }
41616
41686
  function handlePhoneControl(cmd, opts) {
41617
41687
  const log = opts.onLog ?? (() => void 0);
@@ -41807,6 +41877,30 @@ function handlePhoneControl(cmd, opts) {
41807
41877
  emitControl(opts, { op: "error", chatId: cmd.chatId, message: "That file is not in this worktree." });
41808
41878
  return;
41809
41879
  }
41880
+ if (cmd.view === "diff") {
41881
+ void readPhoneChangePatch(thread.id, relative).then((body) => {
41882
+ if (!body) {
41883
+ emitControl(opts, { op: "error", chatId: cmd.chatId, message: "That file has no changes to show." });
41884
+ return;
41885
+ }
41886
+ emitControl(opts, {
41887
+ op: "file",
41888
+ chatId: cmd.chatId,
41889
+ path: relative,
41890
+ content: body.content,
41891
+ encoding: "utf8",
41892
+ view: "diff",
41893
+ ...body.truncated ? { truncated: true } : {}
41894
+ });
41895
+ }).catch(() => {
41896
+ emitControl(opts, {
41897
+ op: "error",
41898
+ chatId: cmd.chatId,
41899
+ message: "That file could not be opened on the phone."
41900
+ });
41901
+ });
41902
+ return;
41903
+ }
41810
41904
  void getOrchestrator().statPath(thread.id, relative).then((kind) => {
41811
41905
  if (kind === "missing") {
41812
41906
  emitControl(opts, { op: "error", chatId: cmd.chatId, message: "That file is not in this worktree." });
package/dist/index.js CHANGED
@@ -9624,6 +9624,97 @@ function pickArtifactMatch(items, request) {
9624
9624
  return null;
9625
9625
  }
9626
9626
 
9627
+ // src/remote/phone-panes.ts
9628
+ var MAX_ROWS = 200;
9629
+ var MAX_QUERY = 200;
9630
+ function parsePhonePane(value, chatId) {
9631
+ const pane = value && typeof value === "object" ? value.pane : void 0;
9632
+ if (pane !== "files" && pane !== "changes" && pane !== "checks") return "invalid";
9633
+ const scopeRaw = value.scope;
9634
+ const scope = scopeRaw === "uncommitted" || scopeRaw === "commits" ? scopeRaw : void 0;
9635
+ const queryRaw = value.query;
9636
+ const query = typeof queryRaw === "string" ? queryRaw.trim().slice(0, MAX_QUERY) : "";
9637
+ return {
9638
+ op: "pane",
9639
+ chatId,
9640
+ pane,
9641
+ ...scope && pane === "changes" ? { scope } : {},
9642
+ ...query && pane === "files" ? { query } : {}
9643
+ };
9644
+ }
9645
+ function filterPhoneFiles(paths, query) {
9646
+ const q = query.trim().toLowerCase();
9647
+ if (!q) return paths;
9648
+ return paths.filter((path2) => path2.toLowerCase().includes(q));
9649
+ }
9650
+ async function readPhonePane(thread, pane, scope, query) {
9651
+ try {
9652
+ if (pane === "files") return await readFiles(thread.id, query);
9653
+ if (pane === "changes") return await readChanges(thread.id, scope ?? "commits");
9654
+ return await readChecks(thread.id);
9655
+ } catch (err) {
9656
+ const message = err instanceof Error ? err.message : String(err);
9657
+ return { rows: [], note: message };
9658
+ }
9659
+ }
9660
+ async function readFiles(threadId, query) {
9661
+ const paths = filterPhoneFiles(await getOrchestrator().listFiles(threadId), query ?? "");
9662
+ const shown = paths.slice(0, MAX_ROWS);
9663
+ const extra = paths.length - shown.length;
9664
+ const note = extra > 0 ? query?.trim() ? `${extra} more matching files` : `${extra} more files on the Mac` : void 0;
9665
+ return {
9666
+ rows: shown.map((path2) => ({ label: path2, path: path2 })),
9667
+ ...note ? { note } : {}
9668
+ };
9669
+ }
9670
+ async function readChanges(threadId, scope) {
9671
+ const diff = await getOrchestrator().diff(threadId, { includePatches: false, scope });
9672
+ const shown = diff.files.slice(0, MAX_ROWS);
9673
+ return {
9674
+ rows: shown.map((file) => {
9675
+ const detail = changeDetail(file.additions, file.deletions);
9676
+ return {
9677
+ label: file.path,
9678
+ path: file.path,
9679
+ ...file.status ? { status: file.status } : {},
9680
+ ...detail ? { detail } : {}
9681
+ };
9682
+ }),
9683
+ ...diff.files.length > shown.length ? { note: `${diff.files.length - shown.length} more changed files` } : {}
9684
+ };
9685
+ }
9686
+ function changeDetail(additions, deletions) {
9687
+ const add = additions ?? 0;
9688
+ const del = deletions ?? 0;
9689
+ if (add === 0 && del === 0) return void 0;
9690
+ return `+${add} \u2212${del}`;
9691
+ }
9692
+ async function readPhoneChangePatch(threadId, path2) {
9693
+ const diff = await getOrchestrator().diff(threadId, {
9694
+ path: path2,
9695
+ scope: "commits",
9696
+ includePatches: true,
9697
+ includeMeta: false,
9698
+ includeUntracked: false
9699
+ });
9700
+ const file = diff.files.find((row2) => row2.path === path2) ?? diff.files[0];
9701
+ if (!file) return null;
9702
+ const content = file.patch ?? "";
9703
+ return { content, truncated: content.includes("\u2026 truncated") };
9704
+ }
9705
+ async function readChecks(threadId) {
9706
+ const checks = await getOrchestrator().getPrChecks(threadId);
9707
+ if (!checks) return { rows: [], note: "No pull request on this branch." };
9708
+ const shown = checks.slice(0, MAX_ROWS);
9709
+ return {
9710
+ rows: shown.map((check) => ({
9711
+ label: check.name,
9712
+ detail: check.bucket || check.state,
9713
+ ...check.link ? { href: check.link } : {}
9714
+ }))
9715
+ };
9716
+ }
9717
+
9627
9718
  // src/remote/phone-chats.ts
9628
9719
  import { randomUUID as randomUUID7 } from "crypto";
9629
9720
 
@@ -9758,62 +9849,34 @@ function headerAction(pr, diff) {
9758
9849
  return { id: "merge", label: "Merge" };
9759
9850
  }
9760
9851
 
9761
- // src/remote/phone-panes.ts
9762
- var MAX_ROWS = 200;
9763
- function parsePhonePane(value, chatId) {
9764
- const pane = value && typeof value === "object" ? value.pane : void 0;
9765
- if (pane !== "files" && pane !== "changes" && pane !== "checks") return "invalid";
9766
- const scopeRaw = value.scope;
9767
- const scope = scopeRaw === "uncommitted" || scopeRaw === "commits" ? scopeRaw : void 0;
9768
- return { op: "pane", chatId, pane, ...scope && pane === "changes" ? { scope } : {} };
9769
- }
9770
- async function readPhonePane(thread, pane, scope) {
9771
- try {
9772
- if (pane === "files") return await readFiles(thread.id);
9773
- if (pane === "changes") return await readChanges(thread.id, scope ?? "commits");
9774
- return await readChecks(thread.id);
9775
- } catch (err) {
9776
- const message = err instanceof Error ? err.message : String(err);
9777
- return { rows: [], note: message };
9778
- }
9779
- }
9780
- async function readFiles(threadId) {
9781
- const paths = await getOrchestrator().listFiles(threadId);
9782
- const shown = paths.slice(0, MAX_ROWS);
9783
- return {
9784
- rows: shown.map((path2) => ({ label: path2, path: path2 })),
9785
- ...paths.length > shown.length ? { note: `${paths.length - shown.length} more files on the Mac` } : {}
9786
- };
9787
- }
9788
- async function readChanges(threadId, scope) {
9789
- const diff = await getOrchestrator().diff(threadId, { includePatches: false, scope });
9790
- const shown = diff.files.slice(0, MAX_ROWS);
9791
- return {
9792
- rows: shown.map((file) => ({
9793
- label: file.path,
9794
- path: file.path,
9795
- detail: changeDetail(file.additions, file.deletions)
9796
- })),
9797
- ...diff.files.length > shown.length ? { note: `${diff.files.length - shown.length} more changed files` } : {}
9798
- };
9799
- }
9800
- function changeDetail(additions, deletions) {
9801
- const add = additions ?? 0;
9802
- const del = deletions ?? 0;
9803
- if (add === 0 && del === 0) return void 0;
9804
- return `+${add} \u2212${del}`;
9852
+ // src/remote/phone-code-refs.ts
9853
+ var MAX_REFS = 8;
9854
+ var MAX_TEXT = 2e4;
9855
+ var MAX_TOTAL = 4e4;
9856
+ function lineNumber(value, key) {
9857
+ const raw = value[key];
9858
+ if (typeof raw !== "number" || !Number.isInteger(raw) || raw < 1 || raw > 1e6) return void 0;
9859
+ return raw;
9805
9860
  }
9806
- async function readChecks(threadId) {
9807
- const checks = await getOrchestrator().getPrChecks(threadId);
9808
- if (!checks) return { rows: [], note: "No pull request on this branch." };
9809
- const shown = checks.slice(0, MAX_ROWS);
9810
- return {
9811
- rows: shown.map((check) => ({
9812
- label: check.name,
9813
- detail: check.bucket || check.state,
9814
- ...check.link ? { href: check.link } : {}
9815
- }))
9816
- };
9861
+ function parsePhoneCodeRefs(value) {
9862
+ if (value == null) return [];
9863
+ if (!Array.isArray(value) || value.length > MAX_REFS) return "invalid";
9864
+ const refs = [];
9865
+ let total = 0;
9866
+ for (const item of value) {
9867
+ if (!item || typeof item !== "object") return "invalid";
9868
+ const pathRaw = item.path;
9869
+ const path2 = typeof pathRaw === "string" ? pathRaw.trim().replace(/\\/g, "/").slice(0, 500) : "";
9870
+ const startLine = lineNumber(item, "startLine");
9871
+ const endLine = lineNumber(item, "endLine");
9872
+ const textRaw = item.text;
9873
+ const text5 = typeof textRaw === "string" ? textRaw.replace(/\n$/, "").slice(0, MAX_TEXT) : "";
9874
+ if (!path2 || !startLine || !endLine || endLine < startLine || !text5.trim()) return "invalid";
9875
+ total += text5.length;
9876
+ if (total > MAX_TOTAL) return "invalid";
9877
+ refs.push({ path: path2, startLine, endLine, text: text5 });
9878
+ }
9879
+ return refs;
9817
9880
  }
9818
9881
 
9819
9882
  // src/remote/phone-defaults.ts
@@ -10033,12 +10096,14 @@ function parsePhoneControl(value) {
10033
10096
  if (op === "media") return { op, chatId, path: path2 };
10034
10097
  const startLine = lineField(value, "startLine");
10035
10098
  const endLine = lineField(value, "endLine");
10099
+ const view = textField(value, "view") === "diff" ? "diff" : void 0;
10036
10100
  return {
10037
10101
  op,
10038
10102
  chatId,
10039
10103
  path: path2,
10040
10104
  ...startLine != null ? { startLine } : {},
10041
- ...endLine != null ? { endLine } : {}
10105
+ ...endLine != null ? { endLine } : {},
10106
+ ...view ? { view } : {}
10042
10107
  };
10043
10108
  }
10044
10109
  const draft = parsePhoneDraft(value);
@@ -10046,7 +10111,7 @@ function parsePhoneControl(value) {
10046
10111
  if (op === "options") return { op: "options", chatId, ...draft };
10047
10112
  if (op === "prompt") {
10048
10113
  const text5 = typeof value.text === "string" ? value.text.trim() : "";
10049
- const hasPayload = Boolean(text5 || draft.files?.length || draft.links?.length);
10114
+ const hasPayload = Boolean(text5 || draft.files?.length || draft.links?.length || draft.refs?.length);
10050
10115
  if (!hasPayload) return "invalid";
10051
10116
  return { op: "prompt", chatId, text: text5, ...draft };
10052
10117
  }
@@ -10110,6 +10175,9 @@ function parsePhoneDraft(value) {
10110
10175
  const links = parsePhoneLinks(value.links);
10111
10176
  if (links === "invalid") return "invalid";
10112
10177
  if (links.length) draft.links = links;
10178
+ const refs = parsePhoneCodeRefs(value.refs);
10179
+ if (refs === "invalid") return "invalid";
10180
+ if (refs.length) draft.refs = refs;
10113
10181
  const prompt = textField(value, "prompt");
10114
10182
  if (prompt) draft.prompt = prompt.slice(0, 2e4);
10115
10183
  return draft;
@@ -10441,13 +10509,14 @@ function dispatchPhoneWorkspace(cmd, emit, publishOpened) {
10441
10509
  emit({ op: "error", chatId: cmd.chatId, message: "That agent is not on this Mac." });
10442
10510
  return;
10443
10511
  }
10444
- void readPhonePane(thread, cmd.pane, cmd.scope).then((body) => {
10512
+ void readPhonePane(thread, cmd.pane, cmd.scope, cmd.query).then((body) => {
10445
10513
  emit({
10446
10514
  op: "pane",
10447
10515
  chatId: cmd.chatId,
10448
10516
  pane: cmd.pane,
10449
10517
  rows: body.rows,
10450
- ...body.note ? { note: body.note } : {}
10518
+ ...body.note ? { note: body.note } : {},
10519
+ ...cmd.pane === "files" ? { query: cmd.query ?? "" } : {}
10451
10520
  });
10452
10521
  });
10453
10522
  return;
@@ -10846,7 +10915,8 @@ function stagePhoneTurnFiles(worktreePath, draft) {
10846
10915
  worktreePath,
10847
10916
  (draft.files ?? []).map((file) => ({ name: file.name, dataBase64: file.dataBase64 }))
10848
10917
  );
10849
- return [...links, ...files];
10918
+ const refs = (draft.refs ?? []).map((ref) => buildCodeRefAttachment(ref));
10919
+ return [...links, ...files, ...refs];
10850
10920
  }
10851
10921
  function handlePhoneControl(cmd, opts) {
10852
10922
  const log = opts.onLog ?? (() => void 0);
@@ -11042,6 +11112,30 @@ function handlePhoneControl(cmd, opts) {
11042
11112
  emitControl(opts, { op: "error", chatId: cmd.chatId, message: "That file is not in this worktree." });
11043
11113
  return;
11044
11114
  }
11115
+ if (cmd.view === "diff") {
11116
+ void readPhoneChangePatch(thread.id, relative).then((body) => {
11117
+ if (!body) {
11118
+ emitControl(opts, { op: "error", chatId: cmd.chatId, message: "That file has no changes to show." });
11119
+ return;
11120
+ }
11121
+ emitControl(opts, {
11122
+ op: "file",
11123
+ chatId: cmd.chatId,
11124
+ path: relative,
11125
+ content: body.content,
11126
+ encoding: "utf8",
11127
+ view: "diff",
11128
+ ...body.truncated ? { truncated: true } : {}
11129
+ });
11130
+ }).catch(() => {
11131
+ emitControl(opts, {
11132
+ op: "error",
11133
+ chatId: cmd.chatId,
11134
+ message: "That file could not be opened on the phone."
11135
+ });
11136
+ });
11137
+ return;
11138
+ }
11045
11139
  void getOrchestrator().statPath(thread.id, relative).then((kind) => {
11046
11140
  if (kind === "missing") {
11047
11141
  emitControl(opts, { op: "error", chatId: cmd.chatId, message: "That file is not in this worktree." });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sideboard-ai/core",
3
- "version": "0.1.290",
3
+ "version": "0.1.292",
4
4
  "description": "Sideboard core — orchestration, agents, git worktrees, MCP server",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",