@ciandt-flow/flow-ai-obs 0.15.0 → 0.15.1-beta.95
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 +160 -151
- package/dist/index.js +1 -1
- package/dist/setup.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,104 +1,111 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var er=require('readline/promises'),Ms=require('https'),_=require('fs'),
|
|
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'),Ms=require('https'),_=require('fs'),Le=require('os'),P=require('path'),child_process=require('child_process'),ro=require('http'),hn=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 Ms__default=/*#__PURE__*/_interopDefault(Ms);var ___namespace=/*#__PURE__*/_interopNamespace(_);var Le__namespace=/*#__PURE__*/_interopNamespace(Le);var P__namespace=/*#__PURE__*/_interopNamespace(P);var ro__default=/*#__PURE__*/_interopDefault(ro);var hn__namespace=/*#__PURE__*/_interopNamespace(hn);var Zt=Object.defineProperty;var bs=Object.getOwnPropertyDescriptor;var Us=Object.getOwnPropertyNames;var Cs=Object.prototype.hasOwnProperty;var Ns=(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 $s=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(r){throw t=0,r}},ae=(e,t)=>{for(var r in t)Zt(e,r,{get:t[r],enumerable:true});},Fs=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Us(t))!Cs.call(e,s)&&s!==r&&Zt(e,s,{get:()=>t[s],enumerable:!(n=bs(t,s))||n.enumerable});return e};var x=e=>Fs(Zt({},"__esModule",{value:true}),e);var Qt={};ae(Qt,{bold:()=>U,cyan:()=>M,dim:()=>m,green:()=>R,red:()=>I,yellow:()=>b});function He(e,t){return Ds?r=>`\x1B[${e}m${r}\x1B[${t}m`:r=>r}var Ds,R,I,b,M,U,m,de=T(()=>{"use strict";Ds=!process.env.NO_COLOR&&process.stdout.isTTY;R=He("32","39"),I=He("31","39"),b=He("33","39"),M=He("36","39"),U=He("1","22"),m=He("2","22");});var at=$s(($i,xs)=>{xs.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.15.1-beta.95",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 fe(){return process.stdout.isTTY===true&&process.stdin.isTTY===true&&!process.argv.includes("--no-interactive")}async function ct(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={};ae(We,{checkForUpdate:()=>js,checkForUpdateInteractive:()=>Vs,fetchLatestVersionAsync:()=>Xr,isNewer:()=>Be,primeUpdateCache:()=>Gs,runUpdate:()=>Jr});function X(){return nr||(nr=at()),nr}function Be(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=X().name,r=Ms__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:Ks},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=X().name,n=` Update available: ${X().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=X().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 Ys(e,t=1e4){let r=Ns("readline"),n=
|
|
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 Ys(e,t=1e4){let r=Ns("readline"),n=X().name,o=` Update available: ${X().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
|
-
`),new Promise(g=>{let u=r.createInterface({input:process.stdin,output:void 0,terminal:false}),E=false;function
|
|
19
|
-
`),g(O));}let w=setTimeout(()=>
|
|
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=X().name;return process.stderr.write(` Installing ${t}@${e}...
|
|
20
20
|
`),new Promise(r=>{let n=child_process.spawn("npm",["install","-g",`${t}@${e}`],{stdio:"inherit",shell:process.platform==="win32"}),s=false;function o(i,a){if(!s){if(s=true,i)process.stderr.write(` \u2713 Updated to ${e}. Please restart the command.
|
|
21
21
|
|
|
22
22
|
`);else {let c=a?` (${a})`:"";process.stderr.write(` \u2717 Update failed${c} \u2014 continuing with current version.
|
|
23
23
|
|
|
24
|
-
`);}r();}}n.on("close",(i,a)=>o(i===0,a??void 0)),n.on("error",i=>o(false,i.code));})}function
|
|
24
|
+
`);}r();}}n.on("close",(i,a)=>o(i===0,a??void 0)),n.on("error",i=>o(false,i.code));})}function Xr(){return new Promise(e=>{cr((t,r)=>e(t||!r?null:r));})}function js(){try{let e=ir();if(e){Be(X().version,e.latestVersion)&&(e.updatePriority==="auto"?or(e.latestVersion):sr(e.latestVersion));return}setImmediate(()=>{cr((t,r)=>{t||!r||(ar(r.version,r.updatePriority),Be(X().version,r.version)&&(r.updatePriority==="auto"?or(r.version):sr(r.version)));});});}catch{}}async function Vs(e={}){try{let t=ir();if(t){if(!Be(X().version,t.latestVersion))return}else {let n=await Xr();if(!n||(ar(n.version,n.updatePriority),!Be(X().version,n.version)))return;t={latestVersion:n.version,updatePriority:n.updatePriority,checkedAt:Date.now()};}if(t.updatePriority==="auto"){or(t.latestVersion);return}if(!fe()){sr(t.latestVersion);return}await Ys(t.latestVersion,e.timeoutMs)&&await Jr(t.latestVersion);}catch{}}function Gs(){try{if(ir())return;setImmediate(()=>{cr((e,t)=>{e||!t||Be(X().version,t.version)&&ar(t.version,t.updatePriority,0);});});}catch{}}var nr,Gr,Ws,Ks,Ke=T(()=>{"use strict";rr();Gr=P__namespace.default.join(Le__namespace.default.tmpdir(),"flow-obs-update-cache.json"),Ws=1440*60*1e3,Ks=3e3;});var qr={};ae(qr,{AUTH_ENGINE:()=>Ye,BUFFER:()=>z,CLAUDE_DESKTOP:()=>N,CONFIG_DIR_NAME:()=>ut,CONFIG_FILE_NAME:()=>pt,COPILOT_OTEL:()=>y,DEBUG_LOG_FILENAME:()=>lr,ENV:()=>d,FLOW_URLS:()=>Xs,HOOK_TIMEOUTS:()=>Ae,INSTALLER:()=>dt,NATIVE_OTEL:()=>me,OTLP:()=>vt,STATE_FILE_PREFIX:()=>qs,TRACE_LIMITS:()=>re,VALIDATION:()=>Y,VAULT:()=>lt,getFlowBaseUrl:()=>Oe,getFlowUrls:()=>q,getMetrics:()=>bt});function Oe(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Js}function q(){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 bt(){let e=Oe();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Js,Xs,lt,ut,pt,vt,me,d,Ye,dt,Ae,z,Y,lr,re,N,y,qs,v=T(()=>{"use strict";Js="https://flow.ciandt.com";Xs=q(),lt={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},ut="FLOW-nodejs",pt="config.json",vt={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},me={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},d={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP",FLOW_OBS_SKIP_DESKTOP_DETECTION:"FLOW_OBS_SKIP_DESKTOP_DETECTION",FLOW_OBS_SKIP_COPILOT_DETECTION:"FLOW_OBS_SKIP_COPILOT_DETECTION",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES",FLOW_USER_EMAIL:"FLOW_USER_EMAIL",FLOW_API_KEY:"FLOW_API_KEY",OTEL_EXPORTER_OTLP_HEADERS:"OTEL_EXPORTER_OTLP_HEADERS",FLOW_BASE_URL:"FLOW_BASE_URL"},Ye={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},dt={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},z={FILE_PREFIX:"flow-obs-buffer-",DEFAULT_TTL_DAYS:4,MIN_TTL_DAYS:1,MAX_TTL_DAYS:30,DEFAULT_MAX_FILES:50,MIN_MAX_FILES:1,MAX_MAX_FILES:500,REPLAY_BATCH_SIZE:10},Y={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[A-Za-z0-9_.\-:=+/]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},lr="flow-ai-obs-debug.log",re={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"},qs="flow-obs-";});function l(...e){if(process.env[d.FLOW_OBS_DEBUG]!=="1")return;let t=`[${new Date().toISOString()}] ${e.join(" ")}
|
|
25
25
|
`;try{_.writeFileSync(eo,t,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
|
|
26
|
-
`);}}var eo,
|
|
27
|
-
`+
|
|
26
|
+
`);}}var eo,D=T(()=>{"use strict";v();eo=P.join(Le.tmpdir(),lr);});function so(e){if(!no.test(e))throw new Error(`Invalid tenant value: "${e}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}function oo(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 Z(e){return new Promise((t,r)=>{try{so(e.tenant);}catch(p){return r(p)}let n=JSON.stringify({clientSecret:e.clientSecret}),s=new URL(q().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?Ms__default.default:ro__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(oo(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(Ye.REQUEST_TIMEOUT_MS,()=>{c.destroy(new Error("Request timeout"));}),c.write(n),c.end();})}var ke,no,zr,Re=T(()=>{"use strict";v();D();ke=class extends Error{statusCode;constructor(t,r=0){super(t),this.name="AuthError",this.statusCode=r;}},no=/^[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 Ut(){if(Zr())return process.stderr.write(`
|
|
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{
|
|
33
|
-
`,{encoding:"utf8",mode:384});try{___namespace.chmodSync(t,384);}catch{}}finally{
|
|
31
|
+
`),1}var Ct=T(()=>{"use strict";de();});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:Le__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||Le__namespace.userInfo().username}}function ce(){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 P__namespace.join(t,".claude","settings.json")}return P__namespace.join(Le__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||Le__namespace.homedir();return P__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 P__namespace.join(t,".claude","settings.json")}return P__namespace.join(Le__namespace.homedir(),".claude","settings.json")}var ft=T(()=>{"use strict";Ct();});function Nt(){if(process.platform==="win32"){let r=process.env.APPDATA||P__namespace.join(Le__namespace.homedir(),"AppData","Roaming");return P__namespace.join(r,Qr,en)}let e=Pe(),t=process.env.XDG_CONFIG_HOME||P__namespace.join(e.home,".config");return P__namespace.join(t,Qr,en)}function pr(){try{let e=___namespace.readFileSync(ce(),"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";ft();Qr="flow-ai-obs",en="config.json";});function nn(e){try{let t=___namespace.statSync(e);Date.now()-t.mtimeMs>io&&___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 ao(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=ce(),n=r+".lock",s=[];___namespace.mkdirSync(P__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=Nt();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={...me,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=ao(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 Q(e){if(gt===void 0)try{let r=___namespace.readFileSync(ce(),"utf8");gt=JSON.parse(r).env??null;}catch{gt=null;}if(!gt)return null;let t=gt[e];return typeof t=="string"?t:null}function Ve(e){let t=ce(),r=t+".lock";___namespace.mkdirSync(P__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 Et(e){let t=process.env[e];return t!==void 0?t!==""?t:void 0:Q(e)??void 0}var io,gt,ge=T(()=>{"use strict";v();Re();ft();dr();io=dt.LOCK_STALE_MS;});function ht(){let e=Le__namespace.default.homedir();if(process.platform==="darwin")return P__namespace.default.join(e,"Library","Preferences",ut,pt);if(process.platform==="win32"){let r=process.env.APPDATA??P__namespace.default.join(e,"AppData","Roaming");return P__namespace.default.join(r,ut,pt)}let t=process.env.XDG_CONFIG_HOME??P__namespace.default.join(e,".config");return P__namespace.default.join(t,ut,pt)}function gr(){try{let e=___namespace.default.readFileSync(ht(),"utf8");return JSON.parse(e)}catch{return {}}}function an(e){let t=ht();___namespace.default.mkdirSync(P__namespace.default.dirname(t),{recursive:true}),___namespace.default.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var mr,$t,cn=T(()=>{"use strict";v();mr={credentials:"credentials","token-cache":"tokenCache"};$t=class{static isAvailable(){return !0}static hasExistingData(){try{if(!___namespace.default.existsSync(ht()))return !1;let t=JSON.parse(___namespace.default.readFileSync(ht(),"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 ${ht()}`}};});async function ln(){return new $t}var un=T(()=>{"use strict";cn();});var dn={};ae(dn,{clearFlowCredentials:()=>uo,getConfigPath:()=>fo,getEmailFromToken:()=>qe,getFlowCredentials:()=>pn,getTokenCache:()=>Tt,hasCredentials:()=>mo,isTokenValid:()=>po,saveFlowCredentials:()=>lo,saveTokenCache:()=>Ee});function Xe(){return Er||(Er=ln()),Er}async function pn(){let t=await(await Xe()).getSecret(Je,hr);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function lo(e){if(!e.clientId||!e.clientSecret||!e.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await Xe()).setSecret(Je,hr,JSON.stringify(e));}async function uo(){let e=await Xe();await e.deleteSecret(Je,hr),await e.deleteSecret(Je,_r);}async function Ee(e){await(await Xe()).setSecret(Je,_r,JSON.stringify({accessToken:e.accessToken,expiresAt:e.expiresAt,lastAuthCheckAt:e.lastAuthCheckAt}));}async function Tt(){let t=await(await Xe()).getSecret(Je,_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 po(){let e=await Tt();return e?new Date(e.expiresAt)>new Date:false}async function qe(){let e=await Tt();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 fo(){return (await Xe()).getStoragePath?.()??"FLOW-nodejs/config.json"}async function mo(){let e=await pn();return !!(e&&e.clientId&&e.clientSecret&&e.tenant)}var Je,hr,_r,Er,ze=T(()=>{"use strict";un();v();Je=lt.SERVICE,hr=lt.ACCOUNT_CREDS,_r=lt.ACCOUNT_TOKEN,Er=null;});function fn(){return !!process.env[d.FLOW_USER_EMAIL]||!!Q(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
37
|
`;return qe().then(r=>{if(r){let n=r.split(/[\r\n]/)[0].replace(/[\x00-\x1F\x7F]/g,"").trim();if(!n)return;let s=n.indexOf("@"),o=n.slice(s+1);if(!(n.length<=254&&Y.EMAIL_HEADER_PATTERN.test(n)&&(n.match(/@/g)??[]).length===1&&s>0&&s<n.length-1&&o.includes("."))){l("maybePersistUserEmail",`${e}: email from token failed basic validation \u2014 skipping persist`);return}try{Ve({[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 fn=T(()=>{"use strict";ze();fe();x();I();});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 ge(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 mn(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 gn(){let e=ge(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=mt(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=ke__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 oe(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 oe(e)}function So(){return new Date().toISOString().slice(0,10)}async function yo(e){let t=So(),r=await ht();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 me({...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()?dn()||await Tr("api-key"):await Tr("oauth"),a.accessToken}catch(a){if(a instanceof Re){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 me({...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 ae(){let e=[],t=ge(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 y={user:u??"",tenant:E??"",team:"",project:""};e.push({mode:"direct",...Oo(Ie(s),o,i),...y}),l("resolveCredentials","direct mode active",`user=${y.user}`,`tenant=${y.tenant}`);}if(!t){if(e.length===0){let u=[];return u.authError=false,u}return e}let a;try{a=await 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:_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();Le();I();x();fn();fe();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 hn(){return !!(process.env.WSL_DISTRO_NAME&&process.platform==="linux")}function $t(){return process.platform==="win32"||hn()}function Ro(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=k__namespace.join(s,N.DIR_3P);return Nt(o)}}if(process.platform==="win32"){let n=process.env.LOCALAPPDATA||k__namespace.join(ke__namespace.homedir(),"AppData","Local"),s=k__namespace.join(n,N.DIR_3P);return Nt(s)}if(process.platform==="darwin"){let n=k__namespace.join(ke__namespace.homedir(),"Library","Application Support",N.DIR_3P);return Nt(n)}let e=Pe(),t=process.env.XDG_CONFIG_HOME||k__namespace.join(e.home,".config"),r=k__namespace.join(t,N.DIR_3P);return Nt(r)}function Nt(e){return {configDir:e,configLibraryDir:k__namespace.join(e,N.CONFIG_LIBRARY_DIR),desktopConfigPath:k__namespace.join(e,N.DESKTOP_CONFIG_FILE),metaPath:k__namespace.join(e,N.CONFIG_LIBRARY_DIR,N.META_FILE)}}function Ft(){let e=se(),t=k__namespace.dirname(e),r=$t()?N.WRAPPER_SCRIPT_WIN:N.WRAPPER_SCRIPT_UNIX;return k__namespace.join(t,r)}function Dt(){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",k__namespace.join(ke__namespace.homedir(),"Applications","Claude.app")].some(r=>___namespace.existsSync(r));if(process.platform==="win32"){let t=process.env.LOCALAPPDATA||k__namespace.join(ke__namespace.homedir(),"AppData","Local"),r=process.env.PROGRAMFILES||"C:\\Program Files";return [k__namespace.join(t,"AnthropicClaude","Claude.exe"),k__namespace.join(r,"Claude","Claude.exe")].some(s=>___namespace.existsSync(s))}if(process.platform==="linux"){let t=Pe(),r=process.env.XDG_CONFIG_HOME||k__namespace.join(t.home,".config"),n=k__namespace.join(r,"Claude");return ___namespace.existsSync(n)}return false}function Lo(e){let t=e??Ft();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 oe(n[1]);let s=r.match(/^set FLOW_API_KEY=([^\r\n]+)$/m);if(s&&s[1])return oe(s[1])}catch{}return null}function Tn(e,t,r=448){let n=k__namespace.dirname(e);___namespace.mkdirSync(n,{recursive:true});let s=$t(),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 ko(e){let t=Ft(),r=e?oe(e):null,n=$t()?yn(r):Sn(r);return Tn(t,n,!!r?448:493),t}function Sn(e){let t=e?oe(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 bo(e,t,r,n){___namespace.mkdirSync(e,{recursive:true});let s=
|
|
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 Uo(e){let t=
|
|
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||
|
|
46
|
-
`,{encoding:"utf8"}),{status:"configured",settingsPath:r}}catch(n){return {status:"skipped",settingsPath:r,reason:n.message}}}var wr=T(()=>{"use strict";
|
|
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 wn(e){let t=e?le(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 On(e){if(!Mt())return {status:"skipped",reason:"Claude Desktop is not installed"};let t=le(e);if(!t)return {status:"skipped",reason:"Invalid API key provided"};try{let r=xt(),n=Dt()?wn(t):Sn(t),{written:s}=yn(r,n,448);return {status:s?"configured":"already_configured",wrapperScriptPath:r}}catch(r){return {status:"skipped",reason:r.message}}}function Io(e){try{let t=___namespace.readFileSync(e,"utf8");try{let r=JSON.parse(t);if(r.appliedId&&typeof r.appliedId=="string"&&Po.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 hn__namespace.randomUUID()}function vo(e,t){let r=P__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 bo(e,t,r,n){___namespace.mkdirSync(e,{recursive:true});let s=P__namespace.resolve(e),o=P__namespace.resolve(e,`${t}.json`);if(!o.startsWith(s+P__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]=_n()?ko(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 Uo(e){let t=P__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 An(e,t){if(!Mt())return {configured:false};let r=Tn(),n=e??q().OTEL_ENDPOINT,s=t!==void 0?t:j()??Ro(xt()),o=Lo(s),i=Io(r.metaPath),a=bo(r.configLibraryDir,i,n,o);return vo(r.metaPath,i),Uo(r.desktopConfigPath),{configured:true,configDir:r.configDir,configLibraryPath:a,uuid:i,wrapperScriptPath:o}}var Po,yr=T(()=>{"use strict";v();ft();H();D();Po=/^[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 P__namespace.join(n,"Code","User","settings.json")}if(process.platform==="win32"){let r=process.env.APPDATA||P__namespace.join(Le__namespace.homedir(),"AppData","Roaming");return P__namespace.join(r,"Code","User","settings.json")}if(process.platform==="darwin")return P__namespace.join(Le__namespace.homedir(),"Library","Application Support","Code","User","settings.json");let e=process.platform==="linux"&&process.getuid?.()===0?Pe().home:process.env.HOME||Le__namespace.homedir(),t=process.env.XDG_CONFIG_HOME||P__namespace.join(e,".config");return P__namespace.join(t,"Code","User","settings.json")}function kn(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 Ht(e){if(process.env[d.FLOW_OBS_SKIP_COPILOT_DETECTION])return !!(e&&___namespace.existsSync(e));if(e&&(___namespace.existsSync(e)||___namespace.existsSync(P__namespace.dirname(e))||___namespace.existsSync(P__namespace.dirname(P__namespace.dirname(e)))))return true;let t=Sr();if(t&&(___namespace.existsSync(t)||___namespace.existsSync(P__namespace.dirname(t))||___namespace.existsSync(P__namespace.dirname(P__namespace.dirname(t))))||process.platform==="darwin"&&["/Applications/Visual Studio Code.app",P__namespace.join(Le__namespace.homedir(),"Applications","Visual Studio Code.app")].some(n=>___namespace.existsSync(n)))return true;if(process.platform==="win32"){let r=process.env.LOCALAPPDATA||P__namespace.join(Le__namespace.homedir(),"AppData","Local"),n=process.env.PROGRAMFILES||"C:\\Program Files",s=process.env["PROGRAMFILES(X86)"]||"C:\\Program Files (x86)";if([P__namespace.join(r,"Programs","Microsoft VS Code","Code.exe"),P__namespace.join(n,"Microsoft VS Code","Code.exe"),P__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 Rn(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(!Ht(r))return {status:"skipped",settingsPath:r,reason:"VS Code is not installed"};try{let n={};if(___namespace.existsSync(r))try{let w=kn(___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||q().OTEL_ENDPOINT,o=t.apiKey!==void 0?t.apiKey:j(),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(P__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(!Ht(r))return {status:"skipped",settingsPath:r,reason:"VS Code is not installed"};try{let n={};if(___namespace.existsSync(r))try{let a=kn(___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(P__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]??q().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();ft();D();});var In={};ae(In,{clearLoggedOutMarker:()=>Ar,isLoggedOut:()=>Fo,markLoggedOut:()=>$o});function Or(){return P__namespace.default.join(Le__namespace.default.homedir(),".claude","flow-obs",".logged-out")}function $o(){try{let e=Or();___namespace.default.mkdirSync(P__namespace.default.dirname(e),{recursive:!0}),___namespace.default.writeFileSync(e,"",{mode:384});}catch{}}function Ar(){try{___namespace.default.unlinkSync(Or());}catch{}}function Fo(){try{return ___namespace.default.existsSync(Or())}catch{return false}}var kr=T(()=>{"use strict";});function Rr(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Q("FLOW_BASE_URL")}function Do(){return Q(d.ANTHROPIC_AUTH_TOKEN)??void 0}async function Wt(){let e=Rr();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=Do(),r=ne(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 Z({clientId:r.clientId,clientSecret:r.clientSecret,tenant:r.tenant});await Ee({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 Lr=T(()=>{"use strict";ze();H();ge();v();Re();});var St={};ae(St,{promptRaw:()=>Pr,runLogin:()=>Ho});function B(e){return typeof e=="string"?e.replace(xo,""):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
|
|
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 Qe(e,t,r=false){let n=Rr(),s=process.env.FLOW_BASE_URL;n&&(process.env.FLOW_BASE_URL=n);try{let{accessToken:o,expiresAt:i}=await Z(e);if(r)return {jwt:t,accessToken:o,expiresAt:i};Ve({[d.ANTHROPIC_AUTH_TOKEN]:t}),Ar(),await Ee({accessToken:o,expiresAt:i});}finally{s===void 0?delete process.env.FLOW_BASE_URL:process.env.FLOW_BASE_URL=s;}}async function Mo(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=ne(t);if(!r)return process.stderr.write(I(` \u2717 Invalid Flow API Token
|
|
49
50
|
`)),1;if(process.stdout.write(m(` Authenticating...
|
|
50
|
-
`)),e){let
|
|
51
|
-
${
|
|
52
|
-
`+m(` Tenant: ${
|
|
51
|
+
`)),e){let n=await Qe(r,t,!0);return process.stdout.write(`
|
|
52
|
+
${R("\u2713")} ${U("Authenticated")}
|
|
53
|
+
`+m(` Tenant: ${B(r.tenant)}
|
|
53
54
|
`)+m(` Storage: pending (will be written at end of init)
|
|
54
55
|
|
|
55
|
-
`)),{code:0,result:
|
|
56
|
-
${
|
|
57
|
-
`+m(` Tenant: ${
|
|
56
|
+
`)),{code:0,result:n}}return await Qe(r,t),process.stdout.write(`
|
|
57
|
+
${R("\u2713")} ${U("Authenticated")}
|
|
58
|
+
`+m(` Tenant: ${B(r.tenant)}
|
|
58
59
|
`)+m(` Storage: ANTHROPIC_AUTH_TOKEN (settings.json)
|
|
59
60
|
|
|
60
61
|
`)),0}catch(t){if(t.message==="SIGINT"||t.message==="NOT_A_TTY")throw t;return process.stderr.write(`
|
|
61
|
-
${
|
|
62
|
-
${
|
|
62
|
+
${I("\u2717")} ${U("Authentication failed:")}
|
|
63
|
+
${B(t.message)}
|
|
63
64
|
|
|
64
|
-
`),1}}async function Ho(e={}){let t=
|
|
65
|
+
`),1}}async function Ho(e={}){let t=Ut();if(t)return t;let{deferPersist:r=false,skipAuthCheck:n=false}=e;if(e.token){let o=e.token.trim(),i=ne(o);if(!i)return process.stderr.write(I(` \u2717 Invalid Flow API Token
|
|
66
|
+
`)),1;try{if(r){let a=await Qe(i,o,!0);return process.stdout.write(R(` \u2713 Authenticated. Tenant: ${B(i.tenant)}
|
|
65
67
|
|
|
66
|
-
`)),{code:0,result:
|
|
68
|
+
`)),{code:0,result:a}}return await Qe(i,o),process.stdout.write(R(` \u2713 Authenticated. Tenant: ${B(i.tenant)}
|
|
67
69
|
|
|
68
|
-
`)),0}catch(
|
|
69
|
-
`)),1}let
|
|
70
|
-
|
|
71
|
-
`)),
|
|
70
|
+
`)),0}catch(a){return process.stderr.write(I(` \u2717 Authentication failed: ${B(a.message)}
|
|
71
|
+
`)),1}}if(e.clientId&&e.clientSecret&&e.tenant){let o={clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant},i=gn(o);try{if(r){let a=await Qe(o,i,!0);return process.stdout.write(R(` \u2713 Authenticated. Tenant: ${B(e.tenant)}
|
|
72
|
+
|
|
73
|
+
`)),{code:0,result:a}}return await Qe(o,i),process.stdout.write(R(` \u2713 Authenticated. Tenant: ${B(e.tenant)}
|
|
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(`
|
|
77
|
+
`),process.stdout.write(U(` Auth
|
|
78
|
+
`)),s.notConfigured)return process.stdout.write(` ${b("\u26A0")} Not configured
|
|
72
79
|
`),process.stdout.write(m(" Run `flow-ai-obs init` to set up the environment first.\n")),process.stdout.write(`
|
|
73
|
-
`),1;if(s.ok){process.stdout.write(` ${
|
|
74
|
-
`),process.stdout.write(m(" URL: ")+
|
|
75
|
-
`),process.stdout.write(m(" Tenant: ")+
|
|
76
|
-
`),process.stdout.write(m(" User: ")+
|
|
80
|
+
`),1;if(s.ok){process.stdout.write(` ${R("\u2713")} Authenticated
|
|
81
|
+
`),process.stdout.write(m(" URL: ")+B(s.baseUrl)+`
|
|
82
|
+
`),process.stdout.write(m(" Tenant: ")+B(s.tenant)+`
|
|
83
|
+
`),process.stdout.write(m(" User: ")+B(s.user)+`
|
|
77
84
|
`),process.stdout.write(`
|
|
78
|
-
`);let o;try{o=await
|
|
79
|
-
`),130;if(i.message==="NOT_A_TTY")return process.stdout.write(
|
|
85
|
+
`);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(R(` \u2713 Using existing credentials.
|
|
80
87
|
|
|
81
|
-
`)),0;throw i}if(o.trim().toLowerCase()!=="y")return process.stdout.write(
|
|
88
|
+
`)),0;throw i}if(o.trim().toLowerCase()!=="y")return process.stdout.write(R(` \u2713 Using existing credentials.
|
|
82
89
|
|
|
83
|
-
`)),0}else s.error==="No credentials found"?(process.stdout.write(` ${
|
|
90
|
+
`)),0}else s.error==="No credentials found"?(process.stdout.write(` ${b("\u26A0")} Not authenticated
|
|
84
91
|
`),process.stdout.write(m(` URL: ${s.baseUrl}
|
|
85
92
|
`)),process.stdout.write(`
|
|
86
|
-
`)):(process.stdout.write(` ${
|
|
87
|
-
`),process.stdout.write(m(" URL: ")+
|
|
88
|
-
`),process.stdout.write(m(" Tenant: ")+
|
|
93
|
+
`)):(process.stdout.write(` ${b("\u26A0")} Session not valid for current endpoint
|
|
94
|
+
`),process.stdout.write(m(" URL: ")+B(s.baseUrl)+`
|
|
95
|
+
`),process.stdout.write(m(" Tenant: ")+B(s.tenant)+`
|
|
89
96
|
`),process.stdout.write(m(" User: ")+m("(not authenticated)")+`
|
|
90
97
|
`),process.stdout.write(`
|
|
91
98
|
`));}try{return await Mo(r)}catch(o){if(o.message==="SIGINT")return process.stdout.write(`
|
|
92
|
-
`),130;if(o.message==="NOT_A_TTY")return process.stderr.write(
|
|
93
|
-
`)+` Pass --
|
|
99
|
+
`),130;if(o.message==="NOT_A_TTY")return process.stderr.write(I(` \u2717 No TTY available for interactive login.
|
|
100
|
+
`)+` Pass --token <JWT> for non-interactive use.
|
|
94
101
|
|
|
95
|
-
`),1;throw o}}var xo,
|
|
102
|
+
`),1;throw o}}var xo,wt=T(()=>{"use strict";ze();kr();Re();H();ge();v();de();Ct();Lr();xo=/[\x00-\x08\x0B-\x1F\x7F]|\x1b\[[0-9;]*[a-zA-Z]/g;});var Cn={};ae(Cn,{normalizeCustomUrl:()=>Un,runInit:()=>Ko,validateCustomUrl:()=>br,validateEmail:()=>vr});function Kt(e,t,r){process.stdout.write(U(M(`
|
|
96
103
|
[${e}/${t}] ${r}
|
|
97
|
-
`)));}function
|
|
98
|
-
`);}function Ue(e){process.stdout.write(` ${
|
|
104
|
+
`)));}function he(e){process.stdout.write(` ${R("\u2713")} ${e}
|
|
105
|
+
`);}function Ue(e){process.stdout.write(` ${b("\u26A0")} ${e}
|
|
99
106
|
`);}function be(e){process.stdout.write(` ${m(e)}
|
|
100
|
-
`);}function
|
|
101
|
-
`,{encoding:"utf8",mode:384});}catch{}return e}function
|
|
107
|
+
`);}function vn(){return !!Q(d.ANTHROPIC_AUTH_TOKEN)}function Bo(){let e=pr();if(!e)return null;Ve({FLOW_BASE_URL:e});try{let t=Nt(),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)+`
|
|
108
|
+
`,{encoding:"utf8",mode:384});}catch{}return e}function Un(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.
|
|
102
109
|
Received: ${e}
|
|
103
110
|
Expected: https://tenant.example.com`);if(i.search)throw new Error(`Custom URL must not contain query parameters.
|
|
104
111
|
Received: ${e}
|
|
@@ -106,29 +113,29 @@
|
|
|
106
113
|
Received: ${e}
|
|
107
114
|
Expected: https://tenant.example.com`);if(i.username||i.password)throw new Error(`Custom URL must not contain embedded credentials.
|
|
108
115
|
Received: ${e}
|
|
109
|
-
Expected: https://tenant.example.com`);if(!i.hostname.includes("."))throw new Error(`Invalid domain: ${i.hostname}. Expected format: tenant.example.com`);let a=`${i.protocol}//${i.host}`,c=process.env[d.FLOW_OBS_ALLOW_HTTP];try{delete process.env[d.FLOW_OBS_ALLOW_HTTP],Ie(a);}finally{c!==void 0&&(process.env[d.FLOW_OBS_ALLOW_HTTP]=c);}return a}let r=
|
|
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=Un(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}
|
|
110
117
|
|
|
111
|
-
`)),e===3)throw process.stderr.write(
|
|
118
|
+
`)),e===3)throw process.stderr.write(I(` Too many invalid attempts.
|
|
112
119
|
|
|
113
|
-
`)),new Error("Too many invalid URL attempts")}throw new Error("Too many invalid URL attempts")}function
|
|
114
|
-
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(
|
|
120
|
+
`)),new Error("Too many invalid URL attempts")}throw new Error("Too many invalid URL attempts")}function bn(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=Q(d.FLOW_USER_EMAIL),s=ve(),o=s??"(could not be derived)";if(!e||!fe()){if(r){let c=bn(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 he(`Email: ${U(c)}`),c}return n??s?he(`Email: ${U(n??s)}`):Ue(`Email not configured \u2014 telemetry will not include user identity.
|
|
121
|
+
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}
|
|
115
122
|
|
|
116
|
-
`)),E}let g=
|
|
123
|
+
`)),E}let g=bn(p),u=vr(g);if(!u)return g;process.stderr.write(b(` \u2717 ${u}
|
|
117
124
|
|
|
118
|
-
`));}throw process.stderr.write(
|
|
125
|
+
`));}throw process.stderr.write(I(` Too many invalid attempts.
|
|
119
126
|
|
|
120
|
-
`)),new Error("Too many invalid email attempts")}async function a(){let c=await i();return process.stdout.write(
|
|
127
|
+
`)),new Error("Too many invalid email attempts")}async function a(){let c=await i();return process.stdout.write(R(` \u2713 Email: ${c}
|
|
121
128
|
|
|
122
|
-
`)),c}return n?await
|
|
129
|
+
`)),c}return n?await ct(` Registered email: ${U(n)} \u2014 still correct?`,true)?(process.stdout.write(R(` \u2713 Email: ${U(n)}
|
|
123
130
|
|
|
124
|
-
`)),null):a():s?t?await
|
|
131
|
+
`)),null):a():s?t?await ct(" Is your corporate email domain @ciandt.com?",true)?(process.stdout.write(R(` \u2713 Email: ${U(o)}
|
|
125
132
|
|
|
126
|
-
`)),s):a():(process.stdout.write(
|
|
133
|
+
`)),s):a():(process.stdout.write(R(` \u2713 Email: ${U(o)}
|
|
127
134
|
|
|
128
|
-
`)),s):(process.stdout.write(
|
|
135
|
+
`)),s):(process.stdout.write(b(`
|
|
129
136
|
\u26A0 Could not derive email from OS username.
|
|
130
|
-
`)),a())}function
|
|
131
|
-
To fix: unset FLOW_API_KEY && flow-ai-obs init`);let s=n?3:4;process.stdout.write(
|
|
137
|
+
`)),a())}function Ot(){let e=Q(d.FLOW_BASE_URL);return e&&e.trim()?e.trim():null}async function Ko(e={}){let t=Ut();if(t)return t;let r=e.url,n=!!j();!n&&process.env[d.FLOW_API_KEY]&&Ue(`FLOW_API_KEY appears to be misconfigured \u2014 authentication with Flow is required.
|
|
138
|
+
To fix: unset FLOW_API_KEY && flow-ai-obs init`);let s=n?3:4;process.stdout.write(U(M(`
|
|
132
139
|
flow-ai-obs init
|
|
133
140
|
`))),process.stdout.write(m(` Configuring your development environment:
|
|
134
141
|
|
|
@@ -137,149 +144,151 @@
|
|
|
137
144
|
`)),n?process.stdout.write(m(` [3/${s}] Observability OpenTelemetry metrics, logs and trace hooks
|
|
138
145
|
`)):(process.stdout.write(m(` [3/${s}] Authentication Authenticate with Flow
|
|
139
146
|
`)),process.stdout.write(m(` [4/${s}] Observability OpenTelemetry metrics, logs and trace hooks
|
|
140
|
-
`))),
|
|
141
|
-
`)+
|
|
142
|
-
`)+
|
|
143
|
-
|
|
144
|
-
`)),Bo(),!r&&!e.noInteractive&&
|
|
145
|
-
Current base URL: ${
|
|
146
|
-
`),await
|
|
147
|
-
`),await
|
|
148
|
-
`);}if(!r&&!e.noInteractive&&!
|
|
147
|
+
`))),Kt(1,s,"Flow Environment Setup");let o=false;{let f=Q(d.FLOW_BASE_URL);if(f&&(Ue(`Base URL already configured (FLOW_BASE_URL=${f})`),!e.noInteractive&&fe()))try{let{promptRaw:C}=await Promise.resolve().then(()=>(wt(),St));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
|
+
`)+b(" on Windows too: ")+M(`npm install -g @ciandt-flow/flow-ai-obs
|
|
149
|
+
`)+b(` Without the Windows install, observability will not work for the Windows-side code assistant.
|
|
150
|
+
|
|
151
|
+
`)),Bo(),!r&&!e.noInteractive&&fe()){let f=Ot();o?r=await Ir():f?(process.stdout.write(`
|
|
152
|
+
Current base URL: ${U(f)}
|
|
153
|
+
`),await ct(" Keep this URL?",true)||(r=await Ir())):(process.stdout.write(`
|
|
154
|
+
`),await ct(" Does your organization use a custom Flow URL?",false)?r=await Ir():he("Using default Flow Base URL: https://flow.ciandt.com")),process.stdout.write(`
|
|
155
|
+
`);}if(!r&&!e.noInteractive&&!fe()){let f=Ot();if(f)process.stdout.write(b(` \u26A0 Non-interactive environment detected.
|
|
149
156
|
`)+m(` Using URL: ${f}
|
|
150
157
|
|
|
151
158
|
`));else return process.stderr.write(` \u2717 No URL configured and no TTY available.
|
|
152
159
|
Run: flow-ai-obs init --custom-url <URL>
|
|
153
160
|
|
|
154
|
-
`),1}let i,a=false;if(r){let f;try{f=
|
|
155
|
-
\u2717 Invalid --custom-url: ${
|
|
161
|
+
`),1}let i,a=false;if(r){let f;try{f=br(r,!0);}catch(se){return process.stderr.write(`
|
|
162
|
+
\u2717 Invalid --custom-url: ${se.message}
|
|
156
163
|
|
|
157
|
-
`),1}let C=
|
|
164
|
+
`),1}let C=Ot();i=f,a=!!C&&C!==f,a?process.stdout.write(b(` \u26A0 Base URL changed \u2014 re-authentication required.
|
|
158
165
|
`)+m(` Previous: ${C}
|
|
159
166
|
`)+m(` New: ${f}
|
|
160
167
|
|
|
161
|
-
`)):process.stdout.write(
|
|
168
|
+
`)):process.stdout.write(R(` \u2713 Base URL configured: ${f}
|
|
162
169
|
|
|
163
|
-
`));}else i=
|
|
170
|
+
`));}else i=Ot()??"https://flow.ciandt.com";let c={FLOW_BASE_URL:i,OTEL_EXPORTER_OTLP_ENDPOINT:`${i}/otel`};process.env.FLOW_BASE_URL=i,process.stdout.write(R(`
|
|
164
171
|
\u2713 Flow environment ready.
|
|
165
172
|
`));let p=36;for(let[f,C]of Object.entries(c))process.stdout.write(m(` ${f.padEnd(p)}`)+C+`
|
|
166
|
-
`);
|
|
167
|
-
${
|
|
173
|
+
`);Kt(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 {Kt(3,s,"Authentication");let f=Ot(),C=!!f&&f!==i;if(!vn()||a||C)if(e.noInteractive||!fe()){let{token:te,clientId:J,clientSecret:K,tenant:oe}=e,ie=!!te,it=!!(J&&K&&oe);if(!ie&&!it&&!!(J||K||oe)){let xe=[!J&&"--client-id",!K&&"--client-secret",!oe&&"--tenant"].filter(Boolean).join(", ");return process.stderr.write(`
|
|
174
|
+
${I("\u2717")} Non-interactive mode requires all credential flags.
|
|
168
175
|
Missing: ${xe}
|
|
169
176
|
|
|
170
|
-
`),1}if(
|
|
171
|
-
${
|
|
172
|
-
${
|
|
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(`
|
|
178
|
+
${I("\u2717")} Authentication failed unexpectedly.
|
|
179
|
+
${It.message}
|
|
173
180
|
|
|
174
181
|
`),1}if(typeof Me=="number")return Me;u=Me.result;}else return process.stderr.write(`
|
|
175
|
-
${
|
|
182
|
+
${I("\u2717")} Authentication required.
|
|
176
183
|
Run: flow-ai-obs login
|
|
177
184
|
|
|
178
|
-
`),1}else {(e.clientId||e.clientSecret||e.tenant)&&process.stderr.write(`
|
|
179
|
-
${
|
|
185
|
+
`),1}else {(e.token||e.clientId||e.clientSecret||e.tenant)&&process.stderr.write(`
|
|
186
|
+
${b("\u26A0")} Credential flags (--token, --client-id, --client-secret, --tenant) are only used with --no-interactive.
|
|
180
187
|
Continuing with interactive authentication.
|
|
181
188
|
|
|
182
189
|
`),process.stdout.write(`
|
|
183
|
-
${
|
|
190
|
+
${b("\u26A0")} Authentication required for the new endpoint.
|
|
184
191
|
|
|
185
|
-
`);let{runLogin:
|
|
186
|
-
${
|
|
187
|
-
`);let De={...
|
|
192
|
+
`);let{runLogin:te}=await Promise.resolve().then(()=>(wt(),St)),J=await te({deferPersist:true,skipAuthCheck:a});if(typeof J=="number")return J;u=J.result;}else he("Already authenticated \u2014 skipping."),be("ANTHROPIC_AUTH_TOKEN will be preserved in settings.json");}let E=vn()?Q(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;Kt(n?3:4,s,"Observability (OpenTelemetry)"),process.stdout.write(`
|
|
193
|
+
${U("Metrics and Logs")}
|
|
194
|
+
`);let De={...me,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+`
|
|
188
195
|
`);process.stdout.write(`
|
|
189
|
-
`),process.stdout.write(` ${
|
|
196
|
+
`),process.stdout.write(` ${U("Trace (Hook)")}
|
|
190
197
|
`);let Se=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"];for(let f of Se){let C=Ae[f];process.stdout.write(m(` ${f.padEnd(18)}`)+`\u2192 flow-ai-obs ${f} (timeout: ${C}s)
|
|
191
198
|
`);}process.stdout.write(`
|
|
192
|
-
`);try{({settingsPath:w,preserved:O}=
|
|
193
|
-
`),1}if(u){let{saveTokenCache:f}=await Promise.resolve().then(()=>(ze(),
|
|
199
|
+
`);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(()=>(ze(),dn));try{await f({accessToken:u.accessToken,expiresAt:u.expiresAt});}catch(se){process.stderr.write(` ${b("\u26A0")} Token cache could not be saved: ${se.message}
|
|
194
201
|
Hooks will authenticate on first use.
|
|
195
|
-
`);}let{clearLoggedOutMarker:C}=await Promise.resolve().then(()=>(
|
|
196
|
-
`),process.stdout.write(
|
|
202
|
+
`);}let{clearLoggedOutMarker:C}=await Promise.resolve().then(()=>(kr(),In));C();}if(he(`Settings written: ${w}`),O.length>0&&(process.stdout.write(`
|
|
203
|
+
`),process.stdout.write(b(` \u26A0 Third-party hooks preserved on: ${O.join(", ")}
|
|
197
204
|
`)),process.stdout.write(m(` flow-ai-obs was prepended \u2014 it executes first.
|
|
198
205
|
`))),process.stdout.write(`
|
|
199
|
-
`),
|
|
200
|
-
`);try{let f=
|
|
206
|
+
`),Mt()){process.stdout.write(` ${U("Claude Desktop")}
|
|
207
|
+
`);try{let f=An(c.OTEL_EXPORTER_OTLP_ENDPOINT,j()??void 0);f.configured&&(he(`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.
|
|
201
208
|
`)));}catch(f){Ue(`Claude Desktop config failed: ${f.message}`),be("CLI observability is configured \u2014 Desktop config can be retried.");}process.stdout.write(`
|
|
202
|
-
`);}if(
|
|
203
|
-
`);try{let f=Rn(c.OTEL_EXPORTER_OTLP_ENDPOINT,{apiKey:j(),userEmail:g??ve()});f.status==="configured"?
|
|
209
|
+
`);}if(Ht()){process.stdout.write(` ${U("GitHub Copilot (VS Code)")}
|
|
210
|
+
`);try{let f=Rn(c.OTEL_EXPORTER_OTLP_ENDPOINT,{apiKey:j(),userEmail:g??ve()});f.status==="configured"?he(`Copilot OTEL configured: ${f.settingsPath}`):f.status==="already_configured"?he("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(`
|
|
204
211
|
`);}return e.skipHint||(process.stdout.write(`
|
|
205
|
-
`),process.stdout.write(
|
|
212
|
+
`),process.stdout.write(R(` \u2713 Setup complete.
|
|
206
213
|
|
|
207
214
|
`)),process.stdout.write(m(` Verify your configuration:
|
|
208
|
-
`)+
|
|
215
|
+
`)+M(` flow-ai-obs status
|
|
209
216
|
|
|
210
217
|
`)+m(` Start your code assistant and begin working.
|
|
211
218
|
|
|
212
|
-
`))),0}var
|
|
213
|
-
`);}function
|
|
214
|
-
`);}function
|
|
215
|
-
`);}function
|
|
216
|
-
`);}function
|
|
217
|
-
`);}function
|
|
218
|
-
`);}function
|
|
219
|
+
`))),0}var Nn=T(()=>{"use strict";ge();v();de();Ct();dr();H();rr();D();yr();wr();});var Mn={};ae(Mn,{runStatus:()=>jo});function $n(e){return !e||e.length<=8?"****":e.slice(0,4)+"****...****"+e.slice(-4)}function Yo(e){process.stdout.write(` ${R("\u2713")} ${e}
|
|
220
|
+
`);}function Ur(e){process.stdout.write(` ${b("\u26A0")} ${e}
|
|
221
|
+
`);}function At(e){process.stdout.write(` ${R("\u2713")} ${e}
|
|
222
|
+
`);}function Yt(e){process.stdout.write(` ${b("\u26A0")} ${e}
|
|
223
|
+
`);}function jt(e){process.stdout.write(` ${I("\u2717")} ${e}
|
|
224
|
+
`);}function tt(e){process.stdout.write(` ${m(e)}
|
|
225
|
+
`);}function Fn(e){process.stdout.write(U(M(`
|
|
219
226
|
${e}
|
|
220
|
-
`)));}function
|
|
227
|
+
`)));}function Dn(e,t=false){let r=t?`${b("\u26A0")} ${U(b(e))}`:U(e);process.stdout.write(`
|
|
221
228
|
${r}
|
|
222
|
-
`);}function
|
|
223
|
-
`);}async function jo(){
|
|
229
|
+
`);}function Cr(){process.stdout.write(`
|
|
230
|
+
`);}async function jo(){Fn("Auth");let e=await Wt();e.notConfigured?(Ur("Not configured."),process.stdout.write(`
|
|
224
231
|
`),process.stdout.write(` ${m("Run `flow-ai-obs init` to set up.")}
|
|
225
|
-
`)):!e.ok&&e.error==="No credentials found"?
|
|
232
|
+
`)):!e.ok&&e.error==="No credentials found"?Ur("Not authenticated. Run `flow-ai-obs login` to set up."):e.ok?(Yo("Authenticated"),process.stdout.write(` ${m("URL: ")}${e.baseUrl}
|
|
226
233
|
`),process.stdout.write(` ${m("Tenant: ")}${e.tenant}
|
|
227
234
|
`),process.stdout.write(` ${m("User: ")}${e.user}
|
|
228
235
|
`),process.stdout.write(` ${m("Storage: ANTHROPIC_AUTH_TOKEN (settings.json)")}
|
|
229
|
-
`)):
|
|
236
|
+
`)):Ur(`Session rejected by ${e.baseUrl}. Run \`flow-ai-obs login\` to re-authenticate.`);let t={},r={};try{let u=___namespace.readFileSync(ce(),"utf8");r=JSON.parse(u),t=r.env||{};}catch{}Fn("Observability configuration (OpenTelemetry)");let n=Object.keys(me).filter(u=>!t[u]);Dn("Metrics and Logs",n.length>0),n.length===0?(At("All OTEL env vars present in settings.json"),tt(`Endpoint: ${t.OTEL_EXPORTER_OTLP_ENDPOINT}`)):(process.stdout.write(`
|
|
230
237
|
`),process.stdout.write(` ${m("Run: flow-ai-obs init (restores missing vars automatically)")}
|
|
231
238
|
`),process.stdout.write(`
|
|
232
|
-
`),
|
|
233
|
-
`);}let s=r.hooks??{},o=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],i=o.every(u=>{let E=s[u];return Array.isArray(E)?E.some(
|
|
239
|
+
`),Yt(`${n.length} OTEL var(s) missing from settings.json`),n.forEach(u=>jt(`Missing: ${u}`))),Cr();for(let u of Object.keys(me)){let E=t[u]??I("(missing)");process.stdout.write(m(` ${u.padEnd(36)}`)+E+`
|
|
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(dt.CLI))}):false});Dn("Tracing",!i),i?At("Hooks registered (trace capture)"):(process.stdout.write(`
|
|
234
241
|
`),process.stdout.write(` ${m("Run `flow-ai-obs init` to configure.")}
|
|
235
242
|
`),process.stdout.write(`
|
|
236
|
-
`),
|
|
237
|
-
`);}
|
|
243
|
+
`),Yt("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)
|
|
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 pe();for(let E of u)E.mode==="direct"&&(At("FLOW_TELEMETRY=true (direct mode enabled)"),At("Mode: direct"),tt(`Endpoint: ${E.endpoint}`),tt(`PK: ${$n(p)}`),tt(`SK: ${$n(g)}`));}else Yt("FLOW_TELEMETRY=true but missing LANGFUSE vars:"),c||jt("LANGFUSE_BASE_URL not set"),p||jt("LANGFUSE_PUBLIC_KEY not set"),g||jt("LANGFUSE_SECRET_KEY not set");else {let u=await pe();if(u.length>0)for(let E of u)E.mode==="gateway"&&(At("Mode: gateway"),tt(`Endpoint: ${E.endpoint}`));else u.authError?Yt("Gateway mode: token refresh failed. Run `flow-ai-obs login`."):tt("No active tracing destination configured.");}return Cr(),0}var Hn=T(()=>{"use strict";H();ge();v();de();Lr();});var Bn={};ae(Bn,{runUpdateApiKey:()=>Vo});async function Vo(e={}){let t=e.key!==void 0?le(e.key):j();if(!t)return e.key!==void 0?process.stderr.write(I(` \u2717 Provided API key is invalid.
|
|
238
245
|
`)+m(` Ensure the key contains valid characters and does not exceed 1024 characters.
|
|
239
246
|
|
|
240
|
-
`)):process.stderr.write(
|
|
247
|
+
`)):process.stderr.write(I(` \u2717 FLOW_API_KEY environment variable is not set or is invalid.
|
|
241
248
|
`)+m(` Set FLOW_API_KEY=<key> in your environment and re-run.
|
|
242
249
|
|
|
243
|
-
`)),1;let r=false,n=Ln(t);n.status==="configured"?process.stdout.write(
|
|
244
|
-
`)):n.status==="already_configured"?process.stdout.write(
|
|
250
|
+
`)),1;let r=false,n=Ln(t);n.status==="configured"?process.stdout.write(R(` \u2713 GitHub Copilot API key updated successfully in ${n.settingsPath}
|
|
251
|
+
`)):n.status==="already_configured"?process.stdout.write(R(` \u2713 GitHub Copilot API key is already up to date in ${n.settingsPath}
|
|
245
252
|
`)):n.reason?.includes("not installed")?process.stdout.write(m(` \u2139 VS Code is not installed \u2014 skipping Copilot API key update.
|
|
246
|
-
`)):(process.stderr.write(
|
|
247
|
-
`)),r=true);let s=
|
|
248
|
-
`)):s.status==="already_configured"?process.stdout.write(
|
|
253
|
+
`)):(process.stderr.write(I(` \u2717 GitHub Copilot API key update failed: ${n.reason}
|
|
254
|
+
`)),r=true);let s=On(t);return s.status==="configured"?process.stdout.write(R(` \u2713 Claude Desktop API key updated successfully in ${s.wrapperScriptPath}
|
|
255
|
+
`)):s.status==="already_configured"?process.stdout.write(R(` \u2713 Claude Desktop API key is already up to date in ${s.wrapperScriptPath}
|
|
249
256
|
`)):s.reason?.includes("not installed")?process.stdout.write(m(` \u2139 Claude Desktop is not installed \u2014 skipping Desktop API key update.
|
|
250
|
-
`)):(process.stderr.write(
|
|
251
|
-
`)),r=true),r?1:0}var
|
|
257
|
+
`)):(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();de();});var Kn={};ae(Kn,{runOtelHeaders:()=>Go});async function Go(){let e=j(),t=ve(),r=ne(Et(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.
|
|
252
259
|
Run: flow-ai-obs init --custom-email <EMAIL>
|
|
253
260
|
`),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.
|
|
254
261
|
`),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)+`
|
|
255
262
|
`),0}if(!r)return process.stderr.write(`[flow-ai-obs otel-headers] Not authenticated \u2014 run: flow-ai-obs login
|
|
256
|
-
`),1;let n=
|
|
263
|
+
`),1;let n=Et(d.FLOW_BASE_URL),s=process.env[d.FLOW_BASE_URL];n&&(process.env[d.FLOW_BASE_URL]=n);let o;try{o=(await Z(r)).accessToken;}catch(i){return process.stderr.write(`[flow-ai-obs otel-headers] Token fetch failed: ${i.message}
|
|
257
264
|
`),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,"")}`})+`
|
|
258
265
|
`),0):(process.stderr.write(`[flow-ai-obs otel-headers] Empty token received
|
|
259
|
-
`),1)}var
|
|
260
|
-
`)[0].slice(0,t).trim()}function
|
|
261
|
-
`);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
|
|
266
|
+
`),1)}var Yn=T(()=>{"use strict";Re();H();ge();v();});function ue(e,t){let r=typeof e=="object"?JSON.stringify(e):String(e??"");return r.length>t?r.slice(0,t)+" \u2026[truncated]":r}function Vt(e,t=100){return String(e??"").split(`
|
|
267
|
+
`)[0].slice(0,t).trim()}function kt(){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 rt=T(()=>{"use strict";});function _e(){return String(BigInt(Date.now())*1000000n)}var Nr,Ce,Rt=T(()=>{"use strict";Nr=()=>hn.randomBytes(16).toString("hex"),Ce=()=>hn.randomBytes(8).toString("hex");});function si(e,t){let r=P.resolve(e);if(!r.startsWith(t))throw new Error(`Path traversal detected: ${e}`);return r}function $r(e){if(!ri.test(e))throw new Error(`Invalid session ID: ${e}`);return si(P.join(Le.tmpdir(),`flow-obs-${e}.json`),ni)}function nt(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 st(e,t){_.writeFileSync($r(e),JSON.stringify(t),{encoding:"utf8",mode:384});}function Fr(e){try{_.unlinkSync($r(e));}catch{}}var ri,ni,Lt=T(()=>{"use strict";ri=/^[0-9a-f-]{1,64}$/i,ni=P.normalize(Le.tmpdir())+P.sep;});function Xn(e){if(!e||!_.existsSync(e))return null;try{let t=_.readFileSync(e,"utf8").trimEnd().split(`
|
|
268
|
+
`);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(`
|
|
262
269
|
`),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(`
|
|
263
270
|
|
|
264
|
-
`),inputTokens:n,outputTokens:s,model:o}}catch{}return null}var
|
|
265
|
-
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function
|
|
266
|
-
`);return}let n=!!(await
|
|
267
|
-
`,{flag:"a",encoding:"utf8",mode:384}),l("sendTraces:dump",`request appendada em ${
|
|
268
|
-
${
|
|
269
|
-
${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${
|
|
270
|
-
`)),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)`),Se=!!(n.slashSkill||i.some(A=>A.tool==="Skill")),f=i.some(A=>A.tool==="Agent");if(!Se&&!f){l("Stop",`sid=${t}`,"skipping trace \u2014 no Skill or Agent calls found"),Ne("TRACE_SKIPPED",{reason:"no_skill_or_agent"})
|
|
271
|
-
`),process.stdin.on("data",t=>process.stdout.write(t));}}var
|
|
272
|
-
`),process.exit(0);});});var Ci=new Set(["UserPromptSubmit","PreToolUse","PostToolUse","Stop"]),[,,V]=process.argv;function
|
|
271
|
+
`),inputTokens:n,outputTokens:s,model:o}}catch{}return null}var xr=T(()=>{"use strict";});function Zn(e){return e.replace(":","/")}function Gt(e,t){if(!e)return null;let r=Zn(e),n=[P.join(Le.homedir(),".claude","skills",r,"SKILL.md"),P.join(t??"",".claude","skills",r,"SKILL.md")];for(let s of n)if(_.existsSync(s))try{return _.readFileSync(s,"utf8")}catch{}return null}function Qn(e){return e.split(`
|
|
272
|
+
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function es(e){return !!e.slashSkill||e.toolCalls.some(n=>n.tool==="Skill")?e.toolCalls.some(n=>n.tool==="Skill"&&!n.synthetic||pi.has(n.tool))?"complete":"prerequisite_required":null}function Jt(e,t){if(!e)return null;let r=Zn(e),n=[P.join(Le.homedir(),".claude","skills",r),P.join(t??"",".claude","skills",r)],s=null;for(let a of n)if(_.existsSync(P.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(ci.has(p.name)||ui.has(p.name)||li.has(P.extname(p.name)))continue;let g=c?`${c}/${p.name}`:p.name;p.isDirectory()?i(P.join(a,p.name),g):o.push(g);}}return i(s,""),o.length>0?o:null}var ci,li,ui,pi,Xt=T(()=>{"use strict";ci=new Set([".venv","__pycache__",".git","node_modules"]),li=new Set([".pyc",".pyo"]),ui=new Set(["SKILL.md",".DS_Store",".gitignore"]);pi=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);});function mi(e){try{let t=e.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(t,"base64").toString())}catch{return null}}function gi(e,t,r,n){return new Promise(s=>{let o=new URL(e),i=o.protocol==="https:",a=(i?Ms__default.default:ro__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=ne(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([Z(r),s]);clearTimeout(n);let i=mi(o);if(!i)return;let a=i.tenant||r.tenant,c=JSON.stringify({action:e,booster:bt().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(bt().API_URL),g=await gi(p,c,o,a);l("metrics.logEvent",`action=${e} status=${g}`);}catch(r){l("metrics.logEvent",`silenced error: ${r.message}`);}}var qt=T(()=>{"use strict";v();Re();H();D();});async function Mr(e,t=false){if(t){process.stdout.write(JSON.stringify({decision:"block",reason:Ei})+`
|
|
273
|
+
`);return}let n=!!(await pe()).authError,s=e.session_id||"unknown",o=e.prompt||"",i=e.cwd||"",a=Xn(e.transcript_path)||Nr(),c=Qn(o),p=c?Gt(c,i):null,g=c?Jt(c,i):null;st(s,{traceId:Nr(),spanId:Ce(),startNs:_e(),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 Ei,ts=T(()=>{"use strict";Rt();Lt();xr();Xt();rt();D();v();H();qt();Ei=`\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 rs(e){let t=e.session_id||"unknown",r=e.tool_name||"unknown",n=e.tool_input||{},s=nt(t);s&&(s.pendingTool={name:r,inputStr:ue(n,re.TOOL_INPUT),startNs:_e()},st(t,s)),l("PreToolUse",`sid=${t}`,`tool=${r}`,`stateFound=${!!s}`),W(e);}var ns=T(()=>{"use strict";Rt();Lt();rt();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 ss(e,t){return {resourceSpans:[{resource:{attributes:e},scopeSpans:[{scope:hi,spans:Array.isArray(t)?t:[t]}]}]}}var hi,k,os=T(()=>{"use strict";v();hi={name:vt.SCOPE_NAME,version:vt.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 as(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(is,o+`
|
|
274
|
+
`,{flag:"a",encoding:"utf8",mode:384}),l("sendTraces:dump",`request appendada em ${is}`);}catch(i){l("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Oi(e){let t=new URL(e),r=new URL(q().GATEWAY_HEALTH);return r.hostname=t.hostname,r.port=t.port,r.protocol=t.protocol,r}function cs(e,t){return new Promise((r,n)=>{let s=e._isSSL?Ms__default.default:ro__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 ls(e,t){let r;try{r=Oi(e);}catch{return false}let n=r.protocol==="https:";try{let s={};t&&(s.Authorization=String(t).replace(/[\r\n]/g,""));let o=await cs({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 zt(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 cs({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}`),as(t,a,n,c.statusCode,c.body),c.statusCode}catch(c){return l("sendTraces:error",c.message),as(t,a,n,0,c.message),0}}var is,us=T(()=>{"use strict";v();D();is=P.join(Le.tmpdir(),"flow-obs-requests.ndjson");});function Ai(){let e=parseInt(process.env[d.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(e)?Math.max(z.MIN_TTL_DAYS,Math.min(z.MAX_TTL_DAYS,e)):z.DEFAULT_TTL_DAYS)*24*60*60*1e3}function ki(){let e=parseInt(process.env[d.BUFFER_MAX_FILES]??"",10);return Number.isFinite(e)?Math.max(z.MIN_MAX_FILES,Math.min(z.MAX_MAX_FILES,e)):z.DEFAULT_MAX_FILES}function ds(e){if(/[/\\]/.test(e))throw new Error(`Invalid buffer fileId: ${e}`);return P__namespace.default.join(Le__namespace.default.tmpdir(),`${z.FILE_PREFIX}${e}.json`)}function Br(){let e=Le__namespace.default.tmpdir(),t;try{t=___namespace.default.readdirSync(e);}catch{return []}return t.filter(r=>r.startsWith(z.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=P__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 Pt(e){try{let t=ki(),r=Br();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(ds(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 fs(e){let t=Br(),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 ms(e){try{___namespace.default.unlinkSync(ds(e)),l("buffer",`deleted fileId=${e}`);}catch{}}function gs(){let e=Date.now()-Ai();for(let t of Br())try{let{mtimeMs:r}=___namespace.default.statSync(t);r<e&&(___namespace.default.unlinkSync(t),l("buffer",`evicted stale: ${P__namespace.default.basename(t)}`));}catch{}}var Es=T(()=>{"use strict";v();D();});async function Ri(e){gs();let t=fs(z.REPLAY_BATCH_SIZE);t.length&&(l("replayBufferedTraces",`replaying ${t.length} buffered trace(s)`),await Promise.allSettled(t.map(async r=>{try{let n=await zt(r.payload,e.endpoint,e.authHeader);n>=200&&n<300?(ms(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 hs(e){let t=await pe();if(!t.length)return t.authError&&(l("postToLangfuse","auth refresh failed \u2014 buffering trace"),Pt(e)),0;let r=await Promise.all(t.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await ls(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 Ri(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"),Pt(e),0;let c=await zt(e,o.endpoint,o.authHeader);return (c===0||c>=500)&&(l("postToLangfuse",`gateway send failed (status ${c}) \u2014 buffering trace`),Pt(e)),c}let a=await zt(e,o.endpoint,o.authHeader);return (a===0||a>=500)&&(l("postToLangfuse",`direct endpoint unavailable (status ${a}) \u2014 buffering trace`),Pt(e)),a}))).find(o=>o!==0)??0}var _s=T(()=>{"use strict";H();D();us();Es();v();});var Wr=T(()=>{"use strict";os();_s();});function ye(e){if(e==null)return "";let t=typeof e=="string"?e:JSON.stringify(e);return vi.reduce((r,{re:n,replace:s})=>r.replace(n,s),t)}var ee,Li,Pi,Ii,Ts,vi,Kr=T(()=>{"use strict";ee="[REDACTED]",Li="[REDACTED-EMAIL]",Pi="[REDACTED-CPF]",Ii="[REDACTED-CNPJ]",Ts="[REDACTED-PHONE]",vi=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${ee}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${ee}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(e,t)=>`${t}${ee}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(e,t)=>`${t}${ee}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(e,t,r)=>`${t}
|
|
275
|
+
${ee}
|
|
276
|
+
${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${ee}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(e,t)=>`${t}${ee}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${ee}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${ee}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${ee}`},{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}${ee}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(e,t)=>`${t}:${ee}@`},{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:()=>Pi},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>Ii},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>Ts},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>Ts}];});async function ys(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=nt(t);if(!i){W(e);return}let a=_e(),c=i.pendingTool,p=c?.name===r,g=p?c.startNs:String(BigInt(a)-200000000n),u=p?c.inputStr:ue(n,re.TOOL_INPUT),E=u,S=null;if(r==="Skill"){let oe=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||n.commandName||String(Object.values(n)[0]??""):String(n);S=oe?String(oe).trim():null;let ie=S?Gt(S,i.cwd):null;ie&&(E=ie,i.skillContent||(i.skillContent=ie),i.skillArtifacts||(i.skillArtifacts=Jt(S,i.cwd))),S&&!i.slashSkill&&(i.slashSkill=S),l("PostToolUse","Skill tool detected",`skillName=${S}`,`contentFound=${!!ie}`);}let w=ye(ue(o,re.TOOL_OUTPUT)),O=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(w.slice(0,500)),De=O?"ERROR":"DEFAULT",Se=Ce(),f=Math.round(Number(BigInt(a)-BigInt(g))/1e6),se={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL",te=r==="Skill"&&S?S:Vt(u,60);i.toolCalls.push({tool:r,brief:te,error:O,durationMs:f});let K=i.spans;K.push({traceId:i.traceId,spanId:Se,parentSpanId:i.spanId,name:r,kind:3,startTimeUnixNano:g,endTimeUnixNano:a,attributes:$e(h(k.OBS_NAME,r),h(k.OBS_TYPE,se),h(k.OBS_LEVEL,De),h(k.OBS_INPUT,ye(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,st(t,i),O&&Ne("TOOL_ERROR",{toolName:r}),l("PostToolUse",`sid=${t}`,`tool=${r}`,`error=${O}`,`durationMs=${f}`,`totalSpans=${K.length}`),W(e);}var Ss=T(()=>{"use strict";Rt();Lt();Wr();rt();Xt();D();v();Kr();qt();});function Os(e,t,r){let n=Object.keys(ws).find(i=>(e??"").toLowerCase().includes(i));if(!n)return;let s=ws[n],o=(t*s.input+r*s.output)/1e6;return Math.round(o*1e6)/1e6}var ws,As=T(()=>{"use strict";ws={"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 ks(e){let t=e.session_id||"unknown",r=e.stop_reason||"end_turn",n=nt(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=_e(),o=await En(),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=ye(p?.text?ue(p.text,re.TRACE_OUTPUT):u===0?"No tools used":i.map((A,we)=>`${we+1}. ${A.tool}${A.brief?` \u2192 ${A.brief}`:""}${A.error?" [ERROR]":""}`).join(`
|
|
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)`),Se=!!(n.slashSkill||i.some(A=>A.tool==="Skill")),f=i.some(A=>A.tool==="Agent");if(!Se&&!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=Se?"skill":"agent",se=Math.round(Number(BigInt(s)-BigInt(n.startNs))/1e6),te=p?.model||"",J=Os(te,w,O),K=es(n);K==="prerequisite_required"&&p?.text&&(K="complete"),K==="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 oe=(()=>{if(!(!Se||!n.prompt)){if(n.slashSkill){let A=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return A?ue(ye(A),re.USER_INSTRUCTION):void 0}return ue(ye(n.prompt),re.USER_INSTRUCTION)||void 0}})(),ie=JSON.stringify({trace_type:C,...K!==null&&{execution_status:K},...n.slashSkill?{skill_name:n.slashSkill}:{},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...oe!==void 0&&{user_instruction:oe},latency_ms:se,...w&&{tokens_input:w},...O&&{tokens_output:O},cost_usd:J,...te?{model:te}:{},toolCount:u,errorCount:E,stopReason:r,sessionId:n.sessionId,tools:De.length?De:void 0}),it=ye(ue(n.prompt,re.TRACE_INPUT)),Yr=$e(h(k.TRACE_NAME,n.traceName),h(k.TRACE_INPUT,it),h(k.TRACE_OUTPUT,S),h(k.OBS_INPUT,it),h(k.OBS_OUTPUT,S),h(k.TRACE_METADATA,ie),h(k.SESSION_ID,n.sessionId),h(k.USER_ID,o.user),h(k.OBS_TYPE,"GENERATION"),h(k.MODEL,te),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:Yr,status:{code:E>0?2:1}},Me=$e(h("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),h("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),It=[...a,xe];l("Stop",`sid=${t}`,`totalTools=${u}`,`errorTools=${E}`,`spans=${It.length}`,`inputTokens=${w}`,`outputTokens=${O}`,`traceOutput="${Vt(S,80)}"`);let vs=await hs(ss(Me,It));l("Stop",`POST status=${vs}`,`traceId=${n.traceId}`),Ne("TRACE_SENT",{latencyMs:se,totalTools:u,errorTools:E,inputTokens:w,outputTokens:O,costUsd:J}),Fr(t),W(e);}var Rs=T(()=>{"use strict";Rt();Lt();Wr();H();As();xr();rt();D();Xt();Kr();v();qt();});var Fe,Ls=T(()=>{"use strict";H();rt();ts();ns();Ss();Rs();Fe=class{static async userPromptSubmit(){let t=await kt(),r;try{r=await pe();}catch{W(t);return}r.authError?await Mr(t,!0):r.length>0?await Mr(t):W(t);}static async preToolUse(){let t=await kt();await rs(t);}static async postToolUse(){let t=await kt();await ys(t);}static async stop(){let t=await kt();await ks(t);}};});var Ui={};async function bi(){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}
|
|
278
|
+
`),process.stdin.on("data",t=>process.stdout.write(t));}}var Ps=T(()=>{"use strict";Ls();bi().catch(e=>{process.stderr.write(`[flow-obs] fatal: ${e.message}
|
|
279
|
+
`),process.exit(0);});});var Ci=new Set(["UserPromptSubmit","PreToolUse","PostToolUse","Stop"]),[,,V]=process.argv;function G(e,t){let r=e.indexOf(t);return r!==-1?e[r+1]:void 0}function Is(){let{bold:e,cyan:t,dim:r,green:n}=(de(),x(Qt)),{version:s}=at();process.stdout.write(`
|
|
273
280
|
`+e(" flow-ai-obs")+r(" v"+s)+`
|
|
274
281
|
|
|
275
282
|
`),process.stdout.write(t(" init")+r(` Configure environment: Claude Code + Proxy + OTEL + Trace hooks
|
|
276
283
|
`)),process.stdout.write(r(` --custom-url <URL> Set a custom Flow base URL
|
|
277
284
|
`)),process.stdout.write(r(` --no-interactive Suppress interactive prompts (CI/CD)
|
|
278
285
|
`)),process.stdout.write(r(` --custom-email <EMAIL> Set user email (used with --no-interactive)
|
|
286
|
+
`)),process.stdout.write(r(` --token <JWT> Flow API Token (non-interactive auth)
|
|
279
287
|
`)),process.stdout.write(r(` --client-id <ID> Flow client ID (non-interactive auth)
|
|
280
288
|
`)),process.stdout.write(r(` --client-secret <S> Flow client secret (non-interactive auth)
|
|
281
289
|
`)),process.stdout.write(r(` --tenant <T> Flow tenant (non-interactive auth)
|
|
282
290
|
`)),process.stdout.write(t(" login")+r(` Refresh authentication token (re-authenticate)
|
|
291
|
+
`)),process.stdout.write(r(` --token <JWT> Flow API Token (non-interactive auth)
|
|
283
292
|
`)),process.stdout.write(t(" status")+r(` Show current observability configuration
|
|
284
293
|
`)),process.stdout.write(n(" update")+r(` Update to the latest version
|
|
285
294
|
|
|
@@ -288,18 +297,18 @@ ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${Q}`},{re:/(aws_secret_ac
|
|
|
288
297
|
|
|
289
298
|
`)),process.stdout.write(r(` (Hook events: UserPromptSubmit | PreToolUse | PostToolUse | Stop)
|
|
290
299
|
|
|
291
|
-
`));}if(V==="--version"||V==="-v")(async()=>{let{version:e}=
|
|
292
|
-
`);let t=(Ke(),
|
|
300
|
+
`));}if(V==="--version"||V==="-v")(async()=>{let{version:e}=at();process.stdout.write(e+`
|
|
301
|
+
`);let t=(Ke(),x(We)),r=await t.fetchLatestVersionAsync().catch(()=>null);if(r&&t.isNewer(e,r.version)){let{dim:n,yellow:s}=(de(),x(Qt));process.stdout.write(s(`
|
|
293
302
|
Update available: ${e} \u2192 ${r.version}
|
|
294
303
|
`)+n(` Run: flow-ai-obs update
|
|
295
304
|
|
|
296
|
-
`));}process.exit(0);})().catch(()=>process.exit(0));else if(V==="--help"||V==="-h")
|
|
297
|
-
`),await(Ke(),
|
|
298
|
-
`),process.exit(1);});else if(V==="login")(async()=>{await(Ke(),
|
|
299
|
-
`),process.exit(1);});else if(V==="status")(async()=>{await(Ke(),
|
|
300
|
-
`),process.exit(1);});else if(V==="update-api-key")(async()=>{let{runUpdateApiKey:e}=(
|
|
301
|
-
`),process.exit(1);});else if(V==="update")(async()=>{let e=(Ke(),
|
|
305
|
+
`));}process.exit(0);})().catch(()=>process.exit(0));else if(V==="--help"||V==="-h")Is(),process.exit(0);else if(V==="init"||V==="install")(async()=>{V==="install"&&process.stderr.write(`Warning: "install" is deprecated, use "init" instead
|
|
306
|
+
`),await(Ke(),x(We)).checkForUpdateInteractive();let{runInit:e}=(Nn(),x(Cn)),t=process.argv.slice(3);process.exit(await e({url:G(t,"--custom-url"),noInteractive:t.includes("--no-interactive"),email:G(t,"--custom-email"),token:G(t,"--token")||G(t,"-t"),clientId:G(t,"--client-id"),clientSecret:G(t,"--client-secret"),tenant:G(t,"--tenant")}));})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
307
|
+
`),process.exit(1);});else if(V==="login")(async()=>{await(Ke(),x(We)).checkForUpdateInteractive();let{runLogin:e}=(wt(),x(St)),t=process.argv.slice(3),r=await e({token:G(t,"--token")||G(t,"-t"),clientId:G(t,"--client-id"),clientSecret:G(t,"--client-secret"),tenant:G(t,"--tenant")});process.exit(typeof r=="number"?r:r.code);})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
308
|
+
`),process.exit(1);});else if(V==="status")(async()=>{await(Ke(),x(We)).checkForUpdateInteractive();let{runStatus:e}=(Hn(),x(Mn));process.exit(await e());})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
309
|
+
`),process.exit(1);});else if(V==="update-api-key")(async()=>{let{runUpdateApiKey:e}=(Wn(),x(Bn)),t=process.argv.slice(3);process.exit(await e({key:G(t,"--key")}));})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
310
|
+
`),process.exit(1);});else if(V==="update")(async()=>{let e=(Ke(),x(We)),{version:t}=at(),r=await e.fetchLatestVersionAsync();r||(process.stderr.write(` \u2717 Could not reach npm registry \u2014 check your connection.
|
|
302
311
|
`),process.exit(1)),e.isNewer(t,r.version)||(process.stdout.write(` \u2713 Already up to date (v${t})
|
|
303
312
|
`),process.exit(0)),await e.runUpdate(r.version),process.exit(0);})().catch(e=>{process.stderr.write(`Unexpected error: ${e.message}
|
|
304
|
-
`),process.exit(1);});else if(V==="otel-headers"){let{runOtelHeaders:e}=(
|
|
305
|
-
`),process.exit(1);});}else Ci.has(V)?(
|
|
313
|
+
`),process.exit(1);});else if(V==="otel-headers"){let{runOtelHeaders:e}=(Yn(),x(Kn));e().then(t=>process.exit(t)).catch(t=>{process.stderr.write(`[flow-ai-obs otel-headers] Unexpected error: ${t.message}
|
|
314
|
+
`),process.exit(1);});}else Ci.has(V)?(Ps(),x(Ui)):(Is(),process.exit(0));
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
`),n=[],r=0,s=0,o;for(let i=e.length-1;i>=0;i--)try{let c=JSON.parse(e[i]);if(c.type==="user")break;if(c.type==="assistant"){!o&&c.message?.model&&(o=c.message.model);let p=(c.message?.content??[]).filter(m=>m.type==="text").map(m=>m.text??"").join("");p&&n.unshift(p);let T=c.message?.usage??{};r+=(T.input_tokens??0)+(T.cache_read_input_tokens??0)+(T.cache_creation_input_tokens??0),s+=T.output_tokens??0;}}catch{}return !n.length&&r===0?null:{text:n.join(`
|
|
14
14
|
|
|
15
15
|
`),inputTokens:r,outputTokens:s,model:o}}catch{}return null}var Sn=new Set([".venv","__pycache__",".git","node_modules"]),hn=new Set([".pyc",".pyo"]),An=new Set(["SKILL.md",".DS_Store",".gitignore"]);function ae(t){return t.replace(":","/")}function St(t,e){if(!t)return null;let n=ae(t),r=[G.join(rt.homedir(),".claude","skills",n,"SKILL.md"),G.join(e??"",".claude","skills",n,"SKILL.md")];for(let s of r)if(h.existsSync(s))try{return h.readFileSync(s,"utf8")}catch{}return null}function ce(t){return t.split(`
|
|
16
|
-
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var On=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function le(t){return !!t.slashSkill||t.toolCalls.some(r=>r.tool==="Skill")?t.toolCalls.some(r=>r.tool==="Skill"&&!r.synthetic||On.has(r.tool))?"complete":"prerequisite_required":null}function ht(t,e){if(!t)return null;let n=ae(t),r=[G.join(rt.homedir(),".claude","skills",n),G.join(e??"",".claude","skills",n)],s=null;for(let c of r)if(h.existsSync(G.join(c,"SKILL.md"))){s=c;break}if(!s)return null;let o=[];function i(c,l){for(let p of h.readdirSync(c,{withFileTypes:true})){if(Sn.has(p.name)||An.has(p.name)||hn.has(G.extname(p.name)))continue;let T=l?`${l}/${p.name}`:p.name;p.isDirectory()?i(G.join(c,p.name),T):o.push(T);}}return i(s,""),o.length>0?o:null}S();S();function kn(t){try{let e=t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(e,"base64").toString())}catch{return null}}function Ln(t,e,n,r){return new Promise(s=>{let o=new URL(t),i=o.protocol==="https:",c=(i?Me__default.default:xe__default.default).request({hostname:o.hostname,port:o.port||(i?443:80),path:o.pathname+o.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(e),Authorization:`Bearer ${String(n).replace(/[\r\n]/g,"")}`,FlowTenant:String(r).replace(/[\r\n]/g,"")}},l=>{l.resume(),s(l.statusCode??0);});c.on("error",()=>s(0)),c.setTimeout(5e3,()=>{c.destroy(),s(0);}),c.write(e),c.end();})}async function F(t,e={}){try{let n=_t(process.env[g.ANTHROPIC_AUTH_TOKEN]);if(!n)return;let r,s=new Promise((m,_)=>{r=setTimeout(()=>_(new Error("getToken timeout")),4e3),r.unref();}),{accessToken:o}=await Promise.race([W(n),s]);clearTimeout(r);let i=kn(o);if(!i)return;let c=i.tenant||n.tenant,l=JSON.stringify({action:t,booster:Rt().BOOSTER,metadata:e,success:!0,tenant:c,timestamp:new Date().toISOString(),os:process.platform,user:{email:i.email||"",id:i.sub||"",name:i.name||i.email||""}}),p=Et(Rt().API_URL),T=await Ln(p,l,o,c);a("metrics.logEvent",`action=${t} status=${T}`);}catch(n){a("metrics.logEvent",`silenced error: ${n.message}`);}}var In=`\u26D4
|
|
16
|
+
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var On=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function le(t){return !!t.slashSkill||t.toolCalls.some(r=>r.tool==="Skill")?t.toolCalls.some(r=>r.tool==="Skill"&&!r.synthetic||On.has(r.tool))?"complete":"prerequisite_required":null}function ht(t,e){if(!t)return null;let n=ae(t),r=[G.join(rt.homedir(),".claude","skills",n),G.join(e??"",".claude","skills",n)],s=null;for(let c of r)if(h.existsSync(G.join(c,"SKILL.md"))){s=c;break}if(!s)return null;let o=[];function i(c,l){for(let p of h.readdirSync(c,{withFileTypes:true})){if(Sn.has(p.name)||An.has(p.name)||hn.has(G.extname(p.name)))continue;let T=l?`${l}/${p.name}`:p.name;p.isDirectory()?i(G.join(c,p.name),T):o.push(T);}}return i(s,""),o.length>0?o:null}S();S();function kn(t){try{let e=t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(e,"base64").toString())}catch{return null}}function Ln(t,e,n,r){return new Promise(s=>{let o=new URL(t),i=o.protocol==="https:",c=(i?Me__default.default:xe__default.default).request({hostname:o.hostname,port:o.port||(i?443:80),path:o.pathname+o.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(e),Authorization:`Bearer ${String(n).replace(/[\r\n]/g,"")}`,FlowTenant:String(r).replace(/[\r\n]/g,"")}},l=>{l.resume(),s(l.statusCode??0);});c.on("error",()=>s(0)),c.setTimeout(5e3,()=>{c.destroy(),s(0);}),c.write(e),c.end();})}async function F(t,e={}){try{let n=_t(process.env[g.ANTHROPIC_AUTH_TOKEN]);if(!n)return;let r,s=new Promise((m,_)=>{r=setTimeout(()=>_(new Error("getToken timeout")),4e3),r.unref();}),{accessToken:o}=await Promise.race([W(n),s]);clearTimeout(r);let i=kn(o);if(!i)return;let c=i.tenant||n.tenant,l=JSON.stringify({action:t,booster:Rt().BOOSTER,metadata:e,success:!0,tenant:c,timestamp:new Date().toISOString(),os:process.platform,user:{email:i.email||"",id:i.sub||"",name:i.name||i.email||""}}),p=Et(Rt().API_URL),T=await Ln(p,l,o,c);a("metrics.logEvent",`action=${t} status=${T}`);}catch(n){a("metrics.logEvent",`silenced error: ${n.message}`);}}var In=`\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 ${B()}/settings/api-keys and run: flow-ai-obs login. If it still persists, contact Flow support through the official channels.`;async function Ft(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:In})+`
|
|
17
17
|
`);return}let r=!!(await V()).authError,s=t.session_id||"unknown",o=t.prompt||"",i=t.cwd||"",c=se(t.transcript_path)||bt(),l=ce(o),p=l?St(l,i):null,T=l?ht(l,i):null;X(s,{traceId:bt(),spanId:C(),startNs:P(),sessionId:s,prompt:o,cwd:i,traceName:c,transcriptPath:t.transcript_path||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:l,skillContent:p,skillArtifacts:T}),F("SESSION_STARTED",{traceType:l?"skill":"prompt",slashSkill:l,clientIdExpired:r}),a("UserPromptSubmit",`sid=${s}`,`traceName=${c}`,`slashSkill=${l}`),O(t);}S();async function ue(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},s=J(e);s&&(s.pendingTool={name:n,inputStr:I(r,L.TOOL_INPUT),startNs:P()},X(e,s)),a("PreToolUse",`sid=${e}`,`tool=${n}`,`stateFound=${!!s}`),O(t);}S();var wn={name:yt.SCOPE_NAME,version:yt.SCOPE_VERSION},d={TRACE_NAME:"langfuse.trace.name",TRACE_INPUT:"langfuse.trace.input",TRACE_OUTPUT:"langfuse.trace.output",TRACE_METADATA:"langfuse.trace.metadata",TRACE_TAGS:"langfuse.trace.tags",USER_ID:"langfuse.user.id",SESSION_ID:"langfuse.session.id",OBS_NAME:"langfuse.observation.name",OBS_INPUT:"langfuse.observation.input",OBS_OUTPUT:"langfuse.observation.output",OBS_LEVEL:"langfuse.observation.level",OBS_TYPE:"langfuse.observation.type",MODEL:"gen_ai.request.model",INPUT_TOKENS:"gen_ai.usage.input_tokens",OUTPUT_TOKENS:"gen_ai.usage.output_tokens"};function u(t,e){return e==null||e===""?null:{key:t,value:{stringValue:String(e)}}}function $(...t){return t.filter(e=>e!==null)}function pe(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:wn,spans:Array.isArray(e)?e:[e]}]}]}}S();var fe=G.join(rt.tmpdir(),"flow-obs-requests.ndjson");function de(t,e,n,r,s){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let o=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(n)},response:{status:r,body:s}});try{h.writeFileSync(fe,o+`
|
|
18
18
|
`,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${fe}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Cn(t){let e=new URL(t),n=new URL(H().GATEWAY_HEALTH);return n.hostname=e.hostname,n.port=e.port,n.protocol=e.protocol,n}function me(t,e){return new Promise((n,r)=>{let s=t._isSSL?Me__default.default:xe__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let o=s.request(t,i=>{let c=[];i.on("data",l=>c.push(l)),i.on("end",()=>n({statusCode:i.statusCode??0,body:c.join("")}));});o.setTimeout(1e4,()=>{o.destroy(new Error("Request timeout"));}),o.on("error",i=>r(new Error(`Network error: ${i.message}`))),e&&o.write(e),o.end();})}async function ge(t,e){let n;try{n=Cn(t);}catch{return false}let r=n.protocol==="https:";try{let s={};e&&(s.Authorization=String(e).replace(/[\r\n]/g,""));let o=await me({hostname:n.hostname,port:n.port||(r?443:80),path:n.pathname,method:"GET",headers:s,_isSSL:r},null);return a("checkHealth",`url=${n.href} status=${o.statusCode}`),o.statusCode>=200&&o.statusCode<300}catch{return false}}async function At(t,e,n){let r=JSON.stringify(t),s=new URL(e),o=s.protocol==="https:",i=String(n).replace(/[\r\n]/g,""),c={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(r)};a("sendTraces:request",`POST ${e}`),a("sendTraces:request",`headers=${JSON.stringify({...c,Authorization:i.slice(0,20)+"\u2026"})}`),a("sendTraces:request",`body=${r.slice(0,500)}${r.length>500?"\u2026":""}`);try{let l=await me({hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:c,_isSSL:o},r);return a("sendTraces:response",`status=${l.statusCode}`),de(e,c,r,l.statusCode,l.body),l.statusCode}catch(l){return a("sendTraces:error",l.message),de(e,c,r,0,l.message),0}}S();function Fn(){let t=parseInt(process.env[g.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(R.MIN_TTL_DAYS,Math.min(R.MAX_TTL_DAYS,t)):R.DEFAULT_TTL_DAYS)*24*60*60*1e3}function $n(){let t=parseInt(process.env[g.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(R.MIN_MAX_FILES,Math.min(R.MAX_MAX_FILES,t)):R.DEFAULT_MAX_FILES}function _e(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return G__namespace.default.join(rt__namespace.default.tmpdir(),`${R.FILE_PREFIX}${t}.json`)}function Dt(){let t=rt__namespace.default.tmpdir(),e;try{e=h__namespace.default.readdirSync(t);}catch{return []}return e.filter(n=>n.startsWith(R.FILE_PREFIX)&&n.endsWith(".json")).map(n=>{let r=G__namespace.default.join(t,n),s=0;try{s=h__namespace.default.statSync(r).mtimeMs;}catch{}return {full:r,mtime:s}}).sort((n,r)=>n.mtime-r.mtime).map(n=>n.full)}function it(t){try{let e=$n(),n=Dt();if(n.length>=e){let o=n.slice(0,n.length-e+1);for(let i of o)try{h__namespace.default.unlinkSync(i);}catch{}}let r=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:r,bufferedAt:Date.now(),payload:t};return h__namespace.default.writeFileSync(_e(r),JSON.stringify(s),{encoding:"utf8",mode:384}),a("buffer",`saved fileId=${r}`),r}catch(e){return a("buffer",`saveToBuffer failed: ${e.message}`),null}}function Te(t){let e=Dt(),n=t!=null&&t>0?t:e.length,r=[];for(let s of e){if(r.length>=n)break;try{let o=h__namespace.default.readFileSync(s,"utf8"),i=JSON.parse(o);i&&i.fileId&&i.payload&&r.push(i);}catch{a("buffer",`skipping malformed file: ${s}`);}}return r}function Se(t){try{h__namespace.default.unlinkSync(_e(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function he(){let t=Date.now()-Fn();for(let e of Dt())try{let{mtimeMs:n}=h__namespace.default.statSync(e);n<t&&(h__namespace.default.unlinkSync(e),a("buffer",`evicted stale: ${G__namespace.default.basename(e)}`));}catch{}}S();async function Dn(t){he();let e=Te(R.REPLAY_BATCH_SIZE);e.length&&(a("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async n=>{try{let r=await At(n.payload,t.endpoint,t.authHeader);r>=200&&r<300?(Se(n.fileId),a("replayBufferedTraces",`replayed fileId=${n.fileId} status=${r}`)):a("replayBufferedTraces",`replay failed fileId=${n.fileId} status=${r}`);}catch(r){a("replayBufferedTraces",`replay error fileId=${n.fileId}: ${r.message}`);}})));}async function Ae(t){let e=await V();if(!e.length)return e.authError&&(a("postToLangfuse","auth refresh failed \u2014 buffering trace"),it(t)),0;let n=await Promise.all(e.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await ge(o.endpoint,o.authHeader);return {creds:o,healthy:i}})),r=n.find(o=>o.creds.mode==="gateway"&&o.healthy)?.creds??n.find(o=>o.creds.mode==="direct")?.creds;return r&&await Dn(r),(await Promise.all(n.map(async({creds:o,healthy:i})=>{if(o.mode==="gateway"){if(!i)return a("postToLangfuse","gateway health check failed \u2014 buffering trace"),it(t),0;let l=await At(t,o.endpoint,o.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`gateway send failed (status ${l}) \u2014 buffering trace`),it(t)),l}let c=await At(t,o.endpoint,o.authHeader);return (c===0||c>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${c}) \u2014 buffering trace`),it(t)),c}))).find(o=>o!==0)??0}S();var y="[REDACTED]",Mn="[REDACTED-EMAIL]",xn="[REDACTED-CPF]",Bn="[REDACTED-CNPJ]",Oe="[REDACTED-PHONE]",Hn=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${y}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${y}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${y}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,n)=>`${e}
|
|
19
19
|
${y}
|
package/dist/setup.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var u=require('path'),a=require('fs'),O=require('os'),child_process=require('child_process'),Ie=require('crypto'),Dt=require('https');require('readline/promises');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var u__namespace=/*#__PURE__*/_interopNamespace(u);var a__namespace=/*#__PURE__*/_interopNamespace(a);var O__namespace=/*#__PURE__*/_interopNamespace(O);var Ie__namespace=/*#__PURE__*/_interopNamespace(Ie);var Dt__default=/*#__PURE__*/_interopDefault(Dt);var B=Object.defineProperty;var Me=Object.getOwnPropertyDescriptor;var $e=Object.getOwnPropertyNames;var He=Object.prototype.hasOwnProperty;var Ye=(e,n,t)=>()=>{if(t)throw t[0];try{return e&&(n=e(e=0)),n}catch(r){throw t=[r],r}};var Ke=(e,n)=>()=>{try{return n||e((n={exports:{}}).exports,n),n.exports}catch(t){throw n=0,t}},je=(e,n)=>{for(var t in n)B(e,t,{get:n[t],enumerable:true});},We=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of $e(n))!He.call(e,s)&&s!==t&&B(e,s,{get:()=>n[s],enumerable:!(r=Me(n,s))||r.enumerable});return e};var Ve=e=>We(B({},"__esModule",{value:true}),e);var ue={};je(ue,{AUTH_ENGINE:()=>X,BUFFER:()=>Xe,CLAUDE_DESKTOP:()=>f,CONFIG_DIR_NAME:()=>U,CONFIG_FILE_NAME:()=>D,COPILOT_OTEL:()=>p,DEBUG_LOG_FILENAME:()=>Z,ENV:()=>h,FLOW_URLS:()=>Be,HOOK_TIMEOUTS:()=>q,INSTALLER:()=>z,NATIVE_OTEL:()=>J,OTLP:()=>Je,STATE_FILE_PREFIX:()=>Ze,TRACE_LIMITS:()=>ze,VALIDATION:()=>T,VAULT:()=>N,getFlowBaseUrl:()=>K,getFlowUrls:()=>S,getMetrics:()=>qe});function K(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Ge}function S(){let e=K();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 qe(){let e=K();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ge,Be,N,U,D,Je,J,h,X,z,q,Xe,T,Z,ze,f,p,Ze,y=Ye(()=>{"use strict";Ge="https://flow.ciandt.com";Be=S(),N={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},U="FLOW-nodejs",D="config.json",Je={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},J={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"},h={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"},X={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},z={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},q={UserPromptSubmit:30,PreToolUse:3,PostToolUse:10,Stop:15},Xe={FILE_PREFIX:"flow-obs-buffer-",DEFAULT_TTL_DAYS:4,MIN_TTL_DAYS:1,MAX_TTL_DAYS:30,DEFAULT_MAX_FILES:50,MIN_MAX_FILES:1,MAX_MAX_FILES:500,REPLAY_BATCH_SIZE:10},T={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[A-Za-z0-9_.\-:=+/]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},Z="flow-ai-obs-debug.log",ze={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};f={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"},p={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"},Ze="flow-obs-";});var Ne=Ke((ar,Ut)=>{Ut.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.15.
|
|
2
|
+
'use strict';var u=require('path'),a=require('fs'),O=require('os'),child_process=require('child_process'),Ie=require('crypto'),Dt=require('https');require('readline/promises');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var u__namespace=/*#__PURE__*/_interopNamespace(u);var a__namespace=/*#__PURE__*/_interopNamespace(a);var O__namespace=/*#__PURE__*/_interopNamespace(O);var Ie__namespace=/*#__PURE__*/_interopNamespace(Ie);var Dt__default=/*#__PURE__*/_interopDefault(Dt);var B=Object.defineProperty;var Me=Object.getOwnPropertyDescriptor;var $e=Object.getOwnPropertyNames;var He=Object.prototype.hasOwnProperty;var Ye=(e,n,t)=>()=>{if(t)throw t[0];try{return e&&(n=e(e=0)),n}catch(r){throw t=[r],r}};var Ke=(e,n)=>()=>{try{return n||e((n={exports:{}}).exports,n),n.exports}catch(t){throw n=0,t}},je=(e,n)=>{for(var t in n)B(e,t,{get:n[t],enumerable:true});},We=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of $e(n))!He.call(e,s)&&s!==t&&B(e,s,{get:()=>n[s],enumerable:!(r=Me(n,s))||r.enumerable});return e};var Ve=e=>We(B({},"__esModule",{value:true}),e);var ue={};je(ue,{AUTH_ENGINE:()=>X,BUFFER:()=>Xe,CLAUDE_DESKTOP:()=>f,CONFIG_DIR_NAME:()=>U,CONFIG_FILE_NAME:()=>D,COPILOT_OTEL:()=>p,DEBUG_LOG_FILENAME:()=>Z,ENV:()=>h,FLOW_URLS:()=>Be,HOOK_TIMEOUTS:()=>q,INSTALLER:()=>z,NATIVE_OTEL:()=>J,OTLP:()=>Je,STATE_FILE_PREFIX:()=>Ze,TRACE_LIMITS:()=>ze,VALIDATION:()=>T,VAULT:()=>N,getFlowBaseUrl:()=>K,getFlowUrls:()=>S,getMetrics:()=>qe});function K(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Ge}function S(){let e=K();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 qe(){let e=K();return {API_URL:process.env.FLOW_METRICS_URL||`${e}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ge,Be,N,U,D,Je,J,h,X,z,q,Xe,T,Z,ze,f,p,Ze,y=Ye(()=>{"use strict";Ge="https://flow.ciandt.com";Be=S(),N={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},U="FLOW-nodejs",D="config.json",Je={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"},J={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"},h={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"},X={REQUEST_TIMEOUT_MS:1e4,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY_MS:1e3},z={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},q={UserPromptSubmit:30,PreToolUse:3,PostToolUse:10,Stop:15},Xe={FILE_PREFIX:"flow-obs-buffer-",DEFAULT_TTL_DAYS:4,MIN_TTL_DAYS:1,MAX_TTL_DAYS:30,DEFAULT_MAX_FILES:50,MIN_MAX_FILES:1,MAX_MAX_FILES:500,REPLAY_BATCH_SIZE:10},T={API_KEY_MAX_LENGTH:1024,API_KEY_PATTERN:/^[A-Za-z0-9_.\-:=+/]+$/,EMAIL_MAX_LENGTH:254,EMAIL_HEADER_PATTERN:/^[\x21-\x7E]+$/},Z="flow-ai-obs-debug.log",ze={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};f={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"},p={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"},Ze="flow-obs-";});var Ne=Ke((ar,Ut)=>{Ut.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.15.1-beta.95",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"}};});y();var Q={credentials:"credentials","token-cache":"tokenCache"};function F(){let e=O__namespace.default.homedir();if(process.platform==="darwin")return u__namespace.default.join(e,"Library","Preferences",U,D);if(process.platform==="win32"){let t=process.env.APPDATA??u__namespace.default.join(e,"AppData","Roaming");return u__namespace.default.join(t,U,D)}let n=process.env.XDG_CONFIG_HOME??u__namespace.default.join(e,".config");return u__namespace.default.join(n,U,D)}function ee(){try{let e=a__namespace.default.readFileSync(F(),"utf8");return JSON.parse(e)}catch{return {}}}function pe(e){let n=F();a__namespace.default.mkdirSync(u__namespace.default.dirname(n),{recursive:true}),a__namespace.default.writeFileSync(n,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var j=class{static isAvailable(){return true}static hasExistingData(){try{if(!a__namespace.default.existsSync(F()))return !1;let n=JSON.parse(a__namespace.default.readFileSync(F(),"utf8"));return !!(n&&n.credentials)}catch{return false}}async getSecret(n,t){let r=ee(),s=Q[t]??t,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(n,t,r){let s=ee(),o=Q[t]??t;if(t==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;pe(s);}async deleteSecret(n,t){let r=ee(),s=Q[t]??t;return s in r?(delete r[s],pe(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${F()}`}};async function fe(){return new j}y();var et=N.SERVICE,tt=N.ACCOUNT_CREDS;N.ACCOUNT_TOKEN;var te=null;function nt(){return te||(te=fe()),te}async function de(){let n=await(await nt()).getSecret(et,tt);if(!n)return null;try{return JSON.parse(n)}catch{return null}}y();y();y();var it=u.join(O.tmpdir(),Z);function c(...e){if(process.env[h.FLOW_OBS_DEBUG]!=="1")return;let n=`[${new Date().toISOString()}] ${e.join(" ")}
|
|
3
3
|
`;try{a.writeFileSync(it,n,{flag:"a"});}catch(t){process.stderr.write(`[flow-obs debug ERROR] ${t.message}
|
|
4
4
|
`);}}!process.env.NO_COLOR&&process.stdout.isTTY;function ne(){return process.platform==="win32"?false:process.getuid?.()===0}function A(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let n=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(n)return {home:n,username:process.env.SUDO_USER}}return {home:O__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||O__namespace.userInfo().username}}function R(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let t=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();t&&/^[A-Za-z]:\\/.test(t)&&(e=t);}if(e){let n=e.replace(/^([A-Za-z]):/,(t,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return u__namespace.join(n,".claude","settings.json")}return u__namespace.join(O__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||O__namespace.homedir();return u__namespace.join(e,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let n=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(n)return u__namespace.join(n,".claude","settings.json")}return u__namespace.join(O__namespace.homedir(),".claude","settings.json")}var Ee="flow-ai-obs",ge="config.json";function he(){if(process.platform==="win32"){let t=process.env.APPDATA||u__namespace.join(O__namespace.homedir(),"AppData","Roaming");return u__namespace.join(t,Ee,ge)}let e=A(),n=process.env.XDG_CONFIG_HOME||u__namespace.join(e.home,".config");return u__namespace.join(n,Ee,ge)}var pt=z.LOCK_STALE_MS;function _e(e){try{let n=a__namespace.statSync(e);Date.now()-n.mtimeMs>pt&&a__namespace.unlinkSync(e);}catch{}try{a__namespace.writeFileSync(e,String(process.pid),{flag:"wx"});}catch(n){throw n.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+e):n}}function Te(e){try{a__namespace.unlinkSync(e);}catch{}}function ft(e,n){let r=(Array.isArray(e)?e:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(i=>!i.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [n,...r]}function ye(e,n){let t=R(),r=t+".lock",s=[];a__namespace.mkdirSync(u__namespace.dirname(t),{recursive:true}),_e(r);try{if(a__namespace.existsSync(t)){a__namespace.copyFileSync(t,t+".bkp");try{a__namespace.chmodSync(t+".bkp",384);}catch{}}let o=he();if(a__namespace.existsSync(o)){let m=o+".bkp";a__namespace.copyFileSync(o,m);try{a__namespace.chmodSync(m,384);}catch{}}let i={};try{i=JSON.parse(a__namespace.readFileSync(t,"utf8"));}catch{}let g=i.env&&typeof i.env=="object"?i.env:{};delete g.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:_}=(y(),Ve(ue)),P=_().OTEL_ENDPOINT,H={...J,OTEL_EXPORTER_OTLP_ENDPOINT:e??P};i.env={...g,...H,...n??{}},i.otelHeadersHelper="flow-ai-obs otel-headers",(!i.hooks||typeof i.hooks!="object"||Array.isArray(i.hooks))&&(i.hooks={});let G=(m,Y)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${m}`,timeout:Y}]}),le=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],k=i.hooks;for(let m of le){let Y=ft(k[m],G(m,q[m]));Y.length>1&&s.push(m),k[m]=Y;}a__namespace.writeFileSync(t,JSON.stringify(i,null,2)+`
|
|
5
5
|
`,{encoding:"utf8",mode:384});try{a__namespace.chmodSync(t,384);}catch{}}finally{Te(r);}return {settingsPath:t,preserved:s}}var M;function Se(e){if(M===void 0)try{let t=a__namespace.readFileSync(R(),"utf8");M=JSON.parse(t).env??null;}catch{M=null;}if(!M)return null;let n=M[e];return typeof n=="string"?n:null}function oe(e){let n=R(),t=n+".lock";a__namespace.mkdirSync(u__namespace.dirname(n),{recursive:true}),_e(t);try{let r={};try{r=JSON.parse(a__namespace.readFileSync(n,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,e),a__namespace.writeFileSync(n,JSON.stringify(r,null,2)+`
|