@seanhogg/builderforce-agents 2026.10.8 → 2026.10.10

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 (98) hide show
  1. package/dist/{audio-preflight-hAkEddaf.js → audio-preflight-CBZJKBS8.js} +1 -1
  2. package/dist/build-info.json +3 -3
  3. package/dist/{builderforce-wxtgU9xu.js → builderforce-2EpP2M8q.js} +3 -3
  4. package/dist/{builderforce-BWCp-M9e.js → builderforce-Cyg20uU8.js} +3 -3
  5. package/dist/{builderforce-onboarding-DuUfZ6oL.js → builderforce-onboarding-C89jVb-9.js} +1 -1
  6. package/dist/{builderforce-onboarding-Dq6VUSKZ.js → builderforce-onboarding-D5A-wEs-.js} +1 -1
  7. package/dist/bundled/boot-md/handler.js +1 -1
  8. package/dist/bundled/session-memory/handler.js +1 -1
  9. package/dist/chrome-CtTMuhww.js +4 -0
  10. package/dist/{command-registry-D_LkOB4n.js → command-registry-CDcuHGpx.js} +1 -1
  11. package/dist/{command-registry-CiR8PUQY.js → command-registry-hHegQvBn.js} +1 -1
  12. package/dist/{completion-cli-C7munVvb.js → completion-cli-Bqr0W4L6.js} +1 -1
  13. package/dist/{completion-cli-CBES884A.js → completion-cli-Ch9ozmkg.js} +1 -1
  14. package/dist/{completion-cli-B72GX2so.js → completion-cli-Ck0FTqPT.js} +1 -1
  15. package/dist/{completion-cli-CijodCzU.js → completion-cli-Do4vXo1k.js} +1 -1
  16. package/dist/{doctor-completion-FErwMP3Y.js → doctor-completion-BjBTLcoC.js} +1 -1
  17. package/dist/{doctor-completion-Bv2ztEeW.js → doctor-completion-Ccs-JEvV.js} +1 -1
  18. package/dist/{embedded-DXDHduG1.js → embedded-BcHzh_y8.js} +6 -6
  19. package/dist/entry.js +1 -1
  20. package/dist/{gateway-cli-DpJjgVYH.js → gateway-cli-CiHNwzdS.js} +3 -3
  21. package/dist/{gateway-cli-U8RlUIuT.js → gateway-cli-z47dfosr.js} +3 -3
  22. package/dist/index.js +2 -2
  23. package/dist/llm-slug-generator.js +1 -1
  24. package/dist/{onboard-O2gyfB4L.js → onboard-D4uXN5Ec.js} +1 -1
  25. package/dist/{onboard-7JGHJRfj.js → onboard-cB37uVxy.js} +1 -1
  26. package/dist/{onboard-interactive-FWIy0HTu.js → onboard-interactive-CnXgQrpI.js} +1 -1
  27. package/dist/{onboard-interactive-DboEcFKf.js → onboard-interactive-CoFFuSJT.js} +1 -1
  28. package/dist/{onboard-interactive-Gl5J4kVC.js → onboard-interactive-gvfRcLOt.js} +1 -1
  29. package/dist/{onboard-interactive-DqpGicxB.js → onboard-interactive-vwqLS6pe.js} +1 -1
  30. package/dist/{onboarding-Ctq_bdkC.js → onboarding-B9GqKO5L.js} +2 -2
  31. package/dist/{onboarding-hPRXZReM.js → onboarding-DdKW5K8Y.js} +2 -2
  32. package/dist/{onboarding.finalize-Db6smxZL.js → onboarding.finalize-CcuO4Yxw.js} +1 -1
  33. package/dist/{onboarding.finalize-B4Tc4IDN.js → onboarding.finalize-D3mTpOdc.js} +1 -1
  34. package/dist/plugin-sdk/{accounts-Cy3WCbWg.js → accounts-BwreSNAR.js} +1 -1
  35. package/dist/plugin-sdk/{active-listener-DVWVNlT9.js → active-listener-DpQ7aGYd.js} +1 -1
  36. package/dist/plugin-sdk/{agent-scope-DgKN27hJ.js → agent-scope-BQByW0cD.js} +1 -1
  37. package/dist/plugin-sdk/{api-key-rotation-ftXf7mBZ.js → api-key-rotation-7YdImWrh.js} +1 -1
  38. package/dist/plugin-sdk/{audio-preflight-CfTmmeS-.js → audio-preflight-EbkaATDO.js} +1 -1
  39. package/dist/plugin-sdk/{auth-json-BrNBg87n.js → auth-json-DK6qod1_.js} +1 -1
  40. package/dist/plugin-sdk/{bindings-CH-YLOLC.js → bindings-CDEzl4kl.js} +1 -1
  41. package/dist/plugin-sdk/{channel-web-B6rg0Rbf.js → channel-web-D2KuONp0.js} +1 -1
  42. package/dist/plugin-sdk/{chrome-CuXP-hes.js → chrome-SOXFIkUM.js} +1 -1
  43. package/dist/plugin-sdk/{chunk-C94IAOuf.js → chunk-cW0POl22.js} +1 -1
  44. package/dist/plugin-sdk/{command-format-B3XMq_73.js → command-format-CAX9XFjI.js} +1 -1
  45. package/dist/plugin-sdk/{common-n0l_XN-S.js → common-BxEWhN2X.js} +1 -1
  46. package/dist/plugin-sdk/{config-DsXZsCkJ.js → config-v1EU9Ll8.js} +2 -2
  47. package/dist/plugin-sdk/{fetch-B-GxSYRO.js → fetch-DH0Y8iyO.js} +1 -1
  48. package/dist/plugin-sdk/index.js +1 -1
  49. package/dist/plugin-sdk/{login-_my8QwPP.js → login-d1zBgykF.js} +1 -1
  50. package/dist/plugin-sdk/{login-qr-BaePtXuG.js → login-qr-B6exvQnN.js} +1 -1
  51. package/dist/plugin-sdk/{manager-BsC-4ymy.js → manager-BH_bmGds.js} +1 -1
  52. package/dist/plugin-sdk/{markdown-tables-BUfhHgfs.js → markdown-tables-Epim9b-0.js} +1 -1
  53. package/dist/plugin-sdk/{message-channel-CuZ2xOAM.js → message-channel-sBPQc_-T.js} +1 -1
  54. package/dist/plugin-sdk/{model-catalog-yuiXVcmw.js → model-catalog-cXsza5GU.js} +1 -1
  55. package/dist/plugin-sdk/{model-selection-BtgvnqB5.js → model-selection-K82MAGlL.js} +1 -1
  56. package/dist/plugin-sdk/{outbound-D_attiyO.js → outbound-Chn_H1O7.js} +1 -1
  57. package/dist/plugin-sdk/{plugins-BdkC9v5E.js → plugins-CaUOZBVb.js} +1 -1
  58. package/dist/plugin-sdk/{pw-ai-A7Rathx6.js → pw-ai-BIiJF7ZD.js} +1 -1
  59. package/dist/plugin-sdk/{qmd-manager-Dxn0jCpE.js → qmd-manager-BRe5fGZw.js} +1 -1
  60. package/dist/plugin-sdk/{registry-CZHRcH-q.js → registry-DJq2Cvo9.js} +1 -1
  61. package/dist/plugin-sdk/{render-CuA_WRX5.js → render-BUCRXPIk.js} +1 -1
  62. package/dist/plugin-sdk/{replies-DmLfO-pg.js → replies-Cz5OD3qN.js} +1 -1
  63. package/dist/plugin-sdk/{reply-3-ne-N_7.js → reply-D5Uk7pUv.js} +9 -9
  64. package/dist/plugin-sdk/{reply-prefix-w7kAvH11.js → reply-prefix-CCymsmsP.js} +1 -1
  65. package/dist/plugin-sdk/{resolve-route-0sbvl4ZN.js → resolve-route-DN1J7Wyc.js} +1 -1
  66. package/dist/plugin-sdk/{runner-4UfrAQnx.js → runner-CYkuO7Fh.js} +4 -4
  67. package/dist/plugin-sdk/{session-BB-yfDWx.js → session-D5jHDo78.js} +1 -1
  68. package/dist/plugin-sdk/{sqlite-JjFgDV-H.js → sqlite-BlMLqMl8.js} +1 -1
  69. package/dist/plugin-sdk/{subsystem-D0Ril4rt.js → subsystem-COTa5Ly_.js} +1 -1
  70. package/dist/plugin-sdk/{tool-images-WRTP95FT.js → tool-images-DSpchb4x.js} +1 -1
  71. package/dist/plugin-sdk/{tool-loop-detection-sC_rhJfb.js → tool-loop-detection-BP6u-mbh.js} +1 -1
  72. package/dist/plugin-sdk/web-BbganhKi.js +1 -0
  73. package/dist/plugin-sdk/{whatsapp-actions-ThxQ5niy.js → whatsapp-actions-CZUqxmP1.js} +1 -1
  74. package/dist/{program-DHWSgdol.js → program-BgDciyOQ.js} +2 -2
  75. package/dist/{program-context-7XUznN5J.js → program-context-CpxTJP1m.js} +1 -1
  76. package/dist/{prompt-select-styled-Depbcbpw.js → prompt-select-styled-Bu7WPMzB.js} +1 -1
  77. package/dist/{prompt-select-styled-Cy70lEMU.js → prompt-select-styled-Qb0DubNy.js} +1 -1
  78. package/dist/{pw-ai-UGketqfG.js → pw-ai-CsJmJcNk.js} +1 -1
  79. package/dist/{register.maintenance-ohxXhvKX.js → register.maintenance-CPnm6L-m.js} +1 -1
  80. package/dist/{register.maintenance-BmnagkdH.js → register.maintenance-D8WmeEaD.js} +1 -1
  81. package/dist/{register.onboard-C2Cnd-e9.js → register.onboard-BoUicPRh.js} +1 -1
  82. package/dist/{register.onboard-FSaweh3A.js → register.onboard-DMfqe2nX.js} +1 -1
  83. package/dist/{register.setup-CyTZQLXP.js → register.setup-BK6OEvY3.js} +1 -1
  84. package/dist/{register.setup-Dk9hBOkZ.js → register.setup-CtcAR3JR.js} +1 -1
  85. package/dist/{register.subclis-lGgi7ATb.js → register.subclis-Dl6jPPsc.js} +1 -1
  86. package/dist/{register.subclis-DqO3Ciiv.js → register.subclis-EScCVgbV.js} +1 -1
  87. package/dist/{run-main-BipfHjUR.js → run-main-C3lmcvyV.js} +1 -1
  88. package/dist/{runner-B70PGCqP.js → runner-D7af_RBH.js} +3 -3
  89. package/dist/{tui-DHjIJOFN.js → tui-D2sTsa4p.js} +1 -1
  90. package/dist/{tui-C5ChWpBg.js → tui-DY2oYbxk.js} +1 -1
  91. package/dist/{tui-cli-BeFWcUWU.js → tui-cli-GW-qybY6.js} +1 -1
  92. package/dist/{tui-cli-wPseN93O.js → tui-cli-wn3DmvUG.js} +1 -1
  93. package/dist/{update-cli-CRkZnN_N.js → update-cli-CN0oxZ_A.js} +1 -1
  94. package/dist/{update-cli-DekV-CP_.js → update-cli-K5dGZmg8.js} +1 -1
  95. package/dist/{web-D44jKC1F.js → web-DPGGHIc_.js} +1 -1
  96. package/package.json +1 -1
  97. package/dist/chrome-Blk2Jftn.js +0 -4
  98. package/dist/plugin-sdk/web-CThgoHQp.js +0 -1
@@ -1 +1 @@
1
- import"./paths-BVMSM1lQ.js";import"./session-key-CYpYHc1e.js";import{X as shouldLogVerbose,q as logVerbose}from"./registry-D_frpmHZ.js";import"./agent-scope-EkacNLg3.js";import"./subsystem-BakM_oqD.js";import"./workspace-BCjtHT4u.js";import"./model-selection-BJ0saFZo.js";import"./env-BhRm7_r8.js";import"./boolean-ssGoaBPk.js";import"./src-CLWuGn12.js";import"./plugins-J28Y83f5.js";import"./accounts-193gfWbH.js";import"./bindings-BfB5A-by.js";import"./accounts-DHeA4T6C.js";import"./fetch-BklyLYYN.js";import"./model-catalog-Abk8cdEI.js";import"./redact-sNZY-pGx.js";import"./errors-BmztzL5I.js";import{a as runCapability,n as createMediaAttachmentCache,o as isAudioAttachment,r as normalizeMediaAttachments,t as buildProviderRegistry}from"./runner-B70PGCqP.js";import"./config-bxyMjPHU.js";import"./chrome-Blk2Jftn.js";import"./frontmatter-DBVosMFY.js";import"./store-DN9AcI73.js";import"./message-channel-tBuQgYSD.js";import"./accounts-C7FtIPYB.js";import"./paths-CzXKnIOb.js";import"./gemini-auth-CzGGgJ0p.js";import"./tool-images-mfC2sOfJ.js";async function transcribeFirstAudio(params){let{ctx,cfg}=params,audioConfig=cfg.tools?.media?.audio;if(!audioConfig||audioConfig.enabled===!1)return;let attachments=normalizeMediaAttachments(ctx);if(!attachments||attachments.length===0)return;let firstAudio=attachments.find(att=>att&&isAudioAttachment(att)&&!att.alreadyTranscribed);if(!firstAudio)return;shouldLogVerbose()&&logVerbose(`audio-preflight: transcribing attachment ${firstAudio.index} for mention check`);let providerRegistry=buildProviderRegistry(params.providers),cache=createMediaAttachmentCache(attachments);try{let result=await runCapability({capability:`audio`,cfg,ctx,attachments:cache,media:attachments,agentDir:params.agentDir,providerRegistry,config:audioConfig,activeModel:params.activeModel});if(!result||result.outputs.length===0)return;let audioOutput=result.outputs.find(output=>output.kind===`audio.transcription`);return!audioOutput||!audioOutput.text?void 0:(firstAudio.alreadyTranscribed=!0,shouldLogVerbose()&&logVerbose(`audio-preflight: transcribed ${audioOutput.text.length} chars from attachment ${firstAudio.index}`),audioOutput.text)}catch(err){shouldLogVerbose()&&logVerbose(`audio-preflight: transcription failed: ${String(err)}`);return}finally{await cache.cleanup()}}export{transcribeFirstAudio};
1
+ import"./paths-BVMSM1lQ.js";import"./session-key-CYpYHc1e.js";import{X as shouldLogVerbose,q as logVerbose}from"./registry-D_frpmHZ.js";import"./agent-scope-EkacNLg3.js";import"./subsystem-BakM_oqD.js";import"./workspace-BCjtHT4u.js";import"./model-selection-BJ0saFZo.js";import"./env-BhRm7_r8.js";import"./boolean-ssGoaBPk.js";import"./src-CLWuGn12.js";import"./plugins-J28Y83f5.js";import"./accounts-193gfWbH.js";import"./bindings-BfB5A-by.js";import"./accounts-DHeA4T6C.js";import"./fetch-BklyLYYN.js";import"./model-catalog-Abk8cdEI.js";import"./redact-sNZY-pGx.js";import"./errors-BmztzL5I.js";import{a as runCapability,n as createMediaAttachmentCache,o as isAudioAttachment,r as normalizeMediaAttachments,t as buildProviderRegistry}from"./runner-D7af_RBH.js";import"./config-bxyMjPHU.js";import"./chrome-CtTMuhww.js";import"./frontmatter-DBVosMFY.js";import"./store-DN9AcI73.js";import"./message-channel-tBuQgYSD.js";import"./accounts-C7FtIPYB.js";import"./paths-CzXKnIOb.js";import"./gemini-auth-CzGGgJ0p.js";import"./tool-images-mfC2sOfJ.js";async function transcribeFirstAudio(params){let{ctx,cfg}=params,audioConfig=cfg.tools?.media?.audio;if(!audioConfig||audioConfig.enabled===!1)return;let attachments=normalizeMediaAttachments(ctx);if(!attachments||attachments.length===0)return;let firstAudio=attachments.find(att=>att&&isAudioAttachment(att)&&!att.alreadyTranscribed);if(!firstAudio)return;shouldLogVerbose()&&logVerbose(`audio-preflight: transcribing attachment ${firstAudio.index} for mention check`);let providerRegistry=buildProviderRegistry(params.providers),cache=createMediaAttachmentCache(attachments);try{let result=await runCapability({capability:`audio`,cfg,ctx,attachments:cache,media:attachments,agentDir:params.agentDir,providerRegistry,config:audioConfig,activeModel:params.activeModel});if(!result||result.outputs.length===0)return;let audioOutput=result.outputs.find(output=>output.kind===`audio.transcription`);return!audioOutput||!audioOutput.text?void 0:(firstAudio.alreadyTranscribed=!0,shouldLogVerbose()&&logVerbose(`audio-preflight: transcribed ${audioOutput.text.length} chars from attachment ${firstAudio.index}`),audioOutput.text)}catch(err){shouldLogVerbose()&&logVerbose(`audio-preflight: transcription failed: ${String(err)}`);return}finally{await cache.cleanup()}}export{transcribeFirstAudio};
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2026.10.8",
3
- "commit": "5d9ad7343669e2fb347d25fc224f02252d4a0bc8",
4
- "builtAt": "2026-10-17T22:01:58.252Z"
2
+ "version": "2026.10.10",
3
+ "commit": "cffa668853c1390933521f96cb644f191eb5f583",
4
+ "builtAt": "2026-10-18T02:06:51.934Z"
5
5
  }
