@ciandt-flow/flow-ai-obs 0.6.0 → 0.7.0-beta.394

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