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