@ciandt-flow/flow-ai-obs 0.13.0 → 0.14.0-beta.61

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,4 +1,4 @@
1
- 'use strict';var child_process=require('child_process'),util=require('util'),h=require('fs'),G=require('path'),st=require('os'),cr=require('https'),lr=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 h__namespace=/*#__PURE__*/_interopNamespace(h);var G__namespace=/*#__PURE__*/_interopNamespace(G);var st__namespace=/*#__PURE__*/_interopNamespace(st);var cr__default=/*#__PURE__*/_interopDefault(cr);var lr__default=/*#__PURE__*/_interopDefault(lr);var Ve=Object.defineProperty;var ft=(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 dt=(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)Ve(t,r,{get:e[r],enumerable:true});};function B(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():je}function H(){let t=B();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=B();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var je,dn,mt,gt,Et,Rt,g,Q,Kt,k,W,Jt,R,T=dt(()=>{"use strict";je="https://flow.ciandt.com";dn=H(),mt={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},gt="FLOW-nodejs",Et="config.json",Rt={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},g={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_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"},Q={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},Kt={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},k={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},W={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[\x21-\x7E]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},Jt="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 qt={};wt(qt,{MacOsKeyVaultProvider:()=>bt});var vt,bt,zt=dt(()=>{"use strict";vt=util.promisify(child_process.execFile),bt=class{static async isAvailable(){try{return h.accessSync("/usr/bin/security",h.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 Qt={};wt(Qt,{LinuxKeyVaultProvider:()=>Nt});var Zt,Nt,te=dt(()=>{"use strict";Zt=util.promisify(child_process.execFile),Nt=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 h.accessSync(r,h.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((s,o)=>{let i=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",r]);i.on("error",o),i.on("close",c=>{c===0?s():o(new Error(`secret-tool exited with code ${c}`));}),i.stdin.write(n),i.stdin.end();});}async deleteSecret(e,r){try{return await Zt("secret-tool",["clear","service",e,"account",r]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var ee={};wt(ee,{WindowsKeyVaultProvider:()=>Ut});var Ut,re=dt(()=>{"use strict";Ut=class{static async isAvailable(){try{return await ft("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,r){return ft("keytar").getPassword(e,r)}async setSecret(e,r,n){await ft("keytar").setPassword(e,r,n);}async deleteSecret(e,r){return ft("keytar").deletePassword(e,r)}getStoragePath(){return "Windows Credential Manager"}};});T();T();var It={credentials:"credentials","token-cache":"tokenCache"};function tt(){let t=st__namespace.default.homedir();if(process.platform==="darwin")return G__namespace.default.join(t,"Library","Preferences",gt,Et);if(process.platform==="win32"){let r=process.env.APPDATA??G__namespace.default.join(t,"AppData","Roaming");return G__namespace.default.join(r,gt,Et)}let e=process.env.XDG_CONFIG_HOME??G__namespace.default.join(t,".config");return G__namespace.default.join(e,gt,Et)}function Pt(){try{let t=h__namespace.default.readFileSync(tt(),"utf8");return JSON.parse(t)}catch{return {}}}function Xt(t){let e=tt();h__namespace.default.mkdirSync(G__namespace.default.dirname(e),{recursive:true}),h__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var rt=class{static isAvailable(){return true}static hasExistingData(){try{if(!h__namespace.default.existsSync(tt()))return !1;let e=JSON.parse(h__namespace.default.readFileSync(tt(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,r){let n=Pt(),s=It[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(e,r,n){let s=Pt(),o=It[r]??r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;Xt(s);}async deleteSecret(e,r){let n=Pt(),s=It[r]??r;return s in n?(delete n[s],Xt(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${tt()}`}};async function ne(){return process.env[g.FLOW_OBS_USE_JSON_VAULT]==="1"?new rt:await nr()??new rt}async function nr(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(zt(),qt));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(te(),Qt));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(re(),ee));return await t.isAvailable()?new t:null}default:return null}}T();var se=mt.SERVICE;mt.ACCOUNT_CREDS;var oe=mt.ACCOUNT_TOKEN,Ct=null;function ie(){return Ct||(Ct=ne()),Ct}async function Ft(t){await(await ie()).setSecret(se,oe,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function $t(){let e=await(await ie()).getSecret(se,oe);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 nt(){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}}T();T();var ar=G.join(st.tmpdir(),Jt);function a(...t){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
1
+ 'use strict';var child_process=require('child_process'),util=require('util'),h=require('fs'),G=require('path'),st=require('os'),cr=require('https'),lr=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 h__namespace=/*#__PURE__*/_interopNamespace(h);var G__namespace=/*#__PURE__*/_interopNamespace(G);var st__namespace=/*#__PURE__*/_interopNamespace(st);var cr__default=/*#__PURE__*/_interopDefault(cr);var lr__default=/*#__PURE__*/_interopDefault(lr);var Ve=Object.defineProperty;var ft=(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 dt=(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)Ve(t,r,{get:e[r],enumerable:true});};function B(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():je}function H(){let t=B();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=B();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var je,dn,mt,gt,Et,Rt,g,Q,Kt,k,W,Jt,R,T=dt(()=>{"use strict";je="https://flow.ciandt.com";dn=H(),mt={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},gt="FLOW-nodejs",Et="config.json",Rt={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},g={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_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",FLOW_OBS_SKIP_DESKTOP_DETECTION:"FLOW_OBS_SKIP_DESKTOP_DETECTION",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"},Q={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},Kt={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},k={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},W={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[\x21-\x7E]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},Jt="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 qt={};wt(qt,{MacOsKeyVaultProvider:()=>vt});var Nt,vt,zt=dt(()=>{"use strict";Nt=util.promisify(child_process.execFile),vt=class{static async isAvailable(){try{return h.accessSync("/usr/bin/security",h.constants.X_OK),!0}catch{return !1}}async getSecret(e,r){try{let{stdout:n}=await Nt("security",["find-generic-password","-w","-a",r,"-s",e]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await Nt("security",["add-generic-password","-U","-a",r,"-s",e,"-w",n]);}async deleteSecret(e,r){try{return await Nt("security",["delete-generic-password","-a",r,"-s",e]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var Qt={};wt(Qt,{LinuxKeyVaultProvider:()=>bt});var Zt,bt,te=dt(()=>{"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 h.accessSync(r,h.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((s,o)=>{let i=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",r]);i.on("error",o),i.on("close",c=>{c===0?s():o(new Error(`secret-tool exited with code ${c}`));}),i.stdin.write(n),i.stdin.end();});}async deleteSecret(e,r){try{return await Zt("secret-tool",["clear","service",e,"account",r]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var ee={};wt(ee,{WindowsKeyVaultProvider:()=>Ut});var Ut,re=dt(()=>{"use strict";Ut=class{static async isAvailable(){try{return await ft("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,r){return ft("keytar").getPassword(e,r)}async setSecret(e,r,n){await ft("keytar").setPassword(e,r,n);}async deleteSecret(e,r){return ft("keytar").deletePassword(e,r)}getStoragePath(){return "Windows Credential Manager"}};});T();T();var It={credentials:"credentials","token-cache":"tokenCache"};function tt(){let t=st__namespace.default.homedir();if(process.platform==="darwin")return G__namespace.default.join(t,"Library","Preferences",gt,Et);if(process.platform==="win32"){let r=process.env.APPDATA??G__namespace.default.join(t,"AppData","Roaming");return G__namespace.default.join(r,gt,Et)}let e=process.env.XDG_CONFIG_HOME??G__namespace.default.join(t,".config");return G__namespace.default.join(e,gt,Et)}function Pt(){try{let t=h__namespace.default.readFileSync(tt(),"utf8");return JSON.parse(t)}catch{return {}}}function Xt(t){let e=tt();h__namespace.default.mkdirSync(G__namespace.default.dirname(e),{recursive:true}),h__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var rt=class{static isAvailable(){return true}static hasExistingData(){try{if(!h__namespace.default.existsSync(tt()))return !1;let e=JSON.parse(h__namespace.default.readFileSync(tt(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,r){let n=Pt(),s=It[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(e,r,n){let s=Pt(),o=It[r]??r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;Xt(s);}async deleteSecret(e,r){let n=Pt(),s=It[r]??r;return s in n?(delete n[s],Xt(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${tt()}`}};async function ne(){return process.env[g.FLOW_OBS_USE_JSON_VAULT]==="1"?new rt:await nr()??new rt}async function nr(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(zt(),qt));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(te(),Qt));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(re(),ee));return await t.isAvailable()?new t:null}default:return null}}T();var se=mt.SERVICE;mt.ACCOUNT_CREDS;var oe=mt.ACCOUNT_TOKEN,Ct=null;function ie(){return Ct||(Ct=ne()),Ct}async function Ft(t){await(await ie()).setSecret(se,oe,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function $t(){let e=await(await ie()).getSecret(se,oe);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 nt(){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}}T();T();var ar=G.join(st.tmpdir(),Jt);function a(...t){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
2
2
  `;try{h.writeFileSync(ar,e,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
3
3
  `);}}var U=class extends Error{statusCode;constructor(e,r=0){super(e),this.name="AuthError",this.statusCode=r;}},ur=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function pr(t){if(!ur.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var ae={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 fr(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}`:"")),ae[n.error]))return new U(ae[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{pr(t.tenant);}catch(p){return r(p)}let n=JSON.stringify({clientSecret:t.clientSecret}),s=new URL(H().AUTH_ENGINE),o=s.protocol==="https:",i={hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname+s.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(n),FlowTenant:t.tenant}};a("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let l=(o?cr__default.default:lr__default.default).request(i,p=>{let S=[];p.on("data",m=>S.push(m)),p.on("end",()=>{let m=S.join("");if((p.statusCode??0)>=400)return r(fr(p.statusCode??0,m));let _;try{_=JSON.parse(m);}catch{return r(new Error("Invalid response from auth engine"))}let E=_.expires_at??new Date(Date.now()+(_.expires_in??3600)*1e3).toISOString();if(!_.access_token)return r(new Error("Auth engine returned an empty access token. Check FLOW_BASE_URL and credentials."));e({accessToken:_.access_token,expiresAt:E});});});l.on("error",p=>r(new Error(`Network error: ${p.message}`))),l.setTimeout(Q.REQUEST_TIMEOUT_MS,()=>{l.destroy(new Error("Request timeout"));}),l.write(n),l.end();})}T();T();!process.env.NO_COLOR&&process.stdout.isTTY;function _t(){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 G__namespace.join(e,".claude","settings.json")}return G__namespace.join(st__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||st__namespace.homedir();return G__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 G__namespace.join(e,".claude","settings.json")}return G__namespace.join(st__namespace.homedir(),".claude","settings.json")}var Er=Kt.LOCK_STALE_MS;function _r(t){try{let e=h__namespace.statSync(t);Date.now()-e.mtimeMs>Er&&h__namespace.unlinkSync(t);}catch{}try{h__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 Sr(t){try{h__namespace.unlinkSync(t);}catch{}}var ot;function ue(t){if(ot===void 0)try{let r=h__namespace.readFileSync(_t(),"utf8");ot=JSON.parse(r).env??null;}catch{ot=null;}if(!ot)return null;let e=ot[t];return typeof e=="string"?e:null}function pe(t){let e=_t(),r=e+".lock";h__namespace.mkdirSync(G__namespace.dirname(e),{recursive:true}),_r(r);try{let n={};try{n=JSON.parse(h__namespace.readFileSync(e,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,t),h__namespace.writeFileSync(e,JSON.stringify(n,null,2)+`
4
4
  `,{encoding:"utf8",mode:384});try{h__namespace.chmodSync(e,384);}catch{}}finally{Sr(r);}}T();function fe(){return !!process.env[g.FLOW_USER_EMAIL]||!!ue(g.FLOW_USER_EMAIL)}function Dt(t){a("maybePersistUserEmail",`${t}: starting`);let e=t==="api-key"?`\u26A0\uFE0F flow-ai-obs: FLOW_USER_EMAIL is not set. Configure it with:
@@ -8,16 +8,16 @@
8
8
  `;return nt().then(r=>{if(r){let n=r.split(/[\r\n]/)[0].replace(/[\x00-\x1F\x7F]/g,"").trim();if(!n)return;let s=n.indexOf("@"),o=n.slice(s+1);if(!(n.length<=254&&W.EMAIL_HEADER_PATTERN.test(n)&&(n.match(/@/g)??[]).length===1&&s>0&&s<n.length-1&&o.includes("."))){a("maybePersistUserEmail",`${t}: email from token failed basic validation \u2014 skipping persist`);return}try{pe({[g.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
9
  Run: flow-ai-obs init
10
10
  `);}}else process.stderr.write(e);}).catch(r=>{a("maybePersistUserEmail",`${t}: getEmailFromToken failed: ${r.message}`);})}var Tr=[/^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 hr(t){return Tr.some(e=>e.test(t))}function yr(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 Tt(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let r=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:n,clientSecret:s,tenant:o}=r;return !n||!s||!o?null:{clientId:n,clientSecret:s,tenant:o}}catch{return null}}function St(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let r=process.env[g.FLOW_OBS_ALLOW_HTTP]==="true";if(!r&&e.protocol!=="https:")throw new Error(`URL must use HTTPS: ${t}`);if(e.username||e.password)throw new Error(`URL must not contain embedded credentials: ${t}`);if(!r&&hr(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function de(){let t=Tt(process.env[g.ANTHROPIC_AUTH_TOKEN]);return t?{user:await nt().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function Ar(){let t=process.env[g.FLOW_API_KEY];if(!t)return null;let e=t.replace(/[\r\n]/g,"").trim();return e?e.length>W.API_KEY_MAX_LENGTH?(a("resolveApiKey",`FLOW_API_KEY exceeds ${W.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):W.API_KEY_PATTERN.test(e)?e:(a("resolveApiKey","FLOW_API_KEY contains non-printable or control characters \u2014 rejected"),null):null}function Or(){return new Date().toISOString().slice(0,10)}async function kr(t){let e=Or(),r=await $t();if(r?.lastAuthCheckAt!==e){a("getOrRefreshToken",`daily auth check (last: ${r?.lastAuthCheckAt??"never"})`);let o=Q.MAX_RETRY_ATTEMPTS;for(let i=1;i<=o;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}`),Ar()?fe()||await Dt("api-key"):await Dt("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<o){a("getOrRefreshToken",`daily check 500 error (attempt ${i}/${o}) \u2014 retrying in 1s`),await new Promise(l=>setTimeout(l,Q.RETRY_DELAY_MS));continue}throw a("getOrRefreshToken",`daily check failed after ${o} 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 s=await Y(t);try{await Ft({...s,lastAuthCheckAt:e});}catch(o){a("getOrRefreshToken",`token cache save failed (non-fatal): ${o.message}`);}return a("getOrRefreshToken",`token refreshed, expires=${s.expiresAt}`),s.accessToken}function wr(t,e){let r=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function Rr(t,e,r){let n=Buffer.from(`${e}:${r}`).toString("base64");return {endpoint:t.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${n}`}}async function K(){let t=[],e=Tt(process.env[g.ANTHROPIC_AUTH_TOKEN]);a("resolveCredentials",e?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),e&&a("resolveCredentials",`clientId=${e.clientId}`,`tenant=${e.tenant}`);let r=e?e.tenant:"",n=process.env[g.FLOW_TELEMETRY]==="true",s=process.env[g.LANGFUSE_BASE_URL],o=process.env[g.LANGFUSE_PUBLIC_KEY],i=process.env[g.LANGFUSE_SECRET_KEY];if(n&&s&&o&&i){let m="",_=r;e&&(m=await nt().catch(()=>null)??e.clientId);let E={user:m??"",tenant:_??"",team:"",project:""};t.push({mode:"direct",...Rr(St(s),o,i),...E}),a("resolveCredentials","direct mode active",`user=${E.user}`,`tenant=${E.tenant}`);}if(!e){if(t.length===0){let m=[];return m.authError=false,m}return t}let c;try{c=await kr(e);}catch(m){if(a("resolveCredentials",`token refresh failed: ${m.message}`,`(tenant=${e.tenant} clientId=${e.clientId})`),t.length>0)return t.authError=true,t;let _=[];return _.authError=true,_}let p={user:yr(c)??e.clientId,tenant:r,team:"",project:""},S=process.env[g.FLOW_TELEMETRY_GATEWAY]??B();return t.push({mode:"gateway",...wr(St(S),{accessToken:c}),...p}),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 ht(t,e=100){return String(t??"").split(`
11
- `)[0].slice(0,e).trim()}function it(){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 xt=()=>crypto.randomBytes(16).toString("hex"),C=()=>crypto.randomBytes(8).toString("hex");function P(){return String(BigInt(Date.now())*1000000n)}var Fr=/^[0-9a-f-]{1,64}$/i,$r=G.normalize(st.tmpdir())+G.sep;function Dr(t,e){let r=G.resolve(t);if(!r.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return r}function Mt(t){if(!Fr.test(t))throw new Error(`Invalid session ID: ${t}`);return Dr(G.join(st.tmpdir(),`flow-obs-${t}.json`),$r)}function J(t){let e;try{e=Mt(t);}catch{return null}if(!h.existsSync(e))return null;try{return JSON.parse(h.readFileSync(e,"utf8"))}catch{return null}}function X(t,e){h.writeFileSync(Mt(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function Bt(t){try{h.unlinkSync(Mt(t));}catch{}}function Se(t){if(!t||!h.existsSync(t))return null;try{let e=h.readFileSync(t,"utf8").trimEnd().split(`
11
+ `)[0].slice(0,e).trim()}function it(){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 Mt=()=>crypto.randomBytes(16).toString("hex"),C=()=>crypto.randomBytes(8).toString("hex");function P(){return String(BigInt(Date.now())*1000000n)}var Fr=/^[0-9a-f-]{1,64}$/i,$r=G.normalize(st.tmpdir())+G.sep;function Dr(t,e){let r=G.resolve(t);if(!r.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return r}function xt(t){if(!Fr.test(t))throw new Error(`Invalid session ID: ${t}`);return Dr(G.join(st.tmpdir(),`flow-obs-${t}.json`),$r)}function J(t){let e;try{e=xt(t);}catch{return null}if(!h.existsSync(e))return null;try{return JSON.parse(h.readFileSync(e,"utf8"))}catch{return null}}function X(t,e){h.writeFileSync(xt(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function Bt(t){try{h.unlinkSync(xt(t));}catch{}}function Se(t){if(!t||!h.existsSync(t))return null;try{let e=h.readFileSync(t,"utf8").trimEnd().split(`
12
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||!h.existsSync(t))return null;try{let e=h.readFileSync(t,"utf8").trimEnd().split(`
13
13
  `),r=[],n=0,s=0,o;for(let i=e.length-1;i>=0;i--)try{let c=JSON.parse(e[i]);if(c.type==="user")break;if(c.type==="assistant"){!o&&c.message?.model&&(o=c.message.model);let p=(c.message?.content??[]).filter(m=>m.type==="text").map(m=>m.text??"").join("");p&&r.unshift(p);let S=c.message?.usage??{};n+=(S.input_tokens??0)+(S.cache_read_input_tokens??0)+(S.cache_creation_input_tokens??0),s+=S.output_tokens??0;}}catch{}return !r.length&&n===0?null:{text:r.join(`
14
14
 
15
15
  `),inputTokens:n,outputTokens:s,model:o}}catch{}return null}var Hr=new Set([".venv","__pycache__",".git","node_modules"]),Wr=new Set([".pyc",".pyo"]),Gr=new Set(["SKILL.md",".DS_Store",".gitignore"]);function ye(t){return t.replace(":","/")}function yt(t,e){if(!t)return null;let r=ye(t),n=[G.join(st.homedir(),".claude","skills",r,"SKILL.md"),G.join(e??"",".claude","skills",r,"SKILL.md")];for(let s of n)if(h.existsSync(s))try{return h.readFileSync(s,"utf8")}catch{}return null}function Ae(t){return t.split(`
16
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 Oe(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 At(t,e){if(!t)return null;let r=ye(t),n=[G.join(st.homedir(),".claude","skills",r),G.join(e??"",".claude","skills",r)],s=null;for(let c of n)if(h.existsSync(G.join(c,"SKILL.md"))){s=c;break}if(!s)return null;let o=[];function i(c,l){for(let p of h.readdirSync(c,{withFileTypes:true})){if(Hr.has(p.name)||Gr.has(p.name)||Wr.has(G.extname(p.name)))continue;let S=l?`${l}/${p.name}`:p.name;p.isDirectory()?i(G.join(c,p.name),S):o.push(S);}}return i(s,""),o.length>0?o:null}T();T();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 Jr(t,e,r,n){return new Promise(s=>{let o=new URL(t),i=o.protocol==="https:",c=(i?cr__default.default:lr__default.default).request({hostname:o.hostname,port:o.port||(i?443:80),path:o.pathname+o.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(),s(l.statusCode??0);});c.on("error",()=>s(0)),c.setTimeout(5e3,()=>{c.destroy(),s(0);}),c.write(e),c.end();})}async function F(t,e={}){try{let r=Tt(process.env[g.ANTHROPIC_AUTH_TOKEN]);if(!r)return;let n,s=new Promise((m,_)=>{n=setTimeout(()=>_(new Error("getToken timeout")),4e3),n.unref();}),{accessToken:o}=await Promise.race([Y(r),s]);clearTimeout(n);let i=Kr(o);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=St(Lt().API_URL),S=await Jr(p,l,o,c);a("metrics.logEvent",`action=${t} status=${S}`);}catch(r){a("metrics.logEvent",`silenced error: ${r.message}`);}}var Xr=`\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 ${B()}/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:Xr})+`
17
- `);return}let n=!!(await K()).authError,s=t.session_id||"unknown",o=t.prompt||"",i=t.cwd||"",c=Se(t.transcript_path)||xt(),l=Ae(o),p=l?yt(l,i):null,S=l?At(l,i):null;X(s,{traceId:xt(),spanId:C(),startNs:P(),sessionId:s,prompt:o,cwd:i,traceName:c,transcriptPath:t.transcript_path||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:l,skillContent:p,skillArtifacts:S}),F("SESSION_STARTED",{traceType:l?"skill":"prompt",slashSkill:l,clientIdExpired:n}),a("UserPromptSubmit",`sid=${s}`,`traceName=${c}`,`slashSkill=${l}`),A(t);}T();async function ke(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=J(e);s&&(s.pendingTool={name:r,inputStr:L(n,R.TOOL_INPUT),startNs:P()},X(e,s)),a("PreToolUse",`sid=${e}`,`tool=${r}`,`stateFound=${!!s}`),A(t);}T();var qr={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 we(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:qr,spans:Array.isArray(e)?e:[e]}]}]}}T();var Re=G.join(st.tmpdir(),"flow-obs-requests.ndjson");function Le(t,e,r,n,s){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let o=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(r)},response:{status:n,body:s}});try{h.writeFileSync(Re,o+`
18
- `,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${Re}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function rn(t){let e=new URL(t),r=new URL(H().GATEWAY_HEALTH);return r.hostname=e.hostname,r.port=e.port,r.protocol=e.protocol,r}function Ie(t,e){return new Promise((r,n)=>{let s=t._isSSL?cr__default.default:lr__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let o=s.request(t,i=>{let c=[];i.on("data",l=>c.push(l)),i.on("end",()=>r({statusCode:i.statusCode??0,body:c.join("")}));});o.setTimeout(1e4,()=>{o.destroy(new Error("Request timeout"));}),o.on("error",i=>n(new Error(`Network error: ${i.message}`))),e&&o.write(e),o.end();})}async function Pe(t,e){let r;try{r=rn(t);}catch{return false}let n=r.protocol==="https:";try{let s={};e&&(s.Authorization=String(e).replace(/[\r\n]/g,""));let o=await Ie({hostname:r.hostname,port:r.port||(n?443:80),path:r.pathname,method:"GET",headers:s,_isSSL:n},null);return a("checkHealth",`url=${r.href} status=${o.statusCode}`),o.statusCode>=200&&o.statusCode<300}catch{return false}}async function Ot(t,e,r){let n=JSON.stringify(t),s=new URL(e),o=s.protocol==="https:",i=String(r).replace(/[\r\n]/g,""),c={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(n)};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 Ie({hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:c,_isSSL:o},n);return a("sendTraces:response",`status=${l.statusCode}`),Le(e,c,n,l.statusCode,l.body),l.statusCode}catch(l){return a("sendTraces:error",l.message),Le(e,c,n,0,l.message),0}}T();function nn(){let t=parseInt(process.env[g.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(k.MIN_TTL_DAYS,Math.min(k.MAX_TTL_DAYS,t)):k.DEFAULT_TTL_DAYS)*24*60*60*1e3}function sn(){let t=parseInt(process.env[g.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(k.MIN_MAX_FILES,Math.min(k.MAX_MAX_FILES,t)):k.DEFAULT_MAX_FILES}function be(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return G__namespace.default.join(st__namespace.default.tmpdir(),`${k.FILE_PREFIX}${t}.json`)}function Yt(){let t=st__namespace.default.tmpdir(),e;try{e=h__namespace.default.readdirSync(t);}catch{return []}return e.filter(r=>r.startsWith(k.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=G__namespace.default.join(t,r),s=0;try{s=h__namespace.default.statSync(n).mtimeMs;}catch{}return {full:n,mtime:s}}).sort((r,n)=>r.mtime-n.mtime).map(r=>r.full)}function at(t){try{let e=sn(),r=Yt();if(r.length>=e){let o=r.slice(0,r.length-e+1);for(let i of o)try{h__namespace.default.unlinkSync(i);}catch{}}let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:n,bufferedAt:Date.now(),payload:t};return h__namespace.default.writeFileSync(be(n),JSON.stringify(s),{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=Yt(),r=t!=null&&t>0?t:e.length,n=[];for(let s of e){if(n.length>=r)break;try{let o=h__namespace.default.readFileSync(s,"utf8"),i=JSON.parse(o);i&&i.fileId&&i.payload&&n.push(i);}catch{a("buffer",`skipping malformed file: ${s}`);}}return n}function Ue(t){try{h__namespace.default.unlinkSync(be(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function Ce(){let t=Date.now()-nn();for(let e of Yt())try{let{mtimeMs:r}=h__namespace.default.statSync(e);r<t&&(h__namespace.default.unlinkSync(e),a("buffer",`evicted stale: ${G__namespace.default.basename(e)}`));}catch{}}T();async function on(t){Ce();let e=Ne(k.REPLAY_BATCH_SIZE);e.length&&(a("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async r=>{try{let n=await Ot(r.payload,t.endpoint,t.authHeader);n>=200&&n<300?(Ue(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 Fe(t){let e=await K();if(!e.length)return e.authError&&(a("postToLangfuse","auth refresh failed \u2014 buffering trace"),at(t)),0;let r=await Promise.all(e.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await Pe(o.endpoint,o.authHeader);return {creds:o,healthy:i}})),n=r.find(o=>o.creds.mode==="gateway"&&o.healthy)?.creds??r.find(o=>o.creds.mode==="direct")?.creds;return n&&await on(n),(await Promise.all(r.map(async({creds:o,healthy:i})=>{if(o.mode==="gateway"){if(!i)return a("postToLangfuse","gateway health check failed \u2014 buffering trace"),at(t),0;let l=await Ot(t,o.endpoint,o.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`gateway send failed (status ${l}) \u2014 buffering trace`),at(t)),l}let c=await Ot(t,o.endpoint,o.authHeader);return (c===0||c>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${c}) \u2014 buffering trace`),at(t)),c}))).find(o=>o!==0)??0}T();var O="[REDACTED]",an="[REDACTED-EMAIL]",cn="[REDACTED-CPF]",ln="[REDACTED-CNPJ]",$e="[REDACTED-PHONE]",un=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${O}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${O}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${O}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${O}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,r)=>`${e}
17
+ `);return}let n=!!(await K()).authError,s=t.session_id||"unknown",o=t.prompt||"",i=t.cwd||"",c=Se(t.transcript_path)||Mt(),l=Ae(o),p=l?yt(l,i):null,S=l?At(l,i):null;X(s,{traceId:Mt(),spanId:C(),startNs:P(),sessionId:s,prompt:o,cwd:i,traceName:c,transcriptPath:t.transcript_path||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:l,skillContent:p,skillArtifacts:S}),F("SESSION_STARTED",{traceType:l?"skill":"prompt",slashSkill:l,clientIdExpired:n}),a("UserPromptSubmit",`sid=${s}`,`traceName=${c}`,`slashSkill=${l}`),A(t);}T();async function ke(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=J(e);s&&(s.pendingTool={name:r,inputStr:L(n,R.TOOL_INPUT),startNs:P()},X(e,s)),a("PreToolUse",`sid=${e}`,`tool=${r}`,`stateFound=${!!s}`),A(t);}T();var qr={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 we(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:qr,spans:Array.isArray(e)?e:[e]}]}]}}T();var Re=G.join(st.tmpdir(),"flow-obs-requests.ndjson");function Le(t,e,r,n,s){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let o=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(r)},response:{status:n,body:s}});try{h.writeFileSync(Re,o+`
18
+ `,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${Re}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function rn(t){let e=new URL(t),r=new URL(H().GATEWAY_HEALTH);return r.hostname=e.hostname,r.port=e.port,r.protocol=e.protocol,r}function Ie(t,e){return new Promise((r,n)=>{let s=t._isSSL?cr__default.default:lr__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let o=s.request(t,i=>{let c=[];i.on("data",l=>c.push(l)),i.on("end",()=>r({statusCode:i.statusCode??0,body:c.join("")}));});o.setTimeout(1e4,()=>{o.destroy(new Error("Request timeout"));}),o.on("error",i=>n(new Error(`Network error: ${i.message}`))),e&&o.write(e),o.end();})}async function Pe(t,e){let r;try{r=rn(t);}catch{return false}let n=r.protocol==="https:";try{let s={};e&&(s.Authorization=String(e).replace(/[\r\n]/g,""));let o=await Ie({hostname:r.hostname,port:r.port||(n?443:80),path:r.pathname,method:"GET",headers:s,_isSSL:n},null);return a("checkHealth",`url=${r.href} status=${o.statusCode}`),o.statusCode>=200&&o.statusCode<300}catch{return false}}async function Ot(t,e,r){let n=JSON.stringify(t),s=new URL(e),o=s.protocol==="https:",i=String(r).replace(/[\r\n]/g,""),c={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(n)};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 Ie({hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:c,_isSSL:o},n);return a("sendTraces:response",`status=${l.statusCode}`),Le(e,c,n,l.statusCode,l.body),l.statusCode}catch(l){return a("sendTraces:error",l.message),Le(e,c,n,0,l.message),0}}T();function nn(){let t=parseInt(process.env[g.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(k.MIN_TTL_DAYS,Math.min(k.MAX_TTL_DAYS,t)):k.DEFAULT_TTL_DAYS)*24*60*60*1e3}function sn(){let t=parseInt(process.env[g.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(k.MIN_MAX_FILES,Math.min(k.MAX_MAX_FILES,t)):k.DEFAULT_MAX_FILES}function ve(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return G__namespace.default.join(st__namespace.default.tmpdir(),`${k.FILE_PREFIX}${t}.json`)}function Yt(){let t=st__namespace.default.tmpdir(),e;try{e=h__namespace.default.readdirSync(t);}catch{return []}return e.filter(r=>r.startsWith(k.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=G__namespace.default.join(t,r),s=0;try{s=h__namespace.default.statSync(n).mtimeMs;}catch{}return {full:n,mtime:s}}).sort((r,n)=>r.mtime-n.mtime).map(r=>r.full)}function at(t){try{let e=sn(),r=Yt();if(r.length>=e){let o=r.slice(0,r.length-e+1);for(let i of o)try{h__namespace.default.unlinkSync(i);}catch{}}let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:n,bufferedAt:Date.now(),payload:t};return h__namespace.default.writeFileSync(ve(n),JSON.stringify(s),{encoding:"utf8",mode:384}),a("buffer",`saved fileId=${n}`),n}catch(e){return a("buffer",`saveToBuffer failed: ${e.message}`),null}}function be(t){let e=Yt(),r=t!=null&&t>0?t:e.length,n=[];for(let s of e){if(n.length>=r)break;try{let o=h__namespace.default.readFileSync(s,"utf8"),i=JSON.parse(o);i&&i.fileId&&i.payload&&n.push(i);}catch{a("buffer",`skipping malformed file: ${s}`);}}return n}function Ue(t){try{h__namespace.default.unlinkSync(ve(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function Ce(){let t=Date.now()-nn();for(let e of Yt())try{let{mtimeMs:r}=h__namespace.default.statSync(e);r<t&&(h__namespace.default.unlinkSync(e),a("buffer",`evicted stale: ${G__namespace.default.basename(e)}`));}catch{}}T();async function on(t){Ce();let e=be(k.REPLAY_BATCH_SIZE);e.length&&(a("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async r=>{try{let n=await Ot(r.payload,t.endpoint,t.authHeader);n>=200&&n<300?(Ue(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 Fe(t){let e=await K();if(!e.length)return e.authError&&(a("postToLangfuse","auth refresh failed \u2014 buffering trace"),at(t)),0;let r=await Promise.all(e.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await Pe(o.endpoint,o.authHeader);return {creds:o,healthy:i}})),n=r.find(o=>o.creds.mode==="gateway"&&o.healthy)?.creds??r.find(o=>o.creds.mode==="direct")?.creds;return n&&await on(n),(await Promise.all(r.map(async({creds:o,healthy:i})=>{if(o.mode==="gateway"){if(!i)return a("postToLangfuse","gateway health check failed \u2014 buffering trace"),at(t),0;let l=await Ot(t,o.endpoint,o.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`gateway send failed (status ${l}) \u2014 buffering trace`),at(t)),l}let c=await Ot(t,o.endpoint,o.authHeader);return (c===0||c>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${c}) \u2014 buffering trace`),at(t)),c}))).find(o=>o!==0)??0}T();var O="[REDACTED]",an="[REDACTED-EMAIL]",cn="[REDACTED-CPF]",ln="[REDACTED-CNPJ]",$e="[REDACTED-PHONE]",un=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${O}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${O}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${O}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${O}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,r)=>`${e}
19
19
  ${O}
20
- ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${O}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${O}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${O}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${O}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${O}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(t,e,r)=>`${e}${r}${O}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${O}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>an},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>cn},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>ln},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>$e},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>$e}];function b(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return un.reduce((r,{re:n,replace:s})=>r.replace(n,s),e)}async function De(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=t.tool_response,o=s!==null&&typeof s=="object"?s.output??JSON.stringify(s):s??"",i=J(e);if(!i){A(t);return}let c=P(),l=i.pendingTool,p=l?.name===r,S=p?l.startNs:String(BigInt(c)-200000000n),m=p?l.inputStr:L(n,R.TOOL_INPUT),_=m,E=null;if(r==="Skill"){let Z=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||n.commandName||String(Object.values(n)[0]??""):String(n);E=Z?String(Z).trim():null;let M=E?yt(E,i.cwd):null;M&&(_=M,i.skillContent||(i.skillContent=M),i.skillArtifacts||(i.skillArtifacts=At(E,i.cwd))),E&&!i.slashSkill&&(i.slashSkill=E),a("PostToolUse","Skill tool detected",`skillName=${E}`,`contentFound=${!!M}`);}let w=b(L(o,R.TOOL_OUTPUT)),y=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(w.slice(0,500)),ct=y?"ERROR":"DEFAULT",z=C(),lt=Math.round(Number(BigInt(c)-BigInt(S))/1e6),pt={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL",x=r==="Skill"&&E?E:ht(m,60);i.toolCalls.push({tool:r,brief:x,error:y,durationMs:lt});let I=i.spans;I.push({traceId:i.traceId,spanId:z,parentSpanId:i.spanId,name:r,kind:3,startTimeUnixNano:S,endTimeUnixNano:c,attributes:$(u(d.OBS_NAME,r),u(d.OBS_TYPE,pt),u(d.OBS_LEVEL,ct),u(d.OBS_INPUT,b(_)),u(d.OBS_OUTPUT,w),u("tool.name",r),u("tool.error",String(y)),r==="Skill"&&E?u("skill.name",E):null,r==="Skill"?u("skill.invocation","slash-command"):null),status:{code:y?2:1}}),i.pendingTool=null,X(e,i),y&&F("TOOL_ERROR",{toolName:r}),a("PostToolUse",`sid=${e}`,`tool=${r}`,`error=${y}`,`durationMs=${lt}`,`totalSpans=${I.length}`),A(t);}var xe={"claude-opus-5":{input:5,output:25},"claude-sonnet-5":{input:2,output:10},"claude-fable-5":{input:10,output:50},"claude-opus-4-6":{input:5,output:25},"claude-opus-4-5":{input:5,output:25},"claude-sonnet-4-6":{input:3,output:15},"claude-sonnet-4-5":{input:3,output:15},"claude-haiku-4-5":{input:1,output:5},"claude-4-6-opus":{input:5,output:25},"claude-4-6-sonnet":{input:3,output:15},"claude-4-5-opus":{input:5,output:25},"claude-4-5-sonnet":{input:3,output:15},"claude-4-5-haiku":{input:1,output:5},"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 Me(t,e,r){let n=Object.keys(xe).find(i=>(t??"").toLowerCase().includes(i));if(!n)return;let s=xe[n],o=(e*s.input+r*s.output)/1e6;return Math.round(o*1e6)/1e6}T();async function Be(t){let e=t.session_id||"unknown",r=t.stop_reason||"end_turn",n=J(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 s=P(),o=await de(),i=n.toolCalls,c=n.spans;if(n.slashSkill&&!i.some(f=>f.tool==="Skill")){let f=C(),N=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,N),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(N=>setTimeout(N,500));let f=Ht(l);f?.text&&(p=f);}a("Stop",`transcriptPath=${l||"(empty)"}`,`assistantOut=${p?`text=${p.text.length}chars`:"null"}`);let m=i.length,_=i.filter(f=>f.error).length,E=b(p?.text?L(p.text,R.TRACE_OUTPUT):m===0?"No tools used":i.map((f,N)=>`${N+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""}`).join(`
21
- `)),w=p?.inputTokens??0,y=p?.outputTokens??0,ct=i.map((f,N)=>`${N+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""} (${f.durationMs}ms)`),z=!!(n.slashSkill||i.some(f=>f.tool==="Skill")),lt=i.some(f=>f.tool==="Agent");if(!z&&!lt){a("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),F("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),Bt(e),A(t);return}let ut=z?"skill":"agent",pt=Math.round(Number(BigInt(s)-BigInt(n.startNs))/1e6),x=p?.model||"",kt=Me(x,w,y),I=Oe(n);I==="prerequisite_required"&&p?.text&&(I="complete"),I==="prerequisite_required"&&(c.push({traceId:n.traceId,spanId:C(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:s,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(!(!z||!n.prompt)){if(n.slashSkill){let f=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return f?L(b(f),R.USER_INSTRUCTION):void 0}return L(b(n.prompt),R.USER_INSTRUCTION)||void 0}})(),M=JSON.stringify({trace_type:ut,...I!==null&&{execution_status:I},...n.slashSkill?{skill_name:n.slashSkill}:{},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...Z!==void 0&&{user_instruction:Z},latency_ms:pt,...w&&{tokens_input:w},...y&&{tokens_output:y},cost_usd:kt,...x?{model:x}:{},toolCount:m,errorCount:_,stopReason:r,sessionId:n.sessionId,tools:ct.length?ct:void 0}),Vt=b(L(n.prompt,R.TRACE_INPUT)),He=$(u(d.TRACE_NAME,n.traceName),u(d.TRACE_INPUT,Vt),u(d.TRACE_OUTPUT,E),u(d.OBS_INPUT,Vt),u(d.OBS_OUTPUT,E),u(d.TRACE_METADATA,M),u(d.SESSION_ID,n.sessionId),u(d.USER_ID,o.user),u(d.OBS_TYPE,"GENERATION"),u(d.MODEL,x),w?u(d.INPUT_TOKENS,w):null,y?u(d.OUTPUT_TOKENS,y):null,u("claude.stop_reason",r),u("claude.tool_count",String(m)),u("claude.error_count",String(_)),u("claude.session_id",n.sessionId),u("flow.trace_type",ut),{key:d.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:ut}]}}}),We={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:He,status:{code:_>0?2:1}},Ge=$(u("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),u("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),jt=[...c,We];a("Stop",`sid=${e}`,`totalTools=${m}`,`errorTools=${_}`,`spans=${jt.length}`,`inputTokens=${w}`,`outputTokens=${y}`,`traceOutput="${ht(E,80)}"`);let Ye=await Fe(we(Ge,jt));a("Stop",`POST status=${Ye}`,`traceId=${n.traceId}`),F("TRACE_SENT",{latencyMs:pt,totalTools:m,errorTools:_,inputTokens:w,outputTokens:y,costUsd:kt}),Bt(e),A(t);}var D=class{static async userPromptSubmit(){let e=await it(),r;try{r=await K();}catch{A(e);return}r.authError?await Wt(e,true):r.length>0?await Wt(e):A(e);}static async preToolUse(){let e=await it();await ke(e);}static async postToolUse(){let e=await it();await De(e);}static async stop(){let e=await it();await Be(e);}};async function pn(){let t=process.argv[2];switch(t){case "UserPromptSubmit":await D.userPromptSubmit();break;case "PreToolUse":await D.preToolUse();break;case "PostToolUse":await D.postToolUse();break;case "Stop":await D.stop();break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
20
+ ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${O}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${O}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${O}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${O}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${O}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(t,e,r)=>`${e}${r}${O}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${O}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>an},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>cn},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>ln},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>$e},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>$e}];function v(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return un.reduce((r,{re:n,replace:s})=>r.replace(n,s),e)}async function De(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=t.tool_response,o=s!==null&&typeof s=="object"?s.output??JSON.stringify(s):s??"",i=J(e);if(!i){A(t);return}let c=P(),l=i.pendingTool,p=l?.name===r,S=p?l.startNs:String(BigInt(c)-200000000n),m=p?l.inputStr:L(n,R.TOOL_INPUT),_=m,E=null;if(r==="Skill"){let Z=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||n.commandName||String(Object.values(n)[0]??""):String(n);E=Z?String(Z).trim():null;let x=E?yt(E,i.cwd):null;x&&(_=x,i.skillContent||(i.skillContent=x),i.skillArtifacts||(i.skillArtifacts=At(E,i.cwd))),E&&!i.slashSkill&&(i.slashSkill=E),a("PostToolUse","Skill tool detected",`skillName=${E}`,`contentFound=${!!x}`);}let w=v(L(o,R.TOOL_OUTPUT)),y=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(w.slice(0,500)),ct=y?"ERROR":"DEFAULT",z=C(),lt=Math.round(Number(BigInt(c)-BigInt(S))/1e6),pt={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL",M=r==="Skill"&&E?E:ht(m,60);i.toolCalls.push({tool:r,brief:M,error:y,durationMs:lt});let I=i.spans;I.push({traceId:i.traceId,spanId:z,parentSpanId:i.spanId,name:r,kind:3,startTimeUnixNano:S,endTimeUnixNano:c,attributes:$(u(d.OBS_NAME,r),u(d.OBS_TYPE,pt),u(d.OBS_LEVEL,ct),u(d.OBS_INPUT,v(_)),u(d.OBS_OUTPUT,w),u("tool.name",r),u("tool.error",String(y)),r==="Skill"&&E?u("skill.name",E):null,r==="Skill"?u("skill.invocation","slash-command"):null),status:{code:y?2:1}}),i.pendingTool=null,X(e,i),y&&F("TOOL_ERROR",{toolName:r}),a("PostToolUse",`sid=${e}`,`tool=${r}`,`error=${y}`,`durationMs=${lt}`,`totalSpans=${I.length}`),A(t);}var Me={"claude-opus-5":{input:5,output:25},"claude-sonnet-5":{input:2,output:10},"claude-fable-5":{input:10,output:50},"claude-opus-4-6":{input:5,output:25},"claude-opus-4-5":{input:5,output:25},"claude-sonnet-4-6":{input:3,output:15},"claude-sonnet-4-5":{input:3,output:15},"claude-haiku-4-5":{input:1,output:5},"claude-4-6-opus":{input:5,output:25},"claude-4-6-sonnet":{input:3,output:15},"claude-4-5-opus":{input:5,output:25},"claude-4-5-sonnet":{input:3,output:15},"claude-4-5-haiku":{input:1,output:5},"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 xe(t,e,r){let n=Object.keys(Me).find(i=>(t??"").toLowerCase().includes(i));if(!n)return;let s=Me[n],o=(e*s.input+r*s.output)/1e6;return Math.round(o*1e6)/1e6}T();async function Be(t){let e=t.session_id||"unknown",r=t.stop_reason||"end_turn",n=J(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 s=P(),o=await de(),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 m=i.length,_=i.filter(f=>f.error).length,E=v(p?.text?L(p.text,R.TRACE_OUTPUT):m===0?"No tools used":i.map((f,b)=>`${b+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""}`).join(`
21
+ `)),w=p?.inputTokens??0,y=p?.outputTokens??0,ct=i.map((f,b)=>`${b+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""} (${f.durationMs}ms)`),z=!!(n.slashSkill||i.some(f=>f.tool==="Skill")),lt=i.some(f=>f.tool==="Agent");if(!z&&!lt){a("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),F("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),Bt(e),A(t);return}let ut=z?"skill":"agent",pt=Math.round(Number(BigInt(s)-BigInt(n.startNs))/1e6),M=p?.model||"",kt=xe(M,w,y),I=Oe(n);I==="prerequisite_required"&&p?.text&&(I="complete"),I==="prerequisite_required"&&(c.push({traceId:n.traceId,spanId:C(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:s,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(!(!z||!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}})(),x=JSON.stringify({trace_type:ut,...I!==null&&{execution_status:I},...n.slashSkill?{skill_name:n.slashSkill}:{},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...Z!==void 0&&{user_instruction:Z},latency_ms:pt,...w&&{tokens_input:w},...y&&{tokens_output:y},cost_usd:kt,...M?{model:M}:{},toolCount:m,errorCount:_,stopReason:r,sessionId:n.sessionId,tools:ct.length?ct:void 0}),Vt=v(L(n.prompt,R.TRACE_INPUT)),He=$(u(d.TRACE_NAME,n.traceName),u(d.TRACE_INPUT,Vt),u(d.TRACE_OUTPUT,E),u(d.OBS_INPUT,Vt),u(d.OBS_OUTPUT,E),u(d.TRACE_METADATA,x),u(d.SESSION_ID,n.sessionId),u(d.USER_ID,o.user),u(d.OBS_TYPE,"GENERATION"),u(d.MODEL,M),w?u(d.INPUT_TOKENS,w):null,y?u(d.OUTPUT_TOKENS,y):null,u("claude.stop_reason",r),u("claude.tool_count",String(m)),u("claude.error_count",String(_)),u("claude.session_id",n.sessionId),u("flow.trace_type",ut),{key:d.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:ut}]}}}),We={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:He,status:{code:_>0?2:1}},Ge=$(u("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),u("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),jt=[...c,We];a("Stop",`sid=${e}`,`totalTools=${m}`,`errorTools=${_}`,`spans=${jt.length}`,`inputTokens=${w}`,`outputTokens=${y}`,`traceOutput="${ht(E,80)}"`);let Ye=await Fe(we(Ge,jt));a("Stop",`POST status=${Ye}`,`traceId=${n.traceId}`),F("TRACE_SENT",{latencyMs:pt,totalTools:m,errorTools:_,inputTokens:w,outputTokens:y,costUsd:kt}),Bt(e),A(t);}var D=class{static async userPromptSubmit(){let e=await it(),r;try{r=await K();}catch{A(e);return}r.authError?await Wt(e,true):r.length>0?await Wt(e):A(e);}static async preToolUse(){let e=await it();await ke(e);}static async postToolUse(){let e=await it();await De(e);}static async stop(){let e=await it();await Be(e);}};async function pn(){let t=process.argv[2];switch(t){case "UserPromptSubmit":await D.userPromptSubmit();break;case "PreToolUse":await D.preToolUse();break;case "PostToolUse":await D.postToolUse();break;case "Stop":await D.stop();break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
22
22
  `),process.stdin.on("data",e=>process.stdout.write(e));}}pn().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
23
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'),p=require('path'),f=require('os'),mt=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 mt__default=/*#__PURE__*/_interopDefault(mt);var I=Object.defineProperty;var Pe=Object.getOwnPropertyDescriptor;var Ie=Object.getOwnPropertyNames;var Ue=Object.prototype.hasOwnProperty;var O=(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 Ne=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(r){throw t=0,r}},L=(e,t)=>{for(var r in t)I(e,r,{get:t[r],enumerable:true});},be=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Ie(t))!Ue.call(e,s)&&s!==r&&I(e,s,{get:()=>t[s],enumerable:!(n=Pe(t,s))||n.enumerable});return e};var Ce=e=>be(I({},"__esModule",{value:true}),e);var q={};L(q,{AUTH_ENGINE:()=>N,BUFFER:()=>xe,CONFIG_DIR_NAME:()=>h,CONFIG_FILE_NAME:()=>_,DEBUG_LOG_FILENAME:()=>$,ENV:()=>u,FEATURES:()=>De,FLOW_URLS:()=>$e,HOOK_TIMEOUTS:()=>C,INSTALLER:()=>b,NATIVE_OTEL:()=>U,OTLP:()=>Me,STATE_FILE_PREFIX:()=>We,TRACE_LIMITS:()=>He,VALIDATION:()=>F,VAULT:()=>E,getFlowBaseUrl:()=>R,getFlowUrls:()=>k,getMetrics:()=>Ve});function R(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Fe}function k(){let e=R();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 Ve(){let e=R();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Fe,$e,E,h,_,Me,U,u,De,N,b,C,xe,F,$,He,We,c=v(()=>{"use strict";Fe="https://flow.ciandt.com";$e=k(),E={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},h="FLOW-nodejs",_="config.json",Me={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},U={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_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"},De={KEYCHAIN_ENABLED:!1},N={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},b={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},C={UserPromptSubmit:30,PreToolUse:3,PostToolUse:10,Stop:15},xe={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]+$/},$="flow-ai-obs-debug.log",He={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};We="flow-obs-";});var Z={};L(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={};L(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",g=>{g===0?s():o(new Error(`secret-tool exited with code ${g}`));}),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={};L(ne,{WindowsKeyVaultProvider:()=>W});var W,se=v(()=>{"use strict";W=class{static async isAvailable(){try{return await O("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(t,r){return O("keytar").getPassword(t,r)}async setSecret(t,r,n){await O("keytar").setPassword(t,r,n);}async deleteSecret(t,r){return O("keytar").deletePassword(t,r)}getStoragePath(){return "Windows Credential Manager"}};});var _e=Ne(($r,dt)=>{dt.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.13.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"}};});c();c();var M={credentials:"credentials","token-cache":"tokenCache"};function T(){let e=f__namespace.default.homedir();if(process.platform==="darwin")return p__namespace.default.join(e,"Library","Preferences",h,_);if(process.platform==="win32"){let r=process.env.APPDATA??p__namespace.default.join(e,"AppData","Roaming");return p__namespace.default.join(r,h,_)}let t=process.env.XDG_CONFIG_HOME??p__namespace.default.join(e,".config");return p__namespace.default.join(t,h,_)}function D(){try{let e=i__namespace.default.readFileSync(T(),"utf8");return JSON.parse(e)}catch{return {}}}function z(e){let t=T();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 S=class{static isAvailable(){return true}static hasExistingData(){try{if(!i__namespace.default.existsSync(T()))return !1;let t=JSON.parse(i__namespace.default.readFileSync(T(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,r){let n=D(),s=M[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,r,n){let s=D(),o=M[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=M[r]??r;return s in n?(delete n[s],z(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${T()}`}};async function oe(){return process.env[u.FLOW_OBS_USE_JSON_VAULT]==="1"?new S:await Qe()??new S}async function Qe(){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 et=E.SERVICE,tt=E.ACCOUNT_CREDS;E.ACCOUNT_TOKEN;var Y=null;function rt(){return Y||(Y=oe()),Y}async function ie(){let t=await(await rt()).getSecret(et,tt);if(!t)return null;try{return JSON.parse(t)}catch{return null}}c();c();c();p.join(f.tmpdir(),$);!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 P(){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 lt=b.LOCK_STALE_MS;function de(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 me(e){try{i__namespace.unlinkSync(e);}catch{}}function ut(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 ge(e,t){let r=P(),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 g=a.env&&typeof a.env=="object"?a.env:{};delete g.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:Oe}=(c(),Ce(q)),ve=Oe().OTEL_ENDPOINT,Le={...U,OTEL_EXPORTER_OTLP_ENDPOINT:e??ve};a.env={...g,...Le,...t??{}},a.otelHeadersHelper="flow-ai-obs otel-headers",(!a.hooks||typeof a.hooks!="object"||Array.isArray(a.hooks))&&(a.hooks={});let Re=(l,A)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${l}`,timeout:A}]}),ke=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],X=a.hooks;for(let l of ke){let A=ut(X[l],Re(l,C[l]));A.length>1&&s.push(l),X[l]=A;}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=P(),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 Ee(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 J;function ye(){return J||(J=_e()),J}var Se=p__namespace.default.join(f__namespace.default.tmpdir(),"flow-obs-update-cache.json"),ht=1440*60*1e3,_t=3e3;function Tt(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 yt(){try{let e=JSON.parse(i__namespace.default.readFileSync(Se,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=ht?null:e}catch{return null}}function St(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=mt__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:_t},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 we(){try{if(yt())return;setImmediate(()=>{wt((e,t)=>{e||!t||Tt(ye().version,t.version)&&St(t.version,t.updatePriority,0);});});}catch{}}var At=p__namespace.default.resolve(__dirname,".."),Ot=process.env.INIT_CWD?p__namespace.default.resolve(process.env.INIT_CWD):null;Ot===At&&process.exit(0);G()&&(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 k=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var ke=Object.getOwnPropertyNames;var Ne=Object.prototype.hasOwnProperty;var O=(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 L=(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)k(e,r,{get:t[r],enumerable:true});},Ce=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ke(t))!Ne.call(e,s)&&s!==r&&k(e,s,{get:()=>t[s],enumerable:!(n=Ie(t,s))||n.enumerable});return e};var be=e=>Ce(k({},"__esModule",{value:true}),e);var q={};R(q,{AUTH_ENGINE:()=>U,BUFFER:()=>xe,CLAUDE_DESKTOP:()=>We,CONFIG_DIR_NAME:()=>h,CONFIG_FILE_NAME:()=>_,DEBUG_LOG_FILENAME:()=>D,ENV:()=>u,FEATURES:()=>Me,FLOW_URLS:()=>De,HOOK_TIMEOUTS:()=>b,INSTALLER:()=>C,NATIVE_OTEL:()=>N,OTLP:()=>$e,STATE_FILE_PREFIX:()=>Ye,TRACE_LIMITS:()=>He,VALIDATION:()=>F,VAULT:()=>g,getFlowBaseUrl:()=>v,getFlowUrls:()=>P,getMetrics:()=>Ve});function v(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Fe}function P(){let e=v();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 Ve(){let e=v();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Fe,De,g,h,_,$e,N,u,Me,U,C,b,xe,F,D,He,We,Ye,c=L(()=>{"use strict";Fe="https://flow.ciandt.com";De=P(),g={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},h="FLOW-nodejs",_="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_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",FLOW_OBS_SKIP_DESKTOP_DETECTION:"FLOW_OBS_SKIP_DESKTOP_DETECTION",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"},Me={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},xe={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]+$/},D="flow-ai-obs-debug.log",He={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};We={DIR_3P:"Claude-3p",CONFIG_LIBRARY_DIR:"configLibrary",DESKTOP_CONFIG_FILE:"claude_desktop_config.json",META_FILE:"_meta.json",DEPLOYMENT_MODE:"3p",CONFIG_NAME:"Flow AI Obs",WRAPPER_SCRIPT_UNIX:"otel-headers-helper.sh",WRAPPER_SCRIPT_WIN:"otel-headers-helper.cmd",OTLP_PROTOCOL:"http/json",KEYS:{OTLP_ENDPOINT:"otlpEndpoint",OTLP_PROTOCOL:"otlpProtocol",OTLP_HEADERS_HELPER:"otlpHeadersHelper"}},Ye="flow-obs-";});var Z={};R(Z,{MacOsKeyVaultProvider:()=>H});var x,H,Q=L(()=>{"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=L(()=>{"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=L(()=>{"use strict";W=class{static async isAvailable(){try{return await O("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(t,r){return O("keytar").getPassword(t,r)}async setSecret(t,r,n){await O("keytar").setPassword(t,r,n);}async deleteSecret(t,r){return O("keytar").deletePassword(t,r)}getStoragePath(){return "Windows Credential Manager"}};});var _e=Ue(($r,mt)=>{mt.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.14.0-beta.61",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'})"`,prepare:"lefthook install || echo '[WARNING] lefthook install failed - git hooks not installed'",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,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","eslint-config-prettier":"^10.1.5",jest:"^30.4.2",lefthook:"^2.1.10",prettier:"^3.5.3","ts-jest":"^29.4.9",tsup:"^8.5.1",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 T(){let e=f__namespace.default.homedir();if(process.platform==="darwin")return p__namespace.default.join(e,"Library","Preferences",h,_);if(process.platform==="win32"){let r=process.env.APPDATA??p__namespace.default.join(e,"AppData","Roaming");return p__namespace.default.join(r,h,_)}let t=process.env.XDG_CONFIG_HOME??p__namespace.default.join(e,".config");return p__namespace.default.join(t,h,_)}function M(){try{let e=i__namespace.default.readFileSync(T(),"utf8");return JSON.parse(e)}catch{return {}}}function z(e){let t=T();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 S=class{static isAvailable(){return true}static hasExistingData(){try{if(!i__namespace.default.existsSync(T()))return !1;let t=JSON.parse(i__namespace.default.readFileSync(T(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,r){let n=M(),s=$[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,r,n){let s=M(),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=M(),s=$[r]??r;return s in n?(delete n[s],z(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${T()}`}};async function oe(){return process.env[u.FLOW_OBS_USE_JSON_VAULT]==="1"?new S:await et()??new S}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=g.SERVICE,rt=g.ACCOUNT_CREDS;g.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(),D);!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 I(){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=I(),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,Re={...N,OTEL_EXPORTER_OTLP_ENDPOINT:e??Le};a.env={...E,...Re,...t??{}},a.otelHeadersHelper="flow-ai-obs otel-headers",(!a.hooks||typeof a.hooks!="object"||Array.isArray(a.hooks))&&(a.hooks={});let ve=(l,A)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${l}`,timeout:A}]}),Pe=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],X=a.hooks;for(let l of Pe){let A=ft(X[l],ve(l,b[l]));A.length>1&&s.push(l),X[l]=A;}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 B(e){let t=I(),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 J;function ye(){return J||(J=_e()),J}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 wt(e,t,r=Date.now()){try{i__namespace.default.writeFileSync(Se,JSON.stringify({latestVersion:e,updatePriority:t??null,checkedAt:r}),{mode:384});}catch{}}function At(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 we(){try{if(St())return;setImmediate(()=>{At((e,t)=>{e||!t||yt(ye().version,t.version)&&wt(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{ge();}catch{}let e=await ie();if(!e){process.stderr.write(`
8
+ `),process.exit(1));async function Rt(){try{Ee();}catch{}let e=await ie();if(!e){process.stderr.write(`
9
9
  [flow-ai-obs] No credentials found.
10
10
  Run \`flow-ai-obs login\` to authenticate and enable telemetry.
11
11
 
12
- `);return}let t=Ee(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(()=>we());
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);B({[u.ANTHROPIC_AUTH_TOKEN]:n});}catch{}}Rt().catch(()=>{}).finally(()=>we());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ciandt-flow/flow-ai-obs",
3
- "version": "0.13.0",
3
+ "version": "0.14.0-beta.61",
4
4
  "description": "Claude Code hooks for Langfuse OTLP tracing — cross-platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -16,6 +16,7 @@
16
16
  "format:check": "prettier --check \"src/**/*.ts\" \"bin/**/*.ts\" \"scripts/**/*.ts\"",
17
17
  "security-scan": "trufflehog filesystem src/ --fail --no-update --exclude-paths .trufflehogignore",
18
18
  "postinstall": "node -e \"require('fs').existsSync('dist/setup.js') && require('child_process').execFileSync(process.execPath, ['dist/setup.js'], {stdio:'inherit'})\"",
19
+ "prepare": "lefthook install || echo '[WARNING] lefthook install failed - git hooks not installed'",
19
20
  "prepublishOnly": "npm run security-scan && npm run build",
20
21
  "release:npm": "changeset publish",
21
22
  "changeset": "changeset",
@@ -47,7 +48,6 @@
47
48
  "author": "CI&T Flow Team",
48
49
  "license": "SEE LICENSE IN LICENSE.md",
49
50
  "private": false,
50
- "dependencies": {},
51
51
  "optionalDependencies": {
52
52
  "keytar": "7.9.0"
53
53
  },
@@ -56,11 +56,12 @@
56
56
  "@changesets/cli": "^2.30.0",
57
57
  "@types/jest": "^30.0.0",
58
58
  "@types/node": "^25.8.0",
59
+ "eslint-config-prettier": "^10.1.5",
59
60
  "jest": "^30.4.2",
61
+ "lefthook": "^2.1.10",
62
+ "prettier": "^3.5.3",
60
63
  "ts-jest": "^29.4.9",
61
64
  "tsup": "^8.5.1",
62
- "eslint-config-prettier": "^10.1.5",
63
- "prettier": "^3.5.3",
64
65
  "typescript": "^6.0.3",
65
66
  "typescript-eslint": "^8.33.0"
66
67
  },