@ai-agent-forge/agent-forge 0.85.7 → 0.85.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/bundle/.build-manifest.json +7 -7
- package/dist/bundle/chunks/{chunk-WD7FTOHY.js → chunk-BTBDSCF4.js} +3 -3
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/plugin-command.d.ts.map +1 -1
- package/dist/cli/plugin-command.js +58 -0
- package/dist/cli/plugin-command.js.map +1 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.js +2 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +27 -3
- package/dist/utils/tools-manager.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.85.8] - 2026-09-30
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `agent-forge plugin update --all [--scope global|project]` batch-upgrades every active plugin in one command (0.85.7 user seat finding: a factory range bump left seven first-party plugins outdated and the per-plugin bootstrap hint meant seven manual installs). The outer human CLI composes `state list` + one single-plugin `update` per entry; `already_installed` counts as "up to date", a single plugin's failure never aborts the batch, and the trailing summary names updated/current/failed counts with a non-zero exit code on any failure. The versioned ecosystem CLI protocol is unchanged. The bootstrap `range_not_satisfied` warning now points at the batch command too.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- A failed or interrupted managed-tool download (fd/rg) no longer leaves the partial archive in the agent bin directory: the archive path is removed when the download itself fails (the checksum-mismatch path already cleaned its own).
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Managed-tool download status messages now state the GitHub-releases source, the worst-case wait (120s), and the `AGENT_FORGE_OFFLINE=1` escape up front, and a slow download reports elapsed time every 15s instead of looking like a hung startup (0.85.7 fresh-user seat finding: two silent minutes of "fd not found. Downloading...").
|
|
18
|
+
|
|
5
19
|
## [0.85.7] - 2026-09-29
|
|
6
20
|
|
|
7
21
|
### Added
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-09-
|
|
2
|
+
"generatedAt": "2026-09-29T16:47:50.932Z",
|
|
3
3
|
"inputCount": 3560,
|
|
4
4
|
"inputs": {
|
|
5
5
|
"node_modules/@anthropic-ai/sdk/_vendor/partial-json-parser/parser.mjs": "717f9403f2d3ee0f2077aeb7f0ca7eaff7cc9bcdbb054ac23c6c0361fa03cd1f",
|
|
@@ -2090,7 +2090,7 @@
|
|
|
2090
2090
|
"packages/agent-forge/dist/cli/file-processor.js": "4946f4e3e193713135a4924982d31c9403190befd421b7be9893d0e5c65055ae",
|
|
2091
2091
|
"packages/agent-forge/dist/cli/initial-message.js": "d15e1b6ff88ebf85944cce50f4eab219a36f3539e42a0ded19b8f5ff5308b29d",
|
|
2092
2092
|
"packages/agent-forge/dist/cli/list-models.js": "d84ba49e3732a64c512dcb87538445d93dd51eb9538062a86a7e9ff248be7e4d",
|
|
2093
|
-
"packages/agent-forge/dist/cli/plugin-command.js": "
|
|
2093
|
+
"packages/agent-forge/dist/cli/plugin-command.js": "b64ab364cd3c70793cebb234ee8598708c374a8582a483c281b751bfe210f3a3",
|
|
2094
2094
|
"packages/agent-forge/dist/cli/plugin-manager-controller.js": "b1ee53343058f84c4758efa499e9334cd8ed4840a0b8e816c58e8c1e437dc48b",
|
|
2095
2095
|
"packages/agent-forge/dist/cli/plugin-selection-controller.js": "8a86426004cbd4453226a697490c86aa74e99a9ad4e6ebe027ffbe0551c04ede",
|
|
2096
2096
|
"packages/agent-forge/dist/cli/serve.js": "ced13e91712c4648b210b184dabdde192f19cacebb9203e2aff24816dd6102fd",
|
|
@@ -2326,7 +2326,7 @@
|
|
|
2326
2326
|
"packages/agent-forge/dist/plugins/ecosystem/node-tar-writer.js": "37fda62437f2985f84187871dc9d96b69ce5249de7a5a1914b9a72a402a3159e",
|
|
2327
2327
|
"packages/agent-forge/dist/plugins/ecosystem/node-url-package-source.js": "06469e98b9fa93b99eb79a54bbabdc1e0f6ca358814e74cd18b59e7fb2152db0",
|
|
2328
2328
|
"packages/agent-forge/dist/plugins/ecosystem/plugin-acquisition.js": "7c6ec970bcdad21d9e36c0888ce07b72b5e72fd1810267f90bd768e0c0543a66",
|
|
2329
|
-
"packages/agent-forge/dist/plugins/ecosystem/plugin-bootstrap.js": "
|
|
2329
|
+
"packages/agent-forge/dist/plugins/ecosystem/plugin-bootstrap.js": "c6b8390478a6789737d0481df8e89f83ef3eef210bcda5c3c39307ce0adf6e41",
|
|
2330
2330
|
"packages/agent-forge/dist/plugins/ecosystem/registry-cli-adapter.js": "6a4fb5c5ca3ee38fca0e38a3eb372c1d90c0d1555d7c3220d0c5fa2a9beef9fb",
|
|
2331
2331
|
"packages/agent-forge/dist/plugins/ecosystem/registry.js": "8f4b1ebb75eab8ceb67e58789b192bd68e4267805b34a16ae6515e58b685adbc",
|
|
2332
2332
|
"packages/agent-forge/dist/plugins/ecosystem/resolver.js": "172323db42c812de83d0e8057a99e01ce85b171f3dbf0a7e9cd509d89346352e",
|
|
@@ -2403,7 +2403,7 @@
|
|
|
2403
2403
|
"packages/agent-forge/dist/utils/syntax-highlight.js": "c7334db2aff539424d0fab8a71f1953dcd66adcf21d0b4e1026cdfd25117db68",
|
|
2404
2404
|
"packages/agent-forge/dist/utils/text.js": "e5520be5740ddb7d67ebd09ef33ea2aee2e360925593ad3a7842b6534304a0f3",
|
|
2405
2405
|
"packages/agent-forge/dist/utils/tool-result-images.js": "5c5b86665109e1619cd06b887eb25314051d6d7bf10d35558adbd6fc27673695",
|
|
2406
|
-
"packages/agent-forge/dist/utils/tools-manager.js": "
|
|
2406
|
+
"packages/agent-forge/dist/utils/tools-manager.js": "b80208130adaf3efe00342968bf5c0055969ec3e18e4392cc934574a1f26e636",
|
|
2407
2407
|
"packages/agent-forge/dist/utils/version-check.js": "56adc7229bfbda60e40eb8ccf8840731e76e4cbc68d5924ba475276e3aacd56b",
|
|
2408
2408
|
"packages/agent-forge/dist/utils/windows-self-update.js": "cc018a2cc563eb65bc0ba0b9bcf4b81f30f6d19c92c5c6974392a4133ea06831",
|
|
2409
2409
|
"packages/agent-forge/src/artifacts/artifact-store.ts": "9bfb4597875ae359b20e2593744b69dd2998dfa2aebaea5982022c7951ca5672",
|
|
@@ -2429,7 +2429,7 @@
|
|
|
2429
2429
|
"packages/agent-forge/src/cli/file-processor.ts": "4a186c0439cdd4a2d659c93b8c8fc131587c5ee2f97f411ddfcdbc9964fa509b",
|
|
2430
2430
|
"packages/agent-forge/src/cli/initial-message.ts": "16ff02cfd63b5ace571c41f9adc03af1c7417f8019e8027a6e16b3f974764391",
|
|
2431
2431
|
"packages/agent-forge/src/cli/list-models.ts": "f7524a442f21a02df878b89fe247e2d33425c18796b9063468a10e39836c2f35",
|
|
2432
|
-
"packages/agent-forge/src/cli/plugin-command.ts": "
|
|
2432
|
+
"packages/agent-forge/src/cli/plugin-command.ts": "55adbda439edcb1850b622523ff0c7c21e635c034c3ab7f5ed0d9df8b1ee771e",
|
|
2433
2433
|
"packages/agent-forge/src/cli/plugin-manager-controller.ts": "a60110f0673c2e1206a1888049830d704c0470a7f95630822e0485b6e46141b0",
|
|
2434
2434
|
"packages/agent-forge/src/cli/plugin-selection-controller.ts": "42ac842904594b5579649ee2143ce6cb6aa805279243b234a91e87a5c1890c47",
|
|
2435
2435
|
"packages/agent-forge/src/cli/serve.ts": "4fbf502fff7a07ed5426c0896ed68aec6c5447993a5d36d57f9cb143c9c8d2c4",
|
|
@@ -2688,7 +2688,7 @@
|
|
|
2688
2688
|
"packages/agent-forge/src/plugins/ecosystem/node-tar-writer.ts": "9bdb91970f3d96bf95e544cedeede5ab9d12f74d7385400173337c8755ef8c18",
|
|
2689
2689
|
"packages/agent-forge/src/plugins/ecosystem/node-url-package-source.ts": "3507e4f9831593ba2d5f59b06eeeb4904310aaec433b2c32d1eaf49ff96e3fc0",
|
|
2690
2690
|
"packages/agent-forge/src/plugins/ecosystem/plugin-acquisition.ts": "9b9a5c2a7d71727dd12d3cb0af371590100e23518ec0bf598665b56509e043fb",
|
|
2691
|
-
"packages/agent-forge/src/plugins/ecosystem/plugin-bootstrap.ts": "
|
|
2691
|
+
"packages/agent-forge/src/plugins/ecosystem/plugin-bootstrap.ts": "6ed0c5b23965ac18742c1cdb43669aaed0c1949200aa80368167c61b41223e0a",
|
|
2692
2692
|
"packages/agent-forge/src/plugins/ecosystem/registry-cli-adapter.ts": "6ea9700bef7e6e78d1e5a8db0164036925902c7ddb580fe5344f04826da6fe13",
|
|
2693
2693
|
"packages/agent-forge/src/plugins/ecosystem/registry.ts": "ab45c6d8e419febadd2259aace966a9cc80465814aac446f1aaec4d0595ac09f",
|
|
2694
2694
|
"packages/agent-forge/src/plugins/ecosystem/resolver.ts": "bfbf8ddff4be64282e78833fa53598e2f8bc77fe228bd5a1bfccfc4444c2e47c",
|
|
@@ -2773,7 +2773,7 @@
|
|
|
2773
2773
|
"packages/agent-forge/src/utils/syntax-highlight.ts": "f5bc699e8609a8217ae60bb3cc9be73efd47df4c3e2a3b62608664603b2fdd56",
|
|
2774
2774
|
"packages/agent-forge/src/utils/text.ts": "bb323f9607c499115b532021f4f0163c6df04d834aee9c32c3c77b273bd2d7c6",
|
|
2775
2775
|
"packages/agent-forge/src/utils/tool-result-images.ts": "ef2919a2c6adab53b9e214777721f4c4ab00e3238acb31cac1d24bd1c23caec1",
|
|
2776
|
-
"packages/agent-forge/src/utils/tools-manager.ts": "
|
|
2776
|
+
"packages/agent-forge/src/utils/tools-manager.ts": "7a48b37b772e7cbefad8669029f4e2cacd7775b84e8080043a155373c9cf19d7",
|
|
2777
2777
|
"packages/agent-forge/src/utils/version-check.ts": "31499191cede00d53958a74dee22682703ae376c4afe121f55cf409bb1b93c45",
|
|
2778
2778
|
"packages/agent-forge/src/utils/windows-self-update.ts": "7cfb10046f5c60fbce605ebdac41f86efeb40dbf67a945c668581861e585355f",
|
|
2779
2779
|
"packages/agent/dist/agent-loop.js": "e99054ef5b95425decd1e306c7e9806cf33531804cbc48661927878b2f97c718",
|
|
@@ -904,7 +904,7 @@ ${command}`:command,spawnContext=resolveSpawnContext(resolvedCommand,ctx?.cwd||c
|
|
|
904
904
|
`),maxLineNum=Math.max(oldLines.length,newLines.length),lineNumWidth=String(maxLineNum).length,oldLineNum=1,newLineNum=1,lastWasChange=!1,firstChangedLine;for(let i=0;i<parts.length;i++){let part=parts[i],raw=part.value.split(`
|
|
905
905
|
`);if(raw[raw.length-1]===""&&raw.pop(),part.added||part.removed){firstChangedLine===void 0&&(firstChangedLine=newLineNum);for(let line of raw)if(part.added){let lineNum=String(newLineNum).padStart(lineNumWidth," ");output.push(`+${lineNum} ${line}`),newLineNum++}else{let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(`-${lineNum} ${line}`),oldLineNum++}lastWasChange=!0}else{let nextPartIsChange=i<parts.length-1&&(parts[i+1].added||parts[i+1].removed),hasLeadingChange=lastWasChange,hasTrailingChange=nextPartIsChange;if(hasLeadingChange&&hasTrailingChange)if(raw.length<=contextLines*2)for(let line of raw){let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(` ${lineNum} ${line}`),oldLineNum++,newLineNum++}else{let leadingLines=raw.slice(0,contextLines),trailingLines=raw.slice(raw.length-contextLines),skippedLines=raw.length-leadingLines.length-trailingLines.length;for(let line of leadingLines){let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(` ${lineNum} ${line}`),oldLineNum++,newLineNum++}output.push(` ${"".padStart(lineNumWidth," ")} ...`),oldLineNum+=skippedLines,newLineNum+=skippedLines;for(let line of trailingLines){let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(` ${lineNum} ${line}`),oldLineNum++,newLineNum++}}else if(hasLeadingChange){let shownLines=raw.slice(0,contextLines),skippedLines=raw.length-shownLines.length;for(let line of shownLines){let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(` ${lineNum} ${line}`),oldLineNum++,newLineNum++}skippedLines>0&&(output.push(` ${"".padStart(lineNumWidth," ")} ...`),oldLineNum+=skippedLines,newLineNum+=skippedLines)}else if(hasTrailingChange){let skippedLines=Math.max(0,raw.length-contextLines);skippedLines>0&&(output.push(` ${"".padStart(lineNumWidth," ")} ...`),oldLineNum+=skippedLines,newLineNum+=skippedLines);for(let line of raw.slice(skippedLines)){let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(` ${lineNum} ${line}`),oldLineNum++,newLineNum++}}else oldLineNum+=raw.length,newLineNum+=raw.length;lastWasChange=!1}}return{diff:output.join(`
|
|
906
906
|
`),firstChangedLine}}var defaultEditDiffOperations={access:absolutePath=>access2(absolutePath,constants4.R_OK),readFile:absolutePath=>readFile8(absolutePath,"utf-8")};async function computeEditsDiff(path15,edits,cwd,operations=defaultEditDiffOperations){let absolutePath=resolveToCwd(path15,cwd);try{try{await operations.access(absolutePath)}catch(error2){let errorMessage2=error2 instanceof Error&&"code"in error2?`Error code: ${error2.code}`:String(error2);return{error:`Could not edit file: ${path15}. ${errorMessage2}.`}}let rawContent=await operations.readFile(absolutePath),{text:content}=splitBom(rawContent),normalizedContent=normalizeToLF2(content),{baseContent,newContent}=applyEditsToNormalizedContent2(normalizedContent,edits,path15);return generateDiffString2(baseContent,newContent)}catch(err2){return{error:err2 instanceof Error?err2.message:String(err2)}}}import{realpath}from"node:fs/promises";import{resolve as resolve9}from"node:path";var fileMutationQueues=new Map,registrationQueue=Promise.resolve();function isMissingPathError2(error2){return typeof error2=="object"&&error2!==null&&"code"in error2&&(error2.code==="ENOENT"||error2.code==="ENOTDIR")}async function getMutationQueueKey(filePath){let resolvedPath=resolve9(filePath);try{return await realpath(resolvedPath)}catch(error2){if(isMissingPathError2(error2))return resolvedPath;throw error2}}async function withFileMutationQueue2(filePath,fn){let registration=registrationQueue.then(async()=>{let key2=await getMutationQueueKey(filePath),currentQueue2=fileMutationQueues.get(key2)??Promise.resolve(),releaseNext2,nextQueue=new Promise(resolveQueue=>{releaseNext2=resolveQueue}),chainedQueue2=currentQueue2.then(()=>nextQueue);return fileMutationQueues.set(key2,chainedQueue2),{key:key2,currentQueue:currentQueue2,chainedQueue:chainedQueue2,releaseNext:releaseNext2}});registrationQueue=registration.then(()=>{},()=>{});let{key,currentQueue,chainedQueue,releaseNext}=await registration;await currentQueue;try{return await fn()}finally{releaseNext(),fileMutationQueues.get(key)===chainedQueue&&fileMutationQueues.delete(key)}}import{constants as constants5}from"fs";import{access as fsAccess2,readFile as fsReadFile,writeFile as fsWriteFile}from"fs/promises";var replaceEditSchema2=typebox_exports.Object({oldText:typebox_exports.String({description:"Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call."}),newText:typebox_exports.String({description:"Replacement text for this targeted edit."})},{}),editSchema2=typebox_exports.Object({path:typebox_exports.String({description:"Path to the file to edit (relative or absolute)"}),edits:typebox_exports.Array(replaceEditSchema2,{description:"One or more targeted replacements. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead."})},{}),editToolSystemPromptContribution={snippet:"Make precise file edits with exact text replacement, including multiple disjoint edits in one call",guidelines:["Use edit for precise changes (edits[].oldText must match exactly)","When changing multiple separate locations in one file, use one edit call with multiple entries in edits[] instead of multiple edit calls","Each edits[].oldText is matched against the original file, not after earlier edits are applied. Do not emit overlapping or nested edits. Merge nearby changes into one edit.","Keep edits[].oldText as small as possible while still being unique in the file. Do not pad with large unchanged regions."]};function isSingleEditInput(value){if(!value||typeof value!="object"||Array.isArray(value))return!1;let edit=value;return typeof edit.oldText=="string"&&typeof edit.newText=="string"}var defaultEditOperations={readFile:path15=>fsReadFile(path15),writeFile:(path15,content)=>fsWriteFile(path15,content,"utf-8"),access:path15=>fsAccess2(path15,constants5.R_OK|constants5.W_OK)};function prepareEditArguments(input){if(!input||typeof input!="object")return input;let args=input;if(typeof args.edits=="string")try{let parsed=JSON.parse(args.edits);Array.isArray(parsed)?args.edits=parsed:isSingleEditInput(parsed)&&(args.edits=[parsed])}catch{}else isSingleEditInput(args.edits)&&(args.edits=[args.edits]);let legacy=args;if(typeof legacy.oldText!="string"||typeof legacy.newText!="string")return args;let edits=Array.isArray(legacy.edits)?[...legacy.edits]:[];edits.push({oldText:legacy.oldText,newText:legacy.newText});let{oldText:_oldText,newText:_newText,...rest}=legacy;return{...rest,edits}}function validateEditInput(input){if(!Array.isArray(input.edits)||input.edits.length===0)throw new Error("Edit tool input is invalid. edits must contain at least one replacement.");return{path:input.path,edits:input.edits}}function createEditCallRenderComponent(){return Object.assign(new Box(1,1,text=>text),{preview:void 0,previewArgsKey:void 0,previewPending:!1,settledError:!1})}function getEditCallRenderComponent(state2,lastComponent){if(lastComponent instanceof Box){let component2=lastComponent;return state2.callComponent=component2,component2}if(state2.callComponent)return state2.callComponent;let component=createEditCallRenderComponent();return state2.callComponent=component,component}function getRenderablePreviewInput(args){if(!args)return null;let path15=typeof args.path=="string"?args.path:typeof args.file_path=="string"?args.file_path:null;return path15?Array.isArray(args.edits)&&args.edits.length>0&&args.edits.every(edit=>typeof edit?.oldText=="string"&&typeof edit?.newText=="string")?{path:path15,edits:args.edits}:typeof args.oldText=="string"&&typeof args.newText=="string"?{path:path15,edits:[{oldText:args.oldText,newText:args.newText}]}:null:null}function formatEditCall(args,theme2,cwd){let pathDisplay=renderToolPath(str(args?.file_path??args?.path),theme2,cwd);return`${theme2.fg("toolTitle",theme2.bold("edit"))} ${pathDisplay}`}function formatEditResult(args,preview,result,theme2,isError){let rawPath=str(args?.file_path??args?.path),previewDiff=preview&&!("error"in preview)?preview.diff:void 0,previewError=preview&&"error"in preview?preview.error:void 0;if(isError){let errorText=result.content.filter(c2=>c2.type==="text").map(c2=>c2.text||"").join(`
|
|
907
|
-
`);return!errorText||errorText===previewError?void 0:theme2.fg("error",errorText)}let resultDiff=result.details?.diff;if(resultDiff&&resultDiff!==previewDiff)return renderDiff(resultDiff,{filePath:rawPath??void 0})}function getEditHeaderBg(preview,settledError,theme2){return preview?"error"in preview?text=>theme2.bg("toolErrorBg",text):text=>theme2.bg("toolSuccessBg",text):settledError?text=>theme2.bg("toolErrorBg",text):text=>theme2.bg("toolPendingBg",text)}function buildEditCallComponent(component,args,theme2,cwd){if(component.setBgFn(getEditHeaderBg(component.preview,component.settledError,theme2)),component.clear(),component.addChild(new Text(formatEditCall(args,theme2,cwd),0,0)),!component.preview)return component;let body="error"in component.preview?theme2.fg("error",component.preview.error):renderDiff(component.preview.diff);return component.addChild(new Spacer(1)),component.addChild(new Text(body,0,0)),component}function setEditPreview(component,preview,argsKey){let current=component.preview,changed=current===void 0||("error"in current&&"error"in preview?current.error!==preview.error:"error"in current!="error"in preview)||!("error"in current)&&!("error"in preview)&&(current.diff!==preview.diff||current.firstChangedLine!==preview.firstChangedLine);return component.preview=preview,component.previewArgsKey=argsKey,component.previewPending=!1,changed}function createEditToolDefinition(cwd,options){let ops=options?.operations??defaultEditOperations;return{name:"edit",label:"edit",description:"Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.",promptSnippet:editToolSystemPromptContribution.snippet,promptGuidelines:[...editToolSystemPromptContribution.guidelines],parameters:editSchema2,constrainedSampling:{type:"json_schema",strict:"prefer"},renderShell:"self",prepareArguments:prepareEditArguments,async execute(_toolCallId,input,signal,_onUpdate,ctx){let{path:path15,edits}=validateEditInput(input),absolutePath=resolveToCwd(path15,ctx?.cwd||cwd);return withFileMutationQueue2(absolutePath,async()=>{let throwIfAborted=()=>{if(signal?.aborted)throw new Error("Operation aborted")};throwIfAborted();try{await ops.access(absolutePath)}catch(error2){throwIfAborted();let errorMessage2=error2 instanceof Error&&"code"in error2?`Error code: ${error2.code}`:String(error2);throw new Error(`Could not edit file: ${path15}. ${errorMessage2}.`)}throwIfAborted();let rawContent=(await ops.readFile(absolutePath)).toString("utf-8");throwIfAborted();let{bom,text:content}=splitBom(rawContent),originalEnding=detectLineEnding2(content),normalizedContent=normalizeToLF2(content),{baseContent,newContent}=applyEditsToNormalizedContent2(normalizedContent,edits,path15);throwIfAborted();let finalContent=bom+restoreLineEndings2(newContent,originalEnding);await ops.writeFile(absolutePath,finalContent),throwIfAborted();let diffResult=generateDiffString2(baseContent,newContent),patch=generateUnifiedPatch2(path15,baseContent,newContent);return{content:[{type:"text",text:`Successfully replaced ${edits.length} block(s) in ${path15}.`}],details:{diff:diffResult.diff,patch,firstChangedLine:diffResult.firstChangedLine}}})},renderCall(args,theme2,context){let component=getEditCallRenderComponent(context.state,context.lastComponent),previewInput=getRenderablePreviewInput(args),argsKey=previewInput?JSON.stringify({path:previewInput.path,edits:previewInput.edits}):void 0;if(component.previewArgsKey!==argsKey&&(component.preview=void 0,component.previewArgsKey=argsKey,component.previewPending=!1,component.settledError=!1),context.argsComplete&&previewInput&&!component.preview&&!component.previewPending){component.previewPending=!0;let requestKey=argsKey;computeEditsDiff(previewInput.path,previewInput.edits,context.cwd).then(preview=>{component.previewArgsKey===requestKey&&(setEditPreview(component,preview,requestKey),context.invalidate())})}return buildEditCallComponent(component,args,theme2,context.cwd)},renderResult(result,_options,theme2,context){let callComponent=context.state.callComponent,previewInput=getRenderablePreviewInput(context.args),argsKey=previewInput?JSON.stringify({path:previewInput.path,edits:previewInput.edits}):void 0,typedResult=result,resultDiff=context.isError?void 0:typedResult.details?.diff,changed=!1;callComponent&&(typeof resultDiff=="string"&&(changed=setEditPreview(callComponent,{diff:resultDiff,firstChangedLine:typedResult.details?.firstChangedLine},argsKey)||changed),callComponent.settledError!==context.isError&&(callComponent.settledError=context.isError,changed=!0),changed&&buildEditCallComponent(callComponent,context.args,theme2,context.cwd));let output=formatEditResult(context.args,callComponent?.preview,typedResult,theme2,context.isError),component=context.lastComponent??new Container;return component.clear(),output&&(component.addChild(new Spacer(1)),component.addChild(new Text(output,1,0))),component}}}function createEditTool2(cwd,options){return wrapToolDefinition(createEditToolDefinition(cwd,options))}import{createInterface as createInterface2}from"node:readline";import{spawn as spawn4}from"child_process";import path9 from"path";import{spawnSync as spawnSync3}from"child_process";import{createHash as createHash6}from"crypto";import{chmodSync,createWriteStream as createWriteStream2,existsSync as existsSync9,mkdirSync as mkdirSync8,readdirSync as readdirSync9,renameSync as renameSync2,rmSync as rmSync2}from"fs";import{arch,platform}from"os";import{join as join33}from"path";import{Readable,Transform}from"stream";import{pipeline}from"stream/promises";var TOOLS_DIR=getBinDir(),NETWORK_TIMEOUT_MS=1e4,DOWNLOAD_TIMEOUT_MS=12e4;function isOfflineModeEnabled(){let value=process.env.AGENT_FORGE_OFFLINE;return value?value==="1"||value.toLowerCase()==="true"||value.toLowerCase()==="yes":!1}var TOOLS={fd:{name:"fd",repo:"sharkdp/fd",binaryName:"fd",systemBinaryNames:["fd","fdfind"],tagPrefix:"v",pinnedVersion:"10.5.0",digests:{"fd-v10.5.0-x86_64-apple-darwin.tar.gz":"7e31028c62c6955877735d0406807aa484c2a5e6f86235a59e26c29c301da590","fd-v10.5.0-aarch64-apple-darwin.tar.gz":"b67e1836c468e42e411984b56e52fa7abec08c2bd22c867398e7cc134aac5e12","fd-v10.5.0-x86_64-unknown-linux-musl.tar.gz":"761c72dc8e120d85b22292063be8a796e2eeb20eb3e4f38b8fa2343ccf3514a7","fd-v10.5.0-aarch64-unknown-linux-musl.tar.gz":"d76c4317f7d5dba69f8a2a15856c90c777e7f0dd4e85f0de8c76de6992c374d4","fd-v10.5.0-x86_64-pc-windows-msvc.zip":"a227701b8551c35a9931d9f6da75503cf86d88e182d71fb849a70864c5d57cd7","fd-v10.5.0-aarch64-pc-windows-msvc.zip":"a2bcddcfd259b05357a77bbc6cd671fdb30f63fd266a0e748305890a8c5ceaa6"},getAssetName:(version,plat,architecture)=>plat==="darwin"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null},rg:{name:"ripgrep",repo:"BurntSushi/ripgrep",binaryName:"rg",tagPrefix:"",checksumSuffix:".sha256",getAssetName:(version,plat,architecture)=>plat==="darwin"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null}};function commandExists(cmd){try{let result=spawnSync3(cmd,["--version"],{stdio:"pipe"});return result.error===void 0||result.error===null}catch{return!1}}function getToolPath(tool){let config=TOOLS[tool];if(!config)return null;let localPath=join33(TOOLS_DIR,config.binaryName+(platform()==="win32"?".exe":""));if(existsSync9(localPath))return localPath;let systemBinaryNames=config.systemBinaryNames??[config.binaryName];for(let systemBinaryName of systemBinaryNames)if(commandExists(systemBinaryName))return systemBinaryName;return null}async function getLatestVersion(repo){let response2=await fetchWithRetry(`https://github.com/${repo}/releases/latest`,{headers:{"User-Agent":`${APP_NAME}-agent-forge`},redirect:"manual"},{timeoutMs:NETWORK_TIMEOUT_MS});try{await response2.body?.cancel()}catch{}let location=response2.status>=300&&response2.status<400?response2.headers.get("location"):null;if(!location)throw new Error(`Failed to resolve latest ${repo} release: HTTP ${response2.status} without redirect`);let tag=new URL(location,"https://github.com").pathname.split("/").pop();if(!tag||!location.includes("/releases/tag/"))throw new Error(`Failed to resolve latest ${repo} release: unexpected redirect to ${location}`);return decodeURIComponent(tag).replace(/^v/,"")}var DownloadIntegrityError=class extends Error{expectedSha256;actualSha256;constructor(url,expectedSha256,actualSha256){super(`Download integrity check failed for ${url}: expected sha256 ${expectedSha256}, got ${actualSha256}`),this.name="DownloadIntegrityError",this.expectedSha256=expectedSha256,this.actualSha256=actualSha256}};async function downloadFile(url,dest,expectedSha256){let response2=await fetchWithRetry(url,void 0,{timeoutMs:DOWNLOAD_TIMEOUT_MS});if(!response2.ok)throw new Error(`Download failed with HTTP ${response2.status}: ${url}`);if(!response2.body)throw new Error("No response body");let hash=createHash6("sha256"),digestTap=new Transform({transform(chunk,_encoding,callback){hash.update(chunk),callback(null,chunk)}}),fileStream=createWriteStream2(dest);if(await pipeline(Readable.fromWeb(response2.body),digestTap,fileStream),expectedSha256===void 0)return;let actual=hash.digest("hex"),expected=expectedSha256.trim().toLowerCase();if(actual!==expected)throw rmSync2(dest,{force:!0}),new DownloadIntegrityError(url,expected,actual)}var SHA256_HEX_PATTERN=/^[0-9a-f]{64}$/;async function resolveExpectedSha256(config,downloadUrl,assetName){let digests=config.digests;if(digests){let digest=digests[assetName];if(digest===void 0)throw new Error(`No committed sha256 for ${config.name} asset ${assetName}; refresh the pin and its digests`);return digest}if(config.checksumSuffix!==void 0)return fetchReleaseSha256(`${downloadUrl}${config.checksumSuffix}`)}async function fetchReleaseSha256(checksumUrl){let response2=await fetchWithRetry(checksumUrl,void 0,{timeoutMs:NETWORK_TIMEOUT_MS});if(!response2.ok)throw new Error(`Failed to fetch release checksum: HTTP ${response2.status}: ${checksumUrl}`);let digest=(await response2.text()).trim().split(/\s+/)[0]?.toLowerCase()??"";if(!SHA256_HEX_PATTERN.test(digest))throw new Error(`Release checksum has an unexpected format: ${checksumUrl}`);return digest}function findBinaryRecursively(rootDir,binaryFileName){let stack=[rootDir];for(;stack.length>0;){let currentDir=stack.pop();if(!currentDir)continue;let entries=readdirSync9(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join33(currentDir,entry.name);if(entry.isFile()&&entry.name===binaryFileName)return fullPath;entry.isDirectory()&&stack.push(fullPath)}}return null}function formatSpawnFailure(result){if(result.error?.message)return result.error.message;let stderr=result.stderr?.toString().trim();if(stderr)return stderr;let stdout=result.stdout?.toString().trim();return stdout||`exit status ${result.status??"unknown"}`}function runExtractionCommand(command,args){let result=spawnSync3(command,args,{stdio:"pipe"});return!result.error&&result.status===0?null:`${command}: ${formatSpawnFailure(result)}`}function extractTarGzArchive(archivePath,extractDir,assetName){let failure2=runExtractionCommand("tar",["xzf",archivePath,"-C",extractDir]);if(failure2)throw new Error(`Failed to extract ${assetName}: ${failure2}`)}function getWindowsTarCommand(){let systemRoot=process.env.SystemRoot??process.env.WINDIR;if(systemRoot){let systemTar=join33(systemRoot,"System32","tar.exe");if(existsSync9(systemTar))return systemTar}return"tar.exe"}function extractZipArchive(archivePath,extractDir,assetName){let failures=[];if(platform()==="win32"){let tarFailure=runExtractionCommand(getWindowsTarCommand(),["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure);let powershellFailure=runExtractionCommand("powershell.exe",["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command","& { param($archive, $destination) $ErrorActionPreference = 'Stop'; Expand-Archive -LiteralPath $archive -DestinationPath $destination -Force }",archivePath,extractDir]);if(!powershellFailure)return;failures.push(powershellFailure)}else{let unzipFailure=runExtractionCommand("unzip",["-q",archivePath,"-d",extractDir]);if(!unzipFailure)return;failures.push(unzipFailure);let tarFailure=runExtractionCommand("tar",["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure)}throw new Error(`Failed to extract ${assetName}: ${failures.join("; ")}`)}async function downloadTool(tool){let config=TOOLS[tool];if(!config)throw new Error(`Unknown tool: ${tool}`);let plat=platform(),architecture=arch(),version=config.pinnedVersion??await getLatestVersion(config.repo),assetName=config.getAssetName(version,plat,architecture);if(!assetName)throw new Error(`Unsupported platform: ${plat}/${architecture}`);mkdirSync8(TOOLS_DIR,{recursive:!0});let downloadUrl=`https://github.com/${config.repo}/releases/download/${config.tagPrefix}${version}/${assetName}`,expectedSha256=await resolveExpectedSha256(config,downloadUrl,assetName),archivePath=join33(TOOLS_DIR,assetName),binaryExt=plat==="win32"?".exe":"",binaryPath=join33(TOOLS_DIR,config.binaryName+binaryExt);await downloadFile(downloadUrl,archivePath,expectedSha256);let extractDir=join33(TOOLS_DIR,`extract_tmp_${config.binaryName}_${process.pid}_${Date.now()}_${Math.random().toString(36).slice(2,10)}`);mkdirSync8(extractDir,{recursive:!0});try{if(assetName.endsWith(".tar.gz"))extractTarGzArchive(archivePath,extractDir,assetName);else if(assetName.endsWith(".zip"))extractZipArchive(archivePath,extractDir,assetName);else throw new Error(`Unsupported archive format: ${assetName}`);let binaryFileName=config.binaryName+binaryExt,extractedDir=join33(extractDir,assetName.replace(/\.(tar\.gz|zip)$/,"")),extractedBinary=[join33(extractedDir,binaryFileName),join33(extractDir,binaryFileName)].find(candidate=>existsSync9(candidate));if(extractedBinary||(extractedBinary=findBinaryRecursively(extractDir,binaryFileName)??void 0),extractedBinary)renameSync2(extractedBinary,binaryPath);else throw new Error(`Binary not found in archive: expected ${binaryFileName} under ${extractDir}`);plat!=="win32"&&chmodSync(binaryPath,493)}finally{rmSync2(archivePath,{force:!0}),rmSync2(extractDir,{recursive:!0,force:!0})}return binaryPath}var TERMUX_PACKAGES={fd:"fd",rg:"ripgrep"};async function ensureTool(tool,onStatus){let existingPath=getToolPath(tool);if(existingPath)return existingPath;let config=TOOLS[tool];if(config){if(isOfflineModeEnabled()){onStatus?.({type:"warning",message:`${config.name} not found. Offline mode enabled, skipping download.`});return}if(platform()==="android"){let pkgName=TERMUX_PACKAGES[tool]??tool;onStatus?.({type:"warning",message:`${config.name} not found. Install with: pkg install ${pkgName}`});return}onStatus?.({type:"info",message:`${config.name} not found. Downloading...`});try{let path15=await downloadTool(tool);return onStatus?.({type:"info",message:`${config.name} installed to ${path15}`}),path15}catch(e){let messages=[];for(let current=e,depth=0;current instanceof Error&&depth<5;current=current.cause,depth++)messages.includes(current.message)||messages.push(current.message);onStatus?.({type:"warning",message:`Failed to download ${config.name}: ${messages.length>0?messages.join(": "):String(e)}`});return}}}function relativizeFindResultPath(resultPath,searchPath,pathModule=path9){let hadTrailingSeparator=resultPath.endsWith(pathModule.sep)||pathModule.sep==="\\"&&resultPath.endsWith("/"),posixPath=(pathModule.isAbsolute(resultPath)?pathModule.relative(searchPath,resultPath):resultPath).split(pathModule.sep).join("/");return hadTrailingSeparator&&!posixPath.endsWith("/")?`${posixPath}/`:posixPath}var findSchema=typebox_exports.Object({pattern:typebox_exports.String({description:"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'"}),path:typebox_exports.Optional(typebox_exports.String({description:"Directory to search in (default: current directory)"})),limit:typebox_exports.Optional(typebox_exports.Number({description:"Maximum number of results (default: 1000)"}))}),findToolSystemPromptContribution={snippet:"Find files by glob pattern (respects .gitignore)",guidelines:[]},DEFAULT_LIMIT=1e3,defaultFindOperations={exists:pathExists,glob:()=>[]};function formatFindCall(args,theme2){let pattern=str(args?.pattern),rawPath=str(args?.path),path15=rawPath!==null?shortenPath(rawPath||"."):null,limit=args?.limit,invalidArg=invalidArgText(theme2),text=theme2.fg("toolTitle",theme2.bold("find"))+" "+(pattern===null?invalidArg:theme2.fg("accent",pattern||""))+theme2.fg("toolOutput",` in ${path15===null?invalidArg:path15}`);return limit!==void 0&&(text+=theme2.fg("toolOutput",` (limit ${limit})`)),text}function formatFindResult(result,options,theme2,showImages){let output=getTextOutput(result,showImages).trim(),text="";if(output){let lines=output.split(`
|
|
907
|
+
`);return!errorText||errorText===previewError?void 0:theme2.fg("error",errorText)}let resultDiff=result.details?.diff;if(resultDiff&&resultDiff!==previewDiff)return renderDiff(resultDiff,{filePath:rawPath??void 0})}function getEditHeaderBg(preview,settledError,theme2){return preview?"error"in preview?text=>theme2.bg("toolErrorBg",text):text=>theme2.bg("toolSuccessBg",text):settledError?text=>theme2.bg("toolErrorBg",text):text=>theme2.bg("toolPendingBg",text)}function buildEditCallComponent(component,args,theme2,cwd){if(component.setBgFn(getEditHeaderBg(component.preview,component.settledError,theme2)),component.clear(),component.addChild(new Text(formatEditCall(args,theme2,cwd),0,0)),!component.preview)return component;let body="error"in component.preview?theme2.fg("error",component.preview.error):renderDiff(component.preview.diff);return component.addChild(new Spacer(1)),component.addChild(new Text(body,0,0)),component}function setEditPreview(component,preview,argsKey){let current=component.preview,changed=current===void 0||("error"in current&&"error"in preview?current.error!==preview.error:"error"in current!="error"in preview)||!("error"in current)&&!("error"in preview)&&(current.diff!==preview.diff||current.firstChangedLine!==preview.firstChangedLine);return component.preview=preview,component.previewArgsKey=argsKey,component.previewPending=!1,changed}function createEditToolDefinition(cwd,options){let ops=options?.operations??defaultEditOperations;return{name:"edit",label:"edit",description:"Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.",promptSnippet:editToolSystemPromptContribution.snippet,promptGuidelines:[...editToolSystemPromptContribution.guidelines],parameters:editSchema2,constrainedSampling:{type:"json_schema",strict:"prefer"},renderShell:"self",prepareArguments:prepareEditArguments,async execute(_toolCallId,input,signal,_onUpdate,ctx){let{path:path15,edits}=validateEditInput(input),absolutePath=resolveToCwd(path15,ctx?.cwd||cwd);return withFileMutationQueue2(absolutePath,async()=>{let throwIfAborted=()=>{if(signal?.aborted)throw new Error("Operation aborted")};throwIfAborted();try{await ops.access(absolutePath)}catch(error2){throwIfAborted();let errorMessage2=error2 instanceof Error&&"code"in error2?`Error code: ${error2.code}`:String(error2);throw new Error(`Could not edit file: ${path15}. ${errorMessage2}.`)}throwIfAborted();let rawContent=(await ops.readFile(absolutePath)).toString("utf-8");throwIfAborted();let{bom,text:content}=splitBom(rawContent),originalEnding=detectLineEnding2(content),normalizedContent=normalizeToLF2(content),{baseContent,newContent}=applyEditsToNormalizedContent2(normalizedContent,edits,path15);throwIfAborted();let finalContent=bom+restoreLineEndings2(newContent,originalEnding);await ops.writeFile(absolutePath,finalContent),throwIfAborted();let diffResult=generateDiffString2(baseContent,newContent),patch=generateUnifiedPatch2(path15,baseContent,newContent);return{content:[{type:"text",text:`Successfully replaced ${edits.length} block(s) in ${path15}.`}],details:{diff:diffResult.diff,patch,firstChangedLine:diffResult.firstChangedLine}}})},renderCall(args,theme2,context){let component=getEditCallRenderComponent(context.state,context.lastComponent),previewInput=getRenderablePreviewInput(args),argsKey=previewInput?JSON.stringify({path:previewInput.path,edits:previewInput.edits}):void 0;if(component.previewArgsKey!==argsKey&&(component.preview=void 0,component.previewArgsKey=argsKey,component.previewPending=!1,component.settledError=!1),context.argsComplete&&previewInput&&!component.preview&&!component.previewPending){component.previewPending=!0;let requestKey=argsKey;computeEditsDiff(previewInput.path,previewInput.edits,context.cwd).then(preview=>{component.previewArgsKey===requestKey&&(setEditPreview(component,preview,requestKey),context.invalidate())})}return buildEditCallComponent(component,args,theme2,context.cwd)},renderResult(result,_options,theme2,context){let callComponent=context.state.callComponent,previewInput=getRenderablePreviewInput(context.args),argsKey=previewInput?JSON.stringify({path:previewInput.path,edits:previewInput.edits}):void 0,typedResult=result,resultDiff=context.isError?void 0:typedResult.details?.diff,changed=!1;callComponent&&(typeof resultDiff=="string"&&(changed=setEditPreview(callComponent,{diff:resultDiff,firstChangedLine:typedResult.details?.firstChangedLine},argsKey)||changed),callComponent.settledError!==context.isError&&(callComponent.settledError=context.isError,changed=!0),changed&&buildEditCallComponent(callComponent,context.args,theme2,context.cwd));let output=formatEditResult(context.args,callComponent?.preview,typedResult,theme2,context.isError),component=context.lastComponent??new Container;return component.clear(),output&&(component.addChild(new Spacer(1)),component.addChild(new Text(output,1,0))),component}}}function createEditTool2(cwd,options){return wrapToolDefinition(createEditToolDefinition(cwd,options))}import{createInterface as createInterface2}from"node:readline";import{spawn as spawn4}from"child_process";import path9 from"path";import{spawnSync as spawnSync3}from"child_process";import{createHash as createHash6}from"crypto";import{chmodSync,createWriteStream as createWriteStream2,existsSync as existsSync9,mkdirSync as mkdirSync8,readdirSync as readdirSync9,renameSync as renameSync2,rmSync as rmSync2}from"fs";import{arch,platform}from"os";import{join as join33}from"path";import{Readable,Transform}from"stream";import{pipeline}from"stream/promises";var TOOLS_DIR=getBinDir(),NETWORK_TIMEOUT_MS=1e4,DOWNLOAD_TIMEOUT_MS=12e4,DOWNLOAD_PROGRESS_INTERVAL_MS=15e3;function isOfflineModeEnabled(){let value=process.env.AGENT_FORGE_OFFLINE;return value?value==="1"||value.toLowerCase()==="true"||value.toLowerCase()==="yes":!1}var TOOLS={fd:{name:"fd",repo:"sharkdp/fd",binaryName:"fd",systemBinaryNames:["fd","fdfind"],tagPrefix:"v",pinnedVersion:"10.5.0",digests:{"fd-v10.5.0-x86_64-apple-darwin.tar.gz":"7e31028c62c6955877735d0406807aa484c2a5e6f86235a59e26c29c301da590","fd-v10.5.0-aarch64-apple-darwin.tar.gz":"b67e1836c468e42e411984b56e52fa7abec08c2bd22c867398e7cc134aac5e12","fd-v10.5.0-x86_64-unknown-linux-musl.tar.gz":"761c72dc8e120d85b22292063be8a796e2eeb20eb3e4f38b8fa2343ccf3514a7","fd-v10.5.0-aarch64-unknown-linux-musl.tar.gz":"d76c4317f7d5dba69f8a2a15856c90c777e7f0dd4e85f0de8c76de6992c374d4","fd-v10.5.0-x86_64-pc-windows-msvc.zip":"a227701b8551c35a9931d9f6da75503cf86d88e182d71fb849a70864c5d57cd7","fd-v10.5.0-aarch64-pc-windows-msvc.zip":"a2bcddcfd259b05357a77bbc6cd671fdb30f63fd266a0e748305890a8c5ceaa6"},getAssetName:(version,plat,architecture)=>plat==="darwin"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null},rg:{name:"ripgrep",repo:"BurntSushi/ripgrep",binaryName:"rg",tagPrefix:"",checksumSuffix:".sha256",getAssetName:(version,plat,architecture)=>plat==="darwin"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null}};function commandExists(cmd){try{let result=spawnSync3(cmd,["--version"],{stdio:"pipe"});return result.error===void 0||result.error===null}catch{return!1}}function getToolPath(tool){let config=TOOLS[tool];if(!config)return null;let localPath=join33(TOOLS_DIR,config.binaryName+(platform()==="win32"?".exe":""));if(existsSync9(localPath))return localPath;let systemBinaryNames=config.systemBinaryNames??[config.binaryName];for(let systemBinaryName of systemBinaryNames)if(commandExists(systemBinaryName))return systemBinaryName;return null}async function getLatestVersion(repo){let response2=await fetchWithRetry(`https://github.com/${repo}/releases/latest`,{headers:{"User-Agent":`${APP_NAME}-agent-forge`},redirect:"manual"},{timeoutMs:NETWORK_TIMEOUT_MS});try{await response2.body?.cancel()}catch{}let location=response2.status>=300&&response2.status<400?response2.headers.get("location"):null;if(!location)throw new Error(`Failed to resolve latest ${repo} release: HTTP ${response2.status} without redirect`);let tag=new URL(location,"https://github.com").pathname.split("/").pop();if(!tag||!location.includes("/releases/tag/"))throw new Error(`Failed to resolve latest ${repo} release: unexpected redirect to ${location}`);return decodeURIComponent(tag).replace(/^v/,"")}var DownloadIntegrityError=class extends Error{expectedSha256;actualSha256;constructor(url,expectedSha256,actualSha256){super(`Download integrity check failed for ${url}: expected sha256 ${expectedSha256}, got ${actualSha256}`),this.name="DownloadIntegrityError",this.expectedSha256=expectedSha256,this.actualSha256=actualSha256}};async function downloadFile(url,dest,expectedSha256){let response2=await fetchWithRetry(url,void 0,{timeoutMs:DOWNLOAD_TIMEOUT_MS});if(!response2.ok)throw new Error(`Download failed with HTTP ${response2.status}: ${url}`);if(!response2.body)throw new Error("No response body");let hash=createHash6("sha256"),digestTap=new Transform({transform(chunk,_encoding,callback){hash.update(chunk),callback(null,chunk)}}),fileStream=createWriteStream2(dest);if(await pipeline(Readable.fromWeb(response2.body),digestTap,fileStream),expectedSha256===void 0)return;let actual=hash.digest("hex"),expected=expectedSha256.trim().toLowerCase();if(actual!==expected)throw rmSync2(dest,{force:!0}),new DownloadIntegrityError(url,expected,actual)}var SHA256_HEX_PATTERN=/^[0-9a-f]{64}$/;async function resolveExpectedSha256(config,downloadUrl,assetName){let digests=config.digests;if(digests){let digest=digests[assetName];if(digest===void 0)throw new Error(`No committed sha256 for ${config.name} asset ${assetName}; refresh the pin and its digests`);return digest}if(config.checksumSuffix!==void 0)return fetchReleaseSha256(`${downloadUrl}${config.checksumSuffix}`)}async function fetchReleaseSha256(checksumUrl){let response2=await fetchWithRetry(checksumUrl,void 0,{timeoutMs:NETWORK_TIMEOUT_MS});if(!response2.ok)throw new Error(`Failed to fetch release checksum: HTTP ${response2.status}: ${checksumUrl}`);let digest=(await response2.text()).trim().split(/\s+/)[0]?.toLowerCase()??"";if(!SHA256_HEX_PATTERN.test(digest))throw new Error(`Release checksum has an unexpected format: ${checksumUrl}`);return digest}function findBinaryRecursively(rootDir,binaryFileName){let stack=[rootDir];for(;stack.length>0;){let currentDir=stack.pop();if(!currentDir)continue;let entries=readdirSync9(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join33(currentDir,entry.name);if(entry.isFile()&&entry.name===binaryFileName)return fullPath;entry.isDirectory()&&stack.push(fullPath)}}return null}function formatSpawnFailure(result){if(result.error?.message)return result.error.message;let stderr=result.stderr?.toString().trim();if(stderr)return stderr;let stdout=result.stdout?.toString().trim();return stdout||`exit status ${result.status??"unknown"}`}function runExtractionCommand(command,args){let result=spawnSync3(command,args,{stdio:"pipe"});return!result.error&&result.status===0?null:`${command}: ${formatSpawnFailure(result)}`}function extractTarGzArchive(archivePath,extractDir,assetName){let failure2=runExtractionCommand("tar",["xzf",archivePath,"-C",extractDir]);if(failure2)throw new Error(`Failed to extract ${assetName}: ${failure2}`)}function getWindowsTarCommand(){let systemRoot=process.env.SystemRoot??process.env.WINDIR;if(systemRoot){let systemTar=join33(systemRoot,"System32","tar.exe");if(existsSync9(systemTar))return systemTar}return"tar.exe"}function extractZipArchive(archivePath,extractDir,assetName){let failures=[];if(platform()==="win32"){let tarFailure=runExtractionCommand(getWindowsTarCommand(),["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure);let powershellFailure=runExtractionCommand("powershell.exe",["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command","& { param($archive, $destination) $ErrorActionPreference = 'Stop'; Expand-Archive -LiteralPath $archive -DestinationPath $destination -Force }",archivePath,extractDir]);if(!powershellFailure)return;failures.push(powershellFailure)}else{let unzipFailure=runExtractionCommand("unzip",["-q",archivePath,"-d",extractDir]);if(!unzipFailure)return;failures.push(unzipFailure);let tarFailure=runExtractionCommand("tar",["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure)}throw new Error(`Failed to extract ${assetName}: ${failures.join("; ")}`)}async function downloadTool(tool){let config=TOOLS[tool];if(!config)throw new Error(`Unknown tool: ${tool}`);let plat=platform(),architecture=arch(),version=config.pinnedVersion??await getLatestVersion(config.repo),assetName=config.getAssetName(version,plat,architecture);if(!assetName)throw new Error(`Unsupported platform: ${plat}/${architecture}`);mkdirSync8(TOOLS_DIR,{recursive:!0});let downloadUrl=`https://github.com/${config.repo}/releases/download/${config.tagPrefix}${version}/${assetName}`,expectedSha256=await resolveExpectedSha256(config,downloadUrl,assetName),archivePath=join33(TOOLS_DIR,assetName),binaryExt=plat==="win32"?".exe":"",binaryPath=join33(TOOLS_DIR,config.binaryName+binaryExt);try{await downloadFile(downloadUrl,archivePath,expectedSha256)}catch(error2){throw rmSync2(archivePath,{force:!0}),error2}let extractDir=join33(TOOLS_DIR,`extract_tmp_${config.binaryName}_${process.pid}_${Date.now()}_${Math.random().toString(36).slice(2,10)}`);mkdirSync8(extractDir,{recursive:!0});try{if(assetName.endsWith(".tar.gz"))extractTarGzArchive(archivePath,extractDir,assetName);else if(assetName.endsWith(".zip"))extractZipArchive(archivePath,extractDir,assetName);else throw new Error(`Unsupported archive format: ${assetName}`);let binaryFileName=config.binaryName+binaryExt,extractedDir=join33(extractDir,assetName.replace(/\.(tar\.gz|zip)$/,"")),extractedBinary=[join33(extractedDir,binaryFileName),join33(extractDir,binaryFileName)].find(candidate=>existsSync9(candidate));if(extractedBinary||(extractedBinary=findBinaryRecursively(extractDir,binaryFileName)??void 0),extractedBinary)renameSync2(extractedBinary,binaryPath);else throw new Error(`Binary not found in archive: expected ${binaryFileName} under ${extractDir}`);plat!=="win32"&&chmodSync(binaryPath,493)}finally{rmSync2(archivePath,{force:!0}),rmSync2(extractDir,{recursive:!0,force:!0})}return binaryPath}var TERMUX_PACKAGES={fd:"fd",rg:"ripgrep"};async function ensureTool(tool,onStatus){let existingPath=getToolPath(tool);if(existingPath)return existingPath;let config=TOOLS[tool];if(!config)return;if(isOfflineModeEnabled()){onStatus?.({type:"warning",message:`${config.name} not found. Offline mode enabled, skipping download.`});return}if(platform()==="android"){let pkgName=TERMUX_PACKAGES[tool]??tool;onStatus?.({type:"warning",message:`${config.name} not found. Install with: pkg install ${pkgName}`});return}onStatus?.({type:"info",message:`${config.name} not found. Downloading from GitHub releases (slow networks can take up to ${Math.round(DOWNLOAD_TIMEOUT_MS/1e3)}s; set AGENT_FORGE_OFFLINE=1 to skip)...`});let startedAt=Date.now(),progressTicker=setInterval(()=>{onStatus?.({type:"info",message:`${config.name} still downloading... ${Math.round((Date.now()-startedAt)/1e3)}s elapsed`})},DOWNLOAD_PROGRESS_INTERVAL_MS);try{let path15=await downloadTool(tool);return onStatus?.({type:"info",message:`${config.name} installed to ${path15}`}),path15}catch(e){let messages=[];for(let current=e,depth=0;current instanceof Error&&depth<5;current=current.cause,depth++)messages.includes(current.message)||messages.push(current.message);onStatus?.({type:"warning",message:`Failed to download ${config.name}: ${messages.length>0?messages.join(": "):String(e)}`});return}finally{clearInterval(progressTicker)}}function relativizeFindResultPath(resultPath,searchPath,pathModule=path9){let hadTrailingSeparator=resultPath.endsWith(pathModule.sep)||pathModule.sep==="\\"&&resultPath.endsWith("/"),posixPath=(pathModule.isAbsolute(resultPath)?pathModule.relative(searchPath,resultPath):resultPath).split(pathModule.sep).join("/");return hadTrailingSeparator&&!posixPath.endsWith("/")?`${posixPath}/`:posixPath}var findSchema=typebox_exports.Object({pattern:typebox_exports.String({description:"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'"}),path:typebox_exports.Optional(typebox_exports.String({description:"Directory to search in (default: current directory)"})),limit:typebox_exports.Optional(typebox_exports.Number({description:"Maximum number of results (default: 1000)"}))}),findToolSystemPromptContribution={snippet:"Find files by glob pattern (respects .gitignore)",guidelines:[]},DEFAULT_LIMIT=1e3,defaultFindOperations={exists:pathExists,glob:()=>[]};function formatFindCall(args,theme2){let pattern=str(args?.pattern),rawPath=str(args?.path),path15=rawPath!==null?shortenPath(rawPath||"."):null,limit=args?.limit,invalidArg=invalidArgText(theme2),text=theme2.fg("toolTitle",theme2.bold("find"))+" "+(pattern===null?invalidArg:theme2.fg("accent",pattern||""))+theme2.fg("toolOutput",` in ${path15===null?invalidArg:path15}`);return limit!==void 0&&(text+=theme2.fg("toolOutput",` (limit ${limit})`)),text}function formatFindResult(result,options,theme2,showImages){let output=getTextOutput(result,showImages).trim(),text="";if(output){let lines=output.split(`
|
|
908
908
|
`),maxLines=options.expanded?lines.length:20,displayLines=lines.slice(0,maxLines),remaining=lines.length-maxLines;text+=`
|
|
909
909
|
${displayLines.map(line=>theme2.fg("toolOutput",line)).join(`
|
|
910
910
|
`)}`,remaining>0&&(text+=`${theme2.fg("muted",`
|
|
@@ -1487,7 +1487,7 @@ Auth commands require at least one of --provider or --model. Checks refresh expi
|
|
|
1487
1487
|
${content}
|
|
1488
1488
|
</file>
|
|
1489
1489
|
`}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(source_default.red(`Error: Could not read file ${absolutePath}: ${message}`)),process.exit(1)}}return{text,images}}function buildInitialMessage({parsed,fileText,fileImages,stdinContent}){let parts=[];return stdinContent!==void 0&&parts.push(stdinContent),fileText&&parts.push(fileText),parsed.messages.length>0&&(parts.push(parsed.messages[0]),parsed.messages.shift()),{initialMessage:parts.length>0?parts.join(""):void 0,initialImages:fileImages&&fileImages.length>0?fileImages:void 0}}function formatTokenCount(count){if(count>=1e6){let millions=count/1e6;return millions%1===0?`${millions}M`:`${millions.toFixed(1)}M`}if(count>=1e3){let thousands=count/1e3;return thousands%1===0?`${thousands}K`:`${thousands.toFixed(1)}K`}return count.toString()}async function listModels(modelRuntime,searchPattern,signal){let loadError=modelRuntime.getError();loadError&&console.error(source_default.yellow(`Warning: errors loading models.json:
|
|
1490
|
-
${loadError}`));let models=[...await modelRuntime.getAvailable(void 0,{signal})];if(models.length===0){console.log(formatNoModelsAvailableMessage());return}let filteredModels=models;if(searchPattern&&(filteredModels=fuzzyFilter(models,searchPattern,m2=>`${m2.provider} ${m2.id}`)),filteredModels.length===0){console.log(`No models matching "${searchPattern}"`);return}filteredModels.sort((a,b2)=>{let providerCmp=a.provider.localeCompare(b2.provider);return providerCmp!==0?providerCmp:a.id.localeCompare(b2.id)});let rows=filteredModels.map(m2=>({provider:m2.provider,model:m2.id,context:formatTokenCount(m2.contextWindow),maxOut:formatTokenCount(m2.maxTokens),thinking:m2.reasoning?"yes":"no",images:m2.input.includes("image")?"yes":"no"})),headers={provider:"provider",model:"model",context:"context",maxOut:"max-out",thinking:"thinking",images:"images"},widths={provider:Math.max(headers.provider.length,...rows.map(r=>r.provider.length)),model:Math.max(headers.model.length,...rows.map(r=>r.model.length)),context:Math.max(headers.context.length,...rows.map(r=>r.context.length)),maxOut:Math.max(headers.maxOut.length,...rows.map(r=>r.maxOut.length)),thinking:Math.max(headers.thinking.length,...rows.map(r=>r.thinking.length)),images:Math.max(headers.images.length,...rows.map(r=>r.images.length))},headerLine=[headers.provider.padEnd(widths.provider),headers.model.padEnd(widths.model),headers.context.padEnd(widths.context),headers.maxOut.padEnd(widths.maxOut),headers.thinking.padEnd(widths.thinking),headers.images.padEnd(widths.images)].join(" ");console.log(headerLine);for(let row of rows){let line=[row.provider.padEnd(widths.provider),row.model.padEnd(widths.model),row.context.padEnd(widths.context),row.maxOut.padEnd(widths.maxOut),row.thinking.padEnd(widths.thinking),row.images.padEnd(widths.images)].join(" ");console.log(line)}}import{join as join59}from"node:path";function printResponse(response2,write){write(response2.text),response2.status!=="succeeded"&&(process.exitCode=1)}function buildMarketCli(options){let{market,overrides}=options;return createPluginEcosystemCliV1({host:overrides?.host??defaultPluginHostFactsV1(),manifests:listBuiltinPluginManifestsV1(),registry:overrides?.registry??market?.cliRegistry,...market?.acquisition===void 0?{}:{acquisition:market.acquisition},installer:overrides?.installer??market?.installer,...overrides?.distribution!==void 0||market?.distribution!==void 0?{distribution:overrides?.distribution??market.distribution}:{},stateStore:overrides?.stateStore??market?.stateStore??createPluginStateStoreV1({filePath:join59(options.agentDir,"plugin-state.json")}),projectStateStore:overrides?.projectStateStore??market?.projectStateStore??createPluginStateStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,"plugin-state.json")}),projectScopeRef:projectPluginScopeRefV1(options.cwd),selectionStore:overrides?.selectionStore??createPluginSelectionStoreV1({filePath:join59(options.agentDir,".plugin-selection.json")}),projectSelectionStore:overrides?.projectSelectionStore??createPluginSelectionStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,".plugin-selection.json")})})}async function createDefaultPluginManagerControllerV1(options){let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=await createDefaultPluginMarketWiringV1({agentDir,cwd}),cli=buildMarketCli({agentDir,cwd,market});return{controller:createPluginManagerControllerV1({registry:market.registry,stateStore:options.scope==="project"?market.projectStateStore:market.stateStore,cli}),close:market.close}}async function handlePluginEcosystemCommand(args,options={}){if(args[0]!=="plugin")return!1;let write=options.write??(line=>console.log(line)),agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=options.registry===void 0&&options.installer===void 0?await createDefaultPluginMarketWiringV1({agentDir,cwd}):void 0;try{let response2=await buildMarketCli({agentDir,cwd,market,overrides:options}).execute({argv:args.slice(1)});return printResponse(response2,write),!0}finally{await market?.close()}}import{join as join60}from"node:path";var DEFAULT_DURABLE_LOG_RELATIVE_PATH=join60("durable","remote-server-ops.jsonl");function isAddrInUse(error2){return typeof error2=="object"&&error2!==null&&error2.code==="EADDRINUSE"}async function runServeMode(port,options){let handle,createListener=options?.createListener??(()=>createWsServerListener({port,httpRequestHandler:(request,response2)=>handle?.server.handleArtifactHttpRequest(request,response2)??!1,onError:error2=>{console.error(`remote-server error: ${error2.message}`)}})),startServer=options?.startServer??startCodingAgentRemoteServer,workspaceRoots=options?.workspaceRoots,sessionDir=options?.sessionDir,durable=options?.durable??createDurableService({backend:createFileDurableStoreBackend({path:join60(getAgentDir(),DEFAULT_DURABLE_LOG_RELATIVE_PATH)})}),writerId=readOrCreateWriterId(getAgentDir());try{handle=await startServer({sessionSourceOptions:{sessionsDir:sessionDir??getSessionsDir(),cwd:process.cwd(),agentDir:getAgentDir(),...workspaceRoots===void 0||workspaceRoots.length===0?{}:{workspaceRoots},agentTaskResults:{store:durable,writerId},subagentPoolFromSelfInvocation:!0,...options?.hostLogger===void 0?{}:{hostLogger:options.hostLogger}},listeners:[createListener()],onError:error2=>{console.error(`remote-server error: ${error2.message}`)},durable,writerId})}catch(error2){throw isAddrInUse(error2)&&(console.error(`Port ${port} is already in use`),process.exit(1)),error2}let closing=!1,shutdown=()=>{closing||(closing=!0,handle.close().then(()=>{process.exit(0)}).catch(error2=>{console.error(`Remote server shutdown failed: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}))};process.on("SIGINT",shutdown),process.on("SIGTERM",shutdown),console.log(`Remote server listening on ${handle.addresses.join(", ")}`)}import{existsSync as existsSync29}from"fs";var THEME_OPTIONS=[{value:"dark",label:"Dark"},{value:"light",label:"Light"}],ANALYTICS_OPTIONS=[{value:!0,label:"Share anonymous usage data"},{value:!1,label:"Don't share"}],SETUP_LOGO_LINES=["\u2588\u2588\u2588\u2588\u2588\u2588","\u2588\u2588 \u2588\u2588","\u2588\u2588\u2588\u2588 \u2588\u2588","\u2588\u2588 \u2588\u2588"],FirstTimeSetupComponent=class extends Container{step="theme";themeIndex;analyticsIndex=0;options;constructor(options){super(),this.options=options,this.themeIndex=Math.max(0,THEME_OPTIONS.findIndex(option=>option.value===options.detectedTheme)),this.update()}update(){this.clear(),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("accent",SETUP_LOGO_LINES.join(`
|
|
1490
|
+
${loadError}`));let models=[...await modelRuntime.getAvailable(void 0,{signal})];if(models.length===0){console.log(formatNoModelsAvailableMessage());return}let filteredModels=models;if(searchPattern&&(filteredModels=fuzzyFilter(models,searchPattern,m2=>`${m2.provider} ${m2.id}`)),filteredModels.length===0){console.log(`No models matching "${searchPattern}"`);return}filteredModels.sort((a,b2)=>{let providerCmp=a.provider.localeCompare(b2.provider);return providerCmp!==0?providerCmp:a.id.localeCompare(b2.id)});let rows=filteredModels.map(m2=>({provider:m2.provider,model:m2.id,context:formatTokenCount(m2.contextWindow),maxOut:formatTokenCount(m2.maxTokens),thinking:m2.reasoning?"yes":"no",images:m2.input.includes("image")?"yes":"no"})),headers={provider:"provider",model:"model",context:"context",maxOut:"max-out",thinking:"thinking",images:"images"},widths={provider:Math.max(headers.provider.length,...rows.map(r=>r.provider.length)),model:Math.max(headers.model.length,...rows.map(r=>r.model.length)),context:Math.max(headers.context.length,...rows.map(r=>r.context.length)),maxOut:Math.max(headers.maxOut.length,...rows.map(r=>r.maxOut.length)),thinking:Math.max(headers.thinking.length,...rows.map(r=>r.thinking.length)),images:Math.max(headers.images.length,...rows.map(r=>r.images.length))},headerLine=[headers.provider.padEnd(widths.provider),headers.model.padEnd(widths.model),headers.context.padEnd(widths.context),headers.maxOut.padEnd(widths.maxOut),headers.thinking.padEnd(widths.thinking),headers.images.padEnd(widths.images)].join(" ");console.log(headerLine);for(let row of rows){let line=[row.provider.padEnd(widths.provider),row.model.padEnd(widths.model),row.context.padEnd(widths.context),row.maxOut.padEnd(widths.maxOut),row.thinking.padEnd(widths.thinking),row.images.padEnd(widths.images)].join(" ");console.log(line)}}import{join as join59}from"node:path";function printResponse(response2,write){write(response2.text),response2.status!=="succeeded"&&(process.exitCode=1)}function buildMarketCli(options){let{market,overrides}=options;return createPluginEcosystemCliV1({host:overrides?.host??defaultPluginHostFactsV1(),manifests:listBuiltinPluginManifestsV1(),registry:overrides?.registry??market?.cliRegistry,...market?.acquisition===void 0?{}:{acquisition:market.acquisition},installer:overrides?.installer??market?.installer,...overrides?.distribution!==void 0||market?.distribution!==void 0?{distribution:overrides?.distribution??market.distribution}:{},stateStore:overrides?.stateStore??market?.stateStore??createPluginStateStoreV1({filePath:join59(options.agentDir,"plugin-state.json")}),projectStateStore:overrides?.projectStateStore??market?.projectStateStore??createPluginStateStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,"plugin-state.json")}),projectScopeRef:projectPluginScopeRefV1(options.cwd),selectionStore:overrides?.selectionStore??createPluginSelectionStoreV1({filePath:join59(options.agentDir,".plugin-selection.json")}),projectSelectionStore:overrides?.projectSelectionStore??createPluginSelectionStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,".plugin-selection.json")})})}async function createDefaultPluginManagerControllerV1(options){let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=await createDefaultPluginMarketWiringV1({agentDir,cwd}),cli=buildMarketCli({agentDir,cwd,market});return{controller:createPluginManagerControllerV1({registry:market.registry,stateStore:options.scope==="project"?market.projectStateStore:market.stateStore,cli}),close:market.close}}async function handlePluginEcosystemCommand(args,options={}){if(args[0]!=="plugin")return!1;let write=options.write??(line=>console.log(line));if(args[1]==="update"&&args[2]==="--all")return await runBatchUpdate(args.slice(3),options,write),!0;let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=options.registry===void 0&&options.installer===void 0?await createDefaultPluginMarketWiringV1({agentDir,cwd}):void 0;try{let response2=await buildMarketCli({agentDir,cwd,market,overrides:options}).execute({argv:args.slice(1)});return printResponse(response2,write),!0}finally{await market?.close()}}async function runBatchUpdate(restArgs,options,write){let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),scopeIndex=restArgs.indexOf("--scope"),scope=scopeIndex!==-1&&restArgs[scopeIndex+1]==="project"?"project":"global",market=options.registry===void 0&&options.installer===void 0?await createDefaultPluginMarketWiringV1({agentDir,cwd}):void 0;try{let cli=buildMarketCli({agentDir,cwd,market,overrides:options}),listResponse=await cli.execute({argv:["state","list","--scope",scope]});if(listResponse.status!=="succeeded"){printResponse(listResponse,write);return}let entries=(listResponse.data?.entries??[]).filter(entry=>entry.lifecycle==="active"&&entry.scope===scope);if(entries.length===0){write("No active plugins to update.");return}let updated=[],current=[],failed=[];for(let entry of entries){let response2=await cli.execute({argv:["update",entry.pluginId,"--scope",scope]});response2.status==="succeeded"?(updated.push(entry.pluginId),write(response2.text)):response2.error?.code==="already_installed"?current.push(entry.pluginId):(failed.push(entry.pluginId),write(response2.text))}let summary=[`updated ${updated.length}${updated.length>0?` (${updated.join(", ")})`:""}`,`already up to date ${current.length}${current.length>0?` (${current.join(", ")})`:""}`,`failed ${failed.length}${failed.length>0?` (${failed.join(", ")})`:""}`].join("; ");write(`plugin update --all [${scope}]: ${summary}`),failed.length>0&&(process.exitCode=1)}finally{await market?.close()}}import{join as join60}from"node:path";var DEFAULT_DURABLE_LOG_RELATIVE_PATH=join60("durable","remote-server-ops.jsonl");function isAddrInUse(error2){return typeof error2=="object"&&error2!==null&&error2.code==="EADDRINUSE"}async function runServeMode(port,options){let handle,createListener=options?.createListener??(()=>createWsServerListener({port,httpRequestHandler:(request,response2)=>handle?.server.handleArtifactHttpRequest(request,response2)??!1,onError:error2=>{console.error(`remote-server error: ${error2.message}`)}})),startServer=options?.startServer??startCodingAgentRemoteServer,workspaceRoots=options?.workspaceRoots,sessionDir=options?.sessionDir,durable=options?.durable??createDurableService({backend:createFileDurableStoreBackend({path:join60(getAgentDir(),DEFAULT_DURABLE_LOG_RELATIVE_PATH)})}),writerId=readOrCreateWriterId(getAgentDir());try{handle=await startServer({sessionSourceOptions:{sessionsDir:sessionDir??getSessionsDir(),cwd:process.cwd(),agentDir:getAgentDir(),...workspaceRoots===void 0||workspaceRoots.length===0?{}:{workspaceRoots},agentTaskResults:{store:durable,writerId},subagentPoolFromSelfInvocation:!0,...options?.hostLogger===void 0?{}:{hostLogger:options.hostLogger}},listeners:[createListener()],onError:error2=>{console.error(`remote-server error: ${error2.message}`)},durable,writerId})}catch(error2){throw isAddrInUse(error2)&&(console.error(`Port ${port} is already in use`),process.exit(1)),error2}let closing=!1,shutdown=()=>{closing||(closing=!0,handle.close().then(()=>{process.exit(0)}).catch(error2=>{console.error(`Remote server shutdown failed: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}))};process.on("SIGINT",shutdown),process.on("SIGTERM",shutdown),console.log(`Remote server listening on ${handle.addresses.join(", ")}`)}import{existsSync as existsSync29}from"fs";var THEME_OPTIONS=[{value:"dark",label:"Dark"},{value:"light",label:"Light"}],ANALYTICS_OPTIONS=[{value:!0,label:"Share anonymous usage data"},{value:!1,label:"Don't share"}],SETUP_LOGO_LINES=["\u2588\u2588\u2588\u2588\u2588\u2588","\u2588\u2588 \u2588\u2588","\u2588\u2588\u2588\u2588 \u2588\u2588","\u2588\u2588 \u2588\u2588"],FirstTimeSetupComponent=class extends Container{step="theme";themeIndex;analyticsIndex=0;options;constructor(options){super(),this.options=options,this.themeIndex=Math.max(0,THEME_OPTIONS.findIndex(option=>option.value===options.detectedTheme)),this.update()}update(){this.clear(),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("accent",SETUP_LOGO_LINES.join(`
|
|
1491
1491
|
`)),1,0)),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("accent",theme.bold(`Welcome to ${APP_NAME}, the minimal coding agent.`)),1,0)),this.addChild(new Spacer(1)),this.step==="theme"?(this.addChild(new Text(theme.fg("text","Pick a theme."),1,0)),this.addChild(new Text(theme.fg("muted",`Detected system appearance: ${this.options.detectedTheme}`),1,0)),this.addChild(new Spacer(1)),this.addOptionList(THEME_OPTIONS.map(option=>option.label),this.themeIndex)):(this.addChild(new Text(theme.fg("text","Opt-in to anonymous usage data sharing?"),1,0)),this.addChild(new Text(theme.fg("muted",`Opting in stores a tracking identifier in settings.json and enables anonymous
|
|
1492
1492
|
usage analytics. This helps us to better debug, reproduce, and resolve issues
|
|
1493
1493
|
and bugs within Agent Forge. You can observe what is shared using /privacy and make
|
|
@@ -1503,7 +1503,7 @@ changes anytime in settings.json.`),1,0)),this.addChild(new Spacer(1)),this.addO
|
|
|
1503
1503
|
${value.stack}`}
|
|
1504
1504
|
`}return`${JSON.stringify(toSafeJson(value))}
|
|
1505
1505
|
`}function createHostLogger(options){if(options.level!==void 0&&!HOST_LOG_LEVELS.includes(options.level))throw new Error(`Host logger level must be one of ${HOST_LOG_LEVELS.map(level=>`"${level}"`).join(" | ")}; got ${JSON.stringify(options.level)}`);let minRank=LEVEL_RANK[options.level??"info"],now=options.now??Date.now,maxAgeDays=options.maxAgeDays??DEFAULT_MAX_AGE_DAYS,processHost=options.processHost??NODE_PROCESS_HOST,closed=!1,dirReady=!1,written=0,failed=0,write=(level,src,msg,context)=>{if(closed||LEVEL_RANK[level]<minRank)return;let entry={v:1,t:now(),level,src,msg,sessionId:context?.sessionId,traceId:context?.traceId,fields:context?.fields===void 0?void 0:toSafeJson(context.fields),cause:context?.cause===void 0?void 0:boundCause(context.cause)};try{dirReady||(mkdirSync19(options.dir,{recursive:!0}),dirReady=!0),appendFileSync4(join61(options.dir,logFileName(entry.t)),`${JSON.stringify(entry)}
|
|
1506
|
-
`),written+=1}catch{failed+=1,dirReady=!1}};(()=>{if(maxAgeDays<=0)return;let cutoff=now()-maxAgeDays*DAY_MS,currentName=logFileName(now()),names2;try{names2=readdirSync16(options.dir)}catch(error2){if(error2.code==="ENOENT")return;write("warn","logger","log sweep failed: cannot read log directory",{cause:error2});return}let removed=0,errors=0;for(let name of names2){if(!name.endsWith(".log")||name===currentName)continue;let fullPath=join61(options.dir,name);try{let stats=statSync18(fullPath);if(!stats.isFile()||stats.mtimeMs>=cutoff)continue;unlinkSync4(fullPath),removed+=1}catch{errors+=1}}errors>0&&write("warn","logger","log sweep finished with failures",{fields:{removed,errors}})})();let exit=processHost.exit??NODE_PROCESS_CRASH_HOST.exit,writeStderr=processHost.writeStderr??NODE_PROCESS_CRASH_HOST.writeStderr,deferThrow=processHost.deferThrow??NODE_PROCESS_CRASH_HOST.deferThrow,loggedFatalValues=new WeakSet,isFatalValueLogged=value=>value!==null&&(typeof value=="object"||typeof value=="function")&&loggedFatalValues.has(value),markFatalValueLogged=value=>{value!==null&&(typeof value=="object"||typeof value=="function")&&loggedFatalValues.add(value)};return processHost.onUncaughtException&&processHost.onUncaughtException(error2=>{isFatalValueLogged(error2)||(markFatalValueLogged(error2),write("error","process","uncaughtException",{cause:error2})),writeStderr(fatalStderrText(error2)),exit(1)}),processHost.onUnhandledRejection&&processHost.onUnhandledRejection(reason=>{markFatalValueLogged(reason),write("error","process","unhandledRejection",{cause:reason}),deferThrow(()=>{throw reason})}),{debug:(src,msg,context)=>write("debug",src,msg,context),info:(src,msg,context)=>write("info",src,msg,context),warn:(src,msg,context)=>write("warn",src,msg,context),error:(src,msg,context)=>write("error",src,msg,context),close:()=>(closed=!0,{written,failed})}}function collectSettingsDiagnostics(settingsManager){return settingsManager.drainErrors().map(({scope,path:path15,error:error2})=>({type:"warning",message:path15?`Invalid settings file ${path15}: ${error2.message}`:`Invalid ${scope} settings: ${error2.message}`}))}function deduplicateDiagnostics(diagnostics){let seen=new Set;return diagnostics.filter(diagnostic5=>{let key=`${diagnostic5.type}\0${diagnostic5.message}`;return seen.has(key)?!1:(seen.add(key),!0)})}import{readdirSync as readdirSync17,statSync as statSync19,unlinkSync as unlinkSync5}from"node:fs";import{join as join62}from"node:path";var DAY_MS2=1440*60*1e3,TRACE_FILE_SUFFIX=".trace.jsonl";function sweepTraceFiles(sessionsRoot,options){if(options.maxAgeDays<=0)return{scanned:0,deleted:0,failed:0};let now=options.now??Date.now,unlink4=options.unlink??(path15=>unlinkSync5(path15)),cutoff=now()-options.maxAgeDays*DAY_MS2,scanned=0,deleted=0,failed=0,readEntries=dir=>{try{return readdirSync17(dir,{withFileTypes:!0})}catch{return}},sweepFilesIn=(dir,entries)=>{for(let entry of entries){if(!entry.name.endsWith(TRACE_FILE_SUFFIX))continue;let fullPath=join62(dir,entry.name),isFile=!1,isExpired=!1;try{let stats=statSync19(fullPath);isFile=stats.isFile(),isExpired=isFile&&stats.mtimeMs<cutoff}catch{continue}if(isFile&&(scanned+=1,!!isExpired))try{unlink4(fullPath),deleted+=1}catch{failed+=1}}},rootEntries=readEntries(sessionsRoot);if(rootEntries===void 0)return{scanned:0,deleted:0,failed:0};sweepFilesIn(sessionsRoot,rootEntries);for(let entry of rootEntries){if(!entry.isDirectory())continue;let subdirectory=join62(sessionsRoot,entry.name),subEntries=readEntries(subdirectory);subEntries!==void 0&&sweepFilesIn(subdirectory,subEntries)}return{scanned,deleted,failed}}import{join as join63}from"node:path";var FACTORY_PLUGIN_RANGE=`^${VERSION}`,BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1=Object.freeze([{pluginId:"agent-forge.plugin.goal",npmName:"@ai-agent-forge/plugin-goal",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.plan",npmName:"@ai-agent-forge/plugin-plan",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.todo-set",npmName:"@ai-agent-forge/plugin-todo-set",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.session-share",npmName:"@ai-agent-forge/plugin-session-share",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.observability",npmName:"@ai-agent-forge/plugin-observability",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.subagent-delegate",npmName:"@ai-agent-forge/plugin-subagent-delegate",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.memory",npmName:"@ai-agent-forge/plugin-memory",range:FACTORY_PLUGIN_RANGE}]);var PLUGIN_BOOTSTRAP_VERSION_V1=1;function satisfiesRangeV1(version,range2){return selectNpmPackageVersionV1([version],range2)===version}function pluginBootstrapInstallCommandV1(entry){return`agent-forge plugin install ${entry.npmName}@${entry.range??"latest"}`}function errorMessage(error2){return error2 instanceof Error?error2.message:String(error2)}function acquireErrorCode(error2){return error2 instanceof PluginAcquisitionErrorV1?error2.code:"install_failed"}function actionOf(entry,status2,reason){return Object.freeze({pluginId:entry.pluginId,status:status2,reason,npmName:entry.npmName,...entry.range===void 0?{}:{range:entry.range}})}async function runPluginBootstrapV1(input){let now=input.deps.now??Date.now,startedAt=now(),finish=(status3,actions2,diagnostics2)=>Object.freeze({version:PLUGIN_BOOTSTRAP_VERSION_V1,status:status3,actions:Object.freeze([...actions2]),diagnostics:Object.freeze([...diagnostics2]),durationMs:Math.max(0,now()-startedAt)});if(input.manifest.length===0)return finish("succeeded",[],[]);let signal=input.deps.signal,active;try{active=await input.deps.listActive({...signal===void 0?{}:{signal}})}catch(error2){return finish("failed",[],[{code:"list_active_failed",message:`Active plugin state could not be read; bootstrap installed nothing: ${errorMessage(error2)}`}])}let actions=[],diagnostics=[];for(let entry of input.manifest){if(signal?.aborted===!0){diagnostics.push({code:"cancelled",message:"Plugin bootstrap was cancelled before all factory entries were processed"});break}let activeVersion=active.get(entry.pluginId);if(activeVersion!==void 0){if(satisfiesRangeV1(activeVersion,entry.range)){actions.push(Object.freeze({...actionOf(entry,"skipped","satisfies_range"),activeVersion}));continue}actions.push(Object.freeze({...actionOf(entry,"diagnosed","range_not_satisfied"),activeVersion})),diagnostics.push({code:"range_not_satisfied",pluginId:entry.pluginId,message:`Active version ${activeVersion} of ${entry.pluginId} does not satisfy the factory range ${entry.range??"latest"}; bootstrap never replaces active installations. Run \`${pluginBootstrapInstallCommandV1(entry)}\` to install a matching version.`});continue}try{let installed=await input.deps.installFromNpm({npmName:entry.npmName,...entry.range===void 0?{}:{range:entry.range},...signal===void 0?{}:{signal}});actions.push(Object.freeze({...actionOf(entry,"installed","installed"),installedVersion:installed.pluginVersion,source:installed.source}))}catch(error2){let errorCode2=acquireErrorCode(error2);actions.push(Object.freeze({...actionOf(entry,"failed","install_failed"),errorCode:errorCode2})),diagnostics.push({code:"install_failed",pluginId:entry.pluginId,message:`Bootstrap could not install ${entry.pluginId} from npm (${errorCode2}: ${errorMessage(error2)}). Startup continues without it; its capabilities stay unavailable until installed. Run \`${pluginBootstrapInstallCommandV1(entry)}\` to install it manually.`})}}let status2=actions.some(action=>action.status==="failed")?"failed":actions.some(action=>action.status==="diagnosed")?"degraded":"succeeded";return finish(status2,actions,diagnostics)}var AGENT_FORGE_PLUGIN_BOOTSTRAP_ENV_V1="AGENT_FORGE_PLUGIN_BOOTSTRAP",PLUGIN_BOOTSTRAP_DISABLED_VALUE_V1="off";function readActiveVersions(store,scope,scopeRef,signal){return(async()=>{let result=await store.read({...signal===void 0?{}:{signal}});if(result.status!=="ok"&&result.status!=="missing")throw new Error(`plugin state read failed (${result.diagnostics[0]?.code??result.status}) for the ${scope} scope`);let versions=new Map;for(let record of result.snapshot.records)record.state.scope!==scope||record.state.scopeRef!==scopeRef||record.state.lifecycle==="active"&&versions.set(record.pluginId,record.pluginVersion);return versions})()}async function runNodePluginBootstrapV1(options){if(process.env[AGENT_FORGE_PLUGIN_BOOTSTRAP_ENV_V1]?.trim()===PLUGIN_BOOTSTRAP_DISABLED_VALUE_V1)return Object.freeze({version:1,status:"succeeded",actions:Object.freeze([]),diagnostics:Object.freeze([]),durationMs:0,skipped:"disabled"});if(options.deps!==void 0)return await runPluginBootstrapV1({manifest:options.manifest??BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1,deps:options.deps});let session,ensureSession=async()=>{if(session!==void 0)return session;let acquisition=createNodePluginAcquisitionHostV1({...options.npmRegistry===void 0?{}:{npmRegistry:options.npmRegistry},...options.npmToken===void 0?{}:{npmToken:options.npmToken},...options.fetch===void 0?{}:{fetch:options.fetch},...options.limits===void 0?{}:{limits:options.limits}}),installHost=await createNodePackageInstallHostV1({openArtifact:input=>acquisition.openArtifact(input),installationDirectory:defaultPluginInstallStoreDirectoryV1(options.agentDir),persistence:"persistent",supportedScopes:["global","project"],...options.limits===void 0?{}:{...options.limits}});return session={acquisition,installHost,installer:createPluginInstallerV1({host:installHost}),stateStore:createPluginStateStoreV1({filePath:join63(options.agentDir,DEFAULT_PLUGIN_STATE_FILE_V1)})},session},deps={listActive:async({signal})=>{let globalVersions=readActiveVersions(createPluginStateStoreV1({filePath:join63(options.agentDir,DEFAULT_PLUGIN_STATE_FILE_V1)}),"global",DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,signal),projectVersions=readActiveVersions(createPluginStateStoreV1({filePath:join63(options.cwd,CONFIG_DIR_NAME,DEFAULT_PLUGIN_STATE_FILE_V1)}),"project",projectPluginScopeRefV1(options.cwd),signal),[globalResult,projectResult]=await Promise.all([globalVersions,projectVersions]);return new Map([...globalResult,...projectResult])},installFromNpm:async({npmName,range:range2,signal})=>{let active=await ensureSession(),ref=range2===void 0?npmName:`${npmName}@${range2}`,acquired=await active.acquisition.resolvePackage({ref,...signal===void 0?{}:{signal}}),released=!1,release=async()=>{released||(released=!0,await acquired.release())};try{let verified=active.installer.prepare({manifest:acquired.manifest,source:acquired.source,host:defaultPluginHostFactsV1()});if(verified.status!=="verified")throw new Error(`installer prepare rejected ${acquired.manifest.id}: ${verified.reason}`);let installed=await active.installer.install({record:verified.record,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,artifact:acquired.artifact,...signal===void 0?{}:{signal}});if(installed.status!=="succeeded")throw new Error(`plugin install failed (${installed.error.code}) for ${acquired.manifest.id}`);let activated=await active.installer.activate({installation:installed.installation,record:verified.record,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,...signal===void 0?{}:{signal}});if(activated.status!=="succeeded")throw await active.installer.remove({installation:installed.installation,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1}).catch(()=>{}),new Error(`plugin activation failed (${activated.error.code}) for ${acquired.manifest.id}`);let persisted=await active.stateStore.upsert({installation:activated.installation,scope:"global",enabled:!0,source:acquired.source,...signal===void 0?{}:{signal}});if(persisted.status!=="ok")throw await active.installer.remove({installation:activated.installation,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1}).catch(()=>{}),new Error(`plugin state persist failed (${persisted.status}) for ${acquired.manifest.id}`);return{pluginVersion:activated.installation.pluginVersion,source:acquired.source}}finally{await release()}},...options.signal===void 0?{}:{signal:options.signal}};try{return await runPluginBootstrapV1({manifest:options.manifest??BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1,deps})}finally{let active=session;session=void 0,active!==void 0&&(await active.installHost.close().catch(()=>{}),await active.acquisition.close().catch(()=>{}))}}import{existsSync as existsSync31,mkdirSync as mkdirSync20,readdirSync as readdirSync18,readFileSync as readFileSync27,renameSync as renameSync4,rmSync as rmSync6,writeFileSync as writeFileSync17}from"fs";import{dirname as dirname30,join as join64}from"path";var MIGRATION_GUIDE_URL="https://github.com/agent-forge/agent-forge/blob/main/packages/agent-forge/CHANGELOG.md#extensions-migration",EXTENSIONS_DOC_URL="https://github.com/agent-forge/agent-forge/blob/main/packages/agent-forge/docs/extensions.md";function migrateAuthToAuthJson(){let agentDir=getAgentDir(),authPath=join64(agentDir,"auth.json"),oauthPath=join64(agentDir,"oauth.json"),settingsPath=join64(agentDir,"settings.json");if(existsSync31(authPath))return[];let migrated={},providers=[];if(existsSync31(oauthPath))try{let oauth=JSON.parse(stripBom(readFileSync27(oauthPath,"utf-8")));for(let[provider,cred]of Object.entries(oauth))migrated[provider]={type:"oauth",...cred},providers.push(provider);renameSync4(oauthPath,`${oauthPath}.migrated`)}catch{}if(existsSync31(settingsPath))try{let content=readFileSync27(settingsPath,"utf-8"),settings2=JSON.parse(stripBom(content));if(settings2.apiKeys&&typeof settings2.apiKeys=="object"){for(let[provider,key]of Object.entries(settings2.apiKeys))!migrated[provider]&&typeof key=="string"&&(migrated[provider]={type:"api_key",key},providers.push(provider));delete settings2.apiKeys,writeFileSync17(settingsPath,JSON.stringify(settings2,null,2))}}catch{}return Object.keys(migrated).length>0&&(mkdirSync20(dirname30(authPath),{recursive:!0}),writeFileSync17(authPath,JSON.stringify(migrated,null,2),{mode:384})),providers}function migrateSessionsFromAgentRoot(){let agentDir=getAgentDir(),files;try{files=readdirSync18(agentDir).filter(f=>f.endsWith(".jsonl")).map(f=>join64(agentDir,f))}catch{return}if(files.length!==0)for(let file of files)try{let firstLine=readFileSync27(file,"utf8").split(`
|
|
1506
|
+
`),written+=1}catch{failed+=1,dirReady=!1}};(()=>{if(maxAgeDays<=0)return;let cutoff=now()-maxAgeDays*DAY_MS,currentName=logFileName(now()),names2;try{names2=readdirSync16(options.dir)}catch(error2){if(error2.code==="ENOENT")return;write("warn","logger","log sweep failed: cannot read log directory",{cause:error2});return}let removed=0,errors=0;for(let name of names2){if(!name.endsWith(".log")||name===currentName)continue;let fullPath=join61(options.dir,name);try{let stats=statSync18(fullPath);if(!stats.isFile()||stats.mtimeMs>=cutoff)continue;unlinkSync4(fullPath),removed+=1}catch{errors+=1}}errors>0&&write("warn","logger","log sweep finished with failures",{fields:{removed,errors}})})();let exit=processHost.exit??NODE_PROCESS_CRASH_HOST.exit,writeStderr=processHost.writeStderr??NODE_PROCESS_CRASH_HOST.writeStderr,deferThrow=processHost.deferThrow??NODE_PROCESS_CRASH_HOST.deferThrow,loggedFatalValues=new WeakSet,isFatalValueLogged=value=>value!==null&&(typeof value=="object"||typeof value=="function")&&loggedFatalValues.has(value),markFatalValueLogged=value=>{value!==null&&(typeof value=="object"||typeof value=="function")&&loggedFatalValues.add(value)};return processHost.onUncaughtException&&processHost.onUncaughtException(error2=>{isFatalValueLogged(error2)||(markFatalValueLogged(error2),write("error","process","uncaughtException",{cause:error2})),writeStderr(fatalStderrText(error2)),exit(1)}),processHost.onUnhandledRejection&&processHost.onUnhandledRejection(reason=>{markFatalValueLogged(reason),write("error","process","unhandledRejection",{cause:reason}),deferThrow(()=>{throw reason})}),{debug:(src,msg,context)=>write("debug",src,msg,context),info:(src,msg,context)=>write("info",src,msg,context),warn:(src,msg,context)=>write("warn",src,msg,context),error:(src,msg,context)=>write("error",src,msg,context),close:()=>(closed=!0,{written,failed})}}function collectSettingsDiagnostics(settingsManager){return settingsManager.drainErrors().map(({scope,path:path15,error:error2})=>({type:"warning",message:path15?`Invalid settings file ${path15}: ${error2.message}`:`Invalid ${scope} settings: ${error2.message}`}))}function deduplicateDiagnostics(diagnostics){let seen=new Set;return diagnostics.filter(diagnostic5=>{let key=`${diagnostic5.type}\0${diagnostic5.message}`;return seen.has(key)?!1:(seen.add(key),!0)})}import{readdirSync as readdirSync17,statSync as statSync19,unlinkSync as unlinkSync5}from"node:fs";import{join as join62}from"node:path";var DAY_MS2=1440*60*1e3,TRACE_FILE_SUFFIX=".trace.jsonl";function sweepTraceFiles(sessionsRoot,options){if(options.maxAgeDays<=0)return{scanned:0,deleted:0,failed:0};let now=options.now??Date.now,unlink4=options.unlink??(path15=>unlinkSync5(path15)),cutoff=now()-options.maxAgeDays*DAY_MS2,scanned=0,deleted=0,failed=0,readEntries=dir=>{try{return readdirSync17(dir,{withFileTypes:!0})}catch{return}},sweepFilesIn=(dir,entries)=>{for(let entry of entries){if(!entry.name.endsWith(TRACE_FILE_SUFFIX))continue;let fullPath=join62(dir,entry.name),isFile=!1,isExpired=!1;try{let stats=statSync19(fullPath);isFile=stats.isFile(),isExpired=isFile&&stats.mtimeMs<cutoff}catch{continue}if(isFile&&(scanned+=1,!!isExpired))try{unlink4(fullPath),deleted+=1}catch{failed+=1}}},rootEntries=readEntries(sessionsRoot);if(rootEntries===void 0)return{scanned:0,deleted:0,failed:0};sweepFilesIn(sessionsRoot,rootEntries);for(let entry of rootEntries){if(!entry.isDirectory())continue;let subdirectory=join62(sessionsRoot,entry.name),subEntries=readEntries(subdirectory);subEntries!==void 0&&sweepFilesIn(subdirectory,subEntries)}return{scanned,deleted,failed}}import{join as join63}from"node:path";var FACTORY_PLUGIN_RANGE=`^${VERSION}`,BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1=Object.freeze([{pluginId:"agent-forge.plugin.goal",npmName:"@ai-agent-forge/plugin-goal",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.plan",npmName:"@ai-agent-forge/plugin-plan",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.todo-set",npmName:"@ai-agent-forge/plugin-todo-set",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.session-share",npmName:"@ai-agent-forge/plugin-session-share",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.observability",npmName:"@ai-agent-forge/plugin-observability",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.subagent-delegate",npmName:"@ai-agent-forge/plugin-subagent-delegate",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.memory",npmName:"@ai-agent-forge/plugin-memory",range:FACTORY_PLUGIN_RANGE}]);var PLUGIN_BOOTSTRAP_VERSION_V1=1;function satisfiesRangeV1(version,range2){return selectNpmPackageVersionV1([version],range2)===version}function pluginBootstrapInstallCommandV1(entry){return`agent-forge plugin install ${entry.npmName}@${entry.range??"latest"}`}function errorMessage(error2){return error2 instanceof Error?error2.message:String(error2)}function acquireErrorCode(error2){return error2 instanceof PluginAcquisitionErrorV1?error2.code:"install_failed"}function actionOf(entry,status2,reason){return Object.freeze({pluginId:entry.pluginId,status:status2,reason,npmName:entry.npmName,...entry.range===void 0?{}:{range:entry.range}})}async function runPluginBootstrapV1(input){let now=input.deps.now??Date.now,startedAt=now(),finish=(status3,actions2,diagnostics2)=>Object.freeze({version:PLUGIN_BOOTSTRAP_VERSION_V1,status:status3,actions:Object.freeze([...actions2]),diagnostics:Object.freeze([...diagnostics2]),durationMs:Math.max(0,now()-startedAt)});if(input.manifest.length===0)return finish("succeeded",[],[]);let signal=input.deps.signal,active;try{active=await input.deps.listActive({...signal===void 0?{}:{signal}})}catch(error2){return finish("failed",[],[{code:"list_active_failed",message:`Active plugin state could not be read; bootstrap installed nothing: ${errorMessage(error2)}`}])}let actions=[],diagnostics=[];for(let entry of input.manifest){if(signal?.aborted===!0){diagnostics.push({code:"cancelled",message:"Plugin bootstrap was cancelled before all factory entries were processed"});break}let activeVersion=active.get(entry.pluginId);if(activeVersion!==void 0){if(satisfiesRangeV1(activeVersion,entry.range)){actions.push(Object.freeze({...actionOf(entry,"skipped","satisfies_range"),activeVersion}));continue}actions.push(Object.freeze({...actionOf(entry,"diagnosed","range_not_satisfied"),activeVersion})),diagnostics.push({code:"range_not_satisfied",pluginId:entry.pluginId,message:`Active version ${activeVersion} of ${entry.pluginId} does not satisfy the factory range ${entry.range??"latest"}; bootstrap never replaces active installations. Run \`${pluginBootstrapInstallCommandV1(entry)}\` to install a matching version, or \`agent-forge plugin update --all\` to upgrade every outdated plugin at once.`});continue}try{let installed=await input.deps.installFromNpm({npmName:entry.npmName,...entry.range===void 0?{}:{range:entry.range},...signal===void 0?{}:{signal}});actions.push(Object.freeze({...actionOf(entry,"installed","installed"),installedVersion:installed.pluginVersion,source:installed.source}))}catch(error2){let errorCode2=acquireErrorCode(error2);actions.push(Object.freeze({...actionOf(entry,"failed","install_failed"),errorCode:errorCode2})),diagnostics.push({code:"install_failed",pluginId:entry.pluginId,message:`Bootstrap could not install ${entry.pluginId} from npm (${errorCode2}: ${errorMessage(error2)}). Startup continues without it; its capabilities stay unavailable until installed. Run \`${pluginBootstrapInstallCommandV1(entry)}\` to install it manually.`})}}let status2=actions.some(action=>action.status==="failed")?"failed":actions.some(action=>action.status==="diagnosed")?"degraded":"succeeded";return finish(status2,actions,diagnostics)}var AGENT_FORGE_PLUGIN_BOOTSTRAP_ENV_V1="AGENT_FORGE_PLUGIN_BOOTSTRAP",PLUGIN_BOOTSTRAP_DISABLED_VALUE_V1="off";function readActiveVersions(store,scope,scopeRef,signal){return(async()=>{let result=await store.read({...signal===void 0?{}:{signal}});if(result.status!=="ok"&&result.status!=="missing")throw new Error(`plugin state read failed (${result.diagnostics[0]?.code??result.status}) for the ${scope} scope`);let versions=new Map;for(let record of result.snapshot.records)record.state.scope!==scope||record.state.scopeRef!==scopeRef||record.state.lifecycle==="active"&&versions.set(record.pluginId,record.pluginVersion);return versions})()}async function runNodePluginBootstrapV1(options){if(process.env[AGENT_FORGE_PLUGIN_BOOTSTRAP_ENV_V1]?.trim()===PLUGIN_BOOTSTRAP_DISABLED_VALUE_V1)return Object.freeze({version:1,status:"succeeded",actions:Object.freeze([]),diagnostics:Object.freeze([]),durationMs:0,skipped:"disabled"});if(options.deps!==void 0)return await runPluginBootstrapV1({manifest:options.manifest??BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1,deps:options.deps});let session,ensureSession=async()=>{if(session!==void 0)return session;let acquisition=createNodePluginAcquisitionHostV1({...options.npmRegistry===void 0?{}:{npmRegistry:options.npmRegistry},...options.npmToken===void 0?{}:{npmToken:options.npmToken},...options.fetch===void 0?{}:{fetch:options.fetch},...options.limits===void 0?{}:{limits:options.limits}}),installHost=await createNodePackageInstallHostV1({openArtifact:input=>acquisition.openArtifact(input),installationDirectory:defaultPluginInstallStoreDirectoryV1(options.agentDir),persistence:"persistent",supportedScopes:["global","project"],...options.limits===void 0?{}:{...options.limits}});return session={acquisition,installHost,installer:createPluginInstallerV1({host:installHost}),stateStore:createPluginStateStoreV1({filePath:join63(options.agentDir,DEFAULT_PLUGIN_STATE_FILE_V1)})},session},deps={listActive:async({signal})=>{let globalVersions=readActiveVersions(createPluginStateStoreV1({filePath:join63(options.agentDir,DEFAULT_PLUGIN_STATE_FILE_V1)}),"global",DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,signal),projectVersions=readActiveVersions(createPluginStateStoreV1({filePath:join63(options.cwd,CONFIG_DIR_NAME,DEFAULT_PLUGIN_STATE_FILE_V1)}),"project",projectPluginScopeRefV1(options.cwd),signal),[globalResult,projectResult]=await Promise.all([globalVersions,projectVersions]);return new Map([...globalResult,...projectResult])},installFromNpm:async({npmName,range:range2,signal})=>{let active=await ensureSession(),ref=range2===void 0?npmName:`${npmName}@${range2}`,acquired=await active.acquisition.resolvePackage({ref,...signal===void 0?{}:{signal}}),released=!1,release=async()=>{released||(released=!0,await acquired.release())};try{let verified=active.installer.prepare({manifest:acquired.manifest,source:acquired.source,host:defaultPluginHostFactsV1()});if(verified.status!=="verified")throw new Error(`installer prepare rejected ${acquired.manifest.id}: ${verified.reason}`);let installed=await active.installer.install({record:verified.record,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,artifact:acquired.artifact,...signal===void 0?{}:{signal}});if(installed.status!=="succeeded")throw new Error(`plugin install failed (${installed.error.code}) for ${acquired.manifest.id}`);let activated=await active.installer.activate({installation:installed.installation,record:verified.record,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,...signal===void 0?{}:{signal}});if(activated.status!=="succeeded")throw await active.installer.remove({installation:installed.installation,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1}).catch(()=>{}),new Error(`plugin activation failed (${activated.error.code}) for ${acquired.manifest.id}`);let persisted=await active.stateStore.upsert({installation:activated.installation,scope:"global",enabled:!0,source:acquired.source,...signal===void 0?{}:{signal}});if(persisted.status!=="ok")throw await active.installer.remove({installation:activated.installation,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1}).catch(()=>{}),new Error(`plugin state persist failed (${persisted.status}) for ${acquired.manifest.id}`);return{pluginVersion:activated.installation.pluginVersion,source:acquired.source}}finally{await release()}},...options.signal===void 0?{}:{signal:options.signal}};try{return await runPluginBootstrapV1({manifest:options.manifest??BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1,deps})}finally{let active=session;session=void 0,active!==void 0&&(await active.installHost.close().catch(()=>{}),await active.acquisition.close().catch(()=>{}))}}import{existsSync as existsSync31,mkdirSync as mkdirSync20,readdirSync as readdirSync18,readFileSync as readFileSync27,renameSync as renameSync4,rmSync as rmSync6,writeFileSync as writeFileSync17}from"fs";import{dirname as dirname30,join as join64}from"path";var MIGRATION_GUIDE_URL="https://github.com/agent-forge/agent-forge/blob/main/packages/agent-forge/CHANGELOG.md#extensions-migration",EXTENSIONS_DOC_URL="https://github.com/agent-forge/agent-forge/blob/main/packages/agent-forge/docs/extensions.md";function migrateAuthToAuthJson(){let agentDir=getAgentDir(),authPath=join64(agentDir,"auth.json"),oauthPath=join64(agentDir,"oauth.json"),settingsPath=join64(agentDir,"settings.json");if(existsSync31(authPath))return[];let migrated={},providers=[];if(existsSync31(oauthPath))try{let oauth=JSON.parse(stripBom(readFileSync27(oauthPath,"utf-8")));for(let[provider,cred]of Object.entries(oauth))migrated[provider]={type:"oauth",...cred},providers.push(provider);renameSync4(oauthPath,`${oauthPath}.migrated`)}catch{}if(existsSync31(settingsPath))try{let content=readFileSync27(settingsPath,"utf-8"),settings2=JSON.parse(stripBom(content));if(settings2.apiKeys&&typeof settings2.apiKeys=="object"){for(let[provider,key]of Object.entries(settings2.apiKeys))!migrated[provider]&&typeof key=="string"&&(migrated[provider]={type:"api_key",key},providers.push(provider));delete settings2.apiKeys,writeFileSync17(settingsPath,JSON.stringify(settings2,null,2))}}catch{}return Object.keys(migrated).length>0&&(mkdirSync20(dirname30(authPath),{recursive:!0}),writeFileSync17(authPath,JSON.stringify(migrated,null,2),{mode:384})),providers}function migrateSessionsFromAgentRoot(){let agentDir=getAgentDir(),files;try{files=readdirSync18(agentDir).filter(f=>f.endsWith(".jsonl")).map(f=>join64(agentDir,f))}catch{return}if(files.length!==0)for(let file of files)try{let firstLine=readFileSync27(file,"utf8").split(`
|
|
1507
1507
|
`)[0];if(!firstLine?.trim())continue;let header=JSON.parse(firstLine);if(header.type!=="session"||!header.cwd)continue;let safePath=`--${header.cwd.replace(/^[/\\]/,"").replace(/[/\\:]/g,"-")}--`,correctDir=join64(agentDir,"sessions",safePath);existsSync31(correctDir)||mkdirSync20(correctDir,{recursive:!0});let fileName=file.split("/").pop()||file.split("\\").pop(),newPath=join64(correctDir,fileName);if(existsSync31(newPath))continue;renameSync4(file,newPath)}catch{}}function migrateCommandsToPrompts(baseDir,label){let commandsDir=join64(baseDir,"commands"),promptsDir=join64(baseDir,"prompts");if(existsSync31(commandsDir)&&!existsSync31(promptsDir))try{return renameSync4(commandsDir,promptsDir),console.log(source_default.green(`Migrated ${label} commands/ \u2192 prompts/`)),!0}catch(err2){console.log(source_default.yellow(`Warning: Could not migrate ${label} commands/ to prompts/: ${err2 instanceof Error?err2.message:err2}`))}return!1}function migrateKeybindingsConfigFile(){let configPath=join64(getAgentDir(),"keybindings.json");if(existsSync31(configPath))try{let parsed=JSON.parse(stripBom(readFileSync27(configPath,"utf-8")));if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))return;let{config,migrated}=migrateKeybindingsConfig(parsed);if(!migrated)return;writeFileSync17(configPath,`${JSON.stringify(config,null,2)}
|
|
1508
1508
|
`,"utf-8")}catch{}}function migrateToolsToBin(){let agentDir=getAgentDir(),toolsDir=join64(agentDir,"tools"),binDir=getBinDir();if(!existsSync31(toolsDir))return;let binaries=["fd","rg","fd.exe","rg.exe"],movedAny=!1;for(let bin of binaries){let oldPath=join64(toolsDir,bin),newPath=join64(binDir,bin);if(existsSync31(oldPath))if(existsSync31(binDir)||mkdirSync20(binDir,{recursive:!0}),existsSync31(newPath))try{rmSync6?.(oldPath,{force:!0})}catch{}else try{renameSync4(oldPath,newPath),movedAny=!0}catch{}}movedAny&&console.log(source_default.green("Migrated managed binaries tools/ \u2192 bin/"))}function checkDeprecatedExtensionDirs(baseDir,label){let hooksDir=join64(baseDir,"hooks"),toolsDir=join64(baseDir,"tools"),warnings=[];if(existsSync31(hooksDir)&&warnings.push(`${label} hooks/ directory found. Hooks have been renamed to extensions.`),existsSync31(toolsDir))try{readdirSync18(toolsDir).filter(e=>{let lower=e.toLowerCase();return lower!=="fd"&&lower!=="rg"&&lower!=="fd.exe"&&lower!=="rg.exe"&&!e.startsWith(".")}).length>0&&warnings.push(`${label} tools/ directory contains custom tools. Custom tools have been merged into extensions.`)}catch{}return warnings}function migrateExtensionSystem(cwd){let agentDir=getAgentDir(),projectDir=join64(cwd,CONFIG_DIR_NAME);return migrateCommandsToPrompts(agentDir,"Global"),migrateCommandsToPrompts(projectDir,"Project"),[...checkDeprecatedExtensionDirs(agentDir,"Global"),...checkDeprecatedExtensionDirs(projectDir,"Project")]}async function showDeprecationWarnings(warnings){if(warnings.length!==0){for(let warning of warnings)console.log(source_default.yellow(`Warning: ${warning}`));console.log(source_default.yellow(`
|
|
1509
1509
|
Move your extensions to the extensions/ directory.`)),console.log(source_default.yellow(`Migration guide: ${MIGRATION_GUIDE_URL}`)),console.log(source_default.yellow(`Documentation: ${EXTENSIONS_DOC_URL}`)),console.log()}}function runMigrations(cwd){let migratedAuthProviders=migrateAuthToAuthJson();migrateSessionsFromAgentRoot(),migrateToolsToBin(),migrateKeybindingsConfigFile();let deprecationWarnings=migrateExtensionSystem(cwd);return{migratedAuthProviders,deprecationWarnings}}import{existsSync as existsSync33,mkdirSync as mkdirSync22,mkdtempSync as mkdtempSync2,readdirSync as readdirSync19,readFileSync as readFileSync28,renameSync as renameSync6,rmSync as rmSync8,writeFileSync as writeFileSync18}from"node:fs";import{join as join67,resolve as resolve24}from"node:path";var import_proper_lockfile3=__toESM(require_proper_lockfile(),1);import{homedir as homedir10}from"node:os";import{basename as basename16,dirname as dirname31,join as join65,relative as relative12}from"node:path";var MAX_PROFILE_ID_CHARS=128,MAX_SELECTION_IDS=128,MAX_CATALOG_ENTRIES=256,MAX_DIAGNOSTIC_CODES2=16;function boundedCount(value,maximum){return value===void 0?{count:0,truncated:!1}:{count:Math.min(value.length,maximum),truncated:value.length>maximum}}function summarizePluginSelectionV1(selection){if(selection===void 0)return Object.freeze({present:!1,selectedCount:0,disabledCount:0,truncated:!1});let selected=boundedCount(selection.selectedPluginIds,MAX_SELECTION_IDS),disabled=boundedCount(selection.disabledPluginIds,MAX_SELECTION_IDS);return Object.freeze({present:!0,selectedCount:selected.count,disabledCount:disabled.count,truncated:selected.truncated||disabled.truncated})}function summarizePluginCatalogV1(catalog){if(catalog===void 0)return Object.freeze({present:!1,entryCount:0,readyCount:0,unavailableCount:0,truncated:!1});let entries=catalog.entries.slice(0,MAX_CATALOG_ENTRIES),readyCount=entries.filter(entry=>entry.resolution.status==="installed-ready").length;return Object.freeze({present:!0,entryCount:entries.length,readyCount,unavailableCount:entries.length-readyCount,truncated:catalog.truncated||catalog.entries.length>MAX_CATALOG_ENTRIES})}function validateProfileId(profileId){if(typeof profileId!="string"||profileId.trim().length===0||profileId.length>MAX_PROFILE_ID_CHARS||/[\u0000-\u001f]/u.test(profileId))throw new Error("invalid plugin selection profile ID");return profileId}function emptySelectionSummary(){return Object.freeze({present:!1,selectedCount:0,disabledCount:0,truncated:!1})}function diagnosticCodes2(result){return result.status==="ok"||result.status==="missing"?Object.freeze([]):Object.freeze(result.diagnostics.slice(0,MAX_DIAGNOSTIC_CODES2).map(item=>item.code))}function selectionForProfile2(result,profileId){return result.snapshot.selections.find(selection=>selection.profileId===profileId)}var PluginSelectionEntryComponent=class{profileId;store;controller;onOpen;onClose;requestRender;selection;catalog;uiProfile;uiPluginIndex=0;_focused=!1;get focused(){return this._focused}set focused(value){this._focused=value}constructor(options){if(this.profileId=validateProfileId(options.profileId),options.selection!==void 0&&options.selection.profileId!==this.profileId)throw new Error("plugin selection profile does not match the entry profile");this.store=options.store,this.controller=options.controller,this.onOpen=options.onOpen,this.onClose=options.onClose,this.requestRender=options.requestRender,this.selection=summarizePluginSelectionV1(options.selection),this.catalog=summarizePluginCatalogV1(options.catalog),this.uiProfile=options.snapshot?.profiles.find(profile=>profile.profileId===this.profileId)}hasHostEntry(){return this.store!==void 0||this.controller!==void 0||this.onOpen!==void 0}render(width){if(!this.hasHostEntry())return[truncateToWidth(theme.fg("dim"," Plugins: unsupported (host selection entry not injected)"),width,"...")];if(this._focused&&this.uiProfile!==void 0){let lines=[truncateToWidth(theme.bold(` Plugins \xB7 ${this.uiProfile.profileId}`),width,"...")];for(let[index3,plugin]of this.uiProfile.plugins.entries()){let cursor=index3===this.uiPluginIndex?">":" ",state2=plugin.state==="selected"?"on":plugin.state==="disabled"?"off":"available",availability=plugin.availability==="ready"?"ready":"unavailable";lines.push(truncateToWidth(` ${cursor} [${state2}] ${plugin.pluginId} (${availability})`,width,"..."))}return lines.push(truncateToWidth(theme.fg("dim"," Enter/Space toggle \xB7 Esc close"),width,"...")),lines}let selectionText=this.selection.present?`selected ${this.selection.selectedCount}, disabled ${this.selection.disabledCount}${this.selection.truncated?", bounded":""}`:this.store===void 0?"selection pending":"selection not loaded",catalogText=this.catalog.present?`catalog ${this.catalog.entryCount} (${this.catalog.readyCount} ready, ${this.catalog.unavailableCount} unavailable${this.catalog.truncated?", bounded":""})`:"catalog unavailable",suffix=this.onOpen===void 0?"host store":"open via host callback";return[truncateToWidth(theme.fg("muted",` Plugins: profile ${this.profileId} \xB7 ${selectionText} \xB7 ${catalogText} \xB7 ${suffix}`),width,"...")]}setUiSnapshot(result){result.status==="ok"&&(this.uiProfile=result.snapshot.profiles.find(profile=>profile.profileId===this.profileId),this.uiProfile!==void 0&&(this.uiPluginIndex=Math.min(this.uiPluginIndex,Math.max(0,this.uiProfile.plugins.length-1))))}currentUiPlugin(){return this.uiProfile?.plugins[this.uiPluginIndex]}handleInput(data){if(!this._focused||this.uiProfile===void 0)return;let keybindings=getKeybindings();if(keybindings.matches(data,"tui.select.up")){this.uiPluginIndex=Math.max(0,this.uiPluginIndex-1),this.requestRender?.();return}if(keybindings.matches(data,"tui.select.down")){this.uiPluginIndex=Math.min(this.uiProfile.plugins.length-1,this.uiPluginIndex+1),this.requestRender?.();return}if(keybindings.matches(data,"tui.select.cancel")){this._focused=!1,this.onClose?.(),this.requestRender?.();return}if(!keybindings.matches(data,"tui.select.confirm")&&data!==" ")return;let plugin=this.currentUiPlugin();plugin===void 0||this.controller===void 0||plugin.state==="disabled"&&plugin.availability!=="ready"||this.controller.toggle({profileId:this.profileId,pluginId:plugin.pluginId}).then(result=>{this.setUiSnapshot(result),this.requestRender?.()}).catch(()=>this.requestRender?.())}async openPluginSelection(){let controllerResult;this.controller!==void 0&&(controllerResult=await this.controller.getSnapshot(),this.setUiSnapshot(controllerResult));let status2=this.hasHostEntry()?"ready":"unsupported",selection=this.selection,codes=Object.freeze([]);if(controllerResult?.status==="error"&&(status2=controllerResult.code==="store-cancelled"?"cancelled":"invalid"),this.store!==void 0){let result=await this.store.read();if(codes=diagnosticCodes2(result),result.status==="ok"||result.status==="missing"){let storedSelection=selectionForProfile2(result,this.profileId);selection=summarizePluginSelectionV1(storedSelection),status2=result.status==="ok"?"ready":"missing"}else selection=emptySelectionSummary(),status2=result.status;this.selection=selection}let context=Object.freeze({profileId:this.profileId,status:status2,selection,catalog:this.catalog,diagnosticCodes:codes});return this.onOpen!==void 0&&await this.onOpen(context),context}invalidate(){}getSelectionSummary(){return this.selection}getCatalogSummary(){return this.catalog}};var RESOURCE_TYPES2=["skills","prompts","themes"],RESOURCE_TYPE_LABELS={skills:"Skills",prompts:"Prompts",themes:"Themes"};function formatBaseDir(baseDir){let homeDir=homedir10(),displayPath;return baseDir===homeDir?displayPath="~":baseDir.startsWith(homeDir)?displayPath=`~${baseDir.slice(homeDir.length).replace(/\\/g,"/")}`:displayPath=baseDir.replace(/\\/g,"/"),displayPath.endsWith("/")?displayPath:`${displayPath}/`}function getGroupLabel(metadata,agentDir){return metadata.origin==="package"?`${metadata.source} (${metadata.scope})`:metadata.source==="auto"?metadata.baseDir?metadata.scope==="user"?`User (${formatBaseDir(metadata.baseDir)})`:`Project (${formatBaseDir(metadata.baseDir)})`:metadata.scope==="user"?`User (${formatBaseDir(agentDir)})`:`Project (${CONFIG_DIR_NAME}/)`:metadata.scope==="user"?"User settings":"Project settings"}function buildGroups(resolved,agentDir){let groupMap=new Map,addToGroup=(resources,resourceType)=>{for(let res of resources){let{path:path15,enabled,metadata}=res,groupKey2=`${metadata.origin}:${metadata.scope}:${metadata.source}:${metadata.baseDir??""}`;groupMap.has(groupKey2)||groupMap.set(groupKey2,{key:groupKey2,label:getGroupLabel(metadata,agentDir),scope:metadata.scope,origin:metadata.origin,source:metadata.source,subgroups:[]});let group=groupMap.get(groupKey2),subgroupKey=`${groupKey2}:${resourceType}`,subgroup=group.subgroups.find(sg=>sg.type===resourceType);subgroup||(subgroup={type:resourceType,label:RESOURCE_TYPE_LABELS[resourceType],items:[]},group.subgroups.push(subgroup));let fileName=basename16(path15),parentFolder=basename16(dirname31(path15)),displayName;resourceType==="skills"&&fileName==="SKILL.md"?displayName=parentFolder:displayName=fileName,subgroup.items.push({path:path15,enabled,metadata,resourceType,displayName,groupKey:groupKey2,subgroupKey})}};addToGroup(resolved.skills,"skills"),addToGroup(resolved.prompts,"prompts"),addToGroup(resolved.themes,"themes");let groups=Array.from(groupMap.values());groups.sort((a,b2)=>a.origin!==b2.origin?a.origin==="package"?-1:1:a.scope!==b2.scope?a.scope==="user"?-1:1:a.source.localeCompare(b2.source));let typeOrder={skills:0,prompts:1,themes:2};for(let group of groups){group.subgroups.sort((a,b2)=>typeOrder[a.type]-typeOrder[b2.type]);for(let subgroup of group.subgroups)subgroup.items.sort((a,b2)=>a.displayName.localeCompare(b2.displayName))}return groups}var ConfigSelectorHeader=class{writeScope;projectModeAvailable;constructor(writeScope,projectModeAvailable){this.writeScope=writeScope,this.projectModeAvailable=projectModeAvailable}setWriteScope(writeScope){this.writeScope=writeScope}invalidate(){}render(width){let title=theme.bold(this.writeScope==="project"?"Project Local Resources":"Global Resources"),sep15=theme.fg("muted"," \xB7 "),switchHint=this.projectModeAvailable?keyHint("tui.input.tab","switch mode")+sep15:"",actionHint=this.writeScope==="project"?rawKeyHint("space","cycle inherit/+/-"):rawKeyHint("space","toggle"),hint=switchHint+actionHint+sep15+rawKeyHint("esc","close"),spacing=Math.max(1,width-visibleWidth(title)-visibleWidth(hint)),scopeHint=this.writeScope==="project"?theme.fg("muted",`${CONFIG_DIR_NAME}/settings.json \xB7 inherited global resources are dimmed`):theme.fg("muted",`~/${CONFIG_DIR_NAME}/agent/settings.json`);return[truncateToWidth(`${title}${" ".repeat(spacing)}${hint}`,width,""),truncateToWidth(scopeHint,width,"")]}},ResourceList=class{groupsByScope;flatItems=[];filteredItems=[];selectedIndex=0;searchInput;maxVisible;settingsManager;cwd;agentDir;writeScope;inheritedEnabledByKey;pluginSelectionEntry;pluginManagerEntry;pluginManagerScope;onCancel;onExit;onToggle;onSwitchMode;_focused=!1;get focused(){return this._focused}set focused(value){this._focused=value,this.searchInput.focused=value}constructor(groupsByScope,settingsManager,cwd,agentDir,terminalHeight,writeScope="global",pluginSelectionEntry,pluginManagerEntry,pluginManagerScope="global"){this.groupsByScope=groupsByScope,this.settingsManager=settingsManager,this.cwd=cwd,this.agentDir=agentDir,this.writeScope=writeScope,this.pluginSelectionEntry=pluginSelectionEntry,this.pluginManagerEntry=pluginManagerEntry,this.pluginManagerScope=pluginManagerScope,this.inheritedEnabledByKey=this.buildInheritedEnabledMap(groupsByScope.global),this.searchInput=new Input;let chrome=8;this.maxVisible=Math.max(5,(terminalHeight??24)-chrome),this.buildFlatList(),this.filteredItems=[...this.flatItems]}setWriteScope(writeScope){this.writeScope=writeScope,this.buildFlatList(),this.filterItems(this.searchInput.getValue())}get groups(){return this.groupsByScope[this.writeScope]}buildInheritedEnabledMap(groups){let result=new Map;for(let group of groups)for(let subgroup of group.subgroups)for(let item of subgroup.items)result.set(this.getResourceItemKey(item),item.enabled);return result}buildFlatList(){this.flatItems=[];for(let group of this.groups){this.flatItems.push({type:"group",group});for(let subgroup of group.subgroups){this.flatItems.push({type:"subgroup",subgroup,group});for(let item of subgroup.items)this.flatItems.push({type:"item",item})}}this.pluginSelectionEntry!==void 0&&this.flatItems.push({type:"plugin",entry:this.pluginSelectionEntry}),this.pluginManagerEntry!==void 0&&this.writeScope===this.pluginManagerScope&&this.flatItems.push({type:"plugin-manager",entry:this.pluginManagerEntry}),this.selectedIndex=this.flatItems.findIndex(e=>e.type==="item"||e.type==="plugin"||e.type==="plugin-manager"),this.selectedIndex<0&&(this.selectedIndex=0)}findNextItem(fromIndex,direction){let idx=fromIndex+direction;for(;idx>=0&&idx<this.filteredItems.length;){if(this.filteredItems[idx].type==="item"||this.filteredItems[idx].type==="plugin"||this.filteredItems[idx].type==="plugin-manager")return idx;idx+=direction}return fromIndex}filterItems(query){if(!query.trim()){this.filteredItems=[...this.flatItems],this.selectFirstItem();return}let lowerQuery=query.toLowerCase(),matchingItems=new Set,matchingSubgroups=new Set,matchingGroups=new Set;for(let entry of this.flatItems)if(entry.type==="item"){let item=entry.item;(item.displayName.toLowerCase().includes(lowerQuery)||item.resourceType.toLowerCase().includes(lowerQuery)||item.path.toLowerCase().includes(lowerQuery))&&matchingItems.add(item)}for(let group of this.groups)for(let subgroup of group.subgroups)for(let item of subgroup.items)matchingItems.has(item)&&(matchingSubgroups.add(subgroup),matchingGroups.add(group));this.filteredItems=[];for(let entry of this.flatItems)entry.type==="group"&&matchingGroups.has(entry.group)?this.filteredItems.push(entry):entry.type==="subgroup"&&matchingSubgroups.has(entry.subgroup)?this.filteredItems.push(entry):entry.type==="item"&&matchingItems.has(entry.item)&&this.filteredItems.push(entry);this.selectFirstItem()}selectFirstItem(){let firstItemIndex=this.filteredItems.findIndex(e=>e.type==="item"||e.type==="plugin"||e.type==="plugin-manager");this.selectedIndex=firstItemIndex>=0?firstItemIndex:0}updateItem(item,enabled){item.enabled=enabled;for(let group of this.groups)for(let subgroup of group.subgroups){let found=subgroup.items.find(i=>i.path===item.path&&i.resourceType===item.resourceType);if(found){found.enabled=enabled;return}}}invalidate(){}render(width){let lines=[];if(lines.push(...this.searchInput.render(width)),lines.push(""),this.filteredItems.length===0)return lines.push(theme.fg("muted"," No resources found")),lines;let startIndex=Math.max(0,Math.min(this.selectedIndex-Math.floor(this.maxVisible/2),this.filteredItems.length-this.maxVisible)),endIndex=Math.min(startIndex+this.maxVisible,this.filteredItems.length);for(let i=startIndex;i<endIndex;i++){let entry=this.filteredItems[i],isSelected=i===this.selectedIndex;if(entry.type==="group"){let inherited=this.writeScope==="project"&&entry.group.scope==="user",label=theme.bold(`${entry.group.label}${inherited?" \xB7 inherited global":""}`),groupLine=theme.fg(inherited?"dim":"accent",label);lines.push(truncateToWidth(` ${groupLine}`,width,""))}else if(entry.type==="subgroup"){let color=this.writeScope==="project"&&entry.group.scope==="user"?"dim":"muted",subgroupLine=theme.fg(color,entry.subgroup.label);lines.push(truncateToWidth(` ${subgroupLine}`,width,""))}else if(entry.type==="plugin"){let prefix=isSelected?"> ":" ";for(let line of entry.entry.render(width))lines.push(truncateToWidth(`${prefix}${line.trimStart()}`,width,"..."))}else if(entry.type==="plugin-manager"){let prefix=isSelected?"> ":" ";for(let line of entry.entry.render(width))lines.push(truncateToWidth(`${prefix}${line.trimStart()}`,width,"..."))}else{let item=entry.item,cursor=isSelected?"> ":" ",dimmed=this.isDimmedItem(item),nameText=isSelected&&!dimmed?theme.bold(item.displayName):item.displayName,name=dimmed?theme.fg("dim",nameText):nameText;lines.push(truncateToWidth(`${cursor} ${this.renderCheckbox(item)} ${name}${this.getItemSuffix(item)}`,width,"..."))}}if(startIndex>0||endIndex<this.filteredItems.length){let itemCount=this.filteredItems.filter(e=>e.type==="item"||e.type==="plugin"||e.type==="plugin-manager").length,currentItemIndex=this.filteredItems.slice(0,this.selectedIndex).filter(e=>e.type==="item"||e.type==="plugin"||e.type==="plugin-manager").length+1;lines.push(theme.fg("dim",` (${currentItemIndex}/${itemCount})`))}return lines}handleInput(data){let kb=getKeybindings();if(this.pluginSelectionEntry?.focused===!0){this.pluginSelectionEntry.handleInput(data);return}if(this.pluginManagerEntry?.focused===!0){this.pluginManagerEntry.handleInput(data);return}if(kb.matches(data,"tui.select.up")){this.selectedIndex=this.findNextItem(this.selectedIndex,-1);return}if(kb.matches(data,"tui.select.down")){this.selectedIndex=this.findNextItem(this.selectedIndex,1);return}if(kb.matches(data,"tui.select.pageUp")){let target=Math.max(0,this.selectedIndex-this.maxVisible);for(;target<this.filteredItems.length&&this.filteredItems[target].type!=="item"&&this.filteredItems[target].type!=="plugin"&&this.filteredItems[target].type!=="plugin-manager";)target++;target<this.filteredItems.length&&(this.selectedIndex=target);return}if(kb.matches(data,"tui.select.pageDown")){let target=Math.min(this.filteredItems.length-1,this.selectedIndex+this.maxVisible);for(;target>=0&&this.filteredItems[target].type!=="item"&&this.filteredItems[target].type!=="plugin"&&this.filteredItems[target].type!=="plugin-manager";)target--;target>=0&&(this.selectedIndex=target);return}if(kb.matches(data,"tui.select.cancel")){this.onCancel?.();return}if(kb.matches(data,"app.config.exit")){this.onExit?.();return}if(kb.matches(data,"tui.input.tab")){this.onSwitchMode?.();return}if(data===" "||kb.matches(data,"tui.select.confirm")){let entry=this.filteredItems[this.selectedIndex];if(entry?.type==="plugin"&&this.writeScope==="global"){entry.entry.focused=!0,entry.entry.openPluginSelection();return}if(entry?.type==="plugin-manager"&&this.writeScope===this.pluginManagerScope){entry.entry.focused=!0,entry.entry.openPluginManager();return}if(entry?.type==="item"&&(this.writeScope==="project"||this.getItemScope(entry.item)==="user")){let newEnabled=this.toggleResource(entry.item);newEnabled!==void 0&&(this.updateItem(entry.item,newEnabled),this.onToggle?.(entry.item,newEnabled))}return}this.searchInput.handleInput(data),this.filterItems(this.searchInput.getValue())}toggleResource(item){if(this.writeScope==="project"){let state2=this.getNextOverrideState(item);return this.setProjectResourceOverride(item,state2)?state2==="inherit"?this.getInheritedEnabled(item):state2==="load":void 0}let enabled=!item.enabled;return item.metadata.origin==="top-level"?this.toggleTopLevelResource(item,enabled):this.togglePackageResource(item,enabled),enabled}toggleTopLevelResource(item,enabled){let scope=item.metadata.scope,settings2=scope==="project"?this.settingsManager.getProjectSettings():this.settingsManager.getGlobalSettings(),arrayKey=item.resourceType,current=settings2[arrayKey]??[],pattern=this.getResourcePattern(item),disablePattern=`-${pattern}`,enablePattern=`+${pattern}`,updated=current.filter(p=>(p.startsWith("!")||p.startsWith("+")||p.startsWith("-")?p.slice(1):p)!==pattern);enabled?updated.push(enablePattern):updated.push(disablePattern),scope==="project"?arrayKey==="skills"?this.settingsManager.setProjectSkillPaths(updated):arrayKey==="prompts"?this.settingsManager.setProjectPromptTemplatePaths(updated):arrayKey==="themes"&&this.settingsManager.setProjectThemePaths(updated):arrayKey==="skills"?this.settingsManager.setSkillPaths(updated):arrayKey==="prompts"?this.settingsManager.setPromptTemplatePaths(updated):arrayKey==="themes"&&this.settingsManager.setThemePaths(updated)}togglePackageResource(item,enabled){let scope=item.metadata.scope,packages=[...(scope==="project"?this.settingsManager.getProjectSettings():this.settingsManager.getGlobalSettings()).packages??[]],pkgIndex=packages.findIndex(pkg3=>(typeof pkg3=="string"?pkg3:pkg3.source)===item.metadata.source);if(pkgIndex===-1)return;let pkg2=packages[pkgIndex];typeof pkg2=="string"&&(pkg2={source:pkg2},packages[pkgIndex]=pkg2);let arrayKey=item.resourceType,current=pkg2[arrayKey]??[],pattern=this.getPackageResourcePattern(item),disablePattern=`-${pattern}`,enablePattern=`+${pattern}`,updated=current.filter(p=>(p.startsWith("!")||p.startsWith("+")||p.startsWith("-")?p.slice(1):p)!==pattern);enabled?updated.push(enablePattern):updated.push(disablePattern),pkg2[arrayKey]=updated.length>0?updated:void 0,["skills","prompts","themes"].some(k=>pkg2[k]!==void 0)||(packages[pkgIndex]=pkg2.source),scope==="project"?this.settingsManager.setProjectPackages(packages):this.settingsManager.setPackages(packages)}renderCheckbox(item){if(this.writeScope==="project"){let state2=this.getProjectOverrideState(item);return state2==="load"?theme.fg("success","[+]"):state2==="unload"?theme.fg("warning","[-]"):theme.fg("dim",item.enabled?"[x]":"[ ]")}return item.enabled?theme.fg("success","[x]"):theme.fg("dim","[ ]")}getItemSuffix(item){if(this.writeScope!=="project")return"";let state2=this.getProjectOverrideState(item);return state2==="load"?theme.fg("muted"," project load"):state2==="unload"?theme.fg("muted"," project unload"):this.isInheritedGlobalItem(item)?theme.fg("dim"," inherited global"):""}isDimmedItem(item){return this.writeScope==="project"&&this.isInheritedGlobalItem(item)&&this.getProjectOverrideState(item)==="inherit"}setProjectResourceOverride(item,state2){return item.metadata.origin==="top-level"?this.setProjectTopLevelOverride(item,state2):this.setProjectPackageOverride(item,state2)}setProjectTopLevelOverride(item,state2){let current=this.settingsManager.getProjectSettings()[item.resourceType]??[],pattern=this.isInheritedGlobalItem(item)?item.path:this.getResourcePatternForScope(item,"project"),patterns=this.getTopLevelOverridePatterns(item,"project"),updated=current.filter(entry=>{let target=this.getPatternEntryTarget(entry);return(entry.startsWith("!")||entry.startsWith("+")||entry.startsWith("-"))&&patterns.has(target)?!1:!(state2==="inherit"&&this.isInheritedGlobalItem(item)&&target===pattern)});return state2!=="inherit"&&(this.isInheritedGlobalItem(item)&&!updated.includes(pattern)&&updated.push(pattern),updated.push(`${state2==="load"?"+":"-"}${pattern}`)),this.setProjectTopLevelPaths(item.resourceType,updated),!0}setProjectTopLevelPaths(key,paths){key==="skills"?this.settingsManager.setProjectSkillPaths(paths):key==="prompts"?this.settingsManager.setProjectPromptTemplatePaths(paths):this.settingsManager.setProjectThemePaths(paths)}setProjectPackageOverride(item,state2){let packages=[...this.settingsManager.getProjectSettings().packages??[]],pkgIndex=packages.findIndex(pkg3=>this.packageSourceStringMatches(item.metadata.source,this.getItemScope(item),typeof pkg3=="string"?pkg3:pkg3.source,"project"));if(pkgIndex===-1){if(state2==="inherit")return!1;packages.push(this.createPackageOverrideSource(item)),pkgIndex=packages.length-1}let pkg2=packages[pkgIndex];if(pkg2===void 0)return!1;typeof pkg2=="string"&&(pkg2={source:pkg2},packages[pkgIndex]=pkg2);let pattern=this.getPackageResourcePattern(item),updated=(pkg2[item.resourceType]??[]).filter(entry=>this.getPatternEntryTarget(entry)!==pattern);return state2!=="inherit"&&updated.push(`${state2==="load"?"+":"-"}${pattern}`),pkg2[item.resourceType]=updated.length>0?updated:void 0,RESOURCE_TYPES2.some(key=>pkg2[key]!==void 0)||(pkg2.autoload===!1?packages.splice(pkgIndex,1):packages[pkgIndex]=pkg2.source),this.settingsManager.setProjectPackages(packages),!0}getNextOverrideState(item){let state2=this.getProjectOverrideState(item),inheritedEnabled=this.getInheritedEnabled(item);return state2==="inherit"?inheritedEnabled?"unload":"load":state2==="unload"?inheritedEnabled?"load":"inherit":inheritedEnabled?"inherit":"unload"}getProjectOverrideState(item){if(this.writeScope!=="project")return"inherit";if(item.metadata.origin==="top-level")return this.getOverrideStateFromEntries(this.settingsManager.getProjectSettings()[item.resourceType]??[],this.getTopLevelOverridePatterns(item,"project"),!1);let pkg2=this.findMatchingPackageSource(item,"project");if(typeof pkg2!="object")return"inherit";let entries=pkg2[item.resourceType];return entries===void 0?"inherit":this.getOverrideStateFromEntries(entries,new Set([this.getPackageResourcePattern(item)]),pkg2.autoload!==!1)}getOverrideStateFromEntries(entries,patterns,emptyArrayIsUnload){if(entries.length===0&&emptyArrayIsUnload)return"unload";let state2="inherit";for(let entry of entries)patterns.has(this.getPatternEntryTarget(entry))&&(entry.startsWith("!")||entry.startsWith("-")?state2="unload":state2="load");return state2}getInheritedEnabled(item){return this.inheritedEnabledByKey.get(this.getResourceItemKey(item))??(this.getItemScope(item)==="user"?item.enabled:!0)}isInheritedGlobalItem(item){return this.getItemScope(item)==="user"||this.inheritedEnabledByKey.has(this.getResourceItemKey(item))}getTopLevelOverridePatterns(item,scope){let baseDir=this.getTopLevelBaseDir(scope),patterns=new Set([this.getResourcePatternForScope(item,scope),item.path,relative12(baseDir,item.path)]);return item.metadata.baseDir&&patterns.add(relative12(item.metadata.baseDir,item.path)),patterns}getResourcePatternForScope(item,scope){let sourceScope=this.getItemScope(item);if(scope!==sourceScope)return item.path;let baseDir=item.metadata.baseDir??this.getTopLevelBaseDir(sourceScope);return relative12(baseDir,item.path)}createPackageOverrideSource(item){let source=item.metadata.source;if(!isLocalPath(source))return{source,autoload:!1};let sourcePath=resolvePath(source,this.getTopLevelBaseDir(this.getItemScope(item)),{trim:!0});return{source:relative12(this.getTopLevelBaseDir("project"),sourcePath)||".",autoload:!1}}packageSourceStringMatches(leftSource,leftScope,rightSource,rightScope){if(leftSource===rightSource)return!0;if(!isLocalPath(leftSource)||!isLocalPath(rightSource))return!1;let left=resolvePath(leftSource,this.getTopLevelBaseDir(leftScope),{trim:!0}),right=resolvePath(rightSource,this.getTopLevelBaseDir(rightScope),{trim:!0});return left===right}findMatchingPackageSource(item,targetScope){return((targetScope==="project"?this.settingsManager.getProjectSettings():this.settingsManager.getGlobalSettings()).packages??[]).find(pkg2=>this.packageSourceStringMatches(item.metadata.source,this.getItemScope(item),typeof pkg2=="string"?pkg2:pkg2.source,targetScope))}getPatternEntryTarget(entry){return entry.startsWith("!")||entry.startsWith("+")||entry.startsWith("-")?entry.slice(1):entry}getResourceItemKey(item){return`${item.resourceType}:${canonicalizePath(item.path)}`}getItemScope(item){return item.metadata.scope==="project"?"project":"user"}getTopLevelBaseDir(scope){return scope==="project"?join65(this.cwd,CONFIG_DIR_NAME):this.agentDir}getResourcePattern(item){let scope=item.metadata.scope,baseDir=item.metadata.baseDir??this.getTopLevelBaseDir(scope);return relative12(baseDir,item.path)}getPackageResourcePattern(item){let baseDir=item.metadata.baseDir??dirname31(item.path);return relative12(baseDir,item.path)}},ConfigSelectorComponent=class extends Container{header;resourceList;pluginSelectionEntry;pluginManagerEntry;writeScope;_focused=!1;get focused(){return this._focused}set focused(value){this._focused=value,this.resourceList.focused=value}constructor(resolvedPaths,settingsManager,cwd,agentDir,onClose,onExit,requestRender,terminalHeight,writeScope="global",projectModeAvailable=!0,pluginSelection,pluginManager,pluginManagerScope="global"){super(),this.writeScope=writeScope;let groupsByScope={global:buildGroups(resolvedPaths.global,agentDir),project:buildGroups(resolvedPaths.project,agentDir)},pluginSelectionEntry=pluginSelection===void 0?void 0:new PluginSelectionEntryComponent({...pluginSelection,onClose:()=>{pluginSelection.onClose?.()},requestRender});this.pluginSelectionEntry=pluginSelectionEntry;let pluginManagerEntry=pluginManager===void 0?void 0:new PluginManagerEntryComponent({...pluginManager,onClose:()=>{pluginManager.onClose?.()},requestRender});this.pluginManagerEntry=pluginManagerEntry,this.addChild(new Spacer(1)),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.header=new ConfigSelectorHeader(this.writeScope,projectModeAvailable),this.addChild(this.header),this.addChild(new Spacer(1)),this.resourceList=new ResourceList(groupsByScope,settingsManager,cwd,agentDir,terminalHeight===void 0?void 0:Math.max(5,terminalHeight-(pluginSelection===void 0?0:2)-(pluginManager===void 0?0:2)),this.writeScope,pluginSelectionEntry,pluginManagerEntry,pluginManagerScope),this.resourceList.onCancel=onClose,this.resourceList.onExit=onExit,this.resourceList.onToggle=()=>requestRender(),projectModeAvailable&&(this.resourceList.onSwitchMode=()=>{this.switchWriteScope(),requestRender()}),this.addChild(this.resourceList),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder)}switchWriteScope(){this.writeScope=this.writeScope==="global"?"project":"global",this.header.setWriteScope(this.writeScope),this.resourceList.setWriteScope(this.writeScope)}getResourceList(){return this.resourceList}getPluginSelectionEntry(){return this.pluginSelectionEntry}getPluginManagerEntry(){return this.pluginManagerEntry}async openPluginSelection(){return this.pluginSelectionEntry===void 0?void 0:await this.pluginSelectionEntry.openPluginSelection()}async openPluginManager(){return this.pluginManagerEntry===void 0?void 0:await this.pluginManagerEntry.openPluginManager()}};async function selectConfig(options){initTheme(options.settingsManager.getTheme(),!0);let pluginSnapshot=options.pluginSelectionController?await options.pluginSelectionController.getSnapshot():void 0,pluginManagerSnapshot=options.pluginManagerController?await options.pluginManagerController.getSnapshot():void 0;return new Promise(resolve25=>{let ui=new TuiMainScreen(new ProcessTerminal,void 0,options.agentDir),resolved=!1,selector=new ConfigSelectorComponent(options.resolvedPaths,options.settingsManager,options.cwd,options.agentDir,()=>{resolved||(resolved=!0,ui.stop(),stopThemeWatcher(),resolve25())},()=>{ui.stop(),stopThemeWatcher(),process.exit(0)},()=>ui.requestRender(),ui.terminal.rows,options.writeScope,options.projectModeAvailable,options.pluginSelectionController===void 0?void 0:{profileId:options.pluginSelectionProfileId??"coding-core",controller:options.pluginSelectionController,snapshot:pluginSnapshot?.status==="ok"?pluginSnapshot.snapshot:void 0,onOpen:()=>ui.requestRender(),requestRender:()=>ui.requestRender()},options.pluginManagerController===void 0?void 0:{controller:options.pluginManagerController,snapshot:pluginManagerSnapshot?.status==="ok"?pluginManagerSnapshot.snapshot:void 0,requestRender:()=>ui.requestRender()},options.pluginManagerScope);ui.addChild(selector),ui.setFocus(selector.getResourceList()),ui.start()})}import{randomUUID as randomUUID21}from"node:crypto";import{copyFileSync as copyFileSync2,existsSync as existsSync32,mkdirSync as mkdirSync21,renameSync as renameSync5,rmSync as rmSync7}from"node:fs";import{basename as basename17,dirname as dirname32,join as join66,relative as relative13,resolve as resolve23,toNamespacedPath}from"node:path";var QUARANTINE_DIR_NAME=".agent-forge-native-quarantine";function normalizePath2(path15){return toNamespacedPath(resolve23(path15))}function getQuarantineRoot(packageDir){let current=resolve23(packageDir);for(;;){if(basename17(current).toLowerCase()==="node_modules")return join66(current,QUARANTINE_DIR_NAME);let parent=dirname32(current);if(parent===current)return;current=parent}}function getLoadedSharedObjectsInPackageDir(packageDir){let sharedObjects=process.report.getReport().sharedObjects;if(!Array.isArray(sharedObjects))return[];let root=normalizePath2(packageDir).toLowerCase(),seen=new Set,loadedFiles=[];for(let value of sharedObjects){if(typeof value!="string")continue;let filePath=normalizePath2(value),comparisonPath=filePath.toLowerCase();getCwdRelativePath(comparisonPath,root)===void 0||seen.has(comparisonPath)||(seen.add(comparisonPath),loadedFiles.push(filePath))}return loadedFiles}function cleanupWindowsSelfUpdateQuarantine(packageDir){let quarantineRoot=getQuarantineRoot(packageDir);if(quarantineRoot)try{rmSync7(quarantineRoot,{recursive:!0,force:!0})}catch{}}function quarantineWindowsNativeDependencies(packageDir){let resolvedPackageDir=normalizePath2(packageDir),quarantineRoot=getQuarantineRoot(resolvedPackageDir);if(!quarantineRoot)return;let loadedFiles=getLoadedSharedObjectsInPackageDir(resolvedPackageDir);if(loadedFiles.length===0)return;let quarantineRunDir=join66(quarantineRoot,`${Date.now()}-${process.pid}-${randomUUID21()}`);for(let loadedFile of loadedFiles){if(!existsSync32(loadedFile))continue;let quarantinePath=join66(quarantineRunDir,relative13(resolvedPackageDir,loadedFile));mkdirSync21(dirname32(quarantinePath),{recursive:!0}),renameSync5(loadedFile,quarantinePath),copyFileSync2(quarantinePath,loadedFile)}}var MANAGED_INSTALL_MARKER="managed-install.json",MANAGED_RELEASE_VERSION_RE=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function getActiveManagedInstallRoot(){let configuredRoot=process.env.AGENT_FORGE_MANAGED_INSTALL_ROOT?.trim();if(!configuredRoot)return;let managedRoot=resolve24(configuredRoot),releasesDir=canonicalizePath(join67(managedRoot,"releases"));if(getCwdRelativePath(canonicalizePath(getPackageDir()),releasesDir)===void 0)return;let markerPath=join67(managedRoot,MANAGED_INSTALL_MARKER);try{let marker=JSON.parse(readFileSync28(markerPath,"utf8"));if(marker.kind!=="agent-forge-managed-install"||marker.schemaVersion!==1||marker.layout!=="releases-v1")throw new Error}catch{throw new Error(`Managed install marker is missing or invalid: ${markerPath}`)}return managedRoot}async function fetchInstallerArtifact(url,label){let response2=await fetch(url,{headers:{"User-Agent":getAgentForgeUserAgent(VERSION)}});if(!response2.ok)throw new Error(`Could not download managed installer ${label} from ${url}: HTTP ${response2.status}`);return await response2.text()}async function runManagedNpmCi(stageDir){let args=["ci","--ignore-scripts","--min-release-age=0","--omit=dev","--include=optional","--no-fund","--no-audit","--loglevel=error","--progress=false"],code=await waitForChildProcess(spawnProcess("npm",args,{cwd:stageDir,stdio:"inherit"}));if(code!==0)throw new Error(`npm ${args.join(" ")} exited with code ${code??"unknown"}`)}function verifyManagedRelease(releaseDir,expectedVersion){let binPath=join67(releaseDir,"node_modules",".bin",process.platform==="win32"?`${APP_NAME}.cmd`:APP_NAME),result=spawnProcessSync(binPath,["--version"],{encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(result.error||result.status!==0){let reason=result.error?.message||result.stderr.trim()||`exit code ${result.status??"unknown"}`;throw new Error(`Could not verify managed ${APP_NAME} ${expectedVersion}: ${reason}`)}let installedVersion=result.stdout.trim();if(installedVersion!==expectedVersion)throw new Error(`Managed ${APP_NAME} smoke test returned version ${installedVersion}; expected ${expectedVersion}.`)}async function activateStagedRelease(stageDir,releaseDir){for(let attempt2=0;;attempt2++)try{renameSync6(stageDir,releaseDir);return}catch(error2){if(attempt2>=9||!existsSync33(stageDir))throw error2;await sleep3(1e3)}}function activateManagedRelease(managedRoot,version){let currentPath=join67(managedRoot,"current-version"),temporaryPath=join67(managedRoot,`current-version.tmp.${process.pid}-${Date.now()}`);try{writeFileSync18(temporaryPath,`${version}
|
package/dist/bundle/cli.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
|
|
3
|
-
import{APP_NAME,configureHttpDispatcher,main}from"./chunks/chunk-
|
|
3
|
+
import{APP_NAME,configureHttpDispatcher,main}from"./chunks/chunk-BTBDSCF4.js";import"./chunks/chunk-JUUC5AZY.js";import"./chunks/chunk-XDUWOHPL.js";import"./chunks/chunk-3QKHSPQL.js";import"./chunks/chunk-DRQDKNXA.js";import"./chunks/chunk-7ZY7IXZD.js";import"./chunks/chunk-V46XUTK3.js";import"./chunks/chunk-WGLBM2BP.js";import"./chunks/chunk-4L3WN2XY.js";process.title=APP_NAME;process.env.AGENT_FORGE="true";process.env.AI_AGENT="agent-forge";process.emitWarning=(()=>{});configureHttpDispatcher();main(process.argv.slice(2));
|