@ciandt-flow/flow-ai-obs 0.14.0-beta.70 → 0.14.0-beta.72
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 +60 -60
- package/dist/index.js +7 -7
- package/dist/setup.js +3 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var zt=require('readline/promises'),
|
|
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 Be={};re(Be,{checkForUpdate:()=>Ms,checkForUpdateInteractive:()=>Hs,fetchLatestVersionAsync:()=>
|
|
2
|
+
'use strict';var zt=require('readline/promises'),Cs=require('https'),S=require('fs'),Le=require('os'),k=require('path'),child_process=require('child_process'),qs=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 Cs__default=/*#__PURE__*/_interopDefault(Cs);var S__namespace=/*#__PURE__*/_interopNamespace(S);var Le__namespace=/*#__PURE__*/_interopNamespace(Le);var k__namespace=/*#__PURE__*/_interopNamespace(k);var qs__default=/*#__PURE__*/_interopDefault(qs);var fn__namespace=/*#__PURE__*/_interopNamespace(fn);var Xt=Object.defineProperty;var Rs=Object.getOwnPropertyDescriptor;var Ls=Object.getOwnPropertyNames;var ks=Object.prototype.hasOwnProperty;var Ps=(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 Is=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(r){throw t=0,r}},re=(e,t)=>{for(var r in t)Xt(e,r,{get:t[r],enumerable:true});},vs=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Ls(t))!ks.call(e,s)&&s!==r&&Xt(e,s,{get:()=>t[s],enumerable:!(n=Rs(t,s))||n.enumerable});return e};var M=e=>vs(Xt({},"__esModule",{value:true}),e);var qt={};re(qt,{bold:()=>b,cyan:()=>D,dim:()=>m,green:()=>I,red:()=>$,yellow:()=>v});function Me(e,t){return bs?r=>`\x1B[${e}m${r}\x1B[${t}m`:r=>r}var bs,I,$,v,D,b,m,le=_(()=>{"use strict";bs=!process.env.NO_COLOR&&process.stdout.isTTY;I=Me("32","39"),$=Me("31","39"),v=Me("33","39"),D=Me("36","39"),b=Me("1","22"),m=Me("2","22");});var st=Is((bi,Us)=>{Us.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.14.0-beta.72",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 ue(){return process.stdout.isTTY===true&&process.stdin.isTTY===true&&!process.argv.includes("--no-interactive")}async function ot(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 Be={};re(Be,{checkForUpdate:()=>Ms,checkForUpdateInteractive:()=>Hs,fetchLatestVersionAsync:()=>jr,isNewer:()=>He,primeUpdateCache:()=>Bs,runUpdate:()=>Kr});function G(){return er||(er=st()),er}function He(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(S__namespace.default.readFileSync(Yr,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=Fs?null:e}catch{return null}}function sr(e,t,r=Date.now()){try{S__namespace.default.writeFileSync(Yr,JSON.stringify({latestVersion:e,updatePriority:t??null,checkedAt:r}),{mode:384});}catch{}}function or(e){let t=G().name,r=Cs__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:Ds},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=G().name,n=` Update available: ${G().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
|
|
@@ -16,36 +16,36 @@
|
|
|
16
16
|
\u2502${a.padEnd(c)}\u2502
|
|
17
17
|
\u2570${p}\u256F
|
|
18
18
|
`),new Promise(g=>{let u=r.createInterface({input:process.stdin,output:void 0,terminal:false}),E=false;function y(O){E||(E=true,clearTimeout(w),u.close(),process.stderr.write(`
|
|
19
|
-
`),g(O));}let w=setTimeout(()=>y(false),t);u.once("line",O=>y(O.trim().toLowerCase()==="y")),u.once("close",()=>y(false));})}async function
|
|
19
|
+
`),g(O));}let w=setTimeout(()=>y(false),t);u.once("line",O=>y(O.trim().toLowerCase()==="y")),u.once("close",()=>y(false));})}async function Kr(e){let t=G().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
|
|
24
|
+
`);}r();}}n.on("close",(i,a)=>o(i===0,a??void 0)),n.on("error",i=>o(false,i.code));})}function jr(){return new Promise(e=>{or((t,r)=>e(t||!r?null:r));})}function Ms(){try{let e=nr();if(e){He(G().version,e.latestVersion)&&(e.updatePriority==="auto"?rr(e.latestVersion):tr(e.latestVersion));return}setImmediate(()=>{or((t,r)=>{t||!r||(sr(r.version,r.updatePriority),He(G().version,r.version)&&(r.updatePriority==="auto"?rr(r.version):tr(r.version)));});});}catch{}}async function Hs(e={}){try{let t=nr();if(t){if(!He(G().version,t.latestVersion))return}else {let n=await jr();if(!n||(sr(n.version,n.updatePriority),!He(G().version,n.version)))return;t={latestVersion:n.version,updatePriority:n.updatePriority,checkedAt:Date.now()};}if(t.updatePriority==="auto"){rr(t.latestVersion);return}if(!ue()){tr(t.latestVersion);return}await xs(t.latestVersion,e.timeoutMs)&&await Kr(t.latestVersion);}catch{}}function Bs(){try{if(nr())return;setImmediate(()=>{or((e,t)=>{e||!t||He(G().version,t.version)&&sr(t.version,t.updatePriority,0);});});}catch{}}var er,Yr,Fs,Ds,We=_(()=>{"use strict";Qt();Yr=k__namespace.default.join(Le__namespace.default.tmpdir(),"flow-obs-update-cache.json"),Fs=1440*60*1e3,Ds=3e3;});var Vr={};re(Vr,{AUTH_ENGINE:()=>Ye,BUFFER:()=>X,CLAUDE_DESKTOP:()=>C,CONFIG_DIR_NAME:()=>at,CONFIG_FILE_NAME:()=>ct,COPILOT_OTEL:()=>T,DEBUG_LOG_FILENAME:()=>ir,ENV:()=>d,FLOW_URLS:()=>Ys,HOOK_TIMEOUTS:()=>Oe,INSTALLER:()=>lt,NATIVE_OTEL:()=>pe,OTLP:()=>kt,STATE_FILE_PREFIX:()=>Ks,TRACE_LIMITS:()=>Q,VALIDATION:()=>Y,VAULT:()=>it,getFlowBaseUrl:()=>we,getFlowUrls:()=>J,getMetrics:()=>Pt});function we(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Ws}function J(){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 Pt(){let e=we();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ws,Ys,it,at,ct,kt,pe,d,Ye,lt,Oe,X,Y,ir,Q,C,T,Ks,P=_(()=>{"use strict";Ws="https://flow.ciandt.com";Ys=J(),it={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},at="FLOW-nodejs",ct="config.json",kt={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},pe={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"},d={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"},Ye={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 "},Oe={UserPromptSubmit:30,PreToolUse:3,PostToolUse:10,Stop:15},X={FILE_PREFIX:"flow-obs-buffer-",DEFAULT_TTL_DAYS:4,MIN_TTL_DAYS:1,MAX_TTL_DAYS:30,DEFAULT_MAX_FILES:50,MIN_MAX_FILES:1,MAX_MAX_FILES:500,REPLAY_BATCH_SIZE:10},Y={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[\x21-\x7E]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},ir="flow-ai-obs-debug.log",Q={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"},Ks="flow-obs-";});function l(...e){if(process.env[d.FLOW_OBS_DEBUG]!=="1")return;let t=`[${new Date().toISOString()}] ${e.join(" ")}
|
|
25
25
|
`;try{S.writeFileSync(Js,t,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
|
|
26
|
-
`);}}var Js,x=_(()=>{"use strict";P();Js=k.join(
|
|
27
|
-
|
|
26
|
+
`);}}var Js,x=_(()=>{"use strict";P();Js=k.join(Le.tmpdir(),ir);});function Zs(e){if(!zs.test(e))throw new Error(`Invalid tenant value: "${e}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}function Qs(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}`:"")),Gr[n.error]))return new Ae(Gr[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 q(e){return new Promise((t,r)=>{try{Zs(e.tenant);}catch(p){return r(p)}let n=JSON.stringify({clientSecret:e.clientSecret}),s=new URL(J().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?Cs__default.default:qs__default.default).request(i,p=>{let g=[];p.on("data",u=>g.push(u)),p.on("end",()=>{let u=g.join("");if((p.statusCode??0)>=400)return r(Qs(p.statusCode??0,u));let E;try{E=JSON.parse(u);}catch{return r(new Error("Invalid response from auth engine"))}let y=E.expires_at??new Date(Date.now()+(E.expires_in??3600)*1e3).toISOString();if(!E.access_token)return r(new Error("Auth engine returned an empty access token. Check FLOW_BASE_URL and credentials."));t({accessToken:E.access_token,expiresAt:y});});});c.on("error",p=>r(new Error(`Network error: ${p.message}`))),c.setTimeout(Ye.REQUEST_TIMEOUT_MS,()=>{c.destroy(new Error("Request timeout"));}),c.write(n),c.end();})}var Ae,zs,Gr,Re=_(()=>{"use strict";P();x();Ae=class extends Error{statusCode;constructor(t,r=0){super(t),this.name="AuthError",this.statusCode=r;}},zs=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;Gr={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 Jr(){return process.platform==="win32"?false:process.getuid?.()===0}function It(){if(Jr())return process.stderr.write(`
|
|
27
|
+
`+$(` \u2717 flow-ai-obs is not supported in a sudo context.
|
|
28
28
|
|
|
29
29
|
`)+D(` npm install -g @ciandt-flow/flow-ai-obs
|
|
30
30
|
`)+`
|
|
31
|
-
`),1}var vt=_(()=>{"use strict";le();});function ke(){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:
|
|
32
|
-
`,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(r,384);}catch{}}finally{en(n);}return {settingsPath:r,preserved:s}}function z(e){if(dt===void 0)try{let r=S__namespace.readFileSync(ne(),"utf8");dt=JSON.parse(r).env??null;}catch{dt=null;}if(!dt)return null;let t=dt[e];return typeof t=="string"?t:null}function
|
|
33
|
-
`,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(t,384);}catch{}}finally{en(r);}}function ft(e){let t=process.env[e];return t!==void 0?t!==""?t:void 0:z(e)??void 0}var eo,dt,de=_(()=>{"use strict";P();
|
|
31
|
+
`),1}var vt=_(()=>{"use strict";le();});function ke(){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 ne(){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 k__namespace.join(t,".claude","settings.json")}return k__namespace.join(Le__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||Le__namespace.homedir();return k__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 k__namespace.join(t,".claude","settings.json")}return k__namespace.join(Le__namespace.homedir(),".claude","settings.json")}var ut=_(()=>{"use strict";vt();});function bt(){if(process.platform==="win32"){let r=process.env.APPDATA||k__namespace.join(Le__namespace.homedir(),"AppData","Roaming");return k__namespace.join(r,Xr,qr)}let e=ke(),t=process.env.XDG_CONFIG_HOME||k__namespace.join(e.home,".config");return k__namespace.join(t,Xr,qr)}function cr(){try{let e=S__namespace.readFileSync(ne(),"utf8"),r=JSON.parse(e).env?.FLOW_BASE_URL;return typeof r=="string"&&r.trim()?r.trim():null}catch{return null}}var Xr,qr,lr=_(()=>{"use strict";ut();Xr="flow-ai-obs",qr="config.json";});function Qr(e){try{let t=S__namespace.statSync(e);Date.now()-t.mtimeMs>eo&&S__namespace.unlinkSync(e);}catch{}try{S__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 en(e){try{S__namespace.unlinkSync(e);}catch{}}function to(e,t){let n=(Array.isArray(e)?e:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(i=>!i.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [t,...n]}function tn(e,t){let r=ne(),n=r+".lock",s=[];S__namespace.mkdirSync(k__namespace.dirname(r),{recursive:true}),Qr(n);try{if(S__namespace.existsSync(r)){S__namespace.copyFileSync(r,r+".bkp");try{S__namespace.chmodSync(r+".bkp",384);}catch{}}let o=bt();if(S__namespace.existsSync(o)){let w=o+".bkp";S__namespace.copyFileSync(o,w);try{S__namespace.chmodSync(w,384);}catch{}}let i={};try{i=JSON.parse(S__namespace.readFileSync(r,"utf8"));}catch{}let a=i.env&&typeof i.env=="object"?i.env:{};delete a.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:c}=(P(),M(Vr)),p=c().OTEL_ENDPOINT,g={...pe,OTEL_EXPORTER_OTLP_ENDPOINT:e??p};i.env={...a,...g,...t??{}},i.otelHeadersHelper="flow-ai-obs otel-headers",(!i.hooks||typeof i.hooks!="object"||Array.isArray(i.hooks))&&(i.hooks={});let u=(w,O)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${w}`,timeout:O}]}),E=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],y=i.hooks;for(let w of E){let O=to(y[w],u(w,Oe[w]));O.length>1&&s.push(w),y[w]=O;}S__namespace.writeFileSync(r,JSON.stringify(i,null,2)+`
|
|
32
|
+
`,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(r,384);}catch{}}finally{en(n);}return {settingsPath:r,preserved:s}}function z(e){if(dt===void 0)try{let r=S__namespace.readFileSync(ne(),"utf8");dt=JSON.parse(r).env??null;}catch{dt=null;}if(!dt)return null;let t=dt[e];return typeof t=="string"?t:null}function je(e){let t=ne(),r=t+".lock";S__namespace.mkdirSync(k__namespace.dirname(t),{recursive:true}),Qr(r);try{let n={};try{n=JSON.parse(S__namespace.readFileSync(t,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,e),S__namespace.writeFileSync(t,JSON.stringify(n,null,2)+`
|
|
33
|
+
`,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(t,384);}catch{}}finally{en(r);}}function ft(e){let t=process.env[e];return t!==void 0?t!==""?t:void 0:z(e)??void 0}var eo,dt,de=_(()=>{"use strict";P();Re();ut();lr();eo=lt.LOCK_STALE_MS;});function mt(){let e=Le__namespace.default.homedir();if(process.platform==="darwin")return k__namespace.default.join(e,"Library","Preferences",at,ct);if(process.platform==="win32"){let r=process.env.APPDATA??k__namespace.default.join(e,"AppData","Roaming");return k__namespace.default.join(r,at,ct)}let t=process.env.XDG_CONFIG_HOME??k__namespace.default.join(e,".config");return k__namespace.default.join(t,at,ct)}function dr(){try{let e=S__namespace.default.readFileSync(mt(),"utf8");return JSON.parse(e)}catch{return {}}}function rn(e){let t=mt();S__namespace.default.mkdirSync(k__namespace.default.dirname(t),{recursive:true}),S__namespace.default.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var pr,Ut,nn=_(()=>{"use strict";P();pr={credentials:"credentials","token-cache":"tokenCache"};Ut=class{static isAvailable(){return !0}static hasExistingData(){try{if(!S__namespace.default.existsSync(mt()))return !1;let t=JSON.parse(S__namespace.default.readFileSync(mt(),"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;rn(s);}async deleteSecret(t,r){let n=dr(),s=pr[r]??r;return s in n?(delete n[s],rn(n),!0):!1}getStoragePath(){return `config.json (unencrypted) \u2014 ${mt()}`}};});async function sn(){return new Ut}var on=_(()=>{"use strict";nn();});var cn={};re(cn,{clearFlowCredentials:()=>so,getConfigPath:()=>io,getEmailFromToken:()=>Xe,getFlowCredentials:()=>an,getTokenCache:()=>Et,hasCredentials:()=>ao,isTokenValid:()=>oo,saveFlowCredentials:()=>no,saveTokenCache:()=>fe});function Je(){return fr||(fr=sn()),fr}async function an(){let t=await(await Je()).getSecret(Ge,mr);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function no(e){if(!e.clientId||!e.clientSecret||!e.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await Je()).setSecret(Ge,mr,JSON.stringify(e));}async function so(){let e=await Je();await e.deleteSecret(Ge,mr),await e.deleteSecret(Ge,gr);}async function fe(e){await(await Je()).setSecret(Ge,gr,JSON.stringify({accessToken:e.accessToken,expiresAt:e.expiresAt,lastAuthCheckAt:e.lastAuthCheckAt}));}async function Et(){let t=await(await Je()).getSecret(Ge,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 oo(){let e=await Et();return e?new Date(e.expiresAt)>new Date:false}async function Xe(){let e=await Et();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 io(){return (await Je()).getStoragePath?.()??"FLOW-nodejs/config.json"}async function ao(){let e=await an();return !!(e&&e.clientId&&e.clientSecret&&e.tenant)}var Ge,mr,gr,fr,qe=_(()=>{"use strict";on();P();Ge=it.SERVICE,mr=it.ACCOUNT_CREDS,gr=it.ACCOUNT_TOKEN,fr=null;});function ln(){return !!process.env[d.FLOW_USER_EMAIL]||!!z(d.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 Xe().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&&Y.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{
|
|
37
|
+
`;return Xe().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&&Y.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{je({[d.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 un=_(()=>{"use strict";qe();de();x();P();});function uo(e){return lo.some(t=>t.test(e))}function po(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 me(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 pn(e){let t=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),r=Buffer.from(JSON.stringify({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant})).toString("base64url");return `${t}.${r}.`}function Pe(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&&uo(t.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${t.hostname}`);return e}async function dn(){let e=me(process.env[d.ANTHROPIC_AUTH_TOKEN]);return e?{user:await Xe().catch(()=>null)??e.clientId,tenant:e.tenant}:{user:"",tenant:""}}function fo(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 Ie(){let e=ft(d.FLOW_USER_EMAIL);if(e!==void 0){let r=e.replace(/[\r\n]/g,"").trim();if(r)if(r.length>Y.EMAIL_MAX_LENGTH)l("resolveUserEmail",`FLOW_USER_EMAIL exceeds ${Y.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!Y.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=fo("x-flow-user");if(t){let r=t.replace(/[\r\n]/g,"").trim();if(r.length>Y.EMAIL_MAX_LENGTH)l("resolveUserEmail",`x-flow-user from OTEL_EXPORTER_OTLP_HEADERS exceeds ${Y.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!Y.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 se(){let e=process.env[d.FLOW_API_KEY];if(!e)return null;let t=e.replace(/[\r\n]/g,"").trim();return t?t.length>Y.API_KEY_MAX_LENGTH?(l("resolveApiKey",`FLOW_API_KEY exceeds ${Y.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):Y.API_KEY_PATTERN.test(t)?t:(l("resolveApiKey","FLOW_API_KEY contains non-printable or control characters \u2014 rejected"),null):null}function mo(){return new Date().toISOString().slice(0,10)}async function go(e){let t=mo(),r=await Et();if(r?.lastAuthCheckAt!==t){l("getOrRefreshToken",`daily auth check (last: ${r?.lastAuthCheckAt??"never"})`);let o=Ye.MAX_RETRY_ATTEMPTS;for(let i=1;i<=o;i++)try{let a=await q(e);try{await fe({...a,lastAuthCheckAt:t});}catch(p){l("getOrRefreshToken",`saveTokenCache failed (non-fatal): ${p.message}`);}return l("getOrRefreshToken",`daily check passed (attempt ${i}), expires=${a.expiresAt}`),se()?ln()||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,Ye.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 q(e);try{await fe({...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 Eo(e,t){let r=t&&t.accessToken?t.accessToken:"";return {endpoint:e.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function ho(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 ie(){let e=[],t=me(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 y={user:u??"",tenant:E??"",team:"",project:""};e.push({mode:"direct",...ho(Pe(s),o,i),...y}),l("resolveCredentials","direct mode active",`user=${y.user}`,`tenant=${y.tenant}`);}if(!t){if(e.length===0){let u=[];return u.authError=false,u}return e}let a;try{a=await go(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:po(a)??t.clientId,tenant:r,team:"",project:""},g=process.env[d.FLOW_TELEMETRY_GATEWAY]??we();return e.push({mode:"gateway",...Eo(Pe(g),{accessToken:a}),...p}),e}var lo,j=_(()=>{"use strict";qe();Le();P();x();un();de();lo=[/^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 To(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=k__namespace.join(s,F.DIR_3P);return Nt(o)}}if(process.platform==="win32"){let n=process.env.LOCALAPPDATA||k__namespace.join(Re__namespace.homedir(),"AppData","Local"),s=k__namespace.join(n,F.DIR_3P);return Nt(s)}if(process.platform==="darwin"){let n=k__namespace.join(Re__namespace.homedir(),"Library","Application Support",F.DIR_3P);return Nt(n)}let e=ke(),t=process.env.XDG_CONFIG_HOME||k__namespace.join(e.home,".config"),r=k__namespace.join(t,F.DIR_3P);return Nt(r)}function Nt(e){return {configDir:e,configLibraryDir:k__namespace.join(e,F.CONFIG_LIBRARY_DIR),desktopConfigPath:k__namespace.join(e,F.DESKTOP_CONFIG_FILE),metaPath:k__namespace.join(e,F.CONFIG_LIBRARY_DIR,F.META_FILE)}}function So(){let e=ne(),t=k__namespace.dirname(e),r=Ct()?F.WRAPPER_SCRIPT_WIN:F.WRAPPER_SCRIPT_UNIX;return k__namespace.join(t,r)}function hr(){if(process.env[d.FLOW_OBS_SKIP_DESKTOP_DETECTION])return false;let e=gn();if(S__namespace.existsSync(e.configDir))return true;if(process.platform==="darwin")return ["/Applications/Claude.app",k__namespace.join(Re__namespace.homedir(),"Applications","Claude.app")].some(r=>S__namespace.existsSync(r));if(process.platform==="win32"){let t=process.env.LOCALAPPDATA||k__namespace.join(Re__namespace.homedir(),"AppData","Local"),r=process.env.PROGRAMFILES||"C:\\Program Files";return [k__namespace.join(t,"AnthropicClaude","Claude.exe"),k__namespace.join(r,"Claude","Claude.exe")].some(s=>S__namespace.existsSync(s))}if(process.platform==="linux"){let t=ke(),r=process.env.XDG_CONFIG_HOME||k__namespace.join(t.home,".config"),n=k__namespace.join(r,"Claude");return S__namespace.existsSync(n)}return false}function yo(){let e=So(),t=k__namespace.dirname(e);S__namespace.mkdirSync(t,{recursive:true});let r=Ct()?Oo():wo(),n=true;try{S__namespace.readFileSync(e,"utf8")===r&&(n=!1);}catch{}if(n&&(S__namespace.existsSync(e)&&S__namespace.copyFileSync(e,e+".bkp"),S__namespace.writeFileSync(e,r,{encoding:"utf8",mode:Ct()?420:493})),!Ct())try{S__namespace.chmodSync(e,493);}catch{}return e}function wo(){return ["#!/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","exec flow-ai-obs otel-headers",""].join(`
|
|
39
|
+
`);}}else process.stderr.write(t);}).catch(r=>{l("maybePersistUserEmail",`${e}: getEmailFromToken failed: ${r.message}`);})}var un=_(()=>{"use strict";qe();de();x();P();});function uo(e){return lo.some(t=>t.test(e))}function po(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 me(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 pn(e){let t=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),r=Buffer.from(JSON.stringify({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant})).toString("base64url");return `${t}.${r}.`}function Pe(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&&uo(t.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${t.hostname}`);return e}async function dn(){let e=me(process.env[d.ANTHROPIC_AUTH_TOKEN]);return e?{user:await Xe().catch(()=>null)??e.clientId,tenant:e.tenant}:{user:"",tenant:""}}function fo(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 Ie(){let e=ft(d.FLOW_USER_EMAIL);if(e!==void 0){let r=e.replace(/[\r\n]/g,"").trim();if(r)if(r.length>Y.EMAIL_MAX_LENGTH)l("resolveUserEmail",`FLOW_USER_EMAIL exceeds ${Y.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!Y.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=fo("x-flow-user");if(t){let r=t.replace(/[\r\n]/g,"").trim();if(r.length>Y.EMAIL_MAX_LENGTH)l("resolveUserEmail",`x-flow-user from OTEL_EXPORTER_OTLP_HEADERS exceeds ${Y.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!Y.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 se(){let e=process.env[d.FLOW_API_KEY];if(!e)return null;let t=e.replace(/[\r\n]/g,"").trim();return t?t.length>Y.API_KEY_MAX_LENGTH?(l("resolveApiKey",`FLOW_API_KEY exceeds ${Y.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):Y.API_KEY_PATTERN.test(t)?t:(l("resolveApiKey","FLOW_API_KEY contains non-printable or control characters \u2014 rejected"),null):null}function mo(){return new Date().toISOString().slice(0,10)}async function go(e){let t=mo(),r=await Et();if(r?.lastAuthCheckAt!==t){l("getOrRefreshToken",`daily auth check (last: ${r?.lastAuthCheckAt??"never"})`);let o=Ye.MAX_RETRY_ATTEMPTS;for(let i=1;i<=o;i++)try{let a=await q(e);try{await fe({...a,lastAuthCheckAt:t});}catch(p){l("getOrRefreshToken",`saveTokenCache failed (non-fatal): ${p.message}`);}return l("getOrRefreshToken",`daily check passed (attempt ${i}), expires=${a.expiresAt}`),se()?ln()||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,Ye.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 q(e);try{await fe({...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 Eo(e,t){let r=t&&t.accessToken?t.accessToken:"";return {endpoint:e.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function ho(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 ie(){let e=[],t=me(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 y={user:u??"",tenant:E??"",team:"",project:""};e.push({mode:"direct",...ho(Pe(s),o,i),...y}),l("resolveCredentials","direct mode active",`user=${y.user}`,`tenant=${y.tenant}`);}if(!t){if(e.length===0){let u=[];return u.authError=false,u}return e}let a;try{a=await go(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:po(a)??t.clientId,tenant:r,team:"",project:""},g=process.env[d.FLOW_TELEMETRY_GATEWAY]??we();return e.push({mode:"gateway",...Eo(Pe(g),{accessToken:a}),...p}),e}var lo,K=_(()=>{"use strict";qe();Re();P();x();un();de();lo=[/^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 Nt(){return process.platform==="win32"||mn()}function To(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=k__namespace.join(s,C.DIR_3P);return Ct(o)}}if(process.platform==="win32"){let n=process.env.LOCALAPPDATA||k__namespace.join(Le__namespace.homedir(),"AppData","Local"),s=k__namespace.join(n,C.DIR_3P);return Ct(s)}if(process.platform==="darwin"){let n=k__namespace.join(Le__namespace.homedir(),"Library","Application Support",C.DIR_3P);return Ct(n)}let e=ke(),t=process.env.XDG_CONFIG_HOME||k__namespace.join(e.home,".config"),r=k__namespace.join(t,C.DIR_3P);return Ct(r)}function Ct(e){return {configDir:e,configLibraryDir:k__namespace.join(e,C.CONFIG_LIBRARY_DIR),desktopConfigPath:k__namespace.join(e,C.DESKTOP_CONFIG_FILE),metaPath:k__namespace.join(e,C.CONFIG_LIBRARY_DIR,C.META_FILE)}}function So(){let e=ne(),t=k__namespace.dirname(e),r=Nt()?C.WRAPPER_SCRIPT_WIN:C.WRAPPER_SCRIPT_UNIX;return k__namespace.join(t,r)}function hr(){if(process.env[d.FLOW_OBS_SKIP_DESKTOP_DETECTION])return false;let e=gn();if(S__namespace.existsSync(e.configDir))return true;if(process.platform==="darwin")return ["/Applications/Claude.app",k__namespace.join(Le__namespace.homedir(),"Applications","Claude.app")].some(r=>S__namespace.existsSync(r));if(process.platform==="win32"){let t=process.env.LOCALAPPDATA||k__namespace.join(Le__namespace.homedir(),"AppData","Local"),r=process.env.PROGRAMFILES||"C:\\Program Files";return [k__namespace.join(t,"AnthropicClaude","Claude.exe"),k__namespace.join(r,"Claude","Claude.exe")].some(s=>S__namespace.existsSync(s))}if(process.platform==="linux"){let t=ke(),r=process.env.XDG_CONFIG_HOME||k__namespace.join(t.home,".config"),n=k__namespace.join(r,"Claude");return S__namespace.existsSync(n)}return false}function yo(){let e=So(),t=k__namespace.dirname(e);S__namespace.mkdirSync(t,{recursive:true});let r=Nt()?Oo():wo(),n=true;try{S__namespace.readFileSync(e,"utf8")===r&&(n=!1);}catch{}if(n&&(S__namespace.existsSync(e)&&S__namespace.copyFileSync(e,e+".bkp"),S__namespace.writeFileSync(e,r,{encoding:"utf8",mode:Nt()?420:493})),!Nt())try{S__namespace.chmodSync(e,493);}catch{}return e}function wo(){return ["#!/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","exec flow-ai-obs otel-headers",""].join(`
|
|
40
40
|
`)}function Oo(){return ["@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.","flow-ai-obs otel-headers",""].join(`\r
|
|
41
|
-
`)}function
|
|
42
|
-
`;try{if(S__namespace.readFileSync(e,"utf8")===s)return}catch{}S__namespace.existsSync(e)&&S__namespace.copyFileSync(e,e+".bkp"),S__namespace.writeFileSync(e,s,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(e,384);}catch{}}function ko(e,t,r,n){S__namespace.mkdirSync(e,{recursive:true});let s=k__namespace.resolve(e),o=k__namespace.resolve(e,`${t}.json`);if(!o.startsWith(s+k__namespace.sep))throw new Error(`Security error: invalid config path ${o}`);let i={};try{let c=S__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[
|
|
43
|
-
`;try{if(S__namespace.readFileSync(o,"utf8")===a)return o}catch{}if(S__namespace.existsSync(o)){S__namespace.copyFileSync(o,o+".bkp");try{S__namespace.chmodSync(o+".bkp",384);}catch{}}S__namespace.writeFileSync(o,a,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(o,384);}catch{}return o}function Po(e){let t=k__namespace.dirname(e);S__namespace.mkdirSync(t,{recursive:true});let r={};try{let n=S__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!==
|
|
44
|
-
`,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(e,384);}catch{}}}function En(e){if(!hr())return {configured:false};let t=gn(),r=e??J().OTEL_ENDPOINT,n=yo(),s=
|
|
41
|
+
`)}function Ro(e){try{let t=S__namespace.readFileSync(e,"utf8");try{let r=JSON.parse(t);if(r.appliedId&&typeof r.appliedId=="string"&&Ao.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 Lo(e,t){let r=k__namespace.dirname(e);S__namespace.mkdirSync(r,{recursive:true});let n;try{let o=S__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(S__namespace.readFileSync(e,"utf8")===s)return}catch{}S__namespace.existsSync(e)&&S__namespace.copyFileSync(e,e+".bkp"),S__namespace.writeFileSync(e,s,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(e,384);}catch{}}function ko(e,t,r,n){S__namespace.mkdirSync(e,{recursive:true});let s=k__namespace.resolve(e),o=k__namespace.resolve(e,`${t}.json`);if(!o.startsWith(s+k__namespace.sep))throw new Error(`Security error: invalid config path ${o}`);let i={};try{let c=S__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()?To(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(S__namespace.readFileSync(o,"utf8")===a)return o}catch{}if(S__namespace.existsSync(o)){S__namespace.copyFileSync(o,o+".bkp");try{S__namespace.chmodSync(o+".bkp",384);}catch{}}S__namespace.writeFileSync(o,a,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(o,384);}catch{}return o}function Po(e){let t=k__namespace.dirname(e);S__namespace.mkdirSync(t,{recursive:true});let r={};try{let n=S__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){S__namespace.existsSync(e)&&S__namespace.copyFileSync(e,e+".bkp"),r.deploymentMode=C.DEPLOYMENT_MODE,S__namespace.writeFileSync(e,JSON.stringify(r,null,2)+`
|
|
44
|
+
`,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(e,384);}catch{}}}function En(e){if(!hr())return {configured:false};let t=gn(),r=e??J().OTEL_ENDPOINT,n=yo(),s=Ro(t.metaPath),o=ko(t.configLibraryDir,s,r,n);return Lo(t.metaPath,s),Po(t.desktopConfigPath),{configured:true,configDir:t.configDir,configLibraryPath:o,uuid:s,wrapperScriptPath:n}}var Ao,hn=_(()=>{"use strict";P();ut();x();Ao=/^[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 k__namespace.join(n,"Code","User","settings.json")}if(process.platform==="win32"){let r=process.env.APPDATA||k__namespace.join(Le__namespace.homedir(),"AppData","Roaming");return k__namespace.join(r,"Code","User","settings.json")}if(process.platform==="darwin")return k__namespace.join(Le__namespace.homedir(),"Library","Application Support","Code","User","settings.json");let e=process.platform==="linux"&&process.getuid?.()===0?ke().home:process.env.HOME||Le__namespace.homedir(),t=process.env.XDG_CONFIG_HOME||k__namespace.join(e,".config");return k__namespace.join(t,"Code","User","settings.json")}function _n(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[d.FLOW_OBS_SKIP_COPILOT_DETECTION])return !!(e&&S__namespace.existsSync(e));if(e&&(S__namespace.existsSync(e)||S__namespace.existsSync(k__namespace.dirname(e))||S__namespace.existsSync(k__namespace.dirname(k__namespace.dirname(e)))))return true;let t=_r();if(t&&(S__namespace.existsSync(t)||S__namespace.existsSync(k__namespace.dirname(t))||S__namespace.existsSync(k__namespace.dirname(k__namespace.dirname(t))))||process.platform==="darwin"&&["/Applications/Visual Studio Code.app",k__namespace.join(Le__namespace.homedir(),"Applications","Visual Studio Code.app")].some(n=>S__namespace.existsSync(n)))return true;if(process.platform==="win32"){let r=process.env.LOCALAPPDATA||k__namespace.join(Le__namespace.homedir(),"AppData","Local"),n=process.env.PROGRAMFILES||"C:\\Program Files",s=process.env["PROGRAMFILES(X86)"]||"C:\\Program Files (x86)";if([k__namespace.join(r,"Programs","Microsoft VS Code","Code.exe"),k__namespace.join(n,"Microsoft VS Code","Code.exe"),k__namespace.join(s,"Microsoft VS Code","Code.exe")].some(i=>S__namespace.existsSync(i)))return true}return !!(process.platform==="linux"&&["/usr/bin/code","/usr/share/code","/snap/bin/code"].some(n=>S__namespace.existsSync(n)))}function Tn(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(S__namespace.existsSync(r))try{let w=_n(S__namespace.readFileSync(r,"utf8"));n=JSON.parse(w);}catch{return {status:"skipped",settingsPath:r,reason:"VS Code settings.json could not be parsed (unsupported JSONC syntax such as comments)"}}let s=e||J().OTEL_ENDPOINT,o=t.apiKey!==void 0?t.apiKey:se(),i=t.userEmail!==void 0?t.userEmail:Ie(),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 p=Object.keys(c),g=Object.keys(a),u=p.length===0&&(n[T.HEADERS_KEY]===void 0||g.length===0)||p.length===g.length&&p.every(w=>a[w]===c[w]);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&&u)return {status:"already_configured",settingsPath:r};S__namespace.mkdirSync(k__namespace.dirname(r),{recursive:!0});let y={...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 p.length>0&&(y[T.HEADERS_KEY]=c),S__namespace.writeFileSync(r,JSON.stringify(y,null,2)+`
|
|
45
45
|
`,{encoding:"utf8"}),{status:"configured",settingsPath:r}}catch(n){return {status:"skipped",settingsPath:r,reason:n.message}}}function Sn(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(S__namespace.existsSync(r))try{let a=_n(S__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};S__namespace.mkdirSync(k__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]??J().OTEL_ENDPOINT,[T.HEADERS_KEY]:o};return S__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();
|
|
46
|
+
`,{encoding:"utf8"}),{status:"configured",settingsPath:r}}catch(n){return {status:"skipped",settingsPath:r,reason:n.message}}}var Tr=_(()=>{"use strict";P();K();ut();x();});var wn={};re(wn,{clearLoggedOutMarker:()=>yr,isLoggedOut:()=>Uo,markLoggedOut:()=>bo});function Sr(){return k__namespace.default.join(Le__namespace.default.homedir(),".claude","flow-obs",".logged-out")}function bo(){try{let e=Sr();S__namespace.default.mkdirSync(k__namespace.default.dirname(e),{recursive:!0}),S__namespace.default.writeFileSync(e,"",{mode:384});}catch{}}function yr(){try{S__namespace.default.unlinkSync(Sr());}catch{}}function Uo(){try{return S__namespace.default.existsSync(Sr())}catch{return false}}var wr=_(()=>{"use strict";});function Or(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():z("FLOW_BASE_URL")}function Co(){return z(d.ANTHROPIC_AUTH_TOKEN)??void 0}async function Dt(){let e=Or();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=Co(),r=me(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 q({clientId:r.clientId,clientSecret:r.clientSecret,tenant:r.tenant});await fe({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 Ar=_(()=>{"use strict";qe();K();de();P();Re();});var Tt={};re(Tt,{promptRaw:()=>_t,runLogin:()=>Fo});function ee(e){return typeof e=="string"?e.replace(No,""):e}function _t(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=g=>{if(g===""){p(),n(new Error("SIGINT"));return}if(g==="\r"||g===`
|
|
47
47
|
`){p(),process.stdout.write(`
|
|
48
|
-
`),r(i);return}if(g==="\x7F"){i.length>0&&(i=i.slice(0,-1),process.stdout.write("\b \b"));return}g.startsWith("\x1B")||(i+=g,process.stdout.write(s?"*".repeat(g.length):g));};function p(){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=false){let r=Or(),n=process.env.FLOW_BASE_URL;r&&(process.env.FLOW_BASE_URL=r);try{let{accessToken:s,expiresAt:o}=await q(e),i=pn(e);if(t)return {jwt:i,accessToken:s,expiresAt:o};
|
|
48
|
+
`),r(i);return}if(g==="\x7F"){i.length>0&&(i=i.slice(0,-1),process.stdout.write("\b \b"));return}g.startsWith("\x1B")||(i+=g,process.stdout.write(s?"*".repeat(g.length):g));};function p(){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=false){let r=Or(),n=process.env.FLOW_BASE_URL;r&&(process.env.FLOW_BASE_URL=r);try{let{accessToken:s,expiresAt:o}=await q(e),i=pn(e);if(t)return {jwt:i,accessToken:s,expiresAt:o};je({[d.ANTHROPIC_AUTH_TOKEN]:i}),yr(),await fe({accessToken:s,expiresAt:o});}finally{n===void 0?delete process.env.FLOW_BASE_URL:process.env.FLOW_BASE_URL=n;}}async function $o(e=false){try{let t=(await _t(D(" ? ")+"Client ID: ")).trim(),r=(await _t(D(" ? ")+"Client Secret: ",{masked:!0})).trim(),n=(await _t(D(" ? ")+"Tenant: ")).trim();if(!t||!r||!n)return process.stderr.write($(` \u2717 All fields are required
|
|
49
49
|
`)),1;if(process.stdout.write(m(` Authenticating...
|
|
50
50
|
`)),e){let s=await xt({clientId:t,clientSecret:r,tenant:n},!0);return process.stdout.write(`
|
|
51
51
|
${I("\u2713")} ${b("Authenticated")}
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
`)+m(` Storage: ANTHROPIC_AUTH_TOKEN (settings.json)
|
|
59
59
|
|
|
60
60
|
`)),0}catch(t){if(t.message==="SIGINT"||t.message==="NOT_A_TTY")throw t;return process.stderr.write(`
|
|
61
|
-
${
|
|
61
|
+
${$("\u2717")} ${b("Authentication failed:")}
|
|
62
62
|
${ee(t.message)}
|
|
63
63
|
|
|
64
64
|
`),1}}async function Fo(e={}){let t=It();if(t)return t;let{deferPersist:r=false,skipAuthCheck:n=false}=e;if(e.clientId&&e.clientSecret&&e.tenant)try{if(r){let o=await xt({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant},!0);return process.stdout.write(I(` \u2713 Authenticated. Tenant: ${ee(e.tenant)}
|
|
65
65
|
|
|
66
66
|
`)),{code:0,result:o}}return await xt({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant}),process.stdout.write(I(` \u2713 Authenticated. Tenant: ${ee(e.tenant)}
|
|
67
67
|
|
|
68
|
-
`)),0}catch(o){return process.stderr.write(
|
|
68
|
+
`)),0}catch(o){return process.stderr.write($(` \u2717 Authentication failed: ${ee(o.message)}
|
|
69
69
|
`)),1}let s=await Dt();if(!n){if(process.stdout.write(`
|
|
70
70
|
`),process.stdout.write(b(` Auth
|
|
71
71
|
`)),s.notConfigured)return process.stdout.write(` ${v("\u26A0")} Not configured
|
|
@@ -89,16 +89,16 @@
|
|
|
89
89
|
`),process.stdout.write(m(" User: ")+m("(not authenticated)")+`
|
|
90
90
|
`),process.stdout.write(`
|
|
91
91
|
`));}try{return await $o(r)}catch(o){if(o.message==="SIGINT")return process.stdout.write(`
|
|
92
|
-
`),130;if(o.message==="NOT_A_TTY")return process.stderr.write(
|
|
92
|
+
`),130;if(o.message==="NOT_A_TTY")return process.stderr.write($(` \u2717 No TTY available for interactive login.
|
|
93
93
|
`)+` Pass --client-id, --client-secret and --tenant for non-interactive use.
|
|
94
94
|
|
|
95
|
-
`),1;throw o}}var
|
|
95
|
+
`),1;throw o}}var No,St=_(()=>{"use strict";qe();wr();Re();K();de();P();le();vt();Ar();No=/[\x00-\x08\x0B-\x1F\x7F]|\x1b\[[0-9;]*[a-zA-Z]/g;});var Ln={};re(Ln,{normalizeCustomUrl:()=>Rn,runInit:()=>Mo,validateCustomUrl:()=>kr,validateEmail:()=>Lr});function Mt(e,t,r){process.stdout.write(b(D(`
|
|
96
96
|
[${e}/${t}] ${r}
|
|
97
97
|
`)));}function ge(e){process.stdout.write(` ${I("\u2713")} ${e}
|
|
98
98
|
`);}function be(e){process.stdout.write(` ${v("\u26A0")} ${e}
|
|
99
99
|
`);}function ve(e){process.stdout.write(` ${m(e)}
|
|
100
|
-
`);}function On(){return !!z(d.ANTHROPIC_AUTH_TOKEN)}function Do(){let e=cr();if(!e)return null;
|
|
101
|
-
`,{encoding:"utf8",mode:384});}catch{}return e}function
|
|
100
|
+
`);}function On(){return !!z(d.ANTHROPIC_AUTH_TOKEN)}function Do(){let e=cr();if(!e)return null;je({FLOW_BASE_URL:e});try{let t=bt(),r={};try{r=JSON.parse(S__namespace.readFileSync(t,"utf8"));}catch{return e}delete r.baseUrl,Object.keys(r).length===0?S__namespace.unlinkSync(t):S__namespace.writeFileSync(t,JSON.stringify(r,null,2)+`
|
|
101
|
+
`,{encoding:"utf8",mode:384});}catch{}return e}function Rn(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 kr(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.
|
|
102
102
|
Received: ${e}
|
|
103
103
|
Expected: https://tenant.example.com`);if(i.search)throw new Error(`Custom URL must not contain query parameters.
|
|
104
104
|
Received: ${e}
|
|
@@ -106,16 +106,16 @@
|
|
|
106
106
|
Received: ${e}
|
|
107
107
|
Expected: https://tenant.example.com`);if(i.username||i.password)throw new Error(`Custom URL must not contain embedded credentials.
|
|
108
108
|
Received: ${e}
|
|
109
|
-
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[d.FLOW_OBS_ALLOW_HTTP];try{delete process.env[d.FLOW_OBS_ALLOW_HTTP],Pe(a);}finally{c!==void 0&&(process.env[d.FLOW_OBS_ALLOW_HTTP]=c);}return a}let r=
|
|
109
|
+
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[d.FLOW_OBS_ALLOW_HTTP];try{delete process.env[d.FLOW_OBS_ALLOW_HTTP],Pe(a);}finally{c!==void 0&&(process.env[d.FLOW_OBS_ALLOW_HTTP]=c);}return a}let r=Rn(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[d.FLOW_OBS_ALLOW_HTTP];try{delete process.env[d.FLOW_OBS_ALLOW_HTTP],Pe(r);}finally{s!==void 0&&(process.env[d.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 kr(t)}catch(t){if(process.stderr.write(v(` \u2717 ${t.message}
|
|
110
110
|
|
|
111
|
-
`)),e===3)throw process.stderr.write(
|
|
111
|
+
`)),e===3)throw process.stderr.write($(` Too many invalid attempts.
|
|
112
112
|
|
|
113
|
-
`)),new Error("Too many invalid URL attempts")}throw new Error("Too many invalid URL attempts")}function An(e){return e.replace(/[\r\n]/g,"").trim()}function
|
|
114
|
-
To set it: flow-ai-obs init --custom-email <you@company.com>`),null}r&&be("--custom-email is ignored in interactive mode. Use --no-interactive to apply it.");async function i(){for(let c=1;c<=3;c++){let p;try{p=await Zt(" Enter your corporate email (e.g., user@company.com)");}catch(E){throw process.stderr.write(
|
|
113
|
+
`)),new Error("Too many invalid URL attempts")}throw new Error("Too many invalid URL attempts")}function An(e){return e.replace(/[\r\n]/g,"").trim()}function Lr(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 xo(e,t,r){let n=z(d.FLOW_USER_EMAIL),s=Ie(),o=s??"(could not be derived)";if(!e||!ue()){if(r){let c=An(r);if(!c)throw new Error("--custom-email: value is empty after normalization");let p=Lr(c);if(p)throw new Error(`--custom-email: ${p}`);return ge(`Email: ${b(c)}`),c}return n??s?ge(`Email: ${b(n??s)}`):be(`Email not configured \u2014 telemetry will not include user identity.
|
|
114
|
+
To set it: flow-ai-obs init --custom-email <you@company.com>`),null}r&&be("--custom-email is ignored in interactive mode. Use --no-interactive to apply it.");async function i(){for(let c=1;c<=3;c++){let p;try{p=await Zt(" Enter your corporate email (e.g., user@company.com)");}catch(E){throw process.stderr.write($(` \u2717 Input error: ${E.message}
|
|
115
115
|
|
|
116
|
-
`)),E}let g=An(p),u=
|
|
116
|
+
`)),E}let g=An(p),u=Lr(g);if(!u)return g;process.stderr.write(v(` \u2717 ${u}
|
|
117
117
|
|
|
118
|
-
`));}throw process.stderr.write(
|
|
118
|
+
`));}throw process.stderr.write($(` Too many invalid attempts.
|
|
119
119
|
|
|
120
120
|
`)),new Error("Too many invalid email attempts")}async function a(){let c=await i();return process.stdout.write(I(` \u2713 Email: ${c}
|
|
121
121
|
|
|
@@ -141,10 +141,10 @@
|
|
|
141
141
|
`)+v(" on Windows too: ")+D(`npm install -g @ciandt-flow/flow-ai-obs
|
|
142
142
|
`)+v(` Without the Windows install, observability will not work for the Windows-side code assistant.
|
|
143
143
|
|
|
144
|
-
`)),Do(),!r&&!e.noInteractive&&ue()){let f=yt();o?r=await
|
|
144
|
+
`)),Do(),!r&&!e.noInteractive&&ue()){let f=yt();o?r=await Rr():f?(process.stdout.write(`
|
|
145
145
|
Current base URL: ${b(f)}
|
|
146
|
-
`),await ot(" Keep this URL?",true)||(r=await
|
|
147
|
-
`),await ot(" Does your organization use a custom Flow URL?",false)?r=await
|
|
146
|
+
`),await ot(" Keep this URL?",true)||(r=await Rr())):(process.stdout.write(`
|
|
147
|
+
`),await ot(" Does your organization use a custom Flow URL?",false)?r=await Rr():ge("Using default Flow Base URL: https://flow.ciandt.com")),process.stdout.write(`
|
|
148
148
|
`);}if(!r&&!e.noInteractive&&!ue()){let f=yt();if(f)process.stdout.write(v(` \u26A0 Non-interactive environment detected.
|
|
149
149
|
`)+m(` Using URL: ${f}
|
|
150
150
|
|
|
@@ -164,15 +164,15 @@
|
|
|
164
164
|
\u2713 Flow environment ready.
|
|
165
165
|
`));let p=36;for(let[f,U]of Object.entries(c))process.stdout.write(m(` ${f.padEnd(p)}`)+U+`
|
|
166
166
|
`);Mt(2,s,"User Identity");let g=await xo(!e.noInteractive,!!(r??cr()),e.email),u=null;if(n)l("init","FLOW_API_KEY detected \u2014 skipping OAuth authentication step");else {Mt(3,s,"Authentication");let f=yt(),U=!!f&&f!==i;if(!On()||a||U)if(e.noInteractive||!ue()){let{clientId:B,clientSecret:V,tenant:W}=e,ce=B&&V&&W;if(!ce&&(B||V||W)){let De=[!B&&"--client-id",!V&&"--client-secret",!W&&"--tenant"].filter(Boolean).join(", ");return process.stderr.write(`
|
|
167
|
-
${
|
|
167
|
+
${$("\u2717")} Non-interactive mode requires all credential flags.
|
|
168
168
|
Missing: ${De}
|
|
169
169
|
|
|
170
170
|
`),1}if(ce){let{runLogin:De}=await Promise.resolve().then(()=>(St(),Tt)),xe;try{xe=await De({deferPersist:!0,clientId:B,clientSecret:V,tenant:W});}catch(Jt){return process.stderr.write(`
|
|
171
|
-
${
|
|
171
|
+
${$("\u2717")} Authentication failed unexpectedly.
|
|
172
172
|
${Jt.message}
|
|
173
173
|
|
|
174
174
|
`),1}if(typeof xe=="number")return xe;u=xe.result;}else return process.stderr.write(`
|
|
175
|
-
${
|
|
175
|
+
${$("\u2717")} Authentication required.
|
|
176
176
|
Run: flow-ai-obs login
|
|
177
177
|
|
|
178
178
|
`),1}else {(e.clientId||e.clientSecret||e.tenant)&&process.stderr.write(`
|
|
@@ -209,11 +209,11 @@
|
|
|
209
209
|
|
|
210
210
|
`)+m(` Start your code assistant and begin working.
|
|
211
211
|
|
|
212
|
-
`))),0}var kn=_(()=>{"use strict";de();P();le();vt();lr();
|
|
212
|
+
`))),0}var kn=_(()=>{"use strict";de();P();le();vt();lr();K();Qt();x();hn();Tr();});var Un={};re(Un,{runStatus:()=>Bo});function Pn(e){return !e||e.length<=8?"****":e.slice(0,4)+"****...****"+e.slice(-4)}function Ho(e){process.stdout.write(` ${I("\u2713")} ${e}
|
|
213
213
|
`);}function Pr(e){process.stdout.write(` ${v("\u26A0")} ${e}
|
|
214
214
|
`);}function wt(e){process.stdout.write(` ${I("\u2713")} ${e}
|
|
215
215
|
`);}function Ht(e){process.stdout.write(` ${v("\u26A0")} ${e}
|
|
216
|
-
`);}function Bt(e){process.stdout.write(` ${
|
|
216
|
+
`);}function Bt(e){process.stdout.write(` ${$("\u2717")} ${e}
|
|
217
217
|
`);}function Qe(e){process.stdout.write(` ${m(e)}
|
|
218
218
|
`);}function In(e){process.stdout.write(b(D(`
|
|
219
219
|
${e}
|
|
@@ -229,19 +229,19 @@
|
|
|
229
229
|
`)):Pr(`Session rejected by ${e.baseUrl}. Run \`flow-ai-obs login\` to re-authenticate.`);let t={},r={};try{let u=S__namespace.readFileSync(ne(),"utf8");r=JSON.parse(u),t=r.env||{};}catch{}In("Observability configuration (OpenTelemetry)");let n=Object.keys(pe).filter(u=>!t[u]);vn("Metrics and Logs",n.length>0),n.length===0?(wt("All OTEL env vars present in settings.json"),Qe(`Endpoint: ${t.OTEL_EXPORTER_OTLP_ENDPOINT}`)):(process.stdout.write(`
|
|
230
230
|
`),process.stdout.write(` ${m("Run: flow-ai-obs init (restores missing vars automatically)")}
|
|
231
231
|
`),process.stdout.write(`
|
|
232
|
-
`),Ht(`${n.length} OTEL var(s) missing from settings.json`),n.forEach(u=>Bt(`Missing: ${u}`))),Ir();for(let u of Object.keys(pe)){let E=t[u]
|
|
232
|
+
`),Ht(`${n.length} OTEL var(s) missing from settings.json`),n.forEach(u=>Bt(`Missing: ${u}`))),Ir();for(let u of Object.keys(pe)){let E=t[u]??$("(missing)");process.stdout.write(m(` ${u.padEnd(36)}`)+E+`
|
|
233
233
|
`);}let s=r.hooks??{},o=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],i=o.every(u=>{let E=s[u];return Array.isArray(E)?E.some(y=>{let w=y;return Array.isArray(w?.hooks)&&w.hooks.some(O=>O?.command?.startsWith(lt.CLI))}):false});vn("Tracing",!i),i?wt("Hooks registered (trace capture)"):(process.stdout.write(`
|
|
234
234
|
`),process.stdout.write(` ${m("Run `flow-ai-obs init` to configure.")}
|
|
235
235
|
`),process.stdout.write(`
|
|
236
236
|
`),Ht("Hooks NOT registered."));for(let u of o){let E=Oe[u];process.stdout.write(m(` ${u.padEnd(18)}`)+`\u2192 flow-ai-obs ${u} (timeout: ${E}s)
|
|
237
|
-
`);}Ir();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 ie();for(let E of u)E.mode==="direct"&&(wt("FLOW_TELEMETRY=true (direct mode enabled)"),wt("Mode: direct"),Qe(`Endpoint: ${E.endpoint}`),Qe(`PK: ${Pn(p)}`),Qe(`SK: ${Pn(g)}`));}else Ht("FLOW_TELEMETRY=true but missing LANGFUSE vars:"),c||Bt("LANGFUSE_BASE_URL not set"),p||Bt("LANGFUSE_PUBLIC_KEY not set"),g||Bt("LANGFUSE_SECRET_KEY not set");else {let u=await ie();if(u.length>0)for(let E of u)E.mode==="gateway"&&(wt("Mode: gateway"),Qe(`Endpoint: ${E.endpoint}`));else u.authError?Ht("Gateway mode: token refresh failed. Run `flow-ai-obs login`."):Qe("No active tracing destination configured.");}return Ir(),0}var
|
|
237
|
+
`);}Ir();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 ie();for(let E of u)E.mode==="direct"&&(wt("FLOW_TELEMETRY=true (direct mode enabled)"),wt("Mode: direct"),Qe(`Endpoint: ${E.endpoint}`),Qe(`PK: ${Pn(p)}`),Qe(`SK: ${Pn(g)}`));}else Ht("FLOW_TELEMETRY=true but missing LANGFUSE vars:"),c||Bt("LANGFUSE_BASE_URL not set"),p||Bt("LANGFUSE_PUBLIC_KEY not set"),g||Bt("LANGFUSE_SECRET_KEY not set");else {let u=await ie();if(u.length>0)for(let E of u)E.mode==="gateway"&&(wt("Mode: gateway"),Qe(`Endpoint: ${E.endpoint}`));else u.authError?Ht("Gateway mode: token refresh failed. Run `flow-ai-obs login`."):Qe("No active tracing destination configured.");}return Ir(),0}var Cn=_(()=>{"use strict";K();de();P();le();Ar();});var Nn={};re(Nn,{runUpdateApiKey:()=>Wo});async function Wo(e={}){let t=e.key||se();if(!t)return process.stderr.write($(` \u2717 FLOW_API_KEY environment variable is not set or is invalid.
|
|
238
238
|
`)+m(` Set FLOW_API_KEY=<key> in your environment and re-run.
|
|
239
239
|
|
|
240
240
|
`)),1;let r=Sn(t);return r.status==="configured"?(process.stdout.write(I(` \u2713 GitHub Copilot API key updated successfully in ${r.settingsPath}
|
|
241
241
|
`)),0):r.status==="already_configured"?(process.stdout.write(I(` \u2713 GitHub Copilot API key is already up to date in ${r.settingsPath}
|
|
242
242
|
`)),0):r.reason?.includes("not installed")?(process.stdout.write(m(` \u2139 VS Code is not installed \u2014 skipping Copilot API key update.
|
|
243
|
-
`)),0):(process.stderr.write(
|
|
244
|
-
`)),1)}var $n=_(()=>{"use strict";
|
|
243
|
+
`)),0):(process.stderr.write($(` \u2717 GitHub Copilot API key update failed: ${r.reason}
|
|
244
|
+
`)),1)}var $n=_(()=>{"use strict";K();Tr();le();});var Fn={};re(Fn,{runOtelHeaders:()=>Yo});async function Yo(){let e=se(),t=Ie(),r=me(ft(d.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.
|
|
245
245
|
Run: flow-ai-obs init --custom-email <EMAIL>
|
|
246
246
|
`),1;if(!e&&process.env[d.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.
|
|
247
247
|
`),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)+`
|
|
@@ -249,20 +249,20 @@
|
|
|
249
249
|
`),1;let n=ft(d.FLOW_BASE_URL),s=process.env[d.FLOW_BASE_URL];n&&(process.env[d.FLOW_BASE_URL]=n);let o;try{o=(await q(r)).accessToken;}catch(i){return process.stderr.write(`[flow-ai-obs otel-headers] Token fetch failed: ${i.message}
|
|
250
250
|
`),1}finally{s===void 0?delete process.env[d.FLOW_BASE_URL]:process.env[d.FLOW_BASE_URL]=s;}return o?(process.stdout.write(JSON.stringify({Authorization:`Bearer ${o.replace(/[\r\n]/g,"")}`})+`
|
|
251
251
|
`),0):(process.stderr.write(`[flow-ai-obs otel-headers] Empty token received
|
|
252
|
-
`),1)}var Dn=_(()=>{"use strict";
|
|
253
|
-
`)[0].slice(0,t).trim()}function Ot(){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 H(e){process.stdout.write(JSON.stringify(e));}var et=_(()=>{"use strict";});function Ee(){return String(BigInt(Date.now())*1000000n)}var vr,Ue,At=_(()=>{"use strict";vr=()=>fn.randomBytes(16).toString("hex"),Ue=()=>fn.randomBytes(8).toString("hex");});function ei(e,t){let r=k.resolve(e);if(!r.startsWith(t))throw new Error(`Path traversal detected: ${e}`);return r}function br(e){if(!Zo.test(e))throw new Error(`Invalid session ID: ${e}`);return ei(k.join(
|
|
254
|
-
`);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
|
|
252
|
+
`),1)}var Dn=_(()=>{"use strict";Re();K();de();P();});function oe(e,t){let r=typeof e=="object"?JSON.stringify(e):String(e??"");return r.length>t?r.slice(0,t)+" \u2026[truncated]":r}function Wt(e,t=100){return String(e??"").split(`
|
|
253
|
+
`)[0].slice(0,t).trim()}function Ot(){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 H(e){process.stdout.write(JSON.stringify(e));}var et=_(()=>{"use strict";});function Ee(){return String(BigInt(Date.now())*1000000n)}var vr,Ue,At=_(()=>{"use strict";vr=()=>fn.randomBytes(16).toString("hex"),Ue=()=>fn.randomBytes(8).toString("hex");});function ei(e,t){let r=k.resolve(e);if(!r.startsWith(t))throw new Error(`Path traversal detected: ${e}`);return r}function br(e){if(!Zo.test(e))throw new Error(`Invalid session ID: ${e}`);return ei(k.join(Le.tmpdir(),`flow-obs-${e}.json`),Qo)}function tt(e){let t;try{t=br(e);}catch{return null}if(!S.existsSync(t))return null;try{return JSON.parse(S.readFileSync(t,"utf8"))}catch{return null}}function rt(e,t){S.writeFileSync(br(e),JSON.stringify(t),{encoding:"utf8",mode:384});}function Ur(e){try{S.unlinkSync(br(e));}catch{}}var Zo,Qo,Rt=_(()=>{"use strict";Zo=/^[0-9a-f-]{1,64}$/i,Qo=k.normalize(Le.tmpdir())+k.sep;});function Wn(e){if(!e||!S.existsSync(e))return null;try{let t=S.readFileSync(e,"utf8").trimEnd().split(`
|
|
254
|
+
`);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 Cr(e){if(!e||!S.existsSync(e))return null;try{let t=S.readFileSync(e,"utf8").trimEnd().split(`
|
|
255
255
|
`),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 p=(a.message?.content??[]).filter(u=>u.type==="text").map(u=>u.text??"").join("");p&&r.unshift(p);let g=a.message?.usage??{};n+=(g.input_tokens??0)+(g.cache_read_input_tokens??0)+(g.cache_creation_input_tokens??0),s+=g.output_tokens??0;}}catch{}return !r.length&&n===0?null:{text:r.join(`
|
|
256
256
|
|
|
257
|
-
`),inputTokens:n,outputTokens:s,model:o}}catch{}return null}var
|
|
258
|
-
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function Gn(e){return !!e.slashSkill||e.toolCalls.some(n=>n.tool==="Skill")?e.toolCalls.some(n=>n.tool==="Skill"&&!n.synthetic||ai.has(n.tool))?"complete":"prerequisite_required":null}function
|
|
259
|
-
`);return}let n=!!(await ie()).authError,s=e.session_id||"unknown",o=e.prompt||"",i=e.cwd||"",a=Wn(e.transcript_path)||vr(),c=Vn(o),p=c?Yt(c,i):null,g=c?
|
|
260
|
-
`,{flag:"a",encoding:"utf8",mode:384}),l("sendTraces:dump",`request appendada em ${Qn}`);}catch(i){l("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Ti(e){let t=new URL(e),r=new URL(J().GATEWAY_HEALTH);return r.hostname=t.hostname,r.port=t.port,r.protocol=t.protocol,r}function ts(e,t){return new Promise((r,n)=>{let s=e._isSSL?
|
|
257
|
+
`),inputTokens:n,outputTokens:s,model:o}}catch{}return null}var Nr=_(()=>{"use strict";});function jn(e){return e.replace(":","/")}function Yt(e,t){if(!e)return null;let r=jn(e),n=[k.join(Le.homedir(),".claude","skills",r,"SKILL.md"),k.join(t??"",".claude","skills",r,"SKILL.md")];for(let s of n)if(S.existsSync(s))try{return S.readFileSync(s,"utf8")}catch{}return null}function Vn(e){return e.split(`
|
|
258
|
+
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function Gn(e){return !!e.slashSkill||e.toolCalls.some(n=>n.tool==="Skill")?e.toolCalls.some(n=>n.tool==="Skill"&&!n.synthetic||ai.has(n.tool))?"complete":"prerequisite_required":null}function Kt(e,t){if(!e)return null;let r=jn(e),n=[k.join(Le.homedir(),".claude","skills",r),k.join(t??"",".claude","skills",r)],s=null;for(let a of n)if(S.existsSync(k.join(a,"SKILL.md"))){s=a;break}if(!s)return null;let o=[];function i(a,c){for(let p of S.readdirSync(a,{withFileTypes:true})){if(si.has(p.name)||ii.has(p.name)||oi.has(k.extname(p.name)))continue;let g=c?`${c}/${p.name}`:p.name;p.isDirectory()?i(k.join(a,p.name),g):o.push(g);}}return i(s,""),o.length>0?o:null}var si,oi,ii,ai,jt=_(()=>{"use strict";si=new Set([".venv","__pycache__",".git","node_modules"]),oi=new Set([".pyc",".pyo"]),ii=new Set(["SKILL.md",".DS_Store",".gitignore"]);ai=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);});function ui(e){try{let t=e.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(t,"base64").toString())}catch{return null}}function pi(e,t,r,n){return new Promise(s=>{let o=new URL(e),i=o.protocol==="https:",a=(i?Cs__default.default:qs__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=me(process.env[d.ANTHROPIC_AUTH_TOKEN]);if(!r)return;let n,s=new Promise((u,E)=>{n=setTimeout(()=>E(new Error("getToken timeout")),4e3),n.unref();}),{accessToken:o}=await Promise.race([q(r),s]);clearTimeout(n);let i=ui(o);if(!i)return;let a=i.tenant||r.tenant,c=JSON.stringify({action:e,booster:Pt().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||""}}),p=Pe(Pt().API_URL),g=await pi(p,c,o,a);l("metrics.logEvent",`action=${e} status=${g}`);}catch(r){l("metrics.logEvent",`silenced error: ${r.message}`);}}var Vt=_(()=>{"use strict";P();Re();K();x();});async function $r(e,t=false){if(t){process.stdout.write(JSON.stringify({decision:"block",reason:di})+`
|
|
259
|
+
`);return}let n=!!(await ie()).authError,s=e.session_id||"unknown",o=e.prompt||"",i=e.cwd||"",a=Wn(e.transcript_path)||vr(),c=Vn(o),p=c?Yt(c,i):null,g=c?Kt(c,i):null;rt(s,{traceId:vr(),spanId:Ue(),startNs:Ee(),sessionId:s,prompt:o,cwd:i,traceName:a,transcriptPath:e.transcript_path||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:c,skillContent:p,skillArtifacts:g}),Ce("SESSION_STARTED",{traceType:c?"skill":"prompt",slashSkill:c,clientIdExpired:n}),l("UserPromptSubmit",`sid=${s}`,`traceName=${a}`,`slashSkill=${c}`),H(e);}var di,Jn=_(()=>{"use strict";At();Rt();Nr();jt();et();x();P();K();Vt();di=`\u26D4 Your Flow API key has expired. You no longer have access to Claude Code through the Flow platform. To restore observability and access, visit ${we()}/settings/api-keys to generate a new API key, then run: flow-ai-obs login`;});async function Xn(e){let t=e.session_id||"unknown",r=e.tool_name||"unknown",n=e.tool_input||{},s=tt(t);s&&(s.pendingTool={name:r,inputStr:oe(n,Q.TOOL_INPUT),startNs:Ee()},rt(t,s)),l("PreToolUse",`sid=${t}`,`tool=${r}`,`stateFound=${!!s}`),H(e);}var qn=_(()=>{"use strict";At();Rt();et();x();P();});function h(e,t){return t==null||t===""?null:{key:e,value:{stringValue:String(t)}}}function Ne(...e){return e.filter(t=>t!==null)}function zn(e,t){return {resourceSpans:[{resource:{attributes:e},scopeSpans:[{scope:fi,spans:Array.isArray(t)?t:[t]}]}]}}var fi,R,Zn=_(()=>{"use strict";P();fi={name:kt.SCOPE_NAME,version:kt.SCOPE_VERSION},R={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 es(e,t,r,n,s){if(process.env[d.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{S.writeFileSync(Qn,o+`
|
|
260
|
+
`,{flag:"a",encoding:"utf8",mode:384}),l("sendTraces:dump",`request appendada em ${Qn}`);}catch(i){l("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Ti(e){let t=new URL(e),r=new URL(J().GATEWAY_HEALTH);return r.hostname=t.hostname,r.port=t.port,r.protocol=t.protocol,r}function ts(e,t){return new Promise((r,n)=>{let s=e._isSSL?Cs__default.default:qs__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 rs(e,t){let r;try{r=Ti(e);}catch{return false}let n=r.protocol==="https:";try{let s={};t&&(s.Authorization=String(t).replace(/[\r\n]/g,""));let o=await ts({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 ts({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}`),es(t,a,n,c.statusCode,c.body),c.statusCode}catch(c){return l("sendTraces:error",c.message),es(t,a,n,0,c.message),0}}var Qn,ns=_(()=>{"use strict";P();x();Qn=k.join(Le.tmpdir(),"flow-obs-requests.ndjson");});function Si(){let e=parseInt(process.env[d.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(e)?Math.max(X.MIN_TTL_DAYS,Math.min(X.MAX_TTL_DAYS,e)):X.DEFAULT_TTL_DAYS)*24*60*60*1e3}function yi(){let e=parseInt(process.env[d.BUFFER_MAX_FILES]??"",10);return Number.isFinite(e)?Math.max(X.MIN_MAX_FILES,Math.min(X.MAX_MAX_FILES,e)):X.DEFAULT_MAX_FILES}function os(e){if(/[/\\]/.test(e))throw new Error(`Invalid buffer fileId: ${e}`);return k__namespace.default.join(Le__namespace.default.tmpdir(),`${X.FILE_PREFIX}${e}.json`)}function Dr(){let e=Le__namespace.default.tmpdir(),t;try{t=S__namespace.default.readdirSync(e);}catch{return []}return t.filter(r=>r.startsWith(X.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=k__namespace.default.join(e,r),s=0;try{s=S__namespace.default.statSync(n).mtimeMs;}catch{}return {full:n,mtime:s}}).sort((r,n)=>r.mtime-n.mtime).map(r=>r.full)}function Lt(e){try{let t=yi(),r=Dr();if(r.length>=t){let o=r.slice(0,r.length-t+1);for(let i of o)try{S__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 S__namespace.default.writeFileSync(os(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 is(e){let t=Dr(),r=e!=null&&e>0?e:t.length,n=[];for(let s of t){if(n.length>=r)break;try{let o=S__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 as(e){try{S__namespace.default.unlinkSync(os(e)),l("buffer",`deleted fileId=${e}`);}catch{}}function cs(){let e=Date.now()-Si();for(let t of Dr())try{let{mtimeMs:r}=S__namespace.default.statSync(t);r<e&&(S__namespace.default.unlinkSync(t),l("buffer",`evicted stale: ${k__namespace.default.basename(t)}`));}catch{}}var ls=_(()=>{"use strict";P();x();});async function wi(e){cs();let t=is(X.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?(as(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 us(e){let t=await ie();if(!t.length)return t.authError&&(l("postToLangfuse","auth refresh failed \u2014 buffering trace"),Lt(e)),0;let r=await Promise.all(t.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await rs(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 wi(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"),Lt(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`),Lt(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`),Lt(e)),a}))).find(o=>o!==0)??0}var ps=_(()=>{"use strict";K();x();ns();ls();P();});var xr=_(()=>{"use strict";Zn();ps();});function _e(e){if(e==null)return "";let t=typeof e=="string"?e:JSON.stringify(e);return Li.reduce((r,{re:n,replace:s})=>r.replace(n,s),t)}var Z,Oi,Ai,Ri,ds,Li,Mr=_(()=>{"use strict";Z="[REDACTED]",Oi="[REDACTED-EMAIL]",Ai="[REDACTED-CPF]",Ri="[REDACTED-CNPJ]",ds="[REDACTED-PHONE]",Li=[{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}
|
|
261
261
|
${Z}
|
|
262
|
-
${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:()=>Oi},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>Ai},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>
|
|
263
|
-
`)),w=p?.inputTokens??0,O=p?.outputTokens??0,Fe=i.map((A,ye)=>`${ye+1}. ${A.tool}${A.brief?` \u2192 ${A.brief}`:""}${A.error?" [ERROR]":""} (${A.durationMs}ms)`),Te=!!(n.slashSkill||i.some(A=>A.tool==="Skill")),f=i.some(A=>A.tool==="Agent");if(!Te&&!f){l("Stop",`sid=${t}`,"skipping trace \u2014 no Skill or Agent calls found"),
|
|
262
|
+
${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:()=>Oi},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>Ai},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>Ri},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>ds},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>ds}];});async function fs(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=tt(t);if(!i){H(e);return}let a=Ee(),c=i.pendingTool,p=c?.name===r,g=p?c.startNs:String(BigInt(a)-200000000n),u=p?c.inputStr:oe(n,Q.TOOL_INPUT),E=u,y=null;if(r==="Skill"){let ce=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||n.commandName||String(Object.values(n)[0]??""):String(n);y=ce?String(ce).trim():null;let Se=y?Yt(y,i.cwd):null;Se&&(E=Se,i.skillContent||(i.skillContent=Se),i.skillArtifacts||(i.skillArtifacts=Kt(y,i.cwd))),y&&!i.slashSkill&&(i.slashSkill=y),l("PostToolUse","Skill tool detected",`skillName=${y}`,`contentFound=${!!Se}`);}let w=_e(oe(o,Q.TOOL_OUTPUT)),O=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(w.slice(0,500)),Fe=O?"ERROR":"DEFAULT",Te=Ue(),f=Math.round(Number(BigInt(a)-BigInt(g))/1e6),te={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL",B=r==="Skill"&&y?y:Wt(u,60);i.toolCalls.push({tool:r,brief:B,error:O,durationMs:f});let W=i.spans;W.push({traceId:i.traceId,spanId:Te,parentSpanId:i.spanId,name:r,kind:3,startTimeUnixNano:g,endTimeUnixNano:a,attributes:Ne(h(R.OBS_NAME,r),h(R.OBS_TYPE,te),h(R.OBS_LEVEL,Fe),h(R.OBS_INPUT,_e(E)),h(R.OBS_OUTPUT,w),h("tool.name",r),h("tool.error",String(O)),r==="Skill"&&y?h("skill.name",y):null,r==="Skill"?h("skill.invocation","slash-command"):null),status:{code:O?2:1}}),i.pendingTool=null,rt(t,i),O&&Ce("TOOL_ERROR",{toolName:r}),l("PostToolUse",`sid=${t}`,`tool=${r}`,`error=${O}`,`durationMs=${f}`,`totalSpans=${W.length}`),H(e);}var ms=_(()=>{"use strict";At();Rt();xr();et();jt();x();P();Mr();Vt();});function Es(e,t,r){let n=Object.keys(gs).find(i=>(e??"").toLowerCase().includes(i));if(!n)return;let s=gs[n],o=(t*s.input+r*s.output)/1e6;return Math.round(o*1e6)/1e6}var gs,hs=_(()=>{"use strict";gs={"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 _s(e){let t=e.session_id||"unknown",r=e.stop_reason||"end_turn",n=tt(t);if(!n){H(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=Ee(),o=await dn(),i=n.toolCalls,a=n.spans;if(n.slashSkill&&!i.some(A=>A.tool==="Skill")){let A=Ue(),ye=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:A,parentSpanId:n.spanId,name:"Skill",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:n.startNs,attributes:Ne(h(R.OBS_NAME,"Skill"),h(R.OBS_TYPE,"TOOL"),h(R.OBS_LEVEL,"DEFAULT"),h(R.OBS_INPUT,ye),h(R.OBS_OUTPUT,"loaded via slash command"),h("tool.name","Skill"),h("tool.error","false"),h("skill.name",n.slashSkill),h("skill.invocation","slash-command")),status:{code:1}}),l("Stop",`slashSkill=${n.slashSkill}`,"synthetic span injected");}let c=e.transcript_path||n.transcriptPath||"",p=Cr(c);if(c&&(i.some(A=>A.tool==="Skill"&&!A.synthetic)||!!n.slashSkill)&&!p?.text){await new Promise(ye=>setTimeout(ye,500));let A=Cr(c);A?.text&&(p=A);}l("Stop",`transcriptPath=${c||"(empty)"}`,`assistantOut=${p?`text=${p.text.length}chars`:"null"}`);let u=i.length,E=i.filter(A=>A.error).length,y=_e(p?.text?oe(p.text,Q.TRACE_OUTPUT):u===0?"No tools used":i.map((A,ye)=>`${ye+1}. ${A.tool}${A.brief?` \u2192 ${A.brief}`:""}${A.error?" [ERROR]":""}`).join(`
|
|
263
|
+
`)),w=p?.inputTokens??0,O=p?.outputTokens??0,Fe=i.map((A,ye)=>`${ye+1}. ${A.tool}${A.brief?` \u2192 ${A.brief}`:""}${A.error?" [ERROR]":""} (${A.durationMs}ms)`),Te=!!(n.slashSkill||i.some(A=>A.tool==="Skill")),f=i.some(A=>A.tool==="Agent");if(!Te&&!f){l("Stop",`sid=${t}`,"skipping trace \u2014 no Skill or Agent calls found"),Ce("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),Ur(t),H(e);return}let U=Te?"skill":"agent",te=Math.round(Number(BigInt(s)-BigInt(n.startNs))/1e6),B=p?.model||"",V=Es(B,w,O),W=Gn(n);W==="prerequisite_required"&&p?.text&&(W="complete"),W==="prerequisite_required"&&(a.push({traceId:n.traceId,spanId:Ue(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:Ne(h(R.OBS_NAME,"prerequisite-check"),h(R.OBS_TYPE,"EVENT"),h(R.OBS_LEVEL,"WARNING"),h(R.OBS_OUTPUT,y),h("skill.name",n.slashSkill||void 0),h("execution_status","prerequisite_required")),status:{code:1}}),l("Stop",`sid=${t}`,"prerequisite-check span injected",`skill=${n.slashSkill}`));let ce=(()=>{if(!(!Te||!n.prompt)){if(n.slashSkill){let A=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return A?oe(_e(A),Q.USER_INSTRUCTION):void 0}return oe(_e(n.prompt),Q.USER_INSTRUCTION)||void 0}})(),Se=JSON.stringify({trace_type:U,...W!==null&&{execution_status:W},...n.slashSkill?{skill_name:n.slashSkill}:{},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...ce!==void 0&&{user_instruction:ce},latency_ms:te,...w&&{tokens_input:w},...O&&{tokens_output:O},cost_usd:V,...B?{model:B}:{},toolCount:u,errorCount:E,stopReason:r,sessionId:n.sessionId,tools:Fe.length?Fe:void 0}),De=_e(oe(n.prompt,Q.TRACE_INPUT)),xe=Ne(h(R.TRACE_NAME,n.traceName),h(R.TRACE_INPUT,De),h(R.TRACE_OUTPUT,y),h(R.OBS_INPUT,De),h(R.OBS_OUTPUT,y),h(R.TRACE_METADATA,Se),h(R.SESSION_ID,n.sessionId),h(R.USER_ID,o.user),h(R.OBS_TYPE,"GENERATION"),h(R.MODEL,B),w?h(R.INPUT_TOKENS,w):null,O?h(R.OUTPUT_TOKENS,O):null,h("claude.stop_reason",r),h("claude.tool_count",String(u)),h("claude.error_count",String(E)),h("claude.session_id",n.sessionId),h("flow.trace_type",U),{key:R.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:U}]}}}),Jt={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:xe,status:{code:E>0?2:1}},Os=Ne(h("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),h("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),Hr=[...a,Jt];l("Stop",`sid=${t}`,`totalTools=${u}`,`errorTools=${E}`,`spans=${Hr.length}`,`inputTokens=${w}`,`outputTokens=${O}`,`traceOutput="${Wt(y,80)}"`);let As=await us(zn(Os,Hr));l("Stop",`POST status=${As}`,`traceId=${n.traceId}`),Ce("TRACE_SENT",{latencyMs:te,totalTools:u,errorTools:E,inputTokens:w,outputTokens:O,costUsd:V}),Ur(t),H(e);}var Ts=_(()=>{"use strict";At();Rt();xr();K();hs();Nr();et();x();jt();Mr();P();Vt();});var $e,Ss=_(()=>{"use strict";K();et();Jn();qn();ms();Ts();$e=class{static async userPromptSubmit(){let t=await Ot(),r;try{r=await ie();}catch{H(t);return}r.authError?await $r(t,!0):r.length>0?await $r(t):H(t);}static async preToolUse(){let t=await Ot();await Xn(t);}static async postToolUse(){let t=await Ot();await fs(t);}static async stop(){let t=await Ot();await _s(t);}};});var Pi={};async function ki(){let e=process.argv[2];switch(e){case "UserPromptSubmit":await $e.userPromptSubmit();break;case "PreToolUse":await $e.preToolUse();break;case "PostToolUse":await $e.postToolUse();break;case "Stop":await $e.stop();break;default:process.stderr.write(`[flow-obs] unknown event: ${e}
|
|
264
264
|
`),process.stdin.on("data",t=>process.stdout.write(t));}}var ys=_(()=>{"use strict";Ss();ki().catch(e=>{process.stderr.write(`[flow-obs] fatal: ${e.message}
|
|
265
|
-
`),process.exit(0);});});var Ii=new Set(["UserPromptSubmit","PreToolUse","PostToolUse","Stop"]),[,,
|
|
265
|
+
`),process.exit(0);});});var Ii=new Set(["UserPromptSubmit","PreToolUse","PostToolUse","Stop"]),[,,j]=process.argv;function ae(e,t){let r=e.indexOf(t);return r!==-1?e[r+1]:void 0}function ws(){let{bold:e,cyan:t,dim:r,green:n}=(le(),M(qt)),{version:s}=st();process.stdout.write(`
|
|
266
266
|
`+e(" flow-ai-obs")+r(" v"+s)+`
|
|
267
267
|
|
|
268
268
|
`),process.stdout.write(t(" init")+r(` Configure environment: Claude Code + Proxy + OTEL + Trace hooks
|
|
@@ -281,18 +281,18 @@ ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${Z}`},{re:/(aws_secret_ac
|
|
|
281
281
|
|
|
282
282
|
`)),process.stdout.write(r(` (Hook events: UserPromptSubmit | PreToolUse | PostToolUse | Stop)
|
|
283
283
|
|
|
284
|
-
`));}if(
|
|
284
|
+
`));}if(j==="--version"||j==="-v")(async()=>{let{version:e}=st();process.stdout.write(e+`
|
|
285
285
|
`);let t=(We(),M(Be)),r=await t.fetchLatestVersionAsync().catch(()=>null);if(r&&t.isNewer(e,r.version)){let{dim:n,yellow:s}=(le(),M(qt));process.stdout.write(s(`
|
|
286
286
|
Update available: ${e} \u2192 ${r.version}
|
|
287
287
|
`)+n(` Run: flow-ai-obs update
|
|
288
288
|
|
|
289
|
-
`));}process.exit(0);})().catch(()=>process.exit(0));else if(
|
|
290
|
-
`),await(We(),M(Be)).checkForUpdateInteractive();let{runInit:e}=(kn(),M(
|
|
291
|
-
`),process.exit(1);});else if(
|
|
292
|
-
`),process.exit(1);});else if(
|
|
293
|
-
`),process.exit(1);});else if(
|
|
294
|
-
`),process.exit(1);});else if(
|
|
289
|
+
`));}process.exit(0);})().catch(()=>process.exit(0));else if(j==="--help"||j==="-h")ws(),process.exit(0);else if(j==="init"||j==="install")(async()=>{j==="install"&&process.stderr.write(`Warning: "install" is deprecated, use "init" instead
|
|
290
|
+
`),await(We(),M(Be)).checkForUpdateInteractive();let{runInit:e}=(kn(),M(Ln)),t=process.argv.slice(3);process.exit(await e({url:ae(t,"--custom-url"),noInteractive:t.includes("--no-interactive"),email:ae(t,"--custom-email"),clientId:ae(t,"--client-id"),clientSecret:ae(t,"--client-secret"),tenant:ae(t,"--tenant")}));})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
291
|
+
`),process.exit(1);});else if(j==="login")(async()=>{await(We(),M(Be)).checkForUpdateInteractive();let{runLogin:e}=(St(),M(Tt)),t=process.argv.slice(3),r=await e({clientId:ae(t,"--client-id"),clientSecret:ae(t,"--client-secret"),tenant:ae(t,"--tenant")});process.exit(typeof r=="number"?r:r.code);})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
292
|
+
`),process.exit(1);});else if(j==="status")(async()=>{await(We(),M(Be)).checkForUpdateInteractive();let{runStatus:e}=(Cn(),M(Un));process.exit(await e());})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
293
|
+
`),process.exit(1);});else if(j==="update-api-key")(async()=>{let{runUpdateApiKey:e}=($n(),M(Nn)),t=process.argv.slice(3);process.exit(await e({key:ae(t,"--key")}));})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
294
|
+
`),process.exit(1);});else if(j==="update")(async()=>{let e=(We(),M(Be)),{version:t}=st(),r=await e.fetchLatestVersionAsync();r||(process.stderr.write(` \u2717 Could not reach npm registry \u2014 check your connection.
|
|
295
295
|
`),process.exit(1)),e.isNewer(t,r.version)||(process.stdout.write(` \u2713 Already up to date (v${t})
|
|
296
296
|
`),process.exit(0)),await e.runUpdate(r.version),process.exit(0);})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
297
|
-
`),process.exit(1);});else if(
|
|
298
|
-
`),process.exit(1);});}else Ii.has(
|
|
297
|
+
`),process.exit(1);});else if(j==="otel-headers"){let{runOtelHeaders:e}=(Dn(),M(Fn));e().then(t=>process.exit(t)).catch(t=>{process.stderr.write(`[flow-ai-obs otel-headers] Unexpected error: ${t.message}
|
|
298
|
+
`),process.exit(1);});}else Ii.has(j)?(ys(),M(Pi)):(ws(),process.exit(0));
|
package/dist/index.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
'use strict';var h=require('fs'),W=require('path'),rt=require('os'),Me=require('https'),xe=require('http'),child_process=require('child_process'),crypto=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var h__namespace=/*#__PURE__*/_interopNamespace(h);var W__namespace=/*#__PURE__*/_interopNamespace(W);var rt__namespace=/*#__PURE__*/_interopNamespace(rt);var Me__default=/*#__PURE__*/_interopDefault(Me);var xe__default=/*#__PURE__*/_interopDefault(xe);var be=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};function B(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():
|
|
1
|
+
'use strict';var h=require('fs'),W=require('path'),rt=require('os'),Me=require('https'),xe=require('http'),child_process=require('child_process'),crypto=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var h__namespace=/*#__PURE__*/_interopNamespace(h);var W__namespace=/*#__PURE__*/_interopNamespace(W);var rt__namespace=/*#__PURE__*/_interopNamespace(rt);var Me__default=/*#__PURE__*/_interopDefault(Me);var xe__default=/*#__PURE__*/_interopDefault(xe);var be=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};function B(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():Ue}function H(){let t=B();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${t}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${t}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${t}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${t}/otel`}}function Rt(){let t=B();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ue,Wn,pt,ft,dt,yt,g,Q,Bt,R,Y,Ht,L,S=be(()=>{"use strict";Ue="https://flow.ciandt.com";Wn=H(),pt={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},ft="FLOW-nodejs",dt="config.json",yt={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},g={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_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"},Q={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},Bt={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},R={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},Y={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[\x21-\x7E]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},Ht="flow-ai-obs-debug.log",L={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};});S();var kt={credentials:"credentials","token-cache":"tokenCache"};function tt(){let t=rt__namespace.default.homedir();if(process.platform==="darwin")return W__namespace.default.join(t,"Library","Preferences",ft,dt);if(process.platform==="win32"){let n=process.env.APPDATA??W__namespace.default.join(t,"AppData","Roaming");return W__namespace.default.join(n,ft,dt)}let e=process.env.XDG_CONFIG_HOME??W__namespace.default.join(t,".config");return W__namespace.default.join(e,ft,dt)}function Lt(){try{let t=h__namespace.default.readFileSync(tt(),"utf8");return JSON.parse(t)}catch{return {}}}function Yt(t){let e=tt();h__namespace.default.mkdirSync(W__namespace.default.dirname(e),{recursive:true}),h__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var mt=class{static isAvailable(){return true}static hasExistingData(){try{if(!h__namespace.default.existsSync(tt()))return !1;let e=JSON.parse(h__namespace.default.readFileSync(tt(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,n){let r=Lt(),s=kt[n]??n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(e,n,r){let s=Lt(),o=kt[n]??n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;Yt(s);}async deleteSecret(e,n){let r=Lt(),s=kt[n]??n;return s in r?(delete r[s],Yt(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${tt()}`}};async function Wt(){return new mt}S();var Gt=pt.SERVICE;pt.ACCOUNT_CREDS;var jt=pt.ACCOUNT_TOKEN,It=null;function Kt(){return It||(It=Wt()),It}async function wt(t){await(await Kt()).setSecret(Gt,jt,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function Pt(){let e=await(await Kt()).getSecret(Gt,jt);if(!e)return null;try{let n=JSON.parse(e);return {accessToken:n.accessToken,expiresAt:n.expiresAt,lastAuthCheckAt:n.lastAuthCheckAt}}catch{return null}}async function nt(){let t=await Pt();if(!t||!t.accessToken)return null;try{let e=t.accessToken.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email??n.preferred_username??n.upn??n.sub??null}catch{return null}}S();S();var De=W.join(rt.tmpdir(),Ht);function a(...t){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
|
|
2
2
|
`;try{h.writeFileSync(De,e,{flag:"a"});}catch(n){process.stderr.write(`[flow-obs debug ERROR] ${n.message}
|
|
3
|
-
`);}}var
|
|
3
|
+
`);}}var v=class extends Error{statusCode;constructor(e,n=0){super(e),this.name="AuthError",this.statusCode=n;}},Be=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function He(t){if(!Be.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var Vt={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 Ye(t,e){let n=e.length>400?e.slice(0,400)+"\u2026":e;a("toAuthError",`status=${t} body=${n}`);try{let r=JSON.parse(e);if(typeof r.error=="string"&&(a("toAuthError",`api_error_code=${r.error}`+(r.message?` api_message=${r.message}`:"")),Vt[r.error]))return new v(Vt[r.error],t)}catch{}return t===401||t===403||t===500?new v("Invalid credentials",t):t>=400&&t<500?new v("Authentication request was rejected",t):new Error("Authentication service unavailable, please try again later")}function G(t){return new Promise((e,n)=>{try{He(t.tenant);}catch(p){return n(p)}let r=JSON.stringify({clientSecret:t.clientSecret}),s=new URL(H().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(r),FlowTenant:t.tenant}};a("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let l=(o?Me__default.default:xe__default.default).request(i,p=>{let T=[];p.on("data",m=>T.push(m)),p.on("end",()=>{let m=T.join("");if((p.statusCode??0)>=400)return n(Ye(p.statusCode??0,m));let _;try{_=JSON.parse(m);}catch{return n(new Error("Invalid response from auth engine"))}let E=_.expires_at??new Date(Date.now()+(_.expires_in??3600)*1e3).toISOString();if(!_.access_token)return n(new Error("Auth engine returned an empty access token. Check FLOW_BASE_URL and credentials."));e({accessToken:_.access_token,expiresAt:E});});});l.on("error",p=>n(new Error(`Network error: ${p.message}`))),l.setTimeout(Q.REQUEST_TIMEOUT_MS,()=>{l.destroy(new Error("Request timeout"));}),l.write(r),l.end();})}S();S();!process.env.NO_COLOR&&process.stdout.isTTY;function gt(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.USERPROFILE;if(!t){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(t=n);}if(t){let e=t.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return W__namespace.join(e,".claude","settings.json")}return W__namespace.join(rt__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||rt__namespace.homedir();return W__namespace.join(t,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return W__namespace.join(e,".claude","settings.json")}return W__namespace.join(rt__namespace.homedir(),".claude","settings.json")}var Ke=Bt.LOCK_STALE_MS;function Ve(t){try{let e=h__namespace.statSync(t);Date.now()-e.mtimeMs>Ke&&h__namespace.unlinkSync(t);}catch{}try{h__namespace.writeFileSync(t,String(process.pid),{flag:"wx"});}catch(e){throw e.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+t):e}}function Je(t){try{h__namespace.unlinkSync(t);}catch{}}var st;function zt(t){if(st===void 0)try{let n=h__namespace.readFileSync(gt(),"utf8");st=JSON.parse(n).env??null;}catch{st=null;}if(!st)return null;let e=st[t];return typeof e=="string"?e:null}function qt(t){let e=gt(),n=e+".lock";h__namespace.mkdirSync(W__namespace.dirname(e),{recursive:true}),Ve(n);try{let r={};try{r=JSON.parse(h__namespace.readFileSync(e,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,t),h__namespace.writeFileSync(e,JSON.stringify(r,null,2)+`
|
|
4
4
|
`,{encoding:"utf8",mode:384});try{h__namespace.chmodSync(e,384);}catch{}}finally{Je(n);}}S();function Zt(){return !!process.env[g.FLOW_USER_EMAIL]||!!zt(g.FLOW_USER_EMAIL)}function Nt(t){a("maybePersistUserEmail",`${t}: starting`);let e=t==="api-key"?`\u26A0\uFE0F flow-ai-obs: FLOW_USER_EMAIL is not set. Configure it with:
|
|
5
5
|
flow-ai-obs init --custom-email <EMAIL>
|
|
6
6
|
`:`\u26A0\uFE0F flow-ai-obs: FLOW_USER_EMAIL is not set and could not be derived from token.
|
|
7
7
|
Run: flow-ai-obs init
|
|
8
8
|
`;return nt().then(n=>{if(n){let r=n.split(/[\r\n]/)[0].replace(/[\x00-\x1F\x7F]/g,"").trim();if(!r)return;let s=r.indexOf("@"),o=r.slice(s+1);if(!(r.length<=254&&Y.EMAIL_HEADER_PATTERN.test(r)&&(r.match(/@/g)??[]).length===1&&s>0&&s<r.length-1&&o.includes("."))){a("maybePersistUserEmail",`${t}: email from token failed basic validation \u2014 skipping persist`);return}try{qt({[g.FLOW_USER_EMAIL]:r}),a("maybePersistUserEmail",`${t}: persisted FLOW_USER_EMAIL from OAuth token`);}catch(c){a("maybePersistUserEmail",`${t}: FLOW_USER_EMAIL write failed: ${c.message}`),process.stderr.write(`\u26A0\uFE0F flow-ai-obs: could not persist FLOW_USER_EMAIL to settings.json.
|
|
9
9
|
Run: flow-ai-obs init
|
|
10
|
-
`);}}else process.stderr.write(e);}).catch(n=>{a("maybePersistUserEmail",`${t}: getEmailFromToken failed: ${n.message}`);})}var Xe=[/^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 ze(t){return Xe.some(e=>e.test(t))}function qe(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}function _t(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:o}=n;return !r||!s||!o?null:{clientId:r,clientSecret:s,tenant:o}}catch{return null}}function Et(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let n=process.env[g.FLOW_OBS_ALLOW_HTTP]==="true";if(!n&&e.protocol!=="https:")throw new Error(`URL must use HTTPS: ${t}`);if(e.username||e.password)throw new Error(`URL must not contain embedded credentials: ${t}`);if(!n&&ze(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function Qt(){let t=_t(process.env[g.ANTHROPIC_AUTH_TOKEN]);return t?{user:await nt().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function Ze(){let t=process.env[g.FLOW_API_KEY];if(!t)return null;let e=t.replace(/[\r\n]/g,"").trim();return e?e.length>Y.API_KEY_MAX_LENGTH?(a("resolveApiKey",`FLOW_API_KEY exceeds ${Y.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):Y.API_KEY_PATTERN.test(e)?e:(a("resolveApiKey","FLOW_API_KEY contains non-printable or control characters \u2014 rejected"),null):null}function Qe(){return new Date().toISOString().slice(0,10)}async function tn(t){let e=Qe(),n=await Pt();if(n?.lastAuthCheckAt!==e){a("getOrRefreshToken",`daily auth check (last: ${n?.lastAuthCheckAt??"never"})`);let o=Q.MAX_RETRY_ATTEMPTS;for(let i=1;i<=o;i++)try{let c=await G(t);try{await wt({...c,lastAuthCheckAt:e});}catch(p){a("getOrRefreshToken",`saveTokenCache failed (non-fatal): ${p.message}`);}return a("getOrRefreshToken",`daily check passed (attempt ${i}), expires=${c.expiresAt}`),Ze()?Zt()||await Nt("api-key"):await Nt("oauth"),c.accessToken}catch(c){if(c instanceof
|
|
11
|
-
`)[0].slice(0,e).trim()}function ot(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n;}),process.stdin.on("end",()=>{try{t(JSON.parse(e));}catch{t({});}});})}function O(t){process.stdout.write(JSON.stringify(t));}var bt=()=>crypto.randomBytes(16).toString("hex"),C=()=>crypto.randomBytes(8).toString("hex");function P(){return String(BigInt(Date.now())*1000000n)}var fn=/^[0-9a-f-]{1,64}$/i,dn=W.normalize(rt.tmpdir())+W.sep;function mn(t,e){let n=W.resolve(t);if(!n.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return n}function
|
|
10
|
+
`);}}else process.stderr.write(e);}).catch(n=>{a("maybePersistUserEmail",`${t}: getEmailFromToken failed: ${n.message}`);})}var Xe=[/^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 ze(t){return Xe.some(e=>e.test(t))}function qe(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}function _t(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:o}=n;return !r||!s||!o?null:{clientId:r,clientSecret:s,tenant:o}}catch{return null}}function Et(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let n=process.env[g.FLOW_OBS_ALLOW_HTTP]==="true";if(!n&&e.protocol!=="https:")throw new Error(`URL must use HTTPS: ${t}`);if(e.username||e.password)throw new Error(`URL must not contain embedded credentials: ${t}`);if(!n&&ze(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function Qt(){let t=_t(process.env[g.ANTHROPIC_AUTH_TOKEN]);return t?{user:await nt().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function Ze(){let t=process.env[g.FLOW_API_KEY];if(!t)return null;let e=t.replace(/[\r\n]/g,"").trim();return e?e.length>Y.API_KEY_MAX_LENGTH?(a("resolveApiKey",`FLOW_API_KEY exceeds ${Y.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):Y.API_KEY_PATTERN.test(e)?e:(a("resolveApiKey","FLOW_API_KEY contains non-printable or control characters \u2014 rejected"),null):null}function Qe(){return new Date().toISOString().slice(0,10)}async function tn(t){let e=Qe(),n=await Pt();if(n?.lastAuthCheckAt!==e){a("getOrRefreshToken",`daily auth check (last: ${n?.lastAuthCheckAt??"never"})`);let o=Q.MAX_RETRY_ATTEMPTS;for(let i=1;i<=o;i++)try{let c=await G(t);try{await wt({...c,lastAuthCheckAt:e});}catch(p){a("getOrRefreshToken",`saveTokenCache failed (non-fatal): ${p.message}`);}return a("getOrRefreshToken",`daily check passed (attempt ${i}), expires=${c.expiresAt}`),Ze()?Zt()||await Nt("api-key"):await Nt("oauth"),c.accessToken}catch(c){if(c instanceof v){if(c.statusCode!==500)throw a("getOrRefreshToken",`daily check auth error (${c.statusCode}) \u2014 propagating immediately`),c;if(i<o){a("getOrRefreshToken",`daily check 500 error (attempt ${i}/${o}) \u2014 retrying in 1s`),await new Promise(l=>setTimeout(l,Q.RETRY_DELAY_MS));continue}throw a("getOrRefreshToken",`daily check failed after ${o} attempts \u2014 propagating`),c}a("getOrRefreshToken",`daily check network error \u2014 using cache: ${c.message}`);break}}let r=n!=null&&new Date(n.expiresAt)>new Date;if(a("getOrRefreshToken",`cacheValid=${r}`),r)return a("getOrRefreshToken",`using cached token, expires=${n.expiresAt}`),n.accessToken;a("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let s=await G(t);try{await wt({...s,lastAuthCheckAt:e});}catch(o){a("getOrRefreshToken",`token cache save failed (non-fatal): ${o.message}`);}return a("getOrRefreshToken",`token refreshed, expires=${s.expiresAt}`),s.accessToken}function en(t,e){let n=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${n}`}}function nn(t,e,n){let r=Buffer.from(`${e}:${n}`).toString("base64");return {endpoint:t.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${r}`}}async function V(){let t=[],e=_t(process.env[g.ANTHROPIC_AUTH_TOKEN]);a("resolveCredentials",e?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),e&&a("resolveCredentials",`clientId=${e.clientId}`,`tenant=${e.tenant}`);let n=e?e.tenant:"",r=process.env[g.FLOW_TELEMETRY]==="true",s=process.env[g.LANGFUSE_BASE_URL],o=process.env[g.LANGFUSE_PUBLIC_KEY],i=process.env[g.LANGFUSE_SECRET_KEY];if(r&&s&&o&&i){let m="",_=n;e&&(m=await nt().catch(()=>null)??e.clientId);let E={user:m??"",tenant:_??"",team:"",project:""};t.push({mode:"direct",...nn(Et(s),o,i),...E}),a("resolveCredentials","direct mode active",`user=${E.user}`,`tenant=${E.tenant}`);}if(!e){if(t.length===0){let m=[];return m.authError=false,m}return t}let c;try{c=await tn(e);}catch(m){if(a("resolveCredentials",`token refresh failed: ${m.message}`,`(tenant=${e.tenant} clientId=${e.clientId})`),t.length>0)return t.authError=true,t;let _=[];return _.authError=true,_}let p={user:qe(c)??e.clientId,tenant:n,team:"",project:""},T=process.env[g.FLOW_TELEMETRY_GATEWAY]??B();return t.push({mode:"gateway",...en(Et(T),{accessToken:c}),...p}),t}function I(t,e){let n=typeof t=="object"?JSON.stringify(t):String(t??"");return n.length>e?n.slice(0,e)+" \u2026[truncated]":n}function Tt(t,e=100){return String(t??"").split(`
|
|
11
|
+
`)[0].slice(0,e).trim()}function ot(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n;}),process.stdin.on("end",()=>{try{t(JSON.parse(e));}catch{t({});}});})}function O(t){process.stdout.write(JSON.stringify(t));}var bt=()=>crypto.randomBytes(16).toString("hex"),C=()=>crypto.randomBytes(8).toString("hex");function P(){return String(BigInt(Date.now())*1000000n)}var fn=/^[0-9a-f-]{1,64}$/i,dn=W.normalize(rt.tmpdir())+W.sep;function mn(t,e){let n=W.resolve(t);if(!n.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return n}function Ut(t){if(!fn.test(t))throw new Error(`Invalid session ID: ${t}`);return mn(W.join(rt.tmpdir(),`flow-obs-${t}.json`),dn)}function J(t){let e;try{e=Ut(t);}catch{return null}if(!h.existsSync(e))return null;try{return JSON.parse(h.readFileSync(e,"utf8"))}catch{return null}}function X(t,e){h.writeFileSync(Ut(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function vt(t){try{h.unlinkSync(Ut(t));}catch{}}function se(t){if(!t||!h.existsSync(t))return null;try{let e=h.readFileSync(t,"utf8").trimEnd().split(`
|
|
12
12
|
`);for(let n=e.length-1;n>=0;n--)try{let r=JSON.parse(e[n]);if(r.type==="user"&&r.uuid)return r.uuid}catch{}}catch{}return null}function Ct(t){if(!t||!h.existsSync(t))return null;try{let e=h.readFileSync(t,"utf8").trimEnd().split(`
|
|
13
13
|
`),n=[],r=0,s=0,o;for(let i=e.length-1;i>=0;i--)try{let c=JSON.parse(e[i]);if(c.type==="user")break;if(c.type==="assistant"){!o&&c.message?.model&&(o=c.message.model);let p=(c.message?.content??[]).filter(m=>m.type==="text").map(m=>m.text??"").join("");p&&n.unshift(p);let T=c.message?.usage??{};r+=(T.input_tokens??0)+(T.cache_read_input_tokens??0)+(T.cache_creation_input_tokens??0),s+=T.output_tokens??0;}}catch{}return !n.length&&r===0?null:{text:n.join(`
|
|
14
14
|
|
|
15
15
|
`),inputTokens:r,outputTokens:s,model:o}}catch{}return null}var Tn=new Set([".venv","__pycache__",".git","node_modules"]),Sn=new Set([".pyc",".pyo"]),hn=new Set(["SKILL.md",".DS_Store",".gitignore"]);function ae(t){return t.replace(":","/")}function St(t,e){if(!t)return null;let n=ae(t),r=[W.join(rt.homedir(),".claude","skills",n,"SKILL.md"),W.join(e??"",".claude","skills",n,"SKILL.md")];for(let s of r)if(h.existsSync(s))try{return h.readFileSync(s,"utf8")}catch{}return null}function ce(t){return t.split(`
|
|
16
16
|
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var An=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function le(t){return !!t.slashSkill||t.toolCalls.some(r=>r.tool==="Skill")?t.toolCalls.some(r=>r.tool==="Skill"&&!r.synthetic||An.has(r.tool))?"complete":"prerequisite_required":null}function ht(t,e){if(!t)return null;let n=ae(t),r=[W.join(rt.homedir(),".claude","skills",n),W.join(e??"",".claude","skills",n)],s=null;for(let c of r)if(h.existsSync(W.join(c,"SKILL.md"))){s=c;break}if(!s)return null;let o=[];function i(c,l){for(let p of h.readdirSync(c,{withFileTypes:true})){if(Tn.has(p.name)||hn.has(p.name)||Sn.has(W.extname(p.name)))continue;let T=l?`${l}/${p.name}`:p.name;p.isDirectory()?i(W.join(c,p.name),T):o.push(T);}}return i(s,""),o.length>0?o:null}S();S();function Rn(t){try{let e=t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(e,"base64").toString())}catch{return null}}function kn(t,e,n,r){return new Promise(s=>{let o=new URL(t),i=o.protocol==="https:",c=(i?Me__default.default:xe__default.default).request({hostname:o.hostname,port:o.port||(i?443:80),path:o.pathname+o.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(e),Authorization:`Bearer ${String(n).replace(/[\r\n]/g,"")}`,FlowTenant:String(r).replace(/[\r\n]/g,"")}},l=>{l.resume(),s(l.statusCode??0);});c.on("error",()=>s(0)),c.setTimeout(5e3,()=>{c.destroy(),s(0);}),c.write(e),c.end();})}async function F(t,e={}){try{let n=_t(process.env[g.ANTHROPIC_AUTH_TOKEN]);if(!n)return;let r,s=new Promise((m,_)=>{r=setTimeout(()=>_(new Error("getToken timeout")),4e3),r.unref();}),{accessToken:o}=await Promise.race([G(n),s]);clearTimeout(r);let i=Rn(o);if(!i)return;let c=i.tenant||n.tenant,l=JSON.stringify({action:t,booster:Rt().BOOSTER,metadata:e,success:!0,tenant:c,timestamp:new Date().toISOString(),os:process.platform,user:{email:i.email||"",id:i.sub||"",name:i.name||i.email||""}}),p=Et(Rt().API_URL),T=await kn(p,l,o,c);a("metrics.logEvent",`action=${t} status=${T}`);}catch(n){a("metrics.logEvent",`silenced error: ${n.message}`);}}var Ln=`\u26D4 Your Flow API key has expired. You no longer have access to Claude Code through the Flow platform. To restore observability and access, visit ${B()}/settings/api-keys to generate a new API key, then run: flow-ai-obs login`;async function Ft(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:Ln})+`
|
|
17
17
|
`);return}let r=!!(await V()).authError,s=t.session_id||"unknown",o=t.prompt||"",i=t.cwd||"",c=se(t.transcript_path)||bt(),l=ce(o),p=l?St(l,i):null,T=l?ht(l,i):null;X(s,{traceId:bt(),spanId:C(),startNs:P(),sessionId:s,prompt:o,cwd:i,traceName:c,transcriptPath:t.transcript_path||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:l,skillContent:p,skillArtifacts:T}),F("SESSION_STARTED",{traceType:l?"skill":"prompt",slashSkill:l,clientIdExpired:r}),a("UserPromptSubmit",`sid=${s}`,`traceName=${c}`,`slashSkill=${l}`),O(t);}S();async function ue(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},s=J(e);s&&(s.pendingTool={name:n,inputStr:I(r,L.TOOL_INPUT),startNs:P()},X(e,s)),a("PreToolUse",`sid=${e}`,`tool=${n}`,`stateFound=${!!s}`),O(t);}S();var In={name:yt.SCOPE_NAME,version:yt.SCOPE_VERSION},d={TRACE_NAME:"langfuse.trace.name",TRACE_INPUT:"langfuse.trace.input",TRACE_OUTPUT:"langfuse.trace.output",TRACE_METADATA:"langfuse.trace.metadata",TRACE_TAGS:"langfuse.trace.tags",USER_ID:"langfuse.user.id",SESSION_ID:"langfuse.session.id",OBS_NAME:"langfuse.observation.name",OBS_INPUT:"langfuse.observation.input",OBS_OUTPUT:"langfuse.observation.output",OBS_LEVEL:"langfuse.observation.level",OBS_TYPE:"langfuse.observation.type",MODEL:"gen_ai.request.model",INPUT_TOKENS:"gen_ai.usage.input_tokens",OUTPUT_TOKENS:"gen_ai.usage.output_tokens"};function u(t,e){return e==null||e===""?null:{key:t,value:{stringValue:String(e)}}}function $(...t){return t.filter(e=>e!==null)}function pe(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:In,spans:Array.isArray(e)?e:[e]}]}]}}S();var fe=W.join(rt.tmpdir(),"flow-obs-requests.ndjson");function de(t,e,n,r,s){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let o=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(n)},response:{status:r,body:s}});try{h.writeFileSync(fe,o+`
|
|
18
|
-
`,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${fe}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function
|
|
18
|
+
`,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${fe}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function vn(t){let e=new URL(t),n=new URL(H().GATEWAY_HEALTH);return n.hostname=e.hostname,n.port=e.port,n.protocol=e.protocol,n}function me(t,e){return new Promise((n,r)=>{let s=t._isSSL?Me__default.default:xe__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let o=s.request(t,i=>{let c=[];i.on("data",l=>c.push(l)),i.on("end",()=>n({statusCode:i.statusCode??0,body:c.join("")}));});o.setTimeout(1e4,()=>{o.destroy(new Error("Request timeout"));}),o.on("error",i=>r(new Error(`Network error: ${i.message}`))),e&&o.write(e),o.end();})}async function ge(t,e){let n;try{n=vn(t);}catch{return false}let r=n.protocol==="https:";try{let s={};e&&(s.Authorization=String(e).replace(/[\r\n]/g,""));let o=await me({hostname:n.hostname,port:n.port||(r?443:80),path:n.pathname,method:"GET",headers:s,_isSSL:r},null);return a("checkHealth",`url=${n.href} status=${o.statusCode}`),o.statusCode>=200&&o.statusCode<300}catch{return false}}async function At(t,e,n){let r=JSON.stringify(t),s=new URL(e),o=s.protocol==="https:",i=String(n).replace(/[\r\n]/g,""),c={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(r)};a("sendTraces:request",`POST ${e}`),a("sendTraces:request",`headers=${JSON.stringify({...c,Authorization:i.slice(0,20)+"\u2026"})}`),a("sendTraces:request",`body=${r.slice(0,500)}${r.length>500?"\u2026":""}`);try{let l=await me({hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:c,_isSSL:o},r);return a("sendTraces:response",`status=${l.statusCode}`),de(e,c,r,l.statusCode,l.body),l.statusCode}catch(l){return a("sendTraces:error",l.message),de(e,c,r,0,l.message),0}}S();function Cn(){let t=parseInt(process.env[g.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(R.MIN_TTL_DAYS,Math.min(R.MAX_TTL_DAYS,t)):R.DEFAULT_TTL_DAYS)*24*60*60*1e3}function Fn(){let t=parseInt(process.env[g.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(R.MIN_MAX_FILES,Math.min(R.MAX_MAX_FILES,t)):R.DEFAULT_MAX_FILES}function _e(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return W__namespace.default.join(rt__namespace.default.tmpdir(),`${R.FILE_PREFIX}${t}.json`)}function Dt(){let t=rt__namespace.default.tmpdir(),e;try{e=h__namespace.default.readdirSync(t);}catch{return []}return e.filter(n=>n.startsWith(R.FILE_PREFIX)&&n.endsWith(".json")).map(n=>{let r=W__namespace.default.join(t,n),s=0;try{s=h__namespace.default.statSync(r).mtimeMs;}catch{}return {full:r,mtime:s}}).sort((n,r)=>n.mtime-r.mtime).map(n=>n.full)}function it(t){try{let e=Fn(),n=Dt();if(n.length>=e){let o=n.slice(0,n.length-e+1);for(let i of o)try{h__namespace.default.unlinkSync(i);}catch{}}let r=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:r,bufferedAt:Date.now(),payload:t};return h__namespace.default.writeFileSync(_e(r),JSON.stringify(s),{encoding:"utf8",mode:384}),a("buffer",`saved fileId=${r}`),r}catch(e){return a("buffer",`saveToBuffer failed: ${e.message}`),null}}function Te(t){let e=Dt(),n=t!=null&&t>0?t:e.length,r=[];for(let s of e){if(r.length>=n)break;try{let o=h__namespace.default.readFileSync(s,"utf8"),i=JSON.parse(o);i&&i.fileId&&i.payload&&r.push(i);}catch{a("buffer",`skipping malformed file: ${s}`);}}return r}function Se(t){try{h__namespace.default.unlinkSync(_e(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function he(){let t=Date.now()-Cn();for(let e of Dt())try{let{mtimeMs:n}=h__namespace.default.statSync(e);n<t&&(h__namespace.default.unlinkSync(e),a("buffer",`evicted stale: ${W__namespace.default.basename(e)}`));}catch{}}S();async function $n(t){he();let e=Te(R.REPLAY_BATCH_SIZE);e.length&&(a("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async n=>{try{let r=await At(n.payload,t.endpoint,t.authHeader);r>=200&&r<300?(Se(n.fileId),a("replayBufferedTraces",`replayed fileId=${n.fileId} status=${r}`)):a("replayBufferedTraces",`replay failed fileId=${n.fileId} status=${r}`);}catch(r){a("replayBufferedTraces",`replay error fileId=${n.fileId}: ${r.message}`);}})));}async function Ae(t){let e=await V();if(!e.length)return e.authError&&(a("postToLangfuse","auth refresh failed \u2014 buffering trace"),it(t)),0;let n=await Promise.all(e.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await ge(o.endpoint,o.authHeader);return {creds:o,healthy:i}})),r=n.find(o=>o.creds.mode==="gateway"&&o.healthy)?.creds??n.find(o=>o.creds.mode==="direct")?.creds;return r&&await $n(r),(await Promise.all(n.map(async({creds:o,healthy:i})=>{if(o.mode==="gateway"){if(!i)return a("postToLangfuse","gateway health check failed \u2014 buffering trace"),it(t),0;let l=await At(t,o.endpoint,o.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`gateway send failed (status ${l}) \u2014 buffering trace`),it(t)),l}let c=await At(t,o.endpoint,o.authHeader);return (c===0||c>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${c}) \u2014 buffering trace`),it(t)),c}))).find(o=>o!==0)??0}S();var y="[REDACTED]",Dn="[REDACTED-EMAIL]",Mn="[REDACTED-CPF]",xn="[REDACTED-CNPJ]",Oe="[REDACTED-PHONE]",Bn=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${y}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${y}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,n)=>`${e}
|
|
19
19
|
${y}
|
|
20
|
-
${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${y}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${y}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${y}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${y}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(t,e,n)=>`${e}${n}${y}${n}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${y}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>Dn},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>Mn},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>xn},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>Oe},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>Oe}];function b(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return Bn.reduce((n,{re:r,replace:s})=>n.replace(r,s),e)}async function ye(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},s=t.tool_response,o=s!==null&&typeof s=="object"?s.output??JSON.stringify(s):s??"",i=J(e);if(!i){O(t);return}let c=P(),l=i.pendingTool,p=l?.name===n,T=p?l.startNs:String(BigInt(c)-200000000n),m=p?l.inputStr:I(r,L.TOOL_INPUT),_=m,E=null;if(n==="Skill"){let Z=typeof r=="object"&&r!==null?r.skill||r.name||r.skillName||r.commandName||String(Object.values(r)[0]??""):String(r);E=Z?String(Z).trim():null;let x=E?St(E,i.cwd):null;x&&(_=x,i.skillContent||(i.skillContent=x),i.skillArtifacts||(i.skillArtifacts=ht(E,i.cwd))),E&&!i.slashSkill&&(i.slashSkill=E),a("PostToolUse","Skill tool detected",`skillName=${E}`,`contentFound=${!!x}`);}let k=b(I(o,L.TOOL_OUTPUT)),A=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(k.slice(0,500)),at=A?"ERROR":"DEFAULT",q=C(),ct=Math.round(Number(BigInt(c)-BigInt(T))/1e6),ut={Agent:"AGENT",Task:"AGENT"}[n]??"TOOL",M=n==="Skill"&&E?E:Tt(m,60);i.toolCalls.push({tool:n,brief:M,error:A,durationMs:ct});let w=i.spans;w.push({traceId:i.traceId,spanId:q,parentSpanId:i.spanId,name:n,kind:3,startTimeUnixNano:T,endTimeUnixNano:c,attributes:$(u(d.OBS_NAME,n),u(d.OBS_TYPE,ut),u(d.OBS_LEVEL,at),u(d.OBS_INPUT,b(_)),u(d.OBS_OUTPUT,k),u("tool.name",n),u("tool.error",String(A)),n==="Skill"&&E?u("skill.name",E):null,n==="Skill"?u("skill.invocation","slash-command"):null),status:{code:A?2:1}}),i.pendingTool=null,X(e,i),A&&F("TOOL_ERROR",{toolName:n}),a("PostToolUse",`sid=${e}`,`tool=${n}`,`error=${A}`,`durationMs=${ct}`,`totalSpans=${w.length}`),O(t);}var Re={"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}};function ke(t,e,n){let r=Object.keys(Re).find(i=>(t??"").toLowerCase().includes(i));if(!r)return;let s=Re[r],o=(e*s.input+n*s.output)/1e6;return Math.round(o*1e6)/1e6}S();async function Le(t){let e=t.session_id||"unknown",n=t.stop_reason||"end_turn",r=J(e);if(!r){O(t);return}r.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(r.slashSkill)&&(a("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${r.slashSkill}"`),r.slashSkill=null);let s=P(),o=await Qt(),i=r.toolCalls,c=r.spans;if(r.slashSkill&&!i.some(f=>f.tool==="Skill")){let f=C(),
|
|
21
|
-
`)),k=p?.inputTokens??0,A=p?.outputTokens??0,at=i.map((f,
|
|
20
|
+
${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${y}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${y}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${y}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${y}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(t,e,n)=>`${e}${n}${y}${n}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${y}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>Dn},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>Mn},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>xn},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>Oe},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>Oe}];function b(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return Bn.reduce((n,{re:r,replace:s})=>n.replace(r,s),e)}async function ye(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},s=t.tool_response,o=s!==null&&typeof s=="object"?s.output??JSON.stringify(s):s??"",i=J(e);if(!i){O(t);return}let c=P(),l=i.pendingTool,p=l?.name===n,T=p?l.startNs:String(BigInt(c)-200000000n),m=p?l.inputStr:I(r,L.TOOL_INPUT),_=m,E=null;if(n==="Skill"){let Z=typeof r=="object"&&r!==null?r.skill||r.name||r.skillName||r.commandName||String(Object.values(r)[0]??""):String(r);E=Z?String(Z).trim():null;let x=E?St(E,i.cwd):null;x&&(_=x,i.skillContent||(i.skillContent=x),i.skillArtifacts||(i.skillArtifacts=ht(E,i.cwd))),E&&!i.slashSkill&&(i.slashSkill=E),a("PostToolUse","Skill tool detected",`skillName=${E}`,`contentFound=${!!x}`);}let k=b(I(o,L.TOOL_OUTPUT)),A=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(k.slice(0,500)),at=A?"ERROR":"DEFAULT",q=C(),ct=Math.round(Number(BigInt(c)-BigInt(T))/1e6),ut={Agent:"AGENT",Task:"AGENT"}[n]??"TOOL",M=n==="Skill"&&E?E:Tt(m,60);i.toolCalls.push({tool:n,brief:M,error:A,durationMs:ct});let w=i.spans;w.push({traceId:i.traceId,spanId:q,parentSpanId:i.spanId,name:n,kind:3,startTimeUnixNano:T,endTimeUnixNano:c,attributes:$(u(d.OBS_NAME,n),u(d.OBS_TYPE,ut),u(d.OBS_LEVEL,at),u(d.OBS_INPUT,b(_)),u(d.OBS_OUTPUT,k),u("tool.name",n),u("tool.error",String(A)),n==="Skill"&&E?u("skill.name",E):null,n==="Skill"?u("skill.invocation","slash-command"):null),status:{code:A?2:1}}),i.pendingTool=null,X(e,i),A&&F("TOOL_ERROR",{toolName:n}),a("PostToolUse",`sid=${e}`,`tool=${n}`,`error=${A}`,`durationMs=${ct}`,`totalSpans=${w.length}`),O(t);}var Re={"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}};function ke(t,e,n){let r=Object.keys(Re).find(i=>(t??"").toLowerCase().includes(i));if(!r)return;let s=Re[r],o=(e*s.input+n*s.output)/1e6;return Math.round(o*1e6)/1e6}S();async function Le(t){let e=t.session_id||"unknown",n=t.stop_reason||"end_turn",r=J(e);if(!r){O(t);return}r.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(r.slashSkill)&&(a("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${r.slashSkill}"`),r.slashSkill=null);let s=P(),o=await Qt(),i=r.toolCalls,c=r.spans;if(r.slashSkill&&!i.some(f=>f.tool==="Skill")){let f=C(),U=r.skillContent?r.skillContent:JSON.stringify({skill:r.slashSkill});i.push({tool:"Skill",brief:r.slashSkill,error:false,durationMs:0,synthetic:true}),c.push({traceId:r.traceId,spanId:f,parentSpanId:r.spanId,name:"Skill",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:r.startNs,attributes:$(u(d.OBS_NAME,"Skill"),u(d.OBS_TYPE,"TOOL"),u(d.OBS_LEVEL,"DEFAULT"),u(d.OBS_INPUT,U),u(d.OBS_OUTPUT,"loaded via slash command"),u("tool.name","Skill"),u("tool.error","false"),u("skill.name",r.slashSkill),u("skill.invocation","slash-command")),status:{code:1}}),a("Stop",`slashSkill=${r.slashSkill}`,"synthetic span injected");}let l=t.transcript_path||r.transcriptPath||"",p=Ct(l);if(l&&(i.some(f=>f.tool==="Skill"&&!f.synthetic)||!!r.slashSkill)&&!p?.text){await new Promise(U=>setTimeout(U,500));let f=Ct(l);f?.text&&(p=f);}a("Stop",`transcriptPath=${l||"(empty)"}`,`assistantOut=${p?`text=${p.text.length}chars`:"null"}`);let m=i.length,_=i.filter(f=>f.error).length,E=b(p?.text?I(p.text,L.TRACE_OUTPUT):m===0?"No tools used":i.map((f,U)=>`${U+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""}`).join(`
|
|
21
|
+
`)),k=p?.inputTokens??0,A=p?.outputTokens??0,at=i.map((f,U)=>`${U+1}. ${f.tool}${f.brief?` \u2192 ${f.brief}`:""}${f.error?" [ERROR]":""} (${f.durationMs}ms)`),q=!!(r.slashSkill||i.some(f=>f.tool==="Skill")),ct=i.some(f=>f.tool==="Agent");if(!q&&!ct){a("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),F("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),vt(e),O(t);return}let lt=q?"skill":"agent",ut=Math.round(Number(BigInt(s)-BigInt(r.startNs))/1e6),M=p?.model||"",Ot=ke(M,k,A),w=le(r);w==="prerequisite_required"&&p?.text&&(w="complete"),w==="prerequisite_required"&&(c.push({traceId:r.traceId,spanId:C(),parentSpanId:r.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:s,attributes:$(u(d.OBS_NAME,"prerequisite-check"),u(d.OBS_TYPE,"EVENT"),u(d.OBS_LEVEL,"WARNING"),u(d.OBS_OUTPUT,E),u("skill.name",r.slashSkill||void 0),u("execution_status","prerequisite_required")),status:{code:1}}),a("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${r.slashSkill}`));let Z=(()=>{if(!(!q||!r.prompt)){if(r.slashSkill){let f=r.prompt.replace(new RegExp(`^\\/${r.slashSkill}\\s*`,"i"),"").trim();return f?I(b(f),L.USER_INSTRUCTION):void 0}return I(b(r.prompt),L.USER_INSTRUCTION)||void 0}})(),x=JSON.stringify({trace_type:lt,...w!==null&&{execution_status:w},...r.slashSkill?{skill_name:r.slashSkill}:{},...r.skillArtifacts?.length&&{skill_artifacts:r.skillArtifacts},...Z!==void 0&&{user_instruction:Z},latency_ms:ut,...k&&{tokens_input:k},...A&&{tokens_output:A},cost_usd:Ot,...M?{model:M}:{},toolCount:m,errorCount:_,stopReason:n,sessionId:r.sessionId,tools:at.length?at:void 0}),Mt=b(I(r.prompt,L.TRACE_INPUT)),Ie=$(u(d.TRACE_NAME,r.traceName),u(d.TRACE_INPUT,Mt),u(d.TRACE_OUTPUT,E),u(d.OBS_INPUT,Mt),u(d.OBS_OUTPUT,E),u(d.TRACE_METADATA,x),u(d.SESSION_ID,r.sessionId),u(d.USER_ID,o.user),u(d.OBS_TYPE,"GENERATION"),u(d.MODEL,M),k?u(d.INPUT_TOKENS,k):null,A?u(d.OUTPUT_TOKENS,A):null,u("claude.stop_reason",n),u("claude.tool_count",String(m)),u("claude.error_count",String(_)),u("claude.session_id",r.sessionId),u("flow.trace_type",lt),{key:d.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:lt}]}}}),we={traceId:r.traceId,spanId:r.spanId,name:r.traceName,kind:1,startTimeUnixNano:r.startNs,endTimeUnixNano:s,attributes:Ie,status:{code:_>0?2:1}},Pe=$(u("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),u("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),xt=[...c,we];a("Stop",`sid=${e}`,`totalTools=${m}`,`errorTools=${_}`,`spans=${xt.length}`,`inputTokens=${k}`,`outputTokens=${A}`,`traceOutput="${Tt(E,80)}"`);let Ne=await Ae(pe(Pe,xt));a("Stop",`POST status=${Ne}`,`traceId=${r.traceId}`),F("TRACE_SENT",{latencyMs:ut,totalTools:m,errorTools:_,inputTokens:k,outputTokens:A,costUsd:Ot}),vt(e),O(t);}var D=class{static async userPromptSubmit(){let e=await ot(),n;try{n=await V();}catch{O(e);return}n.authError?await Ft(e,true):n.length>0?await Ft(e):O(e);}static async preToolUse(){let e=await ot();await ue(e);}static async postToolUse(){let e=await ot();await ye(e);}static async stop(){let e=await ot();await Le(e);}};async function Hn(){let t=process.argv[2];switch(t){case "UserPromptSubmit":await D.userPromptSubmit();break;case "PreToolUse":await D.preToolUse();break;case "PostToolUse":await D.postToolUse();break;case "Stop":await D.stop();break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
|
|
22
22
|
`),process.stdin.on("data",e=>process.stdout.write(e));}}Hn().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
|
|
23
23
|
`),process.exit(0);});
|
package/dist/setup.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var l=require('path'),a=require('fs'),_=require('os'),child_process=require('child_process'),ut=require('https');require('readline/promises');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var l__namespace=/*#__PURE__*/_interopNamespace(l);var a__namespace=/*#__PURE__*/_interopNamespace(a);var ___namespace=/*#__PURE__*/_interopNamespace(_);var ut__default=/*#__PURE__*/_interopDefault(ut);var
|
|
2
|
+
'use strict';var l=require('path'),a=require('fs'),_=require('os'),child_process=require('child_process'),ut=require('https');require('readline/promises');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var l__namespace=/*#__PURE__*/_interopNamespace(l);var a__namespace=/*#__PURE__*/_interopNamespace(a);var ___namespace=/*#__PURE__*/_interopNamespace(_);var ut__default=/*#__PURE__*/_interopDefault(ut);var M=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var ve=Object.prototype.hasOwnProperty;var Ie=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var Ce=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(n){throw t=0,n}},ke=(e,t)=>{for(var n in t)M(e,n,{get:t[n],enumerable:true});},Ne=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Pe(t))!ve.call(e,s)&&s!==n&&M(e,s,{get:()=>t[s],enumerable:!(r=we(t,s))||r.enumerable});return e};var Ue=e=>Ne(M({},"__esModule",{value:true}),e);var te={};ke(te,{AUTH_ENGINE:()=>V,BUFFER:()=>xe,CLAUDE_DESKTOP:()=>Me,CONFIG_DIR_NAME:()=>P,CONFIG_FILE_NAME:()=>v,COPILOT_OTEL:()=>c,DEBUG_LOG_FILENAME:()=>W,ENV:()=>d,FLOW_URLS:()=>be,HOOK_TIMEOUTS:()=>j,INSTALLER:()=>K,NATIVE_OTEL:()=>Y,OTLP:()=>De,STATE_FILE_PREFIX:()=>Ye,TRACE_LIMITS:()=>$e,VALIDATION:()=>E,VAULT:()=>w,getFlowBaseUrl:()=>D,getFlowUrls:()=>O,getMetrics:()=>He});function D(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Fe}function O(){let e=D();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 He(){let e=D();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Fe,be,w,P,v,De,Y,d,V,K,j,xe,E,W,$e,Me,c,Ye,g=Ie(()=>{"use strict";Fe="https://flow.ciandt.com";be=O(),w={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},P="FLOW-nodejs",v="config.json",De={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},Y={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"},d={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"},V={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},K={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},j={UserPromptSubmit:30,PreToolUse:3,PostToolUse:10,Stop:15},xe={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},E={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[\x21-\x7E]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},W="flow-ai-obs-debug.log",$e={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};Me={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"},c={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"},Ye="flow-obs-";});var Oe=Ce((kn,lt)=>{lt.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.14.0-beta.72",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"}};});g();var G={credentials:"credentials","token-cache":"tokenCache"};function I(){let e=___namespace.default.homedir();if(process.platform==="darwin")return l__namespace.default.join(e,"Library","Preferences",P,v);if(process.platform==="win32"){let n=process.env.APPDATA??l__namespace.default.join(e,"AppData","Roaming");return l__namespace.default.join(n,P,v)}let t=process.env.XDG_CONFIG_HOME??l__namespace.default.join(e,".config");return l__namespace.default.join(t,P,v)}function B(){try{let e=a__namespace.default.readFileSync(I(),"utf8");return JSON.parse(e)}catch{return {}}}function ne(e){let t=I();a__namespace.default.mkdirSync(l__namespace.default.dirname(t),{recursive:true}),a__namespace.default.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var x=class{static isAvailable(){return true}static hasExistingData(){try{if(!a__namespace.default.existsSync(I()))return !1;let t=JSON.parse(a__namespace.default.readFileSync(I(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,n){let r=B(),s=G[n]??n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,n,r){let s=B(),o=G[n]??n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;ne(s);}async deleteSecret(t,n){let r=B(),s=G[n]??n;return s in r?(delete r[s],ne(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${I()}`}};async function re(){return new x}g();var Ke=w.SERVICE,je=w.ACCOUNT_CREDS;w.ACCOUNT_TOKEN;var X=null;function We(){return X||(X=re()),X}async function se(){let t=await(await We()).getSecret(Ke,je);if(!t)return null;try{return JSON.parse(t)}catch{return null}}g();g();g();var Je=l.join(_.tmpdir(),W);function p(...e){if(process.env[d.FLOW_OBS_DEBUG]!=="1")return;let t=`[${new Date().toISOString()}] ${e.join(" ")}
|
|
3
3
|
`;try{a.writeFileSync(Je,t,{flag:"a"});}catch(n){process.stderr.write(`[flow-obs debug ERROR] ${n.message}
|
|
4
|
-
`);}}!process.env.NO_COLOR&&process.stdout.isTTY;function J(){return process.platform==="win32"?false:process.getuid?.()===0}function $(){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:___namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||___namespace.userInfo().username}}function k(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(e=n);}if(e){let t=e.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return l__namespace.join(t,".claude","settings.json")}return l__namespace.join(___namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||___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(___namespace.homedir(),".claude","settings.json")}var oe="flow-ai-obs",ie="config.json";function ce(){if(process.platform==="win32"){let n=process.env.APPDATA||l__namespace.join(___namespace.homedir(),"AppData","Roaming");return l__namespace.join(n,oe,ie)}let e=$(),t=process.env.XDG_CONFIG_HOME||l__namespace.join(e.home,".config");return l__namespace.join(t,oe,ie)}var et=K.LOCK_STALE_MS;function le(e){try{let t=a__namespace.statSync(e);Date.now()-t.mtimeMs>et&&a__namespace.unlinkSync(e);}catch{}try{a__namespace.writeFileSync(e,String(process.pid),{flag:"wx"});}catch(t){throw t.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+e):t}}function ue(e){try{a__namespace.unlinkSync(e);}catch{}}function tt(e,t){let r=(Array.isArray(e)?e:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(i=>!i.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [t,...r]}function pe(e,t){let n=k(),r=n+".lock",s=[];a__namespace.mkdirSync(l__namespace.dirname(n),{recursive:true}),le(r);try{if(a__namespace.existsSync(n)){a__namespace.copyFileSync(n,n+".bkp");try{a__namespace.chmodSync(n+".bkp",384);}catch{}}let o=ce();if(a__namespace.existsSync(o)){let f=o+".bkp";a__namespace.copyFileSync(o,f);try{a__namespace.chmodSync(f,384);}catch{}}let i={};try{i=JSON.parse(a__namespace.readFileSync(n,"utf8"));}catch{}let m=i.env&&typeof i.env=="object"?i.env:{};delete m.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:h}=(g(),Ue(te)),T=h().OTEL_ENDPOINT,F={...
|
|
4
|
+
`);}}!process.env.NO_COLOR&&process.stdout.isTTY;function J(){return process.platform==="win32"?false:process.getuid?.()===0}function $(){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:___namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||___namespace.userInfo().username}}function k(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(e=n);}if(e){let t=e.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return l__namespace.join(t,".claude","settings.json")}return l__namespace.join(___namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||___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(___namespace.homedir(),".claude","settings.json")}var oe="flow-ai-obs",ie="config.json";function ce(){if(process.platform==="win32"){let n=process.env.APPDATA||l__namespace.join(___namespace.homedir(),"AppData","Roaming");return l__namespace.join(n,oe,ie)}let e=$(),t=process.env.XDG_CONFIG_HOME||l__namespace.join(e.home,".config");return l__namespace.join(t,oe,ie)}var et=K.LOCK_STALE_MS;function le(e){try{let t=a__namespace.statSync(e);Date.now()-t.mtimeMs>et&&a__namespace.unlinkSync(e);}catch{}try{a__namespace.writeFileSync(e,String(process.pid),{flag:"wx"});}catch(t){throw t.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+e):t}}function ue(e){try{a__namespace.unlinkSync(e);}catch{}}function tt(e,t){let r=(Array.isArray(e)?e:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(i=>!i.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [t,...r]}function pe(e,t){let n=k(),r=n+".lock",s=[];a__namespace.mkdirSync(l__namespace.dirname(n),{recursive:true}),le(r);try{if(a__namespace.existsSync(n)){a__namespace.copyFileSync(n,n+".bkp");try{a__namespace.chmodSync(n+".bkp",384);}catch{}}let o=ce();if(a__namespace.existsSync(o)){let f=o+".bkp";a__namespace.copyFileSync(o,f);try{a__namespace.chmodSync(f,384);}catch{}}let i={};try{i=JSON.parse(a__namespace.readFileSync(n,"utf8"));}catch{}let m=i.env&&typeof i.env=="object"?i.env:{};delete m.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:h}=(g(),Ue(te)),T=h().OTEL_ENDPOINT,F={...Y,OTEL_EXPORTER_OTLP_ENDPOINT:e??T};i.env={...m,...F,...t??{}},i.otelHeadersHelper="flow-ai-obs otel-headers",(!i.hooks||typeof i.hooks!="object"||Array.isArray(i.hooks))&&(i.hooks={});let H=(f,b)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${f}`,timeout:b}]}),ee=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],L=i.hooks;for(let f of ee){let b=tt(L[f],H(f,j[f]));b.length>1&&s.push(f),L[f]=b;}a__namespace.writeFileSync(n,JSON.stringify(i,null,2)+`
|
|
5
5
|
`,{encoding:"utf8",mode:384});try{a__namespace.chmodSync(n,384);}catch{}}finally{ue(r);}return {settingsPath:n,preserved:s}}var U;function fe(e){if(U===void 0)try{let n=a__namespace.readFileSync(k(),"utf8");U=JSON.parse(n).env??null;}catch{U=null;}if(!U)return null;let t=U[e];return typeof t=="string"?t:null}function Z(e){let t=k(),n=t+".lock";a__namespace.mkdirSync(l__namespace.dirname(t),{recursive:true}),le(n);try{let r={};try{r=JSON.parse(a__namespace.readFileSync(t,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,e),a__namespace.writeFileSync(t,JSON.stringify(r,null,2)+`
|
|
6
6
|
`,{encoding:"utf8",mode:384});try{a__namespace.chmodSync(t,384);}catch{}}finally{ue(n);}}function de(e){let t=process.env[e];return t!==void 0?t!==""?t:void 0:fe(e)??void 0}g();g();g();function Ee(e){if(!e)return null;try{let t=e.split(".");if(t.length<2)return null;let n=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:o}=n;return !r||!s||!o?null:{clientId:r,clientSecret:s,tenant:o}}catch{return null}}function ge(e){let t=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),n=Buffer.from(JSON.stringify({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant})).toString("base64url");return `${t}.${n}.`}function st(e){let t=process.env[d.OTEL_EXPORTER_OTLP_HEADERS];if(!t)return null;let n=e.toLowerCase();for(let r of t.split(",")){let s=r.indexOf("=");if(!(s<=0)&&r.slice(0,s).trim().toLowerCase()===n){let o=r.slice(s+1),i=o.search(/[\r\n]/);return (i===-1?o:o.slice(0,i)).trim()||null}}return null}function me(){let e=de(d.FLOW_USER_EMAIL);if(e!==void 0){let n=e.replace(/[\r\n]/g,"").trim();if(n)if(n.length>E.EMAIL_MAX_LENGTH)p("resolveUserEmail",`FLOW_USER_EMAIL exceeds ${E.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!E.EMAIL_HEADER_PATTERN.test(n))p("resolveUserEmail","FLOW_USER_EMAIL contains non-printable or control characters \u2014 skipping");else return p("resolveUserEmail","using FLOW_USER_EMAIL override: [REDACTED]"),n}let t=st("x-flow-user");if(t){let n=t.replace(/[\r\n]/g,"").trim();if(n.length>E.EMAIL_MAX_LENGTH)p("resolveUserEmail",`x-flow-user from OTEL_EXPORTER_OTLP_HEADERS exceeds ${E.EMAIL_MAX_LENGTH} chars \u2014 skipping`);else if(!E.EMAIL_HEADER_PATTERN.test(n))p("resolveUserEmail","x-flow-user from OTEL_EXPORTER_OTLP_HEADERS is empty or contains non-printable characters \u2014 skipping");else return p("resolveUserEmail","using x-flow-user from OTEL_EXPORTER_OTLP_HEADERS: [REDACTED]"),n}try{let n=___namespace.default.userInfo().username||process.env.USERNAME||process.env.USER||"",r=n.lastIndexOf("\\");if(r!==-1&&(n=n.slice(r+1)),n=n.trim().replace(/[^a-zA-Z0-9._%+\-]/g,"").replace(/^\.+/,""),!n)return p("resolveUserEmail","Could not derive x-flow-user: username is empty. Run: flow-ai-obs init"),null;let s=`${n}@ciandt.com`;return p("resolveUserEmail","derived email: [REDACTED]"),s}catch(n){return p("resolveUserEmail",`Could not derive x-flow-user from OS username: ${n.message}. Run: flow-ai-obs init`),null}}function he(){let e=process.env[d.FLOW_API_KEY];if(!e)return null;let t=e.replace(/[\r\n]/g,"").trim();return t?t.length>E.API_KEY_MAX_LENGTH?(p("resolveApiKey",`FLOW_API_KEY exceeds ${E.API_KEY_MAX_LENGTH} chars \u2014 rejected`),null):E.API_KEY_PATTERN.test(t)?t:(p("resolveApiKey","FLOW_API_KEY contains non-printable or control characters \u2014 rejected"),null):null}function _e(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let n=process.env.APPDATA;if(!n)try{let o=child_process.spawnSync("cmd.exe",["/c","echo","%APPDATA%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();o&&/^[A-Za-z]:\\/.test(o)&&(n=o);}catch(s){p("getVsCodeSettingsPath",`cmd.exe APPDATA lookup failed: ${s.message}`);}if(!n)return null;let r=n.replace(/^([A-Za-z]):/,(s,o)=>`/mnt/${o.toLowerCase()}`).replace(/\\/g,"/");return l__namespace.join(r,"Code","User","settings.json")}if(process.platform==="win32"){let n=process.env.APPDATA||l__namespace.join(___namespace.homedir(),"AppData","Roaming");return l__namespace.join(n,"Code","User","settings.json")}if(process.platform==="darwin")return l__namespace.join(___namespace.homedir(),"Library","Application Support","Code","User","settings.json");let e=process.platform==="linux"&&process.getuid?.()===0?$().home:process.env.HOME||___namespace.homedir(),t=process.env.XDG_CONFIG_HOME||l__namespace.join(e,".config");return l__namespace.join(t,"Code","User","settings.json")}function it(e){let t=false,n=false,r="";for(let s=0;s<e.length;s++){let o=e[s];if(t){r+=o,n?n=false:o==="\\"?n=true:o==='"'&&(t=false);continue}if(o==='"'){t=true,r+=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}r+=o;}return r}function at(e){if(process.env[d.FLOW_OBS_SKIP_COPILOT_DETECTION])return !!(e&&a__namespace.existsSync(e));if(e&&(a__namespace.existsSync(e)||a__namespace.existsSync(l__namespace.dirname(e))||a__namespace.existsSync(l__namespace.dirname(l__namespace.dirname(e)))))return true;let t=_e();if(t&&(a__namespace.existsSync(t)||a__namespace.existsSync(l__namespace.dirname(t))||a__namespace.existsSync(l__namespace.dirname(l__namespace.dirname(t))))||process.platform==="darwin"&&["/Applications/Visual Studio Code.app",l__namespace.join(___namespace.homedir(),"Applications","Visual Studio Code.app")].some(r=>a__namespace.existsSync(r)))return true;if(process.platform==="win32"){let n=process.env.LOCALAPPDATA||l__namespace.join(___namespace.homedir(),"AppData","Local"),r=process.env.PROGRAMFILES||"C:\\Program Files",s=process.env["PROGRAMFILES(X86)"]||"C:\\Program Files (x86)";if([l__namespace.join(n,"Programs","Microsoft VS Code","Code.exe"),l__namespace.join(r,"Microsoft VS Code","Code.exe"),l__namespace.join(s,"Microsoft VS Code","Code.exe")].some(i=>a__namespace.existsSync(i)))return true}return !!(process.platform==="linux"&&["/usr/bin/code","/usr/share/code","/snap/bin/code"].some(r=>a__namespace.existsSync(r)))}function Te(e,t={}){let n;try{n=t.customSettingsPath||_e();}catch(r){return {status:"skipped",reason:`VS Code path resolution failed: ${r.message}`}}if(!n)return {status:"skipped",reason:"VS Code path not found"};if(!at(n))return {status:"skipped",settingsPath:n,reason:"VS Code is not installed"};try{let r={};if(a__namespace.existsSync(n))try{let f=it(a__namespace.readFileSync(n,"utf8"));r=JSON.parse(f);}catch{return {status:"skipped",settingsPath:n,reason:"VS Code settings.json could not be parsed (unsupported JSONC syntax such as comments)"}}let s=e||O().OTEL_ENDPOINT,o=t.apiKey!==void 0?t.apiKey:he(),i=t.userEmail!==void 0?t.userEmail:me(),m=typeof r[c.HEADERS_KEY]=="object"&&r[c.HEADERS_KEY]!==null&&!Array.isArray(r[c.HEADERS_KEY])?r[c.HEADERS_KEY]:{},h={...m};o&&(h[c.HEADER_API_KEY]=o),i&&(h[c.HEADER_USER]=i);let T=Object.keys(h),F=Object.keys(m),H=T.length===0&&(r[c.HEADERS_KEY]===void 0||F.length===0)||T.length===F.length&&T.every(f=>m[f]===h[f]);if(r[c.ENABLED_KEY]===c.ENABLED_VALUE&&r[c.EXPORTER_TYPE_KEY]===c.EXPORTER_TYPE_VALUE&&r[c.PROTOCOL_KEY]===c.PROTOCOL_VALUE&&r[c.ENDPOINT_KEY]===s&&H)return {status:"already_configured",settingsPath:n};a__namespace.mkdirSync(l__namespace.dirname(n),{recursive:!0});let L={...r,[c.ENABLED_KEY]:c.ENABLED_VALUE,[c.EXPORTER_TYPE_KEY]:c.EXPORTER_TYPE_VALUE,[c.PROTOCOL_KEY]:c.PROTOCOL_VALUE,[c.ENDPOINT_KEY]:s};return T.length>0&&(L[c.HEADERS_KEY]=h),a__namespace.writeFileSync(n,JSON.stringify(L,null,2)+`
|
|
7
|
-
`,{encoding:"utf8"}),{status:"configured",settingsPath:n}}catch(r){return {status:"skipped",settingsPath:n,reason:r.message}}}g();var Q;function
|
|
7
|
+
`,{encoding:"utf8"}),{status:"configured",settingsPath:n}}catch(r){return {status:"skipped",settingsPath:n,reason:r.message}}}g();var Q;function Ae(){return Q||(Q=Oe()),Q}var ye=l__namespace.default.join(___namespace.default.tmpdir(),"flow-obs-update-cache.json"),dt=1440*60*1e3,Et=3e3;function gt(e,t){let n=o=>{let i=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return i?[+i[1],+i[2],+i[3]]:null},r=n(e),s=n(t);return !r||!s?false:s[0]!==r[0]?s[0]>r[0]:s[1]!==r[1]?s[1]>r[1]:s[2]>r[2]}function mt(){try{let e=JSON.parse(a__namespace.default.readFileSync(ye,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=dt?null:e}catch{return null}}function ht(e,t,n=Date.now()){try{a__namespace.default.writeFileSync(ye,JSON.stringify({latestVersion:e,updatePriority:t??null,checkedAt:n}),{mode:384});}catch{}}function _t(e){let t=Ae().name,n=ut__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:Et},r=>{if(r.statusCode!==200)return r.resume(),e(new Error(`HTTP ${r.statusCode}`));let s="";r.setEncoding("utf8"),r.on("data",o=>{s+=o;}),r.on("end",()=>{try{let o=JSON.parse(s);if(typeof o.version!="string")throw new Error("no version field");e(null,{version:o.version,updatePriority:typeof o.updatePriority=="string"?o.updatePriority:null});}catch(o){e(o);}});});n.on("error",e),n.on("timeout",()=>{n.destroy(new Error("timeout"));});}function Re(){try{if(mt())return;setImmediate(()=>{_t((e,t)=>{e||!t||gt(Ae().version,t.version)&&ht(t.version,t.updatePriority,0);});});}catch{}}var Tt=l__namespace.default.resolve(__dirname,".."),Ot=process.env.INIT_CWD?l__namespace.default.resolve(process.env.INIT_CWD):null;Ot===Tt&&process.exit(0);J()&&(process.stderr.write(`
|
|
8
8
|
[flow-ai-obs] \u2717 Do not install with sudo.
|
|
9
9
|
Run without sudo: npm install -g @ciandt-flow/flow-ai-obs
|
|
10
10
|
|