@ciandt-flow/flow-ai-obs 0.2.0 → 0.3.0-beta.32

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.js CHANGED
@@ -1,100 +1,140 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';var c=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var d=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var fe=d((sa,Qn)=>{Qn.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.2.0",description:"Claude Code hooks for Langfuse OTLP tracing \u2014 cross-platform",main:"dist/index.js",bin:{"flow-ai-obs":"dist/cli.js","flow-ai-obs-setup":"dist/setup.js"},scripts:{build:"tsup",test:"node --test src/**/*.test.js",typecheck:"node --check src/**/*.js bin/cli.js",lint:"node --check src/**/*.js bin/cli.js","security-scan":"trufflehog filesystem src/ --fail --no-update --exclude-paths .trufflehogignore",postinstall:"node dist/setup.js",prepublishOnly:"npm run security-scan && npm run build","release:npm":"changeset publish",changeset:"changeset","version-packages":"changeset version","install:hooks":"node bin/cli.js install","auth:login":"node bin/cli.js auth login","auth:logout":"node bin/cli.js auth logout","auth:status":"node bin/cli.js auth status",smoke:"bash scripts/smoke-test.sh","smoke:debug":"bash scripts/smoke-test.sh --debug","smoke:send":"bash scripts/smoke-test.sh --send --allow-http --debug"},files:["dist/","README.md","LICENSE.md"],keywords:["claude-code","langfuse","observability","otlp","hooks","flow","ciandt"],author:"CI&T Flow Team",license:"SEE LICENSE IN LICENSE.md",private:false,dependencies:{keytar:"7.9.0"},devDependencies:{"@changesets/changelog-github":"^0.6.0","@changesets/cli":"^2.30.0",tsup:"^8.5.1",typescript:"^6.0.3"},engines:{node:">=18.0.0"},publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/CI-T-HyperX/flow-codeassistant-observability.git"}};});var W=d((ra,ot)=>{var es=!process.env.NO_COLOR&&process.stdout.isTTY;function R(e,t){return es?n=>`\x1B[${e}m${n}\x1B[${t}m`:n=>n}var ts=R("32","39"),ns=R("31","39"),ss=R("33","39"),rs=R("36","39"),os=R("1","22"),is=R("2","22");ot.exports={green:ts,red:ns,yellow:ss,cyan:rs,bold:os,dim:is};});var ke=d((oa,lt)=>{var as=c("https"),ct=c("fs"),cs=c("os"),us=c("path"),{spawn:ls}=c("child_process"),Ae;function P(){return Ae||(Ae=fe()),Ae}var ut=us.join(cs.tmpdir(),"flow-obs-update-cache.json"),ds=1440*60*1e3,ps=3e3;function Ie(e,t){let n=r=>{let i=String(r).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return i?[+i[1],+i[2],+i[3]]:null},s=n(e),o=n(t);return !s||!o?false:o[0]!==s[0]?o[0]>s[0]:o[1]!==s[1]?o[1]>s[1]:o[2]>s[2]}function fs(){try{let e=JSON.parse(ct.readFileSync(ut,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=ds?null:e}catch{return null}}function hs(e,t){try{ct.writeFileSync(ut,JSON.stringify({latestVersion:e,updatePriority:t||null,checkedAt:Date.now()}),{mode:384});}catch{}}function Ss(e){let t=P().name,n=as.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:ps},s=>{if(s.statusCode!==200)return s.resume(),e(new Error(`HTTP ${s.statusCode}`));let o="";s.setEncoding("utf8"),s.on("data",r=>{o+=r;}),s.on("end",()=>{try{let r=JSON.parse(o);if(typeof r.version!="string")throw new Error("no version field");e(null,{version:r.version,updatePriority:typeof r.updatePriority=="string"?r.updatePriority:null});}catch(r){e(r);}});});n.on("error",e),n.on("timeout",()=>{n.destroy(new Error("timeout"));});}function it(e){let t=P().name,s=` Update available: ${P().version} \u2192 ${e}`,o=` Run: npm install -g ${t}`,r=Math.max(s.length,o.length)+2,i="\u2500".repeat(r);process.stderr.write(`
2
+ 'use strict';var c=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var p=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Ee=p((xa,Ss)=>{Ss.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.3.0-beta.32",description:"Claude Code hooks for Langfuse OTLP tracing \u2014 cross-platform",main:"dist/index.js",bin:{"flow-ai-obs":"dist/cli.js","flow-ai-obs-setup":"dist/setup.js"},scripts:{build:"tsup",test:"node --test src/**/*.test.js",typecheck:"node --check src/**/*.js bin/cli.js",lint:"node --check src/**/*.js bin/cli.js","security-scan":"trufflehog filesystem src/ --fail --no-update --exclude-paths .trufflehogignore",postinstall:`node -e "require('fs').existsSync('dist/setup.js') && require('child_process').execFileSync(process.execPath, ['dist/setup.js'], {stdio:'inherit'})"`,prepublishOnly:"npm run security-scan && npm run build","release:npm":"changeset publish",changeset:"changeset","version-packages":"changeset version","install:hooks":"node bin/cli.js install","auth:login":"node bin/cli.js auth login","auth:logout":"node bin/cli.js auth logout","auth:status":"node bin/cli.js auth status",smoke:"bash scripts/smoke-test.sh","smoke:debug":"bash scripts/smoke-test.sh --debug","smoke:send":"bash scripts/smoke-test.sh --send --allow-http --debug"},files:["dist/","README.md","LICENSE.md"],keywords:["claude-code","langfuse","observability","otlp","hooks","flow","ciandt"],author:"CI&T Flow Team",license:"SEE LICENSE IN LICENSE.md",private:false,dependencies:{keytar:"7.9.0"},devDependencies:{"@changesets/changelog-github":"^0.6.0","@changesets/cli":"^2.30.0",tsup:"^8.5.1",typescript:"^6.0.3"},engines:{node:">=18.0.0"},publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/CI-T-HyperX/flow-codeassistant-observability.git"}};});var F=p((Ma,pt)=>{var Ts=!process.env.NO_COLOR&&process.stdout.isTTY;function q(e,t){return Ts?n=>`\x1B[${e}m${n}\x1B[${t}m`:n=>n}var Es=q("32","39"),ws=q("31","39"),gs=q("33","39"),_s=q("36","39"),ms=q("1","22"),ys=q("2","22");pt.exports={green:Es,red:ws,yellow:gs,cyan:_s,bold:ms,dim:ys};});var we=p((Ba,Et)=>{var Os=c("https"),St=c("fs"),As=c("os"),Ls=c("path"),{spawn:Ns}=c("child_process"),ve;function x(){return ve||(ve=Ee()),ve}var Tt=Ls.join(As.tmpdir(),"flow-obs-update-cache.json"),Is=1440*60*1e3,ks=3e3;function be(e,t){let n=o=>{let i=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return i?[+i[1],+i[2],+i[3]]:null},s=n(e),r=n(t);return !s||!r?false:r[0]!==s[0]?r[0]>s[0]:r[1]!==s[1]?r[1]>s[1]:r[2]>s[2]}function Cs(){try{let e=JSON.parse(St.readFileSync(Tt,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=Is?null:e}catch{return null}}function vs(e,t){try{St.writeFileSync(Tt,JSON.stringify({latestVersion:e,updatePriority:t||null,checkedAt:Date.now()}),{mode:384});}catch{}}function bs(e){let t=x().name,n=Os.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:ks},s=>{if(s.statusCode!==200)return s.resume(),e(new Error(`HTTP ${s.statusCode}`));let r="";s.setEncoding("utf8"),s.on("data",o=>{r+=o;}),s.on("end",()=>{try{let o=JSON.parse(r);if(typeof o.version!="string")throw new Error("no version field");e(null,{version:o.version,updatePriority:typeof o.updatePriority=="string"?o.updatePriority:null});}catch(o){e(o);}});});n.on("error",e),n.on("timeout",()=>{n.destroy(new Error("timeout"));});}function ft(e){let t=x().name,s=` Update available: ${x().version} \u2192 ${e}`,r=` Run: npm install -g ${t}`,o=Math.max(s.length,r.length)+2,i="\u2500".repeat(o);process.stderr.write(`
3
3
  \u256D${i}\u256E
4
- \u2502${s.padEnd(r)}\u2502
5
- \u2502${o.padEnd(r)}\u2502
4
+ \u2502${s.padEnd(o)}\u2502
5
+ \u2502${r.padEnd(o)}\u2502
6
6
  \u2570${i}\u256F
7
7
 
8
- `);}function at(e){let t=P().name;process.stderr.write(`
8
+ `);}function ht(e){let t=x().name;process.stderr.write(`
9
9
  [${t}] Critical update detected \u2014 auto-updating to ${e}...
10
10
 
11
- `),ls("npm",["install","-g",`${t}@${e}`],{detached:true,stdio:"ignore",windowsHide:true}).unref();}function Es(){try{let e=fs();if(e){Ie(P().version,e.latestVersion)&&(e.updatePriority==="auto"?at(e.latestVersion):it(e.latestVersion));return}setImmediate(()=>{Ss((t,n)=>{t||!n||(hs(n.version,n.updatePriority),Ie(P().version,n.version)&&(n.updatePriority==="auto"?at(n.version):it(n.version)));});});}catch{}}lt.exports={checkForUpdate:Es,isNewer:Ie};});var w=d((ia,pt)=>{var H=process.env.FLOW_BASE_URL||"https://flow.ciandt.com",dt={AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${H}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${H}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${H}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${H}/otel`},Ts={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},ws="FLOW-nodejs",gs="config.json",_s={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},ms={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:dt.OTEL_ENDPOINT,OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},ys={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP"},Os={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3},Ls={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},As={FILE_PREFIX:"flow-obs-buffer-",MAX_AGE_MS:5760*60*1e3,MAX_FILES:50},Is="flow-ai-obs-debug.log",ks={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60},Ns="flow-obs-";pt.exports={FLOW_BASE_URL:H,FLOW_URLS:dt,VAULT:Ts,CONFIG_DIR_NAME:ws,CONFIG_FILE_NAME:gs,OTLP:_s,NATIVE_OTEL:ms,ENV:ys,INSTALLER:Os,HOOK_TIMEOUTS:Ls,BUFFER:As,DEBUG_LOG_FILENAME:Is,STATE_FILE_PREFIX:Ns,TRACE_LIMITS:ks};});var K=d((aa,ht)=>{var Cs=c("https"),bs=c("http"),{FLOW_URLS:Us}=w(),vs=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function Rs(e){if(!vs.test(e))throw new Error(`Invalid tenant value: "${e}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var ft={INVALID_CLIENT_SECRET:"Invalid Client Secret \u2014 check the value and try again",INVALID_CLIENT_ID:"Invalid Client ID \u2014 check the value and try again",INVALID_TENANT:"Invalid Tenant \u2014 check the value and try again",TENANT_NOT_FOUND:"Tenant not found \u2014 verify the tenant identifier"};function Ps(e,t){try{let n=JSON.parse(t);if(typeof n.error=="string"&&ft[n.error])return new Error(ft[n.error])}catch{}return e===401||e===403||e===500?new Error("Invalid credentials"):e>=400&&e<500?new Error("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function $s(e){return new Promise((t,n)=>{try{Rs(e.tenant);}catch(l){return n(l)}let s=JSON.stringify({clientSecret:e.clientSecret}),o=new URL(Us.AUTH_ENGINE),r=o.protocol==="https:",i={hostname:o.hostname,port:o.port||(r?443:80),path:o.pathname+o.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(s),FlowTenant:e.tenant}},p=(r?Cs:bs).request(i,l=>{let u=[];l.on("data",h=>u.push(h)),l.on("end",()=>{let h=u.join("");if(l.statusCode>=400)return n(Ps(l.statusCode,h));let E;try{E=JSON.parse(h);}catch{return n(new Error("Invalid response from auth engine"))}let m=E.expires_at??new Date(Date.now()+(E.expires_in??3600)*1e3).toISOString();t({accessToken:E.access_token,expiresAt:m});});});p.on("error",l=>n(new Error(`Network error: ${l.message}`))),p.write(s),p.end();})}ht.exports={getToken:$s};});var Ce=d((ca,Tt)=>{var y=c("fs"),Se=c("path"),St=c("os"),{FLOW_URLS:qs,INSTALLER:J,HOOK_TIMEOUTS:he,NATIVE_OTEL:Fs}=w(),{getToken:xs}=K();function Et(){return process.platform==="win32"?Se.join(process.env.APPDATA||Se.join(St.homedir(),"AppData","Roaming"),"Claude","settings.json"):Se.join(St.homedir(),".claude","settings.json")}var Ms=J.LOCK_STALE_MS;function Bs(e){try{let t=y.statSync(e);Date.now()-t.mtimeMs>Ms&&y.unlinkSync(e);}catch{}try{y.writeFileSync(e,String(process.pid),{flag:"wx"});}catch(t){throw t.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+e):t}}function Ds(e){try{y.unlinkSync(e);}catch{}}function Gs(){let e=Et(),t=e+".lock";y.mkdirSync(Se.dirname(e),{recursive:true}),Bs(t);try{y.existsSync(e)&&y.copyFileSync(e,e+".bkp");let n={};try{n=JSON.parse(y.readFileSync(e,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,Fs),n.otelHeadersHelper="flow-ai-obs otel-headers",(!n.hooks||typeof n.hooks!="object")&&(n.hooks={});let s=(o,r)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${o}`,timeout:r}]});n.hooks.UserPromptSubmit=[s("UserPromptSubmit",he.UserPromptSubmit)],n.hooks.PreToolUse=[s("PreToolUse",he.PreToolUse)],n.hooks.PostToolUse=[s("PostToolUse",he.PostToolUse)],n.hooks.Stop=[s("Stop",he.Stop)],y.writeFileSync(e,JSON.stringify(n,null,2)+`
12
- `,"utf8");}finally{Ds(t);}return e}async function js(e){let t;try{t=(await xs(e)).accessToken;}catch{return false}return t?new Promise(n=>{Ne(`Bearer ${t}`,n,1);}):false}function Ne(e,t,n){let s=new URL(qs.GATEWAY_TRACES),o=JSON.stringify({resourceSpans:[],validation_run:true}),r=s.protocol==="https:",i={hostname:s.hostname,port:s.port||(r?443:80),path:s.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:e,"Content-Length":Buffer.byteLength(o)}},p=(r?c("https"):c("http")).request(i,l=>{l.resume(),l.statusCode===200||l.statusCode===204?t(true):n<J.CONNECTIVITY_MAX_RETRY?setTimeout(()=>Ne(e,t,n+1),J.CONNECTIVITY_RETRY_MS):t(false);});p.on("error",()=>{n<J.CONNECTIVITY_MAX_RETRY?setTimeout(()=>Ne(e,t,n+1),J.CONNECTIVITY_RETRY_MS):t(false);}),p.write(o),p.end();}Tt.exports={getClaudeSettingsPath:Et,writeClaudeSettings:Gs,validateConnectivity:js};});var _t=d((ua,gt)=>{var X=c("fs"),$=c("path"),Vs=c("os"),{CONFIG_DIR_NAME:be,CONFIG_FILE_NAME:Ue}=w(),ve={credentials:"credentials","token-cache":"tokenCache"};function z(){let e=Vs.homedir();if(process.platform==="darwin")return $.join(e,"Library","Preferences",be,Ue);if(process.platform==="win32"){let n=process.env.APPDATA||$.join(e,"AppData","Roaming");return $.join(n,be,Ue)}let t=process.env.XDG_CONFIG_HOME||$.join(e,".config");return $.join(t,be,Ue)}function Re(){try{let e=X.readFileSync(z(),"utf8");return JSON.parse(e)}catch{return {}}}function wt(e){let t=z();X.mkdirSync($.dirname(t),{recursive:true}),X.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var Pe=class{static isAvailable(){return true}static hasExistingData(){try{if(!X.existsSync(z()))return !1;let t=JSON.parse(X.readFileSync(z(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,n){let s=Re(),o=ve[n]||n,r=s[o];return r?typeof r=="string"?r:JSON.stringify(r):null}async setSecret(t,n,s){let o=Re(),r=ve[n]||n;if(n==="token-cache")try{o[r]=JSON.parse(s);}catch{o[r]=s;}else o[r]=s;wt(o);}async deleteSecret(t,n){let s=Re(),o=ve[n]||n;return o in s?(delete s[o],wt(s),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${z()}`}};function Ys(){}gt.exports={ScryptFallbackProvider:Pe,_resetWarningState:Ys};});var yt=d((la,mt)=>{var{VAULT:Z}=w();async function Ws(e,t){let n=[Z.ACCOUNT_CREDS,Z.ACCOUNT_TOKEN];for(let s of n)try{if(await t.getSecret(Z.SERVICE,s)!==null)continue;let r=await e.getSecret(Z.SERVICE,s);r!==null&&await t.setSecret(Z.SERVICE,s,r);}catch{}}mt.exports={migrateFromJsonFallback:Ws};});var At=d((da,Lt)=>{var{execFile:Hs,exec:Ks}=c("child_process"),{promisify:Ot}=c("util"),$e=Ot(Hs),Js=Ot(Ks),qe=class{static async isAvailable(){try{return await Js("command -v security"),!0}catch{return false}}async getSecret(t,n){try{let{stdout:s}=await $e("security",["find-generic-password","-w","-a",n,"-s",t]);return s.trim()||null}catch{return null}}async setSecret(t,n,s){await $e("security",["add-generic-password","-U","-a",n,"-s",t,"-w",s]);}async deleteSecret(t,n){try{return await $e("security",["delete-generic-password","-a",n,"-s",t]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};Lt.exports={MacOsKeyVaultProvider:qe};});var Ct=d((pa,Nt)=>{var{execFile:zs,exec:Xs,spawn:Zs}=c("child_process"),{promisify:kt}=c("util"),It=kt(zs),Qs=kt(Xs),Fe=class{static async isAvailable(){try{return await Qs("command -v secret-tool"),!0}catch{return false}}async getSecret(t,n){try{let{stdout:s}=await It("secret-tool",["lookup","service",t,"account",n]);return s.trim()||null}catch{return null}}async setSecret(t,n,s){await new Promise((o,r)=>{let i=Zs("secret-tool",["store","--label",t,"service",t,"account",n]);i.on("error",r),i.on("close",a=>{a===0?o():r(new Error(`secret-tool exited with code ${a}`));}),i.stdin.write(s),i.stdin.end();});}async deleteSecret(t,n){try{return await It("secret-tool",["clear","service",t,"account",n]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};Nt.exports={LinuxKeyVaultProvider:Fe};});var Ut=d((fa,bt)=>{var xe=class{static async isAvailable(){try{return await c("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(t,n){return c("keytar").getPassword(t,n)}async setSecret(t,n,s){await c("keytar").setPassword(t,n,s);}async deleteSecret(t,n){return c("keytar").deletePassword(t,n)}getStoragePath(){return "Windows Credential Manager"}};bt.exports={WindowsKeyVaultProvider:xe};});var $t=d((ha,Pt)=>{async function Rt(){let{ScryptFallbackProvider:e}=_t();if(e.hasExistingData()){let t=await vt();if(t){let{migrateFromJsonFallback:n}=yt(),{VAULT:s}=w();if(await n(new e,t),await t.getSecret(s.SERVICE,s.ACCOUNT_CREDS)!==null)return t}return new e}return await vt()??new e}async function vt(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=At();return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=Ct();return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=Ut();return await e.isAvailable()?new e:null}default:return null}}var er=Rt;Pt.exports={createSecretVaultProvider:Rt,createKeyVaultProvider:er};});var x=d((Sa,Ft)=>{var{createSecretVaultProvider:tr}=$t(),{VAULT:Be}=w(),q=Be.SERVICE,De=Be.ACCOUNT_CREDS,Ge=Be.ACCOUNT_TOKEN,Me=null;function F(){return Me||(Me=tr()),Me}async function qt(){let t=await(await F()).getSecret(q,De);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function nr(e){if(!e.clientId||!e.clientSecret||!e.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await F()).setSecret(q,De,JSON.stringify(e));}async function sr(){let e=await F();await e.deleteSecret(q,De),await e.deleteSecret(q,Ge);}async function rr(e){await(await F()).setSecret(q,Ge,JSON.stringify({accessToken:e.accessToken,expiresAt:e.expiresAt}));}async function je(){let t=await(await F()).getSecret(q,Ge);if(!t)return null;try{let n=JSON.parse(t);return {accessToken:n.accessToken,expiresAt:n.expiresAt}}catch{return null}}async function or(){let e=await je();return e?new Date(e.expiresAt)>new Date:false}async function ir(){let e=await je();if(!e||!e.accessToken)return null;try{let t=e.accessToken.split(".");if(t.length<2)return null;let n=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}async function ar(){let e=await F();if(typeof e.getStoragePath=="function")return e.getStoragePath();let t=process.platform;return t==="darwin"?"macOS Keychain":t==="win32"?"Windows Credential Manager":"Linux Secret Service (libsecret)"}async function cr(){let e=await qt();return !!(e&&e.clientId&&e.clientSecret&&e.tenant)}Ft.exports={getFlowCredentials:qt,saveFlowCredentials:nr,clearFlowCredentials:sr,saveTokenCache:rr,getTokenCache:je,isTokenValid:or,getEmailFromToken:ir,getConfigPath:ar,hasCredentials:cr};});var Bt=d((Ea,Mt)=>{var{writeClaudeSettings:ur}=Ce(),{hasCredentials:lr}=x(),{NATIVE_OTEL:dr}=w(),{green:pr,yellow:fr,bold:xt,dim:O,cyan:hr}=W();async function Sr(){let e=await lr(),t;try{t=ur();}catch(n){return process.stderr.write(` \u2717 Failed to write settings: ${n.message}
11
+ `),Ns("npm",["install","-g",`${t}@${e}`],{detached:true,stdio:"ignore",windowsHide:true}).unref();}function Us(){try{let e=Cs();if(e){be(x().version,e.latestVersion)&&(e.updatePriority==="auto"?ht(e.latestVersion):ft(e.latestVersion));return}setImmediate(()=>{bs((t,n)=>{t||!n||(vs(n.version,n.updatePriority),be(x().version,n.version)&&(n.updatePriority==="auto"?ht(n.version):ft(n.version)));});});}catch{}}Et.exports={checkForUpdate:Us,isNewer:be};});var w=p((Da,gt)=>{var M=process.env.FLOW_BASE_URL||"https://flow.ciandt.com",wt={AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${M}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${M}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${M}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${M}/otel`},Rs={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},Ps="FLOW-nodejs",$s="config.json",qs={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},Fs={ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL||`${M}/flow-llm-proxy/`,ANTHROPIC_MODEL:process.env.FLOW_LLM_PROXY_MODEL||"anthropic.claude-4-6-sonnet",ANTHROPIC_SMALL_FAST_MODEL:process.env.FLOW_LLM_PROXY_SMALL_MODEL||"anthropic.claude-4-6-sonnet",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"},xs={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:wt.OTEL_ENDPOINT,OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},Ms={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP"},Bs={KEYCHAIN_ENABLED:false},Ds={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3},Hs={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},js={FILE_PREFIX:"flow-obs-buffer-",MAX_AGE_MS:5760*60*1e3,MAX_FILES:50},Gs="flow-ai-obs-debug.log",Ys={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60},Ks="flow-obs-";gt.exports={FLOW_BASE_URL:M,FLOW_URLS:wt,VAULT:Rs,CONFIG_DIR_NAME:Ps,CONFIG_FILE_NAME:$s,OTLP:qs,LLM_PROXY:Fs,NATIVE_OTEL:xs,ENV:Ms,FEATURES:Bs,INSTALLER:Ds,HOOK_TIMEOUTS:Hs,BUFFER:js,DEBUG_LOG_FILENAME:Gs,STATE_FILE_PREFIX:Ks,TRACE_LIMITS:Ys};});var X=p((Ha,mt)=>{var Vs=c("https"),Ws=c("http"),{FLOW_URLS:Js}=w(),Xs=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function zs(e){if(!Xs.test(e))throw new Error(`Invalid tenant value: "${e}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var _t={INVALID_CLIENT_SECRET:"Invalid Client Secret \u2014 check the value and try again",INVALID_CLIENT_ID:"Invalid Client ID \u2014 check the value and try again",INVALID_TENANT:"Invalid Tenant \u2014 check the value and try again",TENANT_NOT_FOUND:"Tenant not found \u2014 verify the tenant identifier"};function Zs(e,t){try{let n=JSON.parse(t);if(typeof n.error=="string"&&_t[n.error])return new Error(_t[n.error])}catch{}return e===401||e===403||e===500?new Error("Invalid credentials"):e>=400&&e<500?new Error("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function Qs(e){return new Promise((t,n)=>{try{zs(e.tenant);}catch(d){return n(d)}let s=JSON.stringify({clientSecret:e.clientSecret}),r=new URL(Js.AUTH_ENGINE),o=r.protocol==="https:",i={hostname:r.hostname,port:r.port||(o?443:80),path:r.pathname+r.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(s),FlowTenant:e.tenant}},u=(o?Vs:Ws).request(i,d=>{let l=[];d.on("data",h=>l.push(h)),d.on("end",()=>{let h=l.join("");if(d.statusCode>=400)return n(Zs(d.statusCode,h));let T;try{T=JSON.parse(h);}catch{return n(new Error("Invalid response from auth engine"))}let O=T.expires_at??new Date(Date.now()+(T.expires_in??3600)*1e3).toISOString();t({accessToken:T.access_token,expiresAt:O});});});u.on("error",d=>n(new Error(`Network error: ${d.message}`))),u.write(s),u.end();})}mt.exports={getToken:Qs};});var Q=p((ja,Lt)=>{var g=c("fs"),Z=c("path"),yt=c("os"),{FLOW_URLS:er,INSTALLER:z,HOOK_TIMEOUTS:ge,NATIVE_OTEL:tr,LLM_PROXY:nr}=w(),{getToken:sr}=X();function Re(){return process.platform==="win32"?Z.join(process.env.APPDATA||Z.join(yt.homedir(),"AppData","Roaming"),"Claude","settings.json"):Z.join(yt.homedir(),".claude","settings.json")}var rr=z.LOCK_STALE_MS;function Ot(e){try{let t=g.statSync(e);Date.now()-t.mtimeMs>rr&&g.unlinkSync(e);}catch{}try{g.writeFileSync(e,String(process.pid),{flag:"wx"});}catch(t){throw t.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+e):t}}function At(e){try{g.unlinkSync(e);}catch{}}function or(){let e=Re(),t=e+".lock";g.mkdirSync(Z.dirname(e),{recursive:true}),Ot(t);try{if(g.existsSync(e)){g.copyFileSync(e,e+".bkp");try{g.chmodSync(e+".bkp",384);}catch{}}let n={};try{n=JSON.parse(g.readFileSync(e,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,tr),Object.assign(n.env,nr),n.otelHeadersHelper="flow-ai-obs otel-headers",(!n.hooks||typeof n.hooks!="object")&&(n.hooks={});let s=(r,o)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${r}`,timeout:o}]});n.hooks.UserPromptSubmit=[s("UserPromptSubmit",ge.UserPromptSubmit)],n.hooks.PreToolUse=[s("PreToolUse",ge.PreToolUse)],n.hooks.PostToolUse=[s("PostToolUse",ge.PostToolUse)],n.hooks.Stop=[s("Stop",ge.Stop)],g.writeFileSync(e,JSON.stringify(n,null,2)+`
12
+ `,{encoding:"utf8",mode:384});try{g.chmodSync(e,384);}catch{}}finally{At(t);}return e}async function ir(e){let t;try{t=(await sr(e)).accessToken;}catch{return false}return t?new Promise(n=>{Ue(`Bearer ${t}`,n,1);}):false}function Ue(e,t,n){let s=new URL(er.GATEWAY_TRACES),r=JSON.stringify({resourceSpans:[],validation_run:true}),o=s.protocol==="https:",i={hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:e,"Content-Length":Buffer.byteLength(r)}},u=(o?c("https"):c("http")).request(i,d=>{d.resume(),d.statusCode===200||d.statusCode===204?t(true):n<z.CONNECTIVITY_MAX_RETRY?setTimeout(()=>Ue(e,t,n+1),z.CONNECTIVITY_RETRY_MS):t(false);});u.on("error",()=>{n<z.CONNECTIVITY_MAX_RETRY?setTimeout(()=>Ue(e,t,n+1),z.CONNECTIVITY_RETRY_MS):t(false);}),u.write(r),u.end();}function ar(e){let t=Re(),n=t+".lock";g.mkdirSync(Z.dirname(t),{recursive:true}),Ot(n);try{let s={};try{s=JSON.parse(g.readFileSync(t,"utf8"));}catch{}(!s.env||typeof s.env!="object")&&(s.env={}),Object.assign(s.env,e),g.writeFileSync(t,JSON.stringify(s,null,2)+`
13
+ `,{encoding:"utf8",mode:384});try{g.chmodSync(t,384);}catch{}}finally{At(n);}}Lt.exports={getClaudeSettingsPath:Re,writeClaudeSettings:or,addEnvToClaudeSettings:ar,validateConnectivity:ir};});var kt=p((Ga,It)=>{var te=c("fs"),B=c("path"),cr=c("os"),{CONFIG_DIR_NAME:Pe,CONFIG_FILE_NAME:$e}=w(),qe={credentials:"credentials","token-cache":"tokenCache"};function ee(){let e=cr.homedir();if(process.platform==="darwin")return B.join(e,"Library","Preferences",Pe,$e);if(process.platform==="win32"){let n=process.env.APPDATA||B.join(e,"AppData","Roaming");return B.join(n,Pe,$e)}let t=process.env.XDG_CONFIG_HOME||B.join(e,".config");return B.join(t,Pe,$e)}function Fe(){try{let e=te.readFileSync(ee(),"utf8");return JSON.parse(e)}catch{return {}}}function Nt(e){let t=ee();te.mkdirSync(B.dirname(t),{recursive:true}),te.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var xe=class{static isAvailable(){return true}static hasExistingData(){try{if(!te.existsSync(ee()))return !1;let t=JSON.parse(te.readFileSync(ee(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,n){let s=Fe(),r=qe[n]||n,o=s[r];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,n,s){let r=Fe(),o=qe[n]||n;if(n==="token-cache")try{r[o]=JSON.parse(s);}catch{r[o]=s;}else r[o]=s;Nt(r);}async deleteSecret(t,n){let s=Fe(),r=qe[n]||n;return r in s?(delete s[r],Nt(s),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${ee()}`}};function ur(){}It.exports={ScryptFallbackProvider:xe,_resetWarningState:ur};});var bt=p((Ya,vt)=>{var{execFile:lr,exec:dr}=c("child_process"),{promisify:Ct}=c("util"),Me=Ct(lr),pr=Ct(dr),Be=class{static async isAvailable(){try{return await pr("command -v security"),!0}catch{return false}}async getSecret(t,n){try{let{stdout:s}=await Me("security",["find-generic-password","-w","-a",n,"-s",t]);return s.trim()||null}catch{return null}}async setSecret(t,n,s){await Me("security",["add-generic-password","-U","-a",n,"-s",t,"-w",s]);}async deleteSecret(t,n){try{return await Me("security",["delete-generic-password","-a",n,"-s",t]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};vt.exports={MacOsKeyVaultProvider:Be};});var $t=p((Ka,Pt)=>{var{execFile:fr,exec:hr,spawn:Sr}=c("child_process"),{promisify:Rt}=c("util"),Ut=Rt(fr),Tr=Rt(hr),De=class{static async isAvailable(){try{return await Tr("command -v secret-tool"),!0}catch{return false}}async getSecret(t,n){try{let{stdout:s}=await Ut("secret-tool",["lookup","service",t,"account",n]);return s.trim()||null}catch{return null}}async setSecret(t,n,s){await new Promise((r,o)=>{let i=Sr("secret-tool",["store","--label",t,"service",t,"account",n]);i.on("error",o),i.on("close",a=>{a===0?r():o(new Error(`secret-tool exited with code ${a}`));}),i.stdin.write(s),i.stdin.end();});}async deleteSecret(t,n){try{return await Ut("secret-tool",["clear","service",t,"account",n]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};Pt.exports={LinuxKeyVaultProvider:De};});var Ft=p((Va,qt)=>{var He=class{static async isAvailable(){try{return await c("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(t,n){return c("keytar").getPassword(t,n)}async setSecret(t,n,s){await c("keytar").setPassword(t,n,s);}async deleteSecret(t,n){return c("keytar").deletePassword(t,n)}getStoragePath(){return "Windows Credential Manager"}};qt.exports={WindowsKeyVaultProvider:He};});var Bt=p((Wa,Mt)=>{async function xt(){let{ScryptFallbackProvider:e}=kt();return await Er()??new e}async function Er(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=bt();return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=$t();return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=Ft();return await e.isAvailable()?new e:null}default:return null}}var wr=xt;Mt.exports={createSecretVaultProvider:xt,createKeyVaultProvider:wr};});var j=p((Ja,Ht)=>{var{createSecretVaultProvider:gr}=Bt(),{VAULT:Ge}=w(),D=Ge.SERVICE,Ye=Ge.ACCOUNT_CREDS,Ke=Ge.ACCOUNT_TOKEN,je=null;function H(){return je||(je=gr()),je}async function Dt(){let t=await(await H()).getSecret(D,Ye);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function _r(e){if(!e.clientId||!e.clientSecret||!e.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await H()).setSecret(D,Ye,JSON.stringify(e));}async function mr(){let e=await H();await e.deleteSecret(D,Ye),await e.deleteSecret(D,Ke);}async function yr(e){await(await H()).setSecret(D,Ke,JSON.stringify({accessToken:e.accessToken,expiresAt:e.expiresAt}));}async function Ve(){let t=await(await H()).getSecret(D,Ke);if(!t)return null;try{let n=JSON.parse(t);return {accessToken:n.accessToken,expiresAt:n.expiresAt}}catch{return null}}async function Or(){let e=await Ve();return e?new Date(e.expiresAt)>new Date:false}async function Ar(){let e=await Ve();if(!e||!e.accessToken)return null;try{let t=e.accessToken.split(".");if(t.length<2)return null;let n=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}async function Lr(){let e=await H();if(typeof e.getStoragePath=="function")return e.getStoragePath();let t=process.platform;return t==="darwin"?"macOS Keychain":t==="win32"?"Windows Credential Manager":"Linux Secret Service (libsecret)"}async function Nr(){let e=await Dt();return !!(e&&e.clientId&&e.clientSecret&&e.tenant)}Ht.exports={getFlowCredentials:Dt,saveFlowCredentials:_r,clearFlowCredentials:mr,saveTokenCache:yr,getTokenCache:Ve,isTokenValid:Or,getEmailFromToken:Ar,getConfigPath:Lr,hasCredentials:Nr};});var C=p((Xa,Gt)=>{var{writeFileSync:Ir}=c("fs"),{tmpdir:kr}=c("os"),{join:Cr}=c("path"),{DEBUG_LOG_FILENAME:vr,ENV:br}=w(),jt=Cr(kr(),vr);function Ur(...e){if(process.env[br.FLOW_OBS_DEBUG]!=="1")return;let t=`[${new Date().toISOString()}] ${e.join(" ")}
14
+ `;try{Ir(jt,t,{flag:"a"});}catch(n){process.stderr.write(`[flow-obs debug ERROR] ${n.message}
15
+ `);}}Gt.exports={dbg:Ur,DEBUG_LOG:jt};});var P=p((za,Kt)=>{var{getFlowCredentials:We,isTokenValid:Rr,getEmailFromToken:ne,getTokenCache:Pr,saveTokenCache:$r}=j(),{getToken:qr}=X(),{FLOW_BASE_URL:Fr,ENV:A,FEATURES:Je}=w(),{dbg:G}=C(),xr=[/^localhost\.?$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/,/^::1$/,/^\[::1\]$/,/^\[::ffff:/i,/^\[f[cd]/i,/^\[fe80:/i,/^metadata\.google\.internal\.?$/i,/^metadata\.azure\.internal\.?$/i,/(?:^|\.)localtest\.me\.?$/i,/(?:^|\.)lvh\.me\.?$/i,/(?:^|\.)vcap\.me\.?$/i];function Mr(e){return xr.some(t=>t.test(e))}function _e(e){if(!e)return null;try{let t=e.split(".");if(t.length<2)return null;let n=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:s,clientSecret:r,tenant:o}=n;return !s||!r||!o?null:{clientId:s,clientSecret:r,tenant:o}}catch{return null}}function Br(e){let t=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),n=Buffer.from(JSON.stringify({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant})).toString("base64url");return `${t}.${n}.`}function Xe(e){let t;try{t=new URL(e);}catch{throw new Error(`Invalid URL: ${e}`)}if(!(process.env[A.FLOW_OBS_ALLOW_HTTP]==="true")&&t.protocol!=="https:")throw new Error(`URL must use HTTPS: ${e}`);if(t.username||t.password)throw new Error(`URL must not contain embedded credentials: ${e}`);if(Mr(t.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${t.hostname}`);return e}async function Dr(){let e=_e(process.env[A.ANTHROPIC_AUTH_TOKEN]);if(e)return {user:await ne().catch(()=>null)||e.clientId,tenant:e.tenant};if(Je.KEYCHAIN_ENABLED)try{let t=await We();if(!t)return {user:"",tenant:""};let n=await ne()||t.clientId||"",s=t.tenant||"";return {user:n,tenant:s}}catch{return {user:"",tenant:""}}return {user:"",tenant:""}}async function Hr(e){if(await Rr())return (await Pr()).accessToken;G("getOrRefreshToken","token expired \u2014 refreshing via auth-engine");let t=await qr(e);return await $r(t),G("getOrRefreshToken",`token refreshed, expires=${t.expiresAt}`),t.accessToken}function jr(e,t){let n=t&&t.accessToken?t.accessToken:"";return {endpoint:e.replace(/\/$/,"")+"/langfuse/traces",authHeader:`Bearer ${n}`}}function Gr(e,t,n){let s=Buffer.from(`${t}:${n}`).toString("base64");return {endpoint:e.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${s}`}}async function Yt(){let e=[],t=process.env[A.ANTHROPIC_MODEL]||"",n=process.env[A.FLOW_TELEMETRY]==="true",s=process.env[A.LANGFUSE_BASE_URL],r=process.env[A.LANGFUSE_PUBLIC_KEY],o=process.env[A.LANGFUSE_SECRET_KEY];if(n&&s&&r&&o){let l="",h="",T=_e(process.env[A.ANTHROPIC_AUTH_TOKEN]);if(T)l=await ne().catch(()=>null)||T.clientId,h=T.tenant;else if(Je.KEYCHAIN_ENABLED)try{let I=await We();I&&(l=await ne()||I.clientId,h=I.tenant);}catch{}let O={user:l||"",tenant:h||"",team:"",project:"",model:t};e.push({mode:"direct",...Gr(Xe(s),r,o),...O}),G("resolveCredentials","direct mode active",`user=${O.user}`,`tenant=${O.tenant}`);}let i=_e(process.env[A.ANTHROPIC_AUTH_TOKEN]);if(G("resolveCredentials",i?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),!i&&Je.KEYCHAIN_ENABLED&&(i=await We(),i&&G("resolveCredentials","credentials resolved from keychain (FEATURES.KEYCHAIN_ENABLED=true)")),!i){if(e.length===0){let l=[];return l.authError=false,l}return e}let a;try{a=await Hr(i);}catch(l){if(G("resolveCredentials",`token refresh failed: ${l.message}`),e.length>0)return e;let h=[];return h.authError=true,h}let u={user:await ne()||i.clientId,tenant:i.tenant,team:"",project:"",model:t},d=process.env[A.FLOW_TELEMETRY_GATEWAY]||Fr;return e.push({mode:"gateway",...jr(Xe(d),{accessToken:a}),...u}),e}async function Yr(){return (await Yt()).length>0}Kt.exports={credentialsAvailable:Yr,getIdentityFromToken:Dr,resolveCredentials:Yt,validateUrl:Xe,parseCredsFromAnthropicToken:_e,buildAnthropicAuthToken:Br};});var ie=p((Za,Qt)=>{var{getFlowCredentials:ze,saveFlowCredentials:Vt,clearFlowCredentials:Kr,saveTokenCache:Vr,isTokenValid:Wr,getConfigPath:Wt,hasCredentials:Jr}=j(),{getToken:Xr}=X(),{buildAnthropicAuthToken:zr,parseCredsFromAnthropicToken:Jt}=P(),{addEnvToClaudeSettings:Zr}=Q(),{ENV:Ze}=w(),{green:ye,red:se,yellow:me,cyan:re,bold:Xt,dim:Y}=F(),Qr=/[\x00-\x08\x0B-\x1F\x7F]|\x1b\[[0-9;]*[a-zA-Z]/g;function v(e){return typeof e=="string"?e.replace(Qr,""):e}function oe(e,t={}){return new Promise((n,s)=>{let{masked:r=false,defaultValue:o=""}=t;process.stdout.write(e+o);let i=o;function a(){try{process.stdin.setRawMode(!1);}catch{}}process.once("uncaughtException",a),process.once("unhandledRejection",a);let u=l=>{if(l===""){d(),s(new Error("SIGINT"));return}if(l==="\r"||l===`
16
+ `){d(),process.stdout.write(`
17
+ `),n(i);return}if(l==="\x7F"){i.length>0&&(i=i.slice(0,-1),process.stdout.write("\b \b"));return}l.startsWith("\x1B")||(i+=l,process.stdout.write(r?"*".repeat(l.length):l));};function d(){process.stdin.setRawMode(false),process.stdin.removeListener("data",u),process.removeListener("uncaughtException",a),process.removeListener("unhandledRejection",a);}process.stdin.setRawMode(true),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",u);})}async function zt(e){try{let t=await ze();(!t||t.clientId!==e.clientId||t.clientSecret!==e.clientSecret||t.tenant!==e.tenant)&&await Vt(e);}catch{}}async function Zt(e){let{accessToken:t,expiresAt:n}=await Xr(e);await Vt(e),await Vr({accessToken:t,expiresAt:n});try{let s=zr(e);Zr({[Ze.ANTHROPIC_AUTH_TOKEN]:s});}catch{}}async function eo(e){try{return await Zt(e),process.stdout.write(ye(` \u2713 Setup complete. Tenant: ${v(e.tenant)}
18
+
19
+ `)),0}catch(t){return process.stderr.write(se(` \u2717 Authentication failed: ${v(t.message)}
20
+ `)),1}}async function to(){try{process.stdout.write(`
21
+ `);let e=(await oe(re(" ? ")+"Client ID: ")).trim(),t=(await oe(re(" ? ")+"Client Secret: ",{masked:!0})).trim(),n=(await oe(re(" ? ")+"Tenant: ")).trim();if(!e||!t||!n)return process.stderr.write(se(` \u2717 All fields are required
22
+ `)),1;try{await Zt({clientId:e,clientSecret:t,tenant:n});}catch(s){return process.stderr.write(se(` \u2717 Authentication failed: ${v(s.message)}
23
+ `)),1}return process.stdout.write(ye(` \u2713 Setup complete. Tenant: ${v(n)}
24
+ `)),process.stdout.write(` Storage: ${await Wt()}
25
+
26
+ `),0}catch(e){if(e.message==="SIGINT")throw e;return process.stderr.write(se(` \u2717 Unexpected error: ${e.message}
27
+ `)),1}}async function no(e={}){if(e.clientId&&e.clientSecret&&e.tenant)return eo({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant});let t=Jt(process.env[Ze.ANTHROPIC_AUTH_TOKEN]);t&&await zt(t);let n=t||await ze();if(n){process.stdout.write(`
28
+ `),process.stdout.write(Xt(` Already authenticated
29
+ `)),process.stdout.write(Y(" Tenant: ")+v(n.tenant)+`
30
+ `),process.stdout.write(Y(" Client ID: ")+v(n.clientId)+`
31
+ `),process.stdout.write(`
32
+ `);let s;try{s=await oe(re(" ? ")+"Re-authenticate? (y/N): ");}catch(r){if(r.message==="SIGINT")return process.stdout.write(`
33
+ `),130;throw r}if(s.trim().toLowerCase()!=="y")return process.stdout.write(ye(` \u2713 Using existing credentials.
34
+
35
+ `)),0}try{return await to()}catch(s){if(s.message==="SIGINT")return process.stdout.write(`
36
+ `),130;throw s}}async function so(){try{return process.stdout.write(`
37
+ `),(await oe(re(" ? ")+"Are you sure? This will remove your local credentials. (y/N): ")).toLowerCase()!=="y"?(process.stdout.write(me(` \u26A0 Logout cancelled
38
+ `)),0):null}catch(e){if(e.message==="SIGINT")return process.stdout.write(`
39
+ `),130;throw e}}async function ro(e=false){if(!await Jr())return process.stdout.write(me(` \u26A0 You are not authenticated
40
+ `)),0;if(!e){let t=await so();if(t!==null)return t}try{return await Kr(),process.stdout.write(ye(` \u2713 Credentials removed successfully
41
+ `)),0}catch{return process.stderr.write(se(` \u2717 Error removing credentials
42
+ `)),1}}async function oo(){let e=Jt(process.env[Ze.ANTHROPIC_AUTH_TOKEN]);e&&await zt(e);let t=e||await ze();if(!t)return process.stdout.write(me(" \u26A0 Not authenticated. Run `flow-ai-obs auth login` to set up.\n")),0;if(!e&&!await Wr())return process.stdout.write(me(" \u26A0 Session expired. Run `flow-ai-obs auth login` to re-authenticate.\n")),0;let n=t.clientSecret.length>4?"****...****"+t.clientSecret.slice(-4):"****",s=e?"ANTHROPIC_AUTH_TOKEN (settings.json)":await Wt();return process.stdout.write(`
43
+ `+Xt(` Authenticated
44
+ `)),process.stdout.write(Y(" Tenant: ")+v(t.tenant)+`
45
+ `),process.stdout.write(Y(" Client ID: ")+v(t.clientId)+`
46
+ `),process.stdout.write(Y(" Client Secret: ")+n+`
47
+ `),process.stdout.write(Y(" Storage: ")+s+`
48
+
49
+ `),0}Qt.exports={runLogin:no,runLogout:ro,runStatus:oo};});var et=p((Qa,sn)=>{var io=c("fs"),Qe=c("path"),en=c("os"),{spawnSync:ao}=c("child_process"),{writeClaudeSettings:co}=Q(),{NATIVE_OTEL:uo,ENV:lo}=w(),{green:po,red:fo,yellow:ho,bold:tn,dim:L,cyan:So}=F(),{runLogin:To}=ie(),nn={darwin:`npm install -g @anthropic-ai/claude-code
50
+ or visit: https://claude.ai/download`,linux:"npm install -g @anthropic-ai/claude-code",win32:`npm install -g @anthropic-ai/claude-code
51
+ or visit: https://claude.ai/download`};function Eo(){let e=process.platform==="win32"?"where":"which";return ao(e,["claude"],{encoding:"utf8",timeout:5e3}).status===0}function wo(){return process.platform==="win32"?Qe.join(process.env.APPDATA||Qe.join(en.homedir(),"AppData","Roaming"),"Claude","settings.json"):Qe.join(en.homedir(),".claude","settings.json")}function go(){try{let e=io.readFileSync(wo(),"utf8"),t=JSON.parse(e);return !!(t.env&&t.env[lo.ANTHROPIC_AUTH_TOKEN])}catch{return false}}async function _o(){if(!Eo()){let t=nn[process.platform]||nn.linux;return process.stderr.write(`
52
+ `+fo(` \u2717 Claude Code is not installed or not found in PATH.
53
+
54
+ `)+` flow-ai-obs requires Claude Code to function.
55
+ Install it with:
56
+
57
+ `+So(` ${t}`)+`
58
+
59
+ `),1}if(!go()){process.stdout.write(ho(` \u26A0 No credentials found in settings.json \u2014 authentication required.
60
+
61
+ `));let t=await To();if(t!==0)return t}let e;try{e=co();}catch(t){return process.stderr.write(` \u2717 Failed to write settings: ${t.message}
13
62
  `),1}process.stdout.write(`
14
- `+xt(" Native OTEL configured")+` (metrics & logs)
15
- `);for(let[n,s]of Object.entries(dr))process.stdout.write(O(` ${n.padEnd(36)}`)+s+`
63
+ `+tn(" Native OTEL configured")+` (metrics & logs)
64
+ `);for(let[t,n]of Object.entries(uo))process.stdout.write(L(` ${t.padEnd(36)}`)+n+`
16
65
  `);return process.stdout.write(`
17
- `),process.stdout.write(xt(" Hooks registered")+` (Langfuse trace capture)
18
- `),process.stdout.write(O(" UserPromptSubmit")+` \u2192 flow-ai-obs UserPromptSubmit (timeout: 5s)
19
- `),process.stdout.write(O(" PreToolUse ")+` \u2192 flow-ai-obs PreToolUse (timeout: 3s)
20
- `),process.stdout.write(O(" PostToolUse ")+` \u2192 flow-ai-obs PostToolUse (timeout: 10s)
21
- `),process.stdout.write(O(" Stop ")+` \u2192 flow-ai-obs Stop (timeout: 15s)
66
+ `),process.stdout.write(tn(" Hooks registered")+` (Langfuse trace capture)
67
+ `),process.stdout.write(L(" UserPromptSubmit")+` \u2192 flow-ai-obs UserPromptSubmit (timeout: 5s)
68
+ `),process.stdout.write(L(" PreToolUse ")+` \u2192 flow-ai-obs PreToolUse (timeout: 3s)
69
+ `),process.stdout.write(L(" PostToolUse ")+` \u2192 flow-ai-obs PostToolUse (timeout: 10s)
70
+ `),process.stdout.write(L(" Stop ")+` \u2192 flow-ai-obs Stop (timeout: 15s)
22
71
  `),process.stdout.write(`
23
- `),process.stdout.write(O(" Settings: ")+t+`
24
- `),process.stdout.write(O(" Backup: ")+t+`.bkp
25
- `),process.stdout.write(O(" OTEL auth: flow-ai-obs otel-headers")+O(` (reads keychain at runtime)
72
+ `),process.stdout.write(L(" Settings: ")+e+`
73
+ `),process.stdout.write(L(" Backup: ")+e+`.bkp
74
+ `),process.stdout.write(L(" OTEL auth: flow-ai-obs otel-headers")+L(` (reads keychain at runtime)
26
75
  `)),process.stdout.write(`
27
- `),e?process.stdout.write(pr(` \u2713 Ready. Native OTEL + Langfuse trace capture active.
28
-
29
- `)):process.stdout.write(fr(` \u26A0 Not authenticated \u2014 hooks registered, but trace forwarding is inactive.
30
- `)+" Run "+hr("flow-ai-obs auth login")+` to activate Langfuse tracing.
31
-
32
- `),0}Mt.exports={runInstall:Sr};});var Ht=d((Ta,Wt)=>{var{getFlowCredentials:Dt,saveFlowCredentials:Er,clearFlowCredentials:Tr,saveTokenCache:wr,isTokenValid:gr,getConfigPath:Gt,hasCredentials:jt}=x(),{getToken:_r}=K(),{green:Te,red:Q,yellow:Ee,cyan:ee,bold:Vt,dim:M}=W(),mr=/[\x00-\x08\x0B-\x1F\x7F]|\x1b\[[0-9;]*[a-zA-Z]/g;function k(e){return typeof e=="string"?e.replace(mr,""):e}function te(e,t={}){return new Promise((n,s)=>{let{masked:o=false,defaultValue:r=""}=t;process.stdout.write(e+r);let i=r;function a(){try{process.stdin.setRawMode(!1);}catch{}}process.once("uncaughtException",a),process.once("unhandledRejection",a);let p=u=>{if(u===""){l(),s(new Error("SIGINT"));return}if(u==="\r"||u===`
33
- `){l(),process.stdout.write(`
34
- `),n(i);return}if(u==="\x7F"){i.length>0&&(i=i.slice(0,-1),process.stdout.write("\b \b"));return}u.startsWith("\x1B")||(i+=u,process.stdout.write(o?"*".repeat(u.length):u));};function l(){process.stdin.setRawMode(false),process.stdin.removeListener("data",p),process.removeListener("uncaughtException",a),process.removeListener("unhandledRejection",a);}process.stdin.setRawMode(true),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",p);})}async function Yt(e){let{accessToken:t,expiresAt:n}=await _r(e);await Er(e),await wr({accessToken:t,expiresAt:n});}async function yr(e){try{return await Yt(e),process.stdout.write(Te(` \u2713 Setup complete. Tenant: ${k(e.tenant)}
35
-
36
- `)),0}catch(t){return process.stderr.write(Q(` \u2717 Authentication failed: ${k(t.message)}
37
- `)),1}}async function Or(){try{process.stdout.write(`
38
- `);let e=(await te(ee(" ? ")+"Client ID: ")).trim(),t=(await te(ee(" ? ")+"Client Secret: ",{masked:!0})).trim(),n=(await te(ee(" ? ")+"Tenant: ")).trim();if(!e||!t||!n)return process.stderr.write(Q(` \u2717 All fields are required
39
- `)),1;try{await Yt({clientId:e,clientSecret:t,tenant:n});}catch(s){return process.stderr.write(Q(` \u2717 Authentication failed: ${k(s.message)}
40
- `)),1}return process.stdout.write(Te(` \u2713 Setup complete. Tenant: ${k(n)}
41
- `)),process.stdout.write(` Storage: ${await Gt()}
42
-
43
- `),0}catch(e){if(e.message==="SIGINT")throw e;return process.stderr.write(Q(` \u2717 Unexpected error: ${e.message}
44
- `)),1}}async function Lr(e={}){if(e.clientId&&e.clientSecret&&e.tenant)return yr({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant});if(await jt()){let t=await Dt();process.stdout.write(`
45
- `),process.stdout.write(Vt(` Already authenticated
46
- `)),process.stdout.write(M(" Tenant: ")+k(t.tenant)+`
47
- `),process.stdout.write(M(" Client ID: ")+k(t.clientId)+`
48
- `),process.stdout.write(`
49
- `);let n;try{n=await te(ee(" ? ")+"Re-authenticate? (y/N): ");}catch(s){if(s.message==="SIGINT")return process.stdout.write(`
50
- `),130;throw s}if(n.trim().toLowerCase()!=="y")return process.stdout.write(Te(` \u2713 Using existing credentials.
76
+ `),process.stdout.write(po(` \u2713 Ready. Native OTEL + Langfuse trace capture active.
77
+ `)),process.stdout.write(L(" Run `flow-ai-obs setup` to also configure the Flow LLM Proxy.\n\n")),0}sn.exports={runInstall:_o};});var ln=p((ec,un)=>{var{LLM_PROXY:rn}=w(),{green:on,yellow:an,bold:mo,dim:cn}=F(),{runLogin:yo}=ie(),{runInstall:Oo}=et(),{addEnvToClaudeSettings:Ao,validateConnectivity:Lo,getClaudeSettingsPath:No}=Q(),{getFlowCredentials:Io}=j();async function ko(e={}){process.stdout.write(`
78
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
79
+ `),process.stdout.write(`\u2551 flow-ai-obs \u2014 setup \u2551
80
+ `),process.stdout.write(`\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
51
81
 
52
- `)),0}try{return await Or()}catch(t){if(t.message==="SIGINT")return process.stdout.write(`
53
- `),130;throw t}}async function Ar(){try{return process.stdout.write(`
54
- `),(await te(ee(" ? ")+"Are you sure? This will remove your local credentials. (y/N): ")).toLowerCase()!=="y"?(process.stdout.write(Ee(` \u26A0 Logout cancelled
55
- `)),0):null}catch(e){if(e.message==="SIGINT")return process.stdout.write(`
56
- `),130;throw e}}async function Ir(e=false){if(!await jt())return process.stdout.write(Ee(` \u26A0 You are not authenticated
57
- `)),0;if(!e){let t=await Ar();if(t!==null)return t}try{return await Tr(),process.stdout.write(Te(` \u2713 Credentials removed successfully
58
- `)),0}catch{return process.stderr.write(Q(` \u2717 Error removing credentials
59
- `)),1}}async function kr(){let e=await Dt();if(!e)return process.stdout.write(Ee(" \u26A0 Not authenticated. Run `flow-ai-obs auth login` to set up.\n")),0;if(!await gr())return process.stdout.write(Ee(" \u26A0 Session expired. Run `flow-ai-obs auth login` to re-authenticate.\n")),0;let t=e.clientSecret.length>4?"****...****"+e.clientSecret.slice(-4):"****";return process.stdout.write(`
60
- `+Vt(` Authenticated
61
- `)),process.stdout.write(M(" Tenant: ")+k(e.tenant)+`
62
- `),process.stdout.write(M(" Client ID: ")+k(e.clientId)+`
63
- `),process.stdout.write(M(" Client Secret: ")+t+`
64
- `),process.stdout.write(M(" Storage: ")+await Gt()+`
65
-
66
- `),0}Wt.exports={runLogin:Lr,runLogout:Ir,runStatus:kr};});var Jt=d((wa,Kt)=>{var{getFlowCredentials:Nr}=x(),{getToken:Cr}=K();async function br(){let e;try{e=await Nr();}catch{return process.stderr.write(`[flow-ai-obs otel-headers] Failed to read credentials
82
+ `);let t=await yo(e);if(t!==0)return process.stderr.write(`
83
+ Setup aborted. Run \`flow-ai-obs auth login\` to retry.
84
+
85
+ `),t;process.stdout.write(`
86
+ `);let n=await Oo();if(n!==0)return n;try{Ao(rn);}catch(r){process.stderr.write(` \u26A0 Could not write LLM Proxy config: ${r.message}
87
+ `);}process.stdout.write(mo(" Flow LLM Proxy configured")+` (model provider)
88
+ `);for(let[r,o]of Object.entries(rn))process.stdout.write(cn(` ${r.padEnd(36)}`)+o+`
89
+ `);process.stdout.write(`
90
+ `),process.stdout.write(` Validating connectivity to Flow OTEL endpoint\u2026
91
+ `);let s=await Io();return s?await Lo(s)?process.stdout.write(on(` \u2713 Connectivity validated \u2014 telemetry is active.
92
+
93
+ `)):process.stdout.write(an(` \u26A0 Could not reach the OTEL endpoint. Telemetry will activate once connectivity is restored.
94
+
95
+ `)):process.stdout.write(an(` \u26A0 Could not read stored credentials \u2014 skipping connectivity check.
96
+
97
+ `)),process.stdout.write(on(` \u2713 Setup complete!
98
+ `)),process.stdout.write(cn(` Settings: ${No()}
99
+
100
+ `)),0}un.exports={runSetup:ko};});var pn=p((tc,dn)=>{var{getFlowCredentials:Co}=j(),{getToken:vo}=X();async function bo(){let e;try{e=await Co();}catch{return process.stderr.write(`[flow-ai-obs otel-headers] Failed to read credentials
67
101
  `),1}if(!e)return process.stderr.write(`[flow-ai-obs otel-headers] Not authenticated \u2014 run: flow-ai-obs auth login
68
- `),1;let t;try{t=(await Cr(e)).accessToken;}catch(n){return process.stderr.write(`[flow-ai-obs otel-headers] Token fetch failed: ${n.message}
102
+ `),1;let t;try{t=(await vo(e)).accessToken;}catch(n){return process.stderr.write(`[flow-ai-obs otel-headers] Token fetch failed: ${n.message}
69
103
  `),1}return t?(process.stdout.write(`{"Authorization": "Bearer ${t}"}
70
104
  `),0):(process.stderr.write(`[flow-ai-obs otel-headers] Empty token received
71
- `),1)}Kt.exports={runOtelHeaders:br};});var N=d((ga,Xt)=>{var{writeFileSync:Ur}=c("fs"),{tmpdir:vr}=c("os"),{join:Rr}=c("path"),{DEBUG_LOG_FILENAME:Pr,ENV:$r}=w(),zt=Rr(vr(),Pr);function qr(...e){if(process.env[$r.FLOW_OBS_DEBUG]!=="1")return;let t=`[${new Date().toISOString()}] ${e.join(" ")}
72
- `;try{Ur(zt,t,{flag:"a"});}catch(n){process.stderr.write(`[flow-obs debug ERROR] ${n.message}
73
- `);}}Xt.exports={dbg:qr,DEBUG_LOG:zt};});var ne=d((_a,Qt)=>{var{getFlowCredentials:Ve,isTokenValid:Fr,getEmailFromToken:Ye,getTokenCache:xr,saveTokenCache:Mr}=x(),{getToken:Br}=K(),{FLOW_BASE_URL:Dr,ENV:U}=w(),{dbg:we}=N(),Gr=[/^localhost\.?$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/,/^::1$/,/^\[::1\]$/,/^\[::ffff:/i,/^\[f[cd]/i,/^\[fe80:/i,/^metadata\.google\.internal\.?$/i,/^metadata\.azure\.internal\.?$/i,/(?:^|\.)localtest\.me\.?$/i,/(?:^|\.)lvh\.me\.?$/i,/(?:^|\.)vcap\.me\.?$/i];function jr(e){return Gr.some(t=>t.test(e))}function We(e){let t;try{t=new URL(e);}catch{throw new Error(`Invalid URL: ${e}`)}if(!(process.env[U.FLOW_OBS_ALLOW_HTTP]==="true")&&t.protocol!=="https:")throw new Error(`URL must use HTTPS: ${e}`);if(t.username||t.password)throw new Error(`URL must not contain embedded credentials: ${e}`);if(jr(t.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${t.hostname}`);return e}async function Vr(){try{let e=await Ve();if(!e)return {user:"",tenant:""};let t=await Ye()||e.clientId||"",n=e.tenant||"";return {user:t,tenant:n}}catch{return {user:"",tenant:""}}}async function Yr(e){if(await Fr())return (await xr()).accessToken;we("getOrRefreshToken","token expired \u2014 refreshing via auth-engine");let t=await Br(e);return await Mr(t),we("getOrRefreshToken",`token refreshed, expires=${t.expiresAt}`),t.accessToken}function Wr(e,t){let n=t&&t.accessToken?t.accessToken:"";return {endpoint:e.replace(/\/$/,"")+"/langfuse/traces",authHeader:`Bearer ${n}`}}function Hr(e,t,n){let s=Buffer.from(`${t}:${n}`).toString("base64");return {endpoint:e.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${s}`}}async function Zt(){let e=[],t=process.env[U.ANTHROPIC_MODEL]||"",n=process.env[U.FLOW_TELEMETRY]==="true",s=process.env[U.LANGFUSE_BASE_URL],o=process.env[U.LANGFUSE_PUBLIC_KEY],r=process.env[U.LANGFUSE_SECRET_KEY];if(n&&s&&o&&r){let u="",h="";try{let m=await Ve();m&&(u=await Ye()||m.clientId,h=m.tenant);}catch{}let E={user:u||"",tenant:h||"",team:"",project:"",model:t};e.push({mode:"direct",...Hr(We(s),o,r),...E}),we("resolveCredentials","direct mode active",`user=${E.user}`,`tenant=${E.tenant}`);}let i=await Ve();if(!i){if(e.length===0){let u=[];return u.authError=false,u}return e}let a;try{a=await Yr(i);}catch(u){if(we("resolveCredentials",`token refresh failed: ${u.message}`),e.length>0)return e;let h=[];return h.authError=true,h}let p={user:await Ye()||i.clientId,tenant:i.tenant,team:"",project:"",model:t},l=process.env[U.FLOW_TELEMETRY_GATEWAY]||Dr;return e.push({mode:"gateway",...Wr(We(l),{accessToken:a}),...p}),e}async function Kr(){return (await Zt()).length>0}Qt.exports={credentialsAvailable:Kr,getIdentityFromToken:Vr,resolveCredentials:Zt,validateUrl:We};});var tn=d((ma,en)=>{var{getFlowCredentials:Jr,isTokenValid:zr,getEmailFromToken:Xr,getTokenCache:Zr}=x(),{resolveCredentials:Qr}=ne(),{getClaudeSettingsPath:eo}=Ce(),{ENV:B,NATIVE_OTEL:to}=w(),no=c("fs");function He(e){return !e||e.length<=8?"****":e.slice(0,4)+"****...****"+e.slice(-4)}function se(e){process.stdout.write(` \u2713 ${e}
74
- `);}function Ke(e){process.stdout.write(` \u26A0 ${e}
75
- `);}function ge(e){process.stdout.write(` \u2717 ${e}
76
- `);}function g(e){process.stdout.write(` ${e}
77
- `);}function L(){process.stdout.write(`
78
- `);}async function so(){L(),process.stdout.write(` flow-claude-observability \u2014 configuration check
79
- `),L(),process.stdout.write(` Auth
80
- `);let e=await Jr();if(!e)return ge("Not authenticated. Run: flow-claude-observability auth login"),L(),1;if(!await zr())return Ke("Session expired. Run: flow-claude-observability auth login"),g(`Tenant: ${e.tenant}`),g(`Client ID: ${e.clientId}`),L(),1;let t=await Xr()||e.clientId;se("Authenticated"),g(`Tenant: ${e.tenant}`),g(`User: ${t}`),L(),process.stdout.write(` Native OTEL
81
- `);let n={};try{let i=no.readFileSync(eo(),"utf8");n=JSON.parse(i).env||{};}catch{}let s=Object.keys(to).filter(i=>!n[i]);if(s.length===0?(se("All OTEL env vars present in settings.json"),g(`Endpoint: ${n.OTEL_EXPORTER_OTLP_ENDPOINT}`)):(Ke(`${s.length} OTEL var(s) missing from settings.json \u2014 native metrics/logs disabled`),s.forEach(i=>ge(`Missing: ${i}`)),g("Run: flow-ai-obs install (restores missing vars automatically)")),L(),process.stdout.write(` Tracing
82
- `),process.env[B.FLOW_TELEMETRY]==="true"){se("FLOW_TELEMETRY=true (direct mode enabled)");let i=[B.LANGFUSE_BASE_URL,B.LANGFUSE_PUBLIC_KEY,B.LANGFUSE_SECRET_KEY].filter(a=>!process.env[a]);i.length>0&&i.forEach(a=>Ke(`Missing: ${a}`));}else g("FLOW_TELEMETRY not set \u2014 direct mode inactive (gateway mode may still be active)");let r=await Qr();if(!r||r.length===0)return r&&r.authError?ge("Token refresh failed \u2014 gateway mode could not activate"):(ge("No active destinations \u2014 no traces will be sent"),g("For direct mode: set FLOW_TELEMETRY=true + LANGFUSE_BASE_URL + LANGFUSE_PUBLIC_KEY + LANGFUSE_SECRET_KEY"),g("For gateway mode: run flow-claude-observability auth login")),L(),1;for(let i of r)if(i.mode==="gateway"){let a=await Zr();se("Mode: gateway"),g(`Endpoint: ${i.endpoint}`),g(`Token: ${He(a&&a.accessToken)}`);}else i.mode==="direct"&&(se("Mode: direct"),g(`Endpoint: ${i.endpoint}`),g(`PK: ${He(process.env[B.LANGFUSE_PUBLIC_KEY])}`),g(`SK: ${He(process.env[B.LANGFUSE_SECRET_KEY])}`));return L(),process.stdout.write(` All checks passed \u2014 observability is active.
83
- `),L(),0}en.exports={runCheck:so};});var D=d((ya,nn)=>{function ro(e,t){let n=typeof e=="object"?JSON.stringify(e):String(e??"");return n.length>t?n.slice(0,t)+" \u2026[truncated]":n}function oo(e,t=100){return String(e??"").split(`
84
- `)[0].slice(0,t).trim()}function io(){return new Promise(e=>{let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>t+=n),process.stdin.on("end",()=>{try{e(JSON.parse(t));}catch{e({});}});})}function ao(e){process.stdout.write(JSON.stringify(e));}nn.exports={truncate:ro,firstLine:oo,readInput:io,passthrough:ao};});var re=d((Oa,rn)=>{var{randomBytes:sn}=c("crypto"),co=()=>sn(16).toString("hex"),uo=()=>sn(8).toString("hex");function lo(){return String(BigInt(Date.now())*1000000n)}rn.exports={generateTraceId:co,generateSpanId:uo,nowNs:lo};});var oe=d((Aa,an)=>{var{readFileSync:po,writeFileSync:fo,unlinkSync:ho,existsSync:So,realpathSync:La}=c("fs"),{tmpdir:on}=c("os"),{join:Eo,resolve:To,normalize:wo,sep:go}=c("path"),_o=/^[0-9a-f-]{1,64}$/i,mo=wo(on())+go;function yo(e,t){let n=To(e);if(!n.startsWith(t))throw new Error(`Path traversal detected: ${e}`);return n}function Je(e){if(!_o.test(e))throw new Error(`Invalid session ID: ${e}`);return yo(Eo(on(),`flow-obs-${e}.json`),mo)}function Oo(e){let t=Je(e);if(!So(t))return null;try{return JSON.parse(po(t,"utf8"))}catch{return null}}function Lo(e,t){fo(Je(e),JSON.stringify(t),"utf8");}function Ao(e){try{ho(Je(e));}catch{}}an.exports={loadState:Oo,saveState:Lo,deleteState:Ao};});var ze=d((Ia,ln)=>{var{readFileSync:cn,existsSync:un}=c("fs");function Io(e){if(!e||!un(e))return null;try{let t=cn(e,"utf8").trimEnd().split(`
85
- `);for(let n=t.length-1;n>=0;n--)try{let s=JSON.parse(t[n]);if(s.type==="user"&&s.uuid)return s.uuid}catch{}}catch{}return null}function ko(e){if(!e||!un(e))return null;try{let t=cn(e,"utf8").trimEnd().split(`
86
- `),n=[],s=0,o=0,r=!1;for(let i=t.length-1;i>=0;i--)try{let a=JSON.parse(t[i]);if(a.type==="user"){if(r)break;continue}if(a.type==="assistant"){r=!0;let l=(a.message?.content??[]).filter(h=>h.type==="text").map(h=>h.text).join("");l&&n.unshift(l);let u=a.message?.usage??{};s+=(u.input_tokens??0)+(u.cache_read_input_tokens??0)+(u.cache_creation_input_tokens??0),o+=u.output_tokens??0;}}catch{}return !n.length&&s===0?null:{text:n.join(`
87
-
88
- `),inputTokens:s,outputTokens:o}}catch{}return null}ln.exports={readPromptUuid:Io,readLastAssistantOutput:ko};});var _e=d((ka,hn)=>{var{readFileSync:No,existsSync:dn,readdirSync:Co}=c("fs"),{homedir:pn}=c("os"),{join:G,extname:bo}=c("path"),Uo=new Set([".venv","__pycache__",".git","node_modules"]),vo=new Set([".pyc",".pyo"]),Ro=new Set(["SKILL.md",".DS_Store",".gitignore"]);function Po(e,t){if(!e)return null;let n=[G(pn(),".claude","skills",e,"SKILL.md"),G(t||"",".claude","skills",e,"SKILL.md")];for(let s of n)if(dn(s))try{return No(s,"utf8")}catch{}return null}function $o(e){return e.match(/^\/([a-z][a-z0-9-]*)(?:\s.*)?$/i)?.[1]||null}var fn=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function qo(e){return !!e.slashSkill||e.toolCalls.some(s=>s.tool==="Skill")?e.toolCalls.some(s=>fn.has(s.tool))?"complete":"prerequisite_required":null}function Fo(e,t){if(!e)return null;let n=[G(pn(),".claude","skills",e),G(t||"",".claude","skills",e)],s=null;for(let i of n)if(dn(G(i,"SKILL.md"))){s=i;break}if(!s)return null;let o=[];function r(i,a){for(let p of Co(i,{withFileTypes:true})){if(Uo.has(p.name)||Ro.has(p.name)||vo.has(bo(p.name)))continue;let l=a?`${a}/${p.name}`:p.name;p.isDirectory()?r(G(i,p.name),l):o.push(l);}}return r(s,""),o.length>0?o:null}hn.exports={readSkillContent:Po,readSkillArtifacts:Fo,detectSlashSkill:$o,EXECUTION_TOOLS:fn,detectExecutionStatus:qo};});var Tn=d((Na,En)=>{var{generateTraceId:Sn,generateSpanId:xo,nowNs:Mo}=re(),{saveState:Bo}=oe(),{readPromptUuid:Do}=ze(),{detectSlashSkill:Go,readSkillContent:jo,readSkillArtifacts:Vo}=_e(),{passthrough:Yo}=D(),{dbg:Wo}=N(),{ENV:Ho}=w();async function Ko(e){let t=e.session_id||"unknown",n=e.prompt||"",s=e.cwd||"",o=Do(e.transcript_path)||Sn(),r=Go(n),i=r?jo(r,s):null,a=r?Vo(r,s):null;Bo(t,{traceId:Sn(),spanId:xo(),startNs:Mo(),sessionId:t,prompt:n,cwd:s,traceName:o,transcriptPath:e.transcript_path||"",model:process.env[Ho.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:r,skillContent:i,skillArtifacts:a}),Wo("UserPromptSubmit",`sid=${t}`,`traceName=${o}`,`slashSkill=${r}`),Yo(e);}En.exports={onUserPromptSubmit:Ko};});var gn=d((Ca,wn)=>{var{nowNs:Jo}=re(),{loadState:zo,saveState:Xo}=oe(),{truncate:Zo,passthrough:Qo}=D(),{dbg:ei}=N(),{TRACE_LIMITS:ti}=w();async function ni(e){let t=e.session_id||"unknown",n=e.tool_name||"unknown",s=e.tool_input||{},o=zo(t);o&&(o.pendingTool={name:n,inputStr:Zo(s,ti.TOOL_INPUT),startNs:Jo()},Xo(t,o)),ei("PreToolUse",`sid=${t}`,`tool=${n}`,`stateFound=${!!o}`),Qo(e);}wn.exports={onPreToolUse:ni};});var yn=d((ba,mn)=>{var si=c("https"),ri=c("http"),{FLOW_URLS:oi}=w();function ii(e){let t=new URL(e),n=new URL(oi.GATEWAY_HEALTH);return n.hostname=t.hostname,n.port=t.port,n.protocol=t.protocol,n}function _n(e,t){return new Promise((n,s)=>{let r=(e._isSSL?si:ri).request(e,i=>{let a=[];i.on("data",p=>a.push(p)),i.on("end",()=>n({statusCode:i.statusCode,body:a.join("")}));});r.on("error",i=>s(new Error(`Network error: ${i.message}`))),t&&r.write(t),r.end();})}async function ai(e){let t;try{t=ii(e);}catch{return false}let n=t.protocol==="https:";try{let s=await _n({hostname:t.hostname,port:t.port||(n?443:80),path:t.pathname,method:"GET",_isSSL:n},null);return s.statusCode>=200&&s.statusCode<300}catch{return false}}async function ci(e,t,n){let s=JSON.stringify(e),o=new URL(t),r=o.protocol==="https:",i=String(n).replace(/[\r\n]/g,"");try{return (await _n({hostname:o.hostname,port:o.port||(r?443:80),path:o.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(s)},_isSSL:r},s)).statusCode}catch{return 0}}mn.exports={checkHealth:ai,sendTraces:ci};});var In=d((Ua,An)=>{var C=c("fs"),Xe=c("path"),On=c("os"),{BUFFER:ie}=w(),{dbg:ae}=N();function Ln(e){if(/[/\\]/.test(e))throw new Error(`Invalid buffer fileId: ${e}`);return Xe.join(On.tmpdir(),`${ie.FILE_PREFIX}${e}.json`)}function Ze(){let e=On.tmpdir(),t;try{t=C.readdirSync(e);}catch{return []}return t.filter(n=>n.startsWith(ie.FILE_PREFIX)&&n.endsWith(".json")).map(n=>{let s=Xe.join(e,n),o=0;try{o=C.statSync(s).mtimeMs;}catch{}return {full:s,mtime:o}}).sort((n,s)=>n.mtime-s.mtime).map(n=>n.full)}function ui(e){try{let t=Ze();if(t.length>=ie.MAX_FILES){let o=t.slice(0,t.length-ie.MAX_FILES+1);for(let r of o)try{C.unlinkSync(r);}catch{}}let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:n,bufferedAt:Date.now(),payload:e};return C.writeFileSync(Ln(n),JSON.stringify(s),"utf8"),ae("buffer",`saved fileId=${n}`),n}catch(t){return ae("buffer",`saveToBuffer failed: ${t.message}`),null}}function li(){let e=Ze(),t=[];for(let n of e)try{let s=C.readFileSync(n,"utf8"),o=JSON.parse(s);o&&o.fileId&&o.payload&&t.push(o);}catch{ae("buffer",`skipping malformed file: ${n}`);}return t}function di(e){try{C.unlinkSync(Ln(e)),ae("buffer",`deleted fileId=${e}`);}catch{}}function pi(){let e=Ze(),t=Date.now()-ie.MAX_AGE_MS;for(let n of e)try{let{mtimeMs:s}=C.statSync(n);s<t&&(C.unlinkSync(n),ae("buffer",`evicted stale: ${Xe.basename(n)}`));}catch{}}An.exports={saveToBuffer:ui,loadBuffer:li,deleteBuffer:di,cleanStaleBuffers:pi};});var Qe=d((va,bn)=>{var{resolveCredentials:fi}=ne(),{OTLP:kn}=w(),{dbg:j}=N(),{checkHealth:hi,sendTraces:Cn}=yn(),{saveToBuffer:Nn,loadBuffer:Si,deleteBuffer:Ei,cleanStaleBuffers:Ti}=In(),wi={name:kn.SCOPE_NAME,version:kn.SCOPE_VERSION},gi={TRACE_NAME:"langfuse.trace.name",TRACE_INPUT:"langfuse.trace.input",TRACE_OUTPUT:"langfuse.trace.output",TRACE_METADATA:"langfuse.trace.metadata",TRACE_TAGS:"langfuse.trace.tags",USER_ID:"langfuse.user.id",SESSION_ID:"langfuse.session.id",OBS_NAME:"langfuse.observation.name",OBS_INPUT:"langfuse.observation.input",OBS_OUTPUT:"langfuse.observation.output",OBS_LEVEL:"langfuse.observation.level",OBS_TYPE:"langfuse.observation.type",MODEL:"gen_ai.request.model",INPUT_TOKENS:"gen_ai.usage.input_tokens",OUTPUT_TOKENS:"gen_ai.usage.output_tokens"};function _i(e,t){return t==null||t===""?null:{key:e,value:{stringValue:String(t)}}}function mi(...e){return e.filter(Boolean)}function yi(e,t){return {resourceSpans:[{resource:{attributes:e},scopeSpans:[{scope:wi,spans:Array.isArray(t)?t:[t]}]}]}}function Oi(e,t){return new Promise(n=>{let s=JSON.stringify(e),o=new URL(t.endpoint),r=o.protocol==="https:",i=u=>String(u).replace(/[\r\n]/g,""),a={hostname:o.hostname,port:o.port||(r?443:80),path:o.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:i(t.authHeader),"Content-Length":Buffer.byteLength(s)}},l=(r?c("https"):c("http")).request(a,u=>{u.resume(),n(u.statusCode);});l.on("error",()=>n(0)),l.write(s),l.end();})}async function Li(e){Ti();let t=Si();if(t.length){j("replayBufferedTraces",`replaying ${t.length} buffered trace(s)`);for(let n of t)try{let s=await Cn(n.payload,e.endpoint,e.authHeader);s>=200&&s<300?(Ei(n.fileId),j("replayBufferedTraces",`replayed fileId=${n.fileId} status=${s}`)):j("replayBufferedTraces",`replay failed fileId=${n.fileId} status=${s}`);}catch(s){j("replayBufferedTraces",`replay error fileId=${n.fileId}: ${s.message}`);}}}async function Ai(e){let t=await fi();return t.length?(await Promise.all(t.map(async s=>s.mode==="gateway"?await hi(s.endpoint)?(await Li(s),Cn(e,s.endpoint,s.authHeader)):(j("postToLangfuse","gateway health check failed \u2014 buffering trace"),Nn(e),0):Oi(e,s)))).find(s=>s!==0)||0:(t.authError&&(j("postToLangfuse","auth refresh failed \u2014 buffering trace"),Nn(e)),0)}bn.exports={LF:gi,a:_i,attrs:mi,buildPayload:yi,postToLangfuse:Ai};});var et=d((Ra,Un)=>{var _="[REDACTED]",Ii=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${_}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${_}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(e,t)=>`${t}${_}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(e,t)=>`${t}${_}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(e,t,n)=>`${t}
105
+ `),1)}dn.exports={runOtelHeaders:bo};});var En=p((nc,Tn)=>{var{getFlowCredentials:fn,isTokenValid:Uo,getEmailFromToken:Ro,getTokenCache:Po}=j(),{resolveCredentials:$o,parseCredsFromAnthropicToken:hn}=P(),{getClaudeSettingsPath:qo}=Q(),{ENV:b,NATIVE_OTEL:Fo}=w(),{runLogin:Sn}=ie(),xo=c("fs");function tt(e){return !e||e.length<=8?"****":e.slice(0,4)+"****...****"+e.slice(-4)}function ae(e){process.stdout.write(` \u2713 ${e}
106
+ `);}function Oe(e){process.stdout.write(` \u26A0 ${e}
107
+ `);}function Ae(e){process.stdout.write(` \u2717 ${e}
108
+ `);}function m(e){process.stdout.write(` ${e}
109
+ `);}function y(){process.stdout.write(`
110
+ `);}async function Mo(){y(),process.stdout.write(` flow-claude-observability \u2014 configuration check
111
+ `),y(),process.stdout.write(` Auth
112
+ `);let e=hn(process.env[b.ANTHROPIC_AUTH_TOKEN]),t=e||await fn();if(!t){Oe("Not authenticated \u2014 starting setup..."),y();let a=await Sn();if(a!==0)return a;if(e=hn(process.env[b.ANTHROPIC_AUTH_TOKEN]),t=e||await fn(),!t)return Ae("Authentication failed"),y(),1;y(),process.stdout.write(` Auth
113
+ `);}if(!e&&!await Uo()){Oe("Session expired \u2014 re-authenticating..."),y();let a=await Sn();if(a!==0)return a;y(),process.stdout.write(` Auth
114
+ `);}let n=await Ro()||t.clientId;ae("Authenticated"),m(`Tenant: ${t.tenant}`),m(`User: ${n}`),y(),process.stdout.write(` Native OTEL
115
+ `);let s={};try{let a=xo.readFileSync(qo(),"utf8");s=JSON.parse(a).env||{};}catch{}let r=Object.keys(Fo).filter(a=>!s[a]);if(r.length===0?(ae("All OTEL env vars present in settings.json"),m(`Endpoint: ${s.OTEL_EXPORTER_OTLP_ENDPOINT}`)):(Oe(`${r.length} OTEL var(s) missing from settings.json \u2014 native metrics/logs disabled`),r.forEach(a=>Ae(`Missing: ${a}`)),m("Run: flow-ai-obs install (restores missing vars automatically)")),y(),process.stdout.write(` Tracing
116
+ `),process.env[b.FLOW_TELEMETRY]==="true"){ae("FLOW_TELEMETRY=true (direct mode enabled)");let a=[b.LANGFUSE_BASE_URL,b.LANGFUSE_PUBLIC_KEY,b.LANGFUSE_SECRET_KEY].filter(u=>!process.env[u]);a.length>0&&a.forEach(u=>Oe(`Missing: ${u}`));}else m("FLOW_TELEMETRY not set \u2014 direct mode inactive (gateway mode may still be active)");let i=await $o();if(!i||i.length===0)return i&&i.authError?Ae("Token refresh failed \u2014 gateway mode could not activate"):(Ae("No active destinations \u2014 no traces will be sent"),m("For direct mode: set FLOW_TELEMETRY=true + LANGFUSE_BASE_URL + LANGFUSE_PUBLIC_KEY + LANGFUSE_SECRET_KEY"),m("For gateway mode: run flow-claude-observability auth login")),y(),1;for(let a of i)if(a.mode==="gateway"){let u=await Po();ae("Mode: gateway"),m(`Endpoint: ${a.endpoint}`),m(`Token: ${tt(u&&u.accessToken)}`);}else a.mode==="direct"&&(ae("Mode: direct"),m(`Endpoint: ${a.endpoint}`),m(`PK: ${tt(process.env[b.LANGFUSE_PUBLIC_KEY])}`),m(`SK: ${tt(process.env[b.LANGFUSE_SECRET_KEY])}`));return y(),process.stdout.write(` All checks passed \u2014 observability is active.
117
+ `),y(),0}Tn.exports={runCheck:Mo};});var K=p((sc,wn)=>{function Bo(e,t){let n=typeof e=="object"?JSON.stringify(e):String(e??"");return n.length>t?n.slice(0,t)+" \u2026[truncated]":n}function Do(e,t=100){return String(e??"").split(`
118
+ `)[0].slice(0,t).trim()}function Ho(){return new Promise(e=>{let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>t+=n),process.stdin.on("end",()=>{try{e(JSON.parse(t));}catch{e({});}});})}function jo(e){process.stdout.write(JSON.stringify(e));}wn.exports={truncate:Bo,firstLine:Do,readInput:Ho,passthrough:jo};});var ce=p((rc,_n)=>{var{randomBytes:gn}=c("crypto"),Go=()=>gn(16).toString("hex"),Yo=()=>gn(8).toString("hex");function Ko(){return String(BigInt(Date.now())*1000000n)}_n.exports={generateTraceId:Go,generateSpanId:Yo,nowNs:Ko};});var ue=p((ic,yn)=>{var{readFileSync:Vo,writeFileSync:Wo,unlinkSync:Jo,existsSync:Xo,realpathSync:oc}=c("fs"),{tmpdir:mn}=c("os"),{join:zo,resolve:Zo,normalize:Qo,sep:ei}=c("path"),ti=/^[0-9a-f-]{1,64}$/i,ni=Qo(mn())+ei;function si(e,t){let n=Zo(e);if(!n.startsWith(t))throw new Error(`Path traversal detected: ${e}`);return n}function nt(e){if(!ti.test(e))throw new Error(`Invalid session ID: ${e}`);return si(zo(mn(),`flow-obs-${e}.json`),ni)}function ri(e){let t=nt(e);if(!Xo(t))return null;try{return JSON.parse(Vo(t,"utf8"))}catch{return null}}function oi(e,t){Wo(nt(e),JSON.stringify(t),{encoding:"utf8",mode:384});}function ii(e){try{Jo(nt(e));}catch{}}yn.exports={loadState:ri,saveState:oi,deleteState:ii};});var st=p((ac,Ln)=>{var{readFileSync:On,existsSync:An}=c("fs");function ai(e){if(!e||!An(e))return null;try{let t=On(e,"utf8").trimEnd().split(`
119
+ `);for(let n=t.length-1;n>=0;n--)try{let s=JSON.parse(t[n]);if(s.type==="user"&&s.uuid)return s.uuid}catch{}}catch{}return null}function ci(e){if(!e||!An(e))return null;try{let t=On(e,"utf8").trimEnd().split(`
120
+ `),n=[],s=0,r=0,o=!1;for(let i=t.length-1;i>=0;i--)try{let a=JSON.parse(t[i]);if(a.type==="user"){if(o)break;continue}if(a.type==="assistant"){o=!0;let d=(a.message?.content??[]).filter(h=>h.type==="text").map(h=>h.text).join("");d&&n.unshift(d);let l=a.message?.usage??{};s+=(l.input_tokens??0)+(l.cache_read_input_tokens??0)+(l.cache_creation_input_tokens??0),r+=l.output_tokens??0;}}catch{}return !n.length&&s===0?null:{text:n.join(`
121
+
122
+ `),inputTokens:s,outputTokens:r}}catch{}return null}Ln.exports={readPromptUuid:ai,readLastAssistantOutput:ci};});var Le=p((cc,Cn)=>{var{readFileSync:ui,existsSync:Nn,readdirSync:li}=c("fs"),{homedir:In}=c("os"),{join:V,extname:di}=c("path"),pi=new Set([".venv","__pycache__",".git","node_modules"]),fi=new Set([".pyc",".pyo"]),hi=new Set(["SKILL.md",".DS_Store",".gitignore"]);function Si(e,t){if(!e)return null;let n=[V(In(),".claude","skills",e,"SKILL.md"),V(t||"",".claude","skills",e,"SKILL.md")];for(let s of n)if(Nn(s))try{return ui(s,"utf8")}catch{}return null}function Ti(e){return e.match(/^\/([a-z][a-z0-9-]*)(?:\s.*)?$/i)?.[1]||null}var kn=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function Ei(e){return !!e.slashSkill||e.toolCalls.some(s=>s.tool==="Skill")?e.toolCalls.some(s=>kn.has(s.tool))?"complete":"prerequisite_required":null}function wi(e,t){if(!e)return null;let n=[V(In(),".claude","skills",e),V(t||"",".claude","skills",e)],s=null;for(let i of n)if(Nn(V(i,"SKILL.md"))){s=i;break}if(!s)return null;let r=[];function o(i,a){for(let u of li(i,{withFileTypes:true})){if(pi.has(u.name)||hi.has(u.name)||fi.has(di(u.name)))continue;let d=a?`${a}/${u.name}`:u.name;u.isDirectory()?o(V(i,u.name),d):r.push(d);}}return o(s,""),r.length>0?r:null}Cn.exports={readSkillContent:Si,readSkillArtifacts:wi,detectSlashSkill:Ti,EXECUTION_TOOLS:kn,detectExecutionStatus:Ei};});var Rn=p((uc,Un)=>{var{generateTraceId:vn,generateSpanId:gi,nowNs:_i}=ce(),{saveState:mi}=ue(),{readPromptUuid:yi}=st(),{detectSlashSkill:Oi,readSkillContent:Ai,readSkillArtifacts:Li}=Le(),{passthrough:Ni}=K(),{dbg:bn}=C(),{ENV:Ii}=w(),{resolveCredentials:ki}=P();async function Ci(e){let t=e.session_id||"unknown",n=e.prompt||"",s=e.cwd||"";try{(await ki()).authError===!0&&(process.stderr.write(`
123
+ \u26A0 flow-ai-obs: Your Flow credentials have expired.
124
+ Traces will not be captured until you re-authenticate.
125
+ Run: flow-ai-obs auth login
126
+
127
+ `),bn("UserPromptSubmit","auth expired \u2014 warning emitted to stderr"));}catch{}let r=yi(e.transcript_path)||vn(),o=Oi(n),i=o?Ai(o,s):null,a=o?Li(o,s):null;mi(t,{traceId:vn(),spanId:gi(),startNs:_i(),sessionId:t,prompt:n,cwd:s,traceName:r,transcriptPath:e.transcript_path||"",model:process.env[Ii.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:o,skillContent:i,skillArtifacts:a}),bn("UserPromptSubmit",`sid=${t}`,`traceName=${r}`,`slashSkill=${o}`),Ni(e);}Un.exports={onUserPromptSubmit:Ci};});var $n=p((lc,Pn)=>{var{nowNs:vi}=ce(),{loadState:bi,saveState:Ui}=ue(),{truncate:Ri,passthrough:Pi}=K(),{dbg:$i}=C(),{TRACE_LIMITS:qi}=w();async function Fi(e){let t=e.session_id||"unknown",n=e.tool_name||"unknown",s=e.tool_input||{},r=bi(t);r&&(r.pendingTool={name:n,inputStr:Ri(s,qi.TOOL_INPUT),startNs:vi()},Ui(t,r)),$i("PreToolUse",`sid=${t}`,`tool=${n}`,`stateFound=${!!r}`),Pi(e);}Pn.exports={onPreToolUse:Fi};});var xn=p((dc,Fn)=>{var xi=c("https"),Mi=c("http"),{FLOW_URLS:Bi}=w();function Di(e){let t=new URL(e),n=new URL(Bi.GATEWAY_HEALTH);return n.hostname=t.hostname,n.port=t.port,n.protocol=t.protocol,n}function qn(e,t){return new Promise((n,s)=>{let o=(e._isSSL?xi:Mi).request(e,i=>{let a=[];i.on("data",u=>a.push(u)),i.on("end",()=>n({statusCode:i.statusCode,body:a.join("")}));});o.on("error",i=>s(new Error(`Network error: ${i.message}`))),t&&o.write(t),o.end();})}async function Hi(e){let t;try{t=Di(e);}catch{return false}let n=t.protocol==="https:";try{let s=await qn({hostname:t.hostname,port:t.port||(n?443:80),path:t.pathname,method:"GET",_isSSL:n},null);return s.statusCode>=200&&s.statusCode<300}catch{return false}}async function ji(e,t,n){let s=JSON.stringify(e),r=new URL(t),o=r.protocol==="https:",i=String(n).replace(/[\r\n]/g,"");try{return (await qn({hostname:r.hostname,port:r.port||(o?443:80),path:r.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(s)},_isSSL:o},s)).statusCode}catch{return 0}}Fn.exports={checkHealth:Hi,sendTraces:ji};});var Hn=p((pc,Dn)=>{var U=c("fs"),rt=c("path"),Mn=c("os"),{BUFFER:le}=w(),{dbg:de}=C();function Bn(e){if(/[/\\]/.test(e))throw new Error(`Invalid buffer fileId: ${e}`);return rt.join(Mn.tmpdir(),`${le.FILE_PREFIX}${e}.json`)}function ot(){let e=Mn.tmpdir(),t;try{t=U.readdirSync(e);}catch{return []}return t.filter(n=>n.startsWith(le.FILE_PREFIX)&&n.endsWith(".json")).map(n=>{let s=rt.join(e,n),r=0;try{r=U.statSync(s).mtimeMs;}catch{}return {full:s,mtime:r}}).sort((n,s)=>n.mtime-s.mtime).map(n=>n.full)}function Gi(e){try{let t=ot();if(t.length>=le.MAX_FILES){let r=t.slice(0,t.length-le.MAX_FILES+1);for(let o of r)try{U.unlinkSync(o);}catch{}}let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:n,bufferedAt:Date.now(),payload:e};return U.writeFileSync(Bn(n),JSON.stringify(s),{encoding:"utf8",mode:384}),de("buffer",`saved fileId=${n}`),n}catch(t){return de("buffer",`saveToBuffer failed: ${t.message}`),null}}function Yi(){let e=ot(),t=[];for(let n of e)try{let s=U.readFileSync(n,"utf8"),r=JSON.parse(s);r&&r.fileId&&r.payload&&t.push(r);}catch{de("buffer",`skipping malformed file: ${n}`);}return t}function Ki(e){try{U.unlinkSync(Bn(e)),de("buffer",`deleted fileId=${e}`);}catch{}}function Vi(){let e=ot(),t=Date.now()-le.MAX_AGE_MS;for(let n of e)try{let{mtimeMs:s}=U.statSync(n);s<t&&(U.unlinkSync(n),de("buffer",`evicted stale: ${rt.basename(n)}`));}catch{}}Dn.exports={saveToBuffer:Gi,loadBuffer:Yi,deleteBuffer:Ki,cleanStaleBuffers:Vi};});var it=p((fc,Kn)=>{var{resolveCredentials:Wi}=P(),{OTLP:jn}=w(),{dbg:W}=C(),{checkHealth:Ji,sendTraces:Yn}=xn(),{saveToBuffer:Gn,loadBuffer:Xi,deleteBuffer:zi,cleanStaleBuffers:Zi}=Hn(),Qi={name:jn.SCOPE_NAME,version:jn.SCOPE_VERSION},ea={TRACE_NAME:"langfuse.trace.name",TRACE_INPUT:"langfuse.trace.input",TRACE_OUTPUT:"langfuse.trace.output",TRACE_METADATA:"langfuse.trace.metadata",TRACE_TAGS:"langfuse.trace.tags",USER_ID:"langfuse.user.id",SESSION_ID:"langfuse.session.id",OBS_NAME:"langfuse.observation.name",OBS_INPUT:"langfuse.observation.input",OBS_OUTPUT:"langfuse.observation.output",OBS_LEVEL:"langfuse.observation.level",OBS_TYPE:"langfuse.observation.type",MODEL:"gen_ai.request.model",INPUT_TOKENS:"gen_ai.usage.input_tokens",OUTPUT_TOKENS:"gen_ai.usage.output_tokens"};function ta(e,t){return t==null||t===""?null:{key:e,value:{stringValue:String(t)}}}function na(...e){return e.filter(Boolean)}function sa(e,t){return {resourceSpans:[{resource:{attributes:e},scopeSpans:[{scope:Qi,spans:Array.isArray(t)?t:[t]}]}]}}function ra(e,t){return new Promise(n=>{let s=JSON.stringify(e),r=new URL(t.endpoint),o=r.protocol==="https:",i=l=>String(l).replace(/[\r\n]/g,""),a={hostname:r.hostname,port:r.port||(o?443:80),path:r.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:i(t.authHeader),"Content-Length":Buffer.byteLength(s)}},d=(o?c("https"):c("http")).request(a,l=>{l.resume(),n(l.statusCode);});d.on("error",()=>n(0)),d.write(s),d.end();})}async function oa(e){Zi();let t=Xi();if(t.length){W("replayBufferedTraces",`replaying ${t.length} buffered trace(s)`);for(let n of t)try{let s=await Yn(n.payload,e.endpoint,e.authHeader);s>=200&&s<300?(zi(n.fileId),W("replayBufferedTraces",`replayed fileId=${n.fileId} status=${s}`)):W("replayBufferedTraces",`replay failed fileId=${n.fileId} status=${s}`);}catch(s){W("replayBufferedTraces",`replay error fileId=${n.fileId}: ${s.message}`);}}}async function ia(e){let t=await Wi();return t.length?(await Promise.all(t.map(async s=>s.mode==="gateway"?await Ji(s.endpoint)?(await oa(s),Yn(e,s.endpoint,s.authHeader)):(W("postToLangfuse","gateway health check failed \u2014 buffering trace"),Gn(e),0):ra(e,s)))).find(s=>s!==0)||0:(t.authError&&(W("postToLangfuse","auth refresh failed \u2014 buffering trace"),Gn(e)),0)}Kn.exports={LF:ea,a:ta,attrs:na,buildPayload:sa,postToLangfuse:ia};});var at=p((hc,Vn)=>{var _="[REDACTED]",aa=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${_}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${_}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(e,t)=>`${t}${_}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(e,t)=>`${t}${_}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(e,t,n)=>`${t}
89
128
  ${_}
90
- ${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${_}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(e,t)=>`${t}${_}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${_}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${_}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${_}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(e,t,n)=>`${t}${n}${_}${n}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(e,t)=>`${t}:${_}@`}];function ki(e){if(e==null)return "";let t=typeof e=="string"?e:JSON.stringify(e);return Ii.reduce((n,{re:s,replace:o})=>n.replace(s,o),t)}Un.exports={sanitize:ki,REDACTED:_};});var xn=d((Pa,Fn)=>{var{generateSpanId:Ni,nowNs:Ci}=re(),{loadState:bi,saveState:Ui}=oe(),{LF:ce,a:v,attrs:vi}=Qe(),{truncate:vn,firstLine:Ri,passthrough:Rn}=D(),{readSkillContent:Pi,readSkillArtifacts:$i}=_e(),{dbg:Pn}=N(),{TRACE_LIMITS:$n}=w(),{sanitize:qn}=et();async function qi(e){let t=e.session_id||"unknown",n=e.tool_name||"unknown",s=e.tool_input||{},o=e.tool_response||"",r=bi(t);if(!r){Rn(e);return}let i=Ci(),a=r.pendingTool?.name===n,p=a?r.pendingTool.startNs:String(BigInt(i)-200000000n),l=a?r.pendingTool.inputStr:vn(s,$n.TOOL_INPUT),u=l;if(n==="Skill"){let b=typeof s=="object"&&s!==null?s.skill||s.name||s.skillName||String(Object.values(s)[0]??""):String(s),I=b?Pi(b.trim(),r.cwd):null;I&&(u=I,r.skillContent||(r.skillContent=I),r.slashSkill||(r.slashSkill=b.trim()),r.skillArtifacts||(r.skillArtifacts=$i(b.trim(),r.cwd))),Pn("PostToolUse","Skill tool detected",`skillName=${b}`,`contentFound=${!!I}`);}let h=qn(vn(o,$n.TOOL_OUTPUT)),E=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(h.slice(0,500)),m=E?"ERROR":"DEFAULT",V=Ni(),de=Math.round(Number(BigInt(i)-BigInt(p))/1e6),Le={Agent:"AGENT",Task:"AGENT"}[n]??"TOOL";r.toolCalls.push({tool:n,brief:Ri(l,60),error:E,durationMs:de}),r.spans.push({traceId:r.traceId,spanId:V,parentSpanId:r.spanId,name:n,kind:3,startTimeUnixNano:p,endTimeUnixNano:i,attributes:vi(v(ce.OBS_NAME,n),v(ce.OBS_TYPE,Le),v(ce.OBS_LEVEL,m),v(ce.OBS_INPUT,qn(u)),v(ce.OBS_OUTPUT,h),v("tool.name",n),v("tool.error",String(E))),status:{code:E?2:1}}),r.pendingTool=null,Ui(t,r),Pn("PostToolUse",`sid=${t}`,`tool=${n}`,`error=${E}`,`durationMs=${de}`,`totalSpans=${r.spans.length}`),Rn(e);}Fn.exports={onPostToolUse:qi};});var Bn=d(($a,Mn)=>{var tt={"claude-opus-4-6":{input:15,output:75},"claude-opus-4-5":{input:15,output:75},"claude-sonnet-4-6":{input:3,output:15},"claude-sonnet-4-5":{input:3,output:15},"claude-haiku-4-5":{input:.8,output:4},"claude-4-6-opus":{input:15,output:75},"claude-4-6-sonnet":{input:3,output:15},"claude-4-5-opus":{input:15,output:75},"claude-4-5-sonnet":{input:3,output:15},"claude-4-5-haiku":{input:.8,output:4},"claude-3-5-sonnet-20241022":{input:3,output:15},"claude-3-5-haiku-20241022":{input:.8,output:4},"claude-3-opus-20240229":{input:15,output:75}};function Fi(e,t,n){let s=Object.keys(tt).find(i=>(e||"").toLowerCase().includes(i));if(!s)return;let o=tt[s],r=(t*o.input+n*o.output)/1e6;return Math.round(r*1e6)/1e6}Mn.exports={MODEL_PRICING:tt,calcCostUsd:Fi};});var Yn=d((qa,Vn)=>{var{generateSpanId:Dn,nowNs:xi}=re(),{loadState:Mi,deleteState:Gn}=oe(),{LF:T,a:f,attrs:me,buildPayload:Bi,postToLangfuse:Di}=Qe(),{getIdentityFromToken:Gi}=ne(),{calcCostUsd:ji}=Bn(),{readLastAssistantOutput:Vi}=ze(),{truncate:ye,firstLine:Yi,passthrough:nt}=D(),{dbg:ue}=N(),{detectExecutionStatus:Wi}=_e(),{sanitize:jn}=et(),{TRACE_LIMITS:Oe}=w();async function Hi(e){let t=e.session_id||"unknown",n=e.stop_reason||"end_turn",s=Mi(t);if(!s){nt(e);return}let o=xi(),r=await Gi();if(s.slashSkill&&!s.toolCalls.some(S=>S.tool==="Skill")){let S=Dn(),Y=s.skillContent?s.skillContent:JSON.stringify({skill:s.slashSkill});s.toolCalls.push({tool:"Skill",brief:s.slashSkill,error:false,durationMs:0,synthetic:true}),s.spans.push({traceId:s.traceId,spanId:S,parentSpanId:s.spanId,name:"Skill",kind:3,startTimeUnixNano:s.startNs,endTimeUnixNano:s.startNs,attributes:me(f(T.OBS_NAME,"Skill"),f(T.OBS_TYPE,"TOOL"),f(T.OBS_LEVEL,"DEFAULT"),f(T.OBS_INPUT,Y),f(T.OBS_OUTPUT,"loaded via slash command"),f("tool.name","Skill"),f("tool.error","false"),f("skill.name",s.slashSkill),f("skill.invocation","slash-command")),status:{code:1}}),ue("Stop",`slashSkill=${s.slashSkill}`,"synthetic span injected");}let i=e.transcript_path||s.transcriptPath||"",a=Vi(i),p=s.toolCalls.length,l=s.toolCalls.filter(S=>S.error).length,u=jn(a?.text?ye(a.text,Oe.TRACE_OUTPUT):p===0?"No tools used":s.toolCalls.map((S,Y)=>`${Y+1}. ${S.tool}${S.brief?` \u2192 ${S.brief}`:""}${S.error?" [ERROR]":""}`).join(`
91
- `)),h=a?.inputTokens??0,E=a?.outputTokens??0,m=s.toolCalls.map((S,Y)=>`${Y+1}. ${S.tool}${S.brief?` \u2192 ${S.brief}`:""}${S.error?" [ERROR]":""} (${S.durationMs}ms)`),V=!!(s.slashSkill||s.toolCalls.some(S=>S.tool==="Skill")),de=s.toolCalls.some(S=>S.tool==="Agent");if(!V&&!de){ue("Stop",`sid=${t}`,"skipping trace \u2014 no Skill or Agent calls found"),Gn(t),nt(e);return}let pe=V?"skill":"agent",Le=Math.round(Number(BigInt(o)-BigInt(s.startNs))/1e6),b=ji(s.model,h,E),I=Wi(s);I==="prerequisite_required"&&(s.spans.push({traceId:s.traceId,spanId:Dn(),parentSpanId:s.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:s.startNs,endTimeUnixNano:o,attributes:me(f(T.OBS_NAME,"prerequisite-check"),f(T.OBS_TYPE,"EVENT"),f(T.OBS_LEVEL,"WARNING"),f(T.OBS_OUTPUT,u),f("skill.name",s.slashSkill||void 0),f("execution_status","prerequisite_required")),status:{code:1}}),ue("Stop",`sid=${t}`,"prerequisite-check span injected",`skill=${s.slashSkill}`));let st=(()=>{if(!(!V||!s.prompt)){if(s.slashSkill){let S=s.prompt.replace(new RegExp(`^\\/${s.slashSkill}\\s*`,"i"),"").trim();return S?ye(S,Oe.USER_INSTRUCTION):void 0}return ye(s.prompt,Oe.USER_INSTRUCTION)||void 0}})(),Hn=JSON.stringify({trace_type:pe,...I!==null&&{execution_status:I},...s.slashSkill&&{skill_name:s.slashSkill},...s.skillArtifacts?.length&&{skill_artifacts:s.skillArtifacts},...st!==void 0&&{user_instruction:st},latency_ms:Le,...h&&{tokens_input:h},...E&&{tokens_output:E},cost_usd:b,...s.model&&{model:s.model},toolCount:p,errorCount:l,stopReason:n,sessionId:s.sessionId,tools:m.length?m:void 0}),Kn=jn(ye(s.prompt,Oe.TRACE_INPUT)),Jn=me(f(T.TRACE_NAME,s.traceName),f(T.TRACE_INPUT,Kn),f(T.TRACE_OUTPUT,u),f(T.TRACE_METADATA,Hn),f(T.SESSION_ID,s.sessionId),f(T.USER_ID,r.user),f(T.OBS_TYPE,"GENERATION"),f(T.MODEL,s.model),h?f(T.INPUT_TOKENS,h):null,E?f(T.OUTPUT_TOKENS,E):null,f("claude.stop_reason",n),f("claude.tool_count",String(p)),f("claude.error_count",String(l)),f("claude.session_id",s.sessionId),f("flow.trace_type",pe),{key:T.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:pe}]}}}),zn={traceId:s.traceId,spanId:s.spanId,name:s.traceName,kind:1,startTimeUnixNano:s.startNs,endTimeUnixNano:o,attributes:Jn,status:{code:l>0?2:1}},Xn=me(f("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),f("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),rt=[...s.spans||[],zn];ue("Stop",`sid=${t}`,`totalTools=${p}`,`errorTools=${l}`,`spans=${rt.length}`,`inputTokens=${h}`,`outputTokens=${E}`,`traceOutput="${Yi(u,80)}"`);let Zn=await Di(Bi(Xn,rt));ue("Stop",`POST status=${Zn}`,`traceId=${s.traceId}`),Gn(t),nt(e);}Vn.exports={onStop:Hi};});var Wn=d(()=>{var{credentialsAvailable:Ki}=ne(),{readInput:Ji}=D(),{onUserPromptSubmit:zi}=Tn(),{onPreToolUse:Xi}=gn(),{onPostToolUse:Zi}=xn(),{onStop:Qi}=Yn();async function ea(){let e=process.argv[2];if(!await Ki()){let n=[];process.stdin.on("data",s=>n.push(s)),process.stdin.on("end",()=>process.stdout.write(n.join("")));return}let t=await Ji();switch(e){case "UserPromptSubmit":await zi(t);break;case "PreToolUse":await Xi(t);break;case "PostToolUse":await Zi(t);break;case "Stop":await Qi(t);break;default:process.stderr.write(`[flow-obs] unknown event: ${e}
92
- `),process.stdout.write(JSON.stringify(t));}}ea().catch(e=>{process.stderr.write(`[flow-obs] fatal: ${e.message}
93
- `),process.exit(0);});});var ta=new Set(["UserPromptSubmit","PreToolUse","PostToolUse","Stop"]),[,,A,le]=process.argv;if(A==="--version"||A==="-v"){let{version:e}=fe();process.stdout.write(e+`
94
- `),process.exit(0);}else if(A==="--help"||A==="-h"){let{bold:e,cyan:t,dim:n}=W(),{version:s}=fe();process.stdout.write(`
129
+ ${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${_}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(e,t)=>`${t}${_}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${_}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${_}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${_}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(e,t,n)=>`${t}${n}${_}${n}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(e,t)=>`${t}:${_}@`}];function ca(e){if(e==null)return "";let t=typeof e=="string"?e:JSON.stringify(e);return aa.reduce((n,{re:s,replace:r})=>n.replace(s,r),t)}Vn.exports={sanitize:ca,REDACTED:_};});var es=p((Sc,Qn)=>{var{generateSpanId:ua,nowNs:la}=ce(),{loadState:da,saveState:pa}=ue(),{LF:pe,a:$,attrs:fa}=it(),{truncate:Wn,firstLine:ha,passthrough:Jn}=K(),{readSkillContent:Sa,readSkillArtifacts:Ta}=Le(),{dbg:Xn}=C(),{TRACE_LIMITS:zn}=w(),{sanitize:Zn}=at();async function Ea(e){let t=e.session_id||"unknown",n=e.tool_name||"unknown",s=e.tool_input||{},r=e.tool_response||"",o=da(t);if(!o){Jn(e);return}let i=la(),a=o.pendingTool?.name===n,u=a?o.pendingTool.startNs:String(BigInt(i)-200000000n),d=a?o.pendingTool.inputStr:Wn(s,zn.TOOL_INPUT),l=d;if(n==="Skill"){let R=typeof s=="object"&&s!==null?s.skill||s.name||s.skillName||String(Object.values(s)[0]??""):String(s),k=R?Sa(R.trim(),o.cwd):null;k&&(l=k,o.skillContent||(o.skillContent=k),o.slashSkill||(o.slashSkill=R.trim()),o.skillArtifacts||(o.skillArtifacts=Ta(R.trim(),o.cwd))),Xn("PostToolUse","Skill tool detected",`skillName=${R}`,`contentFound=${!!k}`);}let h=Zn(Wn(r,zn.TOOL_OUTPUT)),T=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(h.slice(0,500)),O=T?"ERROR":"DEFAULT",I=ua(),Se=Math.round(Number(BigInt(i)-BigInt(u))/1e6),Ce={Agent:"AGENT",Task:"AGENT"}[n]??"TOOL";o.toolCalls.push({tool:n,brief:ha(d,60),error:T,durationMs:Se}),o.spans.push({traceId:o.traceId,spanId:I,parentSpanId:o.spanId,name:n,kind:3,startTimeUnixNano:u,endTimeUnixNano:i,attributes:fa($(pe.OBS_NAME,n),$(pe.OBS_TYPE,Ce),$(pe.OBS_LEVEL,O),$(pe.OBS_INPUT,Zn(l)),$(pe.OBS_OUTPUT,h),$("tool.name",n),$("tool.error",String(T))),status:{code:T?2:1}}),o.pendingTool=null,pa(t,o),Xn("PostToolUse",`sid=${t}`,`tool=${n}`,`error=${T}`,`durationMs=${Se}`,`totalSpans=${o.spans.length}`),Jn(e);}Qn.exports={onPostToolUse:Ea};});var ns=p((Tc,ts)=>{var ct={"claude-opus-4-6":{input:15,output:75},"claude-opus-4-5":{input:15,output:75},"claude-sonnet-4-6":{input:3,output:15},"claude-sonnet-4-5":{input:3,output:15},"claude-haiku-4-5":{input:.8,output:4},"claude-4-6-opus":{input:15,output:75},"claude-4-6-sonnet":{input:3,output:15},"claude-4-5-opus":{input:15,output:75},"claude-4-5-sonnet":{input:3,output:15},"claude-4-5-haiku":{input:.8,output:4},"claude-3-5-sonnet-20241022":{input:3,output:15},"claude-3-5-haiku-20241022":{input:.8,output:4},"claude-3-opus-20240229":{input:15,output:75}};function wa(e,t,n){let s=Object.keys(ct).find(i=>(e||"").toLowerCase().includes(i));if(!s)return;let r=ct[s],o=(t*r.input+n*r.output)/1e6;return Math.round(o*1e6)/1e6}ts.exports={MODEL_PRICING:ct,calcCostUsd:wa};});var as=p((Ec,is)=>{var{generateSpanId:ss,nowNs:ga}=ce(),{loadState:_a,deleteState:rs}=ue(),{LF:E,a:f,attrs:Ne,buildPayload:ma,postToLangfuse:ya}=it(),{getIdentityFromToken:Oa}=P(),{calcCostUsd:Aa}=ns(),{readLastAssistantOutput:La}=st(),{truncate:Ie,firstLine:Na,passthrough:ut}=K(),{dbg:fe}=C(),{detectExecutionStatus:Ia}=Le(),{sanitize:os}=at(),{TRACE_LIMITS:ke}=w();async function ka(e){let t=e.session_id||"unknown",n=e.stop_reason||"end_turn",s=_a(t);if(!s){ut(e);return}let r=ga(),o=await Oa();if(s.slashSkill&&!s.toolCalls.some(S=>S.tool==="Skill")){let S=ss(),J=s.skillContent?s.skillContent:JSON.stringify({skill:s.slashSkill});s.toolCalls.push({tool:"Skill",brief:s.slashSkill,error:false,durationMs:0,synthetic:true}),s.spans.push({traceId:s.traceId,spanId:S,parentSpanId:s.spanId,name:"Skill",kind:3,startTimeUnixNano:s.startNs,endTimeUnixNano:s.startNs,attributes:Ne(f(E.OBS_NAME,"Skill"),f(E.OBS_TYPE,"TOOL"),f(E.OBS_LEVEL,"DEFAULT"),f(E.OBS_INPUT,J),f(E.OBS_OUTPUT,"loaded via slash command"),f("tool.name","Skill"),f("tool.error","false"),f("skill.name",s.slashSkill),f("skill.invocation","slash-command")),status:{code:1}}),fe("Stop",`slashSkill=${s.slashSkill}`,"synthetic span injected");}let i=e.transcript_path||s.transcriptPath||"",a=La(i),u=s.toolCalls.length,d=s.toolCalls.filter(S=>S.error).length,l=os(a?.text?Ie(a.text,ke.TRACE_OUTPUT):u===0?"No tools used":s.toolCalls.map((S,J)=>`${J+1}. ${S.tool}${S.brief?` \u2192 ${S.brief}`:""}${S.error?" [ERROR]":""}`).join(`
130
+ `)),h=a?.inputTokens??0,T=a?.outputTokens??0,O=s.toolCalls.map((S,J)=>`${J+1}. ${S.tool}${S.brief?` \u2192 ${S.brief}`:""}${S.error?" [ERROR]":""} (${S.durationMs}ms)`),I=!!(s.slashSkill||s.toolCalls.some(S=>S.tool==="Skill")),Se=s.toolCalls.some(S=>S.tool==="Agent");if(!I&&!Se){fe("Stop",`sid=${t}`,"skipping trace \u2014 no Skill or Agent calls found"),rs(t),ut(e);return}let Te=I?"skill":"agent",Ce=Math.round(Number(BigInt(r)-BigInt(s.startNs))/1e6),R=Aa(s.model,h,T),k=Ia(s);k==="prerequisite_required"&&(s.spans.push({traceId:s.traceId,spanId:ss(),parentSpanId:s.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:s.startNs,endTimeUnixNano:r,attributes:Ne(f(E.OBS_NAME,"prerequisite-check"),f(E.OBS_TYPE,"EVENT"),f(E.OBS_LEVEL,"WARNING"),f(E.OBS_OUTPUT,l),f("skill.name",s.slashSkill||void 0),f("execution_status","prerequisite_required")),status:{code:1}}),fe("Stop",`sid=${t}`,"prerequisite-check span injected",`skill=${s.slashSkill}`));let lt=(()=>{if(!(!I||!s.prompt)){if(s.slashSkill){let S=s.prompt.replace(new RegExp(`^\\/${s.slashSkill}\\s*`,"i"),"").trim();return S?Ie(S,ke.USER_INSTRUCTION):void 0}return Ie(s.prompt,ke.USER_INSTRUCTION)||void 0}})(),us=JSON.stringify({trace_type:Te,...k!==null&&{execution_status:k},...s.slashSkill&&{skill_name:s.slashSkill},...s.skillArtifacts?.length&&{skill_artifacts:s.skillArtifacts},...lt!==void 0&&{user_instruction:lt},latency_ms:Ce,...h&&{tokens_input:h},...T&&{tokens_output:T},cost_usd:R,...s.model&&{model:s.model},toolCount:u,errorCount:d,stopReason:n,sessionId:s.sessionId,tools:O.length?O:void 0}),ls=os(Ie(s.prompt,ke.TRACE_INPUT)),ds=Ne(f(E.TRACE_NAME,s.traceName),f(E.TRACE_INPUT,ls),f(E.TRACE_OUTPUT,l),f(E.TRACE_METADATA,us),f(E.SESSION_ID,s.sessionId),f(E.USER_ID,o.user),f(E.OBS_TYPE,"GENERATION"),f(E.MODEL,s.model),h?f(E.INPUT_TOKENS,h):null,T?f(E.OUTPUT_TOKENS,T):null,f("claude.stop_reason",n),f("claude.tool_count",String(u)),f("claude.error_count",String(d)),f("claude.session_id",s.sessionId),f("flow.trace_type",Te),{key:E.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:Te}]}}}),ps={traceId:s.traceId,spanId:s.spanId,name:s.traceName,kind:1,startTimeUnixNano:s.startNs,endTimeUnixNano:r,attributes:ds,status:{code:d>0?2:1}},fs=Ne(f("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),f("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),dt=[...s.spans||[],ps];fe("Stop",`sid=${t}`,`totalTools=${u}`,`errorTools=${d}`,`spans=${dt.length}`,`inputTokens=${h}`,`outputTokens=${T}`,`traceOutput="${Na(l,80)}"`);let hs=await ya(ma(fs,dt));fe("Stop",`POST status=${hs}`,`traceId=${s.traceId}`),rs(t),ut(e);}is.exports={onStop:ka};});var cs=p(()=>{var{credentialsAvailable:Ca}=P(),{readInput:va}=K(),{onUserPromptSubmit:ba}=Rn(),{onPreToolUse:Ua}=$n(),{onPostToolUse:Ra}=es(),{onStop:Pa}=as();async function $a(){let e=process.argv[2];if(!await Ca()){let n=[];process.stdin.on("data",s=>n.push(s)),process.stdin.on("end",()=>process.stdout.write(n.join("")));return}let t=await va();switch(e){case "UserPromptSubmit":await ba(t);break;case "PreToolUse":await Ua(t);break;case "PostToolUse":await Ra(t);break;case "Stop":await Pa(t);break;default:process.stderr.write(`[flow-obs] unknown event: ${e}
131
+ `),process.stdout.write(JSON.stringify(t));}}$a().catch(e=>{process.stderr.write(`[flow-obs] fatal: ${e.message}
132
+ `),process.exit(0);});});var qa=new Set(["UserPromptSubmit","PreToolUse","PostToolUse","Stop"]),[,,N,he]=process.argv;if(N==="--version"||N==="-v"){let{version:e}=Ee();process.stdout.write(e+`
133
+ `),process.exit(0);}else if(N==="--help"||N==="-h"){let{bold:e,cyan:t,dim:n}=F(),{version:s}=Ee();process.stdout.write(`
95
134
  `+e(" flow-ai-obs")+n(" v"+s)+`
96
135
 
97
- `),process.stdout.write(t(" install")+n(` Register Claude Code hooks in ~/.claude/settings.json
136
+ `),process.stdout.write(t(" install")+n(` Auth (if needed) + hooks + native OTEL
137
+ `)),process.stdout.write(t(" setup")+n(` Full Flow wizard: auth + hooks + OTEL + LLM proxy + connectivity
98
138
  `)),process.stdout.write(t(" auth login")+n(` Authenticate with Flow (clientId / clientSecret / tenant)
99
139
  `)),process.stdout.write(t(" auth logout")+n(` Remove credentials
100
140
  `)),process.stdout.write(t(" auth status")+n(` Show current auth status
@@ -105,14 +145,16 @@ ${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${_}`},{re:/(aws_secret_ac
105
145
 
106
146
  `)),process.stdout.write(n(` (Hook events: UserPromptSubmit | PreToolUse | PostToolUse | Stop)
107
147
 
108
- `)),process.exit(0);}else if(A==="install"){ke().checkForUpdate();let{runInstall:e}=Bt();e().then(t=>process.exit(t)).catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
109
- `),process.exit(1);});}else if(A==="auth"){ke().checkForUpdate();let{runLogin:e,runLogout:t,runStatus:n}=Ht();(async()=>{let s=0;if(le==="login"||!le){let o=process.argv.slice(4),r=i=>{let a=o.indexOf(i);return a!==-1?o[a+1]:void 0};s=await e({clientId:r("--client-id"),clientSecret:r("--client-secret"),tenant:r("--tenant")});}else if(le==="logout"){let o=process.argv.includes("--force");s=await t(o);}else le==="status"?s=await n():(process.stderr.write(`Unknown auth subcommand: ${le}
148
+ `)),process.exit(0);}else if(N==="install"){we().checkForUpdate();let{runInstall:e}=et();e().then(t=>process.exit(t)).catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
149
+ `),process.exit(1);});}else if(N==="setup"){we().checkForUpdate();let{runSetup:e}=ln(),t=process.argv.slice(3),n=s=>{let r=t.indexOf(s);return r!==-1?t[r+1]:void 0};e({clientId:n("--client-id"),clientSecret:n("--client-secret"),tenant:n("--tenant")}).then(s=>process.exit(s)).catch(s=>{process.stderr.write(`Unexpected error: ${s.message}
150
+ `),process.exit(1);});}else if(N==="auth"){we().checkForUpdate();let{runLogin:e,runLogout:t,runStatus:n}=ie();(async()=>{let s=0;if(he==="login"||!he){let r=process.argv.slice(4),o=i=>{let a=r.indexOf(i);return a!==-1?r[a+1]:void 0};s=await e({clientId:o("--client-id"),clientSecret:o("--client-secret"),tenant:o("--tenant")});}else if(he==="logout"){let r=process.argv.includes("--force");s=await t(r);}else he==="status"?s=await n():(process.stderr.write(`Unknown auth subcommand: ${he}
110
151
  `),process.stderr.write(`Usage: flow-ai-obs auth [login|logout|status]
111
- `),s=1);process.exit(s);})();}else if(A==="otel-headers"){let{runOtelHeaders:e}=Jt();e().then(t=>process.exit(t)).catch(()=>process.exit(1));}else if(A==="check"){let{runCheck:e}=tn();e().then(t=>process.exit(t)).catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
112
- `),process.exit(1);});}else if(ta.has(A))Wn();else {let{bold:e,cyan:t,dim:n}=W();process.stdout.write(`
152
+ `),s=1);process.exit(s);})();}else if(N==="otel-headers"){let{runOtelHeaders:e}=pn();e().then(t=>process.exit(t)).catch(()=>process.exit(1));}else if(N==="check"){let{runCheck:e}=En();e().then(t=>process.exit(t)).catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
153
+ `),process.exit(1);});}else if(qa.has(N))cs();else {let{bold:e,cyan:t,dim:n}=F();process.stdout.write(`
113
154
  `+e(" flow-ai-obs")+`
114
155
 
115
- `),process.stdout.write(t(" install")+n(` Register Claude Code hooks in ~/.claude/settings.json
156
+ `),process.stdout.write(t(" install")+n(` Auth (if needed) + hooks + native OTEL
157
+ `)),process.stdout.write(t(" setup")+n(` Full Flow wizard: auth + hooks + OTEL + LLM proxy + connectivity
116
158
  `)),process.stdout.write(t(" auth login")+n(` Authenticate with Flow (clientId / clientSecret / tenant)
117
159
  `)),process.stdout.write(t(" auth logout")+n(` Remove credentials
118
160
  `)),process.stdout.write(t(" auth status")+n(` Show current auth status
package/dist/index.js CHANGED
@@ -1,13 +1,18 @@
1
- 'use strict';var c=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var f=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var h=f((Zs,kt)=>{var v=process.env.FLOW_BASE_URL||"https://flow.ciandt.com",Nt={AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${v}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${v}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${v}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${v}/otel`},Ze={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},Qe="FLOW-nodejs",tn="config.json",en={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},nn={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:Nt.OTEL_ENDPOINT,OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},rn={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP"},sn={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3},on={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},an={FILE_PREFIX:"flow-obs-buffer-",MAX_AGE_MS:5760*60*1e3,MAX_FILES:50},cn="flow-ai-obs-debug.log",un={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60},ln="flow-obs-";kt.exports={FLOW_BASE_URL:v,FLOW_URLS:Nt,VAULT:Ze,CONFIG_DIR_NAME:Qe,CONFIG_FILE_NAME:tn,OTLP:en,NATIVE_OTEL:nn,ENV:rn,INSTALLER:sn,HOOK_TIMEOUTS:on,BUFFER:an,DEBUG_LOG_FILENAME:cn,STATE_FILE_PREFIX:ln,TRACE_LIMITS:un};});var Rt=f((Qs,Ct)=>{var F=c("fs"),N=c("path"),dn=c("os"),{CONFIG_DIR_NAME:tt,CONFIG_FILE_NAME:et}=h(),nt={credentials:"credentials","token-cache":"tokenCache"};function q(){let t=dn.homedir();if(process.platform==="darwin")return N.join(t,"Library","Preferences",tt,et);if(process.platform==="win32"){let r=process.env.APPDATA||N.join(t,"AppData","Roaming");return N.join(r,tt,et)}let e=process.env.XDG_CONFIG_HOME||N.join(t,".config");return N.join(e,tt,et)}function rt(){try{let t=F.readFileSync(q(),"utf8");return JSON.parse(t)}catch{return {}}}function Ut(t){let e=q();F.mkdirSync(N.dirname(e),{recursive:true}),F.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var st=class{static isAvailable(){return true}static hasExistingData(){try{if(!F.existsSync(q()))return !1;let e=JSON.parse(F.readFileSync(q(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,r){let n=rt(),s=nt[r]||r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(e,r,n){let s=rt(),o=nt[r]||r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;Ut(s);}async deleteSecret(e,r){let n=rt(),s=nt[r]||r;return s in n?(delete n[s],Ut(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${q()}`}};function pn(){}Ct.exports={ScryptFallbackProvider:st,_resetWarningState:pn};});var $t=f((to,Pt)=>{var{VAULT:x}=h();async function fn(t,e){let r=[x.ACCOUNT_CREDS,x.ACCOUNT_TOKEN];for(let n of r)try{if(await e.getSecret(x.SERVICE,n)!==null)continue;let o=await t.getSecret(x.SERVICE,n);o!==null&&await e.setSecret(x.SERVICE,n,o);}catch{}}Pt.exports={migrateFromJsonFallback:fn};});var qt=f((eo,vt)=>{var{execFile:Sn,exec:_n}=c("child_process"),{promisify:bt}=c("util"),ot=bt(Sn),En=bt(_n),at=class{static async isAvailable(){try{return await En("command -v security"),!0}catch{return false}}async getSecret(e,r){try{let{stdout:n}=await ot("security",["find-generic-password","-w","-a",r,"-s",e]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await ot("security",["add-generic-password","-U","-a",r,"-s",e,"-w",n]);}async deleteSecret(e,r){try{return await ot("security",["delete-generic-password","-a",r,"-s",e]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};vt.exports={MacOsKeyVaultProvider:at};});var Dt=f((no,Bt)=>{var{execFile:Tn,exec:hn,spawn:gn}=c("child_process"),{promisify:xt}=c("util"),Ft=xt(Tn),yn=xt(hn),it=class{static async isAvailable(){try{return await yn("command -v secret-tool"),!0}catch{return false}}async getSecret(e,r){try{let{stdout:n}=await Ft("secret-tool",["lookup","service",e,"account",r]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await new Promise((s,o)=>{let a=gn("secret-tool",["store","--label",e,"service",e,"account",r]);a.on("error",o),a.on("close",u=>{u===0?s():o(new Error(`secret-tool exited with code ${u}`));}),a.stdin.write(n),a.stdin.end();});}async deleteSecret(e,r){try{return await Ft("secret-tool",["clear","service",e,"account",r]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};Bt.exports={LinuxKeyVaultProvider:it};});var Gt=f((ro,Mt)=>{var ct=class{static async isAvailable(){try{return await c("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(e,r){return c("keytar").getPassword(e,r)}async setSecret(e,r,n){await c("keytar").setPassword(e,r,n);}async deleteSecret(e,r){return c("keytar").deletePassword(e,r)}getStoragePath(){return "Windows Credential Manager"}};Mt.exports={WindowsKeyVaultProvider:ct};});var jt=f((so,Yt)=>{async function Vt(){let{ScryptFallbackProvider:t}=Rt();if(t.hasExistingData()){let e=await Wt();if(e){let{migrateFromJsonFallback:r}=$t(),{VAULT:n}=h();if(await r(new t,e),await e.getSecret(n.SERVICE,n.ACCOUNT_CREDS)!==null)return e}return new t}return await Wt()??new t}async function Wt(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=qt();return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=Dt();return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=Gt();return await t.isAvailable()?new t:null}default:return null}}var On=Vt;Yt.exports={createSecretVaultProvider:Vt,createKeyVaultProvider:On};});var Kt=f((oo,Jt)=>{var{createSecretVaultProvider:mn}=jt(),{VAULT:lt}=h(),k=lt.SERVICE,dt=lt.ACCOUNT_CREDS,pt=lt.ACCOUNT_TOKEN,ut=null;function U(){return ut||(ut=mn()),ut}async function Ht(){let e=await(await U()).getSecret(k,dt);if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function An(t){if(!t.clientId||!t.clientSecret||!t.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await U()).setSecret(k,dt,JSON.stringify(t));}async function wn(){let t=await U();await t.deleteSecret(k,dt),await t.deleteSecret(k,pt);}async function Ln(t){await(await U()).setSecret(k,pt,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt}));}async function ft(){let e=await(await U()).getSecret(k,pt);if(!e)return null;try{let r=JSON.parse(e);return {accessToken:r.accessToken,expiresAt:r.expiresAt}}catch{return null}}async function In(){let t=await ft();return t?new Date(t.expiresAt)>new Date:false}async function Nn(){let t=await ft();if(!t||!t.accessToken)return null;try{let e=t.accessToken.split(".");if(e.length<2)return null;let r=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return r.email||r.preferred_username||r.upn||r.sub||null}catch{return null}}async function kn(){let t=await U();if(typeof t.getStoragePath=="function")return t.getStoragePath();let e=process.platform;return e==="darwin"?"macOS Keychain":e==="win32"?"Windows Credential Manager":"Linux Secret Service (libsecret)"}async function Un(){let t=await Ht();return !!(t&&t.clientId&&t.clientSecret&&t.tenant)}Jt.exports={getFlowCredentials:Ht,saveFlowCredentials:An,clearFlowCredentials:wn,saveTokenCache:Ln,getTokenCache:ft,isTokenValid:In,getEmailFromToken:Nn,getConfigPath:kn,hasCredentials:Un};});var Zt=f((ao,Xt)=>{var Cn=c("https"),Rn=c("http"),{FLOW_URLS:Pn}=h(),$n=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function bn(t){if(!$n.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var zt={INVALID_CLIENT_SECRET:"Invalid Client Secret \u2014 check the value and try again",INVALID_CLIENT_ID:"Invalid Client ID \u2014 check the value and try again",INVALID_TENANT:"Invalid Tenant \u2014 check the value and try again",TENANT_NOT_FOUND:"Tenant not found \u2014 verify the tenant identifier"};function vn(t,e){try{let r=JSON.parse(e);if(typeof r.error=="string"&&zt[r.error])return new Error(zt[r.error])}catch{}return t===401||t===403||t===500?new Error("Invalid credentials"):t>=400&&t<500?new Error("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function qn(t){return new Promise((e,r)=>{try{bn(t.tenant);}catch(l){return r(l)}let n=JSON.stringify({clientSecret:t.clientSecret}),s=new URL(Pn.AUTH_ENGINE),o=s.protocol==="https:",a={hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname+s.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(n),FlowTenant:t.tenant}},p=(o?Cn:Rn).request(a,l=>{let d=[];l.on("data",S=>d.push(S)),l.on("end",()=>{let S=d.join("");if(l.statusCode>=400)return r(vn(l.statusCode,S));let E;try{E=JSON.parse(S);}catch{return r(new Error("Invalid response from auth engine"))}let y=E.expires_at??new Date(Date.now()+(E.expires_in??3600)*1e3).toISOString();e({accessToken:E.access_token,expiresAt:y});});});p.on("error",l=>r(new Error(`Network error: ${l.message}`))),p.write(n),p.end();})}Xt.exports={getToken:qn};});var m=f((io,te)=>{var{writeFileSync:Fn}=c("fs"),{tmpdir:xn}=c("os"),{join:Bn}=c("path"),{DEBUG_LOG_FILENAME:Dn,ENV:Mn}=h(),Qt=Bn(xn(),Dn);function Gn(...t){if(process.env[Mn.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
2
- `;try{Fn(Qt,e,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
3
- `);}}te.exports={dbg:Gn,DEBUG_LOG:Qt};});var J=f((co,ne)=>{var{getFlowCredentials:St,isTokenValid:Wn,getEmailFromToken:_t,getTokenCache:Vn,saveTokenCache:Yn}=Kt(),{getToken:jn}=Zt(),{FLOW_BASE_URL:Hn,ENV:L}=h(),{dbg:H}=m(),Jn=[/^localhost\.?$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/,/^::1$/,/^\[::1\]$/,/^\[::ffff:/i,/^\[f[cd]/i,/^\[fe80:/i,/^metadata\.google\.internal\.?$/i,/^metadata\.azure\.internal\.?$/i,/(?:^|\.)localtest\.me\.?$/i,/(?:^|\.)lvh\.me\.?$/i,/(?:^|\.)vcap\.me\.?$/i];function Kn(t){return Jn.some(e=>e.test(t))}function Et(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}if(!(process.env[L.FLOW_OBS_ALLOW_HTTP]==="true")&&e.protocol!=="https:")throw new Error(`URL must use HTTPS: ${t}`);if(e.username||e.password)throw new Error(`URL must not contain embedded credentials: ${t}`);if(Kn(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function zn(){try{let t=await St();if(!t)return {user:"",tenant:""};let e=await _t()||t.clientId||"",r=t.tenant||"";return {user:e,tenant:r}}catch{return {user:"",tenant:""}}}async function Xn(t){if(await Wn())return (await Vn()).accessToken;H("getOrRefreshToken","token expired \u2014 refreshing via auth-engine");let e=await jn(t);return await Yn(e),H("getOrRefreshToken",`token refreshed, expires=${e.expiresAt}`),e.accessToken}function Zn(t,e){let r=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/langfuse/traces",authHeader:`Bearer ${r}`}}function Qn(t,e,r){let n=Buffer.from(`${e}:${r}`).toString("base64");return {endpoint:t.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${n}`}}async function ee(){let t=[],e=process.env[L.ANTHROPIC_MODEL]||"",r=process.env[L.FLOW_TELEMETRY]==="true",n=process.env[L.LANGFUSE_BASE_URL],s=process.env[L.LANGFUSE_PUBLIC_KEY],o=process.env[L.LANGFUSE_SECRET_KEY];if(r&&n&&s&&o){let d="",S="";try{let y=await St();y&&(d=await _t()||y.clientId,S=y.tenant);}catch{}let E={user:d||"",tenant:S||"",team:"",project:"",model:e};t.push({mode:"direct",...Qn(Et(n),s,o),...E}),H("resolveCredentials","direct mode active",`user=${E.user}`,`tenant=${E.tenant}`);}let a=await St();if(!a){if(t.length===0){let d=[];return d.authError=false,d}return t}let u;try{u=await Xn(a);}catch(d){if(H("resolveCredentials",`token refresh failed: ${d.message}`),t.length>0)return t;let S=[];return S.authError=true,S}let p={user:await _t()||a.clientId,tenant:a.tenant,team:"",project:"",model:e},l=process.env[L.FLOW_TELEMETRY_GATEWAY]||Hn;return t.push({mode:"gateway",...Zn(Et(l),{accessToken:u}),...p}),t}async function tr(){return (await ee()).length>0}ne.exports={credentialsAvailable:tr,getIdentityFromToken:zn,resolveCredentials:ee,validateUrl:Et};});var C=f((uo,re)=>{function er(t,e){let r=typeof t=="object"?JSON.stringify(t):String(t??"");return r.length>e?r.slice(0,e)+" \u2026[truncated]":r}function nr(t,e=100){return String(t??"").split(`
4
- `)[0].slice(0,e).trim()}function rr(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",r=>e+=r),process.stdin.on("end",()=>{try{t(JSON.parse(e));}catch{t({});}});})}function sr(t){process.stdout.write(JSON.stringify(t));}re.exports={truncate:er,firstLine:nr,readInput:rr,passthrough:sr};});var B=f((lo,oe)=>{var{randomBytes:se}=c("crypto"),or=()=>se(16).toString("hex"),ar=()=>se(8).toString("hex");function ir(){return String(BigInt(Date.now())*1000000n)}oe.exports={generateTraceId:or,generateSpanId:ar,nowNs:ir};});var D=f((fo,ie)=>{var{readFileSync:cr,writeFileSync:ur,unlinkSync:lr,existsSync:dr,realpathSync:po}=c("fs"),{tmpdir:ae}=c("os"),{join:pr,resolve:fr,normalize:Sr,sep:_r}=c("path"),Er=/^[0-9a-f-]{1,64}$/i,Tr=Sr(ae())+_r;function hr(t,e){let r=fr(t);if(!r.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return r}function Tt(t){if(!Er.test(t))throw new Error(`Invalid session ID: ${t}`);return hr(pr(ae(),`flow-obs-${t}.json`),Tr)}function gr(t){let e=Tt(t);if(!dr(e))return null;try{return JSON.parse(cr(e,"utf8"))}catch{return null}}function yr(t,e){ur(Tt(t),JSON.stringify(e),"utf8");}function Or(t){try{lr(Tt(t));}catch{}}ie.exports={loadState:gr,saveState:yr,deleteState:Or};});var ht=f((So,le)=>{var{readFileSync:ce,existsSync:ue}=c("fs");function mr(t){if(!t||!ue(t))return null;try{let e=ce(t,"utf8").trimEnd().split(`
5
- `);for(let r=e.length-1;r>=0;r--)try{let n=JSON.parse(e[r]);if(n.type==="user"&&n.uuid)return n.uuid}catch{}}catch{}return null}function Ar(t){if(!t||!ue(t))return null;try{let e=ce(t,"utf8").trimEnd().split(`
6
- `),r=[],n=0,s=0,o=!1;for(let a=e.length-1;a>=0;a--)try{let u=JSON.parse(e[a]);if(u.type==="user"){if(o)break;continue}if(u.type==="assistant"){o=!0;let l=(u.message?.content??[]).filter(S=>S.type==="text").map(S=>S.text).join("");l&&r.unshift(l);let d=u.message?.usage??{};n+=(d.input_tokens??0)+(d.cache_read_input_tokens??0)+(d.cache_creation_input_tokens??0),s+=d.output_tokens??0;}}catch{}return !r.length&&n===0?null:{text:r.join(`
1
+ 'use strict';var c=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var _=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var h=_((eo,Re)=>{var k=process.env.FLOW_BASE_URL||"https://flow.ciandt.com",ke={AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${k}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${k}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${k}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${k}/otel`},Xt={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},Zt="FLOW-nodejs",Qt="config.json",en={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},tn={ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL||`${k}/flow-llm-proxy/`,ANTHROPIC_MODEL:process.env.FLOW_LLM_PROXY_MODEL||"anthropic.claude-4-6-sonnet",ANTHROPIC_SMALL_FAST_MODEL:process.env.FLOW_LLM_PROXY_SMALL_MODEL||"anthropic.claude-4-6-sonnet",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"},nn={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:ke.OTEL_ENDPOINT,OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},rn={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP"},sn={KEYCHAIN_ENABLED:false},on={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3},an={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},cn={FILE_PREFIX:"flow-obs-buffer-",MAX_AGE_MS:5760*60*1e3,MAX_FILES:50},ln="flow-ai-obs-debug.log",un={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60},dn="flow-obs-";Re.exports={FLOW_BASE_URL:k,FLOW_URLS:ke,VAULT:Xt,CONFIG_DIR_NAME:Zt,CONFIG_FILE_NAME:Qt,OTLP:en,LLM_PROXY:tn,NATIVE_OTEL:nn,ENV:rn,FEATURES:sn,INSTALLER:on,HOOK_TIMEOUTS:an,BUFFER:cn,DEBUG_LOG_FILENAME:ln,STATE_FILE_PREFIX:dn,TRACE_LIMITS:un};});var Pe=_((to,Ce)=>{var B=c("fs"),R=c("path"),pn=c("os"),{CONFIG_DIR_NAME:te,CONFIG_FILE_NAME:ne}=h(),re={credentials:"credentials","token-cache":"tokenCache"};function F(){let e=pn.homedir();if(process.platform==="darwin")return R.join(e,"Library","Preferences",te,ne);if(process.platform==="win32"){let r=process.env.APPDATA||R.join(e,"AppData","Roaming");return R.join(r,te,ne)}let t=process.env.XDG_CONFIG_HOME||R.join(e,".config");return R.join(t,te,ne)}function se(){try{let e=B.readFileSync(F(),"utf8");return JSON.parse(e)}catch{return {}}}function Ue(e){let t=F();B.mkdirSync(R.dirname(t),{recursive:true}),B.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var oe=class{static isAvailable(){return true}static hasExistingData(){try{if(!B.existsSync(F()))return !1;let t=JSON.parse(B.readFileSync(F(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,r){let n=se(),s=re[r]||r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,r,n){let s=se(),o=re[r]||r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;Ue(s);}async deleteSecret(t,r){let n=se(),s=re[r]||r;return s in n?(delete n[s],Ue(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${F()}`}};function fn(){}Ce.exports={ScryptFallbackProvider:oe,_resetWarningState:fn};});var $e=_((no,be)=>{var{execFile:_n,exec:Sn}=c("child_process"),{promisify:ve}=c("util"),ae=ve(_n),En=ve(Sn),ie=class{static async isAvailable(){try{return await En("command -v security"),!0}catch{return false}}async getSecret(t,r){try{let{stdout:n}=await ae("security",["find-generic-password","-w","-a",r,"-s",t]);return n.trim()||null}catch{return null}}async setSecret(t,r,n){await ae("security",["add-generic-password","-U","-a",r,"-s",t,"-w",n]);}async deleteSecret(t,r){try{return await ae("security",["delete-generic-password","-a",r,"-s",t]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};be.exports={MacOsKeyVaultProvider:ie};});var De=_((ro,Be)=>{var{execFile:Tn,exec:hn,spawn:On}=c("child_process"),{promisify:Fe}=c("util"),qe=Fe(Tn),gn=Fe(hn),ce=class{static async isAvailable(){try{return await gn("command -v secret-tool"),!0}catch{return false}}async getSecret(t,r){try{let{stdout:n}=await qe("secret-tool",["lookup","service",t,"account",r]);return n.trim()||null}catch{return null}}async setSecret(t,r,n){await new Promise((s,o)=>{let a=On("secret-tool",["store","--label",t,"service",t,"account",r]);a.on("error",o),a.on("close",l=>{l===0?s():o(new Error(`secret-tool exited with code ${l}`));}),a.stdin.write(n),a.stdin.end();});}async deleteSecret(t,r){try{return await qe("secret-tool",["clear","service",t,"account",r]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};Be.exports={LinuxKeyVaultProvider:ce};});var xe=_((so,Me)=>{var le=class{static async isAvailable(){try{return await c("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(t,r){return c("keytar").getPassword(t,r)}async setSecret(t,r,n){await c("keytar").setPassword(t,r,n);}async deleteSecret(t,r){return c("keytar").deletePassword(t,r)}getStoragePath(){return "Windows Credential Manager"}};Me.exports={WindowsKeyVaultProvider:le};});var We=_((oo,Ge)=>{async function He(){let{ScryptFallbackProvider:e}=Pe();return await An()??new e}async function An(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=$e();return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=De();return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=xe();return await e.isAvailable()?new e:null}default:return null}}var yn=He;Ge.exports={createSecretVaultProvider:He,createKeyVaultProvider:yn};});var Je=_((ao,Ke)=>{var{createSecretVaultProvider:mn}=We(),{VAULT:de}=h(),U=de.SERVICE,pe=de.ACCOUNT_CREDS,fe=de.ACCOUNT_TOKEN,ue=null;function C(){return ue||(ue=mn()),ue}async function Ye(){let t=await(await C()).getSecret(U,pe);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function Ln(e){if(!e.clientId||!e.clientSecret||!e.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await C()).setSecret(U,pe,JSON.stringify(e));}async function Nn(){let e=await C();await e.deleteSecret(U,pe),await e.deleteSecret(U,fe);}async function In(e){await(await C()).setSecret(U,fe,JSON.stringify({accessToken:e.accessToken,expiresAt:e.expiresAt}));}async function _e(){let t=await(await C()).getSecret(U,fe);if(!t)return null;try{let r=JSON.parse(t);return {accessToken:r.accessToken,expiresAt:r.expiresAt}}catch{return null}}async function wn(){let e=await _e();return e?new Date(e.expiresAt)>new Date:false}async function kn(){let e=await _e();if(!e||!e.accessToken)return null;try{let t=e.accessToken.split(".");if(t.length<2)return null;let r=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return r.email||r.preferred_username||r.upn||r.sub||null}catch{return null}}async function Rn(){let e=await C();if(typeof e.getStoragePath=="function")return e.getStoragePath();let t=process.platform;return t==="darwin"?"macOS Keychain":t==="win32"?"Windows Credential Manager":"Linux Secret Service (libsecret)"}async function Un(){let e=await Ye();return !!(e&&e.clientId&&e.clientSecret&&e.tenant)}Ke.exports={getFlowCredentials:Ye,saveFlowCredentials:Ln,clearFlowCredentials:Nn,saveTokenCache:In,getTokenCache:_e,isTokenValid:wn,getEmailFromToken:kn,getConfigPath:Rn,hasCredentials:Un};});var ze=_((io,je)=>{var Cn=c("https"),Pn=c("http"),{FLOW_URLS:vn}=h(),bn=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function $n(e){if(!bn.test(e))throw new Error(`Invalid tenant value: "${e}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var Ve={INVALID_CLIENT_SECRET:"Invalid Client Secret \u2014 check the value and try again",INVALID_CLIENT_ID:"Invalid Client ID \u2014 check the value and try again",INVALID_TENANT:"Invalid Tenant \u2014 check the value and try again",TENANT_NOT_FOUND:"Tenant not found \u2014 verify the tenant identifier"};function qn(e,t){try{let r=JSON.parse(t);if(typeof r.error=="string"&&Ve[r.error])return new Error(Ve[r.error])}catch{}return e===401||e===403||e===500?new Error("Invalid credentials"):e>=400&&e<500?new Error("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function Fn(e){return new Promise((t,r)=>{try{$n(e.tenant);}catch(u){return r(u)}let n=JSON.stringify({clientSecret:e.clientSecret}),s=new URL(vn.AUTH_ENGINE),o=s.protocol==="https:",a={hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname+s.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(n),FlowTenant:e.tenant}},p=(o?Cn:Pn).request(a,u=>{let d=[];u.on("data",f=>d.push(f)),u.on("end",()=>{let f=d.join("");if(u.statusCode>=400)return r(qn(u.statusCode,f));let E;try{E=JSON.parse(f);}catch{return r(new Error("Invalid response from auth engine"))}let g=E.expires_at??new Date(Date.now()+(E.expires_in??3600)*1e3).toISOString();t({accessToken:E.access_token,expiresAt:g});});});p.on("error",u=>r(new Error(`Network error: ${u.message}`))),p.write(n),p.end();})}je.exports={getToken:Fn};});var L=_((co,Ze)=>{var{writeFileSync:Bn}=c("fs"),{tmpdir:Dn}=c("os"),{join:Mn}=c("path"),{DEBUG_LOG_FILENAME:xn,ENV:Hn}=h(),Xe=Mn(Dn(),xn);function Gn(...e){if(process.env[Hn.FLOW_OBS_DEBUG]!=="1")return;let t=`[${new Date().toISOString()}] ${e.join(" ")}
2
+ `;try{Bn(Xe,t,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
3
+ `);}}Ze.exports={dbg:Gn,DEBUG_LOG:Xe};});var M=_((lo,et)=>{var{getFlowCredentials:Se,isTokenValid:Wn,getEmailFromToken:D,getTokenCache:Yn,saveTokenCache:Kn}=Je(),{getToken:Jn}=ze(),{FLOW_BASE_URL:Vn,ENV:A,FEATURES:Ee}=h(),{dbg:P}=L(),jn=[/^localhost\.?$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/,/^::1$/,/^\[::1\]$/,/^\[::ffff:/i,/^\[f[cd]/i,/^\[fe80:/i,/^metadata\.google\.internal\.?$/i,/^metadata\.azure\.internal\.?$/i,/(?:^|\.)localtest\.me\.?$/i,/(?:^|\.)lvh\.me\.?$/i,/(?:^|\.)vcap\.me\.?$/i];function zn(e){return jn.some(t=>t.test(e))}function j(e){if(!e)return null;try{let t=e.split(".");if(t.length<2)return null;let r=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:n,clientSecret:s,tenant:o}=r;return !n||!s||!o?null:{clientId:n,clientSecret:s,tenant:o}}catch{return null}}function Xn(e){let t=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),r=Buffer.from(JSON.stringify({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant})).toString("base64url");return `${t}.${r}.`}function Te(e){let t;try{t=new URL(e);}catch{throw new Error(`Invalid URL: ${e}`)}if(!(process.env[A.FLOW_OBS_ALLOW_HTTP]==="true")&&t.protocol!=="https:")throw new Error(`URL must use HTTPS: ${e}`);if(t.username||t.password)throw new Error(`URL must not contain embedded credentials: ${e}`);if(zn(t.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${t.hostname}`);return e}async function Zn(){let e=j(process.env[A.ANTHROPIC_AUTH_TOKEN]);if(e)return {user:await D().catch(()=>null)||e.clientId,tenant:e.tenant};if(Ee.KEYCHAIN_ENABLED)try{let t=await Se();if(!t)return {user:"",tenant:""};let r=await D()||t.clientId||"",n=t.tenant||"";return {user:r,tenant:n}}catch{return {user:"",tenant:""}}return {user:"",tenant:""}}async function Qn(e){if(await Wn())return (await Yn()).accessToken;P("getOrRefreshToken","token expired \u2014 refreshing via auth-engine");let t=await Jn(e);return await Kn(t),P("getOrRefreshToken",`token refreshed, expires=${t.expiresAt}`),t.accessToken}function er(e,t){let r=t&&t.accessToken?t.accessToken:"";return {endpoint:e.replace(/\/$/,"")+"/langfuse/traces",authHeader:`Bearer ${r}`}}function tr(e,t,r){let n=Buffer.from(`${t}:${r}`).toString("base64");return {endpoint:e.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${n}`}}async function Qe(){let e=[],t=process.env[A.ANTHROPIC_MODEL]||"",r=process.env[A.FLOW_TELEMETRY]==="true",n=process.env[A.LANGFUSE_BASE_URL],s=process.env[A.LANGFUSE_PUBLIC_KEY],o=process.env[A.LANGFUSE_SECRET_KEY];if(r&&n&&s&&o){let d="",f="",E=j(process.env[A.ANTHROPIC_AUTH_TOKEN]);if(E)d=await D().catch(()=>null)||E.clientId,f=E.tenant;else if(Ee.KEYCHAIN_ENABLED)try{let y=await Se();y&&(d=await D()||y.clientId,f=y.tenant);}catch{}let g={user:d||"",tenant:f||"",team:"",project:"",model:t};e.push({mode:"direct",...tr(Te(n),s,o),...g}),P("resolveCredentials","direct mode active",`user=${g.user}`,`tenant=${g.tenant}`);}let a=j(process.env[A.ANTHROPIC_AUTH_TOKEN]);if(P("resolveCredentials",a?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),!a&&Ee.KEYCHAIN_ENABLED&&(a=await Se(),a&&P("resolveCredentials","credentials resolved from keychain (FEATURES.KEYCHAIN_ENABLED=true)")),!a){if(e.length===0){let d=[];return d.authError=false,d}return e}let l;try{l=await Qn(a);}catch(d){if(P("resolveCredentials",`token refresh failed: ${d.message}`),e.length>0)return e;let f=[];return f.authError=true,f}let p={user:await D()||a.clientId,tenant:a.tenant,team:"",project:"",model:t},u=process.env[A.FLOW_TELEMETRY_GATEWAY]||Vn;return e.push({mode:"gateway",...er(Te(u),{accessToken:l}),...p}),e}async function nr(){return (await Qe()).length>0}et.exports={credentialsAvailable:nr,getIdentityFromToken:Zn,resolveCredentials:Qe,validateUrl:Te,parseCredsFromAnthropicToken:j,buildAnthropicAuthToken:Xn};});var v=_((uo,tt)=>{function rr(e,t){let r=typeof e=="object"?JSON.stringify(e):String(e??"");return r.length>t?r.slice(0,t)+" \u2026[truncated]":r}function sr(e,t=100){return String(e??"").split(`
4
+ `)[0].slice(0,t).trim()}function or(){return new Promise(e=>{let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",r=>t+=r),process.stdin.on("end",()=>{try{e(JSON.parse(t));}catch{e({});}});})}function ar(e){process.stdout.write(JSON.stringify(e));}tt.exports={truncate:rr,firstLine:sr,readInput:or,passthrough:ar};});var x=_((po,rt)=>{var{randomBytes:nt}=c("crypto"),ir=()=>nt(16).toString("hex"),cr=()=>nt(8).toString("hex");function lr(){return String(BigInt(Date.now())*1000000n)}rt.exports={generateTraceId:ir,generateSpanId:cr,nowNs:lr};});var H=_((_o,ot)=>{var{readFileSync:ur,writeFileSync:dr,unlinkSync:pr,existsSync:fr,realpathSync:fo}=c("fs"),{tmpdir:st}=c("os"),{join:_r,resolve:Sr,normalize:Er,sep:Tr}=c("path"),hr=/^[0-9a-f-]{1,64}$/i,Or=Er(st())+Tr;function gr(e,t){let r=Sr(e);if(!r.startsWith(t))throw new Error(`Path traversal detected: ${e}`);return r}function he(e){if(!hr.test(e))throw new Error(`Invalid session ID: ${e}`);return gr(_r(st(),`flow-obs-${e}.json`),Or)}function Ar(e){let t=he(e);if(!fr(t))return null;try{return JSON.parse(ur(t,"utf8"))}catch{return null}}function yr(e,t){dr(he(e),JSON.stringify(t),{encoding:"utf8",mode:384});}function mr(e){try{pr(he(e));}catch{}}ot.exports={loadState:Ar,saveState:yr,deleteState:mr};});var Oe=_((So,ct)=>{var{readFileSync:at,existsSync:it}=c("fs");function Lr(e){if(!e||!it(e))return null;try{let t=at(e,"utf8").trimEnd().split(`
5
+ `);for(let r=t.length-1;r>=0;r--)try{let n=JSON.parse(t[r]);if(n.type==="user"&&n.uuid)return n.uuid}catch{}}catch{}return null}function Nr(e){if(!e||!it(e))return null;try{let t=at(e,"utf8").trimEnd().split(`
6
+ `),r=[],n=0,s=0,o=!1;for(let a=t.length-1;a>=0;a--)try{let l=JSON.parse(t[a]);if(l.type==="user"){if(o)break;continue}if(l.type==="assistant"){o=!0;let u=(l.message?.content??[]).filter(f=>f.type==="text").map(f=>f.text).join("");u&&r.unshift(u);let d=l.message?.usage??{};n+=(d.input_tokens??0)+(d.cache_read_input_tokens??0)+(d.cache_creation_input_tokens??0),s+=d.output_tokens??0;}}catch{}return !r.length&&n===0?null:{text:r.join(`
7
7
 
8
- `),inputTokens:n,outputTokens:s}}catch{}return null}le.exports={readPromptUuid:mr,readLastAssistantOutput:Ar};});var K=f((_o,Se)=>{var{readFileSync:wr,existsSync:de,readdirSync:Lr}=c("fs"),{homedir:pe}=c("os"),{join:R,extname:Ir}=c("path"),Nr=new Set([".venv","__pycache__",".git","node_modules"]),kr=new Set([".pyc",".pyo"]),Ur=new Set(["SKILL.md",".DS_Store",".gitignore"]);function Cr(t,e){if(!t)return null;let r=[R(pe(),".claude","skills",t,"SKILL.md"),R(e||"",".claude","skills",t,"SKILL.md")];for(let n of r)if(de(n))try{return wr(n,"utf8")}catch{}return null}function Rr(t){return t.match(/^\/([a-z][a-z0-9-]*)(?:\s.*)?$/i)?.[1]||null}var fe=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function Pr(t){return !!t.slashSkill||t.toolCalls.some(n=>n.tool==="Skill")?t.toolCalls.some(n=>fe.has(n.tool))?"complete":"prerequisite_required":null}function $r(t,e){if(!t)return null;let r=[R(pe(),".claude","skills",t),R(e||"",".claude","skills",t)],n=null;for(let a of r)if(de(R(a,"SKILL.md"))){n=a;break}if(!n)return null;let s=[];function o(a,u){for(let p of Lr(a,{withFileTypes:true})){if(Nr.has(p.name)||Ur.has(p.name)||kr.has(Ir(p.name)))continue;let l=u?`${u}/${p.name}`:p.name;p.isDirectory()?o(R(a,p.name),l):s.push(l);}}return o(n,""),s.length>0?s:null}Se.exports={readSkillContent:Cr,readSkillArtifacts:$r,detectSlashSkill:Rr,EXECUTION_TOOLS:fe,detectExecutionStatus:Pr};});var Te=f((Eo,Ee)=>{var{generateTraceId:_e,generateSpanId:br,nowNs:vr}=B(),{saveState:qr}=D(),{readPromptUuid:Fr}=ht(),{detectSlashSkill:xr,readSkillContent:Br,readSkillArtifacts:Dr}=K(),{passthrough:Mr}=C(),{dbg:Gr}=m(),{ENV:Wr}=h();async function Vr(t){let e=t.session_id||"unknown",r=t.prompt||"",n=t.cwd||"",s=Fr(t.transcript_path)||_e(),o=xr(r),a=o?Br(o,n):null,u=o?Dr(o,n):null;qr(e,{traceId:_e(),spanId:br(),startNs:vr(),sessionId:e,prompt:r,cwd:n,traceName:s,transcriptPath:t.transcript_path||"",model:process.env[Wr.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:o,skillContent:a,skillArtifacts:u}),Gr("UserPromptSubmit",`sid=${e}`,`traceName=${s}`,`slashSkill=${o}`),Mr(t);}Ee.exports={onUserPromptSubmit:Vr};});var ge=f((To,he)=>{var{nowNs:Yr}=B(),{loadState:jr,saveState:Hr}=D(),{truncate:Jr,passthrough:Kr}=C(),{dbg:zr}=m(),{TRACE_LIMITS:Xr}=h();async function Zr(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=jr(e);s&&(s.pendingTool={name:r,inputStr:Jr(n,Xr.TOOL_INPUT),startNs:Yr()},Hr(e,s)),zr("PreToolUse",`sid=${e}`,`tool=${r}`,`stateFound=${!!s}`),Kr(t);}he.exports={onPreToolUse:Zr};});var me=f((ho,Oe)=>{var Qr=c("https"),ts=c("http"),{FLOW_URLS:es}=h();function ns(t){let e=new URL(t),r=new URL(es.GATEWAY_HEALTH);return r.hostname=e.hostname,r.port=e.port,r.protocol=e.protocol,r}function ye(t,e){return new Promise((r,n)=>{let o=(t._isSSL?Qr:ts).request(t,a=>{let u=[];a.on("data",p=>u.push(p)),a.on("end",()=>r({statusCode:a.statusCode,body:u.join("")}));});o.on("error",a=>n(new Error(`Network error: ${a.message}`))),e&&o.write(e),o.end();})}async function rs(t){let e;try{e=ns(t);}catch{return false}let r=e.protocol==="https:";try{let n=await ye({hostname:e.hostname,port:e.port||(r?443:80),path:e.pathname,method:"GET",_isSSL:r},null);return n.statusCode>=200&&n.statusCode<300}catch{return false}}async function ss(t,e,r){let n=JSON.stringify(t),s=new URL(e),o=s.protocol==="https:",a=String(r).replace(/[\r\n]/g,"");try{return (await ye({hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:a,"Content-Length":Buffer.byteLength(n)},_isSSL:o},n)).statusCode}catch{return 0}}Oe.exports={checkHealth:rs,sendTraces:ss};});var Ie=f((go,Le)=>{var A=c("fs"),gt=c("path"),Ae=c("os"),{BUFFER:M}=h(),{dbg:G}=m();function we(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return gt.join(Ae.tmpdir(),`${M.FILE_PREFIX}${t}.json`)}function yt(){let t=Ae.tmpdir(),e;try{e=A.readdirSync(t);}catch{return []}return e.filter(r=>r.startsWith(M.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=gt.join(t,r),s=0;try{s=A.statSync(n).mtimeMs;}catch{}return {full:n,mtime:s}}).sort((r,n)=>r.mtime-n.mtime).map(r=>r.full)}function os(t){try{let e=yt();if(e.length>=M.MAX_FILES){let s=e.slice(0,e.length-M.MAX_FILES+1);for(let o of s)try{A.unlinkSync(o);}catch{}}let r=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,n={fileId:r,bufferedAt:Date.now(),payload:t};return A.writeFileSync(we(r),JSON.stringify(n),"utf8"),G("buffer",`saved fileId=${r}`),r}catch(e){return G("buffer",`saveToBuffer failed: ${e.message}`),null}}function as(){let t=yt(),e=[];for(let r of t)try{let n=A.readFileSync(r,"utf8"),s=JSON.parse(n);s&&s.fileId&&s.payload&&e.push(s);}catch{G("buffer",`skipping malformed file: ${r}`);}return e}function is(t){try{A.unlinkSync(we(t)),G("buffer",`deleted fileId=${t}`);}catch{}}function cs(){let t=yt(),e=Date.now()-M.MAX_AGE_MS;for(let r of t)try{let{mtimeMs:n}=A.statSync(r);n<e&&(A.unlinkSync(r),G("buffer",`evicted stale: ${gt.basename(r)}`));}catch{}}Le.exports={saveToBuffer:os,loadBuffer:as,deleteBuffer:is,cleanStaleBuffers:cs};});var Ot=f((yo,Ce)=>{var{resolveCredentials:us}=J(),{OTLP:Ne}=h(),{dbg:P}=m(),{checkHealth:ls,sendTraces:Ue}=me(),{saveToBuffer:ke,loadBuffer:ds,deleteBuffer:ps,cleanStaleBuffers:fs}=Ie(),Ss={name:Ne.SCOPE_NAME,version:Ne.SCOPE_VERSION},_s={TRACE_NAME:"langfuse.trace.name",TRACE_INPUT:"langfuse.trace.input",TRACE_OUTPUT:"langfuse.trace.output",TRACE_METADATA:"langfuse.trace.metadata",TRACE_TAGS:"langfuse.trace.tags",USER_ID:"langfuse.user.id",SESSION_ID:"langfuse.session.id",OBS_NAME:"langfuse.observation.name",OBS_INPUT:"langfuse.observation.input",OBS_OUTPUT:"langfuse.observation.output",OBS_LEVEL:"langfuse.observation.level",OBS_TYPE:"langfuse.observation.type",MODEL:"gen_ai.request.model",INPUT_TOKENS:"gen_ai.usage.input_tokens",OUTPUT_TOKENS:"gen_ai.usage.output_tokens"};function Es(t,e){return e==null||e===""?null:{key:t,value:{stringValue:String(e)}}}function Ts(...t){return t.filter(Boolean)}function hs(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:Ss,spans:Array.isArray(e)?e:[e]}]}]}}function gs(t,e){return new Promise(r=>{let n=JSON.stringify(t),s=new URL(e.endpoint),o=s.protocol==="https:",a=d=>String(d).replace(/[\r\n]/g,""),u={hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:a(e.authHeader),"Content-Length":Buffer.byteLength(n)}},l=(o?c("https"):c("http")).request(u,d=>{d.resume(),r(d.statusCode);});l.on("error",()=>r(0)),l.write(n),l.end();})}async function ys(t){fs();let e=ds();if(e.length){P("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`);for(let r of e)try{let n=await Ue(r.payload,t.endpoint,t.authHeader);n>=200&&n<300?(ps(r.fileId),P("replayBufferedTraces",`replayed fileId=${r.fileId} status=${n}`)):P("replayBufferedTraces",`replay failed fileId=${r.fileId} status=${n}`);}catch(n){P("replayBufferedTraces",`replay error fileId=${r.fileId}: ${n.message}`);}}}async function Os(t){let e=await us();return e.length?(await Promise.all(e.map(async n=>n.mode==="gateway"?await ls(n.endpoint)?(await ys(n),Ue(t,n.endpoint,n.authHeader)):(P("postToLangfuse","gateway health check failed \u2014 buffering trace"),ke(t),0):gs(t,n)))).find(n=>n!==0)||0:(e.authError&&(P("postToLangfuse","auth refresh failed \u2014 buffering trace"),ke(t)),0)}Ce.exports={LF:_s,a:Es,attrs:Ts,buildPayload:hs,postToLangfuse:Os};});var mt=f((Oo,Re)=>{var g="[REDACTED]",ms=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${g}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${g}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${g}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${g}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,r)=>`${e}
9
- ${g}
10
- ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${g}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${g}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${g}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${g}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${g}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(t,e,r)=>`${e}${r}${g}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${g}@`}];function As(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return ms.reduce((r,{re:n,replace:s})=>r.replace(n,s),e)}Re.exports={sanitize:As,REDACTED:g};});var xe=f((mo,Fe)=>{var{generateSpanId:ws,nowNs:Ls}=B(),{loadState:Is,saveState:Ns}=D(),{LF:W,a:I,attrs:ks}=Ot(),{truncate:Pe,firstLine:Us,passthrough:$e}=C(),{readSkillContent:Cs,readSkillArtifacts:Rs}=K(),{dbg:be}=m(),{TRACE_LIMITS:ve}=h(),{sanitize:qe}=mt();async function Ps(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=t.tool_response||"",o=Is(e);if(!o){$e(t);return}let a=Ls(),u=o.pendingTool?.name===r,p=u?o.pendingTool.startNs:String(BigInt(a)-200000000n),l=u?o.pendingTool.inputStr:Pe(n,ve.TOOL_INPUT),d=l;if(r==="Skill"){let w=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||String(Object.values(n)[0]??""):String(n),O=w?Cs(w.trim(),o.cwd):null;O&&(d=O,o.skillContent||(o.skillContent=O),o.slashSkill||(o.slashSkill=w.trim()),o.skillArtifacts||(o.skillArtifacts=Rs(w.trim(),o.cwd))),be("PostToolUse","Skill tool detected",`skillName=${w}`,`contentFound=${!!O}`);}let S=qe(Pe(s,ve.TOOL_OUTPUT)),E=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(S.slice(0,500)),y=E?"ERROR":"DEFAULT",$=ws(),Y=Math.round(Number(BigInt(a)-BigInt(p))/1e6),Q={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL";o.toolCalls.push({tool:r,brief:Us(l,60),error:E,durationMs:Y}),o.spans.push({traceId:o.traceId,spanId:$,parentSpanId:o.spanId,name:r,kind:3,startTimeUnixNano:p,endTimeUnixNano:a,attributes:ks(I(W.OBS_NAME,r),I(W.OBS_TYPE,Q),I(W.OBS_LEVEL,y),I(W.OBS_INPUT,qe(d)),I(W.OBS_OUTPUT,S),I("tool.name",r),I("tool.error",String(E))),status:{code:E?2:1}}),o.pendingTool=null,Ns(e,o),be("PostToolUse",`sid=${e}`,`tool=${r}`,`error=${E}`,`durationMs=${Y}`,`totalSpans=${o.spans.length}`),$e(t);}Fe.exports={onPostToolUse:Ps};});var De=f((Ao,Be)=>{var At={"claude-opus-4-6":{input:15,output:75},"claude-opus-4-5":{input:15,output:75},"claude-sonnet-4-6":{input:3,output:15},"claude-sonnet-4-5":{input:3,output:15},"claude-haiku-4-5":{input:.8,output:4},"claude-4-6-opus":{input:15,output:75},"claude-4-6-sonnet":{input:3,output:15},"claude-4-5-opus":{input:15,output:75},"claude-4-5-sonnet":{input:3,output:15},"claude-4-5-haiku":{input:.8,output:4},"claude-3-5-sonnet-20241022":{input:3,output:15},"claude-3-5-haiku-20241022":{input:.8,output:4},"claude-3-opus-20240229":{input:15,output:75}};function $s(t,e,r){let n=Object.keys(At).find(a=>(t||"").toLowerCase().includes(a));if(!n)return;let s=At[n],o=(e*s.input+r*s.output)/1e6;return Math.round(o*1e6)/1e6}Be.exports={MODEL_PRICING:At,calcCostUsd:$s};});var Ye=f((wo,Ve)=>{var{generateSpanId:Me,nowNs:bs}=B(),{loadState:vs,deleteState:Ge}=D(),{LF:T,a:i,attrs:z,buildPayload:qs,postToLangfuse:Fs}=Ot(),{getIdentityFromToken:xs}=J(),{calcCostUsd:Bs}=De(),{readLastAssistantOutput:Ds}=ht(),{truncate:X,firstLine:Ms,passthrough:wt}=C(),{dbg:V}=m(),{detectExecutionStatus:Gs}=K(),{sanitize:We}=mt(),{TRACE_LIMITS:Z}=h();async function Ws(t){let e=t.session_id||"unknown",r=t.stop_reason||"end_turn",n=vs(e);if(!n){wt(t);return}let s=bs(),o=await xs();if(n.slashSkill&&!n.toolCalls.some(_=>_.tool==="Skill")){let _=Me(),b=n.skillContent?n.skillContent:JSON.stringify({skill:n.slashSkill});n.toolCalls.push({tool:"Skill",brief:n.slashSkill,error:false,durationMs:0,synthetic:true}),n.spans.push({traceId:n.traceId,spanId:_,parentSpanId:n.spanId,name:"Skill",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:n.startNs,attributes:z(i(T.OBS_NAME,"Skill"),i(T.OBS_TYPE,"TOOL"),i(T.OBS_LEVEL,"DEFAULT"),i(T.OBS_INPUT,b),i(T.OBS_OUTPUT,"loaded via slash command"),i("tool.name","Skill"),i("tool.error","false"),i("skill.name",n.slashSkill),i("skill.invocation","slash-command")),status:{code:1}}),V("Stop",`slashSkill=${n.slashSkill}`,"synthetic span injected");}let a=t.transcript_path||n.transcriptPath||"",u=Ds(a),p=n.toolCalls.length,l=n.toolCalls.filter(_=>_.error).length,d=We(u?.text?X(u.text,Z.TRACE_OUTPUT):p===0?"No tools used":n.toolCalls.map((_,b)=>`${b+1}. ${_.tool}${_.brief?` \u2192 ${_.brief}`:""}${_.error?" [ERROR]":""}`).join(`
11
- `)),S=u?.inputTokens??0,E=u?.outputTokens??0,y=n.toolCalls.map((_,b)=>`${b+1}. ${_.tool}${_.brief?` \u2192 ${_.brief}`:""}${_.error?" [ERROR]":""} (${_.durationMs}ms)`),$=!!(n.slashSkill||n.toolCalls.some(_=>_.tool==="Skill")),Y=n.toolCalls.some(_=>_.tool==="Agent");if(!$&&!Y){V("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),Ge(e),wt(t);return}let j=$?"skill":"agent",Q=Math.round(Number(BigInt(s)-BigInt(n.startNs))/1e6),w=Bs(n.model,S,E),O=Gs(n);O==="prerequisite_required"&&(n.spans.push({traceId:n.traceId,spanId:Me(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:z(i(T.OBS_NAME,"prerequisite-check"),i(T.OBS_TYPE,"EVENT"),i(T.OBS_LEVEL,"WARNING"),i(T.OBS_OUTPUT,d),i("skill.name",n.slashSkill||void 0),i("execution_status","prerequisite_required")),status:{code:1}}),V("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${n.slashSkill}`));let Lt=(()=>{if(!(!$||!n.prompt)){if(n.slashSkill){let _=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return _?X(_,Z.USER_INSTRUCTION):void 0}return X(n.prompt,Z.USER_INSTRUCTION)||void 0}})(),je=JSON.stringify({trace_type:j,...O!==null&&{execution_status:O},...n.slashSkill&&{skill_name:n.slashSkill},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...Lt!==void 0&&{user_instruction:Lt},latency_ms:Q,...S&&{tokens_input:S},...E&&{tokens_output:E},cost_usd:w,...n.model&&{model:n.model},toolCount:p,errorCount:l,stopReason:r,sessionId:n.sessionId,tools:y.length?y:void 0}),He=We(X(n.prompt,Z.TRACE_INPUT)),Je=z(i(T.TRACE_NAME,n.traceName),i(T.TRACE_INPUT,He),i(T.TRACE_OUTPUT,d),i(T.TRACE_METADATA,je),i(T.SESSION_ID,n.sessionId),i(T.USER_ID,o.user),i(T.OBS_TYPE,"GENERATION"),i(T.MODEL,n.model),S?i(T.INPUT_TOKENS,S):null,E?i(T.OUTPUT_TOKENS,E):null,i("claude.stop_reason",r),i("claude.tool_count",String(p)),i("claude.error_count",String(l)),i("claude.session_id",n.sessionId),i("flow.trace_type",j),{key:T.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:j}]}}}),Ke={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:Je,status:{code:l>0?2:1}},ze=z(i("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),i("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),It=[...n.spans||[],Ke];V("Stop",`sid=${e}`,`totalTools=${p}`,`errorTools=${l}`,`spans=${It.length}`,`inputTokens=${S}`,`outputTokens=${E}`,`traceOutput="${Ms(d,80)}"`);let Xe=await Fs(qs(ze,It));V("Stop",`POST status=${Xe}`,`traceId=${n.traceId}`),Ge(e),wt(t);}Ve.exports={onStop:Ws};});var{credentialsAvailable:Vs}=J(),{readInput:Ys}=C(),{onUserPromptSubmit:js}=Te(),{onPreToolUse:Hs}=ge(),{onPostToolUse:Js}=xe(),{onStop:Ks}=Ye();async function zs(){let t=process.argv[2];if(!await Vs()){let r=[];process.stdin.on("data",n=>r.push(n)),process.stdin.on("end",()=>process.stdout.write(r.join("")));return}let e=await Ys();switch(t){case "UserPromptSubmit":await js(e);break;case "PreToolUse":await Hs(e);break;case "PostToolUse":await Js(e);break;case "Stop":await Ks(e);break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
12
- `),process.stdout.write(JSON.stringify(e));}}zs().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
8
+ `),inputTokens:n,outputTokens:s}}catch{}return null}ct.exports={readPromptUuid:Lr,readLastAssistantOutput:Nr};});var z=_((Eo,pt)=>{var{readFileSync:Ir,existsSync:lt,readdirSync:wr}=c("fs"),{homedir:ut}=c("os"),{join:b,extname:kr}=c("path"),Rr=new Set([".venv","__pycache__",".git","node_modules"]),Ur=new Set([".pyc",".pyo"]),Cr=new Set(["SKILL.md",".DS_Store",".gitignore"]);function Pr(e,t){if(!e)return null;let r=[b(ut(),".claude","skills",e,"SKILL.md"),b(t||"",".claude","skills",e,"SKILL.md")];for(let n of r)if(lt(n))try{return Ir(n,"utf8")}catch{}return null}function vr(e){return e.match(/^\/([a-z][a-z0-9-]*)(?:\s.*)?$/i)?.[1]||null}var dt=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function br(e){return !!e.slashSkill||e.toolCalls.some(n=>n.tool==="Skill")?e.toolCalls.some(n=>dt.has(n.tool))?"complete":"prerequisite_required":null}function $r(e,t){if(!e)return null;let r=[b(ut(),".claude","skills",e),b(t||"",".claude","skills",e)],n=null;for(let a of r)if(lt(b(a,"SKILL.md"))){n=a;break}if(!n)return null;let s=[];function o(a,l){for(let p of wr(a,{withFileTypes:true})){if(Rr.has(p.name)||Cr.has(p.name)||Ur.has(kr(p.name)))continue;let u=l?`${l}/${p.name}`:p.name;p.isDirectory()?o(b(a,p.name),u):s.push(u);}}return o(n,""),s.length>0?s:null}pt.exports={readSkillContent:Pr,readSkillArtifacts:$r,detectSlashSkill:vr,EXECUTION_TOOLS:dt,detectExecutionStatus:br};});var Et=_((To,St)=>{var{generateTraceId:ft,generateSpanId:qr,nowNs:Fr}=x(),{saveState:Br}=H(),{readPromptUuid:Dr}=Oe(),{detectSlashSkill:Mr,readSkillContent:xr,readSkillArtifacts:Hr}=z(),{passthrough:Gr}=v(),{dbg:_t}=L(),{ENV:Wr}=h(),{resolveCredentials:Yr}=M();async function Kr(e){let t=e.session_id||"unknown",r=e.prompt||"",n=e.cwd||"";try{(await Yr()).authError===!0&&(process.stderr.write(`
9
+ \u26A0 flow-ai-obs: Your Flow credentials have expired.
10
+ Traces will not be captured until you re-authenticate.
11
+ Run: flow-ai-obs auth login
12
+
13
+ `),_t("UserPromptSubmit","auth expired \u2014 warning emitted to stderr"));}catch{}let s=Dr(e.transcript_path)||ft(),o=Mr(r),a=o?xr(o,n):null,l=o?Hr(o,n):null;Br(t,{traceId:ft(),spanId:qr(),startNs:Fr(),sessionId:t,prompt:r,cwd:n,traceName:s,transcriptPath:e.transcript_path||"",model:process.env[Wr.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:o,skillContent:a,skillArtifacts:l}),_t("UserPromptSubmit",`sid=${t}`,`traceName=${s}`,`slashSkill=${o}`),Gr(e);}St.exports={onUserPromptSubmit:Kr};});var ht=_((ho,Tt)=>{var{nowNs:Jr}=x(),{loadState:Vr,saveState:jr}=H(),{truncate:zr,passthrough:Xr}=v(),{dbg:Zr}=L(),{TRACE_LIMITS:Qr}=h();async function es(e){let t=e.session_id||"unknown",r=e.tool_name||"unknown",n=e.tool_input||{},s=Vr(t);s&&(s.pendingTool={name:r,inputStr:zr(n,Qr.TOOL_INPUT),startNs:Jr()},jr(t,s)),Zr("PreToolUse",`sid=${t}`,`tool=${r}`,`stateFound=${!!s}`),Xr(e);}Tt.exports={onPreToolUse:es};});var At=_((Oo,gt)=>{var ts=c("https"),ns=c("http"),{FLOW_URLS:rs}=h();function ss(e){let t=new URL(e),r=new URL(rs.GATEWAY_HEALTH);return r.hostname=t.hostname,r.port=t.port,r.protocol=t.protocol,r}function Ot(e,t){return new Promise((r,n)=>{let o=(e._isSSL?ts:ns).request(e,a=>{let l=[];a.on("data",p=>l.push(p)),a.on("end",()=>r({statusCode:a.statusCode,body:l.join("")}));});o.on("error",a=>n(new Error(`Network error: ${a.message}`))),t&&o.write(t),o.end();})}async function os(e){let t;try{t=ss(e);}catch{return false}let r=t.protocol==="https:";try{let n=await Ot({hostname:t.hostname,port:t.port||(r?443:80),path:t.pathname,method:"GET",_isSSL:r},null);return n.statusCode>=200&&n.statusCode<300}catch{return false}}async function as(e,t,r){let n=JSON.stringify(e),s=new URL(t),o=s.protocol==="https:",a=String(r).replace(/[\r\n]/g,"");try{return (await Ot({hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:a,"Content-Length":Buffer.byteLength(n)},_isSSL:o},n)).statusCode}catch{return 0}}gt.exports={checkHealth:os,sendTraces:as};});var Nt=_((go,Lt)=>{var N=c("fs"),ge=c("path"),yt=c("os"),{BUFFER:G}=h(),{dbg:W}=L();function mt(e){if(/[/\\]/.test(e))throw new Error(`Invalid buffer fileId: ${e}`);return ge.join(yt.tmpdir(),`${G.FILE_PREFIX}${e}.json`)}function Ae(){let e=yt.tmpdir(),t;try{t=N.readdirSync(e);}catch{return []}return t.filter(r=>r.startsWith(G.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=ge.join(e,r),s=0;try{s=N.statSync(n).mtimeMs;}catch{}return {full:n,mtime:s}}).sort((r,n)=>r.mtime-n.mtime).map(r=>r.full)}function is(e){try{let t=Ae();if(t.length>=G.MAX_FILES){let s=t.slice(0,t.length-G.MAX_FILES+1);for(let o of s)try{N.unlinkSync(o);}catch{}}let r=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,n={fileId:r,bufferedAt:Date.now(),payload:e};return N.writeFileSync(mt(r),JSON.stringify(n),{encoding:"utf8",mode:384}),W("buffer",`saved fileId=${r}`),r}catch(t){return W("buffer",`saveToBuffer failed: ${t.message}`),null}}function cs(){let e=Ae(),t=[];for(let r of e)try{let n=N.readFileSync(r,"utf8"),s=JSON.parse(n);s&&s.fileId&&s.payload&&t.push(s);}catch{W("buffer",`skipping malformed file: ${r}`);}return t}function ls(e){try{N.unlinkSync(mt(e)),W("buffer",`deleted fileId=${e}`);}catch{}}function us(){let e=Ae(),t=Date.now()-G.MAX_AGE_MS;for(let r of e)try{let{mtimeMs:n}=N.statSync(r);n<t&&(N.unlinkSync(r),W("buffer",`evicted stale: ${ge.basename(r)}`));}catch{}}Lt.exports={saveToBuffer:is,loadBuffer:cs,deleteBuffer:ls,cleanStaleBuffers:us};});var ye=_((Ao,Rt)=>{var{resolveCredentials:ds}=M(),{OTLP:It}=h(),{dbg:$}=L(),{checkHealth:ps,sendTraces:kt}=At(),{saveToBuffer:wt,loadBuffer:fs,deleteBuffer:_s,cleanStaleBuffers:Ss}=Nt(),Es={name:It.SCOPE_NAME,version:It.SCOPE_VERSION},Ts={TRACE_NAME:"langfuse.trace.name",TRACE_INPUT:"langfuse.trace.input",TRACE_OUTPUT:"langfuse.trace.output",TRACE_METADATA:"langfuse.trace.metadata",TRACE_TAGS:"langfuse.trace.tags",USER_ID:"langfuse.user.id",SESSION_ID:"langfuse.session.id",OBS_NAME:"langfuse.observation.name",OBS_INPUT:"langfuse.observation.input",OBS_OUTPUT:"langfuse.observation.output",OBS_LEVEL:"langfuse.observation.level",OBS_TYPE:"langfuse.observation.type",MODEL:"gen_ai.request.model",INPUT_TOKENS:"gen_ai.usage.input_tokens",OUTPUT_TOKENS:"gen_ai.usage.output_tokens"};function hs(e,t){return t==null||t===""?null:{key:e,value:{stringValue:String(t)}}}function Os(...e){return e.filter(Boolean)}function gs(e,t){return {resourceSpans:[{resource:{attributes:e},scopeSpans:[{scope:Es,spans:Array.isArray(t)?t:[t]}]}]}}function As(e,t){return new Promise(r=>{let n=JSON.stringify(e),s=new URL(t.endpoint),o=s.protocol==="https:",a=d=>String(d).replace(/[\r\n]/g,""),l={hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:a(t.authHeader),"Content-Length":Buffer.byteLength(n)}},u=(o?c("https"):c("http")).request(l,d=>{d.resume(),r(d.statusCode);});u.on("error",()=>r(0)),u.write(n),u.end();})}async function ys(e){Ss();let t=fs();if(t.length){$("replayBufferedTraces",`replaying ${t.length} buffered trace(s)`);for(let r of t)try{let n=await kt(r.payload,e.endpoint,e.authHeader);n>=200&&n<300?(_s(r.fileId),$("replayBufferedTraces",`replayed fileId=${r.fileId} status=${n}`)):$("replayBufferedTraces",`replay failed fileId=${r.fileId} status=${n}`);}catch(n){$("replayBufferedTraces",`replay error fileId=${r.fileId}: ${n.message}`);}}}async function ms(e){let t=await ds();return t.length?(await Promise.all(t.map(async n=>n.mode==="gateway"?await ps(n.endpoint)?(await ys(n),kt(e,n.endpoint,n.authHeader)):($("postToLangfuse","gateway health check failed \u2014 buffering trace"),wt(e),0):As(e,n)))).find(n=>n!==0)||0:(t.authError&&($("postToLangfuse","auth refresh failed \u2014 buffering trace"),wt(e)),0)}Rt.exports={LF:Ts,a:hs,attrs:Os,buildPayload:gs,postToLangfuse:ms};});var me=_((yo,Ut)=>{var O="[REDACTED]",Ls=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${O}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${O}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(e,t)=>`${t}${O}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(e,t)=>`${t}${O}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(e,t,r)=>`${t}
14
+ ${O}
15
+ ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${O}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(e,t)=>`${t}${O}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${O}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${O}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${O}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(e,t,r)=>`${t}${r}${O}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(e,t)=>`${t}:${O}@`}];function Ns(e){if(e==null)return "";let t=typeof e=="string"?e:JSON.stringify(e);return Ls.reduce((r,{re:n,replace:s})=>r.replace(n,s),t)}Ut.exports={sanitize:Ns,REDACTED:O};});var Ft=_((mo,qt)=>{var{generateSpanId:Is,nowNs:ws}=x(),{loadState:ks,saveState:Rs}=H(),{LF:Y,a:w,attrs:Us}=ye(),{truncate:Ct,firstLine:Cs,passthrough:Pt}=v(),{readSkillContent:Ps,readSkillArtifacts:vs}=z(),{dbg:vt}=L(),{TRACE_LIMITS:bt}=h(),{sanitize:$t}=me();async function bs(e){let t=e.session_id||"unknown",r=e.tool_name||"unknown",n=e.tool_input||{},s=e.tool_response||"",o=ks(t);if(!o){Pt(e);return}let a=ws(),l=o.pendingTool?.name===r,p=l?o.pendingTool.startNs:String(BigInt(a)-200000000n),u=l?o.pendingTool.inputStr:Ct(n,bt.TOOL_INPUT),d=u;if(r==="Skill"){let I=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||String(Object.values(n)[0]??""):String(n),m=I?Ps(I.trim(),o.cwd):null;m&&(d=m,o.skillContent||(o.skillContent=m),o.slashSkill||(o.slashSkill=I.trim()),o.skillArtifacts||(o.skillArtifacts=vs(I.trim(),o.cwd))),vt("PostToolUse","Skill tool detected",`skillName=${I}`,`contentFound=${!!m}`);}let f=$t(Ct(s,bt.TOOL_OUTPUT)),E=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(f.slice(0,500)),g=E?"ERROR":"DEFAULT",y=Is(),J=Math.round(Number(BigInt(a)-BigInt(p))/1e6),ee={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL";o.toolCalls.push({tool:r,brief:Cs(u,60),error:E,durationMs:J}),o.spans.push({traceId:o.traceId,spanId:y,parentSpanId:o.spanId,name:r,kind:3,startTimeUnixNano:p,endTimeUnixNano:a,attributes:Us(w(Y.OBS_NAME,r),w(Y.OBS_TYPE,ee),w(Y.OBS_LEVEL,g),w(Y.OBS_INPUT,$t(d)),w(Y.OBS_OUTPUT,f),w("tool.name",r),w("tool.error",String(E))),status:{code:E?2:1}}),o.pendingTool=null,Rs(t,o),vt("PostToolUse",`sid=${t}`,`tool=${r}`,`error=${E}`,`durationMs=${J}`,`totalSpans=${o.spans.length}`),Pt(e);}qt.exports={onPostToolUse:bs};});var Dt=_((Lo,Bt)=>{var Le={"claude-opus-4-6":{input:15,output:75},"claude-opus-4-5":{input:15,output:75},"claude-sonnet-4-6":{input:3,output:15},"claude-sonnet-4-5":{input:3,output:15},"claude-haiku-4-5":{input:.8,output:4},"claude-4-6-opus":{input:15,output:75},"claude-4-6-sonnet":{input:3,output:15},"claude-4-5-opus":{input:15,output:75},"claude-4-5-sonnet":{input:3,output:15},"claude-4-5-haiku":{input:.8,output:4},"claude-3-5-sonnet-20241022":{input:3,output:15},"claude-3-5-haiku-20241022":{input:.8,output:4},"claude-3-opus-20240229":{input:15,output:75}};function $s(e,t,r){let n=Object.keys(Le).find(a=>(e||"").toLowerCase().includes(a));if(!n)return;let s=Le[n],o=(t*s.input+r*s.output)/1e6;return Math.round(o*1e6)/1e6}Bt.exports={MODEL_PRICING:Le,calcCostUsd:$s};});var Wt=_((No,Gt)=>{var{generateSpanId:Mt,nowNs:qs}=x(),{loadState:Fs,deleteState:xt}=H(),{LF:T,a:i,attrs:X,buildPayload:Bs,postToLangfuse:Ds}=ye(),{getIdentityFromToken:Ms}=M(),{calcCostUsd:xs}=Dt(),{readLastAssistantOutput:Hs}=Oe(),{truncate:Z,firstLine:Gs,passthrough:Ne}=v(),{dbg:K}=L(),{detectExecutionStatus:Ws}=z(),{sanitize:Ht}=me(),{TRACE_LIMITS:Q}=h();async function Ys(e){let t=e.session_id||"unknown",r=e.stop_reason||"end_turn",n=Fs(t);if(!n){Ne(e);return}let s=qs(),o=await Ms();if(n.slashSkill&&!n.toolCalls.some(S=>S.tool==="Skill")){let S=Mt(),q=n.skillContent?n.skillContent:JSON.stringify({skill:n.slashSkill});n.toolCalls.push({tool:"Skill",brief:n.slashSkill,error:false,durationMs:0,synthetic:true}),n.spans.push({traceId:n.traceId,spanId:S,parentSpanId:n.spanId,name:"Skill",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:n.startNs,attributes:X(i(T.OBS_NAME,"Skill"),i(T.OBS_TYPE,"TOOL"),i(T.OBS_LEVEL,"DEFAULT"),i(T.OBS_INPUT,q),i(T.OBS_OUTPUT,"loaded via slash command"),i("tool.name","Skill"),i("tool.error","false"),i("skill.name",n.slashSkill),i("skill.invocation","slash-command")),status:{code:1}}),K("Stop",`slashSkill=${n.slashSkill}`,"synthetic span injected");}let a=e.transcript_path||n.transcriptPath||"",l=Hs(a),p=n.toolCalls.length,u=n.toolCalls.filter(S=>S.error).length,d=Ht(l?.text?Z(l.text,Q.TRACE_OUTPUT):p===0?"No tools used":n.toolCalls.map((S,q)=>`${q+1}. ${S.tool}${S.brief?` \u2192 ${S.brief}`:""}${S.error?" [ERROR]":""}`).join(`
16
+ `)),f=l?.inputTokens??0,E=l?.outputTokens??0,g=n.toolCalls.map((S,q)=>`${q+1}. ${S.tool}${S.brief?` \u2192 ${S.brief}`:""}${S.error?" [ERROR]":""} (${S.durationMs}ms)`),y=!!(n.slashSkill||n.toolCalls.some(S=>S.tool==="Skill")),J=n.toolCalls.some(S=>S.tool==="Agent");if(!y&&!J){K("Stop",`sid=${t}`,"skipping trace \u2014 no Skill or Agent calls found"),xt(t),Ne(e);return}let V=y?"skill":"agent",ee=Math.round(Number(BigInt(s)-BigInt(n.startNs))/1e6),I=xs(n.model,f,E),m=Ws(n);m==="prerequisite_required"&&(n.spans.push({traceId:n.traceId,spanId:Mt(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:X(i(T.OBS_NAME,"prerequisite-check"),i(T.OBS_TYPE,"EVENT"),i(T.OBS_LEVEL,"WARNING"),i(T.OBS_OUTPUT,d),i("skill.name",n.slashSkill||void 0),i("execution_status","prerequisite_required")),status:{code:1}}),K("Stop",`sid=${t}`,"prerequisite-check span injected",`skill=${n.slashSkill}`));let Ie=(()=>{if(!(!y||!n.prompt)){if(n.slashSkill){let S=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return S?Z(S,Q.USER_INSTRUCTION):void 0}return Z(n.prompt,Q.USER_INSTRUCTION)||void 0}})(),Yt=JSON.stringify({trace_type:V,...m!==null&&{execution_status:m},...n.slashSkill&&{skill_name:n.slashSkill},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...Ie!==void 0&&{user_instruction:Ie},latency_ms:ee,...f&&{tokens_input:f},...E&&{tokens_output:E},cost_usd:I,...n.model&&{model:n.model},toolCount:p,errorCount:u,stopReason:r,sessionId:n.sessionId,tools:g.length?g:void 0}),Kt=Ht(Z(n.prompt,Q.TRACE_INPUT)),Jt=X(i(T.TRACE_NAME,n.traceName),i(T.TRACE_INPUT,Kt),i(T.TRACE_OUTPUT,d),i(T.TRACE_METADATA,Yt),i(T.SESSION_ID,n.sessionId),i(T.USER_ID,o.user),i(T.OBS_TYPE,"GENERATION"),i(T.MODEL,n.model),f?i(T.INPUT_TOKENS,f):null,E?i(T.OUTPUT_TOKENS,E):null,i("claude.stop_reason",r),i("claude.tool_count",String(p)),i("claude.error_count",String(u)),i("claude.session_id",n.sessionId),i("flow.trace_type",V),{key:T.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:V}]}}}),Vt={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:Jt,status:{code:u>0?2:1}},jt=X(i("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),i("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),we=[...n.spans||[],Vt];K("Stop",`sid=${t}`,`totalTools=${p}`,`errorTools=${u}`,`spans=${we.length}`,`inputTokens=${f}`,`outputTokens=${E}`,`traceOutput="${Gs(d,80)}"`);let zt=await Ds(Bs(jt,we));K("Stop",`POST status=${zt}`,`traceId=${n.traceId}`),xt(t),Ne(e);}Gt.exports={onStop:Ys};});var{credentialsAvailable:Ks}=M(),{readInput:Js}=v(),{onUserPromptSubmit:Vs}=Et(),{onPreToolUse:js}=ht(),{onPostToolUse:zs}=Ft(),{onStop:Xs}=Wt();async function Zs(){let e=process.argv[2];if(!await Ks()){let r=[];process.stdin.on("data",n=>r.push(n)),process.stdin.on("end",()=>process.stdout.write(r.join("")));return}let t=await Js();switch(e){case "UserPromptSubmit":await Vs(t);break;case "PreToolUse":await js(t);break;case "PostToolUse":await zs(t);break;case "Stop":await Xs(t);break;default:process.stderr.write(`[flow-obs] unknown event: ${e}
17
+ `),process.stdout.write(JSON.stringify(t));}}Zs().catch(e=>{process.stderr.write(`[flow-obs] fatal: ${e.message}
13
18
  `),process.exit(0);});
package/dist/setup.js CHANGED
@@ -1,51 +1,10 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';var i=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var u=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var E=u((sn,Q)=>{var h=process.env.FLOW_BASE_URL||"https://flow.ciandt.com",Z={AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${h}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${h}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${h}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${h}/otel`},Me={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},Ge="FLOW-nodejs",Ve="config.json",Ye={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},We={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:Z.OTEL_ENDPOINT,OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},$e={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP"},Be={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3},je={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},Je={FILE_PREFIX:"flow-obs-buffer-",MAX_AGE_MS:5760*60*1e3,MAX_FILES:50},Ke="flow-ai-obs-debug.log",He={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60},Xe="flow-obs-";Q.exports={FLOW_BASE_URL:h,FLOW_URLS:Z,VAULT:Me,CONFIG_DIR_NAME:Ge,CONFIG_FILE_NAME:Ve,OTLP:Ye,NATIVE_OTEL:We,ENV:$e,INSTALLER:Be,HOOK_TIMEOUTS:je,BUFFER:Je,DEBUG_LOG_FILENAME:Ke,STATE_FILE_PREFIX:Xe,TRACE_LIMITS:He};});var ne=u((on,te)=>{var O=i("fs"),T=i("path"),ze=i("os"),{CONFIG_DIR_NAME:x,CONFIG_FILE_NAME:b}=E(),D={credentials:"credentials","token-cache":"tokenCache"};function L(){let e=ze.homedir();if(process.platform==="darwin")return T.join(e,"Library","Preferences",x,b);if(process.platform==="win32"){let n=process.env.APPDATA||T.join(e,"AppData","Roaming");return T.join(n,x,b)}let t=process.env.XDG_CONFIG_HOME||T.join(e,".config");return T.join(t,x,b)}function q(){try{let e=O.readFileSync(L(),"utf8");return JSON.parse(e)}catch{return {}}}function ee(e){let t=L();O.mkdirSync(T.dirname(t),{recursive:true}),O.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var M=class{static isAvailable(){return true}static hasExistingData(){try{if(!O.existsSync(L()))return !1;let t=JSON.parse(O.readFileSync(L(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,n){let r=q(),s=D[n]||n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,n,r){let s=q(),o=D[n]||n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;ee(s);}async deleteSecret(t,n){let r=q(),s=D[n]||n;return s in r?(delete r[s],ee(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${L()}`}};function Ze(){}te.exports={ScryptFallbackProvider:M,_resetWarningState:Ze};});var se=u((an,re)=>{var{VAULT:A}=E();async function Qe(e,t){let n=[A.ACCOUNT_CREDS,A.ACCOUNT_TOKEN];for(let r of n)try{if(await t.getSecret(A.SERVICE,r)!==null)continue;let o=await e.getSecret(A.SERVICE,r);o!==null&&await t.setSecret(A.SERVICE,r,o);}catch{}}re.exports={migrateFromJsonFallback:Qe};});var ae=u((cn,ie)=>{var{execFile:et,exec:tt}=i("child_process"),{promisify:oe}=i("util"),G=oe(et),nt=oe(tt),V=class{static async isAvailable(){try{return await nt("command -v security"),!0}catch{return false}}async getSecret(t,n){try{let{stdout:r}=await G("security",["find-generic-password","-w","-a",n,"-s",t]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await G("security",["add-generic-password","-U","-a",n,"-s",t,"-w",r]);}async deleteSecret(t,n){try{return await G("security",["delete-generic-password","-a",n,"-s",t]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};ie.exports={MacOsKeyVaultProvider:V};});var de=u((un,le)=>{var{execFile:rt,exec:st,spawn:ot}=i("child_process"),{promisify:ue}=i("util"),ce=ue(rt),it=ue(st),Y=class{static async isAvailable(){try{return await it("command -v secret-tool"),!0}catch{return false}}async getSecret(t,n){try{let{stdout:r}=await ce("secret-tool",["lookup","service",t,"account",n]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await new Promise((s,o)=>{let c=ot("secret-tool",["store","--label",t,"service",t,"account",n]);c.on("error",o),c.on("close",w=>{w===0?s():o(new Error(`secret-tool exited with code ${w}`));}),c.stdin.write(r),c.stdin.end();});}async deleteSecret(t,n){try{return await ce("secret-tool",["clear","service",t,"account",n]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};le.exports={LinuxKeyVaultProvider:Y};});var pe=u((ln,we)=>{var W=class{static async isAvailable(){try{return await i("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(t,n){return i("keytar").getPassword(t,n)}async setSecret(t,n,r){await i("keytar").setPassword(t,n,r);}async deleteSecret(t,n){return i("keytar").deletePassword(t,n)}getStoragePath(){return "Windows Credential Manager"}};we.exports={WindowsKeyVaultProvider:W};});var _e=u((dn,Te)=>{async function Ee(){let{ScryptFallbackProvider:e}=ne();if(e.hasExistingData()){let t=await fe();if(t){let{migrateFromJsonFallback:n}=se(),{VAULT:r}=E();if(await n(new e,t),await t.getSecret(r.SERVICE,r.ACCOUNT_CREDS)!==null)return t}return new e}return await fe()??new e}async function fe(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=ae();return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=de();return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=pe();return await e.isAvailable()?new e:null}default:return null}}var at=Ee;Te.exports={createSecretVaultProvider:Ee,createKeyVaultProvider:at};});var H=u((wn,ye)=>{var{createSecretVaultProvider:ct}=_e(),{VAULT:B}=E(),_=B.SERVICE,j=B.ACCOUNT_CREDS,J=B.ACCOUNT_TOKEN,$=null;function S(){return $||($=ct()),$}async function Se(){let t=await(await S()).getSecret(_,j);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function ut(e){if(!e.clientId||!e.clientSecret||!e.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await S()).setSecret(_,j,JSON.stringify(e));}async function lt(){let e=await S();await e.deleteSecret(_,j),await e.deleteSecret(_,J);}async function dt(e){await(await S()).setSecret(_,J,JSON.stringify({accessToken:e.accessToken,expiresAt:e.expiresAt}));}async function K(){let t=await(await S()).getSecret(_,J);if(!t)return null;try{let n=JSON.parse(t);return {accessToken:n.accessToken,expiresAt:n.expiresAt}}catch{return null}}async function wt(){let e=await K();return e?new Date(e.expiresAt)>new Date:false}async function pt(){let e=await K();if(!e||!e.accessToken)return null;try{let t=e.accessToken.split(".");if(t.length<2)return null;let n=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}async function ft(){let e=await S();if(typeof e.getStoragePath=="function")return e.getStoragePath();let t=process.platform;return t==="darwin"?"macOS Keychain":t==="win32"?"Windows Credential Manager":"Linux Secret Service (libsecret)"}async function Et(){let e=await Se();return !!(e&&e.clientId&&e.clientSecret&&e.tenant)}ye.exports={getFlowCredentials:Se,saveFlowCredentials:ut,clearFlowCredentials:lt,saveTokenCache:dt,getTokenCache:K,isTokenValid:wt,getEmailFromToken:pt,getConfigPath:ft,hasCredentials:Et};});var X=u((pn,he)=>{var Tt=i("https"),_t=i("http"),{FLOW_URLS:St}=E(),yt=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function gt(e){if(!yt.test(e))throw new Error(`Invalid tenant value: "${e}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var ge={INVALID_CLIENT_SECRET:"Invalid Client Secret \u2014 check the value and try again",INVALID_CLIENT_ID:"Invalid Client ID \u2014 check the value and try again",INVALID_TENANT:"Invalid Tenant \u2014 check the value and try again",TENANT_NOT_FOUND:"Tenant not found \u2014 verify the tenant identifier"};function ht(e,t){try{let n=JSON.parse(t);if(typeof n.error=="string"&&ge[n.error])return new Error(ge[n.error])}catch{}return e===401||e===403||e===500?new Error("Invalid credentials"):e>=400&&e<500?new Error("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function Lt(e){return new Promise((t,n)=>{try{gt(e.tenant);}catch(a){return n(a)}let r=JSON.stringify({clientSecret:e.clientSecret}),s=new URL(St.AUTH_ENGINE),o=s.protocol==="https:",c={hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname+s.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(r),FlowTenant:e.tenant}},d=(o?Tt:_t).request(c,a=>{let l=[];a.on("data",R=>l.push(R)),a.on("end",()=>{let R=l.join("");if(a.statusCode>=400)return n(ht(a.statusCode,R));let v;try{v=JSON.parse(R);}catch{return n(new Error("Invalid response from auth engine"))}let qe=v.expires_at??new Date(Date.now()+(v.expires_in??3600)*1e3).toISOString();t({accessToken:v.access_token,expiresAt:qe});});});d.on("error",a=>n(new Error(`Network error: ${a.message}`))),d.write(r),d.end();})}he.exports={getToken:Lt};});var Oe=u((fn,Le)=>{var Ot=!process.env.NO_COLOR&&process.stdout.isTTY;function y(e,t){return Ot?n=>`\x1B[${e}m${n}\x1B[${t}m`:n=>n}var At=y("32","39"),Ct=y("31","39"),Nt=y("33","39"),It=y("36","39"),mt=y("1","22"),Rt=y("2","22");Le.exports={green:At,red:Ct,yellow:Nt,cyan:It,bold:mt,dim:Rt};});var ve=u((En,Re)=>{var{getFlowCredentials:Ae,saveFlowCredentials:vt,clearFlowCredentials:Ut,saveTokenCache:Pt,isTokenValid:Ft,getConfigPath:Ce,hasCredentials:Ne}=H(),{getToken:kt}=X(),{green:P,red:C,yellow:U,cyan:N,bold:Ie,dim:g}=Oe(),xt=/[\x00-\x08\x0B-\x1F\x7F]|\x1b\[[0-9;]*[a-zA-Z]/g;function f(e){return typeof e=="string"?e.replace(xt,""):e}function I(e,t={}){return new Promise((n,r)=>{let{masked:s=false,defaultValue:o=""}=t;process.stdout.write(e+o);let c=o;function w(){try{process.stdin.setRawMode(!1);}catch{}}process.once("uncaughtException",w),process.once("unhandledRejection",w);let d=l=>{if(l===""){a(),r(new Error("SIGINT"));return}if(l==="\r"||l===`
3
- `){a(),process.stdout.write(`
4
- `),n(c);return}if(l==="\x7F"){c.length>0&&(c=c.slice(0,-1),process.stdout.write("\b \b"));return}l.startsWith("\x1B")||(c+=l,process.stdout.write(s?"*".repeat(l.length):l));};function a(){process.stdin.setRawMode(false),process.stdin.removeListener("data",d),process.removeListener("uncaughtException",w),process.removeListener("unhandledRejection",w);}process.stdin.setRawMode(true),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",d);})}async function me(e){let{accessToken:t,expiresAt:n}=await kt(e);await vt(e),await Pt({accessToken:t,expiresAt:n});}async function bt(e){try{return await me(e),process.stdout.write(P(` \u2713 Setup complete. Tenant: ${f(e.tenant)}
5
-
6
- `)),0}catch(t){return process.stderr.write(C(` \u2717 Authentication failed: ${f(t.message)}
7
- `)),1}}async function Dt(){try{process.stdout.write(`
8
- `);let e=(await I(N(" ? ")+"Client ID: ")).trim(),t=(await I(N(" ? ")+"Client Secret: ",{masked:!0})).trim(),n=(await I(N(" ? ")+"Tenant: ")).trim();if(!e||!t||!n)return process.stderr.write(C(` \u2717 All fields are required
9
- `)),1;try{await me({clientId:e,clientSecret:t,tenant:n});}catch(r){return process.stderr.write(C(` \u2717 Authentication failed: ${f(r.message)}
10
- `)),1}return process.stdout.write(P(` \u2713 Setup complete. Tenant: ${f(n)}
11
- `)),process.stdout.write(` Storage: ${await Ce()}
12
-
13
- `),0}catch(e){if(e.message==="SIGINT")throw e;return process.stderr.write(C(` \u2717 Unexpected error: ${e.message}
14
- `)),1}}async function qt(e={}){if(e.clientId&&e.clientSecret&&e.tenant)return bt({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant});if(await Ne()){let t=await Ae();process.stdout.write(`
15
- `),process.stdout.write(Ie(` Already authenticated
16
- `)),process.stdout.write(g(" Tenant: ")+f(t.tenant)+`
17
- `),process.stdout.write(g(" Client ID: ")+f(t.clientId)+`
18
- `),process.stdout.write(`
19
- `);let n;try{n=await I(N(" ? ")+"Re-authenticate? (y/N): ");}catch(r){if(r.message==="SIGINT")return process.stdout.write(`
20
- `),130;throw r}if(n.trim().toLowerCase()!=="y")return process.stdout.write(P(` \u2713 Using existing credentials.
21
-
22
- `)),0}try{return await Dt()}catch(t){if(t.message==="SIGINT")return process.stdout.write(`
23
- `),130;throw t}}async function Mt(){try{return process.stdout.write(`
24
- `),(await I(N(" ? ")+"Are you sure? This will remove your local credentials. (y/N): ")).toLowerCase()!=="y"?(process.stdout.write(U(` \u26A0 Logout cancelled
25
- `)),0):null}catch(e){if(e.message==="SIGINT")return process.stdout.write(`
26
- `),130;throw e}}async function Gt(e=false){if(!await Ne())return process.stdout.write(U(` \u26A0 You are not authenticated
27
- `)),0;if(!e){let t=await Mt();if(t!==null)return t}try{return await Ut(),process.stdout.write(P(` \u2713 Credentials removed successfully
28
- `)),0}catch{return process.stderr.write(C(` \u2717 Error removing credentials
29
- `)),1}}async function Vt(){let e=await Ae();if(!e)return process.stdout.write(U(" \u26A0 Not authenticated. Run `flow-ai-obs auth login` to set up.\n")),0;if(!await Ft())return process.stdout.write(U(" \u26A0 Session expired. Run `flow-ai-obs auth login` to re-authenticate.\n")),0;let t=e.clientSecret.length>4?"****...****"+e.clientSecret.slice(-4):"****";return process.stdout.write(`
30
- `+Ie(` Authenticated
31
- `)),process.stdout.write(g(" Tenant: ")+f(e.tenant)+`
32
- `),process.stdout.write(g(" Client ID: ")+f(e.clientId)+`
33
- `),process.stdout.write(g(" Client Secret: ")+t+`
34
- `),process.stdout.write(g(" Storage: ")+await Ce()+`
35
-
36
- `),0}Re.exports={runLogin:qt,runLogout:Gt,runStatus:Vt};});var ke=u((Tn,Fe)=>{var p=i("fs"),k=i("path"),Ue=i("os"),{FLOW_URLS:Yt,INSTALLER:m,HOOK_TIMEOUTS:F,NATIVE_OTEL:Wt}=E(),{getToken:$t}=X();function Pe(){return process.platform==="win32"?k.join(process.env.APPDATA||k.join(Ue.homedir(),"AppData","Roaming"),"Claude","settings.json"):k.join(Ue.homedir(),".claude","settings.json")}var Bt=m.LOCK_STALE_MS;function jt(e){try{let t=p.statSync(e);Date.now()-t.mtimeMs>Bt&&p.unlinkSync(e);}catch{}try{p.writeFileSync(e,String(process.pid),{flag:"wx"});}catch(t){throw t.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+e):t}}function Jt(e){try{p.unlinkSync(e);}catch{}}function Kt(){let e=Pe(),t=e+".lock";p.mkdirSync(k.dirname(e),{recursive:true}),jt(t);try{p.existsSync(e)&&p.copyFileSync(e,e+".bkp");let n={};try{n=JSON.parse(p.readFileSync(e,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,Wt),n.otelHeadersHelper="flow-ai-obs otel-headers",(!n.hooks||typeof n.hooks!="object")&&(n.hooks={});let r=(s,o)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${s}`,timeout:o}]});n.hooks.UserPromptSubmit=[r("UserPromptSubmit",F.UserPromptSubmit)],n.hooks.PreToolUse=[r("PreToolUse",F.PreToolUse)],n.hooks.PostToolUse=[r("PostToolUse",F.PostToolUse)],n.hooks.Stop=[r("Stop",F.Stop)],p.writeFileSync(e,JSON.stringify(n,null,2)+`
37
- `,"utf8");}finally{Jt(t);}return e}async function Ht(e){let t;try{t=(await $t(e)).accessToken;}catch{return false}return t?new Promise(n=>{z(`Bearer ${t}`,n,1);}):false}function z(e,t,n){let r=new URL(Yt.GATEWAY_TRACES),s=JSON.stringify({resourceSpans:[],validation_run:true}),o=r.protocol==="https:",c={hostname:r.hostname,port:r.port||(o?443:80),path:r.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:e,"Content-Length":Buffer.byteLength(s)}},d=(o?i("https"):i("http")).request(c,a=>{a.resume(),a.statusCode===200||a.statusCode===204?t(true):n<m.CONNECTIVITY_MAX_RETRY?setTimeout(()=>z(e,t,n+1),m.CONNECTIVITY_RETRY_MS):t(false);});d.on("error",()=>{n<m.CONNECTIVITY_MAX_RETRY?setTimeout(()=>z(e,t,n+1),m.CONNECTIVITY_RETRY_MS):t(false);}),d.write(s),d.end();}Fe.exports={getClaudeSettingsPath:Pe,writeClaudeSettings:Kt,validateConnectivity:Ht};});var xe=i("path"),{hasCredentials:be,getConfigPath:De,isTokenValid:Xt,getFlowCredentials:zt}=H(),{runLogin:Zt}=ve(),{writeClaudeSettings:Qt,validateConnectivity:en}=ke();function tn(){let e=xe.resolve(__dirname,".."),n=(process.env.INIT_CWD?xe.resolve(process.env.INIT_CWD):null)===e;return !process.stdin.isTTY||n||process.env.CI==="true"||process.env.CI==="1"||process.env.npm_config_yes==="true"||process.env.DEBIAN_FRONTEND==="noninteractive"}async function nn(){if(tn()){await be()&&(console.log(`
38
- [flow-ai-obs] Already authenticated \u2014 skipping setup wizard.`),console.log(" Run `flow-ai-obs install` to register Claude Code hooks.\n"));return}if(console.log(`
39
- \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557`),console.log("\u2551 flow-ai-obs \u2014 setup wizard \u2551"),console.log(`\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
40
- `),await be()&&await Xt())console.log(` \u2713 Already authenticated. Config: ${await De()}`),console.log(" Run `flow-ai-obs auth status` to inspect."),console.log(" Run `flow-ai-obs auth login` to re-authenticate.\n");else {console.log(` Authenticate with your Flow credentials (clientId / clientSecret / tenant).
41
- `),console.log(" Credentials will be stored in:"),console.log(` ${await De()}
42
- `);let n=await Zt();n!==0&&(console.error("\n Setup aborted. Run `flow-ai-obs auth login` to retry.\n"),process.exit(n));}try{let n=Qt();console.log(` \u2713 Claude settings updated at ${n}`);}catch(n){console.error(`
43
- [warn] Could not update Claude settings: ${n.message}`);}console.log(`
44
- Validating connectivity to Flow OTEL endpoint\u2026`);let e=await zt();e||(console.error(`
45
- [error] Could not read stored credentials.
46
- `),process.exit(1));let t=await en(e);console.log(t?` \u2713 Connectivity validated \u2014 telemetry is active.
47
- `:` \u26A0 Could not reach the OTEL endpoint. Telemetry will activate once connectivity is restored.
48
- `),console.log(` [done] Setup complete!
49
- `);}nn().catch(e=>{console.error(`
50
- [error] ${e.message}
51
- `),process.exit(1);});
2
+ 'use strict';var c=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var _=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var p=_((tn,ee)=>{var O=process.env.FLOW_BASE_URL||"https://flow.ciandt.com",Z={AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${O}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${O}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${O}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${O}/otel`},Fe={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},ke="FLOW-nodejs",be="config.json",De={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},Me={ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL||`${O}/flow-llm-proxy/`,ANTHROPIC_MODEL:process.env.FLOW_LLM_PROXY_MODEL||"anthropic.claude-4-6-sonnet",ANTHROPIC_SMALL_FAST_MODEL:process.env.FLOW_LLM_PROXY_SMALL_MODEL||"anthropic.claude-4-6-sonnet",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"},He={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:Z.OTEL_ENDPOINT,OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},qe={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP"},Ye={KEYCHAIN_ENABLED:false},We={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3},Ge={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},xe={FILE_PREFIX:"flow-obs-buffer-",MAX_AGE_MS:5760*60*1e3,MAX_FILES:50},$e="flow-ai-obs-debug.log",Be={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60},Ke="flow-obs-";ee.exports={FLOW_BASE_URL:O,FLOW_URLS:Z,VAULT:Fe,CONFIG_DIR_NAME:ke,CONFIG_FILE_NAME:be,OTLP:De,LLM_PROXY:Me,NATIVE_OTEL:He,ENV:qe,FEATURES:Ye,INSTALLER:We,HOOK_TIMEOUTS:Ge,BUFFER:xe,DEBUG_LOG_FILENAME:$e,STATE_FILE_PREFIX:Ke,TRACE_LIMITS:Be};});var re=_((nn,ne)=>{var g=c("fs"),A=c("path"),Ve=c("os"),{CONFIG_DIR_NAME:P,CONFIG_FILE_NAME:F}=p(),k={credentials:"credentials","token-cache":"tokenCache"};function N(){let e=Ve.homedir();if(process.platform==="darwin")return A.join(e,"Library","Preferences",P,F);if(process.platform==="win32"){let n=process.env.APPDATA||A.join(e,"AppData","Roaming");return A.join(n,P,F)}let t=process.env.XDG_CONFIG_HOME||A.join(e,".config");return A.join(t,P,F)}function b(){try{let e=g.readFileSync(N(),"utf8");return JSON.parse(e)}catch{return {}}}function te(e){let t=N();g.mkdirSync(A.dirname(t),{recursive:true}),g.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var D=class{static isAvailable(){return true}static hasExistingData(){try{if(!g.existsSync(N()))return !1;let t=JSON.parse(g.readFileSync(N(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,n){let r=b(),s=k[n]||n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,n,r){let s=b(),o=k[n]||n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;te(s);}async deleteSecret(t,n){let r=b(),s=k[n]||n;return s in r?(delete r[s],te(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${N()}`}};function je(){}ne.exports={ScryptFallbackProvider:D,_resetWarningState:je};});var ce=_((rn,oe)=>{var{execFile:Je,exec:Xe}=c("child_process"),{promisify:se}=c("util"),M=se(Je),ze=se(Xe),H=class{static async isAvailable(){try{return await ze("command -v security"),!0}catch{return false}}async getSecret(t,n){try{let{stdout:r}=await M("security",["find-generic-password","-w","-a",n,"-s",t]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await M("security",["add-generic-password","-U","-a",n,"-s",t,"-w",r]);}async deleteSecret(t,n){try{return await M("security",["delete-generic-password","-a",n,"-s",t]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};oe.exports={MacOsKeyVaultProvider:H};});var ue=_((sn,le)=>{var{execFile:Qe,exec:Ze,spawn:et}=c("child_process"),{promisify:ie}=c("util"),ae=ie(Qe),tt=ie(Ze),q=class{static async isAvailable(){try{return await tt("command -v secret-tool"),!0}catch{return false}}async getSecret(t,n){try{let{stdout:r}=await ae("secret-tool",["lookup","service",t,"account",n]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await new Promise((s,o)=>{let a=et("secret-tool",["store","--label",t,"service",t,"account",n]);a.on("error",o),a.on("close",S=>{S===0?s():o(new Error(`secret-tool exited with code ${S}`));}),a.stdin.write(r),a.stdin.end();});}async deleteSecret(t,n){try{return await ae("secret-tool",["clear","service",t,"account",n]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};le.exports={LinuxKeyVaultProvider:q};});var _e=_((on,Ee)=>{var Y=class{static async isAvailable(){try{return await c("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(t,n){return c("keytar").getPassword(t,n)}async setSecret(t,n,r){await c("keytar").setPassword(t,n,r);}async deleteSecret(t,n){return c("keytar").deletePassword(t,n)}getStoragePath(){return "Windows Credential Manager"}};Ee.exports={WindowsKeyVaultProvider:Y};});var de=_((cn,fe)=>{async function Te(){let{ScryptFallbackProvider:e}=re();return await nt()??new e}async function nt(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=ce();return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=ue();return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=_e();return await e.isAvailable()?new e:null}default:return null}}var rt=Te;fe.exports={createSecretVaultProvider:Te,createKeyVaultProvider:rt};});var K=_((an,Se)=>{var{createSecretVaultProvider:st}=de(),{VAULT:G}=p(),h=G.SERVICE,x=G.ACCOUNT_CREDS,$=G.ACCOUNT_TOKEN,W=null;function L(){return W||(W=st()),W}async function pe(){let t=await(await L()).getSecret(h,x);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function ot(e){if(!e.clientId||!e.clientSecret||!e.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await L()).setSecret(h,x,JSON.stringify(e));}async function ct(){let e=await L();await e.deleteSecret(h,x),await e.deleteSecret(h,$);}async function at(e){await(await L()).setSecret(h,$,JSON.stringify({accessToken:e.accessToken,expiresAt:e.expiresAt}));}async function B(){let t=await(await L()).getSecret(h,$);if(!t)return null;try{let n=JSON.parse(t);return {accessToken:n.accessToken,expiresAt:n.expiresAt}}catch{return null}}async function it(){let e=await B();return e?new Date(e.expiresAt)>new Date:false}async function lt(){let e=await B();if(!e||!e.accessToken)return null;try{let t=e.accessToken.split(".");if(t.length<2)return null;let n=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}async function ut(){let e=await L();if(typeof e.getStoragePath=="function")return e.getStoragePath();let t=process.platform;return t==="darwin"?"macOS Keychain":t==="win32"?"Windows Credential Manager":"Linux Secret Service (libsecret)"}async function Et(){let e=await pe();return !!(e&&e.clientId&&e.clientSecret&&e.tenant)}Se.exports={getFlowCredentials:pe,saveFlowCredentials:ot,clearFlowCredentials:ct,saveTokenCache:at,getTokenCache:B,isTokenValid:it,getEmailFromToken:lt,getConfigPath:ut,hasCredentials:Et};});var V=_((ln,Ae)=>{var _t=c("https"),Tt=c("http"),{FLOW_URLS:ft}=p(),dt=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function pt(e){if(!dt.test(e))throw new Error(`Invalid tenant value: "${e}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var Oe={INVALID_CLIENT_SECRET:"Invalid Client Secret \u2014 check the value and try again",INVALID_CLIENT_ID:"Invalid Client ID \u2014 check the value and try again",INVALID_TENANT:"Invalid Tenant \u2014 check the value and try again",TENANT_NOT_FOUND:"Tenant not found \u2014 verify the tenant identifier"};function St(e,t){try{let n=JSON.parse(t);if(typeof n.error=="string"&&Oe[n.error])return new Error(Oe[n.error])}catch{}return e===401||e===403||e===500?new Error("Invalid credentials"):e>=400&&e<500?new Error("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function Ot(e){return new Promise((t,n)=>{try{pt(e.tenant);}catch(l){return n(l)}let r=JSON.stringify({clientSecret:e.clientSecret}),s=new URL(ft.AUTH_ENGINE),o=s.protocol==="https:",a={hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname+s.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(r),FlowTenant:e.tenant}},f=(o?_t:Tt).request(a,l=>{let u=[];l.on("data",E=>u.push(E)),l.on("end",()=>{let E=u.join("");if(l.statusCode>=400)return n(St(l.statusCode,E));let d;try{d=JSON.parse(E);}catch{return n(new Error("Invalid response from auth engine"))}let w=d.expires_at??new Date(Date.now()+(d.expires_in??3600)*1e3).toISOString();t({accessToken:d.access_token,expiresAt:w});});});f.on("error",l=>n(new Error(`Network error: ${l.message}`))),f.write(r),f.end();})}Ae.exports={getToken:Ot};});var Ne=_((un,we)=>{var i=c("fs"),C=c("path"),he=c("os"),{FLOW_URLS:At,INSTALLER:R,HOOK_TIMEOUTS:v,NATIVE_OTEL:ht,LLM_PROXY:Lt}=p(),{getToken:yt}=V();function J(){return process.platform==="win32"?C.join(process.env.APPDATA||C.join(he.homedir(),"AppData","Roaming"),"Claude","settings.json"):C.join(he.homedir(),".claude","settings.json")}var wt=R.LOCK_STALE_MS;function Le(e){try{let t=i.statSync(e);Date.now()-t.mtimeMs>wt&&i.unlinkSync(e);}catch{}try{i.writeFileSync(e,String(process.pid),{flag:"wx"});}catch(t){throw t.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+e):t}}function ye(e){try{i.unlinkSync(e);}catch{}}function Nt(){let e=J(),t=e+".lock";i.mkdirSync(C.dirname(e),{recursive:true}),Le(t);try{if(i.existsSync(e)){i.copyFileSync(e,e+".bkp");try{i.chmodSync(e+".bkp",384);}catch{}}let n={};try{n=JSON.parse(i.readFileSync(e,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,ht),Object.assign(n.env,Lt),n.otelHeadersHelper="flow-ai-obs otel-headers",(!n.hooks||typeof n.hooks!="object")&&(n.hooks={});let r=(s,o)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${s}`,timeout:o}]});n.hooks.UserPromptSubmit=[r("UserPromptSubmit",v.UserPromptSubmit)],n.hooks.PreToolUse=[r("PreToolUse",v.PreToolUse)],n.hooks.PostToolUse=[r("PostToolUse",v.PostToolUse)],n.hooks.Stop=[r("Stop",v.Stop)],i.writeFileSync(e,JSON.stringify(n,null,2)+`
3
+ `,{encoding:"utf8",mode:384});try{i.chmodSync(e,384);}catch{}}finally{ye(t);}return e}async function gt(e){let t;try{t=(await yt(e)).accessToken;}catch{return false}return t?new Promise(n=>{j(`Bearer ${t}`,n,1);}):false}function j(e,t,n){let r=new URL(At.GATEWAY_TRACES),s=JSON.stringify({resourceSpans:[],validation_run:true}),o=r.protocol==="https:",a={hostname:r.hostname,port:r.port||(o?443:80),path:r.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:e,"Content-Length":Buffer.byteLength(s)}},f=(o?c("https"):c("http")).request(a,l=>{l.resume(),l.statusCode===200||l.statusCode===204?t(true):n<R.CONNECTIVITY_MAX_RETRY?setTimeout(()=>j(e,t,n+1),R.CONNECTIVITY_RETRY_MS):t(false);});f.on("error",()=>{n<R.CONNECTIVITY_MAX_RETRY?setTimeout(()=>j(e,t,n+1),R.CONNECTIVITY_RETRY_MS):t(false);}),f.write(s),f.end();}function Rt(e){let t=J(),n=t+".lock";i.mkdirSync(C.dirname(t),{recursive:true}),Le(n);try{let r={};try{r=JSON.parse(i.readFileSync(t,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,e),i.writeFileSync(t,JSON.stringify(r,null,2)+`
4
+ `,{encoding:"utf8",mode:384});try{i.chmodSync(t,384);}catch{}}finally{ye(n);}}we.exports={getClaudeSettingsPath:J,writeClaudeSettings:Nt,addEnvToClaudeSettings:Rt,validateConnectivity:gt};});var Ce=_((En,Re)=>{var{writeFileSync:Ct}=c("fs"),{tmpdir:It}=c("os"),{join:vt}=c("path"),{DEBUG_LOG_FILENAME:mt,ENV:Ut}=p(),ge=vt(It(),mt);function Pt(...e){if(process.env[Ut.FLOW_OBS_DEBUG]!=="1")return;let t=`[${new Date().toISOString()}] ${e.join(" ")}
5
+ `;try{Ct(ge,t,{flag:"a"});}catch(n){process.stderr.write(`[flow-obs debug ERROR] ${n.message}
6
+ `);}}Re.exports={dbg:Pt,DEBUG_LOG:ge};});var me=_((_n,ve)=>{var{getFlowCredentials:X,isTokenValid:Ft,getEmailFromToken:I,getTokenCache:kt,saveTokenCache:bt}=K(),{getToken:Dt}=V(),{FLOW_BASE_URL:Mt,ENV:T,FEATURES:z}=p(),{dbg:y}=Ce(),Ht=[/^localhost\.?$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/,/^::1$/,/^\[::1\]$/,/^\[::ffff:/i,/^\[f[cd]/i,/^\[fe80:/i,/^metadata\.google\.internal\.?$/i,/^metadata\.azure\.internal\.?$/i,/(?:^|\.)localtest\.me\.?$/i,/(?:^|\.)lvh\.me\.?$/i,/(?:^|\.)vcap\.me\.?$/i];function qt(e){return Ht.some(t=>t.test(e))}function m(e){if(!e)return null;try{let t=e.split(".");if(t.length<2)return null;let n=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:o}=n;return !r||!s||!o?null:{clientId:r,clientSecret:s,tenant:o}}catch{return null}}function Yt(e){let t=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),n=Buffer.from(JSON.stringify({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant})).toString("base64url");return `${t}.${n}.`}function Q(e){let t;try{t=new URL(e);}catch{throw new Error(`Invalid URL: ${e}`)}if(!(process.env[T.FLOW_OBS_ALLOW_HTTP]==="true")&&t.protocol!=="https:")throw new Error(`URL must use HTTPS: ${e}`);if(t.username||t.password)throw new Error(`URL must not contain embedded credentials: ${e}`);if(qt(t.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${t.hostname}`);return e}async function Wt(){let e=m(process.env[T.ANTHROPIC_AUTH_TOKEN]);if(e)return {user:await I().catch(()=>null)||e.clientId,tenant:e.tenant};if(z.KEYCHAIN_ENABLED)try{let t=await X();if(!t)return {user:"",tenant:""};let n=await I()||t.clientId||"",r=t.tenant||"";return {user:n,tenant:r}}catch{return {user:"",tenant:""}}return {user:"",tenant:""}}async function Gt(e){if(await Ft())return (await kt()).accessToken;y("getOrRefreshToken","token expired \u2014 refreshing via auth-engine");let t=await Dt(e);return await bt(t),y("getOrRefreshToken",`token refreshed, expires=${t.expiresAt}`),t.accessToken}function xt(e,t){let n=t&&t.accessToken?t.accessToken:"";return {endpoint:e.replace(/\/$/,"")+"/langfuse/traces",authHeader:`Bearer ${n}`}}function $t(e,t,n){let r=Buffer.from(`${t}:${n}`).toString("base64");return {endpoint:e.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${r}`}}async function Ie(){let e=[],t=process.env[T.ANTHROPIC_MODEL]||"",n=process.env[T.FLOW_TELEMETRY]==="true",r=process.env[T.LANGFUSE_BASE_URL],s=process.env[T.LANGFUSE_PUBLIC_KEY],o=process.env[T.LANGFUSE_SECRET_KEY];if(n&&r&&s&&o){let u="",E="",d=m(process.env[T.ANTHROPIC_AUTH_TOKEN]);if(d)u=await I().catch(()=>null)||d.clientId,E=d.tenant;else if(z.KEYCHAIN_ENABLED)try{let U=await X();U&&(u=await I()||U.clientId,E=U.tenant);}catch{}let w={user:u||"",tenant:E||"",team:"",project:"",model:t};e.push({mode:"direct",...$t(Q(r),s,o),...w}),y("resolveCredentials","direct mode active",`user=${w.user}`,`tenant=${w.tenant}`);}let a=m(process.env[T.ANTHROPIC_AUTH_TOKEN]);if(y("resolveCredentials",a?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),!a&&z.KEYCHAIN_ENABLED&&(a=await X(),a&&y("resolveCredentials","credentials resolved from keychain (FEATURES.KEYCHAIN_ENABLED=true)")),!a){if(e.length===0){let u=[];return u.authError=false,u}return e}let S;try{S=await Gt(a);}catch(u){if(y("resolveCredentials",`token refresh failed: ${u.message}`),e.length>0)return e;let E=[];return E.authError=true,E}let f={user:await I()||a.clientId,tenant:a.tenant,team:"",project:"",model:t},l=process.env[T.FLOW_TELEMETRY_GATEWAY]||Mt;return e.push({mode:"gateway",...xt(Q(l),{accessToken:S}),...f}),e}async function Bt(){return (await Ie()).length>0}ve.exports={credentialsAvailable:Bt,getIdentityFromToken:Wt,resolveCredentials:Ie,validateUrl:Q,parseCredsFromAnthropicToken:m,buildAnthropicAuthToken:Yt};});var Pe=c("path"),{getFlowCredentials:Kt}=K(),{writeClaudeSettings:Vt,addEnvToClaudeSettings:jt}=Ne(),{buildAnthropicAuthToken:Jt,parseCredsFromAnthropicToken:Xt}=me(),{ENV:Ue}=p(),zt=Pe.resolve(__dirname,".."),Qt=process.env.INIT_CWD?Pe.resolve(process.env.INIT_CWD):null;Qt===zt&&process.exit(0);async function Zt(){try{Vt();}catch{}let e=await Kt();if(!e){process.stderr.write(`
7
+ [flow-ai-obs] No credentials found.
8
+ Run \`flow-ai-obs auth login\` to authenticate and enable telemetry.
9
+
10
+ `);return}let t=Xt(process.env[Ue.ANTHROPIC_AUTH_TOKEN]);if(!t||t.clientId!==e.clientId||t.clientSecret!==e.clientSecret||t.tenant!==e.tenant)try{let r=Jt(e);jt({[Ue.ANTHROPIC_AUTH_TOKEN]:r});}catch{}}Zt().catch(()=>{});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ciandt-flow/flow-ai-obs",
3
- "version": "0.2.0",
3
+ "version": "0.3.0-beta.32",
4
4
  "description": "Claude Code hooks for Langfuse OTLP tracing — cross-platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -13,7 +13,7 @@
13
13
  "typecheck": "node --check src/**/*.js bin/cli.js",
14
14
  "lint": "node --check src/**/*.js bin/cli.js",
15
15
  "security-scan": "trufflehog filesystem src/ --fail --no-update --exclude-paths .trufflehogignore",
16
- "postinstall": "node dist/setup.js",
16
+ "postinstall": "node -e \"require('fs').existsSync('dist/setup.js') && require('child_process').execFileSync(process.execPath, ['dist/setup.js'], {stdio:'inherit'})\"",
17
17
  "prepublishOnly": "npm run security-scan && npm run build",
18
18
  "release:npm": "changeset publish",
19
19
  "changeset": "changeset",
@@ -63,4 +63,4 @@
63
63
  "type": "git",
64
64
  "url": "git+https://github.com/CI-T-HyperX/flow-codeassistant-observability.git"
65
65
  }
66
- }
66
+ }