@ciandt-flow/flow-ai-obs 0.15.2 → 0.16.0-beta.122
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 +156 -163
- package/dist/index.js +10 -10
- package/dist/setup.js +12 -12
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,109 +1,109 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var
|
|
3
|
-
`);}catch(i){throw r.close(),i}if(r.close(),t!==void 0)return t;throw new Error("Too many invalid attempts for yes/no prompt")}async function
|
|
2
|
+
'use strict';var zt=require('readline/promises'),Ds=require('https'),E=require('fs'),Le=require('os'),L=require('path'),child_process=require('child_process'),eo=require('http'),fn=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 zt__namespace=/*#__PURE__*/_interopNamespace(zt);var Ds__default=/*#__PURE__*/_interopDefault(Ds);var E__namespace=/*#__PURE__*/_interopNamespace(E);var Le__namespace=/*#__PURE__*/_interopNamespace(Le);var L__namespace=/*#__PURE__*/_interopNamespace(L);var eo__default=/*#__PURE__*/_interopDefault(eo);var fn__namespace=/*#__PURE__*/_interopNamespace(fn);var Xt=Object.defineProperty;var Is=Object.getOwnPropertyDescriptor;var vs=Object.getOwnPropertyNames;var bs=Object.prototype.hasOwnProperty;var Cs=(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 _=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var Us=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(r){throw t=0,r}},se=(e,t)=>{for(var r in t)Xt(e,r,{get:t[r],enumerable:true});},Ns=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of vs(t))!bs.call(e,s)&&s!==r&&Xt(e,s,{get:()=>t[s],enumerable:!(n=Is(t,s))||n.enumerable});return e};var x=e=>Ns(Xt({},"__esModule",{value:true}),e);var qt={};se(qt,{bold:()=>v,cyan:()=>M,dim:()=>m,green:()=>R,red:()=>k,yellow:()=>I});function De(e,t){return $s?r=>`\x1B[${e}m${r}\x1B[${t}m`:r=>r}var $s,R,k,I,M,v,m,pe=_(()=>{"use strict";$s=!process.env.NO_COLOR&&process.stdout.isTTY;R=De("32","39"),k=De("31","39"),I=De("33","39"),M=De("36","39"),v=De("1","22"),m=De("2","22");});var nt=Us((Ui,Fs)=>{Fs.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.16.0-beta.122",description:"Claude Code hooks for Langfuse OTLP tracing \u2014 cross-platform",main:"dist/index.js",bin:{"flow-ai-obs":"dist/cli.js","flow-ai-obs-setup":"dist/setup.js"},scripts:{build:"tsup",test:"jest",typecheck:"tsc --noEmit",lint:"eslint src bin scripts",format:'prettier --write "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"format:check":'prettier --check "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"security-scan":"trufflehog filesystem src/ --fail --no-update --exclude-paths .trufflehogignore",postinstall:`node -e "require('fs').existsSync('dist/setup.js') && require('child_process').execFileSync(process.execPath, ['dist/setup.js'], {stdio:'inherit'})"`,prepare:"lefthook install || echo '[WARNING] lefthook install failed - git hooks not installed'",prepublishOnly:"npm run security-scan && npm run build","release:npm":"changeset publish",changeset:"changeset","version-packages":"changeset version","install:hooks":"node dist/cli.js install","auth:login":"node dist/cli.js auth login","auth:logout":"node dist/cli.js auth logout","auth:status":"node dist/cli.js auth status",smoke:"bash scripts/smoke-test.sh","smoke:debug":"bash scripts/smoke-test.sh --debug","smoke:send":"bash scripts/smoke-test.sh --send --allow-http --debug",regression:"jest --config jest.regression.config.js --forceExit","regression:update":"UPDATE_GOLDEN=1 jest --config jest.regression.config.js --forceExit"},files:["dist/","README.md","LICENSE.md"],keywords:["claude-code","langfuse","observability","otlp","hooks","flow","ciandt"],author:"CI&T Flow Team",license:"SEE LICENSE IN LICENSE.md",private:!1,dependencies:{},devDependencies:{"@changesets/changelog-github":"^0.6.0","@changesets/cli":"^2.30.0","@types/jest":"^30.0.0","@types/node":"^25.8.0","eslint-config-prettier":"^10.1.5",jest:"^30.4.2",lefthook:"^2.1.10",prettier:"^3.5.3","ts-jest":"^29.4.9",tsup:"^8.5.1",typescript:"^6.0.3","typescript-eslint":"^8.33.0"},engines:{node:">=18.0.0"},overrides:{esbuild:"^0.28.1"},publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/CI-T-HyperX/flow-codeassistant-observability.git"}};});function de(){return process.stdout.isTTY===true&&process.stdin.isTTY===true&&!process.argv.includes("--no-interactive")}async function st(e,t){let r=zt__namespace.createInterface({input:process.stdin,output:process.stdout}),s=`${e} ${t===true?"(Y/n)":t===false?"(y/N)":"(y/n)"}: `;for(let o=1;o<=3;o++)try{let i=(await r.question(s)).trim().toLowerCase();if(i===""&&t!==void 0)return r.close(),t;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(),t!==void 0)return t;throw new Error("Too many invalid attempts for yes/no prompt")}async function Zt(e,t){let r=zt__namespace.createInterface({input:process.stdin,output:process.stdout});try{let n=(await r.question(`${e}: `)).trim();if(t);return n}catch(n){throw n}finally{r.close();}}var Qt=_(()=>{"use strict";});var Me={};se(Me,{checkForUpdate:()=>Ks,checkForUpdateInteractive:()=>Ys,fetchLatestVersionAsync:()=>Vr,isNewer:()=>xe,primeUpdateCache:()=>js,runUpdate:()=>jr});function V(){return er||(er=nt()),er}function xe(e,t){let r=o=>{let i=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return i?[+i[1],+i[2],+i[3]]:null},n=r(e),s=r(t);return !n||!s?false:s[0]!==n[0]?s[0]>n[0]:s[1]!==n[1]?s[1]>n[1]:s[2]>n[2]}function nr(){try{let e=JSON.parse(E__namespace.default.readFileSync(Yr,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=Ws?null:e}catch{return null}}function sr(e,t,r=Date.now()){try{E__namespace.default.writeFileSync(Yr,JSON.stringify({latestVersion:e,updatePriority:t??null,checkedAt:r}),{mode:384});}catch{}}function or(e){let t=V().name,r=Ds__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:Bs},n=>{if(n.statusCode!==200)return n.resume(),e(new Error(`HTTP ${n.statusCode}`));let s="";n.setEncoding("utf8"),n.on("data",o=>{s+=o;}),n.on("end",()=>{try{let o=JSON.parse(s);if(typeof o.version!="string")throw new Error("no version field");e(null,{version:o.version,updatePriority:typeof o.updatePriority=="string"?o.updatePriority:null});}catch(o){e(o);}});});r.on("error",e),r.on("timeout",()=>{r.destroy(new Error("timeout"));});}function tr(e){let t=V().name,n=` Update available: ${V().version} \u2192 ${e}`,s=` Run: npm install -g ${t}`,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 rr(e){let t=V().name;process.stderr.write(`
|
|
10
10
|
[${t}] Critical update detected \u2014 auto-updating to ${e}...
|
|
11
11
|
|
|
12
|
-
`);let r=child_process.spawn("npm",["install","-g",`${t}@${e}`],{detached:true,stdio:"ignore",shell:process.platform==="win32",windowsHide:true});r.on("error",()=>{}),r.unref();}async function
|
|
13
|
-
\u256D${
|
|
12
|
+
`);let r=child_process.spawn("npm",["install","-g",`${t}@${e}`],{detached:true,stdio:"ignore",shell:process.platform==="win32",windowsHide:true});r.on("error",()=>{}),r.unref();}async function Hs(e,t=1e4){let r=Cs("readline"),n=V().name,o=` Update available: ${V().version} \u2192 ${e}`,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
|
+
\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
|
-
\u2570${
|
|
18
|
-
`),new Promise(
|
|
19
|
-
`),
|
|
17
|
+
\u2570${u}\u256F
|
|
18
|
+
`),new Promise(h=>{let d=r.createInterface({input:process.stdin,output:void 0,terminal:false}),y=false;function S(b){y||(y=true,clearTimeout($),d.close(),process.stderr.write(`
|
|
19
|
+
`),h(b));}let $=setTimeout(()=>S(false),t);d.once("line",b=>S(b.trim().toLowerCase()==="y")),d.once("close",()=>S(false));})}async function jr(e){let t=V().name;return process.stderr.write(` Installing ${t}@${e}...
|
|
20
20
|
`),new Promise(r=>{let n=child_process.spawn("npm",["install","-g",`${t}@${e}`],{stdio:"inherit",shell:process.platform==="win32"}),s=false;function o(i,a){if(!s){if(s=true,i)process.stderr.write(` \u2713 Updated to ${e}. Please restart the command.
|
|
21
21
|
|
|
22
22
|
`);else {let c=a?` (${a})`:"";process.stderr.write(` \u2717 Update failed${c} \u2014 continuing with current version.
|
|
23
23
|
|
|
24
|
-
`);}r();}}n.on("close",(i,a)=>o(i===0,a??void 0)),n.on("error",i=>o(false,i.code));})}function
|
|
25
|
-
`;try{
|
|
26
|
-
`);}}var
|
|
27
|
-
`+
|
|
24
|
+
`);}r();}}n.on("close",(i,a)=>o(i===0,a??void 0)),n.on("error",i=>o(false,i.code));})}function Vr(){return new Promise(e=>{or((t,r)=>e(t||!r?null:r));})}function Ks(){try{let e=nr();if(e){xe(V().version,e.latestVersion)&&(e.updatePriority==="auto"?rr(e.latestVersion):tr(e.latestVersion));return}setImmediate(()=>{or((t,r)=>{t||!r||(sr(r.version,r.updatePriority),xe(V().version,r.version)&&(r.updatePriority==="auto"?rr(r.version):tr(r.version)));});});}catch{}}async function Ys(e={}){try{let t=nr();if(t){if(!xe(V().version,t.latestVersion))return}else {let n=await Vr();if(!n||(sr(n.version,n.updatePriority),!xe(V().version,n.version)))return;t={latestVersion:n.version,updatePriority:n.updatePriority,checkedAt:Date.now()};}if(t.updatePriority==="auto"){rr(t.latestVersion);return}if(!de()){tr(t.latestVersion);return}await Hs(t.latestVersion,e.timeoutMs)&&await jr(t.latestVersion);}catch{}}function js(){try{if(nr())return;setImmediate(()=>{or((e,t)=>{e||!t||xe(V().version,t.version)&&sr(t.version,t.updatePriority,0);});});}catch{}}var er,Yr,Ws,Bs,We=_(()=>{"use strict";Qt();Yr=L__namespace.default.join(Le__namespace.default.tmpdir(),"flow-obs-update-cache.json"),Ws=1440*60*1e3,Bs=3e3;});var Gr={};se(Gr,{AUTH_ENGINE:()=>Be,BUFFER:()=>J,CLAUDE_DESKTOP:()=>C,CONFIG_DIR_NAME:()=>it,CONFIG_FILE_NAME:()=>at,COPILOT_OTEL:()=>T,DEBUG_LOG_FILENAME:()=>ir,ENV:()=>p,FLOW_URLS:()=>Gs,INSTALLER:()=>Lt,NATIVE_OTEL:()=>fe,OTLP:()=>Ot,STATE_FILE_PREFIX:()=>Js,TRACE_LIMITS:()=>Z,VALIDATION:()=>H,VAULT:()=>ot,getFlowBaseUrl:()=>we,getFlowUrls:()=>G,getMetrics:()=>Rt});function we(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Vs}function G(){let e=we();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${e}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${e}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${e}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${e}/otel`}}function Rt(){let e=we();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Vs,Gs,ot,it,at,Ot,fe,p,Be,Lt,J,H,ir,Z,C,T,Js,P=_(()=>{"use strict";Vs="https://flow.ciandt.com";Gs=G(),ot={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},it="FLOW-nodejs",at="config.json",Ot={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},fe={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},p={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP",FLOW_OBS_SKIP_DESKTOP_DETECTION:"FLOW_OBS_SKIP_DESKTOP_DETECTION",FLOW_OBS_SKIP_COPILOT_DETECTION:"FLOW_OBS_SKIP_COPILOT_DETECTION",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES",FLOW_USER_EMAIL:"FLOW_USER_EMAIL",FLOW_API_KEY:"FLOW_API_KEY",OTEL_EXPORTER_OTLP_HEADERS:"OTEL_EXPORTER_OTLP_HEADERS",FLOW_BASE_URL:"FLOW_BASE_URL"},Be={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},Lt={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},J={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},H={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[A-Za-z0-9_.\-:=+/]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},ir="flow-ai-obs-debug.log",Z={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};C={DIR_3P:"Claude-3p",CONFIG_LIBRARY_DIR:"configLibrary",DESKTOP_CONFIG_FILE:"claude_desktop_config.json",META_FILE:"_meta.json",DEPLOYMENT_MODE:"3p",CONFIG_NAME:"Flow AI Obs",WRAPPER_SCRIPT_UNIX:"otel-headers-helper.sh",WRAPPER_SCRIPT_WIN:"otel-headers-helper.cmd",OTLP_PROTOCOL:"http/json",KEYS:{OTLP_ENDPOINT:"otlpEndpoint",OTLP_PROTOCOL:"otlpProtocol",OTLP_HEADERS_HELPER:"otlpHeadersHelper",OTLP_RESOURCE_ATTRIBUTES:"otlpResourceAttributes"},CUSTOM_PROVIDER_KEY:"custom.provider",CUSTOM_PROVIDER_VALUE:"claude-code-desktop"},T={ENABLED_KEY:"github.copilot.chat.otel.enabled",ENABLED_VALUE:!0,EXPORTER_TYPE_KEY:"github.copilot.chat.otel.exporterType",EXPORTER_TYPE_VALUE:"otlp-http",PROTOCOL_KEY:"github.copilot.chat.otel.protocol",PROTOCOL_VALUE:"http/json",ENDPOINT_KEY:"github.copilot.chat.otel.otlpEndpoint",HEADERS_KEY:"github.copilot.chat.otel.headers",HEADER_API_KEY:"x-flow-api-key",HEADER_USER:"x-flow-user"},Js="flow-obs-";});function l(...e){if(process.env[p.FLOW_OBS_DEBUG]!=="1")return;let t=`[${new Date().toISOString()}] ${e.join(" ")}
|
|
25
|
+
`;try{E.writeFileSync(Zs,t,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
|
|
26
|
+
`);}}var Zs,D=_(()=>{"use strict";P();Zs=L.join(Le.tmpdir(),ir);});function ro(e){if(!to.test(e))throw new Error(`Invalid tenant value: "${e}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}function no(e,t){let r=t.length>400?t.slice(0,400)+"\u2026":t;l("toAuthError",`status=${e} body=${r}`);try{let n=JSON.parse(t);if(typeof n.error=="string"&&(l("toAuthError",`api_error_code=${n.error}`+(n.message?` api_message=${n.message}`:"")),Jr[n.error]))return new Ae(Jr[n.error],e)}catch{}return e===401||e===403||e===500?new Ae("Invalid credentials",e):e>=400&&e<500?new Ae("Authentication request was rejected",e):new Error("Authentication service unavailable, please try again later")}function X(e){return new Promise((t,r)=>{try{ro(e.tenant);}catch(u){return r(u)}let n=JSON.stringify({clientSecret:e.clientSecret}),s=new URL(G().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:e.tenant}};l("getToken",`requesting token tenant=${e.tenant} host=${i.hostname} path=${i.path}`);let c=(o?Ds__default.default:eo__default.default).request(i,u=>{let h=[];u.on("data",d=>h.push(d)),u.on("end",()=>{let d=h.join("");if((u.statusCode??0)>=400)return r(no(u.statusCode??0,d));let y;try{y=JSON.parse(d);}catch{return r(new Error("Invalid response from auth engine"))}let S=y.expires_at??new Date(Date.now()+(y.expires_in??3600)*1e3).toISOString();if(!y.access_token)return r(new Error("Auth engine returned an empty access token. Check FLOW_BASE_URL and credentials."));t({accessToken:y.access_token,expiresAt:S});});});c.on("error",u=>r(new Error(`Network error: ${u.message}`))),c.setTimeout(Be.REQUEST_TIMEOUT_MS,()=>{c.destroy(new Error("Request timeout"));}),c.write(n),c.end();})}var Ae,to,Jr,Oe=_(()=>{"use strict";P();D();Ae=class extends Error{statusCode;constructor(t,r=0){super(t),this.name="AuthError",this.statusCode=r;}},to=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;Jr={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 Xr(){return process.platform==="win32"?false:process.getuid?.()===0}function kt(){if(Xr())return process.stderr.write(`
|
|
27
|
+
`+k(` \u2717 flow-ai-obs is not supported in a sudo context.
|
|
28
28
|
|
|
29
29
|
`)+M(` npm install -g @ciandt-flow/flow-ai-obs
|
|
30
30
|
`)+`
|
|
31
|
-
`),1}var
|
|
32
|
-
`,{encoding:"utf8",mode:384});try{
|
|
33
|
-
`,{encoding:"utf8",mode:384});try{
|
|
31
|
+
`),1}var Pt=_(()=>{"use strict";pe();});function Re(){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:Le__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||Le__namespace.userInfo().username}}function oe(){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(Le__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||Le__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(Le__namespace.homedir(),".claude","settings.json")}var ct=_(()=>{"use strict";Pt();});function It(){if(process.platform==="win32"){let r=process.env.APPDATA||L__namespace.join(Le__namespace.homedir(),"AppData","Roaming");return L__namespace.join(r,qr,zr)}let e=Re(),t=process.env.XDG_CONFIG_HOME||L__namespace.join(e.home,".config");return L__namespace.join(t,qr,zr)}function cr(){try{let e=E__namespace.readFileSync(oe(),"utf8"),r=JSON.parse(e).env?.FLOW_BASE_URL;return typeof r=="string"&&r.trim()?r.trim():null}catch{return null}}var qr,zr,lr=_(()=>{"use strict";ct();qr="flow-ai-obs",zr="config.json";});function en(e){try{let t=E__namespace.statSync(e);Date.now()-t.mtimeMs>so&&E__namespace.unlinkSync(e);}catch{}try{E__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 tn(e){try{E__namespace.unlinkSync(e);}catch{}}function oo(e){let t=[];if(!e.hooks||typeof e.hooks!="object"||Array.isArray(e.hooks))return delete e.hooks,t;let r=e.hooks,n={};for(let[s,o]of Object.entries(r)){if(!Array.isArray(o))continue;let i=o.map(a=>{if(!Array.isArray(a?.hooks))return null;let c=a.hooks.filter(u=>!u.command?.startsWith?.(Lt.CLI));return c.length>0?{...a,hooks:c}:null}).filter(a=>a!=null);i.length>0&&(n[s]=i,t.push(s));}return Object.keys(n).length>0?e.hooks=n:delete e.hooks,t}function rn(e,t){let r=oe(),n=r+".lock";E__namespace.mkdirSync(L__namespace.dirname(r),{recursive:true}),en(n);try{if(E__namespace.existsSync(r)){E__namespace.copyFileSync(r,r+".bkp");try{E__namespace.chmodSync(r+".bkp",384);}catch{}}let s=It();if(E__namespace.existsSync(s)){let d=s+".bkp";E__namespace.copyFileSync(s,d);try{E__namespace.chmodSync(d,384);}catch{}}let o={};try{o=JSON.parse(E__namespace.readFileSync(r,"utf8"));}catch{}let i=o.env&&typeof o.env=="object"?o.env:{};delete i.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:a}=(P(),x(Gr)),c=a().OTEL_ENDPOINT,u={...fe,OTEL_EXPORTER_OTLP_ENDPOINT:e??c};o.env={...i,...u,...t??{}},o.otelHeadersHelper="flow-ai-obs otel-headers";let h=oo(o);E__namespace.writeFileSync(r,JSON.stringify(o,null,2)+`
|
|
32
|
+
`,{encoding:"utf8",mode:384});try{E__namespace.chmodSync(r,384);}catch{}return {settingsPath:r,preserved:h}}finally{tn(n);}}function q(e){if(ut===void 0)try{let r=E__namespace.readFileSync(oe(),"utf8");ut=JSON.parse(r).env??null;}catch{ut=null;}if(!ut)return null;let t=ut[e];return typeof t=="string"?t:null}function Ke(e){let t=oe(),r=t+".lock";E__namespace.mkdirSync(L__namespace.dirname(t),{recursive:true}),en(r);try{let n={};try{n=JSON.parse(E__namespace.readFileSync(t,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,e),E__namespace.writeFileSync(t,JSON.stringify(n,null,2)+`
|
|
33
|
+
`,{encoding:"utf8",mode:384});try{E__namespace.chmodSync(t,384);}catch{}}finally{tn(r);}}function pt(e){let t=process.env[e];return t!==void 0?t!==""?t:void 0:q(e)??void 0}var so,ut,me=_(()=>{"use strict";P();Oe();ct();lr();so=Lt.LOCK_STALE_MS;});function dt(){let e=Le__namespace.default.homedir();if(process.platform==="darwin")return L__namespace.default.join(e,"Library","Preferences",it,at);if(process.platform==="win32"){let r=process.env.APPDATA??L__namespace.default.join(e,"AppData","Roaming");return L__namespace.default.join(r,it,at)}let t=process.env.XDG_CONFIG_HOME??L__namespace.default.join(e,".config");return L__namespace.default.join(t,it,at)}function dr(){try{let e=E__namespace.default.readFileSync(dt(),"utf8");return JSON.parse(e)}catch{return {}}}function nn(e){let t=dt();E__namespace.default.mkdirSync(L__namespace.default.dirname(t),{recursive:true}),E__namespace.default.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var pr,vt,sn=_(()=>{"use strict";P();pr={credentials:"credentials","token-cache":"tokenCache"};vt=class{static isAvailable(){return !0}static hasExistingData(){try{if(!E__namespace.default.existsSync(dt()))return !1;let t=JSON.parse(E__namespace.default.readFileSync(dt(),"utf8"));return !!(t&&t.credentials)}catch{return !1}}async getSecret(t,r){let n=dr(),s=pr[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,r,n){let s=dr(),o=pr[r]??r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;nn(s);}async deleteSecret(t,r){let n=dr(),s=pr[r]??r;return s in n?(delete n[s],nn(n),!0):!1}getStoragePath(){return `config.json (unencrypted) \u2014 ${dt()}`}};});async function on(){return new vt}var an=_(()=>{"use strict";sn();});var ln={};se(ln,{clearFlowCredentials:()=>co,getConfigPath:()=>uo,getEmailFromToken:()=>Ge,getFlowCredentials:()=>cn,getTokenCache:()=>mt,hasCredentials:()=>po,isTokenValid:()=>lo,saveFlowCredentials:()=>ao,saveTokenCache:()=>ge});function Ve(){return fr||(fr=on()),fr}async function cn(){let t=await(await Ve()).getSecret(je,mr);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function ao(e){if(!e.clientId||!e.clientSecret||!e.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await Ve()).setSecret(je,mr,JSON.stringify(e));}async function co(){let e=await Ve();await e.deleteSecret(je,mr),await e.deleteSecret(je,gr);}async function ge(e){await(await Ve()).setSecret(je,gr,JSON.stringify({accessToken:e.accessToken,expiresAt:e.expiresAt,lastAuthCheckAt:e.lastAuthCheckAt}));}async function mt(){let t=await(await Ve()).getSecret(je,gr);if(!t)return null;try{let r=JSON.parse(t);return {accessToken:r.accessToken,expiresAt:r.expiresAt,lastAuthCheckAt:r.lastAuthCheckAt}}catch{return null}}async function lo(){let e=await mt();return e?new Date(e.expiresAt)>new Date:false}async function Ge(){let e=await mt();if(!e||!e.accessToken)return null;try{let t=e.accessToken.split(".");if(t.length<2)return null;let r=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return r.email??r.preferred_username??r.upn??r.sub??null}catch{return null}}async function uo(){return (await Ve()).getStoragePath?.()??"FLOW-nodejs/config.json"}async function po(){let e=await cn();return !!(e&&e.clientId&&e.clientSecret&&e.tenant)}var je,mr,gr,fr,Je=_(()=>{"use strict";an();P();je=ot.SERVICE,mr=ot.ACCOUNT_CREDS,gr=ot.ACCOUNT_TOKEN,fr=null;});function un(){return !!process.env[p.FLOW_USER_EMAIL]||!!q(p.FLOW_USER_EMAIL)}function Er(e){l("maybePersistUserEmail",`${e}: starting`);let t=e==="api-key"?`\u26A0\uFE0F flow-ai-obs: FLOW_USER_EMAIL is not set. Configure it with:
|
|
34
34
|
flow-ai-obs init --custom-email <EMAIL>
|
|
35
35
|
`:`\u26A0\uFE0F flow-ai-obs: FLOW_USER_EMAIL is not set and could not be derived from token.
|
|
36
36
|
Run: flow-ai-obs init
|
|
37
|
-
`;return
|
|
37
|
+
`;return Ge().then(r=>{if(r){let n=r.split(/[\r\n]/)[0].replace(/[\x00-\x1F\x7F]/g,"").trim();if(!n)return;let s=n.indexOf("@"),o=n.slice(s+1);if(!(n.length<=254&&H.EMAIL_HEADER_PATTERN.test(n)&&(n.match(/@/g)??[]).length===1&&s>0&&s<n.length-1&&o.includes("."))){l("maybePersistUserEmail",`${e}: email from token failed basic validation \u2014 skipping persist`);return}try{Ke({[p.FLOW_USER_EMAIL]:n}),l("maybePersistUserEmail",`${e}: persisted FLOW_USER_EMAIL from OAuth token`);}catch(a){l("maybePersistUserEmail",`${e}: FLOW_USER_EMAIL write failed: ${a.message}`),process.stderr.write(`\u26A0\uFE0F flow-ai-obs: could not persist FLOW_USER_EMAIL to settings.json.
|
|
38
38
|
Run: flow-ai-obs init
|
|
39
|
-
`);}}else process.stderr.write(t);}).catch(r=>{l("maybePersistUserEmail",`${e}: getEmailFromToken failed: ${r.message}`);})}var mn=T(()=>{"use strict";qe();me();D();v();});function Eo(e){return go.some(t=>t.test(e))}function ho(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"));return r.email||r.preferred_username||r.upn||r.sub||null}catch{return null}}function Q(e){if(!e)return null;try{let t=e.split(".");if(t.length<2)return null;let r=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:n,clientSecret:s,tenant:o}=r;return !n||!s||!o?null:{clientId:n,clientSecret:s,tenant:o}}catch{return null}}function Ie(e){let t;try{t=new URL(e);}catch{throw new Error(`Invalid URL: ${e}`)}let r=process.env[d.FLOW_OBS_ALLOW_HTTP]==="true";if(!r&&t.protocol!=="https:")throw new Error(`URL must use HTTPS: ${e}`);if(t.username||t.password)throw new Error(`URL must not contain embedded credentials: ${e}`);if(!r&&Eo(t.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${t.hostname}`);return e}async function gn(){let e=Q(process.env[d.ANTHROPIC_AUTH_TOKEN]);return e?{user:await Xe().catch(()=>null)??e.clientId,tenant:e.tenant}:{user:"",tenant:""}}function _o(e){let t=process.env[d.OTEL_EXPORTER_OTLP_HEADERS];if(!t)return null;let r=e.toLowerCase();for(let n of t.split(",")){let s=n.indexOf("=");if(!(s<=0)&&n.slice(0,s).trim().toLowerCase()===r){let o=n.slice(s+1),i=o.search(/[\r\n]/);return (i===-1?o:o.slice(0,i)).trim()||null}}return null}function ve(){let e=ft(d.FLOW_USER_EMAIL);if(e!==void 0){let r=e.replace(/[\r\n]/g,"").trim();if(r)if(r.length>B.EMAIL_MAX_LENGTH)l("resolveUserEmail",`FLOW_USER_EMAIL exceeds ${B.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!B.EMAIL_HEADER_PATTERN.test(r))l("resolveUserEmail","FLOW_USER_EMAIL contains non-printable or control characters \u2014 skipping");else return l("resolveUserEmail","using FLOW_USER_EMAIL override: [REDACTED]"),r}let t=_o("x-flow-user");if(t){let r=t.replace(/[\r\n]/g,"").trim();if(r.length>B.EMAIL_MAX_LENGTH)l("resolveUserEmail",`x-flow-user from OTEL_EXPORTER_OTLP_HEADERS exceeds ${B.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!B.EMAIL_HEADER_PATTERN.test(r))l("resolveUserEmail","x-flow-user from OTEL_EXPORTER_OTLP_HEADERS is empty or contains non-printable characters \u2014 skipping");else return l("resolveUserEmail","using x-flow-user from OTEL_EXPORTER_OTLP_HEADERS: [REDACTED]"),r}try{let r=Re__namespace.default.userInfo().username||process.env.USERNAME||process.env.USER||"",n=r.lastIndexOf("\\");if(n!==-1&&(r=r.slice(n+1)),r=r.trim().replace(/[^a-zA-Z0-9._%+\-]/g,"").replace(/^\.+/,""),!r)return l("resolveUserEmail","Could not derive x-flow-user: username is empty. Run: flow-ai-obs init"),null;let s=`${r}@ciandt.com`;return l("resolveUserEmail","derived email: [REDACTED]"),s}catch(r){return l("resolveUserEmail",`Could not derive x-flow-user from OS username: ${r.message}. Run: flow-ai-obs init`),null}}function ie(e){if(!e)return null;let t=e.replace(/[\r\n]/g,"").trim();return t?t.length>B.API_KEY_MAX_LENGTH?(l("validateApiKey",`API key exceeds ${B.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):B.API_KEY_PATTERN.test(t)?t:(l("validateApiKey","API key contains invalid or unsafe characters \u2014 rejected"),null):null}function K(){let e=process.env[d.FLOW_API_KEY];return ie(e)}function To(){return new Date().toISOString().slice(0,10)}async function yo(e){let t=To(),r=await Et();if(r?.lastAuthCheckAt!==t){l("getOrRefreshToken",`daily auth check (last: ${r?.lastAuthCheckAt??"never"})`);let o=Ke.MAX_RETRY_ATTEMPTS;for(let i=1;i<=o;i++)try{let a=await J(e);try{await ge({...a,lastAuthCheckAt:t});}catch(p){l("getOrRefreshToken",`saveTokenCache failed (non-fatal): ${p.message}`);}return l("getOrRefreshToken",`daily check passed (attempt ${i}), expires=${a.expiresAt}`),K()?fn()||await Tr("api-key"):await Tr("oauth"),a.accessToken}catch(a){if(a instanceof ke){if(a.statusCode!==500)throw l("getOrRefreshToken",`daily check auth error (${a.statusCode}) \u2014 propagating immediately`),a;if(i<o){l("getOrRefreshToken",`daily check 500 error (attempt ${i}/${o}) \u2014 retrying in 1s`),await new Promise(c=>setTimeout(c,Ke.RETRY_DELAY_MS));continue}throw l("getOrRefreshToken",`daily check failed after ${o} attempts \u2014 propagating`),a}l("getOrRefreshToken",`daily check network error \u2014 using cache: ${a.message}`);break}}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=${e.tenant} clientId=${e.clientId})`);let s=await J(e);try{await ge({...s,lastAuthCheckAt:t});}catch(o){l("getOrRefreshToken",`token cache save failed (non-fatal): ${o.message}`);}return l("getOrRefreshToken",`token refreshed, expires=${s.expiresAt}`),s.accessToken}function So(e,t){let r=t&&t.accessToken?t.accessToken:"";return {endpoint:e.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function wo(e,t,r){let n=Buffer.from(`${t}:${r}`).toString("base64");return {endpoint:e.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${n}`}}async function le(){let e=[],t=Q(process.env[d.ANTHROPIC_AUTH_TOKEN]);l("resolveCredentials",t?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),t&&l("resolveCredentials",`clientId=${t.clientId}`,`tenant=${t.tenant}`);let r=t?t.tenant:"",n=process.env[d.FLOW_TELEMETRY]==="true",s=process.env[d.LANGFUSE_BASE_URL],o=process.env[d.LANGFUSE_PUBLIC_KEY],i=process.env[d.LANGFUSE_SECRET_KEY];if(n&&s&&o&&i){let u="",E=r;t&&(u=await Xe().catch(()=>null)??t.clientId);let S={user:u??"",tenant:E??"",team:"",project:""};e.push({mode:"direct",...wo(Ie(s),o,i),...S}),l("resolveCredentials","direct mode active",`user=${S.user}`,`tenant=${S.tenant}`);}if(!t){if(e.length===0){let u=[];return u.authError=false,u}return e}let a;try{a=await yo(t);}catch(u){if(l("resolveCredentials",`token refresh failed: ${u.message}`,`(tenant=${t.tenant} clientId=${t.clientId})`),e.length>0)return e.authError=true,e;let E=[];return E.authError=true,E}let p={user:ho(a)??t.clientId,tenant:r,team:"",project:""},g=process.env[d.FLOW_TELEMETRY_GATEWAY]??Oe();return e.push({mode:"gateway",...So(Ie(g),{accessToken:a}),...p}),e}var go,H=T(()=>{"use strict";qe();Le();v();D();mn();me();go=[/^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 hn(){return !!(process.env.WSL_DISTRO_NAME&&process.platform==="linux")}function Nt(){return process.platform==="win32"||hn()}function Ao(e){let t=e.match(/^\/mnt\/([a-z])\/(.*)$/);if(!t)return e;let r=t[1].toUpperCase(),n=t[2].replace(/\//g,"\\");return `${r}:\\${n}`}function _n(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let n=process.env.LOCALAPPDATA;if(!n)try{let s=child_process.execSync("cmd.exe /c echo %LOCALAPPDATA%",{encoding:"utf8",timeout:5e3}).trim();s&&/^[A-Za-z]:\\/.test(s)&&(n=s);}catch(s){l("getDesktopPaths",`cmd.exe LOCALAPPDATA lookup failed: ${s.message}`);}if(n){let s=n.replace(/^([A-Za-z]):/,(i,a)=>`/mnt/${a.toLowerCase()}`).replace(/\\/g,"/"),o=R__namespace.join(s,N.DIR_3P);return Ct(o)}}if(process.platform==="win32"){let n=process.env.LOCALAPPDATA||R__namespace.join(Re__namespace.homedir(),"AppData","Local"),s=R__namespace.join(n,N.DIR_3P);return Ct(s)}if(process.platform==="darwin"){let n=R__namespace.join(Re__namespace.homedir(),"Library","Application Support",N.DIR_3P);return Ct(n)}let e=Pe(),t=process.env.XDG_CONFIG_HOME||R__namespace.join(e.home,".config"),r=R__namespace.join(t,N.DIR_3P);return Ct(r)}function Ct(e){return {configDir:e,configLibraryDir:R__namespace.join(e,N.CONFIG_LIBRARY_DIR),desktopConfigPath:R__namespace.join(e,N.DESKTOP_CONFIG_FILE),metaPath:R__namespace.join(e,N.CONFIG_LIBRARY_DIR,N.META_FILE)}}function $t(){let e=oe(),t=R__namespace.dirname(e),r=Nt()?N.WRAPPER_SCRIPT_WIN:N.WRAPPER_SCRIPT_UNIX;return R__namespace.join(t,r)}function Ft(){if(process.env[d.FLOW_OBS_SKIP_DESKTOP_DETECTION])return false;let e=_n();if(___namespace.existsSync(e.configDir))return true;if(process.platform==="darwin")return ["/Applications/Claude.app",R__namespace.join(Re__namespace.homedir(),"Applications","Claude.app")].some(r=>___namespace.existsSync(r));if(process.platform==="win32"){let t=process.env.LOCALAPPDATA||R__namespace.join(Re__namespace.homedir(),"AppData","Local"),r=process.env.PROGRAMFILES||"C:\\Program Files";return [R__namespace.join(t,"AnthropicClaude","Claude.exe"),R__namespace.join(r,"Claude","Claude.exe")].some(s=>___namespace.existsSync(s))}if(process.platform==="linux"){let t=Pe(),r=process.env.XDG_CONFIG_HOME||R__namespace.join(t.home,".config"),n=R__namespace.join(r,"Claude");return ___namespace.existsSync(n)}return false}function ko(e){let t=e??$t();try{if(!___namespace.existsSync(t))return null;let r=___namespace.readFileSync(t,"utf8"),n=r.match(/^export FLOW_API_KEY=["']?([^"'\r\n]+)["']?$/m);if(n&&n[1])return ie(n[1]);let s=r.match(/^set FLOW_API_KEY=([^\r\n]+)$/m);if(s&&s[1])return ie(s[1])}catch{}return null}function Tn(e,t,r=448){let n=R__namespace.dirname(e);___namespace.mkdirSync(n,{recursive:true});let s=Nt(),o=s?420:r,i=true;try{___namespace.readFileSync(e,"utf8")===t&&(i=!1);}catch{}if(!i){if(!s)try{___namespace.chmodSync(e,r);}catch{}return {written:false}}if(___namespace.existsSync(e)&&(___namespace.copyFileSync(e,e+".bkp"),!s))try{___namespace.chmodSync(e+".bkp",448);}catch{}if(___namespace.writeFileSync(e,t,{encoding:"utf8",mode:o}),!s)try{___namespace.chmodSync(e,r);}catch{}return {written:true}}function Lo(e){let t=$t(),r=e?ie(e):null,n=Nt()?Sn(r):yn(r);return Tn(t,n,!!r?448:493),t}function yn(e){let t=e?ie(e):null,r=["#!/usr/bin/env bash","# Auto-generated by flow-ai-obs \u2014 do not edit manually.","# Wrapper script for Claude Desktop otelHeadersHelper.","# Invokes flow-ai-obs otel-headers to produce fresh OTLP headers at runtime.","set -euo pipefail"];return t&&r.push(`export FLOW_API_KEY="${t}"`),r.push("exec flow-ai-obs otel-headers",""),r.join(`
|
|
40
|
-
`)}function
|
|
41
|
-
`)}function
|
|
42
|
-
`;try{if(
|
|
43
|
-
`;try{if(
|
|
44
|
-
`,{encoding:"utf8",mode:384});try{
|
|
45
|
-
`,{encoding:"utf8"}),{status:"configured",settingsPath:r}}catch(n){return {status:"skipped",settingsPath:r,reason:n.message}}}function
|
|
46
|
-
`,{encoding:"utf8"}),{status:"configured",settingsPath:r}}catch(n){return {status:"skipped",settingsPath:r,reason:n.message}}}var
|
|
47
|
-
`){
|
|
48
|
-
`),r(i);return}if(
|
|
49
|
-
`)),1;let r=Q(t);if(!r)return process.stderr.write(
|
|
39
|
+
`);}}else process.stderr.write(t);}).catch(r=>{l("maybePersistUserEmail",`${e}: getEmailFromToken failed: ${r.message}`);})}var pn=_(()=>{"use strict";Je();me();D();P();});function go(e){return mo.some(t=>t.test(e))}function Eo(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"));return r.email||r.preferred_username||r.upn||r.sub||null}catch{return null}}function Q(e){if(!e)return null;try{let t=e.split(".");if(t.length<2)return null;let r=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:n,clientSecret:s,tenant:o}=r;return !n||!s||!o?null:{clientId:n,clientSecret:s,tenant:o}}catch{return null}}function ke(e){let t;try{t=new URL(e);}catch{throw new Error(`Invalid URL: ${e}`)}let r=process.env[p.FLOW_OBS_ALLOW_HTTP]==="true";if(!r&&t.protocol!=="https:")throw new Error(`URL must use HTTPS: ${e}`);if(t.username||t.password)throw new Error(`URL must not contain embedded credentials: ${e}`);if(!r&&go(t.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${t.hostname}`);return e}async function dn(){let e=Q(process.env[p.ANTHROPIC_AUTH_TOKEN]);return e?{user:await Ge().catch(()=>null)??e.clientId,tenant:e.tenant}:{user:"",tenant:""}}function ho(e){let t=process.env[p.OTEL_EXPORTER_OTLP_HEADERS];if(!t)return null;let r=e.toLowerCase();for(let n of t.split(",")){let s=n.indexOf("=");if(!(s<=0)&&n.slice(0,s).trim().toLowerCase()===r){let o=n.slice(s+1),i=o.search(/[\r\n]/);return (i===-1?o:o.slice(0,i)).trim()||null}}return null}function Pe(){let e=pt(p.FLOW_USER_EMAIL);if(e!==void 0){let r=e.replace(/[\r\n]/g,"").trim();if(r)if(r.length>H.EMAIL_MAX_LENGTH)l("resolveUserEmail",`FLOW_USER_EMAIL exceeds ${H.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!H.EMAIL_HEADER_PATTERN.test(r))l("resolveUserEmail","FLOW_USER_EMAIL contains non-printable or control characters \u2014 skipping");else return l("resolveUserEmail","using FLOW_USER_EMAIL override: [REDACTED]"),r}let t=ho("x-flow-user");if(t){let r=t.replace(/[\r\n]/g,"").trim();if(r.length>H.EMAIL_MAX_LENGTH)l("resolveUserEmail",`x-flow-user from OTEL_EXPORTER_OTLP_HEADERS exceeds ${H.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!H.EMAIL_HEADER_PATTERN.test(r))l("resolveUserEmail","x-flow-user from OTEL_EXPORTER_OTLP_HEADERS is empty or contains non-printable characters \u2014 skipping");else return l("resolveUserEmail","using x-flow-user from OTEL_EXPORTER_OTLP_HEADERS: [REDACTED]"),r}try{let r=Le__namespace.default.userInfo().username||process.env.USERNAME||process.env.USER||"",n=r.lastIndexOf("\\");if(n!==-1&&(r=r.slice(n+1)),r=r.trim().replace(/[^a-zA-Z0-9._%+\-]/g,"").replace(/^\.+/,""),!r)return l("resolveUserEmail","Could not derive x-flow-user: username is empty. Run: flow-ai-obs init"),null;let s=`${r}@ciandt.com`;return l("resolveUserEmail","derived email: [REDACTED]"),s}catch(r){return l("resolveUserEmail",`Could not derive x-flow-user from OS username: ${r.message}. Run: flow-ai-obs init`),null}}function ie(e){if(!e)return null;let t=e.replace(/[\r\n]/g,"").trim();return t?t.length>H.API_KEY_MAX_LENGTH?(l("validateApiKey",`API key exceeds ${H.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):H.API_KEY_PATTERN.test(t)?t:(l("validateApiKey","API key contains invalid or unsafe characters \u2014 rejected"),null):null}function K(){let e=process.env[p.FLOW_API_KEY];return ie(e)}function _o(){return new Date().toISOString().slice(0,10)}async function To(e){let t=_o(),r=await mt();if(r?.lastAuthCheckAt!==t){l("getOrRefreshToken",`daily auth check (last: ${r?.lastAuthCheckAt??"never"})`);let o=Be.MAX_RETRY_ATTEMPTS;for(let i=1;i<=o;i++)try{let a=await X(e);try{await ge({...a,lastAuthCheckAt:t});}catch(u){l("getOrRefreshToken",`saveTokenCache failed (non-fatal): ${u.message}`);}return l("getOrRefreshToken",`daily check passed (attempt ${i}), expires=${a.expiresAt}`),K()?un()||await Er("api-key"):await Er("oauth"),a.accessToken}catch(a){if(a instanceof Ae){if(a.statusCode!==500)throw l("getOrRefreshToken",`daily check auth error (${a.statusCode}) \u2014 propagating immediately`),a;if(i<o){l("getOrRefreshToken",`daily check 500 error (attempt ${i}/${o}) \u2014 retrying in 1s`),await new Promise(c=>setTimeout(c,Be.RETRY_DELAY_MS));continue}throw l("getOrRefreshToken",`daily check failed after ${o} attempts \u2014 propagating`),a}l("getOrRefreshToken",`daily check network error \u2014 using cache: ${a.message}`);break}}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=${e.tenant} clientId=${e.clientId})`);let s=await X(e);try{await ge({...s,lastAuthCheckAt:t});}catch(o){l("getOrRefreshToken",`token cache save failed (non-fatal): ${o.message}`);}return l("getOrRefreshToken",`token refreshed, expires=${s.expiresAt}`),s.accessToken}function yo(e,t){let r=t&&t.accessToken?t.accessToken:"";return {endpoint:e.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function So(e,t,r){let n=Buffer.from(`${t}:${r}`).toString("base64");return {endpoint:e.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${n}`}}async function le(){let e=[],t=Q(process.env[p.ANTHROPIC_AUTH_TOKEN]);l("resolveCredentials",t?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),t&&l("resolveCredentials",`clientId=${t.clientId}`,`tenant=${t.tenant}`);let r=t?t.tenant:"",n=process.env[p.FLOW_TELEMETRY]==="true",s=process.env[p.LANGFUSE_BASE_URL],o=process.env[p.LANGFUSE_PUBLIC_KEY],i=process.env[p.LANGFUSE_SECRET_KEY];if(n&&s&&o&&i){let d="",y=r;t&&(d=await Ge().catch(()=>null)??t.clientId);let S={user:d??"",tenant:y??"",team:"",project:""};e.push({mode:"direct",...So(ke(s),o,i),...S}),l("resolveCredentials","direct mode active",`user=${S.user}`,`tenant=${S.tenant}`);}if(!t){if(e.length===0){let d=[];return d.authError=false,d}return e}let a;try{a=await To(t);}catch(d){if(l("resolveCredentials",`token refresh failed: ${d.message}`,`(tenant=${t.tenant} clientId=${t.clientId})`),e.length>0)return e.authError=true,e;let y=[];return y.authError=true,y}let u={user:Eo(a)??t.clientId,tenant:r,team:"",project:""},h=process.env[p.FLOW_TELEMETRY_GATEWAY]??we();return e.push({mode:"gateway",...yo(ke(h),{accessToken:a}),...u}),e}var mo,W=_(()=>{"use strict";Je();Oe();P();D();pn();me();mo=[/^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 mn(){return !!(process.env.WSL_DISTRO_NAME&&process.platform==="linux")}function Ct(){return process.platform==="win32"||mn()}function Ao(e){let t=e.match(/^\/mnt\/([a-z])\/(.*)$/);if(!t)return e;let r=t[1].toUpperCase(),n=t[2].replace(/\//g,"\\");return `${r}:\\${n}`}function gn(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let n=process.env.LOCALAPPDATA;if(!n)try{let s=child_process.execSync("cmd.exe /c echo %LOCALAPPDATA%",{encoding:"utf8",timeout:5e3}).trim();s&&/^[A-Za-z]:\\/.test(s)&&(n=s);}catch(s){l("getDesktopPaths",`cmd.exe LOCALAPPDATA lookup failed: ${s.message}`);}if(n){let s=n.replace(/^([A-Za-z]):/,(i,a)=>`/mnt/${a.toLowerCase()}`).replace(/\\/g,"/"),o=L__namespace.join(s,C.DIR_3P);return bt(o)}}if(process.platform==="win32"){let n=process.env.LOCALAPPDATA||L__namespace.join(Le__namespace.homedir(),"AppData","Local"),s=L__namespace.join(n,C.DIR_3P);return bt(s)}if(process.platform==="darwin"){let n=L__namespace.join(Le__namespace.homedir(),"Library","Application Support",C.DIR_3P);return bt(n)}let e=Re(),t=process.env.XDG_CONFIG_HOME||L__namespace.join(e.home,".config"),r=L__namespace.join(t,C.DIR_3P);return bt(r)}function bt(e){return {configDir:e,configLibraryDir:L__namespace.join(e,C.CONFIG_LIBRARY_DIR),desktopConfigPath:L__namespace.join(e,C.DESKTOP_CONFIG_FILE),metaPath:L__namespace.join(e,C.CONFIG_LIBRARY_DIR,C.META_FILE)}}function Ut(){let e=oe(),t=L__namespace.dirname(e),r=Ct()?C.WRAPPER_SCRIPT_WIN:C.WRAPPER_SCRIPT_UNIX;return L__namespace.join(t,r)}function Nt(){if(process.env[p.FLOW_OBS_SKIP_DESKTOP_DETECTION])return false;let e=gn();if(E__namespace.existsSync(e.configDir))return true;if(process.platform==="darwin")return ["/Applications/Claude.app",L__namespace.join(Le__namespace.homedir(),"Applications","Claude.app")].some(r=>E__namespace.existsSync(r));if(process.platform==="win32"){let t=process.env.LOCALAPPDATA||L__namespace.join(Le__namespace.homedir(),"AppData","Local"),r=process.env.PROGRAMFILES||"C:\\Program Files";return [L__namespace.join(t,"AnthropicClaude","Claude.exe"),L__namespace.join(r,"Claude","Claude.exe")].some(s=>E__namespace.existsSync(s))}if(process.platform==="linux"){let t=Re(),r=process.env.XDG_CONFIG_HOME||L__namespace.join(t.home,".config"),n=L__namespace.join(r,"Claude");return E__namespace.existsSync(n)}return false}function Oo(e){let t=e??Ut();try{if(!E__namespace.existsSync(t))return null;let r=E__namespace.readFileSync(t,"utf8"),n=r.match(/^export FLOW_API_KEY=["']?([^"'\r\n]+)["']?$/m);if(n&&n[1])return ie(n[1]);let s=r.match(/^set FLOW_API_KEY=([^\r\n]+)$/m);if(s&&s[1])return ie(s[1])}catch{}return null}function En(e,t,r=448){let n=L__namespace.dirname(e);E__namespace.mkdirSync(n,{recursive:true});let s=Ct(),o=s?420:r,i=true;try{E__namespace.readFileSync(e,"utf8")===t&&(i=!1);}catch{}if(!i){if(!s)try{E__namespace.chmodSync(e,r);}catch{}return {written:false}}if(E__namespace.existsSync(e)&&(E__namespace.copyFileSync(e,e+".bkp"),!s))try{E__namespace.chmodSync(e+".bkp",448);}catch{}if(E__namespace.writeFileSync(e,t,{encoding:"utf8",mode:o}),!s)try{E__namespace.chmodSync(e,r);}catch{}return {written:true}}function Lo(e){let t=Ut(),r=e?ie(e):null,n=Ct()?_n(r):hn(r);return En(t,n,!!r?448:493),t}function hn(e){let t=e?ie(e):null,r=["#!/usr/bin/env bash","# Auto-generated by flow-ai-obs \u2014 do not edit manually.","# Wrapper script for Claude Desktop otelHeadersHelper.","# Invokes flow-ai-obs otel-headers to produce fresh OTLP headers at runtime.","set -euo pipefail"];return t&&r.push(`export FLOW_API_KEY="${t}"`),r.push("exec flow-ai-obs otel-headers",""),r.join(`
|
|
40
|
+
`)}function _n(e){let t=e?ie(e):null,r=["@echo off","REM Auto-generated by flow-ai-obs \u2014 do not edit manually.","REM Wrapper script for Claude Desktop otelHeadersHelper.","REM Invokes flow-ai-obs otel-headers to produce fresh OTLP headers at runtime."];return t&&r.push(`set FLOW_API_KEY=${t}`),r.push("flow-ai-obs otel-headers",""),r.join(`\r
|
|
41
|
+
`)}function Tn(e){if(!Nt())return {status:"skipped",reason:"Claude Desktop is not installed"};let t=ie(e);if(!t)return {status:"skipped",reason:"Invalid API key provided"};try{let r=Ut(),n=Ct()?_n(t):hn(t),{written:s}=En(r,n,448);return {status:s?"configured":"already_configured",wrapperScriptPath:r}}catch(r){return {status:"skipped",reason:r.message}}}function ko(e){try{let t=E__namespace.readFileSync(e,"utf8");try{let r=JSON.parse(t);if(r.appliedId&&typeof r.appliedId=="string"&&Ro.test(r.appliedId))return r.appliedId;r.appliedId&&l("getOrCreateConfigUuid","appliedId is not a valid UUID \u2014 generating new UUID");}catch{l("getOrCreateConfigUuid",`corrupted JSON in ${e} \u2014 generating new UUID`);}}catch(t){t.code!=="ENOENT"&&l("getOrCreateConfigUuid",`read error: ${t.message}`);}return fn__namespace.randomUUID()}function Po(e,t){let r=L__namespace.dirname(e);E__namespace.mkdirSync(r,{recursive:true});let n;try{let o=E__namespace.readFileSync(e,"utf8");try{n=JSON.parse(o),(!n.appliedId||typeof n.appliedId!="string")&&(n.appliedId=t),Array.isArray(n.entries)||(n.entries=[]);}catch{l("writeMetaJson",`corrupted JSON in ${e} \u2014 starting fresh`),n={appliedId:t,entries:[]};}}catch(o){o.code!=="ENOENT"&&l("writeMetaJson",`read error: ${o.message}`),n={appliedId:t,entries:[]};}n.entries.some(o=>o.id===t)||n.entries.push({id:t,name:C.CONFIG_NAME});let s=JSON.stringify(n,null,2)+`
|
|
42
|
+
`;try{if(E__namespace.readFileSync(e,"utf8")===s)return}catch{}if(E__namespace.existsSync(e)){E__namespace.copyFileSync(e,e+".bkp");try{E__namespace.chmodSync(e+".bkp",384);}catch{}}E__namespace.writeFileSync(e,s,{encoding:"utf8",mode:384});try{E__namespace.chmodSync(e,384);}catch{}}function Io(e,t,r,n){E__namespace.mkdirSync(e,{recursive:true});let s=L__namespace.resolve(e),o=L__namespace.resolve(e,`${t}.json`);if(!o.startsWith(s+L__namespace.sep))throw new Error(`Security error: invalid config path ${o}`);let i={};try{let c=E__namespace.readFileSync(o,"utf8");try{i=JSON.parse(c);}catch{l("writeConfigLibraryFile",`corrupted JSON in ${o} \u2014 starting fresh`);}}catch(c){c.code!=="ENOENT"&&l("writeConfigLibraryFile",`read error: ${c.message}`);}i[C.KEYS.OTLP_ENDPOINT]=r,i[C.KEYS.OTLP_PROTOCOL]=C.OTLP_PROTOCOL,i[C.KEYS.OTLP_HEADERS_HELPER]=mn()?Ao(n):n,i[C.KEYS.OTLP_RESOURCE_ATTRIBUTES]={[C.CUSTOM_PROVIDER_KEY]:C.CUSTOM_PROVIDER_VALUE};let a=JSON.stringify(i,null,2)+`
|
|
43
|
+
`;try{if(E__namespace.readFileSync(o,"utf8")===a)return o}catch{}if(E__namespace.existsSync(o)){E__namespace.copyFileSync(o,o+".bkp");try{E__namespace.chmodSync(o+".bkp",384);}catch{}}E__namespace.writeFileSync(o,a,{encoding:"utf8",mode:384});try{E__namespace.chmodSync(o,384);}catch{}return o}function vo(e){let t=L__namespace.dirname(e);E__namespace.mkdirSync(t,{recursive:true});let r={};try{let n=E__namespace.readFileSync(e,"utf8");try{r=JSON.parse(n);}catch{l("mergeClaudeDesktopConfig",`corrupted JSON in ${e} \u2014 starting fresh (original backed up to .bkp)`);}}catch(n){n.code!=="ENOENT"&&l("mergeClaudeDesktopConfig",`read error: ${n.message}`);}if(r.deploymentMode!==C.DEPLOYMENT_MODE){if(E__namespace.existsSync(e)){E__namespace.copyFileSync(e,e+".bkp");try{E__namespace.chmodSync(e+".bkp",384);}catch{}}r.deploymentMode=C.DEPLOYMENT_MODE,E__namespace.writeFileSync(e,JSON.stringify(r,null,2)+`
|
|
44
|
+
`,{encoding:"utf8",mode:384});try{E__namespace.chmodSync(e,384);}catch{}}}function yn(e,t){if(!Nt())return {configured:false};let r=gn(),n=e??G().OTEL_ENDPOINT,s=t!==void 0?t:K()??Oo(Ut()),o=Lo(s),i=ko(r.metaPath),a=Io(r.configLibraryDir,i,n,o);return Po(r.metaPath,i),vo(r.desktopConfigPath),{configured:true,configDir:r.configDir,configLibraryPath:a,uuid:i,wrapperScriptPath:o}}var Ro,hr=_(()=>{"use strict";P();ct();W();D();Ro=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;});function _r(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let r=process.env.APPDATA;if(!r)try{let o=child_process.spawnSync("cmd.exe",["/c","echo","%APPDATA%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();o&&/^[A-Za-z]:\\/.test(o)&&(r=o);}catch(s){l("getVsCodeSettingsPath",`cmd.exe APPDATA lookup failed: ${s.message}`);}if(!r)return null;let n=r.replace(/^([A-Za-z]):/,(s,o)=>`/mnt/${o.toLowerCase()}`).replace(/\\/g,"/");return L__namespace.join(n,"Code","User","settings.json")}if(process.platform==="win32"){let r=process.env.APPDATA||L__namespace.join(Le__namespace.homedir(),"AppData","Roaming");return L__namespace.join(r,"Code","User","settings.json")}if(process.platform==="darwin")return L__namespace.join(Le__namespace.homedir(),"Library","Application Support","Code","User","settings.json");let e=process.platform==="linux"&&process.getuid?.()===0?Re().home:process.env.HOME||Le__namespace.homedir(),t=process.env.XDG_CONFIG_HOME||L__namespace.join(e,".config");return L__namespace.join(t,"Code","User","settings.json")}function Sn(e){let t=false,r=false,n="";for(let s=0;s<e.length;s++){let o=e[s];if(t){n+=o,r?r=false:o==="\\"?r=true:o==='"'&&(t=false);continue}if(o==='"'){t=true,n+=o;continue}if(o===","){let i=s+1;for(;i<e.length&&/\s/.test(e[i]);)i++;if(i<e.length&&(e[i]==="}"||e[i]==="]"))continue}n+=o;}return n}function $t(e){if(process.env[p.FLOW_OBS_SKIP_COPILOT_DETECTION])return !!(e&&E__namespace.existsSync(e));if(e&&(E__namespace.existsSync(e)||E__namespace.existsSync(L__namespace.dirname(e))||E__namespace.existsSync(L__namespace.dirname(L__namespace.dirname(e)))))return true;let t=_r();if(t&&(E__namespace.existsSync(t)||E__namespace.existsSync(L__namespace.dirname(t))||E__namespace.existsSync(L__namespace.dirname(L__namespace.dirname(t))))||process.platform==="darwin"&&["/Applications/Visual Studio Code.app",L__namespace.join(Le__namespace.homedir(),"Applications","Visual Studio Code.app")].some(n=>E__namespace.existsSync(n)))return true;if(process.platform==="win32"){let r=process.env.LOCALAPPDATA||L__namespace.join(Le__namespace.homedir(),"AppData","Local"),n=process.env.PROGRAMFILES||"C:\\Program Files",s=process.env["PROGRAMFILES(X86)"]||"C:\\Program Files (x86)";if([L__namespace.join(r,"Programs","Microsoft VS Code","Code.exe"),L__namespace.join(n,"Microsoft VS Code","Code.exe"),L__namespace.join(s,"Microsoft VS Code","Code.exe")].some(i=>E__namespace.existsSync(i)))return true}return !!(process.platform==="linux"&&["/usr/bin/code","/usr/share/code","/snap/bin/code"].some(n=>E__namespace.existsSync(n)))}function wn(e,t={}){let r;try{r=t.customSettingsPath||_r();}catch(n){return {status:"skipped",reason:`VS Code path resolution failed: ${n.message}`}}if(!r)return {status:"skipped",reason:"VS Code path not found"};if(!$t(r))return {status:"skipped",settingsPath:r,reason:"VS Code is not installed"};try{let n={};if(E__namespace.existsSync(r))try{let $=Sn(E__namespace.readFileSync(r,"utf8"));n=JSON.parse($);}catch{return {status:"skipped",settingsPath:r,reason:"VS Code settings.json could not be parsed (unsupported JSONC syntax such as comments)"}}let s=e||G().OTEL_ENDPOINT,o=t.apiKey!==void 0?t.apiKey:K(),i=t.userEmail!==void 0?t.userEmail:Pe(),a=typeof n[T.HEADERS_KEY]=="object"&&n[T.HEADERS_KEY]!==null&&!Array.isArray(n[T.HEADERS_KEY])?n[T.HEADERS_KEY]:{},c={...a};o&&(c[T.HEADER_API_KEY]=o),i&&(c[T.HEADER_USER]=i);let u=Object.keys(c),h=Object.keys(a),d=u.length===0&&(n[T.HEADERS_KEY]===void 0||h.length===0)||u.length===h.length&&u.every($=>a[$]===c[$]);if(n[T.ENABLED_KEY]===T.ENABLED_VALUE&&n[T.EXPORTER_TYPE_KEY]===T.EXPORTER_TYPE_VALUE&&n[T.PROTOCOL_KEY]===T.PROTOCOL_VALUE&&n[T.ENDPOINT_KEY]===s&&d)return {status:"already_configured",settingsPath:r};E__namespace.mkdirSync(L__namespace.dirname(r),{recursive:!0});let S={...n,[T.ENABLED_KEY]:T.ENABLED_VALUE,[T.EXPORTER_TYPE_KEY]:T.EXPORTER_TYPE_VALUE,[T.PROTOCOL_KEY]:T.PROTOCOL_VALUE,[T.ENDPOINT_KEY]:s};return u.length>0&&(S[T.HEADERS_KEY]=c),E__namespace.writeFileSync(r,JSON.stringify(S,null,2)+`
|
|
45
|
+
`,{encoding:"utf8"}),{status:"configured",settingsPath:r}}catch(n){return {status:"skipped",settingsPath:r,reason:n.message}}}function An(e,t={}){let r;try{r=t.customSettingsPath||_r();}catch(n){return {status:"skipped",reason:`VS Code path resolution failed: ${n.message}`}}if(!r)return {status:"skipped",reason:"VS Code path not found"};if(!$t(r))return {status:"skipped",settingsPath:r,reason:"VS Code is not installed"};try{let n={};if(E__namespace.existsSync(r))try{let a=Sn(E__namespace.readFileSync(r,"utf8"));n=JSON.parse(a);}catch{return {status:"skipped",settingsPath:r,reason:"VS Code settings.json could not be parsed (unsupported JSONC syntax such as comments)"}}let s=typeof n[T.HEADERS_KEY]=="object"&&n[T.HEADERS_KEY]!==null&&!Array.isArray(n[T.HEADERS_KEY])?n[T.HEADERS_KEY]:{};if(s[T.HEADER_API_KEY]===e)return {status:"already_configured",settingsPath:r};let o={...s,[T.HEADER_API_KEY]:e};E__namespace.mkdirSync(L__namespace.dirname(r),{recursive:!0});let i={...n,[T.ENABLED_KEY]:n[T.ENABLED_KEY]??T.ENABLED_VALUE,[T.EXPORTER_TYPE_KEY]:n[T.EXPORTER_TYPE_KEY]??T.EXPORTER_TYPE_VALUE,[T.PROTOCOL_KEY]:n[T.PROTOCOL_KEY]??T.PROTOCOL_VALUE,[T.ENDPOINT_KEY]:n[T.ENDPOINT_KEY]??G().OTEL_ENDPOINT,[T.HEADERS_KEY]:o};return E__namespace.writeFileSync(r,JSON.stringify(i,null,2)+`
|
|
46
|
+
`,{encoding:"utf8"}),{status:"configured",settingsPath:r}}catch(n){return {status:"skipped",settingsPath:r,reason:n.message}}}var Tr=_(()=>{"use strict";P();W();ct();D();});var Ln={};se(Ln,{clearLoggedOutMarker:()=>Sr,isLoggedOut:()=>No,markLoggedOut:()=>Uo});function yr(){return L__namespace.default.join(Le__namespace.default.homedir(),".claude","flow-obs",".logged-out")}function Uo(){try{let e=yr();E__namespace.default.mkdirSync(L__namespace.default.dirname(e),{recursive:!0}),E__namespace.default.writeFileSync(e,"",{mode:384});}catch{}}function Sr(){try{E__namespace.default.unlinkSync(yr());}catch{}}function No(){try{return E__namespace.default.existsSync(yr())}catch{return false}}var wr=_(()=>{"use strict";});function Ar(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():q("FLOW_BASE_URL")}function $o(){return q(p.ANTHROPIC_AUTH_TOKEN)??void 0}async function Dt(){let e=Ar();if(!e)return {ok:false,baseUrl:"",user:"",tenant:"",notConfigured:true,error:"NOT_CONFIGURED"};try{let s=new URL(e);if(s.protocol!=="https:"&&s.protocol!=="http:")throw new Error}catch{return {ok:false,baseUrl:e,user:"",tenant:"",notConfigured:true,error:"NOT_CONFIGURED"}}let t=$o(),r=Q(t);if(!r)return {ok:false,baseUrl:e,user:"",tenant:"",error:"No credentials found"};let n=process.env.FLOW_BASE_URL;process.env.FLOW_BASE_URL=e;try{let s=await X({clientId:r.clientId,clientSecret:r.clientSecret,tenant:r.tenant});await ge({accessToken:s.accessToken,expiresAt:s.expiresAt});let o=r.clientId;try{let i=s.accessToken.split(".");if(i.length>=2){let a=JSON.parse(Buffer.from(i[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));o=a.email??a.preferred_username??a.upn??a.sub??o;}}catch{}return {ok:!0,baseUrl:e,user:o,tenant:r.tenant}}catch(s){return {ok:false,baseUrl:e,user:r.clientId,tenant:r.tenant,error:s.message}}finally{n===void 0?delete process.env.FLOW_BASE_URL:process.env.FLOW_BASE_URL=n;}}var Or=_(()=>{"use strict";Je();W();me();P();Oe();});var Et={};se(Et,{promptRaw:()=>Lr,runLogin:()=>xo});function ee(e){return typeof e=="string"?e.replace(Fo,""):e}function Lr(e,t={}){return new Promise((r,n)=>{if(typeof process.stdin.setRawMode!="function"){n(new Error("NOT_A_TTY"));return}let{masked:s=false,defaultValue:o=""}=t;process.stdout.write(e+o);let i=o;function a(){try{process.stdin.setRawMode(!1);}catch{}}process.once("uncaughtException",a),process.once("unhandledRejection",a);let c=h=>{if(h===""){u(),n(new Error("SIGINT"));return}if(h==="\r"||h===`
|
|
47
|
+
`){u(),process.stdout.write(`
|
|
48
|
+
`),r(i);return}if(h==="\x7F"){i.length>0&&(i=i.slice(0,-1),process.stdout.write("\b \b"));return}h.startsWith("\x1B")||(i+=h,process.stdout.write(s?"*".repeat(h.length):h));};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 xt(e,t,r=false){let n=Ar(),s=process.env.FLOW_BASE_URL;n&&(process.env.FLOW_BASE_URL=n);try{let{accessToken:o,expiresAt:i}=await X(e);if(r)return {jwt:t,accessToken:o,expiresAt:i};Ke({[p.ANTHROPIC_AUTH_TOKEN]:t}),Sr(),await ge({accessToken:o,expiresAt:i});}finally{s===void 0?delete process.env.FLOW_BASE_URL:process.env.FLOW_BASE_URL=s;}}async function Do(e=false){try{let t=(await Lr(M(" ? ")+"Flow API Token (JWT): ",{masked:!0})).trim();if(!t)return process.stderr.write(k(` \u2717 Token is required
|
|
49
|
+
`)),1;let r=Q(t);if(!r)return process.stderr.write(k(` \u2717 Invalid Flow API Token
|
|
50
50
|
`)),1;if(process.stdout.write(m(` Authenticating...
|
|
51
|
-
`)),e){let n=await
|
|
52
|
-
${
|
|
51
|
+
`)),e){let n=await xt(r,t,!0);return process.stdout.write(`
|
|
52
|
+
${R("\u2713")} ${v("Authenticated")}
|
|
53
53
|
`+m(` Tenant: ${ee(r.tenant)}
|
|
54
54
|
`)+m(` Storage: pending (will be written at end of init)
|
|
55
55
|
|
|
56
|
-
`)),{code:0,result:n}}return await
|
|
57
|
-
${
|
|
56
|
+
`)),{code:0,result:n}}return await xt(r,t),process.stdout.write(`
|
|
57
|
+
${R("\u2713")} ${v("Authenticated")}
|
|
58
58
|
`+m(` Tenant: ${ee(r.tenant)}
|
|
59
59
|
`)+m(` Storage: ANTHROPIC_AUTH_TOKEN (settings.json)
|
|
60
60
|
|
|
61
61
|
`)),0}catch(t){if(t.message==="SIGINT"||t.message==="NOT_A_TTY")throw t;return process.stderr.write(`
|
|
62
|
-
${
|
|
62
|
+
${k("\u2717")} ${v("Authentication failed:")}
|
|
63
63
|
${ee(t.message)}
|
|
64
64
|
|
|
65
|
-
`),1}}async function
|
|
66
|
-
`)),1;try{if(r){let a=await
|
|
65
|
+
`),1}}async function xo(e={}){let t=kt();if(t)return t;let{deferPersist:r=false,skipAuthCheck:n=false}=e;if(e.token){let o=e.token.trim(),i=Q(o);if(!i)return process.stderr.write(k(` \u2717 Invalid Flow API Token
|
|
66
|
+
`)),1;try{if(r){let a=await xt(i,o,!0);return process.stdout.write(R(` \u2713 Authenticated. Tenant: ${ee(i.tenant)}
|
|
67
67
|
|
|
68
|
-
`)),{code:0,result:a}}return await
|
|
68
|
+
`)),{code:0,result:a}}return await xt(i,o),process.stdout.write(R(` \u2713 Authenticated. Tenant: ${ee(i.tenant)}
|
|
69
69
|
|
|
70
|
-
`)),0}catch(a){return process.stderr.write(
|
|
71
|
-
`)),1}}if(e.clientId||e.clientSecret||e.tenant)return process.stderr.write(
|
|
70
|
+
`)),0}catch(a){return process.stderr.write(k(` \u2717 Authentication failed: ${ee(a.message)}
|
|
71
|
+
`)),1}}if(e.clientId||e.clientSecret||e.tenant)return process.stderr.write(k(` \u2717 Passing individual credential flags (--client-id, --client-secret, --tenant) is no longer supported.
|
|
72
72
|
`)+` LiteLLM requires a signed Flow API Token. Pass --token <JWT> instead.
|
|
73
73
|
|
|
74
|
-
`),1;let s=await
|
|
75
|
-
`),process.stdout.write(
|
|
76
|
-
`)),s.notConfigured)return process.stdout.write(` ${
|
|
74
|
+
`),1;let s=await Dt();if(!n){if(process.stdout.write(`
|
|
75
|
+
`),process.stdout.write(v(` Auth
|
|
76
|
+
`)),s.notConfigured)return process.stdout.write(` ${I("\u26A0")} Not configured
|
|
77
77
|
`),process.stdout.write(m(" Run `flow-ai-obs init` to set up the environment first.\n")),process.stdout.write(`
|
|
78
|
-
`),1;if(s.ok){process.stdout.write(` ${
|
|
78
|
+
`),1;if(s.ok){process.stdout.write(` ${R("\u2713")} Authenticated
|
|
79
79
|
`),process.stdout.write(m(" URL: ")+ee(s.baseUrl)+`
|
|
80
80
|
`),process.stdout.write(m(" Tenant: ")+ee(s.tenant)+`
|
|
81
81
|
`),process.stdout.write(m(" User: ")+ee(s.user)+`
|
|
82
82
|
`),process.stdout.write(`
|
|
83
|
-
`);let o;try{o=await
|
|
84
|
-
`),130;if(i.message==="NOT_A_TTY")return process.stdout.write(
|
|
83
|
+
`);let o;try{o=await Lr(M(" ? ")+"Re-authenticate? (y/N): ");}catch(i){if(i.message==="SIGINT")return process.stdout.write(`
|
|
84
|
+
`),130;if(i.message==="NOT_A_TTY")return process.stdout.write(R(` \u2713 Using existing credentials.
|
|
85
85
|
|
|
86
|
-
`)),0;throw i}if(o.trim().toLowerCase()!=="y")return process.stdout.write(
|
|
86
|
+
`)),0;throw i}if(o.trim().toLowerCase()!=="y")return process.stdout.write(R(` \u2713 Using existing credentials.
|
|
87
87
|
|
|
88
|
-
`)),0}else s.error==="No credentials found"?(process.stdout.write(` ${
|
|
88
|
+
`)),0}else s.error==="No credentials found"?(process.stdout.write(` ${I("\u26A0")} Not authenticated
|
|
89
89
|
`),process.stdout.write(m(` URL: ${s.baseUrl}
|
|
90
90
|
`)),process.stdout.write(`
|
|
91
|
-
`)):(process.stdout.write(` ${
|
|
91
|
+
`)):(process.stdout.write(` ${I("\u26A0")} Session not valid for current endpoint
|
|
92
92
|
`),process.stdout.write(m(" URL: ")+ee(s.baseUrl)+`
|
|
93
93
|
`),process.stdout.write(m(" Tenant: ")+ee(s.tenant)+`
|
|
94
94
|
`),process.stdout.write(m(" User: ")+m("(not authenticated)")+`
|
|
95
95
|
`),process.stdout.write(`
|
|
96
|
-
`));}try{return await
|
|
97
|
-
`),130;if(o.message==="NOT_A_TTY")return process.stderr.write(
|
|
96
|
+
`));}try{return await Do(r)}catch(o){if(o.message==="SIGINT")return process.stdout.write(`
|
|
97
|
+
`),130;if(o.message==="NOT_A_TTY")return process.stderr.write(k(` \u2717 No TTY available for interactive login.
|
|
98
98
|
`)+` Pass --token <JWT> for non-interactive use.
|
|
99
99
|
|
|
100
|
-
`),1;throw o}}var
|
|
100
|
+
`),1;throw o}}var Fo,ht=_(()=>{"use strict";Je();wr();Oe();W();me();P();pe();Pt();Or();Fo=/[\x00-\x08\x0B-\x1F\x7F]|\x1b\[[0-9;]*[a-zA-Z]/g;});var In={};se(In,{normalizeCustomUrl:()=>Pn,runInit:()=>Bo,validateCustomUrl:()=>Pr,validateEmail:()=>kr});function Mt(e,t,r){process.stdout.write(v(M(`
|
|
101
101
|
[${e}/${t}] ${r}
|
|
102
|
-
`)));}function Ee(e){process.stdout.write(` ${
|
|
103
|
-
`);}function
|
|
104
|
-
`);}function
|
|
105
|
-
`);}function
|
|
106
|
-
`,{encoding:"utf8",mode:384});}catch{}return e}function
|
|
102
|
+
`)));}function Ee(e){process.stdout.write(` ${R("\u2713")} ${e}
|
|
103
|
+
`);}function ve(e){process.stdout.write(` ${I("\u26A0")} ${e}
|
|
104
|
+
`);}function Ie(e){process.stdout.write(` ${m(e)}
|
|
105
|
+
`);}function Rn(){return !!q(p.ANTHROPIC_AUTH_TOKEN)}function Mo(){let e=cr();if(!e)return null;Ke({FLOW_BASE_URL:e});try{let t=It(),r={};try{r=JSON.parse(E__namespace.readFileSync(t,"utf8"));}catch{return e}delete r.baseUrl,Object.keys(r).length===0?E__namespace.unlinkSync(t):E__namespace.writeFileSync(t,JSON.stringify(r,null,2)+`
|
|
106
|
+
`,{encoding:"utf8",mode:384});}catch{}return e}function Pn(e){let t=e.trim().replace(/\\/g,"/");/^https?:\/\//i.test(t)||(t=`https://${t}`);try{let r=new URL(t);return `${r.protocol}//${r.host}`}catch{return t}}function Pr(e,t=false){if(t){let o=/^https?:\/\//i.test(e.trim())?e.trim().replace(/\\/g,"/"):`https://${e.trim().replace(/\\/g,"/")}`,i;try{i=new URL(o);}catch{throw new Error(`Invalid URL: ${e}`)}if(i.protocol!=="https:")throw new Error(`Custom URL must use HTTPS: ${e}`);if(i.pathname!=="/"&&i.pathname!=="")throw new Error(`Custom URL must be a base URL with no path beyond the root.
|
|
107
107
|
Received: ${e}
|
|
108
108
|
Expected: https://tenant.example.com`);if(i.search)throw new Error(`Custom URL must not contain query parameters.
|
|
109
109
|
Received: ${e}
|
|
@@ -111,170 +111,163 @@
|
|
|
111
111
|
Received: ${e}
|
|
112
112
|
Expected: https://tenant.example.com`);if(i.username||i.password)throw new Error(`Custom URL must not contain embedded credentials.
|
|
113
113
|
Received: ${e}
|
|
114
|
-
Expected: https://tenant.example.com`);if(!i.hostname.includes("."))throw new Error(`Invalid domain: ${i.hostname}. Expected format: tenant.example.com`);let a=`${i.protocol}//${i.host}`,c=process.env[
|
|
114
|
+
Expected: https://tenant.example.com`);if(!i.hostname.includes("."))throw new Error(`Invalid domain: ${i.hostname}. Expected format: tenant.example.com`);let a=`${i.protocol}//${i.host}`,c=process.env[p.FLOW_OBS_ALLOW_HTTP];try{delete process.env[p.FLOW_OBS_ALLOW_HTTP],ke(a);}finally{c!==void 0&&(process.env[p.FLOW_OBS_ALLOW_HTTP]=c);}return a}let r=Pn(e),n;try{n=new URL(r);}catch{throw new Error(`Invalid URL: ${e}`)}if(n.protocol!=="https:")throw new Error(`Custom URL must use HTTPS: ${e}`);if(!n.hostname.includes("."))throw new Error(`Invalid domain: ${n.hostname}. Expected format: tenant.example.com`);let s=process.env[p.FLOW_OBS_ALLOW_HTTP];try{delete process.env[p.FLOW_OBS_ALLOW_HTTP],ke(r);}finally{s!==void 0&&(process.env[p.FLOW_OBS_ALLOW_HTTP]=s);}return r.replace(/\/$/,"")}async function Rr(){for(let e=1;e<=3;e++)try{let t=await Zt(" Enter your Flow domain (e.g., tenant.ciandt.com)");return Pr(t)}catch(t){if(process.stderr.write(I(` \u2717 ${t.message}
|
|
115
115
|
|
|
116
|
-
`)),e===3)throw process.stderr.write(
|
|
116
|
+
`)),e===3)throw process.stderr.write(k(` Too many invalid attempts.
|
|
117
117
|
|
|
118
|
-
`)),new Error("Too many invalid URL attempts")}throw new Error("Too many invalid URL attempts")}function
|
|
119
|
-
To set it: flow-ai-obs init --custom-email <you@company.com>`),null}r&&
|
|
118
|
+
`)),new Error("Too many invalid URL attempts")}throw new Error("Too many invalid URL attempts")}function kn(e){return e.replace(/[\r\n]/g,"").trim()}function kr(e){if(e.length>254)return "Email must not exceed 254 characters";if(/\s/.test(e))return "Email must not contain spaces";if((e.match(/@/g)??[]).length!==1)return "Email must contain exactly one @";let t=e.indexOf("@");if(t<=0)return "Email must contain a local part before @";let r=e.slice(t+1);if(!r)return "Email must contain a domain after @";if(r.startsWith("."))return `Invalid email domain: ${r}`;if(/^\d{1,3}(\.\d{1,3}){3}$/.test(r))return "Email domain cannot be an IP address";try{let n=new URL(`https://${r}`);if(!n.hostname.includes("."))return "Email domain must contain at least one dot";if(n.pathname!=="/"||n.search||n.hash||n.port)return `Invalid email domain: ${r}`}catch(n){return l("validateEmail",`URL parse error for domain ${r}: ${n.message}`),`Invalid email domain: ${r}`}return null}async function Wo(e,t,r){let n=q(p.FLOW_USER_EMAIL),s=Pe(),o=s??"(could not be derived)";if(!e||!de()){if(r){let c=kn(r);if(!c)throw new Error("--custom-email: value is empty after normalization");let u=kr(c);if(u)throw new Error(`--custom-email: ${u}`);return Ee(`Email: ${v(c)}`),c}return n??s?Ee(`Email: ${v(n??s)}`):ve(`Email not configured \u2014 telemetry will not include user identity.
|
|
119
|
+
To set it: flow-ai-obs init --custom-email <you@company.com>`),null}r&&ve("--custom-email is ignored in interactive mode. Use --no-interactive to apply it.");async function i(){for(let c=1;c<=3;c++){let u;try{u=await Zt(" Enter your corporate email (e.g., user@company.com)");}catch(y){throw process.stderr.write(k(` \u2717 Input error: ${y.message}
|
|
120
120
|
|
|
121
|
-
`)),
|
|
121
|
+
`)),y}let h=kn(u),d=kr(h);if(!d)return h;process.stderr.write(I(` \u2717 ${d}
|
|
122
122
|
|
|
123
|
-
`));}throw process.stderr.write(
|
|
123
|
+
`));}throw process.stderr.write(k(` Too many invalid attempts.
|
|
124
124
|
|
|
125
|
-
`)),new Error("Too many invalid email attempts")}async function a(){let c=await i();return process.stdout.write(
|
|
125
|
+
`)),new Error("Too many invalid email attempts")}async function a(){let c=await i();return process.stdout.write(R(` \u2713 Email: ${c}
|
|
126
126
|
|
|
127
|
-
`)),c}return n?await
|
|
127
|
+
`)),c}return n?await st(` Registered email: ${v(n)} \u2014 still correct?`,true)?(process.stdout.write(R(` \u2713 Email: ${v(n)}
|
|
128
128
|
|
|
129
|
-
`)),null):a():s?t?await
|
|
129
|
+
`)),null):a():s?t?await st(" Is your corporate email domain @ciandt.com?",true)?(process.stdout.write(R(` \u2713 Email: ${v(o)}
|
|
130
130
|
|
|
131
|
-
`)),s):a():(process.stdout.write(
|
|
131
|
+
`)),s):a():(process.stdout.write(R(` \u2713 Email: ${v(o)}
|
|
132
132
|
|
|
133
|
-
`)),s):(process.stdout.write(
|
|
133
|
+
`)),s):(process.stdout.write(I(`
|
|
134
134
|
\u26A0 Could not derive email from OS username.
|
|
135
|
-
`)),a())}function
|
|
136
|
-
To fix: unset FLOW_API_KEY && flow-ai-obs init`);let s=n?3:4;process.stdout.write(
|
|
135
|
+
`)),a())}function _t(){let e=q(p.FLOW_BASE_URL);return e&&e.trim()?e.trim():null}async function Bo(e={}){let t=kt();if(t)return t;let r=e.url,n=!!K();!n&&process.env[p.FLOW_API_KEY]&&ve(`FLOW_API_KEY appears to be misconfigured \u2014 authentication with Flow is required.
|
|
136
|
+
To fix: unset FLOW_API_KEY && flow-ai-obs init`);let s=n?3:4;process.stdout.write(v(M(`
|
|
137
137
|
flow-ai-obs init
|
|
138
138
|
`))),process.stdout.write(m(` Configuring your development environment:
|
|
139
139
|
|
|
140
140
|
`)),process.stdout.write(m(` [1/${s}] Flow Environment Setup Configure Flow URLs and LLM routing
|
|
141
141
|
`)),process.stdout.write(m(` [2/${s}] User Identity Capture user email for telemetry
|
|
142
|
-
`)),n?process.stdout.write(m(` [3/${s}] Observability OpenTelemetry metrics, logs and
|
|
142
|
+
`)),n?process.stdout.write(m(` [3/${s}] Observability OpenTelemetry metrics, logs and traces
|
|
143
143
|
`)):(process.stdout.write(m(` [3/${s}] Authentication Authenticate with Flow
|
|
144
|
-
`)),process.stdout.write(m(` [4/${s}] Observability OpenTelemetry metrics, logs and
|
|
145
|
-
`))),
|
|
146
|
-
`)+
|
|
147
|
-
`)+
|
|
148
|
-
|
|
149
|
-
`)),
|
|
150
|
-
Current base URL: ${
|
|
151
|
-
`),await
|
|
152
|
-
`),await
|
|
153
|
-
`);}if(!r&&!e.noInteractive&&!de()){let f=
|
|
144
|
+
`)),process.stdout.write(m(` [4/${s}] Observability OpenTelemetry metrics, logs and traces
|
|
145
|
+
`))),Mt(1,s,"Flow Environment Setup");let o=false;{let f=q(p.FLOW_BASE_URL);if(f&&(ve(`Base URL already configured (FLOW_BASE_URL=${f})`),!e.noInteractive&&de()))try{let{promptRaw:F}=await Promise.resolve().then(()=>(ht(),Et));o=(await F(M(" ? ")+"Replace existing base URL configuration? [y/N]: ")).trim().toLowerCase()==="y",o||Ie("Keeping existing base URL configuration.");}catch{}}if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"&&process.stdout.write(I(` \u26A0 WSL detected. If your code assistant is installed on Windows, install flow-ai-obs
|
|
146
|
+
`)+I(" on Windows too: ")+M(`npm install -g @ciandt-flow/flow-ai-obs
|
|
147
|
+
`)+I(` Without the Windows install, observability will not work for the Windows-side code assistant.
|
|
148
|
+
|
|
149
|
+
`)),Mo(),!r&&!e.noInteractive&&de()){let f=_t();o?r=await Rr():f?(process.stdout.write(`
|
|
150
|
+
Current base URL: ${v(f)}
|
|
151
|
+
`),await st(" Keep this URL?",true)||(r=await Rr())):(process.stdout.write(`
|
|
152
|
+
`),await st(" Does your organization use a custom Flow URL?",false)?r=await Rr():Ee("Using default Flow Base URL: https://flow.ciandt.com")),process.stdout.write(`
|
|
153
|
+
`);}if(!r&&!e.noInteractive&&!de()){let f=_t();if(f)process.stdout.write(I(` \u26A0 Non-interactive environment detected.
|
|
154
154
|
`)+m(` Using URL: ${f}
|
|
155
155
|
|
|
156
156
|
`));else return process.stderr.write(` \u2717 No URL configured and no TTY available.
|
|
157
157
|
Run: flow-ai-obs init --custom-url <URL>
|
|
158
158
|
|
|
159
|
-
`),1}let i,a=false;if(r){let f;try{f=
|
|
159
|
+
`),1}let i,a=false;if(r){let f;try{f=Pr(r,!0);}catch(re){return process.stderr.write(`
|
|
160
160
|
\u2717 Invalid --custom-url: ${re.message}
|
|
161
161
|
|
|
162
|
-
`),1}let
|
|
163
|
-
`)+m(` Previous: ${
|
|
162
|
+
`),1}let F=_t();i=f,a=!!F&&F!==f,a?process.stdout.write(I(` \u26A0 Base URL changed \u2014 re-authentication required.
|
|
163
|
+
`)+m(` Previous: ${F}
|
|
164
164
|
`)+m(` New: ${f}
|
|
165
165
|
|
|
166
|
-
`)):process.stdout.write(
|
|
166
|
+
`)):process.stdout.write(R(` \u2713 Base URL configured: ${f}
|
|
167
167
|
|
|
168
|
-
`));}else i=
|
|
168
|
+
`));}else i=_t()??"https://flow.ciandt.com";let c={FLOW_BASE_URL:i,OTEL_EXPORTER_OTLP_ENDPOINT:`${i}/otel`};process.env.FLOW_BASE_URL=i,process.stdout.write(R(`
|
|
169
169
|
\u2713 Flow environment ready.
|
|
170
|
-
`));let
|
|
171
|
-
`);
|
|
172
|
-
${
|
|
173
|
-
${
|
|
170
|
+
`));let u=36;for(let[f,F]of Object.entries(c))process.stdout.write(m(` ${f.padEnd(u)}`)+F+`
|
|
171
|
+
`);Mt(2,s,"User Identity");let h=await Wo(!e.noInteractive,!!(r??cr()),e.email),d=null;if(n)l("init","FLOW_API_KEY detected \u2014 skipping OAuth authentication step");else {Mt(3,s,"Authentication");let f=_t(),F=!!f&&f!==i;if(!Rn()||a||F)if(e.noInteractive||!de()){let{token:ce,clientId:j,clientSecret:rt,tenant:ne}=e,ye=!!ce,ue=!!(j||rt||ne);if(ye){let{runLogin:At}=await Promise.resolve().then(()=>(ht(),Et)),Fe;try{Fe=await At({deferPersist:!0,token:ce});}catch(Jt){return process.stderr.write(`
|
|
172
|
+
${k("\u2717")} Authentication failed unexpectedly.
|
|
173
|
+
${Jt.message}
|
|
174
174
|
|
|
175
|
-
`),1}if(typeof
|
|
176
|
-
${
|
|
175
|
+
`),1}if(typeof Fe=="number")return Fe;d=Fe.result;}else return ue?(process.stderr.write(`
|
|
176
|
+
${k("\u2717")} Passing individual credential flags (--client-id, --client-secret, --tenant) is no longer supported.
|
|
177
177
|
LiteLLM requires a signed Flow API Token. Pass --token <JWT> instead.
|
|
178
178
|
|
|
179
179
|
`),1):(process.stderr.write(`
|
|
180
|
-
${
|
|
180
|
+
${k("\u2717")} Authentication required.
|
|
181
181
|
Run: flow-ai-obs login
|
|
182
182
|
|
|
183
183
|
`),1)}else {(e.token||e.clientId||e.clientSecret||e.tenant)&&process.stderr.write(`
|
|
184
|
-
${
|
|
184
|
+
${I("\u26A0")} Credential flags (--token, --client-id, --client-secret, --tenant) are only used with --no-interactive.
|
|
185
185
|
Continuing with interactive authentication.
|
|
186
186
|
|
|
187
187
|
`),process.stdout.write(`
|
|
188
|
-
${
|
|
188
|
+
${I("\u26A0")} Authentication required for the new endpoint.
|
|
189
189
|
|
|
190
|
-
`);let{runLogin:
|
|
191
|
-
${
|
|
192
|
-
`);let
|
|
190
|
+
`);let{runLogin:ce}=await Promise.resolve().then(()=>(ht(),Et)),j=await ce({deferPersist:true,skipAuthCheck:a});if(typeof j=="number")return j;d=j.result;}else Ee("Already authenticated \u2014 skipping."),Ie("ANTHROPIC_AUTH_TOKEN will be preserved in settings.json");}let y=Rn()?q(p.ANTHROPIC_AUTH_TOKEN):null,S={...c,...h?{[p.FLOW_USER_EMAIL]:h}:{},...d?{[p.ANTHROPIC_AUTH_TOKEN]:d.jwt}:{},...y&&!d?{[p.ANTHROPIC_AUTH_TOKEN]:y}:{}},$,b;Mt(n?3:4,s,"Observability (OpenTelemetry)"),process.stdout.write(`
|
|
191
|
+
${v("Metrics and Logs")}
|
|
192
|
+
`);let $e={...fe,OTEL_EXPORTER_OTLP_ENDPOINT:c.OTEL_EXPORTER_OTLP_ENDPOINT};for(let[f,F]of Object.entries($e))process.stdout.write(m(` ${f.padEnd(36)}`)+F+`
|
|
193
193
|
`);process.stdout.write(`
|
|
194
|
-
`),process.
|
|
195
|
-
`)
|
|
196
|
-
|
|
197
|
-
`);
|
|
198
|
-
`),
|
|
199
|
-
|
|
200
|
-
`);}let{clearLoggedOutMarker:C}=await Promise.resolve().then(()=>(kr(),Pn));C();}if(Ee(`Settings written: ${w}`),O.length>0&&(process.stdout.write(`
|
|
201
|
-
`),process.stdout.write(b(` \u26A0 Third-party hooks preserved on: ${O.join(", ")}
|
|
202
|
-
`)),process.stdout.write(m(` flow-ai-obs was prepended \u2014 it executes first.
|
|
194
|
+
`);try{({settingsPath:$,preserved:b}=rn(c.OTEL_EXPORTER_OTLP_ENDPOINT,S));}catch(f){return process.stderr.write(` \u2717 Failed to write settings: ${f.message}
|
|
195
|
+
`),1}if(d){let{saveTokenCache:f}=await Promise.resolve().then(()=>(Je(),ln));try{await f({accessToken:d.accessToken,expiresAt:d.expiresAt});}catch(re){process.stderr.write(` ${I("\u26A0")} Token cache could not be saved: ${re.message}
|
|
196
|
+
Credentials will be re-resolved on first use.
|
|
197
|
+
`);}let{clearLoggedOutMarker:F}=await Promise.resolve().then(()=>(wr(),Ln));F();}if(Ee(`Settings written: ${$}`),b.length>0&&(process.stdout.write(`
|
|
198
|
+
`),process.stdout.write(I(` \u26A0 Third-party hooks preserved on: ${b.join(", ")}
|
|
199
|
+
`)),process.stdout.write(m(` flow-ai-obs no longer manages lifecycle hooks \u2014 those third-party entries were left untouched.
|
|
203
200
|
`))),process.stdout.write(`
|
|
204
|
-
`),
|
|
205
|
-
`);try{let f=
|
|
206
|
-
`)));}catch(f){
|
|
207
|
-
`);}if(
|
|
208
|
-
`);try{let f=
|
|
201
|
+
`),Nt()){process.stdout.write(` ${v("Claude Desktop")}
|
|
202
|
+
`);try{let f=yn(c.OTEL_EXPORTER_OTLP_ENDPOINT,K()??void 0);f.configured&&(Ee(`Desktop config written: ${f.configLibraryPath}`),Ie(`Wrapper script: ${f.wrapperScriptPath}`),Ie(`Config UUID: ${f.uuid}`),process.stdout.write(m(` Relaunch Claude Desktop to activate OTLP telemetry.
|
|
203
|
+
`)));}catch(f){ve(`Claude Desktop config failed: ${f.message}`),Ie("CLI observability is configured \u2014 Desktop config can be retried.");}process.stdout.write(`
|
|
204
|
+
`);}if($t()){process.stdout.write(` ${v("GitHub Copilot (VS Code)")}
|
|
205
|
+
`);try{let f=wn(c.OTEL_EXPORTER_OTLP_ENDPOINT,{apiKey:K(),userEmail:h??Pe()});f.status==="configured"?Ee(`Copilot OTEL configured: ${f.settingsPath}`):f.status==="already_configured"?Ee("Copilot OTEL: Already configured \u2014 skipping."):(ve(`Copilot OTEL skipped: ${f.reason??"unknown"}`),f.reason?.includes("could not be parsed")&&Ie("Remove comments from VS Code settings.json and re-run init, or add the keys manually."));}catch(f){ve(`GitHub Copilot OTEL config failed: ${f.message}`),Ie("CLI observability is configured \u2014 Copilot config can be retried.");}process.stdout.write(`
|
|
209
206
|
`);}return e.skipHint||(process.stdout.write(`
|
|
210
|
-
`),process.stdout.write(
|
|
207
|
+
`),process.stdout.write(R(` \u2713 Setup complete.
|
|
211
208
|
|
|
212
209
|
`)),process.stdout.write(m(` Verify your configuration:
|
|
213
210
|
`)+M(` flow-ai-obs status
|
|
214
211
|
|
|
215
212
|
`)+m(` Start your code assistant and begin working.
|
|
216
213
|
|
|
217
|
-
`))),0}var
|
|
218
|
-
`);}function
|
|
219
|
-
`);}function
|
|
220
|
-
`);}function
|
|
221
|
-
`);}function
|
|
222
|
-
`);}function
|
|
223
|
-
`);}function
|
|
214
|
+
`))),0}var vn=_(()=>{"use strict";me();P();pe();Pt();lr();W();Qt();D();hr();Tr();});var Fn={};se(Fn,{runStatus:()=>Ko});function bn(e){return !e||e.length<=8?"****":e.slice(0,4)+"****...****"+e.slice(-4)}function Ho(e){process.stdout.write(` ${R("\u2713")} ${e}
|
|
215
|
+
`);}function Ir(e){process.stdout.write(` ${I("\u26A0")} ${e}
|
|
216
|
+
`);}function Wt(e){process.stdout.write(` ${R("\u2713")} ${e}
|
|
217
|
+
`);}function vr(e){process.stdout.write(` ${I("\u26A0")} ${e}
|
|
218
|
+
`);}function Bt(e){process.stdout.write(` ${k("\u2717")} ${e}
|
|
219
|
+
`);}function ze(e){process.stdout.write(` ${m(e)}
|
|
220
|
+
`);}function Cn(e){process.stdout.write(v(M(`
|
|
224
221
|
${e}
|
|
225
|
-
`)));}function
|
|
222
|
+
`)));}function Un(e,t=false){let r=t?`${I("\u26A0")} ${v(I(e))}`:v(e);process.stdout.write(`
|
|
226
223
|
${r}
|
|
227
|
-
`);}function
|
|
228
|
-
`);}async function
|
|
224
|
+
`);}function Nn(){process.stdout.write(`
|
|
225
|
+
`);}async function Ko(){Cn("Auth");let e=await Dt();e.notConfigured?(Ir("Not configured."),process.stdout.write(`
|
|
229
226
|
`),process.stdout.write(` ${m("Run `flow-ai-obs init` to set up.")}
|
|
230
|
-
`)):!e.ok&&e.error==="No credentials found"?
|
|
227
|
+
`)):!e.ok&&e.error==="No credentials found"?Ir("Not authenticated. Run `flow-ai-obs login` to set up."):e.ok?(Ho("Authenticated"),process.stdout.write(` ${m("URL: ")}${e.baseUrl}
|
|
231
228
|
`),process.stdout.write(` ${m("Tenant: ")}${e.tenant}
|
|
232
229
|
`),process.stdout.write(` ${m("User: ")}${e.user}
|
|
233
230
|
`),process.stdout.write(` ${m("Storage: ANTHROPIC_AUTH_TOKEN (settings.json)")}
|
|
234
|
-
`)):
|
|
231
|
+
`)):Ir(`Session rejected by ${e.baseUrl}. Run \`flow-ai-obs login\` to re-authenticate.`);let t={},r={};try{let c=E__namespace.readFileSync(oe(),"utf8");r=JSON.parse(c),t=r.env||{};}catch{}Cn("Observability configuration (OpenTelemetry)");let n=Object.keys(fe).filter(c=>!t[c]);Un("Metrics and Logs",n.length>0),n.length===0?(Wt("All OTEL env vars present in settings.json"),ze(`Endpoint: ${t.OTEL_EXPORTER_OTLP_ENDPOINT}`)):(process.stdout.write(`
|
|
235
232
|
`),process.stdout.write(` ${m("Run: flow-ai-obs init (restores missing vars automatically)")}
|
|
236
233
|
`),process.stdout.write(`
|
|
237
|
-
`),
|
|
238
|
-
`);}let s=
|
|
239
|
-
`),process.stdout.write(` ${m("Run `flow-ai-obs init` to configure.")}
|
|
240
|
-
`),process.stdout.write(`
|
|
241
|
-
`),Bt("Hooks NOT registered."));for(let u of o){let E=Ae[u];process.stdout.write(m(` ${u.padEnd(18)}`)+`\u2192 flow-ai-obs ${u} (timeout: ${E}s)
|
|
242
|
-
`);}Cr();let a=process.env[d.FLOW_TELEMETRY]==="true",c=process.env[d.LANGFUSE_BASE_URL],p=process.env[d.LANGFUSE_PUBLIC_KEY],g=process.env[d.LANGFUSE_SECRET_KEY];if(a)if(c&&p&&g){let u=await le();for(let E of u)E.mode==="direct"&&(St("FLOW_TELEMETRY=true (direct mode enabled)"),St("Mode: direct"),Qe(`Endpoint: ${E.endpoint}`),Qe(`PK: ${Nn(p)}`),Qe(`SK: ${Nn(g)}`));}else Bt("FLOW_TELEMETRY=true but missing LANGFUSE vars:"),c||Kt("LANGFUSE_BASE_URL not set"),p||Kt("LANGFUSE_PUBLIC_KEY not set"),g||Kt("LANGFUSE_SECRET_KEY not set");else {let u=await le();if(u.length>0)for(let E of u)E.mode==="gateway"&&(St("Mode: gateway"),Qe(`Endpoint: ${E.endpoint}`));else u.authError?Bt("Gateway mode: token refresh failed. Run `flow-ai-obs login`."):Qe("No active tracing destination configured.");}return Cr(),0}var Mn=T(()=>{"use strict";H();me();v();pe();Rr();});var Hn={};se(Hn,{runUpdateApiKey:()=>jo});async function jo(e={}){let t=e.key!==void 0?ie(e.key):K();if(!t)return e.key!==void 0?process.stderr.write(I(` \u2717 Provided API key is invalid.
|
|
234
|
+
`),vr(`${n.length} OTEL var(s) missing from settings.json`),n.forEach(c=>Bt(`Missing: ${c}`))),Nn();for(let c of Object.keys(fe)){let u=t[c]??k("(missing)");process.stdout.write(m(` ${c.padEnd(36)}`)+u+`
|
|
235
|
+
`);}Un("Trace Destination");let s=process.env[p.FLOW_TELEMETRY]==="true",o=process.env[p.LANGFUSE_BASE_URL],i=process.env[p.LANGFUSE_PUBLIC_KEY],a=process.env[p.LANGFUSE_SECRET_KEY];if(s)if(o&&i&&a){let c=await le();for(let u of c)u.mode==="direct"&&(Wt("FLOW_TELEMETRY=true (direct mode enabled)"),Wt("Mode: direct"),ze(`Endpoint: ${u.endpoint}`),ze(`PK: ${bn(i)}`),ze(`SK: ${bn(a)}`));}else vr("FLOW_TELEMETRY=true but missing LANGFUSE vars:"),o||Bt("LANGFUSE_BASE_URL not set"),i||Bt("LANGFUSE_PUBLIC_KEY not set"),a||Bt("LANGFUSE_SECRET_KEY not set");else {let c=await le();if(c.length>0)for(let u of c)u.mode==="gateway"&&(Wt("Mode: gateway"),ze(`Endpoint: ${u.endpoint}`));else c.authError?vr("Gateway mode: token refresh failed. Run `flow-ai-obs login`."):ze("No active tracing destination configured.");}return Nn(),0}var Dn=_(()=>{"use strict";W();me();P();pe();Or();});var xn={};se(xn,{runUpdateApiKey:()=>Yo});async function Yo(e={}){let t=e.key!==void 0?ie(e.key):K();if(!t)return e.key!==void 0?process.stderr.write(k(` \u2717 Provided API key is invalid.
|
|
243
236
|
`)+m(` Ensure the key contains valid characters and does not exceed 1024 characters.
|
|
244
237
|
|
|
245
|
-
`)):process.stderr.write(
|
|
238
|
+
`)):process.stderr.write(k(` \u2717 FLOW_API_KEY environment variable is not set or is invalid.
|
|
246
239
|
`)+m(` Set FLOW_API_KEY=<key> in your environment and re-run.
|
|
247
240
|
|
|
248
|
-
`)),1;let r=false,n=
|
|
249
|
-
`)):n.status==="already_configured"?process.stdout.write(
|
|
241
|
+
`)),1;let r=false,n=An(t);n.status==="configured"?process.stdout.write(R(` \u2713 GitHub Copilot API key updated successfully in ${n.settingsPath}
|
|
242
|
+
`)):n.status==="already_configured"?process.stdout.write(R(` \u2713 GitHub Copilot API key is already up to date in ${n.settingsPath}
|
|
250
243
|
`)):n.reason?.includes("not installed")?process.stdout.write(m(` \u2139 VS Code is not installed \u2014 skipping Copilot API key update.
|
|
251
|
-
`)):(process.stderr.write(
|
|
252
|
-
`)),r=true);let s=
|
|
253
|
-
`)):s.status==="already_configured"?process.stdout.write(
|
|
244
|
+
`)):(process.stderr.write(k(` \u2717 GitHub Copilot API key update failed: ${n.reason}
|
|
245
|
+
`)),r=true);let s=Tn(t);return s.status==="configured"?process.stdout.write(R(` \u2713 Claude Desktop API key updated successfully in ${s.wrapperScriptPath}
|
|
246
|
+
`)):s.status==="already_configured"?process.stdout.write(R(` \u2713 Claude Desktop API key is already up to date in ${s.wrapperScriptPath}
|
|
254
247
|
`)):s.reason?.includes("not installed")?process.stdout.write(m(` \u2139 Claude Desktop is not installed \u2014 skipping Desktop API key update.
|
|
255
|
-
`)):(process.stderr.write(
|
|
256
|
-
`)),r=true),r?1:0}var
|
|
248
|
+
`)):(process.stderr.write(k(` \u2717 Claude Desktop API key update failed: ${s.reason}
|
|
249
|
+
`)),r=true),r?1:0}var Mn=_(()=>{"use strict";W();Tr();hr();pe();});var Wn={};se(Wn,{runOtelHeaders:()=>jo});async function jo(){let e=K(),t=Pe(),r=Q(pt(p.ANTHROPIC_AUTH_TOKEN));if(e&&!t&&!r)return process.stderr.write(`[flow-ai-obs otel-headers] FLOW_API_KEY is set but x-flow-user could not be resolved.
|
|
257
250
|
Run: flow-ai-obs init --custom-email <EMAIL>
|
|
258
|
-
`),1;if(!e&&process.env[
|
|
251
|
+
`),1;if(!e&&process.env[p.FLOW_API_KEY]&&process.stderr.write(`[flow-ai-obs otel-headers] FLOW_API_KEY is set but its value was rejected (invalid characters or length). Falling back to OAuth.
|
|
259
252
|
`),e&&t){let i=c=>c.replace(/[\r\n]/g,""),a={"x-flow-api-key":i(e),"x-flow-user":i(t)};return process.stdout.write(JSON.stringify(a)+`
|
|
260
253
|
`),0}if(!r)return process.stderr.write(`[flow-ai-obs otel-headers] Not authenticated \u2014 run: flow-ai-obs login
|
|
261
|
-
`),1;let n=
|
|
262
|
-
`),1}finally{s===void 0?delete process.env[
|
|
254
|
+
`),1;let n=pt(p.FLOW_BASE_URL),s=process.env[p.FLOW_BASE_URL];n&&(process.env[p.FLOW_BASE_URL]=n);let o;try{o=(await X(r)).accessToken;}catch(i){return process.stderr.write(`[flow-ai-obs otel-headers] Token fetch failed: ${i.message}
|
|
255
|
+
`),1}finally{s===void 0?delete process.env[p.FLOW_BASE_URL]:process.env[p.FLOW_BASE_URL]=s;}return o?(process.stdout.write(JSON.stringify({Authorization:`Bearer ${o.replace(/[\r\n]/g,"")}`})+`
|
|
263
256
|
`),0):(process.stderr.write(`[flow-ai-obs otel-headers] Empty token received
|
|
264
|
-
`),1)}var
|
|
265
|
-
`)[0].slice(0,t).trim()}function
|
|
266
|
-
`);for(let r=t.length-1;r>=0;r--)try{let n=JSON.parse(t[r]);if(n.type==="user"&&n.uuid)return n.uuid}catch{}}catch{}return null}function
|
|
267
|
-
`),r=[],n=0,s=0,o;for(let i=t.length-1;i>=0;i--)try{let a=JSON.parse(t[i]);if(a.type==="user")break;if(a.type==="assistant"){!o&&a.message?.model&&(o=a.message.model);let
|
|
268
|
-
|
|
269
|
-
`),inputTokens:n,outputTokens:s,model:o}}catch{}return null}var
|
|
270
|
-
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function
|
|
271
|
-
`);return}let n=!!(await le()).authError,s=e.session_id||"unknown",o=e.prompt||"",i=e.cwd||"",a=
|
|
272
|
-
`,{flag:"a",encoding:"utf8",mode:384}),l("sendTraces:dump",`request appendada em ${
|
|
273
|
-
${
|
|
274
|
-
${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${
|
|
275
|
-
`))
|
|
276
|
-
`),process.stdin.on("data",t=>process.stdout.write(t));}}var
|
|
277
|
-
`),process.exit(0);});});var
|
|
257
|
+
`),1)}var Bn=_(()=>{"use strict";Oe();W();me();P();});function ae(e,t){let r=typeof e=="object"?JSON.stringify(e):String(e??"");return r.length>t?r.slice(0,t)+" \u2026[truncated]":r}function Ht(e,t=100){return String(e??"").split(`
|
|
258
|
+
`)[0].slice(0,t).trim()}function Tt(){return new Promise(e=>{let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",r=>{t+=r;}),process.stdin.on("end",()=>{try{e(JSON.parse(t));}catch{e({});}});})}function B(e){process.stdout.write(JSON.stringify(e));}var Ze=_(()=>{"use strict";});function he(){return String(BigInt(Date.now())*1000000n)}var br,be,yt=_(()=>{"use strict";br=()=>fn.randomBytes(16).toString("hex"),be=()=>fn.randomBytes(8).toString("hex");});function ri(e,t){let r=L.resolve(e);if(!r.startsWith(t))throw new Error(`Path traversal detected: ${e}`);return r}function Cr(e){if(!ei.test(e))throw new Error(`Invalid session ID: ${e}`);return ri(L.join(Le.tmpdir(),`flow-obs-${e}.json`),ti)}function Qe(e){let t;try{t=Cr(e);}catch{return null}if(!E.existsSync(t))return null;try{return JSON.parse(E.readFileSync(t,"utf8"))}catch{return null}}function et(e,t){E.writeFileSync(Cr(e),JSON.stringify(t),{encoding:"utf8",mode:384});}function Ur(e){try{E.unlinkSync(Cr(e));}catch{}}var ei,ti,St=_(()=>{"use strict";ei=/^[0-9a-f-]{1,64}$/i,ti=L.normalize(Le.tmpdir())+L.sep;});function Vn(e){if(!e||!E.existsSync(e))return null;try{let t=E.readFileSync(e,"utf8").trimEnd().split(`
|
|
259
|
+
`);for(let r=t.length-1;r>=0;r--)try{let n=JSON.parse(t[r]);if(n.type==="user"&&n.uuid)return n.uuid}catch{}}catch{}return null}function Nr(e){if(!e||!E.existsSync(e))return null;try{let t=E.readFileSync(e,"utf8").trimEnd().split(`
|
|
260
|
+
`),r=[],n=0,s=0,o;for(let i=t.length-1;i>=0;i--)try{let a=JSON.parse(t[i]);if(a.type==="user")break;if(a.type==="assistant"){!o&&a.message?.model&&(o=a.message.model);let u=(a.message?.content??[]).filter(d=>d.type==="text").map(d=>d.text??"").join("");u&&r.unshift(u);let h=a.message?.usage??{};n+=(h.input_tokens??0)+(h.cache_read_input_tokens??0)+(h.cache_creation_input_tokens??0),s+=h.output_tokens??0;}}catch{}return !r.length&&n===0?null:{text:r.join(`
|
|
261
|
+
|
|
262
|
+
`),inputTokens:n,outputTokens:s,model:o}}catch{}return null}var $r=_(()=>{"use strict";});function Xn(e){return e.replace(":","/")}function Kt(e,t){if(!e)return null;let r=Xn(e),n=[L.join(Le.homedir(),".claude","skills",r,"SKILL.md"),L.join(t??"",".claude","skills",r,"SKILL.md")];for(let s of n)if(E.existsSync(s))try{return E.readFileSync(s,"utf8")}catch{}return null}function qn(e){return e.split(`
|
|
263
|
+
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function zn(e){return !!e.slashSkill||e.toolCalls.some(n=>n.tool==="Skill")?e.toolCalls.some(n=>n.tool==="Skill"&&!n.synthetic||li.has(n.tool))?"complete":"prerequisite_required":null}function Yt(e,t){if(!e)return null;let r=Xn(e),n=[L.join(Le.homedir(),".claude","skills",r),L.join(t??"",".claude","skills",r)],s=null;for(let a of n)if(E.existsSync(L.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(ii.has(u.name)||ci.has(u.name)||ai.has(L.extname(u.name)))continue;let h=c?`${c}/${u.name}`:u.name;u.isDirectory()?i(L.join(a,u.name),h):o.push(h);}}return i(s,""),o.length>0?o:null}var ii,ai,ci,li,jt=_(()=>{"use strict";ii=new Set([".venv","__pycache__",".git","node_modules"]),ai=new Set([".pyc",".pyo"]),ci=new Set(["SKILL.md",".DS_Store",".gitignore"]);li=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);});function di(e){try{let t=e.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(t,"base64").toString())}catch{return null}}function fi(e,t,r,n){return new Promise(s=>{let o=new URL(e),i=o.protocol==="https:",a=(i?Ds__default.default:eo__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(t),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(t),a.end();})}async function Ce(e,t={}){try{let r=Q(process.env[p.ANTHROPIC_AUTH_TOKEN]);if(!r)return;let n,s=new Promise((d,y)=>{n=setTimeout(()=>y(new Error("getToken timeout")),4e3),n.unref();}),{accessToken:o}=await Promise.race([X(r),s]);clearTimeout(n);let i=di(o);if(!i)return;let a=i.tenant||r.tenant,c=JSON.stringify({action:e,booster:Rt().BOOSTER,metadata:t,success:!0,tenant:a,timestamp:new Date().toISOString(),os:process.platform,user:{email:i.email||"",id:i.sub||"",name:i.name||i.email||""}}),u=ke(Rt().API_URL),h=await fi(u,c,o,a);l("metrics.logEvent",`action=${e} status=${h}`);}catch(r){l("metrics.logEvent",`silenced error: ${r.message}`);}}var Vt=_(()=>{"use strict";P();Oe();W();D();});async function Fr(e,t=false){if(t){process.stdout.write(JSON.stringify({decision:"block",reason:mi})+`
|
|
264
|
+
`);return}let n=!!(await le()).authError,s=e.session_id||"unknown",o=e.prompt||"",i=e.cwd||"",a=Vn(e.transcript_path)||br(),c=qn(o),u=c?Kt(c,i):null,h=c?Yt(c,i):null;et(s,{traceId:br(),spanId:be(),startNs:he(),sessionId:s,prompt:o,cwd:i,traceName:a,transcriptPath:e.transcript_path||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:c,skillContent:u,skillArtifacts:h}),Ce("SESSION_STARTED",{traceType:c?"skill":"prompt",slashSkill:c,clientIdExpired:n}),l("UserPromptSubmit",`sid=${s}`,`traceName=${a}`,`slashSkill=${c}`),B(e);}var mi,Zn=_(()=>{"use strict";yt();St();$r();jt();Ze();D();P();W();Vt();mi=`\u26D4 Could not verify your Flow API key. This may be a temporary instability in the Flow services, or your API key may have expired. Please try again in a few minutes. If the issue persists, check your credentials at ${we()}/settings/api-keys and run: flow-ai-obs login. If it still persists, contact Flow support through the official channels.`;});async function Qn(e){let t=e.session_id||"unknown",r=e.tool_name||"unknown",n=e.tool_input||{},s=Qe(t);s&&(s.pendingTool={name:r,inputStr:ae(n,Z.TOOL_INPUT),startNs:he()},et(t,s)),l("PreToolUse",`sid=${t}`,`tool=${r}`,`stateFound=${!!s}`),B(e);}var es=_(()=>{"use strict";yt();St();Ze();D();P();});function g(e,t){return t==null||t===""?null:{key:e,value:{stringValue:String(t)}}}function Ue(...e){return e.filter(t=>t!==null)}function ts(e,t){return {resourceSpans:[{resource:{attributes:e},scopeSpans:[{scope:gi,spans:Array.isArray(t)?t:[t]}]}]}}var gi,A,rs=_(()=>{"use strict";P();gi={name:Ot.SCOPE_NAME,version:Ot.SCOPE_VERSION},A={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 ss(e,t,r,n,s){if(process.env[p.FLOW_OBS_DEBUG]!=="1")return;let o=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:e,headers:t,body:JSON.parse(r)},response:{status:n,body:s}});try{E.writeFileSync(ns,o+`
|
|
265
|
+
`,{flag:"a",encoding:"utf8",mode:384}),l("sendTraces:dump",`request appendada em ${ns}`);}catch(i){l("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Si(e){let t=new URL(e),r=new URL(G().GATEWAY_HEALTH);return r.hostname=t.hostname,r.port=t.port,r.protocol=t.protocol,r}function os(e,t){return new Promise((r,n)=>{let s=e._isSSL?Ds__default.default:eo__default.default;e.headers=Object.assign({},e.headers,{Connection:"close"});let o=s.request(e,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}`))),t&&o.write(t),o.end();})}async function is(e,t){let r;try{r=Si(e);}catch{return false}let n=r.protocol==="https:";try{let s={};t&&(s.Authorization=String(t).replace(/[\r\n]/g,""));let o=await os({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 Gt(e,t,r){let n=JSON.stringify(e),s=new URL(t),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 ${t}`),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 os({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}`),ss(t,a,n,c.statusCode,c.body),c.statusCode}catch(c){return l("sendTraces:error",c.message),ss(t,a,n,0,c.message),0}}var ns,as=_(()=>{"use strict";P();D();ns=L.join(Le.tmpdir(),"flow-obs-requests.ndjson");});function wi(){let e=parseInt(process.env[p.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(e)?Math.max(J.MIN_TTL_DAYS,Math.min(J.MAX_TTL_DAYS,e)):J.DEFAULT_TTL_DAYS)*24*60*60*1e3}function Ai(){let e=parseInt(process.env[p.BUFFER_MAX_FILES]??"",10);return Number.isFinite(e)?Math.max(J.MIN_MAX_FILES,Math.min(J.MAX_MAX_FILES,e)):J.DEFAULT_MAX_FILES}function ls(e){if(/[/\\]/.test(e))throw new Error(`Invalid buffer fileId: ${e}`);return L__namespace.default.join(Le__namespace.default.tmpdir(),`${J.FILE_PREFIX}${e}.json`)}function xr(){let e=Le__namespace.default.tmpdir(),t;try{t=E__namespace.default.readdirSync(e);}catch{return []}return t.filter(r=>r.startsWith(J.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=L__namespace.default.join(e,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 wt(e){try{let t=Ai(),r=xr();if(r.length>=t){let o=r.slice(0,r.length-t+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:e};return E__namespace.default.writeFileSync(ls(n),JSON.stringify(s),{encoding:"utf8",mode:384}),l("buffer",`saved fileId=${n}`),n}catch(t){return l("buffer",`saveToBuffer failed: ${t.message}`),null}}function us(e){let t=xr(),r=e!=null&&e>0?e:t.length,n=[];for(let s of t){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 ps(e){try{E__namespace.default.unlinkSync(ls(e)),l("buffer",`deleted fileId=${e}`);}catch{}}function ds(){let e=Date.now()-wi();for(let t of xr())try{let{mtimeMs:r}=E__namespace.default.statSync(t);r<e&&(E__namespace.default.unlinkSync(t),l("buffer",`evicted stale: ${L__namespace.default.basename(t)}`));}catch{}}var fs=_(()=>{"use strict";P();D();});async function Oi(e){ds();let t=us(J.REPLAY_BATCH_SIZE);t.length&&(l("replayBufferedTraces",`replaying ${t.length} buffered trace(s)`),await Promise.allSettled(t.map(async r=>{try{let n=await Gt(r.payload,e.endpoint,e.authHeader);n>=200&&n<300?(ps(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 ms(e){let t=await le();if(!t.length)return t.authError&&(l("postToLangfuse","auth refresh failed \u2014 buffering trace"),wt(e)),0;let r=await Promise.all(t.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await is(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 Oi(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"),wt(e),0;let c=await Gt(e,o.endpoint,o.authHeader);return (c===0||c>=500)&&(l("postToLangfuse",`gateway send failed (status ${c}) \u2014 buffering trace`),wt(e)),c}let a=await Gt(e,o.endpoint,o.authHeader);return (a===0||a>=500)&&(l("postToLangfuse",`direct endpoint unavailable (status ${a}) \u2014 buffering trace`),wt(e)),a}))).find(o=>o!==0)??0}var gs=_(()=>{"use strict";W();D();as();fs();P();});var Mr=_(()=>{"use strict";rs();gs();});function Te(e){if(e==null)return "";let t=typeof e=="string"?e:JSON.stringify(e);return Pi.reduce((r,{re:n,replace:s})=>r.replace(n,s),t)}var z,Li,Ri,ki,Es,Pi,Wr=_(()=>{"use strict";z="[REDACTED]",Li="[REDACTED-EMAIL]",Ri="[REDACTED-CPF]",ki="[REDACTED-CNPJ]",Es="[REDACTED-PHONE]",Pi=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${z}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${z}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(e,t)=>`${t}${z}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(e,t)=>`${t}${z}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(e,t,r)=>`${t}
|
|
266
|
+
${z}
|
|
267
|
+
${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${z}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(e,t)=>`${t}${z}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${z}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${z}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${z}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(e,t,r)=>`${t}${r}${z}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(e,t)=>`${t}:${z}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>Li},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>Ri},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>ki},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>Es},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>Es}];});async function hs(e){let t=e.session_id||"unknown",r=e.tool_name||"unknown",n=e.tool_input||{},s=e.tool_response,o=s!==null&&typeof s=="object"?s.output??JSON.stringify(s):s??"",i=Qe(t);if(!i){B(e);return}let a=he(),c=i.pendingTool,u=c?.name===r,h=u?c.startNs:String(BigInt(a)-200000000n),d=u?c.inputStr:ae(n,Z.TOOL_INPUT),y=d,S=null;if(r==="Skill"){let ye=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||n.commandName||String(Object.values(n)[0]??""):String(n);S=ye?String(ye).trim():null;let ue=S?Kt(S,i.cwd):null;ue&&(y=ue,i.skillContent||(i.skillContent=ue),i.skillArtifacts||(i.skillArtifacts=Yt(S,i.cwd))),S&&!i.slashSkill&&(i.slashSkill=S),l("PostToolUse","Skill tool detected",`skillName=${S}`,`contentFound=${!!ue}`);}let $=Te(ae(o,Z.TOOL_OUTPUT)),b=/\b(error|exception|failed|failure|traceback|errno)\b/i.test($.slice(0,500)),$e=b?"ERROR":"DEFAULT",f=be(),F=Math.round(Number(BigInt(a)-BigInt(h))/1e6),ce={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL",j=r==="Skill"&&S?S:Ht(d,60);i.toolCalls.push({tool:r,brief:j,error:b,durationMs:F});let ne=i.spans;ne.push({traceId:i.traceId,spanId:f,parentSpanId:i.spanId,name:r,kind:3,startTimeUnixNano:h,endTimeUnixNano:a,attributes:Ue(g(A.OBS_NAME,r),g(A.OBS_TYPE,ce),g(A.OBS_LEVEL,$e),g(A.OBS_INPUT,Te(y)),g(A.OBS_OUTPUT,$),g("tool.name",r),g("tool.error",String(b)),r==="Skill"&&S?g("skill.name",S):null,r==="Skill"?g("skill.invocation","slash-command"):null),status:{code:b?2:1}}),i.pendingTool=null,et(t,i),b&&Ce("TOOL_ERROR",{toolName:r}),l("PostToolUse",`sid=${t}`,`tool=${r}`,`error=${b}`,`durationMs=${F}`,`totalSpans=${ne.length}`),B(e);}var _s=_(()=>{"use strict";yt();St();Mr();Ze();jt();D();P();Wr();Vt();});function ys(e,t,r){let n=Object.keys(Ts).find(i=>(e??"").toLowerCase().includes(i));if(!n)return;let s=Ts[n],o=(t*s.input+r*s.output)/1e6;return Math.round(o*1e6)/1e6}var Ts,Ss=_(()=>{"use strict";Ts={"claude-opus-5":{input:5,output:25},"claude-sonnet-5":{input:2,output:10},"claude-fable-5":{input:10,output:50},"claude-opus-4-6":{input:5,output:25},"claude-opus-4-5":{input:5,output:25},"claude-sonnet-4-6":{input:3,output:15},"claude-sonnet-4-5":{input:3,output:15},"claude-haiku-4-5":{input:1,output:5},"claude-4-6-opus":{input:5,output:25},"claude-4-6-sonnet":{input:3,output:15},"claude-4-5-opus":{input:5,output:25},"claude-4-5-sonnet":{input:3,output:15},"claude-4-5-haiku":{input:1,output:5},"claude-3-5-sonnet-20241022":{input:3,output:15},"claude-3-5-haiku-20241022":{input:.8,output:4},"claude-3-opus-20240229":{input:15,output:75}};});async function ws(e){let t=e.session_id||"unknown",r=e.stop_reason||"end_turn",n=Qe(t);if(!n){B(e);return}n.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(n.slashSkill)&&(l("Stop",`sid=${t}`,`slashSkill rejected post-disk: "${n.slashSkill}"`),n.slashSkill=null);let s=he(),o=await dn(),i=n.toolCalls,a=n.spans;if(n.slashSkill&&!i.some(w=>w.tool==="Skill")){let w=be(),Se=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:w,parentSpanId:n.spanId,name:"Skill",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:n.startNs,attributes:Ue(g(A.OBS_NAME,"Skill"),g(A.OBS_TYPE,"TOOL"),g(A.OBS_LEVEL,"DEFAULT"),g(A.OBS_INPUT,Se),g(A.OBS_OUTPUT,"loaded via slash command"),g("tool.name","Skill"),g("tool.error","false"),g("skill.name",n.slashSkill),g("skill.invocation","slash-command")),status:{code:1}}),l("Stop",`slashSkill=${n.slashSkill}`,"synthetic span injected");}let c=e.transcript_path||n.transcriptPath||"",u=Nr(c);if(c&&(i.some(w=>w.tool==="Skill"&&!w.synthetic)||!!n.slashSkill)&&!u?.text){await new Promise(Se=>setTimeout(Se,500));let w=Nr(c);w?.text&&(u=w);}l("Stop",`transcriptPath=${c||"(empty)"}`,`assistantOut=${u?`text=${u.text.length}chars`:"null"}`);let d=i.length,y=i.filter(w=>w.error).length,S=Te(u?.text?ae(u.text,Z.TRACE_OUTPUT):d===0?"No tools used":i.map((w,Se)=>`${Se+1}. ${w.tool}${w.brief?` \u2192 ${w.brief}`:""}${w.error?" [ERROR]":""}`).join(`
|
|
268
|
+
`)),$=u?.inputTokens??0,b=u?.outputTokens??0,$e=i.map((w,Se)=>`${Se+1}. ${w.tool}${w.brief?` \u2192 ${w.brief}`:""}${w.error?" [ERROR]":""} (${w.durationMs}ms)`),f=!!(n.slashSkill||i.some(w=>w.tool==="Skill")),F=i.some(w=>w.tool==="Agent");if(!f&&!F){l("Stop",`sid=${t}`,"skipping trace \u2014 no Skill or Agent calls found"),Ce("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),Ur(t),B(e);return}let re=f?"skill":"agent",ce=Math.round(Number(BigInt(s)-BigInt(n.startNs))/1e6),j=u?.model||"",rt=ys(j,$,b),ne=zn(n);ne==="prerequisite_required"&&u?.text&&(ne="complete"),ne==="prerequisite_required"&&(a.push({traceId:n.traceId,spanId:be(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:Ue(g(A.OBS_NAME,"prerequisite-check"),g(A.OBS_TYPE,"EVENT"),g(A.OBS_LEVEL,"WARNING"),g(A.OBS_OUTPUT,S),g("skill.name",n.slashSkill||void 0),g("execution_status","prerequisite_required")),status:{code:1}}),l("Stop",`sid=${t}`,"prerequisite-check span injected",`skill=${n.slashSkill}`));let ye=(()=>{if(!(!f||!n.prompt)){if(n.slashSkill){let w=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return w?ae(Te(w),Z.USER_INSTRUCTION):void 0}return ae(Te(n.prompt),Z.USER_INSTRUCTION)||void 0}})(),ue=JSON.stringify({trace_type:re,...ne!==null&&{execution_status:ne},...n.slashSkill?{skill_name:n.slashSkill}:{},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...ye!==void 0&&{user_instruction:ye},latency_ms:ce,...$&&{tokens_input:$},...b&&{tokens_output:b},cost_usd:rt,...j?{model:j}:{},toolCount:d,errorCount:y,stopReason:r,sessionId:n.sessionId,tools:$e.length?$e:void 0}),At=Te(ae(n.prompt,Z.TRACE_INPUT)),Fe=Ue(g(A.TRACE_NAME,n.traceName),g(A.TRACE_INPUT,At),g(A.TRACE_OUTPUT,S),g(A.OBS_INPUT,At),g(A.OBS_OUTPUT,S),g(A.TRACE_METADATA,ue),g(A.SESSION_ID,n.sessionId),g(A.USER_ID,o.user),g(A.OBS_TYPE,"GENERATION"),g(A.MODEL,j),$?g(A.INPUT_TOKENS,$):null,b?g(A.OUTPUT_TOKENS,b):null,g("claude.stop_reason",r),g("claude.tool_count",String(d)),g("claude.error_count",String(y)),g("claude.session_id",n.sessionId),g("flow.trace_type",re),{key:A.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:re}]}}}),Jt={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:Fe,status:{code:y>0?2:1}},ks=Ue(g("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),g("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),Br=[...a,Jt];l("Stop",`sid=${t}`,`totalTools=${d}`,`errorTools=${y}`,`spans=${Br.length}`,`inputTokens=${$}`,`outputTokens=${b}`,`traceOutput="${Ht(S,80)}"`);let Ps=await ms(ts(ks,Br));l("Stop",`POST status=${Ps}`,`traceId=${n.traceId}`),Ce("TRACE_SENT",{latencyMs:ce,totalTools:d,errorTools:y,inputTokens:$,outputTokens:b,costUsd:rt}),Ur(t),B(e);}var As=_(()=>{"use strict";yt();St();Mr();W();Ss();$r();Ze();D();jt();Wr();P();Vt();});var Ne,Os=_(()=>{"use strict";W();Ze();Zn();es();_s();As();Ne=class{static async userPromptSubmit(){let t=await Tt(),r;try{r=await le();}catch{B(t);return}r.authError?await Fr(t,!0):r.length>0?await Fr(t):B(t);}static async preToolUse(){let t=await Tt();await Qn(t);}static async postToolUse(){let t=await Tt();await hs(t);}static async stop(){let t=await Tt();await ws(t);}};});var vi={};async function Ii(){let e=process.argv[2];switch(e){case "UserPromptSubmit":await Ne.userPromptSubmit();break;case "PreToolUse":await Ne.preToolUse();break;case "PostToolUse":await Ne.postToolUse();break;case "Stop":await Ne.stop();break;default:process.stderr.write(`[flow-obs] unknown event: ${e}
|
|
269
|
+
`),process.stdin.on("data",t=>process.stdout.write(t));}}var Ls=_(()=>{"use strict";Os();Ii().catch(e=>{process.stderr.write(`[flow-obs] fatal: ${e.message}
|
|
270
|
+
`),process.exit(0);});});var bi=new Set(["UserPromptSubmit","PreToolUse","PostToolUse","Stop"]),[,,Y]=process.argv;function te(e,t){let r=e.indexOf(t);return r!==-1?e[r+1]:void 0}function Rs(){let{bold:e,cyan:t,dim:r,green:n}=(pe(),x(qt)),{version:s}=nt();process.stdout.write(`
|
|
278
271
|
`+e(" flow-ai-obs")+r(" v"+s)+`
|
|
279
272
|
|
|
280
273
|
`),process.stdout.write(t(" init")+r(` Configure environment: Claude Code + Proxy + OTEL + Trace hooks
|
|
@@ -292,18 +285,18 @@ ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${q}`},{re:/(aws_secret_ac
|
|
|
292
285
|
|
|
293
286
|
`)),process.stdout.write(r(` (Hook events: UserPromptSubmit | PreToolUse | PostToolUse | Stop)
|
|
294
287
|
|
|
295
|
-
`));}if(Y==="--version"||Y==="-v")(async()=>{let{version:e}=
|
|
296
|
-
`);let t=(
|
|
288
|
+
`));}if(Y==="--version"||Y==="-v")(async()=>{let{version:e}=nt();process.stdout.write(e+`
|
|
289
|
+
`);let t=(We(),x(Me)),r=await t.fetchLatestVersionAsync().catch(()=>null);if(r&&t.isNewer(e,r.version)){let{dim:n,yellow:s}=(pe(),x(qt));process.stdout.write(s(`
|
|
297
290
|
Update available: ${e} \u2192 ${r.version}
|
|
298
291
|
`)+n(` Run: flow-ai-obs update
|
|
299
292
|
|
|
300
|
-
`));}process.exit(0);})().catch(()=>process.exit(0));else if(Y==="--help"||Y==="-h")
|
|
301
|
-
`),await(
|
|
302
|
-
`),process.exit(1);});else if(Y==="login")(async()=>{await(
|
|
303
|
-
`),process.exit(1);});else if(Y==="status")(async()=>{await(
|
|
304
|
-
`),process.exit(1);});else if(Y==="update-api-key")(async()=>{let{runUpdateApiKey:e}=(
|
|
305
|
-
`),process.exit(1);});else if(Y==="update")(async()=>{let e=(
|
|
293
|
+
`));}process.exit(0);})().catch(()=>process.exit(0));else if(Y==="--help"||Y==="-h")Rs(),process.exit(0);else if(Y==="init"||Y==="install")(async()=>{Y==="install"&&process.stderr.write(`Warning: "install" is deprecated, use "init" instead
|
|
294
|
+
`),await(We(),x(Me)).checkForUpdateInteractive();let{runInit:e}=(vn(),x(In)),t=process.argv.slice(3);process.exit(await e({url:te(t,"--custom-url"),noInteractive:t.includes("--no-interactive"),email:te(t,"--custom-email"),token:te(t,"--token"),clientId:te(t,"--client-id"),clientSecret:te(t,"--client-secret"),tenant:te(t,"--tenant")}));})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
295
|
+
`),process.exit(1);});else if(Y==="login")(async()=>{await(We(),x(Me)).checkForUpdateInteractive();let{runLogin:e}=(ht(),x(Et)),t=process.argv.slice(3),r=await e({token:te(t,"--token"),clientId:te(t,"--client-id"),clientSecret:te(t,"--client-secret"),tenant:te(t,"--tenant")});process.exit(typeof r=="number"?r:r.code);})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
296
|
+
`),process.exit(1);});else if(Y==="status")(async()=>{await(We(),x(Me)).checkForUpdateInteractive();let{runStatus:e}=(Dn(),x(Fn));process.exit(await e());})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
297
|
+
`),process.exit(1);});else if(Y==="update-api-key")(async()=>{let{runUpdateApiKey:e}=(Mn(),x(xn)),t=process.argv.slice(3);process.exit(await e({key:te(t,"--key")}));})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
298
|
+
`),process.exit(1);});else if(Y==="update")(async()=>{let e=(We(),x(Me)),{version:t}=nt(),r=await e.fetchLatestVersionAsync();r||(process.stderr.write(` \u2717 Could not reach npm registry \u2014 check your connection.
|
|
306
299
|
`),process.exit(1)),e.isNewer(t,r.version)||(process.stdout.write(` \u2713 Already up to date (v${t})
|
|
307
300
|
`),process.exit(0)),await e.runUpdate(r.version),process.exit(0);})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
308
|
-
`),process.exit(1);});else if(Y==="otel-headers"){let{runOtelHeaders:e}=(
|
|
309
|
-
`),process.exit(1);});}else
|
|
301
|
+
`),process.exit(1);});else if(Y==="otel-headers"){let{runOtelHeaders:e}=(Bn(),x(Wn));e().then(t=>process.exit(t)).catch(t=>{process.stderr.write(`[flow-ai-obs otel-headers] Unexpected error: ${t.message}
|
|
302
|
+
`),process.exit(1);});}else bi.has(Y)?(Ls(),x(vi)):(Rs(),process.exit(0));
|