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