@ciandt-flow/flow-ai-obs 0.9.3-beta.728 → 0.9.3-beta.752
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +196 -188
- package/dist/index.js +15 -14
- package/dist/setup.js +5 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
'use strict';var child_process=require('child_process'),util=require('util'),
|
|
2
|
-
`;try{
|
|
3
|
-
`);}}var
|
|
4
|
-
`)[0].slice(0,e).trim()}function
|
|
5
|
-
`);for(let
|
|
6
|
-
`),
|
|
1
|
+
'use strict';var child_process=require('child_process'),util=require('util'),y=require('fs'),st=require('os'),W=require('path'),ln=require('https'),un=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 y__namespace=/*#__PURE__*/_interopNamespace(y);var st__namespace=/*#__PURE__*/_interopNamespace(st);var W__namespace=/*#__PURE__*/_interopNamespace(W);var ln__default=/*#__PURE__*/_interopDefault(ln);var un__default=/*#__PURE__*/_interopDefault(un);var je=Object.defineProperty;var ft=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var dt=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var wt=(t,e)=>{for(var n in e)je(t,n,{get:e[n],enumerable:true});};function B(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():Ye}function H(){let t=B();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${t}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${t}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${t}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${t}/otel`}}function z(){let t=B();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ye,dr,mt,gt,St,kt,m,Vt,w,Gt,R,T=dt(()=>{"use strict";Ye="https://flow.ciandt.com";dr=H(),mt={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},gt="FLOW-nodejs",St="config.json",kt={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},m={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP",FLOW_OBS_USE_JSON_VAULT:"FLOW_TELEMETRY_USE_JSON_VAULT",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES",FLOW_USER_EMAIL:"FLOW_USER_EMAIL",OTEL_EXPORTER_OTLP_HEADERS:"OTEL_EXPORTER_OTLP_HEADERS"},Vt={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},w={FILE_PREFIX:"flow-obs-buffer-",DEFAULT_TTL_DAYS:4,MIN_TTL_DAYS:1,MAX_TTL_DAYS:30,DEFAULT_MAX_FILES:50,MIN_MAX_FILES:1,MAX_MAX_FILES:500,REPLAY_BATCH_SIZE:10},Gt="flow-ai-obs-debug.log",R={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};});var Yt={};wt(Yt,{MacOsKeyVaultProvider:()=>vt});var It,vt,Jt=dt(()=>{"use strict";It=util.promisify(child_process.execFile),vt=class{static async isAvailable(){try{return y.accessSync("/usr/bin/security",y.constants.X_OK),!0}catch{return !1}}async getSecret(e,n){try{let{stdout:r}=await It("security",["find-generic-password","-w","-a",n,"-s",e]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await It("security",["add-generic-password","-U","-a",n,"-s",e,"-w",r]);}async deleteSecret(e,n){try{return await It("security",["delete-generic-password","-a",n,"-s",e]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var qt={};wt(qt,{LinuxKeyVaultProvider:()=>Pt});var Kt,Pt,Xt=dt(()=>{"use strict";Kt=util.promisify(child_process.execFile),Pt=class{static async isAvailable(){let e=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let n of e)try{return y.accessSync(n,y.constants.X_OK),!0}catch{}return !1}async getSecret(e,n){try{let{stdout:r}=await Kt("secret-tool",["lookup","service",e,"account",n]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await new Promise((o,s)=>{let i=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",n]);i.on("error",s),i.on("close",l=>{l===0?o():s(new Error(`secret-tool exited with code ${l}`));}),i.stdin.write(r),i.stdin.end();});}async deleteSecret(e,n){try{return await Kt("secret-tool",["clear","service",e,"account",n]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var zt={};wt(zt,{WindowsKeyVaultProvider:()=>Nt});var Nt,Zt=dt(()=>{"use strict";Nt=class{static async isAvailable(){try{return await ft("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,n){return ft("keytar").getPassword(e,n)}async setSecret(e,n,r){await ft("keytar").setPassword(e,n,r);}async deleteSecret(e,n){return ft("keytar").deletePassword(e,n)}getStoragePath(){return "Windows Credential Manager"}};});T();T();var Rt={credentials:"credentials","token-cache":"tokenCache"};function Z(){let t=st__namespace.default.homedir();if(process.platform==="darwin")return W__namespace.default.join(t,"Library","Preferences",gt,St);if(process.platform==="win32"){let n=process.env.APPDATA??W__namespace.default.join(t,"AppData","Roaming");return W__namespace.default.join(n,gt,St)}let e=process.env.XDG_CONFIG_HOME??W__namespace.default.join(t,".config");return W__namespace.default.join(e,gt,St)}function Lt(){try{let t=y__namespace.default.readFileSync(Z(),"utf8");return JSON.parse(t)}catch{return {}}}function jt(t){let e=Z();y__namespace.default.mkdirSync(W__namespace.default.dirname(e),{recursive:true}),y__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var tt=class{static isAvailable(){return true}static hasExistingData(){try{if(!y__namespace.default.existsSync(Z()))return !1;let e=JSON.parse(y__namespace.default.readFileSync(Z(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,n){let r=Lt(),o=Rt[n]??n,s=r[o];return s?typeof s=="string"?s:JSON.stringify(s):null}async setSecret(e,n,r){let o=Lt(),s=Rt[n]??n;if(n==="token-cache")try{o[s]=JSON.parse(r);}catch{o[s]=r;}else o[s]=r;jt(o);}async deleteSecret(e,n){let r=Lt(),o=Rt[n]??n;return o in r?(delete r[o],jt(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${Z()}`}};async function Qt(){return process.env[m.FLOW_OBS_USE_JSON_VAULT]==="1"?new tt:await rn()??new tt}async function rn(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Jt(),Yt));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Xt(),qt));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Zt(),zt));return await t.isAvailable()?new t:null}default:return null}}T();var te=mt.SERVICE;mt.ACCOUNT_CREDS;var ee=mt.ACCOUNT_TOKEN,bt=null;function ne(){return bt||(bt=Qt()),bt}async function Ut(t){await(await ne()).setSecret(te,ee,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function Ct(){let e=await(await ne()).getSecret(te,ee);if(!e)return null;try{let n=JSON.parse(e);return {accessToken:n.accessToken,expiresAt:n.expiresAt,lastAuthCheckAt:n.lastAuthCheckAt}}catch{return null}}async function et(){let t=await Ct();if(!t||!t.accessToken)return null;try{let e=t.accessToken.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email??n.preferred_username??n.upn??n.sub??null}catch{return null}}T();T();var cn=W.join(st.tmpdir(),Gt);function a(...t){if(process.env[m.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
|
|
2
|
+
`;try{y.writeFileSync(cn,e,{flag:"a"});}catch(n){process.stderr.write(`[flow-obs debug ERROR] ${n.message}
|
|
3
|
+
`);}}var U=class extends Error{constructor(e){super(e),this.name="AuthError";}},pn=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function fn(t){if(!pn.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var re={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 dn(t,e){let n=e.length>400?e.slice(0,400)+"\u2026":e;a("toAuthError",`status=${t} body=${n}`);try{let r=JSON.parse(e);if(typeof r.error=="string"&&(a("toAuthError",`api_error_code=${r.error}`+(r.message?` api_message=${r.message}`:"")),re[r.error]))return new U(re[r.error])}catch{}return t===401||t===403||t===500?new U("Invalid credentials"):t>=400&&t<500?new U("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function V(t){return new Promise((e,n)=>{try{fn(t.tenant);}catch(u){return n(u)}let r=JSON.stringify({clientSecret:t.clientSecret}),o=new URL(H().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(r),FlowTenant:t.tenant}};a("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let c=(s?ln__default.default:un__default.default).request(i,u=>{let S=[];u.on("data",E=>S.push(E)),u.on("end",()=>{let E=S.join("");if((u.statusCode??0)>=400)return n(dn(u.statusCode??0,E));let h;try{h=JSON.parse(E);}catch{return n(new Error("Invalid response from auth engine"))}let g=h.expires_at??new Date(Date.now()+(h.expires_in??3600)*1e3).toISOString();e({accessToken:h.access_token??"",expiresAt:g});});});c.on("error",u=>n(new Error(`Network error: ${u.message}`))),c.write(r),c.end();})}T();var gn=[/^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 Sn(t){return gn.some(e=>e.test(t))}function En(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}function Et(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:o,tenant:s}=n;return !r||!o||!s?null:{clientId:r,clientSecret:o,tenant:s}}catch{return null}}function nt(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let n=process.env[m.FLOW_OBS_ALLOW_HTTP]==="true";if(!n&&e.protocol!=="https:")throw new Error(`URL must use HTTPS: ${t}`);if(e.username||e.password)throw new Error(`URL must not contain embedded credentials: ${t}`);if(!n&&Sn(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function ie(){let t=Et(process.env[m.ANTHROPIC_AUTH_TOKEN]);return t?{user:await et().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function hn(){return new Date().toISOString().slice(0,10)}async function _n(t){let e=hn(),n=await Ct();if(n?.lastAuthCheckAt!==e){a("getOrRefreshToken",`daily auth check (last: ${n?.lastAuthCheckAt??"never"})`);try{let s=await V(t);try{await Ut({...s,lastAuthCheckAt:e});}catch{}return a("getOrRefreshToken",`daily check passed, expires=${s.expiresAt}`),s.accessToken}catch(s){if(s instanceof U)throw s;a("getOrRefreshToken",`daily check network error \u2014 using cache: ${s.message}`);}}let r=n!=null&&new Date(n.expiresAt)>new Date;if(a("getOrRefreshToken",`cacheValid=${r}`),r)return a("getOrRefreshToken",`using cached token, expires=${n.expiresAt}`),n.accessToken;a("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let o=await V(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 Tn(t,e){let n=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${n}`}}function yn(t,e,n){let r=Buffer.from(`${e}:${n}`).toString("base64");return {endpoint:t.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${r}`}}async function C(){let t=[],e=process.env[m.ANTHROPIC_MODEL]??"",n=Et(process.env[m.ANTHROPIC_AUTH_TOKEN]);a("resolveCredentials",n?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),n&&a("resolveCredentials",`clientId=${n.clientId}`,`tenant=${n.tenant}`);let r=n?n.tenant:"",o=process.env[m.FLOW_TELEMETRY]==="true",s=process.env[m.LANGFUSE_BASE_URL],i=process.env[m.LANGFUSE_PUBLIC_KEY],l=process.env[m.LANGFUSE_SECRET_KEY];if(o&&s&&i&&l){let h="",g=r;n&&(h=await et().catch(()=>null)??n.clientId);let _={user:h??"",tenant:g??"",team:"",project:"",model:e};t.push({mode:"direct",...yn(nt(s),i,l),..._}),a("resolveCredentials","direct mode active",`user=${_.user}`,`tenant=${_.tenant}`);}if(!n){if(t.length===0){let h=[];return h.authError=false,h}return t}let c;try{c=await _n(n);}catch(h){if(a("resolveCredentials",`token refresh failed: ${h.message}`,`(tenant=${n.tenant} clientId=${n.clientId})`),t.length>0)return t.authError=true,t;let g=[];return g.authError=true,g}let S={user:En(c)??n.clientId,tenant:r,team:"",project:"",model:e},E=process.env[m.FLOW_TELEMETRY_GATEWAY]??B();return t.push({mode:"gateway",...Tn(nt(E),{accessToken:c}),...S}),t}async function ht(){return (await C()).length>0}var se=false,oe=false;function ae(){let t=process.env[m.FLOW_USER_EMAIL];if(t){let e=t.replace(/[\r\n]/g,"").trim();return e?(a("resolveUserEmail","using FLOW_USER_EMAIL override: [REDACTED]"),e):null}try{let e=st__namespace.default.userInfo().username||process.env.USERNAME||process.env.USER||"",n=e.lastIndexOf("\\");if(n!==-1&&(e=e.slice(n+1)),e=e.trim().replace(/[^a-zA-Z0-9._%+\-]/g,""),!e)return a("resolveUserEmail","username empty after sanitisation \u2014 omitting x-flow-user"),se||(se=!0,console.warn("[flow-ai-obs] Could not derive x-flow-user: username is empty. Set FLOW_USER_EMAIL to fix this.")),null;let r=`${e}@ciandt.com`;return a("resolveUserEmail","derived email: [REDACTED]"),r}catch(e){return a("resolveUserEmail",`os.userInfo() threw: ${e.message} \u2014 omitting x-flow-user`),oe||(oe=true,console.warn("[flow-ai-obs] Could not derive x-flow-user from OS username. Set FLOW_USER_EMAIL to fix this.")),null}}function An(t){let e=process.env.OTEL_EXPORTER_OTLP_HEADERS;if(!e)return null;for(let n of e.split(",")){let r=n.indexOf("=");if(!(r<=0)&&n.slice(0,r).trim().toLowerCase()===t.toLowerCase())return n.slice(r+1).replace(/[\r\n]/g,"").trim()||null}return null}function ce(){return An("x-flow-api-key")}function L(t,e){let n=typeof t=="object"?JSON.stringify(t):String(t??"");return n.length>e?n.slice(0,e)+" \u2026[truncated]":n}function _t(t,e=100){return String(t??"").split(`
|
|
4
|
+
`)[0].slice(0,e).trim()}function rt(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n;}),process.stdin.on("end",()=>{try{t(JSON.parse(e));}catch{t({});}});})}function k(t){process.stdout.write(JSON.stringify(t));}var Ft=()=>crypto.randomBytes(16).toString("hex"),F=()=>crypto.randomBytes(8).toString("hex");function I(){return String(BigInt(Date.now())*1000000n)}var Nn=/^[0-9a-f-]{1,64}$/i,bn=W.normalize(st.tmpdir())+W.sep;function Un(t,e){let n=W.resolve(t);if(!n.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return n}function $t(t){if(!Nn.test(t))throw new Error(`Invalid session ID: ${t}`);return Un(W.join(st.tmpdir(),`flow-obs-${t}.json`),bn)}function G(t){let e=$t(t);if(!y.existsSync(e))return null;try{return JSON.parse(y.readFileSync(e,"utf8"))}catch{return null}}function j(t,e){y.writeFileSync($t(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function Dt(t){try{y.unlinkSync($t(t));}catch{}}function de(t){if(!t||!y.existsSync(t))return null;try{let e=y.readFileSync(t,"utf8").trimEnd().split(`
|
|
5
|
+
`);for(let n=e.length-1;n>=0;n--)try{let r=JSON.parse(e[n]);if(r.type==="user"&&r.uuid)return r.uuid}catch{}}catch{}return null}function xt(t){if(!t||!y.existsSync(t))return null;try{let e=y.readFileSync(t,"utf8").trimEnd().split(`
|
|
6
|
+
`),n=[],r=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(S=>S.type==="text").map(S=>S.text??"").join("");c&&n.unshift(c);let u=i.message?.usage??{};r+=(u.input_tokens??0)+(u.cache_read_input_tokens??0)+(u.cache_creation_input_tokens??0),o+=u.output_tokens??0;}}catch{}return !n.length&&r===0?null:{text:n.join(`
|
|
7
7
|
|
|
8
|
-
`),inputTokens:
|
|
9
|
-
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
${
|
|
13
|
-
${
|
|
14
|
-
`
|
|
15
|
-
`),process.stdin.on("data",e=>process.stdout.write(e));}}
|
|
8
|
+
`),inputTokens:r,outputTokens:o}}catch{}return null}var Dn=new Set([".venv","__pycache__",".git","node_modules"]),xn=new Set([".pyc",".pyo"]),Mn=new Set(["SKILL.md",".DS_Store",".gitignore"]);function Se(t){return t.replace(":","/")}function Tt(t,e){if(!t)return null;let n=Se(t),r=[W.join(st.homedir(),".claude","skills",n,"SKILL.md"),W.join(e??"",".claude","skills",n,"SKILL.md")];for(let o of r)if(y.existsSync(o))try{return y.readFileSync(o,"utf8")}catch{}return null}function Ee(t){return t.split(`
|
|
9
|
+
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var Bn=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function he(t){return !!t.slashSkill||t.toolCalls.some(r=>r.tool==="Skill")?t.toolCalls.some(r=>r.tool==="Skill"&&!r.synthetic||Bn.has(r.tool))?"complete":"prerequisite_required":null}function yt(t,e){if(!t)return null;let n=Se(t),r=[W.join(st.homedir(),".claude","skills",n),W.join(e??"",".claude","skills",n)],o=null;for(let l of r)if(y.existsSync(W.join(l,"SKILL.md"))){o=l;break}if(!o)return null;let s=[];function i(l,c){for(let u of y.readdirSync(l,{withFileTypes:true})){if(Dn.has(u.name)||Mn.has(u.name)||xn.has(W.extname(u.name)))continue;let S=c?`${c}/${u.name}`:u.name;u.isDirectory()?i(W.join(l,u.name),S):s.push(S);}}return i(o,""),s.length>0?s:null}T();T();!process.env.NO_COLOR&&process.stdout.isTTY;function At(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.USERPROFILE;if(!t){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(t=n);}if(t){let e=t.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return W__namespace.join(e,".claude","settings.json")}return W__namespace.join(st__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||st__namespace.homedir();return W__namespace.join(t,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return W__namespace.join(e,".claude","settings.json")}return W__namespace.join(st__namespace.homedir(),".claude","settings.json")}var Gn=Vt.LOCK_STALE_MS;function jn(t){try{let e=y__namespace.statSync(t);Date.now()-e.mtimeMs>Gn&&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 Yn(t){try{y__namespace.unlinkSync(t);}catch{}}function ye(t){try{let e=y__namespace.readFileSync(At(),"utf8"),r=JSON.parse(e).env?.[t];return typeof r=="string"?r:null}catch{return null}}function Ae(t){let e=At(),n=e+".lock";y__namespace.mkdirSync(W__namespace.dirname(e),{recursive:true}),jn(n);try{let r={};try{r=JSON.parse(y__namespace.readFileSync(e,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,t),y__namespace.writeFileSync(e,JSON.stringify(r,null,2)+`
|
|
10
|
+
`,{encoding:"utf8",mode:384});try{y__namespace.chmodSync(e,384);}catch{}}finally{Yn(n);}}T();function qn(t){try{let e=t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(e,"base64").toString())}catch{return null}}function Oe(t,e,n,r,o,s){return new Promise(i=>{let l=new URL(t),c=l.protocol==="https:",u=E=>E.replace(/[\r\n]/g,""),S=(c?ln__default.default:un__default.default).request({hostname:l.hostname,port:l.port||(c?443:80),path:l.pathname+l.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(e),...s?{}:{Authorization:`Bearer ${u(String(n))}`},FlowTenant:u(String(r)),...o?{"x-flow-user":u(o)}:{},...s?{"x-flow-api-key":u(s)}:{}}},E=>{E.resume(),i(E.statusCode??0);});S.on("error",()=>i(0)),S.setTimeout(5e3,()=>{S.destroy(),i(0);}),S.write(e),S.end();})}async function $(t,e={}){try{let n=ae(),r=ce(),o=Et(process.env[m.ANTHROPIC_AUTH_TOKEN]);if(r){let g=JSON.stringify({action:t,booster:z().BOOSTER,metadata:e,success:!0,tenant:"",timestamp:new Date().toISOString(),os:process.platform,user:{email:n||"",id:"",name:n||""}}),_=nt(z().API_URL),A=await Oe(_,g,"","",n,r);a("metrics.logEvent",`action=${t} status=${A} x-flow-user=${n?"[REDACTED]":"omitted"} x-flow-api-key=[REDACTED]`);return}if(!o)return;let s,i=new Promise((g,_)=>{s=setTimeout(()=>_(new Error("getToken timeout")),4e3),s.unref();}),{accessToken:l}=await Promise.race([V(o),i]);clearTimeout(s);let c=qn(l);if(!c)return;let u=c.tenant||o.tenant,S=JSON.stringify({action:t,booster:z().BOOSTER,metadata:e,success:!0,tenant:u,timestamp:new Date().toISOString(),os:process.platform,user:{email:c.email||"",id:c.sub||"",name:c.name||c.email||""}}),E=nt(z().API_URL),h=await Oe(E,S,l,u,n,r);a("metrics.logEvent",`action=${t} status=${h} x-flow-user=${n?"[REDACTED]":"omitted"} x-flow-api-key=${r?"[REDACTED]":"omitted"}`);}catch(n){a("metrics.logEvent",`silenced error: ${n.message}`);}}var Xn=`\u26D4 Your Flow API key has expired. You no longer have access to Claude Code through the Flow platform. To restore observability and access, visit ${B()}/settings/api-keys to generate a new API key, then run: flow-ai-obs login`;async function Mt(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:Xn})+`
|
|
11
|
+
`);return}let r=!!(await C()).authError;!process.env[m.FLOW_USER_EMAIL]&&!ye(m.FLOW_USER_EMAIL)&&et().then(E=>{E&&(Ae({[m.FLOW_USER_EMAIL]:E}),a("UserPromptSubmit","auto-persisted FLOW_USER_EMAIL from access token"));}).catch(()=>{});let o=t.session_id||"unknown",s=t.prompt||"",i=t.cwd||"",l=de(t.transcript_path)||Ft(),c=Ee(s),u=c?Tt(c,i):null,S=c?yt(c,i):null;j(o,{traceId:Ft(),spanId:F(),startNs:I(),sessionId:o,prompt:s,cwd:i,traceName:l,transcriptPath:t.transcript_path||"",model:process.env[m.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:c,skillContent:u,skillArtifacts:S}),$("SESSION_STARTED",{traceType:c?"skill":"prompt",slashSkill:c,clientIdExpired:r}),a("UserPromptSubmit",`sid=${o}`,`traceName=${l}`,`slashSkill=${c}`),k(t);}T();async function we(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},o=G(e);o&&(o.pendingTool={name:n,inputStr:L(r,R.TOOL_INPUT),startNs:I()},j(e,o)),a("PreToolUse",`sid=${e}`,`tool=${n}`,`stateFound=${!!o}`),k(t);}T();var zn={name:kt.SCOPE_NAME,version:kt.SCOPE_VERSION},d={TRACE_NAME:"langfuse.trace.name",TRACE_INPUT:"langfuse.trace.input",TRACE_OUTPUT:"langfuse.trace.output",TRACE_METADATA:"langfuse.trace.metadata",TRACE_TAGS:"langfuse.trace.tags",USER_ID:"langfuse.user.id",SESSION_ID:"langfuse.session.id",OBS_NAME:"langfuse.observation.name",OBS_INPUT:"langfuse.observation.input",OBS_OUTPUT:"langfuse.observation.output",OBS_LEVEL:"langfuse.observation.level",OBS_TYPE:"langfuse.observation.type",MODEL:"gen_ai.request.model",INPUT_TOKENS:"gen_ai.usage.input_tokens",OUTPUT_TOKENS:"gen_ai.usage.output_tokens"};function p(t,e){return e==null||e===""?null:{key:t,value:{stringValue:String(e)}}}function D(...t){return t.filter(e=>e!==null)}function ke(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:zn,spans:Array.isArray(e)?e:[e]}]}]}}T();var Re=W.join(st.tmpdir(),"flow-obs-requests.ndjson");function Le(t,e,n,r,o){if(process.env[m.FLOW_OBS_DEBUG]!=="1")return;let s=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(n)},response:{status:r,body:o}});try{y.writeFileSync(Re,s+`
|
|
12
|
+
`,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${Re}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function rr(t){let e=new URL(t),n=new URL(H().GATEWAY_HEALTH);return n.hostname=e.hostname,n.port=e.port,n.protocol=e.protocol,n}function Ie(t,e){return new Promise((n,r)=>{let o=t._isSSL?ln__default.default:un__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",()=>n({statusCode:i.statusCode??0,body:l.join("")}));});s.setTimeout(1e4,()=>{s.destroy(new Error("Request timeout"));}),s.on("error",i=>r(new Error(`Network error: ${i.message}`))),e&&s.write(e),s.end();})}async function ve(t,e){let n;try{n=rr(t);}catch{return false}let r=n.protocol==="https:";try{let o={};e&&(o.Authorization=String(e).replace(/[\r\n]/g,""));let s=await Ie({hostname:n.hostname,port:n.port||(r?443:80),path:n.pathname,method:"GET",headers:o,_isSSL:r},null);return a("checkHealth",`url=${n.href} status=${s.statusCode}`),s.statusCode>=200&&s.statusCode<300}catch{return false}}async function Ot(t,e,n){let r=JSON.stringify(t),o=new URL(e),s=o.protocol==="https:",i=String(n).replace(/[\r\n]/g,""),l={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(r)};a("sendTraces:request",`POST ${e}`),a("sendTraces:request",`headers=${JSON.stringify({...l,Authorization:i.slice(0,20)+"\u2026"})}`),a("sendTraces:request",`body=${r.slice(0,500)}${r.length>500?"\u2026":""}`);try{let c=await Ie({hostname:o.hostname,port:o.port||(s?443:80),path:o.pathname,method:"POST",headers:l,_isSSL:s},r);return a("sendTraces:response",`status=${c.statusCode}`),Le(e,l,r,c.statusCode,c.body),c.statusCode}catch(c){return a("sendTraces:error",c.message),Le(e,l,r,0,c.message),0}}T();function sr(){let t=parseInt(process.env[m.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(w.MIN_TTL_DAYS,Math.min(w.MAX_TTL_DAYS,t)):w.DEFAULT_TTL_DAYS)*24*60*60*1e3}function or(){let t=parseInt(process.env[m.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(w.MIN_MAX_FILES,Math.min(w.MAX_MAX_FILES,t)):w.DEFAULT_MAX_FILES}function Ne(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return W__namespace.default.join(st__namespace.default.tmpdir(),`${w.FILE_PREFIX}${t}.json`)}function Ht(){let t=st__namespace.default.tmpdir(),e;try{e=y__namespace.default.readdirSync(t);}catch{return []}return e.filter(n=>n.startsWith(w.FILE_PREFIX)&&n.endsWith(".json")).map(n=>{let r=W__namespace.default.join(t,n),o=0;try{o=y__namespace.default.statSync(r).mtimeMs;}catch{}return {full:r,mtime:o}}).sort((n,r)=>n.mtime-r.mtime).map(n=>n.full)}function ot(t){try{let e=or(),n=Ht();if(n.length>=e){let s=n.slice(0,n.length-e+1);for(let i of s)try{y__namespace.default.unlinkSync(i);}catch{}}let r=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,o={fileId:r,bufferedAt:Date.now(),payload:t};return y__namespace.default.writeFileSync(Ne(r),JSON.stringify(o),{encoding:"utf8",mode:384}),a("buffer",`saved fileId=${r}`),r}catch(e){return a("buffer",`saveToBuffer failed: ${e.message}`),null}}function be(t){let e=Ht(),n=t!=null&&t>0?t:e.length,r=[];for(let o of e){if(r.length>=n)break;try{let s=y__namespace.default.readFileSync(o,"utf8"),i=JSON.parse(s);i&&i.fileId&&i.payload&&r.push(i);}catch{a("buffer",`skipping malformed file: ${o}`);}}return r}function Ue(t){try{y__namespace.default.unlinkSync(Ne(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function Ce(){let t=Date.now()-sr();for(let e of Ht())try{let{mtimeMs:n}=y__namespace.default.statSync(e);n<t&&(y__namespace.default.unlinkSync(e),a("buffer",`evicted stale: ${W__namespace.default.basename(e)}`));}catch{}}T();async function ir(t){Ce();let e=be(w.REPLAY_BATCH_SIZE);e.length&&(a("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async n=>{try{let r=await Ot(n.payload,t.endpoint,t.authHeader);r>=200&&r<300?(Ue(n.fileId),a("replayBufferedTraces",`replayed fileId=${n.fileId} status=${r}`)):a("replayBufferedTraces",`replay failed fileId=${n.fileId} status=${r}`);}catch(r){a("replayBufferedTraces",`replay error fileId=${n.fileId}: ${r.message}`);}})));}async function Fe(t){let e=await C();if(!e.length)return e.authError&&(a("postToLangfuse","auth refresh failed \u2014 buffering trace"),ot(t)),0;let n=await Promise.all(e.map(async s=>{if(s.mode!=="gateway")return {creds:s,healthy:true};let i=await ve(s.endpoint,s.authHeader);return {creds:s,healthy:i}})),r=n.find(s=>s.creds.mode==="gateway"&&s.healthy)?.creds??n.find(s=>s.creds.mode==="direct")?.creds;return r&&await ir(r),(await Promise.all(n.map(async({creds:s,healthy:i})=>{if(s.mode==="gateway"){if(!i)return a("postToLangfuse","gateway health check failed \u2014 buffering trace"),ot(t),0;let c=await Ot(t,s.endpoint,s.authHeader);return (c===0||c>=500)&&(a("postToLangfuse",`gateway send failed (status ${c}) \u2014 buffering trace`),ot(t)),c}let l=await Ot(t,s.endpoint,s.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${l}) \u2014 buffering trace`),ot(t)),l}))).find(s=>s!==0)??0}T();var O="[REDACTED]",ar="[REDACTED-EMAIL]",cr="[REDACTED-CPF]",lr="[REDACTED-CNPJ]",$e="[REDACTED-PHONE]",ur=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${O}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${O}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${O}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${O}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,n)=>`${e}
|
|
13
|
+
${O}
|
|
14
|
+
${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${O}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${O}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${O}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${O}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${O}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(t,e,n)=>`${e}${n}${O}${n}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${O}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>ar},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>cr},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>lr},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>$e},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>$e}];function P(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return ur.reduce((n,{re:r,replace:o})=>n.replace(r,o),e)}async function De(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},o=t.tool_response,s=o!==null&&typeof o=="object"?o.output??JSON.stringify(o):o??"",i=G(e);if(!i){k(t);return}let l=I(),c=i.pendingTool,u=c?.name===n,S=u?c.startNs:String(BigInt(l)-200000000n),E=u?c.inputStr:L(r,R.TOOL_INPUT),h=E,g=null;if(n==="Skill"){let pt=typeof r=="object"&&r!==null?r.skill||r.name||r.skillName||r.commandName||String(Object.values(r)[0]??""):String(r);g=pt?String(pt).trim():null;let N=g?Tt(g,i.cwd):null;N&&(h=N,i.skillContent||(i.skillContent=N),i.skillArtifacts||(i.skillArtifacts=yt(g,i.cwd))),g&&!i.slashSkill&&(i.slashSkill=g),a("PostToolUse","Skill tool detected",`skillName=${g}`,`contentFound=${!!N}`);}let _=P(L(s,R.TOOL_OUTPUT)),A=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(_.slice(0,500)),it=A?"ERROR":"DEFAULT",q=F(),at=Math.round(Number(BigInt(l)-BigInt(S))/1e6),lt={Agent:"AGENT",Task:"AGENT"}[n]??"TOOL",ut=n==="Skill"&&g?g:_t(E,60);i.toolCalls.push({tool:n,brief:ut,error:A,durationMs:at});let X=i.spans;X.push({traceId:i.traceId,spanId:q,parentSpanId:i.spanId,name:n,kind:3,startTimeUnixNano:S,endTimeUnixNano:l,attributes:D(p(d.OBS_NAME,n),p(d.OBS_TYPE,lt),p(d.OBS_LEVEL,it),p(d.OBS_INPUT,P(h)),p(d.OBS_OUTPUT,_),p("tool.name",n),p("tool.error",String(A)),n==="Skill"&&g?p("skill.name",g):null,n==="Skill"?p("skill.invocation","slash-command"):null),status:{code:A?2:1}}),i.pendingTool=null,j(e,i),A&&$("TOOL_ERROR",{toolName:n}),a("PostToolUse",`sid=${e}`,`tool=${n}`,`error=${A}`,`durationMs=${at}`,`totalSpans=${X.length}`),k(t);}var xe={"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 Me(t,e,n){let r=Object.keys(xe).find(i=>(t??"").toLowerCase().includes(i));if(!r)return;let o=xe[r],s=(e*o.input+n*o.output)/1e6;return Math.round(s*1e6)/1e6}T();async function Be(t){let e=t.session_id||"unknown",n=t.stop_reason||"end_turn",r=G(e);if(!r){k(t);return}r.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(r.slashSkill)&&(a("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${r.slashSkill}"`),r.slashSkill=null);let o=I(),s=await ie(),i=r.toolCalls,l=r.spans;if(r.slashSkill&&!i.some(f=>f.tool==="Skill")){let f=F(),b=r.skillContent?r.skillContent:JSON.stringify({skill:r.slashSkill});i.push({tool:"Skill",brief:r.slashSkill,error:false,durationMs:0,synthetic:true}),l.push({traceId:r.traceId,spanId:f,parentSpanId:r.spanId,name:"Skill",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:r.startNs,attributes:D(p(d.OBS_NAME,"Skill"),p(d.OBS_TYPE,"TOOL"),p(d.OBS_LEVEL,"DEFAULT"),p(d.OBS_INPUT,b),p(d.OBS_OUTPUT,"loaded via slash command"),p("tool.name","Skill"),p("tool.error","false"),p("skill.name",r.slashSkill),p("skill.invocation","slash-command")),status:{code:1}}),a("Stop",`slashSkill=${r.slashSkill}`,"synthetic span injected");}let c=t.transcript_path||r.transcriptPath||"",u=xt(c);if(c&&(i.some(f=>f.tool==="Skill"&&!f.synthetic)||!!r.slashSkill)&&!u?.text){await new Promise(b=>setTimeout(b,500));let f=xt(c);f?.text&&(u=f);}a("Stop",`transcriptPath=${c||"(empty)"}`,`assistantOut=${u?`text=${u.text.length}chars`:"null"}`);let E=i.length,h=i.filter(f=>f.error).length,g=P(u?.text?L(u.text,R.TRACE_OUTPUT):E===0?"No tools used":i.map((f,b)=>`${b+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""}`).join(`
|
|
15
|
+
`)),_=u?.inputTokens??0,A=u?.outputTokens??0,it=i.map((f,b)=>`${b+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""} (${f.durationMs}ms)`),q=!!(r.slashSkill||i.some(f=>f.tool==="Skill")),at=i.some(f=>f.tool==="Agent");if(!q&&!at){a("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),$("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),Dt(e),k(t);return}let ct=q?"skill":"agent",lt=Math.round(Number(BigInt(o)-BigInt(r.startNs))/1e6),ut=Me(r.model,_,A),M=he(r);M==="prerequisite_required"&&u?.text&&(M="complete"),M==="prerequisite_required"&&(l.push({traceId:r.traceId,spanId:F(),parentSpanId:r.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:o,attributes:D(p(d.OBS_NAME,"prerequisite-check"),p(d.OBS_TYPE,"EVENT"),p(d.OBS_LEVEL,"WARNING"),p(d.OBS_OUTPUT,g),p("skill.name",r.slashSkill||void 0),p("execution_status","prerequisite_required")),status:{code:1}}),a("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${r.slashSkill}`));let X=(()=>{if(!(!q||!r.prompt)){if(r.slashSkill){let f=r.prompt.replace(new RegExp(`^\\/${r.slashSkill}\\s*`,"i"),"").trim();return f?L(P(f),R.USER_INSTRUCTION):void 0}return L(P(r.prompt),R.USER_INSTRUCTION)||void 0}})(),pt=JSON.stringify({trace_type:ct,...M!==null&&{execution_status:M},...r.slashSkill?{skill_name:r.slashSkill}:{},...r.skillArtifacts?.length&&{skill_artifacts:r.skillArtifacts},...X!==void 0&&{user_instruction:X},latency_ms:lt,..._&&{tokens_input:_},...A&&{tokens_output:A},cost_usd:ut,...r.model?{model:r.model}:{},toolCount:E,errorCount:h,stopReason:n,sessionId:r.sessionId,tools:it.length?it:void 0}),N=P(L(r.prompt,R.TRACE_INPUT)),He=D(p(d.TRACE_NAME,r.traceName),p(d.TRACE_INPUT,N),p(d.TRACE_OUTPUT,g),p(d.OBS_INPUT,N),p(d.OBS_OUTPUT,g),p(d.TRACE_METADATA,pt),p(d.SESSION_ID,r.sessionId),p(d.USER_ID,s.user),p(d.OBS_TYPE,"GENERATION"),p(d.MODEL,r.model),_?p(d.INPUT_TOKENS,_):null,A?p(d.OUTPUT_TOKENS,A):null,p("claude.stop_reason",n),p("claude.tool_count",String(E)),p("claude.error_count",String(h)),p("claude.session_id",r.sessionId),p("flow.trace_type",ct),{key:d.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:ct}]}}}),We={traceId:r.traceId,spanId:r.spanId,name:r.traceName,kind:1,startTimeUnixNano:r.startNs,endTimeUnixNano:o,attributes:He,status:{code:h>0?2:1}},Ve=D(p("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),p("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),Wt=[...l,We];a("Stop",`sid=${e}`,`totalTools=${E}`,`errorTools=${h}`,`spans=${Wt.length}`,`inputTokens=${_}`,`outputTokens=${A}`,`traceOutput="${_t(g,80)}"`);let Ge=await Fe(ke(Ve,Wt));a("Stop",`POST status=${Ge}`,`traceId=${r.traceId}`),$("TRACE_SENT",{latencyMs:lt,totalTools:E,errorTools:h,inputTokens:_,outputTokens:A,costUsd:ut}),Dt(e),k(t);}var x=class t{static passthroughStdin(){let e=[];process.stdin.on("data",n=>e.push(n)),process.stdin.on("end",()=>process.stdout.write(Buffer.concat(e)));}static async userPromptSubmit(){let e=await rt(),n;try{n=await C();}catch{process.stdout.write(JSON.stringify(e));return}n.authError?await Mt(e,true):n.length>0?await Mt(e):process.stdout.write(JSON.stringify(e));}static async preToolUse(){if(!await ht()){t.passthroughStdin();return}let e=await rt();await we(e);}static async postToolUse(){if(!await ht()){t.passthroughStdin();return}let e=await rt();await De(e);}static async stop(){if(!await ht()){t.passthroughStdin();return}let e=await rt();await Be(e);}};async function pr(){let t=process.argv[2];switch(t){case "UserPromptSubmit":await x.userPromptSubmit();break;case "PreToolUse":await x.preToolUse();break;case "PostToolUse":await x.postToolUse();break;case "Stop":await x.stop();break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
|
|
16
|
+
`),process.stdin.on("data",e=>process.stdout.write(e));}}pr().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
|
|
16
17
|
`),process.exit(0);});
|
package/dist/setup.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var child_process=require('child_process'),util=require('util'),i=require('fs'),f=require('path'),p=require('os'),ft=require('https');require('readline/promises');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var i__namespace=/*#__PURE__*/_interopNamespace(i);var f__namespace=/*#__PURE__*/_interopNamespace(f);var p__namespace=/*#__PURE__*/_interopNamespace(p);var ft__default=/*#__PURE__*/_interopDefault(ft);var I=Object.defineProperty;var Le=Object.getOwnPropertyDescriptor;var Re=Object.getOwnPropertyNames;var ke=Object.prototype.hasOwnProperty;var A=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var L=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var Pe=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(n){throw t=0,n}},R=(e,t)=>{for(var n in t)I(e,n,{get:t[n],enumerable:true});},Ie=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Re(t))!ke.call(e,s)&&s!==n&&I(e,s,{get:()=>t[s],enumerable:!(r=Le(t,s))||r.enumerable});return e};var Ne=e=>Ie(I({},"__esModule",{value:true}),e);var J={};R(J,{BUFFER:()=>De,CONFIG_DIR_NAME:()=>y,CONFIG_FILE_NAME:()=>T,DEBUG_LOG_FILENAME:()=>U,ENV:()=>u,FEATURES:()=>$e,FLOW_URLS:()=>be,HOOK_TIMEOUTS:()=>b,INSTALLER:()=>C,NATIVE_OTEL:()=>N,OTLP:()=>Ue,STATE_FILE_PREFIX:()=>Ve,TRACE_LIMITS:()=>xe,VAULT:()=>E,getFlowBaseUrl:()=>h,getFlowUrls:()=>k,getLlmProxy:()=>Fe,getMetrics:()=>He});function h(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Ce}function k(){let e=h();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${e}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${e}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${e}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${e}/otel`}}function Fe(){let e=h();return {ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${e}/flow-llm-proxy/`,ANTHROPIC_MODEL:process.env.FLOW_LLM_PROXY_MODEL??"anthropic.claude-4-6-sonnet",ANTHROPIC_SMALL_FAST_MODEL:process.env.FLOW_LLM_PROXY_SMALL_MODEL??"anthropic.claude-4-6-haiku",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"}}function He(){let e=h();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ce,be,E,y,T,Ue,N,u,$e,C,b,De,U,xe,Ve,l=L(()=>{"use strict";Ce="https://flow.ciandt.com";be=k(),E={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},y="FLOW-nodejs",T="config.json",Ue={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};N={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},u={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP",FLOW_OBS_USE_JSON_VAULT:"FLOW_TELEMETRY_USE_JSON_VAULT",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"},$e={KEYCHAIN_ENABLED:!1},C={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},b={UserPromptSubmit:30,PreToolUse:3,PostToolUse:10,Stop:15},De={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},U="flow-ai-obs-debug.log",xe={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};Ve="flow-obs-";});var X={};R(X,{MacOsKeyVaultProvider:()=>x});var D,x,q=L(()=>{"use strict";D=util.promisify(child_process.execFile),x=class{static async isAvailable(){try{return i.accessSync("/usr/bin/security",i.constants.X_OK),!0}catch{return !1}}async getSecret(t,n){try{let{stdout:r}=await D("security",["find-generic-password","-w","-a",n,"-s",t]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await D("security",["add-generic-password","-U","-a",n,"-s",t,"-w",r]);}async deleteSecret(t,n){try{return await D("security",["delete-generic-password","-a",n,"-s",t]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var Z={};R(Z,{LinuxKeyVaultProvider:()=>H});var z,H,Q=L(()=>{"use strict";z=util.promisify(child_process.execFile),H=class{static async isAvailable(){let t=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let n of t)try{return i.accessSync(n,i.constants.X_OK),!0}catch{}return !1}async getSecret(t,n){try{let{stdout:r}=await z("secret-tool",["lookup","service",t,"account",n]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await new Promise((s,o)=>{let a=child_process.spawn("secret-tool",["store","--label",t,"service",t,"account",n]);a.on("error",o),a.on("close",m=>{m===0?s():o(new Error(`secret-tool exited with code ${m}`));}),a.stdin.write(r),a.stdin.end();});}async deleteSecret(t,n){try{return await z("secret-tool",["clear","service",t,"account",n]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var ee={};R(ee,{WindowsKeyVaultProvider:()=>V});var V,te=L(()=>{"use strict";V=class{static async isAvailable(){try{return await A("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(t,n){return A("keytar").getPassword(t,n)}async setSecret(t,n,r){await A("keytar").setPassword(t,n,r);}async deleteSecret(t,n){return A("keytar").deletePassword(t,n)}getStoragePath(){return "Windows Credential Manager"}};});var me=Pe((An,pt)=>{pt.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.9.3-beta.728",description:"Claude Code hooks for Langfuse OTLP tracing \u2014 cross-platform",main:"dist/index.js",bin:{"flow-ai-obs":"dist/cli.js","flow-ai-obs-setup":"dist/setup.js"},scripts:{build:"tsup",test:"jest",typecheck:"tsc --noEmit",lint:"eslint src bin scripts",format:'prettier --write "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"format:check":'prettier --check "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"security-scan":"trufflehog filesystem src/ --fail --no-update --exclude-paths .trufflehogignore",postinstall:`node -e "require('fs').existsSync('dist/setup.js') && require('child_process').execFileSync(process.execPath, ['dist/setup.js'], {stdio:'inherit'})"`,prepublishOnly:"npm run security-scan && npm run build","release:npm":"changeset publish",changeset:"changeset","version-packages":"changeset version","install:hooks":"node dist/cli.js install","auth:login":"node dist/cli.js auth login","auth:logout":"node dist/cli.js auth logout","auth:status":"node dist/cli.js auth status",smoke:"bash scripts/smoke-test.sh","smoke:debug":"bash scripts/smoke-test.sh --debug","smoke:send":"bash scripts/smoke-test.sh --send --allow-http --debug",regression:"jest --config jest.regression.config.js --forceExit","regression:update":"UPDATE_GOLDEN=1 jest --config jest.regression.config.js --forceExit"},files:["dist/","README.md","LICENSE.md"],keywords:["claude-code","langfuse","observability","otlp","hooks","flow","ciandt"],author:"CI&T Flow Team",license:"SEE LICENSE IN LICENSE.md",private:!1,dependencies:{},optionalDependencies:{keytar:"7.9.0"},devDependencies:{"@changesets/changelog-github":"^0.6.0","@changesets/cli":"^2.30.0","@types/jest":"^30.0.0","@types/node":"^25.8.0",jest:"^30.4.2","ts-jest":"^29.4.9",tsup:"^8.5.1","eslint-config-prettier":"^10.1.5",prettier:"^3.5.3",typescript:"^6.0.3","typescript-eslint":"^8.33.0"},engines:{node:">=18.0.0"},overrides:{esbuild:"^0.28.1"},publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/CI-T-HyperX/flow-codeassistant-observability.git"}};});l();l();var F={credentials:"credentials","token-cache":"tokenCache"};function _(){let e=p__namespace.default.homedir();if(process.platform==="darwin")return f__namespace.default.join(e,"Library","Preferences",y,T);if(process.platform==="win32"){let n=process.env.APPDATA??f__namespace.default.join(e,"AppData","Roaming");return f__namespace.default.join(n,y,T)}let t=process.env.XDG_CONFIG_HOME??f__namespace.default.join(e,".config");return f__namespace.default.join(t,y,T)}function $(){try{let e=i__namespace.default.readFileSync(_(),"utf8");return JSON.parse(e)}catch{return {}}}function K(e){let t=_();i__namespace.default.mkdirSync(f__namespace.default.dirname(t),{recursive:true}),i__namespace.default.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var w=class{static isAvailable(){return true}static hasExistingData(){try{if(!i__namespace.default.existsSync(_()))return !1;let t=JSON.parse(i__namespace.default.readFileSync(_(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,n){let r=$(),s=F[n]??n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,n,r){let s=$(),o=F[n]??n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;K(s);}async deleteSecret(t,n){let r=$(),s=F[n]??n;return s in r?(delete r[s],K(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${_()}`}};async function ne(){return process.env[u.FLOW_OBS_USE_JSON_VAULT]==="1"?new w:await ze()??new w}async function ze(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=await Promise.resolve().then(()=>(q(),X));return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=await Promise.resolve().then(()=>(Q(),Z));return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=await Promise.resolve().then(()=>(te(),ee));return await e.isAvailable()?new e:null}default:return null}}l();var Ze=E.SERVICE,Qe=E.ACCOUNT_CREDS;E.ACCOUNT_TOKEN;var M=null;function et(){return M||(M=ne()),M}async function re(){let t=await(await et()).getSecret(Ze,Qe);if(!t)return null;try{return JSON.parse(t)}catch{return null}}l();l();l();f.join(p.tmpdir(),U);!process.env.NO_COLOR&&process.stdout.isTTY;function j(){return process.platform==="win32"?false:process.getuid?.()===0}function se(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let t=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(t)return {home:t,username:process.env.SUDO_USER}}return {home:p__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||p__namespace.userInfo().username}}function P(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(e=n);}if(e){let t=e.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return f__namespace.join(t,".claude","settings.json")}return f__namespace.join(p__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||p__namespace.homedir();return f__namespace.join(e,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let t=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(t)return f__namespace.join(t,".claude","settings.json")}return f__namespace.join(p__namespace.homedir(),".claude","settings.json")}var oe="flow-ai-obs",ie="config.json";function ce(){if(process.platform==="win32"){let n=process.env.APPDATA||f__namespace.join(p__namespace.homedir(),"AppData","Roaming");return f__namespace.join(n,oe,ie)}let e=se(),t=process.env.XDG_CONFIG_HOME||f__namespace.join(e.home,".config");return f__namespace.join(t,oe,ie)}var ct=C.LOCK_STALE_MS;function le(e){try{let t=i__namespace.statSync(e);Date.now()-t.mtimeMs>ct&&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 ue(e){try{i__namespace.unlinkSync(e);}catch{}}function lt(e,t){let r=(Array.isArray(e)?e:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(a=>!a.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [t,...r]}function pe(e,t){let n=P(),r=n+".lock",s=[];i__namespace.mkdirSync(f__namespace.dirname(n),{recursive:true}),le(r);try{if(i__namespace.existsSync(n)){i__namespace.copyFileSync(n,n+".bkp");try{i__namespace.chmodSync(n+".bkp",384);}catch{}}let o=ce();if(i__namespace.existsSync(o)){let c=o+".bkp";i__namespace.copyFileSync(o,c);try{i__namespace.chmodSync(c,384);}catch{}}let a={};try{a=JSON.parse(i__namespace.readFileSync(n,"utf8"));}catch{}let m=a.env&&typeof a.env=="object"?a.env:{};delete m.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:Se}=(l(),Ne(J)),we=Se().OTEL_ENDPOINT,ve={...N,OTEL_EXPORTER_OTLP_ENDPOINT:e??we};a.env={...m,...ve,...t??{}},a.otelHeadersHelper="flow-ai-obs otel-headers",(!a.hooks||typeof a.hooks!="object"||Array.isArray(a.hooks))&&(a.hooks={});let Oe=(c,O)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${c}`,timeout:O}]}),Ae=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],B=a.hooks;for(let c of Ae){let O=lt(B[c],Oe(c,b[c]));O.length>1&&s.push(c),B[c]=O;}i__namespace.writeFileSync(n,JSON.stringify(a,null,2)+`
|
|
3
|
-
`,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(
|
|
4
|
-
`,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(t,384);}catch{}}finally{ue(
|
|
2
|
+
'use strict';var child_process=require('child_process'),util=require('util'),i=require('fs'),f=require('path'),p=require('os'),ft=require('https');require('readline/promises');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var i__namespace=/*#__PURE__*/_interopNamespace(i);var f__namespace=/*#__PURE__*/_interopNamespace(f);var p__namespace=/*#__PURE__*/_interopNamespace(p);var ft__default=/*#__PURE__*/_interopDefault(ft);var I=Object.defineProperty;var Le=Object.getOwnPropertyDescriptor;var Re=Object.getOwnPropertyNames;var Pe=Object.prototype.hasOwnProperty;var A=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var L=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var ke=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(r){throw t=0,r}},R=(e,t)=>{for(var r in t)I(e,r,{get:t[r],enumerable:true});},Ie=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Re(t))!Pe.call(e,s)&&s!==r&&I(e,s,{get:()=>t[s],enumerable:!(n=Le(t,s))||n.enumerable});return e};var Ce=e=>Ie(I({},"__esModule",{value:true}),e);var J={};R(J,{BUFFER:()=>$e,CONFIG_DIR_NAME:()=>y,CONFIG_FILE_NAME:()=>_,DEBUG_LOG_FILENAME:()=>b,ENV:()=>u,FEATURES:()=>De,FLOW_URLS:()=>Ue,HOOK_TIMEOUTS:()=>U,INSTALLER:()=>N,NATIVE_OTEL:()=>C,OTLP:()=>be,STATE_FILE_PREFIX:()=>He,TRACE_LIMITS:()=>xe,VAULT:()=>E,getFlowBaseUrl:()=>h,getFlowUrls:()=>P,getLlmProxy:()=>Fe,getMetrics:()=>Me});function h(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Ne}function P(){let e=h();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${e}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${e}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${e}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${e}/otel`}}function Fe(){let e=h();return {ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${e}/flow-llm-proxy/`,ANTHROPIC_MODEL:process.env.FLOW_LLM_PROXY_MODEL??"anthropic.claude-4-6-sonnet",ANTHROPIC_SMALL_FAST_MODEL:process.env.FLOW_LLM_PROXY_SMALL_MODEL??"anthropic.claude-4-6-haiku",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"}}function Me(){let e=h();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ne,Ue,E,y,_,be,C,u,De,N,U,$e,b,xe,He,l=L(()=>{"use strict";Ne="https://flow.ciandt.com";Ue=P(),E={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},y="FLOW-nodejs",_="config.json",be={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};C={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},u={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP",FLOW_OBS_USE_JSON_VAULT:"FLOW_TELEMETRY_USE_JSON_VAULT",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES",FLOW_USER_EMAIL:"FLOW_USER_EMAIL",OTEL_EXPORTER_OTLP_HEADERS:"OTEL_EXPORTER_OTLP_HEADERS"},De={KEYCHAIN_ENABLED:!1},N={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},U={UserPromptSubmit:30,PreToolUse:3,PostToolUse:10,Stop:15},$e={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},b="flow-ai-obs-debug.log",xe={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};He="flow-obs-";});var X={};R(X,{MacOsKeyVaultProvider:()=>x});var $,x,q=L(()=>{"use strict";$=util.promisify(child_process.execFile),x=class{static async isAvailable(){try{return i.accessSync("/usr/bin/security",i.constants.X_OK),!0}catch{return !1}}async getSecret(t,r){try{let{stdout:n}=await $("security",["find-generic-password","-w","-a",r,"-s",t]);return n.trim()||null}catch{return null}}async setSecret(t,r,n){await $("security",["add-generic-password","-U","-a",r,"-s",t,"-w",n]);}async deleteSecret(t,r){try{return await $("security",["delete-generic-password","-a",r,"-s",t]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var Z={};R(Z,{LinuxKeyVaultProvider:()=>M});var z,M,Q=L(()=>{"use strict";z=util.promisify(child_process.execFile),M=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 z("secret-tool",["lookup","service",t,"account",r]);return n.trim()||null}catch{return null}}async setSecret(t,r,n){await new Promise((s,o)=>{let a=child_process.spawn("secret-tool",["store","--label",t,"service",t,"account",r]);a.on("error",o),a.on("close",g=>{g===0?s():o(new Error(`secret-tool exited with code ${g}`));}),a.stdin.write(n),a.stdin.end();});}async deleteSecret(t,r){try{return await z("secret-tool",["clear","service",t,"account",r]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var ee={};R(ee,{WindowsKeyVaultProvider:()=>H});var H,te=L(()=>{"use strict";H=class{static async isAvailable(){try{return await A("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(t,r){return A("keytar").getPassword(t,r)}async setSecret(t,r,n){await A("keytar").setPassword(t,r,n);}async deleteSecret(t,r){return A("keytar").deletePassword(t,r)}getStoragePath(){return "Windows Credential Manager"}};});var ge=ke((Or,pt)=>{pt.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.9.3-beta.752",description:"Claude Code hooks for Langfuse OTLP tracing \u2014 cross-platform",main:"dist/index.js",bin:{"flow-ai-obs":"dist/cli.js","flow-ai-obs-setup":"dist/setup.js"},scripts:{build:"tsup",test:"jest",typecheck:"tsc --noEmit",lint:"eslint src bin scripts",format:'prettier --write "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"format:check":'prettier --check "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"security-scan":"trufflehog filesystem src/ --fail --no-update --exclude-paths .trufflehogignore",postinstall:`node -e "require('fs').existsSync('dist/setup.js') && require('child_process').execFileSync(process.execPath, ['dist/setup.js'], {stdio:'inherit'})"`,prepublishOnly:"npm run security-scan && npm run build","release:npm":"changeset publish",changeset:"changeset","version-packages":"changeset version","install:hooks":"node dist/cli.js install","auth:login":"node dist/cli.js auth login","auth:logout":"node dist/cli.js auth logout","auth:status":"node dist/cli.js auth status",smoke:"bash scripts/smoke-test.sh","smoke:debug":"bash scripts/smoke-test.sh --debug","smoke:send":"bash scripts/smoke-test.sh --send --allow-http --debug",regression:"jest --config jest.regression.config.js --forceExit","regression:update":"UPDATE_GOLDEN=1 jest --config jest.regression.config.js --forceExit"},files:["dist/","README.md","LICENSE.md"],keywords:["claude-code","langfuse","observability","otlp","hooks","flow","ciandt"],author:"CI&T Flow Team",license:"SEE LICENSE IN LICENSE.md",private:!1,dependencies:{},optionalDependencies:{keytar:"7.9.0"},devDependencies:{"@changesets/changelog-github":"^0.6.0","@changesets/cli":"^2.30.0","@types/jest":"^30.0.0","@types/node":"^25.8.0",jest:"^30.4.2","ts-jest":"^29.4.9",tsup:"^8.5.1","eslint-config-prettier":"^10.1.5",prettier:"^3.5.3",typescript:"^6.0.3","typescript-eslint":"^8.33.0"},engines:{node:">=18.0.0"},overrides:{esbuild:"^0.28.1"},publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/CI-T-HyperX/flow-codeassistant-observability.git"}};});l();l();var F={credentials:"credentials","token-cache":"tokenCache"};function T(){let e=p__namespace.default.homedir();if(process.platform==="darwin")return f__namespace.default.join(e,"Library","Preferences",y,_);if(process.platform==="win32"){let r=process.env.APPDATA??f__namespace.default.join(e,"AppData","Roaming");return f__namespace.default.join(r,y,_)}let t=process.env.XDG_CONFIG_HOME??f__namespace.default.join(e,".config");return f__namespace.default.join(t,y,_)}function D(){try{let e=i__namespace.default.readFileSync(T(),"utf8");return JSON.parse(e)}catch{return {}}}function K(e){let t=T();i__namespace.default.mkdirSync(f__namespace.default.dirname(t),{recursive:true}),i__namespace.default.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var w=class{static isAvailable(){return true}static hasExistingData(){try{if(!i__namespace.default.existsSync(T()))return !1;let t=JSON.parse(i__namespace.default.readFileSync(T(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,r){let n=D(),s=F[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,r,n){let s=D(),o=F[r]??r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;K(s);}async deleteSecret(t,r){let n=D(),s=F[r]??r;return s in n?(delete n[s],K(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${T()}`}};async function re(){return process.env[u.FLOW_OBS_USE_JSON_VAULT]==="1"?new w:await ze()??new w}async function ze(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=await Promise.resolve().then(()=>(q(),X));return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=await Promise.resolve().then(()=>(Q(),Z));return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=await Promise.resolve().then(()=>(te(),ee));return await e.isAvailable()?new e:null}default:return null}}l();var Ze=E.SERVICE,Qe=E.ACCOUNT_CREDS;E.ACCOUNT_TOKEN;var V=null;function et(){return V||(V=re()),V}async function ne(){let t=await(await et()).getSecret(Ze,Qe);if(!t)return null;try{return JSON.parse(t)}catch{return null}}l();l();l();f.join(p.tmpdir(),b);!process.env.NO_COLOR&&process.stdout.isTTY;function j(){return process.platform==="win32"?false:process.getuid?.()===0}function se(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let t=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(t)return {home:t,username:process.env.SUDO_USER}}return {home:p__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||p__namespace.userInfo().username}}function k(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let r=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();r&&/^[A-Za-z]:\\/.test(r)&&(e=r);}if(e){let t=e.replace(/^([A-Za-z]):/,(r,n)=>`/mnt/${n.toLowerCase()}`).replace(/\\/g,"/");return f__namespace.join(t,".claude","settings.json")}return f__namespace.join(p__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||p__namespace.homedir();return f__namespace.join(e,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let t=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(t)return f__namespace.join(t,".claude","settings.json")}return f__namespace.join(p__namespace.homedir(),".claude","settings.json")}var oe="flow-ai-obs",ie="config.json";function ce(){if(process.platform==="win32"){let r=process.env.APPDATA||f__namespace.join(p__namespace.homedir(),"AppData","Roaming");return f__namespace.join(r,oe,ie)}let e=se(),t=process.env.XDG_CONFIG_HOME||f__namespace.join(e.home,".config");return f__namespace.join(t,oe,ie)}var ct=N.LOCK_STALE_MS;function le(e){try{let t=i__namespace.statSync(e);Date.now()-t.mtimeMs>ct&&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 ue(e){try{i__namespace.unlinkSync(e);}catch{}}function lt(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 pe(e,t){let r=k(),n=r+".lock",s=[];i__namespace.mkdirSync(f__namespace.dirname(r),{recursive:true}),le(n);try{if(i__namespace.existsSync(r)){i__namespace.copyFileSync(r,r+".bkp");try{i__namespace.chmodSync(r+".bkp",384);}catch{}}let o=ce();if(i__namespace.existsSync(o)){let c=o+".bkp";i__namespace.copyFileSync(o,c);try{i__namespace.chmodSync(c,384);}catch{}}let a={};try{a=JSON.parse(i__namespace.readFileSync(r,"utf8"));}catch{}let g=a.env&&typeof a.env=="object"?a.env:{};delete g.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:Se}=(l(),Ce(J)),we=Se().OTEL_ENDPOINT,ve={...C,OTEL_EXPORTER_OTLP_ENDPOINT:e??we};a.env={...g,...ve,...t??{}},a.otelHeadersHelper="flow-ai-obs otel-headers",(!a.hooks||typeof a.hooks!="object"||Array.isArray(a.hooks))&&(a.hooks={});let Oe=(c,O)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${c}`,timeout:O}]}),Ae=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],B=a.hooks;for(let c of Ae){let O=lt(B[c],Oe(c,U[c]));O.length>1&&s.push(c),B[c]=O;}i__namespace.writeFileSync(r,JSON.stringify(a,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(r,384);}catch{}}finally{ue(n);}return {settingsPath:r,preserved:s}}function fe(e){let t=k(),r=t+".lock";i__namespace.mkdirSync(f__namespace.dirname(t),{recursive:true}),le(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{ue(r);}}l();function de(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 me(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}.`}l();var G;function Ee(){return G||(G=ge()),G}var ye=f__namespace.default.join(p__namespace.default.tmpdir(),"flow-obs-update-cache.json"),gt=1440*60*1e3,ht=3e3;function Et(e,t){let r=o=>{let a=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return a?[+a[1],+a[2],+a[3]]:null},n=r(e),s=r(t);return !n||!s?false:s[0]!==n[0]?s[0]>n[0]:s[1]!==n[1]?s[1]>n[1]:s[2]>n[2]}function yt(){try{let e=JSON.parse(i__namespace.default.readFileSync(ye,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=gt?null:e}catch{return null}}function _t(e,t,r=Date.now()){try{i__namespace.default.writeFileSync(ye,JSON.stringify({latestVersion:e,updatePriority:t??null,checkedAt:r}),{mode:384});}catch{}}function Tt(e){let t=Ee().name,r=ft__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:ht},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 _e(){try{if(yt())return;setImmediate(()=>{Tt((e,t)=>{e||!t||Et(Ee().version,t.version)&&_t(t.version,t.updatePriority,0);});});}catch{}}var St=f__namespace.default.resolve(__dirname,".."),wt=process.env.INIT_CWD?f__namespace.default.resolve(process.env.INIT_CWD):null;wt===St&&process.exit(0);j()&&(process.stderr.write(`
|
|
5
5
|
[flow-ai-obs] \u2717 Do not install with sudo.
|
|
6
6
|
Run without sudo: npm install -g @ciandt-flow/flow-ai-obs
|
|
7
7
|
|
|
8
|
-
`),process.exit(1));async function vt(){try{pe();}catch{}let e=await
|
|
8
|
+
`),process.exit(1));async function vt(){try{pe();}catch{}let e=await ne();if(!e){process.stderr.write(`
|
|
9
9
|
[flow-ai-obs] No credentials found.
|
|
10
10
|
Run \`flow-ai-obs auth login\` to authenticate and enable telemetry.
|
|
11
11
|
|
|
12
|
-
`);return}let t=de(process.env[u.ANTHROPIC_AUTH_TOKEN]);if(!t||t.clientId!==e.clientId||t.clientSecret!==e.clientSecret||t.tenant!==e.tenant)try{let
|
|
12
|
+
`);return}let t=de(process.env[u.ANTHROPIC_AUTH_TOKEN]);if(!t||t.clientId!==e.clientId||t.clientSecret!==e.clientSecret||t.tenant!==e.tenant)try{let n=me(e);fe({[u.ANTHROPIC_AUTH_TOKEN]:n});}catch{}}vt().catch(()=>{}).finally(()=>_e());
|