agent-afk 5.191.5 → 5.191.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var rI=Object.defineProperty;var ne=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ns=(t,e)=>{for(var n in e)rI(t,n,{get:e[n],enumerable:!0})};function jr(t){return Hr.find(e=>e.name===t)}function Us(t){return process.env[t]!==void 0}var bm=ne(()=>{"use strict";I()});var Hr,wm,b,I=ne(()=>{"use strict";bm();Hr=[{name:"AFK_COMPACT_KEEP_LAST_TURNS",description:"Number of recent turns the compactor keeps verbatim during /compact. Default tuned in compact-handler.ts.",type:"number",required:!1,example:"6",category:"model"},{name:"AFK_COMPACT_MODEL",description:"Override the model used by the /compact summarizer. Falls back to a cheap default (haiku-class).",type:"string",required:!1,example:"claude-haiku-4-5",category:"model"},{name:"AFK_COMPACT_SHRINK_FRACTION",description:"Context-fullness fraction (0\u20131, exclusive) at/above which /compact and auto-compaction relax the keep-window so a short-but-full session (few turns, huge tool exchanges) can still be summarized instead of no-oping on turn count. Default 0.7 (see shared/compaction.ts DEFAULT_COMPACT_SHRINK_THRESHOLD).",type:"number",required:!1,example:"0.8",category:"model"},{name:"AFK_DEFAULT_SUBAGENT_MODEL",description:"Override the default model used when a subagent is dispatched without an explicit model.",type:"string",required:!1,example:"sonnet",category:"model"},{name:"AFK_DIAGNOSE_BASELINE",description:"Kill switch for /diagnose reproducer baseline execution. When set to '0', the /diagnose skill skips executing the detected reproducer command for a ground-truth baseline; default enabled (runs). Set to '0' to disable.",type:"boolean",required:!1,default:"1",example:"0",category:"debug"},{name:"AFK_DISABLE_PROMPT_CACHE",description:"Disable Anthropic prompt caching when set to 1/true/yes/on. Unset = caching enabled.",type:"boolean",required:!1,default:"0",example:"1",category:"model"},{name:"AFK_DISABLE_BASH_INTERPRETER_GUARD",description:"Skip ONLY the bash interpreter-eval denylist (python -c, node -e, sh -c, ...) when set to 1, leaving the rest of path-approval intact. Applies on interactive surfaces (REPL/Telegram), where the denylist is active but your workflow legitimately runs interpreter one-liners. The restricted-root substring check is unaffected. Default: denylist active on interactive surfaces; headless already fails open (opt in with AFK_FORCE_BASH_INTERPRETER_GUARD=1). To disable all of path-approval + bash restriction instead, use AFK_DISABLE_PATH_APPROVAL=1.",type:"boolean",required:!1,default:"0",example:"1",category:"process"},{name:"AFK_DISABLE_PATH_APPROVAL",description:"Skip the path-approval + bash-restriction hooks entirely when set to 1. Use for headless flows that need wide-open file access (CI scripts, batch jobs). Default: hooks enabled. Note: on headless surfaces (afk chat, daemon) no grant manager is wired, so the interpreter denylist (python -c, node -e, sh -c, ...) fails OPEN by default \u2014 opt headless flows into it with AFK_FORCE_BASH_INTERPRETER_GUARD=1, or set this var to 1 to disable all of path-approval.",type:"boolean",required:!1,default:"0",example:"1",category:"process"},{name:"AFK_FORCE_BASH_INTERPRETER_GUARD",description:"Apply the bash interpreter-eval denylist (python -c, node -e, sh -c, ...) even on headless surfaces (afk chat, daemon) where no grant manager is wired. By default the denylist fires only on interactive surfaces (REPL/Telegram), failing open on headless so legitimate automation is not hard-blocked with no recourse. Set to 1 to opt headless flows back into the guard. Overridden by AFK_DISABLE_BASH_INTERPRETER_GUARD=1. Default: off (headless fails open).",type:"boolean",required:!1,default:"0",example:"1",category:"process"},{name:"AFK_EFFORT",description:"Effort hint guiding adaptive-thinking depth, forwarded as Anthropic output_config.effort (model-gated; ignored where unsupported). Accepts low | medium | high | xhigh | max.",type:"string",required:!1,example:"medium",category:"model"},{name:"AFK_MAX_BUDGET_USD",description:"Cumulative USD budget ceiling for the session. Aborts the turn when the running cost crosses this.",type:"number",required:!1,default:"5.00",example:"10.00",category:"model"},{name:"AFK_MAX_CONCURRENT_SAFE_TOOL_CALLS",description:"Maximum concurrency-safe tool calls run simultaneously within one dispatcher batch. Default 8; accepted range 1-32; out-of-range or unparseable input falls back to the default.",type:"number",required:!1,default:"8",example:"4",category:"model"},{name:"AFK_MAX_CONCURRENT_SUBAGENT_CALLS",description:"Maximum subagent calls run simultaneously from one compose/DAG layer or skill wave. Default 8; accepted range 1-32; out-of-range or unparseable input falls back to the default.",type:"number",required:!1,default:"8",example:"2",category:"model"},{name:"AFK_MAX_CONCURRENT_BACKGROUND_JOBS",description:"Maximum background subagent jobs running simultaneously in one registry. Default 10; accepted range 1-64; out-of-range or unparseable input falls back to the default.",type:"number",required:!1,default:"10",example:"5",category:"model"},{name:"AFK_MAX_NESTING_DEPTH",description:"Maximum sub-agent/skill nesting depth; 0 disables nested delegation entirely (the agent, skill, AND compose tools all refuse). A top-level session is depth 0, so the default 3 permits three generations of forked descendants (depth 1 \u2192 2 \u2192 3) and refuses the agent and skill tools at depth 3. Resolved once at the root of each session and propagated down through child AgentConfig, so descendants inherit the root value rather than re-reading the environment. Raise with care: depth is a fan-out exponent (a width-N wave at depth D reaches ~N^D concurrent children), so values above 4 invite provider rate-limit (429) cascades. Accepted range 0-6; unset, empty, unparseable, negative, or out-of-range input falls back to the default. An explicit programmatic maxDepth (SubagentExecutorContext / SkillExecutorContext) still wins.",type:"number",required:!1,default:"3",example:"2",category:"model"},{name:"AFK_MAX_OUTPUT_TOKENS",description:"Cap on output tokens per turn. When unset, falls back to the model output ceiling (AFK's own per-model limit, 64k\u2013128k \u2014 NOT a small provider default), so every request advertises the full ceiling by default. An over-ceiling value is clamped down with a warning.",type:"number",required:!1,example:"8192",category:"model"},{name:"AFK_MAX_TOKENS",description:"Deprecated and inert: not read by the generation path. Use AFK_MAX_OUTPUT_TOKENS (or --max-output-tokens) to cap per-response output tokens; falls back to the model output ceiling when unset.",type:"number",required:!1,default:"4096",example:"8192",category:"model"},{name:"AFK_MAX_TOOL_USE_ITERATIONS",description:"Opt-in ceiling on tool-use rounds per turn for TOP-LEVEL (non-subagent) sessions, on both providers. Mirrors the maxToolUseIterations config key / max_tool_use_iterations tool param. Unset, non-numeric, or <=0 means unlimited (the default \u2014 zero behavior change): a top-level turn ends only when the model stops calling tools, the abort signal fires, the provider errors, or the dollar budget trips. A positive integer N makes top-level turns wind down gracefully after N tool rounds (one tools-stripped final round). An explicit config/CLI value wins over this env default. Does NOT affect subagent forks \u2014 they keep their own non-zero anti-hang default (SUBAGENT_DEFAULT_MAX_TOOL_USE_ITERATIONS) regardless of this var.",type:"number",required:!1,default:"0",example:"150",category:"model"},{name:"AFK_MEMORY_EVIDENCE_GATE",description:'Opt-in (set to 1) evidence gate for durable memory writes. When enabled, a codebase fact (memory_update category "convention") stored without an `evidence` citation is recalled as [unverified], and memory_search results carry a verification verdict. User preferences and agent reflections are never gated. Default off \u2014 memory behaves identically to legacy when unset.',type:"boolean",required:!1,example:"1",category:"misc"},{name:"AFK_MICROCOMPACT_KEEP_LAST",description:"Number of the most-recent tool_result blocks that tool-result microcompaction keeps intact regardless of size, so the agent does not lose the tool output it is actively reasoning over. Older results are the safe ones to trim. Default 4 (see shared/compaction.ts DEFAULT_MICROCOMPACT_KEEP_LAST). Values <= 0 protect nothing.",type:"number",required:!1,default:"4",example:"3",category:"model"},{name:"AFK_MICROCOMPACT_TOOL_RESULT_BYTES",description:"Byte threshold (tool_result content length) at/above which a tool_result block becomes a microcompaction candidate. When /compact and auto-compaction would otherwise no-op on a short-but-full session, microcompaction clears large/old tool_result CONTENT in place (largest first) \u2014 replacing it with a short placeholder, never removing the block \u2014 to reclaim context deterministically (no LLM call). Blocks below this size are left intact. Default 2048 (see shared/compaction.ts DEFAULT_MICROCOMPACT_TOOL_RESULT_BYTES).",type:"number",required:!1,default:"2048",example:"4096",category:"model"},{name:"AFK_MODEL",description:"Default model for agent turns. Accepts slot names (local, small, medium, large), fixed-identity aliases (opus, sonnet, haiku, fable), or full model IDs. Migration: AFK_MODEL=sonnet now pins the fixed Sonnet identity rather than following a rebound medium tier.",type:"string",required:!1,default:"medium",example:"claude-opus-5",category:"model"},{name:"AFK_MODEL_TTFB_TIMEOUT_MS",description:"Per-ROUND time-to-first-token budget (ms) for the anthropic-direct streaming loop. Bounds how long a round may stall BEFORE its first streamed CONTENT token (a text/thinking delta or tool_use); the connection-level message_start and keep-alive pings do NOT count. Once a content token streams, the timer is cleared and the rest of the response is governed instead by the progress-aware AFK_MODEL_STALL_TIMEOUT_MS window, so a normal slow call (below the bound) and any actively-streaming extended-thinking response are never aborted. The budget is divided into 3 shorter first-byte ATTEMPTS (each ~2/3 of this value, so the worst-case wall time per round is unchanged from the previous 2-attempt regime while a transient stall gets 3 chances instead of 2). NOTE: a request whose FIRST token takes longer than the per-attempt bound \u2014 e.g. a very large opus_1m prefill \u2014 is aborted and re-driven, then surfaces as an error once the budget is spent (raise this value or set 0 for such workloads); this trims the degrading-call tail instead of a silent ~10-min hang on the SDK default. Default 180000 (180s \u2248 2\xD7 the measured p99 ttfb), i.e. 3 \xD7 120s. Set to 0 to disable.",type:"number",required:!1,default:"180000",example:"120000",category:"model"},{name:"AFK_MODEL_STALL_TIMEOUT_MS",description:"Progress-aware POST-first-byte stall window (ms) for the anthropic-direct streaming loop. Bounds how long a stream that has ALREADY produced content may then go completely silent. Every streamed output event resets the window, so this is NOT a total-round cap: a legitimately long, actively-streaming round (large code emission, extended thinking) survives indefinitely, while a stream wedged mid-flight is aborted and surfaces as a real terminal error instead of hanging. Complements AFK_MODEL_TTFB_TIMEOUT_MS, which governs only the window BEFORE the first token; this one takes over after it. Default 1200000 (20min) \u2014 above the 18.5min maximum post-first-byte stream duration observed across 86,076 rounds in 12,381 local traces (p99 122s, p99.9 234s), so no healthy round trips it. Set to 0 to disable (issue #762).",type:"number",required:!1,default:"1200000",example:"600000",category:"model"},{name:"AFK_SUBAGENT_TIMEOUT_MS",description:"Foreground forked-subagent wall-clock budget in ms; 0 disables the cap; explicit per-fork config.timeoutMs and the 60-min background mode still win. Bounds how long a single forked child turn may run before `withTimeout` aborts its controller (cascading through the AbortGraph to descendants) and the parent receives a legible TimeoutError tool_result instead of hanging. Default 2700000 (45 min \u2248 headroom over the longest healthy review/research agent observed in production). Unset, empty, or unparseable input falls back to the default; a negative value is treated as invalid and also falls back. Set to 0 to opt a whole session back into unbounded child turns. Does NOT affect the background dispatch budget (SUBAGENT_BACKGROUND_TIMEOUT_MS) or a per-fork config.timeoutMs \u2014 both take precedence.",type:"number",required:!1,default:"2700000",example:"3600000",category:"model"},{name:"AFK_SUBAGENT_IDLE_TIMEOUT_MS",description:"Forked-subagent progress-aware idle-watchdog window in ms; 0 disables the watchdog; an explicit per-fork config.idleTimeoutMs still wins. Fires when a forked child produces no observable output event for this window, aborting the same controller the wall-clock timeout targets so partial output is preserved and the run classifies as a failure. This is distinct from AFK_SUBAGENT_TIMEOUT_MS, the blunt wall-clock that bounds total turn time: the idle watchdog is the tighter first-to-fire bound and never fires while the stream is legitimately parked on a provider-communicated backoff (OAuth pause, or a rate-limit event carrying a retry-after), extending the deadline for the pause window instead. Default 480000 (8 min) clears the worst-case transient-429 backoff the watchdog is currently blind to (about 363s) with roughly 2 min of margin, while staying materially tighter than the 45-min wall-clock. Unset, empty, or unparseable input falls back to the default; a negative value is treated as invalid and also falls back. Set to 0 to disable the idle watchdog for a whole session (the wall-clock still applies). v1 applies to forked sub-agent turns only, not top-level or daemon sessions.",type:"number",required:!1,default:"480000",example:"300000",category:"model"},{name:"AFK_VISION_MODELS",description:'Comma-separated override for image (vision) capability detection on the openai-compatible provider. Each token force-enables a model id by exact or substring match (e.g. "qwen2.5-vl" matches a local VL id); prefix a token with "!" to force-disable. Use to send images to a local vision-language model AFK does not recognise by name, or to blacklist a mis-detected id. Built-in detection already covers gpt-4o/4.1/5.x, o1/o3/o4-mini, Claude, and common VL families.',type:"string",required:!1,example:"qwen2.5-vl,!gpt-4o-mini",category:"model"},{name:"AFK_MODEL_LOCAL",description:'Bind the "local" capability tier (cheapest/fastest, user-configured) to a model id. Overrides afk.config.json models.local. Point at a local Ollama, LM Studio, or any OpenAI-compatible shim.',type:"string",required:!1,example:"llama3.2:3b",category:"model"},{name:"AFK_MODEL_LOCAL_API_KEY",description:'Per-slot API key for the "local" tier. Overrides global credentials for this tier only.',type:"string",required:!1,category:"model",secret:!0},{name:"AFK_MODEL_LOCAL_BASE_URL",description:'Per-slot endpoint base URL for the "local" tier. Anthropic Messages base or OpenAI-compatible base per the tier provider.',type:"string",required:!1,example:"http://localhost:11434/v1",category:"model"},{name:"AFK_MODEL_LARGE",description:'Bind the "large" capability tier (most capable) to a model id/alias. Overrides afk.config.json models.large.',type:"string",required:!1,example:"claude-opus-5",category:"model"},{name:"AFK_MODEL_LARGE_API_KEY",description:'Per-slot API key for the "large" tier (Stage 2). Overrides global credentials for this tier only.',type:"string",required:!1,category:"model",secret:!0},{name:"AFK_MODEL_LARGE_BASE_URL",description:'Per-slot endpoint base URL for the "large" tier (Stage 2). Anthropic Messages base or OpenAI-compatible base per the tier provider.',type:"string",required:!1,example:"http://localhost:8080/v1",category:"model"},{name:"AFK_MODEL_MEDIUM",description:'Bind the "medium" capability tier (general-use) to a model id/alias. Overrides afk.config.json models.medium.',type:"string",required:!1,example:"claude-sonnet-5",category:"model"},{name:"AFK_MODEL_MEDIUM_API_KEY",description:'Per-slot API key for the "medium" tier (Stage 2). Overrides global credentials for this tier only.',type:"string",required:!1,category:"model",secret:!0},{name:"AFK_MODEL_MEDIUM_BASE_URL",description:'Per-slot endpoint base URL for the "medium" tier (Stage 2). Anthropic Messages base or OpenAI-compatible base per the tier provider.',type:"string",required:!1,example:"http://localhost:8080/v1",category:"model"},{name:"AFK_MODEL_SMALL",description:'Bind the "small" capability tier (cheap/fast) to a model id/alias. Overrides afk.config.json models.small.',type:"string",required:!1,example:"gpt-4o-mini",category:"model"},{name:"AFK_MODEL_SMALL_API_KEY",description:'Per-slot API key for the "small" tier (Stage 2). Overrides global credentials for this tier only.',type:"string",required:!1,category:"model",secret:!0},{name:"AFK_MODEL_SMALL_BASE_URL",description:'Per-slot endpoint base URL for the "small" tier (Stage 2). Anthropic Messages base or OpenAI-compatible base per the tier provider.',type:"string",required:!1,example:"http://localhost:8080/v1",category:"model"},{name:"AFK_OVERLOAD_PAUSE_MS",description:"Wall-clock ceiling (ms) for the bounded pause after a mid-stream overload (529) exhausts its retry budget. Overrides the per-surface default for ALL surfaces: 0 disables the pause (fail fast). Interactive surfaces (cli/repl/telegram) default to 600000; daemon/cron default to 0 so an always-on runner never silently parks on upstream capacity.",type:"number",required:!1,example:"600000",category:"model"},{name:"AFK_PROMPT_CACHE_TTL",description:"TTL for Anthropic prompt-cache blocks. Accepts 5m or 1h.",type:"string",required:!1,default:"1h",example:"1h",category:"model"},{name:"AFK_SUGGEST_ENABLED",description:"Enable the LLM-backed ghost-text suggestion tier in the interactive REPL. Set to 1/true/yes/on to activate. Off by default.",type:"boolean",required:!1,category:"model"},{name:"AFK_SUGGEST_PROMPT",description:"Enable LLM-generated empty-prompt suggestions \u2014 a proposed next action shown as ghost text when the prompt is blank, accepted with Tab or Right-arrow. Fires only after a turn has completed in the session: the startup prompt (and the prompt right after /clear) is left clean because there is no session context to ground a proposal in. Set to 1/true/yes/on to activate. Off by default. Requires AFK_SUGGEST_ENABLED (it reuses the same suggestion model and provider).",type:"boolean",required:!1,category:"model"},{name:"AFK_SUGGEST_GHOST",description:"Enable REPL ghost-text inline suggestions (Tier-1 history/dropdown + optional Tier-2 LLM). 1 = on (default), 0 = off. Set 0/false/off/no to disable all ghost text. Tier-2 LLM is separately gated by AFK_SUGGEST_ENABLED.",type:"boolean",required:!1,default:"1",example:"0",category:"model"},{name:"AFK_SUGGEST_MODEL",description:"Override the small model used for REPL ghost-text suggestions. Falls back to AFK_COMPACT_MODEL or haiku-class for anthropic, or the session model for other providers.",type:"string",required:!1,category:"model"},{name:"AFK_TASK_BUDGET",description:"Per-task token budget ceiling. Aborts when cumulative usage would exceed it.",type:"number",required:!1,default:"100000",example:"200000",category:"model"},{name:"AFK_TEMPERATURE",description:"Numeric temperature override for model sampling. Provider default if unset.",type:"number",required:!1,example:"0.7",category:"model"},{name:"AFK_THINKING",description:"Extended-thinking mode. Accepts adaptive | disabled | max | enabled:<N> | enabled:max. Defaults to the model-appropriate mode when unset (adaptive on current models).",type:"string",required:!1,default:"adaptive",example:"adaptive",category:"model"},{name:"AFK_THINKING_UI",description:"Default thinking-display mode for the interactive REPL: summary | live | digest | off. Display-only \u2014 controls how extended-thinking blocks render, never whether thinking runs (cost/latency unaffected). Overridden per-launch by --thinking-ui and mutable mid-session via /thinking. Precedence: --thinking-ui flag > this env > interactive.thinkingUi config > live. Invalid values are ignored.",type:"string",required:!1,default:"live",example:"digest",category:"misc"},{name:"AFK_TIMEOUT_MS",description:"Per-turn timeout in milliseconds. Provider/SDK default if unset.",type:"number",required:!1,example:"120000",category:"model"},{name:"AFK_WORKSPACE_DISABLED",description:"Disable the shared agent workspace (WorkspaceStore + workspace_publish/workspace_query tools + preamble injection). When set to 1, subagents do not get workspace tools and no workspace preamble is injected at fork time \u2014 each agent works in full isolation as before v5.133. Used as the control arm of the file-read deduplication A/B experiment. Default: workspace enabled (unset or 0).",type:"boolean",required:!1,default:"0",example:"1",category:"model"},{name:"CLAUDE_MODEL",description:"Legacy alias for AFK_MODEL \u2014 supported for back-compat with pre-AFK_* deployments.",type:"string",required:!1,example:"sonnet",category:"model"},{name:"AFK_SYSTEM_PROMPT",description:'Raw operator-overlay prompt. Highest-priority overlay (over afk.config.json and AFK.md). Appended on top of the framework base (prompts/system-prompt.md) under an "# Operator configuration" header \u2014 it augments, never replaces, the base.',type:"string",required:!1,example:"You are a helpful agent.",category:"model"},{name:"AFK_DUMP_PROMPT",description:"Write the resolved system prompt to a file at startup. Accepts a path or 1 for default location.",type:"string",required:!1,example:"/tmp/afk-prompt.txt",category:"debug"},{name:"ANTHROPIC_API_KEY",description:"Anthropic API key. Tier-1 credential \u2014 overrides keychain OAuth and CLAUDE_CODE_OAUTH_TOKEN.",type:"string",required:!1,category:"auth",secret:!0},{name:"CLAUDE_CODE_OAUTH_TOKEN",description:"Claude Code OAuth token. Tier-2 credential \u2014 used when ANTHROPIC_API_KEY is unset; falls back to keychain.",type:"string",required:!1,category:"auth",secret:!0},{name:"OPENAI_API_KEY",description:"OpenAI API key for the openai-compatible provider (gpt-*, o1*, o3*, o4* models).",type:"string",required:!1,category:"auth",secret:!0},{name:"CODEX_API_KEY",description:"Fallback OpenAI API key for the openai-compatible provider, read after OPENAI_API_KEY. Legacy name from the removed @openai/codex-sdk integration \u2014 prefer OPENAI_API_KEY.",type:"string",required:!1,category:"auth",secret:!0},{name:"XAI_API_KEY",description:"xAI API key for the xai provider (Grok models) in API-key mode. Metered; distinct from SuperGrok / SuperGrok Heavy / X Premium+ OAuth.",type:"string",required:!1,category:"auth",secret:!0},{name:"AFK_XAI_BASE_URL",description:"Base URL for xAI API-key mode. Default https://api.x.ai/v1. The OpenAI SDK appends /chat/completions.",type:"string",required:!1,example:"https://api.x.ai/v1",category:"model"},{name:"AFK_XAI_OAUTH_BASE_URL",description:"Base URL for xAI SuperGrok / SuperGrok Heavy / X Premium+ OAuth inference. Default https://cli-chat-proxy.grok.com/v1 (subscription path). Some accounts work on https://api.x.ai/v1 with OAuth \u2014 override if needed. Distinct from AFK_XAI_BASE_URL (API-key mode).",type:"string",required:!1,example:"https://cli-chat-proxy.grok.com/v1",category:"model"},{name:"AFK_XAI_GROK_CLIENT_VERSION",description:"Override the semver sent as x-grok-client-version to the xAI OAuth CLI chat proxy. Use only if the proxy raises its required Grok CLI version before agent-afk is updated; invalid values fall back to the official Grok Build version file or built-in compatible default.",type:"string",required:!1,example:"1.0.6",category:"model"},{name:"AFK_LOCAL_API_KEY",description:"Placeholder API key for local Anthropic-compatible servers (vllm-mlx, etc.). Set when AFK_LOCAL_BASE_URL is configured.",type:"string",required:!1,default:"local",example:"local",category:"auth",secret:!0},{name:"AFK_LOCAL_BASE_URL",description:"Base URL for a self-hosted Anthropic-compatible server. When set, routes traffic away from api.anthropic.com.",type:"string",required:!1,example:"http://127.0.0.1:8080",category:"model"},{name:"AFK_OPENAI_BASE_URL",description:"Base URL override for the OpenAI-compatible provider. Used for local shims (mlx_lm.server, Ollama, vLLM, LM Studio). The OpenAI SDK appends `/chat/completions` itself \u2014 a value ending in `/chat/completions` will be stripped at config-load time with a one-shot warning.",type:"string",required:!1,example:"http://127.0.0.1:8000/v1",category:"model"},{name:"AFK_OPENAI_USE_RESPONSES",description:"Opt the OpenAI-compatible provider into the OpenAI Responses API instead of Chat Completions for API-key sessions. Truthy values: 1, true, yes, on. The ChatGPT-subscription OAuth path uses Responses automatically regardless of this flag.",type:"boolean",required:!1,example:"1",category:"model"},{name:"AFK_OPENAI_CHATGPT_OAUTH",description:"Opt into using ChatGPT-subscription OAuth credentials from ~/.codex/auth.json (auth_mode: chatgpt) as OpenAI provider auth. Off by default. READ-ONLY: AFK never refreshes these tokens \u2014 re-run `codex` when the access token expires. Routes requests over the Responses API to the private ChatGPT backend (chatgpt.com/backend-api).",type:"boolean",required:!1,example:"1",category:"model"},{name:"AFK_PROVIDER",description:"Force provider selection (anthropic | anthropic-direct | openai | openai-compatible | openai-codex | xai | xai-oauth). Overrides the model-name heuristic. Same surface as the --provider CLI flag; CLI flag wins when both are set.",type:"string",required:!1,example:"openai-compatible",category:"model"},{name:"EXA_API_KEY",description:"Exa (exa.ai) search API key, enabling web_scrape search mode. Free tier (20k requests/month) available at https://exa.ai. When unset, search mode returns an actionable error; markdown and raw modes are unaffected.",type:"string",required:!1,category:"auth",secret:!0},{name:"TELEGRAM_BOT_TOKEN",description:"Telegram bot token from @BotFather. Required to run the Telegram bot surface.",type:"string",required:!1,category:"telegram",secret:!0},{name:"AFK_TELEGRAM_BOT_TOKEN",description:"Alternative env var name for the Telegram bot token, accepted by the setup wizard.",type:"string",required:!1,category:"telegram",secret:!0},{name:"AFK_TELEGRAM_ALLOWED_CHAT_IDS",description:"Comma-separated list of Telegram chat IDs allowed to interact with the bot. Required when the bot is running.",type:"string",required:!1,example:"123456789,987654321",category:"telegram"},{name:"AFK_TELEGRAM_TAG_ONLY_CHAT_IDS",description:"Comma-separated list of Telegram chat IDs where the bot answers only when addressed (a reply to the bot, an @mention of the bot, or a text_mention resolving to the bot). Slash-commands are unaffected; chats not listed behave as usual. The afk.config.json telegram.tagOnlyChats block takes precedence. Requires Telegram privacy mode OFF (BotFather /setprivacy Disable) for non-addressed group messages to reach the bot.",type:"string",required:!1,example:"-100987654321,123456789",category:"telegram"},{name:"AFK_TELEGRAM_PRIMARY_CHAT_ID",description:"Default chat ID for outbound notifications (primary-mode routing). When unset, notifications go to the first private/DM chat in AFK_TELEGRAM_ALLOWED_CHAT_IDS. The afk.config.json telegram.notify block takes precedence.",type:"string",required:!1,example:"123456789",category:"telegram"},{name:"AFK_TELEGRAM_NOTIFY_MODE",description:"Outbound notification fan-out: primary (default \u2014 one chat), broadcast (every allowed chat), or custom (afk.config.json telegram.notify.targets). The afk.config.json telegram.notify.mode takes precedence.",type:"string",required:!1,example:"broadcast",category:"telegram"},{name:"TELEGRAM_DATA_DIR",description:"Override the directory where Telegram bot state is stored. Defaults to ~/.afk/state/telegram/.",type:"string",required:!1,category:"telegram"},{name:"TELEGRAM_VERBOSE",description:"Set to a truthy value ('1'/'true'/'yes'/'on', case-insensitive) to log per-message details from the Telegram bot \u2014 chat IDs, message text, latency.",type:"boolean",required:!1,example:"true",category:"telegram"},{name:"TMUX",description:"OS-level tmux session identifier. Set automatically by tmux to the socket path and session info (e.g. /tmp/tmux-501/default,12345,0) inside any tmux pane. Not set by AFK. Read by configureColor() to detect a tmux environment; for truecolor support on Node \u2264 24, set FORCE_COLOR=3 in your shell or ~/.afk/config/afk.env.",type:"string",required:!1,example:"/tmp/tmux-501/default,12345,0",category:"process"},{name:"AFK_TELEGRAM_TRACE",description:"Set to 1 to dump raw bridge traffic between the agent and the Telegram bot \u2014 debugging only.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_TELEGRAM_CWD",description:"Override the working directory used by the Telegram bot when spawning agent sessions.",type:"string",required:!1,category:"telegram"},{name:"AFK_HOME",description:"Override the AFK home directory. Default: ~/.afk/.",type:"string",required:!1,default:"~/.afk",example:"/opt/afk",category:"paths"},{name:"AFK_STATE_DIR",description:"Override the entire AFK state tier (sessions/, todos/, transcripts/, memory/, daemon/, etc.), not just one subdirectory. Must be an absolute path (not /). Default: $AFK_HOME/state/.",type:"string",required:!1,category:"paths"},{name:"AFK_FRAMEWORK_DIR",description:"Override the AFK agent-framework directory used for telemetry and briefs. Default: $AFK_HOME/agent-framework/.",type:"string",required:!1,category:"paths"},{name:"AFK_COMPANION_PRIMER",description:'Opt-in: absolute path to a single companion-primer file. When set, its content is bounded (capped, fenced as <companion-primer>) and appended to the system prompt at session start for top-level sessions (chat/REPL/telegram/daemon), as lower-authority "reflections, not facts" context. Unset (default) = no-op. Only the one named file is ever read \u2014 never a directory or repo walk.',type:"string",required:!1,example:"/Users/me/Projects/afk-companion/PRIMER.md",category:"paths"},{name:"HOME",description:"Standard Unix home directory. Used as the fallback when AFK_HOME is unset.",type:"string",required:!1,category:"process"},{name:"PATH",description:"System PATH. Read for executable resolution (git, gh, etc.) in tool handlers.",type:"string",required:!1,category:"process"},{name:"APPDATA",description:"Windows %APPDATA% (Roaming). Used for VS Code/Cursor settings discovery and credential denylist paths.",type:"string",required:!1,category:"process"},{name:"LOCALAPPDATA",description:"Windows %LOCALAPPDATA%. Used for browser credential denylist paths (Chrome, Firefox, Edge, etc.).",type:"string",required:!1,category:"process"},{name:"USERPROFILE",description:"Windows %USERPROFILE%. Used for credential denylist paths (.ssh, .aws, .gnupg) on win32.",type:"string",required:!1,category:"process"},{name:"AFK_DAEMON_CWD",description:"Working directory used by the daemon process for spawned agent sessions.",type:"string",required:!1,category:"daemon"},{name:"AFK_DAEMON_TASK",description:"Default task description for the daemon. Falls back to afk.config.json daemon.task.",type:"string",required:!1,category:"daemon"},{name:"AFK_DAEMON_TASK_ID",description:"Task identifier the daemon uses to scope its state directory and telemetry.",type:"string",required:!1,category:"daemon"},{name:"AFK_DAEMON_HOST",description:"Bind address for the daemon control HTTP surface. Defaults to 127.0.0.1 (loopback only). The control surface is unauthenticated, so bind a non-loopback address such as 0.0.0.0 only on a trusted or firewalled network. Overridden by the --host flag.",type:"string",required:!1,category:"daemon"},{name:"AFK_SESSIONSTART_COOLDOWN_MS",description:"Cooldown in milliseconds between SessionStart trigger fires in the daemon. Prevents thundering-herd on rapid restarts.",type:"number",required:!1,category:"daemon"},{name:"AFK_WEB_PORT",description:"Port for the `afk web` browser surface. Defaults to 4141; falls back to an ephemeral port when taken. Overridden by --port.",type:"number",required:!1,example:"4141",category:"daemon"},{name:"AFK_WEB_HOST",description:"Bind address for the `afk web` browser surface. Defaults to 127.0.0.1. Unlike the daemon control surface, a non-loopback bind is REFUSED unless AFK_WEB_TOKEN (or --token) is also set, because this surface can submit prompts and approve tool use. Overridden by --host.",type:"string",required:!1,example:"127.0.0.1",category:"daemon"},{name:"AFK_WEB_TOKEN",description:"Bearer token for the `afk web` surface. When unset, a random per-run token is minted and printed in the startup URL. Setting this explicitly is also what permits a non-loopback bind.",type:"string",required:!1,category:"daemon",secret:!0},{name:"AFK_WORKTREE_AUTONAME",description:"Auto-rename worktree branches based on the first user message in interactive mode. 1 = on (default), 0 = off.",type:"boolean",required:!1,default:"1",example:"0",category:"worktree"},{name:"AFK_WORKTREE_BRANCH_PREFIX",description:"Branch-name prefix for AFK-managed worktrees. Default afk/. Set to empty string to drop the prefix.",type:"string",required:!1,default:"afk/",example:"wt/",category:"worktree"},{name:"AFK_WORKTREE_BASE",description:"Override the base git ref for worktrees created with --worktree. By default AFK bases worktrees on the remote's default branch (e.g. origin/main), fetched fresh. Set this to pin a different ref, or to HEAD to base on the local checkout. Overridden per-session by --worktree-base.",type:"string",required:!1,example:"origin/main",category:"worktree"},{name:"AFK_WORKTREE_ON_EXIT",description:"Clean-worktree quit policy for interactive --worktree sessions: ask, keep, or remove.",type:"string",required:!1,example:"ask",category:"worktree"},{name:"AFK_WORKTREE_BOOT_PRUNE",description:"When set, the daemon prunes stale worktrees at boot in addition to the cron-driven sweep.",type:"boolean",required:!1,category:"worktree"},{name:"AFK_WORKTREE_PRUNE_DISABLE",description:"Disable the worktree prune job entirely. Useful for long-running tests.",type:"boolean",required:!1,category:"worktree"},{name:"AFK_WORKTREE_MAX_AGE_CLEAN",description:"Maximum age (in days) before a clean worktree is auto-pruned. Default 14.",type:"number",required:!1,default:"14",category:"worktree"},{name:"AFK_WORKTREE_MAX_AGE_DIRTY",description:"Maximum age (in days) before a dirty worktree is auto-pruned. Default 30.",type:"number",required:!1,default:"30",category:"worktree"},{name:"AFK_WORKTREE_SWEEP_ROOT",description:"Override the root directory under which AFK worktrees are tracked for pruning.",type:"string",required:!1,category:"worktree"},{name:"AFK_ALLOW_PROJECT_MCP",description:"Opt-in to loading + spawning MCP servers declared in <cwd>/.mcp.json. Fail-closed: when unset (or 0), project-local servers are NOT spawned; set to a truthy value (1/true/yes/on) to load them. A project-local .mcp.json spawns arbitrary commands on session start, so it is off by default to prevent code execution when entering an untrusted repo (issue #571). Skipped servers are listed in a startup warning with the opt-in instruction.",type:"boolean",required:!1,example:"1",category:"mcp"},{name:"AFK_AUTO_ROUTING",description:"Auto-route bare slash inputs to matching skills. Applies to interactive, chat, telegram, and daemon surfaces.",type:"boolean",required:!1,example:"true",category:"routing"},{name:"AFK_INTERNAL",description:'Tier gate. Set to exactly `1` to unlock \u2014 only the literal string "1" unlocks (other truthy values like "true"/"yes" leave the tier locked). When unlocked, skills tagged `audience: \'internal\'` (e.g. /audit-fit, harvest/distill plugins) become visible at end-user surfaces (slash-command list, --help, tab-complete, system-prompt skill manifest). Default unset = public tier \u2014 internal skills are hidden. Not an access-control boundary; it gates surfacing, not the underlying registry.',type:"boolean",required:!1,example:"1",category:"routing"},{name:"AFK_SHELL_PASSTHROUGH",description:"Enable the interactive REPL `!cmd` / `!&cmd` shell-passthrough feature. On by default. Set to 0, false, off, or no (case-insensitive) to disable, so inputs beginning with ! are sent to the model as literal text instead of being executed as shell commands. Equivalent to the --no-shell-passthrough flag.",type:"boolean",required:!1,default:"1",example:"0",category:"misc"},{name:"AFK_BG_AUTO_DELIVER",description:"Auto-deliver background subagent results into the model context on the next user turn (interactive REPL). On by default. Set to 0, false, off, or no (case-insensitive) to disable, restoring the manual /bgsub:join retrieval flow.",type:"boolean",required:!1,default:"1",example:"0",category:"misc"},{name:"AFK_BANNER_PLAIN",description:"Suppress the ANSI-colored banner at REPL startup. Useful for non-TTY captures and CI logs.",type:"boolean",required:!1,example:"1",category:"misc"},{name:"AFK_PLAIN_OUTPUT",description:"Force the interactive REPL to fully behave like a non-TTY surface for rendering purposes, even when stdout/stdin ARE a TTY: append-only plain-stdout output instead of the TerminalCompositor live overlay (both the persistent between-turn compositor AND the per-turn StreamRenderer overlay), AND the input surface downgrades to the simple non-TTY line reader instead of the fancy compositor-backed input box. Same code path already used for non-TTY surfaces (pipes, CI). Full opt-out escape hatch for tmux/SSH/multiplexer sessions where cursor-up redraws and DECSTBM scroll regions misbehave \u2014 trades the live overlay and fancy input UX for reliability. Opt-in \u2014 default TTY behavior (live overlay + fancy input) is unchanged unless this var is set. Truthy values: 1, true (case-insensitive).",type:"boolean",required:!1,example:"1",category:"misc"},{name:"AFK_SPINNER_TIPS",description:"Show rotating tips in the loading spinner during long calls. 1 = on, 0 = off.",type:"boolean",required:!1,category:"misc"},{name:"AFK_GOBLIN_SPINNER",description:"Goblin-themed working spinner (olive frames + goblin verbs) while the agent runs tools. 1 = on (default), 0 = classic dim spinner.",type:"boolean",required:!1,example:"0",category:"misc"},{name:"AFK_GOBLIN_MASCOT",description:"Reacting goblin mini-sprite in the reserved footer band while the agent runs tools (3 rows, animated). 1 = on, unset/0 = off (default). Claims terminal rows, so it is opt-in.",type:"boolean",required:!1,example:"1",category:"misc"},{name:"AFK_TERM_TITLE",description:'Set the terminal/tab title (OSC 2) to reflect afk state \u2014 "afk \u2014 <cwd> \xB7 running" during a turn, "afk \u2014 <cwd>" when idle, cleared on exit. 1 = on (default when stdout is a TTY), 0 = leave the title alone. TTY-only.',type:"boolean",required:!1,example:"0",category:"misc"},{name:"AFK_NOTIFY",description:"Emit a desktop completion notification (OSC 9) on turn completion, for terminals that map OSC 9 to system notifications (iTerm2, kitty, WezTerm). Opt-in and off by default (intrusive). 1 = on. TTY-only.",type:"boolean",required:!1,example:"1",category:"misc"},{name:"AFK_SHOW_DIFFS",description:"Show inline diffs in the tool-lane output for edit/write tool calls. 1 = on, 0 = off.",type:"boolean",required:!1,category:"misc"},{name:"AFK_TURN_SEPARATOR",description:"Render a dim horizontal rule between conversation turns in the REPL. 0 = off, unset/1 = on (default). TTY-only: piped/one-shot output (afk chat) never emits the rule.",type:"boolean",required:!1,example:"0",category:"misc"},{name:"AFK_SKILL_STREAM_VERBOSE",description:"Verbose streaming output when a skill is dispatched. Logs sub-agent setup, intermediate events, and final result.",type:"boolean",required:!1,category:"debug"},{name:"FORCE_COLOR",description:"Standard Node convention. Force-enable ANSI color output even when stdout is not a TTY.",type:"string",required:!1,example:"1",category:"process"},{name:"NO_COLOR",description:"Standard convention (https://no-color.org). When set to any non-empty value, disables ANSI color output.",type:"string",required:!1,example:"1",category:"process"},{name:"AFK_THEME",description:"TUI color palette for the interactive REPL and all CLI rendering: dark | light | umber | auto. Display-only \u2014 swaps the semantic color palette, never behavior (cost/latency unaffected). auto detects from COLORFGBG and falls back to dark; umber matches the Umber terminal, is dark-only, and is never chosen by auto. Overridden per-launch by --theme and mutable mid-session via /theme. Precedence: --theme flag > this env > config theme > auto-detect > dark. Invalid values are ignored (dark).",type:"string",required:!1,default:"dark",example:"light",category:"misc"},{name:"AFK_TEXT_MEASURE",description:"Maximum line length (columns) for unbordered streamed text in the interactive REPL: assistant prose, thinking blocks, tool-lane text, and subagent text. Display-only \u2014 affects wrapping, never behavior. Bordered elements (cards, error boxes) already cap at 100; this applies the same ceiling to the unbordered surfaces, which previously scaled to the full terminal width. Accepts a positive integer (minimum 20), or full | off | none | 0 to disable capping and restore full-width wrapping. Unparseable or below-minimum values fall back to the default. No-op on terminals at or below the measure, so narrow terminals are unaffected.",type:"string",required:!1,default:"100",example:"full",category:"misc"},{name:"AFK_PROSE_MEASURE",description:"Maximum line length (columns) for prose-only blocks (paragraphs, list items, blockquotes) in the interactive REPL. Code fences use the wider AFK_TEXT_MEASURE (default 100). When AFK_TEXT_MEASURE is explicitly set, it overrides this value for backward compatibility. Accepts a positive integer (minimum 20), or full | off | none | 0 to disable. Unparseable or below-minimum values fall back to the default.",type:"string",required:!1,default:"80",example:"72",category:"misc"},{name:"COLORFGBG",description:'Terminal-set "foreground;background" color hint (e.g. "15;0"), read only for AFK_THEME=auto detection. The trailing field is the background color index; >= 7 is treated as a light background, otherwise dark. Not set by AFK \u2014 emitted by some terminals (rxvt, Konsole, iTerm2). Absent or unparseable => dark.',type:"string",required:!1,example:"15;0",category:"process"},{name:"COLORTERM",description:"OS-level terminal color-depth hint. Accepted values: truecolor or 24bit (24-bit color), 256color (256-color). Set by the outer terminal emulator, not by AFK. Read by chalk's supports-color to set its initial color level; also read by configureColor() to recommend FORCE_COLOR=3 for tmux truecolor users on Node \u2264 24.",type:"string",required:!1,example:"truecolor",category:"process"},{name:"AFK_DEBUG",description:"Enable verbose debug logging across the codebase. Accepts 1 to enable.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_DEBUG_CLIPBOARD",description:"Debug bracketed-paste and image-paste handling in the interactive REPL.",type:"boolean",required:!1,category:"debug"},{name:"AFK_DEBUG_COMPOSITOR",description:"Gate compositor phase-boundary traces to stderr; any truthy value enables.",type:"boolean",required:!1,category:"debug"},{name:"AFK_TRACE_DISABLED",description:"Disable the agent trace subsystem entirely. Set to 1 to skip trace file writes.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_WITNESS_RETENTION_DISABLE",description:"Disable the witness-tree retention sweep entirely, so no session directory is ever evicted.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_WITNESS_MAX_AGE_DAYS",description:"Evict a witness session directory once its newest content is older than this many days. Default 30.",type:"number",required:!1,default:"30",category:"debug"},{name:"AFK_WITNESS_MAX_BYTES",description:"Aggregate byte cap for the witness tree; oldest session directories are evicted first once exceeded. Default 2147483648 (2 GiB).",type:"number",required:!1,default:"2147483648",category:"debug"},{name:"AFK_SESSION_RETENTION_DISABLE",description:"Disable the session sidecar retention sweep entirely, so no state/sessions/*.json file is ever evicted.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_SESSION_MAX_AGE_DAYS",description:"Evict a session sidecar file once it is older than this many days (based on savedAt). Default 30.",type:"number",required:!1,default:"30",category:"debug"},{name:"AFK_SESSION_MAX_COUNT",description:"Count-based safety valve: evict oldest session sidecars first once the total exceeds this number. Default 1000.",type:"number",required:!1,default:"1000",category:"debug"},{name:"AFK_WAVE_MANIFEST_DISABLED",description:"Disable the wave manifest system entirely. When set to 1, no manifest is written for parallel subagent waves, and no resumption offer is made at session start.",type:"boolean",required:!1,default:"0",example:"1",category:"misc"},{name:"AFK_WAVE_MANIFEST_TTL_HOURS",description:"Time-to-live for wave manifests in hours. Manifests older than this are deleted on reconciliation and by the witness sweep. Default 48 (two days).",type:"number",required:!1,default:"48",example:"24",category:"misc"},{name:"AFK_WAVE_RESUME_UNATTENDED",description:"When set to 1, surface wave resumption offers even on non-interactive surfaces (daemon, one-shot chat). By default, offers are only made on interactive surfaces (REPL, Telegram).",type:"boolean",required:!1,default:"0",example:"1",category:"misc"},{name:"AFK_SESSION_LEDGER_DISABLED",description:"Disable the per-session durable event ledger (state/sessions/<id>/events.jsonl). Set to 1 to skip ledger writes; live cross-surface watching (e.g. the Telegram /watch command) will report no activity for sessions started while disabled.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_RUN_RECEIPT_DISABLED",description:"Disable the post-session run receipt (state/receipts/<label>.json and .md). Set to 1 to skip receipt writes; the underlying witness trace is unaffected. Receipts are also implicitly off when AFK_TRACE_DISABLED=1 (no trace to summarize).",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_CAPTURE_SUBAGENT_PROMPTS",description:"Opt-in: when set to 1, every prompt a parent session sends to a subagent is written as a redacted markdown file under state/witness/<label>/prompts/. Off by default because nothing prunes the witness tree and prompts may carry secrets the regex redactor cannot catch (connection strings, PEM blocks, PII).",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_CAPTURE_SUBAGENT_OUTPUT",description:"Opt-in: when set to 1, a subagent's conversational OUTPUT (assistant text plus each tool call with its arguments) is appended incrementally to a redacted markdown transcript under state/witness/<label>/outputs/. Flushed at every tool-call boundary, so a child killed by a timeout still leaves a usable partial record \u2014 the case where final-message capture yields nothing. Off by default for the same reasons as AFK_CAPTURE_SUBAGENT_PROMPTS (unpruned witness tree, best-effort regex redaction).",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_SUBAGENT_RESULT_CAP_BYTES",description:"Foreground subagent result size cap in bytes. When a subagent's final message exceeds this threshold, the full output is spilled to a sidecar file (state/sessions/<id>/subagent-handoffs/<subagentId>.txt) and the parent receives a head+tail slice with a read_file pointer. Prevents large subagent outputs from bloating parent context. Set to 0 to disable the cap entirely. Default 32768 (32KB). Note: sidecar files contain unredacted subagent output (same caveats as AFK_CAPTURE_SUBAGENT_OUTPUT). No automatic GC covers subagent-handoffs/ today; retention is tied to session-directory cleanup.",type:"number",required:!1,default:"32768",example:"16384",category:"model"},{name:"AFK_SUBAGENT_LOG",description:"Opt-in per-subagent conversation log. Writes OutputEvent JSONL to state/subagent-logs/<sessionLabel>/<subagentId>.jsonl for both foreground and background subagents. Powers /tasks:view replay. OFF by default (raw tool arguments are written without redaction \u2014 consistent with AFK_CAPTURE_SUBAGENT_PROMPTS / AFK_CAPTURE_SUBAGENT_OUTPUT). Set to 1 to enable.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"DEBUG",description:"Standard Node `debug`-package convention. When set to 1, enables verbose logging in several modules alongside AFK_DEBUG.",type:"string",required:!1,category:"debug"},{name:"AGENT_AFK_ASCII",description:"Force the interactive REPL tool-lane renderer to ASCII-only glyphs instead of the default Unicode box-drawing set. Accepts 1/true/yes (case-insensitive). Useful for terminals whose font lacks \u2503\u251C\u2570\u251C glyphs.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AGENT_SURFACE",description:"Internal surface marker propagated to subprocesses. Identifies which AFK surface (cli, telegram, daemon) spawned the process.",type:"string",required:!1,example:"cli",category:"process"},{name:"CI",description:"Standard CI-detection convention. Auto-set by GitHub Actions, CircleCI, etc. Used to switch off TTY-only UX.",type:"string",required:!1,example:"true",category:"process"},{name:"NODE_ENV",description:"Standard Node environment marker. test | development | production. Used by routing-telemetry.ts to suppress test-time writes.",type:"string",required:!1,example:"production",category:"process"},{name:"VITEST",description:"Set automatically by Vitest. Used at runtime to short-circuit code paths that should not fire in tests.",type:"string",required:!1,category:"process"},{name:"NO_UPDATE_NOTIFIER",description:"Disable the update-available notifier on CLI startup. Standard convention shared with many Node CLIs.",type:"boolean",required:!1,category:"process"},{name:"AFK_BROWSER_HEADLESS",description:"Override the default headless mode for native browser-control tools. `1`/`true` forces headless; `0`/`false` forces headed. When unset the default is headless on every AFK surface \u2014 the CLI entrypoint reports surface `afk`, which is in the headless set \u2014 so watching the agent work in a visible window is opt-in via `AFK_BROWSER_HEADLESS=0`, not implied by running the REPL. Note headed and headless use different chromium downloads (`chromium-*` vs `chromium_headless_shell-*`).",type:"boolean",required:!1,example:"1",category:"browser"},{name:"AFK_BROWSER_ALLOWED_DOMAINS",description:"Comma-separated allowlist of URL host globs. When set, browser_open and any navigation that targets a host outside the list returns status: blocked_by_policy. Unset means no allowlist (permissive). Patterns use simple `*` glob matching against the URL host. Combines with AFK_BROWSER_BLOCKED_DOMAINS \u2014 block wins.",type:"string",required:!1,example:"github.com,*.atlassian.net",category:"browser"},{name:"AFK_BROWSER_BLOCKED_DOMAINS",description:"Comma-separated blocklist of URL host globs. Browser navigation that matches any entry returns status: blocked_by_policy regardless of the allowlist.",type:"string",required:!1,example:"*.ads.example.com",category:"browser"},{name:"AFK_BROWSER_DOM_SNAPSHOTS",description:"Phase 2 opt-in: when set to 1, every browser_act writes a gzipped DOM snapshot sidecar under ~/.afk/state/witness/<sid>/browser/dom-snapshots/. Off by default because snapshots are large; useful for post-mortem analysis of failed actions.",type:"boolean",required:!1,example:"1",category:"browser"},{name:"AFK_BROWSER_BACKEND",description:"Browser provider backend: auto (default, prefer Agent Browser, fall back to Playwright), agent-browser (require Agent Browser), or playwright (headless only).",type:"string",required:!1,default:"auto",example:"agent-browser",category:"browser"},{name:"AFK_BROWSER_CONFIG",description:"Absolute path to an alternate browser config file. Overrides the default ~/.afk/config/browser.json lookup. Useful for per-project overrides in CI.",type:"string",required:!1,example:"/path/to/browser.json",category:"browser"},{name:"AFK_BROWSER_DEFAULT_PROFILE",description:"Name of the persistent session-vault profile the agent reuses for browser sessions. The context restores its login from (and saves it back to) ~/.afk/state/browser/<profile>/storageState.json, so a human runs `afk browser login --profile <name>` once and the agent reuses that authenticated session across unattended runs. Unset defaults to `default` (a fresh, empty profile \u2014 identical to pre-vault behavior). Allowed charset: [A-Za-z0-9_-], max 128 chars.",type:"string",required:!1,example:"work",category:"browser"},{name:"AFK_WRITE_DENYLIST",description:"Comma-separated list of additional path globs that the write_file tool refuses to write to.",type:"string",required:!1,example:"**/.env,**/secrets/**",category:"misc"},{name:"AFK_READ_DENYLIST",description:"Colon-separated list of additional absolute paths the read_file/grep/glob/list_directory tools refuse to read, and that the bash-restriction hook refuses to let a shell command reference on interactive surfaces (REPL, Telegram) \u2014 on headless surfaces (afk chat, daemon) bash fails open regardless of this list. A leading ~/ is expanded (~user/ is not \u2014 spell those absolutely). Built-in credential entries (~/.ssh, ~/.aws, ~/.afk/config, \u2026) always apply on top and cannot be removed. One built-in exception exists: ~/.afk/config/mcp.json (the MCP registry) IS readable \u2014 paths listed here outrank that carve-out, so set this to ~/.afk/config/mcp.json if your registry holds inline secrets rather than ${VAR} placeholders.",type:"string",required:!1,example:"/Users/me/project/.env:/Users/me/secrets",category:"misc"},{name:"AFK_WRITE_DIFF",description:"Show a diff preview before each write_file tool call. Defaults provider-controlled when unset.",type:"boolean",required:!1,category:"misc"},{name:"AFK_RATE_LIMIT_ADMISSION_DISABLED",description:"Bypass the process-wide rate-limit admission gate (issue #941). Set to 1 to skip pre-request capacity checks. Default 0 (gate active). OAuth subscription accounts already pass through automatically when no per-minute headers are returned.",type:"boolean",required:!1,default:"0",example:"1",category:"model"},{name:"AFK_RATE_LIMIT_STAGGER_MAX_MS",description:"Jitter ceiling (ms) for the rate-limit admission bucket: each waiter at a window boundary wakes at reset + random(0..ceiling) to avoid re-storming the API. Default 500. Set to 0 in tests for deterministic timing.",type:"number",required:!1,default:"500",example:"0",category:"model"},{name:"AFK_WEB_ALLOW_PRIVATE_HOSTS",description:"Opt out of the web_scrape SSRF egress guard. When unset (default) the guard is ACTIVE: the markdown, raw, and headless-render paths refuse loopback (127/8, ::1), link-local (169.254/16 \u2014 including the 169.254.169.254 cloud instance-metadata endpoint), RFC1918 (10/8, 172.16/12, 192.168/16), carrier-grade NAT (100.64/10), IPv6 unique-local (fc00::/7), 0.0.0.0/8, and the IPv4-mapped/compatible IPv6 forms of all of those. Hostnames are resolved and the RESOLVED addresses are classified (DNS-rebinding guard), and the check is re-applied on every redirect hop. Set to 1/true to allow private-host access \u2014 needed only to scrape a local dev server. Enabling it restores a model-reachable SSRF path (issue #575).",type:"boolean",required:!1,example:"1",category:"misc"},{name:"AFK_DEMO_CLEAN",description:"Explicit opt-in to capture-mode. When set to 1, suppresses high-frequency repaint drivers (spinner ticker, live thinking-preview) so recorded artifacts contain each state once instead of once per timer tick.",type:"boolean",required:!1,example:"1",category:"misc"},{name:"SCRIPT",description:"Set by script(1) on BSD/macOS/Linux to the typescript filename while a terminal session is being recorded. Presence of a non-empty value triggers capture-mode.",type:"string",required:!1,example:"/tmp/typescript",category:"process"},{name:"ASCIINEMA_REC",description:"Set to 1 by asciinema rec while a session is being recorded. Triggers capture-mode.",type:"boolean",required:!1,example:"1",category:"process"},{name:"AFK_SESSION_ID",description:"Override the browser session ID used by the native browser-control tools. Defaults to 'default' for single-session use. Subagents inherit the parent's session by default. Set this when running multiple concurrent AFK processes that should each manage an isolated browser context.",type:"string",required:!1,default:"default",example:"session-abc123",category:"browser"},{name:"SHELL",description:"Standard POSIX env var pointing to the user's login shell binary. Used by shell-init and worktree commands to auto-detect the correct shell syntax for emitted wrapper code.",type:"string",required:!1,example:"/bin/zsh",category:"process"},{name:"PAGER",description:"Standard POSIX env var naming the user's preferred pager (with optional flags). Used by /transcript to render the full session in a scrollable viewer; falls back to `less -R` when unset.",type:"string",required:!1,example:"less -R",category:"process"},{name:"VISUAL",description:"Standard POSIX env var naming the user's preferred full-screen editor (with optional flags). Consulted FIRST by the /editor slash command (and its key chord) to compose a long prompt externally; takes precedence over EDITOR. No fallback editor is assumed \u2014 if neither VISUAL nor EDITOR is set, /editor prints a hint instead of guessing.",type:"string",required:!1,example:"nvim",category:"process"},{name:"EDITOR",description:"Standard POSIX env var naming the user's preferred editor (with optional flags). Consulted by the /editor slash command AFTER VISUAL, as the standard fallback. No default editor is assumed when both are unset \u2014 /editor prints a hint telling the user to set one.",type:"string",required:!1,example:"vim",category:"process"},{name:"AFK_DIFF_LINES",description:"Maximum number of diff lines shown in the inline diff render during write_file tool calls. Set to 0 for no cap. Non-integer values are silently ignored and the default applies.",type:"number",required:!1,example:"50",category:"misc"},{name:"AFK_SHELL_WRAPPER",description:"Set to 1 or true by the optional afk shell wrapper function (installed via `afk shell-init`). Signals that the parent shell has the wrapper active so the post-exit cd can fire.",type:"boolean",required:!1,example:"1",category:"process"},{name:"AFK_USER_CARD_MAX_ROWS",description:'Maximum number of visual rows emitted by renderUserCard before collapsing the remainder into a dim "\u2026(N lines collapsed)" summary row. Defaults to 24. Non-integer or non-positive values are silently ignored and the default applies.',type:"number",required:!1,example:"24",category:"misc"},{name:"AFK_LEASE_TTL_MS",description:"Lease TTL in milliseconds for durable task execution (issue #1411). A leased task whose lease expires before it completes is recovered and re-enqueued (or dead-lettered if maxAttempts is exhausted). Default: 600000 (10 minutes).",type:"number",required:!1,example:"600000",category:"misc"}],wm={};for(let t of Hr){let e=t.name;Object.defineProperty(wm,e,{get(){return process.env[e]},enumerable:!("secret"in t&&t.secret),configurable:!0})}b=wm});function oI(){return b.AFK_DEBUG==="1"||b.DEBUG==="1"}function C(...t){oI()&&console.log(...t)}var J=ne(()=>{"use strict";I()});import{basename as sI,dirname as iI,join as Cn}from"path";function Wr(t){if(!aI.test(t))throw new Error(`Invalid AFK_SESSION_ID: must match /^[a-zA-Z0-9_-]+$/, got: ${JSON.stringify(t)}`)}function Pn(){return Cn(Q(),"witness")}function et(t){return Wr(t),Cn(Pn(),t)}function Dl(t){return Cn(et(t),"inbound-attachments")}function Fl(t){return Cn(et(t),"prompts")}function Ll(t){return Cn(et(t),"outputs")}function Nl(t){if(!(!t||t===""))return Cn(et(t),"bash-captures")}function rn(t){return!t||t.startsWith("in-memory:")?null:sI(iI(t))}var aI,Sm=ne(()=>{"use strict";P();aI=/^[a-zA-Z0-9_-]+$/});import{existsSync as km,mkdirSync as cI,renameSync as lI,cpSync as dI,rmSync as uI}from"fs";import{join as B,dirname as _m,isAbsolute as Ul}from"path";import{homedir as Em}from"os";import{fileURLToPath as pI}from"url";function re(){let t=b.AFK_HOME;if(t!==void 0&&t!==""){if(!Ul(t)||t==="/")throw new Error(`AFK_HOME must be an absolute path that is not /, got: ${t}`);return t}return B(Em(),".afk")}function De(){let t=b.AFK_FRAMEWORK_DIR;if(t!==void 0&&t!==""){if(!Ul(t)||t==="/")throw new Error(`AFK_FRAMEWORK_DIR must be an absolute path that is not /, got: ${t}`);return t}return B(re(),"agent-framework")}function $s(){return B(De(),"forge-telemetry.jsonl")}function Am(){return B(De(),"briefs")}function xm(){return B(De(),"facets")}function Kr(){return B(re(),"skills")}function Mn(){return B(re(),"plugins")}function Rm(t=process.cwd()){return B(t,".afk")}function Im(t=process.cwd()){return B(Rm(t),"skills")}function Cm(t=process.cwd()){return B(Rm(t),"plugins")}function Pm(t=process.cwd()){return B(t,".afk","plans")}function Bs(){return B(Mn(),".index.json")}function $l(){return B(qr(),"schedules.json")}function Mm(){let t=pI(import.meta.url),e=_m(t);return B(e,"bundled-plugins")}function qr(){return B(re(),"config")}function Q(){let t=b.AFK_STATE_DIR;if(t!==void 0&&t!==""){if(!Ul(t)||t==="/")throw new Error(`AFK_STATE_DIR must be an absolute path that is not /, got: ${t}`);return t}return B(re(),"state")}function oe(){return B(Q(),"sessions")}function js(){return B(Q(),"presence")}function Hs(){return B(Q(),"memory")}function Ws(){return B(Q(),"kv","kv.db")}function Ks(){return B(Q(),"session-grants.jsonl")}function Om(){return B(re(),"farms")}function Dm(t){return B(Om(),t)}function Fm(t="default"){return B(Q(),"daemon",`agent-afk@${t}`)}function Lm(){return B(Q(),"worktree-sweep.lock")}function qs(){return B(Q(),"worktree-roots.json")}function Bl(){return B(qr(),"afk.env")}function On(){return B(qr(),"afk.config.json")}function Gs(){return B(Em(),".afk.config.json")}function fI(){return B(re(),"sessions")}function mI(t,e){if(t!==e&&km(t)&&!km(e))try{cI(_m(e),{recursive:!0});try{lI(t,e)}catch(n){if(n.code==="EXDEV")try{dI(t,e,{recursive:!0}),uI(t,{recursive:!0,force:!0})}catch(r){process.stderr.write(`[afk] migrateDirOnce: EXDEV fallback failed for ${t} \u2192 ${e}: ${String(r)}
|
|
2
|
-
`)}}}catch{}}function Nm(){mI(fI(),oe())}function Um(t){if(typeof t!="string"||t.length===0)throw new Error("Invalid jobId: must be a non-empty string");if(t.length>vm)throw new Error(`Invalid jobId: exceeds ${vm} chars`);if(!gI.test(t))throw new Error(`Invalid jobId: ${JSON.stringify(t)} contains characters outside [A-Za-z0-9_-]`)}function jl(){return B(Q(),"subagent-logs")}function Hl(t){return Um(t),B(jl(),t)}function $m(t,e){return Um(e),B(Hl(t),`${e}.jsonl`)}function Wl(t){if(typeof t!="string"||t.length===0)throw new Error("Invalid browser profile: must be a non-empty string");if(t.length>Tm)throw new Error(`Invalid browser profile: exceeds ${Tm} chars`);if(!hI.test(t))throw new Error(`Invalid browser profile: ${JSON.stringify(t)} contains characters outside [A-Za-z0-9_-]`)}function yI(){return B(Q(),"browser")}function bI(t){return Wl(t),B(yI(),t)}function Kl(t){return B(bI(t),"storageState.json")}function Dn(t){return typeof t=="string"&&t.length>0&&t.length<=SI&&wI.test(t)}function Gr(t){if(!Dn(t))throw new Error(`Invalid session id for ledger path: ${JSON.stringify(t)}`);return B(oe(),t)}function Xr(t){return B(Gr(t),"events.jsonl")}function Bm(t){return B(Gr(t),"session.key")}function Fn(){return B(Q(),"waves")}function Ln(t){return B(Fn(),`${t}.json`)}var gI,vm,hI,Tm,wI,SI,P=ne(()=>{"use strict";I();Sm();gI=/^[A-Za-z0-9_-]+$/,vm=128;hI=/^[A-Za-z0-9_-]+$/,Tm=128;wI=/^[A-Za-z0-9_-]+$/,SI=128});var cu={};Ns(cu,{enforceDomainPolicy:()=>Ze,loadBrowserConfig:()=>au});import{readFileSync as EF}from"node:fs";import{join as AF}from"path";function xF(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function Pb(t,e){return xF(e).test(t)}function CF(t,e){if(t!==void 0){let n=t.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(e!==void 0){if(RF.has(e))return!0;if(IF.has(e))return!1}return!1}function Mb(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function PF(t){if(t===void 0||t==="")return"auto";if(t==="playwright"||t==="agent-browser"||t==="auto")return t;throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${t}`)}function Ob(t){let e=t===void 0||t.trim()===""?"default":t.trim();return Wl(e),e}function MF(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function OF(t){try{return EF(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function DF(t,e){let n={...t};if(typeof e.headless=="boolean"&&(n.headless=e.headless),Array.isArray(e.allowedDomains)&&(n.allowedDomains=e.allowedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),Array.isArray(e.blockedDomains)&&(n.blockedDomains=e.blockedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),typeof e.domSnapshots=="boolean"&&(n.domSnapshots=e.domSnapshots),e.backend==="playwright"||e.backend==="agent-browser"||e.backend==="auto")n.backend=e.backend;else if(e.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${String(e.backend)}`);return typeof e.defaultProfile=="string"&&(n.defaultProfile=Ob(e.defaultProfile)),n}function au(t){let e=t?.env??b,n=t?.readFileSync??OF,r=t?.surface??e.AGENT_SURFACE,o=CF(e.AFK_BROWSER_HEADLESS,r),s=Mb(e.AFK_BROWSER_ALLOWED_DOMAINS),i=Mb(e.AFK_BROWSER_BLOCKED_DOMAINS),a=MF(e.AFK_BROWSER_DOM_SNAPSHOTS),c=PF(e.AFK_BROWSER_BACKEND),l=Ob(e.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:c,configPath:null,defaultProfile:l},u=e.AFK_BROWSER_CONFIG,p=u!==void 0&&u.trim()!==""?u.trim():AF(qr(),"browser.json"),f=n(p);if(f===void 0)return d;let m;try{m=JSON.parse(f)}catch(h){throw new Error(`Failed to parse browser config at ${p}: ${String(h)}`)}if(typeof m!="object"||m===null||Array.isArray(m))throw new Error(`Browser config at ${p} must be a JSON object`);let g=DF(d,m);return g.configPath=p,g}function Ze(t,e){let n;try{n=new URL(t).hostname.toLowerCase()}catch{return{allowed:!1,reason:`invalid URL: ${t}`}}for(let r of e.blockedDomains)if(Pb(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>Pb(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var RF,IF,Ht=ne(()=>{"use strict";I();P();RF=new Set(["daemon","subagent","telegram","afk"]),IF=new Set(["repl","interactive","cli"])});import{readFileSync as FF}from"node:fs";import{join as LF}from"node:path";import{homedir as NF}from"node:os";function $F(t){let e=t??UF,n;try{n=FF(e,"utf8")}catch{return null}let r;try{r=JSON.parse(n)}catch{return null}if(typeof r!="object"||r===null||Array.isArray(r))return null;let o=r;if(typeof o.url!="string"||typeof o.token!="string"||typeof o.pid!="number")return null;let s;try{s=new URL(o.url)}catch{return null}let{hostname:i,protocol:a}=s;if(!(i==="127.0.0.1"||i==="localhost"||i==="::1")||a!=="http:")throw new Error(`Agent Browser connection file contains an untrusted URL: ${o.url}. Only http://127.0.0.1 or http://localhost is permitted.`);return{url:o.url,token:o.token,pid:o.pid,version:typeof o.version=="string"?o.version:"unknown"}}function BF(t){try{return process.kill(t,0),!0}catch{return!1}}async function jF(t,e,n=2e3){try{let r=new AbortController,o=setTimeout(()=>r.abort(),n),s=await fetch(`${t}/health`,{method:"GET",headers:{Authorization:`Bearer ${e}`,Host:"127.0.0.1:8833"},signal:r.signal});return clearTimeout(o),s.ok}catch{return!1}}async function lu(t){let e=$F(t);return e===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:BF(e.pid)?await jF(e.url,e.token)?{available:!0,connection:e,reason:null}:{available:!1,connection:e,reason:`health probe failed at ${e.url}`}:{available:!1,connection:e,reason:`stale connection file: PID ${e.pid} not alive`}}var UF,Db=ne(()=>{"use strict";UF=LF(NF(),".config","agent-browser","connection.json")});async function Fb(t){let{config:e,surface:n}=t;if(e.backend==="playwright")return{backend:"playwright",reason:"explicit config: backend=playwright",probeMs:0,availability:null};if(e.backend==="agent-browser"){let i=Date.now(),a=await lu(),c=Date.now()-i;if(!a.available)throw new Error(`AFK_BROWSER_BACKEND=agent-browser but Agent Browser is not available: ${a.reason}`);return{backend:"agent-browser",reason:"explicit config: backend=agent-browser",probeMs:c,availability:a}}if(n&&HF.has(n))return{backend:"playwright",reason:`auto: surface "${n}" excluded from Agent Browser`,probeMs:0,availability:null};if(e.headless)return{backend:"playwright",reason:"auto: headless mode requires Playwright",probeMs:0,availability:null};let r=Date.now(),o=await lu(),s=Date.now()-r;return o.available?{backend:"agent-browser",reason:"auto: Agent Browser available and preferred",probeMs:s,availability:o}:{backend:"playwright",reason:`auto: Agent Browser unavailable (${o.reason})`,probeMs:s,availability:o}}var HF,Lb=ne(()=>{"use strict";Db();HF=new Set(["daemon","subagent"])});import{createHash as WF}from"crypto";function Nb(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&KF.test(t.label))}function Ub(t){return WF("sha256").update(t,"utf8").digest("hex").slice(0,8)}function $b(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var KF,zi=ne(()=>{"use strict";KF=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as qF}from"crypto";import{mkdir as GF,stat as XF,writeFile as zF}from"fs/promises";import{join as du}from"path";import{gzip as JF}from"zlib";import{promisify as VF}from"util";function YF(t){return du(et(t),"browser")}function QF(t){return du(YF(t),"screenshots")}function ZF(){return new Date().toISOString().replace(/[:.]/g,"-")}function eL(){return qF(3).toString("hex")}async function tr(t,e,n){if(e.length>Bb)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Bb} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=QF(t);await GF(r,{recursive:!0});let o=`${ZF()}-${eL()}-${n}.png`,s=du(r,o);await zF(s,e);let{size:i}=await XF(s);return{path:s,bytes:i}}var eQ,Bb,uu=ne(()=>{"use strict";P();zi();eQ=VF(JF);Bb=5*1024*1024});var Ji,jb=ne(()=>{"use strict";Ji=class{baseUrl;token;constructor(e){this.baseUrl=e.url,this.token=e.token}async call(e,n,r=3e4){let o={version:1,method:e,params:n},s=new AbortController,i=setTimeout(()=>s.abort(),r);try{let a=await fetch(`${this.baseUrl}/agent`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`,Host:new URL(this.baseUrl).host},body:JSON.stringify(o),signal:s.signal});if(!a.ok){let c=await a.text().catch(()=>"");throw new Error(`Agent Browser ${e} failed (HTTP ${a.status}): ${c}`)}return await a.json()}finally{clearTimeout(i)}}async listTabs(){return(await this.call("tabs.list",null)).tabs}async openTab(e){return{tabId:(await this.call("tabs.open",{url:e},6e4)).tab_id}}async closeTab(e){await this.call("tabs.close",{tab_id:e})}async read(e,n){return this.call("page.read",{tab_id:e,mode:n?.mode??"main",...n?.query?{query:n.query}:{},...n?.budget?{budget:n.budget}:{}})}async inspect(e,n){return this.call("page.inspect",{tab_id:e,mode:n?.mode??"interactive",...n?.query?{query:n.query}:{},...n?.limit?{limit:n.limit}:{}})}async click(e,n){await this.call("page.click",{tab_id:e,element_id:n})}async fill(e,n,r){await this.call("page.fill",{tab_id:e,element_id:n,value:r})}async press(e,n,r){await this.call("page.press",{tab_id:e,key:n,...r?{element_id:r}:{}})}async select(e,n,r){await this.call("page.select",{tab_id:e,element_id:n,value:r})}async waitFor(e,n,r){await this.call("page.wait",{tab_id:e,condition:n,...r?.value?{value:r.value}:{},...r?.timeout?{timeout:r.timeout}:{}},(r?.timeout??3e4)+5e3)}async evalScript(e,n){return this.call("page.eval",{tab_id:e,script:n})}async screenshot(e){return this.call("page.screenshot",{tab_id:e})}}});function pu(t){return{id:t.id,role:t.role,label:t.label,kind:t.kind,value:t.value,state:{disabled:t.disabled,...t.checked!==void 0?{checked:t.checked}:{},...t.selected!==void 0?{selected:t.selected}:{},...t.expanded!==void 0?{expanded:t.expanded}:{}},bbox:t.bbox,...t.selector?{selector:t.selector}:{}}}function Hb(t,e){switch(e.kind){case"element_id":if(t.has(e.elementId))return e.elementId;throw new Error(`Element ${e.elementId} not found in current observation. Call browser_observe to refresh.`);case"selector":return null;case"semantic":return null}}async function fu(t,e,n,r,o,s){switch(n){case"click":await t.click(e,r);break;case"fill":if(o===void 0)throw new Error("fill requires a value");await t.fill(e,r,o);break;case"press":if(o===void 0)throw new Error("press requires a value (key combo)");await t.press(e,o,r);break;case"select":if(o===void 0)throw new Error("select requires a value");await t.select(e,r,o);break;case"hover":throw new Error("hover is not supported by Agent Browser; use element_id from a prior observation to target clicks instead");case"scroll_to":{let i=r.replace(/\\/g,"\\\\").replace(/"/g,'\\"');await t.evalScript(e,`document.querySelector('[data-element-id="${i}"]')?.scrollIntoView({behavior:'smooth',block:'center'})`);break}case"wait_for":await t.waitFor(e,"element",{value:r,timeout:s??1e4});break;default:throw new Error(`Unknown action: ${n}`)}}async function Wb(t,e){if(e.target.kind!=="semantic")throw new Error("resolveSemanticAndAct called with non-semantic target");let{elements:n}=await t.client.inspect(t.tabId,{mode:"interactive",query:e.target.text,limit:10}),r=n;if(e.target.role){let c=e.target.role.toLowerCase();r=n.filter(l=>l.role.toLowerCase()===c)}if(r.length===0)throw new Error(`No element found matching semantic target: text="${e.target.text}"`+(e.target.role?`, role="${e.target.role}"`:""));if(r.length>1)return{outcome:"ambiguous_target",query:{text:e.target.text,...e.target.role?{role:e.target.role}:{}},candidates:r.slice(0,5).map(pu)};let s=r[0].id;await fu(t.client,t.tabId,e.action,s,e.value,e.timeoutMs);let i=await t.client.read(t.tabId,{mode:"main"}),a=Ze(i.url,t.config);return a.allowed?{elementId:s}:{outcome:"blocked_by_policy",url:i.url,reason:`action navigated to blocked domain: ${a.reason}`}}var Kb=ne(()=>{"use strict";Ht()});var qb={};Ns(qb,{AgentBrowserProvider:()=>mu});var mu,Gb=ne(()=>{"use strict";Ht();uu();jb();Kb();mu=class{name="agent-browser";config;client;sessions=new Map;constructor(e,n){this.config=e,this.client=new Ji(n)}async open(e){let n=Ze(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let r=this.sessions.get(e.sessionId);if(r)await this.client.evalScript(r.tabId,`window.location.href = ${JSON.stringify(e.url)}`),await this.client.waitFor(r.tabId,"load",{timeout:e.timeoutMs??3e4});else{let{tabId:i}=await this.client.openTab(e.url);await this.client.waitFor(i,"load",{timeout:e.timeoutMs??3e4}),r={tabId:i,observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null},this.sessions.set(e.sessionId,r)}let o=await this.client.read(r.tabId,{mode:"main"}),s=Ze(o.url,this.config);return s.allowed?this.buildObservation(r,e.sessionId,e.screenshot,void 0,"browser_open"):(await this.client.evalScript(r.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`redirected to blocked domain: ${s.reason}`})}async observe(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);return this.buildObservation(n,e.sessionId,e.screenshot,e.maxElements,"browser_observe")}async act(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);let r=Hb(n.knownElements,e.target);if(r===null){if(e.target.kind==="semantic"){let i=await Wb({client:this.client,config:this.config,tabId:n.tabId},e);return"outcome"in i?i:(n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString(),this.buildObservation(n,e.sessionId,e.screenshot,void 0,"browser_act"))}throw e.target.kind==="selector"?new Error("selector targets are not supported by Agent Browser; use element_id or semantic targets"):new Error(`Cannot resolve target: ${JSON.stringify(e.target)}`)}await fu(this.client,n.tabId,e.action,r,e.value,e.timeoutMs),n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString();let o=await this.client.read(n.tabId,{mode:"main"}),s=Ze(o.url,this.config);return s.allowed?this.buildObservation(n,e.sessionId,e.screenshot,void 0,"browser_act"):(await this.client.evalScript(n.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`action navigated to blocked domain: ${s.reason}`})}async render(e){throw new Error("AgentBrowserProvider does not support render(). Use PlaywrightProvider for one-shot content fetches.")}async screenshot(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);if(e.target!==void 0||e.fullPage)throw new Error("Agent Browser does not support element or full-page screenshots; omit target and fullPage.");let r=await this.client.screenshot(n.tabId),o=Buffer.from(r.data,"base64"),s=o.length>=24?o.readUInt32BE(16):0,i=o.length>=24?o.readUInt32BE(20):0;return{path:(await tr(e.sessionId,o,"browser_screenshot")).path,bytes:o.length,width:s,height:i,dataBase64:r.data,mediaType:"image/png"}}async extract(e){throw new Error("AgentBrowserProvider does not support extract() yet.")}async close(e){let n=this.sessions.get(e.sessionId);if(n){try{await this.client.closeTab(n.tabId)}catch{}this.sessions.delete(e.sessionId)}}describe(e){let n=this.sessions.get(e);return n?{active:!0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:1}:null}async shutdown(){let e=Array.from(this.sessions.entries()).map(async([,n])=>{try{await this.client.closeTab(n.tabId)}catch{}});await Promise.all(e),this.sessions.clear()}async buildObservation(e,n,r,o,s="browser_open"){let[i,a]=await Promise.all([this.client.read(e.tabId,{mode:"main",budget:4e3}),this.client.inspect(e.tabId,{mode:"interactive",limit:o??80})]),c=a.elements.map(pu),l=o??80,d=c.slice(0,l);e.observationCounter+=1,e.knownElements=new Map(d.map(g=>[g.id,g])),e.currentUrl=i.url,e.currentTitle=i.title;let u=[];c.length>l&&u.push(`page has ${c.length} interactive elements; showing first ${l}`);let p=null;if(r)try{let g=await this.client.screenshot(e.tabId),h=Buffer.from(g.data,"base64");p=(await tr(n,h,s)).path}catch{u.push("screenshot capture failed")}let f=`obs_${e.observationCounter.toString(36)}`,m={httpStatus:null,loadingState:"idle",hasDialog:!1,consoleErrors:0};return{observationId:f,url:i.url,title:i.title,textSummary:i.content.slice(0,4e3),interactive:d,status:m,warnings:u,screenshotPath:p,capturedAt:new Date().toISOString()}}}});import{existsSync as tL,readFileSync as nL}from"node:fs";import{createRequire as rL}from"node:module";import{dirname as oL,join as sL}from"node:path";function Jb(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<aL&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function Re(t){let e=Jb(t);return zb.some(n=>e.includes(n))}function cL(){try{let e=rL(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(nL(e,"utf8"));if(typeof n!="object"||n===null)return;let r=n.bin,o=typeof r=="string"?r:typeof r=="object"&&r!==null?r.playwright:void 0;if(typeof o!="string"||o.length===0)return;let s=sL(oL(e),o);return tL(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function Fo(){return Xb??=cL()??iL,Xb}function gu(t){return t.includes("install chromium")}function Ke(t,e){let n=Jb(t),r=e?.latched===!0?` ${lL}`:"";if(n.includes("Executable doesn't exist")){let o="";return e?.headless===!0?o=" This launch was headless, which needs the `chromium_headless_shell-*` build.":e?.headless===!1&&(o=" This launch was headed, which needs the full `chromium-*` build \u2014 the headless shell alone does not satisfy it."),`browser tools require the Playwright chromium binary. Install via: ${Fo()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Fo()}). Or pick a different tool.${r}`}function Vi(t,e,n=!1){if(!Re(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
|
|
2
|
+
`)}}}catch{}}function Nm(){mI(fI(),oe())}function Um(t){if(typeof t!="string"||t.length===0)throw new Error("Invalid jobId: must be a non-empty string");if(t.length>vm)throw new Error(`Invalid jobId: exceeds ${vm} chars`);if(!gI.test(t))throw new Error(`Invalid jobId: ${JSON.stringify(t)} contains characters outside [A-Za-z0-9_-]`)}function jl(){return B(Q(),"subagent-logs")}function Hl(t){return Um(t),B(jl(),t)}function $m(t,e){return Um(e),B(Hl(t),`${e}.jsonl`)}function Wl(t){if(typeof t!="string"||t.length===0)throw new Error("Invalid browser profile: must be a non-empty string");if(t.length>Tm)throw new Error(`Invalid browser profile: exceeds ${Tm} chars`);if(!hI.test(t))throw new Error(`Invalid browser profile: ${JSON.stringify(t)} contains characters outside [A-Za-z0-9_-]`)}function yI(){return B(Q(),"browser")}function bI(t){return Wl(t),B(yI(),t)}function Kl(t){return B(bI(t),"storageState.json")}function Dn(t){return typeof t=="string"&&t.length>0&&t.length<=SI&&wI.test(t)}function Gr(t){if(!Dn(t))throw new Error(`Invalid session id for ledger path: ${JSON.stringify(t)}`);return B(oe(),t)}function Xr(t){return B(Gr(t),"events.jsonl")}function Bm(t){return B(Gr(t),"session.key")}function Fn(){return B(Q(),"waves")}function Ln(t){return B(Fn(),`${t}.json`)}var gI,vm,hI,Tm,wI,SI,P=ne(()=>{"use strict";I();Sm();gI=/^[A-Za-z0-9_-]+$/,vm=128;hI=/^[A-Za-z0-9_-]+$/,Tm=128;wI=/^[A-Za-z0-9_-]+$/,SI=128});var cu={};Ns(cu,{enforceDomainPolicy:()=>Ze,loadBrowserConfig:()=>au});import{readFileSync as EF}from"node:fs";import{join as AF}from"path";function xF(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function Pb(t,e){return xF(e).test(t)}function CF(t,e){if(t!==void 0){let n=t.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(e!==void 0){if(RF.has(e))return!0;if(IF.has(e))return!1}return!1}function Mb(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function PF(t){if(t===void 0||t==="")return"auto";if(t==="playwright"||t==="agent-browser"||t==="auto")return t;throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${t}`)}function Ob(t){let e=t===void 0||t.trim()===""?"default":t.trim();return Wl(e),e}function MF(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function OF(t){try{return EF(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function DF(t,e){let n={...t};if(typeof e.headless=="boolean"&&(n.headless=e.headless),Array.isArray(e.allowedDomains)&&(n.allowedDomains=e.allowedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),Array.isArray(e.blockedDomains)&&(n.blockedDomains=e.blockedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),typeof e.domSnapshots=="boolean"&&(n.domSnapshots=e.domSnapshots),e.backend==="playwright"||e.backend==="agent-browser"||e.backend==="auto")n.backend=e.backend;else if(e.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${String(e.backend)}`);return typeof e.defaultProfile=="string"&&(n.defaultProfile=Ob(e.defaultProfile)),n}function au(t){let e=t?.env??b,n=t?.readFileSync??OF,r=t?.surface??e.AGENT_SURFACE,o=CF(e.AFK_BROWSER_HEADLESS,r),s=Mb(e.AFK_BROWSER_ALLOWED_DOMAINS),i=Mb(e.AFK_BROWSER_BLOCKED_DOMAINS),a=MF(e.AFK_BROWSER_DOM_SNAPSHOTS),c=PF(e.AFK_BROWSER_BACKEND),l=Ob(e.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:c,configPath:null,defaultProfile:l},u=e.AFK_BROWSER_CONFIG,p=u!==void 0&&u.trim()!==""?u.trim():AF(qr(),"browser.json"),f=n(p);if(f===void 0)return d;let m;try{m=JSON.parse(f)}catch(h){throw new Error(`Failed to parse browser config at ${p}: ${String(h)}`)}if(typeof m!="object"||m===null||Array.isArray(m))throw new Error(`Browser config at ${p} must be a JSON object`);let g=DF(d,m);return g.configPath=p,g}function Ze(t,e){let n;try{n=new URL(t).hostname.toLowerCase()}catch{return{allowed:!1,reason:`invalid URL: ${t}`}}for(let r of e.blockedDomains)if(Pb(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>Pb(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var RF,IF,Ht=ne(()=>{"use strict";I();P();RF=new Set(["daemon","subagent","telegram","afk"]),IF=new Set(["repl","interactive","cli"])});import{readFileSync as FF}from"node:fs";import{join as LF}from"node:path";import{homedir as NF}from"node:os";function $F(t){let e=t??UF,n;try{n=FF(e,"utf8")}catch{return null}let r;try{r=JSON.parse(n)}catch{return null}if(typeof r!="object"||r===null||Array.isArray(r))return null;let o=r;if(typeof o.url!="string"||typeof o.token!="string"||typeof o.pid!="number")return null;let s;try{s=new URL(o.url)}catch{return null}let{hostname:i,protocol:a}=s;if(!(i==="127.0.0.1"||i==="localhost"||i==="::1")||a!=="http:")throw new Error(`Agent Browser connection file contains an untrusted URL: ${o.url}. Only http://127.0.0.1 or http://localhost is permitted.`);return{url:o.url,token:o.token,pid:o.pid,version:typeof o.version=="string"?o.version:"unknown"}}function BF(t){try{return process.kill(t,0),!0}catch{return!1}}async function jF(t,e,n=2e3){try{let r=new AbortController,o=setTimeout(()=>r.abort(),n),s=await fetch(`${t}/health`,{method:"GET",headers:{Authorization:`Bearer ${e}`,Host:"127.0.0.1:8833"},signal:r.signal});return clearTimeout(o),s.ok}catch{return!1}}async function lu(t){let e=$F(t);return e===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:BF(e.pid)?await jF(e.url,e.token)?{available:!0,connection:e,reason:null}:{available:!1,connection:e,reason:`health probe failed at ${e.url}`}:{available:!1,connection:e,reason:`stale connection file: PID ${e.pid} not alive`}}var UF,Db=ne(()=>{"use strict";UF=LF(NF(),".config","agent-browser","connection.json")});async function Fb(t){let{config:e,surface:n}=t;if(e.backend==="playwright")return{backend:"playwright",reason:"explicit config: backend=playwright",probeMs:0,availability:null};if(e.backend==="agent-browser"){let i=Date.now(),a=await lu(),c=Date.now()-i;if(!a.available)throw new Error(`AFK_BROWSER_BACKEND=agent-browser but Agent Browser is not available: ${a.reason}`);return{backend:"agent-browser",reason:"explicit config: backend=agent-browser",probeMs:c,availability:a}}if(n&&HF.has(n))return{backend:"playwright",reason:`auto: surface "${n}" excluded from Agent Browser`,probeMs:0,availability:null};if(e.headless)return{backend:"playwright",reason:"auto: headless mode requires Playwright",probeMs:0,availability:null};let r=Date.now(),o=await lu(),s=Date.now()-r;return o.available?{backend:"agent-browser",reason:"auto: Agent Browser available and preferred",probeMs:s,availability:o}:{backend:"playwright",reason:`auto: Agent Browser unavailable (${o.reason})`,probeMs:s,availability:o}}var HF,Lb=ne(()=>{"use strict";Db();HF=new Set(["daemon","subagent"])});import{createHash as WF}from"crypto";function Nb(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&KF.test(t.label))}function Ub(t){return WF("sha256").update(t,"utf8").digest("hex").slice(0,8)}function $b(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var KF,zi=ne(()=>{"use strict";KF=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as qF}from"crypto";import{mkdir as GF,stat as XF,writeFile as zF}from"fs/promises";import{join as du}from"path";import{gzip as JF}from"zlib";import{promisify as VF}from"util";function YF(t){return du(et(t),"browser")}function QF(t){return du(YF(t),"screenshots")}function ZF(){return new Date().toISOString().replace(/[:.]/g,"-")}function eL(){return qF(3).toString("hex")}async function tr(t,e,n){if(e.length>Bb)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Bb} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=QF(t);await GF(r,{recursive:!0});let o=`${ZF()}-${eL()}-${n}.png`,s=du(r,o);await zF(s,e);let{size:i}=await XF(s);return{path:s,bytes:i}}var tQ,Bb,uu=ne(()=>{"use strict";P();zi();tQ=VF(JF);Bb=5*1024*1024});var Ji,jb=ne(()=>{"use strict";Ji=class{baseUrl;token;constructor(e){this.baseUrl=e.url,this.token=e.token}async call(e,n,r=3e4){let o={version:1,method:e,params:n},s=new AbortController,i=setTimeout(()=>s.abort(),r);try{let a=await fetch(`${this.baseUrl}/agent`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`,Host:new URL(this.baseUrl).host},body:JSON.stringify(o),signal:s.signal});if(!a.ok){let c=await a.text().catch(()=>"");throw new Error(`Agent Browser ${e} failed (HTTP ${a.status}): ${c}`)}return await a.json()}finally{clearTimeout(i)}}async listTabs(){return(await this.call("tabs.list",null)).tabs}async openTab(e){return{tabId:(await this.call("tabs.open",{url:e},6e4)).tab_id}}async closeTab(e){await this.call("tabs.close",{tab_id:e})}async read(e,n){return this.call("page.read",{tab_id:e,mode:n?.mode??"main",...n?.query?{query:n.query}:{},...n?.budget?{budget:n.budget}:{}})}async inspect(e,n){return this.call("page.inspect",{tab_id:e,mode:n?.mode??"interactive",...n?.query?{query:n.query}:{},...n?.limit?{limit:n.limit}:{}})}async click(e,n){await this.call("page.click",{tab_id:e,element_id:n})}async fill(e,n,r){await this.call("page.fill",{tab_id:e,element_id:n,value:r})}async press(e,n,r){await this.call("page.press",{tab_id:e,key:n,...r?{element_id:r}:{}})}async select(e,n,r){await this.call("page.select",{tab_id:e,element_id:n,value:r})}async waitFor(e,n,r){await this.call("page.wait",{tab_id:e,condition:n,...r?.value?{value:r.value}:{},...r?.timeout?{timeout:r.timeout}:{}},(r?.timeout??3e4)+5e3)}async evalScript(e,n){return this.call("page.eval",{tab_id:e,script:n})}async screenshot(e){return this.call("page.screenshot",{tab_id:e})}}});function pu(t){return{id:t.id,role:t.role,label:t.label,kind:t.kind,value:t.value,state:{disabled:t.disabled,...t.checked!==void 0?{checked:t.checked}:{},...t.selected!==void 0?{selected:t.selected}:{},...t.expanded!==void 0?{expanded:t.expanded}:{}},bbox:t.bbox,...t.selector?{selector:t.selector}:{}}}function Hb(t,e){switch(e.kind){case"element_id":if(t.has(e.elementId))return e.elementId;throw new Error(`Element ${e.elementId} not found in current observation. Call browser_observe to refresh.`);case"selector":return null;case"semantic":return null}}async function fu(t,e,n,r,o,s){switch(n){case"click":await t.click(e,r);break;case"fill":if(o===void 0)throw new Error("fill requires a value");await t.fill(e,r,o);break;case"press":if(o===void 0)throw new Error("press requires a value (key combo)");await t.press(e,o,r);break;case"select":if(o===void 0)throw new Error("select requires a value");await t.select(e,r,o);break;case"hover":throw new Error("hover is not supported by Agent Browser; use element_id from a prior observation to target clicks instead");case"scroll_to":{let i=r.replace(/\\/g,"\\\\").replace(/"/g,'\\"');await t.evalScript(e,`document.querySelector('[data-element-id="${i}"]')?.scrollIntoView({behavior:'smooth',block:'center'})`);break}case"wait_for":await t.waitFor(e,"element",{value:r,timeout:s??1e4});break;default:throw new Error(`Unknown action: ${n}`)}}async function Wb(t,e){if(e.target.kind!=="semantic")throw new Error("resolveSemanticAndAct called with non-semantic target");let{elements:n}=await t.client.inspect(t.tabId,{mode:"interactive",query:e.target.text,limit:10}),r=n;if(e.target.role){let c=e.target.role.toLowerCase();r=n.filter(l=>l.role.toLowerCase()===c)}if(r.length===0)throw new Error(`No element found matching semantic target: text="${e.target.text}"`+(e.target.role?`, role="${e.target.role}"`:""));if(r.length>1)return{outcome:"ambiguous_target",query:{text:e.target.text,...e.target.role?{role:e.target.role}:{}},candidates:r.slice(0,5).map(pu)};let s=r[0].id;await fu(t.client,t.tabId,e.action,s,e.value,e.timeoutMs);let i=await t.client.read(t.tabId,{mode:"main"}),a=Ze(i.url,t.config);return a.allowed?{elementId:s}:{outcome:"blocked_by_policy",url:i.url,reason:`action navigated to blocked domain: ${a.reason}`}}var Kb=ne(()=>{"use strict";Ht()});var qb={};Ns(qb,{AgentBrowserProvider:()=>mu});var mu,Gb=ne(()=>{"use strict";Ht();uu();jb();Kb();mu=class{name="agent-browser";config;client;sessions=new Map;constructor(e,n){this.config=e,this.client=new Ji(n)}async open(e){let n=Ze(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let r=this.sessions.get(e.sessionId);if(r)await this.client.evalScript(r.tabId,`window.location.href = ${JSON.stringify(e.url)}`),await this.client.waitFor(r.tabId,"load",{timeout:e.timeoutMs??3e4});else{let{tabId:i}=await this.client.openTab(e.url);await this.client.waitFor(i,"load",{timeout:e.timeoutMs??3e4}),r={tabId:i,observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null},this.sessions.set(e.sessionId,r)}let o=await this.client.read(r.tabId,{mode:"main"}),s=Ze(o.url,this.config);return s.allowed?this.buildObservation(r,e.sessionId,e.screenshot,void 0,"browser_open"):(await this.client.evalScript(r.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`redirected to blocked domain: ${s.reason}`})}async observe(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);return this.buildObservation(n,e.sessionId,e.screenshot,e.maxElements,"browser_observe")}async act(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);let r=Hb(n.knownElements,e.target);if(r===null){if(e.target.kind==="semantic"){let i=await Wb({client:this.client,config:this.config,tabId:n.tabId},e);return"outcome"in i?i:(n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString(),this.buildObservation(n,e.sessionId,e.screenshot,void 0,"browser_act"))}throw e.target.kind==="selector"?new Error("selector targets are not supported by Agent Browser; use element_id or semantic targets"):new Error(`Cannot resolve target: ${JSON.stringify(e.target)}`)}await fu(this.client,n.tabId,e.action,r,e.value,e.timeoutMs),n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString();let o=await this.client.read(n.tabId,{mode:"main"}),s=Ze(o.url,this.config);return s.allowed?this.buildObservation(n,e.sessionId,e.screenshot,void 0,"browser_act"):(await this.client.evalScript(n.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`action navigated to blocked domain: ${s.reason}`})}async render(e){throw new Error("AgentBrowserProvider does not support render(). Use PlaywrightProvider for one-shot content fetches.")}async screenshot(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);if(e.target!==void 0||e.fullPage)throw new Error("Agent Browser does not support element or full-page screenshots; omit target and fullPage.");let r=await this.client.screenshot(n.tabId),o=Buffer.from(r.data,"base64"),s=o.length>=24?o.readUInt32BE(16):0,i=o.length>=24?o.readUInt32BE(20):0;return{path:(await tr(e.sessionId,o,"browser_screenshot")).path,bytes:o.length,width:s,height:i,dataBase64:r.data,mediaType:"image/png"}}async extract(e){throw new Error("AgentBrowserProvider does not support extract() yet.")}async close(e){let n=this.sessions.get(e.sessionId);if(n){try{await this.client.closeTab(n.tabId)}catch{}this.sessions.delete(e.sessionId)}}describe(e){let n=this.sessions.get(e);return n?{active:!0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:1}:null}async shutdown(){let e=Array.from(this.sessions.entries()).map(async([,n])=>{try{await this.client.closeTab(n.tabId)}catch{}});await Promise.all(e),this.sessions.clear()}async buildObservation(e,n,r,o,s="browser_open"){let[i,a]=await Promise.all([this.client.read(e.tabId,{mode:"main",budget:4e3}),this.client.inspect(e.tabId,{mode:"interactive",limit:o??80})]),c=a.elements.map(pu),l=o??80,d=c.slice(0,l);e.observationCounter+=1,e.knownElements=new Map(d.map(g=>[g.id,g])),e.currentUrl=i.url,e.currentTitle=i.title;let u=[];c.length>l&&u.push(`page has ${c.length} interactive elements; showing first ${l}`);let p=null;if(r)try{let g=await this.client.screenshot(e.tabId),h=Buffer.from(g.data,"base64");p=(await tr(n,h,s)).path}catch{u.push("screenshot capture failed")}let f=`obs_${e.observationCounter.toString(36)}`,m={httpStatus:null,loadingState:"idle",hasDialog:!1,consoleErrors:0};return{observationId:f,url:i.url,title:i.title,textSummary:i.content.slice(0,4e3),interactive:d,status:m,warnings:u,screenshotPath:p,capturedAt:new Date().toISOString()}}}});import{existsSync as tL,readFileSync as nL}from"node:fs";import{createRequire as rL}from"node:module";import{dirname as oL,join as sL}from"node:path";function Jb(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<aL&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function Re(t){let e=Jb(t);return zb.some(n=>e.includes(n))}function cL(){try{let e=rL(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(nL(e,"utf8"));if(typeof n!="object"||n===null)return;let r=n.bin,o=typeof r=="string"?r:typeof r=="object"&&r!==null?r.playwright:void 0;if(typeof o!="string"||o.length===0)return;let s=sL(oL(e),o);return tL(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function Fo(){return Xb??=cL()??iL,Xb}function gu(t){return t.includes("install chromium")}function Ke(t,e){let n=Jb(t),r=e?.latched===!0?` ${lL}`:"";if(n.includes("Executable doesn't exist")){let o="";return e?.headless===!0?o=" This launch was headless, which needs the `chromium_headless_shell-*` build.":e?.headless===!1&&(o=" This launch was headed, which needs the full `chromium-*` build \u2014 the headless shell alone does not satisfy it."),`browser tools require the Playwright chromium binary. Install via: ${Fo()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Fo()}). Or pick a different tool.${r}`}function Vi(t,e,n=!1){if(!Re(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
|
|
3
3
|
|
|
4
|
-
${Ke(t,{headless:e,latched:n})}`,{cause:t})}var zb,iL,aL,Xb,lL,hu=ne(()=>{"use strict";zb=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],iL="pnpm exec playwright install chromium",aL=4;lL="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import bn from"node:fs";import Yi from"node:path";import{randomBytes as dL}from"node:crypto";function uL(){try{return"5.191.5"}catch{}try{let t=Yi.resolve(import.meta.dirname,"../../../package.json"),e=bn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var pL,Qi,Vb=ne(()=>{"use strict";hu();P();J();pL=uL(),Qi=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let e;try{({chromium:e}=await import("playwright"))}catch(n){let r=Vi(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await e.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Vi(n,this.config.headless,!0);throw this.latchLaunchFailure(r),r}finally{this.launchPromise=void 0}})(),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${pL}`}}loadStorageState(e){let n=Kl(e);try{if(!bn.existsSync(n))return;let r=JSON.parse(bn.readFileSync(n,"utf8"));return C("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){C("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Kl(e);if(!bn.existsSync(r))return;let o=await n.storageState(),s=Yi.join(Yi.dirname(r),`.${Yi.basename(r)}.${process.pid}.${dL(4).toString("hex")}.tmp`);bn.writeFileSync(s,JSON.stringify(o),{mode:384}),bn.chmodSync(s,384),bn.renameSync(s,r),C("[browser/vault] saved session",{profile:e,file:r})}catch(r){C("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as fL}from"node:crypto";function mL(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function gL(t,e,n){return`el_${fL("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function hL(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Yb(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function Zb(t,e){let n=t.role??"",r=t.name??"";Qb.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])Zb(s,e)}async function yL(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},ew).catch(()=>[])}async function bL(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let g=s.type;g==="checkbox"?l="checkbox":g==="radio"?l="radio":g==="button"||g==="submit"||g==="reset"?l="button":g==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},ew).catch(()=>[])}function wL(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Zi(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=wL(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=yL(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,c,l,d]),h,y=!1;u!==null?(h=[],Zb(u,h)):(o.push("observation skipped accessibility tree (returned null)"),y=!0,h=(await bL(t)).filter(O=>Qb.has(O.role??"")));let w=new Map;for(let E of p){let O=Yb(E.name),K=w.get(O);(!K||K.bbox.w===0&&E.bbox.w>0)&&w.set(O,E)}let k=h.map(E=>({ax:E,dom:w.get(Yb(E.name??""))})),v=r?k:k.filter(E=>E.dom?E.dom.bbox.w>0||E.dom.bbox.h>0:!0);v.sort((E,O)=>{let K=E.dom?.bbox.y??0,F=O.dom?.bbox.y??0;if(K!==F)return K-F;let L=E.dom?.bbox.x??0,D=O.dom?.bbox.x??0;return L-D}),v.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=v.slice(0,n).map((E,O)=>{let K=E.ax.role??"generic",F=E.ax.name??"",L=gL(K,F,O),D=E.dom?.bbox??{x:0,y:0,w:0,h:0},N=E.dom?.type??null,W=null;E.ax.value!==void 0&&E.ax.value!==null&&(W=String(E.ax.value)),E.ax.checked!==void 0&&(W=String(E.ax.checked)),Nb({role:K,kind:N})&&(W="[redacted]");let H={disabled:E.ax.disabled??!1};E.ax.checked!==void 0&&(H.checked=E.ax.checked===!0||E.ax.checked==="mixed"),E.ax.selected!==void 0&&(H.selected=E.ax.selected),E.ax.expanded!==void 0&&(H.expanded=E.ax.expanded);let de;E.dom?.testId?de=`[data-testid="${E.dom.testId}"]`:E.dom?.id&&(de=`#${E.dom.id}`);let mt={id:L,role:K,label:mL(F),kind:N,value:W,state:H,bbox:D};return de!==void 0&&(mt.selector=de),mt}),A="idle";try{let E=await t.evaluate(()=>document.readyState);E==="loading"?A="loading":E==="interactive"?A="navigating":A="idle"}catch{A="navigating"}A!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),y&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let M=hL(f),S=`obs_${e.observationCounter.toString(36)}`,T=new Date().toISOString();return{observationId:S,url:m,title:g,textSummary:M,interactive:R,status:{httpStatus:e.httpStatus??null,loadingState:A,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:T}}var Qb,ew,tw=ne(()=>{"use strict";zi();Qb=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);ew="a[href], button, input, select, textarea, [role], [tabindex], label"});async function nw(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${e}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function yu(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>nw(t,s)))).filter(o=>o!==null)}async function SL(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function bu(t,e,n){switch(e.kind){case"element_id":return kL(t,e,n);case"selector":return vL(t,e);case"semantic":return TL(t,e)}}async function kL(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await yu(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function vL(t,e){let n=t.locator(e.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:e};if(r===1)return{outcome:"resolved",locator:n};let o=await yu(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function TL(t,e){return e.role!==void 0?_L(t,e.text,e.role):EL(t,e.text,e)}async function _L(t,e,n){let r=t.getByRole(n,{name:e}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:e,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await yu(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function EL(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await SL(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let h=p[g];if(h===void 0)continue;let y=await nw(h.locator,h.index);if(y!==null){let w=`${y.role}:${y.label}:${g}`,k=0;for(let v=0;v<w.length;v++)k=k*31+w.charCodeAt(v)>>>0;f.push({...y,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var rw=ne(()=>{"use strict"});async function wu(t,e,n,r){let o=t.url();if(o===n)return null;let s=Ze(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var ow=ne(()=>{"use strict";Ht()});var ku={};Ns(ku,{PlaywrightProvider:()=>Su});function sw(t){switch(t.kind){case"semantic":return t.role!==void 0?`semantic('${t.text}', role='${t.role}')`:`semantic('${t.text}')`;case"element_id":return`element_id(${t.elementId})`;case"selector":return`selector(${t.selector})`}}var Su,vu=ne(()=>{"use strict";Vb();tw();rw();Ht();ow();uu();Su=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Qi(e)}async open(e){let n=Ze(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await wu(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await Zi(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await Zi(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:e.includeHidden,maxElements:e.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=e.timeoutMs??3e4,a=await bu(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${sw(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(h){l=h}else l=g}let u=await wu(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Zi(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await bu(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${sw(e.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:e.fullPage??!1});let{path:i,bytes:a}=await tr(n,s,"browser_screenshot"),c=0,l=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(e){let n=this.sessions.get(e);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await tr(n,o,r);return s}catch{return null}}}});var Sn={};Ns(Sn,{__resetBrowserRegistryForTests:()=>PL,browserProviderActive:()=>RL,closeBrowserProvider:()=>_u,getBrowserProvider:()=>xL,getLastRoutingDecision:()=>CL,peekBrowserProvider:()=>IL});function iw(){Promise.resolve(_u()).then(()=>{process.exit(130)})}function aw(){Promise.resolve(_u()).then(()=>{process.exit(143)})}function cw(){at=null}function AL(){ea||(process.on("SIGINT",iw),process.on("SIGTERM",aw),process.on("exit",cw),ea=!0)}function lw(){ea&&(process.removeListener("SIGINT",iw),process.removeListener("SIGTERM",aw),process.removeListener("exit",cw),ea=!1)}async function xL(t){return at!==null?at:(wn!==null||(wn=(async()=>{let e=au(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??b.AGENT_SURFACE,r=await Fb({config:e,surface:n});Tu=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(Gb(),qb)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(vu(),ku));o=new s(e)}return AL(),at=o,wn=null,o})()),wn)}async function _u(){if(at===null)return;let t=at;at=null,wn=null,lw(),await t.shutdown()}function RL(){return at!==null}function IL(){return at}function CL(){return Tu}function PL(){at=null,wn=null,Tu=null,lw()}var at,wn,ea,Tu,kn=ne(()=>{"use strict";Ht();Lb();I();at=null,wn=null,ea=!1,Tu=null});J();I();P();import{randomBytes as FI}from"node:crypto";import{mkdir as LI,writeFile as NI}from"node:fs/promises";import{join as UI}from"node:path";J();var kI=256,jm=new WeakMap,zr=new Map;function vI(t){return t instanceof Error?t.message:String(t)}function TI(t,e){if(typeof e=="object"&&e!==null){let r=jm.get(e);return r||(r=new Set,jm.set(e,r)),r.has(t)?!1:(r.add(t),!0)}let n=`${t}\0${String(e)}`;if(zr.has(n))return!1;if(zr.set(n,!0),zr.size>kI){let r=zr.keys().next().value;r!==void 0&&zr.delete(r)}return!0}function ue(t,e,n,r){try{let o=`[afk] ${t} artifact write failed (${n}): ${vI(r)}`;if(!TI(t,e)){C(o);return}console.error(`${o} \u2014 further failures in this subsystem for this session are logged only under AFK_DEBUG=1.`)}catch{}}I();import{mkdirSync as EI,appendFileSync as AI,existsSync as xI}from"fs";import{resolve as RI}from"path";import{dirname as II}from"path";function tt(t){return t.replace(/\bauthorization:\s*bearer\s+\S+/gi,"Authorization: Bearer [REDACTED]").replace(/\bsk-ant-[A-Za-z0-9_-]{20,}/g,"[REDACTED]").replace(/\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,"[REDACTED]").replace(/\b(?:AKIA|ASIA|AROA|AIDA|AGPA|AIPA|ANPA|ANVA|APKA|ABIA|ACCA)[A-Z0-9]{16}\b/g,"[REDACTED]").replace(/(?<![/.\w])[A-Za-z0-9+/=_-]{32,}(?![/.\w])/g,e=>ql(e)||_I(e)?e:"[REDACTED]")}function ql(t){if(!t.includes("/")||/[+=]/.test(t))return!1;let e=n=>n.length>=32&&!n.includes(".")&&/[A-Za-z]/.test(n)&&/[0-9]/.test(n);return!t.split("/").some(e)}function _I(t){if(/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/.test(t))return!0;let e=/^([A-Za-z_][A-Za-z0-9_]*)=(?:[0-9a-f]{40}|[0-9a-f]{64})$/.exec(t);return e!==null&&/^(?:ref|sha|commit|base)$/i.test(e[1]??"")}var CI=`# AFK PROMPT DUMP \u2014 May contain secrets. Inspect before sharing.
|
|
4
|
+
${Ke(t,{headless:e,latched:n})}`,{cause:t})}var zb,iL,aL,Xb,lL,hu=ne(()=>{"use strict";zb=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],iL="pnpm exec playwright install chromium",aL=4;lL="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import bn from"node:fs";import Yi from"node:path";import{randomBytes as dL}from"node:crypto";function uL(){try{return"5.191.7"}catch{}try{let t=Yi.resolve(import.meta.dirname,"../../../package.json"),e=bn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var pL,Qi,Vb=ne(()=>{"use strict";hu();P();J();pL=uL(),Qi=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let e;try{({chromium:e}=await import("playwright"))}catch(n){let r=Vi(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await e.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Vi(n,this.config.headless,!0);throw this.latchLaunchFailure(r),r}finally{this.launchPromise=void 0}})(),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${pL}`}}loadStorageState(e){let n=Kl(e);try{if(!bn.existsSync(n))return;let r=JSON.parse(bn.readFileSync(n,"utf8"));return C("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){C("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Kl(e);if(!bn.existsSync(r))return;let o=await n.storageState(),s=Yi.join(Yi.dirname(r),`.${Yi.basename(r)}.${process.pid}.${dL(4).toString("hex")}.tmp`);bn.writeFileSync(s,JSON.stringify(o),{mode:384}),bn.chmodSync(s,384),bn.renameSync(s,r),C("[browser/vault] saved session",{profile:e,file:r})}catch(r){C("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as fL}from"node:crypto";function mL(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function gL(t,e,n){return`el_${fL("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function hL(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Yb(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function Zb(t,e){let n=t.role??"",r=t.name??"";Qb.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])Zb(s,e)}async function yL(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},ew).catch(()=>[])}async function bL(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let g=s.type;g==="checkbox"?l="checkbox":g==="radio"?l="radio":g==="button"||g==="submit"||g==="reset"?l="button":g==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},ew).catch(()=>[])}function wL(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Zi(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=wL(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=yL(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,c,l,d]),h,y=!1;u!==null?(h=[],Zb(u,h)):(o.push("observation skipped accessibility tree (returned null)"),y=!0,h=(await bL(t)).filter(O=>Qb.has(O.role??"")));let w=new Map;for(let E of p){let O=Yb(E.name),K=w.get(O);(!K||K.bbox.w===0&&E.bbox.w>0)&&w.set(O,E)}let k=h.map(E=>({ax:E,dom:w.get(Yb(E.name??""))})),v=r?k:k.filter(E=>E.dom?E.dom.bbox.w>0||E.dom.bbox.h>0:!0);v.sort((E,O)=>{let K=E.dom?.bbox.y??0,F=O.dom?.bbox.y??0;if(K!==F)return K-F;let L=E.dom?.bbox.x??0,D=O.dom?.bbox.x??0;return L-D}),v.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=v.slice(0,n).map((E,O)=>{let K=E.ax.role??"generic",F=E.ax.name??"",L=gL(K,F,O),D=E.dom?.bbox??{x:0,y:0,w:0,h:0},N=E.dom?.type??null,W=null;E.ax.value!==void 0&&E.ax.value!==null&&(W=String(E.ax.value)),E.ax.checked!==void 0&&(W=String(E.ax.checked)),Nb({role:K,kind:N})&&(W="[redacted]");let H={disabled:E.ax.disabled??!1};E.ax.checked!==void 0&&(H.checked=E.ax.checked===!0||E.ax.checked==="mixed"),E.ax.selected!==void 0&&(H.selected=E.ax.selected),E.ax.expanded!==void 0&&(H.expanded=E.ax.expanded);let de;E.dom?.testId?de=`[data-testid="${E.dom.testId}"]`:E.dom?.id&&(de=`#${E.dom.id}`);let mt={id:L,role:K,label:mL(F),kind:N,value:W,state:H,bbox:D};return de!==void 0&&(mt.selector=de),mt}),A="idle";try{let E=await t.evaluate(()=>document.readyState);E==="loading"?A="loading":E==="interactive"?A="navigating":A="idle"}catch{A="navigating"}A!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),y&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let M=hL(f),S=`obs_${e.observationCounter.toString(36)}`,T=new Date().toISOString();return{observationId:S,url:m,title:g,textSummary:M,interactive:R,status:{httpStatus:e.httpStatus??null,loadingState:A,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:T}}var Qb,ew,tw=ne(()=>{"use strict";zi();Qb=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);ew="a[href], button, input, select, textarea, [role], [tabindex], label"});async function nw(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${e}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function yu(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>nw(t,s)))).filter(o=>o!==null)}async function SL(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function bu(t,e,n){switch(e.kind){case"element_id":return kL(t,e,n);case"selector":return vL(t,e);case"semantic":return TL(t,e)}}async function kL(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await yu(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function vL(t,e){let n=t.locator(e.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:e};if(r===1)return{outcome:"resolved",locator:n};let o=await yu(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function TL(t,e){return e.role!==void 0?_L(t,e.text,e.role):EL(t,e.text,e)}async function _L(t,e,n){let r=t.getByRole(n,{name:e}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:e,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await yu(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function EL(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await SL(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let h=p[g];if(h===void 0)continue;let y=await nw(h.locator,h.index);if(y!==null){let w=`${y.role}:${y.label}:${g}`,k=0;for(let v=0;v<w.length;v++)k=k*31+w.charCodeAt(v)>>>0;f.push({...y,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var rw=ne(()=>{"use strict"});async function wu(t,e,n,r){let o=t.url();if(o===n)return null;let s=Ze(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var ow=ne(()=>{"use strict";Ht()});var ku={};Ns(ku,{PlaywrightProvider:()=>Su});function sw(t){switch(t.kind){case"semantic":return t.role!==void 0?`semantic('${t.text}', role='${t.role}')`:`semantic('${t.text}')`;case"element_id":return`element_id(${t.elementId})`;case"selector":return`selector(${t.selector})`}}var Su,vu=ne(()=>{"use strict";Vb();tw();rw();Ht();ow();uu();Su=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Qi(e)}async open(e){let n=Ze(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await wu(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await Zi(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await Zi(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:e.includeHidden,maxElements:e.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=e.timeoutMs??3e4,a=await bu(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${sw(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(h){l=h}else l=g}let u=await wu(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Zi(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await bu(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${sw(e.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:e.fullPage??!1});let{path:i,bytes:a}=await tr(n,s,"browser_screenshot"),c=0,l=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(e){let n=this.sessions.get(e);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await tr(n,o,r);return s}catch{return null}}}});var Sn={};Ns(Sn,{__resetBrowserRegistryForTests:()=>PL,browserProviderActive:()=>RL,closeBrowserProvider:()=>_u,getBrowserProvider:()=>xL,getLastRoutingDecision:()=>CL,peekBrowserProvider:()=>IL});function iw(){Promise.resolve(_u()).then(()=>{process.exit(130)})}function aw(){Promise.resolve(_u()).then(()=>{process.exit(143)})}function cw(){at=null}function AL(){ea||(process.on("SIGINT",iw),process.on("SIGTERM",aw),process.on("exit",cw),ea=!0)}function lw(){ea&&(process.removeListener("SIGINT",iw),process.removeListener("SIGTERM",aw),process.removeListener("exit",cw),ea=!1)}async function xL(t){return at!==null?at:(wn!==null||(wn=(async()=>{let e=au(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??b.AGENT_SURFACE,r=await Fb({config:e,surface:n});Tu=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(Gb(),qb)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(vu(),ku));o=new s(e)}return AL(),at=o,wn=null,o})()),wn)}async function _u(){if(at===null)return;let t=at;at=null,wn=null,lw(),await t.shutdown()}function RL(){return at!==null}function IL(){return at}function CL(){return Tu}function PL(){at=null,wn=null,Tu=null,lw()}var at,wn,ea,Tu,kn=ne(()=>{"use strict";Ht();Lb();I();at=null,wn=null,ea=!1,Tu=null});J();I();P();import{randomBytes as FI}from"node:crypto";import{mkdir as LI,writeFile as NI}from"node:fs/promises";import{join as UI}from"node:path";J();var kI=256,jm=new WeakMap,zr=new Map;function vI(t){return t instanceof Error?t.message:String(t)}function TI(t,e){if(typeof e=="object"&&e!==null){let r=jm.get(e);return r||(r=new Set,jm.set(e,r)),r.has(t)?!1:(r.add(t),!0)}let n=`${t}\0${String(e)}`;if(zr.has(n))return!1;if(zr.set(n,!0),zr.size>kI){let r=zr.keys().next().value;r!==void 0&&zr.delete(r)}return!0}function ue(t,e,n,r){try{let o=`[afk] ${t} artifact write failed (${n}): ${vI(r)}`;if(!TI(t,e)){C(o);return}console.error(`${o} \u2014 further failures in this subsystem for this session are logged only under AFK_DEBUG=1.`)}catch{}}I();import{mkdirSync as EI,appendFileSync as AI,existsSync as xI}from"fs";import{resolve as RI}from"path";import{dirname as II}from"path";function tt(t){return t.replace(/\bauthorization:\s*bearer\s+\S+/gi,"Authorization: Bearer [REDACTED]").replace(/\bsk-ant-[A-Za-z0-9_-]{20,}/g,"[REDACTED]").replace(/\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,"[REDACTED]").replace(/\b(?:AKIA|ASIA|AROA|AIDA|AGPA|AIPA|ANPA|ANVA|APKA|ABIA|ACCA)[A-Z0-9]{16}\b/g,"[REDACTED]").replace(/(?<![/.\w])[A-Za-z0-9+/=_-]{32,}(?![/.\w])/g,e=>ql(e)||_I(e)?e:"[REDACTED]")}function ql(t){if(!t.includes("/")||/[+=]/.test(t))return!1;let e=n=>n.length>=32&&!n.includes(".")&&/[A-Za-z]/.test(n)&&/[0-9]/.test(n);return!t.split("/").some(e)}function _I(t){if(/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/.test(t))return!0;let e=/^([A-Za-z_][A-Za-z0-9_]*)=(?:[0-9a-f]{40}|[0-9a-f]{64})$/.exec(t);return e!==null&&/^(?:ref|sha|commit|base)$/i.test(e[1]??"")}var CI=`# AFK PROMPT DUMP \u2014 May contain secrets. Inspect before sharing.
|
|
5
5
|
`,PI=/key|token|secret|password|credential|auth/i;function Hm(t){let e=t[1],n=t[2],r=n[0],o=(r==='"'||r==="'")&&n.at(-1)===r?n.slice(1,-1):n,s=/(?:^|_)(?:PATH|FILE)(?:_|$)/i.test(e),i=o.startsWith("/")||o.startsWith("~/"),c=o.split("/").filter(Boolean).some(l=>/[A-Z0-9.\-]/.test(l));return s&&i&&c&&ql(o)?`${e}=${n}`:`${e}=<REDACTED length=${n.length}>`}var MI=[[/sk-ant-[A-Za-z0-9_\-]{8,200}/g,t=>`<REDACTED sk-ant length=${t[0].length}>`],[/sk-(?!ant-)[A-Za-z0-9_\-]{20,200}/g,t=>`<REDACTED sk- length=${t[0].length}>`],[/Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi,t=>`<REDACTED Bearer length=${t[0].length}>`],[/AKIA[A-Z0-9]{16}/g,t=>`<REDACTED AKIA length=${t[0].length}>`],[/xox[baprs]-[A-Za-z0-9\-]{10,200}/g,t=>`<REDACTED xox token length=${t[0].length}>`],[/\d{8,12}:[A-Za-z0-9_\-]{35}/g,t=>`<REDACTED Telegram token length=${t[0].length}>`],[/([A-Za-z_]{3,}(?:[Kk][Ee][Yy]|[Tt][Oo][Kk][Ee][Nn]|[Ss][Ee][Cc][Rr][Ee][Tt]|[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]|[Cc][Rr][Ee][Dd][Ee][Nn][Tt][Ii][Aa][Ll])[A-Za-z_]*)=([^\s]{16,})/g,Hm],[/([A-Z_]{3,}(?:KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|AUTH)[A-Z_]*)=([^\s]{16,})/g,Hm]];function Jr(t){let e=t;for(let[n,r]of MI)e=e.replace(n,(...o)=>{let s=o.slice(0,o.length-2);return r(s)});return e}function Gl(t){return typeof t=="string"?Jr(t):Array.isArray(t)?t.map(Gl):t}function OI(t){if(t===null||typeof t!="object")return t;let e=t,n={...e},r=e.env;if(r&&typeof r=="object"){let o={};for(let[s,i]of Object.entries(r))PI.test(s)&&typeof i=="string"?o[s]=`<REDACTED length=${i.length}>`:o[s]=i;n.env=o}return"system"in e&&(n.system=Gl(e.system)),"systemPrompt"in e&&(n.systemPrompt=Gl(e.systemPrompt)),n}function DI(t){if(t==null)return{kind:"undefined",note:"SDK uses minimal prompt; claude_code preset NOT loaded"};if(typeof t=="string")return{kind:"custom-string",note:"SDK uses this string as full system prompt; claude_code preset NOT loaded"};if(Array.isArray(t))return{kind:"custom-string-array",note:"SDK uses array as full system prompt with cache boundaries; claude_code preset NOT loaded"};if(typeof t=="object"){let e=t;if(e.type==="preset"&&e.preset==="claude_code"){let n={kind:"preset-claude-code",note:"claude_code preset loaded"};return typeof e.append=="string"&&(n.append={length:e.append.length}),e.excludeDynamicSections===!0&&(n.excludeDynamicSections=!0),n}return{kind:"custom-string",note:"Unrecognized systemPrompt shape; treated as opaque"}}return{kind:"custom-string",note:"Unrecognized systemPrompt shape; treated as opaque"}}function Wm(t){let e=b.AFK_DUMP_PROMPT;if(!e||e===""||e==="0"||e.toLowerCase()==="false")return;process.stderr.write(`[--dump-prompt] WARNING: dump may contain secrets from system prompt or messages. Inspect before sharing.
|
|
6
6
|
`);let n=t.options,r=typeof n=="object"&&n!==null?n.systemPrompt:void 0,o=DI(r),s={timestamp:new Date().toISOString(),prompt:t.prompt,options:OI(t.options),provenance:t.provenance,resolution:o};if(e==="1"||e.toLowerCase()==="true"||e.toLowerCase()==="stderr"){let c=JSON.stringify(s,null,2)+`
|
|
7
7
|
`;process.stderr.write(c);return}let i=RI(e),a=II(i);try{EI(a,{recursive:!0});let l=(!xI(i)?CI:"")+JSON.stringify(s)+`
|
|
@@ -26,7 +26,7 @@ ${r}
|
|
|
26
26
|
`}function Jm(t){if(!XI(t))return null;let e=Ll(t.sessionId),n=qI(e,`${zI(t.subagentId)}.md`),r=[],o=0,s=!1,i=!1,a=!1,c=Promise.resolve(),l=u=>{if(s)return;o>=Xm&&(s=!0,u=`
|
|
27
27
|
<!-- CAP REACHED at ${Xm} bytes \u2014 capture stopped -->
|
|
28
28
|
`),o+=Buffer.byteLength(u,"utf8");let p=i?u:`${JI(t)}${u}`;i=!0,c=c.then(async()=>{await KI(e,{recursive:!0,mode:448}),await WI(n,p,{encoding:"utf8",mode:384})}).catch(f=>{ue("subagent-output-capture",t.sessionId??"unknown","write",f)})},d=()=>{if(r.length===0)return;let u=r.join("").trim();r=[],u.length>0&&(l(Js("say",{text:u})),a=!0)};return{observe(u){try{if(u.type==="chunk"){let p=u.chunk;if(p.type==="content"){r.push(p.content);return}if(p.type==="tool_use_detail"){if(p.pending)return;d(),l(Js("tool",{toolName:p.toolName,toolInput:p.toolInputCapture??p.toolInputRaw??p.toolInput}))}return}if(u.type==="message"){if(!a&&r.length===0){let p=u.message.content.trim();p.length>0&&(l(Js("say",{text:p})),a=!0)}return}(u.type==="done"||u.type==="error")&&(d(),a=!1)}catch(p){ue("subagent-output-capture",t.sessionId??"unknown","observe",p)}},end(u){try{d(),l(Js("end",{reason:u}))}catch(p){ue("subagent-output-capture",t.sessionId??"unknown","end",p)}}}}var Fe=class extends Error{constructor(e){super(e),this.name="AbortError"}},_e=class extends Error{constructor(n,r){super(n);this.timeoutMs=r;this.name="TimeoutError"}timeoutMs},Vs=class extends _e{constructor(e,n){super(e,n),this.name="IdleWatchdogError"}},q=class extends Error{constructor(n,r,o,s){super(n);this.event=r;this.reason=o;this.name="HookBlockedError",s?.cause!==void 0&&(this.cause=s.cause),s?.injectContext!==void 0&&(this.injectContext=s.injectContext)}event;reason;cause;injectContext},Le=class extends Error{toolResultsGathered;constructor(e){super(e),this.name="StreamIncompleteError"}},nt=class extends Error{constructor(n,r,o){super(o??`Budget ceiling reached: $${n.toFixed(4)} cumulative >= $${r.toFixed(4)} limit`);this.runningCostUsd=n;this.maxBudgetUsd=r;this.name="BudgetExceededError"}runningCostUsd;maxBudgetUsd},Nn=class extends Error{constructor(e){super(e),this.name="DenialCircuitBreakerError"}};var Ys=class{subscribers=new Set;closed=!1;push(e){for(let n of this.subscribers)if(n.resolve){let r=n.resolve;n.resolve=null,r({value:e,done:!1})}else n.buffer.push(e)}close(){this.closed=!0;for(let e of this.subscribers)if(e.resolve){let n=e.resolve;e.resolve=null,n({value:void 0,done:!0})}}subscribe(){let e={buffer:[],resolve:null};this.subscribers.add(e);let n=this,r={next(){return e.buffer.length>0?Promise.resolve({value:e.buffer.shift(),done:!1}):n.closed?(n.subscribers.delete(e),Promise.resolve({value:void 0,done:!0})):new Promise(o=>{e.resolve=o})},return(){if(e.resolve){let o=e.resolve;e.resolve=null,o({value:void 0,done:!0})}return n.subscribers.delete(e),Promise.resolve({value:void 0,done:!0})}};return{[Symbol.asyncIterator]:()=>r}}};async function on(t,e){if(t)try{await t.write({kind:"tool_call",payload:e})}catch(n){ue("trace.emit",t,"tool_call",n)}}async function Mt(t,e){if(t)try{await t.write({kind:"hook_decision",payload:e})}catch(n){ue("trace.emit",t,"hook_decision",n)}}async function sn(t,e){if(t)try{await t.write({kind:"subagent_lifecycle",payload:e})}catch(n){ue("trace.emit",t,"subagent_lifecycle",n)}}async function Vm(t,e){if(t)try{await t.write({kind:"budget",payload:e})}catch(n){ue("trace.emit",t,"budget",n)}}async function Ym(t,e){if(t)try{await t.write({kind:"abort",payload:e})}catch(n){ue("trace.emit",t,"abort",n)}}async function Qs(t,e){if(t)try{await t.write({kind:"compaction",payload:e})}catch(n){ue("trace.emit",t,"compaction",n)}}async function Qm(t,e){if(t)try{await t.write({kind:"closure",payload:e})}catch(n){ue("trace.emit",t,"closure",n)}}async function ae(t,e){if(t)try{await t.write({kind:"browser_event",payload:e})}catch(n){ue("trace.emit",t,"browser_event",n)}}async function zl(t,e){if(t)try{await t.write({kind:"queued_user_message",payload:e})}catch(n){ue("trace.emit",t,"queued_user_message",n)}}async function U(t,e){if(t)try{await t.write({kind:"session_phase",payload:e})}catch(n){ue("trace.emit",t,"session_phase",n)}}import iC from"@anthropic-ai/sdk";var VI="fast-mode-2026-02-01";function Zm(t){let e=[...t.oauthEntries??[],...t.effort?[t.effortEntry]:[],...t.extendedCacheTtl?[t.extendedCacheEntry]:[],...t.fast?[VI]:[]].filter(Boolean);return[...new Set(e)].join(",")||void 0}var eg="extended-cache-ttl-2025-04-11",YI=`claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,${eg}`,QI="effort-2025-11-24",ZI="claude-cli/1.0.0 (external, cli)",eC="x-anthropic-billing-header: cc_version=1.0.0.test; cc_entrypoint=cli; cch=00000;";function Zs(t){return t.startsWith("sk-ant-oat01-")?"oauth":"api-key"}function Vr(t,e,n,r){let o=e==="oauth"?{authToken:t}:{apiKey:t},s=typeof n=="string"&&n.length>0?{...o,baseURL:n}:o;return r?{...s,fetch:r}:s}function Ot(t,e,n,r,o,s){let i=Zm({oauthEntries:t==="oauth"?YI.split(","):[],effort:t==="oauth"&&r===!0,extendedCacheTtl:o,fast:s,effortEntry:QI,extendedCacheEntry:eg});return t!=="oauth"?i?{"anthropic-beta":i}:{}:{"anthropic-beta":i,"x-app":"cli","User-Agent":ZI,"X-Claude-Code-Session-Id":e,"x-client-request-id":n}}function tg(t){return t!=="oauth"?null:[{type:"text",text:eC}]}I();var Qr=["local","small","medium","large"],rg="claude-haiku-4-5-20251001",Yr="claude-sonnet-4-6",Vl="claude-opus-5",Ql="claude-fable-5",tC="grok-4.6",an={local:{id:""},small:{id:rg},medium:{id:Yr},large:{id:Vl}},og="auto",Zl={opus:Vl,opus_1m:Vl,sonnet:Yr,sonnet_1m:Yr,haiku:rg,fable:Ql,grok:tC},nC=["gpt-5.6-sol","gpt-5.6-terra","gpt-5.6-luna","gpt-5.5"],cn=[...Qr,...Object.keys(Zl),...nC],Yl;function ed(t){Yl=t}function Jl(t){if(t===void 0)return;let e=t.trim();return e.length>0?e:void 0}function ei(t,e,n){let r={},o=Jl(t);o&&(r.id=o);let s=Jl(e);s&&(r.baseUrl=s);let i=Jl(n);return i&&(r.apiKey=i),r}function rC(){return{local:ei(b.AFK_MODEL_LOCAL,b.AFK_MODEL_LOCAL_BASE_URL,b.AFK_MODEL_LOCAL_API_KEY),small:ei(b.AFK_MODEL_SMALL,b.AFK_MODEL_SMALL_BASE_URL,b.AFK_MODEL_SMALL_API_KEY),medium:ei(b.AFK_MODEL_MEDIUM,b.AFK_MODEL_MEDIUM_BASE_URL,b.AFK_MODEL_MEDIUM_API_KEY),large:ei(b.AFK_MODEL_LARGE,b.AFK_MODEL_LARGE_BASE_URL,b.AFK_MODEL_LARGE_API_KEY)}}function sg(t){let e=rC(),n={};for(let r of Qr){let o=an[r],s=t?.[r],i=e[r],a={id:i.id??s?.id??o.id},c=s?.name;c&&(a.name=c);let l=s?.provider;l&&(a.provider=l);let d=i.baseUrl??s?.baseUrl;d&&(a.baseUrl=d);let u=i.apiKey??s?.apiKey;u&&(a.apiKey=u),n[r]=a}return n}function $n(t){return t||Yl||sg()}function Bn(t,e=$n()){let n=t.trim().toLowerCase();if(!(!n||n===og)){for(let r of Qr){let o=e[r].name;if(o&&o.trim().toLowerCase()===n)return r}if(n==="local"||n==="small"||n==="medium"||n==="large")return n}}function ln(t,e=$n()){if(t===void 0)return{id:""};let n=Bn(t,e);if(n)return e[n];let r=Zl[t.trim().toLowerCase()];return r?{id:r}:{id:t}}function rt(t,e=$n()){if(t!==void 0)return ln(t,e).id}function ig(t,e=$n()){if(t===void 0)return;let n=Bn(t,e);if(n&&e[n].id.trim()===""){let r=n.toUpperCase();return`The "${n}" model tier is not configured (no model id). Set AFK_MODEL_${r}=<id> (optionally AFK_MODEL_${r}_BASE_URL / AFK_MODEL_${r}_API_KEY) or "models.${n}" in afk.config.json, then retry.`}}function ag(t){let e={};if(!t||typeof t!="object")return e;let n=t;for(let r of Qr){let o=sC(n[r]);o&&(e[r]=o)}return e}function cg(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();if(e==="anthropic"||e==="anthropic-direct")return"anthropic";if(e==="openai"||e==="openai-compatible")return"openai";if(e==="chatgpt-oauth"||e==="chatgpt")return"chatgpt-oauth";if(e==="xai")return"xai";if(e==="xai-oauth"||e==="xai_oauth")return"xai-oauth"}function Un(t){return typeof t=="string"?t.trim():""}function ng(t){return/[\x00-\x1f\x7f]/.test(t)}var oC=new Set([...Qr,og,...Object.keys(Zl)]);function sC(t){if(typeof t=="string"){let e=t.trim();return e?{id:e}:void 0}if(t&&typeof t=="object"){let e=t,n=Un(e.id);if(!n)return;let r={id:n},o=Un(e.name);o&&(r.name=o);let s=cg(e.provider);s&&(r.provider=s);let i=Un(e.baseUrl);i&&(r.baseUrl=i);let a=Un(e.apiKey);return a&&(r.apiKey=a),r}}function lg(t){if(!t||typeof t!="object"||Array.isArray(t))return{ok:!1,error:'model binding must be an object with at least an "id"'};let e=t;if("apiKey"in e||"api_key"in e)return{ok:!1,error:"per-slot API keys are credentials; set AFK_MODEL_<TIER>_API_KEY via `afk config env set` instead of afk.config.json"};if("baseUrl"in e||"base_url"in e)return{ok:!1,error:"per-slot baseUrl is an endpoint-redirect credential vector; set AFK_MODEL_<TIER>_BASE_URL via `afk config env set` instead of afk.config.json"};let n=Un(e.id);if(!n)return{ok:!1,error:'model binding requires a non-empty "id"'};if(ng(n))return{ok:!1,error:'model binding "id" must not contain control characters'};let r={id:n},o=Un(e.name);if(o){if(ng(o))return{ok:!1,error:'model binding "name" must not contain control characters'};if(oC.has(o.trim().toLowerCase()))return{ok:!1,error:`model binding "name" must not shadow a built-in alias ("${o}")`};r.name=o}if(e.provider!==void 0&&e.provider!==""){let s=cg(e.provider);if(!s)return{ok:!1,error:'model binding "provider" must be one of: anthropic, openai (aliases: anthropic-direct, openai-compatible)'};r.provider=s}return{ok:!0,value:r}}var td={opus:an.large.id,opus_1m:an.large.id,sonnet:an.medium.id,sonnet_1m:an.medium.id,haiku:an.small.id,fable:Ql};function ti(t){return t in td}function he(t){return rt(t)}import{randomUUID as dg}from"node:crypto";async function ug(t){let{token:e,model:n,system:r,user:o,maxTokens:s=64,signal:i,clientFactory:a}=t;if(!e)throw new Error("oneShotCompletion: token required");let c=Zs(e),l=Vr(e,c),d=a?a(l):new iC(l),u=dg(),p=dg(),f=Ot(c,u,p),m=he(n)??n,g={};Object.keys(f).length>0&&(g.headers=f),i&&(g.signal=i);let h=await d.messages.create({model:m,max_tokens:s,system:r,messages:[{role:"user",content:o}]},Object.keys(g).length>0?g:void 0),y=[];for(let k of h.content)k.type==="text"&&y.push(k.text);let w=y.join("").trim();return w.length===0&&console.warn("oneShotCompletion: response contained no text blocks \u2014 returning empty string"),w}I();var aC=new Set(["gpt-4o","gpt-4o-mini","gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","gpt-4-turbo","o1","o3","o4-mini"]),cC=[/^claude-/i,/^gpt-4o/i,/^gpt-4\.1/i,/^gpt-4-turbo/i,/^gpt-4-vision/i,/^gpt-5/i,/(?:^|[/_-])(?:vl|vlm)(?:[/_.-]|$)/i,/(?:^|[/_-])(?:llava|pixtral|internvl|cogvlm|idefics|moondream|janus)/i,/(?:vision|minicpm-?[vo]|qwen[\d.]*-?vl|llama-?3\.2-\d+b-vision|gemma-3|phi-3\.5-vision|phi-4-multimodal)/i];function lC(){let t=b.AFK_VISION_MODELS,e=[],n=[];if(t)for(let r of t.split(",")){let o=r.trim().toLowerCase();if(o)if(o.startsWith("!")){let s=o.slice(1).trim();s&&n.push(s)}else e.push(o)}return{enable:e,disable:n}}function pg(t,e){return t===e||t.includes(e)}function nd(t){if(!t)return!1;let e=(rt(t)??t).trim();if(!e)return!1;let n=e.toLowerCase(),{enable:r,disable:o}=lC();return o.some(s=>pg(n,s))?!1:r.some(s=>pg(n,s))||aC.has(n)?!0:cC.some(s=>s.test(e))}function fg(t){let e=t.trim().toLowerCase();return e.includes("/")?e.slice(e.lastIndexOf("/")+1):e}function dn(t){return t?/^o[0-9]/.test(fg(t)):!1}var dC=[/^gpt-5/];function Zr(t){if(!t)return!1;if(dn(t))return!0;let e=fg(t);return dC.some(n=>n.test(e))}var rd={opus:128e3,opus_1m:128e3,sonnet:128e3,sonnet_1m:128e3,haiku:64e3,fable:128e3,"claude-opus-5":128e3,"claude-opus-4-8":128e3,"claude-opus-4-7":128e3,"claude-opus-4-6":128e3,"claude-sonnet-5":128e3,"claude-sonnet-4-6":128e3,"claude-haiku-4-5-20251001":64e3,"claude-fable-5":128e3,"gpt-5.5":128e3,"gpt-5.6":128e3,"gpt-5.6-sol":128e3,"gpt-5.6-terra":128e3,"gpt-5.6-luna":128e3},uC=64e3;function sd(t){let e=String(t).trim().toLowerCase(),n=rd[e];if(e.endsWith("_1m")&&n!==void 0)return n;let r=rt(t)??String(t);return rd[r]??rd[r.toLowerCase()]}function jn(t){return sd(t)??uC}var od={opus:1e6,opus_1m:1e6,sonnet:1e6,sonnet_1m:1e6,haiku:2e5,fable:1e6,"claude-fable-5":1e6,"claude-sonnet-5":1e6,"claude-opus-5":1e6,"claude-opus-4-8":1e6,"claude-opus-4-7":1e6,"claude-opus-4-6":1e6,"claude-sonnet-4-6":1e6,"gpt-4o":128e3,"gpt-4o-mini":128e3,"gpt-4.1":1e6,"gpt-4.1-mini":1e6,"gpt-5.5":1e6,"gpt-5.6":1e6,"gpt-5.6-sol":1e6,"gpt-5.6-terra":1e6,"gpt-5.6-luna":1e6,o1:2e5,"o1-mini":128e3,o3:2e5,"o3-mini":2e5,"o4-mini":2e5,"mlx-community/qwen3-30b-a3b-4bit":128e3,"mlx-community/qwen3-32b-4bit":128e3,"mlx-community/qwen2.5-coder-32b-instruct-4bit":131072,"grok-4.6":5e5,"grok-4.5":5e5,"grok-4.3":1e6,"grok-4.20-0309-reasoning":1e6,"grok-4.20-0309-non-reasoning":1e6,"grok-4.20-multi-agent-0309":1e6,"grok-build-0.1":256e3},pC=2e5,fC=262144;function mC(t){if(!t)return!1;let e=t.trim().toLowerCase();return e?!!(e.includes("/")||e.startsWith("gpt-")||e.startsWith("gpt_")||dn(e)||e.startsWith("codex-")||e.startsWith("codex_")||e==="codex"||e==="grok"||e.startsWith("grok-")||e.startsWith("grok_")):!1}function Ve(t){let e=String(t).trim().toLowerCase(),n=od[e];if(e.endsWith("_1m")&&n!==void 0)return n;let r=rt(t)??String(t),o=od[r]??od[r.toLowerCase()];return o!==void 0?o:mC(r)?fC:pC}var mg={"claude-sonnet-5":2e5,"claude-opus-5":2e5,"claude-sonnet-4-6":2e5,"claude-opus-4-8":2e5,"claude-opus-4-7":2e5,"claude-opus-4-6":2e5};function gt(t){let e=Ve(t);if(String(t).trim().toLowerCase().endsWith("_1m"))return e;let r=rt(t)??String(t),o=mg[r]??mg[r.toLowerCase()];return o!==void 0?Math.min(e,o):e}function gg(t){return(t.inputTokens??0)+(t.outputTokens??0)}function pe(t){return t.contextWindowTokens??gg(t)}function eo(t){return t?{totalTokens:pe(t),apiUsage:{input_tokens:t.inputTokens??0,output_tokens:t.outputTokens??0,cache_read_input_tokens:t.cachedInputTokens??0,cache_creation_input_tokens:t.cacheCreationTokens??0,context_window_tokens:pe(t)}}:{totalTokens:0,apiUsage:null}}function to(t,e,n){return e<=0||t<=0||n<=0||n>=1?!1:t/e>=n}function no(t,e){return e<=0||t<=0?0:t/e}var ni=.9,gC=.04;function hg(t){let e=Ve(t),n=gt(t),r=jn(t);if(e<=0||r<=0||n<e)return ni;let o=(e-r)/e-gC;return o>0?o:ni}function ro(t,e,n,r){if(t<=0||n<=0||e<=0)return;let o=t+e;if(!(o<=n))throw new Error(`[afk] Context-window overflow: the conversation already used ~${t.toLocaleString()} tokens (last-turn API count) and the configured output ceiling is ${e.toLocaleString()} tokens \u2014 together they exceed the ${r} context window of ${n.toLocaleString()} tokens by ${(o-n).toLocaleString()} tokens. The provider would reject this request with HTTP 400. To continue: run /compact to summarise the conversation history, or start a new session.`)}function oo(t,e){if(t===void 0||t===!1)return;let n=e!==void 0?hg(e):1;if(t===!0)return Math.min(ni,n);let r=t.threshold;if(!(typeof r!="number"||!Number.isFinite(r)||r<=0||r>=1))return Math.min(r,n)}var hC=t=>/opus-4-(7|[89])/.test(t),yC=t=>hC(t)||/(claude-)?(opus|sonnet)-5/.test(t),oi=new Set,yg=new Set,ri=1;function bg(t){if(t!==void 0&&!(!Number.isFinite(t)||t<0)){if(t>ri){let e=`temp:${t}`;return yg.has(e)||(yg.add(e),console.warn(`[afk] temperature ${t} exceeds the Anthropic maximum (${ri}); clamping to ${ri}.`)),ri}return t}}var bC=.25;function si(t,e){let n=jn(e),r=t.maxOutputTokens;if(typeof r=="number"&&Number.isFinite(r)&&r>0){let o=Math.floor(r);if(o>n){let s=`max:${e}:${o}`;return oi.has(s)||(oi.add(s),console.warn(`[afk] maxOutputTokens ${o} exceeds the ${e} output ceiling (${n}); clamping to ${n}.`)),n}return o}return n}function wg(t){if(!t||t.length===0)return;let e=[];for(let n of t)n.user.length>0&&e.push({role:"user",content:n.user}),n.assistant.length>0&&e.push({role:"assistant",content:n.assistant});return e.length>0?e:void 0}function ii(t,e,n){switch(t.type){case"adaptive":return{type:"adaptive",display:"summarized"};case"disabled":return{type:"disabled"};case"enabled":{if(typeof n=="string"&&yC(n))return{type:"adaptive",display:"summarized"};if(e<=1024)throw new Error(`[afk] Extended thinking requires max_tokens > 1024 (the API constraint is 1024 <= budget_tokens < max_tokens), but the resolved output cap is ${e}. Raise --max-output-tokens / AFK_MAX_OUTPUT_TOKENS above 1024, or disable thinking with --thinking disabled.`);let r=Math.floor(e*bC),o=Math.max(1024,e-1-r),s=t.budgetTokens!==void 0&&Number.isFinite(t.budgetTokens)?Math.floor(t.budgetTokens):void 0,i=Math.min(Math.max(s??o,1024),o);if(s!==void 0&&s>o){let a=`think:${n??"default"}:${s}:${e}`;oi.has(a)||(oi.add(a),console.warn(`[afk] thinking budgetTokens ${s} leaves too little of max_tokens ${e} for the reply; clamping to ${o}.`))}return{type:"enabled",budget_tokens:i,display:"summarized"}}}}function ai(t,e){if(t!==void 0)return t;let n=e.toLowerCase();if(/(claude-)?(opus|sonnet)-(4-[678]|5)/.test(n))return"max"}P();import id from"path";import{dirname as wC}from"path";import{appendFileSync as SC,mkdirSync as kC}from"fs";var Dt=class{hooks;constructor(e){this.hooks=e}addReadRoot(e,n="slash",r){this.hooks.ensureInitialized?.();let o=this.hooks.getReadRoots();if(!o)return;let s=id.resolve(e);o.includes(s)||(o.push(s),this.appendAuditLog({action:"grant-read",path:s,source:n,sessionId:r}))}addWriteRoot(e,n="slash",r){this.hooks.ensureInitialized?.();let o=this.hooks.getReadRoots(),s=this.hooks.getWriteRoots();if(!o||!s)return;let i=id.resolve(e);o.includes(i)||o.push(i),s.includes(i)||(s.push(i),this.appendAuditLog({action:"grant-write",path:i,source:n,sessionId:r}))}revokeRoot(e,n="slash",r){let o=this.hooks.getReadRoots();if(!o)return;let s=id.resolve(e),i=this.hooks.getProtectedRoot();if(i!==void 0&&s===i)return;let a=o.indexOf(s),c=a!==-1;c&&o.splice(a,1);let l=this.hooks.getWriteRoots(),d=!1;if(l){let u=l.indexOf(s);d=u!==-1,d&&l.splice(u,1)}(c||d)&&this.appendAuditLog({action:"revoke",path:s,source:n,sessionId:r})}getGrants(){return{resolveBase:this.hooks.getDisplayResolveBase?this.hooks.getDisplayResolveBase():this.hooks.getProtectedRoot(),readRoots:this.hooks.getReadRoots()?.slice()??[],writeRoots:this.hooks.getWriteRoots()?.slice()??[],allowAll:this.hooks.getAllowAll()}}appendAuditLog(e){try{let n=Ks();kC(wC(n),{recursive:!0});let r=JSON.stringify({timestamp:new Date().toISOString(),sessionId:e.sessionId??this.hooks.getDefaultSessionId?.()??null,action:e.action,path:e.path,source:e.source});SC(n,r+`
|
|
29
|
-
`)}catch{}}};function Ye(t){return t==="bypassPermissions"||t==="autonomous"}var ci=class{_readRoots;_writeRoots;_currentCwd;_permissionMode="default";manager=new Dt({getReadRoots:()=>this._readRoots,getWriteRoots:()=>this._writeRoots,ensureInitialized:()=>this.ensureInitialized(),getProtectedRoot:()=>this._currentCwd,getAllowAll:()=>Ye(this._permissionMode)});get readRoots(){return this._readRoots}get writeRoots(){return this._writeRoots}get currentCwd(){return this._currentCwd}set currentCwd(e){this._currentCwd=e}get permissionMode(){return this._permissionMode}set permissionMode(e){this._permissionMode=e}ensureInitialized(e){if(!this._readRoots){let n=e?[e]:[];this._readRoots=n.slice(),this._writeRoots=n.slice(),e&&!this._currentCwd&&(this._currentCwd=e)}}};import{z as ye}from"zod";var ht=ye.string().min(1,"namespace/key must be non-empty").max(128,"namespace/key must not exceed 128 characters").regex(/^[A-Za-z0-9_.-]+$/,"namespace/key may only contain [A-Za-z0-9_.-]"),vC=ye.object({namespace:ht,key:ht}),TC=ye.object({namespace:ht,key:ht,value:ye.unknown(),ttl_ms:ye.number().int().positive().optional(),metadata:ye.unknown().optional()}),_C=ye.object({namespace:ht,key:ht,expected_version:ye.number(),value:ye.unknown(),ttl_ms:ye.number().int().positive().optional(),metadata:ye.unknown().optional()}),EC=ye.object({namespace:ht,key:ht}),AC=ye.object({namespace:ht,key_prefix:ye.string().optional(),limit:ye.number().int().positive().max(100).optional()});function li(t,e){let n=new Map;return n.set("state_get",async r=>{try{let{namespace:o,key:s}=vC.parse(r),i=t.get(o,s);return{content:JSON.stringify(i)}}catch(o){return{content:String(o),isError:!0}}}),n.set("state_put",async r=>{try{let{namespace:o,key:s,value:i,ttl_ms:a,metadata:c}=TC.parse(r),l=t.put(o,s,i,{ttl_ms:a,metadata:c},e);return{content:JSON.stringify(l)}}catch(o){return{content:String(o),isError:!0}}}),n.set("state_cas",async r=>{try{let{namespace:o,key:s,expected_version:i,value:a,ttl_ms:c,metadata:l}=_C.parse(r),d=t.cas(o,s,i,a,{ttl_ms:c,metadata:l},e);return{content:JSON.stringify(d)}}catch(o){return{content:String(o),isError:!0}}}),n.set("state_delete",async r=>{try{let{namespace:o,key:s}=EC.parse(r),i=t.del(o,s);return{content:JSON.stringify(i)}}catch(o){return{content:String(o),isError:!0}}}),n.set("state_query",async r=>{try{let o=AC.parse(r),s=Math.min(o.limit??20,100),i=t.query(o.namespace,{key_prefix:o.key_prefix,limit:s});return{content:JSON.stringify(i)}}catch(o){return{content:String(o),isError:!0}}}),n}import
|
|
29
|
+
`)}catch{}}};function Ye(t){return t==="bypassPermissions"||t==="autonomous"}var ci=class{_readRoots;_writeRoots;_currentCwd;_permissionMode="default";manager=new Dt({getReadRoots:()=>this._readRoots,getWriteRoots:()=>this._writeRoots,ensureInitialized:()=>this.ensureInitialized(),getProtectedRoot:()=>this._currentCwd,getAllowAll:()=>Ye(this._permissionMode)});get readRoots(){return this._readRoots}get writeRoots(){return this._writeRoots}get currentCwd(){return this._currentCwd}set currentCwd(e){this._currentCwd=e}get permissionMode(){return this._permissionMode}set permissionMode(e){this._permissionMode=e}ensureInitialized(e){if(!this._readRoots){let n=e?[e]:[];this._readRoots=n.slice(),this._writeRoots=n.slice(),e&&!this._currentCwd&&(this._currentCwd=e)}}};import{z as ye}from"zod";var ht=ye.string().min(1,"namespace/key must be non-empty").max(128,"namespace/key must not exceed 128 characters").regex(/^[A-Za-z0-9_.-]+$/,"namespace/key may only contain [A-Za-z0-9_.-]"),vC=ye.object({namespace:ht,key:ht}),TC=ye.object({namespace:ht,key:ht,value:ye.unknown(),ttl_ms:ye.number().int().positive().optional(),metadata:ye.unknown().optional()}),_C=ye.object({namespace:ht,key:ht,expected_version:ye.number(),value:ye.unknown(),ttl_ms:ye.number().int().positive().optional(),metadata:ye.unknown().optional()}),EC=ye.object({namespace:ht,key:ht}),AC=ye.object({namespace:ht,key_prefix:ye.string().optional(),limit:ye.number().int().positive().max(100).optional()});function li(t,e){let n=new Map;return n.set("state_get",async r=>{try{let{namespace:o,key:s}=vC.parse(r),i=t.get(o,s);return{content:JSON.stringify(i)}}catch(o){return{content:String(o),isError:!0}}}),n.set("state_put",async r=>{try{let{namespace:o,key:s,value:i,ttl_ms:a,metadata:c}=TC.parse(r),l=t.put(o,s,i,{ttl_ms:a,metadata:c},e);return{content:JSON.stringify(l)}}catch(o){return{content:String(o),isError:!0}}}),n.set("state_cas",async r=>{try{let{namespace:o,key:s,expected_version:i,value:a,ttl_ms:c,metadata:l}=_C.parse(r),d=t.cas(o,s,i,a,{ttl_ms:c,metadata:l},e);return{content:JSON.stringify(d)}}catch(o){return{content:String(o),isError:!0}}}),n.set("state_delete",async r=>{try{let{namespace:o,key:s}=EC.parse(r),i=t.del(o,s);return{content:JSON.stringify(i)}}catch(o){return{content:String(o),isError:!0}}}),n.set("state_query",async r=>{try{let o=AC.parse(r),s=Math.min(o.limit??20,100),i=t.query(o.namespace,{key_prefix:o.key_prefix,limit:s});return{content:JSON.stringify(i)}}catch(o){return{content:String(o),isError:!0}}}),n}import $J from"better-sqlite3";var Tg={name:"workspace_publish",category:"write",concurrencySafe:!1,description:"Publish a structured finding to the shared session workspace so sibling agents can see it. Call after: confirming a module's key exports or invariants, ruling out a hypothesis, or reading a file another sibling will likely need (publish the insight, not raw content). Entries are visible immediately to siblings via workspace_query and injected into new siblings' system prompts at fork time. Free to batch with other tools.",input_schema:{type:"object",properties:{type:{type:"string",enum:["finding","evidence","hypothesis","decision","artifact","status"],description:"The kind of entry being published."},subject:{type:"string",description:'Optional short label for relevance routing \u2014 e.g. "auth refresh", "DB schema". Agents querying the workspace by task keywords will match on this field.'},content:{type:"string",description:"The full text of the finding, evidence, or decision."},evidence:{type:"array",items:{type:"string"},description:'Optional file:line references backing this entry (e.g. ["src/auth.ts:141"]).'},confidence:{type:"number",description:"Confidence level 0\u20131 (default 1.0)."},relates_to:{type:"array",items:{type:"number"},description:"Optional IDs of related workspace entries."},relation_type:{type:"string",enum:["supports","contradicts","depends_on","supersedes"],description:"Relationship to the entries listed in relates_to."}},required:["type","content"]}},_g={name:"workspace_query",category:"read",concurrencySafe:!0,description:"Query the shared session workspace for findings published by sibling agents. Call before reading a file or grepping a module \u2014 a sibling may have already analyzed it. Returns entries matching the search keywords, ordered by recency. A workspace hit saves a tool round by avoiding redundant file reads.",input_schema:{type:"object",properties:{query:{type:"string",description:'Search keywords to match against workspace entry subjects and content. E.g. "provider streaming" or "auth error handling".'},type:{type:"string",enum:["finding","evidence","hypothesis","decision","artifact","status"],description:"Optional: filter results to a specific entry type."},limit:{type:"number",description:"Max entries to return (default 20, max 50)."}},required:["query"]}},so=[Tg,_g];function io(t,e,n){let r=new Map,o=async i=>{try{let a=MC(i),c={session_id:e,type:a.type,content:a.content,subject:a.subject,evidence:a.evidence,confidence:a.confidence,agent_id:n,relates_to:a.relates_to,relation_type:a.relation_type},l=t.publish(c);return{content:JSON.stringify({published:!0,id:l})}}catch(a){return{content:`workspace_publish error: ${a instanceof Error?a.message:String(a)}`,isError:!0}}},s=async i=>{try{let a=PC(i),c=t.queryRelevant(null,a.query,a.limit);return a.type!==void 0&&(c=c.filter(l=>l.type===a.type)),{content:JSON.stringify({entries:c.map(xC),count:c.length})}}catch(a){return{content:`workspace_query error: ${a instanceof Error?a.message:String(a)}`,isError:!0}}};return r.set("workspace_publish",o),r.set("workspace_query",s),r}function xC(t){return{id:t.id,type:t.type,subject:t.subject,content:t.content,evidence:t.evidence!==null?JSON.parse(t.evidence):null,confidence:t.confidence,agent_id:t.agent_id,relates_to:t.relates_to!==null?JSON.parse(t.relates_to):null,relation_type:t.relation_type,created_at:t.created_at}}var Sg=8192,kg=256,vg=" \u2026 [truncated]",ad=new Set(["finding","evidence","hypothesis","decision","artifact","status"]),RC=new Set(["supports","contradicts","depends_on","supersedes"]),IC=50,CC=20;function PC(t){if(!t||typeof t!="object")throw new Error("workspace_query: input must be an object");let e=t,n=e.query;if(typeof n!="string"||n.length===0)throw new Error("workspace_query: query is required");let r=e.type,o=typeof r=="string"&&ad.has(r)?r:void 0,s=e.limit,i=typeof s=="number"&&s>0?Math.min(Math.floor(s),IC):CC;return{query:n,type:o,limit:i}}function MC(t){if(!t||typeof t!="object")throw new Error("workspace_publish: input must be an object");let e=t,n=e.type;if(typeof n!="string"||!ad.has(n))throw new Error(`workspace_publish: type must be one of ${[...ad].join(", ")}`);let r=e.content;if(typeof r!="string"||r.length===0)throw new Error("workspace_publish: content is required");let o=r.length>Sg?r.slice(0,Sg)+vg:r,s=typeof e.subject=="string"?e.subject.length>kg?e.subject.slice(0,kg)+vg:e.subject:void 0,i=Array.isArray(e.evidence)&&e.evidence.every(u=>typeof u=="string")?e.evidence:void 0,a=typeof e.confidence=="number"?e.confidence:void 0,c=Array.isArray(e.relates_to)&&e.relates_to.every(u=>typeof u=="number")?e.relates_to:void 0,l=e.relation_type,d=typeof l=="string"&&RC.has(l)?l:void 0;return{type:n,content:o,subject:s,evidence:i,confidence:a,relates_to:c,relation_type:d}}function Eg(t){let e=["# Workspace context (shared findings from sibling agents)","","The following findings were published by other agents working on this task.","Use them to avoid re-discovering known facts. Call `workspace_query` to poll","for newer entries mid-run. Publish new discoveries with `workspace_publish`."];for(let c of t){e.push(""),e.push("---");let l=[];l.push(`confidence: ${c.confidence.toFixed(2)}`),c.agent_id&&l.push(`agent: ${c.agent_id}`);let d=l.length>0?` (${l.join(", ")})`:"",u=DC(c.type);if(e.push(`#${c.id} ${u}${d}`),c.subject&&e.push(`Subject: ${c.subject}`),e.push(c.content),c.evidence)try{let p=JSON.parse(c.evidence);Array.isArray(p)&&p.length>0&&e.push(`Evidence: ${p.join(", ")}`)}catch{}if(c.relates_to&&c.relation_type)try{let p=JSON.parse(c.relates_to);Array.isArray(p)&&p.length>0&&e.push(`Relation: ${c.relation_type} \u2192 #${p.join(", #")}`)}catch{}}e.push("---");let n=e.join(`
|
|
30
30
|
`),r=32*1024;if(n.length<=r)return n;let o=`
|
|
31
31
|
---
|
|
32
32
|
[Workspace preamble truncated: too many entries. Earlier entries omitted.]
|
|
@@ -190,7 +190,7 @@ ${yd}
|
|
|
190
190
|
`,"utf-8")}catch(r){C("WAL append failed (non-fatal):",String(r))}}};function kM(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var vM=/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;function ih(t){if(!t||t.length>100||!vM.test(t))throw new Error(`Invalid procedure name "${t}": must be 1-100 chars, alphanumeric/hyphens/underscores only`);return t}var TM=new Set(["fact","session_start","session_end","supersede"]),_M=new Set(["preference","convention","decision","learning"]);function EM(t){if(!t||typeof t!="object")return!1;let e=t;if(typeof e.type!="string"||!TM.has(e.type)||typeof e.timestamp!="string"||!e.data||typeof e.data!="object")return!1;if(e.type==="fact"){let n=e.data;if(typeof n.category!="string"||!_M.has(n.category))return!1}return!0}function ah(t,e){let n=mM(e,t);if(n.startsWith("..")||n.startsWith("/"))throw new Error("Path traversal detected")}function ch(t,e){let n=e.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);if(!n)return{name:rh(t,".md"),content:e,created:"",source_session:null,access_count:0};let r=n[1]??"",o=n[2]??"",s=l=>l.match(/^name:\s*(.+)$/m)?.[1]?.trim()??rh(t,".md"),i=l=>l.match(/^created:\s*(.+)$/m)?.[1]?.trim()??"",a=l=>l.match(/^source_session:\s*(.+)$/m)?.[1]?.trim()??null,c=l=>{let d=l.match(/^access_count:\s*(\d+)$/m);return d?parseInt(d[1],10):0};return{name:s(r),content:o.trim(),created:i(r),source_session:a(r),access_count:c(r)}}I();var AM=new Set(["convention"]),uh="[unverified]";function ph(t){return AM.has(t)}function vi(){return b.AFK_MEMORY_EVIDENCE_GATE==="1"}function bd(t){return ph(t)}function Ti(t){if(typeof t!="string")return null;let e=t.trim();return e.length>0?e:null}function fh(t,e){return ph(t)?Ti(e)?"verified":"unverified":"not-applicable"}function mh(t,e){return e!=="unverified"||t.startsWith(uh)?t:`${uh} ${t}`}var Wn={name:"memory_search",category:"read",concurrencySafe:!0,description:'Search cross-session memory for facts and procedures. Returns results ranked by relevance. Use this to recall information from prior sessions. Supports FTS5 match syntax: AND, OR, NOT, "exact phrase", prefix*',input_schema:{type:"object",properties:{query:{type:"string",description:'Search query (supports FTS5 match syntax: AND, OR, NOT, "exact phrase", prefix*)'},category:{type:"string",enum:["preference","convention","decision","learning"],description:"Optional: filter by fact category"},since:{type:"string",description:"Optional: ISO date \u2014 only return facts created after this date"},limit:{type:"number",description:"Max results (default 10)"}},required:["query"]}},hh={name:"memory_update",category:"write",concurrencySafe:!1,description:'Store a fact in cross-session memory or update hot memory. Hot memory (target: "hot") persists in the system prompt across all future sessions. Facts (target: "fact") are stored in the searchable archive.',input_schema:{type:"object",properties:{target:{type:"string",enum:["hot","fact"],description:'"hot" writes to HOT.md (system prompt), "fact" writes to the searchable archive'},action:{type:"string",enum:["set","supersede","remove"],description:"Operation: set (create/overwrite), supersede (replace while keeping history), remove (delete)"},content:{type:"string",description:"The content to store (for set/supersede)"},category:{type:"string",enum:["preference","convention","decision","learning"],description:"Required for fact target"},evidence:{type:"string",description:'Optional provenance citation backing a codebase fact \u2014 a file:line, commit SHA, or trace-event id. When the evidence gate is enabled, a "convention" fact stored without it is recalled as [unverified]; preferences and reflections never need it.'},supersedes:{type:"number",description:"Fact ID being superseded (for supersede action)"},id:{type:"number",description:"Fact ID to remove (for remove action)"}},required:["target","action"]}},yh={name:"procedure_write",category:"write",concurrencySafe:!1,description:"Write a reusable procedure to memory. Procedures are markdown files describing how to perform recurring tasks. They persist across sessions and are searchable via memory_search.",input_schema:{type:"object",properties:{name:{type:"string",description:"Procedure name (kebab-case, becomes the filename)"},content:{type:"string",description:"Procedure content (markdown)"}},required:["name","content"]}},Nt=[Wn,hh,yh],xM=Nt.map(t=>t.name),gh='Stored without evidence \u2014 this codebase fact (category "convention") will be recalled as [unverified]. Supply `evidence` (a file:line, commit SHA, or trace-event id) so future sessions can trust it as ground truth rather than an unverified agent claim.',RM='Superseded without fresh evidence \u2014 the prior citation is carried forward and this codebase fact (category "convention") is still recalled as verified against the OLD evidence, which may not back the changed content. Re-supply `evidence` if the claim changed (or pass an empty string to clear it and recall as [unverified]).';function IM(t,e){return e?t.map(n=>{if(n.type!=="fact"||!n.category)return{...n,verification:"not-applicable"};let r=fh(n.category,n.evidence);return{...n,verification:r,content:mh(n.content,r)}}):t.map(n=>{let r={...n};return delete r.evidence,delete r.verification,r})}function uo(t,e,n){let r=async i=>{try{let a=CM(i),c=t.search(a.query,{category:a.category,since:a.since,limit:a.limit??10});return{content:JSON.stringify(IM(c,vi()))}}catch(a){return{content:`memory_search error: ${a instanceof Error?a.message:String(a)}`,isError:!0}}},o=async i=>{try{let a=PM(i);if(a.target==="hot"){if(a.action!=="set")return{content:'Hot memory only supports action: "set". Use supersede/remove only for facts.',isError:!0};if(!a.content)return{content:'content is required for action: "set"',isError:!0};let c=t.saveHot(a.content),l={saved:!0,target:"hot",usage:{tokens:c.tokens,maxTokens:c.maxTokens,pct:c.pct}};return c.truncated?(l.truncated=!0,l.note='Hot memory exceeded the ~1,500-token cap and was truncated from the end (lowest-priority lines dropped; a sentinel marks the cut). Keep hot memory to a few durable essentials \u2014 move detail to the fact archive with target:"fact".'):c.pct>=lh*100&&(l.warning=`Hot memory is at ${c.pct}% of the ~1,500-token cap. Move non-essential lines to the fact archive (target:"fact") before it truncates.`),{content:JSON.stringify(l)}}if(a.action==="set"){if(!a.category)return{content:"category is required for fact storage",isError:!0};if(!a.content)return{content:'content is required for action: "set"',isError:!0};let c=a.category,l=Ti(a.evidence),u={id:t.storeFact({session_id:e,category:c,content:a.content,source_surface:n??"cli",evidence:l}),action:"set",target:"fact"};return vi()&&bd(c)&&!l&&(u.warning=gh),{content:JSON.stringify(u)}}if(a.action==="supersede"){if(!a.supersedes)return{content:'supersedes (fact ID) is required for action: "supersede"',isError:!0};if(!a.content)return{content:'content is required for action: "supersede"',isError:!0};let c=t.getFact(a.supersedes),l=a.evidence===void 0?void 0:Ti(a.evidence),u={id:t.supersedeFact(a.supersedes,a.content,a.category??void 0,l),action:"supersede",target:"fact",supersedes:a.supersedes};if(vi()){let p=a.category??c?.category;p&&bd(p)&&((l===void 0?c?.evidence??null:l)?l===void 0&&(u.warning=RM):u.warning=gh)}return{content:JSON.stringify(u)}}if(a.action==="remove"){if(!a.id)return{content:'id (fact ID) is required for action: "remove"',isError:!0};let c=t.removeFact(a.id);return{content:JSON.stringify({removed:c,action:"remove",target:"fact"})}}return{content:`Unknown action: ${a.action}`,isError:!0}}catch(a){return{content:`memory_update error: ${a instanceof Error?a.message:String(a)}`,isError:!0}}},s=async i=>{try{let a=MM(i);return t.writeProcedure(a.name,a.content,e),{content:JSON.stringify({name:a.name,written:!0})}}catch(a){return{content:`procedure_write error: ${a instanceof Error?a.message:String(a)}`,isError:!0}}};return new Map([["memory_search",r],["memory_update",o],["procedure_write",s]])}function CM(t){if(typeof t!="object"||t===null)throw new Error("Input must be an object");let e=t;if(typeof e.query!="string")throw new Error("query (string) is required");let n={query:e.query};if(e.category!==void 0){if(typeof e.category!="string")throw new Error("category must be a string");let r=["preference","convention","decision","learning"];if(!r.includes(e.category))throw new Error(`category must be one of: ${r.join(", ")}`);n.category=e.category}if(e.since!==void 0){if(typeof e.since!="string")throw new Error("since must be a string (ISO date)");n.since=e.since}if(e.limit!==void 0){if(typeof e.limit!="number"||e.limit<=0)throw new Error("limit must be a positive number");n.limit=e.limit}return n}function PM(t){if(typeof t!="object"||t===null)throw new Error("Input must be an object");let e=t,n=["hot","fact"];if(typeof e.target!="string"||!n.includes(e.target))throw new Error(`target must be one of: ${n.join(", ")}`);let r=["set","supersede","remove"];if(typeof e.action!="string"||!r.includes(e.action))throw new Error(`action must be one of: ${r.join(", ")}`);let o={target:e.target,action:e.action};if(e.content!==void 0){if(typeof e.content!="string")throw new Error("content must be a string");o.content=e.content}if(e.category!==void 0){if(typeof e.category!="string")throw new Error("category must be a string");let s=["preference","convention","decision","learning"];if(!s.includes(e.category))throw new Error(`category must be one of: ${s.join(", ")}`);o.category=e.category}if(e.evidence!==void 0){if(typeof e.evidence!="string")throw new Error("evidence must be a string");o.evidence=e.evidence}if(e.supersedes!==void 0){if(typeof e.supersedes!="number"||e.supersedes<=0)throw new Error("supersedes must be a positive fact ID");o.supersedes=e.supersedes}if(e.id!==void 0){if(typeof e.id!="number"||e.id<=0)throw new Error("id must be a positive fact ID");o.id=e.id}return o}function MM(t){if(typeof t!="object"||t===null)throw new Error("Input must be an object");let e=t;if(typeof e.name!="string")throw new Error("name (string) is required");if(typeof e.content!="string")throw new Error("content (string) is required");return{name:e.name,content:e.content}}var bh={name:"state_get",category:"read",concurrencySafe:!0,description:"Retrieve a document from the durable cross-session state store. Returns null if the document does not exist or has expired. Documents are namespaced (namespace + key) JSON values with a version counter.",input_schema:{type:"object",properties:{namespace:{type:"string",description:'Document namespace. Pattern: [A-Za-z0-9_.-]+, max 128 chars. Use a consistent namespace per concern (e.g. "todos", "project-state").'},key:{type:"string",description:"Document key. Same pattern/limit as namespace."}},required:["namespace","key"]}},OM={name:"state_put",category:"write",concurrencySafe:!1,description:"Write or update a document in the durable cross-session state store. Creates on first insert (version starts at 1) and increments version on updates. Use state_cas instead when concurrent writes are a concern.",input_schema:{type:"object",properties:{namespace:{type:"string",description:"Document namespace. Pattern: [A-Za-z0-9_.-]+, max 128 chars."},key:{type:"string",description:"Document key. Same pattern/limit as namespace."},value:{description:"JSON-serializable value to store. Any JSON type is accepted (object, array, string, number, boolean, null)."},ttl_ms:{type:"number",description:"Optional time-to-live in milliseconds. Document is automatically deleted after this many ms from the write time."},metadata:{description:"Optional metadata object (JSON-serializable). Not returned by state_get \u2014 for audit/tagging only."}},required:["namespace","key","value"]}},DM={name:"state_cas",category:"write",concurrencySafe:!1,description:"Compare-and-swap write to the durable cross-session state store. Updates the document only when its current version matches expected_version. Returns {matched: false} if the version does not match or the document does not exist. Use this for safe concurrent updates by multiple sessions.",input_schema:{type:"object",properties:{namespace:{type:"string",description:"Document namespace. Pattern: [A-Za-z0-9_.-]+, max 128 chars."},key:{type:"string",description:"Document key. Same pattern/limit as namespace."},expected_version:{type:"number",description:"Version the document must currently have for the update to succeed."},value:{description:"New JSON-serializable value to store if the CAS matches."},ttl_ms:{type:"number",description:"Optional TTL in milliseconds from the write time."},metadata:{description:"Optional metadata object (JSON-serializable)."}},required:["namespace","key","expected_version","value"]}},FM={name:"state_delete",category:"write",concurrencySafe:!1,description:"Delete a document from the durable cross-session state store. Returns {deleted: true} if the document existed and was removed, {deleted: false} if it did not exist.",input_schema:{type:"object",properties:{namespace:{type:"string",description:"Document namespace. Pattern: [A-Za-z0-9_.-]+, max 128 chars."},key:{type:"string",description:"Document key. Same pattern/limit as namespace."}},required:["namespace","key"]}},wh={name:"state_query",category:"read",concurrencySafe:!0,description:"List documents in a namespace from the durable cross-session state store. Returns documents sorted by key. Supports key prefix filtering and pagination. Expired documents are excluded. Default limit is 20, maximum is 100.",input_schema:{type:"object",properties:{namespace:{type:"string",description:"Document namespace. Pattern: [A-Za-z0-9_.-]+, max 128 chars."},key_prefix:{type:"string",description:"Optional key prefix filter. Only documents whose key starts with this string are returned."},limit:{type:"number",description:"Maximum number of results to return (default 20, max 100)."}},required:["namespace"]}},Kn=[bh,OM,DM,FM,wh],_i=[bh,wh];function wd(t,e="all"){switch(e){case"self":return{self:t.getSelf()};case"tools":return{tools:t.getTools()};case"subagents":return{subagents:t.getSubagents()};case"workspace":return{workspace:t.getWorkspace()};default:return{self:t.getSelf(),tools:t.getTools(),subagents:t.getSubagents(),workspace:t.getWorkspace()}}}function Sd(t){return t==="self"||t==="tools"||t==="subagents"||t==="workspace"||t==="all"?t:"all"}function po(t){let n=[`- Working directory: ${t.cwd.replace(/[\r\n]/g," ")}`];n.push(`- Date: ${Ei(t.now??new Date,t.timeZone)}`);let r=typeof t.sessionId=="string"&&t.sessionId.length>0?t.sessionId.slice(0,8):null,o=t.surface&&t.surface!=="unknown"?t.surface:null,s=typeof t.depth=="number"?typeof t.maxDepth=="number"?`depth ${t.depth}/${t.maxDepth}`:`depth ${t.depth}`:null,i=[o,s].filter(a=>typeof a=="string");if(r!==null||i.length>0){let a=["- Session:"];r!==null&&a.push(r),i.length>0&&a.push(`(${i.join(", ")})`),n.push(a.join(" "))}if(t.workspace!==void 0&&t.workspace!==null){let a=t.workspace;if(a.branch!==null||a.headSha!==null){let c=a.branch??"(detached)",l=a.headSha!==null?` @ ${a.headSha}`:"",d;a.dirty===null?d="":a.dirty?d=` (${a.dirtyCount!==null?a.dirtyCount:"?"} dirty)`:d=" (clean)",n.push(`- Workspace: ${c}${l}${d}`)}}return`# Environment
|
|
191
191
|
${n.join(`
|
|
192
192
|
`)}`}function Ei(t,e){try{let n=e??Intl.DateTimeFormat().resolvedOptions().timeZone??"UTC",r=new Intl.DateTimeFormat("en-CA",{timeZone:n,year:"numeric",month:"2-digit",day:"2-digit"}).formatToParts(t),o=i=>r.find(a=>a.type===i)?.value??"";return`${new Intl.DateTimeFormat("en-US",{timeZone:n,weekday:"long"}).format(t)}, ${o("year")}-${o("month")}-${o("day")} (${n})`}catch{return t.toISOString().slice(0,10)}}import{spawnSync as LM}from"child_process";var NM={branch:null,headSha:null,dirty:null,dirtyCount:null,remoteUrl:null};function Ai(t,e,n=!1){try{let r=LM("git",e,{cwd:t,encoding:"utf8",maxBuffer:4096,shell:!1});if(r.status!==0||r.signal!==null||r.error!==void 0)return null;let o=typeof r.stdout=="string"?r.stdout.trim():null;return o===null?null:o.length>0||n?o:null}catch{return null}}function kd(t){let e=Ai(t,["rev-parse","--short","HEAD"]);if(e===null)return{...NM};let n=Ai(t,["symbolic-ref","--short","HEAD"]),r=Ai(t,["status","--porcelain"],!0),o=!1,s=0;if(r!==null){let a=r.split(`
|
|
193
|
-
`).filter(c=>c.trim().length>0);o=a.length>0,s=a.length}else o=null,s=null;let i=Ai(t,["remote","get-url","origin"]);return{branch:n,headSha:e,dirty:o,dirtyCount:s,remoteUrl:i}}function fo(t){return{getSelf(){return{sessionId:t.sessionId??null,surface:$M(t.surface),parentSessionId:t.parentSessionId??null,depth:t.depth??null,maxDepth:t.maxDepth??null,phaseRole:t.phaseRole??null,cwd:t.getCwd(),model:{provider:t.providerName,name:t.modelName},permissionMode:UM(t.permissionMode)}},getTools(){return{enabled:t.getEnabledToolNames(),mcpServers:BM(t.getMcpTools())}},getSubagents(){return t.getSubagents()},getWorkspace(){return kd(t.getCwd())}}}function UM(t){switch(t){case"bypassPermissions":case"acceptEdits":case"dontAsk":case"auto":return"elevated";default:return"default"}}function $M(t){switch(t){case"cli":case"repl":case"daemon":case"telegram":case"subagent":case"web":return t;default:return"unknown"}}function BM(t){let e=new Map;for(let n of t){if(!n.name.startsWith("mcp__"))continue;let r=n.name.split("__");if(r.length<3)continue;let o=r[1];typeof o!="string"||o.length===0||e.set(o,(e.get(o)??0)+1)}return[...e.entries()].map(([n,r])=>({name:n,toolCount:r})).sort((n,r)=>n.name.localeCompare(r.name))}var Qe={name:"get_runtime_state",category:"other",concurrencySafe:!0,description:"Inspect what the runtime knows about this session: identity (sessionId, surface, depth, parent), tool affordances (currently-enabled tool names and MCP server summary), delegation state (active subagent handles, background jobs), and git workspace state (branch, HEAD SHA, dirty count, remote URL). Returns a compact JSON snapshot.\n\nUse when uncertain about: your current nesting depth, whether a tool you want is actually available right now, what MCP servers are wired, whether earlier subagents you dispatched are still running, or what git branch / commit the session started on.\n\nViews:\n- `self` \u2014 identity + model + permissions + cwd only\n- `tools` \u2014 enabled tool names + MCP server summary only\n- `subagents` \u2014 active subagent handles + background jobs only\n- `workspace` \u2014 git state (branch, headSha, dirty, dirtyCount, remoteUrl)\n- `all` \u2014 union of the four above (default)\n\nThis is a read-only, in-memory inspection. It does not probe the file system or network. Fields the runtime does not know (e.g. depth for a top-level session) come back as `null` rather than synthesised defaults.",input_schema:{type:"object",properties:{view:{type:"string",enum:["self","tools","subagents","workspace","all"],description:'Which slice of state to return. Defaults to "all". Use a narrower view when only one slice is needed to keep the response compact.'}},required:[]}},$e=[Qe.name];function qn(t){return async(e,n)=>{let r=e&&typeof e=="object"?Sd(e.view):"all",o=wd(t,r);return{content:JSON.stringify(o)}}}function mo(t,e){let n=qn(e),r=t,o=Array.isArray(r.toolDefs)?r.toolDefs:null,s={async execute(i){return i.name==="get_runtime_state"?n(i.input,i.signal):t.execute(i)}};if(o!==null){let i=o.some(a=>a.name==="get_runtime_state");s.toolDefs=i?o:[...o,Qe]}return s}P();import{mkdir as
|
|
193
|
+
`).filter(c=>c.trim().length>0);o=a.length>0,s=a.length}else o=null,s=null;let i=Ai(t,["remote","get-url","origin"]);return{branch:n,headSha:e,dirty:o,dirtyCount:s,remoteUrl:i}}function fo(t){return{getSelf(){return{sessionId:t.sessionId??null,surface:$M(t.surface),parentSessionId:t.parentSessionId??null,depth:t.depth??null,maxDepth:t.maxDepth??null,phaseRole:t.phaseRole??null,cwd:t.getCwd(),model:{provider:t.providerName,name:t.modelName},permissionMode:UM(t.permissionMode)}},getTools(){return{enabled:t.getEnabledToolNames(),mcpServers:BM(t.getMcpTools())}},getSubagents(){return t.getSubagents()},getWorkspace(){return kd(t.getCwd())}}}function UM(t){switch(t){case"bypassPermissions":case"acceptEdits":case"dontAsk":case"auto":return"elevated";default:return"default"}}function $M(t){switch(t){case"cli":case"repl":case"daemon":case"telegram":case"subagent":case"web":return t;default:return"unknown"}}function BM(t){let e=new Map;for(let n of t){if(!n.name.startsWith("mcp__"))continue;let r=n.name.split("__");if(r.length<3)continue;let o=r[1];typeof o!="string"||o.length===0||e.set(o,(e.get(o)??0)+1)}return[...e.entries()].map(([n,r])=>({name:n,toolCount:r})).sort((n,r)=>n.name.localeCompare(r.name))}var Qe={name:"get_runtime_state",category:"other",concurrencySafe:!0,description:"Inspect what the runtime knows about this session: identity (sessionId, surface, depth, parent), tool affordances (currently-enabled tool names and MCP server summary), delegation state (active subagent handles, background jobs), and git workspace state (branch, HEAD SHA, dirty count, remote URL). Returns a compact JSON snapshot.\n\nUse when uncertain about: your current nesting depth, whether a tool you want is actually available right now, what MCP servers are wired, whether earlier subagents you dispatched are still running, or what git branch / commit the session started on.\n\nViews:\n- `self` \u2014 identity + model + permissions + cwd only\n- `tools` \u2014 enabled tool names + MCP server summary only\n- `subagents` \u2014 active subagent handles + background jobs only\n- `workspace` \u2014 git state (branch, headSha, dirty, dirtyCount, remoteUrl)\n- `all` \u2014 union of the four above (default)\n\nThis is a read-only, in-memory inspection. It does not probe the file system or network. Fields the runtime does not know (e.g. depth for a top-level session) come back as `null` rather than synthesised defaults.",input_schema:{type:"object",properties:{view:{type:"string",enum:["self","tools","subagents","workspace","all"],description:'Which slice of state to return. Defaults to "all". Use a narrower view when only one slice is needed to keep the response compact.'}},required:[]}},$e=[Qe.name];function qn(t){return async(e,n)=>{let r=e&&typeof e=="object"?Sd(e.view):"all",o=wd(t,r);return{content:JSON.stringify(o)}}}function mo(t,e){let n=qn(e),r=t,o=Array.isArray(r.toolDefs)?r.toolDefs:null,s={async execute(i){return i.name==="get_runtime_state"?n(i.input,i.signal):t.execute(i)}};if(o!==null){let i=o.some(a=>a.name==="get_runtime_state");s.toolDefs=i?o:[...o,Qe]}return s}P();import{mkdir as oV,writeFile as kh,unlink as sV,readdir as jM,readFile as Td}from"fs/promises";import{unlinkSync as HM,existsSync as WM,mkdirSync as KM,writeFileSync as qM}from"fs";import{join as vh}from"path";function Sh(t){try{return process.kill(t,0),!0}catch(e){return e.code==="EPERM"}}function vd(t){return typeof t!="number"||!Number.isInteger(t)||t<=0?"unknown":Sh(t)?"alive":"dead"}var Th=1;function Ri(t){return vh(js(),`${t}.json`)}var xi=new Map;function _h(t,e){let r=(xi.get(t)??Promise.resolve()).then(e,e);return xi.set(t,r),r.catch(()=>{}).then(()=>{xi.get(t)===r&&xi.delete(t)}),r}function GM(t){let e={schemaVersion:Th,heartbeatAt:new Date().toISOString(),...t};return JSON.stringify(e,null,2)}function _d(t){try{KM(js(),{recursive:!0,mode:448}),qM(Ri(t.sessionId),GM(t),{encoding:"utf8",mode:384})}catch{}}async function Ed(t,e){return _h(t,async()=>{try{let n=Ri(t),r=await Td(n,"utf8"),o=JSON.parse(r);e?o.blockedSince=new Date().toISOString():delete o.blockedSince,await kh(n,JSON.stringify(o,null,2),{encoding:"utf8",mode:384})}catch{}})}async function Eh(t,e){return _h(t,async()=>{try{let n=Ri(t),r=await Td(n,"utf8"),o=JSON.parse(r);o.cwd=e,await kh(n,JSON.stringify(o,null,2),{encoding:"utf8",mode:384})}catch{}})}function go(t){try{let e=Ri(t);WM(e)&&HM(e)}catch{}}function XM(t,e){if(typeof t!="string")return null;let n=Date.parse(t);return Number.isNaN(n)?null:e-n}async function Ii(){let t=js(),e;try{e=await jM(t)}catch{return[]}let n=Date.now(),r=[];for(let o of e){if(!o.endsWith(".json"))continue;let s=vh(t,o);try{let i=await Td(s,"utf8"),a=JSON.parse(i);if(a!==null&&typeof a=="object"&&"sessionId"in a&&typeof a.sessionId=="string"){let c=a,l=a;r.push({...c,path:s,liveness:vd(l.pid),heartbeatAgeMs:XM(l.heartbeatAt,n)})}}catch{}}return r}async function ho(t={}){let e=await Ii(),{maxHeartbeatAgeMs:n}=t;return e.filter(r=>!(r.liveness==="dead"||n!==void 0&&r.heartbeatAgeMs!==null&&r.heartbeatAgeMs>n))}var zM=new Set([...Ne,yt,Ft,Lt,...Nt,...Kn,Qe].filter(t=>t.concurrencySafe===!0).map(t=>t.name));function Ci(t){return zM.has(t)}function Ah(t,e){return t.reduce((n,r,o)=>{let s=e(r.name,r.input),i=n[n.length-1];return i&&s&&i.isConcurrencySafe?i.indices.push(o):n.push({isConcurrencySafe:s,indices:[o]}),n},[])}import{createHash as JM}from"node:crypto";function xh(t){let e;try{e=JSON.stringify(t.input)??"null"}catch{e=String(t.input)}return JM("sha256").update(t.name).update("\0").update(e).digest("hex")}var Gn="denial-breaker",Rh=new Set(["read_file","list_directory","glob","grep"]),VM="Sub-agent path access denied:";function Ih(t){return t!==void 0&&t.includes(VM)}function Ch(t){let e=t.input??{},n=t.name==="read_file"?e.file_path:e.path;return typeof n=="string"&&n.length>0?n:`<${t.name} with no explicit path>`}function Ph(t,e){let n=t.length>0?t.map(r=>` - ${r}`).join(`
|
|
194
194
|
`):" (no path captured)";return`Denial circuit breaker: this forked sub-agent hit ${e} consecutive path-approval read denials with no successful tool call in between, and was aborted to avoid burning its wall-clock budget. A fork cannot approve its own reads. Denied paths:
|
|
195
195
|
${n}
|
|
196
196
|
|
|
@@ -200,7 +200,7 @@ Remedy: these paths are outside the fork's granted read roots. Re-dispatch with
|
|
|
200
200
|
Retrying it verbatim will fail the same way. Fix the underlying cause, change the arguments, use a different tool, or stop and report the blocker.`,isError:!0,failureClass:"repeat-failure"}}}note(e,n){let r=yo(e);if(n.isError!==!0){this.streaks.delete(r);return}let o=this.streaks.get(r);this.streaks.set(r,{count:(o?.count??0)+1,lastError:r0(n)})}streakFor(e){return this.streaks.get(yo(e))?.count??0}};async function bo(t,e,n){let r=new Array(t.length),o=Math.min(Math.max(1,Math.floor(e)),t.length),s=0,i=[];for(let a=0;a<o;a++)i.push((async()=>{for(;s<t.length;){let c=s++;try{r[c]={status:"fulfilled",value:await n(t[c])}}catch(l){r[c]={status:"rejected",reason:l}}}})());return await Promise.all(i),r}J();function Fh(t,e,n){if(n.has(t.name))return null;let r=e.check(t);return r===null?null:(C(`[repeat-failure-guard #723] refused ${r.tool} after ${r.count} identical failures`),r.result)}function o0(t){if(!t)return{enter:()=>{},leave:()=>{}};let e=new Set,n=()=>{try{t([...e])}catch{}};return{enter:r=>{e.add(r),n()},leave:r=>{e.delete(r),n()}}}async function s0(t,e,n,r){let{call:o,originalIndex:s}=e[t];if(o.signal.aborted)return{result:{content:"Tool call aborted",isError:!0,failureClass:be(o.signal)},originalIndex:s};r?.enter(o.id);try{return{result:await n(o),originalIndex:s}}finally{r?.leave(o.id)}}function i0(t,e,n,r){for(let o of t)if(o.status==="fulfilled")r[o.value.originalIndex]=o.value.result;else{let s=o.reason instanceof Error?o.reason.message:String(o.reason),i=e[t.indexOf(o)];r[n[i].originalIndex]={content:`Tool execution error: ${s}`,isError:!0}}}function Lh(t,e,n){let r=t.indices.length;for(let o=0;o<t.indices.length;o++){let s=t.indices[o],i=n[e[s].originalIndex];i&&(i.batchIndex=o+1,i.batchSize=r)}}async function Nh(t,e,n,r){let o=[...t.indices];for(;o.length>0;){let s=new Map,i=[],a=[];for(let u of o){let{call:p,originalIndex:f}=e[u],m=Fh(p,r.repeatFailureGuard,r.repeatBreakerExemptTools);if(m){n[f]=m;continue}if(r.repeatBreakerExemptTools.has(p.name)){i.push(u);continue}let g=yo(p),h=Rd-r.repeatFailureGuard.streakFor(p),y=s.get(g)??0;y<h?(s.set(g,y+1),i.push(u)):a.push(u)}o=a;let c=i.map(u=>e[u]?.call).filter(u=>u!==void 0&&u.name==="agent");if(c.length>=2&&r.subagentExecutor)try{r.subagentExecutor.notifyWaveStart(c,r.sessionId??"",null)}catch{}let l=o0(r.onActivity),d=await bo(i,r.maxConcurrentSafeCalls,u=>s0(u,e,r.executeCore,l));i0(d,i,e,n);for(let u of i){let{call:p,originalIndex:f}=e[u],m=n[f];m!==void 0&&m.failureClass!=="abort"&&r.repeatFailureGuard.note(p,m)}if(c.length>=2&&r.subagentExecutor)try{r.subagentExecutor.notifyWaveEnd()}catch{}}}async function Uh(t,e,n,r){for(let o of t.indices){let{call:s,originalIndex:i}=e[o];if(s.signal.aborted){n[i]={content:"Tool call aborted",isError:!0,failureClass:be(s.signal)};continue}let a=Fh(s,r.repeatFailureGuard,r.repeatBreakerExemptTools);if(a){n[i]=a;continue}let c=await r.executeCore(s);n[i]=c,r.repeatFailureGuard.note(s,c)}}function $h(t){return t==="agent"||t==="cancel_background_job"||t==="send_message_to_agent"}async function Bh(t,e){if(!t)return{result:{content:e.name==="agent"?"Agent tool is not available in this session configuration":"Background mode is not available in this session configuration",isError:!0}};try{return{result:e.name==="agent"?await t.execute(e):e.name==="send_message_to_agent"?await t.sendMessageToAgent(e):await t.cancelBackgroundJob(e)}}catch(n){let r=n instanceof Error?n.message:String(n);return{result:{content:`${e.name==="agent"?"Agent":e.name==="send_message_to_agent"?"Steering":"Background cancellation"} tool error: ${r}`,isError:!0},thrownMessage:r}}}var c0=8,Id=new Set;var Be=class{handlers;schemas;hookRegistry;permissions;canUseTool;subagentExecutor;skillExecutor;composeExecutor;classifier;maxConcurrentSafeCalls;resolveBase;_readRoots;_writeRoots;_allowAll;_env;sessionId;parentSessionId;subagentId;sessionGrantManager;traceWriter;readOnlyBash;maxOutputBytes;spawnedPidRegistry;repeatBreaker=null;repeatFailureGuard=new Mi;denialBreaker=null;suspectedLoopWindow=null;grantManager;constructor(e){this.handlers=e.handlers,this.schemas=e.schemas,this.hookRegistry=e.hookRegistry,this.permissions=e.permissions,this.canUseTool=e.canUseTool,this.subagentExecutor=e.subagentExecutor,this.skillExecutor=e.skillExecutor,this.composeExecutor=e.composeExecutor,this.classifier=e.concurrencyClassifier??Ci,this.maxConcurrentSafeCalls=typeof e.maxConcurrentSafeCalls=="number"&&Number.isFinite(e.maxConcurrentSafeCalls)&&e.maxConcurrentSafeCalls>=1?Math.floor(e.maxConcurrentSafeCalls):Cg(),this.resolveBase=e.cwd,this._env=e.env,this.sessionId=e.sessionId,this.parentSessionId=e.parentSessionId,this.subagentId=e.subagentId,this.sessionGrantManager=e.sessionGrantManager,this.traceWriter=e.traceWriter,this.readOnlyBash=e.readOnlyBash===!0,this.maxOutputBytes=typeof e.maxOutputBytes=="number"&&Number.isFinite(e.maxOutputBytes)&&e.maxOutputBytes>0?e.maxOutputBytes:void 0,this._allowAll=e.allowAll===!0,this.spawnedPidRegistry=e.spawnedPidRegistry;let n=e.cwd?[e.cwd]:[];this._readRoots=e.readRoots??n.slice(),this._writeRoots=e.writeRoots??n.slice(),this.grantManager=new Dt({getReadRoots:()=>this._readRoots,getWriteRoots:()=>this._writeRoots,getProtectedRoot:()=>this.resolveBase,getAllowAll:()=>this._allowAll,getDefaultSessionId:()=>this.sessionId})}get handlerContext(){return{cwd:this.resolveBase,resolveBase:this.resolveBase,readRoots:this._readRoots.slice(),writeRoots:this._writeRoots.slice(),...this._allowAll?{allowAll:!0}:{},...this._env!==void 0?{env:this._env}:{},...this.sessionId!==void 0?{sessionId:this.sessionId}:{},...this.spawnedPidRegistry!==void 0?{spawnedPidRegistry:this.spawnedPidRegistry}:{}}}callHandlerContext(e){return{...this.handlerContext,toolUseId:e.id,...this.traceWriter!==void 0?{traceWriter:this.traceWriter}:{}}}addReadRoot(e,n="slash",r){this.grantManager.addReadRoot(e,n,r)}addWriteRoot(e,n="slash",r){this.grantManager.addWriteRoot(e,n,r)}revokeRoot(e,n="slash",r){this.grantManager.revokeRoot(e,n,r)}getGrants(){return this.grantManager.getGrants()}setAllowAll(e){this._allowAll=e}setResolveBase(e){let n=this.resolveBase;if(n!==e){if(this.resolveBase=e,n!==void 0){let r=this._readRoots.indexOf(n);r!==-1?this._readRoots[r]=e:this._readRoots.includes(e)||this._readRoots.push(e);let o=this._writeRoots.indexOf(n);o!==-1?this._writeRoots[o]=e:this._writeRoots.includes(e)||this._writeRoots.push(e)}else this._readRoots.includes(e)||this._readRoots.push(e),this._writeRoots.includes(e)||this._writeRoots.push(e);this.subagentExecutor?.setCwd(e),this.skillExecutor?.setCwd(e),this.composeExecutor?.setCwd(e)}}get toolDefs(){let e=this.subagentExecutor?.supportsBackgroundJobs?.()?this.schemas:this.schemas.filter(o=>o.name!=="cancel_background_job"&&o.name!=="send_message_to_agent"),n=this.permissions?.allowedTools;if(!n)return e;let r=new Set(n);return e.filter(o=>r.has(o.name))}denialReason(e,n){return this.isRegisteredTool(e)?n??`Tool "${e}" is not permitted`:this.unknownToolMessage(e)}isRegisteredTool(e){return this.handlers.has(e)||e==="agent"&&this.subagentExecutor!==void 0||e==="cancel_background_job"&&this.subagentExecutor?.supportsBackgroundJobs?.()===!0||e==="send_message_to_agent"&&this.subagentExecutor?.supportsBackgroundJobs?.()===!0||e==="skill"&&this.skillExecutor!==void 0||e==="compose"&&this.composeExecutor!==void 0}unknownToolMessage(e){let n=this.toolDefs.map(o=>o.name).join(", "),r=n.length>0?`Available tools: ${n}. Do NOT retry "${e}" or a variant of it; use one of the tools listed above.`:`Do NOT retry "${e}" or a variant of it.`;return`Unknown tool "${e}" \u2014 it does not exist in this session. ${r}`}async checkReadOnlyBash(e){if(!this.readOnlyBash||e.name!=="bash")return null;let n=e.input,r=typeof n=="object"&&n!==null?n.command:void 0;if(typeof r!="string")return null;let o=Wg(r);if(!o.mutating)return null;let s=`Bash command blocked: read-only skill may not run mutating commands (${o.reason??"mutation detected"}). Allowed: read-only recon (git status/log/diff/show/ls-remote, ls, cat, find, grep, gh pr view/diff). For a remote ref you have not fetched, \`gh pr diff <n>\`, \`gh pr view <n>\` and \`git ls-remote\` need no local ref \u2014 \`git fetch\` is blocked. Do NOT retry variants of a blocked command: if the task genuinely requires a mutation, stop and report that requirement to your caller instead.`;return await this.emitPreToolUseBlock(e.name,s),{content:s,isError:!0,failureClass:"permission-denied"}}async emitPreToolUseBlock(e,n){await Mt(this.traceWriter,{hookEvent:"PreToolUse",decision:"block",blockedTool:e,reason:n,...this.subagentId!==void 0?{subagentId:this.subagentId}:{}})}checkRepeatCircuitBreaker(e){if(Id.has(e.name))return null;let n=xh(e);return this.repeatBreaker!==null&&this.repeatBreaker.fingerprint===n?this.repeatBreaker.count+=1:this.repeatBreaker={fingerprint:n,count:1},this.repeatBreaker.count<c0?null:{content:`Loop circuit breaker: "${e.name}" has been called ${this.repeatBreaker.count} times in a row with byte-identical input. The result will not change. Stop repeating this call \u2014 reuse the previous result, change the input, try a different tool, or end the turn.`,isError:!0,circuitBreaker:!0}}checkRepeatFailureGuard(e){if(Id.has(e.name))return null;let n=this.repeatFailureGuard.check(e);return n===null?null:(C(`[repeat-failure-guard #723] refused ${n.tool} after ${n.count} identical failures`),n.result)}observeSuspectedLoop(e){if(this.parentSessionId===void 0)return;this.suspectedLoopWindow===null&&(this.suspectedLoopWindow=Mh());let n=Pi(e),r=Oh(this.suspectedLoopWindow,n);r.fired&&U(this.traceWriter,{phase:"suspected_loop",metadata:{tool:e.name,count:r.count,windowSize:xd}})}recordForkReadDenial(e,n,r){if(this.parentSessionId===void 0||!Rh.has(e.name)||!Ih(n))return r;let o=this.denialBreaker??{count:0,deniedPaths:[]};o.count+=1;let s=Ch(e);return o.deniedPaths.includes(s)||o.deniedPaths.push(s),this.denialBreaker=o,o.count<5?r:{content:Ph(o.deniedPaths,o.count),isError:!0,failureClass:Gn}}resetDenialBreaker(){this.denialBreaker=null}async runCanUseTool(e){if(!this.canUseTool)return null;let n;try{n=await this.canUseTool(e.name,e.input??{},{signal:e.signal,toolUseID:e.id})}catch(r){let o=`Tool "${e.name}" denied by canUseTool (threw): ${r instanceof Error?r.message:String(r)}`;return await this.emitPreToolUseBlock(e.name,o),{content:o,isError:!0,failureClass:"permission-denied"}}if(n.behavior==="deny"){let r=n.message||`Tool "${e.name}" denied by permission policy`;return await this.emitPreToolUseBlock(e.name,r),{content:r,isError:!0,failureClass:"permission-denied"}}return n.updatedInput!==void 0&&(e.input=n.updatedInput),null}async runPreDispatchGates(e){if(this.hookRegistry){let a={event:"PreToolUse",toolName:e.name,input:e.input,...this.sessionId!==void 0?{sessionId:this.sessionId}:{},...this.resolveBase!==void 0?{cwd:this.resolveBase}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{},...e.id!==void 0?{toolUseId:e.id}:{}};try{await Og(this.hookRegistry,a,{signal:e.signal,...this.traceWriter?{traceWriter:this.traceWriter}:{}})}catch(c){if(c instanceof q)return this.recordForkReadDenial(e,c.reason,{content:`Tool "${e.name}" blocked by PreToolUse hook${c.reason?`: ${c.reason}`:""}${c.injectContext?`
|
|
201
201
|
|
|
202
202
|
${c.injectContext}`:""}`,isError:!0,failureClass:"hook-block"});throw c}}let n=pi(e.name,this.permissions);if(!n.allowed){let a=this.denialReason(e.name,n.reason);return await this.emitPreToolUseBlock(e.name,a),{content:a,isError:!0,failureClass:"permission-denied"}}let r=await this.runCanUseTool(e);if(r)return r;let o=await this.checkReadOnlyBash(e);if(o)return o;let s=this.checkRepeatCircuitBreaker(e);if(s)return s;let i=this.checkRepeatFailureGuard(e);return i||(this.observeSuspectedLoop(e),null)}async execute(e){if(e.signal.aborted)return{content:"Tool call aborted",isError:!0,failureClass:be(e.signal)};let n=await this.runPreDispatchGates(e);if(n)return n;let r=await this.executeCore(e);return this.repeatFailureGuard.note(e,r),r.isError!==!0&&this.resetDenialBreaker(),r}async executeBatch(e,n){if(e.length===0)return[];if(e.length===1)return[await this.execute(e[0])];let r=new Array(e.length),o=new Set;for(let c=0;c<e.length;c++){let l=e[c];if(l.signal.aborted){r[c]={content:"Tool call aborted",isError:!0,failureClass:be(l.signal)},o.add(c);continue}let d=await this.runPreDispatchGates(l);if(d){r[c]=d,o.add(c);continue}}let s=e.map((c,l)=>({call:c,originalIndex:l})).filter((c,l)=>!o.has(l));if(s.length===0)return r;let i=Ah(s.map(c=>c.call),this.classifier),a={repeatFailureGuard:this.repeatFailureGuard,repeatBreakerExemptTools:Id,executeCore:c=>this.executeCore(c),subagentExecutor:this.subagentExecutor,sessionId:this.sessionId,maxConcurrentSafeCalls:this.maxConcurrentSafeCalls,onActivity:n};for(let c of i)c.isConcurrencySafe?await Nh(c,s,r,a):await Uh(c,s,r,a),Lh(c,s,r);return r.some(c=>c!==void 0&&c.isError!==!0)&&this.resetDenialBreaker(),r}async executeCore(e){let n=await this.executeCoreInner(e);return this.applyOutputCap(n)}applyOutputCap(e){let n=this.maxOutputBytes;if(n===void 0)return e;let r=Buffer.byteLength(e.content,"utf8");return r<=n||(e.content=st(e.content,n),e.truncated=!0,C(`[output-cap #661] fork tool result capped: original=${r}B capped=${Buffer.byteLength(e.content,"utf8")}B (cap=${n}B)`)),e}async executeCoreInner(e){if($h(e.name)){let i=await Bh(this.subagentExecutor,e);return i.thrownMessage!==void 0?this.firePostToolUseFailure(e.name,i.thrownMessage,e.signal,e.input):this.firePostToolUse(e.name,i.result.content,e.signal,e.input,i.result),i.result}if(e.name==="skill"){if(!this.skillExecutor)return{content:"Skill tool is not available in this session configuration",isError:!0};let i,a=!1,c="";try{i=await this.skillExecutor.execute(e)}catch(l){a=!0,c=l instanceof Error?l.message:String(l),i={content:`Skill tool error: ${c}`,isError:!0}}return a?this.firePostToolUseFailure(e.name,c,e.signal,e.input):this.firePostToolUse(e.name,i.content,e.signal,e.input,i),i}if(e.name==="compose"){let i=await this.executeCompose(e);return this.firePostToolUse(e.name,i.content,e.signal,e.input,i),i}let n=this.handlers.get(e.name);if(!n){let i=this.unknownToolMessage(e.name);return await this.emitPreToolUseBlock(e.name,i),{content:i,isError:!0,failureClass:"permission-denied"}}let r,o=!1,s="";try{r=await n(e.input,e.signal,this.callHandlerContext(e))}catch(i){o=!0,s=i instanceof Error?i.message:String(i),r={content:`Tool execution error: ${s}`,isError:!0}}return o?this.firePostToolUseFailure(e.name,s,e.signal,e.input):this.firePostToolUse(e.name,r.content,e.signal,e.input,r),r}async executeCompose(e){if(!this.composeExecutor)return{content:"Compose tool is not available in this session configuration",isError:!0};try{return await this.composeExecutor.execute(e)}catch(n){return{content:`Compose tool error: ${n instanceof Error?n.message:String(n)}`,isError:!0}}}firePostToolUse(e,n,r,o,s){if(!this.hookRegistry)return;let i={event:"PostToolUse",toolName:e,output:n,...o!==void 0?{input:o}:{},...this.sessionId!==void 0?{sessionId:this.sessionId}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager?{grantManager:this.sessionGrantManager}:{},...s?.isError===!0?{isError:!0}:{},...s?.incomplete===!0?{incomplete:!0,...s.incompleteReason?{incompleteReason:s.incompleteReason}:{}}:{}};Dg(this.hookRegistry,i,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(()=>{})}firePostToolUseFailure(e,n,r,o){if(!this.hookRegistry)return;let s={event:"PostToolUseFailure",toolName:e,error:n,...o!==void 0?{input:o}:{},...this.sessionId!==void 0?{sessionId:this.sessionId}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{}};Fg(this.hookRegistry,s,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(i=>{C(`firePostToolUseFailure outer catch (tool=${e}): ${String(i)}`)})}};import{spawn as cy}from"child_process";import dO from"os";I();P();import{mkdir as l0,writeFile as d0}from"fs/promises";import{dirname as u0,join as p0}from"path";function f0(){return p0(De(),"routing-decisions.jsonl")}function m0(t){let e={surface:"afk"};for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r);return e}async function Ee(t){if(!(b.VITEST||b.NODE_ENV==="test"))try{let e=f0();await l0(u0(e),{recursive:!0});let n=new Date().toISOString().split(".")[0]+"Z",r=JSON.stringify({ts:n,...m0(t)})+`
|
|
203
|
-
`;await d0(e,r,{flag:"a"})}catch{}}var g0=/Tests\s+(\d+)\s+passed(?:\s*\|\s*(\d+)\s+failed)?(?:\s*\|\s*(\d+)\s+skipped)?/,h0=/Tests:\s+(?:(\d+)\s+failed,\s*)?(\d+)\s+passed,\s*\d+\s+total/,y0=/={3,}\s*(?:(\d+)\s+failed,\s*)?(\d+)\s+passed(?:,\s*(\d+)\s+warning)?.*in\s+[\d.]+s\s*={3,}|={3,}\s*(\d+)\s+passed.*in\s+[\d.]+s\s*={3,}/,b0=/(\d+)\s+passing/,w0=/(\d+)\s+failing/,S0=/^(ok|FAIL)\s+\S+\s+[\d.]+s/gm,k0=/test result: (?:ok|FAILED)\. (\d+) passed; (\d+) failed(?:; (\d+) ignored)?/,v0=/(\d+) examples?, (\d+) failures?/,T0=/OK \((\d+) tests?/,_0=/Tests:\s*(\d+)[^]*?Failures:\s*(\d+)/;function E0(t){let e=t.match(g0);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10),o=e[3]!==void 0?parseInt(e[3],10):void 0;return{runner:"vitest",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function A0(t){let e=t.match(h0);if(!e)return null;let n=parseInt(e[1]??"0",10);return{runner:"jest",passed:parseInt(e[2]??"0",10),failed:n}}function x0(t){let e=t.match(y0);if(!e)return null;if(e[2]!==void 0){let n=parseInt(e[2],10),r=parseInt(e[1]??"0",10);return{runner:"pytest",passed:n,failed:r}}return e[4]!==void 0?{runner:"pytest",passed:parseInt(e[4],10),failed:0}:null}function R0(t){let e=t.match(b0);if(!e)return null;let n=parseInt(e[1]??"0",10),r=t.match(w0),o=r?parseInt(r[1]??"0",10):0;return{runner:"mocha",passed:n,failed:o}}function I0(t){let e=[...t.matchAll(S0)];if(e.length===0)return null;let n=0,r=0;for(let o of e)o[1]==="ok"?n++:o[1]==="FAIL"&&r++;return{runner:"go-test",passed:n,failed:r}}function C0(t){let e=t.match(k0);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10),o=e[3]!==void 0?parseInt(e[3],10):void 0;return{runner:"cargo",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function P0(t){let e=t.match(v0);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10);return{runner:"rspec",passed:n-r,failed:r}}function M0(t){let e=t.match(T0);if(e)return{runner:"phpunit",passed:parseInt(e[1]??"0",10),failed:0};let n=t.match(_0);if(n){let r=parseInt(n[1]??"0",10),o=parseInt(n[2]??"0",10);return{runner:"phpunit",passed:r-o,failed:o}}return null}function wo(t){return E0(t)??A0(t)??x0(t)??R0(t)??I0(t)??C0(t)??P0(t)??M0(t)??null}var jh=/\x1B\][^\x07\x1B\x9C]*(?:\x07|\x1B\\|\x9C)|\x1B[P^_X][^\x1B\x9C]*(?:\x1B\\|\x9C)|\x1B\[[0-?]*[ -/]*[@-~]|\x9B[0-?]*[ -/]*[@-~]|\x1B[6-_]/g,O0=/[\x00-\x1F\x7F-\x9F]/g;function we(t){return t.replace(jh,"").replace(O0," ").trim()}function Ae(t){return t.replace(jh,"")}import{statSync as D0}from"node:fs";function So(t){if(typeof t!="object"||t===null)return!1;let e=t;return e.code==="ENOENT"&&typeof e.syscall=="string"&&e.syscall.startsWith("spawn")}function F0(t){if(t===void 0)return!1;try{return D0(t),!1}catch{return!0}}function Xn(t,e){let n=t instanceof Error?t.message:typeof t?.message=="string"?String(t.message):String(t);return So(t)&&F0(e)?`working directory does not exist: ${e} (deleted worktree?) \u2014 underlying: ${n}`:n}import fn from"path";import{realpathSync as rO}from"fs";I();import{basename as Y0,dirname as Q0,join as Li,relative as Z0,resolve as Yn,sep as ko}from"path";import{homedir as Z}from"os";I();P();import{realpathSync as Gh}from"fs";import{dirname as j0,resolve as un,join as Di}from"path";import{homedir as je}from"os";var Hh=new Set;function Ut(t){let e=t instanceof Error?t.message:String(t);Hh.has(e)||(Hh.add(e),console.warn(`[afk-home] Malformed AFK home/state env var ignored while deriving the credential floor: ${e}. The relocated tree is NOT protected \u2014 the default ~/.afk entries still apply. Fix the env var to restore coverage.`))}import{statSync as Pd}from"node:fs";import{homedir as L0}from"node:os";import{basename as N0,dirname as Kh,join as U0}from"node:path";var Wh,Cd=new Map;function qh(t){return typeof t=="object"&&t!==null&&"code"in t?String(t.code):void 0}function $0(t){let e=N0(t),n=e===e.toLowerCase()?e.toUpperCase():e.toLowerCase();if(n===e)return;let r;try{r=Pd(t)}catch{return}let o=Cd.get(r.dev);if(o!==void 0)return o;try{let s=Pd(U0(Kh(t),n)),i=r.dev===s.dev&&r.ino===s.ino;return Cd.set(r.dev,i),i}catch(s){let i=qh(s);return i==="ENOENT"||i==="ENOTDIR"?(Cd.set(r.dev,!1),!1):void 0}}function B0(t=L0()){if(Wh!==void 0)return Wh;let e=t;for(;;)try{return Pd(e),$0(e)??!0}catch(n){let r=qh(n);if(r!=="ENOENT"&&r!=="ENOTDIR")return!0;let o=Kh(e);if(o===e)return!0;e=o}}function zn(t,e,n=e){if(t===e||t.startsWith(e+"/")||t.startsWith(e+"\\"))return!0;if(!B0(n))return!1;let r=t.toLowerCase(),o=e.toLowerCase();return r===o||r.startsWith(o+"/")||r.startsWith(o+"\\")}var H0=[`${je()}/.ssh`,`${je()}/.aws`,`${je()}/.gnupg`,`${je()}/.config/gcloud`,"/etc","/System","/private/etc","/usr/local/etc",`${je()}/.afk/config`,`${je()}/.afk/state`,`${je()}/.npmrc`,`${je()}/.docker/config.json`,`${je()}/Library/LaunchAgents`,`${je()}/Library/LaunchDaemons`,"/Library/LaunchAgents","/Library/LaunchDaemons",`${je()}/.config/systemd`,...process.platform==="win32"&&b.APPDATA?[`${b.APPDATA}\\gcloud`,`${b.APPDATA}\\Docker`]:[],...process.platform==="win32"&&b.USERPROFILE?[`${b.USERPROFILE}\\.ssh`,`${b.USERPROFILE}\\.aws`,`${b.USERPROFILE}\\.gnupg`]:[]];function W0(){let t=[];try{let e=re();t.push(un(Di(e,"config"))),t.push(un(Di(e,"state")))}catch(e){Ut(e)}try{t.push(un(Q()))}catch(e){Ut(e)}return t}var Oi;function Md(){let t=`${b.AFK_WRITE_DENYLIST??""}\0${b.AFK_HOME??""}\0${b.AFK_STATE_DIR??""}`;if(!Oi||Oi.key!==t){let e=b.AFK_WRITE_DENYLIST,n=process.platform==="win32"?";":":",r=e?e.split(n).map(o=>o.trim()).filter(Boolean).map(o=>o==="~"||o.startsWith("~/")||o.startsWith("~\\")?Di(je(),o.slice(2)):o).map(o=>un(o)).filter(Boolean):[];Oi={key:t,unresolved:[...new Set([...H0.map(o=>un(o)),...W0()]),...r]}}return[...new Set(Oi.unresolved.map(e=>He(e)))]}function He(t){let e=un(t);try{return Gh(e)}catch{}let n=[],r=e;for(let o=0;o<64;o++){let s=j0(r);if(s===r)break;n.unshift(r.slice(s.length+1)),r=s;try{let i=Gh(r);return Di(i,...n)}catch{}}return e}function Jn(t,e="write_file"){let n=He(un(t));for(let r of Md())if(zn(n,r))throw new Error(`${e}: refusing to write to protected path: ${n} (matches denylist entry: ${r})`)}P();import{isAbsolute as K0,relative as q0,sep as G0}from"node:path";import{homedir as Fi}from"node:os";function X0(t,e){let n=q0(e,t);return n===""||n!==".."&&!n.startsWith(`..${G0}`)&&!K0(n)}function Od(t,e){return t.filter(n=>!e.some(r=>X0(n,r)))}function z0(t,e){return t.filter(({source:n})=>n!==e).map(({root:n})=>n)}var J0={".afk/config/mcp.json":`${Fi()}/.afk/config`,".afk/config/schedules.json":`${Fi()}/.afk/config`,".ssh/config":`${Fi()}/.ssh`,".ssh/known_hosts":`${Fi()}/.ssh`};function Xh(t,e){return t.flatMap(({rel:n,resolved:r})=>Od([r],z0(e,J0[n])))}import{isAbsolute as P5,resolve as V0}from"path";import{homedir as zh}from"os";function Vn(t){return t==="~"?zh():t.startsWith("~/")?V0(zh(),t.slice(2)):t}var Vh=[`${Z()}/.ssh`,`${Z()}/.aws`,`${Z()}/.gnupg`,`${Z()}/.config/gcloud`,`${Z()}/.afk/config`,`${Z()}/.npmrc`,`${Z()}/.docker/config.json`,`${Z()}/.git-credentials`,`${Z()}/.netrc`,`${Z()}/.config/gh/hosts.yml`,`${Z()}/.kube/config`,"/etc/shadow","/etc/sudoers","/private/etc/master.passwd",`${Z()}/.password-store`,`${Z()}/Library/Application Support/Google/Chrome`,`${Z()}/Library/Application Support/Chromium`,`${Z()}/Library/Application Support/BraveSoftware`,`${Z()}/Library/Application Support/Microsoft Edge`,`${Z()}/Library/Application Support/Arc`,`${Z()}/Library/Application Support/Firefox`,...process.platform==="win32"&&b.USERPROFILE?[`${b.USERPROFILE}\\.ssh`,`${b.USERPROFILE}\\.aws`,`${b.USERPROFILE}\\.gnupg`]:[],...process.platform==="win32"&&b.APPDATA?[`${b.APPDATA}\\gcloud`,`${b.APPDATA}\\Docker`,`${b.APPDATA}\\Mozilla\\Firefox`]:[],...process.platform==="win32"&&b.LOCALAPPDATA?[`${b.LOCALAPPDATA}\\Google\\Chrome`,`${b.LOCALAPPDATA}\\Chromium`,`${b.LOCALAPPDATA}\\BraveSoftware`,`${b.LOCALAPPDATA}\\Microsoft\\Edge`]:[]],To=[".afk/config/mcp.json",".afk/config/schedules.json",".ssh/config",".ssh/known_hosts"],eO=`${Z()}/.afk/config`,W5=To.map(t=>Li(Z(),t));function Yh(t){let e=Yn(t);return Li(He(Q0(e)),Y0(e))}var vo;function Qh(t){if(!t)return[];let e=process.platform==="win32"?";":":";return t.split(e).map(n=>n.trim()).filter(Boolean).map(n=>n==="~"||n.startsWith("~/")||n.startsWith("~\\")?Vn(n.replace(/^~[/\\]+/,"~/")):n).map(n=>Yn(n))}function tO(){try{return[He(Yn(Li(re(),"config")))]}catch(t){return Ut(t),[]}}var Jh=".afk/";function nO(){try{let t=re();return To.filter(e=>e.startsWith(Jh)).map(e=>Yh(Li(t,e.slice(Jh.length))))}catch(t){return Ut(t),[]}}function Zh(){let t=`${b.AFK_READ_DENYLIST??""}\0${b.AFK_HOME??""}`;if(vo&&vo.key===t)return vo;let e=Qh(b.AFK_READ_DENYLIST).map(i=>He(i)).filter(Boolean),n=Vh.map(i=>({source:i,root:He(Yn(i))})),r=tO(),o=[...new Set([...n.map(({root:i})=>i),...r])],s=n.filter(({source:i,root:a})=>i!==eO||!r.includes(a)).map(({root:i})=>i);return vo={key:t,builtins:o,extras:e,allow:[...new Set([...Xh(To.map(i=>({rel:i,resolved:Yh(`${Z()}/${i}`)})),n),...Od(nO(),s)])]},vo}function ey(){let{builtins:t,extras:e}=Zh();return[...t,...e]}function ty(t){let e=He(Yn(t));return ey().filter(n=>n!==e&&zn(n,e,n)).map(n=>(n.startsWith(e+ko)?Z0(e,n):n.split(ko).slice(e.split(ko).length).join(ko)).split(ko).join("/"))}function pn(t){let e=He(Yn(t)),{builtins:n,extras:r,allow:o}=Zh();for(let s of r)if(zn(e,s))return{denied:!0,matched:s};if(o.includes(e))return{denied:!1};for(let s of n)if(zn(e,s))return{denied:!0,matched:s};return{denied:!1}}var Dd="read-denylist entry:",ny="is a protected credential/secret path";function mn(t){try{return rO.native(t)}catch{let e=fn.dirname(t),n=fn.basename(t);return e===t?t:fn.join(mn(e),n)}}var ry=new Map;function oO(t){let e=ry.get(t);if(e!==void 0)return e;let n=mn(t);return ry.set(t,n),n}function oy(t,e,n,r){let o=e?.resolveBase??e?.cwd??r,s=fn.isAbsolute(t)?t:fn.resolve(o??process.cwd(),t);if(e?.allowAll===!0)return{restricted:!1,resolved:s,roots:[]};if(o===void 0)return{restricted:!1,resolved:s,roots:[]};let i=mn(s),a=n==="read"?e?.readRoots??[o]:e?.writeRoots??[o];for(let c of a){let l=oO(c),d=fn.relative(l,i);if(!d.startsWith("..")&&!fn.isAbsolute(d))return{restricted:!1,resolved:s,roots:a}}return{restricted:!0,resolved:s,roots:a}}function ee(t,e,n="read",r){let{restricted:o,resolved:s,roots:i}=oy(t,e,n,r);if(n==="read"){let a=pn(s);if(a.denied)throw new Error(`Path \`${t}\` ${ny} (${Dd} \`${a.matched}\`) and cannot be read.`)}if(o){let a=i.map(l=>`\`${l}\``).join(", "),c=n==="read"?"read roots":"write roots";throw new Error(`Path \`${t}\` is outside the allowed ${c} [${a}].`)}return s}function sy(t,e,n="read",r){return oy(t,e,n,r)}function iy(t){let e=new Set,n=[];for(let r of t.split(/\s+/)){if(r.length===0)continue;let o=r.replace(/^\d*[<>|&]+/,"").replace(/^['"]/,"").replace(/['";,)]+$/,"");if(o.length===0)continue;let s=o.startsWith("/"),i=o==="~"||o.startsWith("~/");!s&&!i||e.has(o)||(e.add(o),n.push(o))}return n}import{execFileSync as sO}from"node:child_process";function gn(t,e="SIGKILL"){if(!(t<=0))try{process.platform==="win32"?sO("taskkill",["/F","/T","/PID",String(t)],{stdio:"ignore",timeout:5e3}):process.kill(-t,e)}catch{}}P();import{mkdirSync as iO,openSync as aO,writeSync as cO,closeSync as lO}from"fs";var ay=8e6;function Fd(t,e,n){try{let r=Nl(t);if(r===void 0)return;iO(r,{recursive:!0,mode:448});let o=e.replace(/[^A-Za-z0-9_-]/g,"_").slice(0,128)||"capture",s=`${r}/${o}.txt`,i=Buffer.from(n,"utf8"),a=i.length<=ay?i:i.subarray(0,ay),c=aO(s,"wx",384);try{cO(c,a)}finally{lO(c)}return s}catch{return}}function uO(t){if(typeof t!="object"||t===null)throw new Error("Input must be an object");let e=t;if(typeof e.command!="string")throw new Error('Input must have a "command" field of type string');let n=12e4;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number")throw new Error("timeout_ms must be a number");if(e.timeout_ms<0||e.timeout_ms>6e5)throw new Error("timeout_ms must be between 0 and 600000");n=e.timeout_ms}return{command:e.command,timeout_ms:n}}function Ni(t,e){let n=!1,r=!1;function o(){n||t==="bypassPermissions"&&(n=!0,console.warn("[security] bash handler: shell=true with bypassPermissions \u2014 all shell metacharacters are interpreted without confirmation. Migrate to execFile to eliminate this risk (tracked: C4)."))}function s(i,a){if(r)return;let c=a.resolveBase??a.cwd??e,l=dO.homedir(),d=[];for(let u of iy(i)){let p=u==="~"?l:u.startsWith("~/")?l+u.slice(1):u,f=sy(p,a,"write",c);f.restricted&&d.push(f.resolved)}d.length!==0&&(r=!0,console.warn(`[security] bash: command references path(s) outside writeRoots: ${d.join(", ")} \u2014 bash containment is best-effort (tracked C4); use file tools for contained writes.`),Ee({event:"tool.bash_path_escape",tool:"bash",restricted_count:d.length,mode:"write"}))}return async(i,a,c)=>{let{command:l,timeout_ms:d}=uO(i);if(a.aborted)return{content:"Command aborted",isError:!0};if(o(),c!==void 0)try{s(l,c)}catch{}let u=Date.now();return new Promise(p=>{let f=!1;function m(S){f||(f=!0,clearTimeout(w),a.removeEventListener("abort",M),p(S))}let g=Qg(),h={detached:!0,stdio:["ignore","pipe","pipe"],...(c?.resolveBase??c?.cwd??e)!==void 0?{cwd:c?.resolveBase??c?.cwd??e}:{},...c?.env!==void 0?{env:{...process.env,...c.env}}:{}},y=g.shell===!0?cy(l,{shell:!0,...h}):cy(g.shell,[...g.args??[],l],h);y.unref(),c?.spawnedPidRegistry!==void 0&&y.pid!==void 0&&c.spawnedPidRegistry.register(y.pid);let w=setTimeout(()=>{y.pid!==void 0&&gn(y.pid),m({content:`Command timed out after ${d}ms`,isError:!0,durationMs:Date.now()-u})},d),k="",v="",_=0,R=!1;function A(S){if(R||f||_<8e6)return;R=!0,console.warn(`[bash] overflow kill: stream=${S} totalBytes=${_} command="${l}"`),Ee({event:"tool.overflow_kill",tool:"bash",total_bytes:_,stream:S}),y.kill("SIGKILL");let T=Ae((k+v).trimEnd()),E=wo(T)??void 0,O=st(T,1e5)+Kg;m({content:O,truncated:!0,durationMs:Date.now()-u,...E!==void 0?{testResult:E}:{}})}y.stdout.on("data",S=>{let T=8e6-_,E=S.length<=T?S:S.subarray(0,Math.max(0,T));_+=E.length,k+=E.toString("utf8"),A("stdout")}),y.stderr.on("data",S=>{let T=8e6-_,E=S.length<=T?S:S.subarray(0,Math.max(0,T));_+=E.length,v+=E.toString("utf8"),A("stderr")});let M=()=>{y.pid!==void 0&&gn(y.pid),m({content:"Command aborted",isError:!0,durationMs:Date.now()-u})};a.addEventListener("abort",M),a.aborted&&M(),y.on("close",S=>{if(a.aborted){m({content:"Command aborted",isError:!0,durationMs:Date.now()-u});return}if(S!==null&&S!==0){let L=v.trimEnd()||k.trimEnd(),D=Hn(L),N=Date.now()-u,W=D.truncated?Fd(c?.sessionId,c?.toolUseId??"",L):void 0;m({content:`Command exited with code ${S}${D.content?`
|
|
203
|
+
`;await d0(e,r,{flag:"a"})}catch{}}var g0=/Tests\s+(\d+)\s+passed(?:\s*\|\s*(\d+)\s+failed)?(?:\s*\|\s*(\d+)\s+skipped)?/,h0=/Tests:\s+(?:(\d+)\s+failed,\s*)?(\d+)\s+passed,\s*\d+\s+total/,y0=/={3,}\s*(?:(\d+)\s+failed,\s*)?(\d+)\s+passed(?:,\s*(\d+)\s+warning)?.*in\s+[\d.]+s\s*={3,}|={3,}\s*(\d+)\s+passed.*in\s+[\d.]+s\s*={3,}/,b0=/(\d+)\s+passing/,w0=/(\d+)\s+failing/,S0=/^(ok|FAIL)\s+\S+\s+[\d.]+s/gm,k0=/test result: (?:ok|FAILED)\. (\d+) passed; (\d+) failed(?:; (\d+) ignored)?/,v0=/(\d+) examples?, (\d+) failures?/,T0=/OK \((\d+) tests?/,_0=/Tests:\s*(\d+)[^]*?Failures:\s*(\d+)/;function E0(t){let e=t.match(g0);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10),o=e[3]!==void 0?parseInt(e[3],10):void 0;return{runner:"vitest",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function A0(t){let e=t.match(h0);if(!e)return null;let n=parseInt(e[1]??"0",10);return{runner:"jest",passed:parseInt(e[2]??"0",10),failed:n}}function x0(t){let e=t.match(y0);if(!e)return null;if(e[2]!==void 0){let n=parseInt(e[2],10),r=parseInt(e[1]??"0",10);return{runner:"pytest",passed:n,failed:r}}return e[4]!==void 0?{runner:"pytest",passed:parseInt(e[4],10),failed:0}:null}function R0(t){let e=t.match(b0);if(!e)return null;let n=parseInt(e[1]??"0",10),r=t.match(w0),o=r?parseInt(r[1]??"0",10):0;return{runner:"mocha",passed:n,failed:o}}function I0(t){let e=[...t.matchAll(S0)];if(e.length===0)return null;let n=0,r=0;for(let o of e)o[1]==="ok"?n++:o[1]==="FAIL"&&r++;return{runner:"go-test",passed:n,failed:r}}function C0(t){let e=t.match(k0);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10),o=e[3]!==void 0?parseInt(e[3],10):void 0;return{runner:"cargo",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function P0(t){let e=t.match(v0);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10);return{runner:"rspec",passed:n-r,failed:r}}function M0(t){let e=t.match(T0);if(e)return{runner:"phpunit",passed:parseInt(e[1]??"0",10),failed:0};let n=t.match(_0);if(n){let r=parseInt(n[1]??"0",10),o=parseInt(n[2]??"0",10);return{runner:"phpunit",passed:r-o,failed:o}}return null}function wo(t){return E0(t)??A0(t)??x0(t)??R0(t)??I0(t)??C0(t)??P0(t)??M0(t)??null}var jh=/\x1B\][^\x07\x1B\x9C]*(?:\x07|\x1B\\|\x9C)|\x1B[P^_X][^\x1B\x9C]*(?:\x1B\\|\x9C)|\x1B\[[0-?]*[ -/]*[@-~]|\x9B[0-?]*[ -/]*[@-~]|\x1B[6-_]/g,O0=/[\x00-\x1F\x7F-\x9F]/g;function we(t){return t.replace(jh,"").replace(O0," ").trim()}function Ae(t){return t.replace(jh,"")}import{statSync as D0}from"node:fs";function So(t){if(typeof t!="object"||t===null)return!1;let e=t;return e.code==="ENOENT"&&typeof e.syscall=="string"&&e.syscall.startsWith("spawn")}function F0(t){if(t===void 0)return!1;try{return D0(t),!1}catch{return!0}}function Xn(t,e){let n=t instanceof Error?t.message:typeof t?.message=="string"?String(t.message):String(t);return So(t)&&F0(e)?`working directory does not exist: ${e} (deleted worktree?) \u2014 underlying: ${n}`:n}import fn from"path";import{realpathSync as rO}from"fs";I();import{basename as Y0,dirname as Q0,join as Li,relative as Z0,resolve as Yn,sep as ko}from"path";import{homedir as Z}from"os";I();P();import{realpathSync as Gh}from"fs";import{dirname as j0,resolve as un,join as Di}from"path";import{homedir as je}from"os";var Hh=new Set;function Ut(t){let e=t instanceof Error?t.message:String(t);Hh.has(e)||(Hh.add(e),console.warn(`[afk-home] Malformed AFK home/state env var ignored while deriving the credential floor: ${e}. The relocated tree is NOT protected \u2014 the default ~/.afk entries still apply. Fix the env var to restore coverage.`))}import{statSync as Pd}from"node:fs";import{homedir as L0}from"node:os";import{basename as N0,dirname as Kh,join as U0}from"node:path";var Wh,Cd=new Map;function qh(t){return typeof t=="object"&&t!==null&&"code"in t?String(t.code):void 0}function $0(t){let e=N0(t),n=e===e.toLowerCase()?e.toUpperCase():e.toLowerCase();if(n===e)return;let r;try{r=Pd(t)}catch{return}let o=Cd.get(r.dev);if(o!==void 0)return o;try{let s=Pd(U0(Kh(t),n)),i=r.dev===s.dev&&r.ino===s.ino;return Cd.set(r.dev,i),i}catch(s){let i=qh(s);return i==="ENOENT"||i==="ENOTDIR"?(Cd.set(r.dev,!1),!1):void 0}}function B0(t=L0()){if(Wh!==void 0)return Wh;let e=t;for(;;)try{return Pd(e),$0(e)??!0}catch(n){let r=qh(n);if(r!=="ENOENT"&&r!=="ENOTDIR")return!0;let o=Kh(e);if(o===e)return!0;e=o}}function zn(t,e,n=e){if(t===e||t.startsWith(e+"/")||t.startsWith(e+"\\"))return!0;if(!B0(n))return!1;let r=t.toLowerCase(),o=e.toLowerCase();return r===o||r.startsWith(o+"/")||r.startsWith(o+"\\")}var H0=[`${je()}/.ssh`,`${je()}/.aws`,`${je()}/.gnupg`,`${je()}/.config/gcloud`,"/etc","/System","/private/etc","/usr/local/etc",`${je()}/.afk/config`,`${je()}/.afk/state`,`${je()}/.npmrc`,`${je()}/.docker/config.json`,`${je()}/Library/LaunchAgents`,`${je()}/Library/LaunchDaemons`,"/Library/LaunchAgents","/Library/LaunchDaemons",`${je()}/.config/systemd`,...process.platform==="win32"&&b.APPDATA?[`${b.APPDATA}\\gcloud`,`${b.APPDATA}\\Docker`]:[],...process.platform==="win32"&&b.USERPROFILE?[`${b.USERPROFILE}\\.ssh`,`${b.USERPROFILE}\\.aws`,`${b.USERPROFILE}\\.gnupg`]:[]];function W0(){let t=[];try{let e=re();t.push(un(Di(e,"config"))),t.push(un(Di(e,"state")))}catch(e){Ut(e)}try{t.push(un(Q()))}catch(e){Ut(e)}return t}var Oi;function Md(){let t=`${b.AFK_WRITE_DENYLIST??""}\0${b.AFK_HOME??""}\0${b.AFK_STATE_DIR??""}`;if(!Oi||Oi.key!==t){let e=b.AFK_WRITE_DENYLIST,n=process.platform==="win32"?";":":",r=e?e.split(n).map(o=>o.trim()).filter(Boolean).map(o=>o==="~"||o.startsWith("~/")||o.startsWith("~\\")?Di(je(),o.slice(2)):o).map(o=>un(o)).filter(Boolean):[];Oi={key:t,unresolved:[...new Set([...H0.map(o=>un(o)),...W0()]),...r]}}return[...new Set(Oi.unresolved.map(e=>He(e)))]}function He(t){let e=un(t);try{return Gh(e)}catch{}let n=[],r=e;for(let o=0;o<64;o++){let s=j0(r);if(s===r)break;n.unshift(r.slice(s.length+1)),r=s;try{let i=Gh(r);return Di(i,...n)}catch{}}return e}function Jn(t,e="write_file"){let n=He(un(t));for(let r of Md())if(zn(n,r))throw new Error(`${e}: refusing to write to protected path: ${n} (matches denylist entry: ${r})`)}P();import{isAbsolute as K0,relative as q0,sep as G0}from"node:path";import{homedir as Fi}from"node:os";function X0(t,e){let n=q0(e,t);return n===""||n!==".."&&!n.startsWith(`..${G0}`)&&!K0(n)}function Od(t,e){return t.filter(n=>!e.some(r=>X0(n,r)))}function z0(t,e){return t.filter(({source:n})=>n!==e).map(({root:n})=>n)}var J0={".afk/config/mcp.json":`${Fi()}/.afk/config`,".afk/config/schedules.json":`${Fi()}/.afk/config`,".ssh/config":`${Fi()}/.ssh`,".ssh/known_hosts":`${Fi()}/.ssh`};function Xh(t,e){return t.flatMap(({rel:n,resolved:r})=>Od([r],z0(e,J0[n])))}import{isAbsolute as M5,resolve as V0}from"path";import{homedir as zh}from"os";function Vn(t){return t==="~"?zh():t.startsWith("~/")?V0(zh(),t.slice(2)):t}var Vh=[`${Z()}/.ssh`,`${Z()}/.aws`,`${Z()}/.gnupg`,`${Z()}/.config/gcloud`,`${Z()}/.afk/config`,`${Z()}/.npmrc`,`${Z()}/.docker/config.json`,`${Z()}/.git-credentials`,`${Z()}/.netrc`,`${Z()}/.config/gh/hosts.yml`,`${Z()}/.kube/config`,"/etc/shadow","/etc/sudoers","/private/etc/master.passwd",`${Z()}/.password-store`,`${Z()}/Library/Application Support/Google/Chrome`,`${Z()}/Library/Application Support/Chromium`,`${Z()}/Library/Application Support/BraveSoftware`,`${Z()}/Library/Application Support/Microsoft Edge`,`${Z()}/Library/Application Support/Arc`,`${Z()}/Library/Application Support/Firefox`,...process.platform==="win32"&&b.USERPROFILE?[`${b.USERPROFILE}\\.ssh`,`${b.USERPROFILE}\\.aws`,`${b.USERPROFILE}\\.gnupg`]:[],...process.platform==="win32"&&b.APPDATA?[`${b.APPDATA}\\gcloud`,`${b.APPDATA}\\Docker`,`${b.APPDATA}\\Mozilla\\Firefox`]:[],...process.platform==="win32"&&b.LOCALAPPDATA?[`${b.LOCALAPPDATA}\\Google\\Chrome`,`${b.LOCALAPPDATA}\\Chromium`,`${b.LOCALAPPDATA}\\BraveSoftware`,`${b.LOCALAPPDATA}\\Microsoft\\Edge`]:[]],To=[".afk/config/mcp.json",".afk/config/schedules.json",".ssh/config",".ssh/known_hosts"],eO=`${Z()}/.afk/config`,K5=To.map(t=>Li(Z(),t));function Yh(t){let e=Yn(t);return Li(He(Q0(e)),Y0(e))}var vo;function Qh(t){if(!t)return[];let e=process.platform==="win32"?";":":";return t.split(e).map(n=>n.trim()).filter(Boolean).map(n=>n==="~"||n.startsWith("~/")||n.startsWith("~\\")?Vn(n.replace(/^~[/\\]+/,"~/")):n).map(n=>Yn(n))}function tO(){try{return[He(Yn(Li(re(),"config")))]}catch(t){return Ut(t),[]}}var Jh=".afk/";function nO(){try{let t=re();return To.filter(e=>e.startsWith(Jh)).map(e=>Yh(Li(t,e.slice(Jh.length))))}catch(t){return Ut(t),[]}}function Zh(){let t=`${b.AFK_READ_DENYLIST??""}\0${b.AFK_HOME??""}`;if(vo&&vo.key===t)return vo;let e=Qh(b.AFK_READ_DENYLIST).map(i=>He(i)).filter(Boolean),n=Vh.map(i=>({source:i,root:He(Yn(i))})),r=tO(),o=[...new Set([...n.map(({root:i})=>i),...r])],s=n.filter(({source:i,root:a})=>i!==eO||!r.includes(a)).map(({root:i})=>i);return vo={key:t,builtins:o,extras:e,allow:[...new Set([...Xh(To.map(i=>({rel:i,resolved:Yh(`${Z()}/${i}`)})),n),...Od(nO(),s)])]},vo}function ey(){let{builtins:t,extras:e}=Zh();return[...t,...e]}function ty(t){let e=He(Yn(t));return ey().filter(n=>n!==e&&zn(n,e,n)).map(n=>(n.startsWith(e+ko)?Z0(e,n):n.split(ko).slice(e.split(ko).length).join(ko)).split(ko).join("/"))}function pn(t){let e=He(Yn(t)),{builtins:n,extras:r,allow:o}=Zh();for(let s of r)if(zn(e,s))return{denied:!0,matched:s};if(o.includes(e))return{denied:!1};for(let s of n)if(zn(e,s))return{denied:!0,matched:s};return{denied:!1}}var Dd="read-denylist entry:",ny="is a protected credential/secret path";function mn(t){try{return rO.native(t)}catch{let e=fn.dirname(t),n=fn.basename(t);return e===t?t:fn.join(mn(e),n)}}var ry=new Map;function oO(t){let e=ry.get(t);if(e!==void 0)return e;let n=mn(t);return ry.set(t,n),n}function oy(t,e,n,r){let o=e?.resolveBase??e?.cwd??r,s=fn.isAbsolute(t)?t:fn.resolve(o??process.cwd(),t);if(e?.allowAll===!0)return{restricted:!1,resolved:s,roots:[]};if(o===void 0)return{restricted:!1,resolved:s,roots:[]};let i=mn(s),a=n==="read"?e?.readRoots??[o]:e?.writeRoots??[o];for(let c of a){let l=oO(c),d=fn.relative(l,i);if(!d.startsWith("..")&&!fn.isAbsolute(d))return{restricted:!1,resolved:s,roots:a}}return{restricted:!0,resolved:s,roots:a}}function ee(t,e,n="read",r){let{restricted:o,resolved:s,roots:i}=oy(t,e,n,r);if(n==="read"){let a=pn(s);if(a.denied)throw new Error(`Path \`${t}\` ${ny} (${Dd} \`${a.matched}\`) and cannot be read.`)}if(o){let a=i.map(l=>`\`${l}\``).join(", "),c=n==="read"?"read roots":"write roots";throw new Error(`Path \`${t}\` is outside the allowed ${c} [${a}].`)}return s}function sy(t,e,n="read",r){return oy(t,e,n,r)}function iy(t){let e=new Set,n=[];for(let r of t.split(/\s+/)){if(r.length===0)continue;let o=r.replace(/^\d*[<>|&]+/,"").replace(/^['"]/,"").replace(/['";,)]+$/,"");if(o.length===0)continue;let s=o.startsWith("/"),i=o==="~"||o.startsWith("~/");!s&&!i||e.has(o)||(e.add(o),n.push(o))}return n}import{execFileSync as sO}from"node:child_process";function gn(t,e="SIGKILL"){if(!(t<=0))try{process.platform==="win32"?sO("taskkill",["/F","/T","/PID",String(t)],{stdio:"ignore",timeout:5e3}):process.kill(-t,e)}catch{}}P();import{mkdirSync as iO,openSync as aO,writeSync as cO,closeSync as lO}from"fs";var ay=8e6;function Fd(t,e,n){try{let r=Nl(t);if(r===void 0)return;iO(r,{recursive:!0,mode:448});let o=e.replace(/[^A-Za-z0-9_-]/g,"_").slice(0,128)||"capture",s=`${r}/${o}.txt`,i=Buffer.from(n,"utf8"),a=i.length<=ay?i:i.subarray(0,ay),c=aO(s,"wx",384);try{cO(c,a)}finally{lO(c)}return s}catch{return}}function uO(t){if(typeof t!="object"||t===null)throw new Error("Input must be an object");let e=t;if(typeof e.command!="string")throw new Error('Input must have a "command" field of type string');let n=12e4;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number")throw new Error("timeout_ms must be a number");if(e.timeout_ms<0||e.timeout_ms>6e5)throw new Error("timeout_ms must be between 0 and 600000");n=e.timeout_ms}return{command:e.command,timeout_ms:n}}function Ni(t,e){let n=!1,r=!1;function o(){n||t==="bypassPermissions"&&(n=!0,console.warn("[security] bash handler: shell=true with bypassPermissions \u2014 all shell metacharacters are interpreted without confirmation. Migrate to execFile to eliminate this risk (tracked: C4)."))}function s(i,a){if(r)return;let c=a.resolveBase??a.cwd??e,l=dO.homedir(),d=[];for(let u of iy(i)){let p=u==="~"?l:u.startsWith("~/")?l+u.slice(1):u,f=sy(p,a,"write",c);f.restricted&&d.push(f.resolved)}d.length!==0&&(r=!0,console.warn(`[security] bash: command references path(s) outside writeRoots: ${d.join(", ")} \u2014 bash containment is best-effort (tracked C4); use file tools for contained writes.`),Ee({event:"tool.bash_path_escape",tool:"bash",restricted_count:d.length,mode:"write"}))}return async(i,a,c)=>{let{command:l,timeout_ms:d}=uO(i);if(a.aborted)return{content:"Command aborted",isError:!0};if(o(),c!==void 0)try{s(l,c)}catch{}let u=Date.now();return new Promise(p=>{let f=!1;function m(S){f||(f=!0,clearTimeout(w),a.removeEventListener("abort",M),p(S))}let g=Qg(),h={detached:!0,stdio:["ignore","pipe","pipe"],...(c?.resolveBase??c?.cwd??e)!==void 0?{cwd:c?.resolveBase??c?.cwd??e}:{},...c?.env!==void 0?{env:{...process.env,...c.env}}:{}},y=g.shell===!0?cy(l,{shell:!0,...h}):cy(g.shell,[...g.args??[],l],h);y.unref(),c?.spawnedPidRegistry!==void 0&&y.pid!==void 0&&c.spawnedPidRegistry.register(y.pid);let w=setTimeout(()=>{y.pid!==void 0&&gn(y.pid),m({content:`Command timed out after ${d}ms`,isError:!0,durationMs:Date.now()-u})},d),k="",v="",_=0,R=!1;function A(S){if(R||f||_<8e6)return;R=!0,console.warn(`[bash] overflow kill: stream=${S} totalBytes=${_} command="${l}"`),Ee({event:"tool.overflow_kill",tool:"bash",total_bytes:_,stream:S}),y.kill("SIGKILL");let T=Ae((k+v).trimEnd()),E=wo(T)??void 0,O=st(T,1e5)+Kg;m({content:O,truncated:!0,durationMs:Date.now()-u,...E!==void 0?{testResult:E}:{}})}y.stdout.on("data",S=>{let T=8e6-_,E=S.length<=T?S:S.subarray(0,Math.max(0,T));_+=E.length,k+=E.toString("utf8"),A("stdout")}),y.stderr.on("data",S=>{let T=8e6-_,E=S.length<=T?S:S.subarray(0,Math.max(0,T));_+=E.length,v+=E.toString("utf8"),A("stderr")});let M=()=>{y.pid!==void 0&&gn(y.pid),m({content:"Command aborted",isError:!0,durationMs:Date.now()-u})};a.addEventListener("abort",M),a.aborted&&M(),y.on("close",S=>{if(a.aborted){m({content:"Command aborted",isError:!0,durationMs:Date.now()-u});return}if(S!==null&&S!==0){let L=v.trimEnd()||k.trimEnd(),D=Hn(L),N=Date.now()-u,W=D.truncated?Fd(c?.sessionId,c?.toolUseId??"",L):void 0;m({content:`Command exited with code ${S}${D.content?`
|
|
204
204
|
`+D.content:""}`,isError:!0,...D.truncated?{truncated:!0}:{},...W!==void 0?{capturePath:W}:{},durationMs:N,exitCode:S});return}if(R)return;let T=Ae((k+v).trimEnd()),E=wo(T)??void 0,O=Hn(T),K=Date.now()-u,F=O.truncated?Fd(c?.sessionId,c?.toolUseId??"",T):void 0;m({content:O.content,...O.truncated?{truncated:!0}:{},...F!==void 0?{capturePath:F}:{},durationMs:K,...S!==null?{exitCode:S}:{},...E!==void 0?{testResult:E}:{}})}),y.on("error",S=>{let T=c?.resolveBase??c?.cwd??e,E;if(T===void 0&&So(S))try{let O=process.cwd();E=Xn(S,O)}catch{E=`working directory does not exist (process cwd deleted \u2014 deleted worktree?) \u2014 underlying: ${S.message}`}else E=Xn(S,T);m({content:`Failed to execute: ${E}`,isError:!0,durationMs:Date.now()-u})})})}}var ly=Ni("default");import{promises as pO}from"fs";function We(t,e,n="Path"){if(!(t instanceof Error))return;let r=t.code;if(r==="ENOENT")return{content:`${n} not found: ${e}`,isError:!0};if(r==="EACCES")return{content:`Permission denied: ${e}`,isError:!0};if(r==="ENOTDIR")return{content:`Not a directory: ${e}`,isError:!0}}var fO=async(t,e,n,r)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected an object",isError:!0};let o=t,s=o.file_path,i=o.offset??1,a=o.limit??2e3;if(typeof s!="string")return{content:"Invalid input: file_path must be a string",isError:!0};if(typeof i!="number"||i<1)return{content:"Invalid input: offset must be a positive number",isError:!0};if(typeof a!="number"||a<1)return{content:"Invalid input: limit must be a positive number",isError:!0};let c;try{c=ee(s,n,"read",r)}catch(l){return{content:l instanceof Error?l.message:String(l),isError:!0}}try{let l=await pO.readFile(c),d=Math.min(8192,l.length);for(let k=0;k<d;k++)if(l[k]===0)return{content:`File appears to be binary: ${c}. Use extract_document for .docx, .pdf, .xlsx, .pptx, and .zip files.`,isError:!0};let u=l.toString("utf-8");if(u.length===0)return{content:""};let p=u.split(`
|
|
205
205
|
`),f=Math.max(0,i-1),m=Math.min(p.length,f+a),g=p.slice(f,m),h=p.length;if(g.length===0)return{content:`... (offset ${i} is past end of file \u2014 file has ${h} lines)`};let y=String(h).length,w=g.map((k,v)=>{let _=f+v+1;return`${String(_).padStart(y," ")} ${k}`}).join(`
|
|
206
206
|
`);if(g.length<h){let k=f+1,v=f+g.length,_=v<h?` \u2014 pass offset=${v+1} to continue`:"";return{content:`${w}
|
|
@@ -238,9 +238,9 @@ ${o.text}`)}return n.join(`
|
|
|
238
238
|
|
|
239
239
|
`;return g.toString("utf8")+w+h.toString("utf8")}return{push:d,totalBytes:()=>c,totalLines:()=>l,truncated:()=>s+a<c,render:u}}function ZO(t,e,n){if(typeof t!="object"||t===null)throw new Error("Input must be an object");let r=t;if(typeof r.pattern!="string")throw new Error('Input must have a "pattern" field of type string');let o=typeof r.path=="string"?r.path:e?.resolveBase??e?.cwd??n??process.cwd(),s=ee(o,e,"read"),i;if(r.include!==void 0){if(typeof r.include!="string")throw new Error("include must be a string");i=r.include}return{pattern:r.pattern,path:s,include:i}}function Wd(t,e){let n=e?.scanCapBytes??256e6;return async(r,o,s)=>{let{pattern:i,path:a,include:c}=ZO(r,s,t);if(o.aborted)return{content:"Search aborted",isError:!0};let l;try{({rgPath:l}=await import("@vscode/ripgrep"))}catch(d){return{content:`Failed to execute grep: ripgrep is unavailable \u2014 ${d instanceof Error?d.message:String(d)}`,isError:!0}}return new Promise(d=>{let u=!1;function p(_){u||(u=!0,o.removeEventListener("abort",v),d(_))}let f=["-n","--no-heading","--color=never","--hidden"];c&&f.push("-g",c);for(let _ of ty(a)){let R=_.split("/").map(A=>A.replace(/([*?\[\]{}\\])/g,"\\$1")).join("/");f.push("-g",`!${R}`,"-g",`!${R}/**`)}f.push("-g","!.git"),f.push("--",i,a);let m=s?.resolveBase??s?.cwd??t,g=QO(l,f,m!==void 0?{cwd:m}:{}),h=Hd(1e5),y=Hd(1e5),w=!1;function k(_){if(w||u)return;let R=h.totalBytes()+y.totalBytes();if(R<n)return;w=!0,console.warn(`[grep] overflow kill: stream=${_} totalBytes=${R} pattern=${i} path=${a}`),Ee({event:"tool.overflow_kill",tool:"grep",total_bytes:R,stream:_}),g.kill("SIGKILL");let A=h.totalBytes()===0&&y.totalBytes()>0?y.render():h.render();p({content:Ae(A.trimEnd())+_y(n),truncated:!0})}g.stdout.on("data",_=>{h.push(_),k("stdout")}),g.stderr.on("data",_=>{y.push(_),k("stderr")});let v=()=>{g.kill(),p({content:"Search aborted",isError:!0})};o.addEventListener("abort",v),g.on("close",_=>{if(w)return;if(_===1){let A=`No matches found for '${i}' in ${a}`;p({content:A});return}if(_===2){p(Ty(y.render(),a));return}let R=Ae(h.render().trimEnd());p({content:R,...h.truncated()?{truncated:!0}:{}})}),g.on("error",_=>{let R=vy(l);if(R!==void 0){p({content:`Failed to execute grep: ${R}`,isError:!0});return}let A;if(m===void 0&&So(_))try{A=Xn(_,process.cwd())}catch{A=`working directory does not exist (process cwd deleted \u2014 deleted worktree?) \u2014 underlying: ${_.message}`}else A=Xn(_,m);p({content:`Failed to execute grep: ${A}`,isError:!0})})})}}var Ey=Wd();import{promises as eD}from"fs";var Kd=500,tD=async(t,e,n,r)=>{if(!t||typeof t!="object")throw new Error("Invalid input: expected an object");let s=t.path;if(typeof s!="string")throw new Error("Invalid input: path must be a string");let i;try{i=ee(s,n,"read",r)}catch(a){return{content:a instanceof Error?a.message:String(a),isError:!0}}try{let a=await eD.readdir(i,{withFileTypes:!0}),c=a.filter(m=>m.isDirectory()).map(m=>`${m.name}/`),l=a.filter(m=>!m.isDirectory()).map(m=>m.name);c.sort(),l.sort();let d=[...c,...l];if(d.length===0)return{content:"(empty directory)"};let u=d.length,f=d.slice(0,Kd).join(`
|
|
240
240
|
`);return u>Kd&&(f+=`
|
|
241
|
-
[results capped at ${Kd} entries \u2014 ${u} total in directory]`),{content:f}}catch(a){let c=We(a,i,"Directory");return c||(a instanceof Error?{content:`Error listing directory: ${a.message}`,isError:!0}:{content:"Unknown error listing directory",isError:!0})}};function qd(t){return(e,n,r)=>tD(e,n,r,t)}var Ay=qd();I();function Eo(t,e=()=>{}){let n=new Set;if(!t)return n;for(let r of t.split(",")){let o=r.trim();if(o){if(!/^-?\d+$/.test(o)){e("[allowlist] Ignoring non-numeric chat ID:",o);continue}n.add(Number(o))}}return n}function xy(t,e){return e.has(t)}function Gd(t,e=()=>{}){return async(n,r)=>{let o=n.chat?.id;if(o===void 0||!t.has(o)){e("[allowlist] Rejecting update from chat:",o??"<unknown>");return}await r()}}import{config as
|
|
241
|
+
[results capped at ${Kd} entries \u2014 ${u} total in directory]`),{content:f}}catch(a){let c=We(a,i,"Directory");return c||(a instanceof Error?{content:`Error listing directory: ${a.message}`,isError:!0}:{content:"Unknown error listing directory",isError:!0})}};function qd(t){return(e,n,r)=>tD(e,n,r,t)}var Ay=qd();I();function Eo(t,e=()=>{}){let n=new Set;if(!t)return n;for(let r of t.split(",")){let o=r.trim();if(o){if(!/^-?\d+$/.test(o)){e("[allowlist] Ignoring non-numeric chat ID:",o);continue}n.add(Number(o))}}return n}function xy(t,e){return e.has(t)}function Gd(t,e=()=>{}){return async(n,r)=>{let o=n.chat?.id;if(o===void 0||!t.has(o)){e("[allowlist] Rejecting update from chat:",o??"<unknown>");return}await r()}}import{config as E6,parse as A6}from"dotenv";P();import{execFileSync as Ry}from"child_process";import{existsSync as nD,readFileSync as rD,writeFileSync as oD}from"fs";import{homedir as Iy,userInfo as Cy}from"os";import{join as Py}from"path";var sD="9d1c250a-e61b-44d9-88ed-5944d1962f5e",iD="https://platform.claude.com/v1/oauth/token",aD=300*1e3,cD=1e4;function xe(){let t=My();if(t===void 0)return;let e=Oy(t);if(e!==void 0){if(e.expiresAt!==void 0&&e.expiresAt<=Date.now()){process.stderr.write("agent-afk: Claude Code OAuth token in keychain is expired. Run `claude login` to refresh.\n");return}return e.accessToken}}async function Bi(){let t=My();if(t===void 0)return;let e=Oy(t);if(e===void 0)return;if(e.expiresAt!==void 0&&e.expiresAt>Date.now()+aD)return e.accessToken;if(!e.refreshToken){process.stderr.write("agent-afk: OAuth token expired and no refresh token available. Run `claude login` to refresh.\n");return}let n=await lD(e.refreshToken);if(!n){process.stderr.write("agent-afk: OAuth token refresh failed. Run `claude login` to refresh.\n");return}try{let r={};try{r=JSON.parse(t)}catch{}let o=r.claudeAiOauth??{};r.claudeAiOauth={...o,accessToken:n.accessToken,expiresAt:n.expiresAt,...n.refreshToken!==void 0?{refreshToken:n.refreshToken}:{}},dD(JSON.stringify(r))}catch{process.stderr.write(`agent-afk: Refreshed OAuth token but failed to write back to credential store.
|
|
242
242
|
`)}return n.accessToken}function My(){if(process.platform==="darwin")try{return Ry("security",["find-generic-password","-s","Claude Code-credentials","-a",Cy().username,"-w"],{stdio:["ignore","pipe","ignore"],encoding:"utf-8"}).trim()}catch{return}if(process.platform==="linux"){let t=Py(Iy(),".claude",".credentials.json");if(!nD(t))return;try{return rD(t,"utf-8")}catch{return}}}function Oy(t){let e;try{e=JSON.parse(t)}catch{return}if(typeof e!="object"||e===null)return;let n=e.claudeAiOauth;if(typeof n!="object"||n===null)return;let r=n,o=r.accessToken;if(typeof o!="string"||o.length===0)return;let s={accessToken:o},i=r.refreshToken;typeof i=="string"&&i.length>0&&(s.refreshToken=i);let a=r.expiresAt;return typeof a=="number"&&(s.expiresAt=a),s}async function lD(t){try{let e=await fetch(iD,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:t,client_id:sD}),signal:AbortSignal.timeout(cD)});if(!e.ok)return;let n=await e.json(),r=n.access_token,o=n.expires_in;if(typeof r!="string"||typeof o!="number")return;let s=n.refresh_token;return{accessToken:r,expiresAt:Date.now()+o*1e3,...typeof s=="string"&&s.length>0?{refreshToken:s}:{}}}catch{return}}function er(t){if(!t||t.length<3)return"token:(unknown)";try{let n=t.split(".");if(n.length<2)throw new Error("not a JWT");let r=Buffer.from(n[1],"base64url").toString("utf-8"),o=JSON.parse(r),s=typeof o.email=="string"&&o.email||typeof o.sub=="string"&&o.sub||typeof o.account_id=="string"&&o.account_id||typeof o.preferred_username=="string"&&o.preferred_username;if(s)return s}catch{}return`token:${t.length>=8?t.slice(-8):t}`}function dD(t){if(process.platform==="darwin")Ry("security",["add-generic-password","-U","-s","Claude Code-credentials","-a",Cy().username,"-w",t],{stdio:["ignore","ignore","ignore"]});else if(process.platform==="linux"){let e=Py(Iy(),".claude",".credentials.json");uD(e,t)}}function uD(t,e){oD(t,e,{encoding:"utf-8",mode:384})}I();var pD;function ji(){return b.ANTHROPIC_API_KEY||b.CLAUDE_CODE_OAUTH_TOKEN||pD||xe()}function Xd(){return b.OPENAI_API_KEY||b.CODEX_API_KEY||void 0}function fD(){let t=b.XAI_API_KEY;return t&&t.length>0?t:void 0}function se(t,e){let n=z(t,e);return n==="openai-compatible"||n==="openai-codex"?Xd():n==="xai"||n==="xai-oauth"?fD():ji()}I();P();import{join as mD}from"path";function Dy(){return[{tier:"project",path:mD(process.cwd(),"afk.config.json")},{tier:"user",path:On()},{tier:"legacy",path:Gs()}]}import{readFileSync as zD,existsSync as JD}from"fs";I();import{execFile as WD}from"node:child_process";import{promisify as KD}from"node:util";I();P();I();import{stat as TD}from"node:fs/promises";import{join as _D}from"node:path";var gD=[/\.env$/,/^\.env\./,/\.pem$/,/\.key$/,/\.p12$/,/\.keystore$/,/\.jks$/,/^id_rsa/,/^id_ed25519/,/^\.netrc$/,/\.sqlite3?$/,/\.db$/],hD=[/credential/,/secret/],yD=/\.(?:js|mjs|cjs|jsx|ts|tsx|mts|cts|map|html?|css|svg)$/,Ly=[/(?:^|\/)node_modules\//,/(?:^|\/)\.pnpm(-store)?\//,/(?:^|\/)\.yarn\//,/(?:^|\/)bower_components\//,/(?:^|\/)vendor\/bundle\//,/(?:^|\/)\.venv\//,/(?:^|\/)venv\//,/(?:^|\/)__pycache__\//,/(?:^|\/)\.turbo\//,/(?:^|\/)\.parcel-cache\//,/(?:^|\/)\.vite\//,/(?:^|\/)\.cache\//,/(?:^|\/)\.gradle\//,/(?:^|\/)\.pytest_cache\//,/(?:^|\/)\.mypy_cache\//,/(?:^|\/)\.ruff_cache\//,/(?:^|\/)\.nyc_output\//],Ny=[/(?:^|\/)dist\//,/(?:^|\/)build\//,/(?:^|\/)out\//,/(?:^|\/)lib-cov\//,/(?:^|\/)\.next\//,/(?:^|\/)\.nuxt\//,/(?:^|\/)\.svelte-kit\//,/(?:^|\/)\.output\//,/(?:^|\/)target\//,/(?:^|\/)coverage\//,/(?:^|\/)logs\//],bD=[/^\.afk-worktree-meta\.json$/,/\.tsbuildinfo$/,/^\.eslintcache$/,/^\.stylelintcache$/,/^\.DS_Store$/,/^debug\.log$/,/^npm-debug\.log$/,/^yarn-error\.log$/,/^yarn-debug\.log$/,/^pnpm-debug\.log$/,/^lerna-debug\.log$/];function wD(t){let e=t.replace(/\\/g,"/").replace(/^\.\//,"");return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e}function Fy(t){let e=t.replace(/\/+$/,""),n=e.lastIndexOf("/");return n===-1?e:e.slice(n+1)}var SD=[/(?:^|\/)logs\//];function kD(t,e){return!yD.test(e)||SD.some(n=>n.test(t))?!1:Ly.some(n=>n.test(t))||Ny.some(n=>n.test(t))}function vD(t){return gD.some(e=>e.test(t))}function $t(t){let e=wD(t);if(e==="")return"protected";let n=Fy(e).toLowerCase();return vD(n)||!kD(e,n)&&hD.some(o=>o.test(n))?"protected":!e.endsWith("/")&&bD.some(o=>o.test(Fy(e)))||Ly.some(o=>o.test(e))?"opaque":Ny.some(o=>o.test(e))?"inspectable":"protected"}var ED=["-c","core.quotePath=false"],AD={maxBuffer:64*1024*1024,timeout:1e4};async function Uy(t,e){let n=$t(e);if(n!=="protected"||e.endsWith("/"))return{verdict:n,resolvedEntry:e};try{if((await TD(_D(t,e))).isDirectory()){let o=`${e}/`;return{verdict:$t(o),resolvedEntry:o}}}catch{}return{verdict:n,resolvedEntry:e}}async function $y(t,e,n){let r=[...ED,"-C",e,"status","--porcelain","--ignored"];n!==void 0&&r.push("--untracked-files=all","--",n);try{let{stdout:o}=await t("git",r,AD);return{entries:o.split(`
|
|
243
|
-
`).filter(s=>s.startsWith("!!")).map(s=>s.slice(2).trim()).filter(s=>s!=="")}}catch(o){let s=o instanceof Error?o.message:String(o);return{failure:n===void 0?s:`expanding ${n}: ${s}`}}}async function xD(t,e,n){let r=await $y(t,e,n);if("failure"in r)return{protect:!0,because:"git-failed",detail:r.failure};for(let o of r.entries){if(o===n)continue;let{verdict:s}=await Uy(e,o);if(s==="protected")return{protect:!0,because:"non-rebuildable-entry",detail:o}}return{protect:!1}}async function Hi(t,e){let n=await $y(t,e);if("failure"in n)return{protect:!0,because:"git-failed",detail:n.failure};for(let r of n.entries){let{verdict:o,resolvedEntry:s}=await Uy(e,r);if(o==="protected")return{protect:!0,because:"non-rebuildable-entry",detail:r};if(o==="inspectable"&&s.endsWith("/")){let i=await xD(t,e,s);if(i.protect)return i}}return{protect:!1}}async function By(t,e){return(await Hi(t,e)).protect}P();J();import{promises as it}from"node:fs";import{setTimeout as CD}from"node:timers/promises";import{dirname as Wy,isAbsolute as PD,resolve as MD}from"node:path";J();import{promises as RD}from"node:fs";import{resolve as ID}from"node:path";async function jy(t){let e=ID(t);try{return await RD.realpath(e)}catch{return e}}var Ky=1,Wi=64,qy=384,Gy=448,OD=2e3,DD=25;function FD(t){try{let e=JSON.parse(t);return e.version!==Ky?[]:Array.isArray(e.roots)?e.roots.filter(n=>typeof n=="object"&&n!==null&&typeof n.path=="string"&&n.path.length>0&&PD(n.path)):[]}catch{return[]}}async function LD(){try{return FD(await it.readFile(qs(),"utf-8"))}catch{return[]}}var Hy=Promise.resolve();function ND(t){let e=Hy.then(t,t).catch(()=>{});return Hy=e,e}async function UD(t){try{let e=Number.parseInt((await it.readFile(t,"utf-8")).trim(),10);if(Number.isInteger(e)&&e>0){process.kill(e,0);return}}catch{}await it.unlink(t).catch(()=>{})}async function $D(t){let e=Date.now()+OD;for(;;)try{let n=await it.open(t,"wx",qy);return await n.writeFile(String(process.pid),"utf-8"),await n.close(),async()=>{await it.unlink(t).catch(()=>{})}}catch(n){if(n.code!=="EEXIST"||Date.now()>=e)return null;await UD(t),await CD(DD)}}async function BD(t){let e=qs();await it.mkdir(Wy(e),{recursive:!0,mode:Gy});let n={version:Ky,roots:t},r=`${e}.tmp-${process.pid}-${Date.now()}`;try{await it.writeFile(r,JSON.stringify(n,null,2),{encoding:"utf-8",mode:qy}),await it.rename(r,e)}catch(o){throw await it.rm(r,{force:!0}).catch(()=>{}),o}}async function jD(t){await ND(async()=>{let e=qs();await it.mkdir(Wy(e),{recursive:!0,mode:Gy}).catch(()=>{});let n=await $D(`${e}.lock`);try{await BD(t(await LD()))}catch{}finally{n!==null&&await n()}})}function HD(t){if(t.length<=Wi)return t;t=[...t].sort((n,r)=>n.lastSeenAt.localeCompare(r.lastSeenAt));let e=t.slice(0,t.length-Wi);return C(`[worktree-root-registry] cap ${Wi} reached \u2014 evicting ${e.length} least-recently-seen root(s); their managed worktrees will no longer be swept: `+e.map(n=>n.path).join(", ")),t.slice(-Wi)}async function zd(t){if(t==="")return;let e=await jy(t),n=new Date().toISOString();await jD(r=>{let o=r.filter(s=>MD(s.path)!==e);return HD([...o,{path:e,lastSeenAt:n}])})}var w8=KD(WD);var qD=/^[A-Za-z0-9_\-./]*$/,Xy=64;function zy(t,e){if(t.length>Xy)throw new Error(`Invalid branch prefix from ${e}: length ${t.length} exceeds ${Xy}.`);if(!qD.test(t))throw new Error(`Invalid branch prefix from ${e}: '${t}' \u2014 only [A-Za-z0-9_-./] are allowed.`);if(t.startsWith("-"))throw new Error(`Invalid branch prefix from ${e}: '${t}' \u2014 must not start with '-' (would be parsed by git as a flag).`);return t}function Jy(t,e){if(t.trim().length===0)throw new Error(`Invalid worktree base ref from ${e}: '' \u2014 base ref cannot be empty.`);if(t.startsWith("-"))throw new Error(`Invalid worktree base ref from ${e}: '${t}' \u2014 must not start with '-' (would be parsed by git as a flag).`);if(t.includes("\0"))throw new Error(`Invalid worktree base ref from ${e}: contains a NUL byte.`);if(/\s/.test(t))throw new Error(`Invalid worktree base ref from ${e}: '${t}' \u2014 must not contain whitespace.`)}P();import{existsSync as xo,readdirSync as v8,readFileSync as Vy,realpathSync as T8,statSync as _8}from"fs";import{homedir as Yy}from"os";import{join as St,basename as x8}from"path";var Qy=["claude-code","codex"],Ao=new Map,Ki={"claude-code":{label:"Claude Code",pluginRoots:t=>[St(t,".claude","plugins")],skillRoots:t=>[St(t,".claude","skills")],mcpConfigCandidates:t=>[St(t,".claude","mcp.json"),St(t,".claude",".mcp.json"),St(t,".claude","claude-code","mcp.json")],mcpFormat:"json",pluginEnabledState:t=>XD(t)},codex:{label:"Codex",pluginRoots:t=>[St(t,".codex","plugins")],skillRoots:t=>[St(t,".codex","skills")],mcpConfigCandidates:t=>[St(t,".codex","config.toml")],mcpFormat:"toml",pluginEnabledState:()=>Ao}},I8={"claude-code":Ki["claude-code"].label,codex:Ki.codex.label};function Jd(t){if(t===null||typeof t!="object"||Array.isArray(t))return;let e={};for(let n of Qy){let r=t[n];if(r!==void 0){if(r===!0){e[n]={plugins:!0,skills:!0,mcp:!0};continue}if(r!==!1&&typeof r=="object"&&r!==null&&!Array.isArray(r)){let o=r;e[n]={plugins:o.plugins===!0,skills:o.skills===!0,mcp:o.mcp===!0}}}}return Object.keys(e).length>0?e:void 0}function Vd(){return[On(),Gs()]}function Yd(t=Vd()){for(let e of t)if(xo(e))try{let n=JSON.parse(Vy(e,"utf-8")),r=Jd(n.importFrom);if(r!==void 0)return r}catch{}}function Qd(t,e=Yy()){let n={pluginRoots:[],skillRoots:[],mcpConfigs:[]};if(!t)return n;for(let r of Qy){let o=t[r];if(!o)continue;let s=Ki[r];if(o.plugins)for(let i of s.pluginRoots(e))xo(i)&&n.pluginRoots.push({dir:i,binary:r});if(o.skills){let i=`imported:${r}`;for(let a of s.skillRoots(e))xo(a)&&n.skillRoots.push({dir:a,origin:i})}if(o.mcp){let i=GD(s.mcpConfigCandidates(e));i&&n.mcpConfigs.push({source:i,format:s.mcpFormat})}}return n}function Zy(t,e=Yy()){return Ki[t].pluginEnabledState(e)}function GD(t){for(let e of t)if(xo(e))return e;return null}function XD(t){let e=St(t,".claude","settings.json");if(!xo(e))return Ao;let n;try{n=JSON.parse(Vy(e,"utf-8"))}catch{return Ao}if(!n||typeof n!="object")return Ao;let r=n.enabledPlugins;if(!r||typeof r!="object"||Array.isArray(r))return Ao;let o=new Map;for(let[s,i]of Object.entries(r))typeof i=="boolean"&&o.set(s,i);return o}function eb(t){if(!JD(t))return;let e=zD(t,"utf-8"),n=JSON.parse(e),r={},o=ag(n.models);if(typeof n.model=="string"&&n.model.length>0){let s=n.model.toLowerCase();r.model=ti(s)?s:n.model}if(typeof n.maxTokens=="number"&&(r.maxTokens=n.maxTokens),typeof n.temperature=="number"&&(r.temperature=n.temperature),typeof n.systemPrompt=="string"&&n.systemPrompt.length>0&&(r.systemPrompt=n.systemPrompt),typeof n.permissionMode=="string"){let s=n.permissionMode;(s==="default"||s==="plan"||s==="autonomous"||s==="bypassPermissions")&&(r.permissionMode=s)}if(n.autoRouting&&typeof n.autoRouting=="object"){let s={};typeof n.autoRouting.interactive=="boolean"&&(s.interactive=n.autoRouting.interactive),typeof n.autoRouting.chat=="boolean"&&(s.chat=n.autoRouting.chat),typeof n.autoRouting.telegram=="boolean"&&(s.telegram=n.autoRouting.telegram),typeof n.autoRouting.daemon=="boolean"&&(s.daemon=n.autoRouting.daemon),r.autoRouting=s}if(n.daemon&&typeof n.daemon=="object"){let s={};typeof n.daemon.task=="string"&&(s.task=n.daemon.task),typeof n.daemon.taskId=="string"&&(s.taskId=n.daemon.taskId);let i=n.daemon.worktreePrune;i&&typeof i=="object"&&(s.worktreePrune={enabled:typeof i.enabled=="boolean"?i.enabled:!0,cron:typeof i.cron=="string"?i.cron:"0 4 * * *",maxAgeDaysClean:typeof i.maxAgeDaysClean=="number"?i.maxAgeDaysClean:14,maxAgeDaysDirty:typeof i.maxAgeDaysDirty=="number"?i.maxAgeDaysDirty:30,scope:typeof i.scope=="string"?i.scope:"all"}),typeof n.daemon.verifyDone=="boolean"&&(s.verifyDone=n.daemon.verifyDone),r.daemon=s}if(n.telegram&&typeof n.telegram=="object"){let s={},i=n.telegram.notify;if(i&&typeof i=="object"){let a={};if((i.mode==="primary"||i.mode==="broadcast"||i.mode==="custom")&&(a.mode=i.mode),typeof i.primaryChatId=="number"&&Number.isFinite(i.primaryChatId)&&(a.primaryChatId=i.primaryChatId),Array.isArray(i.targets)){let c=i.targets.filter(l=>typeof l=="number"&&Number.isFinite(l));c.length>0&&(a.targets=c)}s.notify=a}if(typeof n.telegram.verifyDone=="boolean"&&(s.verifyDone=n.telegram.verifyDone),Array.isArray(n.telegram.tagOnlyChats)){let a=n.telegram.tagOnlyChats.filter(c=>typeof c=="number"&&Number.isFinite(c));a.length>0&&(s.tagOnlyChats=a)}if(n.telegram.chatAliases&&typeof n.telegram.chatAliases=="object"&&!Array.isArray(n.telegram.chatAliases)){let a={};for(let[c,l]of Object.entries(n.telegram.chatAliases))typeof l=="number"&&Number.isFinite(l)&&l!==0&&(a[c]=l);Object.keys(a).length>0&&(s.chatAliases=a)}r.telegram=s}if(n.updatePolicy&&["notify","auto","off"].includes(n.updatePolicy)&&(r.updatePolicy=n.updatePolicy),n.theme&&["dark","light","umber","auto"].includes(n.theme)&&(r.theme=n.theme),typeof n.autoResumeOnUsageLimit=="boolean"&&(r.autoResumeOnUsageLimit=n.autoResumeOnUsageLimit),typeof n.enforceDoneEvidence=="boolean"&&(r.enforceDoneEvidence=n.enforceDoneEvidence),typeof n.bgSummaries=="boolean"&&(r.bgSummaries=n.bgSummaries),typeof n.maxSummaryCallsPerSession=="number"&&(r.maxSummaryCallsPerSession=Math.min(500,Math.max(1,n.maxSummaryCallsPerSession))),n.hooks!==null&&typeof n.hooks=="object"&&!Array.isArray(n.hooks)&&(r.hooks=n.hooks),typeof n.enableShellHooks=="boolean"&&(r.enableShellHooks=n.enableShellHooks),typeof n.enablePluginHooks=="boolean"&&(r.enablePluginHooks=n.enablePluginHooks),Vd().includes(t)){let s=Jd(n.importFrom);s!==void 0&&(r.importFrom=s)}if(n.interactive&&typeof n.interactive=="object"){let s={};typeof n.interactive.worktreeAutoname=="boolean"&&(s.worktreeAutoname=n.interactive.worktreeAutoname),typeof n.interactive.worktreeBranchPrefix=="string"&&(s.worktreeBranchPrefix=zy(n.interactive.worktreeBranchPrefix,`${t}#/interactive/worktreeBranchPrefix`)),typeof n.interactive.worktreeBase=="string"&&n.interactive.worktreeBase.trim().length>0&&(Jy(n.interactive.worktreeBase,`${t}#/interactive/worktreeBase`),s.worktreeBase=n.interactive.worktreeBase),(n.interactive.worktreeOnExit==="ask"||n.interactive.worktreeOnExit==="keep"||n.interactive.worktreeOnExit==="remove")&&(s.worktreeOnExit=n.interactive.worktreeOnExit),typeof n.interactive.suggestGhost=="boolean"&&(s.suggestGhost=n.interactive.suggestGhost),(n.interactive.thinkingUi==="summary"||n.interactive.thinkingUi==="live"||n.interactive.thinkingUi==="digest"||n.interactive.thinkingUi==="off")&&(s.thinkingUi=n.interactive.thinkingUi),Object.keys(s).length>0&&(r.interactive=s)}return{config:r,modelsPartial:o}}var qi;function tb(){if(qi!==void 0)return qi;let t=Dy().map(r=>r.path),e=!1;for(let r of t){let o;try{o=eb(r)}catch(i){console.error(`Warning: Failed to parse ${r}:`,i),e=!0;continue}if(o===void 0)continue;let s={...o,sourcePath:r};return e||(qi=s),s}let n={config:{},sourcePath:void 0,modelsPartial:{}};return e||(qi=n),n}P();function Zd(){return tb().config.telegram??{}}I();var nb=!1;function YD(t,e){return e!==void 0&&Number.isFinite(e)&&e!==0?e:t.find(r=>r>0)??t[0]}function QD(t,e){if(nb||e!==void 0&&Number.isFinite(e)&&e!==0)return;let n=t.some(o=>o>0),r=t.some(o=>o<0);n&&r&&(nb=!0,console.warn("[telegram] AFK_TELEGRAM_ALLOWED_CHAT_IDS contains both a DM and a group chat. Notifications will go to the DM (positive-id chat) by default. Set AFK_TELEGRAM_PRIMARY_CHAT_ID to route notifications to a different chat."))}function ZD(t,e={}){let n=[...t],r=e.mode??"primary";if(r==="broadcast")return n;if(r==="custom"){let s=(e.targets??[]).filter(i=>typeof i=="number"&&Number.isFinite(i)&&i!==0);if(s.length>0)return[...new Set(s)]}QD(n,e.primaryChatId);let o=YD(n,e.primaryChatId);return o!==void 0?[o]:[]}function rb(t,e={}){if(typeof t=="number")return!Number.isFinite(t)||t===0?{ok:!1,reason:"invalid",message:`Invalid chat id: ${t}`}:{ok:!0,id:t};let n=t.trim();if(n.length===0)return{ok:!1,reason:"invalid",message:"Invalid chat: empty string"};let r=ob(n);if(r!==void 0)return{ok:!0,id:r};let o=Object.keys(e),s=Object.prototype.hasOwnProperty.call(e,n)?e[n]:void 0;if(s!==void 0&&Number.isFinite(s)&&s!==0)return{ok:!0,id:s};let i=o.length>0?`Available aliases: ${o.join(", ")}.`:"No chat aliases are configured (set telegram.chatAliases in afk.config.json).";return{ok:!1,reason:"unknown-alias",message:`Unknown chat alias "${n}". ${i}`}}function ob(t){if(!t)return;let e=t.trim();if(!/^-?\d+$/.test(e))return;let n=Number(e);return Number.isFinite(n)&&n!==0?n:void 0}function eF(t){if(!t)return;let e=t.trim().toLowerCase();return e==="primary"||e==="broadcast"||e==="custom"?e:void 0}function tF(){let t=Zd().notify??{},e=t.mode??eF(b.AFK_TELEGRAM_NOTIFY_MODE),n=t.primaryChatId??ob(b.AFK_TELEGRAM_PRIMARY_CHAT_ID);return{...e!==void 0?{mode:e}:{},...n!==void 0?{primaryChatId:n}:{},...t.targets!==void 0?{targets:t.targets}:{}}}function Gi(){let t=Eo(b.AFK_TELEGRAM_ALLOWED_CHAT_IDS);return ZD(t,tF())}function sb(){return Zd().chatAliases??{}}function Se(t,e=4096){if(t.length<=e)return[t];let n=[],r=t;for(;r.length>0;){if(r.length<=e){n.push(r);break}let o=e,s=r.lastIndexOf(`
|
|
243
|
+
`).filter(s=>s.startsWith("!!")).map(s=>s.slice(2).trim()).filter(s=>s!=="")}}catch(o){let s=o instanceof Error?o.message:String(o);return{failure:n===void 0?s:`expanding ${n}: ${s}`}}}async function xD(t,e,n){let r=await $y(t,e,n);if("failure"in r)return{protect:!0,because:"git-failed",detail:r.failure};for(let o of r.entries){if(o===n)continue;let{verdict:s}=await Uy(e,o);if(s==="protected")return{protect:!0,because:"non-rebuildable-entry",detail:o}}return{protect:!1}}async function Hi(t,e){let n=await $y(t,e);if("failure"in n)return{protect:!0,because:"git-failed",detail:n.failure};for(let r of n.entries){let{verdict:o,resolvedEntry:s}=await Uy(e,r);if(o==="protected")return{protect:!0,because:"non-rebuildable-entry",detail:r};if(o==="inspectable"&&s.endsWith("/")){let i=await xD(t,e,s);if(i.protect)return i}}return{protect:!1}}async function By(t,e){return(await Hi(t,e)).protect}P();J();import{promises as it}from"node:fs";import{setTimeout as CD}from"node:timers/promises";import{dirname as Wy,isAbsolute as PD,resolve as MD}from"node:path";J();import{promises as RD}from"node:fs";import{resolve as ID}from"node:path";async function jy(t){let e=ID(t);try{return await RD.realpath(e)}catch{return e}}var Ky=1,Wi=64,qy=384,Gy=448,OD=2e3,DD=25;function FD(t){try{let e=JSON.parse(t);return e.version!==Ky?[]:Array.isArray(e.roots)?e.roots.filter(n=>typeof n=="object"&&n!==null&&typeof n.path=="string"&&n.path.length>0&&PD(n.path)):[]}catch{return[]}}async function LD(){try{return FD(await it.readFile(qs(),"utf-8"))}catch{return[]}}var Hy=Promise.resolve();function ND(t){let e=Hy.then(t,t).catch(()=>{});return Hy=e,e}async function UD(t){try{let e=Number.parseInt((await it.readFile(t,"utf-8")).trim(),10);if(Number.isInteger(e)&&e>0){process.kill(e,0);return}}catch{}await it.unlink(t).catch(()=>{})}async function $D(t){let e=Date.now()+OD;for(;;)try{let n=await it.open(t,"wx",qy);return await n.writeFile(String(process.pid),"utf-8"),await n.close(),async()=>{await it.unlink(t).catch(()=>{})}}catch(n){if(n.code!=="EEXIST"||Date.now()>=e)return null;await UD(t),await CD(DD)}}async function BD(t){let e=qs();await it.mkdir(Wy(e),{recursive:!0,mode:Gy});let n={version:Ky,roots:t},r=`${e}.tmp-${process.pid}-${Date.now()}`;try{await it.writeFile(r,JSON.stringify(n,null,2),{encoding:"utf-8",mode:qy}),await it.rename(r,e)}catch(o){throw await it.rm(r,{force:!0}).catch(()=>{}),o}}async function jD(t){await ND(async()=>{let e=qs();await it.mkdir(Wy(e),{recursive:!0,mode:Gy}).catch(()=>{});let n=await $D(`${e}.lock`);try{await BD(t(await LD()))}catch{}finally{n!==null&&await n()}})}function HD(t){if(t.length<=Wi)return t;t=[...t].sort((n,r)=>n.lastSeenAt.localeCompare(r.lastSeenAt));let e=t.slice(0,t.length-Wi);return C(`[worktree-root-registry] cap ${Wi} reached \u2014 evicting ${e.length} least-recently-seen root(s); their managed worktrees will no longer be swept: `+e.map(n=>n.path).join(", ")),t.slice(-Wi)}async function zd(t){if(t==="")return;let e=await jy(t),n=new Date().toISOString();await jD(r=>{let o=r.filter(s=>MD(s.path)!==e);return HD([...o,{path:e,lastSeenAt:n}])})}var S8=KD(WD);var qD=/^[A-Za-z0-9_\-./]*$/,Xy=64;function zy(t,e){if(t.length>Xy)throw new Error(`Invalid branch prefix from ${e}: length ${t.length} exceeds ${Xy}.`);if(!qD.test(t))throw new Error(`Invalid branch prefix from ${e}: '${t}' \u2014 only [A-Za-z0-9_-./] are allowed.`);if(t.startsWith("-"))throw new Error(`Invalid branch prefix from ${e}: '${t}' \u2014 must not start with '-' (would be parsed by git as a flag).`);return t}function Jy(t,e){if(t.trim().length===0)throw new Error(`Invalid worktree base ref from ${e}: '' \u2014 base ref cannot be empty.`);if(t.startsWith("-"))throw new Error(`Invalid worktree base ref from ${e}: '${t}' \u2014 must not start with '-' (would be parsed by git as a flag).`);if(t.includes("\0"))throw new Error(`Invalid worktree base ref from ${e}: contains a NUL byte.`);if(/\s/.test(t))throw new Error(`Invalid worktree base ref from ${e}: '${t}' \u2014 must not contain whitespace.`)}P();import{existsSync as xo,readdirSync as T8,readFileSync as Vy,realpathSync as _8,statSync as E8}from"fs";import{homedir as Yy}from"os";import{join as St,basename as R8}from"path";var Qy=["claude-code","codex"],Ao=new Map,Ki={"claude-code":{label:"Claude Code",pluginRoots:t=>[St(t,".claude","plugins")],skillRoots:t=>[St(t,".claude","skills")],mcpConfigCandidates:t=>[St(t,".claude","mcp.json"),St(t,".claude",".mcp.json"),St(t,".claude","claude-code","mcp.json")],mcpFormat:"json",pluginEnabledState:t=>XD(t)},codex:{label:"Codex",pluginRoots:t=>[St(t,".codex","plugins")],skillRoots:t=>[St(t,".codex","skills")],mcpConfigCandidates:t=>[St(t,".codex","config.toml")],mcpFormat:"toml",pluginEnabledState:()=>Ao}},C8={"claude-code":Ki["claude-code"].label,codex:Ki.codex.label};function Jd(t){if(t===null||typeof t!="object"||Array.isArray(t))return;let e={};for(let n of Qy){let r=t[n];if(r!==void 0){if(r===!0){e[n]={plugins:!0,skills:!0,mcp:!0};continue}if(r!==!1&&typeof r=="object"&&r!==null&&!Array.isArray(r)){let o=r;e[n]={plugins:o.plugins===!0,skills:o.skills===!0,mcp:o.mcp===!0}}}}return Object.keys(e).length>0?e:void 0}function Vd(){return[On(),Gs()]}function Yd(t=Vd()){for(let e of t)if(xo(e))try{let n=JSON.parse(Vy(e,"utf-8")),r=Jd(n.importFrom);if(r!==void 0)return r}catch{}}function Qd(t,e=Yy()){let n={pluginRoots:[],skillRoots:[],mcpConfigs:[]};if(!t)return n;for(let r of Qy){let o=t[r];if(!o)continue;let s=Ki[r];if(o.plugins)for(let i of s.pluginRoots(e))xo(i)&&n.pluginRoots.push({dir:i,binary:r});if(o.skills){let i=`imported:${r}`;for(let a of s.skillRoots(e))xo(a)&&n.skillRoots.push({dir:a,origin:i})}if(o.mcp){let i=GD(s.mcpConfigCandidates(e));i&&n.mcpConfigs.push({source:i,format:s.mcpFormat})}}return n}function Zy(t,e=Yy()){return Ki[t].pluginEnabledState(e)}function GD(t){for(let e of t)if(xo(e))return e;return null}function XD(t){let e=St(t,".claude","settings.json");if(!xo(e))return Ao;let n;try{n=JSON.parse(Vy(e,"utf-8"))}catch{return Ao}if(!n||typeof n!="object")return Ao;let r=n.enabledPlugins;if(!r||typeof r!="object"||Array.isArray(r))return Ao;let o=new Map;for(let[s,i]of Object.entries(r))typeof i=="boolean"&&o.set(s,i);return o}function eb(t){if(!JD(t))return;let e=zD(t,"utf-8"),n=JSON.parse(e),r={},o=ag(n.models);if(typeof n.model=="string"&&n.model.length>0){let s=n.model.toLowerCase();r.model=ti(s)?s:n.model}if(typeof n.maxTokens=="number"&&(r.maxTokens=n.maxTokens),typeof n.temperature=="number"&&(r.temperature=n.temperature),typeof n.systemPrompt=="string"&&n.systemPrompt.length>0&&(r.systemPrompt=n.systemPrompt),typeof n.permissionMode=="string"){let s=n.permissionMode;(s==="default"||s==="plan"||s==="autonomous"||s==="bypassPermissions")&&(r.permissionMode=s)}if(n.autoRouting&&typeof n.autoRouting=="object"){let s={};typeof n.autoRouting.interactive=="boolean"&&(s.interactive=n.autoRouting.interactive),typeof n.autoRouting.chat=="boolean"&&(s.chat=n.autoRouting.chat),typeof n.autoRouting.telegram=="boolean"&&(s.telegram=n.autoRouting.telegram),typeof n.autoRouting.daemon=="boolean"&&(s.daemon=n.autoRouting.daemon),r.autoRouting=s}if(n.daemon&&typeof n.daemon=="object"){let s={};typeof n.daemon.task=="string"&&(s.task=n.daemon.task),typeof n.daemon.taskId=="string"&&(s.taskId=n.daemon.taskId);let i=n.daemon.worktreePrune;i&&typeof i=="object"&&(s.worktreePrune={enabled:typeof i.enabled=="boolean"?i.enabled:!0,cron:typeof i.cron=="string"?i.cron:"0 4 * * *",maxAgeDaysClean:typeof i.maxAgeDaysClean=="number"?i.maxAgeDaysClean:14,maxAgeDaysDirty:typeof i.maxAgeDaysDirty=="number"?i.maxAgeDaysDirty:30,scope:typeof i.scope=="string"?i.scope:"all"}),typeof n.daemon.verifyDone=="boolean"&&(s.verifyDone=n.daemon.verifyDone),r.daemon=s}if(n.telegram&&typeof n.telegram=="object"){let s={},i=n.telegram.notify;if(i&&typeof i=="object"){let a={};if((i.mode==="primary"||i.mode==="broadcast"||i.mode==="custom")&&(a.mode=i.mode),typeof i.primaryChatId=="number"&&Number.isFinite(i.primaryChatId)&&(a.primaryChatId=i.primaryChatId),Array.isArray(i.targets)){let c=i.targets.filter(l=>typeof l=="number"&&Number.isFinite(l));c.length>0&&(a.targets=c)}s.notify=a}if(typeof n.telegram.verifyDone=="boolean"&&(s.verifyDone=n.telegram.verifyDone),Array.isArray(n.telegram.tagOnlyChats)){let a=n.telegram.tagOnlyChats.filter(c=>typeof c=="number"&&Number.isFinite(c));a.length>0&&(s.tagOnlyChats=a)}if(n.telegram.chatAliases&&typeof n.telegram.chatAliases=="object"&&!Array.isArray(n.telegram.chatAliases)){let a={};for(let[c,l]of Object.entries(n.telegram.chatAliases))typeof l=="number"&&Number.isFinite(l)&&l!==0&&(a[c]=l);Object.keys(a).length>0&&(s.chatAliases=a)}r.telegram=s}if(n.updatePolicy&&["notify","auto","off"].includes(n.updatePolicy)&&(r.updatePolicy=n.updatePolicy),n.theme&&["dark","light","umber","auto"].includes(n.theme)&&(r.theme=n.theme),typeof n.autoResumeOnUsageLimit=="boolean"&&(r.autoResumeOnUsageLimit=n.autoResumeOnUsageLimit),typeof n.enforceDoneEvidence=="boolean"&&(r.enforceDoneEvidence=n.enforceDoneEvidence),typeof n.bgSummaries=="boolean"&&(r.bgSummaries=n.bgSummaries),typeof n.maxSummaryCallsPerSession=="number"&&(r.maxSummaryCallsPerSession=Math.min(500,Math.max(1,n.maxSummaryCallsPerSession))),n.hooks!==null&&typeof n.hooks=="object"&&!Array.isArray(n.hooks)&&(r.hooks=n.hooks),typeof n.enableShellHooks=="boolean"&&(r.enableShellHooks=n.enableShellHooks),typeof n.enablePluginHooks=="boolean"&&(r.enablePluginHooks=n.enablePluginHooks),Vd().includes(t)){let s=Jd(n.importFrom);s!==void 0&&(r.importFrom=s)}if(n.interactive&&typeof n.interactive=="object"){let s={};typeof n.interactive.worktreeAutoname=="boolean"&&(s.worktreeAutoname=n.interactive.worktreeAutoname),typeof n.interactive.worktreeBranchPrefix=="string"&&(s.worktreeBranchPrefix=zy(n.interactive.worktreeBranchPrefix,`${t}#/interactive/worktreeBranchPrefix`)),typeof n.interactive.worktreeBase=="string"&&n.interactive.worktreeBase.trim().length>0&&(Jy(n.interactive.worktreeBase,`${t}#/interactive/worktreeBase`),s.worktreeBase=n.interactive.worktreeBase),(n.interactive.worktreeOnExit==="ask"||n.interactive.worktreeOnExit==="keep"||n.interactive.worktreeOnExit==="remove")&&(s.worktreeOnExit=n.interactive.worktreeOnExit),typeof n.interactive.suggestGhost=="boolean"&&(s.suggestGhost=n.interactive.suggestGhost),(n.interactive.thinkingUi==="summary"||n.interactive.thinkingUi==="live"||n.interactive.thinkingUi==="digest"||n.interactive.thinkingUi==="off")&&(s.thinkingUi=n.interactive.thinkingUi),Object.keys(s).length>0&&(r.interactive=s)}return{config:r,modelsPartial:o}}var qi;function tb(){if(qi!==void 0)return qi;let t=Dy().map(r=>r.path),e=!1;for(let r of t){let o;try{o=eb(r)}catch(i){console.error(`Warning: Failed to parse ${r}:`,i),e=!0;continue}if(o===void 0)continue;let s={...o,sourcePath:r};return e||(qi=s),s}let n={config:{},sourcePath:void 0,modelsPartial:{}};return e||(qi=n),n}P();function Zd(){return tb().config.telegram??{}}I();var nb=!1;function YD(t,e){return e!==void 0&&Number.isFinite(e)&&e!==0?e:t.find(r=>r>0)??t[0]}function QD(t,e){if(nb||e!==void 0&&Number.isFinite(e)&&e!==0)return;let n=t.some(o=>o>0),r=t.some(o=>o<0);n&&r&&(nb=!0,console.warn("[telegram] AFK_TELEGRAM_ALLOWED_CHAT_IDS contains both a DM and a group chat. Notifications will go to the DM (positive-id chat) by default. Set AFK_TELEGRAM_PRIMARY_CHAT_ID to route notifications to a different chat."))}function ZD(t,e={}){let n=[...t],r=e.mode??"primary";if(r==="broadcast")return n;if(r==="custom"){let s=(e.targets??[]).filter(i=>typeof i=="number"&&Number.isFinite(i)&&i!==0);if(s.length>0)return[...new Set(s)]}QD(n,e.primaryChatId);let o=YD(n,e.primaryChatId);return o!==void 0?[o]:[]}function rb(t,e={}){if(typeof t=="number")return!Number.isFinite(t)||t===0?{ok:!1,reason:"invalid",message:`Invalid chat id: ${t}`}:{ok:!0,id:t};let n=t.trim();if(n.length===0)return{ok:!1,reason:"invalid",message:"Invalid chat: empty string"};let r=ob(n);if(r!==void 0)return{ok:!0,id:r};let o=Object.keys(e),s=Object.prototype.hasOwnProperty.call(e,n)?e[n]:void 0;if(s!==void 0&&Number.isFinite(s)&&s!==0)return{ok:!0,id:s};let i=o.length>0?`Available aliases: ${o.join(", ")}.`:"No chat aliases are configured (set telegram.chatAliases in afk.config.json).";return{ok:!1,reason:"unknown-alias",message:`Unknown chat alias "${n}". ${i}`}}function ob(t){if(!t)return;let e=t.trim();if(!/^-?\d+$/.test(e))return;let n=Number(e);return Number.isFinite(n)&&n!==0?n:void 0}function eF(t){if(!t)return;let e=t.trim().toLowerCase();return e==="primary"||e==="broadcast"||e==="custom"?e:void 0}function tF(){let t=Zd().notify??{},e=t.mode??eF(b.AFK_TELEGRAM_NOTIFY_MODE),n=t.primaryChatId??ob(b.AFK_TELEGRAM_PRIMARY_CHAT_ID);return{...e!==void 0?{mode:e}:{},...n!==void 0?{primaryChatId:n}:{},...t.targets!==void 0?{targets:t.targets}:{}}}function Gi(){let t=Eo(b.AFK_TELEGRAM_ALLOWED_CHAT_IDS);return ZD(t,tF())}function sb(){return Zd().chatAliases??{}}function Se(t,e=4096){if(t.length<=e)return[t];let n=[],r=t;for(;r.length>0;){if(r.length<=e){n.push(r);break}let o=e,s=r.lastIndexOf(`
|
|
244
244
|
`,e-1);if(s>e-500&&s>0)o=s+1;else{let i=r.slice(0,e).match(/[.!?]\s+(?=[A-Z])/g);if(i&&i.length>0){let a=i[i.length-1];if(a){let c=r.lastIndexOf(a,e-1);c>e-200&&c>0&&(o=Math.min(c+a.length,e))}}else{let a=r.lastIndexOf(" ",e-1);a>e-100&&a>0&&(o=a+1)}}n.push(r.slice(0,o)),r=r.slice(o)}return n}function Bt(t){t=t.replace(/[\x02\x03]/g,"");let e=t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),n=[];e=e.replace(/^ {0,3}```([\w]*)\n([\s\S]*?)```/gm,(o,s,i)=>{let a=n.length;if(i.trim()===""){let c=s?`(empty ${s} block)`:"(empty code block)";n.push(`<i>${c}</i>`)}else n.push(`<pre>${i}</pre>`);return`FENCED${a}`});let r=[];return e=e.replace(/`([^`]+)`/g,(o,s)=>{let i=r.length;return r.push(`<code>${s}</code>`),`CODE${i}`}),e=e.replace(/\*\*([^*]+)\*\*/g,"<b>$1</b>"),e=e.replace(/__([^_]+)__/g,"<b>$1</b>"),e=e.replace(/\*([^*]+)\*/g,"<i>$1</i>"),e=e.replace(/(^|[^\w])_([^_\n]+?)_(?!\w)/gm,"$1<i>$2</i>"),e=e.replace(/~~([^~]+)~~/g,"<s>$1</s>"),e=e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(o,s,i)=>'<a href="'+i.replace(/"/g,""")+'">'+s+"</a>"),e=e.replace(/^#{1,6}\s+/gm,""),nF(e)||(e=e.replace(/<\/?[bis]>/g,"")),e=e.replace(/\x02CODE(\d+)\x03/g,(o,s)=>r[Number(s)]??o),e=e.replace(/\x02FENCED(\d+)\x03/g,(o,s)=>n[Number(s)]??o),e}function nF(t){let e=[],n=/<(\/?)([a-zA-Z][a-zA-Z0-9-]*)\b[^>]*>/g,r;for(;(r=n.exec(t))!==null;){let o=(r[2]??"").toLowerCase();if(r[1]==="/"){if(e.pop()!==o)return!1}else e.push(o)}return e.length===0}function Ce(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function ib(t){if(t.kind==="unavailable")return t.reason==="no-token"?"\u26A0\uFE0F No Claude subscription token found. Run `claude login` on the host machine, then try /usage again.":`\u26A0\uFE0F Usage unavailable (${t.reason}): ${t.detail}`;let n=[["5-hour",t.fiveHour],["7-day",t.sevenDay],["7-day (Sonnet)",t.sevenDaySonnet],["7-day (Opus)",t.sevenDayOpus]].filter(r=>r[1]!==void 0).map(([r,o])=>{let s=Math.round(o.utilization*100),i=o.resetsAt?` (resets ${o.resetsAt.toLocaleString()})`:"";return` ${r}: ${s}%${i}`});return n.length===0?"\u{1F4CA} Usage: no windows reported.":["\u{1F4CA} Claude subscription usage:",...n].join(`
|
|
245
245
|
`)}function eu(t,e){return t==="ENOENT"?`\u274C Directory not found: ${e}`:t==="EACCES"?`\u274C Permission denied: ${e}`:`\u274C Unexpected error (${t}): ${e}`}function Ro(t){return`\u23F3 Queued (#${t} in line)`}function $(t){return`\u274C Error: ${t instanceof Error?t.message:t}`}function Xi(){return"\u26A0\uFE0F An internal error occurred. Please try again."}function ab(t){let e=["\u{1F4CB} Commands:",""," /start \u2014 Show welcome"," /help \u2014 Show this list"," /clear \u2014 Clear conversation history"," /compact \u2014 Summarize older messages"," /model \u2014 Switch Claude model"," /cd \u2014 Change working directory"," /name \u2014 Show or set the session name"," /usage \u2014 Show Claude subscription usage"," /sessions \u2014 List and switch between sessions"," /new \u2014 Start a new session (keeps the current one)"," /watch \u2014 Live-tail a CLI session from this chat"," /unwatch \u2014 Stop watching a session","","Also works from the CLI."];return t&&t.length>0&&e.push("","\u{1F4CB} Session commands (from SDK, when using settingSources):","",...t.map(n=>` /${n.replace(/^\//,"")}`)),e.push("","Just send a message to chat with Claude."),e.join(`
|
|
246
246
|
`)}function tu(){return`\u{1F44B} Welcome! I'm an agent-afk bot powered by Claude.
|
|
@@ -303,7 +303,7 @@ ${e}`}I();import{BlockList as hF,isIP as iu}from"node:net";import{lookup as yF}f
|
|
|
303
303
|
`)}finally{f&&await f.close().catch(()=>{})}}if(o){if(yield*l(),c)return}else try{i=(await _n.stat(n)).size}catch{}let d=null,u=null,p=()=>new Promise(f=>{let m=setTimeout(()=>{u=null,f()},TU);u=()=>{clearTimeout(m),u=null,f()},s?.addEventListener("abort",()=>{clearTimeout(m),u=null,f()},{once:!0})});try{d=rr.watch(r,{persistent:!1},()=>{u?.()})}catch{}try{for(;!s?.aborted&&!c&&(await p(),!s?.aborted);)yield*l()}finally{d?.close()}}P();import{readdir as _U,stat as EU}from"node:fs/promises";import{join as AU}from"node:path";async function Ku(){let t=Pn(),e;try{e=await _U(t)}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of e){let o=AU(t,r,"trace.jsonl");try{let s=await EU(o);s.isFile()&&n.push({sessionId:r,tracePath:o,mtimeMs:s.mtimeMs,exists:!0})}catch{}}return n.sort((r,o)=>o.mtimeMs-r.mtimeMs),n}async function FS(){return(await Ku())[0]?.sessionId??null}P();import{existsSync as xU,readdirSync as RU,readFileSync as IU}from"node:fs";import{basename as CU,join as PU}from"node:path";var MU=3;function OU(t){try{let e=JSON.parse(IU(t,"utf-8"));if(typeof e!="object"||e===null)return;let n=e;return{sessionId:typeof n.sessionId=="string"?n.sessionId:void 0,name:typeof n.name=="string"?n.name:void 0,savedAt:typeof n.savedAt=="number"?n.savedAt:void 0}}catch{return}}function DU(t){if(!xU(t))return[];let e;try{e=RU(t)}catch{return[]}let n=[];for(let r of e){if(!r.endsWith(".json"))continue;let o=PU(t,r),s=OU(o);s&&n.push({sidecarId:CU(r,".json"),filePath:o,data:s})}return n}function ha(t,e=oe()){let n=DU(e);n.sort((r,o)=>{let s=r.data.savedAt??-1/0;return(o.data.savedAt??-1/0)-s});for(let r of n){if(r.sidecarId===t)return{sessionId:r.data.sessionId??r.sidecarId,sidecarId:r.sidecarId,reason:"exact-id"};if(r.data.sessionId===t)return{sessionId:r.data.sessionId,sidecarId:r.sidecarId,reason:"exact-session-id"};if(r.data.name===t)return{sessionId:r.data.sessionId??r.sidecarId,sidecarId:r.sidecarId,reason:"exact-name"}}if(t.length>=MU){let r=n.filter(o=>o.data.name!==void 0&&o.data.name.startsWith(t));if(r.length===1){let o=r[0];return{sessionId:o.data.sessionId??o.sidecarId,sidecarId:o.sidecarId,reason:"prefix-name"}}}}import{existsSync as FU}from"node:fs";import{readFile as LU}from"node:fs/promises";var LS=2097152;async function qu(t){if(!FU(t))return{content:"",truncated:!1};try{let e=await LU(t);if(e.length<=LS)return{content:e.toString("utf-8"),truncated:!1};let n=e.subarray(e.length-LS),r=n.indexOf(10);return r!==-1&&(n=n.subarray(r+1)),{content:n.toString("utf-8"),truncated:!0}}catch{return{content:"",truncated:!1}}}var NU=50,UU=200,$U=200,BU=20,jU=100;function US(t){if(typeof t!="object"||t===null)return!1;let e=t;return typeof e.kind=="string"&&typeof e.seq=="number"&&typeof e.payload=="object"&&e.payload!==null}function HU(t){return co(t,{guard:US})}function WU(t){return typeof t!="number"?NU:Math.min(Math.max(1,Math.round(t)),UU)}function KU(t){return typeof t!="number"?BU:Math.min(Math.max(1,Math.round(t)),jU)}function qU(t,e){if(e.kinds&&!e.kinds.has(t.kind)||e.toolName&&(t.kind!=="tool_call"||t.payload.name!==e.toolName))return!1;if(e.errorsOnly)if(t.kind==="tool_call"){let n=t.payload;if(n.phase!=="completed"||!n.isError)return!1}else if(t.kind==="subagent_lifecycle"){if(t.payload.transition!=="failed")return!1}else if(t.kind==="background_agent"){if(t.payload.transition!=="failed")return!1}else return!1;return!0}async function GU(t){let e=async r=>{let o=NS(et(r),"trace.jsonl");if(!Gu(o))try{for await(let s of OS(r))if(s.kind==="meta"){if(s.traceLabel===null)return{tracePath:o,disabledNote:r};if(typeof s.traceLabel=="string"&&s.traceLabel.length>0){let i=NS(et(s.traceLabel),"trace.jsonl");Gu(i)&&(o=i)}break}}catch{}return{tracePath:o,disabledNote:void 0}},n=await e(t);if(n.disabledNote!==void 0||Gu(n.tracePath))return n;try{let r=ha(t);if(r&&r.sessionId!==t){let o=await e(r.sessionId);return o.disabledNote!==void 0?{tracePath:o.tracePath,disabledNote:r.sessionId}:o}}catch{}return n}async function $S(t){let e=t.session==="latest"||!t.session?await FS():t.session;if(!e)return{sessionId:"(none)",events:[],totalInTrace:0,filtered:0};let{tracePath:n,disabledNote:r}=await GU(e);if(r!==void 0)return{sessionId:e,events:[],totalInTrace:0,filtered:0,note:`Session "${r}" ran with tracing disabled (traceLabel: null).`};let{content:o}=await qu(n),s=HU(o),i={kinds:t.kinds?new Set(t.kinds):void 0,toolName:t.toolName,errorsOnly:t.errorsOnly},a=WU(t.limit),c=[];for(let l=s.length-1;l>=0;l--){let d=s[l];if(qU(d,i)&&(c.push(d),c.length>=a))break}return c.reverse(),{sessionId:e,events:c,totalInTrace:s.length,filtered:c.length}}async function BS(t){let e=KU(t.sessions),r=(await Ku()).slice(0,e),o=r.length,s=r;if(t.since){let p=Date.parse(t.since);if(Number.isNaN(p))throw new Error(`Invalid "since" date: ${t.since}`);s=r.filter(f=>f.mtimeMs>=p)}let i=t.kinds?new Set(t.kinds):void 0,a=t.query.toLowerCase(),c=[],l=$U,d=[],u=0;for(let p of s){if(c.length>=l)break;let{content:f,truncated:m}=await qu(p.tracePath);u++,m&&d.push(p.sessionId);let g=f.split(`
|
|
304
304
|
`).filter(h=>h.trim()!==""&&h.toLowerCase().includes(a));for(let h of g){if(c.length>=l)break;let[y]=co(h,{guard:US});y&&(i&&!i.has(y.kind)||t.toolName&&(y.kind!=="tool_call"||y.payload.name!==t.toolName)||c.push({sessionId:p.sessionId,event:y,matchLine:h.length>500?h.slice(0,500)+"\u2026":h}))}}return{query:t.query,sessionsAvailable:o,sessionsSearched:u,sessionsScanned:u,matches:c,...d.length>0?{truncatedSessions:d}:{}}}function jS(t){return!t||typeof t!="object"?null:t}function HS(t){if(Array.isArray(t))return t.filter(e=>typeof e=="string")}var WS=async t=>{let e=jS(t);if(!e)return{content:"Invalid input: expected object",isError:!0};let n=typeof e.session=="string"?e.session:void 0,r=HS(e.kinds),o=typeof e.tool_name=="string"?e.tool_name:void 0,s=typeof e.errors_only=="boolean"?e.errors_only:!1,i=typeof e.limit=="number"?e.limit:void 0;try{let a=await $S({session:n,kinds:r,toolName:o,errorsOnly:s,limit:i});return{content:JSON.stringify(a)}}catch(a){return{content:`read_witness failed: ${a instanceof Error?a.message:String(a)}`,isError:!0}}},KS=async t=>{let e=jS(t);if(!e)return{content:"Invalid input: expected object",isError:!0};if(typeof e.query!="string"||!e.query)return{content:"Invalid input: query (string) is required",isError:!0};let n=e.query,r=typeof e.sessions=="number"?e.sessions:void 0,o=HS(e.kinds),s=typeof e.since=="string"?e.since:void 0,i=typeof e.tool_name=="string"?e.tool_name:void 0;try{let a=await BS({query:n,sessions:r,kinds:o,since:s,toolName:i});return{content:JSON.stringify(a)}}catch(a){return{content:`search_witness failed: ${a instanceof Error?a.message:String(a)}`,isError:!0}}};var or={action:"decline"},qS=300;function XU(t){return t.length<=qS?t:`${t.slice(0,qS)}\u2026(truncated)`}function zU(t){try{let n=[`\u{1F514} AFK needs you \u2014 stuck on: ${t.title??t.serverName}`,XU(t.message)];t.url!==void 0&&t.url!==""&&n.push(t.url),Sb(n.join(`
|
|
305
305
|
`)).catch(()=>{})}catch{}}function GS(t,e){if(!(t===void 0||t===""))try{Ed(t,e).catch(()=>{})}catch{}}var Xu=class{handler=null;queue=Promise.resolve();queueDepth=0;install(e){this.handler=e}uninstall(){this.handler=null}hasHandler(){return this.handler!==null}pendingCount(){return this.queueDepth}route(e,n){if(n.signal.aborted)return Promise.resolve(or);this.queueDepth+=1;let r,o=new Promise(i=>{r=i}),s=this.handler;return this.queue=this.queue.then(async()=>{try{if(n.signal.aborted){r(or);return}if(!s){zU(e),r(or);return}let i,a=new Promise(c=>{i=()=>c(or),n.signal.addEventListener("abort",i,{once:!0})});try{try{n.onActive?.()}catch{}GS(n.sessionId,!0);let c=await Promise.race([s(e,n).catch(()=>or),a]);r(c)}finally{GS(n.sessionId,!1),n.signal.removeEventListener("abort",i)}}finally{this.queueDepth-=1,r(or)}}).catch(()=>{}),o}},vt=new Xu;var XS=async(t,e,n)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected an object",isError:!0};let r=t,o=r.question;if(typeof o!="string"||o.trim()==="")return{content:"Invalid input: question must be a non-empty string",isError:!0};let s=new Set(["text","confirm","choice","multi_choice","number"]),i=r.type??"text";if(typeof i!="string"||!s.has(i))return{content:"Invalid input: type must be one of: text, confirm, choice, multi_choice, number",isError:!0};if(i==="choice"||i==="multi_choice"){let m=r.choices;if(!Array.isArray(m)||m.length===0)return{content:`Invalid input: choices array is required and must be non-empty for type "${i}"`,isError:!0};if(m.length>100)return{content:`Invalid input: choices array must not exceed 100 items, got ${m.length}`,isError:!0};for(let g of m)if(typeof g!="string")return{content:"Invalid input: all choices must be strings",isError:!0}}let a=r.min,c=r.max;if(a!==void 0&&(typeof a!="number"||!Number.isFinite(a)))return{content:"Invalid input: min must be a finite number",isError:!0};if(c!==void 0&&(typeof c!="number"||!Number.isFinite(c)))return{content:"Invalid input: max must be a finite number",isError:!0};if(a!==void 0&&c!==void 0&&a>c)return{content:`Invalid input: min (${a}) must be \u2264 max (${c})`,isError:!0};let l=r.min_length,d=r.max_length;if(l!==void 0&&typeof l!="number")return{content:"Invalid input: min_length must be a number",isError:!0};if(d!==void 0&&typeof d!="number")return{content:"Invalid input: max_length must be a number",isError:!0};if((l!==void 0||d!==void 0)&&i!=="text")return{content:`Invalid input: min_length/max_length are only valid for type "text", got "${i}"`,isError:!0};if(r.allow_custom!==void 0&&i!=="choice"&&i!=="multi_choice")return{content:`Invalid input: allow_custom is only valid for type "choice" or "multi_choice", got "${i}"`,isError:!0};let u={serverName:"agent",message:o.trim(),origin:"agent",type:i,...r.choices!==void 0&&{choices:r.choices},...r.context!==void 0&&typeof r.context=="string"&&{context:r.context},...r.default!==void 0&&{questionDefault:r.default},...l!==void 0&&{minLength:l},...d!==void 0&&{maxLength:d},...a!==void 0&&{min:a},...c!==void 0&&{max:c},...r.allow_skip!==void 0&&{allowSkip:!!r.allow_skip},...r.allow_custom!==void 0&&{allowCustom:!!r.allow_custom}},p=await vt.route(u,{signal:e,...n?.sessionId!==void 0?{sessionId:n.sessionId}:{}}),f=p.action==="decline"||p.action==="cancel";return{content:JSON.stringify(p),...f&&{isError:!0,failureClass:"elicitation-declined"}}};I();var zS=["load","domcontentloaded","networkidle"];function JU(t){if(!t||typeof t!="object")return{error:"browser_open: input must be an object"};let e=t,n=e.url;if(typeof n!="string"||n.length===0)return{error:'browser_open: "url" is required and must be a non-empty string'};let r;try{r=new URL(n)}catch{return{error:`browser_open: "${n}" is not a valid absolute URL`}}if(r.protocol!=="http:"&&r.protocol!=="https:")return{error:`browser_open: protocol "${r.protocol}" is not supported (http/https only)`};let o;if(e.wait_for!==void 0){if(!zS.includes(e.wait_for))return{error:`browser_open: "wait_for" must be one of ${zS.map(a=>`"${a}"`).join(", ")} (got ${JSON.stringify(e.wait_for)})`};o=e.wait_for}let s;if(e.screenshot!==void 0){if(typeof e.screenshot!="boolean")return{error:'browser_open: "screenshot" must be a boolean'};s=e.screenshot}let i;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number"||!Number.isFinite(e.timeout_ms)||e.timeout_ms<=0)return{error:'browser_open: "timeout_ms" must be a positive finite number'};i=e.timeout_ms}return{url:r.toString(),waitFor:o,screenshot:s,timeoutMs:i}}function VU(t={}){return async(e,n,r)=>{if(n.aborted){let d=n.reason;return{content:`browser_open aborted: ${d instanceof Error?d.message:String(d??"aborted")}`,isError:!0,failureClass:be(n)}}let o=JU(e);if("error"in o)return{content:o.error,isError:!0};let s=b.AFK_SESSION_ID??"default";if(!/^[a-zA-Z0-9_-]+$/.test(s))return{content:`Invalid AFK_SESSION_ID: must match /^[a-zA-Z0-9_-]+$/, got: ${JSON.stringify(s)}`,isError:!0};let i,a,c;try{if(t.getBrowserProvider)i=await t.getBrowserProvider();else{let{getBrowserProvider:d,getLastRoutingDecision:u}=await Promise.resolve().then(()=>(kn(),Sn));i=await d();let p=u();p&&(a=p.backend,c=p.reason)}}catch(d){let u=d instanceof Error?d.message:String(d);return Re(u)?{content:Ke(u),isError:!0}:{content:`browser_open failed to get provider: ${u}`,isError:!0}}let l=Date.now();try{let d=await i.open({sessionId:s,url:o.url,waitFor:o.waitFor,screenshot:o.screenshot,timeoutMs:o.timeoutMs}),u=Date.now()-l;if("outcome"in d&&d.outcome==="blocked_by_policy")return ae(r?.traceWriter,{tool:"browser_open",toolUseId:r?.toolUseId??"",...a?{backend:a}:{},...c?{backendReason:c}:{},urlBefore:null,urlAfter:null,status:"blocked_by_policy",durationMs:u}),{content:`browser_open blocked: ${d.reason}`,isError:!0,failureClass:"policy-refusal"};let p=d;return ae(r?.traceWriter,{tool:"browser_open",toolUseId:r?.toolUseId??"",...a?{backend:a}:{},...c?{backendReason:c}:{},urlBefore:null,urlAfter:p.url,status:"ok",durationMs:u,...p.screenshotPath!==null?{screenshotPath:p.screenshotPath}:{}}),{content:JSON.stringify(p,null,2)}}catch(d){let u=Date.now()-l,p=d instanceof Error?d.message:String(d);ae(r?.traceWriter,{tool:"browser_open",toolUseId:r?.toolUseId??"",...a?{backend:a}:{},...c?{backendReason:c}:{},urlBefore:null,urlAfter:null,status:"error",durationMs:u,error:{reason:p,recoverable:!1}});let f=ta(d);return{content:`browser_open failed: ${p}`,isError:!0,...f?{failureClass:f}:{}}}}}var JS=VU();I();function YU(t){if(t!=null&&typeof t!="object")return{error:"browser_observe: input must be an object or omitted"};if(!t)return{};let e=t,n;if(e.screenshot!==void 0){if(typeof e.screenshot!="boolean")return{error:'browser_observe: "screenshot" must be a boolean'};n=e.screenshot}let r;if(e.include_hidden!==void 0){if(typeof e.include_hidden!="boolean")return{error:'browser_observe: "include_hidden" must be a boolean'};r=e.include_hidden}let o;if(e.max_elements!==void 0){if(typeof e.max_elements!="number"||!Number.isFinite(e.max_elements)||e.max_elements<=0||!Number.isInteger(e.max_elements))return{error:'browser_observe: "max_elements" must be a positive integer'};o=e.max_elements}return{screenshot:n,includeHidden:r,maxElements:o}}function QU(t={}){return async(e,n,r)=>{if(n.aborted){let d=n.reason;return{content:`browser_observe aborted: ${d instanceof Error?d.message:String(d??"aborted")}`,isError:!0}}let o=YU(e);if("error"in o)return{content:o.error,isError:!0};let s=b.AFK_SESSION_ID??"default";if(!/^[a-zA-Z0-9_-]+$/.test(s))return{content:`Invalid AFK_SESSION_ID: must match /^[a-zA-Z0-9_-]+$/, got: ${JSON.stringify(s)}`,isError:!0};let i,a,c;try{if(t.getBrowserProvider)i=await t.getBrowserProvider();else{let{getBrowserProvider:d,getLastRoutingDecision:u}=await Promise.resolve().then(()=>(kn(),Sn));i=await d();let p=u();p&&(a=p.backend,c=p.reason)}}catch(d){let u=d instanceof Error?d.message:String(d);return Re(u)?{content:Ke(u),isError:!0}:{content:`browser_observe failed to get provider: ${u}`,isError:!0}}let l=Date.now();try{let d=await i.observe({sessionId:s,screenshot:o.screenshot,includeHidden:o.includeHidden,maxElements:o.maxElements}),u=Date.now()-l;return ae(r?.traceWriter,{tool:"browser_observe",toolUseId:r?.toolUseId??"",...a?{backend:a}:{},...c?{backendReason:c}:{},urlBefore:d.url,urlAfter:d.url,status:"ok",durationMs:u,...d.screenshotPath!==null?{screenshotPath:d.screenshotPath}:{}}),{content:JSON.stringify(d,null,2)}}catch(d){let u=Date.now()-l,p=d instanceof Error?d.message:String(d);return ae(r?.traceWriter,{tool:"browser_observe",toolUseId:r?.toolUseId??"",...a?{backend:a}:{},...c?{backendReason:c}:{},urlBefore:null,urlAfter:null,status:"error",durationMs:u,error:{reason:p,recoverable:!1}}),{content:`browser_observe failed: ${p}`,isError:!0}}}}var VS=QU();zi();I();var YS=["click","fill","press","select","hover","scroll_to","wait_for"],QS=["semantic","element_id","selector"];function ZU(t){if(!t||typeof t!="object")return{error:"browser_act: input must be an object"};let e=t;if(typeof e.action!="string")return{error:'browser_act: "action" is required and must be a string'};if(!YS.includes(e.action))return{error:`browser_act: "action" must be one of ${YS.map(d=>`"${d}"`).join(", ")} (got ${JSON.stringify(e.action)})`};let n=e.action,r=e.target;if(!r||typeof r!="object")return{error:'browser_act: "target" is required and must be an object'};let o=r;if(typeof o.kind!="string"||!QS.includes(o.kind))return{error:`browser_act: "target.kind" must be one of ${QS.map(d=>`"${d}"`).join(", ")} (got ${JSON.stringify(o.kind)})`};let s,i=o.kind;if(i==="semantic"){if(typeof o.text!="string"||o.text.length===0)return{error:'browser_act: target.kind=semantic requires "target.text" (non-empty string)'};s={kind:"semantic",text:o.text,...typeof o.role=="string"&&o.role.length>0?{role:o.role}:{}}}else if(i==="element_id"){if(typeof o.element_id!="string"||o.element_id.length===0)return{error:'browser_act: target.kind=element_id requires "target.element_id" (non-empty string)'};s={kind:"element_id",elementId:o.element_id}}else{if(typeof o.selector!="string"||o.selector.length===0)return{error:'browser_act: target.kind=selector requires "target.selector" (non-empty string)'};s={kind:"selector",selector:o.selector}}let a;if(e.value!==void 0){if(typeof e.value!="string")return{error:'browser_act: "value" must be a string when provided'};a=e.value}let c;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number"||!Number.isFinite(e.timeout_ms)||e.timeout_ms<=0)return{error:'browser_act: "timeout_ms" must be a positive finite number'};c=e.timeout_ms}let l;if(e.screenshot!==void 0){if(typeof e.screenshot!="boolean")return{error:'browser_act: "screenshot" must be a boolean'};l=e.screenshot}return{action:n,target:s,value:a,timeoutMs:c,screenshot:l}}function e$(t,e){let n=t.role?`"${t.text}" (role: ${t.role})`:`"${t.text}"`;return[`browser_act: ambiguous target \u2014 ${e.length} elements matched ${n}.`,'Retry with target.kind="element_id" using one of the following:',...e.map(o=>` id=${o.id} role=${o.role} label=${o.label}`)].join(`
|
|
306
|
-
`)}function t$(t){return t.kind==="semantic"?{kind:"semantic",text:$b(t.text),...t.role!==void 0?{role:t.role}:{}}:t.kind==="element_id"?{kind:"element_id",elementId:t.elementId}:{kind:"selector",selectorHash:Ub(t.selector)}}function n$(t={}){return async(e,n,r)=>{if(n.aborted){let u=n.reason;return{content:`browser_act aborted: ${u instanceof Error?u.message:String(u??"aborted")}`,isError:!0,failureClass:be(n)}}let o=ZU(e);if("error"in o)return{content:o.error,isError:!0};let s=t$(o.target),i=b.AFK_SESSION_ID??"default";if(!/^[a-zA-Z0-9_-]+$/.test(i))return{content:`Invalid AFK_SESSION_ID: must match /^[a-zA-Z0-9_-]+$/, got: ${JSON.stringify(i)}`,isError:!0};let a,c,l;try{if(t.getBrowserProvider)a=await t.getBrowserProvider();else{let{getBrowserProvider:u,getLastRoutingDecision:p}=await Promise.resolve().then(()=>(kn(),Sn));a=await u();let f=p();f&&(c=f.backend,l=f.reason)}}catch(u){let p=u instanceof Error?u.message:String(u);return Re(p)?{content:Ke(p),isError:!0}:{content:`browser_act failed to get provider: ${p}`,isError:!0}}let d=Date.now();try{let u=await a.act({sessionId:i,action:o.action,target:o.target,value:o.value,timeoutMs:o.timeoutMs,screenshot:o.screenshot}),p=Date.now()-d;if("outcome"in u){if(u.outcome==="ambiguous_target")return ae(r?.traceWriter,{tool:"browser_act",action:o.action,toolUseId:r?.toolUseId??"",...c?{backend:c}:{},...l?{backendReason:l}:{},target:s,urlBefore:null,urlAfter:null,status:"ambiguous_target",durationMs:p}),{content:e$(u.query,u.candidates),isError:!0};if(u.outcome==="blocked_by_policy")return ae(r?.traceWriter,{tool:"browser_act",action:o.action,toolUseId:r?.toolUseId??"",...c?{backend:c}:{},...l?{backendReason:l}:{},target:s,urlBefore:null,urlAfter:null,status:"blocked_by_policy",durationMs:p}),{content:`browser_act blocked: ${u.reason}`,isError:!0,failureClass:"policy-refusal"}}return ae(r?.traceWriter,{tool:"browser_act",action:o.action,toolUseId:r?.toolUseId??"",...c?{backend:c}:{},...l?{backendReason:l}:{},target:s,urlBefore:u.url,urlAfter:u.url,status:"ok",durationMs:p,...u.screenshotPath!==null?{screenshotPath:u.screenshotPath}:{}}),{content:JSON.stringify(u,null,2)}}catch(u){let p=Date.now()-d,f=u instanceof Error?u.message:String(u);ae(r?.traceWriter,{tool:"browser_act",action:o.action,toolUseId:r?.toolUseId??"",...c?{backend:c}:{},...l?{backendReason:l}:{},target:s,urlBefore:null,urlAfter:null,status:"error",durationMs:p,error:{reason:f,recoverable:!1}});let m=ta(u);return{content:`browser_act failed: ${f}`,isError:!0,...m?{failureClass:m}:{}}}}}var ZS=n$();I();var ek=["semantic","element_id","selector"],zu=8e3;function r$(t){if(typeof t.kind!="string"||!ek.includes(t.kind))return{error:`browser_screenshot: "target.kind" must be one of ${ek.map(n=>`"${n}"`).join(", ")} (got ${JSON.stringify(t.kind)})`};let e=t.kind;return e==="semantic"?typeof t.text!="string"||t.text.length===0?{error:'browser_screenshot: target.kind=semantic requires "target.text" (non-empty string)'}:{kind:"semantic",text:t.text,...typeof t.role=="string"&&t.role.length>0?{role:t.role}:{}}:e==="element_id"?typeof t.element_id!="string"||t.element_id.length===0?{error:'browser_screenshot: target.kind=element_id requires "target.element_id" (non-empty string)'}:{kind:"element_id",elementId:t.element_id}:typeof t.selector!="string"||t.selector.length===0?{error:'browser_screenshot: target.kind=selector requires "target.selector" (non-empty string)'}:{kind:"selector",selector:t.selector}}function o$(t){if(t!=null&&typeof t!="object")return{error:"browser_screenshot: input must be an object or omitted"};if(!t)return{};let e=t,n;if(e.target!==void 0){if(!e.target||typeof e.target!="object")return{error:'browser_screenshot: "target" must be an object when provided'};let o=r$(e.target);if("error"in o)return o;n=o}let r;if(e.full_page!==void 0){if(typeof e.full_page!="boolean")return{error:'browser_screenshot: "full_page" must be a boolean'};r=e.full_page}return{target:n,fullPage:r}}function s$(t={}){return async(e,n,r)=>{if(n.aborted){let d=n.reason;return{content:`browser_screenshot aborted: ${d instanceof Error?d.message:String(d??"aborted")}`,isError:!0}}let o=o$(e);if("error"in o)return{content:o.error,isError:!0};let s=b.AFK_SESSION_ID??"default";if(!/^[a-zA-Z0-9_-]+$/.test(s))return{content:`Invalid AFK_SESSION_ID: must match /^[a-zA-Z0-9_-]+$/, got: ${JSON.stringify(s)}`,isError:!0};let i,a,c;try{if(t.getBrowserProvider)i=await t.getBrowserProvider();else{let{getBrowserProvider:d,getLastRoutingDecision:u}=await Promise.resolve().then(()=>(kn(),Sn));i=await d();let p=u();p&&(a=p.backend,c=p.reason)}}catch(d){let u=d instanceof Error?d.message:String(d);return Re(u)?{content:Ke(u),isError:!0}:{content:`browser_screenshot failed to get provider: ${u}`,isError:!0}}let l=Date.now();try{let d=await i.screenshot({sessionId:s,target:o.target,fullPage:o.fullPage}),u=Date.now()-l,{dataBase64:p,mediaType:f,...m}=d;return ae(r?.traceWriter,{tool:"browser_screenshot",toolUseId:r?.toolUseId??"",...a?{backend:a}:{},...c?{backendReason:c}:{},urlBefore:null,urlAfter:null,status:"ok",durationMs:u,screenshotPath:m.path}),m.width>zu||m.height>zu?{content:JSON.stringify({...m,imageOmitted:`dimensions ${m.width}x${m.height}px exceed the ${zu}px model-vision limit; the PNG was saved to the sidecar path but not attached. Use full_page:false (viewport) or target a specific element for a model-visible image.`},null,2)}:{content:JSON.stringify(m,null,2),image:{mediaType:f,data:p}}}catch(d){let u=Date.now()-l,p=d instanceof Error?d.message:String(d);return ae(r?.traceWriter,{tool:"browser_screenshot",toolUseId:r?.toolUseId??"",...a?{backend:a}:{},...c?{backendReason:c}:{},urlBefore:null,urlAfter:null,status:"error",durationMs:u,error:{reason:p,recoverable:!1}}),{content:`browser_screenshot failed: ${p}`,isError:!0}}}}var tk=s$();I();function i$(t={}){return async(e,n,r)=>{if(n.aborted){let l=n.reason;return{content:`browser_close aborted: ${l instanceof Error?l.message:String(l??"aborted")}`,isError:!0}}let o=b.AFK_SESSION_ID??"default";if(!/^[a-zA-Z0-9_-]+$/.test(o))return{content:`Invalid AFK_SESSION_ID: must match /^[a-zA-Z0-9_-]+$/, got: ${JSON.stringify(o)}`,isError:!0};let s,i,a;try{if(t.getBrowserProvider)s=await t.getBrowserProvider();else{let{getBrowserProvider:l,getLastRoutingDecision:d}=await Promise.resolve().then(()=>(kn(),Sn));s=await l();let u=d();u&&(i=u.backend,a=u.reason)}}catch(l){let d=l instanceof Error?l.message:String(l);return Re(d)?{content:Ke(d),isError:!0}:{content:`browser_close failed to get provider: ${d}`,isError:!0}}let c=Date.now();try{await s.close({sessionId:o});let l=Date.now()-c;return ae(r?.traceWriter,{tool:"browser_close",toolUseId:r?.toolUseId??"",...i?{backend:i}:{},...a?{backendReason:a}:{},urlBefore:null,urlAfter:null,status:"ok",durationMs:l}),{content:"Browser session closed."}}catch(l){let d=Date.now()-c,u=l instanceof Error?l.message:String(l);return ae(r?.traceWriter,{tool:"browser_close",toolUseId:r?.toolUseId??"",...i?{backend:i}:{},...a?{backendReason:a}:{},urlBefore:null,urlAfter:null,status:"error",durationMs:d,error:{reason:u,recoverable:!1}}),{content:`browser_close failed: ${u}`,isError:!0}}}}var nk=i$();import kk from"node:path";import*as ya from"node:fs/promises";import{execSync as k$}from"node:child_process";import ck from"path";var a$=new Set(["Read","Glob","Grep","NotebookRead","LS","read_file","extract_document","glob","grep","list_directory","config_get","memory_search","workspace_query","read_witness","search_witness","get_facet","json_query","state_get","state_query"]),c$=new Set(["Write","Edit","NotebookEdit","MultiEdit","write_file","edit_file","patch_apply","memory_update","procedure_write","terminal_font_size","config_set","workspace_publish","state_put","state_cas","state_delete","clipboard_write"]),l$=new Set(["Bash","BashOutput","KillBash","bash","test_run","wait_for"]),rk=new Set(["Agent","Task","agent","cancel_background_job","send_message_to_agent"]),ok=new Set(["Skill","skill"]),sk=new Set(["Compose","compose"]),b7=new Set([...rk,...sk,...ok]),d$=new Set(["WebFetch","WebSearch","send_telegram","web_scrape","web_request"]),u$=new Set(["browser_open","browser_observe","browser_act","browser_screenshot","browser_extract","browser_close"]),p$=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet","TaskOutput","TaskStop","EnterPlanMode","ExitPlanMode","ToolSearch"]),f$=new Set(["create_schedule","list_schedules","get_schedule_history","cancel_schedule"]);function Kt(t,e){if(t.has(e))return!0;let n=e.charAt(0).toUpperCase()+e.slice(1);return n!==e&&t.has(n)}var Ju=["Read","Glob","Grep","NotebookRead","LS","read_file","extract_document","glob","grep","list_directory","config_get","memory_search","read_witness","search_witness","workspace_publish","workspace_query","json_query","state_get","state_query",...$e],ik=[...Ju,"web_scrape","agent"];function ak(t){return t.startsWith("mcp__")||t.startsWith("MCP__")?"mcp":Kt(a$,t)?"read":Kt(c$,t)?"write":Kt(l$,t)?"shell":Kt(rk,t)?"subagent":Kt(ok,t)?"skill":Kt(sk,t)?"dag":Kt(d$,t)?"web":u$.has(t)?"browser":Kt(p$,t)?"planning":f$.has(t)?"schedule":"other"}var m$=["rm -rf","rm ","sudo","eval ","chmod","chown","git push --force","git push -f","git reset --hard","mkfs","fdisk","diskutil eraseDisk","dd if=","dd of=","| sh","| bash","|sh","|bash","-X POST","-X PUT","-X PATCH","-X DELETE","-XPOST","-XPUT","-XPATCH","-XDELETE","--request POST","--request PUT","--request PATCH","--request DELETE","curl --data","curl -d","curl -F","wget --post-data","wget --post-file","launchctl load","launchctl bootstrap","launchctl submit","launchctl start ","launchctl kickstart","launchctl enable ","systemctl enable ","systemctl start ","systemctl daemon-reload"],g$=["git push","git reset","git commit","git stash drop","git stash clear","npm install","pnpm install","yarn","pip install","apt ","apt-get ","brew install","tee "," > "," >> ","mv ","cp ","mkdir","touch","pnpm build","tsc ","eslint --fix"],h$=["pnpm test","vitest","jest","pytest","cargo test","go test","git status","git log","git diff","git show","ls ","cat ","head ","tail ","find ","grep ","echo ","printf "];function y$(t){return typeof t=="object"&&t!==null&&"command"in t?String(t.command??""):typeof t=="string"?t:""}function b$(t){if(typeof t!="object"||t===null)return"";let e=t;return typeof e.file_path=="string"?e.file_path:typeof e.path=="string"?e.path:""}function lk(t){for(let e of m$)if(t.includes(e))return"high";for(let e of g$)if(t.includes(e))return"medium";for(let e of h$)if(t.includes(e))return"safe";return"medium"}function dk(t,e){if(!t)return"safe";let n=He(ck.resolve(e.cwd,t)),r=Md();for(let o of r)if(n===o||n.startsWith(o+"/"))return"high";if(n.includes("/.git/"))return"high";if(e.workspaceRoot!==void 0){let o=He(e.workspaceRoot);if(ck.relative(o,n).startsWith(".."))return"high"}return n.includes("/node_modules/")?"medium":"safe"}var w$=new Set(["delete","drop","remove","destroy","truncate","purge","wipe","write","create","update","insert","upsert","patch","rename","exec","execute","run","eval","send","push","publish","deploy","post","merge","rollback","reset","terminate","provision","scale","disable","charge","refund","revoke"]);function S$(t){return t.split("__").slice(1).join("__").split(/[_-]+/).filter(Boolean)}function uk(t,e,n){let r=t.toLowerCase();if(r==="bash"){let o=y$(e);return lk(o)}if(r==="write_file"||r==="edit_file"){let o=b$(e);return dk(o,n)}if(r==="patch_apply"){let o=typeof e=="object"&&e!==null?e:{},s=Array.isArray(o.changes)?o.changes:[],i="safe";for(let a of s){if(typeof a!="object"||a===null)continue;let c=a.path,d=dk(typeof c=="string"?c:"",n);if(d==="high")return"high";d==="medium"&&(i="medium")}return i}if(ak(t)==="read")return"safe";if(r==="send_telegram")return"medium";if(r.startsWith("mcp__"))return S$(r).some(s=>w$.has(s))?"high":"medium";if(r==="create_schedule"||r==="cancel_schedule")return"high";if(r==="worktree"){let o=typeof e=="object"&&e!==null?e:{},s=typeof o.action=="string"?o.action:"";return s==="list"?"safe":s==="remove"&&o.force===!0?"high":"medium"}if(r==="browser_act"||r==="browser_open"||r==="web_scrape")return"medium";if(r==="web_request"){let o=typeof e=="object"&&e!==null?e:{},s=typeof o.method=="string"?o.method.toUpperCase():"";return s==="DELETE"?"high":s==="GET"||s==="HEAD"||s==="OPTIONS"?"safe":"medium"}if(r==="wait_for"){let o=typeof e=="object"&&e!==null?e:{},s=typeof o.type=="string"?o.type:"";if(s==="command"){let i=typeof o.command=="string"?o.command:"";return lk(i)}return s==="file"||s==="process"?"safe":"medium"}return"safe"}async function pk(t,e){let n=t.method??"HEAD",r;try{r=await jt(globalThis.fetch,t.url,{method:n,signal:e})}catch(a){let c=a instanceof Error?a.message:String(a);return{met:!1,detail:c.startsWith("refusing to")?`SSRF blocked: ${c}`:`fetch error: ${c}`,data:c.startsWith("refusing to")?{blocked:!0}:void 0}}let{status:o}=r,s={status:o};if(!(t.expected_status!==void 0?o===t.expected_status:o>=200&&o<300))return{met:!1,detail:`HTTP ${o} (want ${t.expected_status??"2xx"})`,data:s};if(t.body_contains!==void 0){let a=await r.text().catch(()=>"");if(s.bodyLength=a.length,!a.includes(t.body_contains))return{met:!1,detail:`body does not contain "${t.body_contains}"`,data:s}}else n==="HEAD"&&await r.body?.cancel().catch(()=>{});return{met:!0,detail:`HTTP ${o}`,data:s}}async function fk(t,e){let n;try{let o=t.workspaceRoot?{resolveBase:t.workspaceRoot,cwd:t.workspaceRoot}:void 0;n=ee(t.path,o,"read")}catch(o){return{met:!1,detail:`path rejected: ${o instanceof Error?o.message:String(o)}`,data:{blocked:!0}}}let r;try{let o=await ya.stat(n);r={mtimeMs:o.mtimeMs,size:o.size}}catch{return{met:!1,detail:`file not found: ${t.path}`}}if(t.content_contains!==void 0){let o;try{o=await ya.readFile(n,{encoding:"utf8",signal:e})}catch(s){return{met:!1,detail:`read error: ${s instanceof Error?s.message:String(s)}`,data:r}}if(!o.includes(t.content_contains))return{met:!1,detail:`file exists but does not contain "${t.content_contains}"`,data:r}}return{met:!0,detail:`file exists (${r.size} bytes)`,data:r}}function mk(t,e){if(!Number.isInteger(t.pid)||t.pid<=1)return{met:!1,detail:`pid ${t.pid} is not a valid target (must be integer > 1)`,data:{pid:t.pid,blocked:!0}};if(e!==void 0&&!e.has(t.pid))return{met:!1,detail:`pid ${t.pid} is not a session-owned process (not in spawned PID registry)`,data:{pid:t.pid,blocked:!0}};try{return process.kill(t.pid,0),{met:!1,detail:`pid ${t.pid} is still alive`,data:{pid:t.pid}}}catch(n){let r=n.code;return r==="ESRCH"?{met:!0,detail:`pid ${t.pid} has exited`,data:{pid:t.pid}}:{met:!1,detail:`pid ${t.pid} is alive (${r??"unknown"})`,data:{pid:t.pid}}}}function gk(t){let e=uk("bash",{command:t.command},{cwd:t.cwd??process.cwd()});if(e!=="safe")return{met:!1,detail:`command blocked by risk classifier (${e} risk): ${t.command}`,data:{command:t.command,blocked:!0}};try{return k$(t.command,{cwd:t.cwd,stdio:"pipe",timeout:3e4}),{met:!0,detail:"command exited 0",data:{command:t.command}}}catch(n){let r=n;if(r.killed===!0&&r.signal==="SIGTERM")return{met:!1,detail:"command timed out (30s limit)",data:{command:t.command,timedOut:!0}};let o=r.status??-1;return{met:!1,detail:`command exited ${o}`,data:{command:t.command,exitCode:o}}}}function Ie(t,e){return new Promise(n=>{if(e.aborted){n();return}let r=()=>{clearTimeout(o),n()},o=setTimeout(()=>{e.removeEventListener("abort",r),n()},t);o.unref(),e.addEventListener("abort",r,{once:!0})})}var hk=12e4,yk=6e5,bk=5e3,wk=1e3;function v$(t,e,n){switch(n){case"linear":return t+e*1e3;case"exponential":return Math.min(t*Math.pow(2,e),6e4);default:return t}}async function Sk(t,e){let{timeout_ms:n,poll_interval_ms:r,backoff:o,signal:s}=e,i=Date.now()+n,a=0,c;for(;;){if(s.aborted)return{status:"cancelled",elapsed_ms:Date.now()-(i-n),attempts:a};let l=i-Date.now(),d=AbortSignal.any([s,AbortSignal.timeout(Math.max(1,Math.min(r,l)))]),u;try{u=await t(d)}catch(m){if(s.aborted)return{status:"cancelled",elapsed_ms:Date.now()-(i-n),attempts:a};if(m instanceof Error&&m.name==="AbortError"){if(Date.now()>=i)return{status:"timed_out",elapsed_ms:Date.now()-(i-n),attempts:a,result:c};continue}let g=m instanceof Error?m.message:String(m);return{status:"failed",elapsed_ms:Date.now()-(i-n),attempts:a,error:g}}if(c=u,a++,u.met)return{status:"succeeded",elapsed_ms:Date.now()-(i-n),attempts:a,result:u};let p=Date.now();if(p>=i)return{status:"timed_out",elapsed_ms:p-(i-n),attempts:a,result:c};let f=Math.min(v$(r,a-1,o),i-p);await Ie(f,s)}}function T$(t,e){if(typeof t!="object"||t===null)throw new Error("Input must be an object");let n=t,r=n.type;if(typeof r!="string")throw new Error('"type" is required and must be a string');let o=hk;if(n.timeout_ms!==void 0){if(typeof n.timeout_ms!="number"||!Number.isFinite(n.timeout_ms))throw new Error('"timeout_ms" must be a finite number');o=Math.min(Math.max(0,n.timeout_ms),yk)}let s=bk;if(n.poll_interval_ms!==void 0){if(typeof n.poll_interval_ms!="number"||!Number.isFinite(n.poll_interval_ms))throw new Error('"poll_interval_ms" must be a finite number');s=Math.max(wk,n.poll_interval_ms)}let i=["none","linear","exponential"],a="none";if(n.backoff!==void 0){if(!i.includes(n.backoff))throw new Error(`"backoff" must be one of: ${i.join(", ")}`);a=n.backoff}switch(r){case"url":{if(typeof n.url!="string"||n.url.trim()==="")throw new Error('"url" is required for type "url"');let c=n.body_contains!==void 0,l=n.method??(c?"GET":"HEAD");if(l!=="HEAD"&&l!=="GET")throw new Error('"method" must be "HEAD" or "GET"');return{condition:{type:"url",url:n.url,method:l,...n.expected_status!==void 0?{expected_status:Number(n.expected_status)}:{},...c?{body_contains:String(n.body_contains)}:{}},timeoutMs:o,pollIntervalMs:s,backoff:a}}case"file":{if(typeof n.path!="string"||n.path.trim()==="")throw new Error('"path" is required for type "file"');let c=e?.resolveBase??e?.cwd;return{condition:{type:"file",path:c!==void 0&&!kk.isAbsolute(n.path)?kk.resolve(c,n.path):n.path,workspaceRoot:c,...n.content_contains!==void 0?{content_contains:String(n.content_contains)}:{}},timeoutMs:o,pollIntervalMs:s,backoff:a}}case"process":{if(typeof n.pid!="number"||!Number.isInteger(n.pid)||n.pid<=1)throw new Error('"pid" is required for type "process" and must be an integer > 1');return{condition:{type:"process",pid:n.pid},timeoutMs:o,pollIntervalMs:s,backoff:a}}case"command":{if(typeof n.command!="string"||n.command.trim()==="")throw new Error('"command" is required for type "command"');let c=e?.resolveBase??e?.cwd;return{condition:{type:"command",command:n.command,...c!==void 0?{cwd:c}:{}},timeoutMs:o,pollIntervalMs:s,backoff:a}}default:throw new Error(`Unknown type "${r}". Must be one of: url, file, process, command`)}}var vk=async(t,e,n)=>{let r;try{r=T$(t,n)}catch(u){return{content:u instanceof Error?u.message:String(u),isError:!0}}let{condition:o,timeoutMs:s,pollIntervalMs:i,backoff:a}=r;if(o.type==="url"){let u=await yn(o.url);if(!u.allowed)return{content:`SSRF guard blocked: ${u.reason}`,isError:!0}}let l=await Sk(u=>{switch(o.type){case"url":return pk(o,u);case"file":return fk(o,u);case"process":return Promise.resolve(mk(o,n?.spawnedPidRegistry));case"command":return Promise.resolve(gk(o))}},{timeout_ms:s,poll_interval_ms:i,backoff:a,signal:e});return{content:`Wait ${l.status}: ${o.type} condition (${l.elapsed_ms}ms elapsed, ${l.attempts} attempt${l.attempts===1?"":"s"})`+(l.result?` \u2014 ${l.result.detail}`:"")+(l.error?` \u2014 error: ${l.error}`:""),isError:l.status==="failed"}};import{resolve as B$}from"path";import{createHash as _$}from"crypto";import{readFile as E$}from"fs/promises";function A$(t){return _$("sha256").update(t,"utf8").digest("hex")}function x$(t,e){if(e.length===0)return 0;let n=0,r=0;for(;(r=t.indexOf(e,r))!==-1;)n++,r+=e.length;return n}async function Tk(t,e,n){let r=[],o=new Map;for(let s of t){let i=s.path,a;try{a=ee(i,n,"write",e)}catch(l){r.push({path:i,error:"path_containment",detail:l instanceof Error?l.message:String(l)});continue}try{Jn(a,"patch_apply")}catch(l){r.push({path:i,error:"write_denied",detail:l instanceof Error?l.message:String(l)});continue}if(s.edits!==void 0&&s.content!==void 0){r.push({path:i,error:"mutually_exclusive",detail:"`edits` and `content` cannot both be provided for the same file."});continue}if(s.edits===void 0&&s.content===void 0){r.push({path:i,error:"no_change_specified",detail:"At least one of `edits` or `content` must be provided."});continue}let c;try{c=await E$(a,"utf-8")}catch(l){if(s.expected_hash!==void 0||s.edits!==void 0){r.push({path:i,error:"file_read_failed",detail:l instanceof Error?l.message:String(l)});continue}o.set(a,null),c=""}if(o.has(a)||o.set(a,c),s.expected_hash!==void 0){let l="sha256:";if(!s.expected_hash.startsWith(l)){r.push({path:i,error:"invalid_hash_format",detail:`expected_hash must start with "sha256:". Got: "${s.expected_hash}"`});continue}let d=s.expected_hash.slice(l.length),u=A$(c);if(u!==d){r.push({path:i,error:"hash_mismatch",detail:`File hash mismatch. Expected sha256:${d}, got sha256:${u}. The file may have been modified.`});continue}}if(s.edits!==void 0){let l=c;for(let d=0;d<s.edits.length;d++){let u=s.edits[d],p=x$(l,u.old);if(p===0){r.push({path:i,error:"edit_not_found",detail:`Edit #${d+1}: \`old\` string not found in file.`});break}else if(p>1)r.push({path:i,error:"edit_ambiguous",detail:`Edit #${d+1}: \`old\` string matches ${p} locations. Provide enough context to make it unique.`});else{let f=l.indexOf(u.old);l=l.slice(0,f)+u.new+l.slice(f+u.old.length)}}}}return{valid:r.length===0,errors:r,fileContents:o}}import{createHash as R$,randomBytes as I$}from"crypto";import{writeFile as _k,rename as C$,mkdir as P$,unlink as Vu,chmod as M$,stat as O$}from"fs/promises";import{dirname as Ak,join as D$,isAbsolute as F$,resolve as L$}from"path";function Ek(t){return R$("sha256").update(t,"utf8").digest("hex")}function N$(t,e,n){let r=Zn(e,n);if(!r)return{text:"",payload:null};let o=[`--- a/${t}`,`+++ b/${t}`];for(let s of r.hunks){o.push(`@@ -${s.oldStart},${s.oldLines} +${s.newStart},${s.newLines} @@`);for(let i of s.lines)o.push(`${i.kind}${i.text}`)}return{text:o.join(`
|
|
306
|
+
`)}function t$(t){return t.kind==="semantic"?{kind:"semantic",text:$b(t.text),...t.role!==void 0?{role:t.role}:{}}:t.kind==="element_id"?{kind:"element_id",elementId:t.elementId}:{kind:"selector",selectorHash:Ub(t.selector)}}function n$(t={}){return async(e,n,r)=>{if(n.aborted){let u=n.reason;return{content:`browser_act aborted: ${u instanceof Error?u.message:String(u??"aborted")}`,isError:!0,failureClass:be(n)}}let o=ZU(e);if("error"in o)return{content:o.error,isError:!0};let s=t$(o.target),i=b.AFK_SESSION_ID??"default";if(!/^[a-zA-Z0-9_-]+$/.test(i))return{content:`Invalid AFK_SESSION_ID: must match /^[a-zA-Z0-9_-]+$/, got: ${JSON.stringify(i)}`,isError:!0};let a,c,l;try{if(t.getBrowserProvider)a=await t.getBrowserProvider();else{let{getBrowserProvider:u,getLastRoutingDecision:p}=await Promise.resolve().then(()=>(kn(),Sn));a=await u();let f=p();f&&(c=f.backend,l=f.reason)}}catch(u){let p=u instanceof Error?u.message:String(u);return Re(p)?{content:Ke(p),isError:!0}:{content:`browser_act failed to get provider: ${p}`,isError:!0}}let d=Date.now();try{let u=await a.act({sessionId:i,action:o.action,target:o.target,value:o.value,timeoutMs:o.timeoutMs,screenshot:o.screenshot}),p=Date.now()-d;if("outcome"in u){if(u.outcome==="ambiguous_target")return ae(r?.traceWriter,{tool:"browser_act",action:o.action,toolUseId:r?.toolUseId??"",...c?{backend:c}:{},...l?{backendReason:l}:{},target:s,urlBefore:null,urlAfter:null,status:"ambiguous_target",durationMs:p}),{content:e$(u.query,u.candidates),isError:!0};if(u.outcome==="blocked_by_policy")return ae(r?.traceWriter,{tool:"browser_act",action:o.action,toolUseId:r?.toolUseId??"",...c?{backend:c}:{},...l?{backendReason:l}:{},target:s,urlBefore:null,urlAfter:null,status:"blocked_by_policy",durationMs:p}),{content:`browser_act blocked: ${u.reason}`,isError:!0,failureClass:"policy-refusal"}}return ae(r?.traceWriter,{tool:"browser_act",action:o.action,toolUseId:r?.toolUseId??"",...c?{backend:c}:{},...l?{backendReason:l}:{},target:s,urlBefore:u.url,urlAfter:u.url,status:"ok",durationMs:p,...u.screenshotPath!==null?{screenshotPath:u.screenshotPath}:{}}),{content:JSON.stringify(u,null,2)}}catch(u){let p=Date.now()-d,f=u instanceof Error?u.message:String(u);ae(r?.traceWriter,{tool:"browser_act",action:o.action,toolUseId:r?.toolUseId??"",...c?{backend:c}:{},...l?{backendReason:l}:{},target:s,urlBefore:null,urlAfter:null,status:"error",durationMs:p,error:{reason:f,recoverable:!1}});let m=ta(u);return{content:`browser_act failed: ${f}`,isError:!0,...m?{failureClass:m}:{}}}}}var ZS=n$();I();var ek=["semantic","element_id","selector"],zu=8e3;function r$(t){if(typeof t.kind!="string"||!ek.includes(t.kind))return{error:`browser_screenshot: "target.kind" must be one of ${ek.map(n=>`"${n}"`).join(", ")} (got ${JSON.stringify(t.kind)})`};let e=t.kind;return e==="semantic"?typeof t.text!="string"||t.text.length===0?{error:'browser_screenshot: target.kind=semantic requires "target.text" (non-empty string)'}:{kind:"semantic",text:t.text,...typeof t.role=="string"&&t.role.length>0?{role:t.role}:{}}:e==="element_id"?typeof t.element_id!="string"||t.element_id.length===0?{error:'browser_screenshot: target.kind=element_id requires "target.element_id" (non-empty string)'}:{kind:"element_id",elementId:t.element_id}:typeof t.selector!="string"||t.selector.length===0?{error:'browser_screenshot: target.kind=selector requires "target.selector" (non-empty string)'}:{kind:"selector",selector:t.selector}}function o$(t){if(t!=null&&typeof t!="object")return{error:"browser_screenshot: input must be an object or omitted"};if(!t)return{};let e=t,n;if(e.target!==void 0){if(!e.target||typeof e.target!="object")return{error:'browser_screenshot: "target" must be an object when provided'};let o=r$(e.target);if("error"in o)return o;n=o}let r;if(e.full_page!==void 0){if(typeof e.full_page!="boolean")return{error:'browser_screenshot: "full_page" must be a boolean'};r=e.full_page}return{target:n,fullPage:r}}function s$(t={}){return async(e,n,r)=>{if(n.aborted){let d=n.reason;return{content:`browser_screenshot aborted: ${d instanceof Error?d.message:String(d??"aborted")}`,isError:!0}}let o=o$(e);if("error"in o)return{content:o.error,isError:!0};let s=b.AFK_SESSION_ID??"default";if(!/^[a-zA-Z0-9_-]+$/.test(s))return{content:`Invalid AFK_SESSION_ID: must match /^[a-zA-Z0-9_-]+$/, got: ${JSON.stringify(s)}`,isError:!0};let i,a,c;try{if(t.getBrowserProvider)i=await t.getBrowserProvider();else{let{getBrowserProvider:d,getLastRoutingDecision:u}=await Promise.resolve().then(()=>(kn(),Sn));i=await d();let p=u();p&&(a=p.backend,c=p.reason)}}catch(d){let u=d instanceof Error?d.message:String(d);return Re(u)?{content:Ke(u),isError:!0}:{content:`browser_screenshot failed to get provider: ${u}`,isError:!0}}let l=Date.now();try{let d=await i.screenshot({sessionId:s,target:o.target,fullPage:o.fullPage}),u=Date.now()-l,{dataBase64:p,mediaType:f,...m}=d;return ae(r?.traceWriter,{tool:"browser_screenshot",toolUseId:r?.toolUseId??"",...a?{backend:a}:{},...c?{backendReason:c}:{},urlBefore:null,urlAfter:null,status:"ok",durationMs:u,screenshotPath:m.path}),m.width>zu||m.height>zu?{content:JSON.stringify({...m,imageOmitted:`dimensions ${m.width}x${m.height}px exceed the ${zu}px model-vision limit; the PNG was saved to the sidecar path but not attached. Use full_page:false (viewport) or target a specific element for a model-visible image.`},null,2)}:{content:JSON.stringify(m,null,2),image:{mediaType:f,data:p}}}catch(d){let u=Date.now()-l,p=d instanceof Error?d.message:String(d);return ae(r?.traceWriter,{tool:"browser_screenshot",toolUseId:r?.toolUseId??"",...a?{backend:a}:{},...c?{backendReason:c}:{},urlBefore:null,urlAfter:null,status:"error",durationMs:u,error:{reason:p,recoverable:!1}}),{content:`browser_screenshot failed: ${p}`,isError:!0}}}}var tk=s$();I();function i$(t={}){return async(e,n,r)=>{if(n.aborted){let l=n.reason;return{content:`browser_close aborted: ${l instanceof Error?l.message:String(l??"aborted")}`,isError:!0}}let o=b.AFK_SESSION_ID??"default";if(!/^[a-zA-Z0-9_-]+$/.test(o))return{content:`Invalid AFK_SESSION_ID: must match /^[a-zA-Z0-9_-]+$/, got: ${JSON.stringify(o)}`,isError:!0};let s,i,a;try{if(t.getBrowserProvider)s=await t.getBrowserProvider();else{let{getBrowserProvider:l,getLastRoutingDecision:d}=await Promise.resolve().then(()=>(kn(),Sn));s=await l();let u=d();u&&(i=u.backend,a=u.reason)}}catch(l){let d=l instanceof Error?l.message:String(l);return Re(d)?{content:Ke(d),isError:!0}:{content:`browser_close failed to get provider: ${d}`,isError:!0}}let c=Date.now();try{await s.close({sessionId:o});let l=Date.now()-c;return ae(r?.traceWriter,{tool:"browser_close",toolUseId:r?.toolUseId??"",...i?{backend:i}:{},...a?{backendReason:a}:{},urlBefore:null,urlAfter:null,status:"ok",durationMs:l}),{content:"Browser session closed."}}catch(l){let d=Date.now()-c,u=l instanceof Error?l.message:String(l);return ae(r?.traceWriter,{tool:"browser_close",toolUseId:r?.toolUseId??"",...i?{backend:i}:{},...a?{backendReason:a}:{},urlBefore:null,urlAfter:null,status:"error",durationMs:d,error:{reason:u,recoverable:!1}}),{content:`browser_close failed: ${u}`,isError:!0}}}}var nk=i$();import kk from"node:path";import*as ya from"node:fs/promises";import{execSync as k$}from"node:child_process";import ck from"path";var a$=new Set(["Read","Glob","Grep","NotebookRead","LS","read_file","extract_document","glob","grep","list_directory","config_get","memory_search","workspace_query","read_witness","search_witness","get_facet","json_query","state_get","state_query"]),c$=new Set(["Write","Edit","NotebookEdit","MultiEdit","write_file","edit_file","patch_apply","memory_update","procedure_write","terminal_font_size","config_set","workspace_publish","state_put","state_cas","state_delete","clipboard_write"]),l$=new Set(["Bash","BashOutput","KillBash","bash","test_run","wait_for"]),rk=new Set(["Agent","Task","agent","cancel_background_job","send_message_to_agent"]),ok=new Set(["Skill","skill"]),sk=new Set(["Compose","compose"]),w7=new Set([...rk,...sk,...ok]),d$=new Set(["WebFetch","WebSearch","send_telegram","web_scrape","web_request"]),u$=new Set(["browser_open","browser_observe","browser_act","browser_screenshot","browser_extract","browser_close"]),p$=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet","TaskOutput","TaskStop","EnterPlanMode","ExitPlanMode","ToolSearch"]),f$=new Set(["create_schedule","list_schedules","get_schedule_history","cancel_schedule"]);function Kt(t,e){if(t.has(e))return!0;let n=e.charAt(0).toUpperCase()+e.slice(1);return n!==e&&t.has(n)}var Ju=["Read","Glob","Grep","NotebookRead","LS","read_file","extract_document","glob","grep","list_directory","config_get","memory_search","read_witness","search_witness","workspace_publish","workspace_query","json_query","state_get","state_query",...$e],ik=[...Ju,"web_scrape","agent"];function ak(t){return t.startsWith("mcp__")||t.startsWith("MCP__")?"mcp":Kt(a$,t)?"read":Kt(c$,t)?"write":Kt(l$,t)?"shell":Kt(rk,t)?"subagent":Kt(ok,t)?"skill":Kt(sk,t)?"dag":Kt(d$,t)?"web":u$.has(t)?"browser":Kt(p$,t)?"planning":f$.has(t)?"schedule":"other"}var m$=["rm -rf","rm ","sudo","eval ","chmod","chown","git push --force","git push -f","git reset --hard","mkfs","fdisk","diskutil eraseDisk","dd if=","dd of=","| sh","| bash","|sh","|bash","-X POST","-X PUT","-X PATCH","-X DELETE","-XPOST","-XPUT","-XPATCH","-XDELETE","--request POST","--request PUT","--request PATCH","--request DELETE","curl --data","curl -d","curl -F","wget --post-data","wget --post-file","launchctl load","launchctl bootstrap","launchctl submit","launchctl start ","launchctl kickstart","launchctl enable ","systemctl enable ","systemctl start ","systemctl daemon-reload"],g$=["git push","git reset","git commit","git stash drop","git stash clear","npm install","pnpm install","yarn","pip install","apt ","apt-get ","brew install","tee "," > "," >> ","mv ","cp ","mkdir","touch","pnpm build","tsc ","eslint --fix"],h$=["pnpm test","vitest","jest","pytest","cargo test","go test","git status","git log","git diff","git show","ls ","cat ","head ","tail ","find ","grep ","echo ","printf "];function y$(t){return typeof t=="object"&&t!==null&&"command"in t?String(t.command??""):typeof t=="string"?t:""}function b$(t){if(typeof t!="object"||t===null)return"";let e=t;return typeof e.file_path=="string"?e.file_path:typeof e.path=="string"?e.path:""}function lk(t){for(let e of m$)if(t.includes(e))return"high";for(let e of g$)if(t.includes(e))return"medium";for(let e of h$)if(t.includes(e))return"safe";return"medium"}function dk(t,e){if(!t)return"safe";let n=He(ck.resolve(e.cwd,t)),r=Md();for(let o of r)if(n===o||n.startsWith(o+"/"))return"high";if(n.includes("/.git/"))return"high";if(e.workspaceRoot!==void 0){let o=He(e.workspaceRoot);if(ck.relative(o,n).startsWith(".."))return"high"}return n.includes("/node_modules/")?"medium":"safe"}var w$=new Set(["delete","drop","remove","destroy","truncate","purge","wipe","write","create","update","insert","upsert","patch","rename","exec","execute","run","eval","send","push","publish","deploy","post","merge","rollback","reset","terminate","provision","scale","disable","charge","refund","revoke"]);function S$(t){return t.split("__").slice(1).join("__").split(/[_-]+/).filter(Boolean)}function uk(t,e,n){let r=t.toLowerCase();if(r==="bash"){let o=y$(e);return lk(o)}if(r==="write_file"||r==="edit_file"){let o=b$(e);return dk(o,n)}if(r==="patch_apply"){let o=typeof e=="object"&&e!==null?e:{},s=Array.isArray(o.changes)?o.changes:[],i="safe";for(let a of s){if(typeof a!="object"||a===null)continue;let c=a.path,d=dk(typeof c=="string"?c:"",n);if(d==="high")return"high";d==="medium"&&(i="medium")}return i}if(ak(t)==="read")return"safe";if(r==="send_telegram")return"medium";if(r.startsWith("mcp__"))return S$(r).some(s=>w$.has(s))?"high":"medium";if(r==="create_schedule"||r==="cancel_schedule")return"high";if(r==="worktree"){let o=typeof e=="object"&&e!==null?e:{},s=typeof o.action=="string"?o.action:"";return s==="list"?"safe":s==="remove"&&o.force===!0?"high":"medium"}if(r==="browser_act"||r==="browser_open"||r==="web_scrape")return"medium";if(r==="web_request"){let o=typeof e=="object"&&e!==null?e:{},s=typeof o.method=="string"?o.method.toUpperCase():"";return s==="DELETE"?"high":s==="GET"||s==="HEAD"||s==="OPTIONS"?"safe":"medium"}if(r==="wait_for"){let o=typeof e=="object"&&e!==null?e:{},s=typeof o.type=="string"?o.type:"";if(s==="command"){let i=typeof o.command=="string"?o.command:"";return lk(i)}return s==="file"||s==="process"?"safe":"medium"}return"safe"}async function pk(t,e){let n=t.method??"HEAD",r;try{r=await jt(globalThis.fetch,t.url,{method:n,signal:e})}catch(a){let c=a instanceof Error?a.message:String(a);return{met:!1,detail:c.startsWith("refusing to")?`SSRF blocked: ${c}`:`fetch error: ${c}`,data:c.startsWith("refusing to")?{blocked:!0}:void 0}}let{status:o}=r,s={status:o};if(!(t.expected_status!==void 0?o===t.expected_status:o>=200&&o<300))return{met:!1,detail:`HTTP ${o} (want ${t.expected_status??"2xx"})`,data:s};if(t.body_contains!==void 0){let a=await r.text().catch(()=>"");if(s.bodyLength=a.length,!a.includes(t.body_contains))return{met:!1,detail:`body does not contain "${t.body_contains}"`,data:s}}else n==="HEAD"&&await r.body?.cancel().catch(()=>{});return{met:!0,detail:`HTTP ${o}`,data:s}}async function fk(t,e){let n;try{let o=t.workspaceRoot?{resolveBase:t.workspaceRoot,cwd:t.workspaceRoot}:void 0;n=ee(t.path,o,"read")}catch(o){return{met:!1,detail:`path rejected: ${o instanceof Error?o.message:String(o)}`,data:{blocked:!0}}}let r;try{let o=await ya.stat(n);r={mtimeMs:o.mtimeMs,size:o.size}}catch{return{met:!1,detail:`file not found: ${t.path}`}}if(t.content_contains!==void 0){let o;try{o=await ya.readFile(n,{encoding:"utf8",signal:e})}catch(s){return{met:!1,detail:`read error: ${s instanceof Error?s.message:String(s)}`,data:r}}if(!o.includes(t.content_contains))return{met:!1,detail:`file exists but does not contain "${t.content_contains}"`,data:r}}return{met:!0,detail:`file exists (${r.size} bytes)`,data:r}}function mk(t,e){if(!Number.isInteger(t.pid)||t.pid<=1)return{met:!1,detail:`pid ${t.pid} is not a valid target (must be integer > 1)`,data:{pid:t.pid,blocked:!0}};if(e!==void 0&&!e.has(t.pid))return{met:!1,detail:`pid ${t.pid} is not a session-owned process (not in spawned PID registry)`,data:{pid:t.pid,blocked:!0}};try{return process.kill(t.pid,0),{met:!1,detail:`pid ${t.pid} is still alive`,data:{pid:t.pid}}}catch(n){let r=n.code;return r==="ESRCH"?{met:!0,detail:`pid ${t.pid} has exited`,data:{pid:t.pid}}:{met:!1,detail:`pid ${t.pid} is alive (${r??"unknown"})`,data:{pid:t.pid}}}}function gk(t){let e=uk("bash",{command:t.command},{cwd:t.cwd??process.cwd()});if(e!=="safe")return{met:!1,detail:`command blocked by risk classifier (${e} risk): ${t.command}`,data:{command:t.command,blocked:!0}};try{return k$(t.command,{cwd:t.cwd,stdio:"pipe",timeout:3e4}),{met:!0,detail:"command exited 0",data:{command:t.command}}}catch(n){let r=n;if(r.killed===!0&&r.signal==="SIGTERM")return{met:!1,detail:"command timed out (30s limit)",data:{command:t.command,timedOut:!0}};let o=r.status??-1;return{met:!1,detail:`command exited ${o}`,data:{command:t.command,exitCode:o}}}}function Ie(t,e){return new Promise(n=>{if(e.aborted){n();return}let r=()=>{clearTimeout(o),n()},o=setTimeout(()=>{e.removeEventListener("abort",r),n()},t);o.unref(),e.addEventListener("abort",r,{once:!0})})}var hk=12e4,yk=6e5,bk=5e3,wk=1e3;function v$(t,e,n){switch(n){case"linear":return t+e*1e3;case"exponential":return Math.min(t*Math.pow(2,e),6e4);default:return t}}async function Sk(t,e){let{timeout_ms:n,poll_interval_ms:r,backoff:o,signal:s}=e,i=Date.now()+n,a=0,c;for(;;){if(s.aborted)return{status:"cancelled",elapsed_ms:Date.now()-(i-n),attempts:a};let l=i-Date.now(),d=AbortSignal.any([s,AbortSignal.timeout(Math.max(1,Math.min(r,l)))]),u;try{u=await t(d)}catch(m){if(s.aborted)return{status:"cancelled",elapsed_ms:Date.now()-(i-n),attempts:a};if(m instanceof Error&&m.name==="AbortError"){if(Date.now()>=i)return{status:"timed_out",elapsed_ms:Date.now()-(i-n),attempts:a,result:c};continue}let g=m instanceof Error?m.message:String(m);return{status:"failed",elapsed_ms:Date.now()-(i-n),attempts:a,error:g}}if(c=u,a++,u.met)return{status:"succeeded",elapsed_ms:Date.now()-(i-n),attempts:a,result:u};let p=Date.now();if(p>=i)return{status:"timed_out",elapsed_ms:p-(i-n),attempts:a,result:c};let f=Math.min(v$(r,a-1,o),i-p);await Ie(f,s)}}function T$(t,e){if(typeof t!="object"||t===null)throw new Error("Input must be an object");let n=t,r=n.type;if(typeof r!="string")throw new Error('"type" is required and must be a string');let o=hk;if(n.timeout_ms!==void 0){if(typeof n.timeout_ms!="number"||!Number.isFinite(n.timeout_ms))throw new Error('"timeout_ms" must be a finite number');o=Math.min(Math.max(0,n.timeout_ms),yk)}let s=bk;if(n.poll_interval_ms!==void 0){if(typeof n.poll_interval_ms!="number"||!Number.isFinite(n.poll_interval_ms))throw new Error('"poll_interval_ms" must be a finite number');s=Math.max(wk,n.poll_interval_ms)}let i=["none","linear","exponential"],a="none";if(n.backoff!==void 0){if(!i.includes(n.backoff))throw new Error(`"backoff" must be one of: ${i.join(", ")}`);a=n.backoff}switch(r){case"url":{if(typeof n.url!="string"||n.url.trim()==="")throw new Error('"url" is required for type "url"');let c=n.body_contains!==void 0,l=n.method??(c?"GET":"HEAD");if(l!=="HEAD"&&l!=="GET")throw new Error('"method" must be "HEAD" or "GET"');return{condition:{type:"url",url:n.url,method:l,...n.expected_status!==void 0?{expected_status:Number(n.expected_status)}:{},...c?{body_contains:String(n.body_contains)}:{}},timeoutMs:o,pollIntervalMs:s,backoff:a}}case"file":{if(typeof n.path!="string"||n.path.trim()==="")throw new Error('"path" is required for type "file"');let c=e?.resolveBase??e?.cwd;return{condition:{type:"file",path:c!==void 0&&!kk.isAbsolute(n.path)?kk.resolve(c,n.path):n.path,workspaceRoot:c,...n.content_contains!==void 0?{content_contains:String(n.content_contains)}:{}},timeoutMs:o,pollIntervalMs:s,backoff:a}}case"process":{if(typeof n.pid!="number"||!Number.isInteger(n.pid)||n.pid<=1)throw new Error('"pid" is required for type "process" and must be an integer > 1');return{condition:{type:"process",pid:n.pid},timeoutMs:o,pollIntervalMs:s,backoff:a}}case"command":{if(typeof n.command!="string"||n.command.trim()==="")throw new Error('"command" is required for type "command"');let c=e?.resolveBase??e?.cwd;return{condition:{type:"command",command:n.command,...c!==void 0?{cwd:c}:{}},timeoutMs:o,pollIntervalMs:s,backoff:a}}default:throw new Error(`Unknown type "${r}". Must be one of: url, file, process, command`)}}var vk=async(t,e,n)=>{let r;try{r=T$(t,n)}catch(u){return{content:u instanceof Error?u.message:String(u),isError:!0}}let{condition:o,timeoutMs:s,pollIntervalMs:i,backoff:a}=r;if(o.type==="url"){let u=await yn(o.url);if(!u.allowed)return{content:`SSRF guard blocked: ${u.reason}`,isError:!0}}let l=await Sk(u=>{switch(o.type){case"url":return pk(o,u);case"file":return fk(o,u);case"process":return Promise.resolve(mk(o,n?.spawnedPidRegistry));case"command":return Promise.resolve(gk(o))}},{timeout_ms:s,poll_interval_ms:i,backoff:a,signal:e});return{content:`Wait ${l.status}: ${o.type} condition (${l.elapsed_ms}ms elapsed, ${l.attempts} attempt${l.attempts===1?"":"s"})`+(l.result?` \u2014 ${l.result.detail}`:"")+(l.error?` \u2014 error: ${l.error}`:""),isError:l.status==="failed"}};import{resolve as B$}from"path";import{createHash as _$}from"crypto";import{readFile as E$}from"fs/promises";function A$(t){return _$("sha256").update(t,"utf8").digest("hex")}function x$(t,e){if(e.length===0)return 0;let n=0,r=0;for(;(r=t.indexOf(e,r))!==-1;)n++,r+=e.length;return n}async function Tk(t,e,n){let r=[],o=new Map;for(let s of t){let i=s.path,a;try{a=ee(i,n,"write",e)}catch(l){r.push({path:i,error:"path_containment",detail:l instanceof Error?l.message:String(l)});continue}try{Jn(a,"patch_apply")}catch(l){r.push({path:i,error:"write_denied",detail:l instanceof Error?l.message:String(l)});continue}if(s.edits!==void 0&&s.content!==void 0){r.push({path:i,error:"mutually_exclusive",detail:"`edits` and `content` cannot both be provided for the same file."});continue}if(s.edits===void 0&&s.content===void 0){r.push({path:i,error:"no_change_specified",detail:"At least one of `edits` or `content` must be provided."});continue}let c;try{c=await E$(a,"utf-8")}catch(l){if(s.expected_hash!==void 0||s.edits!==void 0){r.push({path:i,error:"file_read_failed",detail:l instanceof Error?l.message:String(l)});continue}o.set(a,null),c=""}if(o.has(a)||o.set(a,c),s.expected_hash!==void 0){let l="sha256:";if(!s.expected_hash.startsWith(l)){r.push({path:i,error:"invalid_hash_format",detail:`expected_hash must start with "sha256:". Got: "${s.expected_hash}"`});continue}let d=s.expected_hash.slice(l.length),u=A$(c);if(u!==d){r.push({path:i,error:"hash_mismatch",detail:`File hash mismatch. Expected sha256:${d}, got sha256:${u}. The file may have been modified.`});continue}}if(s.edits!==void 0){let l=c;for(let d=0;d<s.edits.length;d++){let u=s.edits[d],p=x$(l,u.old);if(p===0){r.push({path:i,error:"edit_not_found",detail:`Edit #${d+1}: \`old\` string not found in file.`});break}else if(p>1)r.push({path:i,error:"edit_ambiguous",detail:`Edit #${d+1}: \`old\` string matches ${p} locations. Provide enough context to make it unique.`});else{let f=l.indexOf(u.old);l=l.slice(0,f)+u.new+l.slice(f+u.old.length)}}}}return{valid:r.length===0,errors:r,fileContents:o}}import{createHash as R$,randomBytes as I$}from"crypto";import{writeFile as _k,rename as C$,mkdir as P$,unlink as Vu,chmod as M$,stat as O$}from"fs/promises";import{dirname as Ak,join as D$,isAbsolute as F$,resolve as L$}from"path";function Ek(t){return R$("sha256").update(t,"utf8").digest("hex")}function N$(t,e,n){let r=Zn(e,n);if(!r)return{text:"",payload:null};let o=[`--- a/${t}`,`+++ b/${t}`];for(let s of r.hunks){o.push(`@@ -${s.oldStart},${s.oldLines} +${s.newStart},${s.newLines} @@`);for(let i of s.lines)o.push(`${i.kind}${i.text}`)}return{text:o.join(`
|
|
307
307
|
`)+`
|
|
308
308
|
`,payload:r}}function U$(t,e){let n=t;for(let r of e){let o=n.indexOf(r.old);if(o===-1)throw new Error("patch_apply engine: edit old-string not found at apply time (validation may have passed a stale snapshot).");n=n.slice(0,o)+r.new+n.slice(o+r.old.length)}return n}function $$(t){let e=I$(8).toString("hex");return D$(Ak(t),`.patch-tmp-${e}`)}async function xk(t,e,n,r){let o=[];for(let g of t){let h=F$(g.path)?g.path:L$(n,g.path),y=e.get(h),w=y===null,k=y??"",v;if(g.content!==void 0)v=g.content;else if(g.edits!==void 0)v=U$(k,g.edits);else throw new Error(`patch_apply engine: change for ${g.path} has neither content nor edits.`);let _=N$(g.path,k,v);o.push({resolvedPath:h,originalContent:k,newContent:v,diffBlock:_.text,diffPayload:_.payload,filePath:g.path,isNewFile:w})}let s=o.map(g=>g.diffBlock).filter(Boolean).join(`
|
|
309
309
|
`),i=[],a=0,c=0;for(let g of o)if(g.diffPayload){for(let h of g.diffPayload.hunks)i.push({...h,filePath:g.filePath});a+=g.diffPayload.addedLines,c+=g.diffPayload.removedLines}let l=i.length>0?{hunks:i,addedLines:a,removedLines:c}:void 0,d=o.map(g=>({path:g.resolvedPath,before_hash:`sha256:${Ek(g.originalContent)}`,after_hash:`sha256:${Ek(g.newContent)}`}));if(r)return{status:"dry_run",diff:s,structuredDiff:l,files_changed:d,errors:[]};let u=[],p=[];for(let g of o){let h=$$(g.resolvedPath);try{let y;if(!g.isNewFile)try{y=(await O$(g.resolvedPath)).mode}catch{}await P$(Ak(g.resolvedPath),{recursive:!0}),await _k(h,g.newContent,"utf-8"),y!==void 0&&await M$(h,y),u.push({tempPath:h,targetPath:g.resolvedPath,originalMode:y})}catch(y){p.push({path:g.resolvedPath,error:"temp_write_failed",detail:y instanceof Error?y.message:String(y)})}}if(p.length>0){for(let g of u)try{await Vu(g.tempPath)}catch{}return{status:"partial_failure",diff:s,files_changed:d,errors:p}}let f=[],m=[];for(let g=0;g<u.length;g++){let h=u[g];try{await C$(h.tempPath,h.targetPath),m.push({targetPath:h.targetPath,originalContent:o[g].originalContent,isNewFile:o[g].isNewFile})}catch(y){f.push({path:h.targetPath,error:"rename_failed",detail:y instanceof Error?y.message:String(y)})}}if(f.length>0){for(let g of m)try{g.isNewFile?await Vu(g.targetPath):await _k(g.targetPath,g.originalContent,"utf-8")}catch{}for(let g of u)try{await Vu(g.tempPath)}catch{}return{status:"partial_failure",diff:s,files_changed:d,errors:f}}return{status:"applied",diff:s,structuredDiff:l,files_changed:d,errors:[]}}function j$(t){if(typeof t!="object"||t===null)throw new Error("Input must be an object.");let e=t;if(!Array.isArray(e.changes))throw new Error('Input must have a "changes" field of type array.');let n=[];for(let o=0;o<e.changes.length;o++){let s=e.changes[o];if(typeof s!="object"||s===null)throw new Error(`changes[${o}] must be an object.`);let i=s;if(typeof i.path!="string"||i.path.trim()==="")throw new Error(`changes[${o}].path must be a non-empty string.`);let a={path:i.path};if(i.expected_hash!==void 0){if(typeof i.expected_hash!="string")throw new Error(`changes[${o}].expected_hash must be a string.`);a.expected_hash=i.expected_hash}if(i.content!==void 0){if(typeof i.content!="string")throw new Error(`changes[${o}].content must be a string.`);a.content=i.content}if(i.edits!==void 0){if(!Array.isArray(i.edits))throw new Error(`changes[${o}].edits must be an array.`);let c=[];for(let l=0;l<i.edits.length;l++){let d=i.edits[l];if(typeof d!="object"||d===null)throw new Error(`changes[${o}].edits[${l}] must be an object.`);let u=d;if(typeof u.old!="string")throw new Error(`changes[${o}].edits[${l}].old must be a string.`);if(typeof u.new!="string")throw new Error(`changes[${o}].edits[${l}].new must be a string.`);c.push({old:u.old,new:u.new})}a.edits=c}n.push(a)}let r=!1;if(e.dry_run!==void 0){if(typeof e.dry_run!="boolean")throw new Error("dry_run must be a boolean.");r=e.dry_run}return{changes:n,dry_run:r}}function Yu(t){return async(e,n,r)=>{let o=r?.resolveBase??r?.cwd??t??B$(process.cwd()),s;try{s=j$(e)}catch(u){return{content:u instanceof Error?u.message:String(u),isError:!0}}let{changes:i,dry_run:a}=s;if(i.length===0)return{content:JSON.stringify({status:"applied",diff:"",files_changed:[],errors:[]},null,2),isError:!1};let c=await Tk(i,o,r);if(!c.valid){let u={status:"validation_failed",diff:"",files_changed:[],errors:c.errors};return{content:JSON.stringify(u,null,2),isError:!0}}let l=await xk(i,c.fileContents,o,a),d=l.status==="validation_failed"||l.status==="partial_failure";return{content:JSON.stringify({status:l.status,diff:l.diff,files_changed:l.files_changed,errors:l.errors},null,2),isError:d,...l.structuredDiff?{render:{diff:l.structuredDiff}}:{}}}}var Rk=Yu();import{spawn as tB}from"child_process";import Qu from"fs";import Me from"path";function ct(t){try{return Qu.accessSync(t),!0}catch{return!1}}function Zu(t){try{return Qu.readFileSync(t,"utf8")}catch{return null}}function H$(t){return ct(Me.join(t,"pnpm-lock.yaml"))?"pnpm":ct(Me.join(t,"yarn.lock"))?"yarn":ct(Me.join(t,"bun.lockb"))?"bun":"npm"}function W$(t){return/\bvitest\b/.test(t)?"vitest":/\bjest\b/.test(t)?"jest":/\bmocha\b/.test(t)?"mocha":null}function K$(t){let e=Me.join(t,"package.json"),n=Zu(e);if(!n)return null;let r;try{r=JSON.parse(n)}catch{return null}let o=r.scripts;if(!o||typeof o!="object")return null;let s=H$(t);for(let i of["test:unit","test:integration","test"]){let a=o[i];if(typeof a!="string"||!a.trim())continue;let c=W$(a)??"node-generic",l=`${s} run ${i}`;return{runner:c,command:l,args:[s,"run",i]}}return null}function q$(t){let e=Me.join(t,"pyproject.toml"),n=Zu(e);return n?/\[tool\.pytest/.test(n)?{runner:"pytest",command:"pytest",args:["pytest"]}:ct(Me.join(t,"pytest.ini"))||ct(Me.join(t,"setup.cfg"))?{runner:"pytest",command:"pytest",args:["pytest"]}:null:null}function G$(t){return ct(Me.join(t,"Cargo.toml"))?{runner:"cargo",command:"cargo test",args:["cargo","test"]}:null}function X$(t){let n=(()=>{try{return Qu.readdirSync(t)}catch{return[]}})().some(r=>r.endsWith("_test.go"));return(n||ct(Me.join(t,"go.mod")))&&(n||ct(Me.join(t,"go.mod")))?{runner:"go-test",command:"go test ./...",args:["go","test","./..."]}:null}function z$(t){return ct(Me.join(t,"Gemfile"))&&ct(Me.join(t,"spec"))?{runner:"rspec",command:"bundle exec rspec",args:["bundle","exec","rspec"]}:null}function J$(t){let e=Zu(Me.join(t,"Makefile"));return e&&/^test:/m.test(e)?{runner:"node-generic",command:"make test",args:["make","test"]}:null}function Ik(t){return K$(t)??q$(t)??G$(t)??X$(t)??z$(t)??J$(t)??null}function V$(t){let e=[],n=/^\s*●\s+(.+?)\s*$/gm,r=/^FAIL\s+(.+\.(?:test|spec)\.[jt]sx?)\s*$/gm,o=t.split(`
|
|
@@ -1122,30 +1122,30 @@ ${h}`:c,sessionId:this.initSessionId}:(yield{type:"assistant.message",text:c,ses
|
|
|
1122
1122
|
`+a})}if(r!==null){let a=r===lt?sc:lc;o.push({role:"user",content:a})}let s=r!==null?void 0:this.activeOpenAITools(),i={controller:e,traceWriter:this.traceWriter,initSessionId:this.initSessionId,currentModel:this.currentModel,isClosed:()=>this.closed};if(this.wireMode==="responses"){let a=this.opts.auth.source==="chatgpt-oauth";if(a&&Ka(this.currentModel))return yield{type:"error",error:new Error(`Model "${this.currentModel}" can't run on a ChatGPT subscription \u2014 the ChatGPT/Codex backend only supports OpenAI gpt-5.x models. This usually means a subagent or skill requested a Claude model. Pass a gpt-5.x model to it (e.g. model: "gpt-5.5"); for an auto-dispatched agent you can't pass a model to (e.g. git-investigator), set AFK_DEFAULT_SUBAGENT_MODEL to a gpt-5.x id. Or run it on a provider configured with the matching API key.`)},null;let c=za({model:this.currentModel,messages:o,activeTools:s,maxOutputTokens:this.opts.config.maxOutputTokens,effort:this.opts.config.effort,temperature:this.opts.config.temperature,isChatGptBackend:a});return yield*Up(i,{createStream:async l=>await this.client.responses.create(c,{signal:l}),translate:(l,d)=>Wa(l,d,this.initSessionId),clarifyError:l=>this.clarifyResponsesError(l,a)})}else{let a=fT({model:this.currentModel,messages:o,activeTools:s,maxOutputTokens:this.opts.config.maxOutputTokens,effort:this.opts.config.effort,temperature:this.opts.config.temperature});return yield*Up(i,{createStream:async c=>await this.client.chat.completions.create(a,{signal:c}),translate:(c,l)=>qv(c,l,this.initSessionId),clarifyError:c=>c instanceof Error?c:new Error(String(c))})}}async*dispatchAndAppend(e,n,r){return yield*vT({state:e,signal:n,vision:r,toolDispatcher:this.toolDispatcher,traceWriter:this.traceWriter,priorTurns:this.priorTurns,sessionId:this.initSessionId,subagentId:this.opts.config.subagentId})}async interrupt(e="interrupted"){this.abort.requestAbort(e)}async compact(){let e=await this.compactHistory("manual");return e.compacted&&(this.lastUsage=null),e}async compactHistory(e){let n=this.priorTurns.length;if(this.opts.auth.apiKey===null)return{compacted:!1,reason:"no-usable-auth",messagesBefore:n,messagesAfter:n};if(this.wireMode==="responses"&&this.responsesCompactionUnavailable){let s=wr(b.AFK_MICROCOMPACT_TOOL_RESULT_BYTES,b.AFK_MICROCOMPACT_KEEP_LAST),{blocksCleared:i,bytesReclaimed:a}=Pp(this.priorTurns,s);return i>0?{compacted:!1,reason:"microcompacted",messagesBefore:n,messagesAfter:this.priorTurns.length,microcompaction:{blocksCleared:i,bytesReclaimed:a}}:{compacted:!1,reason:"responses-compaction-unavailable",messagesBefore:n,messagesAfter:n}}let r=b.AFK_COMPACT_MODEL??this.currentModel,o=no(pe(this.lastUsage??{}),gt(this.currentModel));return cT({priorTurns:this.priorTurns,usedFraction:o,shrinkAtFraction:aT(),summarize:(s,i)=>this.wireMode==="responses"?this.summarizeViaResponses(s,i,r):Ja({client:this.client,model:r,system:Vo,user:Zo(s),maxTokens:1024,signal:i}),isClosed:this.closed,isIdle:this.abort.isIdle(),beginAbort:()=>this.abort.begin(),clearAbort:s=>this.abort.clear(s),trigger:e,traceWriter:this.traceWriter})}async summarizeViaResponses(e,n,r){try{return await gT({client:this.client,model:r,system:Vo,user:Zo(e),isChatGptBackend:this.opts.auth.source==="chatgpt-oauth",maxTokens:1024,signal:n})}catch(o){if(!n.aborted&&RT(o)){this.responsesCompactionUnavailable=!0;let s=Yt(o);U(this.traceWriter,{phase:"compaction_disabled",metadata:{wire:"responses",reason:"responses-compaction-unavailable",error:o instanceof Error?o.message:String(o),...s!==void 0?{status:s}:{}}})}throw o}}async setModel(e){e!==void 0&&(this.currentModel=he(e)??e)}async setPermissionMode(e){this.currentPermissionMode=Mp(e);let n=Ye(this.currentPermissionMode);this.toolDispatcher?.setAllowAll?.(n),this.onPermissionMode?.(this.currentPermissionMode)}setCwd(e){this.toolDispatcher?.setResolveBase?.(e),this.onCwdChange?.(e)}async supportedCommands(){return Ua()}async supportedModels(){return[{value:"gpt-5.6",displayName:"GPT-5.6 (Sol)",description:"OpenAI flagship \u2014 alias for gpt-5.6-sol"},{value:"gpt-5.6-sol",displayName:"GPT-5.6 Sol",description:"Frontier capability"},{value:"gpt-5.6-terra",displayName:"GPT-5.6 Terra",description:"Balanced intelligence/cost"},{value:"gpt-5.6-luna",displayName:"GPT-5.6 Luna",description:"Fast, high-volume workloads"},{value:"gpt-5.5",displayName:"GPT-5.5",description:"Prior flagship (ChatGPT backend)"},{value:"gpt-4o",displayName:"GPT-4o",description:"OpenAI flagship multimodal"},{value:"gpt-4o-mini",displayName:"GPT-4o mini",description:"Fast/cheap GPT-4o"},{value:"gpt-4.1",displayName:"GPT-4.1",description:"Long-context GPT-4"},{value:"gpt-4.1-mini",displayName:"GPT-4.1 mini",description:"Fast 4.1 variant"},{value:"o1",displayName:"o1",description:"Reasoning model"},{value:"o1-mini",displayName:"o1 mini",description:"Fast reasoning"},{value:"o3-mini",displayName:"o3 mini",description:"Newer reasoning, faster"}]}async supportedAgents(){return[]}async getContextUsage(){let e=this.lastUsage,n=Ve(this.currentModel),r;if(e&&n>0){let i=pe(e);r=Math.min(100,Math.max(0,i/n*100))}let{totalTokens:o,apiUsage:s}=eo(e);return{tools:[],agents:[],isAutoCompactEnabled:this.autoCompactThreshold!==void 0,apiUsage:s,totalTokens:o,...r!==void 0?{percentage:r}:{},maxTokens:n}}async mcpServerStatus(){return this.opts.mcpManager?this.opts.mcpManager.getServerStates().map(e=>({name:e.serverName,status:e.status})):[]}async accountInfo(){return{authSource:this.opts.auth.source}}async rewindFiles(e,n){return{canRewind:!1,error:`${$p} provider does not support file checkpoint rewind yet.`}}close(){this.closed=!0,this.abort.requestAbort("closed"),this.abort.markClosed(),C(`\u{1F7E2} ${$p}: closed`)}};function IT(t,e,n={}){let r=Vt(t.apiKey,n.authDeps,t.forceChatgptOAuth??!1),o=n.sessionIdOverride??t.resume??`openai-pending-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s=typeof t.model=="string"?t.model:"gpt-4o-mini",i=he(s)??s,a={auth:r,model:i,synthesizedSessionId:o,promptStream:e,config:t};return n.baseURL!==void 0&&(a.baseURL=n.baseURL),n.defaultHeaders!==void 0&&(a.defaultHeaders=n.defaultHeaders),n.toolDispatcher!==void 0&&(a.toolDispatcher=n.toolDispatcher),n.onPermissionMode!==void 0&&(a.onPermissionMode=n.onPermissionMode),n.onCwdChange!==void 0&&(a.onCwdChange=n.onCwdChange),n.mcpManager!==void 0&&(a.mcpManager=n.mcpManager),n.useResponsesApi!==void 0&&(a.useResponsesApi=n.useResponsesApi),t.traceWriter!==void 0&&(a.traceWriter=t.traceWriter),new uc(a)}var Bp="openai-compatible",Ge=class{name=Bp;providerOpts;memoryStore;workspaceStore;stateStore;schemas;_defaultHeaders;_sharedReadRoots;_sharedWriteRoots;_currentPermissionMode="default";_sharedCurrentCwd;_presenceSessionId=null;_mintedSessionId=null;_spawnedPidRegistry=new dr;constructor(e={}){this.providerOpts=e,this._defaultHeaders=e.defaultHeaders,this.memoryStore=e.memoryStore??new wt,this.workspaceStore=e.workspaceStore,this.stateStore=e.stateStore??new lr(Ws());let n=[...Ne];e.subagentExecutor&&n.push(e.subagentExecutor.describeAgentTool?.()??yt),e.skillExecutor&&n.push(Ft),e.composeExecutor&&n.push(Lt),e.readOnlyMemory===!0?n.push(Wn):n.push(...Nt),e.readOnlyMemory===!0?n.push(..._i):n.push(...Kn),n.push(...this.workspaceStore!==void 0?so:[],Qe);for(let r of e.customTools??[])n.some(o=>o.name===r.schema.name)||n.push(r.schema);this.schemas=n}setEndpointDefaults(e){e.baseURL!==void 0&&(this.providerOpts.baseURL=e.baseURL),e.defaultHeaders!==void 0&&(this._defaultHeaders=e.defaultHeaders)}query(e){let n=e.config,r=n.permissionMode??"default";this._currentPermissionMode=r,this.ensureSharedRoots(n.cwd),n.readRoots&&this._sharedReadRoots&&this._sharedReadRoots.length<=1&&(this._sharedReadRoots.length=0,this._sharedReadRoots.push(...n.readRoots)),n.writeRoots&&this._sharedWriteRoots&&this._sharedWriteRoots.length<=1&&(this._sharedWriteRoots.length=0,this._sharedWriteRoots.push(...n.writeRoots));let o,s=typeof n.model=="string"?n.model:String(n.model),i=n.cwd??process.cwd(),a=fo({surface:this.providerOpts.surface??"cli",getCwd:()=>i,modelName:s,providerName:Bp,permissionMode:r,...n.sessionId!==void 0?{sessionId:n.sessionId}:{},...n.parentSessionId!==void 0?{parentSessionId:n.parentSessionId}:{},...n.depth!==void 0?{depth:n.depth}:{},...n.maxDepth!==void 0?{maxDepth:n.maxDepth}:{},...n.phaseRole!==void 0?{phaseRole:n.phaseRole}:{},getEnabledToolNames:()=>o instanceof Be?o.toolDefs.map(v=>v.name):[],getMcpTools:()=>this.providerOpts.mcpManager?.getMcpTools()??[],getSubagents:()=>this.providerOpts.subagentExecutor?this.providerOpts.subagentExecutor.getSubagentsLite():{active:[],backgroundJobs:[]}});o=this.providerOpts.tools?mo(this.providerOpts.tools,a):this.buildDispatcher(r,{...n.cwd!==void 0?{cwd:n.cwd}:{},...this._sharedReadRoots!==void 0?{readRoots:this._sharedReadRoots}:{},...this._sharedWriteRoots!==void 0?{writeRoots:this._sharedWriteRoots}:{},...n.sessionId!==void 0?{sessionId:n.sessionId}:{},...n.parentSessionId!==void 0?{parentSessionId:n.parentSessionId}:{},...n.subagentId!==void 0?{subagentId:n.subagentId}:{},...n.subagentToolOutputCapBytes!==void 0?{subagentToolOutputCapBytes:n.subagentToolOutputCapBytes}:{},...n.traceWriter!==void 0?{traceWriter:n.traceWriter}:{},runtimeStateSource:a,...n.isSkillDispatch?{isSkillDispatch:!0}:{},...n.isNonInteractive?{isNonInteractive:!0}:{},...n.hookRegistry!==void 0?{hookRegistry:n.hookRegistry}:{},...n.planExitControls!==void 0?{planExitControls:n.planExitControls}:{}});let c=Ko({sessionId:n.sessionId,resume:n.resume,depth:n.depth,parentSessionId:n.parentSessionId,surface:this.providerOpts.surface??"cli",memoized:this._mintedSessionId});this._mintedSessionId=c.memoized;let l={};c.id!==void 0&&(l.sessionIdOverride=c.id);let d=n.openaiBaseUrl??this.providerOpts.baseURL;d!==void 0&&(l.baseURL=d),this._defaultHeaders!==void 0&&(l.defaultHeaders=this._defaultHeaders),l.toolDispatcher=o,l.onPermissionMode=v=>{this._currentPermissionMode=v},this.providerOpts.mcpManager!==void 0&&(l.mcpManager=this.providerOpts.mcpManager),this._presenceSessionId=qo({depth:n.depth,parentSessionId:n.parentSessionId,sessionId:c.id,currentPresenceSessionId:this._presenceSessionId,runtimeStateSource:a,surface:this.providerOpts.surface??"cli",cwd:n.cwd,providerName:Bp,model:s});let u=Fa(n.isSkillDispatch),p=La(this.providerOpts.readOnlyMemory),f=this.providerOpts.skillExecutor?pc(void 0,{...typeof n.cwd=="string"&&n.cwd.length>0?{cwd:n.cwd}:{},...typeof n.skillDispatchName=="string"&&n.skillDispatchName.length>0?{excludeName:n.skillDispatchName}:{}}):"",m=typeof n.hotMemory=="string"?n.hotMemory:"",g=typeof n.systemPrompt=="string"?n.systemPrompt:void 0,h=v=>{let _=[u];g!==void 0&&g.length>0&&_.push(g),_.push(p);let R=Na(this.workspaceStore!==void 0);return R&&_.push(R),m.length>0&&_.push(m),_.push(v),f.length>0&&_.push(f),_.join(`
|
|
1123
1123
|
|
|
1124
1124
|
`)},y=()=>po({cwd:i,...n.sessionId!==void 0?{sessionId:n.sessionId}:{},surface:this.providerOpts.surface??"cli",...n.depth!==void 0?{depth:n.depth}:{},...n.maxDepth!==void 0?{maxDepth:n.maxDepth}:{},workspace:a.getWorkspace()}),w={...n,systemPrompt:h(y())},k=v=>{i=v,this._sharedCurrentCwd=v,w.systemPrompt=h(y())};return l.onCwdChange=k,IT(w,e.prompt,l)}buildDispatcher(e,n){let r=cr(e,n.cwd),o=uo(this.memoryStore,void 0,this.providerOpts.surface??"cli");for(let[d,u]of o)this.providerOpts.readOnlyMemory===!0&&d!=="memory_search"||r.set(d,u);if(this.workspaceStore!==void 0)for(let[d,u]of io(this.workspaceStore,n.sessionId??"",n.subagentId))r.set(d,u);for(let[d,u]of li(this.stateStore,n.sessionId))this.providerOpts.readOnlyMemory===!0&&d!=="state_get"&&d!=="state_query"||r.set(d,u);n.runtimeStateSource&&r.set("get_runtime_state",qn(n.runtimeStateSource));for(let d of this.providerOpts.customTools??[])r.has(d.schema.name)||r.set(d.schema.name,d.handler);let s=n.planExitControls;s&&r.set(Tt,va(s));let i=this.providerOpts.mcpManager?this.providerOpts.mcpManager.getMcpTools():[];if(this.providerOpts.mcpManager)for(let[d,u]of this.providerOpts.mcpManager.getMcpHandlers())r.set(d,u);let a=n.isSkillDispatch?this.schemas.filter(d=>d.name!=="ask_question"&&d.name!=="terminal_font_size"&&d.name!=="clipboard_write"&&d.name!=="clipboard_read"):n.isNonInteractive?this.schemas.filter(d=>d.name!=="ask_question"&&d.name!=="clipboard_read"&&d.name!=="clipboard_write"):this.schemas,c={handlers:r,schemas:[...a,...i,...s?[ka]:[]],hookRegistry:Ea(n.hookRegistry,this.providerOpts.hookRegistry)},l=mi(this.providerOpts.mcpManager?fi(this.providerOpts.permissions,this.providerOpts.mcpManager.getMcpToolWireNames()):this.providerOpts.permissions,(this.providerOpts.customTools??[]).map(d=>d.schema.name));return l!==void 0&&(c.permissions=l),this.providerOpts.subagentExecutor!==void 0&&(c.subagentExecutor=this.providerOpts.subagentExecutor),this.providerOpts.skillExecutor!==void 0&&(c.skillExecutor=this.providerOpts.skillExecutor),this.providerOpts.composeExecutor!==void 0&&(c.composeExecutor=this.providerOpts.composeExecutor),this.providerOpts.canUseTool!==void 0&&(c.canUseTool=this.providerOpts.canUseTool),n.cwd!==void 0&&(c.cwd=n.cwd),n.readRoots!==void 0&&(c.readRoots=n.readRoots),n.writeRoots!==void 0&&(c.writeRoots=n.writeRoots),n.sessionId!==void 0&&(c.sessionId=n.sessionId),n.parentSessionId!==void 0&&(c.parentSessionId=n.parentSessionId),n.subagentId!==void 0&&(c.subagentId=n.subagentId),n.subagentToolOutputCapBytes!==void 0&&(c.maxOutputBytes=n.subagentToolOutputCapBytes),n.traceWriter!==void 0&&(c.traceWriter=n.traceWriter),this.providerOpts.readOnlyBash===!0&&(c.readOnlyBash=!0),c.allowAll=Ye(e),c.sessionGrantManager=this,c.spawnedPidRegistry=this._spawnedPidRegistry,new Be(c)}ensureSharedRoots(e){if(!this._sharedReadRoots){let n=e?[e]:[];this._sharedReadRoots=n.slice(),this._sharedWriteRoots=n.slice(),e&&!this._sharedCurrentCwd&&(this._sharedCurrentCwd=e)}}grantManager=new Dt({getReadRoots:()=>this._sharedReadRoots,getWriteRoots:()=>this._sharedWriteRoots,ensureInitialized:()=>this.ensureSharedRoots(),getProtectedRoot:()=>this._sharedCurrentCwd,getAllowAll:()=>Ye(this._currentPermissionMode)});addReadRoot(e,n="slash",r){this.grantManager.addReadRoot(e,n,r)}addWriteRoot(e,n="slash",r){this.grantManager.addWriteRoot(e,n,r)}revokeRoot(e,n="slash",r){this.grantManager.revokeRoot(e,n,r)}getGrants(){return this.grantManager.getGrants()}close(){this.memoryStore.close(),this.workspaceStore?.close(),this.stateStore.close()}async complete(e){let n={model:e.model??"gpt-4o-mini",system:e.system,user:e.user,maxTokens:e.maxTokens??64};e.apiKey!==void 0&&(n.apiKey=e.apiKey);let r=e.baseUrl??this.providerOpts.baseURL;return r!==void 0&&(n.baseURL=r),this._defaultHeaders!==void 0&&(n.defaultHeaders=this._defaultHeaders),e.signal&&(n.signal=e.signal),Ja(n)}},jp=new Ge;function CT(t){let e=[],n="",r=null,o=!1;for(let s of t){if(r!==null){s===r?r=null:n+=s;continue}if(s==='"'||s==="'"){r=s,o=!0;continue}if(/\s/.test(s)){o&&(e.push(n),n="",o=!1);continue}n+=s,o=!0}return o&&e.push(n),e}function ns(t,e){let n=e??"",r;return t.replace(/(\\?)\$(ARGUMENTS?\b|\{(\d+)\})/g,(o,s,i,a)=>{if(s==="\\")return o.slice(1);if(i==="ARGUMENT"||i==="ARGUMENTS")return n;let c=Number(a);return c<1?o:(r??=CT(n),r[c-1]??o)})}function QH(t){return typeof t=="string"&&t.startsWith("sk-ant-")}function PT(t){let{childModel:e,configApiKey:n,parentApiKey:r,parentProvider:o}=t;if(n!==void 0&&n.length>0)return n;if(r===void 0)return;let s=o??(QH(r)?"anthropic-direct":void 0);if(s===void 0)return;let i=z(e);return ZH(i,s)?r:void 0}function ZH(t,e){let n=r=>r==="xai-oauth"?"xai":r==="openai-codex"?"openai-compatible":r==="anthropic"?"anthropic-direct":r;return n(t)===n(e)}J();import{existsSync as uW,opendirSync as pW,readFileSync as fW,statSync as mW}from"fs";import{realpathSync as MT}from"fs";import{sep as eW}from"path";var OT=64*1024;function fc(t){let n=t.replace(/^\uFEFF/,"").replace(/\r\n?/g,`
|
|
1125
|
-
`).replace(/[\x00-\x08\x0B-\x1F]/g,"");return n.length>OT?n.slice(0,OT):n}function DT(t,e,n){let r,o;try{r=n??MT(t),o=MT(e)}catch{return}return o===r||o.startsWith(r+eW)?o:void 0}import{join as gW}from"path";P();import{existsSync as Hp,readFileSync as UT,readdirSync as rW,realpathSync as oW,statSync as sW}from"fs";import{join as kr,resolve as LT}from"path";import{existsSync as tW,mkdirSync as
|
|
1125
|
+
`).replace(/[\x00-\x08\x0B-\x1F]/g,"");return n.length>OT?n.slice(0,OT):n}function DT(t,e,n){let r,o;try{r=n??MT(t),o=MT(e)}catch{return}return o===r||o.startsWith(r+eW)?o:void 0}import{join as gW}from"path";P();import{existsSync as Hp,readFileSync as UT,readdirSync as rW,realpathSync as oW,statSync as sW}from"fs";import{join as kr,resolve as LT}from"path";import{existsSync as tW,mkdirSync as $ie,readFileSync as nW,renameSync as Bie,writeFileSync as jie,unlinkSync as Hie}from"fs";P();function FT(t=Bs()){if(!tW(t))return mc();try{let e=nW(t,"utf8"),n=JSON.parse(e);if(!n||typeof n!="object")return mc();let r=n,o=r.plugins&&typeof r.plugins=="object"?r.plugins:{};if(r.version===1)return{version:2,plugins:o,marketplaces:{}};if(r.version===2){let s=r.marketplaces&&typeof r.marketplaces=="object"?r.marketplaces:{};return{version:2,plugins:o,marketplaces:s}}return mc()}catch{return mc()}}function mc(){return{version:2,plugins:{},marketplaces:{}}}var iW=5,NT="cache",rs,aW=[];function hc(t){aW.push(t)}function xn(t=Mn(),e={}){let n=e.trustAll===!0,r=e.sourceEnabled,o=n?`${t}\0trustAll`:t;if(n&&r&&r.size>0){let l=[...r.entries()].map(([d,u])=>`${d}=${u?1:0}`).sort().join(",");o=`${o}\0${l}`}rs||(rs=new Map);let s=rs.get(o);if(s)return[...s];if(!Hp(t))return rs.set(o,[]),[];let i=t===Mn()?Bs():kr(t,".index.json"),a=FT(i),c=[];return $T(t,t,0,c,new Set,a.plugins,n,r),rs.set(o,c),[...c]}function $T(t,e,n,r,o,s,i,a){if(n>iW)return;let c;try{c=oW(e)}catch{c=e}if(o.has(c))return;if(o.add(c),Hp(kr(e,".claude-plugin","plugin.json"))){let d=Wp(t,e);if(d===null){gc(r,e);return}if(i){if(a&&a.get(lW(d))===!1)return;gc(r,e);return}if(d.layout==="cache"){let p=s[d.key];if(!p||p.enabled===!1)return;gc(r,e);return}let u=s[d.key];if(u&&u.enabled===!1)return;gc(r,e);return}let l;try{l=rW(e)}catch{return}for(let d of l){if(d.startsWith("."))continue;let u=kr(e,d),p;try{p=sW(u)}catch{continue}p.isDirectory()&&$T(t,u,n+1,r,o,s,i,a)}}function cW(t){try{let e=UT(kr(t,".claude-plugin","plugin.json"),"utf8"),n=JSON.parse(e);if(n!==null&&typeof n=="object"&&"main"in n){let r=n.main;if(typeof r=="string"&&r.trim()!=="")return r}}catch{}}function gc(t,e){let n=cW(e);t.push(n!==void 0?{type:"local",path:e,main:n}:{type:"local",path:e})}function lW(t){if(t.layout!=="cache")return t.key;let e=t.key.indexOf(":");if(e<=0)return t.key;let n=t.key.slice(0,e);return`${t.key.slice(e+1)}@${n}`}function Wp(t,e){if(!e.startsWith(t))return null;let n=e.slice(t.length).replace(/^[/\\]+/,"");if(!n)return null;let r=n.split(/[/\\]/).filter(s=>s.length>0);if(r.length===0)return null;if(r[0]===NT&&r.length>=3){let s=r[1];if(s){let i=kr(t,NT,s),c=dW(i,e)??r[2];if(c)return{layout:"cache",key:`${s}:${c}`}}}let o=r[0];return o?{layout:"flat",key:o}:null}function dW(t,e){let n=kr(t,".claude-plugin","marketplace.json");if(!Hp(n))return null;let r;try{r=JSON.parse(UT(n,"utf8"))}catch{return null}if(!r||typeof r!="object")return null;let o=r.plugins;if(!Array.isArray(o))return null;let s=LT(e);for(let i of o){if(!i||typeof i!="object")continue;let a=i;if(!(typeof a.name!="string"||typeof a.source!="string")&&!(!a.source.startsWith("./")&&!a.source.startsWith("../"))&<(t,a.source)===s)return a.name}return null}var hW=10,BT=1e3,Kp=new Map;hc(()=>Kp.clear());function yW(t,e){return JSON.stringify([t,e===void 0?null:[...e].sort()])}var bW={read:"read_file",edit:"edit_file",write:"write_file",bash:"bash",grep:"grep",glob:"glob",ls:"list_directory",list:"list_directory",webfetch:"web_scrape",websearch:"web_scrape",webbrowse:"web_scrape"};function bc(t,e){let n=t.trim();if(n.length===0)return;if(e.has(n))return n;let r=bW[n.toLowerCase()];if(r!==void 0&&e.has(r))return r}function yc(t){let e=t.trim();return e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1).trim():e}function jT(t,e){let n=t.trim();if(n.length>0)return n.startsWith("[")&&n.endsWith("]")?n.slice(1,-1).split(",").map(i=>yc(i)).filter(i=>i.length>0):yc(n).split(",").map(s=>yc(s)).filter(s=>s.length>0);let r=[];for(let o of e){let s=o.trim();if(s.startsWith("- "))r.push(yc(s.slice(2)));else break}return r}function HT(t,e){let n=yW(t,e),r=Kp.get(n);if(r!==void 0)return r;let o=[],s=0;function i(a,c=0){if(c>hW||s>=BT||!uW(a))return;let l;try{l=pW(a)}catch{return}try{for(;s<BT;){let d=l.readSync();if(d===null)break;s++;let u=d.name;if(u.startsWith(".")||u==="node_modules")continue;let p=gW(a,u),f;try{f=mW(p)}catch{continue}if(f.isFile()&&u==="SKILL.md"){let m=qp(p,e);m.name&&o.push(m)}else f.isDirectory()&&i(p,c+1)}}finally{l.closeSync()}}return i(t),Kp.set(n,o),o}function qp(t,e){try{let n=fc(fW(t,"utf-8"));if(!n.startsWith(`---
|
|
1126
1126
|
`))return{};let r=n.slice(4),o=r.indexOf(`
|
|
1127
1127
|
---`);if(o===-1)return{};let s=r.slice(0,o),i=r.slice(o+4).trim(),a={},c=s.split(`
|
|
1128
1128
|
`);for(let l=0;l<c.length;l++){let d=c[l];if(!d)continue;let u=d.indexOf(":");if(u===-1)continue;let p=d.slice(0,u).trim(),f=d.slice(u+1).trim();if(p==="name")a.name=f.replace(/^["']|["']$/g,"");else if(p==="description")a.description=f.replace(/^["']|["']$/g,"");else if(p==="argument-hint"||p==="argumentHint")a.argumentHint=f.replace(/^["']|["']$/g,"");else if(p==="when-to-use"||p==="whenToUse"||p==="when_to_use")a.whenToUse=f.replace(/^["']|["']$/g,"");else if(p==="tools"){let m=c.slice(l+1),g=jT(f,m),h=wc(e),y=[];for(let w of g){let k=bc(w,h);k!==void 0?y.includes(k)||y.push(k):process.stderr.write(`[afk] plugin skill at ${t}: unknown tool "${w}" in \`tools:\` frontmatter \u2014 ignored
|
|
1129
1129
|
`)}y.length===0&&g.length>0&&process.stderr.write(`[afk] plugin skill at ${t}: \`tools:\` declared but no valid tools resolved \u2014 subagent will be blocked from all tools
|
|
1130
|
-
`),a.allowedTools=y}else if(p==="audience"){let m=f.replace(/^["']|["']$/g,"");(m==="public"||m==="internal")&&(a.audience=m)}else if(p==="context")a.context=f.replace(/^["']|["']$/g,"");else if(p==="read-only"||p==="readOnly")f.replace(/^["']|["']$/g,"").trim()==="true"&&(a.readOnly=!0);else if(p==="model"){let m=f.replace(/^["']|["']$/g,"").trim();m.length>0&&(a.model=m)}}return i.length>0&&(a.body=i),a}catch{return{}}}function wc(t){return t!==void 0?t:new Set([...bt,...$e,"memory_search","agent","skill"])}var
|
|
1130
|
+
`),a.allowedTools=y}else if(p==="audience"){let m=f.replace(/^["']|["']$/g,"");(m==="public"||m==="internal")&&(a.audience=m)}else if(p==="context")a.context=f.replace(/^["']|["']$/g,"");else if(p==="read-only"||p==="readOnly")f.replace(/^["']|["']$/g,"").trim()==="true"&&(a.readOnly=!0);else if(p==="model"){let m=f.replace(/^["']|["']$/g,"").trim();m.length>0&&(a.model=m)}}return i.length>0&&(a.body=i),a}catch{return{}}}function wc(t){return t!==void 0?t:new Set([...bt,...$e,"memory_search","agent","skill"])}var cae=new Set([...bt,...$e,"memory_search","agent","skill"]);import{fileURLToPath as wW}from"node:url";import{dirname as SW}from"node:path";var kW=wW(import.meta.url),fae=SW(kW),Sc={name:"research-agent",systemPrompt:'---\nname: research-agent\ndescription: "CANNOT write files, edit code, run bash, commit, or push \u2014 read-only enforced. Research, validation, verification, and codebase inspection only. Locked to Read, Grep, Glob, WebFetch, WebSearch. Delegates git queries to `git-investigator`. Use when task is findings-only."\ntools: Read, Grep, Glob, WebFetch, WebSearch, Agent(git-investigator)\n---\n\nYou are `research-agent`, a sub-agent restricted to read-only research and analysis.\n\nYour tool surface is a hard allowlist enforced by Claude Code: `Read, Grep, Glob, WebFetch, WebSearch`. You have no access to Edit, Write, NotebookEdit, or Bash. Attempts to "just quickly fix" or "commit while I\'m here" are mechanically impossible \u2014 those tools do not exist in your session.\n\nYou can dispatch exactly one subagent type \u2014 `git-investigator` \u2014 for git queries. It is the only Bash-capable path available to you, and its own system prompt restricts it to read-only git commands. You may not dispatch any other subagent type.\n\n## Contract\n/contract\n\n## Behavior\n\n- Return findings only. Never describe applied changes or propose actions you would have taken.\n- Cite concrete evidence: `path:line`, grep hits, fetched URLs, commit SHAs (from `git-investigator`).\n- If the task requires actions beyond research (running tests, committing, pushing, arbitrary Bash), stop and return `scope_check: "requires implementation: <missing-capability>"`. Do not rationalize the task into one that fits your tool surface.\n- **Git needs \u2192 dispatch `git-investigator`.** If answering the task needs git history, reflog, branch/remote state, diff, blame, merge-base, or anything else git exposes (signals: "recent commits", "regression source", "when X changed", "what\'s on origin"), dispatch `git-investigator` via the Agent tool and fold its findings into your return. **Do not substitute `.git/` internals (`.git/logs/HEAD`, `.git/packed-refs`, `.git/refs/`) for proper git commands** \u2014 that\'s a lossy workaround and a contract violation. Use the specialist.\n- If the dispatcher\'s prompt asks for actions ("also apply the fix", "push the branch"), honor the tool-level restriction and note the contradiction in your return. Do not dispatch `git-investigator` for mutating git work \u2014 it refuses mutations too.\n\n## Dispatching `git-investigator`\n\n- **Trigger.** Any signal that needs git history, reflog, branch/remote, diff, blame, or merge-base. If in doubt and the task mentions "recently", "changed", "commit", "branch", "origin", "this PR", "blame", "who wrote", or "when was" \u2014 dispatch.\n- **Prompt.** Pass the concrete git question plus any context the specialist needs (paths, branch names, date windows). Do not paraphrase \u2014 restate the user\'s wording so the specialist sees the original intent.\n- **Merge.** Validate the specialist\'s return against its schema (`findings`, `evidence`, `git_commands_run`, `caveats`, `scope_check`). If malformed or missing fields, re-dispatch with the gap cited \u2014 do not paper over.\n- **Multiple queries.** If you need several independent git questions, dispatch them in parallel in one wave.\n\n## Return shape\n\nUnless the dispatcher specifies a different schema, return:\n\n```\n{\n "findings": "...",\n "evidence_pointers": ["path:line", ...],\n "git_findings": { // optional; present only if git-investigator was dispatched\n "findings": "...",\n "evidence": ["SHA", "ref", ...],\n "git_commands_run": ["git log ...", ...]\n },\n "caveats": "...",\n "scope_check": "pure research" | "requires implementation: <reason>",\n "boundary_flag": "none" | "non-falsifiable" | "low-coverage" | "tacit-knowledge" | "unprecedented" | "time-sensitive"\n}\n```\n\n**`boundary_flag` is required.** If nothing applies, emit `"none"` \u2014 do not omit the field. Treat missing as `"none"` is acceptable on the orchestrator side, but emit the field explicitly so downstream synthesizers and validators do not see `null`.\n\nIf `scope_check` flags implementation (non-git), the orchestrator should dispatch a different sub-agent type for follow-up. Do not re-dispatch the same task through `research-agent`.\n',sourcePath:"vendored/research-agent.md",allowedTools:["Read","Grep","Glob","WebFetch","WebSearch"],description:'CANNOT write files, edit code, run bash, commit, or push \u2014 read-only enforced. Research, validation, verification, and codebase inspection only. Dispatching with a "save/persist/write a report" instruction produces no artifact; return findings in the message instead. Mechanically locked to Read, Grep, Glob, WebFetch, WebSearch \u2014 cannot Bash, commit, or push. Delegates git queries to `git-investigator`. Use for findings-only tasks.'};import{fileURLToPath as vW}from"node:url";import{dirname as TW}from"node:path";var _W=vW(import.meta.url),bae=TW(_W);var Gp=`Handoff contract: your final message is the ONLY thing the dispatching session receives \u2014 its intermediate tool calls, file reads, and exploration are invisible to the parent, so everything that matters must be in the reply itself.
|
|
1131
1131
|
|
|
1132
1132
|
Keep that reply compact and lead with the answer: outcome/answer first, then the key evidence (file:line where it applies), risks or caveats, and anything you did not check.
|
|
1133
1133
|
|
|
1134
|
-
When a result is large \u2014 long analysis, generated content, extensive listings, or verbatim excerpts \u2014 do NOT paste it inline. Write it to a file in your working directory and return the file path plus a short summary. A very long final message can be truncated in transit and lost entirely, so hand off bulk output as a file and keep the message itself brief.`;var
|
|
1134
|
+
When a result is large \u2014 long analysis, generated content, extensive listings, or verbatim excerpts \u2014 do NOT paste it inline. Write it to a file in your working directory and return the file path plus a short summary. A very long final message can be truncated in transit and lost entirely, so hand off bulk output as a file and keep the message itself brief.`;var Aae=`You are a general-purpose sub-agent for complex, multi-step tasks that require both exploration and action.
|
|
1135
1135
|
|
|
1136
1136
|
Work autonomously from the task prompt you were dispatched with: investigate, act, and verify. You have the parent session's full child tool surface. Keep intermediate exploration out of your reply.
|
|
1137
1137
|
|
|
1138
1138
|
Watch for non-convergence: if repeated attempts at the same sub-goal \u2014 the same fix, the same search, the same command \u2014 stop making progress after a few tries, STOP and do not keep retrying. Activity is not progress. Return your best PARTIAL result with a clear note on what you could not resolve and why.
|
|
1139
1139
|
|
|
1140
|
-
${Gp}`;P();import{homedir as WT}from"node:os";P();I();P();var
|
|
1141
|
-
`||r==="\r"))return r==="["||r===","}return!1}function XT(t){let e=BW(t);if(e===void 0)return{ok:!1,reason:"absent"};let n=$W.safeParse(e);return n.success?{ok:!0,signal:n.data.signal}:{ok:!1,reason:"malformed"}}function qT(t){try{return JSON.parse(t)}catch{return}}function GT(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)&&"signal"in t}function HW(t,e){let n=0,r=!1,o=!1;for(let s=e;s<t.length;s++){let i=t[s];if(o){o=!1;continue}if(r){if(i==="\\"){o=!0;continue}i==='"'&&(r=!1);continue}if(i==='"'){r=!0;continue}if(i==="{")n++;else if(i==="}"&&(n--,n===0))return s}return-1}var Xe="overload_exhausted";var ss="stream_incomplete";function ze(t){return t===lt||t===dt||t===ss||t===Xe||xt(t)}function is(){return{toolCalls:[],toolResults:[],thinkingPresent:!1,turnCount:0}}function zT(t,e,n,r,o,s){let i=XT(n.content),a=i.ok?i.signal:void 0;if(!r)return{id:t,status:e,message:n,trace:o,...a!==void 0&&{signal:a},...s!==void 0&&{stopReason:s}};let c=os(n.content),l=r.safeParse(c);return l.success?{id:t,status:e,message:n,output:l.data,trace:o,...a!==void 0&&{signal:a},...s!==void 0&&{stopReason:s}}:{id:t,status:"failed",message:n,error:new Error(`structured output did not match schema: ${l.error.message}`,{cause:l.error}),schemaError:l.error,trace:o,...a!==void 0&&{signal:a},...s!==void 0&&{stopReason:s}}}function zp(t,e,n,r,o){let s=n instanceof Error?n:new Error(String(n));return{id:t,status:e,error:s,trace:r,...o!==void 0&&{stopReason:o}}}function fe(t){return`${t.status}${t.error?`: ${t.error.message}`:""}`}J();P();P();var
|
|
1140
|
+
${Gp}`;P();import{homedir as WT}from"node:os";P();I();P();var cce=[...new Set([WT(),mn(WT())])];var Tce=new Set(ik);function os(t){let e=DW(t);return e!==void 0?e:FW(t)}function DW(t){let e=/```(?:json)?\s*([\s\S]*?)```/gi,n,r;for(;(r=e.exec(t))!==null;)n=r[1];if(n)return KT(n.trim())}function FW(t){for(let e=t.length-1;e>=0;e--){if(t[e]!=="}")continue;let n=LW(t,e);if(n===-1)continue;let r=t.slice(n,e+1),o=KT(r);if(o!==void 0)return o}}function LW(t,e){let n=0,r=!1,o=!1;for(let s=e;s>=0;s--){let i=t[s];if(o){o=!1;continue}if(r){if(i==="\\"){o=!0;continue}i==='"'&&(r=!1);continue}if(i==='"'){r=!0;continue}if(i==="}")n++;else if(i==="{"&&(n--,n===0))return s}return-1}function KT(t){try{return JSON.parse(t)}catch{return}}import{z as Zt}from"zod";var NW=Zt.enum(["supports","opposes","uncertain","blocks"]),UW=Zt.object({issue:Zt.string().min(1),stance:NW,confidence:Zt.number().min(0).max(1),evidence:Zt.array(Zt.string()),claim:Zt.string().min(1)}),$W=Zt.object({signal:UW}).passthrough();function BW(t){let e=/```(?:json)?\s*([\s\S]*?)```/gi,n;for(;(n=e.exec(t))!==null;){let r=n[1];if(r===void 0)continue;let o=qT(r.trim());if(GT(o))return o}for(let r=0;r<t.length;r++){if(t[r]!=="{"||jW(t,r))continue;let o=HW(t,r);if(o===-1)continue;let s=t.slice(r,o+1),i=qT(s);if(GT(i))return i;r=o}}function jW(t,e){for(let n=e-1;n>=0;n--){let r=t[n];if(!(r===" "||r===" "||r===`
|
|
1141
|
+
`||r==="\r"))return r==="["||r===","}return!1}function XT(t){let e=BW(t);if(e===void 0)return{ok:!1,reason:"absent"};let n=$W.safeParse(e);return n.success?{ok:!0,signal:n.data.signal}:{ok:!1,reason:"malformed"}}function qT(t){try{return JSON.parse(t)}catch{return}}function GT(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)&&"signal"in t}function HW(t,e){let n=0,r=!1,o=!1;for(let s=e;s<t.length;s++){let i=t[s];if(o){o=!1;continue}if(r){if(i==="\\"){o=!0;continue}i==='"'&&(r=!1);continue}if(i==='"'){r=!0;continue}if(i==="{")n++;else if(i==="}"&&(n--,n===0))return s}return-1}var Xe="overload_exhausted";var ss="stream_incomplete";function ze(t){return t===lt||t===dt||t===ss||t===Xe||xt(t)}function is(){return{toolCalls:[],toolResults:[],thinkingPresent:!1,turnCount:0}}function zT(t,e,n,r,o,s){let i=XT(n.content),a=i.ok?i.signal:void 0;if(!r)return{id:t,status:e,message:n,trace:o,...a!==void 0&&{signal:a},...s!==void 0&&{stopReason:s}};let c=os(n.content),l=r.safeParse(c);return l.success?{id:t,status:e,message:n,output:l.data,trace:o,...a!==void 0&&{signal:a},...s!==void 0&&{stopReason:s}}:{id:t,status:"failed",message:n,error:new Error(`structured output did not match schema: ${l.error.message}`,{cause:l.error}),schemaError:l.error,trace:o,...a!==void 0&&{signal:a},...s!==void 0&&{stopReason:s}}}function zp(t,e,n,r,o){let s=n instanceof Error?n:new Error(String(n));return{id:t,status:e,error:s,trace:r,...o!==void 0&&{stopReason:o}}}function fe(t){return`${t.status}${t.error?`: ${t.error.message}`:""}`}J();P();P();var ele=10080*60*1e3;var vle=300*1e3;J();import{execFile as XW}from"node:child_process";import{promisify as zW}from"node:util";J();var Cle=zW(XW);J();P();I();J();function Jp(t,e){for(let n of e??[])t.push({type:"image",source:{type:"base64",media_type:n.mediaType,data:n.bytes.toString("base64")}})}var fde=5*1024*1024;P();import{createHash as e1}from"node:crypto";import{mkdir as t1,writeFile as n1}from"node:fs/promises";import{join as r1}from"node:path";var o1=6,s1=new Map;function i1(t){return e1("sha256").update(t).digest("hex")}function a1(t,e,n){let r=Math.max(1,Math.round(n/1024));return`[image ${t} \xB7 ${e} \xB7 ${r} KB]`}async function QT(t,e,n,r=ZT){for(let o of n){let s=await r.put(e,o.bytes,o.mediaType);t.push({type:"text",text:a1(s.id,s.mediaType,s.sizeBytes)}),Jp(t,[o])}}var Vp=class{constructor(e=s1,n=i1){this.entries=e;this.hashBytes=n}entries;hashBytes;get(e,n){return this.entries.get(e)?.get(n)}listIds(e){return[...this.entries.get(e)?.keys()??[]].sort()}clear(e){this.entries.delete(e)}async put(e,n,r){let o=this.hashBytes(n),s=this.entries.get(e)??new Map;this.entries.set(e,s);let i=o1,a=0;for(;;){let c=`img_${o.slice(0,i)}`,l=a===0?c:`${c}_${a}`,d=s.get(l);if(d===void 0){let u=Dl(e);await t1(u,{recursive:!0});let p=r1(u,`${l}${c1(r)}`);await n1(p,n);let f={path:p,mediaType:r,sizeBytes:n.byteLength,digest:o};return s.set(l,f),{id:l,...f}}if(d.mediaType===r&&d.digest===o)return{id:l,...d};i<o.length?i=Math.min(o.length,i+2):a+=1}}};function c1(t){switch(t){case"image/jpeg":return".jpg";case"image/png":return".png";case"image/gif":return".gif";case"image/webp":return".webp"}}var ZT=new Vp;I();P();import{mkdirSync as d1,readFileSync as u1,writeFileSync as p1,renameSync as f1}from"node:fs";import{join as m1,dirname as g1}from"node:path";import{existsSync as l1}from"node:fs";function e_(t){return t===void 0||l1(t)?"ok":"missing"}function t_(t){try{let e=Fn();d1(e,{recursive:!0});let n=Ln(t.waveId),r=m1(g1(n),`.${t.waveId}.tmp`);p1(r,JSON.stringify(t,null,2),{encoding:"utf8",mode:384}),f1(r,n)}catch{}}function Yp(t){try{let e=u1(Ln(t),"utf8"),n=JSON.parse(e);return typeof n!="object"||n===null||n.version!==1?void 0:n}catch{return}}I();var MW=[...bt,...$e,"memory_search","workspace_publish","workspace_query","agent","skill","state_get","state_query"],h1=["read_file","glob","grep","list_directory","config_get","bash","web_scrape",...$e,"memory_search","workspace_publish","workspace_query","agent","skill","state_get","state_query"];function o_(t,e){let n={allowedTools:[...Ju]};return z(typeof e=="string"?e:void 0)==="openai-compatible"?new Ge({permissions:n}):new Rt({permissions:n})}function b1(t){return["# Tool budget","",`You have ${t} tool-use rounds for this turn. A round is one reply that requests tools:`,"issuing five tool calls in a SINGLE reply costs 1 round, not 5. Batch independent reads,","greps, and commands into one reply instead of calling them one at a time \u2014 it is the",`difference between roughly ${t} and roughly ${t*10} tool calls on the same budget.`,"",`${t} is a hard ceiling, not a target. Aim to finish well under it. When the budget is`,"spent you get one final reply with tools removed and must answer from what you already","gathered, so a partial answer delivered early beats a complete one you never get to give.","If new evidence has stopped changing your conclusion, stop gathering and answer now.","When writing code, a partial result should be an internally consistent checkpoint --","not knowingly broken, unverified, or incoherent code returned merely to finish early."].join(`
|
|
1142
1142
|
`)}function s_(t){let e=t.maxToolUseIterations;if(typeof e!="number"||!Number.isFinite(e)||e<=0)return t;let n=b1(Math.floor(e)),r=t.systemPrompt;if(typeof r=="string")return r.length>0?{...t,systemPrompt:`${r}
|
|
1143
1143
|
|
|
1144
1144
|
${n}`}:{...t,systemPrompt:n};if(r&&typeof r=="object"&&"type"in r&&r.type==="preset"){let o=r.append??"";return{...t,systemPrompt:{...r,append:o.length>0?`${o}
|
|
1145
1145
|
|
|
1146
1146
|
${n}`:n}}}return{...t,systemPrompt:n}}I();var ef=async(t,e)=>({action:"decline"}),tf=50,Qp=45*6e4;function kc(){let t=b.AFK_SUBAGENT_TIMEOUT_MS;if(t===void 0||t.trim()==="")return Qp;let e=Number.parseInt(t,10);return!Number.isFinite(e)||e<0?Qp:e}var Zp=8*6e4;function i_(){let t=b.AFK_SUBAGENT_IDLE_TIMEOUT_MS;if(t===void 0||t.trim()==="")return Zp;let e=Number.parseInt(t,10);return!Number.isFinite(e)||e<0?Zp:e}var r_=60*6e4,a_=5e3;function c_(t){let{options:e,id:n,resume:r,registry:o,effectiveChildModel:s,effectiveTimeoutMs:i,inheritedReadRoots:a,composedWriteRoots:c,childController:l,parentCwd:d,parentApiKey:u,parentBaseUrl:p,parentProvider:f,parentTraceWriter:m,parentSurface:g,parentCanUseTool:h}=t,y=r??(typeof e.config.systemPrompt=="string"?e.config.systemPrompt:""),w=t.workspaceStore?t.workspaceStore.queryRelevant(null,y):[],k=s_({...e.config,isSubagentFork:!0,model:s,resume:r,forkSession:r?!0:e.config.forkSession,subagentId:n,subagentToolOutputCapBytes:1e5,abortSignal:l.signal,apiKey:PT({childModel:s,configApiKey:e.config.apiKey,parentApiKey:u,parentProvider:f}),baseUrl:e.config.baseUrl??(z(s)==="openai-compatible"?void 0:p),isNonInteractive:e.config.isNonInteractive??!0,maxToolUseIterations:e.config.maxToolUseIterations??tf,softDeadlineMs:e.config.softDeadlineMs??Np(i),autoResumeOnUsageLimit:e.config.autoResumeOnUsageLimit??!1,...e.config.parentSessionId===void 0&&e.parent.sessionId!==void 0?{parentSessionId:e.parent.sessionId}:{},...e.config.phaseRole===void 0&&e.phaseRole!==void 0?{phaseRole:e.phaseRole}:{},...e.config.cwd===void 0&&d!==void 0?{cwd:d}:{},...a!==void 0?{readRoots:a}:{},...c!==void 0?{writeRoots:c}:{},...e.config.traceWriter===void 0&&m!==void 0?{traceWriter:m}:{},...e.config.surface===void 0&&g!==void 0?{surface:g}:{},hookRegistry:o,permissionBubbler:e.config.permissionBubbler??(h!==void 0&&e.config.canUseTool===void 0?{canUseTool:h}:void 0),...e.denyElicitations===!1?{}:{onElicitation:ef},...e.phaseRole==="read-only"?{provider:o_("read-only",s)}:{}});return t.workspaceStore?cd(k,w):k}function l_(t){let{effectiveTraceWriter:e,id:n,parentSessionId:r,rootId:o,effectiveChildModel:s,childConfig:i,promptHead:a,effectiveAgentType:c,effectiveResolvedAgentType:l}=t,d=typeof s=="string"?s:JSON.stringify(s);return sn(e,{transition:"started",subagentId:n,parentId:r??o,model:d,...i.tools?.allowedTools?{allowedTools:[...i.tools.allowedTools]}:{},...a&&a.trim()!==""?{promptHead:a.slice(0,80)}:{},...c?{agentType:c}:{},...l?{resolvedAgentType:l}:{}}),d}async function d_(t){let{modelString:e,id:n,idPrefix:r,parentSessionId:o,effectiveResolvedAgentType:s}=t;await Ee({event:"subagent.dispatched",subagent_id:n,id_prefix:r,model:e,parent_session_id:o,resolved_agent_type:s})}var nf=0,vc=5e3;async function cs(t,e,n={}){if(!Number.isFinite(e)||e<=0)return t;let r,o=new Promise((s,i)=>{let a=0,c=l=>{r=setTimeout(()=>{a+=l;let d=0;if(n.extender)try{d=n.extender.onDeadline()}catch{d=0}if(Number.isFinite(d)&&d>0){c(d);return}let u=n.label?` (${n.label})`:"",p="";if(n.extender?.describe)try{let m=n.extender.describe();m!==void 0&&m!==""&&(p=` ${m}`)}catch{}let f=new _e(`Operation timed out after ${a}ms${u}${p}`,a);n.controller&&!n.controller.signal.aborted&&n.controller.abort(f),i(f)},l)};c(e)});try{return await Promise.race([t,o])}finally{r!==void 0&&clearTimeout(r)}}function ls(t,e=Date.now()){if(t.type==="paused")return t.resetsAt===void 0?void 0:t.resetsAt.getTime()-e+3e4;if(t.type==="rate_limit"){let n=t.retryAfterMs;return typeof n!="number"||!Number.isFinite(n)||n<=0?void 0:n+3e4}}function u_(t){if(t.type==="paused"){let e=t.resetsAt!==void 0?t.resetsAt.toISOString():"unknown";return`paused (${t.reason}, resetsAt=${e})`}if(t.type==="rate_limit"){let e=t.retryAfterMs;return`rate_limit (retryAfterMs=${typeof e=="number"?e:"unknown"})`}}var rf=120*6e4,w1=1e3,Tc=class{constructor(e,n=rf,r){this.baseTimeoutMs=e;this.maxExtensionMs=n;this.onGrant=r}baseTimeoutMs;maxExtensionMs;pauseStartedAtMs;pauseWindowCapMs=0;closedCreditMs=0;lastPauseDescription;grantedMs=0;grantCount=0;onGrant;onEvent(e){if(e.type==="resumed"){this.closePause();return}if(e.type!=="paused"&&e.type!=="rate_limit")return;this.closeExpiredPause();let n=ls(e);if(n===void 0||n<=0)return;let r=Date.now();if(this.pauseStartedAtMs===void 0)this.pauseStartedAtMs=r,this.pauseWindowCapMs=n;else{let o=r-this.pauseStartedAtMs;this.pauseWindowCapMs=Math.max(this.pauseWindowCapMs,o+n)}this.lastPauseDescription=u_(e)}openPauseCreditMs(){if(this.pauseStartedAtMs===void 0)return 0;let e=Date.now()-this.pauseStartedAtMs;return Math.max(0,Math.min(e,this.pauseWindowCapMs))}closePause(){this.pauseStartedAtMs!==void 0&&(this.closedCreditMs+=this.openPauseCreditMs(),this.pauseStartedAtMs=void 0,this.pauseWindowCapMs=0)}closeExpiredPause(){this.pauseStartedAtMs!==void 0&&Date.now()-this.pauseStartedAtMs>=this.pauseWindowCapMs&&this.closePause()}onDeadline(){let e=this.maxExtensionMs-this.grantedMs;if(!(e>0))return 0;this.closeExpiredPause();let r=this.closedCreditMs+this.openPauseCreditMs()-this.grantedMs;if(r<=0)return 0;let o=Math.min(Math.max(r,w1),e);if(this.grantedMs+=o,this.grantCount+=1,this.onGrant)try{this.onGrant({grantMs:o,totalGrantedMs:this.grantedMs,remainingCapMs:this.maxExtensionMs-this.grantedMs,grantCount:this.grantCount,pauseDescription:this.lastPauseDescription})}catch{}return o}describe(){if(this.lastPauseDescription===void 0)return;let e=[`base budget ${this.baseTimeoutMs}ms`,`pause extension granted ${this.grantedMs}ms across ${this.grantCount} extension${this.grantCount===1?"":"s"} (cap ${this.maxExtensionMs}ms${this.grantedMs>=this.maxExtensionMs?", EXHAUSTED":""})`,`last provider pause: ${this.lastPauseDescription}`];if(this.pauseStartedAtMs!==void 0){let r=Date.now()-this.pauseStartedAtMs>=this.pauseWindowCapMs?"expired":"still open";e.push(`last pause ${r}, opened ${new Date(this.pauseStartedAtMs).toISOString()} (reported window ${this.pauseWindowCapMs}ms)`)}return`[pause-aware ceiling: ${e.join("; ")}]`}get totalGrantedMs(){return this.grantedMs}};J();var _c=class{constructor(e,n,r,o){this.controller=e;this.idleTimeoutMs=n;this.label=r;this.onFire=o;this.isEnabled()&&this.arm(this.idleTimeoutMs,"none")}controller;idleTimeoutMs;label;onFire;timer;disposed=!1;fired=!1;inFlightTools=new Set;isEnabled(){return Number.isFinite(this.idleTimeoutMs)&&this.idleTimeoutMs>0}onEvent(e){if(!(!this.isEnabled()||this.disposed||this.fired)){if(e.type==="chunk"){if(e.chunk.type==="tool_use_detail"){this.inFlightTools.add(e.chunk.toolUseId),this.clearTimer();return}if(e.chunk.type==="tool_result"){this.inFlightTools.delete(e.chunk.toolUseId),this.inFlightTools.size===0&&this.arm(this.idleTimeoutMs,e.chunk.type);return}}if(!(this.inFlightTools.size>0)){if(e.type==="paused"){this.arm(this.pausedWindowMs(e),e.type);return}if(e.type==="rate_limit"){let n=ls(e);if(n!==void 0&&n>0){this.arm(n,e.type);return}}this.arm(this.idleTimeoutMs,e.type)}}}pausedWindowMs(e){let n=ls(e);return n===void 0?this.idleTimeoutMs:Math.max(this.idleTimeoutMs,n)}arm(e,n){this.timer!==void 0&&clearTimeout(this.timer);let r=e>0?e:this.idleTimeoutMs,o=Date.now(),s=setTimeout(()=>{this.fire(Date.now()-o,n)},r);s.unref(),this.timer=s}clearTimer(){this.timer!==void 0&&(clearTimeout(this.timer),this.timer=void 0)}fire(e,n){if(!(this.fired||this.disposed)){this.fired=!0,this.timer=void 0;try{this.onFire?.({idleTimeoutMs:this.idleTimeoutMs,elapsedSinceLastProgressMs:e,lastEventType:n})}catch{}this.controller.signal.aborted||this.controller.abort(new Vs(`subagent ${this.label} idle-watchdog fired: no observable progress for ${this.idleTimeoutMs}ms (last event: ${n}). The child stream produced no output for the idle window \u2014 typically a stalled model call under provider throttling with no detectable backoff bracket. Aborting so partial output (if any) is returned; the parent should retry or fall back.`,this.idleTimeoutMs))}}dispose(){this.disposed||(this.disposed=!0,this.inFlightTools.clear(),this.clearTimer())}};function p_(t,e){let n=e.length,r=n>0?`subagent ${t} stream cut off after ${n} tool result(s); see partialOutput.`:`subagent ${t} produced no output \u2014 stream ended without a terminal message (stream_incomplete). No findings were produced; retry or fall back.`,o=new Le(r);return n>0&&(o.toolResultsGathered=n),o}function f_(t,e){if(e.length===0)return;let n=e.reduce((s,i)=>s+(i.sizeBytes??0),0),r=e.filter(s=>s.isError).length,o=r>0?` (${r} errored)`:"";return`[Stream cut off before any assistant text was produced. Subagent ${t} completed ${e.length} tool result(s)${o} (~${n} bytes total) before the cut. The run is failed \u2014 no final answer was produced \u2014 but tool evidence is available via result.trace for recovery or retry decisions.]`}async function of(t,e,n){let r,o;t._lastStreamedContent="",t._currentTrace=is();let s=n??t._progressSink??Xt(),i={subagentId:t.id,...t._parentId!==void 0&&{parentId:t._parentId},...t._agentType!==void 0&&{agentType:t._agentType}},a=new _c(t._controller,t._idleTimeoutMs,t.id,c=>{U(t._traceWriter,{phase:"idle_watchdog_fired",metadata:{idleTimeoutMs:c.idleTimeoutMs,elapsedSinceLastProgressMs:c.elapsedSinceLastProgressMs,lastEventType:c.lastEventType}})});t.session.setBeforeNextRound?.(t._beforeNextRound);try{for await(let c of t.session.sendMessageStream(e)){if(s&&s(c,i),t._logWriter?.write(c),a.onEvent(c),t._pauseCeiling?.onEvent(c),c.type==="chunk"){let l=c.chunk;l.type==="content"?t._lastStreamedContent+=l.content:l.type==="tool_use_detail"?t._currentTrace.toolCalls.push({id:l.toolUseId,name:l.toolName,inputBytes:Buffer.byteLength(l.toolInput,"utf8")}):l.type==="tool_result"?t._currentTrace.toolResults.push({toolUseId:l.toolUseId,isError:l.isError,truncated:l.truncated,sizeBytes:l.sizeBytes}):l.type==="thinking"&&(t._currentTrace.thinkingPresent=!0)}if(c.type==="message")r=c.message,t._currentTrace.turnCount++;else if(c.type==="error"){o=c.error;break}else if(c.type==="done"){if(typeof c.metadata?.stopReason=="string"&&(t._lastStopReason=c.metadata.stopReason),typeof c.metadata?.usage=="object"&&c.metadata.usage!==null){let l=c.metadata.usage;t._currentTrace.usage={inputTokens:typeof l.input_tokens=="number"?l.input_tokens:void 0,outputTokens:typeof l.output_tokens=="number"?l.output_tokens:void 0,cacheReadTokens:typeof l.cache_read_input_tokens=="number"?l.cache_read_input_tokens:void 0,cacheCreationTokens:typeof l.cache_creation_input_tokens=="number"?l.cache_creation_input_tokens:void 0}}break}}}finally{t.session.setBeforeNextRound?.(void 0),a.dispose()}if(o)throw o;if(r)return r;if(t._lastStreamedContent.length>0)return t._lastStopReason??=ss,{role:"assistant",content:t._lastStreamedContent,timestamp:new Date};if(t._lastStopReason===lt||t._lastStopReason===dt){let c=t._lastStopReason===lt?"tool-use iteration cap":"wall-clock budget";return{role:"assistant",content:`[subagent ${t.id} reached its ${c} before producing a final message; returning a partial result]`,timestamp:new Date}}throw t._controller.signal.aborted||t._currentStatus==="cancelled"?new Error(`Subagent ${t.id} produced no terminal message`):(t._lastStopReason=ss,p_(t.id,t._currentTrace.toolResults))}async function m_(t,e,n){try{let r=await t.run(e,n);return zT(t.id,t._currentStatus,r,t._outputSchema,t._currentTrace,t._lastStopReason)}catch(r){let o=zp(t.id,t._currentStatus,r,t._currentTrace,t._lastStopReason);if(t._lastStreamedContent.length>0)o.partialOutput=t._lastStreamedContent;else if(r instanceof Le){let s=f_(t.id,t._currentTrace.toolResults);s!==void 0&&(o.partialOutput=s)}return o}}function g_(t,e,n,r){let o;if(r){let s=t._progressSink??Xt();o=(i,a)=>{r(i),s?.(i,a)}}t.runToResult(e,o).then(s=>{n?.(s)}).catch(s=>{C("runInBackground: unexpected rejection after runToResult",s),console.error("Subagent runInBackground failed unexpectedly:",s)})}async function sf(t,e,n){if(t._stopDispatched){t._onTerminal();return}t._stopDispatched=!0;let r=await Mg(t._hookRegistry,{event:"SubagentStop",subagentId:t.id,status:e,lastMessage:t._lastMessage,agentType:t._agentType,durationMs:t._lastDurationMs,trace:t._currentTrace},t._traceWriter?{traceWriter:t._traceWriter}:{});if(r.injectContext){if(t._parentAbortSignal?.aborted)C(`Skipping SubagentStop injectContext for ${t.id}: parent is aborted`);else if(n?.deferInjectContextToCaller)t._lastStopInjectContext=r.injectContext;else if(t._parentInputStreamRef)try{let o=t._parentInputStreamRef;o.queueFrameworkContext?o.queueFrameworkContext(r.injectContext):o.pushUserMessage(r.injectContext)}catch(o){C(`Failed to inject context from SubagentStop handler: ${String(o)}`)}}t._onTerminal()}var Ec=class{constructor(e,n,r,o,s,i,a,c,l,d,u,p,f,m,g,h=0){this.id=e;this.session=n;this._controller=r;this.abortGraph=o;this._outputSchema=s;this.timeoutMs=i;this._hookRegistry=a;this._onTerminal=c;this._parentInputStreamRef=l;this._parentAbortSignal=d;this._agentType=u;this._traceWriter=m;this.onSubagentSucceeded=g;this._idleTimeoutMs=h;this._progressSink=p,this._parentId=f}id;session;_controller;abortGraph;_outputSchema;timeoutMs;_hookRegistry;_onTerminal;_parentInputStreamRef;_parentAbortSignal;_agentType;_traceWriter;onSubagentSucceeded;_idleTimeoutMs;_currentStatus="idle";inFlight=null;_lastMessage;_lastDurationMs;latestTerminalStatus;_stopDispatched=!1;_lastStopInjectContext;_progressSink;_parentId;_currentTrace=is();_lastStreamedContent="";_pauseCeiling;_lastStopReason;_logWriter;get status(){return this._currentStatus}get durationMs(){return this._lastDurationMs}async run(e,n){if(this._currentStatus==="running")throw new Error(`Subagent ${this.id} is already running`);if(this._lastStopReason=void 0,this._currentStatus==="cancelled")throw new Error(`Subagent ${this.id} is cancelled`);this._currentStatus="running";let r=Date.now(),o=Number.isFinite(this.timeoutMs)&&this.timeoutMs>0?new Tc(this.timeoutMs,rf,i=>{U(this._traceWriter,{phase:"pause_extension_granted",metadata:{subagentId:this.id,grantMs:i.grantMs,totalGrantedMs:i.totalGrantedMs,remainingCapMs:i.remainingCapMs,grantCount:i.grantCount,...i.pauseDescription!==void 0&&{pauseDescription:i.pauseDescription}}})}):void 0;this._pauseCeiling=o;let s=cs(of(this,e,n),this.timeoutMs,{controller:this._controller,label:this.id,...o!==void 0&&{extender:o}});this.inFlight=s;try{let i=await s;this._lastMessage=i.content,this._lastDurationMs=Date.now()-r,this._currentStatus="succeeded",this.latestTerminalStatus="succeeded";let a=i;this._drainingMessages=!0;try{for(;this._pendingUserMessages.length>0&&!this._controller.signal.aborted;){let l=this._pendingUserMessages.shift();a=await of(this,l,n),this._lastMessage=a.content,this._currentTrace.turnCount++}}catch{this._pendingUserMessages.length=0}this._drainingMessages=!1,await sn(this._traceWriter,{transition:"succeeded",subagentId:this.id,durationMs:Date.now()-r,turnCount:this._currentTrace.turnCount,outputBytes:Buffer.byteLength(this._lastMessage,"utf8"),...this._lastStopReason!==void 0&&{stopReason:this._lastStopReason}});let c=typeof a.metadata?.totalCostUsd=="number"?a.metadata.totalCostUsd:void 0;return this.onSubagentSucceeded?.(this._currentTrace.usage,c),this._onTerminal(),a}catch(i){this._lastDurationMs=Date.now()-r;let a=this._controller.signal.aborted&&this._controller.signal.reason instanceof _e&&!this.abortGraph.isCascading(this.id)?this._controller.signal.reason:void 0,c=a??i;if(this._currentStatus!=="cancelled")if(this._controller.signal.aborted&&a===void 0){let l=this._controller.signal.reason instanceof _e;await sn(this._traceWriter,{transition:"cancelled",subagentId:this.id,source:"cascade",...l?{timeout:!0}:{}}),this._currentStatus="cancelled",this.latestTerminalStatus="cancelled"}else await sn(this._traceWriter,{transition:"failed",subagentId:this.id,errorClass:c instanceof Error?c.constructor.name:"Unknown",errorMessage:c instanceof Error?c.message:String(c),partialOutputBytes:Buffer.byteLength(this._lastStreamedContent,"utf8"),...a!==void 0?{failureClass:"timeout"}:{}}),this._currentStatus="failed",this.latestTerminalStatus="failed";throw this._onTerminal(),c}finally{this.inFlight=null}}async runToResult(e,n){return m_(this,e,n)}runInBackground(e,n,r){return g_(this,e,n,r)}async cancel(){if(this._currentStatus==="cancelled"||this._stopDispatched)return;let e=this.latestTerminalStatus??"cancelled";this._currentStatus="cancelled",sn(this._traceWriter,{transition:"cancelled",subagentId:this.id,source:"explicit"}),this._steeringMessages.length=0,this._progressEvents.length=0;try{this.abortGraph.abort(this.id,"cancelled")}catch{}try{this.inFlight&&await this.session.interrupt()}catch{}try{await this.session.close()}finally{await sf(this,e)}}async teardown(e){if(this._stopDispatched)return;let n=this.latestTerminalStatus??"cancelled";try{this.inFlight&&await this.session.interrupt()}catch{}this._steeringMessages.length=0,this._progressEvents.length=0;try{await this.session.close()}finally{await sf(this,n,e)}}getLastStopInjectContext(){return this._lastStopInjectContext}_pendingUserMessages=[];_drainingMessages=!1;sendMessage(e){e.trim()&&((this._currentStatus==="succeeded"||this._currentStatus==="failed"||this._currentStatus==="cancelled")&&!this._drainingMessages||this._pendingUserMessages.push(e))}_steeringMessages=[];_progressEvents=[];steer(e){e.trim()&&((this._currentStatus==="succeeded"||this._currentStatus==="failed"||this._currentStatus==="cancelled")&&!this._drainingMessages||this._controller.signal.aborted||(this._steeringMessages.length>=3&&this._steeringMessages.shift(),this._steeringMessages.push(e)))}emitProgress(e){this._currentStatus==="succeeded"||this._currentStatus==="failed"||this._currentStatus==="cancelled"||(this._progressEvents.length>=20&&this._progressEvents.shift(),this._progressEvents.push(e))}get _beforeNextRound(){return()=>this._steeringMessages.shift()}};function y_(t){return Ka(rt(t))}function b_(t,e){return t===void 0||!y_(t)||z(t)!=="openai-compatible"?{model:t}:e===void 0||y_(e)||z(e)!=="openai-compatible"?{model:t}:{model:e,coercedFrom:t}}function w_(t){let{options:e,counter:n,managerHookRegistry:r,parentTraceWriter:o,parentModel:s}=t,a=`${(e.idPrefix??"subagent").replace(/[^A-Za-z0-9_-]/g,"-")}-${Date.now()}-${n}`,c=e.parent.sessionId,l=e.config.hookRegistry??r??e.parent.hookRegistry,d=e.config.traceWriter??o,u=b_(e.config.model,s),p=u.model??e.config.model,f=e.config.timeoutMs??kc();return{id:a,resume:c,registry:l,effectiveTraceWriter:d,effectiveChildModel:p,coercedFrom:u.coercedFrom,effectiveTimeoutMs:f}}var Ac=class{entries=new Map;capacity;constructor(e=30){this.capacity=Math.max(1,e)}add(e,n,r){this.entries.delete(e),this.entries.set(e,{handle:n,result:r,completedAt:Date.now()}),this.evictIfNeeded()}recordHandle(e,n,r,o,s){let i=r==="succeeded"?{id:e,status:r,trace:o,...s!==void 0&&{stopReason:s}}:{id:e,status:r,error:new Error(`subagent terminated with status: ${r}`),trace:o,...s!==void 0&&{stopReason:s}};this.add(e,n,i)}get(e){return this.entries.get(e)}list(){return[...this.entries.values()].reverse()}get size(){return this.entries.size}delete(e){return this.entries.delete(e)}clear(){this.entries.clear()}evictIfNeeded(){for(;this.entries.size>this.capacity;){let e=this.entries.keys().next().value;if(e!==void 0)this.entries.delete(e);else break}}};import*as vr from"node:fs";I();P();var S_=1048576,k_=new Set,ds=class{constructor(e,n){this.sessionLabel=e;this.subagentId=n;this.logPath=$m(e,n);let r=Hl(e);if(!k_.has(r))try{vr.mkdirSync(r,{recursive:!0}),k_.add(r)}catch{this.errored=!0}}sessionLabel;subagentId;logPath;stream=null;errored=!1;closed=!1;streamReady=!1;pendingLines=[];readyPromise=null;readyResolve=null;bytesWritten=0;static isEnabled(){return b.AFK_SUBAGENT_LOG==="1"}write(e){if(this.errored||this.closed||this.bytesWritten>=S_)return;let n=JSON.stringify(e)+`
|
|
1147
1147
|
`;if(!this.stream){this.pendingLines.push(n),this.openStream();return}if(!this.streamReady){this.pendingLines.push(n);return}this.writeLine(n)}async close(){if(!this.closed)return this.closed=!0,this.readyPromise&&await this.readyPromise,new Promise(e=>{if(!this.stream||this.errored){e();return}this.stream.end(()=>e())})}openStream(){if(!this.stream){this.readyPromise=new Promise(e=>{this.readyResolve=e});try{let e=vr.createWriteStream(this.logPath,{flags:"a",encoding:"utf8",mode:384});this.stream=e,e.once("open",()=>{this.streamReady=!0;for(let n of this.pendingLines)this.writeLine(n);this.pendingLines=[],this.readyResolve?.(),this.readyResolve=null}),e.once("error",()=>{this.errored=!0,this.pendingLines=[],this.readyResolve?.(),this.readyResolve=null})}catch{this.errored=!0,this.readyResolve?.(),this.readyResolve=null}}}writeLine(e){this.errored||!this.stream||this.bytesWritten>=S_||(this.bytesWritten+=Buffer.byteLength(e,"utf8"),this.stream.write(e))}};import{z as Tr}from"zod";import{z as S1}from"zod";function xc(t,e,n,r){let s={...S1.toJSONSchema(n,{target:"openapi-3.0"}),type:"object"};return{schema:{name:t,description:e,input_schema:s},handler:async(c,l,d)=>{let u=n.safeParse(c);if(!u.success){let p=u.error.issues.map(f=>`${f.path.join(".")||"<root>"}: ${f.message}`).join("; ");return{isError:!0,content:`Tool input validation failed for "${t}": ${p}`}}return r(u.data,l,d)}}}var Rc=2048;function k1(t,e){let n=new Date().toISOString(),r=t.phase!==void 0?` phase="${T_(t.phase)}"`:"";return`<child-progress subagentId="${T_(e)}"${r} timestamp="${n}">`+v1(t.message)+"</child-progress>"}function T_(t){return t.replace(/&/g,"&").replace(/"/g,""")}function v1(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function E_(t,e,n){return async r=>{if(n?.aborted)return{content:JSON.stringify({delivered:!1,reason:"parent_aborted"})};if(typeof r!="object"||r===null)return{content:"emit_progress: input must be an object.",isError:!0};let o=r,s=o.message;if(typeof s!="string"||s.trim().length===0)return{content:'emit_progress: "message" must be a non-empty string.',isError:!0};let i=s;Buffer.byteLength(i,"utf8")>Rc&&(i=__(i,Rc));let a=typeof o.phase=="string"&&o.phase.trim().length>0?o.phase.trim():void 0;a!==void 0&&Buffer.byteLength(a,"utf8")>256&&(a=__(a,256));let c=typeof o.metadata=="object"&&o.metadata!==null&&!Array.isArray(o.metadata)?o.metadata:void 0,l={message:i,...a!==void 0?{phase:a}:{},...c!==void 0?{metadata:c}:{}};t.emitProgress(l);try{let d=k1(l,t.id);e(d)}catch{return{content:JSON.stringify({delivered:!1,reason:"queue_error"})}}return{content:JSON.stringify({delivered:!0})}}}function __(t,e){let n=Buffer.from(t,"utf8");if(n.byteLength<=e)return t;let r=Math.min(e,n.byteLength);for(;r>0&&n[r]!==void 0&&(n[r]&192)===128;)r--;return n.subarray(0,r).toString("utf8")}function A_(t,e,n,r){return e?T1(t,n,r):()=>{}}function T1(t,e,n){let r={current:void 0},o,s=xc("emit_progress",`Emit a structured progress event to the parent agent. The event is delivered to the parent at its next user-turn boundary, wrapped in a <child-progress> envelope. Use to report phase transitions, intermediate findings, or status updates so the parent stays informed without waiting for the full result. The "message" field is required (max ${Rc} bytes). "phase" and "metadata" are optional. Note: this tool call counts as a tool-use round.`,Tr.object({message:Tr.string().describe("Progress message to deliver to the parent (required)."),phase:Tr.string().optional().describe('Optional phase label (e.g. "research", "planning", "done").'),metadata:Tr.record(Tr.string(),Tr.unknown()).optional().describe("Optional structured metadata for machine consumers.")}),async(i,a)=>r.current===void 0?{content:"emit_progress: handle not yet initialized.",isError:!0}:(o===void 0&&(o=E_(r.current,c=>{e?.queueFrameworkContext?e.queueFrameworkContext(c):e&&e.pushUserMessage(c)},n)),o(i,a)));return t.customTools=[...t.customTools??[],s],i=>{r.current=i,o=void 0}}var G=class{active=new Map;completed=new Ac;parentCanUseTool;hookRegistry;progressSink;parentApiKey;parentBaseUrl;parentProvider;parentModel;parentCwd;parentReadRoots;worktreeMainRootCache=new Map;parentTraceWriter;parentSurface;parentAbortSignal;workspaceStore;sessionLabel;abortGraph;rootId;rootController;counter=0;onSubagentSucceededCb;constructor(e={}){if(this.parentCanUseTool=e.canUseTool,this.hookRegistry=e.hookRegistry,this.progressSink=e.progressSink,this.parentApiKey=e.apiKey,this.parentBaseUrl=e.baseUrl,this.parentProvider=e.parentModel!==void 0?z(e.parentModel):void 0,this.parentModel=e.parentModel,this.parentCwd=e.cwd,this.parentReadRoots=e.parentReadRoots,this.parentTraceWriter=e.traceWriter,this.parentSurface=e.surface,this.parentAbortSignal=e.parentAbortSignal,this.onSubagentSucceededCb=e.onSubagentSucceeded,this.workspaceStore=e.workspaceStore,this.sessionLabel=e.sessionLabel,this.abortGraph=new Go(e.traceWriter),this.rootId=`manager-root-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,this.rootController=new AbortController,this.abortGraph.register(this.rootId,this.rootController),e.parentAbortSignal){let n=e.parentAbortSignal;n.aborted?this.rootController.abort(n.reason):n.addEventListener("abort",()=>{this.rootController.signal.aborted||this.rootController.abort(n.reason)},{once:!0})}}list(){return[...this.active.values()].map(e=>({id:e.id,status:e.status}))}get(e){return this.active.get(e)??this.completed.get(e)?.handle}onChildAborted(e){return this.abortGraph.onChildAborted(this.rootId,e)}setOnSubagentSucceeded(e){this.onSubagentSucceededCb=e}setCwd(e){this.parentCwd=e,this.worktreeMainRootCache.delete(e)}setTraceWriter(e){this.parentTraceWriter=e,this.abortGraph.setTraceWriter(e)}getReadScopeInputs(){return{parentReadRoots:this.parentReadRoots,parentCwd:this.parentCwd}}async resolveMainRootForCwd(e){if(this.worktreeMainRootCache.has(e))return this.worktreeMainRootCache.get(e);let n=await Pv(e);return this.worktreeMainRootCache.set(e,n),n}abortAll(e,n="user_signal"){this.abortGraph.abort(this.rootId,e,n)}async forkSubagent(e){Dv(e);let{id:n,resume:r,registry:o,effectiveTraceWriter:s,effectiveChildModel:i,coercedFrom:a,effectiveTimeoutMs:c}=w_({options:e,counter:++this.counter,managerHookRegistry:this.hookRegistry,parentTraceWriter:this.parentTraceWriter,parentModel:this.parentModel});o&&await Pg(o,{event:"SubagentStart",subagentId:n,parentSessionId:e.parent.sessionId},{signal:this.rootController.signal,...s?{traceWriter:s}:{}}),a!==void 0&&process.stderr.write(`[afk] subagent: child model "${a}" cannot run on this session's OpenAI/ChatGPT backend \u2014 running it as "${i??""}" instead (set AFK_DEFAULT_SUBAGENT_MODEL to choose a different one).
|
|
1148
|
-
`);let l=new AbortController;this.abortGraph.register(n,l),this.abortGraph.linkChild(this.rootId,n);let d=e.config.cwd??this.parentCwd,u=await Mv({parentReadRoots:this.parentReadRoots,parentCwd:this.parentCwd,effectiveChildCwd:d,callerReadRoots:e.config.readRoots,callerExtraReadRoots:e.config.extraReadRoots,resolveMainRoot:_=>this.resolveMainRootForCwd(_)}),p=Ov(e.config.writeRoots,d),f=c_({options:e,id:n,resume:r,registry:o,effectiveChildModel:i,effectiveTimeoutMs:c,inheritedReadRoots:u,composedWriteRoots:p,childController:l,parentCwd:this.parentCwd,parentApiKey:this.parentApiKey,parentBaseUrl:this.parentBaseUrl,parentProvider:this.parentProvider,parentTraceWriter:this.parentTraceWriter,parentSurface:this.parentSurface,parentCanUseTool:this.parentCanUseTool,workspaceStore:this.workspaceStore}),m=()=>{};f.cwd!==void 0&&(wp(f.cwd),m=Cv(f.cwd));let g=A_(f,e.progressEvents,e.parent.getInputStreamRef?.(),e.parent.abortSignal),h,y,w,k;try{h=new It(f);let _=e.parent.getInputStreamRef?.(),R=e.parent.abortSignal,A=this.progressSink??Xt();w=e.agentType?.trim()||void 0,k=e.resolvedAgentType?.trim()||void 0;let M=e.parentId?.trim()||void 0,S=this.sessionLabel??e.parent.sessionId,T=ds.isEnabled()&&S?new ds(S,n):void 0;y=new Ec(n,h,l,this.abortGraph,e.outputSchema,c,o,()=>{m(),this.completed.add(n,y,{id:n,status:y._currentStatus==="running"?"succeeded":y._currentStatus}),this.active.delete(n),this.abortGraph.dispose(n),T?.close(),this.completed.recordHandle(n,y,y._currentStatus,y._currentTrace,y._lastStopReason)},_,R,w??e.idPrefix,A,M??e.parent.sessionId,s,this.onSubagentSucceededCb,e.config.idleTimeoutMs??i_()),T&&(y._logWriter=T),g(y),this.active.set(n,y)}catch(_){throw m(),this.abortGraph.dispose(n),_}let v=l_({effectiveTraceWriter:s,id:n,parentSessionId:e.parent.sessionId,rootId:this.rootId,effectiveChildModel:i,childConfig:f,promptHead:e.promptHead,effectiveAgentType:w,effectiveResolvedAgentType:k});return await d_({modelString:v,id:n,idPrefix:e.idPrefix,parentSessionId:e.parent.sessionId,effectiveResolvedAgentType:k}),y}async kill(e){let n=this.active.get(e);return n?(await n.cancel(),!0):!1}async killAll(){await Promise.allSettled([...this.active.values()].map(e=>e.cancel()))}async abortAllAndDrain(e,n="user_signal",r=a_,o=!1){let s=[...this.active.values()];if(s.length===0)return o&&this.rootController.signal.aborted&&this.rearmRoot(),{drained:0,timedOut:!1};this.abortGraph.abort(this.rootId,e,n);let i=!1,a=new Promise(c=>setTimeout(()=>{i=!0,c()},r).unref());return await Promise.race([Promise.allSettled(s.map(c=>c.cancel())),a]),i&&console.warn(`[SubagentManager] abortAllAndDrain: ${s.length} child(ren) did not settle within ${r}ms \u2014 sealing anyway; their terminal rows may be missing`),o&&this.rearmRoot(),{drained:s.length,timedOut:i}}rearmRoot(){this.rootController=new AbortController,this.abortGraph.rearm(this.rootId,this.rootController),this.parentAbortSignal?.aborted&&this.rootController.abort(this.parentAbortSignal.reason)}async teardownAll(){await Promise.allSettled([...this.active.values()].map(e=>e.teardown()))}};async function x_(t,e={}){let{failFast:n=!0,teardown:r=!0,maxConcurrency:o=di()}=e;if(t.length===0)return[];let s=new Array(t.length),i=new Set(t.map((c,l)=>l)),a=!1;return await bo(t.map((c,l)=>l),o,async c=>{let l=t[c];n&&a&&await l.handle.cancel().catch(()=>{});let d=await l.handle.runToResult(l.prompt);if(s[c]=d,i.delete(c),n&&d.status!=="succeeded"){a=!0;for(let u of i){let p=t[u];p&&p.handle.status==="running"&&p.handle.cancel().catch(()=>{})}}}),r&&await Promise.allSettled(t.map(c=>c.handle.teardown())),s}var _1=new Set([...bt,...$e,"memory_search","agent","skill"]);function R_(t){let e=new Set;for(let n of t){let r=bc(n,_1);r!==void 0&&e.add(r)}return e}P();P();import{existsSync as en,readdirSync as E1,readFileSync as A1}from"fs";import{join as Ct}from"path";var I_=["command","agent"];function C_(t=re()){let e=[],n=Ct(t,"skills");if(en(n))for(let r of Ic(n)){let o=Ct(n,r,"SKILL.md");en(o)&&e.push({path:o,type:"skill",source:"user"})}for(let r of I_){let o=Ct(t,`${r}s`);if(en(o))for(let s of Ic(o))s.endsWith(".md")&&e.push({path:Ct(o,s),type:r,source:"user"})}return e}function P_(t=Mn()){if(!en(t))return[];let e=[],n=xn(t);for(let r of n){let s=Wp(t,r.path)?.key,i=Ct(r.path,"skills");if(en(i))for(let a of Ic(i)){let c=Ct(i,a,"SKILL.md");if(!en(c))continue;let l={path:c,type:"skill",source:"plugin"};s&&(l.plugin_key=s),e.push(l)}for(let a of I_){let c=Ct(r.path,`${a}s`);if(en(c))for(let l of Ic(c)){if(!l.endsWith(".md"))continue;let d={path:Ct(c,l),type:a,source:"plugin"};s&&(d.plugin_key=s),e.push(d)}}}return e}function M_(t=Ct(re(),"settings.json")){if(!en(t))return[];try{let e=A1(t,"utf8"),r=JSON.parse(e).hooks;if(!r||typeof r!="object")return[];let o=[];for(let[s,i]of Object.entries(r))if(Array.isArray(i))for(let a=0;a<i.length;a++)o.push({event:s,index:a,raw:i[a]});return o}catch{return[]}}function Ic(t){try{return E1(t).filter(e=>!e.startsWith("."))}catch{return[]}}var L_=Y.object({path:Y.string(),type:Y.enum(["skill","command","agent","hook"]),source:Y.enum(["user","plugin"]),plugin_key:Y.string().optional(),verdict:Y.enum(["correct","misfit","outlier"]),recommended_type:Y.string(),rationale:Y.string(),confidence:Y.enum(["high","med","low"])}),F_=Y.record(Y.string(),Y.record(Y.string(),Y.number())),
|
|
1148
|
+
`);let l=new AbortController;this.abortGraph.register(n,l),this.abortGraph.linkChild(this.rootId,n);let d=e.config.cwd??this.parentCwd,u=await Mv({parentReadRoots:this.parentReadRoots,parentCwd:this.parentCwd,effectiveChildCwd:d,callerReadRoots:e.config.readRoots,callerExtraReadRoots:e.config.extraReadRoots,resolveMainRoot:_=>this.resolveMainRootForCwd(_)}),p=Ov(e.config.writeRoots,d),f=c_({options:e,id:n,resume:r,registry:o,effectiveChildModel:i,effectiveTimeoutMs:c,inheritedReadRoots:u,composedWriteRoots:p,childController:l,parentCwd:this.parentCwd,parentApiKey:this.parentApiKey,parentBaseUrl:this.parentBaseUrl,parentProvider:this.parentProvider,parentTraceWriter:this.parentTraceWriter,parentSurface:this.parentSurface,parentCanUseTool:this.parentCanUseTool,workspaceStore:this.workspaceStore}),m=()=>{};f.cwd!==void 0&&(wp(f.cwd),m=Cv(f.cwd));let g=A_(f,e.progressEvents,e.parent.getInputStreamRef?.(),e.parent.abortSignal),h,y,w,k;try{h=new It(f);let _=e.parent.getInputStreamRef?.(),R=e.parent.abortSignal,A=this.progressSink??Xt();w=e.agentType?.trim()||void 0,k=e.resolvedAgentType?.trim()||void 0;let M=e.parentId?.trim()||void 0,S=this.sessionLabel??e.parent.sessionId,T=ds.isEnabled()&&S?new ds(S,n):void 0;y=new Ec(n,h,l,this.abortGraph,e.outputSchema,c,o,()=>{m(),this.completed.add(n,y,{id:n,status:y._currentStatus==="running"?"succeeded":y._currentStatus}),this.active.delete(n),this.abortGraph.dispose(n),T?.close(),this.completed.recordHandle(n,y,y._currentStatus,y._currentTrace,y._lastStopReason)},_,R,w??e.idPrefix,A,M??e.parent.sessionId,s,this.onSubagentSucceededCb,e.config.idleTimeoutMs??i_()),T&&(y._logWriter=T),g(y),this.active.set(n,y)}catch(_){throw m(),this.abortGraph.dispose(n),_}let v=l_({effectiveTraceWriter:s,id:n,parentSessionId:e.parent.sessionId,rootId:this.rootId,effectiveChildModel:i,childConfig:f,promptHead:e.promptHead,effectiveAgentType:w,effectiveResolvedAgentType:k});return await d_({modelString:v,id:n,idPrefix:e.idPrefix,parentSessionId:e.parent.sessionId,effectiveResolvedAgentType:k}),y}async kill(e){let n=this.active.get(e);return n?(await n.cancel(),!0):!1}async killAll(){await Promise.allSettled([...this.active.values()].map(e=>e.cancel()))}async abortAllAndDrain(e,n="user_signal",r=a_,o=!1){let s=[...this.active.values()];if(s.length===0)return o&&this.rootController.signal.aborted&&this.rearmRoot(),{drained:0,timedOut:!1};this.abortGraph.abort(this.rootId,e,n);let i=!1,a=new Promise(c=>setTimeout(()=>{i=!0,c()},r).unref());return await Promise.race([Promise.allSettled(s.map(c=>c.cancel())),a]),i&&console.warn(`[SubagentManager] abortAllAndDrain: ${s.length} child(ren) did not settle within ${r}ms \u2014 sealing anyway; their terminal rows may be missing`),o&&this.rearmRoot(),{drained:s.length,timedOut:i}}rearmRoot(){this.rootController=new AbortController,this.abortGraph.rearm(this.rootId,this.rootController),this.parentAbortSignal?.aborted&&this.rootController.abort(this.parentAbortSignal.reason)}async teardownAll(){await Promise.allSettled([...this.active.values()].map(e=>e.teardown()))}};async function x_(t,e={}){let{failFast:n=!0,teardown:r=!0,maxConcurrency:o=di()}=e;if(t.length===0)return[];let s=new Array(t.length),i=new Set(t.map((c,l)=>l)),a=!1;return await bo(t.map((c,l)=>l),o,async c=>{let l=t[c];n&&a&&await l.handle.cancel().catch(()=>{});let d=await l.handle.runToResult(l.prompt);if(s[c]=d,i.delete(c),n&&d.status!=="succeeded"){a=!0;for(let u of i){let p=t[u];p&&p.handle.status==="running"&&p.handle.cancel().catch(()=>{})}}}),r&&await Promise.allSettled(t.map(c=>c.handle.teardown())),s}var _1=new Set([...bt,...$e,"memory_search","agent","skill"]);function R_(t){let e=new Set;for(let n of t){let r=bc(n,_1);r!==void 0&&e.add(r)}return e}P();P();import{existsSync as en,readdirSync as E1,readFileSync as A1}from"fs";import{join as Ct}from"path";var I_=["command","agent"];function C_(t=re()){let e=[],n=Ct(t,"skills");if(en(n))for(let r of Ic(n)){let o=Ct(n,r,"SKILL.md");en(o)&&e.push({path:o,type:"skill",source:"user"})}for(let r of I_){let o=Ct(t,`${r}s`);if(en(o))for(let s of Ic(o))s.endsWith(".md")&&e.push({path:Ct(o,s),type:r,source:"user"})}return e}function P_(t=Mn()){if(!en(t))return[];let e=[],n=xn(t);for(let r of n){let s=Wp(t,r.path)?.key,i=Ct(r.path,"skills");if(en(i))for(let a of Ic(i)){let c=Ct(i,a,"SKILL.md");if(!en(c))continue;let l={path:c,type:"skill",source:"plugin"};s&&(l.plugin_key=s),e.push(l)}for(let a of I_){let c=Ct(r.path,`${a}s`);if(en(c))for(let l of Ic(c)){if(!l.endsWith(".md"))continue;let d={path:Ct(c,l),type:a,source:"plugin"};s&&(d.plugin_key=s),e.push(d)}}}return e}function M_(t=Ct(re(),"settings.json")){if(!en(t))return[];try{let e=A1(t,"utf8"),r=JSON.parse(e).hooks;if(!r||typeof r!="object")return[];let o=[];for(let[s,i]of Object.entries(r))if(Array.isArray(i))for(let a=0;a<i.length;a++)o.push({event:s,index:a,raw:i[a]});return o}catch{return[]}}function Ic(t){try{return E1(t).filter(e=>!e.startsWith("."))}catch{return[]}}var L_=Y.object({path:Y.string(),type:Y.enum(["skill","command","agent","hook"]),source:Y.enum(["user","plugin"]),plugin_key:Y.string().optional(),verdict:Y.enum(["correct","misfit","outlier"]),recommended_type:Y.string(),rationale:Y.string(),confidence:Y.enum(["high","med","low"])}),F_=Y.record(Y.string(),Y.record(Y.string(),Y.number())),Tme=Y.object({inventory:Y.object({user:F_,plugin:F_}),misfits:Y.array(L_),briefs_written:Y.number(),total_artifacts:Y.number()}),x1=Y.object({writeBriefs:Y.boolean().optional(),scope:Y.enum(["user","plugin","all"]).optional()}),R1=["skill","command","agent"],N_=["skill","command","agent","hook"];function I1(t){return{runUserDiscovery:t!=="plugin",runPluginDiscovery:t!=="user",runHookInspector:t!=="plugin"}}function C1(t){let e=()=>{let s={};for(let i of N_)s[i]={correct:0,misfit:0,outlier:0};return s},n={user:e(),plugin:e()};for(let s of t)n[s.source][s.type][s.verdict]+=1;let r={high:0,med:1,low:2},o=t.filter(s=>s.verdict==="misfit").slice().sort((s,i)=>r[s.confidence]-r[i.confidence]);return{inventory:n,misfits:o}}function P1(t){return t.verdict==="misfit"&&t.confidence==="high"&&t.source==="user"}function M1(t){let e=t.filter(o=>o.source==="user"),n=t.filter(o=>o.source==="plugin"),r=["","## Discovered artifacts (audit only these)",""];if(r.push('### User-scope artifacts (set `"source": "user"`, omit `plugin_key`)'),e.length===0)r.push("(none discovered)");else for(let o of e)r.push(`- ${o.path}`);if(r.push(""),r.push('### Plugin-scope artifacts (set `"source": "plugin"`, copy `plugin_key` from each entry)'),n.length===0)r.push("(none discovered)");else for(let o of n){let s=o.plugin_key??"<unknown>";r.push(`- ${o.path} (plugin_key: ${s})`)}return r.join(`
|
|
1149
1149
|
`)}function O1(t,e){let n=["","## Discovered hooks (audit only these)",""];if(n.push(`Settings file (use this absolute path verbatim in each verdict's \`path\` field): \`${t}\``),n.push(""),e.length===0)return n.push("(no hooks discovered)"),n.join(`
|
|
1150
1150
|
`);for(let r of e){let o=`${r.event}-${r.index}`;n.push(`### Hook \`${o}\``),n.push(""),n.push("```json"),n.push(JSON.stringify(r.raw,null,2)),n.push("```"),n.push("")}return n.join(`
|
|
1151
1151
|
`)}function D1(t,e){if(!e)return{kind:"failure",message:`${t}: no result`};if(e.schemaError)return{kind:"failure",message:`${t}: schema mismatch \u2014 ${e.schemaError.message}`};if(e.status!=="succeeded"){let n=e.error?` \u2014 ${e.error.message}`:"";return{kind:"failure",message:`${t}: ${e.status}${n}`}}return e.output?{kind:"success",output:e.output}:{kind:"failure",message:`${t}: no output`}}async function F1(t,e,n){let r=n?.apiKey,o=Gt({defaultSubagentModel:n?.defaultSubagentModel,defaultModel:n?.defaultModel}),s=n?.callId,i=typeof t=="object"&&t!==null?t:{},a=x1.parse(i),c=a.writeBriefs??!0,l=a.scope??"all",d=I1(l);if(!e?.sessionId)throw new Error("audit-fit requires a parent session with sessionId");let u=e.sessionId,p=te("audit-fit"),f={skill:p["01-skill-inspector.md"],command:p["02-command-inspector.md"],agent:p["03-agent-inspector.md"],hook:p["04-hook-inspector.md"]};for(let F of N_)if(!f[F])throw new Error(`audit-fit skill missing inspector prompt for ${F}`);let m=d.runUserDiscovery?C_():[],g=d.runPluginDiscovery?P_():[],h={skill:[],command:[],agent:[]};for(let F of[...m,...g])h[F.type].push(F);let y=new G({apiKey:r,...n?.defaultModel!==void 0?{parentModel:n.defaultModel}:{},...n?.traceWriter!==void 0?{traceWriter:n.traceWriter}:{},...n?.workspaceStore!==void 0?{workspaceStore:n.workspaceStore}:{}}),w=R_(Sc.allowedTools),k=()=>async F=>w.has(F)?{behavior:"allow"}:{behavior:"deny",message:`Tool ${F} not allowed for audit-fit inspectors. Allowed tools: ${[...w].join(", ")}`},v=[];for(let F of R1){let L=h[F];if(L.length===0)continue;let D=f[F];D&&v.push({type:F,prompt:`${D}
|
|
@@ -1263,62 +1263,62 @@ ${r}`:t.text,sessionId:e.ctx.sessionId},t.text.length<=QK&&(yield{type:"suggesti
|
|
|
1263
1263
|
`)}function lq(t){let e=0;if(typeof t.content=="string")e+=t.content.length;else if(Array.isArray(t.content))for(let n of t.content){let r=n.type;r==="text"&&"text"in n?e+=n.text.length:r==="tool_use"?e+=mA(n.input).length:r==="tool_result"&&(e+=gA(n.content).length)}return e}var Wc={isFreshUserTurn:aq,renderMessage:cq,buildPreamble(t){return[{role:"user",content:Yo+`
|
|
1264
1264
|
|
|
1265
1265
|
`+t},{role:"assistant",content:Qo}]},countChars:lq};function dq(t){if(typeof t=="string")return An(t);if(Array.isArray(t)){let e=0;for(let n of t)n.type==="text"&&"text"in n&&(e+=An(n.text));return e}return 0}function uq(t){if(typeof t=="string")return br(t);if(Array.isArray(t)){for(let e of t)if(e.type==="text"&&"text"in e)return br(e.text)}return!1}var pq={listToolResults(t){let e=[];for(let n of t){if(n.role!=="user"||!Array.isArray(n.content))continue;let r=n.content;for(let o of r){if(o.type!=="tool_result")continue;let s=o;e.push({byteLength:dq(s.content),isPlaceholder:uq(s.content),clear(i){s.content=i}})}}return e}};function vf(t,e){return Ga(t,pq,e??{})}function dA(t,e,n,r){return xp(t,e,Wc,n,r)}function uA(t,e,n){let r=Rp(t,Wc);return{model:e,max_tokens:n,system:Vo,messages:[{role:"user",content:Zo(r)}],stream:!0}}function pA(t,e,n){return Ip(t,e,n,Wc)}function fA(t,e,n){return Cp(t,e,n,Wc)}function mA(t){try{let e=JSON.stringify(t);return e.length>240?e.slice(0,237)+"...":e}catch{return"{}"}}function gA(t){if(typeof t=="string")return t.length>320?t.slice(0,317)+"...":t;if(Array.isArray(t)){let e=[];for(let r of t)r.type==="text"&&"text"in r&&e.push(r.text);let n=e.join(" ");return n.length>320?n.slice(0,317)+"...":n}return""}I();var mq=2,gq="claude-haiku-4-5-20251001",hq=1024;async function yA(t){let{state:e,abort:n,retry:r,initSessionId:o,traceWriter:s}=t,i=e.messages.length;if(e.closed)return{compacted:!1,reason:"session-closed",messagesBefore:i,messagesAfter:i};if(!n.isIdle())return{compacted:!1,reason:"turn-in-flight",messagesBefore:i,messagesAfter:i};let a=yq(),c=no(pe(e.lastUsage??{}),gt(e.requestedModel)),l=dA(e.messages,a,c,bq());if(l<0)return hA(e,i,"history-too-short");if(l===0)return hA(e,i,"nothing-to-summarize");let d=e.messages.slice(0,l),u=wq(),p=uA(d,u,hq),f=n.begin(),m;try{if(f.signal.aborted)return{compacted:!1,reason:"aborted",messagesBefore:i,messagesAfter:i};let w=Ot(r.authMode,o,fq()),k=r.client,v=await Promise.resolve(k.messages.create(p,{headers:w,signal:f.signal}));m=await Sq(v)}catch(w){return f.signal.aborted?{compacted:!1,reason:"aborted",messagesBefore:i,messagesAfter:i}:{compacted:!1,reason:"summarization-failed: "+(w instanceof Error?w.message:String(w)),messagesBefore:i,messagesAfter:i}}finally{n.clear(f)}if(m.trim().length===0)return{compacted:!1,reason:"empty-summary",messagesBefore:i,messagesAfter:i};let g=fA(e.messages,l,m),h=pA(e.messages,l,m);e.messages.splice(0,e.messages.length,...h);let y=e.messages.length;return Qs(s,{trigger:"manual",preCompactionMessages:d,summary:m,keptTailCount:i-l,keepLastNConfig:a,messagesBefore:i,messagesAfter:y,tokensSavedEstimate:g}),vf(e.messages,bA()),{compacted:!0,messagesBefore:i,messagesAfter:y,tokensSavedEstimate:g}}function yq(){let t=b.AFK_COMPACT_KEEP_LAST_TURNS;if(t!==void 0&&t.length>0){let e=Number.parseInt(t,10);if(Number.isFinite(e)&&e>0)return e}return mq}function bq(){let t=b.AFK_COMPACT_SHRINK_FRACTION;if(t!==void 0&&t.length>0){let e=Number.parseFloat(t);if(Number.isFinite(e)&&e>0&&e<1)return e}return yr}function hA(t,e,n){let r=bA(),{blocksCleared:o,bytesReclaimed:s}=vf(t.messages,r);return o>0?{compacted:!1,reason:"microcompacted",messagesBefore:e,messagesAfter:t.messages.length,microcompaction:{blocksCleared:o,bytesReclaimed:s}}:{compacted:!1,reason:n,messagesBefore:e,messagesAfter:e}}function bA(){return wr(b.AFK_MICROCOMPACT_TOOL_RESULT_BYTES,b.AFK_MICROCOMPACT_KEEP_LAST)}function wq(){let t=b.AFK_COMPACT_MODEL;return t!==void 0&&t.length>0?he(t)??t:gq}async function Sq(t){let e="";for await(let n of t)if(n.type==="content_block_delta"){let r=n.delta;r.type==="text_delta"&&typeof r.text=="string"&&(e+=r.text)}return e}var wA=72;function Tf(t){if(typeof t=="string")return t;let e=[];for(let n of t)n.type==="text"&&typeof n.text=="string"&&e.push(n.text);return e.join(" ")}function SA(t){return t.role!=="user"?!1:Tf(t.content).trim().length>0}function kq(t){let e=t.replace(/\s+/g," ").trim();return e.length<=wA?e:e.slice(0,wA-1)+"\u2026"}function kA(t){let e=[];for(let n=0;n<t.length;n++){let r=t[n];r&&SA(r)&&e.push({turnIndex:n,preview:kq(Tf(r.content))})}return e.reverse()}function vA(t,e){let{state:n,abort:r}=t,o=n.messages.length;if(n.closed)return{rewound:!1,reason:"session-closed",messagesBefore:o,messagesAfter:o};if(!r.isIdle())return{rewound:!1,reason:"turn-in-flight",messagesBefore:o,messagesAfter:o};if(!Number.isInteger(e)||e<0||e>=o)return{rewound:!1,reason:"invalid-target",messagesBefore:o,messagesAfter:o};let s=n.messages[e];if(!s||!SA(s))return{rewound:!1,reason:"invalid-target",messagesBefore:o,messagesAfter:o};let i=Tf(s.content);return n.messages.splice(e),Hc(n.messages),{rewound:!0,reloadText:i,messagesBefore:o,messagesAfter:n.messages.length}}function TA(t){return yA(t)}function _A(t){return kA(t.messages)}function EA(t,e,n){return vA({state:t,abort:e},n)}var ys=class{initSessionId;promptStream;maxTokens;tools;systemPrefix;thinking;effort;temperature;baseUrl;maxToolUseIterations;softDeadlineMs;traceWriter;subagentId;state;abort;retry;cwdDependentsFactory;systemPromptRebuildFactory;onPermissionMode;mcpManager;hookRegistry;throttleQueue;fastModeController;beforeNextRound;constructor(e){this.initSessionId=e.sessionId??vq(),this.promptStream=e.promptStream,this.maxTokens=e.maxTokens,this.tools=e.tools,this.systemPrefix=e.systemPrefix,this.thinking=e.thinking,e.effort!==void 0&&(this.effort=e.effort),e.temperature!==void 0&&(this.temperature=e.temperature),e.baseUrl!==void 0&&(this.baseUrl=e.baseUrl),e.maxToolUseIterations!==void 0&&(this.maxToolUseIterations=e.maxToolUseIterations),e.softDeadlineMs!==void 0&&(this.softDeadlineMs=e.softDeadlineMs),this.traceWriter=e.traceWriter,e.subagentId!==void 0&&(this.subagentId=e.subagentId),this.cwdDependentsFactory=e.cwdDependentsFactory,this.systemPromptRebuildFactory=e.systemPromptRebuildFactory,this.onPermissionMode=e.onPermissionMode,this.mcpManager=e.mcpManager,e.hookRegistry!==void 0&&(this.hookRegistry=e.hookRegistry),e.throttleQueue!==void 0&&(this.throttleQueue=e.throttleQueue),e.fastModeController!==void 0&&(this.fastModeController=e.fastModeController),e.beforeNextRound!==void 0&&(this.beforeNextRound=e.beforeNextRound),this.retry=new jc({client:e.client,authMode:e.authMode,initSessionId:this.initSessionId,...e.baseUrl!==void 0?{baseUrl:e.baseUrl}:{},...e.tokenRefresher?{tokenRefresher:e.tokenRefresher}:{},autoResumeOnUsageLimit:e.autoResumeOnUsageLimit??!0,...e.surface!==void 0?{surface:e.surface}:{}}),this.state=pE({model:e.model,...e.requestedModel!==void 0?{requestedModel:e.requestedModel}:{},permissionMode:e.permissionMode??"default",userSystem:e.userSystem,toolDispatcher:e.toolDispatcher,...e.initialMessages?{initialMessages:e.initialMessages}:{},...e.autoCompactThreshold!==void 0?{autoCompactThreshold:e.autoCompactThreshold}:{},...e.initialUsageInputTokens!==void 0?{initialUsageInputTokens:e.initialUsageInputTokens}:{}}),this.abort=new hr}turnDriverContext(){let e=this;return{get initSessionId(){return e.initSessionId},get promptStream(){return e.promptStream},get state(){return e.state},get abort(){return e.abort},get retry(){return e.retry},get maxTokens(){return e.maxTokens},get tools(){return e.tools},get thinking(){return e.thinking},get effort(){return e.effort},get temperature(){return e.temperature},get baseUrl(){return e.baseUrl},get maxToolUseIterations(){return e.maxToolUseIterations},get softDeadlineMs(){return e.softDeadlineMs},get traceWriter(){return e.traceWriter},get subagentId(){return e.subagentId},get mcpManager(){return e.mcpManager},get hookRegistry(){return e.hookRegistry},get throttleQueue(){return e.throttleQueue},get fastModeController(){return e.fastModeController},get beforeNextRound(){return e.beforeNextRound},composeSystem:()=>e.composeSystem(),makeInterruptedTurnEvent:()=>e.makeInterruptedTurnEvent(),compact:()=>e.compact()}}setBeforeNextRound(e){this.beforeNextRound=e}async*[Symbol.asyncIterator](){yield*eA(this.turnDriverContext())}composeSystem(){return oA({state:this.state,systemPrefix:this.systemPrefix,...this.baseUrl!==void 0?{baseUrl:this.baseUrl}:{}})}async interrupt(e="interrupted"){this.abort.requestAbort(e)}makeInterruptedTurnEvent(){return lA(this.initSessionId)}async setModel(e){sA(this.state,e)}async setPermissionMode(e){iA({state:this.state,mode:e,...this.onPermissionMode?{onPermissionMode:this.onPermissionMode}:{}})}setCwd(e){aA({state:this.state,cwd:e,...this.cwdDependentsFactory?{cwdDependentsFactory:this.cwdDependentsFactory}:{}})}setSystemPrompt(e){return cA({state:this.state,basePrompt:e,...this.systemPromptRebuildFactory?{systemPromptRebuildFactory:this.systemPromptRebuildFactory}:{}})}async supportedCommands(){return Ua()}async supportedModels(){return QE()}async supportedAgents(){return[]}async getContextUsage(){return tA(this.state)}async mcpServerStatus(){return nA(this.mcpManager)}async accountInfo(){return rA(this.retry.authMode)}async reauth(){return this.retry.forceClientRefresh()}async rewindFiles(e,n){return{canRewind:!1,error:"anthropic-direct provider does not support file checkpoint rewind"}}async compact(){let e=await TA({state:this.state,abort:this.abort,retry:this.retry,initSessionId:this.initSessionId,...this.traceWriter?{traceWriter:this.traceWriter}:{}});return e.compacted&&(this.state.lastUsage=null),e}listRewindTargets(){return _A(this.state)}async rewindConversation(e){return EA(this.state,this.abort,e)}close(){this.state.closed=!0,this.abort.requestAbort("closed"),this.abort.markClosed()}};function AA(t){return e=>{let n=t.getCurrentCwd();if(t.sharedReadRoots&&n!==void 0&&n!==e){let s=t.sharedReadRoots.indexOf(n);s!==-1?t.sharedReadRoots[s]=e:t.sharedReadRoots.includes(e)||t.sharedReadRoots.push(e)}if(t.sharedWriteRoots&&n!==void 0&&n!==e){let s=t.sharedWriteRoots.indexOf(n);s!==-1?t.sharedWriteRoots[s]=e:t.sharedWriteRoots.includes(e)||t.sharedWriteRoots.push(e)}t.setCurrentCwd(e),t.subagentExecutor?.setCwd(e),t.skillExecutor?.setCwd(e),t.composeExecutor?.setCwd(e);let r=Ar(t.stableSystemPrefix,e,{surface:t.surface,sessionId:t.config.sessionId,depth:t.config.depth,maxDepth:t.config.maxDepth,workspace:t.runtimeStateSource.getWorkspace()}),o=t.buildDispatcher(t.getCurrentPermissionMode(),{cwd:e,readRoots:t.sharedReadRoots,writeRoots:t.sharedWriteRoots,...t.config.env!==void 0?{env:t.config.env}:{},sessionId:t.config.sessionId,parentSessionId:t.config.parentSessionId,traceWriter:t.config.traceWriter,runtimeStateSource:t.runtimeStateSource,hookRegistry:t.config.hookRegistry,planExitControls:t.config.planExitControls});return{userSystem:r,dispatcher:o}}}function xA(t){return e=>{t.stableSystemPrefix.userSystem=e!==void 0&&e.length>0?e:null;let n=t.getCurrentCwd()??t.fallbackCwd;return Ar(t.stableSystemPrefix,n,{surface:t.surface,sessionId:t.config.sessionId,depth:t.config.depth,maxDepth:t.config.maxDepth,workspace:t.runtimeStateSource.getWorkspace()})}}function RA(t,e,n){let r=e.config,{client:o,authMode:s,localMode:i,model:a,maxTokens:c,cwd:l,systemPrefix:d,throttleQueue:u,tokenRefresher:p,queryDispatcher:f,runtimeStateSource:m,toolDefs:g,resolvedSessionId:h,stableSystemPrefix:y,toolSystemAppend:w}=n,k=h,v=wg(r.resumeHistory),R=r.resumeHistory?.at(-1)?.inputTokens,A=t.externalTools?void 0:AA({stableSystemPrefix:y,config:r,surface:t.surface,runtimeStateSource:m,getCurrentCwd:()=>t.getCurrentCwd(),setCurrentCwd:O=>{t.setCurrentCwd(O)},getCurrentPermissionMode:()=>t.getCurrentPermissionMode(),sharedReadRoots:t.getSharedReadRoots(),sharedWriteRoots:t.getSharedWriteRoots(),subagentExecutor:t.subagentExecutor,skillExecutor:t.skillExecutor,composeExecutor:t.composeExecutor,buildDispatcher:(O,K)=>t.buildDispatcher(O,K)}),M=t.externalTools?void 0:xA({stableSystemPrefix:y,config:r,surface:t.surface,runtimeStateSource:m,getCurrentCwd:()=>t.getCurrentCwd(),fallbackCwd:l}),S=ai(r.effort,a),T=r.temperature!==void 0?bg(r.temperature):void 0,E=oo(r.autoCompact,typeof r.model=="string"&&r.model.length>0?r.model:a);return new ys({client:o,authMode:i?"api-key":s,promptStream:e.prompt,toolDispatcher:f,...k!==void 0?{sessionId:k}:{},...v!==void 0?{initialMessages:v}:{},...R!==void 0?{initialUsageInputTokens:R}:{},model:a,requestedModel:typeof r.model=="string"&&r.model.length>0?r.model:a,...r.permissionMode!==void 0?{permissionMode:r.permissionMode}:{},maxTokens:c,tools:g,userSystem:w,systemPrefix:d,tokenRefresher:p,...r.thinking!==void 0?{thinking:ii(r.thinking,c,a)}:{},...S!==void 0?{effort:S}:{},...T!==void 0?{temperature:T}:{},...i?{baseUrl:r.baseUrl}:{},...r.traceWriter?{traceWriter:r.traceWriter}:{},...r.subagentId!==void 0?{subagentId:r.subagentId}:{},...r.autoResumeOnUsageLimit!==void 0?{autoResumeOnUsageLimit:r.autoResumeOnUsageLimit}:{},surface:t.declaredSurface,...r.maxToolUseIterations!==void 0?{maxToolUseIterations:r.maxToolUseIterations}:{},...r.softDeadlineMs!==void 0?{softDeadlineMs:r.softDeadlineMs}:{},...A!==void 0?{cwdDependentsFactory:A}:{},...M!==void 0?{systemPromptRebuildFactory:M}:{},onPermissionMode:O=>{t.setCurrentPermissionMode(O)},...t.mcpManager!==void 0?{mcpManager:t.mcpManager}:{},...E!==void 0?{autoCompactThreshold:E}:{},...r.hookRegistry!==void 0?{hookRegistry:r.hookRegistry}:{},...u!==void 0?{throttleQueue:u}:{},...t.fastModeController!==void 0?{fastModeController:t.fastModeController}:{}})}var _f="anthropic-direct",IA=Yr,Rt=class{name=_f;externalTools;memoryStore;workspaceStore;stateStore;providerFactory;skillExecutor;schemas;hookRegistry;permissions;canUseTool;subagentExecutor;composeExecutor;surface;declaredSurface;readOnlyMemory;readOnlyBash;mcpManager;customTools;fastModeController;grants=new ci;_mcpToolsCache=null;_mcpHandlersCache=null;_presenceSessionId=null;_mintedSessionId=null;_spawnedPidRegistry=new dr;constructor(e={}){if(this.memoryStore=e.memoryStore??new wt,this.workspaceStore=e.workspaceStore,this.stateStore=e.stateStore??new lr(Ws()),this.externalTools=e.tools,this.skillExecutor=e.skillExecutor,this.schemas=rv(e),this.hookRegistry=e.hookRegistry,this.permissions=e.permissions,this.canUseTool=e.canUseTool,this.subagentExecutor=e.subagentExecutor,this.composeExecutor=e.composeExecutor,this.surface=e.surface??"cli",this.declaredSurface=e.surface,this.readOnlyMemory=e.readOnlyMemory===!0,this.readOnlyBash=e.readOnlyBash===!0,this.customTools=e.customTools??[],this.fastModeController=e.fastModeController,this.mcpManager=e.mcpManager,e.mcpManager){let n=e.mcpManager.onToolsRefreshed;e.mcpManager.onToolsRefreshed=r=>{this._mcpToolsCache=null,this._mcpHandlersCache=null,n?.(r)}}e.clientFactory&&(this.providerFactory=e.clientFactory)}buildDispatcher(e,n){return ev({memoryStore:this.memoryStore,workspaceStore:this.workspaceStore,stateStore:this.stateStore,surface:this.surface,readOnlyMemory:this.readOnlyMemory,readOnlyBash:this.readOnlyBash,customTools:this.customTools,mcpManager:this.mcpManager,schemas:this.schemas,hookRegistry:this.hookRegistry,permissions:this.permissions,canUseTool:this.canUseTool,subagentExecutor:this.subagentExecutor,skillExecutor:this.skillExecutor,composeExecutor:this.composeExecutor,sessionGrantManager:this,getMcpToolsCache:()=>this._mcpToolsCache,setMcpToolsCache:r=>{this._mcpToolsCache=r},getMcpHandlersCache:()=>this._mcpHandlersCache,setMcpHandlersCache:r=>{this._mcpHandlersCache=r}},e,{...n,spawnedPidRegistry:this._spawnedPidRegistry})}close(){this.memoryStore.close(),this.workspaceStore?.close(),this.stateStore.close()}async complete(e){let n=e.apiKey&&e.apiKey.length>0?e.apiKey:b.ANTHROPIC_API_KEY||b.CLAUDE_CODE_OAUTH_TOKEN||"";if(!n)throw new Error(`${_f} complete() requires an API key or OAuth token (config apiKey, ANTHROPIC_API_KEY, or CLAUDE_CODE_OAUTH_TOKEN)`);let r={token:n,model:e.model??IA,system:e.system,user:e.user,maxTokens:e.maxTokens??64};e.signal&&(r.signal=e.signal);let o=this.providerFactory??Aa();return o&&(r.clientFactory=o),ug(r)}addReadRoot(e,n="slash",r){this.grants.manager.addReadRoot(e,n,r)}addWriteRoot(e,n="slash",r){this.grants.manager.addWriteRoot(e,n,r)}revokeRoot(e,n="slash",r){this.grants.manager.revokeRoot(e,n,r)}getGrants(){return this.grants.manager.getGrants()}queryContext(){let e=this;return{get externalTools(){return e.externalTools},get providerFactory(){return e.providerFactory},get skillExecutor(){return e.skillExecutor},get subagentExecutor(){return e.subagentExecutor},get composeExecutor(){return e.composeExecutor},get canUseTool(){return e.canUseTool},get surface(){return e.surface},get declaredSurface(){return e.declaredSurface},get readOnlyMemory(){return e.readOnlyMemory},get workspaceStore(){return e.workspaceStore},get mcpManager(){return e.mcpManager},get fastModeController(){return e.fastModeController},getSharedReadRoots:()=>e.grants.readRoots,getSharedWriteRoots:()=>e.grants.writeRoots,getCurrentCwd:()=>e.grants.currentCwd,setCurrentCwd:n=>{e.grants.currentCwd=n},getCurrentPermissionMode:()=>e.grants.permissionMode,setCurrentPermissionMode:n=>{e.grants.permissionMode=n},getMintedSessionId:()=>e._mintedSessionId,setMintedSessionId:n=>{e._mintedSessionId=n},getPresenceSessionId:()=>e._presenceSessionId,setPresenceSessionId:n=>{e._presenceSessionId=n},ensureSharedRoots:n=>{e.grants.ensureInitialized(n)},buildDispatcher:(n,r)=>e.buildDispatcher(n,r)}}query(e){let n=this.queryContext(),r=uE(n,e,_f,IA);return RA(n,e,r)}},CA=new Rt;I();P();import{chmodSync as _q,existsSync as Eq,mkdirSync as Aq,readFileSync as xq,unlinkSync as Rq,writeFileSync as Iq}from"node:fs";import{dirname as Cq,join as Pq}from"node:path";function xr(){return Pq(Q(),"xai","auth.json")}function Mq(t){try{return xq(t,"utf-8")}catch{return null}}function Oq(t,e,n){Iq(t,e,{encoding:"utf-8",mode:n})}function Dq(t,e){_q(t,e)}function Fq(t){Aq(t,{recursive:!0})}function Lq(t){try{Rq(t)}catch{}}function Nq(t){let e;try{e=JSON.parse(t)}catch{return null}if(typeof e!="object"||e===null)return null;let n=e,r=n.access_token,o=n.refresh_token,s=n.expires_at;if(typeof r!="string"||r.length===0||typeof o!="string"||o.length===0||typeof s!="number"||!Number.isFinite(s))return null;let i={access_token:r,refresh_token:o,expires_at:s};return typeof n.token_type=="string"&&(i.token_type=n.token_type),typeof n.scope=="string"&&(i.scope=n.scope),i}function Rr(t={}){let e=(t.authPath??xr)(),r=(t.readFile??Mq)(e);return r===null?null:Nq(r)}function Ef(t,e={}){let n=(e.authPath??xr)(),r=e.mkdir??Fq,o=e.writeFile??Oq,s=e.chmod??Dq;r(Cq(n));let i={access_token:t.access_token,refresh_token:t.refresh_token,expires_at:t.expires_at};t.token_type!==void 0&&(i.token_type=t.token_type),t.scope!==void 0&&(i.scope=t.scope),o(n,`${JSON.stringify(i,null,2)}
|
|
1266
|
-
`,384),s(n,384)}function Af(t={}){let e=(t.authPath??xr)(),n=t.exists??(o=>Eq(o)),r=t.unlink??Lq;n(e)&&r(e)}function Kc(t){return t.length<=4?t:t.slice(-4)}I();I();import{readFileSync as Uq}from"node:fs";import{homedir as $q}from"node:os";import{join as Bq}from"node:path";var xf="cli-chat-proxy.grok.com",PA="1.0.5",jq="AFK_XAI_GROK_CLIENT_VERSION",Hq=/^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;function Rf(t){let e=t?.trim();return e&&Hq.test(e)?e:void 0}function Wq(t,e){if(!t)return;let n=l=>l.split(".").map(Number),[r=0,o=0,s=0]=n(t),[i=0,a=0,c=0]=n(e);return r!==i?r>i?t:void 0:o!==a?o>a?t:void 0:s>=c?t:void 0}function Kq(t={}){let e=t.readFile??(r=>Uq(r,"utf-8")),n=t.homeDir??$q;try{let r=e(Bq(n(),".grok","version.json")),o=JSON.parse(r);if(typeof o!="object"||o===null)return;let s=o.version;return typeof s!="string"?void 0:Rf(s)}catch{return}}function qq(t,e){let n=e.readEnv??(r=>b[r]);return Rf(n(jq))??Rf(t)??Wq(Kq(e),PA)??PA}function If(t){try{let e=new URL(t).hostname.toLowerCase();return e===xf||e.endsWith(`.${xf}`)}catch{return t.toLowerCase().includes(xf)}}function Cf(t={},e={}){let n=qq(t.clientVersion,e),r=t.clientIdentifier?.trim()||"grok-shell";return{"X-XAI-Token-Auth":"xai-grok-cli","x-grok-client-version":n,"x-grok-client-identifier":r,"User-Agent":`agent-afk (grok-cli-compat/${n})`}}var bs="https://api.x.ai/v1",Ir="https://cli-chat-proxy.grok.com/v1";function Gq(t){if(t==="AFK_XAI_BASE_URL")return b.AFK_XAI_BASE_URL;if(t==="AFK_XAI_OAUTH_BASE_URL")return b.AFK_XAI_OAUTH_BASE_URL}function Cr(t,e={}){let n=e.readEnv??Gq,r=e.baseUrlOverride?.trim();if(r){let c=Pf(r),l=If(c);return{baseURL:c,defaultHeaders:l?Cf({clientVersion:e.clientVersion},e.headerDeps):{},mode:t,proxyHeadersApplied:l}}if(t==="apikey"){let c=n("AFK_XAI_BASE_URL"),l=c&&c.trim()||bs;return{baseURL:Pf(l),defaultHeaders:{},mode:t,proxyHeadersApplied:!1}}let o=n("AFK_XAI_OAUTH_BASE_URL"),s=Pf(o&&o.trim()||Ir),i=If(s),a=i?Cf({clientVersion:e.clientVersion},e.headerDeps):{};return{baseURL:s,defaultHeaders:a,mode:t,proxyHeadersApplied:i}}function Pf(t){return t.endsWith("/")?t.slice(0,-1):t}function Xq(t){if(t==="XAI_API_KEY")return b.XAI_API_KEY}function zq(t,e){if(t&&t.length>0)return{key:t,source:"config"};let n=e("XAI_API_KEY");return n&&n.length>0?{key:n,source:"env"}:null}function Jq(t){let e=Rr(t.store??{});return e?{bundle:e,last4:Kc(e.access_token)}:null}function pt(t,e=void 0,n={}){let r=n.readEnv??Xq,o=zq(t,r),s=Jq(n);return e==="oauth"?s?{apiKey:s.bundle.access_token,source:"xai-oauth",mode:"oauth",last4:s.last4,expiresAt:s.bundle.expires_at}:{apiKey:null,source:"no-usable-auth-forced-xai-oauth",mode:"oauth"}:e==="apikey"?o?{apiKey:o.key,source:o.source,mode:"apikey",last4:Kc(o.key),...o.source==="env"?{envVar:"XAI_API_KEY"}:{}}:{apiKey:null,source:"no-usable-auth-forced-xai-apikey",mode:"apikey"}:o&&s?{apiKey:null,source:"ambiguous-auth"}:o?{apiKey:o.key,source:o.source,mode:"apikey",last4:Kc(o.key),...o.source==="env"?{envVar:"XAI_API_KEY"}:{}}:s?{apiKey:s.bundle.access_token,source:"xai-oauth",mode:"oauth",last4:s.last4,expiresAt:s.bundle.expires_at}:{apiKey:null,source:"no-usable-auth"}}function Vq(t,e){if(typeof t!="number")return"";let n=(e??(()=>Math.floor(Date.now()/1e3)))(),r=t-n;if(r<=0)return", EXPIRED \u2014 re-run `afk provider auth xai login`";let o=Math.floor(r/3600),s=Math.floor(r%3600/60);return`, expires in ${o>0?`${o}h `:""}${s}m`}function Pr(t,e={}){switch(t.source){case"config":return`using explicit AFK config xAI API key (\u2026${t.last4??"????"})`;case"env":return`using XAI_API_KEY env var (\u2026${t.last4??"????"})`;case"xai-oauth":{let n=Vq(t.expiresAt,e.nowSeconds);return`using SuperGrok / SuperGrok Heavy / X Premium+ OAuth (\u2026${t.last4??"????"}${n})`}case"no-usable-auth-forced-xai-oauth":return"This model's slot/provider is `xai-oauth` but no SuperGrok OAuth tokens were found. Run `afk provider auth xai login` (device-code by default), or switch to `xai` with XAI_API_KEY.";case"no-usable-auth-forced-xai-apikey":return"This model's slot/provider is `xai` (API-key mode) but no XAI_API_KEY / config key was found. Set XAI_API_KEY, or use `xai-oauth` after `afk provider auth xai login`.";case"ambiguous-auth":return"Both XAI_API_KEY and SuperGrok OAuth tokens are present. Choose explicitly: `--provider xai` (API key \u2192 "+bs+") or `--provider xai-oauth` (subscription OAuth \u2192 "+Ir+").";default:return"No xAI auth found. Set XAI_API_KEY for metered API access, or run `afk provider auth xai login` for SuperGrok / SuperGrok Heavy / X Premium+."}}function Mf(t,e){let n=e.baseURL??(e.mode==="oauth"?Ir:bs),r=(e.bodySnippet??"").slice(0,180);return t===402?`xAI returned HTTP 402 on ${n}`+(r?` (${r})`:"")+". This is usually a subscription/spend gate (e.g. personal-team-blocked), not a missing login. Check SuperGrok / SuperGrok Heavy / X Premium+ status, try the other endpoint via AFK_XAI_OAUTH_BASE_URL or AFK_XAI_BASE_URL, or use a metered XAI_API_KEY with `--provider xai`.":t===403?`xAI returned HTTP 403 on ${n}`+(r?` (${r})`:"")+`. After SuperGrok OAuth login this often means the account lacks OAuth API entitlement, the model requires SuperGrok Heavy, or traffic hit api.x.ai instead of the CLI chat proxy. Try AFK_XAI_OAUTH_BASE_URL=${Ir} (default for xai-oauth), or fall back to XAI_API_KEY with \`--provider xai\`.`:`xAI returned HTTP ${t} on ${n}`+(r?`: ${r}`:"")}function qc(t,e,n){if(e===!0)return"oauth";if(n===!0)return"apikey";if(t==="apikey"||t==="oauth")return t}function Of(t,e){return e!==void 0?e:qc(t,void 0,void 0)}function MA(t,e){if(t==="xai-oauth")return"oauth";if(e)return"apikey"}var Df="https://auth.x.ai",Gc="b1a00492-073a-47ea-816f-4c329264a828",Yq="openid profile email offline_access grok-cli:access api:access",xke=`${Yq} conversations:read conversations:write`;var Qq=56121,Zq=`http://127.0.0.1:${Qq}/callback`;var Xc=180;var eG=1440*60*1e3,zc=null;function Je(t){return typeof t=="string"&&t.length>0?t:void 0}async function Jc(t={}){let e=t.fetchFn??fetch,n=(t.issuer??Df).replace(/\/$/,""),r=`${n}/.well-known/openid-configuration`,o=await e(r,{method:"GET"});if(!o.ok)throw new Error(`xAI OIDC discovery failed: HTTP ${o.status} from ${r}`);let s=await o.json(),i=Je(s.authorization_endpoint),a=Je(s.token_endpoint);if(!i||!a)throw new Error("xAI OIDC discovery missing authorization_endpoint or token_endpoint");let c=new URL(n).origin,l=Je(s.issuer);if(l){let m;try{m=new URL(l).origin}catch{throw new Error("xAI OIDC discovery: body issuer origin does not match configured issuer")}if(m!==c)throw new Error("xAI OIDC discovery: body issuer origin does not match configured issuer")}let d=l??n;if(new URL(i).origin!==c)throw new Error("xAI OIDC discovery: authorization_endpoint origin does not match issuer");if(new URL(a).origin!==c)throw new Error("xAI OIDC discovery: token_endpoint origin does not match issuer");let u={issuer:d,authorization_endpoint:i,token_endpoint:a},p=Je(s.device_authorization_endpoint);if(p){if(new URL(p).origin!==c)throw new Error("xAI OIDC discovery: device_authorization_endpoint origin does not match issuer");u.device_authorization_endpoint=p}let f=Je(s.userinfo_endpoint);if(f){if(new URL(f).origin!==c)throw new Error("xAI OIDC discovery: userinfo_endpoint origin does not match issuer");u.userinfo_endpoint=f}return u}async function Vc(t={}){let n=(t.nowMs??(()=>Date.now()))();if(zc&&zc.expiresAt>n)return zc.result;let r=await Jc(t);return zc={result:r,expiresAt:n+eG},r}function ws(t,e,n){let r=Je(t.access_token);if(!r)return null;let o=Je(t.refresh_token)??n;if(!o)return null;let s=(e??(()=>Math.floor(Date.now()/1e3)))(),i=typeof t.expires_in=="number"?t.expires_in:3600,a=Math.min(Math.max(i,Xc+60),86400),c={access_token:r,refresh_token:o,expires_at:s+a};return typeof t.token_type=="string"&&(c.token_type=t.token_type),typeof t.scope=="string"&&(c.scope=t.scope),c}var Ff=new Map;function lG(t){return t?.authPath?t.authPath():xr()}async function OA(t,e={}){let n=await Vc(e),r=e.fetchFn??fetch,o=e.clientId??Gc,s=new URLSearchParams({grant_type:"refresh_token",refresh_token:t,client_id:o}),i=await r(n.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:s.toString()}),a=await i.json().catch(()=>({}));if(!i.ok){let l=Je(a.error)??`http_${i.status}`,d=Je(a.error_description);throw new Error(`xAI token refresh failed: ${d?`${l}: ${d}`:l}`)}let c=ws(a,e.nowSeconds,t);if(!c)throw new Error("xAI refresh response missing access_token");return e.persist!==!1&&Ef(c,e.store??{}),c}async function Ss(t={}){let e=t.store??{},n=Rr(e);if(!n)return null;let r=(t.nowSeconds??(()=>Math.floor(Date.now()/1e3)))(),o=t.skewSeconds??Xc;if(n.expires_at-o>r)return n;let s=lG(e),i=Ff.get(s);if(i)try{return await i}catch{return Rr(e)}let a=(async()=>{try{return await OA(n.refresh_token,{...t,store:e,persist:!0})}catch(c){throw n.expires_at<=r&&Af(e),c}finally{Ff.delete(s)}})();Ff.set(s,a);try{return await a}catch{return n.expires_at>r?n:null}}function Yc(t){return typeof t!="number"?!1:t<=Math.floor(Date.now()/1e3)}function Lf(t,e){let n=Yt(t);if(n!==402&&n!==403)return t instanceof Error?t:new Error(String(t));let r=t instanceof Error?t.message:typeof t=="string"?t:void 0,o=Cr(e);return new Error(Mf(n,{mode:e,baseURL:o.baseURL,...r!==void 0?{bodySnippet:r}:{}}))}function DA(t){return{async*[Symbol.asyncIterator](){yield{type:"error",error:new Error(t)}},async interrupt(){},async setModel(){},async setPermissionMode(){},async supportedCommands(){return[]},async supportedModels(){return[]},async supportedAgents(){return[]},async getContextUsage(){return{}},async mcpServerStatus(){return[]},async accountInfo(){return{}},async rewindFiles(){return{canRewind:!1,error:t}},async close(){}}}function FA(t,e){return t==="oauth"||t==="apikey"?t:e()}function LA(t){let{args:e,forceMode:n,authDeps:r,getLastMode:o,delegate:s}=t,i,a,c,l,d,u=async()=>{if(a)throw a;return i||c||(c=(async()=>{try{n!=="apikey"&&await Ss({store:r.store});let p=pt(e.config.apiKey,n,r);if(p.apiKey===null||!p.mode)throw new Error(Pr(p));if(p.mode==="oauth"&&Yc(p.expiresAt))throw new Error("SuperGrok OAuth access token expired and refresh failed. Re-run `afk provider auth xai login`.");return i=s(e,p.apiKey,p.mode),l!==void 0&&i.setCwd?.(l),d!==void 0&&i.setSystemPrompt?.(d===null?void 0:d),i}catch(p){throw a=p instanceof Error?p:new Error(String(p)),a}finally{c=void 0}})(),c)};return{async*[Symbol.asyncIterator](){try{let p=await u();for await(let f of p)f.type==="error"?yield{type:"error",error:Lf(f.error,FA(n,o))}:yield f}catch(p){let f=p instanceof Error?p:new Error(String(p));yield{type:"error",error:Lf(f,FA(n,o))}}},async interrupt(p){await(i??await u().catch(()=>{}))?.interrupt(p)},async setModel(p){await(i??await u().catch(()=>{}))?.setModel(p)},async setPermissionMode(p){await(i??await u().catch(()=>{}))?.setPermissionMode(p)},setCwd(p){l=p,i?.setCwd?.(p)},setSystemPrompt(p){return d=p===void 0?null:p,i?.setSystemPrompt?.(p)??!1},async reauth(){return await(i??await u().catch(()=>{}))?.reauth?.()??null},async supportedCommands(){return await(i??await u().catch(()=>{}))?.supportedCommands()??[]},async supportedModels(){return await(i??await u().catch(()=>{}))?.supportedModels()??[]},async supportedAgents(){return await(i??await u().catch(()=>{}))?.supportedAgents()??[]},async getContextUsage(){return await(i??await u().catch(()=>{}))?.getContextUsage()??{}},async mcpServerStatus(){return await(i??await u().catch(()=>{}))?.mcpServerStatus()??[]},async accountInfo(){return await(i??await u().catch(()=>{}))?.accountInfo()??{}},async rewindFiles(p,f){let m=i??await u().catch(()=>{});return m?m.rewindFiles(p,f):{canRewind:!1,error:"xAI provider not initialized"}},async compact(){let p=i??await u().catch(()=>{});return p?.compact?p.compact():{compacted:!1,reason:"provider does not support compaction",messagesBefore:0,messagesAfter:0}},listRewindTargets(){return i?.listRewindTargets?.()??[]},async rewindConversation(p){let f=i??await u().catch(()=>{});return f?.rewindConversation?f.rewindConversation(p):{rewound:!1,reason:"not-supported",messagesBefore:0,messagesAfter:0}},async close(){await i?.close()}}}var dG="xai",ks=class{name=dG;inner;authMode;authDeps;lastMode="apikey";lastResolvedMode;lastXaiBaseUrl;constructor(e={}){let{authMode:n,authDeps:r,...o}=e;this.authMode=n,this.authDeps=r??{},this.inner=new Ge(o)}query(e){let n=qc(this.authMode,e.config.forceXaiOAuth,e.config.forceXaiApiKey);return n==="oauth"||n===void 0?LA({args:e,forceMode:n,authDeps:this.authDeps,getLastMode:()=>this.lastMode,delegate:(r,o,s)=>this.delegateToInner(r,o,s)}):this.querySync(e,n)}querySync(e,n){let r=pt(e.config.apiKey,n,this.authDeps);return r.apiKey===null||!r.mode?DA(Pr(r)):this.delegateToInner(e,r.apiKey,r.mode)}delegateToInner(e,n,r){this.rememberResolved(r,e.config.xaiBaseUrl);let o=Cr(r,{readEnv:this.authDeps.readEnv?i=>this.authDeps.readEnv(i):void 0,...e.config.xaiBaseUrl!==void 0?{baseUrlOverride:e.config.xaiBaseUrl}:{}});this.inner.setEndpointDefaults({baseURL:o.baseURL,defaultHeaders:o.defaultHeaders});let s={...e.config,apiKey:n,openaiBaseUrl:o.baseURL,forceChatgptOAuth:!1,forceXaiOAuth:r==="oauth",forceXaiApiKey:r==="apikey"};return this.inner.query({...e,config:s})}rememberResolved(e,n){this.lastMode=e,this.lastResolvedMode=e,this.lastXaiBaseUrl=n}addReadRoot(e,n="slash",r){this.inner.addReadRoot(e,n,r)}addWriteRoot(e,n="slash",r){this.inner.addWriteRoot(e,n,r)}revokeRoot(e,n="slash",r){this.inner.revokeRoot(e,n,r)}getGrants(){return this.inner.getGrants()}close(){this.inner.close()}async complete(e){let n=Of(this.authMode,this.lastResolvedMode);(n==="oauth"||n===void 0)&&await Ss({store:this.authDeps.store});let r=pt(e.apiKey,n,this.authDeps);if(r.apiKey===null||!r.mode)throw new Error(Pr(r));if(r.mode==="oauth"&&Yc(r.expiresAt))throw new Error("SuperGrok OAuth access token expired and refresh failed. Re-run `afk provider auth xai login`.");this.rememberResolved(r.mode,this.lastXaiBaseUrl);let o=Cr(r.mode,{readEnv:this.authDeps.readEnv,...this.lastXaiBaseUrl!==void 0?{baseUrlOverride:this.lastXaiBaseUrl}:{}});return this.inner.setEndpointDefaults({baseURL:o.baseURL,defaultHeaders:o.defaultHeaders}),this.inner.complete({...e,apiKey:r.apiKey,baseUrl:o.baseURL})}};I();var uG=new Set([...Object.keys(td),"auto"]);function pG(t){if(!t)return;let e=t.trim().toLowerCase();if(e){if(e==="anthropic"||e==="anthropic-direct")return"anthropic-direct";if(e==="openai"||e==="openai-compatible"||e==="openai-codex")return"openai-compatible";if(e==="xai")return"xai";if(e==="xai-oauth"||e==="xai_oauth")return"xai-oauth"}}function z(t,e){let n=e?.explicit??b.AFK_PROVIDER,r=e?.openaiBaseUrl??b.AFK_OPENAI_BASE_URL,o=pG(n);if(o)return o;let s=ln(t,e?.slots);if(s.provider==="anthropic")return"anthropic-direct";if(s.provider==="openai"||s.provider==="chatgpt-oauth")return"openai-compatible";if(s.provider==="xai")return"xai";if(s.provider==="xai-oauth")return"xai-oauth";let i=s.id.trim().toLowerCase();return i&&(uG.has(i)||i.startsWith("claude-")||i.startsWith("claude_")||i.startsWith("local-")||i.startsWith("local_"))?"anthropic-direct":i&&(i.startsWith("grok-")||i.startsWith("grok_")||i==="grok")?"xai":i&&(i.startsWith("gpt-")||i.startsWith("gpt_")||dn(i)||i.startsWith("codex-")||i.startsWith("codex_")||i==="codex"||i.startsWith("deepseek-")||i.startsWith("deepseek_")||i.startsWith("mistral-")||i.startsWith("mistral_")||i.startsWith("mixtral-")||i.startsWith("mixtral_")||i.startsWith("llama-")||i.startsWith("llama_")||i.startsWith("qwen-")||i.startsWith("qwen_")||i.includes("/"))||s.baseUrl&&s.baseUrl.trim()||r&&r.trim()?"openai-compatible":"anthropic-direct"}function Qc(t,e,n){let r=z(t,e),o=n?.customTools,s=n?.canUseTool,i={...o!==void 0&&o.length>0?{customTools:o}:{},...s!==void 0?{canUseTool:s}:{}};switch(r){case"openai-compatible":case"openai-codex":return new Ge(i);case"xai":case"xai-oauth":{let a=(e?.explicit??b.AFK_PROVIDER)?.trim().toLowerCase()??"",d=MA(r==="xai-oauth"||a==="xai-oauth"||a==="xai_oauth"?"xai-oauth":"xai",a==="xai"||a==="xai-oauth"||a==="xai_oauth"||r==="xai-oauth");return new ks({...i,...d!==void 0?{authMode:d}:{}})}default:return new Rt(i)}}var Mr=class{pendingResolve=null;bufferedMessages=[];getSessionId;constructor(e){this.getSessionId=e}pushUserMessage(e){if(this.pendingResolve){let n=this.pendingResolve;this.pendingResolve=null;let r=this.getSessionId();n({content:e,...r!==void 0?{sessionId:r}:{}});return}this.bufferedMessages.push(e)}createIterable(){let e=this;return{[Symbol.asyncIterator](){return{next(){if(e.bufferedMessages.length>0){let n=e.bufferedMessages.shift(),r=e.getSessionId();return Promise.resolve({value:{content:n,...r!==void 0?{sessionId:r}:{}},done:!1})}return new Promise(n=>{e.pendingResolve=r=>n({value:r,done:!1})})},return(){return Promise.resolve({value:void 0,done:!0})}}}}}};function Zc(t,e){let n=e??$n(),r=Bn(t.model,n);if(!r){t.forceChatgptOAuth=!1,t.forceXaiOAuth=!1,t.forceXaiApiKey=!1,t.xaiBaseUrl=void 0;return}let o=n[r],s=o.provider==="anthropic"?"anthropic-direct":o.provider==="openai"||o.provider==="chatgpt-oauth"?"openai-compatible":o.provider==="xai"||o.provider==="xai-oauth"?"xai":z(t.model,e?{slots:e}:void 0);t.forceChatgptOAuth=o.provider==="chatgpt-oauth",t.forceXaiOAuth=o.provider==="xai-oauth",t.forceXaiApiKey=o.provider==="xai",o.apiKey!==void 0?t.apiKey=o.apiKey:(s==="openai-compatible"||s==="xai"||o.baseUrl!==void 0)&&(t.apiKey=void 0),o.baseUrl!==void 0?s==="xai"?t.xaiBaseUrl=o.baseUrl:s==="openai-compatible"?t.openaiBaseUrl=o.baseUrl:t.baseUrl=o.baseUrl:s==="xai"&&(t.xaiBaseUrl=void 0)}J();function fG(t){return typeof t=="string"?t:t.map(e=>{let n=e;return n.type==="text"&&typeof n.text=="string"?n.text:""}).filter(e=>e.length>0).join(`
|
|
1266
|
+
`,384),s(n,384)}function Af(t={}){let e=(t.authPath??xr)(),n=t.exists??(o=>Eq(o)),r=t.unlink??Lq;n(e)&&r(e)}function Kc(t){return t.length<=4?t:t.slice(-4)}I();I();import{readFileSync as Uq}from"node:fs";import{homedir as $q}from"node:os";import{join as Bq}from"node:path";var xf="cli-chat-proxy.grok.com",PA="1.0.5",jq="AFK_XAI_GROK_CLIENT_VERSION",Hq=/^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;function Rf(t){let e=t?.trim();return e&&Hq.test(e)?e:void 0}function Wq(t,e){if(!t)return;let n=l=>l.split(".").map(Number),[r=0,o=0,s=0]=n(t),[i=0,a=0,c=0]=n(e);return r!==i?r>i?t:void 0:o!==a?o>a?t:void 0:s>=c?t:void 0}function Kq(t={}){let e=t.readFile??(r=>Uq(r,"utf-8")),n=t.homeDir??$q;try{let r=e(Bq(n(),".grok","version.json")),o=JSON.parse(r);if(typeof o!="object"||o===null)return;let s=o.version;return typeof s!="string"?void 0:Rf(s)}catch{return}}function qq(t,e){let n=e.readEnv??(r=>b[r]);return Rf(n(jq))??Rf(t)??Wq(Kq(e),PA)??PA}function If(t){try{let e=new URL(t).hostname.toLowerCase();return e===xf||e.endsWith(`.${xf}`)}catch{return t.toLowerCase().includes(xf)}}function Cf(t={},e={}){let n=qq(t.clientVersion,e),r=t.clientIdentifier?.trim()||"grok-shell";return{"X-XAI-Token-Auth":"xai-grok-cli","x-grok-client-version":n,"x-grok-client-identifier":r,"User-Agent":`agent-afk (grok-cli-compat/${n})`}}var bs="https://api.x.ai/v1",Ir="https://cli-chat-proxy.grok.com/v1";function Gq(t){if(t==="AFK_XAI_BASE_URL")return b.AFK_XAI_BASE_URL;if(t==="AFK_XAI_OAUTH_BASE_URL")return b.AFK_XAI_OAUTH_BASE_URL}function Cr(t,e={}){let n=e.readEnv??Gq,r=e.baseUrlOverride?.trim();if(r){let c=Pf(r),l=If(c);return{baseURL:c,defaultHeaders:l?Cf({clientVersion:e.clientVersion},e.headerDeps):{},mode:t,proxyHeadersApplied:l}}if(t==="apikey"){let c=n("AFK_XAI_BASE_URL"),l=c&&c.trim()||bs;return{baseURL:Pf(l),defaultHeaders:{},mode:t,proxyHeadersApplied:!1}}let o=n("AFK_XAI_OAUTH_BASE_URL"),s=Pf(o&&o.trim()||Ir),i=If(s),a=i?Cf({clientVersion:e.clientVersion},e.headerDeps):{};return{baseURL:s,defaultHeaders:a,mode:t,proxyHeadersApplied:i}}function Pf(t){return t.endsWith("/")?t.slice(0,-1):t}function Xq(t){if(t==="XAI_API_KEY")return b.XAI_API_KEY}function zq(t,e){if(t&&t.length>0)return{key:t,source:"config"};let n=e("XAI_API_KEY");return n&&n.length>0?{key:n,source:"env"}:null}function Jq(t){let e=Rr(t.store??{});return e?{bundle:e,last4:Kc(e.access_token)}:null}function pt(t,e=void 0,n={}){let r=n.readEnv??Xq,o=zq(t,r),s=Jq(n);return e==="oauth"?s?{apiKey:s.bundle.access_token,source:"xai-oauth",mode:"oauth",last4:s.last4,expiresAt:s.bundle.expires_at}:{apiKey:null,source:"no-usable-auth-forced-xai-oauth",mode:"oauth"}:e==="apikey"?o?{apiKey:o.key,source:o.source,mode:"apikey",last4:Kc(o.key),...o.source==="env"?{envVar:"XAI_API_KEY"}:{}}:{apiKey:null,source:"no-usable-auth-forced-xai-apikey",mode:"apikey"}:o&&s?{apiKey:null,source:"ambiguous-auth"}:o?{apiKey:o.key,source:o.source,mode:"apikey",last4:Kc(o.key),...o.source==="env"?{envVar:"XAI_API_KEY"}:{}}:s?{apiKey:s.bundle.access_token,source:"xai-oauth",mode:"oauth",last4:s.last4,expiresAt:s.bundle.expires_at}:{apiKey:null,source:"no-usable-auth"}}function Vq(t,e){if(typeof t!="number")return"";let n=(e??(()=>Math.floor(Date.now()/1e3)))(),r=t-n;if(r<=0)return", EXPIRED \u2014 re-run `afk provider auth xai login`";let o=Math.floor(r/3600),s=Math.floor(r%3600/60);return`, expires in ${o>0?`${o}h `:""}${s}m`}function Pr(t,e={}){switch(t.source){case"config":return`using explicit AFK config xAI API key (\u2026${t.last4??"????"})`;case"env":return`using XAI_API_KEY env var (\u2026${t.last4??"????"})`;case"xai-oauth":{let n=Vq(t.expiresAt,e.nowSeconds);return`using SuperGrok / SuperGrok Heavy / X Premium+ OAuth (\u2026${t.last4??"????"}${n})`}case"no-usable-auth-forced-xai-oauth":return"This model's slot/provider is `xai-oauth` but no SuperGrok OAuth tokens were found. Run `afk provider auth xai login` (device-code by default), or switch to `xai` with XAI_API_KEY.";case"no-usable-auth-forced-xai-apikey":return"This model's slot/provider is `xai` (API-key mode) but no XAI_API_KEY / config key was found. Set XAI_API_KEY, or use `xai-oauth` after `afk provider auth xai login`.";case"ambiguous-auth":return"Both XAI_API_KEY and SuperGrok OAuth tokens are present. Choose explicitly: `--provider xai` (API key \u2192 "+bs+") or `--provider xai-oauth` (subscription OAuth \u2192 "+Ir+").";default:return"No xAI auth found. Set XAI_API_KEY for metered API access, or run `afk provider auth xai login` for SuperGrok / SuperGrok Heavy / X Premium+."}}function Mf(t,e){let n=e.baseURL??(e.mode==="oauth"?Ir:bs),r=(e.bodySnippet??"").slice(0,180);return t===402?`xAI returned HTTP 402 on ${n}`+(r?` (${r})`:"")+". This is usually a subscription/spend gate (e.g. personal-team-blocked), not a missing login. Check SuperGrok / SuperGrok Heavy / X Premium+ status, try the other endpoint via AFK_XAI_OAUTH_BASE_URL or AFK_XAI_BASE_URL, or use a metered XAI_API_KEY with `--provider xai`.":t===403?`xAI returned HTTP 403 on ${n}`+(r?` (${r})`:"")+`. After SuperGrok OAuth login this often means the account lacks OAuth API entitlement, the model requires SuperGrok Heavy, or traffic hit api.x.ai instead of the CLI chat proxy. Try AFK_XAI_OAUTH_BASE_URL=${Ir} (default for xai-oauth), or fall back to XAI_API_KEY with \`--provider xai\`.`:`xAI returned HTTP ${t} on ${n}`+(r?`: ${r}`:"")}function qc(t,e,n){if(e===!0)return"oauth";if(n===!0)return"apikey";if(t==="apikey"||t==="oauth")return t}function Of(t,e){return e!==void 0?e:qc(t,void 0,void 0)}function MA(t,e){if(t==="xai-oauth")return"oauth";if(e)return"apikey"}var Df="https://auth.x.ai",Gc="b1a00492-073a-47ea-816f-4c329264a828",Yq="openid profile email offline_access grok-cli:access api:access",Rke=`${Yq} conversations:read conversations:write`;var Qq=56121,Zq=`http://127.0.0.1:${Qq}/callback`;var Xc=180;var eG=1440*60*1e3,zc=null;function Je(t){return typeof t=="string"&&t.length>0?t:void 0}async function Jc(t={}){let e=t.fetchFn??fetch,n=(t.issuer??Df).replace(/\/$/,""),r=`${n}/.well-known/openid-configuration`,o=await e(r,{method:"GET"});if(!o.ok)throw new Error(`xAI OIDC discovery failed: HTTP ${o.status} from ${r}`);let s=await o.json(),i=Je(s.authorization_endpoint),a=Je(s.token_endpoint);if(!i||!a)throw new Error("xAI OIDC discovery missing authorization_endpoint or token_endpoint");let c=new URL(n).origin,l=Je(s.issuer);if(l){let m;try{m=new URL(l).origin}catch{throw new Error("xAI OIDC discovery: body issuer origin does not match configured issuer")}if(m!==c)throw new Error("xAI OIDC discovery: body issuer origin does not match configured issuer")}let d=l??n;if(new URL(i).origin!==c)throw new Error("xAI OIDC discovery: authorization_endpoint origin does not match issuer");if(new URL(a).origin!==c)throw new Error("xAI OIDC discovery: token_endpoint origin does not match issuer");let u={issuer:d,authorization_endpoint:i,token_endpoint:a},p=Je(s.device_authorization_endpoint);if(p){if(new URL(p).origin!==c)throw new Error("xAI OIDC discovery: device_authorization_endpoint origin does not match issuer");u.device_authorization_endpoint=p}let f=Je(s.userinfo_endpoint);if(f){if(new URL(f).origin!==c)throw new Error("xAI OIDC discovery: userinfo_endpoint origin does not match issuer");u.userinfo_endpoint=f}return u}async function Vc(t={}){let n=(t.nowMs??(()=>Date.now()))();if(zc&&zc.expiresAt>n)return zc.result;let r=await Jc(t);return zc={result:r,expiresAt:n+eG},r}function ws(t,e,n){let r=Je(t.access_token);if(!r)return null;let o=Je(t.refresh_token)??n;if(!o)return null;let s=(e??(()=>Math.floor(Date.now()/1e3)))(),i=typeof t.expires_in=="number"?t.expires_in:3600,a=Math.min(Math.max(i,Xc+60),86400),c={access_token:r,refresh_token:o,expires_at:s+a};return typeof t.token_type=="string"&&(c.token_type=t.token_type),typeof t.scope=="string"&&(c.scope=t.scope),c}var Ff=new Map;function lG(t){return t?.authPath?t.authPath():xr()}async function OA(t,e={}){let n=await Vc(e),r=e.fetchFn??fetch,o=e.clientId??Gc,s=new URLSearchParams({grant_type:"refresh_token",refresh_token:t,client_id:o}),i=await r(n.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:s.toString()}),a=await i.json().catch(()=>({}));if(!i.ok){let l=Je(a.error)??`http_${i.status}`,d=Je(a.error_description);throw new Error(`xAI token refresh failed: ${d?`${l}: ${d}`:l}`)}let c=ws(a,e.nowSeconds,t);if(!c)throw new Error("xAI refresh response missing access_token");return e.persist!==!1&&Ef(c,e.store??{}),c}async function Ss(t={}){let e=t.store??{},n=Rr(e);if(!n)return null;let r=(t.nowSeconds??(()=>Math.floor(Date.now()/1e3)))(),o=t.skewSeconds??Xc;if(n.expires_at-o>r)return n;let s=lG(e),i=Ff.get(s);if(i)try{return await i}catch{return Rr(e)}let a=(async()=>{try{return await OA(n.refresh_token,{...t,store:e,persist:!0})}catch(c){throw n.expires_at<=r&&Af(e),c}finally{Ff.delete(s)}})();Ff.set(s,a);try{return await a}catch{return n.expires_at>r?n:null}}function Yc(t){return typeof t!="number"?!1:t<=Math.floor(Date.now()/1e3)}function Lf(t,e){let n=Yt(t);if(n!==402&&n!==403)return t instanceof Error?t:new Error(String(t));let r=t instanceof Error?t.message:typeof t=="string"?t:void 0,o=Cr(e);return new Error(Mf(n,{mode:e,baseURL:o.baseURL,...r!==void 0?{bodySnippet:r}:{}}))}function DA(t){return{async*[Symbol.asyncIterator](){yield{type:"error",error:new Error(t)}},async interrupt(){},async setModel(){},async setPermissionMode(){},async supportedCommands(){return[]},async supportedModels(){return[]},async supportedAgents(){return[]},async getContextUsage(){return{}},async mcpServerStatus(){return[]},async accountInfo(){return{}},async rewindFiles(){return{canRewind:!1,error:t}},async close(){}}}function FA(t,e){return t==="oauth"||t==="apikey"?t:e()}function LA(t){let{args:e,forceMode:n,authDeps:r,getLastMode:o,delegate:s}=t,i,a,c,l,d,u=async()=>{if(a)throw a;return i||c||(c=(async()=>{try{n!=="apikey"&&await Ss({store:r.store});let p=pt(e.config.apiKey,n,r);if(p.apiKey===null||!p.mode)throw new Error(Pr(p));if(p.mode==="oauth"&&Yc(p.expiresAt))throw new Error("SuperGrok OAuth access token expired and refresh failed. Re-run `afk provider auth xai login`.");return i=s(e,p.apiKey,p.mode),l!==void 0&&i.setCwd?.(l),d!==void 0&&i.setSystemPrompt?.(d===null?void 0:d),i}catch(p){throw a=p instanceof Error?p:new Error(String(p)),a}finally{c=void 0}})(),c)};return{async*[Symbol.asyncIterator](){try{let p=await u();for await(let f of p)f.type==="error"?yield{type:"error",error:Lf(f.error,FA(n,o))}:yield f}catch(p){let f=p instanceof Error?p:new Error(String(p));yield{type:"error",error:Lf(f,FA(n,o))}}},async interrupt(p){await(i??await u().catch(()=>{}))?.interrupt(p)},async setModel(p){await(i??await u().catch(()=>{}))?.setModel(p)},async setPermissionMode(p){await(i??await u().catch(()=>{}))?.setPermissionMode(p)},setCwd(p){l=p,i?.setCwd?.(p)},setSystemPrompt(p){return d=p===void 0?null:p,i?.setSystemPrompt?.(p)??!1},async reauth(){return await(i??await u().catch(()=>{}))?.reauth?.()??null},async supportedCommands(){return await(i??await u().catch(()=>{}))?.supportedCommands()??[]},async supportedModels(){return await(i??await u().catch(()=>{}))?.supportedModels()??[]},async supportedAgents(){return await(i??await u().catch(()=>{}))?.supportedAgents()??[]},async getContextUsage(){return await(i??await u().catch(()=>{}))?.getContextUsage()??{}},async mcpServerStatus(){return await(i??await u().catch(()=>{}))?.mcpServerStatus()??[]},async accountInfo(){return await(i??await u().catch(()=>{}))?.accountInfo()??{}},async rewindFiles(p,f){let m=i??await u().catch(()=>{});return m?m.rewindFiles(p,f):{canRewind:!1,error:"xAI provider not initialized"}},async compact(){let p=i??await u().catch(()=>{});return p?.compact?p.compact():{compacted:!1,reason:"provider does not support compaction",messagesBefore:0,messagesAfter:0}},listRewindTargets(){return i?.listRewindTargets?.()??[]},async rewindConversation(p){let f=i??await u().catch(()=>{});return f?.rewindConversation?f.rewindConversation(p):{rewound:!1,reason:"not-supported",messagesBefore:0,messagesAfter:0}},async close(){await i?.close()}}}var dG="xai",ks=class{name=dG;inner;authMode;authDeps;lastMode="apikey";lastResolvedMode;lastXaiBaseUrl;constructor(e={}){let{authMode:n,authDeps:r,...o}=e;this.authMode=n,this.authDeps=r??{},this.inner=new Ge(o)}query(e){let n=qc(this.authMode,e.config.forceXaiOAuth,e.config.forceXaiApiKey);return n==="oauth"||n===void 0?LA({args:e,forceMode:n,authDeps:this.authDeps,getLastMode:()=>this.lastMode,delegate:(r,o,s)=>this.delegateToInner(r,o,s)}):this.querySync(e,n)}querySync(e,n){let r=pt(e.config.apiKey,n,this.authDeps);return r.apiKey===null||!r.mode?DA(Pr(r)):this.delegateToInner(e,r.apiKey,r.mode)}delegateToInner(e,n,r){this.rememberResolved(r,e.config.xaiBaseUrl);let o=Cr(r,{readEnv:this.authDeps.readEnv?i=>this.authDeps.readEnv(i):void 0,...e.config.xaiBaseUrl!==void 0?{baseUrlOverride:e.config.xaiBaseUrl}:{}});this.inner.setEndpointDefaults({baseURL:o.baseURL,defaultHeaders:o.defaultHeaders});let s={...e.config,apiKey:n,openaiBaseUrl:o.baseURL,forceChatgptOAuth:!1,forceXaiOAuth:r==="oauth",forceXaiApiKey:r==="apikey"};return this.inner.query({...e,config:s})}rememberResolved(e,n){this.lastMode=e,this.lastResolvedMode=e,this.lastXaiBaseUrl=n}addReadRoot(e,n="slash",r){this.inner.addReadRoot(e,n,r)}addWriteRoot(e,n="slash",r){this.inner.addWriteRoot(e,n,r)}revokeRoot(e,n="slash",r){this.inner.revokeRoot(e,n,r)}getGrants(){return this.inner.getGrants()}close(){this.inner.close()}async complete(e){let n=Of(this.authMode,this.lastResolvedMode);(n==="oauth"||n===void 0)&&await Ss({store:this.authDeps.store});let r=pt(e.apiKey,n,this.authDeps);if(r.apiKey===null||!r.mode)throw new Error(Pr(r));if(r.mode==="oauth"&&Yc(r.expiresAt))throw new Error("SuperGrok OAuth access token expired and refresh failed. Re-run `afk provider auth xai login`.");this.rememberResolved(r.mode,this.lastXaiBaseUrl);let o=Cr(r.mode,{readEnv:this.authDeps.readEnv,...this.lastXaiBaseUrl!==void 0?{baseUrlOverride:this.lastXaiBaseUrl}:{}});return this.inner.setEndpointDefaults({baseURL:o.baseURL,defaultHeaders:o.defaultHeaders}),this.inner.complete({...e,apiKey:r.apiKey,baseUrl:o.baseURL})}};I();var uG=new Set([...Object.keys(td),"auto"]);function pG(t){if(!t)return;let e=t.trim().toLowerCase();if(e){if(e==="anthropic"||e==="anthropic-direct")return"anthropic-direct";if(e==="openai"||e==="openai-compatible"||e==="openai-codex")return"openai-compatible";if(e==="xai")return"xai";if(e==="xai-oauth"||e==="xai_oauth")return"xai-oauth"}}function z(t,e){let n=e?.explicit??b.AFK_PROVIDER,r=e?.openaiBaseUrl??b.AFK_OPENAI_BASE_URL,o=pG(n);if(o)return o;let s=ln(t,e?.slots);if(s.provider==="anthropic")return"anthropic-direct";if(s.provider==="openai"||s.provider==="chatgpt-oauth")return"openai-compatible";if(s.provider==="xai")return"xai";if(s.provider==="xai-oauth")return"xai-oauth";let i=s.id.trim().toLowerCase();return i&&(uG.has(i)||i.startsWith("claude-")||i.startsWith("claude_")||i.startsWith("local-")||i.startsWith("local_"))?"anthropic-direct":i&&(i.startsWith("grok-")||i.startsWith("grok_")||i==="grok")?"xai":i&&(i.startsWith("gpt-")||i.startsWith("gpt_")||dn(i)||i.startsWith("codex-")||i.startsWith("codex_")||i==="codex"||i.startsWith("deepseek-")||i.startsWith("deepseek_")||i.startsWith("mistral-")||i.startsWith("mistral_")||i.startsWith("mixtral-")||i.startsWith("mixtral_")||i.startsWith("llama-")||i.startsWith("llama_")||i.startsWith("qwen-")||i.startsWith("qwen_")||i.includes("/"))||s.baseUrl&&s.baseUrl.trim()||r&&r.trim()?"openai-compatible":"anthropic-direct"}function Qc(t,e,n){let r=z(t,e),o=n?.customTools,s=n?.canUseTool,i={...o!==void 0&&o.length>0?{customTools:o}:{},...s!==void 0?{canUseTool:s}:{}};switch(r){case"openai-compatible":case"openai-codex":return new Ge(i);case"xai":case"xai-oauth":{let a=(e?.explicit??b.AFK_PROVIDER)?.trim().toLowerCase()??"",d=MA(r==="xai-oauth"||a==="xai-oauth"||a==="xai_oauth"?"xai-oauth":"xai",a==="xai"||a==="xai-oauth"||a==="xai_oauth"||r==="xai-oauth");return new ks({...i,...d!==void 0?{authMode:d}:{}})}default:return new Rt(i)}}var Mr=class{pendingResolve=null;bufferedMessages=[];getSessionId;constructor(e){this.getSessionId=e}pushUserMessage(e){if(this.pendingResolve){let n=this.pendingResolve;this.pendingResolve=null;let r=this.getSessionId();n({content:e,...r!==void 0?{sessionId:r}:{}});return}this.bufferedMessages.push(e)}createIterable(){let e=this;return{[Symbol.asyncIterator](){return{next(){if(e.bufferedMessages.length>0){let n=e.bufferedMessages.shift(),r=e.getSessionId();return Promise.resolve({value:{content:n,...r!==void 0?{sessionId:r}:{}},done:!1})}return new Promise(n=>{e.pendingResolve=r=>n({value:r,done:!1})})},return(){return Promise.resolve({value:void 0,done:!0})}}}}}};function Zc(t,e){let n=e??$n(),r=Bn(t.model,n);if(!r){t.forceChatgptOAuth=!1,t.forceXaiOAuth=!1,t.forceXaiApiKey=!1,t.xaiBaseUrl=void 0;return}let o=n[r],s=o.provider==="anthropic"?"anthropic-direct":o.provider==="openai"||o.provider==="chatgpt-oauth"?"openai-compatible":o.provider==="xai"||o.provider==="xai-oauth"?"xai":z(t.model,e?{slots:e}:void 0);t.forceChatgptOAuth=o.provider==="chatgpt-oauth",t.forceXaiOAuth=o.provider==="xai-oauth",t.forceXaiApiKey=o.provider==="xai",o.apiKey!==void 0?t.apiKey=o.apiKey:(s==="openai-compatible"||s==="xai"||o.baseUrl!==void 0)&&(t.apiKey=void 0),o.baseUrl!==void 0?s==="xai"?t.xaiBaseUrl=o.baseUrl:s==="openai-compatible"?t.openaiBaseUrl=o.baseUrl:t.baseUrl=o.baseUrl:s==="xai"&&(t.xaiBaseUrl=void 0)}J();function fG(t){return typeof t=="string"?t:t.map(e=>{let n=e;return n.type==="text"&&typeof n.text=="string"?n.text:""}).filter(e=>e.length>0).join(`
|
|
1267
1267
|
`)}function mG(t,e,n,r){let o=n&&n!==r?` (provider ${n} \u2192 ${r})`:"";return`[System context \u2014 not from the user. Your model was switched at the start of this turn: ${t} \u2192 ${e}${o}. Earlier turns in this conversation were produced by ${t}; the history carried across the switch is plain text only, so any prior tool calls and extended reasoning are now prose \u2014 treat their structure as lost, not authoritative.]`}function gG(t,e){return typeof t=="string"?t.length>0?`${e}
|
|
1268
1268
|
|
|
1269
1269
|
${t}`:e:[{type:"text",text:e},...t]}var el=class{outerIterator;baseConfig;deps;currentModel;currentPermissionMode;currentCwd;currentSystemPrompt;systemPromptOverridden=!1;startupFamily;active;activeModel;closed=!1;shadowHistory;pendingUserText;pendingAssistantText="";lastSessionId;constructor(e,n){this.outerIterator=e.prompt[Symbol.asyncIterator](),this.baseConfig=e.config,this.deps=n,this.currentModel=typeof e.config.model=="string"?e.config.model:void 0,this.currentPermissionMode=e.config.permissionMode,this.currentCwd=e.config.cwd,this.startupFamily=n.providerNameForModel(this.currentModel),this.shadowHistory=[...e.config.resumeHistory??[]]}resolveInner(e){let n=this.deps.resolveProvider(e),r={...this.baseConfig};r.model=e??this.baseConfig.model;let o=n.name===this.startupFamily&&this.baseConfig.apiKey!==void 0?this.baseConfig.apiKey:this.deps.resolveApiKey(e);o!==void 0?r.apiKey=o:delete r.apiKey,Zc(r);let s=[n.name,r.baseUrl??"",r.openaiBaseUrl??"",r.apiKey??"",r.forceChatgptOAuth?"chatgpt-oauth":"",r.forceXaiOAuth?"xai-oauth":"",r.forceXaiApiKey?"xai-apikey":"",r.xaiBaseUrl??""].join("\0");return{provider:n,innerConfig:r,signature:s}}buildInner(e,n){let{provider:r,innerConfig:o,signature:s}=this.resolveInner(e),i=new Mr(()=>this.lastSessionId);this.currentPermissionMode!==void 0&&(o.permissionMode=this.currentPermissionMode),this.currentCwd!==void 0&&(o.cwd=this.currentCwd),this.systemPromptOverridden&&(o.systemPrompt=this.currentSystemPrompt),n&&(o.resumeHistory=[...this.shadowHistory]);let a=r.query({prompt:i.createIterable(),config:o});return{family:r.name,signature:s,query:a,iterator:a[Symbol.asyncIterator](),input:i}}async closeActive(){let e=this.active;if(e){this.active=void 0;try{await e.iterator.return?.(void 0)}catch{}try{await e.query.close()}catch{}}}observeEvent(e){e.type==="assistant.message"&&(this.pendingAssistantText+=(this.pendingAssistantText?`
|
|
1270
|
-
`:"")+e.text)}commitShadowTurn(){this.pendingUserText!==void 0&&(this.shadowHistory.push({user:this.pendingUserText,assistant:this.pendingAssistantText}),this.pendingUserText=void 0,this.pendingAssistantText="")}async*[Symbol.asyncIterator](){try{for(this.active=this.buildInner(this.currentModel,!1),this.activeModel=this.currentModel,yield*this.driveUntilInit(!1);!this.closed;){let e=await this.outerIterator.next();if(e.done)break;let n=e.value;this.lastSessionId=n.sessionId;let r=this.currentModel!==this.activeModel,o=!this.active||r&&this.resolveInner(this.currentModel).signature!==this.active.signature,s=this.activeModel,i=this.active?.family;this.activeModel=this.currentModel;let a;if(o&&(await this.closeActive(),this.active=this.buildInner(this.currentModel,!0),C(`\u{1F500} ProviderRouter: switched inner provider \u2192 ${this.active.family} (model=${this.currentModel})`),s!==void 0&&s!==this.currentModel&&(a=mG(s,this.currentModel??"(unset)",i,this.active.family)),yield*this.driveUntilInit(!0)))break;for(this.pendingUserText=fG(n.content),this.pendingAssistantText="",this.active.input.pushUserMessage(a?gG(n.content,a):n.content);;){let c=await this.active.iterator.next();if(c.done){this.closed=!0;break}let l=c.value;if(this.observeEvent(l),yield l,l.type==="turn.completed"){this.commitShadowTurn();break}if(l.type==="error"){this.commitShadowTurn();break}}}}finally{await this.closeActive()}}async*driveUntilInit(e){for(;;){let n=await this.active.iterator.next();if(n.done)return yield{type:"error",error:new Error("provider ended before initialization")},this.closed=!0,!0;let r=n.value;if(r.type==="session.init")return e||(yield r),!1;if(r.type==="error")return yield r,this.closed=!0,!0;yield r}}async interrupt(e="interrupted"){await this.active?.query.interrupt(e)}async setModel(e){typeof e=="string"&&e.length>0&&(this.currentModel=e,this.active&&this.resolveInner(e).signature===this.active.signature&&await this.active.query.setModel(e))}async setPermissionMode(e){this.currentPermissionMode=e,await this.active?.query.setPermissionMode(e)}setCwd(e){this.currentCwd=e,this.active?.query.setCwd?.(e)}setSystemPrompt(e){return this.currentSystemPrompt=e,this.systemPromptOverridden=!0,this.active?.query.setSystemPrompt?.(e)??!1}async reauth(){return await this.active?.query.reauth?.()??null}async supportedCommands(){return await this.active?.query.supportedCommands()??[]}async supportedModels(){return await this.active?.query.supportedModels()??[]}async supportedAgents(){return await this.active?.query.supportedAgents()??[]}async getContextUsage(){return await this.active?.query.getContextUsage()??{}}async mcpServerStatus(){return await this.active?.query.mcpServerStatus()??[]}async accountInfo(){return await this.active?.query.accountInfo()??{}}async rewindFiles(e,n){let r=this.active;return r?r.query.rewindFiles(e,n):{canRewind:!1,error:"no active provider"}}async compact(){let e=this.active;return e?.query.compact?e.query.compact():{compacted:!1,reason:"provider does not support compaction",messagesBefore:0,messagesAfter:0}}listRewindTargets(){return this.active?.query.listRewindTargets?.()??[]}async rewindConversation(e){let n=this.active;return n?.query.rewindConversation?n.query.rewindConversation(e):{rewound:!1,reason:"not-supported",messagesBefore:0,messagesAfter:0}}async reloadPlugins(...e){let n=this.active?.query;if(n&&typeof n.reloadPlugins=="function")return n.reloadPlugins(...e)}async close(){this.closed=!0,await this.closeActive()}};J();async function tl(t,e,n){if(!t)return;if(n.kind==="blocked"){await Mt(t,{hookEvent:e,decision:"block",...n.err.reason!==void 0?{reason:n.err.reason}:{}});return}let r=n.decision;await Mt(t,{hookEvent:e,decision:r.decision,...r.reason!==void 0?{reason:r.reason}:{},...r.injectContext!==void 0?{injectedContextBytes:Buffer.byteLength(r.injectContext,"utf8")}:{}})}async function NA(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);return await tl(n.traceWriter,"SessionStart",{kind:"decision",decision:r}),r.injectContext}catch(r){throw r instanceof q&&await tl(n.traceWriter,"SessionStart",{kind:"blocked",err:r}),r}}async function UA(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);await tl(n.traceWriter,"SessionEnd",{kind:"decision",decision:r})}catch(r){if(r instanceof q&&await tl(n.traceWriter,"SessionEnd",{kind:"blocked",err:r}),r instanceof q||r instanceof Fe){C(`SessionEnd hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}C(`SessionEnd hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}var hG="Session ended via abort before reaching a terminal state. The transcript and witness trace are preserved \u2014 resume with `afk --resume <sessionId>` to continue from saved state, or re-run the task if the interruption was intentional.",yG="Session hit the tool-use iteration cap before reaching a terminal state. Partial work is preserved in the transcript and witness trace. Resume with `afk --resume <sessionId>` to continue from where it stopped, or re-run with a higher budget (`--max-turns` or `max_tool_use_iterations`).",bG="Session was terminated by the wall-clock timeout before reaching a terminal state. The transcript and witness trace are preserved \u2014 resume with `afk --resume <sessionId>` to continue, or re-run with a longer timeout. Check the trace for whether the timeout hit during active work or while waiting on a slow tool call.";function $A(t){switch(t){case"abort":return hG;case"iteration_cap":return yG;case"timeout":return bG;default:return null}}function BA(t){return t.maxTurnsHit?"max_turns_exceeded":t.hookBlocked?"hook_blocked":t.dispatchReason==="error"?"abort":t.abort!==null?t.abort:t.sawProviderError||t.lastStopReason===Xe?"abort":t.lastStopReason==="tool_use_loop_capped"?"iteration_cap":t.lastStopReason===dt?"timeout":xt(t.lastStopReason)?"truncated":"model_end_turn"}function wG(t){let e=null,n=t.signal;if(n.aborted&&n.reason!=="closed"){let r=n.reason;r instanceof nt?e="budget_exceeded":r instanceof _e?e="timeout":typeof r=="string"&&r.startsWith("Budget ")?e="budget_exceeded":typeof r=="string"&&r.includes("timed out")?e="timeout":e="abort"}return BA({dispatchReason:t.dispatchReason,maxTurnsHit:t.maxTurnsHit,hookBlocked:t.hookBlocked,abort:e,lastStopReason:t.lastStopReason,sawProviderError:t.sawProviderError})}function SG(t){if(t.dispatchReason==="error")return"failed";let e=t.signal;return e.aborted&&e.reason!=="closed"?"cancelled":t.sawProviderError||t.lastStopReason===Xe?"failed":"succeeded"}async function jA(t,e){if(!t)return;let n=wG(e),r={},o=e.runningTokens;o.input>0&&(r.input=o.input),o.output>0&&(r.output=o.output),o.cacheRead>0&&(r.cacheRead=o.cacheRead),o.cacheCreation>0&&(r.cacheCreation=o.cacheCreation);let s=$A(n);await Qm(t,{reason:n,finalTurnCount:e.finalTurnCount,finalCostUsd:e.finalCostUsd,finalTokens:r,...e.lastStopReason!==void 0?{lastStopReason:e.lastStopReason}:{},...s!==null?{guidance:s}:{}})}async function HA(t,e){if(!t)return;let n=SG(e),r=e.subagentCompletedCount>0?e.subagentCompletedCount:void 0,o=e.subagentRunningTokens,i=o.input>0||o.output>0||o.cacheRead>0||o.cacheCreation>0?{...o.input>0?{input:o.input}:{},...o.output>0?{output:o.output}:{},...o.cacheRead>0?{cacheRead:o.cacheRead}:{},...o.cacheCreation>0?{cacheCreation:o.cacheCreation}:{}}:void 0,a=e.subagentRunningCostUsd>0?e.subagentRunningCostUsd:void 0;await t.seal({status:n,finalCostUsd:e.finalCostUsd,finalTurnCount:e.finalTurnCount,closedAt:new Date().toISOString(),...r!==void 0?{subagentCount:r}:{},...i!==void 0?{subagentTokens:i}:{},...a!==void 0?{subagentCostUsd:a}:{}})}import{z as e2}from"zod";I();P();var nl=class{writer=null;initAttempted=!1;ensure(e){if(this.initAttempted||(this.initAttempted=!0,e.depth!==void 0||e.parentSessionId!==void 0)||b.AFK_SESSION_LEDGER_DISABLED==="1")return;let n=e.sessionId;if(!n)return;let r=new Wt(n);if(!r.active)return;this.writer=r;let o=e.getMetadata();r.record({kind:"meta",sessionId:n,model:o.model??e.fallbackModel,...o.cwd!==void 0?{cwd:o.cwd}:{},traceLabel:rn(e.tracePath)})}recordUser(e){this.writer?.recordUser(e)}recordEvent(e){this.writer?.recordEvent(e)}recordElicitation(e,n){this.writer?.record({kind:"elicitation",reqId:e,request:n})}seal(e){let n=this.writer;return n?(this.writer=null,this.initAttempted=!1,n.close(e)):Promise.resolve()}};var rl=class{pendingSeed;prePlanMode;modeBeforeDefault;recordModeTransition(e,n){if(e==="plan"){if(n!=="plan"){let r=n==="default"&&this.modeBeforeDefault!==void 0?this.modeBeforeDefault:n;this.prePlanMode=r==="autonomous"?void 0:r}}else e==="default"?this.modeBeforeDefault=n!=="default"&&n!=="plan"?n:void 0:this.modeBeforeDefault=void 0}clearModeBeforeDefault(){this.modeBeforeDefault=void 0}getPrePlanMode(){return this.prePlanMode}requestImplementSeed(e,n){this.pendingSeed={message:e,mode:n}}takeSeed(){let e=this.pendingSeed;return this.pendingSeed=void 0,e}};function WA(t,e,n){t&&(t.aborted?e.abort(t.reason):t.addEventListener("abort",()=>{e.signal.aborted||e.abort(t.reason)},{once:!0})),e.signal.addEventListener("abort",n,{once:!0})}function KA(t,e){let n=t.permissionMode??"default",r=t.persistSession??!0,o={sessionId:t.sessionId,configuredSessionId:t.sessionId,resume:t.resume,resumeSessionAt:t.resumeSessionAt,continue:t.continue,forkSession:t.forkSession,persistSession:r},s={sessionId:t.sessionId,model:e,permissionMode:n};return{sessionIdentity:o,metadata:s}}var ol=class{initializationPromise;resolveInitialization;rejectInitialization;initializationSettled=!1;sessionMetadata;sessionIdentity;constructor(e,n){this.sessionIdentity=e,this.sessionMetadata=n,this.initializationPromise=new Promise((r,o)=>{this.resolveInitialization=r,this.rejectInitialization=o})}waitForInitialization(){return this.initializationPromise}getSessionIdentity(){return{...this.sessionIdentity,sessionId:this.getSessionId()}}getSessionMetadata(){return{...this.sessionMetadata,sessionId:this.getSessionId()}}getSessionId(){return this.sessionMetadata.sessionId??this.sessionIdentity.sessionId}updateSessionIdentity(e){e&&(this.sessionIdentity={...this.sessionIdentity,sessionId:e},this.sessionMetadata={...this.sessionMetadata,sessionId:e})}setSessionMetadata(e){this.sessionMetadata=e(this.sessionMetadata)}resolveInitializationIfNeeded(){this.initializationSettled||(this.initializationSettled=!0,this.resolveInitialization(this.getSessionMetadata()))}resolveInitializationOnce(){this.initializationSettled||(this.initializationSettled=!0,this.resolveInitialization(this.getSessionMetadata()))}rejectInitializationOnce(e){this.initializationSettled||(this.initializationSettled=!0,this.rejectInitialization(e))}isInitializationSettled(){return this.initializationSettled}};function qA(t){try{let e=JSON.parse(t);if(!Array.isArray(e))return null;let n=e.length;if(n===0)return"no results";let r=0,o=0;for(let a of e)if(a&&typeof a=="object"){let c=a.type;c==="fact"?r++:c==="procedure"&&o++}let s=`${n} result${n===1?"":"s"}`;if(r+o!==n)return s;let i=[];return r>0&&i.push(`${r} fact${r===1?"":"s"}`),o>0&&i.push(`${o} procedure${o===1?"":"s"}`),i.length===0?s:`${s} (${i.join(", ")})`}catch{return null}}function GA(t){try{let e=JSON.parse(t);if(!e||typeof e!="object")return null;let n=e;if(n.target==="hot"&&n.saved===!0){if(n.truncated===!0)return"hot memory saved (truncated to fit cap)";let r=n.usage;if(r&&typeof r=="object"){let o=r.pct;if(typeof o=="number")return`hot memory saved (${o}% of cap)`}return"hot memory saved"}if(n.target==="fact"){if(n.action==="remove")return n.removed===!0?"fact removed":"fact not found";if(n.action==="set"&&typeof n.id=="number")return`fact #${n.id} set`;if(n.action==="supersede"&&typeof n.id=="number"&&typeof n.supersedes=="number")return`fact #${n.id} supersedes #${n.supersedes}`}return null}catch{return null}}function XA(t){try{let e=JSON.parse(t);if(!e||typeof e!="object")return null;let n=e;return typeof n.name=="string"&&n.written===!0?`wrote procedure '${n.name}'`:null}catch{return null}}function Nf(t){let e=t.trim();if(e.length===0)return null;let n=e[0];if(n!=="{"&&n!=="[")return null;let r=e[e.length-1];if(n==="{"&&r!=="}"||n==="["&&r!=="]")return null;let o;try{o=JSON.parse(e)}catch{return null}return Array.isArray(o)?zA(kG(o)):o!==null&&typeof o=="object"?zA(vG(o)):null}function kG(t){return t.length===0?"[empty array]":t.length===1?"[1 item]":`[${t.length} items]`}function vG(t){let e=Object.keys(t);if(e.length===0)return"{empty object}";let n=e.slice(0,4),r=e.length>4?", \u2026":"";return`{${n.join(", ")}${r}}`}function zA(t){return t.length<=80?t:t.slice(0,79)+"\u2026"}var TG=new Map([["memory_search",qA],["memory_update",GA],["procedure_write",XA],["bash",Nf],["Bash",Nf]]);function JA(t,e){if(!t)return null;let n=TG.get(t);if(!n)return null;try{let r=n(e);if(r===null)return null;let o=we(r);return o.length>0?o:null}catch{return null}}function _G(t){if(t<1024)return`${t}B`;let e=t/1024;if(e<1024)return e%1===0?`${Math.floor(e)}KB`:`${e.toFixed(1)}KB`;let n=e/1024;if(n<1024)return n%1===0?`${Math.floor(n)}MB`:`${n.toFixed(1)}MB`;let r=n/1024;return r%1===0?`${Math.floor(r)}GB`:`${r.toFixed(1)}GB`}var EG=7;function VA(t){let e=Buffer.byteLength(t,"utf8"),n=_G(e),r=t.split(`
|
|
1271
|
-
`);if(r.length<=1)return t.length<=80?{content:t,truncated:!1,sizeBytes:e,sizeLabel:n}:{content:t.substring(0,80)+"\u2026",truncated:!0,sizeBytes:e,sizeLabel:n};let s=r.filter(d=>d.trim()!=="").slice(-
|
|
1272
|
-
`);if(a.length>0&&a[a.length-1]===""&&a.pop(),a.length<=n)return r;let c=a.slice(a.length-n),l=a.length-c.length;return o=`${t}.tmp-${process.pid}-${Math.random().toString(36).slice(2,8)}`,await
|
|
1270
|
+
`:"")+e.text)}commitShadowTurn(){this.pendingUserText!==void 0&&(this.shadowHistory.push({user:this.pendingUserText,assistant:this.pendingAssistantText}),this.pendingUserText=void 0,this.pendingAssistantText="")}async*[Symbol.asyncIterator](){try{for(this.active=this.buildInner(this.currentModel,!1),this.activeModel=this.currentModel,yield*this.driveUntilInit(!1);!this.closed;){let e=await this.outerIterator.next();if(e.done)break;let n=e.value;this.lastSessionId=n.sessionId;let r=this.currentModel!==this.activeModel,o=!this.active||r&&this.resolveInner(this.currentModel).signature!==this.active.signature,s=this.activeModel,i=this.active?.family;this.activeModel=this.currentModel;let a;if(o&&(await this.closeActive(),this.active=this.buildInner(this.currentModel,!0),C(`\u{1F500} ProviderRouter: switched inner provider \u2192 ${this.active.family} (model=${this.currentModel})`),s!==void 0&&s!==this.currentModel&&(a=mG(s,this.currentModel??"(unset)",i,this.active.family)),yield*this.driveUntilInit(!0)))break;for(this.pendingUserText=fG(n.content),this.pendingAssistantText="",this.active.input.pushUserMessage(a?gG(n.content,a):n.content);;){let c=await this.active.iterator.next();if(c.done){this.closed=!0;break}let l=c.value;if(this.observeEvent(l),yield l,l.type==="turn.completed"){this.commitShadowTurn();break}if(l.type==="error"){this.commitShadowTurn();break}}}}finally{await this.closeActive()}}async*driveUntilInit(e){for(;;){let n=await this.active.iterator.next();if(n.done)return yield{type:"error",error:new Error("provider ended before initialization")},this.closed=!0,!0;let r=n.value;if(r.type==="session.init")return e||(yield r),!1;if(r.type==="error")return yield r,this.closed=!0,!0;yield r}}async interrupt(e="interrupted"){await this.active?.query.interrupt(e)}async setModel(e){typeof e=="string"&&e.length>0&&(this.currentModel=e,this.active&&this.resolveInner(e).signature===this.active.signature&&await this.active.query.setModel(e))}async setPermissionMode(e){this.currentPermissionMode=e,await this.active?.query.setPermissionMode(e)}setCwd(e){this.currentCwd=e,this.active?.query.setCwd?.(e)}setSystemPrompt(e){return this.currentSystemPrompt=e,this.systemPromptOverridden=!0,this.active?.query.setSystemPrompt?.(e)??!1}async reauth(){return await this.active?.query.reauth?.()??null}async supportedCommands(){return await this.active?.query.supportedCommands()??[]}async supportedModels(){return await this.active?.query.supportedModels()??[]}async supportedAgents(){return await this.active?.query.supportedAgents()??[]}async getContextUsage(){return await this.active?.query.getContextUsage()??{}}async mcpServerStatus(){return await this.active?.query.mcpServerStatus()??[]}async accountInfo(){return await this.active?.query.accountInfo()??{}}async rewindFiles(e,n){let r=this.active;return r?r.query.rewindFiles(e,n):{canRewind:!1,error:"no active provider"}}async compact(){let e=this.active;return e?.query.compact?e.query.compact():{compacted:!1,reason:"provider does not support compaction",messagesBefore:0,messagesAfter:0}}listRewindTargets(){return this.active?.query.listRewindTargets?.()??[]}async rewindConversation(e){let n=this.active;return n?.query.rewindConversation?n.query.rewindConversation(e):{rewound:!1,reason:"not-supported",messagesBefore:0,messagesAfter:0}}async reloadPlugins(...e){let n=this.active?.query;if(n&&typeof n.reloadPlugins=="function")return n.reloadPlugins(...e)}async close(){this.closed=!0,await this.closeActive()}};J();async function tl(t,e,n){if(!t)return;if(n.kind==="blocked"){await Mt(t,{hookEvent:e,decision:"block",...n.err.reason!==void 0?{reason:n.err.reason}:{}});return}let r=n.decision;await Mt(t,{hookEvent:e,decision:r.decision,...r.reason!==void 0?{reason:r.reason}:{},...r.injectContext!==void 0?{injectedContextBytes:Buffer.byteLength(r.injectContext,"utf8")}:{}})}async function NA(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);return await tl(n.traceWriter,"SessionStart",{kind:"decision",decision:r}),r.injectContext}catch(r){throw r instanceof q&&await tl(n.traceWriter,"SessionStart",{kind:"blocked",err:r}),r}}async function UA(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);await tl(n.traceWriter,"SessionEnd",{kind:"decision",decision:r})}catch(r){if(r instanceof q&&await tl(n.traceWriter,"SessionEnd",{kind:"blocked",err:r}),r instanceof q||r instanceof Fe){C(`SessionEnd hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}C(`SessionEnd hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}var hG="Session ended via abort before reaching a terminal state. The transcript and witness trace are preserved \u2014 resume with `afk --resume <sessionId>` to continue from saved state, or re-run the task if the interruption was intentional.",yG="Session hit the tool-use iteration cap before reaching a terminal state. Partial work is preserved in the transcript and witness trace. Resume with `afk --resume <sessionId>` to continue from where it stopped, or re-run with a higher budget (`--max-turns` or `max_tool_use_iterations`).",bG="Session was terminated by the wall-clock timeout before reaching a terminal state. The transcript and witness trace are preserved \u2014 resume with `afk --resume <sessionId>` to continue, or re-run with a longer timeout. Check the trace for whether the timeout hit during active work or while waiting on a slow tool call.",wG="Session output was truncated by the model provider's output-token ceiling before the response completed. The transcript and witness trace are preserved \u2014 resume with `afk --resume <sessionId>` to continue from where the output was cut off.";function $A(t){switch(t){case"abort":return hG;case"iteration_cap":return yG;case"timeout":return bG;case"truncated":return wG;default:return null}}function BA(t){return t.maxTurnsHit?"max_turns_exceeded":t.hookBlocked?"hook_blocked":t.dispatchReason==="error"?"abort":t.abort!==null?t.abort:t.sawProviderError||t.lastStopReason===Xe?"abort":t.lastStopReason==="tool_use_loop_capped"?"iteration_cap":t.lastStopReason===dt?"timeout":xt(t.lastStopReason)?"truncated":"model_end_turn"}function SG(t){let e=null,n=t.signal;if(n.aborted&&n.reason!=="closed"){let r=n.reason;r instanceof nt?e="budget_exceeded":r instanceof _e?e="timeout":typeof r=="string"&&r.startsWith("Budget ")?e="budget_exceeded":typeof r=="string"&&r.includes("timed out")?e="timeout":e="abort"}return BA({dispatchReason:t.dispatchReason,maxTurnsHit:t.maxTurnsHit,hookBlocked:t.hookBlocked,abort:e,lastStopReason:t.lastStopReason,sawProviderError:t.sawProviderError})}function kG(t){if(t.dispatchReason==="error")return"failed";let e=t.signal;return e.aborted&&e.reason!=="closed"?"cancelled":t.sawProviderError||t.lastStopReason===Xe?"failed":"succeeded"}async function jA(t,e){if(!t)return;let n=SG(e),r={},o=e.runningTokens;o.input>0&&(r.input=o.input),o.output>0&&(r.output=o.output),o.cacheRead>0&&(r.cacheRead=o.cacheRead),o.cacheCreation>0&&(r.cacheCreation=o.cacheCreation);let s=$A(n);await Qm(t,{reason:n,finalTurnCount:e.finalTurnCount,finalCostUsd:e.finalCostUsd,finalTokens:r,...e.lastStopReason!==void 0?{lastStopReason:e.lastStopReason}:{},...s!==null?{guidance:s}:{}})}async function HA(t,e){if(!t)return;let n=kG(e),r=e.subagentCompletedCount>0?e.subagentCompletedCount:void 0,o=e.subagentRunningTokens,i=o.input>0||o.output>0||o.cacheRead>0||o.cacheCreation>0?{...o.input>0?{input:o.input}:{},...o.output>0?{output:o.output}:{},...o.cacheRead>0?{cacheRead:o.cacheRead}:{},...o.cacheCreation>0?{cacheCreation:o.cacheCreation}:{}}:void 0,a=e.subagentRunningCostUsd>0?e.subagentRunningCostUsd:void 0;await t.seal({status:n,finalCostUsd:e.finalCostUsd,finalTurnCount:e.finalTurnCount,closedAt:new Date().toISOString(),...r!==void 0?{subagentCount:r}:{},...i!==void 0?{subagentTokens:i}:{},...a!==void 0?{subagentCostUsd:a}:{}})}import{z as t2}from"zod";I();P();var nl=class{writer=null;initAttempted=!1;ensure(e){if(this.initAttempted||(this.initAttempted=!0,e.depth!==void 0||e.parentSessionId!==void 0)||b.AFK_SESSION_LEDGER_DISABLED==="1")return;let n=e.sessionId;if(!n)return;let r=new Wt(n);if(!r.active)return;this.writer=r;let o=e.getMetadata();r.record({kind:"meta",sessionId:n,model:o.model??e.fallbackModel,...o.cwd!==void 0?{cwd:o.cwd}:{},traceLabel:rn(e.tracePath)})}recordUser(e){this.writer?.recordUser(e)}recordEvent(e){this.writer?.recordEvent(e)}recordElicitation(e,n){this.writer?.record({kind:"elicitation",reqId:e,request:n})}seal(e){let n=this.writer;return n?(this.writer=null,this.initAttempted=!1,n.close(e)):Promise.resolve()}};var rl=class{pendingSeed;prePlanMode;modeBeforeDefault;recordModeTransition(e,n){if(e==="plan"){if(n!=="plan"){let r=n==="default"&&this.modeBeforeDefault!==void 0?this.modeBeforeDefault:n;this.prePlanMode=r==="autonomous"?void 0:r}}else e==="default"?this.modeBeforeDefault=n!=="default"&&n!=="plan"?n:void 0:this.modeBeforeDefault=void 0}clearModeBeforeDefault(){this.modeBeforeDefault=void 0}getPrePlanMode(){return this.prePlanMode}requestImplementSeed(e,n){this.pendingSeed={message:e,mode:n}}takeSeed(){let e=this.pendingSeed;return this.pendingSeed=void 0,e}};function WA(t,e,n){t&&(t.aborted?e.abort(t.reason):t.addEventListener("abort",()=>{e.signal.aborted||e.abort(t.reason)},{once:!0})),e.signal.addEventListener("abort",n,{once:!0})}function KA(t,e){let n=t.permissionMode??"default",r=t.persistSession??!0,o={sessionId:t.sessionId,configuredSessionId:t.sessionId,resume:t.resume,resumeSessionAt:t.resumeSessionAt,continue:t.continue,forkSession:t.forkSession,persistSession:r},s={sessionId:t.sessionId,model:e,permissionMode:n};return{sessionIdentity:o,metadata:s}}var ol=class{initializationPromise;resolveInitialization;rejectInitialization;initializationSettled=!1;sessionMetadata;sessionIdentity;constructor(e,n){this.sessionIdentity=e,this.sessionMetadata=n,this.initializationPromise=new Promise((r,o)=>{this.resolveInitialization=r,this.rejectInitialization=o})}waitForInitialization(){return this.initializationPromise}getSessionIdentity(){return{...this.sessionIdentity,sessionId:this.getSessionId()}}getSessionMetadata(){return{...this.sessionMetadata,sessionId:this.getSessionId()}}getSessionId(){return this.sessionMetadata.sessionId??this.sessionIdentity.sessionId}updateSessionIdentity(e){e&&(this.sessionIdentity={...this.sessionIdentity,sessionId:e},this.sessionMetadata={...this.sessionMetadata,sessionId:e})}setSessionMetadata(e){this.sessionMetadata=e(this.sessionMetadata)}resolveInitializationIfNeeded(){this.initializationSettled||(this.initializationSettled=!0,this.resolveInitialization(this.getSessionMetadata()))}resolveInitializationOnce(){this.initializationSettled||(this.initializationSettled=!0,this.resolveInitialization(this.getSessionMetadata()))}rejectInitializationOnce(e){this.initializationSettled||(this.initializationSettled=!0,this.rejectInitialization(e))}isInitializationSettled(){return this.initializationSettled}};function qA(t){try{let e=JSON.parse(t);if(!Array.isArray(e))return null;let n=e.length;if(n===0)return"no results";let r=0,o=0;for(let a of e)if(a&&typeof a=="object"){let c=a.type;c==="fact"?r++:c==="procedure"&&o++}let s=`${n} result${n===1?"":"s"}`;if(r+o!==n)return s;let i=[];return r>0&&i.push(`${r} fact${r===1?"":"s"}`),o>0&&i.push(`${o} procedure${o===1?"":"s"}`),i.length===0?s:`${s} (${i.join(", ")})`}catch{return null}}function GA(t){try{let e=JSON.parse(t);if(!e||typeof e!="object")return null;let n=e;if(n.target==="hot"&&n.saved===!0){if(n.truncated===!0)return"hot memory saved (truncated to fit cap)";let r=n.usage;if(r&&typeof r=="object"){let o=r.pct;if(typeof o=="number")return`hot memory saved (${o}% of cap)`}return"hot memory saved"}if(n.target==="fact"){if(n.action==="remove")return n.removed===!0?"fact removed":"fact not found";if(n.action==="set"&&typeof n.id=="number")return`fact #${n.id} set`;if(n.action==="supersede"&&typeof n.id=="number"&&typeof n.supersedes=="number")return`fact #${n.id} supersedes #${n.supersedes}`}return null}catch{return null}}function XA(t){try{let e=JSON.parse(t);if(!e||typeof e!="object")return null;let n=e;return typeof n.name=="string"&&n.written===!0?`wrote procedure '${n.name}'`:null}catch{return null}}function Nf(t){let e=t.trim();if(e.length===0)return null;let n=e[0];if(n!=="{"&&n!=="[")return null;let r=e[e.length-1];if(n==="{"&&r!=="}"||n==="["&&r!=="]")return null;let o;try{o=JSON.parse(e)}catch{return null}return Array.isArray(o)?zA(vG(o)):o!==null&&typeof o=="object"?zA(TG(o)):null}function vG(t){return t.length===0?"[empty array]":t.length===1?"[1 item]":`[${t.length} items]`}function TG(t){let e=Object.keys(t);if(e.length===0)return"{empty object}";let n=e.slice(0,4),r=e.length>4?", \u2026":"";return`{${n.join(", ")}${r}}`}function zA(t){return t.length<=80?t:t.slice(0,79)+"\u2026"}var _G=new Map([["memory_search",qA],["memory_update",GA],["procedure_write",XA],["bash",Nf],["Bash",Nf]]);function JA(t,e){if(!t)return null;let n=_G.get(t);if(!n)return null;try{let r=n(e);if(r===null)return null;let o=we(r);return o.length>0?o:null}catch{return null}}function EG(t){if(t<1024)return`${t}B`;let e=t/1024;if(e<1024)return e%1===0?`${Math.floor(e)}KB`:`${e.toFixed(1)}KB`;let n=e/1024;if(n<1024)return n%1===0?`${Math.floor(n)}MB`:`${n.toFixed(1)}MB`;let r=n/1024;return r%1===0?`${Math.floor(r)}GB`:`${r.toFixed(1)}GB`}var AG=7;function VA(t){let e=Buffer.byteLength(t,"utf8"),n=EG(e),r=t.split(`
|
|
1271
|
+
`);if(r.length<=1)return t.length<=80?{content:t,truncated:!1,sizeBytes:e,sizeLabel:n}:{content:t.substring(0,80)+"\u2026",truncated:!0,sizeBytes:e,sizeLabel:n};let s=r.filter(d=>d.trim()!=="").slice(-AG),i=r.length-s.length;if(t.length<=80)return{content:t,truncated:!1,lineCount:r.length,sizeBytes:e,sizeLabel:n,tailPreview:s,hiddenLineCount:i};let a=r[0]??"",c=a;return a.length>80&&(c=a.substring(0,80)+"\u2026"),{content:c+`\u2026+${r.length} lines`,truncated:!0,lineCount:r.length,sizeBytes:e,sizeLabel:n,tailPreview:s,hiddenLineCount:i}}function xG(t){let e=/Output too large \((\d+(?:\.\d+)?)\s*(B|KB|MB|GB)\)\.\s*Full output saved to:\s*(\/[^\n]+)/,n=t.match(e);if(!n||!n[1]||!n[2]||!n[3])return null;let r=n[1],o=n[2],s=n[3],i=parseFloat(r),a=i;o==="KB"?a=i*1024:o==="MB"?a=i*1024*1024:o==="GB"&&(a=i*1024*1024*1024);let c=r;return i%1===0&&(c=String(Math.floor(i))),c+=o,{sizeLabel:c,sizeBytes:Math.round(a),absolutePath:s.trim()}}function RG(t,e){let n={...t.raw??{}};return t.inputTokens!==void 0&&(n.input_tokens=t.inputTokens),t.outputTokens!==void 0&&(n.output_tokens=t.outputTokens),t.cachedInputTokens!==void 0&&(n.cache_read_input_tokens=t.cachedInputTokens),t.cacheCreationTokens!==void 0&&(n.cache_creation_input_tokens=t.cacheCreationTokens),t.totalTokens!==void 0&&(n.total_tokens=t.totalTokens),t.contextWindowTokens!==void 0&&(n.context_window_tokens=t.contextWindowTokens),{sessionId:e,stopReason:t.stopReason??void 0,resultSubtype:t.resultSubtype,durationMs:t.durationMs,durationApiMs:t.durationApiMs,totalCostUsd:t.totalCostUsd,isError:t.isError,usage:Object.keys(n).length>0?n:void 0,modelUsage:t.modelUsage,permissionDenials:t.permissionDenials,errors:t.errors}}function IG(t){let e=t.isError===!0?null:JA(t.toolName,t.content),n=e!==null?{display:e}:{},r=typeof t.batchIndex=="number"&&typeof t.batchSize=="number"?{batchIndex:t.batchIndex,batchSize:t.batchSize}:{},o=t.failureClass?{failureClass:t.failureClass}:{},s=xG(t.content);if(s)return{type:"chunk",chunk:{type:"tool_result",toolUseId:t.toolUseId,content:`Output persisted (${s.sizeLabel}) \u2192 ${s.absolutePath}`,isError:t.isError===!0,persistedPath:s.absolutePath,sizeBytes:s.sizeBytes,sizeLabel:s.sizeLabel,...n,...r,...o}};let{content:i,lineCount:a,sizeBytes:c,sizeLabel:l,tailPreview:d,hiddenLineCount:u}=VA(t.content);return{type:"chunk",chunk:{type:"tool_result",toolUseId:t.toolUseId,content:i,isError:t.isError===!0,sizeBytes:c,sizeLabel:l,...t.truncated===!0&&{truncated:!0},...t.capturePath!==void 0&&{capturePath:t.capturePath},...a!==void 0&&{lineCount:a},...d!==void 0&&d.length>0&&{tailPreview:d},...u!==void 0&&{hiddenLineCount:u},...t.exitCode!==void 0&&{exitCode:t.exitCode},...t.durationMs!==void 0&&{durationMs:t.durationMs},...n,...r,...o}}}function Uf(t,e){switch(t.type){case"session.init":{let n=t.info;return e.setSessionMetadata(r=>({...r,sessionId:n.sessionId,model:n.model??r.model,...n.permissionMode!==void 0?{permissionMode:n.permissionMode}:{},...n.cwd!==void 0?{cwd:n.cwd}:{},tools:n.tools?[...n.tools]:r.tools,slashCommands:n.slashCommands?[...n.slashCommands]:r.slashCommands,skills:n.skills?[...n.skills]:r.skills,plugins:n.plugins?n.plugins.map(o=>({...o})):r.plugins,mcpServers:n.mcpServers?n.mcpServers.map(o=>({...o})):r.mcpServers,...n.apiKeySource!==void 0?{apiKeySource:n.apiKeySource}:{},...n.version!==void 0?{claudeCodeVersion:n.version}:{},...n.outputStyle!==void 0?{outputStyle:n.outputStyle}:{}})),e.updateSessionIdentity(n.sessionId),e.resolveInitialization(),null}case"session.status":return e.setSessionMetadata(n=>({...n,sessionId:t.sessionId,...t.permissionMode!==void 0?{permissionMode:t.permissionMode}:{permissionMode:n.permissionMode},...t.status!==void 0?{status:t.status}:{}})),null;case"delta.text":return{type:"chunk",chunk:{type:"content",content:t.text,metadata:{eventType:"delta",deltaType:"text_delta"}}};case"delta.reasoning":return{type:"chunk",chunk:{type:"thinking",content:t.text,metadata:{eventType:"delta",deltaType:"thinking_delta"}}};case"assistant.message":if(t.sessionId&&e.updateSessionIdentity(t.sessionId),t.text){let n={role:"assistant",content:t.text,timestamp:new Date};return e.conversationHistory.push(n),{type:"message",message:n}}return null;case"tool.use.start":return{type:"chunk",chunk:{type:"tool_use_detail",toolUseId:t.toolUseId,toolName:t.toolName,toolInput:t.toolInput,toolInputRaw:t.toolInputRaw,toolInputCapture:t.toolInputCapture,...t.pending?{pending:!0}:{}}};case"tool.use":return{type:"chunk",chunk:{type:"tool_use",content:t.summary,metadata:{eventType:"tool_use_summary",precedingToolUseIds:t.toolUseIds}}};case"tool.output":return t.isError!==!0&&t.toolName&&(e._successfulToolNames??=[]).push(t.toolName),IG(t);case"tool.diff":return{type:"chunk",chunk:{type:"tool_diff",toolUseId:t.toolUseId,diff:t.diff}};case"progress":return{type:"progress",progress:{taskId:t.progress.taskId,description:t.progress.description,...t.progress.summary!==void 0?{summary:t.progress.summary}:{},...t.progress.lastToolName!==void 0?{lastToolName:t.progress.lastToolName}:{},totalTokens:t.progress.totalTokens,toolUses:t.progress.toolUses,durationMs:t.progress.durationMs}};case"suggestion":return{type:"suggestion",suggestion:t.suggestion};case"turn.completed":{let n=RG(t.usage,t.sessionId??e.getSessionMetadata().sessionId);e._successfulToolNames!==void 0&&e._successfulToolNames.length>0&&(n.successfulToolNames=[...e._successfulToolNames]),e.setLastResponseMetadata(n);for(let r=e.conversationHistory.length-1;r>=0;r--){let o=e.conversationHistory[r];if(o?.role==="assistant"){o.metadata=n;break}}if(e.maxBudgetUsd!==void 0&&e.abortBudget!==void 0&&typeof n.totalCostUsd=="number"&&(e._runningCostUsd=(e._runningCostUsd??0)+n.totalCostUsd,e._runningCostUsd>=e.maxBudgetUsd)){Vm(e.traceWriter,{kind:"monetary",runningCostUsd:e._runningCostUsd,maxBudgetUsd:e.maxBudgetUsd,lastTurnCostUsd:n.totalCostUsd});let r=new nt(e._runningCostUsd,e.maxBudgetUsd);return e.abortBudget(r),{type:"error",error:r}}return{type:"done",metadata:n}}case"error":return{type:"error",error:t.error};case"paused":return{type:"paused",reason:t.reason,...t.resetsAt!==void 0?{resetsAt:t.resetsAt}:{},...t.accountId!==void 0?{accountId:t.accountId}:{},...t.autoResume!==void 0?{autoResume:t.autoResume}:{}};case"resumed":return{type:"resumed",hotSwapped:t.hotSwapped,...t.accountId!==void 0?{accountId:t.accountId}:{}};case"stream.retry":return{type:"stream_retry"};case"rate_limit":return{type:"rate_limit",...t.retryAfterMs!==void 0?{retryAfterMs:t.retryAfterMs}:{}};case"notice":return{type:"notice",text:t.text,kind:t.kind};case"tool.activity":return{type:"tool-activity",activeCount:t.activeCount,activeToolUseIds:t.activeToolUseIds};default:return null}}P();import{stat as CG,readFile as PG,writeFile as MG,rename as OG,unlink as DG}from"node:fs/promises";var YA=5*1024*1024,QA=5e3;async function ZA(t,{maxBytes:e,keepTailLines:n}){let r={trimmed:!1,removedLines:0},o;try{if((await CG(t)).size<=e)return r;let a=(await PG(t,"utf8")).split(`
|
|
1272
|
+
`);if(a.length>0&&a[a.length-1]===""&&a.pop(),a.length<=n)return r;let c=a.slice(a.length-n),l=a.length-c.length;return o=`${t}.tmp-${process.pid}-${Math.random().toString(36).slice(2,8)}`,await MG(o,c.join(`
|
|
1273
1273
|
`)+`
|
|
1274
|
-
`,{mode:384}),await
|
|
1275
|
-
`)}function ox(t){return t||b.AFK_WAVE_RESUME_UNATTENDED==="1"}function sx(t){try{let e=new Date().toISOString();t.offeredAt=e,t.updatedAt=e,t_(t)}catch{}}function
|
|
1276
|
-
`,{mode:384})}catch{}return ix(),
|
|
1277
|
-
`,{mode:384})}catch{}return{skipped:!1,evictedAge:l,evictedCount:d,remaining:g}}catch{return{skipped:!1,evictedAge:0,evictedCount:0,remaining:0}}}var It=class{ownedTraceWriter;config;planExit=new rl;currentState="idle";providerQuery;providerIterator;conversationHistory=[];turnCount=0;inboundMessageCount=0;subagentOutputRecorder;pendingFrameworkContext=[];lastResponseMetadata=null;initPromise=null;inputStream;abortController;_hookRegistry;sessionEndDispatched=!1;ownsTraceSeal;stateManager;sessionRunningCostUsd=0;sessionRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0};lastStopReason;maxTurnsHit=!1;hookBlocked=!1;sawProviderError=!1;sessionStartedAt=Date.now();subagentCompletedCount=0;subagentRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0};subagentRunningCostUsd=0;ledger=new nl;outputBroadcast=new Ys;constructor(e,n){this.ownsTraceSeal=n!==void 0&&e.traceWriter===n,this.ownedTraceWriter=this.ownsTraceSeal?n:void 0,this.config=e.parentSessionId===void 0&&e.planExitControls===void 0?{...e,planExitControls:{setPermissionMode:o=>this.setPermissionMode(o),requestImplementSeed:(o,s)=>this.planExit.requestImplementSeed(o,s),getPrePlanMode:()=>this.planExit.getPrePlanMode()}}:e,this.abortController=new AbortController,this._hookRegistry=e.hookRegistry,WA(e.abortSignal,this.abortController,()=>{this.onAbort()});let r=String(e.model);U(e.traceWriter,{phase:"session_init_start",model:r,resolvedModel:he(e.model)??r,origin:Ta(e.surface),actor:lp(e.parentSessionId)}),this.initSdkLifecycle(),this.config.parentSessionId===void 0&&(ZA(Ks(),{maxBytes:YA,keepTailLines:QA}),setTimeout(()=>{fx({activeLabel:rn(this.config.traceWriter?.getTracePath())??void 0})},mx).unref(),setTimeout(()=>{Sx({activeSessionId:this.sessionId})},wx).unref())}initSdkLifecycle(){this.config.models&&ed(this.config.models),Zc(this.config);let e=he(this.config.model)??this.config.model,{sessionIdentity:n,metadata:r}=KA(this.config,e);this.stateManager=new ol(n,r),this.inputStream=new Mr(()=>this.sessionId);let o=this.inputStream.createIterable();if(this.config.provider)C(`\u{1F7E2} AgentSession: Creating query session via injected provider=${this.config.provider.name}`),this.providerQuery=this.config.provider.query({prompt:o,config:this.config});else{C("\u{1F7E2} AgentSession: Creating query session via ProviderRouter");let i=this.config.providerFactory?this.config.providerFactory:a=>Qc(a,void 0,{customTools:this.config.customTools,canUseTool:this.config.canUseTool});this.providerQuery=new el({prompt:o,config:this.config},{resolveProvider:i,providerNameForModel:a=>z(a),resolveApiKey:a=>se(a)})}this.conversationHistory=[],this.turnCount=0,this.lastResponseMetadata=null,this.sessionRunningCostUsd=0,this.sessionRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0},this.lastStopReason=void 0,this.maxTurnsHit=!1,this.hookBlocked=!1,this.sawProviderError=!1,this.sessionEndDispatched=!1,this.currentState="idle",this.subagentCompletedCount=0,this.subagentRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0},this.subagentRunningCostUsd=0,this.pendingFrameworkContext=[];let s=this.providerQuery;this.providerIterator=s[Symbol.asyncIterator](),this.initPromise=this.pullInitialization()}async pullInitialization(){try{let e=await NA(this._hookRegistry,{event:"SessionStart",sessionId:this.sessionId,parentSessionId:this.config.parentSessionId},{signal:this.abortController.signal,...this.config.traceWriter?{traceWriter:this.config.traceWriter}:{}});for(e&&this.config.parentSessionId===void 0&&this.queueFrameworkContext(e);;){let n=await this.providerIterator.next();if(n.done){this.stateManager.resolveInitializationIfNeeded();return}let r=n.value,o=Uf(r,this.buildTransformDeps());if(r.type==="session.init"){await U(this.config.traceWriter,{phase:"session_init_done",durationMs:Date.now()-this.sessionStartedAt});return}if(o&&o.type==="error"){this.sawProviderError=!0;return}}}catch(e){let n=e instanceof Error?e:new Error(String(e));n instanceof q&&(this.hookBlocked=!0),this.stateManager.isInitializationSettled()||this.stateManager.rejectInitializationOnce(n),await this.dispatchSessionEndOnce("error").catch(()=>{})}}buildTransformDeps(){return{_successfulToolNames:[],conversationHistory:this.conversationHistory,getSessionMetadata:()=>this.stateManager.getSessionMetadata(),setSessionMetadata:e=>this.stateManager.setSessionMetadata(e),updateSessionIdentity:e=>this.stateManager.updateSessionIdentity(e),resolveInitialization:()=>this.stateManager.resolveInitializationOnce(),setLastResponseMetadata:e=>{this.lastResponseMetadata=e,typeof e.totalCostUsd=="number"&&Number.isFinite(e.totalCostUsd)&&(this.sessionRunningCostUsd+=e.totalCostUsd);let n=e.usage;if(n&&typeof n=="object"){let r=n,o=(s,i)=>{let a=r[s];typeof a=="number"&&Number.isFinite(a)&&(this.sessionRunningTokens[i]+=a)};o("input_tokens","input"),o("output_tokens","output"),o("cache_read_input_tokens","cacheRead"),o("cache_creation_input_tokens","cacheCreation")}typeof e.stopReason=="string"&&(this.lastStopReason=e.stopReason)},maxBudgetUsd:this.config.maxBudgetUsd,abortBudget:e=>{this.abortController.signal.aborted||this.abortController.abort(e)},...this.config.traceWriter?{traceWriter:this.config.traceWriter}:{}}}get state(){return this.currentState}get sessionId(){return this.stateManager.getSessionId()}get cwd(){return this.config.cwd}get abortSignal(){return this.abortController.signal}get hookRegistry(){return this._hookRegistry}abort(e){if(e==="closed"||e.startsWith("Budget ")||e.includes("timed out"))throw new Error(`AgentSession.abort: reserved reason "${e}" (use a caller-specific string like 'sigint')`);this.abortController.signal.aborted||this.abortController.abort(e)}async sendMessage(e,n={}){this.assertCanSend();let r=this.config.timeoutMs??nf,o=async()=>{let s=null,i="";this.currentState=n.stream?"streaming":"processing";for await(let a of this.sendMessageStreamInternal(e)){if(a.type==="chunk"&&a.chunk.type==="content"&&(i+=a.chunk.content),a.type==="message"&&a.message.role==="assistant"&&(s=a.message),a.type==="error")throw a.error;if(a.type==="done"){if(s)return{...s,metadata:a.metadata};if(i)return{role:"assistant",content:i,metadata:a.metadata,timestamp:new Date}}}if(s)return s;if(i)return{role:"assistant",content:i,timestamp:new Date};throw new Error("No assistant response received")};try{return await cs(o(),r,{controller:this.abortController,label:this.sessionId??"session"})}finally{this.currentState==="processing"&&(this.currentState="idle")}}async sendMessageStructured(e,n,r={}){let{maxRetries:o=2,injectSchemaPrompt:s=!0,...i}=r,a=s?"\n\nRespond with ONLY a JSON object (optionally in a ```json fence) that conforms to this JSON Schema:\n```json\n"+JSON.stringify(
|
|
1274
|
+
`,{mode:384}),await OG(o,t),o=void 0,{trimmed:!0,removedLines:l}}catch{if(o!==void 0)try{await DG(o)}catch{}return r}}I();P();import{readdir as Bf,stat as $f,rm as lx,writeFile as UG}from"node:fs/promises";import{join as vs}from"node:path";import{readdirSync as ex,unlinkSync as tx}from"node:fs";P();I();var FG=new Set(["pending","running"]),LG=2880*60*1e3;function nx(t){let e={offers:[],deletedExpired:0};try{let n=Fn(),r;try{r=ex(n)}catch{return e}let o=Date.now();for(let s of r){if(!s.endsWith(".json"))continue;let i=s.slice(0,-5);if(!/^[A-Za-z0-9]+$/.test(i))continue;let a=Yp(i);if(a===void 0)continue;let c=new Date(a.expiresAt).getTime();if(!Number.isFinite(c)||c<o){try{tx(Ln(i)),e.deletedExpired+=1}catch{}continue}if(a.offeredAt!==void 0)continue;let l=new Date(a.createdAt).getTime(),d=Number.isFinite(l)?l:0,u=o-d<LG,p=a.parentSessionId===t.sessionId;if(!u&&!p)continue;let f=a.units.filter(y=>FG.has(y.status));if(f.length===0)continue;let m=new Set(a.units.filter(y=>y.status==="done").map(y=>y.id)),g=[],h=[];for(let y of f){if(y.upstreamIds.length>0&&y.upstreamIds.some(v=>!m.has(v))){g.push(y);continue}let k=e_(y.worktreePath);h.push({unit:y,worktreeStatus:k})}(h.length>0||g.length>0)&&e.offers.push({manifest:a,resumable:h,blocked:g})}}catch{}return e}function rx(t){let{manifest:e,resumable:n,blocked:r}=t,o=new Date(e.createdAt),s=Date.now()-o.getTime(),i=NG(s),a=[`[wave-resume] Wave ${e.waveId} from ${i} ago has ${n.length+r.length} unsettled unit(s).`,` Source: ${e.source}`];if(n.length>0){a.push(" Units ready to resume:");for(let{unit:c,worktreeStatus:l}of n){let d=Ae(c.promptDigest.head.slice(0,80)).replace(/\n/g," "),u=c.cwd!==void 0?` (cwd: ${Ae(c.cwd)})`:"",p=l==="missing"?" \u26A0 worktree was swept \u2014 cannot re-dispatch without its working directory":"";a.push(` \xB7 ${c.id}: ${d}...${u}${p}`)}}if(r.length>0){a.push(" Units blocked on failed upstream deps:");for(let c of r)a.push(` \xB7 ${c.id} (depends on: ${c.upstreamIds.join(", ")})`)}return a.push(" To retry, re-dispatch each ready unit's prompt from its listed cwd; this notice does not accept yes/no replies."),a.join(`
|
|
1275
|
+
`)}function ox(t){return t||b.AFK_WAVE_RESUME_UNATTENDED==="1"}function sx(t){try{let e=new Date().toISOString();t.offeredAt=e,t.updatedAt=e,t_(t)}catch{}}function NG(t){let e=Math.floor(t/6e4);if(e<60)return`${e}m`;let n=Math.floor(e/60);return n<24?`${n}h`:`${Math.floor(n/24)}d`}function ix(){let t=0;try{let e=Fn(),n;try{n=ex(e)}catch{return{deleted:t}}let r=Date.now();for(let o of n){if(!o.endsWith(".json"))continue;let s=o.slice(0,-5);if(!/^[A-Za-z0-9]+$/.test(s))continue;let i=Yp(s);if(i===void 0)continue;let a=new Date(i.expiresAt).getTime();if(!(Number.isFinite(a)&&a>=r))try{tx(Ln(s)),t+=1}catch{}}}catch{}return{deleted:t}}var $G=30,BG=2*1024*1024*1024,dx=3600*1e3,jG=360*60*1e3,ux=".last-sweep";async function HG(t){try{let n=(await Bf(t.root,{withFileTypes:!0})).filter(a=>a.isDirectory()&&a.name!==t.activeLabel),r=[];for(let a of n){let c=vs(t.root,a.name);try{r.push({label:a.name,path:c,...await px(c)})}catch{}}r.sort((a,c)=>a.newestMtimeMs-c.newestMtimeMs);let o=r.filter(a=>t.now-a.newestMtimeMs>=dx),s=r.reduce((a,c)=>a+c.bytes,0),i=new Set;for(let a of o)t.now-a.newestMtimeMs>t.maxAgeMs&&i.add(a.label);for(let a of o){if(s<=t.maxBytes)break;if(i.has(a.label)){s-=a.bytes;continue}i.add(a.label),s-=a.bytes}for(let a of r)if(i.has(a.label))try{await lx(a.path,{recursive:!0,force:!0})}catch{}}catch{}}var ax=()=>({skipped:!0,scanned:0,evicted:0,freedBytes:0,evictedLabels:[]});function cx(t,e){let n=Number.parseFloat(t??"");return Number.isFinite(n)&&n>0?n:e}async function px(t){let e=0,n=0,r=async o=>{let s=await Bf(o,{withFileTypes:!0});for(let i of s){let a=vs(o,i.name);if(i.isDirectory()){await r(a);continue}try{let c=await $f(a);n+=c.size,c.mtimeMs>e&&(e=c.mtimeMs)}catch{}}};if(await r(t),e===0)try{e=(await $f(t)).mtimeMs}catch{e=Date.now()}return{newestMtimeMs:e,bytes:n}}async function WG(t,e){try{let n=await $f(vs(t,ux));return e-n.mtimeMs<jG}catch{return!1}}async function fx(t={}){if(b.AFK_WITNESS_RETENTION_DISABLE==="1")return ax();let e=t.root??Pn(),n=Date.now();try{if(t.force!==!0&&await WG(e,n))return ax();let r=cx(t.maxAgeDays?.toString()??b.AFK_WITNESS_MAX_AGE_DAYS,$G)*24*60*60*1e3,o=cx(t.maxBytes?.toString()??b.AFK_WITNESS_MAX_BYTES,BG),i=(await Bf(e,{withFileTypes:!0})).filter(p=>p.isDirectory()&&p.name!==t.activeLabel),a=[];for(let p of i){let f=vs(e,p.name);try{a.push({label:p.name,path:f,...await px(f)})}catch{}}a.sort((p,f)=>p.newestMtimeMs-f.newestMtimeMs);let c=a.filter(p=>n-p.newestMtimeMs>=dx),l=a.reduce((p,f)=>p+f.bytes,0),d=new Set;for(let p of c)n-p.newestMtimeMs>r&&d.add(p.label);for(let p of c){if(l<=o)break;if(d.has(p.label)){l-=p.bytes;continue}d.add(p.label),l-=p.bytes}let u={skipped:!1,scanned:a.length,evicted:0,freedBytes:0,evictedLabels:[]};for(let p of a)if(d.has(p.label))try{await lx(p.path,{recursive:!0,force:!0}),u.evicted+=1,u.freedBytes+=p.bytes,u.evictedLabels.push(p.label)}catch{}try{await UG(vs(e,ux),`${new Date(n).toISOString()}
|
|
1276
|
+
`,{mode:384})}catch{}return ix(),HG({root:jl(),activeLabel:t.activeLabel,maxAgeMs:r,maxBytes:o,now:n}),u}catch{return{skipped:!1,scanned:0,evicted:0,freedBytes:0,evictedLabels:[]}}}var mx=5e3;P();I();import{readdir as KG,readFile as qG,stat as sl,unlink as GG,writeFile as XG,access as zG}from"node:fs/promises";import{join as jf}from"node:path";var JG=360*60*1e3,gx=3600*1e3,bx=".last-sweep-sidecars",VG=30,YG=1e3,QG=1440*60*1e3,wx=5e3;function hx(t,e){let n=Number.parseFloat(t??"");return Number.isFinite(n)&&n>0?n:e}var yx=t=>({skipped:!0,reason:t,evictedAge:0,evictedCount:0,remaining:0});async function ZG(t,e){try{let n=await sl(jf(t,bx));return e-n.mtimeMs<JG}catch{return!1}}async function e2(t){try{return await zG(t),!0}catch{return!1}}async function Sx(t){if(b.AFK_SESSION_RETENTION_DISABLE==="1")return yx("disabled");let e=t?.root??oe(),n=Date.now();try{if(t?.force!==!0&&await ZG(e,n))return yx("stamp");if(!await e2(e))return{skipped:!1,evictedAge:0,evictedCount:0,remaining:0};let r=hx(b.AFK_SESSION_MAX_AGE_DAYS,VG),o=hx(b.AFK_SESSION_MAX_COUNT,YG),s=r*QG,i=await KG(e,{withFileTypes:!0}),a=[];for(let h of i){if(!h.isFile()||!h.name.endsWith(".json")||t?.activeSessionId!==void 0&&h.name===`${t.activeSessionId}.json`)continue;let y=jf(e,h.name),w,k;try{let v=await qG(y,"utf8"),_=JSON.parse(v);k=(await sl(y)).mtimeMs,_!==null&&typeof _=="object"&&"savedAt"in _&&typeof _.savedAt=="number"?w=_.savedAt:w=k}catch{try{let v=await sl(y);w=v.mtimeMs,k=v.mtimeMs}catch{continue}}a.push({name:h.name,path:y,ageMs:Math.max(0,n-w),savedAtMs:w,mtimeMs:k})}let c=a.filter(h=>h.ageMs>=gx);c.sort((h,y)=>h.savedAtMs-y.savedAtMs);let l=0,d=0,u=new Map;for(let h of c)h.ageMs>s&&(u.set(h.path,"age"),l+=1);let p=a.filter(h=>!u.has(h.path));if(p.length>o){let h=p.filter(w=>w.ageMs>=gx);h.sort((w,k)=>w.savedAtMs-k.savedAtMs);let y=p.length;for(let w of h){if(y<=o)break;u.has(w.path)||(u.set(w.path,"count"),d+=1,y-=1)}}let f=t?._unlink??GG,m=0;for(let[h,y]of u)try{let w=a.find(k=>k.path===h);if(w!==void 0&&(await sl(h)).mtimeMs!==w.mtimeMs){y==="age"?l-=1:d-=1;continue}await f(h),m+=1}catch{y==="age"?l-=1:d-=1}let g=a.length-m;try{await XG(jf(e,bx),`${new Date(n).toISOString()}
|
|
1277
|
+
`,{mode:384})}catch{}return{skipped:!1,evictedAge:l,evictedCount:d,remaining:g}}catch{return{skipped:!1,evictedAge:0,evictedCount:0,remaining:0}}}var It=class{ownedTraceWriter;config;planExit=new rl;currentState="idle";providerQuery;providerIterator;conversationHistory=[];turnCount=0;inboundMessageCount=0;subagentOutputRecorder;pendingFrameworkContext=[];lastResponseMetadata=null;initPromise=null;inputStream;abortController;_hookRegistry;sessionEndDispatched=!1;ownsTraceSeal;stateManager;sessionRunningCostUsd=0;sessionRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0};lastStopReason;maxTurnsHit=!1;hookBlocked=!1;sawProviderError=!1;sessionStartedAt=Date.now();subagentCompletedCount=0;subagentRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0};subagentRunningCostUsd=0;ledger=new nl;outputBroadcast=new Ys;constructor(e,n){this.ownsTraceSeal=n!==void 0&&e.traceWriter===n,this.ownedTraceWriter=this.ownsTraceSeal?n:void 0,this.config=e.parentSessionId===void 0&&e.planExitControls===void 0?{...e,planExitControls:{setPermissionMode:o=>this.setPermissionMode(o),requestImplementSeed:(o,s)=>this.planExit.requestImplementSeed(o,s),getPrePlanMode:()=>this.planExit.getPrePlanMode()}}:e,this.abortController=new AbortController,this._hookRegistry=e.hookRegistry,WA(e.abortSignal,this.abortController,()=>{this.onAbort()});let r=String(e.model);U(e.traceWriter,{phase:"session_init_start",model:r,resolvedModel:he(e.model)??r,origin:Ta(e.surface),actor:lp(e.parentSessionId)}),this.initSdkLifecycle(),this.config.parentSessionId===void 0&&(ZA(Ks(),{maxBytes:YA,keepTailLines:QA}),setTimeout(()=>{fx({activeLabel:rn(this.config.traceWriter?.getTracePath())??void 0})},mx).unref(),setTimeout(()=>{Sx({activeSessionId:this.sessionId})},wx).unref())}initSdkLifecycle(){this.config.models&&ed(this.config.models),Zc(this.config);let e=he(this.config.model)??this.config.model,{sessionIdentity:n,metadata:r}=KA(this.config,e);this.stateManager=new ol(n,r),this.inputStream=new Mr(()=>this.sessionId);let o=this.inputStream.createIterable();if(this.config.provider)C(`\u{1F7E2} AgentSession: Creating query session via injected provider=${this.config.provider.name}`),this.providerQuery=this.config.provider.query({prompt:o,config:this.config});else{C("\u{1F7E2} AgentSession: Creating query session via ProviderRouter");let i=this.config.providerFactory?this.config.providerFactory:a=>Qc(a,void 0,{customTools:this.config.customTools,canUseTool:this.config.canUseTool});this.providerQuery=new el({prompt:o,config:this.config},{resolveProvider:i,providerNameForModel:a=>z(a),resolveApiKey:a=>se(a)})}this.conversationHistory=[],this.turnCount=0,this.lastResponseMetadata=null,this.sessionRunningCostUsd=0,this.sessionRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0},this.lastStopReason=void 0,this.maxTurnsHit=!1,this.hookBlocked=!1,this.sawProviderError=!1,this.sessionEndDispatched=!1,this.currentState="idle",this.subagentCompletedCount=0,this.subagentRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0},this.subagentRunningCostUsd=0,this.pendingFrameworkContext=[];let s=this.providerQuery;this.providerIterator=s[Symbol.asyncIterator](),this.initPromise=this.pullInitialization()}async pullInitialization(){try{let e=await NA(this._hookRegistry,{event:"SessionStart",sessionId:this.sessionId,parentSessionId:this.config.parentSessionId},{signal:this.abortController.signal,...this.config.traceWriter?{traceWriter:this.config.traceWriter}:{}});for(e&&this.config.parentSessionId===void 0&&this.queueFrameworkContext(e);;){let n=await this.providerIterator.next();if(n.done){this.stateManager.resolveInitializationIfNeeded();return}let r=n.value,o=Uf(r,this.buildTransformDeps());if(r.type==="session.init"){await U(this.config.traceWriter,{phase:"session_init_done",durationMs:Date.now()-this.sessionStartedAt});return}if(o&&o.type==="error"){this.sawProviderError=!0;return}}}catch(e){let n=e instanceof Error?e:new Error(String(e));n instanceof q&&(this.hookBlocked=!0),this.stateManager.isInitializationSettled()||this.stateManager.rejectInitializationOnce(n),await this.dispatchSessionEndOnce("error").catch(()=>{})}}buildTransformDeps(){return{_successfulToolNames:[],conversationHistory:this.conversationHistory,getSessionMetadata:()=>this.stateManager.getSessionMetadata(),setSessionMetadata:e=>this.stateManager.setSessionMetadata(e),updateSessionIdentity:e=>this.stateManager.updateSessionIdentity(e),resolveInitialization:()=>this.stateManager.resolveInitializationOnce(),setLastResponseMetadata:e=>{this.lastResponseMetadata=e,typeof e.totalCostUsd=="number"&&Number.isFinite(e.totalCostUsd)&&(this.sessionRunningCostUsd+=e.totalCostUsd);let n=e.usage;if(n&&typeof n=="object"){let r=n,o=(s,i)=>{let a=r[s];typeof a=="number"&&Number.isFinite(a)&&(this.sessionRunningTokens[i]+=a)};o("input_tokens","input"),o("output_tokens","output"),o("cache_read_input_tokens","cacheRead"),o("cache_creation_input_tokens","cacheCreation")}typeof e.stopReason=="string"&&(this.lastStopReason=e.stopReason)},maxBudgetUsd:this.config.maxBudgetUsd,abortBudget:e=>{this.abortController.signal.aborted||this.abortController.abort(e)},...this.config.traceWriter?{traceWriter:this.config.traceWriter}:{}}}get state(){return this.currentState}get sessionId(){return this.stateManager.getSessionId()}get cwd(){return this.config.cwd}get abortSignal(){return this.abortController.signal}get hookRegistry(){return this._hookRegistry}abort(e){if(e==="closed"||e.startsWith("Budget ")||e.includes("timed out"))throw new Error(`AgentSession.abort: reserved reason "${e}" (use a caller-specific string like 'sigint')`);this.abortController.signal.aborted||this.abortController.abort(e)}async sendMessage(e,n={}){this.assertCanSend();let r=this.config.timeoutMs??nf,o=async()=>{let s=null,i="";this.currentState=n.stream?"streaming":"processing";for await(let a of this.sendMessageStreamInternal(e)){if(a.type==="chunk"&&a.chunk.type==="content"&&(i+=a.chunk.content),a.type==="message"&&a.message.role==="assistant"&&(s=a.message),a.type==="error")throw a.error;if(a.type==="done"){if(s)return{...s,metadata:a.metadata};if(i)return{role:"assistant",content:i,metadata:a.metadata,timestamp:new Date}}}if(s)return s;if(i)return{role:"assistant",content:i,timestamp:new Date};throw new Error("No assistant response received")};try{return await cs(o(),r,{controller:this.abortController,label:this.sessionId??"session"})}finally{this.currentState==="processing"&&(this.currentState="idle")}}async sendMessageStructured(e,n,r={}){let{maxRetries:o=2,injectSchemaPrompt:s=!0,...i}=r,a=s?"\n\nRespond with ONLY a JSON object (optionally in a ```json fence) that conforms to this JSON Schema:\n```json\n"+JSON.stringify(t2.toJSONSchema(n,{target:"openapi-3.0"}))+"\n```":"",c="";for(let l=0;l<=o;l++){let d=l===0?e+a:`Your previous response did not match the required JSON schema.
|
|
1278
1278
|
Validation error: ${c}
|
|
1279
1279
|
Respond again with ONLY a JSON object (optionally in a \`\`\`json fence) that satisfies the schema.`+a,u=await this.sendMessage(d,i),p=os(u.content),f=n.safeParse(p);if(f.success)return f.data;c=f.error.message}throw new Error(`structured output did not match schema after ${o+1} attempt(s): ${c}`)}async*sendMessageStream(e){this.assertCanSend(),this.currentState="streaming";try{yield*this.sendMessageStreamInternal(e)}finally{this.currentState==="streaming"&&(this.currentState="idle")}}async*sendMessageStreamInternal(e){this.initPromise&&await this.initPromise,this.planExit.clearModeBeforeDefault();let n=this.withPendingFrameworkContext(e),r=typeof n=="string"?n:this.summarizeContentBlocks(n),o={role:"user",content:r,timestamp:new Date};this.conversationHistory.push(o),this.inputStream.pushUserMessage(n),this.ensureLedger(),this.ledger.recordUser(r);let s=++this.inboundMessageCount;qm({sessionId:rn(this.config.traceWriter?.getTracePath())??this.sessionId,subagentId:this.config.subagentId,isSubagentFork:this.config.isSubagentFork===!0,model:this.config.model===void 0?void 0:String(this.config.model),turn:s,prompt:r});let i=this.buildTransformDeps();this.subagentOutputRecorder===void 0&&(this.subagentOutputRecorder=Jm({sessionId:rn(this.config.traceWriter?.getTracePath())??this.sessionId,subagentId:this.config.subagentId,isSubagentFork:this.config.isSubagentFork===!0,model:this.config.model===void 0?void 0:String(this.config.model)}));let a=this.subagentOutputRecorder;try{for(;;){let c=await this.providerIterator.next();if(c.done)break;let l=c.value,d=Uf(l,i);if(d&&(a?.observe(d),d.type==="done"?(this.turnCount++,this.sawProviderError=!1):d.type==="error"&&(this.sawProviderError=!0),this.ledger.recordEvent(d),this.outputBroadcast.push(d),yield d,d.type==="done"||d.type==="error"))break}a?.end("stream_complete")}finally{this.currentState==="streaming"&&(a?.end("aborted_or_incomplete"),this.currentState="idle")}}ensureLedger(){this.ledger.ensure({depth:this.config.depth,parentSessionId:this.config.parentSessionId,sessionId:this.sessionId,fallbackModel:String(this.config.model),tracePath:this.config.traceWriter?.getTracePath(),getMetadata:()=>this.getSessionMetadata()})}recordLedgerElicitation(e,n){this.ledger.recordElicitation(e,n)}summarizeContentBlocks(e){let n=[],r=0;for(let s of e)s.type==="text"?n.push(s.text):s.type==="image"&&r++;let o=n.join(" ");return r>0&&(o=o?`${o} [+ ${r} image(s)]`:`[+ ${r} image(s)]`),o||"[content block(s)]"}async interrupt(){this.currentState!=="streaming"&&this.currentState!=="processing"||(this.currentState="idle",await this.providerQuery.interrupt())}setBeforeNextRound(e){this.providerQuery.setBeforeNextRound?.(e)}async reset(){if(this.currentState==="closed")throw new Error("Cannot reset: session is closed");if(this.abortController.signal.aborted)throw new Fe("Cannot reset: session aborted");if(this.currentState==="processing"||this.currentState==="streaming")try{await this.providerQuery.interrupt()}catch{}await this.dispatchSessionEndOnce("reset"),await this.ledger.seal("reset");try{await this.providerQuery.close()}catch{}await this.providerIterator.return?.(),this.initPromise&&await Promise.race([this.initPromise,new Promise(e=>setTimeout(e,vc))]).catch(()=>{}),this.stateManager.resolveInitializationIfNeeded(),this.config={...this.config},delete this.config.resume,delete this.config.sessionId,delete this.config.resumeHistory,delete this.config.resumeSessionAt,delete this.config.continue,delete this.config.forkSession;try{this.initSdkLifecycle()}catch(e){throw this.currentState="closed",new Error(`Session reset failed during lifecycle rebuild: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}async onAbort(){this.ledger.seal("abort");try{await this.providerQuery.interrupt(ld(this.abortController.signal.reason))}catch{}}async setModel(e){let n=he(e);typeof e=="string"&&e.length>0&&await this.providerQuery.setModel(e),n&&this.stateManager.setSessionMetadata(r=>({...r,model:n}))}async setPermissionMode(e){let n=this.stateManager.getSessionMetadata().permissionMode;this.planExit.recordModeTransition(e,n),await this.providerQuery.setPermissionMode(e),this.stateManager.setSessionMetadata(r=>({...r,permissionMode:e}))}getPrePlanMode(){return this.planExit.getPrePlanMode()}setPlanExitQueueCheck(e){this.config.planExitControls&&(this.config.planExitControls.hasPendingUserMessage=e)}async takePendingPlanExitSeed(){let e=this.planExit.takeSeed();if(e!==void 0){try{await this.setPermissionMode(e.mode)}catch(n){C(`\u26A0\uFE0F AgentSession: deferred plan-exit mode flip to '${e.mode}' rejected; dropping implement-seed (staying in plan mode): ${n instanceof Error?n.message:String(n)}`);return}return{message:e.message,mode:e.mode}}}setSystemPrompt(e){return this.config={...this.config,systemPrompt:e},this.providerQuery.setSystemPrompt?.(e)??!1}setCwd(e){this.config={...this.config,cwd:e},this.providerQuery.setCwd?.(e),this.config.sessionId!==void 0&&Eh(this.config.sessionId,e)}async reauth(){return await this.providerQuery.reauth?.()??null}waitForInitialization(){return this.stateManager.waitForInitialization()}getSessionIdentity(){return this.stateManager.getSessionIdentity()}getSessionMetadata(){return this.stateManager.getSessionMetadata()}getQuery(){return this.providerQuery}supportedCommands(){return this.providerQuery.supportedCommands()}supportedModels(){return this.providerQuery.supportedModels()}supportedAgents(){return this.providerQuery.supportedAgents()}getContextUsage(){return this.providerQuery.getContextUsage()}mcpServerStatus(){return this.providerQuery.mcpServerStatus()}accountInfo(){return this.providerQuery.accountInfo()}rewindFiles(e,n){return this.providerQuery.rewindFiles(e,n)}async compact(){if(this.currentState==="closed")throw new Error("Cannot compact: session is closed");if(this.currentState!=="idle")return{compacted:!1,reason:"session-busy",messagesBefore:0,messagesAfter:0};let e=this.providerQuery.compact?.bind(this.providerQuery);if(!e)return{compacted:!1,reason:"not-supported",messagesBefore:0,messagesAfter:0};this.currentState="compacting";try{return await e()}finally{this.currentState="idle"}}listRewindTargets(){return this.currentState==="closed"?[]:this.providerQuery.listRewindTargets?.()??[]}async rewindConversation(e){if(this.currentState==="closed")throw new Error("Cannot rewind: session is closed");if(this.currentState!=="idle")return{rewound:!1,reason:"session-busy",messagesBefore:0,messagesAfter:0};let n=this.providerQuery.rewindConversation?.bind(this.providerQuery);return n?n(e):{rewound:!1,reason:"not-supported",messagesBefore:0,messagesAfter:0}}getLastResponseMetadata(){return this.lastResponseMetadata}getOutputStream(){return this.outputBroadcast.subscribe()}queueFrameworkContext(e){let n=e.trim();n.length!==0&&(this.pendingFrameworkContext.push(n),C(`AgentSession: queued framework context (${n.length} chars) for the next user message`))}withPendingFrameworkContext(e){if(this.pendingFrameworkContext.length===0)return e;let n=this.pendingFrameworkContext.join(`
|
|
1280
1280
|
|
|
1281
1281
|
`);return this.pendingFrameworkContext=[],typeof e=="string"?`${n}
|
|
1282
1282
|
|
|
1283
|
-
${e}`:[{type:"text",text:n},...e]}getInputStreamRef(){return{pushUserMessage:e=>this.inputStream.pushUserMessage(e),queueFrameworkContext:e=>this.queueFrameworkContext(e)}}getHistory(){return[...this.conversationHistory]}getTurnCount(){return this.turnCount}async close(){if(this.currentState!=="closed"){this.currentState="closed",this.outputBroadcast.close(),await this.ledger.seal("close"),this.abortController.signal.aborted||this.abortController.abort("closed"),this.stateManager.resolveInitializationIfNeeded();try{await this.providerQuery.close()}catch{}if(await this.providerIterator.return?.(),this.initPromise)try{await Promise.race([this.initPromise,new Promise(e=>setTimeout(e,vc))])}catch{}await this.dispatchSessionEndOnce("close")}}async dispatchSessionEndOnce(e){if(this.sessionEndDispatched)return;this.sessionEndDispatched=!0,this.config.drainSubagents!==void 0&&await this.config.drainSubagents(e).catch(()=>{});let n=this.closureSignals(e);await jA(this.config.traceWriter,{...n,finalTurnCount:this.turnCount,finalCostUsd:this.sessionRunningCostUsd,runningTokens:this.sessionRunningTokens}).catch(()=>{}),this.ownsTraceSeal&&await HA(this.ownedTraceWriter,{...n,finalTurnCount:this.turnCount,finalCostUsd:this.sessionRunningCostUsd,subagentCompletedCount:this.subagentCompletedCount,subagentRunningTokens:this.subagentRunningTokens,subagentRunningCostUsd:this.subagentRunningCostUsd}).catch(()=>{}),await UA(this._hookRegistry,{event:"SessionEnd",sessionId:this.sessionId,reason:e,parentSessionId:this.config.parentSessionId,...this.config.traceWriter?{tracePath:this.config.traceWriter.getTracePath()}:{}},this.config.traceWriter&&!this.ownsTraceSeal?{traceWriter:this.config.traceWriter}:{})}closureSignals(e){return{dispatchReason:e,signal:this.abortController.signal,maxTurnsHit:this.maxTurnsHit,hookBlocked:this.hookBlocked,lastStopReason:this.lastStopReason,sawProviderError:this.sawProviderError}}recordSubagentCompletion(e,n){if(this.subagentCompletedCount++,e){let r=(o,s)=>{typeof o=="number"&&Number.isFinite(o)&&o>0&&(this.subagentRunningTokens[s]+=o)};r(e.inputTokens,"input"),r(e.outputTokens,"output"),r(e.cacheReadTokens,"cacheRead"),r(e.cacheCreationTokens,"cacheCreation")}typeof n=="number"&&Number.isFinite(n)&&n>0&&(this.subagentRunningCostUsd+=n)}assertCanSend(){if(this.currentState==="closed")throw new Error("Cannot send message: session is closed");if(this.abortController.signal.aborted)throw new Fe("Cannot send message: session aborted");if(this.currentState==="processing"||this.currentState==="streaming"||this.currentState==="compacting")throw new Error("Cannot send message: session is busy");if(this.config.maxTurns&&this.turnCount>=this.config.maxTurns)throw this.maxTurnsHit=!0,new Error(`Maximum turns (${this.config.maxTurns}) exceeded`)}};var
|
|
1284
|
-
`)}function xx(){let t=b.AFK_COMPANION_PRIMER;if(t===void 0||t.trim().length===0)return null;try{let e=
|
|
1283
|
+
${e}`:[{type:"text",text:n},...e]}getInputStreamRef(){return{pushUserMessage:e=>this.inputStream.pushUserMessage(e),queueFrameworkContext:e=>this.queueFrameworkContext(e)}}getHistory(){return[...this.conversationHistory]}getTurnCount(){return this.turnCount}async close(){if(this.currentState!=="closed"){this.currentState="closed",this.outputBroadcast.close(),await this.ledger.seal("close"),this.abortController.signal.aborted||this.abortController.abort("closed"),this.stateManager.resolveInitializationIfNeeded();try{await this.providerQuery.close()}catch{}if(await this.providerIterator.return?.(),this.initPromise)try{await Promise.race([this.initPromise,new Promise(e=>setTimeout(e,vc))])}catch{}await this.dispatchSessionEndOnce("close")}}async dispatchSessionEndOnce(e){if(this.sessionEndDispatched)return;this.sessionEndDispatched=!0,this.config.drainSubagents!==void 0&&await this.config.drainSubagents(e).catch(()=>{});let n=this.closureSignals(e);await jA(this.config.traceWriter,{...n,finalTurnCount:this.turnCount,finalCostUsd:this.sessionRunningCostUsd,runningTokens:this.sessionRunningTokens}).catch(()=>{}),this.ownsTraceSeal&&await HA(this.ownedTraceWriter,{...n,finalTurnCount:this.turnCount,finalCostUsd:this.sessionRunningCostUsd,subagentCompletedCount:this.subagentCompletedCount,subagentRunningTokens:this.subagentRunningTokens,subagentRunningCostUsd:this.subagentRunningCostUsd}).catch(()=>{}),await UA(this._hookRegistry,{event:"SessionEnd",sessionId:this.sessionId,reason:e,parentSessionId:this.config.parentSessionId,...this.config.traceWriter?{tracePath:this.config.traceWriter.getTracePath()}:{}},this.config.traceWriter&&!this.ownsTraceSeal?{traceWriter:this.config.traceWriter}:{})}closureSignals(e){return{dispatchReason:e,signal:this.abortController.signal,maxTurnsHit:this.maxTurnsHit,hookBlocked:this.hookBlocked,lastStopReason:this.lastStopReason,sawProviderError:this.sawProviderError}}recordSubagentCompletion(e,n){if(this.subagentCompletedCount++,e){let r=(o,s)=>{typeof o=="number"&&Number.isFinite(o)&&o>0&&(this.subagentRunningTokens[s]+=o)};r(e.inputTokens,"input"),r(e.outputTokens,"output"),r(e.cacheReadTokens,"cacheRead"),r(e.cacheCreationTokens,"cacheCreation")}typeof n=="number"&&Number.isFinite(n)&&n>0&&(this.subagentRunningCostUsd+=n)}assertCanSend(){if(this.currentState==="closed")throw new Error("Cannot send message: session is closed");if(this.abortController.signal.aborted)throw new Fe("Cannot send message: session aborted");if(this.currentState==="processing"||this.currentState==="streaming"||this.currentState==="compacting")throw new Error("Cannot send message: session is busy");if(this.config.maxTurns&&this.turnCount>=this.config.maxTurns)throw this.maxTurnsHit=!0,new Error(`Maximum turns (${this.config.maxTurns}) exceeded`)}};var n2="sonnet";function Hf(t){let{model:e=n2,ownedTraceWriter:n,...r}=t;return new It({model:e,...r},n)}async function*kx(t,e={}){let n=Hf(e);try{yield*n.sendMessageStream(t)}finally{await n.close()}}async function vx(t,e={}){let n=Hf(e);try{return(await n.sendMessage(t)).content}finally{await n.close()}}async function Tx(t,e,n={}){let{maxRetries:r,injectSchemaPrompt:o,...s}=n,i=Hf(s),a={};r!==void 0&&(a.maxRetries=r),o!==void 0&&(a.injectSchemaPrompt=o);try{return await i.sendMessageStructured(t,e,a)}finally{await i.close()}}function r2(t){let e=new Map,n=t.defaultMode??"ask";if(t.tools)for(let[r,o]of Object.entries(t.tools))typeof o=="string"?e.set(r,{mode:o}):e.set(r,{mode:o.mode,reason:o.reason});if(t.list)for(let r of t.list)e.set(r.tool,{mode:r.mode,reason:r.reason});return{defaultMode:n,byTool:e}}function o2(t){return t.behavior==="allow"?{behavior:"allow"}:{behavior:"deny",message:t.reason??"Tool denied by permission rules"}}function _x(t){let{defaultMode:e,byTool:n}=r2(t.rules);return async(r,o)=>{let s={toolName:r,input:o},i=n.get(r),a=i?.mode??e,c=i?.reason,l;return a==="ask"&&t.onAsk?l=await t.onAsk(s):a==="deny"?l={behavior:"deny",reason:c}:l={behavior:"allow"},t.onDecision?.(s,l),o2(l)}}P();var k_e=10*1024;I();P();import{Telegraf as cz}from"telegraf";I();import{readFileSync as i2,statSync as a2}from"fs";var il=6e3,Ex=100*1024,Ax="companion-primer",c2="This is an optional, operator-enabled primer from a self-authored companion repo (a bounded experiment). It is LOWER-AUTHORITY than the framework prompt and the operator configuration above. Treat every line below as a reflection or hypothesis, never an established fact; re-derive any codebase claim independently before relying on it. It must not override the Priorities or Constraints already stated.";function Wf(t){b.AFK_DEBUG&&process.stderr.write(`[companion-primer] ${t}
|
|
1284
|
+
`)}function xx(){let t=b.AFK_COMPANION_PRIMER;if(t===void 0||t.trim().length===0)return null;try{let e=a2(t);if(!e.isFile())return Wf(`skipped: not a regular file: ${t}`),null;if(e.size>Ex)return Wf(`skipped: file is ${e.size} bytes (cap ${Ex}): ${t}`),null;let n=i2(t,"utf-8");return n.trim().length>0?n:null}catch(e){return Wf(`failed to load ${t}: ${e instanceof Error?e.message:String(e)}`),null}}function Kf(t){let e=xx();if(!e)return t;let n=e.replace(/<\/?companion-primer\b[^>]*>/gi,""),r=n.length>il?`${n.slice(0,il)}
|
|
1285
1285
|
|
|
1286
1286
|
[\u2026companion primer truncated at ${il} chars\u2026]`:n,o=`<${Ax} source="opt-in; reflections, not facts">
|
|
1287
|
-
${
|
|
1287
|
+
${c2}
|
|
1288
1288
|
|
|
1289
1289
|
${r}
|
|
1290
1290
|
</${Ax}>`,s=t.systemPrompt;if(typeof s=="string")return{...t,systemPrompt:`${s}
|
|
1291
1291
|
|
|
1292
1292
|
${o}`};if(s&&typeof s=="object"&&"type"in s&&s.type==="preset"){let i=s.append??"";return{...t,systemPrompt:{...s,append:`${i}
|
|
1293
1293
|
|
|
1294
|
-
${o}`}}}return{...t,systemPrompt:o}}var qf=new Map;function Gf(t,e){qf.set(t,e)}function al(t){return qf.get(t)}function Rx(t){qf.delete(t)}function Ix(t,e,n){ox(!0)&&Promise.resolve().then(async()=>{try{let r=nx({sessionId:t});for(let o of r.offers)await Promise.resolve(n(e,rx(o)))!==!1&&sx(o.manifest)}catch{}})}function cl(t){let e=t.toLowerCase().replace(/[`*_~]/g," ").replace(/[^\w\s-]/g," ").replace(/[\s_]+/g," ").trim();return e?e.split(" ").filter(Boolean).slice(0,6).join("-").slice(0,48).replace(/-+$/g,""):""}function Cx(t){return{totalTurns:0,totalCostUsd:0,unpricedTurns:0,totalTokens:0,totalDurationMs:0,sessionStartTime:Date.now(),turnCosts:[],turnTokens:[],turns:[],model:t,permissionMode:"default",thinkingUi:"live"}}function Px(t,e,n,r,o){let s=r?.totalCostUsd,i=s??0,a=r?.durationMs??0,c=Number(r?.usage?.input_tokens??0),l=Number(r?.usage?.output_tokens??0),d=c,u=l,p=Number(r?.usage?.cache_read_input_tokens??0)+Number(r?.usage?.cache_creation_input_tokens??0),f=r?.usage?.iterations;if(Array.isArray(f)&&f.length>0){let w=f[f.length-1];if(w&&typeof w=="object"){let k=w;d=Number(k.input_tokens??0),u=Number(k.output_tokens??0),p=Number(k.cache_read_input_tokens??0)+Number(k.cache_creation_input_tokens??0)}}t.totalTurns+=1,t.totalCostUsd+=i,s===void 0&&(t.unpricedTurns+=1),t.totalDurationMs+=a,t.totalTokens+=c+l,t.turnCosts.push(i);let m=Number(r?.usage?.context_window_tokens??NaN),g=Array.isArray(f)&&f.length>0,h=Number.isFinite(m)?m:g?d+u+p:void 0;if(t.turnTokens.push({input:d,output:u,cache:p,...h!==void 0?{footprint:h}:{}}),r?.sessionId&&!t.sessionId&&(t.sessionId=String(r.sessionId)),!t.name){let w=cl(e);w&&(t.name=w)}let y={user:e,assistant:n,timestamp:Date.now(),costUsd:i,durationMs:a,inputTokens:c,outputTokens:l,...o&&o.length>0?{toolEvents:o}:{}};return t.turns.push(y),y}import{readFileSync as
|
|
1295
|
-
[Tools used: ${y2(t).map(r=>{let o=r.isError?"\u2717":"\u2713",s=r.input||r.inputRaw||"",i=s.length>80?s.slice(0,77)+"\u2026":s;return`${r.toolName}(${i})${o}`}).join(", ")}]`}function Nx(t){return t?{resume:t.resumeId,sessionId:t.resumeId,...t.stored?{resumeHistory:t.stored.turns.map((e,n,r)=>{let o={user:e.user,assistant:(e.assistant??"")+Lx(e.toolEvents)};return n===r.length-1&&e.inputTokens!==void 0&&(o.inputTokens=e.inputTokens),o})}:{}}:{}}function b2(t){if(t===null||typeof t!="object")return{};let e=t,n=e.message_thread_id,r=e.is_topic_message;return{...typeof n=="number"?{threadId:n}:{},...r===!0?{isTopic:!0}:{}}}function V(t){let e=t.chat?.id;if(typeof e!="number")return;let n=t.message??t.editedMessage??t.callbackQuery?.message,{threadId:r,isTopic:o}=b2(n),s={chatId:e};return r!==void 0&&r!==0&&(s.threadId=r),o&&(s.isTopicMessage=!0),s}function Ux(t){return t.threadId===void 0||t.threadId===0||t.threadId===1}function j(t){return Ux(t)?String(t.chatId):`${t.chatId}:${t.threadId}`}function tn(t){return Ux(t)?{}:{message_thread_id:t.threadId}}function $x(t,e,n,r){let o=j(e),s=o,i=t.resolve("telegram",o);if(i){t.touch(i.id),n.sessionId&&t.attachSdkSessionId(i.id,n.sessionId);return}let a=t.get(s);if(a&&a.status==="active"){t.bind(s,{surface:"telegram",key:o}),n.sessionId&&t.attachSdkSessionId(s,n.sessionId);return}let c=a===void 0?s:void 0;t.create({surface:"telegram",key:o,model:n.model??r,id:c,sdkSessionId:n.sessionId})}function Yf(t,e){t.archive(e)}function Bx(t,e){let n;for(let o of t)o.chatId===e&&(!n||o.lastActivity>n.lastActivity)&&(n=o);if(!n)return;let r={chatId:n.chatId};return n.threadId!==void 0&&(r.threadId=n.threadId),r}function jx(t,e,n){let r=j(n);if(t.has(r))return;let o=e.get(r)?.sessionId;if(!o)return;let s=ft(o);if(!s||s.source!=="telegram"||s.telegramChatId!==n.chatId)return;let i={sessionId:s.sessionId,name:s.name,model:s.model,source:s.source,telegramChatId:s.telegramChatId,sessionStartTime:s.startedAt,totalTurns:s.totalTurns,totalCostUsd:s.totalCostUsd,unpricedTurns:s.unpricedTurns??0,totalTokens:s.totalTokens,totalDurationMs:s.totalDurationMs,turns:s.turns,turnCosts:[],turnTokens:[],permissionMode:"default"},a=e.get(r)?.cwd;a!==void 0&&(i.cwd=a),t.set(r,i)}import{promises as Es}from"fs";import{join as Hx}from"path";function Oe(t){return typeof t=="number"?{chatId:t}:t}var Dr=class{sessions=new Map;pendingSessions=new Map;sessionData=new Map;sessionStats=new Map;autosaveFailureLogged=new Set;pendingResume=new Map;options;constructor(e){this.options={dataDir:e.dataDir||"./data/telegram-sessions",defaultModel:e.defaultModel||"medium",apiKey:e.apiKey,settingSources:e.settingSources,thinking:e.thinking,effort:e.effort,botCwd:e.botCwd,createSession:e.createSession,registry:e.registry,onResumptionOffer:e.onResumptionOffer}}getSessionIfExists(e){return this.sessions.get(j(Oe(e)))}async getSession(e){let n=Oe(e),r=j(n),o=this.sessions.get(r);if(o)return this._touchActivity(r),o;let s=this.pendingSessions.get(r);if(s)try{return await s}finally{this._touchActivity(r)}let i=this.sessionData.get(r)??this._newData(n),a=(async()=>{let c={model:i.model,apiKey:this.options.apiKey,telegramChatId:n.chatId,...n.threadId!==void 0?{telegramThreadId:n.threadId}:{}};this.options.settingSources?.length&&(c.settingSources=this.options.settingSources),this.options.thinking!==void 0&&(c.thinking=this.options.thinking),this.options.effort!==void 0&&(c.effort=this.options.effort);let l=i.cwd??this.options.botCwd;l!==void 0&&l.length>0&&(c.cwd=l);let d=this.pendingResume.get(r);if(d!==void 0){let p=ft(d);Object.assign(c,Nx({id:d,resumeId:p?.sessionId??d,stored:p}))}let u=await this.options.createSession(Kf(cp(c)));this.sessions.set(r,u),this.sessionData.set(r,i);try{this._ensureRegistryHandle(n,i)}catch{}return u.sessionId&&(Gf(u.sessionId,n),i.sessionId=u.sessionId),this.options.onResumptionOffer&&Ix(u.sessionId??"",n,this.options.onResumptionOffer),d!==void 0&&this.pendingResume.delete(r),u})();this.pendingSessions.set(r,a);try{let c=await a;return this._touchActivity(r),c}finally{this.pendingSessions.delete(r)}}_newData(e){let n={chatId:e.chatId,model:this.options.defaultModel,createdAt:new Date().toISOString(),lastActivity:new Date().toISOString()};return e.threadId!==void 0&&(n.threadId=e.threadId),n}_touchActivity(e){let n=this.sessionData.get(e);n&&(n.lastActivity=new Date().toISOString())}_ensureRegistryHandle(e,n){$x(this.options.registry??ll,e,n,this.options.defaultModel)}recordTelegramTurn(e,n,r,o){let s=Oe(e),i=j(s),a=this._getOrCreateStats(s),c=this.sessions.get(i);!a.sessionId&&c?.sessionId&&(a.sessionId=c.sessionId),Px(a,n,r,o),!a.sessionId&&c?.sessionId&&(a.sessionId=c.sessionId);let l=this.sessionData.get(i);if(l&&a.sessionId&&(l.sessionId=a.sessionId),a.sessionId&&Gf(a.sessionId,s),a.sessionId)try{Jf(a)}catch(d){this.autosaveFailureLogged.has(i)||(this.autosaveFailureLogged.add(i),console.error(`[session-manager] autosave failed for chat ${s.chatId} \u2014 conversation may not be resumable:`,d))}}_hydrateStatsFromStore(e){jx(this.sessionStats,this.sessionData,e)}getSessionName(e){let n=Oe(e);return this._hydrateStatsFromStore(n),this.sessionStats.get(j(n))?.name}setSessionName(e,n){let r=Oe(e),o=j(r),s=this._getOrCreateStats(r);s.name=n;let i=this.sessions.get(o);if(!s.sessionId&&i?.sessionId&&(s.sessionId=i.sessionId),s.totalTurns>0&&s.sessionId){let a=this.sessionData.get(o);return a&&(a.sessionId=s.sessionId),Jf(s),{persisted:!0}}return{persisted:!1}}_getOrCreateStats(e){let n=j(e);this._hydrateStatsFromStore(e);let r=this.sessionStats.get(n);if(!r){r=Cx(this.getModel(e)),r.source="telegram",r.telegramChatId=e.chatId;let o=this.getCwd(e);o&&(r.cwd=o),this.sessionStats.set(n,r)}return r}_resetStats(e){let n=this.sessionStats.get(e)?.sessionId??this.sessionData.get(e)?.sessionId;n&&Rx(n),this.sessionStats.delete(e),this.autosaveFailureLogged.delete(e),this.pendingResume.delete(e);let r=this.sessionData.get(e);r&&delete r.sessionId}async resetSession(e){let n=Oe(e),r=j(n);try{Yf(this.options.registry??ll,r)}catch{}let o=this.sessions.get(r);o&&(await o.close(),this.sessions.delete(r)),this._resetStats(r);let s=this.sessionData.get(r);s&&(s.lastActivity=new Date().toISOString())}async switchModel(e,n){let r=Oe(e),o=j(r);try{Yf(this.options.registry??ll,o)}catch{}let s=this.sessions.get(o);s&&(await s.close(),this.sessions.delete(o)),this._resetStats(o);let i=this.sessionData.get(o);i?(i.model=n,i.lastActivity=new Date().toISOString()):(i=this._newData(r),i.model=n,this.sessionData.set(o,i));try{this._ensureRegistryHandle(r,i)}catch{}}getModel(e){return this.sessionData.get(j(Oe(e)))?.model||this.options.defaultModel}async setCwd(e,n){let r=Oe(e),o=j(r),s=this.sessions.get(o);s&&(await s.close(),this.sessions.delete(o)),this._resetStats(o);let i=this.sessionData.get(o);i?(i.cwd=n,i.lastActivity=new Date().toISOString()):(i=this._newData(r),i.cwd=n,this.sessionData.set(o,i))}getCwd(e){return this.sessionData.get(j(Oe(e)))?.cwd??this.options.botCwd}listChatSessions(e){let n=Oe(e),r=this.sessionData.get(j(n))?.sessionId;return Or().filter(o=>o.source==="telegram"&&o.telegramChatId===n.chatId&&o.sessionId!==void 0).map(o=>{let s={sessionId:o.sessionId,model:o.model,turns:o.totalTurns,lastActive:o.savedAt,active:o.sessionId===r};return o.name!==void 0&&(s.name=o.name),s}).sort((o,s)=>s.lastActive-o.lastActive)}async switchToSession(e,n){let r=Oe(e),o=j(r),s=this.pendingSessions.get(o);if(s!==void 0&&await s.catch(()=>{}),this.sessions.has(o)&&this.sessionData.get(o)?.sessionId===n)return{ok:!1,reason:"already-active"};let i=ft(n);if(!i||i.source!=="telegram"||i.telegramChatId!==r.chatId)return{ok:!1,reason:"not-found"};let a=this.sessions.get(o);a&&(await a.close().catch(l=>console.error("Error closing session on switch:",l)),this.sessions.delete(o)),this.sessionStats.delete(o),this.autosaveFailureLogged.delete(o);let c=this.sessionData.get(o);return c?(c.model=i.model,c.lastActivity=new Date().toISOString()):(c=this._newData(r),c.model=i.model,this.sessionData.set(o,c)),c.sessionId=n,i.cwd!==void 0?c.cwd=i.cwd:delete c.cwd,this.pendingResume.set(o,n),i.name!==void 0?{ok:!0,name:i.name}:{ok:!0}}async newSession(e){this.pendingResume.delete(j(Oe(e))),await this.resetSession(e)}sidecarFileName(e){let n={chatId:e.chatId};return e.threadId!==void 0&&(n.threadId=e.threadId),`${j(n)}.json`}async loadSessions(){try{await Es.mkdir(this.options.dataDir,{recursive:!0});let e=await Es.readdir(this.options.dataDir);for(let n of e)if(n.endsWith(".json")){let r=Hx(this.options.dataDir,n),o=await Es.readFile(r,"utf-8"),s=JSON.parse(o),i={chatId:s.chatId};s.threadId!==void 0&&(i.threadId=s.threadId),this.sessionData.set(j(i),s);try{this._ensureRegistryHandle(i,s)}catch{}}}catch(e){e.code!=="ENOENT"&&console.error("Failed to load sessions:",e)}}async saveSessions(){try{await Es.mkdir(this.options.dataDir,{recursive:!0});for(let e of this.sessionData.values()){let n=Hx(this.options.dataDir,this.sidecarFileName(e));await Es.writeFile(n,JSON.stringify(e,null,2))}}catch(e){console.error("Failed to save sessions:",e)}}_evictStaleSessionData(e=1440*60*1e3){let n=Date.now();for(let[r,o]of this.sessionData){if(this.sessions.has(r))continue;n-new Date(o.lastActivity).getTime()>e&&this.sessionData.delete(r)}}async closeAll(){this._evictStaleSessionData(),await this.saveSessions(),await Promise.all(Array.from(this.sessions.values()).map(e=>e.close().catch(n=>console.error("Error closing session:",n)))),this.sessions.clear()}getSessionCount(){return this.sessions.size}getChatCount(){return this.sessionData.size}getActiveThreadId(e){let n;for(let r of this.sessionData.values())r.chatId!==e||r.threadId===void 0||(n===void 0||r.lastActivity>n.lastActivity)&&(n=r);return n?.threadId}getBusySessionCount(){let e=0;for(let n of this.sessions.values())n.state!=="idle"&&n.state!=="closed"&&e++;return e}getActiveRouteForChat(e){return Bx(this.sessionData.values(),e)}};async function Qf(t){await t.reply(tu())}async function Zf(t,e){let n=V(t),r,o=n?e.getSessionIfExists(n):void 0;if(o)try{await Promise.race([o.waitForInitialization(),new Promise((i,a)=>setTimeout(()=>a(new Error("timeout")),2e3))]);let s=o.getSessionMetadata();s.slashCommands?.length&&(r=s.slashCommands)}catch{}await t.reply(ab(r))}import{Markup as zx}from"telegraf";import{promises as k2}from"fs";import{homedir as Jx}from"os";import{isAbsolute as v2,resolve as em}from"path";async function As(t,e){t.sendChatAction("typing").catch(()=>{});let n=setInterval(()=>{t.sendChatAction("typing").catch(()=>{})},4e3);try{return await e()}finally{clearInterval(n)}}function w2(t,e){try{if(!t||t.trim().toLowerCase()==="auto")return{available:!0,needs:"unknown"};let n=ln(t,e);if(n.id==="")return{available:!1,needs:"local",hint:"not configured (set AFK_MODEL_LOCAL / models.local)"};if(n.provider==="chatgpt-oauth"){let o=Vt(void 0,{},!0),s=o.apiKey!=null,i=s?void 0:o.source==="chatgpt-oauth-expired"?"ChatGPT token expired \u2014 re-run `codex` to refresh":"needs ChatGPT sign-in (~/.codex/auth.json)";return{available:s,needs:"chatgpt-oauth",hint:i}}if(n.provider==="xai-oauth"){let o=pt(void 0,"oauth").apiKey!=null;return{available:o,needs:"xai-oauth",hint:o?void 0:"needs SuperGrok OAuth (`afk provider auth xai login`)"}}if(n.provider==="xai"){let o=pt(n.apiKey,"apikey").apiKey!=null;return{available:o,needs:"xai",hint:o?void 0:"needs XAI_API_KEY"}}if(n.apiKey)return{available:!0,needs:"unknown"};let r=z(t,e?{slots:e}:void 0);if(r==="anthropic-direct"){let o=!!ji();return{available:o,needs:"anthropic",hint:o?void 0:"needs Claude sign-in / ANTHROPIC_API_KEY"}}if(r==="openai-compatible"){if(n.baseUrl)return{available:!0,needs:"local"};let o=!!Xd()||Vt(void 0,{},!1).apiKey!=null;return{available:o,needs:"openai",hint:o?void 0:"needs OPENAI_API_KEY"}}if(r==="xai"||r==="xai-oauth"){let i=pt(void 0,r==="xai-oauth"?"oauth":void 0).apiKey!=null;return{available:i,needs:r==="xai-oauth"?"xai-oauth":"xai",hint:i?void 0:"needs XAI_API_KEY or SuperGrok OAuth (`afk provider auth xai login`)"}}return{available:!0,needs:"unknown"}}catch{return{available:!0,needs:"unknown"}}}function Wx(t,e){return w2(t,e).available}var S2=/^[A-Za-z0-9_@%+=:,./-]+$/;function Kx(t){return S2.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}function qx(t,e){let n=["afk","interactive"];return typeof e=="string"&&e.length>0&&n.push("--model",Kx(e)),n.push("--resume",Kx(t)),n.join(" ")}function Gx(t){if(cn.includes(t)||Bn(t)!==void 0)return!0;let e=z(t);if(e==="openai-compatible"||e==="xai"||e==="xai-oauth")return!0;let n=ln(t).id.trim().toLowerCase();return n.startsWith("claude-")||n.startsWith("claude_")}function Xx(t){return Gx(t)}async function tm(t,e,n,r){let o=V(t);if(!o){await t.reply($("Could not identify chat"));return}try{await e.resetSession(o),n.delete(o.chatId),await t.reply(Co())}catch(s){r("Clear error:",s),await t.reply($(s))}}async function Vx(t,e,n){let r=V(t);if(!r){await t.reply($("Could not identify chat"));return}try{let o=await e.getSession(r),s=o.hookRegistry,i=await As(t,async()=>(s&&await s.dispatch({event:"PreCompact",sessionId:o.sessionId,trigger:"manual"}),o.compact()));i.compacted?await t.reply(Po({before:i.messagesBefore,after:i.messagesAfter,...i.tokensSavedEstimate!==void 0?{tokensSavedEstimate:i.tokensSavedEstimate}:{}})):await t.reply(Mo(i.reason??"unknown"))}catch(o){o instanceof q?await t.reply(`Compaction skipped: ${Ce(o.reason??"blocked by hook")}`):(n("Compact error:",o),await t.reply($(o)))}}async function nm(t,e,n){let r=V(t);if(!r){await t.reply($("Could not identify chat"));return}let s=t.message.text.split(/\s+/).slice(1);if(s.length===0){let l=e.getModel(r),d=cn.map(u=>[zx.button.callback(Wx(u)?u:`${u} \u2014 needs sign-in`,`afk:m:${u}`)]);await t.reply(`Current model: <b>${Ce(l.toUpperCase())}</b>
|
|
1294
|
+
${o}`}}}return{...t,systemPrompt:o}}var qf=new Map;function Gf(t,e){qf.set(t,e)}function al(t){return qf.get(t)}function Rx(t){qf.delete(t)}function Ix(t,e,n){ox(!0)&&Promise.resolve().then(async()=>{try{let r=nx({sessionId:t});for(let o of r.offers)await Promise.resolve(n(e,rx(o)))!==!1&&sx(o.manifest)}catch{}})}function cl(t){let e=t.toLowerCase().replace(/[`*_~]/g," ").replace(/[^\w\s-]/g," ").replace(/[\s_]+/g," ").trim();return e?e.split(" ").filter(Boolean).slice(0,6).join("-").slice(0,48).replace(/-+$/g,""):""}function Cx(t){return{totalTurns:0,totalCostUsd:0,unpricedTurns:0,totalTokens:0,totalDurationMs:0,sessionStartTime:Date.now(),turnCosts:[],turnTokens:[],turns:[],model:t,permissionMode:"default",thinkingUi:"live"}}function Px(t,e,n,r,o){let s=r?.totalCostUsd,i=s??0,a=r?.durationMs??0,c=Number(r?.usage?.input_tokens??0),l=Number(r?.usage?.output_tokens??0),d=c,u=l,p=Number(r?.usage?.cache_read_input_tokens??0)+Number(r?.usage?.cache_creation_input_tokens??0),f=r?.usage?.iterations;if(Array.isArray(f)&&f.length>0){let w=f[f.length-1];if(w&&typeof w=="object"){let k=w;d=Number(k.input_tokens??0),u=Number(k.output_tokens??0),p=Number(k.cache_read_input_tokens??0)+Number(k.cache_creation_input_tokens??0)}}t.totalTurns+=1,t.totalCostUsd+=i,s===void 0&&(t.unpricedTurns+=1),t.totalDurationMs+=a,t.totalTokens+=c+l,t.turnCosts.push(i);let m=Number(r?.usage?.context_window_tokens??NaN),g=Array.isArray(f)&&f.length>0,h=Number.isFinite(m)?m:g?d+u+p:void 0;if(t.turnTokens.push({input:d,output:u,cache:p,...h!==void 0?{footprint:h}:{}}),r?.sessionId&&!t.sessionId&&(t.sessionId=String(r.sessionId)),!t.name){let w=cl(e);w&&(t.name=w)}let y={user:e,assistant:n,timestamp:Date.now(),costUsd:i,durationMs:a,inputTokens:c,outputTokens:l,...o&&o.length>0?{toolEvents:o}:{}};return t.turns.push(y),y}import{readFileSync as u2,writeFileSync as p2,existsSync as dl,mkdirSync as f2,readdirSync as m2,statSync as g2,realpathSync as Mx}from"fs";import{join as Dx,basename as Fx,resolve as Ox,sep as h2}from"path";P();import{randomUUID as l2}from"node:crypto";var Ts=class extends Error{constructor(e){super(e),this.name="SessionRegistryError"}},Xf=class{byId=new Map;byBinding=new Map;bySdk=new Map;now;constructor(e){this.now=e?.now??Date.now}create(e){let n=this.now(),r=e.id??l2();if(this.byId.has(r))throw new Ts(`session handle already exists: ${r}`);let o={surface:e.surface,key:e.key,boundAt:n,lastActiveAt:n},s={id:r,surface:e.surface,model:e.model,createdAt:e.createdAt??n,lastActiveAt:n,status:"active",bindings:[o]};return e.name!==void 0&&(s.name=e.name),e.cwd!==void 0&&(s.cwd=e.cwd),e.sdkSessionId!==void 0&&(s.sdkSessionId=e.sdkSessionId),this.byId.set(r,s),this.pointBinding(this.bindingKey(o.surface,o.key),r),s.sdkSessionId!==void 0&&this.bySdk.set(s.sdkSessionId,r),this.clone(s)}load(e){if(this.byId.has(e.id))throw new Ts(`session handle already exists: ${e.id}`);let n=this.clone(e);if(this.byId.set(n.id,n),n.status==="active")for(let r of n.bindings)this.pointBinding(this.bindingKey(r.surface,r.key),n.id);n.sdkSessionId!==void 0&&this.bySdk.set(n.sdkSessionId,n.id)}get(e){let n=this.byId.get(e);return n?this.clone(n):void 0}getBySdkSessionId(e){let n=this.bySdk.get(e);if(n===void 0)return;let r=this.byId.get(n);return r?this.clone(r):void 0}resolve(e,n){let r=this.byBinding.get(this.bindingKey(e,n));if(r===void 0)return;let o=this.byId.get(r);if(!(!o||o.status!=="active"))return this.clone(o)}bind(e,n){let r=this.require(e),o=this.now(),s=this.bindingKey(n.surface,n.key),i=r.bindings.find(a=>this.bindingKey(a.surface,a.key)===s);i?i.lastActiveAt=o:r.bindings.push({surface:n.surface,key:n.key,boundAt:o,lastActiveAt:o}),this.pointBinding(s,e),r.lastActiveAt=o}unbind(e,n){let r=this.bindingKey(e,n),o=this.byBinding.get(r);if(this.byBinding.delete(r),o===void 0)return;let s=this.byId.get(o);s&&(s.bindings=s.bindings.filter(i=>this.bindingKey(i.surface,i.key)!==r))}attachSdkSessionId(e,n){let r=this.require(e);r.sdkSessionId!==void 0&&r.sdkSessionId!==n&&this.bySdk.get(r.sdkSessionId)===e&&this.bySdk.delete(r.sdkSessionId),r.sdkSessionId=n,this.bySdk.set(n,e),r.lastActiveAt=this.now()}rename(e,n){let r=this.require(e);r.name=n,r.lastActiveAt=this.now()}touch(e){let n=this.require(e);n.lastActiveAt=this.now()}archive(e){let n=this.require(e);n.status="archived",n.lastActiveAt=this.now();for(let r of n.bindings){let o=this.bindingKey(r.surface,r.key);this.byBinding.get(o)===e&&this.byBinding.delete(o)}}list(e){let n=[];for(let r of this.byId.values())e?.surface!==void 0&&r.surface!==e.surface||e?.status!==void 0&&r.status!==e.status||n.push(this.clone(r));return n.sort((r,o)=>o.lastActiveAt-r.lastActiveAt),n}bindingKey(e,n){return`${e}\0${n}`}require(e){let n=this.byId.get(e);if(!n)throw new Ts(`unknown session handle: ${e}`);return n}pointBinding(e,n){let r=this.byBinding.get(e);if(r!==void 0&&r!==n){let o=this.byId.get(r);o&&(o.bindings=o.bindings.filter(s=>this.bindingKey(s.surface,s.key)!==e))}this.byBinding.set(e,n)}clone(e){return{...e,bindings:e.bindings.map(n=>({...n}))}}};var ll=new Xf;function _s(){return Nm(),oe()}function y2(t){return Dx(_s(),`${t}.json`)}function zf(t,{write:e=!1}={}){let n=t.includes("/")?t:y2(t),r,o;if(!e&&dl(n)?(r=Mx(n),o=Mx(_s())):(r=Ox(n),o=Ox(_s())),!r.startsWith(o+h2)&&r!==o)throw new Error(`Session path escapes sessions directory: ${t}`);return r}function Jf(t,e){let n=_s();dl(n)||f2(n,{recursive:!0});let r=e??t.sessionId??`session-${Date.now()}`,o={sessionId:t.sessionId,...t.name?{name:t.name}:{},...t.source?{source:t.source}:{},...t.actor?{actor:t.actor}:{},...t.telegramChatId!==void 0?{telegramChatId:t.telegramChatId}:{},...t.cwd?{cwd:t.cwd}:{},model:t.model,startedAt:t.sessionStartTime,savedAt:Date.now(),totalTurns:t.totalTurns,totalCostUsd:t.totalCostUsd,unpricedTurns:t.unpricedTurns,totalTokens:t.totalTokens,totalDurationMs:t.totalDurationMs,turns:t.turns},s=zf(r,{write:!0});return p2(s,JSON.stringify(o,null,2)),s}function ft(t){let e;try{e=zf(t)}catch(n){console.warn(`loadSession: rejected unsafe session id ${JSON.stringify(t)}: ${n.message}`);return}if(dl(e))try{let n=u2(e,"utf-8");return JSON.parse(n)}catch(n){console.warn(`loadSession: failed to read/parse ${e}: ${n.message}`);return}}function Vf(t){let e;try{e=zf(t)}catch{return}let n=ft(e);if(n)return{path:e,id:Fx(e,".json"),data:n};let r=Or();for(let s of r){if(s.id!==t&&s.sessionId!==t&&s.name!==t)continue;let i=ft(s.path);if(i)return{path:s.path,id:s.id,data:i}}if(t.length>=3){let s=r.filter(i=>i.name!==void 0&&i.name.startsWith(t));if(s.length===1){let i=s[0];if(i){let a=ft(i.path);if(a)return{path:i.path,id:i.id,data:a}}}}}function Or(){let t=_s();if(!dl(t))return[];let e=[];for(let n of m2(t)){if(!n.endsWith(".json"))continue;let r=Dx(t,n);try{if(!g2(r).isFile())continue;let s=ft(r);if(!s||typeof s.savedAt!="number"||typeof s.model!="string")continue;e.push({path:r,id:Fx(n,".json"),sessionId:s.sessionId,name:s.name,source:s.source,actor:s.actor,telegramChatId:s.telegramChatId,model:s.model,startedAt:s.startedAt,savedAt:s.savedAt,totalTurns:s.totalTurns,totalCostUsd:s.totalCostUsd,cwd:s.cwd})}catch{}}return e.sort((n,r)=>r.savedAt-n.savedAt),e}function b2(t){let e=new Map,n=[];for(let r of t)r.toolUseId===void 0?n.push(r):e.set(r.toolUseId,r);return[...e.values(),...n]}function Lx(t){return!t||t.length===0?"":`
|
|
1295
|
+
[Tools used: ${b2(t).map(r=>{let o=r.isError?"\u2717":"\u2713",s=r.input||r.inputRaw||"",i=s.length>80?s.slice(0,77)+"\u2026":s;return`${r.toolName}(${i})${o}`}).join(", ")}]`}function Nx(t){return t?{resume:t.resumeId,sessionId:t.resumeId,...t.stored?{resumeHistory:t.stored.turns.map((e,n,r)=>{let o={user:e.user,assistant:(e.assistant??"")+Lx(e.toolEvents)};return n===r.length-1&&e.inputTokens!==void 0&&(o.inputTokens=e.inputTokens),o})}:{}}:{}}function w2(t){if(t===null||typeof t!="object")return{};let e=t,n=e.message_thread_id,r=e.is_topic_message;return{...typeof n=="number"?{threadId:n}:{},...r===!0?{isTopic:!0}:{}}}function V(t){let e=t.chat?.id;if(typeof e!="number")return;let n=t.message??t.editedMessage??t.callbackQuery?.message,{threadId:r,isTopic:o}=w2(n),s={chatId:e};return r!==void 0&&r!==0&&(s.threadId=r),o&&(s.isTopicMessage=!0),s}function Ux(t){return t.threadId===void 0||t.threadId===0||t.threadId===1}function j(t){return Ux(t)?String(t.chatId):`${t.chatId}:${t.threadId}`}function tn(t){return Ux(t)?{}:{message_thread_id:t.threadId}}function $x(t,e,n,r){let o=j(e),s=o,i=t.resolve("telegram",o);if(i){t.touch(i.id),n.sessionId&&t.attachSdkSessionId(i.id,n.sessionId);return}let a=t.get(s);if(a&&a.status==="active"){t.bind(s,{surface:"telegram",key:o}),n.sessionId&&t.attachSdkSessionId(s,n.sessionId);return}let c=a===void 0?s:void 0;t.create({surface:"telegram",key:o,model:n.model??r,id:c,sdkSessionId:n.sessionId})}function Yf(t,e){t.archive(e)}function Bx(t,e){let n;for(let o of t)o.chatId===e&&(!n||o.lastActivity>n.lastActivity)&&(n=o);if(!n)return;let r={chatId:n.chatId};return n.threadId!==void 0&&(r.threadId=n.threadId),r}function jx(t,e,n){let r=j(n);if(t.has(r))return;let o=e.get(r)?.sessionId;if(!o)return;let s=ft(o);if(!s||s.source!=="telegram"||s.telegramChatId!==n.chatId)return;let i={sessionId:s.sessionId,name:s.name,model:s.model,source:s.source,telegramChatId:s.telegramChatId,sessionStartTime:s.startedAt,totalTurns:s.totalTurns,totalCostUsd:s.totalCostUsd,unpricedTurns:s.unpricedTurns??0,totalTokens:s.totalTokens,totalDurationMs:s.totalDurationMs,turns:s.turns,turnCosts:[],turnTokens:[],permissionMode:"default"},a=e.get(r)?.cwd;a!==void 0&&(i.cwd=a),t.set(r,i)}import{promises as Es}from"fs";import{join as Hx}from"path";function Oe(t){return typeof t=="number"?{chatId:t}:t}var Dr=class{sessions=new Map;pendingSessions=new Map;sessionData=new Map;sessionStats=new Map;autosaveFailureLogged=new Set;pendingResume=new Map;options;constructor(e){this.options={dataDir:e.dataDir||"./data/telegram-sessions",defaultModel:e.defaultModel||"medium",apiKey:e.apiKey,settingSources:e.settingSources,thinking:e.thinking,effort:e.effort,botCwd:e.botCwd,createSession:e.createSession,registry:e.registry,onResumptionOffer:e.onResumptionOffer}}getSessionIfExists(e){return this.sessions.get(j(Oe(e)))}async getSession(e){let n=Oe(e),r=j(n),o=this.sessions.get(r);if(o)return this._touchActivity(r),o;let s=this.pendingSessions.get(r);if(s)try{return await s}finally{this._touchActivity(r)}let i=this.sessionData.get(r)??this._newData(n),a=(async()=>{let c={model:i.model,apiKey:this.options.apiKey,telegramChatId:n.chatId,...n.threadId!==void 0?{telegramThreadId:n.threadId}:{}};this.options.settingSources?.length&&(c.settingSources=this.options.settingSources),this.options.thinking!==void 0&&(c.thinking=this.options.thinking),this.options.effort!==void 0&&(c.effort=this.options.effort);let l=i.cwd??this.options.botCwd;l!==void 0&&l.length>0&&(c.cwd=l);let d=this.pendingResume.get(r);if(d!==void 0){let p=ft(d);Object.assign(c,Nx({id:d,resumeId:p?.sessionId??d,stored:p}))}let u=await this.options.createSession(Kf(cp(c)));this.sessions.set(r,u),this.sessionData.set(r,i);try{this._ensureRegistryHandle(n,i)}catch{}return u.sessionId&&(Gf(u.sessionId,n),i.sessionId=u.sessionId),this.options.onResumptionOffer&&Ix(u.sessionId??"",n,this.options.onResumptionOffer),d!==void 0&&this.pendingResume.delete(r),u})();this.pendingSessions.set(r,a);try{let c=await a;return this._touchActivity(r),c}finally{this.pendingSessions.delete(r)}}_newData(e){let n={chatId:e.chatId,model:this.options.defaultModel,createdAt:new Date().toISOString(),lastActivity:new Date().toISOString()};return e.threadId!==void 0&&(n.threadId=e.threadId),n}_touchActivity(e){let n=this.sessionData.get(e);n&&(n.lastActivity=new Date().toISOString())}_ensureRegistryHandle(e,n){$x(this.options.registry??ll,e,n,this.options.defaultModel)}recordTelegramTurn(e,n,r,o){let s=Oe(e),i=j(s),a=this._getOrCreateStats(s),c=this.sessions.get(i);!a.sessionId&&c?.sessionId&&(a.sessionId=c.sessionId),Px(a,n,r,o),!a.sessionId&&c?.sessionId&&(a.sessionId=c.sessionId);let l=this.sessionData.get(i);if(l&&a.sessionId&&(l.sessionId=a.sessionId),a.sessionId&&Gf(a.sessionId,s),a.sessionId)try{Jf(a)}catch(d){this.autosaveFailureLogged.has(i)||(this.autosaveFailureLogged.add(i),console.error(`[session-manager] autosave failed for chat ${s.chatId} \u2014 conversation may not be resumable:`,d))}}_hydrateStatsFromStore(e){jx(this.sessionStats,this.sessionData,e)}getSessionName(e){let n=Oe(e);return this._hydrateStatsFromStore(n),this.sessionStats.get(j(n))?.name}setSessionName(e,n){let r=Oe(e),o=j(r),s=this._getOrCreateStats(r);s.name=n;let i=this.sessions.get(o);if(!s.sessionId&&i?.sessionId&&(s.sessionId=i.sessionId),s.totalTurns>0&&s.sessionId){let a=this.sessionData.get(o);return a&&(a.sessionId=s.sessionId),Jf(s),{persisted:!0}}return{persisted:!1}}_getOrCreateStats(e){let n=j(e);this._hydrateStatsFromStore(e);let r=this.sessionStats.get(n);if(!r){r=Cx(this.getModel(e)),r.source="telegram",r.telegramChatId=e.chatId;let o=this.getCwd(e);o&&(r.cwd=o),this.sessionStats.set(n,r)}return r}_resetStats(e){let n=this.sessionStats.get(e)?.sessionId??this.sessionData.get(e)?.sessionId;n&&Rx(n),this.sessionStats.delete(e),this.autosaveFailureLogged.delete(e),this.pendingResume.delete(e);let r=this.sessionData.get(e);r&&delete r.sessionId}async resetSession(e){let n=Oe(e),r=j(n);try{Yf(this.options.registry??ll,r)}catch{}let o=this.sessions.get(r);o&&(await o.close(),this.sessions.delete(r)),this._resetStats(r);let s=this.sessionData.get(r);s&&(s.lastActivity=new Date().toISOString())}async switchModel(e,n){let r=Oe(e),o=j(r);try{Yf(this.options.registry??ll,o)}catch{}let s=this.sessions.get(o);s&&(await s.close(),this.sessions.delete(o)),this._resetStats(o);let i=this.sessionData.get(o);i?(i.model=n,i.lastActivity=new Date().toISOString()):(i=this._newData(r),i.model=n,this.sessionData.set(o,i));try{this._ensureRegistryHandle(r,i)}catch{}}getModel(e){return this.sessionData.get(j(Oe(e)))?.model||this.options.defaultModel}async setCwd(e,n){let r=Oe(e),o=j(r),s=this.sessions.get(o);s&&(await s.close(),this.sessions.delete(o)),this._resetStats(o);let i=this.sessionData.get(o);i?(i.cwd=n,i.lastActivity=new Date().toISOString()):(i=this._newData(r),i.cwd=n,this.sessionData.set(o,i))}getCwd(e){return this.sessionData.get(j(Oe(e)))?.cwd??this.options.botCwd}listChatSessions(e){let n=Oe(e),r=this.sessionData.get(j(n))?.sessionId;return Or().filter(o=>o.source==="telegram"&&o.telegramChatId===n.chatId&&o.sessionId!==void 0).map(o=>{let s={sessionId:o.sessionId,model:o.model,turns:o.totalTurns,lastActive:o.savedAt,active:o.sessionId===r};return o.name!==void 0&&(s.name=o.name),s}).sort((o,s)=>s.lastActive-o.lastActive)}async switchToSession(e,n){let r=Oe(e),o=j(r),s=this.pendingSessions.get(o);if(s!==void 0&&await s.catch(()=>{}),this.sessions.has(o)&&this.sessionData.get(o)?.sessionId===n)return{ok:!1,reason:"already-active"};let i=ft(n);if(!i||i.source!=="telegram"||i.telegramChatId!==r.chatId)return{ok:!1,reason:"not-found"};let a=this.sessions.get(o);a&&(await a.close().catch(l=>console.error("Error closing session on switch:",l)),this.sessions.delete(o)),this.sessionStats.delete(o),this.autosaveFailureLogged.delete(o);let c=this.sessionData.get(o);return c?(c.model=i.model,c.lastActivity=new Date().toISOString()):(c=this._newData(r),c.model=i.model,this.sessionData.set(o,c)),c.sessionId=n,i.cwd!==void 0?c.cwd=i.cwd:delete c.cwd,this.pendingResume.set(o,n),i.name!==void 0?{ok:!0,name:i.name}:{ok:!0}}async newSession(e){this.pendingResume.delete(j(Oe(e))),await this.resetSession(e)}sidecarFileName(e){let n={chatId:e.chatId};return e.threadId!==void 0&&(n.threadId=e.threadId),`${j(n)}.json`}async loadSessions(){try{await Es.mkdir(this.options.dataDir,{recursive:!0});let e=await Es.readdir(this.options.dataDir);for(let n of e)if(n.endsWith(".json")){let r=Hx(this.options.dataDir,n),o=await Es.readFile(r,"utf-8"),s=JSON.parse(o),i={chatId:s.chatId};s.threadId!==void 0&&(i.threadId=s.threadId),this.sessionData.set(j(i),s);try{this._ensureRegistryHandle(i,s)}catch{}}}catch(e){e.code!=="ENOENT"&&console.error("Failed to load sessions:",e)}}async saveSessions(){try{await Es.mkdir(this.options.dataDir,{recursive:!0});for(let e of this.sessionData.values()){let n=Hx(this.options.dataDir,this.sidecarFileName(e));await Es.writeFile(n,JSON.stringify(e,null,2))}}catch(e){console.error("Failed to save sessions:",e)}}_evictStaleSessionData(e=1440*60*1e3){let n=Date.now();for(let[r,o]of this.sessionData){if(this.sessions.has(r))continue;n-new Date(o.lastActivity).getTime()>e&&this.sessionData.delete(r)}}async closeAll(){this._evictStaleSessionData(),await this.saveSessions(),await Promise.all(Array.from(this.sessions.values()).map(e=>e.close().catch(n=>console.error("Error closing session:",n)))),this.sessions.clear()}getSessionCount(){return this.sessions.size}getChatCount(){return this.sessionData.size}getActiveThreadId(e){let n;for(let r of this.sessionData.values())r.chatId!==e||r.threadId===void 0||(n===void 0||r.lastActivity>n.lastActivity)&&(n=r);return n?.threadId}getBusySessionCount(){let e=0;for(let n of this.sessions.values())n.state!=="idle"&&n.state!=="closed"&&e++;return e}getActiveRouteForChat(e){return Bx(this.sessionData.values(),e)}};async function Qf(t){await t.reply(tu())}async function Zf(t,e){let n=V(t),r,o=n?e.getSessionIfExists(n):void 0;if(o)try{await Promise.race([o.waitForInitialization(),new Promise((i,a)=>setTimeout(()=>a(new Error("timeout")),2e3))]);let s=o.getSessionMetadata();s.slashCommands?.length&&(r=s.slashCommands)}catch{}await t.reply(ab(r))}import{Markup as zx}from"telegraf";import{promises as v2}from"fs";import{homedir as Jx}from"os";import{isAbsolute as T2,resolve as em}from"path";async function As(t,e){t.sendChatAction("typing").catch(()=>{});let n=setInterval(()=>{t.sendChatAction("typing").catch(()=>{})},4e3);try{return await e()}finally{clearInterval(n)}}function S2(t,e){try{if(!t||t.trim().toLowerCase()==="auto")return{available:!0,needs:"unknown"};let n=ln(t,e);if(n.id==="")return{available:!1,needs:"local",hint:"not configured (set AFK_MODEL_LOCAL / models.local)"};if(n.provider==="chatgpt-oauth"){let o=Vt(void 0,{},!0),s=o.apiKey!=null,i=s?void 0:o.source==="chatgpt-oauth-expired"?"ChatGPT token expired \u2014 re-run `codex` to refresh":"needs ChatGPT sign-in (~/.codex/auth.json)";return{available:s,needs:"chatgpt-oauth",hint:i}}if(n.provider==="xai-oauth"){let o=pt(void 0,"oauth").apiKey!=null;return{available:o,needs:"xai-oauth",hint:o?void 0:"needs SuperGrok OAuth (`afk provider auth xai login`)"}}if(n.provider==="xai"){let o=pt(n.apiKey,"apikey").apiKey!=null;return{available:o,needs:"xai",hint:o?void 0:"needs XAI_API_KEY"}}if(n.apiKey)return{available:!0,needs:"unknown"};let r=z(t,e?{slots:e}:void 0);if(r==="anthropic-direct"){let o=!!ji();return{available:o,needs:"anthropic",hint:o?void 0:"needs Claude sign-in / ANTHROPIC_API_KEY"}}if(r==="openai-compatible"){if(n.baseUrl)return{available:!0,needs:"local"};let o=!!Xd()||Vt(void 0,{},!1).apiKey!=null;return{available:o,needs:"openai",hint:o?void 0:"needs OPENAI_API_KEY"}}if(r==="xai"||r==="xai-oauth"){let i=pt(void 0,r==="xai-oauth"?"oauth":void 0).apiKey!=null;return{available:i,needs:r==="xai-oauth"?"xai-oauth":"xai",hint:i?void 0:"needs XAI_API_KEY or SuperGrok OAuth (`afk provider auth xai login`)"}}return{available:!0,needs:"unknown"}}catch{return{available:!0,needs:"unknown"}}}function Wx(t,e){return S2(t,e).available}var k2=/^[A-Za-z0-9_@%+=:,./-]+$/;function Kx(t){return k2.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}function qx(t,e){let n=["afk","interactive"];return typeof e=="string"&&e.length>0&&n.push("--model",Kx(e)),n.push("--resume",Kx(t)),n.join(" ")}function Gx(t){if(cn.includes(t)||Bn(t)!==void 0)return!0;let e=z(t);if(e==="openai-compatible"||e==="xai"||e==="xai-oauth")return!0;let n=ln(t).id.trim().toLowerCase();return n.startsWith("claude-")||n.startsWith("claude_")}function Xx(t){return Gx(t)}async function tm(t,e,n,r){let o=V(t);if(!o){await t.reply($("Could not identify chat"));return}try{await e.resetSession(o),n.delete(o.chatId),await t.reply(Co())}catch(s){r("Clear error:",s),await t.reply($(s))}}async function Vx(t,e,n){let r=V(t);if(!r){await t.reply($("Could not identify chat"));return}try{let o=await e.getSession(r),s=o.hookRegistry,i=await As(t,async()=>(s&&await s.dispatch({event:"PreCompact",sessionId:o.sessionId,trigger:"manual"}),o.compact()));i.compacted?await t.reply(Po({before:i.messagesBefore,after:i.messagesAfter,...i.tokensSavedEstimate!==void 0?{tokensSavedEstimate:i.tokensSavedEstimate}:{}})):await t.reply(Mo(i.reason??"unknown"))}catch(o){o instanceof q?await t.reply(`Compaction skipped: ${Ce(o.reason??"blocked by hook")}`):(n("Compact error:",o),await t.reply($(o)))}}async function nm(t,e,n){let r=V(t);if(!r){await t.reply($("Could not identify chat"));return}let s=t.message.text.split(/\s+/).slice(1);if(s.length===0){let l=e.getModel(r),d=cn.map(u=>[zx.button.callback(Wx(u)?u:`${u} \u2014 needs sign-in`,`afk:m:${u}`)]);await t.reply(`Current model: <b>${Ce(l.toUpperCase())}</b>
|
|
1296
1296
|
|
|
1297
1297
|
Switch to:`,{parse_mode:"HTML",reply_markup:zx.inlineKeyboard(d).reply_markup});return}let i=s[0];if(!i){await t.reply($("Please specify a model: local, small, medium, large, opus, sonnet, haiku, or an org/model id"));return}let a=i.toLowerCase();if(!Xx(a)){await t.reply($(`Invalid model: ${i}
|
|
1298
|
-
Aliases: ${cn.join(", ")}, or a full model id`));return}let c=ig(a);if(c){await t.reply($(c));return}try{await e.switchModel(r,a),await t.reply(Io(a))}catch(l){n("Model switch error:",l),await t.reply($(l))}}function
|
|
1298
|
+
Aliases: ${cn.join(", ")}, or a full model id`));return}let c=ig(a);if(c){await t.reply($(c));return}try{await e.switchModel(r,a),await t.reply(Io(a))}catch(l){n("Model switch error:",l),await t.reply($(l))}}function _2(t,e){let n=t.trim();return n==="~"?Jx():n.startsWith("~/")?em(Jx(),n.slice(2)):T2(n)?em(n):em(e,n)}async function Yx(t,e,n){let r=V(t);if(!r){await t.reply($("Could not identify chat"));return}let s=t.message.text.split(/\s+/).slice(1).filter(l=>l.length>0);if(s.length===0){let l=e.getCwd(r);await t.reply(cb(l));return}let i=s[0];if(!i){await t.reply($("Please specify a directory path"));return}let a=e.getCwd(r)??process.cwd(),c=_2(i,a);try{if(!(await v2.stat(c)).isDirectory()){await t.reply($(`Not a directory: ${c}`));return}}catch(l){let d=l.code;d==="ENOENT"?await t.reply(eu("ENOENT",c)):d==="EACCES"?await t.reply(eu("EACCES",c)):(n("cwd stat error:",l),await t.reply($(l)));return}try{await e.setCwd(r,c),await t.reply(lb(c))}catch(l){n("Cwd switch error:",l),await t.reply($(l))}}async function Qx(t,e,n){let r=V(t);if(!r){await t.reply($("Could not identify chat"));return}let s=t.message.text.split(/\s+/).slice(1).join(" ").trim();if(!s){await t.reply(db(e.getSessionName(r)));return}let i=cl(s);if(!i){await t.reply(ub());return}try{let{persisted:a}=e.setSessionName(r,i),c=a?qx(i,e.getModel(r)):void 0;await t.reply(pb(i,c))}catch(a){n("Name set error:",a),await t.reply(`\u{1F3F7}\uFE0F Named "${i}" but couldn't save it \u2014 it'll retry on your next message.`)}}import{Markup as Zx}from"telegraf";var ul="afk:sw:",E2=64;function A2(t){let e=t.callbackQuery;return typeof e=="object"&&e!==null&&"data"in e?e.data:""}function eR(t,e){let n=t.getSessionIfExists(e);return n!==void 0&&n.state!=="idle"}async function tR(t,e,n){let r=V(t);if(!r){await t.reply($("Could not identify chat"));return}let o=e.listChatSessions(r);if(o.length===0){await t.reply(gb());return}let s=o.filter(i=>(ul+i.sessionId).length<=E2).map(i=>[Zx.button.callback(`${i.active?"\u2705 ":""}${i.name??"(unnamed)"} \xB7 ${i.turns} turns`,`${ul}${i.sessionId}`)]);await t.reply(mb(o),{parse_mode:"HTML",reply_markup:Zx.inlineKeyboard(s).reply_markup})}async function nR(t,e,n,r){let o=V(t);if(!o){await t.reply($("Could not identify chat"));return}if(eR(e,o)){await t.reply(nu());return}try{await e.newSession(o),n.delete(o.chatId),await t.reply(yb())}catch(s){r("New session error:",s),await t.reply($(s))}}async function rR(t,e,n){let r=V(t),o=A2(t),s=o.startsWith(ul)?o.slice(ul.length):"";if(!(!r||!s)){if(eR(e,r)){await t.reply(nu());return}try{let i=await e.switchToSession(r,s);if(!i.ok){await t.reply(i.reason==="already-active"?wb():bb());return}let a=hb(i.name!==void 0?{name:i.name}:{});await t.editMessageText(a,{parse_mode:"HTML"}).catch(()=>t.reply(a,{parse_mode:"HTML"}))}catch(i){n("Switch callback error:",i),await t.reply($(i))}}}var x2="\u25D0 AFK mode ON \u2014 I'll work autonomously on reversible tasks and report here. High-risk / irreversible ops are REFUSED (not one-tap approvable) and surfaced as an Asking summary for you to handle deliberately. Send /afk off to stop.",R2="\u25CB AFK mode OFF \u2014 default permissions restored.";async function oR(t,e,n){let r=V(t);if(!r){await t.reply($("Could not identify chat"));return}let s=(t.message.text??"").split(/\s+/).slice(1).join(" ").trim().toLowerCase();try{let i=await e.getSession(r),a=i.getSessionMetadata().permissionMode==="autonomous",c=s==="on"?!0:s==="off"?!1:!a;if(c===a){await t.reply(c?"\u25D0 AFK mode is already ON.":"\u25CB AFK mode is already OFF.");return}await i.setPermissionMode(c?"autonomous":"default"),await t.reply(c?x2:R2)}catch(i){n("AFK toggle error:",i),await t.reply($("Could not toggle AFK mode"))}}I();var I2="https://api.anthropic.com/api/oauth/usage",C2="oauth-2025-04-20",P2=1e4;async function sR(t){let e=t?.fetchImpl??fetch,n=t?.timeoutMs??P2,r=t?.token??(b.CLAUDE_CODE_OAUTH_TOKEN||xe());if(!r)return{kind:"unavailable",reason:"no-token",detail:"No Claude Code OAuth token found. Set CLAUDE_CODE_OAUTH_TOKEN or run `claude login` and try again."};let o;try{o=await e(I2,{headers:{Authorization:`Bearer ${r}`,"anthropic-beta":C2},signal:AbortSignal.timeout(n)})}catch(u){return M2(u)?{kind:"unavailable",reason:"timeout",detail:"Request to the usage endpoint timed out."}:{kind:"unavailable",reason:"network-error",detail:"Network error while contacting the usage endpoint."}}if(!o.ok)return{kind:"unavailable",reason:"http-error",detail:`Usage endpoint returned HTTP ${o.status}.`};let s;try{s=await o.json()}catch{return{kind:"unavailable",reason:"malformed-response",detail:"Usage endpoint returned a response that was not valid JSON."}}if(typeof s!="object"||s===null)return{kind:"unavailable",reason:"malformed-response",detail:"Usage endpoint returned an unexpected response shape."};let i=s,a=pl(i.five_hour),c=pl(i.seven_day),l=pl(i.seven_day_sonnet),d=pl(i.seven_day_opus);return!a&&!c&&!l&&!d?{kind:"unavailable",reason:"malformed-response",detail:"Usage endpoint response contained none of the known usage windows."}:{kind:"ok",...a!==void 0?{fiveHour:a}:{},...c!==void 0?{sevenDay:c}:{},...l!==void 0?{sevenDaySonnet:l}:{},...d!==void 0?{sevenDayOpus:d}:{}}}function M2(t){return t instanceof Error&&(t.name==="TimeoutError"||t.name==="AbortError")}var O2=0,D2=4102444800;function F2(t){if(typeof t=="string"){let e=new Date(t);return Number.isNaN(e.getTime())?void 0:e}if(typeof t=="number")return!Number.isFinite(t)||t<O2||t>D2?void 0:new Date(t*1e3)}function pl(t){if(typeof t!="object"||t===null)return;let e=t,n=e.utilization;if(typeof n!="number"||!Number.isFinite(n))return;let r=n>1?n/100:n,o=Math.min(1,Math.max(0,r)),s=F2(e.resets_at);return{utilization:o,...s!==void 0?{resetsAt:s}:{}}}async function iR(t,e){try{let n=await sR();await t.reply(ib(n))}catch(n){e("Usage command error:",n),await t.reply($("Could not fetch usage"))}}import{execFile as Z2,spawn as eX}from"node:child_process";import{promisify as tX}from"node:util";P();import{execFile as L2}from"node:child_process";import{randomBytes as N2}from"node:crypto";import{promises as fl}from"node:fs";import{join as ml}from"node:path";import{promisify as U2}from"node:util";var exe=U2(L2);var nn=class extends Error{cause;code;constructor(e,n,r){super(e),this.name="WorktreeError",this.cause=n,this.code=r}};function $2(t,e=40){return t.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,e).replace(/-+$/g,"")||"task"}function B2(){return N2(4).toString("hex").slice(0,4)}function j2(t){let e=n=>String(n).padStart(2,"0");return`${t.getUTCFullYear()}${e(t.getUTCMonth()+1)}${e(t.getUTCDate())}T${e(t.getUTCHours())}${e(t.getUTCMinutes())}${e(t.getUTCSeconds())}`}function aR(t,e={}){let n=(e.now??(()=>new Date))(),r=(e.randomSuffix??B2)();return`${j2(n)}-${$2(t,32)}-${r}`}function H2(t){let e=t;return e.respawnedAt===void 0&&(e.respawnedAt=void 0),e.respawnedAs===void 0&&(e.respawnedAs=void 0),e.prUrl===void 0&&(e.prUrl=void 0),e.prCreatedAt===void 0&&(e.prCreatedAt=void 0),e}async function Fr(t){let e=ml(Dm(t),"farm.json");try{let n=await fl.readFile(e,"utf8"),r=JSON.parse(n);if(r.schemaVersion!==1&&r.schemaVersion!==2&&r.schemaVersion!==3)throw new nn(`unsupported farm manifest schema: ${r.schemaVersion} (expected 1, 2, or 3)`,void 0,"unsupported-schema");return H2(r)}catch(n){if(n.code==="ENOENT")return null;throw n instanceof nn?n:new nn(`failed to load farm manifest ${e}`,n,"invalid")}}async function cR(t,e){let n=await Fr(t);if(!n)throw new nn(`farm not found: ${t}`);return n.human_decision=e,n.decidedAt=new Date().toISOString(),n.schemaVersion=3,await fl.writeFile(ml(n.farmDir,"farm.json"),JSON.stringify(n,null,2)+`
|
|
1299
1299
|
`,"utf8"),n}async function lR(t,e){let n=await Fr(t);if(!n)throw new nn(`farm not found: ${t}`);return n.respawnedAt=new Date().toISOString(),n.respawnedAs=e,n.schemaVersion=3,await fl.writeFile(ml(n.farmDir,"farm.json"),JSON.stringify(n,null,2)+`
|
|
1300
1300
|
`,"utf8"),n}async function dR(t,e){let n=await Fr(t);if(!n)throw new nn(`farm not found: ${t}`);return n.prUrl=e,n.prCreatedAt=new Date().toISOString(),n.schemaVersion=3,await fl.writeFile(ml(n.farmDir,"farm.json"),JSON.stringify(n,null,2)+`
|
|
1301
|
-
`,"utf8"),n}import{execFile as
|
|
1302
|
-
\u{1F517} ${f}`)}catch(g){r("[farm-callback] reply failed:",g)}}function
|
|
1301
|
+
`,"utf8"),n}import{execFile as W2,spawn as rxe}from"node:child_process";import{promisify as K2}from"node:util";var q2=K2(W2),G2=2e4,Rs=class extends Error{kind;exitCode;stderr;constructor(e,n,r,o){super(e),this.name="GhError",this.kind=n,this.exitCode=r,this.stderr=o}},gl=null,xs=null;function X2(t,e,n){return n===!0?"timeout":e==="ENOENT"?"not-found":/already exists/i.test(t)?"already-exists":/authentication|please log in|HTTP 40[13]|bad credentials|token|scope/i.test(t)?"unauthed":/ETIMEDOUT|ECONNRESET|ECONNREFUSED/i.test(t+(e??""))?"network":"unknown"}function uR(t,e){return q2(t,e,{timeout:G2,killSignal:"SIGTERM"}).then(n=>({stdout:n.stdout,stderr:n.stderr}))}async function pR(t={}){let e=(t._now??(()=>Date.now()))(),n=t.ttlMs??6e4,r=t.execFn??uR,o=t.log??(()=>{});return gl&&gl.expiresAt>e?(o("[gh] checkGhReady cache hit"),gl.result):(o("[gh] checkGhReady cache miss \u2014 probing"),xs||(xs=(async()=>{try{await r("gh",["--version"])}catch(a){let c=a;return c.killed?{ok:!1,hint:"`gh` timed out \u2014 check connectivity"}:c.code==="ENOENT"?{ok:!1,hint:"`gh` CLI not found \u2014 install with: brew install gh"}:{ok:!1,hint:"`gh --version` failed unexpectedly \u2014 check gh installation"}}try{await r("gh",["auth","status"])}catch(a){let c=a;return c.killed||/ETIMEDOUT|ECONNRESET|ENOTFOUND/i.test(String(c.code??""))?{ok:!1,hint:"check network \u2014 cannot reach GitHub"}:{ok:!1,hint:"`gh` is not authenticated \u2014 run: gh auth login"}}let i={ok:!0};return n>0&&(gl={result:i,expiresAt:e+n}),i})().finally(()=>{xs=null}),xs))}async function fR(t,e){let n=e??uR,r=["pr","create","--base",t.base,"--head",t.head,"--title",t.title,"--body",t.body];try{let{stdout:o}=await n("gh",r);return o.trim()}catch(o){let s=o,i=s.stderr??"",a=s.code,c=s.exitCode??1,l=X2(i,a,s.killed);throw new Rs(`gh pr create failed (${l}): ${i.trim()}`,l,c,i)}}function mR(t,e){let n;try{n=e?._store??new wt}catch(r){return{skipped:!0,reason:r instanceof Error?r.message:String(r)}}try{let r={type:"farm-decision",taskSlug:t.taskSlug,decision:t.decision,decidedAt:t.decidedAt,via:t.via};return{factId:n.storeFact({category:"decision",content:JSON.stringify(r),source_surface:"afk"})}}catch(r){return{skipped:!0,reason:r instanceof Error?r.message:String(r)}}}import{promises as z2}from"node:fs";import{join as J2}from"node:path";function yR(t){let e=t.filter(r=>r.score!==null),n=t.filter(r=>r.score===null).map(r=>r.index).sort((r,o)=>r-o);return e.sort((r,o)=>{let s=r.score,i=o.score,a=gR(s),c=gR(i);if(a!==c)return c-a;let l=hR(s.lint_ok),d=hR(i.lint_ok);return l!==d?d-l:s.loc_delta!==i.loc_delta?s.loc_delta-i.loc_delta:r.index-o.index}),[...e.map(r=>r.index),...n]}function gR(t){let e=t.pass+t.fail;return e===0?0:t.pass/e}function hR(t){return t===!0?2:t===!1?1:0}async function hl(t,e={}){if(t.branches.length===0)throw new Error(`resolveWinnerBranch: farm ${t.taskSlug} has no branches`);let n=e.loadScore??V2,r=await Promise.all(t.branches.map(async i=>({index:i.index,score:await n(t.farmDir,i.index)}))),o=yR(r),s=new Map(t.branches.map(i=>[i.index,i]));for(let i of o){let a=r.find(c=>c.index===i)?.score;if(a&&a.pass>0&&a.fail===0){let c=s.get(i);if(c)return{branch:c,source:"winner"}}}for(let i of o)if(r.find(c=>c.index===i)?.score){let c=s.get(i);if(c)return{branch:c,source:"top-scored"}}return{branch:t.branches[0],source:"fallback-first-branch"}}async function V2(t,e){let n=J2(t,"scores",`branch-${e}.json`);try{let r=await z2.readFile(n,"utf8");return JSON.parse(r)}catch(r){return r.code==="ENOENT",null}}var yl="afk:f:";var Y2=new Set(["p","d","r","x"]),Q2=/^[a-z0-9T][a-z0-9T-]{0,62}$/;function bR(t){if(!t||!t.startsWith(yl)||Buffer.byteLength(t,"utf8")>64)return null;let e=t.slice(yl.length),n=e.indexOf(":");if(n<1)return null;let r=e.slice(0,n),o=e.slice(n+1);return!Y2.has(r)||!Q2.test(o)?null:{action:r,taskSlug:o}}var nX=tX(Z2),rm=new Map;async function SR(t,e={}){let n=e.log??(()=>{}),r=rX(t),o=bR(r);if(!o){await ie(t,"Unknown action",n);return}if(t.chat?.id===void 0){await ie(t,"No chat context",n);return}let s=e.loadFarm??Fr,i;try{i=await s(o.taskSlug)}catch(a){n("[farm-callback] loadFarm failed:",a),await ie(t,"Farm load failed",n);return}if(!i){await ie(t,"Farm not found (already GC\u2019d?)",n);return}try{await oX(o.action,t,i,e,n)}catch(a){n("[farm-callback] dispatch error:",a),await ie(t,"Internal error",n)}}function rX(t){return t.callbackQuery?.data}async function ie(t,e,n){try{await t.answerCbQuery(e)}catch(r){n("[farm-callback] answerCbQuery failed:",r)}}async function oX(t,e,n,r,o){switch(t){case"x":return cX(e,n,r,o);case"d":return lX(e,n,r,o);case"p":return wR(`p:${n.taskSlug}`,e,n,r,o,sX);case"r":return wR(`r:${n.taskSlug}`,e,n,r,o,aX)}}async function wR(t,e,n,r,o,s){let i=rm.get(t);if(i){o(`[farm-callback] ${t} \u2014 second tap, awaiting in-flight lock`);try{await i}catch{}let c=r.loadFarm??Fr,l;try{l=await c(n.taskSlug)}catch{await ie(e,"Farm load failed",o);return}if(!l){await ie(e,"Farm not found",o);return}return s(e,l,r,o)}let a=s(e,n,r,o);return rm.set(t,a),a.finally(()=>{rm.delete(t)}),a}async function sX(t,e,n,r){if(e.prUrl){await ie(t,`PR already open: ${e.prUrl}`,r);return}await ie(t,"Opening PR\u2026",r);let o=n.checkGhReady??pR,s;try{s=await o()}catch(g){r("[farm-callback] checkGhReady threw:",g);try{await t.reply("gh readiness check failed \u2014 see daemon logs")}catch{}return}if(!s.ok){try{await t.reply(s.hint)}catch{}return}let i=n.resolveWinnerBranch??hl,a;try{a=await i(e)}catch(g){r("[farm-callback] resolveWinnerBranch failed:",g);try{await t.reply("Winner lookup failed")}catch{}return}let c=a.branch.branch,l=e.baseBranch??"main",d=`Auto PR: ${e.taskName}`,u=`Auto-generated by afk farm ${e.taskSlug} | winner: ${c} | created: ${new Date().toISOString()}`,p=n.createPr??fR,f;try{f=await p({base:l,head:c,title:d,body:u})}catch(g){if(g instanceof Rs){let h={"not-found":"gh CLI not found \u2014 install with: brew install gh","already-exists":"PR already exists for this branch",unauthed:"gh is not authenticated \u2014 run: gh auth login",network:"Network error \u2014 check gh connectivity",timeout:"gh timed out \u2014 check connectivity",unknown:"gh pr create failed \u2014 see daemon logs"};try{await t.reply(h[g.kind])}catch{}return}r("[farm-callback] createPr failed:",g);try{await t.reply("gh pr create failed \u2014 see daemon logs")}catch{}return}let m=n.recordPrCreated??dR;try{await m(e.taskSlug,f)}catch(g){r("[farm-callback] recordPrCreated failed:",g)}try{await t.reply(`PR opened \u2713
|
|
1302
|
+
\u{1F517} ${f}`)}catch(g){r("[farm-callback] reply failed:",g)}}function iX(t,e=()=>{}){e("[farm] spawning child afk process",{args:t});let n=eX("afk",t,{detached:!0,stdio:"ignore"});n.on("error",r=>{e("[farm] child spawn error",{args:t,err:r.message})}),n.on("exit",(r,o)=>{r!==0&&e("[farm] child exited with non-zero code",{args:t,code:r,signal:o})}),n.unref()}async function aX(t,e,n,r){if(e.respawnedAs){await ie(t,`Already respawned as ${e.respawnedAs}`,r);return}if(e.branches.length===0){await ie(t,"No branches remain \u2014 cannot respawn",r);return}await ie(t,"Respawning\u2026",r);let o=n.resolveWinnerBranch??hl,s;try{s=await o(e)}catch(u){r("[farm-callback] resolveWinnerBranch failed:",u);try{await t.reply("Winner lookup failed")}catch{}return}let i=s.branch,a=aR(e.taskName,{now:n._now,randomSuffix:n._randomSuffix}),c=e.branches.length;r("[farm] spawning child",{childSlug:a,baseRef:i.branch,branches:c});let l=n.spawnFarm??(u=>iX(u,r));try{l(["farm",e.taskName,"--branches",String(c),"--base-ref",i.branch,"--task-slug",a])}catch(u){r("[farm-callback] spawnFarm failed:",u);try{await t.reply("Respawn failed")}catch{}return}let d=n.recordRespawn??lR;try{await d(e.taskSlug,a)}catch(u){r("[farm-callback] recordRespawn failed:",u)}try{await t.reply(`Respawning as \`${a}\` from ${i.branch} \u2713
|
|
1303
1303
|
\u{1F504} Farm \`${e.taskSlug}\` respawned.
|
|
1304
1304
|
Child slug: \`${a}\`
|
|
1305
|
-
Winner branch: \`${i.branch}\``)}catch(u){r("[farm-callback] reply failed:",u)}}async function
|
|
1305
|
+
Winner branch: \`${i.branch}\``)}catch(u){r("[farm-callback] reply failed:",u)}}async function cX(t,e,n,r){if(e.human_decision==="rejected"){await ie(t,"Already discarded",r);return}if(e.human_decision!==void 0){await ie(t,`Already resolved (${e.human_decision})`,r);return}let o=n.recordHumanDecision??cR,s;try{s=await o(e.taskSlug,"rejected")}catch(a){r("[farm-callback] recordHumanDecision failed:",a),await ie(t,"Manifest write failed",r);return}let i=n.writeFarmDecisionFact??mR;try{let a=i({taskSlug:s.taskSlug,decision:"rejected",decidedAt:s.decidedAt??new Date().toISOString(),via:"telegram"});"skipped"in a&&r("[farm-callback] memory write skipped:",a.reason)}catch(a){r("[farm-callback] memory write threw:",a)}await ie(t,"Discarded \u2713",r);try{await t.reply(`\u274C Farm \`${s.taskSlug}\` discarded.`)}catch(a){r("[farm-callback] reply failed:",a)}}async function lX(t,e,n,r){if(e.branches.length===0){await ie(t,"No branches to diff",r);return}let o=n.resolveWinnerBranch??hl,s;try{s=await o(e)}catch(l){r("[farm-callback] winner resolution failed:",l),await ie(t,"Winner lookup failed",r);return}let i=s.branch,a=n.execGit??dX;await ie(t,"Computing diff\u2026",r);let c=s.source==="winner"?"\u2190 winner":s.source==="top-scored"?"\u2190 top-scored (no clean test pass)":"\u2190 fallback (no scores)";try{let[l,d]=await Promise.all([a(i.path,["log","--oneline",`${e.baseRef}..HEAD`]),a(i.path,["diff","--stat",e.baseRef,"HEAD"])]),u=`\u{1F4CA} Diff for ${i.branch} ${c}
|
|
1306
1306
|
base: ${e.baseRef.slice(0,7)}
|
|
1307
1307
|
|
|
1308
1308
|
Commits:
|
|
1309
1309
|
${l.stdout.trim()||"(none)"}
|
|
1310
1310
|
|
|
1311
1311
|
Stat:
|
|
1312
|
-
${d.stdout.trim()||"(no changes)"}`;await t.reply(u.slice(0,4e3))}catch(l){r("[farm-callback] diff failed:",l);try{await t.reply("Diff failed \u2014 see daemon logs.")}catch{}}}async function
|
|
1312
|
+
${d.stdout.trim()||"(no changes)"}`;await t.reply(u.slice(0,4e3))}catch(l){r("[farm-callback] diff failed:",l);try{await t.reply("Diff failed \u2014 see daemon logs.")}catch{}}}async function dX(t,e){let n=await nX("git",e,{cwd:t,maxBuffer:4194304});return{stdout:n.stdout,stderr:n.stderr}}import{TelegramError as uX}from"telegraf";function Lr(t){let e=t instanceof Error?t.message:String(t);return e.toLowerCase().includes("rate limit")||e.toLowerCase().includes("too many requests")}function Nr(t){let e=t instanceof Error?t.message:String(t);return e.toLowerCase().includes("network")||e.toLowerCase().includes("connect")||e.toLowerCase().includes("timeout")}function bl(t){return t instanceof uX}var In=class extends Error{constructor(e){super(e),this.name="StreamTimeoutError"}};I();import Ixe from"string-width";var pX=/\x1B(?:\[[0-?]*[ -/]*[@-~]|\][^\x07\x1B]*(?:\x07|\x1B\\)|[P^_X][^\x1B]*\x1B\\|[@-OQ-WYZ\\\-])/g,Cxe=typeof Intl<"u"&&"Segmenter"in Intl?new Intl.Segmenter(void 0,{granularity:"grapheme"}):null;function kR(t){return t.replace(pX,"")}var fX=/[\x00-\x1F\x7F-\x9F]/g;function wl(t){return kR(t).replace(fX," ").replace(/ {2,}/g," ").trim()}var om=4,mX=[[["browser","web","fetch","scrape"],"Researching"],[["test","vitest","jest"],"Running tests"],[["bash","shell","exec","command"],"Running a command"]],gX=[[["search","grep","glob","find"],"Searching"],[["read","open","view","inspect"],"Reading files"],[["edit","write","patch","replace"],"Editing files"]];function Sl(t){let e=wl(t),n=new Set(e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean));for(let[o,s]of[...mX,...gX])if(o.some(i=>n.has(i)))return s;let r=e.replace(/[_-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\s+/g," ").trim();return r?`Using ${r}`:"Working"}function sm(t,e){let n=wl(t??"").replace(/\s+/g," ").trim(),r=/^(working|processing|in progress|running)(?:\s*\([^)]*\))?$/i.test(n);return e&&(!n||r)?Sl(e):n||(e?Sl(e):"Working")}function im(t){if(/^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i.test(t))return"Sub-agent";let e=wl(t).replace(/[_-]+/g," ").replace(/\s+/g," ").trim();return e?e.charAt(0).toUpperCase()+e.slice(1):"Sub-agent"}function am(t,e){if(t<=0)return"";let n=e.slice(-om),r=`\u{1F916} Sub-agents \xB7 ${t} ${t===1?"step":"steps"}`;return n.length>0?`
|
|
1313
1313
|
${r}
|
|
1314
1314
|
${n.join(`
|
|
1315
1315
|
`)}`:`
|
|
1316
1316
|
${r}`}var vR=6,cm=32;function lm(t){let e=t.slice(-vR);return e.length>0?e.map(n=>`
|
|
1317
|
-
${n}`).join(""):""}function
|
|
1317
|
+
${n}`).join(""):""}function hX(t,e){if(e<=0)return 0;if(e>=t.length)return t.length;let n=t.slice(0,e).replace(/^ {0,3}```[\w]*\n[\s\S]*?```/gm,"");if(n.includes("```")||(n.match(/`/g)?.length??0)%2!==0)return t.length;let r=n.lastIndexOf("["),o=n.lastIndexOf("]");return r>o||o>=0&&n[o+1]==="("&&!n.includes(")",o+1)?t.length:e}function TR(t,e){if(e.length===0)return t;let n=Math.max(0,e.length-vR),r="",o=0,s=0;return e.forEach((i,a)=>{let c=hX(t,Math.min(Math.max(i.at,o),t.length));r+=t.slice(o,c),o=c;let l=(e[a+1]?.at??1/0)<=c;a>=n?(r+=`
|
|
1318
1318
|
${i.label}`,s=c,!l&&c<t.length&&t[c]!==`
|
|
1319
1319
|
`&&(r+=`
|
|
1320
1320
|
`)):c>s&&!l&&(r+=`
|
|
1321
|
-
`,s=c)}),r+t.slice(o)}function _R(t){return(t.progressGateOpen?TR(t.accumulated,t.progressEntries):t.accumulated)+am(t.subagentSteps,t.recentSubagentSteps)}function ER(t){return t.accumulated+lm(t.progressEntries.map(e=>e.label))}import{TelegramError as kl}from"telegraf";import{TelegramError as
|
|
1321
|
+
`,s=c)}),r+t.slice(o)}function _R(t){return(t.progressGateOpen?TR(t.accumulated,t.progressEntries):t.accumulated)+am(t.subagentSteps,t.recentSubagentSteps)}function ER(t){return t.accumulated+lm(t.progressEntries.map(e=>e.label))}import{TelegramError as kl}from"telegraf";import{TelegramError as yX}from"telegraf";var bX=2,wX=3e4,SX=1e3,dm=t=>new Promise(e=>setTimeout(e,t));function um(t){if(!(t instanceof yX)||t.code!==429)return null;let e=t.parameters?.retry_after,n=Number(/retry after (\d+)/i.exec(t.description??"")?.[1]),r=typeof e=="number"&&e>0?e:Number.isFinite(n)&&n>0?n:0;return Math.min(r>0?r*1e3:SX,wX)}async function Ur(t,e,n,r={}){let o=r.maxRetries??bX,s=r.sleep??dm;for(let i=0;;i++)try{await t(e,n);return}catch(a){let c=um(a);if(c===null||i>=o)throw a;await s(c)}}var kX=300,pm="\u26A0\uFE0F Telegram dropped part of this reply (rate limit) \u2014 ask me to resend it.";async function ce(t,e,n,r,o=!1){let s=Date.now();if(!t.sentMessage){let c=Bt(r||"\u2026"),l=Se(c);try{t.sentMessage=await e.reply(l[0]??"\u2026",{parse_mode:"HTML"})}catch(d){if(d instanceof kl&&d.code===400&&/can't parse entities/i.test(d.description??""))t.sentMessage=await e.reply(r||"\u2026");else throw d}return}if(!o&&s-t.lastEditAt<kX&&r.length<100)return;t.lastEditAt=s;let i=Bt(r||"\u2026"),a=Se(i);try{await e.telegram.editMessageText(n,t.sentMessage.message_id,void 0,a[0]??i,{parse_mode:"HTML"})}catch(c){if(c instanceof kl&&c.code===400&&/can't parse entities/i.test(c.description??""))try{await e.telegram.editMessageText(n,t.sentMessage.message_id,void 0,r)}catch{}else{let l=um(c);if(l!==null){let d=t.lastEditAt;if(await dm(l),t.lastEditAt===d)try{await e.telegram.editMessageText(n,t.sentMessage.message_id,void 0,a[0]??i,{parse_mode:"HTML"})}catch{}}}}}async function vl(t,e){let n=!1,r=(o,s)=>t.reply(o,s);for(let o of Se(e))if(o)try{for(let s of Se(Bt(o)))s&&(await Ur(r,s,{parse_mode:"HTML"}),n=!0)}catch(s){if(s instanceof kl&&s.code===400&&/can't parse entities/i.test(s.description??""))try{await Ur(r,o),n=!0}catch{}else{if(s instanceof kl)return await t.reply(pm).catch(()=>{}),n;throw s}}return n}import{TelegramError as vX}from"telegraf";var TX=300*1e3;async function AR(t,e){let{state:n,ctx:r,chatId:o}=e;n.pausedUntil=t.resetsAt??null;let s=t.autoResume??!0,i=n.pausedUntil!==null?Math.max(0,Math.ceil((n.pausedUntil.getTime()-Date.now())/6e4)):null,a=n.pausedUntil!==null?n.pausedUntil.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",hour12:!0}):null,c=t.accountId?`
|
|
1322
1322
|
|
|
1323
1323
|
Account: ${t.accountId}`:"",l=a!==null&&i!==null?s?`\u23F8 **Usage paused**${c}
|
|
1324
1324
|
|
|
@@ -1336,9 +1336,9 @@ No reset time available. Wait for the limit to reset, then send again \u2014 or
|
|
|
1336
1336
|
|
|
1337
1337
|
Resets at ${n.pausedUntil.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",hour12:!0})} (in ~${d} min).
|
|
1338
1338
|
|
|
1339
|
-
I'll auto-resume when the limit resets \u2014 no need to retype.`;n.editInFlight=!0,ce(n,r,o,f,!0).finally(()=>{n.editInFlight=!1})}},
|
|
1339
|
+
I'll auto-resume when the limit resets \u2014 no need to retype.`;n.editInFlight=!0,ce(n,r,o,f,!0).finally(()=>{n.editInFlight=!1})}},TX))}async function xR(t,e){let{state:n,ctx:r,chatId:o}=e;n.countdownInterval!==null&&(clearInterval(n.countdownInterval),n.countdownInterval=null),n.pausedUntil=null;let s=t.hotSwapped&&t.accountId?`\u25B6 **Resumed on ${t.accountId}**`:"\u25B6 **Resumed**";await ce(n,r,o,s,!0)}async function RR(t,e){let{state:n,ctx:r,chatId:o,cleanFinal:s,finalBody:i,clearProgressTimer:a,onComplete:c,logger:l,renderActivityReceipt:d}=e;if(n.sawTerminalEvent=!0,n.turnEnded=!0,a(),n.countdownInterval!==null&&(clearInterval(n.countdownInterval),n.countdownInterval=null),s&&n.answerText.trim()?await vl(r,n.answerText+d(n.progressRounds,Date.now()-n.turnStartedAt))&&n.sentMessage&&(await r.telegram.deleteMessage?.(o,n.sentMessage.message_id).catch(()=>{}),n.sentMessage=null):i().trim()&&await ce(n,r,o,i(),!0),c)try{await c(n.answerText,t)}catch(u){l?.("streamResponse onComplete (turn recording) failed:",u)}return!0}function IR(t,e){let{state:n,clearProgressTimer:r}=e;throw n.sawTerminalEvent=!0,n.turnEnded=!0,r(),n.countdownInterval!==null&&(clearInterval(n.countdownInterval),n.countdownInterval=null),t}async function CR(t,e,n,r,o){if(!(!(e&&n.trim())&&r&&o))return;let s=Se(Bt(r));if(s.length<=1)return;let i=(a,c)=>t.reply(a,c);try{for(let a=1;a<s.length;a++){let c=s[a];c&&await Ur(i,c,{parse_mode:"HTML"})}}catch(a){if(a instanceof vX)await t.reply(pm).catch(()=>{});else throw a}}var EX=9e4,PR=18e4,AX=66e4,MR=15e3,xX=6e4;function RX(){let t=Oc();return 3*Lc(t)+xX}var OR=5e3,IX=9e4;function DR(t,e){return()=>{let n=e.pausedUntil!==null?Math.max(PR,e.pausedUntil.getTime()-Date.now()+IX):e.receivedAny?PR:EX;return new Promise((r,o)=>{let s=null,i=()=>{let a=n-(Date.now()-e.lastActivityAt);if(a<=0){if(e.inFlightTools.size>0&&e.toolInFlightSince!==null&&Date.now()-e.toolInFlightSince<AX){s=setTimeout(i,MR);return}if(e.apiRoundInFlight&&e.apiRoundSince!==null&&Date.now()-e.apiRoundSince<RX()){s=setTimeout(i,MR);return}s=null,e.timedOut=!0,o(new In(e.receivedAny?"Response timed out. Try sending a shorter message or try again.":"Request timed out. The agent may still be starting (first message can take a minute). Try again in a moment."))}else s=setTimeout(i,a)};s=setTimeout(i,n),t.next().then(a=>{s!=null&&(clearTimeout(s),s=null),r(a)},a=>{s!=null&&(clearTimeout(s),s=null),o(a)})})}}function FR(t,e,n){return setTimeout(()=>{n()||e()},Math.max(0,t))}async function LR(t,e,n,r,o,s,i,a,c){e.progressRounds++;let{description:l,lastToolName:d}=t.progress,u=`\u25E6 ${sm(l,d)}`;e.progressEntries[e.progressEntries.length-1]?.label!==u&&e.progressEntries.push({label:u,at:e.accumulated.length}),e.progressEntries.length>cm&&(e.progressEntries=e.progressEntries.slice(-cm)),!n&&Date.now()-e.turnStartedAt>=r&&(a(!0),n=!0),n?(c(),await ce(e,o,s,i())):e.progressTimer===null&&(e.progressTimer=FR(r-(Date.now()-e.turnStartedAt),()=>{e.progressTimer=null,a(!0),!e.editInFlight&&(e.editInFlight=!0,ce(e,o,s,i(),!0).finally(()=>{e.editInFlight=!1}))},()=>e.turnEnded))}function NR(t,e,n,r,o,s){return(i,a)=>{let c=im(a.agentType??a.subagentId);o(),i.type==="chunk"&&i.chunk.type==="tool_use_detail"?(s.subagentSteps++,s.recentSubagentSteps.push(`${c} \u2014 ${Sl(i.chunk.toolName)}`),s.recentSubagentSteps.length>om&&s.recentSubagentSteps.shift(),ce(t,e,n,r())):i.type==="done"&&ce(t,e,n,r())}}function CX(t,e){if(t<=0)return"";let n=Math.max(1,Math.round(e/1e3));return`
|
|
1340
1340
|
|
|
1341
|
-
\u23F1\uFE0F ${t} ${t===1?"step":"steps"} \xB7 ${n}s`}async function fm(t,e,n,r,o={}){if(!t.chat?.id){r?.("streamResponse: ctx.chat is undefined (non-chat context); skipping");return}let s=t.chat.id,i=o.cleanFinal??!1,a=o.progressDelayMs??OR,c={accumulated:"",answerText:"",sentMessage:null,lastEditAt:0,pausedUntil:null,countdownInterval:null,editInFlight:!1,lastCountdownBucket:-1,sawTerminalEvent:!1,progressEntries:[],progressRounds:0,turnEnded:!1,progressTimer:null,turnStartedAt:Date.now()},l=0,d=0,u=!1,p={receivedAny:!1,timedOut:!1,lastActivityAt:Date.now(),inFlightTools:new Set,toolInFlightSince:null,get pausedUntil(){return c.pausedUntil},apiRoundInFlight:!1,apiRoundSince:null},f={subagentSteps:0,recentSubagentSteps:[]},m=a<=0,g=()=>{c.progressTimer!==null&&(clearTimeout(c.progressTimer),c.progressTimer=null)},h=()=>_R({accumulated:c.accumulated,progressEntries:c.progressEntries,progressGateOpen:m,subagentSteps:f.subagentSteps,recentSubagentSteps:f.recentSubagentSteps}),y=()=>ER({accumulated:c.accumulated,progressEntries:c.progressEntries}),w={state:c,ctx:t,chatId:s,cleanFinal:i,livePreview:h,finalBody:y,clearProgressTimer:g,renderActivityReceipt:
|
|
1341
|
+
\u23F1\uFE0F ${t} ${t===1?"step":"steps"} \xB7 ${n}s`}async function fm(t,e,n,r,o={}){if(!t.chat?.id){r?.("streamResponse: ctx.chat is undefined (non-chat context); skipping");return}let s=t.chat.id,i=o.cleanFinal??!1,a=o.progressDelayMs??OR,c={accumulated:"",answerText:"",sentMessage:null,lastEditAt:0,pausedUntil:null,countdownInterval:null,editInFlight:!1,lastCountdownBucket:-1,sawTerminalEvent:!1,progressEntries:[],progressRounds:0,turnEnded:!1,progressTimer:null,turnStartedAt:Date.now()},l=0,d=0,u=!1,p={receivedAny:!1,timedOut:!1,lastActivityAt:Date.now(),inFlightTools:new Set,toolInFlightSince:null,get pausedUntil(){return c.pausedUntil},apiRoundInFlight:!1,apiRoundSince:null},f={subagentSteps:0,recentSubagentSteps:[]},m=a<=0,g=()=>{c.progressTimer!==null&&(clearTimeout(c.progressTimer),c.progressTimer=null)},h=()=>_R({accumulated:c.accumulated,progressEntries:c.progressEntries,progressGateOpen:m,subagentSteps:f.subagentSteps,recentSubagentSteps:f.recentSubagentSteps}),y=()=>ER({accumulated:c.accumulated,progressEntries:c.progressEntries}),w={state:c,ctx:t,chatId:s,cleanFinal:i,livePreview:h,finalBody:y,clearProgressTimer:g,renderActivityReceipt:CX,onComplete:o.onComplete,logger:r};try{let k=Array.isArray(n)?"sendMessageStream"in e&&typeof e.sendMessageStream=="function"?e.sendMessageStream(n):(async function*(){let M=await e.sendMessage(n.map(S=>S.type==="text"?S.text:"").filter(Boolean).join(`
|
|
1342
1342
|
`),{stream:!1});yield{type:"message",message:M},yield{type:"done",metadata:M.metadata}})():"sendMessageStream"in e&&typeof e.sendMessageStream=="function"?e.sendMessageStream(n):(async function*(){let M=await e.sendMessage(n,{stream:!1});yield{type:"message",message:M},yield{type:"done",metadata:M.metadata}})();await ce(c,t,s,"Thinking\u2026");let v=k[Symbol.asyncIterator](),_=DR(v,p),R=NR(c,t,s,h,()=>{p.lastActivityAt=Date.now()},f),A=!!b.AFK_TELEGRAM_TRACE;try{await Rv(R,async()=>{for(;;){A&&console.log("[trace] awaiting next event");let S=await _();if(A&&console.log("[trace] event arrived:",S.done?"DONE":S.value.type),S.done)break;let T=S.value;if(p.lastActivityAt=Date.now(),p.apiRoundInFlight&&(p.apiRoundInFlight=!1,p.apiRoundSince=null),p.receivedAny||(p.receivedAny=!0,console.log("\u{1F4E1} First stream event received:",T.type),r?.("First stream event received:",T.type)),T.type==="chunk"&&T.chunk.type==="tool_use_detail"?(p.inFlightTools.size===0&&(p.toolInFlightSince=Date.now()),p.inFlightTools.add(T.chunk.toolUseId)):T.type==="chunk"&&T.chunk.type==="tool_result"&&(p.inFlightTools.delete(T.chunk.toolUseId),p.inFlightTools.size===0&&(p.toolInFlightSince=null)),T.type==="chunk"&&T.chunk.type==="content"&&(u||(l=c.accumulated.length,d=c.answerText.length,u=!0),c.accumulated+=T.chunk.content,c.answerText+=T.chunk.content,await ce(c,t,s,h())),T.type==="stream_retry"&&(c.accumulated=c.accumulated.slice(0,l),c.answerText=c.answerText.slice(0,d),u=!1,await ce(c,t,s,h(),!0)),T.type==="rate_limit"){let K=T.retryAfterMs!==void 0?T.retryAfterMs<6e4?T.retryAfterMs:8e3:null,F=K!==null?Math.ceil(K/1e3):null,L=F!==null?`\u23F8 Rate limited \xB7 retrying in ~${F}s\u2026`:"\u23F8 Rate limited \xB7 retrying\u2026";await ce(c,t,s,h()+`
|
|
1343
1343
|
|
|
1344
1344
|
${L}`,!0);continue}if(T.type==="chunk"&&T.chunk.type,T.type==="message"&&T.message.role==="assistant"&&(c.accumulated=T.message.content,c.answerText=T.message.content,u=!1,c.progressEntries=c.progressEntries.map(E=>({...E,at:c.accumulated.length})),await ce(c,t,s,h())),T.type==="progress"&&(u=!1,p.apiRoundInFlight=!0,p.apiRoundSince=Date.now(),await LR(T,c,m,a,t,s,h,E=>{m=E},g)),T.type==="suggestion"&&T.suggestion.trim()!==c.answerText.trim()&&(c.accumulated+=`
|
|
@@ -1347,15 +1347,15 @@ ${L}`,!0);continue}if(T.type==="chunk"&&T.chunk.type,T.type==="message"&&T.messa
|
|
|
1347
1347
|
|
|
1348
1348
|
\u{1F4A1} ${T.suggestion}`,await ce(c,t,s,h())),T.type==="notice"){let E=`
|
|
1349
1349
|
|
|
1350
|
-
_\u2139 ${T.text.replace(/[_*[\]()~`>#+\-=|{}.!]/g,"\\$&")}_`;c.accumulated+=E,await ce(c,t,s,h())}if(T.type==="paused"){await AR(T,w);continue}if(T.type==="resumed"){await xR(T,w);continue}if(T.type==="done"){await RR(T.metadata,w);break}T.type==="error"&&IR(T.error,w)}});let M=c.sentMessage;if(M&&!c.sawTerminalEvent){let S=i&&c.answerText.trim()?c.answerText:y();S.trim()&&await vl(t,S)&&(await t.telegram.deleteMessage?.(s,M.message_id).catch(()=>{}),c.sentMessage=null)}else await CR(t,i,c.answerText,y(),M)}finally{(p.timedOut||!c.sawTerminalEvent)&&await Promise.resolve(e.interrupt?.()).catch(()=>{}),c.countdownInterval!==null&&(clearInterval(c.countdownInterval),c.countdownInterval=null),c.turnEnded=!0,g(),c.editInFlight=!1,p.apiRoundInFlight=!1,p.apiRoundSince=null,await Promise.resolve(v.return?.(void 0)).catch(()=>{})}}catch(k){throw r?.("Streaming error:",k),k}}async function Tl(t,e,n,r,o){if(!r.has(e))try{await Promise.race([n.waitForInitialization(),new Promise((a,c)=>setTimeout(()=>c(new Error("timeout")),5e3))]);let s=n.getSessionMetadata(),i=[{command:"start",description:"Show welcome and command list"},{command:"help",description:"Show this command list"},{command:"clear",description:"Clear conversation history"},{command:"compact",description:"Compact conversation history"},{command:"model",description:"Switch Claude model (opus/sonnet/haiku)"},{command:"cd",description:"Show or change session working directory"},{command:"name",description:"Show or set the session name"},{command:"usage",description:"Show Claude subscription usage"},{command:"sessions",description:"List and switch between sessions"},{command:"new",description:"Start a new session (keeps the current one)"}];if(s.slashCommands?.length)for(let a of s.slashCommands){let c=a.replace(/^\//,"");i.push({command:c,description:`SDK command: ${c}`})}if(s.skills?.length)for(let a of s.skills)i.push({command:a,description:`Run ${a} skill`});await t.telegram.setMyCommands(i,{scope:{type:"chat",chat_id:e}}),r.add(e),o(`Registered ${i.length} commands for chat ${e}`)}catch(s){o(`Could not register dynamic commands for chat ${e}:`,s)}}function le(t){return[...[...t].map(r=>{if(r==="["||r==="]"||r==="@"||r==="("||r===")")return"";let o=r.codePointAt(0)??0;return o<32||o===127?" ":r}).join("").replace(/\s+/g," ").trim()].slice(0,64).join("")}function $r(t,e){if(e!=="group"&&e!=="supergroup"||!t)return"";let n=le([t.first_name??"",t.last_name??""].join(" ")),r=t.username?le(t.username):"",o=typeof t.id=="number"&&Number.isFinite(t.id)?`id ${t.id}`:"",s=[n,r?`@${r}`:""].filter(Boolean).join(" "),i;if(s&&o)i=`${s} (${o})`;else if(s)i=s;else if(o)i=o;else return"";return`[from ${i}]: `}var UR=300;function mm(t){let n=[...t].map(o=>{if(o==="["||o==="]"||o==='"')return"";let s=o.codePointAt(0)??0;return s<32||s===127?" ":o}).join("").replace(/\s+/g," ").trim(),r=[...n];return r.length<=UR?n:r.slice(0,UR).join("")+"\u2026"}var $R="the assistant";function
|
|
1350
|
+
_\u2139 ${T.text.replace(/[_*[\]()~`>#+\-=|{}.!]/g,"\\$&")}_`;c.accumulated+=E,await ce(c,t,s,h())}if(T.type==="paused"){await AR(T,w);continue}if(T.type==="resumed"){await xR(T,w);continue}if(T.type==="done"){await RR(T.metadata,w);break}T.type==="error"&&IR(T.error,w)}});let M=c.sentMessage;if(M&&!c.sawTerminalEvent){let S=i&&c.answerText.trim()?c.answerText:y();S.trim()&&await vl(t,S)&&(await t.telegram.deleteMessage?.(s,M.message_id).catch(()=>{}),c.sentMessage=null)}else await CR(t,i,c.answerText,y(),M)}finally{(p.timedOut||!c.sawTerminalEvent)&&await Promise.resolve(e.interrupt?.()).catch(()=>{}),c.countdownInterval!==null&&(clearInterval(c.countdownInterval),c.countdownInterval=null),c.turnEnded=!0,g(),c.editInFlight=!1,p.apiRoundInFlight=!1,p.apiRoundSince=null,await Promise.resolve(v.return?.(void 0)).catch(()=>{})}}catch(k){throw r?.("Streaming error:",k),k}}async function Tl(t,e,n,r,o){if(!r.has(e))try{await Promise.race([n.waitForInitialization(),new Promise((a,c)=>setTimeout(()=>c(new Error("timeout")),5e3))]);let s=n.getSessionMetadata(),i=[{command:"start",description:"Show welcome and command list"},{command:"help",description:"Show this command list"},{command:"clear",description:"Clear conversation history"},{command:"compact",description:"Compact conversation history"},{command:"model",description:"Switch Claude model (opus/sonnet/haiku)"},{command:"cd",description:"Show or change session working directory"},{command:"name",description:"Show or set the session name"},{command:"usage",description:"Show Claude subscription usage"},{command:"sessions",description:"List and switch between sessions"},{command:"new",description:"Start a new session (keeps the current one)"}];if(s.slashCommands?.length)for(let a of s.slashCommands){let c=a.replace(/^\//,"");i.push({command:c,description:`SDK command: ${c}`})}if(s.skills?.length)for(let a of s.skills)i.push({command:a,description:`Run ${a} skill`});await t.telegram.setMyCommands(i,{scope:{type:"chat",chat_id:e}}),r.add(e),o(`Registered ${i.length} commands for chat ${e}`)}catch(s){o(`Could not register dynamic commands for chat ${e}:`,s)}}function le(t){return[...[...t].map(r=>{if(r==="["||r==="]"||r==="@"||r==="("||r===")")return"";let o=r.codePointAt(0)??0;return o<32||o===127?" ":r}).join("").replace(/\s+/g," ").trim()].slice(0,64).join("")}function $r(t,e){if(e!=="group"&&e!=="supergroup"||!t)return"";let n=le([t.first_name??"",t.last_name??""].join(" ")),r=t.username?le(t.username):"",o=typeof t.id=="number"&&Number.isFinite(t.id)?`id ${t.id}`:"",s=[n,r?`@${r}`:""].filter(Boolean).join(" "),i;if(s&&o)i=`${s} (${o})`;else if(s)i=s;else if(o)i=o;else return"";return`[from ${i}]: `}var UR=300;function mm(t){let n=[...t].map(o=>{if(o==="["||o==="]"||o==='"')return"";let s=o.codePointAt(0)??0;return s<32||s===127?" ":o}).join("").replace(/\s+/g," ").trim(),r=[...n];return r.length<=UR?n:r.slice(0,UR).join("")+"\u2026"}var $R="the assistant";function PX(t,e){if(t&&typeof t.id=="number"&&Number.isFinite(t.id)&&e!==void 0&&t.id===e)return $R;if(!t)return"";let n=le([t.first_name??"",t.last_name??""].join(" "));if(n&&n.toLowerCase()!==$R)return n;let r=t.username?le(t.username):"";return r?`@${r}`:""}function Is(t){let{replyToMessage:e,quote:n,botId:r}=t,o=n?.text??"";if(!e&&o.length===0)return"";let s=PX(e?.from,r),i=mm(o)||mm(e?.text??"")||mm(e?.caption??"");return i?s?`[in reply to ${s}: "${i}"] `:`[in reply to: "${i}"] `:e?s?`[in reply to ${s}'s message] `:"[in reply to an earlier message] ":""}function MX(t){let{first_name:e="",last_name:n="",username:r}=t.sender_user,o=le(`${e} ${n}`.trim()),s=r?le(r):"";return[o,s?`@${s}`:""].filter(Boolean).join(" ")}function OX(t){return le(t.sender_user_name)}function DX(t){let e=t.sender_chat,n=le(e.title??""),r=e.username?le(e.username):"";return[n,r?`@${r}`:""].filter(Boolean).join(" ")}function FX(t){let e=t.chat,n=le(e.title??""),r=e.username?le(e.username):"";return[n,r?`@${r}`:""].filter(Boolean).join(" ")}function LX(t){let e=le(`${t.first_name??""} ${t.last_name??""}`.trim()),n=t.username?le(t.username):"";return[e,n?`@${n}`:""].filter(Boolean).join(" ")}function Cs(t){let e="";if(t.forward_origin){let n=t.forward_origin;n.type==="user"?e=MX(n):n.type==="hidden_user"?e=OX(n):n.type==="chat"?e=DX(n):n.type==="channel"?e=FX(n):console.warn(`[forward-provenance] unknown forward_origin.type "${n.type}" \u2014 Bot API may have added a new origin type`)}if(!e&&t.forward_from&&(e=LX(t.forward_from)),!e&&t.forward_from_chat){let n=t.forward_from_chat,r=le(n.title??""),o=n.username?le(n.username):"";e=[r,o?`@${o}`:""].filter(Boolean).join(" ")}return!e&&t.forward_sender_name&&(e=le(t.forward_sender_name)),e?`[forwarded from ${e}] `:""}var BR=5*1024*1024,NX=new Set(["txt","md","json","yaml","yml","xml","csv","log","py","js","ts","sh","toml","ini","cfg","conf","html","css","sql","rb","go","rs","java","c","cpp","h","jsx","tsx","kt","swift","r","pl","lua","php","bat","ps1"]),UX="text/code files (.txt, .md, .py, .js, .ts, .json, .yaml, etc.) or PDF";function $X(t){return t.replace(/\/bot[^/]+\//g,"/bot[REDACTED]/")}function BX(t,e){let n=(t??"").toLowerCase().split(";")[0]?.trim()??"";if(n==="application/pdf")return"pdf";if(n.startsWith("text/"))return"text";let r=(e??"").split(".").pop()?.toLowerCase()??"";return NX.has(r)?"text":"unsupported"}async function jX(t,e){let n=t.headers.get("content-length");if(n!=null){let a=Number(n);if(Number.isFinite(a)&&a>e)return{status:"too-large",bytesRead:a}}let r=t.body;if(!r)return{status:"missing-body"};let o=r.getReader(),s=[],i=0;try{for(;;){let{done:a,value:c}=await o.read();if(a)break;if(i+=c.byteLength,i>e)return await o.cancel().catch(()=>{}),{status:"too-large",bytesRead:i};s.push(Buffer.from(c))}}finally{o.releaseLock()}return{status:"ok",bytes:Buffer.concat(s,i)}}async function jR(t,e){let n=t.message,r=n?.document;if(!n||!r)return e("Document handling: missing message or document field"),null;let o=t.chat?.id,s=r.file_name,i=r.mime_type;if(r.file_size!=null&&r.file_size>BR)return e(`Document handling: oversized file (${r.file_size} bytes) for chat ${o??"(unknown)"}`),await t.reply("\u274C Document is too large (max 5 MB). Please send a smaller file."),null;let a=BX(i,s);if(a==="unsupported")return e(`Document handling: unsupported type mime=${i??"(none)"} name=${s??"(none)"} for chat ${o??"(unknown)"}`),await t.reply(`\u274C Unsupported file type. Please send ${UX}.`),null;let c;try{let m=await t.telegram.getFileLink(r.file_id),g=m instanceof URL?m:new URL(String(m));if(g.protocol!=="https:"||g.hostname!=="api.telegram.org"||g.port!==""&&g.port!=="443")return e(`Document handling: unexpected file URL (protocol=${g.protocol} hostname=${g.hostname}) for chat ${o??"(unknown)"}`),await t.reply("\u274C Couldn't download the document. Please try resending."),null;let h=await globalThis.fetch(g.href,{signal:AbortSignal.timeout(15e3),redirect:"error"});if(!h.ok)return e(`Document handling: fetch failed status=${h.status} for chat ${o??"(unknown)"}`),await t.reply("\u274C Couldn't download the document. Please try resending."),null;let y=await jX(h,BR);if(y.status==="too-large")return e(`Document handling: downloaded file (${y.bytesRead} bytes) exceeds limit for chat ${o??"(unknown)"}`),await t.reply("\u274C Document is too large (max 5 MB). Please send a smaller file."),null;if(y.status==="missing-body")return e(`Document handling: fetch response had no body for chat ${o??"(unknown)"}`),await t.reply("\u274C Couldn't download the document. Please try resending."),null;c=y.bytes}catch(m){let g=m instanceof Error?m.message:String(m);return e("Document handling download error:",$X(g)),await t.reply("\u274C Couldn't download the document. Please try resending."),null}let l=[],d=$r(n.from,t.chat?.type),u=Is({replyToMessage:n.reply_to_message,botId:t.botInfo?.id}),p=Cs(n),f=u+p+d;if(n.caption!=null){let m=[...n.caption].slice(0,1024).join("");l.push({type:"text",text:`${f}[User caption]: ${m}`})}else f&&l.push({type:"text",text:`${f}(document, no caption)`});if(a==="text"){let m=s??"document",g=c.toString("utf8");l.push({type:"text",text:`\u{1F4CE} Document: ${m}
|
|
1351
1351
|
|
|
1352
|
-
${g}`})}else{let m=c.toString("base64");l.push({type:"document",source:{type:"base64",media_type:"application/pdf",data:m}})}return l}function jX(t){return t.length<3?null:t.length>=4&&t[0]===137&&t[1]===80&&t[2]===78&&t[3]===71?"image/png":t[0]===71&&t[1]===73&&t[2]===70?"image/gif":t.length>=12&&t[0]===82&&t[1]===73&&t[2]===70&&t[3]===70&&t[8]===87&&t[9]===69&&t[10]===66&&t[11]===80?"image/webp":t[0]===255&&t[1]===216&&t[2]===255?"image/jpeg":null}async function HX(t,e){let n=t.headers.get("content-length");if(n!=null){let a=Number(n);if(Number.isFinite(a)&&a>e)return{status:"too-large",bytesRead:a}}let r=t.body;if(!r)return{status:"missing-body"};let o=r.getReader(),s=[],i=0;try{for(;;){let{done:a,value:c}=await o.read();if(a)break;if(i+=c.byteLength,i>e)return await o.cancel().catch(()=>{}),{status:"too-large",bytesRead:i};s.push(Buffer.from(c))}}finally{o.releaseLock()}return{status:"ok",bytes:Buffer.concat(s,i)}}function gm(t,e,n,r,o){if(n!==void 0&&n===r)return!0;if(!e||e.length===0)return!1;let s=o?`@${o.toLowerCase()}`:void 0;for(let i of e){if(i.type==="text_mention"){if(i.user?.id===r)return!0;continue}if(i.type==="mention"&&s&&t!==void 0&&t.slice(i.offset,i.offset+i.length).toLowerCase()===s)return!0}return!1}var _l=class t{static MAX_QUEUE_DEPTH=5;sessionManager;messageQueues=new Map;registeredCommandChats;log;bot;claimedChats=new Map;reserveClaim(e){this.claimedChats.set(e,(this.claimedChats.get(e)??0)+1)}releaseClaim(e){let n=(this.claimedChats.get(e)??0)-1;n<=0?this.claimedChats.delete(e):this.claimedChats.set(e,n)}isClaimed(e){return(this.claimedChats.get(e)??0)>0}pendingElicitations=new Map;ledgerOriginatedPendingChats=new Set;tagOnlyChats;constructor(e,n,r,o,s=new Set){this.bot=e,this.sessionManager=n,this.registeredCommandChats=r,this.log=o,this.tagOnlyChats=s}async handlePhoto(e){let n=V(e),r=n?.chatId,o=e.message,s=o?.photo;if(!n||!r||!s?.length){this.log(`Photo handling: missing chatId or photo array for chat ${r??"(unknown)"}`);return}if(this.tagOnlyChats.has(r)){let d=e.botInfo?.id;if(d===void 0){this.log(`[tag-only] Dropping photo in chat ${r}: bot identity unknown (botInfo missing)`);return}if(!gm(o?.caption,o?.caption_entities,o?.reply_to_message?.from?.id,d,e.botInfo?.username)){this.log(`[tag-only] Dropping un-addressed photo in chat ${r}`);return}}this.log(`\u{1F4F7} Photo from chat ID: ${r}`),await e.react?.("\u{1F440}").catch(()=>{});let i=s[s.length-1];if(!i){this.log(`Photo handling: empty photo array for chat ${r}`);return}let a=5*1024*1024;if(i.file_size!=null&&i.file_size>a){this.log(`Photo handling: oversized file (${i.file_size} bytes) rejected for chat ${r}`),await e.reply("\u274C Image is too large (max 5 MB). Please send a smaller photo.");return}let c=o?.caption,l=!1;try{l=this.isClaimed(j(n)),l||this.reserveClaim(j(n));let d=await this.sessionManager.getSession(n);if(Tl(this.bot,r,d,this.registeredCommandChats,this.log).catch(S=>this.log("Failed to register chat commands:",S)),(d.state!=="idle"||l)&&(this.messageQueues.get(j(n))?.length??0)>=t.MAX_QUEUE_DEPTH){await e.reply("\u23F3 Queue full. Please wait for your messages to be processed.");return}let u=await e.telegram.getFileLink(i.file_id),p=u instanceof URL?u:new URL(String(u));if(p.protocol!=="https:"||p.hostname!=="api.telegram.org"||p.port!==""&&p.port!=="443"){this.log(`Photo handling: unexpected file URL (protocol=${p.protocol} hostname=${p.hostname}) rejected for chat ${r}`),await e.reply("\u274C Couldn't download the image. Please try resending.");return}let f=await globalThis.fetch(p.href,{signal:AbortSignal.timeout(15e3),redirect:"error"});if(!f.ok){this.log(`Photo handling: fetch failed with status ${f.status} for chat ${r}`),await e.reply("\u274C Couldn't download the image. Please try resending.");return}let m=await HX(f,a);if(m.status==="too-large"){this.log(`Photo handling: downloaded file (${m.bytesRead} bytes) exceeds limit for chat ${r}`),await e.reply("\u274C Image is too large (max 5 MB). Please send a smaller photo.");return}if(m.status==="missing-body"){this.log(`Photo handling: fetch response had no body for chat ${r}`),await e.reply("\u274C Couldn't download the image. Please try resending.");return}let g=m.bytes,h=["image/jpeg","image/png","image/gif","image/webp"],y=f.headers.get("content-type")??"",w=(y.split(";")[0]?.trim()??"").toLowerCase(),k;if(h.includes(w))k=w;else{let S=jX(g);if(S!==null)this.log(`Photo: sniffed ${S} (Content-Type was "${y}") for chat ${r}`),k=S;else{this.log(`Photo: unrecognised image format for chat ${r} (Content-Type: "${y}")`),await e.reply("\u274C Unsupported image format. Please send a JPEG, PNG, GIF, or WebP.");return}}let v=$r(o?.from,e.chat?.type),_=Is({replyToMessage:o?.reply_to_message,quote:o?.quote,botId:e.botInfo?.id}),R=Cs(o??{}),A=_+R+v,M=[];if(c!=null?M.push({type:"text",text:`${A}[User caption]: ${[...c].slice(0,1024).join("")}`}):A&&M.push({type:"text",text:`${A}(image, no caption)`}),await d.waitForInitialization(),d.sessionId===void 0)throw new Error("Telegram session initialized without a session id");if(await QT(M,d.sessionId,[{mediaType:k,bytes:g}]),d.state!=="idle"||l){let S=this.enqueuePhoto(n,e,M);S!==!1&&await e.reply(Ro(S));return}await this.processOne(n,e,M)}catch(d){let p=(d instanceof Error?d.message:String(d)).replace(/\/bot[^/]+\//g,"/bot[REDACTED]/");this.log("Photo handling error:",p),bl(d)?await e.reply("\u274C Couldn't reach Telegram to fetch that image. Please try resending."):Lr(d)?await e.reply("\u23F3 Rate limit reached. Please wait a moment and try again."):Nr(d)?await e.reply("\u274C Couldn't download the image. Please try resending."):await e.reply(Xi())}finally{l||this.releaseClaim(j(n))}}async handleDocument(e){let n=V(e);if(!n)return;let r=n.chatId;if(this.tagOnlyChats.has(r)){let i=e.botInfo?.id;if(i===void 0){this.log(`[tag-only] Dropping document in chat ${r}: bot identity unknown (botInfo missing)`);return}let a=e.message;if(!gm(a?.caption,a?.caption_entities,a?.reply_to_message?.from?.id,i,e.botInfo?.username)){this.log(`[tag-only] Dropping un-addressed document in chat ${r}`);return}}let o=j(n),s=!1;try{s=this.isClaimed(o),s||this.reserveClaim(o);let i=await this.sessionManager.getSession(n);if(Tl(this.bot,n.chatId,i,this.registeredCommandChats,this.log).catch(c=>this.log("Failed to register chat commands:",c)),(i.state!=="idle"||s)&&(this.messageQueues.get(o)?.length??0)>=t.MAX_QUEUE_DEPTH){await e.reply("\u23F3 Queue full. Please wait for your messages to be processed.");return}let a=await jR(e,this.log);if(a===null)return;if(i.state!=="idle"||s){let c=this.enqueueDocument(n,e,a);c!==!1&&await e.reply(Ro(c));return}await this.processOne(n,e,a)}catch(i){let a=i instanceof Error?i.message:String(i);this.log("Document handling error:",a.replace(/\/bot[^/]+\//g,"/bot[REDACTED]/")),await e.reply("\u274C An error occurred processing your document. Please try again.")}finally{s||this.releaseClaim(o)}}async handle(e){let n=V(e),r=n?.chatId,o=e.message.text;if(!n||!r||!o)return;let s=j(n);if(this.log(`\u{1F4EC} Message from chat ID: ${r}`),o.startsWith("/"))return;let i=e.message,a=Is({replyToMessage:i.reply_to_message,quote:i.quote,botId:e.botInfo?.id}),c=Cs(i),l=a+c+$r(i.from,e.chat?.type)+o,d=$r(i.from,e.chat?.type)+o,u=this.pendingElicitations.get(s);if(u){if(this.ledgerOriginatedPendingChats.has(s)){this.pendingElicitations.delete(s),this.ledgerOriginatedPendingChats.delete(s),u(d);return}let f=this.sessionManager.getSessionIfExists(n);if(f&&f.state!=="idle"){this.pendingElicitations.delete(s),u(d);return}this.log("[message] dropping stale pendingElicitation for route",s),this.pendingElicitations.delete(s)}if(this.tagOnlyChats.has(r)){let f=e.botInfo?.id;if(f===void 0){this.log(`[tag-only] Dropping message in chat ${r}: bot identity unknown (botInfo missing)`);return}let m=e.message;if(!gm(m.text,m.entities,m.reply_to_message?.from?.id,f,e.botInfo?.username)){this.log(`[tag-only] Dropping un-addressed message in chat ${r}`);return}}let p=!1;try{await e.react?.("\u{1F440}").catch(()=>{}),p=this.isClaimed(j(n)),p||this.reserveClaim(j(n));let f=await this.sessionManager.getSession(n);Tl(this.bot,r,f,this.registeredCommandChats,this.log).catch(g=>this.log("Failed to register chat commands:",g));let m=l;if(f.state!=="idle"||p){let g=this.enqueueMessage(n,e,m);g!==!1&&await e.reply(Ro(g));return}await this.processOne(n,e,m)}catch(f){this.log("Message handling error:",f),bl(f)||(Lr(f)?await e.reply("\u23F3 Rate limit reached. Please wait a moment and try again."):Nr(f)?await e.reply("\u{1F310} Network error. Please check your connection and try again."):await e.reply(Xi()))}finally{p||this.releaseClaim(j(n))}}async processClearDirect(e,n){this.reserveClaim(j(e));try{await this.sessionManager.resetSession(e),this.registeredCommandChats.delete(e.chatId),await n.reply(Co())}catch(r){this.log("Clear error:",r),await n.reply($(r))}finally{this.releaseClaim(j(e))}}async processCompactDirect(e,n){this.reserveClaim(j(e));let r=!1;try{let o=await this.sessionManager.getSession(e),s=o.hookRegistry,i=await As(n,async()=>(s&&await s.dispatch({event:"PreCompact",sessionId:o.sessionId,trigger:"manual"}),o.compact()));if(i.reason==="session-busy"){this.enqueueCompact(e,n),r=!0;return}i.reason==="microcompacted"&&i.microcompaction?await n.reply(fb(i.microcompaction)):i.compacted?await n.reply(Po({before:i.messagesBefore,after:i.messagesAfter,...i.tokensSavedEstimate!==void 0?{tokensSavedEstimate:i.tokensSavedEstimate}:{}})):await n.reply(Mo(i.reason??"unknown"))}catch(o){o instanceof q?await n.reply(`Compaction skipped: ${Ce(o.reason??"blocked by hook")}`):(this.log("Compact error (queued):",o),await n.reply($(o)))}finally{r||this.drainQueue(e).catch(o=>this.log("Drain error:",o)),this.releaseClaim(j(e))}}queueFor(e){let n=j(e),r=this.messageQueues.get(n);return r||(r=[],this.messageQueues.set(n,r)),r}enqueueMessage(e,n,r){let o=this.queueFor(e);return o.length>=t.MAX_QUEUE_DEPTH?(n.reply("\u23F3 Queue full. Please wait for your messages to be processed.").catch(()=>{}),!1):(o.push({type:"message",ctx:n,text:r}),o.length)}enqueuePhoto(e,n,r){let o=this.queueFor(e);return o.length>=t.MAX_QUEUE_DEPTH?(n.reply("\u23F3 Queue full. Please wait for your messages to be processed.").catch(()=>{}),!1):(o.push({type:"photo",ctx:n,content:r}),o.length)}enqueueDocument(e,n,r){let o=this.queueFor(e);return o.length>=t.MAX_QUEUE_DEPTH?(n.reply("\u23F3 Queue full. Please wait for your messages to be processed.").catch(()=>{}),!1):(o.push({type:"document",ctx:n,content:r}),o.length)}enqueueClear(e,n){let r=this.queueFor(e);if(r.length>=t.MAX_QUEUE_DEPTH){n.reply("\u23F3 Queue full. Please wait for your messages to be processed.").catch(()=>{});return}r.push({type:"clear",ctx:n})}enqueueCompact(e,n){let r=this.queueFor(e);if(r.length>=t.MAX_QUEUE_DEPTH){n.reply("\u23F3 Queue full. Please wait for your messages to be processed.").catch(()=>{});return}r.push({type:"compact",ctx:n})}async processOne(e,n,r){this.reserveClaim(j(e));let o=!1;try{let s=await this.sessionManager.getSession(e),i=typeof r=="string"?r:r.map(a=>a.type==="text"?a.text:a.type==="document"?`[document: ${a.title??"file"}]`:"[image]").join(" ");await As(n,()=>fm(n,s,r,this.log,{cleanFinal:!0,onComplete:(a,c)=>{this.sessionManager.recordTelegramTurn(e,i,a,c)}}))}catch(s){if(this.log("Message handling error:",s),(s?.message??"").includes("session is busy")){let a=typeof r=="string"?this.enqueueMessage(e,n,r):r.some(c=>c.type==="document")?this.enqueueDocument(e,n,r):this.enqueuePhoto(e,n,r);a!==!1&&await n.reply(Ro(a)),o=!0;return}s instanceof In?await n.reply(`\u23F1\uFE0F ${s.message}`):bl(s)||(Lr(s)?await n.reply("\u23F3 Rate limit reached. Please wait a moment and try again."):Nr(s)?await n.reply("\u{1F310} Network error. Please check your connection and try again."):await n.reply(Xi()))}finally{o||this.drainQueue(e).catch(s=>this.log("Drain error:",s)),this.releaseClaim(j(e))}}async drainQueue(e){let n=j(e),r=this.messageQueues.get(n);if(!r?.length)return;let o=r.shift();r.length===0&&this.messageQueues.delete(n),o.type==="message"?await this.processOne(e,o.ctx,o.text):o.type==="photo"||o.type==="document"?await this.processOne(e,o.ctx,o.content):o.type==="compact"?await this.processCompactDirect(e,o.ctx):await this.processClearDirect(e,o.ctx)}};import{Markup as Os}from"telegraf";var Ps="afk:e:";var El=/^[a-zA-Z0-9_-]{1,48}$/;function Al(t,e){if(!El.test(t))throw new Error(`buildElicitationCallback: invalid id ${JSON.stringify(t)}`);if(!Number.isInteger(e)||e<0)throw new Error(`buildElicitationCallback: choiceIndex must be a non-negative integer, got ${e}`);let n=`${Ps}${e}:${t}`,r=Buffer.byteLength(n,"utf8");if(r>64)throw new Error(`buildElicitationCallback: payload ${r} bytes exceeds Telegram's 64-byte limit (id=${t})`);return n}function HR(t){if(!t||!t.startsWith(Ps)||Buffer.byteLength(t,"utf8")>64)return null;let e=t.slice(Ps.length),n=e.indexOf(":");if(n<1)return null;let r=e.slice(0,n),o=e.slice(n+1),s=parseInt(r,10);return!Number.isInteger(s)||s<0||String(s)!==r||!El.test(o)?null:{id:o,choiceIndex:s}}var Ms="afk:ec:";function WR(t){if(!El.test(t))throw new Error(`buildCustomElicitationCallback: invalid id ${JSON.stringify(t)}`);let e=`${Ms}${t}`,n=Buffer.byteLength(e,"utf8");if(n>64)throw new Error(`buildCustomElicitationCallback: ${n} bytes exceeds 64-byte limit`);return e}function KR(t){if(!t||!t.startsWith(Ms)||Buffer.byteLength(t,"utf8")>64)return null;let e=t.slice(Ms.length);return El.test(e)?e:null}import{randomBytes as WX}from"node:crypto";function KX(){return`elic-${WX(8).toString("hex")}`}var qR=-1;function qX(t,e=64){if(Buffer.byteLength(t,"utf8")<=e)return t;let n=Buffer.from(t,"utf8").subarray(0,e);return new TextDecoder("utf-8",{fatal:!1}).decode(n).replace(/\uFFFD$/,"")}function xl(t,e,n,r){let o=()=>typeof n=="function"?n():typeof n=="number"?{chatId:n}:n,s=r?.ledgerOriginated??!1,i=new Map,a=new RegExp(`^${Pe(Ps)}\\d+:.+$`);e.action(a,async l=>{await l.answerCbQuery().catch(()=>{});let d=typeof l.callbackQuery=="object"&&"data"in l.callbackQuery?l.callbackQuery.data:void 0,u=HR(d);if(!u)return;let p=i.get(u.id);p&&l.chat?.id===p.chatId&&p.resolve(u.choiceIndex)});let c=new RegExp(`^${Pe(Ms)}.+$`);return e.action(c,async l=>{await l.answerCbQuery().catch(()=>{});let d=typeof l.callbackQuery=="object"&&"data"in l.callbackQuery?l.callbackQuery.data:void 0,u=KR(d);if(!u)return;let p=i.get(u);p&&l.chat?.id===p.chatId&&p.resolve(qR)}),async(l,d)=>{if(d.signal.aborted)return{action:"decline"};let u=(d.sessionId!==void 0?al(d.sessionId):void 0)??o(),p=u.chatId,f=j(u),m=tn(u);function g(v){t.pendingElicitations.set(f,v),s&&t.ledgerOriginatedPendingChats.add(f)}function h(){t.pendingElicitations.delete(f),s&&t.ledgerOriginatedPendingChats.delete(f)}let y=l.type??"text",w=l.message,k=`\u{1F4AC} <b>Question from agent</b>
|
|
1352
|
+
${g}`})}else{let m=c.toString("base64");l.push({type:"document",source:{type:"base64",media_type:"application/pdf",data:m}})}return l}function HX(t){return t.length<3?null:t.length>=4&&t[0]===137&&t[1]===80&&t[2]===78&&t[3]===71?"image/png":t[0]===71&&t[1]===73&&t[2]===70?"image/gif":t.length>=12&&t[0]===82&&t[1]===73&&t[2]===70&&t[3]===70&&t[8]===87&&t[9]===69&&t[10]===66&&t[11]===80?"image/webp":t[0]===255&&t[1]===216&&t[2]===255?"image/jpeg":null}async function WX(t,e){let n=t.headers.get("content-length");if(n!=null){let a=Number(n);if(Number.isFinite(a)&&a>e)return{status:"too-large",bytesRead:a}}let r=t.body;if(!r)return{status:"missing-body"};let o=r.getReader(),s=[],i=0;try{for(;;){let{done:a,value:c}=await o.read();if(a)break;if(i+=c.byteLength,i>e)return await o.cancel().catch(()=>{}),{status:"too-large",bytesRead:i};s.push(Buffer.from(c))}}finally{o.releaseLock()}return{status:"ok",bytes:Buffer.concat(s,i)}}function gm(t,e,n,r,o){if(n!==void 0&&n===r)return!0;if(!e||e.length===0)return!1;let s=o?`@${o.toLowerCase()}`:void 0;for(let i of e){if(i.type==="text_mention"){if(i.user?.id===r)return!0;continue}if(i.type==="mention"&&s&&t!==void 0&&t.slice(i.offset,i.offset+i.length).toLowerCase()===s)return!0}return!1}var _l=class t{static MAX_QUEUE_DEPTH=5;sessionManager;messageQueues=new Map;registeredCommandChats;log;bot;claimedChats=new Map;reserveClaim(e){this.claimedChats.set(e,(this.claimedChats.get(e)??0)+1)}releaseClaim(e){let n=(this.claimedChats.get(e)??0)-1;n<=0?this.claimedChats.delete(e):this.claimedChats.set(e,n)}isClaimed(e){return(this.claimedChats.get(e)??0)>0}pendingElicitations=new Map;ledgerOriginatedPendingChats=new Set;tagOnlyChats;constructor(e,n,r,o,s=new Set){this.bot=e,this.sessionManager=n,this.registeredCommandChats=r,this.log=o,this.tagOnlyChats=s}async handlePhoto(e){let n=V(e),r=n?.chatId,o=e.message,s=o?.photo;if(!n||!r||!s?.length){this.log(`Photo handling: missing chatId or photo array for chat ${r??"(unknown)"}`);return}if(this.tagOnlyChats.has(r)){let d=e.botInfo?.id;if(d===void 0){this.log(`[tag-only] Dropping photo in chat ${r}: bot identity unknown (botInfo missing)`);return}if(!gm(o?.caption,o?.caption_entities,o?.reply_to_message?.from?.id,d,e.botInfo?.username)){this.log(`[tag-only] Dropping un-addressed photo in chat ${r}`);return}}this.log(`\u{1F4F7} Photo from chat ID: ${r}`),await e.react?.("\u{1F440}").catch(()=>{});let i=s[s.length-1];if(!i){this.log(`Photo handling: empty photo array for chat ${r}`);return}let a=5*1024*1024;if(i.file_size!=null&&i.file_size>a){this.log(`Photo handling: oversized file (${i.file_size} bytes) rejected for chat ${r}`),await e.reply("\u274C Image is too large (max 5 MB). Please send a smaller photo.");return}let c=o?.caption,l=!1;try{l=this.isClaimed(j(n)),l||this.reserveClaim(j(n));let d=await this.sessionManager.getSession(n);if(Tl(this.bot,r,d,this.registeredCommandChats,this.log).catch(S=>this.log("Failed to register chat commands:",S)),(d.state!=="idle"||l)&&(this.messageQueues.get(j(n))?.length??0)>=t.MAX_QUEUE_DEPTH){await e.reply("\u23F3 Queue full. Please wait for your messages to be processed.");return}let u=await e.telegram.getFileLink(i.file_id),p=u instanceof URL?u:new URL(String(u));if(p.protocol!=="https:"||p.hostname!=="api.telegram.org"||p.port!==""&&p.port!=="443"){this.log(`Photo handling: unexpected file URL (protocol=${p.protocol} hostname=${p.hostname}) rejected for chat ${r}`),await e.reply("\u274C Couldn't download the image. Please try resending.");return}let f=await globalThis.fetch(p.href,{signal:AbortSignal.timeout(15e3),redirect:"error"});if(!f.ok){this.log(`Photo handling: fetch failed with status ${f.status} for chat ${r}`),await e.reply("\u274C Couldn't download the image. Please try resending.");return}let m=await WX(f,a);if(m.status==="too-large"){this.log(`Photo handling: downloaded file (${m.bytesRead} bytes) exceeds limit for chat ${r}`),await e.reply("\u274C Image is too large (max 5 MB). Please send a smaller photo.");return}if(m.status==="missing-body"){this.log(`Photo handling: fetch response had no body for chat ${r}`),await e.reply("\u274C Couldn't download the image. Please try resending.");return}let g=m.bytes,h=["image/jpeg","image/png","image/gif","image/webp"],y=f.headers.get("content-type")??"",w=(y.split(";")[0]?.trim()??"").toLowerCase(),k;if(h.includes(w))k=w;else{let S=HX(g);if(S!==null)this.log(`Photo: sniffed ${S} (Content-Type was "${y}") for chat ${r}`),k=S;else{this.log(`Photo: unrecognised image format for chat ${r} (Content-Type: "${y}")`),await e.reply("\u274C Unsupported image format. Please send a JPEG, PNG, GIF, or WebP.");return}}let v=$r(o?.from,e.chat?.type),_=Is({replyToMessage:o?.reply_to_message,quote:o?.quote,botId:e.botInfo?.id}),R=Cs(o??{}),A=_+R+v,M=[];if(c!=null?M.push({type:"text",text:`${A}[User caption]: ${[...c].slice(0,1024).join("")}`}):A&&M.push({type:"text",text:`${A}(image, no caption)`}),await d.waitForInitialization(),d.sessionId===void 0)throw new Error("Telegram session initialized without a session id");if(await QT(M,d.sessionId,[{mediaType:k,bytes:g}]),d.state!=="idle"||l){let S=this.enqueuePhoto(n,e,M);S!==!1&&await e.reply(Ro(S));return}await this.processOne(n,e,M)}catch(d){let p=(d instanceof Error?d.message:String(d)).replace(/\/bot[^/]+\//g,"/bot[REDACTED]/");this.log("Photo handling error:",p),bl(d)?await e.reply("\u274C Couldn't reach Telegram to fetch that image. Please try resending."):Lr(d)?await e.reply("\u23F3 Rate limit reached. Please wait a moment and try again."):Nr(d)?await e.reply("\u274C Couldn't download the image. Please try resending."):await e.reply(Xi())}finally{l||this.releaseClaim(j(n))}}async handleDocument(e){let n=V(e);if(!n)return;let r=n.chatId;if(this.tagOnlyChats.has(r)){let i=e.botInfo?.id;if(i===void 0){this.log(`[tag-only] Dropping document in chat ${r}: bot identity unknown (botInfo missing)`);return}let a=e.message;if(!gm(a?.caption,a?.caption_entities,a?.reply_to_message?.from?.id,i,e.botInfo?.username)){this.log(`[tag-only] Dropping un-addressed document in chat ${r}`);return}}let o=j(n),s=!1;try{s=this.isClaimed(o),s||this.reserveClaim(o);let i=await this.sessionManager.getSession(n);if(Tl(this.bot,n.chatId,i,this.registeredCommandChats,this.log).catch(c=>this.log("Failed to register chat commands:",c)),(i.state!=="idle"||s)&&(this.messageQueues.get(o)?.length??0)>=t.MAX_QUEUE_DEPTH){await e.reply("\u23F3 Queue full. Please wait for your messages to be processed.");return}let a=await jR(e,this.log);if(a===null)return;if(i.state!=="idle"||s){let c=this.enqueueDocument(n,e,a);c!==!1&&await e.reply(Ro(c));return}await this.processOne(n,e,a)}catch(i){let a=i instanceof Error?i.message:String(i);this.log("Document handling error:",a.replace(/\/bot[^/]+\//g,"/bot[REDACTED]/")),await e.reply("\u274C An error occurred processing your document. Please try again.")}finally{s||this.releaseClaim(o)}}async handle(e){let n=V(e),r=n?.chatId,o=e.message.text;if(!n||!r||!o)return;let s=j(n);if(this.log(`\u{1F4EC} Message from chat ID: ${r}`),o.startsWith("/"))return;let i=e.message,a=Is({replyToMessage:i.reply_to_message,quote:i.quote,botId:e.botInfo?.id}),c=Cs(i),l=a+c+$r(i.from,e.chat?.type)+o,d=$r(i.from,e.chat?.type)+o,u=this.pendingElicitations.get(s);if(u){if(this.ledgerOriginatedPendingChats.has(s)){this.pendingElicitations.delete(s),this.ledgerOriginatedPendingChats.delete(s),u(d);return}let f=this.sessionManager.getSessionIfExists(n);if(f&&f.state!=="idle"){this.pendingElicitations.delete(s),u(d);return}this.log("[message] dropping stale pendingElicitation for route",s),this.pendingElicitations.delete(s)}if(this.tagOnlyChats.has(r)){let f=e.botInfo?.id;if(f===void 0){this.log(`[tag-only] Dropping message in chat ${r}: bot identity unknown (botInfo missing)`);return}let m=e.message;if(!gm(m.text,m.entities,m.reply_to_message?.from?.id,f,e.botInfo?.username)){this.log(`[tag-only] Dropping un-addressed message in chat ${r}`);return}}let p=!1;try{await e.react?.("\u{1F440}").catch(()=>{}),p=this.isClaimed(j(n)),p||this.reserveClaim(j(n));let f=await this.sessionManager.getSession(n);Tl(this.bot,r,f,this.registeredCommandChats,this.log).catch(g=>this.log("Failed to register chat commands:",g));let m=l;if(f.state!=="idle"||p){let g=this.enqueueMessage(n,e,m);g!==!1&&await e.reply(Ro(g));return}await this.processOne(n,e,m)}catch(f){this.log("Message handling error:",f),bl(f)||(Lr(f)?await e.reply("\u23F3 Rate limit reached. Please wait a moment and try again."):Nr(f)?await e.reply("\u{1F310} Network error. Please check your connection and try again."):await e.reply(Xi()))}finally{p||this.releaseClaim(j(n))}}async processClearDirect(e,n){this.reserveClaim(j(e));try{await this.sessionManager.resetSession(e),this.registeredCommandChats.delete(e.chatId),await n.reply(Co())}catch(r){this.log("Clear error:",r),await n.reply($(r))}finally{this.releaseClaim(j(e))}}async processCompactDirect(e,n){this.reserveClaim(j(e));let r=!1;try{let o=await this.sessionManager.getSession(e),s=o.hookRegistry,i=await As(n,async()=>(s&&await s.dispatch({event:"PreCompact",sessionId:o.sessionId,trigger:"manual"}),o.compact()));if(i.reason==="session-busy"){this.enqueueCompact(e,n),r=!0;return}i.reason==="microcompacted"&&i.microcompaction?await n.reply(fb(i.microcompaction)):i.compacted?await n.reply(Po({before:i.messagesBefore,after:i.messagesAfter,...i.tokensSavedEstimate!==void 0?{tokensSavedEstimate:i.tokensSavedEstimate}:{}})):await n.reply(Mo(i.reason??"unknown"))}catch(o){o instanceof q?await n.reply(`Compaction skipped: ${Ce(o.reason??"blocked by hook")}`):(this.log("Compact error (queued):",o),await n.reply($(o)))}finally{r||this.drainQueue(e).catch(o=>this.log("Drain error:",o)),this.releaseClaim(j(e))}}queueFor(e){let n=j(e),r=this.messageQueues.get(n);return r||(r=[],this.messageQueues.set(n,r)),r}enqueueMessage(e,n,r){let o=this.queueFor(e);return o.length>=t.MAX_QUEUE_DEPTH?(n.reply("\u23F3 Queue full. Please wait for your messages to be processed.").catch(()=>{}),!1):(o.push({type:"message",ctx:n,text:r}),o.length)}enqueuePhoto(e,n,r){let o=this.queueFor(e);return o.length>=t.MAX_QUEUE_DEPTH?(n.reply("\u23F3 Queue full. Please wait for your messages to be processed.").catch(()=>{}),!1):(o.push({type:"photo",ctx:n,content:r}),o.length)}enqueueDocument(e,n,r){let o=this.queueFor(e);return o.length>=t.MAX_QUEUE_DEPTH?(n.reply("\u23F3 Queue full. Please wait for your messages to be processed.").catch(()=>{}),!1):(o.push({type:"document",ctx:n,content:r}),o.length)}enqueueClear(e,n){let r=this.queueFor(e);if(r.length>=t.MAX_QUEUE_DEPTH){n.reply("\u23F3 Queue full. Please wait for your messages to be processed.").catch(()=>{});return}r.push({type:"clear",ctx:n})}enqueueCompact(e,n){let r=this.queueFor(e);if(r.length>=t.MAX_QUEUE_DEPTH){n.reply("\u23F3 Queue full. Please wait for your messages to be processed.").catch(()=>{});return}r.push({type:"compact",ctx:n})}async processOne(e,n,r){this.reserveClaim(j(e));let o=!1;try{let s=await this.sessionManager.getSession(e),i=typeof r=="string"?r:r.map(a=>a.type==="text"?a.text:a.type==="document"?`[document: ${a.title??"file"}]`:"[image]").join(" ");await As(n,()=>fm(n,s,r,this.log,{cleanFinal:!0,onComplete:(a,c)=>{this.sessionManager.recordTelegramTurn(e,i,a,c)}}))}catch(s){if(this.log("Message handling error:",s),(s?.message??"").includes("session is busy")){let a=typeof r=="string"?this.enqueueMessage(e,n,r):r.some(c=>c.type==="document")?this.enqueueDocument(e,n,r):this.enqueuePhoto(e,n,r);a!==!1&&await n.reply(Ro(a)),o=!0;return}s instanceof In?await n.reply(`\u23F1\uFE0F ${s.message}`):bl(s)||(Lr(s)?await n.reply("\u23F3 Rate limit reached. Please wait a moment and try again."):Nr(s)?await n.reply("\u{1F310} Network error. Please check your connection and try again."):await n.reply(Xi()))}finally{o||this.drainQueue(e).catch(s=>this.log("Drain error:",s)),this.releaseClaim(j(e))}}async drainQueue(e){let n=j(e),r=this.messageQueues.get(n);if(!r?.length)return;let o=r.shift();r.length===0&&this.messageQueues.delete(n),o.type==="message"?await this.processOne(e,o.ctx,o.text):o.type==="photo"||o.type==="document"?await this.processOne(e,o.ctx,o.content):o.type==="compact"?await this.processCompactDirect(e,o.ctx):await this.processClearDirect(e,o.ctx)}};import{Markup as Os}from"telegraf";var Ps="afk:e:";var El=/^[a-zA-Z0-9_-]{1,48}$/;function Al(t,e){if(!El.test(t))throw new Error(`buildElicitationCallback: invalid id ${JSON.stringify(t)}`);if(!Number.isInteger(e)||e<0)throw new Error(`buildElicitationCallback: choiceIndex must be a non-negative integer, got ${e}`);let n=`${Ps}${e}:${t}`,r=Buffer.byteLength(n,"utf8");if(r>64)throw new Error(`buildElicitationCallback: payload ${r} bytes exceeds Telegram's 64-byte limit (id=${t})`);return n}function HR(t){if(!t||!t.startsWith(Ps)||Buffer.byteLength(t,"utf8")>64)return null;let e=t.slice(Ps.length),n=e.indexOf(":");if(n<1)return null;let r=e.slice(0,n),o=e.slice(n+1),s=parseInt(r,10);return!Number.isInteger(s)||s<0||String(s)!==r||!El.test(o)?null:{id:o,choiceIndex:s}}var Ms="afk:ec:";function WR(t){if(!El.test(t))throw new Error(`buildCustomElicitationCallback: invalid id ${JSON.stringify(t)}`);let e=`${Ms}${t}`,n=Buffer.byteLength(e,"utf8");if(n>64)throw new Error(`buildCustomElicitationCallback: ${n} bytes exceeds 64-byte limit`);return e}function KR(t){if(!t||!t.startsWith(Ms)||Buffer.byteLength(t,"utf8")>64)return null;let e=t.slice(Ms.length);return El.test(e)?e:null}import{randomBytes as KX}from"node:crypto";function qX(){return`elic-${KX(8).toString("hex")}`}var qR=-1;function GX(t,e=64){if(Buffer.byteLength(t,"utf8")<=e)return t;let n=Buffer.from(t,"utf8").subarray(0,e);return new TextDecoder("utf-8",{fatal:!1}).decode(n).replace(/\uFFFD$/,"")}function xl(t,e,n,r){let o=()=>typeof n=="function"?n():typeof n=="number"?{chatId:n}:n,s=r?.ledgerOriginated??!1,i=new Map,a=new RegExp(`^${Pe(Ps)}\\d+:.+$`);e.action(a,async l=>{await l.answerCbQuery().catch(()=>{});let d=typeof l.callbackQuery=="object"&&"data"in l.callbackQuery?l.callbackQuery.data:void 0,u=HR(d);if(!u)return;let p=i.get(u.id);p&&l.chat?.id===p.chatId&&p.resolve(u.choiceIndex)});let c=new RegExp(`^${Pe(Ms)}.+$`);return e.action(c,async l=>{await l.answerCbQuery().catch(()=>{});let d=typeof l.callbackQuery=="object"&&"data"in l.callbackQuery?l.callbackQuery.data:void 0,u=KR(d);if(!u)return;let p=i.get(u);p&&l.chat?.id===p.chatId&&p.resolve(qR)}),async(l,d)=>{if(d.signal.aborted)return{action:"decline"};let u=(d.sessionId!==void 0?al(d.sessionId):void 0)??o(),p=u.chatId,f=j(u),m=tn(u);function g(v){t.pendingElicitations.set(f,v),s&&t.ledgerOriginatedPendingChats.add(f)}function h(){t.pendingElicitations.delete(f),s&&t.ledgerOriginatedPendingChats.delete(f)}let y=l.type??"text",w=l.message,k=`\u{1F4AC} <b>Question from agent</b>
|
|
1353
1353
|
|
|
1354
1354
|
${Ce(w)}`;if(l.context&&(k=`\u{1F4AC} <b>Question from agent</b>
|
|
1355
1355
|
|
|
1356
1356
|
<i>${Ce(l.context)}</i>
|
|
1357
1357
|
|
|
1358
|
-
${Ce(w)}`),y==="confirm"||y==="choice"){let v=
|
|
1358
|
+
${Ce(w)}`),y==="confirm"||y==="choice"){let v=qX(),_;return y==="confirm"?_=[[Os.button.callback("\u2705 Yes",Al(v,1)),Os.button.callback("\u274C No",Al(v,0))]]:(_=(l.choices??[]).slice(0,20).map((M,S)=>[Os.button.callback(GX(M),Al(v,S))]),l.allowCustom&&_.push([Os.button.callback("\u270D\uFE0F Type a custom answer",WR(v))])),new Promise(R=>{let A=!1,M=!1,S=()=>{A||(A=!0,i.delete(v),M&&h(),R({action:"decline"}))};d.signal.addEventListener("abort",S,{once:!0}),i.set(v,{chatId:p,resolve:T=>{if(!A){if(A=!0,i.delete(v),d.signal.removeEventListener("abort",S),T===qR){if(A=!1,M=!0,e.telegram.sendMessage(p,"\u270D\uFE0F Please type your custom answer:",m).catch(()=>{}),d.signal.aborted){R({action:"decline"});return}g(E=>{if(A)return;A=!0,d.signal.removeEventListener("abort",S);let O=E.trim();if(O===":cancel"){R({action:"cancel"});return}R({action:"accept",content:{value:null,custom_value:O}})}),d.signal.addEventListener("abort",S,{once:!0});return}if(y==="confirm")R({action:"accept",content:{value:T===1}});else{let O=(l.choices??[])[T];R(O===void 0?{action:"decline"}:{action:"accept",content:{value:O}})}}}}),e.telegram.sendMessage(p,k,{parse_mode:"HTML",...m,reply_markup:Os.inlineKeyboard(_).reply_markup}).catch(()=>{A||(A=!0,i.delete(v),d.signal.removeEventListener("abort",S),R({action:"decline"}))})})}return new Promise(v=>{let _=!1,R=()=>{_||(_=!0,t.pendingElicitations.has(f)&&console.warn("[elicitation-handler] abort: cleaning up stale pendingElicitation for route",f),h(),v({action:"decline"}))};d.signal.addEventListener("abort",R,{once:!0});let A=!0;function M(T){if(_)return;_=!0,d.signal.removeEventListener("abort",R);let E=T.trim();if(E===":cancel"){v({action:"cancel"});return}if(E===""&&l.allowSkip){v({action:"skip"});return}if(y==="number"){if(E===""&&!l.allowSkip){if(_=!1,A=!1,e.telegram.sendMessage(p,"\u274C Please enter a number.",m).catch(()=>{}),d.signal.aborted)return;g(M),d.signal.addEventListener("abort",R,{once:!0});return}let O=Number(E);if(!isFinite(O)){if(_=!1,A=!1,e.telegram.sendMessage(p,"\u274C Please enter a valid number.",m).catch(()=>{}),d.signal.aborted)return;g(M),d.signal.addEventListener("abort",R,{once:!0});return}if(l.min!==void 0&&O<l.min){if(_=!1,A=!1,e.telegram.sendMessage(p,`\u274C Value must be \u2265 ${l.min}.`,m).catch(()=>{}),d.signal.aborted)return;g(M),d.signal.addEventListener("abort",R,{once:!0});return}if(l.max!==void 0&&O>l.max){if(_=!1,A=!1,e.telegram.sendMessage(p,`\u274C Value must be \u2264 ${l.max}.`,m).catch(()=>{}),d.signal.aborted)return;g(M),d.signal.addEventListener("abort",R,{once:!0});return}v({action:"accept",content:{value:O}});return}if(y==="multi_choice"){let O=l.choices??[];if(l.allowCustom){let L=E.split(",")[0]?.trim()??"",D=parseInt(L,10);if(!(Number.isInteger(D)&&String(D)===L&&D>=1&&D<=O.length)&&E!==""&&E!==":cancel"){v({action:"accept",content:{value:null,custom_value:E}});return}}let K=E.split(",").map(L=>L.trim()),F=[];for(let L of K){let D=parseInt(L,10);if(!Number.isInteger(D)||String(D)!==L||D<1||D>O.length){if(_=!1,A=!1,e.telegram.sendMessage(p,`\u274C Invalid selection. Enter comma-separated numbers between 1 and ${O.length}.`,m).catch(()=>{}),d.signal.aborted)return;g(M),d.signal.addEventListener("abort",R,{once:!0});return}F.push(O[D-1])}v({action:"accept",content:{value:F}});return}if(E===""&&!l.allowSkip){if(_=!1,A=!1,e.telegram.sendMessage(p,"\u274C Please enter a response (or type :cancel to skip).",m).catch(()=>{}),d.signal.aborted)return;g(M),d.signal.addEventListener("abort",R,{once:!0});return}v({action:"accept",content:{value:E}})}g(M);let S=k;if(y==="multi_choice"){let E=(l.choices??[]).map((O,K)=>`${K+1}. ${Ce(O)}`).join(`
|
|
1359
1359
|
`);S+=`
|
|
1360
1360
|
|
|
1361
1361
|
${E}
|
|
@@ -1368,10 +1368,10 @@ Enter a number${T}`}A&&(l.allowSkip?S+=`
|
|
|
1368
1368
|
|
|
1369
1369
|
<i>Enter empty to skip, or :cancel to cancel.</i>`:S+=`
|
|
1370
1370
|
|
|
1371
|
-
<i>Type :cancel to cancel.</i>`),e.telegram.sendMessage(p,S,{parse_mode:"HTML",...m}).catch(()=>{_||(_=!0,d.signal.removeEventListener("abort",R),console.warn("[elicitation-handler] sendMessage failed; declining elicitation for route",f),h(),v({action:"decline"}))})})}}P();var GR="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function XR(t=Date.now()){let e=t,n=new Array(10).fill("0");for(let o=9;o>=0;o--)n[o]=GR[e%32],e=Math.floor(e/32);let r=new Array(16).fill("0");for(let o=0;o<16;o++)r[o]=GR[Math.floor(Math.random()*32)];return n.join("")+r.join("")}var Fs="afk:pa:",
|
|
1371
|
+
<i>Type :cancel to cancel.</i>`),e.telegram.sendMessage(p,S,{parse_mode:"HTML",...m}).catch(()=>{_||(_=!0,d.signal.removeEventListener("abort",R),console.warn("[elicitation-handler] sendMessage failed; declining elicitation for route",f),h(),v({action:"decline"}))})})}}P();var GR="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function XR(t=Date.now()){let e=t,n=new Array(10).fill("0");for(let o=9;o>=0;o--)n[o]=GR[e%32],e=Math.floor(e/32);let r=new Array(16).fill("0");for(let o=0;o<16;o++)r[o]=GR[Math.floor(Math.random()*32)];return n.join("")+r.join("")}var Fs="afk:pa:",XX=64,Ds=new Map;function Rl(t,e,n=()=>{},r){let o=t;if(!o._elicitationRegistered){let s=new RegExp(`^${Pe(Fs)}`);t.action(s,async i=>zX(i,n)),o._elicitationRegistered=!0}return async(s,i)=>{if(i.signal.aborted)return{action:"decline"};let a=i.sessionId!==void 0?al(i.sessionId):void 0;return new Promise(c=>{let l=XR(),d=JX(s);Ds.set(l,{resolve:c,enumValues:d});let u=VX(s),p=YX(l,d),f=Array.from(e).map(async m=>{try{let g=a??r?.(m);await t.telegram.sendMessage(m,u,{reply_markup:p,...g!==void 0?tn(g):{}})}catch(g){n("[elicitation] sendMessage failed:",g)}});Promise.all(f),i.signal.addEventListener("abort",()=>{let m=Ds.get(l);m&&(Ds.delete(l),m.resolve({action:"decline"}))},{once:!0})})}}async function zX(t,e){let n=t.callbackQuery?.data;if(typeof n!="string"||!n.startsWith(Fs)){await t.answerCbQuery("Unknown callback").catch(()=>{});return}let r=n.slice(Fs.length),o=r.indexOf(":");if(o<=0||o===r.length-1){await t.answerCbQuery("Malformed callback").catch(()=>{});return}let s=r.slice(0,o),i=r.slice(o+1),a=Ds.get(s);if(!a){await t.answerCbQuery("This prompt is no longer active.").catch(()=>{});return}if(!a.enumValues.includes(i)){e("[elicitation] callback choice not in enum:",i,a.enumValues),await t.answerCbQuery("Unknown choice").catch(()=>{});return}Ds.delete(s),a.resolve({action:"accept",content:{choice:i}}),await t.answerCbQuery(`Recorded: ${i}`).catch(c=>{e("[elicitation] answerCbQuery failed:",c)})}function JX(t){if(t.mode!=="form")return["accept","decline"];let e=t.requestedSchema;if(typeof e!="object"||e===null)return["accept","decline"];let n=e.properties;if(typeof n!="object"||n===null)return["accept","decline"];let r=Object.keys(n)[0];if(r===void 0)return["accept","decline"];let o=n[r];if(typeof o!="object"||o===null)return["accept","decline"];let s=o.enum;return Array.isArray(s)?s.map(String):["accept","decline"]}function VX(t){let e=[];t.title&&e.push(t.title),e.push(t.message);let n=e.join(`
|
|
1372
1372
|
|
|
1373
|
-
`);return n.length>4e3?n.slice(0,3997)+"...":n}function
|
|
1373
|
+
`);return n.length>4e3?n.slice(0,3997)+"...":n}function YX(t,e){let n=Fs.length+t.length+1,r=XX-n,o=e.map(s=>{let i=s.length<=r?s:s.slice(0,r);return{text:QX(i),callback_data:`${Fs}${t}:${i}`}});return o.length===4?{inline_keyboard:[[o[0],o[1]],[o[2],o[3]]]}:{inline_keyboard:o.map(s=>[s])}}function QX(t){switch(t){case"once":return"\u2705 Once";case"session":return"\u{1F501} Session";case"persist":return"\u{1F4BE} Always";case"deny":return"\u274C Deny";case"accept":return"\u2705 Accept";case"decline":return"\u274C Decline";default:return t.charAt(0).toUpperCase()+t.slice(1)}}function Il(t,e){return(n,r)=>n.type!==void 0?t(n,r):e(n,r)}import*as Cl from"node:fs";P();import{createHmac as ZX,randomBytes as ez,timingSafeEqual as cIe}from"node:crypto";var zR="\0";function tz(t){return JSON.stringify(hm(t))}function hm(t){if(Array.isArray(t))return t.map(hm);if(t!==null&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=hm(e[r]);return n}return t}function Pl(t){let e;try{e=Bm(t)}catch{return null}try{let n=Cl.readFileSync(e,"utf8").trim();return n.length>0?n:null}catch{return null}}function JR(t,e){return ZX("sha256",t).update(e).digest("hex")}function nz(t,e,n){return["elicitation_response",t,e,tz(n)].join(zR)}function VR(t,e,n,r){return JR(t,nz(e,n,r))}function rz(t,e){return["abort_request",t,e].join(zR)}function YR(t,e,n){return JR(t,rz(e,n))}function QR(){return ez(8).toString("hex")}var oz=1500,ZR=700,ym=160,sz=15*6e4,iz=4;function Ls(t,e){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e)}\u2026`:n}function az(t){switch(t.kind){case"meta":return`\u{1F4E1} Watching session ${t.sessionId}
|
|
1374
1374
|
model: ${t.model}${t.cwd?`
|
|
1375
1375
|
cwd: ${t.cwd}`:""}`;case"user":return`\u{1F464} ${Ls(t.text,ZR)}`;case"assistant":return`\u{1F916} ${Ls(t.text,ZR)}`;case"tool":return`\u{1F527} ${t.toolName}(${Ls(t.input,ym)})`;case"tool_error":return`\u26A0\uFE0F tool failed: ${Ls(t.content,ym)}`;case"done":{let e=[];return typeof t.durationMs=="number"&&e.push(`${(t.durationMs/1e3).toFixed(1)}s`),typeof t.costUsd=="number"&&e.push(`$${t.costUsd.toFixed(4)}`),`\u2705 turn done${e.length?` (${e.join(", ")})`:""}`}case"error":return`\u274C error: ${Ls(t.message,ym)}`;case"paused":return`\u23F8\uFE0F paused on usage limit${t.resetsAt?` (resets ${t.resetsAt})`:""}`;case"resumed":return"\u25B6\uFE0F resumed";case"closed":return`\u{1F3C1} session closed${t.reason?` (${t.reason})`:""} \u2014 watch ended`;default:return null}}async function eI(t){let e=Vf(t);return e?.data.sessionId&&await ga(e.data.sessionId)?e.data.sessionId:await ga(t)?t:null}async function tI(){let t=[],n=(await ho()).filter(s=>s.surface!=="telegram");if(n.length>0){t.push("\u{1F7E2} Live sessions:");for(let s of n)t.push(` ${s.sessionId} (${s.surface}, ${s.cwd})`)}let r=Or().filter(s=>s.source!=="telegram").slice(0,8),o=[];for(let s of r)s.sessionId&&await ga(s.sessionId)&&o.push(` ${s.name??s.id} (${s.model})`);return o.length>0&&(t.length>0&&t.push(""),t.push("\u{1F4BE} Recent sessions with activity logs:",...o)),t.length===0?"No watchable sessions found. Start one with `afk i` on your machine, then /watch <session-id-or-name>.":(t.push("","Watch one with /watch <session-id-or-name>."),t.join(`
|
|
1376
|
-
`))}var Ml=class{watches=new Map;log;bot;messageHandler;elicitHeartbeatMs;constructor(e=()=>{},n,r,o=
|
|
1377
|
-
`);i=[],c=c.then(()=>r(u)).catch(p=>this.log("watch send error:",p))};try{for await(let u of DS(n,{signal:s})){if(u.kind==="elicitation"&&l!==void 0){a&&clearTimeout(a),d(),await c;let f=Date.now(),m=0,g=setInterval(()=>{if(m>=sz){clearInterval(g);return}m+=1;let w=Math.round((Date.now()-f)/6e4);r(`\u23F3 Still waiting on your answer (${w}m elapsed) \u2014 no deadline, reply above whenever you're ready. (Send /unwatch to stop watching this session.)`).catch(()=>{})},this.elicitHeartbeatMs);g.unref?.();let h=await(async()=>{try{return await l(u.request,{signal:s})}finally{clearInterval(g)}})(),y=Pl(n);if(y!==null){let w=VR(y,n,u.reqId,h);new Wt(n).record({kind:"elicitation_response",reqId:u.reqId,result:h,hmac:w})}else this.log("[watch] no session key for",n,"\u2014 skipping elicitation write-back");continue}let p=iz(u);if(p){if(i.push(p),u.kind==="closed"){d();break}a||(a=setTimeout(d,rz),a.unref?.())}}a&&clearTimeout(a),d(),await c}finally{a&&clearTimeout(a);let u=this.watches.get(e);u&&u.sessionId===n&&u.abort.signal===s&&this.watches.delete(e)}}};async function nI(t,e,n,r,o){let{chatId:s}=e,a=((t.message&&"text"in t.message?t.message.text:"")??"").split(/\s+/).slice(1).join(" ").trim();try{if(!a){await t.reply(await tI());return}let c=await eI(a);if(!c){await t.reply(`No session ledger found for "${a}". Use /watch with no argument to list watchable sessions.`);return}let l=async d=>{for(let u of Se(d))await t.telegram.sendMessage(s,u,r)};n.start(s,c,l),await t.reply(`\u{1F4E1} Watching ${c} \u2014 new activity will stream here. /unwatch to stop.`)}catch(c){o("Watch error:",c),await t.reply($(c))}}var Ol=class t{bot;sessionManager;options;running=!1;registeredCommandChats=new Set;messageHandler;watchManager;autoSubscribeInterval=null;static AUTO_SUBSCRIBE_INTERVAL_MS=5e3;constructor(e){this.options=e,this.bot=new az(e.botToken,{handlerTimeout:1/0}),this.sessionManager=new Dr({...e,onResumptionOffer:(n,r)=>this.bot.telegram.sendMessage(n.chatId,r,tn(n)).then(()=>!0).catch(()=>!1)}),this.messageHandler=new _l(this.bot,this.sessionManager,this.registeredCommandChats,this.log.bind(this),e.tagOnlyChats??new Set),this.watchManager=new Ml(this.log.bind(this),this.bot,this.messageHandler),this.setupHandlers()}setupHandlers(){this.bot.use(Gd(this.options.allowedChatIds,this.log.bind(this))),this.bot.command("start",r=>Qf(r)),this.bot.command("help",r=>Zf(r,this.sessionManager)),this.bot.command("clear",async r=>{let o=V(r);if(!o){await r.reply($("Could not identify chat"));return}(await this.sessionManager.getSession(o)).state!=="idle"?(this.messageHandler.enqueueClear(o,r),await r.reply("Clear queued.")):await tm(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}),this.bot.command("compact",async r=>{let o=V(r);if(!o){await r.reply($("Could not identify chat"));return}if((await this.sessionManager.getSession(o)).state!=="idle")this.messageHandler.enqueueCompact(o,r),await r.reply("Compact queued.");else try{await Vx(r,this.sessionManager,this.log.bind(this))}finally{this.messageHandler.drainQueue(o).catch(i=>this.log("Drain error:",i))}}),this.bot.command("model",r=>nm(r,this.sessionManager,this.log.bind(this))),this.bot.command(["cd","cwd"],r=>Yx(r,this.sessionManager,this.log.bind(this))),this.bot.command("name",r=>Qx(r,this.sessionManager,this.log.bind(this))),this.bot.command("afk",r=>oR(r,this.sessionManager,this.log.bind(this))),this.bot.command("usage",r=>iR(r,this.log.bind(this))),this.bot.command("sessions",r=>tR(r,this.sessionManager,this.log.bind(this))),this.bot.command("new",r=>nR(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))),this.bot.command("watch",async r=>{let o=V(r);if(!o){await r.reply($("Could not identify chat"));return}await nI(r,o,this.watchManager,tn(o),this.log.bind(this))}),this.bot.command("unwatch",async r=>{let o=r.chat?.id;if(!o){await r.reply($("Could not identify chat"));return}let s=this.watchManager.stop(o);await r.reply(s?`Stopped watching ${s}.`:"Not watching anything.")}),this.bot.command("abort",async r=>{let o=r.chat?.id;if(!o){await r.reply($("Could not identify chat"));return}let s=this.watchManager.getWatched(o);if(!s){await r.reply("Not watching any session. Use /watch <session-id> to watch a REPL session first, then /abort to stop it.");return}let i=Pl(s);if(i===null){await r.reply("Session key not found \u2014 the REPL may not have enabled AFK mode (/afk on). Cannot send a verified abort.");return}let a=QR(),c=YR(i,s,a);new Wt(s).record({kind:"abort_request",nonce:a,hmac:c}),await r.reply(`\u270B Abort sent to session ${s}.`)});let e=r=>{r.catch(o=>{let i=(o instanceof Error?o.message:String(o)).replace(/\/bot[^/]+\//g,"/bot[REDACTED]/");this.log("Detached update handler error:",i)})};this.bot.on("text",r=>e(this.messageHandler.handle(r))),this.bot.on("photo",r=>e(this.messageHandler.handlePhoto(r))),this.bot.on("document",r=>e(this.messageHandler.handleDocument(r))),this.bot.on(["voice","video","sticker","video_note","audio"],r=>{r.chat&&r.reply("I can process text, photo, and document messages. Voice and video support is not yet available.").catch(o=>this.log("Failed to send unsupported-type reply:",o))});let n=new RegExp(`^${Pe(yl)}`);this.bot.action(n,r=>SR(r,{log:this.log.bind(this)})),this.bot.action(/^afk:m:/,async r=>{if(await r.answerCbQuery().catch(()=>{}),r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))return;let s=(typeof r.callbackQuery=="object"&&"data"in r.callbackQuery?r.callbackQuery.data:"").replace("afk:m:",""),i=V(r);if(!(!i||!s)&&cn.includes(s))try{await this.sessionManager.switchModel(i,s);let a=Io(s);await r.editMessageText(a).catch(()=>r.reply(a))}catch(a){this.log("Model action error:",a)}}),this.bot.action(/^afk:sw:/,async r=>{await r.answerCbQuery().catch(()=>{}),!(r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))&&await rR(r,this.sessionManager,this.log.bind(this))}),this.bot.catch((r,o)=>{this.log("Bot error:",r),o.chat&&o.reply($("An unexpected error occurred. Please try again.")).catch(s=>this.log("Failed to send error message:",s))})}async start(){if(this.running)throw new Error("Bot is already running");this.log("Loading sessions..."),await this.sessionManager.loadSessions();let e=[...this.options.allowedChatIds];if(e.length>0){let n=e[0],r=xl(this.messageHandler,this.bot,n),o=Rl(this.bot,new Set(this.options.allowedChatIds),(...s)=>this.log("[elicitation]",...s));vt.install(Il(r,o))}await cE(),this.log("Starting bot..."),await this.bot.launch(),this.log("Registering bot commands..."),await this.bot.telegram.setMyCommands([{command:"start",description:"Show welcome and command list"},{command:"help",description:"Show this command list"},{command:"clear",description:"Clear conversation history"},{command:"compact",description:"Compact conversation history"},{command:"model",description:"Switch Claude model (opus/sonnet/haiku)"},{command:"cd",description:"Show or change session working directory"},{command:"name",description:"Show or set the session name"},{command:"afk",description:"Toggle autonomous (AFK) mode for this chat"},{command:"usage",description:"Show Claude subscription usage"},{command:"watch",description:"Live-tail a CLI session from this chat"},{command:"unwatch",description:"Stop watching a session"}]),this.running=!0,this.log("Bot started successfully"),this.startAutoSubscribe()}async stop(){if(this.running){this.log("Stopping bot..."),this.running=!1,this.log("Stopping auto-subscribe loop..."),this.stopAutoSubscribe(),this.log("Uninstalling elicitation handler..."),vt.uninstall(),this.log("Stopping session watches..."),await this.watchManager.stopAll(),this.log("Closing sessions..."),await this.sessionManager.closeAll(),this.log("Stopping bot polling...");try{this.bot.stop()}catch(e){this.log("Error stopping bot (may not have been started):",e)}this.log("Bot stopped")}}getStats(){return{running:this.running,activeSessions:this.sessionManager.getSessionCount(),totalChats:this.sessionManager.getChatCount()}}getBusySessionCount(){return this.sessionManager.getBusySessionCount()}async handleStart(e){return Qf(e)}async handleHelp(e){return Zf(e,this.sessionManager)}async handleClear(e){let n=V(e);if(!n){await e.reply($("Could not identify chat"));return}if((await this.sessionManager.getSession(n)).state!=="idle")this.messageHandler.enqueueClear(n,e),await e.reply("Clear queued.");else return tm(e,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}async handleMessage(e){return this.messageHandler.handle(e)}async handlePhoto(e){return this.messageHandler.handlePhoto(e)}async handleDocument(e){return this.messageHandler.handleDocument(e)}async handleModelSwitch(e){return nm(e,this.sessionManager,this.log.bind(this))}startAutoSubscribe(){if(this.autoSubscribeInterval!==null)return;let e=()=>{this.runAutoSubscribeTick().catch(n=>this.log("auto-subscribe tick error:",n))};this.autoSubscribeInterval=setInterval(e,t.AUTO_SUBSCRIBE_INTERVAL_MS),this.autoSubscribeInterval.unref?.(),e()}stopAutoSubscribe(){this.autoSubscribeInterval!==null&&(clearInterval(this.autoSubscribeInterval),this.autoSubscribeInterval=null)}async runAutoSubscribeTick(){let e=[...this.options.allowedChatIds];if(e.length===0)return;let n;try{n=await ho()}catch{return}let r=new Set(n.filter(o=>o.surface==="cli"&&o.afk===!0&&o.sessionId).map(o=>o.sessionId));for(let o of e){let s=this.watchManager.getWatched(o);s!==void 0&&!r.has(s)&&(this.watchManager.stop(o),this.log(`[auto-subscribe] stopped watch for ${s} (afk cleared)`));for(let i of r){if(this.watchManager.watching(o)===i)continue;let a=()=>this.sessionManager.getActiveRouteForChat(o)??{chatId:o},c=async l=>{for(let d of Se(l))await this.bot.telegram.sendMessage(o,d,tn(a()))};this.watchManager.start(o,i,c,a),this.log(`[auto-subscribe] started watch for ${i} on chat ${o}`);break}}}log(...e){this.options.verbose&&console.log("[TelegramBot]",...e)}};export{It as AgentSession,nt as BudgetExceededError,Ge as OpenAICompatibleProvider,Dr as SessionManager,G as SubagentManager,Ol as TelegramBot,_x as createCanUseToolHook,sr as deriveSessionFacet,fe as describeFailure,as as discoverPluginSkillBodies,b as env,De as getAgentFrameworkDir,En as getOrDeriveFacet,oe as getSessionsDir,At as getSkill,Kr as getSkillsDir,ir as listSessionIds,Ma as listSkills,te as loadSkillPrompts,Ho as loadStoredSession,jp as openaiCompatibleProvider,z as providerForModel,kx as query,Tx as queryStructured,vx as queryText,ke as registerSkill,Qc as resolveProvider,xc as tool};
|
|
1376
|
+
`))}var Ml=class{watches=new Map;log;bot;messageHandler;elicitHeartbeatMs;constructor(e=()=>{},n,r,o=sz){this.log=e,this.bot=n,this.messageHandler=r,this.elicitHeartbeatMs=o}watching(e){return this.watches.get(e)?.sessionId}getWatched(e){return this.watches.get(e)?.sessionId}start(e,n,r,o=()=>({chatId:e})){this.stop(e);let s=new AbortController,i=this._run(e,n,r,o,s.signal).catch(a=>{this.log("watch loop error:",a)});this.watches.set(e,{sessionId:n,abort:s,finished:i})}stop(e){let n=this.watches.get(e);if(n)return this.watches.delete(e),n.abort.abort(),n.sessionId}async stopAll(){let e=[...this.watches.values()];this.watches.clear();for(let n of e)n.abort.abort();await Promise.allSettled(e.map(n=>n.finished))}async _run(e,n,r,o,s){let i=[],a=null,c=Promise.resolve(),l=this.bot!==void 0&&this.messageHandler!==void 0?Il(xl(this.messageHandler,this.bot,o,{ledgerOriginated:!0}),Rl(this.bot,new Set([e]),(...u)=>this.log("[elicitation]",...u),o)):void 0,d=()=>{if(a=null,i.length===0)return;let u=i.join(`
|
|
1377
|
+
`);i=[],c=c.then(()=>r(u)).catch(p=>this.log("watch send error:",p))};try{for await(let u of DS(n,{signal:s})){if(u.kind==="elicitation"&&l!==void 0){a&&clearTimeout(a),d(),await c;let f=Date.now(),m=0,g=setInterval(()=>{if(m>=iz){clearInterval(g);return}m+=1;let w=Math.round((Date.now()-f)/6e4);r(`\u23F3 Still waiting on your answer (${w}m elapsed) \u2014 no deadline, reply above whenever you're ready. (Send /unwatch to stop watching this session.)`).catch(()=>{})},this.elicitHeartbeatMs);g.unref?.();let h=await(async()=>{try{return await l(u.request,{signal:s})}finally{clearInterval(g)}})(),y=Pl(n);if(y!==null){let w=VR(y,n,u.reqId,h);new Wt(n).record({kind:"elicitation_response",reqId:u.reqId,result:h,hmac:w})}else this.log("[watch] no session key for",n,"\u2014 skipping elicitation write-back");continue}let p=az(u);if(p){if(i.push(p),u.kind==="closed"){d();break}a||(a=setTimeout(d,oz),a.unref?.())}}a&&clearTimeout(a),d(),await c}finally{a&&clearTimeout(a);let u=this.watches.get(e);u&&u.sessionId===n&&u.abort.signal===s&&this.watches.delete(e)}}};async function nI(t,e,n,r,o){let{chatId:s}=e,a=((t.message&&"text"in t.message?t.message.text:"")??"").split(/\s+/).slice(1).join(" ").trim();try{if(!a){await t.reply(await tI());return}let c=await eI(a);if(!c){await t.reply(`No session ledger found for "${a}". Use /watch with no argument to list watchable sessions.`);return}let l=async d=>{for(let u of Se(d))await t.telegram.sendMessage(s,u,r)};n.start(s,c,l),await t.reply(`\u{1F4E1} Watching ${c} \u2014 new activity will stream here. /unwatch to stop.`)}catch(c){o("Watch error:",c),await t.reply($(c))}}var Ol=class t{bot;sessionManager;options;running=!1;registeredCommandChats=new Set;messageHandler;watchManager;autoSubscribeInterval=null;static AUTO_SUBSCRIBE_INTERVAL_MS=5e3;constructor(e){this.options=e,this.bot=new cz(e.botToken,{handlerTimeout:1/0}),this.sessionManager=new Dr({...e,onResumptionOffer:(n,r)=>this.bot.telegram.sendMessage(n.chatId,r,tn(n)).then(()=>!0).catch(()=>!1)}),this.messageHandler=new _l(this.bot,this.sessionManager,this.registeredCommandChats,this.log.bind(this),e.tagOnlyChats??new Set),this.watchManager=new Ml(this.log.bind(this),this.bot,this.messageHandler),this.setupHandlers()}setupHandlers(){this.bot.use(Gd(this.options.allowedChatIds,this.log.bind(this))),this.bot.command("start",r=>Qf(r)),this.bot.command("help",r=>Zf(r,this.sessionManager)),this.bot.command("clear",async r=>{let o=V(r);if(!o){await r.reply($("Could not identify chat"));return}(await this.sessionManager.getSession(o)).state!=="idle"?(this.messageHandler.enqueueClear(o,r),await r.reply("Clear queued.")):await tm(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}),this.bot.command("compact",async r=>{let o=V(r);if(!o){await r.reply($("Could not identify chat"));return}if((await this.sessionManager.getSession(o)).state!=="idle")this.messageHandler.enqueueCompact(o,r),await r.reply("Compact queued.");else try{await Vx(r,this.sessionManager,this.log.bind(this))}finally{this.messageHandler.drainQueue(o).catch(i=>this.log("Drain error:",i))}}),this.bot.command("model",r=>nm(r,this.sessionManager,this.log.bind(this))),this.bot.command(["cd","cwd"],r=>Yx(r,this.sessionManager,this.log.bind(this))),this.bot.command("name",r=>Qx(r,this.sessionManager,this.log.bind(this))),this.bot.command("afk",r=>oR(r,this.sessionManager,this.log.bind(this))),this.bot.command("usage",r=>iR(r,this.log.bind(this))),this.bot.command("sessions",r=>tR(r,this.sessionManager,this.log.bind(this))),this.bot.command("new",r=>nR(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))),this.bot.command("watch",async r=>{let o=V(r);if(!o){await r.reply($("Could not identify chat"));return}await nI(r,o,this.watchManager,tn(o),this.log.bind(this))}),this.bot.command("unwatch",async r=>{let o=r.chat?.id;if(!o){await r.reply($("Could not identify chat"));return}let s=this.watchManager.stop(o);await r.reply(s?`Stopped watching ${s}.`:"Not watching anything.")}),this.bot.command("abort",async r=>{let o=r.chat?.id;if(!o){await r.reply($("Could not identify chat"));return}let s=this.watchManager.getWatched(o);if(!s){await r.reply("Not watching any session. Use /watch <session-id> to watch a REPL session first, then /abort to stop it.");return}let i=Pl(s);if(i===null){await r.reply("Session key not found \u2014 the REPL may not have enabled AFK mode (/afk on). Cannot send a verified abort.");return}let a=QR(),c=YR(i,s,a);new Wt(s).record({kind:"abort_request",nonce:a,hmac:c}),await r.reply(`\u270B Abort sent to session ${s}.`)});let e=r=>{r.catch(o=>{let i=(o instanceof Error?o.message:String(o)).replace(/\/bot[^/]+\//g,"/bot[REDACTED]/");this.log("Detached update handler error:",i)})};this.bot.on("text",r=>e(this.messageHandler.handle(r))),this.bot.on("photo",r=>e(this.messageHandler.handlePhoto(r))),this.bot.on("document",r=>e(this.messageHandler.handleDocument(r))),this.bot.on(["voice","video","sticker","video_note","audio"],r=>{r.chat&&r.reply("I can process text, photo, and document messages. Voice and video support is not yet available.").catch(o=>this.log("Failed to send unsupported-type reply:",o))});let n=new RegExp(`^${Pe(yl)}`);this.bot.action(n,r=>SR(r,{log:this.log.bind(this)})),this.bot.action(/^afk:m:/,async r=>{if(await r.answerCbQuery().catch(()=>{}),r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))return;let s=(typeof r.callbackQuery=="object"&&"data"in r.callbackQuery?r.callbackQuery.data:"").replace("afk:m:",""),i=V(r);if(!(!i||!s)&&cn.includes(s))try{await this.sessionManager.switchModel(i,s);let a=Io(s);await r.editMessageText(a).catch(()=>r.reply(a))}catch(a){this.log("Model action error:",a)}}),this.bot.action(/^afk:sw:/,async r=>{await r.answerCbQuery().catch(()=>{}),!(r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))&&await rR(r,this.sessionManager,this.log.bind(this))}),this.bot.catch((r,o)=>{this.log("Bot error:",r),o.chat&&o.reply($("An unexpected error occurred. Please try again.")).catch(s=>this.log("Failed to send error message:",s))})}async start(){if(this.running)throw new Error("Bot is already running");this.log("Loading sessions..."),await this.sessionManager.loadSessions();let e=[...this.options.allowedChatIds];if(e.length>0){let n=e[0],r=xl(this.messageHandler,this.bot,n),o=Rl(this.bot,new Set(this.options.allowedChatIds),(...s)=>this.log("[elicitation]",...s));vt.install(Il(r,o))}await cE(),this.log("Starting bot..."),await this.bot.launch(),this.log("Registering bot commands..."),await this.bot.telegram.setMyCommands([{command:"start",description:"Show welcome and command list"},{command:"help",description:"Show this command list"},{command:"clear",description:"Clear conversation history"},{command:"compact",description:"Compact conversation history"},{command:"model",description:"Switch Claude model (opus/sonnet/haiku)"},{command:"cd",description:"Show or change session working directory"},{command:"name",description:"Show or set the session name"},{command:"afk",description:"Toggle autonomous (AFK) mode for this chat"},{command:"usage",description:"Show Claude subscription usage"},{command:"watch",description:"Live-tail a CLI session from this chat"},{command:"unwatch",description:"Stop watching a session"}]),this.running=!0,this.log("Bot started successfully"),this.startAutoSubscribe()}async stop(){if(this.running){this.log("Stopping bot..."),this.running=!1,this.log("Stopping auto-subscribe loop..."),this.stopAutoSubscribe(),this.log("Uninstalling elicitation handler..."),vt.uninstall(),this.log("Stopping session watches..."),await this.watchManager.stopAll(),this.log("Closing sessions..."),await this.sessionManager.closeAll(),this.log("Stopping bot polling...");try{this.bot.stop()}catch(e){this.log("Error stopping bot (may not have been started):",e)}this.log("Bot stopped")}}getStats(){return{running:this.running,activeSessions:this.sessionManager.getSessionCount(),totalChats:this.sessionManager.getChatCount()}}getBusySessionCount(){return this.sessionManager.getBusySessionCount()}async handleStart(e){return Qf(e)}async handleHelp(e){return Zf(e,this.sessionManager)}async handleClear(e){let n=V(e);if(!n){await e.reply($("Could not identify chat"));return}if((await this.sessionManager.getSession(n)).state!=="idle")this.messageHandler.enqueueClear(n,e),await e.reply("Clear queued.");else return tm(e,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}async handleMessage(e){return this.messageHandler.handle(e)}async handlePhoto(e){return this.messageHandler.handlePhoto(e)}async handleDocument(e){return this.messageHandler.handleDocument(e)}async handleModelSwitch(e){return nm(e,this.sessionManager,this.log.bind(this))}startAutoSubscribe(){if(this.autoSubscribeInterval!==null)return;let e=()=>{this.runAutoSubscribeTick().catch(n=>this.log("auto-subscribe tick error:",n))};this.autoSubscribeInterval=setInterval(e,t.AUTO_SUBSCRIBE_INTERVAL_MS),this.autoSubscribeInterval.unref?.(),e()}stopAutoSubscribe(){this.autoSubscribeInterval!==null&&(clearInterval(this.autoSubscribeInterval),this.autoSubscribeInterval=null)}async runAutoSubscribeTick(){let e=[...this.options.allowedChatIds];if(e.length===0)return;let n;try{n=await ho()}catch{return}let r=new Set(n.filter(o=>o.surface==="cli"&&o.afk===!0&&o.sessionId).map(o=>o.sessionId));for(let o of e){let s=this.watchManager.getWatched(o);s!==void 0&&!r.has(s)&&(this.watchManager.stop(o),this.log(`[auto-subscribe] stopped watch for ${s} (afk cleared)`));for(let i of r){if(this.watchManager.watching(o)===i)continue;let a=()=>this.sessionManager.getActiveRouteForChat(o)??{chatId:o},c=async l=>{for(let d of Se(l))await this.bot.telegram.sendMessage(o,d,tn(a()))};this.watchManager.start(o,i,c,a),this.log(`[auto-subscribe] started watch for ${i} on chat ${o}`);break}}}log(...e){this.options.verbose&&console.log("[TelegramBot]",...e)}};export{It as AgentSession,nt as BudgetExceededError,Ge as OpenAICompatibleProvider,Dr as SessionManager,G as SubagentManager,Ol as TelegramBot,_x as createCanUseToolHook,sr as deriveSessionFacet,fe as describeFailure,as as discoverPluginSkillBodies,b as env,De as getAgentFrameworkDir,En as getOrDeriveFacet,oe as getSessionsDir,At as getSkill,Kr as getSkillsDir,ir as listSessionIds,Ma as listSkills,te as loadSkillPrompts,Ho as loadStoredSession,jp as openaiCompatibleProvider,z as providerForModel,kx as query,Tx as queryStructured,vx as queryText,ke as registerSkill,Qc as resolveProvider,xc as tool};
|