@adhdev/daemon-standalone 1.0.58-rc.53 → 1.0.58-rc.55
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 +148 -20
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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 ? "
|
|
36915
|
-
const commitShort = readInjected(true ? "
|
|
36916
|
-
const version2 = readInjected(true ? "1.0.58-rc.
|
|
36917
|
-
const builtAt = readInjected(true ? "2026-08-
|
|
36914
|
+
const commit = readInjected(true ? "f6e2e8552cb27f341450b69d2f6c5c0bdc511003" : void 0) ?? "unknown";
|
|
36915
|
+
const commitShort = readInjected(true ? "f6e2e855" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
36916
|
+
const version2 = readInjected(true ? "1.0.58-rc.55" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
36917
|
+
const builtAt = readInjected(true ? "2026-08-31T13:05:59.798Z" : void 0);
|
|
36918
36918
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
36919
36919
|
return cached2;
|
|
36920
36920
|
}
|
|
@@ -48823,8 +48823,26 @@ ${blocks.join("\n\n")}`;
|
|
|
48823
48823
|
{
|
|
48824
48824
|
providerType: "antigravity-cli",
|
|
48825
48825
|
imports: [
|
|
48826
|
+
// Security.framework resolves the default keychain through HOME.
|
|
48827
|
+
// Keep the worker-private HOME while linking macOS's keychain
|
|
48828
|
+
// directory back to the real home. This stays optional and
|
|
48829
|
+
// platform-agnostic: hosts without this path use the generic
|
|
48830
|
+
// missing-import skip contract below.
|
|
48831
|
+
{ relativePath: path222.join("Library", "Keychains"), mode: "symlink" },
|
|
48826
48832
|
{ relativePath: path222.join(".gemini", "antigravity-cli", "antigravity-oauth-token"), mode: "symlink", required: true, requireOwnerOnly: true },
|
|
48827
48833
|
{ relativePath: path222.join(".gemini", "antigravity-cli", "settings.json"), mode: "symlink", requireOwnerOnly: true },
|
|
48834
|
+
// First-run onboarding completion — COPIED, never symlinked. Without
|
|
48835
|
+
// it the CLI opens its colour-scheme picker and then the Terms of
|
|
48836
|
+
// Service screen inside the worker PTY, where nobody is there to
|
|
48837
|
+
// answer: the session sits in `starting` making zero model calls
|
|
48838
|
+
// until it is reaped. Private HOMEs are keyed per TASK, so every
|
|
48839
|
+
// task would re-onboard without this.
|
|
48840
|
+
// Copy rather than symlink because the worker has no reason to
|
|
48841
|
+
// rewrite it, and a symlink would let a worker's write land in the
|
|
48842
|
+
// real user config. Not `required`: a host that has never run agy
|
|
48843
|
+
// (or any non-mac host laid out differently) must still launch, and
|
|
48844
|
+
// the generic missing-import skip contract covers it.
|
|
48845
|
+
{ relativePath: path222.join(".gemini", "antigravity-cli", "cache", "onboarding.json"), mode: "copy" },
|
|
48828
48846
|
// Transcript surfaces — linked THROUGH so the daemon's
|
|
48829
48847
|
// os.homedir()-rooted reader still finds what the worker writes.
|
|
48830
48848
|
// Not `required`: a fresh machine may not have them yet, and the
|
|
@@ -123940,7 +123958,7 @@ ${text}` : text;
|
|
|
123940
123958
|
LOG2.warn("SpecAdapter", `[${this.cliType}] send_keys refused (actionable_modal): keys=${encoded.keys.join(",")} \u2014 use mesh_approve`);
|
|
123941
123959
|
return { ok: false, refused: "actionable_modal", keys: encoded.keys, hasDestructive: encoded.hasDestructive };
|
|
123942
123960
|
}
|
|
123943
|
-
if (this.latestState?.status === "generating") {
|
|
123961
|
+
if (this.latestState?.status === "generating" && !encoded.hasDestructive) {
|
|
123944
123962
|
const message = "session is generating; mesh_send_keys cannot write during an active turn. Use mesh_send_task with delivery_mode: 'interrupt' to interrupt it.";
|
|
123945
123963
|
LOG2.warn("SpecAdapter", `[${this.cliType}] send_keys refused (generating): keys=${encoded.keys.join(",")} \u2014 use mesh_send_task delivery_mode=interrupt`);
|
|
123946
123964
|
return { ok: false, refused: "generating", keys: encoded.keys, hasDestructive: encoded.hasDestructive, message };
|
|
@@ -124036,6 +124054,10 @@ ${text}` : text;
|
|
|
124036
124054
|
}
|
|
124037
124055
|
}
|
|
124038
124056
|
await this.assertFocusedClaudeTuiReview(prompt, allowsFreeform);
|
|
124057
|
+
if (!this.activeInteractivePrompt) return;
|
|
124058
|
+
if (this.activeInteractivePrompt.promptId !== prompt.promptId) {
|
|
124059
|
+
throw new Error("Claude TUI active interactive prompt changed before review submission");
|
|
124060
|
+
}
|
|
124039
124061
|
this.driver.dispatch({ kind: "pty_write", data: "\r" });
|
|
124040
124062
|
await new Promise((resolve32) => setTimeout(resolve32, 180));
|
|
124041
124063
|
} else {
|
|
@@ -124591,27 +124613,101 @@ ${text}` : text;
|
|
|
124591
124613
|
* When the held question text is absent for
|
|
124592
124614
|
* INTERACTIVE_PROMPT_LOST_GRACE_MS the prompt is genuinely resolved.
|
|
124593
124615
|
*/
|
|
124594
|
-
maybeClearResolvedClaudeTuiPrompt() {
|
|
124595
|
-
if (this.interactivePromptScheme() !== "claude_tui" || !this.activeInteractivePrompt) return;
|
|
124596
|
-
let screenText =
|
|
124597
|
-
|
|
124598
|
-
|
|
124599
|
-
|
|
124600
|
-
|
|
124616
|
+
maybeClearResolvedClaudeTuiPrompt(options = {}) {
|
|
124617
|
+
if (this.interactivePromptScheme() !== "claude_tui" || !this.activeInteractivePrompt) return "unavailable";
|
|
124618
|
+
let screenText = options.screenText;
|
|
124619
|
+
if (screenText === void 0) {
|
|
124620
|
+
try {
|
|
124621
|
+
screenText = this.driver.snapshot();
|
|
124622
|
+
} catch {
|
|
124623
|
+
return "unavailable";
|
|
124624
|
+
}
|
|
124601
124625
|
}
|
|
124602
124626
|
const identifiableQuestions = this.activeInteractivePrompt.questions.filter((q) => !!q.question?.trim());
|
|
124603
124627
|
const stillOnScreen = identifiableQuestions.length > 0 ? identifiableQuestions.some((q) => this.claudeTuiQuestionTextAppears(q, screenText)) : screenText.includes("Enter to select");
|
|
124604
124628
|
if (stillOnScreen) {
|
|
124605
124629
|
this.interactivePromptLostAt = null;
|
|
124606
|
-
return;
|
|
124630
|
+
return "held";
|
|
124607
124631
|
}
|
|
124632
|
+
const resolvedByBusyAdvance = options.resolveImmediatelyWhenBusy === true && this.latestState?.status === "generating";
|
|
124633
|
+
const resolvedByBoundToolResult = options.resolvedByBoundToolResult === true;
|
|
124608
124634
|
const lostAt = this.interactivePromptLostAt ?? Date.now();
|
|
124609
|
-
if (this.interactivePromptLostAt
|
|
124610
|
-
if (Date.now() - lostAt < _SpecCliAdapter.INTERACTIVE_PROMPT_LOST_GRACE_MS) return;
|
|
124635
|
+
if (this.interactivePromptLostAt == null) this.interactivePromptLostAt = lostAt;
|
|
124636
|
+
if (!resolvedByBusyAdvance && !resolvedByBoundToolResult && Date.now() - lostAt < _SpecCliAdapter.INTERACTIVE_PROMPT_LOST_GRACE_MS) return "missing";
|
|
124611
124637
|
this.activeInteractivePrompt = null;
|
|
124612
124638
|
this.interactivePromptTransport = null;
|
|
124613
124639
|
this.interactivePromptLostAt = null;
|
|
124614
124640
|
this.statusCallback?.();
|
|
124641
|
+
return "cleared";
|
|
124642
|
+
}
|
|
124643
|
+
/**
|
|
124644
|
+
* True only when the native Claude JSONL contains a tool_result for the
|
|
124645
|
+
* AskUserQuestion bound to `prompt`. TUI-captured prompts use a stable
|
|
124646
|
+
* content-derived id rather than Claude's tool_use id, so bind the native
|
|
124647
|
+
* call by its exact question/header/option identity first (ignoring only
|
|
124648
|
+
* Claude's synthetic freeform/chat rows) and only then accept its matching
|
|
124649
|
+
* tool_use_id. A later identical unresolved call resets the result, keeping
|
|
124650
|
+
* latest-call-wins semantics.
|
|
124651
|
+
*/
|
|
124652
|
+
hasBoundClaudeAskUserQuestionToolResult(prompt) {
|
|
124653
|
+
if (this.cliType !== "claude-cli" || this.spec.native_history?.source?.kind !== "jsonl") return false;
|
|
124654
|
+
try {
|
|
124655
|
+
const history = executeNativeHistory(this.spec.native_history, {
|
|
124656
|
+
agentType: this.cliType,
|
|
124657
|
+
providerSessionId: this.providerSessionId,
|
|
124658
|
+
sessionStartedAtMs: this.spawnedAtMs,
|
|
124659
|
+
envOverrides: this.spawnedEnv,
|
|
124660
|
+
workspace: this.workingDir,
|
|
124661
|
+
instanceId: this.owningSessionId
|
|
124662
|
+
});
|
|
124663
|
+
if (!history?.sourcePath) return false;
|
|
124664
|
+
let boundToolUseId = null;
|
|
124665
|
+
let resolved = false;
|
|
124666
|
+
for (const record2 of readJsonlLines(history.sourcePath)) {
|
|
124667
|
+
const observedPrompt = detectClaudeAskUserQuestionPromptFromJson(record2, this.cliType);
|
|
124668
|
+
if (observedPrompt && (observedPrompt.promptId === prompt.promptId || this.claudeAskUserQuestionPromptsMatch(prompt, observedPrompt))) {
|
|
124669
|
+
boundToolUseId = observedPrompt.promptId;
|
|
124670
|
+
resolved = false;
|
|
124671
|
+
}
|
|
124672
|
+
if (!boundToolUseId) continue;
|
|
124673
|
+
if (this.readClaudeToolResultIds(record2).includes(boundToolUseId)) resolved = true;
|
|
124674
|
+
}
|
|
124675
|
+
return resolved;
|
|
124676
|
+
} catch {
|
|
124677
|
+
return false;
|
|
124678
|
+
}
|
|
124679
|
+
}
|
|
124680
|
+
claudeAskUserQuestionPromptsMatch(expected, observed) {
|
|
124681
|
+
if (expected.questions.length !== observed.questions.length) return false;
|
|
124682
|
+
return expected.questions.every((expectedQuestion, index) => {
|
|
124683
|
+
const observedQuestion = observed.questions[index];
|
|
124684
|
+
if (!observedQuestion || this.normalizeClaudeTuiIdentity(expectedQuestion.question) !== this.normalizeClaudeTuiIdentity(observedQuestion.question)) return false;
|
|
124685
|
+
const observedHeader = this.normalizeClaudeTuiIdentity(observedQuestion.header || "");
|
|
124686
|
+
if (observedHeader && this.normalizeClaudeTuiIdentity(expectedQuestion.header || "") !== observedHeader) return false;
|
|
124687
|
+
const expectedLabels = expectedQuestion.options.map((option) => this.normalizeClaudeTuiIdentity(option.label)).filter((label) => !/^(?:Type something\.?|Chat about this)$/i.test(label));
|
|
124688
|
+
const observedLabels = observedQuestion.options.map((option) => this.normalizeClaudeTuiIdentity(option.label));
|
|
124689
|
+
return expectedLabels.length === observedLabels.length && expectedLabels.every((label, optionIndex) => label === observedLabels[optionIndex]);
|
|
124690
|
+
});
|
|
124691
|
+
}
|
|
124692
|
+
readClaudeToolResultIds(value) {
|
|
124693
|
+
if (!value || typeof value !== "object") return [];
|
|
124694
|
+
const record2 = value;
|
|
124695
|
+
const blocks = [];
|
|
124696
|
+
if (Array.isArray(record2.content)) blocks.push(...record2.content);
|
|
124697
|
+
const message = record2.message;
|
|
124698
|
+
if (message && typeof message === "object" && Array.isArray(message.content)) {
|
|
124699
|
+
blocks.push(...message.content);
|
|
124700
|
+
}
|
|
124701
|
+
if (record2.type === "tool_result") blocks.push(record2);
|
|
124702
|
+
const ids = [];
|
|
124703
|
+
for (const block2 of blocks) {
|
|
124704
|
+
if (!block2 || typeof block2 !== "object") continue;
|
|
124705
|
+
const candidate = block2;
|
|
124706
|
+
if (candidate.type !== "tool_result") continue;
|
|
124707
|
+
const id = typeof candidate.tool_use_id === "string" ? candidate.tool_use_id.trim() : "";
|
|
124708
|
+
if (id) ids.push(id);
|
|
124709
|
+
}
|
|
124710
|
+
return ids;
|
|
124615
124711
|
}
|
|
124616
124712
|
maybeCaptureClaudeTuiPrompt() {
|
|
124617
124713
|
if (this.interactivePromptScheme() !== "claude_tui" || this.activeInteractivePrompt || this.claudeTuiPromptCaptureInFlight) return;
|
|
@@ -124747,19 +124843,51 @@ ${text}` : text;
|
|
|
124747
124843
|
* the user selects a standard option. The wider budget accounts for this
|
|
124748
124844
|
* extra layout time when validating the review echo screen.
|
|
124749
124845
|
*/
|
|
124750
|
-
async snapshotSettledClaudeTuiReview(allowsFreeform) {
|
|
124846
|
+
async snapshotSettledClaudeTuiReview(prompt, allowsFreeform) {
|
|
124751
124847
|
let screenText = this.readClaudeTuiSnapshotForAnswer();
|
|
124752
124848
|
const budgetMs = allowsFreeform ? _SpecCliAdapter.CLAUDE_TUI_REVIEW_SETTLE_TIMEOUT_MS : _SpecCliAdapter.CLAUDE_TUI_PAGE_SETTLE_TIMEOUT_MS;
|
|
124753
124849
|
const deadline = Date.now() + budgetMs;
|
|
124754
|
-
|
|
124755
|
-
|
|
124850
|
+
let poll = 0;
|
|
124851
|
+
while (true) {
|
|
124852
|
+
poll += 1;
|
|
124853
|
+
const focused = readFocusedClaudeTuiQuestion(screenText);
|
|
124854
|
+
const review = !focused && isClaudeTuiReviewScreen(screenText);
|
|
124855
|
+
let classification;
|
|
124856
|
+
let directSubmitted = false;
|
|
124857
|
+
if (focused) {
|
|
124858
|
+
const boundQuestion = prompt.questions.some((question) => this.claudeTuiQuestionMatches(question, focused));
|
|
124859
|
+
classification = boundQuestion ? "bound_question" : "foreign_question";
|
|
124860
|
+
} else if (review) {
|
|
124861
|
+
classification = "review";
|
|
124862
|
+
} else if (!this.activeInteractivePrompt) {
|
|
124863
|
+
classification = "direct_submit_already_cleared";
|
|
124864
|
+
directSubmitted = true;
|
|
124865
|
+
} else if (this.activeInteractivePrompt.promptId !== prompt.promptId) {
|
|
124866
|
+
classification = "active_prompt_changed";
|
|
124867
|
+
} else {
|
|
124868
|
+
const resolvedByBoundToolResult = this.hasBoundClaudeAskUserQuestionToolResult(prompt);
|
|
124869
|
+
const resolution = this.maybeClearResolvedClaudeTuiPrompt({
|
|
124870
|
+
screenText,
|
|
124871
|
+
resolveImmediatelyWhenBusy: true,
|
|
124872
|
+
resolvedByBoundToolResult
|
|
124873
|
+
});
|
|
124874
|
+
classification = resolution === "cleared" ? resolvedByBoundToolResult ? "direct_submit_tool_result" : "direct_submit_busy" : resolution === "held" ? "bound_question_unparsed" : resolution === "missing" ? "bound_question_missing" : "snapshot_unavailable";
|
|
124875
|
+
directSubmitted = resolution === "cleared";
|
|
124876
|
+
}
|
|
124877
|
+
LOG2.debug(
|
|
124878
|
+
"SpecAdapter",
|
|
124879
|
+
`[${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}`
|
|
124880
|
+
);
|
|
124881
|
+
if (review) return screenText;
|
|
124882
|
+
if (directSubmitted) return null;
|
|
124883
|
+
if (Date.now() >= deadline) return screenText;
|
|
124756
124884
|
await new Promise((resolve32) => setTimeout(resolve32, _SpecCliAdapter.CLAUDE_TUI_PAGE_POLL_INTERVAL_MS));
|
|
124757
124885
|
screenText = this.readClaudeTuiSnapshotForAnswer();
|
|
124758
124886
|
}
|
|
124759
|
-
return screenText;
|
|
124760
124887
|
}
|
|
124761
124888
|
async assertFocusedClaudeTuiReview(prompt, allowsFreeform) {
|
|
124762
|
-
const screenText = await this.snapshotSettledClaudeTuiReview(allowsFreeform);
|
|
124889
|
+
const screenText = await this.snapshotSettledClaudeTuiReview(prompt, allowsFreeform);
|
|
124890
|
+
if (screenText === null) return;
|
|
124763
124891
|
const focused = readFocusedClaudeTuiQuestion(screenText);
|
|
124764
124892
|
if (focused || !isClaudeTuiReviewScreen(screenText)) {
|
|
124765
124893
|
const observed = focused?.question ? `; focused question is "${focused.question}"` : "";
|