@sideboard-ai/core 0.1.310 → 0.1.311

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/index.js CHANGED
@@ -201,7 +201,7 @@ import {
201
201
  worktreeCleanupSettings,
202
202
  writeAgentBlock,
203
203
  writeWorktreeFile
204
- } from "./chunk-IT6A4FZF.js";
204
+ } from "./chunk-2ER7DQJP.js";
205
205
  import {
206
206
  LEGACY_PLAN_FILE_REL,
207
207
  PLAN_FILE_NAME,
@@ -335,6 +335,7 @@ import {
335
335
  appendCompactedMessages,
336
336
  applyCompaction,
337
337
  applyForwardOccupancy,
338
+ askBlockStillWaiting,
338
339
  buildBrightsySessionSeed,
339
340
  buildForkTranscriptAttachment,
340
341
  buildReviewRequestAttachment,
@@ -380,6 +381,7 @@ import {
380
381
  killStaleWorktreeListeners,
381
382
  killableListenerPids,
382
383
  lastRequestOccupancy,
384
+ lastTopLevelToolIsAskUser,
383
385
  latestPendingPlanQuestions,
384
386
  linkSharedDirectories,
385
387
  listRunScripts,
@@ -424,7 +426,7 @@ import {
424
426
  workspaceAgentChatSummaries,
425
427
  worktreeRunPortsPath,
426
428
  wrapReviewSkillMarkdown
427
- } from "./chunk-VBVSJUM2.js";
429
+ } from "./chunk-QC2TQMPJ.js";
428
430
  import {
429
431
  STDERR_EVENT_MAX_CHARS,
430
432
  STDOUT_EVENT_MAX_CHARS,
@@ -2848,6 +2850,7 @@ function parsePhoneCreate(value) {
2848
2850
  }
2849
2851
  function summarize(thread) {
2850
2852
  const pr = phonePrPill(thread);
2853
+ const block = visibleAgentBlock(thread);
2851
2854
  return {
2852
2855
  id: thread.id,
2853
2856
  title: thread.title?.trim() || "Untitled",
@@ -2858,14 +2861,12 @@ function summarize(thread) {
2858
2861
  ...pr?.url ? { prUrl: pr.url } : {},
2859
2862
  ...pr?.number ? { prNumber: pr.number } : {},
2860
2863
  ...pr?.status ? { prStatus: pr.status } : {},
2861
- ...thread.agentBlock ? { needsYou: true, blockedReason: thread.agentBlock.reason } : {}
2864
+ ...block ? { needsYou: true, blockedReason: block.reason } : {}
2862
2865
  };
2863
2866
  }
2864
2867
  function previewOf2(thread) {
2865
- const messages = listPhoneMessages(thread);
2866
- const last = messages[messages.length - 1];
2867
- if (!last) return "";
2868
- return clip(last.text.replace(/\s+/g, " ").trim(), PREVIEW_LIMIT2);
2868
+ const last = listPhoneMessages(thread).at(-1);
2869
+ return last ? clip(last.text.replace(/\s+/g, " ").trim(), PREVIEW_LIMIT2) : "";
2869
2870
  }
2870
2871
  function repoName2(repoPath) {
2871
2872
  return repoPath.replace(/\/$/, "").split("/").pop() || repoPath;
@@ -3215,7 +3216,8 @@ function emitChatTurn(opts, chatId, threadId) {
3215
3216
  const pending = latestPendingPlanQuestions({
3216
3217
  messages: thread.messages,
3217
3218
  agentBlock: thread.agentBlock,
3218
- dismissedQuestionSignature: thread.dismissedQuestionSignature
3219
+ dismissedQuestionSignature: thread.dismissedQuestionSignature,
3220
+ status: thread.status
3219
3221
  });
3220
3222
  if (pending && result.taskState !== "failed" && result.taskState !== "canceled" && (result.taskState === "input-required" || thread.agentBlock?.source === "ask_user")) {
3221
3223
  emitControl(opts, {
@@ -3575,7 +3577,8 @@ function republishPendingAsk(opts, chatId) {
3575
3577
  const pending = latestPendingPlanQuestions({
3576
3578
  messages: thread.messages,
3577
3579
  agentBlock: thread.agentBlock,
3578
- dismissedQuestionSignature: thread.dismissedQuestionSignature
3580
+ dismissedQuestionSignature: thread.dismissedQuestionSignature,
3581
+ status: thread.status
3579
3582
  });
3580
3583
  if (!pending) return;
3581
3584
  emitControl(opts, {
@@ -5800,7 +5803,8 @@ function runCoordinatorPrompt(opts, body, generation) {
5800
5803
  const pending = latestPendingPlanQuestions({
5801
5804
  messages: thread.messages,
5802
5805
  agentBlock: thread.agentBlock,
5803
- dismissedQuestionSignature: thread.dismissedQuestionSignature
5806
+ dismissedQuestionSignature: thread.dismissedQuestionSignature,
5807
+ status: thread.status
5804
5808
  });
5805
5809
  if (pending && result.taskState !== "failed" && result.taskState !== "canceled" && (result.taskState === "input-required" || thread.agentBlock?.source === "ask_user")) {
5806
5810
  opts.onOutbound({
@@ -6246,7 +6250,15 @@ import { basename as basename2 } from "path";
6246
6250
  import { watch } from "chokidar";
6247
6251
  var PHONE_BOARD_SYNC_MS = 300;
6248
6252
  function chatKey(row2) {
6249
- return [row2.id, row2.title, row2.status, row2.agent, row2.preview].join(" ");
6253
+ return [
6254
+ row2.id,
6255
+ row2.title,
6256
+ row2.status,
6257
+ row2.agent,
6258
+ row2.preview,
6259
+ row2.needsYou ? "1" : "0",
6260
+ row2.blockedReason ?? ""
6261
+ ].join(" ");
6250
6262
  }
6251
6263
  function phoneBoardKey(sidebar) {
6252
6264
  const orchestration = sidebar.orchestration.map(chatKey).join("\n");
@@ -8905,7 +8917,7 @@ async function startHeadlessHost(opts) {
8905
8917
  };
8906
8918
  const refreshRunning = async () => {
8907
8919
  try {
8908
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-XFE3U3RP.js");
8920
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-2CCFGYAA.js");
8909
8921
  agentsRunning = getOrchestrator2().getRuntime().running;
8910
8922
  } catch {
8911
8923
  agentsRunning = 0;
@@ -10837,7 +10849,7 @@ async function handleJobStop(params, _ctx) {
10837
10849
  return stopDetachedJob(jobCwd(rec), id, reason ? { reason } : void 0);
10838
10850
  }
10839
10851
  async function defaultTurnWait(ref, timeoutMs) {
10840
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-XFE3U3RP.js");
10852
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-2CCFGYAA.js");
10841
10853
  const orch = getOrchestrator2();
10842
10854
  const thread = await orch.waitForTurn(ref, timeoutMs, {
10843
10855
  resolveIfStillRunning: true
@@ -14213,7 +14225,7 @@ async function continueSourceThread(threadId, prompt) {
14213
14225
  await continueOnReply(threadId, prompt);
14214
14226
  return;
14215
14227
  }
14216
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-XFE3U3RP.js");
14228
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-2CCFGYAA.js");
14217
14229
  await getOrchestrator2().send(threadId, prompt);
14218
14230
  } catch {
14219
14231
  }
@@ -14677,6 +14689,7 @@ export {
14677
14689
  archiveRemovedWorkspaceChats,
14678
14690
  archivesWithRemovedWorkspace,
14679
14691
  armSchedules,
14692
+ askBlockStillWaiting,
14680
14693
  assertAbleTimeCredential,
14681
14694
  assertAbleTimeMcpCredential,
14682
14695
  assertOrchestratorCapableAgent,
@@ -15117,6 +15130,7 @@ export {
15117
15130
  lastAgentReply,
15118
15131
  lastAssistantMessageText,
15119
15132
  lastRequestOccupancy,
15133
+ lastTopLevelToolIsAskUser,
15120
15134
  latestPendingPlanQuestions,
15121
15135
  linearAuthorizationHeader,
15122
15136
  linearCycleIsActive,
@@ -2153,6 +2153,16 @@ function isAskUserToolName(name) {
2153
2153
  const base = name.replace(/^mcp__sideboard__/i, "");
2154
2154
  return ASK_USER_TOOL_RE.test(name) || /^ask_user$/i.test(base);
2155
2155
  }
2156
+ function lastTopLevelToolIsAskUser(parts) {
2157
+ if (!parts?.length) return false;
2158
+ for (let i = parts.length - 1; i >= 0; i--) {
2159
+ const part = parts[i];
2160
+ if (part.type === "tool" && !part.parentId) {
2161
+ return isAskUserToolName(part.name);
2162
+ }
2163
+ }
2164
+ return false;
2165
+ }
2156
2166
  function questionsFromToolPart(part) {
2157
2167
  const fromInput = parsePlanQuestionsInput(part.input);
2158
2168
  if (fromInput.length) return fromInput;
@@ -2180,6 +2190,18 @@ function extractPendingPlanQuestions(parts) {
2180
2190
  }
2181
2191
  return null;
2182
2192
  }
2193
+ function askBlockStillWaiting(block, messages) {
2194
+ if (!messages?.length) return Boolean(block?.at);
2195
+ const askedAt = block?.at;
2196
+ if (!askedAt) return false;
2197
+ for (let i = messages.length - 1; i >= 0; i--) {
2198
+ const message = messages[i];
2199
+ if (message.role !== "user" || message.origin === "continue") continue;
2200
+ if (!message.ts) return true;
2201
+ return askedAt > message.ts;
2202
+ }
2203
+ return true;
2204
+ }
2183
2205
  var ASK_USER_TOOL_RE;
2184
2206
  var init_ask_user = __esm({
2185
2207
  "src/plan/ask-user.ts"() {
@@ -2196,14 +2218,7 @@ function needsCoordinatorAction(state) {
2196
2218
  return isIncompleteTaskState(state) || state === "input-required";
2197
2219
  }
2198
2220
  function endedOnAskUser(parts) {
2199
- if (!parts?.length) return false;
2200
- for (let i = parts.length - 1; i >= 0; i--) {
2201
- const p = parts[i];
2202
- if (p.type === "tool" && !p.parentId) {
2203
- return isAskUserToolName(p.name);
2204
- }
2205
- }
2206
- return false;
2221
+ return lastTopLevelToolIsAskUser(parts);
2207
2222
  }
2208
2223
  function deriveTaskState(input) {
2209
2224
  if (input.stillRunning) {
@@ -18696,6 +18711,11 @@ function visibleAgentBlock(thread) {
18696
18711
  const block = thread.agentBlock;
18697
18712
  if (!block?.reason?.trim()) return null;
18698
18713
  if (isDismissedAskUserBlock(block, thread.dismissedQuestionSignature)) return null;
18714
+ if (block.source === "ask_user") {
18715
+ const inFlight = thread.status === "running" || thread.status === "queued";
18716
+ if (inFlight && !block.onScreen) return null;
18717
+ if (!askBlockStillWaiting(block, thread.messages)) return null;
18718
+ }
18699
18719
  return block;
18700
18720
  }
18701
18721
  function worktreeAgentBlock(group) {
@@ -18714,6 +18734,7 @@ function threadCardBlockFields(group) {
18714
18734
  var init_agent_block_view = __esm({
18715
18735
  "src/board/agent-block-view.ts"() {
18716
18736
  "use strict";
18737
+ init_ask_user();
18717
18738
  }
18718
18739
  });
18719
18740
 
@@ -18939,6 +18960,7 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
18939
18960
  const reason = pending ? formatAskUserNotifyMessage(pending.questions) : "Waiting for an answer in that chat.";
18940
18961
  return {
18941
18962
  ...makeAgentBlock("ask_user", reason, at),
18963
+ onScreen: true,
18942
18964
  ...pending ? { questionSignature: pending.signature, questions: pending.questions } : {}
18943
18965
  };
18944
18966
  }
@@ -18996,6 +19018,38 @@ function dismissAskUserQuestion(threadId, signature) {
18996
19018
  ...clearBlock ? { agentBlock: null } : {}
18997
19019
  });
18998
19020
  }
19021
+ function askBlocksEqual(a, b) {
19022
+ if (a === b) return true;
19023
+ if (!a || !b) return false;
19024
+ return a.source === b.source && a.reason === b.reason && a.at === b.at && a.onScreen === b.onScreen && a.questionSignature === b.questionSignature;
19025
+ }
19026
+ function askBlockAfterLiveParts(existing, parts) {
19027
+ const last = lastTopLevelTool(parts);
19028
+ if (last?.type === "tool" && isAskUserToolName(last.name)) {
19029
+ if (existing?.source === "ask_user" && existing.onScreen) return existing;
19030
+ const pending = extractPendingPlanQuestions(parts);
19031
+ const questions = pending?.questions ?? existing?.questions;
19032
+ if (!questions?.length) {
19033
+ return existing?.source === "ask_user" ? { ...existing, onScreen: true } : existing ?? null;
19034
+ }
19035
+ const at = existing?.source === "ask_user" ? existing.at : void 0;
19036
+ return {
19037
+ ...makeAgentBlock("ask_user", formatAskUserNotifyMessage(questions), at),
19038
+ onScreen: true,
19039
+ questionSignature: pending?.signature ?? existing?.questionSignature,
19040
+ questions
19041
+ };
19042
+ }
19043
+ if (last && existing?.source === "ask_user") return null;
19044
+ return existing ?? null;
19045
+ }
19046
+ function syncAskUserBlockFromLive(threadId, parts) {
19047
+ const thread = readThread(threadId);
19048
+ if (!thread || thread.status === "archived") return;
19049
+ const next = askBlockAfterLiveParts(thread.agentBlock, parts);
19050
+ if (askBlocksEqual(thread.agentBlock, next)) return;
19051
+ updateThread(threadId, { agentBlock: next });
19052
+ }
18999
19053
  function writeAgentBlock(threadId, block) {
19000
19054
  const thread = readThread(threadId);
19001
19055
  if (!thread || thread.status === "archived") return;
@@ -22366,6 +22420,7 @@ function noteTurnLiveEvent(threadId, event) {
22366
22420
  const prev = buffers.get(threadId) ?? { parts: [], timer: null };
22367
22421
  prev.parts = trimParts(applyAgentEvent(prev.parts, event));
22368
22422
  buffers.set(threadId, prev);
22423
+ syncAskUserBlockFromLive(threadId, prev.parts);
22369
22424
  if (event.type === "exit") {
22370
22425
  flush(threadId);
22371
22426
  const cur = buffers.get(threadId);
@@ -22419,6 +22474,7 @@ var init_turn_live = __esm({
22419
22474
  import_node_fs55 = require("fs");
22420
22475
  init_message_parts();
22421
22476
  init_paths();
22477
+ init_agent_block();
22422
22478
  buffers = /* @__PURE__ */ new Map();
22423
22479
  FLUSH_MS = 800;
22424
22480
  MAX_PARTS = 80;
@@ -56,7 +56,7 @@ import {
56
56
  updateSchedule,
57
57
  workspaceTagTargetRef,
58
58
  writeAgentBlock
59
- } from "../chunk-JXOW5JAW.js";
59
+ } from "../chunk-7ORMOP3D.js";
60
60
  import "../chunk-LX5R5JOR.js";
61
61
  import {
62
62
  commentAbleTimeTask,
@@ -114,7 +114,7 @@ import {
114
114
  waitForDetachedJob,
115
115
  waitForTurnToolResult,
116
116
  workspaceAgentChatSummaries
117
- } from "../chunk-AILQRQ26.js";
117
+ } from "../chunk-ZW7RSQHY.js";
118
118
  import {
119
119
  HUGE_TOOL_RESULT_SUMMARY,
120
120
  clipToolResultForStore,
@@ -9,11 +9,11 @@ import {
9
9
  resolveSendFollowUp,
10
10
  startOrchestration,
11
11
  waitForPidExit
12
- } from "./chunk-IT6A4FZF.js";
12
+ } from "./chunk-2ER7DQJP.js";
13
13
  import "./chunk-PGPSIEMW.js";
14
14
  import "./chunk-4YBQBVYL.js";
15
15
  import "./chunk-VEVFHO6K.js";
16
- import "./chunk-VBVSJUM2.js";
16
+ import "./chunk-QC2TQMPJ.js";
17
17
  import "./chunk-7Q327QF2.js";
18
18
  import "./chunk-7H655NEW.js";
19
19
  import "./chunk-WRZRX4Q7.js";
@@ -11,7 +11,7 @@ import {
11
11
  resolveSendFollowUp,
12
12
  startOrchestration,
13
13
  waitForPidExit
14
- } from "./chunk-JXOW5JAW.js";
14
+ } from "./chunk-7ORMOP3D.js";
15
15
  import "./chunk-LX5R5JOR.js";
16
16
  import "./chunk-62ESCTJ4.js";
17
17
  import "./chunk-4GK32AYX.js";
@@ -21,7 +21,7 @@ import "./chunk-EGTCXNQM.js";
21
21
  import "./chunk-42JGPPVS.js";
22
22
  import "./chunk-PXMLMBMI.js";
23
23
  import "./chunk-2GPQZZLY.js";
24
- import "./chunk-AILQRQ26.js";
24
+ import "./chunk-ZW7RSQHY.js";
25
25
  import "./chunk-I5TESHDN.js";
26
26
  import "./chunk-X3FSWWW2.js";
27
27
  import "./chunk-DLGGLV2M.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sideboard-ai/core",
3
- "version": "0.1.310",
3
+ "version": "0.1.311",
4
4
  "description": "Sideboard core — orchestration, agents, git worktrees, MCP server",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",