@@ -1,4 +1,4 @@
1
- import"./paths-BHg-VHB4.js";import"./registry-Cv7CoWAs.js";import{z as theme}from"./utils-BP60e80M.js";import"./subsystem-C4b1Von0.js";import"./boolean-ssGoaBPk.js";import"./env-BoE8QSib.js";import"./auth-profiles-C1VbcUOm.js";import"./src-DvWaTze9.js";import"./logger-wuOr7HKl.js";import"./session-key-CksCYipj.js";import"./builderforce-root-DY1qbWNX.js";import"./exec-COgsU9ql.js";import"./agent-scope-CufEmNj_.js";import{t as normalizeBaseUrl}from"./normalize-base-url-D_sv6Zgt.js";import{a as upsertSharedEnvVar,i as readSharedEnvVar}from"./env-file-DeS6x2OL.js";import"./src-HrLX5bhG.js";import{U as VERSION,a as readConfigFileSnapshot,c as writeConfigFile}from"./io-CohJffHG.js";import"./manifest-registry-009gLJ4l.js";import"./config-toczWD3q.js";import"./model-discovery-C9Xm95uL.js";import"./model-catalog-CiiFJX77.js";import"./frontmatter-CaY7feZm.js";import"./skills-D3MwwPOH.js";import"./plugin-skills-pSFUbhg_.js";import"./client-CGgp3zkQ.js";import"./call-DmAU4cRX.js";import"./message-channel-z5YRpR2d.js";import"./sessions-Bl1wwotX.js";import{_ as isBuilderForceAgentsProject,n as loadProjectContext,o as updateProjectContextFields}from"./project-context-store-CIUcwUP_.js";import"./plugins-1Mn6RiNf.js";import"./accounts-BkTLjSrD.js";import"./bindings-CKSDlQ1i.js";import"./accounts-Cx82nj4E.js";import"./image-ops-CotJhwRR.js";import"./redact-CgO7wehS.js";import"./errors-tAt19c1E.js";import"./embedded-helpers-DK8_apW0.js";import"./sandbox-z9t_PRf9.js";import"./chrome-BnEbJV3D.js";import"./tailscale-DV-yOmYe.js";import"./auth-ChecwOXS.js";import"./server-context-owOmmyUM.js";import"./routes-lclJHOYY.js";import"./paths-BnOjueoX.js";import"./ssrf-DJXLYZ0d.js";import"./store-DHD2IEgd.js";import"./ports-DTku9NSx.js";import"./trash-C3zmJ_O7.js";import"./accounts-DcoaLXKI.js";import"./paths-ClsbsPQP.js";import"./tool-images-CCpqFtrL.js";import"./tool-display-Cs4hDP1f.js";import{n as fetchWithTimeout}from"./fetch-timeout-Cb8Yj9Tw.js";import"./builderforcellm-syscheck-CprBhARf.js";import"./usage-format-5sp5AMSu.js";import{f as initializeBuilderForceAgentsProject}from"./project-context-D3Mx4maV.js";import{r as saveMambaState}from"./mamba-state-engine-CV4nDcCk.js";import"./transformers-stream-Buj40qHl.js";import"./builderforce-directory-sync-DQ6u60yX.js";import"./shared-xj-xaKFi.js";import{_ as setOpenrouterApiKey,c as setAnthropicApiKey,u as setGeminiApiKey}from"./onboard-auth.credentials-yagR-VMG.js";import"./model-picker-swoSwauV.js";import"./auth-choice.apply.transformers-1plI0MUg.js";import{t as runTui}from"./tui-C5ChWpBg.js";import"./tui-stream-assembler-q9GANTDr.js";import path from"node:path";import fs from"node:fs/promises";import{confirm,intro,note,outro,password,select,spinner,text}from"@clack/prompts";import{Command}from"commander";const DEFAULT_REGISTRY_URL=`https://api.builderforce.ai`;function resolveRegistryUrl(){return normalizeBaseUrl(readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_URL`)??DEFAULT_REGISTRY_URL)}function resolveAuthHeaders(){let apiKey=readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_API_KEY`);return apiKey?{Authorization:`Bearer ${apiKey}`}:{}}function isV2Package(pkg){return pkg.version===`2.0`}async function fetchAgentPackage(params){let url=`${normalizeBaseUrl(params.registryUrl??resolveRegistryUrl())}/api/agents/${encodeURIComponent(params.agentId)}/package`,res;try{res=await fetchWithTimeout(url,{method:`GET`,headers:{Accept:`application/json`,...resolveAuthHeaders()}},3e4)}catch(err){let msg=err instanceof Error?err.message:String(err);throw Error(`Network error fetching agent package: ${msg}`,{cause:err})}if(!res.ok){let text=await res.text().catch(()=>``);throw Error(`Registry returned ${res.status} ${res.statusText}${text?`: ${text}`:``}`)}let pkg=await res.json();if(!pkg.version||!pkg.platform||!pkg.name||!pkg.base_model)throw Error(`Invalid agent package: missing required fields (version, platform, name, base_model)`);return pkg}function resolveWorkforceModelRef(params){return readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_API_KEY`)?`builderforcellm/workforce-${params.agentId}`:params.pkg.base_model}async function installWorkforceAgent(params){let registryUrl=params.registryUrl??resolveRegistryUrl(),spin=spinner();spin.start(`Fetching agent package for "${params.agentId}" from ${registryUrl}…`);let pkg;try{pkg=await fetchAgentPackage({agentId:params.agentId,registryUrl}),spin.stop(`Package downloaded: ${pkg.name} (v${pkg.version})`)}catch(err){throw spin.stop(`Failed to download agent package`),err}let modelRef=resolveWorkforceModelRef({agentId:params.agentId,pkg}),hasMambaState=isV2Package(pkg)&&!!pkg.mamba_state,installed={agentId:params.agentId,name:pkg.name,title:pkg.title,baseModel:pkg.base_model,modelRef,loraArtifactKey:pkg.r2_artifact_key,packageVersion:pkg.version,hasMambaState,installedAt:new Date().toISOString(),registryUrl};return await updateProjectContextFields(params.projectRoot,{customAgent:installed,llm:{provider:`builderforcellm`,model:modelRef}}),hasMambaState&&isV2Package(pkg)&&pkg.mamba_state&&await saveMambaState(params.projectRoot,pkg.mamba_state),[`Workforce agent installed: ${pkg.name} (${params.agentId})`,` Base model: ${pkg.base_model}`,` Package: v${pkg.version}`,` Mamba state: ${hasMambaState?`yes (persistent memory)`:`no`}`,` Model ref: ${modelRef}`].join(`
1
+ import"./paths-BHg-VHB4.js";import"./registry-Cv7CoWAs.js";import{z as theme}from"./utils-BP60e80M.js";import"./subsystem-C4b1Von0.js";import"./boolean-ssGoaBPk.js";import"./env-BoE8QSib.js";import"./auth-profiles-C1VbcUOm.js";import"./src-DvWaTze9.js";import"./logger-wuOr7HKl.js";import"./session-key-CksCYipj.js";import"./builderforce-root-DY1qbWNX.js";import"./exec-COgsU9ql.js";import"./agent-scope-CufEmNj_.js";import{t as normalizeBaseUrl}from"./normalize-base-url-D_sv6Zgt.js";import{a as upsertSharedEnvVar,i as readSharedEnvVar}from"./env-file-DeS6x2OL.js";import"./src-HrLX5bhG.js";import{U as VERSION,a as readConfigFileSnapshot,c as writeConfigFile}from"./io-CohJffHG.js";import"./manifest-registry-009gLJ4l.js";import"./config-toczWD3q.js";import"./model-discovery-C9Xm95uL.js";import"./model-catalog-CiiFJX77.js";import"./frontmatter-CaY7feZm.js";import"./skills-D3MwwPOH.js";import"./plugin-skills-pSFUbhg_.js";import"./client-CGgp3zkQ.js";import"./call-DmAU4cRX.js";import"./message-channel-z5YRpR2d.js";import"./sessions-Bl1wwotX.js";import{_ as isBuilderForceAgentsProject,n as loadProjectContext,o as updateProjectContextFields}from"./project-context-store-CIUcwUP_.js";import"./plugins-1Mn6RiNf.js";import"./accounts-BkTLjSrD.js";import"./bindings-CKSDlQ1i.js";import"./accounts-Cx82nj4E.js";import"./image-ops-CotJhwRR.js";import"./redact-CgO7wehS.js";import"./errors-tAt19c1E.js";import"./embedded-helpers-DK8_apW0.js";import"./sandbox-z9t_PRf9.js";import"./chrome-BnEbJV3D.js";import"./tailscale-DV-yOmYe.js";import"./auth-ChecwOXS.js";import"./server-context-owOmmyUM.js";import"./routes-lclJHOYY.js";import"./paths-BnOjueoX.js";import"./ssrf-DJXLYZ0d.js";import"./store-DHD2IEgd.js";import"./ports-DTku9NSx.js";import"./trash-C3zmJ_O7.js";import"./accounts-DcoaLXKI.js";import"./paths-ClsbsPQP.js";import"./tool-images-CCpqFtrL.js";import"./tool-display-Cs4hDP1f.js";import{n as fetchWithTimeout}from"./fetch-timeout-Cb8Yj9Tw.js";import"./builderforcellm-syscheck-CprBhARf.js";import"./usage-format-5sp5AMSu.js";import{f as initializeBuilderForceAgentsProject}from"./project-context-D3Mx4maV.js";import{r as saveMambaState}from"./mamba-state-engine-CV4nDcCk.js";import"./transformers-stream-Buj40qHl.js";import"./builderforce-directory-sync-DQ6u60yX.js";import"./shared-xj-xaKFi.js";import{_ as setOpenrouterApiKey,c as setAnthropicApiKey,u as setGeminiApiKey}from"./onboard-auth.credentials-yagR-VMG.js";import"./model-picker-swoSwauV.js";import"./auth-choice.apply.transformers-1plI0MUg.js";import{t as runTui}from"./tui-DY2oYbxk.js";import"./tui-stream-assembler-q9GANTDr.js";import path from"node:path";import fs from"node:fs/promises";import{confirm,intro,note,outro,password,select,spinner,text}from"@clack/prompts";import{Command}from"commander";const DEFAULT_REGISTRY_URL=`https://api.builderforce.ai`;function resolveRegistryUrl(){return normalizeBaseUrl(readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_URL`)??DEFAULT_REGISTRY_URL)}function resolveAuthHeaders(){let apiKey=readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_API_KEY`);return apiKey?{Authorization:`Bearer ${apiKey}`}:{}}function isV2Package(pkg){return pkg.version===`2.0`}async function fetchAgentPackage(params){let url=`${normalizeBaseUrl(params.registryUrl??resolveRegistryUrl())}/api/agents/${encodeURIComponent(params.agentId)}/package`,res;try{res=await fetchWithTimeout(url,{method:`GET`,headers:{Accept:`application/json`,...resolveAuthHeaders()}},3e4)}catch(err){let msg=err instanceof Error?err.message:String(err);throw Error(`Network error fetching agent package: ${msg}`,{cause:err})}if(!res.ok){let text=await res.text().catch(()=>``);throw Error(`Registry returned ${res.status} ${res.statusText}${text?`: ${text}`:``}`)}let pkg=await res.json();if(!pkg.version||!pkg.platform||!pkg.name||!pkg.base_model)throw Error(`Invalid agent package: missing required fields (version, platform, name, base_model)`);return pkg}function resolveWorkforceModelRef(params){return readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_API_KEY`)?`builderforcellm/workforce-${params.agentId}`:params.pkg.base_model}async function installWorkforceAgent(params){let registryUrl=params.registryUrl??resolveRegistryUrl(),spin=spinner();spin.start(`Fetching agent package for "${params.agentId}" from ${registryUrl}…`);let pkg;try{pkg=await fetchAgentPackage({agentId:params.agentId,registryUrl}),spin.stop(`Package downloaded: ${pkg.name} (v${pkg.version})`)}catch(err){throw spin.stop(`Failed to download agent package`),err}let modelRef=resolveWorkforceModelRef({agentId:params.agentId,pkg}),hasMambaState=isV2Package(pkg)&&!!pkg.mamba_state,installed={agentId:params.agentId,name:pkg.name,title:pkg.title,baseModel:pkg.base_model,modelRef,loraArtifactKey:pkg.r2_artifact_key,packageVersion:pkg.version,hasMambaState,installedAt:new Date().toISOString(),registryUrl};return await updateProjectContextFields(params.projectRoot,{customAgent:installed,llm:{provider:`builderforcellm`,model:modelRef}}),hasMambaState&&isV2Package(pkg)&&pkg.mamba_state&&await saveMambaState(params.projectRoot,pkg.mamba_state),[`Workforce agent installed: ${pkg.name} (${params.agentId})`,` Base model: ${pkg.base_model}`,` Package: v${pkg.version}`,` Mamba state: ${hasMambaState?`yes (persistent memory)`:`no`}`,` Model ref: ${modelRef}`].join(`
2
2
  `)}async function showWorkforceAgentInfo(projectRoot){let ctx=await loadProjectContext(projectRoot);if(!ctx?.customAgent){note(`No Workforce agent is installed in this project.
3
3
 
4
4
  Run: builderforce agent install <agentId>`,`No agent installed`);return}let a=ctx.customAgent;note([theme.heading(`Workforce Agent`),` ID: ${a.agentId}`,` Name: ${a.name}${a.title?` — ${a.title}`:``}`,` Base model: ${a.baseModel}`,` Model ref: ${a.modelRef}`,` Package: v${a.packageVersion}`,` Mamba state: ${a.hasMambaState?`yes (persistent memory)`:`no`}`,` Installed: ${a.installedAt}`,` Registry: ${a.registryUrl}`].join(`
@@ -6,9 +6,9 @@ Run: builderforce agent install <agentId>`,`No agent installed`);return}let a=ct
6
6
  `)+`
7
7
 
8
8
  `),await runTui({message:opts.message})}async function readJsonFile(filePath){try{let content=await fs.readFile(filePath,`utf-8`);return JSON.parse(content)}catch{return null}}async function fileExists(filePath){try{return await fs.access(filePath),!0}catch{return!1}}async function detectLanguagesFromFiles(projectRoot){let extLangMap={".ts":`typescript`,".tsx":`typescript`,".js":`javascript`,".jsx":`javascript`,".mjs":`javascript`,".cjs":`javascript`,".py":`python`,".go":`go`,".rs":`rust`,".java":`java`,".kt":`kotlin`,".swift":`swift`,".rb":`ruby`,".php":`php`,".cs":`csharp`,".cpp":`cpp`,".c":`c`,".dart":`dart`,".ex":`elixir`,".exs":`elixir`,".hs":`haskell`},counts={},ignoreDirs=new Set([`node_modules`,`.git`,`dist`,`build`,`.builderForceAgents`,`__pycache__`,`.next`,`out`,`coverage`,`vendor`]);async function walk(dir,depth){if(depth>3)return;let entries;try{entries=await fs.readdir(dir,{withFileTypes:!0})}catch{return}for(let entry of entries)if(entry.isDirectory())!ignoreDirs.has(entry.name)&&!entry.name.startsWith(`.`)&&await walk(path.join(dir,entry.name),depth+1);else{let lang=extLangMap[path.extname(entry.name).toLowerCase()];lang&&(counts[lang]=(counts[lang]??0)+1)}}return await walk(projectRoot,0),Object.entries(counts).toSorted((a,b)=>b[1]-a[1]).map(([lang])=>lang)}async function detectFrameworks(projectRoot,pkgDeps){let found=[],all=Object.keys(pkgDeps);for(let[match,label]of[[`next`,`next.js`],[`nuxt`,`nuxt`],[/^@remix-run/,`remix`],[`astro`,`astro`],[`@sveltejs/kit`,`sveltekit`],[`svelte`,`svelte`],[`react`,`react`],[`vue`,`@vue`],[`angular`,`angular`],[`express`,`express`],[`fastify`,`fastify`],[`hono`,`hono`],[`koa`,`koa`],[`nest`,`nestjs`],[/^@nestjs/,`nestjs`],[`trpc`,`trpc`],[/^@trpc/,`trpc`],[`drizzle-orm`,`drizzle`],[`prisma`,`prisma`],[/^@prisma/,`prisma`],[`mongoose`,`mongoose`],[`typeorm`,`typeorm`],[`django`,`django`],[`flask`,`flask`],[`fastapi`,`fastapi`],[`tailwindcss`,`tailwind`]])found.includes(label)||(typeof match==`string`?all.some(k=>k===match||k.startsWith(`${match}/`)||k.startsWith(`@${match}/`))&&found.push(label):all.some(k=>match.test(k))&&found.push(label));for(let[file,label]of[[`next.config.js`,`next.js`],[`next.config.ts`,`next.js`],[`nuxt.config.ts`,`nuxt`],[`astro.config.mjs`,`astro`],[`astro.config.ts`,`astro`],[`svelte.config.js`,`sveltekit`],[`vite.config.ts`,`vite`],[`vite.config.js`,`vite`],[`angular.json`,`angular`],[`remix.config.js`,`remix`],[`tailwind.config.ts`,`tailwind`],[`tailwind.config.js`,`tailwind`]])!found.includes(label)&&await fileExists(path.join(projectRoot,file))&&found.push(label);return[...new Set(found)]}async function detectTestFramework(projectRoot,pkgDeps){let all=Object.keys(pkgDeps);if(all.includes(`vitest`))return`vitest`;if(all.includes(`jest`)||all.some(k=>k.startsWith(`@jest/`)))return`jest`;if(all.includes(`mocha`))return`mocha`;if(all.includes(`jasmine`))return`jasmine`;if(all.includes(`ava`))return`ava`;if(all.includes(`pytest`)||await fileExists(path.join(projectRoot,`pytest.ini`)))return`pytest`;if(await fileExists(path.join(projectRoot,`vitest.config.ts`)))return`vitest`;if(await fileExists(path.join(projectRoot,`jest.config.js`))||await fileExists(path.join(projectRoot,`jest.config.ts`)))return`jest`}async function detectLintingTools(projectRoot,pkgDeps){let tools=[],all=Object.keys(pkgDeps);return(all.includes(`eslint`)||await fileExists(path.join(projectRoot,`.eslintrc.js`)))&&tools.push(`eslint`),all.includes(`oxlint`)&&tools.push(`oxlint`),(all.includes(`prettier`)||await fileExists(path.join(projectRoot,`.prettierrc`)))&&tools.push(`prettier`),all.includes(`biome`)&&tools.push(`biome`),(all.includes(`ruff`)||await fileExists(path.join(projectRoot,`ruff.toml`)))&&tools.push(`ruff`),all.includes(`pylint`)&&tools.push(`pylint`),tools}async function detectBuildSystem(projectRoot,pkgDeps){let all=Object.keys(pkgDeps);if(all.includes(`turbo`))return`turborepo`;if(all.includes(`nx`))return`nx`;if(all.includes(`tsdown`)||all.includes(`tsup`))return all.includes(`tsdown`)?`tsdown`:`tsup`;if(all.includes(`vite`))return`vite`;if(all.includes(`webpack`))return`webpack`;if(all.includes(`rollup`))return`rollup`;if(all.includes(`esbuild`))return`esbuild`;if(await fileExists(path.join(projectRoot,`Makefile`)))return`make`;if(await fileExists(path.join(projectRoot,`CMakeLists.txt`)))return`cmake`;if(await fileExists(path.join(projectRoot,`Cargo.toml`)))return`cargo`;if(await fileExists(path.join(projectRoot,`pyproject.toml`)))return`poetry`;if(await fileExists(path.join(projectRoot,`setup.py`)))return`setuptools`;if(await fileExists(path.join(projectRoot,`pnpm-lock.yaml`)))return`pnpm`;if(await fileExists(path.join(projectRoot,`yarn.lock`)))return`yarn`;if(await fileExists(path.join(projectRoot,`package-lock.json`)))return`npm`}async function detectProjectInfo(projectRoot){let pkg=await readJsonFile(path.join(projectRoot,`package.json`)),pkgName=typeof pkg?.name==`string`?pkg.name:``,pkgDesc=typeof pkg?.description==`string`?pkg.description:``,allDeps={...pkg?.dependencies,...pkg?.devDependencies,...pkg?.peerDependencies},[langsByFile,frameworks,testFramework,lintingTools,buildSystem]=await Promise.all([detectLanguagesFromFiles(projectRoot),detectFrameworks(projectRoot,allDeps),detectTestFramework(projectRoot,allDeps),detectLintingTools(projectRoot,allDeps),detectBuildSystem(projectRoot,allDeps)]),languages=await fileExists(path.join(projectRoot,`tsconfig.json`))?[`typescript`,...langsByFile.filter(l=>l!==`typescript`)]:langsByFile;return{projectName:pkgName||path.basename(projectRoot),description:pkgDesc,languages:[...new Set(languages)].slice(0,6),frameworks,buildSystem,testFramework,lintingTools}}const PROVIDERS=[{id:`builderforcellm`,label:`BuilderForceAgentsLLM (recommended) — Builderforce.AI`,defaultModel:`builderforcellm/auto`},{id:`anthropic`,label:`Anthropic (Claude)`,envVar:`ANTHROPIC_API_KEY`,defaultModel:`anthropic/claude-sonnet-4-6`},{id:`openai`,label:`OpenAI (GPT-4o)`,envVar:`OPENAI_API_KEY`,defaultModel:`openai/gpt-4o`},{id:`openrouter`,label:`OpenRouter`,envVar:`OPENROUTER_API_KEY`,defaultModel:`openrouter/auto`},{id:`gemini`,label:`Google Gemini`,envVar:`GEMINI_API_KEY`,defaultModel:`google/gemini-2.0-flash`},{id:`ollama`,label:`Ollama (local)`,envVar:`OLLAMA_API_KEY`,defaultModel:`ollama/llama3.3`},{id:`vllm`,label:`vLLM / llama.cpp / LiteLLM (local)`,defaultModel:`vllm/your-model-id`},{id:`workforce`,label:`Builderforce Workforce Agent (custom trained LLM)`,defaultModel:`builderforcellm/auto`}];function isProviderConfigured(p){if(!p.envVar)return!1;let val=process.env[p.envVar];return typeof val==`string`&&val.trim().length>0}async function applyLlmProviderModel(projectRoot,provider,modelRef){try{await updateProjectContextFields(projectRoot,{llm:{provider,model:modelRef}})}catch{}}async function promptWorkforceAgentProvider(projectRoot){let registryUrl=await text({message:`Builderforce registry URL:`,initialValue:DEFAULT_REGISTRY_URL});if(typeof registryUrl==`symbol`)return null;let agentIdInput=await text({message:`Workforce agent ID (from the Builderforce registry):`,placeholder:`e.g. 550e8400-e29b-41d4-a716-446655440000`});if(typeof agentIdInput==`symbol`||!agentIdInput.trim())return null;let agentId=agentIdInput.trim();try{return await installWorkforceAgent({agentId,projectRoot,registryUrl:normalizeBaseUrl(registryUrl.trim())||DEFAULT_REGISTRY_URL})}catch(err){return note([err instanceof Error?err.message:String(err),``,`You can retry later with: builderforce agent install <agentId>`].join(`
9
- `),`Failed to install Workforce agent`),null}}async function promptLlmProvider(projectRoot){let chosen=await select({message:`LLM provider to use for AI agents:`,options:[...PROVIDERS.map(p=>({value:p.id,label:isProviderConfigured(p)?`${p.label} ✓ configured`:p.label,hint:p.id===`builderforcellm`?`managed proxy (no local API key needed)`:isProviderConfigured(p)?`${p.envVar} is set`:p.envVar?`needs ${p.envVar}`:`enter server URL`})),{value:`skip`,label:`Skip — configure later`}]});if(typeof chosen==`symbol`||chosen===`skip`)return null;if(chosen===`workforce`)return promptWorkforceAgentProvider(projectRoot);let meta=PROVIDERS.find(p=>p.id===chosen);if(chosen===`builderforcellm`||chosen===`anthropic`||chosen===`openai`||chosen===`openrouter`||chosen===`gemini`){if(chosen===`builderforcellm`){if(!readSharedEnvVar(`BUILDERFORCE_API_KEY`)?.trim()){let{promptBuilderforceOnboarding}=await import(`./builderforce-onboarding-Dq6VUSKZ.js`);await promptBuilderforceOnboarding({projectRoot,defaultInstanceName:path.basename(projectRoot)||`builderforce`,forcePrompt:!0}),readSharedEnvVar(`BUILDERFORCE_API_KEY`)?.trim()||note([`BuilderForceAgentsLLM requires a Builderforce account to work.`,`You can connect later with: builderforce init --reconnect`,`Or switch to a different provider with: builderforce init`].join(`
9
+ `),`Failed to install Workforce agent`),null}}async function promptLlmProvider(projectRoot){let chosen=await select({message:`LLM provider to use for AI agents:`,options:[...PROVIDERS.map(p=>({value:p.id,label:isProviderConfigured(p)?`${p.label} ✓ configured`:p.label,hint:p.id===`builderforcellm`?`managed proxy (no local API key needed)`:isProviderConfigured(p)?`${p.envVar} is set`:p.envVar?`needs ${p.envVar}`:`enter server URL`})),{value:`skip`,label:`Skip — configure later`}]});if(typeof chosen==`symbol`||chosen===`skip`)return null;if(chosen===`workforce`)return promptWorkforceAgentProvider(projectRoot);let meta=PROVIDERS.find(p=>p.id===chosen);if(chosen===`builderforcellm`||chosen===`anthropic`||chosen===`openai`||chosen===`openrouter`||chosen===`gemini`){if(chosen===`builderforcellm`){if(!readSharedEnvVar(`BUILDERFORCE_API_KEY`)?.trim()){let{promptBuilderforceOnboarding}=await import(`./builderforce-onboarding-D5A-wEs-.js`);await promptBuilderforceOnboarding({projectRoot,defaultInstanceName:path.basename(projectRoot)||`builderforce`,forcePrompt:!0}),readSharedEnvVar(`BUILDERFORCE_API_KEY`)?.trim()||note([`BuilderForceAgentsLLM requires a Builderforce account to work.`,`You can connect later with: builderforce init --reconnect`,`Or switch to a different provider with: builderforce init`].join(`
10
10
  `),`Skipped — BuilderForceAgentsLLM won't be available yet`)}return await applyLlmProviderModel(projectRoot,chosen,meta.defaultModel),`${meta.label} configured, model → ${meta.defaultModel}`}if(isProviderConfigured(meta))return note(`${meta.envVar} is already set — keeping existing credential.`,meta.label),await applyLlmProviderModel(projectRoot,chosen,meta.defaultModel),`${meta.label} (existing credential kept), model → ${meta.defaultModel}`;let apiKey=await password({message:`${meta.label} API key:`});if(typeof apiKey==`symbol`||!apiKey.trim())return null;let keyValue=apiKey.trim();return chosen===`anthropic`?await setAnthropicApiKey(keyValue):chosen===`openrouter`?await setOpenrouterApiKey(keyValue):chosen===`gemini`?await setGeminiApiKey(keyValue):upsertSharedEnvVar({key:`OPENAI_API_KEY`,value:keyValue}),await applyLlmProviderModel(projectRoot,chosen,meta.defaultModel),`${meta.label} configured, model → ${meta.defaultModel}`}if(chosen===`ollama`){let ollamaUrl=await text({message:`Ollama base URL:`,initialValue:`http://127.0.0.1:11434`});if(typeof ollamaUrl==`symbol`)return null;let ollamaModel=await text({message:`Ollama model to use as default:`,initialValue:`llama3.3`,placeholder:`llama3.3 or qwen2.5-coder:32b or deepseek-r1:32b`});if(typeof ollamaModel==`symbol`)return null;let modelRef=`ollama/${ollamaModel.trim()||`llama3.3`}`;upsertSharedEnvVar({key:`OLLAMA_API_KEY`,value:`ollama-local`});let normalizedUrl=normalizeBaseUrl(ollamaUrl.trim());if(normalizedUrl!==`http://127.0.0.1:11434`)try{let existing=(await readConfigFileSnapshot())?.config??{};await writeConfigFile({...existing,models:{...existing.models,providers:{...existing.models?.providers,ollama:{baseUrl:normalizedUrl,api:`ollama`,apiKey:`ollama-local`,models:[]}}}})}catch{}return await applyLlmProviderModel(projectRoot,`ollama`,modelRef),`Ollama configured (${normalizedUrl}), model → ${modelRef}`}if(chosen===`vllm`){let vllmUrl=await text({message:`Server base URL (e.g. http://127.0.0.1:8000/v1):`,initialValue:`http://127.0.0.1:8000/v1`});if(typeof vllmUrl==`symbol`)return null;let vllmModelId=await text({message:`Model ID served at that endpoint:`,placeholder:`meta-llama/Llama-3.1-8B-Instruct`});if(typeof vllmModelId==`symbol`||!vllmModelId.trim())return null;let modelId=vllmModelId.trim(),modelRef=`vllm/${modelId}`;try{let existing=(await readConfigFileSnapshot())?.config??{};await writeConfigFile({...existing,models:{...existing.models,providers:{...existing.models?.providers,vllm:{baseUrl:normalizeBaseUrl(vllmUrl.trim()),api:`openai-completions`,apiKey:`VLLM_API_KEY`,models:[{id:modelId,name:modelId,reasoning:!1,input:[`text`],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:128e3,maxTokens:8192}]}}}})}catch{}return await applyLlmProviderModel(projectRoot,`vllm`,modelRef),`vLLM configured (${vllmUrl.trim()}), model → ${modelRef}`}return null}async function builderforceApiFetch(url,opts={}){let{token,...rest}=opts,headers={"Content-Type":`application/json`,...token?{Authorization:`Bearer ${token}`}:{}},res=await fetch(url,{...rest,headers}),body=await res.json().catch(()=>({}));if(!res.ok){let msg=body.error??body.message??res.statusText;throw Error(`${res.status} ${msg}`)}return body}async function ensureProjectMapping(params){try{let upsert=await builderforceApiFetch(`${params.serverUrl}/api/projects/upsert`,{method:`POST`,token:params.tenantJwt,body:JSON.stringify({name:params.projectName,description:params.description??`Managed from ${params.projectRoot}`})});return await builderforceApiFetch(`${params.serverUrl}/api/agent-hosts/${params.agentNodeId}/projects/${upsert.project.id}`,{method:`PUT`,token:params.tenantJwt}),{projectId:upsert.project.id,action:upsert.action}}catch{return null}}async function ensureProjectMappingFromStoredCreds(params){let serverUrl=readSharedEnvVar(`BUILDERFORCE_URL`)??`https://api.builderforce.ai`,webToken=readSharedEnvVar(`BUILDERFORCE_WEB_TOKEN`),tenantIdRaw=readSharedEnvVar(`BUILDERFORCE_TENANT_ID`);if(!webToken||!tenantIdRaw)return;let tenantId=Number(tenantIdRaw);if(!Number.isFinite(tenantId)||tenantId<=0)return;let ctx=await loadProjectContext(params.projectRoot).catch(()=>null),agentNodeId=ctx?.builderforce?.instanceId?.trim();if(!agentNodeId)return;let tenantJwtRes=await builderforceApiFetch(`${serverUrl}/api/auth/tenant-token`,{method:`POST`,token:webToken,body:JSON.stringify({tenantId})}).catch(()=>null);if(!tenantJwtRes?.token)return;let mapped=await ensureProjectMapping({serverUrl,tenantJwt:tenantJwtRes.token,projectRoot:params.projectRoot,projectName:params.projectName,description:params.description,agentNodeId});mapped&&await updateProjectContextFields(params.projectRoot,{builderforce:{instanceId:agentNodeId,...ctx?.builderforce,projectId:mapped.projectId}}).catch(()=>void 0)}async function promptBuilderforceSetup(projectRoot,defaultInstanceName){if(readSharedEnvVar(`BUILDERFORCE_API_KEY`)){let existingUrl=readSharedEnvVar(`BUILDERFORCE_URL`)??`https://api.builderforce.ai`,existingTenantId=readSharedEnvVar(`BUILDERFORCE_TENANT_ID`),existingCtx=await loadProjectContext(projectRoot).catch(()=>null),agentNodeLabel=existingCtx?.builderforce?.instanceSlug??existingCtx?.builderforce?.instanceName??existingCtx?.builderforce?.instanceId??`(registered)`;return note([`URL: ${existingUrl}`,`Tenant: ${existingTenantId??`unknown`}`,`AgentNode: ${agentNodeLabel}`,``,`Run 'builderforce init --reconnect' to link a different account.`].join(`
11
- `),`Already connected to Builderforce`),`Builderforce: already connected (${existingUrl})`}if(readSharedEnvVar(`BUILDERFORCE_SKIPPED`)===`1`)return null;let connect=await confirm({message:`Connect to Builderforce? (optional — manage projects, tasks & agents across your mesh)`,initialValue:!0});if(typeof connect==`symbol`||!connect)return upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`1`}),note(`You can connect to Builderforce anytime with: builderforce init --reconnect`,`Skipped`),null;let urlInput=await text({message:`Orchestration API URL (Builderforce):`,initialValue:`https://api.builderforce.ai`});if(typeof urlInput==`symbol`)return null;let serverUrl=normalizeBaseUrl(urlInput.trim())||`https://api.builderforce.ai`,authMode=await select({message:`Do you have a Builderforce account?`,options:[{value:`login`,label:`Yes — log in`},{value:`register`,label:`No — create a free account`}]});if(typeof authMode==`symbol`)return null;let emailInput=await text({message:`Email:`});if(typeof emailInput==`symbol`||!emailInput.trim())return null;let email=emailInput.trim(),usernameForReg=``;if(authMode===`register`){let unInput=await text({message:`Username:`,initialValue:defaultInstanceName.toLowerCase().replace(/[^a-z0-9]+/g,`-`)});if(typeof unInput==`symbol`||!unInput.trim())return null;usernameForReg=unInput.trim()}let pwdInput=await password({message:`Password:`});if(typeof pwdInput==`symbol`||!pwdInput.trim())return null;let pwd=pwdInput.trim(),webToken=``,authSpin=spinner();try{authMode===`register`?(authSpin.start(`Creating account…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/register`,{method:`POST`,body:JSON.stringify({email,username:usernameForReg,password:pwd})})).token,authSpin.stop(`Account created`)):(authSpin.start(`Authenticating…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/login`,{method:`POST`,body:JSON.stringify({email,password:pwd})})).token,authSpin.stop(`Authenticated`))}catch(err){return authSpin.stop(`Authentication failed`),note(String(err instanceof Error?err.message:err),`Error`),null}let tenantId=0,tenantSpin=spinner();tenantSpin.start(`Loading workspaces…`);let tenants=[];try{tenants=(await builderforceApiFetch(`${serverUrl}/api/auth/my-tenants`,{token:webToken})).tenants,tenantSpin.stop(`${tenants.length} workspace(s) found`)}catch(err){return tenantSpin.stop(`Could not load workspaces`),note(String(err instanceof Error?err.message:err),`Error`),null}if(tenants.length===0){let wsNameInput=await text({message:`Create your first workspace:`,initialValue:defaultInstanceName});if(typeof wsNameInput==`symbol`||!wsNameInput.trim())return null;let wsSpin=spinner();wsSpin.start(`Creating workspace…`);try{let created=await builderforceApiFetch(`${serverUrl}/api/tenants/create`,{method:`POST`,token:webToken,body:JSON.stringify({name:wsNameInput.trim()})});tenantId=created.id,wsSpin.stop(`Workspace "${created.name}" created`)}catch(err){return wsSpin.stop(`Could not create workspace`),note(String(err instanceof Error?err.message:err),`Error`),null}}else if(tenants.length===1)tenantId=tenants[0].id,note(`Using workspace: ${tenants[0].name}`,`Workspace`);else{let picked=await select({message:`Select workspace:`,options:tenants.map(t=>({value:t.id,label:t.name,hint:t.slug}))});if(typeof picked==`symbol`)return null;tenantId=picked}let tenantJwt=``;try{tenantJwt=(await builderforceApiFetch(`${serverUrl}/api/auth/tenant-token`,{method:`POST`,token:webToken,body:JSON.stringify({tenantId})})).token}catch(err){return note(String(err instanceof Error?err.message:err),`Could not get workspace token`),null}let agentNodeNameInput=await text({message:`AgentNode instance name (shown in dashboard):`,initialValue:defaultInstanceName});if(typeof agentNodeNameInput==`symbol`)return null;let agentNodeName=agentNodeNameInput.trim()||defaultInstanceName,agentNodeSpin=spinner();agentNodeSpin.start(`Registering agentNode instance…`);let agentNodeId=``,agentNodeSlug=``,apiKey=``,projectId=``,projectAction=`unknown`;try{let res=await builderforceApiFetch(`${serverUrl}/api/agent-hosts`,{method:`POST`,token:tenantJwt,body:JSON.stringify({name:agentNodeName})});agentNodeId=String(res.agentHost.id),agentNodeSlug=res.agentHost.slug,apiKey=res.apiKey;let mapped=await ensureProjectMapping({serverUrl,tenantJwt,agentNodeId,projectRoot,projectName:defaultInstanceName,description:`builderForceAgents project at ${projectRoot}`});mapped&&(projectId=mapped.projectId,projectAction=mapped.action),agentNodeSpin.stop(`AgentNode "${res.agentHost.name}" registered`)}catch(err){return agentNodeSpin.stop(`AgentNode registration failed`),note(String(err instanceof Error?err.message:err),`Error`),null}upsertSharedEnvVar({key:`BUILDERFORCE_URL`,value:serverUrl}),upsertSharedEnvVar({key:`BUILDERFORCE_WEB_TOKEN`,value:webToken}),upsertSharedEnvVar({key:`BUILDERFORCE_TENANT_ID`,value:String(tenantId)}),upsertSharedEnvVar({key:`BUILDERFORCE_API_KEY`,value:apiKey});try{await updateProjectContextFields(projectRoot,{builderforce:{instanceId:agentNodeId,instanceSlug:agentNodeSlug,instanceName:agentNodeName,...projectId?{projectId}:{},tenantId,url:serverUrl}})}catch{}return note([`AgentNode API key saved to ~/.builderforce/.env`,`This key was shown once — it is hashed on the server.`,`Instance slug: ${agentNodeSlug} · tenant: ${tenantId}`,projectId?`Project ${projectAction}: ${projectId}`:`Project mapping: not available`].join(`
11
+ `),`Already connected to Builderforce`),`Builderforce: already connected (${existingUrl})`}if(readSharedEnvVar(`BUILDERFORCE_SKIPPED`)===`1`)return null;let connect=await confirm({message:`Connect to Builderforce? (optional — manage projects, tasks & agents across your mesh)`,initialValue:!0});if(typeof connect==`symbol`||!connect)return upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`1`}),note(`You can connect to Builderforce anytime with: builderforce init --reconnect`,`Skipped`),null;let urlInput=await text({message:`Orchestration API URL (Builderforce):`,initialValue:`https://api.builderforce.ai`});if(typeof urlInput==`symbol`)return null;let serverUrl=normalizeBaseUrl(urlInput.trim())||`https://api.builderforce.ai`,authMode=await select({message:`Do you have a Builderforce account?`,options:[{value:`login`,label:`Yes — log in`},{value:`register`,label:`No — create a free account`}]});if(typeof authMode==`symbol`)return null;let emailInput=await text({message:`Email:`});if(typeof emailInput==`symbol`||!emailInput.trim())return null;let email=emailInput.trim(),usernameForReg=``;if(authMode===`register`){let unInput=await text({message:`Username:`,initialValue:defaultInstanceName.toLowerCase().replace(/[^a-z0-9]+/g,`-`)});if(typeof unInput==`symbol`||!unInput.trim())return null;usernameForReg=unInput.trim()}let pwdInput=await password({message:`Password:`});if(typeof pwdInput==`symbol`||!pwdInput.trim())return null;let pwd=pwdInput.trim(),webToken=``,authSpin=spinner();try{authMode===`register`?(authSpin.start(`Creating account…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/register`,{method:`POST`,body:JSON.stringify({email,username:usernameForReg,password:pwd})})).token,authSpin.stop(`Account created`)):(authSpin.start(`Authenticating…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/login`,{method:`POST`,body:JSON.stringify({email,password:pwd})})).token,authSpin.stop(`Authenticated`))}catch(err){return authSpin.stop(`Authentication failed`),note(String(err instanceof Error?err.message:err),`Error`),null}let tenantId=0,tenantSpin=spinner();tenantSpin.start(`Loading workspaces…`);let tenants=[];try{tenants=(await builderforceApiFetch(`${serverUrl}/api/tenants`,{token:webToken})).tenants,tenantSpin.stop(`${tenants.length} workspace(s) found`)}catch(err){return tenantSpin.stop(`Could not load workspaces`),note(String(err instanceof Error?err.message:err),`Error`),null}if(tenants.length===0){let wsNameInput=await text({message:`Create your first workspace:`,initialValue:defaultInstanceName});if(typeof wsNameInput==`symbol`||!wsNameInput.trim())return null;let wsSpin=spinner();wsSpin.start(`Creating workspace…`);try{let created=await builderforceApiFetch(`${serverUrl}/api/tenants`,{method:`POST`,token:webToken,body:JSON.stringify({name:wsNameInput.trim()})});tenantId=created.id,wsSpin.stop(`Workspace "${created.name}" created`)}catch(err){return wsSpin.stop(`Could not create workspace`),note(String(err instanceof Error?err.message:err),`Error`),null}}else if(tenants.length===1)tenantId=tenants[0].id,note(`Using workspace: ${tenants[0].name}`,`Workspace`);else{let picked=await select({message:`Select workspace:`,options:tenants.map(t=>({value:t.id,label:t.name,hint:t.slug}))});if(typeof picked==`symbol`)return null;tenantId=picked}let tenantJwt=``;try{tenantJwt=(await builderforceApiFetch(`${serverUrl}/api/auth/tenant-token`,{method:`POST`,token:webToken,body:JSON.stringify({tenantId})})).token}catch(err){return note(String(err instanceof Error?err.message:err),`Could not get workspace token`),null}let agentNodeNameInput=await text({message:`AgentNode instance name (shown in dashboard):`,initialValue:defaultInstanceName});if(typeof agentNodeNameInput==`symbol`)return null;let agentNodeName=agentNodeNameInput.trim()||defaultInstanceName,agentNodeSpin=spinner();agentNodeSpin.start(`Registering agentNode instance…`);let agentNodeId=``,agentNodeSlug=``,apiKey=``,projectId=``,projectAction=`unknown`;try{let res=await builderforceApiFetch(`${serverUrl}/api/agent-hosts`,{method:`POST`,token:tenantJwt,body:JSON.stringify({name:agentNodeName})});agentNodeId=String(res.agentHost.id),agentNodeSlug=res.agentHost.slug,apiKey=res.apiKey;let mapped=await ensureProjectMapping({serverUrl,tenantJwt,agentNodeId,projectRoot,projectName:defaultInstanceName,description:`builderForceAgents project at ${projectRoot}`});mapped&&(projectId=mapped.projectId,projectAction=mapped.action),agentNodeSpin.stop(`AgentNode "${res.agentHost.name}" registered`)}catch(err){return agentNodeSpin.stop(`AgentNode registration failed`),note(String(err instanceof Error?err.message:err),`Error`),null}upsertSharedEnvVar({key:`BUILDERFORCE_URL`,value:serverUrl}),upsertSharedEnvVar({key:`BUILDERFORCE_WEB_TOKEN`,value:webToken}),upsertSharedEnvVar({key:`BUILDERFORCE_TENANT_ID`,value:String(tenantId)}),upsertSharedEnvVar({key:`BUILDERFORCE_API_KEY`,value:apiKey});try{await updateProjectContextFields(projectRoot,{builderforce:{instanceId:agentNodeId,instanceSlug:agentNodeSlug,instanceName:agentNodeName,...projectId?{projectId}:{},tenantId,url:serverUrl}})}catch{}return note([`AgentNode API key saved to ~/.builderforce/.env`,`This key was shown once — it is hashed on the server.`,`Instance slug: ${agentNodeSlug} · tenant: ${tenantId}`,projectId?`Project ${projectAction}: ${projectId}`:`Project mapping: not available`].join(`
12
12
  `),`Builderforce connected`),`Builderforce: ${agentNodeName} (${agentNodeSlug}) on tenant ${tenantId}`}function createBuilderForceAgentsCommand(){let cmd=new Command(`project`);return cmd.description(`Manage builderForceAgents project context`).addCommand(createStatusCommand()),cmd}function createInitCommand(){return new Command(`init`).description(`Initialize a project with builderForceAgents`).argument(`[path]`,`Project directory path`,`.`).action(async projectPath=>{let projectRoot=projectPath===`.`?process.cwd():projectPath;if(await isBuilderForceAgentsProject(projectRoot)){await runBuilderForceAgentsSession(projectRoot);return}intro(theme.accent(`builderForceAgents`));let detectSpin=spinner();detectSpin.start(`Detecting project info...`);let detected=await detectProjectInfo(projectRoot);detectSpin.stop(`Project info detected`),note([`name: ${detected.projectName}`,`languages: ${detected.languages.join(`, `)||`(none detected)`}`,`frameworks: ${detected.frameworks.join(`, `)||`(none detected)`}`,`build: ${detected.buildSystem??`(unknown)`}`,`test: ${detected.testFramework??`(unknown)`}`,`lint: ${detected.lintingTools.join(`, `)||`(none detected)`}`].join(`
13
13
  `),`Auto-detected`);let projectNameInput=await text({message:`Project name:`,initialValue:detected.projectName});if(typeof projectNameInput==`symbol`){outro(theme.muted(`Cancelled`));return}let descriptionInput=await text({message:`Project description:`,initialValue:detected.description,placeholder:`A brief description of what this project does`});if(typeof descriptionInput==`symbol`){outro(theme.muted(`Cancelled`));return}let languagesInput=await text({message:`Primary languages (comma-separated):`,initialValue:detected.languages.join(`, `),placeholder:`typescript, javascript`});if(typeof languagesInput==`symbol`){outro(theme.muted(`Cancelled`));return}let frameworksInput=await text({message:`Frameworks used (comma-separated):`,initialValue:detected.frameworks.join(`, `),placeholder:`express, react`});if(typeof frameworksInput==`symbol`){outro(theme.muted(`Cancelled`));return}let spin=spinner();spin.start(`Setting up .builderforce/...`);try{await initializeBuilderForceAgentsProject(projectRoot,{projectName:projectNameInput||detected.projectName,description:descriptionInput||detected.description,languages:languagesInput.trim().length>0?languagesInput.split(`,`).map(l=>l.trim()).filter(Boolean):detected.languages,frameworks:frameworksInput.trim().length>0?frameworksInput.split(`,`).map(f=>f.trim()).filter(Boolean):detected.frameworks,buildSystem:detected.buildSystem,testFramework:detected.testFramework,lintingTools:detected.lintingTools}),spin.stop(theme.success(`builderForceAgents initialized!`)),note([` ${theme.muted(`context.yaml`)} – project metadata (edit to tune AI understanding)`,` ${theme.muted(`architecture.md`)} – high-level design docs`,` ${theme.muted(`rules.yaml`)} – coding standards & conventions`].join(`
14
14
  `),`.builderforce/ created`),await promptLlmProvider(projectRoot),await promptBuilderforceSetup(projectRoot,projectNameInput||detected.projectName),await ensureProjectMappingFromStoredCreds({projectRoot,projectName:projectNameInput||detected.projectName,description:descriptionInput||detected.description});let aiPopulate=await confirm({message:`Use an AI agent to populate context.yaml, architecture.md, and rules.yaml now?`,initialValue:!0});await runBuilderForceAgentsSession(projectRoot,{message:typeof aiPopulate!=`symbol`&&aiPopulate?`Analyze this project and populate .builderforce/context.yaml, architecture.md, and rules.yaml with accurate project context`:void 0})}catch(error){spin.stop(theme.error(`Failed to initialize project`)),outro(theme.error(error instanceof Error?error.message:String(error)))}})}function createStatusCommand(){return new Command(`status`).description(`Show builderForceAgents project status and context`).argument(`[path]`,`Project directory path`,`.`).action(async projectPath=>{let projectRoot=projectPath===`.`?process.cwd():projectPath;if(!await isBuilderForceAgentsProject(projectRoot)){console.log(theme.warn(`Project is not initialized with builderForceAgents`)),console.log(theme.muted(`Run 'builderforce init' to initialize`));return}console.log(theme.success(`✓ builderForceAgents project detected`)),console.log(theme.muted(` Location: ${projectRoot}/.builderforce/`))})}function createAgentCommand(){let cmd=new Command(`workforce`).description(`Manage Builderforce Workforce agents (custom trained LLMs)`);return cmd.addCommand(new Command(`install`).description(`Install a Workforce agent from the Builderforce registry`).argument(`<agentId>`,`Agent UUID or name from the Workforce Registry`).option(`--registry <url>`,`Builderforce registry URL`,DEFAULT_REGISTRY_URL).option(`--path <dir>`,`Project directory`,`.`).action(async(agentId,opts)=>{let projectRoot=opts.path===`.`?process.cwd():opts.path;intro(theme.accent(`builderForceAgents`)+` `+theme.muted(`agent install`));try{let summary=await installWorkforceAgent({agentId,projectRoot,registryUrl:opts.registry});outro(theme.success(`Agent installed!
@@ -1,4 +1,4 @@
1
- import"./paths-5FcIFMsj.js";import{B as theme}from"./utils-DbaBVFaK.js";import"./embedded-helpers-CEsr3aQ0.js";import"./session-key-EoB0qaG9.js";import"./builderforce-root-D64_sXEi.js";import"./subsystem-B3TqcCrZ.js";import"./registry-TdK-aV05.js";import"./logger-Bch0bx9c.js";import"./exec-DdcIjeyn.js";import"./agent-scope-DPtjOxzp.js";import"./src-CA0fU67C.js";import"./model-selection-9bRFKBI_.js";import{t as normalizeBaseUrl}from"./normalize-base-url-DmugqkQ6.js";import{a as upsertSharedEnvVar,i as readSharedEnvVar}from"./env-file-D1MDi-AM.js";import"./boolean-Cnh1KNl1.js";import"./env-BIdU5BAp.js";import"./src-DTFqOIQD.js";import{U as VERSION,a as readConfigFileSnapshot,c as writeConfigFile}from"./io-3R_ZyUxB.js";import"./manifest-registry-BJCfNV1a.js";import"./config-_1Ca6jGb.js";import"./model-catalog-C6UrZ0uG.js";import"./sandbox-BZibn6PX.js";import"./chrome-a3X9_-nf.js";import"./tailscale-DLkpGquM.js";import"./auth-lebUHrkd.js";import"./server-context-DJZT7Upf.js";import"./frontmatter-3D1EdC1L.js";import"./skills-Ba4ftrB-.js";import"./plugin-skills-B11rggZh.js";import"./routes-BzfLvF8W.js";import"./redact-BHdfp2MZ.js";import"./errors-B1MIg3g-.js";import"./paths-cR8ct-Y3.js";import"./ssrf-p9k-iapc.js";import"./image-ops-C8IUQKjn.js";import"./store-CmHBQ-yX.js";import"./ports-DgmEDNOm.js";import"./trash-DD2Hc5oq.js";import"./sessions-CdanN_ZI.js";import"./message-channel-D_jXxXQj.js";import"./plugins-D5zP6ENo.js";import"./accounts-o35LU_iy.js";import"./accounts-rmXEiebi.js";import"./accounts-BLueHgKj.js";import"./bindings-DR59065T.js";import"./paths-DJ6rztqJ.js";import"./tool-images-B7b_OiMz.js";import"./tool-display-ByOZtWvA.js";import{n as fetchWithTimeout}from"./fetch-timeout-BIqoSVfA.js";import{_ as isBuilderForceAgentsProject,n as loadProjectContext,o as updateProjectContextFields}from"./project-context-store-wcq7lXuI.js";import"./client-xfoidwPI.js";import"./call-BbRf8gFM.js";import"./builderforcellm-syscheck-DrFJ638L.js";import"./usage-format-DGf8ZWPH.js";import{f as initializeBuilderForceAgentsProject}from"./project-context-CJj0Inz-.js";import{r as saveMambaState}from"./mamba-state-engine-CoGqoBTH.js";import"./transformers-stream-D7nRu4Qu.js";import"./builderforce-directory-sync-DAH62b3b.js";import"./shared-BPN3qd7G.js";import{_ as setOpenrouterApiKey,c as setAnthropicApiKey,u as setGeminiApiKey}from"./onboard-auth.credentials-BuT-etnE.js";import"./model-picker-BUePD7Zg.js";import"./auth-choice.apply.transformers-CIn3fs7K.js";import{t as runTui}from"./tui-DHjIJOFN.js";import"./tui-stream-assembler-ign_cPkv.js";import path from"node:path";import fs from"node:fs/promises";import{confirm,intro,note,outro,password,select,spinner,text}from"@clack/prompts";import{Command}from"commander";const DEFAULT_REGISTRY_URL=`https://api.builderforce.ai`;function resolveRegistryUrl(){return normalizeBaseUrl(readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_URL`)??DEFAULT_REGISTRY_URL)}function resolveAuthHeaders(){let apiKey=readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_API_KEY`);return apiKey?{Authorization:`Bearer ${apiKey}`}:{}}function isV2Package(pkg){return pkg.version===`2.0`}async function fetchAgentPackage(params){let url=`${normalizeBaseUrl(params.registryUrl??resolveRegistryUrl())}/api/agents/${encodeURIComponent(params.agentId)}/package`,res;try{res=await fetchWithTimeout(url,{method:`GET`,headers:{Accept:`application/json`,...resolveAuthHeaders()}},3e4)}catch(err){let msg=err instanceof Error?err.message:String(err);throw Error(`Network error fetching agent package: ${msg}`,{cause:err})}if(!res.ok){let text=await res.text().catch(()=>``);throw Error(`Registry returned ${res.status} ${res.statusText}${text?`: ${text}`:``}`)}let pkg=await res.json();if(!pkg.version||!pkg.platform||!pkg.name||!pkg.base_model)throw Error(`Invalid agent package: missing required fields (version, platform, name, base_model)`);return pkg}function resolveWorkforceModelRef(params){return readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_API_KEY`)?`builderforcellm/workforce-${params.agentId}`:params.pkg.base_model}async function installWorkforceAgent(params){let registryUrl=params.registryUrl??resolveRegistryUrl(),spin=spinner();spin.start(`Fetching agent package for "${params.agentId}" from ${registryUrl}…`);let pkg;try{pkg=await fetchAgentPackage({agentId:params.agentId,registryUrl}),spin.stop(`Package downloaded: ${pkg.name} (v${pkg.version})`)}catch(err){throw spin.stop(`Failed to download agent package`),err}let modelRef=resolveWorkforceModelRef({agentId:params.agentId,pkg}),hasMambaState=isV2Package(pkg)&&!!pkg.mamba_state,installed={agentId:params.agentId,name:pkg.name,title:pkg.title,baseModel:pkg.base_model,modelRef,loraArtifactKey:pkg.r2_artifact_key,packageVersion:pkg.version,hasMambaState,installedAt:new Date().toISOString(),registryUrl};return await updateProjectContextFields(params.projectRoot,{customAgent:installed,llm:{provider:`builderforcellm`,model:modelRef}}),hasMambaState&&isV2Package(pkg)&&pkg.mamba_state&&await saveMambaState(params.projectRoot,pkg.mamba_state),[`Workforce agent installed: ${pkg.name} (${params.agentId})`,` Base model: ${pkg.base_model}`,` Package: v${pkg.version}`,` Mamba state: ${hasMambaState?`yes (persistent memory)`:`no`}`,` Model ref: ${modelRef}`].join(`
1
+ import"./paths-5FcIFMsj.js";import{B as theme}from"./utils-DbaBVFaK.js";import"./embedded-helpers-CEsr3aQ0.js";import"./session-key-EoB0qaG9.js";import"./builderforce-root-D64_sXEi.js";import"./subsystem-B3TqcCrZ.js";import"./registry-TdK-aV05.js";import"./logger-Bch0bx9c.js";import"./exec-DdcIjeyn.js";import"./agent-scope-DPtjOxzp.js";import"./src-CA0fU67C.js";import"./model-selection-9bRFKBI_.js";import{t as normalizeBaseUrl}from"./normalize-base-url-DmugqkQ6.js";import{a as upsertSharedEnvVar,i as readSharedEnvVar}from"./env-file-D1MDi-AM.js";import"./boolean-Cnh1KNl1.js";import"./env-BIdU5BAp.js";import"./src-DTFqOIQD.js";import{U as VERSION,a as readConfigFileSnapshot,c as writeConfigFile}from"./io-3R_ZyUxB.js";import"./manifest-registry-BJCfNV1a.js";import"./config-_1Ca6jGb.js";import"./model-catalog-C6UrZ0uG.js";import"./sandbox-BZibn6PX.js";import"./chrome-a3X9_-nf.js";import"./tailscale-DLkpGquM.js";import"./auth-lebUHrkd.js";import"./server-context-DJZT7Upf.js";import"./frontmatter-3D1EdC1L.js";import"./skills-Ba4ftrB-.js";import"./plugin-skills-B11rggZh.js";import"./routes-BzfLvF8W.js";import"./redact-BHdfp2MZ.js";import"./errors-B1MIg3g-.js";import"./paths-cR8ct-Y3.js";import"./ssrf-p9k-iapc.js";import"./image-ops-C8IUQKjn.js";import"./store-CmHBQ-yX.js";import"./ports-DgmEDNOm.js";import"./trash-DD2Hc5oq.js";import"./sessions-CdanN_ZI.js";import"./message-channel-D_jXxXQj.js";import"./plugins-D5zP6ENo.js";import"./accounts-o35LU_iy.js";import"./accounts-rmXEiebi.js";import"./accounts-BLueHgKj.js";import"./bindings-DR59065T.js";import"./paths-DJ6rztqJ.js";import"./tool-images-B7b_OiMz.js";import"./tool-display-ByOZtWvA.js";import{n as fetchWithTimeout}from"./fetch-timeout-BIqoSVfA.js";import{_ as isBuilderForceAgentsProject,n as loadProjectContext,o as updateProjectContextFields}from"./project-context-store-wcq7lXuI.js";import"./client-xfoidwPI.js";import"./call-BbRf8gFM.js";import"./builderforcellm-syscheck-DrFJ638L.js";import"./usage-format-DGf8ZWPH.js";import{f as initializeBuilderForceAgentsProject}from"./project-context-CJj0Inz-.js";import{r as saveMambaState}from"./mamba-state-engine-CoGqoBTH.js";import"./transformers-stream-D7nRu4Qu.js";import"./builderforce-directory-sync-DAH62b3b.js";import"./shared-BPN3qd7G.js";import{_ as setOpenrouterApiKey,c as setAnthropicApiKey,u as setGeminiApiKey}from"./onboard-auth.credentials-BuT-etnE.js";import"./model-picker-BUePD7Zg.js";import"./auth-choice.apply.transformers-CIn3fs7K.js";import{t as runTui}from"./tui-D2sTsa4p.js";import"./tui-stream-assembler-ign_cPkv.js";import path from"node:path";import fs from"node:fs/promises";import{confirm,intro,note,outro,password,select,spinner,text}from"@clack/prompts";import{Command}from"commander";const DEFAULT_REGISTRY_URL=`https://api.builderforce.ai`;function resolveRegistryUrl(){return normalizeBaseUrl(readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_URL`)??DEFAULT_REGISTRY_URL)}function resolveAuthHeaders(){let apiKey=readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_API_KEY`);return apiKey?{Authorization:`Bearer ${apiKey}`}:{}}function isV2Package(pkg){return pkg.version===`2.0`}async function fetchAgentPackage(params){let url=`${normalizeBaseUrl(params.registryUrl??resolveRegistryUrl())}/api/agents/${encodeURIComponent(params.agentId)}/package`,res;try{res=await fetchWithTimeout(url,{method:`GET`,headers:{Accept:`application/json`,...resolveAuthHeaders()}},3e4)}catch(err){let msg=err instanceof Error?err.message:String(err);throw Error(`Network error fetching agent package: ${msg}`,{cause:err})}if(!res.ok){let text=await res.text().catch(()=>``);throw Error(`Registry returned ${res.status} ${res.statusText}${text?`: ${text}`:``}`)}let pkg=await res.json();if(!pkg.version||!pkg.platform||!pkg.name||!pkg.base_model)throw Error(`Invalid agent package: missing required fields (version, platform, name, base_model)`);return pkg}function resolveWorkforceModelRef(params){return readSharedEnvVar(`BUILDERFORCE_AGENTS_LINK_API_KEY`)?`builderforcellm/workforce-${params.agentId}`:params.pkg.base_model}async function installWorkforceAgent(params){let registryUrl=params.registryUrl??resolveRegistryUrl(),spin=spinner();spin.start(`Fetching agent package for "${params.agentId}" from ${registryUrl}…`);let pkg;try{pkg=await fetchAgentPackage({agentId:params.agentId,registryUrl}),spin.stop(`Package downloaded: ${pkg.name} (v${pkg.version})`)}catch(err){throw spin.stop(`Failed to download agent package`),err}let modelRef=resolveWorkforceModelRef({agentId:params.agentId,pkg}),hasMambaState=isV2Package(pkg)&&!!pkg.mamba_state,installed={agentId:params.agentId,name:pkg.name,title:pkg.title,baseModel:pkg.base_model,modelRef,loraArtifactKey:pkg.r2_artifact_key,packageVersion:pkg.version,hasMambaState,installedAt:new Date().toISOString(),registryUrl};return await updateProjectContextFields(params.projectRoot,{customAgent:installed,llm:{provider:`builderforcellm`,model:modelRef}}),hasMambaState&&isV2Package(pkg)&&pkg.mamba_state&&await saveMambaState(params.projectRoot,pkg.mamba_state),[`Workforce agent installed: ${pkg.name} (${params.agentId})`,` Base model: ${pkg.base_model}`,` Package: v${pkg.version}`,` Mamba state: ${hasMambaState?`yes (persistent memory)`:`no`}`,` Model ref: ${modelRef}`].join(`
2
2
  `)}async function showWorkforceAgentInfo(projectRoot){let ctx=await loadProjectContext(projectRoot);if(!ctx?.customAgent){note(`No Workforce agent is installed in this project.
3
3
 
4
4
  Run: builderforce agent install <agentId>`,`No agent installed`);return}let a=ctx.customAgent;note([theme.heading(`Workforce Agent`),` ID: ${a.agentId}`,` Name: ${a.name}${a.title?` — ${a.title}`:``}`,` Base model: ${a.baseModel}`,` Model ref: ${a.modelRef}`,` Package: v${a.packageVersion}`,` Mamba state: ${a.hasMambaState?`yes (persistent memory)`:`no`}`,` Installed: ${a.installedAt}`,` Registry: ${a.registryUrl}`].join(`
@@ -6,9 +6,9 @@ Run: builderforce agent install <agentId>`,`No agent installed`);return}let a=ct
6
6
  `)+`
7
7
 
8
8
  `),await runTui({message:opts.message})}async function readJsonFile(filePath){try{let content=await fs.readFile(filePath,`utf-8`);return JSON.parse(content)}catch{return null}}async function fileExists(filePath){try{return await fs.access(filePath),!0}catch{return!1}}async function detectLanguagesFromFiles(projectRoot){let extLangMap={".ts":`typescript`,".tsx":`typescript`,".js":`javascript`,".jsx":`javascript`,".mjs":`javascript`,".cjs":`javascript`,".py":`python`,".go":`go`,".rs":`rust`,".java":`java`,".kt":`kotlin`,".swift":`swift`,".rb":`ruby`,".php":`php`,".cs":`csharp`,".cpp":`cpp`,".c":`c`,".dart":`dart`,".ex":`elixir`,".exs":`elixir`,".hs":`haskell`},counts={},ignoreDirs=new Set([`node_modules`,`.git`,`dist`,`build`,`.builderForceAgents`,`__pycache__`,`.next`,`out`,`coverage`,`vendor`]);async function walk(dir,depth){if(depth>3)return;let entries;try{entries=await fs.readdir(dir,{withFileTypes:!0})}catch{return}for(let entry of entries)if(entry.isDirectory())!ignoreDirs.has(entry.name)&&!entry.name.startsWith(`.`)&&await walk(path.join(dir,entry.name),depth+1);else{let lang=extLangMap[path.extname(entry.name).toLowerCase()];lang&&(counts[lang]=(counts[lang]??0)+1)}}return await walk(projectRoot,0),Object.entries(counts).toSorted((a,b)=>b[1]-a[1]).map(([lang])=>lang)}async function detectFrameworks(projectRoot,pkgDeps){let found=[],all=Object.keys(pkgDeps);for(let[match,label]of[[`next`,`next.js`],[`nuxt`,`nuxt`],[/^@remix-run/,`remix`],[`astro`,`astro`],[`@sveltejs/kit`,`sveltekit`],[`svelte`,`svelte`],[`react`,`react`],[`vue`,`@vue`],[`angular`,`angular`],[`express`,`express`],[`fastify`,`fastify`],[`hono`,`hono`],[`koa`,`koa`],[`nest`,`nestjs`],[/^@nestjs/,`nestjs`],[`trpc`,`trpc`],[/^@trpc/,`trpc`],[`drizzle-orm`,`drizzle`],[`prisma`,`prisma`],[/^@prisma/,`prisma`],[`mongoose`,`mongoose`],[`typeorm`,`typeorm`],[`django`,`django`],[`flask`,`flask`],[`fastapi`,`fastapi`],[`tailwindcss`,`tailwind`]])found.includes(label)||(typeof match==`string`?all.some(k=>k===match||k.startsWith(`${match}/`)||k.startsWith(`@${match}/`))&&found.push(label):all.some(k=>match.test(k))&&found.push(label));for(let[file,label]of[[`next.config.js`,`next.js`],[`next.config.ts`,`next.js`],[`nuxt.config.ts`,`nuxt`],[`astro.config.mjs`,`astro`],[`astro.config.ts`,`astro`],[`svelte.config.js`,`sveltekit`],[`vite.config.ts`,`vite`],[`vite.config.js`,`vite`],[`angular.json`,`angular`],[`remix.config.js`,`remix`],[`tailwind.config.ts`,`tailwind`],[`tailwind.config.js`,`tailwind`]])!found.includes(label)&&await fileExists(path.join(projectRoot,file))&&found.push(label);return[...new Set(found)]}async function detectTestFramework(projectRoot,pkgDeps){let all=Object.keys(pkgDeps);if(all.includes(`vitest`))return`vitest`;if(all.includes(`jest`)||all.some(k=>k.startsWith(`@jest/`)))return`jest`;if(all.includes(`mocha`))return`mocha`;if(all.includes(`jasmine`))return`jasmine`;if(all.includes(`ava`))return`ava`;if(all.includes(`pytest`)||await fileExists(path.join(projectRoot,`pytest.ini`)))return`pytest`;if(await fileExists(path.join(projectRoot,`vitest.config.ts`)))return`vitest`;if(await fileExists(path.join(projectRoot,`jest.config.js`))||await fileExists(path.join(projectRoot,`jest.config.ts`)))return`jest`}async function detectLintingTools(projectRoot,pkgDeps){let tools=[],all=Object.keys(pkgDeps);return(all.includes(`eslint`)||await fileExists(path.join(projectRoot,`.eslintrc.js`)))&&tools.push(`eslint`),all.includes(`oxlint`)&&tools.push(`oxlint`),(all.includes(`prettier`)||await fileExists(path.join(projectRoot,`.prettierrc`)))&&tools.push(`prettier`),all.includes(`biome`)&&tools.push(`biome`),(all.includes(`ruff`)||await fileExists(path.join(projectRoot,`ruff.toml`)))&&tools.push(`ruff`),all.includes(`pylint`)&&tools.push(`pylint`),tools}async function detectBuildSystem(projectRoot,pkgDeps){let all=Object.keys(pkgDeps);if(all.includes(`turbo`))return`turborepo`;if(all.includes(`nx`))return`nx`;if(all.includes(`tsdown`)||all.includes(`tsup`))return all.includes(`tsdown`)?`tsdown`:`tsup`;if(all.includes(`vite`))return`vite`;if(all.includes(`webpack`))return`webpack`;if(all.includes(`rollup`))return`rollup`;if(all.includes(`esbuild`))return`esbuild`;if(await fileExists(path.join(projectRoot,`Makefile`)))return`make`;if(await fileExists(path.join(projectRoot,`CMakeLists.txt`)))return`cmake`;if(await fileExists(path.join(projectRoot,`Cargo.toml`)))return`cargo`;if(await fileExists(path.join(projectRoot,`pyproject.toml`)))return`poetry`;if(await fileExists(path.join(projectRoot,`setup.py`)))return`setuptools`;if(await fileExists(path.join(projectRoot,`pnpm-lock.yaml`)))return`pnpm`;if(await fileExists(path.join(projectRoot,`yarn.lock`)))return`yarn`;if(await fileExists(path.join(projectRoot,`package-lock.json`)))return`npm`}async function detectProjectInfo(projectRoot){let pkg=await readJsonFile(path.join(projectRoot,`package.json`)),pkgName=typeof pkg?.name==`string`?pkg.name:``,pkgDesc=typeof pkg?.description==`string`?pkg.description:``,allDeps={...pkg?.dependencies,...pkg?.devDependencies,...pkg?.peerDependencies},[langsByFile,frameworks,testFramework,lintingTools,buildSystem]=await Promise.all([detectLanguagesFromFiles(projectRoot),detectFrameworks(projectRoot,allDeps),detectTestFramework(projectRoot,allDeps),detectLintingTools(projectRoot,allDeps),detectBuildSystem(projectRoot,allDeps)]),languages=await fileExists(path.join(projectRoot,`tsconfig.json`))?[`typescript`,...langsByFile.filter(l=>l!==`typescript`)]:langsByFile;return{projectName:pkgName||path.basename(projectRoot),description:pkgDesc,languages:[...new Set(languages)].slice(0,6),frameworks,buildSystem,testFramework,lintingTools}}const PROVIDERS=[{id:`builderforcellm`,label:`BuilderForceAgentsLLM (recommended) — Builderforce.AI`,defaultModel:`builderforcellm/auto`},{id:`anthropic`,label:`Anthropic (Claude)`,envVar:`ANTHROPIC_API_KEY`,defaultModel:`anthropic/claude-sonnet-4-6`},{id:`openai`,label:`OpenAI (GPT-4o)`,envVar:`OPENAI_API_KEY`,defaultModel:`openai/gpt-4o`},{id:`openrouter`,label:`OpenRouter`,envVar:`OPENROUTER_API_KEY`,defaultModel:`openrouter/auto`},{id:`gemini`,label:`Google Gemini`,envVar:`GEMINI_API_KEY`,defaultModel:`google/gemini-2.0-flash`},{id:`ollama`,label:`Ollama (local)`,envVar:`OLLAMA_API_KEY`,defaultModel:`ollama/llama3.3`},{id:`vllm`,label:`vLLM / llama.cpp / LiteLLM (local)`,defaultModel:`vllm/your-model-id`},{id:`workforce`,label:`Builderforce Workforce Agent (custom trained LLM)`,defaultModel:`builderforcellm/auto`}];function isProviderConfigured(p){if(!p.envVar)return!1;let val=process.env[p.envVar];return typeof val==`string`&&val.trim().length>0}async function applyLlmProviderModel(projectRoot,provider,modelRef){try{await updateProjectContextFields(projectRoot,{llm:{provider,model:modelRef}})}catch{}}async function promptWorkforceAgentProvider(projectRoot){let registryUrl=await text({message:`Builderforce registry URL:`,initialValue:DEFAULT_REGISTRY_URL});if(typeof registryUrl==`symbol`)return null;let agentIdInput=await text({message:`Workforce agent ID (from the Builderforce registry):`,placeholder:`e.g. 550e8400-e29b-41d4-a716-446655440000`});if(typeof agentIdInput==`symbol`||!agentIdInput.trim())return null;let agentId=agentIdInput.trim();try{return await installWorkforceAgent({agentId,projectRoot,registryUrl:normalizeBaseUrl(registryUrl.trim())||DEFAULT_REGISTRY_URL})}catch(err){return note([err instanceof Error?err.message:String(err),``,`You can retry later with: builderforce agent install <agentId>`].join(`
9
- `),`Failed to install Workforce agent`),null}}async function promptLlmProvider(projectRoot){let chosen=await select({message:`LLM provider to use for AI agents:`,options:[...PROVIDERS.map(p=>({value:p.id,label:isProviderConfigured(p)?`${p.label} ✓ configured`:p.label,hint:p.id===`builderforcellm`?`managed proxy (no local API key needed)`:isProviderConfigured(p)?`${p.envVar} is set`:p.envVar?`needs ${p.envVar}`:`enter server URL`})),{value:`skip`,label:`Skip — configure later`}]});if(typeof chosen==`symbol`||chosen===`skip`)return null;if(chosen===`workforce`)return promptWorkforceAgentProvider(projectRoot);let meta=PROVIDERS.find(p=>p.id===chosen);if(chosen===`builderforcellm`||chosen===`anthropic`||chosen===`openai`||chosen===`openrouter`||chosen===`gemini`){if(chosen===`builderforcellm`){if(!readSharedEnvVar(`BUILDERFORCE_API_KEY`)?.trim()){let{promptBuilderforceOnboarding}=await import(`./builderforce-onboarding-DuUfZ6oL.js`);await promptBuilderforceOnboarding({projectRoot,defaultInstanceName:path.basename(projectRoot)||`builderforce`,forcePrompt:!0}),readSharedEnvVar(`BUILDERFORCE_API_KEY`)?.trim()||note([`BuilderForceAgentsLLM requires a Builderforce account to work.`,`You can connect later with: builderforce init --reconnect`,`Or switch to a different provider with: builderforce init`].join(`
9
+ `),`Failed to install Workforce agent`),null}}async function promptLlmProvider(projectRoot){let chosen=await select({message:`LLM provider to use for AI agents:`,options:[...PROVIDERS.map(p=>({value:p.id,label:isProviderConfigured(p)?`${p.label} ✓ configured`:p.label,hint:p.id===`builderforcellm`?`managed proxy (no local API key needed)`:isProviderConfigured(p)?`${p.envVar} is set`:p.envVar?`needs ${p.envVar}`:`enter server URL`})),{value:`skip`,label:`Skip — configure later`}]});if(typeof chosen==`symbol`||chosen===`skip`)return null;if(chosen===`workforce`)return promptWorkforceAgentProvider(projectRoot);let meta=PROVIDERS.find(p=>p.id===chosen);if(chosen===`builderforcellm`||chosen===`anthropic`||chosen===`openai`||chosen===`openrouter`||chosen===`gemini`){if(chosen===`builderforcellm`){if(!readSharedEnvVar(`BUILDERFORCE_API_KEY`)?.trim()){let{promptBuilderforceOnboarding}=await import(`./builderforce-onboarding-C89jVb-9.js`);await promptBuilderforceOnboarding({projectRoot,defaultInstanceName:path.basename(projectRoot)||`builderforce`,forcePrompt:!0}),readSharedEnvVar(`BUILDERFORCE_API_KEY`)?.trim()||note([`BuilderForceAgentsLLM requires a Builderforce account to work.`,`You can connect later with: builderforce init --reconnect`,`Or switch to a different provider with: builderforce init`].join(`
10
10
  `),`Skipped — BuilderForceAgentsLLM won't be available yet`)}return await applyLlmProviderModel(projectRoot,chosen,meta.defaultModel),`${meta.label} configured, model → ${meta.defaultModel}`}if(isProviderConfigured(meta))return note(`${meta.envVar} is already set — keeping existing credential.`,meta.label),await applyLlmProviderModel(projectRoot,chosen,meta.defaultModel),`${meta.label} (existing credential kept), model → ${meta.defaultModel}`;let apiKey=await password({message:`${meta.label} API key:`});if(typeof apiKey==`symbol`||!apiKey.trim())return null;let keyValue=apiKey.trim();return chosen===`anthropic`?await setAnthropicApiKey(keyValue):chosen===`openrouter`?await setOpenrouterApiKey(keyValue):chosen===`gemini`?await setGeminiApiKey(keyValue):upsertSharedEnvVar({key:`OPENAI_API_KEY`,value:keyValue}),await applyLlmProviderModel(projectRoot,chosen,meta.defaultModel),`${meta.label} configured, model → ${meta.defaultModel}`}if(chosen===`ollama`){let ollamaUrl=await text({message:`Ollama base URL:`,initialValue:`http://127.0.0.1:11434`});if(typeof ollamaUrl==`symbol`)return null;let ollamaModel=await text({message:`Ollama model to use as default:`,initialValue:`llama3.3`,placeholder:`llama3.3 or qwen2.5-coder:32b or deepseek-r1:32b`});if(typeof ollamaModel==`symbol`)return null;let modelRef=`ollama/${ollamaModel.trim()||`llama3.3`}`;upsertSharedEnvVar({key:`OLLAMA_API_KEY`,value:`ollama-local`});let normalizedUrl=normalizeBaseUrl(ollamaUrl.trim());if(normalizedUrl!==`http://127.0.0.1:11434`)try{let existing=(await readConfigFileSnapshot())?.config??{};await writeConfigFile({...existing,models:{...existing.models,providers:{...existing.models?.providers,ollama:{baseUrl:normalizedUrl,api:`ollama`,apiKey:`ollama-local`,models:[]}}}})}catch{}return await applyLlmProviderModel(projectRoot,`ollama`,modelRef),`Ollama configured (${normalizedUrl}), model → ${modelRef}`}if(chosen===`vllm`){let vllmUrl=await text({message:`Server base URL (e.g. http://127.0.0.1:8000/v1):`,initialValue:`http://127.0.0.1:8000/v1`});if(typeof vllmUrl==`symbol`)return null;let vllmModelId=await text({message:`Model ID served at that endpoint:`,placeholder:`meta-llama/Llama-3.1-8B-Instruct`});if(typeof vllmModelId==`symbol`||!vllmModelId.trim())return null;let modelId=vllmModelId.trim(),modelRef=`vllm/${modelId}`;try{let existing=(await readConfigFileSnapshot())?.config??{};await writeConfigFile({...existing,models:{...existing.models,providers:{...existing.models?.providers,vllm:{baseUrl:normalizeBaseUrl(vllmUrl.trim()),api:`openai-completions`,apiKey:`VLLM_API_KEY`,models:[{id:modelId,name:modelId,reasoning:!1,input:[`text`],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:128e3,maxTokens:8192}]}}}})}catch{}return await applyLlmProviderModel(projectRoot,`vllm`,modelRef),`vLLM configured (${vllmUrl.trim()}), model → ${modelRef}`}return null}async function builderforceApiFetch(url,opts={}){let{token,...rest}=opts,headers={"Content-Type":`application/json`,...token?{Authorization:`Bearer ${token}`}:{}},res=await fetch(url,{...rest,headers}),body=await res.json().catch(()=>({}));if(!res.ok){let msg=body.error??body.message??res.statusText;throw Error(`${res.status} ${msg}`)}return body}async function ensureProjectMapping(params){try{let upsert=await builderforceApiFetch(`${params.serverUrl}/api/projects/upsert`,{method:`POST`,token:params.tenantJwt,body:JSON.stringify({name:params.projectName,description:params.description??`Managed from ${params.projectRoot}`})});return await builderforceApiFetch(`${params.serverUrl}/api/agent-hosts/${params.agentNodeId}/projects/${upsert.project.id}`,{method:`PUT`,token:params.tenantJwt}),{projectId:upsert.project.id,action:upsert.action}}catch{return null}}async function ensureProjectMappingFromStoredCreds(params){let serverUrl=readSharedEnvVar(`BUILDERFORCE_URL`)??`https://api.builderforce.ai`,webToken=readSharedEnvVar(`BUILDERFORCE_WEB_TOKEN`),tenantIdRaw=readSharedEnvVar(`BUILDERFORCE_TENANT_ID`);if(!webToken||!tenantIdRaw)return;let tenantId=Number(tenantIdRaw);if(!Number.isFinite(tenantId)||tenantId<=0)return;let ctx=await loadProjectContext(params.projectRoot).catch(()=>null),agentNodeId=ctx?.builderforce?.instanceId?.trim();if(!agentNodeId)return;let tenantJwtRes=await builderforceApiFetch(`${serverUrl}/api/auth/tenant-token`,{method:`POST`,token:webToken,body:JSON.stringify({tenantId})}).catch(()=>null);if(!tenantJwtRes?.token)return;let mapped=await ensureProjectMapping({serverUrl,tenantJwt:tenantJwtRes.token,projectRoot:params.projectRoot,projectName:params.projectName,description:params.description,agentNodeId});mapped&&await updateProjectContextFields(params.projectRoot,{builderforce:{instanceId:agentNodeId,...ctx?.builderforce,projectId:mapped.projectId}}).catch(()=>void 0)}async function promptBuilderforceSetup(projectRoot,defaultInstanceName){if(readSharedEnvVar(`BUILDERFORCE_API_KEY`)){let existingUrl=readSharedEnvVar(`BUILDERFORCE_URL`)??`https://api.builderforce.ai`,existingTenantId=readSharedEnvVar(`BUILDERFORCE_TENANT_ID`),existingCtx=await loadProjectContext(projectRoot).catch(()=>null),agentNodeLabel=existingCtx?.builderforce?.instanceSlug??existingCtx?.builderforce?.instanceName??existingCtx?.builderforce?.instanceId??`(registered)`;return note([`URL: ${existingUrl}`,`Tenant: ${existingTenantId??`unknown`}`,`AgentNode: ${agentNodeLabel}`,``,`Run 'builderforce init --reconnect' to link a different account.`].join(`
11
- `),`Already connected to Builderforce`),`Builderforce: already connected (${existingUrl})`}if(readSharedEnvVar(`BUILDERFORCE_SKIPPED`)===`1`)return null;let connect=await confirm({message:`Connect to Builderforce? (optional — manage projects, tasks & agents across your mesh)`,initialValue:!0});if(typeof connect==`symbol`||!connect)return upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`1`}),note(`You can connect to Builderforce anytime with: builderforce init --reconnect`,`Skipped`),null;let urlInput=await text({message:`Orchestration API URL (Builderforce):`,initialValue:`https://api.builderforce.ai`});if(typeof urlInput==`symbol`)return null;let serverUrl=normalizeBaseUrl(urlInput.trim())||`https://api.builderforce.ai`,authMode=await select({message:`Do you have a Builderforce account?`,options:[{value:`login`,label:`Yes — log in`},{value:`register`,label:`No — create a free account`}]});if(typeof authMode==`symbol`)return null;let emailInput=await text({message:`Email:`});if(typeof emailInput==`symbol`||!emailInput.trim())return null;let email=emailInput.trim(),usernameForReg=``;if(authMode===`register`){let unInput=await text({message:`Username:`,initialValue:defaultInstanceName.toLowerCase().replace(/[^a-z0-9]+/g,`-`)});if(typeof unInput==`symbol`||!unInput.trim())return null;usernameForReg=unInput.trim()}let pwdInput=await password({message:`Password:`});if(typeof pwdInput==`symbol`||!pwdInput.trim())return null;let pwd=pwdInput.trim(),webToken=``,authSpin=spinner();try{authMode===`register`?(authSpin.start(`Creating account…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/register`,{method:`POST`,body:JSON.stringify({email,username:usernameForReg,password:pwd})})).token,authSpin.stop(`Account created`)):(authSpin.start(`Authenticating…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/login`,{method:`POST`,body:JSON.stringify({email,password:pwd})})).token,authSpin.stop(`Authenticated`))}catch(err){return authSpin.stop(`Authentication failed`),note(String(err instanceof Error?err.message:err),`Error`),null}let tenantId=0,tenantSpin=spinner();tenantSpin.start(`Loading workspaces…`);let tenants=[];try{tenants=(await builderforceApiFetch(`${serverUrl}/api/auth/my-tenants`,{token:webToken})).tenants,tenantSpin.stop(`${tenants.length} workspace(s) found`)}catch(err){return tenantSpin.stop(`Could not load workspaces`),note(String(err instanceof Error?err.message:err),`Error`),null}if(tenants.length===0){let wsNameInput=await text({message:`Create your first workspace:`,initialValue:defaultInstanceName});if(typeof wsNameInput==`symbol`||!wsNameInput.trim())return null;let wsSpin=spinner();wsSpin.start(`Creating workspace…`);try{let created=await builderforceApiFetch(`${serverUrl}/api/tenants/create`,{method:`POST`,token:webToken,body:JSON.stringify({name:wsNameInput.trim()})});tenantId=created.id,wsSpin.stop(`Workspace "${created.name}" created`)}catch(err){return wsSpin.stop(`Could not create workspace`),note(String(err instanceof Error?err.message:err),`Error`),null}}else if(tenants.length===1)tenantId=tenants[0].id,note(`Using workspace: ${tenants[0].name}`,`Workspace`);else{let picked=await select({message:`Select workspace:`,options:tenants.map(t=>({value:t.id,label:t.name,hint:t.slug}))});if(typeof picked==`symbol`)return null;tenantId=picked}let tenantJwt=``;try{tenantJwt=(await builderforceApiFetch(`${serverUrl}/api/auth/tenant-token`,{method:`POST`,token:webToken,body:JSON.stringify({tenantId})})).token}catch(err){return note(String(err instanceof Error?err.message:err),`Could not get workspace token`),null}let agentNodeNameInput=await text({message:`AgentNode instance name (shown in dashboard):`,initialValue:defaultInstanceName});if(typeof agentNodeNameInput==`symbol`)return null;let agentNodeName=agentNodeNameInput.trim()||defaultInstanceName,agentNodeSpin=spinner();agentNodeSpin.start(`Registering agentNode instance…`);let agentNodeId=``,agentNodeSlug=``,apiKey=``,projectId=``,projectAction=`unknown`;try{let res=await builderforceApiFetch(`${serverUrl}/api/agent-hosts`,{method:`POST`,token:tenantJwt,body:JSON.stringify({name:agentNodeName})});agentNodeId=String(res.agentHost.id),agentNodeSlug=res.agentHost.slug,apiKey=res.apiKey;let mapped=await ensureProjectMapping({serverUrl,tenantJwt,agentNodeId,projectRoot,projectName:defaultInstanceName,description:`builderForceAgents project at ${projectRoot}`});mapped&&(projectId=mapped.projectId,projectAction=mapped.action),agentNodeSpin.stop(`AgentNode "${res.agentHost.name}" registered`)}catch(err){return agentNodeSpin.stop(`AgentNode registration failed`),note(String(err instanceof Error?err.message:err),`Error`),null}upsertSharedEnvVar({key:`BUILDERFORCE_URL`,value:serverUrl}),upsertSharedEnvVar({key:`BUILDERFORCE_WEB_TOKEN`,value:webToken}),upsertSharedEnvVar({key:`BUILDERFORCE_TENANT_ID`,value:String(tenantId)}),upsertSharedEnvVar({key:`BUILDERFORCE_API_KEY`,value:apiKey});try{await updateProjectContextFields(projectRoot,{builderforce:{instanceId:agentNodeId,instanceSlug:agentNodeSlug,instanceName:agentNodeName,...projectId?{projectId}:{},tenantId,url:serverUrl}})}catch{}return note([`AgentNode API key saved to ~/.builderforce/.env`,`This key was shown once — it is hashed on the server.`,`Instance slug: ${agentNodeSlug} · tenant: ${tenantId}`,projectId?`Project ${projectAction}: ${projectId}`:`Project mapping: not available`].join(`
11
+ `),`Already connected to Builderforce`),`Builderforce: already connected (${existingUrl})`}if(readSharedEnvVar(`BUILDERFORCE_SKIPPED`)===`1`)return null;let connect=await confirm({message:`Connect to Builderforce? (optional — manage projects, tasks & agents across your mesh)`,initialValue:!0});if(typeof connect==`symbol`||!connect)return upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`1`}),note(`You can connect to Builderforce anytime with: builderforce init --reconnect`,`Skipped`),null;let urlInput=await text({message:`Orchestration API URL (Builderforce):`,initialValue:`https://api.builderforce.ai`});if(typeof urlInput==`symbol`)return null;let serverUrl=normalizeBaseUrl(urlInput.trim())||`https://api.builderforce.ai`,authMode=await select({message:`Do you have a Builderforce account?`,options:[{value:`login`,label:`Yes — log in`},{value:`register`,label:`No — create a free account`}]});if(typeof authMode==`symbol`)return null;let emailInput=await text({message:`Email:`});if(typeof emailInput==`symbol`||!emailInput.trim())return null;let email=emailInput.trim(),usernameForReg=``;if(authMode===`register`){let unInput=await text({message:`Username:`,initialValue:defaultInstanceName.toLowerCase().replace(/[^a-z0-9]+/g,`-`)});if(typeof unInput==`symbol`||!unInput.trim())return null;usernameForReg=unInput.trim()}let pwdInput=await password({message:`Password:`});if(typeof pwdInput==`symbol`||!pwdInput.trim())return null;let pwd=pwdInput.trim(),webToken=``,authSpin=spinner();try{authMode===`register`?(authSpin.start(`Creating account…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/register`,{method:`POST`,body:JSON.stringify({email,username:usernameForReg,password:pwd})})).token,authSpin.stop(`Account created`)):(authSpin.start(`Authenticating…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/login`,{method:`POST`,body:JSON.stringify({email,password:pwd})})).token,authSpin.stop(`Authenticated`))}catch(err){return authSpin.stop(`Authentication failed`),note(String(err instanceof Error?err.message:err),`Error`),null}let tenantId=0,tenantSpin=spinner();tenantSpin.start(`Loading workspaces…`);let tenants=[];try{tenants=(await builderforceApiFetch(`${serverUrl}/api/tenants`,{token:webToken})).tenants,tenantSpin.stop(`${tenants.length} workspace(s) found`)}catch(err){return tenantSpin.stop(`Could not load workspaces`),note(String(err instanceof Error?err.message:err),`Error`),null}if(tenants.length===0){let wsNameInput=await text({message:`Create your first workspace:`,initialValue:defaultInstanceName});if(typeof wsNameInput==`symbol`||!wsNameInput.trim())return null;let wsSpin=spinner();wsSpin.start(`Creating workspace…`);try{let created=await builderforceApiFetch(`${serverUrl}/api/tenants`,{method:`POST`,token:webToken,body:JSON.stringify({name:wsNameInput.trim()})});tenantId=created.id,wsSpin.stop(`Workspace "${created.name}" created`)}catch(err){return wsSpin.stop(`Could not create workspace`),note(String(err instanceof Error?err.message:err),`Error`),null}}else if(tenants.length===1)tenantId=tenants[0].id,note(`Using workspace: ${tenants[0].name}`,`Workspace`);else{let picked=await select({message:`Select workspace:`,options:tenants.map(t=>({value:t.id,label:t.name,hint:t.slug}))});if(typeof picked==`symbol`)return null;tenantId=picked}let tenantJwt=``;try{tenantJwt=(await builderforceApiFetch(`${serverUrl}/api/auth/tenant-token`,{method:`POST`,token:webToken,body:JSON.stringify({tenantId})})).token}catch(err){return note(String(err instanceof Error?err.message:err),`Could not get workspace token`),null}let agentNodeNameInput=await text({message:`AgentNode instance name (shown in dashboard):`,initialValue:defaultInstanceName});if(typeof agentNodeNameInput==`symbol`)return null;let agentNodeName=agentNodeNameInput.trim()||defaultInstanceName,agentNodeSpin=spinner();agentNodeSpin.start(`Registering agentNode instance…`);let agentNodeId=``,agentNodeSlug=``,apiKey=``,projectId=``,projectAction=`unknown`;try{let res=await builderforceApiFetch(`${serverUrl}/api/agent-hosts`,{method:`POST`,token:tenantJwt,body:JSON.stringify({name:agentNodeName})});agentNodeId=String(res.agentHost.id),agentNodeSlug=res.agentHost.slug,apiKey=res.apiKey;let mapped=await ensureProjectMapping({serverUrl,tenantJwt,agentNodeId,projectRoot,projectName:defaultInstanceName,description:`builderForceAgents project at ${projectRoot}`});mapped&&(projectId=mapped.projectId,projectAction=mapped.action),agentNodeSpin.stop(`AgentNode "${res.agentHost.name}" registered`)}catch(err){return agentNodeSpin.stop(`AgentNode registration failed`),note(String(err instanceof Error?err.message:err),`Error`),null}upsertSharedEnvVar({key:`BUILDERFORCE_URL`,value:serverUrl}),upsertSharedEnvVar({key:`BUILDERFORCE_WEB_TOKEN`,value:webToken}),upsertSharedEnvVar({key:`BUILDERFORCE_TENANT_ID`,value:String(tenantId)}),upsertSharedEnvVar({key:`BUILDERFORCE_API_KEY`,value:apiKey});try{await updateProjectContextFields(projectRoot,{builderforce:{instanceId:agentNodeId,instanceSlug:agentNodeSlug,instanceName:agentNodeName,...projectId?{projectId}:{},tenantId,url:serverUrl}})}catch{}return note([`AgentNode API key saved to ~/.builderforce/.env`,`This key was shown once — it is hashed on the server.`,`Instance slug: ${agentNodeSlug} · tenant: ${tenantId}`,projectId?`Project ${projectAction}: ${projectId}`:`Project mapping: not available`].join(`
12
12
  `),`Builderforce connected`),`Builderforce: ${agentNodeName} (${agentNodeSlug}) on tenant ${tenantId}`}function createBuilderForceAgentsCommand(){let cmd=new Command(`project`);return cmd.description(`Manage builderForceAgents project context`).addCommand(createStatusCommand()),cmd}function createInitCommand(){return new Command(`init`).description(`Initialize a project with builderForceAgents`).argument(`[path]`,`Project directory path`,`.`).action(async projectPath=>{let projectRoot=projectPath===`.`?process.cwd():projectPath;if(await isBuilderForceAgentsProject(projectRoot)){await runBuilderForceAgentsSession(projectRoot);return}intro(theme.accent(`builderForceAgents`));let detectSpin=spinner();detectSpin.start(`Detecting project info...`);let detected=await detectProjectInfo(projectRoot);detectSpin.stop(`Project info detected`),note([`name: ${detected.projectName}`,`languages: ${detected.languages.join(`, `)||`(none detected)`}`,`frameworks: ${detected.frameworks.join(`, `)||`(none detected)`}`,`build: ${detected.buildSystem??`(unknown)`}`,`test: ${detected.testFramework??`(unknown)`}`,`lint: ${detected.lintingTools.join(`, `)||`(none detected)`}`].join(`
13
13
  `),`Auto-detected`);let projectNameInput=await text({message:`Project name:`,initialValue:detected.projectName});if(typeof projectNameInput==`symbol`){outro(theme.muted(`Cancelled`));return}let descriptionInput=await text({message:`Project description:`,initialValue:detected.description,placeholder:`A brief description of what this project does`});if(typeof descriptionInput==`symbol`){outro(theme.muted(`Cancelled`));return}let languagesInput=await text({message:`Primary languages (comma-separated):`,initialValue:detected.languages.join(`, `),placeholder:`typescript, javascript`});if(typeof languagesInput==`symbol`){outro(theme.muted(`Cancelled`));return}let frameworksInput=await text({message:`Frameworks used (comma-separated):`,initialValue:detected.frameworks.join(`, `),placeholder:`express, react`});if(typeof frameworksInput==`symbol`){outro(theme.muted(`Cancelled`));return}let spin=spinner();spin.start(`Setting up .builderforce/...`);try{await initializeBuilderForceAgentsProject(projectRoot,{projectName:projectNameInput||detected.projectName,description:descriptionInput||detected.description,languages:languagesInput.trim().length>0?languagesInput.split(`,`).map(l=>l.trim()).filter(Boolean):detected.languages,frameworks:frameworksInput.trim().length>0?frameworksInput.split(`,`).map(f=>f.trim()).filter(Boolean):detected.frameworks,buildSystem:detected.buildSystem,testFramework:detected.testFramework,lintingTools:detected.lintingTools}),spin.stop(theme.success(`builderForceAgents initialized!`)),note([` ${theme.muted(`context.yaml`)} – project metadata (edit to tune AI understanding)`,` ${theme.muted(`architecture.md`)} – high-level design docs`,` ${theme.muted(`rules.yaml`)} – coding standards & conventions`].join(`
14
14
  `),`.builderforce/ created`),await promptLlmProvider(projectRoot),await promptBuilderforceSetup(projectRoot,projectNameInput||detected.projectName),await ensureProjectMappingFromStoredCreds({projectRoot,projectName:projectNameInput||detected.projectName,description:descriptionInput||detected.description});let aiPopulate=await confirm({message:`Use an AI agent to populate context.yaml, architecture.md, and rules.yaml now?`,initialValue:!0});await runBuilderForceAgentsSession(projectRoot,{message:typeof aiPopulate!=`symbol`&&aiPopulate?`Analyze this project and populate .builderforce/context.yaml, architecture.md, and rules.yaml with accurate project context`:void 0})}catch(error){spin.stop(theme.error(`Failed to initialize project`)),outro(theme.error(error instanceof Error?error.message:String(error)))}})}function createStatusCommand(){return new Command(`status`).description(`Show builderForceAgents project status and context`).argument(`[path]`,`Project directory path`,`.`).action(async projectPath=>{let projectRoot=projectPath===`.`?process.cwd():projectPath;if(!await isBuilderForceAgentsProject(projectRoot)){console.log(theme.warn(`Project is not initialized with builderForceAgents`)),console.log(theme.muted(`Run 'builderforce init' to initialize`));return}console.log(theme.success(`✓ builderForceAgents project detected`)),console.log(theme.muted(` Location: ${projectRoot}/.builderforce/`))})}function createAgentCommand(){let cmd=new Command(`workforce`).description(`Manage Builderforce Workforce agents (custom trained LLMs)`);return cmd.addCommand(new Command(`install`).description(`Install a Workforce agent from the Builderforce registry`).argument(`<agentId>`,`Agent UUID or name from the Workforce Registry`).option(`--registry <url>`,`Builderforce registry URL`,DEFAULT_REGISTRY_URL).option(`--path <dir>`,`Project directory`,`.`).action(async(agentId,opts)=>{let projectRoot=opts.path===`.`?process.cwd():opts.path;intro(theme.accent(`builderForceAgents`)+` `+theme.muted(`agent install`));try{let summary=await installWorkforceAgent({agentId,projectRoot,registryUrl:opts.registry});outro(theme.success(`Agent installed!
@@ -20,5 +20,5 @@ import"./paths-5FcIFMsj.js";import"./utils-DbaBVFaK.js";import"./session-key-EoB
20
20
  </div>
21
21
  </body>
22
22
  </html>`),setImmediate(()=>server.close()),resolve({webToken:token})});server.listen(CALLBACK_PORT,`127.0.0.1`);let timer=setTimeout(()=>{server.close(),reject(Error(`Authentication timed out after 5 minutes.`))},3e5);server.on(`close`,()=>clearTimeout(timer))})}async function builderforceApiFetch(url,opts={}){let{token,...rest}=opts,headers={"Content-Type":`application/json`,...token?{Authorization:`Bearer ${token}`}:{}},res=await fetch(url,{...rest,headers}),body=await res.json().catch(()=>({}));if(!res.ok){let msg=body.error??body.message??res.statusText;throw Error(`${res.status} ${msg}`)}return body}async function ensureProjectMapping(params){try{let upsert=await builderforceApiFetch(`${params.serverUrl}/api/projects/upsert`,{method:`POST`,token:params.tenantJwt,body:JSON.stringify({name:params.projectName,description:params.description??`Managed from ${params.projectRoot}`})});return await builderforceApiFetch(`${params.serverUrl}/api/agent-hosts/${params.agentNodeId}/projects/${upsert.project.id}`,{method:`PUT`,token:params.tenantJwt}),{projectId:upsert.project.id,action:upsert.action}}catch{return null}}async function promptBuilderforceOnboarding(params){if(readSharedEnvVar(`BUILDERFORCE_API_KEY`)){let existingUrl=readSharedEnvVar(`BUILDERFORCE_URL`)??`https://api.builderforce.ai`,existingTenantId=readSharedEnvVar(`BUILDERFORCE_TENANT_ID`),existingCtx=await loadProjectContext(params.projectRoot).catch(()=>null),agentNodeLabel=existingCtx?.builderforce?.instanceSlug??existingCtx?.builderforce?.instanceName??existingCtx?.builderforce?.instanceId??`(registered)`;return note([`URL: ${existingUrl}`,`Tenant: ${existingTenantId??`unknown`}`,`AgentNode: ${agentNodeLabel}`,``,`Run 'builderforce init --reconnect' to link a different account.`].join(`
23
- `),`Already connected to Builderforce`),`Builderforce: already connected (${existingUrl})`}if(!params.forcePrompt&&readSharedEnvVar(`BUILDERFORCE_SKIPPED`)===`1`)return null;let connect=await confirm({message:`Connect to Builderforce? (optional — manage projects, tasks & agents across your mesh)`,initialValue:!0});if(typeof connect==`symbol`||!connect)return upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`1`}),null;let urlInput=await text({message:`Orchestration API URL (Builderforce):`,initialValue:`https://api.builderforce.ai`});if(typeof urlInput==`symbol`)return null;let serverUrl=normalizeBaseUrl(urlInput.trim())||`https://api.builderforce.ai`,authMethod=(await detectBrowserOpenSupport()).ok?await select({message:`How would you like to authenticate?`,options:[{value:`browser`,label:`Open browser (recommended)`,hint:`login or register in your browser`},{value:`terminal`,label:`Type here`,hint:`enter email & password in this terminal`}]}):`terminal`;if(typeof authMethod==`symbol`)return null;let webToken=``;if(authMethod===`browser`){let result=await authenticateViaBrowser({serverUrl,prompter:{note:async(msg,title)=>{note(msg,title)},text:opts=>text({...opts,validate:opts.validate?value=>opts.validate(value??``):void 0})}});if(!result)return null;webToken=result.webToken}else{let authMode=await select({message:`Do you have a Builderforce account?`,options:[{value:`login`,label:`Yes — log in`},{value:`register`,label:`No — create a free account`}]});if(typeof authMode==`symbol`)return null;let emailInput=await text({message:`Email:`});if(typeof emailInput==`symbol`||!emailInput.trim())return null;let email=emailInput.trim(),usernameForReg=``;if(authMode===`register`){let usernameInput=await text({message:`Username:`,initialValue:params.defaultInstanceName.toLowerCase().replace(/[^a-z0-9]+/g,`-`)});if(typeof usernameInput==`symbol`||!usernameInput.trim())return null;usernameForReg=usernameInput.trim()}let passwordInput=await password({message:`Password:`});if(typeof passwordInput==`symbol`||!passwordInput.trim())return null;let rawPassword=passwordInput.trim(),authSpin=spinner();try{authMode===`register`?(authSpin.start(`Creating account…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/register`,{method:`POST`,body:JSON.stringify({email,username:usernameForReg,password:rawPassword})})).token,authSpin.stop(`Account created`)):(authSpin.start(`Authenticating…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/login`,{method:`POST`,body:JSON.stringify({email,password:rawPassword})})).token,authSpin.stop(`Authenticated`))}catch(err){return authSpin.stop(`Authentication failed`),note(String(err instanceof Error?err.message:err),`Error`),null}}let tenantId=0,tenantSpin=spinner();tenantSpin.start(`Loading workspaces…`);let tenants=[];try{tenants=(await builderforceApiFetch(`${serverUrl}/api/auth/my-tenants`,{token:webToken})).tenants,tenantSpin.stop(`${tenants.length} workspace(s) found`)}catch(err){return tenantSpin.stop(`Could not load workspaces`),note(String(err instanceof Error?err.message:err),`Error`),null}if(tenants.length===0){let wsNameInput=await text({message:`Create your first workspace:`,initialValue:params.defaultInstanceName});if(typeof wsNameInput==`symbol`||!wsNameInput.trim())return null;let wsSpin=spinner();wsSpin.start(`Creating workspace…`);try{let created=await builderforceApiFetch(`${serverUrl}/api/tenants/create`,{method:`POST`,token:webToken,body:JSON.stringify({name:wsNameInput.trim()})});tenantId=created.id,wsSpin.stop(`Workspace "${created.name}" created`)}catch(err){return wsSpin.stop(`Could not create workspace`),note(String(err instanceof Error?err.message:err),`Error`),null}}else if(tenants.length===1)tenantId=tenants[0].id,note(`Using workspace: ${tenants[0].name}`,`Workspace`);else{let picked=await select({message:`Select workspace:`,options:tenants.map(tenant=>({value:tenant.id,label:tenant.name,hint:tenant.slug}))});if(typeof picked==`symbol`)return null;tenantId=picked}let tenantJwt=``;try{tenantJwt=(await builderforceApiFetch(`${serverUrl}/api/auth/tenant-token`,{method:`POST`,token:webToken,body:JSON.stringify({tenantId})})).token}catch(err){return note(String(err instanceof Error?err.message:err),`Could not get workspace token`),null}let agentNodeNameInput=await text({message:`AgentNode instance name (shown in dashboard):`,initialValue:params.defaultInstanceName});if(typeof agentNodeNameInput==`symbol`)return null;let agentNodeName=agentNodeNameInput.trim()||params.defaultInstanceName,agentNodeSpin=spinner();agentNodeSpin.start(`Registering agentNode instance…`);let agentNodeId=``,agentNodeSlug=``,apiKey=``,projectId=``,projectAction=`unknown`,machineProfile=buildLocalMachineProfile({workspaceDirectory:params.projectRoot,rootInstallDirectory:process.cwd(),gatewayPort:18789,tunnelUrl:process.env.BUILDERFORCE_AGENTS_PUBLIC_TUNNEL_URL,tunnelStatus:process.env.BUILDERFORCE_AGENTS_PUBLIC_TUNNEL_URL?`connected`:`none`});try{let res=await builderforceApiFetch(`${serverUrl}/api/agent-hosts`,{method:`POST`,token:tenantJwt,body:JSON.stringify({name:agentNodeName,machineProfile})});agentNodeId=String(res.agentHost.id),agentNodeSlug=res.agentHost.slug,apiKey=res.apiKey;let mapped=await ensureProjectMapping({serverUrl,tenantJwt,agentNodeId,projectRoot:params.projectRoot,projectName:params.defaultInstanceName,description:`builderForceAgents project at ${params.projectRoot}`});mapped&&(projectId=mapped.projectId,projectAction=mapped.action),agentNodeSpin.stop(`AgentNode "${res.agentHost.name}" registered`)}catch(err){return agentNodeSpin.stop(`AgentNode registration failed`),note(String(err instanceof Error?err.message:err),`Error`),null}upsertSharedEnvVar({key:`BUILDERFORCE_URL`,value:serverUrl}),upsertSharedEnvVar({key:`BUILDERFORCE_WEB_TOKEN`,value:webToken}),upsertSharedEnvVar({key:`BUILDERFORCE_TENANT_ID`,value:String(tenantId)}),upsertSharedEnvVar({key:`BUILDERFORCE_API_KEY`,value:apiKey}),upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`0`});try{await updateProjectContextFields(params.projectRoot,{builderforce:{instanceId:agentNodeId,instanceSlug:agentNodeSlug,instanceName:agentNodeName,...projectId?{projectId}:{},tenantId,url:serverUrl,machineProfile}})}catch{}return note([`AgentNode API key saved to ~/.builderforce/.env`,`This key was shown once — it is hashed on the server.`,`Instance slug: ${agentNodeSlug} · tenant: ${tenantId}`,projectId?`Project ${projectAction}: ${projectId}`:`Project mapping: not available`].join(`
23
+ `),`Already connected to Builderforce`),`Builderforce: already connected (${existingUrl})`}if(!params.forcePrompt&&readSharedEnvVar(`BUILDERFORCE_SKIPPED`)===`1`)return null;let connect=await confirm({message:`Connect to Builderforce? (optional — manage projects, tasks & agents across your mesh)`,initialValue:!0});if(typeof connect==`symbol`||!connect)return upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`1`}),null;let urlInput=await text({message:`Orchestration API URL (Builderforce):`,initialValue:`https://api.builderforce.ai`});if(typeof urlInput==`symbol`)return null;let serverUrl=normalizeBaseUrl(urlInput.trim())||`https://api.builderforce.ai`,authMethod=(await detectBrowserOpenSupport()).ok?await select({message:`How would you like to authenticate?`,options:[{value:`browser`,label:`Open browser (recommended)`,hint:`login or register in your browser`},{value:`terminal`,label:`Type here`,hint:`enter email & password in this terminal`}]}):`terminal`;if(typeof authMethod==`symbol`)return null;let webToken=``;if(authMethod===`browser`){let result=await authenticateViaBrowser({serverUrl,prompter:{note:async(msg,title)=>{note(msg,title)},text:opts=>text({...opts,validate:opts.validate?value=>opts.validate(value??``):void 0})}});if(!result)return null;webToken=result.webToken}else{let authMode=await select({message:`Do you have a Builderforce account?`,options:[{value:`login`,label:`Yes — log in`},{value:`register`,label:`No — create a free account`}]});if(typeof authMode==`symbol`)return null;let emailInput=await text({message:`Email:`});if(typeof emailInput==`symbol`||!emailInput.trim())return null;let email=emailInput.trim(),usernameForReg=``;if(authMode===`register`){let usernameInput=await text({message:`Username:`,initialValue:params.defaultInstanceName.toLowerCase().replace(/[^a-z0-9]+/g,`-`)});if(typeof usernameInput==`symbol`||!usernameInput.trim())return null;usernameForReg=usernameInput.trim()}let passwordInput=await password({message:`Password:`});if(typeof passwordInput==`symbol`||!passwordInput.trim())return null;let rawPassword=passwordInput.trim(),authSpin=spinner();try{authMode===`register`?(authSpin.start(`Creating account…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/register`,{method:`POST`,body:JSON.stringify({email,username:usernameForReg,password:rawPassword})})).token,authSpin.stop(`Account created`)):(authSpin.start(`Authenticating…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/login`,{method:`POST`,body:JSON.stringify({email,password:rawPassword})})).token,authSpin.stop(`Authenticated`))}catch(err){return authSpin.stop(`Authentication failed`),note(String(err instanceof Error?err.message:err),`Error`),null}}let tenantId=0,tenantSpin=spinner();tenantSpin.start(`Loading workspaces…`);let tenants=[];try{tenants=(await builderforceApiFetch(`${serverUrl}/api/tenants`,{token:webToken})).tenants,tenantSpin.stop(`${tenants.length} workspace(s) found`)}catch(err){return tenantSpin.stop(`Could not load workspaces`),note(String(err instanceof Error?err.message:err),`Error`),null}if(tenants.length===0){let wsNameInput=await text({message:`Create your first workspace:`,initialValue:params.defaultInstanceName});if(typeof wsNameInput==`symbol`||!wsNameInput.trim())return null;let wsSpin=spinner();wsSpin.start(`Creating workspace…`);try{let created=await builderforceApiFetch(`${serverUrl}/api/tenants`,{method:`POST`,token:webToken,body:JSON.stringify({name:wsNameInput.trim()})});tenantId=created.id,wsSpin.stop(`Workspace "${created.name}" created`)}catch(err){return wsSpin.stop(`Could not create workspace`),note(String(err instanceof Error?err.message:err),`Error`),null}}else if(tenants.length===1)tenantId=tenants[0].id,note(`Using workspace: ${tenants[0].name}`,`Workspace`);else{let picked=await select({message:`Select workspace:`,options:tenants.map(tenant=>({value:tenant.id,label:tenant.name,hint:tenant.slug}))});if(typeof picked==`symbol`)return null;tenantId=picked}let tenantJwt=``;try{tenantJwt=(await builderforceApiFetch(`${serverUrl}/api/auth/tenant-token`,{method:`POST`,token:webToken,body:JSON.stringify({tenantId})})).token}catch(err){return note(String(err instanceof Error?err.message:err),`Could not get workspace token`),null}let agentNodeNameInput=await text({message:`AgentNode instance name (shown in dashboard):`,initialValue:params.defaultInstanceName});if(typeof agentNodeNameInput==`symbol`)return null;let agentNodeName=agentNodeNameInput.trim()||params.defaultInstanceName,agentNodeSpin=spinner();agentNodeSpin.start(`Registering agentNode instance…`);let agentNodeId=``,agentNodeSlug=``,apiKey=``,projectId=``,projectAction=`unknown`,machineProfile=buildLocalMachineProfile({workspaceDirectory:params.projectRoot,rootInstallDirectory:process.cwd(),gatewayPort:18789,tunnelUrl:process.env.BUILDERFORCE_AGENTS_PUBLIC_TUNNEL_URL,tunnelStatus:process.env.BUILDERFORCE_AGENTS_PUBLIC_TUNNEL_URL?`connected`:`none`});try{let res=await builderforceApiFetch(`${serverUrl}/api/agent-hosts`,{method:`POST`,token:tenantJwt,body:JSON.stringify({name:agentNodeName,machineProfile})});agentNodeId=String(res.agentHost.id),agentNodeSlug=res.agentHost.slug,apiKey=res.apiKey;let mapped=await ensureProjectMapping({serverUrl,tenantJwt,agentNodeId,projectRoot:params.projectRoot,projectName:params.defaultInstanceName,description:`builderForceAgents project at ${params.projectRoot}`});mapped&&(projectId=mapped.projectId,projectAction=mapped.action),agentNodeSpin.stop(`AgentNode "${res.agentHost.name}" registered`)}catch(err){return agentNodeSpin.stop(`AgentNode registration failed`),note(String(err instanceof Error?err.message:err),`Error`),null}upsertSharedEnvVar({key:`BUILDERFORCE_URL`,value:serverUrl}),upsertSharedEnvVar({key:`BUILDERFORCE_WEB_TOKEN`,value:webToken}),upsertSharedEnvVar({key:`BUILDERFORCE_TENANT_ID`,value:String(tenantId)}),upsertSharedEnvVar({key:`BUILDERFORCE_API_KEY`,value:apiKey}),upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`0`});try{await updateProjectContextFields(params.projectRoot,{builderforce:{instanceId:agentNodeId,instanceSlug:agentNodeSlug,instanceName:agentNodeName,...projectId?{projectId}:{},tenantId,url:serverUrl,machineProfile}})}catch{}return note([`AgentNode API key saved to ~/.builderforce/.env`,`This key was shown once — it is hashed on the server.`,`Instance slug: ${agentNodeSlug} · tenant: ${tenantId}`,projectId?`Project ${projectAction}: ${projectId}`:`Project mapping: not available`].join(`
24
24
  `),`Builderforce connected`),`Builderforce: ${agentNodeName} (${agentNodeSlug}) on tenant ${tenantId}`}export{promptBuilderforceOnboarding};
@@ -20,5 +20,5 @@ import"./paths-BHg-VHB4.js";import"./registry-Cv7CoWAs.js";import"./utils-BP60e8
20
20
  </div>
21
21
  </body>
22
22
  </html>`),setImmediate(()=>server.close()),resolve({webToken:token})});server.listen(CALLBACK_PORT,`127.0.0.1`);let timer=setTimeout(()=>{server.close(),reject(Error(`Authentication timed out after 5 minutes.`))},3e5);server.on(`close`,()=>clearTimeout(timer))})}async function builderforceApiFetch(url,opts={}){let{token,...rest}=opts,headers={"Content-Type":`application/json`,...token?{Authorization:`Bearer ${token}`}:{}},res=await fetch(url,{...rest,headers}),body=await res.json().catch(()=>({}));if(!res.ok){let msg=body.error??body.message??res.statusText;throw Error(`${res.status} ${msg}`)}return body}async function ensureProjectMapping(params){try{let upsert=await builderforceApiFetch(`${params.serverUrl}/api/projects/upsert`,{method:`POST`,token:params.tenantJwt,body:JSON.stringify({name:params.projectName,description:params.description??`Managed from ${params.projectRoot}`})});return await builderforceApiFetch(`${params.serverUrl}/api/agent-hosts/${params.agentNodeId}/projects/${upsert.project.id}`,{method:`PUT`,token:params.tenantJwt}),{projectId:upsert.project.id,action:upsert.action}}catch{return null}}async function promptBuilderforceOnboarding(params){if(readSharedEnvVar(`BUILDERFORCE_API_KEY`)){let existingUrl=readSharedEnvVar(`BUILDERFORCE_URL`)??`https://api.builderforce.ai`,existingTenantId=readSharedEnvVar(`BUILDERFORCE_TENANT_ID`),existingCtx=await loadProjectContext(params.projectRoot).catch(()=>null),agentNodeLabel=existingCtx?.builderforce?.instanceSlug??existingCtx?.builderforce?.instanceName??existingCtx?.builderforce?.instanceId??`(registered)`;return note([`URL: ${existingUrl}`,`Tenant: ${existingTenantId??`unknown`}`,`AgentNode: ${agentNodeLabel}`,``,`Run 'builderforce init --reconnect' to link a different account.`].join(`
23
- `),`Already connected to Builderforce`),`Builderforce: already connected (${existingUrl})`}if(!params.forcePrompt&&readSharedEnvVar(`BUILDERFORCE_SKIPPED`)===`1`)return null;let connect=await confirm({message:`Connect to Builderforce? (optional — manage projects, tasks & agents across your mesh)`,initialValue:!0});if(typeof connect==`symbol`||!connect)return upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`1`}),null;let urlInput=await text({message:`Orchestration API URL (Builderforce):`,initialValue:`https://api.builderforce.ai`});if(typeof urlInput==`symbol`)return null;let serverUrl=normalizeBaseUrl(urlInput.trim())||`https://api.builderforce.ai`,authMethod=(await detectBrowserOpenSupport()).ok?await select({message:`How would you like to authenticate?`,options:[{value:`browser`,label:`Open browser (recommended)`,hint:`login or register in your browser`},{value:`terminal`,label:`Type here`,hint:`enter email & password in this terminal`}]}):`terminal`;if(typeof authMethod==`symbol`)return null;let webToken=``;if(authMethod===`browser`){let result=await authenticateViaBrowser({serverUrl,prompter:{note:async(msg,title)=>{note(msg,title)},text:opts=>text({...opts,validate:opts.validate?value=>opts.validate(value??``):void 0})}});if(!result)return null;webToken=result.webToken}else{let authMode=await select({message:`Do you have a Builderforce account?`,options:[{value:`login`,label:`Yes — log in`},{value:`register`,label:`No — create a free account`}]});if(typeof authMode==`symbol`)return null;let emailInput=await text({message:`Email:`});if(typeof emailInput==`symbol`||!emailInput.trim())return null;let email=emailInput.trim(),usernameForReg=``;if(authMode===`register`){let usernameInput=await text({message:`Username:`,initialValue:params.defaultInstanceName.toLowerCase().replace(/[^a-z0-9]+/g,`-`)});if(typeof usernameInput==`symbol`||!usernameInput.trim())return null;usernameForReg=usernameInput.trim()}let passwordInput=await password({message:`Password:`});if(typeof passwordInput==`symbol`||!passwordInput.trim())return null;let rawPassword=passwordInput.trim(),authSpin=spinner();try{authMode===`register`?(authSpin.start(`Creating account…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/register`,{method:`POST`,body:JSON.stringify({email,username:usernameForReg,password:rawPassword})})).token,authSpin.stop(`Account created`)):(authSpin.start(`Authenticating…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/login`,{method:`POST`,body:JSON.stringify({email,password:rawPassword})})).token,authSpin.stop(`Authenticated`))}catch(err){return authSpin.stop(`Authentication failed`),note(String(err instanceof Error?err.message:err),`Error`),null}}let tenantId=0,tenantSpin=spinner();tenantSpin.start(`Loading workspaces…`);let tenants=[];try{tenants=(await builderforceApiFetch(`${serverUrl}/api/auth/my-tenants`,{token:webToken})).tenants,tenantSpin.stop(`${tenants.length} workspace(s) found`)}catch(err){return tenantSpin.stop(`Could not load workspaces`),note(String(err instanceof Error?err.message:err),`Error`),null}if(tenants.length===0){let wsNameInput=await text({message:`Create your first workspace:`,initialValue:params.defaultInstanceName});if(typeof wsNameInput==`symbol`||!wsNameInput.trim())return null;let wsSpin=spinner();wsSpin.start(`Creating workspace…`);try{let created=await builderforceApiFetch(`${serverUrl}/api/tenants/create`,{method:`POST`,token:webToken,body:JSON.stringify({name:wsNameInput.trim()})});tenantId=created.id,wsSpin.stop(`Workspace "${created.name}" created`)}catch(err){return wsSpin.stop(`Could not create workspace`),note(String(err instanceof Error?err.message:err),`Error`),null}}else if(tenants.length===1)tenantId=tenants[0].id,note(`Using workspace: ${tenants[0].name}`,`Workspace`);else{let picked=await select({message:`Select workspace:`,options:tenants.map(tenant=>({value:tenant.id,label:tenant.name,hint:tenant.slug}))});if(typeof picked==`symbol`)return null;tenantId=picked}let tenantJwt=``;try{tenantJwt=(await builderforceApiFetch(`${serverUrl}/api/auth/tenant-token`,{method:`POST`,token:webToken,body:JSON.stringify({tenantId})})).token}catch(err){return note(String(err instanceof Error?err.message:err),`Could not get workspace token`),null}let agentNodeNameInput=await text({message:`AgentNode instance name (shown in dashboard):`,initialValue:params.defaultInstanceName});if(typeof agentNodeNameInput==`symbol`)return null;let agentNodeName=agentNodeNameInput.trim()||params.defaultInstanceName,agentNodeSpin=spinner();agentNodeSpin.start(`Registering agentNode instance…`);let agentNodeId=``,agentNodeSlug=``,apiKey=``,projectId=``,projectAction=`unknown`,machineProfile=buildLocalMachineProfile({workspaceDirectory:params.projectRoot,rootInstallDirectory:process.cwd(),gatewayPort:18789,tunnelUrl:process.env.BUILDERFORCE_AGENTS_PUBLIC_TUNNEL_URL,tunnelStatus:process.env.BUILDERFORCE_AGENTS_PUBLIC_TUNNEL_URL?`connected`:`none`});try{let res=await builderforceApiFetch(`${serverUrl}/api/agent-hosts`,{method:`POST`,token:tenantJwt,body:JSON.stringify({name:agentNodeName,machineProfile})});agentNodeId=String(res.agentHost.id),agentNodeSlug=res.agentHost.slug,apiKey=res.apiKey;let mapped=await ensureProjectMapping({serverUrl,tenantJwt,agentNodeId,projectRoot:params.projectRoot,projectName:params.defaultInstanceName,description:`builderForceAgents project at ${params.projectRoot}`});mapped&&(projectId=mapped.projectId,projectAction=mapped.action),agentNodeSpin.stop(`AgentNode "${res.agentHost.name}" registered`)}catch(err){return agentNodeSpin.stop(`AgentNode registration failed`),note(String(err instanceof Error?err.message:err),`Error`),null}upsertSharedEnvVar({key:`BUILDERFORCE_URL`,value:serverUrl}),upsertSharedEnvVar({key:`BUILDERFORCE_WEB_TOKEN`,value:webToken}),upsertSharedEnvVar({key:`BUILDERFORCE_TENANT_ID`,value:String(tenantId)}),upsertSharedEnvVar({key:`BUILDERFORCE_API_KEY`,value:apiKey}),upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`0`});try{await updateProjectContextFields(params.projectRoot,{builderforce:{instanceId:agentNodeId,instanceSlug:agentNodeSlug,instanceName:agentNodeName,...projectId?{projectId}:{},tenantId,url:serverUrl,machineProfile}})}catch{}return note([`AgentNode API key saved to ~/.builderforce/.env`,`This key was shown once — it is hashed on the server.`,`Instance slug: ${agentNodeSlug} · tenant: ${tenantId}`,projectId?`Project ${projectAction}: ${projectId}`:`Project mapping: not available`].join(`
23
+ `),`Already connected to Builderforce`),`Builderforce: already connected (${existingUrl})`}if(!params.forcePrompt&&readSharedEnvVar(`BUILDERFORCE_SKIPPED`)===`1`)return null;let connect=await confirm({message:`Connect to Builderforce? (optional — manage projects, tasks & agents across your mesh)`,initialValue:!0});if(typeof connect==`symbol`||!connect)return upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`1`}),null;let urlInput=await text({message:`Orchestration API URL (Builderforce):`,initialValue:`https://api.builderforce.ai`});if(typeof urlInput==`symbol`)return null;let serverUrl=normalizeBaseUrl(urlInput.trim())||`https://api.builderforce.ai`,authMethod=(await detectBrowserOpenSupport()).ok?await select({message:`How would you like to authenticate?`,options:[{value:`browser`,label:`Open browser (recommended)`,hint:`login or register in your browser`},{value:`terminal`,label:`Type here`,hint:`enter email & password in this terminal`}]}):`terminal`;if(typeof authMethod==`symbol`)return null;let webToken=``;if(authMethod===`browser`){let result=await authenticateViaBrowser({serverUrl,prompter:{note:async(msg,title)=>{note(msg,title)},text:opts=>text({...opts,validate:opts.validate?value=>opts.validate(value??``):void 0})}});if(!result)return null;webToken=result.webToken}else{let authMode=await select({message:`Do you have a Builderforce account?`,options:[{value:`login`,label:`Yes — log in`},{value:`register`,label:`No — create a free account`}]});if(typeof authMode==`symbol`)return null;let emailInput=await text({message:`Email:`});if(typeof emailInput==`symbol`||!emailInput.trim())return null;let email=emailInput.trim(),usernameForReg=``;if(authMode===`register`){let usernameInput=await text({message:`Username:`,initialValue:params.defaultInstanceName.toLowerCase().replace(/[^a-z0-9]+/g,`-`)});if(typeof usernameInput==`symbol`||!usernameInput.trim())return null;usernameForReg=usernameInput.trim()}let passwordInput=await password({message:`Password:`});if(typeof passwordInput==`symbol`||!passwordInput.trim())return null;let rawPassword=passwordInput.trim(),authSpin=spinner();try{authMode===`register`?(authSpin.start(`Creating account…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/register`,{method:`POST`,body:JSON.stringify({email,username:usernameForReg,password:rawPassword})})).token,authSpin.stop(`Account created`)):(authSpin.start(`Authenticating…`),webToken=(await builderforceApiFetch(`${serverUrl}/api/auth/web/login`,{method:`POST`,body:JSON.stringify({email,password:rawPassword})})).token,authSpin.stop(`Authenticated`))}catch(err){return authSpin.stop(`Authentication failed`),note(String(err instanceof Error?err.message:err),`Error`),null}}let tenantId=0,tenantSpin=spinner();tenantSpin.start(`Loading workspaces…`);let tenants=[];try{tenants=(await builderforceApiFetch(`${serverUrl}/api/tenants`,{token:webToken})).tenants,tenantSpin.stop(`${tenants.length} workspace(s) found`)}catch(err){return tenantSpin.stop(`Could not load workspaces`),note(String(err instanceof Error?err.message:err),`Error`),null}if(tenants.length===0){let wsNameInput=await text({message:`Create your first workspace:`,initialValue:params.defaultInstanceName});if(typeof wsNameInput==`symbol`||!wsNameInput.trim())return null;let wsSpin=spinner();wsSpin.start(`Creating workspace…`);try{let created=await builderforceApiFetch(`${serverUrl}/api/tenants`,{method:`POST`,token:webToken,body:JSON.stringify({name:wsNameInput.trim()})});tenantId=created.id,wsSpin.stop(`Workspace "${created.name}" created`)}catch(err){return wsSpin.stop(`Could not create workspace`),note(String(err instanceof Error?err.message:err),`Error`),null}}else if(tenants.length===1)tenantId=tenants[0].id,note(`Using workspace: ${tenants[0].name}`,`Workspace`);else{let picked=await select({message:`Select workspace:`,options:tenants.map(tenant=>({value:tenant.id,label:tenant.name,hint:tenant.slug}))});if(typeof picked==`symbol`)return null;tenantId=picked}let tenantJwt=``;try{tenantJwt=(await builderforceApiFetch(`${serverUrl}/api/auth/tenant-token`,{method:`POST`,token:webToken,body:JSON.stringify({tenantId})})).token}catch(err){return note(String(err instanceof Error?err.message:err),`Could not get workspace token`),null}let agentNodeNameInput=await text({message:`AgentNode instance name (shown in dashboard):`,initialValue:params.defaultInstanceName});if(typeof agentNodeNameInput==`symbol`)return null;let agentNodeName=agentNodeNameInput.trim()||params.defaultInstanceName,agentNodeSpin=spinner();agentNodeSpin.start(`Registering agentNode instance…`);let agentNodeId=``,agentNodeSlug=``,apiKey=``,projectId=``,projectAction=`unknown`,machineProfile=buildLocalMachineProfile({workspaceDirectory:params.projectRoot,rootInstallDirectory:process.cwd(),gatewayPort:18789,tunnelUrl:process.env.BUILDERFORCE_AGENTS_PUBLIC_TUNNEL_URL,tunnelStatus:process.env.BUILDERFORCE_AGENTS_PUBLIC_TUNNEL_URL?`connected`:`none`});try{let res=await builderforceApiFetch(`${serverUrl}/api/agent-hosts`,{method:`POST`,token:tenantJwt,body:JSON.stringify({name:agentNodeName,machineProfile})});agentNodeId=String(res.agentHost.id),agentNodeSlug=res.agentHost.slug,apiKey=res.apiKey;let mapped=await ensureProjectMapping({serverUrl,tenantJwt,agentNodeId,projectRoot:params.projectRoot,projectName:params.defaultInstanceName,description:`builderForceAgents project at ${params.projectRoot}`});mapped&&(projectId=mapped.projectId,projectAction=mapped.action),agentNodeSpin.stop(`AgentNode "${res.agentHost.name}" registered`)}catch(err){return agentNodeSpin.stop(`AgentNode registration failed`),note(String(err instanceof Error?err.message:err),`Error`),null}upsertSharedEnvVar({key:`BUILDERFORCE_URL`,value:serverUrl}),upsertSharedEnvVar({key:`BUILDERFORCE_WEB_TOKEN`,value:webToken}),upsertSharedEnvVar({key:`BUILDERFORCE_TENANT_ID`,value:String(tenantId)}),upsertSharedEnvVar({key:`BUILDERFORCE_API_KEY`,value:apiKey}),upsertSharedEnvVar({key:`BUILDERFORCE_SKIPPED`,value:`0`});try{await updateProjectContextFields(params.projectRoot,{builderforce:{instanceId:agentNodeId,instanceSlug:agentNodeSlug,instanceName:agentNodeName,...projectId?{projectId}:{},tenantId,url:serverUrl,machineProfile}})}catch{}return note([`AgentNode API key saved to ~/.builderforce/.env`,`This key was shown once — it is hashed on the server.`,`Instance slug: ${agentNodeSlug} · tenant: ${tenantId}`,projectId?`Project ${projectAction}: ${projectId}`:`Project mapping: not available`].join(`
24
24
  `),`Builderforce connected`),`Builderforce: ${agentNodeName} (${agentNodeSlug}) on tenant ${tenantId}`}export{promptBuilderforceOnboarding};
