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