@adhdev/daemon-standalone 1.0.58-rc.53 → 1.0.58-rc.54

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
@@ -36911,10 +36911,10 @@ var require_dist3 = __commonJS({
36911
36911
  }
36912
36912
  function getDaemonBuildInfo() {
36913
36913
  if (cached2) return cached2;
36914
- const commit = readInjected(true ? "7335576b38c7efe574df77aa232271dca8221f88" : void 0) ?? "unknown";
36915
- const commitShort = readInjected(true ? "7335576b" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
36916
- const version2 = readInjected(true ? "1.0.58-rc.53" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
36917
- const builtAt = readInjected(true ? "2026-08-30T19:29:33.228Z" : void 0);
36914
+ const commit = readInjected(true ? "c269ba93419ec36106d4f3d3d63068b2362fe92b" : void 0) ?? "unknown";
36915
+ const commitShort = readInjected(true ? "c269ba93" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
36916
+ const version2 = readInjected(true ? "1.0.58-rc.54" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
36917
+ const builtAt = readInjected(true ? "2026-08-31T06:34:22.633Z" : void 0);
36918
36918
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
36919
36919
  return cached2;
36920
36920
  }
@@ -124036,6 +124036,10 @@ ${text}` : text;
124036
124036
  }
124037
124037
  }
124038
124038
  await this.assertFocusedClaudeTuiReview(prompt, allowsFreeform);
124039
+ if (!this.activeInteractivePrompt) return;
124040
+ if (this.activeInteractivePrompt.promptId !== prompt.promptId) {
124041
+ throw new Error("Claude TUI active interactive prompt changed before review submission");
124042
+ }
124039
124043
  this.driver.dispatch({ kind: "pty_write", data: "\r" });
124040
124044
  await new Promise((resolve32) => setTimeout(resolve32, 180));
124041
124045
  } else {
@@ -124591,27 +124595,101 @@ ${text}` : text;
124591
124595
  * When the held question text is absent for
124592
124596
  * INTERACTIVE_PROMPT_LOST_GRACE_MS the prompt is genuinely resolved.
124593
124597
  */
124594
- maybeClearResolvedClaudeTuiPrompt() {
124595
- if (this.interactivePromptScheme() !== "claude_tui" || !this.activeInteractivePrompt) return;
124596
- let screenText = "";
124597
- try {
124598
- screenText = this.driver.snapshot();
124599
- } catch {
124600
- return;
124598
+ maybeClearResolvedClaudeTuiPrompt(options = {}) {
124599
+ if (this.interactivePromptScheme() !== "claude_tui" || !this.activeInteractivePrompt) return "unavailable";
124600
+ let screenText = options.screenText;
124601
+ if (screenText === void 0) {
124602
+ try {
124603
+ screenText = this.driver.snapshot();
124604
+ } catch {
124605
+ return "unavailable";
124606
+ }
124601
124607
  }
124602
124608
  const identifiableQuestions = this.activeInteractivePrompt.questions.filter((q) => !!q.question?.trim());
124603
124609
  const stillOnScreen = identifiableQuestions.length > 0 ? identifiableQuestions.some((q) => this.claudeTuiQuestionTextAppears(q, screenText)) : screenText.includes("Enter to select");
124604
124610
  if (stillOnScreen) {
124605
124611
  this.interactivePromptLostAt = null;
124606
- return;
124612
+ return "held";
124607
124613
  }
124614
+ const resolvedByBusyAdvance = options.resolveImmediatelyWhenBusy === true && this.latestState?.status === "generating";
124615
+ const resolvedByBoundToolResult = options.resolvedByBoundToolResult === true;
124608
124616
  const lostAt = this.interactivePromptLostAt ?? Date.now();
124609
- if (this.interactivePromptLostAt === null) this.interactivePromptLostAt = lostAt;
124610
- if (Date.now() - lostAt < _SpecCliAdapter.INTERACTIVE_PROMPT_LOST_GRACE_MS) return;
124617
+ if (this.interactivePromptLostAt == null) this.interactivePromptLostAt = lostAt;
124618
+ if (!resolvedByBusyAdvance && !resolvedByBoundToolResult && Date.now() - lostAt < _SpecCliAdapter.INTERACTIVE_PROMPT_LOST_GRACE_MS) return "missing";
124611
124619
  this.activeInteractivePrompt = null;
124612
124620
  this.interactivePromptTransport = null;
124613
124621
  this.interactivePromptLostAt = null;
124614
124622
  this.statusCallback?.();
124623
+ return "cleared";
124624
+ }
124625
+ /**
124626
+ * True only when the native Claude JSONL contains a tool_result for the
124627
+ * AskUserQuestion bound to `prompt`. TUI-captured prompts use a stable
124628
+ * content-derived id rather than Claude's tool_use id, so bind the native
124629
+ * call by its exact question/header/option identity first (ignoring only
124630
+ * Claude's synthetic freeform/chat rows) and only then accept its matching
124631
+ * tool_use_id. A later identical unresolved call resets the result, keeping
124632
+ * latest-call-wins semantics.
124633
+ */
124634
+ hasBoundClaudeAskUserQuestionToolResult(prompt) {
124635
+ if (this.cliType !== "claude-cli" || this.spec.native_history?.source?.kind !== "jsonl") return false;
124636
+ try {
124637
+ const history = executeNativeHistory(this.spec.native_history, {
124638
+ agentType: this.cliType,
124639
+ providerSessionId: this.providerSessionId,
124640
+ sessionStartedAtMs: this.spawnedAtMs,
124641
+ envOverrides: this.spawnedEnv,
124642
+ workspace: this.workingDir,
124643
+ instanceId: this.owningSessionId
124644
+ });
124645
+ if (!history?.sourcePath) return false;
124646
+ let boundToolUseId = null;
124647
+ let resolved = false;
124648
+ for (const record2 of readJsonlLines(history.sourcePath)) {
124649
+ const observedPrompt = detectClaudeAskUserQuestionPromptFromJson(record2, this.cliType);
124650
+ if (observedPrompt && (observedPrompt.promptId === prompt.promptId || this.claudeAskUserQuestionPromptsMatch(prompt, observedPrompt))) {
124651
+ boundToolUseId = observedPrompt.promptId;
124652
+ resolved = false;
124653
+ }
124654
+ if (!boundToolUseId) continue;
124655
+ if (this.readClaudeToolResultIds(record2).includes(boundToolUseId)) resolved = true;
124656
+ }
124657
+ return resolved;
124658
+ } catch {
124659
+ return false;
124660
+ }
124661
+ }
124662
+ claudeAskUserQuestionPromptsMatch(expected, observed) {
124663
+ if (expected.questions.length !== observed.questions.length) return false;
124664
+ return expected.questions.every((expectedQuestion, index) => {
124665
+ const observedQuestion = observed.questions[index];
124666
+ if (!observedQuestion || this.normalizeClaudeTuiIdentity(expectedQuestion.question) !== this.normalizeClaudeTuiIdentity(observedQuestion.question)) return false;
124667
+ const observedHeader = this.normalizeClaudeTuiIdentity(observedQuestion.header || "");
124668
+ if (observedHeader && this.normalizeClaudeTuiIdentity(expectedQuestion.header || "") !== observedHeader) return false;
124669
+ const expectedLabels = expectedQuestion.options.map((option) => this.normalizeClaudeTuiIdentity(option.label)).filter((label) => !/^(?:Type something\.?|Chat about this)$/i.test(label));
124670
+ const observedLabels = observedQuestion.options.map((option) => this.normalizeClaudeTuiIdentity(option.label));
124671
+ return expectedLabels.length === observedLabels.length && expectedLabels.every((label, optionIndex) => label === observedLabels[optionIndex]);
124672
+ });
124673
+ }
124674
+ readClaudeToolResultIds(value) {
124675
+ if (!value || typeof value !== "object") return [];
124676
+ const record2 = value;
124677
+ const blocks = [];
124678
+ if (Array.isArray(record2.content)) blocks.push(...record2.content);
124679
+ const message = record2.message;
124680
+ if (message && typeof message === "object" && Array.isArray(message.content)) {
124681
+ blocks.push(...message.content);
124682
+ }
124683
+ if (record2.type === "tool_result") blocks.push(record2);
124684
+ const ids = [];
124685
+ for (const block2 of blocks) {
124686
+ if (!block2 || typeof block2 !== "object") continue;
124687
+ const candidate = block2;
124688
+ if (candidate.type !== "tool_result") continue;
124689
+ const id = typeof candidate.tool_use_id === "string" ? candidate.tool_use_id.trim() : "";
124690
+ if (id) ids.push(id);
124691
+ }
124692
+ return ids;
124615
124693
  }
124616
124694
  maybeCaptureClaudeTuiPrompt() {
124617
124695
  if (this.interactivePromptScheme() !== "claude_tui" || this.activeInteractivePrompt || this.claudeTuiPromptCaptureInFlight) return;
@@ -124747,19 +124825,51 @@ ${text}` : text;
124747
124825
  * the user selects a standard option. The wider budget accounts for this
124748
124826
  * extra layout time when validating the review echo screen.
124749
124827
  */
124750
- async snapshotSettledClaudeTuiReview(allowsFreeform) {
124828
+ async snapshotSettledClaudeTuiReview(prompt, allowsFreeform) {
124751
124829
  let screenText = this.readClaudeTuiSnapshotForAnswer();
124752
124830
  const budgetMs = allowsFreeform ? _SpecCliAdapter.CLAUDE_TUI_REVIEW_SETTLE_TIMEOUT_MS : _SpecCliAdapter.CLAUDE_TUI_PAGE_SETTLE_TIMEOUT_MS;
124753
124831
  const deadline = Date.now() + budgetMs;
124754
- while (Date.now() < deadline) {
124755
- if (!readFocusedClaudeTuiQuestion(screenText) && isClaudeTuiReviewScreen(screenText)) return screenText;
124832
+ let poll = 0;
124833
+ while (true) {
124834
+ poll += 1;
124835
+ const focused = readFocusedClaudeTuiQuestion(screenText);
124836
+ const review = !focused && isClaudeTuiReviewScreen(screenText);
124837
+ let classification;
124838
+ let directSubmitted = false;
124839
+ if (focused) {
124840
+ const boundQuestion = prompt.questions.some((question) => this.claudeTuiQuestionMatches(question, focused));
124841
+ classification = boundQuestion ? "bound_question" : "foreign_question";
124842
+ } else if (review) {
124843
+ classification = "review";
124844
+ } else if (!this.activeInteractivePrompt) {
124845
+ classification = "direct_submit_already_cleared";
124846
+ directSubmitted = true;
124847
+ } else if (this.activeInteractivePrompt.promptId !== prompt.promptId) {
124848
+ classification = "active_prompt_changed";
124849
+ } else {
124850
+ const resolvedByBoundToolResult = this.hasBoundClaudeAskUserQuestionToolResult(prompt);
124851
+ const resolution = this.maybeClearResolvedClaudeTuiPrompt({
124852
+ screenText,
124853
+ resolveImmediatelyWhenBusy: true,
124854
+ resolvedByBoundToolResult
124855
+ });
124856
+ classification = resolution === "cleared" ? resolvedByBoundToolResult ? "direct_submit_tool_result" : "direct_submit_busy" : resolution === "held" ? "bound_question_unparsed" : resolution === "missing" ? "bound_question_missing" : "snapshot_unavailable";
124857
+ directSubmitted = resolution === "cleared";
124858
+ }
124859
+ LOG2.debug(
124860
+ "SpecAdapter",
124861
+ `[${this.cliType}] Claude TUI answer poll=${poll} classification=${classification} screenBytes=${Buffer.byteLength(screenText, "utf8")} providerState=${this.latestState?.id ?? "unknown"} providerStatus=${this.latestState?.status ?? "unknown"} allowsFreeform=${allowsFreeform}`
124862
+ );
124863
+ if (review) return screenText;
124864
+ if (directSubmitted) return null;
124865
+ if (Date.now() >= deadline) return screenText;
124756
124866
  await new Promise((resolve32) => setTimeout(resolve32, _SpecCliAdapter.CLAUDE_TUI_PAGE_POLL_INTERVAL_MS));
124757
124867
  screenText = this.readClaudeTuiSnapshotForAnswer();
124758
124868
  }
124759
- return screenText;
124760
124869
  }
124761
124870
  async assertFocusedClaudeTuiReview(prompt, allowsFreeform) {
124762
- const screenText = await this.snapshotSettledClaudeTuiReview(allowsFreeform);
124871
+ const screenText = await this.snapshotSettledClaudeTuiReview(prompt, allowsFreeform);
124872
+ if (screenText === null) return;
124763
124873
  const focused = readFocusedClaudeTuiQuestion(screenText);
124764
124874
  if (focused || !isClaudeTuiReviewScreen(screenText)) {
124765
124875
  const observed = focused?.question ? `; focused question is "${focused.question}"` : "";