@@ -1,2 +1,2 @@
1
- import"../../paths-BVMSM1lQ.js";import{d as resolveAgentIdFromSessionKey,l as normalizeAgentId,u as normalizeMainKey}from"../../session-key-CYpYHc1e.js";import{r as DEFAULT_CHAT_CHANNEL}from"../../registry-D_frpmHZ.js";import{a as resolveAgentModelPrimary,l as resolveEffectiveModelFallbacks,o as resolveAgentSkillsFilter,r as resolveAgentDir,s as resolveAgentWorkspaceDir,t as listAgentIds,u as resolveSessionAgentId}from"../../agent-scope-EkacNLg3.js";import{r as defaultRuntime,t as createSubsystemLogger}from"../../subsystem-BakM_oqD.js";import{h as resolveWorkspaceFilePath,l as ensureAgentWorkspace}from"../../workspace-BCjtHT4u.js";import{Ct as DEFAULT_CONTEXT_TOKENS,Tt as DEFAULT_PROVIDER,a as isCliProvider,d as resolveConfiguredModelRef,g as resolveThinkingDefault,mt as ensureAuthProfileStore,o as modelKey,s as normalizeModelRef,t as buildAllowedModelSet,wt as DEFAULT_MODEL}from"../../model-selection-BJ0saFZo.js";import{n as formatCliCommand}from"../../env-BhRm7_r8.js";import"../../boolean-ssGoaBPk.js";import"../../src-CLWuGn12.js";import{A as clearSessionAuthProfileOverride,C as deriveSessionTotalTokens,D as getRemoteSkillEligibility,E as resolveSendPolicy,G as formatOutboundPayloadLog,J as clearAgentRunContext,K as normalizeOutboundPayloads,M as applyVerboseOverride,O as getSkillsSnapshotVersion,U as resolveAgentTimeoutMs,W as deliverOutboundPayloads,X as registerAgentRunContext,Y as emitAgentEvent,Z as runWithModelFallback,_ as resolveOutboundTarget,b as AGENT_LANE_SUBAGENT,g as runCliAgent,h as setCliSessionId,j as applyModelOverrideToSessionEntry,k as lookupContextTokens,m as getCliSessionId,q as normalizeOutboundPayloadsForJson,t as runEmbeddedAgent,v as resolveSessionDeliveryTarget,w as hasNonzeroUsage,y as AGENT_LANE_NESTED}from"../../embedded-DXDHduG1.js";import{s as SILENT_REPLY_TOKEN}from"../../replies-BG-eHErp.js";import{r as normalizeChannelId,t as getChannelPlugin}from"../../plugins-J28Y83f5.js";import"../../accounts-193gfWbH.js";import"../../bindings-BfB5A-by.js";import"../../send-DcxNvcKU.js";import"../../send-d9H-BT6p.js";import"../../accounts-DHeA4T6C.js";import"../../send-BxVr1pPI.js";import"../../fetch-BklyLYYN.js";import{n as loadModelCatalog}from"../../model-catalog-Abk8cdEI.js";import"../../redact-sNZY-pGx.js";import"../../errors-BmztzL5I.js";import{$t as resolveChannelResetConfig,An as buildWorkspaceSkillSnapshot,H as normalizeThinkLevel,Ht as normalizeAccountId,K as supportsXHighThinking,L as formatThinkingLevels,Nt as updateSessionStore,Qt as evaluateSessionFreshness,R as formatXHighModelHint,W as normalizeVerboseLevel,Zt as resolveSessionKey,en as resolveSessionResetPolicy,kt as loadSessionStore,on as resolveExplicitAgentSessionKey,sn as resolveMainSessionKey,tn as resolveSessionResetType}from"../../runner-B70PGCqP.js";import{n as loadConfig}from"../../config-bxyMjPHU.js";import"../../chrome-Blk2Jftn.js";import"../../frontmatter-DBVosMFY.js";import"../../store-DN9AcI73.js";import{i as isInternalMessageChannel,l as resolveMessageChannel,n as isDeliverableMessageChannel,r as isGatewayMessageChannel,s as normalizeMessageChannel,t as INTERNAL_MESSAGE_CHANNEL}from"../../message-channel-tBuQgYSD.js";import"../../accounts-C7FtIPYB.js";import{n as resolveSessionFilePath,s as resolveStorePath}from"../../paths-CzXKnIOb.js";import"../../gemini-auth-CzGGgJ0p.js";import"../../tool-images-mfC2sOfJ.js";import"../../config-DfXnxW-V.js";import"../../reply-prefix-me5vnbrB.js";import"../../sqlite-D3Ov16zb.js";import"../../manager-BdFSM6B3.js";import"../../retry-BYnMCvOU.js";import"../../common-CDXsNQYT.js";import"../../chunk-CrsAQ01n.js";import"../../markdown-tables-DvSC1OTb.js";import"../../ir-Ct8GNKB7.js";import"../../render-CVWbhuqU.js";import"../../send-ZeI8StQK.js";import"../../outbound-attachment-U-XtahS5.js";import"../../fetch-Jq1KZsRq.js";import"../../send-CqER7CIV.js";import"../../resolve-route-CGe48x_Z.js";import"../../channel-activity-xLea9vdo.js";import"../../tables-Desw59m6.js";import"../../active-listener-BQLkI7vg.js";import fs from"node:fs/promises";import crypto from"node:crypto";function createDefaultDeps(){return{sendMessageWhatsApp:async(...args)=>{let{sendMessageWhatsApp}=await import(`../../web-D44jKC1F.js`);return await sendMessageWhatsApp(...args)},sendMessageTelegram:async(...args)=>{let{sendMessageTelegram}=await import(`../../send-BxVr1pPI.js`).then(n=>n.l);return await sendMessageTelegram(...args)},sendMessageDiscord:async(...args)=>{let{sendMessageDiscord}=await import(`../../send-d9H-BT6p.js`).then(n=>n.t);return await sendMessageDiscord(...args)},sendMessageSlack:async(...args)=>{let{sendMessageSlack}=await import(`../../send-DcxNvcKU.js`).then(n=>n.n);return await sendMessageSlack(...args)},sendMessageSignal:async(...args)=>{let{sendMessageSignal}=await import(`../../send-ZeI8StQK.js`).then(n=>n.i);return await sendMessageSignal(...args)},sendMessageIMessage:async(...args)=>{let{sendMessageIMessage}=await import(`../../send-CqER7CIV.js`).then(n=>n.n);return await sendMessageIMessage(...args)}}}function createOutboundSendDeps(deps){return{sendWhatsApp:deps.sendMessageWhatsApp,sendTelegram:deps.sendMessageTelegram,sendDiscord:deps.sendMessageDiscord,sendSlack:deps.sendMessageSlack,sendSignal:deps.sendMessageSignal,sendIMessage:deps.sendMessageIMessage}}function resolveAgentDeliveryPlan(params){let requestedRaw=typeof params.requestedChannel==`string`?params.requestedChannel.trim():``,requestedChannel=(requestedRaw?normalizeMessageChannel(requestedRaw):void 0)||`last`,explicitTo=typeof params.explicitTo==`string`&&params.explicitTo.trim()?params.explicitTo.trim():void 0,baseDelivery=resolveSessionDeliveryTarget({entry:params.sessionEntry,requestedChannel:requestedChannel===INTERNAL_MESSAGE_CHANNEL?`last`:requestedChannel,explicitTo,explicitThreadId:params.explicitThreadId}),resolvedChannel=requestedChannel===INTERNAL_MESSAGE_CHANNEL?INTERNAL_MESSAGE_CHANNEL:requestedChannel===`last`?baseDelivery.channel&&baseDelivery.channel!==INTERNAL_MESSAGE_CHANNEL?baseDelivery.channel:params.wantsDelivery?DEFAULT_CHAT_CHANNEL:INTERNAL_MESSAGE_CHANNEL:isGatewayMessageChannel(requestedChannel)?requestedChannel:baseDelivery.channel&&baseDelivery.channel!==INTERNAL_MESSAGE_CHANNEL?baseDelivery.channel:params.wantsDelivery?DEFAULT_CHAT_CHANNEL:INTERNAL_MESSAGE_CHANNEL,deliveryTargetMode=explicitTo?`explicit`:isDeliverableMessageChannel(resolvedChannel)?`implicit`:void 0,resolvedAccountId=normalizeAccountId(params.accountId)??(deliveryTargetMode===`implicit`?baseDelivery.accountId:void 0),resolvedTo=explicitTo;return!resolvedTo&&isDeliverableMessageChannel(resolvedChannel)&&resolvedChannel===baseDelivery.lastChannel&&(resolvedTo=baseDelivery.lastTo),{baseDelivery,resolvedChannel,resolvedTo,resolvedAccountId,resolvedThreadId:baseDelivery.threadId,deliveryTargetMode}}function resolveAgentOutboundTarget(params){let targetMode=params.targetMode??params.plan.deliveryTargetMode??(params.plan.resolvedTo?`explicit`:`implicit`);if(!isDeliverableMessageChannel(params.plan.resolvedChannel)||params.validateExplicitTarget!==!0&&params.plan.resolvedTo)return{resolvedTarget:null,resolvedTo:params.plan.resolvedTo,targetMode};let resolvedTarget=resolveOutboundTarget({channel:params.plan.resolvedChannel,to:params.plan.resolvedTo,cfg:params.cfg,accountId:params.plan.resolvedAccountId,mode:targetMode});return{resolvedTarget,resolvedTo:resolvedTarget.ok?resolvedTarget.to:params.plan.resolvedTo,targetMode}}const isOutboundPayloadJson=payload=>`mediaUrl`in payload;function buildOutboundResultEnvelope(params){let hasPayloads=params.payloads!==void 0,payloads=params.payloads===void 0?void 0:params.payloads.length===0?[]:isOutboundPayloadJson(params.payloads[0])?params.payloads:normalizeOutboundPayloadsForJson(params.payloads);return params.flattenDelivery!==!1&&params.delivery&&!params.meta&&!hasPayloads?params.delivery:{...hasPayloads?{payloads}:{},...params.meta?{meta:params.meta}:{},...params.delivery?{delivery:params.delivery}:{}}}function formatNestedLogPrefix(opts){let parts=[`[agent:nested]`],session=opts.sessionKey??opts.sessionId;session&&parts.push(`session=${session}`),opts.runId&&parts.push(`run=${opts.runId}`);let channel=opts.messageChannel??opts.channel;return channel&&parts.push(`channel=${channel}`),opts.to&&parts.push(`to=${opts.to}`),opts.accountId&&parts.push(`account=${opts.accountId}`),parts.join(` `)}function logNestedOutput(runtime,opts,output){let prefix=formatNestedLogPrefix(opts);for(let line of output.split(/\r?\n/))line&&runtime.log(`${prefix} ${line}`)}async function deliverAgentCommandResult(params){let{cfg,deps,runtime,opts,sessionEntry,payloads,result}=params,deliver=opts.deliver===!0,bestEffortDeliver=opts.bestEffortDeliver===!0,deliveryPlan=resolveAgentDeliveryPlan({sessionEntry,requestedChannel:opts.replyChannel??opts.channel,explicitTo:opts.replyTo??opts.to,explicitThreadId:opts.threadId,accountId:opts.replyAccountId??opts.accountId,wantsDelivery:deliver}),deliveryChannel=deliveryPlan.resolvedChannel,deliveryPlugin=isInternalMessageChannel(deliveryChannel)?void 0:getChannelPlugin(normalizeChannelId(deliveryChannel)??deliveryChannel),isDeliveryChannelKnown=isInternalMessageChannel(deliveryChannel)||!!deliveryPlugin,targetMode=opts.deliveryTargetMode??deliveryPlan.deliveryTargetMode??(opts.to?`explicit`:`implicit`),resolvedAccountId=deliveryPlan.resolvedAccountId,resolved=deliver&&isDeliveryChannelKnown&&deliveryChannel?resolveAgentOutboundTarget({cfg,plan:deliveryPlan,targetMode,validateExplicitTarget:!0}):{resolvedTarget:null,resolvedTo:deliveryPlan.resolvedTo,targetMode},resolvedTarget=resolved.resolvedTarget,deliveryTarget=resolved.resolvedTo,resolvedThreadId=deliveryPlan.resolvedThreadId??opts.threadId,resolvedReplyToId=deliveryChannel===`slack`&&resolvedThreadId!=null?String(resolvedThreadId):void 0,resolvedThreadTarget=deliveryChannel===`slack`?void 0:resolvedThreadId,logDeliveryError=err=>{let message=`Delivery failed (${deliveryChannel}${deliveryTarget?` to ${deliveryTarget}`:``}): ${String(err)}`;runtime.error?.(message),runtime.error||runtime.log(message)};if(deliver){if(!isDeliveryChannelKnown){let err=Error(`Unknown channel: ${deliveryChannel}`);if(!bestEffortDeliver)throw err;logDeliveryError(err)}else if(resolvedTarget&&!resolvedTarget.ok){if(!bestEffortDeliver)throw resolvedTarget.error;logDeliveryError(resolvedTarget.error)}}let normalizedPayloads=normalizeOutboundPayloadsForJson(payloads??[]);if(opts.json&&(runtime.log(JSON.stringify(buildOutboundResultEnvelope({payloads:normalizedPayloads,meta:result.meta}),null,2)),!deliver))return{payloads:normalizedPayloads,meta:result.meta};if(!payloads||payloads.length===0)return runtime.log(`No reply from agent.`),{payloads:[],meta:result.meta};let deliveryPayloads=normalizeOutboundPayloads(payloads),logPayload=payload=>{if(opts.json)return;let output=formatOutboundPayloadLog(payload);if(output){if(opts.lane===AGENT_LANE_NESTED){logNestedOutput(runtime,opts,output);return}runtime.log(output)}};if(!deliver)for(let payload of deliveryPayloads)logPayload(payload);return deliver&&deliveryChannel&&!isInternalMessageChannel(deliveryChannel)&&deliveryTarget&&await deliverOutboundPayloads({cfg,channel:deliveryChannel,to:deliveryTarget,accountId:resolvedAccountId,payloads:deliveryPayloads,agentId:opts.agentId??(opts.sessionKey?resolveSessionAgentId({sessionKey:opts.sessionKey,config:cfg}):void 0),replyToId:resolvedReplyToId??null,threadId:resolvedThreadTarget??null,bestEffort:bestEffortDeliver,onError:err=>logDeliveryError(err),onPayload:logPayload,deps:createOutboundSendDeps(deps)}),{payloads:normalizedPayloads,meta:result.meta}}function resolveAgentRunContext(opts){let merged=opts.runContext?{...opts.runContext}:{},normalizedChannel=resolveMessageChannel(merged.messageChannel??opts.messageChannel,opts.replyChannel??opts.channel);normalizedChannel&&(merged.messageChannel=normalizedChannel);let normalizedAccountId=normalizeAccountId(merged.accountId??opts.accountId);normalizedAccountId&&(merged.accountId=normalizedAccountId);let groupId=(merged.groupId??opts.groupId)?.toString().trim();groupId&&(merged.groupId=groupId);let groupChannel=(merged.groupChannel??opts.groupChannel)?.toString().trim();groupChannel&&(merged.groupChannel=groupChannel);let groupSpace=(merged.groupSpace??opts.groupSpace)?.toString().trim();if(groupSpace&&(merged.groupSpace=groupSpace),merged.currentThreadTs==null&&opts.threadId!=null&&opts.threadId!==``&&opts.threadId!==null&&(merged.currentThreadTs=String(opts.threadId)),!merged.currentChannelId&&opts.to){let trimmedTo=opts.to.trim();trimmedTo&&(merged.currentChannelId=trimmedTo)}return merged}async function updateSessionStoreAfterAgentRun(params){let{cfg,sessionId,sessionKey,storePath,sessionStore,defaultProvider,defaultModel,fallbackProvider,fallbackModel,result}=params,usage=result.meta.agentMeta?.usage,promptTokens=result.meta.agentMeta?.promptTokens,compactionsThisRun=Math.max(0,result.meta.agentMeta?.compactionCount??0),modelUsed=result.meta.agentMeta?.model??fallbackModel??defaultModel,providerUsed=result.meta.agentMeta?.provider??fallbackProvider??defaultProvider,contextTokens=params.contextTokensOverride??lookupContextTokens(modelUsed)??DEFAULT_CONTEXT_TOKENS,entry=sessionStore[sessionKey]??{sessionId,updatedAt:Date.now()},next={...entry,sessionId,updatedAt:Date.now(),modelProvider:providerUsed,model:modelUsed,contextTokens};if(isCliProvider(providerUsed,cfg)){let cliSessionId=result.meta.agentMeta?.sessionId?.trim();cliSessionId&&setCliSessionId(next,providerUsed,cliSessionId)}if(next.abortedLastRun=result.meta.aborted??!1,hasNonzeroUsage(usage)){let input=usage.input??0,output=usage.output??0,totalTokens=deriveSessionTotalTokens({usage,contextTokens,promptTokens})??input;next.inputTokens=input,next.outputTokens=output,next.totalTokens=totalTokens,next.totalTokensFresh=!0}compactionsThisRun>0&&(next.compactionCount=(entry.compactionCount??0)+compactionsThisRun),sessionStore[sessionKey]=next,await updateSessionStore(storePath,store=>{store[sessionKey]=next})}function resolveSessionKeyForRequest(opts){let sessionCfg=opts.cfg.session,scope=sessionCfg?.scope??`per-sender`,mainKey=normalizeMainKey(sessionCfg?.mainKey),explicitSessionKey=opts.sessionKey?.trim()||resolveExplicitAgentSessionKey({cfg:opts.cfg,agentId:opts.agentId}),storeAgentId=resolveAgentIdFromSessionKey(explicitSessionKey),storePath=resolveStorePath(sessionCfg?.store,{agentId:storeAgentId}),sessionStore=loadSessionStore(storePath),ctx=opts.to?.trim()?{From:opts.to}:void 0,sessionKey=explicitSessionKey??(ctx?resolveSessionKey(scope,ctx,mainKey):void 0);if(!explicitSessionKey&&opts.sessionId&&(!sessionKey||sessionStore[sessionKey]?.sessionId!==opts.sessionId)){let foundKey=Object.keys(sessionStore).find(key=>sessionStore[key]?.sessionId===opts.sessionId);foundKey&&(sessionKey=foundKey)}if(opts.sessionId&&!explicitSessionKey&&(!sessionKey||sessionStore[sessionKey]?.sessionId!==opts.sessionId)){let allAgentIds=listAgentIds(opts.cfg);for(let agentId of allAgentIds){if(agentId===storeAgentId)continue;let altStorePath=resolveStorePath(sessionCfg?.store,{agentId}),altStore=loadSessionStore(altStorePath),foundKey=Object.keys(altStore).find(key=>altStore[key]?.sessionId===opts.sessionId);if(foundKey)return{sessionKey:foundKey,sessionStore:altStore,storePath:altStorePath}}}return{sessionKey,sessionStore,storePath}}function resolveSession(opts){let sessionCfg=opts.cfg.session,{sessionKey,sessionStore,storePath}=resolveSessionKeyForRequest({cfg:opts.cfg,to:opts.to,sessionId:opts.sessionId,sessionKey:opts.sessionKey,agentId:opts.agentId}),now=Date.now(),sessionEntry=sessionKey?sessionStore[sessionKey]:void 0,resetPolicy=resolveSessionResetPolicy({sessionCfg,resetType:resolveSessionResetType({sessionKey}),resetOverride:resolveChannelResetConfig({sessionCfg,channel:sessionEntry?.lastChannel??sessionEntry?.channel})}),fresh=sessionEntry?evaluateSessionFreshness({updatedAt:sessionEntry.updatedAt,now,policy:resetPolicy}).fresh:!1;return{sessionId:opts.sessionId?.trim()||(fresh?sessionEntry?.sessionId:void 0)||crypto.randomUUID(),sessionKey,sessionEntry,sessionStore,storePath,isNewSession:!fresh&&!opts.sessionId,persistedThinking:fresh&&sessionEntry?.thinkingLevel?normalizeThinkLevel(sessionEntry.thinkingLevel):void 0,persistedVerbose:fresh&&sessionEntry?.verboseLevel?normalizeVerboseLevel(sessionEntry.verboseLevel):void 0}}async function persistSessionEntry(params){params.sessionStore[params.sessionKey]=params.entry,await updateSessionStore(params.storePath,store=>{store[params.sessionKey]=params.entry})}function resolveFallbackRetryPrompt(params){return params.isFallbackRetry?`Continue where you left off. The previous model attempt failed or timed out.`:params.body}function runAgentAttempt(params){let effectivePrompt=resolveFallbackRetryPrompt({body:params.body,isFallbackRetry:params.isFallbackRetry});if(isCliProvider(params.providerOverride,params.cfg)){let cliSessionId=getCliSessionId(params.sessionEntry,params.providerOverride);return runCliAgent({sessionId:params.sessionId,sessionKey:params.sessionKey,agentId:params.sessionAgentId,sessionFile:params.sessionFile,workspaceDir:params.workspaceDir,config:params.cfg,prompt:effectivePrompt,provider:params.providerOverride,model:params.modelOverride,thinkLevel:params.resolvedThinkLevel,timeoutMs:params.timeoutMs,runId:params.runId,extraSystemPrompt:params.opts.extraSystemPrompt,cliSessionId,images:params.isFallbackRetry?void 0:params.opts.images,streamParams:params.opts.streamParams})}let authProfileId=params.providerOverride===params.primaryProvider?params.sessionEntry?.authProfileOverride:void 0;return runEmbeddedAgent({sessionId:params.sessionId,sessionKey:params.sessionKey,agentId:params.sessionAgentId,messageChannel:params.messageChannel,agentAccountId:params.runContext.accountId,messageTo:params.opts.replyTo??params.opts.to,messageThreadId:params.opts.threadId,groupId:params.runContext.groupId,groupChannel:params.runContext.groupChannel,groupSpace:params.runContext.groupSpace,spawnedBy:params.spawnedBy,currentChannelId:params.runContext.currentChannelId,currentThreadTs:params.runContext.currentThreadTs,replyToMode:params.runContext.replyToMode,hasRepliedRef:params.runContext.hasRepliedRef,senderIsOwner:!0,sessionFile:params.sessionFile,workspaceDir:params.workspaceDir,config:params.cfg,skillsSnapshot:params.skillsSnapshot,prompt:effectivePrompt,images:params.isFallbackRetry?void 0:params.opts.images,clientTools:params.opts.clientTools,provider:params.providerOverride,model:params.modelOverride,authProfileId,authProfileIdSource:authProfileId?params.sessionEntry?.authProfileOverrideSource:void 0,thinkLevel:params.resolvedThinkLevel,verboseLevel:params.resolvedVerboseLevel,timeoutMs:params.timeoutMs,runId:params.runId,lane:params.opts.lane,abortSignal:params.opts.abortSignal,extraSystemPrompt:params.opts.extraSystemPrompt,inputProvenance:params.opts.inputProvenance,streamParams:params.opts.streamParams,agentDir:params.agentDir,onAgentEvent:params.onAgentEvent})}async function agentCommand(opts,runtime=defaultRuntime,deps=createDefaultDeps()){let body=(opts.message??``).trim();if(!body)throw Error(`Message (--message) is required`);if(!opts.to&&!opts.sessionId&&!opts.sessionKey&&!opts.agentId)throw Error(`Pass --to <E.164>, --session-id, or --agent to choose a session`);let cfg=loadConfig(),agentIdOverrideRaw=opts.agentId?.trim(),agentIdOverride=agentIdOverrideRaw?normalizeAgentId(agentIdOverrideRaw):void 0;if(agentIdOverride&&!listAgentIds(cfg).includes(agentIdOverride))throw Error(`Unknown agent id "${agentIdOverrideRaw}". Use "${formatCliCommand(`builderforce agents list`)}" to see configured agents.`);if(agentIdOverride&&opts.sessionKey){let sessionAgentId=resolveAgentIdFromSessionKey(opts.sessionKey);if(sessionAgentId!==agentIdOverride)throw Error(`Agent id "${agentIdOverrideRaw}" does not match session key agent "${sessionAgentId}".`)}let agentCfg=cfg.agents?.defaults,sessionAgentId=agentIdOverride??resolveAgentIdFromSessionKey(opts.sessionKey?.trim()),workspaceDirRaw=resolveAgentWorkspaceDir(cfg,sessionAgentId),agentDir=resolveAgentDir(cfg,sessionAgentId),workspaceDir=(await ensureAgentWorkspace({dir:workspaceDirRaw,ensureBootstrapFiles:!agentCfg?.skipBootstrap})).dir,configuredModel=resolveConfiguredModelRef({cfg,defaultProvider:DEFAULT_PROVIDER,defaultModel:DEFAULT_MODEL}),thinkingLevelsHint=formatThinkingLevels(configuredModel.provider,configuredModel.model),thinkOverride=normalizeThinkLevel(opts.thinking),thinkOnce=normalizeThinkLevel(opts.thinkingOnce);if(opts.thinking&&!thinkOverride)throw Error(`Invalid thinking level. Use one of: ${thinkingLevelsHint}.`);if(opts.thinkingOnce&&!thinkOnce)throw Error(`Invalid one-shot thinking level. Use one of: ${thinkingLevelsHint}.`);let verboseOverride=normalizeVerboseLevel(opts.verbose);if(opts.verbose&&!verboseOverride)throw Error(`Invalid verbose level. Use "on", "full", or "off".`);let isSubagentLane=(typeof opts.lane==`string`?opts.lane.trim():``)===String(AGENT_LANE_SUBAGENT),timeoutSecondsRaw=opts.timeout===void 0?isSubagentLane?0:void 0:Number.parseInt(String(opts.timeout),10);if(timeoutSecondsRaw!==void 0&&(Number.isNaN(timeoutSecondsRaw)||timeoutSecondsRaw<0))throw Error(`--timeout must be a non-negative integer (seconds; 0 means no timeout)`);let timeoutMs=resolveAgentTimeoutMs({cfg,overrideSeconds:timeoutSecondsRaw}),{sessionId,sessionKey,sessionEntry:resolvedSessionEntry,sessionStore,storePath,isNewSession,persistedThinking,persistedVerbose}=resolveSession({cfg,to:opts.to,sessionId:opts.sessionId,sessionKey:opts.sessionKey,agentId:agentIdOverride}),sessionEntry=resolvedSessionEntry,runId=opts.runId?.trim()||sessionId;try{if(opts.deliver===!0&&resolveSendPolicy({cfg,entry:sessionEntry,sessionKey,channel:sessionEntry?.channel,chatType:sessionEntry?.chatType})===`deny`)throw Error(`send blocked by session policy`);let resolvedThinkLevel=thinkOnce??thinkOverride??persistedThinking??agentCfg?.thinkingDefault,resolvedVerboseLevel=verboseOverride??persistedVerbose??agentCfg?.verboseDefault??`on`;sessionKey&&registerAgentRunContext(runId,{sessionKey,verboseLevel:resolvedVerboseLevel});let needsSkillsSnapshot=isNewSession||!sessionEntry?.skillsSnapshot,skillsSnapshotVersion=getSkillsSnapshotVersion(workspaceDir),skillFilter=resolveAgentSkillsFilter(cfg,sessionAgentId),skillsSnapshot=needsSkillsSnapshot?buildWorkspaceSkillSnapshot(workspaceDir,{config:cfg,eligibility:{remote:getRemoteSkillEligibility()},snapshotVersion:skillsSnapshotVersion,skillFilter}):sessionEntry?.skillsSnapshot;if(skillsSnapshot&&sessionStore&&sessionKey&&needsSkillsSnapshot){let next={...sessionEntry??{sessionId,updatedAt:Date.now()},sessionId,updatedAt:Date.now(),skillsSnapshot};await persistSessionEntry({sessionStore,sessionKey,storePath,entry:next}),sessionEntry=next}if(sessionStore&&sessionKey){let next={...sessionStore[sessionKey]??sessionEntry??{sessionId,updatedAt:Date.now()},sessionId,updatedAt:Date.now()};thinkOverride&&(next.thinkingLevel=thinkOverride),applyVerboseOverride(next,verboseOverride),await persistSessionEntry({sessionStore,sessionKey,storePath,entry:next})}let agentModelPrimary=resolveAgentModelPrimary(cfg,sessionAgentId),configuredDefaultRef=resolveConfiguredModelRef({cfg:agentModelPrimary?{...cfg,agents:{...cfg.agents,defaults:{...cfg.agents?.defaults,model:{...typeof cfg.agents?.defaults?.model==`object`?cfg.agents.defaults.model:void 0,primary:agentModelPrimary}}}}:cfg,defaultProvider:DEFAULT_PROVIDER,defaultModel:DEFAULT_MODEL}),{provider:defaultProvider,model:defaultModel}=normalizeModelRef(configuredDefaultRef.provider,configuredDefaultRef.model),provider=defaultProvider,model=defaultModel,hasAllowlist=agentCfg?.models&&Object.keys(agentCfg.models).length>0,hasStoredOverride=!!(sessionEntry?.modelOverride||sessionEntry?.providerOverride),needsModelCatalog=hasAllowlist||hasStoredOverride,allowedModelKeys=new Set,allowedModelCatalog=[],modelCatalog=null;if(needsModelCatalog){modelCatalog=await loadModelCatalog({config:cfg});let allowed=buildAllowedModelSet({cfg,catalog:modelCatalog,defaultProvider,defaultModel});allowedModelKeys=allowed.allowedKeys,allowedModelCatalog=allowed.allowedCatalog}if(sessionEntry&&sessionStore&&sessionKey&&hasStoredOverride){let entry=sessionEntry,overrideProvider=sessionEntry.providerOverride?.trim()||defaultProvider,overrideModel=sessionEntry.modelOverride?.trim();if(overrideModel){let normalizedOverride=normalizeModelRef(overrideProvider,overrideModel),key=modelKey(normalizedOverride.provider,normalizedOverride.model);if(!isCliProvider(normalizedOverride.provider,cfg)&&allowedModelKeys.size>0&&!allowedModelKeys.has(key)){let{updated}=applyModelOverrideToSessionEntry({entry,selection:{provider:defaultProvider,model:defaultModel,isDefault:!0}});updated&&await persistSessionEntry({sessionStore,sessionKey,storePath,entry})}}}let storedProviderOverride=sessionEntry?.providerOverride?.trim(),storedModelOverride=sessionEntry?.modelOverride?.trim();if(storedModelOverride){let normalizedStored=normalizeModelRef(storedProviderOverride||defaultProvider,storedModelOverride),key=modelKey(normalizedStored.provider,normalizedStored.model);(isCliProvider(normalizedStored.provider,cfg)||allowedModelKeys.size===0||allowedModelKeys.has(key))&&(provider=normalizedStored.provider,model=normalizedStored.model)}if(sessionEntry){let authProfileId=sessionEntry.authProfileOverride;if(authProfileId){let entry=sessionEntry,profile=(await ensureAuthProfileStore()).profiles[authProfileId];(!profile||profile.provider!==provider)&&sessionStore&&sessionKey&&await clearSessionAuthProfileOverride({sessionEntry:entry,sessionStore,sessionKey,storePath})}}if(!resolvedThinkLevel){let catalogForThinking=modelCatalog??allowedModelCatalog;(!catalogForThinking||catalogForThinking.length===0)&&(modelCatalog=await loadModelCatalog({config:cfg}),catalogForThinking=modelCatalog),resolvedThinkLevel=resolveThinkingDefault({cfg,provider,model,catalog:catalogForThinking})}if(resolvedThinkLevel===`xhigh`&&!supportsXHighThinking(provider,model)){if(thinkOnce||thinkOverride)throw Error(`Thinking level "xhigh" is only supported for ${formatXHighModelHint()}.`);if(resolvedThinkLevel=`high`,sessionEntry&&sessionStore&&sessionKey&&sessionEntry.thinkingLevel===`xhigh`){let entry=sessionEntry;entry.thinkingLevel=`high`,entry.updatedAt=Date.now(),await persistSessionEntry({sessionStore,sessionKey,storePath,entry})}}let sessionFile=resolveSessionFilePath(sessionId,sessionEntry,{agentId:sessionAgentId}),startedAt=Date.now(),lifecycleEnded=!1,result,fallbackProvider=provider,fallbackModel=model;try{let runContext=resolveAgentRunContext(opts),messageChannel=resolveMessageChannel(runContext.messageChannel,opts.replyChannel??opts.channel),spawnedBy=opts.spawnedBy??sessionEntry?.spawnedBy,effectiveFallbacksOverride=resolveEffectiveModelFallbacks({cfg,agentId:sessionAgentId,hasSessionModelOverride:!!storedModelOverride}),fallbackAttemptIndex=0,fallbackResult=await runWithModelFallback({cfg,provider,model,agentDir,fallbacksOverride:effectiveFallbacksOverride,run:(providerOverride,modelOverride)=>{let isFallbackRetry=fallbackAttemptIndex>0;return fallbackAttemptIndex+=1,runAgentAttempt({providerOverride,modelOverride,cfg,sessionEntry,sessionId,sessionKey,sessionAgentId,sessionFile,workspaceDir,body,isFallbackRetry,resolvedThinkLevel,timeoutMs,runId,opts,runContext,spawnedBy,messageChannel,skillsSnapshot,resolvedVerboseLevel,agentDir,primaryProvider:provider,onAgentEvent:evt=>{evt.stream===`lifecycle`&&typeof evt.data?.phase==`string`&&(evt.data.phase===`end`||evt.data.phase===`error`)&&(lifecycleEnded=!0)}})}});result=fallbackResult.result,fallbackProvider=fallbackResult.provider,fallbackModel=fallbackResult.model,lifecycleEnded||emitAgentEvent({runId,stream:`lifecycle`,data:{phase:`end`,startedAt,endedAt:Date.now(),aborted:result.meta.aborted??!1}})}catch(err){throw lifecycleEnded||emitAgentEvent({runId,stream:`lifecycle`,data:{phase:`error`,startedAt,endedAt:Date.now(),error:String(err)}}),err}sessionStore&&sessionKey&&await updateSessionStoreAfterAgentRun({cfg,contextTokensOverride:agentCfg?.contextTokens,sessionId,sessionKey,storePath,sessionStore,defaultProvider:provider,defaultModel:model,fallbackProvider,fallbackModel,result});let payloads=result.payloads??[];return await deliverAgentCommandResult({cfg,deps,runtime,opts,sessionEntry,result,payloads})}finally{clearAgentRunContext(runId)}}function generateBootSessionId(){return`boot-${new Date().toISOString().replace(/[:.]/g,`-`).replace(`T`,`_`).replace(`Z`,``)}-${crypto.randomUUID().slice(0,8)}`}const log=createSubsystemLogger(`gateway/boot`),BOOT_FILENAME=`BOOT.md`;function buildBootPrompt(content){return[`You are running a boot check. Follow BOOT.md instructions exactly.`,``,`BOOT.md:`,content,``,`If BOOT.md asks you to send a message, use the message tool (action=send with channel + target).`,"Use the `target` field (not `to`) for message tool destinations.",`After sending with the message tool, reply with ONLY: ${SILENT_REPLY_TOKEN}.`,`If nothing needs attention, reply with ONLY: ${SILENT_REPLY_TOKEN}.`].join(`
1
+ import"../../paths-BVMSM1lQ.js";import{d as resolveAgentIdFromSessionKey,l as normalizeAgentId,u as normalizeMainKey}from"../../session-key-CYpYHc1e.js";import{r as DEFAULT_CHAT_CHANNEL}from"../../registry-D_frpmHZ.js";import{a as resolveAgentModelPrimary,l as resolveEffectiveModelFallbacks,o as resolveAgentSkillsFilter,r as resolveAgentDir,s as resolveAgentWorkspaceDir,t as listAgentIds,u as resolveSessionAgentId}from"../../agent-scope-EkacNLg3.js";import{r as defaultRuntime,t as createSubsystemLogger}from"../../subsystem-BakM_oqD.js";import{h as resolveWorkspaceFilePath,l as ensureAgentWorkspace}from"../../workspace-BCjtHT4u.js";import{Ct as DEFAULT_CONTEXT_TOKENS,Tt as DEFAULT_PROVIDER,a as isCliProvider,d as resolveConfiguredModelRef,g as resolveThinkingDefault,mt as ensureAuthProfileStore,o as modelKey,s as normalizeModelRef,t as buildAllowedModelSet,wt as DEFAULT_MODEL}from"../../model-selection-BJ0saFZo.js";import{n as formatCliCommand}from"../../env-BhRm7_r8.js";import"../../boolean-ssGoaBPk.js";import"../../src-CLWuGn12.js";import{A as clearSessionAuthProfileOverride,C as deriveSessionTotalTokens,D as getRemoteSkillEligibility,E as resolveSendPolicy,G as formatOutboundPayloadLog,J as clearAgentRunContext,K as normalizeOutboundPayloads,M as applyVerboseOverride,O as getSkillsSnapshotVersion,U as resolveAgentTimeoutMs,W as deliverOutboundPayloads,X as registerAgentRunContext,Y as emitAgentEvent,Z as runWithModelFallback,_ as resolveOutboundTarget,b as AGENT_LANE_SUBAGENT,g as runCliAgent,h as setCliSessionId,j as applyModelOverrideToSessionEntry,k as lookupContextTokens,m as getCliSessionId,q as normalizeOutboundPayloadsForJson,t as runEmbeddedAgent,v as resolveSessionDeliveryTarget,w as hasNonzeroUsage,y as AGENT_LANE_NESTED}from"../../embedded-BcHzh_y8.js";import{s as SILENT_REPLY_TOKEN}from"../../replies-BG-eHErp.js";import{r as normalizeChannelId,t as getChannelPlugin}from"../../plugins-J28Y83f5.js";import"../../accounts-193gfWbH.js";import"../../bindings-BfB5A-by.js";import"../../send-DcxNvcKU.js";import"../../send-d9H-BT6p.js";import"../../accounts-DHeA4T6C.js";import"../../send-BxVr1pPI.js";import"../../fetch-BklyLYYN.js";import{n as loadModelCatalog}from"../../model-catalog-Abk8cdEI.js";import"../../redact-sNZY-pGx.js";import"../../errors-BmztzL5I.js";import{$t as resolveChannelResetConfig,An as buildWorkspaceSkillSnapshot,H as normalizeThinkLevel,Ht as normalizeAccountId,K as supportsXHighThinking,L as formatThinkingLevels,Nt as updateSessionStore,Qt as evaluateSessionFreshness,R as formatXHighModelHint,W as normalizeVerboseLevel,Zt as resolveSessionKey,en as resolveSessionResetPolicy,kt as loadSessionStore,on as resolveExplicitAgentSessionKey,sn as resolveMainSessionKey,tn as resolveSessionResetType}from"../../runner-D7af_RBH.js";import{n as loadConfig}from"../../config-bxyMjPHU.js";import"../../chrome-CtTMuhww.js";import"../../frontmatter-DBVosMFY.js";import"../../store-DN9AcI73.js";import{i as isInternalMessageChannel,l as resolveMessageChannel,n as isDeliverableMessageChannel,r as isGatewayMessageChannel,s as normalizeMessageChannel,t as INTERNAL_MESSAGE_CHANNEL}from"../../message-channel-tBuQgYSD.js";import"../../accounts-C7FtIPYB.js";import{n as resolveSessionFilePath,s as resolveStorePath}from"../../paths-CzXKnIOb.js";import"../../gemini-auth-CzGGgJ0p.js";import"../../tool-images-mfC2sOfJ.js";import"../../config-DfXnxW-V.js";import"../../reply-prefix-me5vnbrB.js";import"../../sqlite-D3Ov16zb.js";import"../../manager-BdFSM6B3.js";import"../../retry-BYnMCvOU.js";import"../../common-CDXsNQYT.js";import"../../chunk-CrsAQ01n.js";import"../../markdown-tables-DvSC1OTb.js";import"../../ir-Ct8GNKB7.js";import"../../render-CVWbhuqU.js";import"../../send-ZeI8StQK.js";import"../../outbound-attachment-U-XtahS5.js";import"../../fetch-Jq1KZsRq.js";import"../../send-CqER7CIV.js";import"../../resolve-route-CGe48x_Z.js";import"../../channel-activity-xLea9vdo.js";import"../../tables-Desw59m6.js";import"../../active-listener-BQLkI7vg.js";import fs from"node:fs/promises";import crypto from"node:crypto";function createDefaultDeps(){return{sendMessageWhatsApp:async(...args)=>{let{sendMessageWhatsApp}=await import(`../../web-DPGGHIc_.js`);return await sendMessageWhatsApp(...args)},sendMessageTelegram:async(...args)=>{let{sendMessageTelegram}=await import(`../../send-BxVr1pPI.js`).then(n=>n.l);return await sendMessageTelegram(...args)},sendMessageDiscord:async(...args)=>{let{sendMessageDiscord}=await import(`../../send-d9H-BT6p.js`).then(n=>n.t);return await sendMessageDiscord(...args)},sendMessageSlack:async(...args)=>{let{sendMessageSlack}=await import(`../../send-DcxNvcKU.js`).then(n=>n.n);return await sendMessageSlack(...args)},sendMessageSignal:async(...args)=>{let{sendMessageSignal}=await import(`../../send-ZeI8StQK.js`).then(n=>n.i);return await sendMessageSignal(...args)},sendMessageIMessage:async(...args)=>{let{sendMessageIMessage}=await import(`../../send-CqER7CIV.js`).then(n=>n.n);return await sendMessageIMessage(...args)}}}function createOutboundSendDeps(deps){return{sendWhatsApp:deps.sendMessageWhatsApp,sendTelegram:deps.sendMessageTelegram,sendDiscord:deps.sendMessageDiscord,sendSlack:deps.sendMessageSlack,sendSignal:deps.sendMessageSignal,sendIMessage:deps.sendMessageIMessage}}function resolveAgentDeliveryPlan(params){let requestedRaw=typeof params.requestedChannel==`string`?params.requestedChannel.trim():``,requestedChannel=(requestedRaw?normalizeMessageChannel(requestedRaw):void 0)||`last`,explicitTo=typeof params.explicitTo==`string`&&params.explicitTo.trim()?params.explicitTo.trim():void 0,baseDelivery=resolveSessionDeliveryTarget({entry:params.sessionEntry,requestedChannel:requestedChannel===INTERNAL_MESSAGE_CHANNEL?`last`:requestedChannel,explicitTo,explicitThreadId:params.explicitThreadId}),resolvedChannel=requestedChannel===INTERNAL_MESSAGE_CHANNEL?INTERNAL_MESSAGE_CHANNEL:requestedChannel===`last`?baseDelivery.channel&&baseDelivery.channel!==INTERNAL_MESSAGE_CHANNEL?baseDelivery.channel:params.wantsDelivery?DEFAULT_CHAT_CHANNEL:INTERNAL_MESSAGE_CHANNEL:isGatewayMessageChannel(requestedChannel)?requestedChannel:baseDelivery.channel&&baseDelivery.channel!==INTERNAL_MESSAGE_CHANNEL?baseDelivery.channel:params.wantsDelivery?DEFAULT_CHAT_CHANNEL:INTERNAL_MESSAGE_CHANNEL,deliveryTargetMode=explicitTo?`explicit`:isDeliverableMessageChannel(resolvedChannel)?`implicit`:void 0,resolvedAccountId=normalizeAccountId(params.accountId)??(deliveryTargetMode===`implicit`?baseDelivery.accountId:void 0),resolvedTo=explicitTo;return!resolvedTo&&isDeliverableMessageChannel(resolvedChannel)&&resolvedChannel===baseDelivery.lastChannel&&(resolvedTo=baseDelivery.lastTo),{baseDelivery,resolvedChannel,resolvedTo,resolvedAccountId,resolvedThreadId:baseDelivery.threadId,deliveryTargetMode}}function resolveAgentOutboundTarget(params){let targetMode=params.targetMode??params.plan.deliveryTargetMode??(params.plan.resolvedTo?`explicit`:`implicit`);if(!isDeliverableMessageChannel(params.plan.resolvedChannel)||params.validateExplicitTarget!==!0&&params.plan.resolvedTo)return{resolvedTarget:null,resolvedTo:params.plan.resolvedTo,targetMode};let resolvedTarget=resolveOutboundTarget({channel:params.plan.resolvedChannel,to:params.plan.resolvedTo,cfg:params.cfg,accountId:params.plan.resolvedAccountId,mode:targetMode});return{resolvedTarget,resolvedTo:resolvedTarget.ok?resolvedTarget.to:params.plan.resolvedTo,targetMode}}const isOutboundPayloadJson=payload=>`mediaUrl`in payload;function buildOutboundResultEnvelope(params){let hasPayloads=params.payloads!==void 0,payloads=params.payloads===void 0?void 0:params.payloads.length===0?[]:isOutboundPayloadJson(params.payloads[0])?params.payloads:normalizeOutboundPayloadsForJson(params.payloads);return params.flattenDelivery!==!1&&params.delivery&&!params.meta&&!hasPayloads?params.delivery:{...hasPayloads?{payloads}:{},...params.meta?{meta:params.meta}:{},...params.delivery?{delivery:params.delivery}:{}}}function formatNestedLogPrefix(opts){let parts=[`[agent:nested]`],session=opts.sessionKey??opts.sessionId;session&&parts.push(`session=${session}`),opts.runId&&parts.push(`run=${opts.runId}`);let channel=opts.messageChannel??opts.channel;return channel&&parts.push(`channel=${channel}`),opts.to&&parts.push(`to=${opts.to}`),opts.accountId&&parts.push(`account=${opts.accountId}`),parts.join(` `)}function logNestedOutput(runtime,opts,output){let prefix=formatNestedLogPrefix(opts);for(let line of output.split(/\r?\n/))line&&runtime.log(`${prefix} ${line}`)}async function deliverAgentCommandResult(params){let{cfg,deps,runtime,opts,sessionEntry,payloads,result}=params,deliver=opts.deliver===!0,bestEffortDeliver=opts.bestEffortDeliver===!0,deliveryPlan=resolveAgentDeliveryPlan({sessionEntry,requestedChannel:opts.replyChannel??opts.channel,explicitTo:opts.replyTo??opts.to,explicitThreadId:opts.threadId,accountId:opts.replyAccountId??opts.accountId,wantsDelivery:deliver}),deliveryChannel=deliveryPlan.resolvedChannel,deliveryPlugin=isInternalMessageChannel(deliveryChannel)?void 0:getChannelPlugin(normalizeChannelId(deliveryChannel)??deliveryChannel),isDeliveryChannelKnown=isInternalMessageChannel(deliveryChannel)||!!deliveryPlugin,targetMode=opts.deliveryTargetMode??deliveryPlan.deliveryTargetMode??(opts.to?`explicit`:`implicit`),resolvedAccountId=deliveryPlan.resolvedAccountId,resolved=deliver&&isDeliveryChannelKnown&&deliveryChannel?resolveAgentOutboundTarget({cfg,plan:deliveryPlan,targetMode,validateExplicitTarget:!0}):{resolvedTarget:null,resolvedTo:deliveryPlan.resolvedTo,targetMode},resolvedTarget=resolved.resolvedTarget,deliveryTarget=resolved.resolvedTo,resolvedThreadId=deliveryPlan.resolvedThreadId??opts.threadId,resolvedReplyToId=deliveryChannel===`slack`&&resolvedThreadId!=null?String(resolvedThreadId):void 0,resolvedThreadTarget=deliveryChannel===`slack`?void 0:resolvedThreadId,logDeliveryError=err=>{let message=`Delivery failed (${deliveryChannel}${deliveryTarget?` to ${deliveryTarget}`:``}): ${String(err)}`;runtime.error?.(message),runtime.error||runtime.log(message)};if(deliver){if(!isDeliveryChannelKnown){let err=Error(`Unknown channel: ${deliveryChannel}`);if(!bestEffortDeliver)throw err;logDeliveryError(err)}else if(resolvedTarget&&!resolvedTarget.ok){if(!bestEffortDeliver)throw resolvedTarget.error;logDeliveryError(resolvedTarget.error)}}let normalizedPayloads=normalizeOutboundPayloadsForJson(payloads??[]);if(opts.json&&(runtime.log(JSON.stringify(buildOutboundResultEnvelope({payloads:normalizedPayloads,meta:result.meta}),null,2)),!deliver))return{payloads:normalizedPayloads,meta:result.meta};if(!payloads||payloads.length===0)return runtime.log(`No reply from agent.`),{payloads:[],meta:result.meta};let deliveryPayloads=normalizeOutboundPayloads(payloads),logPayload=payload=>{if(opts.json)return;let output=formatOutboundPayloadLog(payload);if(output){if(opts.lane===AGENT_LANE_NESTED){logNestedOutput(runtime,opts,output);return}runtime.log(output)}};if(!deliver)for(let payload of deliveryPayloads)logPayload(payload);return deliver&&deliveryChannel&&!isInternalMessageChannel(deliveryChannel)&&deliveryTarget&&await deliverOutboundPayloads({cfg,channel:deliveryChannel,to:deliveryTarget,accountId:resolvedAccountId,payloads:deliveryPayloads,agentId:opts.agentId??(opts.sessionKey?resolveSessionAgentId({sessionKey:opts.sessionKey,config:cfg}):void 0),replyToId:resolvedReplyToId??null,threadId:resolvedThreadTarget??null,bestEffort:bestEffortDeliver,onError:err=>logDeliveryError(err),onPayload:logPayload,deps:createOutboundSendDeps(deps)}),{payloads:normalizedPayloads,meta:result.meta}}function resolveAgentRunContext(opts){let merged=opts.runContext?{...opts.runContext}:{},normalizedChannel=resolveMessageChannel(merged.messageChannel??opts.messageChannel,opts.replyChannel??opts.channel);normalizedChannel&&(merged.messageChannel=normalizedChannel);let normalizedAccountId=normalizeAccountId(merged.accountId??opts.accountId);normalizedAccountId&&(merged.accountId=normalizedAccountId);let groupId=(merged.groupId??opts.groupId)?.toString().trim();groupId&&(merged.groupId=groupId);let groupChannel=(merged.groupChannel??opts.groupChannel)?.toString().trim();groupChannel&&(merged.groupChannel=groupChannel);let groupSpace=(merged.groupSpace??opts.groupSpace)?.toString().trim();if(groupSpace&&(merged.groupSpace=groupSpace),merged.currentThreadTs==null&&opts.threadId!=null&&opts.threadId!==``&&opts.threadId!==null&&(merged.currentThreadTs=String(opts.threadId)),!merged.currentChannelId&&opts.to){let trimmedTo=opts.to.trim();trimmedTo&&(merged.currentChannelId=trimmedTo)}return merged}async function updateSessionStoreAfterAgentRun(params){let{cfg,sessionId,sessionKey,storePath,sessionStore,defaultProvider,defaultModel,fallbackProvider,fallbackModel,result}=params,usage=result.meta.agentMeta?.usage,promptTokens=result.meta.agentMeta?.promptTokens,compactionsThisRun=Math.max(0,result.meta.agentMeta?.compactionCount??0),modelUsed=result.meta.agentMeta?.model??fallbackModel??defaultModel,providerUsed=result.meta.agentMeta?.provider??fallbackProvider??defaultProvider,contextTokens=params.contextTokensOverride??lookupContextTokens(modelUsed)??DEFAULT_CONTEXT_TOKENS,entry=sessionStore[sessionKey]??{sessionId,updatedAt:Date.now()},next={...entry,sessionId,updatedAt:Date.now(),modelProvider:providerUsed,model:modelUsed,contextTokens};if(isCliProvider(providerUsed,cfg)){let cliSessionId=result.meta.agentMeta?.sessionId?.trim();cliSessionId&&setCliSessionId(next,providerUsed,cliSessionId)}if(next.abortedLastRun=result.meta.aborted??!1,hasNonzeroUsage(usage)){let input=usage.input??0,output=usage.output??0,totalTokens=deriveSessionTotalTokens({usage,contextTokens,promptTokens})??input;next.inputTokens=input,next.outputTokens=output,next.totalTokens=totalTokens,next.totalTokensFresh=!0}compactionsThisRun>0&&(next.compactionCount=(entry.compactionCount??0)+compactionsThisRun),sessionStore[sessionKey]=next,await updateSessionStore(storePath,store=>{store[sessionKey]=next})}function resolveSessionKeyForRequest(opts){let sessionCfg=opts.cfg.session,scope=sessionCfg?.scope??`per-sender`,mainKey=normalizeMainKey(sessionCfg?.mainKey),explicitSessionKey=opts.sessionKey?.trim()||resolveExplicitAgentSessionKey({cfg:opts.cfg,agentId:opts.agentId}),storeAgentId=resolveAgentIdFromSessionKey(explicitSessionKey),storePath=resolveStorePath(sessionCfg?.store,{agentId:storeAgentId}),sessionStore=loadSessionStore(storePath),ctx=opts.to?.trim()?{From:opts.to}:void 0,sessionKey=explicitSessionKey??(ctx?resolveSessionKey(scope,ctx,mainKey):void 0);if(!explicitSessionKey&&opts.sessionId&&(!sessionKey||sessionStore[sessionKey]?.sessionId!==opts.sessionId)){let foundKey=Object.keys(sessionStore).find(key=>sessionStore[key]?.sessionId===opts.sessionId);foundKey&&(sessionKey=foundKey)}if(opts.sessionId&&!explicitSessionKey&&(!sessionKey||sessionStore[sessionKey]?.sessionId!==opts.sessionId)){let allAgentIds=listAgentIds(opts.cfg);for(let agentId of allAgentIds){if(agentId===storeAgentId)continue;let altStorePath=resolveStorePath(sessionCfg?.store,{agentId}),altStore=loadSessionStore(altStorePath),foundKey=Object.keys(altStore).find(key=>altStore[key]?.sessionId===opts.sessionId);if(foundKey)return{sessionKey:foundKey,sessionStore:altStore,storePath:altStorePath}}}return{sessionKey,sessionStore,storePath}}function resolveSession(opts){let sessionCfg=opts.cfg.session,{sessionKey,sessionStore,storePath}=resolveSessionKeyForRequest({cfg:opts.cfg,to:opts.to,sessionId:opts.sessionId,sessionKey:opts.sessionKey,agentId:opts.agentId}),now=Date.now(),sessionEntry=sessionKey?sessionStore[sessionKey]:void 0,resetPolicy=resolveSessionResetPolicy({sessionCfg,resetType:resolveSessionResetType({sessionKey}),resetOverride:resolveChannelResetConfig({sessionCfg,channel:sessionEntry?.lastChannel??sessionEntry?.channel})}),fresh=sessionEntry?evaluateSessionFreshness({updatedAt:sessionEntry.updatedAt,now,policy:resetPolicy}).fresh:!1;return{sessionId:opts.sessionId?.trim()||(fresh?sessionEntry?.sessionId:void 0)||crypto.randomUUID(),sessionKey,sessionEntry,sessionStore,storePath,isNewSession:!fresh&&!opts.sessionId,persistedThinking:fresh&&sessionEntry?.thinkingLevel?normalizeThinkLevel(sessionEntry.thinkingLevel):void 0,persistedVerbose:fresh&&sessionEntry?.verboseLevel?normalizeVerboseLevel(sessionEntry.verboseLevel):void 0}}async function persistSessionEntry(params){params.sessionStore[params.sessionKey]=params.entry,await updateSessionStore(params.storePath,store=>{store[params.sessionKey]=params.entry})}function resolveFallbackRetryPrompt(params){return params.isFallbackRetry?`Continue where you left off. The previous model attempt failed or timed out.`:params.body}function runAgentAttempt(params){let effectivePrompt=resolveFallbackRetryPrompt({body:params.body,isFallbackRetry:params.isFallbackRetry});if(isCliProvider(params.providerOverride,params.cfg)){let cliSessionId=getCliSessionId(params.sessionEntry,params.providerOverride);return runCliAgent({sessionId:params.sessionId,sessionKey:params.sessionKey,agentId:params.sessionAgentId,sessionFile:params.sessionFile,workspaceDir:params.workspaceDir,config:params.cfg,prompt:effectivePrompt,provider:params.providerOverride,model:params.modelOverride,thinkLevel:params.resolvedThinkLevel,timeoutMs:params.timeoutMs,runId:params.runId,extraSystemPrompt:params.opts.extraSystemPrompt,cliSessionId,images:params.isFallbackRetry?void 0:params.opts.images,streamParams:params.opts.streamParams})}let authProfileId=params.providerOverride===params.primaryProvider?params.sessionEntry?.authProfileOverride:void 0;return runEmbeddedAgent({sessionId:params.sessionId,sessionKey:params.sessionKey,agentId:params.sessionAgentId,messageChannel:params.messageChannel,agentAccountId:params.runContext.accountId,messageTo:params.opts.replyTo??params.opts.to,messageThreadId:params.opts.threadId,groupId:params.runContext.groupId,groupChannel:params.runContext.groupChannel,groupSpace:params.runContext.groupSpace,spawnedBy:params.spawnedBy,currentChannelId:params.runContext.currentChannelId,currentThreadTs:params.runContext.currentThreadTs,replyToMode:params.runContext.replyToMode,hasRepliedRef:params.runContext.hasRepliedRef,senderIsOwner:!0,sessionFile:params.sessionFile,workspaceDir:params.workspaceDir,config:params.cfg,skillsSnapshot:params.skillsSnapshot,prompt:effectivePrompt,images:params.isFallbackRetry?void 0:params.opts.images,clientTools:params.opts.clientTools,provider:params.providerOverride,model:params.modelOverride,authProfileId,authProfileIdSource:authProfileId?params.sessionEntry?.authProfileOverrideSource:void 0,thinkLevel:params.resolvedThinkLevel,verboseLevel:params.resolvedVerboseLevel,timeoutMs:params.timeoutMs,runId:params.runId,lane:params.opts.lane,abortSignal:params.opts.abortSignal,extraSystemPrompt:params.opts.extraSystemPrompt,inputProvenance:params.opts.inputProvenance,streamParams:params.opts.streamParams,agentDir:params.agentDir,onAgentEvent:params.onAgentEvent})}async function agentCommand(opts,runtime=defaultRuntime,deps=createDefaultDeps()){let body=(opts.message??``).trim();if(!body)throw Error(`Message (--message) is required`);if(!opts.to&&!opts.sessionId&&!opts.sessionKey&&!opts.agentId)throw Error(`Pass --to <E.164>, --session-id, or --agent to choose a session`);let cfg=loadConfig(),agentIdOverrideRaw=opts.agentId?.trim(),agentIdOverride=agentIdOverrideRaw?normalizeAgentId(agentIdOverrideRaw):void 0;if(agentIdOverride&&!listAgentIds(cfg).includes(agentIdOverride))throw Error(`Unknown agent id "${agentIdOverrideRaw}". Use "${formatCliCommand(`builderforce agents list`)}" to see configured agents.`);if(agentIdOverride&&opts.sessionKey){let sessionAgentId=resolveAgentIdFromSessionKey(opts.sessionKey);if(sessionAgentId!==agentIdOverride)throw Error(`Agent id "${agentIdOverrideRaw}" does not match session key agent "${sessionAgentId}".`)}let agentCfg=cfg.agents?.defaults,sessionAgentId=agentIdOverride??resolveAgentIdFromSessionKey(opts.sessionKey?.trim()),workspaceDirRaw=resolveAgentWorkspaceDir(cfg,sessionAgentId),agentDir=resolveAgentDir(cfg,sessionAgentId),workspaceDir=(await ensureAgentWorkspace({dir:workspaceDirRaw,ensureBootstrapFiles:!agentCfg?.skipBootstrap})).dir,configuredModel=resolveConfiguredModelRef({cfg,defaultProvider:DEFAULT_PROVIDER,defaultModel:DEFAULT_MODEL}),thinkingLevelsHint=formatThinkingLevels(configuredModel.provider,configuredModel.model),thinkOverride=normalizeThinkLevel(opts.thinking),thinkOnce=normalizeThinkLevel(opts.thinkingOnce);if(opts.thinking&&!thinkOverride)throw Error(`Invalid thinking level. Use one of: ${thinkingLevelsHint}.`);if(opts.thinkingOnce&&!thinkOnce)throw Error(`Invalid one-shot thinking level. Use one of: ${thinkingLevelsHint}.`);let verboseOverride=normalizeVerboseLevel(opts.verbose);if(opts.verbose&&!verboseOverride)throw Error(`Invalid verbose level. Use "on", "full", or "off".`);let isSubagentLane=(typeof opts.lane==`string`?opts.lane.trim():``)===String(AGENT_LANE_SUBAGENT),timeoutSecondsRaw=opts.timeout===void 0?isSubagentLane?0:void 0:Number.parseInt(String(opts.timeout),10);if(timeoutSecondsRaw!==void 0&&(Number.isNaN(timeoutSecondsRaw)||timeoutSecondsRaw<0))throw Error(`--timeout must be a non-negative integer (seconds; 0 means no timeout)`);let timeoutMs=resolveAgentTimeoutMs({cfg,overrideSeconds:timeoutSecondsRaw}),{sessionId,sessionKey,sessionEntry:resolvedSessionEntry,sessionStore,storePath,isNewSession,persistedThinking,persistedVerbose}=resolveSession({cfg,to:opts.to,sessionId:opts.sessionId,sessionKey:opts.sessionKey,agentId:agentIdOverride}),sessionEntry=resolvedSessionEntry,runId=opts.runId?.trim()||sessionId;try{if(opts.deliver===!0&&resolveSendPolicy({cfg,entry:sessionEntry,sessionKey,channel:sessionEntry?.channel,chatType:sessionEntry?.chatType})===`deny`)throw Error(`send blocked by session policy`);let resolvedThinkLevel=thinkOnce??thinkOverride??persistedThinking??agentCfg?.thinkingDefault,resolvedVerboseLevel=verboseOverride??persistedVerbose??agentCfg?.verboseDefault??`on`;sessionKey&&registerAgentRunContext(runId,{sessionKey,verboseLevel:resolvedVerboseLevel});let needsSkillsSnapshot=isNewSession||!sessionEntry?.skillsSnapshot,skillsSnapshotVersion=getSkillsSnapshotVersion(workspaceDir),skillFilter=resolveAgentSkillsFilter(cfg,sessionAgentId),skillsSnapshot=needsSkillsSnapshot?buildWorkspaceSkillSnapshot(workspaceDir,{config:cfg,eligibility:{remote:getRemoteSkillEligibility()},snapshotVersion:skillsSnapshotVersion,skillFilter}):sessionEntry?.skillsSnapshot;if(skillsSnapshot&&sessionStore&&sessionKey&&needsSkillsSnapshot){let next={...sessionEntry??{sessionId,updatedAt:Date.now()},sessionId,updatedAt:Date.now(),skillsSnapshot};await persistSessionEntry({sessionStore,sessionKey,storePath,entry:next}),sessionEntry=next}if(sessionStore&&sessionKey){let next={...sessionStore[sessionKey]??sessionEntry??{sessionId,updatedAt:Date.now()},sessionId,updatedAt:Date.now()};thinkOverride&&(next.thinkingLevel=thinkOverride),applyVerboseOverride(next,verboseOverride),await persistSessionEntry({sessionStore,sessionKey,storePath,entry:next})}let agentModelPrimary=resolveAgentModelPrimary(cfg,sessionAgentId),configuredDefaultRef=resolveConfiguredModelRef({cfg:agentModelPrimary?{...cfg,agents:{...cfg.agents,defaults:{...cfg.agents?.defaults,model:{...typeof cfg.agents?.defaults?.model==`object`?cfg.agents.defaults.model:void 0,primary:agentModelPrimary}}}}:cfg,defaultProvider:DEFAULT_PROVIDER,defaultModel:DEFAULT_MODEL}),{provider:defaultProvider,model:defaultModel}=normalizeModelRef(configuredDefaultRef.provider,configuredDefaultRef.model),provider=defaultProvider,model=defaultModel,hasAllowlist=agentCfg?.models&&Object.keys(agentCfg.models).length>0,hasStoredOverride=!!(sessionEntry?.modelOverride||sessionEntry?.providerOverride),needsModelCatalog=hasAllowlist||hasStoredOverride,allowedModelKeys=new Set,allowedModelCatalog=[],modelCatalog=null;if(needsModelCatalog){modelCatalog=await loadModelCatalog({config:cfg});let allowed=buildAllowedModelSet({cfg,catalog:modelCatalog,defaultProvider,defaultModel});allowedModelKeys=allowed.allowedKeys,allowedModelCatalog=allowed.allowedCatalog}if(sessionEntry&&sessionStore&&sessionKey&&hasStoredOverride){let entry=sessionEntry,overrideProvider=sessionEntry.providerOverride?.trim()||defaultProvider,overrideModel=sessionEntry.modelOverride?.trim();if(overrideModel){let normalizedOverride=normalizeModelRef(overrideProvider,overrideModel),key=modelKey(normalizedOverride.provider,normalizedOverride.model);if(!isCliProvider(normalizedOverride.provider,cfg)&&allowedModelKeys.size>0&&!allowedModelKeys.has(key)){let{updated}=applyModelOverrideToSessionEntry({entry,selection:{provider:defaultProvider,model:defaultModel,isDefault:!0}});updated&&await persistSessionEntry({sessionStore,sessionKey,storePath,entry})}}}let storedProviderOverride=sessionEntry?.providerOverride?.trim(),storedModelOverride=sessionEntry?.modelOverride?.trim();if(storedModelOverride){let normalizedStored=normalizeModelRef(storedProviderOverride||defaultProvider,storedModelOverride),key=modelKey(normalizedStored.provider,normalizedStored.model);(isCliProvider(normalizedStored.provider,cfg)||allowedModelKeys.size===0||allowedModelKeys.has(key))&&(provider=normalizedStored.provider,model=normalizedStored.model)}if(sessionEntry){let authProfileId=sessionEntry.authProfileOverride;if(authProfileId){let entry=sessionEntry,profile=(await ensureAuthProfileStore()).profiles[authProfileId];(!profile||profile.provider!==provider)&&sessionStore&&sessionKey&&await clearSessionAuthProfileOverride({sessionEntry:entry,sessionStore,sessionKey,storePath})}}if(!resolvedThinkLevel){let catalogForThinking=modelCatalog??allowedModelCatalog;(!catalogForThinking||catalogForThinking.length===0)&&(modelCatalog=await loadModelCatalog({config:cfg}),catalogForThinking=modelCatalog),resolvedThinkLevel=resolveThinkingDefault({cfg,provider,model,catalog:catalogForThinking})}if(resolvedThinkLevel===`xhigh`&&!supportsXHighThinking(provider,model)){if(thinkOnce||thinkOverride)throw Error(`Thinking level "xhigh" is only supported for ${formatXHighModelHint()}.`);if(resolvedThinkLevel=`high`,sessionEntry&&sessionStore&&sessionKey&&sessionEntry.thinkingLevel===`xhigh`){let entry=sessionEntry;entry.thinkingLevel=`high`,entry.updatedAt=Date.now(),await persistSessionEntry({sessionStore,sessionKey,storePath,entry})}}let sessionFile=resolveSessionFilePath(sessionId,sessionEntry,{agentId:sessionAgentId}),startedAt=Date.now(),lifecycleEnded=!1,result,fallbackProvider=provider,fallbackModel=model;try{let runContext=resolveAgentRunContext(opts),messageChannel=resolveMessageChannel(runContext.messageChannel,opts.replyChannel??opts.channel),spawnedBy=opts.spawnedBy??sessionEntry?.spawnedBy,effectiveFallbacksOverride=resolveEffectiveModelFallbacks({cfg,agentId:sessionAgentId,hasSessionModelOverride:!!storedModelOverride}),fallbackAttemptIndex=0,fallbackResult=await runWithModelFallback({cfg,provider,model,agentDir,fallbacksOverride:effectiveFallbacksOverride,run:(providerOverride,modelOverride)=>{let isFallbackRetry=fallbackAttemptIndex>0;return fallbackAttemptIndex+=1,runAgentAttempt({providerOverride,modelOverride,cfg,sessionEntry,sessionId,sessionKey,sessionAgentId,sessionFile,workspaceDir,body,isFallbackRetry,resolvedThinkLevel,timeoutMs,runId,opts,runContext,spawnedBy,messageChannel,skillsSnapshot,resolvedVerboseLevel,agentDir,primaryProvider:provider,onAgentEvent:evt=>{evt.stream===`lifecycle`&&typeof evt.data?.phase==`string`&&(evt.data.phase===`end`||evt.data.phase===`error`)&&(lifecycleEnded=!0)}})}});result=fallbackResult.result,fallbackProvider=fallbackResult.provider,fallbackModel=fallbackResult.model,lifecycleEnded||emitAgentEvent({runId,stream:`lifecycle`,data:{phase:`end`,startedAt,endedAt:Date.now(),aborted:result.meta.aborted??!1}})}catch(err){throw lifecycleEnded||emitAgentEvent({runId,stream:`lifecycle`,data:{phase:`error`,startedAt,endedAt:Date.now(),error:String(err)}}),err}sessionStore&&sessionKey&&await updateSessionStoreAfterAgentRun({cfg,contextTokensOverride:agentCfg?.contextTokens,sessionId,sessionKey,storePath,sessionStore,defaultProvider:provider,defaultModel:model,fallbackProvider,fallbackModel,result});let payloads=result.payloads??[];return await deliverAgentCommandResult({cfg,deps,runtime,opts,sessionEntry,result,payloads})}finally{clearAgentRunContext(runId)}}function generateBootSessionId(){return`boot-${new Date().toISOString().replace(/[:.]/g,`-`).replace(`T`,`_`).replace(`Z`,``)}-${crypto.randomUUID().slice(0,8)}`}const log=createSubsystemLogger(`gateway/boot`),BOOT_FILENAME=`BOOT.md`;function buildBootPrompt(content){return[`You are running a boot check. Follow BOOT.md instructions exactly.`,``,`BOOT.md:`,content,``,`If BOOT.md asks you to send a message, use the message tool (action=send with channel + target).`,"Use the `target` field (not `to`) for message tool destinations.",`After sending with the message tool, reply with ONLY: ${SILENT_REPLY_TOKEN}.`,`If nothing needs attention, reply with ONLY: ${SILENT_REPLY_TOKEN}.`].join(`
2
2
  `)}async function loadBootFile(workspaceDir){let bootPath=resolveWorkspaceFilePath(workspaceDir,BOOT_FILENAME);try{let trimmed=(await fs.readFile(bootPath,`utf-8`)).trim();return trimmed?{status:`ok`,content:trimmed}:{status:`empty`}}catch(err){if(err.code===`ENOENT`)return{status:`missing`};throw err}}function snapshotMainSessionMapping(params){let agentId=resolveAgentIdFromSessionKey(params.sessionKey),storePath=resolveStorePath(params.cfg.session?.store,{agentId});try{let entry=loadSessionStore(storePath,{skipCache:!0})[params.sessionKey];return entry?{storePath,sessionKey:params.sessionKey,canRestore:!0,hadEntry:!0,entry:structuredClone(entry)}:{storePath,sessionKey:params.sessionKey,canRestore:!0,hadEntry:!1}}catch(err){return log.debug(`boot: could not snapshot main session mapping`,{sessionKey:params.sessionKey,error:String(err)}),{storePath,sessionKey:params.sessionKey,canRestore:!1,hadEntry:!1}}}async function restoreMainSessionMapping(snapshot){if(snapshot.canRestore)try{await updateSessionStore(snapshot.storePath,store=>{if(snapshot.hadEntry&&snapshot.entry){store[snapshot.sessionKey]=snapshot.entry;return}delete store[snapshot.sessionKey]},{activeSessionKey:snapshot.sessionKey});return}catch(err){return err instanceof Error?err.message:String(err)}}async function runBootOnce(params){let bootRuntime={log:()=>{},error:message=>log.error(String(message)),exit:defaultRuntime.exit},result;try{result=await loadBootFile(params.workspaceDir)}catch(err){let message=err instanceof Error?err.message:String(err);return log.error(`boot: failed to read ${BOOT_FILENAME}: ${message}`),{status:`failed`,reason:message}}if(result.status===`missing`||result.status===`empty`)return{status:`skipped`,reason:result.status};let sessionKey=resolveMainSessionKey(params.cfg),message=buildBootPrompt(result.content??``),sessionId=generateBootSessionId(),mappingSnapshot=snapshotMainSessionMapping({cfg:params.cfg,sessionKey}),agentFailure;try{await agentCommand({message,sessionKey,sessionId,deliver:!1},bootRuntime,params.deps)}catch(err){agentFailure=err instanceof Error?err.message:String(err),log.error(`boot: agent run failed: ${agentFailure}`)}let mappingRestoreFailure=await restoreMainSessionMapping(mappingSnapshot);return mappingRestoreFailure&&log.error(`boot: failed to restore main session mapping: ${mappingRestoreFailure}`),!agentFailure&&!mappingRestoreFailure?{status:`ran`}:{status:`failed`,reason:[agentFailure?`agent run failed: ${agentFailure}`:void 0,mappingRestoreFailure?`mapping restore failed: ${mappingRestoreFailure}`:void 0].filter(part=>!!part).join(`; `)}}const runBootChecklist=async event=>{if(event.type!==`gateway`||event.action!==`startup`)return;let context=event.context??{};if(!context.cfg||!context.workspaceDir)return;let deps=context.deps??createDefaultDeps();await runBootOnce({cfg:context.cfg,deps,workspaceDir:context.workspaceDir})};export{runBootChecklist as default};
@@ -1,4 +1,4 @@
1
- import{s as resolveStateDir}from"../../paths-BVMSM1lQ.js";import{d as resolveAgentIdFromSessionKey}from"../../session-key-CYpYHc1e.js";import"../../registry-D_frpmHZ.js";import{s as resolveAgentWorkspaceDir}from"../../agent-scope-EkacNLg3.js";import{t as createSubsystemLogger}from"../../subsystem-BakM_oqD.js";import"../../workspace-BCjtHT4u.js";import"../../model-selection-BJ0saFZo.js";import"../../env-BhRm7_r8.js";import"../../boolean-ssGoaBPk.js";import"../../src-CLWuGn12.js";import"../../embedded-DXDHduG1.js";import"../../replies-BG-eHErp.js";import"../../plugins-J28Y83f5.js";import"../../accounts-193gfWbH.js";import"../../bindings-BfB5A-by.js";import"../../send-DcxNvcKU.js";import"../../send-d9H-BT6p.js";import"../../accounts-DHeA4T6C.js";import"../../send-BxVr1pPI.js";import"../../fetch-BklyLYYN.js";import"../../model-catalog-Abk8cdEI.js";import"../../redact-sNZY-pGx.js";import"../../errors-BmztzL5I.js";import{Yt as hasInterSessionUserProvenance}from"../../runner-B70PGCqP.js";import"../../config-bxyMjPHU.js";import"../../chrome-Blk2Jftn.js";import"../../frontmatter-DBVosMFY.js";import"../../store-DN9AcI73.js";import"../../message-channel-tBuQgYSD.js";import"../../accounts-C7FtIPYB.js";import"../../paths-CzXKnIOb.js";import"../../gemini-auth-CzGGgJ0p.js";import"../../tool-images-mfC2sOfJ.js";import{t as resolveHookConfig}from"../../config-DfXnxW-V.js";import"../../reply-prefix-me5vnbrB.js";import"../../sqlite-D3Ov16zb.js";import"../../manager-BdFSM6B3.js";import"../../retry-BYnMCvOU.js";import"../../common-CDXsNQYT.js";import"../../chunk-CrsAQ01n.js";import"../../markdown-tables-DvSC1OTb.js";import"../../ir-Ct8GNKB7.js";import"../../render-CVWbhuqU.js";import"../../send-ZeI8StQK.js";import"../../outbound-attachment-U-XtahS5.js";import"../../fetch-Jq1KZsRq.js";import"../../send-CqER7CIV.js";import"../../resolve-route-CGe48x_Z.js";import"../../channel-activity-xLea9vdo.js";import"../../tables-Desw59m6.js";import"../../active-listener-BQLkI7vg.js";import{generateSlugViaLLM}from"../../llm-slug-generator.js";import fs from"node:fs/promises";import os from"node:os";import path from"node:path";const log=createSubsystemLogger(`hooks/session-memory`);async function getRecentSessionContent(sessionFilePath,messageCount=15){try{let lines=(await fs.readFile(sessionFilePath,`utf-8`)).trim().split(`
1
+ import{s as resolveStateDir}from"../../paths-BVMSM1lQ.js";import{d as resolveAgentIdFromSessionKey}from"../../session-key-CYpYHc1e.js";import"../../registry-D_frpmHZ.js";import{s as resolveAgentWorkspaceDir}from"../../agent-scope-EkacNLg3.js";import{t as createSubsystemLogger}from"../../subsystem-BakM_oqD.js";import"../../workspace-BCjtHT4u.js";import"../../model-selection-BJ0saFZo.js";import"../../env-BhRm7_r8.js";import"../../boolean-ssGoaBPk.js";import"../../src-CLWuGn12.js";import"../../embedded-BcHzh_y8.js";import"../../replies-BG-eHErp.js";import"../../plugins-J28Y83f5.js";import"../../accounts-193gfWbH.js";import"../../bindings-BfB5A-by.js";import"../../send-DcxNvcKU.js";import"../../send-d9H-BT6p.js";import"../../accounts-DHeA4T6C.js";import"../../send-BxVr1pPI.js";import"../../fetch-BklyLYYN.js";import"../../model-catalog-Abk8cdEI.js";import"../../redact-sNZY-pGx.js";import"../../errors-BmztzL5I.js";import{Yt as hasInterSessionUserProvenance}from"../../runner-D7af_RBH.js";import"../../config-bxyMjPHU.js";import"../../chrome-CtTMuhww.js";import"../../frontmatter-DBVosMFY.js";import"../../store-DN9AcI73.js";import"../../message-channel-tBuQgYSD.js";import"../../accounts-C7FtIPYB.js";import"../../paths-CzXKnIOb.js";import"../../gemini-auth-CzGGgJ0p.js";import"../../tool-images-mfC2sOfJ.js";import{t as resolveHookConfig}from"../../config-DfXnxW-V.js";import"../../reply-prefix-me5vnbrB.js";import"../../sqlite-D3Ov16zb.js";import"../../manager-BdFSM6B3.js";import"../../retry-BYnMCvOU.js";import"../../common-CDXsNQYT.js";import"../../chunk-CrsAQ01n.js";import"../../markdown-tables-DvSC1OTb.js";import"../../ir-Ct8GNKB7.js";import"../../render-CVWbhuqU.js";import"../../send-ZeI8StQK.js";import"../../outbound-attachment-U-XtahS5.js";import"../../fetch-Jq1KZsRq.js";import"../../send-CqER7CIV.js";import"../../resolve-route-CGe48x_Z.js";import"../../channel-activity-xLea9vdo.js";import"../../tables-Desw59m6.js";import"../../active-listener-BQLkI7vg.js";import{generateSlugViaLLM}from"../../llm-slug-generator.js";import fs from"node:fs/promises";import os from"node:os";import path from"node:path";const log=createSubsystemLogger(`hooks/session-memory`);async function getRecentSessionContent(sessionFilePath,messageCount=15){try{let lines=(await fs.readFile(sessionFilePath,`utf-8`)).trim().split(`
2
2
  `),allMessages=[];for(let line of lines)try{let entry=JSON.parse(line);if(entry.type===`message`&&entry.message){let msg=entry.message,role=msg.role;if((role===`user`||role===`assistant`)&&msg.content){if(role===`user`&&hasInterSessionUserProvenance(msg))continue;let text=Array.isArray(msg.content)?msg.content.find(c=>c.type===`text`)?.text:msg.content;text&&!text.startsWith(`/`)&&allMessages.push(`${role}: ${text}`)}}}catch{}return allMessages.slice(-messageCount).join(`
3
3
  `)}catch{return null}}async function getRecentSessionContentWithResetFallback(sessionFilePath,messageCount=15){let primary=await getRecentSessionContent(sessionFilePath,messageCount);if(primary)return primary;try{let dir=path.dirname(sessionFilePath),resetPrefix=`${path.basename(sessionFilePath)}.reset.`,resetCandidates=(await fs.readdir(dir)).filter(name=>name.startsWith(resetPrefix)).toSorted();if(resetCandidates.length===0)return primary;let latestResetPath=path.join(dir,resetCandidates[resetCandidates.length-1]),fallback=await getRecentSessionContent(latestResetPath,messageCount);return fallback&&log.debug(`Loaded session content from reset fallback`,{sessionFilePath,latestResetPath}),fallback||primary}catch{return primary}}function stripResetSuffix(fileName){let resetIndex=fileName.indexOf(`.reset.`);return resetIndex===-1?fileName:fileName.slice(0,resetIndex)}async function findPreviousSessionFile(params){try{let files=await fs.readdir(params.sessionsDir),fileSet=new Set(files),baseFromReset=params.currentSessionFile?stripResetSuffix(path.basename(params.currentSessionFile)):void 0;if(baseFromReset&&fileSet.has(baseFromReset))return path.join(params.sessionsDir,baseFromReset);let trimmedSessionId=params.sessionId?.trim();if(trimmedSessionId){let canonicalFile=`${trimmedSessionId}.jsonl`;if(fileSet.has(canonicalFile))return path.join(params.sessionsDir,canonicalFile);let topicVariants=files.filter(name=>name.startsWith(`${trimmedSessionId}-topic-`)&&name.endsWith(`.jsonl`)&&!name.includes(`.reset.`)).toSorted().toReversed();if(topicVariants.length>0)return path.join(params.sessionsDir,topicVariants[0])}if(!params.currentSessionFile)return;let nonResetJsonl=files.filter(name=>name.endsWith(`.jsonl`)&&!name.includes(`.reset.`)).toSorted().toReversed();if(nonResetJsonl.length>0)return path.join(params.sessionsDir,nonResetJsonl[0])}catch{}}const saveSessionToMemory=async event=>{if(!(event.type!==`command`||event.action!==`new`))try{log.debug(`Hook triggered for /new command`);let context=event.context||{},cfg=context.cfg,agentId=resolveAgentIdFromSessionKey(event.sessionKey),workspaceDir=cfg?resolveAgentWorkspaceDir(cfg,agentId):path.join(resolveStateDir(process.env,os.homedir),`workspace`),memoryDir=path.join(workspaceDir,`.builderforce`,`memory`);await fs.mkdir(memoryDir,{recursive:!0});let now=new Date(event.timestamp),dateStr=now.toISOString().split(`T`)[0],sessionEntry=context.previousSessionEntry||context.sessionEntry||{},currentSessionId=sessionEntry.sessionId,currentSessionFile=sessionEntry.sessionFile||void 0;if(!currentSessionFile||currentSessionFile.includes(`.reset.`)){let sessionsDirs=new Set;currentSessionFile&&sessionsDirs.add(path.dirname(currentSessionFile)),sessionsDirs.add(path.join(workspaceDir,`sessions`));for(let sessionsDir of sessionsDirs){let recoveredSessionFile=await findPreviousSessionFile({sessionsDir,currentSessionFile,sessionId:currentSessionId});if(recoveredSessionFile){currentSessionFile=recoveredSessionFile,log.debug(`Found previous session file`,{file:currentSessionFile});break}}}log.debug(`Session context resolved`,{sessionId:currentSessionId,sessionFile:currentSessionFile,hasCfg:!!cfg});let sessionFile=currentSessionFile||void 0,hookConfig=resolveHookConfig(cfg,`session-memory`),messageCount=typeof hookConfig?.messages==`number`&&hookConfig.messages>0?hookConfig.messages:15,slug=null,sessionContent=null;if(sessionFile){sessionContent=await getRecentSessionContentWithResetFallback(sessionFile,messageCount),log.debug(`Session content loaded`,{length:sessionContent?.length??0,messageCount});let allowLlmSlug=!(process.env.BUILDERFORCE_AGENTS_TEST_FAST===`1`||process.env.VITEST===`true`||process.env.VITEST===`1`)&&hookConfig?.llmSlug!==!1;sessionContent&&cfg&&allowLlmSlug&&(log.debug(`Calling generateSlugViaLLM...`),slug=await generateSlugViaLLM({sessionContent,cfg}),log.debug(`Generated slug`,{slug}))}slug||(slug=now.toISOString().split(`T`)[1].split(`.`)[0].replace(/:/g,``).slice(0,4),log.debug(`Using fallback timestamp slug`,{slug}));let filename=`${dateStr}-${slug}.md`,memoryFilePath=path.join(memoryDir,filename);log.debug(`Memory file path resolved`,{filename,path:memoryFilePath.replace(os.homedir(),`~`)});let timeStr=now.toISOString().split(`T`)[1].split(`.`)[0],sessionId=sessionEntry.sessionId||`unknown`,source=context.commandSource||`unknown`,entryParts=[`# Session: ${dateStr} ${timeStr} UTC`,``,`- **Session Key**: ${event.sessionKey}`,`- **Session ID**: ${sessionId}`,`- **Source**: ${source}`,``];sessionContent&&entryParts.push(`## Conversation Summary`,``,sessionContent,``);let entry=entryParts.join(`
4
4
  `);await fs.writeFile(memoryFilePath,entry,`utf-8`),log.debug(`Memory file written successfully`);let relPath=memoryFilePath.replace(os.homedir(),`~`);log.info(`Session context saved to ${relPath}`)}catch(err){err instanceof Error?log.error(`Failed to save session memory`,{errorName:err.name,errorMessage:err.message,stack:err.stack}):log.error(`Failed to save session memory`,{error:String(err)})}};export{saveSessionToMemory as default};