@code-yeongyu/senpi 2026.9.29-2 → 2026.9.29-3

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.
Files changed (115) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/bundle/chunks/{anthropic-messages-OMTQOHSI.js → anthropic-messages-7WTVWELD.js} +1 -1
  3. package/dist/bundle/chunks/{app-server-command-ZC6A4C3L.js → app-server-command-5DSRGKFG.js} +1 -1
  4. package/dist/bundle/chunks/{azure-openai-responses-Z4FAFKPJ.js → azure-openai-responses-XVZ3FMH2.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-U2SAEU63.js → chunk-27C3ZSZG.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-YJUO37UX.js → chunk-2POUJCWM.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-4LVZQRDG.js → chunk-4VWWEMCJ.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-36ACNYQR.js → chunk-7RVWDN5Z.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-YS72TY6S.js → chunk-CZNE6LIO.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-ILELKDDB.js → chunk-DWNYCJ43.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-OMLHHPMZ.js → chunk-EB3GDOU4.js} +1 -1
  12. package/dist/bundle/chunks/{chunk-2HWLCW54.js → chunk-EQBN6TVJ.js} +1 -1
  13. package/dist/bundle/chunks/{chunk-E5F5SVZF.js → chunk-FUGMDU6B.js} +1 -1
  14. package/dist/bundle/chunks/{chunk-RSPHQOSG.js → chunk-GE32OHDE.js} +7 -7
  15. package/dist/bundle/chunks/chunk-GKR74EKE.js +3 -0
  16. package/dist/bundle/chunks/{chunk-UYV2UM6E.js → chunk-ILQTW6KB.js} +1 -1
  17. package/dist/bundle/chunks/{chunk-TH4XD7AJ.js → chunk-JEWB5XTL.js} +1 -1
  18. package/dist/bundle/chunks/{chunk-FAV4DX74.js → chunk-K2SHQNAA.js} +1 -1
  19. package/dist/bundle/chunks/{chunk-NVJUCNHP.js → chunk-K7B7NFOK.js} +1 -1
  20. package/dist/bundle/chunks/{chunk-TZMNXKL2.js → chunk-KO6GO5ZY.js} +1 -1
  21. package/dist/bundle/chunks/{chunk-5CGFVKUK.js → chunk-LB2B2Q4P.js} +1 -1
  22. package/dist/bundle/chunks/{chunk-77OBRAUG.js → chunk-M4AHRI5L.js} +1 -1
  23. package/dist/bundle/chunks/{chunk-SW4U2HHU.js → chunk-OVDACFW2.js} +1 -1
  24. package/dist/bundle/chunks/{chunk-BTRONX2A.js → chunk-RUOJQL6B.js} +1 -1
  25. package/dist/bundle/chunks/{chunk-ASAQQ6VM.js → chunk-SH6VUPE4.js} +1 -1
  26. package/dist/bundle/chunks/{chunk-TFW6SS3P.js → chunk-SNDTJL2H.js} +1 -1
  27. package/dist/bundle/chunks/{chunk-Y5A6TKBN.js → chunk-T3HGPHPP.js} +1 -1
  28. package/dist/bundle/chunks/{chunk-BPZ5KIOS.js → chunk-UK5TE7WR.js} +1 -1
  29. package/dist/bundle/chunks/{chunk-NDNZU2X7.js → chunk-UNTVGMGW.js} +3 -3
  30. package/dist/bundle/chunks/{chunk-BQGFWWDC.js → chunk-VLTMFAWQ.js} +1 -1
  31. package/dist/bundle/chunks/{chunk-XDZ5RSMX.js → chunk-W4AG5TN4.js} +1 -1
  32. package/dist/bundle/chunks/chunk-WCAKUCN3.js +14 -0
  33. package/dist/bundle/chunks/{chunk-UEWSEALS.js → chunk-WRPX2M5D.js} +1 -1
  34. package/dist/bundle/chunks/{chunk-DA4W77J7.js → chunk-XBGO2JZD.js} +1 -1
  35. package/dist/bundle/chunks/chunk-XVX4M3DZ.js +2 -0
  36. package/dist/bundle/chunks/chunk-YD32NXKZ.js +8 -0
  37. package/dist/bundle/chunks/chunk-YOPVJDSU.js +2 -0
  38. package/dist/bundle/chunks/cli-main-V3T5WOV6.js +3 -0
  39. package/dist/bundle/chunks/{google-generative-ai-NFSRK6V5.js → google-generative-ai-XO6BUQVD.js} +1 -1
  40. package/dist/bundle/chunks/{google-vertex-6YEVHEPI.js → google-vertex-SGNV6ZMK.js} +1 -1
  41. package/dist/bundle/chunks/{help-fast-path-RYMO5ODA.js → help-fast-path-AYPE26W2.js} +1 -1
  42. package/dist/bundle/chunks/{host-command-BU6XSX4H.js → host-command-ZTMADQIT.js} +1 -1
  43. package/dist/bundle/chunks/{host-lifecycle-22DRSTVI.js → host-lifecycle-FTH7WAQN.js} +1 -1
  44. package/dist/bundle/chunks/{interactive-host-runtime-P3FYZWSY.js → interactive-host-runtime-XDRXCEJ3.js} +1 -1
  45. package/dist/bundle/chunks/{interactive-mode-VCIOGSIZ.js → interactive-mode-6VFVZKKW.js} +1 -1
  46. package/dist/bundle/chunks/{list-tips-XXZ5PLE3.js → list-tips-ASETMEFS.js} +1 -1
  47. package/dist/bundle/chunks/{mistral-conversations-R5PTP4P3.js → mistral-conversations-TVJBIL35.js} +1 -1
  48. package/dist/bundle/chunks/{multi-session-host-PRY7CJLK.js → multi-session-host-5VFMTPY7.js} +1 -1
  49. package/dist/bundle/chunks/{native-loader-SU5SGTSW.js → native-loader-WM7NDPEO.js} +1 -1
  50. package/dist/bundle/chunks/{openai-codex-responses-6B2ZLWTN.js → openai-codex-responses-RUT66DHS.js} +1 -1
  51. package/dist/bundle/chunks/{openai-completions-5NTZZNVJ.js → openai-completions-THHRTH7B.js} +1 -1
  52. package/dist/bundle/chunks/{openai-responses-V4JEBGEX.js → openai-responses-ITED6XXB.js} +1 -1
  53. package/dist/bundle/chunks/{package-manager-cli-RQ2NJAJ3.js → package-manager-cli-RAQRCH5L.js} +3 -3
  54. package/dist/bundle/chunks/{rg-engine-XHGOVGVG.js → rg-engine-G2YTYL2T.js} +1 -1
  55. package/dist/bundle/chunks/{rotation-stream-YQLGLRCX.js → rotation-stream-4FQW6IX5.js} +1 -1
  56. package/dist/bundle/chunks/{rpc-mode-U2EQRVC3.js → rpc-mode-W5P5QMF7.js} +1 -1
  57. package/dist/bundle/chunks/{schedule-command-DXC3ECXT.js → schedule-command-EFQUSPN4.js} +1 -1
  58. package/dist/bundle/chunks/{session-picker-KTXLU6MQ.js → session-picker-FF2J4OQA.js} +1 -1
  59. package/dist/bundle/chunks/session-worker.js +188 -188
  60. package/dist/bundle/chunks/{state-store-5A2TZ4SG.js → state-store-IIQL55GC.js} +1 -1
  61. package/dist/bundle/cli.js +2 -1
  62. package/dist/bundle/index.js +1 -1
  63. package/dist/bundle/rpc-entry.js +1 -1
  64. package/dist/bundle/runtime-manifest.json +1 -0
  65. package/dist/cli.js +24 -4
  66. package/dist/cli.js.map +1 -1
  67. package/dist/config.d.ts +5 -0
  68. package/dist/config.d.ts.map +1 -1
  69. package/dist/config.js +16 -6
  70. package/dist/config.js.map +1 -1
  71. package/dist/main.d.ts.map +1 -1
  72. package/dist/main.js +2 -2
  73. package/dist/main.js.map +1 -1
  74. package/dist/package-manager-cli.js +3 -3
  75. package/dist/package-manager-cli.js.map +1 -1
  76. package/dist/runtime-snapshot/enter.d.ts +17 -0
  77. package/dist/runtime-snapshot/enter.d.ts.map +1 -0
  78. package/dist/runtime-snapshot/enter.js +72 -0
  79. package/dist/runtime-snapshot/enter.js.map +1 -0
  80. package/dist/runtime-snapshot/layout.d.ts +15 -0
  81. package/dist/runtime-snapshot/layout.d.ts.map +1 -0
  82. package/dist/runtime-snapshot/layout.js +126 -0
  83. package/dist/runtime-snapshot/layout.js.map +1 -0
  84. package/dist/runtime-snapshot/marker.d.ts +13 -0
  85. package/dist/runtime-snapshot/marker.d.ts.map +1 -0
  86. package/dist/runtime-snapshot/marker.js +40 -0
  87. package/dist/runtime-snapshot/marker.js.map +1 -0
  88. package/dist/runtime-snapshot/registry.d.ts +14 -0
  89. package/dist/runtime-snapshot/registry.d.ts.map +1 -0
  90. package/dist/runtime-snapshot/registry.js +124 -0
  91. package/dist/runtime-snapshot/registry.js.map +1 -0
  92. package/dist/senpi +24 -4
  93. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
  94. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  95. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  96. package/node_modules/@earendil-works/pi-ai/dist/api/lazy.d.ts.map +1 -1
  97. package/node_modules/@earendil-works/pi-ai/dist/api/lazy.js +2 -1
  98. package/node_modules/@earendil-works/pi-ai/dist/api/lazy.js.map +1 -1
  99. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  100. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  101. package/node_modules/@earendil-works/pi-ai/dist/utils/provider-failure-description.d.ts +7 -0
  102. package/node_modules/@earendil-works/pi-ai/dist/utils/provider-failure-description.d.ts.map +1 -1
  103. package/node_modules/@earendil-works/pi-ai/dist/utils/provider-failure-description.js +21 -0
  104. package/node_modules/@earendil-works/pi-ai/dist/utils/provider-failure-description.js.map +1 -1
  105. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  106. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  107. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  108. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  109. package/package.json +7 -7
  110. package/dist/bundle/chunks/chunk-DXU53IPJ.js +0 -8
  111. package/dist/bundle/chunks/chunk-FILEUW2D.js +0 -3
  112. package/dist/bundle/chunks/chunk-PBWQK23Z.js +0 -14
  113. package/dist/bundle/chunks/chunk-TJV2LFKM.js +0 -2
  114. package/dist/bundle/chunks/chunk-UIOI2SK3.js +0 -2
  115. package/dist/bundle/chunks/cli-main-RPQFXRJ7.js +0 -3
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{APP_NAME,CONFIG_DIR_NAME,agentDirLabel}from"./chunk-PBWQK23Z.js";var CLI_TIPS=[{id:"print-mode",bindings:[],render:()=>`${APP_NAME} -p "question" answers without the TUI, and piped stdin is merged into the prompt.`},{id:"tool-flags",bindings:[],render:()=>"Limit a run's tools with -t read,bash, or drop a few with -xt write,edit."}];function stopChord(){return process.platform==="darwin"?"Control+Option+Command+Escape":"Ctrl+Alt+Shift+Escape"}var COMPUTER_TIPS=[{id:"computer.what-it-is",bindings:[],requiresCommand:"computer",render:()=>"Experimental: your agent can use native apps too: screenshots, windows, clicks and typing. Run /computer to see whether this machine is ready."},{id:"computer.stop-chord",bindings:[],requiresCommand:"computer",render:()=>`Press ${stopChord()} at any moment to stop computer input. It stays stopped until you run /computer resume; the agent cannot resume it.`},{id:"computer.background-input",bindings:[],requiresCommand:"computer",render:()=>"Computer use clicks and types into the target app in the background, so your frontmost app, keyboard focus and cursor stay where you left them."},{id:"computer.look-dont-touch",bindings:[],requiresCommand:"computer",render:()=>"Want the agent to look but not touch? Start with --permission computer:exec=deny: screenshots and accessibility reads still work, clicks and typing are refused."},{id:"computer.permissions",bindings:[],requiresCommand:"computer",render:()=>"On macOS, computer use needs Screen Recording and Accessibility for the app you launch from. /computer status shows which one is missing."}];var DAG_TIPS=[{id:"dag.one-keyword-mastery",bindings:[],requiresCommand:"dag",render:()=>'One keyword makes you a master of graph engineering: say "mass-ulw" and your work becomes a dependency graph that schedules itself.'},{id:"dag.what-it-is",bindings:[],requiresCommand:"dag",render:()=>'Trigger "mass-ulw" when some tasks must wait for others - describe the work, get a graph that runs in the right order.'},{id:"dag.parallel-waves",bindings:[],requiresCommand:"dag",render:()=>"A graph run executes in waves: everything with no pending dependency starts at once, the rest starts the moment it is unblocked."},{id:"dag.depends-on",bindings:[],requiresCommand:"dag",render:()=>"Say what needs what - review after implementation, docs after both - and the ordering is enforced for you."},{id:"dag.categories",bindings:[],requiresCommand:"dag",render:()=>"Each node in the graph picks its own worker category, so cheap steps stay cheap and hard steps get the strong model."},{id:"dag.status-view",bindings:[],requiresCommand:"dag",render:()=>"Use /dag to watch a run: which nodes finished, which are running, and which one failed."},{id:"dag.resume",bindings:[],requiresCommand:"dag",render:()=>"Graph runs are journaled - if the session dies mid-run it resumes later and never redoes the nodes that already finished."},{id:"dag.vs-parallel",bindings:[],requiresCommand:"dag",render:()=>"Fully independent jobs just need parallel subagents; reach for a graph when the ordering between them is the whole point."},{id:"dag.scale",bindings:[],requiresCommand:"dag",render:()=>"Stop hand-running steps in sequence. Describe the dependencies once and let a dozen agents fan out and rejoin on their own."}];var ETHOS_TIPS=[{id:"ethos.tuning-discipline",bindings:[],render:()=>"gpt-5.6-sol used to turn a sprint into a marathon. We tuned the system prompt and killed that habit: 5-minute jobs take 5 minutes, 12-hour jobs take 12."},{id:"ethos.tools-transparent",bindings:[],render:()=>"Don't study our tools. A tool that needs studying is a tool that failed. We just ride shotgun while you keep doing your actual job."},{id:"ethos.only-harness",bindings:[],render:()=>"The only harness that actually knows how to drive gpt-5.6-sol. Same job, feels up to 30% faster. *we counted*"},{id:"ethos.spend-tokens",bindings:[],render:()=>"Stop hoarding tokens. Spend them like they buy your hours back, because they do."},{id:"ethos.deep-work",bindings:[],render:()=>"Using our tools means your work is already the deep, valuable kind. Keep your eyes on the essence of your craft. The rest is our problem now, and we're great at problems."},{id:"ethos.ulw-plan-sage",bindings:[],requiresCommand:"tasks",render:()=>"Try ulw-plan on fable-5.1 xhigh. A patient sage obsessed with the essence does the agonizing for you and fills in every blank you were pretending not to see."},{id:"ethos.ulw-loop-shallow",bindings:[],requiresCommand:"tasks",render:()=>"For days when deep thought sounds awful, run the ulw loop with gpt-6-sol fast/medium. Fair warning: shallow thinking sends invoices."},{id:"ethos.monitor-subscribe",bindings:[],render:()=>"Subscribe to a command's stdout and forget it. CI finishes, server boots, log line lands... you're mid-edit and the news finds *you*. No sleep loops, no polling, no re-reading context like a chump."},{id:"ethos.cache-budget",bindings:[],render:()=>"My harness knows the prompt cache's expiry to the second and never blocks past it. Cold re-read tax? *Refused on your behalf.* Other agents eat that cost, mine declines it."},{id:"ethos.cache-hit-rate",bindings:[],render:()=>"Live cache-hit rate in the footer, plus a running tab of misses, idle gaps, and model swaps. I can point at the exact moment cache broke and why. Watching tokens you never re-pay stack up? Smug doesn't cover it."},{id:"ethos.multimodal-vision",bindings:[],render:()=>`Drop a screenshot, a PDF, a crusty whiteboard photo... ${APP_NAME} actually sees it, reads it, reasons about it. Your agent has eyes now. *Yes, really.*`},{id:"ethos.oauth-multi-account",bindings:[],render:()=>`Hit a rate limit, switch accounts. Wrong org, switch again. ${APP_NAME} treats your Claude logins like a roster, not a single lifeline. *Env vars could never.*`},{id:"ethos.agent-sdk-foundation",bindings:[],render:()=>'Built on the official agent SDK, speaking the protocol natively. No reverse-engineered wrapper, no ToS gray zone, no "will I get banned for this" anxiety. *Sleep easy, ship loud.*'},{id:"ethos.tool-call-repair",bindings:[],render:()=>`${APP_NAME} catches malformed tool calls on the wire, fixes them, and salvages the turn - claude's sloppy invokes, kimi k3's leaked XTML channels, all of it. Other harnesses retry the whole thing and bill you for the privilege. *table stakes, honestly*`}];var INPUT_TIPS=[{id:"click-pending-question",bindings:[],render:()=>"Click a pending question's option to answer. Use the displayed selection-bypass modifier to select terminal text, or disable terminal.mouse in /settings."},{id:"queue-follow-up",bindings:["app.message.followUp"],render:keys=>`While the agent is working, use ${keys("app.message.followUp")} to queue a follow-up for after it finishes.`},{id:"steering-message",bindings:["tui.input.submit","app.message.followUp"],render:keys=>`Press ${keys("tui.input.submit")} while the agent works to steer it after the current tool batch; ${keys("app.message.followUp")} waits until all work is done.`},{id:"edit-queued-message",bindings:["app.message.dequeue"],render:keys=>`Use ${keys("app.message.dequeue")} to bring queued messages back for editing.`},{id:"interrupt-restores-queue",bindings:["app.interrupt"],render:keys=>`Press ${keys("app.interrupt")} to abort the current turn and restore queued messages to the editor.`},{id:"file-reference",bindings:[],render:()=>"Type @ in the editor to fuzzy-search project files and insert their paths."},{id:"path-completion",bindings:["tui.input.tab"],render:keys=>`Press ${keys("tui.input.tab")} to complete file paths while typing.`},{id:"shortcut-overlay",bindings:[],render:()=>"Type ? in an empty editor to pop up the full shortcut grid."},{id:"prompt-history",bindings:["app.history.search"],requiresCommand:"history",render:keys=>`Search prompt history across sessions with ${keys("app.history.search")}.`},{id:"external-editor",bindings:["app.editor.external"],render:keys=>`Open the current prompt in your external editor with ${keys("app.editor.external")}.`},{id:"expand-tool-output",bindings:["app.tools.expand"],render:keys=>`Collapse or expand tool output with ${keys("app.tools.expand")}.`},{id:"thinking-blocks",bindings:["app.thinking.toggle"],render:keys=>`Collapse or expand thinking blocks with ${keys("app.thinking.toggle")}.`},{id:"paste-image",bindings:["app.clipboard.pasteImage"],render:keys=>`Paste an image from the clipboard with ${keys("app.clipboard.pasteImage")}.`},{id:"copy-message",bindings:["app.message.copy"],render:keys=>`Copy the latest assistant message with ${keys("app.message.copy")}.`},{id:"input-newline",bindings:["tui.input.newLine"],render:keys=>`Insert a newline without sending with ${keys("tui.input.newLine")}.`},{id:"bash-prefixes",bindings:[],render:()=>"Prefix a prompt with ! to run bash, or !! to run bash without adding its output to model context."},{id:"drag-drop-files",bindings:[],render:()=>"Drag and drop files into the terminal to add their paths to your prompt."},{id:"answer-agent-question",bindings:[],render:()=>"When the agent asks you a question, pick options with digits or arrows, press Enter to advance, and use the final Submit tab for a comment or partial answers; anything unanswered is reported back as unanswered."},{id:"open-pending-question",bindings:["app.question.answer","app.question.next"],render:keys=>`Pending questions queue above the editor. An empty-composer digit selects an option; ${keys("app.question.answer")} opens the shown request and ${keys("app.question.next")} cycles requests. /answer lists them.`}];var MEMORY_TIPS=[{id:"memory.persistent",bindings:[],requiresCommand:"memory",render:()=>`${APP_NAME} remembers across sessions. Close the terminal, come back tomorrow, and the context is still there.`},{id:"memory.remember-command",bindings:[],requiresCommand:"remember",render:()=>"Use /remember to save something you want kept - a preference, a decision, a fact worth reusing."},{id:"memory.just-tell-it",bindings:[],requiresCommand:"remember",render:()=>'You can also just say it: "remember that we deploy on Fridays" is enough. No syntax, no file to open.'},{id:"memory.search-command",bindings:[],requiresCommand:"search",render:()=>"Use /search to look through everything remembered so far, in plain words."},{id:"memory.memory-command",bindings:[],requiresCommand:"memory",render:()=>"Use /memory to see what is currently remembered about you and this project."},{id:"memory.init-command",bindings:[],requiresCommand:"init",render:()=>"Use /init to start memory for a new project, so it learns this codebase from the first session."},{id:"memory.people-command",bindings:[],requiresCommand:"people",render:()=>"Use /people to keep notes on teammates - who owns what, who to ask, what they prefer."},{id:"memory.reflect-command",bindings:[],requiresCommand:"reflect",render:()=>"Use /reflect to have the session reviewed now and the parts worth keeping written down."},{id:"memory.dream-command",bindings:[],requiresCommand:"dream",render:()=>"Memory tidies itself in the background between turns - /dream shows that work and lets you start it yourself."},{id:"memory.sleeptime-command",bindings:[],requiresCommand:"sleeptime",render:()=>"Use /sleeptime to decide how often memory reorganizes itself while you are not looking."},{id:"memory.memfs-command",bindings:[],requiresCommand:"memfs",render:()=>"Memory is plain files you own - browse them with /memfs and edit anything that looks wrong."},{id:"memory.repository-command",bindings:[],requiresCommand:"memory-repository",render:()=>"Every memory change is a git commit - use /memory-repository to see the history and undo a bad one."},{id:"memory.doctor-command",bindings:[],requiresCommand:"doctor",render:()=>"Use /doctor when memory feels off; it checks the setup and tells you what to fix."},{id:"memory.facts-command",bindings:[],requiresCommand:"facts",render:()=>"Use /facts to see the individual things learned about you, and drop the ones that no longer hold."},{id:"memory.recompile-command",bindings:[],requiresCommand:"recompile",render:()=>"Edited memory files by hand? Run /recompile so this session picks the changes up right away."},{id:"memory.aha-moment",bindings:[],requiresCommand:"memory",render:()=>"Memory speaks up on its own: when something remembered would change the next step, an Aha moment! line surfaces it mid-task. Silence means nothing relevant was found."},{id:"memory.stop-repeating",bindings:[],requiresCommand:"memory",render:()=>"Explain your setup once. Memory means you stop re-explaining it at the start of every session."}];var MODEL_TIPS=[{id:"thinking-level",bindings:["app.thinking.cycle"],render:keys=>`Use /thinking <level> to set the thinking level, /thinking to pick one, or ${keys("app.thinking.cycle")} to cycle through them.`},{id:"efforts-command",bindings:[],requiresCommand:"efforts",render:()=>"Use /efforts <level> to set the reasoning effort for the current model; /efforts alone lists the levels it supports."},{id:"favorite-model-rotation",bindings:["app.model.cycleForward","app.model.cycleBackward"],render:keys=>`Rotate through favorite models with ${keys("app.model.cycleForward")}; go backward with ${keys("app.model.cycleBackward")}.`},{id:"model-selector-favorites",bindings:["app.model.select","app.models.toggleFavorite"],render:keys=>`Open the model selector with ${keys("app.model.select")}, then use ${keys("app.models.toggleFavorite")} to toggle the highlighted favorite.`},{id:"model-command-search",bindings:[],render:()=>"Use /model to open the selector, or /model <pattern> to jump straight to a matching model."},{id:"model-cycling-scope",bindings:["app.model.cycleForward"],render:keys=>`Start ${APP_NAME} with --models "anthropic/*,gpt-5*" to limit which models ${keys("app.model.cycleForward")} cycles through.`},{id:"thinking-budgets",bindings:[],render:()=>"Set thinkingBudgets in settings.json to choose the token budget behind each thinking level."},{id:"prompt-preset",bindings:[],render:()=>"Set promptPreset in settings.json when a model does not auto-detect the system prompt you want."},{id:"provider-login",bindings:[],render:()=>"Use /login to add a subscription or API-key provider, and /logout to remove stored credentials."},{id:"fallback-chains-setting",bindings:[],render:()=>"retry.fallbackChains in settings.json maps a model to ordered fallbacks, so a failed turn retries on the next one."},{id:"fallback-command",bindings:[],requiresCommand:"fallback",render:()=>"Use /fallback to inspect and manage the retry fallback chain for the current model."}];var SESSION_TIPS=[{id:"favorite-models-command",bindings:[],render:()=>"Use /favorite-models to choose and reorder the models in your rotation."},{id:"tree-command",bindings:[],render:()=>"Use /tree to revisit earlier points and switch between session branches."},{id:"fork-command",bindings:[],render:()=>"Use /fork to create a separate session from an earlier user message."},{id:"clone-session",bindings:[],render:()=>"Use /clone to duplicate the current branch into its own session before trying something risky."},{id:"continue-session",bindings:[],render:()=>`Use /resume or /sessions to reopen a past session; from the shell, ${APP_NAME} -r opens the same picker and ${APP_NAME} -c continues the most recent one.`},{id:"session-name",bindings:[],render:()=>"Use /rename [name] to label a session so it is easy to spot in the footer and in /resume."},{id:"session-info",bindings:[],render:()=>"Use /session to see the session file, id, message count, tokens, and cost."},{id:"export-share",bindings:[],render:()=>"Use /export to write the session to HTML or JSONL, or /share to upload it as a private gist link."},{id:"compact-command",bindings:[],render:()=>"Use /compact to compact context now, or /compact <prompt> to tell the summarizer what to keep."},{id:"auto-compaction",bindings:[],render:()=>"Auto-compaction is on by default - the (auto) marker in the footer shows it; tune it with compaction.* in settings.json."}];var SETTINGS_TIPS=[{id:"settings-locations",bindings:[],render:()=>`Use /settings for common options; the rest live in settings.json, with ${CONFIG_DIR_NAME}/settings.json overriding per project.`},{id:"permission-preset",bindings:[],render:()=>'Set permissionPreset to "workspace", "read-only", or "ask" to decide which tool calls need your approval.'},{id:"packages-setting",bindings:[],render:()=>"The packages setting loads skills, extensions, prompts, and themes from an npm or git package."},{id:"custom-themes",bindings:[],render:()=>`Switch themes from /settings, and drop custom theme files in ${agentDirLabel()}/themes.`},{id:"reload-resources",bindings:[],render:()=>"Use /reload to re-read keybindings, extensions, skills, prompts, themes, and context files without restarting."},{id:"project-trust",bindings:[],render:()=>"Use /trust to save a trust decision so this project's settings, skills, and extensions load next time."},{id:"tips-toggle",bindings:[],render:()=>'Set "tips": false in settings.json to stop showing these tips.'}];var SUBAGENT_TIPS=[{id:"workflow-skills.plan",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "ulw plan" to get an explored, decision-complete plan under .omo/plans/.'},{id:"workflow-skills.start-work",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "$start-work <plan-name>" to execute a plan end-to-end in a fresh session.'},{id:"workflow-skills.ultrawork",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "ulw" or "ulw loop" for a long, evidence-driven autonomous run in ultrawork mode.'},{id:"workflow-skills.research",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "ulw-research" for a saturating, citation-backed investigation across the codebase, docs, and the web.'},{id:"workflow-skills.hyperplan",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "hyperplan" to have adversarial reviewers attack a plan before you commit to it.'},{id:"workflow-skills.review",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "review work" to run parallel goal, quality, security, and hands-on QA reviews.'},{id:"workflow-skills.init-deep",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "/init-deep" to map a project and generate a hierarchical AGENTS.md knowledge base.'},{id:"workflow-skills.debugging",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "debug this" for parallel hypotheses, a failing regression test, a minimal fix, and real-surface QA.'},{id:"workflow-skills.refactor",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "refactor" for codebase-aware cleanup that pins behavior before changing structure.'},{id:"workflow-skills.remove-ai-slops",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "remove AI slop" to lock behavior first, then strip generated-code smells without drive-by rewrites.'},{id:"workflow-skills.visual-qa",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "visual QA" to capture browser or xterm evidence and review web or terminal interfaces.'},{id:"workflow-skills.report-bug",bindings:[],requiresCommand:"tasks",render:()=>'Hit a bug? Say "report a bug" - the report-bug skill finds the session, records the exact provider and model, routes it to the right repository, and files an evidence-backed issue only after you confirm.'},{id:"subagent-categories",bindings:[],requiresCommand:"tasks",render:()=>"Delegate by category - quick, deep, ultrabrain, architect, artistry, git, writing - each runs on its own model."},{id:"subagent-commands",bindings:[],requiresCommand:"tasks",render:()=>"Use /tasks to see this session's background subagents, and /task-kill to stop one."},{id:"subagent-config",bindings:[],requiresCommand:"tasks",render:()=>"~/.omo/omo.jsonc maps every subagent category to its model, reasoning effort, and fallback chain."},{id:"subagent-team",bindings:[],requiresCommand:"tasks",render:()=>"Ask for a team when one task needs several agents at once: members share a tasklist and report back to you."}];var WORKSPACE_TIPS=[{id:"help-command",bindings:[],requiresCommand:"help",render:()=>"Use /help to see available commands and guidance."},{id:"keybindings-command",bindings:[],render:()=>"Use /keybindings to review and customize keyboard shortcuts."},{id:"agents-md-context",bindings:[],render:()=>`${APP_NAME} loads AGENTS.md from your home directory, every parent folder, and the current folder as project instructions.`},{id:"skills-and-prompts",bindings:[],render:()=>`Skills run as /skill:name, and prompt templates in ${agentDirLabel()}/prompts expand as /templatename.`},{id:"files-command",bindings:[],requiresCommand:"files",render:()=>"Use /files to list every file this session read, wrote, or edited."},{id:"diff-command",bindings:[],requiresCommand:"diff",render:()=>"Use /diff to review this session's git changes and open them in a diff view."},{id:"todo-command",bindings:[],requiresCommand:"todo",render:()=>"Use /todo to show or edit the todo list without leaving the session."},{id:"goal-command",bindings:[],requiresCommand:"goal",render:()=>`Use /goal to set a persistent goal ${APP_NAME} keeps pursuing, then pause, resume, or clear it.`},{id:"btw-command",bindings:[],requiresCommand:"btw",render:()=>"Use /btw to ask a side question in a parallel session without disturbing this one."},{id:"lookat-command",bindings:[],requiresCommand:"lookat",render:()=>"Use /lookat to manage the vision-model chain the look_at tool uses for images and screenshots."},{id:"mcp-command",bindings:[],requiresCommand:"mcp",render:()=>"Use /mcp to inspect and manage the MCP servers wired into this session."},{id:"rules-command",bindings:[],requiresCommand:"rules",render:()=>"Use /rules to see which rules are loaded, and /reload-rules to re-read them mid-session."},{id:"hooks-command",bindings:[],requiresCommand:"hooks",render:()=>"Use /hooks to list loaded hook sources and their diagnostics."},{id:"websearch-command",bindings:[],requiresCommand:"websearch",render:()=>"Use /websearch to check which web-search provider is currently active."}];var TIP_DEFINITIONS=[...MODEL_TIPS,...INPUT_TIPS,...SESSION_TIPS,...WORKSPACE_TIPS,...SETTINGS_TIPS,...CLI_TIPS,...SUBAGENT_TIPS,...MEMORY_TIPS,...DAG_TIPS,...COMPUTER_TIPS,...ETHOS_TIPS];export{TIP_DEFINITIONS};
2
+ import{APP_NAME,CONFIG_DIR_NAME,agentDirLabel}from"./chunk-WCAKUCN3.js";var CLI_TIPS=[{id:"print-mode",bindings:[],render:()=>`${APP_NAME} -p "question" answers without the TUI, and piped stdin is merged into the prompt.`},{id:"tool-flags",bindings:[],render:()=>"Limit a run's tools with -t read,bash, or drop a few with -xt write,edit."}];function stopChord(){return process.platform==="darwin"?"Control+Option+Command+Escape":"Ctrl+Alt+Shift+Escape"}var COMPUTER_TIPS=[{id:"computer.what-it-is",bindings:[],requiresCommand:"computer",render:()=>"Experimental: your agent can use native apps too: screenshots, windows, clicks and typing. Run /computer to see whether this machine is ready."},{id:"computer.stop-chord",bindings:[],requiresCommand:"computer",render:()=>`Press ${stopChord()} at any moment to stop computer input. It stays stopped until you run /computer resume; the agent cannot resume it.`},{id:"computer.background-input",bindings:[],requiresCommand:"computer",render:()=>"Computer use clicks and types into the target app in the background, so your frontmost app, keyboard focus and cursor stay where you left them."},{id:"computer.look-dont-touch",bindings:[],requiresCommand:"computer",render:()=>"Want the agent to look but not touch? Start with --permission computer:exec=deny: screenshots and accessibility reads still work, clicks and typing are refused."},{id:"computer.permissions",bindings:[],requiresCommand:"computer",render:()=>"On macOS, computer use needs Screen Recording and Accessibility for the app you launch from. /computer status shows which one is missing."}];var DAG_TIPS=[{id:"dag.one-keyword-mastery",bindings:[],requiresCommand:"dag",render:()=>'One keyword makes you a master of graph engineering: say "mass-ulw" and your work becomes a dependency graph that schedules itself.'},{id:"dag.what-it-is",bindings:[],requiresCommand:"dag",render:()=>'Trigger "mass-ulw" when some tasks must wait for others - describe the work, get a graph that runs in the right order.'},{id:"dag.parallel-waves",bindings:[],requiresCommand:"dag",render:()=>"A graph run executes in waves: everything with no pending dependency starts at once, the rest starts the moment it is unblocked."},{id:"dag.depends-on",bindings:[],requiresCommand:"dag",render:()=>"Say what needs what - review after implementation, docs after both - and the ordering is enforced for you."},{id:"dag.categories",bindings:[],requiresCommand:"dag",render:()=>"Each node in the graph picks its own worker category, so cheap steps stay cheap and hard steps get the strong model."},{id:"dag.status-view",bindings:[],requiresCommand:"dag",render:()=>"Use /dag to watch a run: which nodes finished, which are running, and which one failed."},{id:"dag.resume",bindings:[],requiresCommand:"dag",render:()=>"Graph runs are journaled - if the session dies mid-run it resumes later and never redoes the nodes that already finished."},{id:"dag.vs-parallel",bindings:[],requiresCommand:"dag",render:()=>"Fully independent jobs just need parallel subagents; reach for a graph when the ordering between them is the whole point."},{id:"dag.scale",bindings:[],requiresCommand:"dag",render:()=>"Stop hand-running steps in sequence. Describe the dependencies once and let a dozen agents fan out and rejoin on their own."}];var ETHOS_TIPS=[{id:"ethos.tuning-discipline",bindings:[],render:()=>"gpt-5.6-sol used to turn a sprint into a marathon. We tuned the system prompt and killed that habit: 5-minute jobs take 5 minutes, 12-hour jobs take 12."},{id:"ethos.tools-transparent",bindings:[],render:()=>"Don't study our tools. A tool that needs studying is a tool that failed. We just ride shotgun while you keep doing your actual job."},{id:"ethos.only-harness",bindings:[],render:()=>"The only harness that actually knows how to drive gpt-5.6-sol. Same job, feels up to 30% faster. *we counted*"},{id:"ethos.spend-tokens",bindings:[],render:()=>"Stop hoarding tokens. Spend them like they buy your hours back, because they do."},{id:"ethos.deep-work",bindings:[],render:()=>"Using our tools means your work is already the deep, valuable kind. Keep your eyes on the essence of your craft. The rest is our problem now, and we're great at problems."},{id:"ethos.ulw-plan-sage",bindings:[],requiresCommand:"tasks",render:()=>"Try ulw-plan on fable-5.1 xhigh. A patient sage obsessed with the essence does the agonizing for you and fills in every blank you were pretending not to see."},{id:"ethos.ulw-loop-shallow",bindings:[],requiresCommand:"tasks",render:()=>"For days when deep thought sounds awful, run the ulw loop with gpt-6-sol fast/medium. Fair warning: shallow thinking sends invoices."},{id:"ethos.monitor-subscribe",bindings:[],render:()=>"Subscribe to a command's stdout and forget it. CI finishes, server boots, log line lands... you're mid-edit and the news finds *you*. No sleep loops, no polling, no re-reading context like a chump."},{id:"ethos.cache-budget",bindings:[],render:()=>"My harness knows the prompt cache's expiry to the second and never blocks past it. Cold re-read tax? *Refused on your behalf.* Other agents eat that cost, mine declines it."},{id:"ethos.cache-hit-rate",bindings:[],render:()=>"Live cache-hit rate in the footer, plus a running tab of misses, idle gaps, and model swaps. I can point at the exact moment cache broke and why. Watching tokens you never re-pay stack up? Smug doesn't cover it."},{id:"ethos.multimodal-vision",bindings:[],render:()=>`Drop a screenshot, a PDF, a crusty whiteboard photo... ${APP_NAME} actually sees it, reads it, reasons about it. Your agent has eyes now. *Yes, really.*`},{id:"ethos.oauth-multi-account",bindings:[],render:()=>`Hit a rate limit, switch accounts. Wrong org, switch again. ${APP_NAME} treats your Claude logins like a roster, not a single lifeline. *Env vars could never.*`},{id:"ethos.agent-sdk-foundation",bindings:[],render:()=>'Built on the official agent SDK, speaking the protocol natively. No reverse-engineered wrapper, no ToS gray zone, no "will I get banned for this" anxiety. *Sleep easy, ship loud.*'},{id:"ethos.tool-call-repair",bindings:[],render:()=>`${APP_NAME} catches malformed tool calls on the wire, fixes them, and salvages the turn - claude's sloppy invokes, kimi k3's leaked XTML channels, all of it. Other harnesses retry the whole thing and bill you for the privilege. *table stakes, honestly*`}];var INPUT_TIPS=[{id:"click-pending-question",bindings:[],render:()=>"Click a pending question's option to answer. Use the displayed selection-bypass modifier to select terminal text, or disable terminal.mouse in /settings."},{id:"queue-follow-up",bindings:["app.message.followUp"],render:keys=>`While the agent is working, use ${keys("app.message.followUp")} to queue a follow-up for after it finishes.`},{id:"steering-message",bindings:["tui.input.submit","app.message.followUp"],render:keys=>`Press ${keys("tui.input.submit")} while the agent works to steer it after the current tool batch; ${keys("app.message.followUp")} waits until all work is done.`},{id:"edit-queued-message",bindings:["app.message.dequeue"],render:keys=>`Use ${keys("app.message.dequeue")} to bring queued messages back for editing.`},{id:"interrupt-restores-queue",bindings:["app.interrupt"],render:keys=>`Press ${keys("app.interrupt")} to abort the current turn and restore queued messages to the editor.`},{id:"file-reference",bindings:[],render:()=>"Type @ in the editor to fuzzy-search project files and insert their paths."},{id:"path-completion",bindings:["tui.input.tab"],render:keys=>`Press ${keys("tui.input.tab")} to complete file paths while typing.`},{id:"shortcut-overlay",bindings:[],render:()=>"Type ? in an empty editor to pop up the full shortcut grid."},{id:"prompt-history",bindings:["app.history.search"],requiresCommand:"history",render:keys=>`Search prompt history across sessions with ${keys("app.history.search")}.`},{id:"external-editor",bindings:["app.editor.external"],render:keys=>`Open the current prompt in your external editor with ${keys("app.editor.external")}.`},{id:"expand-tool-output",bindings:["app.tools.expand"],render:keys=>`Collapse or expand tool output with ${keys("app.tools.expand")}.`},{id:"thinking-blocks",bindings:["app.thinking.toggle"],render:keys=>`Collapse or expand thinking blocks with ${keys("app.thinking.toggle")}.`},{id:"paste-image",bindings:["app.clipboard.pasteImage"],render:keys=>`Paste an image from the clipboard with ${keys("app.clipboard.pasteImage")}.`},{id:"copy-message",bindings:["app.message.copy"],render:keys=>`Copy the latest assistant message with ${keys("app.message.copy")}.`},{id:"input-newline",bindings:["tui.input.newLine"],render:keys=>`Insert a newline without sending with ${keys("tui.input.newLine")}.`},{id:"bash-prefixes",bindings:[],render:()=>"Prefix a prompt with ! to run bash, or !! to run bash without adding its output to model context."},{id:"drag-drop-files",bindings:[],render:()=>"Drag and drop files into the terminal to add their paths to your prompt."},{id:"answer-agent-question",bindings:[],render:()=>"When the agent asks you a question, pick options with digits or arrows, press Enter to advance, and use the final Submit tab for a comment or partial answers; anything unanswered is reported back as unanswered."},{id:"open-pending-question",bindings:["app.question.answer","app.question.next"],render:keys=>`Pending questions queue above the editor. An empty-composer digit selects an option; ${keys("app.question.answer")} opens the shown request and ${keys("app.question.next")} cycles requests. /answer lists them.`}];var MEMORY_TIPS=[{id:"memory.persistent",bindings:[],requiresCommand:"memory",render:()=>`${APP_NAME} remembers across sessions. Close the terminal, come back tomorrow, and the context is still there.`},{id:"memory.remember-command",bindings:[],requiresCommand:"remember",render:()=>"Use /remember to save something you want kept - a preference, a decision, a fact worth reusing."},{id:"memory.just-tell-it",bindings:[],requiresCommand:"remember",render:()=>'You can also just say it: "remember that we deploy on Fridays" is enough. No syntax, no file to open.'},{id:"memory.search-command",bindings:[],requiresCommand:"search",render:()=>"Use /search to look through everything remembered so far, in plain words."},{id:"memory.memory-command",bindings:[],requiresCommand:"memory",render:()=>"Use /memory to see what is currently remembered about you and this project."},{id:"memory.init-command",bindings:[],requiresCommand:"init",render:()=>"Use /init to start memory for a new project, so it learns this codebase from the first session."},{id:"memory.people-command",bindings:[],requiresCommand:"people",render:()=>"Use /people to keep notes on teammates - who owns what, who to ask, what they prefer."},{id:"memory.reflect-command",bindings:[],requiresCommand:"reflect",render:()=>"Use /reflect to have the session reviewed now and the parts worth keeping written down."},{id:"memory.dream-command",bindings:[],requiresCommand:"dream",render:()=>"Memory tidies itself in the background between turns - /dream shows that work and lets you start it yourself."},{id:"memory.sleeptime-command",bindings:[],requiresCommand:"sleeptime",render:()=>"Use /sleeptime to decide how often memory reorganizes itself while you are not looking."},{id:"memory.memfs-command",bindings:[],requiresCommand:"memfs",render:()=>"Memory is plain files you own - browse them with /memfs and edit anything that looks wrong."},{id:"memory.repository-command",bindings:[],requiresCommand:"memory-repository",render:()=>"Every memory change is a git commit - use /memory-repository to see the history and undo a bad one."},{id:"memory.doctor-command",bindings:[],requiresCommand:"doctor",render:()=>"Use /doctor when memory feels off; it checks the setup and tells you what to fix."},{id:"memory.facts-command",bindings:[],requiresCommand:"facts",render:()=>"Use /facts to see the individual things learned about you, and drop the ones that no longer hold."},{id:"memory.recompile-command",bindings:[],requiresCommand:"recompile",render:()=>"Edited memory files by hand? Run /recompile so this session picks the changes up right away."},{id:"memory.aha-moment",bindings:[],requiresCommand:"memory",render:()=>"Memory speaks up on its own: when something remembered would change the next step, an Aha moment! line surfaces it mid-task. Silence means nothing relevant was found."},{id:"memory.stop-repeating",bindings:[],requiresCommand:"memory",render:()=>"Explain your setup once. Memory means you stop re-explaining it at the start of every session."}];var MODEL_TIPS=[{id:"thinking-level",bindings:["app.thinking.cycle"],render:keys=>`Use /thinking <level> to set the thinking level, /thinking to pick one, or ${keys("app.thinking.cycle")} to cycle through them.`},{id:"efforts-command",bindings:[],requiresCommand:"efforts",render:()=>"Use /efforts <level> to set the reasoning effort for the current model; /efforts alone lists the levels it supports."},{id:"favorite-model-rotation",bindings:["app.model.cycleForward","app.model.cycleBackward"],render:keys=>`Rotate through favorite models with ${keys("app.model.cycleForward")}; go backward with ${keys("app.model.cycleBackward")}.`},{id:"model-selector-favorites",bindings:["app.model.select","app.models.toggleFavorite"],render:keys=>`Open the model selector with ${keys("app.model.select")}, then use ${keys("app.models.toggleFavorite")} to toggle the highlighted favorite.`},{id:"model-command-search",bindings:[],render:()=>"Use /model to open the selector, or /model <pattern> to jump straight to a matching model."},{id:"model-cycling-scope",bindings:["app.model.cycleForward"],render:keys=>`Start ${APP_NAME} with --models "anthropic/*,gpt-5*" to limit which models ${keys("app.model.cycleForward")} cycles through.`},{id:"thinking-budgets",bindings:[],render:()=>"Set thinkingBudgets in settings.json to choose the token budget behind each thinking level."},{id:"prompt-preset",bindings:[],render:()=>"Set promptPreset in settings.json when a model does not auto-detect the system prompt you want."},{id:"provider-login",bindings:[],render:()=>"Use /login to add a subscription or API-key provider, and /logout to remove stored credentials."},{id:"fallback-chains-setting",bindings:[],render:()=>"retry.fallbackChains in settings.json maps a model to ordered fallbacks, so a failed turn retries on the next one."},{id:"fallback-command",bindings:[],requiresCommand:"fallback",render:()=>"Use /fallback to inspect and manage the retry fallback chain for the current model."}];var SESSION_TIPS=[{id:"favorite-models-command",bindings:[],render:()=>"Use /favorite-models to choose and reorder the models in your rotation."},{id:"tree-command",bindings:[],render:()=>"Use /tree to revisit earlier points and switch between session branches."},{id:"fork-command",bindings:[],render:()=>"Use /fork to create a separate session from an earlier user message."},{id:"clone-session",bindings:[],render:()=>"Use /clone to duplicate the current branch into its own session before trying something risky."},{id:"continue-session",bindings:[],render:()=>`Use /resume or /sessions to reopen a past session; from the shell, ${APP_NAME} -r opens the same picker and ${APP_NAME} -c continues the most recent one.`},{id:"session-name",bindings:[],render:()=>"Use /rename [name] to label a session so it is easy to spot in the footer and in /resume."},{id:"session-info",bindings:[],render:()=>"Use /session to see the session file, id, message count, tokens, and cost."},{id:"export-share",bindings:[],render:()=>"Use /export to write the session to HTML or JSONL, or /share to upload it as a private gist link."},{id:"compact-command",bindings:[],render:()=>"Use /compact to compact context now, or /compact <prompt> to tell the summarizer what to keep."},{id:"auto-compaction",bindings:[],render:()=>"Auto-compaction is on by default - the (auto) marker in the footer shows it; tune it with compaction.* in settings.json."}];var SETTINGS_TIPS=[{id:"settings-locations",bindings:[],render:()=>`Use /settings for common options; the rest live in settings.json, with ${CONFIG_DIR_NAME}/settings.json overriding per project.`},{id:"permission-preset",bindings:[],render:()=>'Set permissionPreset to "workspace", "read-only", or "ask" to decide which tool calls need your approval.'},{id:"packages-setting",bindings:[],render:()=>"The packages setting loads skills, extensions, prompts, and themes from an npm or git package."},{id:"custom-themes",bindings:[],render:()=>`Switch themes from /settings, and drop custom theme files in ${agentDirLabel()}/themes.`},{id:"reload-resources",bindings:[],render:()=>"Use /reload to re-read keybindings, extensions, skills, prompts, themes, and context files without restarting."},{id:"project-trust",bindings:[],render:()=>"Use /trust to save a trust decision so this project's settings, skills, and extensions load next time."},{id:"tips-toggle",bindings:[],render:()=>'Set "tips": false in settings.json to stop showing these tips.'}];var SUBAGENT_TIPS=[{id:"workflow-skills.plan",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "ulw plan" to get an explored, decision-complete plan under .omo/plans/.'},{id:"workflow-skills.start-work",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "$start-work <plan-name>" to execute a plan end-to-end in a fresh session.'},{id:"workflow-skills.ultrawork",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "ulw" or "ulw loop" for a long, evidence-driven autonomous run in ultrawork mode.'},{id:"workflow-skills.research",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "ulw-research" for a saturating, citation-backed investigation across the codebase, docs, and the web.'},{id:"workflow-skills.hyperplan",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "hyperplan" to have adversarial reviewers attack a plan before you commit to it.'},{id:"workflow-skills.review",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "review work" to run parallel goal, quality, security, and hands-on QA reviews.'},{id:"workflow-skills.init-deep",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "/init-deep" to map a project and generate a hierarchical AGENTS.md knowledge base.'},{id:"workflow-skills.debugging",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "debug this" for parallel hypotheses, a failing regression test, a minimal fix, and real-surface QA.'},{id:"workflow-skills.refactor",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "refactor" for codebase-aware cleanup that pins behavior before changing structure.'},{id:"workflow-skills.remove-ai-slops",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "remove AI slop" to lock behavior first, then strip generated-code smells without drive-by rewrites.'},{id:"workflow-skills.visual-qa",bindings:[],requiresCommand:"tasks",render:()=>'Trigger "visual QA" to capture browser or xterm evidence and review web or terminal interfaces.'},{id:"workflow-skills.report-bug",bindings:[],requiresCommand:"tasks",render:()=>'Hit a bug? Say "report a bug" - the report-bug skill finds the session, records the exact provider and model, routes it to the right repository, and files an evidence-backed issue only after you confirm.'},{id:"subagent-categories",bindings:[],requiresCommand:"tasks",render:()=>"Delegate by category - quick, deep, ultrabrain, architect, artistry, git, writing - each runs on its own model."},{id:"subagent-commands",bindings:[],requiresCommand:"tasks",render:()=>"Use /tasks to see this session's background subagents, and /task-kill to stop one."},{id:"subagent-config",bindings:[],requiresCommand:"tasks",render:()=>"~/.omo/omo.jsonc maps every subagent category to its model, reasoning effort, and fallback chain."},{id:"subagent-team",bindings:[],requiresCommand:"tasks",render:()=>"Ask for a team when one task needs several agents at once: members share a tasklist and report back to you."}];var WORKSPACE_TIPS=[{id:"help-command",bindings:[],requiresCommand:"help",render:()=>"Use /help to see available commands and guidance."},{id:"keybindings-command",bindings:[],render:()=>"Use /keybindings to review and customize keyboard shortcuts."},{id:"agents-md-context",bindings:[],render:()=>`${APP_NAME} loads AGENTS.md from your home directory, every parent folder, and the current folder as project instructions.`},{id:"skills-and-prompts",bindings:[],render:()=>`Skills run as /skill:name, and prompt templates in ${agentDirLabel()}/prompts expand as /templatename.`},{id:"files-command",bindings:[],requiresCommand:"files",render:()=>"Use /files to list every file this session read, wrote, or edited."},{id:"diff-command",bindings:[],requiresCommand:"diff",render:()=>"Use /diff to review this session's git changes and open them in a diff view."},{id:"todo-command",bindings:[],requiresCommand:"todo",render:()=>"Use /todo to show or edit the todo list without leaving the session."},{id:"goal-command",bindings:[],requiresCommand:"goal",render:()=>`Use /goal to set a persistent goal ${APP_NAME} keeps pursuing, then pause, resume, or clear it.`},{id:"btw-command",bindings:[],requiresCommand:"btw",render:()=>"Use /btw to ask a side question in a parallel session without disturbing this one."},{id:"lookat-command",bindings:[],requiresCommand:"lookat",render:()=>"Use /lookat to manage the vision-model chain the look_at tool uses for images and screenshots."},{id:"mcp-command",bindings:[],requiresCommand:"mcp",render:()=>"Use /mcp to inspect and manage the MCP servers wired into this session."},{id:"rules-command",bindings:[],requiresCommand:"rules",render:()=>"Use /rules to see which rules are loaded, and /reload-rules to re-read them mid-session."},{id:"hooks-command",bindings:[],requiresCommand:"hooks",render:()=>"Use /hooks to list loaded hook sources and their diagnostics."},{id:"websearch-command",bindings:[],requiresCommand:"websearch",render:()=>"Use /websearch to check which web-search provider is currently active."}];var TIP_DEFINITIONS=[...MODEL_TIPS,...INPUT_TIPS,...SESSION_TIPS,...WORKSPACE_TIPS,...SETTINGS_TIPS,...CLI_TIPS,...SUBAGENT_TIPS,...MEMORY_TIPS,...DAG_TIPS,...COMPUTER_TIPS,...ETHOS_TIPS];export{TIP_DEFINITIONS};
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{require_semver}from"./chunk-ZOFZRJSL.js";import{fetchWithRetry}from"./chunk-2SOVDETB.js";import{APP_NAME,BRAND,DISPLAY_VERSION,PACKAGE_NAME,brandProfile,envValue}from"./chunk-PBWQK23Z.js";import{__toESM}from"./chunk-IKOFCODM.js";import{spawnSync}from"node:child_process";import{homedir as osHomedir}from"node:os";import{posix,win32}from"node:path";var RUNTIME_ENV_VAR="SENPI_RUNTIME",MIN_BUN_VERSION="1.4.0";function normalize(path){return path.replaceAll("\\","/")}function paths(options){return options.platform==="win32"?win32:posix}function bunRoot(options){let configured=options.env.BUN_INSTALL;return configured!==void 0&&configured.trim()!==""?configured:paths(options).join(options.homedir,".bun")}function resolveOrSelf(path,options){try{return options.realpath(path)}catch{return path}}function isUnderBunGlobalTree(scriptRealPath,options){let globalRoot=paths(options).join(bunRoot(options),"install","global"),script=normalize(scriptRealPath);for(let candidate of new Set([globalRoot,resolveOrSelf(globalRoot,options)]))if(script.startsWith(`${normalize(candidate)}/`))return!0;return!1}function isInstalledPackageScript(scriptRealPath){return normalize(scriptRealPath).includes("/node_modules/")}function bunVersionSatisfies(version){let actual=/^v?(\d+)\.(\d+)\.(\d+)/.exec(version?.trim()??""),minimum=/^(\d+)\.(\d+)\.(\d+)/.exec(MIN_BUN_VERSION);if(!actual||!minimum)return!1;for(let index=1;index<=3;index++){let difference=Number(actual[index])-Number(minimum[index]);if(difference!==0)return difference>0}return!0}function bunExecutableName(options){return options.platform==="win32"?"bun.exe":"bun"}function pathCandidateNames(options){if(options.platform!=="win32")return["bun"];let extensions=(options.env.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").map(extension=>extension.trim()).filter(extension=>extension.length>0);return extensions.length>0?extensions.map(extension=>`bun${extension}`):["bun.exe"]}function findBunBinary(options){let path=paths(options),executable=bunExecutableName(options),rootCandidates=[path.join(bunRoot(options),"bin",executable),path.join(options.homedir,".bun","bin",executable)];for(let candidate of rootCandidates)if(options.exists(candidate))return candidate;let pathValue=options.env.PATH??options.env.Path;if(pathValue===void 0||pathValue==="")return;let names=pathCandidateNames(options);for(let directory of pathValue.split(path.delimiter))if(directory!=="")for(let name of names){let candidate=path.join(directory,name);if(options.exists(candidate))return candidate}}function readRuntimePin(options){let value=options.env[RUNTIME_ENV_VAR];if(value==="node"||value==="bun")return value}function resolveBunReexec(input){if(input.versions.bun!==void 0)return{action:"stay",reason:"already-bun"};let pinned=readRuntimePin(input.options);if(pinned==="node")return{action:"stay",reason:"runtime-pinned-node"};if(input.hasInheritedInspectorOption)return{action:"stay",reason:"inspector"};let trustsInstalledBun=pinned==="bun"||isUnderBunGlobalTree(input.scriptRealPath,input.options);if(!trustsInstalledBun&&!isInstalledPackageScript(input.scriptRealPath))return{action:"stay",reason:"not-bun-install"};let bunPath=findBunBinary(input.options);return bunPath===void 0?{action:"stay",reason:"bun-not-found"}:!trustsInstalledBun&&!bunVersionSatisfies(input.options.bunVersion(bunPath))?{action:"stay",reason:"bun-too-old"}:{action:"reexec",bunPath}}function readBunVersion(bunPath){try{let result=spawnSync(bunPath,["--version"],{encoding:"utf8",timeout:5e3,windowsHide:!0});if(result.status!==0)return;let version=result.stdout.trim();return version===""?void 0:version}catch{return}}function processBunRuntimeOptions(exists,realpath){return{env:process.env,homedir:osHomedir(),platform:process.platform,exists,realpath,bunVersion:readBunVersion}}import{close as closeInspector,url as inspectorUrl}from"node:inspector";var VM_DYNAMIC_IMPORT_CALLBACK_MISSING="ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING",INSPECTOR_IMPORT_FRAME="at importModuleDynamicallyCallback (node:internal/modules/esm/",INSPECTOR_TIMEOUT_FRAME=/\bat Timeout\._onTimeout \(<anonymous>:\d+:\d+\)/,RECOVER_INSPECTOR_VM_IMPORT=envValue("RECOVER_INSPECTOR_VM_IMPORT")==="1",INSPECTOR_VM_IMPORT_WARNING="Node Inspector dynamic import is unsupported; use require() or a target-side loader. Senpi kept running.";function hasInheritedInspectorOption(){return process.execArgv.some(argument=>argument.startsWith("--inspect"))||process.env.NODE_OPTIONS?.includes("--inspect")===!0}function releaseInheritedInspectorForChild(){inspectorUrl()!==void 0&&hasInheritedInspectorOption()&&closeInspector()}function isRecoverableInspectorVmImportError(error,origin){if(!RECOVER_INSPECTOR_VM_IMPORT||origin!=="unhandledRejection")return!1;try{return inspectorUrl()===void 0||typeof error!="object"||error===null||!("code"in error)||!("stack"in error)?!1:error.code===VM_DYNAMIC_IMPORT_CALLBACK_MISSING&&typeof error.stack=="string"&&error.stack.includes(INSPECTOR_IMPORT_FRAME)&&INSPECTOR_TIMEOUT_FRAME.test(error.stack)}catch{return!1}}var earlyRecoveryCount=0,earlyRecoveryInstalled=!1;function installEarlyInspectorVmImportRecovery(){!RECOVER_INSPECTOR_VM_IMPORT||earlyRecoveryInstalled||(earlyRecoveryInstalled=!0,process.on("uncaughtException",(error,origin)=>{let otherHandlerActive=process.listenerCount("uncaughtException")>1;if(isRecoverableInspectorVmImportError(error,origin)){otherHandlerActive||earlyRecoveryCount++;return}otherHandlerActive||(console.error(error),process.exit(1))}))}function consumeEarlyInspectorVmImportRecoveries(){let count=earlyRecoveryCount;return earlyRecoveryCount=0,count}function getPiUserAgent(version=DISPLAY_VERSION){let runtime=process.versions.bun?`bun/${process.versions.bun}`:`node/${process.version}`;return`${BRAND?.userAgent??APP_NAME}/${version} (${process.platform}; ${runtime}; ${process.arch})`}var import_semver=__toESM(require_semver(),1);var REGISTRY_BASE_URL="https://registry.npmjs.org",LATEST_VERSION_URL=`${REGISTRY_BASE_URL}/${encodeURIComponent(PACKAGE_NAME)}/latest`;function latestVersionUrl(channel){return channel?`${REGISTRY_BASE_URL}/-/package/${encodeURIComponent(channel.packageName)}/dist-tags`:LATEST_VERSION_URL}function readAvailableVersion(payload,channel){if(typeof payload!="object"||payload===null)return;let source=payload,raw=channel?source[channel.distTag]:source.version;return typeof raw=="string"&&raw.trim()?raw.trim():void 0}var DEFAULT_VERSION_CHECK_TIMEOUT_MS=1e4,RELEASE_CHANGELOG_BASE_URL="https://github.com/code-yeongyu/senpi/blob",RELEASE_CHANGELOG_PATH="packages/coding-agent/CHANGELOG.md",SENPI_CALVER_PATTERN=/^(\d{4})\.(\d{1,2})\.(\d{1,2})(?:-([2-9]\d*))?$/;function parseSenpiCalVer(version){let match=SENPI_CALVER_PATTERN.exec(version);if(match)return[Number(match[1]),Number(match[2]),Number(match[3]),Number(match[4]??1)]}function formatVersionCheckError(error){let rootMessage=error instanceof Error&&error.message?error.message:String(error),cause=error instanceof Error?error.cause:void 0,causes=cause instanceof AggregateError?cause.errors:cause===void 0?[]:[cause],codes=causes.map(value=>typeof value=="object"&&value!==null&&"code"in value&&typeof value.code=="string"?value.code:void 0).filter(code=>code!==void 0);if(codes.length>0)return`${rootMessage} (${[...new Set(codes)].join(", ")})`;let causeMessage=causes.find(value=>value instanceof Error&&!!value.message)?.message;return causeMessage?`${rootMessage} (cause: ${causeMessage})`:rootMessage}function comparePackageVersions(leftVersion,rightVersion){let leftTrimmed=leftVersion.trim(),rightTrimmed=rightVersion.trim(),leftCalVer=parseSenpiCalVer(leftTrimmed),rightCalVer=parseSenpiCalVer(rightTrimmed);if(leftCalVer&&rightCalVer){for(let index=0;index<leftCalVer.length;index++)if(leftCalVer[index]!==rightCalVer[index])return leftCalVer[index]<rightCalVer[index]?-1:1;return 0}let left=(0,import_semver.valid)(leftTrimmed),right=(0,import_semver.valid)(rightTrimmed);if(!(!left||!right))return(0,import_semver.compare)(left,right)}function isNewerPackageVersion(candidateVersion,currentVersion){let comparison=comparePackageVersions(candidateVersion,currentVersion);return comparison!==void 0&&comparison>0}function getReleaseChangelogUrl(version){let trimmedVersion=version.trim(),channel=brandProfile()?.update;if(channel?.changelogUrl)return channel.changelogUrl.replace("{version}",trimmedVersion);let tag=trimmedVersion.startsWith("v")?trimmedVersion:`v${trimmedVersion}`;return`${RELEASE_CHANGELOG_BASE_URL}/${tag}/${RELEASE_CHANGELOG_PATH}`}async function getLatestPiRelease(currentVersion,options={}){if(envValue("OFFLINE"))return;let brand=brandProfile(),channel=brand?.update;if(brand&&!channel)return;let response=await fetchWithRetry(latestVersionUrl(channel),{headers:{"User-Agent":getPiUserAgent(currentVersion),accept:"application/json"}},{maxRetries:options.retry?2:0,timeoutMs:options.timeoutMs??DEFAULT_VERSION_CHECK_TIMEOUT_MS});if(!response.ok)return;let data=await response.json(),availableVersion=readAvailableVersion(data,channel);if(!availableVersion)return;if(channel)return{version:availableVersion,packageName:channel.packageName};let packageName=typeof data.packageName=="string"&&data.packageName.trim()?data.packageName.trim():void 0,note=typeof data.note=="string"&&data.note.trim()?data.note.trim():void 0;return{version:availableVersion,packageName,note}}async function checkForNewPiVersion(currentVersion){if(!envValue("SKIP_VERSION_CHECK"))try{let latestRelease=await getLatestPiRelease(currentVersion);return latestRelease&&isNewerPackageVersion(latestRelease.version,currentVersion)?latestRelease:void 0}catch{return}}export{RUNTIME_ENV_VAR,MIN_BUN_VERSION,bunVersionSatisfies,findBunBinary,resolveBunReexec,processBunRuntimeOptions,INSPECTOR_VM_IMPORT_WARNING,hasInheritedInspectorOption,releaseInheritedInspectorForChild,isRecoverableInspectorVmImportError,installEarlyInspectorVmImportRecovery,consumeEarlyInspectorVmImportRecoveries,getPiUserAgent,formatVersionCheckError,isNewerPackageVersion,getReleaseChangelogUrl,getLatestPiRelease,checkForNewPiVersion};
2
+ import{require_semver}from"./chunk-ZOFZRJSL.js";import{fetchWithRetry}from"./chunk-2SOVDETB.js";import{APP_NAME,BRAND,DISPLAY_VERSION,PACKAGE_NAME,brandProfile,envValue}from"./chunk-WCAKUCN3.js";import{__toESM}from"./chunk-IKOFCODM.js";import{spawnSync}from"node:child_process";import{homedir as osHomedir}from"node:os";import{posix,win32}from"node:path";var RUNTIME_ENV_VAR="SENPI_RUNTIME",MIN_BUN_VERSION="1.4.0";function normalize(path){return path.replaceAll("\\","/")}function paths(options){return options.platform==="win32"?win32:posix}function bunRoot(options){let configured=options.env.BUN_INSTALL;return configured!==void 0&&configured.trim()!==""?configured:paths(options).join(options.homedir,".bun")}function resolveOrSelf(path,options){try{return options.realpath(path)}catch{return path}}function isUnderBunGlobalTree(scriptRealPath,options){let globalRoot=paths(options).join(bunRoot(options),"install","global"),script=normalize(scriptRealPath);for(let candidate of new Set([globalRoot,resolveOrSelf(globalRoot,options)]))if(script.startsWith(`${normalize(candidate)}/`))return!0;return!1}function isInstalledPackageScript(scriptRealPath){return normalize(scriptRealPath).includes("/node_modules/")}function bunVersionSatisfies(version){let actual=/^v?(\d+)\.(\d+)\.(\d+)/.exec(version?.trim()??""),minimum=/^(\d+)\.(\d+)\.(\d+)/.exec(MIN_BUN_VERSION);if(!actual||!minimum)return!1;for(let index=1;index<=3;index++){let difference=Number(actual[index])-Number(minimum[index]);if(difference!==0)return difference>0}return!0}function bunExecutableName(options){return options.platform==="win32"?"bun.exe":"bun"}function pathCandidateNames(options){if(options.platform!=="win32")return["bun"];let extensions=(options.env.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").map(extension=>extension.trim()).filter(extension=>extension.length>0);return extensions.length>0?extensions.map(extension=>`bun${extension}`):["bun.exe"]}function findBunBinary(options){let path=paths(options),executable=bunExecutableName(options),rootCandidates=[path.join(bunRoot(options),"bin",executable),path.join(options.homedir,".bun","bin",executable)];for(let candidate of rootCandidates)if(options.exists(candidate))return candidate;let pathValue=options.env.PATH??options.env.Path;if(pathValue===void 0||pathValue==="")return;let names=pathCandidateNames(options);for(let directory of pathValue.split(path.delimiter))if(directory!=="")for(let name of names){let candidate=path.join(directory,name);if(options.exists(candidate))return candidate}}function readRuntimePin(options){let value=options.env[RUNTIME_ENV_VAR];if(value==="node"||value==="bun")return value}function resolveBunReexec(input){if(input.versions.bun!==void 0)return{action:"stay",reason:"already-bun"};let pinned=readRuntimePin(input.options);if(pinned==="node")return{action:"stay",reason:"runtime-pinned-node"};if(input.hasInheritedInspectorOption)return{action:"stay",reason:"inspector"};let trustsInstalledBun=pinned==="bun"||isUnderBunGlobalTree(input.scriptRealPath,input.options);if(!trustsInstalledBun&&!isInstalledPackageScript(input.scriptRealPath))return{action:"stay",reason:"not-bun-install"};let bunPath=findBunBinary(input.options);return bunPath===void 0?{action:"stay",reason:"bun-not-found"}:!trustsInstalledBun&&!bunVersionSatisfies(input.options.bunVersion(bunPath))?{action:"stay",reason:"bun-too-old"}:{action:"reexec",bunPath}}function readBunVersion(bunPath){try{let result=spawnSync(bunPath,["--version"],{encoding:"utf8",timeout:5e3,windowsHide:!0});if(result.status!==0)return;let version=result.stdout.trim();return version===""?void 0:version}catch{return}}function processBunRuntimeOptions(exists,realpath){return{env:process.env,homedir:osHomedir(),platform:process.platform,exists,realpath,bunVersion:readBunVersion}}import{close as closeInspector,url as inspectorUrl}from"node:inspector";var VM_DYNAMIC_IMPORT_CALLBACK_MISSING="ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING",INSPECTOR_IMPORT_FRAME="at importModuleDynamicallyCallback (node:internal/modules/esm/",INSPECTOR_TIMEOUT_FRAME=/\bat Timeout\._onTimeout \(<anonymous>:\d+:\d+\)/,RECOVER_INSPECTOR_VM_IMPORT=envValue("RECOVER_INSPECTOR_VM_IMPORT")==="1",INSPECTOR_VM_IMPORT_WARNING="Node Inspector dynamic import is unsupported; use require() or a target-side loader. Senpi kept running.";function hasInheritedInspectorOption(){return process.execArgv.some(argument=>argument.startsWith("--inspect"))||process.env.NODE_OPTIONS?.includes("--inspect")===!0}function releaseInheritedInspectorForChild(){inspectorUrl()!==void 0&&hasInheritedInspectorOption()&&closeInspector()}function isRecoverableInspectorVmImportError(error,origin){if(!RECOVER_INSPECTOR_VM_IMPORT||origin!=="unhandledRejection")return!1;try{return inspectorUrl()===void 0||typeof error!="object"||error===null||!("code"in error)||!("stack"in error)?!1:error.code===VM_DYNAMIC_IMPORT_CALLBACK_MISSING&&typeof error.stack=="string"&&error.stack.includes(INSPECTOR_IMPORT_FRAME)&&INSPECTOR_TIMEOUT_FRAME.test(error.stack)}catch{return!1}}var earlyRecoveryCount=0,earlyRecoveryInstalled=!1;function installEarlyInspectorVmImportRecovery(){!RECOVER_INSPECTOR_VM_IMPORT||earlyRecoveryInstalled||(earlyRecoveryInstalled=!0,process.on("uncaughtException",(error,origin)=>{let otherHandlerActive=process.listenerCount("uncaughtException")>1;if(isRecoverableInspectorVmImportError(error,origin)){otherHandlerActive||earlyRecoveryCount++;return}otherHandlerActive||(console.error(error),process.exit(1))}))}function consumeEarlyInspectorVmImportRecoveries(){let count=earlyRecoveryCount;return earlyRecoveryCount=0,count}function getPiUserAgent(version=DISPLAY_VERSION){let runtime=process.versions.bun?`bun/${process.versions.bun}`:`node/${process.version}`;return`${BRAND?.userAgent??APP_NAME}/${version} (${process.platform}; ${runtime}; ${process.arch})`}var import_semver=__toESM(require_semver(),1);var REGISTRY_BASE_URL="https://registry.npmjs.org",LATEST_VERSION_URL=`${REGISTRY_BASE_URL}/${encodeURIComponent(PACKAGE_NAME)}/latest`;function latestVersionUrl(channel){return channel?`${REGISTRY_BASE_URL}/-/package/${encodeURIComponent(channel.packageName)}/dist-tags`:LATEST_VERSION_URL}function readAvailableVersion(payload,channel){if(typeof payload!="object"||payload===null)return;let source=payload,raw=channel?source[channel.distTag]:source.version;return typeof raw=="string"&&raw.trim()?raw.trim():void 0}var DEFAULT_VERSION_CHECK_TIMEOUT_MS=1e4,RELEASE_CHANGELOG_BASE_URL="https://github.com/code-yeongyu/senpi/blob",RELEASE_CHANGELOG_PATH="packages/coding-agent/CHANGELOG.md",SENPI_CALVER_PATTERN=/^(\d{4})\.(\d{1,2})\.(\d{1,2})(?:-([2-9]\d*))?$/;function parseSenpiCalVer(version){let match=SENPI_CALVER_PATTERN.exec(version);if(match)return[Number(match[1]),Number(match[2]),Number(match[3]),Number(match[4]??1)]}function formatVersionCheckError(error){let rootMessage=error instanceof Error&&error.message?error.message:String(error),cause=error instanceof Error?error.cause:void 0,causes=cause instanceof AggregateError?cause.errors:cause===void 0?[]:[cause],codes=causes.map(value=>typeof value=="object"&&value!==null&&"code"in value&&typeof value.code=="string"?value.code:void 0).filter(code=>code!==void 0);if(codes.length>0)return`${rootMessage} (${[...new Set(codes)].join(", ")})`;let causeMessage=causes.find(value=>value instanceof Error&&!!value.message)?.message;return causeMessage?`${rootMessage} (cause: ${causeMessage})`:rootMessage}function comparePackageVersions(leftVersion,rightVersion){let leftTrimmed=leftVersion.trim(),rightTrimmed=rightVersion.trim(),leftCalVer=parseSenpiCalVer(leftTrimmed),rightCalVer=parseSenpiCalVer(rightTrimmed);if(leftCalVer&&rightCalVer){for(let index=0;index<leftCalVer.length;index++)if(leftCalVer[index]!==rightCalVer[index])return leftCalVer[index]<rightCalVer[index]?-1:1;return 0}let left=(0,import_semver.valid)(leftTrimmed),right=(0,import_semver.valid)(rightTrimmed);if(!(!left||!right))return(0,import_semver.compare)(left,right)}function isNewerPackageVersion(candidateVersion,currentVersion){let comparison=comparePackageVersions(candidateVersion,currentVersion);return comparison!==void 0&&comparison>0}function getReleaseChangelogUrl(version){let trimmedVersion=version.trim(),channel=brandProfile()?.update;if(channel?.changelogUrl)return channel.changelogUrl.replace("{version}",trimmedVersion);let tag=trimmedVersion.startsWith("v")?trimmedVersion:`v${trimmedVersion}`;return`${RELEASE_CHANGELOG_BASE_URL}/${tag}/${RELEASE_CHANGELOG_PATH}`}async function getLatestPiRelease(currentVersion,options={}){if(envValue("OFFLINE"))return;let brand=brandProfile(),channel=brand?.update;if(brand&&!channel)return;let response=await fetchWithRetry(latestVersionUrl(channel),{headers:{"User-Agent":getPiUserAgent(currentVersion),accept:"application/json"}},{maxRetries:options.retry?2:0,timeoutMs:options.timeoutMs??DEFAULT_VERSION_CHECK_TIMEOUT_MS});if(!response.ok)return;let data=await response.json(),availableVersion=readAvailableVersion(data,channel);if(!availableVersion)return;if(channel)return{version:availableVersion,packageName:channel.packageName};let packageName=typeof data.packageName=="string"&&data.packageName.trim()?data.packageName.trim():void 0,note=typeof data.note=="string"&&data.note.trim()?data.note.trim():void 0;return{version:availableVersion,packageName,note}}async function checkForNewPiVersion(currentVersion){if(!envValue("SKIP_VERSION_CHECK"))try{let latestRelease=await getLatestPiRelease(currentVersion);return latestRelease&&isNewerPackageVersion(latestRelease.version,currentVersion)?latestRelease:void 0}catch{return}}export{RUNTIME_ENV_VAR,MIN_BUN_VERSION,bunVersionSatisfies,findBunBinary,resolveBunReexec,processBunRuntimeOptions,INSPECTOR_VM_IMPORT_WARNING,hasInheritedInspectorOption,releaseInheritedInspectorForChild,isRecoverableInspectorVmImportError,installEarlyInspectorVmImportRecovery,consumeEarlyInspectorVmImportRecoveries,getPiUserAgent,formatVersionCheckError,isNewerPackageVersion,getReleaseChangelogUrl,getLatestPiRelease,checkForNewPiVersion};
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{CredentialStoreBusyError,FILE_STORAGE_LOCK_OPTIONS,FILE_STORAGE_LOCK_RETRY_BUDGET_MS,FILE_STORAGE_LOCK_RETRY_MAX_DELAY_MS,FILE_STORAGE_LOCK_RETRY_MIN_DELAY_MS,isLockError}from"./chunk-7X72IACK.js";import{external_exports}from"./chunk-KUPQO7MC.js";import{require_proper_lockfile}from"./chunk-GZVCRV7I.js";import{getAgentDir}from"./chunk-PBWQK23Z.js";import{__toESM}from"./chunk-IKOFCODM.js";var import_proper_lockfile=__toESM(require_proper_lockfile(),1);import{createHmac,randomBytes,randomUUID}from"node:crypto";import{existsSync,mkdirSync,readFileSync,writeFileSync}from"node:fs";import{dirname,join}from"node:path";var CREDENTIAL_POOL_STATE_FILENAME="credential-pool-state.json",HEX_256_BIT=/^[0-9a-f]{64}$/,leaseSchema=external_exports.strictObject({id:external_exports.string().min(1).max(128),expiresAt:external_exports.number().int().positive()}),slotStateSchema=external_exports.strictObject({stateVersion:external_exports.number().int().nonnegative(),blockedUntil:external_exports.number().int().positive().optional(),blockReason:external_exports.enum(["auth_error","rate_limit","account_disabled"]).optional(),failureCount:external_exports.number().int().nonnegative().optional(),lastSuccessAt:external_exports.number().int().positive().optional(),credentialRevision:external_exports.string().regex(HEX_256_BIT).optional(),lease:leaseSchema.optional()}),documentSchema=external_exports.strictObject({schemaVersion:external_exports.literal(1),installationKey:external_exports.string().regex(HEX_256_BIT),providers:external_exports.record(external_exports.string(),external_exports.strictObject({lanes:external_exports.record(external_exports.string(),external_exports.strictObject({slots:external_exports.record(external_exports.string(),slotStateSchema)}))}))});function credentialPoolStatePath(agentDir=getAgentDir()){return join(agentDir,CREDENTIAL_POOL_STATE_FILENAME)}var FILE_WRITE_OPTIONS={encoding:"utf-8",mode:384};function freshDocument(){return{schemaVersion:1,installationKey:randomBytes(32).toString("hex"),providers:{}}}function parseDocument(content){try{let parsed=documentSchema.safeParse(JSON.parse(content));return parsed.success?parsed.data:freshDocument()}catch{return freshDocument()}}function slotHealth(state,now){return state?state.blockReason==="auth_error"||state.blockReason==="account_disabled"||state.blockedUntil!==void 0&&state.blockedUntil>now?"blocked":state.blockedUntil!==void 0&&state.lease!==void 0&&state.lease.expiresAt>now?"half_open":"ready":"ready"}var CredentialSlotRepository=class{constructor(path=credentialPoolStatePath()){this.path=path}ensureFile(){existsSync(this.path)||(mkdirSync(dirname(this.path),{recursive:!0,mode:448}),writeFileSync(this.path,JSON.stringify(freshDocument(),null,2),FILE_WRITE_OPTIONS))}async withDocument(fn){this.ensureFile();let release=await this.acquire();try{let document=parseDocument(readFileSync(this.path,"utf-8")),{result,next}=fn(document);return next&&writeFileSync(this.path,JSON.stringify(next,null,2),FILE_WRITE_OPTIONS),result}finally{await release()}}async acquire(){let startedAt=Date.now(),attempt=0;for(;;)try{return await import_proper_lockfile.default.lock(this.path,FILE_STORAGE_LOCK_OPTIONS)}catch(error){if(!isLockError(error))throw error;let waitedMs=Date.now()-startedAt;if(waitedMs>=FILE_STORAGE_LOCK_RETRY_BUDGET_MS)throw new CredentialStoreBusyError(this.path,waitedMs,error);let delayMs=Math.min(FILE_STORAGE_LOCK_RETRY_MIN_DELAY_MS*2**attempt,FILE_STORAGE_LOCK_RETRY_MAX_DELAY_MS,FILE_STORAGE_LOCK_RETRY_BUDGET_MS-waitedMs);attempt++,await new Promise(resolve=>setTimeout(resolve,delayMs))}}async installationKey(){return this.withDocument(document=>({result:document.installationKey,next:document}))}async envCredentialRevision(envVarName,envValue){let key=await this.installationKey();return createHmac("sha256",key).update(`${envVarName}\0${envValue}`).digest("hex")}async storedCredentialRevision(providerId,slotName,material){let key=await this.installationKey();return createHmac("sha256",key).update(`${providerId}\0${slotName}\0${material.key??""}\0${material.access??""}\0${material.refresh??""}`).digest("hex")}async listSlots(providerId,laneId){return this.withDocument(document=>({result:{...document.providers[providerId]?.lanes[laneId]?.slots}}))}async mutateSlotState(providerId,laneId,slotId,fn){return this.withDocument(document=>{let provider=document.providers[providerId]??{lanes:{}},lane=provider.lanes[laneId]??{slots:{}},current=lane.slots[slotId],mutated=fn(current),slots={...lane.slots},result;mutated===void 0?delete slots[slotId]:(result={...mutated,stateVersion:(current?.stateVersion??0)+1},slots[slotId]=result);let next={...document,providers:{...document.providers,[providerId]:{lanes:{...provider.lanes,[laneId]:{slots}}}}};return{result,next}})}};async function acquireHalfOpenLease(repository,providerId,laneId,slotId,options={}){let now=options.now??Date.now(),leaseTtlMs=options.leaseTtlMs??3e4,lease;return await repository.mutateSlotState(providerId,laneId,slotId,current=>{if(!current)return current;let expired=current.blockedUntil!==void 0&&current.blockedUntil<=now,leaseLive=current.lease!==void 0&&current.lease.expiresAt>now;return!expired||leaseLive||current.blockReason==="auth_error"?current:(lease={leaseId:randomUUID(),expiresAt:now+leaseTtlMs},{...current,lease:{id:lease.leaseId,expiresAt:lease.expiresAt}})}),lease}export{CREDENTIAL_POOL_STATE_FILENAME,credentialPoolStatePath,slotHealth,CredentialSlotRepository,acquireHalfOpenLease};
2
+ import{CredentialStoreBusyError,FILE_STORAGE_LOCK_OPTIONS,FILE_STORAGE_LOCK_RETRY_BUDGET_MS,FILE_STORAGE_LOCK_RETRY_MAX_DELAY_MS,FILE_STORAGE_LOCK_RETRY_MIN_DELAY_MS,isLockError}from"./chunk-7X72IACK.js";import{external_exports}from"./chunk-KUPQO7MC.js";import{require_proper_lockfile}from"./chunk-GZVCRV7I.js";import{getAgentDir}from"./chunk-WCAKUCN3.js";import{__toESM}from"./chunk-IKOFCODM.js";var import_proper_lockfile=__toESM(require_proper_lockfile(),1);import{createHmac,randomBytes,randomUUID}from"node:crypto";import{existsSync,mkdirSync,readFileSync,writeFileSync}from"node:fs";import{dirname,join}from"node:path";var CREDENTIAL_POOL_STATE_FILENAME="credential-pool-state.json",HEX_256_BIT=/^[0-9a-f]{64}$/,leaseSchema=external_exports.strictObject({id:external_exports.string().min(1).max(128),expiresAt:external_exports.number().int().positive()}),slotStateSchema=external_exports.strictObject({stateVersion:external_exports.number().int().nonnegative(),blockedUntil:external_exports.number().int().positive().optional(),blockReason:external_exports.enum(["auth_error","rate_limit","account_disabled"]).optional(),failureCount:external_exports.number().int().nonnegative().optional(),lastSuccessAt:external_exports.number().int().positive().optional(),credentialRevision:external_exports.string().regex(HEX_256_BIT).optional(),lease:leaseSchema.optional()}),documentSchema=external_exports.strictObject({schemaVersion:external_exports.literal(1),installationKey:external_exports.string().regex(HEX_256_BIT),providers:external_exports.record(external_exports.string(),external_exports.strictObject({lanes:external_exports.record(external_exports.string(),external_exports.strictObject({slots:external_exports.record(external_exports.string(),slotStateSchema)}))}))});function credentialPoolStatePath(agentDir=getAgentDir()){return join(agentDir,CREDENTIAL_POOL_STATE_FILENAME)}var FILE_WRITE_OPTIONS={encoding:"utf-8",mode:384};function freshDocument(){return{schemaVersion:1,installationKey:randomBytes(32).toString("hex"),providers:{}}}function parseDocument(content){try{let parsed=documentSchema.safeParse(JSON.parse(content));return parsed.success?parsed.data:freshDocument()}catch{return freshDocument()}}function slotHealth(state,now){return state?state.blockReason==="auth_error"||state.blockReason==="account_disabled"||state.blockedUntil!==void 0&&state.blockedUntil>now?"blocked":state.blockedUntil!==void 0&&state.lease!==void 0&&state.lease.expiresAt>now?"half_open":"ready":"ready"}var CredentialSlotRepository=class{constructor(path=credentialPoolStatePath()){this.path=path}ensureFile(){existsSync(this.path)||(mkdirSync(dirname(this.path),{recursive:!0,mode:448}),writeFileSync(this.path,JSON.stringify(freshDocument(),null,2),FILE_WRITE_OPTIONS))}async withDocument(fn){this.ensureFile();let release=await this.acquire();try{let document=parseDocument(readFileSync(this.path,"utf-8")),{result,next}=fn(document);return next&&writeFileSync(this.path,JSON.stringify(next,null,2),FILE_WRITE_OPTIONS),result}finally{await release()}}async acquire(){let startedAt=Date.now(),attempt=0;for(;;)try{return await import_proper_lockfile.default.lock(this.path,FILE_STORAGE_LOCK_OPTIONS)}catch(error){if(!isLockError(error))throw error;let waitedMs=Date.now()-startedAt;if(waitedMs>=FILE_STORAGE_LOCK_RETRY_BUDGET_MS)throw new CredentialStoreBusyError(this.path,waitedMs,error);let delayMs=Math.min(FILE_STORAGE_LOCK_RETRY_MIN_DELAY_MS*2**attempt,FILE_STORAGE_LOCK_RETRY_MAX_DELAY_MS,FILE_STORAGE_LOCK_RETRY_BUDGET_MS-waitedMs);attempt++,await new Promise(resolve=>setTimeout(resolve,delayMs))}}async installationKey(){return this.withDocument(document=>({result:document.installationKey,next:document}))}async envCredentialRevision(envVarName,envValue){let key=await this.installationKey();return createHmac("sha256",key).update(`${envVarName}\0${envValue}`).digest("hex")}async storedCredentialRevision(providerId,slotName,material){let key=await this.installationKey();return createHmac("sha256",key).update(`${providerId}\0${slotName}\0${material.key??""}\0${material.access??""}\0${material.refresh??""}`).digest("hex")}async listSlots(providerId,laneId){return this.withDocument(document=>({result:{...document.providers[providerId]?.lanes[laneId]?.slots}}))}async mutateSlotState(providerId,laneId,slotId,fn){return this.withDocument(document=>{let provider=document.providers[providerId]??{lanes:{}},lane=provider.lanes[laneId]??{slots:{}},current=lane.slots[slotId],mutated=fn(current),slots={...lane.slots},result;mutated===void 0?delete slots[slotId]:(result={...mutated,stateVersion:(current?.stateVersion??0)+1},slots[slotId]=result);let next={...document,providers:{...document.providers,[providerId]:{lanes:{...provider.lanes,[laneId]:{slots}}}}};return{result,next}})}};async function acquireHalfOpenLease(repository,providerId,laneId,slotId,options={}){let now=options.now??Date.now(),leaseTtlMs=options.leaseTtlMs??3e4,lease;return await repository.mutateSlotState(providerId,laneId,slotId,current=>{if(!current)return current;let expired=current.blockedUntil!==void 0&&current.blockedUntil<=now,leaseLive=current.lease!==void 0&&current.lease.expiresAt>now;return!expired||leaseLive||current.blockReason==="auth_error"?current:(lease={leaseId:randomUUID(),expiresAt:now+leaseTtlMs},{...current,lease:{id:lease.leaseId,expiresAt:lease.expiresAt}})}),lease}export{CREDENTIAL_POOL_STATE_FILENAME,credentialPoolStatePath,slotHealth,CredentialSlotRepository,acquireHalfOpenLease};
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{ProjectTrustStore,hasTrustRequiringProjectResources}from"./chunk-Y5A6TKBN.js";import{parseArgs,printHelp}from"./chunk-XDZ5RSMX.js";import{CONFIG_DIR_NAME,DISPLAY_VERSION,getAgentDir}from"./chunk-PBWQK23Z.js";import{createHash}from"node:crypto";import{existsSync,mkdirSync,readFileSync,renameSync,rmSync,statSync,writeFileSync}from"node:fs";import{dirname,isAbsolute,join}from"node:path";var CACHE_FILE_VERSION=1,MAX_CACHED_SCOPES=8;function cachePath(agentDir){return join(agentDir,"cache","help-flags.json")}function scopeKey(scope){let material=[scope.cwd,scope.noExtensions?"no-extensions":"extensions",scope.projectTrusted?"trusted":"untrusted",...scope.cliExtensionPaths].join("\0");return createHash("sha256").update(material).digest("hex").slice(0,32)}function stamp(path){try{let stats=statSync(path);return stats.isDirectory()?`d:${stats.mtimeMs}`:`f:${stats.mtimeMs}:${stats.size}`}catch{return"absent"}}function discoveryInputs(scope,extensionPaths){let paths=new Set([join(scope.agentDir,"settings.json"),join(scope.agentDir,"extensions"),join(scope.agentDir,"trust.json"),join(scope.cwd,CONFIG_DIR_NAME,"settings.json"),join(scope.cwd,CONFIG_DIR_NAME,"extensions")]);for(let path of extensionPaths)isAbsolute(path)&&(paths.add(path),paths.add(dirname(path)));for(let path of scope.cliExtensionPaths)isAbsolute(path)&&paths.add(path);return[...paths].sort()}function readCacheFile(agentDir){try{let parsed=JSON.parse(readFileSync(cachePath(agentDir),"utf8"));return parsed.version!==CACHE_FILE_VERSION||typeof parsed.scopes!="object"||parsed.scopes===null?void 0:parsed}catch{return}}function readHelpFlagsCache(scope){let cached=readCacheFile(scope.agentDir)?.scopes[scopeKey(scope)];if(!(!cached||cached.appVersion!==DISPLAY_VERSION||!Array.isArray(cached.inputs))){for(let input of cached.inputs)if(stamp(input.path)!==input.state)return;return[...cached.flags]}}function writeHelpFlagsCache(options){let{scope,flags,extensionPaths}=options;try{let scopes={...readCacheFile(scope.agentDir)?.scopes??{}};scopes[scopeKey(scope)]={writtenAt:Date.now(),appVersion:DISPLAY_VERSION,inputs:discoveryInputs(scope,extensionPaths).map(path=>({path,state:stamp(path)})),flags:[...flags]};let keptEntries=Object.entries(scopes).sort(([,left],[,right])=>right.writtenAt-left.writtenAt).slice(0,MAX_CACHED_SCOPES),file={version:CACHE_FILE_VERSION,scopes:Object.fromEntries(keptEntries)},target=cachePath(scope.agentDir);mkdirSync(dirname(target),{recursive:!0});let temporary=`${target}.${process.pid}.tmp`;writeFileSync(temporary,JSON.stringify(file),{mode:384});try{renameSync(temporary,target)}catch(error){throw existsSync(temporary)&&rmSync(temporary,{force:!0}),error}}catch{return}}function isPlainHelpRequest(parsed){return parsed.help===!0&&parsed.print!==!0&&parsed.mode===void 0}function resolveHelpProjectTrust(parsed,cwd,agentDir){return parsed.projectTrustOverride!==void 0?parsed.projectTrustOverride:hasTrustRequiringProjectResources(cwd)?new ProjectTrustStore(agentDir).get(cwd)===!0:!0}function helpFlagsScope(parsed,cwd,agentDir,projectTrusted){return{cwd,agentDir,cliExtensionPaths:[...parsed.extensions??[]],noExtensions:parsed.noExtensions===!0,projectTrusted}}function tryPrintHelpWithoutEngine(argv){let parsed;try{parsed=parseArgs([...argv])}catch{return!1}if(!isPlainHelpRequest(parsed)||parsed.diagnostics.length>0)return!1;if(parsed.noExtensions===!0)return printHelp([]),!0;let flags;try{let cwd=process.cwd(),agentDir=getAgentDir();flags=readHelpFlagsCache(helpFlagsScope(parsed,cwd,agentDir,resolveHelpProjectTrust(parsed,cwd,agentDir)))}catch{return!1}return flags?(printHelp(flags),!0):!1}export{writeHelpFlagsCache,isPlainHelpRequest,resolveHelpProjectTrust,helpFlagsScope,tryPrintHelpWithoutEngine};
2
+ import{ProjectTrustStore,hasTrustRequiringProjectResources}from"./chunk-T3HGPHPP.js";import{parseArgs,printHelp}from"./chunk-W4AG5TN4.js";import{CONFIG_DIR_NAME,DISPLAY_VERSION,getAgentDir}from"./chunk-WCAKUCN3.js";import{createHash}from"node:crypto";import{existsSync,mkdirSync,readFileSync,renameSync,rmSync,statSync,writeFileSync}from"node:fs";import{dirname,isAbsolute,join}from"node:path";var CACHE_FILE_VERSION=1,MAX_CACHED_SCOPES=8;function cachePath(agentDir){return join(agentDir,"cache","help-flags.json")}function scopeKey(scope){let material=[scope.cwd,scope.noExtensions?"no-extensions":"extensions",scope.projectTrusted?"trusted":"untrusted",...scope.cliExtensionPaths].join("\0");return createHash("sha256").update(material).digest("hex").slice(0,32)}function stamp(path){try{let stats=statSync(path);return stats.isDirectory()?`d:${stats.mtimeMs}`:`f:${stats.mtimeMs}:${stats.size}`}catch{return"absent"}}function discoveryInputs(scope,extensionPaths){let paths=new Set([join(scope.agentDir,"settings.json"),join(scope.agentDir,"extensions"),join(scope.agentDir,"trust.json"),join(scope.cwd,CONFIG_DIR_NAME,"settings.json"),join(scope.cwd,CONFIG_DIR_NAME,"extensions")]);for(let path of extensionPaths)isAbsolute(path)&&(paths.add(path),paths.add(dirname(path)));for(let path of scope.cliExtensionPaths)isAbsolute(path)&&paths.add(path);return[...paths].sort()}function readCacheFile(agentDir){try{let parsed=JSON.parse(readFileSync(cachePath(agentDir),"utf8"));return parsed.version!==CACHE_FILE_VERSION||typeof parsed.scopes!="object"||parsed.scopes===null?void 0:parsed}catch{return}}function readHelpFlagsCache(scope){let cached=readCacheFile(scope.agentDir)?.scopes[scopeKey(scope)];if(!(!cached||cached.appVersion!==DISPLAY_VERSION||!Array.isArray(cached.inputs))){for(let input of cached.inputs)if(stamp(input.path)!==input.state)return;return[...cached.flags]}}function writeHelpFlagsCache(options){let{scope,flags,extensionPaths}=options;try{let scopes={...readCacheFile(scope.agentDir)?.scopes??{}};scopes[scopeKey(scope)]={writtenAt:Date.now(),appVersion:DISPLAY_VERSION,inputs:discoveryInputs(scope,extensionPaths).map(path=>({path,state:stamp(path)})),flags:[...flags]};let keptEntries=Object.entries(scopes).sort(([,left],[,right])=>right.writtenAt-left.writtenAt).slice(0,MAX_CACHED_SCOPES),file={version:CACHE_FILE_VERSION,scopes:Object.fromEntries(keptEntries)},target=cachePath(scope.agentDir);mkdirSync(dirname(target),{recursive:!0});let temporary=`${target}.${process.pid}.tmp`;writeFileSync(temporary,JSON.stringify(file),{mode:384});try{renameSync(temporary,target)}catch(error){throw existsSync(temporary)&&rmSync(temporary,{force:!0}),error}}catch{return}}function isPlainHelpRequest(parsed){return parsed.help===!0&&parsed.print!==!0&&parsed.mode===void 0}function resolveHelpProjectTrust(parsed,cwd,agentDir){return parsed.projectTrustOverride!==void 0?parsed.projectTrustOverride:hasTrustRequiringProjectResources(cwd)?new ProjectTrustStore(agentDir).get(cwd)===!0:!0}function helpFlagsScope(parsed,cwd,agentDir,projectTrusted){return{cwd,agentDir,cliExtensionPaths:[...parsed.extensions??[]],noExtensions:parsed.noExtensions===!0,projectTrusted}}function tryPrintHelpWithoutEngine(argv){let parsed;try{parsed=parseArgs([...argv])}catch{return!1}if(!isPlainHelpRequest(parsed)||parsed.diagnostics.length>0)return!1;if(parsed.noExtensions===!0)return printHelp([]),!0;let flags;try{let cwd=process.cwd(),agentDir=getAgentDir();flags=readHelpFlagsCache(helpFlagsScope(parsed,cwd,agentDir,resolveHelpProjectTrust(parsed,cwd,agentDir)))}catch{return!1}return flags?(printHelp(flags),!0):!1}export{writeHelpFlagsCache,isPlainHelpRequest,resolveHelpProjectTrust,helpFlagsScope,tryPrintHelpWithoutEngine};
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{estimateContextTokens}from"./chunk-UIOI2SK3.js";var CONTEXT_SAFETY_TOKENS=4096,MIN_ANSWER_TOKENS=1024,MIN_MAX_TOKENS=1,CONTEXT_GUARD_MIN_WINDOW=CONTEXT_SAFETY_TOKENS+MIN_ANSWER_TOKENS,ContextWindowExhaustedError=class extends Error{constructor(estimatedTokens,contextWindow){super(`Context window exhausted: the conversation is estimated at ${estimatedTokens} of ${contextWindow} tokens, leaving fewer than ${MIN_ANSWER_TOKENS} tokens for a response. Compact the conversation, enable auto-compaction, or start a new session before retrying.`),this.name="ContextWindowExhaustedError",this.estimatedTokens=estimatedTokens,this.contextWindow=contextWindow}};function clampMaxTokensToContext(model,context,maxTokens){if(model.contextWindow<=0)return Number.isFinite(maxTokens)&&maxTokens>0?Math.max(MIN_MAX_TOKENS,Math.floor(maxTokens)):MIN_MAX_TOKENS;let estimatedTokens=estimateContextTokens(context).tokens,available=model.contextWindow-estimatedTokens-CONTEXT_SAFETY_TOKENS;if(model.contextWindow>=CONTEXT_GUARD_MIN_WINDOW&&available<MIN_ANSWER_TOKENS)throw new ContextWindowExhaustedError(estimatedTokens,model.contextWindow);let safeAvailable=Math.max(MIN_MAX_TOKENS,available),requested=Number.isFinite(maxTokens)&&maxTokens>0?Math.floor(maxTokens):safeAvailable;return Math.min(requested,safeAvailable)}function applyExtraBody(target,extraBody,reservedKeys){if(extraBody)for(let[key,value]of Object.entries(extraBody))reservedKeys.has(key)||Reflect.set(target,key,value)}var OPENAI_COMPLETIONS_RESERVED_BODY_KEYS=new Set(["model","messages","stream","stream_options","tools","tool_choice","store","temperature","max_tokens","max_completion_tokens","reasoning_effort","reasoning","thinking","enable_thinking","chat_template_kwargs","tool_stream","provider","providerOptions"]),OPENAI_RESPONSES_RESERVED_BODY_KEYS=new Set(["model","input","instructions","stream","tools","tool_choice","parallel_tool_calls","reasoning","max_output_tokens","temperature","text","store","include","prompt_cache_key","prompt_cache_retention","service_tier"]),GOOGLE_RESERVED_BODY_KEYS=new Set(["systemInstruction","tools","toolConfig","temperature","maxOutputTokens","thinkingConfig","responseMimeType","responseSchema","cachedContent","abortSignal","httpOptions"]),ANTHROPIC_RESERVED_BODY_KEYS=new Set(["model","messages","system","stream","tools","tool_choice","temperature","max_tokens","thinking","output_config","metadata"]),MISTRAL_RESERVED_BODY_KEYS=new Set(["model","messages","stream","tools","toolChoice","temperature","maxTokens","promptMode"]);function buildBaseOptions(model,context,options,apiKey){let samplingParams=model.samplingParams||options?.samplingParams?{...model.samplingParams,...options?.samplingParams}:void 0;return{temperature:options?.temperature,samplingParams,maxTokens:clampMaxTokensToContext(model,context,options?.maxTokens??model.maxTokens),signal:options?.signal,abortServerSideFallback:options?.abortServerSideFallback,telemetryContext:options?.telemetryContext,apiKey:apiKey||options?.apiKey,fetch:options?.fetch,transport:options?.transport,cacheRetention:options?.cacheRetention??model.cacheRetention,sessionId:options?.sessionId,headers:options?.headers,extraBody:options?.extraBody,onPayload:options?.onPayload,onResponse:options?.onResponse,timeoutMs:options?.timeoutMs,websocketConnectTimeoutMs:options?.websocketConnectTimeoutMs,maxRetries:options?.maxRetries,maxRetryDelayMs:options?.maxRetryDelayMs,metadata:options?.metadata,env:options?.env}}var DEFAULT_THINKING_BUDGETS={minimal:1024,low:2048,medium:8192,high:16384};function clampReasoning(effort){return effort==="xhigh"||effort==="max"?"high":effort}function clampMaxForOpenAI(effort,xhighSupported){return effort==="max"?xhighSupported?"xhigh":"high":effort}function thinkingBudgetForLevel(reasoningLevel,customBudgets){let budgets={...DEFAULT_THINKING_BUDGETS,...customBudgets},level=clampReasoning(reasoningLevel);return budgets[level]}function clampThinkingBudgetToAnswerRoom(thinkingBudget,ceiling){return Math.min(thinkingBudget,Math.max(0,ceiling-MIN_ANSWER_TOKENS))}function adjustMaxTokensForThinking(baseMaxTokens,modelMaxTokens,reasoningLevel,customBudgets){let level=clampReasoning(reasoningLevel);if(!level)return{maxTokens:baseMaxTokens??modelMaxTokens,thinkingBudget:0};let thinkingBudget=thinkingBudgetForLevel(level,customBudgets),maxTokens=baseMaxTokens===void 0?modelMaxTokens:Math.min(baseMaxTokens+thinkingBudget,modelMaxTokens);return maxTokens<=thinkingBudget&&(thinkingBudget=clampThinkingBudgetToAnswerRoom(thinkingBudget,maxTokens)),{maxTokens,thinkingBudget}}export{clampMaxTokensToContext,applyExtraBody,OPENAI_COMPLETIONS_RESERVED_BODY_KEYS,OPENAI_RESPONSES_RESERVED_BODY_KEYS,GOOGLE_RESERVED_BODY_KEYS,ANTHROPIC_RESERVED_BODY_KEYS,MISTRAL_RESERVED_BODY_KEYS,buildBaseOptions,clampMaxForOpenAI,thinkingBudgetForLevel,clampThinkingBudgetToAnswerRoom,adjustMaxTokensForThinking};
2
+ import{estimateContextTokens}from"./chunk-XVX4M3DZ.js";var CONTEXT_SAFETY_TOKENS=4096,MIN_ANSWER_TOKENS=1024,MIN_MAX_TOKENS=1,CONTEXT_GUARD_MIN_WINDOW=CONTEXT_SAFETY_TOKENS+MIN_ANSWER_TOKENS,ContextWindowExhaustedError=class extends Error{constructor(estimatedTokens,contextWindow){super(`Context window exhausted: the conversation is estimated at ${estimatedTokens} of ${contextWindow} tokens, leaving fewer than ${MIN_ANSWER_TOKENS} tokens for a response. Compact the conversation, enable auto-compaction, or start a new session before retrying.`),this.name="ContextWindowExhaustedError",this.estimatedTokens=estimatedTokens,this.contextWindow=contextWindow}};function clampMaxTokensToContext(model,context,maxTokens){if(model.contextWindow<=0)return Number.isFinite(maxTokens)&&maxTokens>0?Math.max(MIN_MAX_TOKENS,Math.floor(maxTokens)):MIN_MAX_TOKENS;let estimatedTokens=estimateContextTokens(context).tokens,available=model.contextWindow-estimatedTokens-CONTEXT_SAFETY_TOKENS;if(model.contextWindow>=CONTEXT_GUARD_MIN_WINDOW&&available<MIN_ANSWER_TOKENS)throw new ContextWindowExhaustedError(estimatedTokens,model.contextWindow);let safeAvailable=Math.max(MIN_MAX_TOKENS,available),requested=Number.isFinite(maxTokens)&&maxTokens>0?Math.floor(maxTokens):safeAvailable;return Math.min(requested,safeAvailable)}function applyExtraBody(target,extraBody,reservedKeys){if(extraBody)for(let[key,value]of Object.entries(extraBody))reservedKeys.has(key)||Reflect.set(target,key,value)}var OPENAI_COMPLETIONS_RESERVED_BODY_KEYS=new Set(["model","messages","stream","stream_options","tools","tool_choice","store","temperature","max_tokens","max_completion_tokens","reasoning_effort","reasoning","thinking","enable_thinking","chat_template_kwargs","tool_stream","provider","providerOptions"]),OPENAI_RESPONSES_RESERVED_BODY_KEYS=new Set(["model","input","instructions","stream","tools","tool_choice","parallel_tool_calls","reasoning","max_output_tokens","temperature","text","store","include","prompt_cache_key","prompt_cache_retention","service_tier"]),GOOGLE_RESERVED_BODY_KEYS=new Set(["systemInstruction","tools","toolConfig","temperature","maxOutputTokens","thinkingConfig","responseMimeType","responseSchema","cachedContent","abortSignal","httpOptions"]),ANTHROPIC_RESERVED_BODY_KEYS=new Set(["model","messages","system","stream","tools","tool_choice","temperature","max_tokens","thinking","output_config","metadata"]),MISTRAL_RESERVED_BODY_KEYS=new Set(["model","messages","stream","tools","toolChoice","temperature","maxTokens","promptMode"]);function buildBaseOptions(model,context,options,apiKey){let samplingParams=model.samplingParams||options?.samplingParams?{...model.samplingParams,...options?.samplingParams}:void 0;return{temperature:options?.temperature,samplingParams,maxTokens:clampMaxTokensToContext(model,context,options?.maxTokens??model.maxTokens),signal:options?.signal,abortServerSideFallback:options?.abortServerSideFallback,telemetryContext:options?.telemetryContext,apiKey:apiKey||options?.apiKey,fetch:options?.fetch,transport:options?.transport,cacheRetention:options?.cacheRetention??model.cacheRetention,sessionId:options?.sessionId,headers:options?.headers,extraBody:options?.extraBody,onPayload:options?.onPayload,onResponse:options?.onResponse,timeoutMs:options?.timeoutMs,websocketConnectTimeoutMs:options?.websocketConnectTimeoutMs,maxRetries:options?.maxRetries,maxRetryDelayMs:options?.maxRetryDelayMs,metadata:options?.metadata,env:options?.env}}var DEFAULT_THINKING_BUDGETS={minimal:1024,low:2048,medium:8192,high:16384};function clampReasoning(effort){return effort==="xhigh"||effort==="max"?"high":effort}function clampMaxForOpenAI(effort,xhighSupported){return effort==="max"?xhighSupported?"xhigh":"high":effort}function thinkingBudgetForLevel(reasoningLevel,customBudgets){let budgets={...DEFAULT_THINKING_BUDGETS,...customBudgets},level=clampReasoning(reasoningLevel);return budgets[level]}function clampThinkingBudgetToAnswerRoom(thinkingBudget,ceiling){return Math.min(thinkingBudget,Math.max(0,ceiling-MIN_ANSWER_TOKENS))}function adjustMaxTokensForThinking(baseMaxTokens,modelMaxTokens,reasoningLevel,customBudgets){let level=clampReasoning(reasoningLevel);if(!level)return{maxTokens:baseMaxTokens??modelMaxTokens,thinkingBudget:0};let thinkingBudget=thinkingBudgetForLevel(level,customBudgets),maxTokens=baseMaxTokens===void 0?modelMaxTokens:Math.min(baseMaxTokens+thinkingBudget,modelMaxTokens);return maxTokens<=thinkingBudget&&(thinkingBudget=clampThinkingBudgetToAnswerRoom(thinkingBudget,maxTokens)),{maxTokens,thinkingBudget}}export{clampMaxTokensToContext,applyExtraBody,OPENAI_COMPLETIONS_RESERVED_BODY_KEYS,OPENAI_RESPONSES_RESERVED_BODY_KEYS,GOOGLE_RESERVED_BODY_KEYS,ANTHROPIC_RESERVED_BODY_KEYS,MISTRAL_RESERVED_BODY_KEYS,buildBaseOptions,clampMaxForOpenAI,thinkingBudgetForLevel,clampThinkingBudgetToAnswerRoom,adjustMaxTokensForThinking};
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{CUSTOM_UNSUPPORTED_CAPABILITY,EXTENSION_EVENTS_CAPABILITY,RPC_CLIENT_CAPABILITIES_ENV,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY,hostLaunchProfile}from"./chunk-TFW6SS3P.js";import{DEFAULT_HOST_IDLE_EXIT_MS,HOST_DAEMON_DIR_ENV,HOST_STATE_FILE_MODE,INTERNAL_SUPERVISOR_FLAG,MAX_SOCKET_PATH_BYTES,OBSERVE_REQUEST_FIELD,ProcessIdentityUnreadableError,canonicalEndpointPath,clearHostRegistration,createDaemonDirectories,createHostDaemonPaths,createSocketSecret,ensureEndpointIdentity,generationBindPath,generationPaths,legacyHostIsLive,parseJson,processIsLive,processMatchesPidFile,provenOwner,readFileOrUndefined,readHostRegistration,readHostSettings,readProcessStartTime,readSocketSecret,releaseGeneration,resolveCliMainPath,resolveSocketTransportAddress,sameEndpoint,sendSocketHandshake,socketSecretPath,statSocketIdentity,waitForStartTime,writeGenerationRecord,writeHostRegistration,writeHostSettings,writeStateFile,writtenByThisProcess}from"./chunk-BPZ5KIOS.js";import{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV,compareEngineOrdinal,engineBuildIdentity}from"./chunk-E5F5SVZF.js";import{ENV_AGENT_DIR,getAgentDir,isBunBinary}from"./chunk-PBWQK23Z.js";function parseHostProtocolInfo(data){if(!isRecord(data)||typeof data.serverVersion!="string"||!Array.isArray(data.capabilities)||!data.capabilities.every(entry=>typeof entry=="string"))return;let ordinal=parseOrdinal(data.engineOrdinal),launchProfile=parseLaunchProfile(data.launch_profile);return{protocolVersion:typeof data.protocolVersion=="number"?data.protocolVersion:0,serverVersion:data.serverVersion,capabilities:data.capabilities,...typeof data.instanceId=="string"&&{instanceId:data.instanceId},...typeof data.generation=="number"&&Number.isSafeInteger(data.generation)&&{generation:data.generation},...typeof data.engineVersion=="string"&&{engineVersion:data.engineVersion},...ordinal&&{engineOrdinal:ordinal},...launchProfile&&{launch_profile:launchProfile},...typeof data.memory_pressure=="boolean"&&{memory_pressure:data.memory_pressure}}}function parseOrdinal(value){if(!(!Array.isArray(value)||value.length!==5||!value.every(part=>typeof part=="number")))return[value[0],value[1],value[2],value[3],value[4]]}function parseLaunchProfile(value){if(!isRecord(value)||typeof value.profile_id!="string"||!isRecord(value.core))return;let{extensions,multi_session,session_runtime}=value.core;if(!(!Array.isArray(extensions)||!extensions.every(entry=>typeof entry=="string"))&&typeof multi_session=="boolean"&&!(session_runtime!=="in-process"&&session_runtime!=="worker"))return{profile_id:value.profile_id,core:{extensions,multi_session,session_runtime}}}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var HOST_PROTOCOL_VERSION=1,GENERATION_HANDOFF_CAPABILITY="generation_handoff",REQUIRED_HOST_CAPABILITIES=["multi_session",EXTENSION_EVENTS_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY],HostEnsureRefusedError=class extends Error{constructor(socket,reason,host){super(`RPC socket ${socket} refused: ${reason} - ${refusalDetail(reason,host)}`),this.name="HostEnsureRefusedError",this.socket=socket,this.reason=reason}};function refusalDetail(reason,host){switch(reason){case"protocol":return`the running host speaks protocol version ${host?.protocolVersion??"unknown"}, this build speaks ${HOST_PROTOCOL_VERSION}`;case"capability":{let missing=REQUIRED_HOST_CAPABILITIES.filter(capability=>!host?.capabilities.includes(capability));return`the running host is missing ${JSON.stringify(missing)}; it owns the socket, so no second host is started`}case"foreign_writer":return"its pidfile was written by another process, so this one may not signal it; stop that host explicitly instead";case"legacy_host":return"a host from before the per-socket daemon directory is still running on this endpoint; it is never signalled, and no second host is started beside it";case"host_busy":return"its socket accepts connections but did not answer inside the probe budget: a live host under load, which is never ended to make room for a replacement";default:return assertNever(reason)}}function decideHostAction(client,host,policy){if(host===void 0)return{action:"start",reason:client.startedByUs?"restart_own_host":"no_host",upgradeable:!1};if(host.protocolVersion!==client.protocolVersion)return{action:"refuse",reason:"protocol",upgradeable:!1};if(!client.requiredCapabilities.every(capability=>host.capabilities.includes(capability)))return policy==="fallback"?{action:"fallback",reason:"capability",upgradeable:!1}:{action:"refuse",reason:"capability",upgradeable:!1};let upgradeable=client.platform!=="win32"&&host.capabilities.includes(GENERATION_HANDOFF_CAPABILITY);if(policy==="fallback"&&host.engineVersion!==client.identity.text)return{action:"fallback",reason:"engine_mismatch",upgradeable};let warning=profileWarning(client,host);return client.platform==="win32"?{action:"reuse",reason:"win32_attach_only",upgradeable:!1,...warning&&{warning}}:upgradeable?policy==="upgrade"&&client.launchProfile&&host.launch_profile&&supersedes(client,host)?{action:"handoff",reason:sameRelease(client.identity.ordinal,host.engineOrdinal)?"profile":"newer_engine",upgradeable:!0}:{action:"reuse",reason:"compatible",upgradeable,...warning&&{warning}}:{action:"reuse",reason:"handoff_unsupported",upgradeable:!1,...warning&&{warning}}}function supersedes(client,host){if(host.engineOrdinal===void 0)return!1;let hostIdentity={text:host.engineVersion??"",ordinal:host.engineOrdinal,scheme:host.engineOrdinal[4]>0?"epoch":"nodef"};return compareEngineOrdinal(client.identity,hostIdentity)<=0?!1:covers(client.launchProfile,host.launch_profile)}function profileWarning(client,host){if(client.launchProfile===void 0||host.launch_profile===void 0)return"profile_mismatch_attached";if(client.launchProfile.profile_id!==host.launch_profile.profile_id)return covers(client.launchProfile,host.launch_profile)?"profile_mismatch_attached":"profile_narrower_attached"}function covers(candidate,running){return candidate===void 0||running===void 0?!1:running.core.extensions.every(extension=>candidate.core.extensions.includes(extension))}function sameRelease(candidate,running){return running!==void 0&&candidate.slice(0,4).every((part,index)=>part===running[index])}function assertNever(value){throw new Error(`unreachable host decision: ${JSON.stringify(value)}`)}import{createConnection}from"node:net";function holdAttachment(socket){return socket.removeAllListeners("data"),socket.resume(),socket.on("error",()=>socket.destroy()),socket.unref(),{release:()=>socket.destroy()}}var DEFAULT_PROBE_TIMEOUT_MS=1e4,PROBE_REQUEST_ID="ensure-host-probe";function probeHost(options){return probeProtocolInfo(options.socket,options.timeoutMs??DEFAULT_PROBE_TIMEOUT_MS)}async function probeProtocolInfo(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info"},timeoutMs);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function observeProtocolInfo(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info",[OBSERVE_REQUEST_FIELD]:!0},timeoutMs);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function holdProtocolInfo(socketPath,timeoutMs){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs,!0),info=outcome.answer===void 0?void 0:parseHostProtocolInfo(outcome.answer);if(outcome.kept===void 0)return;let hold=holdAttachment(outcome.kept);if(info!==void 0)return{info,hold};hold.release()}async function probeSocketReachable(socketPath,timeoutMs){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs)).connected}async function probeSessionCount(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"list_sessions",include_workers:!0},timeoutMs);if(!(!isRecord2(reply)||!Array.isArray(reply.sessions)))return reply.sessions.length}async function requestOnSocket(socketPath,command,timeoutMs){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,...command},timeoutMs)).answer}async function connectAndAsk(socketPath,request,timeoutMs,keep=!1){let secret;if(process.platform==="win32")try{secret=await readSocketSecret(socketSecretPath(socketPath))}catch{return{connected:!1,answer:void 0}}return new Promise(resolveProbe=>{let socket=createConnection(resolveSocketTransportAddress(socketPath,process.platform,secret)),buffer="",settled=!1,connected=!1,finish=value=>{if(!settled){if(settled=!0,clearTimeout(timeout),keep&&value!==void 0&&!socket.destroyed){resolveProbe({connected,answer:value,kept:socket});return}socket.destroy(),resolveProbe({connected,answer:value})}},timeout=setTimeout(()=>finish(),timeoutMs);socket.once("connect",()=>{connected=!0,socket.write(`${JSON.stringify(request)}
2
+ import{CUSTOM_UNSUPPORTED_CAPABILITY,EXTENSION_EVENTS_CAPABILITY,RPC_CLIENT_CAPABILITIES_ENV,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY,hostLaunchProfile}from"./chunk-SNDTJL2H.js";import{DEFAULT_HOST_IDLE_EXIT_MS,HOST_DAEMON_DIR_ENV,HOST_STATE_FILE_MODE,INTERNAL_SUPERVISOR_FLAG,MAX_SOCKET_PATH_BYTES,OBSERVE_REQUEST_FIELD,ProcessIdentityUnreadableError,canonicalEndpointPath,clearHostRegistration,createDaemonDirectories,createHostDaemonPaths,createSocketSecret,ensureEndpointIdentity,generationBindPath,generationPaths,legacyHostIsLive,parseJson,processIsLive,processMatchesPidFile,provenOwner,readFileOrUndefined,readHostRegistration,readHostSettings,readProcessStartTime,readSocketSecret,releaseGeneration,resolveCliMainPath,resolveSocketTransportAddress,sameEndpoint,sendSocketHandshake,socketSecretPath,statSocketIdentity,waitForStartTime,writeGenerationRecord,writeHostRegistration,writeHostSettings,writeStateFile,writtenByThisProcess}from"./chunk-UK5TE7WR.js";import{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV,compareEngineOrdinal,engineBuildIdentity}from"./chunk-FUGMDU6B.js";import{ENV_AGENT_DIR,getAgentDir,isBunBinary}from"./chunk-WCAKUCN3.js";function parseHostProtocolInfo(data){if(!isRecord(data)||typeof data.serverVersion!="string"||!Array.isArray(data.capabilities)||!data.capabilities.every(entry=>typeof entry=="string"))return;let ordinal=parseOrdinal(data.engineOrdinal),launchProfile=parseLaunchProfile(data.launch_profile);return{protocolVersion:typeof data.protocolVersion=="number"?data.protocolVersion:0,serverVersion:data.serverVersion,capabilities:data.capabilities,...typeof data.instanceId=="string"&&{instanceId:data.instanceId},...typeof data.generation=="number"&&Number.isSafeInteger(data.generation)&&{generation:data.generation},...typeof data.engineVersion=="string"&&{engineVersion:data.engineVersion},...ordinal&&{engineOrdinal:ordinal},...launchProfile&&{launch_profile:launchProfile},...typeof data.memory_pressure=="boolean"&&{memory_pressure:data.memory_pressure}}}function parseOrdinal(value){if(!(!Array.isArray(value)||value.length!==5||!value.every(part=>typeof part=="number")))return[value[0],value[1],value[2],value[3],value[4]]}function parseLaunchProfile(value){if(!isRecord(value)||typeof value.profile_id!="string"||!isRecord(value.core))return;let{extensions,multi_session,session_runtime}=value.core;if(!(!Array.isArray(extensions)||!extensions.every(entry=>typeof entry=="string"))&&typeof multi_session=="boolean"&&!(session_runtime!=="in-process"&&session_runtime!=="worker"))return{profile_id:value.profile_id,core:{extensions,multi_session,session_runtime}}}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var HOST_PROTOCOL_VERSION=1,GENERATION_HANDOFF_CAPABILITY="generation_handoff",REQUIRED_HOST_CAPABILITIES=["multi_session",EXTENSION_EVENTS_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY],HostEnsureRefusedError=class extends Error{constructor(socket,reason,host){super(`RPC socket ${socket} refused: ${reason} - ${refusalDetail(reason,host)}`),this.name="HostEnsureRefusedError",this.socket=socket,this.reason=reason}};function refusalDetail(reason,host){switch(reason){case"protocol":return`the running host speaks protocol version ${host?.protocolVersion??"unknown"}, this build speaks ${HOST_PROTOCOL_VERSION}`;case"capability":{let missing=REQUIRED_HOST_CAPABILITIES.filter(capability=>!host?.capabilities.includes(capability));return`the running host is missing ${JSON.stringify(missing)}; it owns the socket, so no second host is started`}case"foreign_writer":return"its pidfile was written by another process, so this one may not signal it; stop that host explicitly instead";case"legacy_host":return"a host from before the per-socket daemon directory is still running on this endpoint; it is never signalled, and no second host is started beside it";case"host_busy":return"its socket accepts connections but did not answer inside the probe budget: a live host under load, which is never ended to make room for a replacement";default:return assertNever(reason)}}function decideHostAction(client,host,policy){if(host===void 0)return{action:"start",reason:client.startedByUs?"restart_own_host":"no_host",upgradeable:!1};if(host.protocolVersion!==client.protocolVersion)return{action:"refuse",reason:"protocol",upgradeable:!1};if(!client.requiredCapabilities.every(capability=>host.capabilities.includes(capability)))return policy==="fallback"?{action:"fallback",reason:"capability",upgradeable:!1}:{action:"refuse",reason:"capability",upgradeable:!1};let upgradeable=client.platform!=="win32"&&host.capabilities.includes(GENERATION_HANDOFF_CAPABILITY);if(policy==="fallback"&&host.engineVersion!==client.identity.text)return{action:"fallback",reason:"engine_mismatch",upgradeable};let warning=profileWarning(client,host);return client.platform==="win32"?{action:"reuse",reason:"win32_attach_only",upgradeable:!1,...warning&&{warning}}:upgradeable?policy==="upgrade"&&client.launchProfile&&host.launch_profile&&supersedes(client,host)?{action:"handoff",reason:sameRelease(client.identity.ordinal,host.engineOrdinal)?"profile":"newer_engine",upgradeable:!0}:{action:"reuse",reason:"compatible",upgradeable,...warning&&{warning}}:{action:"reuse",reason:"handoff_unsupported",upgradeable:!1,...warning&&{warning}}}function supersedes(client,host){if(host.engineOrdinal===void 0)return!1;let hostIdentity={text:host.engineVersion??"",ordinal:host.engineOrdinal,scheme:host.engineOrdinal[4]>0?"epoch":"nodef"};return compareEngineOrdinal(client.identity,hostIdentity)<=0?!1:covers(client.launchProfile,host.launch_profile)}function profileWarning(client,host){if(client.launchProfile===void 0||host.launch_profile===void 0)return"profile_mismatch_attached";if(client.launchProfile.profile_id!==host.launch_profile.profile_id)return covers(client.launchProfile,host.launch_profile)?"profile_mismatch_attached":"profile_narrower_attached"}function covers(candidate,running){return candidate===void 0||running===void 0?!1:running.core.extensions.every(extension=>candidate.core.extensions.includes(extension))}function sameRelease(candidate,running){return running!==void 0&&candidate.slice(0,4).every((part,index)=>part===running[index])}function assertNever(value){throw new Error(`unreachable host decision: ${JSON.stringify(value)}`)}import{createConnection}from"node:net";function holdAttachment(socket){return socket.removeAllListeners("data"),socket.resume(),socket.on("error",()=>socket.destroy()),socket.unref(),{release:()=>socket.destroy()}}var DEFAULT_PROBE_TIMEOUT_MS=1e4,PROBE_REQUEST_ID="ensure-host-probe";function probeHost(options){return probeProtocolInfo(options.socket,options.timeoutMs??DEFAULT_PROBE_TIMEOUT_MS)}async function probeProtocolInfo(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info"},timeoutMs);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function observeProtocolInfo(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info",[OBSERVE_REQUEST_FIELD]:!0},timeoutMs);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function holdProtocolInfo(socketPath,timeoutMs){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs,!0),info=outcome.answer===void 0?void 0:parseHostProtocolInfo(outcome.answer);if(outcome.kept===void 0)return;let hold=holdAttachment(outcome.kept);if(info!==void 0)return{info,hold};hold.release()}async function probeSocketReachable(socketPath,timeoutMs){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs)).connected}async function probeSessionCount(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"list_sessions",include_workers:!0},timeoutMs);if(!(!isRecord2(reply)||!Array.isArray(reply.sessions)))return reply.sessions.length}async function requestOnSocket(socketPath,command,timeoutMs){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,...command},timeoutMs)).answer}async function connectAndAsk(socketPath,request,timeoutMs,keep=!1){let secret;if(process.platform==="win32")try{secret=await readSocketSecret(socketSecretPath(socketPath))}catch{return{connected:!1,answer:void 0}}return new Promise(resolveProbe=>{let socket=createConnection(resolveSocketTransportAddress(socketPath,process.platform,secret)),buffer="",settled=!1,connected=!1,finish=value=>{if(!settled){if(settled=!0,clearTimeout(timeout),keep&&value!==void 0&&!socket.destroyed){resolveProbe({connected,answer:value,kept:socket});return}socket.destroy(),resolveProbe({connected,answer:value})}},timeout=setTimeout(()=>finish(),timeoutMs);socket.once("connect",()=>{connected=!0,socket.write(`${JSON.stringify(request)}
3
3
  `)}),socket.on("data",chunk=>{for(buffer+=chunk.toString("utf8");;){let newline=buffer.indexOf(`
4
4
  `);if(newline===-1)return;let line=buffer.slice(0,newline);buffer=buffer.slice(newline+1);let answer=readAnswer(line);if(answer!==void 0)return finish(answer)}}),socket.once("error",()=>finish()),socket.once("close",()=>finish()),secret&&sendSocketHandshake(socket,secret)})}function readAnswer(text){let parsed;try{parsed=JSON.parse(text)}catch{return}if(!(!isRecord2(parsed)||parsed.id!==PROBE_REQUEST_ID||parsed.success!==!0))return parsed.data??{}}function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}import{existsSync}from"node:fs";import{basename,dirname,resolve}from"node:path";import{fileURLToPath}from"node:url";var PINNED_HOST_CLIENT_CAPABILITIES=[EXTENSION_EVENTS_CAPABILITY,CUSTOM_UNSUPPORTED_CAPABILITY];function defaultHostLaunch(supervisorArgs,compiled=isBunBinary,sibling=resolveHostLifecycleEntryPath()??null){return compiled?{command:process.execPath,args:[INTERNAL_SUPERVISOR_FLAG,...supervisorArgs]}:sibling!==null?{command:process.execPath,args:[...process.execArgv,sibling,...supervisorArgs]}:{command:process.execPath,args:[...process.execArgv,resolveCliMainPath(),INTERNAL_SUPERVISOR_FLAG,...supervisorArgs]}}function resolveHostLifecycleEntryPath(){let modulePath=fileURLToPath(import.meta.url);if(basename(dirname(modulePath))==="chunks")return;let extension=modulePath.endsWith(".ts")?".ts":".js",sibling=resolve(dirname(modulePath),`host-lifecycle${extension}`);return existsSync(sibling)?sibling:void 0}async function stopHost(options){let paths=createHostDaemonPaths({socket:options.socket,...options.agentDir?{agentDir:options.agentDir}:{}}),registered=await readHostRegistration(paths),owner=await provenOwner(registered,options.socket);if(!owner)return{action:"refuse",reason:"unknown_owner"};let host=await probeProtocolInfo(options.socket,options.timeoutMs??1e4);if(options.drain===!0)return!host?.capabilities.includes(GENERATION_HANDOFF_CAPABILITY)||process.platform==="win32"?{action:"refuse",reason:"drain_unsupported"}:(signalGeneration(owner.pid,"SIGUSR1"),{action:"drained",pid:owner.pid});let sessions=await probeSessionCount(options.socket,options.timeoutMs??1e4);return options.force!==!0&&host!==void 0&&sessions!==void 0&&sessions>0?{action:"refuse",reason:"sessions_live"}:(signalGeneration(owner.pid,"SIGTERM"),await releaseGeneration(paths,{instanceId:owner.instanceId,pid:owner.pid}),{action:"stopped",pid:owner.pid})}function signalGeneration(pid,signal){try{return process.kill(pid,signal),!0}catch(error){if(error instanceof Error&&"code"in error&&error.code==="ESRCH")return!1;throw error}}import{createHash}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{tmpdir}from"node:os";import{dirname as dirname2,join}from"node:path";import{stat}from"node:fs/promises";var LegacyLockArtifactError=class extends Error{constructor(lockPath){super(`Legacy lock directory is present at ${lockPath}`),this.code="ELEGACY_LOCK_ARTIFACT",this.name="LegacyLockArtifactError",this.lockPath=lockPath}},DEFAULT_RETRIES={retries:100,minTimeout:20,maxTimeout:100};async function openLockDatabase(lockPath){if(typeof globalThis.Bun<"u"){let{Database}=await import("bun:sqlite"),database2=new Database(lockPath,{create:!0});return{exec:sql=>database2.exec(sql),close:()=>database2.close(!1)}}let{DatabaseSync}=await import("node:sqlite"),database=new DatabaseSync(lockPath);return{exec:sql=>database.exec(sql),close:()=>database.close()}}async function acquireOwnershipSafeLock(lockPath,options={}){let retries=options.retries??DEFAULT_RETRIES,deadline=Date.now()+retries.retries*retries.maxTimeout;for(;;){await rejectLegacyDirectory(lockPath);let busyMs=Math.max(1,Math.min(retries.maxTimeout,deadline-Date.now())),database;try{database=await openLockDatabase(lockPath),database.exec(`PRAGMA busy_timeout = ${busyMs}; BEGIN EXCLUSIVE;`);let released=!1,held=database;return async()=>{if(!released){released=!0;try{held.exec("COMMIT;")}finally{held.close()}}}}catch(error){try{database?.close()}catch{}if(await rejectLegacyDirectory(lockPath),isBusy(error)&&Date.now()<deadline){await new Promise(resolve2=>setTimeout(resolve2,Math.min(retries.minTimeout,Math.max(1,deadline-Date.now()))));continue}throw error}}}async function rejectLegacyDirectory(lockPath){try{if((await stat(lockPath)).isDirectory())throw new LegacyLockArtifactError(lockPath)}catch(error){if(error instanceof LegacyLockArtifactError||error.code!=="ENOENT")throw error}}function isBusy(error){let message=error instanceof Error?error.message:String(error);return/busy|locked/i.test(message)||error?.code==="SQLITE_BUSY"}var LOCK_BUSY_WAIT_MS=100;function hostEnsureLockTarget(socket){return join(tmpdir(),"senpi-rpc-host-locks",createSocketLockName(socket))}async function acquireHostEnsureLock(socket,waitMs){let lockTarget=hostEnsureLockTarget(socket);return await mkdir(dirname2(lockTarget),{recursive:!0}),await writeFile(lockTarget,"",{flag:"a",mode:384}),acquireOwnershipSafeLock(`${lockTarget}.lock`,hostEnsureLockOptions(waitMs))}function hostEnsureLockOptions(waitMs){return{retries:{retries:Math.ceil(waitMs/LOCK_BUSY_WAIT_MS),minTimeout:20,maxTimeout:LOCK_BUSY_WAIT_MS}}}function createSocketLockName(socket){return createHash("sha256").update(socketLockAddress(socket),"utf8").digest("hex").slice(0,32)}function socketLockAddress(socket){return process.platform==="win32"||socket.startsWith("\0")?resolveSocketTransportAddress(socket,process.platform):canonicalEndpointPath(socket)}import{spawn}from"node:child_process";import{randomUUID}from"node:crypto";import{open,rm,writeFile as writeFile2}from"node:fs/promises";import{join as join2}from"node:path";var ALLOWED_ENV_NAMES=[/^(PATH|HOME|USER|LOGNAME|SHELL|TMPDIR|TERM|LANG)$/u,/^(LC|XDG)_/u,/^(SENPI|OMO|PI)_/u,/^(HTTPS?_PROXY|NO_PROXY)$/u,/^[A-Z0-9_]+_API_KEY$/u,/^(ANTHROPIC|OPENAI|GOOGLE|GEMINI|AZURE|AWS|OPENROUTER|XAI|MISTRAL|DEEPSEEK|GROQ|CEREBRAS|MINIMAX)_/u],WINDOWS_SYSTEM_ENV_NAMES=new Set(["SYSTEMROOT","SYSTEMDRIVE","WINDIR","COMSPEC","PATHEXT","TEMP","TMP","USERPROFILE","APPDATA","LOCALAPPDATA","PROGRAMFILES","PROGRAMFILES(X86)","PROGRAMDATA","HOMEDRIVE","HOMEPATH","NUMBER_OF_PROCESSORS","PROCESSOR_ARCHITECTURE","OS"]),TRANSIENT_ENV_NAMES=new Set(["PI_SESSION_ID","PI_SESSION_FILE","PI_SESSION_CWD","PI_GOAL_STORE_FILE","PI_PROVIDER","PI_MODEL","PI_REASONING_LEVEL","PI_PROMPT_CACHE_SAFE_WAIT_SECONDS","SENPI_PY_KERNEL_PARENT_PID","SENPI_RPC_HOST_WATCH_FD","SENPI_RPC_HOST_WATCH_PPID","SENPI_RPC_HOST_SCRATCH_DIR","SENPI_RPC_HOST_CLEANUP_PATHS","SENPI_RPC_HOST_PUBLIC_SOCKET","SENPI_RPC_HOST_INSTANCE_ID","SENPI_RPC_HOST_GENERATION","SENPI_RPC_HOST_DAEMON_DIR"]);function daemonEnvIsAllowed(name,platform=process.platform){let upper=name.toUpperCase();return TRANSIENT_ENV_NAMES.has(platform==="win32"?upper:name)?!1:platform!=="win32"?ALLOWED_ENV_NAMES.some(pattern=>pattern.test(name)):WINDOWS_SYSTEM_ENV_NAMES.has(upper)||ALLOWED_ENV_NAMES.some(pattern=>pattern.test(upper))}function daemonEnvOverrides(processEnv,specEnv={},platform=process.platform){let overrides={};for(let name of Object.keys(processEnv))daemonEnvIsAllowed(name,platform)||(overrides[name]=null);for(let[name,value]of Object.entries(specEnv))daemonEnvIsAllowed(name,platform)&&(overrides[name]=value);return overrides}function daemonEnvironment(processEnv,overrides={},forced={},platform=process.platform){let env={};for(let[name,value]of Object.entries(processEnv))value!==void 0&&daemonEnvIsAllowed(name,platform)&&(env[name]=value);for(let[name,value]of Object.entries(overrides))daemonEnvIsAllowed(name,platform)&&(deleteEnvironmentName(env,name,platform),value!==null&&(env[name]=value));for(let[name,value]of Object.entries(forced))deleteEnvironmentName(env,name,platform),env[name]=value;return env}function daemonEnvKeys(processEnv,specEnv={},platform=process.platform){let kept=Object.keys(processEnv).filter(name=>daemonEnvIsAllowed(name,platform)),explicit=Object.keys(specEnv).filter(name=>daemonEnvIsAllowed(name,platform));return[...new Set([...kept,...explicit])].sort()}async function writeDaemonEnvKeys(paths,keys){await writeStateFile(daemonEnvKeysFile(paths),{env_keys:keys})}async function readDaemonEnvKeys(paths){let keys=parseJson(await readFileOrUndefined(daemonEnvKeysFile(paths)))?.env_keys;return Array.isArray(keys)?keys.filter(key=>typeof key=="string"):[]}function daemonEnvKeysFile(paths){return join2(paths.dir,"env-keys.json")}function deleteEnvironmentName(env,name,platform){if(platform!=="win32"){delete env[name];return}let upper=name.toUpperCase();for(let existing of Object.keys(env))existing.toUpperCase()===upper&&delete env[existing]}function initialHostEnvironment(options){return daemonEnvironment(process.env,options.env,{[ENV_AGENT_DIR]:options.agentDir??getAgentDir(),[RPC_CLIENT_CAPABILITIES_ENV]:PINNED_HOST_CLIENT_CAPABILITIES.join(","),[HOST_INSTANCE_ID_ENV]:options.instanceId,[HOST_GENERATION_ENV]:String(options.generation),[HOST_DAEMON_DIR_ENV]:options.paths.dir})}function successorHostEnvironment(options){return daemonEnvironment(process.env,options.env,{[RPC_CLIENT_CAPABILITIES_ENV]:PINNED_HOST_CLIENT_CAPABILITIES.join(","),...options.agentDir?{[ENV_AGENT_DIR]:options.agentDir}:{},[HOST_INSTANCE_ID_ENV]:options.instanceId,[HOST_GENERATION_ENV]:String(options.generation),[HOST_DAEMON_DIR_ENV]:options.paths.dir})}var DEFAULT_HANDOFF_READINESS_MS=3e4,SUCCESSOR_EXIT_WAIT_MS=5e3,SUCCESSOR_START_BUDGET_MS=1e4+DEFAULT_HANDOFF_READINESS_MS+2e3+SUCCESSOR_EXIT_WAIT_MS;async function startSuccessor(context){let{options,paths,host,owner}=context,generation=(host.generation??0)+1,instanceId=randomUUID(),bindSocket=generationBindPath(options.socket,generation);if(Buffer.byteLength(bindSocket)>MAX_SOCKET_PATH_BYTES)return{action:"refuse",reason:"socket_path_too_long",upgradeable:!0,detail:bindSocket};let replaced=await statSocketIdentity(options.socket);if(!replaced)return{action:"refuse",reason:"socket_replaced",upgradeable:!0};let running=await readHostSettings(paths),bootSettings=await readFileOrUndefined(paths.settingsFile);await writeHostSettings(paths,{socket:options.socket,capabilities:PINNED_HOST_CLIENT_CAPABILITIES,coldStart:options.policy?.coldStart??running?.coldStart??"transient",idleExitMs:options.policy?.idleExitMs??running?.idleExitMs??9e5,generation,instanceId});let child,exited;try{await options._test?.beforeSpawn?.();let argv=["--socket",options.socket,"--bind",bindSocket,"--replace",`${replaced.dev}:${replaced.ino}`,...options.hostArgs??[]],launch=options._test?.launch?.(argv)??defaultHostLaunch(argv),stderr=await open(paths.stderrLog,"a",384),spawned=spawn(launch.command,[...launch.args],{detached:!0,windowsHide:!0,env:successorHostEnvironment({agentDir:options.agentDir,env:options.env,paths,generation,instanceId}),stdio:["ignore","ignore",stderr.fd]});if(await stderr.close(),child=spawned,exited=new Promise(resolve2=>spawned.once("exit",()=>resolve2())),child.pid===void 0)throw new Error("failed to spawn the successor generation");let processStartTime=await waitForStartTime(child.pid,1e4).catch(()=>{})??null,registration={record:{pid:child.pid,processStartTime},socket:options.socket,instanceId,generation,launchProfileId:hostLaunchProfile(["--mode","rpc","--multi-session",...options.hostArgs??[]],process.cwd()).profile_id};await writeGenerationRecord(paths,registration),await options._test?.afterSpawn?.(child.pid);let answer=await awaitSuccessor(options,host,exited);if(!answer){let reason=await abortReason(options.socket,replaced),cleanupFailure=await abandonSuccessor({child,exited,paths,instanceId,bootSettings});return{action:"refuse",reason,upgradeable:!0,...cleanupFailure&&{detail:cleanupFailure}}}return await writeHostRegistration(paths,registration),child.unref(),signalGeneration(owner.pid,"SIGUSR1"),{action:"handoff",pid:child.pid,socket:options.socket,generation:answer.generation??generation,instanceId:answer.instanceId??""}}catch(cause){let cleanupFailure=await abandonSuccessor({child,exited,paths,instanceId,bootSettings}),detail=cause instanceof Error?cause.message:String(cause);return{action:"refuse",reason:"successor_unavailable",upgradeable:!0,detail:cleanupFailure?`${detail}; ${cleanupFailure}`:detail}}}async function abandonSuccessor(context){let{child,exited,paths,instanceId,bootSettings}=context;child!==void 0&&child.exitCode===null&&child.signalCode===null&&child.kill("SIGKILL");try{bootSettings===void 0?await rm(paths.settingsFile,{force:!0}):await writeFile2(paths.settingsFile,bootSettings,{mode:HOST_STATE_FILE_MODE}),child?.pid===void 0?await rm(generationPaths(paths,instanceId).dir,{recursive:!0,force:!0}):exited!==void 0&&await exitedWithin(exited,SUCCESSOR_EXIT_WAIT_MS)&&await releaseGeneration(paths,{instanceId,pid:child.pid});return}catch(cause){return`successor cleanup failed: ${cause instanceof Error?cause.message:String(cause)}`}}async function exitedWithin(exited,ms){let timer,timedOut=new Promise(resolve2=>{timer=setTimeout(()=>resolve2(!1),ms)});try{return await Promise.race([exited.then(()=>!0),timedOut])}finally{clearTimeout(timer)}}async function awaitSuccessor(options,previous,exited){let deadline=Date.now()+(options._test?.readinessTimeoutMs??DEFAULT_HANDOFF_READINESS_MS),childGone=!1;for(exited.then(()=>{childGone=!0});Date.now()<=deadline;){let answer=await probeProtocolInfo(options.socket,2e3);if(answer&&answer.instanceId!==void 0&&answer.instanceId!==previous.instanceId)return answer;if(childGone)return;await delay(50)}}async function abortReason(socket,replaced){let current=await statSocketIdentity(socket).catch(()=>{});return current===void 0||current.dev!==replaced.dev||current.ino!==replaced.ino?"socket_replaced":"successor_unavailable"}function delay(ms){return new Promise(resolve2=>setTimeout(resolve2,ms))}var HANDOFF_PROBE_TIMEOUT_MS=1e4,HANDOFF_LOCK_HOLD_MS=HANDOFF_PROBE_TIMEOUT_MS+SUCCESSOR_START_BUDGET_MS,HANDOFF_LOCK_WAIT_MS=HANDOFF_PROBE_TIMEOUT_MS+HANDOFF_LOCK_HOLD_MS+1e4;async function handoffHost(options){if(handoffUnsupported(options))return{action:"refuse",reason:"upgrade_unsupported",upgradeable:!1};let release=await acquireHostEnsureLock(options.socket,HANDOFF_LOCK_WAIT_MS);try{return await handoffHostLocked(options)}finally{await release()}}async function handoffHostLocked(options){if(handoffUnsupported(options))return{action:"refuse",reason:"upgrade_unsupported",upgradeable:!1};let paths=createHostDaemonPaths({socket:options.socket,...options.agentDir?{agentDir:options.agentDir}:{}});await createDaemonDirectories(paths);let host=await probeProtocolInfo(options.socket,HANDOFF_PROBE_TIMEOUT_MS);if(!host)return{action:"refuse",reason:"no_host",upgradeable:!1};if(!host.capabilities.includes(GENERATION_HANDOFF_CAPABILITY))return{action:"refuse",reason:"handoff_unsupported",upgradeable:!1};let registered=await readHostRegistration(paths),owner=await provenOwner(registered,options.socket);return owner?startSuccessor({options,paths,host,owner}):{action:"refuse",reason:"unknown_owner",upgradeable:!0}}function handoffUnsupported(options){return(options._test?.platform??process.platform)==="win32"}var hostGenerationScopes=0;function isHostGenerationProcess(){return hostGenerationScopes>0}async function runAsHostGenerationProcess(action){hostGenerationScopes+=1;try{return await action()}finally{hostGenerationScopes-=1}}import{spawn as spawn2}from"node:child_process";import{randomUUID as randomUUID2}from"node:crypto";import{mkdir as mkdir2,open as open2,readdir,readFile,rm as rm2,writeFile as writeFile3}from"node:fs/promises";import{tmpdir as tmpdir2}from"node:os";import{dirname as dirname3,join as join3}from"node:path";var SPAWNED_HOST_PROBE_TIMEOUT_MS=1e4;async function pollProtocolInfo(socket,timeoutMs,isCompatible2,childExit){let deadline=Date.now()+timeoutMs,lastProtocol;for(;Date.now()<=deadline;){let probe=holdProtocolInfo(socket,Math.min(SPAWNED_HOST_PROBE_TIMEOUT_MS,Math.max(1,deadline-Date.now()))),raced=childExit?await Promise.race([probe,childExit]):await probe;if(isChildExit(raced)){let held=await probe;if(!held)return{ready:!1,protocol:lastProtocol,exited:raced};if(lastProtocol=held.info,isCompatible2(held.info))return{ready:!0,protocol:held.info,hold:held.hold};held.hold.release()}else if(raced){if(lastProtocol=raced.info,isCompatible2(raced.info))return{ready:!0,protocol:raced.info,hold:raced.hold};raced.hold.release()}await delay2(50)}return{ready:!1,protocol:lastProtocol}}function isChildExit(value){return!!value&&"code"in value&&"signal"in value}function delay2(ms){return new Promise(resolveDelay=>setTimeout(resolveDelay,ms))}var EXISTING_HOST_PROBE_TIMEOUT_MS=1e4,DEFAULT_READINESS_TIMEOUT_MS=1e4,DEFAULT_STOP_TIMEOUT_MS=1e4,SIGKILL_GRACE_MS=2e3,ENSURE_LOCK_WAIT_MS=EXISTING_HOST_PROBE_TIMEOUT_MS+Math.max(DEFAULT_STOP_TIMEOUT_MS+SIGKILL_GRACE_MS+DEFAULT_READINESS_TIMEOUT_MS,HANDOFF_LOCK_HOLD_MS)+1e4,lockOptions=hostEnsureLockOptions(ENSURE_LOCK_WAIT_MS);async function ensureHost(options){let socket=normalizeSocketPath(options.socket),paths=createHostDaemonPaths({socket,...options.agentDir?{agentDir:options.agentDir}:{}});await createDaemonDirectories(paths);let lockTarget=hostEnsureLockTarget(socket);await mkdir2(dirname3(lockTarget),{recursive:!0}),await writeFile3(lockTarget,"",{flag:"a",mode:384}),await reapOrphanedInternalHostDirs();let release=await acquireOwnershipSafeLock(`${lockTarget}.lock`,lockOptions);try{return await options._test?.afterLockAcquired?.(),await ensureHostLocked(paths,socket,options)}finally{await release()}}async function ensureHostLocked(paths,socket,options){await ensureEndpointIdentity(paths,socket,{repair:!0});let testOptions=options._test,registered=await readHostRegistration(paths),registeredHere=registersSocket(registered,socket),held=await holdProtocolInfo(socket,EXISTING_HOST_PROBE_TIMEOUT_MS),protocol=held?.info,startedByUs=registeredHere&&await writtenByThisProcess(registered?.writer,testOptions?.readProcessStartTime),attachedPid=registeredHere?registered?.record.pid??0:0,decision=decide(options,startedByUs,protocol);if(decision.action==="reuse"&&held)return{pid:attachedPid,socket,reused:!0,release:held.hold.release};switch(held?.hold.release(),decision.action){case"reuse":throw new Error(`host at ${socket} was reused without answering its probe`);case"refuse":throw new HostEnsureRefusedError(socket,decision.reason,protocol);case"handoff":return upgradeGeneration(paths,socket,options,attachedPid);case"start":break;default:return assertNever2(decision)}let probe=testOptions?.readProcessStartTime??readProcessStartTime,pidMatches=registeredHere&&registered?await matchesPidFileOrUnknown(registered.record,probe):!1,stranded;if(registered&&pidMatches)if(startedByUs){if(await probeSocketReachable(socket,EXISTING_HOST_PROBE_TIMEOUT_MS))throw new HostEnsureRefusedError(socket,"host_busy",protocol);await stopManagedHost(registered.record,testOptions?.stopTimeoutMs??DEFAULT_STOP_TIMEOUT_MS,probe)}else{if(await publicEndpointAccepts(socket))throw new HostEnsureRefusedError(socket,"foreign_writer",protocol);stranded=registered}if(await legacyHostIsLive(paths,probe))throw new HostEnsureRefusedError(socket,"legacy_host",protocol);return stranded!==void 0?startHost(paths,socket,options,stranded.generation+1):(registeredHere&&await clearHostRegistration(paths),startHost(paths,socket,options))}var FOREIGN_ENDPOINT_PROBE_TIMEOUT_MS=2e3;async function publicEndpointAccepts(socket){if(process.platform==="win32"||socket.startsWith("\0"))return!0;let entry=await statSocketIdentity(socket).then(identity=>identity===void 0?"absent":"present",()=>"unknown");return entry==="absent"?!1:entry==="unknown"?!0:probeSocketReachable(socket,FOREIGN_ENDPOINT_PROBE_TIMEOUT_MS)}function decide(options,startedByUs,protocol){if(options.upgrade!=="if-engine-differs"||isHostGenerationProcess())return decideHostAction(ensureClient(options,startedByUs),protocol,"never");let decision=decideHostAction(ensureClient(options,startedByUs),protocol,"upgrade");return decision.action==="fallback"?{action:"reuse",reason:"compatible",upgradeable:!1}:decision}async function upgradeGeneration(paths,socket,options,attachedPid){let result=await handoffHostLocked({socket,agentDir:options.agentDir??getAgentDir(),hostArgs:options.hostArgs??[],...options.env?{env:options.env}:{},...options.policy?{policy:options.policy}:{},_test:{...options._test?.launch?{launch:options._test.launch}:{},...options._test?.readinessTimeoutMs?{readinessTimeoutMs:options._test.readinessTimeoutMs}:{}}});return result.action==="handoff"?{pid:result.pid,socket,reused:!1,release:await holdEnsured(socket)}:(await appendStderr(paths,`generation handoff refused: ${result.reason}${result.detail?` (${result.detail})`:""}`),{pid:attachedPid,socket,reused:!0,release:await holdEnsured(socket)})}async function holdEnsured(socket){let held=await holdProtocolInfo(socket,EXISTING_HOST_PROBE_TIMEOUT_MS);if(!held)throw new Error(`RPC socket host at ${socket} stopped answering before this ensure could hold it`);return held.hold.release}function ensureClient(options,startedByUs){return{protocolVersion:HOST_PROTOCOL_VERSION,requiredCapabilities:REQUIRED_HOST_CAPABILITIES,identity:engineBuildIdentity(),...options.upgrade==="if-engine-differs"?{launchProfile:hostLaunchProfile(hostChildArgv(options.hostArgs??[]),process.cwd())}:{},startedByUs,platform:process.platform}}function hostChildArgv(hostArgs){return["--mode","rpc","--multi-session",...hostArgs]}function registersSocket(registered,socket){return registered===void 0?!1:registered.socket===void 0||sameEndpoint(registered.socket,socket)}async function startHost(paths,socket,options,generation=0){let testOptions=options._test,instanceId=randomUUID2();process.platform==="win32"&&await createSocketSecret(socketSecretPath(socket)),await writeHostSettings(paths,{socket,capabilities:PINNED_HOST_CLIENT_CAPABILITIES,coldStart:options.policy?.coldStart??"transient",idleExitMs:options.policy?.idleExitMs??9e5,generation,instanceId});let stderr=await open2(paths.stderrLog,generation===0?"w":"a",384),pidFile,child,exitedEarly,childExit;try{let supervisorArgs=["--socket",socket,...options.hostArgs??[]],launch=testOptions?.spawn??testOptions?.launch?.(supervisorArgs)??defaultHostLaunch(supervisorArgs);if(child=spawn2(launch.command,[...launch.args],{detached:!0,windowsHide:!0,env:initialHostEnvironment({agentDir:options.agentDir,env:options.env,paths,instanceId,generation}),stdio:["ignore","ignore",stderr.fd]}),childExit=new Promise(resolveExit=>{child.once("exit",(code,signal)=>{exitedEarly={code,signal},resolveExit(exitedEarly)})}),child.pid===void 0)throw new Error("failed to spawn RPC socket host");let probe=testOptions?.readProcessStartTime??readProcessStartTime,observedStartTime=await Promise.race([waitForStartTime(child.pid,1e4,probe),childExit.then(()=>{throw new Error("RPC socket host exited before its start time could be read")})]),unhurriedProbe=testOptions?.readProcessStartTime?testOptions.readProcessStartTime:pid=>readProcessStartTime(pid,process.platform,15e3),processStartTime=observedStartTime??await unhurriedProbe(child.pid).catch(()=>{});pidFile={pid:child.pid,processStartTime:processStartTime??null},await testOptions?.beforePidFileWrite?.(),await writeHostRegistration(paths,{record:pidFile,socket,instanceId,generation,launchProfileId:hostLaunchProfile(hostChildArgv(options.hostArgs??[]),process.cwd()).profile_id}),child.unref()}catch(error){let exitedBeforeCleanup=exitedEarly;if(!exitedBeforeCleanup&&child&&child.exitCode===null&&child.signalCode===null){try{child.kill("SIGTERM")}catch{}if(childExit&&await Promise.race([childExit,delay3(2e3)]),child.exitCode===null&&child.signalCode===null)try{child.kill("SIGKILL")}catch{}}if(!exitedBeforeCleanup)throw await clearHostRegistration(paths),error;let diagnostic2=await appendStderr(paths,`RPC socket host exited with code ${exitedBeforeCleanup.code??"null"}${exitedBeforeCleanup.signal?` (${exitedBeforeCleanup.signal})`:""} before answering get_protocol_info`);throw await clearHostRegistration(paths),new Error(diagnostic2)}finally{await stderr.close()}let readinessTimeoutMs=testOptions?.readinessTimeoutMs??DEFAULT_READINESS_TIMEOUT_MS,result=await pollProtocolInfo(socket,readinessTimeoutMs,isCompatible,childExit);if(result.ready)return{pid:pidFile.pid,socket,reused:!1,release:result.hold.release};let stopFailure=await stopSpawnedChild(child,childExit,testOptions?.stopTimeoutMs??DEFAULT_STOP_TIMEOUT_MS).then(()=>{},error=>error instanceof Error?error.message:String(error)),message=result.protocol?`RPC socket host answered get_protocol_info with protocolVersion ${result.protocol.protocolVersion}, serverVersion ${result.protocol.serverVersion} and capabilities ${JSON.stringify(result.protocol.capabilities)}, but is incompatible with protocol version ${HOST_PROTOCOL_VERSION} and required capabilities ${JSON.stringify(REQUIRED_HOST_CAPABILITIES)}`:result.exited?`RPC socket host exited with code ${result.exited.code??"null"}${result.exited.signal?` (${result.exited.signal})`:""} before answering get_protocol_info`:`spawned RPC socket host did not answer get_protocol_info within ${readinessTimeoutMs}ms`,diagnostic=await appendStderr(paths,stopFailure===void 0?message:`${message} (teardown also reported: ${stopFailure})`);throw await clearHostRegistration(paths),new Error(diagnostic)}async function matchesPidFileOrUnknown(pidFile,probe){try{return await processMatchesPidFile(pidFile,probe)}catch(error){if(error instanceof ProcessIdentityUnreadableError)return!1;throw error}}async function stopSpawnedChild(child,childExit,termTimeoutMs){let exited=()=>child.exitCode!==null||child.signalCode!==null;if(exited())return;let signal=name=>{try{child.kill(name)}catch(error){if(!isNodeErrorCode(error,"ESRCH"))throw error}},waitFor=ms=>Promise.race([childExit.then(()=>!0),delay3(ms).then(()=>exited())]);if(signal("SIGTERM"),!await waitFor(termTimeoutMs)&&(signal("SIGKILL"),!await waitFor(SIGKILL_GRACE_MS)))throw new Error(`RPC socket host pid ${child.pid??"?"} remained alive after SIGKILL`)}async function stopManagedHost(pidFile,termTimeoutMs,readStartTime=readProcessStartTime){if(await signalValidated(pidFile,"SIGTERM",readStartTime),!await waitForGone(pidFile,termTimeoutMs,readStartTime)&&(await signalValidated(pidFile,"SIGKILL",readStartTime),!await waitForGone(pidFile,SIGKILL_GRACE_MS,readStartTime)))throw new Error(`RPC socket host pid ${pidFile.pid} remained alive after SIGKILL`)}async function resolvePidFileOwnership(pidFile,readStartTime){try{return await processMatchesPidFile(pidFile,readStartTime,processIsLive,{attempts:1})?"owns":"gone"}catch(error){if(error instanceof ProcessIdentityUnreadableError)return"unknown";throw error}}async function signalValidated(pidFile,signal,readStartTime=readProcessStartTime){if(await resolvePidFileOwnership(pidFile,readStartTime)==="owns")try{process.kill(pidFile.pid,signal)}catch(error){if(!isNodeErrorCode(error,"ESRCH"))throw error}}async function waitForGone(pidFile,timeoutMs,readStartTime=readProcessStartTime){let deadline=Date.now()+timeoutMs;for(;Date.now()<=deadline;){if(await resolvePidFileOwnership(pidFile,readStartTime)==="gone")return!0;await delay3(50)}return await resolvePidFileOwnership(pidFile,readStartTime)==="gone"}function isCompatible(protocol){return decideHostAction(ensureClient({socket:""},!1),protocol,"never").action==="reuse"}async function reapOrphanedInternalHostDirs(){try{let entries=await readdir(tmpdir2(),{withFileTypes:!0});await Promise.all(entries.filter(entry=>entry.isDirectory()&&entry.name.startsWith("senpi-rpc-host-internal-")).map(async entry=>{try{let owner=JSON.parse(await readFile(join3(tmpdir2(),entry.name,".owner"),"utf8"));typeof owner.pid=="number"&&typeof owner.processStartTime=="string"&&typeof owner.createdAt=="number"&&owner.processStartTime.length>0&&owner.createdAt<Date.now()-6e4&&(await readdir(join3(tmpdir2(),entry.name))).length===1&&!await processMatchesPidFile({pid:owner.pid,processStartTime:owner.processStartTime}).catch(error=>{if(error instanceof ProcessIdentityUnreadableError)return!0;throw error})&&await rm2(join3(tmpdir2(),entry.name),{recursive:!0,force:!0})}catch{}}))}catch{}}async function appendStderr(paths,message){try{let stderr=(await readFile(paths.stderrLog,"utf8")).trim();return stderr?`${message}
5
5
  ${stderr}`:message}catch(error){if(isNodeErrorCode(error,"ENOENT"))return message;throw error}}function normalizeSocketPath(value){return value.startsWith("unix://")?value.slice(7):value}function delay3(ms){return new Promise(resolveDelay=>setTimeout(resolveDelay,ms))}function isNodeErrorCode(error,code){return error instanceof Error&&"code"in error&&error.code===code}function assertNever2(value){throw new Error(`unreachable host decision: ${JSON.stringify(value)}`)}export{daemonEnvOverrides,daemonEnvKeys,writeDaemonEnvKeys,readDaemonEnvKeys,parseHostProtocolInfo,HOST_PROTOCOL_VERSION,GENERATION_HANDOFF_CAPABILITY,REQUIRED_HOST_CAPABILITIES,HostEnsureRefusedError,decideHostAction,acquireOwnershipSafeLock,acquireHostEnsureLock,probeHost,probeProtocolInfo,observeProtocolInfo,requestOnSocket,PINNED_HOST_CLIENT_CAPABILITIES,stopHost,handoffHost,runAsHostGenerationProcess,ensureHost};