@stackone/cli 1.17.1 → 1.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const e=require(`./agentConfig-CgKwpn5X.cjs`),t=require(`./cliCore-
|
|
2
|
+
const e=require(`./agentConfig-CgKwpn5X.cjs`),t=require(`./cliCore-BsHXu26d.cjs`);require(`./setupMigration-DAlx4sxl.cjs`);let n=require(`dotenv`);process.env.DOTENV_CONFIG_QUIET=`true`,(0,n.config)(),new t.t().run();
|
package/dist/cli.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import"./agentConfig-BljaB-6S.mjs";import{t as e}from"./cliCore-
|
|
2
|
+
import"./agentConfig-BljaB-6S.mjs";import{t as e}from"./cliCore-CTkOiHS_.mjs";import"./setupMigration-DdeVl8db.mjs";import{config as t}from"dotenv";process.env.DOTENV_CONFIG_QUIET=`true`,t(),new e().run();export{};
|
|
@@ -1,26 +1,33 @@
|
|
|
1
|
-
const e=require(`./agentConfig-CgKwpn5X.cjs`),t=require(`./setupMigration-DAlx4sxl.cjs`);let n=require(`chalk`);n=e.y(n);let r=require(`commander`),i=require(`@stackone/agent-harness`),a=require(`node:fs`);a=e.y(a);let o=require(`node:os`);o=e.y(o);let s=require(`node:path`);s=e.y(s);let c=require(`ink`),l=require(`react`);l=e.y(l);let u=require(`ink-spinner`);u=e.y(u);let d=require(`fs`);d=e.y(d);let f=require(`path`);f=e.y(f);let p=require(`url`),m=require(`node:child_process`),h=require(`node:fs/promises`),g=require(`node:util`),_=require(`ora`);_=e.y(_);let v=require(`node:process`),y=require(`node:readline`),b=require(`inquirer`);b=e.y(b);let x=require(`@stackone/utils`),S=require(`@clack/prompts`),C=require(`@stackone/connect-sdk`),w=require(`diff`),T=require(`readline`),E=require(`@stackone/transport`),D=require(`semver`);D=e.y(D);let O=require(`fs/promises`);function k(e){return e.replace(/\*\*\*(.+?)\*\*\*/g,`$1`).replace(/\*\*(.+?)\*\*/g,`$1`).replace(/\*(.+?)\*/g,`$1`).replace(/__(.+?)__/g,`$1`).replace(/_(.+?)_/g,`$1`).replace(/^#{1,6}\s+(.+)$/gm,`$1`).replace(/```[\s\S]*?```/g,``).replace(/`(.+?)`/g,`$1`).replace(/\[([^\]]+)\]\([^\)]+\)/g,`$1`).replace(/!\[([^\]]*)\]\([^\)]+\)/g,`$1`).replace(/^[-*_]{3,}$/gm,``).replace(/^>\s+/gm,``).trim()}const ee=({title:e,mode:t,connector:n,action:r,onSubmit:i,onExit:a,onStop:o,messages:s,currentToolCalls:d=[],isThinking:f=!1,isComplete:p=!1,error:m,isInterrupted:h=!1,commandHistory:g=[],streamingText:_=``,usage:v,detailViewData:y=null,onCloseDetailView:b,onResumeConversation:x,onToggleSkill:S,onRewindTo:C,spawnedSubagentActive:w=!1,spawnedSubagentName:T=`Subagent`,spawnedSubagentComplete:E=!1,queuedMessages:D=[],isProcessingQueue:O=!1,enabledSkills:ee=[],initInfo:te})=>{let{exit:A}=(0,c.useApp)(),[j,M]=(0,l.useState)(``),[
|
|
1
|
+
const e=require(`./agentConfig-CgKwpn5X.cjs`),t=require(`./setupMigration-DAlx4sxl.cjs`);let n=require(`chalk`);n=e.y(n);let r=require(`commander`),i=require(`@stackone/agent-harness`),a=require(`node:fs`);a=e.y(a);let o=require(`node:os`);o=e.y(o);let s=require(`node:path`);s=e.y(s);let c=require(`ink`),l=require(`react`);l=e.y(l);let u=require(`ink-spinner`);u=e.y(u);let d=require(`fs`);d=e.y(d);let f=require(`path`);f=e.y(f);let p=require(`url`),m=require(`node:child_process`),h=require(`node:fs/promises`),g=require(`node:util`),_=require(`ora`);_=e.y(_);let v=require(`node:process`),y=require(`node:readline`),b=require(`inquirer`);b=e.y(b);let x=require(`@stackone/utils`),S=require(`@clack/prompts`),C=require(`@stackone/connect-sdk`),w=require(`diff`),T=require(`readline`),E=require(`@stackone/transport`),D=require(`semver`);D=e.y(D);let O=require(`fs/promises`);function k(e){return e.replace(/\*\*\*(.+?)\*\*\*/g,`$1`).replace(/\*\*(.+?)\*\*/g,`$1`).replace(/\*(.+?)\*/g,`$1`).replace(/__(.+?)__/g,`$1`).replace(/_(.+?)_/g,`$1`).replace(/^#{1,6}\s+(.+)$/gm,`$1`).replace(/```[\s\S]*?```/g,``).replace(/`(.+?)`/g,`$1`).replace(/\[([^\]]+)\]\([^\)]+\)/g,`$1`).replace(/!\[([^\]]*)\]\([^\)]+\)/g,`$1`).replace(/^[-*_]{3,}$/gm,``).replace(/^>\s+/gm,``).trim()}const ee=({title:e,mode:t,connector:n,action:r,onSubmit:i,onExit:a,onStop:o,messages:s,currentToolCalls:d=[],isThinking:f=!1,isComplete:p=!1,error:m,isInterrupted:h=!1,commandHistory:g=[],streamingText:_=``,usage:v,detailViewData:y=null,onCloseDetailView:b,onResumeConversation:x,onToggleSkill:S,onRewindTo:C,spawnedSubagentActive:w=!1,spawnedSubagentName:T=`Subagent`,spawnedSubagentComplete:E=!1,queuedMessages:D=[],isProcessingQueue:O=!1,enabledSkills:ee=[],initInfo:te})=>{let{exit:A}=(0,c.useApp)(),[j,M]=(0,l.useState)(``),[N,P]=(0,l.useState)(0),[F,I]=(0,l.useState)(!0),ne=(0,l.useRef)(0),[L,re]=(0,l.useState)(0),ie=(0,l.useRef)(!1),[R,z]=(0,l.useState)(!1),B=(0,l.useRef)(s),[V,H]=(0,l.useState)(-1),ae=(0,l.useRef)(g),U=(0,l.useRef)(``),[W,oe]=(0,l.useState)([]),[G,se]=(0,l.useState)(0),[K,ce]=(0,l.useState)(0),[q,le]=(0,l.useState)(!1),[J,Y]=(0,l.useState)(!1),[X,Z]=(0,l.useState)(!1),[ue,de]=(0,l.useState)(!1),fe=[`/commands`,`/skills`,`/tools`,`/mcp`,`/compact`,`/rewind`,`/resume`,`/exit`];(0,l.useEffect)(()=>{ie.current=R},[R]),(0,l.useEffect)(()=>{ne.current=L},[L]),(0,l.useEffect)(()=>{B.current=s},[s]),(0,l.useEffect)(()=>{ae.current=g},[g]),(0,l.useEffect)(()=>{U.current=j,j.startsWith(`/`)?(oe(fe.filter(e=>e.startsWith(j.toLowerCase()))),se(0)):(oe([]),se(0))},[j]),(0,l.useEffect)(()=>{ie.current||re(0)},[s]),(0,c.useInput)((0,l.useCallback)((e,t)=>{let n=U.current,r=V;if(t.escape&&(f||_||d.length>0)){o?.(),M(``),P(0),H(-1);return}if(t.escape&&w&&X){Z(!1);return}if(y){if(t.escape||t.ctrl&&e===`c`)if(q){le(!1);return}else{b?.(),ce(0);return}if(t.upArrow&&!q){ce(e=>e>0?e-1:y.items.length-1);return}if(t.downArrow&&!q){ce(e=>e<y.items.length-1?e+1:0);return}if(t.ctrl&&e===`o`&&y.type===`skills`){let e=y.items[K];S&&S(e.name);return}if(t.return){if(q)return;if(y.type===`resume`){let e=y.items[K];e.messages&&x&&(x(e.messages),b?.(),ce(0));return}if(y.type===`rewind`){let e=y.items[K];e.index!==void 0&&C&&(C(e.index),b?.(),ce(0));return}le(!0);return}return}if(t.ctrl&&e===`o`){w?Z(e=>!e):de(e=>!e);return}if(t.ctrl&&e===`u`){M(``),P(0),H(-1),Y(!1);return}if(t.ctrl&&e===`c`||e===``)if(n.trim()){M(``),P(0),H(-1),Y(!1);return}else if(J){a(),A();return}else{Y(!0);return}if(t.shift&&t.return){M(e=>e.slice(0,N)+`
|
|
2
|
+
`+e.slice(N)),P(e=>e+1);return}if(t.ctrl&&e===`a`){P(0);return}if(t.ctrl&&e===`e`){P(n.length);return}if((t.alt||t.meta)&&t.leftArrow&&!t.ctrl&&!t.shift){let e=n.slice(0,N).match(/\S+\s*$/);P(e?N-e[0].length:0);return}if((t.alt||t.meta)&&t.rightArrow&&!t.ctrl&&!t.shift){let e=n.slice(N).match(/^\s*\S+/);P(e?N+e[0].length:n.length);return}if(t.home||e===`\x1B[H`||e===`\x1BOH`){P(0);return}if(t.end||e===`\x1B[F`||e===`\x1BOF`){P(n.length);return}if(process.platform===`darwin`&&t.meta&&t.leftArrow&&!t.alt){P(0);return}if(process.platform===`darwin`&&t.meta&&t.rightArrow&&!t.alt){P(n.length);return}if(process.platform===`darwin`&&t.meta&&t.upArrow){P(0);return}if(process.platform===`darwin`&&t.meta&&t.downArrow){P(n.length);return}if(t.ctrl&&t.leftArrow&&process.platform!==`darwin`){let e=n.slice(0,N).match(/\S+\s*$/);P(e?N-e[0].length:0);return}if(t.ctrl&&t.rightArrow&&process.platform!==`darwin`){let e=n.slice(N).match(/^\s*\S+/);P(e?N+e[0].length:n.length);return}if(t.upArrow){if(W.length>0){se(e=>e>0?e-1:W.length-1);return}let e=n.slice(0,N).lastIndexOf(`
|
|
3
|
+
`);if(e!==-1){let t=n.lastIndexOf(`
|
|
4
|
+
`,e-1),r=N-e-1,i=e-t-1;P(Math.max(0,e-i+Math.min(r,i-1),t+1));return}let t=ae.current;if(t.length>0&&(n===``||r>=0)){H(e=>{let n=e<0?t.length-1:Math.max(0,e-1),r=t[n]||``;return M(r),P(r.length),n});return}let i=Math.max(0,B.current.length-5),a=Math.min(ne.current+5,i);re(a),z(a>0);return}if(t.downArrow){if(W.length>0){se(e=>e<W.length-1?e+1:0);return}let e=n.indexOf(`
|
|
5
|
+
`,N);if(e!==-1){let t=N-(n.lastIndexOf(`
|
|
6
|
+
`,N-1)+1),r=n.indexOf(`
|
|
7
|
+
`,e+1),i=(r===-1?n.length:r)-e-1;P(e+1+Math.min(t,i));return}let t=ae.current;if(r>=0){H(e=>{let n=e>=t.length-1?-1:e+1,r=n<0?``:t[n]||``;return M(r),P(r.length),n});return}let i=Math.max(ne.current-5,0);re(i),z(i>0);return}if(t.return){if(W.length>0){let e=W[G];oe([]),se(0),M(``),P(0),i(e);return}j.trim()&&(i(j.trim()),M(``),P(0),H(-1),re(0),z(!1));return}if(t.backspace||t.delete){t.backspace&&N>0?(M(e=>e.slice(0,N-1)+e.slice(N)),P(e=>Math.max(0,e-1))):t.delete&&N<n.length&&M(e=>e.slice(0,N)+e.slice(N+1)),H(-1);return}if(t.leftArrow&&!t.meta&&!t.alt&&!t.ctrl){P(e=>Math.max(0,e-1));return}if(t.rightArrow&&!t.meta&&!t.alt&&!t.ctrl){P(e=>Math.min(n.length,e+1));return}if(t.tab&&n.startsWith(`/`)){let e=fe.filter(e=>e.startsWith(j.toLowerCase()));e.length===1&&(M(e[0]),P(e[0].length));return}if(e){if(t.meta||t.alt||t.ctrl)return;M(t=>t.slice(0,N)+e+t.slice(N)),P(e=>e+1),H(-1),Y(!1)}},[i,a,A,j,N,V,fe,W,G,y,q,b,J,w,E,X,x,K,f,_,d,o,S,C])),(0,l.useEffect)(()=>{p&&I(!1)},[p]);let Q=`\x1B[38;2;0;175;102m`,$=`\x1B[0m`,pe=`${Q} ╔═════════╗${$} ▄▖▗ ▌ ▄▖ ▄▖ ▗ ${Q}╔═════════╗${$}
|
|
2
8
|
${Q} ║ ┌────╚════╗${$} ▚ ▜▘▀▌▛▘▙▘▌▌▛▌█▌ ▌▌▛▌█▌▛▌▜▘ ${Q}║ ┌────╚════╗${$}
|
|
3
9
|
${Q} ╚════╗────┘ ║${$} ▄▌▐▖█▌▙▖▛▖▙▌▌▌▙▖ ▛▌▙▌▙▖▌▌▐▖ ${Q}╚════╗────┘ ║${$}
|
|
4
|
-
${Q} ╚═════════╝${$} ▄▌ ${Q}╚═════════╝${$}`;return l.default.createElement(c.Box,{flexDirection:`column`,padding:2},l.default.createElement(c.Box,{flexDirection:`column`,marginBottom:2,marginTop:1},l.default.createElement(c.Text,null,
|
|
10
|
+
${Q} ╚═════════╝${$} ▄▌ ${Q}╚═════════╝${$}`;return l.default.createElement(c.Box,{flexDirection:`column`,padding:2},l.default.createElement(c.Box,{flexDirection:`column`,marginBottom:2,marginTop:1},l.default.createElement(c.Text,null,pe,`
|
|
5
11
|
|
|
6
12
|
|
|
7
13
|
|
|
8
14
|
`),l.default.createElement(c.Text,{dimColor:!0},`⚠️ Data collected may be used for training and monitoring purposes`),s.length===0&&l.default.createElement(c.Text,{dimColor:!0},`
|
|
9
15
|
|
|
10
16
|
|
|
11
|
-
`,`Welcome to `,t,` mode! What would you like to do?`)),l.default.createElement(c.Box,{flexDirection:`column`,marginBottom:1},(()=>{let e=s.findIndex(e=>e.isSubagent),t=s.map((e,t)=>e.isSubagent?t:-1).reduce((e,t)=>Math.max(e,t),-1),n=e===-1?s:s.slice(0,e),r=t===-1?[]:s.slice(t+1),i=(e,t,n)=>{let r=e.role===`system`&&e.content.startsWith(`TOOL:`),i=e.role===`system`&&e.content.startsWith(`TOOL_START:`),a=e.role===`user`?`white`:e.role===`assistant`||r||i?`#00AF66`:`gray`,o=e.role===`user`?`❯ You`:e.role===`assistant`?`◆ StackOne Agent`:`ℹ System`,s=e.content,d=!1,f=!1;if(i&&(o=`🔧 Tool • ${e.content.split(`|||`)[1]||``}`,s=``,f=!
|
|
12
|
-
... (truncated)`)}return l.default.createElement(c.Box,{key:`${e.timestamp.getTime()}-${t}-${e.role}-subagent`,marginTop:1,flexDirection:`column`},l.default.createElement(c.Text,{bold:!0,color:`#00AF66`},r,l.default.createElement(c.Text,{dimColor:!0},` `,`•`,` `,e.timestamp.toLocaleTimeString())),l.default.createElement(c.Box,{paddingLeft:2},l.default.createElement(c.Text,{color:n?`gray`:`#00AF66`,dimColor:n},k(i))))}),!E&&!h&&f&&d.length===0&&l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{color:`#00AF66`},l.default.createElement(u.default,{type:`dots`})),l.default.createElement(c.Text,{dimColor:!0},` Thinking...`)),!E&&!h&&d.length>0&&l.default.createElement(c.Box,{flexDirection:`column`,marginTop:1},d.map((e,t)=>l.default.createElement(c.Box,{key:t,marginBottom:1},e.status===`running`&&l.default.createElement(c.Text,{color:`#00AF66`},l.default.createElement(u.default,{type:`dots`})),l.default.createElement(c.Text,{color:`#00AF66`},` `,`🔧 `,e.name,e.status===`running`&&`...`,e.status===`completed`&&` ✓`)))),!E&&_&&l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{color:`#00AF66`},k(_)))):l.default.createElement(l.default.Fragment,null,s.filter(e=>e.isSubagent&&!e.content.startsWith(`TOOL_START:`)&&e.role!==`system`||e.content.startsWith(`TOOL:`)).slice(-2).map((e,t)=>{let n=e.role===`system`&&e.content.startsWith(`TOOL:`),r=e.content;if(n){let t=e.content.split(`|||`),n=t[0].replace(`TOOL:`,``),i=t[1]||``;r=`🔧 ${n}: ${i.slice(0,100)}${i.length>100?`...`:``}`}let i=r.split(`
|
|
17
|
+
`,`Welcome to `,t,` mode! What would you like to do?`)),l.default.createElement(c.Box,{flexDirection:`column`,marginBottom:1},(()=>{let e=s.findIndex(e=>e.isSubagent),t=s.map((e,t)=>e.isSubagent?t:-1).reduce((e,t)=>Math.max(e,t),-1),n=e===-1?s:s.slice(0,e),r=t===-1?[]:s.slice(t+1),i=(e,t,n)=>{let r=e.role===`system`&&e.content.startsWith(`TOOL:`),i=e.role===`system`&&e.content.startsWith(`TOOL_START:`),a=e.role===`user`?`white`:e.role===`assistant`||r||i?`#00AF66`:`gray`,o=e.role===`user`?`❯ You`:e.role===`assistant`?`◆ StackOne Agent`:`ℹ System`,s=e.content,d=!1,f=!1;if(i&&(o=`🔧 Tool • ${e.content.split(`|||`)[1]||``}`,s=``,f=!h),r){let t=e.content.split(`|||`),n=t[0].replace(`TOOL:`,``),r=t[1]||``;o=`🔧 Tool • ${n}`,!ue&&r.length>500?(s=r.slice(0,500),d=!0):s=r}return l.default.createElement(c.Box,{key:`${n}-${e.timestamp.getTime()}-${t}-${e.role}`,marginBottom:1,flexDirection:`column`},l.default.createElement(c.Box,null,f&&l.default.createElement(c.Text,{color:a},l.default.createElement(u.default,{type:`dots`})),l.default.createElement(c.Text,{bold:!0,color:a},f?` `:``,o,l.default.createElement(c.Text,{dimColor:!0},` `,`• `,e.timestamp.toLocaleTimeString()))),s&&l.default.createElement(c.Box,{paddingLeft:2,flexDirection:`column`},l.default.createElement(c.Text,{color:r?`gray`:void 0,italic:r},k(s)),d&&l.default.createElement(c.Text,{dimColor:!0,italic:!0},`... (truncated, press Ctrl+O to expand)`)))};return l.default.createElement(l.default.Fragment,null,n.map((e,t)=>i(e,t,`before`)),(w||E)&&l.default.createElement(c.Box,{marginBottom:0,marginTop:0,borderStyle:`single`,borderColor:`#00AF66`,paddingX:2,paddingY:1,flexDirection:`column`,height:X?`100%`:void 0},l.default.createElement(c.Text,{bold:!0,color:`#00AF66`},E?`✓`:`⚡`,` Subprocess:`,` `,T,` `,E?`(Complete)`:``,` `,X?`(Expanded)`:``),l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{dimColor:!0},E?X?`Press Ctrl+O or ESC to collapse`:`Press Ctrl+O to expand`:X?`Running... Press Ctrl+O or ESC to collapse`:`Running... Press Ctrl+O to expand`)),X?l.default.createElement(l.default.Fragment,null,s.filter(e=>e.isSubagent&&!e.content.startsWith(`TOOL_START:`)).map((e,t)=>{let n=e.role===`system`&&e.content.startsWith(`TOOL:`),r=e.role===`assistant`?`⚡ Subagent`:`ℹ System`,i=e.content;if(n){let t=e.content.split(`|||`),n=t[0].replace(`TOOL:`,``),a=t[1]||``;r=`🔧 Tool • ${n}`,i=a.slice(0,500),a.length>500&&(i+=`
|
|
18
|
+
... (truncated)`)}return l.default.createElement(c.Box,{key:`${e.timestamp.getTime()}-${t}-${e.role}-subagent`,marginTop:1,flexDirection:`column`},l.default.createElement(c.Text,{bold:!0,color:`#00AF66`},r,l.default.createElement(c.Text,{dimColor:!0},` `,`•`,` `,e.timestamp.toLocaleTimeString())),l.default.createElement(c.Box,{paddingLeft:2},l.default.createElement(c.Text,{color:n?`gray`:`#00AF66`,dimColor:n},k(i))))}),!E&&!h&&f&&d.length===0&&l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{color:`#00AF66`},l.default.createElement(u.default,{type:`dots`})),l.default.createElement(c.Text,{dimColor:!0},` Thinking...`)),!E&&!h&&d.length>0&&l.default.createElement(c.Box,{flexDirection:`column`,marginTop:1},d.map((e,t)=>l.default.createElement(c.Box,{key:t,marginBottom:1},e.status===`running`&&l.default.createElement(c.Text,{color:`#00AF66`},l.default.createElement(u.default,{type:`dots`})),l.default.createElement(c.Text,{color:`#00AF66`},` `,`🔧 `,e.name,e.status===`running`&&`...`,e.status===`completed`&&` ✓`)))),!E&&_&&!h&&l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{color:`#00AF66`},k(_)))):l.default.createElement(l.default.Fragment,null,s.filter(e=>e.isSubagent&&!e.content.startsWith(`TOOL_START:`)&&e.role!==`system`||e.content.startsWith(`TOOL:`)).slice(-2).map((e,t)=>{let n=e.role===`system`&&e.content.startsWith(`TOOL:`),r=e.content;if(n){let t=e.content.split(`|||`),n=t[0].replace(`TOOL:`,``),i=t[1]||``;r=`🔧 ${n}: ${i.slice(0,100)}${i.length>100?`...`:``}`}let i=r.split(`
|
|
13
19
|
`).slice(0,2).join(`
|
|
14
20
|
`);return l.default.createElement(c.Box,{key:t,marginTop:1},l.default.createElement(c.Text,{color:`#00AF66`,dimColor:n},k(i),r.split(`
|
|
15
21
|
`).length>2&&`...`))}),!E&&!h&&f&&d.length===0&&l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{color:`#00AF66`},l.default.createElement(u.default,{type:`dots`})),l.default.createElement(c.Text,{dimColor:!0},` Thinking...`)),!E&&!h&&d.length>0&&l.default.createElement(c.Box,{flexDirection:`column`,marginTop:1},d.slice(-2).map((e,t)=>l.default.createElement(c.Box,{key:t,marginBottom:1},e.status===`running`&&l.default.createElement(c.Text,{color:`#00AF66`},l.default.createElement(u.default,{type:`dots`})),l.default.createElement(c.Text,{color:`#00AF66`},` `,`🔧 `,e.name,e.status===`running`&&`...`,e.status===`completed`&&` ✓`))),d.length>2&&l.default.createElement(c.Text,{dimColor:!0},`... and`,` `,d.length-2,` more (Ctrl+O to expand)`)),!E&&_&&l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{color:`#00AF66`},k(_).split(`
|
|
16
22
|
`).slice(0,2).join(`
|
|
17
23
|
`),k(_).split(`
|
|
18
24
|
`).length>2&&`
|
|
19
|
-
...`)))),r.map((e,t)=>i(e,t,`after`)))})(),_&&!w&&l.default.createElement(c.Box,{marginBottom:1,flexDirection:`column`},l.default.createElement(c.Text,{bold:!0,color:`#00AF66`},`◆ StackOne Agent`,l.default.createElement(c.Text,{dimColor:!0},` • `,new Date().toLocaleTimeString())),l.default.createElement(c.Box,{paddingLeft:2},l.default.createElement(c.Text,null,k(_))))),!w&&!h&&d.length>0&&l.default.createElement(c.Box,{marginBottom:1},l.default.createElement(c.Text,{dimColor:!0},`🔧`,` `,d.length>1?`${d.length} tools running`:Array.from(d.values())[0].name,`...`)),!w&&!h&&f&&d.length===0&&l.default.createElement(c.Box,{marginBottom:1},l.default.createElement(c.Text,{color:`#00AF66`},l.default.createElement(u.default,{type:`dots`})),l.default.createElement(c.Text,{dimColor:!0},` Thinking...`)),h&&l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{color:`red`},`⏺ Interrupted · What should the StackOne Agent do instead?`)),m&&l.default.createElement(c.Box,{marginBottom:1,borderStyle:`single`,borderColor:`red`,paddingX:2,paddingY:1,flexDirection:`column`},l.default.createElement(c.Text,{color:`red`},`✗ `,m),l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{dimColor:!0},`Press Enter to try again or Ctrl+C to exit`))),p&&l.default.createElement(c.Box,{marginBottom:1,borderStyle:`single`,borderColor:`#00AF66`,paddingX:2},l.default.createElement(c.Text,{color:`#00AF66`},`✓ Complete`)),y&&l.default.createElement(c.Box,{marginBottom:1,borderStyle:`single`,borderColor:`#00AF66`,paddingX:2,paddingY:1,flexDirection:`column`},
|
|
20
|
-
`).
|
|
21
|
-
`)
|
|
25
|
+
...`)))),r.map((e,t)=>i(e,t,`after`)))})(),_&&!w&&!h&&l.default.createElement(c.Box,{marginBottom:1,flexDirection:`column`},l.default.createElement(c.Text,{bold:!0,color:`#00AF66`},`◆ StackOne Agent`,l.default.createElement(c.Text,{dimColor:!0},` • `,new Date().toLocaleTimeString())),l.default.createElement(c.Box,{paddingLeft:2},l.default.createElement(c.Text,null,k(_))))),!w&&!h&&d.length>0&&l.default.createElement(c.Box,{marginBottom:1},l.default.createElement(c.Text,{dimColor:!0},`🔧`,` `,d.length>1?`${d.length} tools running`:Array.from(d.values())[0].name,`...`)),!w&&!h&&f&&d.length===0&&l.default.createElement(c.Box,{marginBottom:1},l.default.createElement(c.Text,{color:`#00AF66`},l.default.createElement(u.default,{type:`dots`})),l.default.createElement(c.Text,{dimColor:!0},` Thinking...`)),h&&l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{color:`red`},`⏺ Interrupted · What should the StackOne Agent do instead?`)),m&&l.default.createElement(c.Box,{marginBottom:1,borderStyle:`single`,borderColor:`red`,paddingX:2,paddingY:1,flexDirection:`column`},l.default.createElement(c.Text,{color:`red`},`✗ `,m),l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{dimColor:!0},`Press Enter to try again or Ctrl+C to exit`))),p&&l.default.createElement(c.Box,{marginBottom:1,borderStyle:`single`,borderColor:`#00AF66`,paddingX:2},l.default.createElement(c.Text,{color:`#00AF66`},`✓ Complete`)),y&&l.default.createElement(c.Box,{marginBottom:1,borderStyle:`single`,borderColor:`#00AF66`,paddingX:2,paddingY:1,flexDirection:`column`},q?l.default.createElement(l.default.Fragment,null,l.default.createElement(c.Text,{bold:!0,color:`#00AF66`},y.items[K].name),l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{dimColor:!0},y.items[K].description)),y.type===`skills`&&l.default.createElement(c.Box,{flexDirection:`column`},y.items[K].version?l.default.createElement(c.Text,{dimColor:!0},`Version:`,` `,String(y.items[K].version)):null,y.items[K].author?l.default.createElement(c.Text,{dimColor:!0},`Author:`,` `,String(y.items[K].author)):null,y.items[K].tags&&Array.isArray(y.items[K].tags)?l.default.createElement(c.Text,{dimColor:!0},`Tags:`,` `,y.items[K].tags.join(`, `)):null,l.default.createElement(c.Text,{dimColor:!0},`Size:`,` `,String(y.items[K].size)),y.items[K].tokens?l.default.createElement(c.Text,{dimColor:!0},`Tokens: ~`,y.items[K].tokens.toLocaleString()):null,l.default.createElement(c.Text,{dimColor:!0},`Resources:`,` `,String(y.items[K].resources),` `,`files`),l.default.createElement(c.Text,{dimColor:!0},`Path:`,` `,String(y.items[K].path))),y.type===`tools`&&l.default.createElement(c.Box,{flexDirection:`column`},l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{dimColor:!0},`Category:`,` `,String(y.items[K].category))),l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{bold:!0},`Input Parameters:`)),y.items[K].inputSchema?l.default.createElement(c.Box,{marginTop:1,paddingLeft:2,flexDirection:`column`},(()=>{let e=y.items[K].inputSchema,t=e.properties||{},n=e.required||[];return Object.entries(t).map(([e,t])=>l.default.createElement(c.Box,{key:e,flexDirection:`column`,marginBottom:1},l.default.createElement(c.Text,null,e,n.includes(e)?` *`:``,l.default.createElement(c.Text,{dimColor:!0},` `,`(`,t.type?String(t.type):`any`,`)`)),t.description?l.default.createElement(c.Box,{paddingLeft:2},l.default.createElement(c.Text,{dimColor:!0},String(t.description))):null))})(),l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{dimColor:!0},`* = required parameter`))):l.default.createElement(c.Box,{marginTop:1,paddingLeft:2},l.default.createElement(c.Text,{dimColor:!0},`No parameters`)),l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{bold:!0},`Output:`)),l.default.createElement(c.Box,{marginTop:1,paddingLeft:2},l.default.createElement(c.Text,{dimColor:!0},`Returns JSON with tool execution results`))),l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{dimColor:!0},`Press Esc to go back`))):l.default.createElement(l.default.Fragment,null,l.default.createElement(c.Text,{bold:!0,color:`#00AF66`},y.type===`skills`?`📚 Skills (${y.items.filter(e=>e.enabled).length}/8 connected, max 8 skills)`:y.type===`tools`?`🔧 Tools (${y.items.length})`:y.type===`mcp`?`📡 MCP Servers (${y.items.filter(e=>e.connected).length}/${y.items.length} connected)`:y.type===`rewind`?`⏮️ Command History (${y.items.length})`:`💬 Recent Conversations (${y.items.length})`),l.default.createElement(c.Box,{flexDirection:`column`,marginTop:1},y.items.map((e,t)=>{let n=t===K?`❯ `:` `,r=process.stdout.columns||80,i=Math.min(r-10,120),a=(e.name||``).replace(/\n/g,` ⏎ `),o=``;y.type===`skills`?o=e.enabled?`● `:`○ `:y.type===`mcp`&&(o=e.connected?`● `:`○ `);let s=y.type===`skills`&&e.tokens?` (~${e.tokens.toLocaleString()} tokens)`:``,u=i-(n.length+o.length+a.length+s.length)-5,d=``;if(e.description&&u>10){let t=String(e.description).replace(/\n/g,` ⏎ `);d=t.length>u?` - ${t.slice(0,u)}...`:` - ${t}`}let f=`${n}${o}${a}${s}${d}`,p=f.slice(0,i);return l.default.createElement(c.Text,{key:t,color:t===K?`#00AF66`:`gray`},p,f.length>i?`...`:``)})),l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{dimColor:!0},y.type===`skills`?`↑↓ Navigate • Ctrl+O to toggle • Enter for details • Esc to close`:y.type===`resume`?`↑↓ Navigate • Enter to resume • Esc to close`:y.type===`rewind`?`↑↓ Navigate • Enter to rewind to • Esc to close`:`↑↓ Navigate • Enter for details • Esc to close`)))),D.length>0&&l.default.createElement(c.Box,{flexDirection:`column`,marginBottom:1},D.map((e,t)=>l.default.createElement(c.Box,{key:t,marginBottom:t<D.length-1?1:0},l.default.createElement(c.Text,{dimColor:!0},`📬 `),l.default.createElement(c.Text,null,e.content))),O&&l.default.createElement(c.Text,{dimColor:!0,italic:!0},`Processing...`)),F&&!p&&!y&&l.default.createElement(l.default.Fragment,null,l.default.createElement(c.Box,{borderStyle:`double`,borderColor:`white`,paddingX:2,flexDirection:`column`},(()=>{let e=j.split(`
|
|
26
|
+
`),t=0;return e.map((n,r)=>{let i=t,a=i+n.length;t=a+1;let o=N>=i&&N<=a,s=N===a&&r<e.length-1;if(o||s){let e=N-i,t=n.slice(0,e),a=s?` `:n.charAt(e)||` `,o=s?``:n.slice(e+1);return l.default.createElement(c.Box,{key:r},r===0&&l.default.createElement(c.Text,{color:`#00AF66`},`❯ `),l.default.createElement(c.Text,{color:`white`},t),l.default.createElement(c.Text,{backgroundColor:`white`,color:`black`,bold:!0},a),l.default.createElement(c.Text,{color:`white`},o))}else return l.default.createElement(c.Box,{key:r},r===0&&l.default.createElement(c.Text,{color:`#00AF66`},`❯ `),l.default.createElement(c.Text,{color:`white`},n||` `))})})()),J&&l.default.createElement(c.Box,{marginTop:1,paddingLeft:2},l.default.createElement(c.Text,{color:`yellow`},`Press Ctrl+C again to exit`)),W.length>0&&l.default.createElement(c.Box,{marginTop:1,paddingLeft:2,flexDirection:`column`},W.map((e,t)=>l.default.createElement(c.Box,{key:e},l.default.createElement(c.Text,{color:t===G?`#00AF66`:`gray`},t===G?`❯ `:` `,e))))),v&&(()=>{let e=100-(v.input_tokens+v.output_tokens)/1e6*100,t=e>50?`green`:e>20?`yellow`:`red`,n=e<10;return l.default.createElement(c.Box,{marginTop:1,flexDirection:`column`},l.default.createElement(c.Text,{dimColor:!0},`📊 Model: Sonnet 4.5 • 🧠 Context left:`,` `,l.default.createElement(c.Text,{color:t},e.toFixed(1),`%`)),n&&l.default.createElement(c.Text,{color:`red`},`⚠️ Context low (`,e.toFixed(1),`% remaining)`))})(),l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{dimColor:!0},F?`Type message and press Enter • Shift+Enter for new line • `:``,(f||_||d.length>0)&&`ESC to stop • `,w?`Ctrl+O to expand subprocess • `:`Ctrl+O to expand tool outputs • `,`↑↓ to scroll • Ctrl+C to clear/exit`)))},te=({directory:e,onConfirm:t,onCancel:n})=>{let{exit:r}=(0,c.useApp)(),[i,a]=(0,l.useState)(0);(0,c.useInput)((e,o)=>{o.upArrow?a(0):o.downArrow?a(1):o.return?i===0?(t(),r()):(n(),r()):o.escape&&(n(),r())});let o=`\x1B[38;2;0;175;102m`;return l.default.createElement(c.Box,{flexDirection:`column`,padding:2},l.default.createElement(c.Box,{borderStyle:`round`,borderColor:`#00AF66`,flexDirection:`column`,paddingX:2,paddingY:1},l.default.createElement(c.Text,{bold:!0},`Do you trust the files in this folder?`),l.default.createElement(c.Text,null),l.default.createElement(c.Text,{dimColor:!0},e),l.default.createElement(c.Text,null),l.default.createElement(c.Text,null,`StackOne Agent may read, write, or execute files contained in this directory.`),l.default.createElement(c.Text,null,`This can pose security risks, so only use files and commands from trusted sources.`),l.default.createElement(c.Text,null),l.default.createElement(c.Text,{color:i===0?o:`white`},i===0?`❯ `:` `,`1. Yes, proceed`),l.default.createElement(c.Text,{color:i===1?o:`white`},i===1?`❯ `:` `,`2. No, exit`)),l.default.createElement(c.Box,{marginTop:1},l.default.createElement(c.Text,{dimColor:!0},`↑↓ to navigate • Enter to confirm • Esc to exit`)))},A=()=>{try{let e=(0,f.join)((0,f.dirname)((0,p.fileURLToPath)(require(`url`).pathToFileURL(__filename).href)),`..`,`package.json`);return JSON.parse((0,d.readFileSync)(e,`utf8`)).version}catch{return`unknown`}};A();const j=({mode:t,connector:n,action:r,goal:c,verbose:u,temperature:d,apiKey:f})=>{let[p,m]=(0,l.useState)([]),[h,g]=(0,l.useState)(new Map),[_,v]=(0,l.useState)(!1),[y,b]=(0,l.useState)(),[x,S]=(0,l.useState)(!1),[C,w]=(0,l.useState)(!0),[T,E]=(0,l.useState)(),[D,O]=(0,l.useState)([]),[k,te]=(0,l.useState)([]),[A,j]=(0,l.useState)([]),[M,N]=(0,l.useState)([]),[P,F]=(0,l.useState)(``),[I,ne]=(0,l.useState)(),[L,re]=(0,l.useState)(!1),[ie,R]=(0,l.useState)(null),[z,B]=(0,l.useState)(!1),V=(0,l.useRef)(!1),[H,ae]=(0,l.useState)(``),[U,W]=(0,l.useState)(!1),[oe,G]=(0,l.useState)([]),[se,K]=(0,l.useState)(!1),[ce,q]=(0,l.useState)(!1),le=(0,l.useRef)(!1),J=(0,l.useRef)({shouldStop:!1}),[Y,X]=(0,l.useState)([]),Z=(0,l.useRef)(null),[ue,de]=(0,l.useState)({claudeSkills:{count:0,names:[],totalSize:0},mcpServers:[],toolCounts:{total:0,builtin:[],mcpByServer:{}},errors:[]});(0,l.useEffect)(()=>{let t=s.join(o.homedir(),`.stackone`,`agent_history`);try{a.existsSync(t)&&N(a.readFileSync(t,`utf-8`).split(`
|
|
27
|
+
`).filter(e=>e.trim()))}catch(t){u&&e._.error(`[History] Failed to load command history:`,t)}},[u]),(0,l.useEffect)(()=>{(async()=>{let t={claudeSkills:{count:0,names:[],totalSize:0},mcpServers:[],toolCounts:{total:0,builtin:[],mcpByServer:{}},errors:[]};i.skillLoader.registerSkills(i.builtinSkills),i.skillLoader.registerSkills(i.customSkills);try{let e=await(0,i.loadBundledSkills)();j(e);let n=e.map(e=>e.name);O(n),te(n.slice(0,8)),t.claudeSkills={count:e.length,names:n,totalSize:0}}catch(n){e._.error(`[Skills] Failed to load bundled skills:`,n),t.errors.push(`Failed to load Claude Skills`)}try{let{loadBundledMCPConfigs:e,loadMultipleMCPServers:n}=await import(`@stackone/agent-harness`),r=e();if(r.length>0){let e=await n(r);for(let[n,r]of e.entries())r.length>0&&(i.skillLoader.registerSkills(r),t.mcpServers.push({name:n,count:r.length}))}}catch(e){t.errors.push(`MCP: ${e instanceof Error?e.message:String(e)}`)}let n=i.skillLoader.toToolAdapters(),r=n.filter(e=>!e.name.includes(`__`)),a=n.filter(e=>e.name.includes(`__`));t.toolCounts.total=n.length,t.toolCounts.builtin=r.map(e=>e.name),a.length>0&&(t.toolCounts.mcpByServer=a.reduce((e,t)=>{let[n]=t.name.split(`__`);return e[n]||(e[n]=[]),e[n].push(t.name.split(`__`)[1]),e},{})),de(t),E(new i.AgentRuntime({apiKey:f,tools:n,temperature:d,verbose:u||!1,projectName:`stackone-agent-cli-chat`})),w(!1)})()},[f,d,u]),(0,l.useEffect)(()=>{le.current=ce},[ce]),(0,l.useEffect)(()=>{if(I&&!L){let e=I.input_tokens+I.output_tokens,t=(1e6-e)/1e6*100;if(t<10){let n={role:`system`,content:`⚠️ Context Warning\n\nYou have ${t.toFixed(1)}% context remaining (${(1e6-e).toLocaleString()} tokens).\n\nConsider using /compact to summarize the conversation and free up context.`,timestamp:new Date};m(e=>[...e,n]),re(!0)}}},[I,L]);let fe=(0,l.useCallback)(async i=>{try{let e=p.filter(e=>e.role===`user`||e.role===`assistant`);if(e.length<2)return;let c=e.slice(0,6).map(e=>`${e.role}: ${e.content.slice(0,200)}`).join(`
|
|
28
|
+
`),l=await T?.generateConversationTitle(c);if(!l)return;await a.promises.mkdir(s.join(o.homedir(),`.stackone`,`conversations`),{recursive:!0});let u=Date.now(),d=`${u}-${l.replace(/[^a-zA-Z0-9]/g,`-`).toLowerCase().slice(0,50)}.json`,f=s.join(o.homedir(),`.stackone`,`conversations`,d);await a.promises.writeFile(f,JSON.stringify({title:l,timestamp:u,goal:i,messages:p.filter(e=>e.role!==`system`),mode:t,connector:n,action:r},null,2))}catch(t){e._.error(`Failed to save conversation:`,t)}},[p,T,t,n,r]),Q=(0,l.useCallback)(async(c,l=!1)=>{if(!T){b(`Runtime not initialized`);return}if(le.current&&!l){G(e=>[...e,{content:c,timestamp:new Date}]),Z.current&&clearTimeout(Z.current),Z.current=setTimeout(()=>{pe()},3e4);return}if(b(void 0),S(!1),c===`/skills`){if(A.length===0){let e={role:`system`,content:`📚 No skills loaded. Skills will be loaded on startup.`,timestamp:new Date};m(t=>[...t,e]);return}R({type:`skills`,items:A.map(e=>({name:e.name,description:e.description,version:e.version,author:e.author,tags:e.tags,enabled:k.includes(e.name)}))});return}if(c===`/tools`){try{let e=i.skillLoader.toToolAdapters();if(e.length===0){let e={role:`system`,content:`🔧 No tools found
|
|
22
29
|
|
|
23
|
-
Tools are loaded automatically from built-in, custom, and MCP sources.`,timestamp:new Date};m(t=>[...t,e]);return}
|
|
30
|
+
Tools are loaded automatically from built-in, custom, and MCP sources.`,timestamp:new Date};m(t=>[...t,e]);return}R({type:`tools`,items:e.map(e=>({name:e.name,description:e.description||`No description`,category:e.name.includes(`__`)?`MCP (${e.name.split(`__`)[0]})`:[`read_file`,`write_file`,`list_files`,`execute_command`].includes(e.name)?`Built-in`:`Custom`,inputSchema:e.inputSchema||e.input_schema}))})}catch(e){let t={role:`system`,content:`🔧 Error loading tools\n\n${e instanceof Error?e.message:String(e)}`,timestamp:new Date};m(e=>[...e,t])}return}if(c===`/commands`){let e={role:`system`,content:`📋 Available Commands:
|
|
24
31
|
|
|
25
32
|
• /commands - Show this help message
|
|
26
33
|
• /skills - View and toggle skills (max 8)
|
|
@@ -29,13 +36,13 @@ Tools are loaded automatically from built-in, custom, and MCP sources.`,timestam
|
|
|
29
36
|
• /compact - Summarize conversation to free up context
|
|
30
37
|
• /rewind - Remove last message from history
|
|
31
38
|
• /resume - Resume with last command
|
|
32
|
-
• /exit - Exit the agent (or use Ctrl+C)`,timestamp:new Date};m(t=>[...t,e]);return}if(c===`/exit`&&process.exit(0),c===`/mcp`){try{let{loadBundledMCPConfigs:e}=await import(`@stackone/agent-harness`),t=e();if(t.length===0){let e={role:`system`,content:`📡 No bundled MCP servers available`,timestamp:new Date};m(t=>[...t,e]);return}let n=new Set(ue.mcpServers.map(e=>e.name));
|
|
33
|
-
`).filter(e=>e.trim());if(t.length===0){let e={role:`system`,content:`⏮️ Command history is empty.`,timestamp:new Date};m(t=>[...t,e]);return}
|
|
39
|
+
• /exit - Exit the agent (or use Ctrl+C)`,timestamp:new Date};m(t=>[...t,e]);return}if(c===`/exit`&&process.exit(0),c===`/mcp`){try{let{loadBundledMCPConfigs:e}=await import(`@stackone/agent-harness`),t=e();if(t.length===0){let e={role:`system`,content:`📡 No bundled MCP servers available`,timestamp:new Date};m(t=>[...t,e]);return}let n=new Set(ue.mcpServers.map(e=>e.name));R({type:`mcp`,items:t.map(e=>{let t=n.has(e.name),r=ue.toolCounts.mcpByServer[e.name]?.length||0,i=e.type===`http`?e.url:void 0;return{name:e.name,description:`${r} tools${i?` • ${i}`:``}`,connected:t,toolCount:r,url:i}})})}catch(e){let t={role:`system`,content:`❌ Error loading MCP servers: ${e instanceof Error?e.message:String(e)}`,timestamp:new Date};m(e=>[...e,t])}return}if(c===`/rewind`){try{let e=s.join(o.homedir(),`.stackone`,`agent_history`);if(!a.existsSync(e)){let e={role:`system`,content:`⏮️ No command history found.`,timestamp:new Date};m(t=>[...t,e]);return}let t=a.readFileSync(e,`utf-8`).split(`
|
|
40
|
+
`).filter(e=>e.trim());if(t.length===0){let e={role:`system`,content:`⏮️ Command history is empty.`,timestamp:new Date};m(t=>[...t,e]);return}R({type:`rewind`,items:t.reverse().slice(0,10).map((e,n)=>({name:e,description:`${t.length-n} messages ago`,index:t.length-n-1}))})}catch(e){let t={role:`system`,content:`❌ Error loading history: ${e instanceof Error?e.message:String(e)}`,timestamp:new Date};m(e=>[...e,t])}return}if(c===`/resume`){try{let e=s.join(o.homedir(),`.stackone`,`conversations`);if(!a.existsSync(e)){let e={role:`system`,content:`▶️ No conversation history found. Start a new conversation first!`,timestamp:new Date};m(t=>[...t,e]);return}let t=a.readdirSync(e).filter(e=>e.endsWith(`.json`)).sort((e,t)=>{let n=parseInt(e.split(`-`)[0])||0;return(parseInt(t.split(`-`)[0])||0)-n}).slice(0,10);if(t.length===0){let e={role:`system`,content:`▶️ No conversations found.`,timestamp:new Date};m(t=>[...t,e]);return}let n=t.map(t=>{try{let n=a.readFileSync(s.join(e,t),`utf-8`),r=JSON.parse(n);return{file:t,title:r.title||`Untitled conversation`,timestamp:r.timestamp,messages:r.messages,goal:r.goal}}catch{return null}}).filter(Boolean);if(n.length===0){let e={role:`system`,content:`▶️ No valid conversations found.`,timestamp:new Date};m(t=>[...t,e]);return}R({type:`resume`,items:n.map(e=>({name:e?.title,description:new Date(e?.timestamp).toLocaleString(),goal:e?.goal,file:e?.file,messages:e?.messages}))})}catch(e){let t={role:`system`,content:`❌ Error loading conversations: ${e instanceof Error?e.message:String(e)}`,timestamp:new Date};m(e=>[...e,t])}return}if(c.startsWith(`/`)&&![`/`,`/ /commands`,`/skills`,`/tools`,`/mcp`,`/compact`,`/rewind`,`/resume`,`/exit`].includes(c)){let e={role:`system`,content:`❌ Unknown command: ${c}\n\nType /commands to see available commands.`,timestamp:new Date};m(t=>[...t,e]);return}if(c===`/compact`){let e={role:`user`,content:c,timestamp:new Date};m(t=>[...t,e]),v(!0);try{let e=p.filter(e=>e.role===`user`||e.role===`assistant`).map(e=>`${e.role===`user`?`User`:`Assistant`}: ${e.content}`).join(`
|
|
34
41
|
|
|
35
|
-
`),t=await T?.generateConversationSummary(e);v(!1);let n={role:`system`,content:`🗜️ Compact mode activated - conversation summarized:\n\n${t}`,timestamp:new Date};m(e=>[e[e.length-1],n])}catch(e){v(!1),b(e instanceof Error?e.message:`Failed to summarize conversation`)}return}
|
|
36
|
-
`),`utf-8`)}catch(t){u&&e._.error(`[History] Failed to save command history:`,t)}return n});let d={role:`user`,content:c,timestamp:new Date};m(e=>[...e,d]),v(!0),
|
|
42
|
+
`),t=await T?.generateConversationSummary(e);v(!1);let n={role:`system`,content:`🗜️ Compact mode activated - conversation summarized:\n\n${t}`,timestamp:new Date};m(e=>[e[e.length-1],n])}catch(e){v(!1),b(e instanceof Error?e.message:`Failed to summarize conversation`)}return}N(t=>{let n=[...t,c],r=s.join(o.homedir(),`.stackone`,`agent_history`);try{let e=s.dirname(r);a.existsSync(e)||a.mkdirSync(e,{recursive:!0});let t=n.slice(-1e3);a.writeFileSync(r,t.join(`
|
|
43
|
+
`),`utf-8`)}catch(t){u&&e._.error(`[History] Failed to save command history:`,t)}return n});let d={role:`user`,content:c,timestamp:new Date};m(e=>[...e,d]),v(!0),q(!0),J.current.shouldStop=!1;try{let i=p.filter(e=>(e.role===`user`||e.role===`assistant`)&&!e.isSubagent).map(e=>({role:e.role,content:e.content})),a=k.length>0?k.slice(0,8):void 0;k.length>8&&u&&e._.warn(`[Skills] Warning: ${k.length} skills enabled, but Claude API limit is 8. Using first 8 skills.`);let o=await T.executeStream({mode:t,goal:c,connector:n,action:r,conversationHistory:i,skills:a},{onThinking:()=>{J.current.shouldStop||(v(!0),g(new Map),F(``),$())},onToolCall:t=>{if(J.current.shouldStop)return;v(!1),X(e=>e.find(e=>e.id===t.id)?e.map(e=>e.id===t.id?{...e,input:t.input}:e):[...e,{id:t.id,name:t.name,input:t.input,output:void 0}]);let n=t.name===`spawn_subagent`;if(F(r=>{let i=[];if(r){let t={role:`assistant`,content:r,timestamp:new Date,isSubagent:n?!1:V.current};u&&e._.log(`[MSG] Adding pre-tool message: isSubagent=${t.isSubagent}, isSpawnSubagent=${n}, content="${r.slice(0,50)}..."`),i.push(t)}let a={role:`system`,content:`TOOL_START:${t.id}|||${t.name}`,timestamp:new Date,isSubagent:n?!0:V.current};return u&&e._.log(`[MSG] Adding TOOL_START: isSubagent=${a.isSubagent}, tool=${t.name}`),i.push(a),m(e=>[...e,...i]),``}),n&&t.input){let n=t.input;u&&e._.log(`spawn_subagent input:`,JSON.stringify(n,null,2));let r=n.description||n.goal||n.name||`Subagent`;if(typeof r==`string`&&r.length>50){let e=r.split(/[.!?]/)[0];r=e.length>50?e.slice(0,47)+`...`:e}u&&e._.log(`Extracted agent name:`,r),ae(String(r)),V.current=!0,setTimeout(()=>{B(!0)},10)}g(e=>{let n=new Map(e);return n.set(t.id,{name:t.name,status:`running`}),n})},onToolResult:e=>{if(J.current.shouldStop)return;X(t=>t.map(t=>t.id===e.id?{...t,output:e.output}:t)),g(t=>{let n=new Map(t);return n.set(e.id,{name:e.name,status:`completed`}),n});let t=typeof e.output==`string`?e.output:JSON.stringify(e.output,null,2);m(n=>n.map(n=>n.content.startsWith(`TOOL_START:${e.id}|||`)?{...n,content:`TOOL:${e.name}|||${t}`}:n)),setTimeout(()=>{g(t=>{let n=new Map(t);return n.delete(e.id),n})},500)},onToken:e=>{J.current.shouldStop||(F(t=>t+e),$())},onUsage:e=>{J.current.shouldStop||ne(e)},onComplete:async t=>{if(J.current.shouldStop)return;v(!1),g(new Map),X([]);let n=V.current;F(e=>{if(e){let t={role:`assistant`,content:e,timestamp:new Date,isSubagent:n};m(e=>[...e,t])}return``}),n?(u&&e._.log(`[SUBAGENT] Subprocess completed, collecting output...`),V.current=!1,setTimeout(()=>{m(t=>{u&&(e._.log(`[SUBAGENT] Total messages:`,t.length),e._.log(`[SUBAGENT] Messages with isSubagent=true:`,t.filter(e=>e.isSubagent).length));let n=t.filter(t=>{let n=t.isSubagent&&t.role===`assistant`;return n&&u&&e._.log(`[SUBAGENT] Found message:`,t.content.slice(0,50)),n}).map(e=>e.content).join(`
|
|
37
44
|
|
|
38
|
-
`);return u&&e._.log(`[SUBAGENT] Collected output length:`,n.length),n&&n.trim()?setTimeout(()=>{u&&e._.log(`[SUBAGENT] Hiding subprocess UI...`),
|
|
45
|
+
`);return u&&e._.log(`[SUBAGENT] Collected output length:`,n.length),n&&n.trim()?setTimeout(()=>{u&&e._.log(`[SUBAGENT] Hiding subprocess UI...`),W(!1),B(!1),setTimeout(()=>{u&&e._.log(`[SUBAGENT] Sending output to main agent`);try{Q(n,!0)}catch(t){e._.error(`[SUBAGENT] Error submitting to main agent:`,t),q(!1)}},100)},300):(u&&e._.log(`[SUBAGENT] No output found, closing subprocess`),W(!1),B(!1),q(!1)),t})},100)):q(!1),await fe(c)},onError:e=>{v(!1),g(new Map),b(e.message)}});v(!1),g(new Map),q(!1),X([]),o.status===`failed`&&o.error&&b(o.error)}catch(t){v(!1),g(new Map),q(!1),X([]);let n=t instanceof Error?t.message:String(t);n.includes(`403`)||n.includes(`Invalid authentication token`)||n.includes(`authentication`)?b(f?.startsWith(`falcon_key_`)?`Authentication failed. The token in your .env is a Falcon MCP token, which is not authorized for the Claude proxy endpoint.
|
|
39
46
|
|
|
40
47
|
⚠️ Known Issue: The authentication system currently returns MCP-only tokens that don't work with the Claude proxy.
|
|
41
48
|
|
|
@@ -53,16 +60,16 @@ To fix this:
|
|
|
53
60
|
|
|
54
61
|
Original error: ${n}`):n.includes(`API key`)||n.includes(`Invalid API Key`)?(e._.error(`
|
|
55
62
|
❌ Critical error:`,n),e._.error(`Please check your configuration and try again.
|
|
56
|
-
`),process.exit(1)):b(n),
|
|
63
|
+
`),process.exit(1)):b(n),q(!1),v(!1),g(new Map)}},[T,p,c,t,n,r,D,k,I,L,f,z,fe]);(0,l.useEffect)(()=>{!T||C||c&&Q(c)},[T,C,c,t,Q,ue]);let $=()=>{G(e=>(e.length===0||g(e=>(!(e.size>0)&&le.current&&(Z.current&&=(clearTimeout(Z.current),null),setTimeout(()=>pe(),100)),e)),e))},pe=()=>{G(e=>{if(e.length===0)return e;K(!0),F(e=>{if(e){let t={role:`assistant`,content:e,timestamp:new Date,isSubagent:V.current};m(e=>[...e,t])}return``});let t=e.map(e=>({role:`user`,content:e.content,timestamp:new Date}));m(e=>[...e,...t]);let n=e.map(e=>e.content).join(`
|
|
57
64
|
|
|
58
65
|
---
|
|
59
66
|
|
|
60
|
-
`);return
|
|
67
|
+
`);return K(!1),q(!1),X([]),Z.current&&=(clearTimeout(Z.current),null),setTimeout(()=>{Q(n,!0)},100),[]})},me=(0,l.useCallback)(e=>{te(t=>t.includes(e)?t.filter(t=>t!==e):t.length>=8?t:[...t,e])},[]);(0,l.useEffect)(()=>{ie?.type===`skills`&&A.length>0&&R({type:`skills`,items:A.map(e=>({name:e.name,description:e.description,version:e.version,author:e.author,tags:e.tags,enabled:k.includes(e.name)}))})},[k,A,ie?.type]);let he=()=>{},ge=(0,l.useCallback)(()=>{J.current.shouldStop=!0,S(!0),F(e=>{if(e){let t=V.current,n={role:`assistant`,content:e,timestamp:new Date,isSubagent:t};m(e=>[...e,n])}return``}),v(!1),q(!1),le.current=!1,g(new Map),X([]),G([]),K(!1)},[]);return C?l.default.createElement(ee,{title:`Agent ${t.charAt(0).toUpperCase()+t.slice(1)} Mode`,mode:t,connector:n,action:r,messages:[],currentToolCalls:[],isThinking:!1,isComplete:!1,error:void 0,isInterrupted:!1,onSubmit:()=>{},onExit:he,onStop:ge}):l.default.createElement(ee,{title:`Agent ${t.charAt(0).toUpperCase()+t.slice(1)} Mode`,mode:t,connector:n,action:r,messages:p,currentToolCalls:Array.from(h.values()),isThinking:_,isComplete:!1,error:y,isInterrupted:x,onSubmit:Q,onExit:he,onStop:ge,commandHistory:M,streamingText:P,usage:I,detailViewData:ie,onCloseDetailView:()=>R(null),onToggleSkill:me,onRewindTo:e=>{try{let t=s.join(o.homedir(),`.stackone`,`agent_history`),n=a.readFileSync(t,`utf-8`).split(`
|
|
61
68
|
`).filter(e=>e.trim()),r=n.slice(0,e+1);a.writeFileSync(t,r.join(`
|
|
62
|
-
`),`utf-8`);let i={role:`system`,content:`⏮️ Rewound to command: "${n[e]}"`,timestamp:new Date};m(e=>[...e,i])}catch(e){let t={role:`system`,content:`❌ Error rewinding: ${e instanceof Error?e.message:String(e)}`,timestamp:new Date};m(e=>[...e,t])}},onResumeConversation:e=>{m(e.map(e=>({...e,timestamp:new Date(e.timestamp)})))},spawnedSubagentActive:
|
|
69
|
+
`),`utf-8`);let i={role:`system`,content:`⏮️ Rewound to command: "${n[e]}"`,timestamp:new Date};m(e=>[...e,i])}catch(e){let t={role:`system`,content:`❌ Error rewinding: ${e instanceof Error?e.message:String(e)}`,timestamp:new Date};m(e=>[...e,t])}},onResumeConversation:e=>{m(e.map(e=>({...e,timestamp:new Date(e.timestamp)})))},spawnedSubagentActive:z,spawnedSubagentName:H,spawnedSubagentComplete:U,queuedMessages:oe,isProcessingQueue:se,enabledSkills:k,initInfo:ue})};var M=class{async execute(t){if(!process.execArgv.some(e=>e.startsWith(`--max-old-space-size`))){let{spawn:e}=await import(`child_process`);e(process.execPath,[`--max-old-space-size=8192`,...process.argv.slice(1)],{stdio:`inherit`,env:process.env}).on(`exit`,e=>{process.exit(e||0)});return}process.stdout.write(`\x1Bc`);let{getAgentApiKey:r}=await Promise.resolve().then(()=>require(`./agentApiKey-BULbfkYn.cjs`)),{hasOldSetupFiles:i,migrateFromLocalSetup:u,displayMigrationMessage:d}=await Promise.resolve().then(()=>require(`./setupMigration-DFIrvmxq.cjs`));try{let n=process.cwd();i(n)&&d(await u(n));let f=r();process.env.STACKONE_AGENT_TOKEN||(process.env.STACKONE_AGENT_TOKEN=f);let p=s.join(o.homedir(),`.stackone`,`trusted_directories`),m=[];try{a.existsSync(p)&&(m=a.readFileSync(p,`utf-8`).split(`
|
|
63
70
|
`).filter(e=>e.trim()))}catch(t){e._.error(`[Trust] Failed to load trusted directories:`,t)}if(!m.includes(n)){let t=!1,{waitUntilExit:r}=(0,c.render)(l.default.createElement(te,{directory:n,onConfirm:()=>{t=!0;try{let e=s.dirname(p);a.existsSync(e)||a.mkdirSync(e,{recursive:!0}),m.push(n),a.writeFileSync(p,m.join(`
|
|
64
71
|
`),`utf-8`)}catch(t){e._.error(`[Trust] Failed to save trusted directory:`,t)}},onCancel:()=>{t=!1}}));await r(),t||(e._.log(`
|
|
65
|
-
Exiting...`),process.exit(0)),process.stdout.write(`\x1Bc`)}(0,c.render)(l.default.createElement(j,{...t,apiKey:f}))}catch(t){let r=t instanceof Error?t.message:String(t);r.includes(`STACKONE_AGENT_TOKEN`)?(e._.error(`
|
|
72
|
+
Exiting...`),process.exit(0)),process.stdout.write(`\x1Bc`)}(0,c.render)(l.default.createElement(j,{...t,apiKey:f}),{exitOnCtrlC:!1})}catch(t){let r=t instanceof Error?t.message:String(t);r.includes(`STACKONE_AGENT_TOKEN`)?(e._.error(`
|
|
66
73
|
❌ Authentication Required
|
|
67
74
|
`),e._.log(n.default.white(`You need to authenticate before using the agent.
|
|
68
75
|
`)),e._.log(n.default.white(`To get started, run:
|
|
@@ -72,22 +79,22 @@ Exiting...`),process.exit(0)),process.stdout.write(`\x1Bc`)}(0,c.render)(l.defau
|
|
|
72
79
|
`))):(e._.error(`
|
|
73
80
|
❌ Error:`,r),e._.log(n.default.dim(`
|
|
74
81
|
If you continue to see this error, try running:`)),e._.log(n.default.cyan(` stackone agent setup
|
|
75
|
-
`))),process.exit(1)}}};const
|
|
76
|
-
`));let t={configsCleaned:0};try{let r=(0,_.default)(`Removing stored configuration...`).start();await e.t(),r.succeed(`Removed ~/.stackone/agent-config.json`);let i=(0,_.default)(`Removing MCP servers from Claude...`).start(),a=0;try{await
|
|
82
|
+
`))),process.exit(1)}}};const N=(0,g.promisify)(m.exec);async function P(e){try{let t=await(0,h.readFile)(e,`utf-8`),n=JSON.parse(t),r=!1;if(n.mcpServers&&typeof n.mcpServers==`object`){for(let[e,t]of Object.entries(n.mcpServers))if(t&&typeof t==`object`&&`transport`in t){let e=t.transport;if(e&&typeof e==`object`&&`headers`in e){let t=e.headers;if(t&&typeof t==`object`&&`Authorization`in t){let e=t.Authorization;typeof e==`string`&&e.startsWith(`Bearer `)&&!e.includes("${")&&(t.Authorization="Bearer ${STACKONE_AGENT_TOKEN}",r=!0)}}}}return r&&await(0,h.writeFile)(e,JSON.stringify(n,null,2)),r}catch{return!1}}var F=class{async execute(){e._.log(n.default.blue.bold(`🧹 StackOne Agent Cleanup
|
|
83
|
+
`));let t={configsCleaned:0};try{let r=(0,_.default)(`Removing stored configuration...`).start();await e.t(),r.succeed(`Removed ~/.stackone/agent-config.json`);let i=(0,_.default)(`Removing MCP servers from Claude...`).start(),a=0;try{await N(`claude mcp remove ${e.r()} 2>/dev/null`),a++}catch{}try{await N(`claude mcp remove ${e.i()} 2>/dev/null`),a++}catch{}a>0?i.succeed(`Removed ${a} MCP server(s) from Claude`):i.warn(`No MCP servers found in Claude (already removed or not configured)`);let o=(0,_.default)(`Checking for .mcp.json file...`).start(),c=(0,s.join)(process.cwd(),`.mcp.json`);try{await P(c)?(t.configsCleaned=1,o.succeed(`Cleaned .mcp.json (replaced tokens with environment variables)`)):o.info(`.mcp.json already uses environment variables or not found`)}catch{o.info(`.mcp.json not found (already cleaned or not created)`)}e._.success(`Cleanup complete!`),e._.log(n.default.white(`
|
|
77
84
|
What was removed:`)),e._.log(n.default.cyan(` • ~/.stackone/agent-config.json`)),e._.log(n.default.cyan(` • MCP server from Claude configuration`)),t.configsCleaned>0&&e._.log(n.default.cyan(` • Hardcoded credentials from .mcp.json`)),e._.log(n.default.dim(`
|
|
78
|
-
To authenticate again:`)),e._.log(n.default.cyan(` stackone agent setup --global`),n.default.dim(`(for global setup)`)),e._.log(n.default.cyan(` stackone agent setup --local`),n.default.dim(`(for local project setup)`)),e._.log(``),process.exit(0)}catch(t){t instanceof Error?e._.error(t.message):e._.error(`Unknown error occurred`),process.exit(1)}}},
|
|
85
|
+
To authenticate again:`)),e._.log(n.default.cyan(` stackone agent setup --global`),n.default.dim(`(for global setup)`)),e._.log(n.default.cyan(` stackone agent setup --local`),n.default.dim(`(for local project setup)`)),e._.log(``),process.exit(0)}catch(t){t instanceof Error?e._.error(t.message):e._.error(`Unknown error occurred`),process.exit(1)}}},I=class{constructor(e){this.baseUrl=e||process.env.AUTH_SERVER_URL||`https://idp-api.stackone.com`}async login(e,t){try{let n=`${this.baseUrl}/auth/sign-in/mcp`,r=await fetch(n,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({email:e,password:t})});if(!r.ok){let e=await r.text(),t={};try{t=JSON.parse(e)}catch{}return{success:!1,error:t.error||`HTTP ${r.status}: ${r.statusText}`}}let i=await r.text(),a=JSON.parse(i);return a.apiKey?{success:!0,apiKey:a.apiKey}:{success:!1,error:`Invalid response format`}}catch(e){return{success:!1,error:e instanceof Error?e.message:`Network error occurred`}}}async validateKey(e){try{let t=`${this.baseUrl}/api-key/verify`,n=await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({key:e})});if(!n.ok){let e=await n.text(),t={};try{t=JSON.parse(e)}catch{}return{valid:!1,error:t.error||`HTTP ${n.status}: ${n.statusText}`}}let r=await n.text();return JSON.parse(r)}catch(e){return{valid:!1,error:e instanceof Error?e.message:`Network error occurred`}}}};const ne=new I,L=(0,g.promisify)(m.exec);function re(e){let t=new Date(e),n=new Date,r=t.getTime()-n.getTime(),i=Math.floor(r/(3600*1e3)),a=t.toLocaleTimeString(`en-US`,{hour:`numeric`,minute:`2-digit`,hour12:!0});return`${t.toDateString()===n.toDateString()?`Today`:t.toDateString()===new Date(n.getTime()+864e5).toDateString()?`Tomorrow`:t.toLocaleDateString(`en-US`,{month:`short`,day:`numeric`})} at ${a} (${i} hours from now)`}var ie=class{async execute(){e._.log(n.default.blue.bold(`🤖 StackOne Agent Setup - Global Configuration
|
|
79
86
|
`));try{let t=process.cwd(),r=await(0,h.access)(`${t}/CLAUDE.md`).then(()=>!0).catch(()=>!1),i=await(0,h.access)(`${t}/.mcp.json`).then(()=>!0).catch(()=>!1);if(r||i){e._.warn(`Existing local setup detected:`),r&&e._.log(n.default.dim(` • CLAUDE.md found in current directory`)),i&&e._.log(n.default.dim(` • .mcp.json found in current directory`)),e._.log(``);let{proceed:t}=await b.default.prompt([{type:`confirm`,name:`proceed`,message:`Re-authenticate globally despite existing local setup?`,default:!0}]);t||(e._.log(n.default.dim(`
|
|
80
|
-
Setup cancelled.`)),process.exit(0)),e._.log(``)}let a=await e.o(),o;if(a?.email){e._.log(n.default.dim(`Last used email: ${a.email}\n`));let{useExisting:t}=await b.default.prompt([{type:`confirm`,name:`useExisting`,message:`Sign in with this email?`,default:!0}]);if(t)o=a.email;else{let t=(0,y.createInterface)({input:v.stdin,output:v.stdout});o=await new Promise(e=>{t.question(n.default.white(`Email: `),t=>{e(t.trim())})}),t.close(),o||(e._.error(`Email is required`),process.exit(1))}}else{let t=(0,y.createInterface)({input:v.stdin,output:v.stdout});o=await new Promise(e=>{t.question(n.default.white(`Email: `),t=>{e(t.trim())})}),t.close(),o||(e._.error(`Email is required`),process.exit(1))}let s=await b.default.prompt([{type:`password`,name:`password`,message:`Password:`,mask:`*`}]);s.password||(e._.error(`Password is required`),process.exit(1)),e._.log(``);let c=(0,_.default)(`Authenticating...`).start(),l=await
|
|
81
|
-
`)),process.exit(1)),c.succeed(`Login successful!`);let u=new Date(Date.now()+1440*60*1e3).toISOString();await e.c({apiKey:l.apiKey,userId:o,email:o,expiresAt:u,serverUrl:e.n()}),e._.success(`API key saved to ~/.stackone/agent-config.json`),e._.log(n.default.white(`✓ Key expires at`),n.default.cyan(
|
|
87
|
+
Setup cancelled.`)),process.exit(0)),e._.log(``)}let a=await e.o(),o;if(a?.email){e._.log(n.default.dim(`Last used email: ${a.email}\n`));let{useExisting:t}=await b.default.prompt([{type:`confirm`,name:`useExisting`,message:`Sign in with this email?`,default:!0}]);if(t)o=a.email;else{let t=(0,y.createInterface)({input:v.stdin,output:v.stdout});o=await new Promise(e=>{t.question(n.default.white(`Email: `),t=>{e(t.trim())})}),t.close(),o||(e._.error(`Email is required`),process.exit(1))}}else{let t=(0,y.createInterface)({input:v.stdin,output:v.stdout});o=await new Promise(e=>{t.question(n.default.white(`Email: `),t=>{e(t.trim())})}),t.close(),o||(e._.error(`Email is required`),process.exit(1))}let s=await b.default.prompt([{type:`password`,name:`password`,message:`Password:`,mask:`*`}]);s.password||(e._.error(`Password is required`),process.exit(1)),e._.log(``);let c=(0,_.default)(`Authenticating...`).start(),l=await ne.login(o,s.password);(!l.success||!l.apiKey)&&(c.fail(`Authentication failed`),e._.error(`${l.error||`Invalid credentials`}`),e._.log(n.default.dim(`Please check your email and password and try again.
|
|
88
|
+
`)),process.exit(1)),c.succeed(`Login successful!`);let u=new Date(Date.now()+1440*60*1e3).toISOString();await e.c({apiKey:l.apiKey,userId:o,email:o,expiresAt:u,serverUrl:e.n()}),e._.success(`API key saved to ~/.stackone/agent-config.json`),e._.log(n.default.white(`✓ Key expires at`),n.default.cyan(re(u)));let d=(0,_.default)(`Setting up global MCP configuration...`).start();try{let t=e.r(),r=e.n();try{await L(`claude mcp remove ${t} 2>/dev/null`)}catch{}await L(`claude mcp add ${t} ${r} --scope user --transport http --header "Authorization: Bearer ${l.apiKey}"`),d.succeed(`Installed to Claude (global)`),e._.success(`Global setup complete!`),e._.log(n.default.white(`Config location:`),n.default.cyan(`~/.claude.json`)),e._.log(n.default.blue(`
|
|
82
89
|
Verify:`),n.default.cyan(`claude mcp list`)),e._.log(n.default.dim(`
|
|
83
90
|
💡 Tip: Run Claude without permission prompts:`),n.default.cyan(`claude --dangerously-skip-permissions`)),e._.log(n.default.dim(`
|
|
84
|
-
To setup for a specific project, run:`),n.default.cyan(`stackone agent setup --local`)),e._.log(``)}catch(t){d.fail(`Installation to Claude failed`),t instanceof Error&&(e._.error(t.message),e._.log(n.default.dim(`You can manually add the server later with:`)),e._.log(n.default.cyan(` claude mcp add ${e.r()} ${e.n()} --scope user --transport http --header "Authorization: Bearer ${l.apiKey}"`)))}process.exit(0)}catch(t){t instanceof Error?e._.error(t.message):e._.error(`Unknown error occurred`),process.exit(1)}}},
|
|
91
|
+
To setup for a specific project, run:`),n.default.cyan(`stackone agent setup --local`)),e._.log(``)}catch(t){d.fail(`Installation to Claude failed`),t instanceof Error&&(e._.error(t.message),e._.log(n.default.dim(`You can manually add the server later with:`)),e._.log(n.default.cyan(` claude mcp add ${e.r()} ${e.n()} --scope user --transport http --header "Authorization: Bearer ${l.apiKey}"`)))}process.exit(0)}catch(t){t instanceof Error?e._.error(t.message):e._.error(`Unknown error occurred`),process.exit(1)}}},R=class{async execute(){e._.log(n.default.blue.bold(`🤖 StackOne Agent Setup - Local Project
|
|
85
92
|
`));try{let r=process.cwd();t.n(r)&&t.t(await t.r(r));let i=await e.o();if(!i||!e.a(i)){e._.warn(`Not authenticated globally.`),e._.log(n.default.white(`Let's authenticate now...
|
|
86
|
-
`));let t=(0,y.createInterface)({input:v.stdin,output:v.stdout}),r=await new Promise(e=>{t.question(n.default.white(`Email: `),t=>{e(t.trim())})});t.close(),r||(e._.error(`Email is required`),process.exit(1));let a=await b.default.prompt([{type:`password`,name:`password`,message:`Password:`,mask:`*`}]);a.password||(e._.error(`Password is required`),process.exit(1)),e._.log(``);let o=(0,_.default)(`Authenticating...`).start(),s=await
|
|
93
|
+
`));let t=(0,y.createInterface)({input:v.stdin,output:v.stdout}),r=await new Promise(e=>{t.question(n.default.white(`Email: `),t=>{e(t.trim())})});t.close(),r||(e._.error(`Email is required`),process.exit(1));let a=await b.default.prompt([{type:`password`,name:`password`,message:`Password:`,mask:`*`}]);a.password||(e._.error(`Password is required`),process.exit(1)),e._.log(``);let o=(0,_.default)(`Authenticating...`).start(),s=await ne.login(r,a.password);(!s.success||!s.apiKey)&&(o.fail(`Authentication failed`),e._.error(`${s.error||`Invalid credentials`}`),e._.log(n.default.dim(`Please check your email and password and try again.
|
|
87
94
|
`)),process.exit(1)),o.succeed(`Login successful!`);let c=new Date(Date.now()+1440*60*1e3).toISOString();await e.c({apiKey:s.apiKey,userId:r,email:r,expiresAt:c,serverUrl:e.n()}),i={apiKey:s.apiKey,userId:r,email:r,expiresAt:c,serverUrl:e.n()},e._.log(``)}e._.success(`Setup complete!`),e._.log(n.default.white(`
|
|
88
|
-
Token saved to:`)),e._.log(n.default.cyan(` ~/.stackone/agent-config.json`)),e._.log(``),process.exit(0)}catch(t){t instanceof Error?e._.error(t.message):e._.error(`Unknown error occurred`),process.exit(1)}}};const
|
|
95
|
+
Token saved to:`)),e._.log(n.default.cyan(` ~/.stackone/agent-config.json`)),e._.log(``),process.exit(0)}catch(t){t instanceof Error?e._.error(t.message):e._.error(`Unknown error occurred`),process.exit(1)}}};const z={profiles:{}},B=()=>{let t=e.l.readConfigFile(e.u);if(!t)return z;try{return JSON.parse(t)}catch{return z}},V=e=>B().profiles[e],H=e=>!!B().profiles[e],ae=(t,n)=>{let r=B();r.profiles[t]=n,e.l.writeConfigFile(e.u,JSON.stringify(r,null,2))},U=()=>{let e=B();return Object.keys(e.profiles)},W=`https://api.stackone.com`;var oe=class{async execute({profile:t,connector:r,apiUrl:i,apiKey:a}={}){if(!t&&!a&&(e._.error(`Profile or API key is required`),e._.log(`Please provide a profile using the ${e.g(`--profile`)} option or an API key using the ${e.g(`--api-key`)} option.`),e._.log(`To create a profile, run ${e.g(`stackone init`)}.`),process.exit(1)),t&&a&&(e._.error(`Please provide either a profile or an API key, not both`),process.exit(1)),t&&i&&e._.warn(`Specifying ${e.g(`--api-url`)} with a profile won't have any effect. Using API url from profile.`),t&&!H(t)){e._.error(`Configuration profile ${e.g(t)} not found`),e._.log(`Run ${e.g(`stackone init`)} to create a new configuration profile.\n`);let r=U();r.length>0&&(e._.info(`Available configuration profiles:`),r.forEach(t=>{e._.log(` - ${n.default.blue(t)}`)})),process.exit(1)}let o=t?V(t):{apiUrl:i??W,apiKey:a};o?.apiKey||(e._.error(`API key is missing`),e._.log(`Please provide a valid API key in the profile or via the ${e.g(`--api-key`)} option.`),process.exit(1)),r||(e._.error(`Connector identifier is required in the format provider_key@version.`),process.exit(1));let s=r.split(`@`);(s.length!==2||!s[0]||!s[1])&&(e._.error(`Invalid connector format ${e.h(r)}. Expected format: ${e.g(`provider_key@version`)}`),process.exit(1));let c=o.apiUrl??W,l=await this.dropConnector(r,c,o.apiKey);process.exit(l?0:1)}async dropConnector(t,n,r){let i=(0,_.default)(`🗑️ Dropping connector ${e.g(t)}...`).start();try{let a=Buffer.from(r).toString(`base64`),o=await fetch(`${n}/registry/connectors/${t}`,{method:`DELETE`,headers:{Authorization:`Basic ${a}`}});return i.stop(),o.status===204?(e._.success(`Successfully dropped connector ${e.g(t)} from the registry`),!0):o.status===404?(e._.error(`Connector ${e.g(t)} not found in the registry`),!1):o.status===401||o.status===403?(e._.error(`You do not have permission to drop this connector`),!1):o.status===409?(e._.error(`Connector ${e.g(t)} has associated configs and cannot be dropped`),e._.log(`Please delete all associated integration configurations before dropping the connector.`),!1):(o.ok||await e.m(o,`Failed to drop connector ${e.g(t)} from the registry`),!1)}catch(r){return i.stop(),e._.error(`Failed to drop connector ${e.g(t)} from registry: ${r.message}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid`),!1}}};const G=`https://api.stackone.com`;var se=class{async execute({profile:t,connector:r,accountId:i,format:a,outputFile:o,apiUrl:s,apiKey:c}={}){if(!t&&!c&&(e._.error(`Profile or API key is required`),e._.log(`Please provide a profile using the ${e.g(`--profile`)} option or an API key using the ${e.g(`--api-key`)} option.`),e._.log(`To create a profile, run ${e.g(`stackone init`)}.`),process.exit(1)),t&&c&&(e._.error(`Please provide either a profile or an API key, not both`),process.exit(1)),t&&s&&e._.warn(`Specifying ${e.g(`--api-url`)} with a profile won't have any effect. Using API url from profile.`),t&&!H(t)){e._.error(`Configuration profile ${e.g(t)} not found`),e._.log(`Run ${e.g(`stackone init`)} to create a new configuration profile.\n`);let r=U();r.length>0&&(e._.info(`Available configuration profiles:`),r.forEach(t=>{e._.log(` - ${n.default.blue(t)}`)})),process.exit(1)}let l=t?V(t):{apiUrl:s??G,apiKey:c};l?.apiKey||(e._.error(`API key is missing`),e._.log(`Please provide a valid API key in the profile or via the ${e.g(`--api-key`)} option.`),process.exit(1)),(0,x.isMissing)(r)&&(0,x.isMissing)(i)&&(e._.error(`Either ${e.g(`--connector`)} or ${e.g(`--account-id`)} must be provided`),process.exit(1)),(0,x.notMissing)(r)&&(0,x.notMissing)(i)&&(e._.error(`Please provide either ${e.g(`--connector`)} or ${e.g(`--account-id`)}, not both.`),process.exit(1)),(0,x.notMissing)(a)&&a!==`yaml`&&a!==`json`&&(e._.error(`Format must be either ${e.g(`yaml`)} or ${e.g(`json`)}.`),process.exit(1));let u=l.apiUrl??G,f;if((0,x.notMissing)(r)){this.#t(r)||(e._.error(`Invalid connector format ${e.h(r)}. Expected format: ${e.g(`provider_key@version`)} or ${e.g(`provider_key`)}`),process.exit(1));let t=this.#n(r);f=await this.#r(t,u,l.apiKey,a)}else (0,x.notMissing)(i)?f=await this.#i(i,u,l.apiKey,a):(e._.error(`Either ${e.g(`--connector`)} or ${e.g(`--account-id`)} must be provided`),process.exit(1));if((0,x.notMissing)(o))try{d.default.writeFileSync(o,f,`utf-8`),e._.success(`Connector written to file: ${e.g(o)}`)}catch(t){e._.error(`Failed to write connector to file ${e.g(o)}: ${t.message}`),process.exit(1)}else if(e._.log(`\n${n.default.blue.inverse(` CONNECTOR CONTENT `)}\n`),!a||a===`yaml`)e._.log(this.#e(f));else if(a===`json`)try{e.p(JSON.parse(f))}catch{e._.log(f)}else e._.log(f);process.exit(0)}#e(e){return e.split(`
|
|
89
96
|
`).map(e=>{if(e.trim().startsWith(`#`))return n.default.gray(e);if(e.includes(`:`)){let t=e.indexOf(`:`),r=e.substring(0,t+1),i=e.substring(t+1),a=i,o=i.trim();return o===`true`||o===`false`?a=i.replace(o,n.default.cyan(o)):o===`null`||o===`~`?a=i.replace(o,n.default.gray(o)):/^-?\d+(\.\d+)?$/.test(o)?a=i.replace(o,n.default.green(o)):(o.startsWith(`"`)&&o.endsWith(`"`)||o.startsWith(`'`)&&o.endsWith(`'`)||o&&!o.startsWith(`-`))&&(a=i.replace(o,n.default.yellow(o))),n.default.red(r)+a}return e.trim().startsWith(`-`)?e.replace(`-`,n.default.gray(`-`)):e}).join(`
|
|
90
|
-
`)}#t=e=>!e.includes(`/`)&&!e.includes(`\\`)&&!e.endsWith(`.yaml`)&&!e.endsWith(`.yml`)?e.includes(`@`)?e.split(`@`).length===2:!0:!1;#n=e=>e.includes(`@`)?e:`${e}@latest`;async#r(t,n,r,i){let a=(0,_.default)(`Getting connector ${e.g(t)} from registry...`).start();try{let o=Buffer.from(r).toString(`base64`),s=i?`?format=${i}`:``,c=await fetch(`${n}/registry/connectors/${t}${s}`,{method:`GET`,headers:{Authorization:`Basic ${o}`}});return a.stop(),c.ok||(await e.m(c,`Failed to get connector ${e.g(t)} from the registry`),process.exit(1)),await c.text()}catch(r){a.stop(),e._.error(`Failed to get connector ${e.g(t)} from the registry: ${r.message}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid`),process.exit(1)}}async#i(t,n,r,i){let a=(0,_.default)(`Getting connector from account ${e.g(t)}...`).start();try{let o=Buffer.from(r).toString(`base64`),s=i?`?format=${i}`:``,c=await fetch(`${n}/accounts/${t}/connector${s}`,{method:`GET`,headers:{Authorization:`Basic ${o}`}});return a.stop(),c.ok||(await e.m(c,`Failed to get connector from account ${e.g(t)}`),process.exit(1)),await c.text()}catch(r){a.stop(),e._.error(`Failed to get connector from account ${e.g(t)}: ${r.message}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid`),process.exit(1)}}};const
|
|
97
|
+
`)}#t=e=>!e.includes(`/`)&&!e.includes(`\\`)&&!e.endsWith(`.yaml`)&&!e.endsWith(`.yml`)?e.includes(`@`)?e.split(`@`).length===2:!0:!1;#n=e=>e.includes(`@`)?e:`${e}@latest`;async#r(t,n,r,i){let a=(0,_.default)(`Getting connector ${e.g(t)} from registry...`).start();try{let o=Buffer.from(r).toString(`base64`),s=i?`?format=${i}`:``,c=await fetch(`${n}/registry/connectors/${t}${s}`,{method:`GET`,headers:{Authorization:`Basic ${o}`}});return a.stop(),c.ok||(await e.m(c,`Failed to get connector ${e.g(t)} from the registry`),process.exit(1)),await c.text()}catch(r){a.stop(),e._.error(`Failed to get connector ${e.g(t)} from the registry: ${r.message}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid`),process.exit(1)}}async#i(t,n,r,i){let a=(0,_.default)(`Getting connector from account ${e.g(t)}...`).start();try{let o=Buffer.from(r).toString(`base64`),s=i?`?format=${i}`:``,c=await fetch(`${n}/accounts/${t}/connector${s}`,{method:`GET`,headers:{Authorization:`Basic ${o}`}});return a.stop(),c.ok||(await e.m(c,`Failed to get connector from account ${e.g(t)}`),process.exit(1)),await c.text()}catch(r){a.stop(),e._.error(`Failed to get connector from account ${e.g(t)}: ${r.message}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid`),process.exit(1)}}};const K=`https://api.stackone.com`,ce=`https://api.stackone-dev.com`,q=`http://localhost:4000`;var le=class{async execute({environment:t}={}){let r=t?.toLowerCase()??`production`;try{(0,S.intro)(`${n.default.inverse(` Initialize profile `)}`);let t=await(0,S.text)({message:`Profile label`,validate:e=>{if(!e||e.trim().length===0)return`The profile label is required`;if(e.includes(` `))return`The profile label cannot contain spaces`}});if((0,S.isCancel)(t))return(0,S.cancel)(`Configuration profile initialization cancelled`),process.exit(0);if(H(t)){let n=await(0,S.confirm)({message:`Configuration profile with name ${e.g(t)} already exists. Do you want to overwrite it?`});if((0,S.isCancel)(n)||!n)return(0,S.cancel)(`Configuration profile initialization cancelled`),process.exit(0)}let i;if(r===`production`)i=`https://api.stackone.com`;else if(r===`staging`)i=`https://api.stackone-dev.com`;else{let e=await(0,S.text)({message:`API URL`,placeholder:q,initialValue:q,validate:e=>{if(!e||e.trim().length===0)return`API URL is required`;try{new URL(e)}catch{return`Please enter a valid URL`}}});if((0,S.isCancel)(e))return(0,S.cancel)(`Configuration profile initialization cancelled`),process.exit(0);i=e}let a=await(0,S.password)({message:`API Key`,validate:e=>{if(!e||e.trim().length===0)return`API Key is required`}});if((0,S.isCancel)(a))return(0,S.cancel)(`Configuration profile initialization cancelled`),process.exit(0);ae(t,{label:t,environment:r,apiUrl:i,apiKey:a}),(0,S.outro)(`${n.default.green(`✔`)} Configuration profile ${e.g(t)} initialized successfully!`),process.exit(0)}catch(t){t?.isTtyError?e._.error(`Prompt couldn't be rendered in the current environment`):e._.error(`Failed to initialize configuration profile: ${t}`),process.exit(1)}}};const J=20,Y={pending:`○`,acceptRemote:`●`,acceptLocal:`◐`,acceptBoth:`◑`,current:`◉`,arrow:`→`,check:`✓`,cross:`✗`,warning:`⚠`};var X=class{constructor(e,t,n,r){this.conflicts=[],this.currentIndex=0,this.totalConflicts=0,this.currentCleanup=null,this.connectorId=t,this.localVersion=n,this.remoteVersion=r,this.conflicts=e.map(e=>({conflict:e,choice:e.type===`unchanged`?`remote`:`pending`})),this.totalConflicts=e.filter(e=>e.type===`conflict`).length}resetForReResolution(){this.currentIndex=0}async resolve(){return this.totalConflicts===0?{cancelled:!1,states:this.conflicts}:(this.moveToNextConflict(),new Promise(e=>{let t=(0,T.createInterface)({input:process.stdin,output:process.stdout});process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume(),this.render();let n=n=>{let r=n.toString();if(r===``){this.cleanup(t),this.renderCancelled(),e({cancelled:!0,states:this.conflicts});return}if(r===`\x1B`&&n.length===1){this.cleanup(t),this.renderCancelled(),e({cancelled:!0,states:this.conflicts});return}if(r.startsWith(`\x1B[`)){switch(r.slice(2)){case`D`:this.moveToPrevConflict(),this.render();break;case`C`:this.moveToNextConflict(),this.render();break}return}switch(r){case`r`:case`R`:this.setCurrentChoice(`remote`),this.advanceAfterChoice(t);break;case`l`:case`L`:this.setCurrentChoice(`local`),this.advanceAfterChoice(t);break;case`b`:case`B`:this.setCurrentChoice(`both`),this.advanceAfterChoice(t);break;case`\r`:case`
|
|
91
98
|
`:this.allResolved()?(this.cleanup(t),e({cancelled:!1,states:this.conflicts})):(this.moveToNextUnresolved(),this.render());break;case`q`:case`Q`:this.cleanup(t),this.renderCancelled(),e({cancelled:!0,states:this.conflicts});break;case`a`:case`A`:this.acceptAllRemaining(`remote`),this.render();break;case`u`:case`U`:this.setCurrentChoice(`pending`),this.render();break}};process.stdin.on(`data`,n),this.currentCleanup=()=>{process.stdin.removeListener(`data`,n),process.stdin.isTTY&&process.stdin.setRawMode(!1),t.close()}}))}cleanup(e){this.currentCleanup?(this.currentCleanup(),this.currentCleanup=null):(process.stdin.isTTY&&process.stdin.setRawMode(!1),e.close())}advanceAfterChoice(e){this.allResolved()||this.moveToNextUnresolved(),this.render()}render(){e.d();let t=process.stdout.columns||80;this.renderHeader(t),this.renderProgressBar(t),this.renderCurrentConflict(t),this.renderControls(t)}renderHeader(t){let r=this.connectorId,i=`${this.localVersion} ${Y.arrow} ${this.remoteVersion}`,a=Math.max(0,t-17),o=Math.floor(a/2),s=a-o,c=` `.repeat(o)+`CONFLICT RESOLVER`+` `.repeat(s);e._.log(``),e._.log(n.default.bgBlue.white.bold(c)),e._.log(n.default.gray(this.centerText(r,t))),e._.log(n.default.gray(this.centerText(i,t))),e._.log(``)}renderProgressBar(t){let r=this.conflicts.filter(e=>e.conflict.type===`conflict`),i=this.getCurrentConflictIndex(),a=r.map((e,t)=>{let r=t===i,a,o;switch(e.choice){case`remote`:a=r?Y.current:Y.acceptRemote,o=n.default.green;break;case`local`:a=r?Y.current:Y.acceptLocal,o=n.default.yellow;break;case`both`:a=r?Y.current:Y.acceptBoth,o=n.default.cyan;break;default:a=r?Y.current:Y.pending,o=r?n.default.white:n.default.gray}return o(a)}),o=r.filter(e=>e.choice!==`pending`).length,s=` Conflict ${i+1} of ${this.totalConflicts} • ${o}/${this.totalConflicts} resolved `;e._.log(n.default.gray(this.centerText(s,t))),e._.log(this.centerText(a.join(` `),t)),e._.log(``)}renderCurrentConflict(t){let r=this.conflicts[this.currentIndex];if(!r||r.conflict.type!==`conflict`)return;let i=r.conflict;if(e._.log(n.default.gray(`_`.repeat(t))),e._.log(`
|
|
92
99
|
|
|
93
100
|
`),i.local){let t=r.choice===`local`||r.choice===`both`?n.default.yellow.bold(`${Y.check} LOCAL (keeping)`):n.default.red.bold(`${Y.cross} LOCAL (removing)`),a=i.local.split(`
|
|
@@ -101,9 +108,9 @@ Token saved to:`)),e._.log(n.default.cyan(` ~/.stackone/agent-config.json`)),e.
|
|
|
101
108
|
`),l=a.length>20?`\n${n.default.gray(`... and ${a.length-20} more lines`)}`:``;e._.log(`${t}\n\n${c}${l}`)}e._.log(`
|
|
102
109
|
|
|
103
110
|
`),e._.log(n.default.gray(`_`.repeat(t))),e._.log(``)}renderControls(t){let r=[n.default.green(`[R] Accept Remote`),n.default.yellow(`[L] Keep Local`),n.default.cyan(`[B] Keep Both`),n.default.gray(`[U] Undo`)],i=[n.default.gray(`[←/→] Navigate`),n.default.gray(`[A] Accept all remaining`)],a=this.allResolved()?[n.default.green.bold(`[Enter] Apply Changes`),n.default.gray(`[Esc] Cancel`)]:[n.default.gray(`[Enter] Next Unresolved`),n.default.gray(`[Esc] Cancel`)];e._.log(this.centerText(r.join(` `),t)),e._.log(``),e._.log(this.centerText(i.join(` `),t)),e._.log(``),e._.log(this.centerText(a.join(` `),t)),this.allResolved()&&(e._.log(``),e._.log(n.default.green.bold(this.centerText(`✓ All conflicts resolved!`,t))))}renderFinalSummary(){e.d();let t=this.conflicts.filter(e=>e.conflict.type===`conflict`),r=0,i=0,a=0;for(let e of t)switch(e.choice){case`remote`:r++;break;case`local`:i++;break;case`both`:a++;break}let o=[n.default.green.bold(`Conflict resolution complete`),``,`${n.default.bold(this.totalConflicts)} conflicts resolved:`,``,`${n.default.green(Y.acceptRemote)} Accepted remote: ${r}`,`${n.default.yellow(Y.acceptLocal)} Kept local: ${i}`,`${n.default.cyan(Y.acceptBoth)} Kept both: ${a}`];e._.box(o.join(`
|
|
104
|
-
`))}renderCancelled(){e.d(),e._.log(n.default.yellow(`Conflict resolution cancelled`)),e._.log(``),e._.log(`No changes were made to your local connector file.`)}getCurrentConflictIndex(){let e=-1;for(let t=0;t<=this.currentIndex&&t<this.conflicts.length;t++)this.conflicts[t].conflict.type===`conflict`&&e++;return e}moveToNextConflict(){for(let e=this.currentIndex+1;e<this.conflicts.length;e++)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}for(let e=0;e<this.currentIndex;e++)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}}moveToPrevConflict(){for(let e=this.currentIndex-1;e>=0;e--)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}for(let e=this.conflicts.length-1;e>this.currentIndex;e--)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}}moveToNextUnresolved(){for(let e=this.currentIndex+1;e<this.conflicts.length;e++)if(this.conflicts[e].conflict.type===`conflict`&&this.conflicts[e].choice===`pending`){this.currentIndex=e;return}for(let e=0;e<this.currentIndex;e++)if(this.conflicts[e].conflict.type===`conflict`&&this.conflicts[e].choice===`pending`){this.currentIndex=e;return}}setCurrentChoice(e){this.conflicts[this.currentIndex]?.conflict.type===`conflict`&&(this.conflicts[this.currentIndex].choice=e)}allResolved(){return this.conflicts.filter(e=>e.conflict.type===`conflict`).every(e=>e.choice!==`pending`)}acceptAllRemaining(e){for(let t of this.conflicts)t.conflict.type===`conflict`&&t.choice===`pending`&&(t.choice=e)}centerText(e,t){let n=this.stripAnsi(e),r=Math.max(0,Math.floor((t-n.length)/2));return` `.repeat(r)+e}stripAnsi(e){return e.replace(/\x1b\[[0-9;]*m/g,``)}getResolvedContent(){let e=[];for(let t of this.conflicts)if(t.conflict.type===`unchanged`)e.push(t.conflict.content||``);else if(t.conflict.type===`conflict`)switch(t.choice){case`remote`:t.conflict.remote&&e.push(t.conflict.remote);break;case`local`:t.conflict.local&&e.push(t.conflict.local);break;case`both`:t.conflict.local&&e.push(t.conflict.local),t.conflict.remote&&e.push(t.conflict.remote);break;case`pending`:t.conflict.remote&&e.push(t.conflict.remote);break}return e.join(``)}};const Z=`https://api.stackone.com`,ue=3;var
|
|
111
|
+
`))}renderCancelled(){e.d(),e._.log(n.default.yellow(`Conflict resolution cancelled`)),e._.log(``),e._.log(`No changes were made to your local connector file.`)}getCurrentConflictIndex(){let e=-1;for(let t=0;t<=this.currentIndex&&t<this.conflicts.length;t++)this.conflicts[t].conflict.type===`conflict`&&e++;return e}moveToNextConflict(){for(let e=this.currentIndex+1;e<this.conflicts.length;e++)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}for(let e=0;e<this.currentIndex;e++)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}}moveToPrevConflict(){for(let e=this.currentIndex-1;e>=0;e--)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}for(let e=this.conflicts.length-1;e>this.currentIndex;e--)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}}moveToNextUnresolved(){for(let e=this.currentIndex+1;e<this.conflicts.length;e++)if(this.conflicts[e].conflict.type===`conflict`&&this.conflicts[e].choice===`pending`){this.currentIndex=e;return}for(let e=0;e<this.currentIndex;e++)if(this.conflicts[e].conflict.type===`conflict`&&this.conflicts[e].choice===`pending`){this.currentIndex=e;return}}setCurrentChoice(e){this.conflicts[this.currentIndex]?.conflict.type===`conflict`&&(this.conflicts[this.currentIndex].choice=e)}allResolved(){return this.conflicts.filter(e=>e.conflict.type===`conflict`).every(e=>e.choice!==`pending`)}acceptAllRemaining(e){for(let t of this.conflicts)t.conflict.type===`conflict`&&t.choice===`pending`&&(t.choice=e)}centerText(e,t){let n=this.stripAnsi(e),r=Math.max(0,Math.floor((t-n.length)/2));return` `.repeat(r)+e}stripAnsi(e){return e.replace(/\x1b\[[0-9;]*m/g,``)}getResolvedContent(){let e=[];for(let t of this.conflicts)if(t.conflict.type===`unchanged`)e.push(t.conflict.content||``);else if(t.conflict.type===`conflict`)switch(t.choice){case`remote`:t.conflict.remote&&e.push(t.conflict.remote);break;case`local`:t.conflict.local&&e.push(t.conflict.local);break;case`both`:t.conflict.local&&e.push(t.conflict.local),t.conflict.remote&&e.push(t.conflict.remote);break;case`pending`:t.conflict.remote&&e.push(t.conflict.remote);break}return e.join(``)}};const Z=`https://api.stackone.com`,ue=3;var de=class{async execute({profile:t,connector:r,outputPath:i,apiUrl:a,apiKey:o}={}){if((0,x.isMissing)(r)&&(e._.error(`Connector identifier is required`),e._.log(`Please provide a connector identifier using the ${e.g(`--connector`)} option in the format: ${e.g(`provider_key@version`)} or ${e.g(`provider_key`)}`),e._.log(`If no version is specified, the latest version will be pulled.`),process.exit(1)),!t&&!o&&(e._.error(`Profile or API key is required`),e._.log(`Please provide a profile using the ${e.g(`--profile`)} option or an API key using the ${e.g(`--api-key`)} option.`),e._.log(`To create a profile, run ${e.g(`stackone init`)}.`),process.exit(1)),t&&o&&(e._.error(`Please provide either a profile or an API key, not both`),process.exit(1)),t&&a&&e._.warn(`Specifying ${e.g(`--api-url`)} with a profile won't have any effect. Using API url from profile.`),t&&!H(t)){e._.error(`Configuration profile ${e.g(t)} not found`),e._.log(`Run ${e.g(`stackone init`)} to create a new configuration profile.\n`);let r=U();r.length>0&&(e._.info(`Available configuration profiles:`),r.forEach(t=>{e._.log(` - ${n.default.blue(t)}`)})),process.exit(1)}let s=t?V(t):{apiUrl:a??Z,apiKey:o};s?.apiKey||(e._.error(`API key is missing`),e._.log(`Please provide a valid API key in the profile or via the ${e.g(`--api-key`)} option.`),process.exit(1));let c=s.apiUrl??Z,[l,u]=r.split(`@`),d=await this.#f(l,c,s.apiKey,u??`latest`),f=this.#e(d),p=f.version??`unknown`,m=this.#t(i,f.key,p),h=this.#r(m),g=h===null,_=d;if(!g){let t=this.#i(h,m);t&&(e._.warn(t.message),t.errors.length>0&&e.f(t.errors,!1),e._.log(``));let n=t?void 0:this.#e(h);if(this.#o(h,d)){this.#a(h,d,m);let t=n?.version??`unknown`,i=await this.#s(h,d,r,t,p);i.action===`cancel`&&((0,S.cancel)(`Pull cancelled`),process.exit(0)),i.action===`keep-local`&&(e._.log(``),e._.info(`Keeping local version. No changes made.`),process.exit(0)),i.action===`interactive-cancel`&&process.exit(0),i.action===`interactive`&&(_=i.resolvedContent)}else e._.info(`No changes detected in connector configuration.`),process.exit(0)}let v=(0,C.validateYamlConnector)(_).connector,y=v?.key??f.key,b=v?.version??p,w=this.#t(i,y,b),T=w;if(w!==m){let t=await this.#n(w);e._.log(``),t!==void 0&&(T=t)}await this.#d(T,_),g?e._.success(`Connector ${e.g(y)}@${e.g(b)} pulled successfully (new connector)`):e._.success(`Connector ${e.g(y)}@${e.g(b)} updated successfully`);let E=y===f.key?e.g(y):`${e.g(f.key)} ${n.default.whiteBright(`→`)} ${e.g(y)}`,D=b===p?e.g(b):`${e.g(p)} ${n.default.whiteBright(`→`)} ${e.g(b)}`,O=T===m?e.g(T):`${e.g(m)}\n ${n.default.whiteBright(`→`)} ${e.g(T)}`;e._.log(`\n${n.default.blue.inverse(` CONNECTOR DETAILS `)}\n`),e._.log(` Provider: ${E}`),e._.log(` Version: ${D}`),e._.log(` Output file: ${O}`),process.exit(0)}#e(t){let n=(0,C.validateYamlConnector)(t),r=n?.errors??[];if(n.success)return n.connector;e._.error(`Connector pulled from the registry is not valid`),e._.log(`Please make sure you are using the latest version of the StackOne CLI by running ${e.g(`stackone update`)}`),r.length>0&&e.f(r,!0),process.exit(1)}#t(t,n,r){let i=`${n}_v${r.replaceAll(`.`,`-`)}.s1.yaml`;return t?(d.default.existsSync(t)&&(d.default.statSync(t).isDirectory()||(e._.error(`Output path ${e.g(t)} is not a directory`),e._.log(`Please provide a valid directory path to store connectors or use the default path.`),process.exit(1))),f.default.resolve(t,n,i)):f.default.resolve(process.cwd(),`connectors`,n,i)}async#n(t){if(!d.default.existsSync(t))return;let n=f.default.basename(t),r=f.default.dirname(t);e._.warn(`File ${e.g(n)} already exists at ${e.g(r)}`);let i=await(0,S.select)({message:`How would you like to proceed?`,options:[{value:`override`,label:`Override existing file`,hint:`Replace the existing file with the new content`},{value:`rename`,label:`Save with a different name`,hint:`Provide a new filename for the connector`},{value:`cancel`,label:`Cancel`,hint:`Abort the pull operation`}]});if(((0,S.isCancel)(i)||i===`cancel`)&&((0,S.cancel)(`Operation cancelled. No local changes were made.`),process.exit(0)),i===`override`)return;let a=await(0,S.text)({message:`Enter the new filename:`,placeholder:n,validate:e=>{if(!e||e.trim()===``)return`Filename cannot be empty`;if(!e.endsWith(`.s1.yaml`))return`Filename must end with .s1.yaml`;let t=f.default.join(r,e.trim());if(d.default.existsSync(t))return`File ${e} already exists`}});return(0,S.isCancel)(a)&&((0,S.cancel)(`Operation cancelled. No local changes were made.`),process.exit(0)),f.default.join(r,a.trim())}#r(e){if(!d.default.existsSync(e))return null;try{return d.default.readFileSync(e,`utf-8`)}catch{return null}}#i(t,n){try{let r=(0,C.validateYamlConnector)(t);if(!r.success){let t=r.errors??[];return{message:`Local connector ${e.g(f.default.basename(n))} has validation errors:`,errors:t}}}catch(t){return{message:`Local connector ${e.g(f.default.basename(n))} could not be validated: ${t.message}`,errors:[]}}return null}#a(t,r,i){let a=(0,w.diffLines)(t,r);if(!a.some(e=>e.added||e.removed)){e._.info(`No changes detected in connector configuration.`);return}e._.log(`${n.default.blue.inverse(` CHANGES `)}\n`),e._.log(n.default.gray(`--- local: ${i}`)),e._.log(n.default.gray(`+++ remote: StackOne Registry`)),e._.log(``);let o=0,s=0;for(let t of a){let r=t.value.split(`
|
|
105
112
|
`).filter(e=>e!==``);if(t.added){o+=r.length;for(let t of r)e._.log(n.default.green(`+ ${t}`))}else if(t.removed){s+=r.length;for(let t of r)e._.log(n.default.red(`- ${t}`))}else if(r.length<=6)for(let t of r)e._.log(n.default.gray(` ${t}`));else{for(let t=0;t<3;t++)e._.log(n.default.gray(` ${r[t]}`));e._.log(n.default.gray(` ... (${r.length-6} unchanged lines)`));for(let t=r.length-3;t<r.length;t++)e._.log(n.default.gray(` ${r[t]}`))}}e._.log(``),e._.log(n.default.gray(`Summary: ${n.default.green(`+${o}`)} additions, ${n.default.red(`-${s}`)} deletions`))}#o(e,t){return(0,w.diffLines)(e,t).some(e=>e.added||e.removed)}async#s(t,n,r,i,a){e._.log(``);let o=await(0,S.select)({message:`How would you like to resolve the differences?`,options:[{value:`override`,label:`Override local with remote`,hint:`Replace your local file with the StackOne version`},{value:`keep-local`,label:`Keep local version`,hint:`Cancel the pull and keep your current file`},{value:`interactive`,label:`Resolve conflicts interactively`,hint:`Choose which changes to accept one by one`},{value:`cancel`,label:`Cancel`,hint:`Abort the pull operation`}]});if((0,S.isCancel)(o))return{action:`cancel`};if(o===`override`)return{action:`override`};if(o===`keep-local`)return{action:`keep-local`};if(o===`interactive`){let e=await this.#c(t,n,r,i,a);return e===null?{action:`interactive-cancel`}:{action:`interactive`,resolvedContent:e}}return{action:`cancel`}}async#c(t,n,r,i,a){let o=(0,w.diffLines)(t,n),s=this.#u(o);if(s.length===0)return e._.info(`No conflicts to resolve.`),n;let c=new X(s,r,i,a);for(;;){if((await c.resolve()).cancelled)return null;let t=c.getResolvedContent(),n=(0,C.validateYamlConnector)(t);if(n.success)return c.renderFinalSummary(),t;let r=await this.#l(n.errors);if(r===`cancel`)return e.d(),e._.info(`Operation cancelled. No changes were made to the local connector.`),null;if(r===`save`)return e.d(),e._.warn(`The connector was saved but it is invalid`),t;c.resetForReResolution()}}async#l(t){let{createInterface:r}=await import(`readline`);return new Promise(i=>{e.d();let a=(t||[{message:`Unknown validation error`}]).map(e=>` • ${e.message}`).join(`
|
|
106
|
-
`);e._.box({title:`⚠️ Validation Failed`,message:`The resolved connector configuration is invalid:\n\n${a}`,style:{borderColor:`yellow`,padding:1}}),e._.log(``),e._.log(n.default.bold(` Choose an action:`)),e._.log(``),e._.log(n.default.cyan(` [B]`)+` ← Go back to conflict resolution`),e._.log(n.default.dim(` Modify your choices to fix the validation errors`)),e._.log(``),e._.log(n.default.yellow(` [S]`)+` 💾 Save anyway`),e._.log(n.default.dim(` Save the invalid configuration (not recommended)`)),e._.log(``),e._.log(n.default.red(` [C]`)+` ✖ Cancel`),e._.log(n.default.dim(` Discard all changes`)),e._.log(``);let o=r({input:process.stdin,output:process.stdout});process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume();let s=e=>{let t=e.toString().toLowerCase(),n=()=>{process.stdin.removeListener(`data`,s),process.stdin.isTTY&&process.stdin.setRawMode(!1),o.close()};if(t===``||t===`\x1B`){n(),i(`cancel`);return}switch(t){case`b`:n(),i(`back`);break;case`s`:n(),i(`save`);break;case`c`:case`q`:n(),i(`cancel`);break}};process.stdin.on(`data`,s)})}#u(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(!r.added&&!r.removed)t.push({type:`unchanged`,content:r.value}),n++;else if(r.removed){let i=e[n+1];i?.added?(t.push({type:`conflict`,local:r.value,remote:i.value}),n+=2):(t.push({type:`conflict`,local:r.value,remote:void 0}),n++)}else r.added&&t.push({type:`conflict`,local:void 0,remote:r.value}),n++}return t}async#d(t,n){let r=f.default.dirname(t);d.default.existsSync(r)||d.default.mkdirSync(r,{recursive:!0});try{d.default.writeFileSync(t,n,`utf-8`)}catch(n){e._.error(`Failed to write connector to file ${e.g(t)}: ${n.message}`),process.exit(1)}}async#f(t,n,r,i){let a=(0,_.default)(`Pulling connector ${e.g(t)}@${e.g(i)} from registry...`).start();try{let e=Buffer.from(r).toString(`base64`),o=`${n}/registry/connectors/${t}@${i}`,s=await fetch(o,{method:`GET`,headers:{Authorization:`Basic ${e}`}});return a.stop(),s.ok||(await this.#p(s,t,i),process.exit(1)),await s.text()}catch(r){a.stop(),e._.error(`Failed to pull connector ${e.g(t)}@${e.g(i)} from the registry: ${r.message}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid.`),process.exit(1)}}async#p(t,n,r){switch(t.status){case 401:case 403:e._.error(`Access denied`),e._.log(`Please ensure that your API key is valid and has the ${e.g(`connectors:read`)} scope required to pull connectors.`);break;case 404:e._.error(`Connector ${e.g(n)}@${e.g(r)} was not found in the registry`),await this.#m(n);break;case 429:e._.error(`Rate limit exceeded`),e._.log(`Too many requests. Please wait a moment before trying again.`);break;default:await e.m(t,`Failed to pull connector ${e.g(n)}`)}}async#m(t){e._.info(`To see available versions, check the connector documentation or contact support.`)}};const $=`https://api.stackone.com`;var de=class{async execute({profile:t,fileOrDir:r,apiUrl:i,apiKey:a}={}){if(!t&&!a&&(e._.error(`Profile or API key is required`),e._.log(`Please provide a profile using the ${e.g(`--profile`)} option or an API key using the ${e.g(`--api-key`)} option.`),e._.log(`To create a profile, run ${e.g(`stackone init`)}.`),process.exit(1)),t&&a&&(e._.error(`Please provide either a profile or an API key, not both`),process.exit(1)),t&&i&&e._.warn(`Specifying ${e.g(`--api-url`)} with a profile won't have any effect. Using API url from profile.`),t&&!z(t)){e._.error(`Configuration profile ${e.g(t)} not found`),e._.log(`Run ${e.g(`stackone init`)} to create a new configuration profile.\n`);let r=V();r.length>0&&(e._.info(`Available configuration profiles:`),r.forEach(t=>{e._.log(` - ${n.default.blue(t)}`)})),process.exit(1)}let o=t?R(t):{apiUrl:i??$,apiKey:a};o?.apiKey||(e._.error(`API key is missing`),e._.log(`Please provide a valid API key in the profile or via the ${e.g(`--api-key`)} option.`),process.exit(1)),r||(e._.error(`File or directory is required.`),process.exit(1));try{(0,d.statSync)(r)}catch{e._.error(`File or directory not found: ${n.default.red(r)}`),process.exit(1)}let s=(0,d.statSync)(r),c=o.apiUrl??$;if(s.isDirectory()){let t=pe(r),i=0;t.length===0?(e._.error(`No .s1.yaml connector files found in the directory: ${r}.`),process.exit(1)):(e._.start(`Found ${t.length} connector(s) file(s). Pushing to registry...`),e._.log(``));for(let e of t)await this.uploadFile(e,c,o.apiKey)&&i++;i===0?e._.error(`Error while pushing connectors: no files were uploaded`):(e._.log(``),e._.info(`Upload completed: ${n.default.green(i)} of ${n.default.blue(t.length)} file(s) uploaded successfully.`)),process.exit(i>0?0:1)}else r.endsWith(`.s1.yaml`)||(e._.error(`Only ${e.g(`.s1.yaml`)} files are supported for upload`),process.exit(1));let l=await this.uploadFile(r,c,o.apiKey);process.exit(l?0:1)}async uploadFile(t,n,r){let i=(0,_.default)(`📤 Pushing connector in ${(0,f.basename)(t)}...`).start();try{let a=fe(t);if(!a)return!1;let o=(0,f.basename)(t),s=new FormData,c=new Blob([a],{type:`application/x-yaml`});s.append(`file`,c,o);let l=Buffer.from(r).toString(`base64`),u=await fetch(`${n}/registry/connectors`,{method:`POST`,headers:{Authorization:`Basic ${l}`},body:s});if(i.stop(),!u.ok)return await e.m(u,`Failed to push connector in ${e.g(o)} to the registry`),!1;let d=await u.json();return e._.success(`Successfully uploaded ${e.g(o)} with connector ${e.g(d.provider)}@${e.g(d.version)}`),!0}catch(r){return i.stop(),e._.error(`Failed to upload file ${e.g(t)}: ${r}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid`),!1}}};const fe=t=>{let n=(0,C.loadConnector)(t),r=(0,C.validateYamlConnector)(n),i=r?.errors??[];if(r.success)return n;i.length>0?(e._.error(`Connector in ${e.h(t)} is not valid`),e.f(i,!0)):e._.error(`Connector in ${e.h(t)} is not valid. Please check the file for errors.`)},pe=e=>{let t=[],n=(0,d.readdirSync)(e,{withFileTypes:!0});for(let r of n){let n=(0,f.join)(e,r.name);r.isDirectory()?t.push(...pe(n)):r.name.endsWith(`.s1.yaml`)&&t.push(n)}return t},me=x.z.object({provider_key:x.z.string().optional(),provider_version:x.z.string().optional(),auth_config_key:x.z.string(),environment:x.z.string().default(`production`),organization_id:x.z.string().default(`cli-organization-id`),account_id:x.z.string().default(`cli-account-secure-id`),project_id:x.z.string().default(`cli-project-secure-id`),credentials:x.z.record(x.z.string(),x.z.any()).default({})}),he=x.z.record(x.z.string(),x.z.any()),ge=x.z.object({path:x.z.record(x.z.string(),x.z.any()).default({}),queryParams:x.z.record(x.z.string(),x.z.any()).default({}),header:x.z.record(x.z.string(),x.z.any()).default({}),body:x.z.record(x.z.string(),x.z.any()).default({})}),_e=`https://api.stackone.com`;var ve=class{async execute({connector:t,action:r,actionId:i,account:a,accountId:o,params:s,credentials:c,profile:l,outputFile:u,debug:f,apiUrl:p,apiKey:m}={}){if(!l&&!m&&o&&(e._.error(`Profile or API key is required when providing an account ID`),e._.log(`Please provide a profile using the ${e.g(`--profile`)} option or an API key using the ${e.g(`--api-key`)} option.`),e._.log(`To create a profile, run ${e.g(`stackone init`)}.`),process.exit(1)),l&&m&&(e._.error(`Please provide either a profile or an API key, not both`),process.exit(1)),l&&p&&e._.warn(`Specifying --api-url with a profile won't have any effect. Using API url from profile.`),l&&!z(l)){e._.error(`Configuration profile ${e.g(l)} not found`),e._.log(`Run ${e.g(`stackone init`)} to create a new configuration profile.\n`);let t=V();t.length>0&&(e._.info(`Available configuration profiles:`),t.forEach(t=>{e._.log(` - ${n.default.blue(t)}`)})),process.exit(1)}let h=l?R(l):{apiUrl:p??_e,apiKey:m};(0,x.isMissing)(a)&&(0,x.isMissing)(o)&&(e._.error(`A valid account or account ID is required to run an action`),process.exit(1));let g;if((0,x.notMissing)(t))if(this.#a(t)){!l&&!m&&(e._.error(`Profile or API key is required when using a connector identifier`),e._.log(`Please provide a profile using the ${e.g(`--profile`)} option or an API key using the ${e.g(`--api-key`)} option.`),e._.log(`Run ${e.g(`stackone init`)} to create a new configuration profile.`),process.exit(1));let n=this.#o(t);g=await this.#s(n,h?.apiUrl??_e,h?.apiKey)}else g=this.#e(t);else (0,x.notMissing)(o)&&(g=await this.#c(o,h?.apiUrl??_e,h?.apiKey));let _=(0,x.notMissing)(r)?this.#r(r,t):g;(0,x.isMissing)(_)&&(e._.error(`A valid connector is required to run an action.`),process.exit(1));let v=(0,x.notMissing)(_?.actions)?Object.keys(_?.actions).length:0,y=(0,x.notMissing)(_?.actions)?Object.keys(_.actions)[v-1]:void 0,b=(0,x.notMissing)(y)?_?.actions?.[y]?.id:void 0,S=((0,x.notMissing)(i)&&!i?.startsWith(`${_.key}_`)?`${_.key}_${i}`:i)??b;(0,x.isMissing)(S)&&(e._.error(`A valid action ID is required to run an action`),process.exit(1));let C=(0,x.notMissing)(o)?await this.#l(o,h?.apiUrl??_e,h?.apiKey):{},w=(0,x.notMissing)(a)?this.#i(a,_.key??`unknown`,_.version??`unknown`):void 0,T=(0,x.notMissing)(c)?this.#u(c):{},E={...C,...w,credentials:{...C.credentials??{},...T}};(0,x.isMissing)(E)&&(e._.error(`A valid account data is required to run an action.`),process.exit(1));let D=_.actions?.[S];(0,x.isMissing)(D)&&(e._.error(`Action ID ${e.g(S)} not found in the connector ${e.g(_.key)}@${e.g(_.version)}.`),process.exit(1));let O=(0,x.notMissing)(s)?this.#d(s,S):{path:{},queryParams:{},header:{},body:{}},k=Date.now(),ee=await this.#f({connector:_,actionId:S,account:E,queryParams:{...O.queryParams,...f?{debug:`true`}:{}},pathParams:O.path,body:O.body,headers:O.header}),te=Date.now()-k;if((0,x.notMissing)(u))try{d.default.writeFileSync(u,JSON.stringify(ee.output,null,2),`utf-8`),e._.info(`Output written to file: ${u}`)}catch(t){e._.error(`Failed to write output to file ${u}: ${t.message}`),process.exit(1)}else e._.log(`\n${n.default.blue.inverse(` ACTION OUTPUT `)}`),e.p(ee.output);e._.log(``),e._.info(`Action ${e.g(S)} from connector ${e.g(_?.key)}@${e.g(_?.version)} finished in ${n.default.yellowBright((te/1e3).toFixed(2))} seconds.`),process.exit(0)}#e=e=>{let t=e;try{t=(0,C.loadConnector)(e)}catch{}return t?this.#n(t):void 0};#t=t=>{try{return(0,C.loadConnector)(t)}catch(n){e._.error(`Failed to load connector file from ${e.g(t)}: ${n.message}`),process.exit(1)}};#n=t=>{let n=(0,C.validateYamlConnector)(t),r=n?.errors??[];if(n.success)return n.connector||(e._.error(`Failed to load connector.`),process.exit(1)),n.connector;r.length>0?(e._.error(`Connector is not valid`),e.f(r,!0),process.exit(1)):(e._.error(`Connector is not valid. Please check the file for errors.`),process.exit(1))};#r=(t,n)=>{let r=t;try{r=d.default.readFileSync(t,`utf-8`)}catch{}(0,x.isMissing)(n)&&(e._.error(`A valid connector is required to load an action.`),process.exit(1));let i=`${this.#t(n)} - ${r.split(`
|
|
113
|
+
`);e._.box({title:`⚠️ Validation Failed`,message:`The resolved connector configuration is invalid:\n\n${a}`,style:{borderColor:`yellow`,padding:1}}),e._.log(``),e._.log(n.default.bold(` Choose an action:`)),e._.log(``),e._.log(n.default.cyan(` [B]`)+` ← Go back to conflict resolution`),e._.log(n.default.dim(` Modify your choices to fix the validation errors`)),e._.log(``),e._.log(n.default.yellow(` [S]`)+` 💾 Save anyway`),e._.log(n.default.dim(` Save the invalid configuration (not recommended)`)),e._.log(``),e._.log(n.default.red(` [C]`)+` ✖ Cancel`),e._.log(n.default.dim(` Discard all changes`)),e._.log(``);let o=r({input:process.stdin,output:process.stdout});process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume();let s=e=>{let t=e.toString().toLowerCase(),n=()=>{process.stdin.removeListener(`data`,s),process.stdin.isTTY&&process.stdin.setRawMode(!1),o.close()};if(t===``||t===`\x1B`){n(),i(`cancel`);return}switch(t){case`b`:n(),i(`back`);break;case`s`:n(),i(`save`);break;case`c`:case`q`:n(),i(`cancel`);break}};process.stdin.on(`data`,s)})}#u(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(!r.added&&!r.removed)t.push({type:`unchanged`,content:r.value}),n++;else if(r.removed){let i=e[n+1];i?.added?(t.push({type:`conflict`,local:r.value,remote:i.value}),n+=2):(t.push({type:`conflict`,local:r.value,remote:void 0}),n++)}else r.added&&t.push({type:`conflict`,local:void 0,remote:r.value}),n++}return t}async#d(t,n){let r=f.default.dirname(t);d.default.existsSync(r)||d.default.mkdirSync(r,{recursive:!0});try{d.default.writeFileSync(t,n,`utf-8`)}catch(n){e._.error(`Failed to write connector to file ${e.g(t)}: ${n.message}`),process.exit(1)}}async#f(t,n,r,i){let a=(0,_.default)(`Pulling connector ${e.g(t)}@${e.g(i)} from registry...`).start();try{let e=Buffer.from(r).toString(`base64`),o=`${n}/registry/connectors/${t}@${i}`,s=await fetch(o,{method:`GET`,headers:{Authorization:`Basic ${e}`}});return a.stop(),s.ok||(await this.#p(s,t,i),process.exit(1)),await s.text()}catch(r){a.stop(),e._.error(`Failed to pull connector ${e.g(t)}@${e.g(i)} from the registry: ${r.message}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid.`),process.exit(1)}}async#p(t,n,r){switch(t.status){case 401:case 403:e._.error(`Access denied`),e._.log(`Please ensure that your API key is valid and has the ${e.g(`connectors:read`)} scope required to pull connectors.`);break;case 404:e._.error(`Connector ${e.g(n)}@${e.g(r)} was not found in the registry`),await this.#m(n);break;case 429:e._.error(`Rate limit exceeded`),e._.log(`Too many requests. Please wait a moment before trying again.`);break;default:await e.m(t,`Failed to pull connector ${e.g(n)}`)}}async#m(t){e._.info(`To see available versions, check the connector documentation or contact support.`)}};const fe=`https://api.stackone.com`;var Q=class{async execute({profile:t,fileOrDir:r,apiUrl:i,apiKey:a}={}){if(!t&&!a&&(e._.error(`Profile or API key is required`),e._.log(`Please provide a profile using the ${e.g(`--profile`)} option or an API key using the ${e.g(`--api-key`)} option.`),e._.log(`To create a profile, run ${e.g(`stackone init`)}.`),process.exit(1)),t&&a&&(e._.error(`Please provide either a profile or an API key, not both`),process.exit(1)),t&&i&&e._.warn(`Specifying ${e.g(`--api-url`)} with a profile won't have any effect. Using API url from profile.`),t&&!H(t)){e._.error(`Configuration profile ${e.g(t)} not found`),e._.log(`Run ${e.g(`stackone init`)} to create a new configuration profile.\n`);let r=U();r.length>0&&(e._.info(`Available configuration profiles:`),r.forEach(t=>{e._.log(` - ${n.default.blue(t)}`)})),process.exit(1)}let o=t?V(t):{apiUrl:i??fe,apiKey:a};o?.apiKey||(e._.error(`API key is missing`),e._.log(`Please provide a valid API key in the profile or via the ${e.g(`--api-key`)} option.`),process.exit(1)),r||(e._.error(`File or directory is required.`),process.exit(1));try{(0,d.statSync)(r)}catch{e._.error(`File or directory not found: ${n.default.red(r)}`),process.exit(1)}let s=(0,d.statSync)(r),c=o.apiUrl??fe;if(s.isDirectory()){let t=pe(r),i=0;t.length===0?(e._.error(`No .s1.yaml connector files found in the directory: ${r}.`),process.exit(1)):(e._.start(`Found ${t.length} connector(s) file(s). Pushing to registry...`),e._.log(``));for(let e of t)await this.uploadFile(e,c,o.apiKey)&&i++;i===0?e._.error(`Error while pushing connectors: no files were uploaded`):(e._.log(``),e._.info(`Upload completed: ${n.default.green(i)} of ${n.default.blue(t.length)} file(s) uploaded successfully.`)),process.exit(i>0?0:1)}else r.endsWith(`.s1.yaml`)||(e._.error(`Only ${e.g(`.s1.yaml`)} files are supported for upload`),process.exit(1));let l=await this.uploadFile(r,c,o.apiKey);process.exit(l?0:1)}async uploadFile(t,n,r){let i=(0,_.default)(`📤 Pushing connector in ${(0,f.basename)(t)}...`).start();try{let a=$(t);if(!a)return!1;let o=(0,f.basename)(t),s=new FormData,c=new Blob([a],{type:`application/x-yaml`});s.append(`file`,c,o);let l=Buffer.from(r).toString(`base64`),u=await fetch(`${n}/registry/connectors`,{method:`POST`,headers:{Authorization:`Basic ${l}`},body:s});if(i.stop(),!u.ok)return await e.m(u,`Failed to push connector in ${e.g(o)} to the registry`),!1;let d=await u.json();return e._.success(`Successfully uploaded ${e.g(o)} with connector ${e.g(d.provider)}@${e.g(d.version)}`),!0}catch(r){return i.stop(),e._.error(`Failed to upload file ${e.g(t)}: ${r}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid`),!1}}};const $=t=>{let n=(0,C.loadConnector)(t),r=(0,C.validateYamlConnector)(n),i=r?.errors??[];if(r.success)return n;i.length>0?(e._.error(`Connector in ${e.h(t)} is not valid`),e.f(i,!0)):e._.error(`Connector in ${e.h(t)} is not valid. Please check the file for errors.`)},pe=e=>{let t=[],n=(0,d.readdirSync)(e,{withFileTypes:!0});for(let r of n){let n=(0,f.join)(e,r.name);r.isDirectory()?t.push(...pe(n)):r.name.endsWith(`.s1.yaml`)&&t.push(n)}return t},me=x.z.object({provider_key:x.z.string().optional(),provider_version:x.z.string().optional(),auth_config_key:x.z.string(),environment:x.z.string().default(`production`),organization_id:x.z.string().default(`cli-organization-id`),account_id:x.z.string().default(`cli-account-secure-id`),project_id:x.z.string().default(`cli-project-secure-id`),credentials:x.z.record(x.z.string(),x.z.any()).default({})}),he=x.z.record(x.z.string(),x.z.any()),ge=x.z.object({path:x.z.record(x.z.string(),x.z.any()).default({}),queryParams:x.z.record(x.z.string(),x.z.any()).default({}),header:x.z.record(x.z.string(),x.z.any()).default({}),body:x.z.record(x.z.string(),x.z.any()).default({})}),_e=`https://api.stackone.com`;var ve=class{async execute({connector:t,action:r,actionId:i,account:a,accountId:o,params:s,credentials:c,profile:l,outputFile:u,debug:f,apiUrl:p,apiKey:m}={}){if(!l&&!m&&o&&(e._.error(`Profile or API key is required when providing an account ID`),e._.log(`Please provide a profile using the ${e.g(`--profile`)} option or an API key using the ${e.g(`--api-key`)} option.`),e._.log(`To create a profile, run ${e.g(`stackone init`)}.`),process.exit(1)),l&&m&&(e._.error(`Please provide either a profile or an API key, not both`),process.exit(1)),l&&p&&e._.warn(`Specifying --api-url with a profile won't have any effect. Using API url from profile.`),l&&!H(l)){e._.error(`Configuration profile ${e.g(l)} not found`),e._.log(`Run ${e.g(`stackone init`)} to create a new configuration profile.\n`);let t=U();t.length>0&&(e._.info(`Available configuration profiles:`),t.forEach(t=>{e._.log(` - ${n.default.blue(t)}`)})),process.exit(1)}let h=l?V(l):{apiUrl:p??_e,apiKey:m};(0,x.isMissing)(a)&&(0,x.isMissing)(o)&&(e._.error(`A valid account or account ID is required to run an action`),process.exit(1));let g;if((0,x.notMissing)(t))if(this.#a(t)){!l&&!m&&(e._.error(`Profile or API key is required when using a connector identifier`),e._.log(`Please provide a profile using the ${e.g(`--profile`)} option or an API key using the ${e.g(`--api-key`)} option.`),e._.log(`Run ${e.g(`stackone init`)} to create a new configuration profile.`),process.exit(1));let n=this.#o(t);g=await this.#s(n,h?.apiUrl??_e,h?.apiKey)}else g=this.#e(t);else (0,x.notMissing)(o)&&(g=await this.#c(o,h?.apiUrl??_e,h?.apiKey));let _=(0,x.notMissing)(r)?this.#r(r,t):g;(0,x.isMissing)(_)&&(e._.error(`A valid connector is required to run an action.`),process.exit(1));let v=(0,x.notMissing)(_?.actions)?Object.keys(_?.actions).length:0,y=(0,x.notMissing)(_?.actions)?Object.keys(_.actions)[v-1]:void 0,b=(0,x.notMissing)(y)?_?.actions?.[y]?.id:void 0,S=((0,x.notMissing)(i)&&!i?.startsWith(`${_.key}_`)?`${_.key}_${i}`:i)??b;(0,x.isMissing)(S)&&(e._.error(`A valid action ID is required to run an action`),process.exit(1));let C=(0,x.notMissing)(o)?await this.#l(o,h?.apiUrl??_e,h?.apiKey):{},w=(0,x.notMissing)(a)?this.#i(a,_.key??`unknown`,_.version??`unknown`):void 0,T=(0,x.notMissing)(c)?this.#u(c):{},E={...C,...w,credentials:{...C.credentials??{},...T}};(0,x.isMissing)(E)&&(e._.error(`A valid account data is required to run an action.`),process.exit(1));let D=_.actions?.[S];(0,x.isMissing)(D)&&(e._.error(`Action ID ${e.g(S)} not found in the connector ${e.g(_.key)}@${e.g(_.version)}.`),process.exit(1));let O=(0,x.notMissing)(s)?this.#d(s,S):{path:{},queryParams:{},header:{},body:{}},k=Date.now(),ee=await this.#f({connector:_,actionId:S,account:E,queryParams:{...O.queryParams,...f?{debug:`true`}:{}},pathParams:O.path,body:O.body,headers:O.header}),te=Date.now()-k;if((0,x.notMissing)(u))try{d.default.writeFileSync(u,JSON.stringify(ee.output,null,2),`utf-8`),e._.info(`Output written to file: ${u}`)}catch(t){e._.error(`Failed to write output to file ${u}: ${t.message}`),process.exit(1)}else e._.log(`\n${n.default.blue.inverse(` ACTION OUTPUT `)}`),e.p(ee.output);e._.log(``),e._.info(`Action ${e.g(S)} from connector ${e.g(_?.key)}@${e.g(_?.version)} finished in ${n.default.yellowBright((te/1e3).toFixed(2))} seconds.`),process.exit(0)}#e=e=>{let t=e;try{t=(0,C.loadConnector)(e)}catch{}return t?this.#n(t):void 0};#t=t=>{try{return(0,C.loadConnector)(t)}catch(n){e._.error(`Failed to load connector file from ${e.g(t)}: ${n.message}`),process.exit(1)}};#n=t=>{let n=(0,C.validateYamlConnector)(t),r=n?.errors??[];if(n.success)return n.connector||(e._.error(`Failed to load connector.`),process.exit(1)),n.connector;r.length>0?(e._.error(`Connector is not valid`),e.f(r,!0),process.exit(1)):(e._.error(`Connector is not valid. Please check the file for errors.`),process.exit(1))};#r=(t,n)=>{let r=t;try{r=d.default.readFileSync(t,`utf-8`)}catch{}(0,x.isMissing)(n)&&(e._.error(`A valid connector is required to load an action.`),process.exit(1));let i=`${this.#t(n)} - ${r.split(`
|
|
107
114
|
`).map((e,t)=>t===0?e:` ${e}`).join(`
|
|
108
115
|
`)}`;return this.#n(i)};#i=(t,n,r)=>{let i=t;try{i=d.default.readFileSync(t,`utf-8`)}catch{}try{let e=me.parse(JSON.parse(i));return{providerKey:n,providerVersion:r,authConfigKey:e.auth_config_key,environment:e.environment,organizationId:e.organization_id,secureId:e.account_id,projectSecureId:e.project_id}}catch(t){let n=[];try{n=JSON.parse(t.message)}catch{}e._.error(`Failed to parse account information`),e.f(n,!1),n.length===0&&e._.log(t.message),process.exit(1)}};#a=e=>!e.includes(`/`)&&!e.includes(`\\`)&&!e.endsWith(`.yaml`)&&!e.endsWith(`.yml`)?e.includes(`@`)?e.split(`@`).length===2:!0:!1;#o=e=>e.includes(`@`)?e:`${e}@latest`;#s=async(t,n,r)=>{((0,x.isMissing)(t)||(0,x.isMissing)(n)||(0,x.isMissing)(r))&&(e._.error(`Connector identifier, API URL, and API key are required to fetch connector from registry.`),process.exit(1));let i=(0,_.default)();try{i.text=`Fetching connector ${e.g(t)} from registry...`,i.start();let a=Buffer.from(r).toString(`base64`),o=await fetch(`${n}/registry/connectors/${t}`,{method:`GET`,headers:{Authorization:`Basic ${a}`}});i.stop(),o.ok||(await e.m(o,`Failed to fetch connector ${e.g(t)} from registry`),process.exit(1));let s=await o.text(),c=this.#n(s);return e._.success(`Fetched connector ${e.g(c.key)}@${e.g(c.version)} from registry`),c}catch(r){i.stop(),e._.error(`Failed to fetch connector ${e.g(t)} from registry: ${r.message}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid`),process.exit(1)}};#c=async(t,n,r)=>{((0,x.isMissing)(t)||(0,x.isMissing)(n)||(0,x.isMissing)(r))&&(e._.error(`Account ID, API URL, and API key are required to fetch connector`),process.exit(1));let i=(0,_.default)();try{i.text=`Fetching connector for account ${e.g(t)} from API...`,i.start();let a=Buffer.from(r).toString(`base64`),o=await fetch(`${n}/accounts/${t}/connector`,{method:`GET`,headers:{Authorization:`Basic ${a}`}});i.stop(),o.ok||(await e.m(o,`Failed to fetch connector`),process.exit(1));let s=await o.text(),c=this.#n(s);return e._.success(`Fetched connector ${e.g(c.key)}@${e.g(c.version)} for account ${e.g(t)}`),c}catch(t){i.stop(),e._.error(`Failed to fetch connector: ${t.message}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid`),process.exit(1)}};#l=async(t,n,r)=>{((0,x.isMissing)(t)||(0,x.isMissing)(n)||(0,x.isMissing)(r))&&(e._.error(`Account ID, API URL, and API key are required to fetch account information.`),process.exit(1));let i=(0,_.default)();try{i.text=`Fetching account ${e.g(t)} information from API...`,i.start();let a=Buffer.from(r).toString(`base64`),o=await fetch(`${n}/accounts/${t}/credentials`,{method:`GET`,headers:{Authorization:`Basic ${a}`}});i.stop(),o.ok||(await e.m(o,`Failed to fetch account ${e.g(t)} information`),process.exit(1));let s=await o.json();return e._.success(`Fetched account ${e.g(t)} information from project ${e.g(s.project_id)}`),{providerKey:s.provider_key,providerVersion:s.provider_version,authConfigKey:s.auth_config_key,environment:s.environment,organizationId:s.organization_id,secureId:s.account_id,projectSecureId:s.project_id,credentials:s.credentials}}catch(r){i.stop(),e._.error(`Failed to fetch account ${e.g(t)} information: ${r.message}`),e._.log(`Please ensure that the API at ${e.v(n)} is reachable and the API key is valid`),process.exit(1)}};#u=t=>{let n=t;try{n=d.default.readFileSync(t,`utf-8`)}catch{}try{return he.parse(JSON.parse(n))}catch(t){let n=[];try{n=JSON.parse(t.message)}catch{}e._.error(`Failed to parse credentials`),e.f(n,!1),n.length===0&&e._.log(t.message),process.exit(1)}};#d=(t,n)=>{let r=t;try{r=d.default.readFileSync(t,`utf-8`)}catch{}try{return ge.parse(JSON.parse(r))}catch(t){let r=[];try{r=JSON.parse(t.message)}catch{}e._.error(`Invalid parameters for action ${e.g(n)}.`),e.f(r,!1),r.length===0&&e._.log(t.message),process.exit(1)}};async#f({connector:t,actionId:r,account:i,pathParams:a={},queryParams:o={},body:s={},headers:c={}}){try{let l=await(0,C.runAction)({mode:`action_id`,actionId:r,account:i,connector:t,pathParams:a,queryParams:o,body:s,headers:c,getHttpClient:async()=>new E.HttpClient});if(l.response?.successful){let e={...this.#p(o,l.steps),...(0,x.isObject)(l.outputs)?l.outputs:{data:l.outputs}};return{statusCode:l.response?.statusCode,output:e}}else{let i=l.response?.message??`An error occurred while processing the request`;e._.error(`Action ID ${e.g(r)} from connector ${e.g(t.key)}@${e.g(t.version)} failed with status ${l.response?.statusCode}: ${i}`);let a={...this.#p(o,l.steps)};Object.keys(a).length>0&&(e._.log(`${n.default.yellow.inverse(` EXECUTION DETAILS `)}`),e.p(a)),process.exit(1)}}catch(e){this.#m(e)}}#p(e,t){return e?.debug===`true`?{debug:{steps:t}}:{}}#m(t){let n=t;switch((0,x.isMissing)(n.errorType)&&(e._.error(`An unknown error occurred`),e._.log(`${t instanceof Error?t.message:String(t)}`),process.exit(1)),n.errorType){case`MISSING_ACTION_ERROR`:e._.error(`The specified action was not found: ${n.message}`);break;case`INVALID_ACTION_INPUTS_ERROR`:let t=n;e._.error(`Invalid action inputs`),e.f(t.validationErrors,!1);break;case`INVALID_CURSOR_ERROR`:e._.error(`Invalid cursor: ${n.message}`);break;default:e._.error(`An error occurred: ${n.message}`)}process.exit(1)}};const ye=(0,g.promisify)(m.exec);var be=class{constructor(){this.packageName=`@stackone/cli`,this.spinner=(0,_.default)(),this.currentVersion=A()}async execute(t={}){this.spinner.text=`Checking for updates...`,this.spinner.start();try{let r=await this.getLatestVersion();this.spinner.stop(),r||(e._.error(`Failed to check for updates`),process.exit(1)),this.isNewerVersion(r,this.currentVersion)?(e._.box(`New version available: ${n.default.yellow(this.currentVersion)} → ${n.default.green(r)}`),await this.performUpdate(r)):t.force?(e._.warn(`No updates available, but forcing reinstall...`),await this.performUpdate(r)):e._.success(`You are already on the latest version (${this.currentVersion})`),process.exit(0)}catch(t){this.spinner.stop(),e._.error(`Error while trying to update StackOne CLI: ${t?.message??`Unknown error`}`),process.exit(1)}}async getLatestVersion(){try{let{stdout:e}=await ye(`npm view ${this.packageName} version`,{encoding:`utf-8`});return e.trim()}catch{return null}}isNewerVersion(e,t){return D.default.gt(e,t)}isUsingVolta(){if(typeof process.env.VOLTA_HOME!=`string`||process.env.VOLTA_HOME.length===0)return!1;let e=(0,s.join)(process.env.VOLTA_HOME,`bin`),t=(0,s.join)(e,`stackone`),n=(0,s.join)(e,`stackone.exe`);return(0,a.existsSync)(t)||(0,a.existsSync)(n)}async performUpdate(t){let n=this.isUsingVolta();this.spinner.text=`Updating to latest version (${e.g(t)})...`,this.spinner.start();try{await ye(n?`volta install ${this.packageName}@latest`:`npm install -g ${this.packageName}@latest`,{encoding:`utf-8`}),this.spinner.stop(),e._.success(`StackOne CLI updated successfully to latest version (${e.g(t)})`)}catch{this.spinner.stop();let e=n?`volta install ${this.packageName}@latest`:`npm install -g ${this.packageName}@latest`;throw Error(`Failed to install update. Please try manually: ${e}`)}}};const xe=()=>{e._.log(`${n.default.gray.inverse(` CONNECTORS VALIDATION `)} ${n.default.yellow.inverse(` WATCH MODE `)}\n`)};var Se=class{async execute(t){let{watchMode:r,fileOrDir:i}=t,a=(0,_.default)(`Watching for file changes... ${n.default.gray(`(press "q" to quit)`)}`);if(!i)return;let o=(0,f.resolve)(i);try{await(0,O.stat)(o)}catch{e._.error(`The specified path does not exist: ${o}\n`),process.exit(1)}if(r){e.d();let t={},{watch:r}=await import(`chokidar`),i=(await import(`readline`)).createInterface({input:process.stdin,output:process.stdout});process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding(`utf8`);let s=()=>{l.close(),a.stop(),i.close(),e._.log(n.default.grey(`
|
|
109
|
-
Exiting watch mode...`)),process.exit(0)};xe(),e._.start(`Validating connectors...`);let c=await Ee(o);t=Ce(t,c||{}),we(t,o),a.start();let l=r(o,{persistent:!0,ignoreInitial:!0}),u=async r=>{if(!r.endsWith(`.s1.yaml`)&&!r.endsWith(`s1.partial.yaml`))return;let i=r.endsWith(`s1.partial.yaml`)?await Oe(r):[r];if(!(!i||i.length===0)){e.d(),a.stop(),xe(),e._.log(n.default.gray(`File change detected: ${r}`)),e._.start(`Validating connectors...`);for(let e of i){let n=await Ee(e);t=Ce(t,n||{})}we(t,o),a.start()}};l.on(`change`,async e=>await u(e)),process.stdin.on(`data`,e=>{e.toString()===`q`&&s()}),process.on(`SIGINT`,()=>{s()})}else await Ee(o,e._),process.exit(0)}};const Ce=(e,t)=>{for(let[n,r]of Object.entries(t))e[n]=r;return e},we=(t,r)=>{e.d(),xe();let i=0,a=0;for(let[n,r]of Object.entries(t))r===null?i++:(e._?.error(`Connector ${e.g(n)} is not valid`),e.f(r,!0),a++);e._.log(``),e._.log(n.default.blue.inverse(` Validation Summary `)),e._.log(`Connectors path: ${e.g(r)}`),e._.log(`${i===0?n.default.red(`0`):n.default.green(i)} valid, ${a===0?n.default.green(`0`):n.default.red(a)} invalid connectors\n`)},Te=async e=>{let t=[],n=await(0,O.readdir)(e);for(let r of n){let n=(0,f.join)(e,r),i=await(0,O.stat)(n);i.isDirectory()?t.push(...await Te(n)):i.isFile()&&r.endsWith(`.s1.yaml`)&&t.push(n)}return t},Ee=async(t,r)=>{let i=await(0,O.stat)(t),a={};if(i.isDirectory()){let i=await Te(t);if(i.length===0)return r?.error(`No StackOne connector found in ${e.h(t)}`),r?.log(`Connector files need to have the extension ${e.g(`*.s1.yaml`)}`),null;let o=0,s=0;for(let e of i){let t=await De(e,r);t===null?o++:(r?.log(``),s++),a[e]=t}return r?.log(``),r?.log(n.default.blue.inverse(` Validation Summary `)),r?.log(`${o===0?n.default.red(`0`):n.default.green(o)} valid, ${s===0?n.default.green(`0`):n.default.red(s)} invalid connectors`),a}else if(i.isFile()&&t.endsWith(`s1.yaml`))return a[t]=await De(t,r),a;else if(i.isFile()&&t.endsWith(`partial.yaml`)){r?.error(`Partial connector files cannot be validated directly`),r?.log(`The file ${e.h(t)} is a partial connector file.`);let n=await Oe(t);return n&&n?.length>0&&r?.log(`Did you mean ${e.g(n[0])}?`),null}else return r?.error(`No StackOne connector found in ${e.h(t)}`),r?.log(`Connector files need to have the extension ${e.g(`*.s1.yaml`)}`),null},De=async(t,n)=>{let r=(0,C.validateYamlConnector)((0,C.loadConnector)(t)),i=r?.errors??[];if(r.success){let r=t.split(`/`).pop()||t;return n?.success(`Connector ${e.g(r)} is valid!`),null}else if(i.length>0)return n?.error(`Connector ${e.g(t)} is not valid`),n&&e.f(i,!0),i;else return n?.error(`Connector ${e.g(t)} is not valid. Please check the file for errors`),[]},Oe=async e=>{let t=(0,f.dirname)(e);try{return(await(0,O.readdir)(t)).filter(e=>e.endsWith(`.s1.yaml`))?.map(e=>(0,f.join)(t,e))}catch{}};function ke(){let e=process.env.LANGSMITH_API_KEY,t=process.env.LANGSMITH_PROJECT||`stackone-agent-cli`;e&&((0,i.initLangSmith)({apiKey:e,projectName:t,enabled:!0,metadata:{source:`cli`,version:process.env.npm_package_version||`unknown`}}),process.env.VERBOSE&&console.log(`[Telemetry] LangSmith initialized for project:`,t))}const Ae=`@stackone/cli`,je=2880*60*1e3,Me=(0,s.join)((0,o.homedir)(),`.stackone`),Ne=(0,s.join)(Me,`version-check.json`),Pe=(e=!1)=>{let t=Re(),n=Date.now();if(e||!t||n-t.lastCheckTime>1728e5){let e=Fe();e&&Ie(e)&&Le(e),ze({lastCheckTime:n})}},Fe=()=>{try{return(0,m.execSync)(`npm view @stackone/cli version`,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:15e3}).trim()}catch{return null}},Ie=e=>{try{let t=A();return D.default.gt(e,t)}catch{return!1}},Le=t=>{let r=A(),i=`Update available: ${n.default.dim(r)} → ${n.default.green(t)}`,a=`\n\nRun ${n.default.cyan(`stackone update`)} to update`;e._.box(i,a)},Re=()=>{try{if(!(0,a.existsSync)(Ne))return null;let e=(0,a.readFileSync)(Ne,`utf-8`);return JSON.parse(e)}catch{return null}},ze=e=>{try{(0,a.existsSync)(Me)||(0,a.mkdirSync)(Me,{recursive:!0}),(0,a.writeFileSync)(Ne,JSON.stringify(e,null,2),`utf-8`)}catch{}};var Be=class{constructor(e=new r.Command,t=A()){this.program=e,this.version=t,ke(),this.setupProgram(),this.registerCommands()}setupProgram(){this.program.name(`stackone`).description(`StackOne CLI`).version(this.version,`-v, --version`)}registerCommands(){let t=new q,i=new de,a=new Q,o=new U,s=new ce,c=new Se,l=new oe,u=new I,d=new N,f=new M,p=new ve,m=new be;this.program.configureOutput({writeOut:e=>process.stdout.write(e),writeErr:e=>process.stderr.write(e),outputError:(e,t)=>{t(n.default.red(e))}}),this.program.command(`init`).option(`-e, --env <environment>`,`Specify the environment for the configuration profile`).description(`Initialize & create a StackOne CLI configuration profile`).action(e=>{t.execute({environment:e.env})}),this.program.command(`push`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new r.Argument(`<path>`,`Connector file or directory to push`)).description(`Push a connector to the StackOne registry`).action((e,t)=>{i.execute({profile:t.profile,fileOrDir:e,apiUrl:t.apiUrl,apiKey:t.apiKey})}),this.program.command(`drop`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new r.Argument(`<connector>`,`Connector identifier in format provider_key@version`)).description(`Drop a connector from the StackOne registry`).action((e,t)=>{o.execute({profile:t.profile,connector:e,apiUrl:t.apiUrl,apiKey:t.apiKey})}),this.program.command(`get`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-c, --connector <connector>`,`Connector identifier in format provider_key@version or provider_key (defaults to latest)`).option(`--account-id <account-id>`,`Account ID to fetch connector from`).option(`-f, --format <format>`,`Output format: yaml or json (default: yaml)`,`yaml`).option(`-o, --output-file <output-file>`,`File to write the output to`).description(`Get a connector from the StackOne registry`).action(e=>{s.execute({profile:e.profile,connector:e.connector,accountId:e.accountId,format:e.format,outputFile:e.outputFile,apiUrl:e.apiUrl,apiKey:e.apiKey})}),this.program.command(`pull`).option(`-c, --connector <connector>`,`Connector identifier in format provider_key@version or provider_key`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-o, --output <path>`,`Output directory for the connectors files (default: ./connectors)`).description(`Pull a connector configuration from StackOne registry to local filesystem`).action(e=>{a.execute({profile:e.profile,connector:e.connector,outputPath:e.output,apiUrl:e.apiUrl,apiKey:e.apiKey})}),this.program.command(`validate`).option(`-w, --watch`,`Run in watch mode`).addArgument(new r.Argument(`<path>`,`Connector file or directory with connectors to validate`)).description(`Validate a StackOne connector`).action((e,t)=>{c.execute({watchMode:t.watch,fileOrDir:e})}),this.program.command(`run`).option(`--connector <connector>`,`Connector file, inline YAML, or identifier (provider_key@version or provider_key for latest)`).option(`--action <action>`,`Action to execute on the connector (path to file or inline string action code)`).option(`--action-id <action-id>`,`Action ID to execute on the connector`).option(`--account <account>`,`Account details to use for running the connector (path to file or inline string account data)`).option(`--account-id <account-id>`,`Account ID to use for running the connector against (fetches connector from API if --connector not provided)`).option(`--params <params>`,`Action parameters (path to file or inline string with JSON parameters)`).option(`--credentials <credentials>`,`Credentials to use (path to file or inline string with JSON credentials)`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-o, --output-file <output-file>`,`File to write the output to`).option(`-d, --debug`,`Enables debug mode to include more details in the action execution output`).description(`Run a connector action`).action(e=>{p.execute({connector:e.connector,action:e.action,actionId:e.actionId,account:e.account,accountId:e.accountId,params:e.params,credentials:e.credentials,profile:e.profile,outputFile:e.outputFile,debug:e.debug,apiUrl:e.apiUrl,apiKey:e.apiKey})});let h=this.program.command(`agent`).description(`StackOne agent commands`);h.command(`setup`).option(`-g, --global`,`Setup global configuration`).option(`-l, --local`,`Setup local project configuration`).description(`Setup StackOne agent (global or local)`).action(e=>{e.global?l.execute():u.execute()}),h.command(`cleanup`).description(`Remove all API keys and credentials from configurations`).action(()=>{d.execute()}),h.command(`chat`).option(`-m, --mode <mode>`,`Mode: build, test, or research`,`build`).option(`-c, --connector <name>`,`Connector name`).option(`-a, --action <name>`,`Action name`).option(`-g, --goal <goal>`,`Initial goal/message`).option(`-t, --temperature <number>`,`Temperature (0-1, default: 0.5)`,parseFloat).option(`-v, --verbose`,`Enable verbose logging`).description(`Start an interactive chat session with the agent (use /commands in chat)`).action(async t=>{let n=[`build`,`test`,`research`];t.mode&&!n.includes(t.mode)&&(e._.error(`❌ Error: Invalid mode "${t.mode}". Must be one of: ${n.join(`, `)}`),process.exit(1)),t.temperature!==void 0&&(isNaN(t.temperature)&&(e._.error(`❌ Error: Temperature must be a valid number`),process.exit(1)),(t.temperature<0||t.temperature>1)&&(e._.error(`❌ Error: Temperature must be between 0 and 1`),process.exit(1))),f.execute({mode:t.mode,connector:t.connector,action:t.action,goal:t.goal,temperature:t.temperature,verbose:t.verbose})}),this.program.command(`update`).option(`-f, --force`,`Force reinstall even if already on latest version`).description(`Update the CLI to the latest version`).action(e=>{m.execute({force:e.force})}),this.program.command(`version`).description(`Show version information`).action(async()=>{e._.log(`${n.default.inverse.greenBright(`StackOne`)} ${n.default.grey(`CLI`)} ${n.default.whiteBright(this.version)}`),Pe(!0),process.exit(0)})}run(){process.argv.includes(`version`)||Pe(),this.program.parse(process.argv)}};Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Be}});
|
|
116
|
+
Exiting watch mode...`)),process.exit(0)};xe(),e._.start(`Validating connectors...`);let c=await Ee(o);t=Ce(t,c||{}),we(t,o),a.start();let l=r(o,{persistent:!0,ignoreInitial:!0}),u=async r=>{if(!r.endsWith(`.s1.yaml`)&&!r.endsWith(`s1.partial.yaml`))return;let i=r.endsWith(`s1.partial.yaml`)?await Oe(r):[r];if(!(!i||i.length===0)){e.d(),a.stop(),xe(),e._.log(n.default.gray(`File change detected: ${r}`)),e._.start(`Validating connectors...`);for(let e of i){let n=await Ee(e);t=Ce(t,n||{})}we(t,o),a.start()}};l.on(`change`,async e=>await u(e)),process.stdin.on(`data`,e=>{e.toString()===`q`&&s()}),process.on(`SIGINT`,()=>{s()})}else await Ee(o,e._),process.exit(0)}};const Ce=(e,t)=>{for(let[n,r]of Object.entries(t))e[n]=r;return e},we=(t,r)=>{e.d(),xe();let i=0,a=0;for(let[n,r]of Object.entries(t))r===null?i++:(e._?.error(`Connector ${e.g(n)} is not valid`),e.f(r,!0),a++);e._.log(``),e._.log(n.default.blue.inverse(` Validation Summary `)),e._.log(`Connectors path: ${e.g(r)}`),e._.log(`${i===0?n.default.red(`0`):n.default.green(i)} valid, ${a===0?n.default.green(`0`):n.default.red(a)} invalid connectors\n`)},Te=async e=>{let t=[],n=await(0,O.readdir)(e);for(let r of n){let n=(0,f.join)(e,r),i=await(0,O.stat)(n);i.isDirectory()?t.push(...await Te(n)):i.isFile()&&r.endsWith(`.s1.yaml`)&&t.push(n)}return t},Ee=async(t,r)=>{let i=await(0,O.stat)(t),a={};if(i.isDirectory()){let i=await Te(t);if(i.length===0)return r?.error(`No StackOne connector found in ${e.h(t)}`),r?.log(`Connector files need to have the extension ${e.g(`*.s1.yaml`)}`),null;let o=0,s=0;for(let e of i){let t=await De(e,r);t===null?o++:(r?.log(``),s++),a[e]=t}return r?.log(``),r?.log(n.default.blue.inverse(` Validation Summary `)),r?.log(`${o===0?n.default.red(`0`):n.default.green(o)} valid, ${s===0?n.default.green(`0`):n.default.red(s)} invalid connectors`),a}else if(i.isFile()&&t.endsWith(`s1.yaml`))return a[t]=await De(t,r),a;else if(i.isFile()&&t.endsWith(`partial.yaml`)){r?.error(`Partial connector files cannot be validated directly`),r?.log(`The file ${e.h(t)} is a partial connector file.`);let n=await Oe(t);return n&&n?.length>0&&r?.log(`Did you mean ${e.g(n[0])}?`),null}else return r?.error(`No StackOne connector found in ${e.h(t)}`),r?.log(`Connector files need to have the extension ${e.g(`*.s1.yaml`)}`),null},De=async(t,n)=>{let r=(0,C.validateYamlConnector)((0,C.loadConnector)(t)),i=r?.errors??[];if(r.success){let r=t.split(`/`).pop()||t;return n?.success(`Connector ${e.g(r)} is valid!`),null}else if(i.length>0)return n?.error(`Connector ${e.g(t)} is not valid`),n&&e.f(i,!0),i;else return n?.error(`Connector ${e.g(t)} is not valid. Please check the file for errors`),[]},Oe=async e=>{let t=(0,f.dirname)(e);try{return(await(0,O.readdir)(t)).filter(e=>e.endsWith(`.s1.yaml`))?.map(e=>(0,f.join)(t,e))}catch{}};function ke(){let e=process.env.LANGSMITH_API_KEY,t=process.env.LANGSMITH_PROJECT||`stackone-agent-cli`;e&&((0,i.initLangSmith)({apiKey:e,projectName:t,enabled:!0,metadata:{source:`cli`,version:process.env.npm_package_version||`unknown`}}),process.env.VERBOSE&&console.log(`[Telemetry] LangSmith initialized for project:`,t))}const Ae=`@stackone/cli`,je=2880*60*1e3,Me=(0,s.join)((0,o.homedir)(),`.stackone`),Ne=(0,s.join)(Me,`version-check.json`),Pe=(e=!1)=>{let t=Re(),n=Date.now();if(e||!t||n-t.lastCheckTime>1728e5){let e=Fe();e&&Ie(e)&&Le(e),ze({lastCheckTime:n})}},Fe=()=>{try{return(0,m.execSync)(`npm view @stackone/cli version`,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:15e3}).trim()}catch{return null}},Ie=e=>{try{let t=A();return D.default.gt(e,t)}catch{return!1}},Le=t=>{let r=A(),i=`Update available: ${n.default.dim(r)} → ${n.default.green(t)}`,a=`\n\nRun ${n.default.cyan(`stackone update`)} to update`;e._.box(i,a)},Re=()=>{try{if(!(0,a.existsSync)(Ne))return null;let e=(0,a.readFileSync)(Ne,`utf-8`);return JSON.parse(e)}catch{return null}},ze=e=>{try{(0,a.existsSync)(Me)||(0,a.mkdirSync)(Me,{recursive:!0}),(0,a.writeFileSync)(Ne,JSON.stringify(e,null,2),`utf-8`)}catch{}};var Be=class{constructor(e=new r.Command,t=A()){this.program=e,this.version=t,ke(),this.setupProgram(),this.registerCommands()}setupProgram(){this.program.name(`stackone`).description(`StackOne CLI`).version(this.version,`-v, --version`)}registerCommands(){let t=new le,i=new Q,a=new de,o=new oe,s=new se,c=new Se,l=new ie,u=new R,d=new F,f=new M,p=new ve,m=new be;this.program.configureOutput({writeOut:e=>process.stdout.write(e),writeErr:e=>process.stderr.write(e),outputError:(e,t)=>{t(n.default.red(e))}}),this.program.command(`init`).option(`-e, --env <environment>`,`Specify the environment for the configuration profile`).description(`Initialize & create a StackOne CLI configuration profile`).action(e=>{t.execute({environment:e.env})}),this.program.command(`push`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new r.Argument(`<path>`,`Connector file or directory to push`)).description(`Push a connector to the StackOne registry`).action((e,t)=>{i.execute({profile:t.profile,fileOrDir:e,apiUrl:t.apiUrl,apiKey:t.apiKey})}),this.program.command(`drop`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new r.Argument(`<connector>`,`Connector identifier in format provider_key@version`)).description(`Drop a connector from the StackOne registry`).action((e,t)=>{o.execute({profile:t.profile,connector:e,apiUrl:t.apiUrl,apiKey:t.apiKey})}),this.program.command(`get`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-c, --connector <connector>`,`Connector identifier in format provider_key@version or provider_key (defaults to latest)`).option(`--account-id <account-id>`,`Account ID to fetch connector from`).option(`-f, --format <format>`,`Output format: yaml or json (default: yaml)`,`yaml`).option(`-o, --output-file <output-file>`,`File to write the output to`).description(`Get a connector from the StackOne registry`).action(e=>{s.execute({profile:e.profile,connector:e.connector,accountId:e.accountId,format:e.format,outputFile:e.outputFile,apiUrl:e.apiUrl,apiKey:e.apiKey})}),this.program.command(`pull`).option(`-c, --connector <connector>`,`Connector identifier in format provider_key@version or provider_key`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-o, --output <path>`,`Output directory for the connectors files (default: ./connectors)`).description(`Pull a connector configuration from StackOne registry to local filesystem`).action(e=>{a.execute({profile:e.profile,connector:e.connector,outputPath:e.output,apiUrl:e.apiUrl,apiKey:e.apiKey})}),this.program.command(`validate`).option(`-w, --watch`,`Run in watch mode`).addArgument(new r.Argument(`<path>`,`Connector file or directory with connectors to validate`)).description(`Validate a StackOne connector`).action((e,t)=>{c.execute({watchMode:t.watch,fileOrDir:e})}),this.program.command(`run`).option(`--connector <connector>`,`Connector file, inline YAML, or identifier (provider_key@version or provider_key for latest)`).option(`--action <action>`,`Action to execute on the connector (path to file or inline string action code)`).option(`--action-id <action-id>`,`Action ID to execute on the connector`).option(`--account <account>`,`Account details to use for running the connector (path to file or inline string account data)`).option(`--account-id <account-id>`,`Account ID to use for running the connector against (fetches connector from API if --connector not provided)`).option(`--params <params>`,`Action parameters (path to file or inline string with JSON parameters)`).option(`--credentials <credentials>`,`Credentials to use (path to file or inline string with JSON credentials)`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-o, --output-file <output-file>`,`File to write the output to`).option(`-d, --debug`,`Enables debug mode to include more details in the action execution output`).description(`Run a connector action`).action(e=>{p.execute({connector:e.connector,action:e.action,actionId:e.actionId,account:e.account,accountId:e.accountId,params:e.params,credentials:e.credentials,profile:e.profile,outputFile:e.outputFile,debug:e.debug,apiUrl:e.apiUrl,apiKey:e.apiKey})});let h=this.program.command(`agent`).description(`StackOne agent commands`);h.command(`setup`).option(`-g, --global`,`Setup global configuration`).option(`-l, --local`,`Setup local project configuration`).description(`Setup StackOne agent (global or local)`).action(e=>{e.global?l.execute():u.execute()}),h.command(`cleanup`).description(`Remove all API keys and credentials from configurations`).action(()=>{d.execute()}),h.command(`chat`).option(`-m, --mode <mode>`,`Mode: build, test, or research`,`build`).option(`-c, --connector <name>`,`Connector name`).option(`-a, --action <name>`,`Action name`).option(`-g, --goal <goal>`,`Initial goal/message`).option(`-t, --temperature <number>`,`Temperature (0-1, default: 0.5)`,parseFloat).option(`-v, --verbose`,`Enable verbose logging`).description(`Start an interactive chat session with the agent (use /commands in chat)`).action(async t=>{let n=[`build`,`test`,`research`];t.mode&&!n.includes(t.mode)&&(e._.error(`❌ Error: Invalid mode "${t.mode}". Must be one of: ${n.join(`, `)}`),process.exit(1)),t.temperature!==void 0&&(isNaN(t.temperature)&&(e._.error(`❌ Error: Temperature must be a valid number`),process.exit(1)),(t.temperature<0||t.temperature>1)&&(e._.error(`❌ Error: Temperature must be between 0 and 1`),process.exit(1))),f.execute({mode:t.mode,connector:t.connector,action:t.action,goal:t.goal,temperature:t.temperature,verbose:t.verbose})}),this.program.command(`update`).option(`-f, --force`,`Force reinstall even if already on latest version`).description(`Update the CLI to the latest version`).action(e=>{m.execute({force:e.force})}),this.program.command(`version`).description(`Show version information`).action(async()=>{e._.log(`${n.default.inverse.greenBright(`StackOne`)} ${n.default.grey(`CLI`)} ${n.default.whiteBright(this.version)}`),Pe(!0),process.exit(0)})}run(){process.argv.includes(`version`)||Pe(),this.program.parse(process.argv)}};Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Be}});
|
|
@@ -1,24 +1,31 @@
|
|
|
1
|
-
import{_ as e,a as t,c as n,d as r,f as i,g as a,h as o,i as s,l as c,m as l,n as u,o as d,p as f,r as p,t as m,u as h,v as g}from"./agentConfig-BljaB-6S.mjs";import{n as _,r as v,t as ee}from"./setupMigration-DdeVl8db.mjs";import y from"chalk";import{Argument as b,Command as x}from"commander";import{AgentRuntime as S,builtinSkills as C,customSkills as te,initLangSmith as ne,loadBundledSkills as re,skillLoader as w}from"@stackone/agent-harness";import*as T from"node:fs";import{existsSync as E,mkdirSync as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import{_ as e,a as t,c as n,d as r,f as i,g as a,h as o,i as s,l as c,m as l,n as u,o as d,p as f,r as p,t as m,u as h,v as g}from"./agentConfig-BljaB-6S.mjs";import{n as _,r as v,t as ee}from"./setupMigration-DdeVl8db.mjs";import y from"chalk";import{Argument as b,Command as x}from"commander";import{AgentRuntime as S,builtinSkills as C,customSkills as te,initLangSmith as ne,loadBundledSkills as re,skillLoader as w}from"@stackone/agent-harness";import*as T from"node:fs";import{existsSync as E,mkdirSync as D,readFileSync as O,writeFileSync as ie}from"node:fs";import*as ae from"node:os";import{homedir as oe}from"node:os";import*as k from"node:path";import{join as A}from"node:path";import{Box as j,Text as M,render as N,useApp as se,useInput as ce}from"ink";import P,{useCallback as le,useEffect as F,useRef as ue,useState as I}from"react";import de from"ink-spinner";import L,{readFileSync as R,readdirSync as fe,statSync as pe}from"fs";import z,{basename as me,dirname as he,join as B,resolve as ge}from"path";import{fileURLToPath as _e}from"url";import{exec as V,execSync as H}from"node:child_process";import{access as U,readFile as ve,writeFile as W}from"node:fs/promises";import{promisify as G}from"node:util";import K from"ora";import{stdin as ye,stdout as q}from"node:process";import{createInterface as J}from"node:readline";import be from"inquirer";import{isMissing as Y,isObject as X,notMissing as Z,z as Q}from"@stackone/utils";import{cancel as xe,confirm as Se,intro as Ce,isCancel as we,outro as Te,password as Ee,select as De,text as Oe}from"@clack/prompts";import{loadConnector as ke,runAction as Ae,validateYamlConnector as je}from"@stackone/connect-sdk";import{diffLines as Me}from"diff";import{createInterface as Ne}from"readline";import{HttpClient as Pe}from"@stackone/transport";import Fe from"semver";import{readdir as Ie,stat as Le}from"fs/promises";function Re(e){return e.replace(/\*\*\*(.+?)\*\*\*/g,`$1`).replace(/\*\*(.+?)\*\*/g,`$1`).replace(/\*(.+?)\*/g,`$1`).replace(/__(.+?)__/g,`$1`).replace(/_(.+?)_/g,`$1`).replace(/^#{1,6}\s+(.+)$/gm,`$1`).replace(/```[\s\S]*?```/g,``).replace(/`(.+?)`/g,`$1`).replace(/\[([^\]]+)\]\([^\)]+\)/g,`$1`).replace(/!\[([^\]]*)\]\([^\)]+\)/g,`$1`).replace(/^[-*_]{3,}$/gm,``).replace(/^>\s+/gm,``).trim()}const ze=({title:e,mode:t,connector:n,action:r,onSubmit:i,onExit:a,onStop:o,messages:s,currentToolCalls:c=[],isThinking:l=!1,isComplete:u=!1,error:d,isInterrupted:f=!1,commandHistory:p=[],streamingText:m=``,usage:h,detailViewData:g=null,onCloseDetailView:_,onResumeConversation:v,onToggleSkill:ee,onRewindTo:y,spawnedSubagentActive:b=!1,spawnedSubagentName:x=`Subagent`,spawnedSubagentComplete:S=!1,queuedMessages:C=[],isProcessingQueue:te=!1,enabledSkills:ne=[],initInfo:re})=>{let{exit:w}=se(),[T,E]=I(``),[D,O]=I(0),[ie,ae]=I(!0),oe=ue(0),[k,A]=I(0),N=ue(!1),[L,R]=I(!1),fe=ue(s),[pe,z]=I(-1),me=ue(p),he=ue(``),[B,ge]=I([]),[_e,V]=I(0),[H,U]=I(0),[ve,W]=I(!1),[G,K]=I(!1),[ye,q]=I(!1),[J,be]=I(!1),Y=[`/commands`,`/skills`,`/tools`,`/mcp`,`/compact`,`/rewind`,`/resume`,`/exit`];F(()=>{N.current=L},[L]),F(()=>{oe.current=k},[k]),F(()=>{fe.current=s},[s]),F(()=>{me.current=p},[p]),F(()=>{he.current=T,T.startsWith(`/`)?(ge(Y.filter(e=>e.startsWith(T.toLowerCase()))),V(0)):(ge([]),V(0))},[T]),F(()=>{N.current||A(0)},[s]),ce(le((e,t)=>{let n=he.current,r=pe;if(t.escape&&(l||m||c.length>0)){o?.(),E(``),O(0),z(-1);return}if(t.escape&&b&&ye){q(!1);return}if(g){if(t.escape||t.ctrl&&e===`c`)if(ve){W(!1);return}else{_?.(),U(0);return}if(t.upArrow&&!ve){U(e=>e>0?e-1:g.items.length-1);return}if(t.downArrow&&!ve){U(e=>e<g.items.length-1?e+1:0);return}if(t.ctrl&&e===`o`&&g.type===`skills`){let e=g.items[H];ee&&ee(e.name);return}if(t.return){if(ve)return;if(g.type===`resume`){let e=g.items[H];e.messages&&v&&(v(e.messages),_?.(),U(0));return}if(g.type===`rewind`){let e=g.items[H];e.index!==void 0&&y&&(y(e.index),_?.(),U(0));return}W(!0);return}return}if(t.ctrl&&e===`o`){b?q(e=>!e):be(e=>!e);return}if(t.ctrl&&e===`u`){E(``),O(0),z(-1),K(!1);return}if(t.ctrl&&e===`c`||e===``)if(n.trim()){E(``),O(0),z(-1),K(!1);return}else if(G){a(),w();return}else{K(!0);return}if(t.shift&&t.return){E(e=>e.slice(0,D)+`
|
|
2
|
+
`+e.slice(D)),O(e=>e+1);return}if(t.ctrl&&e===`a`){O(0);return}if(t.ctrl&&e===`e`){O(n.length);return}if((t.alt||t.meta)&&t.leftArrow&&!t.ctrl&&!t.shift){let e=n.slice(0,D).match(/\S+\s*$/);O(e?D-e[0].length:0);return}if((t.alt||t.meta)&&t.rightArrow&&!t.ctrl&&!t.shift){let e=n.slice(D).match(/^\s*\S+/);O(e?D+e[0].length:n.length);return}if(t.home||e===`\x1B[H`||e===`\x1BOH`){O(0);return}if(t.end||e===`\x1B[F`||e===`\x1BOF`){O(n.length);return}if(process.platform===`darwin`&&t.meta&&t.leftArrow&&!t.alt){O(0);return}if(process.platform===`darwin`&&t.meta&&t.rightArrow&&!t.alt){O(n.length);return}if(process.platform===`darwin`&&t.meta&&t.upArrow){O(0);return}if(process.platform===`darwin`&&t.meta&&t.downArrow){O(n.length);return}if(t.ctrl&&t.leftArrow&&process.platform!==`darwin`){let e=n.slice(0,D).match(/\S+\s*$/);O(e?D-e[0].length:0);return}if(t.ctrl&&t.rightArrow&&process.platform!==`darwin`){let e=n.slice(D).match(/^\s*\S+/);O(e?D+e[0].length:n.length);return}if(t.upArrow){if(B.length>0){V(e=>e>0?e-1:B.length-1);return}let e=n.slice(0,D).lastIndexOf(`
|
|
3
|
+
`);if(e!==-1){let t=n.lastIndexOf(`
|
|
4
|
+
`,e-1),r=D-e-1,i=e-t-1;O(Math.max(0,e-i+Math.min(r,i-1),t+1));return}let t=me.current;if(t.length>0&&(n===``||r>=0)){z(e=>{let n=e<0?t.length-1:Math.max(0,e-1),r=t[n]||``;return E(r),O(r.length),n});return}let i=Math.max(0,fe.current.length-5),a=Math.min(oe.current+5,i);A(a),R(a>0);return}if(t.downArrow){if(B.length>0){V(e=>e<B.length-1?e+1:0);return}let e=n.indexOf(`
|
|
5
|
+
`,D);if(e!==-1){let t=D-(n.lastIndexOf(`
|
|
6
|
+
`,D-1)+1),r=n.indexOf(`
|
|
7
|
+
`,e+1),i=(r===-1?n.length:r)-e-1;O(e+1+Math.min(t,i));return}let t=me.current;if(r>=0){z(e=>{let n=e>=t.length-1?-1:e+1,r=n<0?``:t[n]||``;return E(r),O(r.length),n});return}let i=Math.max(oe.current-5,0);A(i),R(i>0);return}if(t.return){if(B.length>0){let e=B[_e];ge([]),V(0),E(``),O(0),i(e);return}T.trim()&&(i(T.trim()),E(``),O(0),z(-1),A(0),R(!1));return}if(t.backspace||t.delete){t.backspace&&D>0?(E(e=>e.slice(0,D-1)+e.slice(D)),O(e=>Math.max(0,e-1))):t.delete&&D<n.length&&E(e=>e.slice(0,D)+e.slice(D+1)),z(-1);return}if(t.leftArrow&&!t.meta&&!t.alt&&!t.ctrl){O(e=>Math.max(0,e-1));return}if(t.rightArrow&&!t.meta&&!t.alt&&!t.ctrl){O(e=>Math.min(n.length,e+1));return}if(t.tab&&n.startsWith(`/`)){let e=Y.filter(e=>e.startsWith(T.toLowerCase()));e.length===1&&(E(e[0]),O(e[0].length));return}if(e){if(t.meta||t.alt||t.ctrl)return;E(t=>t.slice(0,D)+e+t.slice(D)),O(e=>e+1),z(-1),K(!1)}},[i,a,w,T,D,pe,Y,B,_e,g,ve,_,G,b,S,ye,v,H,l,m,c,o,ee,y])),F(()=>{u&&ae(!1)},[u]);let X=`\x1B[38;2;0;175;102m`,Z=`\x1B[0m`,Q=`${X} ╔═════════╗${Z} ▄▖▗ ▌ ▄▖ ▄▖ ▗ ${X}╔═════════╗${Z}
|
|
8
|
+
${X} ║ ┌────╚════╗${Z} ▚ ▜▘▀▌▛▘▙▘▌▌▛▌█▌ ▌▌▛▌█▌▛▌▜▘ ${X}║ ┌────╚════╗${Z}
|
|
9
|
+
${X} ╚════╗────┘ ║${Z} ▄▌▐▖█▌▙▖▛▖▙▌▌▌▙▖ ▛▌▙▌▙▖▌▌▐▖ ${X}╚════╗────┘ ║${Z}
|
|
10
|
+
${X} ╚═════════╝${Z} ▄▌ ${X}╚═════════╝${Z}`;return P.createElement(j,{flexDirection:`column`,padding:2},P.createElement(j,{flexDirection:`column`,marginBottom:2,marginTop:1},P.createElement(M,null,Q,`
|
|
5
11
|
|
|
6
12
|
|
|
7
13
|
|
|
8
|
-
`),
|
|
14
|
+
`),P.createElement(M,{dimColor:!0},`⚠️ Data collected may be used for training and monitoring purposes`),s.length===0&&P.createElement(M,{dimColor:!0},`
|
|
9
15
|
|
|
10
16
|
|
|
11
|
-
`,`Welcome to `,t,` mode! What would you like to do?`)),
|
|
12
|
-
... (truncated)`)}return
|
|
17
|
+
`,`Welcome to `,t,` mode! What would you like to do?`)),P.createElement(j,{flexDirection:`column`,marginBottom:1},(()=>{let e=s.findIndex(e=>e.isSubagent),t=s.map((e,t)=>e.isSubagent?t:-1).reduce((e,t)=>Math.max(e,t),-1),n=e===-1?s:s.slice(0,e),r=t===-1?[]:s.slice(t+1),i=(e,t,n)=>{let r=e.role===`system`&&e.content.startsWith(`TOOL:`),i=e.role===`system`&&e.content.startsWith(`TOOL_START:`),a=e.role===`user`?`white`:e.role===`assistant`||r||i?`#00AF66`:`gray`,o=e.role===`user`?`❯ You`:e.role===`assistant`?`◆ StackOne Agent`:`ℹ System`,s=e.content,c=!1,l=!1;if(i&&(o=`🔧 Tool • ${e.content.split(`|||`)[1]||``}`,s=``,l=!f),r){let t=e.content.split(`|||`),n=t[0].replace(`TOOL:`,``),r=t[1]||``;o=`🔧 Tool • ${n}`,!J&&r.length>500?(s=r.slice(0,500),c=!0):s=r}return P.createElement(j,{key:`${n}-${e.timestamp.getTime()}-${t}-${e.role}`,marginBottom:1,flexDirection:`column`},P.createElement(j,null,l&&P.createElement(M,{color:a},P.createElement(de,{type:`dots`})),P.createElement(M,{bold:!0,color:a},l?` `:``,o,P.createElement(M,{dimColor:!0},` `,`• `,e.timestamp.toLocaleTimeString()))),s&&P.createElement(j,{paddingLeft:2,flexDirection:`column`},P.createElement(M,{color:r?`gray`:void 0,italic:r},Re(s)),c&&P.createElement(M,{dimColor:!0,italic:!0},`... (truncated, press Ctrl+O to expand)`)))};return P.createElement(P.Fragment,null,n.map((e,t)=>i(e,t,`before`)),(b||S)&&P.createElement(j,{marginBottom:0,marginTop:0,borderStyle:`single`,borderColor:`#00AF66`,paddingX:2,paddingY:1,flexDirection:`column`,height:ye?`100%`:void 0},P.createElement(M,{bold:!0,color:`#00AF66`},S?`✓`:`⚡`,` Subprocess:`,` `,x,` `,S?`(Complete)`:``,` `,ye?`(Expanded)`:``),P.createElement(j,{marginTop:1},P.createElement(M,{dimColor:!0},S?ye?`Press Ctrl+O or ESC to collapse`:`Press Ctrl+O to expand`:ye?`Running... Press Ctrl+O or ESC to collapse`:`Running... Press Ctrl+O to expand`)),ye?P.createElement(P.Fragment,null,s.filter(e=>e.isSubagent&&!e.content.startsWith(`TOOL_START:`)).map((e,t)=>{let n=e.role===`system`&&e.content.startsWith(`TOOL:`),r=e.role===`assistant`?`⚡ Subagent`:`ℹ System`,i=e.content;if(n){let t=e.content.split(`|||`),n=t[0].replace(`TOOL:`,``),a=t[1]||``;r=`🔧 Tool • ${n}`,i=a.slice(0,500),a.length>500&&(i+=`
|
|
18
|
+
... (truncated)`)}return P.createElement(j,{key:`${e.timestamp.getTime()}-${t}-${e.role}-subagent`,marginTop:1,flexDirection:`column`},P.createElement(M,{bold:!0,color:`#00AF66`},r,P.createElement(M,{dimColor:!0},` `,`•`,` `,e.timestamp.toLocaleTimeString())),P.createElement(j,{paddingLeft:2},P.createElement(M,{color:n?`gray`:`#00AF66`,dimColor:n},Re(i))))}),!S&&!f&&l&&c.length===0&&P.createElement(j,{marginTop:1},P.createElement(M,{color:`#00AF66`},P.createElement(de,{type:`dots`})),P.createElement(M,{dimColor:!0},` Thinking...`)),!S&&!f&&c.length>0&&P.createElement(j,{flexDirection:`column`,marginTop:1},c.map((e,t)=>P.createElement(j,{key:t,marginBottom:1},e.status===`running`&&P.createElement(M,{color:`#00AF66`},P.createElement(de,{type:`dots`})),P.createElement(M,{color:`#00AF66`},` `,`🔧 `,e.name,e.status===`running`&&`...`,e.status===`completed`&&` ✓`)))),!S&&m&&!f&&P.createElement(j,{marginTop:1},P.createElement(M,{color:`#00AF66`},Re(m)))):P.createElement(P.Fragment,null,s.filter(e=>e.isSubagent&&!e.content.startsWith(`TOOL_START:`)&&e.role!==`system`||e.content.startsWith(`TOOL:`)).slice(-2).map((e,t)=>{let n=e.role===`system`&&e.content.startsWith(`TOOL:`),r=e.content;if(n){let t=e.content.split(`|||`),n=t[0].replace(`TOOL:`,``),i=t[1]||``;r=`🔧 ${n}: ${i.slice(0,100)}${i.length>100?`...`:``}`}let i=r.split(`
|
|
13
19
|
`).slice(0,2).join(`
|
|
14
|
-
`);return
|
|
15
|
-
`).length>2&&`...`))}),!S&&!f&&l&&c.length===0&&
|
|
20
|
+
`);return P.createElement(j,{key:t,marginTop:1},P.createElement(M,{color:`#00AF66`,dimColor:n},Re(i),r.split(`
|
|
21
|
+
`).length>2&&`...`))}),!S&&!f&&l&&c.length===0&&P.createElement(j,{marginTop:1},P.createElement(M,{color:`#00AF66`},P.createElement(de,{type:`dots`})),P.createElement(M,{dimColor:!0},` Thinking...`)),!S&&!f&&c.length>0&&P.createElement(j,{flexDirection:`column`,marginTop:1},c.slice(-2).map((e,t)=>P.createElement(j,{key:t,marginBottom:1},e.status===`running`&&P.createElement(M,{color:`#00AF66`},P.createElement(de,{type:`dots`})),P.createElement(M,{color:`#00AF66`},` `,`🔧 `,e.name,e.status===`running`&&`...`,e.status===`completed`&&` ✓`))),c.length>2&&P.createElement(M,{dimColor:!0},`... and`,` `,c.length-2,` more (Ctrl+O to expand)`)),!S&&m&&P.createElement(j,{marginTop:1},P.createElement(M,{color:`#00AF66`},Re(m).split(`
|
|
16
22
|
`).slice(0,2).join(`
|
|
17
23
|
`),Re(m).split(`
|
|
18
24
|
`).length>2&&`
|
|
19
|
-
...`)))),r.map((e,t)=>i(e,t,`after`)))})(),m&&!b&&
|
|
20
|
-
`).
|
|
21
|
-
`)
|
|
25
|
+
...`)))),r.map((e,t)=>i(e,t,`after`)))})(),m&&!b&&!f&&P.createElement(j,{marginBottom:1,flexDirection:`column`},P.createElement(M,{bold:!0,color:`#00AF66`},`◆ StackOne Agent`,P.createElement(M,{dimColor:!0},` • `,new Date().toLocaleTimeString())),P.createElement(j,{paddingLeft:2},P.createElement(M,null,Re(m))))),!b&&!f&&c.length>0&&P.createElement(j,{marginBottom:1},P.createElement(M,{dimColor:!0},`🔧`,` `,c.length>1?`${c.length} tools running`:Array.from(c.values())[0].name,`...`)),!b&&!f&&l&&c.length===0&&P.createElement(j,{marginBottom:1},P.createElement(M,{color:`#00AF66`},P.createElement(de,{type:`dots`})),P.createElement(M,{dimColor:!0},` Thinking...`)),f&&P.createElement(j,{marginTop:1},P.createElement(M,{color:`red`},`⏺ Interrupted · What should the StackOne Agent do instead?`)),d&&P.createElement(j,{marginBottom:1,borderStyle:`single`,borderColor:`red`,paddingX:2,paddingY:1,flexDirection:`column`},P.createElement(M,{color:`red`},`✗ `,d),P.createElement(j,{marginTop:1},P.createElement(M,{dimColor:!0},`Press Enter to try again or Ctrl+C to exit`))),u&&P.createElement(j,{marginBottom:1,borderStyle:`single`,borderColor:`#00AF66`,paddingX:2},P.createElement(M,{color:`#00AF66`},`✓ Complete`)),g&&P.createElement(j,{marginBottom:1,borderStyle:`single`,borderColor:`#00AF66`,paddingX:2,paddingY:1,flexDirection:`column`},ve?P.createElement(P.Fragment,null,P.createElement(M,{bold:!0,color:`#00AF66`},g.items[H].name),P.createElement(j,{marginTop:1},P.createElement(M,{dimColor:!0},g.items[H].description)),g.type===`skills`&&P.createElement(j,{flexDirection:`column`},g.items[H].version?P.createElement(M,{dimColor:!0},`Version:`,` `,String(g.items[H].version)):null,g.items[H].author?P.createElement(M,{dimColor:!0},`Author:`,` `,String(g.items[H].author)):null,g.items[H].tags&&Array.isArray(g.items[H].tags)?P.createElement(M,{dimColor:!0},`Tags:`,` `,g.items[H].tags.join(`, `)):null,P.createElement(M,{dimColor:!0},`Size:`,` `,String(g.items[H].size)),g.items[H].tokens?P.createElement(M,{dimColor:!0},`Tokens: ~`,g.items[H].tokens.toLocaleString()):null,P.createElement(M,{dimColor:!0},`Resources:`,` `,String(g.items[H].resources),` `,`files`),P.createElement(M,{dimColor:!0},`Path:`,` `,String(g.items[H].path))),g.type===`tools`&&P.createElement(j,{flexDirection:`column`},P.createElement(j,{marginTop:1},P.createElement(M,{dimColor:!0},`Category:`,` `,String(g.items[H].category))),P.createElement(j,{marginTop:1},P.createElement(M,{bold:!0},`Input Parameters:`)),g.items[H].inputSchema?P.createElement(j,{marginTop:1,paddingLeft:2,flexDirection:`column`},(()=>{let e=g.items[H].inputSchema,t=e.properties||{},n=e.required||[];return Object.entries(t).map(([e,t])=>P.createElement(j,{key:e,flexDirection:`column`,marginBottom:1},P.createElement(M,null,e,n.includes(e)?` *`:``,P.createElement(M,{dimColor:!0},` `,`(`,t.type?String(t.type):`any`,`)`)),t.description?P.createElement(j,{paddingLeft:2},P.createElement(M,{dimColor:!0},String(t.description))):null))})(),P.createElement(j,{marginTop:1},P.createElement(M,{dimColor:!0},`* = required parameter`))):P.createElement(j,{marginTop:1,paddingLeft:2},P.createElement(M,{dimColor:!0},`No parameters`)),P.createElement(j,{marginTop:1},P.createElement(M,{bold:!0},`Output:`)),P.createElement(j,{marginTop:1,paddingLeft:2},P.createElement(M,{dimColor:!0},`Returns JSON with tool execution results`))),P.createElement(j,{marginTop:1},P.createElement(M,{dimColor:!0},`Press Esc to go back`))):P.createElement(P.Fragment,null,P.createElement(M,{bold:!0,color:`#00AF66`},g.type===`skills`?`📚 Skills (${g.items.filter(e=>e.enabled).length}/8 connected, max 8 skills)`:g.type===`tools`?`🔧 Tools (${g.items.length})`:g.type===`mcp`?`📡 MCP Servers (${g.items.filter(e=>e.connected).length}/${g.items.length} connected)`:g.type===`rewind`?`⏮️ Command History (${g.items.length})`:`💬 Recent Conversations (${g.items.length})`),P.createElement(j,{flexDirection:`column`,marginTop:1},g.items.map((e,t)=>{let n=t===H?`❯ `:` `,r=process.stdout.columns||80,i=Math.min(r-10,120),a=(e.name||``).replace(/\n/g,` ⏎ `),o=``;g.type===`skills`?o=e.enabled?`● `:`○ `:g.type===`mcp`&&(o=e.connected?`● `:`○ `);let s=g.type===`skills`&&e.tokens?` (~${e.tokens.toLocaleString()} tokens)`:``,c=i-(n.length+o.length+a.length+s.length)-5,l=``;if(e.description&&c>10){let t=String(e.description).replace(/\n/g,` ⏎ `);l=t.length>c?` - ${t.slice(0,c)}...`:` - ${t}`}let u=`${n}${o}${a}${s}${l}`,d=u.slice(0,i);return P.createElement(M,{key:t,color:t===H?`#00AF66`:`gray`},d,u.length>i?`...`:``)})),P.createElement(j,{marginTop:1},P.createElement(M,{dimColor:!0},g.type===`skills`?`↑↓ Navigate • Ctrl+O to toggle • Enter for details • Esc to close`:g.type===`resume`?`↑↓ Navigate • Enter to resume • Esc to close`:g.type===`rewind`?`↑↓ Navigate • Enter to rewind to • Esc to close`:`↑↓ Navigate • Enter for details • Esc to close`)))),C.length>0&&P.createElement(j,{flexDirection:`column`,marginBottom:1},C.map((e,t)=>P.createElement(j,{key:t,marginBottom:t<C.length-1?1:0},P.createElement(M,{dimColor:!0},`📬 `),P.createElement(M,null,e.content))),te&&P.createElement(M,{dimColor:!0,italic:!0},`Processing...`)),ie&&!u&&!g&&P.createElement(P.Fragment,null,P.createElement(j,{borderStyle:`double`,borderColor:`white`,paddingX:2,flexDirection:`column`},(()=>{let e=T.split(`
|
|
26
|
+
`),t=0;return e.map((n,r)=>{let i=t,a=i+n.length;t=a+1;let o=D>=i&&D<=a,s=D===a&&r<e.length-1;if(o||s){let e=D-i,t=n.slice(0,e),a=s?` `:n.charAt(e)||` `,o=s?``:n.slice(e+1);return P.createElement(j,{key:r},r===0&&P.createElement(M,{color:`#00AF66`},`❯ `),P.createElement(M,{color:`white`},t),P.createElement(M,{backgroundColor:`white`,color:`black`,bold:!0},a),P.createElement(M,{color:`white`},o))}else return P.createElement(j,{key:r},r===0&&P.createElement(M,{color:`#00AF66`},`❯ `),P.createElement(M,{color:`white`},n||` `))})})()),G&&P.createElement(j,{marginTop:1,paddingLeft:2},P.createElement(M,{color:`yellow`},`Press Ctrl+C again to exit`)),B.length>0&&P.createElement(j,{marginTop:1,paddingLeft:2,flexDirection:`column`},B.map((e,t)=>P.createElement(j,{key:e},P.createElement(M,{color:t===_e?`#00AF66`:`gray`},t===_e?`❯ `:` `,e))))),h&&(()=>{let e=100-(h.input_tokens+h.output_tokens)/1e6*100,t=e>50?`green`:e>20?`yellow`:`red`,n=e<10;return P.createElement(j,{marginTop:1,flexDirection:`column`},P.createElement(M,{dimColor:!0},`📊 Model: Sonnet 4.5 • 🧠 Context left:`,` `,P.createElement(M,{color:t},e.toFixed(1),`%`)),n&&P.createElement(M,{color:`red`},`⚠️ Context low (`,e.toFixed(1),`% remaining)`))})(),P.createElement(j,{marginTop:1},P.createElement(M,{dimColor:!0},ie?`Type message and press Enter • Shift+Enter for new line • `:``,(l||m||c.length>0)&&`ESC to stop • `,b?`Ctrl+O to expand subprocess • `:`Ctrl+O to expand tool outputs • `,`↑↓ to scroll • Ctrl+C to clear/exit`)))},Be=({directory:e,onConfirm:t,onCancel:n})=>{let{exit:r}=se(),[i,a]=I(0);ce((e,o)=>{o.upArrow?a(0):o.downArrow?a(1):o.return?i===0?(t(),r()):(n(),r()):o.escape&&(n(),r())});let o=`\x1B[38;2;0;175;102m`;return P.createElement(j,{flexDirection:`column`,padding:2},P.createElement(j,{borderStyle:`round`,borderColor:`#00AF66`,flexDirection:`column`,paddingX:2,paddingY:1},P.createElement(M,{bold:!0},`Do you trust the files in this folder?`),P.createElement(M,null),P.createElement(M,{dimColor:!0},e),P.createElement(M,null),P.createElement(M,null,`StackOne Agent may read, write, or execute files contained in this directory.`),P.createElement(M,null,`This can pose security risks, so only use files and commands from trusted sources.`),P.createElement(M,null),P.createElement(M,{color:i===0?o:`white`},i===0?`❯ `:` `,`1. Yes, proceed`),P.createElement(M,{color:i===1?o:`white`},i===1?`❯ `:` `,`2. No, exit`)),P.createElement(j,{marginTop:1},P.createElement(M,{dimColor:!0},`↑↓ to navigate • Enter to confirm • Esc to exit`)))},Ve=()=>{try{let e=B(he(_e(import.meta.url)),`..`,`package.json`);return JSON.parse(R(e,`utf8`)).version}catch{return`unknown`}};Ve();const He=({mode:t,connector:n,action:r,goal:i,verbose:a,temperature:o,apiKey:s})=>{let[c,l]=I([]),[u,d]=I(new Map),[f,p]=I(!1),[m,h]=I(),[g,_]=I(!1),[v,ee]=I(!0),[y,b]=I(),[x,ne]=I([]),[E,D]=I([]),[O,ie]=I([]),[oe,A]=I([]),[j,M]=I(``),[N,se]=I(),[ce,de]=I(!1),[L,R]=I(null),[fe,pe]=I(!1),z=ue(!1),[me,he]=I(``),[B,ge]=I(!1),[_e,V]=I([]),[H,U]=I(!1),[ve,W]=I(!1),G=ue(!1),K=ue({shouldStop:!1}),[ye,q]=I([]),J=ue(null),[be,Y]=I({claudeSkills:{count:0,names:[],totalSize:0},mcpServers:[],toolCounts:{total:0,builtin:[],mcpByServer:{}},errors:[]});F(()=>{let t=k.join(ae.homedir(),`.stackone`,`agent_history`);try{T.existsSync(t)&&A(T.readFileSync(t,`utf-8`).split(`
|
|
27
|
+
`).filter(e=>e.trim()))}catch(t){a&&e.error(`[History] Failed to load command history:`,t)}},[a]),F(()=>{(async()=>{let t={claudeSkills:{count:0,names:[],totalSize:0},mcpServers:[],toolCounts:{total:0,builtin:[],mcpByServer:{}},errors:[]};w.registerSkills(C),w.registerSkills(te);try{let e=await re();ie(e);let n=e.map(e=>e.name);ne(n),D(n.slice(0,8)),t.claudeSkills={count:e.length,names:n,totalSize:0}}catch(n){e.error(`[Skills] Failed to load bundled skills:`,n),t.errors.push(`Failed to load Claude Skills`)}try{let{loadBundledMCPConfigs:e,loadMultipleMCPServers:n}=await import(`@stackone/agent-harness`),r=e();if(r.length>0){let e=await n(r);for(let[n,r]of e.entries())r.length>0&&(w.registerSkills(r),t.mcpServers.push({name:n,count:r.length}))}}catch(e){t.errors.push(`MCP: ${e instanceof Error?e.message:String(e)}`)}let n=w.toToolAdapters(),r=n.filter(e=>!e.name.includes(`__`)),i=n.filter(e=>e.name.includes(`__`));t.toolCounts.total=n.length,t.toolCounts.builtin=r.map(e=>e.name),i.length>0&&(t.toolCounts.mcpByServer=i.reduce((e,t)=>{let[n]=t.name.split(`__`);return e[n]||(e[n]=[]),e[n].push(t.name.split(`__`)[1]),e},{})),Y(t),b(new S({apiKey:s,tools:n,temperature:o,verbose:a||!1,projectName:`stackone-agent-cli-chat`})),ee(!1)})()},[s,o,a]),F(()=>{G.current=ve},[ve]),F(()=>{if(N&&!ce){let e=N.input_tokens+N.output_tokens,t=(1e6-e)/1e6*100;if(t<10){let n={role:`system`,content:`⚠️ Context Warning\n\nYou have ${t.toFixed(1)}% context remaining (${(1e6-e).toLocaleString()} tokens).\n\nConsider using /compact to summarize the conversation and free up context.`,timestamp:new Date};l(e=>[...e,n]),de(!0)}}},[N,ce]);let X=le(async i=>{try{let e=c.filter(e=>e.role===`user`||e.role===`assistant`);if(e.length<2)return;let a=e.slice(0,6).map(e=>`${e.role}: ${e.content.slice(0,200)}`).join(`
|
|
28
|
+
`),o=await y?.generateConversationTitle(a);if(!o)return;await T.promises.mkdir(k.join(ae.homedir(),`.stackone`,`conversations`),{recursive:!0});let s=Date.now(),l=`${s}-${o.replace(/[^a-zA-Z0-9]/g,`-`).toLowerCase().slice(0,50)}.json`,u=k.join(ae.homedir(),`.stackone`,`conversations`,l);await T.promises.writeFile(u,JSON.stringify({title:o,timestamp:s,goal:i,messages:c.filter(e=>e.role!==`system`),mode:t,connector:n,action:r},null,2))}catch(t){e.error(`Failed to save conversation:`,t)}},[c,y,t,n,r]),Z=le(async(i,o=!1)=>{if(!y){h(`Runtime not initialized`);return}if(G.current&&!o){V(e=>[...e,{content:i,timestamp:new Date}]),J.current&&clearTimeout(J.current),J.current=setTimeout(()=>{xe()},3e4);return}if(h(void 0),_(!1),i===`/skills`){if(O.length===0){let e={role:`system`,content:`📚 No skills loaded. Skills will be loaded on startup.`,timestamp:new Date};l(t=>[...t,e]);return}R({type:`skills`,items:O.map(e=>({name:e.name,description:e.description,version:e.version,author:e.author,tags:e.tags,enabled:E.includes(e.name)}))});return}if(i===`/tools`){try{let e=w.toToolAdapters();if(e.length===0){let e={role:`system`,content:`🔧 No tools found
|
|
22
29
|
|
|
23
30
|
Tools are loaded automatically from built-in, custom, and MCP sources.`,timestamp:new Date};l(t=>[...t,e]);return}R({type:`tools`,items:e.map(e=>({name:e.name,description:e.description||`No description`,category:e.name.includes(`__`)?`MCP (${e.name.split(`__`)[0]})`:[`read_file`,`write_file`,`list_files`,`execute_command`].includes(e.name)?`Built-in`:`Custom`,inputSchema:e.inputSchema||e.input_schema}))})}catch(e){let t={role:`system`,content:`🔧 Error loading tools\n\n${e instanceof Error?e.message:String(e)}`,timestamp:new Date};l(e=>[...e,t])}return}if(i===`/commands`){let e={role:`system`,content:`📋 Available Commands:
|
|
24
31
|
|
|
@@ -29,13 +36,13 @@ Tools are loaded automatically from built-in, custom, and MCP sources.`,timestam
|
|
|
29
36
|
• /compact - Summarize conversation to free up context
|
|
30
37
|
• /rewind - Remove last message from history
|
|
31
38
|
• /resume - Resume with last command
|
|
32
|
-
• /exit - Exit the agent (or use Ctrl+C)`,timestamp:new Date};l(t=>[...t,e]);return}if(i===`/exit`&&process.exit(0),i===`/mcp`){try{let{loadBundledMCPConfigs:e}=await import(`@stackone/agent-harness`),t=e();if(t.length===0){let e={role:`system`,content:`📡 No bundled MCP servers available`,timestamp:new Date};l(t=>[...t,e]);return}let n=new Set(
|
|
33
|
-
`).filter(e=>e.trim());if(t.length===0){let e={role:`system`,content:`⏮️ Command history is empty.`,timestamp:new Date};l(t=>[...t,e]);return}R({type:`rewind`,items:t.reverse().slice(0,10).map((e,n)=>({name:e,description:`${t.length-n} messages ago`,index:t.length-n-1}))})}catch(e){let t={role:`system`,content:`❌ Error loading history: ${e instanceof Error?e.message:String(e)}`,timestamp:new Date};l(e=>[...e,t])}return}if(i===`/resume`){try{let e=
|
|
39
|
+
• /exit - Exit the agent (or use Ctrl+C)`,timestamp:new Date};l(t=>[...t,e]);return}if(i===`/exit`&&process.exit(0),i===`/mcp`){try{let{loadBundledMCPConfigs:e}=await import(`@stackone/agent-harness`),t=e();if(t.length===0){let e={role:`system`,content:`📡 No bundled MCP servers available`,timestamp:new Date};l(t=>[...t,e]);return}let n=new Set(be.mcpServers.map(e=>e.name));R({type:`mcp`,items:t.map(e=>{let t=n.has(e.name),r=be.toolCounts.mcpByServer[e.name]?.length||0,i=e.type===`http`?e.url:void 0;return{name:e.name,description:`${r} tools${i?` • ${i}`:``}`,connected:t,toolCount:r,url:i}})})}catch(e){let t={role:`system`,content:`❌ Error loading MCP servers: ${e instanceof Error?e.message:String(e)}`,timestamp:new Date};l(e=>[...e,t])}return}if(i===`/rewind`){try{let e=k.join(ae.homedir(),`.stackone`,`agent_history`);if(!T.existsSync(e)){let e={role:`system`,content:`⏮️ No command history found.`,timestamp:new Date};l(t=>[...t,e]);return}let t=T.readFileSync(e,`utf-8`).split(`
|
|
40
|
+
`).filter(e=>e.trim());if(t.length===0){let e={role:`system`,content:`⏮️ Command history is empty.`,timestamp:new Date};l(t=>[...t,e]);return}R({type:`rewind`,items:t.reverse().slice(0,10).map((e,n)=>({name:e,description:`${t.length-n} messages ago`,index:t.length-n-1}))})}catch(e){let t={role:`system`,content:`❌ Error loading history: ${e instanceof Error?e.message:String(e)}`,timestamp:new Date};l(e=>[...e,t])}return}if(i===`/resume`){try{let e=k.join(ae.homedir(),`.stackone`,`conversations`);if(!T.existsSync(e)){let e={role:`system`,content:`▶️ No conversation history found. Start a new conversation first!`,timestamp:new Date};l(t=>[...t,e]);return}let t=T.readdirSync(e).filter(e=>e.endsWith(`.json`)).sort((e,t)=>{let n=parseInt(e.split(`-`)[0])||0;return(parseInt(t.split(`-`)[0])||0)-n}).slice(0,10);if(t.length===0){let e={role:`system`,content:`▶️ No conversations found.`,timestamp:new Date};l(t=>[...t,e]);return}let n=t.map(t=>{try{let n=T.readFileSync(k.join(e,t),`utf-8`),r=JSON.parse(n);return{file:t,title:r.title||`Untitled conversation`,timestamp:r.timestamp,messages:r.messages,goal:r.goal}}catch{return null}}).filter(Boolean);if(n.length===0){let e={role:`system`,content:`▶️ No valid conversations found.`,timestamp:new Date};l(t=>[...t,e]);return}R({type:`resume`,items:n.map(e=>({name:e?.title,description:new Date(e?.timestamp).toLocaleString(),goal:e?.goal,file:e?.file,messages:e?.messages}))})}catch(e){let t={role:`system`,content:`❌ Error loading conversations: ${e instanceof Error?e.message:String(e)}`,timestamp:new Date};l(e=>[...e,t])}return}if(i.startsWith(`/`)&&![`/`,`/ /commands`,`/skills`,`/tools`,`/mcp`,`/compact`,`/rewind`,`/resume`,`/exit`].includes(i)){let e={role:`system`,content:`❌ Unknown command: ${i}\n\nType /commands to see available commands.`,timestamp:new Date};l(t=>[...t,e]);return}if(i===`/compact`){let e={role:`user`,content:i,timestamp:new Date};l(t=>[...t,e]),p(!0);try{let e=c.filter(e=>e.role===`user`||e.role===`assistant`).map(e=>`${e.role===`user`?`User`:`Assistant`}: ${e.content}`).join(`
|
|
34
41
|
|
|
35
|
-
`),t=await y?.generateConversationSummary(e);p(!1);let n={role:`system`,content:`🗜️ Compact mode activated - conversation summarized:\n\n${t}`,timestamp:new Date};l(e=>[e[e.length-1],n])}catch(e){p(!1),h(e instanceof Error?e.message:`Failed to summarize conversation`)}return}
|
|
36
|
-
`),`utf-8`)}catch(t){a&&e.error(`[History] Failed to save command history:`,t)}return n});let u={role:`user`,content:i,timestamp:new Date};l(e=>[...e,u]),p(!0),W(!0),K.current.shouldStop=!1;try{let o=c.filter(e=>(e.role===`user`||e.role===`assistant`)&&!e.isSubagent).map(e=>({role:e.role,content:e.content})),s=E.length>0?E.slice(0,8):void 0;E.length>8&&a&&e.warn(`[Skills] Warning: ${E.length} skills enabled, but Claude API limit is 8. Using first 8 skills.`);let u=await y.executeStream({mode:t,goal:i,connector:n,action:r,conversationHistory:o,skills:s},{onThinking:()=>{K.current.shouldStop||(p(!0),d(new Map),
|
|
42
|
+
`),t=await y?.generateConversationSummary(e);p(!1);let n={role:`system`,content:`🗜️ Compact mode activated - conversation summarized:\n\n${t}`,timestamp:new Date};l(e=>[e[e.length-1],n])}catch(e){p(!1),h(e instanceof Error?e.message:`Failed to summarize conversation`)}return}A(t=>{let n=[...t,i],r=k.join(ae.homedir(),`.stackone`,`agent_history`);try{let e=k.dirname(r);T.existsSync(e)||T.mkdirSync(e,{recursive:!0});let t=n.slice(-1e3);T.writeFileSync(r,t.join(`
|
|
43
|
+
`),`utf-8`)}catch(t){a&&e.error(`[History] Failed to save command history:`,t)}return n});let u={role:`user`,content:i,timestamp:new Date};l(e=>[...e,u]),p(!0),W(!0),K.current.shouldStop=!1;try{let o=c.filter(e=>(e.role===`user`||e.role===`assistant`)&&!e.isSubagent).map(e=>({role:e.role,content:e.content})),s=E.length>0?E.slice(0,8):void 0;E.length>8&&a&&e.warn(`[Skills] Warning: ${E.length} skills enabled, but Claude API limit is 8. Using first 8 skills.`);let u=await y.executeStream({mode:t,goal:i,connector:n,action:r,conversationHistory:o,skills:s},{onThinking:()=>{K.current.shouldStop||(p(!0),d(new Map),M(``),Q())},onToolCall:t=>{if(K.current.shouldStop)return;p(!1),q(e=>e.find(e=>e.id===t.id)?e.map(e=>e.id===t.id?{...e,input:t.input}:e):[...e,{id:t.id,name:t.name,input:t.input,output:void 0}]);let n=t.name===`spawn_subagent`;if(M(r=>{let i=[];if(r){let t={role:`assistant`,content:r,timestamp:new Date,isSubagent:n?!1:z.current};a&&e.log(`[MSG] Adding pre-tool message: isSubagent=${t.isSubagent}, isSpawnSubagent=${n}, content="${r.slice(0,50)}..."`),i.push(t)}let o={role:`system`,content:`TOOL_START:${t.id}|||${t.name}`,timestamp:new Date,isSubagent:n?!0:z.current};return a&&e.log(`[MSG] Adding TOOL_START: isSubagent=${o.isSubagent}, tool=${t.name}`),i.push(o),l(e=>[...e,...i]),``}),n&&t.input){let n=t.input;a&&e.log(`spawn_subagent input:`,JSON.stringify(n,null,2));let r=n.description||n.goal||n.name||`Subagent`;if(typeof r==`string`&&r.length>50){let e=r.split(/[.!?]/)[0];r=e.length>50?e.slice(0,47)+`...`:e}a&&e.log(`Extracted agent name:`,r),he(String(r)),z.current=!0,setTimeout(()=>{pe(!0)},10)}d(e=>{let n=new Map(e);return n.set(t.id,{name:t.name,status:`running`}),n})},onToolResult:e=>{if(K.current.shouldStop)return;q(t=>t.map(t=>t.id===e.id?{...t,output:e.output}:t)),d(t=>{let n=new Map(t);return n.set(e.id,{name:e.name,status:`completed`}),n});let t=typeof e.output==`string`?e.output:JSON.stringify(e.output,null,2);l(n=>n.map(n=>n.content.startsWith(`TOOL_START:${e.id}|||`)?{...n,content:`TOOL:${e.name}|||${t}`}:n)),setTimeout(()=>{d(t=>{let n=new Map(t);return n.delete(e.id),n})},500)},onToken:e=>{K.current.shouldStop||(M(t=>t+e),Q())},onUsage:e=>{K.current.shouldStop||se(e)},onComplete:async t=>{if(K.current.shouldStop)return;p(!1),d(new Map),q([]);let n=z.current;M(e=>{if(e){let t={role:`assistant`,content:e,timestamp:new Date,isSubagent:n};l(e=>[...e,t])}return``}),n?(a&&e.log(`[SUBAGENT] Subprocess completed, collecting output...`),z.current=!1,setTimeout(()=>{l(t=>{a&&(e.log(`[SUBAGENT] Total messages:`,t.length),e.log(`[SUBAGENT] Messages with isSubagent=true:`,t.filter(e=>e.isSubagent).length));let n=t.filter(t=>{let n=t.isSubagent&&t.role===`assistant`;return n&&a&&e.log(`[SUBAGENT] Found message:`,t.content.slice(0,50)),n}).map(e=>e.content).join(`
|
|
37
44
|
|
|
38
|
-
`);return a&&e.log(`[SUBAGENT] Collected output length:`,n.length),n&&n.trim()?setTimeout(()=>{a&&e.log(`[SUBAGENT] Hiding subprocess UI...`),
|
|
45
|
+
`);return a&&e.log(`[SUBAGENT] Collected output length:`,n.length),n&&n.trim()?setTimeout(()=>{a&&e.log(`[SUBAGENT] Hiding subprocess UI...`),ge(!1),pe(!1),setTimeout(()=>{a&&e.log(`[SUBAGENT] Sending output to main agent`);try{Z(n,!0)}catch(t){e.error(`[SUBAGENT] Error submitting to main agent:`,t),W(!1)}},100)},300):(a&&e.log(`[SUBAGENT] No output found, closing subprocess`),ge(!1),pe(!1),W(!1)),t})},100)):W(!1),await X(i)},onError:e=>{p(!1),d(new Map),h(e.message)}});p(!1),d(new Map),W(!1),q([]),u.status===`failed`&&u.error&&h(u.error)}catch(t){p(!1),d(new Map),W(!1),q([]);let n=t instanceof Error?t.message:String(t);n.includes(`403`)||n.includes(`Invalid authentication token`)||n.includes(`authentication`)?h(s?.startsWith(`falcon_key_`)?`Authentication failed. The token in your .env is a Falcon MCP token, which is not authorized for the Claude proxy endpoint.
|
|
39
46
|
|
|
40
47
|
⚠️ Known Issue: The authentication system currently returns MCP-only tokens that don't work with the Claude proxy.
|
|
41
48
|
|
|
@@ -53,16 +60,16 @@ To fix this:
|
|
|
53
60
|
|
|
54
61
|
Original error: ${n}`):n.includes(`API key`)||n.includes(`Invalid API Key`)?(e.error(`
|
|
55
62
|
❌ Critical error:`,n),e.error(`Please check your configuration and try again.
|
|
56
|
-
`),process.exit(1)):h(n),W(!1),p(!1),d(new Map)}},[y,c,i,t,n,r,x,E,
|
|
63
|
+
`),process.exit(1)):h(n),W(!1),p(!1),d(new Map)}},[y,c,i,t,n,r,x,E,N,ce,s,fe,X]);F(()=>{!y||v||i&&Z(i)},[y,v,i,t,Z,be]);let Q=()=>{V(e=>(e.length===0||d(e=>(!(e.size>0)&&G.current&&(J.current&&=(clearTimeout(J.current),null),setTimeout(()=>xe(),100)),e)),e))},xe=()=>{V(e=>{if(e.length===0)return e;U(!0),M(e=>{if(e){let t={role:`assistant`,content:e,timestamp:new Date,isSubagent:z.current};l(e=>[...e,t])}return``});let t=e.map(e=>({role:`user`,content:e.content,timestamp:new Date}));l(e=>[...e,...t]);let n=e.map(e=>e.content).join(`
|
|
57
64
|
|
|
58
65
|
---
|
|
59
66
|
|
|
60
|
-
`);return
|
|
67
|
+
`);return U(!1),W(!1),q([]),J.current&&=(clearTimeout(J.current),null),setTimeout(()=>{Z(n,!0)},100),[]})},Se=le(e=>{D(t=>t.includes(e)?t.filter(t=>t!==e):t.length>=8?t:[...t,e])},[]);F(()=>{L?.type===`skills`&&O.length>0&&R({type:`skills`,items:O.map(e=>({name:e.name,description:e.description,version:e.version,author:e.author,tags:e.tags,enabled:E.includes(e.name)}))})},[E,O,L?.type]);let Ce=()=>{},we=le(()=>{K.current.shouldStop=!0,_(!0),M(e=>{if(e){let t=z.current,n={role:`assistant`,content:e,timestamp:new Date,isSubagent:t};l(e=>[...e,n])}return``}),p(!1),W(!1),G.current=!1,d(new Map),q([]),V([]),U(!1)},[]);return v?P.createElement(ze,{title:`Agent ${t.charAt(0).toUpperCase()+t.slice(1)} Mode`,mode:t,connector:n,action:r,messages:[],currentToolCalls:[],isThinking:!1,isComplete:!1,error:void 0,isInterrupted:!1,onSubmit:()=>{},onExit:Ce,onStop:we}):P.createElement(ze,{title:`Agent ${t.charAt(0).toUpperCase()+t.slice(1)} Mode`,mode:t,connector:n,action:r,messages:c,currentToolCalls:Array.from(u.values()),isThinking:f,isComplete:!1,error:m,isInterrupted:g,onSubmit:Z,onExit:Ce,onStop:we,commandHistory:oe,streamingText:j,usage:N,detailViewData:L,onCloseDetailView:()=>R(null),onToggleSkill:Se,onRewindTo:e=>{try{let t=k.join(ae.homedir(),`.stackone`,`agent_history`),n=T.readFileSync(t,`utf-8`).split(`
|
|
61
68
|
`).filter(e=>e.trim()),r=n.slice(0,e+1);T.writeFileSync(t,r.join(`
|
|
62
|
-
`),`utf-8`);let i={role:`system`,content:`⏮️ Rewound to command: "${n[e]}"`,timestamp:new Date};l(e=>[...e,i])}catch(e){let t={role:`system`,content:`❌ Error rewinding: ${e instanceof Error?e.message:String(e)}`,timestamp:new Date};l(e=>[...e,t])}},onResumeConversation:e=>{l(e.map(e=>({...e,timestamp:new Date(e.timestamp)})))},spawnedSubagentActive:
|
|
63
|
-
`).filter(e=>e.trim()))}catch(t){e.error(`[Trust] Failed to load trusted directories:`,t)}if(!l.includes(o)){let t=!1,{waitUntilExit:n}=
|
|
69
|
+
`),`utf-8`);let i={role:`system`,content:`⏮️ Rewound to command: "${n[e]}"`,timestamp:new Date};l(e=>[...e,i])}catch(e){let t={role:`system`,content:`❌ Error rewinding: ${e instanceof Error?e.message:String(e)}`,timestamp:new Date};l(e=>[...e,t])}},onResumeConversation:e=>{l(e.map(e=>({...e,timestamp:new Date(e.timestamp)})))},spawnedSubagentActive:fe,spawnedSubagentName:me,spawnedSubagentComplete:B,queuedMessages:_e,isProcessingQueue:H,enabledSkills:E,initInfo:be})};var Ue=class{async execute(t){if(!process.execArgv.some(e=>e.startsWith(`--max-old-space-size`))){let{spawn:e}=await import(`child_process`);e(process.execPath,[`--max-old-space-size=8192`,...process.argv.slice(1)],{stdio:`inherit`,env:process.env}).on(`exit`,e=>{process.exit(e||0)});return}process.stdout.write(`\x1Bc`);let{getAgentApiKey:n}=await import(`./agentApiKey-BEwv4ueA.mjs`),{hasOldSetupFiles:r,migrateFromLocalSetup:i,displayMigrationMessage:a}=await import(`./setupMigration-DWVcBa3h.mjs`);try{let o=process.cwd();r(o)&&a(await i(o));let s=n();process.env.STACKONE_AGENT_TOKEN||(process.env.STACKONE_AGENT_TOKEN=s);let c=k.join(ae.homedir(),`.stackone`,`trusted_directories`),l=[];try{T.existsSync(c)&&(l=T.readFileSync(c,`utf-8`).split(`
|
|
70
|
+
`).filter(e=>e.trim()))}catch(t){e.error(`[Trust] Failed to load trusted directories:`,t)}if(!l.includes(o)){let t=!1,{waitUntilExit:n}=N(P.createElement(Be,{directory:o,onConfirm:()=>{t=!0;try{let e=k.dirname(c);T.existsSync(e)||T.mkdirSync(e,{recursive:!0}),l.push(o),T.writeFileSync(c,l.join(`
|
|
64
71
|
`),`utf-8`)}catch(t){e.error(`[Trust] Failed to save trusted directory:`,t)}},onCancel:()=>{t=!1}}));await n(),t||(e.log(`
|
|
65
|
-
Exiting...`),process.exit(0)),process.stdout.write(`\x1Bc`)}
|
|
72
|
+
Exiting...`),process.exit(0)),process.stdout.write(`\x1Bc`)}N(P.createElement(He,{...t,apiKey:s}),{exitOnCtrlC:!1})}catch(t){let n=t instanceof Error?t.message:String(t);n.includes(`STACKONE_AGENT_TOKEN`)?(e.error(`
|
|
66
73
|
❌ Authentication Required
|
|
67
74
|
`),e.log(y.white(`You need to authenticate before using the agent.
|
|
68
75
|
`)),e.log(y.white(`To get started, run:
|
|
@@ -72,20 +79,20 @@ Exiting...`),process.exit(0)),process.stdout.write(`\x1Bc`)}M(N.createElement(He
|
|
|
72
79
|
`))):(e.error(`
|
|
73
80
|
❌ Error:`,n),e.log(y.dim(`
|
|
74
81
|
If you continue to see this error, try running:`)),e.log(y.cyan(` stackone agent setup
|
|
75
|
-
`))),process.exit(1)}}};const We=G(
|
|
76
|
-
`));let t={configsCleaned:0};try{let n=K(`Removing stored configuration...`).start();await m(),n.succeed(`Removed ~/.stackone/agent-config.json`);let r=K(`Removing MCP servers from Claude...`).start(),i=0;try{await We(`claude mcp remove ${p()} 2>/dev/null`),i++}catch{}try{await We(`claude mcp remove ${s()} 2>/dev/null`),i++}catch{}i>0?r.succeed(`Removed ${i} MCP server(s) from Claude`):r.warn(`No MCP servers found in Claude (already removed or not configured)`);let a=K(`Checking for .mcp.json file...`).start(),o=
|
|
82
|
+
`))),process.exit(1)}}};const We=G(V);async function Ge(e){try{let t=await ve(e,`utf-8`),n=JSON.parse(t),r=!1;if(n.mcpServers&&typeof n.mcpServers==`object`){for(let[e,t]of Object.entries(n.mcpServers))if(t&&typeof t==`object`&&`transport`in t){let e=t.transport;if(e&&typeof e==`object`&&`headers`in e){let t=e.headers;if(t&&typeof t==`object`&&`Authorization`in t){let e=t.Authorization;typeof e==`string`&&e.startsWith(`Bearer `)&&!e.includes("${")&&(t.Authorization="Bearer ${STACKONE_AGENT_TOKEN}",r=!0)}}}}return r&&await W(e,JSON.stringify(n,null,2)),r}catch{return!1}}var Ke=class{async execute(){e.log(y.blue.bold(`🧹 StackOne Agent Cleanup
|
|
83
|
+
`));let t={configsCleaned:0};try{let n=K(`Removing stored configuration...`).start();await m(),n.succeed(`Removed ~/.stackone/agent-config.json`);let r=K(`Removing MCP servers from Claude...`).start(),i=0;try{await We(`claude mcp remove ${p()} 2>/dev/null`),i++}catch{}try{await We(`claude mcp remove ${s()} 2>/dev/null`),i++}catch{}i>0?r.succeed(`Removed ${i} MCP server(s) from Claude`):r.warn(`No MCP servers found in Claude (already removed or not configured)`);let a=K(`Checking for .mcp.json file...`).start(),o=A(process.cwd(),`.mcp.json`);try{await Ge(o)?(t.configsCleaned=1,a.succeed(`Cleaned .mcp.json (replaced tokens with environment variables)`)):a.info(`.mcp.json already uses environment variables or not found`)}catch{a.info(`.mcp.json not found (already cleaned or not created)`)}e.success(`Cleanup complete!`),e.log(y.white(`
|
|
77
84
|
What was removed:`)),e.log(y.cyan(` • ~/.stackone/agent-config.json`)),e.log(y.cyan(` • MCP server from Claude configuration`)),t.configsCleaned>0&&e.log(y.cyan(` • Hardcoded credentials from .mcp.json`)),e.log(y.dim(`
|
|
78
|
-
To authenticate again:`)),e.log(y.cyan(` stackone agent setup --global`),y.dim(`(for global setup)`)),e.log(y.cyan(` stackone agent setup --local`),y.dim(`(for local project setup)`)),e.log(``),process.exit(0)}catch(t){t instanceof Error?e.error(t.message):e.error(`Unknown error occurred`),process.exit(1)}}};const qe=new class{constructor(e){this.baseUrl=e||process.env.AUTH_SERVER_URL||`https://idp-api.stackone.com`}async login(e,t){try{let n=`${this.baseUrl}/auth/sign-in/mcp`,r=await fetch(n,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({email:e,password:t})});if(!r.ok){let e=await r.text(),t={};try{t=JSON.parse(e)}catch{}return{success:!1,error:t.error||`HTTP ${r.status}: ${r.statusText}`}}let i=await r.text(),a=JSON.parse(i);return a.apiKey?{success:!0,apiKey:a.apiKey}:{success:!1,error:`Invalid response format`}}catch(e){return{success:!1,error:e instanceof Error?e.message:`Network error occurred`}}}async validateKey(e){try{let t=`${this.baseUrl}/api-key/verify`,n=await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({key:e})});if(!n.ok){let e=await n.text(),t={};try{t=JSON.parse(e)}catch{}return{valid:!1,error:t.error||`HTTP ${n.status}: ${n.statusText}`}}let r=await n.text();return JSON.parse(r)}catch(e){return{valid:!1,error:e instanceof Error?e.message:`Network error occurred`}}}},Je=G(
|
|
79
|
-
`));try{let t=process.cwd(),r=await
|
|
80
|
-
Setup cancelled.`)),process.exit(0)),e.log(``)}let a=await d(),o;if(a?.email){e.log(y.dim(`Last used email: ${a.email}\n`));let{useExisting:t}=await
|
|
85
|
+
To authenticate again:`)),e.log(y.cyan(` stackone agent setup --global`),y.dim(`(for global setup)`)),e.log(y.cyan(` stackone agent setup --local`),y.dim(`(for local project setup)`)),e.log(``),process.exit(0)}catch(t){t instanceof Error?e.error(t.message):e.error(`Unknown error occurred`),process.exit(1)}}};const qe=new class{constructor(e){this.baseUrl=e||process.env.AUTH_SERVER_URL||`https://idp-api.stackone.com`}async login(e,t){try{let n=`${this.baseUrl}/auth/sign-in/mcp`,r=await fetch(n,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({email:e,password:t})});if(!r.ok){let e=await r.text(),t={};try{t=JSON.parse(e)}catch{}return{success:!1,error:t.error||`HTTP ${r.status}: ${r.statusText}`}}let i=await r.text(),a=JSON.parse(i);return a.apiKey?{success:!0,apiKey:a.apiKey}:{success:!1,error:`Invalid response format`}}catch(e){return{success:!1,error:e instanceof Error?e.message:`Network error occurred`}}}async validateKey(e){try{let t=`${this.baseUrl}/api-key/verify`,n=await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({key:e})});if(!n.ok){let e=await n.text(),t={};try{t=JSON.parse(e)}catch{}return{valid:!1,error:t.error||`HTTP ${n.status}: ${n.statusText}`}}let r=await n.text();return JSON.parse(r)}catch(e){return{valid:!1,error:e instanceof Error?e.message:`Network error occurred`}}}},Je=G(V);function Ye(e){let t=new Date(e),n=new Date,r=t.getTime()-n.getTime(),i=Math.floor(r/(3600*1e3)),a=t.toLocaleTimeString(`en-US`,{hour:`numeric`,minute:`2-digit`,hour12:!0});return`${t.toDateString()===n.toDateString()?`Today`:t.toDateString()===new Date(n.getTime()+864e5).toDateString()?`Tomorrow`:t.toLocaleDateString(`en-US`,{month:`short`,day:`numeric`})} at ${a} (${i} hours from now)`}var Xe=class{async execute(){e.log(y.blue.bold(`🤖 StackOne Agent Setup - Global Configuration
|
|
86
|
+
`));try{let t=process.cwd(),r=await U(`${t}/CLAUDE.md`).then(()=>!0).catch(()=>!1),i=await U(`${t}/.mcp.json`).then(()=>!0).catch(()=>!1);if(r||i){e.warn(`Existing local setup detected:`),r&&e.log(y.dim(` • CLAUDE.md found in current directory`)),i&&e.log(y.dim(` • .mcp.json found in current directory`)),e.log(``);let{proceed:t}=await be.prompt([{type:`confirm`,name:`proceed`,message:`Re-authenticate globally despite existing local setup?`,default:!0}]);t||(e.log(y.dim(`
|
|
87
|
+
Setup cancelled.`)),process.exit(0)),e.log(``)}let a=await d(),o;if(a?.email){e.log(y.dim(`Last used email: ${a.email}\n`));let{useExisting:t}=await be.prompt([{type:`confirm`,name:`useExisting`,message:`Sign in with this email?`,default:!0}]);if(t)o=a.email;else{let t=J({input:ye,output:q});o=await new Promise(e=>{t.question(y.white(`Email: `),t=>{e(t.trim())})}),t.close(),o||(e.error(`Email is required`),process.exit(1))}}else{let t=J({input:ye,output:q});o=await new Promise(e=>{t.question(y.white(`Email: `),t=>{e(t.trim())})}),t.close(),o||(e.error(`Email is required`),process.exit(1))}let s=await be.prompt([{type:`password`,name:`password`,message:`Password:`,mask:`*`}]);s.password||(e.error(`Password is required`),process.exit(1)),e.log(``);let c=K(`Authenticating...`).start(),l=await qe.login(o,s.password);(!l.success||!l.apiKey)&&(c.fail(`Authentication failed`),e.error(`${l.error||`Invalid credentials`}`),e.log(y.dim(`Please check your email and password and try again.
|
|
81
88
|
`)),process.exit(1)),c.succeed(`Login successful!`);let f=new Date(Date.now()+1440*60*1e3).toISOString();await n({apiKey:l.apiKey,userId:o,email:o,expiresAt:f,serverUrl:u()}),e.success(`API key saved to ~/.stackone/agent-config.json`),e.log(y.white(`✓ Key expires at`),y.cyan(Ye(f)));let m=K(`Setting up global MCP configuration...`).start();try{let t=p(),n=u();try{await Je(`claude mcp remove ${t} 2>/dev/null`)}catch{}await Je(`claude mcp add ${t} ${n} --scope user --transport http --header "Authorization: Bearer ${l.apiKey}"`),m.succeed(`Installed to Claude (global)`),e.success(`Global setup complete!`),e.log(y.white(`Config location:`),y.cyan(`~/.claude.json`)),e.log(y.blue(`
|
|
82
89
|
Verify:`),y.cyan(`claude mcp list`)),e.log(y.dim(`
|
|
83
90
|
💡 Tip: Run Claude without permission prompts:`),y.cyan(`claude --dangerously-skip-permissions`)),e.log(y.dim(`
|
|
84
91
|
To setup for a specific project, run:`),y.cyan(`stackone agent setup --local`)),e.log(``)}catch(t){m.fail(`Installation to Claude failed`),t instanceof Error&&(e.error(t.message),e.log(y.dim(`You can manually add the server later with:`)),e.log(y.cyan(` claude mcp add ${p()} ${u()} --scope user --transport http --header "Authorization: Bearer ${l.apiKey}"`)))}process.exit(0)}catch(t){t instanceof Error?e.error(t.message):e.error(`Unknown error occurred`),process.exit(1)}}},Ze=class{async execute(){e.log(y.blue.bold(`🤖 StackOne Agent Setup - Local Project
|
|
85
92
|
`));try{let r=process.cwd();_(r)&&ee(await v(r));let i=await d();if(!i||!t(i)){e.warn(`Not authenticated globally.`),e.log(y.white(`Let's authenticate now...
|
|
86
|
-
`));let t=J({input:ye,output:q}),r=await new Promise(e=>{t.question(y.white(`Email: `),t=>{e(t.trim())})});t.close(),r||(e.error(`Email is required`),process.exit(1));let a=await
|
|
93
|
+
`));let t=J({input:ye,output:q}),r=await new Promise(e=>{t.question(y.white(`Email: `),t=>{e(t.trim())})});t.close(),r||(e.error(`Email is required`),process.exit(1));let a=await be.prompt([{type:`password`,name:`password`,message:`Password:`,mask:`*`}]);a.password||(e.error(`Password is required`),process.exit(1)),e.log(``);let o=K(`Authenticating...`).start(),s=await qe.login(r,a.password);(!s.success||!s.apiKey)&&(o.fail(`Authentication failed`),e.error(`${s.error||`Invalid credentials`}`),e.log(y.dim(`Please check your email and password and try again.
|
|
87
94
|
`)),process.exit(1)),o.succeed(`Login successful!`);let c=new Date(Date.now()+1440*60*1e3).toISOString();await n({apiKey:s.apiKey,userId:r,email:r,expiresAt:c,serverUrl:u()}),i={apiKey:s.apiKey,userId:r,email:r,expiresAt:c,serverUrl:u()},e.log(``)}e.success(`Setup complete!`),e.log(y.white(`
|
|
88
|
-
Token saved to:`)),e.log(y.cyan(` ~/.stackone/agent-config.json`)),e.log(``),process.exit(0)}catch(t){t instanceof Error?e.error(t.message):e.error(`Unknown error occurred`),process.exit(1)}}};const Qe={profiles:{}},$e=()=>{let e=c.readConfigFile(h);if(!e)return Qe;try{return JSON.parse(e)}catch{return Qe}},et=e=>$e().profiles[e],tt=e=>!!$e().profiles[e],nt=(e,t)=>{let n=$e();n.profiles[e]=t,c.writeConfigFile(h,JSON.stringify(n,null,2))},rt=()=>{let e=$e();return Object.keys(e.profiles)},it=`https://api.stackone.com`;var at=class{async execute({profile:t,connector:n,apiUrl:r,apiKey:i}={}){if(!t&&!i&&(e.error(`Profile or API key is required`),e.log(`Please provide a profile using the ${a(`--profile`)} option or an API key using the ${a(`--api-key`)} option.`),e.log(`To create a profile, run ${a(`stackone init`)}.`),process.exit(1)),t&&i&&(e.error(`Please provide either a profile or an API key, not both`),process.exit(1)),t&&r&&e.warn(`Specifying ${a(`--api-url`)} with a profile won't have any effect. Using API url from profile.`),t&&!tt(t)){e.error(`Configuration profile ${a(t)} not found`),e.log(`Run ${a(`stackone init`)} to create a new configuration profile.\n`);let n=rt();n.length>0&&(e.info(`Available configuration profiles:`),n.forEach(t=>{e.log(` - ${y.blue(t)}`)})),process.exit(1)}let s=t?et(t):{apiUrl:r??it,apiKey:i};s?.apiKey||(e.error(`API key is missing`),e.log(`Please provide a valid API key in the profile or via the ${a(`--api-key`)} option.`),process.exit(1)),n||(e.error(`Connector identifier is required in the format provider_key@version.`),process.exit(1));let c=n.split(`@`);(c.length!==2||!c[0]||!c[1])&&(e.error(`Invalid connector format ${o(n)}. Expected format: ${a(`provider_key@version`)}`),process.exit(1));let l=s.apiUrl??it,u=await this.dropConnector(n,l,s.apiKey);process.exit(u?0:1)}async dropConnector(t,n,r){let i=K(`🗑️ Dropping connector ${a(t)}...`).start();try{let o=Buffer.from(r).toString(`base64`),s=await fetch(`${n}/registry/connectors/${t}`,{method:`DELETE`,headers:{Authorization:`Basic ${o}`}});return i.stop(),s.status===204?(e.success(`Successfully dropped connector ${a(t)} from the registry`),!0):s.status===404?(e.error(`Connector ${a(t)} not found in the registry`),!1):s.status===401||s.status===403?(e.error(`You do not have permission to drop this connector`),!1):s.status===409?(e.error(`Connector ${a(t)} has associated configs and cannot be dropped`),e.log(`Please delete all associated integration configurations before dropping the connector.`),!1):(s.ok||await l(s,`Failed to drop connector ${a(t)} from the registry`),!1)}catch(r){return i.stop(),e.error(`Failed to drop connector ${a(t)} from registry: ${r.message}`),e.log(`Please ensure that the API at ${g(n)} is reachable and the API key is valid`),!1}}};const ot=`https://api.stackone.com`;var st=class{async execute({profile:t,connector:n,accountId:r,format:i,outputFile:s,apiUrl:c,apiKey:l}={}){if(!t&&!l&&(e.error(`Profile or API key is required`),e.log(`Please provide a profile using the ${a(`--profile`)} option or an API key using the ${a(`--api-key`)} option.`),e.log(`To create a profile, run ${a(`stackone init`)}.`),process.exit(1)),t&&l&&(e.error(`Please provide either a profile or an API key, not both`),process.exit(1)),t&&c&&e.warn(`Specifying ${a(`--api-url`)} with a profile won't have any effect. Using API url from profile.`),t&&!tt(t)){e.error(`Configuration profile ${a(t)} not found`),e.log(`Run ${a(`stackone init`)} to create a new configuration profile.\n`);let n=rt();n.length>0&&(e.info(`Available configuration profiles:`),n.forEach(t=>{e.log(` - ${y.blue(t)}`)})),process.exit(1)}let u=t?et(t):{apiUrl:c??ot,apiKey:l};u?.apiKey||(e.error(`API key is missing`),e.log(`Please provide a valid API key in the profile or via the ${a(`--api-key`)} option.`),process.exit(1)),
|
|
95
|
+
Token saved to:`)),e.log(y.cyan(` ~/.stackone/agent-config.json`)),e.log(``),process.exit(0)}catch(t){t instanceof Error?e.error(t.message):e.error(`Unknown error occurred`),process.exit(1)}}};const Qe={profiles:{}},$e=()=>{let e=c.readConfigFile(h);if(!e)return Qe;try{return JSON.parse(e)}catch{return Qe}},et=e=>$e().profiles[e],tt=e=>!!$e().profiles[e],nt=(e,t)=>{let n=$e();n.profiles[e]=t,c.writeConfigFile(h,JSON.stringify(n,null,2))},rt=()=>{let e=$e();return Object.keys(e.profiles)},it=`https://api.stackone.com`;var at=class{async execute({profile:t,connector:n,apiUrl:r,apiKey:i}={}){if(!t&&!i&&(e.error(`Profile or API key is required`),e.log(`Please provide a profile using the ${a(`--profile`)} option or an API key using the ${a(`--api-key`)} option.`),e.log(`To create a profile, run ${a(`stackone init`)}.`),process.exit(1)),t&&i&&(e.error(`Please provide either a profile or an API key, not both`),process.exit(1)),t&&r&&e.warn(`Specifying ${a(`--api-url`)} with a profile won't have any effect. Using API url from profile.`),t&&!tt(t)){e.error(`Configuration profile ${a(t)} not found`),e.log(`Run ${a(`stackone init`)} to create a new configuration profile.\n`);let n=rt();n.length>0&&(e.info(`Available configuration profiles:`),n.forEach(t=>{e.log(` - ${y.blue(t)}`)})),process.exit(1)}let s=t?et(t):{apiUrl:r??it,apiKey:i};s?.apiKey||(e.error(`API key is missing`),e.log(`Please provide a valid API key in the profile or via the ${a(`--api-key`)} option.`),process.exit(1)),n||(e.error(`Connector identifier is required in the format provider_key@version.`),process.exit(1));let c=n.split(`@`);(c.length!==2||!c[0]||!c[1])&&(e.error(`Invalid connector format ${o(n)}. Expected format: ${a(`provider_key@version`)}`),process.exit(1));let l=s.apiUrl??it,u=await this.dropConnector(n,l,s.apiKey);process.exit(u?0:1)}async dropConnector(t,n,r){let i=K(`🗑️ Dropping connector ${a(t)}...`).start();try{let o=Buffer.from(r).toString(`base64`),s=await fetch(`${n}/registry/connectors/${t}`,{method:`DELETE`,headers:{Authorization:`Basic ${o}`}});return i.stop(),s.status===204?(e.success(`Successfully dropped connector ${a(t)} from the registry`),!0):s.status===404?(e.error(`Connector ${a(t)} not found in the registry`),!1):s.status===401||s.status===403?(e.error(`You do not have permission to drop this connector`),!1):s.status===409?(e.error(`Connector ${a(t)} has associated configs and cannot be dropped`),e.log(`Please delete all associated integration configurations before dropping the connector.`),!1):(s.ok||await l(s,`Failed to drop connector ${a(t)} from the registry`),!1)}catch(r){return i.stop(),e.error(`Failed to drop connector ${a(t)} from registry: ${r.message}`),e.log(`Please ensure that the API at ${g(n)} is reachable and the API key is valid`),!1}}};const ot=`https://api.stackone.com`;var st=class{async execute({profile:t,connector:n,accountId:r,format:i,outputFile:s,apiUrl:c,apiKey:l}={}){if(!t&&!l&&(e.error(`Profile or API key is required`),e.log(`Please provide a profile using the ${a(`--profile`)} option or an API key using the ${a(`--api-key`)} option.`),e.log(`To create a profile, run ${a(`stackone init`)}.`),process.exit(1)),t&&l&&(e.error(`Please provide either a profile or an API key, not both`),process.exit(1)),t&&c&&e.warn(`Specifying ${a(`--api-url`)} with a profile won't have any effect. Using API url from profile.`),t&&!tt(t)){e.error(`Configuration profile ${a(t)} not found`),e.log(`Run ${a(`stackone init`)} to create a new configuration profile.\n`);let n=rt();n.length>0&&(e.info(`Available configuration profiles:`),n.forEach(t=>{e.log(` - ${y.blue(t)}`)})),process.exit(1)}let u=t?et(t):{apiUrl:c??ot,apiKey:l};u?.apiKey||(e.error(`API key is missing`),e.log(`Please provide a valid API key in the profile or via the ${a(`--api-key`)} option.`),process.exit(1)),Y(n)&&Y(r)&&(e.error(`Either ${a(`--connector`)} or ${a(`--account-id`)} must be provided`),process.exit(1)),Z(n)&&Z(r)&&(e.error(`Please provide either ${a(`--connector`)} or ${a(`--account-id`)}, not both.`),process.exit(1)),Z(i)&&i!==`yaml`&&i!==`json`&&(e.error(`Format must be either ${a(`yaml`)} or ${a(`json`)}.`),process.exit(1));let d=u.apiUrl??ot,p;if(Z(n)){this.#t(n)||(e.error(`Invalid connector format ${o(n)}. Expected format: ${a(`provider_key@version`)} or ${a(`provider_key`)}`),process.exit(1));let t=this.#n(n);p=await this.#r(t,d,u.apiKey,i)}else Z(r)?p=await this.#i(r,d,u.apiKey,i):(e.error(`Either ${a(`--connector`)} or ${a(`--account-id`)} must be provided`),process.exit(1));if(Z(s))try{L.writeFileSync(s,p,`utf-8`),e.success(`Connector written to file: ${a(s)}`)}catch(t){e.error(`Failed to write connector to file ${a(s)}: ${t.message}`),process.exit(1)}else if(e.log(`\n${y.blue.inverse(` CONNECTOR CONTENT `)}\n`),!i||i===`yaml`)e.log(this.#e(p));else if(i===`json`)try{f(JSON.parse(p))}catch{e.log(p)}else e.log(p);process.exit(0)}#e(e){return e.split(`
|
|
89
96
|
`).map(e=>{if(e.trim().startsWith(`#`))return y.gray(e);if(e.includes(`:`)){let t=e.indexOf(`:`),n=e.substring(0,t+1),r=e.substring(t+1),i=r,a=r.trim();return a===`true`||a===`false`?i=r.replace(a,y.cyan(a)):a===`null`||a===`~`?i=r.replace(a,y.gray(a)):/^-?\d+(\.\d+)?$/.test(a)?i=r.replace(a,y.green(a)):(a.startsWith(`"`)&&a.endsWith(`"`)||a.startsWith(`'`)&&a.endsWith(`'`)||a&&!a.startsWith(`-`))&&(i=r.replace(a,y.yellow(a))),y.red(n)+i}return e.trim().startsWith(`-`)?e.replace(`-`,y.gray(`-`)):e}).join(`
|
|
90
97
|
`)}#t=e=>!e.includes(`/`)&&!e.includes(`\\`)&&!e.endsWith(`.yaml`)&&!e.endsWith(`.yml`)?e.includes(`@`)?e.split(`@`).length===2:!0:!1;#n=e=>e.includes(`@`)?e:`${e}@latest`;async#r(t,n,r,i){let o=K(`Getting connector ${a(t)} from registry...`).start();try{let e=Buffer.from(r).toString(`base64`),s=i?`?format=${i}`:``,c=await fetch(`${n}/registry/connectors/${t}${s}`,{method:`GET`,headers:{Authorization:`Basic ${e}`}});return o.stop(),c.ok||(await l(c,`Failed to get connector ${a(t)} from the registry`),process.exit(1)),await c.text()}catch(r){o.stop(),e.error(`Failed to get connector ${a(t)} from the registry: ${r.message}`),e.log(`Please ensure that the API at ${g(n)} is reachable and the API key is valid`),process.exit(1)}}async#i(t,n,r,i){let o=K(`Getting connector from account ${a(t)}...`).start();try{let e=Buffer.from(r).toString(`base64`),s=i?`?format=${i}`:``,c=await fetch(`${n}/accounts/${t}/connector${s}`,{method:`GET`,headers:{Authorization:`Basic ${e}`}});return o.stop(),c.ok||(await l(c,`Failed to get connector from account ${a(t)}`),process.exit(1)),await c.text()}catch(r){o.stop(),e.error(`Failed to get connector from account ${a(t)}: ${r.message}`),e.log(`Please ensure that the API at ${g(n)} is reachable and the API key is valid`),process.exit(1)}}};const ct=`http://localhost:4000`;var lt=class{async execute({environment:t}={}){let n=t?.toLowerCase()??`production`;try{Ce(`${y.inverse(` Initialize profile `)}`);let e=await Oe({message:`Profile label`,validate:e=>{if(!e||e.trim().length===0)return`The profile label is required`;if(e.includes(` `))return`The profile label cannot contain spaces`}});if(we(e))return xe(`Configuration profile initialization cancelled`),process.exit(0);if(tt(e)){let t=await Se({message:`Configuration profile with name ${a(e)} already exists. Do you want to overwrite it?`});if(we(t)||!t)return xe(`Configuration profile initialization cancelled`),process.exit(0)}let t;if(n===`production`)t=`https://api.stackone.com`;else if(n===`staging`)t=`https://api.stackone-dev.com`;else{let e=await Oe({message:`API URL`,placeholder:ct,initialValue:ct,validate:e=>{if(!e||e.trim().length===0)return`API URL is required`;try{new URL(e)}catch{return`Please enter a valid URL`}}});if(we(e))return xe(`Configuration profile initialization cancelled`),process.exit(0);t=e}let r=await Ee({message:`API Key`,validate:e=>{if(!e||e.trim().length===0)return`API Key is required`}});if(we(r))return xe(`Configuration profile initialization cancelled`),process.exit(0);nt(e,{label:e,environment:n,apiUrl:t,apiKey:r}),Te(`${y.green(`✔`)} Configuration profile ${a(e)} initialized successfully!`),process.exit(0)}catch(t){t?.isTtyError?e.error(`Prompt couldn't be rendered in the current environment`):e.error(`Failed to initialize configuration profile: ${t}`),process.exit(1)}}};const $={pending:`○`,acceptRemote:`●`,acceptLocal:`◐`,acceptBoth:`◑`,current:`◉`,arrow:`→`,check:`✓`,cross:`✗`,warning:`⚠`};var ut=class{constructor(e,t,n,r){this.conflicts=[],this.currentIndex=0,this.totalConflicts=0,this.currentCleanup=null,this.connectorId=t,this.localVersion=n,this.remoteVersion=r,this.conflicts=e.map(e=>({conflict:e,choice:e.type===`unchanged`?`remote`:`pending`})),this.totalConflicts=e.filter(e=>e.type===`conflict`).length}resetForReResolution(){this.currentIndex=0}async resolve(){return this.totalConflicts===0?{cancelled:!1,states:this.conflicts}:(this.moveToNextConflict(),new Promise(e=>{let t=Ne({input:process.stdin,output:process.stdout});process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume(),this.render();let n=n=>{let r=n.toString();if(r===``){this.cleanup(t),this.renderCancelled(),e({cancelled:!0,states:this.conflicts});return}if(r===`\x1B`&&n.length===1){this.cleanup(t),this.renderCancelled(),e({cancelled:!0,states:this.conflicts});return}if(r.startsWith(`\x1B[`)){switch(r.slice(2)){case`D`:this.moveToPrevConflict(),this.render();break;case`C`:this.moveToNextConflict(),this.render();break}return}switch(r){case`r`:case`R`:this.setCurrentChoice(`remote`),this.advanceAfterChoice(t);break;case`l`:case`L`:this.setCurrentChoice(`local`),this.advanceAfterChoice(t);break;case`b`:case`B`:this.setCurrentChoice(`both`),this.advanceAfterChoice(t);break;case`\r`:case`
|
|
91
98
|
`:this.allResolved()?(this.cleanup(t),e({cancelled:!1,states:this.conflicts})):(this.moveToNextUnresolved(),this.render());break;case`q`:case`Q`:this.cleanup(t),this.renderCancelled(),e({cancelled:!0,states:this.conflicts});break;case`a`:case`A`:this.acceptAllRemaining(`remote`),this.render();break;case`u`:case`U`:this.setCurrentChoice(`pending`),this.render();break}};process.stdin.on(`data`,n),this.currentCleanup=()=>{process.stdin.removeListener(`data`,n),process.stdin.isTTY&&process.stdin.setRawMode(!1),t.close()}}))}cleanup(e){this.currentCleanup?(this.currentCleanup(),this.currentCleanup=null):(process.stdin.isTTY&&process.stdin.setRawMode(!1),e.close())}advanceAfterChoice(e){this.allResolved()||this.moveToNextUnresolved(),this.render()}render(){r();let e=process.stdout.columns||80;this.renderHeader(e),this.renderProgressBar(e),this.renderCurrentConflict(e),this.renderControls(e)}renderHeader(t){let n=this.connectorId,r=`${this.localVersion} ${$.arrow} ${this.remoteVersion}`,i=Math.max(0,t-17),a=Math.floor(i/2),o=i-a,s=` `.repeat(a)+`CONFLICT RESOLVER`+` `.repeat(o);e.log(``),e.log(y.bgBlue.white.bold(s)),e.log(y.gray(this.centerText(n,t))),e.log(y.gray(this.centerText(r,t))),e.log(``)}renderProgressBar(t){let n=this.conflicts.filter(e=>e.conflict.type===`conflict`),r=this.getCurrentConflictIndex(),i=n.map((e,t)=>{let n=t===r,i,a;switch(e.choice){case`remote`:i=n?$.current:$.acceptRemote,a=y.green;break;case`local`:i=n?$.current:$.acceptLocal,a=y.yellow;break;case`both`:i=n?$.current:$.acceptBoth,a=y.cyan;break;default:i=n?$.current:$.pending,a=n?y.white:y.gray}return a(i)}),a=n.filter(e=>e.choice!==`pending`).length,o=` Conflict ${r+1} of ${this.totalConflicts} • ${a}/${this.totalConflicts} resolved `;e.log(y.gray(this.centerText(o,t))),e.log(this.centerText(i.join(` `),t)),e.log(``)}renderCurrentConflict(t){let n=this.conflicts[this.currentIndex];if(!n||n.conflict.type!==`conflict`)return;let r=n.conflict;if(e.log(y.gray(`_`.repeat(t))),e.log(`
|
|
@@ -101,9 +108,9 @@ Token saved to:`)),e.log(y.cyan(` ~/.stackone/agent-config.json`)),e.log(``),pr
|
|
|
101
108
|
`),c=i.length>20?`\n${y.gray(`... and ${i.length-20} more lines`)}`:``;e.log(`${t}\n\n${s}${c}`)}e.log(`
|
|
102
109
|
|
|
103
110
|
`),e.log(y.gray(`_`.repeat(t))),e.log(``)}renderControls(t){let n=[y.green(`[R] Accept Remote`),y.yellow(`[L] Keep Local`),y.cyan(`[B] Keep Both`),y.gray(`[U] Undo`)],r=[y.gray(`[←/→] Navigate`),y.gray(`[A] Accept all remaining`)],i=this.allResolved()?[y.green.bold(`[Enter] Apply Changes`),y.gray(`[Esc] Cancel`)]:[y.gray(`[Enter] Next Unresolved`),y.gray(`[Esc] Cancel`)];e.log(this.centerText(n.join(` `),t)),e.log(``),e.log(this.centerText(r.join(` `),t)),e.log(``),e.log(this.centerText(i.join(` `),t)),this.allResolved()&&(e.log(``),e.log(y.green.bold(this.centerText(`✓ All conflicts resolved!`,t))))}renderFinalSummary(){r();let t=this.conflicts.filter(e=>e.conflict.type===`conflict`),n=0,i=0,a=0;for(let e of t)switch(e.choice){case`remote`:n++;break;case`local`:i++;break;case`both`:a++;break}let o=[y.green.bold(`Conflict resolution complete`),``,`${y.bold(this.totalConflicts)} conflicts resolved:`,``,`${y.green($.acceptRemote)} Accepted remote: ${n}`,`${y.yellow($.acceptLocal)} Kept local: ${i}`,`${y.cyan($.acceptBoth)} Kept both: ${a}`];e.box(o.join(`
|
|
104
|
-
`))}renderCancelled(){r(),e.log(y.yellow(`Conflict resolution cancelled`)),e.log(``),e.log(`No changes were made to your local connector file.`)}getCurrentConflictIndex(){let e=-1;for(let t=0;t<=this.currentIndex&&t<this.conflicts.length;t++)this.conflicts[t].conflict.type===`conflict`&&e++;return e}moveToNextConflict(){for(let e=this.currentIndex+1;e<this.conflicts.length;e++)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}for(let e=0;e<this.currentIndex;e++)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}}moveToPrevConflict(){for(let e=this.currentIndex-1;e>=0;e--)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}for(let e=this.conflicts.length-1;e>this.currentIndex;e--)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}}moveToNextUnresolved(){for(let e=this.currentIndex+1;e<this.conflicts.length;e++)if(this.conflicts[e].conflict.type===`conflict`&&this.conflicts[e].choice===`pending`){this.currentIndex=e;return}for(let e=0;e<this.currentIndex;e++)if(this.conflicts[e].conflict.type===`conflict`&&this.conflicts[e].choice===`pending`){this.currentIndex=e;return}}setCurrentChoice(e){this.conflicts[this.currentIndex]?.conflict.type===`conflict`&&(this.conflicts[this.currentIndex].choice=e)}allResolved(){return this.conflicts.filter(e=>e.conflict.type===`conflict`).every(e=>e.choice!==`pending`)}acceptAllRemaining(e){for(let t of this.conflicts)t.conflict.type===`conflict`&&t.choice===`pending`&&(t.choice=e)}centerText(e,t){let n=this.stripAnsi(e),r=Math.max(0,Math.floor((t-n.length)/2));return` `.repeat(r)+e}stripAnsi(e){return e.replace(/\x1b\[[0-9;]*m/g,``)}getResolvedContent(){let e=[];for(let t of this.conflicts)if(t.conflict.type===`unchanged`)e.push(t.conflict.content||``);else if(t.conflict.type===`conflict`)switch(t.choice){case`remote`:t.conflict.remote&&e.push(t.conflict.remote);break;case`local`:t.conflict.local&&e.push(t.conflict.local);break;case`both`:t.conflict.local&&e.push(t.conflict.local),t.conflict.remote&&e.push(t.conflict.remote);break;case`pending`:t.conflict.remote&&e.push(t.conflict.remote);break}return e.join(``)}};const dt=`https://api.stackone.com`;var ft=class{async execute({profile:t,connector:n,outputPath:r,apiUrl:o,apiKey:s}={}){if(
|
|
111
|
+
`))}renderCancelled(){r(),e.log(y.yellow(`Conflict resolution cancelled`)),e.log(``),e.log(`No changes were made to your local connector file.`)}getCurrentConflictIndex(){let e=-1;for(let t=0;t<=this.currentIndex&&t<this.conflicts.length;t++)this.conflicts[t].conflict.type===`conflict`&&e++;return e}moveToNextConflict(){for(let e=this.currentIndex+1;e<this.conflicts.length;e++)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}for(let e=0;e<this.currentIndex;e++)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}}moveToPrevConflict(){for(let e=this.currentIndex-1;e>=0;e--)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}for(let e=this.conflicts.length-1;e>this.currentIndex;e--)if(this.conflicts[e].conflict.type===`conflict`){this.currentIndex=e;return}}moveToNextUnresolved(){for(let e=this.currentIndex+1;e<this.conflicts.length;e++)if(this.conflicts[e].conflict.type===`conflict`&&this.conflicts[e].choice===`pending`){this.currentIndex=e;return}for(let e=0;e<this.currentIndex;e++)if(this.conflicts[e].conflict.type===`conflict`&&this.conflicts[e].choice===`pending`){this.currentIndex=e;return}}setCurrentChoice(e){this.conflicts[this.currentIndex]?.conflict.type===`conflict`&&(this.conflicts[this.currentIndex].choice=e)}allResolved(){return this.conflicts.filter(e=>e.conflict.type===`conflict`).every(e=>e.choice!==`pending`)}acceptAllRemaining(e){for(let t of this.conflicts)t.conflict.type===`conflict`&&t.choice===`pending`&&(t.choice=e)}centerText(e,t){let n=this.stripAnsi(e),r=Math.max(0,Math.floor((t-n.length)/2));return` `.repeat(r)+e}stripAnsi(e){return e.replace(/\x1b\[[0-9;]*m/g,``)}getResolvedContent(){let e=[];for(let t of this.conflicts)if(t.conflict.type===`unchanged`)e.push(t.conflict.content||``);else if(t.conflict.type===`conflict`)switch(t.choice){case`remote`:t.conflict.remote&&e.push(t.conflict.remote);break;case`local`:t.conflict.local&&e.push(t.conflict.local);break;case`both`:t.conflict.local&&e.push(t.conflict.local),t.conflict.remote&&e.push(t.conflict.remote);break;case`pending`:t.conflict.remote&&e.push(t.conflict.remote);break}return e.join(``)}};const dt=`https://api.stackone.com`;var ft=class{async execute({profile:t,connector:n,outputPath:r,apiUrl:o,apiKey:s}={}){if(Y(n)&&(e.error(`Connector identifier is required`),e.log(`Please provide a connector identifier using the ${a(`--connector`)} option in the format: ${a(`provider_key@version`)} or ${a(`provider_key`)}`),e.log(`If no version is specified, the latest version will be pulled.`),process.exit(1)),!t&&!s&&(e.error(`Profile or API key is required`),e.log(`Please provide a profile using the ${a(`--profile`)} option or an API key using the ${a(`--api-key`)} option.`),e.log(`To create a profile, run ${a(`stackone init`)}.`),process.exit(1)),t&&s&&(e.error(`Please provide either a profile or an API key, not both`),process.exit(1)),t&&o&&e.warn(`Specifying ${a(`--api-url`)} with a profile won't have any effect. Using API url from profile.`),t&&!tt(t)){e.error(`Configuration profile ${a(t)} not found`),e.log(`Run ${a(`stackone init`)} to create a new configuration profile.\n`);let n=rt();n.length>0&&(e.info(`Available configuration profiles:`),n.forEach(t=>{e.log(` - ${y.blue(t)}`)})),process.exit(1)}let c=t?et(t):{apiUrl:o??dt,apiKey:s};c?.apiKey||(e.error(`API key is missing`),e.log(`Please provide a valid API key in the profile or via the ${a(`--api-key`)} option.`),process.exit(1));let l=c.apiUrl??dt,[u,d]=n.split(`@`),f=await this.#f(u,l,c.apiKey,d??`latest`),p=this.#e(f),m=p.version??`unknown`,h=this.#t(r,p.key,m),g=this.#r(h),_=g===null,v=f;if(!_){let t=this.#i(g,h);t&&(e.warn(t.message),t.errors.length>0&&i(t.errors,!1),e.log(``));let r=t?void 0:this.#e(g);if(this.#o(g,f)){this.#a(g,f,h);let t=r?.version??`unknown`,i=await this.#s(g,f,n,t,m);i.action===`cancel`&&(xe(`Pull cancelled`),process.exit(0)),i.action===`keep-local`&&(e.log(``),e.info(`Keeping local version. No changes made.`),process.exit(0)),i.action===`interactive-cancel`&&process.exit(0),i.action===`interactive`&&(v=i.resolvedContent)}else e.info(`No changes detected in connector configuration.`),process.exit(0)}let ee=je(v).connector,b=ee?.key??p.key,x=ee?.version??m,S=this.#t(r,b,x),C=S;if(S!==h){let t=await this.#n(S);e.log(``),t!==void 0&&(C=t)}await this.#d(C,v),_?e.success(`Connector ${a(b)}@${a(x)} pulled successfully (new connector)`):e.success(`Connector ${a(b)}@${a(x)} updated successfully`);let te=b===p.key?a(b):`${a(p.key)} ${y.whiteBright(`→`)} ${a(b)}`,ne=x===m?a(x):`${a(m)} ${y.whiteBright(`→`)} ${a(x)}`,re=C===h?a(C):`${a(h)}\n ${y.whiteBright(`→`)} ${a(C)}`;e.log(`\n${y.blue.inverse(` CONNECTOR DETAILS `)}\n`),e.log(` Provider: ${te}`),e.log(` Version: ${ne}`),e.log(` Output file: ${re}`),process.exit(0)}#e(t){let n=je(t),r=n?.errors??[];if(n.success)return n.connector;e.error(`Connector pulled from the registry is not valid`),e.log(`Please make sure you are using the latest version of the StackOne CLI by running ${a(`stackone update`)}`),r.length>0&&i(r,!0),process.exit(1)}#t(t,n,r){let i=`${n}_v${r.replaceAll(`.`,`-`)}.s1.yaml`;return t?(L.existsSync(t)&&(L.statSync(t).isDirectory()||(e.error(`Output path ${a(t)} is not a directory`),e.log(`Please provide a valid directory path to store connectors or use the default path.`),process.exit(1))),z.resolve(t,n,i)):z.resolve(process.cwd(),`connectors`,n,i)}async#n(t){if(!L.existsSync(t))return;let n=z.basename(t),r=z.dirname(t);e.warn(`File ${a(n)} already exists at ${a(r)}`);let i=await De({message:`How would you like to proceed?`,options:[{value:`override`,label:`Override existing file`,hint:`Replace the existing file with the new content`},{value:`rename`,label:`Save with a different name`,hint:`Provide a new filename for the connector`},{value:`cancel`,label:`Cancel`,hint:`Abort the pull operation`}]});if((we(i)||i===`cancel`)&&(xe(`Operation cancelled. No local changes were made.`),process.exit(0)),i===`override`)return;let o=await Oe({message:`Enter the new filename:`,placeholder:n,validate:e=>{if(!e||e.trim()===``)return`Filename cannot be empty`;if(!e.endsWith(`.s1.yaml`))return`Filename must end with .s1.yaml`;let t=z.join(r,e.trim());if(L.existsSync(t))return`File ${e} already exists`}});return we(o)&&(xe(`Operation cancelled. No local changes were made.`),process.exit(0)),z.join(r,o.trim())}#r(e){if(!L.existsSync(e))return null;try{return L.readFileSync(e,`utf-8`)}catch{return null}}#i(e,t){try{let n=je(e);if(!n.success){let e=n.errors??[];return{message:`Local connector ${a(z.basename(t))} has validation errors:`,errors:e}}}catch(e){return{message:`Local connector ${a(z.basename(t))} could not be validated: ${e.message}`,errors:[]}}return null}#a(t,n,r){let i=Me(t,n);if(!i.some(e=>e.added||e.removed)){e.info(`No changes detected in connector configuration.`);return}e.log(`${y.blue.inverse(` CHANGES `)}\n`),e.log(y.gray(`--- local: ${r}`)),e.log(y.gray(`+++ remote: StackOne Registry`)),e.log(``);let a=0,o=0;for(let t of i){let n=t.value.split(`
|
|
105
112
|
`).filter(e=>e!==``);if(t.added){a+=n.length;for(let t of n)e.log(y.green(`+ ${t}`))}else if(t.removed){o+=n.length;for(let t of n)e.log(y.red(`- ${t}`))}else if(n.length<=6)for(let t of n)e.log(y.gray(` ${t}`));else{for(let t=0;t<3;t++)e.log(y.gray(` ${n[t]}`));e.log(y.gray(` ... (${n.length-6} unchanged lines)`));for(let t=n.length-3;t<n.length;t++)e.log(y.gray(` ${n[t]}`))}}e.log(``),e.log(y.gray(`Summary: ${y.green(`+${a}`)} additions, ${y.red(`-${o}`)} deletions`))}#o(e,t){return Me(e,t).some(e=>e.added||e.removed)}async#s(t,n,r,i,a){e.log(``);let o=await De({message:`How would you like to resolve the differences?`,options:[{value:`override`,label:`Override local with remote`,hint:`Replace your local file with the StackOne version`},{value:`keep-local`,label:`Keep local version`,hint:`Cancel the pull and keep your current file`},{value:`interactive`,label:`Resolve conflicts interactively`,hint:`Choose which changes to accept one by one`},{value:`cancel`,label:`Cancel`,hint:`Abort the pull operation`}]});if(we(o))return{action:`cancel`};if(o===`override`)return{action:`override`};if(o===`keep-local`)return{action:`keep-local`};if(o===`interactive`){let e=await this.#c(t,n,r,i,a);return e===null?{action:`interactive-cancel`}:{action:`interactive`,resolvedContent:e}}return{action:`cancel`}}async#c(t,n,i,a,o){let s=Me(t,n),c=this.#u(s);if(c.length===0)return e.info(`No conflicts to resolve.`),n;let l=new ut(c,i,a,o);for(;;){if((await l.resolve()).cancelled)return null;let t=l.getResolvedContent(),n=je(t);if(n.success)return l.renderFinalSummary(),t;let i=await this.#l(n.errors);if(i===`cancel`)return r(),e.info(`Operation cancelled. No changes were made to the local connector.`),null;if(i===`save`)return r(),e.warn(`The connector was saved but it is invalid`),t;l.resetForReResolution()}}async#l(t){let{createInterface:n}=await import(`readline`);return new Promise(i=>{r();let a=(t||[{message:`Unknown validation error`}]).map(e=>` • ${e.message}`).join(`
|
|
106
|
-
`);e.box({title:`⚠️ Validation Failed`,message:`The resolved connector configuration is invalid:\n\n${a}`,style:{borderColor:`yellow`,padding:1}}),e.log(``),e.log(y.bold(` Choose an action:`)),e.log(``),e.log(y.cyan(` [B]`)+` ← Go back to conflict resolution`),e.log(y.dim(` Modify your choices to fix the validation errors`)),e.log(``),e.log(y.yellow(` [S]`)+` 💾 Save anyway`),e.log(y.dim(` Save the invalid configuration (not recommended)`)),e.log(``),e.log(y.red(` [C]`)+` ✖ Cancel`),e.log(y.dim(` Discard all changes`)),e.log(``);let o=n({input:process.stdin,output:process.stdout});process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume();let s=e=>{let t=e.toString().toLowerCase(),n=()=>{process.stdin.removeListener(`data`,s),process.stdin.isTTY&&process.stdin.setRawMode(!1),o.close()};if(t===``||t===`\x1B`){n(),i(`cancel`);return}switch(t){case`b`:n(),i(`back`);break;case`s`:n(),i(`save`);break;case`c`:case`q`:n(),i(`cancel`);break}};process.stdin.on(`data`,s)})}#u(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(!r.added&&!r.removed)t.push({type:`unchanged`,content:r.value}),n++;else if(r.removed){let i=e[n+1];i?.added?(t.push({type:`conflict`,local:r.value,remote:i.value}),n+=2):(t.push({type:`conflict`,local:r.value,remote:void 0}),n++)}else r.added&&t.push({type:`conflict`,local:void 0,remote:r.value}),n++}return t}async#d(t,n){let r=
|
|
113
|
+
`);e.box({title:`⚠️ Validation Failed`,message:`The resolved connector configuration is invalid:\n\n${a}`,style:{borderColor:`yellow`,padding:1}}),e.log(``),e.log(y.bold(` Choose an action:`)),e.log(``),e.log(y.cyan(` [B]`)+` ← Go back to conflict resolution`),e.log(y.dim(` Modify your choices to fix the validation errors`)),e.log(``),e.log(y.yellow(` [S]`)+` 💾 Save anyway`),e.log(y.dim(` Save the invalid configuration (not recommended)`)),e.log(``),e.log(y.red(` [C]`)+` ✖ Cancel`),e.log(y.dim(` Discard all changes`)),e.log(``);let o=n({input:process.stdin,output:process.stdout});process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume();let s=e=>{let t=e.toString().toLowerCase(),n=()=>{process.stdin.removeListener(`data`,s),process.stdin.isTTY&&process.stdin.setRawMode(!1),o.close()};if(t===``||t===`\x1B`){n(),i(`cancel`);return}switch(t){case`b`:n(),i(`back`);break;case`s`:n(),i(`save`);break;case`c`:case`q`:n(),i(`cancel`);break}};process.stdin.on(`data`,s)})}#u(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(!r.added&&!r.removed)t.push({type:`unchanged`,content:r.value}),n++;else if(r.removed){let i=e[n+1];i?.added?(t.push({type:`conflict`,local:r.value,remote:i.value}),n+=2):(t.push({type:`conflict`,local:r.value,remote:void 0}),n++)}else r.added&&t.push({type:`conflict`,local:void 0,remote:r.value}),n++}return t}async#d(t,n){let r=z.dirname(t);L.existsSync(r)||L.mkdirSync(r,{recursive:!0});try{L.writeFileSync(t,n,`utf-8`)}catch(n){e.error(`Failed to write connector to file ${a(t)}: ${n.message}`),process.exit(1)}}async#f(t,n,r,i){let o=K(`Pulling connector ${a(t)}@${a(i)} from registry...`).start();try{let e=Buffer.from(r).toString(`base64`),a=`${n}/registry/connectors/${t}@${i}`,s=await fetch(a,{method:`GET`,headers:{Authorization:`Basic ${e}`}});return o.stop(),s.ok||(await this.#p(s,t,i),process.exit(1)),await s.text()}catch(r){o.stop(),e.error(`Failed to pull connector ${a(t)}@${a(i)} from the registry: ${r.message}`),e.log(`Please ensure that the API at ${g(n)} is reachable and the API key is valid.`),process.exit(1)}}async#p(t,n,r){switch(t.status){case 401:case 403:e.error(`Access denied`),e.log(`Please ensure that your API key is valid and has the ${a(`connectors:read`)} scope required to pull connectors.`);break;case 404:e.error(`Connector ${a(n)}@${a(r)} was not found in the registry`),await this.#m(n);break;case 429:e.error(`Rate limit exceeded`),e.log(`Too many requests. Please wait a moment before trying again.`);break;default:await l(t,`Failed to pull connector ${a(n)}`)}}async#m(t){e.info(`To see available versions, check the connector documentation or contact support.`)}};const pt=`https://api.stackone.com`;var mt=class{async execute({profile:t,fileOrDir:n,apiUrl:r,apiKey:i}={}){if(!t&&!i&&(e.error(`Profile or API key is required`),e.log(`Please provide a profile using the ${a(`--profile`)} option or an API key using the ${a(`--api-key`)} option.`),e.log(`To create a profile, run ${a(`stackone init`)}.`),process.exit(1)),t&&i&&(e.error(`Please provide either a profile or an API key, not both`),process.exit(1)),t&&r&&e.warn(`Specifying ${a(`--api-url`)} with a profile won't have any effect. Using API url from profile.`),t&&!tt(t)){e.error(`Configuration profile ${a(t)} not found`),e.log(`Run ${a(`stackone init`)} to create a new configuration profile.\n`);let n=rt();n.length>0&&(e.info(`Available configuration profiles:`),n.forEach(t=>{e.log(` - ${y.blue(t)}`)})),process.exit(1)}let o=t?et(t):{apiUrl:r??pt,apiKey:i};o?.apiKey||(e.error(`API key is missing`),e.log(`Please provide a valid API key in the profile or via the ${a(`--api-key`)} option.`),process.exit(1)),n||(e.error(`File or directory is required.`),process.exit(1));try{pe(n)}catch{e.error(`File or directory not found: ${y.red(n)}`),process.exit(1)}let s=pe(n),c=o.apiUrl??pt;if(s.isDirectory()){let t=gt(n),r=0;t.length===0?(e.error(`No .s1.yaml connector files found in the directory: ${n}.`),process.exit(1)):(e.start(`Found ${t.length} connector(s) file(s). Pushing to registry...`),e.log(``));for(let e of t)await this.uploadFile(e,c,o.apiKey)&&r++;r===0?e.error(`Error while pushing connectors: no files were uploaded`):(e.log(``),e.info(`Upload completed: ${y.green(r)} of ${y.blue(t.length)} file(s) uploaded successfully.`)),process.exit(r>0?0:1)}else n.endsWith(`.s1.yaml`)||(e.error(`Only ${a(`.s1.yaml`)} files are supported for upload`),process.exit(1));let l=await this.uploadFile(n,c,o.apiKey);process.exit(l?0:1)}async uploadFile(t,n,r){let i=K(`📤 Pushing connector in ${me(t)}...`).start();try{let o=ht(t);if(!o)return!1;let s=me(t),c=new FormData,u=new Blob([o],{type:`application/x-yaml`});c.append(`file`,u,s);let d=Buffer.from(r).toString(`base64`),f=await fetch(`${n}/registry/connectors`,{method:`POST`,headers:{Authorization:`Basic ${d}`},body:c});if(i.stop(),!f.ok)return await l(f,`Failed to push connector in ${a(s)} to the registry`),!1;let p=await f.json();return e.success(`Successfully uploaded ${a(s)} with connector ${a(p.provider)}@${a(p.version)}`),!0}catch(r){return i.stop(),e.error(`Failed to upload file ${a(t)}: ${r}`),e.log(`Please ensure that the API at ${g(n)} is reachable and the API key is valid`),!1}}};const ht=t=>{let n=ke(t),r=je(n),a=r?.errors??[];if(r.success)return n;a.length>0?(e.error(`Connector in ${o(t)} is not valid`),i(a,!0)):e.error(`Connector in ${o(t)} is not valid. Please check the file for errors.`)},gt=e=>{let t=[],n=fe(e,{withFileTypes:!0});for(let r of n){let n=B(e,r.name);r.isDirectory()?t.push(...gt(n)):r.name.endsWith(`.s1.yaml`)&&t.push(n)}return t},_t=Q.object({provider_key:Q.string().optional(),provider_version:Q.string().optional(),auth_config_key:Q.string(),environment:Q.string().default(`production`),organization_id:Q.string().default(`cli-organization-id`),account_id:Q.string().default(`cli-account-secure-id`),project_id:Q.string().default(`cli-project-secure-id`),credentials:Q.record(Q.string(),Q.any()).default({})}),vt=Q.record(Q.string(),Q.any()),yt=Q.object({path:Q.record(Q.string(),Q.any()).default({}),queryParams:Q.record(Q.string(),Q.any()).default({}),header:Q.record(Q.string(),Q.any()).default({}),body:Q.record(Q.string(),Q.any()).default({})}),bt=`https://api.stackone.com`;var xt=class{async execute({connector:t,action:n,actionId:r,account:i,accountId:o,params:s,credentials:c,profile:l,outputFile:u,debug:d,apiUrl:p,apiKey:m}={}){if(!l&&!m&&o&&(e.error(`Profile or API key is required when providing an account ID`),e.log(`Please provide a profile using the ${a(`--profile`)} option or an API key using the ${a(`--api-key`)} option.`),e.log(`To create a profile, run ${a(`stackone init`)}.`),process.exit(1)),l&&m&&(e.error(`Please provide either a profile or an API key, not both`),process.exit(1)),l&&p&&e.warn(`Specifying --api-url with a profile won't have any effect. Using API url from profile.`),l&&!tt(l)){e.error(`Configuration profile ${a(l)} not found`),e.log(`Run ${a(`stackone init`)} to create a new configuration profile.\n`);let t=rt();t.length>0&&(e.info(`Available configuration profiles:`),t.forEach(t=>{e.log(` - ${y.blue(t)}`)})),process.exit(1)}let h=l?et(l):{apiUrl:p??bt,apiKey:m};Y(i)&&Y(o)&&(e.error(`A valid account or account ID is required to run an action`),process.exit(1));let g;if(Z(t))if(this.#a(t)){!l&&!m&&(e.error(`Profile or API key is required when using a connector identifier`),e.log(`Please provide a profile using the ${a(`--profile`)} option or an API key using the ${a(`--api-key`)} option.`),e.log(`Run ${a(`stackone init`)} to create a new configuration profile.`),process.exit(1));let n=this.#o(t);g=await this.#s(n,h?.apiUrl??bt,h?.apiKey)}else g=this.#e(t);else Z(o)&&(g=await this.#c(o,h?.apiUrl??bt,h?.apiKey));let _=Z(n)?this.#r(n,t):g;Y(_)&&(e.error(`A valid connector is required to run an action.`),process.exit(1));let v=Z(_?.actions)?Object.keys(_?.actions).length:0,ee=Z(_?.actions)?Object.keys(_.actions)[v-1]:void 0,b=Z(ee)?_?.actions?.[ee]?.id:void 0,x=(Z(r)&&!r?.startsWith(`${_.key}_`)?`${_.key}_${r}`:r)??b;Y(x)&&(e.error(`A valid action ID is required to run an action`),process.exit(1));let S=Z(o)?await this.#l(o,h?.apiUrl??bt,h?.apiKey):{},C=Z(i)?this.#i(i,_.key??`unknown`,_.version??`unknown`):void 0,te=Z(c)?this.#u(c):{},ne={...S,...C,credentials:{...S.credentials??{},...te}};Y(ne)&&(e.error(`A valid account data is required to run an action.`),process.exit(1));let re=_.actions?.[x];Y(re)&&(e.error(`Action ID ${a(x)} not found in the connector ${a(_.key)}@${a(_.version)}.`),process.exit(1));let w=Z(s)?this.#d(s,x):{path:{},queryParams:{},header:{},body:{}},T=Date.now(),E=await this.#f({connector:_,actionId:x,account:ne,queryParams:{...w.queryParams,...d?{debug:`true`}:{}},pathParams:w.path,body:w.body,headers:w.header}),D=Date.now()-T;if(Z(u))try{L.writeFileSync(u,JSON.stringify(E.output,null,2),`utf-8`),e.info(`Output written to file: ${u}`)}catch(t){e.error(`Failed to write output to file ${u}: ${t.message}`),process.exit(1)}else e.log(`\n${y.blue.inverse(` ACTION OUTPUT `)}`),f(E.output);e.log(``),e.info(`Action ${a(x)} from connector ${a(_?.key)}@${a(_?.version)} finished in ${y.yellowBright((D/1e3).toFixed(2))} seconds.`),process.exit(0)}#e=e=>{let t=e;try{t=ke(e)}catch{}return t?this.#n(t):void 0};#t=t=>{try{return ke(t)}catch(n){e.error(`Failed to load connector file from ${a(t)}: ${n.message}`),process.exit(1)}};#n=t=>{let n=je(t),r=n?.errors??[];if(n.success)return n.connector||(e.error(`Failed to load connector.`),process.exit(1)),n.connector;r.length>0?(e.error(`Connector is not valid`),i(r,!0),process.exit(1)):(e.error(`Connector is not valid. Please check the file for errors.`),process.exit(1))};#r=(t,n)=>{let r=t;try{r=L.readFileSync(t,`utf-8`)}catch{}Y(n)&&(e.error(`A valid connector is required to load an action.`),process.exit(1));let i=`${this.#t(n)} - ${r.split(`
|
|
107
114
|
`).map((e,t)=>t===0?e:` ${e}`).join(`
|
|
108
|
-
`)}`;return this.#n(i)};#i=(t,n,r)=>{let a=t;try{a=L.readFileSync(t,`utf-8`)}catch{}try{let e=_t.parse(JSON.parse(a));return{providerKey:n,providerVersion:r,authConfigKey:e.auth_config_key,environment:e.environment,organizationId:e.organization_id,secureId:e.account_id,projectSecureId:e.project_id}}catch(t){let n=[];try{n=JSON.parse(t.message)}catch{}e.error(`Failed to parse account information`),i(n,!1),n.length===0&&e.log(t.message),process.exit(1)}};#a=e=>!e.includes(`/`)&&!e.includes(`\\`)&&!e.endsWith(`.yaml`)&&!e.endsWith(`.yml`)?e.includes(`@`)?e.split(`@`).length===2:!0:!1;#o=e=>e.includes(`@`)?e:`${e}@latest`;#s=async(t,n,r)=>{(
|
|
109
|
-
Exiting watch mode...`)),process.exit(0)};wt(),e.start(`Validating connectors...`);let c=await kt(o);t=Et(t,c||{}),Dt(t,o),a.start();let l=n(o,{persistent:!0,ignoreInitial:!0}),u=async n=>{if(!n.endsWith(`.s1.yaml`)&&!n.endsWith(`s1.partial.yaml`))return;let i=n.endsWith(`s1.partial.yaml`)?await jt(n):[n];if(!(!i||i.length===0)){r(),a.stop(),wt(),e.log(y.gray(`File change detected: ${n}`)),e.start(`Validating connectors...`);for(let e of i){let n=await kt(e);t=Et(t,n||{})}Dt(t,o),a.start()}};l.on(`change`,async e=>await u(e)),process.stdin.on(`data`,e=>{e.toString()===`q`&&s()}),process.on(`SIGINT`,()=>{s()})}else await kt(o,e),process.exit(0)}};const Et=(e,t)=>{for(let[n,r]of Object.entries(t))e[n]=r;return e},Dt=(t,n)=>{r(),wt();let o=0,s=0;for(let[n,r]of Object.entries(t))r===null?o++:(e?.error(`Connector ${a(n)} is not valid`),i(r,!0),s++);e.log(``),e.log(y.blue.inverse(` Validation Summary `)),e.log(`Connectors path: ${a(n)}`),e.log(`${o===0?y.red(`0`):y.green(o)} valid, ${s===0?y.green(`0`):y.red(s)} invalid connectors\n`)},Ot=async e=>{let t=[],n=await Ie(e);for(let r of n){let n=me(e,r),i=await Le(n);i.isDirectory()?t.push(...await Ot(n)):i.isFile()&&r.endsWith(`.s1.yaml`)&&t.push(n)}return t},kt=async(e,t)=>{let n=await Le(e),r={};if(n.isDirectory()){let n=await Ot(e);if(n.length===0)return t?.error(`No StackOne connector found in ${o(e)}`),t?.log(`Connector files need to have the extension ${a(`*.s1.yaml`)}`),null;let i=0,s=0;for(let e of n){let n=await At(e,t);n===null?i++:(t?.log(``),s++),r[e]=n}return t?.log(``),t?.log(y.blue.inverse(` Validation Summary `)),t?.log(`${i===0?y.red(`0`):y.green(i)} valid, ${s===0?y.green(`0`):y.red(s)} invalid connectors`),r}else if(n.isFile()&&e.endsWith(`s1.yaml`))return r[e]=await At(e,t),r;else if(n.isFile()&&e.endsWith(`partial.yaml`)){t?.error(`Partial connector files cannot be validated directly`),t?.log(`The file ${o(e)} is a partial connector file.`);let n=await jt(e);return n&&n?.length>0&&t?.log(`Did you mean ${a(n[0])}?`),null}else return t?.error(`No StackOne connector found in ${o(e)}`),t?.log(`Connector files need to have the extension ${a(`*.s1.yaml`)}`),null},At=async(e,t)=>{let n=je(ke(e)),r=n?.errors??[];if(n.success){let n=e.split(`/`).pop()||e;return t?.success(`Connector ${a(n)} is valid!`),null}else if(r.length>0)return t?.error(`Connector ${a(e)} is not valid`),t&&i(r,!0),r;else return t?.error(`Connector ${a(e)} is not valid. Please check the file for errors`),[]},jt=async e=>{let t=pe(e);try{return(await Ie(t)).filter(e=>e.endsWith(`.s1.yaml`))?.map(e=>me(t,e))}catch{}};function Mt(){let e=process.env.LANGSMITH_API_KEY,t=process.env.LANGSMITH_PROJECT||`stackone-agent-cli`;e&&(ne({apiKey:e,projectName:t,enabled:!0,metadata:{source:`cli`,version:process.env.npm_package_version||`unknown`}}),process.env.VERBOSE&&console.log(`[Telemetry] LangSmith initialized for project:`,t))}const Nt=k(se(),`.stackone`),Pt=k(Nt,`version-check.json`),Ft=(e=!1)=>{let t=zt(),n=Date.now();if(e||!t||n-t.lastCheckTime>1728e5){let e=It();e&&Lt(e)&&Rt(e),Bt({lastCheckTime:n})}},It=()=>{try{return ge(`npm view @stackone/cli version`,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:15e3}).trim()}catch{return null}},Lt=e=>{try{let t=Ve();return Fe.gt(e,t)}catch{return!1}},Rt=t=>{let n=Ve(),r=`Update available: ${y.dim(n)} → ${y.green(t)}`,i=`\n\nRun ${y.cyan(`stackone update`)} to update`;e.box(r,i)},zt=()=>{try{if(!E(Pt))return null;let e=ae(Pt,`utf-8`);return JSON.parse(e)}catch{return null}},Bt=e=>{try{E(Nt)||ie(Nt,{recursive:!0}),oe(Pt,JSON.stringify(e,null,2),`utf-8`)}catch{}};var Vt=class{constructor(e=new x,t=Ve()){this.program=e,this.version=t,Mt(),this.setupProgram(),this.registerCommands()}setupProgram(){this.program.name(`stackone`).description(`StackOne CLI`).version(this.version,`-v, --version`)}registerCommands(){let t=new lt,n=new mt,r=new ft,i=new at,a=new st,o=new Tt,s=new Xe,c=new Ze,l=new Ke,u=new Ue,d=new xt,f=new Ct;this.program.configureOutput({writeOut:e=>process.stdout.write(e),writeErr:e=>process.stderr.write(e),outputError:(e,t)=>{t(y.red(e))}}),this.program.command(`init`).option(`-e, --env <environment>`,`Specify the environment for the configuration profile`).description(`Initialize & create a StackOne CLI configuration profile`).action(e=>{t.execute({environment:e.env})}),this.program.command(`push`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new b(`<path>`,`Connector file or directory to push`)).description(`Push a connector to the StackOne registry`).action((e,t)=>{n.execute({profile:t.profile,fileOrDir:e,apiUrl:t.apiUrl,apiKey:t.apiKey})}),this.program.command(`drop`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new b(`<connector>`,`Connector identifier in format provider_key@version`)).description(`Drop a connector from the StackOne registry`).action((e,t)=>{i.execute({profile:t.profile,connector:e,apiUrl:t.apiUrl,apiKey:t.apiKey})}),this.program.command(`get`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-c, --connector <connector>`,`Connector identifier in format provider_key@version or provider_key (defaults to latest)`).option(`--account-id <account-id>`,`Account ID to fetch connector from`).option(`-f, --format <format>`,`Output format: yaml or json (default: yaml)`,`yaml`).option(`-o, --output-file <output-file>`,`File to write the output to`).description(`Get a connector from the StackOne registry`).action(e=>{a.execute({profile:e.profile,connector:e.connector,accountId:e.accountId,format:e.format,outputFile:e.outputFile,apiUrl:e.apiUrl,apiKey:e.apiKey})}),this.program.command(`pull`).option(`-c, --connector <connector>`,`Connector identifier in format provider_key@version or provider_key`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-o, --output <path>`,`Output directory for the connectors files (default: ./connectors)`).description(`Pull a connector configuration from StackOne registry to local filesystem`).action(e=>{r.execute({profile:e.profile,connector:e.connector,outputPath:e.output,apiUrl:e.apiUrl,apiKey:e.apiKey})}),this.program.command(`validate`).option(`-w, --watch`,`Run in watch mode`).addArgument(new b(`<path>`,`Connector file or directory with connectors to validate`)).description(`Validate a StackOne connector`).action((e,t)=>{o.execute({watchMode:t.watch,fileOrDir:e})}),this.program.command(`run`).option(`--connector <connector>`,`Connector file, inline YAML, or identifier (provider_key@version or provider_key for latest)`).option(`--action <action>`,`Action to execute on the connector (path to file or inline string action code)`).option(`--action-id <action-id>`,`Action ID to execute on the connector`).option(`--account <account>`,`Account details to use for running the connector (path to file or inline string account data)`).option(`--account-id <account-id>`,`Account ID to use for running the connector against (fetches connector from API if --connector not provided)`).option(`--params <params>`,`Action parameters (path to file or inline string with JSON parameters)`).option(`--credentials <credentials>`,`Credentials to use (path to file or inline string with JSON credentials)`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-o, --output-file <output-file>`,`File to write the output to`).option(`-d, --debug`,`Enables debug mode to include more details in the action execution output`).description(`Run a connector action`).action(e=>{d.execute({connector:e.connector,action:e.action,actionId:e.actionId,account:e.account,accountId:e.accountId,params:e.params,credentials:e.credentials,profile:e.profile,outputFile:e.outputFile,debug:e.debug,apiUrl:e.apiUrl,apiKey:e.apiKey})});let p=this.program.command(`agent`).description(`StackOne agent commands`);p.command(`setup`).option(`-g, --global`,`Setup global configuration`).option(`-l, --local`,`Setup local project configuration`).description(`Setup StackOne agent (global or local)`).action(e=>{e.global?s.execute():c.execute()}),p.command(`cleanup`).description(`Remove all API keys and credentials from configurations`).action(()=>{l.execute()}),p.command(`chat`).option(`-m, --mode <mode>`,`Mode: build, test, or research`,`build`).option(`-c, --connector <name>`,`Connector name`).option(`-a, --action <name>`,`Action name`).option(`-g, --goal <goal>`,`Initial goal/message`).option(`-t, --temperature <number>`,`Temperature (0-1, default: 0.5)`,parseFloat).option(`-v, --verbose`,`Enable verbose logging`).description(`Start an interactive chat session with the agent (use /commands in chat)`).action(async t=>{let n=[`build`,`test`,`research`];t.mode&&!n.includes(t.mode)&&(e.error(`❌ Error: Invalid mode "${t.mode}". Must be one of: ${n.join(`, `)}`),process.exit(1)),t.temperature!==void 0&&(isNaN(t.temperature)&&(e.error(`❌ Error: Temperature must be a valid number`),process.exit(1)),(t.temperature<0||t.temperature>1)&&(e.error(`❌ Error: Temperature must be between 0 and 1`),process.exit(1))),u.execute({mode:t.mode,connector:t.connector,action:t.action,goal:t.goal,temperature:t.temperature,verbose:t.verbose})}),this.program.command(`update`).option(`-f, --force`,`Force reinstall even if already on latest version`).description(`Update the CLI to the latest version`).action(e=>{f.execute({force:e.force})}),this.program.command(`version`).description(`Show version information`).action(async()=>{e.log(`${y.inverse.greenBright(`StackOne`)} ${y.grey(`CLI`)} ${y.whiteBright(this.version)}`),Ft(!0),process.exit(0)})}run(){process.argv.includes(`version`)||Ft(),this.program.parse(process.argv)}};export{Vt as t};
|
|
115
|
+
`)}`;return this.#n(i)};#i=(t,n,r)=>{let a=t;try{a=L.readFileSync(t,`utf-8`)}catch{}try{let e=_t.parse(JSON.parse(a));return{providerKey:n,providerVersion:r,authConfigKey:e.auth_config_key,environment:e.environment,organizationId:e.organization_id,secureId:e.account_id,projectSecureId:e.project_id}}catch(t){let n=[];try{n=JSON.parse(t.message)}catch{}e.error(`Failed to parse account information`),i(n,!1),n.length===0&&e.log(t.message),process.exit(1)}};#a=e=>!e.includes(`/`)&&!e.includes(`\\`)&&!e.endsWith(`.yaml`)&&!e.endsWith(`.yml`)?e.includes(`@`)?e.split(`@`).length===2:!0:!1;#o=e=>e.includes(`@`)?e:`${e}@latest`;#s=async(t,n,r)=>{(Y(t)||Y(n)||Y(r))&&(e.error(`Connector identifier, API URL, and API key are required to fetch connector from registry.`),process.exit(1));let i=K();try{i.text=`Fetching connector ${a(t)} from registry...`,i.start();let o=Buffer.from(r).toString(`base64`),s=await fetch(`${n}/registry/connectors/${t}`,{method:`GET`,headers:{Authorization:`Basic ${o}`}});i.stop(),s.ok||(await l(s,`Failed to fetch connector ${a(t)} from registry`),process.exit(1));let c=await s.text(),u=this.#n(c);return e.success(`Fetched connector ${a(u.key)}@${a(u.version)} from registry`),u}catch(r){i.stop(),e.error(`Failed to fetch connector ${a(t)} from registry: ${r.message}`),e.log(`Please ensure that the API at ${g(n)} is reachable and the API key is valid`),process.exit(1)}};#c=async(t,n,r)=>{(Y(t)||Y(n)||Y(r))&&(e.error(`Account ID, API URL, and API key are required to fetch connector`),process.exit(1));let i=K();try{i.text=`Fetching connector for account ${a(t)} from API...`,i.start();let o=Buffer.from(r).toString(`base64`),s=await fetch(`${n}/accounts/${t}/connector`,{method:`GET`,headers:{Authorization:`Basic ${o}`}});i.stop(),s.ok||(await l(s,`Failed to fetch connector`),process.exit(1));let c=await s.text(),u=this.#n(c);return e.success(`Fetched connector ${a(u.key)}@${a(u.version)} for account ${a(t)}`),u}catch(t){i.stop(),e.error(`Failed to fetch connector: ${t.message}`),e.log(`Please ensure that the API at ${g(n)} is reachable and the API key is valid`),process.exit(1)}};#l=async(t,n,r)=>{(Y(t)||Y(n)||Y(r))&&(e.error(`Account ID, API URL, and API key are required to fetch account information.`),process.exit(1));let i=K();try{i.text=`Fetching account ${a(t)} information from API...`,i.start();let o=Buffer.from(r).toString(`base64`),s=await fetch(`${n}/accounts/${t}/credentials`,{method:`GET`,headers:{Authorization:`Basic ${o}`}});i.stop(),s.ok||(await l(s,`Failed to fetch account ${a(t)} information`),process.exit(1));let c=await s.json();return e.success(`Fetched account ${a(t)} information from project ${a(c.project_id)}`),{providerKey:c.provider_key,providerVersion:c.provider_version,authConfigKey:c.auth_config_key,environment:c.environment,organizationId:c.organization_id,secureId:c.account_id,projectSecureId:c.project_id,credentials:c.credentials}}catch(r){i.stop(),e.error(`Failed to fetch account ${a(t)} information: ${r.message}`),e.log(`Please ensure that the API at ${g(n)} is reachable and the API key is valid`),process.exit(1)}};#u=t=>{let n=t;try{n=L.readFileSync(t,`utf-8`)}catch{}try{return vt.parse(JSON.parse(n))}catch(t){let n=[];try{n=JSON.parse(t.message)}catch{}e.error(`Failed to parse credentials`),i(n,!1),n.length===0&&e.log(t.message),process.exit(1)}};#d=(t,n)=>{let r=t;try{r=L.readFileSync(t,`utf-8`)}catch{}try{return yt.parse(JSON.parse(r))}catch(t){let r=[];try{r=JSON.parse(t.message)}catch{}e.error(`Invalid parameters for action ${a(n)}.`),i(r,!1),r.length===0&&e.log(t.message),process.exit(1)}};async#f({connector:t,actionId:n,account:r,pathParams:i={},queryParams:o={},body:s={},headers:c={}}){try{let l=await Ae({mode:`action_id`,actionId:n,account:r,connector:t,pathParams:i,queryParams:o,body:s,headers:c,getHttpClient:async()=>new Pe});if(l.response?.successful){let e={...this.#p(o,l.steps),...X(l.outputs)?l.outputs:{data:l.outputs}};return{statusCode:l.response?.statusCode,output:e}}else{let r=l.response?.message??`An error occurred while processing the request`;e.error(`Action ID ${a(n)} from connector ${a(t.key)}@${a(t.version)} failed with status ${l.response?.statusCode}: ${r}`);let i={...this.#p(o,l.steps)};Object.keys(i).length>0&&(e.log(`${y.yellow.inverse(` EXECUTION DETAILS `)}`),f(i)),process.exit(1)}}catch(e){this.#m(e)}}#p(e,t){return e?.debug===`true`?{debug:{steps:t}}:{}}#m(t){let n=t;switch(Y(n.errorType)&&(e.error(`An unknown error occurred`),e.log(`${t instanceof Error?t.message:String(t)}`),process.exit(1)),n.errorType){case`MISSING_ACTION_ERROR`:e.error(`The specified action was not found: ${n.message}`);break;case`INVALID_ACTION_INPUTS_ERROR`:let t=n;e.error(`Invalid action inputs`),i(t.validationErrors,!1);break;case`INVALID_CURSOR_ERROR`:e.error(`Invalid cursor: ${n.message}`);break;default:e.error(`An error occurred: ${n.message}`)}process.exit(1)}};const St=G(V);var Ct=class{constructor(){this.packageName=`@stackone/cli`,this.spinner=K(),this.currentVersion=Ve()}async execute(t={}){this.spinner.text=`Checking for updates...`,this.spinner.start();try{let n=await this.getLatestVersion();this.spinner.stop(),n||(e.error(`Failed to check for updates`),process.exit(1)),this.isNewerVersion(n,this.currentVersion)?(e.box(`New version available: ${y.yellow(this.currentVersion)} → ${y.green(n)}`),await this.performUpdate(n)):t.force?(e.warn(`No updates available, but forcing reinstall...`),await this.performUpdate(n)):e.success(`You are already on the latest version (${this.currentVersion})`),process.exit(0)}catch(t){this.spinner.stop(),e.error(`Error while trying to update StackOne CLI: ${t?.message??`Unknown error`}`),process.exit(1)}}async getLatestVersion(){try{let{stdout:e}=await St(`npm view ${this.packageName} version`,{encoding:`utf-8`});return e.trim()}catch{return null}}isNewerVersion(e,t){return Fe.gt(e,t)}isUsingVolta(){if(typeof process.env.VOLTA_HOME!=`string`||process.env.VOLTA_HOME.length===0)return!1;let e=A(process.env.VOLTA_HOME,`bin`),t=A(e,`stackone`),n=A(e,`stackone.exe`);return E(t)||E(n)}async performUpdate(t){let n=this.isUsingVolta();this.spinner.text=`Updating to latest version (${a(t)})...`,this.spinner.start();try{await St(n?`volta install ${this.packageName}@latest`:`npm install -g ${this.packageName}@latest`,{encoding:`utf-8`}),this.spinner.stop(),e.success(`StackOne CLI updated successfully to latest version (${a(t)})`)}catch{this.spinner.stop();let e=n?`volta install ${this.packageName}@latest`:`npm install -g ${this.packageName}@latest`;throw Error(`Failed to install update. Please try manually: ${e}`)}}};const wt=()=>{e.log(`${y.gray.inverse(` CONNECTORS VALIDATION `)} ${y.yellow.inverse(` WATCH MODE `)}\n`)};var Tt=class{async execute(t){let{watchMode:n,fileOrDir:i}=t,a=K(`Watching for file changes... ${y.gray(`(press "q" to quit)`)}`);if(!i)return;let o=ge(i);try{await Le(o)}catch{e.error(`The specified path does not exist: ${o}\n`),process.exit(1)}if(n){r();let t={},{watch:n}=await import(`chokidar`),i=(await import(`readline`)).createInterface({input:process.stdin,output:process.stdout});process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding(`utf8`);let s=()=>{l.close(),a.stop(),i.close(),e.log(y.grey(`
|
|
116
|
+
Exiting watch mode...`)),process.exit(0)};wt(),e.start(`Validating connectors...`);let c=await kt(o);t=Et(t,c||{}),Dt(t,o),a.start();let l=n(o,{persistent:!0,ignoreInitial:!0}),u=async n=>{if(!n.endsWith(`.s1.yaml`)&&!n.endsWith(`s1.partial.yaml`))return;let i=n.endsWith(`s1.partial.yaml`)?await jt(n):[n];if(!(!i||i.length===0)){r(),a.stop(),wt(),e.log(y.gray(`File change detected: ${n}`)),e.start(`Validating connectors...`);for(let e of i){let n=await kt(e);t=Et(t,n||{})}Dt(t,o),a.start()}};l.on(`change`,async e=>await u(e)),process.stdin.on(`data`,e=>{e.toString()===`q`&&s()}),process.on(`SIGINT`,()=>{s()})}else await kt(o,e),process.exit(0)}};const Et=(e,t)=>{for(let[n,r]of Object.entries(t))e[n]=r;return e},Dt=(t,n)=>{r(),wt();let o=0,s=0;for(let[n,r]of Object.entries(t))r===null?o++:(e?.error(`Connector ${a(n)} is not valid`),i(r,!0),s++);e.log(``),e.log(y.blue.inverse(` Validation Summary `)),e.log(`Connectors path: ${a(n)}`),e.log(`${o===0?y.red(`0`):y.green(o)} valid, ${s===0?y.green(`0`):y.red(s)} invalid connectors\n`)},Ot=async e=>{let t=[],n=await Ie(e);for(let r of n){let n=B(e,r),i=await Le(n);i.isDirectory()?t.push(...await Ot(n)):i.isFile()&&r.endsWith(`.s1.yaml`)&&t.push(n)}return t},kt=async(e,t)=>{let n=await Le(e),r={};if(n.isDirectory()){let n=await Ot(e);if(n.length===0)return t?.error(`No StackOne connector found in ${o(e)}`),t?.log(`Connector files need to have the extension ${a(`*.s1.yaml`)}`),null;let i=0,s=0;for(let e of n){let n=await At(e,t);n===null?i++:(t?.log(``),s++),r[e]=n}return t?.log(``),t?.log(y.blue.inverse(` Validation Summary `)),t?.log(`${i===0?y.red(`0`):y.green(i)} valid, ${s===0?y.green(`0`):y.red(s)} invalid connectors`),r}else if(n.isFile()&&e.endsWith(`s1.yaml`))return r[e]=await At(e,t),r;else if(n.isFile()&&e.endsWith(`partial.yaml`)){t?.error(`Partial connector files cannot be validated directly`),t?.log(`The file ${o(e)} is a partial connector file.`);let n=await jt(e);return n&&n?.length>0&&t?.log(`Did you mean ${a(n[0])}?`),null}else return t?.error(`No StackOne connector found in ${o(e)}`),t?.log(`Connector files need to have the extension ${a(`*.s1.yaml`)}`),null},At=async(e,t)=>{let n=je(ke(e)),r=n?.errors??[];if(n.success){let n=e.split(`/`).pop()||e;return t?.success(`Connector ${a(n)} is valid!`),null}else if(r.length>0)return t?.error(`Connector ${a(e)} is not valid`),t&&i(r,!0),r;else return t?.error(`Connector ${a(e)} is not valid. Please check the file for errors`),[]},jt=async e=>{let t=he(e);try{return(await Ie(t)).filter(e=>e.endsWith(`.s1.yaml`))?.map(e=>B(t,e))}catch{}};function Mt(){let e=process.env.LANGSMITH_API_KEY,t=process.env.LANGSMITH_PROJECT||`stackone-agent-cli`;e&&(ne({apiKey:e,projectName:t,enabled:!0,metadata:{source:`cli`,version:process.env.npm_package_version||`unknown`}}),process.env.VERBOSE&&console.log(`[Telemetry] LangSmith initialized for project:`,t))}const Nt=A(oe(),`.stackone`),Pt=A(Nt,`version-check.json`),Ft=(e=!1)=>{let t=zt(),n=Date.now();if(e||!t||n-t.lastCheckTime>1728e5){let e=It();e&&Lt(e)&&Rt(e),Bt({lastCheckTime:n})}},It=()=>{try{return H(`npm view @stackone/cli version`,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:15e3}).trim()}catch{return null}},Lt=e=>{try{let t=Ve();return Fe.gt(e,t)}catch{return!1}},Rt=t=>{let n=Ve(),r=`Update available: ${y.dim(n)} → ${y.green(t)}`,i=`\n\nRun ${y.cyan(`stackone update`)} to update`;e.box(r,i)},zt=()=>{try{if(!E(Pt))return null;let e=O(Pt,`utf-8`);return JSON.parse(e)}catch{return null}},Bt=e=>{try{E(Nt)||D(Nt,{recursive:!0}),ie(Pt,JSON.stringify(e,null,2),`utf-8`)}catch{}};var Vt=class{constructor(e=new x,t=Ve()){this.program=e,this.version=t,Mt(),this.setupProgram(),this.registerCommands()}setupProgram(){this.program.name(`stackone`).description(`StackOne CLI`).version(this.version,`-v, --version`)}registerCommands(){let t=new lt,n=new mt,r=new ft,i=new at,a=new st,o=new Tt,s=new Xe,c=new Ze,l=new Ke,u=new Ue,d=new xt,f=new Ct;this.program.configureOutput({writeOut:e=>process.stdout.write(e),writeErr:e=>process.stderr.write(e),outputError:(e,t)=>{t(y.red(e))}}),this.program.command(`init`).option(`-e, --env <environment>`,`Specify the environment for the configuration profile`).description(`Initialize & create a StackOne CLI configuration profile`).action(e=>{t.execute({environment:e.env})}),this.program.command(`push`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new b(`<path>`,`Connector file or directory to push`)).description(`Push a connector to the StackOne registry`).action((e,t)=>{n.execute({profile:t.profile,fileOrDir:e,apiUrl:t.apiUrl,apiKey:t.apiKey})}),this.program.command(`drop`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new b(`<connector>`,`Connector identifier in format provider_key@version`)).description(`Drop a connector from the StackOne registry`).action((e,t)=>{i.execute({profile:t.profile,connector:e,apiUrl:t.apiUrl,apiKey:t.apiKey})}),this.program.command(`get`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-c, --connector <connector>`,`Connector identifier in format provider_key@version or provider_key (defaults to latest)`).option(`--account-id <account-id>`,`Account ID to fetch connector from`).option(`-f, --format <format>`,`Output format: yaml or json (default: yaml)`,`yaml`).option(`-o, --output-file <output-file>`,`File to write the output to`).description(`Get a connector from the StackOne registry`).action(e=>{a.execute({profile:e.profile,connector:e.connector,accountId:e.accountId,format:e.format,outputFile:e.outputFile,apiUrl:e.apiUrl,apiKey:e.apiKey})}),this.program.command(`pull`).option(`-c, --connector <connector>`,`Connector identifier in format provider_key@version or provider_key`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-o, --output <path>`,`Output directory for the connectors files (default: ./connectors)`).description(`Pull a connector configuration from StackOne registry to local filesystem`).action(e=>{r.execute({profile:e.profile,connector:e.connector,outputPath:e.output,apiUrl:e.apiUrl,apiKey:e.apiKey})}),this.program.command(`validate`).option(`-w, --watch`,`Run in watch mode`).addArgument(new b(`<path>`,`Connector file or directory with connectors to validate`)).description(`Validate a StackOne connector`).action((e,t)=>{o.execute({watchMode:t.watch,fileOrDir:e})}),this.program.command(`run`).option(`--connector <connector>`,`Connector file, inline YAML, or identifier (provider_key@version or provider_key for latest)`).option(`--action <action>`,`Action to execute on the connector (path to file or inline string action code)`).option(`--action-id <action-id>`,`Action ID to execute on the connector`).option(`--account <account>`,`Account details to use for running the connector (path to file or inline string account data)`).option(`--account-id <account-id>`,`Account ID to use for running the connector against (fetches connector from API if --connector not provided)`).option(`--params <params>`,`Action parameters (path to file or inline string with JSON parameters)`).option(`--credentials <credentials>`,`Credentials to use (path to file or inline string with JSON credentials)`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-o, --output-file <output-file>`,`File to write the output to`).option(`-d, --debug`,`Enables debug mode to include more details in the action execution output`).description(`Run a connector action`).action(e=>{d.execute({connector:e.connector,action:e.action,actionId:e.actionId,account:e.account,accountId:e.accountId,params:e.params,credentials:e.credentials,profile:e.profile,outputFile:e.outputFile,debug:e.debug,apiUrl:e.apiUrl,apiKey:e.apiKey})});let p=this.program.command(`agent`).description(`StackOne agent commands`);p.command(`setup`).option(`-g, --global`,`Setup global configuration`).option(`-l, --local`,`Setup local project configuration`).description(`Setup StackOne agent (global or local)`).action(e=>{e.global?s.execute():c.execute()}),p.command(`cleanup`).description(`Remove all API keys and credentials from configurations`).action(()=>{l.execute()}),p.command(`chat`).option(`-m, --mode <mode>`,`Mode: build, test, or research`,`build`).option(`-c, --connector <name>`,`Connector name`).option(`-a, --action <name>`,`Action name`).option(`-g, --goal <goal>`,`Initial goal/message`).option(`-t, --temperature <number>`,`Temperature (0-1, default: 0.5)`,parseFloat).option(`-v, --verbose`,`Enable verbose logging`).description(`Start an interactive chat session with the agent (use /commands in chat)`).action(async t=>{let n=[`build`,`test`,`research`];t.mode&&!n.includes(t.mode)&&(e.error(`❌ Error: Invalid mode "${t.mode}". Must be one of: ${n.join(`, `)}`),process.exit(1)),t.temperature!==void 0&&(isNaN(t.temperature)&&(e.error(`❌ Error: Temperature must be a valid number`),process.exit(1)),(t.temperature<0||t.temperature>1)&&(e.error(`❌ Error: Temperature must be between 0 and 1`),process.exit(1))),u.execute({mode:t.mode,connector:t.connector,action:t.action,goal:t.goal,temperature:t.temperature,verbose:t.verbose})}),this.program.command(`update`).option(`-f, --force`,`Force reinstall even if already on latest version`).description(`Update the CLI to the latest version`).action(e=>{f.execute({force:e.force})}),this.program.command(`version`).description(`Show version information`).action(async()=>{e.log(`${y.inverse.greenBright(`StackOne`)} ${y.grey(`CLI`)} ${y.whiteBright(this.version)}`),Ft(!0),process.exit(0)})}run(){process.argv.includes(`version`)||Ft(),this.program.parse(process.argv)}};export{Vt as t};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
require(`./agentConfig-CgKwpn5X.cjs`);const e=require(`./cliCore-
|
|
1
|
+
require(`./agentConfig-CgKwpn5X.cjs`);const e=require(`./cliCore-BsHXu26d.cjs`);require(`./setupMigration-DAlx4sxl.cjs`),exports.CLI=e.t;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./agentConfig-BljaB-6S.mjs";import{t as e}from"./cliCore-
|
|
1
|
+
import"./agentConfig-BljaB-6S.mjs";import{t as e}from"./cliCore-CTkOiHS_.mjs";import"./setupMigration-DdeVl8db.mjs";export{e as CLI};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackone/cli",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.2",
|
|
4
4
|
"description": "StackOne Connect CLI tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"@clack/prompts": "0.11.0",
|
|
48
48
|
"@stackone/agent-config": "1.4.0",
|
|
49
49
|
"@stackone/agent-harness": "0.4.3",
|
|
50
|
-
"@stackone/connect-sdk": "2.
|
|
51
|
-
"@stackone/core": "2.
|
|
50
|
+
"@stackone/connect-sdk": "2.22.0",
|
|
51
|
+
"@stackone/core": "2.14.0",
|
|
52
52
|
"@stackone/transport": "2.7.1",
|
|
53
53
|
"@stackone/utils": "0.16.1",
|
|
54
54
|
"chalk": "5.6.2",
|