@ciandt-flow/flow-ai-obs 0.14.0 → 0.15.0-beta.87

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,23 +1,23 @@
1
- 'use strict';var h=require('fs'),W=require('path'),rt=require('os'),Me=require('https'),xe=require('http'),child_process=require('child_process'),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 W__namespace=/*#__PURE__*/_interopNamespace(W);var rt__namespace=/*#__PURE__*/_interopNamespace(rt);var Me__default=/*#__PURE__*/_interopDefault(Me);var xe__default=/*#__PURE__*/_interopDefault(xe);var be=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};function B(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():Ue}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 Rt(){let t=B();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ue,Wn,pt,ft,dt,yt,g,Q,Bt,R,Y,Ht,L,S=be(()=>{"use strict";Ue="https://flow.ciandt.com";Wn=H(),pt={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},ft="FLOW-nodejs",dt="config.json",yt={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_SKIP_DESKTOP_DETECTION:"FLOW_OBS_SKIP_DESKTOP_DETECTION",FLOW_OBS_SKIP_COPILOT_DETECTION:"FLOW_OBS_SKIP_COPILOT_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},Bt={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},R={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},Y={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[\x21-\x7E]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},Ht="flow-ai-obs-debug.log",L={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};});S();var kt={credentials:"credentials","token-cache":"tokenCache"};function tt(){let t=rt__namespace.default.homedir();if(process.platform==="darwin")return W__namespace.default.join(t,"Library","Preferences",ft,dt);if(process.platform==="win32"){let n=process.env.APPDATA??W__namespace.default.join(t,"AppData","Roaming");return W__namespace.default.join(n,ft,dt)}let e=process.env.XDG_CONFIG_HOME??W__namespace.default.join(t,".config");return W__namespace.default.join(e,ft,dt)}function Lt(){try{let t=h__namespace.default.readFileSync(tt(),"utf8");return JSON.parse(t)}catch{return {}}}function Yt(t){let e=tt();h__namespace.default.mkdirSync(W__namespace.default.dirname(e),{recursive:true}),h__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var mt=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,n){let r=Lt(),s=kt[n]??n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(e,n,r){let s=Lt(),o=kt[n]??n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;Yt(s);}async deleteSecret(e,n){let r=Lt(),s=kt[n]??n;return s in r?(delete r[s],Yt(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${tt()}`}};async function Wt(){return new mt}S();var Gt=pt.SERVICE;pt.ACCOUNT_CREDS;var jt=pt.ACCOUNT_TOKEN,It=null;function Kt(){return It||(It=Wt()),It}async function wt(t){await(await Kt()).setSecret(Gt,jt,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function Pt(){let e=await(await Kt()).getSecret(Gt,jt);if(!e)return null;try{let n=JSON.parse(e);return {accessToken:n.accessToken,expiresAt:n.expiresAt,lastAuthCheckAt:n.lastAuthCheckAt}}catch{return null}}async function nt(){let t=await Pt();if(!t||!t.accessToken)return null;try{let e=t.accessToken.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email??n.preferred_username??n.upn??n.sub??null}catch{return null}}S();S();var De=W.join(rt.tmpdir(),Ht);function a(...t){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
1
+ 'use strict';var h=require('fs'),G=require('path'),rt=require('os'),Me=require('https'),xe=require('http'),child_process=require('child_process'),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 rt__namespace=/*#__PURE__*/_interopNamespace(rt);var Me__default=/*#__PURE__*/_interopDefault(Me);var xe__default=/*#__PURE__*/_interopDefault(xe);var be=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};function B(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():Ue}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 Rt(){let t=B();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ue,Wn,pt,ft,dt,yt,g,Q,Bt,R,Y,Ht,L,S=be(()=>{"use strict";Ue="https://flow.ciandt.com";Wn=H(),pt={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},ft="FLOW-nodejs",dt="config.json",yt={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_SKIP_DESKTOP_DETECTION:"FLOW_OBS_SKIP_DESKTOP_DETECTION",FLOW_OBS_SKIP_COPILOT_DETECTION:"FLOW_OBS_SKIP_COPILOT_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},Bt={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},R={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},Y={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[A-Za-z0-9_.\-:=+/]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},Ht="flow-ai-obs-debug.log",L={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};});S();var kt={credentials:"credentials","token-cache":"tokenCache"};function tt(){let t=rt__namespace.default.homedir();if(process.platform==="darwin")return G__namespace.default.join(t,"Library","Preferences",ft,dt);if(process.platform==="win32"){let n=process.env.APPDATA??G__namespace.default.join(t,"AppData","Roaming");return G__namespace.default.join(n,ft,dt)}let e=process.env.XDG_CONFIG_HOME??G__namespace.default.join(t,".config");return G__namespace.default.join(e,ft,dt)}function Lt(){try{let t=h__namespace.default.readFileSync(tt(),"utf8");return JSON.parse(t)}catch{return {}}}function Yt(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 mt=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,n){let r=Lt(),s=kt[n]??n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(e,n,r){let s=Lt(),o=kt[n]??n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;Yt(s);}async deleteSecret(e,n){let r=Lt(),s=kt[n]??n;return s in r?(delete r[s],Yt(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${tt()}`}};async function Gt(){return new mt}S();var Wt=pt.SERVICE;pt.ACCOUNT_CREDS;var jt=pt.ACCOUNT_TOKEN,It=null;function Kt(){return It||(It=Gt()),It}async function wt(t){await(await Kt()).setSecret(Wt,jt,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function Pt(){let e=await(await Kt()).getSecret(Wt,jt);if(!e)return null;try{let n=JSON.parse(e);return {accessToken:n.accessToken,expiresAt:n.expiresAt,lastAuthCheckAt:n.lastAuthCheckAt}}catch{return null}}async function nt(){let t=await Pt();if(!t||!t.accessToken)return null;try{let e=t.accessToken.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email??n.preferred_username??n.upn??n.sub??null}catch{return null}}S();S();var De=G.join(rt.tmpdir(),Ht);function a(...t){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
2
2
  `;try{h.writeFileSync(De,e,{flag:"a"});}catch(n){process.stderr.write(`[flow-obs debug ERROR] ${n.message}
3
- `);}}var v=class extends Error{statusCode;constructor(e,n=0){super(e),this.name="AuthError",this.statusCode=n;}},Be=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function He(t){if(!Be.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var Vt={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 Ye(t,e){let n=e.length>400?e.slice(0,400)+"\u2026":e;a("toAuthError",`status=${t} body=${n}`);try{let r=JSON.parse(e);if(typeof r.error=="string"&&(a("toAuthError",`api_error_code=${r.error}`+(r.message?` api_message=${r.message}`:"")),Vt[r.error]))return new v(Vt[r.error],t)}catch{}return t===401||t===403||t===500?new v("Invalid credentials",t):t>=400&&t<500?new v("Authentication request was rejected",t):new Error("Authentication service unavailable, please try again later")}function G(t){return new Promise((e,n)=>{try{He(t.tenant);}catch(p){return n(p)}let r=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(r),FlowTenant:t.tenant}};a("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let l=(o?Me__default.default:xe__default.default).request(i,p=>{let T=[];p.on("data",m=>T.push(m)),p.on("end",()=>{let m=T.join("");if((p.statusCode??0)>=400)return n(Ye(p.statusCode??0,m));let _;try{_=JSON.parse(m);}catch{return n(new Error("Invalid response from auth engine"))}let E=_.expires_at??new Date(Date.now()+(_.expires_in??3600)*1e3).toISOString();if(!_.access_token)return n(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=>n(new Error(`Network error: ${p.message}`))),l.setTimeout(Q.REQUEST_TIMEOUT_MS,()=>{l.destroy(new Error("Request timeout"));}),l.write(r),l.end();})}S();S();!process.env.NO_COLOR&&process.stdout.isTTY;function gt(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.USERPROFILE;if(!t){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(t=n);}if(t){let e=t.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return W__namespace.join(e,".claude","settings.json")}return W__namespace.join(rt__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||rt__namespace.homedir();return W__namespace.join(t,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return W__namespace.join(e,".claude","settings.json")}return W__namespace.join(rt__namespace.homedir(),".claude","settings.json")}var Ke=Bt.LOCK_STALE_MS;function Ve(t){try{let e=h__namespace.statSync(t);Date.now()-e.mtimeMs>Ke&&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 Je(t){try{h__namespace.unlinkSync(t);}catch{}}var st;function zt(t){if(st===void 0)try{let n=h__namespace.readFileSync(gt(),"utf8");st=JSON.parse(n).env??null;}catch{st=null;}if(!st)return null;let e=st[t];return typeof e=="string"?e:null}function qt(t){let e=gt(),n=e+".lock";h__namespace.mkdirSync(W__namespace.dirname(e),{recursive:true}),Ve(n);try{let r={};try{r=JSON.parse(h__namespace.readFileSync(e,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,t),h__namespace.writeFileSync(e,JSON.stringify(r,null,2)+`
3
+ `);}}var v=class extends Error{statusCode;constructor(e,n=0){super(e),this.name="AuthError",this.statusCode=n;}},Be=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function He(t){if(!Be.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var Vt={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 Ye(t,e){let n=e.length>400?e.slice(0,400)+"\u2026":e;a("toAuthError",`status=${t} body=${n}`);try{let r=JSON.parse(e);if(typeof r.error=="string"&&(a("toAuthError",`api_error_code=${r.error}`+(r.message?` api_message=${r.message}`:"")),Vt[r.error]))return new v(Vt[r.error],t)}catch{}return t===401||t===403||t===500?new v("Invalid credentials",t):t>=400&&t<500?new v("Authentication request was rejected",t):new Error("Authentication service unavailable, please try again later")}function W(t){return new Promise((e,n)=>{try{He(t.tenant);}catch(p){return n(p)}let r=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(r),FlowTenant:t.tenant}};a("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let l=(o?Me__default.default:xe__default.default).request(i,p=>{let T=[];p.on("data",m=>T.push(m)),p.on("end",()=>{let m=T.join("");if((p.statusCode??0)>=400)return n(Ye(p.statusCode??0,m));let _;try{_=JSON.parse(m);}catch{return n(new Error("Invalid response from auth engine"))}let E=_.expires_at??new Date(Date.now()+(_.expires_in??3600)*1e3).toISOString();if(!_.access_token)return n(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=>n(new Error(`Network error: ${p.message}`))),l.setTimeout(Q.REQUEST_TIMEOUT_MS,()=>{l.destroy(new Error("Request timeout"));}),l.write(r),l.end();})}S();S();!process.env.NO_COLOR&&process.stdout.isTTY;function gt(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.USERPROFILE;if(!t){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(t=n);}if(t){let e=t.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return G__namespace.join(e,".claude","settings.json")}return G__namespace.join(rt__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||rt__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(rt__namespace.homedir(),".claude","settings.json")}var Ke=Bt.LOCK_STALE_MS;function Ve(t){try{let e=h__namespace.statSync(t);Date.now()-e.mtimeMs>Ke&&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 Je(t){try{h__namespace.unlinkSync(t);}catch{}}var st;function zt(t){if(st===void 0)try{let n=h__namespace.readFileSync(gt(),"utf8");st=JSON.parse(n).env??null;}catch{st=null;}if(!st)return null;let e=st[t];return typeof e=="string"?e:null}function qt(t){let e=gt(),n=e+".lock";h__namespace.mkdirSync(G__namespace.dirname(e),{recursive:true}),Ve(n);try{let r={};try{r=JSON.parse(h__namespace.readFileSync(e,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,t),h__namespace.writeFileSync(e,JSON.stringify(r,null,2)+`
4
4
  `,{encoding:"utf8",mode:384});try{h__namespace.chmodSync(e,384);}catch{}}finally{Je(n);}}S();function Zt(){return !!process.env[g.FLOW_USER_EMAIL]||!!zt(g.FLOW_USER_EMAIL)}function Nt(t){a("maybePersistUserEmail",`${t}: starting`);let e=t==="api-key"?`\u26A0\uFE0F flow-ai-obs: FLOW_USER_EMAIL is not set. Configure it with:
5
5
  flow-ai-obs init --custom-email <EMAIL>
6
6
  `:`\u26A0\uFE0F flow-ai-obs: FLOW_USER_EMAIL is not set and could not be derived from token.
7
7
  Run: flow-ai-obs init
8
8
  `;return nt().then(n=>{if(n){let r=n.split(/[\r\n]/)[0].replace(/[\x00-\x1F\x7F]/g,"").trim();if(!r)return;let s=r.indexOf("@"),o=r.slice(s+1);if(!(r.length<=254&&Y.EMAIL_HEADER_PATTERN.test(r)&&(r.match(/@/g)??[]).length===1&&s>0&&s<r.length-1&&o.includes("."))){a("maybePersistUserEmail",`${t}: email from token failed basic validation \u2014 skipping persist`);return}try{qt({[g.FLOW_USER_EMAIL]:r}),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
- `);}}else process.stderr.write(e);}).catch(n=>{a("maybePersistUserEmail",`${t}: getEmailFromToken failed: ${n.message}`);})}var Xe=[/^localhost\.?$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/,/^::1$/,/^\[::1\]$/,/^\[::ffff:/i,/^\[f[cd]/i,/^\[fe80:/i,/^metadata\.google\.internal\.?$/i,/^metadata\.azure\.internal\.?$/i,/(?:^|\.)localtest\.me\.?$/i,/(?:^|\.)lvh\.me\.?$/i,/(?:^|\.)vcap\.me\.?$/i];function ze(t){return Xe.some(e=>e.test(t))}function qe(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}function _t(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:o}=n;return !r||!s||!o?null:{clientId:r,clientSecret:s,tenant:o}}catch{return null}}function Et(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let n=process.env[g.FLOW_OBS_ALLOW_HTTP]==="true";if(!n&&e.protocol!=="https:")throw new Error(`URL must use HTTPS: ${t}`);if(e.username||e.password)throw new Error(`URL must not contain embedded credentials: ${t}`);if(!n&&ze(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function Qt(){let t=_t(process.env[g.ANTHROPIC_AUTH_TOKEN]);return t?{user:await nt().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function Ze(){let t=process.env[g.FLOW_API_KEY];if(!t)return null;let e=t.replace(/[\r\n]/g,"").trim();return e?e.length>Y.API_KEY_MAX_LENGTH?(a("resolveApiKey",`FLOW_API_KEY exceeds ${Y.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):Y.API_KEY_PATTERN.test(e)?e:(a("resolveApiKey","FLOW_API_KEY contains non-printable or control characters \u2014 rejected"),null):null}function Qe(){return new Date().toISOString().slice(0,10)}async function tn(t){let e=Qe(),n=await Pt();if(n?.lastAuthCheckAt!==e){a("getOrRefreshToken",`daily auth check (last: ${n?.lastAuthCheckAt??"never"})`);let o=Q.MAX_RETRY_ATTEMPTS;for(let i=1;i<=o;i++)try{let c=await G(t);try{await wt({...c,lastAuthCheckAt:e});}catch(p){a("getOrRefreshToken",`saveTokenCache failed (non-fatal): ${p.message}`);}return a("getOrRefreshToken",`daily check passed (attempt ${i}), expires=${c.expiresAt}`),Ze()?Zt()||await Nt("api-key"):await Nt("oauth"),c.accessToken}catch(c){if(c instanceof v){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 r=n!=null&&new Date(n.expiresAt)>new Date;if(a("getOrRefreshToken",`cacheValid=${r}`),r)return a("getOrRefreshToken",`using cached token, expires=${n.expiresAt}`),n.accessToken;a("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let s=await G(t);try{await wt({...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 en(t,e){let n=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${n}`}}function nn(t,e,n){let r=Buffer.from(`${e}:${n}`).toString("base64");return {endpoint:t.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${r}`}}async function V(){let t=[],e=_t(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 n=e?e.tenant:"",r=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(r&&s&&o&&i){let m="",_=n;e&&(m=await nt().catch(()=>null)??e.clientId);let E={user:m??"",tenant:_??"",team:"",project:""};t.push({mode:"direct",...nn(Et(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 tn(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:qe(c)??e.clientId,tenant:n,team:"",project:""},T=process.env[g.FLOW_TELEMETRY_GATEWAY]??B();return t.push({mode:"gateway",...en(Et(T),{accessToken:c}),...p}),t}function I(t,e){let n=typeof t=="object"?JSON.stringify(t):String(t??"");return n.length>e?n.slice(0,e)+" \u2026[truncated]":n}function Tt(t,e=100){return String(t??"").split(`
11
- `)[0].slice(0,e).trim()}function ot(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n;}),process.stdin.on("end",()=>{try{t(JSON.parse(e));}catch{t({});}});})}function O(t){process.stdout.write(JSON.stringify(t));}var bt=()=>crypto.randomBytes(16).toString("hex"),C=()=>crypto.randomBytes(8).toString("hex");function P(){return String(BigInt(Date.now())*1000000n)}var fn=/^[0-9a-f-]{1,64}$/i,dn=W.normalize(rt.tmpdir())+W.sep;function mn(t,e){let n=W.resolve(t);if(!n.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return n}function Ut(t){if(!fn.test(t))throw new Error(`Invalid session ID: ${t}`);return mn(W.join(rt.tmpdir(),`flow-obs-${t}.json`),dn)}function J(t){let e;try{e=Ut(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(Ut(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function vt(t){try{h.unlinkSync(Ut(t));}catch{}}function se(t){if(!t||!h.existsSync(t))return null;try{let e=h.readFileSync(t,"utf8").trimEnd().split(`
10
+ `);}}else process.stderr.write(e);}).catch(n=>{a("maybePersistUserEmail",`${t}: getEmailFromToken failed: ${n.message}`);})}var Xe=[/^localhost\.?$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/,/^::1$/,/^\[::1\]$/,/^\[::ffff:/i,/^\[f[cd]/i,/^\[fe80:/i,/^metadata\.google\.internal\.?$/i,/^metadata\.azure\.internal\.?$/i,/(?:^|\.)localtest\.me\.?$/i,/(?:^|\.)lvh\.me\.?$/i,/(?:^|\.)vcap\.me\.?$/i];function ze(t){return Xe.some(e=>e.test(t))}function qe(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}function _t(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:o}=n;return !r||!s||!o?null:{clientId:r,clientSecret:s,tenant:o}}catch{return null}}function Et(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let n=process.env[g.FLOW_OBS_ALLOW_HTTP]==="true";if(!n&&e.protocol!=="https:")throw new Error(`URL must use HTTPS: ${t}`);if(e.username||e.password)throw new Error(`URL must not contain embedded credentials: ${t}`);if(!n&&ze(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function Qt(){let t=_t(process.env[g.ANTHROPIC_AUTH_TOKEN]);return t?{user:await nt().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function Ze(t){if(!t)return null;let e=t.replace(/[\r\n]/g,"").trim();return e?e.length>Y.API_KEY_MAX_LENGTH?(a("validateApiKey",`API key exceeds ${Y.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):Y.API_KEY_PATTERN.test(e)?e:(a("validateApiKey","API key contains invalid or unsafe characters \u2014 rejected"),null):null}function Qe(){let t=process.env[g.FLOW_API_KEY];return Ze(t)}function tn(){return new Date().toISOString().slice(0,10)}async function en(t){let e=tn(),n=await Pt();if(n?.lastAuthCheckAt!==e){a("getOrRefreshToken",`daily auth check (last: ${n?.lastAuthCheckAt??"never"})`);let o=Q.MAX_RETRY_ATTEMPTS;for(let i=1;i<=o;i++)try{let c=await W(t);try{await wt({...c,lastAuthCheckAt:e});}catch(p){a("getOrRefreshToken",`saveTokenCache failed (non-fatal): ${p.message}`);}return a("getOrRefreshToken",`daily check passed (attempt ${i}), expires=${c.expiresAt}`),Qe()?Zt()||await Nt("api-key"):await Nt("oauth"),c.accessToken}catch(c){if(c instanceof v){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 r=n!=null&&new Date(n.expiresAt)>new Date;if(a("getOrRefreshToken",`cacheValid=${r}`),r)return a("getOrRefreshToken",`using cached token, expires=${n.expiresAt}`),n.accessToken;a("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let s=await W(t);try{await wt({...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 nn(t,e){let n=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${n}`}}function rn(t,e,n){let r=Buffer.from(`${e}:${n}`).toString("base64");return {endpoint:t.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${r}`}}async function V(){let t=[],e=_t(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 n=e?e.tenant:"",r=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(r&&s&&o&&i){let m="",_=n;e&&(m=await nt().catch(()=>null)??e.clientId);let E={user:m??"",tenant:_??"",team:"",project:""};t.push({mode:"direct",...rn(Et(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 en(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:qe(c)??e.clientId,tenant:n,team:"",project:""},T=process.env[g.FLOW_TELEMETRY_GATEWAY]??B();return t.push({mode:"gateway",...nn(Et(T),{accessToken:c}),...p}),t}function I(t,e){let n=typeof t=="object"?JSON.stringify(t):String(t??"");return n.length>e?n.slice(0,e)+" \u2026[truncated]":n}function Tt(t,e=100){return String(t??"").split(`
11
+ `)[0].slice(0,e).trim()}function ot(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n;}),process.stdin.on("end",()=>{try{t(JSON.parse(e));}catch{t({});}});})}function O(t){process.stdout.write(JSON.stringify(t));}var bt=()=>crypto.randomBytes(16).toString("hex"),C=()=>crypto.randomBytes(8).toString("hex");function P(){return String(BigInt(Date.now())*1000000n)}var dn=/^[0-9a-f-]{1,64}$/i,mn=G.normalize(rt.tmpdir())+G.sep;function gn(t,e){let n=G.resolve(t);if(!n.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return n}function Ut(t){if(!dn.test(t))throw new Error(`Invalid session ID: ${t}`);return gn(G.join(rt.tmpdir(),`flow-obs-${t}.json`),mn)}function J(t){let e;try{e=Ut(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(Ut(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function vt(t){try{h.unlinkSync(Ut(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 n=e.length-1;n>=0;n--)try{let r=JSON.parse(e[n]);if(r.type==="user"&&r.uuid)return r.uuid}catch{}}catch{}return null}function Ct(t){if(!t||!h.existsSync(t))return null;try{let e=h.readFileSync(t,"utf8").trimEnd().split(`
13
13
  `),n=[],r=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&&n.unshift(p);let T=c.message?.usage??{};r+=(T.input_tokens??0)+(T.cache_read_input_tokens??0)+(T.cache_creation_input_tokens??0),s+=T.output_tokens??0;}}catch{}return !n.length&&r===0?null:{text:n.join(`
14
14
 
15
- `),inputTokens:r,outputTokens:s,model:o}}catch{}return null}var Tn=new Set([".venv","__pycache__",".git","node_modules"]),Sn=new Set([".pyc",".pyo"]),hn=new Set(["SKILL.md",".DS_Store",".gitignore"]);function ae(t){return t.replace(":","/")}function St(t,e){if(!t)return null;let n=ae(t),r=[W.join(rt.homedir(),".claude","skills",n,"SKILL.md"),W.join(e??"",".claude","skills",n,"SKILL.md")];for(let s of r)if(h.existsSync(s))try{return h.readFileSync(s,"utf8")}catch{}return null}function ce(t){return t.split(`
16
- `)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var An=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function le(t){return !!t.slashSkill||t.toolCalls.some(r=>r.tool==="Skill")?t.toolCalls.some(r=>r.tool==="Skill"&&!r.synthetic||An.has(r.tool))?"complete":"prerequisite_required":null}function ht(t,e){if(!t)return null;let n=ae(t),r=[W.join(rt.homedir(),".claude","skills",n),W.join(e??"",".claude","skills",n)],s=null;for(let c of r)if(h.existsSync(W.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(Tn.has(p.name)||hn.has(p.name)||Sn.has(W.extname(p.name)))continue;let T=l?`${l}/${p.name}`:p.name;p.isDirectory()?i(W.join(c,p.name),T):o.push(T);}}return i(s,""),o.length>0?o:null}S();S();function Rn(t){try{let e=t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(e,"base64").toString())}catch{return null}}function kn(t,e,n,r){return new Promise(s=>{let o=new URL(t),i=o.protocol==="https:",c=(i?Me__default.default:xe__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(n).replace(/[\r\n]/g,"")}`,FlowTenant:String(r).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 n=_t(process.env[g.ANTHROPIC_AUTH_TOKEN]);if(!n)return;let r,s=new Promise((m,_)=>{r=setTimeout(()=>_(new Error("getToken timeout")),4e3),r.unref();}),{accessToken:o}=await Promise.race([G(n),s]);clearTimeout(r);let i=Rn(o);if(!i)return;let c=i.tenant||n.tenant,l=JSON.stringify({action:t,booster:Rt().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=Et(Rt().API_URL),T=await kn(p,l,o,c);a("metrics.logEvent",`action=${t} status=${T}`);}catch(n){a("metrics.logEvent",`silenced error: ${n.message}`);}}var Ln=`\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 Ft(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:Ln})+`
17
- `);return}let r=!!(await V()).authError,s=t.session_id||"unknown",o=t.prompt||"",i=t.cwd||"",c=se(t.transcript_path)||bt(),l=ce(o),p=l?St(l,i):null,T=l?ht(l,i):null;X(s,{traceId:bt(),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:T}),F("SESSION_STARTED",{traceType:l?"skill":"prompt",slashSkill:l,clientIdExpired:r}),a("UserPromptSubmit",`sid=${s}`,`traceName=${c}`,`slashSkill=${l}`),O(t);}S();async function ue(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},s=J(e);s&&(s.pendingTool={name:n,inputStr:I(r,L.TOOL_INPUT),startNs:P()},X(e,s)),a("PreToolUse",`sid=${e}`,`tool=${n}`,`stateFound=${!!s}`),O(t);}S();var In={name:yt.SCOPE_NAME,version:yt.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 pe(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:In,spans:Array.isArray(e)?e:[e]}]}]}}S();var fe=W.join(rt.tmpdir(),"flow-obs-requests.ndjson");function de(t,e,n,r,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(n)},response:{status:r,body:s}});try{h.writeFileSync(fe,o+`
18
- `,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${fe}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function vn(t){let e=new URL(t),n=new URL(H().GATEWAY_HEALTH);return n.hostname=e.hostname,n.port=e.port,n.protocol=e.protocol,n}function me(t,e){return new Promise((n,r)=>{let s=t._isSSL?Me__default.default:xe__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",()=>n({statusCode:i.statusCode??0,body:c.join("")}));});o.setTimeout(1e4,()=>{o.destroy(new Error("Request timeout"));}),o.on("error",i=>r(new Error(`Network error: ${i.message}`))),e&&o.write(e),o.end();})}async function ge(t,e){let n;try{n=vn(t);}catch{return false}let r=n.protocol==="https:";try{let s={};e&&(s.Authorization=String(e).replace(/[\r\n]/g,""));let o=await me({hostname:n.hostname,port:n.port||(r?443:80),path:n.pathname,method:"GET",headers:s,_isSSL:r},null);return a("checkHealth",`url=${n.href} status=${o.statusCode}`),o.statusCode>=200&&o.statusCode<300}catch{return false}}async function At(t,e,n){let r=JSON.stringify(t),s=new URL(e),o=s.protocol==="https:",i=String(n).replace(/[\r\n]/g,""),c={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(r)};a("sendTraces:request",`POST ${e}`),a("sendTraces:request",`headers=${JSON.stringify({...c,Authorization:i.slice(0,20)+"\u2026"})}`),a("sendTraces:request",`body=${r.slice(0,500)}${r.length>500?"\u2026":""}`);try{let l=await me({hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:c,_isSSL:o},r);return a("sendTraces:response",`status=${l.statusCode}`),de(e,c,r,l.statusCode,l.body),l.statusCode}catch(l){return a("sendTraces:error",l.message),de(e,c,r,0,l.message),0}}S();function Cn(){let t=parseInt(process.env[g.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(R.MIN_TTL_DAYS,Math.min(R.MAX_TTL_DAYS,t)):R.DEFAULT_TTL_DAYS)*24*60*60*1e3}function Fn(){let t=parseInt(process.env[g.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(R.MIN_MAX_FILES,Math.min(R.MAX_MAX_FILES,t)):R.DEFAULT_MAX_FILES}function _e(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return W__namespace.default.join(rt__namespace.default.tmpdir(),`${R.FILE_PREFIX}${t}.json`)}function Dt(){let t=rt__namespace.default.tmpdir(),e;try{e=h__namespace.default.readdirSync(t);}catch{return []}return e.filter(n=>n.startsWith(R.FILE_PREFIX)&&n.endsWith(".json")).map(n=>{let r=W__namespace.default.join(t,n),s=0;try{s=h__namespace.default.statSync(r).mtimeMs;}catch{}return {full:r,mtime:s}}).sort((n,r)=>n.mtime-r.mtime).map(n=>n.full)}function it(t){try{let e=Fn(),n=Dt();if(n.length>=e){let o=n.slice(0,n.length-e+1);for(let i of o)try{h__namespace.default.unlinkSync(i);}catch{}}let r=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:r,bufferedAt:Date.now(),payload:t};return h__namespace.default.writeFileSync(_e(r),JSON.stringify(s),{encoding:"utf8",mode:384}),a("buffer",`saved fileId=${r}`),r}catch(e){return a("buffer",`saveToBuffer failed: ${e.message}`),null}}function Te(t){let e=Dt(),n=t!=null&&t>0?t:e.length,r=[];for(let s of e){if(r.length>=n)break;try{let o=h__namespace.default.readFileSync(s,"utf8"),i=JSON.parse(o);i&&i.fileId&&i.payload&&r.push(i);}catch{a("buffer",`skipping malformed file: ${s}`);}}return r}function Se(t){try{h__namespace.default.unlinkSync(_e(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function he(){let t=Date.now()-Cn();for(let e of Dt())try{let{mtimeMs:n}=h__namespace.default.statSync(e);n<t&&(h__namespace.default.unlinkSync(e),a("buffer",`evicted stale: ${W__namespace.default.basename(e)}`));}catch{}}S();async function $n(t){he();let e=Te(R.REPLAY_BATCH_SIZE);e.length&&(a("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async n=>{try{let r=await At(n.payload,t.endpoint,t.authHeader);r>=200&&r<300?(Se(n.fileId),a("replayBufferedTraces",`replayed fileId=${n.fileId} status=${r}`)):a("replayBufferedTraces",`replay failed fileId=${n.fileId} status=${r}`);}catch(r){a("replayBufferedTraces",`replay error fileId=${n.fileId}: ${r.message}`);}})));}async function Ae(t){let e=await V();if(!e.length)return e.authError&&(a("postToLangfuse","auth refresh failed \u2014 buffering trace"),it(t)),0;let n=await Promise.all(e.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await ge(o.endpoint,o.authHeader);return {creds:o,healthy:i}})),r=n.find(o=>o.creds.mode==="gateway"&&o.healthy)?.creds??n.find(o=>o.creds.mode==="direct")?.creds;return r&&await $n(r),(await Promise.all(n.map(async({creds:o,healthy:i})=>{if(o.mode==="gateway"){if(!i)return a("postToLangfuse","gateway health check failed \u2014 buffering trace"),it(t),0;let l=await At(t,o.endpoint,o.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`gateway send failed (status ${l}) \u2014 buffering trace`),it(t)),l}let c=await At(t,o.endpoint,o.authHeader);return (c===0||c>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${c}) \u2014 buffering trace`),it(t)),c}))).find(o=>o!==0)??0}S();var y="[REDACTED]",Dn="[REDACTED-EMAIL]",Mn="[REDACTED-CPF]",xn="[REDACTED-CNPJ]",Oe="[REDACTED-PHONE]",Bn=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${y}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${y}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,n)=>`${e}
15
+ `),inputTokens:r,outputTokens:s,model:o}}catch{}return null}var Sn=new Set([".venv","__pycache__",".git","node_modules"]),hn=new Set([".pyc",".pyo"]),An=new Set(["SKILL.md",".DS_Store",".gitignore"]);function ae(t){return t.replace(":","/")}function St(t,e){if(!t)return null;let n=ae(t),r=[G.join(rt.homedir(),".claude","skills",n,"SKILL.md"),G.join(e??"",".claude","skills",n,"SKILL.md")];for(let s of r)if(h.existsSync(s))try{return h.readFileSync(s,"utf8")}catch{}return null}function ce(t){return t.split(`
16
+ `)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var On=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function le(t){return !!t.slashSkill||t.toolCalls.some(r=>r.tool==="Skill")?t.toolCalls.some(r=>r.tool==="Skill"&&!r.synthetic||On.has(r.tool))?"complete":"prerequisite_required":null}function ht(t,e){if(!t)return null;let n=ae(t),r=[G.join(rt.homedir(),".claude","skills",n),G.join(e??"",".claude","skills",n)],s=null;for(let c of r)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(Sn.has(p.name)||An.has(p.name)||hn.has(G.extname(p.name)))continue;let T=l?`${l}/${p.name}`:p.name;p.isDirectory()?i(G.join(c,p.name),T):o.push(T);}}return i(s,""),o.length>0?o:null}S();S();function kn(t){try{let e=t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(e,"base64").toString())}catch{return null}}function Ln(t,e,n,r){return new Promise(s=>{let o=new URL(t),i=o.protocol==="https:",c=(i?Me__default.default:xe__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(n).replace(/[\r\n]/g,"")}`,FlowTenant:String(r).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 n=_t(process.env[g.ANTHROPIC_AUTH_TOKEN]);if(!n)return;let r,s=new Promise((m,_)=>{r=setTimeout(()=>_(new Error("getToken timeout")),4e3),r.unref();}),{accessToken:o}=await Promise.race([W(n),s]);clearTimeout(r);let i=kn(o);if(!i)return;let c=i.tenant||n.tenant,l=JSON.stringify({action:t,booster:Rt().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=Et(Rt().API_URL),T=await Ln(p,l,o,c);a("metrics.logEvent",`action=${t} status=${T}`);}catch(n){a("metrics.logEvent",`silenced error: ${n.message}`);}}var In=`\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 Ft(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:In})+`
17
+ `);return}let r=!!(await V()).authError,s=t.session_id||"unknown",o=t.prompt||"",i=t.cwd||"",c=se(t.transcript_path)||bt(),l=ce(o),p=l?St(l,i):null,T=l?ht(l,i):null;X(s,{traceId:bt(),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:T}),F("SESSION_STARTED",{traceType:l?"skill":"prompt",slashSkill:l,clientIdExpired:r}),a("UserPromptSubmit",`sid=${s}`,`traceName=${c}`,`slashSkill=${l}`),O(t);}S();async function ue(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},s=J(e);s&&(s.pendingTool={name:n,inputStr:I(r,L.TOOL_INPUT),startNs:P()},X(e,s)),a("PreToolUse",`sid=${e}`,`tool=${n}`,`stateFound=${!!s}`),O(t);}S();var wn={name:yt.SCOPE_NAME,version:yt.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 pe(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:wn,spans:Array.isArray(e)?e:[e]}]}]}}S();var fe=G.join(rt.tmpdir(),"flow-obs-requests.ndjson");function de(t,e,n,r,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(n)},response:{status:r,body:s}});try{h.writeFileSync(fe,o+`
18
+ `,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${fe}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Cn(t){let e=new URL(t),n=new URL(H().GATEWAY_HEALTH);return n.hostname=e.hostname,n.port=e.port,n.protocol=e.protocol,n}function me(t,e){return new Promise((n,r)=>{let s=t._isSSL?Me__default.default:xe__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",()=>n({statusCode:i.statusCode??0,body:c.join("")}));});o.setTimeout(1e4,()=>{o.destroy(new Error("Request timeout"));}),o.on("error",i=>r(new Error(`Network error: ${i.message}`))),e&&o.write(e),o.end();})}async function ge(t,e){let n;try{n=Cn(t);}catch{return false}let r=n.protocol==="https:";try{let s={};e&&(s.Authorization=String(e).replace(/[\r\n]/g,""));let o=await me({hostname:n.hostname,port:n.port||(r?443:80),path:n.pathname,method:"GET",headers:s,_isSSL:r},null);return a("checkHealth",`url=${n.href} status=${o.statusCode}`),o.statusCode>=200&&o.statusCode<300}catch{return false}}async function At(t,e,n){let r=JSON.stringify(t),s=new URL(e),o=s.protocol==="https:",i=String(n).replace(/[\r\n]/g,""),c={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(r)};a("sendTraces:request",`POST ${e}`),a("sendTraces:request",`headers=${JSON.stringify({...c,Authorization:i.slice(0,20)+"\u2026"})}`),a("sendTraces:request",`body=${r.slice(0,500)}${r.length>500?"\u2026":""}`);try{let l=await me({hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:c,_isSSL:o},r);return a("sendTraces:response",`status=${l.statusCode}`),de(e,c,r,l.statusCode,l.body),l.statusCode}catch(l){return a("sendTraces:error",l.message),de(e,c,r,0,l.message),0}}S();function Fn(){let t=parseInt(process.env[g.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(R.MIN_TTL_DAYS,Math.min(R.MAX_TTL_DAYS,t)):R.DEFAULT_TTL_DAYS)*24*60*60*1e3}function $n(){let t=parseInt(process.env[g.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(R.MIN_MAX_FILES,Math.min(R.MAX_MAX_FILES,t)):R.DEFAULT_MAX_FILES}function _e(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return G__namespace.default.join(rt__namespace.default.tmpdir(),`${R.FILE_PREFIX}${t}.json`)}function Dt(){let t=rt__namespace.default.tmpdir(),e;try{e=h__namespace.default.readdirSync(t);}catch{return []}return e.filter(n=>n.startsWith(R.FILE_PREFIX)&&n.endsWith(".json")).map(n=>{let r=G__namespace.default.join(t,n),s=0;try{s=h__namespace.default.statSync(r).mtimeMs;}catch{}return {full:r,mtime:s}}).sort((n,r)=>n.mtime-r.mtime).map(n=>n.full)}function it(t){try{let e=$n(),n=Dt();if(n.length>=e){let o=n.slice(0,n.length-e+1);for(let i of o)try{h__namespace.default.unlinkSync(i);}catch{}}let r=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:r,bufferedAt:Date.now(),payload:t};return h__namespace.default.writeFileSync(_e(r),JSON.stringify(s),{encoding:"utf8",mode:384}),a("buffer",`saved fileId=${r}`),r}catch(e){return a("buffer",`saveToBuffer failed: ${e.message}`),null}}function Te(t){let e=Dt(),n=t!=null&&t>0?t:e.length,r=[];for(let s of e){if(r.length>=n)break;try{let o=h__namespace.default.readFileSync(s,"utf8"),i=JSON.parse(o);i&&i.fileId&&i.payload&&r.push(i);}catch{a("buffer",`skipping malformed file: ${s}`);}}return r}function Se(t){try{h__namespace.default.unlinkSync(_e(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function he(){let t=Date.now()-Fn();for(let e of Dt())try{let{mtimeMs:n}=h__namespace.default.statSync(e);n<t&&(h__namespace.default.unlinkSync(e),a("buffer",`evicted stale: ${G__namespace.default.basename(e)}`));}catch{}}S();async function Dn(t){he();let e=Te(R.REPLAY_BATCH_SIZE);e.length&&(a("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async n=>{try{let r=await At(n.payload,t.endpoint,t.authHeader);r>=200&&r<300?(Se(n.fileId),a("replayBufferedTraces",`replayed fileId=${n.fileId} status=${r}`)):a("replayBufferedTraces",`replay failed fileId=${n.fileId} status=${r}`);}catch(r){a("replayBufferedTraces",`replay error fileId=${n.fileId}: ${r.message}`);}})));}async function Ae(t){let e=await V();if(!e.length)return e.authError&&(a("postToLangfuse","auth refresh failed \u2014 buffering trace"),it(t)),0;let n=await Promise.all(e.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await ge(o.endpoint,o.authHeader);return {creds:o,healthy:i}})),r=n.find(o=>o.creds.mode==="gateway"&&o.healthy)?.creds??n.find(o=>o.creds.mode==="direct")?.creds;return r&&await Dn(r),(await Promise.all(n.map(async({creds:o,healthy:i})=>{if(o.mode==="gateway"){if(!i)return a("postToLangfuse","gateway health check failed \u2014 buffering trace"),it(t),0;let l=await At(t,o.endpoint,o.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`gateway send failed (status ${l}) \u2014 buffering trace`),it(t)),l}let c=await At(t,o.endpoint,o.authHeader);return (c===0||c>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${c}) \u2014 buffering trace`),it(t)),c}))).find(o=>o!==0)??0}S();var y="[REDACTED]",Mn="[REDACTED-EMAIL]",xn="[REDACTED-CPF]",Bn="[REDACTED-CNPJ]",Oe="[REDACTED-PHONE]",Hn=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${y}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${y}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,n)=>`${e}
19
19
  ${y}
20
- ${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${y}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${y}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${y}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${y}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(t,e,n)=>`${e}${n}${y}${n}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${y}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>Dn},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>Mn},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>xn},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>Oe},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>Oe}];function b(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return Bn.reduce((n,{re:r,replace:s})=>n.replace(r,s),e)}async function ye(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},s=t.tool_response,o=s!==null&&typeof s=="object"?s.output??JSON.stringify(s):s??"",i=J(e);if(!i){O(t);return}let c=P(),l=i.pendingTool,p=l?.name===n,T=p?l.startNs:String(BigInt(c)-200000000n),m=p?l.inputStr:I(r,L.TOOL_INPUT),_=m,E=null;if(n==="Skill"){let Z=typeof r=="object"&&r!==null?r.skill||r.name||r.skillName||r.commandName||String(Object.values(r)[0]??""):String(r);E=Z?String(Z).trim():null;let x=E?St(E,i.cwd):null;x&&(_=x,i.skillContent||(i.skillContent=x),i.skillArtifacts||(i.skillArtifacts=ht(E,i.cwd))),E&&!i.slashSkill&&(i.slashSkill=E),a("PostToolUse","Skill tool detected",`skillName=${E}`,`contentFound=${!!x}`);}let k=b(I(o,L.TOOL_OUTPUT)),A=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(k.slice(0,500)),at=A?"ERROR":"DEFAULT",q=C(),ct=Math.round(Number(BigInt(c)-BigInt(T))/1e6),ut={Agent:"AGENT",Task:"AGENT"}[n]??"TOOL",M=n==="Skill"&&E?E:Tt(m,60);i.toolCalls.push({tool:n,brief:M,error:A,durationMs:ct});let w=i.spans;w.push({traceId:i.traceId,spanId:q,parentSpanId:i.spanId,name:n,kind:3,startTimeUnixNano:T,endTimeUnixNano:c,attributes:$(u(d.OBS_NAME,n),u(d.OBS_TYPE,ut),u(d.OBS_LEVEL,at),u(d.OBS_INPUT,b(_)),u(d.OBS_OUTPUT,k),u("tool.name",n),u("tool.error",String(A)),n==="Skill"&&E?u("skill.name",E):null,n==="Skill"?u("skill.invocation","slash-command"):null),status:{code:A?2:1}}),i.pendingTool=null,X(e,i),A&&F("TOOL_ERROR",{toolName:n}),a("PostToolUse",`sid=${e}`,`tool=${n}`,`error=${A}`,`durationMs=${ct}`,`totalSpans=${w.length}`),O(t);}var Re={"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 ke(t,e,n){let r=Object.keys(Re).find(i=>(t??"").toLowerCase().includes(i));if(!r)return;let s=Re[r],o=(e*s.input+n*s.output)/1e6;return Math.round(o*1e6)/1e6}S();async function Le(t){let e=t.session_id||"unknown",n=t.stop_reason||"end_turn",r=J(e);if(!r){O(t);return}r.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(r.slashSkill)&&(a("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${r.slashSkill}"`),r.slashSkill=null);let s=P(),o=await Qt(),i=r.toolCalls,c=r.spans;if(r.slashSkill&&!i.some(f=>f.tool==="Skill")){let f=C(),U=r.skillContent?r.skillContent:JSON.stringify({skill:r.slashSkill});i.push({tool:"Skill",brief:r.slashSkill,error:false,durationMs:0,synthetic:true}),c.push({traceId:r.traceId,spanId:f,parentSpanId:r.spanId,name:"Skill",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:r.startNs,attributes:$(u(d.OBS_NAME,"Skill"),u(d.OBS_TYPE,"TOOL"),u(d.OBS_LEVEL,"DEFAULT"),u(d.OBS_INPUT,U),u(d.OBS_OUTPUT,"loaded via slash command"),u("tool.name","Skill"),u("tool.error","false"),u("skill.name",r.slashSkill),u("skill.invocation","slash-command")),status:{code:1}}),a("Stop",`slashSkill=${r.slashSkill}`,"synthetic span injected");}let l=t.transcript_path||r.transcriptPath||"",p=Ct(l);if(l&&(i.some(f=>f.tool==="Skill"&&!f.synthetic)||!!r.slashSkill)&&!p?.text){await new Promise(U=>setTimeout(U,500));let f=Ct(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?I(p.text,L.TRACE_OUTPUT):m===0?"No tools used":i.map((f,U)=>`${U+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""}`).join(`
21
- `)),k=p?.inputTokens??0,A=p?.outputTokens??0,at=i.map((f,U)=>`${U+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""} (${f.durationMs}ms)`),q=!!(r.slashSkill||i.some(f=>f.tool==="Skill")),ct=i.some(f=>f.tool==="Agent");if(!q&&!ct){a("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),F("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),vt(e),O(t);return}let lt=q?"skill":"agent",ut=Math.round(Number(BigInt(s)-BigInt(r.startNs))/1e6),M=p?.model||"",Ot=ke(M,k,A),w=le(r);w==="prerequisite_required"&&p?.text&&(w="complete"),w==="prerequisite_required"&&(c.push({traceId:r.traceId,spanId:C(),parentSpanId:r.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:r.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",r.slashSkill||void 0),u("execution_status","prerequisite_required")),status:{code:1}}),a("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${r.slashSkill}`));let Z=(()=>{if(!(!q||!r.prompt)){if(r.slashSkill){let f=r.prompt.replace(new RegExp(`^\\/${r.slashSkill}\\s*`,"i"),"").trim();return f?I(b(f),L.USER_INSTRUCTION):void 0}return I(b(r.prompt),L.USER_INSTRUCTION)||void 0}})(),x=JSON.stringify({trace_type:lt,...w!==null&&{execution_status:w},...r.slashSkill?{skill_name:r.slashSkill}:{},...r.skillArtifacts?.length&&{skill_artifacts:r.skillArtifacts},...Z!==void 0&&{user_instruction:Z},latency_ms:ut,...k&&{tokens_input:k},...A&&{tokens_output:A},cost_usd:Ot,...M?{model:M}:{},toolCount:m,errorCount:_,stopReason:n,sessionId:r.sessionId,tools:at.length?at:void 0}),Mt=b(I(r.prompt,L.TRACE_INPUT)),Ie=$(u(d.TRACE_NAME,r.traceName),u(d.TRACE_INPUT,Mt),u(d.TRACE_OUTPUT,E),u(d.OBS_INPUT,Mt),u(d.OBS_OUTPUT,E),u(d.TRACE_METADATA,x),u(d.SESSION_ID,r.sessionId),u(d.USER_ID,o.user),u(d.OBS_TYPE,"GENERATION"),u(d.MODEL,M),k?u(d.INPUT_TOKENS,k):null,A?u(d.OUTPUT_TOKENS,A):null,u("claude.stop_reason",n),u("claude.tool_count",String(m)),u("claude.error_count",String(_)),u("claude.session_id",r.sessionId),u("flow.trace_type",lt),{key:d.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:lt}]}}}),we={traceId:r.traceId,spanId:r.spanId,name:r.traceName,kind:1,startTimeUnixNano:r.startNs,endTimeUnixNano:s,attributes:Ie,status:{code:_>0?2:1}},Pe=$(u("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),u("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),xt=[...c,we];a("Stop",`sid=${e}`,`totalTools=${m}`,`errorTools=${_}`,`spans=${xt.length}`,`inputTokens=${k}`,`outputTokens=${A}`,`traceOutput="${Tt(E,80)}"`);let Ne=await Ae(pe(Pe,xt));a("Stop",`POST status=${Ne}`,`traceId=${r.traceId}`),F("TRACE_SENT",{latencyMs:ut,totalTools:m,errorTools:_,inputTokens:k,outputTokens:A,costUsd:Ot}),vt(e),O(t);}var D=class{static async userPromptSubmit(){let e=await ot(),n;try{n=await V();}catch{O(e);return}n.authError?await Ft(e,true):n.length>0?await Ft(e):O(e);}static async preToolUse(){let e=await ot();await ue(e);}static async postToolUse(){let e=await ot();await ye(e);}static async stop(){let e=await ot();await Le(e);}};async function Hn(){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
- `),process.stdin.on("data",e=>process.stdout.write(e));}}Hn().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
20
+ ${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${y}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${y}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${y}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${y}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(t,e,n)=>`${e}${n}${y}${n}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${y}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>Mn},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>xn},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>Bn},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>Oe},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>Oe}];function b(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return Hn.reduce((n,{re:r,replace:s})=>n.replace(r,s),e)}async function ye(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},s=t.tool_response,o=s!==null&&typeof s=="object"?s.output??JSON.stringify(s):s??"",i=J(e);if(!i){O(t);return}let c=P(),l=i.pendingTool,p=l?.name===n,T=p?l.startNs:String(BigInt(c)-200000000n),m=p?l.inputStr:I(r,L.TOOL_INPUT),_=m,E=null;if(n==="Skill"){let Z=typeof r=="object"&&r!==null?r.skill||r.name||r.skillName||r.commandName||String(Object.values(r)[0]??""):String(r);E=Z?String(Z).trim():null;let x=E?St(E,i.cwd):null;x&&(_=x,i.skillContent||(i.skillContent=x),i.skillArtifacts||(i.skillArtifacts=ht(E,i.cwd))),E&&!i.slashSkill&&(i.slashSkill=E),a("PostToolUse","Skill tool detected",`skillName=${E}`,`contentFound=${!!x}`);}let k=b(I(o,L.TOOL_OUTPUT)),A=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(k.slice(0,500)),at=A?"ERROR":"DEFAULT",q=C(),ct=Math.round(Number(BigInt(c)-BigInt(T))/1e6),ut={Agent:"AGENT",Task:"AGENT"}[n]??"TOOL",M=n==="Skill"&&E?E:Tt(m,60);i.toolCalls.push({tool:n,brief:M,error:A,durationMs:ct});let w=i.spans;w.push({traceId:i.traceId,spanId:q,parentSpanId:i.spanId,name:n,kind:3,startTimeUnixNano:T,endTimeUnixNano:c,attributes:$(u(d.OBS_NAME,n),u(d.OBS_TYPE,ut),u(d.OBS_LEVEL,at),u(d.OBS_INPUT,b(_)),u(d.OBS_OUTPUT,k),u("tool.name",n),u("tool.error",String(A)),n==="Skill"&&E?u("skill.name",E):null,n==="Skill"?u("skill.invocation","slash-command"):null),status:{code:A?2:1}}),i.pendingTool=null,X(e,i),A&&F("TOOL_ERROR",{toolName:n}),a("PostToolUse",`sid=${e}`,`tool=${n}`,`error=${A}`,`durationMs=${ct}`,`totalSpans=${w.length}`),O(t);}var Re={"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 ke(t,e,n){let r=Object.keys(Re).find(i=>(t??"").toLowerCase().includes(i));if(!r)return;let s=Re[r],o=(e*s.input+n*s.output)/1e6;return Math.round(o*1e6)/1e6}S();async function Le(t){let e=t.session_id||"unknown",n=t.stop_reason||"end_turn",r=J(e);if(!r){O(t);return}r.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(r.slashSkill)&&(a("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${r.slashSkill}"`),r.slashSkill=null);let s=P(),o=await Qt(),i=r.toolCalls,c=r.spans;if(r.slashSkill&&!i.some(f=>f.tool==="Skill")){let f=C(),U=r.skillContent?r.skillContent:JSON.stringify({skill:r.slashSkill});i.push({tool:"Skill",brief:r.slashSkill,error:false,durationMs:0,synthetic:true}),c.push({traceId:r.traceId,spanId:f,parentSpanId:r.spanId,name:"Skill",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:r.startNs,attributes:$(u(d.OBS_NAME,"Skill"),u(d.OBS_TYPE,"TOOL"),u(d.OBS_LEVEL,"DEFAULT"),u(d.OBS_INPUT,U),u(d.OBS_OUTPUT,"loaded via slash command"),u("tool.name","Skill"),u("tool.error","false"),u("skill.name",r.slashSkill),u("skill.invocation","slash-command")),status:{code:1}}),a("Stop",`slashSkill=${r.slashSkill}`,"synthetic span injected");}let l=t.transcript_path||r.transcriptPath||"",p=Ct(l);if(l&&(i.some(f=>f.tool==="Skill"&&!f.synthetic)||!!r.slashSkill)&&!p?.text){await new Promise(U=>setTimeout(U,500));let f=Ct(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?I(p.text,L.TRACE_OUTPUT):m===0?"No tools used":i.map((f,U)=>`${U+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""}`).join(`
21
+ `)),k=p?.inputTokens??0,A=p?.outputTokens??0,at=i.map((f,U)=>`${U+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""} (${f.durationMs}ms)`),q=!!(r.slashSkill||i.some(f=>f.tool==="Skill")),ct=i.some(f=>f.tool==="Agent");if(!q&&!ct){a("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),F("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),vt(e),O(t);return}let lt=q?"skill":"agent",ut=Math.round(Number(BigInt(s)-BigInt(r.startNs))/1e6),M=p?.model||"",Ot=ke(M,k,A),w=le(r);w==="prerequisite_required"&&p?.text&&(w="complete"),w==="prerequisite_required"&&(c.push({traceId:r.traceId,spanId:C(),parentSpanId:r.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:r.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",r.slashSkill||void 0),u("execution_status","prerequisite_required")),status:{code:1}}),a("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${r.slashSkill}`));let Z=(()=>{if(!(!q||!r.prompt)){if(r.slashSkill){let f=r.prompt.replace(new RegExp(`^\\/${r.slashSkill}\\s*`,"i"),"").trim();return f?I(b(f),L.USER_INSTRUCTION):void 0}return I(b(r.prompt),L.USER_INSTRUCTION)||void 0}})(),x=JSON.stringify({trace_type:lt,...w!==null&&{execution_status:w},...r.slashSkill?{skill_name:r.slashSkill}:{},...r.skillArtifacts?.length&&{skill_artifacts:r.skillArtifacts},...Z!==void 0&&{user_instruction:Z},latency_ms:ut,...k&&{tokens_input:k},...A&&{tokens_output:A},cost_usd:Ot,...M?{model:M}:{},toolCount:m,errorCount:_,stopReason:n,sessionId:r.sessionId,tools:at.length?at:void 0}),Mt=b(I(r.prompt,L.TRACE_INPUT)),Ie=$(u(d.TRACE_NAME,r.traceName),u(d.TRACE_INPUT,Mt),u(d.TRACE_OUTPUT,E),u(d.OBS_INPUT,Mt),u(d.OBS_OUTPUT,E),u(d.TRACE_METADATA,x),u(d.SESSION_ID,r.sessionId),u(d.USER_ID,o.user),u(d.OBS_TYPE,"GENERATION"),u(d.MODEL,M),k?u(d.INPUT_TOKENS,k):null,A?u(d.OUTPUT_TOKENS,A):null,u("claude.stop_reason",n),u("claude.tool_count",String(m)),u("claude.error_count",String(_)),u("claude.session_id",r.sessionId),u("flow.trace_type",lt),{key:d.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:lt}]}}}),we={traceId:r.traceId,spanId:r.spanId,name:r.traceName,kind:1,startTimeUnixNano:r.startNs,endTimeUnixNano:s,attributes:Ie,status:{code:_>0?2:1}},Pe=$(u("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),u("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),xt=[...c,we];a("Stop",`sid=${e}`,`totalTools=${m}`,`errorTools=${_}`,`spans=${xt.length}`,`inputTokens=${k}`,`outputTokens=${A}`,`traceOutput="${Tt(E,80)}"`);let Ne=await Ae(pe(Pe,xt));a("Stop",`POST status=${Ne}`,`traceId=${r.traceId}`),F("TRACE_SENT",{latencyMs:ut,totalTools:m,errorTools:_,inputTokens:k,outputTokens:A,costUsd:Ot}),vt(e),O(t);}var D=class{static async userPromptSubmit(){let e=await ot(),n;try{n=await V();}catch{O(e);return}n.authError?await Ft(e,true):n.length>0?await Ft(e):O(e);}static async preToolUse(){let e=await ot();await ue(e);}static async postToolUse(){let e=await ot();await ye(e);}static async stop(){let e=await ot();await Le(e);}};async function Yn(){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
+ `),process.stdin.on("data",e=>process.stdout.write(e));}}Yn().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
23
23
  `),process.exit(0);});
package/dist/setup.js CHANGED
@@ -1,15 +1,20 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';var l=require('path'),a=require('fs'),_=require('os'),child_process=require('child_process'),ut=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 l__namespace=/*#__PURE__*/_interopNamespace(l);var a__namespace=/*#__PURE__*/_interopNamespace(a);var ___namespace=/*#__PURE__*/_interopNamespace(_);var ut__default=/*#__PURE__*/_interopDefault(ut);var M=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var ve=Object.prototype.hasOwnProperty;var Ie=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var Ce=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(n){throw t=0,n}},ke=(e,t)=>{for(var n in t)M(e,n,{get:t[n],enumerable:true});},Ne=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Pe(t))!ve.call(e,s)&&s!==n&&M(e,s,{get:()=>t[s],enumerable:!(r=we(t,s))||r.enumerable});return e};var Ue=e=>Ne(M({},"__esModule",{value:true}),e);var te={};ke(te,{AUTH_ENGINE:()=>V,BUFFER:()=>xe,CLAUDE_DESKTOP:()=>Me,CONFIG_DIR_NAME:()=>P,CONFIG_FILE_NAME:()=>v,COPILOT_OTEL:()=>c,DEBUG_LOG_FILENAME:()=>W,ENV:()=>d,FLOW_URLS:()=>be,HOOK_TIMEOUTS:()=>j,INSTALLER:()=>K,NATIVE_OTEL:()=>Y,OTLP:()=>De,STATE_FILE_PREFIX:()=>Ye,TRACE_LIMITS:()=>$e,VALIDATION:()=>E,VAULT:()=>w,getFlowBaseUrl:()=>D,getFlowUrls:()=>O,getMetrics:()=>He});function D(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Fe}function O(){let e=D();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 He(){let e=D();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Fe,be,w,P,v,De,Y,d,V,K,j,xe,E,W,$e,Me,c,Ye,g=Ie(()=>{"use strict";Fe="https://flow.ciandt.com";be=O(),w={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},P="FLOW-nodejs",v="config.json",De={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},Y={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"},d={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP",FLOW_OBS_SKIP_DESKTOP_DETECTION:"FLOW_OBS_SKIP_DESKTOP_DETECTION",FLOW_OBS_SKIP_COPILOT_DETECTION:"FLOW_OBS_SKIP_COPILOT_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"},V={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},K={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},j={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},E={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[\x21-\x7E]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},W="flow-ai-obs-debug.log",$e={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};Me={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",OTLP_RESOURCE_ATTRIBUTES:"otlpResourceAttributes"},CUSTOM_PROVIDER_KEY:"custom.provider",CUSTOM_PROVIDER_VALUE:"claude-code-desktop"},c={ENABLED_KEY:"github.copilot.chat.otel.enabled",ENABLED_VALUE:!0,EXPORTER_TYPE_KEY:"github.copilot.chat.otel.exporterType",EXPORTER_TYPE_VALUE:"otlp-http",PROTOCOL_KEY:"github.copilot.chat.otel.protocol",PROTOCOL_VALUE:"http/json",ENDPOINT_KEY:"github.copilot.chat.otel.otlpEndpoint",HEADERS_KEY:"github.copilot.chat.otel.headers",HEADER_API_KEY:"x-flow-api-key",HEADER_USER:"x-flow-user"},Ye="flow-obs-";});var Oe=Ce((kn,lt)=>{lt.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.14.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'})"`,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,dependencies:{},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"}};});g();var G={credentials:"credentials","token-cache":"tokenCache"};function I(){let e=___namespace.default.homedir();if(process.platform==="darwin")return l__namespace.default.join(e,"Library","Preferences",P,v);if(process.platform==="win32"){let n=process.env.APPDATA??l__namespace.default.join(e,"AppData","Roaming");return l__namespace.default.join(n,P,v)}let t=process.env.XDG_CONFIG_HOME??l__namespace.default.join(e,".config");return l__namespace.default.join(t,P,v)}function B(){try{let e=a__namespace.default.readFileSync(I(),"utf8");return JSON.parse(e)}catch{return {}}}function ne(e){let t=I();a__namespace.default.mkdirSync(l__namespace.default.dirname(t),{recursive:true}),a__namespace.default.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var x=class{static isAvailable(){return true}static hasExistingData(){try{if(!a__namespace.default.existsSync(I()))return !1;let t=JSON.parse(a__namespace.default.readFileSync(I(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,n){let r=B(),s=G[n]??n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,n,r){let s=B(),o=G[n]??n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;ne(s);}async deleteSecret(t,n){let r=B(),s=G[n]??n;return s in r?(delete r[s],ne(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${I()}`}};async function re(){return new x}g();var Ke=w.SERVICE,je=w.ACCOUNT_CREDS;w.ACCOUNT_TOKEN;var X=null;function We(){return X||(X=re()),X}async function se(){let t=await(await We()).getSecret(Ke,je);if(!t)return null;try{return JSON.parse(t)}catch{return null}}g();g();g();var Je=l.join(_.tmpdir(),W);function p(...e){if(process.env[d.FLOW_OBS_DEBUG]!=="1")return;let t=`[${new Date().toISOString()}] ${e.join(" ")}
3
- `;try{a.writeFileSync(Je,t,{flag:"a"});}catch(n){process.stderr.write(`[flow-obs debug ERROR] ${n.message}
4
- `);}}!process.env.NO_COLOR&&process.stdout.isTTY;function J(){return process.platform==="win32"?false:process.getuid?.()===0}function $(){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:___namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||___namespace.userInfo().username}}function k(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(e=n);}if(e){let t=e.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return l__namespace.join(t,".claude","settings.json")}return l__namespace.join(___namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||___namespace.homedir();return l__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 l__namespace.join(t,".claude","settings.json")}return l__namespace.join(___namespace.homedir(),".claude","settings.json")}var oe="flow-ai-obs",ie="config.json";function ce(){if(process.platform==="win32"){let n=process.env.APPDATA||l__namespace.join(___namespace.homedir(),"AppData","Roaming");return l__namespace.join(n,oe,ie)}let e=$(),t=process.env.XDG_CONFIG_HOME||l__namespace.join(e.home,".config");return l__namespace.join(t,oe,ie)}var et=K.LOCK_STALE_MS;function le(e){try{let t=a__namespace.statSync(e);Date.now()-t.mtimeMs>et&&a__namespace.unlinkSync(e);}catch{}try{a__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 ue(e){try{a__namespace.unlinkSync(e);}catch{}}function tt(e,t){let r=(Array.isArray(e)?e:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(i=>!i.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [t,...r]}function pe(e,t){let n=k(),r=n+".lock",s=[];a__namespace.mkdirSync(l__namespace.dirname(n),{recursive:true}),le(r);try{if(a__namespace.existsSync(n)){a__namespace.copyFileSync(n,n+".bkp");try{a__namespace.chmodSync(n+".bkp",384);}catch{}}let o=ce();if(a__namespace.existsSync(o)){let f=o+".bkp";a__namespace.copyFileSync(o,f);try{a__namespace.chmodSync(f,384);}catch{}}let i={};try{i=JSON.parse(a__namespace.readFileSync(n,"utf8"));}catch{}let m=i.env&&typeof i.env=="object"?i.env:{};delete m.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:h}=(g(),Ue(te)),T=h().OTEL_ENDPOINT,F={...Y,OTEL_EXPORTER_OTLP_ENDPOINT:e??T};i.env={...m,...F,...t??{}},i.otelHeadersHelper="flow-ai-obs otel-headers",(!i.hooks||typeof i.hooks!="object"||Array.isArray(i.hooks))&&(i.hooks={});let H=(f,b)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${f}`,timeout:b}]}),ee=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],L=i.hooks;for(let f of ee){let b=tt(L[f],H(f,j[f]));b.length>1&&s.push(f),L[f]=b;}a__namespace.writeFileSync(n,JSON.stringify(i,null,2)+`
5
- `,{encoding:"utf8",mode:384});try{a__namespace.chmodSync(n,384);}catch{}}finally{ue(r);}return {settingsPath:n,preserved:s}}var U;function fe(e){if(U===void 0)try{let n=a__namespace.readFileSync(k(),"utf8");U=JSON.parse(n).env??null;}catch{U=null;}if(!U)return null;let t=U[e];return typeof t=="string"?t:null}function Z(e){let t=k(),n=t+".lock";a__namespace.mkdirSync(l__namespace.dirname(t),{recursive:true}),le(n);try{let r={};try{r=JSON.parse(a__namespace.readFileSync(t,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,e),a__namespace.writeFileSync(t,JSON.stringify(r,null,2)+`
6
- `,{encoding:"utf8",mode:384});try{a__namespace.chmodSync(t,384);}catch{}}finally{ue(n);}}function de(e){let t=process.env[e];return t!==void 0?t!==""?t:void 0:fe(e)??void 0}g();g();g();function Ee(e){if(!e)return null;try{let t=e.split(".");if(t.length<2)return null;let n=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:o}=n;return !r||!s||!o?null:{clientId:r,clientSecret:s,tenant:o}}catch{return null}}function ge(e){let t=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),n=Buffer.from(JSON.stringify({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant})).toString("base64url");return `${t}.${n}.`}function st(e){let t=process.env[d.OTEL_EXPORTER_OTLP_HEADERS];if(!t)return null;let n=e.toLowerCase();for(let r of t.split(",")){let s=r.indexOf("=");if(!(s<=0)&&r.slice(0,s).trim().toLowerCase()===n){let o=r.slice(s+1),i=o.search(/[\r\n]/);return (i===-1?o:o.slice(0,i)).trim()||null}}return null}function me(){let e=de(d.FLOW_USER_EMAIL);if(e!==void 0){let n=e.replace(/[\r\n]/g,"").trim();if(n)if(n.length>E.EMAIL_MAX_LENGTH)p("resolveUserEmail",`FLOW_USER_EMAIL exceeds ${E.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!E.EMAIL_HEADER_PATTERN.test(n))p("resolveUserEmail","FLOW_USER_EMAIL contains non-printable or control characters \u2014 skipping");else return p("resolveUserEmail","using FLOW_USER_EMAIL override: [REDACTED]"),n}let t=st("x-flow-user");if(t){let n=t.replace(/[\r\n]/g,"").trim();if(n.length>E.EMAIL_MAX_LENGTH)p("resolveUserEmail",`x-flow-user from OTEL_EXPORTER_OTLP_HEADERS exceeds ${E.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!E.EMAIL_HEADER_PATTERN.test(n))p("resolveUserEmail","x-flow-user from OTEL_EXPORTER_OTLP_HEADERS is empty or contains non-printable characters \u2014 skipping");else return p("resolveUserEmail","using x-flow-user from OTEL_EXPORTER_OTLP_HEADERS: [REDACTED]"),n}try{let n=___namespace.default.userInfo().username||process.env.USERNAME||process.env.USER||"",r=n.lastIndexOf("\\");if(r!==-1&&(n=n.slice(r+1)),n=n.trim().replace(/[^a-zA-Z0-9._%+\-]/g,"").replace(/^\.+/,""),!n)return p("resolveUserEmail","Could not derive x-flow-user: username is empty. Run: flow-ai-obs init"),null;let s=`${n}@ciandt.com`;return p("resolveUserEmail","derived email: [REDACTED]"),s}catch(n){return p("resolveUserEmail",`Could not derive x-flow-user from OS username: ${n.message}. Run: flow-ai-obs init`),null}}function he(){let e=process.env[d.FLOW_API_KEY];if(!e)return null;let t=e.replace(/[\r\n]/g,"").trim();return t?t.length>E.API_KEY_MAX_LENGTH?(p("resolveApiKey",`FLOW_API_KEY exceeds ${E.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):E.API_KEY_PATTERN.test(t)?t:(p("resolveApiKey","FLOW_API_KEY contains non-printable or control characters \u2014 rejected"),null):null}function _e(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let n=process.env.APPDATA;if(!n)try{let o=child_process.spawnSync("cmd.exe",["/c","echo","%APPDATA%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();o&&/^[A-Za-z]:\\/.test(o)&&(n=o);}catch(s){p("getVsCodeSettingsPath",`cmd.exe APPDATA lookup failed: ${s.message}`);}if(!n)return null;let r=n.replace(/^([A-Za-z]):/,(s,o)=>`/mnt/${o.toLowerCase()}`).replace(/\\/g,"/");return l__namespace.join(r,"Code","User","settings.json")}if(process.platform==="win32"){let n=process.env.APPDATA||l__namespace.join(___namespace.homedir(),"AppData","Roaming");return l__namespace.join(n,"Code","User","settings.json")}if(process.platform==="darwin")return l__namespace.join(___namespace.homedir(),"Library","Application Support","Code","User","settings.json");let e=process.platform==="linux"&&process.getuid?.()===0?$().home:process.env.HOME||___namespace.homedir(),t=process.env.XDG_CONFIG_HOME||l__namespace.join(e,".config");return l__namespace.join(t,"Code","User","settings.json")}function it(e){let t=false,n=false,r="";for(let s=0;s<e.length;s++){let o=e[s];if(t){r+=o,n?n=false:o==="\\"?n=true:o==='"'&&(t=false);continue}if(o==='"'){t=true,r+=o;continue}if(o===","){let i=s+1;for(;i<e.length&&/\s/.test(e[i]);)i++;if(i<e.length&&(e[i]==="}"||e[i]==="]"))continue}r+=o;}return r}function at(e){if(process.env[d.FLOW_OBS_SKIP_COPILOT_DETECTION])return !!(e&&a__namespace.existsSync(e));if(e&&(a__namespace.existsSync(e)||a__namespace.existsSync(l__namespace.dirname(e))||a__namespace.existsSync(l__namespace.dirname(l__namespace.dirname(e)))))return true;let t=_e();if(t&&(a__namespace.existsSync(t)||a__namespace.existsSync(l__namespace.dirname(t))||a__namespace.existsSync(l__namespace.dirname(l__namespace.dirname(t))))||process.platform==="darwin"&&["/Applications/Visual Studio Code.app",l__namespace.join(___namespace.homedir(),"Applications","Visual Studio Code.app")].some(r=>a__namespace.existsSync(r)))return true;if(process.platform==="win32"){let n=process.env.LOCALAPPDATA||l__namespace.join(___namespace.homedir(),"AppData","Local"),r=process.env.PROGRAMFILES||"C:\\Program Files",s=process.env["PROGRAMFILES(X86)"]||"C:\\Program Files (x86)";if([l__namespace.join(n,"Programs","Microsoft VS Code","Code.exe"),l__namespace.join(r,"Microsoft VS Code","Code.exe"),l__namespace.join(s,"Microsoft VS Code","Code.exe")].some(i=>a__namespace.existsSync(i)))return true}return !!(process.platform==="linux"&&["/usr/bin/code","/usr/share/code","/snap/bin/code"].some(r=>a__namespace.existsSync(r)))}function Te(e,t={}){let n;try{n=t.customSettingsPath||_e();}catch(r){return {status:"skipped",reason:`VS Code path resolution failed: ${r.message}`}}if(!n)return {status:"skipped",reason:"VS Code path not found"};if(!at(n))return {status:"skipped",settingsPath:n,reason:"VS Code is not installed"};try{let r={};if(a__namespace.existsSync(n))try{let f=it(a__namespace.readFileSync(n,"utf8"));r=JSON.parse(f);}catch{return {status:"skipped",settingsPath:n,reason:"VS Code settings.json could not be parsed (unsupported JSONC syntax such as comments)"}}let s=e||O().OTEL_ENDPOINT,o=t.apiKey!==void 0?t.apiKey:he(),i=t.userEmail!==void 0?t.userEmail:me(),m=typeof r[c.HEADERS_KEY]=="object"&&r[c.HEADERS_KEY]!==null&&!Array.isArray(r[c.HEADERS_KEY])?r[c.HEADERS_KEY]:{},h={...m};o&&(h[c.HEADER_API_KEY]=o),i&&(h[c.HEADER_USER]=i);let T=Object.keys(h),F=Object.keys(m),H=T.length===0&&(r[c.HEADERS_KEY]===void 0||F.length===0)||T.length===F.length&&T.every(f=>m[f]===h[f]);if(r[c.ENABLED_KEY]===c.ENABLED_VALUE&&r[c.EXPORTER_TYPE_KEY]===c.EXPORTER_TYPE_VALUE&&r[c.PROTOCOL_KEY]===c.PROTOCOL_VALUE&&r[c.ENDPOINT_KEY]===s&&H)return {status:"already_configured",settingsPath:n};a__namespace.mkdirSync(l__namespace.dirname(n),{recursive:!0});let L={...r,[c.ENABLED_KEY]:c.ENABLED_VALUE,[c.EXPORTER_TYPE_KEY]:c.EXPORTER_TYPE_VALUE,[c.PROTOCOL_KEY]:c.PROTOCOL_VALUE,[c.ENDPOINT_KEY]:s};return T.length>0&&(L[c.HEADERS_KEY]=h),a__namespace.writeFileSync(n,JSON.stringify(L,null,2)+`
7
- `,{encoding:"utf8"}),{status:"configured",settingsPath:n}}catch(r){return {status:"skipped",settingsPath:n,reason:r.message}}}g();var Q;function Ae(){return Q||(Q=Oe()),Q}var ye=l__namespace.default.join(___namespace.default.tmpdir(),"flow-obs-update-cache.json"),dt=1440*60*1e3,Et=3e3;function gt(e,t){let n=o=>{let i=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return i?[+i[1],+i[2],+i[3]]:null},r=n(e),s=n(t);return !r||!s?false:s[0]!==r[0]?s[0]>r[0]:s[1]!==r[1]?s[1]>r[1]:s[2]>r[2]}function mt(){try{let e=JSON.parse(a__namespace.default.readFileSync(ye,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=dt?null:e}catch{return null}}function ht(e,t,n=Date.now()){try{a__namespace.default.writeFileSync(ye,JSON.stringify({latestVersion:e,updatePriority:t??null,checkedAt:n}),{mode:384});}catch{}}function _t(e){let t=Ae().name,n=ut__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:Et},r=>{if(r.statusCode!==200)return r.resume(),e(new Error(`HTTP ${r.statusCode}`));let s="";r.setEncoding("utf8"),r.on("data",o=>{s+=o;}),r.on("end",()=>{try{let o=JSON.parse(s);if(typeof o.version!="string")throw new Error("no version field");e(null,{version:o.version,updatePriority:typeof o.updatePriority=="string"?o.updatePriority:null});}catch(o){e(o);}});});n.on("error",e),n.on("timeout",()=>{n.destroy(new Error("timeout"));});}function Re(){try{if(mt())return;setImmediate(()=>{_t((e,t)=>{e||!t||gt(Ae().version,t.version)&&ht(t.version,t.updatePriority,0);});});}catch{}}var Tt=l__namespace.default.resolve(__dirname,".."),Ot=process.env.INIT_CWD?l__namespace.default.resolve(process.env.INIT_CWD):null;Ot===Tt&&process.exit(0);J()&&(process.stderr.write(`
2
+ 'use strict';var u=require('path'),a=require('fs'),O=require('os'),child_process=require('child_process'),Ie=require('crypto'),Dt=require('https');require('readline/promises');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var u__namespace=/*#__PURE__*/_interopNamespace(u);var a__namespace=/*#__PURE__*/_interopNamespace(a);var O__namespace=/*#__PURE__*/_interopNamespace(O);var Ie__namespace=/*#__PURE__*/_interopNamespace(Ie);var Dt__default=/*#__PURE__*/_interopDefault(Dt);var B=Object.defineProperty;var Me=Object.getOwnPropertyDescriptor;var $e=Object.getOwnPropertyNames;var He=Object.prototype.hasOwnProperty;var Ye=(e,n,t)=>()=>{if(t)throw t[0];try{return e&&(n=e(e=0)),n}catch(r){throw t=[r],r}};var Ke=(e,n)=>()=>{try{return n||e((n={exports:{}}).exports,n),n.exports}catch(t){throw n=0,t}},je=(e,n)=>{for(var t in n)B(e,t,{get:n[t],enumerable:true});},We=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of $e(n))!He.call(e,s)&&s!==t&&B(e,s,{get:()=>n[s],enumerable:!(r=Me(n,s))||r.enumerable});return e};var Ve=e=>We(B({},"__esModule",{value:true}),e);var ue={};je(ue,{AUTH_ENGINE:()=>X,BUFFER:()=>Xe,CLAUDE_DESKTOP:()=>f,CONFIG_DIR_NAME:()=>U,CONFIG_FILE_NAME:()=>D,COPILOT_OTEL:()=>p,DEBUG_LOG_FILENAME:()=>Z,ENV:()=>h,FLOW_URLS:()=>Be,HOOK_TIMEOUTS:()=>q,INSTALLER:()=>z,NATIVE_OTEL:()=>J,OTLP:()=>Je,STATE_FILE_PREFIX:()=>Ze,TRACE_LIMITS:()=>ze,VALIDATION:()=>T,VAULT:()=>N,getFlowBaseUrl:()=>K,getFlowUrls:()=>S,getMetrics:()=>qe});function K(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Ge}function S(){let e=K();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 qe(){let e=K();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ge,Be,N,U,D,Je,J,h,X,z,q,Xe,T,Z,ze,f,p,Ze,y=Ye(()=>{"use strict";Ge="https://flow.ciandt.com";Be=S(),N={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},U="FLOW-nodejs",D="config.json",Je={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},J={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"},h={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_SKIP_DESKTOP_DETECTION:"FLOW_OBS_SKIP_DESKTOP_DETECTION",FLOW_OBS_SKIP_COPILOT_DETECTION:"FLOW_OBS_SKIP_COPILOT_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"},X={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},z={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},q={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},T={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[A-Za-z0-9_.\-:=+/]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},Z="flow-ai-obs-debug.log",ze={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};f={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",OTLP_RESOURCE_ATTRIBUTES:"otlpResourceAttributes"},CUSTOM_PROVIDER_KEY:"custom.provider",CUSTOM_PROVIDER_VALUE:"claude-code-desktop"},p={ENABLED_KEY:"github.copilot.chat.otel.enabled",ENABLED_VALUE:!0,EXPORTER_TYPE_KEY:"github.copilot.chat.otel.exporterType",EXPORTER_TYPE_VALUE:"otlp-http",PROTOCOL_KEY:"github.copilot.chat.otel.protocol",PROTOCOL_VALUE:"http/json",ENDPOINT_KEY:"github.copilot.chat.otel.otlpEndpoint",HEADERS_KEY:"github.copilot.chat.otel.headers",HEADER_API_KEY:"x-flow-api-key",HEADER_USER:"x-flow-user"},Ze="flow-obs-";});var Ne=Ke((ar,Ut)=>{Ut.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.15.0-beta.87",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,dependencies:{},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"}};});y();var Q={credentials:"credentials","token-cache":"tokenCache"};function F(){let e=O__namespace.default.homedir();if(process.platform==="darwin")return u__namespace.default.join(e,"Library","Preferences",U,D);if(process.platform==="win32"){let t=process.env.APPDATA??u__namespace.default.join(e,"AppData","Roaming");return u__namespace.default.join(t,U,D)}let n=process.env.XDG_CONFIG_HOME??u__namespace.default.join(e,".config");return u__namespace.default.join(n,U,D)}function ee(){try{let e=a__namespace.default.readFileSync(F(),"utf8");return JSON.parse(e)}catch{return {}}}function pe(e){let n=F();a__namespace.default.mkdirSync(u__namespace.default.dirname(n),{recursive:true}),a__namespace.default.writeFileSync(n,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var j=class{static isAvailable(){return true}static hasExistingData(){try{if(!a__namespace.default.existsSync(F()))return !1;let n=JSON.parse(a__namespace.default.readFileSync(F(),"utf8"));return !!(n&&n.credentials)}catch{return false}}async getSecret(n,t){let r=ee(),s=Q[t]??t,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(n,t,r){let s=ee(),o=Q[t]??t;if(t==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;pe(s);}async deleteSecret(n,t){let r=ee(),s=Q[t]??t;return s in r?(delete r[s],pe(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${F()}`}};async function fe(){return new j}y();var et=N.SERVICE,tt=N.ACCOUNT_CREDS;N.ACCOUNT_TOKEN;var te=null;function nt(){return te||(te=fe()),te}async function de(){let n=await(await nt()).getSecret(et,tt);if(!n)return null;try{return JSON.parse(n)}catch{return null}}y();y();y();var it=u.join(O.tmpdir(),Z);function c(...e){if(process.env[h.FLOW_OBS_DEBUG]!=="1")return;let n=`[${new Date().toISOString()}] ${e.join(" ")}
3
+ `;try{a.writeFileSync(it,n,{flag:"a"});}catch(t){process.stderr.write(`[flow-obs debug ERROR] ${t.message}
4
+ `);}}!process.env.NO_COLOR&&process.stdout.isTTY;function ne(){return process.platform==="win32"?false:process.getuid?.()===0}function A(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let n=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(n)return {home:n,username:process.env.SUDO_USER}}return {home:O__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||O__namespace.userInfo().username}}function R(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let t=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();t&&/^[A-Za-z]:\\/.test(t)&&(e=t);}if(e){let n=e.replace(/^([A-Za-z]):/,(t,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return u__namespace.join(n,".claude","settings.json")}return u__namespace.join(O__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||O__namespace.homedir();return u__namespace.join(e,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let n=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(n)return u__namespace.join(n,".claude","settings.json")}return u__namespace.join(O__namespace.homedir(),".claude","settings.json")}var Ee="flow-ai-obs",ge="config.json";function he(){if(process.platform==="win32"){let t=process.env.APPDATA||u__namespace.join(O__namespace.homedir(),"AppData","Roaming");return u__namespace.join(t,Ee,ge)}let e=A(),n=process.env.XDG_CONFIG_HOME||u__namespace.join(e.home,".config");return u__namespace.join(n,Ee,ge)}var pt=z.LOCK_STALE_MS;function _e(e){try{let n=a__namespace.statSync(e);Date.now()-n.mtimeMs>pt&&a__namespace.unlinkSync(e);}catch{}try{a__namespace.writeFileSync(e,String(process.pid),{flag:"wx"});}catch(n){throw n.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+e):n}}function Te(e){try{a__namespace.unlinkSync(e);}catch{}}function ft(e,n){let r=(Array.isArray(e)?e:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(i=>!i.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [n,...r]}function ye(e,n){let t=R(),r=t+".lock",s=[];a__namespace.mkdirSync(u__namespace.dirname(t),{recursive:true}),_e(r);try{if(a__namespace.existsSync(t)){a__namespace.copyFileSync(t,t+".bkp");try{a__namespace.chmodSync(t+".bkp",384);}catch{}}let o=he();if(a__namespace.existsSync(o)){let m=o+".bkp";a__namespace.copyFileSync(o,m);try{a__namespace.chmodSync(m,384);}catch{}}let i={};try{i=JSON.parse(a__namespace.readFileSync(t,"utf8"));}catch{}let g=i.env&&typeof i.env=="object"?i.env:{};delete g.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:_}=(y(),Ve(ue)),P=_().OTEL_ENDPOINT,H={...J,OTEL_EXPORTER_OTLP_ENDPOINT:e??P};i.env={...g,...H,...n??{}},i.otelHeadersHelper="flow-ai-obs otel-headers",(!i.hooks||typeof i.hooks!="object"||Array.isArray(i.hooks))&&(i.hooks={});let G=(m,Y)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${m}`,timeout:Y}]}),le=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],k=i.hooks;for(let m of le){let Y=ft(k[m],G(m,q[m]));Y.length>1&&s.push(m),k[m]=Y;}a__namespace.writeFileSync(t,JSON.stringify(i,null,2)+`
5
+ `,{encoding:"utf8",mode:384});try{a__namespace.chmodSync(t,384);}catch{}}finally{Te(r);}return {settingsPath:t,preserved:s}}var M;function Se(e){if(M===void 0)try{let t=a__namespace.readFileSync(R(),"utf8");M=JSON.parse(t).env??null;}catch{M=null;}if(!M)return null;let n=M[e];return typeof n=="string"?n:null}function oe(e){let n=R(),t=n+".lock";a__namespace.mkdirSync(u__namespace.dirname(n),{recursive:true}),_e(t);try{let r={};try{r=JSON.parse(a__namespace.readFileSync(n,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,e),a__namespace.writeFileSync(n,JSON.stringify(r,null,2)+`
6
+ `,{encoding:"utf8",mode:384});try{a__namespace.chmodSync(n,384);}catch{}}finally{Te(t);}}function Oe(e){let n=process.env[e];return n!==void 0?n!==""?n:void 0:Se(e)??void 0}y();y();y();function Ae(e){if(!e)return null;try{let n=e.split(".");if(n.length<2)return null;let t=JSON.parse(Buffer.from(n[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:o}=t;return !r||!s||!o?null:{clientId:r,clientSecret:s,tenant:o}}catch{return null}}function Re(e){let n=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),t=Buffer.from(JSON.stringify({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant})).toString("base64url");return `${n}.${t}.`}function gt(e){let n=process.env[h.OTEL_EXPORTER_OTLP_HEADERS];if(!n)return null;let t=e.toLowerCase();for(let r of n.split(",")){let s=r.indexOf("=");if(!(s<=0)&&r.slice(0,s).trim().toLowerCase()===t){let o=r.slice(s+1),i=o.search(/[\r\n]/);return (i===-1?o:o.slice(0,i)).trim()||null}}return null}function Le(){let e=Oe(h.FLOW_USER_EMAIL);if(e!==void 0){let t=e.replace(/[\r\n]/g,"").trim();if(t)if(t.length>T.EMAIL_MAX_LENGTH)c("resolveUserEmail",`FLOW_USER_EMAIL exceeds ${T.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!T.EMAIL_HEADER_PATTERN.test(t))c("resolveUserEmail","FLOW_USER_EMAIL contains non-printable or control characters \u2014 skipping");else return c("resolveUserEmail","using FLOW_USER_EMAIL override: [REDACTED]"),t}let n=gt("x-flow-user");if(n){let t=n.replace(/[\r\n]/g,"").trim();if(t.length>T.EMAIL_MAX_LENGTH)c("resolveUserEmail",`x-flow-user from OTEL_EXPORTER_OTLP_HEADERS exceeds ${T.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!T.EMAIL_HEADER_PATTERN.test(t))c("resolveUserEmail","x-flow-user from OTEL_EXPORTER_OTLP_HEADERS is empty or contains non-printable characters \u2014 skipping");else return c("resolveUserEmail","using x-flow-user from OTEL_EXPORTER_OTLP_HEADERS: [REDACTED]"),t}try{let t=O__namespace.default.userInfo().username||process.env.USERNAME||process.env.USER||"",r=t.lastIndexOf("\\");if(r!==-1&&(t=t.slice(r+1)),t=t.trim().replace(/[^a-zA-Z0-9._%+\-]/g,"").replace(/^\.+/,""),!t)return c("resolveUserEmail","Could not derive x-flow-user: username is empty. Run: flow-ai-obs init"),null;let s=`${t}@ciandt.com`;return c("resolveUserEmail","derived email: [REDACTED]"),s}catch(t){return c("resolveUserEmail",`Could not derive x-flow-user from OS username: ${t.message}. Run: flow-ai-obs init`),null}}function L(e){if(!e)return null;let n=e.replace(/[\r\n]/g,"").trim();return n?n.length>T.API_KEY_MAX_LENGTH?(c("validateApiKey",`API key exceeds ${T.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):T.API_KEY_PATTERN.test(n)?n:(c("validateApiKey","API key contains invalid or unsafe characters \u2014 rejected"),null):null}function W(){let e=process.env[h.FLOW_API_KEY];return L(e)}function Pe(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.APPDATA;if(!t)try{let o=child_process.spawnSync("cmd.exe",["/c","echo","%APPDATA%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();o&&/^[A-Za-z]:\\/.test(o)&&(t=o);}catch(s){c("getVsCodeSettingsPath",`cmd.exe APPDATA lookup failed: ${s.message}`);}if(!t)return null;let r=t.replace(/^([A-Za-z]):/,(s,o)=>`/mnt/${o.toLowerCase()}`).replace(/\\/g,"/");return u__namespace.join(r,"Code","User","settings.json")}if(process.platform==="win32"){let t=process.env.APPDATA||u__namespace.join(O__namespace.homedir(),"AppData","Roaming");return u__namespace.join(t,"Code","User","settings.json")}if(process.platform==="darwin")return u__namespace.join(O__namespace.homedir(),"Library","Application Support","Code","User","settings.json");let e=process.platform==="linux"&&process.getuid?.()===0?A().home:process.env.HOME||O__namespace.homedir(),n=process.env.XDG_CONFIG_HOME||u__namespace.join(e,".config");return u__namespace.join(n,"Code","User","settings.json")}function ht(e){let n=false,t=false,r="";for(let s=0;s<e.length;s++){let o=e[s];if(n){r+=o,t?t=false:o==="\\"?t=true:o==='"'&&(n=false);continue}if(o==='"'){n=true,r+=o;continue}if(o===","){let i=s+1;for(;i<e.length&&/\s/.test(e[i]);)i++;if(i<e.length&&(e[i]==="}"||e[i]==="]"))continue}r+=o;}return r}function _t(e){if(process.env[h.FLOW_OBS_SKIP_COPILOT_DETECTION])return !!(e&&a__namespace.existsSync(e));if(e&&(a__namespace.existsSync(e)||a__namespace.existsSync(u__namespace.dirname(e))||a__namespace.existsSync(u__namespace.dirname(u__namespace.dirname(e)))))return true;let n=Pe();if(n&&(a__namespace.existsSync(n)||a__namespace.existsSync(u__namespace.dirname(n))||a__namespace.existsSync(u__namespace.dirname(u__namespace.dirname(n))))||process.platform==="darwin"&&["/Applications/Visual Studio Code.app",u__namespace.join(O__namespace.homedir(),"Applications","Visual Studio Code.app")].some(r=>a__namespace.existsSync(r)))return true;if(process.platform==="win32"){let t=process.env.LOCALAPPDATA||u__namespace.join(O__namespace.homedir(),"AppData","Local"),r=process.env.PROGRAMFILES||"C:\\Program Files",s=process.env["PROGRAMFILES(X86)"]||"C:\\Program Files (x86)";if([u__namespace.join(t,"Programs","Microsoft VS Code","Code.exe"),u__namespace.join(r,"Microsoft VS Code","Code.exe"),u__namespace.join(s,"Microsoft VS Code","Code.exe")].some(i=>a__namespace.existsSync(i)))return true}return !!(process.platform==="linux"&&["/usr/bin/code","/usr/share/code","/snap/bin/code"].some(r=>a__namespace.existsSync(r)))}function we(e,n={}){let t;try{t=n.customSettingsPath||Pe();}catch(r){return {status:"skipped",reason:`VS Code path resolution failed: ${r.message}`}}if(!t)return {status:"skipped",reason:"VS Code path not found"};if(!_t(t))return {status:"skipped",settingsPath:t,reason:"VS Code is not installed"};try{let r={};if(a__namespace.existsSync(t))try{let m=ht(a__namespace.readFileSync(t,"utf8"));r=JSON.parse(m);}catch{return {status:"skipped",settingsPath:t,reason:"VS Code settings.json could not be parsed (unsupported JSONC syntax such as comments)"}}let s=e||S().OTEL_ENDPOINT,o=n.apiKey!==void 0?n.apiKey:W(),i=n.userEmail!==void 0?n.userEmail:Le(),g=typeof r[p.HEADERS_KEY]=="object"&&r[p.HEADERS_KEY]!==null&&!Array.isArray(r[p.HEADERS_KEY])?r[p.HEADERS_KEY]:{},_={...g};o&&(_[p.HEADER_API_KEY]=o),i&&(_[p.HEADER_USER]=i);let P=Object.keys(_),H=Object.keys(g),G=P.length===0&&(r[p.HEADERS_KEY]===void 0||H.length===0)||P.length===H.length&&P.every(m=>g[m]===_[m]);if(r[p.ENABLED_KEY]===p.ENABLED_VALUE&&r[p.EXPORTER_TYPE_KEY]===p.EXPORTER_TYPE_VALUE&&r[p.PROTOCOL_KEY]===p.PROTOCOL_VALUE&&r[p.ENDPOINT_KEY]===s&&G)return {status:"already_configured",settingsPath:t};a__namespace.mkdirSync(u__namespace.dirname(t),{recursive:!0});let k={...r,[p.ENABLED_KEY]:p.ENABLED_VALUE,[p.EXPORTER_TYPE_KEY]:p.EXPORTER_TYPE_VALUE,[p.PROTOCOL_KEY]:p.PROTOCOL_VALUE,[p.ENDPOINT_KEY]:s};return P.length>0&&(k[p.HEADERS_KEY]=_),a__namespace.writeFileSync(t,JSON.stringify(k,null,2)+`
7
+ `,{encoding:"utf8"}),{status:"configured",settingsPath:t}}catch(r){return {status:"skipped",settingsPath:t,reason:r.message}}}y();function ve(){return !!(process.env.WSL_DISTRO_NAME&&process.platform==="linux")}function ie(){return process.platform==="win32"||ve()}function yt(e){let n=e.match(/^\/mnt\/([a-z])\/(.*)$/);if(!n)return e;let t=n[1].toUpperCase(),r=n[2].replace(/\//g,"\\");return `${t}:\\${r}`}function Ce(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let r=process.env.LOCALAPPDATA;if(!r)try{let s=child_process.execSync("cmd.exe /c echo %LOCALAPPDATA%",{encoding:"utf8",timeout:5e3}).trim();s&&/^[A-Za-z]:\\/.test(s)&&(r=s);}catch(s){c("getDesktopPaths",`cmd.exe LOCALAPPDATA lookup failed: ${s.message}`);}if(r){let s=r.replace(/^([A-Za-z]):/,(i,g)=>`/mnt/${g.toLowerCase()}`).replace(/\\/g,"/"),o=u__namespace.join(s,f.DIR_3P);return V(o)}}if(process.platform==="win32"){let r=process.env.LOCALAPPDATA||u__namespace.join(O__namespace.homedir(),"AppData","Local"),s=u__namespace.join(r,f.DIR_3P);return V(s)}if(process.platform==="darwin"){let r=u__namespace.join(O__namespace.homedir(),"Library","Application Support",f.DIR_3P);return V(r)}let e=A(),n=process.env.XDG_CONFIG_HOME||u__namespace.join(e.home,".config"),t=u__namespace.join(n,f.DIR_3P);return V(t)}function V(e){return {configDir:e,configLibraryDir:u__namespace.join(e,f.CONFIG_LIBRARY_DIR),desktopConfigPath:u__namespace.join(e,f.DESKTOP_CONFIG_FILE),metaPath:u__namespace.join(e,f.CONFIG_LIBRARY_DIR,f.META_FILE)}}function ae(){let e=R(),n=u__namespace.dirname(e),t=ie()?f.WRAPPER_SCRIPT_WIN:f.WRAPPER_SCRIPT_UNIX;return u__namespace.join(n,t)}function St(){if(process.env[h.FLOW_OBS_SKIP_DESKTOP_DETECTION])return false;let e=Ce();if(a__namespace.existsSync(e.configDir))return true;if(process.platform==="darwin")return ["/Applications/Claude.app",u__namespace.join(O__namespace.homedir(),"Applications","Claude.app")].some(t=>a__namespace.existsSync(t));if(process.platform==="win32"){let n=process.env.LOCALAPPDATA||u__namespace.join(O__namespace.homedir(),"AppData","Local"),t=process.env.PROGRAMFILES||"C:\\Program Files";return [u__namespace.join(n,"AnthropicClaude","Claude.exe"),u__namespace.join(t,"Claude","Claude.exe")].some(s=>a__namespace.existsSync(s))}if(process.platform==="linux"){let n=A(),t=process.env.XDG_CONFIG_HOME||u__namespace.join(n.home,".config"),r=u__namespace.join(t,"Claude");return a__namespace.existsSync(r)}return false}function Ot(e){let n=e??ae();try{if(!a__namespace.existsSync(n))return null;let t=a__namespace.readFileSync(n,"utf8"),r=t.match(/^export FLOW_API_KEY=["']?([^"'\r\n]+)["']?$/m);if(r&&r[1])return L(r[1]);let s=t.match(/^set FLOW_API_KEY=([^\r\n]+)$/m);if(s&&s[1])return L(s[1])}catch{}return null}function At(e,n,t=448){let r=u__namespace.dirname(e);a__namespace.mkdirSync(r,{recursive:true});let s=ie(),o=s?420:t,i=true;try{a__namespace.readFileSync(e,"utf8")===n&&(i=!1);}catch{}if(!i){if(!s)try{a__namespace.chmodSync(e,t);}catch{}return {written:false}}if(a__namespace.existsSync(e)&&(a__namespace.copyFileSync(e,e+".bkp"),!s))try{a__namespace.chmodSync(e+".bkp",448);}catch{}if(a__namespace.writeFileSync(e,n,{encoding:"utf8",mode:o}),!s)try{a__namespace.chmodSync(e,t);}catch{}return {written:true}}function Rt(e){let n=ae(),t=e?L(e):null,r=ie()?Pt(t):Lt(t);return At(n,r,!!t?448:493),n}function Lt(e){let n=e?L(e):null,t=["#!/usr/bin/env bash","# Auto-generated by flow-ai-obs \u2014 do not edit manually.","# Wrapper script for Claude Desktop otelHeadersHelper.","# Invokes flow-ai-obs otel-headers to produce fresh OTLP headers at runtime.","set -euo pipefail"];return n&&t.push(`export FLOW_API_KEY="${n}"`),t.push("exec flow-ai-obs otel-headers",""),t.join(`
8
+ `)}function Pt(e){let n=e?L(e):null,t=["@echo off","REM Auto-generated by flow-ai-obs \u2014 do not edit manually.","REM Wrapper script for Claude Desktop otelHeadersHelper.","REM Invokes flow-ai-obs otel-headers to produce fresh OTLP headers at runtime."];return n&&t.push(`set FLOW_API_KEY=${n}`),t.push("flow-ai-obs otel-headers",""),t.join(`\r
9
+ `)}var wt=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function It(e){try{let n=a__namespace.readFileSync(e,"utf8");try{let t=JSON.parse(n);if(t.appliedId&&typeof t.appliedId=="string"&&wt.test(t.appliedId))return t.appliedId;t.appliedId&&c("getOrCreateConfigUuid","appliedId is not a valid UUID \u2014 generating new UUID");}catch{c("getOrCreateConfigUuid",`corrupted JSON in ${e} \u2014 generating new UUID`);}}catch(n){n.code!=="ENOENT"&&c("getOrCreateConfigUuid",`read error: ${n.message}`);}return Ie__namespace.randomUUID()}function vt(e,n){let t=u__namespace.dirname(e);a__namespace.mkdirSync(t,{recursive:true});let r;try{let o=a__namespace.readFileSync(e,"utf8");try{r=JSON.parse(o),(!r.appliedId||typeof r.appliedId!="string")&&(r.appliedId=n),Array.isArray(r.entries)||(r.entries=[]);}catch{c("writeMetaJson",`corrupted JSON in ${e} \u2014 starting fresh`),r={appliedId:n,entries:[]};}}catch(o){o.code!=="ENOENT"&&c("writeMetaJson",`read error: ${o.message}`),r={appliedId:n,entries:[]};}r.entries.some(o=>o.id===n)||r.entries.push({id:n,name:f.CONFIG_NAME});let s=JSON.stringify(r,null,2)+`
10
+ `;try{if(a__namespace.readFileSync(e,"utf8")===s)return}catch{}if(a__namespace.existsSync(e)){a__namespace.copyFileSync(e,e+".bkp");try{a__namespace.chmodSync(e+".bkp",384);}catch{}}a__namespace.writeFileSync(e,s,{encoding:"utf8",mode:384});try{a__namespace.chmodSync(e,384);}catch{}}function Ct(e,n,t,r){a__namespace.mkdirSync(e,{recursive:true});let s=u__namespace.resolve(e),o=u__namespace.resolve(e,`${n}.json`);if(!o.startsWith(s+u__namespace.sep))throw new Error(`Security error: invalid config path ${o}`);let i={};try{let _=a__namespace.readFileSync(o,"utf8");try{i=JSON.parse(_);}catch{c("writeConfigLibraryFile",`corrupted JSON in ${o} \u2014 starting fresh`);}}catch(_){_.code!=="ENOENT"&&c("writeConfigLibraryFile",`read error: ${_.message}`);}i[f.KEYS.OTLP_ENDPOINT]=t,i[f.KEYS.OTLP_PROTOCOL]=f.OTLP_PROTOCOL,i[f.KEYS.OTLP_HEADERS_HELPER]=ve()?yt(r):r,i[f.KEYS.OTLP_RESOURCE_ATTRIBUTES]={[f.CUSTOM_PROVIDER_KEY]:f.CUSTOM_PROVIDER_VALUE};let g=JSON.stringify(i,null,2)+`
11
+ `;try{if(a__namespace.readFileSync(o,"utf8")===g)return o}catch{}if(a__namespace.existsSync(o)){a__namespace.copyFileSync(o,o+".bkp");try{a__namespace.chmodSync(o+".bkp",384);}catch{}}a__namespace.writeFileSync(o,g,{encoding:"utf8",mode:384});try{a__namespace.chmodSync(o,384);}catch{}return o}function kt(e){let n=u__namespace.dirname(e);a__namespace.mkdirSync(n,{recursive:true});let t={};try{let r=a__namespace.readFileSync(e,"utf8");try{t=JSON.parse(r);}catch{c("mergeClaudeDesktopConfig",`corrupted JSON in ${e} \u2014 starting fresh (original backed up to .bkp)`);}}catch(r){r.code!=="ENOENT"&&c("mergeClaudeDesktopConfig",`read error: ${r.message}`);}if(t.deploymentMode!==f.DEPLOYMENT_MODE){if(a__namespace.existsSync(e)){a__namespace.copyFileSync(e,e+".bkp");try{a__namespace.chmodSync(e+".bkp",384);}catch{}}t.deploymentMode=f.DEPLOYMENT_MODE,a__namespace.writeFileSync(e,JSON.stringify(t,null,2)+`
12
+ `,{encoding:"utf8",mode:384});try{a__namespace.chmodSync(e,384);}catch{}}}function ke(e,n){if(!St())return {configured:false};let t=Ce(),r=S().OTEL_ENDPOINT,s=W()??Ot(ae()),o=Rt(s),i=It(t.metaPath),g=Ct(t.configLibraryDir,i,r,o);return vt(t.metaPath,i),kt(t.desktopConfigPath),{configured:true,configDir:t.configDir,configLibraryPath:g,uuid:i,wrapperScriptPath:o}}y();var ce;function De(){return ce||(ce=Ne()),ce}var Fe=u__namespace.default.join(O__namespace.default.tmpdir(),"flow-obs-update-cache.json"),xt=1440*60*1e3,Mt=3e3;function $t(e,n){let t=o=>{let i=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return i?[+i[1],+i[2],+i[3]]:null},r=t(e),s=t(n);return !r||!s?false:s[0]!==r[0]?s[0]>r[0]:s[1]!==r[1]?s[1]>r[1]:s[2]>r[2]}function Ht(){try{let e=JSON.parse(a__namespace.default.readFileSync(Fe,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=xt?null:e}catch{return null}}function Yt(e,n,t=Date.now()){try{a__namespace.default.writeFileSync(Fe,JSON.stringify({latestVersion:e,updatePriority:n??null,checkedAt:t}),{mode:384});}catch{}}function Kt(e){let n=De().name,t=Dt__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(n)}/latest`,{timeout:Mt},r=>{if(r.statusCode!==200)return r.resume(),e(new Error(`HTTP ${r.statusCode}`));let s="";r.setEncoding("utf8"),r.on("data",o=>{s+=o;}),r.on("end",()=>{try{let o=JSON.parse(s);if(typeof o.version!="string")throw new Error("no version field");e(null,{version:o.version,updatePriority:typeof o.updatePriority=="string"?o.updatePriority:null});}catch(o){e(o);}});});t.on("error",e),t.on("timeout",()=>{t.destroy(new Error("timeout"));});}function be(){try{if(Ht())return;setImmediate(()=>{Kt((e,n)=>{e||!n||$t(De().version,n.version)&&Yt(n.version,n.updatePriority,0);});});}catch{}}var jt=u__namespace.default.resolve(__dirname,".."),Wt=process.env.INIT_CWD?u__namespace.default.resolve(process.env.INIT_CWD):null;Wt===jt&&process.exit(0);ne()&&(process.stderr.write(`
8
13
  [flow-ai-obs] \u2717 Do not install with sudo.
9
14
  Run without sudo: npm install -g @ciandt-flow/flow-ai-obs
10
15
 
11
- `),process.exit(1));async function St(){try{pe();}catch{}try{Te();}catch{}let e=await se();if(!e){process.stderr.write(`
16
+ `),process.exit(1));async function Vt(){try{ye();}catch{}try{we();}catch{}try{ke();}catch{}let e=await de();if(!e){process.stderr.write(`
12
17
  [flow-ai-obs] No credentials found.
13
18
  Run \`flow-ai-obs login\` to authenticate and enable telemetry.
14
19
 
15
- `);return}let t=Ee(process.env[d.ANTHROPIC_AUTH_TOKEN]);if(!t||t.clientId!==e.clientId||t.clientSecret!==e.clientSecret||t.tenant!==e.tenant)try{let r=ge(e);Z({[d.ANTHROPIC_AUTH_TOKEN]:r});}catch{}}St().catch(()=>{}).finally(()=>Re());
20
+ `);return}let n=Ae(process.env[h.ANTHROPIC_AUTH_TOKEN]);if(!n||n.clientId!==e.clientId||n.clientSecret!==e.clientSecret||n.tenant!==e.tenant)try{let r=Re(e);oe({[h.ANTHROPIC_AUTH_TOKEN]:r});}catch{}}Vt().catch(()=>{}).finally(()=>be());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ciandt-flow/flow-ai-obs",
3
- "version": "0.14.0",
3
+ "version": "0.15.0-beta.87",
4
4
  "description": "Claude Code hooks for Langfuse OTLP tracing — cross-platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {