@ciandt-flow/flow-ai-obs 0.12.0 → 0.12.1-beta.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,16 +1,23 @@
1
- 'use strict';var child_process=require('child_process'),util=require('util'),R=require('fs'),M=require('path'),me=require('os'),Je=require('https'),Ke=require('http'),crypto=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var R__default=/*#__PURE__*/_interopDefault(R);var M__default=/*#__PURE__*/_interopDefault(M);var me__default=/*#__PURE__*/_interopDefault(me);var Je__default=/*#__PURE__*/_interopDefault(Je);var Ke__default=/*#__PURE__*/_interopDefault(Ke);var Pe=Object.defineProperty;var ot=(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 gt=(t,e,r)=>()=>{if(r)throw r[0];try{return t&&(e=t(t=0)),e}catch(n){throw r=[n],n}};var _t=(t,e)=>{for(var r in e)Pe(t,r,{get:e[r],enumerable:true});};var xt={};_t(xt,{MacOsKeyVaultProvider:()=>yt});var At,yt,Bt=gt(()=>{"use strict";At=util.promisify(child_process.execFile),yt=class{static async isAvailable(){try{return R.accessSync("/usr/bin/security",R.constants.X_OK),!0}catch{return !1}}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 !1}}getStoragePath(){return "macOS Keychain"}};});var Ht={};_t(Ht,{LinuxKeyVaultProvider:()=>Ot});var Yt,Ot,Vt=gt(()=>{"use strict";Yt=util.promisify(child_process.execFile),Ot=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 !1}async getSecret(e,r){try{let{stdout:n}=await Yt("secret-tool",["lookup","service",e,"account",r]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await new Promise((i,s)=>{let o=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",r]);o.on("error",s),o.on("close",c=>{c===0?i():s(new Error(`secret-tool exited with code ${c}`));}),o.stdin.write(n),o.stdin.end();});}async deleteSecret(e,r){try{return await Yt("secret-tool",["clear","service",e,"account",r]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var Gt={};_t(Gt,{WindowsKeyVaultProvider:()=>kt});var kt,Wt=gt(()=>{"use strict";kt=class{static async isAvailable(){try{return await ot("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,r){return ot("keytar").getPassword(e,r)}async setSecret(e,r,n){await ot("keytar").setPassword(e,r,n);}async deleteSecret(e,r){return ot("keytar").deletePassword(e,r)}getStoragePath(){return "Windows Credential Manager"}};});var Ne="https://flow.ciandt.com";function D(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():Ne}function W(){let t=D();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${t}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${t}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${t}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${t}/otel`}}W();var it={SERVICE:"flow-plugins-cli",ACCOUNT_TOKEN:"token-cache"},at="FLOW-nodejs",ct="config.json",Tt={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};var _={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",FLOW_OBS_USE_JSON_VAULT:"FLOW_TELEMETRY_USE_JSON_VAULT",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"};var J={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3};var O={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},Dt="flow-ai-obs-debug.log",k={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4};function St(){let t=D();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Et={credentials:"credentials","token-cache":"tokenCache"};function K(){let t=me__default.default.homedir();if(process.platform==="darwin")return M__default.default.join(t,"Library","Preferences",at,ct);if(process.platform==="win32"){let r=process.env.APPDATA??M__default.default.join(t,"AppData","Roaming");return M__default.default.join(r,at,ct)}let e=process.env.XDG_CONFIG_HOME??M__default.default.join(t,".config");return M__default.default.join(e,at,ct)}function ht(){try{let t=R__default.default.readFileSync(K(),"utf8");return JSON.parse(t)}catch{return {}}}function Mt(t){let e=K();R__default.default.mkdirSync(M__default.default.dirname(e),{recursive:true}),R__default.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var q=class{static isAvailable(){return true}static hasExistingData(){try{if(!R__default.default.existsSync(K()))return !1;let e=JSON.parse(R__default.default.readFileSync(K(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,r){let n=ht(),i=Et[r]??r,s=n[i];return s?typeof s=="string"?s:JSON.stringify(s):null}async setSecret(e,r,n){let i=ht(),s=Et[r]??r;if(r==="token-cache")try{i[s]=JSON.parse(n);}catch{i[s]=n;}else i[s]=n;Mt(i);}async deleteSecret(e,r){let n=ht(),i=Et[r]??r;return i in n?(delete n[i],Mt(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${K()}`}};async function Jt(){return process.env[_.FLOW_OBS_USE_JSON_VAULT]==="1"?new q:await Ye()??new q}async function Ye(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Bt(),xt));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Vt(),Ht));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Wt(),Gt));return await t.isAvailable()?new t:null}default:return null}}var Kt=it.SERVICE,jt=it.ACCOUNT_TOKEN,wt=null;function qt(){return wt||(wt=Jt()),wt}async function Lt(t){await(await qt()).setSecret(Kt,jt,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function Rt(){let e=await(await qt()).getSecret(Kt,jt);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 It(){let t=await Rt();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 We=M.join(me.tmpdir(),Dt);function a(...t){if(process.env[_.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
2
- `;try{R.writeFileSync(We,e,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
3
- `);}}var b=class extends Error{statusCode;constructor(e,r=0){super(e),this.name="AuthError",this.statusCode=r;}},je=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function qe(t){if(!je.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var Xt={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 Xe(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}`:"")),Xt[n.error]))return new b(Xt[n.error],t)}catch{}return t===401||t===403||t===500?new b("Invalid credentials",t):t>=400&&t<500?new b("Authentication request was rejected",t):new Error("Authentication service unavailable, please try again later")}function X(t){return new Promise((e,r)=>{try{qe(t.tenant);}catch(p){return r(p)}let n=JSON.stringify({clientSecret:t.clientSecret}),i=new URL(W().AUTH_ENGINE),s=i.protocol==="https:",o={hostname:i.hostname,port:i.port||(s?443:80),path:i.pathname+i.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(n),FlowTenant:t.tenant}};a("getToken",`requesting token tenant=${t.tenant} host=${o.hostname} path=${o.path}`);let l=(s?Je__default.default:Ke__default.default).request(o,p=>{let T=[];p.on("data",S=>T.push(S)),p.on("end",()=>{let S=T.join("");if((p.statusCode??0)>=400)return r(Xe(p.statusCode??0,S));let m;try{m=JSON.parse(S);}catch{return r(new Error("Invalid response from auth engine"))}let g=m.expires_at??new Date(Date.now()+(m.expires_in??3600)*1e3).toISOString();if(!m.access_token)return r(new Error("Auth engine returned an empty access token. Check FLOW_BASE_URL and credentials."));e({accessToken:m.access_token,expiresAt:g});});});l.on("error",p=>r(new Error(`Network error: ${p.message}`))),l.setTimeout(J.REQUEST_TIMEOUT_MS,()=>{l.destroy(new Error("Request timeout"));}),l.write(n),l.end();})}var ze=[/^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 Ze(t){return ze.some(e=>e.test(t))}function Qe(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:i,tenant:s}=r;return !n||!i||!s?null:{clientId:n,clientSecret:i,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[_.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&&Ze(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function zt(){let t=ut(process.env[_.ANTHROPIC_AUTH_TOKEN]);return t?{user:await It().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function tr(){return new Date().toISOString().slice(0,10)}async function er(t){let e=tr(),r=await Rt();if(r?.lastAuthCheckAt!==e){a("getOrRefreshToken",`daily auth check (last: ${r?.lastAuthCheckAt??"never"})`);let s=J.MAX_RETRY_ATTEMPTS;for(let o=1;o<=s;o++)try{let c=await X(t);try{await Lt({...c,lastAuthCheckAt:e});}catch(l){a("getOrRefreshToken",`saveTokenCache failed (non-fatal): ${l.message}`);}return a("getOrRefreshToken",`daily check passed (attempt ${o}), expires=${c.expiresAt}`),c.accessToken}catch(c){if(c instanceof b){if(c.statusCode!==500)throw a("getOrRefreshToken",`daily check auth error (${c.statusCode}) \u2014 propagating immediately`),c;if(o<s){a("getOrRefreshToken",`daily check 500 error (attempt ${o}/${s}) \u2014 retrying in 1s`),await new Promise(l=>setTimeout(l,J.RETRY_DELAY_MS));continue}throw a("getOrRefreshToken",`daily check failed after ${s} attempts \u2014 propagating`),c}a("getOrRefreshToken",`daily check network error \u2014 using cache: ${c.message}`);break}}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 i=await X(t);try{await Lt({...i,lastAuthCheckAt:e});}catch(s){a("getOrRefreshToken",`token cache save failed (non-fatal): ${s.message}`);}return a("getOrRefreshToken",`token refreshed, expires=${i.expiresAt}`),i.accessToken}function rr(t,e){let r=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function nr(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 x(){let t=[],e=process.env[_.ANTHROPIC_MODEL]??"",r=ut(process.env[_.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:"",i=process.env[_.FLOW_TELEMETRY]==="true",s=process.env[_.LANGFUSE_BASE_URL],o=process.env[_.LANGFUSE_PUBLIC_KEY],c=process.env[_.LANGFUSE_SECRET_KEY];if(i&&s&&o&&c){let m="",g=n;r&&(m=await It().catch(()=>null)??r.clientId);let E={user:m??"",tenant:g??"",team:"",project:"",model:e};t.push({mode:"direct",...nr(lt(s),o,c),...E}),a("resolveCredentials","direct mode active",`user=${E.user}`,`tenant=${E.tenant}`);}if(!r){if(t.length===0){let m=[];return m.authError=false,m}return t}let l;try{l=await er(r);}catch(m){if(a("resolveCredentials",`token refresh failed: ${m.message}`,`(tenant=${r.tenant} clientId=${r.clientId})`),t.length>0)return t.authError=true,t;let g=[];return g.authError=true,g}let T={user:Qe(l)??r.clientId,tenant:n,team:"",project:"",model:e},S=process.env[_.FLOW_TELEMETRY_GATEWAY]??D();return t.push({mode:"gateway",...rr(lt(S),{accessToken:l}),...T}),t}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 pt(t,e=100){return String(t??"").split(`
4
- `)[0].slice(0,e).trim()}function z(){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 A(t){process.stdout.write(JSON.stringify(t));}var Pt=()=>crypto.randomBytes(16).toString("hex"),U=()=>crypto.randomBytes(8).toString("hex");function L(){return String(BigInt(Date.now())*1000000n)}var dr=/^[0-9a-f-]{1,64}$/i,fr=M.normalize(me.tmpdir())+M.sep;function mr(t,e){let r=M.resolve(t);if(!r.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return r}function Nt(t){if(!dr.test(t))throw new Error(`Invalid session ID: ${t}`);return mr(M.join(me.tmpdir(),`flow-obs-${t}.json`),fr)}function B(t){let e;try{e=Nt(t);}catch{return null}if(!R.existsSync(e))return null;try{return JSON.parse(R.readFileSync(e,"utf8"))}catch{return null}}function Y(t,e){R.writeFileSync(Nt(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function bt(t){try{R.unlinkSync(Nt(t));}catch{}}function re(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 Ut(t){if(!t||!R.existsSync(t))return null;try{let e=R.readFileSync(t,"utf8").trimEnd().split(`
6
- `),r=[],n=0,i=0;for(let s=e.length-1;s>=0;s--)try{let o=JSON.parse(e[s]);if(o.type==="user")break;if(o.type==="assistant"){let l=(o.message?.content??[]).filter(T=>T.type==="text").map(T=>T.text??"").join("");l&&r.unshift(l);let p=o.message?.usage??{};n+=(p.input_tokens??0)+(p.cache_read_input_tokens??0)+(p.cache_creation_input_tokens??0),i+=p.output_tokens??0;}}catch{}return !r.length&&n===0?null:{text:r.join(`
1
+ 'use strict';var child_process=require('child_process'),util=require('util'),T=require('fs'),W=require('path'),nt=require('os'),ar=require('https'),cr=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 T__namespace=/*#__PURE__*/_interopNamespace(T);var W__namespace=/*#__PURE__*/_interopNamespace(W);var nt__namespace=/*#__PURE__*/_interopNamespace(nt);var ar__default=/*#__PURE__*/_interopDefault(ar);var cr__default=/*#__PURE__*/_interopDefault(cr);var Ge=Object.defineProperty;var dt=(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 mt=(t,e,r)=>()=>{if(r)throw r[0];try{return t&&(e=t(t=0)),e}catch(n){throw r=[n],n}};var wt=(t,e)=>{for(var r in e)Ge(t,r,{get:e[r],enumerable:true});};function x(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():Ve}function B(){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`}}function Lt(){let t=x();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ve,fn,gt,Et,_t,Rt,m,Z,jt,w,H,Kt,R,S=mt(()=>{"use strict";Ve="https://flow.ciandt.com";fn=B(),gt={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},Et="FLOW-nodejs",_t="config.json",Rt={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},m={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",FLOW_OBS_USE_JSON_VAULT:"FLOW_TELEMETRY_USE_JSON_VAULT",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES",FLOW_USER_EMAIL:"FLOW_USER_EMAIL",FLOW_API_KEY:"FLOW_API_KEY",OTEL_EXPORTER_OTLP_HEADERS:"OTEL_EXPORTER_OTLP_HEADERS",FLOW_BASE_URL:"FLOW_BASE_URL"},Z={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},jt={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},w={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},H={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[\x21-\x7E]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},Kt="flow-ai-obs-debug.log",R={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};});var Xt={};wt(Xt,{MacOsKeyVaultProvider:()=>Nt});var vt,Nt,qt=mt(()=>{"use strict";vt=util.promisify(child_process.execFile),Nt=class{static async isAvailable(){try{return T.accessSync("/usr/bin/security",T.constants.X_OK),!0}catch{return !1}}async getSecret(e,r){try{let{stdout:n}=await vt("security",["find-generic-password","-w","-a",r,"-s",e]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await vt("security",["add-generic-password","-U","-a",r,"-s",e,"-w",n]);}async deleteSecret(e,r){try{return await vt("security",["delete-generic-password","-a",r,"-s",e]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var Zt={};wt(Zt,{LinuxKeyVaultProvider:()=>bt});var zt,bt,Qt=mt(()=>{"use strict";zt=util.promisify(child_process.execFile),bt=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 T.accessSync(r,T.constants.X_OK),!0}catch{}return !1}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",c=>{c===0?o():s(new Error(`secret-tool exited with code ${c}`));}),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 !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var te={};wt(te,{WindowsKeyVaultProvider:()=>Ut});var Ut,ee=mt(()=>{"use strict";Ut=class{static async isAvailable(){try{return await dt("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,r){return dt("keytar").getPassword(e,r)}async setSecret(e,r,n){await dt("keytar").setPassword(e,r,n);}async deleteSecret(e,r){return dt("keytar").deletePassword(e,r)}getStoragePath(){return "Windows Credential Manager"}};});S();S();var It={credentials:"credentials","token-cache":"tokenCache"};function Q(){let t=nt__namespace.default.homedir();if(process.platform==="darwin")return W__namespace.default.join(t,"Library","Preferences",Et,_t);if(process.platform==="win32"){let r=process.env.APPDATA??W__namespace.default.join(t,"AppData","Roaming");return W__namespace.default.join(r,Et,_t)}let e=process.env.XDG_CONFIG_HOME??W__namespace.default.join(t,".config");return W__namespace.default.join(e,Et,_t)}function Pt(){try{let t=T__namespace.default.readFileSync(Q(),"utf8");return JSON.parse(t)}catch{return {}}}function Jt(t){let e=Q();T__namespace.default.mkdirSync(W__namespace.default.dirname(e),{recursive:true}),T__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var et=class{static isAvailable(){return true}static hasExistingData(){try{if(!T__namespace.default.existsSync(Q()))return !1;let e=JSON.parse(T__namespace.default.readFileSync(Q(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,r){let n=Pt(),o=It[r]??r,s=n[o];return s?typeof s=="string"?s:JSON.stringify(s):null}async setSecret(e,r,n){let o=Pt(),s=It[r]??r;if(r==="token-cache")try{o[s]=JSON.parse(n);}catch{o[s]=n;}else o[s]=n;Jt(o);}async deleteSecret(e,r){let n=Pt(),o=It[r]??r;return o in n?(delete n[o],Jt(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${Q()}`}};async function re(){return process.env[m.FLOW_OBS_USE_JSON_VAULT]==="1"?new et:await rr()??new et}async function rr(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(qt(),Xt));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}}S();var ne=gt.SERVICE;gt.ACCOUNT_CREDS;var se=gt.ACCOUNT_TOKEN,Ct=null;function oe(){return Ct||(Ct=re()),Ct}async function Ft(t){await(await oe()).setSecret(ne,se,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function $t(){let e=await(await oe()).getSecret(ne,se);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 rt(){let t=await $t();if(!t||!t.accessToken)return null;try{let e=t.accessToken.split(".");if(e.length<2)return null;let r=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return r.email??r.preferred_username??r.upn??r.sub??null}catch{return null}}S();S();var ir=W.join(nt.tmpdir(),Kt);function a(...t){if(process.env[m.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
2
+ `;try{T.writeFileSync(ir,e,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
3
+ `);}}var U=class extends Error{statusCode;constructor(e,r=0){super(e),this.name="AuthError",this.statusCode=r;}},lr=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function ur(t){if(!lr.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var ie={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 pr(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}`:"")),ie[n.error]))return new U(ie[n.error],t)}catch{}return t===401||t===403||t===500?new U("Invalid credentials",t):t>=400&&t<500?new U("Authentication request was rejected",t):new Error("Authentication service unavailable, please try again later")}function Y(t){return new Promise((e,r)=>{try{ur(t.tenant);}catch(p){return r(p)}let n=JSON.stringify({clientSecret:t.clientSecret}),o=new URL(B().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 l=(s?ar__default.default:cr__default.default).request(i,p=>{let _=[];p.on("data",h=>_.push(h)),p.on("end",()=>{let h=_.join("");if((p.statusCode??0)>=400)return r(pr(p.statusCode??0,h));let g;try{g=JSON.parse(h);}catch{return r(new Error("Invalid response from auth engine"))}let E=g.expires_at??new Date(Date.now()+(g.expires_in??3600)*1e3).toISOString();if(!g.access_token)return r(new Error("Auth engine returned an empty access token. Check FLOW_BASE_URL and credentials."));e({accessToken:g.access_token,expiresAt:E});});});l.on("error",p=>r(new Error(`Network error: ${p.message}`))),l.setTimeout(Z.REQUEST_TIMEOUT_MS,()=>{l.destroy(new Error("Request timeout"));}),l.write(n),l.end();})}S();S();!process.env.NO_COLOR&&process.stdout.isTTY;function St(){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 W__namespace.join(e,".claude","settings.json")}return W__namespace.join(nt__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||nt__namespace.homedir();return W__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 W__namespace.join(e,".claude","settings.json")}return W__namespace.join(nt__namespace.homedir(),".claude","settings.json")}var gr=jt.LOCK_STALE_MS;function Er(t){try{let e=T__namespace.statSync(t);Date.now()-e.mtimeMs>gr&&T__namespace.unlinkSync(t);}catch{}try{T__namespace.writeFileSync(t,String(process.pid),{flag:"wx"});}catch(e){throw e.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+t):e}}function _r(t){try{T__namespace.unlinkSync(t);}catch{}}var st;function le(t){if(st===void 0)try{let r=T__namespace.readFileSync(St(),"utf8");st=JSON.parse(r).env??null;}catch{st=null;}if(!st)return null;let e=st[t];return typeof e=="string"?e:null}function ue(t){let e=St(),r=e+".lock";T__namespace.mkdirSync(W__namespace.dirname(e),{recursive:true}),Er(r);try{let n={};try{n=JSON.parse(T__namespace.readFileSync(e,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,t),T__namespace.writeFileSync(e,JSON.stringify(n,null,2)+`
4
+ `,{encoding:"utf8",mode:384});try{T__namespace.chmodSync(e,384);}catch{}}finally{_r(r);}}S();function pe(){return !!process.env[m.FLOW_USER_EMAIL]||!!le(m.FLOW_USER_EMAIL)}function Mt(t){a("maybePersistUserEmail",`${t}: starting`);let e=t==="api-key"?`\u26A0\uFE0F flow-ai-obs: FLOW_USER_EMAIL is not set. Configure it with:
5
+ flow-ai-obs init --custom-email <EMAIL>
6
+ `:`\u26A0\uFE0F flow-ai-obs: FLOW_USER_EMAIL is not set and could not be derived from token.
7
+ Run: flow-ai-obs init
8
+ `;return rt().then(r=>{if(r){let n=r.split(/[\r\n]/)[0].replace(/[\x00-\x1F\x7F]/g,"").trim();if(!n)return;let o=n.indexOf("@"),s=n.slice(o+1);if(!(n.length<=254&&H.EMAIL_HEADER_PATTERN.test(n)&&(n.match(/@/g)??[]).length===1&&o>0&&o<n.length-1&&s.includes("."))){a("maybePersistUserEmail",`${t}: email from token failed basic validation \u2014 skipping persist`);return}try{ue({[m.FLOW_USER_EMAIL]:n}),a("maybePersistUserEmail",`${t}: persisted FLOW_USER_EMAIL from OAuth token`);}catch(c){a("maybePersistUserEmail",`${t}: FLOW_USER_EMAIL write failed: ${c.message}`),process.stderr.write(`\u26A0\uFE0F flow-ai-obs: could not persist FLOW_USER_EMAIL to settings.json.
9
+ Run: flow-ai-obs init
10
+ `);}}else process.stderr.write(e);}).catch(r=>{a("maybePersistUserEmail",`${t}: getEmailFromToken failed: ${r.message}`);})}var Sr=[/^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 Tr(t){return Sr.some(e=>e.test(t))}function hr(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 ht(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 Tt(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let r=process.env[m.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&&Tr(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function fe(){let t=ht(process.env[m.ANTHROPIC_AUTH_TOKEN]);return t?{user:await rt().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function yr(){let t=process.env[m.FLOW_API_KEY];if(!t)return null;let e=t.replace(/[\r\n]/g,"").trim();return e?e.length>H.API_KEY_MAX_LENGTH?(a("resolveApiKey",`FLOW_API_KEY exceeds ${H.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):H.API_KEY_PATTERN.test(e)?e:(a("resolveApiKey","FLOW_API_KEY contains non-printable or control characters \u2014 rejected"),null):null}function Ar(){return new Date().toISOString().slice(0,10)}async function Or(t){let e=Ar(),r=await $t();if(r?.lastAuthCheckAt!==e){a("getOrRefreshToken",`daily auth check (last: ${r?.lastAuthCheckAt??"never"})`);let s=Z.MAX_RETRY_ATTEMPTS;for(let i=1;i<=s;i++)try{let c=await Y(t);try{await Ft({...c,lastAuthCheckAt:e});}catch(p){a("getOrRefreshToken",`saveTokenCache failed (non-fatal): ${p.message}`);}return a("getOrRefreshToken",`daily check passed (attempt ${i}), expires=${c.expiresAt}`),yr()?pe()||await Mt("api-key"):await Mt("oauth"),c.accessToken}catch(c){if(c instanceof U){if(c.statusCode!==500)throw a("getOrRefreshToken",`daily check auth error (${c.statusCode}) \u2014 propagating immediately`),c;if(i<s){a("getOrRefreshToken",`daily check 500 error (attempt ${i}/${s}) \u2014 retrying in 1s`),await new Promise(l=>setTimeout(l,Z.RETRY_DELAY_MS));continue}throw a("getOrRefreshToken",`daily check failed after ${s} attempts \u2014 propagating`),c}a("getOrRefreshToken",`daily check network error \u2014 using cache: ${c.message}`);break}}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 Y(t);try{await Ft({...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 kr(t,e){let r=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function wr(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 j(){let t=[],e=process.env[m.ANTHROPIC_MODEL]??"",r=ht(process.env[m.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[m.FLOW_TELEMETRY]==="true",s=process.env[m.LANGFUSE_BASE_URL],i=process.env[m.LANGFUSE_PUBLIC_KEY],c=process.env[m.LANGFUSE_SECRET_KEY];if(o&&s&&i&&c){let g="",E=n;r&&(g=await rt().catch(()=>null)??r.clientId);let y={user:g??"",tenant:E??"",team:"",project:"",model:e};t.push({mode:"direct",...wr(Tt(s),i,c),...y}),a("resolveCredentials","direct mode active",`user=${y.user}`,`tenant=${y.tenant}`);}if(!r){if(t.length===0){let g=[];return g.authError=false,g}return t}let l;try{l=await Or(r);}catch(g){if(a("resolveCredentials",`token refresh failed: ${g.message}`,`(tenant=${r.tenant} clientId=${r.clientId})`),t.length>0)return t.authError=true,t;let E=[];return E.authError=true,E}let _={user:hr(l)??r.clientId,tenant:n,team:"",project:"",model:e},h=process.env[m.FLOW_TELEMETRY_GATEWAY]??x();return t.push({mode:"gateway",...kr(Tt(h),{accessToken:l}),..._}),t}function L(t,e){let r=typeof t=="object"?JSON.stringify(t):String(t??"");return r.length>e?r.slice(0,e)+" \u2026[truncated]":r}function yt(t,e=100){return String(t??"").split(`
11
+ `)[0].slice(0,e).trim()}function ot(){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 Dt=()=>crypto.randomBytes(16).toString("hex"),C=()=>crypto.randomBytes(8).toString("hex");function I(){return String(BigInt(Date.now())*1000000n)}var Cr=/^[0-9a-f-]{1,64}$/i,Fr=W.normalize(nt.tmpdir())+W.sep;function $r(t,e){let r=W.resolve(t);if(!r.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return r}function xt(t){if(!Cr.test(t))throw new Error(`Invalid session ID: ${t}`);return $r(W.join(nt.tmpdir(),`flow-obs-${t}.json`),Fr)}function K(t){let e;try{e=xt(t);}catch{return null}if(!T.existsSync(e))return null;try{return JSON.parse(T.readFileSync(e,"utf8"))}catch{return null}}function J(t,e){T.writeFileSync(xt(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function Bt(t){try{T.unlinkSync(xt(t));}catch{}}function _e(t){if(!t||!T.existsSync(t))return null;try{let e=T.readFileSync(t,"utf8").trimEnd().split(`
12
+ `);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 Ht(t){if(!t||!T.existsSync(t))return null;try{let e=T.readFileSync(t,"utf8").trimEnd().split(`
13
+ `),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 l=(i.message?.content??[]).filter(_=>_.type==="text").map(_=>_.text??"").join("");l&&r.unshift(l);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
14
 
8
- `),inputTokens:n,outputTokens:i}}catch{}return null}var Sr=new Set([".venv","__pycache__",".git","node_modules"]),Er=new Set([".pyc",".pyo"]),hr=new Set(["SKILL.md",".DS_Store",".gitignore"]);function oe(t){return t.replace(":","/")}function dt(t,e){if(!t)return null;let r=oe(t),n=[M.join(me.homedir(),".claude","skills",r,"SKILL.md"),M.join(e??"",".claude","skills",r,"SKILL.md")];for(let i of n)if(R.existsSync(i))try{return R.readFileSync(i,"utf8")}catch{}return null}function ie(t){return t.split(`
9
- `)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var Ar=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function ae(t){return !!t.slashSkill||t.toolCalls.some(n=>n.tool==="Skill")?t.toolCalls.some(n=>n.tool==="Skill"&&!n.synthetic||Ar.has(n.tool))?"complete":"prerequisite_required":null}function ft(t,e){if(!t)return null;let r=oe(t),n=[M.join(me.homedir(),".claude","skills",r),M.join(e??"",".claude","skills",r)],i=null;for(let c of n)if(R.existsSync(M.join(c,"SKILL.md"))){i=c;break}if(!i)return null;let s=[];function o(c,l){for(let p of R.readdirSync(c,{withFileTypes:true})){if(Sr.has(p.name)||hr.has(p.name)||Er.has(M.extname(p.name)))continue;let T=l?`${l}/${p.name}`:p.name;p.isDirectory()?o(M.join(c,p.name),T):s.push(T);}}return o(i,""),s.length>0?s:null}function kr(t){try{let e=t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(e,"base64").toString())}catch{return null}}function wr(t,e,r,n){return new Promise(i=>{let s=new URL(t),o=s.protocol==="https:",c=(o?Je__default.default:Ke__default.default).request({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(e),Authorization:`Bearer ${String(r).replace(/[\r\n]/g,"")}`,FlowTenant:String(n).replace(/[\r\n]/g,"")}},l=>{l.resume(),i(l.statusCode??0);});c.on("error",()=>i(0)),c.setTimeout(5e3,()=>{c.destroy(),i(0);}),c.write(e),c.end();})}async function v(t,e={}){try{let r=ut(process.env[_.ANTHROPIC_AUTH_TOKEN]);if(!r)return;let n,i=new Promise((S,m)=>{n=setTimeout(()=>m(new Error("getToken timeout")),4e3),n.unref();}),{accessToken:s}=await Promise.race([X(r),i]);clearTimeout(n);let o=kr(s);if(!o)return;let c=o.tenant||r.tenant,l=JSON.stringify({action:t,booster:St().BOOSTER,metadata:e,success:!0,tenant:c,timestamp:new Date().toISOString(),os:process.platform,user:{email:o.email||"",id:o.sub||"",name:o.name||o.email||""}}),p=lt(St().API_URL),T=await wr(p,l,s,c);a("metrics.logEvent",`action=${t} status=${T}`);}catch(r){a("metrics.logEvent",`silenced error: ${r.message}`);}}var Lr=`\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 ${D()}/settings/api-keys to generate a new API key, then run: flow-ai-obs login`;async function vt(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:Lr})+`
10
- `);return}let n=!!(await x()).authError,i=t.session_id||"unknown",s=t.prompt||"",o=t.cwd||"",c=re(t.transcript_path)||Pt(),l=ie(s),p=l?dt(l,o):null,T=l?ft(l,o):null;Y(i,{traceId:Pt(),spanId:U(),startNs:L(),sessionId:i,prompt:s,cwd:o,traceName:c,transcriptPath:t.transcript_path||"",model:process.env[_.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:l,skillContent:p,skillArtifacts:T}),v("SESSION_STARTED",{traceType:l?"skill":"prompt",slashSkill:l,clientIdExpired:n}),a("UserPromptSubmit",`sid=${i}`,`traceName=${c}`,`slashSkill=${l}`),A(t);}async function ce(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},i=B(e);i&&(i.pendingTool={name:r,inputStr:w(n,k.TOOL_INPUT),startNs:L()},Y(e,i)),a("PreToolUse",`sid=${e}`,`tool=${r}`,`stateFound=${!!i}`),A(t);}var Rr={name:Tt.SCOPE_NAME,version:Tt.SCOPE_VERSION},f={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 le(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:Rr,spans:Array.isArray(e)?e:[e]}]}]}}var ue=M.join(me.tmpdir(),"flow-obs-requests.ndjson");function pe(t,e,r,n,i){if(process.env[_.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:i}});try{R.writeFileSync(ue,s+`
11
- `,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${ue}`);}catch(o){a("sendTraces:dump",`falha ao salvar: ${o.message}`);}}function vr(t){let e=new URL(t),r=new URL(W().GATEWAY_HEALTH);return r.hostname=e.hostname,r.port=e.port,r.protocol=e.protocol,r}function de(t,e){return new Promise((r,n)=>{let i=t._isSSL?Je__default.default:Ke__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let s=i.request(t,o=>{let c=[];o.on("data",l=>c.push(l)),o.on("end",()=>r({statusCode:o.statusCode??0,body:c.join("")}));});s.setTimeout(1e4,()=>{s.destroy(new Error("Request timeout"));}),s.on("error",o=>n(new Error(`Network error: ${o.message}`))),e&&s.write(e),s.end();})}async function fe(t,e){let r;try{r=vr(t);}catch{return false}let n=r.protocol==="https:";try{let i={};e&&(i.Authorization=String(e).replace(/[\r\n]/g,""));let s=await de({hostname:r.hostname,port:r.port||(n?443:80),path:r.pathname,method:"GET",headers:i,_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),i=new URL(e),s=i.protocol==="https:",o=String(r).replace(/[\r\n]/g,""),c={"Content-Type":"application/json",Authorization:o,"Content-Length":Buffer.byteLength(n)};a("sendTraces:request",`POST ${e}`),a("sendTraces:request",`headers=${JSON.stringify({...c,Authorization:o.slice(0,20)+"\u2026"})}`),a("sendTraces:request",`body=${n.slice(0,500)}${n.length>500?"\u2026":""}`);try{let l=await de({hostname:i.hostname,port:i.port||(s?443:80),path:i.pathname,method:"POST",headers:c,_isSSL:s},n);return a("sendTraces:response",`status=${l.statusCode}`),pe(e,c,n,l.statusCode,l.body),l.statusCode}catch(l){return a("sendTraces:error",l.message),pe(e,c,n,0,l.message),0}}function Cr(){let t=parseInt(process.env[_.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(O.MIN_TTL_DAYS,Math.min(O.MAX_TTL_DAYS,t)):O.DEFAULT_TTL_DAYS)*24*60*60*1e3}function $r(){let t=parseInt(process.env[_.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(O.MIN_MAX_FILES,Math.min(O.MAX_MAX_FILES,t)):O.DEFAULT_MAX_FILES}function ge(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return M__default.default.join(me__default.default.tmpdir(),`${O.FILE_PREFIX}${t}.json`)}function $t(){let t=me__default.default.tmpdir(),e;try{e=R__default.default.readdirSync(t);}catch{return []}return e.filter(r=>r.startsWith(O.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=M__default.default.join(t,r),i=0;try{i=R__default.default.statSync(n).mtimeMs;}catch{}return {full:n,mtime:i}}).sort((r,n)=>r.mtime-n.mtime).map(r=>r.full)}function Z(t){try{let e=$r(),r=$t();if(r.length>=e){let s=r.slice(0,r.length-e+1);for(let o of s)try{R__default.default.unlinkSync(o);}catch{}}let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,i={fileId:n,bufferedAt:Date.now(),payload:t};return R__default.default.writeFileSync(ge(n),JSON.stringify(i),{encoding:"utf8",mode:384}),a("buffer",`saved fileId=${n}`),n}catch(e){return a("buffer",`saveToBuffer failed: ${e.message}`),null}}function _e(t){let e=$t(),r=t,n=[];for(let i of e){if(n.length>=r)break;try{let s=R__default.default.readFileSync(i,"utf8"),o=JSON.parse(s);o&&o.fileId&&o.payload&&n.push(o);}catch{a("buffer",`skipping malformed file: ${i}`);}}return n}function Te(t){try{R__default.default.unlinkSync(ge(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function Se(){let t=Date.now()-Cr();for(let e of $t())try{let{mtimeMs:r}=R__default.default.statSync(e);r<t&&(R__default.default.unlinkSync(e),a("buffer",`evicted stale: ${M__default.default.basename(e)}`));}catch{}}async function Fr(t){Se();let e=_e(O.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?(Te(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 Ee(t){let e=await x();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 o=await fe(s.endpoint,s.authHeader);return {creds:s,healthy:o}})),n=r.find(s=>s.creds.mode==="gateway"&&s.healthy)?.creds??r.find(s=>s.creds.mode==="direct")?.creds;return n&&await Fr(n),(await Promise.all(r.map(async({creds:s,healthy:o})=>{if(s.mode==="gateway"){if(!o)return a("postToLangfuse","gateway health check failed \u2014 buffering trace"),Z(t),0;let l=await mt(t,s.endpoint,s.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`gateway send failed (status ${l}) \u2014 buffering trace`),Z(t)),l}let c=await mt(t,s.endpoint,s.authHeader);return (c===0||c>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${c}) \u2014 buffering trace`),Z(t)),c}))).find(s=>s!==0)??0}var y="[REDACTED]",Dr="[REDACTED-EMAIL]",Mr="[REDACTED-CPF]",xr="[REDACTED-CNPJ]",he="[REDACTED-PHONE]",Br=[{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}
12
- ${y}
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}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>Dr},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>Mr},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>xr},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>he},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>he}];function I(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return Br.reduce((r,{re:n,replace:i})=>r.replace(n,i),e)}async function Ae(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},i=t.tool_response,s=i!==null&&typeof i=="object"?i.output??JSON.stringify(i):i??"",o=B(e);if(!o){A(t);return}let c=L(),l=o.pendingTool,p=l?.name===r,T=p?l.startNs:String(BigInt(c)-200000000n),S=p?l.inputStr:w(n,k.TOOL_INPUT),m=S,g=null;if(r==="Skill"){let st=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||n.commandName||String(Object.values(n)[0]??""):String(n);g=st?String(st).trim():null;let P=g?dt(g,o.cwd):null;P&&(m=P,o.skillContent||(o.skillContent=P),o.skillArtifacts||(o.skillArtifacts=ft(g,o.cwd))),g&&!o.slashSkill&&(o.slashSkill=g),a("PostToolUse","Skill tool detected",`skillName=${g}`,`contentFound=${!!P}`);}let E=I(w(s,k.TOOL_OUTPUT)),h=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(E.slice(0,500)),Q=h?"ERROR":"DEFAULT",V=U(),tt=Math.round(Number(BigInt(c)-BigInt(T))/1e6),rt={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL",nt=r==="Skill"&&g?g:pt(S,60);o.toolCalls.push({tool:r,brief:nt,error:h,durationMs:tt});let G=o.spans;G.push({traceId:o.traceId,spanId:V,parentSpanId:o.spanId,name:r,kind:3,startTimeUnixNano:T,endTimeUnixNano:c,attributes:C(u(f.OBS_NAME,r),u(f.OBS_TYPE,rt),u(f.OBS_LEVEL,Q),u(f.OBS_INPUT,I(m)),u(f.OBS_OUTPUT,E),u("tool.name",r),u("tool.error",String(h)),r==="Skill"&&g?u("skill.name",g):null,r==="Skill"?u("skill.invocation","slash-command"):null),status:{code:h?2:1}}),o.pendingTool=null,Y(e,o),h&&v("TOOL_ERROR",{toolName:r}),a("PostToolUse",`sid=${e}`,`tool=${r}`,`error=${h}`,`durationMs=${tt}`,`totalSpans=${G.length}`),A(t);}var ye={"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 Oe(t,e,r){let n=Object.keys(ye).find(o=>(t??"").toLowerCase().includes(o));if(!n)return;let i=ye[n],s=(e*i.input+r*i.output)/1e6;return Math.round(s*1e6)/1e6}async function ke(t){let e=t.session_id||"unknown",r=t.stop_reason||"end_turn",n=B(e);if(!n){A(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 i=L(),s=await zt(),o=n.toolCalls,c=n.spans;if(n.slashSkill&&!o.some(d=>d.tool==="Skill")){let d=U(),N=n.skillContent?n.skillContent:JSON.stringify({skill:n.slashSkill});o.push({tool:"Skill",brief:n.slashSkill,error:false,durationMs:0,synthetic:true}),c.push({traceId:n.traceId,spanId:d,parentSpanId:n.spanId,name:"Skill",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:n.startNs,attributes:C(u(f.OBS_NAME,"Skill"),u(f.OBS_TYPE,"TOOL"),u(f.OBS_LEVEL,"DEFAULT"),u(f.OBS_INPUT,N),u(f.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 l=t.transcript_path||n.transcriptPath||"",p=Ut(l);if(l&&(o.some(d=>d.tool==="Skill"&&!d.synthetic)||!!n.slashSkill)&&!p?.text){await new Promise(N=>setTimeout(N,500));let d=Ut(l);d?.text&&(p=d);}a("Stop",`transcriptPath=${l||"(empty)"}`,`assistantOut=${p?`text=${p.text.length}chars`:"null"}`);let S=o.length,m=o.filter(d=>d.error).length,g=I(p?.text?w(p.text,k.TRACE_OUTPUT):S===0?"No tools used":o.map((d,N)=>`${N+1}. ${d.tool}${d.brief?` \u2192 ${d.brief}`:""}${d.error?" [ERROR]":""}`).join(`
14
- `)),E=p?.inputTokens??0,h=p?.outputTokens??0,Q=o.map((d,N)=>`${N+1}. ${d.tool}${d.brief?` \u2192 ${d.brief}`:""}${d.error?" [ERROR]":""} (${d.durationMs}ms)`),V=!!(n.slashSkill||o.some(d=>d.tool==="Skill")),tt=o.some(d=>d.tool==="Agent");if(!V&&!tt){a("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),v("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),bt(e),A(t);return}let et=V?"skill":"agent",rt=Math.round(Number(BigInt(i)-BigInt(n.startNs))/1e6),nt=Oe(n.model,E,h),F=ae(n);F==="prerequisite_required"&&p?.text&&(F="complete"),F==="prerequisite_required"&&(c.push({traceId:n.traceId,spanId:U(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:i,attributes:C(u(f.OBS_NAME,"prerequisite-check"),u(f.OBS_TYPE,"EVENT"),u(f.OBS_LEVEL,"WARNING"),u(f.OBS_OUTPUT,g),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 G=(()=>{if(!(!V||!n.prompt)){if(n.slashSkill){let d=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return d?w(I(d),k.USER_INSTRUCTION):void 0}return w(I(n.prompt),k.USER_INSTRUCTION)||void 0}})(),st=JSON.stringify({trace_type:et,...F!==null&&{execution_status:F},...n.slashSkill?{skill_name:n.slashSkill}:{},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...G!==void 0&&{user_instruction:G},latency_ms:rt,...E&&{tokens_input:E},...h&&{tokens_output:h},cost_usd:nt,...n.model?{model:n.model}:{},toolCount:S,errorCount:m,stopReason:r,sessionId:n.sessionId,tools:Q.length?Q:void 0}),P=I(w(n.prompt,k.TRACE_INPUT)),we=C(u(f.TRACE_NAME,n.traceName),u(f.TRACE_INPUT,P),u(f.TRACE_OUTPUT,g),u(f.OBS_INPUT,P),u(f.OBS_OUTPUT,g),u(f.TRACE_METADATA,st),u(f.SESSION_ID,n.sessionId),u(f.USER_ID,s.user),u(f.OBS_TYPE,"GENERATION"),u(f.MODEL,n.model),E?u(f.INPUT_TOKENS,E):null,h?u(f.OUTPUT_TOKENS,h):null,u("claude.stop_reason",r),u("claude.tool_count",String(S)),u("claude.error_count",String(m)),u("claude.session_id",n.sessionId),u("flow.trace_type",et),{key:f.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:et}]}}}),Le={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:i,attributes:we,status:{code:m>0?2:1}},Re=C(u("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),u("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),Ft=[...c,Le];a("Stop",`sid=${e}`,`totalTools=${S}`,`errorTools=${m}`,`spans=${Ft.length}`,`inputTokens=${E}`,`outputTokens=${h}`,`traceOutput="${pt(g,80)}"`);let Ie=await Ee(le(Re,Ft));a("Stop",`POST status=${Ie}`,`traceId=${n.traceId}`),v("TRACE_SENT",{latencyMs:rt,totalTools:S,errorTools:m,inputTokens:E,outputTokens:h,costUsd:nt}),bt(e),A(t);}var $=class{static async userPromptSubmit(){let e=await z(),r;try{r=await x();}catch{A(e);return}r.authError?await vt(e,true):r.length>0?await vt(e):A(e);}static async preToolUse(){let e=await z();await ce(e);}static async postToolUse(){let e=await z();await Ae(e);}static async stop(){let e=await z();await ke(e);}};async function Yr(){let t=process.argv[2];switch(t){case "UserPromptSubmit":await $.userPromptSubmit();break;case "PreToolUse":await $.preToolUse();break;case "PostToolUse":await $.postToolUse();break;case "Stop":await $.stop();break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
15
- `),process.stdin.on("data",e=>process.stdout.write(e));}}Yr().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
15
+ `),inputTokens:n,outputTokens:o}}catch{}return null}var Br=new Set([".venv","__pycache__",".git","node_modules"]),Hr=new Set([".pyc",".pyo"]),Wr=new Set(["SKILL.md",".DS_Store",".gitignore"]);function he(t){return t.replace(":","/")}function At(t,e){if(!t)return null;let r=he(t),n=[W.join(nt.homedir(),".claude","skills",r,"SKILL.md"),W.join(e??"",".claude","skills",r,"SKILL.md")];for(let o of n)if(T.existsSync(o))try{return T.readFileSync(o,"utf8")}catch{}return null}function ye(t){return t.split(`
16
+ `)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var Yr=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function Ae(t){return !!t.slashSkill||t.toolCalls.some(n=>n.tool==="Skill")?t.toolCalls.some(n=>n.tool==="Skill"&&!n.synthetic||Yr.has(n.tool))?"complete":"prerequisite_required":null}function Ot(t,e){if(!t)return null;let r=he(t),n=[W.join(nt.homedir(),".claude","skills",r),W.join(e??"",".claude","skills",r)],o=null;for(let c of n)if(T.existsSync(W.join(c,"SKILL.md"))){o=c;break}if(!o)return null;let s=[];function i(c,l){for(let p of T.readdirSync(c,{withFileTypes:true})){if(Br.has(p.name)||Wr.has(p.name)||Hr.has(W.extname(p.name)))continue;let _=l?`${l}/${p.name}`:p.name;p.isDirectory()?i(W.join(c,p.name),_):s.push(_);}}return i(o,""),s.length>0?s:null}S();S();function jr(t){try{let e=t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(e,"base64").toString())}catch{return null}}function Kr(t,e,r,n){return new Promise(o=>{let s=new URL(t),i=s.protocol==="https:",c=(i?ar__default.default:cr__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,"")}},l=>{l.resume(),o(l.statusCode??0);});c.on("error",()=>o(0)),c.setTimeout(5e3,()=>{c.destroy(),o(0);}),c.write(e),c.end();})}async function F(t,e={}){try{let r=ht(process.env[m.ANTHROPIC_AUTH_TOKEN]);if(!r)return;let n,o=new Promise((h,g)=>{n=setTimeout(()=>g(new Error("getToken timeout")),4e3),n.unref();}),{accessToken:s}=await Promise.race([Y(r),o]);clearTimeout(n);let i=jr(s);if(!i)return;let c=i.tenant||r.tenant,l=JSON.stringify({action:t,booster:Lt().BOOSTER,metadata:e,success:!0,tenant:c,timestamp:new Date().toISOString(),os:process.platform,user:{email:i.email||"",id:i.sub||"",name:i.name||i.email||""}}),p=Tt(Lt().API_URL),_=await Kr(p,l,s,c);a("metrics.logEvent",`action=${t} status=${_}`);}catch(r){a("metrics.logEvent",`silenced error: ${r.message}`);}}var Jr=`\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 login`;async function Wt(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:Jr})+`
17
+ `);return}let n=!!(await j()).authError,o=t.session_id||"unknown",s=t.prompt||"",i=t.cwd||"",c=_e(t.transcript_path)||Dt(),l=ye(s),p=l?At(l,i):null,_=l?Ot(l,i):null;J(o,{traceId:Dt(),spanId:C(),startNs:I(),sessionId:o,prompt:s,cwd:i,traceName:c,transcriptPath:t.transcript_path||"",model:process.env[m.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:l,skillContent:p,skillArtifacts:_}),F("SESSION_STARTED",{traceType:l?"skill":"prompt",slashSkill:l,clientIdExpired:n}),a("UserPromptSubmit",`sid=${o}`,`traceName=${c}`,`slashSkill=${l}`),O(t);}S();async function Oe(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},o=K(e);o&&(o.pendingTool={name:r,inputStr:L(n,R.TOOL_INPUT),startNs:I()},J(e,o)),a("PreToolUse",`sid=${e}`,`tool=${r}`,`stateFound=${!!o}`),O(t);}S();var Xr={name:Rt.SCOPE_NAME,version:Rt.SCOPE_VERSION},d={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 $(...t){return t.filter(e=>e!==null)}function ke(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:Xr,spans:Array.isArray(e)?e:[e]}]}]}}S();var we=W.join(nt.tmpdir(),"flow-obs-requests.ndjson");function Re(t,e,r,n,o){if(process.env[m.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{T.writeFileSync(we,s+`
18
+ `,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${we}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function en(t){let e=new URL(t),r=new URL(B().GATEWAY_HEALTH);return r.hostname=e.hostname,r.port=e.port,r.protocol=e.protocol,r}function Le(t,e){return new Promise((r,n)=>{let o=t._isSSL?ar__default.default:cr__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let s=o.request(t,i=>{let c=[];i.on("data",l=>c.push(l)),i.on("end",()=>r({statusCode:i.statusCode??0,body:c.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 Ie(t,e){let r;try{r=en(t);}catch{return false}let n=r.protocol==="https:";try{let o={};e&&(o.Authorization=String(e).replace(/[\r\n]/g,""));let s=await Le({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 kt(t,e,r){let n=JSON.stringify(t),o=new URL(e),s=o.protocol==="https:",i=String(r).replace(/[\r\n]/g,""),c={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(n)};a("sendTraces:request",`POST ${e}`),a("sendTraces:request",`headers=${JSON.stringify({...c,Authorization:i.slice(0,20)+"\u2026"})}`),a("sendTraces:request",`body=${n.slice(0,500)}${n.length>500?"\u2026":""}`);try{let l=await Le({hostname:o.hostname,port:o.port||(s?443:80),path:o.pathname,method:"POST",headers:c,_isSSL:s},n);return a("sendTraces:response",`status=${l.statusCode}`),Re(e,c,n,l.statusCode,l.body),l.statusCode}catch(l){return a("sendTraces:error",l.message),Re(e,c,n,0,l.message),0}}S();function rn(){let t=parseInt(process.env[m.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(w.MIN_TTL_DAYS,Math.min(w.MAX_TTL_DAYS,t)):w.DEFAULT_TTL_DAYS)*24*60*60*1e3}function nn(){let t=parseInt(process.env[m.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(w.MIN_MAX_FILES,Math.min(w.MAX_MAX_FILES,t)):w.DEFAULT_MAX_FILES}function ve(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return W__namespace.default.join(nt__namespace.default.tmpdir(),`${w.FILE_PREFIX}${t}.json`)}function Gt(){let t=nt__namespace.default.tmpdir(),e;try{e=T__namespace.default.readdirSync(t);}catch{return []}return e.filter(r=>r.startsWith(w.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=W__namespace.default.join(t,r),o=0;try{o=T__namespace.default.statSync(n).mtimeMs;}catch{}return {full:n,mtime:o}}).sort((r,n)=>r.mtime-n.mtime).map(r=>r.full)}function it(t){try{let e=nn(),r=Gt();if(r.length>=e){let s=r.slice(0,r.length-e+1);for(let i of s)try{T__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 T__namespace.default.writeFileSync(ve(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 Ne(t){let e=Gt(),r=t!=null&&t>0?t:e.length,n=[];for(let o of e){if(n.length>=r)break;try{let s=T__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 be(t){try{T__namespace.default.unlinkSync(ve(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function Ue(){let t=Date.now()-rn();for(let e of Gt())try{let{mtimeMs:r}=T__namespace.default.statSync(e);r<t&&(T__namespace.default.unlinkSync(e),a("buffer",`evicted stale: ${W__namespace.default.basename(e)}`));}catch{}}S();async function sn(t){Ue();let e=Ne(w.REPLAY_BATCH_SIZE);e.length&&(a("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async r=>{try{let n=await kt(r.payload,t.endpoint,t.authHeader);n>=200&&n<300?(be(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 Ce(t){let e=await j();if(!e.length)return e.authError&&(a("postToLangfuse","auth refresh failed \u2014 buffering trace"),it(t)),0;let r=await Promise.all(e.map(async s=>{if(s.mode!=="gateway")return {creds:s,healthy:true};let i=await Ie(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 sn(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"),it(t),0;let l=await kt(t,s.endpoint,s.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`gateway send failed (status ${l}) \u2014 buffering trace`),it(t)),l}let c=await kt(t,s.endpoint,s.authHeader);return (c===0||c>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${c}) \u2014 buffering trace`),it(t)),c}))).find(s=>s!==0)??0}S();var k="[REDACTED]",on="[REDACTED-EMAIL]",an="[REDACTED-CPF]",cn="[REDACTED-CNPJ]",Fe="[REDACTED-PHONE]",ln=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${k}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${k}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${k}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${k}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,r)=>`${e}
19
+ ${k}
20
+ ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${k}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${k}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${k}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${k}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${k}`},{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}${k}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${k}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>on},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>an},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>cn},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>Fe},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>Fe}];function v(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return ln.reduce((r,{re:n,replace:o})=>r.replace(n,o),e)}async function $e(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},o=t.tool_response,s=o!==null&&typeof o=="object"?o.output??JSON.stringify(o):o??"",i=K(e);if(!i){O(t);return}let c=I(),l=i.pendingTool,p=l?.name===r,_=p?l.startNs:String(BigInt(c)-200000000n),h=p?l.inputStr:L(n,R.TOOL_INPUT),g=h,E=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);E=ft?String(ft).trim():null;let N=E?At(E,i.cwd):null;N&&(g=N,i.skillContent||(i.skillContent=N),i.skillArtifacts||(i.skillArtifacts=Ot(E,i.cwd))),E&&!i.slashSkill&&(i.slashSkill=E),a("PostToolUse","Skill tool detected",`skillName=${E}`,`contentFound=${!!N}`);}let y=v(L(s,R.TOOL_OUTPUT)),A=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(y.slice(0,500)),at=A?"ERROR":"DEFAULT",q=C(),ct=Math.round(Number(BigInt(c)-BigInt(_))/1e6),ut={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL",pt=r==="Skill"&&E?E:yt(h,60);i.toolCalls.push({tool:r,brief:pt,error:A,durationMs:ct});let z=i.spans;z.push({traceId:i.traceId,spanId:q,parentSpanId:i.spanId,name:r,kind:3,startTimeUnixNano:_,endTimeUnixNano:c,attributes:$(u(d.OBS_NAME,r),u(d.OBS_TYPE,ut),u(d.OBS_LEVEL,at),u(d.OBS_INPUT,v(g)),u(d.OBS_OUTPUT,y),u("tool.name",r),u("tool.error",String(A)),r==="Skill"&&E?u("skill.name",E):null,r==="Skill"?u("skill.invocation","slash-command"):null),status:{code:A?2:1}}),i.pendingTool=null,J(e,i),A&&F("TOOL_ERROR",{toolName:r}),a("PostToolUse",`sid=${e}`,`tool=${r}`,`error=${A}`,`durationMs=${ct}`,`totalSpans=${z.length}`),O(t);}var Me={"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 De(t,e,r){let n=Object.keys(Me).find(i=>(t??"").toLowerCase().includes(i));if(!n)return;let o=Me[n],s=(e*o.input+r*o.output)/1e6;return Math.round(s*1e6)/1e6}S();async function xe(t){let e=t.session_id||"unknown",r=t.stop_reason||"end_turn",n=K(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=I(),s=await fe(),i=n.toolCalls,c=n.spans;if(n.slashSkill&&!i.some(f=>f.tool==="Skill")){let f=C(),b=n.skillContent?n.skillContent:JSON.stringify({skill:n.slashSkill});i.push({tool:"Skill",brief:n.slashSkill,error:false,durationMs:0,synthetic:true}),c.push({traceId:n.traceId,spanId:f,parentSpanId:n.spanId,name:"Skill",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:n.startNs,attributes:$(u(d.OBS_NAME,"Skill"),u(d.OBS_TYPE,"TOOL"),u(d.OBS_LEVEL,"DEFAULT"),u(d.OBS_INPUT,b),u(d.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 l=t.transcript_path||n.transcriptPath||"",p=Ht(l);if(l&&(i.some(f=>f.tool==="Skill"&&!f.synthetic)||!!n.slashSkill)&&!p?.text){await new Promise(b=>setTimeout(b,500));let f=Ht(l);f?.text&&(p=f);}a("Stop",`transcriptPath=${l||"(empty)"}`,`assistantOut=${p?`text=${p.text.length}chars`:"null"}`);let h=i.length,g=i.filter(f=>f.error).length,E=v(p?.text?L(p.text,R.TRACE_OUTPUT):h===0?"No tools used":i.map((f,b)=>`${b+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""}`).join(`
21
+ `)),y=p?.inputTokens??0,A=p?.outputTokens??0,at=i.map((f,b)=>`${b+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""} (${f.durationMs}ms)`),q=!!(n.slashSkill||i.some(f=>f.tool==="Skill")),ct=i.some(f=>f.tool==="Agent");if(!q&&!ct){a("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),F("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),Bt(e),O(t);return}let lt=q?"skill":"agent",ut=Math.round(Number(BigInt(o)-BigInt(n.startNs))/1e6),pt=De(n.model,y,A),D=Ae(n);D==="prerequisite_required"&&p?.text&&(D="complete"),D==="prerequisite_required"&&(c.push({traceId:n.traceId,spanId:C(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:o,attributes:$(u(d.OBS_NAME,"prerequisite-check"),u(d.OBS_TYPE,"EVENT"),u(d.OBS_LEVEL,"WARNING"),u(d.OBS_OUTPUT,E),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 z=(()=>{if(!(!q||!n.prompt)){if(n.slashSkill){let f=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return f?L(v(f),R.USER_INSTRUCTION):void 0}return L(v(n.prompt),R.USER_INSTRUCTION)||void 0}})(),ft=JSON.stringify({trace_type:lt,...D!==null&&{execution_status:D},...n.slashSkill?{skill_name:n.slashSkill}:{},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...z!==void 0&&{user_instruction:z},latency_ms:ut,...y&&{tokens_input:y},...A&&{tokens_output:A},cost_usd:pt,...n.model?{model:n.model}:{},toolCount:h,errorCount:g,stopReason:r,sessionId:n.sessionId,tools:at.length?at:void 0}),N=v(L(n.prompt,R.TRACE_INPUT)),Be=$(u(d.TRACE_NAME,n.traceName),u(d.TRACE_INPUT,N),u(d.TRACE_OUTPUT,E),u(d.OBS_INPUT,N),u(d.OBS_OUTPUT,E),u(d.TRACE_METADATA,ft),u(d.SESSION_ID,n.sessionId),u(d.USER_ID,s.user),u(d.OBS_TYPE,"GENERATION"),u(d.MODEL,n.model),y?u(d.INPUT_TOKENS,y):null,A?u(d.OUTPUT_TOKENS,A):null,u("claude.stop_reason",r),u("claude.tool_count",String(h)),u("claude.error_count",String(g)),u("claude.session_id",n.sessionId),u("flow.trace_type",lt),{key:d.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:lt}]}}}),He={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:o,attributes:Be,status:{code:g>0?2:1}},We=$(u("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),u("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),Vt=[...c,He];a("Stop",`sid=${e}`,`totalTools=${h}`,`errorTools=${g}`,`spans=${Vt.length}`,`inputTokens=${y}`,`outputTokens=${A}`,`traceOutput="${yt(E,80)}"`);let Ye=await Ce(ke(We,Vt));a("Stop",`POST status=${Ye}`,`traceId=${n.traceId}`),F("TRACE_SENT",{latencyMs:ut,totalTools:h,errorTools:g,inputTokens:y,outputTokens:A,costUsd:pt}),Bt(e),O(t);}var M=class{static async userPromptSubmit(){let e=await ot(),r;try{r=await j();}catch{O(e);return}r.authError?await Wt(e,true):r.length>0?await Wt(e):O(e);}static async preToolUse(){let e=await ot();await Oe(e);}static async postToolUse(){let e=await ot();await $e(e);}static async stop(){let e=await ot();await xe(e);}};async function un(){let t=process.argv[2];switch(t){case "UserPromptSubmit":await M.userPromptSubmit();break;case "PreToolUse":await M.preToolUse();break;case "PostToolUse":await M.postToolUse();break;case "Stop":await M.stop();break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
22
+ `),process.stdin.on("data",e=>process.stdout.write(e));}}un().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
16
23
  `),process.exit(0);});
package/dist/setup.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';var child_process=require('child_process'),util=require('util'),i=require('fs'),f=require('path'),p=require('os'),dt=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 p__namespace=/*#__PURE__*/_interopNamespace(p);var dt__default=/*#__PURE__*/_interopDefault(dt);var I=Object.defineProperty;var Le=Object.getOwnPropertyDescriptor;var ke=Object.getOwnPropertyNames;var Pe=Object.prototype.hasOwnProperty;var A=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var R=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var Ie=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(n){throw t=0,n}},L=(e,t)=>{for(var n in t)I(e,n,{get:t[n],enumerable:true});},Ne=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ke(t))!Pe.call(e,s)&&s!==n&&I(e,s,{get:()=>t[s],enumerable:!(r=Le(t,s))||r.enumerable});return e};var Ce=e=>Ne(I({},"__esModule",{value:true}),e);var K={};L(K,{AUTH_ENGINE:()=>C,BUFFER:()=>Me,CONFIG_DIR_NAME:()=>y,CONFIG_FILE_NAME:()=>T,DEBUG_LOG_FILENAME:()=>F,ENV:()=>u,FEATURES:()=>De,FLOW_URLS:()=>be,HOOK_TIMEOUTS:()=>b,INSTALLER:()=>U,NATIVE_OTEL:()=>N,OTLP:()=>Fe,STATE_FILE_PREFIX:()=>Ve,TRACE_LIMITS:()=>xe,VAULT:()=>E,getFlowBaseUrl:()=>h,getFlowUrls:()=>k,getLlmProxy:()=>$e,getMetrics:()=>He});function h(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Ue}function k(){let e=h();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`}}function $e(){let e=h();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-haiku",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"}}function He(){let e=h();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ue,be,E,y,T,Fe,N,u,De,C,U,b,Me,F,xe,Ve,l=R(()=>{"use strict";Ue="https://flow.ciandt.com";be=k(),E={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},y="FLOW-nodejs",T="config.json",Fe={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};N={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},u={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",FLOW_OBS_USE_JSON_VAULT:"FLOW_TELEMETRY_USE_JSON_VAULT",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"},De={KEYCHAIN_ENABLED:!1},C={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},U={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},b={UserPromptSubmit:30,PreToolUse:3,PostToolUse:10,Stop:15},Me={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},F="flow-ai-obs-debug.log",xe={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};Ve="flow-obs-";});var q={};L(q,{MacOsKeyVaultProvider:()=>x});var M,x,z=R(()=>{"use strict";M=util.promisify(child_process.execFile),x=class{static async isAvailable(){try{return i.accessSync("/usr/bin/security",i.constants.X_OK),!0}catch{return !1}}async getSecret(t,n){try{let{stdout:r}=await M("security",["find-generic-password","-w","-a",n,"-s",t]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await M("security",["add-generic-password","-U","-a",n,"-s",t,"-w",r]);}async deleteSecret(t,n){try{return await M("security",["delete-generic-password","-a",n,"-s",t]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var Z={};L(Z,{LinuxKeyVaultProvider:()=>H});var Q,H,ee=R(()=>{"use strict";Q=util.promisify(child_process.execFile),H=class{static async isAvailable(){let t=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let n of t)try{return i.accessSync(n,i.constants.X_OK),!0}catch{}return !1}async getSecret(t,n){try{let{stdout:r}=await Q("secret-tool",["lookup","service",t,"account",n]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await new Promise((s,o)=>{let a=child_process.spawn("secret-tool",["store","--label",t,"service",t,"account",n]);a.on("error",o),a.on("close",m=>{m===0?s():o(new Error(`secret-tool exited with code ${m}`));}),a.stdin.write(r),a.stdin.end();});}async deleteSecret(t,n){try{return await Q("secret-tool",["clear","service",t,"account",n]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var te={};L(te,{WindowsKeyVaultProvider:()=>V});var V,ne=R(()=>{"use strict";V=class{static async isAvailable(){try{return await A("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(t,n){return A("keytar").getPassword(t,n)}async setSecret(t,n,r){await A("keytar").setPassword(t,n,r);}async deleteSecret(t,n){return A("keytar").deletePassword(t,n)}getStoragePath(){return "Windows Credential Manager"}};});var he=Ie((Rn,ft)=>{ft.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.12.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",regression:"jest --config jest.regression.config.js --forceExit","regression:update":"UPDATE_GOLDEN=1 jest --config jest.regression.config.js --forceExit"},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:!1,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"},overrides:{esbuild:"^0.28.1"},publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/CI-T-HyperX/flow-codeassistant-observability.git"}};});l();l();var $={credentials:"credentials","token-cache":"tokenCache"};function _(){let e=p__namespace.default.homedir();if(process.platform==="darwin")return f__namespace.default.join(e,"Library","Preferences",y,T);if(process.platform==="win32"){let n=process.env.APPDATA??f__namespace.default.join(e,"AppData","Roaming");return f__namespace.default.join(n,y,T)}let t=process.env.XDG_CONFIG_HOME??f__namespace.default.join(e,".config");return f__namespace.default.join(t,y,T)}function D(){try{let e=i__namespace.default.readFileSync(_(),"utf8");return JSON.parse(e)}catch{return {}}}function X(e){let t=_();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 w=class{static isAvailable(){return true}static hasExistingData(){try{if(!i__namespace.default.existsSync(_()))return !1;let t=JSON.parse(i__namespace.default.readFileSync(_(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,n){let r=D(),s=$[n]??n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,n,r){let s=D(),o=$[n]??n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;X(s);}async deleteSecret(t,n){let r=D(),s=$[n]??n;return s in r?(delete r[s],X(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${_()}`}};async function re(){return process.env[u.FLOW_OBS_USE_JSON_VAULT]==="1"?new w:await Qe()??new w}async function Qe(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=await Promise.resolve().then(()=>(z(),q));return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=await Promise.resolve().then(()=>(ee(),Z));return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=await Promise.resolve().then(()=>(ne(),te));return await e.isAvailable()?new e:null}default:return null}}l();var Ze=E.SERVICE,et=E.ACCOUNT_CREDS;E.ACCOUNT_TOKEN;var Y=null;function tt(){return Y||(Y=re()),Y}async function se(){let t=await(await tt()).getSecret(Ze,et);if(!t)return null;try{return JSON.parse(t)}catch{return null}}l();l();l();f.join(p.tmpdir(),F);!process.env.NO_COLOR&&process.stdout.isTTY;function j(){return process.platform==="win32"?false:process.getuid?.()===0}function oe(){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:p__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||p__namespace.userInfo().username}}function P(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(e=n);}if(e){let t=e.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return f__namespace.join(t,".claude","settings.json")}return f__namespace.join(p__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||p__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(p__namespace.homedir(),".claude","settings.json")}var ie="flow-ai-obs",ae="config.json";function le(){if(process.platform==="win32"){let n=process.env.APPDATA||f__namespace.join(p__namespace.homedir(),"AppData","Roaming");return f__namespace.join(n,ie,ae)}let e=oe(),t=process.env.XDG_CONFIG_HOME||f__namespace.join(e.home,".config");return f__namespace.join(t,ie,ae)}var lt=U.LOCK_STALE_MS;function ue(e){try{let t=i__namespace.statSync(e);Date.now()-t.mtimeMs>lt&&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 pe(e){try{i__namespace.unlinkSync(e);}catch{}}function ut(e,t){let r=(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,...r]}function fe(e,t){let n=P(),r=n+".lock",s=[];i__namespace.mkdirSync(f__namespace.dirname(n),{recursive:true}),ue(r);try{if(i__namespace.existsSync(n)){i__namespace.copyFileSync(n,n+".bkp");try{i__namespace.chmodSync(n+".bkp",384);}catch{}}let o=le();if(i__namespace.existsSync(o)){let c=o+".bkp";i__namespace.copyFileSync(o,c);try{i__namespace.chmodSync(c,384);}catch{}}let a={};try{a=JSON.parse(i__namespace.readFileSync(n,"utf8"));}catch{}let m=a.env&&typeof a.env=="object"?a.env:{};delete m.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:we}=(l(),Ce(K)),Oe=we().OTEL_ENDPOINT,ve={...N,OTEL_EXPORTER_OTLP_ENDPOINT:e??Oe};a.env={...m,...ve,...t??{}},a.otelHeadersHelper="flow-ai-obs otel-headers",(!a.hooks||typeof a.hooks!="object"||Array.isArray(a.hooks))&&(a.hooks={});let Ae=(c,v)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${c}`,timeout:v}]}),Re=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],J=a.hooks;for(let c of Re){let v=ut(J[c],Ae(c,b[c]));v.length>1&&s.push(c),J[c]=v;}i__namespace.writeFileSync(n,JSON.stringify(a,null,2)+`
3
- `,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(n,384);}catch{}}finally{pe(r);}return {settingsPath:n,preserved:s}}function de(e){let t=P(),n=t+".lock";i__namespace.mkdirSync(f__namespace.dirname(t),{recursive:true}),ue(n);try{let r={};try{r=JSON.parse(i__namespace.readFileSync(t,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,e),i__namespace.writeFileSync(t,JSON.stringify(r,null,2)+`
4
- `,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(t,384);}catch{}}finally{pe(n);}}l();function ge(e){if(!e)return null;try{let t=e.split(".");if(t.length<2)return null;let n=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:o}=n;return !r||!s||!o?null:{clientId:r,clientSecret:s,tenant:o}}catch{return null}}function me(e){let t=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),n=Buffer.from(JSON.stringify({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant})).toString("base64url");return `${t}.${n}.`}l();var B;function ye(){return B||(B=he()),B}var Te=f__namespace.default.join(p__namespace.default.tmpdir(),"flow-obs-update-cache.json"),ht=1440*60*1e3,Et=3e3;function yt(e,t){let n=o=>{let a=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return a?[+a[1],+a[2],+a[3]]:null},r=n(e),s=n(t);return !r||!s?false:s[0]!==r[0]?s[0]>r[0]:s[1]!==r[1]?s[1]>r[1]:s[2]>r[2]}function Tt(){try{let e=JSON.parse(i__namespace.default.readFileSync(Te,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=ht?null:e}catch{return null}}function _t(e,t,n=Date.now()){try{i__namespace.default.writeFileSync(Te,JSON.stringify({latestVersion:e,updatePriority:t??null,checkedAt:n}),{mode:384});}catch{}}function St(e){let t=ye().name,n=dt__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:Et},r=>{if(r.statusCode!==200)return r.resume(),e(new Error(`HTTP ${r.statusCode}`));let s="";r.setEncoding("utf8"),r.on("data",o=>{s+=o;}),r.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);}});});n.on("error",e),n.on("timeout",()=>{n.destroy(new Error("timeout"));});}function _e(){try{if(Tt())return;setImmediate(()=>{St((e,t)=>{e||!t||yt(ye().version,t.version)&&_t(t.version,t.updatePriority,0);});});}catch{}}var wt=f__namespace.default.resolve(__dirname,".."),Ot=process.env.INIT_CWD?f__namespace.default.resolve(process.env.INIT_CWD):null;Ot===wt&&process.exit(0);j()&&(process.stderr.write(`
2
+ 'use strict';var child_process=require('child_process'),util=require('util'),i=require('fs'),p=require('path'),f=require('os'),Et=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 p__namespace=/*#__PURE__*/_interopNamespace(p);var f__namespace=/*#__PURE__*/_interopNamespace(f);var Et__default=/*#__PURE__*/_interopDefault(Et);var I=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var Ie=Object.getOwnPropertyNames;var Ne=Object.prototype.hasOwnProperty;var L=(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,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var Ue=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(r){throw t=0,r}},R=(e,t)=>{for(var r in t)I(e,r,{get:t[r],enumerable:true});},Ce=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Ie(t))!Ne.call(e,s)&&s!==r&&I(e,s,{get:()=>t[s],enumerable:!(n=ke(t,s))||n.enumerable});return e};var be=e=>Ce(I({},"__esModule",{value:true}),e);var q={};R(q,{AUTH_ENGINE:()=>U,BUFFER:()=>He,CONFIG_DIR_NAME:()=>_,CONFIG_FILE_NAME:()=>T,DEBUG_LOG_FILENAME:()=>M,ENV:()=>u,FEATURES:()=>xe,FLOW_URLS:()=>Me,HOOK_TIMEOUTS:()=>b,INSTALLER:()=>C,NATIVE_OTEL:()=>N,OTLP:()=>$e,STATE_FILE_PREFIX:()=>Ye,TRACE_LIMITS:()=>Ve,VALIDATION:()=>F,VAULT:()=>h,getFlowBaseUrl:()=>g,getFlowUrls:()=>P,getLlmProxy:()=>De,getMetrics:()=>We});function g(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Fe}function P(){let e=g();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`}}function De(){let e=g();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-haiku",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"}}function We(){let e=g();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Fe,Me,h,_,T,$e,N,u,xe,U,C,b,He,F,M,Ve,Ye,c=v(()=>{"use strict";Fe="https://flow.ciandt.com";Me=P(),h={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},_="FLOW-nodejs",T="config.json",$e={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};N={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},u={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",FLOW_OBS_USE_JSON_VAULT:"FLOW_TELEMETRY_USE_JSON_VAULT",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES",FLOW_USER_EMAIL:"FLOW_USER_EMAIL",FLOW_API_KEY:"FLOW_API_KEY",OTEL_EXPORTER_OTLP_HEADERS:"OTEL_EXPORTER_OTLP_HEADERS",FLOW_BASE_URL:"FLOW_BASE_URL"},xe={KEYCHAIN_ENABLED:!1},U={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},C={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},b={UserPromptSubmit:30,PreToolUse:3,PostToolUse:10,Stop:15},He={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},F={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[\x21-\x7E]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},M="flow-ai-obs-debug.log",Ve={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};Ye="flow-obs-";});var Z={};R(Z,{MacOsKeyVaultProvider:()=>H});var x,H,Q=v(()=>{"use strict";x=util.promisify(child_process.execFile),H=class{static async isAvailable(){try{return i.accessSync("/usr/bin/security",i.constants.X_OK),!0}catch{return !1}}async getSecret(t,r){try{let{stdout:n}=await x("security",["find-generic-password","-w","-a",r,"-s",t]);return n.trim()||null}catch{return null}}async setSecret(t,r,n){await x("security",["add-generic-password","-U","-a",r,"-s",t,"-w",n]);}async deleteSecret(t,r){try{return await x("security",["delete-generic-password","-a",r,"-s",t]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var te={};R(te,{LinuxKeyVaultProvider:()=>V});var ee,V,re=v(()=>{"use strict";ee=util.promisify(child_process.execFile),V=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 !1}async getSecret(t,r){try{let{stdout:n}=await ee("secret-tool",["lookup","service",t,"account",r]);return n.trim()||null}catch{return null}}async setSecret(t,r,n){await new Promise((s,o)=>{let a=child_process.spawn("secret-tool",["store","--label",t,"service",t,"account",r]);a.on("error",o),a.on("close",E=>{E===0?s():o(new Error(`secret-tool exited with code ${E}`));}),a.stdin.write(n),a.stdin.end();});}async deleteSecret(t,r){try{return await ee("secret-tool",["clear","service",t,"account",r]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var ne={};R(ne,{WindowsKeyVaultProvider:()=>W});var W,se=v(()=>{"use strict";W=class{static async isAvailable(){try{return await L("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(t,r){return L("keytar").getPassword(t,r)}async setSecret(t,r,n){await L("keytar").setPassword(t,r,n);}async deleteSecret(t,r){return L("keytar").deletePassword(t,r)}getStoragePath(){return "Windows Credential Manager"}};});var _e=Ue(($r,mt)=>{mt.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.12.1-beta.22",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",regression:"jest --config jest.regression.config.js --forceExit","regression:update":"UPDATE_GOLDEN=1 jest --config jest.regression.config.js --forceExit"},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:!1,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"},overrides:{esbuild:"^0.28.1"},publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/CI-T-HyperX/flow-codeassistant-observability.git"}};});c();c();var $={credentials:"credentials","token-cache":"tokenCache"};function y(){let e=f__namespace.default.homedir();if(process.platform==="darwin")return p__namespace.default.join(e,"Library","Preferences",_,T);if(process.platform==="win32"){let r=process.env.APPDATA??p__namespace.default.join(e,"AppData","Roaming");return p__namespace.default.join(r,_,T)}let t=process.env.XDG_CONFIG_HOME??p__namespace.default.join(e,".config");return p__namespace.default.join(t,_,T)}function D(){try{let e=i__namespace.default.readFileSync(y(),"utf8");return JSON.parse(e)}catch{return {}}}function z(e){let t=y();i__namespace.default.mkdirSync(p__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(y()))return !1;let t=JSON.parse(i__namespace.default.readFileSync(y(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,r){let n=D(),s=$[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,r,n){let s=D(),o=$[r]??r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;z(s);}async deleteSecret(t,r){let n=D(),s=$[r]??r;return s in n?(delete n[s],z(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${y()}`}};async function oe(){return process.env[u.FLOW_OBS_USE_JSON_VAULT]==="1"?new A:await et()??new A}async function et(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=await Promise.resolve().then(()=>(Q(),Z));return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=await Promise.resolve().then(()=>(re(),te));return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=await Promise.resolve().then(()=>(se(),ne));return await e.isAvailable()?new e:null}default:return null}}c();var tt=h.SERVICE,rt=h.ACCOUNT_CREDS;h.ACCOUNT_TOKEN;var Y=null;function nt(){return Y||(Y=oe()),Y}async function ie(){let t=await(await nt()).getSecret(tt,rt);if(!t)return null;try{return JSON.parse(t)}catch{return null}}c();c();c();p.join(f.tmpdir(),M);!process.env.NO_COLOR&&process.stdout.isTTY;function G(){return process.platform==="win32"?false:process.getuid?.()===0}function ce(){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:f__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||f__namespace.userInfo().username}}function k(){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 p__namespace.join(t,".claude","settings.json")}return p__namespace.join(f__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||f__namespace.homedir();return p__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 p__namespace.join(t,".claude","settings.json")}return p__namespace.join(f__namespace.homedir(),".claude","settings.json")}var le="flow-ai-obs",ue="config.json";function pe(){if(process.platform==="win32"){let r=process.env.APPDATA||p__namespace.join(f__namespace.homedir(),"AppData","Roaming");return p__namespace.join(r,le,ue)}let e=ce(),t=process.env.XDG_CONFIG_HOME||p__namespace.join(e.home,".config");return p__namespace.join(t,le,ue)}var ut=C.LOCK_STALE_MS;function de(e){try{let t=i__namespace.statSync(e);Date.now()-t.mtimeMs>ut&&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 me(e){try{i__namespace.unlinkSync(e);}catch{}}function ft(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 Ee(e,t){let r=k(),n=r+".lock",s=[];i__namespace.mkdirSync(p__namespace.dirname(r),{recursive:true}),de(n);try{if(i__namespace.existsSync(r)){i__namespace.copyFileSync(r,r+".bkp");try{i__namespace.chmodSync(r+".bkp",384);}catch{}}let o=pe();if(i__namespace.existsSync(o)){let l=o+".bkp";i__namespace.copyFileSync(o,l);try{i__namespace.chmodSync(l,384);}catch{}}let a={};try{a=JSON.parse(i__namespace.readFileSync(r,"utf8"));}catch{}let E=a.env&&typeof a.env=="object"?a.env:{};delete E.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:Oe}=(c(),be(q)),Le=Oe().OTEL_ENDPOINT,ve={...N,OTEL_EXPORTER_OTLP_ENDPOINT:e??Le};a.env={...E,...ve,...t??{}},a.otelHeadersHelper="flow-ai-obs otel-headers",(!a.hooks||typeof a.hooks!="object"||Array.isArray(a.hooks))&&(a.hooks={});let Re=(l,O)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${l}`,timeout:O}]}),Pe=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],J=a.hooks;for(let l of Pe){let O=ft(J[l],Re(l,b[l]));O.length>1&&s.push(l),J[l]=O;}i__namespace.writeFileSync(r,JSON.stringify(a,null,2)+`
3
+ `,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(r,384);}catch{}}finally{me(n);}return {settingsPath:r,preserved:s}}function K(e){let t=k(),r=t+".lock";i__namespace.mkdirSync(p__namespace.dirname(t),{recursive:true}),de(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{me(r);}}c();c();function ge(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 he(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}.`}c();var X;function ye(){return X||(X=_e()),X}var Se=p__namespace.default.join(f__namespace.default.tmpdir(),"flow-obs-update-cache.json"),_t=1440*60*1e3,Tt=3e3;function yt(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 St(){try{let e=JSON.parse(i__namespace.default.readFileSync(Se,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=_t?null:e}catch{return null}}function At(e,t,r=Date.now()){try{i__namespace.default.writeFileSync(Se,JSON.stringify({latestVersion:e,updatePriority:t??null,checkedAt:r}),{mode:384});}catch{}}function wt(e){let t=ye().name,r=Et__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:Tt},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 Ae(){try{if(St())return;setImmediate(()=>{wt((e,t)=>{e||!t||yt(ye().version,t.version)&&At(t.version,t.updatePriority,0);});});}catch{}}var Ot=p__namespace.default.resolve(__dirname,".."),Lt=process.env.INIT_CWD?p__namespace.default.resolve(process.env.INIT_CWD):null;Lt===Ot&&process.exit(0);G()&&(process.stderr.write(`
5
5
  [flow-ai-obs] \u2717 Do not install with sudo.
6
6
  Run without sudo: npm install -g @ciandt-flow/flow-ai-obs
7
7
 
8
- `),process.exit(1));async function vt(){try{fe();}catch{}let e=await se();if(!e){process.stderr.write(`
8
+ `),process.exit(1));async function vt(){try{Ee();}catch{}let e=await ie();if(!e){process.stderr.write(`
9
9
  [flow-ai-obs] No credentials found.
10
- Run \`flow-ai-obs auth login\` to authenticate and enable telemetry.
10
+ Run \`flow-ai-obs login\` to authenticate and enable telemetry.
11
11
 
12
- `);return}let t=ge(process.env[u.ANTHROPIC_AUTH_TOKEN]);if(!t||t.clientId!==e.clientId||t.clientSecret!==e.clientSecret||t.tenant!==e.tenant)try{let r=me(e);de({[u.ANTHROPIC_AUTH_TOKEN]:r});}catch{}}vt().catch(()=>{}).finally(()=>_e());
12
+ `);return}let t=ge(process.env[u.ANTHROPIC_AUTH_TOKEN]);if(!t||t.clientId!==e.clientId||t.clientSecret!==e.clientSecret||t.tenant!==e.tenant)try{let n=he(e);K({[u.ANTHROPIC_AUTH_TOKEN]:n});}catch{}}vt().catch(()=>{}).finally(()=>Ae());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ciandt-flow/flow-ai-obs",
3
- "version": "0.12.0",
3
+ "version": "0.12.1-beta.22",
4
4
  "description": "Claude Code hooks for Langfuse OTLP tracing — cross-platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {