@ciandt-flow/flow-ai-obs 0.5.2-beta.363 → 0.6.0

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,204 +1,169 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';var Zn=require('https'),E=require('fs'),Q=require('os'),Et=require('path'),child_process=require('child_process'),ms=require('http'),util=require('util'),crypto=require('crypto');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var Zn__namespace=/*#__PURE__*/_interopNamespace(Zn);var E__namespace=/*#__PURE__*/_interopNamespace(E);var Q__namespace=/*#__PURE__*/_interopNamespace(Q);var Et__namespace=/*#__PURE__*/_interopNamespace(Et);var ms__namespace=/*#__PURE__*/_interopNamespace(ms);var me=Object.defineProperty;var Gn=Object.getOwnPropertyDescriptor;var Wn=Object.getOwnPropertyNames;var Kn=Object.prototype.hasOwnProperty;var Nt=(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 p=(t,e)=>()=>(t&&(e=t(t=0)),e);var qn=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),$=(t,e)=>{for(var r in e)me(t,r,{get:e[r],enumerable:true});},Jn=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Wn(e))!Kn.call(t,s)&&s!==r&&me(t,s,{get:()=>e[s],enumerable:!(n=Gn(e,s))||n.enumerable});return t};var L=t=>Jn(me({},"__esModule",{value:true}),t);var qt=qn((Uo,Xn)=>{Xn.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.5.2-beta.363",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:"jest",typecheck:"tsc --noEmit",lint:"eslint src bin scripts",format:'prettier --write "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"format:check":'prettier --check "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"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 dist/cli.js install","auth:login":"node dist/cli.js auth login","auth:logout":"node dist/cli.js auth logout","auth:status":"node dist/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:{},optionalDependencies:{keytar:"7.9.0"},devDependencies:{"@changesets/changelog-github":"^0.6.0","@changesets/cli":"^2.30.0","@types/jest":"^30.0.0","@types/node":"^25.8.0",jest:"^30.4.2","ts-jest":"^29.4.9",tsup:"^8.5.1","eslint-config-prettier":"^10.1.5",prettier:"^3.5.3",typescript:"^6.0.3","typescript-eslint":"^8.33.0"},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 ge={};$(ge,{bold:()=>V,cyan:()=>x,dim:()=>S,green:()=>N,red:()=>j,yellow:()=>y});function dt(t,e){return zn?r=>`\x1B[${t}m${r}\x1B[${e}m`:r=>r}var zn,N,j,y,x,V,S,pt=p(()=>{zn=!process.env.NO_COLOR&&process.stdout.isTTY;N=dt("32","39"),j=dt("31","39"),y=dt("33","39"),x=dt("36","39"),V=dt("1","22"),S=dt("2","22");});function nr(){return process.stdin.isTTY===true&&!process.argv.includes("--no-interactive")}var sr=p(()=>{});var ft={};$(ft,{checkForUpdate:()=>os,checkForUpdateInteractive:()=>is,isNewer:()=>Ct,primeUpdateCache:()=>as});function C(){return he||(he=qt()),he}function Ct(t,e){let r=o=>{let i=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return i?[+i[1],+i[2],+i[3]]:null},n=r(t),s=r(e);return !n||!s?false:s[0]!==n[0]?s[0]>n[0]:s[1]!==n[1]?s[1]>n[1]:s[2]>n[2]}function Ee(){try{let t=JSON.parse(E__namespace.default.readFileSync(ar,"utf8"));return typeof t.latestVersion!="string"||Date.now()-t.checkedAt>=es?null:t}catch{return null}}function cr(t,e,r=Date.now()){try{E__namespace.default.writeFileSync(ar,JSON.stringify({latestVersion:t,updatePriority:e??null,checkedAt:r}),{mode:384});}catch{}}function lr(t){let e=C().name,r=Zn__namespace.default.get(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`,{timeout:rs},n=>{if(n.statusCode!==200)return n.resume(),t(new Error(`HTTP ${n.statusCode}`));let s="";n.setEncoding("utf8"),n.on("data",o=>{s+=o;}),n.on("end",()=>{try{let o=JSON.parse(s);if(typeof o.version!="string")throw new Error("no version field");t(null,{version:o.version,updatePriority:typeof o.updatePriority=="string"?o.updatePriority:null});}catch(o){t(o);}});});r.on("error",t),r.on("timeout",()=>{r.destroy(new Error("timeout"));});}function we(t){let e=C().name,n=` Update available: ${C().version} \u2192 ${t}`,s=` Run: npm install -g ${e}`,o=Math.max(n.length,s.length)+2,i="\u2500".repeat(o);process.stderr.write(`
2
+ 'use strict';var Ln=require('https'),w=require('fs'),It=require('os'),pt=require('path'),child_process=require('child_process'),Hn=require('http'),util=require('util'),crypto=require('crypto');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var Ln__namespace=/*#__PURE__*/_interopNamespace(Ln);var w__namespace=/*#__PURE__*/_interopNamespace(w);var It__namespace=/*#__PURE__*/_interopNamespace(It);var pt__namespace=/*#__PURE__*/_interopNamespace(pt);var Hn__namespace=/*#__PURE__*/_interopNamespace(Hn);var oe=Object.defineProperty;var wn=Object.getOwnPropertyDescriptor;var Tn=Object.getOwnPropertyNames;var _n=Object.prototype.hasOwnProperty;var Bt=(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 p=(t,e)=>()=>(t&&(e=t(t=0)),e);var yn=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),U=(t,e)=>{for(var r in e)oe(t,r,{get:e[r],enumerable:true});},kn=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Tn(e))!_n.call(t,s)&&s!==r&&oe(t,s,{get:()=>e[s],enumerable:!(n=wn(e,s))||n.enumerable});return t};var N=t=>kn(oe({},"__esModule",{value:true}),t);var Ht=yn((ro,An)=>{An.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.6.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:"jest",typecheck:"tsc --noEmit",lint:"eslint src bin scripts",format:'prettier --write "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"format:check":'prettier --check "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"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 dist/cli.js install","auth:login":"node dist/cli.js auth login","auth:logout":"node dist/cli.js auth logout","auth:status":"node dist/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","@types/jest":"^30.0.0","@types/node":"^25.8.0",jest:"^30.4.2","ts-jest":"^29.4.9",tsup:"^8.5.1","eslint-config-prettier":"^10.1.5",prettier:"^3.5.3",typescript:"^6.0.3","typescript-eslint":"^8.33.0"},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 ie={};U(ie,{bold:()=>j,cyan:()=>H,dim:()=>E,green:()=>R,red:()=>B,yellow:()=>O});function it(t,e){return On?r=>`\x1B[${t}m${r}\x1B[${e}m`:r=>r}var On,R,B,O,H,j,E,at=p(()=>{On=!process.env.NO_COLOR&&process.stdout.isTTY;R=it("32","39"),B=it("31","39"),O=it("33","39"),H=it("36","39"),j=it("1","22"),E=it("2","22");});var jt={};U(jt,{checkForUpdate:()=>Fn,isNewer:()=>ce});function ct(){return ae||(ae=Ht()),ae}function ce(t,e){let r=o=>{let i=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return i?[+i[1],+i[2],+i[3]]:null},n=r(t),s=r(e);return !n||!s?false:s[0]!==n[0]?s[0]>n[0]:s[1]!==n[1]?s[1]>n[1]:s[2]>n[2]}function Pn(){try{let t=JSON.parse(w__namespace.default.readFileSync(Ve,"utf8"));return typeof t.latestVersion!="string"||Date.now()-t.checkedAt>=Nn?null:t}catch{return null}}function Cn(t,e){try{w__namespace.default.writeFileSync(Ve,JSON.stringify({latestVersion:t,updatePriority:e??null,checkedAt:Date.now()}),{mode:384});}catch{}}function Un(t){let e=ct().name,r=Ln__namespace.default.get(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`,{timeout:Rn},n=>{if(n.statusCode!==200)return n.resume(),t(new Error(`HTTP ${n.statusCode}`));let s="";n.setEncoding("utf8"),n.on("data",o=>{s+=o;}),n.on("end",()=>{try{let o=JSON.parse(s);if(typeof o.version!="string")throw new Error("no version field");t(null,{version:o.version,updatePriority:typeof o.updatePriority=="string"?o.updatePriority:null});}catch(o){t(o);}});});r.on("error",t),r.on("timeout",()=>{r.destroy(new Error("timeout"));});}function Be(t){let e=ct().name,n=` Update available: ${ct().version} \u2192 ${t}`,s=` Run: npm install -g ${e}`,o=Math.max(n.length,s.length)+2,i="\u2500".repeat(o);process.stderr.write(`
3
3
  \u256D${i}\u256E
4
4
  \u2502${n.padEnd(o)}\u2502
5
5
  \u2502${s.padEnd(o)}\u2502
6
6
  \u2570${i}\u256F
7
7
 
8
- `);}function Se(t){let e=C().name;process.stderr.write(`
8
+ `);}function He(t){let e=ct().name;process.stderr.write(`
9
9
  [${e}] Critical update detected \u2014 auto-updating to ${t}...
10
10
 
11
- `),child_process.spawn("npm",["install","-g",`${e}@${t}`],{detached:true,stdio:"ignore",windowsHide:true}).unref();}async function ns(t,e=1e4){let r=Nt("readline"),n=C().name,s=C().version;return process.stderr.write(`
12
- Update available: ${s} \u2192 ${t}
13
- Run: npm install -g ${n}@${t}
14
- Install now? [y/N]: `),new Promise(o=>{let i=r.createInterface({input:process.stdin,output:void 0,terminal:false}),c=false;function a(m){c||(c=true,clearTimeout(l),i.close(),process.stderr.write(`
15
- `),o(m));}let l=setTimeout(()=>a(false),e);i.once("line",m=>a(m.trim().toLowerCase()==="y")),i.once("close",()=>a(false));})}async function ss(t){let e=C().name;return process.stderr.write(` Installing ${e}@${t}...
16
- `),new Promise(r=>{let n=child_process.spawn("npm",["install","-g",`${e}@${t}`],{stdio:"inherit"});n.on("close",s=>{s!==0?process.stderr.write(` \u2717 Update failed \u2014 continuing with current version.
17
-
18
- `):process.stderr.write(` \u2713 Updated to ${t}. Please restart the command.
19
-
20
- `),r();}),n.on("error",()=>{process.stderr.write(` \u2717 Update failed \u2014 continuing with current version.
21
-
22
- `),r();});})}function os(){try{let t=Ee();if(t){Ct(C().version,t.latestVersion)&&(t.updatePriority==="auto"?Se(t.latestVersion):we(t.latestVersion));return}setImmediate(()=>{lr((e,r)=>{e||!r||(cr(r.version,r.updatePriority),Ct(C().version,r.version)&&(r.updatePriority==="auto"?Se(r.version):we(r.version)));});});}catch{}}async function is(t={}){try{let e=Ee();if(!e||!Ct(C().version,e.latestVersion))return;if(e.updatePriority==="auto"){Se(e.latestVersion);return}if(!nr()){we(e.latestVersion);return}await ns(e.latestVersion,t.timeoutMs)&&await ss(e.latestVersion);}catch{}}function as(){try{if(Ee())return;setImmediate(()=>{lr((t,e)=>{t||!e||Ct(C().version,e.version)&&cr(e.version,e.updatePriority,0);});});}catch{}}var he,ar,es,rs,mt=p(()=>{sr();ar=Et__namespace.default.join(Q__namespace.default.tmpdir(),"flow-obs-update-cache.json"),es=1440*60*1e3,rs=3e3;});function ur(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return {home:e,username:process.env.SUDO_USER}}return {home:Q__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||Q__namespace.userInfo().username}}function Y(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.USERPROFILE;if(!t){let r=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();r&&/^[A-Za-z]:\\/.test(r)&&(t=r);}if(t){let e=t.replace(/^([A-Za-z]):/,(r,n)=>`/mnt/${n.toLowerCase()}`).replace(/\\/g,"/");return Et__namespace.join(e,".claude","settings.json")}return Et__namespace.join(Q__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||Q__namespace.homedir();return Et__namespace.join(t,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return Et__namespace.join(e,".claude","settings.json")}return Et__namespace.join(Q__namespace.homedir(),".claude","settings.json")}function dr(){return process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER?`Running as root via sudo is not recommended.
11
+ `),child_process.spawn("npm",["install","-g",`${e}@${t}`],{detached:true,stdio:"ignore",windowsHide:true}).unref();}function Fn(){try{let t=Pn();if(t){ce(ct().version,t.latestVersion)&&(t.updatePriority==="auto"?He(t.latestVersion):Be(t.latestVersion));return}setImmediate(()=>{Un((e,r)=>{e||!r||(Cn(r.version,r.updatePriority),ce(ct().version,r.version)&&(r.updatePriority==="auto"?He(r.version):Be(r.version)));});});}catch{}}var ae,Ve,Nn,Rn,Vt=p(()=>{Ve=pt__namespace.default.join(It__namespace.default.tmpdir(),"flow-obs-update-cache.json"),Nn=1440*60*1e3,Rn=3e3;});var G,Q,Yt,Gt,Wt,le,Lt,lt,f,Kt,ut,Ye,P,Ge,F,T=p(()=>{G=process.env.FLOW_BASE_URL||"https://flow.ciandt.com",Q={AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${G}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${G}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${G}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${G}/otel`},Yt={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},Gt="FLOW-nodejs",Wt="config.json",le={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},Lt={ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${G}/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"},lt={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:Q.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"},f={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",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"},Kt={KEYCHAIN_ENABLED:false},ut={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3},Ye={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},P={FILE_PREFIX:"flow-obs-buffer-",DEFAULT_TTL_DAYS:4,MIN_TTL_DAYS:1,MAX_TTL_DAYS:30,DEFAULT_MAX_FILES:50,MIN_MAX_FILES:1,MAX_MAX_FILES:500,REPLAY_BATCH_SIZE:10},Ge="flow-ai-obs-debug.log",F={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60},{API_URL:process.env.FLOW_METRICS_URL||`${G}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"};});function l(...t){if(process.env[f.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
12
+ `;try{w.writeFileSync(Dn,e,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
13
+ `);}}var Dn,$=p(()=>{T();Dn=pt.join(It.tmpdir(),Ge);});function Vn(t){if(!jn.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}function Yn(t,e){let r=e.length>400?e.slice(0,400)+"\u2026":e;l("toAuthError",`status=${t} body=${r}`);try{let n=JSON.parse(e);if(typeof n.error=="string"&&(l("toAuthError",`api_error_code=${n.error}`+(n.message?` api_message=${n.message}`:"")),We[n.error]))return new Error(We[n.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 W(t){return new Promise((e,r)=>{try{Vn(t.tenant);}catch(u){return r(u)}let n=JSON.stringify({clientSecret:t.clientSecret}),s=new URL(Q.AUTH_ENGINE),o=s.protocol==="https:",i={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}};l("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let c=(o?Ln__namespace.default:Hn__namespace.default).request(i,u=>{let S=[];u.on("data",A=>S.push(A)),u.on("end",()=>{let A=S.join("");if((u.statusCode??0)>=400)return r(Yn(u.statusCode??0,A));let m;try{m=JSON.parse(A);}catch{return r(new Error("Invalid response from auth engine"))}let k=m.expires_at??new Date(Date.now()+(m.expires_in??3600)*1e3).toISOString();e({accessToken:m.access_token??"",expiresAt:k});});});c.on("error",u=>r(new Error(`Network error: ${u.message}`))),c.write(n),c.end();})}var jn,We,bt=p(()=>{T();$();jn=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;We={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 V(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.USERPROFILE;if(!t){let r=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();r&&/^[A-Za-z]:\\/.test(r)&&(t=r);}if(t){let e=t.replace(/^([A-Za-z]):/,(r,n)=>`/mnt/${n.toLowerCase()}`).replace(/\\/g,"/");return pt__namespace.join(e,".claude","settings.json")}return pt__namespace.join(It__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||It__namespace.homedir();return pt__namespace.join(t,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return pt__namespace.join(e,".claude","settings.json")}return pt__namespace.join(It__namespace.homedir(),".claude","settings.json")}function qe(){return process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER?`Running as root via sudo is not recommended.
23
14
  Configure npm to install globals without sudo:
24
15
  npm config set prefix '~/.npm-global'
25
- export PATH=~/.npm-global/bin:$PATH`:null}var Jt=p(()=>{});function gr(){if(process.platform==="win32"){let r=process.env.APPDATA||Et__namespace.join(Q__namespace.homedir(),"AppData","Roaming");return Et__namespace.join(r,pr,fr)}let t=ur(),e=process.env.XDG_CONFIG_HOME||Et__namespace.join(t.home,".config");return Et__namespace.join(e,pr,fr)}function hr(){try{let t=E__namespace.readFileSync(gr(),"utf8");return JSON.parse(t)}catch{return {}}}function ht(){return hr().baseUrl??null}function wr(t){let e=gr();E__namespace.mkdirSync(Et__namespace.dirname(e),{recursive:true});let n={...hr(),baseUrl:t};E__namespace.writeFileSync(e,JSON.stringify(n,null,2)+`
26
- `,{encoding:"utf8",mode:384});try{E__namespace.chmodSync(e,384);}catch{}}var pr,fr,ye=p(()=>{Jt();pr="flow-ai-obs",fr="config.json";});function _e(){return ht()??process.env.FLOW_BASE_URL??"https://flow.ciandt.com"}function et(){let t=_e();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${t}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${t}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${t}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${t}/otel`}}var Xt,cs,zt,Zt,Qt,Ae,Ut,rt,f,te,wt,Sr,U,Er,D,T=p(()=>{ye();Xt=ht()??process.env.FLOW_BASE_URL??"https://flow.ciandt.com";cs=et(),zt={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},Zt="FLOW-nodejs",Qt="config.json",Ae={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},Ut={ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${Xt}/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"},rt={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:cs.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"},f={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",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"},te={KEYCHAIN_ENABLED:false},wt={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3},Sr={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},U={FILE_PREFIX:"flow-obs-buffer-",DEFAULT_TTL_DAYS:4,MIN_TTL_DAYS:1,MAX_TTL_DAYS:30,DEFAULT_MAX_FILES:50,MIN_MAX_FILES:1,MAX_MAX_FILES:500,REPLAY_BATCH_SIZE:10},Er="flow-ai-obs-debug.log",D={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60},{API_URL:process.env.FLOW_METRICS_URL||`${Xt}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"};});function u(...t){if(process.env[f.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
27
- `;try{E.writeFileSync(ps,e,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
28
- `);}}var ps,M=p(()=>{T();ps=Et.join(Q.tmpdir(),Er);});function hs(t){if(!gs.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}function ws(t,e){let r=e.length>400?e.slice(0,400)+"\u2026":e;u("toAuthError",`status=${t} body=${r}`);try{let n=JSON.parse(e);if(typeof n.error=="string"&&(u("toAuthError",`api_error_code=${n.error}`+(n.message?` api_message=${n.message}`:"")),Tr[n.error]))return new nt(Tr[n.error])}catch{}return t===401||t===403||t===500?new nt("Invalid credentials"):t>=400&&t<500?new nt("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function G(t){return new Promise((e,r)=>{try{hs(t.tenant);}catch(l){return r(l)}let n=JSON.stringify({clientSecret:t.clientSecret}),s=new URL(et().AUTH_ENGINE),o=s.protocol==="https:",i={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}};u("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let a=(o?Zn__namespace.default:ms__namespace.default).request(i,l=>{let m=[];l.on("data",k=>m.push(k)),l.on("end",()=>{let k=m.join("");if((l.statusCode??0)>=400)return r(ws(l.statusCode??0,k));let g;try{g=JSON.parse(k);}catch{return r(new Error("Invalid response from auth engine"))}let O=g.expires_at??new Date(Date.now()+(g.expires_in??3600)*1e3).toISOString();e({accessToken:g.access_token??"",expiresAt:O});});});a.on("error",l=>r(new Error(`Network error: ${l.message}`))),a.write(n),a.end();})}var nt,gs,Tr,Ft=p(()=>{T();M();nt=class extends Error{constructor(e){super(e),this.name="AuthError";}},gs=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;Tr={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 yr(t){try{let e=E__namespace.statSync(t);Date.now()-e.mtimeMs>Ts&&E__namespace.unlinkSync(t);}catch{}try{E__namespace.writeFileSync(t,String(process.pid),{flag:"wx"});}catch(e){throw e.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+t):e}}function _r(t){try{E__namespace.unlinkSync(t);}catch{}}function ys(t,e){let n=(Array.isArray(t)?t:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(i=>!i.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [e,...n]}function Ar(){let t=Y(),e=t+".lock",r=[];E__namespace.mkdirSync(Et__namespace.dirname(t),{recursive:true}),yr(e);try{if(E__namespace.existsSync(t)){E__namespace.copyFileSync(t,t+".bkp");try{E__namespace.chmodSync(t+".bkp",384);}catch{}}let n={};try{n=JSON.parse(E__namespace.readFileSync(t,"utf8"));}catch{}let s=n.env&&typeof n.env=="object"?n.env:{};n.env={...rt,...Ut,...s},n.otelHeadersHelper="flow-ai-obs otel-headers",(!n.hooks||typeof n.hooks!="object"||Array.isArray(n.hooks))&&(n.hooks={});let o=(a,l)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${a}`,timeout:l}]}),i=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],c=n.hooks;for(let a of i){let l=ys(c[a],o(a,Sr[a]));l.length>1&&r.push(a),c[a]=l;}E__namespace.writeFileSync(t,JSON.stringify(n,null,2)+`
29
- `,{encoding:"utf8",mode:384});try{E__namespace.chmodSync(t,384);}catch{}}finally{_r(e);}return {settingsPath:t,preserved:r}}async function Or(t){let e;try{e=(await G(t)).accessToken;}catch{return false}return e?new Promise(r=>{Oe(`Bearer ${e}`,r,1);}):false}function Oe(t,e,r){let n=new URL(et().GATEWAY_TRACES),s=JSON.stringify({resourceSpans:[],validation_run:true}),o=n.protocol==="https:",i={hostname:n.hostname,port:n.port||(o?443:80),path:n.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:t,"Content-Length":Buffer.byteLength(s)}},a=(o?Zn__namespace:ms__namespace).request(i,l=>{l.resume(),l.statusCode===200||l.statusCode===204?e(true):r<wt.CONNECTIVITY_MAX_RETRY?setTimeout(()=>Oe(t,e,r+1),wt.CONNECTIVITY_RETRY_MS):e(false);});a.on("error",()=>{r<wt.CONNECTIVITY_MAX_RETRY?setTimeout(()=>Oe(t,e,r+1),wt.CONNECTIVITY_RETRY_MS):e(false);}),a.write(s),a.end();}function St(t){let e=Y(),r=e+".lock";E__namespace.mkdirSync(Et__namespace.dirname(e),{recursive:true}),yr(r);try{let n={};try{n=JSON.parse(E__namespace.readFileSync(e,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,t),E__namespace.writeFileSync(e,JSON.stringify(n,null,2)+`
30
- `,{encoding:"utf8",mode:384});try{E__namespace.chmodSync(e,384);}catch{}}finally{_r(r);}}var Ts,$t=p(()=>{T();Ft();Jt();Ts=wt.LOCK_STALE_MS;});function xt(){let t=Q__namespace.default.homedir();if(process.platform==="darwin")return Et__namespace.default.join(t,"Library","Preferences",Zt,Qt);if(process.platform==="win32"){let r=process.env.APPDATA??Et__namespace.default.join(t,"AppData","Roaming");return Et__namespace.default.join(r,Zt,Qt)}let e=process.env.XDG_CONFIG_HOME??Et__namespace.default.join(t,".config");return Et__namespace.default.join(e,Zt,Qt)}function ve(){try{let t=E__namespace.default.readFileSync(xt(),"utf8");return JSON.parse(t)}catch{return {}}}function kr(t){let e=xt();E__namespace.default.mkdirSync(Et__namespace.default.dirname(e),{recursive:true}),E__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var Le,ee,Lr=p(()=>{T();Le={credentials:"credentials","token-cache":"tokenCache"};ee=class{static isAvailable(){return true}static hasExistingData(){try{if(!E__namespace.default.existsSync(xt()))return !1;let e=JSON.parse(E__namespace.default.readFileSync(xt(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,r){let n=ve(),s=Le[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(e,r,n){let s=ve(),o=Le[r]??r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;kr(s);}async deleteSecret(e,r){let n=ve(),s=Le[r]??r;return s in n?(delete n[s],kr(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${xt()}`}};});var vr={};$(vr,{MacOsKeyVaultProvider:()=>be});var Ie,be,Ir=p(()=>{Ie=util.promisify(child_process.execFile),be=class{static async isAvailable(){try{return E.accessSync("/usr/bin/security",E.constants.X_OK),!0}catch{return false}}async getSecret(e,r){try{let{stdout:n}=await Ie("security",["find-generic-password","-w","-a",r,"-s",e]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await Ie("security",["add-generic-password","-U","-a",r,"-s",e,"-w",n]);}async deleteSecret(e,r){try{return await Ie("security",["delete-generic-password","-a",r,"-s",e]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};});var Rr={};$(Rr,{LinuxKeyVaultProvider:()=>Re});var br,Re,Pr=p(()=>{br=util.promisify(child_process.execFile),Re=class{static async isAvailable(){let e=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let r of e)try{return E.accessSync(r,E.constants.X_OK),!0}catch{}return false}async getSecret(e,r){try{let{stdout:n}=await br("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 i=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",r]);i.on("error",o),i.on("close",c=>{c===0?s():o(new Error(`secret-tool exited with code ${c}`));}),i.stdin.write(n),i.stdin.end();});}async deleteSecret(e,r){try{return await br("secret-tool",["clear","service",e,"account",r]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var Nr={};$(Nr,{WindowsKeyVaultProvider:()=>Pe});var Pe,Cr=p(()=>{Pe=class{static async isAvailable(){try{return await Nt("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(e,r){return Nt("keytar").getPassword(e,r)}async setSecret(e,r,n){await Nt("keytar").setPassword(e,r,n);}async deleteSecret(e,r){return Nt("keytar").deletePassword(e,r)}getStoragePath(){return "Windows Credential Manager"}};});async function Ur(){return await Ns()??new ee}async function Ns(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Ir(),vr));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Pr(),Rr));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Cr(),Nr));return await t.isAvailable()?new t:null}default:return null}}var Fr=p(()=>{Lr();});function yt(){return Ne||(Ne=Ur()),Ne}async function A(){let e=await(await yt()).getSecret(Tt,Ce);if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Fe(t){if(!t.clientId||!t.clientSecret||!t.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await yt()).setSecret(Tt,Ce,JSON.stringify(t));}async function $r(){let t=await yt();await t.deleteSecret(Tt,Ce),await t.deleteSecret(Tt,Ue);}async function Mt(t){await(await yt()).setSecret(Tt,Ue,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function _t(){let e=await(await yt()).getSecret(Tt,Ue);if(!e)return null;try{let r=JSON.parse(e);return {accessToken:r.accessToken,expiresAt:r.expiresAt,lastAuthCheckAt:r.lastAuthCheckAt}}catch{return null}}async function re(){let t=await _t();return t?new Date(t.expiresAt)>new Date:false}async function st(){let t=await _t();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 $e(){let t=await yt();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 xr(){let t=await A();return !!(t&&t.clientId&&t.clientSecret&&t.tenant)}var Tt,Ce,Ue,Ne,At=p(()=>{Fr();T();Tt=zt.SERVICE,Ce=zt.ACCOUNT_CREDS,Ue=zt.ACCOUNT_TOKEN,Ne=null;});function Us(t){return Cs.some(e=>e.test(t))}function Fs(t){if(!t)return null;try{let e=t.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}}function B(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let r=JSON.parse(Buffer.from(e[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 Dr(t){let e=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),r=Buffer.from(JSON.stringify({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant})).toString("base64url");return `${e}.${r}.`}function ne(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let r=process.env[f.FLOW_OBS_ALLOW_HTTP]==="true";if(!r&&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(!r&&Us(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function Mr(){let t=B(process.env[f.ANTHROPIC_AUTH_TOKEN]);if(t)return {user:await st().catch(()=>null)??t.clientId,tenant:t.tenant};if(te.KEYCHAIN_ENABLED)try{let e=await A();if(!e)return {user:"",tenant:""};let r=await st()??e.clientId??"",n=e.tenant??"";return {user:r,tenant:n}}catch{return {user:"",tenant:""}}return {user:"",tenant:""}}function $s(){return new Date().toISOString().slice(0,10)}async function xs(t){let e=$s(),r=await _t();if(r?.lastAuthCheckAt!==e){u("getOrRefreshToken",`daily auth check (last: ${r?.lastAuthCheckAt??"never"})`);try{let o=await G(t);try{await Mt({...o,lastAuthCheckAt:e});}catch{}return u("getOrRefreshToken",`daily check passed, expires=${o.expiresAt}`),o.accessToken}catch(o){if(o instanceof nt)throw o;u("getOrRefreshToken",`daily check network error \u2014 using cache: ${o.message}`);}}let n=r!=null&&new Date(r.expiresAt)>new Date;if(u("getOrRefreshToken",`cacheValid=${n}`),n)return u("getOrRefreshToken",`using cached token, expires=${r.expiresAt}`),r.accessToken;u("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let s=await G(t);try{await Mt({...s,lastAuthCheckAt:e});}catch(o){u("getOrRefreshToken",`token cache save failed (non-fatal): ${o.message}`);}return u("getOrRefreshToken",`token refreshed, expires=${s.expiresAt}`),s.accessToken}function Ds(t,e){let r=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function Ms(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 ot(){let t=[],e=process.env[f.ANTHROPIC_MODEL]??"",r=B(process.env[f.ANTHROPIC_AUTH_TOKEN]);u("resolveCredentials",r?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),r&&u("resolveCredentials",`clientId=${r.clientId}`,`tenant=${r.tenant}`),!r&&te.KEYCHAIN_ENABLED&&(r=await A(),r&&u("resolveCredentials","credentials resolved from keychain (FEATURES.KEYCHAIN_ENABLED=true)"));let n=r?r.tenant:"",s=process.env[f.FLOW_TELEMETRY]==="true",o=process.env[f.LANGFUSE_BASE_URL],i=process.env[f.LANGFUSE_PUBLIC_KEY],c=process.env[f.LANGFUSE_SECRET_KEY];if(s&&o&&i&&c){let g="",O=n;if(r)g=await st().catch(()=>null)??r.clientId;else if(te.KEYCHAIN_ENABLED)try{let v=await A();v&&(g=await st()??v.clientId,O=v.tenant);}catch{}let _={user:g??"",tenant:O??"",team:"",project:"",model:e};t.push({mode:"direct",...Ms(ne(o),i,c),..._}),u("resolveCredentials","direct mode active",`user=${_.user}`,`tenant=${_.tenant}`);}if(!r){if(t.length===0){let g=[];return g.authError=false,g}return t}let a;try{a=await xs(r);}catch(g){if(u("resolveCredentials",`token refresh failed: ${g.message}`,`(tenant=${r.tenant} clientId=${r.clientId})`),t.length>0)return t.authError=true,t;let O=[];return O.authError=true,O}let m={user:Fs(a)??r.clientId,tenant:n,team:"",project:"",model:e},k=process.env[f.FLOW_TELEMETRY_GATEWAY]??_e();return t.push({mode:"gateway",...Ds(ne(k),{accessToken:a}),...m}),t}async function Br(){return (await ot()).length>0}var Cs,q=p(()=>{At();Ft();T();M();Cs=[/^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 xe(){return Et__namespace.default.join(Q__namespace.default.homedir(),".claude","flow-obs",".logged-out")}function jr(){try{let t=xe();E__namespace.default.mkdirSync(Et__namespace.default.dirname(t),{recursive:!0}),E__namespace.default.writeFileSync(t,"",{mode:384});}catch{}}function Vr(){try{E__namespace.default.unlinkSync(xe());}catch{}}function oe(){try{return E__namespace.default.existsSync(xe())}catch{return false}}var Yr=p(()=>{});var De={};$(De,{runLogin:()=>Ot,runLogout:()=>Gs,runStatus:()=>Ws});function J(t){return typeof t=="string"?t.replace(Hs,""):t}function Bt(t,e={}){return new Promise((r,n)=>{let{masked:s=false,defaultValue:o=""}=e;process.stdout.write(t+o);let i=o;function c(){try{process.stdin.setRawMode(!1);}catch{}}process.once("uncaughtException",c),process.once("unhandledRejection",c);let a=m=>{if(m===""){l(),n(new Error("SIGINT"));return}if(m==="\r"||m===`
31
- `){l(),process.stdout.write(`
32
- `),r(i);return}if(m==="\x7F"){i.length>0&&(i=i.slice(0,-1),process.stdout.write("\b \b"));return}m.startsWith("\x1B")||(i+=m,process.stdout.write(s?"*".repeat(m.length):m));};function l(){process.stdin.setRawMode(false),process.stdin.removeListener("data",a),process.removeListener("uncaughtException",c),process.removeListener("unhandledRejection",c);}process.stdin.setRawMode(true),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",a);})}async function Gr(t){if(!oe())try{let e=await A();(!e||e.clientId!==t.clientId||e.clientSecret!==t.clientSecret||e.tenant!==t.tenant)&&await Fe(t);}catch{}}async function Wr(t){let{accessToken:e,expiresAt:r}=await G(t);await Fe(t),await Mt({accessToken:e,expiresAt:r}),Vr();try{let n=Dr(t);St({[f.ANTHROPIC_AUTH_TOKEN]:n});}catch{}}async function js(t){try{return await Wr(t),process.stdout.write(N(` \u2713 Setup complete. Tenant: ${J(t.tenant)}
33
-
34
- `)),0}catch(e){return process.stderr.write(j(` \u2717 Authentication failed: ${J(e.message)}
35
- `)),1}}async function Vs(){try{process.stdout.write(`
36
- `);let t=(await Bt(x(" ? ")+"Client ID: ")).trim(),e=(await Bt(x(" ? ")+"Client Secret: ",{masked:!0})).trim(),r=(await Bt(x(" ? ")+"Tenant: ")).trim();if(!t||!e||!r)return process.stderr.write(j(` \u2717 All fields are required
37
- `)),1;try{await Wr({clientId:t,clientSecret:e,tenant:r});}catch(n){return process.stderr.write(j(` \u2717 Authentication failed: ${J(n.message)}
38
- `)),1}return process.stdout.write(N(` \u2713 Setup complete. Tenant: ${J(r)}
39
- `)),process.stdout.write(` Storage: ${await $e()}
40
-
41
- `),0}catch(t){if(t.message==="SIGINT")throw t;return process.stderr.write(j(` \u2717 Unexpected error: ${t.message}
42
- `)),1}}async function Ot(t={}){if(t.clientId&&t.clientSecret&&t.tenant)return js({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant});let e=oe()?null:B(process.env[f.ANTHROPIC_AUTH_TOKEN]);e&&await Gr(e);let r=e||await A();if(r){process.stdout.write(`
43
- `),process.stdout.write(V(` Already authenticated
44
- `)),process.stdout.write(S(" Tenant: ")+J(r.tenant)+`
45
- `),process.stdout.write(S(" Client ID: ")+J(r.clientId)+`
16
+ export PATH=~/.npm-global/bin:$PATH`:null}var ue=p(()=>{});function Je(t){try{let e=w__namespace.statSync(t);Date.now()-e.mtimeMs>Kn&&w__namespace.unlinkSync(t);}catch{}try{w__namespace.writeFileSync(t,String(process.pid),{flag:"wx"});}catch(e){throw e.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+t):e}}function Xe(t){try{w__namespace.unlinkSync(t);}catch{}}function qn(t,e){let n=(Array.isArray(t)?t:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(i=>!i.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [e,...n]}function ze(){let t=V(),e=t+".lock",r=[];w__namespace.mkdirSync(pt__namespace.dirname(t),{recursive:true}),Je(e);try{if(w__namespace.existsSync(t)){w__namespace.copyFileSync(t,t+".bkp");try{w__namespace.chmodSync(t+".bkp",384);}catch{}}let n={};try{n=JSON.parse(w__namespace.readFileSync(t,"utf8"));}catch{}let s=n.env&&typeof n.env=="object"?n.env:{};n.env={...lt,...Lt,...s},n.otelHeadersHelper="flow-ai-obs otel-headers",(!n.hooks||typeof n.hooks!="object"||Array.isArray(n.hooks))&&(n.hooks={});let o=(c,u)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${c}`,timeout:u}]}),i=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],a=n.hooks;for(let c of i){let u=qn(a[c],o(c,Ye[c]));u.length>1&&r.push(c),a[c]=u;}w__namespace.writeFileSync(t,JSON.stringify(n,null,2)+`
17
+ `,{encoding:"utf8",mode:384});try{w__namespace.chmodSync(t,384);}catch{}}finally{Xe(e);}return {settingsPath:t,preserved:r}}async function Ze(t){let e;try{e=(await W(t)).accessToken;}catch{return false}return e?new Promise(r=>{de(`Bearer ${e}`,r,1);}):false}function de(t,e,r){let n=new URL(Q.GATEWAY_TRACES),s=JSON.stringify({resourceSpans:[],validation_run:true}),o=n.protocol==="https:",i={hostname:n.hostname,port:n.port||(o?443:80),path:n.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:t,"Content-Length":Buffer.byteLength(s)}},c=(o?Ln__namespace:Hn__namespace).request(i,u=>{u.resume(),u.statusCode===200||u.statusCode===204?e(true):r<ut.CONNECTIVITY_MAX_RETRY?setTimeout(()=>de(t,e,r+1),ut.CONNECTIVITY_RETRY_MS):e(false);});c.on("error",()=>{r<ut.CONNECTIVITY_MAX_RETRY?setTimeout(()=>de(t,e,r+1),ut.CONNECTIVITY_RETRY_MS):e(false);}),c.write(s),c.end();}function qt(t){let e=V(),r=e+".lock";w__namespace.mkdirSync(pt__namespace.dirname(e),{recursive:true}),Je(r);try{let n={};try{n=JSON.parse(w__namespace.readFileSync(e,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,t),w__namespace.writeFileSync(e,JSON.stringify(n,null,2)+`
18
+ `,{encoding:"utf8",mode:384});try{w__namespace.chmodSync(e,384);}catch{}}finally{Xe(r);}}var Kn,vt=p(()=>{T();bt();ue();Kn=ut.LOCK_STALE_MS;});function Nt(){let t=It__namespace.default.homedir();if(process.platform==="darwin")return pt__namespace.default.join(t,"Library","Preferences",Gt,Wt);if(process.platform==="win32"){let r=process.env.APPDATA??pt__namespace.default.join(t,"AppData","Roaming");return pt__namespace.default.join(r,Gt,Wt)}let e=process.env.XDG_CONFIG_HOME??pt__namespace.default.join(t,".config");return pt__namespace.default.join(e,Gt,Wt)}function me(){try{let t=w__namespace.default.readFileSync(Nt(),"utf8");return JSON.parse(t)}catch{return {}}}function Qe(t){let e=Nt();w__namespace.default.mkdirSync(pt__namespace.default.dirname(e),{recursive:true}),w__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var fe,Jt,tr=p(()=>{T();fe={credentials:"credentials","token-cache":"tokenCache"};Jt=class{static isAvailable(){return true}static hasExistingData(){try{if(!w__namespace.default.existsSync(Nt()))return !1;let e=JSON.parse(w__namespace.default.readFileSync(Nt(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,r){let n=me(),s=fe[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(e,r,n){let s=me(),o=fe[r]??r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;Qe(s);}async deleteSecret(e,r){let n=me(),s=fe[r]??r;return s in n?(delete n[s],Qe(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${Nt()}`}};});var er={};U(er,{MacOsKeyVaultProvider:()=>he});var ge,he,rr=p(()=>{ge=util.promisify(child_process.execFile),he=class{static async isAvailable(){try{return w.accessSync("/usr/bin/security",w.constants.X_OK),!0}catch{return false}}async getSecret(e,r){try{let{stdout:n}=await ge("security",["find-generic-password","-w","-a",r,"-s",e]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await ge("security",["add-generic-password","-U","-a",r,"-s",e,"-w",n]);}async deleteSecret(e,r){try{return await ge("security",["delete-generic-password","-a",r,"-s",e]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};});var sr={};U(sr,{LinuxKeyVaultProvider:()=>Se});var nr,Se,or=p(()=>{nr=util.promisify(child_process.execFile),Se=class{static async isAvailable(){let e=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let r of e)try{return w.accessSync(r,w.constants.X_OK),!0}catch{}return false}async getSecret(e,r){try{let{stdout:n}=await nr("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 i=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",r]);i.on("error",o),i.on("close",a=>{a===0?s():o(new Error(`secret-tool exited with code ${a}`));}),i.stdin.write(n),i.stdin.end();});}async deleteSecret(e,r){try{return await nr("secret-tool",["clear","service",e,"account",r]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var ir={};U(ir,{WindowsKeyVaultProvider:()=>Ee});var Ee,ar=p(()=>{Ee=class{static async isAvailable(){try{return await Bt("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(e,r){return Bt("keytar").getPassword(e,r)}async setSecret(e,r,n){await Bt("keytar").setPassword(e,r,n);}async deleteSecret(e,r){return Bt("keytar").deletePassword(e,r)}getStoragePath(){return "Windows Credential Manager"}};});async function cr(){return await os()??new Jt}async function os(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(rr(),er));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(or(),sr));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(ar(),ir));return await t.isAvailable()?new t:null}default:return null}}var lr=p(()=>{tr();});function mt(){return we||(we=cr()),we}async function y(){let e=await(await mt()).getSecret(ft,Te);if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function ye(t){if(!t.clientId||!t.clientSecret||!t.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await mt()).setSecret(ft,Te,JSON.stringify(t));}async function ur(){let t=await mt();await t.deleteSecret(ft,Te),await t.deleteSecret(ft,_e);}async function Xt(t){await(await mt()).setSecret(ft,_e,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt}));}async function gt(){let e=await(await mt()).getSecret(ft,_e);if(!e)return null;try{let r=JSON.parse(e);return {accessToken:r.accessToken,expiresAt:r.expiresAt}}catch{return null}}async function ht(){let t=await gt();return t?new Date(t.expiresAt)>new Date:false}async function tt(){let t=await gt();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 ke(){let t=await mt();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 dr(){let t=await y();return !!(t&&t.clientId&&t.clientSecret&&t.tenant)}var ft,Te,_e,we,St=p(()=>{lr();T();ft=Yt.SERVICE,Te=Yt.ACCOUNT_CREDS,_e=Yt.ACCOUNT_TOKEN,we=null;});function as(t){return is.some(e=>e.test(t))}function cs(t){if(!t)return null;try{let e=t.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}}function x(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let r=JSON.parse(Buffer.from(e[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 fr(t){let e=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),r=Buffer.from(JSON.stringify({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant})).toString("base64url");return `${e}.${r}.`}function pr(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let r=process.env[f.FLOW_OBS_ALLOW_HTTP]==="true";if(!r&&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(!r&&as(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function mr(){let t=x(process.env[f.ANTHROPIC_AUTH_TOKEN]);if(t)return {user:await tt().catch(()=>null)??t.clientId,tenant:t.tenant};if(Kt.KEYCHAIN_ENABLED)try{let e=await y();if(!e)return {user:"",tenant:""};let r=await tt()??e.clientId??"",n=e.tenant??"";return {user:r,tenant:n}}catch{return {user:"",tenant:""}}return {user:"",tenant:""}}async function ls(t){if(await ht()){let r=await gt();return l("getOrRefreshToken",`using cached token, expires=${r.expiresAt}`),r.accessToken}l("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let e=await W(t);try{await Xt(e);}catch(r){l("getOrRefreshToken",`token cache save failed (non-fatal): ${r.message}`);}return l("getOrRefreshToken",`token refreshed, expires=${e.expiresAt}`),e.accessToken}function us(t,e){let r=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function ds(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 et(){let t=[],e=process.env[f.ANTHROPIC_MODEL]??"",r=x(process.env[f.ANTHROPIC_AUTH_TOKEN]);l("resolveCredentials",r?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),!r&&Kt.KEYCHAIN_ENABLED&&(r=await y(),r&&l("resolveCredentials","credentials resolved from keychain (FEATURES.KEYCHAIN_ENABLED=true)"));let n=r?r.tenant:"",s=process.env[f.FLOW_TELEMETRY]==="true",o=process.env[f.LANGFUSE_BASE_URL],i=process.env[f.LANGFUSE_PUBLIC_KEY],a=process.env[f.LANGFUSE_SECRET_KEY];if(s&&o&&i&&a){let m="",k=n;if(r)m=await tt().catch(()=>null)??r.clientId;else if(Kt.KEYCHAIN_ENABLED)try{let L=await y();L&&(m=await tt()??L.clientId,k=L.tenant);}catch{}let _={user:m??"",tenant:k??"",team:"",project:"",model:e};t.push({mode:"direct",...ds(pr(o),i,a),..._}),l("resolveCredentials","direct mode active",`user=${_.user}`,`tenant=${_.tenant}`);}if(!r){if(t.length===0){let m=[];return m.authError=false,m}return t}let c;try{c=await ls(r);}catch(m){if(l("resolveCredentials",`token refresh failed: ${m.message}`,`(tenant=${r.tenant} clientId=${r.clientId})`),t.length>0)return t;let k=[];return k.authError=true,k}let S={user:cs(c)??r.clientId,tenant:n,team:"",project:"",model:e},A=process.env[f.FLOW_TELEMETRY_GATEWAY]??G;return t.push({mode:"gateway",...us(pr(A),{accessToken:c}),...S}),t}async function gr(){return (await et()).length>0}var is,K=p(()=>{St();bt();T();$();is=[/^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];});var Er={};U(Er,{runLogin:()=>J,runLogout:()=>hs,runStatus:()=>Ss});function q(t){return typeof t=="string"?t.replace(ps,""):t}function Pt(t,e={}){return new Promise((r,n)=>{let{masked:s=false,defaultValue:o=""}=e;process.stdout.write(t+o);let i=o;function a(){try{process.stdin.setRawMode(!1);}catch{}}process.once("uncaughtException",a),process.once("unhandledRejection",a);let c=S=>{if(S===""){u(),n(new Error("SIGINT"));return}if(S==="\r"||S===`
19
+ `){u(),process.stdout.write(`
20
+ `),r(i);return}if(S==="\x7F"){i.length>0&&(i=i.slice(0,-1),process.stdout.write("\b \b"));return}S.startsWith("\x1B")||(i+=S,process.stdout.write(s?"*".repeat(S.length):S));};function u(){process.stdin.setRawMode(false),process.stdin.removeListener("data",c),process.removeListener("uncaughtException",a),process.removeListener("unhandledRejection",a);}process.stdin.setRawMode(true),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",c);})}async function hr(t){try{let e=await y();(!e||e.clientId!==t.clientId||e.clientSecret!==t.clientSecret||e.tenant!==t.tenant)&&await ye(t);}catch{}}async function Sr(t){let{accessToken:e,expiresAt:r}=await W(t);await ye(t),await Xt({accessToken:e,expiresAt:r});try{let n=fr(t);qt({[f.ANTHROPIC_AUTH_TOKEN]:n});}catch{}}async function fs(t){try{return await Sr(t),process.stdout.write(R(` \u2713 Setup complete. Tenant: ${q(t.tenant)}
21
+
22
+ `)),0}catch(e){return process.stderr.write(B(` \u2717 Authentication failed: ${q(e.message)}
23
+ `)),1}}async function ms(){try{process.stdout.write(`
24
+ `);let t=(await Pt(H(" ? ")+"Client ID: ")).trim(),e=(await Pt(H(" ? ")+"Client Secret: ",{masked:!0})).trim(),r=(await Pt(H(" ? ")+"Tenant: ")).trim();if(!t||!e||!r)return process.stderr.write(B(` \u2717 All fields are required
25
+ `)),1;try{await Sr({clientId:t,clientSecret:e,tenant:r});}catch(n){return process.stderr.write(B(` \u2717 Authentication failed: ${q(n.message)}
26
+ `)),1}return process.stdout.write(R(` \u2713 Setup complete. Tenant: ${q(r)}
27
+ `)),process.stdout.write(` Storage: ${await ke()}
28
+
29
+ `),0}catch(t){if(t.message==="SIGINT")throw t;return process.stderr.write(B(` \u2717 Unexpected error: ${t.message}
30
+ `)),1}}async function J(t={}){if(t.clientId&&t.clientSecret&&t.tenant)return fs({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant});let e=x(process.env[f.ANTHROPIC_AUTH_TOKEN]);e&&await hr(e);let r=e||await y();if(r){process.stdout.write(`
31
+ `),process.stdout.write(j(` Already authenticated
32
+ `)),process.stdout.write(E(" Tenant: ")+q(r.tenant)+`
33
+ `),process.stdout.write(E(" Client ID: ")+q(r.clientId)+`
46
34
  `),process.stdout.write(`
47
- `);let n;try{n=await Bt(x(" ? ")+"Re-authenticate? (y/N): ");}catch(s){if(s.message==="SIGINT")return process.stdout.write(`
48
- `),130;throw s}if(n.trim().toLowerCase()!=="y")return process.stdout.write(N(` \u2713 Using existing credentials.
35
+ `);let n;try{n=await Pt(H(" ? ")+"Re-authenticate? (y/N): ");}catch(s){if(s.message==="SIGINT")return process.stdout.write(`
36
+ `),130;throw s}if(n.trim().toLowerCase()!=="y")return process.stdout.write(R(` \u2713 Using existing credentials.
49
37
 
50
- `)),0}try{return await Vs()}catch(n){if(n.message==="SIGINT")return process.stdout.write(`
51
- `),130;throw n}}async function Ys(){try{return process.stdout.write(`
52
- `),(await Bt(x(" ? ")+"Are you sure? This will remove your local credentials. (y/N): ")).toLowerCase()!=="y"?(process.stdout.write(y(` \u26A0 Logout cancelled
38
+ `)),0}try{return await ms()}catch(n){if(n.message==="SIGINT")return process.stdout.write(`
39
+ `),130;throw n}}async function gs(){try{return process.stdout.write(`
40
+ `),(await Pt(H(" ? ")+"Are you sure? This will remove your local credentials. (y/N): ")).toLowerCase()!=="y"?(process.stdout.write(O(` \u26A0 Logout cancelled
53
41
  `)),0):null}catch(t){if(t.message==="SIGINT")return process.stdout.write(`
54
- `),130;throw t}}async function Gs(t=false){if(!await xr())return process.stdout.write(y(` \u26A0 You are not authenticated
55
- `)),0;if(!t){let e=await Ys();if(e!==null)return e}try{return await $r(),jr(),process.stdout.write(N(` \u2713 Credentials removed successfully
56
- `)),0}catch{return process.stderr.write(j(` \u2717 Error removing credentials
57
- `)),1}}async function Ws(){if(oe())return process.stdout.write(y(" \u26A0 Not authenticated. Run `flow-ai-obs auth login` to set up.\n")),0;let t=B(process.env[f.ANTHROPIC_AUTH_TOKEN]);t&&await Gr(t);let e=t||await A();if(!e)return process.stdout.write(y(" \u26A0 Not authenticated. Run `flow-ai-obs auth login` to set up.\n")),0;if(!t&&!await re())return process.stdout.write(y(" \u26A0 Session expired. Run `flow-ai-obs auth login` to re-authenticate.\n")),0;let r=e.clientSecret.length>4?"****...****"+e.clientSecret.slice(-4):"****",n=t?"ANTHROPIC_AUTH_TOKEN (settings.json)":await $e();return process.stdout.write(`
58
- `+V(` Authenticated
59
- `)),process.stdout.write(S(" Tenant: ")+J(e.tenant)+`
60
- `),process.stdout.write(S(" Client ID: ")+J(e.clientId)+`
61
- `),process.stdout.write(S(" Client Secret: ")+r+`
62
- `),process.stdout.write(S(" Storage: ")+n+`
63
-
64
- `),0}var Hs,Ht=p(()=>{At();Yr();Ft();q();$t();T();pt();Hs=/[\x00-\x08\x0B-\x1F\x7F]|\x1b\[[0-9;]*[a-zA-Z]/g;});var Xr={};$(Xr,{runInstall:()=>Me});function Ks(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux")return child_process.spawnSync("cmd.exe",["/c","where","claude"],{encoding:"utf8",timeout:5e3}).status===0;let t=process.platform==="win32"?"where":"which";return child_process.spawnSync(t,["claude"],{encoding:"utf8",timeout:5e3}).status===0}function qs(){try{let t=E__namespace.readFileSync(Y(),"utf8"),e=JSON.parse(t);return !!(e.env&&e.env[f.ANTHROPIC_AUTH_TOKEN])}catch{return false}}function Js(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}if(e.protocol!=="https:")throw new Error(`Custom URL must use HTTPS: ${t}`);let r=process.env[f.FLOW_OBS_ALLOW_HTTP];try{delete process.env[f.FLOW_OBS_ALLOW_HTTP],ne(t);}finally{r!==void 0&&(process.env[f.FLOW_OBS_ALLOW_HTTP]=r);}if(e.pathname!=="/"&&e.pathname!=="")throw new Error(`Custom URL must be a base URL with no path beyond the root.
65
- Received: ${t}
66
- Expected: https://tenant.example.com`);if(e.search)throw new Error(`Custom URL must not contain query parameters.
67
- Received: ${t}
68
- Expected: https://tenant.example.com`);if(e.hash)throw new Error(`Custom URL must not contain fragment.
69
- Received: ${t}
70
- Expected: https://tenant.example.com`);return t.replace(/\/$/,"")}async function Me(t={}){if(!Ks()){let a=qr[process.platform]||qr.linux;return process.stderr.write(`
71
- `+j(` \u2717 Claude Code is not installed or not found in PATH.
42
+ `),130;throw t}}async function hs(t=false){if(!await dr())return process.stdout.write(O(` \u26A0 You are not authenticated
43
+ `)),0;if(!t){let e=await gs();if(e!==null)return e}try{return await ur(),process.stdout.write(R(` \u2713 Credentials removed successfully
44
+ `)),0}catch{return process.stderr.write(B(` \u2717 Error removing credentials
45
+ `)),1}}async function Ss(){let t=x(process.env[f.ANTHROPIC_AUTH_TOKEN]);t&&await hr(t);let e=t||await y();if(!e)return process.stdout.write(O(" \u26A0 Not authenticated. Run `flow-ai-obs auth login` to set up.\n")),0;if(!t&&!await ht())return process.stdout.write(O(" \u26A0 Session expired. Run `flow-ai-obs auth login` to re-authenticate.\n")),0;let r=e.clientSecret.length>4?"****...****"+e.clientSecret.slice(-4):"****",n=t?"ANTHROPIC_AUTH_TOKEN (settings.json)":await ke();return process.stdout.write(`
46
+ `+j(` Authenticated
47
+ `)),process.stdout.write(E(" Tenant: ")+q(e.tenant)+`
48
+ `),process.stdout.write(E(" Client ID: ")+q(e.clientId)+`
49
+ `),process.stdout.write(E(" Client Secret: ")+r+`
50
+ `),process.stdout.write(E(" Storage: ")+n+`
51
+
52
+ `),0}var ps,Ct=p(()=>{St();bt();K();vt();T();at();ps=/[\x00-\x08\x0B-\x1F\x7F]|\x1b\[[0-9;]*[a-zA-Z]/g;});var yr={};U(yr,{runInstall:()=>Ae});function Es(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux")return child_process.spawnSync("cmd.exe",["/c","where","claude"],{encoding:"utf8",timeout:5e3}).status===0;let t=process.platform==="win32"?"where":"which";return child_process.spawnSync(t,["claude"],{encoding:"utf8",timeout:5e3}).status===0}function ws(){try{let t=w__namespace.readFileSync(V(),"utf8"),e=JSON.parse(t);return !!(e.env&&e.env[f.ANTHROPIC_AUTH_TOKEN])}catch{return false}}async function Ae(){if(!Es()){let n=Tr[process.platform]||Tr.linux;return process.stderr.write(`
53
+ `+B(` \u2717 Claude Code is not installed or not found in PATH.
72
54
 
73
55
  `)+` flow-ai-obs requires Claude Code to function.
74
56
  Install it with:
75
57
 
76
- `+x(` ${a}`)+`
77
-
78
- `),1}process.env.WSL_DISTRO_NAME&&process.platform==="linux"&&process.stdout.write(y(` \u26A0 WSL detected.
79
- `)+y(` Claude Code runs on Windows and can only call tools installed there.
80
- `)+y(" Install flow-ai-obs on Windows too: ")+x(`npm install -g @ciandt-flow/flow-ai-obs
81
-
82
- `));let e=null,r=null;if(t.url){let a;try{a=Js(t.url);}catch(m){return process.stderr.write(`
83
- \u2717 Invalid --custom-url: ${m.message}
58
+ `+H(` ${n}`)+`
84
59
 
85
- `),1}let l=ht();try{wr(a);}catch(m){return process.stderr.write(`
86
- \u2717 Failed to persist custom URL: ${m.message}
60
+ `),1}if(!ws()){process.stdout.write(O(` \u26A0 No credentials found in settings.json \u2014 authentication required.
87
61
 
88
- `),1}e=a,r={OTEL_EXPORTER_OTLP_ENDPOINT:`${a}/otel`,ANTHROPIC_BASE_URL:`${a}/flow-llm-proxy/`},l&&l!==a&&process.stdout.write(y(` \u26A0 Base URL updated.
89
- `)+S(` Previous: ${l}
90
- `)+S(` New: ${a}
91
-
92
- `));}if(!qs()){process.stdout.write(y(` \u26A0 No credentials found in settings.json \u2014 authentication required.
93
-
94
- `));let{runLogin:a}=await Promise.resolve().then(()=>(Ht(),De)),l=await a();if(l!==0)return l}let n,s;try{(({settingsPath:n,preserved:s}=Ar())),r&&St(r);}catch(a){return process.stderr.write(` \u2717 Failed to write settings: ${a.message}
62
+ `));let n=await J();if(n!==0)return n}let t,e;try{({settingsPath:t,preserved:e}=ze());}catch(n){return process.stderr.write(` \u2717 Failed to write settings: ${n.message}
95
63
  `),1}process.stdout.write(`
96
- `+V(" Native OTEL configured")+` (metrics & logs)
97
- `);let o=r?{...rt,OTEL_EXPORTER_OTLP_ENDPOINT:r.OTEL_EXPORTER_OTLP_ENDPOINT}:rt;for(let[a,l]of Object.entries(o))process.stdout.write(S(` ${a.padEnd(36)}`)+l+`
64
+ `+j(" Native OTEL configured")+` (metrics & logs)
65
+ `);for(let[n,s]of Object.entries(lt))process.stdout.write(E(` ${n.padEnd(36)}`)+s+`
98
66
  `);process.stdout.write(`
99
- `),process.stdout.write(V(" Hooks registered")+` (Langfuse trace capture)
100
- `),process.stdout.write(S(" UserPromptSubmit")+` \u2192 flow-ai-obs UserPromptSubmit (timeout: 5s)
101
- `),process.stdout.write(S(" PreToolUse ")+` \u2192 flow-ai-obs PreToolUse (timeout: 3s)
102
- `),process.stdout.write(S(" PostToolUse ")+` \u2192 flow-ai-obs PostToolUse (timeout: 10s)
103
- `),process.stdout.write(S(" Stop ")+` \u2192 flow-ai-obs Stop (timeout: 15s)
104
- `),s.length>0&&(process.stdout.write(`
105
- `),process.stdout.write(y(` \u26A0 Third-party hooks detected and preserved on: ${s.join(", ")}
106
- `)),process.stdout.write(S(` flow-ai-obs was prepended \u2014 it executes first.
67
+ `),process.stdout.write(j(" Hooks registered")+` (Langfuse trace capture)
68
+ `),process.stdout.write(E(" UserPromptSubmit")+` \u2192 flow-ai-obs UserPromptSubmit (timeout: 5s)
69
+ `),process.stdout.write(E(" PreToolUse ")+` \u2192 flow-ai-obs PreToolUse (timeout: 3s)
70
+ `),process.stdout.write(E(" PostToolUse ")+` \u2192 flow-ai-obs PostToolUse (timeout: 10s)
71
+ `),process.stdout.write(E(" Stop ")+` \u2192 flow-ai-obs Stop (timeout: 15s)
72
+ `),e.length>0&&(process.stdout.write(`
73
+ `),process.stdout.write(O(` \u26A0 Third-party hooks detected and preserved on: ${e.join(", ")}
74
+ `)),process.stdout.write(E(` flow-ai-obs was prepended \u2014 it executes first.
107
75
  `))),process.stdout.write(`
108
- `),process.stdout.write(S(" Settings: ")+n+`
109
- `),process.stdout.write(S(" Backup: ")+n+`.bkp
110
- `),process.stdout.write(S(" OTEL auth: flow-ai-obs otel-headers")+S(` (reads keychain at runtime)
111
- `));let i=e??ht()??process.env.FLOW_BASE_URL??"https://flow.ciandt.com";process.stdout.write(S(" Base URL: ")+i+`
112
- `),process.stdout.write(`
113
- `),process.stdout.write(N(` \u2713 Ready. Native OTEL + Langfuse trace capture active.
114
- `)),process.stdout.write(S(" Run `flow-ai-obs setup` to also configure the Flow LLM Proxy.\n\n"));let c=dr();return c&&process.stdout.write(y(` \u26A0 ${c}
115
-
116
- `)),0}var qr,Be=p(()=>{$t();T();pt();Jt();ye();q();qr={darwin:`npm install -g @anthropic-ai/claude-code
76
+ `),process.stdout.write(E(" Settings: ")+t+`
77
+ `),process.stdout.write(E(" Backup: ")+t+`.bkp
78
+ `),process.stdout.write(E(" OTEL auth: flow-ai-obs otel-headers")+E(` (reads keychain at runtime)
79
+ `)),process.stdout.write(`
80
+ `),process.stdout.write(R(` \u2713 Ready. Native OTEL + Langfuse trace capture active.
81
+ `)),process.stdout.write(E(" Run `flow-ai-obs setup` to also configure the Flow LLM Proxy.\n\n"));let r=qe();return r&&process.stdout.write(O(` \u26A0 ${r}
82
+
83
+ `)),0}var Tr,Oe=p(()=>{vt();T();at();ue();Ct();Tr={darwin:`npm install -g @anthropic-ai/claude-code
117
84
  or visit: https://claude.ai/download`,linux:"npm install -g @anthropic-ai/claude-code",win32:`npm install -g @anthropic-ai/claude-code
118
- or visit: https://claude.ai/download`};});var zr={};$(zr,{runSetup:()=>Xs});async function Xs(t={}){process.stdout.write(`
85
+ or visit: https://claude.ai/download`};});var kr={};U(kr,{runSetup:()=>Ts});async function Ts(t={}){process.stdout.write(`
119
86
  \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
120
87
  `),process.stdout.write(`\u2551 flow-ai-obs \u2014 setup \u2551
121
88
  `),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
122
89
 
123
- `);let e=await Ot(t);if(e!==0)return process.stderr.write(`
90
+ `);let e=await J(t);if(e!==0)return process.stderr.write(`
124
91
  Setup aborted. Run \`flow-ai-obs auth login\` to retry.
125
92
 
126
93
  `),e;process.stdout.write(`
127
- `);let r=await Me();if(r!==0)return r;try{St(Ut);}catch(s){process.stderr.write(` \u26A0 Could not write LLM Proxy config: ${s.message}
128
- `);}process.stdout.write(V(" Flow LLM Proxy configured")+` (model provider)
129
- `);for(let[s,o]of Object.entries(Ut))process.stdout.write(S(` ${s.padEnd(36)}`)+o+`
94
+ `);let r=await Ae();if(r!==0)return r;try{qt(Lt);}catch(s){process.stderr.write(` \u26A0 Could not write LLM Proxy config: ${s.message}
95
+ `);}process.stdout.write(j(" Flow LLM Proxy configured")+` (model provider)
96
+ `);for(let[s,o]of Object.entries(Lt))process.stdout.write(E(` ${s.padEnd(36)}`)+o+`
130
97
  `);process.stdout.write(`
131
98
  `),process.stdout.write(` Validating connectivity to Flow OTEL endpoint\u2026
132
- `);let n=await A();return n?await Or(n)?process.stdout.write(N(` \u2713 Connectivity validated \u2014 telemetry is active.
99
+ `);let n=await y();return n?await Ze(n)?process.stdout.write(R(` \u2713 Connectivity validated \u2014 telemetry is active.
133
100
 
134
- `)):process.stdout.write(y(` \u26A0 Could not reach the OTEL endpoint. Telemetry will activate once connectivity is restored.
101
+ `)):process.stdout.write(O(` \u26A0 Could not reach the OTEL endpoint. Telemetry will activate once connectivity is restored.
135
102
 
136
- `)):process.stdout.write(y(` \u26A0 Could not read stored credentials \u2014 skipping connectivity check.
103
+ `)):process.stdout.write(O(` \u26A0 Could not read stored credentials \u2014 skipping connectivity check.
137
104
 
138
- `)),process.stdout.write(N(` \u2713 Setup complete!
139
- `)),process.stdout.write(S(` Settings: ${Y()}
105
+ `)),process.stdout.write(R(` \u2713 Setup complete!
106
+ `)),process.stdout.write(E(` Settings: ${V()}
140
107
 
141
- `)),0}var Zr=p(()=>{T();pt();Ht();Be();$t();At();});var Qr={};$(Qr,{runOtelHeaders:()=>zs});async function zs(){let t=B(process.env[f.ANTHROPIC_AUTH_TOKEN]);if(!t)try{t=await A();}catch{return process.stderr.write(`[flow-ai-obs otel-headers] Failed to read credentials
108
+ `)),0}var Ar=p(()=>{T();at();Ct();Oe();vt();St();});var Or={};U(Or,{runOtelHeaders:()=>_s});async function _s(){let t=x(process.env[f.ANTHROPIC_AUTH_TOKEN]);if(!t)try{t=await y();}catch{return process.stderr.write(`[flow-ai-obs otel-headers] Failed to read credentials
142
109
  `),1}if(!t)return process.stderr.write(`[flow-ai-obs otel-headers] Not authenticated \u2014 run: flow-ai-obs auth login
143
- `),1;let e;try{e=(await G(t)).accessToken;}catch(r){return process.stderr.write(`[flow-ai-obs otel-headers] Token fetch failed: ${r.message}
110
+ `),1;let e;try{e=(await W(t)).accessToken;}catch(r){return process.stderr.write(`[flow-ai-obs otel-headers] Token fetch failed: ${r.message}
144
111
  `),1}return e?(process.stdout.write(`{"Authorization": "Bearer ${e}"}
145
112
  `),0):(process.stderr.write(`[flow-ai-obs otel-headers] Empty token received
146
- `),1)}var tn=p(()=>{At();Ft();q();T();});var rn={};$(rn,{runCheck:()=>Zs});function He(t){return !t||t.length<=8?"****":t.slice(0,4)+"****...****"+t.slice(-4)}function jt(t){process.stdout.write(` \u2713 ${t}
147
- `);}function ie(t){process.stdout.write(` \u26A0 ${t}
148
- `);}function ae(t){process.stdout.write(` \u2717 ${t}
149
- `);}function I(t){process.stdout.write(` ${t}
150
- `);}function b(){process.stdout.write(`
151
- `);}async function Zs(){b(),process.stdout.write(` flow-claude-observability \u2014 configuration check
152
- `),b(),process.stdout.write(` Auth
153
- `);let t=B(process.env[f.ANTHROPIC_AUTH_TOKEN]),e=t||await A();if(!e){ie("Not authenticated \u2014 starting setup..."),b();let c=await Ot();if(c!==0)return c;if(t=B(process.env[f.ANTHROPIC_AUTH_TOKEN]),e=t||await A(),!e)return ae("Authentication failed"),b(),1;b(),process.stdout.write(` Auth
154
- `);}if(!t&&!await re()){ie("Session expired \u2014 re-authenticating..."),b();let c=await Ot();if(c!==0)return c;b(),process.stdout.write(` Auth
155
- `);}let r=await st()||e.clientId;jt("Authenticated"),I(`Tenant: ${e.tenant}`),I(`User: ${r}`),b(),process.stdout.write(` Native OTEL
156
- `);let n={};try{let c=E__namespace.readFileSync(Y(),"utf8");n=JSON.parse(c).env||{};}catch{}let s=Object.keys(rt).filter(c=>!n[c]);if(s.length===0?(jt("All OTEL env vars present in settings.json"),I(`Endpoint: ${n.OTEL_EXPORTER_OTLP_ENDPOINT}`)):(ie(`${s.length} OTEL var(s) missing from settings.json \u2014 native metrics/logs disabled`),s.forEach(c=>ae(`Missing: ${c}`)),I("Run: flow-ai-obs install (restores missing vars automatically)")),b(),process.stdout.write(` Tracing
157
- `),process.env[f.FLOW_TELEMETRY]==="true"){jt("FLOW_TELEMETRY=true (direct mode enabled)");let c=[f.LANGFUSE_BASE_URL,f.LANGFUSE_PUBLIC_KEY,f.LANGFUSE_SECRET_KEY].filter(a=>!process.env[a]);c.length>0&&c.forEach(a=>ie(`Missing: ${a}`));}else I("FLOW_TELEMETRY not set \u2014 direct mode inactive (gateway mode may still be active)");let i=await ot();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"),I("For direct mode: set FLOW_TELEMETRY=true + LANGFUSE_BASE_URL + LANGFUSE_PUBLIC_KEY + LANGFUSE_SECRET_KEY"),I("For gateway mode: run flow-claude-observability auth login")),b(),1;for(let c of i)if(c.mode==="gateway"){let a=await _t();jt("Mode: gateway"),I(`Endpoint: ${c.endpoint}`),I(`Token: ${He(a?.accessToken)}`);}else c.mode==="direct"&&(jt("Mode: direct"),I(`Endpoint: ${c.endpoint}`),I(`PK: ${He(process.env[f.LANGFUSE_PUBLIC_KEY])}`),I(`SK: ${He(process.env[f.LANGFUSE_SECRET_KEY])}`));return b(),process.stdout.write(` All checks passed \u2014 observability is active.
158
- `),b(),0}var nn=p(()=>{At();q();$t();T();Ht();});function H(t,e){let r=typeof t=="object"?JSON.stringify(t):String(t??"");return r.length>e?r.slice(0,e)+" \u2026[truncated]":r}function ce(t,e=100){return String(t??"").split(`
159
- `)[0].slice(0,e).trim()}function je(){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 F(t){process.stdout.write(JSON.stringify(t));}var kt=p(()=>{});function X(){return String(BigInt(Date.now())*1000000n)}var Ve,it,Vt=p(()=>{Ve=()=>crypto.randomBytes(16).toString("hex"),it=()=>crypto.randomBytes(8).toString("hex");});function lo(t,e){let r=Et.resolve(t);if(!r.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return r}function Ye(t){if(!ao.test(t))throw new Error(`Invalid session ID: ${t}`);return lo(Et.join(Q.tmpdir(),`flow-obs-${t}.json`),co)}function Lt(t){let e=Ye(t);if(!E.existsSync(e))return null;try{return JSON.parse(E.readFileSync(e,"utf8"))}catch{return null}}function vt(t,e){E.writeFileSync(Ye(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function Ge(t){try{E.unlinkSync(Ye(t));}catch{}}var ao,co,Yt=p(()=>{ao=/^[0-9a-f-]{1,64}$/i,co=Et.normalize(Q.tmpdir())+Et.sep;});function ln(t){if(!t||!E.existsSync(t))return null;try{let e=E.readFileSync(t,"utf8").trimEnd().split(`
160
- `);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 We(t){if(!t||!E.existsSync(t))return null;try{let e=E.readFileSync(t,"utf8").trimEnd().split(`
161
- `),r=[],n=0,s=0;for(let o=e.length-1;o>=0;o--)try{let i=JSON.parse(e[o]);if(i.type==="user")break;if(i.type==="assistant"){let a=(i.message?.content??[]).filter(m=>m.type==="text").map(m=>m.text??"").join("");a&&r.unshift(a);let l=i.message?.usage??{};n+=(l.input_tokens??0)+(l.cache_read_input_tokens??0)+(l.cache_creation_input_tokens??0),s+=l.output_tokens??0;}}catch{}return !r.length&&n===0?null:{text:r.join(`
162
-
163
- `),inputTokens:n,outputTokens:s}}catch{}return null}var Ke=p(()=>{});function pn(t){return t.replace(":","/")}function le(t,e){if(!t)return null;let r=pn(t),n=[Et.join(Q.homedir(),".claude","skills",r,"SKILL.md"),Et.join(e??"",".claude","skills",r,"SKILL.md")];for(let s of n)if(E.existsSync(s))try{return E.readFileSync(s,"utf8")}catch{}return null}function fn(t){return t.split(`
164
- `)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function mn(t){return !!t.slashSkill||t.toolCalls.some(n=>n.tool==="Skill")?t.toolCalls.some(n=>n.tool==="Skill"&&!n.synthetic||wo.has(n.tool))?"complete":"prerequisite_required":null}function ue(t,e){if(!t)return null;let r=pn(t),n=[Et.join(Q.homedir(),".claude","skills",r),Et.join(e??"",".claude","skills",r)],s=null;for(let c of n)if(E.existsSync(Et.join(c,"SKILL.md"))){s=c;break}if(!s)return null;let o=[];function i(c,a){for(let l of E.readdirSync(c,{withFileTypes:true})){if(mo.has(l.name)||ho.has(l.name)||go.has(Et.extname(l.name)))continue;let m=a?`${a}/${l.name}`:l.name;l.isDirectory()?i(Et.join(c,l.name),m):o.push(m);}}return i(s,""),o.length>0?o:null}var mo,go,ho,wo,de=p(()=>{mo=new Set([".venv","__pycache__",".git","node_modules"]),go=new Set([".pyc",".pyo"]),ho=new Set(["SKILL.md",".DS_Store",".gitignore"]);wo=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);});async function qe(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:So})+`
165
- `);return}let r=t.session_id||"unknown",n=t.prompt||"",s=t.cwd||"",o=ln(t.transcript_path)||Ve(),i=fn(n),c=i?le(i,s):null,a=i?ue(i,s):null;vt(r,{traceId:Ve(),spanId:it(),startNs:X(),sessionId:r,prompt:n,cwd:s,traceName:o,transcriptPath:t.transcript_path||"",model:process.env[f.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:i,skillContent:c,skillArtifacts:a}),u("UserPromptSubmit",`sid=${r}`,`traceName=${o}`,`slashSkill=${i}`),F(t);}var So,gn=p(()=>{Vt();Yt();Ke();de();kt();M();T();So=`\u26D4 Your Flow API key has expired. You no longer have access to Claude Code through the Flow platform. To restore observability and access, visit ${Xt}/settings/api-keys to generate a new API key, then run: flow-ai-obs auth login`;});async function hn(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=Lt(e);s&&(s.pendingTool={name:r,inputStr:H(n,D.TOOL_INPUT),startNs:X()},vt(e,s)),u("PreToolUse",`sid=${e}`,`tool=${r}`,`stateFound=${!!s}`),F(t);}var wn=p(()=>{Vt();Yt();kt();M();T();});function d(t,e){return e==null||e===""?null:{key:t,value:{stringValue:String(e)}}}function at(...t){return t.filter(e=>e!==null)}function Sn(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:Eo,spans:Array.isArray(e)?e:[e]}]}]}}var Eo,w,En=p(()=>{T();Eo={name:Ae.SCOPE_NAME,version:Ae.SCOPE_VERSION},w={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 yn(t,e,r,n,s){if(process.env[f.FLOW_OBS_DEBUG]!=="1")return;let o=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(r)},response:{status:n,body:s}});try{E.writeFileSync(Tn,o+`
166
- `,{flag:"a",encoding:"utf8",mode:384}),u("sendTraces:dump",`request appendada em ${Tn}`);}catch(i){u("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function ko(t){let e=new URL(t),r=new URL(et().GATEWAY_HEALTH);return r.hostname=e.hostname,r.port=e.port,r.protocol=e.protocol,r}function _n(t,e){return new Promise((r,n)=>{let s=t._isSSL?Zn__namespace.default:ms__namespace.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let o=s.request(t,i=>{let c=[];i.on("data",a=>c.push(a)),i.on("end",()=>r({statusCode:i.statusCode??0,body:c.join("")}));});o.setTimeout(1e4,()=>{o.destroy(new Error("Request timeout"));}),o.on("error",i=>n(new Error(`Network error: ${i.message}`))),e&&o.write(e),o.end();})}async function An(t,e){let r;try{r=ko(t);}catch{return false}let n=r.protocol==="https:";try{let s={};e&&(s.Authorization=String(e).replace(/[\r\n]/g,""));let o=await _n({hostname:r.hostname,port:r.port||(n?443:80),path:r.pathname,method:"GET",headers:s,_isSSL:n},null);return u("checkHealth",`url=${r.href} status=${o.statusCode}`),o.statusCode>=200&&o.statusCode<300}catch{return false}}async function pe(t,e,r){let n=JSON.stringify(t),s=new URL(e),o=s.protocol==="https:",i=String(r).replace(/[\r\n]/g,""),c={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(n)};u("sendTraces:request",`POST ${e}`),u("sendTraces:request",`headers=${JSON.stringify({...c,Authorization:i.slice(0,20)+"\u2026"})}`),u("sendTraces:request",`body=${n.slice(0,500)}${n.length>500?"\u2026":""}`);try{let a=await _n({hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:c,_isSSL:o},n);return u("sendTraces:response",`status=${a.statusCode}`),yn(e,c,n,a.statusCode,a.body),a.statusCode}catch(a){return u("sendTraces:error",a.message),yn(e,c,n,0,a.message),0}}var Tn,On=p(()=>{T();M();Tn=Et.join(Q.tmpdir(),"flow-obs-requests.ndjson");});function Lo(){let t=parseInt(process.env[f.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(U.MIN_TTL_DAYS,Math.min(U.MAX_TTL_DAYS,t)):U.DEFAULT_TTL_DAYS)*24*60*60*1e3}function vo(){let t=parseInt(process.env[f.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(U.MIN_MAX_FILES,Math.min(U.MAX_MAX_FILES,t)):U.DEFAULT_MAX_FILES}function Ln(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return Et__namespace.default.join(Q__namespace.default.tmpdir(),`${U.FILE_PREFIX}${t}.json`)}function Xe(){let t=Q__namespace.default.tmpdir(),e;try{e=E__namespace.default.readdirSync(t);}catch{return []}return e.filter(r=>r.startsWith(U.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=Et__namespace.default.join(t,r),s=0;try{s=E__namespace.default.statSync(n).mtimeMs;}catch{}return {full:n,mtime:s}}).sort((r,n)=>r.mtime-n.mtime).map(r=>r.full)}function Gt(t){try{let e=vo(),r=Xe();if(r.length>=e){let o=r.slice(0,r.length-e+1);for(let i of o)try{E__namespace.default.unlinkSync(i);}catch{}}let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:n,bufferedAt:Date.now(),payload:t};return E__namespace.default.writeFileSync(Ln(n),JSON.stringify(s),{encoding:"utf8",mode:384}),u("buffer",`saved fileId=${n}`),n}catch(e){return u("buffer",`saveToBuffer failed: ${e.message}`),null}}function vn(t){let e=Xe(),r=t!=null&&t>0?t:e.length,n=[];for(let s of e){if(n.length>=r)break;try{let o=E__namespace.default.readFileSync(s,"utf8"),i=JSON.parse(o);i&&i.fileId&&i.payload&&n.push(i);}catch{u("buffer",`skipping malformed file: ${s}`);}}return n}function In(t){try{E__namespace.default.unlinkSync(Ln(t)),u("buffer",`deleted fileId=${t}`);}catch{}}function bn(){let t=Date.now()-Lo();for(let e of Xe())try{let{mtimeMs:r}=E__namespace.default.statSync(e);r<t&&(E__namespace.default.unlinkSync(e),u("buffer",`evicted stale: ${Et__namespace.default.basename(e)}`));}catch{}}var Rn=p(()=>{T();M();});async function Io(t){bn();let e=vn(U.REPLAY_BATCH_SIZE);e.length&&(u("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async r=>{try{let n=await pe(r.payload,t.endpoint,t.authHeader);n>=200&&n<300?(In(r.fileId),u("replayBufferedTraces",`replayed fileId=${r.fileId} status=${n}`)):u("replayBufferedTraces",`replay failed fileId=${r.fileId} status=${n}`);}catch(n){u("replayBufferedTraces",`replay error fileId=${r.fileId}: ${n.message}`);}})));}async function Pn(t){let e=await ot();if(!e.length)return e.authError&&(u("postToLangfuse","auth refresh failed \u2014 buffering trace"),Gt(t)),0;let r=await Promise.all(e.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await An(o.endpoint,o.authHeader);return {creds:o,healthy:i}})),n=r.find(o=>o.creds.mode==="gateway"&&o.healthy)?.creds??r.find(o=>o.creds.mode==="direct")?.creds;return n&&await Io(n),(await Promise.all(r.map(async({creds:o,healthy:i})=>{if(o.mode==="gateway"){if(!i)return u("postToLangfuse","gateway health check failed \u2014 buffering trace"),Gt(t),0;let a=await pe(t,o.endpoint,o.authHeader);return (a===0||a>=500)&&(u("postToLangfuse",`gateway send failed (status ${a}) \u2014 buffering trace`),Gt(t)),a}let c=await pe(t,o.endpoint,o.authHeader);return (c===0||c>=500)&&(u("postToLangfuse",`direct endpoint unavailable (status ${c}) \u2014 buffering trace`),Gt(t)),c}))).find(o=>o!==0)??0}var Nn=p(()=>{q();M();On();Rn();T();});var ze=p(()=>{En();Nn();});function bt(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return bo.reduce((r,{re:n,replace:s})=>r.replace(n,s),e)}var R,bo,Ze=p(()=>{R="[REDACTED]",bo=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${R}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${R}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${R}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${R}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,r)=>`${e}
167
- ${R}
168
- ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${R}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${R}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${R}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${R}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${R}`},{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}${R}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${R}@`}];});async function Cn(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=t.tool_response||"",o=Lt(e);if(!o){F(t);return}let i=X(),c=o.pendingTool,a=c?.name===r,l=a?c.startNs:String(BigInt(i)-200000000n),m=a?c.inputStr:H(n,D.TOOL_INPUT),k=m,g=null;if(r==="Skill"){let Pt=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||n.commandName||String(Object.values(n)[0]??""):String(n);g=Pt?String(Pt).trim():null;let ut=g?le(g,o.cwd):null;ut&&(k=ut,o.skillContent||(o.skillContent=ut),o.skillArtifacts||(o.skillArtifacts=ue(g,o.cwd))),g&&!o.slashSkill&&(o.slashSkill=g),u("PostToolUse","Skill tool detected",`skillName=${g}`,`contentFound=${!!ut}`);}let O=bt(H(s,D.TOOL_OUTPUT)),_=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(O.slice(0,500)),v=_?"ERROR":"DEFAULT",Kt=it(),lt=Math.round(Number(BigInt(i)-BigInt(l))/1e6),Rt={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL",fe=r==="Skill"&&g?g:ce(m,60);o.toolCalls.push({tool:r,brief:fe,error:_,durationMs:lt});let W=o.spans;W.push({traceId:o.traceId,spanId:Kt,parentSpanId:o.spanId,name:r,kind:3,startTimeUnixNano:l,endTimeUnixNano:i,attributes:at(d(w.OBS_NAME,r),d(w.OBS_TYPE,Rt),d(w.OBS_LEVEL,v),d(w.OBS_INPUT,bt(k)),d(w.OBS_OUTPUT,O),d("tool.name",r),d("tool.error",String(_)),r==="Skill"&&g?d("skill.name",g):null,r==="Skill"?d("skill.invocation","slash-command"):null),status:{code:_?2:1}}),o.pendingTool=null,vt(e,o),u("PostToolUse",`sid=${e}`,`tool=${r}`,`error=${_}`,`durationMs=${lt}`,`totalSpans=${W.length}`),F(t);}var Un=p(()=>{Vt();Yt();ze();kt();de();M();T();Ze();});function $n(t,e,r){let n=Object.keys(Fn).find(i=>(t??"").toLowerCase().includes(i));if(!n)return;let s=Fn[n],o=(e*s.input+r*s.output)/1e6;return Math.round(o*1e6)/1e6}var Fn,xn=p(()=>{Fn={"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}};});async function Dn(t){let e=t.session_id||"unknown",r=t.stop_reason||"end_turn",n=Lt(e);if(!n){F(t);return}n.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(n.slashSkill)&&(u("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${n.slashSkill}"`),n.slashSkill=null);let s=X(),o=await Mr(),i=n.toolCalls,c=n.spans;if(n.slashSkill&&!i.some(h=>h.tool==="Skill")){let h=it(),Z=n.skillContent?n.skillContent:JSON.stringify({skill:n.slashSkill});i.push({tool:"Skill",brief:n.slashSkill,error:false,durationMs:0,synthetic:true}),c.push({traceId:n.traceId,spanId:h,parentSpanId:n.spanId,name:"Skill",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:n.startNs,attributes:at(d(w.OBS_NAME,"Skill"),d(w.OBS_TYPE,"TOOL"),d(w.OBS_LEVEL,"DEFAULT"),d(w.OBS_INPUT,Z),d(w.OBS_OUTPUT,"loaded via slash command"),d("tool.name","Skill"),d("tool.error","false"),d("skill.name",n.slashSkill),d("skill.invocation","slash-command")),status:{code:1}}),u("Stop",`slashSkill=${n.slashSkill}`,"synthetic span injected");}let a=t.transcript_path||n.transcriptPath||"",l=We(a);if(a&&(i.some(h=>h.tool==="Skill"&&!h.synthetic)||!!n.slashSkill)&&!l?.text){await new Promise(Z=>setTimeout(Z,500));let h=We(a);h?.text&&(l=h);}u("Stop",`transcriptPath=${a||"(empty)"}`,`assistantOut=${l?`text=${l.text.length}chars`:"null"}`);let k=i.length,g=i.filter(h=>h.error).length,O=bt(l?.text?H(l.text,D.TRACE_OUTPUT):k===0?"No tools used":i.map((h,Z)=>`${Z+1}. ${h.tool}${h.brief?` \u2192 ${h.brief}`:""}${h.error?" [ERROR]":""}`).join(`
169
- `)),_=l?.inputTokens??0,v=l?.outputTokens??0,Kt=i.map((h,Z)=>`${Z+1}. ${h.tool}${h.brief?` \u2192 ${h.brief}`:""}${h.error?" [ERROR]":""} (${h.durationMs}ms)`),lt=!!(n.slashSkill||i.some(h=>h.tool==="Skill")),Qe=i.some(h=>h.tool==="Agent");if(!lt&&!Qe){u("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),Ge(e),F(t);return}let Rt=lt?"skill":"agent",fe=Math.round(Number(BigInt(s)-BigInt(n.startNs))/1e6),tr=$n(n.model,_,v),W=mn(n);W==="prerequisite_required"&&l?.text&&(W="complete"),W==="prerequisite_required"&&(c.push({traceId:n.traceId,spanId:it(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:at(d(w.OBS_NAME,"prerequisite-check"),d(w.OBS_TYPE,"EVENT"),d(w.OBS_LEVEL,"WARNING"),d(w.OBS_OUTPUT,O),d("skill.name",n.slashSkill||void 0),d("execution_status","prerequisite_required")),status:{code:1}}),u("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${n.slashSkill}`));let Pt=(()=>{if(!(!lt||!n.prompt)){if(n.slashSkill){let h=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return h?H(h,D.USER_INSTRUCTION):void 0}return H(n.prompt,D.USER_INSTRUCTION)||void 0}})(),ut=JSON.stringify({trace_type:Rt,...W!==null&&{execution_status:W},...n.slashSkill?{skill_name:n.slashSkill}:{},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...Pt!==void 0&&{user_instruction:Pt},latency_ms:fe,..._&&{tokens_input:_},...v&&{tokens_output:v},cost_usd:tr,...n.model?{model:n.model}:{},toolCount:k,errorCount:g,stopReason:r,sessionId:n.sessionId,tools:Kt.length?Kt:void 0}),er=bt(H(n.prompt,D.TRACE_INPUT)),Hn=at(d(w.TRACE_NAME,n.traceName),d(w.TRACE_INPUT,er),d(w.TRACE_OUTPUT,O),d(w.OBS_INPUT,er),d(w.OBS_OUTPUT,O),d(w.TRACE_METADATA,ut),d(w.SESSION_ID,n.sessionId),d(w.USER_ID,o.user),d(w.OBS_TYPE,"GENERATION"),d(w.MODEL,n.model),_?d(w.INPUT_TOKENS,_):null,v?d(w.OUTPUT_TOKENS,v):null,d("claude.stop_reason",r),d("claude.tool_count",String(k)),d("claude.error_count",String(g)),d("claude.session_id",n.sessionId),d("flow.trace_type",Rt),{key:w.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:Rt}]}}}),jn={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:Hn,status:{code:g>0?2:1}},Vn=at(d("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),d("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),rr=[...c,jn];u("Stop",`sid=${e}`,`totalTools=${k}`,`errorTools=${g}`,`spans=${rr.length}`,`inputTokens=${_}`,`outputTokens=${v}`,`traceOutput="${ce(O,80)}"`);let Yn=await Pn(Sn(Vn,rr));u("Stop",`POST status=${Yn}`,`traceId=${n.traceId}`),Ge(e),F(t);}var Mn=p(()=>{Vt();Yt();ze();q();xn();Ke();kt();M();de();Ze();T();});async function Ro(){let t=process.argv[2];if(t==="UserPromptSubmit"){let r=await je(),n;try{n=await ot();}catch{process.stdout.write(JSON.stringify(r));return}n.authError?await qe(r,true):n.length>0?await qe(r):process.stdout.write(JSON.stringify(r));return}if(!await Br()){let r=[];process.stdin.on("data",n=>r.push(n)),process.stdin.on("end",()=>process.stdout.write(r.join("")));return}let e=await je();switch(t){case "PreToolUse":await hn(e);break;case "PostToolUse":await Cn(e);break;case "Stop":await Dn(e);break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
170
- `),process.stdout.write(JSON.stringify(e));}}var Bn=p(()=>{q();kt();gn();wn();Un();Mn();Ro().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
171
- `),process.exit(0);});});var No=new Set(["UserPromptSubmit","PreToolUse","PostToolUse","Stop"]),[,,P,Wt]=process.argv;function ct(t,e){let r=t.indexOf(e);return r!==-1?t[r+1]:void 0}if(P==="--version"||P==="-v"){let{version:t}=qt();process.stdout.write(t+`
172
- `),process.exit(0);}else if(P==="--help"||P==="-h"){let{bold:t,cyan:e,dim:r}=(pt(),L(ge)),{version:n}=qt();process.stdout.write(`
113
+ `),1)}var Lr=p(()=>{St();bt();K();T();});var Ir={};U(Ir,{runCheck:()=>ys});function Le(t){return !t||t.length<=8?"****":t.slice(0,4)+"****...****"+t.slice(-4)}function Ut(t){process.stdout.write(` \u2713 ${t}
114
+ `);}function zt(t){process.stdout.write(` \u26A0 ${t}
115
+ `);}function Zt(t){process.stdout.write(` \u2717 ${t}
116
+ `);}function b(t){process.stdout.write(` ${t}
117
+ `);}function I(){process.stdout.write(`
118
+ `);}async function ys(){I(),process.stdout.write(` flow-claude-observability \u2014 configuration check
119
+ `),I(),process.stdout.write(` Auth
120
+ `);let t=x(process.env[f.ANTHROPIC_AUTH_TOKEN]),e=t||await y();if(!e){zt("Not authenticated \u2014 starting setup..."),I();let a=await J();if(a!==0)return a;if(t=x(process.env[f.ANTHROPIC_AUTH_TOKEN]),e=t||await y(),!e)return Zt("Authentication failed"),I(),1;I(),process.stdout.write(` Auth
121
+ `);}if(!t&&!await ht()){zt("Session expired \u2014 re-authenticating..."),I();let a=await J();if(a!==0)return a;I(),process.stdout.write(` Auth
122
+ `);}let r=await tt()||e.clientId;Ut("Authenticated"),b(`Tenant: ${e.tenant}`),b(`User: ${r}`),I(),process.stdout.write(` Native OTEL
123
+ `);let n={};try{let a=w__namespace.readFileSync(V(),"utf8");n=JSON.parse(a).env||{};}catch{}let s=Object.keys(lt).filter(a=>!n[a]);if(s.length===0?(Ut("All OTEL env vars present in settings.json"),b(`Endpoint: ${n.OTEL_EXPORTER_OTLP_ENDPOINT}`)):(zt(`${s.length} OTEL var(s) missing from settings.json \u2014 native metrics/logs disabled`),s.forEach(a=>Zt(`Missing: ${a}`)),b("Run: flow-ai-obs install (restores missing vars automatically)")),I(),process.stdout.write(` Tracing
124
+ `),process.env[f.FLOW_TELEMETRY]==="true"){Ut("FLOW_TELEMETRY=true (direct mode enabled)");let a=[f.LANGFUSE_BASE_URL,f.LANGFUSE_PUBLIC_KEY,f.LANGFUSE_SECRET_KEY].filter(c=>!process.env[c]);a.length>0&&a.forEach(c=>zt(`Missing: ${c}`));}else b("FLOW_TELEMETRY not set \u2014 direct mode inactive (gateway mode may still be active)");let i=await et();if(!i||i.length===0)return i&&i.authError?Zt("Token refresh failed \u2014 gateway mode could not activate"):(Zt("No active destinations \u2014 no traces will be sent"),b("For direct mode: set FLOW_TELEMETRY=true + LANGFUSE_BASE_URL + LANGFUSE_PUBLIC_KEY + LANGFUSE_SECRET_KEY"),b("For gateway mode: run flow-claude-observability auth login")),I(),1;for(let a of i)if(a.mode==="gateway"){let c=await gt();Ut("Mode: gateway"),b(`Endpoint: ${a.endpoint}`),b(`Token: ${Le(c?.accessToken)}`);}else a.mode==="direct"&&(Ut("Mode: direct"),b(`Endpoint: ${a.endpoint}`),b(`PK: ${Le(process.env[f.LANGFUSE_PUBLIC_KEY])}`),b(`SK: ${Le(process.env[f.LANGFUSE_SECRET_KEY])}`));return I(),process.stdout.write(` All checks passed \u2014 observability is active.
125
+ `),I(),0}var vr=p(()=>{St();K();vt();T();Ct();});function M(t,e){let r=typeof t=="object"?JSON.stringify(t):String(t??"");return r.length>e?r.slice(0,e)+" \u2026[truncated]":r}function Qt(t,e=100){return String(t??"").split(`
126
+ `)[0].slice(0,e).trim()}function Nr(){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 C(t){process.stdout.write(JSON.stringify(t));}var Et=p(()=>{});function X(){return String(BigInt(Date.now())*1000000n)}var be,rt,Ft=p(()=>{be=()=>crypto.randomBytes(16).toString("hex"),rt=()=>crypto.randomBytes(8).toString("hex");});function Cs(t,e){let r=pt.resolve(t);if(!r.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return r}function Ie(t){if(!Rs.test(t))throw new Error(`Invalid session ID: ${t}`);return Cs(pt.join(It.tmpdir(),`flow-obs-${t}.json`),Ps)}function wt(t){let e=Ie(t);if(!w.existsSync(e))return null;try{return JSON.parse(w.readFileSync(e,"utf8"))}catch{return null}}function Tt(t,e){w.writeFileSync(Ie(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function ve(t){try{w.unlinkSync(Ie(t));}catch{}}var Rs,Ps,$t=p(()=>{Rs=/^[0-9a-f-]{1,64}$/i,Ps=pt.normalize(It.tmpdir())+pt.sep;});function Fr(t){if(!t||!w.existsSync(t))return null;try{let e=w.readFileSync(t,"utf8").trimEnd().split(`
127
+ `);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 Ne(t){if(!t||!w.existsSync(t))return null;try{let e=w.readFileSync(t,"utf8").trimEnd().split(`
128
+ `),r=[],n=0,s=0;for(let o=e.length-1;o>=0;o--)try{let i=JSON.parse(e[o]);if(i.type==="user")break;if(i.type==="assistant"){let c=(i.message?.content??[]).filter(S=>S.type==="text").map(S=>S.text??"").join("");c&&r.unshift(c);let u=i.message?.usage??{};n+=(u.input_tokens??0)+(u.cache_read_input_tokens??0)+(u.cache_creation_input_tokens??0),s+=u.output_tokens??0;}}catch{}return !r.length&&n===0?null:{text:r.join(`
129
+
130
+ `),inputTokens:n,outputTokens:s}}catch{}return null}var Re=p(()=>{});function Mr(t){return t.replace(":","/")}function te(t,e){if(!t)return null;let r=Mr(t),n=[pt.join(It.homedir(),".claude","skills",r,"SKILL.md"),pt.join(e??"",".claude","skills",r,"SKILL.md")];for(let s of n)if(w.existsSync(s))try{return w.readFileSync(s,"utf8")}catch{}return null}function Dr(t){return t.split(`
131
+ `)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function Br(t){return !!t.slashSkill||t.toolCalls.some(n=>n.tool==="Skill")?t.toolCalls.some(n=>n.tool==="Skill"&&!n.synthetic||Bs.has(n.tool))?"complete":"prerequisite_required":null}function ee(t,e){if(!t)return null;let r=Mr(t),n=[pt.join(It.homedir(),".claude","skills",r),pt.join(e??"",".claude","skills",r)],s=null;for(let a of n)if(w.existsSync(pt.join(a,"SKILL.md"))){s=a;break}if(!s)return null;let o=[];function i(a,c){for(let u of w.readdirSync(a,{withFileTypes:true})){if(xs.has(u.name)||Ds.has(u.name)||Ms.has(pt.extname(u.name)))continue;let S=c?`${c}/${u.name}`:u.name;u.isDirectory()?i(pt.join(a,u.name),S):o.push(S);}}return i(s,""),o.length>0?o:null}var xs,Ms,Ds,Bs,re=p(()=>{xs=new Set([".venv","__pycache__",".git","node_modules"]),Ms=new Set([".pyc",".pyo"]),Ds=new Set(["SKILL.md",".DS_Store",".gitignore"]);Bs=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);});async function Hr(t){let e=t.session_id||"unknown",r=t.prompt||"",n=t.cwd||"";try{(await et()).authError===!0&&(process.stderr.write(`
132
+ \u26A0 flow-ai-obs: Your Flow credentials have expired.
133
+ Traces will not be captured until you re-authenticate.
134
+ Run: flow-ai-obs auth login
135
+
136
+ `),l("UserPromptSubmit","auth expired \u2014 warning emitted to stderr"));}catch{}let s=Fr(t.transcript_path)||be(),o=Dr(r),i=o?te(o,n):null,a=o?ee(o,n):null;Tt(e,{traceId:be(),spanId:rt(),startNs:X(),sessionId:e,prompt:r,cwd:n,traceName:s,transcriptPath:t.transcript_path||"",model:process.env[f.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:o,skillContent:i,skillArtifacts:a}),l("UserPromptSubmit",`sid=${e}`,`traceName=${s}`,`slashSkill=${o}`),C(t);}var jr=p(()=>{Ft();$t();Re();re();Et();$();T();K();});async function Vr(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=wt(e);s&&(s.pendingTool={name:r,inputStr:M(n,F.TOOL_INPUT),startNs:X()},Tt(e,s)),l("PreToolUse",`sid=${e}`,`tool=${r}`,`stateFound=${!!s}`),C(t);}var Yr=p(()=>{Ft();$t();Et();$();T();});function d(t,e){return e==null||e===""?null:{key:t,value:{stringValue:String(e)}}}function nt(...t){return t.filter(e=>e!==null)}function Gr(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:Hs,spans:Array.isArray(e)?e:[e]}]}]}}var Hs,h,Wr=p(()=>{T();Hs={name:le.SCOPE_NAME,version:le.SCOPE_VERSION},h={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 qr(t,e,r,n,s){if(process.env[f.FLOW_OBS_DEBUG]!=="1")return;let o=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(r)},response:{status:n,body:s}});try{w.writeFileSync(Kr,o+`
137
+ `,{flag:"a",encoding:"utf8",mode:384}),l("sendTraces:dump",`request appendada em ${Kr}`);}catch(i){l("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Ks(t){let e=new URL(t),r=new URL(Q.GATEWAY_HEALTH);return r.hostname=e.hostname,r.port=e.port,r.protocol=e.protocol,r}function Jr(t,e){return new Promise((r,n)=>{let s=t._isSSL?Ln__namespace.default:Hn__namespace.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let o=s.request(t,i=>{let a=[];i.on("data",c=>a.push(c)),i.on("end",()=>r({statusCode:i.statusCode??0,body:a.join("")}));});o.setTimeout(1e4,()=>{o.destroy(new Error("Request timeout"));}),o.on("error",i=>n(new Error(`Network error: ${i.message}`))),e&&o.write(e),o.end();})}async function Xr(t,e){let r;try{r=Ks(t);}catch{return false}let n=r.protocol==="https:";try{let s={};e&&(s.Authorization=String(e).replace(/[\r\n]/g,""));let o=await Jr({hostname:r.hostname,port:r.port||(n?443:80),path:r.pathname,method:"GET",headers:s,_isSSL:n},null);return l("checkHealth",`url=${r.href} status=${o.statusCode}`),o.statusCode>=200&&o.statusCode<300}catch{return false}}async function ne(t,e,r){let n=JSON.stringify(t),s=new URL(e),o=s.protocol==="https:",i=String(r).replace(/[\r\n]/g,""),a={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(n)};l("sendTraces:request",`POST ${e}`),l("sendTraces:request",`headers=${JSON.stringify({...a,Authorization:i.slice(0,20)+"\u2026"})}`),l("sendTraces:request",`body=${n.slice(0,500)}${n.length>500?"\u2026":""}`);try{let c=await Jr({hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:a,_isSSL:o},n);return l("sendTraces:response",`status=${c.statusCode}`),qr(e,a,n,c.statusCode,c.body),c.statusCode}catch(c){return l("sendTraces:error",c.message),qr(e,a,n,0,c.message),0}}var Kr,zr=p(()=>{T();$();Kr=pt.join(It.tmpdir(),"flow-obs-requests.ndjson");});function qs(){let t=parseInt(process.env[f.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(P.MIN_TTL_DAYS,Math.min(P.MAX_TTL_DAYS,t)):P.DEFAULT_TTL_DAYS)*24*60*60*1e3}function Js(){let t=parseInt(process.env[f.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(P.MIN_MAX_FILES,Math.min(P.MAX_MAX_FILES,t)):P.DEFAULT_MAX_FILES}function Qr(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return pt__namespace.default.join(It__namespace.default.tmpdir(),`${P.FILE_PREFIX}${t}.json`)}function Ce(){let t=It__namespace.default.tmpdir(),e;try{e=w__namespace.default.readdirSync(t);}catch{return []}return e.filter(r=>r.startsWith(P.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=pt__namespace.default.join(t,r),s=0;try{s=w__namespace.default.statSync(n).mtimeMs;}catch{}return {full:n,mtime:s}}).sort((r,n)=>r.mtime-n.mtime).map(r=>r.full)}function xt(t){try{let e=Js(),r=Ce();if(r.length>=e){let o=r.slice(0,r.length-e+1);for(let i of o)try{w__namespace.default.unlinkSync(i);}catch{}}let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:n,bufferedAt:Date.now(),payload:t};return w__namespace.default.writeFileSync(Qr(n),JSON.stringify(s),{encoding:"utf8",mode:384}),l("buffer",`saved fileId=${n}`),n}catch(e){return l("buffer",`saveToBuffer failed: ${e.message}`),null}}function tn(t){let e=Ce(),r=t!=null&&t>0?t:e.length,n=[];for(let s of e){if(n.length>=r)break;try{let o=w__namespace.default.readFileSync(s,"utf8"),i=JSON.parse(o);i&&i.fileId&&i.payload&&n.push(i);}catch{l("buffer",`skipping malformed file: ${s}`);}}return n}function en(t){try{w__namespace.default.unlinkSync(Qr(t)),l("buffer",`deleted fileId=${t}`);}catch{}}function rn(){let t=Date.now()-qs();for(let e of Ce())try{let{mtimeMs:r}=w__namespace.default.statSync(e);r<t&&(w__namespace.default.unlinkSync(e),l("buffer",`evicted stale: ${pt__namespace.default.basename(e)}`));}catch{}}var nn=p(()=>{T();$();});async function Xs(t){rn();let e=tn(P.REPLAY_BATCH_SIZE);e.length&&(l("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async r=>{try{let n=await ne(r.payload,t.endpoint,t.authHeader);n>=200&&n<300?(en(r.fileId),l("replayBufferedTraces",`replayed fileId=${r.fileId} status=${n}`)):l("replayBufferedTraces",`replay failed fileId=${r.fileId} status=${n}`);}catch(n){l("replayBufferedTraces",`replay error fileId=${r.fileId}: ${n.message}`);}})));}async function sn(t){let e=await et();if(!e.length)return e.authError&&(l("postToLangfuse","auth refresh failed \u2014 buffering trace"),xt(t)),0;let r=await Promise.all(e.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await Xr(o.endpoint,o.authHeader);return {creds:o,healthy:i}})),n=r.find(o=>o.creds.mode==="gateway"&&o.healthy)?.creds??r.find(o=>o.creds.mode==="direct")?.creds;return n&&await Xs(n),(await Promise.all(r.map(async({creds:o,healthy:i})=>{if(o.mode==="gateway"){if(!i)return l("postToLangfuse","gateway health check failed \u2014 buffering trace"),xt(t),0;let c=await ne(t,o.endpoint,o.authHeader);return (c===0||c>=500)&&(l("postToLangfuse",`gateway send failed (status ${c}) \u2014 buffering trace`),xt(t)),c}let a=await ne(t,o.endpoint,o.authHeader);return (a===0||a>=500)&&(l("postToLangfuse",`direct endpoint unavailable (status ${a}) \u2014 buffering trace`),xt(t)),a}))).find(o=>o!==0)??0}var on=p(()=>{K();$();zr();nn();T();});var Ue=p(()=>{Wr();on();});function yt(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return zs.reduce((r,{re:n,replace:s})=>r.replace(n,s),e)}var v,zs,Fe=p(()=>{v="[REDACTED]",zs=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${v}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${v}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${v}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${v}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,r)=>`${e}
138
+ ${v}
139
+ ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${v}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${v}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${v}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${v}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${v}`},{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}${v}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${v}@`}];});async function an(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=t.tool_response||"",o=wt(e);if(!o){C(t);return}let i=X(),a=o.pendingTool,c=a?.name===r,u=c?a.startNs:String(BigInt(i)-200000000n),S=c?a.inputStr:M(n,F.TOOL_INPUT),A=S,m=null;if(r==="Skill"){let Ot=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||n.commandName||String(Object.values(n)[0]??""):String(n);m=Ot?String(Ot).trim():null;let ot=m?te(m,o.cwd):null;ot&&(A=ot,o.skillContent||(o.skillContent=ot),o.skillArtifacts||(o.skillArtifacts=ee(m,o.cwd))),m&&!o.slashSkill&&(o.slashSkill=m),l("PostToolUse","Skill tool detected",`skillName=${m}`,`contentFound=${!!ot}`);}let k=yt(M(s,F.TOOL_OUTPUT)),_=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(k.slice(0,500)),L=_?"ERROR":"DEFAULT",Dt=rt(),st=Math.round(Number(BigInt(i)-BigInt(u))/1e6),At={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL",se=r==="Skill"&&m?m:Qt(S,60);o.toolCalls.push({tool:r,brief:se,error:_,durationMs:st});let Y=o.spans;Y.push({traceId:o.traceId,spanId:Dt,parentSpanId:o.spanId,name:r,kind:3,startTimeUnixNano:u,endTimeUnixNano:i,attributes:nt(d(h.OBS_NAME,r),d(h.OBS_TYPE,At),d(h.OBS_LEVEL,L),d(h.OBS_INPUT,yt(A)),d(h.OBS_OUTPUT,k),d("tool.name",r),d("tool.error",String(_)),r==="Skill"&&m?d("skill.name",m):null,r==="Skill"?d("skill.invocation","slash-command"):null),status:{code:_?2:1}}),o.pendingTool=null,Tt(e,o),l("PostToolUse",`sid=${e}`,`tool=${r}`,`error=${_}`,`durationMs=${st}`,`totalSpans=${Y.length}`),C(t);}var cn=p(()=>{Ft();$t();Ue();Et();re();$();T();Fe();});function un(t,e,r){let n=Object.keys(ln).find(i=>(t??"").toLowerCase().includes(i));if(!n)return;let s=ln[n],o=(e*s.input+r*s.output)/1e6;return Math.round(o*1e6)/1e6}var ln,dn=p(()=>{ln={"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}};});async function pn(t){let e=t.session_id||"unknown",r=t.stop_reason||"end_turn",n=wt(e);if(!n){C(t);return}n.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(n.slashSkill)&&(l("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${n.slashSkill}"`),n.slashSkill=null);let s=X(),o=await mr(),i=n.toolCalls,a=n.spans;if(n.slashSkill&&!i.some(g=>g.tool==="Skill")){let g=rt(),Z=n.skillContent?n.skillContent:JSON.stringify({skill:n.slashSkill});i.push({tool:"Skill",brief:n.slashSkill,error:false,durationMs:0,synthetic:true}),a.push({traceId:n.traceId,spanId:g,parentSpanId:n.spanId,name:"Skill",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:n.startNs,attributes:nt(d(h.OBS_NAME,"Skill"),d(h.OBS_TYPE,"TOOL"),d(h.OBS_LEVEL,"DEFAULT"),d(h.OBS_INPUT,Z),d(h.OBS_OUTPUT,"loaded via slash command"),d("tool.name","Skill"),d("tool.error","false"),d("skill.name",n.slashSkill),d("skill.invocation","slash-command")),status:{code:1}}),l("Stop",`slashSkill=${n.slashSkill}`,"synthetic span injected");}let c=t.transcript_path||n.transcriptPath||"",u=Ne(c);if(c&&(i.some(g=>g.tool==="Skill"&&!g.synthetic)||!!n.slashSkill)&&!u?.text){await new Promise(Z=>setTimeout(Z,500));let g=Ne(c);g?.text&&(u=g);}l("Stop",`transcriptPath=${c||"(empty)"}`,`assistantOut=${u?`text=${u.text.length}chars`:"null"}`);let A=i.length,m=i.filter(g=>g.error).length,k=yt(u?.text?M(u.text,F.TRACE_OUTPUT):A===0?"No tools used":i.map((g,Z)=>`${Z+1}. ${g.tool}${g.brief?` \u2192 ${g.brief}`:""}${g.error?" [ERROR]":""}`).join(`
140
+ `)),_=u?.inputTokens??0,L=u?.outputTokens??0,Dt=i.map((g,Z)=>`${Z+1}. ${g.tool}${g.brief?` \u2192 ${g.brief}`:""}${g.error?" [ERROR]":""} (${g.durationMs}ms)`),st=!!(n.slashSkill||i.some(g=>g.tool==="Skill")),$e=i.some(g=>g.tool==="Agent");if(!st&&!$e){l("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),ve(e),C(t);return}let At=st?"skill":"agent",se=Math.round(Number(BigInt(s)-BigInt(n.startNs))/1e6),xe=un(n.model,_,L),Y=Br(n);Y==="prerequisite_required"&&u?.text&&(Y="complete"),Y==="prerequisite_required"&&(a.push({traceId:n.traceId,spanId:rt(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:nt(d(h.OBS_NAME,"prerequisite-check"),d(h.OBS_TYPE,"EVENT"),d(h.OBS_LEVEL,"WARNING"),d(h.OBS_OUTPUT,k),d("skill.name",n.slashSkill||void 0),d("execution_status","prerequisite_required")),status:{code:1}}),l("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${n.slashSkill}`));let Ot=(()=>{if(!(!st||!n.prompt)){if(n.slashSkill){let g=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return g?M(g,F.USER_INSTRUCTION):void 0}return M(n.prompt,F.USER_INSTRUCTION)||void 0}})(),ot=JSON.stringify({trace_type:At,...Y!==null&&{execution_status:Y},...n.slashSkill?{skill_name:n.slashSkill}:{},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...Ot!==void 0&&{user_instruction:Ot},latency_ms:se,..._&&{tokens_input:_},...L&&{tokens_output:L},cost_usd:xe,...n.model?{model:n.model}:{},toolCount:A,errorCount:m,stopReason:r,sessionId:n.sessionId,tools:Dt.length?Dt:void 0}),Me=yt(M(n.prompt,F.TRACE_INPUT)),gn=nt(d(h.TRACE_NAME,n.traceName),d(h.TRACE_INPUT,Me),d(h.TRACE_OUTPUT,k),d(h.OBS_INPUT,Me),d(h.OBS_OUTPUT,k),d(h.TRACE_METADATA,ot),d(h.SESSION_ID,n.sessionId),d(h.USER_ID,o.user),d(h.OBS_TYPE,"GENERATION"),d(h.MODEL,n.model),_?d(h.INPUT_TOKENS,_):null,L?d(h.OUTPUT_TOKENS,L):null,d("claude.stop_reason",r),d("claude.tool_count",String(A)),d("claude.error_count",String(m)),d("claude.session_id",n.sessionId),d("flow.trace_type",At),{key:h.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:At}]}}}),hn={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:gn,status:{code:m>0?2:1}},Sn=nt(d("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),d("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),De=[...a,hn];l("Stop",`sid=${e}`,`totalTools=${A}`,`errorTools=${m}`,`spans=${De.length}`,`inputTokens=${_}`,`outputTokens=${L}`,`traceOutput="${Qt(k,80)}"`);let En=await sn(Gr(Sn,De));l("Stop",`POST status=${En}`,`traceId=${n.traceId}`),ve(e),C(t);}var fn=p(()=>{Ft();$t();Ue();K();dn();Re();Et();$();re();Fe();T();});async function Zs(){let t=process.argv[2];if(!await gr()){let r=[];process.stdin.on("data",n=>r.push(n)),process.stdin.on("end",()=>process.stdout.write(r.join("")));return}let e=await Nr();switch(t){case "UserPromptSubmit":await Hr(e);break;case "PreToolUse":await Vr(e);break;case "PostToolUse":await an(e);break;case "Stop":await pn(e);break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
141
+ `),process.stdout.write(JSON.stringify(e));}}var mn=p(()=>{K();Et();jr();Yr();cn();fn();Zs().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
142
+ `),process.exit(0);});});var to=new Set(["UserPromptSubmit","PreToolUse","PostToolUse","Stop"]),[,,D,Mt]=process.argv;function kt(t,e){let r=t.indexOf(e);return r!==-1?t[r+1]:void 0}if(D==="--version"||D==="-v"){let{version:t}=Ht();process.stdout.write(t+`
143
+ `),process.exit(0);}else if(D==="--help"||D==="-h"){let{bold:t,cyan:e,dim:r}=(at(),N(ie)),{version:n}=Ht();process.stdout.write(`
173
144
  `+t(" flow-ai-obs")+r(" v"+n)+`
174
145
 
175
- `),process.stdout.write(e(" init")+r(` Auth (if needed) + hooks + native OTEL
176
- `)),process.stdout.write(r(` --custom-url <URL> Set a custom Flow base URL (e.g. https://tenant.example.com)
146
+ `),process.stdout.write(e(" install")+r(` Auth (if needed) + hooks + native OTEL
177
147
  `)),process.stdout.write(e(" setup")+r(` Full Flow wizard: auth + hooks + OTEL + LLM proxy + connectivity
178
148
  `)),process.stdout.write(e(" auth login")+r(` Authenticate with Flow (clientId / clientSecret / tenant)
179
149
  `)),process.stdout.write(e(" auth logout")+r(` Remove credentials
180
150
  `)),process.stdout.write(e(" auth status")+r(` Show current auth status
181
151
  `)),process.stdout.write(e(" check")+r(` Validate full observability setup
182
152
 
183
- `)),process.stdout.write(r(` Flags: --version, -v Show version
184
- `)),process.stdout.write(r(` --help, -h Show this help
185
- `)),process.stdout.write(r(` --no-interactive Skip interactive prompts
186
-
187
- `)),process.stdout.write(r(` Aliases: install \u2192 init (deprecated)
153
+ `)),process.stdout.write(r(` Flags: --version, -v Show version
154
+ `)),process.stdout.write(r(` --help, -h Show this help
188
155
 
189
156
  `)),process.stdout.write(r(` (Hook events: UserPromptSubmit | PreToolUse | PostToolUse | Stop)
190
157
 
191
- `)),process.exit(0);}else if(P==="init"||P==="install")(async()=>{P==="install"&&process.stderr.write(`Warning: "install" is deprecated, use "init" instead
192
- `),await(mt(),L(ft)).checkForUpdateInteractive();let{runInstall:t}=(Be(),L(Xr)),e=process.argv.slice(3);process.exit(await t({url:ct(e,"--custom-url")}));})().catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
193
- `),process.exit(1);});else if(P==="setup")(async()=>{await(mt(),L(ft)).checkForUpdateInteractive();let{runSetup:t}=(Zr(),L(zr)),e=process.argv.slice(3);process.exit(await t({clientId:ct(e,"--client-id"),clientSecret:ct(e,"--client-secret"),tenant:ct(e,"--tenant")}));})().catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
194
- `),process.exit(1);});else if(P==="auth")(async()=>{let{runLogin:t,runLogout:e,runStatus:r}=(Ht(),L(De)),n=0;if(Wt==="login"||!Wt){await(mt(),L(ft)).checkForUpdateInteractive();let s=process.argv.slice(4);n=await t({clientId:ct(s,"--client-id"),clientSecret:ct(s,"--client-secret"),tenant:ct(s,"--tenant")});}else if(Wt==="logout"){let s=process.argv.includes("--force");n=await e(s);}else Wt==="status"?(await(mt(),L(ft)).checkForUpdateInteractive(),n=await r()):(process.stderr.write(`Unknown auth subcommand: ${Wt}
158
+ `)),process.exit(0);}else if(D==="install"){(Vt(),N(jt)).checkForUpdate();let{runInstall:t}=(Oe(),N(yr));t().then(e=>process.exit(e)).catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
159
+ `),process.exit(1);});}else if(D==="setup"){(Vt(),N(jt)).checkForUpdate();let{runSetup:t}=(Ar(),N(kr)),e=process.argv.slice(3);t({clientId:kt(e,"--client-id"),clientSecret:kt(e,"--client-secret"),tenant:kt(e,"--tenant")}).then(r=>process.exit(r)).catch(r=>{process.stderr.write(`Unexpected error: ${r.message}
160
+ `),process.exit(1);});}else if(D==="auth"){(Vt(),N(jt)).checkForUpdate();let{runLogin:t,runLogout:e,runStatus:r}=(Ct(),N(Er));(async()=>{let n=0;if(Mt==="login"||!Mt){let s=process.argv.slice(4);n=await t({clientId:kt(s,"--client-id"),clientSecret:kt(s,"--client-secret"),tenant:kt(s,"--tenant")});}else if(Mt==="logout"){let s=process.argv.includes("--force");n=await e(s);}else Mt==="status"?n=await r():(process.stderr.write(`Unknown auth subcommand: ${Mt}
195
161
  `),process.stderr.write(`Usage: flow-ai-obs auth [login|logout|status]
196
- `),n=1);process.exit(n);})();else if(P==="otel-headers"){let{runOtelHeaders:t}=(tn(),L(Qr));t().then(e=>process.exit(e)).catch(()=>process.exit(1));}else if(P==="check")(async()=>{await(mt(),L(ft)).checkForUpdateInteractive();let{runCheck:t}=(nn(),L(rn));process.exit(await t());})().catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
197
- `),process.exit(1);});else if(No.has(P))Bn();else {let{bold:t,cyan:e,dim:r}=(pt(),L(ge));process.stdout.write(`
162
+ `),n=1);process.exit(n);})();}else if(D==="otel-headers"){let{runOtelHeaders:t}=(Lr(),N(Or));t().then(e=>process.exit(e)).catch(()=>process.exit(1));}else if(D==="check"){let{runCheck:t}=(vr(),N(Ir));t().then(e=>process.exit(e)).catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
163
+ `),process.exit(1);});}else if(to.has(D))mn();else {let{bold:t,cyan:e,dim:r}=(at(),N(ie));process.stdout.write(`
198
164
  `+t(" flow-ai-obs")+`
199
165
 
200
- `),process.stdout.write(e(" init")+r(` Auth (if needed) + hooks + native OTEL
201
- `)),process.stdout.write(r(` --custom-url <URL> Set a custom Flow base URL (e.g. https://tenant.example.com)
166
+ `),process.stdout.write(e(" install")+r(` Auth (if needed) + hooks + native OTEL
202
167
  `)),process.stdout.write(e(" setup")+r(` Full Flow wizard: auth + hooks + OTEL + LLM proxy + connectivity
203
168
  `)),process.stdout.write(e(" auth login")+r(` Authenticate with Flow (clientId / clientSecret / tenant)
204
169
  `)),process.stdout.write(e(" auth logout")+r(` Remove credentials
package/dist/index.js CHANGED
@@ -1,16 +1,20 @@
1
- 'use strict';var child_process=require('child_process'),util=require('util'),R=require('fs'),$=require('path'),Z=require('os'),rn=require('https'),sn=require('http'),crypto=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var R__namespace=/*#__PURE__*/_interopNamespace(R);var $__namespace=/*#__PURE__*/_interopNamespace($);var Z__namespace=/*#__PURE__*/_interopNamespace(Z);var rn__default=/*#__PURE__*/_interopDefault(rn);var sn__default=/*#__PURE__*/_interopDefault(sn);var $e=Object.defineProperty;var z=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var pt=(t,e)=>()=>(t&&(e=t(t=0)),e);var ft=(t,e)=>{for(var n in e)$e(t,n,{get:e[n],enumerable:true});};var Vt={};ft(Vt,{MacOsKeyVaultProvider:()=>ht});var Et,ht,Jt=pt(()=>{Et=util.promisify(child_process.execFile),ht=class{static async isAvailable(){try{return R.accessSync("/usr/bin/security",R.constants.X_OK),!0}catch{return false}}async getSecret(e,n){try{let{stdout:r}=await Et("security",["find-generic-password","-w","-a",n,"-s",e]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await Et("security",["add-generic-password","-U","-a",n,"-s",e,"-w",r]);}async deleteSecret(e,n){try{return await Et("security",["delete-generic-password","-a",n,"-s",e]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};});var qt={};ft(qt,{LinuxKeyVaultProvider:()=>Tt});var Kt,Tt,Xt=pt(()=>{Kt=util.promisify(child_process.execFile),Tt=class{static async isAvailable(){let e=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let n of e)try{return R.accessSync(n,R.constants.X_OK),!0}catch{}return false}async getSecret(e,n){try{let{stdout:r}=await Kt("secret-tool",["lookup","service",e,"account",n]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await new Promise((o,s)=>{let i=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",n]);i.on("error",s),i.on("close",u=>{u===0?o():s(new Error(`secret-tool exited with code ${u}`));}),i.stdin.write(r),i.stdin.end();});}async deleteSecret(e,n){try{return await Kt("secret-tool",["clear","service",e,"account",n]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var zt={};ft(zt,{WindowsKeyVaultProvider:()=>yt});var yt,Zt=pt(()=>{yt=class{static async isAvailable(){try{return await z("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(e,n){return z("keytar").getPassword(e,n)}async setSecret(e,n,r){await z("keytar").setPassword(e,n,r);}async deleteSecret(e,n){return z("keytar").deletePassword(e,n)}getStoragePath(){return "Windows Credential Manager"}};});function Mt(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return {home:e,username:process.env.SUDO_USER}}return {home:Z__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||Z__namespace.userInfo().username}}var Ht="flow-ai-obs",Yt="config.json";function xe(){if(process.platform==="win32"){let n=process.env.APPDATA||$__namespace.join(Z__namespace.homedir(),"AppData","Roaming");return $__namespace.join(n,Ht,Yt)}let t=Mt(),e=process.env.XDG_CONFIG_HOME||$__namespace.join(t.home,".config");return $__namespace.join(e,Ht,Yt)}function Be(){try{let t=R__namespace.readFileSync(xe(),"utf8");return JSON.parse(t)}catch{return {}}}function dt(){return Be().baseUrl??null}var Q=dt()??process.env.FLOW_BASE_URL??"https://flow.ciandt.com";function mt(){return dt()??process.env.FLOW_BASE_URL??"https://flow.ciandt.com"}function W(){let t=mt();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${t}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${t}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${t}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${t}/otel`}}W();var tt={SERVICE:"flow-plugins-cli",ACCOUNT_TOKEN:"token-cache"},et="FLOW-nodejs",nt="config.json",gt={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};({ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${Q}/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"});var g={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",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"};var A={FILE_PREFIX:"flow-obs-buffer-",DEFAULT_TTL_DAYS:4,MIN_TTL_DAYS:1,MAX_TTL_DAYS:30,DEFAULT_MAX_FILES:50,MIN_MAX_FILES:1,MAX_MAX_FILES:500,REPLAY_BATCH_SIZE:10},Wt="flow-ai-obs-debug.log",w={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4};({API_URL:process.env.FLOW_METRICS_URL||`${Q}/metrics-collector-api/log-event`});var St={credentials:"credentials","token-cache":"tokenCache"};function j(){let t=Z__namespace.default.homedir();if(process.platform==="darwin")return $__namespace.default.join(t,"Library","Preferences",et,nt);if(process.platform==="win32"){let n=process.env.APPDATA??$__namespace.default.join(t,"AppData","Roaming");return $__namespace.default.join(n,et,nt)}let e=process.env.XDG_CONFIG_HOME??$__namespace.default.join(t,".config");return $__namespace.default.join(e,et,nt)}function _t(){try{let t=R__namespace.default.readFileSync(j(),"utf8");return JSON.parse(t)}catch{return {}}}function jt(t){let e=j();R__namespace.default.mkdirSync($__namespace.default.dirname(e),{recursive:true}),R__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var st=class{static isAvailable(){return true}static hasExistingData(){try{if(!R__namespace.default.existsSync(j()))return !1;let e=JSON.parse(R__namespace.default.readFileSync(j(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,n){let r=_t(),o=St[n]??n,s=r[o];return s?typeof s=="string"?s:JSON.stringify(s):null}async setSecret(e,n,r){let o=_t(),s=St[n]??n;if(n==="token-cache")try{o[s]=JSON.parse(r);}catch{o[s]=r;}else o[s]=r;jt(o);}async deleteSecret(e,n){let r=_t(),o=St[n]??n;return o in r?(delete r[o],jt(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${j()}`}};async function Qt(){return await ze()??new st}async function ze(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Jt(),Vt));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Xt(),qt));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Zt(),zt));return await t.isAvailable()?new t:null}default:return null}}var Ot=tt.SERVICE,te=tt.ACCOUNT_TOKEN,At=null;function wt(){return At||(At=Qt()),At}async function kt(t){await(await wt()).setSecret(Ot,te,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function It(){let e=await(await wt()).getSecret(Ot,te);if(!e)return null;try{let n=JSON.parse(e);return {accessToken:n.accessToken,expiresAt:n.expiresAt,lastAuthCheckAt:n.lastAuthCheckAt}}catch{return null}}async function J(){let t=await It();if(!t||!t.accessToken)return null;try{let e=t.accessToken.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email??n.preferred_username??n.upn??n.sub??null}catch{return null}}var nn=$.join(Z.tmpdir(),Wt);function a(...t){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
2
- `;try{R.writeFileSync(nn,e,{flag:"a"});}catch(n){process.stderr.write(`[flow-obs debug ERROR] ${n.message}
3
- `);}}var P=class extends Error{constructor(e){super(e),this.name="AuthError";}},on=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function an(t){if(!on.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var ee={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 cn(t,e){let n=e.length>400?e.slice(0,400)+"\u2026":e;a("toAuthError",`status=${t} body=${n}`);try{let r=JSON.parse(e);if(typeof r.error=="string"&&(a("toAuthError",`api_error_code=${r.error}`+(r.message?` api_message=${r.message}`:"")),ee[r.error]))return new P(ee[r.error])}catch{}return t===401||t===403||t===500?new P("Invalid credentials"):t>=400&&t<500?new P("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function Lt(t){return new Promise((e,n)=>{try{an(t.tenant);}catch(p){return n(p)}let r=JSON.stringify({clientSecret:t.clientSecret}),o=new URL(W().AUTH_ENGINE),s=o.protocol==="https:",i={hostname:o.hostname,port:o.port||(s?443:80),path:o.pathname+o.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(r),FlowTenant:t.tenant}};a("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let l=(s?rn__default.default:sn__default.default).request(i,p=>{let _=[];p.on("data",h=>_.push(h)),p.on("end",()=>{let h=_.join("");if((p.statusCode??0)>=400)return n(cn(p.statusCode??0,h));let f;try{f=JSON.parse(h);}catch{return n(new Error("Invalid response from auth engine"))}let E=f.expires_at??new Date(Date.now()+(f.expires_in??3600)*1e3).toISOString();e({accessToken:f.access_token??"",expiresAt:E});});});l.on("error",p=>n(new Error(`Network error: ${p.message}`))),l.write(r),l.end();})}var ln=[/^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 un(t){return ln.some(e=>e.test(t))}function pn(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}function re(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:o,tenant:s}=n;return !r||!o||!s?null:{clientId:r,clientSecret:o,tenant:s}}catch{return null}}function ne(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let n=process.env[g.FLOW_OBS_ALLOW_HTTP]==="true";if(!n&&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(!n&&un(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function se(){let t=re(process.env[g.ANTHROPIC_AUTH_TOKEN]);if(t)return {user:await J().catch(()=>null)??t.clientId,tenant:t.tenant};return {user:"",tenant:""}}function fn(){return new Date().toISOString().slice(0,10)}async function dn(t){let e=fn(),n=await It();if(n?.lastAuthCheckAt!==e){a("getOrRefreshToken",`daily auth check (last: ${n?.lastAuthCheckAt??"never"})`);try{let s=await Lt(t);try{await kt({...s,lastAuthCheckAt:e});}catch{}return a("getOrRefreshToken",`daily check passed, expires=${s.expiresAt}`),s.accessToken}catch(s){if(s instanceof P)throw s;a("getOrRefreshToken",`daily check network error \u2014 using cache: ${s.message}`);}}let r=n!=null&&new Date(n.expiresAt)>new Date;if(a("getOrRefreshToken",`cacheValid=${r}`),r)return a("getOrRefreshToken",`using cached token, expires=${n.expiresAt}`),n.accessToken;a("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let o=await Lt(t);try{await kt({...o,lastAuthCheckAt:e});}catch(s){a("getOrRefreshToken",`token cache save failed (non-fatal): ${s.message}`);}return a("getOrRefreshToken",`token refreshed, expires=${o.expiresAt}`),o.accessToken}function mn(t,e){let n=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${n}`}}function gn(t,e,n){let r=Buffer.from(`${e}:${n}`).toString("base64");return {endpoint:t.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${r}`}}async function K(){let t=[],e=process.env[g.ANTHROPIC_MODEL]??"",n=re(process.env[g.ANTHROPIC_AUTH_TOKEN]);a("resolveCredentials",n?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),n&&a("resolveCredentials",`clientId=${n.clientId}`,`tenant=${n.tenant}`);let r=n?n.tenant:"",o=process.env[g.FLOW_TELEMETRY]==="true",s=process.env[g.LANGFUSE_BASE_URL],i=process.env[g.LANGFUSE_PUBLIC_KEY],u=process.env[g.LANGFUSE_SECRET_KEY];if(o&&s&&i&&u){let f="",E=r;if(n)f=await J().catch(()=>null)??n.clientId;let S={user:f??"",tenant:E??"",team:"",project:"",model:e};t.push({mode:"direct",...gn(ne(s),i,u),...S}),a("resolveCredentials","direct mode active",`user=${S.user}`,`tenant=${S.tenant}`);}if(!n){if(t.length===0){let f=[];return f.authError=false,f}return t}let l;try{l=await dn(n);}catch(f){if(a("resolveCredentials",`token refresh failed: ${f.message}`,`(tenant=${n.tenant} clientId=${n.clientId})`),t.length>0)return t.authError=true,t;let E=[];return E.authError=true,E}let _={user:pn(l)??n.clientId,tenant:r,team:"",project:"",model:e},h=process.env[g.FLOW_TELEMETRY_GATEWAY]??mt();return t.push({mode:"gateway",...mn(ne(h),{accessToken:l}),..._}),t}async function oe(){return (await K()).length>0}function k(t,e){let n=typeof t=="object"?JSON.stringify(t):String(t??"");return n.length>e?n.slice(0,e)+" \u2026[truncated]":n}function it(t,e=100){return String(t??"").split(`
4
- `)[0].slice(0,e).trim()}function Rt(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n;}),process.stdin.on("end",()=>{try{t(JSON.parse(e));}catch{t({});}});})}function O(t){process.stdout.write(JSON.stringify(t));}var Nt=()=>crypto.randomBytes(16).toString("hex"),b=()=>crypto.randomBytes(8).toString("hex");function L(){return String(BigInt(Date.now())*1000000n)}var wn=/^[0-9a-f-]{1,64}$/i,kn=$.normalize(Z.tmpdir())+$.sep;function In(t,e){let n=$.resolve(t);if(!n.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return n}function Pt(t){if(!wn.test(t))throw new Error(`Invalid session ID: ${t}`);return In($.join(Z.tmpdir(),`flow-obs-${t}.json`),kn)}function D(t){let e=Pt(t);if(!R.existsSync(e))return null;try{return JSON.parse(R.readFileSync(e,"utf8"))}catch{return null}}function x(t,e){R.writeFileSync(Pt(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function bt(t){try{R.unlinkSync(Pt(t));}catch{}}function ue(t){if(!t||!R.existsSync(t))return null;try{let e=R.readFileSync(t,"utf8").trimEnd().split(`
5
- `);for(let n=e.length-1;n>=0;n--)try{let r=JSON.parse(e[n]);if(r.type==="user"&&r.uuid)return r.uuid}catch{}}catch{}return null}function Ut(t){if(!t||!R.existsSync(t))return null;try{let e=R.readFileSync(t,"utf8").trimEnd().split(`
6
- `),n=[],r=0,o=0;for(let s=e.length-1;s>=0;s--)try{let i=JSON.parse(e[s]);if(i.type==="user")break;if(i.type==="assistant"){let l=(i.message?.content??[]).filter(_=>_.type==="text").map(_=>_.text??"").join("");l&&n.unshift(l);let p=i.message?.usage??{};r+=(p.input_tokens??0)+(p.cache_read_input_tokens??0)+(p.cache_creation_input_tokens??0),o+=p.output_tokens??0;}}catch{}return !n.length&&r===0?null:{text:n.join(`
1
+ 'use strict';var child_process=require('child_process'),util=require('util'),R=require('fs'),$=require('path'),fe=require('os'),Ve=require('https'),Ge=require('http'),crypto=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var R__default=/*#__PURE__*/_interopDefault(R);var $__default=/*#__PURE__*/_interopDefault($);var fe__default=/*#__PURE__*/_interopDefault(fe);var Ve__default=/*#__PURE__*/_interopDefault(Ve);var Ge__default=/*#__PURE__*/_interopDefault(Ge);var Ie=Object.defineProperty;var q=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var ct=(t,e)=>()=>(t&&(e=t(t=0)),e);var lt=(t,e)=>{for(var n in e)Ie(t,n,{get:e[n],enumerable:true});};var Ut={};lt(Ut,{MacOsKeyVaultProvider:()=>mt});var ft,mt,vt=ct(()=>{ft=util.promisify(child_process.execFile),mt=class{static async isAvailable(){try{return R.accessSync("/usr/bin/security",R.constants.X_OK),!0}catch{return false}}async getSecret(e,n){try{let{stdout:r}=await ft("security",["find-generic-password","-w","-a",n,"-s",e]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await ft("security",["add-generic-password","-U","-a",n,"-s",e,"-w",r]);}async deleteSecret(e,n){try{return await ft("security",["delete-generic-password","-a",n,"-s",e]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};});var $t={};lt($t,{LinuxKeyVaultProvider:()=>gt});var Ct,gt,Ft=ct(()=>{Ct=util.promisify(child_process.execFile),gt=class{static async isAvailable(){let e=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let n of e)try{return R.accessSync(n,R.constants.X_OK),!0}catch{}return false}async getSecret(e,n){try{let{stdout:r}=await Ct("secret-tool",["lookup","service",e,"account",n]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await new Promise((o,s)=>{let i=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",n]);i.on("error",s),i.on("close",u=>{u===0?o():s(new Error(`secret-tool exited with code ${u}`));}),i.stdin.write(r),i.stdin.end();});}async deleteSecret(e,n){try{return await Ct("secret-tool",["clear","service",e,"account",n]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var Bt={};lt(Bt,{WindowsKeyVaultProvider:()=>_t});var _t,Dt=ct(()=>{_t=class{static async isAvailable(){try{return await q("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(e,n){return q("keytar").getPassword(e,n)}async setSecret(e,n,r){await q("keytar").setPassword(e,n,r);}async deleteSecret(e,n){return q("keytar").deletePassword(e,n)}getStoragePath(){return "Windows Credential Manager"}};});var I=process.env.FLOW_BASE_URL||"https://flow.ciandt.com",Y={AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${I}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${I}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${I}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${I}/otel`},X={SERVICE:"flow-plugins-cli",ACCOUNT_TOKEN:"token-cache"},z="FLOW-nodejs",Z="config.json",ut={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};({ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${I}/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"});var g={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",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"};var A={FILE_PREFIX:"flow-obs-buffer-",DEFAULT_TTL_DAYS:4,MIN_TTL_DAYS:1,MAX_TTL_DAYS:30,DEFAULT_MAX_FILES:50,MIN_MAX_FILES:1,MAX_MAX_FILES:500,REPLAY_BATCH_SIZE:10},Pt="flow-ai-obs-debug.log",k={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4};({API_URL:process.env.FLOW_METRICS_URL||`${I}/metrics-collector-api/log-event`});var pt={credentials:"credentials","token-cache":"tokenCache"};function W(){let t=fe__default.default.homedir();if(process.platform==="darwin")return $__default.default.join(t,"Library","Preferences",z,Z);if(process.platform==="win32"){let n=process.env.APPDATA??$__default.default.join(t,"AppData","Roaming");return $__default.default.join(n,z,Z)}let e=process.env.XDG_CONFIG_HOME??$__default.default.join(t,".config");return $__default.default.join(e,z,Z)}function dt(){try{let t=R__default.default.readFileSync(W(),"utf8");return JSON.parse(t)}catch{return {}}}function bt(t){let e=W();R__default.default.mkdirSync($__default.default.dirname(e),{recursive:true}),R__default.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var tt=class{static isAvailable(){return true}static hasExistingData(){try{if(!R__default.default.existsSync(W()))return !1;let e=JSON.parse(R__default.default.readFileSync(W(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,n){let r=dt(),o=pt[n]??n,s=r[o];return s?typeof s=="string"?s:JSON.stringify(s):null}async setSecret(e,n,r){let o=dt(),s=pt[n]??n;if(n==="token-cache")try{o[s]=JSON.parse(r);}catch{o[s]=r;}else o[s]=r;bt(o);}async deleteSecret(e,n){let r=dt(),o=pt[n]??n;return o in r?(delete r[o],bt(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${W()}`}};async function Mt(){return await De()??new tt}async function De(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(vt(),Ut));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Ft(),$t));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Dt(),Bt));return await t.isAvailable()?new t:null}default:return null}}var Et=X.SERVICE,xt=X.ACCOUNT_TOKEN,St=null;function Tt(){return St||(St=Mt()),St}async function Ht(t){await(await Tt()).setSecret(Et,xt,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt}));}async function nt(){let e=await(await Tt()).getSecret(Et,xt);if(!e)return null;try{let n=JSON.parse(e);return {accessToken:n.accessToken,expiresAt:n.expiresAt}}catch{return null}}async function Yt(){let t=await nt();return t?new Date(t.expiresAt)>new Date:false}async function G(){let t=await nt();if(!t||!t.accessToken)return null;try{let e=t.accessToken.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email??n.preferred_username??n.upn??n.sub??null}catch{return null}}var We=$.join(fe.tmpdir(),Pt);function a(...t){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
2
+ `;try{R.writeFileSync(We,e,{flag:"a"});}catch(n){process.stderr.write(`[flow-obs debug ERROR] ${n.message}
3
+ `);}}var Ke=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function je(t){if(!Ke.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var Wt={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 Je(t,e){let n=e.length>400?e.slice(0,400)+"\u2026":e;a("toAuthError",`status=${t} body=${n}`);try{let r=JSON.parse(e);if(typeof r.error=="string"&&(a("toAuthError",`api_error_code=${r.error}`+(r.message?` api_message=${r.message}`:"")),Wt[r.error]))return new Error(Wt[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 Vt(t){return new Promise((e,n)=>{try{je(t.tenant);}catch(p){return n(p)}let r=JSON.stringify({clientSecret:t.clientSecret}),o=new URL(Y.AUTH_ENGINE),s=o.protocol==="https:",i={hostname:o.hostname,port:o.port||(s?443:80),path:o.pathname+o.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(r),FlowTenant:t.tenant}};a("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let l=(s?Ve__default.default:Ge__default.default).request(i,p=>{let S=[];p.on("data",T=>S.push(T)),p.on("end",()=>{let T=S.join("");if((p.statusCode??0)>=400)return n(Je(p.statusCode??0,T));let d;try{d=JSON.parse(T);}catch{return n(new Error("Invalid response from auth engine"))}let E=d.expires_at??new Date(Date.now()+(d.expires_in??3600)*1e3).toISOString();e({accessToken:d.access_token??"",expiresAt:E});});});l.on("error",p=>n(new Error(`Network error: ${p.message}`))),l.write(r),l.end();})}var qe=[/^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 Xe(t){return qe.some(e=>e.test(t))}function ze(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}function Kt(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:o,tenant:s}=n;return !r||!o||!s?null:{clientId:r,clientSecret:o,tenant:s}}catch{return null}}function Gt(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let n=process.env[g.FLOW_OBS_ALLOW_HTTP]==="true";if(!n&&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(!n&&Xe(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function jt(){let t=Kt(process.env[g.ANTHROPIC_AUTH_TOKEN]);if(t)return {user:await G().catch(()=>null)??t.clientId,tenant:t.tenant};return {user:"",tenant:""}}async function Ze(t){if(await Yt()){let n=await nt();return a("getOrRefreshToken",`using cached token, expires=${n.expiresAt}`),n.accessToken}a("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let e=await Vt(t);try{await Ht(e);}catch(n){a("getOrRefreshToken",`token cache save failed (non-fatal): ${n.message}`);}return a("getOrRefreshToken",`token refreshed, expires=${e.expiresAt}`),e.accessToken}function Qe(t,e){let n=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${n}`}}function tn(t,e,n){let r=Buffer.from(`${e}:${n}`).toString("base64");return {endpoint:t.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${r}`}}async function K(){let t=[],e=process.env[g.ANTHROPIC_MODEL]??"",n=Kt(process.env[g.ANTHROPIC_AUTH_TOKEN]);a("resolveCredentials",n?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid");let r=n?n.tenant:"",o=process.env[g.FLOW_TELEMETRY]==="true",s=process.env[g.LANGFUSE_BASE_URL],i=process.env[g.LANGFUSE_PUBLIC_KEY],u=process.env[g.LANGFUSE_SECRET_KEY];if(o&&s&&i&&u){let d="",E=r;if(n)d=await G().catch(()=>null)??n.clientId;let _={user:d??"",tenant:E??"",team:"",project:"",model:e};t.push({mode:"direct",...tn(Gt(s),i,u),..._}),a("resolveCredentials","direct mode active",`user=${_.user}`,`tenant=${_.tenant}`);}if(!n){if(t.length===0){let d=[];return d.authError=false,d}return t}let l;try{l=await Ze(n);}catch(d){if(a("resolveCredentials",`token refresh failed: ${d.message}`,`(tenant=${n.tenant} clientId=${n.clientId})`),t.length>0)return t;let E=[];return E.authError=true,E}let S={user:ze(l)??n.clientId,tenant:r,team:"",project:"",model:e},T=process.env[g.FLOW_TELEMETRY_GATEWAY]??I;return t.push({mode:"gateway",...Qe(Gt(T),{accessToken:l}),...S}),t}async function Jt(){return (await K()).length>0}function w(t,e){let n=typeof t=="object"?JSON.stringify(t):String(t??"");return n.length>e?n.slice(0,e)+" \u2026[truncated]":n}function rt(t,e=100){return String(t??"").split(`
4
+ `)[0].slice(0,e).trim()}function qt(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n;}),process.stdin.on("end",()=>{try{t(JSON.parse(e));}catch{t({});}});})}function O(t){process.stdout.write(JSON.stringify(t));}var ht=()=>crypto.randomBytes(16).toString("hex"),b=()=>crypto.randomBytes(8).toString("hex");function N(){return String(BigInt(Date.now())*1000000n)}var un=/^[0-9a-f-]{1,64}$/i,pn=$.normalize(fe.tmpdir())+$.sep;function dn(t,e){let n=$.resolve(t);if(!n.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return n}function yt(t){if(!un.test(t))throw new Error(`Invalid session ID: ${t}`);return dn($.join(fe.tmpdir(),`flow-obs-${t}.json`),pn)}function F(t){let e=yt(t);if(!R.existsSync(e))return null;try{return JSON.parse(R.readFileSync(e,"utf8"))}catch{return null}}function B(t,e){R.writeFileSync(yt(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function At(t){try{R.unlinkSync(yt(t));}catch{}}function te(t){if(!t||!R.existsSync(t))return null;try{let e=R.readFileSync(t,"utf8").trimEnd().split(`
5
+ `);for(let n=e.length-1;n>=0;n--)try{let r=JSON.parse(e[n]);if(r.type==="user"&&r.uuid)return r.uuid}catch{}}catch{}return null}function Ot(t){if(!t||!R.existsSync(t))return null;try{let e=R.readFileSync(t,"utf8").trimEnd().split(`
6
+ `),n=[],r=0,o=0;for(let s=e.length-1;s>=0;s--)try{let i=JSON.parse(e[s]);if(i.type==="user")break;if(i.type==="assistant"){let l=(i.message?.content??[]).filter(S=>S.type==="text").map(S=>S.text??"").join("");l&&n.unshift(l);let p=i.message?.usage??{};r+=(p.input_tokens??0)+(p.cache_read_input_tokens??0)+(p.cache_creation_input_tokens??0),o+=p.output_tokens??0;}}catch{}return !n.length&&r===0?null:{text:n.join(`
7
7
 
8
- `),inputTokens:r,outputTokens:o}}catch{}return null}var Pn=new Set([".venv","__pycache__",".git","node_modules"]),bn=new Set([".pyc",".pyo"]),Un=new Set(["SKILL.md",".DS_Store",".gitignore"]);function de(t){return t.replace(":","/")}function at(t,e){if(!t)return null;let n=de(t),r=[$.join(Z.homedir(),".claude","skills",n,"SKILL.md"),$.join(e??"",".claude","skills",n,"SKILL.md")];for(let o of r)if(R.existsSync(o))try{return R.readFileSync(o,"utf8")}catch{}return null}function me(t){return t.split(`
9
- `)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var vn=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function ge(t){return !!t.slashSkill||t.toolCalls.some(r=>r.tool==="Skill")?t.toolCalls.some(r=>r.tool==="Skill"&&!r.synthetic||vn.has(r.tool))?"complete":"prerequisite_required":null}function ct(t,e){if(!t)return null;let n=de(t),r=[$.join(Z.homedir(),".claude","skills",n),$.join(e??"",".claude","skills",n)],o=null;for(let u of r)if(R.existsSync($.join(u,"SKILL.md"))){o=u;break}if(!o)return null;let s=[];function i(u,l){for(let p of R.readdirSync(u,{withFileTypes:true})){if(Pn.has(p.name)||Un.has(p.name)||bn.has($.extname(p.name)))continue;let _=l?`${l}/${p.name}`:p.name;p.isDirectory()?i($.join(u,p.name),_):s.push(_);}}return i(o,""),s.length>0?s:null}var Cn=`\u26D4 Your Flow API key has expired. You no longer have access to Claude Code through the Flow platform. To restore observability and access, visit ${Q}/settings/api-keys to generate a new API key, then run: flow-ai-obs auth login`;async function vt(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:Cn})+`
10
- `);return}let n=t.session_id||"unknown",r=t.prompt||"",o=t.cwd||"",s=ue(t.transcript_path)||Nt(),i=me(r),u=i?at(i,o):null,l=i?ct(i,o):null;x(n,{traceId:Nt(),spanId:b(),startNs:L(),sessionId:n,prompt:r,cwd:o,traceName:s,transcriptPath:t.transcript_path||"",model:process.env[g.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:i,skillContent:u,skillArtifacts:l}),a("UserPromptSubmit",`sid=${n}`,`traceName=${s}`,`slashSkill=${i}`),O(t);}async function Se(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},o=D(e);o&&(o.pendingTool={name:n,inputStr:k(r,w.TOOL_INPUT),startNs:L()},x(e,o)),a("PreToolUse",`sid=${e}`,`tool=${n}`,`stateFound=${!!o}`),O(t);}var Fn={name:gt.SCOPE_NAME,version:gt.SCOPE_VERSION},m={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 c(t,e){return e==null||e===""?null:{key:t,value:{stringValue:String(e)}}}function U(...t){return t.filter(e=>e!==null)}function _e(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:Fn,spans:Array.isArray(e)?e:[e]}]}]}}var Ee=$.join(Z.tmpdir(),"flow-obs-requests.ndjson");function he(t,e,n,r,o){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let s=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(n)},response:{status:r,body:o}});try{R.writeFileSync(Ee,s+`
11
- `,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${Ee}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Hn(t){let e=new URL(t),n=new URL(W().GATEWAY_HEALTH);return n.hostname=e.hostname,n.port=e.port,n.protocol=e.protocol,n}function Te(t,e){return new Promise((n,r)=>{let o=t._isSSL?rn__default.default:sn__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let s=o.request(t,i=>{let u=[];i.on("data",l=>u.push(l)),i.on("end",()=>n({statusCode:i.statusCode??0,body:u.join("")}));});s.setTimeout(1e4,()=>{s.destroy(new Error("Request timeout"));}),s.on("error",i=>r(new Error(`Network error: ${i.message}`))),e&&s.write(e),s.end();})}async function ye(t,e){let n;try{n=Hn(t);}catch{return false}let r=n.protocol==="https:";try{let o={};e&&(o.Authorization=String(e).replace(/[\r\n]/g,""));let s=await Te({hostname:n.hostname,port:n.port||(r?443:80),path:n.pathname,method:"GET",headers:o,_isSSL:r},null);return a("checkHealth",`url=${n.href} status=${s.statusCode}`),s.statusCode>=200&&s.statusCode<300}catch{return false}}async function lt(t,e,n){let r=JSON.stringify(t),o=new URL(e),s=o.protocol==="https:",i=String(n).replace(/[\r\n]/g,""),u={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(r)};a("sendTraces:request",`POST ${e}`),a("sendTraces:request",`headers=${JSON.stringify({...u,Authorization:i.slice(0,20)+"\u2026"})}`),a("sendTraces:request",`body=${r.slice(0,500)}${r.length>500?"\u2026":""}`);try{let l=await Te({hostname:o.hostname,port:o.port||(s?443:80),path:o.pathname,method:"POST",headers:u,_isSSL:s},r);return a("sendTraces:response",`status=${l.statusCode}`),he(e,u,r,l.statusCode,l.body),l.statusCode}catch(l){return a("sendTraces:error",l.message),he(e,u,r,0,l.message),0}}function Yn(){let t=parseInt(process.env[g.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(A.MIN_TTL_DAYS,Math.min(A.MAX_TTL_DAYS,t)):A.DEFAULT_TTL_DAYS)*24*60*60*1e3}function Gn(){let t=parseInt(process.env[g.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(A.MIN_MAX_FILES,Math.min(A.MAX_MAX_FILES,t)):A.DEFAULT_MAX_FILES}function Oe(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return $__namespace.default.join(Z__namespace.default.tmpdir(),`${A.FILE_PREFIX}${t}.json`)}function Ft(){let t=Z__namespace.default.tmpdir(),e;try{e=R__namespace.default.readdirSync(t);}catch{return []}return e.filter(n=>n.startsWith(A.FILE_PREFIX)&&n.endsWith(".json")).map(n=>{let r=$__namespace.default.join(t,n),o=0;try{o=R__namespace.default.statSync(r).mtimeMs;}catch{}return {full:r,mtime:o}}).sort((n,r)=>n.mtime-r.mtime).map(n=>n.full)}function q(t){try{let e=Gn(),n=Ft();if(n.length>=e){let s=n.slice(0,n.length-e+1);for(let i of s)try{R__namespace.default.unlinkSync(i);}catch{}}let r=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,o={fileId:r,bufferedAt:Date.now(),payload:t};return R__namespace.default.writeFileSync(Oe(r),JSON.stringify(o),{encoding:"utf8",mode:384}),a("buffer",`saved fileId=${r}`),r}catch(e){return a("buffer",`saveToBuffer failed: ${e.message}`),null}}function we(t){let e=Ft(),n=t,r=[];for(let o of e){if(r.length>=n)break;try{let s=R__namespace.default.readFileSync(o,"utf8"),i=JSON.parse(s);i&&i.fileId&&i.payload&&r.push(i);}catch{a("buffer",`skipping malformed file: ${o}`);}}return r}function ke(t){try{R__namespace.default.unlinkSync(Oe(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function Ie(){let t=Date.now()-Yn();for(let e of Ft())try{let{mtimeMs:n}=R__namespace.default.statSync(e);n<t&&(R__namespace.default.unlinkSync(e),a("buffer",`evicted stale: ${$__namespace.default.basename(e)}`));}catch{}}async function Wn(t){Ie();let e=we(A.REPLAY_BATCH_SIZE);e.length&&(a("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async n=>{try{let r=await lt(n.payload,t.endpoint,t.authHeader);r>=200&&r<300?(ke(n.fileId),a("replayBufferedTraces",`replayed fileId=${n.fileId} status=${r}`)):a("replayBufferedTraces",`replay failed fileId=${n.fileId} status=${r}`);}catch(r){a("replayBufferedTraces",`replay error fileId=${n.fileId}: ${r.message}`);}})));}async function Le(t){let e=await K();if(!e.length)return e.authError&&(a("postToLangfuse","auth refresh failed \u2014 buffering trace"),q(t)),0;let n=await Promise.all(e.map(async s=>{if(s.mode!=="gateway")return {creds:s,healthy:true};let i=await ye(s.endpoint,s.authHeader);return {creds:s,healthy:i}})),r=n.find(s=>s.creds.mode==="gateway"&&s.healthy)?.creds??n.find(s=>s.creds.mode==="direct")?.creds;return r&&await Wn(r),(await Promise.all(n.map(async({creds:s,healthy:i})=>{if(s.mode==="gateway"){if(!i)return a("postToLangfuse","gateway health check failed \u2014 buffering trace"),q(t),0;let l=await lt(t,s.endpoint,s.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`gateway send failed (status ${l}) \u2014 buffering trace`),q(t)),l}let u=await lt(t,s.endpoint,s.authHeader);return (u===0||u>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${u}) \u2014 buffering trace`),q(t)),u}))).find(s=>s!==0)??0}var y="[REDACTED]",jn=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${y}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${y}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,n)=>`${e}
8
+ `),inputTokens:r,outputTokens:o}}catch{}return null}var _n=new Set([".venv","__pycache__",".git","node_modules"]),Sn=new Set([".pyc",".pyo"]),En=new Set(["SKILL.md",".DS_Store",".gitignore"]);function re(t){return t.replace(":","/")}function st(t,e){if(!t)return null;let n=re(t),r=[$.join(fe.homedir(),".claude","skills",n,"SKILL.md"),$.join(e??"",".claude","skills",n,"SKILL.md")];for(let o of r)if(R.existsSync(o))try{return R.readFileSync(o,"utf8")}catch{}return null}function se(t){return t.split(`
9
+ `)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var Tn=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function oe(t){return !!t.slashSkill||t.toolCalls.some(r=>r.tool==="Skill")?t.toolCalls.some(r=>r.tool==="Skill"&&!r.synthetic||Tn.has(r.tool))?"complete":"prerequisite_required":null}function ot(t,e){if(!t)return null;let n=re(t),r=[$.join(fe.homedir(),".claude","skills",n),$.join(e??"",".claude","skills",n)],o=null;for(let u of r)if(R.existsSync($.join(u,"SKILL.md"))){o=u;break}if(!o)return null;let s=[];function i(u,l){for(let p of R.readdirSync(u,{withFileTypes:true})){if(_n.has(p.name)||En.has(p.name)||Sn.has($.extname(p.name)))continue;let S=l?`${l}/${p.name}`:p.name;p.isDirectory()?i($.join(u,p.name),S):s.push(S);}}return i(o,""),s.length>0?s:null}async function ie(t){let e=t.session_id||"unknown",n=t.prompt||"",r=t.cwd||"";try{(await K()).authError===!0&&(process.stderr.write(`
10
+ \u26A0 flow-ai-obs: Your Flow credentials have expired.
11
+ Traces will not be captured until you re-authenticate.
12
+ Run: flow-ai-obs auth login
13
+
14
+ `),a("UserPromptSubmit","auth expired \u2014 warning emitted to stderr"));}catch{}let o=te(t.transcript_path)||ht(),s=se(n),i=s?st(s,r):null,u=s?ot(s,r):null;B(e,{traceId:ht(),spanId:b(),startNs:N(),sessionId:e,prompt:n,cwd:r,traceName:o,transcriptPath:t.transcript_path||"",model:process.env[g.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:s,skillContent:i,skillArtifacts:u}),a("UserPromptSubmit",`sid=${e}`,`traceName=${o}`,`slashSkill=${s}`),O(t);}async function ae(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},o=F(e);o&&(o.pendingTool={name:n,inputStr:w(r,k.TOOL_INPUT),startNs:N()},B(e,o)),a("PreToolUse",`sid=${e}`,`tool=${n}`,`stateFound=${!!o}`),O(t);}var hn={name:ut.SCOPE_NAME,version:ut.SCOPE_VERSION},m={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 c(t,e){return e==null||e===""?null:{key:t,value:{stringValue:String(e)}}}function U(...t){return t.filter(e=>e!==null)}function ce(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:hn,spans:Array.isArray(e)?e:[e]}]}]}}var le=$.join(fe.tmpdir(),"flow-obs-requests.ndjson");function ue(t,e,n,r,o){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let s=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(n)},response:{status:r,body:o}});try{R.writeFileSync(le,s+`
15
+ `,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${le}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Ln(t){let e=new URL(t),n=new URL(Y.GATEWAY_HEALTH);return n.hostname=e.hostname,n.port=e.port,n.protocol=e.protocol,n}function pe(t,e){return new Promise((n,r)=>{let o=t._isSSL?Ve__default.default:Ge__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let s=o.request(t,i=>{let u=[];i.on("data",l=>u.push(l)),i.on("end",()=>n({statusCode:i.statusCode??0,body:u.join("")}));});s.setTimeout(1e4,()=>{s.destroy(new Error("Request timeout"));}),s.on("error",i=>r(new Error(`Network error: ${i.message}`))),e&&s.write(e),s.end();})}async function de(t,e){let n;try{n=Ln(t);}catch{return false}let r=n.protocol==="https:";try{let o={};e&&(o.Authorization=String(e).replace(/[\r\n]/g,""));let s=await pe({hostname:n.hostname,port:n.port||(r?443:80),path:n.pathname,method:"GET",headers:o,_isSSL:r},null);return a("checkHealth",`url=${n.href} status=${s.statusCode}`),s.statusCode>=200&&s.statusCode<300}catch{return false}}async function it(t,e,n){let r=JSON.stringify(t),o=new URL(e),s=o.protocol==="https:",i=String(n).replace(/[\r\n]/g,""),u={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(r)};a("sendTraces:request",`POST ${e}`),a("sendTraces:request",`headers=${JSON.stringify({...u,Authorization:i.slice(0,20)+"\u2026"})}`),a("sendTraces:request",`body=${r.slice(0,500)}${r.length>500?"\u2026":""}`);try{let l=await pe({hostname:o.hostname,port:o.port||(s?443:80),path:o.pathname,method:"POST",headers:u,_isSSL:s},r);return a("sendTraces:response",`status=${l.statusCode}`),ue(e,u,r,l.statusCode,l.body),l.statusCode}catch(l){return a("sendTraces:error",l.message),ue(e,u,r,0,l.message),0}}function In(){let t=parseInt(process.env[g.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(A.MIN_TTL_DAYS,Math.min(A.MAX_TTL_DAYS,t)):A.DEFAULT_TTL_DAYS)*24*60*60*1e3}function Nn(){let t=parseInt(process.env[g.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(A.MIN_MAX_FILES,Math.min(A.MAX_MAX_FILES,t)):A.DEFAULT_MAX_FILES}function me(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return $__default.default.join(fe__default.default.tmpdir(),`${A.FILE_PREFIX}${t}.json`)}function wt(){let t=fe__default.default.tmpdir(),e;try{e=R__default.default.readdirSync(t);}catch{return []}return e.filter(n=>n.startsWith(A.FILE_PREFIX)&&n.endsWith(".json")).map(n=>{let r=$__default.default.join(t,n),o=0;try{o=R__default.default.statSync(r).mtimeMs;}catch{}return {full:r,mtime:o}}).sort((n,r)=>n.mtime-r.mtime).map(n=>n.full)}function j(t){try{let e=Nn(),n=wt();if(n.length>=e){let s=n.slice(0,n.length-e+1);for(let i of s)try{R__default.default.unlinkSync(i);}catch{}}let r=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,o={fileId:r,bufferedAt:Date.now(),payload:t};return R__default.default.writeFileSync(me(r),JSON.stringify(o),{encoding:"utf8",mode:384}),a("buffer",`saved fileId=${r}`),r}catch(e){return a("buffer",`saveToBuffer failed: ${e.message}`),null}}function ge(t){let e=wt(),n=t,r=[];for(let o of e){if(r.length>=n)break;try{let s=R__default.default.readFileSync(o,"utf8"),i=JSON.parse(s);i&&i.fileId&&i.payload&&r.push(i);}catch{a("buffer",`skipping malformed file: ${o}`);}}return r}function _e(t){try{R__default.default.unlinkSync(me(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function Se(){let t=Date.now()-In();for(let e of wt())try{let{mtimeMs:n}=R__default.default.statSync(e);n<t&&(R__default.default.unlinkSync(e),a("buffer",`evicted stale: ${$__default.default.basename(e)}`));}catch{}}async function Rn(t){Se();let e=ge(A.REPLAY_BATCH_SIZE);e.length&&(a("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async n=>{try{let r=await it(n.payload,t.endpoint,t.authHeader);r>=200&&r<300?(_e(n.fileId),a("replayBufferedTraces",`replayed fileId=${n.fileId} status=${r}`)):a("replayBufferedTraces",`replay failed fileId=${n.fileId} status=${r}`);}catch(r){a("replayBufferedTraces",`replay error fileId=${n.fileId}: ${r.message}`);}})));}async function Ee(t){let e=await K();if(!e.length)return e.authError&&(a("postToLangfuse","auth refresh failed \u2014 buffering trace"),j(t)),0;let n=await Promise.all(e.map(async s=>{if(s.mode!=="gateway")return {creds:s,healthy:true};let i=await de(s.endpoint,s.authHeader);return {creds:s,healthy:i}})),r=n.find(s=>s.creds.mode==="gateway"&&s.healthy)?.creds??n.find(s=>s.creds.mode==="direct")?.creds;return r&&await Rn(r),(await Promise.all(n.map(async({creds:s,healthy:i})=>{if(s.mode==="gateway"){if(!i)return a("postToLangfuse","gateway health check failed \u2014 buffering trace"),j(t),0;let l=await it(t,s.endpoint,s.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`gateway send failed (status ${l}) \u2014 buffering trace`),j(t)),l}let u=await it(t,s.endpoint,s.authHeader);return (u===0||u>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${u}) \u2014 buffering trace`),j(t)),u}))).find(s=>s!==0)??0}var y="[REDACTED]",Pn=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${y}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${y}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,n)=>`${e}
12
16
  ${y}
13
- ${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${y}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${y}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${y}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${y}`},{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,n)=>`${e}${n}${y}${n}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${y}@`}];function M(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return jn.reduce((n,{re:r,replace:o})=>n.replace(r,o),e)}async function Re(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},o=t.tool_response||"",s=D(e);if(!s){O(t);return}let i=L(),u=s.pendingTool,l=u?.name===n,p=l?u.startNs:String(BigInt(i)-200000000n),_=l?u.inputStr:k(r,w.TOOL_INPUT),h=_,f=null;if(n==="Skill"){let Y=typeof r=="object"&&r!==null?r.skill||r.name||r.skillName||r.commandName||String(Object.values(r)[0]??""):String(r);f=Y?String(Y).trim():null;let C=f?at(f,s.cwd):null;C&&(h=C,s.skillContent||(s.skillContent=C),s.skillArtifacts||(s.skillArtifacts=ct(f,s.cwd))),f&&!s.slashSkill&&(s.slashSkill=f),a("PostToolUse","Skill tool detected",`skillName=${f}`,`contentFound=${!!C}`);}let E=M(k(o,w.TOOL_OUTPUT)),S=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(E.slice(0,500)),T=S?"ERROR":"DEFAULT",X=b(),v=Math.round(Number(BigInt(i)-BigInt(p))/1e6),H={Agent:"AGENT",Task:"AGENT"}[n]??"TOOL",ut=n==="Skill"&&f?f:it(_,60);s.toolCalls.push({tool:n,brief:ut,error:S,durationMs:v});let I=s.spans;I.push({traceId:s.traceId,spanId:X,parentSpanId:s.spanId,name:n,kind:3,startTimeUnixNano:p,endTimeUnixNano:i,attributes:U(c(m.OBS_NAME,n),c(m.OBS_TYPE,H),c(m.OBS_LEVEL,T),c(m.OBS_INPUT,M(h)),c(m.OBS_OUTPUT,E),c("tool.name",n),c("tool.error",String(S)),n==="Skill"&&f?c("skill.name",f):null,n==="Skill"?c("skill.invocation","slash-command"):null),status:{code:S?2:1}}),s.pendingTool=null,x(e,s),a("PostToolUse",`sid=${e}`,`tool=${n}`,`error=${S}`,`durationMs=${v}`,`totalSpans=${I.length}`),O(t);}var Ne={"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 Pe(t,e,n){let r=Object.keys(Ne).find(i=>(t??"").toLowerCase().includes(i));if(!r)return;let o=Ne[r],s=(e*o.input+n*o.output)/1e6;return Math.round(s*1e6)/1e6}async function be(t){let e=t.session_id||"unknown",n=t.stop_reason||"end_turn",r=D(e);if(!r){O(t);return}r.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(r.slashSkill)&&(a("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${r.slashSkill}"`),r.slashSkill=null);let o=L(),s=await se(),i=r.toolCalls,u=r.spans;if(r.slashSkill&&!i.some(d=>d.tool==="Skill")){let d=b(),N=r.skillContent?r.skillContent:JSON.stringify({skill:r.slashSkill});i.push({tool:"Skill",brief:r.slashSkill,error:false,durationMs:0,synthetic:true}),u.push({traceId:r.traceId,spanId:d,parentSpanId:r.spanId,name:"Skill",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:r.startNs,attributes:U(c(m.OBS_NAME,"Skill"),c(m.OBS_TYPE,"TOOL"),c(m.OBS_LEVEL,"DEFAULT"),c(m.OBS_INPUT,N),c(m.OBS_OUTPUT,"loaded via slash command"),c("tool.name","Skill"),c("tool.error","false"),c("skill.name",r.slashSkill),c("skill.invocation","slash-command")),status:{code:1}}),a("Stop",`slashSkill=${r.slashSkill}`,"synthetic span injected");}let l=t.transcript_path||r.transcriptPath||"",p=Ut(l);if(l&&(i.some(d=>d.tool==="Skill"&&!d.synthetic)||!!r.slashSkill)&&!p?.text){await new Promise(N=>setTimeout(N,500));let d=Ut(l);d?.text&&(p=d);}a("Stop",`transcriptPath=${l||"(empty)"}`,`assistantOut=${p?`text=${p.text.length}chars`:"null"}`);let h=i.length,f=i.filter(d=>d.error).length,E=M(p?.text?k(p.text,w.TRACE_OUTPUT):h===0?"No tools used":i.map((d,N)=>`${N+1}. ${d.tool}${d.brief?` \u2192 ${d.brief}`:""}${d.error?" [ERROR]":""}`).join(`
14
- `)),S=p?.inputTokens??0,T=p?.outputTokens??0,X=i.map((d,N)=>`${N+1}. ${d.tool}${d.brief?` \u2192 ${d.brief}`:""}${d.error?" [ERROR]":""} (${d.durationMs}ms)`),v=!!(r.slashSkill||i.some(d=>d.tool==="Skill")),$t=i.some(d=>d.tool==="Agent");if(!v&&!$t){a("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),bt(e),O(t);return}let H=v?"skill":"agent",ut=Math.round(Number(BigInt(o)-BigInt(r.startNs))/1e6),Dt=Pe(r.model,S,T),I=ge(r);I==="prerequisite_required"&&p?.text&&(I="complete"),I==="prerequisite_required"&&(u.push({traceId:r.traceId,spanId:b(),parentSpanId:r.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:o,attributes:U(c(m.OBS_NAME,"prerequisite-check"),c(m.OBS_TYPE,"EVENT"),c(m.OBS_LEVEL,"WARNING"),c(m.OBS_OUTPUT,E),c("skill.name",r.slashSkill||void 0),c("execution_status","prerequisite_required")),status:{code:1}}),a("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${r.slashSkill}`));let Y=(()=>{if(!(!v||!r.prompt)){if(r.slashSkill){let d=r.prompt.replace(new RegExp(`^\\/${r.slashSkill}\\s*`,"i"),"").trim();return d?k(d,w.USER_INSTRUCTION):void 0}return k(r.prompt,w.USER_INSTRUCTION)||void 0}})(),C=JSON.stringify({trace_type:H,...I!==null&&{execution_status:I},...r.slashSkill?{skill_name:r.slashSkill}:{},...r.skillArtifacts?.length&&{skill_artifacts:r.skillArtifacts},...Y!==void 0&&{user_instruction:Y},latency_ms:ut,...S&&{tokens_input:S},...T&&{tokens_output:T},cost_usd:Dt,...r.model?{model:r.model}:{},toolCount:h,errorCount:f,stopReason:n,sessionId:r.sessionId,tools:X.length?X:void 0}),xt=M(k(r.prompt,w.TRACE_INPUT)),Ue=U(c(m.TRACE_NAME,r.traceName),c(m.TRACE_INPUT,xt),c(m.TRACE_OUTPUT,E),c(m.OBS_INPUT,xt),c(m.OBS_OUTPUT,E),c(m.TRACE_METADATA,C),c(m.SESSION_ID,r.sessionId),c(m.USER_ID,s.user),c(m.OBS_TYPE,"GENERATION"),c(m.MODEL,r.model),S?c(m.INPUT_TOKENS,S):null,T?c(m.OUTPUT_TOKENS,T):null,c("claude.stop_reason",n),c("claude.tool_count",String(h)),c("claude.error_count",String(f)),c("claude.session_id",r.sessionId),c("flow.trace_type",H),{key:m.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:H}]}}}),ve={traceId:r.traceId,spanId:r.spanId,name:r.traceName,kind:1,startTimeUnixNano:r.startNs,endTimeUnixNano:o,attributes:Ue,status:{code:f>0?2:1}},Ce=U(c("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),c("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),Bt=[...u,ve];a("Stop",`sid=${e}`,`totalTools=${h}`,`errorTools=${f}`,`spans=${Bt.length}`,`inputTokens=${S}`,`outputTokens=${T}`,`traceOutput="${it(E,80)}"`);let Fe=await Le(_e(Ce,Bt));a("Stop",`POST status=${Fe}`,`traceId=${r.traceId}`),bt(e),O(t);}async function Vn(){let t=process.argv[2];if(t==="UserPromptSubmit"){let n=await Rt(),r;try{r=await K();}catch{process.stdout.write(JSON.stringify(n));return}r.authError?await vt(n,true):r.length>0?await vt(n):process.stdout.write(JSON.stringify(n));return}if(!await oe()){let n=[];process.stdin.on("data",r=>n.push(r)),process.stdin.on("end",()=>process.stdout.write(n.join("")));return}let e=await Rt();switch(t){case "PreToolUse":await Se(e);break;case "PostToolUse":await Re(e);break;case "Stop":await be(e);break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
15
- `),process.stdout.write(JSON.stringify(e));}}Vn().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
17
+ ${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${y}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${y}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${y}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${y}`},{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,n)=>`${e}${n}${y}${n}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${y}@`}];function M(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return Pn.reduce((n,{re:r,replace:o})=>n.replace(r,o),e)}async function Te(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},o=t.tool_response||"",s=F(e);if(!s){O(t);return}let i=N(),u=s.pendingTool,l=u?.name===n,p=l?u.startNs:String(BigInt(i)-200000000n),S=l?u.inputStr:w(r,k.TOOL_INPUT),T=S,d=null;if(n==="Skill"){let H=typeof r=="object"&&r!==null?r.skill||r.name||r.skillName||r.commandName||String(Object.values(r)[0]??""):String(r);d=H?String(H).trim():null;let C=d?st(d,s.cwd):null;C&&(T=C,s.skillContent||(s.skillContent=C),s.skillArtifacts||(s.skillArtifacts=ot(d,s.cwd))),d&&!s.slashSkill&&(s.slashSkill=d),a("PostToolUse","Skill tool detected",`skillName=${d}`,`contentFound=${!!C}`);}let E=M(w(o,k.TOOL_OUTPUT)),_=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(E.slice(0,500)),h=_?"ERROR":"DEFAULT",J=b(),v=Math.round(Number(BigInt(i)-BigInt(p))/1e6),x={Agent:"AGENT",Task:"AGENT"}[n]??"TOOL",at=n==="Skill"&&d?d:rt(S,60);s.toolCalls.push({tool:n,brief:at,error:_,durationMs:v});let L=s.spans;L.push({traceId:s.traceId,spanId:J,parentSpanId:s.spanId,name:n,kind:3,startTimeUnixNano:p,endTimeUnixNano:i,attributes:U(c(m.OBS_NAME,n),c(m.OBS_TYPE,x),c(m.OBS_LEVEL,h),c(m.OBS_INPUT,M(T)),c(m.OBS_OUTPUT,E),c("tool.name",n),c("tool.error",String(_)),n==="Skill"&&d?c("skill.name",d):null,n==="Skill"?c("skill.invocation","slash-command"):null),status:{code:_?2:1}}),s.pendingTool=null,B(e,s),a("PostToolUse",`sid=${e}`,`tool=${n}`,`error=${_}`,`durationMs=${v}`,`totalSpans=${L.length}`),O(t);}var he={"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 ye(t,e,n){let r=Object.keys(he).find(i=>(t??"").toLowerCase().includes(i));if(!r)return;let o=he[r],s=(e*o.input+n*o.output)/1e6;return Math.round(s*1e6)/1e6}async function Ae(t){let e=t.session_id||"unknown",n=t.stop_reason||"end_turn",r=F(e);if(!r){O(t);return}r.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(r.slashSkill)&&(a("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${r.slashSkill}"`),r.slashSkill=null);let o=N(),s=await jt(),i=r.toolCalls,u=r.spans;if(r.slashSkill&&!i.some(f=>f.tool==="Skill")){let f=b(),P=r.skillContent?r.skillContent:JSON.stringify({skill:r.slashSkill});i.push({tool:"Skill",brief:r.slashSkill,error:false,durationMs:0,synthetic:true}),u.push({traceId:r.traceId,spanId:f,parentSpanId:r.spanId,name:"Skill",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:r.startNs,attributes:U(c(m.OBS_NAME,"Skill"),c(m.OBS_TYPE,"TOOL"),c(m.OBS_LEVEL,"DEFAULT"),c(m.OBS_INPUT,P),c(m.OBS_OUTPUT,"loaded via slash command"),c("tool.name","Skill"),c("tool.error","false"),c("skill.name",r.slashSkill),c("skill.invocation","slash-command")),status:{code:1}}),a("Stop",`slashSkill=${r.slashSkill}`,"synthetic span injected");}let l=t.transcript_path||r.transcriptPath||"",p=Ot(l);if(l&&(i.some(f=>f.tool==="Skill"&&!f.synthetic)||!!r.slashSkill)&&!p?.text){await new Promise(P=>setTimeout(P,500));let f=Ot(l);f?.text&&(p=f);}a("Stop",`transcriptPath=${l||"(empty)"}`,`assistantOut=${p?`text=${p.text.length}chars`:"null"}`);let T=i.length,d=i.filter(f=>f.error).length,E=M(p?.text?w(p.text,k.TRACE_OUTPUT):T===0?"No tools used":i.map((f,P)=>`${P+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""}`).join(`
18
+ `)),_=p?.inputTokens??0,h=p?.outputTokens??0,J=i.map((f,P)=>`${P+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""} (${f.durationMs}ms)`),v=!!(r.slashSkill||i.some(f=>f.tool==="Skill")),Lt=i.some(f=>f.tool==="Agent");if(!v&&!Lt){a("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),At(e),O(t);return}let x=v?"skill":"agent",at=Math.round(Number(BigInt(o)-BigInt(r.startNs))/1e6),It=ye(r.model,_,h),L=oe(r);L==="prerequisite_required"&&p?.text&&(L="complete"),L==="prerequisite_required"&&(u.push({traceId:r.traceId,spanId:b(),parentSpanId:r.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:o,attributes:U(c(m.OBS_NAME,"prerequisite-check"),c(m.OBS_TYPE,"EVENT"),c(m.OBS_LEVEL,"WARNING"),c(m.OBS_OUTPUT,E),c("skill.name",r.slashSkill||void 0),c("execution_status","prerequisite_required")),status:{code:1}}),a("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${r.slashSkill}`));let H=(()=>{if(!(!v||!r.prompt)){if(r.slashSkill){let f=r.prompt.replace(new RegExp(`^\\/${r.slashSkill}\\s*`,"i"),"").trim();return f?w(f,k.USER_INSTRUCTION):void 0}return w(r.prompt,k.USER_INSTRUCTION)||void 0}})(),C=JSON.stringify({trace_type:x,...L!==null&&{execution_status:L},...r.slashSkill?{skill_name:r.slashSkill}:{},...r.skillArtifacts?.length&&{skill_artifacts:r.skillArtifacts},...H!==void 0&&{user_instruction:H},latency_ms:at,..._&&{tokens_input:_},...h&&{tokens_output:h},cost_usd:It,...r.model?{model:r.model}:{},toolCount:T,errorCount:d,stopReason:n,sessionId:r.sessionId,tools:J.length?J:void 0}),Nt=M(w(r.prompt,k.TRACE_INPUT)),Oe=U(c(m.TRACE_NAME,r.traceName),c(m.TRACE_INPUT,Nt),c(m.TRACE_OUTPUT,E),c(m.OBS_INPUT,Nt),c(m.OBS_OUTPUT,E),c(m.TRACE_METADATA,C),c(m.SESSION_ID,r.sessionId),c(m.USER_ID,s.user),c(m.OBS_TYPE,"GENERATION"),c(m.MODEL,r.model),_?c(m.INPUT_TOKENS,_):null,h?c(m.OUTPUT_TOKENS,h):null,c("claude.stop_reason",n),c("claude.tool_count",String(T)),c("claude.error_count",String(d)),c("claude.session_id",r.sessionId),c("flow.trace_type",x),{key:m.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:x}]}}}),ke={traceId:r.traceId,spanId:r.spanId,name:r.traceName,kind:1,startTimeUnixNano:r.startNs,endTimeUnixNano:o,attributes:Oe,status:{code:d>0?2:1}},we=U(c("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),c("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),Rt=[...u,ke];a("Stop",`sid=${e}`,`totalTools=${T}`,`errorTools=${d}`,`spans=${Rt.length}`,`inputTokens=${_}`,`outputTokens=${h}`,`traceOutput="${rt(E,80)}"`);let Le=await Ee(ce(we,Rt));a("Stop",`POST status=${Le}`,`traceId=${r.traceId}`),At(e),O(t);}async function bn(){let t=process.argv[2];if(!await Jt()){let n=[];process.stdin.on("data",r=>n.push(r)),process.stdin.on("end",()=>process.stdout.write(n.join("")));return}let e=await qt();switch(t){case "UserPromptSubmit":await ie(e);break;case "PreToolUse":await ae(e);break;case "PostToolUse":await Te(e);break;case "Stop":await Ae(e);break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
19
+ `),process.stdout.write(JSON.stringify(e));}}bn().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
16
20
  `),process.exit(0);});
package/dist/setup.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';var child_process=require('child_process'),util=require('util'),i=require('fs'),d=require('path'),l=require('os'),Ge=require('https');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var i__namespace=/*#__PURE__*/_interopNamespace(i);var d__namespace=/*#__PURE__*/_interopNamespace(d);var l__namespace=/*#__PURE__*/_interopNamespace(l);var Ge__default=/*#__PURE__*/_interopDefault(Ge);var _e=Object.defineProperty;var T=(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 O=(e,t)=>()=>(e&&(t=e(e=0)),t);var Te=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),v=(e,t)=>{for(var r in t)_e(e,r,{get:t[r],enumerable:true});};var Z={};v(Z,{MacOsKeyVaultProvider:()=>U});var N,U,Q=O(()=>{N=util.promisify(child_process.execFile),U=class{static async isAvailable(){try{return i.accessSync("/usr/bin/security",i.constants.X_OK),!0}catch{return false}}async getSecret(t,r){try{let{stdout:n}=await N("security",["find-generic-password","-w","-a",r,"-s",t]);return n.trim()||null}catch{return null}}async setSecret(t,r,n){await N("security",["add-generic-password","-U","-a",r,"-s",t,"-w",n]);}async deleteSecret(t,r){try{return await N("security",["delete-generic-password","-a",r,"-s",t]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};});var te={};v(te,{LinuxKeyVaultProvider:()=>b});var ee,b,re=O(()=>{ee=util.promisify(child_process.execFile),b=class{static async isAvailable(){let t=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let r of t)try{return i.accessSync(r,i.constants.X_OK),!0}catch{}return false}async getSecret(t,r){try{let{stdout:n}=await ee("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=child_process.spawn("secret-tool",["store","--label",t,"service",t,"account",r]);a.on("error",o),a.on("close",f=>{f===0?s():o(new Error(`secret-tool exited with code ${f}`));}),a.stdin.write(n),a.stdin.end();});}async deleteSecret(t,r){try{return await ee("secret-tool",["clear","service",t,"account",r]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var ne={};v(ne,{WindowsKeyVaultProvider:()=>F});var F,se=O(()=>{F=class{static async isAvailable(){try{return await T("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(t,r){return T("keytar").getPassword(t,r)}async setSecret(t,r,n){await T("keytar").setPassword(t,r,n);}async deleteSecret(t,r){return T("keytar").deletePassword(t,r)}getStoragePath(){return "Windows Credential Manager"}};});var de=Te((qt,je)=>{je.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.5.2-beta.363",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:"jest",typecheck:"tsc --noEmit",lint:"eslint src bin scripts",format:'prettier --write "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"format:check":'prettier --check "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"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 dist/cli.js install","auth:login":"node dist/cli.js auth login","auth:logout":"node dist/cli.js auth logout","auth:status":"node dist/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:{},optionalDependencies:{keytar:"7.9.0"},devDependencies:{"@changesets/changelog-github":"^0.6.0","@changesets/cli":"^2.30.0","@types/jest":"^30.0.0","@types/node":"^25.8.0",jest:"^30.4.2","ts-jest":"^29.4.9",tsup:"^8.5.1","eslint-config-prettier":"^10.1.5",prettier:"^3.5.3",typescript:"^6.0.3","typescript-eslint":"^8.33.0"},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"}};});function x(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let t=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(t)return {home:t,username:process.env.SUDO_USER}}return {home:l__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||l__namespace.userInfo().username}}function R(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let r=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();r&&/^[A-Za-z]:\\/.test(r)&&(e=r);}if(e){let t=e.replace(/^([A-Za-z]):/,(r,n)=>`/mnt/${n.toLowerCase()}`).replace(/\\/g,"/");return d__namespace.join(t,".claude","settings.json")}return d__namespace.join(l__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||l__namespace.homedir();return d__namespace.join(e,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let t=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(t)return d__namespace.join(t,".claude","settings.json")}return d__namespace.join(l__namespace.homedir(),".claude","settings.json")}var V="flow-ai-obs",Y="config.json";function ye(){if(process.platform==="win32"){let r=process.env.APPDATA||d__namespace.join(l__namespace.homedir(),"AppData","Roaming");return d__namespace.join(r,V,Y)}let e=x(),t=process.env.XDG_CONFIG_HOME||d__namespace.join(e.home,".config");return d__namespace.join(t,V,Y)}function Se(){try{let e=i__namespace.readFileSync(ye(),"utf8");return JSON.parse(e)}catch{return {}}}function I(){return Se().baseUrl??null}var G=I()??process.env.FLOW_BASE_URL??"https://flow.ciandt.com";function B(){return I()??process.env.FLOW_BASE_URL??"https://flow.ciandt.com"}function P(){let e=B();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${e}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${e}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${e}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${e}/otel`}}var we=P(),y={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials"},S="FLOW-nodejs",w="config.json";var W={ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${G}/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"},K={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:we.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"},g={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",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"};var J={LOCK_STALE_MS:3e4},X={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15};var q="flow-ai-obs-debug.log";({API_URL:process.env.FLOW_METRICS_URL||`${G}/metrics-collector-api/log-event`});var C={credentials:"credentials","token-cache":"tokenCache"};function h(){let e=l__namespace.default.homedir();if(process.platform==="darwin")return d__namespace.default.join(e,"Library","Preferences",S,w);if(process.platform==="win32"){let r=process.env.APPDATA??d__namespace.default.join(e,"AppData","Roaming");return d__namespace.default.join(r,S,w)}let t=process.env.XDG_CONFIG_HOME??d__namespace.default.join(e,".config");return d__namespace.default.join(t,S,w)}function k(){try{let e=i__namespace.default.readFileSync(h(),"utf8");return JSON.parse(e)}catch{return {}}}function z(e){let t=h();i__namespace.default.mkdirSync(d__namespace.default.dirname(t),{recursive:true}),i__namespace.default.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var A=class{static isAvailable(){return true}static hasExistingData(){try{if(!i__namespace.default.existsSync(h()))return !1;let t=JSON.parse(i__namespace.default.readFileSync(h(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,r){let n=k(),s=C[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,r,n){let s=k(),o=C[r]??r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;z(s);}async deleteSecret(t,r){let n=k(),s=C[r]??r;return s in n?(delete n[s],z(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${h()}`}};async function oe(){return await Ue()??new A}async function Ue(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=await Promise.resolve().then(()=>(Q(),Z));return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=await Promise.resolve().then(()=>(re(),te));return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=await Promise.resolve().then(()=>(se(),ne));return await e.isAvailable()?new e:null}default:return null}}var be=y.SERVICE,Fe=y.ACCOUNT_CREDS,D=null;function De(){return D||(D=oe()),D}async function $(){let t=await(await De()).getSecret(be,Fe);if(!t)return null;try{return JSON.parse(t)}catch{return null}}d.join(l.tmpdir(),q);var Ve=J.LOCK_STALE_MS;function ie(e){try{let t=i__namespace.statSync(e);Date.now()-t.mtimeMs>Ve&&i__namespace.unlinkSync(e);}catch{}try{i__namespace.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 ae(e){try{i__namespace.unlinkSync(e);}catch{}}function Ye(e,t){let n=(Array.isArray(e)?e:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(a=>!a.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [t,...n]}function ce(){let e=R(),t=e+".lock",r=[];i__namespace.mkdirSync(d__namespace.dirname(e),{recursive:true}),ie(t);try{if(i__namespace.existsSync(e)){i__namespace.copyFileSync(e,e+".bkp");try{i__namespace.chmodSync(e+".bkp",384);}catch{}}let n={};try{n=JSON.parse(i__namespace.readFileSync(e,"utf8"));}catch{}let s=n.env&&typeof n.env=="object"?n.env:{};n.env={...K,...W,...s},n.otelHeadersHelper="flow-ai-obs otel-headers",(!n.hooks||typeof n.hooks!="object"||Array.isArray(n.hooks))&&(n.hooks={});let o=(c,_)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${c}`,timeout:_}]}),a=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],f=n.hooks;for(let c of a){let _=Ye(f[c],o(c,X[c]));_.length>1&&r.push(c),f[c]=_;}i__namespace.writeFileSync(e,JSON.stringify(n,null,2)+`
3
- `,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(e,384);}catch{}}finally{ae(t);}return {settingsPath:e,preserved:r}}function le(e){let t=R(),r=t+".lock";i__namespace.mkdirSync(d__namespace.dirname(t),{recursive:true}),ie(r);try{let n={};try{n=JSON.parse(i__namespace.readFileSync(t,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,e),i__namespace.writeFileSync(t,JSON.stringify(n,null,2)+`
4
- `,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(t,384);}catch{}}finally{ae(r);}}function ue(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 pe(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}.`}var M;function me(){return M||(M=de()),M}var ge=d__namespace.default.join(l__namespace.default.tmpdir(),"flow-obs-update-cache.json"),Ke=1440*60*1e3,Je=3e3;function Xe(e,t){let r=o=>{let a=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return a?[+a[1],+a[2],+a[3]]:null},n=r(e),s=r(t);return !n||!s?false:s[0]!==n[0]?s[0]>n[0]:s[1]!==n[1]?s[1]>n[1]:s[2]>n[2]}function qe(){try{let e=JSON.parse(i__namespace.default.readFileSync(ge,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=Ke?null:e}catch{return null}}function ze(e,t,r=Date.now()){try{i__namespace.default.writeFileSync(ge,JSON.stringify({latestVersion:e,updatePriority:t??null,checkedAt:r}),{mode:384});}catch{}}function Ze(e){let t=me().name,r=Ge__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:Je},n=>{if(n.statusCode!==200)return n.resume(),e(new Error(`HTTP ${n.statusCode}`));let s="";n.setEncoding("utf8"),n.on("data",o=>{s+=o;}),n.on("end",()=>{try{let o=JSON.parse(s);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);}});});r.on("error",e),r.on("timeout",()=>{r.destroy(new Error("timeout"));});}function he(){try{if(qe())return;setImmediate(()=>{Ze((e,t)=>{e||!t||Xe(me().version,t.version)&&ze(t.version,t.updatePriority,0);});});}catch{}}var Qe=d__namespace.default.resolve(__dirname,".."),et=process.env.INIT_CWD?d__namespace.default.resolve(process.env.INIT_CWD):null;et===Qe&&process.exit(0);async function tt(){try{ce();}catch{}let e=await $();if(!e){process.stderr.write(`
2
+ 'use strict';var child_process=require('child_process'),util=require('util'),s=require('fs'),u=require('path'),_=require('os');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var s__namespace=/*#__PURE__*/_interopNamespace(s);var u__namespace=/*#__PURE__*/_interopNamespace(u);var ___namespace=/*#__PURE__*/_interopNamespace(_);var oe=Object.defineProperty;var T=(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 A=(e,t)=>()=>(e&&(t=e(e=0)),t);var L=(e,t)=>{for(var r in t)oe(e,r,{get:t[r],enumerable:true});};var x={};L(x,{MacOsKeyVaultProvider:()=>N});var I,N,G=A(()=>{I=util.promisify(child_process.execFile),N=class{static async isAvailable(){try{return s.accessSync("/usr/bin/security",s.constants.X_OK),!0}catch{return false}}async getSecret(t,r){try{let{stdout:n}=await I("security",["find-generic-password","-w","-a",r,"-s",t]);return n.trim()||null}catch{return null}}async setSecret(t,r,n){await I("security",["add-generic-password","-U","-a",r,"-s",t,"-w",n]);}async deleteSecret(t,r){try{return await I("security",["delete-generic-password","-a",r,"-s",t]),!0}catch{return false}}getStoragePath(){return "macOS Keychain"}};});var B={};L(B,{LinuxKeyVaultProvider:()=>P});var V,P,K=A(()=>{V=util.promisify(child_process.execFile),P=class{static async isAvailable(){let t=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let r of t)try{return s.accessSync(r,s.constants.X_OK),!0}catch{}return false}async getSecret(t,r){try{let{stdout:n}=await V("secret-tool",["lookup","service",t,"account",r]);return n.trim()||null}catch{return null}}async setSecret(t,r,n){await new Promise((o,i)=>{let a=child_process.spawn("secret-tool",["store","--label",t,"service",t,"account",r]);a.on("error",i),a.on("close",f=>{f===0?o():i(new Error(`secret-tool exited with code ${f}`));}),a.stdin.write(n),a.stdin.end();});}async deleteSecret(t,r){try{return await V("secret-tool",["clear","service",t,"account",r]),!0}catch{return false}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var j={};L(j,{WindowsKeyVaultProvider:()=>C});var C,X=A(()=>{C=class{static async isAvailable(){try{return await T("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return false}}async getSecret(t,r){return T("keytar").getPassword(t,r)}async setSecret(t,r,n){await T("keytar").setPassword(t,r,n);}async deleteSecret(t,r){return T("keytar").deletePassword(t,r)}getStoragePath(){return "Windows Credential Manager"}};});var l=process.env.FLOW_BASE_URL||"https://flow.ciandt.com",w={AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${l}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${l}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${l}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${l}/otel`},S={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials"},y="FLOW-nodejs",h="config.json";var D={ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${l}/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"},M={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:w.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"},d={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",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"};var H={LOCK_STALE_MS:3e4},$={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15};var Y="flow-ai-obs-debug.log";({API_URL:process.env.FLOW_METRICS_URL||`${l}/metrics-collector-api/log-event`});var R={credentials:"credentials","token-cache":"tokenCache"};function E(){let e=___namespace.default.homedir();if(process.platform==="darwin")return u__namespace.default.join(e,"Library","Preferences",y,h);if(process.platform==="win32"){let r=process.env.APPDATA??u__namespace.default.join(e,"AppData","Roaming");return u__namespace.default.join(r,y,h)}let t=process.env.XDG_CONFIG_HOME??u__namespace.default.join(e,".config");return u__namespace.default.join(t,y,h)}function v(){try{let e=s__namespace.default.readFileSync(E(),"utf8");return JSON.parse(e)}catch{return {}}}function W(e){let t=E();s__namespace.default.mkdirSync(u__namespace.default.dirname(t),{recursive:true}),s__namespace.default.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var O=class{static isAvailable(){return true}static hasExistingData(){try{if(!s__namespace.default.existsSync(E()))return !1;let t=JSON.parse(s__namespace.default.readFileSync(E(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,r){let n=v(),o=R[r]??r,i=n[o];return i?typeof i=="string"?i:JSON.stringify(i):null}async setSecret(t,r,n){let o=v(),i=R[r]??r;if(r==="token-cache")try{o[i]=JSON.parse(n);}catch{o[i]=n;}else o[i]=n;W(o);}async deleteSecret(t,r){let n=v(),o=R[r]??r;return o in n?(delete n[o],W(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${E()}`}};async function J(){return await me()??new O}async function me(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=await Promise.resolve().then(()=>(G(),x));return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=await Promise.resolve().then(()=>(K(),B));return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=await Promise.resolve().then(()=>(X(),j));return await e.isAvailable()?new e:null}default:return null}}var _e=S.SERVICE,ge=S.ACCOUNT_CREDS,k=null;function Te(){return k||(k=J()),k}async function U(){let t=await(await Te()).getSecret(_e,ge);if(!t)return null;try{return JSON.parse(t)}catch{return null}}u.join(_.tmpdir(),Y);function F(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let r=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();r&&/^[A-Za-z]:\\/.test(r)&&(e=r);}if(e){let t=e.replace(/^([A-Za-z]):/,(r,n)=>`/mnt/${n.toLowerCase()}`).replace(/\\/g,"/");return u__namespace.join(t,".claude","settings.json")}return u__namespace.join(___namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||___namespace.homedir();return u__namespace.join(e,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let t=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(t)return u__namespace.join(t,".claude","settings.json")}return u__namespace.join(___namespace.homedir(),".claude","settings.json")}var Ae=H.LOCK_STALE_MS;function z(e){try{let t=s__namespace.statSync(e);Date.now()-t.mtimeMs>Ae&&s__namespace.unlinkSync(e);}catch{}try{s__namespace.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 Z(e){try{s__namespace.unlinkSync(e);}catch{}}function Le(e,t){let n=(Array.isArray(e)?e:[]).map(o=>{if(!Array.isArray(o?.hooks))return null;let i=o.hooks.filter(a=>!a.command?.startsWith?.("flow-ai-obs "));return i.length>0?{...o,hooks:i}:null}).filter(o=>o!=null);return [t,...n]}function Q(){let e=F(),t=e+".lock",r=[];s__namespace.mkdirSync(u__namespace.dirname(e),{recursive:true}),z(t);try{if(s__namespace.existsSync(e)){s__namespace.copyFileSync(e,e+".bkp");try{s__namespace.chmodSync(e+".bkp",384);}catch{}}let n={};try{n=JSON.parse(s__namespace.readFileSync(e,"utf8"));}catch{}let o=n.env&&typeof n.env=="object"?n.env:{};n.env={...M,...D,...o},n.otelHeadersHelper="flow-ai-obs otel-headers",(!n.hooks||typeof n.hooks!="object"||Array.isArray(n.hooks))&&(n.hooks={});let i=(c,g)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${c}`,timeout:g}]}),a=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],f=n.hooks;for(let c of a){let g=Le(f[c],i(c,$[c]));g.length>1&&r.push(c),f[c]=g;}s__namespace.writeFileSync(e,JSON.stringify(n,null,2)+`
3
+ `,{encoding:"utf8",mode:384});try{s__namespace.chmodSync(e,384);}catch{}}finally{Z(t);}return {settingsPath:e,preserved:r}}function ee(e){let t=F(),r=t+".lock";s__namespace.mkdirSync(u__namespace.dirname(t),{recursive:true}),z(r);try{let n={};try{n=JSON.parse(s__namespace.readFileSync(t,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,e),s__namespace.writeFileSync(t,JSON.stringify(n,null,2)+`
4
+ `,{encoding:"utf8",mode:384});try{s__namespace.chmodSync(t,384);}catch{}}finally{Z(r);}}function te(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:o,tenant:i}=r;return !n||!o||!i?null:{clientId:n,clientSecret:o,tenant:i}}catch{return null}}function re(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}.`}var we=u__namespace.default.resolve(__dirname,".."),Re=process.env.INIT_CWD?u__namespace.default.resolve(process.env.INIT_CWD):null;Re===we&&process.exit(0);async function ve(){try{Q();}catch{}let e=await U();if(!e){process.stderr.write(`
5
5
  [flow-ai-obs] No credentials found.
6
6
  Run \`flow-ai-obs auth login\` to authenticate and enable telemetry.
7
7
 
8
- `);return}let t=ue(process.env[g.ANTHROPIC_AUTH_TOKEN]);if(!t||t.clientId!==e.clientId||t.clientSecret!==e.clientSecret||t.tenant!==e.tenant)try{let n=pe(e);le({[g.ANTHROPIC_AUTH_TOKEN]:n});}catch{}}tt().catch(()=>{}).finally(()=>he());
8
+ `);return}let t=te(process.env[d.ANTHROPIC_AUTH_TOKEN]);if(!t||t.clientId!==e.clientId||t.clientSecret!==e.clientSecret||t.tenant!==e.tenant)try{let n=re(e);ee({[d.ANTHROPIC_AUTH_TOKEN]:n});}catch{}}ve().catch(()=>{});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ciandt-flow/flow-ai-obs",
3
- "version": "0.5.2-beta.363",
3
+ "version": "0.6.0",
4
4
  "description": "Claude Code hooks for Langfuse OTLP tracing — cross-platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -45,8 +45,7 @@
45
45
  "author": "CI&T Flow Team",
46
46
  "license": "SEE LICENSE IN LICENSE.md",
47
47
  "private": false,
48
- "dependencies": {},
49
- "optionalDependencies": {
48
+ "dependencies": {
50
49
  "keytar": "7.9.0"
51
50
  },
52
51
  "devDependencies": {