@buoy-gg/agent-core 7.0.74 → 7.0.76

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.
@@ -502,7 +502,7 @@
502
502
  {
503
503
  "toolId": "zustand",
504
504
  "title": "Zustand",
505
- "summary": "Reads and writes the app's live Zustand stores: list registered stores with their top-level keys or full state, fetch one store's current state, fetch the real before/after trees for one recorded state change, and setState a store for time-travel/reset. Reach for it when on-screen data disagrees with the API, or when a QA user needs the app put into a specific state. The change TIMELINE (history over time) is better read via get_events sources:['zustand']; this tool is for CURRENT state plus on-demand detail. Everything here works in release builds \u2014 but setState defaults to replace:true, which wipes the store's action functions.",
505
+ "summary": "Reads and writes the app's live Zustand stores (on Vue, its Pinia stores too, named by store id and marked library \"pinia\"): list registered stores with their top-level keys or full state, fetch one store's current state, fetch the real before/after trees for one recorded state change, and setState a store for time-travel/reset. Reach for it when on-screen data disagrees with the API, or when a QA user needs the app put into a specific state. The change TIMELINE (history over time) is better read via get_events sources:['zustand']; this tool is for CURRENT state plus on-demand detail. Everything here works in release builds \u2014 but setState defaults to replace:true, which wipes the store's action functions.",
506
506
  "actions": [
507
507
  {
508
508
  "action": "getSnapshot",
@@ -4447,6 +4447,32 @@
4447
4447
  "dev build (__DEV__ === true)"
4448
4448
  ]
4449
4449
  },
4450
+ {
4451
+ "action": "getComponentSource",
4452
+ "summary": "Find the code file behind a part of the screen, and the parts around it. Pass query (a component name, testID or text from describeScreen) or nativeTag. Use this when someone asks which file or component draws something, instead of guessing a path.",
4453
+ "params": {
4454
+ "type": "object",
4455
+ "properties": {
4456
+ "query": {
4457
+ "type": "string",
4458
+ "description": "A component name, testID or visible text from describeScreen, e.g. 'RequestOptions' or 'Send'."
4459
+ },
4460
+ "nativeTag": {
4461
+ "type": "number",
4462
+ "description": "The exact nativeTag from describeScreen. Wins over query."
4463
+ }
4464
+ },
4465
+ "additionalProperties": false
4466
+ },
4467
+ "effect": "read",
4468
+ "release": "empty",
4469
+ "description": "Returns {found:true, component, owners[], sourceKind?} or {found:false, reason}. component and each owner have {name, source?:{fileName, lineNumber?, columnNumber?}, reason?}; owners run outward, up to six. React gives where each component is USED (the JSX line in its parent's file); with sourceKind \"definition\" (Vue and other DOM frameworks) each fileName is the file the component is DEFINED in, with no line. React 19 may give rawStack (bundle URLs) instead of source: read the file name out of it, and say the line may be off. A part with no file says why in reason (a library component, for example). Read only: nothing on screen moves. Needs a dev build.",
4470
+ "releaseNote": "packages/highlight-updates/src/highlight-updates/utils/componentSource.ts \u2014 React's _debugSource and the debug stack exist only in dev, and Vue sets __file only in dev, so a release build answers {found:false, reason}.",
4471
+ "requires": [
4472
+ "@buoy-gg/highlight-updates installed and registered with <FloatingDevTools>",
4473
+ "dev build (__DEV__ === true)"
4474
+ ]
4475
+ },
4450
4476
  {
4451
4477
  "action": "getRenderDetail",
4452
4478
  "summary": "Fetch one tracked component's full renderHistory and lastRenderCause (including hook-change values), which the synced snapshot omits.",
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.CATALOG_ACTIONS=void 0;const CATALOG_ACTIONS=exports.CATALOG_ACTIONS={"env":["getSnapshot"],"console":["getSnapshot","clearEntries"],"sentry":["getSnapshot","clearEnvelopes"],"jotai":["getSnapshot","listAtoms","getAtomValue","getChangeDetail","setAtom","clearEvents"],"route-events":["getSnapshot","getCurrentRoute","navigate","stackGoBack","stackNavigateToIndex","stackPopToIndex","stackPopToTop","clearEvents"],"debug-borders":["cycleMode","setMode"],"zustand":["getSnapshot","listStores","getStoreState","getChangeDetail","setState","rehydrate","clearEvents"],"redux":["getSnapshot","getState","getActionDetail","dispatch","setState","clearEvents"],"impersonate":["getSnapshot","searchUsers","startImpersonation","stopImpersonation","pauseImpersonation","resumeImpersonation","updateSettings","removeFromHistory","clearHistory"],"query":["listQueries","getQueryData","refetch","invalidate","reset","remove","setQueryData","triggerError","restoreError","triggerLoading","restoreLoading","clearQueryCache","clearMutationCache","setOnline"],"events":["exportEvents","setEnabledSources","clearEvents"],"network":["getSnapshot","getCaptureStatus","getEventBody","setPinned","setSaved","removeSavedRecord","clearSavedRequests","clearPinnedRequests","clearEvents","listOverrideRules","getOverrideRuleBody","debugOverrides","upsertOverrideRule","setOverrideRuleEnabled","setOverridesEnabled","deleteOverrideRule","clearOverrideRules","getNetworkConditions","setNetworkConditions"],"js-top":["sample","getOriginDetail","setEnabled","pause","resume","clear"],"app":["ping","reloadApp"],"time-machine":["list","capture","captureBaseline","wipeAll","restore","preview","inspect","delete","rename","duplicate","setExclusions","setScope","setRestoreRoute"],"clock":["getState","setTime","shift","freeze","resume","setRate","reset","updateSettings","jumpToTokenExpiry","failNextRequest","stopTokenCheck"],"lifecycle":["getState","background","interrupt","returnToApp","memoryWarning","openUrl","pressBack","setColorScheme","setPower","resetPower","relaunch","runRecipe","clearReport","reset"],"location":["getState","setLocation","startRoute","pauseRoute","resumeRoute","stopRoute","seekRoute","setSpeed","enterRegion","exitRegion","setConditions","setSignal","setServices","tune","useRealLocation","reset","updateSettings","clearLog"],"permissions":["getState","setOverride","clearOverride","resetAll","requestReal","updateSettings","simulateReturnFromSettings","clearLog"],"storage":["getSnapshot","getRequiredKeys","async.getAllKeys","async.multiGet","async.getItem","async.setItem","async.removeItem","async.multiRemove","async.multiSet","async.clear","clearAppStorage","getEventDetail","clearEvents","timeTravel.undo","timeTravel.jump","mmkv.snapshot","mmkv.get","mmkv.set","mmkv.remove","secure.keys","secure.snapshot","secure.get","secure.set","secure.delete"],"highlight-updates":["describeScreen","tapElement","waitFor","beginMeasurement","endMeasurement","locateComponent","getRenderDetail","setEnabled","toggle","setSilentTracking","toggleFreeze","setSpotlight","clearRenderCounts","startTouchCapture","stopTouchCapture","clearTouchCapture","readTouchCapture"],"scenarios":["listScenarios","getScenario","save","acceptDraft","discardDraft","preview","run","deactivate","delete","setFolder","listFolders","getActive","export"],"perf-monitor":["setEnabled","startRecording","stopRecording","savePending","discardPending","mark","startAutomation","cancelAutomation","acknowledgeAutomation","refreshIndex","getAutomationConfig","setAutomationConfig","loadReport","deleteReport","deleteBatch","clearAll"],"assets":["list","getDetail","rescan","measureSizes","saveBaseline","clearBaseline","getDiff","clearRecords","getScanStatus"],"tv-remote":["arm","getEventsSince","setMenuCapture","disarm","clear"],"focus-inspector":["rescan","focusElement","setTracking","clearHistory"],"images":["list","getDetail","getCaptureStatus","retry","flash","proveSavings","setOverride","clearOverride","setNetworkMode","setBlankImages","hardReload","evictDisk","massAction","clearRecords","clearExpoCaches"],"ask-buoy":["listChanges","undoChange","undoAll","retrieve","openProcedure"],"push-notifications":["getSnapshot","getCapabilities","getEvent","getPermissions","listPresented","refreshToken","setCaptureSession","clearCapturedEvents","scheduleLocal"],"image-overlay":["getSnapshot","listTargets","selectTarget","loadImage","setSettings","fitToScreen","resetSettings","remove"],"three":["getScene","getStats","action"]};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.CATALOG_ACTIONS=void 0;const CATALOG_ACTIONS=exports.CATALOG_ACTIONS={"env":["getSnapshot"],"console":["getSnapshot","clearEntries"],"sentry":["getSnapshot","clearEnvelopes"],"jotai":["getSnapshot","listAtoms","getAtomValue","getChangeDetail","setAtom","clearEvents"],"route-events":["getSnapshot","getCurrentRoute","navigate","stackGoBack","stackNavigateToIndex","stackPopToIndex","stackPopToTop","clearEvents"],"debug-borders":["cycleMode","setMode"],"zustand":["getSnapshot","listStores","getStoreState","getChangeDetail","setState","rehydrate","clearEvents"],"redux":["getSnapshot","getState","getActionDetail","dispatch","setState","clearEvents"],"impersonate":["getSnapshot","searchUsers","startImpersonation","stopImpersonation","pauseImpersonation","resumeImpersonation","updateSettings","removeFromHistory","clearHistory"],"query":["listQueries","getQueryData","refetch","invalidate","reset","remove","setQueryData","triggerError","restoreError","triggerLoading","restoreLoading","clearQueryCache","clearMutationCache","setOnline"],"events":["exportEvents","setEnabledSources","clearEvents"],"network":["getSnapshot","getCaptureStatus","getEventBody","setPinned","setSaved","removeSavedRecord","clearSavedRequests","clearPinnedRequests","clearEvents","listOverrideRules","getOverrideRuleBody","debugOverrides","upsertOverrideRule","setOverrideRuleEnabled","setOverridesEnabled","deleteOverrideRule","clearOverrideRules","getNetworkConditions","setNetworkConditions"],"js-top":["sample","getOriginDetail","setEnabled","pause","resume","clear"],"app":["ping","reloadApp"],"time-machine":["list","capture","captureBaseline","wipeAll","restore","preview","inspect","delete","rename","duplicate","setExclusions","setScope","setRestoreRoute"],"clock":["getState","setTime","shift","freeze","resume","setRate","reset","updateSettings","jumpToTokenExpiry","failNextRequest","stopTokenCheck"],"lifecycle":["getState","background","interrupt","returnToApp","memoryWarning","openUrl","pressBack","setColorScheme","setPower","resetPower","relaunch","runRecipe","clearReport","reset"],"location":["getState","setLocation","startRoute","pauseRoute","resumeRoute","stopRoute","seekRoute","setSpeed","enterRegion","exitRegion","setConditions","setSignal","setServices","tune","useRealLocation","reset","updateSettings","clearLog"],"permissions":["getState","setOverride","clearOverride","resetAll","requestReal","updateSettings","simulateReturnFromSettings","clearLog"],"storage":["getSnapshot","getRequiredKeys","async.getAllKeys","async.multiGet","async.getItem","async.setItem","async.removeItem","async.multiRemove","async.multiSet","async.clear","clearAppStorage","getEventDetail","clearEvents","timeTravel.undo","timeTravel.jump","mmkv.snapshot","mmkv.get","mmkv.set","mmkv.remove","secure.keys","secure.snapshot","secure.get","secure.set","secure.delete"],"highlight-updates":["describeScreen","tapElement","waitFor","beginMeasurement","endMeasurement","locateComponent","getComponentSource","getRenderDetail","setEnabled","toggle","setSilentTracking","toggleFreeze","setSpotlight","clearRenderCounts","startTouchCapture","stopTouchCapture","clearTouchCapture","readTouchCapture"],"scenarios":["listScenarios","getScenario","save","acceptDraft","discardDraft","preview","run","deactivate","delete","setFolder","listFolders","getActive","export"],"perf-monitor":["setEnabled","startRecording","stopRecording","savePending","discardPending","mark","startAutomation","cancelAutomation","acknowledgeAutomation","refreshIndex","getAutomationConfig","setAutomationConfig","loadReport","deleteReport","deleteBatch","clearAll"],"assets":["list","getDetail","rescan","measureSizes","saveBaseline","clearBaseline","getDiff","clearRecords","getScanStatus"],"tv-remote":["arm","getEventsSince","setMenuCapture","disarm","clear"],"focus-inspector":["rescan","focusElement","setTracking","clearHistory"],"images":["list","getDetail","getCaptureStatus","retry","flash","proveSavings","setOverride","clearOverride","setNetworkMode","setBlankImages","hardReload","evictDisk","massAction","clearRecords","clearExpoCaches"],"ask-buoy":["listChanges","undoChange","undoAll","retrieve","openProcedure"],"push-notifications":["getSnapshot","getCapabilities","getEvent","getPermissions","listPresented","refreshToken","setCaptureSession","clearCapturedEvents","scheduleLocal"],"image-overlay":["getSnapshot","listTargets","selectTarget","loadImage","setSettings","fitToScreen","resetSettings","remove"],"three":["getScene","getStats","action"]};
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ACQUISITION_CALLS=void 0;exports.synthesizeAskBlock=synthesizeAskBlock;exports.synthesizeShortfallBlock=synthesizeShortfallBlock;var _runId=require("../blocks/runId");const nextId=(0,_runId.idFactory)("ask");const OFFER=/\b(?:want me to|would you like me to|would you like|do you want me to|do you want|should i|shall i|ok(?:ay)? if i|say the word|let me know if|if you'?d (?:like|prefer)|if you want)\b/i;const VALUE_ASK=/\b(?:tell me|let me know|just say|say|give me|pick|choose)\s+(?:the|which|what|how|your|one)\b/i;const ASK=new RegExp(`${OFFER.source}|${VALUE_ASK.source}`,"i");const TRAILING_MARKUP=/[*_`"'’”\s]+$/;const LEADING_MARKUP=/^[*_`>\-\s]+/;const SENTENCE_END=/[.!?]["'’”)\]]*\s+(?=[A-Z("'“])|\n+/;const OR_SPLIT=/,?\s+or\s+/i;const PARENTHETICAL=/\(([^()]{3,140})\)/;const LIST_SPLIT=/\s*,\s*|\s+or\s+/i;const CLEAN_LABEL=/^[A-Za-z0-9][^,;:—–]*$/;const CLEAN_OPTION=/^[A-Za-z0-9$][^;:—–()]*$/;const YES_NO=[{id:"yes",label:"Yes, go ahead"},{id:"no",label:"No thanks"}];function synthesizeAskBlock(o){const e=lastSentence(o);if(!e||e.length<8||e.length>240)return null;const t=ASK.exec(e);if(!t)return null;const n=enumerated(e);if(n)return{id:nextId(),kind:"choice",question:e,options:n};const s=e.slice(t.index+t[0].length).replace(/[?.!,]+$/,"").trim();const i=s?s.split(OR_SPLIT):[];if(i.length>2)return null;if(i.length===2){const r=alternatives(i);return r?{id:nextId(),kind:"choice",question:e,options:r}:null}if(VALUE_ASK.test(e)||!OFFER.test(e))return null;return{id:nextId(),kind:"choice",question:e,options:YES_NO}}function lastSentence(o){const e=o.replace(TRAILING_MARKUP,"").trim();if(!e)return null;const t=e.split(SENTENCE_END);const n=t[t.length-1]?.replace(LEADING_MARKUP,"").trim();return n||null}function enumerated(o){const e=PARENTHETICAL.exec(o)?.[1];if(!e||!/\bor\b/i.test(e))return null;const t=e.split(LIST_SPLIT).map(n=>n.trim()).filter(Boolean);if(t.length<2||t.length>5)return null;for(const n of t){if(n.length<1||n.length>48||!CLEAN_OPTION.test(n))return null}return t.map((n,s)=>({id:`o${s+1}`,label:capitalize(n)}))}function alternatives(o){const e=o.map(t=>t.trim().replace(/[?.!]+$/,"").trim());for(const t of e){if(t.length<2||t.length>48||!CLEAN_LABEL.test(t))return null}return e.map((t,n)=>({id:n===0?"a":"b",label:capitalize(t)}))}function capitalize(o){return/^[a-z]/.test(o)?o[0].toUpperCase()+o.slice(1):o}const LIMITED=/\b(?:that'?s (?:all|everything|it)|only|just|so far|nothing else|no others?|the rest (?:are|is)?n'?t)\b/i;const NOT_LOADED=/\b(?:cache[ds]?|cached|loaded|fetched|in memory|visited|opened|rendered|recorded|captured)\b/i;const GO_YOURSELF=/\b(?:if|once|when|after) you (?:visit|open|go to|navigate|browse|load|tap|swipe|scroll|look at)\b/i;const TAIL_SENTENCES=3;const ACQUISITION_CALLS=exports.ACQUISITION_CALLS=new Set(["route-events.navigate","route-events.stackGoBack","route-events.stackNavigateToIndex","highlight-updates.describeScreen","highlight-updates.tapElement","highlight-updates.waitFor","query.refetch","query.invalidate"]);function synthesizeShortfallBlock({text:o,attempted:e}){if(e)return null;const t=lastSentences(o,TAIL_SENTENCES);if(!t)return null;const n=GO_YOURSELF.test(t)||LIMITED.test(t)&&NOT_LOADED.test(t);if(!n)return null;return{id:nextShortfallId(),kind:"actions",actions:[{label:"Go get the rest",primary:true,send:"Don't stop at what's already loaded. Drive the app to get the rest \u2014 check the other layers, use the sitemap to navigate to the screen that loads it, wait for it, then answer in full. If it truly isn't reachable, tell me exactly what you tried."}]}}const nextShortfallId=(0,_runId.idFactory)("gap");function lastSentences(o,e){const t=o.replace(TRAILING_MARKUP,"").trim();if(!t)return null;const n=t.split(SENTENCE_END).filter(i=>i.trim());const s=n.slice(-e).join(" ").replace(LEADING_MARKUP,"").trim();return s||null}
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ACQUISITION_CALLS=void 0;exports.synthesizeAskBlock=synthesizeAskBlock;exports.synthesizeShortfallBlock=synthesizeShortfallBlock;var _runId=require("../blocks/runId");const nextId=(0,_runId.idFactory)("ask");const OFFER=/\b(?:want me to|would you like me to|would you like|do you want me to|do you want|should i|shall i|ok(?:ay)? if i|say the word|let me know if|if you'?d (?:like|prefer)|if you want)\b/i;const VALUE_ASK=/\b(?:tell me|let me know|just say|say|give me|pick|choose)\s+(?:the|which|what|how|your|one)\b/i;const ASK=new RegExp(`${OFFER.source}|${VALUE_ASK.source}`,"i");const TRAILING_MARKUP=/[*_`"'’”\s]+$/;const LEADING_MARKUP=/^[*_`>\-\s]+/;const SENTENCE_END=/[.!?]["'’”)\]]*\s+(?=[A-Z("'“])|\n+/;const OR_SPLIT=/,?\s+or\s+/i;const PARENTHETICAL=/\(([^()]{3,140})\)/;const LIST_SPLIT=/\s*,\s*|\s+or\s+/i;const CLEAN_LABEL=/^[A-Za-z0-9][^,;:—–]*$/;const CLEAN_OPTION=/^[A-Za-z0-9$][^;:—–()]*$/;const YES_NO=[{id:"yes",label:"Yes, go ahead"},{id:"no",label:"No thanks"}];function synthesizeAskBlock(s){const e=lastSentence(s);if(!e||e.length<8||e.length>240)return null;const t=ASK.exec(e);if(!t)return null;const n=enumerated(e);if(n)return{id:nextId(),kind:"choice",question:e,questionInAnswer:true,options:n};const o=e.slice(t.index+t[0].length).replace(/[?.!,]+$/,"").trim();const i=o?o.split(OR_SPLIT):[];if(i.length>2)return null;if(i.length===2){const r=alternatives(i);return r?{id:nextId(),kind:"choice",question:e,questionInAnswer:true,options:r}:null}if(VALUE_ASK.test(e)||!OFFER.test(e))return null;return{id:nextId(),kind:"choice",question:e,questionInAnswer:true,options:YES_NO}}function lastSentence(s){const e=s.replace(TRAILING_MARKUP,"").trim();if(!e)return null;const t=e.split(SENTENCE_END);const n=t[t.length-1]?.replace(LEADING_MARKUP,"").trim();return n||null}function enumerated(s){const e=PARENTHETICAL.exec(s)?.[1];if(!e||!/\bor\b/i.test(e))return null;const t=e.split(LIST_SPLIT).map(n=>n.trim()).filter(Boolean);if(t.length<2||t.length>5)return null;for(const n of t){if(n.length<1||n.length>48||!CLEAN_OPTION.test(n))return null}return t.map((n,o)=>({id:`o${o+1}`,label:capitalize(n)}))}function alternatives(s){const e=s.map(t=>t.trim().replace(/[?.!]+$/,"").trim());for(const t of e){if(t.length<2||t.length>48||!CLEAN_LABEL.test(t))return null}return e.map((t,n)=>({id:n===0?"a":"b",label:capitalize(t)}))}function capitalize(s){return/^[a-z]/.test(s)?s[0].toUpperCase()+s.slice(1):s}const LIMITED=/\b(?:that'?s (?:all|everything|it)|only|just|so far|nothing else|no others?|the rest (?:are|is)?n'?t)\b/i;const NOT_LOADED=/\b(?:cache[ds]?|cached|loaded|fetched|in memory|visited|opened|rendered|recorded|captured)\b/i;const GO_YOURSELF=/\b(?:if|once|when|after) you (?:visit|open|go to|navigate|browse|load|tap|swipe|scroll|look at)\b/i;const TAIL_SENTENCES=3;const ACQUISITION_CALLS=exports.ACQUISITION_CALLS=new Set(["route-events.navigate","route-events.stackGoBack","route-events.stackNavigateToIndex","highlight-updates.describeScreen","highlight-updates.tapElement","highlight-updates.waitFor","query.refetch","query.invalidate"]);function synthesizeShortfallBlock({text:s,attempted:e}){if(e)return null;const t=lastSentences(s,TAIL_SENTENCES);if(!t)return null;const n=GO_YOURSELF.test(t)||LIMITED.test(t)&&NOT_LOADED.test(t);if(!n)return null;return{id:nextShortfallId(),kind:"actions",actions:[{label:"Go get the rest",primary:true,send:"Don't stop at what's already loaded. Drive the app to get the rest \u2014 check the other layers, use the sitemap to navigate to the screen that loads it, wait for it, then answer in full. If it truly isn't reachable, tell me exactly what you tried."}]}}const nextShortfallId=(0,_runId.idFactory)("gap");function lastSentences(s,e){const t=s.replace(TRAILING_MARKUP,"").trim();if(!t)return null;const n=t.split(SENTENCE_END).filter(i=>i.trim());const o=n.slice(-e).join(" ").replace(LEADING_MARKUP,"").trim();return o||null}
@@ -1,13 +1,13 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"digestOf",{enumerable:true,get:function(){return _digest.digestOf}});exports.readTargetDigest=readTargetDigest;exports.runAgentTurn=runAgentTurn;exports.runGatedAction=runGatedAction;var _catalog=require("../catalog/catalog.g");var _validateParams=require("../catalog/validateParams");var _normalizeParams=require("../catalog/normalizeParams");var _toProviderTools=require("../catalog/toProviderTools");var _snapshotReads=require("../catalog/snapshotReads");var _types=require("../providers/types");var _ledger=require("../effects/ledger");var _turnScope=require("../policy/turnScope");var _policy=require("../policy/policy");var _redact=require("../policy/redact");var _idGrounding=require("./idGrounding");var _effectFor=require("./effectFor");var _digest=require("../effects/digest");var _uiTool=require("../blocks/uiTool");var _receipts=require("../blocks/receipts");var _types2=require("../blocks/types");var _askGate=require("./askGate");var _textToolCalls=require("./textToolCalls");var _planOnlyStop=require("./planOnlyStop");var _compactScreen=require("./compactScreen");var _historyBudget=require("./historyBudget");var _tokenCalibration=require("./tokenCalibration");var _evidence=require("./evidence");var _retrieve=require("./retrieve");var _verify=require("./verify");var _realNow=require("../realNow");const MAX_RESULT_CHARS=24e3;const MAX_TRACE_RESULT_CHARS=2e3;const LOOP_REPEATS=3;function callSignature(t){const r=o=>{if(o===null||typeof o!=="object")return o;if(Array.isArray(o))return o.map(r);const d=o;return Object.keys(d).sort().reduce((l,k)=>(l[k]=r(d[k]),l),{})};return t.map(o=>`${o.name}:${JSON.stringify(r(o.input??{}))}`).join("|")}const LOOP_WARNING="[Buoy] You have now made this exact call three times in a row and gotten the same thing back. Repeating it again will not change the answer. Read the result you already have, then either try a different tool or different arguments, or tell the user plainly what you could not get and what you tried.";const DEFAULT_MAX_STEPS=24;const CONTINUE_SEND="Resume where you left off. Don't redo past changes. Read the past tool results first.";const STEP_CAP_WRAP_UP="You are out of steps. No more tools may run. Reply in the user's language with plain words. Name every write that ran, what you found, and what is still not done. Use the tool results as proof. A tap alone does not prove a save or an order worked. Do not claim the job is done if you have not checked it. Keep the reply short.";const DEFAULT_TURN_MS=18e4;const THROTTLE_RETRIES=2;const OVERFLOW_RETRIES=1;const NETWORK_RETRIES=1;const NETWORK_RETRY_MS=1e3;const RETRY_BASE_MS=1e3;const RETRY_JITTER_MS=250;const RETRY_AFTER_CAP_MS=3e4;function sleep(t,r){return new Promise(o=>{if(r?.aborted)return o();const d=(0,_realNow.realSetTimeout)(l,t);function l(){(0,_realNow.realClearTimeout)(d);r?.removeEventListener("abort",l);o()}r?.addEventListener("abort",l,{once:true})})}function readAnswer(t){if(typeof t==="boolean")return{approved:t,trust:false};const r=t.reason?.trim();return{approved:t.approved,...r?{reason:r}:{},trust:t.trust===true&&t.approved}}function declinedResult(t){return t?`The user declined this change and said: "${t}". Do not retry it as proposed; take their note into account and, if a different change would fit, propose that instead.`:"The user declined this change. Do not retry it; ask what they would prefer."}function closeAction(t,r){const o=t.toLowerCase();const d=r.toLowerCase();if(Math.abs(o.length-d.length)>1)return false;let l=0;while(l<o.length&&o[l]===d[l])l++;return o===d||o.slice(l+1)===d.slice(l+1)||o.slice(l+1)===d.slice(l)||o.slice(l)===d.slice(l+1)}function findDescriptor(t,r,o){return t.find(d=>d.toolId===r)?.actions.find(d=>d.action===o)}const URL_PROVENANCE_REJECTION="Rejected: every image URL must be one you read from a tool result in THIS conversation (images.list, a storage value, a response body). Never invent or remember URLs \u2014 read them first, then show them.";const droppedImageNote=t=>` NOTE: ${t} image ${t===1?"URL was":"URLs were"} dropped \u2014 they were not read from a tool result in this conversation, so the card the user is looking at has no picture there. Do not tell them it does; read the URLs and show it again, or say the artwork is missing.`;function fullText(t){try{return JSON.stringify(t??null)}catch{return String(t)}}function encodeResult(t,r){if(t.length<=MAX_RESULT_CHARS)return t;return`${t.slice(0,MAX_RESULT_CHARS)}${(0,_evidence.truncationMarker)(t.length,r)}`}function summarise(t){if(t===null||t===void 0)return"Done";if(Array.isArray(t))return countOf(t.length);if(typeof t==="boolean")return t?"Done":"Failed";if(typeof t==="object"){const r=t;if(r.ok===false)return typeof r.error==="string"?r.error:"Failed";if(r.found===false)return"Not found";if(r.tapped===false)return"Nothing to tap";if(r.active===false&&typeof r.inactiveReason==="string"&&r.inactiveReason.length>0){return"Saved, but inactive in this build"}for(const d of["returned","count","total"]){const l=r[d];if(typeof l==="number")return countOf(l)}const o=Object.values(r).filter(Array.isArray);if(o.length===1)return countOf(o[0].length);return"Done"}return String(t).slice(0,80)}function countOf(t){return t===1?"1 item":`${t} items`}function reportsFailure(t){return typeof t==="object"&&t!==null&&t.ok===false}const EMPTY_TAP_ERROR="tapElement needs nativeTag, testID or query. Read describeScreen and pass one.";function emptyTap(t,r,o){return t==="highlight-updates"&&r==="tapElement"&&![o.nativeTag,o.testID,o.query].some(d=>typeof d==="string"?d.trim().length>0:d!=null)}function tapResult(t,r,o){if(t!=="highlight-updates"||r!=="tapElement"||!o||typeof o!=="object")return o;const d=o;if(d.tapped!==false)return o;return{...d,ok:false,error:typeof d.reason==="string"?d.reason:typeof d.error==="string"?d.error:"Nothing was tapped. Read describeScreen and try again."}}async function*runAgentTurn(t){const{provider:r,catalog:o,system:d,systemVolatile:l,model:k,maxTokens:y,dispatch:u,readSnapshot:m,storeKeyOwners:U,ledger:g,policy:x,isRelease:M,requestApproval:Y,signal:_,evidence:K,trusted:A,procedures:F}=t;const Q=new Map;const O=t.calibration??new _tokenCalibration.TokenCalibration;const ae=[...t.messages].reverse().find(p=>(0,_types.isRealUserMessage)(p));const j=(0,_turnScope.classifyTurn)(ae?.role==="user"?ae.text:"");const f=[...t.messages];const pe=r.protocol==="anthropic"?t.feedOptions??{}:{};const G=pe.freezeHistory===true;const P=pe.notices==="system-msg";const de=(p,E=false)=>({role:"user",text:p,...r.protocol==="anthropic"?{source:"engine"}:{},...E?{systemNotice:true}:{}});const qe=()=>{const p=f[f.length-1];return P&&(p?.role==="tool-results"||p?.role==="user"&&p.systemNotice===true)};const Ue=(0,_idGrounding.idGrounding)(f,`${t.system}
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"digestOf",{enumerable:true,get:function(){return _digest.digestOf}});exports.readTargetDigest=readTargetDigest;exports.runAgentTurn=runAgentTurn;exports.runGatedAction=runGatedAction;var _catalog=require("../catalog/catalog.g");var _validateParams=require("../catalog/validateParams");var _normalizeParams=require("../catalog/normalizeParams");var _toProviderTools=require("../catalog/toProviderTools");var _snapshotReads=require("../catalog/snapshotReads");var _types=require("../providers/types");var _ledger=require("../effects/ledger");var _turnScope=require("../policy/turnScope");var _policy=require("../policy/policy");var _redact=require("../policy/redact");var _idGrounding=require("./idGrounding");var _effectFor=require("./effectFor");var _digest=require("../effects/digest");var _uiTool=require("../blocks/uiTool");var _receipts=require("../blocks/receipts");var _types2=require("../blocks/types");var _askGate=require("./askGate");var _textToolCalls=require("./textToolCalls");var _planOnlyStop=require("./planOnlyStop");var _compactScreen=require("./compactScreen");var _historyBudget=require("./historyBudget");var _tokenCalibration=require("./tokenCalibration");var _evidence=require("./evidence");var _retrieve=require("./retrieve");var _verify=require("./verify");var _realNow=require("../realNow");const MAX_RESULT_CHARS=24e3;const MAX_TRACE_RESULT_CHARS=2e3;const LOOP_REPEATS=3;function callSignature(t){const r=o=>{if(o===null||typeof o!=="object")return o;if(Array.isArray(o))return o.map(r);const d=o;return Object.keys(d).sort().reduce((l,k)=>(l[k]=r(d[k]),l),{})};return t.map(o=>`${o.name}:${JSON.stringify(r(o.input??{}))}`).join("|")}const LOOP_WARNING="[Buoy] You have now made this exact call three times in a row and gotten the same thing back. Repeating it again will not change the answer. Read the result you already have, then either try a different tool or different arguments, or tell the user plainly what you could not get and what you tried.";const DEFAULT_MAX_STEPS=24;const CONTINUE_SEND="Resume where you left off. Don't redo past changes. Read the past tool results first.";const STEP_CAP_WRAP_UP="You are out of steps. No more tools may run. Reply in the user's language with plain words. Name every write that ran, what you found, and what is still not done. Use the tool results as proof. A tap alone does not prove a save or an order worked. Do not claim the job is done if you have not checked it. Keep the reply short.";const DEFAULT_TURN_MS=18e4;const THROTTLE_RETRIES=2;const OVERFLOW_RETRIES=1;const NETWORK_RETRIES=1;const NETWORK_RETRY_MS=1e3;const RETRY_BASE_MS=1e3;const RETRY_JITTER_MS=250;const RETRY_AFTER_CAP_MS=3e4;function sleep(t,r){return new Promise(o=>{if(r?.aborted)return o();const d=(0,_realNow.realSetTimeout)(l,t);function l(){(0,_realNow.realClearTimeout)(d);r?.removeEventListener("abort",l);o()}r?.addEventListener("abort",l,{once:true})})}function readAnswer(t){if(typeof t==="boolean")return{approved:t,trust:false};const r=t.reason?.trim();return{approved:t.approved,...r?{reason:r}:{},trust:t.trust===true&&t.approved}}function declinedResult(t){return t?`The user declined this change and said: "${t}". Do not retry it as proposed; take their note into account and, if a different change would fit, propose that instead.`:"The user declined this change. Do not retry it; ask what they would prefer."}function closeAction(t,r){const o=t.toLowerCase();const d=r.toLowerCase();if(Math.abs(o.length-d.length)>1)return false;let l=0;while(l<o.length&&o[l]===d[l])l++;return o===d||o.slice(l+1)===d.slice(l+1)||o.slice(l+1)===d.slice(l)||o.slice(l)===d.slice(l+1)}function findDescriptor(t,r,o){return t.find(d=>d.toolId===r)?.actions.find(d=>d.action===o)}const URL_PROVENANCE_REJECTION="Rejected: every image URL must be one you read from a tool result in THIS conversation (images.list, a storage value, a response body). Never invent or remember URLs \u2014 read them first, then show them.";const droppedImageNote=t=>` NOTE: ${t} image ${t===1?"URL was":"URLs were"} dropped \u2014 they were not read from a tool result in this conversation, so the card the user is looking at has no picture there. Do not tell them it does; read the URLs and show it again, or say the artwork is missing.`;const NO_DATA_RESULT="Done. This action sends back no data. Read the app's state to see what changed.";const RELOADING_TEXT="The app is reloading.";function fullText(t){if(t===void 0)return NO_DATA_RESULT;try{return JSON.stringify(t??null)}catch{return String(t)}}function encodeResult(t,r){if(t.length<=MAX_RESULT_CHARS)return t;return`${t.slice(0,MAX_RESULT_CHARS)}${(0,_evidence.truncationMarker)(t.length,r)}`}function summarise(t){if(t===null||t===void 0)return"Done";if(Array.isArray(t))return countOf(t.length);if(typeof t==="boolean")return t?"Done":"Failed";if(typeof t==="object"){const r=t;if(r.ok===false)return typeof r.error==="string"?r.error:"Failed";if(r.found===false)return"Not found";if(r.tapped===false)return"Nothing to tap";if(r.active===false&&typeof r.inactiveReason==="string"&&r.inactiveReason.length>0){return"Saved, but inactive in this build"}for(const d of["returned","count","total"]){const l=r[d];if(typeof l==="number")return countOf(l)}const o=Object.values(r).filter(Array.isArray);if(o.length===1)return countOf(o[0].length);return"Done"}return String(t).slice(0,80)}function countOf(t){return t===1?"1 item":`${t} items`}function reportsFailure(t){return typeof t==="object"&&t!==null&&t.ok===false}const EMPTY_TAP_ERROR="tapElement needs nativeTag, testID or query. Read describeScreen and pass one.";function emptyTap(t,r,o){return t==="highlight-updates"&&r==="tapElement"&&![o.nativeTag,o.testID,o.query].some(d=>typeof d==="string"?d.trim().length>0:d!=null)}function tapResult(t,r,o){if(t!=="highlight-updates"||r!=="tapElement"||!o||typeof o!=="object")return o;const d=o;if(d.tapped!==false)return o;return{...d,ok:false,error:typeof d.reason==="string"?d.reason:typeof d.error==="string"?d.error:"Nothing was tapped. Read describeScreen and try again."}}async function*runAgentTurn(t){const{provider:r,catalog:o,system:d,systemVolatile:l,model:k,maxTokens:y,dispatch:f,readSnapshot:m,storeKeyOwners:U,ledger:g,policy:x,isRelease:D,requestApproval:Y,signal:_,evidence:K,trusted:A,procedures:F}=t;const Q=new Map;const O=t.calibration??new _tokenCalibration.TokenCalibration;const ae=[...t.messages].reverse().find(p=>(0,_types.isRealUserMessage)(p));const j=(0,_turnScope.classifyTurn)(ae?.role==="user"?ae.text:"");const u=[...t.messages];const pe=r.protocol==="anthropic"?t.feedOptions??{}:{};const G=pe.freezeHistory===true;const P=pe.notices==="system-msg";const de=(p,N=false)=>({role:"user",text:p,...r.protocol==="anthropic"?{source:"engine"}:{},...N?{systemNotice:true}:{}});const qe=()=>{const p=u[u.length-1];return P&&(p?.role==="tool-results"||p?.role==="user"&&p.systemNotice===true)};const Ue=(0,_idGrounding.idGrounding)(u,`${t.system}
2
2
  ${t.systemVolatile??""}${ae?.role==="user"&&ae.liveBlock?`
3
3
  ${ae.liveBlock.text}`:""}
4
- ${JSON.stringify(F??[])}`);let V=(0,_toProviderTools.toProviderTools)(o,{availableToolIds:t.availableToolIds,availableActions:t.availableActions,isRelease:M});V.push((0,_uiTool.uiProviderTool)());if(G)V=JSON.parse(JSON.stringify(V));const X=x.maxSteps??DEFAULT_MAX_STEPS;const xe=newAskId();const st=g.generation;const it=new Set(g.list().map(p=>p.id));const Me=d.length+(l?.length??0)+V.reduce((p,E)=>p+E.description.length+JSON.stringify(E.inputSchema).length,0);const he=()=>Me+O.chars(y);let le=(0,_realNow.realNow)()+DEFAULT_TURN_MS;const Z={throttled:0,overflow:0,network:0};let ee=_historyBudget.MAX_HISTORY_TOKENS;const ke=t.seenUrls??new Set;const at=/https?:\/\/[^\s"'\\)\]}>]+/g;let ve=false;const te=[];let De=false;const we=[];let Te=false;let Le=false;let ye=false;let je=false;let Be=false;const dt=[...f].reverse().find(_types.isRealUserMessage);const lt=/\?\s*$/.test(dt?.text?.trim()??"");const ze=p=>p.reduce((E,$)=>E+(0,_historyBudget.messageSize)($),0)<=Math.min(O.chars(ee),O.chars(_historyBudget.MAX_REQUEST_TOKENS)-he());const Re="This turn has no room left. Tap Continue to go on.";for(let p=0;p<X;p++){if(_?.aborted){yield{type:"done",stopReason:"stopped"};return f}if((0,_realNow.realNow)()>le){yield{type:"block",block:{id:`cap${(0,_realNow.realNow)()}`,kind:"notice",tone:"warning",text:`This is taking too long \u2014 stopped after ${Math.round(DEFAULT_TURN_MS/1e3)}s. What it found so far is above.`,actions:[{label:"Continue",primary:true,send:CONTINUE_SEND}]}};yield{type:"done",stopReason:"time-cap"};return f}const E=G&&p>0?{messages:f,droppedRounds:0,droppedPinned:0}:(0,_historyBudget.budgetForRequest)(f,he(),O.chars(ee),O.charsPerToken,g.liveCallIds());if(E.droppedRounds>0){f.length=0;f.push(...E.messages);yield{type:"history-trimmed",droppedRounds:E.droppedRounds,droppedPinned:E.droppedPinned}}else if(E.messages!==f){f.length=0;f.push(...E.messages)}if(X>6&&p===X-6){f.push(de("6 steps left. Finish what the user asked. Skip extra checks. Batch reads that do not depend on each other in one round.",qe()))}if(G&&!ze(f)){yield{type:"block",block:{id:`space${(0,_realNow.realNow)()}`,kind:"notice",tone:"warning",text:Re,actions:[{label:"Continue",primary:true,send:CONTINUE_SEND}]}};yield{type:"done",stopReason:"incomplete"};return f}let $="";let We=false;const re=e=>{const c=ve&&!We;We=true;ve=true;return c?{type:"text",delta:e,breakBefore:true}:{type:"text",delta:e}};let w=[];const Je=new Set;let q="";let Ee=true;let ne=[];let me=false;let H;let W;let Ie=0;for(;;){Ie+=1;$="";w=[];q="";Ee=true;ne=[];me=false;H=void 0;W=void 0;let e;const c=Me+f.reduce((i,I)=>i+(0,_historyBudget.messageSize)(I),0);let n=false;try{for await(const i of r.send({messages:f,system:d,systemVolatile:l,tools:V,model:k,maxTokens:y,signal:_,meta:{askId:xe,round:p+1,attempt:Ie}})){if(i.type==="text"){$+=i.delta;if(!Ee){yield re(i.delta)}else if((0,_textToolCalls.couldBeToolCallEnvelope)($)){q+=i.delta}else{Ee=false;q="";yield re($)}}else if(i.type==="tool-call"){w.push(i.call)}else if(i.type==="meter"){yield{type:"meter",frame:i.frame}}else if(i.type==="thinking"){ne.push(i.block);if(i.block.type==="thinking"&&i.block.thinking.trim()){yield{type:"reasoning",text:i.block.thinking}}}else if(i.type==="error"){if(i.kind==="truncated"||i.kind==="timeout"){W={message:i.message}}else if(i.problem&&(i.problem.kind==="throttled"||i.problem.kind==="overflow")&&$===""&&w.length===0&&ne.length===0){e={problem:i.problem,message:i.message}}else{yield{type:"error",message:i.message,...i.problem?.hosted?{hosted:i.problem.hosted}:{}};me=true}}else if(i.type==="done"){H=i.outcome;if(i.usage){O.observe(c,(0,_tokenCalibration.promptTokensOf)(i.usage,r.protocol));yield{type:"usage",...i.usage,model:i.model}}}}}catch(i){const I=$===""&&w.length===0&&ne.length===0;if(_?.aborted||!I||Z.network>=NETWORK_RETRIES||(0,_realNow.realNow)()+NETWORK_RETRY_MS>le)throw i;n=true}if(n){Z.network+=1;yield{type:"retrying",reason:"network",attempt:Z.network+1,maxAttempts:1+NETWORK_RETRIES,inMs:NETWORK_RETRY_MS};await sleep(NETWORK_RETRY_MS,_);if(_?.aborted){yield{type:"done",stopReason:"stopped"};return f}continue}if(!e)break;const s=e.problem.kind;if(G&&s==="overflow"){W={message:Re};break}const b=1+(s==="throttled"?THROTTLE_RETRIES:OVERFLOW_RETRIES);const h=Z[s];let C=s==="throttled"?Math.min(e.problem.retryAfterMs??RETRY_BASE_MS*2**h,RETRY_AFTER_CAP_MS)+Math.floor(Math.random()*RETRY_JITTER_MS):0;let D=h>=b-1||_?.aborted===true||(0,_realNow.realNow)()+C>le;if(e.problem.hosted&&Ie>=2)D=true;if(!D&&s==="overflow"){ee=Math.floor(ee/2);const i=f.reduce((J,z)=>J+(0,_historyBudget.messageSize)(z),0);const I=(0,_historyBudget.budgetForRequest)(f,he(),O.chars(ee),O.charsPerToken,g.liveCallIds());const _e=I.messages.reduce((J,z)=>J+(0,_historyBudget.messageSize)(z),0);if(_e>=i){D=true}else{f.length=0;f.push(...I.messages);if(I.droppedRounds>0)yield{type:"history-trimmed",droppedRounds:I.droppedRounds,droppedPinned:I.droppedPinned}}}if(D){const i=s==="throttled"?h>0?`The AI endpoint is rate-limiting requests \u2014 tried ${h+1} times.`:"The AI endpoint is rate-limiting requests.":"This conversation is too large for the AI endpoint and there was nothing older to trim. Start a new conversation, or ask a shorter question.";const I=e.problem.hosted;yield I?{type:"error",message:I.message,hosted:I}:{type:"error",message:`${i} (${e.message})`};me=true;break}Z[s]+=1;yield{type:"retrying",reason:s,attempt:Z[s]+1,maxAttempts:b,inMs:C};if(C>0)await sleep(C,_);if(_?.aborted){yield{type:"done",stopReason:"stopped"};return f}}if(H==="refused"||H==="context-limited"){yield{type:"error",message:H==="refused"?"Claude could not help with this request.":"Claude ran out of room for this turn. Please send a new message."};yield{type:"done",stopReason:"error"};return f}if(me){if(q)yield re(q);yield{type:"done",stopReason:"error"};return f}if(!W&&H!=="completed"){W={message:H==="output-limited"?w.length?"The model ran out of room mid-plan, so nothing was run. What it found so far is above.":"The model ran out of room before finishing this answer.":"The answer ended before the endpoint said it was finished, so nothing was run."}}if(W){if(q)yield re(q);if($.trim())f.push({role:"assistant",text:$});yield{type:"block",block:{id:`cut${(0,_realNow.realNow)()}`,kind:"notice",tone:"warning",text:W.message,actions:[{label:"Continue",primary:true,send:CONTINUE_SEND}]}};yield{type:"done",stopReason:"incomplete"};return f}if(q){const e=w.length===0?(0,_textToolCalls.parseTextToolCalls)(q,o):void 0;if(e){for(const c of e.calls){w.push(c);Je.add(c.id)}$=e.reply;if(e.reply)yield re(e.reply)}else{yield re(q)}q=""}f.push({role:"assistant",text:$,toolCalls:w.length?w:void 0,thinking:ne.length?ne:void 0});if($.trim())we.push($.trim());if(w.length===0&&!ye&&!Te&&p<X-1&&((0,_planOnlyStop.announcesUnstartedWork)($,j==="task")||je&&!Be&&!lt)){ye=true;f.push(de(_planOnlyStop.PLAN_ONLY_NUDGE));continue}if(w.length===0&&!ye&&we.length===0&&p<X-1){ye=true;f.push(de(_planOnlyStop.SILENT_NUDGE));continue}if(w.length===0){const e=we.join("\n\n");const c=(0,_askGate.synthesizeShortfallBlock)({text:e,attempted:Le});if(c)yield{type:"block",block:c};const n=Te||c?null:(0,_askGate.synthesizeAskBlock)(e);if(n){yield{type:"block",block:n};yield{type:"awaiting-user",blockId:n.id}}yield{type:"done",stopReason:n?"awaiting-user":"answered"};return f}const v=[];const ge=[];const L=e=>{if(!P)return e;ge.push(e.trim());return""};let Ye=false;const Ke=new Map;if(w.length>1){const e=w.every(c=>{if(c.name===_uiTool.UI_TOOL_NAME)return false;const n=(0,_toProviderTools.fromProviderToolName)(c.name,o);if(!n||n==="ask-buoy")return false;const s=c.input?.action;if(typeof s!=="string"||s===_snapshotReads.SNAPSHOT_ACTION)return false;const b=findDescriptor(o,n,s);if(!b||b.effect!=="read")return false;return(0,_policy.decide)({descriptor:b,toolId:n,policy:x,isRelease:M}).verdict==="allow"});if(e){for(const c of w){const n=(0,_toProviderTools.fromProviderToolName)(c.name,o);const s=String(c.input.action);const b={...c.input.params??{}};const h=findDescriptor(o,n,s);const C=(0,_normalizeParams.normalizeParams)(n,s,b);const D=(0,_validateParams.applyDefaults)(C.params,h.params);if(!(0,_validateParams.validateParams)(D,h.params).ok)continue;const i=Promise.resolve(u(n,s,D)).catch(I=>{throw I});i.catch(()=>{});Ke.set(c.id,i)}}}let Ne=null;const ut=e=>{const c=(0,_toProviderTools.fromProviderToolName)(e.name,o)??e.name;const n=typeof e.input?.action==="string"?e.input.action:"";const s=n?findDescriptor(o,c,n):void 0;const b=e.input?.params??{};return[{type:"tool-start",id:e.id,toolId:c,action:n,label:s?(0,_policy.describeCall)(c,s,b):`${c}.${n}`,description:s?.summary??"",params:b,effect:s?.effect??"read"},{type:"tool-end",id:e.id,ok:false,summary:"stopped",durationMs:0}]};const be=new Map;if(j==="question"){for(const e of w){if((0,_toProviderTools.fromProviderToolName)(e.name,o)!=="highlight-updates"||e.input?.action!=="tapElement")continue;const c=(0,_normalizeParams.normalizeParams)("highlight-updates","tapElement",e.input.params??{}).params;if(emptyTap("highlight-updates","tapElement",c))continue;const n=findDescriptor(o,"highlight-updates","describeScreen");const s=findDescriptor(o,"highlight-updates","tapElement");if(_?.aborted||!n||!s||(0,_policy.decide)({descriptor:n,toolId:"highlight-updates",policy:x,isRelease:M}).verdict!=="allow"||(0,_policy.decide)({descriptor:s,toolId:"highlight-updates",policy:x,isRelease:M,turnScope:j,params:c}).verdict==="refuse")continue;const b=await u("highlight-updates","describeScreen",{}).catch(()=>void 0);be.set(e.id,(0,_turnScope.tapLabels)(b,c))}}const Qe=w.map(e=>{if(e.name===_uiTool.UI_TOOL_NAME)return void 0;const c=(0,_toProviderTools.fromProviderToolName)(e.name,o);const n=typeof e.input?.action==="string"?e.input.action:void 0;if(!c||!n)return void 0;const s=findDescriptor(o,c,n);if(!s)return void 0;const b=e.input.params??{};const h=(0,_validateParams.applyDefaults)((0,_normalizeParams.normalizeParams)(c,n,b).params,s.params);if(emptyTap(c,n,h)||!(0,_validateParams.validateParams)(h,s.params).ok)return void 0;const C=(0,_policy.decide)({descriptor:s,toolId:c,policy:x,isRelease:M,turnScope:j,params:h,tapLabels:be.get(e.id)});return{call:e,toolId:c,action:n,descriptor:s,params:h,label:(0,_policy.describeCall)(c,s,h),mutates:s.effect!=="read",gated:C.verdict==="needs-approval",turnScoped:C.verdict==="needs-approval"&&C.turnScoped,reason:C.verdict==="needs-approval"?C.reason:""}});const ft=Qe.some(e=>e?.gated);const B=new Map;let Ve=false;let Xe=false;async function*pt(){Ve=true;for(const e of Qe){if(!e?.gated||B.has(e.call.id))continue;if(!e.turnScoped&&A?.has(`${e.toolId}.${e.action}`)){B.set(e.call.id,true);continue}yield{type:"approval-required",id:e.call.id,toolId:e.toolId,action:e.action,label:e.label,description:e.descriptor.summary,reason:e.reason};const c=(0,_realNow.realNow)();const n=await readTargetDigest({toolId:e.toolId,action:e.action,params:e.params,dispatch:u,catalog:o});const s=readAnswer(!e.turnScoped&&A?.has(`${e.toolId}.${e.action}`)?true:Y?await Y({id:e.call.id,toolId:e.toolId,action:e.action,label:e.label,description:e.descriptor.summary,reason:e.reason,params:e.params,targetDigest:n}):false);le+=(0,_realNow.realNow)()-c;const b=s.approved;B.set(e.call.id,b);if(s.trust)A?.add(`${e.toolId}.${e.action}`);if(s.reason)Q.set(e.call.id,s.reason);if(!b){Xe=true;return}}}for(const e of w){if(_?.aborted){if(e.name!==_uiTool.UI_TOOL_NAME){for(const a of ut(e))yield a}v.push({toolCallId:e.id,content:"Not run \u2014 the user pressed Stop before this call started.",isError:true});continue}const c=e.input?.[_types.UNPARSEABLE_ARGS];if(typeof c==="string"){v.push({toolCallId:e.id,content:`Not run \u2014 this call's arguments were not valid JSON, so nothing changed (${c.slice(0,120)}). Send the call again with compact JSON: {"action": "...", "params": {...}}.`,isError:true});continue}if(e.name===_uiTool.UI_TOOL_NAME){const a=(0,_uiTool.buildUiBlock)(e.input);if(!a.ok||!a.block){v.push({toolCallId:e.id,content:`Invalid ${_uiTool.UI_TOOL_NAME} block:
5
- ${a.errors.join("\n")}`+L("\n\nResend ONLY the corrected block. Do not rewrite your answer \u2014 whatever you already said this turn has been shown to the user, and saying it again repeats it on their screen."),isError:true});continue}let R=0;if(a.block.kind==="imageGrid"){const N=a.block.images.filter(S=>ke.has(S.url));R=a.block.images.length-N.length;if(N.length===0){v.push({toolCallId:e.id,content:P?"Rejected: image URLs were not read from a tool result."+L(URL_PROVENANCE_REJECTION):URL_PROVENANCE_REJECTION,isError:true});continue}a.block={...a.block,images:N}}if(a.block.kind==="list"){const N=a.block.items.map(S=>{if(!S.image||ke.has(S.image))return S;R+=1;return{...S,image:void 0}});a.block={...a.block,items:N}}yield{type:"block",block:a.block,forToolCallId:e.id};if(a.block.kind==="actions"||a.block.kind==="suggestions"||a.block.kind==="plan"&&a.block.pending){Te=true}if((0,_types2.isAskBlock)(a.block)){Ne=a.block.id;v.push({toolCallId:e.id,content:"Shown. Waiting for the user's answer \u2014 it will arrive as their next message."+L(" Do not guess it.")})}else{v.push({toolCallId:e.id,content:"Shown to the user."+L(" Don't repeat its contents in text.")+(R>0?droppedImageNote(R):"")})}continue}const n=(0,_toProviderTools.fromProviderToolName)(e.name,o);const s=e.input.action;const b=(a,R)=>[{type:"tool-start",id:e.id,toolId:n??e.name,action:s??"",label:a,description:"",params:e.input.params??{},effect:"read"},{type:"tool-end",id:e.id,ok:false,summary:R,durationMs:0}];if(!n){for(const a of b(e.name,"No such tool"))yield a;v.push({toolCallId:e.id,content:`There is no tool called "${e.name}". Use one of the tools you were given.`,isError:true});continue}if(!s){for(const a of b(e.name,"No action given"))yield a;v.push({toolCallId:e.id,content:`"${e.name}" needs an "action" \u2014 it is required, and it names which of this tool's actions to run. See the action list in the tool's description.`,isError:true});continue}const h=findDescriptor(o,n,s);if(!h){const a=o.find(T=>T.toolId===n)?.actions.map(T=>T.action)??[];const R=o.filter(T=>T.toolId!==n&&T.actions.some(Ce=>Ce.action===s));const N=a.filter(T=>closeAction(T,s));const S=[...R.map(T=>`${T.toolId}.${s}`),...N.map(T=>`${n}.${T}`)].slice(0,3);const ie=`${n} has no ${s}.${S.length?` Did you mean ${S.join(" or ")}?`:""}`;for(const T of b(`${n}.${s}`,S.length?ie:"No such action"))yield T;v.push({toolCallId:e.id,content:`${ie}${a.length?` Valid actions: ${a.join(", ")}.`:""}`,isError:true});continue}const C=e.input.params??{};const D=(0,_normalizeParams.normalizeParams)(n,s,C);const i=(0,_validateParams.applyDefaults)(D.params,h.params);if(emptyTap(n,s,i)){for(const a of b(`${n}.${s}`,EMPTY_TAP_ERROR))yield a;v.push({toolCallId:e.id,content:JSON.stringify({ok:false,error:P?"tapElement needs nativeTag, testID or query."+L("Read describeScreen and pass nativeTag, testID or query."):EMPTY_TAP_ERROR}),isError:true});continue}const I=(0,_validateParams.validateParams)(i,h.params);if(!I.ok){v.push({toolCallId:e.id,content:`Invalid parameters for ${n}.${s}:
4
+ ${JSON.stringify(F??[])}`);let V=(0,_toProviderTools.toProviderTools)(o,{availableToolIds:t.availableToolIds,availableActions:t.availableActions,isRelease:D});V.push((0,_uiTool.uiProviderTool)());if(G)V=JSON.parse(JSON.stringify(V));const X=x.maxSteps??DEFAULT_MAX_STEPS;const xe=newAskId();const st=g.generation;const it=new Set(g.list().map(p=>p.id));const De=d.length+(l?.length??0)+V.reduce((p,N)=>p+N.description.length+JSON.stringify(N.inputSchema).length,0);const he=()=>De+O.chars(y);let le=(0,_realNow.realNow)()+DEFAULT_TURN_MS;const Z={throttled:0,overflow:0,network:0};let ee=_historyBudget.MAX_HISTORY_TOKENS;const ve=t.seenUrls??new Set;const at=/https?:\/\/[^\s"'\\)\]}>]+/g;let ye=false;const te=[];let Le=false;const we=[];let Te=false;let Me=false;let me=false;let je=false;let Be=false;const dt=[...u].reverse().find(_types.isRealUserMessage);const lt=/\?\s*$/.test(dt?.text?.trim()??"");const ze=p=>p.reduce((N,$)=>N+(0,_historyBudget.messageSize)($),0)<=Math.min(O.chars(ee),O.chars(_historyBudget.MAX_REQUEST_TOKENS)-he());const Re="This turn has no room left. Tap Continue to go on.";for(let p=0;p<X;p++){if(_?.aborted){yield{type:"done",stopReason:"stopped"};return u}if((0,_realNow.realNow)()>le){yield{type:"block",block:{id:`cap${(0,_realNow.realNow)()}`,kind:"notice",tone:"warning",text:`This is taking too long \u2014 stopped after ${Math.round(DEFAULT_TURN_MS/1e3)}s. What it found so far is above.`,actions:[{label:"Continue",primary:true,send:CONTINUE_SEND}]}};yield{type:"done",stopReason:"time-cap"};return u}const N=G&&p>0?{messages:u,droppedRounds:0,droppedPinned:0}:(0,_historyBudget.budgetForRequest)(u,he(),O.chars(ee),O.charsPerToken,g.liveCallIds());if(N.droppedRounds>0){u.length=0;u.push(...N.messages);yield{type:"history-trimmed",droppedRounds:N.droppedRounds,droppedPinned:N.droppedPinned}}else if(N.messages!==u){u.length=0;u.push(...N.messages)}if(X>6&&p===X-6){u.push(de("6 steps left. Finish what the user asked. Skip extra checks. Batch reads that do not depend on each other in one round.",qe()))}if(G&&!ze(u)){yield{type:"block",block:{id:`space${(0,_realNow.realNow)()}`,kind:"notice",tone:"warning",text:Re,actions:[{label:"Continue",primary:true,send:CONTINUE_SEND}]}};yield{type:"done",stopReason:"incomplete"};return u}let $="";let We=false;const re=e=>{const c=ye&&!We;We=true;ye=true;return c?{type:"text",delta:e,breakBefore:true}:{type:"text",delta:e}};let w=[];const Je=new Set;let q="";let Ee=true;let ne=[];let ge=false;let H;let W;let Ne=0;for(;;){Ne+=1;$="";w=[];q="";Ee=true;ne=[];ge=false;H=void 0;W=void 0;let e;const c=De+u.reduce((i,I)=>i+(0,_historyBudget.messageSize)(I),0);let n=false;try{for await(const i of r.send({messages:u,system:d,systemVolatile:l,tools:V,model:k,maxTokens:y,signal:_,meta:{askId:xe,round:p+1,attempt:Ne}})){if(i.type==="text"){$+=i.delta;if(!Ee){yield re(i.delta)}else if((0,_textToolCalls.couldBeToolCallEnvelope)($)){q+=i.delta}else{Ee=false;q="";yield re($)}}else if(i.type==="tool-call"){w.push(i.call)}else if(i.type==="meter"){yield{type:"meter",frame:i.frame}}else if(i.type==="thinking"){ne.push(i.block);if(i.block.type==="thinking"&&i.block.thinking.trim()){yield{type:"reasoning",text:i.block.thinking}}}else if(i.type==="error"){if(i.kind==="truncated"||i.kind==="timeout"){W={message:i.message}}else if(i.problem&&(i.problem.kind==="throttled"||i.problem.kind==="overflow")&&$===""&&w.length===0&&ne.length===0){e={problem:i.problem,message:i.message}}else{yield{type:"error",message:i.message,...i.problem?.hosted?{hosted:i.problem.hosted}:{}};ge=true}}else if(i.type==="done"){H=i.outcome;if(i.usage){O.observe(c,(0,_tokenCalibration.promptTokensOf)(i.usage,r.protocol));yield{type:"usage",...i.usage,model:i.model}}}}}catch(i){const I=$===""&&w.length===0&&ne.length===0;if(_?.aborted||!I||Z.network>=NETWORK_RETRIES||(0,_realNow.realNow)()+NETWORK_RETRY_MS>le)throw i;n=true}if(n){Z.network+=1;yield{type:"retrying",reason:"network",attempt:Z.network+1,maxAttempts:1+NETWORK_RETRIES,inMs:NETWORK_RETRY_MS};await sleep(NETWORK_RETRY_MS,_);if(_?.aborted){yield{type:"done",stopReason:"stopped"};return u}continue}if(!e)break;const s=e.problem.kind;if(G&&s==="overflow"){W={message:Re};break}const b=1+(s==="throttled"?THROTTLE_RETRIES:OVERFLOW_RETRIES);const h=Z[s];let C=s==="throttled"?Math.min(e.problem.retryAfterMs??RETRY_BASE_MS*2**h,RETRY_AFTER_CAP_MS)+Math.floor(Math.random()*RETRY_JITTER_MS):0;let L=h>=b-1||_?.aborted===true||(0,_realNow.realNow)()+C>le;if(e.problem.hosted&&Ne>=2)L=true;if(!L&&s==="overflow"){ee=Math.floor(ee/2);const i=u.reduce((J,z)=>J+(0,_historyBudget.messageSize)(z),0);const I=(0,_historyBudget.budgetForRequest)(u,he(),O.chars(ee),O.charsPerToken,g.liveCallIds());const _e=I.messages.reduce((J,z)=>J+(0,_historyBudget.messageSize)(z),0);if(_e>=i){L=true}else{u.length=0;u.push(...I.messages);if(I.droppedRounds>0)yield{type:"history-trimmed",droppedRounds:I.droppedRounds,droppedPinned:I.droppedPinned}}}if(L){const i=s==="throttled"?h>0?`The AI endpoint is rate-limiting requests \u2014 tried ${h+1} times.`:"The AI endpoint is rate-limiting requests.":"This conversation is too large for the AI endpoint and there was nothing older to trim. Start a new conversation, or ask a shorter question.";const I=e.problem.hosted;yield I?{type:"error",message:I.message,hosted:I}:{type:"error",message:`${i} (${e.message})`};ge=true;break}Z[s]+=1;yield{type:"retrying",reason:s,attempt:Z[s]+1,maxAttempts:b,inMs:C};if(C>0)await sleep(C,_);if(_?.aborted){yield{type:"done",stopReason:"stopped"};return u}}if(H==="refused"||H==="context-limited"){yield{type:"error",message:H==="refused"?"Claude could not help with this request.":"Claude ran out of room for this turn. Please send a new message."};yield{type:"done",stopReason:"error"};return u}if(ge){if(q)yield re(q);yield{type:"done",stopReason:"error"};return u}if(!W&&H!=="completed"){W={message:H==="output-limited"?w.length?"The model ran out of room mid-plan, so nothing was run. What it found so far is above.":"The model ran out of room before finishing this answer.":"The answer ended before the endpoint said it was finished, so nothing was run."}}if(W){if(q)yield re(q);if($.trim())u.push({role:"assistant",text:$});yield{type:"block",block:{id:`cut${(0,_realNow.realNow)()}`,kind:"notice",tone:"warning",text:W.message,actions:[{label:"Continue",primary:true,send:CONTINUE_SEND}]}};yield{type:"done",stopReason:"incomplete"};return u}if(q){const e=w.length===0?(0,_textToolCalls.parseTextToolCalls)(q,o):void 0;if(e){for(const c of e.calls){w.push(c);Je.add(c.id)}$=e.reply;if(e.reply)yield re(e.reply)}else{yield re(q)}q=""}u.push({role:"assistant",text:$,toolCalls:w.length?w:void 0,thinking:ne.length?ne:void 0});if($.trim())we.push($.trim());if(w.length===0&&!me&&!Te&&p<X-1&&((0,_planOnlyStop.announcesUnstartedWork)($,j==="task")||je&&!Be&&!lt)){me=true;u.push(de(_planOnlyStop.PLAN_ONLY_NUDGE));continue}if(w.length===0&&!me&&we.length===0&&p<X-1){me=true;u.push(de(_planOnlyStop.SILENT_NUDGE));continue}if(w.length===0){const e=we.join("\n\n");const c=(0,_askGate.synthesizeShortfallBlock)({text:e,attempted:Me});if(c)yield{type:"block",block:c};const n=Te||c?null:(0,_askGate.synthesizeAskBlock)(e);if(n){yield{type:"block",block:n};yield{type:"awaiting-user",blockId:n.id}}yield{type:"done",stopReason:n?"awaiting-user":"answered"};return u}const v=[];const be=[];const M=e=>{if(!P)return e;be.push(e.trim());return""};let Ye=false;const Ke=new Map;if(w.length>1){const e=w.every(c=>{if(c.name===_uiTool.UI_TOOL_NAME)return false;const n=(0,_toProviderTools.fromProviderToolName)(c.name,o);if(!n||n==="ask-buoy")return false;const s=c.input?.action;if(typeof s!=="string"||s===_snapshotReads.SNAPSHOT_ACTION)return false;const b=findDescriptor(o,n,s);if(!b||b.effect!=="read")return false;return(0,_policy.decide)({descriptor:b,toolId:n,policy:x,isRelease:D}).verdict==="allow"});if(e){for(const c of w){const n=(0,_toProviderTools.fromProviderToolName)(c.name,o);const s=String(c.input.action);const b={...c.input.params??{}};const h=findDescriptor(o,n,s);const C=(0,_normalizeParams.normalizeParams)(n,s,b);const L=(0,_validateParams.applyDefaults)(C.params,h.params);if(!(0,_validateParams.validateParams)(L,h.params).ok)continue;const i=Promise.resolve(f(n,s,L)).catch(I=>{throw I});i.catch(()=>{});Ke.set(c.id,i)}}}let Ie=null;const ut=e=>{const c=(0,_toProviderTools.fromProviderToolName)(e.name,o)??e.name;const n=typeof e.input?.action==="string"?e.input.action:"";const s=n?findDescriptor(o,c,n):void 0;const b=e.input?.params??{};return[{type:"tool-start",id:e.id,toolId:c,action:n,label:s?(0,_policy.describeCall)(c,s,b):`${c}.${n}`,description:s?.summary??"",params:b,effect:s?.effect??"read"},{type:"tool-end",id:e.id,ok:false,summary:"stopped",durationMs:0}]};const ke=new Map;if(j==="question"){for(const e of w){if((0,_toProviderTools.fromProviderToolName)(e.name,o)!=="highlight-updates"||e.input?.action!=="tapElement")continue;const c=(0,_normalizeParams.normalizeParams)("highlight-updates","tapElement",e.input.params??{}).params;if(emptyTap("highlight-updates","tapElement",c))continue;const n=findDescriptor(o,"highlight-updates","describeScreen");const s=findDescriptor(o,"highlight-updates","tapElement");if(_?.aborted||!n||!s||(0,_policy.decide)({descriptor:n,toolId:"highlight-updates",policy:x,isRelease:D}).verdict!=="allow"||(0,_policy.decide)({descriptor:s,toolId:"highlight-updates",policy:x,isRelease:D,turnScope:j,params:c}).verdict==="refuse")continue;const b=await f("highlight-updates","describeScreen",{}).catch(()=>void 0);ke.set(e.id,(0,_turnScope.tapLabels)(b,c))}}const Qe=w.map(e=>{if(e.name===_uiTool.UI_TOOL_NAME)return void 0;const c=(0,_toProviderTools.fromProviderToolName)(e.name,o);const n=typeof e.input?.action==="string"?e.input.action:void 0;if(!c||!n)return void 0;const s=findDescriptor(o,c,n);if(!s)return void 0;const b=e.input.params??{};const h=(0,_validateParams.applyDefaults)((0,_normalizeParams.normalizeParams)(c,n,b).params,s.params);if(emptyTap(c,n,h)||!(0,_validateParams.validateParams)(h,s.params).ok)return void 0;const C=(0,_policy.decide)({descriptor:s,toolId:c,policy:x,isRelease:D,turnScope:j,params:h,tapLabels:ke.get(e.id)});return{call:e,toolId:c,action:n,descriptor:s,params:h,label:(0,_policy.describeCall)(c,s,h),mutates:s.effect!=="read",gated:C.verdict==="needs-approval",turnScoped:C.verdict==="needs-approval"&&C.turnScoped,reason:C.verdict==="needs-approval"?C.reason:""}});const ft=Qe.some(e=>e?.gated);const B=new Map;let Ve=false;let Xe=false;async function*pt(){Ve=true;for(const e of Qe){if(!e?.gated||B.has(e.call.id))continue;if(!e.turnScoped&&A?.has(`${e.toolId}.${e.action}`)){B.set(e.call.id,true);continue}yield{type:"approval-required",id:e.call.id,toolId:e.toolId,action:e.action,label:e.label,description:e.descriptor.summary,reason:e.reason};const c=(0,_realNow.realNow)();const n=await readTargetDigest({toolId:e.toolId,action:e.action,params:e.params,dispatch:f,catalog:o});const s=readAnswer(!e.turnScoped&&A?.has(`${e.toolId}.${e.action}`)?true:Y?await Y({id:e.call.id,toolId:e.toolId,action:e.action,label:e.label,description:e.descriptor.summary,reason:e.reason,params:e.params,targetDigest:n}):false);le+=(0,_realNow.realNow)()-c;const b=s.approved;B.set(e.call.id,b);if(s.trust)A?.add(`${e.toolId}.${e.action}`);if(s.reason)Q.set(e.call.id,s.reason);if(!b){Xe=true;return}}}for(const e of w){if(_?.aborted){if(e.name!==_uiTool.UI_TOOL_NAME){for(const a of ut(e))yield a}v.push({toolCallId:e.id,content:"Not run \u2014 the user pressed Stop before this call started.",isError:true});continue}const c=e.input?.[_types.UNPARSEABLE_ARGS];if(typeof c==="string"){v.push({toolCallId:e.id,content:`Not run \u2014 this call's arguments were not valid JSON, so nothing changed (${c.slice(0,120)}). Send the call again with compact JSON: {"action": "...", "params": {...}}.`,isError:true});continue}if(e.name===_uiTool.UI_TOOL_NAME){const a=(0,_uiTool.buildUiBlock)(e.input);if(!a.ok||!a.block){v.push({toolCallId:e.id,content:`Invalid ${_uiTool.UI_TOOL_NAME} block:
5
+ ${a.errors.join("\n")}`+M("\n\nResend ONLY the corrected block. Do not rewrite your answer \u2014 whatever you already said this turn has been shown to the user, and saying it again repeats it on their screen."),isError:true});continue}let R=0;if(a.block.kind==="imageGrid"){const S=a.block.images.filter(E=>ve.has(E.url));R=a.block.images.length-S.length;if(S.length===0){v.push({toolCallId:e.id,content:P?"Rejected: image URLs were not read from a tool result."+M(URL_PROVENANCE_REJECTION):URL_PROVENANCE_REJECTION,isError:true});continue}a.block={...a.block,images:S}}if(a.block.kind==="list"){const S=a.block.items.map(E=>{if(!E.image||ve.has(E.image))return E;R+=1;return{...E,image:void 0}});a.block={...a.block,items:S}}yield{type:"block",block:a.block,forToolCallId:e.id};if(a.block.kind==="actions"||a.block.kind==="suggestions"||a.block.kind==="plan"&&a.block.pending){Te=true}if((0,_types2.isAskBlock)(a.block)){Ie=a.block.id;v.push({toolCallId:e.id,content:"Shown. Waiting for the user's answer \u2014 it will arrive as their next message."+M(" Do not guess it.")})}else{v.push({toolCallId:e.id,content:"Shown to the user."+M(" Don't repeat its contents in text.")+(R>0?droppedImageNote(R):"")})}continue}const n=(0,_toProviderTools.fromProviderToolName)(e.name,o);const s=e.input.action;const b=(a,R)=>[{type:"tool-start",id:e.id,toolId:n??e.name,action:s??"",label:a,description:"",params:e.input.params??{},effect:"read"},{type:"tool-end",id:e.id,ok:false,summary:R,durationMs:0}];if(!n){for(const a of b(e.name,"No such tool"))yield a;v.push({toolCallId:e.id,content:`There is no tool called "${e.name}". Use one of the tools you were given.`,isError:true});continue}if(!s){for(const a of b(e.name,"No action given"))yield a;v.push({toolCallId:e.id,content:`"${e.name}" needs an "action" \u2014 it is required, and it names which of this tool's actions to run. See the action list in the tool's description.`,isError:true});continue}const h=findDescriptor(o,n,s);if(!h){const a=o.find(T=>T.toolId===n)?.actions.map(T=>T.action)??[];const R=o.filter(T=>T.toolId!==n&&T.actions.some(Ce=>Ce.action===s));const S=a.filter(T=>closeAction(T,s));const E=[...R.map(T=>`${T.toolId}.${s}`),...S.map(T=>`${n}.${T}`)].slice(0,3);const ie=`${n} has no ${s}.${E.length?` Did you mean ${E.join(" or ")}?`:""}`;for(const T of b(`${n}.${s}`,E.length?ie:"No such action"))yield T;v.push({toolCallId:e.id,content:`${ie}${a.length?` Valid actions: ${a.join(", ")}.`:""}`,isError:true});continue}const C=e.input.params??{};const L=(0,_normalizeParams.normalizeParams)(n,s,C);const i=(0,_validateParams.applyDefaults)(L.params,h.params);if(emptyTap(n,s,i)){for(const a of b(`${n}.${s}`,EMPTY_TAP_ERROR))yield a;v.push({toolCallId:e.id,content:JSON.stringify({ok:false,error:P?"tapElement needs nativeTag, testID or query."+M("Read describeScreen and pass nativeTag, testID or query."):EMPTY_TAP_ERROR}),isError:true});continue}const I=(0,_validateParams.validateParams)(i,h.params);if(!I.ok){v.push({toolCallId:e.id,content:`Invalid parameters for ${n}.${s}:
6
6
  ${I.errors.join("\n")}
7
7
 
8
8
  Expected schema:
9
- ${JSON.stringify(h.params)}`,isError:true});continue}const _e=(0,_normalizeParams.aliasNote)(D.notes);const J=h.effect!=="read"?Ue.trailer(i,!P):"";if(P&&J)L(_idGrounding.UNSEEN_ID_ADVICE);const z=(0,_policy.describeCall)(n,h,i);const se=(0,_policy.decide)({descriptor:h,toolId:n,policy:x,isRelease:M,turnScope:j,params:i,tapLabels:be.get(e.id)});const ue=a=>[{type:"tool-start",id:e.id,toolId:n,action:s,label:z,description:h.summary,params:i,effect:h.effect},{type:"tool-end",id:e.id,ok:false,summary:a,durationMs:0}];if(se.verdict==="refuse"){for(const a of ue("refused"))yield a;v.push({toolCallId:e.id,content:se.reason,isError:true});continue}const Ae=se.verdict==="needs-approval";if(ft&&!Ve&&(h.effect!=="read"||Ae)){yield*pt()}if(Xe&&(h.effect!=="read"||Ae)){for(const a of ue("declined"))yield a;v.push({toolCallId:e.id,content:j==="question"?_turnScope.QUESTION_DECLINED:B.get(e.id)===false?declinedResult(Q.get(e.id)):"Not run \u2014 the user declined another change in this same batch, so none of it was applied. Ask what they would prefer before proposing it again.",isError:true});continue}if(Ae){let a;if(B.has(e.id)){a=B.get(e.id)}else if(!se.turnScoped&&A?.has(`${n}.${s}`)){a=true;B.set(e.id,true)}else{yield{type:"approval-required",id:e.id,toolId:n,action:s,label:z,description:h.summary,reason:se.reason};const R=(0,_realNow.realNow)();const N=await readTargetDigest({toolId:n,action:s,params:i,dispatch:u,catalog:o});const S=readAnswer(Y?await Y({id:e.id,toolId:n,action:s,label:z,description:h.summary,reason:se.reason,params:i,targetDigest:N}):false);le+=(0,_realNow.realNow)()-R;a=S.approved;B.set(e.id,a);if(S.trust)A?.add(`${n}.${s}`);if(S.reason)Q.set(e.id,S.reason)}if(!a){for(const R of ue("declined"))yield R;v.push({toolCallId:e.id,content:j==="question"?_turnScope.QUESTION_DECLINED:declinedResult(Q.get(e.id)),isError:true});continue}}if(_askGate.ACQUISITION_CALLS.has(`${n}.${s}`))Le=true;if(n==="ask-buoy"&&s==="openProcedure")je=true;yield{type:"tool-start",id:e.id,toolId:n,action:s,label:z,description:h.summary,params:i,effect:h.effect};const Ze=(0,_realNow.realNow)();const et=await captureBefore(h,n,i,u);const $e=await captureStoreState(h,n,i,u);if(_?.aborted){for(const a of ue("stopped"))yield a;v.push({toolCallId:e.id,content:"Not run \u2014 the user pressed Stop before this call started.",isError:true});continue}const tt=(0,_policy.decide)({descriptor:h,toolId:n,policy:x,isRelease:M,turnScope:j,params:i,tapLabels:be.get(e.id)});if(tt.verdict==="refuse"){for(const a of ue("refused"))yield a;v.push({toolCallId:e.id,content:tt.reason,isError:true});continue}try{let a=s===_snapshotReads.SNAPSHOT_ACTION?(0,_snapshotReads.projectSnapshot)(n,await requireSnapshot(m,n),i):n==="ask-buoy"?await runAskBuoyAction(s,g,u,K,i,F):await(Ke.get(e.id)??u(n,s,i));a=tapResult(n,s,a);const R=(0,_redact.redact)((0,_redact.stripSelfTraffic)(a));const N=reportsFailure(a);if(h.effect!=="read"&&!N)Be=true;const S=fullText(n==="highlight-updates"&&s==="describeScreen"&&!N?(0,_compactScreen.compactScreen)(R):R);const ie=K&&!N&&!(n==="ask-buoy"&&s==="retrieve")?K.stash({toolId:n,action:s,params:i,capturedAt:(0,_realNow.realNow)(),text:S}):void 0;const T=encodeResult(S,ie);Ue.add(S);const Ce=T.length>MAX_TRACE_RESULT_CHARS?`${T.slice(0,MAX_TRACE_RESULT_CHARS)}\u2026`:T;yield{type:"tool-end",id:e.id,ok:!N,summary:summarise(a),durationMs:(0,_realNow.realNow)()-Ze,result:Ce};const Oe=$e===void 0||N?void 0:await captureStoreState(h,n,i,u);if(h.effect!=="read"&&n!=="ask-buoy"&&!N){const Pe=g.noteExternalRevert(n,s,i);const rt=(0,_effectFor.effectFor)(n,h,i,a,et,{before:$e,after:Oe});if(rt&&!Pe){const nt=g.record(n,s,rt,st);if(nt)nt.callId=e.id}}const ot=N?void 0:(0,_receipts.projectReceipt)({toolId:n,action:s,params:i,result:R,before:$e??et,after:Oe,effect:h.effect});if(ot)yield{type:"block",block:ot,forToolCallId:e.id};const fe=h.effect!=="read"&&!N?await(0,_verify.verifyOutcome)({toolId:n,action:s,params:i,result:a,dispatch:u,readSnapshot:m,signal:_,after:Oe}):void 0;if(fe)yield{type:"tool-verified",id:e.id,verification:fe};if(P&&fe?.status==="failed")L(_verify.VERIFICATION_REPAIR);for(const Pe of T.match(at)??[])ke.add(Pe);v.push({toolCallId:e.id,content:T+ownedKeyNote(n,h,i,U,P?L:void 0)+_e+J+(fe?(0,_verify.verificationTrailer)(fe,!P):"")+(Je.has(e.id)?L(_textToolCalls.SALVAGE_NOTE):""),...ie?{ref:ie}:{}});if(n==="app"&&(s==="reloadApp"||s==="reload")){Ye=true}}catch(a){const R=a instanceof Error?a.message:String(a);yield{type:"tool-end",id:e.id,ok:false,summary:R,durationMs:(0,_realNow.realNow)()-Ze};v.push({toolCallId:e.id,content:`Failed: ${R}${J}`,isError:true})}}if(w.length){te.push(callSignature(w));if(te.length>LOOP_REPEATS)te.shift();const e=!De&&te.length===LOOP_REPEATS&&te.every(c=>c===te[0]);if(e){De=true;const c=v[v.length-1];if(P)ge.push(LOOP_WARNING);else if(c)c.content=`${c.content}
9
+ ${JSON.stringify(h.params)}`,isError:true});continue}const _e=(0,_normalizeParams.aliasNote)(L.notes);const J=h.effect!=="read"?Ue.trailer(i,!P):"";if(P&&J)M(_idGrounding.UNSEEN_ID_ADVICE);const z=(0,_policy.describeCall)(n,h,i);const se=(0,_policy.decide)({descriptor:h,toolId:n,policy:x,isRelease:D,turnScope:j,params:i,tapLabels:ke.get(e.id)});const ue=a=>[{type:"tool-start",id:e.id,toolId:n,action:s,label:z,description:h.summary,params:i,effect:h.effect},{type:"tool-end",id:e.id,ok:false,summary:a,durationMs:0}];if(se.verdict==="refuse"){for(const a of ue("refused"))yield a;v.push({toolCallId:e.id,content:se.reason,isError:true});continue}const Ae=se.verdict==="needs-approval";if(ft&&!Ve&&(h.effect!=="read"||Ae)){yield*pt()}if(Xe&&(h.effect!=="read"||Ae)){for(const a of ue("declined"))yield a;v.push({toolCallId:e.id,content:j==="question"?_turnScope.QUESTION_DECLINED:B.get(e.id)===false?declinedResult(Q.get(e.id)):"Not run \u2014 the user declined another change in this same batch, so none of it was applied. Ask what they would prefer before proposing it again.",isError:true});continue}if(Ae){let a;if(B.has(e.id)){a=B.get(e.id)}else if(!se.turnScoped&&A?.has(`${n}.${s}`)){a=true;B.set(e.id,true)}else{yield{type:"approval-required",id:e.id,toolId:n,action:s,label:z,description:h.summary,reason:se.reason};const R=(0,_realNow.realNow)();const S=await readTargetDigest({toolId:n,action:s,params:i,dispatch:f,catalog:o});const E=readAnswer(Y?await Y({id:e.id,toolId:n,action:s,label:z,description:h.summary,reason:se.reason,params:i,targetDigest:S}):false);le+=(0,_realNow.realNow)()-R;a=E.approved;B.set(e.id,a);if(E.trust)A?.add(`${n}.${s}`);if(E.reason)Q.set(e.id,E.reason)}if(!a){for(const R of ue("declined"))yield R;v.push({toolCallId:e.id,content:j==="question"?_turnScope.QUESTION_DECLINED:declinedResult(Q.get(e.id)),isError:true});continue}}if(_askGate.ACQUISITION_CALLS.has(`${n}.${s}`))Me=true;if(n==="ask-buoy"&&s==="openProcedure")je=true;yield{type:"tool-start",id:e.id,toolId:n,action:s,label:z,description:h.summary,params:i,effect:h.effect};const Ze=(0,_realNow.realNow)();const et=await captureBefore(h,n,i,f);const $e=await captureStoreState(h,n,i,f);if(_?.aborted){for(const a of ue("stopped"))yield a;v.push({toolCallId:e.id,content:"Not run \u2014 the user pressed Stop before this call started.",isError:true});continue}const tt=(0,_policy.decide)({descriptor:h,toolId:n,policy:x,isRelease:D,turnScope:j,params:i,tapLabels:ke.get(e.id)});if(tt.verdict==="refuse"){for(const a of ue("refused"))yield a;v.push({toolCallId:e.id,content:tt.reason,isError:true});continue}try{let a=s===_snapshotReads.SNAPSHOT_ACTION?(0,_snapshotReads.projectSnapshot)(n,await requireSnapshot(m,n),i):n==="ask-buoy"?await runAskBuoyAction(s,g,f,K,i,F):await(Ke.get(e.id)??f(n,s,i));a=tapResult(n,s,a);const R=(0,_redact.redact)((0,_redact.stripSelfTraffic)(a));const S=reportsFailure(a);if(h.effect!=="read"&&!S)Be=true;const E=fullText(n==="highlight-updates"&&s==="describeScreen"&&!S?(0,_compactScreen.compactScreen)(R):R);const ie=K&&!S&&!(n==="ask-buoy"&&s==="retrieve")?K.stash({toolId:n,action:s,params:i,capturedAt:(0,_realNow.realNow)(),text:E}):void 0;const T=encodeResult(E,ie);Ue.add(E);const Ce=T.length>MAX_TRACE_RESULT_CHARS?`${T.slice(0,MAX_TRACE_RESULT_CHARS)}\u2026`:T;yield{type:"tool-end",id:e.id,ok:!S,summary:summarise(a),durationMs:(0,_realNow.realNow)()-Ze,result:Ce};const Oe=$e===void 0||S?void 0:await captureStoreState(h,n,i,f);if(h.effect!=="read"&&n!=="ask-buoy"&&!S){const Pe=g.noteExternalRevert(n,s,i);const rt=(0,_effectFor.effectFor)(n,h,i,a,et,{before:$e,after:Oe});if(rt&&!Pe){const nt=g.record(n,s,rt,st);if(nt)nt.callId=e.id}}const ot=S?void 0:(0,_receipts.projectReceipt)({toolId:n,action:s,params:i,result:R,before:$e??et,after:Oe,effect:h.effect});if(ot)yield{type:"block",block:ot,forToolCallId:e.id};const fe=h.effect!=="read"&&!S?await(0,_verify.verifyOutcome)({toolId:n,action:s,params:i,result:a,dispatch:f,readSnapshot:m,signal:_,after:Oe}):void 0;if(fe)yield{type:"tool-verified",id:e.id,verification:fe};if(P&&fe?.status==="failed")M(_verify.VERIFICATION_REPAIR);for(const Pe of T.match(at)??[])ve.add(Pe);v.push({toolCallId:e.id,content:T+ownedKeyNote(n,h,i,U,P?M:void 0)+_e+J+(fe?(0,_verify.verificationTrailer)(fe,!P):"")+(Je.has(e.id)?M(_textToolCalls.SALVAGE_NOTE):""),...ie?{ref:ie}:{}});if(!S&&n==="app"&&(s==="reloadApp"||s==="reload")){Ye=true}}catch(a){const R=a instanceof Error?a.message:String(a);yield{type:"tool-end",id:e.id,ok:false,summary:R,durationMs:(0,_realNow.realNow)()-Ze};v.push({toolCallId:e.id,content:`Failed: ${R}${J}`,isError:true})}}if(w.length){te.push(callSignature(w));if(te.length>LOOP_REPEATS)te.shift();const e=!Le&&te.length===LOOP_REPEATS&&te.every(c=>c===te[0]);if(e){Le=true;const c=v[v.length-1];if(P)be.push(LOOP_WARNING);else if(c)c.content=`${c.content}
10
10
 
11
- ${LOOP_WARNING}`}}f.push({role:"tool-results",results:v});if(ge.length)f.push(de([...new Set(ge)].join("\n\n"),true));if(Ne){yield{type:"awaiting-user",blockId:Ne};yield{type:"done",stopReason:"awaiting-user"};return f}if(Ye){yield{type:"done",stopReason:"realm-died"};return f}}if(_?.aborted){yield{type:"done",stopReason:"stopped"};return f}const oe=[];let Fe=false;let Se=false;const ce=[...f,de(STEP_CAP_WRAP_UP,qe())];const ct=G?{messages:ce}:(0,_historyBudget.budgetForRequest)(ce,he(),O.chars(ee),O.charsPerToken,g.liveCallIds());try{if(G&&!ze(ce))throw new Error(Re);if(G||P||pe.liveBlock==="append"||pe.liveBlock==="system-msg")f.push(ce[ce.length-1]);for await(const p of r.send({messages:ct.messages,system:d,systemVolatile:l,tools:V,toolChoice:"none",model:k,maxTokens:y,signal:_,meta:{askId:xe,round:X+1,attempt:1}})){if(p.type==="text")oe.push(p.delta);else if(p.type==="tool-call"||p.type==="error")Se=true;else if(p.type==="meter")yield{type:"meter",frame:p.frame};else if(p.type==="done"){if(p.outcome==="refused"||p.outcome==="context-limited"){yield{type:"error",message:p.outcome==="refused"?"Claude could not help with this request.":"Claude ran out of room for this turn. Please send a new message."};yield{type:"done",stopReason:"error"};return f}Fe=p.outcome==="completed";if(p.usage)yield{type:"usage",...p.usage,model:p.model}}}}catch{Se=true}if(_?.aborted){yield{type:"done",stopReason:"stopped"};return f}const Ge=oe.join("");if(Se||!Fe||!Ge.trim()||(0,_textToolCalls.couldBeToolCallEnvelope)(Ge)){const p=g.list().filter(E=>!it.has(E.id));oe.length=0;oe.push(["I ran out of steps. The job is not done.",...p.length?["These steps ran:",...p.map(E=>`- ${E.effect.label}${E.undoneAt?" (since undone)":""}`),"This list does not prove each change worked."]:[]].join("\n"))}let He=true;for(const p of oe){if(!p)continue;yield{type:"text",delta:p,...He&&ve?{breakBefore:true}:{}};He=false}f.push({role:"assistant",text:oe.join("")});yield{type:"block",block:{id:`cap${(0,_realNow.realNow)()}`,kind:"notice",tone:"warning",text:"I ran out of steps. The job is not done. Tap Continue to go on.",actions:[{label:"Continue",primary:true,send:CONTINUE_SEND}]}};yield{type:"done",stopReason:"step-cap"};return f}function ownedKeyNote(t,r,o,d,l){if(t!=="storage"||r.effect==="read")return"";if(!d||typeof o.key!=="string")return"";const k=d[o.key];if(!k)return"";const y=`
11
+ ${LOOP_WARNING}`}}u.push({role:"tool-results",results:v});if(be.length)u.push(de([...new Set(be)].join("\n\n"),true));if(Ie){yield{type:"awaiting-user",blockId:Ie};yield{type:"done",stopReason:"awaiting-user"};return u}if(Ye){yield{type:"text",delta:RELOADING_TEXT,...ye?{breakBefore:true}:{}};u.push({role:"assistant",text:RELOADING_TEXT});yield{type:"done",stopReason:"realm-died"};return u}}if(_?.aborted){yield{type:"done",stopReason:"stopped"};return u}const oe=[];let Fe=false;let Se=false;const ce=[...u,de(STEP_CAP_WRAP_UP,qe())];const ct=G?{messages:ce}:(0,_historyBudget.budgetForRequest)(ce,he(),O.chars(ee),O.charsPerToken,g.liveCallIds());try{if(G&&!ze(ce))throw new Error(Re);if(G||P||pe.liveBlock==="append"||pe.liveBlock==="system-msg")u.push(ce[ce.length-1]);for await(const p of r.send({messages:ct.messages,system:d,systemVolatile:l,tools:V,toolChoice:"none",model:k,maxTokens:y,signal:_,meta:{askId:xe,round:X+1,attempt:1}})){if(p.type==="text")oe.push(p.delta);else if(p.type==="tool-call"||p.type==="error")Se=true;else if(p.type==="meter")yield{type:"meter",frame:p.frame};else if(p.type==="done"){if(p.outcome==="refused"||p.outcome==="context-limited"){yield{type:"error",message:p.outcome==="refused"?"Claude could not help with this request.":"Claude ran out of room for this turn. Please send a new message."};yield{type:"done",stopReason:"error"};return u}Fe=p.outcome==="completed";if(p.usage)yield{type:"usage",...p.usage,model:p.model}}}}catch{Se=true}if(_?.aborted){yield{type:"done",stopReason:"stopped"};return u}const Ge=oe.join("");if(Se||!Fe||!Ge.trim()||(0,_textToolCalls.couldBeToolCallEnvelope)(Ge)){const p=g.list().filter(N=>!it.has(N.id));oe.length=0;oe.push(["I ran out of steps. The job is not done.",...p.length?["These steps ran:",...p.map(N=>`- ${N.effect.label}${N.undoneAt?" (since undone)":""}`),"This list does not prove each change worked."]:[]].join("\n"))}let He=true;for(const p of oe){if(!p)continue;yield{type:"text",delta:p,...He&&ye?{breakBefore:true}:{}};He=false}u.push({role:"assistant",text:oe.join("")});yield{type:"block",block:{id:`cap${(0,_realNow.realNow)()}`,kind:"notice",tone:"warning",text:"I ran out of steps. The job is not done. Tap Continue to go on.",actions:[{label:"Continue",primary:true,send:CONTINUE_SEND}]}};yield{type:"done",stopReason:"step-cap"};return u}function ownedKeyNote(t,r,o,d,l){if(t!=="storage"||r.effect==="read")return"";if(!d||typeof o.key!=="string")return"";const k=d[o.key];if(!k)return"";const y=`
12
12
 
13
- [Buoy] This wrote to disk, but "${o.key}" is the saved copy of the live "${k}" store, so nothing on screen has changed \u2014 the app read that key once at startup and has held the state in memory since.`;if(l){l("Use zustand.rehydrate for the store named in the result to load the saved value. Use zustand.setState to change the live store. If the change was for the next app launch, no more work is needed.");return y}return y+` Call zustand.rehydrate({"storeName":"${k}"}) to make the app pick this up, or use zustand.setState next time to change the store directly. If you meant to set the value for the app's next launch, this is already done and no further action is needed.`}async function readTargetDigest(t){const r=findDescriptor(t.catalog??_catalog.CATALOG,t.toolId,t.action);if(!r||r.effect==="read")return void 0;const o=await captureStoreState(r,t.toolId,t.params,t.dispatch);if(o!==void 0)return(0,_digest.digestOf)(o);const d=await captureBefore(r,t.toolId,t.params,t.dispatch);if(d!==void 0)return(0,_digest.digestOf)(d);return void 0}async function runGatedAction(t){const{toolId:r,action:o,dispatch:d,ledger:l,policy:k,isRelease:y}=t;const u=t.catalog??_catalog.CATALOG;const m=findDescriptor(u,r,o);if(!m){return{ok:false,error:`${r}.${o} is not in Buoy's catalog.`}}const U=(0,_normalizeParams.normalizeParams)(r,o,t.params??{});const g=(0,_validateParams.applyDefaults)(U.params,m.params);if(emptyTap(r,o,g))return{ok:false,error:EMPTY_TAP_ERROR};const x=(0,_validateParams.validateParams)(g,m.params);if(!x.ok){return{ok:false,error:x.errors.join("\n")}}const M=(0,_policy.decide)({descriptor:m,toolId:r,policy:k,isRelease:y});if(M.verdict==="refuse"){return{ok:false,error:M.reason}}const Y=await captureBefore(m,r,g,d);const _=await captureStoreState(m,r,g,d);const K=(0,_policy.decide)({descriptor:m,toolId:r,policy:k,isRelease:y});if(K.verdict==="refuse"){return{ok:false,error:K.reason}}try{let A=r==="ask-buoy"?await runAskBuoyAction(o,l,d,void 0,g):await d(r,o,g);A=tapResult(r,o,A);if(reportsFailure(A)){const F=A.error;return{ok:false,error:typeof F==="string"?F:"The tool refused this."}}if(m.effect!=="read"&&r!=="ask-buoy"){const F=l.noteExternalRevert(r,o,g);const Q=await captureStoreState(m,r,g,d);const O=(0,_effectFor.effectFor)(r,m,g,A,Y,{before:_,after:Q});if(O&&!F)l.record(r,o,O)}return{ok:true,result:A}}catch(A){return{ok:false,error:A instanceof Error?A.message:String(A)}}}async function runAskBuoyAction(t,r,o,d,l,k){if(t==="retrieve"){return(0,_retrieve.retrieveEvidence)(d,l??{})}if(t==="openProcedure"){const y=typeof l?.id==="string"?l.id:"";const u=k?.find(m=>m.id===y);if(!u){const m=(k??[]).map(U=>U.id);return{ok:false,error:m.length?`No procedure "${y}". This app's procedures: ${m.join(", ")}.`:"This app has no procedures written for it."}}return{id:u.id,title:u.title,...u.version?{version:u.version}:{},...u.requires?.length?{requires:u.requires}:{},body:u.body,note:"Follow these steps with the ordinary tools. Every write still goes through the same policy, approval and undo as any other call; a step that is refused stays refused."}}if(t==="listChanges"){const y=r.list().filter(u=>!u.undoneAt).map(u=>({id:u.id,toolId:u.toolId,action:u.action,kind:u.effect.kind,label:u.effect.label,reversible:(0,_ledger.isReversible)(u.effect)}));return{changes:y,returned:y.length}}if(t==="undoChange"){const y=typeof l?.id==="string"?l.id:"";const u=r.list().find(U=>U.id===y);if(!u){const U=r.list().filter(g=>!g.undoneAt).map(g=>g.id);return{ok:false,error:`No change with id "${y}". Call listChanges for the current ids${U.length?` (${U.join(", ")})`:""}.`}}if(u.undoneAt)return{ok:false,error:`"${u.effect.label}" was already undone.`};if(!(0,_ledger.isReversible)(u.effect)){return{ok:false,error:`"${u.effect.label}" can't be undone automatically \u2014 it is permanent.`}}const m=await r.revertOne(u,o);return m?{ok:false,error:m}:{ok:true,undone:{id:u.id,label:u.effect.label}}}if(t==="undoAll"){const y=await r.revertAll(o);return{ok:y.failed.length===0,...y}}throw new Error(`Unknown ask-buoy action "${t}"`)}async function requireSnapshot(t,r){if(!t){throw new Error(`This app cannot read ${r}'s snapshot \u2014 Buoy's tool registry is not published here.`)}return await t(r)}async function captureStoreState(t,r,o,d){if(r==="zustand"&&t.action==="setState"){if(typeof o.storeName!=="string")return void 0;try{return await d(r,"getStoreState",{storeName:o.storeName})}catch{return void 0}}if(r==="query"&&t.action==="setQueryData"){const l=typeof o.queryHash==="string"?o.queryHash:Array.isArray(o.queryKey)?(0,_normalizeParams.hashQueryKey)(o.queryKey):void 0;if(!l)return void 0;try{return await d(r,"getQueryData",{queryHash:l})}catch{return void 0}}return void 0}async function captureBefore(t,r,o,d){if(t.effect==="read")return void 0;if(r==="network")return captureRuleSwitch(t,o,d);if(r!=="storage"||typeof o.key!=="string")return void 0;const l=t.action.startsWith("async.")?"async.getItem":t.action.startsWith("mmkv.")?"mmkv.get":void 0;if(!l)return void 0;const k={key:o.key};if(l==="mmkv.get"){if(typeof o.instanceId!=="string")return void 0;k.instanceId=o.instanceId}try{const y=await d(r,l,k);const u=y&&typeof y==="object"?y:void 0;if(u?.found===false)return void 0;const m=u?u.value:y;return{had:m!==void 0&&m!==null,value:m??void 0}}catch{return void 0}}async function captureRuleSwitch(t,r,o){if(t.action!=="setOverrideRuleEnabled"&&t.action!=="setOverridesEnabled"){return void 0}try{const d=await o("network","listOverrideRules",{});if(!d||typeof d!=="object")return void 0;if(t.action==="setOverridesEnabled"){return{had:true,value:String(d.enabled!==false)}}const l=(d.rules??[]).find(k=>k&&k.id===r.id);if(!l)return void 0;return{had:true,value:String(l.enabled!==false)}}catch{return void 0}}function newAskId(){const t="abcdefghijklmnopqrstuvwxyz0123456789";let r="ask_";for(let o=0;o<20;o++)r+=t[Math.floor(Math.random()*t.length)];return r}
13
+ [Buoy] This wrote to disk, but "${o.key}" is the saved copy of the live "${k}" store, so nothing on screen has changed \u2014 the app read that key once at startup and has held the state in memory since.`;if(l){l("Use zustand.rehydrate for the store named in the result to load the saved value. Use zustand.setState to change the live store. If the change was for the next app launch, no more work is needed.");return y}return y+` Call zustand.rehydrate({"storeName":"${k}"}) to make the app pick this up, or use zustand.setState next time to change the store directly. If you meant to set the value for the app's next launch, this is already done and no further action is needed.`}async function readTargetDigest(t){const r=findDescriptor(t.catalog??_catalog.CATALOG,t.toolId,t.action);if(!r||r.effect==="read")return void 0;const o=await captureStoreState(r,t.toolId,t.params,t.dispatch);if(o!==void 0)return(0,_digest.digestOf)(o);const d=await captureBefore(r,t.toolId,t.params,t.dispatch);if(d!==void 0)return(0,_digest.digestOf)(d);return void 0}async function runGatedAction(t){const{toolId:r,action:o,dispatch:d,ledger:l,policy:k,isRelease:y}=t;const f=t.catalog??_catalog.CATALOG;const m=findDescriptor(f,r,o);if(!m){return{ok:false,error:`${r}.${o} is not in Buoy's catalog.`}}const U=(0,_normalizeParams.normalizeParams)(r,o,t.params??{});const g=(0,_validateParams.applyDefaults)(U.params,m.params);if(emptyTap(r,o,g))return{ok:false,error:EMPTY_TAP_ERROR};const x=(0,_validateParams.validateParams)(g,m.params);if(!x.ok){return{ok:false,error:x.errors.join("\n")}}const D=(0,_policy.decide)({descriptor:m,toolId:r,policy:k,isRelease:y});if(D.verdict==="refuse"){return{ok:false,error:D.reason}}const Y=await captureBefore(m,r,g,d);const _=await captureStoreState(m,r,g,d);const K=(0,_policy.decide)({descriptor:m,toolId:r,policy:k,isRelease:y});if(K.verdict==="refuse"){return{ok:false,error:K.reason}}try{let A=r==="ask-buoy"?await runAskBuoyAction(o,l,d,void 0,g):await d(r,o,g);A=tapResult(r,o,A);if(reportsFailure(A)){const F=A.error;return{ok:false,error:typeof F==="string"?F:"The tool refused this."}}if(m.effect!=="read"&&r!=="ask-buoy"){const F=l.noteExternalRevert(r,o,g);const Q=await captureStoreState(m,r,g,d);const O=(0,_effectFor.effectFor)(r,m,g,A,Y,{before:_,after:Q});if(O&&!F)l.record(r,o,O)}return{ok:true,result:A}}catch(A){return{ok:false,error:A instanceof Error?A.message:String(A)}}}async function runAskBuoyAction(t,r,o,d,l,k){if(t==="retrieve"){return(0,_retrieve.retrieveEvidence)(d,l??{})}if(t==="openProcedure"){const y=typeof l?.id==="string"?l.id:"";const f=k?.find(m=>m.id===y);if(!f){const m=(k??[]).map(U=>U.id);return{ok:false,error:m.length?`No procedure "${y}". This app's procedures: ${m.join(", ")}.`:"This app has no procedures written for it."}}return{id:f.id,title:f.title,...f.version?{version:f.version}:{},...f.requires?.length?{requires:f.requires}:{},body:f.body,note:"Follow these steps with the ordinary tools. Every write still goes through the same policy, approval and undo as any other call; a step that is refused stays refused."}}if(t==="listChanges"){const y=r.list().filter(f=>!f.undoneAt).map(f=>({id:f.id,toolId:f.toolId,action:f.action,kind:f.effect.kind,label:f.effect.label,reversible:(0,_ledger.isReversible)(f.effect)}));return{changes:y,returned:y.length}}if(t==="undoChange"){const y=typeof l?.id==="string"?l.id:"";const f=r.list().find(U=>U.id===y);if(!f){const U=r.list().filter(g=>!g.undoneAt).map(g=>g.id);return{ok:false,error:`No change with id "${y}". Call listChanges for the current ids${U.length?` (${U.join(", ")})`:""}.`}}if(f.undoneAt)return{ok:false,error:`"${f.effect.label}" was already undone.`};if(!(0,_ledger.isReversible)(f.effect)){return{ok:false,error:`"${f.effect.label}" can't be undone automatically \u2014 it is permanent.`}}const m=await r.revertOne(f,o);return m?{ok:false,error:m}:{ok:true,undone:{id:f.id,label:f.effect.label}}}if(t==="undoAll"){const y=await r.revertAll(o);return{ok:y.failed.length===0,...y}}throw new Error(`Unknown ask-buoy action "${t}"`)}async function requireSnapshot(t,r){if(!t){throw new Error(`This app cannot read ${r}'s snapshot \u2014 Buoy's tool registry is not published here.`)}return await t(r)}async function captureStoreState(t,r,o,d){if(r==="zustand"&&t.action==="setState"){if(typeof o.storeName!=="string")return void 0;try{return await d(r,"getStoreState",{storeName:o.storeName})}catch{return void 0}}if(r==="query"&&t.action==="setQueryData"){const l=typeof o.queryHash==="string"?o.queryHash:Array.isArray(o.queryKey)?(0,_normalizeParams.hashQueryKey)(o.queryKey):void 0;if(!l)return void 0;try{return await d(r,"getQueryData",{queryHash:l})}catch{return void 0}}return void 0}async function captureBefore(t,r,o,d){if(t.effect==="read")return void 0;if(r==="network")return captureRuleSwitch(t,o,d);if(r!=="storage"||typeof o.key!=="string")return void 0;const l=t.action.startsWith("async.")?"async.getItem":t.action.startsWith("mmkv.")?"mmkv.get":void 0;if(!l)return void 0;const k={key:o.key};if(l==="mmkv.get"){if(typeof o.instanceId!=="string")return void 0;k.instanceId=o.instanceId}try{const y=await d(r,l,k);const f=y&&typeof y==="object"?y:void 0;if(f?.found===false)return void 0;const m=f?f.value:y;return{had:m!==void 0&&m!==null,value:m??void 0}}catch{return void 0}}async function captureRuleSwitch(t,r,o){if(t.action!=="setOverrideRuleEnabled"&&t.action!=="setOverridesEnabled"){return void 0}try{const d=await o("network","listOverrideRules",{});if(!d||typeof d!=="object")return void 0;if(t.action==="setOverridesEnabled"){return{had:true,value:String(d.enabled!==false)}}const l=(d.rules??[]).find(k=>k&&k.id===r.id);if(!l)return void 0;return{had:true,value:String(l.enabled!==false)}}catch{return void 0}}function newAskId(){const t="abcdefghijklmnopqrstuvwxyz0123456789";let r="ask_";for(let o=0;o<20;o++)r+=t[Math.floor(Math.random()*t.length)];return r}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.buildLiveBlock=buildLiveBlock;exports.buildSystemPrompt=buildSystemPrompt;exports.listableProcedures=listableProcedures;function buildSystemPrompt(a){const{context:e,isRelease:n,readOnly:r,readOnlySource:s,requireApproval:i,approvalsBypassed:h,appName:d,platform:l,availableToolIds:c}=a;const t=[];t.push(`You are Ask Buoy, an assistant embedded inside ${d?`the ${d} app`:"a React Native app"} via Buoy devtools${l?` on ${l}`:""}.
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.buildLiveBlock=buildLiveBlock;exports.buildSystemPrompt=buildSystemPrompt;exports.listableProcedures=listableProcedures;function buildSystemPrompt(a){const{context:e,isRelease:n,readOnly:r,readOnlySource:s,requireApproval:i,approvalsBypassed:h,appName:d,platform:l,availableToolIds:c}=a;const t=[];t.push(`You are Ask Buoy, an assistant embedded inside ${d?`the ${d} app`:"this app"} via Buoy devtools${l?` on ${l}`:""}.
2
2
 
3
3
  The people who talk to you are usually NOT developers \u2014 QA testers, customer support, product managers. Write like you are talking to a smart colleague who does not read code. Never show raw JSON, stack traces, or internal ids unless they ask. Say what you found and what it means.
4
4