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