@ciandt-flow/flow-ai-obs 0.9.1 → 0.10.0-beta.693
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 +120 -118
- package/dist/index.js +10 -10
- package/dist/setup.js +5 -5
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,94 +1,95 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var
|
|
3
|
-
`);}catch(o){throw n.close(),o}if(n.close(),e!==void 0)return e;throw new Error("Too many invalid attempts for yes/no prompt")}async function
|
|
2
|
+
'use strict';var Ue=require('readline/promises'),Ts=require('https'),A=require('fs'),Et=require('os'),bt=require('path'),child_process=require('child_process'),Bs=require('http'),util=require('util'),crypto=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var Ue__namespace=/*#__PURE__*/_interopNamespace(Ue);var Ts__default=/*#__PURE__*/_interopDefault(Ts);var A__namespace=/*#__PURE__*/_interopNamespace(A);var Et__namespace=/*#__PURE__*/_interopNamespace(Et);var bt__namespace=/*#__PURE__*/_interopNamespace(bt);var Bs__default=/*#__PURE__*/_interopDefault(Bs);var Ce=Object.defineProperty;var fs=Object.getOwnPropertyDescriptor;var ms=Object.getOwnPropertyNames;var gs=Object.prototype.hasOwnProperty;var Bt=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var m=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var hs=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(n){throw e=0,n}},$=(t,e)=>{for(var n in e)Ce(t,n,{get:e[n],enumerable:true});},Es=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ms(e))!gs.call(t,s)&&s!==n&&Ce(t,s,{get:()=>e[s],enumerable:!(r=fs(e,s))||r.enumerable});return t};var C=t=>Es(Ce({},"__esModule",{value:true}),t);var Ne={};$(Ne,{bold:()=>b,cyan:()=>v,dim:()=>p,green:()=>P,red:()=>I,yellow:()=>R});function kt(t,e){return Ss?n=>`\x1B[${t}m${n}\x1B[${e}m`:n=>n}var Ss,P,I,R,v,b,p,dt=m(()=>{"use strict";Ss=!process.env.NO_COLOR&&process.stdout.isTTY;P=kt("32","39"),I=kt("31","39"),R=kt("33","39"),v=kt("36","39"),b=kt("1","22"),p=kt("2","22");});var Mt=hs((Ei,ws)=>{ws.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.10.0-beta.693",description:"Claude Code hooks for Langfuse OTLP tracing \u2014 cross-platform",main:"dist/index.js",bin:{"flow-ai-obs":"dist/cli.js","flow-ai-obs-setup":"dist/setup.js"},scripts:{build:"tsup",test:"jest",typecheck:"tsc --noEmit",lint:"eslint src bin scripts",format:'prettier --write "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"format:check":'prettier --check "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"security-scan":"trufflehog filesystem src/ --fail --no-update --exclude-paths .trufflehogignore",postinstall:`node -e "require('fs').existsSync('dist/setup.js') && require('child_process').execFileSync(process.execPath, ['dist/setup.js'], {stdio:'inherit'})"`,prepublishOnly:"npm run security-scan && npm run build","release:npm":"changeset publish",changeset:"changeset","version-packages":"changeset version","install:hooks":"node dist/cli.js install","auth:login":"node dist/cli.js auth login","auth:logout":"node dist/cli.js auth logout","auth:status":"node dist/cli.js auth status",smoke:"bash scripts/smoke-test.sh","smoke:debug":"bash scripts/smoke-test.sh --debug","smoke:send":"bash scripts/smoke-test.sh --send --allow-http --debug"},files:["dist/","README.md","LICENSE.md"],keywords:["claude-code","langfuse","observability","otlp","hooks","flow","ciandt"],author:"CI&T Flow Team",license:"SEE LICENSE IN LICENSE.md",private:!1,dependencies:{},optionalDependencies:{keytar:"7.9.0"},devDependencies:{"@changesets/changelog-github":"^0.6.0","@changesets/cli":"^2.30.0","@types/jest":"^30.0.0","@types/node":"^25.8.0",jest:"^30.4.2","ts-jest":"^29.4.9",tsup:"^8.5.1","eslint-config-prettier":"^10.1.5",prettier:"^3.5.3",typescript:"^6.0.3","typescript-eslint":"^8.33.0"},engines:{node:">=18.0.0"},overrides:{esbuild:"^0.28.1"},publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/CI-T-HyperX/flow-codeassistant-observability.git"}};});function pt(){return process.stdout.isTTY===true&&process.stdin.isTTY===true&&!process.argv.includes("--no-interactive")}async function $e(t,e){let n=Ue__namespace.createInterface({input:process.stdin,output:process.stdout}),s=`${t} ${e===true?"(Y/n)":e===false?"(y/N)":"(y/n)"}: `;for(let i=1;i<=3;i++)try{let o=(await n.question(s)).trim().toLowerCase();if(o===""&&e!==void 0)return n.close(),e;if(o==="y"||o==="yes")return n.close(),!0;if(o==="n"||o==="no")return n.close(),!1;i<3&&process.stdout.write(` Invalid input. Please answer "y" or "n".
|
|
3
|
+
`);}catch(o){throw n.close(),o}if(n.close(),e!==void 0)return e;throw new Error("Too many invalid attempts for yes/no prompt")}async function Ln(t,e){let n=Ue__namespace.createInterface({input:process.stdin,output:process.stdout});try{let r=(await n.question(`${t}: `)).trim();if(e);return r}catch(r){throw r}finally{n.close();}}var Fe=m(()=>{"use strict";});var Rt={};$(Rt,{checkForUpdate:()=>Ls,checkForUpdateInteractive:()=>Rs,fetchLatestVersionAsync:()=>In,isNewer:()=>Lt,pkg:()=>N,primeUpdateCache:()=>vs,runUpdate:()=>bn});function N(){return xe||(xe=Mt()),xe}function Lt(t,e){let n=i=>{let o=String(i).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return o?[+o[1],+o[2],+o[3]]:null},r=n(t),s=n(e);return !r||!s?false:s[0]!==r[0]?s[0]>r[0]:s[1]!==r[1]?s[1]>r[1]:s[2]>r[2]}function Me(){try{let t=JSON.parse(A__namespace.default.readFileSync(Pn,"utf8"));return typeof t.latestVersion!="string"||Date.now()-t.checkedAt>=Os?null:t}catch{return null}}function He(t,e,n=Date.now()){try{A__namespace.default.writeFileSync(Pn,JSON.stringify({latestVersion:t,updatePriority:e??null,checkedAt:n}),{mode:384});}catch{}}function je(t){let e=N().name,n=Ts__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`,{timeout:As},r=>{if(r.statusCode!==200)return r.resume(),t(new Error(`HTTP ${r.statusCode}`));let s="";r.setEncoding("utf8"),r.on("data",i=>{s+=i;}),r.on("end",()=>{try{let i=JSON.parse(s);if(typeof i.version!="string")throw new Error("no version field");t(null,{version:i.version,updatePriority:typeof i.updatePriority=="string"?i.updatePriority:null});}catch(i){t(i);}});});n.on("error",t),n.on("timeout",()=>{n.destroy(new Error("timeout"));});}function De(t){let e=N().name,r=` Update available: ${N().version} \u2192 ${t}`,s=` Run: npm install -g ${e}`,i=Math.max(r.length,s.length)+2,o="\u2500".repeat(i);process.stderr.write(`
|
|
4
4
|
\u256D${o}\u256E
|
|
5
5
|
\u2502${r.padEnd(i)}\u2502
|
|
6
6
|
\u2502${s.padEnd(i)}\u2502
|
|
7
7
|
\u2570${o}\u256F
|
|
8
8
|
|
|
9
|
-
`);}function
|
|
9
|
+
`);}function Be(t){let e=N().name;process.stderr.write(`
|
|
10
10
|
[${e}] Critical update detected \u2014 auto-updating to ${t}...
|
|
11
11
|
|
|
12
|
-
`),child_process.spawn("npm",["install","-g",`${e}@${t}`],{detached:true,stdio:"ignore",windowsHide:true}).unref();}async function
|
|
12
|
+
`),child_process.spawn("npm",["install","-g",`${e}@${t}`],{detached:true,stdio:"ignore",windowsHide:true}).unref();}async function ks(t,e=1e4){let n=Bt("readline"),r=N().name,i=` Update available: ${N().version} \u2192 ${t}`,o=` Run: npm install -g ${r}`,c=" Install now? [y/N]: ",a=Math.max(i.length,o.length,c.length-2)+2,d="\u2500".repeat(a);return process.stderr.write(`
|
|
13
13
|
\u256D${d}\u256E
|
|
14
|
-
\u2502${i.padEnd(
|
|
15
|
-
\u2502${o.padEnd(
|
|
16
|
-
\u2502${
|
|
14
|
+
\u2502${i.padEnd(a)}\u2502
|
|
15
|
+
\u2502${o.padEnd(a)}\u2502
|
|
16
|
+
\u2502${c.padEnd(a)}\u2502
|
|
17
17
|
\u2570${d}\u256F
|
|
18
|
-
`),new Promise(h=>{let
|
|
19
|
-
`),h(E));}let u=setTimeout(()=>
|
|
18
|
+
`),new Promise(h=>{let O=n.createInterface({input:process.stdin,output:void 0,terminal:false}),w=false;function S(E){w||(w=true,clearTimeout(u),O.close(),process.stderr.write(`
|
|
19
|
+
`),h(E));}let u=setTimeout(()=>S(false),e);O.once("line",E=>S(E.trim().toLowerCase()==="y")),O.once("close",()=>S(false));})}async function bn(t){let e=N().name;return process.stderr.write(` Installing ${e}@${t}...
|
|
20
20
|
`),new Promise(n=>{let r=child_process.spawn("npm",["install","-g",`${e}@${t}`],{stdio:"inherit"});r.on("close",s=>{s!==0?process.stderr.write(` \u2717 Update failed \u2014 continuing with current version.
|
|
21
21
|
|
|
22
22
|
`):process.stderr.write(` \u2713 Updated to ${t}. Please restart the command.
|
|
23
23
|
|
|
24
24
|
`),n();}),r.on("error",()=>{process.stderr.write(` \u2717 Update failed \u2014 continuing with current version.
|
|
25
25
|
|
|
26
|
-
`),n();});})}function
|
|
27
|
-
`;try{
|
|
28
|
-
`);}}var
|
|
26
|
+
`),n();});})}function In(){return new Promise(t=>{je((e,n)=>t(e||!n?null:n));})}function Ls(){try{let t=Me();if(t){Lt(N().version,t.latestVersion)&&(t.updatePriority==="auto"?Be(t.latestVersion):De(t.latestVersion));return}setImmediate(()=>{je((e,n)=>{e||!n||(He(n.version,n.updatePriority),Lt(N().version,n.version)&&(n.updatePriority==="auto"?Be(n.version):De(n.version)));});});}catch{}}async function Rs(t={}){try{let e=Me();if(e){if(!Lt(N().version,e.latestVersion))return}else {let r=await In();if(!r||(He(r.version,r.updatePriority),!Lt(N().version,r.version)))return;e={latestVersion:r.version,updatePriority:r.updatePriority,checkedAt:Date.now()};}if(e.updatePriority==="auto"){Be(e.latestVersion);return}if(!pt()){De(e.latestVersion);return}await ks(e.latestVersion,t.timeoutMs)&&await bn(e.latestVersion);}catch{}}function vs(){try{if(Me())return;setImmediate(()=>{je((t,e)=>{t||!e||Lt(N().version,e.version)&&He(e.version,e.updatePriority,0);});});}catch{}}var xe,Pn,Os,As,vt=m(()=>{"use strict";Fe();Pn=bt__namespace.default.join(Et__namespace.default.tmpdir(),"flow-obs-update-cache.json"),Os=1440*60*1e3,As=3e3;});var Cn={};$(Cn,{BUFFER:()=>x,CONFIG_DIR_NAME:()=>jt,CONFIG_FILE_NAME:()=>Vt,COPILOT_OTEL:()=>F,DEBUG_LOG_FILENAME:()=>Ve,ENV:()=>g,FEATURES:()=>Cs,FLOW_URLS:()=>bs,HOOK_TIMEOUTS:()=>mt,INSTALLER:()=>Wt,NATIVE_OTEL:()=>et,OTLP:()=>ce,STATE_FILE_PREFIX:()=>Ns,TRACE_LIMITS:()=>j,VAULT:()=>Ht,getFlowBaseUrl:()=>tt,getFlowUrls:()=>ft,getLlmProxy:()=>Is,getMetrics:()=>le});function tt(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():Ps}function ft(){let t=tt();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${t}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${t}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${t}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${t}/otel`}}function Is(){let t=tt();return {ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${t}/flow-llm-proxy/`,ANTHROPIC_MODEL:process.env.FLOW_LLM_PROXY_MODEL??"anthropic.claude-4-6-sonnet",ANTHROPIC_SMALL_FAST_MODEL:process.env.FLOW_LLM_PROXY_SMALL_MODEL??"anthropic.claude-4-6-haiku",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"}}function le(){let t=tt();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ps,bs,Ht,jt,Vt,ce,et,F,g,Cs,Wt,mt,x,Ve,j,Ns,L=m(()=>{"use strict";Ps="https://flow.ciandt.com";bs=ft(),Ht={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},jt="FLOW-nodejs",Vt="config.json",ce={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};et={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"},F={ENABLED_KEY:"github.copilot.chat.otel.enabled",EXPORTER_TYPE_KEY:"github.copilot.chat.otel.exporterType",ENDPOINT_KEY:"github.copilot.chat.otel.otlpEndpoint",ENABLED_VALUE:!0,EXPORTER_TYPE_VALUE:"otlp-http"},g={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"},Cs={KEYCHAIN_ENABLED:!1},Wt={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},mt={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},x={FILE_PREFIX:"flow-obs-buffer-",DEFAULT_TTL_DAYS:4,MIN_TTL_DAYS:1,MAX_TTL_DAYS:30,DEFAULT_MAX_FILES:50,MIN_MAX_FILES:1,MAX_MAX_FILES:500,REPLAY_BATCH_SIZE:10},Ve="flow-ai-obs-debug.log",j={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};Ns="flow-obs-";});function l(...t){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
|
|
27
|
+
`;try{A.writeFileSync(xs,e,{flag:"a"});}catch(n){process.stderr.write(`[flow-obs debug ERROR] ${n.message}
|
|
28
|
+
`);}}var xs,V=m(()=>{"use strict";L();xs=bt.join(Et.tmpdir(),Ve);});function Hs(t){if(!Ms.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}function js(t,e){let n=e.length>400?e.slice(0,400)+"\u2026":e;l("toAuthError",`status=${t} body=${n}`);try{let r=JSON.parse(e);if(typeof r.error=="string"&&(l("toAuthError",`api_error_code=${r.error}`+(r.message?` api_message=${r.message}`:"")),Nn[r.error]))return new gt(Nn[r.error])}catch{}return t===401||t===403||t===500?new gt("Invalid credentials"):t>=400&&t<500?new gt("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function D(t){return new Promise((e,n)=>{try{Hs(t.tenant);}catch(d){return n(d)}let r=JSON.stringify({clientSecret:t.clientSecret}),s=new URL(ft().AUTH_ENGINE),i=s.protocol==="https:",o={hostname:s.hostname,port:s.port||(i?443:80),path:s.pathname+s.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(r),FlowTenant:t.tenant}};l("getToken",`requesting token tenant=${t.tenant} host=${o.hostname} path=${o.path}`);let a=(i?Ts__default.default:Bs__default.default).request(o,d=>{let h=[];d.on("data",O=>h.push(O)),d.on("end",()=>{let O=h.join("");if((d.statusCode??0)>=400)return n(js(d.statusCode??0,O));let w;try{w=JSON.parse(O);}catch{return n(new Error("Invalid response from auth engine"))}let S=w.expires_at??new Date(Date.now()+(w.expires_in??3600)*1e3).toISOString();e({accessToken:w.access_token??"",expiresAt:S});});});a.on("error",d=>n(new Error(`Network error: ${d.message}`))),a.write(r),a.end();})}var gt,Ms,Nn,ht=m(()=>{"use strict";L();V();gt=class extends Error{constructor(e){super(e),this.name="AuthError";}},Ms=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;Nn={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 Un(){return process.platform==="win32"?false:process.getuid?.()===0}function ue(){if(Un())return process.stderr.write(`
|
|
29
29
|
`+I(` \u2717 flow-ai-obs is not supported in a sudo context.
|
|
30
30
|
|
|
31
31
|
`)+v(` npm install -g @ciandt-flow/flow-ai-obs
|
|
32
32
|
`)+`
|
|
33
|
-
`),1}var
|
|
34
|
-
`,{encoding:"utf8",mode:384});try{
|
|
35
|
-
`,{encoding:"utf8",mode:384});try{O__namespace.chmodSync(e,384);}catch{}}finally{xn(n);}}var Fs,jt=g(()=>{"use strict";L();ft();ie();He();Fs=Mt.LOCK_STALE_MS;});function Wt(){let t=mt__namespace.default.homedir();if(process.platform==="darwin")return Lt__namespace.default.join(t,"Library","Preferences",Dt,Bt);if(process.platform==="win32"){let n=process.env.APPDATA??Lt__namespace.default.join(t,"AppData","Roaming");return Lt__namespace.default.join(n,Dt,Bt)}let e=process.env.XDG_CONFIG_HOME??Lt__namespace.default.join(t,".config");return Lt__namespace.default.join(e,Dt,Bt)}function Ye(){try{let t=O__namespace.default.readFileSync(Wt(),"utf8");return JSON.parse(t)}catch{return {}}}function Bn(t){let e=Wt();O__namespace.default.mkdirSync(Lt__namespace.default.dirname(e),{recursive:true}),O__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var Ve,le,Mn=g(()=>{"use strict";L();Ve={credentials:"credentials","token-cache":"tokenCache"};le=class{static isAvailable(){return !0}static hasExistingData(){try{if(!O__namespace.default.existsSync(Wt()))return !1;let e=JSON.parse(O__namespace.default.readFileSync(Wt(),"utf8"));return !!(e&&e.credentials)}catch{return !1}}async getSecret(e,n){let r=Ye(),s=Ve[n]??n,i=r[s];return i?typeof i=="string"?i:JSON.stringify(i):null}async setSecret(e,n,r){let s=Ye(),i=Ve[n]??n;if(n==="token-cache")try{s[i]=JSON.parse(r);}catch{s[i]=r;}else s[i]=r;Bn(s);}async deleteSecret(e,n){let r=Ye(),s=Ve[n]??n;return s in r?(delete r[s],Bn(r),!0):!1}getStoragePath(){return `config.json (unencrypted) \u2014 ${Wt()}`}};});var Hn={};$(Hn,{MacOsKeyVaultProvider:()=>Je});var Ge,Je,jn=g(()=>{"use strict";Ge=util.promisify(child_process.execFile),Je=class{static async isAvailable(){try{return O.accessSync("/usr/bin/security",O.constants.X_OK),!0}catch{return !1}}async getSecret(e,n){try{let{stdout:r}=await Ge("security",["find-generic-password","-w","-a",n,"-s",e]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await Ge("security",["add-generic-password","-U","-a",n,"-s",e,"-w",r]);}async deleteSecret(e,n){try{return await Ge("security",["delete-generic-password","-a",n,"-s",e]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var Vn={};$(Vn,{LinuxKeyVaultProvider:()=>Ke});var Wn,Ke,Yn=g(()=>{"use strict";Wn=util.promisify(child_process.execFile),Ke=class{static async isAvailable(){let e=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let n of e)try{return O.accessSync(n,O.constants.X_OK),!0}catch{}return !1}async getSecret(e,n){try{let{stdout:r}=await Wn("secret-tool",["lookup","service",e,"account",n]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await new Promise((s,i)=>{let o=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",n]);o.on("error",i),o.on("close",a=>{a===0?s():i(new Error(`secret-tool exited with code ${a}`));}),o.stdin.write(r),o.stdin.end();});}async deleteSecret(e,n){try{return await Wn("secret-tool",["clear","service",e,"account",n]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var Gn={};$(Gn,{WindowsKeyVaultProvider:()=>qe});var qe,Jn=g(()=>{"use strict";qe=class{static async isAvailable(){try{return await $t("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,n){return $t("keytar").getPassword(e,n)}async setSecret(e,n,r){await $t("keytar").setPassword(e,n,r);}async deleteSecret(e,n){return $t("keytar").deletePassword(e,n)}getStoragePath(){return "Windows Credential Manager"}};});async function Kn(){return await Ks()??new le}async function Ks(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(jn(),Hn));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Yn(),Vn));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Jn(),Gn));return await t.isAvailable()?new t:null}default:return null}}var qn=g(()=>{"use strict";Mn();});var zn={};$(zn,{clearFlowCredentials:()=>Xs,getConfigPath:()=>Zs,getEmailFromToken:()=>ue,getFlowCredentials:()=>Xn,getTokenCache:()=>Yt,hasCredentials:()=>Qs,isTokenValid:()=>zs,saveFlowCredentials:()=>qs,saveTokenCache:()=>tt});function vt(){return Xe||(Xe=Kn()),Xe}async function Xn(){let e=await(await vt()).getSecret(Rt,ze);if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function qs(t){if(!t.clientId||!t.clientSecret||!t.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await vt()).setSecret(Rt,ze,JSON.stringify(t));}async function Xs(){let t=await vt();await t.deleteSecret(Rt,ze),await t.deleteSecret(Rt,Ze);}async function tt(t){await(await vt()).setSecret(Rt,Ze,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function Yt(){let e=await(await vt()).getSecret(Rt,Ze);if(!e)return null;try{let n=JSON.parse(e);return {accessToken:n.accessToken,expiresAt:n.expiresAt,lastAuthCheckAt:n.lastAuthCheckAt}}catch{return null}}async function zs(){let t=await Yt();return t?new Date(t.expiresAt)>new Date:false}async function ue(){let t=await Yt();if(!t||!t.accessToken)return null;try{let e=t.accessToken.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email??n.preferred_username??n.upn??n.sub??null}catch{return null}}async function Zs(){let t=await vt();if(typeof t.getStoragePath=="function")return t.getStoragePath();let e=process.platform;return e==="darwin"?"macOS Keychain":e==="win32"?"Windows Credential Manager":"Linux Secret Service (libsecret)"}async function Qs(){let t=await Xn();return !!(t&&t.clientId&&t.clientSecret&&t.tenant)}var Rt,ze,Ze,Xe,Gt=g(()=>{"use strict";qn();L();Rt=xt.SERVICE,ze=xt.ACCOUNT_CREDS,Ze=xt.ACCOUNT_TOKEN,Xe=null;});function eo(t){return to.some(e=>e.test(t))}function no(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}function et(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:i}=n;return !r||!s||!i?null:{clientId:r,clientSecret:s,tenant:i}}catch{return null}}function Zn(t){let e=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),n=Buffer.from(JSON.stringify({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant})).toString("base64url");return `${e}.${n}.`}function gt(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let n=process.env[m.FLOW_OBS_ALLOW_HTTP]==="true";if(!n&&e.protocol!=="https:")throw new Error(`URL must use HTTPS: ${t}`);if(e.username||e.password)throw new Error(`URL must not contain embedded credentials: ${t}`);if(!n&&eo(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function Qn(){let t=et(process.env[m.ANTHROPIC_AUTH_TOKEN]);return t?{user:await ue().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function ro(){return new Date().toISOString().slice(0,10)}async function so(t){let e=ro(),n=await Yt();if(n?.lastAuthCheckAt!==e){l("getOrRefreshToken",`daily auth check (last: ${n?.lastAuthCheckAt??"never"})`);try{let i=await x(t);try{await tt({...i,lastAuthCheckAt:e});}catch{}return l("getOrRefreshToken",`daily check passed, expires=${i.expiresAt}`),i.accessToken}catch(i){if(i instanceof pt)throw i;l("getOrRefreshToken",`daily check network error \u2014 using cache: ${i.message}`);}}let r=n!=null&&new Date(n.expiresAt)>new Date;if(l("getOrRefreshToken",`cacheValid=${r}`),r)return l("getOrRefreshToken",`using cached token, expires=${n.expiresAt}`),n.accessToken;l("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let s=await x(t);try{await tt({...s,lastAuthCheckAt:e});}catch(i){l("getOrRefreshToken",`token cache save failed (non-fatal): ${i.message}`);}return l("getOrRefreshToken",`token refreshed, expires=${s.expiresAt}`),s.accessToken}function oo(t,e){let n=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${n}`}}function io(t,e,n){let r=Buffer.from(`${e}:${n}`).toString("base64");return {endpoint:t.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${r}`}}async function G(){let t=[],e=process.env[m.ANTHROPIC_MODEL]??"",n=et(process.env[m.ANTHROPIC_AUTH_TOKEN]);l("resolveCredentials",n?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),n&&l("resolveCredentials",`clientId=${n.clientId}`,`tenant=${n.tenant}`);let r=n?n.tenant:"",s=process.env[m.FLOW_TELEMETRY]==="true",i=process.env[m.LANGFUSE_BASE_URL],o=process.env[m.LANGFUSE_PUBLIC_KEY],a=process.env[m.LANGFUSE_SECRET_KEY];if(s&&i&&o&&a){let S="",w=r;n&&(S=await ue().catch(()=>null)??n.clientId);let u={user:S??"",tenant:w??"",team:"",project:"",model:e};t.push({mode:"direct",...io(gt(i),o,a),...u}),l("resolveCredentials","direct mode active",`user=${u.user}`,`tenant=${u.tenant}`);}if(!n){if(t.length===0){let S=[];return S.authError=false,S}return t}let c;try{c=await so(n);}catch(S){if(l("resolveCredentials",`token refresh failed: ${S.message}`,`(tenant=${n.tenant} clientId=${n.clientId})`),t.length>0)return t.authError=true,t;let w=[];return w.authError=true,w}let h={user:no(c)??n.clientId,tenant:r,team:"",project:"",model:e},A=process.env[m.FLOW_TELEMETRY_GATEWAY]??Z();return t.push({mode:"gateway",...oo(gt(A),{accessToken:c}),...h}),t}async function de(){return (await G()).length>0}var to,W=g(()=>{"use strict";Gt();ft();L();j();to=[/^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 tr(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux")return child_process.spawnSync("cmd.exe",["/c","where","claude"],{encoding:"utf8",timeout:5e3}).status===0;let t=process.platform==="win32"?"where":"which";return child_process.spawnSync(t,["claude"],{encoding:"utf8",timeout:5e3}).status===0}function er(){try{if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=child_process.spawnSync("cmd.exe",["/c","claude","--version"],{encoding:"utf8",timeout:5e3});return e.status===0?e.stdout.trim():null}let t=child_process.spawnSync("claude",["--version"],{encoding:"utf8",timeout:5e3});return t.status===0?t.stdout.trim():null}catch{return null}}var nr=g(()=>{"use strict";});var sr={};$(sr,{clearLoggedOutMarker:()=>tn,isLoggedOut:()=>lo,markLoggedOut:()=>co});function Qe(){return Lt__namespace.default.join(mt__namespace.default.homedir(),".claude","flow-obs",".logged-out")}function co(){try{let t=Qe();O__namespace.default.mkdirSync(Lt__namespace.default.dirname(t),{recursive:!0}),O__namespace.default.writeFileSync(t,"",{mode:384});}catch{}}function tn(){try{O__namespace.default.unlinkSync(Qe());}catch{}}function lo(){try{return O__namespace.default.existsSync(Qe())}catch{return false}}var en=g(()=>{"use strict";});function nn(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():We("FLOW_BASE_URL")}function uo(){return We(m.ANTHROPIC_AUTH_TOKEN)??void 0}async function me(){let t=nn();if(!t)return {ok:false,baseUrl:"",user:"",tenant:"",notConfigured:true,error:"NOT_CONFIGURED"};try{let s=new URL(t);if(s.protocol!=="https:"&&s.protocol!=="http:")throw new Error}catch{return {ok:false,baseUrl:t,user:"",tenant:"",notConfigured:true,error:"NOT_CONFIGURED"}}let e=uo(),n=et(e);if(!n)return {ok:false,baseUrl:t,user:"",tenant:"",error:"No credentials found"};let r=process.env.FLOW_BASE_URL;process.env.FLOW_BASE_URL=t;try{let s=await x({clientId:n.clientId,clientSecret:n.clientSecret,tenant:n.tenant});await tt({accessToken:s.accessToken,expiresAt:s.expiresAt});let i=n.clientId;try{let o=s.accessToken.split(".");if(o.length>=2){let a=JSON.parse(Buffer.from(o[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));i=a.email??a.preferred_username??a.upn??a.sub??i;}}catch{}return {ok:!0,baseUrl:t,user:i,tenant:n.tenant}}catch(s){return {ok:false,baseUrl:t,user:n.clientId,tenant:n.tenant,error:s.message}}finally{r===void 0?delete process.env.FLOW_BASE_URL:process.env.FLOW_BASE_URL=r;}}var rn=g(()=>{"use strict";Gt();W();jt();L();ft();});var he={};$(he,{promptRaw:()=>Jt,runLogin:()=>mo});function V(t){return typeof t=="string"?t.replace(po,""):t}function Jt(t,e={}){return new Promise((n,r)=>{if(typeof process.stdin.setRawMode!="function"){r(new Error("NOT_A_TTY"));return}let{masked:s=false,defaultValue:i=""}=e;process.stdout.write(t+i);let o=i;function a(){try{process.stdin.setRawMode(!1);}catch{}}process.once("uncaughtException",a),process.once("unhandledRejection",a);let c=h=>{if(h===""){d(),r(new Error("SIGINT"));return}if(h==="\r"||h===`
|
|
33
|
+
`),1}var de=m(()=>{"use strict";dt();});function $n(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return {home:e,username:process.env.SUDO_USER}}return {home:Et__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||Et__namespace.userInfo().username}}function B(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.USERPROFILE;if(!t){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(t=n);}if(t){let e=t.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return bt__namespace.join(e,".claude","settings.json")}return bt__namespace.join(Et__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||Et__namespace.homedir();return bt__namespace.join(t,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return bt__namespace.join(e,".claude","settings.json")}return bt__namespace.join(Et__namespace.homedir(),".claude","settings.json")}var pe=m(()=>{"use strict";de();});function fe(){if(process.platform==="win32"){let n=process.env.APPDATA||bt__namespace.join(Et__namespace.homedir(),"AppData","Roaming");return bt__namespace.join(n,Fn,xn)}let t=$n(),e=process.env.XDG_CONFIG_HOME||bt__namespace.join(t.home,".config");return bt__namespace.join(e,Fn,xn)}function Mn(){try{let t=A__namespace.readFileSync(B(),"utf8"),n=JSON.parse(t).env?.FLOW_BASE_URL;return typeof n=="string"&&n.trim()?n.trim():null}catch{return null}}var Fn,xn,Ye=m(()=>{"use strict";pe();Fn="flow-ai-obs",xn="config.json";});function Hn(t){try{let e=A__namespace.statSync(t);Date.now()-e.mtimeMs>Vs&&A__namespace.unlinkSync(t);}catch{}try{A__namespace.writeFileSync(t,String(process.pid),{flag:"wx"});}catch(e){throw e.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+t):e}}function jn(t){try{A__namespace.unlinkSync(t);}catch{}}function Ws(t,e){let r=(Array.isArray(t)?t:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let i=s.hooks.filter(o=>!o.command?.startsWith?.("flow-ai-obs "));return i.length>0?{...s,hooks:i}:null}).filter(s=>s!=null);return [e,...r]}function Vn(t,e){let n=B(),r=n+".lock",s=[];A__namespace.mkdirSync(bt__namespace.dirname(n),{recursive:true}),Hn(r);try{if(A__namespace.existsSync(n)){A__namespace.copyFileSync(n,n+".bkp");try{A__namespace.chmodSync(n+".bkp",384);}catch{}}let i=fe();if(A__namespace.existsSync(i)){let u=i+".bkp";A__namespace.copyFileSync(i,u);try{A__namespace.chmodSync(u,384);}catch{}}let o={};try{o=JSON.parse(A__namespace.readFileSync(n,"utf8"));}catch{}let c=o.env&&typeof o.env=="object"?o.env:{};delete c.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:a}=(L(),C(Cn)),d=a().OTEL_ENDPOINT,h={...et,OTEL_EXPORTER_OTLP_ENDPOINT:t??d};o.env={...c,...h,...e??{}},o.otelHeadersHelper="flow-ai-obs otel-headers",(!o.hooks||typeof o.hooks!="object"||Array.isArray(o.hooks))&&(o.hooks={});let O=(u,E)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${u}`,timeout:E}]}),w=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],S=o.hooks;for(let u of w){let E=Ws(S[u],O(u,mt[u]));E.length>1&&s.push(u),S[u]=E;}A__namespace.writeFileSync(n,JSON.stringify(o,null,2)+`
|
|
34
|
+
`,{encoding:"utf8",mode:384});try{A__namespace.chmodSync(n,384);}catch{}}finally{jn(r);}return {settingsPath:n,preserved:s}}function Ke(t){try{let e=A__namespace.readFileSync(B(),"utf8"),r=JSON.parse(e).env?.[t];return typeof r=="string"?r:null}catch{return null}}function me(t){let e=B(),n=e+".lock";A__namespace.mkdirSync(bt__namespace.dirname(e),{recursive:true}),Hn(n);try{let r={};try{r=JSON.parse(A__namespace.readFileSync(e,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,t),A__namespace.writeFileSync(e,JSON.stringify(r,null,2)+`
|
|
35
|
+
`,{encoding:"utf8",mode:384});try{A__namespace.chmodSync(e,384);}catch{}}finally{jn(n);}}var Vs,Gt=m(()=>{"use strict";L();ht();pe();Ye();Vs=Wt.LOCK_STALE_MS;});function Gs(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.APPDATA;if(!t){let r=child_process.spawnSync("cmd.exe",["/c","echo","%APPDATA%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();r&&/^[A-Za-z]:\\/.test(r)&&(t=r);}if(!t)return null;let e=t.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return bt__namespace.join(e,"Code","User","settings.json")}if(process.platform==="win32"){let t=process.env.APPDATA;return t?bt__namespace.join(t,"Code","User","settings.json"):null}return process.platform==="darwin"?bt__namespace.join(Et__namespace.homedir(),"Library","Application Support","Code","User","settings.json"):bt__namespace.join(Et__namespace.homedir(),".config","Code","User","settings.json")}function Wn(t){let e;try{e=Gs();}catch{return {status:"skipped",reason:"VS Code path resolution failed"}}if(!e)return {status:"skipped",reason:"VS Code path not found"};try{let n={};if(A__namespace.existsSync(e))try{let i=A__namespace.readFileSync(e,"utf8").replace(/,(\s*[}\]])/g,"$1");n=JSON.parse(i);}catch{return {status:"skipped",reason:"VS Code settings.json could not be parsed (unsupported JSONC syntax such as comments)"}}if(n[F.ENABLED_KEY]===F.ENABLED_VALUE&&n[F.EXPORTER_TYPE_KEY]===F.EXPORTER_TYPE_VALUE&&n[F.ENDPOINT_KEY]===t)return {status:"already_configured"};A__namespace.mkdirSync(bt__namespace.dirname(e),{recursive:!0});let s={...n,[F.ENABLED_KEY]:F.ENABLED_VALUE,[F.EXPORTER_TYPE_KEY]:F.EXPORTER_TYPE_VALUE,[F.ENDPOINT_KEY]:t};return A__namespace.writeFileSync(e,JSON.stringify(s,null,2)+`
|
|
36
|
+
`,{encoding:"utf8"}),{status:"configured"}}catch(n){return {status:"skipped",reason:n.message}}}var Yn=m(()=>{"use strict";L();});function Kt(){let t=Et__namespace.default.homedir();if(process.platform==="darwin")return bt__namespace.default.join(t,"Library","Preferences",jt,Vt);if(process.platform==="win32"){let n=process.env.APPDATA??bt__namespace.default.join(t,"AppData","Roaming");return bt__namespace.default.join(n,jt,Vt)}let e=process.env.XDG_CONFIG_HOME??bt__namespace.default.join(t,".config");return bt__namespace.default.join(e,jt,Vt)}function Xe(){try{let t=A__namespace.default.readFileSync(Kt(),"utf8");return JSON.parse(t)}catch{return {}}}function Gn(t){let e=Kt();A__namespace.default.mkdirSync(bt__namespace.default.dirname(e),{recursive:true}),A__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var qe,ge,Kn=m(()=>{"use strict";L();qe={credentials:"credentials","token-cache":"tokenCache"};ge=class{static isAvailable(){return !0}static hasExistingData(){try{if(!A__namespace.default.existsSync(Kt()))return !1;let e=JSON.parse(A__namespace.default.readFileSync(Kt(),"utf8"));return !!(e&&e.credentials)}catch{return !1}}async getSecret(e,n){let r=Xe(),s=qe[n]??n,i=r[s];return i?typeof i=="string"?i:JSON.stringify(i):null}async setSecret(e,n,r){let s=Xe(),i=qe[n]??n;if(n==="token-cache")try{s[i]=JSON.parse(r);}catch{s[i]=r;}else s[i]=r;Gn(s);}async deleteSecret(e,n){let r=Xe(),s=qe[n]??n;return s in r?(delete r[s],Gn(r),!0):!1}getStoragePath(){return `config.json (unencrypted) \u2014 ${Kt()}`}};});var Jn={};$(Jn,{MacOsKeyVaultProvider:()=>Ze});var ze,Ze,qn=m(()=>{"use strict";ze=util.promisify(child_process.execFile),Ze=class{static async isAvailable(){try{return A.accessSync("/usr/bin/security",A.constants.X_OK),!0}catch{return !1}}async getSecret(e,n){try{let{stdout:r}=await ze("security",["find-generic-password","-w","-a",n,"-s",e]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await ze("security",["add-generic-password","-U","-a",n,"-s",e,"-w",r]);}async deleteSecret(e,n){try{return await ze("security",["delete-generic-password","-a",n,"-s",e]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var zn={};$(zn,{LinuxKeyVaultProvider:()=>Qe});var Xn,Qe,Zn=m(()=>{"use strict";Xn=util.promisify(child_process.execFile),Qe=class{static async isAvailable(){let e=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let n of e)try{return A.accessSync(n,A.constants.X_OK),!0}catch{}return !1}async getSecret(e,n){try{let{stdout:r}=await Xn("secret-tool",["lookup","service",e,"account",n]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await new Promise((s,i)=>{let o=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",n]);o.on("error",i),o.on("close",c=>{c===0?s():i(new Error(`secret-tool exited with code ${c}`));}),o.stdin.write(r),o.stdin.end();});}async deleteSecret(e,n){try{return await Xn("secret-tool",["clear","service",e,"account",n]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var Qn={};$(Qn,{WindowsKeyVaultProvider:()=>tn});var tn,tr=m(()=>{"use strict";tn=class{static async isAvailable(){try{return await Bt("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,n){return Bt("keytar").getPassword(e,n)}async setSecret(e,n,r){await Bt("keytar").setPassword(e,n,r);}async deleteSecret(e,n){return Bt("keytar").deletePassword(e,n)}getStoragePath(){return "Windows Credential Manager"}};});async function er(){return await ro()??new ge}async function ro(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(qn(),Jn));return await t.isAvailable()?new t:null}case "linux":{if(process.env.WSL_DISTRO_NAME)return null;let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Zn(),zn));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(tr(),Qn));return await t.isAvailable()?new t:null}default:return null}}var nr=m(()=>{"use strict";Kn();});var sr={};$(sr,{clearFlowCredentials:()=>oo,getConfigPath:()=>ao,getEmailFromToken:()=>he,getFlowCredentials:()=>rr,getTokenCache:()=>qt,hasCredentials:()=>co,isTokenValid:()=>io,saveFlowCredentials:()=>so,saveTokenCache:()=>rt});function Ct(){return en||(en=er()),en}async function rr(){let e=await(await Ct()).getSecret(It,nn);if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function so(t){if(!t.clientId||!t.clientSecret||!t.tenant)throw new Error("clientId, clientSecret and tenant are required");await(await Ct()).setSecret(It,nn,JSON.stringify(t));}async function oo(){let t=await Ct();await t.deleteSecret(It,nn),await t.deleteSecret(It,rn);}async function rt(t){await(await Ct()).setSecret(It,rn,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function qt(){let e=await(await Ct()).getSecret(It,rn);if(!e)return null;try{let n=JSON.parse(e);return {accessToken:n.accessToken,expiresAt:n.expiresAt,lastAuthCheckAt:n.lastAuthCheckAt}}catch{return null}}async function io(){let t=await qt();return t?new Date(t.expiresAt)>new Date:false}async function he(){let t=await qt();if(!t||!t.accessToken)return null;try{let e=t.accessToken.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email??n.preferred_username??n.upn??n.sub??null}catch{return null}}async function ao(){let t=await Ct();if(typeof t.getStoragePath=="function")return t.getStoragePath();let e=process.platform;return e==="darwin"?"macOS Keychain":e==="win32"?"Windows Credential Manager":"Linux Secret Service (libsecret)"}async function co(){let t=await rr();return !!(t&&t.clientId&&t.clientSecret&&t.tenant)}var It,nn,rn,en,Xt=m(()=>{"use strict";nr();L();It=Ht.SERVICE,nn=Ht.ACCOUNT_CREDS,rn=Ht.ACCOUNT_TOKEN,en=null;});function uo(t){return lo.some(e=>e.test(t))}function po(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return n.email||n.preferred_username||n.upn||n.sub||null}catch{return null}}function st(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:i}=n;return !r||!s||!i?null:{clientId:r,clientSecret:s,tenant:i}}catch{return null}}function or(t){let e=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),n=Buffer.from(JSON.stringify({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant})).toString("base64url");return `${e}.${n}.`}function wt(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let n=process.env[g.FLOW_OBS_ALLOW_HTTP]==="true";if(!n&&e.protocol!=="https:")throw new Error(`URL must use HTTPS: ${t}`);if(e.username||e.password)throw new Error(`URL must not contain embedded credentials: ${t}`);if(!n&&uo(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function ir(){let t=st(process.env[g.ANTHROPIC_AUTH_TOKEN]);return t?{user:await he().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function fo(){return new Date().toISOString().slice(0,10)}async function mo(t){let e=fo(),n=await qt();if(n?.lastAuthCheckAt!==e){l("getOrRefreshToken",`daily auth check (last: ${n?.lastAuthCheckAt??"never"})`);try{let i=await D(t);try{await rt({...i,lastAuthCheckAt:e});}catch{}return l("getOrRefreshToken",`daily check passed, expires=${i.expiresAt}`),i.accessToken}catch(i){if(i instanceof gt)throw i;l("getOrRefreshToken",`daily check network error \u2014 using cache: ${i.message}`);}}let r=n!=null&&new Date(n.expiresAt)>new Date;if(l("getOrRefreshToken",`cacheValid=${r}`),r)return l("getOrRefreshToken",`using cached token, expires=${n.expiresAt}`),n.accessToken;l("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let s=await D(t);try{await rt({...s,lastAuthCheckAt:e});}catch(i){l("getOrRefreshToken",`token cache save failed (non-fatal): ${i.message}`);}return l("getOrRefreshToken",`token refreshed, expires=${s.expiresAt}`),s.accessToken}function go(t,e){let n=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${n}`}}function ho(t,e,n){let r=Buffer.from(`${e}:${n}`).toString("base64");return {endpoint:t.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${r}`}}async function K(){let t=[],e=process.env[g.ANTHROPIC_MODEL]??"",n=st(process.env[g.ANTHROPIC_AUTH_TOKEN]);l("resolveCredentials",n?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),n&&l("resolveCredentials",`clientId=${n.clientId}`,`tenant=${n.tenant}`);let r=n?n.tenant:"",s=process.env[g.FLOW_TELEMETRY]==="true",i=process.env[g.LANGFUSE_BASE_URL],o=process.env[g.LANGFUSE_PUBLIC_KEY],c=process.env[g.LANGFUSE_SECRET_KEY];if(s&&i&&o&&c){let w="",S=r;n&&(w=await he().catch(()=>null)??n.clientId);let u={user:w??"",tenant:S??"",team:"",project:"",model:e};t.push({mode:"direct",...ho(wt(i),o,c),...u}),l("resolveCredentials","direct mode active",`user=${u.user}`,`tenant=${u.tenant}`);}if(!n){if(t.length===0){let w=[];return w.authError=false,w}return t}let a;try{a=await mo(n);}catch(w){if(l("resolveCredentials",`token refresh failed: ${w.message}`,`(tenant=${n.tenant} clientId=${n.clientId})`),t.length>0)return t.authError=true,t;let S=[];return S.authError=true,S}let h={user:po(a)??n.clientId,tenant:r,team:"",project:"",model:e},O=process.env[g.FLOW_TELEMETRY_GATEWAY]??tt();return t.push({mode:"gateway",...go(wt(O),{accessToken:a}),...h}),t}async function Ee(){return (await K()).length>0}var lo,W=m(()=>{"use strict";Xt();ht();L();V();lo=[/^localhost\.?$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/,/^::1$/,/^\[::1\]$/,/^\[::ffff:/i,/^\[f[cd]/i,/^\[fe80:/i,/^metadata\.google\.internal\.?$/i,/^metadata\.azure\.internal\.?$/i,/(?:^|\.)localtest\.me\.?$/i,/(?:^|\.)lvh\.me\.?$/i,/(?:^|\.)vcap\.me\.?$/i];});function ar(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux")return child_process.spawnSync("cmd.exe",["/c","where","claude"],{encoding:"utf8",timeout:5e3}).status===0;let t=process.platform==="win32"?"where":"which";return child_process.spawnSync(t,["claude"],{encoding:"utf8",timeout:5e3}).status===0}function cr(){try{if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=child_process.spawnSync("cmd.exe",["/c","claude","--version"],{encoding:"utf8",timeout:5e3});return e.status===0?e.stdout.trim():null}let t=child_process.spawnSync("claude",["--version"],{encoding:"utf8",timeout:5e3});return t.status===0?t.stdout.trim():null}catch{return null}}var lr=m(()=>{"use strict";});var dr={};$(dr,{clearLoggedOutMarker:()=>on,isLoggedOut:()=>wo,markLoggedOut:()=>So});function sn(){return bt__namespace.default.join(Et__namespace.default.homedir(),".claude","flow-obs",".logged-out")}function So(){try{let t=sn();A__namespace.default.mkdirSync(bt__namespace.default.dirname(t),{recursive:!0}),A__namespace.default.writeFileSync(t,"",{mode:384});}catch{}}function on(){try{A__namespace.default.unlinkSync(sn());}catch{}}function wo(){try{return A__namespace.default.existsSync(sn())}catch{return false}}var an=m(()=>{"use strict";});function cn(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():Ke("FLOW_BASE_URL")}function To(){return Ke(g.ANTHROPIC_AUTH_TOKEN)??void 0}async function Te(){let t=cn();if(!t)return {ok:false,baseUrl:"",user:"",tenant:"",notConfigured:true,error:"NOT_CONFIGURED"};try{let s=new URL(t);if(s.protocol!=="https:"&&s.protocol!=="http:")throw new Error}catch{return {ok:false,baseUrl:t,user:"",tenant:"",notConfigured:true,error:"NOT_CONFIGURED"}}let e=To(),n=st(e);if(!n)return {ok:false,baseUrl:t,user:"",tenant:"",error:"No credentials found"};let r=process.env.FLOW_BASE_URL;process.env.FLOW_BASE_URL=t;try{let s=await D({clientId:n.clientId,clientSecret:n.clientSecret,tenant:n.tenant});await rt({accessToken:s.accessToken,expiresAt:s.expiresAt});let i=n.clientId;try{let o=s.accessToken.split(".");if(o.length>=2){let c=JSON.parse(Buffer.from(o[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));i=c.email??c.preferred_username??c.upn??c.sub??i;}}catch{}return {ok:!0,baseUrl:t,user:i,tenant:n.tenant}}catch(s){return {ok:false,baseUrl:t,user:n.clientId,tenant:n.tenant,error:s.message}}finally{r===void 0?delete process.env.FLOW_BASE_URL:process.env.FLOW_BASE_URL=r;}}var ln=m(()=>{"use strict";Xt();W();Gt();L();ht();});var _e={};$(_e,{promptRaw:()=>zt,runLogin:()=>Oo});function Y(t){return typeof t=="string"?t.replace(yo,""):t}function zt(t,e={}){return new Promise((n,r)=>{if(typeof process.stdin.setRawMode!="function"){r(new Error("NOT_A_TTY"));return}let{masked:s=false,defaultValue:i=""}=e;process.stdout.write(t+i);let o=i;function c(){try{process.stdin.setRawMode(!1);}catch{}}process.once("uncaughtException",c),process.once("unhandledRejection",c);let a=h=>{if(h===""){d(),r(new Error("SIGINT"));return}if(h==="\r"||h===`
|
|
36
37
|
`){d(),process.stdout.write(`
|
|
37
|
-
`),n(o);return}if(h==="\x7F"){o.length>0&&(o=o.slice(0,-1),process.stdout.write("\b \b"));return}h.startsWith("\x1B")||(o+=h,process.stdout.write(s?"*".repeat(h.length):h));};function d(){process.stdin.setRawMode(false),process.stdin.removeListener("data",
|
|
38
|
+
`),n(o);return}if(h==="\x7F"){o.length>0&&(o=o.slice(0,-1),process.stdout.write("\b \b"));return}h.startsWith("\x1B")||(o+=h,process.stdout.write(s?"*".repeat(h.length):h));};function d(){process.stdin.setRawMode(false),process.stdin.removeListener("data",a),process.removeListener("uncaughtException",c),process.removeListener("unhandledRejection",c);}process.stdin.setRawMode(true),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",a);})}async function ye(t,e=false){let n=cn(),r=process.env.FLOW_BASE_URL;n&&(process.env.FLOW_BASE_URL=n);try{let{accessToken:s,expiresAt:i}=await D(t),o=or(t);if(e)return {jwt:o,accessToken:s,expiresAt:i};me({[g.ANTHROPIC_AUTH_TOKEN]:o}),on(),await rt({accessToken:s,expiresAt:i});}finally{r===void 0?delete process.env.FLOW_BASE_URL:process.env.FLOW_BASE_URL=r;}}async function _o(t=false){try{let e=(await zt(v(" ? ")+"Client ID: ")).trim(),n=(await zt(v(" ? ")+"Client Secret: ",{masked:!0})).trim(),r=(await zt(v(" ? ")+"Tenant: ")).trim();if(!e||!n||!r)return process.stderr.write(I(` \u2717 All fields are required
|
|
38
39
|
`)),1;if(process.stdout.write(p(` Authenticating...
|
|
39
|
-
`)),t){let s=await
|
|
40
|
-
${
|
|
41
|
-
`+p(` Tenant: ${
|
|
40
|
+
`)),t){let s=await ye({clientId:e,clientSecret:n,tenant:r},!0);return process.stdout.write(`
|
|
41
|
+
${P("\u2713")} ${b("Authenticated")}
|
|
42
|
+
`+p(` Tenant: ${Y(r)}
|
|
42
43
|
`)+p(` Storage: pending (will be written at end of init)
|
|
43
44
|
|
|
44
|
-
`)),{code:0,result:s}}return await
|
|
45
|
-
${
|
|
46
|
-
`+p(` Tenant: ${
|
|
45
|
+
`)),{code:0,result:s}}return await ye({clientId:e,clientSecret:n,tenant:r}),process.stdout.write(`
|
|
46
|
+
${P("\u2713")} ${b("Authenticated")}
|
|
47
|
+
`+p(` Tenant: ${Y(r)}
|
|
47
48
|
`)+p(` Storage: ANTHROPIC_AUTH_TOKEN (settings.json)
|
|
48
49
|
|
|
49
50
|
`)),0}catch(e){if(e.message==="SIGINT"||e.message==="NOT_A_TTY")throw e;return process.stderr.write(`
|
|
50
|
-
${I("\u2717")} ${
|
|
51
|
-
${
|
|
51
|
+
${I("\u2717")} ${b("Authentication failed:")}
|
|
52
|
+
${Y(e.message)}
|
|
52
53
|
|
|
53
|
-
`),1}}async function
|
|
54
|
+
`),1}}async function Oo(t={}){let e=ue();if(e)return e;let{deferPersist:n=false,skipAuthCheck:r=false}=t;if(t.clientId&&t.clientSecret&&t.tenant)try{if(n){let i=await ye({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant},!0);return process.stdout.write(P(` \u2713 Authenticated. Tenant: ${Y(t.tenant)}
|
|
54
55
|
|
|
55
|
-
`)),{code:0,result:i}}return await
|
|
56
|
+
`)),{code:0,result:i}}return await ye({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant}),process.stdout.write(P(` \u2713 Authenticated. Tenant: ${Y(t.tenant)}
|
|
56
57
|
|
|
57
|
-
`)),0}catch(i){return process.stderr.write(I(` \u2717 Authentication failed: ${
|
|
58
|
-
`)),1}let s=await
|
|
59
|
-
`),process.stdout.write(
|
|
58
|
+
`)),0}catch(i){return process.stderr.write(I(` \u2717 Authentication failed: ${Y(i.message)}
|
|
59
|
+
`)),1}let s=await Te();if(!r){if(process.stdout.write(`
|
|
60
|
+
`),process.stdout.write(b(` Auth
|
|
60
61
|
`)),s.notConfigured)return process.stdout.write(` ${R("\u26A0")} Not configured
|
|
61
62
|
`),process.stdout.write(p(" Run `flow-ai-obs init` to set up the environment first.\n")),process.stdout.write(`
|
|
62
|
-
`),1;if(s.ok){process.stdout.write(` ${
|
|
63
|
-
`),process.stdout.write(p(" URL: ")+
|
|
64
|
-
`),process.stdout.write(p(" Tenant: ")+
|
|
65
|
-
`),process.stdout.write(p(" User: ")+
|
|
63
|
+
`),1;if(s.ok){process.stdout.write(` ${P("\u2713")} Authenticated
|
|
64
|
+
`),process.stdout.write(p(" URL: ")+Y(s.baseUrl)+`
|
|
65
|
+
`),process.stdout.write(p(" Tenant: ")+Y(s.tenant)+`
|
|
66
|
+
`),process.stdout.write(p(" User: ")+Y(s.user)+`
|
|
66
67
|
`),process.stdout.write(`
|
|
67
|
-
`);let i;try{i=await
|
|
68
|
-
`),130;if(o.message==="NOT_A_TTY")return process.stdout.write(
|
|
68
|
+
`);let i;try{i=await zt(v(" ? ")+"Re-authenticate? (y/N): ");}catch(o){if(o.message==="SIGINT")return process.stdout.write(`
|
|
69
|
+
`),130;if(o.message==="NOT_A_TTY")return process.stdout.write(P(` \u2713 Using existing credentials.
|
|
69
70
|
|
|
70
|
-
`)),0;throw o}if(i.trim().toLowerCase()!=="y")return process.stdout.write(
|
|
71
|
+
`)),0;throw o}if(i.trim().toLowerCase()!=="y")return process.stdout.write(P(` \u2713 Using existing credentials.
|
|
71
72
|
|
|
72
73
|
`)),0}else s.error==="No credentials found"?(process.stdout.write(` ${R("\u26A0")} Not authenticated
|
|
73
74
|
`),process.stdout.write(p(` URL: ${s.baseUrl}
|
|
74
75
|
`)),process.stdout.write(`
|
|
75
76
|
`)):(process.stdout.write(` ${R("\u26A0")} Session not valid for current endpoint
|
|
76
|
-
`),process.stdout.write(p(" URL: ")+
|
|
77
|
-
`),process.stdout.write(p(" Tenant: ")+
|
|
77
|
+
`),process.stdout.write(p(" URL: ")+Y(s.baseUrl)+`
|
|
78
|
+
`),process.stdout.write(p(" Tenant: ")+Y(s.tenant)+`
|
|
78
79
|
`),process.stdout.write(p(" User: ")+p("(not authenticated)")+`
|
|
79
80
|
`),process.stdout.write(`
|
|
80
|
-
`));}try{return await
|
|
81
|
+
`));}try{return await _o(n)}catch(i){if(i.message==="SIGINT")return process.stdout.write(`
|
|
81
82
|
`),130;if(i.message==="NOT_A_TTY")return process.stderr.write(I(` \u2717 No TTY available for interactive login.
|
|
82
83
|
`)+` Pass --client-id, --client-secret and --tenant for non-interactive use.
|
|
83
84
|
|
|
84
|
-
`),1;throw i}}var
|
|
85
|
+
`),1;throw i}}var yo,Oe=m(()=>{"use strict";Xt();an();ht();W();Gt();L();dt();de();ln();yo=/[\x00-\x08\x0B-\x1F\x7F]|\x1b\[[0-9;]*[a-zA-Z]/g;});var hr={};$(hr,{normalizeCustomUrl:()=>gr,runInit:()=>Lo,validateCustomUrl:()=>dn});function Zt(t,e,n){process.stdout.write(b(v(`
|
|
85
86
|
[${t}/${e}] ${n}
|
|
86
|
-
`)));}function
|
|
87
|
-
`);}function
|
|
88
|
-
`);}function
|
|
89
|
-
`);}function
|
|
90
|
-
`);}function
|
|
91
|
-
`,{encoding:"utf8",mode:384});}catch{}return t}function
|
|
87
|
+
`)));}function Nt(t){process.stdout.write(` ${P("\u2713")} ${t}
|
|
88
|
+
`);}function pr(t){process.stdout.write(` ${R("\u26A0")} ${t}
|
|
89
|
+
`);}function Ao(t){process.stderr.write(` ${I("\u2717")} ${t}
|
|
90
|
+
`);}function Qt(t){process.stdout.write(` ${p(t)}
|
|
91
|
+
`);}function fr(){try{let t=A__namespace.readFileSync(B(),"utf8");return JSON.parse(t).env||{}}catch{return {}}}function mr(){try{let t=A__namespace.readFileSync(B(),"utf8"),e=JSON.parse(t);return !!(e.env&&e.env[g.ANTHROPIC_AUTH_TOKEN])}catch{return false}}function ko(){let t=Mn();if(!t)return null;me({FLOW_BASE_URL:t});try{let e=fe(),n={};try{n=JSON.parse(A__namespace.readFileSync(e,"utf8"));}catch{return t}delete n.baseUrl,Object.keys(n).length===0?A__namespace.unlinkSync(e):A__namespace.writeFileSync(e,JSON.stringify(n,null,2)+`
|
|
92
|
+
`,{encoding:"utf8",mode:384});}catch{}return t}function gr(t){let e=t.trim().replace(/\\/g,"/");/^https?:\/\//i.test(e)||(e=`https://${e}`);try{let n=new URL(e);return `${n.protocol}//${n.host}`}catch{return e}}function dn(t,e=false){if(e){let i=/^https?:\/\//i.test(t.trim())?t.trim().replace(/\\/g,"/"):`https://${t.trim().replace(/\\/g,"/")}`,o;try{o=new URL(i);}catch{throw new Error(`Invalid URL: ${t}`)}if(o.protocol!=="https:")throw new Error(`Custom URL must use HTTPS: ${t}`);if(o.pathname!=="/"&&o.pathname!=="")throw new Error(`Custom URL must be a base URL with no path beyond the root.
|
|
92
93
|
Received: ${t}
|
|
93
94
|
Expected: https://tenant.example.com`);if(o.search)throw new Error(`Custom URL must not contain query parameters.
|
|
94
95
|
Received: ${t}
|
|
@@ -96,20 +97,21 @@
|
|
|
96
97
|
Received: ${t}
|
|
97
98
|
Expected: https://tenant.example.com`);if(o.username||o.password)throw new Error(`Custom URL must not contain embedded credentials.
|
|
98
99
|
Received: ${t}
|
|
99
|
-
Expected: https://tenant.example.com`);if(!o.hostname.includes("."))throw new Error(`Invalid domain: ${o.hostname}. Expected format: tenant.example.com`);let
|
|
100
|
+
Expected: https://tenant.example.com`);if(!o.hostname.includes("."))throw new Error(`Invalid domain: ${o.hostname}. Expected format: tenant.example.com`);let c=`${o.protocol}//${o.host}`,a=process.env[g.FLOW_OBS_ALLOW_HTTP];try{delete process.env[g.FLOW_OBS_ALLOW_HTTP],wt(c);}finally{a!==void 0&&(process.env[g.FLOW_OBS_ALLOW_HTTP]=a);}return c}let n=gr(t),r;try{r=new URL(n);}catch{throw new Error(`Invalid URL: ${t}`)}if(r.protocol!=="https:")throw new Error(`Custom URL must use HTTPS: ${t}`);if(!r.hostname.includes("."))throw new Error(`Invalid domain: ${r.hostname}. Expected format: tenant.example.com`);let s=process.env[g.FLOW_OBS_ALLOW_HTTP];try{delete process.env[g.FLOW_OBS_ALLOW_HTTP],wt(n);}finally{s!==void 0&&(process.env[g.FLOW_OBS_ALLOW_HTTP]=s);}return n.replace(/\/$/,"")}async function un(){for(let t=1;t<=3;t++)try{let e=await Ln(" Enter your Flow domain (e.g., tenant.ciandt.com)");return dn(e)}catch(e){if(process.stderr.write(R(` \u2717 ${e.message}
|
|
100
101
|
|
|
101
102
|
`)),t===3)throw process.stderr.write(I(` Too many invalid attempts.
|
|
102
103
|
|
|
103
|
-
`)),new Error("Too many invalid URL attempts")}throw new Error("Too many invalid URL attempts")}function
|
|
104
|
+
`)),new Error("Too many invalid URL attempts")}throw new Error("Too many invalid URL attempts")}function te(){try{let t=A__namespace.readFileSync(B(),"utf8"),n=JSON.parse(t).env?.FLOW_BASE_URL;return typeof n=="string"&&n.trim()?n.trim():null}catch{return null}}async function Lo(t={}){let e=ue();if(e)return e;let n=t.url,r=5;if(process.stdout.write(b(v(`
|
|
104
105
|
flow-ai-obs init
|
|
105
106
|
`))),process.stdout.write(p(` Configuring your development environment:
|
|
106
107
|
|
|
107
|
-
`)),process.stdout.write(p(` [1/
|
|
108
|
-
`)),process.stdout.write(p(` [2/
|
|
109
|
-
`)),process.stdout.write(p(` [3/
|
|
110
|
-
`)),process.stdout.write(p(` [4/
|
|
111
|
-
`)),
|
|
112
|
-
`),
|
|
108
|
+
`)),process.stdout.write(p(` [1/5] Claude Code Installation Verify @anthropic-ai/claude-code
|
|
109
|
+
`)),process.stdout.write(p(` [2/5] Flow Environment Setup Configure Flow URLs and LLM routing
|
|
110
|
+
`)),process.stdout.write(p(` [3/5] Authentication Authenticate with Flow
|
|
111
|
+
`)),process.stdout.write(p(` [4/5] Observability OpenTelemetry metrics, logs and trace hooks
|
|
112
|
+
`)),process.stdout.write(p(` [5/5] GitHub Copilot OTEL Configure VS Code telemetry
|
|
113
|
+
`)),Zt(1,r,"Claude Code Installation"),!ar())return Ao("Claude Code is not installed or not found in PATH."),process.stdout.write(`
|
|
114
|
+
`),process.stdout.write(b(` Cannot continue \u2014 Claude Code is required.
|
|
113
115
|
|
|
114
116
|
`)),process.stdout.write(` Install it with:
|
|
115
117
|
|
|
@@ -117,53 +119,53 @@
|
|
|
117
119
|
|
|
118
120
|
`)),process.stdout.write(` More info: https://docs.anthropic.com/en/docs/claude-code
|
|
119
121
|
|
|
120
|
-
`),1;let s=
|
|
122
|
+
`),1;let s=cr();Nt(s?`Already installed (${s}) \u2014 skipping.`:"Already installed \u2014 skipping."),Zt(2,r,"Flow Environment Setup");let i=false;{let T=fr().FLOW_BASE_URL;if(T&&(pr(`Base URL already configured (FLOW_BASE_URL=${T})`),!t.noInteractive&&pt()))try{let{promptRaw:k}=await Promise.resolve().then(()=>(Oe(),_e));i=(await k(v(" ? ")+"Replace existing base URL configuration? [y/N]: ")).trim().toLowerCase()==="y",i||Qt("Keeping existing base URL configuration.");}catch{}}if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"&&process.stdout.write(R(` \u26A0 WSL detected. If Claude Code is installed on Windows, install flow-ai-obs
|
|
121
123
|
`)+R(" on Windows too: ")+v(`npm install -g @ciandt-flow/flow-ai-obs
|
|
122
124
|
`)+R(` Running Claude (Windows) + flow-ai-obs (WSL) is not a supported configuration.
|
|
123
125
|
|
|
124
|
-
`)),
|
|
125
|
-
Current base URL: ${
|
|
126
|
-
`),await
|
|
127
|
-
`),await
|
|
128
|
-
`);}if(!n&&!t.noInteractive&&!
|
|
126
|
+
`)),ko(),!n&&!t.noInteractive&&pt()){let T=te();try{i?n=await un():T?(process.stdout.write(`
|
|
127
|
+
Current base URL: ${b(T)}
|
|
128
|
+
`),await $e(" Keep this URL?",!0)||(n=await un())):(process.stdout.write(`
|
|
129
|
+
`),await $e(" Does your organization use a custom Flow URL?",!1)?n=await un():Nt("Using default Flow Base URL: https://flow.ciandt.com"));}catch{return 1}process.stdout.write(`
|
|
130
|
+
`);}if(!n&&!t.noInteractive&&!pt()){let T=te();if(T)process.stdout.write(R(` \u26A0 Non-interactive environment detected.
|
|
129
131
|
`)+p(` Using URL: ${T}
|
|
130
132
|
|
|
131
133
|
`));else return process.stderr.write(` \u2717 No URL configured and no TTY available.
|
|
132
134
|
Run: flow-ai-obs init --custom-url <URL>
|
|
133
135
|
|
|
134
|
-
`),1}let o,
|
|
135
|
-
\u2717 Invalid --custom-url: ${
|
|
136
|
+
`),1}let o,c=false;if(n){let T;try{T=dn(n,!0);}catch(Q){return process.stderr.write(`
|
|
137
|
+
\u2717 Invalid --custom-url: ${Q.message}
|
|
136
138
|
|
|
137
|
-
`),1}let k=
|
|
139
|
+
`),1}let k=te();o=T,c=!!k&&k!==T,c?process.stdout.write(R(` \u26A0 Base URL changed \u2014 re-authentication required.
|
|
138
140
|
`)+p(` Previous: ${k}
|
|
139
141
|
`)+p(` New: ${T}
|
|
140
142
|
|
|
141
|
-
`)):process.stdout.write(
|
|
143
|
+
`)):process.stdout.write(P(` \u2713 Base URL configured: ${T}
|
|
142
144
|
|
|
143
|
-
`));}else o=
|
|
145
|
+
`));}else o=te()??"https://flow.ciandt.com";let a={FLOW_BASE_URL:o,OTEL_EXPORTER_OTLP_ENDPOINT:`${o}/otel`,ANTHROPIC_BASE_URL:`${o}/flow-llm-proxy/`,ANTHROPIC_MODEL:"anthropic.claude-4-6-sonnet",ANTHROPIC_SMALL_FAST_MODEL:"anthropic.claude-4-6-haiku",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"};process.env.FLOW_BASE_URL=o,process.stdout.write(P(`
|
|
144
146
|
\u2713 Flow environment ready.
|
|
145
|
-
`));let d=36;for(let[T,k]of Object.entries(
|
|
146
|
-
`);
|
|
147
|
+
`));let d=36;for(let[T,k]of Object.entries(a))process.stdout.write(p(` ${T.padEnd(d)}`)+k+`
|
|
148
|
+
`);Zt(3,r,"Authentication");let h=null,O=te(),w=!!O&&O!==o;if(!mr()||c||w){if(t.noInteractive||!pt())return process.stderr.write(`
|
|
147
149
|
${I("\u2717")} Authentication required.
|
|
148
150
|
Run: flow-ai-obs login
|
|
149
151
|
|
|
150
152
|
`),1;{process.stdout.write(`
|
|
151
153
|
${R("\u26A0")} Authentication required for the new endpoint.
|
|
152
154
|
|
|
153
|
-
`);let{runLogin:T}=await Promise.resolve().then(()=>(
|
|
154
|
-
${
|
|
155
|
-
`);let
|
|
155
|
+
`);let{runLogin:T}=await Promise.resolve().then(()=>(Oe(),_e)),k=await T({deferPersist:true,skipAuthCheck:c});if(typeof k=="number")return k;h=k.result;}}else Nt("Already authenticated \u2014 skipping."),Qt("ANTHROPIC_AUTH_TOKEN will be preserved in settings.json");let u=mr()?fr()[g.ANTHROPIC_AUTH_TOKEN]:null,E={...a,...h?{[g.ANTHROPIC_AUTH_TOKEN]:h.jwt}:{},...u&&!h?{[g.ANTHROPIC_AUTH_TOKEN]:u}:{}},q,U;Zt(4,r,"Observability (OpenTelemetry)"),process.stdout.write(`
|
|
156
|
+
${b("Metrics and Logs")}
|
|
157
|
+
`);let Z={...et,OTEL_EXPORTER_OTLP_ENDPOINT:a.OTEL_EXPORTER_OTLP_ENDPOINT};for(let[T,k]of Object.entries(Z))process.stdout.write(p(` ${T.padEnd(36)}`)+k+`
|
|
156
158
|
`);process.stdout.write(`
|
|
157
|
-
`),process.stdout.write(` ${
|
|
158
|
-
`);let
|
|
159
|
+
`),process.stdout.write(` ${b("Trace (Hook)")}
|
|
160
|
+
`);let At=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"];for(let T of At){let k=mt[T];process.stdout.write(p(` ${T.padEnd(18)}`)+`\u2192 flow-ai-obs ${T} (timeout: ${k}s)
|
|
159
161
|
`);}process.stdout.write(`
|
|
160
|
-
`);try{({settingsPath:
|
|
161
|
-
`),1}if(h){let{saveTokenCache:T}=await Promise.resolve().then(()=>(
|
|
162
|
-
`),process.stdout.write(R(` \u26A0 Third-party hooks preserved on: ${
|
|
162
|
+
`);try{({settingsPath:q,preserved:U}=Vn(a.OTEL_EXPORTER_OTLP_ENDPOINT,E));}catch(T){return process.stderr.write(` \u2717 Failed to write settings: ${T.message}
|
|
163
|
+
`),1}if(h){let{saveTokenCache:T}=await Promise.resolve().then(()=>(Xt(),sr));await T({accessToken:h.accessToken,expiresAt:h.expiresAt});let{clearLoggedOutMarker:k}=await Promise.resolve().then(()=>(an(),dr));k();}Nt(`Settings written: ${q}`),U.length>0&&(process.stdout.write(`
|
|
164
|
+
`),process.stdout.write(R(` \u26A0 Third-party hooks preserved on: ${U.join(", ")}
|
|
163
165
|
`)),process.stdout.write(p(` flow-ai-obs was prepended \u2014 it executes first.
|
|
164
166
|
`))),process.stdout.write(`
|
|
165
|
-
`),t.skipHint||(process.stdout.write(`
|
|
166
|
-
`),process.stdout.write(
|
|
167
|
+
`),Zt(5,r,"GitHub Copilot OTEL (VS Code telemetry)");let X=Wn(a.OTEL_EXPORTER_OTLP_ENDPOINT);return X.status==="configured"?(Nt("GitHub Copilot OTEL configured."),Qt("VS Code settings now include the OTEL endpoint.")):X.status==="already_configured"?Nt("Already configured \u2014 skipping."):(pr(`Skipped: ${X.reason??"VS Code not found"}.`),X.reason?.includes("could not be parsed")?Qt("Remove comments from VS Code settings.json and re-run init, or add the keys manually."):Qt("Install VS Code and re-run init to enable Copilot telemetry.")),t.skipHint||(process.stdout.write(`
|
|
168
|
+
`),process.stdout.write(P(` \u2713 Setup complete.
|
|
167
169
|
|
|
168
170
|
`)),process.stdout.write(p(` Verify your configuration:
|
|
169
171
|
`)+v(` flow-ai-obs status
|
|
@@ -171,53 +173,53 @@
|
|
|
171
173
|
`)+p(` Start Claude Code:
|
|
172
174
|
`)+v(` claude
|
|
173
175
|
|
|
174
|
-
`))),0}var
|
|
175
|
-
`);}function
|
|
176
|
-
`);}function
|
|
177
|
-
`);}function
|
|
178
|
-
`);}function
|
|
179
|
-
`);}function
|
|
180
|
-
`);}function
|
|
176
|
+
`))),0}var Er=m(()=>{"use strict";Gt();L();Yn();dt();pe();de();Ye();W();lr();Fe();});var Tr={};$(Tr,{runStatus:()=>vo});function Sr(t){return !t||t.length<=8?"****":t.slice(0,4)+"****...****"+t.slice(-4)}function Ro(t){process.stdout.write(` ${P("\u2713")} ${t}
|
|
177
|
+
`);}function pn(t){process.stdout.write(` ${R("\u26A0")} ${t}
|
|
178
|
+
`);}function Ut(t){process.stdout.write(` ${P("\u2713")} ${t}
|
|
179
|
+
`);}function ee(t){process.stdout.write(` ${R("\u26A0")} ${t}
|
|
180
|
+
`);}function ne(t){process.stdout.write(` ${I("\u2717")} ${t}
|
|
181
|
+
`);}function ot(t){process.stdout.write(` ${p(t)}
|
|
182
|
+
`);}function fn(t){process.stdout.write(b(v(`
|
|
181
183
|
${t}
|
|
182
|
-
`)));}function
|
|
184
|
+
`)));}function mn(t,e=false){let n=e?`${R("\u26A0")} ${b(R(t))}`:b(t);process.stdout.write(`
|
|
183
185
|
${n}
|
|
184
|
-
`);}function
|
|
185
|
-
`);}async function
|
|
186
|
+
`);}function Ae(){process.stdout.write(`
|
|
187
|
+
`);}async function vo(){fn("Auth");let t=await Te();t.notConfigured?(pn("Not configured."),process.stdout.write(`
|
|
186
188
|
`),process.stdout.write(` ${p("Run `flow-ai-obs init` to set up.")}
|
|
187
|
-
`)):!t.ok&&t.error==="No credentials found"?
|
|
189
|
+
`)):!t.ok&&t.error==="No credentials found"?pn("Not authenticated. Run `flow-ai-obs login` to set up."):t.ok?(Ro("Authenticated"),process.stdout.write(` ${p("URL: ")}${t.baseUrl}
|
|
188
190
|
`),process.stdout.write(` ${p("Tenant: ")}${t.tenant}
|
|
189
191
|
`),process.stdout.write(` ${p("User: ")}${t.user}
|
|
190
192
|
`),process.stdout.write(` ${p("Storage: ANTHROPIC_AUTH_TOKEN (settings.json)")}
|
|
191
|
-
`)):
|
|
193
|
+
`)):pn(`Session rejected by ${t.baseUrl}. Run \`flow-ai-obs login\` to re-authenticate.`),fn("Flow Provider Configuration");let e=["ANTHROPIC_BASE_URL","ANTHROPIC_MODEL","ANTHROPIC_SMALL_FAST_MODEL","CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS"],n={},r={};try{let u=A__namespace.readFileSync(B(),"utf8");r=JSON.parse(u),n=r.env||{};}catch{}let s=e.filter(u=>!n[u]),i=s.length===0;mn("LLM Proxy",!i),i?(Ut("Flow LLM Proxy configured"),ot(`Endpoint: ${n.ANTHROPIC_BASE_URL}`),ot(`Model: ${n.ANTHROPIC_MODEL}`)):(process.stdout.write(`
|
|
192
194
|
`),process.stdout.write(` ${p("Run: flow-ai-obs init (configures the Flow LLM proxy)")}
|
|
193
195
|
`),process.stdout.write(`
|
|
194
|
-
`),
|
|
195
|
-
`);}
|
|
196
|
+
`),ee(`${s.length} proxy var(s) missing from settings.json`),s.forEach(u=>ne(`Missing: ${u}`))),Ae();for(let u of e){let E=n[u]??I("(missing)");process.stdout.write(p(` ${u.padEnd(36)}`)+E+`
|
|
197
|
+
`);}fn("Observability configuration (OpenTelemetry)");let o=Object.keys(et).filter(u=>!n[u]);mn("Metrics and Logs",o.length>0),o.length===0?(Ut("All OTEL env vars present in settings.json"),ot(`Endpoint: ${n.OTEL_EXPORTER_OTLP_ENDPOINT}`)):(process.stdout.write(`
|
|
196
198
|
`),process.stdout.write(` ${p("Run: flow-ai-obs init (restores missing vars automatically)")}
|
|
197
199
|
`),process.stdout.write(`
|
|
198
|
-
`),
|
|
199
|
-
`);}let
|
|
200
|
+
`),ee(`${o.length} OTEL var(s) missing from settings.json`),o.forEach(u=>ne(`Missing: ${u}`))),Ae();for(let u of Object.keys(et)){let E=n[u]??I("(missing)");process.stdout.write(p(` ${u.padEnd(36)}`)+E+`
|
|
201
|
+
`);}let c=r.hooks??{},a=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],d=a.every(u=>{let E=c[u];return Array.isArray(E)?E.some(q=>{let U=q;return Array.isArray(U?.hooks)&&U.hooks.some(Z=>Z?.command?.startsWith(Wt.CLI))}):false});mn("Tracing",!d),d?Ut("Hooks registered (trace capture)"):(process.stdout.write(`
|
|
200
202
|
`),process.stdout.write(` ${p("Run `flow-ai-obs init` to configure.")}
|
|
201
203
|
`),process.stdout.write(`
|
|
202
|
-
`),
|
|
203
|
-
`);}
|
|
204
|
-
`),1;let e;try{e=(await
|
|
204
|
+
`),ee("Hooks NOT registered."));for(let u of a){let E=mt[u];process.stdout.write(p(` ${u.padEnd(18)}`)+`\u2192 flow-ai-obs ${u} (timeout: ${E}s)
|
|
205
|
+
`);}Ae();let h=process.env[g.FLOW_TELEMETRY]==="true",O=process.env[g.LANGFUSE_BASE_URL],w=process.env[g.LANGFUSE_PUBLIC_KEY],S=process.env[g.LANGFUSE_SECRET_KEY];if(h)if(O&&w&&S){let u=await K();for(let E of u)E.mode==="direct"&&(Ut("FLOW_TELEMETRY=true (direct mode enabled)"),Ut("Mode: direct"),ot(`Endpoint: ${E.endpoint}`),ot(`PK: ${Sr(w)}`),ot(`SK: ${Sr(S)}`));}else ee("FLOW_TELEMETRY=true but missing LANGFUSE vars:"),O||ne("LANGFUSE_BASE_URL not set"),w||ne("LANGFUSE_PUBLIC_KEY not set"),S||ne("LANGFUSE_SECRET_KEY not set");else {let u=await K();if(u.length>0)for(let E of u)E.mode==="gateway"&&(Ut("Mode: gateway"),ot(`Endpoint: ${E.endpoint}`));else u.authError?ee("Gateway mode: token refresh failed. Run `flow-ai-obs login`."):ot("No active tracing destination configured.");}return Ae(),0}var yr=m(()=>{"use strict";W();Gt();L();dt();ln();});var _r={};$(_r,{runOtelHeaders:()=>Po});async function Po(){let t=st(process.env[g.ANTHROPIC_AUTH_TOKEN]);if(!t)return process.stderr.write(`[flow-ai-obs otel-headers] Not authenticated \u2014 run: flow-ai-obs auth login
|
|
206
|
+
`),1;let e;try{e=(await D(t)).accessToken;}catch(n){return process.stderr.write(`[flow-ai-obs otel-headers] Token fetch failed: ${n.message}
|
|
205
207
|
`),1}return e?(process.stdout.write(`{"Authorization": "Bearer ${e}"}
|
|
206
208
|
`),0):(process.stderr.write(`[flow-ai-obs otel-headers] Empty token received
|
|
207
|
-
`),1)}var
|
|
208
|
-
`)[0].slice(0,e).trim()}function
|
|
209
|
-
`);for(let n=e.length-1;n>=0;n--)try{let r=JSON.parse(e[n]);if(r.type==="user"&&r.uuid)return r.uuid}catch{}}catch{}return null}function
|
|
210
|
-
`),n=[],r=0,s=0;for(let i=e.length-1;i>=0;i--)try{let o=JSON.parse(e[i]);if(o.type==="user")break;if(o.type==="assistant"){let
|
|
211
|
-
|
|
212
|
-
`),inputTokens:r,outputTokens:s}}catch{}return null}var
|
|
213
|
-
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function
|
|
214
|
-
`);return}let r=!!(await
|
|
215
|
-
`,{flag:"a",encoding:"utf8",mode:384}),l("sendTraces:dump",`request appendada em ${
|
|
216
|
-
${
|
|
217
|
-
${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${
|
|
218
|
-
`)),u=d?.inputTokens??0,E=d?.outputTokens??0,
|
|
219
|
-
`),process.stdin.on("data",e=>process.stdout.write(e));}}var
|
|
220
|
-
`),process.exit(0);});});var
|
|
209
|
+
`),1)}var Or=m(()=>{"use strict";ht();W();L();});function J(t,e){let n=typeof t=="object"?JSON.stringify(t):String(t??"");return n.length>e?n.slice(0,e)+" \u2026[truncated]":n}function ke(t,e=100){return String(t??"").split(`
|
|
210
|
+
`)[0].slice(0,e).trim()}function re(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n;}),process.stdin.on("end",()=>{try{t(JSON.parse(e));}catch{t({});}});})}function G(t){process.stdout.write(JSON.stringify(t));}var $t=m(()=>{"use strict";});function it(){return String(BigInt(Date.now())*1000000n)}var gn,Tt,se=m(()=>{"use strict";gn=()=>crypto.randomBytes(16).toString("hex"),Tt=()=>crypto.randomBytes(8).toString("hex");});function Mo(t,e){let n=bt.resolve(t);if(!n.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return n}function hn(t){if(!Do.test(t))throw new Error(`Invalid session ID: ${t}`);return Mo(bt.join(Et.tmpdir(),`flow-obs-${t}.json`),Bo)}function Ft(t){let e=hn(t);if(!A.existsSync(e))return null;try{return JSON.parse(A.readFileSync(e,"utf8"))}catch{return null}}function xt(t,e){A.writeFileSync(hn(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function En(t){try{A.unlinkSync(hn(t));}catch{}}var Do,Bo,oe=m(()=>{"use strict";Do=/^[0-9a-f-]{1,64}$/i,Bo=bt.normalize(Et.tmpdir())+bt.sep;});function vr(t){if(!t||!A.existsSync(t))return null;try{let e=A.readFileSync(t,"utf8").trimEnd().split(`
|
|
211
|
+
`);for(let n=e.length-1;n>=0;n--)try{let r=JSON.parse(e[n]);if(r.type==="user"&&r.uuid)return r.uuid}catch{}}catch{}return null}function Sn(t){if(!t||!A.existsSync(t))return null;try{let e=A.readFileSync(t,"utf8").trimEnd().split(`
|
|
212
|
+
`),n=[],r=0,s=0;for(let i=e.length-1;i>=0;i--)try{let o=JSON.parse(e[i]);if(o.type==="user")break;if(o.type==="assistant"){let a=(o.message?.content??[]).filter(h=>h.type==="text").map(h=>h.text??"").join("");a&&n.unshift(a);let d=o.message?.usage??{};r+=(d.input_tokens??0)+(d.cache_read_input_tokens??0)+(d.cache_creation_input_tokens??0),s+=d.output_tokens??0;}}catch{}return !n.length&&r===0?null:{text:n.join(`
|
|
213
|
+
|
|
214
|
+
`),inputTokens:r,outputTokens:s}}catch{}return null}var wn=m(()=>{"use strict";});function Ir(t){return t.replace(":","/")}function Le(t,e){if(!t)return null;let n=Ir(t),r=[bt.join(Et.homedir(),".claude","skills",n,"SKILL.md"),bt.join(e??"",".claude","skills",n,"SKILL.md")];for(let s of r)if(A.existsSync(s))try{return A.readFileSync(s,"utf8")}catch{}return null}function Cr(t){return t.split(`
|
|
215
|
+
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function Nr(t){return !!t.slashSkill||t.toolCalls.some(r=>r.tool==="Skill")?t.toolCalls.some(r=>r.tool==="Skill"&&!r.synthetic||Ko.has(r.tool))?"complete":"prerequisite_required":null}function Re(t,e){if(!t)return null;let n=Ir(t),r=[bt.join(Et.homedir(),".claude","skills",n),bt.join(e??"",".claude","skills",n)],s=null;for(let c of r)if(A.existsSync(bt.join(c,"SKILL.md"))){s=c;break}if(!s)return null;let i=[];function o(c,a){for(let d of A.readdirSync(c,{withFileTypes:true})){if(Wo.has(d.name)||Go.has(d.name)||Yo.has(bt.extname(d.name)))continue;let h=a?`${a}/${d.name}`:d.name;d.isDirectory()?o(bt.join(c,d.name),h):i.push(h);}}return o(s,""),i.length>0?i:null}var Wo,Yo,Go,Ko,ve=m(()=>{"use strict";Wo=new Set([".venv","__pycache__",".git","node_modules"]),Yo=new Set([".pyc",".pyo"]),Go=new Set(["SKILL.md",".DS_Store",".gitignore"]);Ko=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);});function Xo(t){try{let e=t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(e,"base64").toString())}catch{return null}}function zo(t,e,n,r){return new Promise(s=>{let i=new URL(t),o=i.protocol==="https:",c=(o?Ts__default.default:Bs__default.default).request({hostname:i.hostname,port:i.port||(o?443:80),path:i.pathname+i.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,"")}},a=>{a.resume(),s(a.statusCode??0);});c.on("error",()=>s(0)),c.setTimeout(5e3,()=>{c.destroy(),s(0);}),c.write(e),c.end();})}async function yt(t,e={}){try{let n=st(process.env[g.ANTHROPIC_AUTH_TOKEN]);if(!n)return;let r,s=new Promise((O,w)=>{r=setTimeout(()=>w(new Error("getToken timeout")),4e3),r.unref();}),{accessToken:i}=await Promise.race([D(n),s]);clearTimeout(r);let o=Xo(i);if(!o)return;let c=o.tenant||n.tenant,a=JSON.stringify({action:t,booster:le().BOOSTER,metadata:e,success:!0,tenant:c,timestamp:new Date().toISOString(),os:process.platform,user:{email:o.email||"",id:o.sub||"",name:o.name||o.email||""}}),d=wt(le().API_URL),h=await zo(d,a,i,c);l("metrics.logEvent",`action=${t} status=${h}`);}catch(n){l("metrics.logEvent",`silenced error: ${n.message}`);}}var Pe=m(()=>{"use strict";L();ht();W();V();});async function Tn(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:Zo})+`
|
|
216
|
+
`);return}let r=!!(await K()).authError,s=t.session_id||"unknown",i=t.prompt||"",o=t.cwd||"",c=vr(t.transcript_path)||gn(),a=Cr(i),d=a?Le(a,o):null,h=a?Re(a,o):null;xt(s,{traceId:gn(),spanId:Tt(),startNs:it(),sessionId:s,prompt:i,cwd:o,traceName:c,transcriptPath:t.transcript_path||"",model:process.env[g.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:a,skillContent:d,skillArtifacts:h}),yt("SESSION_STARTED",{traceType:a?"skill":"prompt",slashSkill:a,clientIdExpired:r}),l("UserPromptSubmit",`sid=${s}`,`traceName=${c}`,`slashSkill=${a}`),G(t);}var Zo,Ur=m(()=>{"use strict";se();oe();wn();ve();$t();V();L();W();Pe();Zo=`\u26D4 Your Flow API key has expired. You no longer have access to Claude Code through the Flow platform. To restore observability and access, visit ${tt()}/settings/api-keys to generate a new API key, then run: flow-ai-obs login`;});async function $r(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},s=Ft(e);s&&(s.pendingTool={name:n,inputStr:J(r,j.TOOL_INPUT),startNs:it()},xt(e,s)),l("PreToolUse",`sid=${e}`,`tool=${n}`,`stateFound=${!!s}`),G(t);}var Fr=m(()=>{"use strict";se();oe();$t();V();L();});function f(t,e){return e==null||e===""?null:{key:t,value:{stringValue:String(e)}}}function _t(...t){return t.filter(e=>e!==null)}function xr(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:Qo,spans:Array.isArray(e)?e:[e]}]}]}}var Qo,_,Dr=m(()=>{"use strict";L();Qo={name:ce.SCOPE_NAME,version:ce.SCOPE_VERSION},_={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 Mr(t,e,n,r,s){if(process.env[g.FLOW_OBS_DEBUG]!=="1")return;let i=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(n)},response:{status:r,body:s}});try{A.writeFileSync(Br,i+`
|
|
217
|
+
`,{flag:"a",encoding:"utf8",mode:384}),l("sendTraces:dump",`request appendada em ${Br}`);}catch(o){l("sendTraces:dump",`falha ao salvar: ${o.message}`);}}function oi(t){let e=new URL(t),n=new URL(ft().GATEWAY_HEALTH);return n.hostname=e.hostname,n.port=e.port,n.protocol=e.protocol,n}function Hr(t,e){return new Promise((n,r)=>{let s=t._isSSL?Ts__default.default:Bs__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let i=s.request(t,o=>{let c=[];o.on("data",a=>c.push(a)),o.on("end",()=>n({statusCode:o.statusCode??0,body:c.join("")}));});i.setTimeout(1e4,()=>{i.destroy(new Error("Request timeout"));}),i.on("error",o=>r(new Error(`Network error: ${o.message}`))),e&&i.write(e),i.end();})}async function jr(t,e){let n;try{n=oi(t);}catch{return false}let r=n.protocol==="https:";try{let s={};e&&(s.Authorization=String(e).replace(/[\r\n]/g,""));let i=await Hr({hostname:n.hostname,port:n.port||(r?443:80),path:n.pathname,method:"GET",headers:s,_isSSL:r},null);return l("checkHealth",`url=${n.href} status=${i.statusCode}`),i.statusCode>=200&&i.statusCode<300}catch{return false}}async function be(t,e,n){let r=JSON.stringify(t),s=new URL(e),i=s.protocol==="https:",o=String(n).replace(/[\r\n]/g,""),c={"Content-Type":"application/json",Authorization:o,"Content-Length":Buffer.byteLength(r)};l("sendTraces:request",`POST ${e}`),l("sendTraces:request",`headers=${JSON.stringify({...c,Authorization:o.slice(0,20)+"\u2026"})}`),l("sendTraces:request",`body=${r.slice(0,500)}${r.length>500?"\u2026":""}`);try{let a=await Hr({hostname:s.hostname,port:s.port||(i?443:80),path:s.pathname,method:"POST",headers:c,_isSSL:i},r);return l("sendTraces:response",`status=${a.statusCode}`),Mr(e,c,r,a.statusCode,a.body),a.statusCode}catch(a){return l("sendTraces:error",a.message),Mr(e,c,r,0,a.message),0}}var Br,Vr=m(()=>{"use strict";L();V();Br=bt.join(Et.tmpdir(),"flow-obs-requests.ndjson");});function ii(){let t=parseInt(process.env[g.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(x.MIN_TTL_DAYS,Math.min(x.MAX_TTL_DAYS,t)):x.DEFAULT_TTL_DAYS)*24*60*60*1e3}function ai(){let t=parseInt(process.env[g.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(x.MIN_MAX_FILES,Math.min(x.MAX_MAX_FILES,t)):x.DEFAULT_MAX_FILES}function Yr(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return bt__namespace.default.join(Et__namespace.default.tmpdir(),`${x.FILE_PREFIX}${t}.json`)}function _n(){let t=Et__namespace.default.tmpdir(),e;try{e=A__namespace.default.readdirSync(t);}catch{return []}return e.filter(n=>n.startsWith(x.FILE_PREFIX)&&n.endsWith(".json")).map(n=>{let r=bt__namespace.default.join(t,n),s=0;try{s=A__namespace.default.statSync(r).mtimeMs;}catch{}return {full:r,mtime:s}}).sort((n,r)=>n.mtime-r.mtime).map(n=>n.full)}function ie(t){try{let e=ai(),n=_n();if(n.length>=e){let i=n.slice(0,n.length-e+1);for(let o of i)try{A__namespace.default.unlinkSync(o);}catch{}}let r=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:r,bufferedAt:Date.now(),payload:t};return A__namespace.default.writeFileSync(Yr(r),JSON.stringify(s),{encoding:"utf8",mode:384}),l("buffer",`saved fileId=${r}`),r}catch(e){return l("buffer",`saveToBuffer failed: ${e.message}`),null}}function Gr(t){let e=_n(),n=t!=null&&t>0?t:e.length,r=[];for(let s of e){if(r.length>=n)break;try{let i=A__namespace.default.readFileSync(s,"utf8"),o=JSON.parse(i);o&&o.fileId&&o.payload&&r.push(o);}catch{l("buffer",`skipping malformed file: ${s}`);}}return r}function Kr(t){try{A__namespace.default.unlinkSync(Yr(t)),l("buffer",`deleted fileId=${t}`);}catch{}}function Jr(){let t=Date.now()-ii();for(let e of _n())try{let{mtimeMs:n}=A__namespace.default.statSync(e);n<t&&(A__namespace.default.unlinkSync(e),l("buffer",`evicted stale: ${bt__namespace.default.basename(e)}`));}catch{}}var qr=m(()=>{"use strict";L();V();});async function ci(t){Jr();let e=Gr(x.REPLAY_BATCH_SIZE);e.length&&(l("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async n=>{try{let r=await be(n.payload,t.endpoint,t.authHeader);r>=200&&r<300?(Kr(n.fileId),l("replayBufferedTraces",`replayed fileId=${n.fileId} status=${r}`)):l("replayBufferedTraces",`replay failed fileId=${n.fileId} status=${r}`);}catch(r){l("replayBufferedTraces",`replay error fileId=${n.fileId}: ${r.message}`);}})));}async function Xr(t){let e=await K();if(!e.length)return e.authError&&(l("postToLangfuse","auth refresh failed \u2014 buffering trace"),ie(t)),0;let n=await Promise.all(e.map(async i=>{if(i.mode!=="gateway")return {creds:i,healthy:true};let o=await jr(i.endpoint,i.authHeader);return {creds:i,healthy:o}})),r=n.find(i=>i.creds.mode==="gateway"&&i.healthy)?.creds??n.find(i=>i.creds.mode==="direct")?.creds;return r&&await ci(r),(await Promise.all(n.map(async({creds:i,healthy:o})=>{if(i.mode==="gateway"){if(!o)return l("postToLangfuse","gateway health check failed \u2014 buffering trace"),ie(t),0;let a=await be(t,i.endpoint,i.authHeader);return (a===0||a>=500)&&(l("postToLangfuse",`gateway send failed (status ${a}) \u2014 buffering trace`),ie(t)),a}let c=await be(t,i.endpoint,i.authHeader);return (c===0||c>=500)&&(l("postToLangfuse",`direct endpoint unavailable (status ${c}) \u2014 buffering trace`),ie(t)),c}))).find(i=>i!==0)??0}var zr=m(()=>{"use strict";W();V();Vr();qr();L();});var On=m(()=>{"use strict";Dr();zr();});function ct(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return pi.reduce((n,{re:r,replace:s})=>n.replace(r,s),e)}var M,li,ui,di,Zr,pi,An=m(()=>{"use strict";M="[REDACTED]",li="[REDACTED-EMAIL]",ui="[REDACTED-CPF]",di="[REDACTED-CNPJ]",Zr="[REDACTED-PHONE]",pi=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${M}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${M}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${M}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${M}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,n)=>`${e}
|
|
218
|
+
${M}
|
|
219
|
+
${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${M}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${M}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${M}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${M}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${M}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(t,e,n)=>`${e}${n}${M}${n}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${M}@`},{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:()=>ui},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>di},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>Zr},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>Zr}];});async function Qr(t){let e=t.session_id||"unknown",n=t.tool_name||"unknown",r=t.tool_input||{},s=t.tool_response,i=s!==null&&typeof s=="object"?s.output??JSON.stringify(s):s??"",o=Ft(e);if(!o){G(t);return}let c=it(),a=o.pendingTool,d=a?.name===n,h=d?a.startNs:String(BigInt(c)-200000000n),O=d?a.inputStr:J(r,j.TOOL_INPUT),w=O,S=null;if(n==="Skill"){let ae=typeof r=="object"&&r!==null?r.skill||r.name||r.skillName||r.commandName||String(Object.values(r)[0]??""):String(r);S=ae?String(ae).trim():null;let lt=S?Le(S,o.cwd):null;lt&&(w=lt,o.skillContent||(o.skillContent=lt),o.skillArtifacts||(o.skillArtifacts=Re(S,o.cwd))),S&&!o.slashSkill&&(o.slashSkill=S),l("PostToolUse","Skill tool detected",`skillName=${S}`,`contentFound=${!!lt}`);}let u=ct(J(i,j.TOOL_OUTPUT)),E=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(u.slice(0,500)),q=E?"ERROR":"DEFAULT",U=Tt(),Z=Math.round(Number(BigInt(c)-BigInt(h))/1e6),X={Agent:"AGENT",Task:"AGENT"}[n]??"TOOL",T=n==="Skill"&&S?S:ke(O,60);o.toolCalls.push({tool:n,brief:T,error:E,durationMs:Z});let Q=o.spans;Q.push({traceId:o.traceId,spanId:U,parentSpanId:o.spanId,name:n,kind:3,startTimeUnixNano:h,endTimeUnixNano:c,attributes:_t(f(_.OBS_NAME,n),f(_.OBS_TYPE,X),f(_.OBS_LEVEL,q),f(_.OBS_INPUT,ct(w)),f(_.OBS_OUTPUT,u),f("tool.name",n),f("tool.error",String(E)),n==="Skill"&&S?f("skill.name",S):null,n==="Skill"?f("skill.invocation","slash-command"):null),status:{code:E?2:1}}),o.pendingTool=null,xt(e,o),E&&yt("TOOL_ERROR",{toolName:n}),l("PostToolUse",`sid=${e}`,`tool=${n}`,`error=${E}`,`durationMs=${Z}`,`totalSpans=${Q.length}`),G(t);}var ts=m(()=>{"use strict";se();oe();On();$t();ve();V();L();An();Pe();});function ns(t,e,n){let r=Object.keys(es).find(o=>(t??"").toLowerCase().includes(o));if(!r)return;let s=es[r],i=(e*s.input+n*s.output)/1e6;return Math.round(i*1e6)/1e6}var es,rs=m(()=>{"use strict";es={"claude-opus-4-6":{input:15,output:75},"claude-opus-4-5":{input:15,output:75},"claude-sonnet-4-6":{input:3,output:15},"claude-sonnet-4-5":{input:3,output:15},"claude-haiku-4-5":{input:.8,output:4},"claude-4-6-opus":{input:15,output:75},"claude-4-6-sonnet":{input:3,output:15},"claude-4-5-opus":{input:15,output:75},"claude-4-5-sonnet":{input:3,output:15},"claude-4-5-haiku":{input:.8,output:4},"claude-3-5-sonnet-20241022":{input:3,output:15},"claude-3-5-haiku-20241022":{input:.8,output:4},"claude-3-opus-20240229":{input:15,output:75}};});async function ss(t){let e=t.session_id||"unknown",n=t.stop_reason||"end_turn",r=Ft(e);if(!r){G(t);return}r.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(r.slashSkill)&&(l("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${r.slashSkill}"`),r.slashSkill=null);let s=it(),i=await ir(),o=r.toolCalls,c=r.spans;if(r.slashSkill&&!o.some(y=>y.tool==="Skill")){let y=Tt(),ut=r.skillContent?r.skillContent:JSON.stringify({skill:r.slashSkill});o.push({tool:"Skill",brief:r.slashSkill,error:false,durationMs:0,synthetic:true}),c.push({traceId:r.traceId,spanId:y,parentSpanId:r.spanId,name:"Skill",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:r.startNs,attributes:_t(f(_.OBS_NAME,"Skill"),f(_.OBS_TYPE,"TOOL"),f(_.OBS_LEVEL,"DEFAULT"),f(_.OBS_INPUT,ut),f(_.OBS_OUTPUT,"loaded via slash command"),f("tool.name","Skill"),f("tool.error","false"),f("skill.name",r.slashSkill),f("skill.invocation","slash-command")),status:{code:1}}),l("Stop",`slashSkill=${r.slashSkill}`,"synthetic span injected");}let a=t.transcript_path||r.transcriptPath||"",d=Sn(a);if(a&&(o.some(y=>y.tool==="Skill"&&!y.synthetic)||!!r.slashSkill)&&!d?.text){await new Promise(ut=>setTimeout(ut,500));let y=Sn(a);y?.text&&(d=y);}l("Stop",`transcriptPath=${a||"(empty)"}`,`assistantOut=${d?`text=${d.text.length}chars`:"null"}`);let O=o.length,w=o.filter(y=>y.error).length,S=ct(d?.text?J(d.text,j.TRACE_OUTPUT):O===0?"No tools used":o.map((y,ut)=>`${ut+1}. ${y.tool}${y.brief?` \u2192 ${y.brief}`:""}${y.error?" [ERROR]":""}`).join(`
|
|
220
|
+
`)),u=d?.inputTokens??0,E=d?.outputTokens??0,q=o.map((y,ut)=>`${ut+1}. ${y.tool}${y.brief?` \u2192 ${y.brief}`:""}${y.error?" [ERROR]":""} (${y.durationMs}ms)`),U=!!(r.slashSkill||o.some(y=>y.tool==="Skill")),Z=o.some(y=>y.tool==="Agent");if(!U&&!Z){l("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),yt("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),En(e),G(t);return}let At=U?"skill":"agent",X=Math.round(Number(BigInt(s)-BigInt(r.startNs))/1e6),T=ns(r.model,u,E),k=Nr(r);k==="prerequisite_required"&&d?.text&&(k="complete"),k==="prerequisite_required"&&(c.push({traceId:r.traceId,spanId:Tt(),parentSpanId:r.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:r.startNs,endTimeUnixNano:s,attributes:_t(f(_.OBS_NAME,"prerequisite-check"),f(_.OBS_TYPE,"EVENT"),f(_.OBS_LEVEL,"WARNING"),f(_.OBS_OUTPUT,S),f("skill.name",r.slashSkill||void 0),f("execution_status","prerequisite_required")),status:{code:1}}),l("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${r.slashSkill}`));let Q=(()=>{if(!(!U||!r.prompt)){if(r.slashSkill){let y=r.prompt.replace(new RegExp(`^\\/${r.slashSkill}\\s*`,"i"),"").trim();return y?J(ct(y),j.USER_INSTRUCTION):void 0}return J(ct(r.prompt),j.USER_INSTRUCTION)||void 0}})(),ae=JSON.stringify({trace_type:At,...k!==null&&{execution_status:k},...r.slashSkill?{skill_name:r.slashSkill}:{},...r.skillArtifacts?.length&&{skill_artifacts:r.skillArtifacts},...Q!==void 0&&{user_instruction:Q},latency_ms:X,...u&&{tokens_input:u},...E&&{tokens_output:E},cost_usd:T,...r.model?{model:r.model}:{},toolCount:O,errorCount:w,stopReason:n,sessionId:r.sessionId,tools:q.length?q:void 0}),lt=ct(J(r.prompt,j.TRACE_INPUT)),ls=_t(f(_.TRACE_NAME,r.traceName),f(_.TRACE_INPUT,lt),f(_.TRACE_OUTPUT,S),f(_.OBS_INPUT,lt),f(_.OBS_OUTPUT,S),f(_.TRACE_METADATA,ae),f(_.SESSION_ID,r.sessionId),f(_.USER_ID,i.user),f(_.OBS_TYPE,"GENERATION"),f(_.MODEL,r.model),u?f(_.INPUT_TOKENS,u):null,E?f(_.OUTPUT_TOKENS,E):null,f("claude.stop_reason",n),f("claude.tool_count",String(O)),f("claude.error_count",String(w)),f("claude.session_id",r.sessionId),f("flow.trace_type",At),{key:_.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:At}]}}}),us={traceId:r.traceId,spanId:r.spanId,name:r.traceName,kind:1,startTimeUnixNano:r.startNs,endTimeUnixNano:s,attributes:ls,status:{code:w>0?2:1}},ds=_t(f("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),f("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),kn=[...c,us];l("Stop",`sid=${e}`,`totalTools=${O}`,`errorTools=${w}`,`spans=${kn.length}`,`inputTokens=${u}`,`outputTokens=${E}`,`traceOutput="${ke(S,80)}"`);let ps=await Xr(xr(ds,kn));l("Stop",`POST status=${ps}`,`traceId=${r.traceId}`),yt("TRACE_SENT",{latencyMs:X,totalTools:O,errorTools:w,inputTokens:u,outputTokens:E,costUsd:T}),En(e),G(t);}var os=m(()=>{"use strict";se();oe();On();W();rs();wn();$t();V();ve();An();L();Pe();});var Ot,is=m(()=>{"use strict";W();$t();Ur();Fr();ts();os();Ot=class t{static passthroughStdin(){let e=[];process.stdin.on("data",n=>e.push(n)),process.stdin.on("end",()=>process.stdout.write(Buffer.concat(e)));}static async userPromptSubmit(){let e=await re(),n;try{n=await K();}catch{process.stdout.write(JSON.stringify(e));return}n.authError?await Tn(e,!0):n.length>0?await Tn(e):process.stdout.write(JSON.stringify(e));}static async preToolUse(){if(!await Ee()){t.passthroughStdin();return}let e=await re();await $r(e);}static async postToolUse(){if(!await Ee()){t.passthroughStdin();return}let e=await re();await Qr(e);}static async stop(){if(!await Ee()){t.passthroughStdin();return}let e=await re();await ss(e);}};});var mi={};async function fi(){let t=process.argv[2];switch(t){case "UserPromptSubmit":await Ot.userPromptSubmit();break;case "PreToolUse":await Ot.preToolUse();break;case "PostToolUse":await Ot.postToolUse();break;case "Stop":await Ot.stop();break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
|
|
221
|
+
`),process.stdin.on("data",e=>process.stdout.write(e));}}var as=m(()=>{"use strict";is();fi().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
|
|
222
|
+
`),process.exit(0);});});var gi=new Set(["UserPromptSubmit","PreToolUse","PostToolUse","Stop"]),[,,H]=process.argv;function Ie(t,e){let n=t.indexOf(e);return n!==-1?t[n+1]:void 0}function cs(){let{bold:t,cyan:e,dim:n,green:r}=(dt(),C(Ne)),{version:s}=Mt();process.stdout.write(`
|
|
221
223
|
`+t(" flow-ai-obs")+n(" v"+s)+`
|
|
222
224
|
|
|
223
225
|
`),process.stdout.write(e(" init")+n(` Configure environment: Claude Code + Proxy + OTEL + Trace hooks
|
|
@@ -232,16 +234,16 @@ ${n}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${B}`},{re:/(aws_secret_ac
|
|
|
232
234
|
|
|
233
235
|
`)),process.stdout.write(n(` (Hook events: UserPromptSubmit | PreToolUse | PostToolUse | Stop)
|
|
234
236
|
|
|
235
|
-
`));}if(
|
|
236
|
-
`);let e=(
|
|
237
|
+
`));}if(H==="--version"||H==="-v")(async()=>{let{version:t}=Mt();process.stdout.write(t+`
|
|
238
|
+
`);let e=(vt(),C(Rt)),n=await e.fetchLatestVersionAsync().catch(()=>null);if(n&&e.isNewer(t,n.version)){let{dim:r,yellow:s}=(dt(),C(Ne));process.stdout.write(s(`
|
|
237
239
|
Update available: ${t} \u2192 ${n.version}
|
|
238
240
|
`)+r(` Run: flow-ai-obs update
|
|
239
241
|
|
|
240
|
-
`));}process.exit(0);})().catch(()=>process.exit(0));else if(
|
|
241
|
-
`),await(
|
|
242
|
-
`),process.exit(1);});else if(
|
|
243
|
-
`),process.exit(1);});else if(
|
|
244
|
-
`),process.exit(1);});else if(
|
|
242
|
+
`));}process.exit(0);})().catch(()=>process.exit(0));else if(H==="--help"||H==="-h")cs(),process.exit(0);else if(H==="init"||H==="install")(async()=>{H==="install"&&process.stderr.write(`Warning: "install" is deprecated, use "init" instead
|
|
243
|
+
`),await(vt(),C(Rt)).checkForUpdateInteractive();let{runInit:t}=(Er(),C(hr)),e=process.argv.slice(3);process.exit(await t({url:Ie(e,"--custom-url"),noInteractive:e.includes("--no-interactive")}));})().catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
|
|
244
|
+
`),process.exit(1);});else if(H==="login")(async()=>{await(vt(),C(Rt)).checkForUpdateInteractive();let{runLogin:t}=(Oe(),C(_e)),e=process.argv.slice(3),n=await t({clientId:Ie(e,"--client-id"),clientSecret:Ie(e,"--client-secret"),tenant:Ie(e,"--tenant")});process.exit(typeof n=="number"?n:n.code);})().catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
|
|
245
|
+
`),process.exit(1);});else if(H==="status")(async()=>{await(vt(),C(Rt)).checkForUpdateInteractive();let{runStatus:t}=(yr(),C(Tr));process.exit(await t());})().catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
|
|
246
|
+
`),process.exit(1);});else if(H==="update")(async()=>{let t=(vt(),C(Rt)),{version:e}=Mt(),n=await t.fetchLatestVersionAsync();n||(process.stderr.write(` \u2717 Could not reach npm registry \u2014 check your connection.
|
|
245
247
|
`),process.exit(1)),t.isNewer(e,n.version)||(process.stdout.write(` \u2713 Already up to date (v${e})
|
|
246
248
|
`),process.exit(0)),await t.runUpdate(n.version),process.exit(0);})().catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
|
|
247
|
-
`),process.exit(1);});else if(
|
|
249
|
+
`),process.exit(1);});else if(H==="otel-headers"){let{runOtelHeaders:t}=(Or(),C(_r));t().then(e=>process.exit(e)).catch(()=>process.exit(1));}else gi.has(H)?(as(),C(mi)):(cs(),process.exit(0));
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
'use strict';var child_process=require('child_process'),util=require('util'),I=require('fs'),
|
|
1
|
+
'use strict';var child_process=require('child_process'),util=require('util'),I=require('fs'),x=require('path'),me=require('os'),Je=require('https'),Ke=require('http'),crypto=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var I__default=/*#__PURE__*/_interopDefault(I);var x__default=/*#__PURE__*/_interopDefault(x);var me__default=/*#__PURE__*/_interopDefault(me);var Je__default=/*#__PURE__*/_interopDefault(Je);var Ke__default=/*#__PURE__*/_interopDefault(Ke);var Pe=Object.defineProperty;var nt=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var gt=(t,e,r)=>()=>{if(r)throw r[0];try{return t&&(e=t(t=0)),e}catch(n){throw r=[n],n}};var St=(t,e)=>{for(var r in e)Pe(t,r,{get:e[r],enumerable:true});};var xt={};St(xt,{MacOsKeyVaultProvider:()=>At});var yt,At,Mt=gt(()=>{"use strict";yt=util.promisify(child_process.execFile),At=class{static async isAvailable(){try{return I.accessSync("/usr/bin/security",I.constants.X_OK),!0}catch{return !1}}async getSecret(e,r){try{let{stdout:n}=await yt("security",["find-generic-password","-w","-a",r,"-s",e]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await yt("security",["add-generic-password","-U","-a",r,"-s",e,"-w",n]);}async deleteSecret(e,r){try{return await yt("security",["delete-generic-password","-a",r,"-s",e]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var Ht={};St(Ht,{LinuxKeyVaultProvider:()=>Ot});var Yt,Ot,Vt=gt(()=>{"use strict";Yt=util.promisify(child_process.execFile),Ot=class{static async isAvailable(){let e=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let r of e)try{return I.accessSync(r,I.constants.X_OK),!0}catch{}return !1}async getSecret(e,r){try{let{stdout:n}=await Yt("secret-tool",["lookup","service",e,"account",r]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await new Promise((o,s)=>{let i=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",r]);i.on("error",s),i.on("close",l=>{l===0?o():s(new Error(`secret-tool exited with code ${l}`));}),i.stdin.write(n),i.stdin.end();});}async deleteSecret(e,r){try{return await Yt("secret-tool",["clear","service",e,"account",r]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var Gt={};St(Gt,{WindowsKeyVaultProvider:()=>wt});var wt,Wt=gt(()=>{"use strict";wt=class{static async isAvailable(){try{return await nt("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,r){return nt("keytar").getPassword(e,r)}async setSecret(e,r,n){await nt("keytar").setPassword(e,r,n);}async deleteSecret(e,r){return nt("keytar").deletePassword(e,r)}getStoragePath(){return "Windows Credential Manager"}};});var Ne="https://flow.ciandt.com";function B(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():Ne}function W(){let t=B();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${t}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${t}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${t}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${t}/otel`}}W();var st={SERVICE:"flow-plugins-cli",ACCOUNT_TOKEN:"token-cache"},ot="FLOW-nodejs",it="config.json",_t={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};var S={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"};var A={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},Dt="flow-ai-obs-debug.log",w={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4};function Et(){let t=B();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Tt={credentials:"credentials","token-cache":"tokenCache"};function J(){let t=me__default.default.homedir();if(process.platform==="darwin")return x__default.default.join(t,"Library","Preferences",ot,it);if(process.platform==="win32"){let r=process.env.APPDATA??x__default.default.join(t,"AppData","Roaming");return x__default.default.join(r,ot,it)}let e=process.env.XDG_CONFIG_HOME??x__default.default.join(t,".config");return x__default.default.join(e,ot,it)}function ht(){try{let t=I__default.default.readFileSync(J(),"utf8");return JSON.parse(t)}catch{return {}}}function Bt(t){let e=J();I__default.default.mkdirSync(x__default.default.dirname(e),{recursive:true}),I__default.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var at=class{static isAvailable(){return true}static hasExistingData(){try{if(!I__default.default.existsSync(J()))return !1;let e=JSON.parse(I__default.default.readFileSync(J(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,r){let n=ht(),o=Tt[r]??r,s=n[o];return s?typeof s=="string"?s:JSON.stringify(s):null}async setSecret(e,r,n){let o=ht(),s=Tt[r]??r;if(r==="token-cache")try{o[s]=JSON.parse(n);}catch{o[s]=n;}else o[s]=n;Bt(o);}async deleteSecret(e,r){let n=ht(),o=Tt[r]??r;return o in n?(delete n[o],Bt(n),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${J()}`}};async function Jt(){return await Ye()??new at}async function Ye(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Mt(),xt));return await t.isAvailable()?new t:null}case "linux":{if(process.env.WSL_DISTRO_NAME)return null;let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Vt(),Ht));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Wt(),Gt));return await t.isAvailable()?new t:null}default:return null}}var Kt=st.SERVICE,jt=st.ACCOUNT_TOKEN,kt=null;function qt(){return kt||(kt=Jt()),kt}async function Lt(t){await(await qt()).setSecret(Kt,jt,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function It(){let e=await(await qt()).getSecret(Kt,jt);if(!e)return null;try{let r=JSON.parse(e);return {accessToken:r.accessToken,expiresAt:r.expiresAt,lastAuthCheckAt:r.lastAuthCheckAt}}catch{return null}}async function Rt(){let t=await It();if(!t||!t.accessToken)return null;try{let e=t.accessToken.split(".");if(e.length<2)return null;let r=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return r.email??r.preferred_username??r.upn??r.sub??null}catch{return null}}var We=x.join(me.tmpdir(),Dt);function a(...t){if(process.env[S.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
|
|
2
2
|
`;try{I.writeFileSync(We,e,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
|
|
3
|
-
`);}}var b=class extends Error{constructor(e){super(e),this.name="AuthError";}},je=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function qe(t){if(!je.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var zt={INVALID_CLIENT_SECRET:"Invalid Client Secret \u2014 check the value and try again",INVALID_CLIENT_ID:"Invalid Client ID \u2014 check the value and try again",INVALID_TENANT:"Invalid Tenant \u2014 check the value and try again",TENANT_NOT_FOUND:"Tenant not found \u2014 verify the tenant identifier"};function ze(t,e){let r=e.length>400?e.slice(0,400)+"\u2026":e;a("toAuthError",`status=${t} body=${r}`);try{let n=JSON.parse(e);if(typeof n.error=="string"&&(a("toAuthError",`api_error_code=${n.error}`+(n.message?` api_message=${n.message}`:"")),zt[n.error]))return new b(zt[n.error])}catch{}return t===401||t===403||t===500?new b("Invalid credentials"):t>=400&&t<500?new b("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function j(t){return new Promise((e,r)=>{try{qe(t.tenant);}catch(p){return r(p)}let n=JSON.stringify({clientSecret:t.clientSecret}),o=new URL(W().AUTH_ENGINE),s=o.protocol==="https:",i={hostname:o.hostname,port:o.port||(s?443:80),path:o.pathname+o.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(n),FlowTenant:t.tenant}};a("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let c=(s?Je__default.default:Ke__default.default).request(i,p=>{let _=[];p.on("data",
|
|
4
|
-
`)[0].slice(0,e).trim()}function q(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",r=>{e+=r;}),process.stdin.on("end",()=>{try{t(JSON.parse(e));}catch{t({});}});})}function
|
|
3
|
+
`);}}var b=class extends Error{constructor(e){super(e),this.name="AuthError";}},je=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function qe(t){if(!je.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var zt={INVALID_CLIENT_SECRET:"Invalid Client Secret \u2014 check the value and try again",INVALID_CLIENT_ID:"Invalid Client ID \u2014 check the value and try again",INVALID_TENANT:"Invalid Tenant \u2014 check the value and try again",TENANT_NOT_FOUND:"Tenant not found \u2014 verify the tenant identifier"};function ze(t,e){let r=e.length>400?e.slice(0,400)+"\u2026":e;a("toAuthError",`status=${t} body=${r}`);try{let n=JSON.parse(e);if(typeof n.error=="string"&&(a("toAuthError",`api_error_code=${n.error}`+(n.message?` api_message=${n.message}`:"")),zt[n.error]))return new b(zt[n.error])}catch{}return t===401||t===403||t===500?new b("Invalid credentials"):t>=400&&t<500?new b("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function j(t){return new Promise((e,r)=>{try{qe(t.tenant);}catch(p){return r(p)}let n=JSON.stringify({clientSecret:t.clientSecret}),o=new URL(W().AUTH_ENGINE),s=o.protocol==="https:",i={hostname:o.hostname,port:o.port||(s?443:80),path:o.pathname+o.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(n),FlowTenant:t.tenant}};a("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let c=(s?Je__default.default:Ke__default.default).request(i,p=>{let _=[];p.on("data",E=>_.push(E)),p.on("end",()=>{let E=_.join("");if((p.statusCode??0)>=400)return r(ze(p.statusCode??0,E));let m;try{m=JSON.parse(E);}catch{return r(new Error("Invalid response from auth engine"))}let g=m.expires_at??new Date(Date.now()+(m.expires_in??3600)*1e3).toISOString();e({accessToken:m.access_token??"",expiresAt:g});});});c.on("error",p=>r(new Error(`Network error: ${p.message}`))),c.write(n),c.end();})}var Xe=[/^localhost\.?$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/,/^::1$/,/^\[::1\]$/,/^\[::ffff:/i,/^\[f[cd]/i,/^\[fe80:/i,/^metadata\.google\.internal\.?$/i,/^metadata\.azure\.internal\.?$/i,/(?:^|\.)localtest\.me\.?$/i,/(?:^|\.)lvh\.me\.?$/i,/(?:^|\.)vcap\.me\.?$/i];function Ze(t){return Xe.some(e=>e.test(t))}function Qe(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let r=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8"));return r.email||r.preferred_username||r.upn||r.sub||null}catch{return null}}function lt(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let r=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:n,clientSecret:o,tenant:s}=r;return !n||!o||!s?null:{clientId:n,clientSecret:o,tenant:s}}catch{return null}}function ct(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let r=process.env[S.FLOW_OBS_ALLOW_HTTP]==="true";if(!r&&e.protocol!=="https:")throw new Error(`URL must use HTTPS: ${t}`);if(e.username||e.password)throw new Error(`URL must not contain embedded credentials: ${t}`);if(!r&&Ze(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function Xt(){let t=lt(process.env[S.ANTHROPIC_AUTH_TOKEN]);return t?{user:await Rt().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function tr(){return new Date().toISOString().slice(0,10)}async function er(t){let e=tr(),r=await It();if(r?.lastAuthCheckAt!==e){a("getOrRefreshToken",`daily auth check (last: ${r?.lastAuthCheckAt??"never"})`);try{let s=await j(t);try{await Lt({...s,lastAuthCheckAt:e});}catch{}return a("getOrRefreshToken",`daily check passed, expires=${s.expiresAt}`),s.accessToken}catch(s){if(s instanceof b)throw s;a("getOrRefreshToken",`daily check network error \u2014 using cache: ${s.message}`);}}let n=r!=null&&new Date(r.expiresAt)>new Date;if(a("getOrRefreshToken",`cacheValid=${n}`),n)return a("getOrRefreshToken",`using cached token, expires=${r.expiresAt}`),r.accessToken;a("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let o=await j(t);try{await Lt({...o,lastAuthCheckAt:e});}catch(s){a("getOrRefreshToken",`token cache save failed (non-fatal): ${s.message}`);}return a("getOrRefreshToken",`token refreshed, expires=${o.expiresAt}`),o.accessToken}function rr(t,e){let r=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function nr(t,e,r){let n=Buffer.from(`${e}:${r}`).toString("base64");return {endpoint:t.replace(/\/$/,"")+"/api/public/otel/v1/traces",authHeader:`Basic ${n}`}}async function v(){let t=[],e=process.env[S.ANTHROPIC_MODEL]??"",r=lt(process.env[S.ANTHROPIC_AUTH_TOKEN]);a("resolveCredentials",r?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),r&&a("resolveCredentials",`clientId=${r.clientId}`,`tenant=${r.tenant}`);let n=r?r.tenant:"",o=process.env[S.FLOW_TELEMETRY]==="true",s=process.env[S.LANGFUSE_BASE_URL],i=process.env[S.LANGFUSE_PUBLIC_KEY],l=process.env[S.LANGFUSE_SECRET_KEY];if(o&&s&&i&&l){let m="",g=n;r&&(m=await Rt().catch(()=>null)??r.clientId);let T={user:m??"",tenant:g??"",team:"",project:"",model:e};t.push({mode:"direct",...nr(ct(s),i,l),...T}),a("resolveCredentials","direct mode active",`user=${T.user}`,`tenant=${T.tenant}`);}if(!r){if(t.length===0){let m=[];return m.authError=false,m}return t}let c;try{c=await er(r);}catch(m){if(a("resolveCredentials",`token refresh failed: ${m.message}`,`(tenant=${r.tenant} clientId=${r.clientId})`),t.length>0)return t.authError=true,t;let g=[];return g.authError=true,g}let _={user:Qe(c)??r.clientId,tenant:n,team:"",project:"",model:e},E=process.env[S.FLOW_TELEMETRY_GATEWAY]??B();return t.push({mode:"gateway",...rr(ct(E),{accessToken:c}),..._}),t}async function ut(){return (await v()).length>0}function k(t,e){let r=typeof t=="object"?JSON.stringify(t):String(t??"");return r.length>e?r.slice(0,e)+" \u2026[truncated]":r}function pt(t,e=100){return String(t??"").split(`
|
|
4
|
+
`)[0].slice(0,e).trim()}function q(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",r=>{e+=r;}),process.stdin.on("end",()=>{try{t(JSON.parse(e));}catch{t({});}});})}function O(t){process.stdout.write(JSON.stringify(t));}var Pt=()=>crypto.randomBytes(16).toString("hex"),U=()=>crypto.randomBytes(8).toString("hex");function L(){return String(BigInt(Date.now())*1000000n)}var dr=/^[0-9a-f-]{1,64}$/i,fr=x.normalize(me.tmpdir())+x.sep;function mr(t,e){let r=x.resolve(t);if(!r.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return r}function Nt(t){if(!dr.test(t))throw new Error(`Invalid session ID: ${t}`);return mr(x.join(me.tmpdir(),`flow-obs-${t}.json`),fr)}function M(t){let e=Nt(t);if(!I.existsSync(e))return null;try{return JSON.parse(I.readFileSync(e,"utf8"))}catch{return null}}function Y(t,e){I.writeFileSync(Nt(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function bt(t){try{I.unlinkSync(Nt(t));}catch{}}function re(t){if(!t||!I.existsSync(t))return null;try{let e=I.readFileSync(t,"utf8").trimEnd().split(`
|
|
5
5
|
`);for(let r=e.length-1;r>=0;r--)try{let n=JSON.parse(e[r]);if(n.type==="user"&&n.uuid)return n.uuid}catch{}}catch{}return null}function vt(t){if(!t||!I.existsSync(t))return null;try{let e=I.readFileSync(t,"utf8").trimEnd().split(`
|
|
6
6
|
`),r=[],n=0,o=0;for(let s=e.length-1;s>=0;s--)try{let i=JSON.parse(e[s]);if(i.type==="user")break;if(i.type==="assistant"){let c=(i.message?.content??[]).filter(_=>_.type==="text").map(_=>_.text??"").join("");c&&r.unshift(c);let p=i.message?.usage??{};n+=(p.input_tokens??0)+(p.cache_read_input_tokens??0)+(p.cache_creation_input_tokens??0),o+=p.output_tokens??0;}}catch{}return !r.length&&n===0?null:{text:r.join(`
|
|
7
7
|
|
|
8
|
-
`),inputTokens:n,outputTokens:o}}catch{}return null}var
|
|
9
|
-
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var yr=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function ae(t){return !!t.slashSkill||t.toolCalls.some(n=>n.tool==="Skill")?t.toolCalls.some(n=>n.tool==="Skill"&&!n.synthetic||yr.has(n.tool))?"complete":"prerequisite_required":null}function ft(t,e){if(!t)return null;let r=oe(t),n=[
|
|
10
|
-
`);return}let n=!!(await v()).authError,o=t.session_id||"unknown",s=t.prompt||"",i=t.cwd||"",l=re(t.transcript_path)||Pt(),c=ie(s),p=c?dt(c,i):null,_=c?ft(c,i):null;
|
|
11
|
-
`,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${ue}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Ur(t){let e=new URL(t),r=new URL(W().GATEWAY_HEALTH);return r.hostname=e.hostname,r.port=e.port,r.protocol=e.protocol,r}function de(t,e){return new Promise((r,n)=>{let o=t._isSSL?Je__default.default:Ke__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let s=o.request(t,i=>{let l=[];i.on("data",c=>l.push(c)),i.on("end",()=>r({statusCode:i.statusCode??0,body:l.join("")}));});s.setTimeout(1e4,()=>{s.destroy(new Error("Request timeout"));}),s.on("error",i=>n(new Error(`Network error: ${i.message}`))),e&&s.write(e),s.end();})}async function fe(t,e){let r;try{r=Ur(t);}catch{return false}let n=r.protocol==="https:";try{let o={};e&&(o.Authorization=String(e).replace(/[\r\n]/g,""));let s=await de({hostname:r.hostname,port:r.port||(n?443:80),path:r.pathname,method:"GET",headers:o,_isSSL:n},null);return a("checkHealth",`url=${r.href} status=${s.statusCode}`),s.statusCode>=200&&s.statusCode<300}catch{return false}}async function mt(t,e,r){let n=JSON.stringify(t),o=new URL(e),s=o.protocol==="https:",i=String(r).replace(/[\r\n]/g,""),l={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(n)};a("sendTraces:request",`POST ${e}`),a("sendTraces:request",`headers=${JSON.stringify({...l,Authorization:i.slice(0,20)+"\u2026"})}`),a("sendTraces:request",`body=${n.slice(0,500)}${n.length>500?"\u2026":""}`);try{let c=await de({hostname:o.hostname,port:o.port||(s?443:80),path:o.pathname,method:"POST",headers:l,_isSSL:s},n);return a("sendTraces:response",`status=${c.statusCode}`),pe(e,l,n,c.statusCode,c.body),c.statusCode}catch(c){return a("sendTraces:error",c.message),pe(e,l,n,0,c.message),0}}function Cr(){let t=parseInt(process.env[S.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(A.MIN_TTL_DAYS,Math.min(A.MAX_TTL_DAYS,t)):A.DEFAULT_TTL_DAYS)*24*60*60*1e3}function $r(){let t=parseInt(process.env[S.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(A.MIN_MAX_FILES,Math.min(A.MAX_MAX_FILES,t)):A.DEFAULT_MAX_FILES}function ge(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return
|
|
8
|
+
`),inputTokens:n,outputTokens:o}}catch{}return null}var Er=new Set([".venv","__pycache__",".git","node_modules"]),Tr=new Set([".pyc",".pyo"]),hr=new Set(["SKILL.md",".DS_Store",".gitignore"]);function oe(t){return t.replace(":","/")}function dt(t,e){if(!t)return null;let r=oe(t),n=[x.join(me.homedir(),".claude","skills",r,"SKILL.md"),x.join(e??"",".claude","skills",r,"SKILL.md")];for(let o of n)if(I.existsSync(o))try{return I.readFileSync(o,"utf8")}catch{}return null}function ie(t){return t.split(`
|
|
9
|
+
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}var yr=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);function ae(t){return !!t.slashSkill||t.toolCalls.some(n=>n.tool==="Skill")?t.toolCalls.some(n=>n.tool==="Skill"&&!n.synthetic||yr.has(n.tool))?"complete":"prerequisite_required":null}function ft(t,e){if(!t)return null;let r=oe(t),n=[x.join(me.homedir(),".claude","skills",r),x.join(e??"",".claude","skills",r)],o=null;for(let l of n)if(I.existsSync(x.join(l,"SKILL.md"))){o=l;break}if(!o)return null;let s=[];function i(l,c){for(let p of I.readdirSync(l,{withFileTypes:true})){if(Er.has(p.name)||hr.has(p.name)||Tr.has(x.extname(p.name)))continue;let _=c?`${c}/${p.name}`:p.name;p.isDirectory()?i(x.join(l,p.name),_):s.push(_);}}return i(o,""),s.length>0?s:null}function wr(t){try{let e=t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(e,"base64").toString())}catch{return null}}function kr(t,e,r,n){return new Promise(o=>{let s=new URL(t),i=s.protocol==="https:",l=(i?Je__default.default:Ke__default.default).request({hostname:s.hostname,port:s.port||(i?443:80),path:s.pathname+s.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(e),Authorization:`Bearer ${String(r).replace(/[\r\n]/g,"")}`,FlowTenant:String(n).replace(/[\r\n]/g,"")}},c=>{c.resume(),o(c.statusCode??0);});l.on("error",()=>o(0)),l.setTimeout(5e3,()=>{l.destroy(),o(0);}),l.write(e),l.end();})}async function C(t,e={}){try{let r=lt(process.env[S.ANTHROPIC_AUTH_TOKEN]);if(!r)return;let n,o=new Promise((E,m)=>{n=setTimeout(()=>m(new Error("getToken timeout")),4e3),n.unref();}),{accessToken:s}=await Promise.race([j(r),o]);clearTimeout(n);let i=wr(s);if(!i)return;let l=i.tenant||r.tenant,c=JSON.stringify({action:t,booster:Et().BOOSTER,metadata:e,success:!0,tenant:l,timestamp:new Date().toISOString(),os:process.platform,user:{email:i.email||"",id:i.sub||"",name:i.name||i.email||""}}),p=ct(Et().API_URL),_=await kr(p,c,s,l);a("metrics.logEvent",`action=${t} status=${_}`);}catch(r){a("metrics.logEvent",`silenced error: ${r.message}`);}}var Lr=`\u26D4 Your Flow API key has expired. You no longer have access to Claude Code through the Flow platform. To restore observability and access, visit ${B()}/settings/api-keys to generate a new API key, then run: flow-ai-obs login`;async function Ut(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:Lr})+`
|
|
10
|
+
`);return}let n=!!(await v()).authError,o=t.session_id||"unknown",s=t.prompt||"",i=t.cwd||"",l=re(t.transcript_path)||Pt(),c=ie(s),p=c?dt(c,i):null,_=c?ft(c,i):null;Y(o,{traceId:Pt(),spanId:U(),startNs:L(),sessionId:o,prompt:s,cwd:i,traceName:l,transcriptPath:t.transcript_path||"",model:process.env[S.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:c,skillContent:p,skillArtifacts:_}),C("SESSION_STARTED",{traceType:c?"skill":"prompt",slashSkill:c,clientIdExpired:n}),a("UserPromptSubmit",`sid=${o}`,`traceName=${l}`,`slashSkill=${c}`),O(t);}async function ce(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},o=M(e);o&&(o.pendingTool={name:r,inputStr:k(n,w.TOOL_INPUT),startNs:L()},Y(e,o)),a("PreToolUse",`sid=${e}`,`tool=${r}`,`stateFound=${!!o}`),O(t);}var Ir={name:_t.SCOPE_NAME,version:_t.SCOPE_VERSION},f={TRACE_NAME:"langfuse.trace.name",TRACE_INPUT:"langfuse.trace.input",TRACE_OUTPUT:"langfuse.trace.output",TRACE_METADATA:"langfuse.trace.metadata",TRACE_TAGS:"langfuse.trace.tags",USER_ID:"langfuse.user.id",SESSION_ID:"langfuse.session.id",OBS_NAME:"langfuse.observation.name",OBS_INPUT:"langfuse.observation.input",OBS_OUTPUT:"langfuse.observation.output",OBS_LEVEL:"langfuse.observation.level",OBS_TYPE:"langfuse.observation.type",MODEL:"gen_ai.request.model",INPUT_TOKENS:"gen_ai.usage.input_tokens",OUTPUT_TOKENS:"gen_ai.usage.output_tokens"};function u(t,e){return e==null||e===""?null:{key:t,value:{stringValue:String(e)}}}function $(...t){return t.filter(e=>e!==null)}function le(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:Ir,spans:Array.isArray(e)?e:[e]}]}]}}var ue=x.join(me.tmpdir(),"flow-obs-requests.ndjson");function pe(t,e,r,n,o){if(process.env[S.FLOW_OBS_DEBUG]!=="1")return;let s=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(r)},response:{status:n,body:o}});try{I.writeFileSync(ue,s+`
|
|
11
|
+
`,{flag:"a",encoding:"utf8",mode:384}),a("sendTraces:dump",`request appendada em ${ue}`);}catch(i){a("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Ur(t){let e=new URL(t),r=new URL(W().GATEWAY_HEALTH);return r.hostname=e.hostname,r.port=e.port,r.protocol=e.protocol,r}function de(t,e){return new Promise((r,n)=>{let o=t._isSSL?Je__default.default:Ke__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let s=o.request(t,i=>{let l=[];i.on("data",c=>l.push(c)),i.on("end",()=>r({statusCode:i.statusCode??0,body:l.join("")}));});s.setTimeout(1e4,()=>{s.destroy(new Error("Request timeout"));}),s.on("error",i=>n(new Error(`Network error: ${i.message}`))),e&&s.write(e),s.end();})}async function fe(t,e){let r;try{r=Ur(t);}catch{return false}let n=r.protocol==="https:";try{let o={};e&&(o.Authorization=String(e).replace(/[\r\n]/g,""));let s=await de({hostname:r.hostname,port:r.port||(n?443:80),path:r.pathname,method:"GET",headers:o,_isSSL:n},null);return a("checkHealth",`url=${r.href} status=${s.statusCode}`),s.statusCode>=200&&s.statusCode<300}catch{return false}}async function mt(t,e,r){let n=JSON.stringify(t),o=new URL(e),s=o.protocol==="https:",i=String(r).replace(/[\r\n]/g,""),l={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(n)};a("sendTraces:request",`POST ${e}`),a("sendTraces:request",`headers=${JSON.stringify({...l,Authorization:i.slice(0,20)+"\u2026"})}`),a("sendTraces:request",`body=${n.slice(0,500)}${n.length>500?"\u2026":""}`);try{let c=await de({hostname:o.hostname,port:o.port||(s?443:80),path:o.pathname,method:"POST",headers:l,_isSSL:s},n);return a("sendTraces:response",`status=${c.statusCode}`),pe(e,l,n,c.statusCode,c.body),c.statusCode}catch(c){return a("sendTraces:error",c.message),pe(e,l,n,0,c.message),0}}function Cr(){let t=parseInt(process.env[S.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(A.MIN_TTL_DAYS,Math.min(A.MAX_TTL_DAYS,t)):A.DEFAULT_TTL_DAYS)*24*60*60*1e3}function $r(){let t=parseInt(process.env[S.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(A.MIN_MAX_FILES,Math.min(A.MAX_MAX_FILES,t)):A.DEFAULT_MAX_FILES}function ge(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return x__default.default.join(me__default.default.tmpdir(),`${A.FILE_PREFIX}${t}.json`)}function $t(){let t=me__default.default.tmpdir(),e;try{e=I__default.default.readdirSync(t);}catch{return []}return e.filter(r=>r.startsWith(A.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=x__default.default.join(t,r),o=0;try{o=I__default.default.statSync(n).mtimeMs;}catch{}return {full:n,mtime:o}}).sort((r,n)=>r.mtime-n.mtime).map(r=>r.full)}function z(t){try{let e=$r(),r=$t();if(r.length>=e){let s=r.slice(0,r.length-e+1);for(let i of s)try{I__default.default.unlinkSync(i);}catch{}}let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,o={fileId:n,bufferedAt:Date.now(),payload:t};return I__default.default.writeFileSync(ge(n),JSON.stringify(o),{encoding:"utf8",mode:384}),a("buffer",`saved fileId=${n}`),n}catch(e){return a("buffer",`saveToBuffer failed: ${e.message}`),null}}function Se(t){let e=$t(),r=t,n=[];for(let o of e){if(n.length>=r)break;try{let s=I__default.default.readFileSync(o,"utf8"),i=JSON.parse(s);i&&i.fileId&&i.payload&&n.push(i);}catch{a("buffer",`skipping malformed file: ${o}`);}}return n}function _e(t){try{I__default.default.unlinkSync(ge(t)),a("buffer",`deleted fileId=${t}`);}catch{}}function Ee(){let t=Date.now()-Cr();for(let e of $t())try{let{mtimeMs:r}=I__default.default.statSync(e);r<t&&(I__default.default.unlinkSync(e),a("buffer",`evicted stale: ${x__default.default.basename(e)}`));}catch{}}async function Fr(t){Ee();let e=Se(A.REPLAY_BATCH_SIZE);e.length&&(a("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async r=>{try{let n=await mt(r.payload,t.endpoint,t.authHeader);n>=200&&n<300?(_e(r.fileId),a("replayBufferedTraces",`replayed fileId=${r.fileId} status=${n}`)):a("replayBufferedTraces",`replay failed fileId=${r.fileId} status=${n}`);}catch(n){a("replayBufferedTraces",`replay error fileId=${r.fileId}: ${n.message}`);}})));}async function Te(t){let e=await v();if(!e.length)return e.authError&&(a("postToLangfuse","auth refresh failed \u2014 buffering trace"),z(t)),0;let r=await Promise.all(e.map(async s=>{if(s.mode!=="gateway")return {creds:s,healthy:true};let i=await fe(s.endpoint,s.authHeader);return {creds:s,healthy:i}})),n=r.find(s=>s.creds.mode==="gateway"&&s.healthy)?.creds??r.find(s=>s.creds.mode==="direct")?.creds;return n&&await Fr(n),(await Promise.all(r.map(async({creds:s,healthy:i})=>{if(s.mode==="gateway"){if(!i)return a("postToLangfuse","gateway health check failed \u2014 buffering trace"),z(t),0;let c=await mt(t,s.endpoint,s.authHeader);return (c===0||c>=500)&&(a("postToLangfuse",`gateway send failed (status ${c}) \u2014 buffering trace`),z(t)),c}let l=await mt(t,s.endpoint,s.authHeader);return (l===0||l>=500)&&(a("postToLangfuse",`direct endpoint unavailable (status ${l}) \u2014 buffering trace`),z(t)),l}))).find(s=>s!==0)??0}var y="[REDACTED]",Dr="[REDACTED-EMAIL]",Br="[REDACTED-CPF]",xr="[REDACTED-CNPJ]",he="[REDACTED-PHONE]",Mr=[{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,r)=>`${e}
|
|
12
12
|
${y}
|
|
13
|
-
${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${y}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${y}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${y}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${y}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(t,e,r)=>`${e}${r}${y}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${y}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>Dr},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>
|
|
14
|
-
`)),
|
|
15
|
-
`),process.stdin.on("data",e=>process.stdout.write(e));}}
|
|
13
|
+
${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${y}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${y}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${y}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${y}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${y}`},{re:/\b([A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PWD|CREDENTIAL|API)[A-Z0-9_]*\s*=\s*)(['"]?)([^\s'"#\n]+)\2/gi,replace:(t,e,r)=>`${e}${r}${y}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${y}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>Dr},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>Br},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>xr},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>he},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>he}];function R(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return Mr.reduce((r,{re:n,replace:o})=>r.replace(n,o),e)}async function ye(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},o=t.tool_response,s=o!==null&&typeof o=="object"?o.output??JSON.stringify(o):o??"",i=M(e);if(!i){O(t);return}let l=L(),c=i.pendingTool,p=c?.name===r,_=p?c.startNs:String(BigInt(l)-200000000n),E=p?c.inputStr:k(n,w.TOOL_INPUT),m=E,g=null;if(r==="Skill"){let rt=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||n.commandName||String(Object.values(n)[0]??""):String(n);g=rt?String(rt).trim():null;let P=g?dt(g,i.cwd):null;P&&(m=P,i.skillContent||(i.skillContent=P),i.skillArtifacts||(i.skillArtifacts=ft(g,i.cwd))),g&&!i.slashSkill&&(i.slashSkill=g),a("PostToolUse","Skill tool detected",`skillName=${g}`,`contentFound=${!!P}`);}let T=R(k(s,w.TOOL_OUTPUT)),h=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(T.slice(0,500)),X=h?"ERROR":"DEFAULT",V=U(),Z=Math.round(Number(BigInt(l)-BigInt(_))/1e6),tt={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL",et=r==="Skill"&&g?g:pt(E,60);i.toolCalls.push({tool:r,brief:et,error:h,durationMs:Z});let G=i.spans;G.push({traceId:i.traceId,spanId:V,parentSpanId:i.spanId,name:r,kind:3,startTimeUnixNano:_,endTimeUnixNano:l,attributes:$(u(f.OBS_NAME,r),u(f.OBS_TYPE,tt),u(f.OBS_LEVEL,X),u(f.OBS_INPUT,R(m)),u(f.OBS_OUTPUT,T),u("tool.name",r),u("tool.error",String(h)),r==="Skill"&&g?u("skill.name",g):null,r==="Skill"?u("skill.invocation","slash-command"):null),status:{code:h?2:1}}),i.pendingTool=null,Y(e,i),h&&C("TOOL_ERROR",{toolName:r}),a("PostToolUse",`sid=${e}`,`tool=${r}`,`error=${h}`,`durationMs=${Z}`,`totalSpans=${G.length}`),O(t);}var Ae={"claude-opus-4-6":{input:15,output:75},"claude-opus-4-5":{input:15,output:75},"claude-sonnet-4-6":{input:3,output:15},"claude-sonnet-4-5":{input:3,output:15},"claude-haiku-4-5":{input:.8,output:4},"claude-4-6-opus":{input:15,output:75},"claude-4-6-sonnet":{input:3,output:15},"claude-4-5-opus":{input:15,output:75},"claude-4-5-sonnet":{input:3,output:15},"claude-4-5-haiku":{input:.8,output:4},"claude-3-5-sonnet-20241022":{input:3,output:15},"claude-3-5-haiku-20241022":{input:.8,output:4},"claude-3-opus-20240229":{input:15,output:75}};function Oe(t,e,r){let n=Object.keys(Ae).find(i=>(t??"").toLowerCase().includes(i));if(!n)return;let o=Ae[n],s=(e*o.input+r*o.output)/1e6;return Math.round(s*1e6)/1e6}async function we(t){let e=t.session_id||"unknown",r=t.stop_reason||"end_turn",n=M(e);if(!n){O(t);return}n.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(n.slashSkill)&&(a("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${n.slashSkill}"`),n.slashSkill=null);let o=L(),s=await Xt(),i=n.toolCalls,l=n.spans;if(n.slashSkill&&!i.some(d=>d.tool==="Skill")){let d=U(),N=n.skillContent?n.skillContent:JSON.stringify({skill:n.slashSkill});i.push({tool:"Skill",brief:n.slashSkill,error:false,durationMs:0,synthetic:true}),l.push({traceId:n.traceId,spanId:d,parentSpanId:n.spanId,name:"Skill",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:n.startNs,attributes:$(u(f.OBS_NAME,"Skill"),u(f.OBS_TYPE,"TOOL"),u(f.OBS_LEVEL,"DEFAULT"),u(f.OBS_INPUT,N),u(f.OBS_OUTPUT,"loaded via slash command"),u("tool.name","Skill"),u("tool.error","false"),u("skill.name",n.slashSkill),u("skill.invocation","slash-command")),status:{code:1}}),a("Stop",`slashSkill=${n.slashSkill}`,"synthetic span injected");}let c=t.transcript_path||n.transcriptPath||"",p=vt(c);if(c&&(i.some(d=>d.tool==="Skill"&&!d.synthetic)||!!n.slashSkill)&&!p?.text){await new Promise(N=>setTimeout(N,500));let d=vt(c);d?.text&&(p=d);}a("Stop",`transcriptPath=${c||"(empty)"}`,`assistantOut=${p?`text=${p.text.length}chars`:"null"}`);let E=i.length,m=i.filter(d=>d.error).length,g=R(p?.text?k(p.text,w.TRACE_OUTPUT):E===0?"No tools used":i.map((d,N)=>`${N+1}. ${d.tool}${d.brief?` \u2192 ${d.brief}`:""}${d.error?" [ERROR]":""}`).join(`
|
|
14
|
+
`)),T=p?.inputTokens??0,h=p?.outputTokens??0,X=i.map((d,N)=>`${N+1}. ${d.tool}${d.brief?` \u2192 ${d.brief}`:""}${d.error?" [ERROR]":""} (${d.durationMs}ms)`),V=!!(n.slashSkill||i.some(d=>d.tool==="Skill")),Z=i.some(d=>d.tool==="Agent");if(!V&&!Z){a("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),C("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),bt(e),O(t);return}let Q=V?"skill":"agent",tt=Math.round(Number(BigInt(o)-BigInt(n.startNs))/1e6),et=Oe(n.model,T,h),D=ae(n);D==="prerequisite_required"&&p?.text&&(D="complete"),D==="prerequisite_required"&&(l.push({traceId:n.traceId,spanId:U(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:o,attributes:$(u(f.OBS_NAME,"prerequisite-check"),u(f.OBS_TYPE,"EVENT"),u(f.OBS_LEVEL,"WARNING"),u(f.OBS_OUTPUT,g),u("skill.name",n.slashSkill||void 0),u("execution_status","prerequisite_required")),status:{code:1}}),a("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${n.slashSkill}`));let G=(()=>{if(!(!V||!n.prompt)){if(n.slashSkill){let d=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return d?k(R(d),w.USER_INSTRUCTION):void 0}return k(R(n.prompt),w.USER_INSTRUCTION)||void 0}})(),rt=JSON.stringify({trace_type:Q,...D!==null&&{execution_status:D},...n.slashSkill?{skill_name:n.slashSkill}:{},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...G!==void 0&&{user_instruction:G},latency_ms:tt,...T&&{tokens_input:T},...h&&{tokens_output:h},cost_usd:et,...n.model?{model:n.model}:{},toolCount:E,errorCount:m,stopReason:r,sessionId:n.sessionId,tools:X.length?X:void 0}),P=R(k(n.prompt,w.TRACE_INPUT)),ke=$(u(f.TRACE_NAME,n.traceName),u(f.TRACE_INPUT,P),u(f.TRACE_OUTPUT,g),u(f.OBS_INPUT,P),u(f.OBS_OUTPUT,g),u(f.TRACE_METADATA,rt),u(f.SESSION_ID,n.sessionId),u(f.USER_ID,s.user),u(f.OBS_TYPE,"GENERATION"),u(f.MODEL,n.model),T?u(f.INPUT_TOKENS,T):null,h?u(f.OUTPUT_TOKENS,h):null,u("claude.stop_reason",r),u("claude.tool_count",String(E)),u("claude.error_count",String(m)),u("claude.session_id",n.sessionId),u("flow.trace_type",Q),{key:f.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:Q}]}}}),Le={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:o,attributes:ke,status:{code:m>0?2:1}},Ie=$(u("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),u("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),Ft=[...l,Le];a("Stop",`sid=${e}`,`totalTools=${E}`,`errorTools=${m}`,`spans=${Ft.length}`,`inputTokens=${T}`,`outputTokens=${h}`,`traceOutput="${pt(g,80)}"`);let Re=await Te(le(Ie,Ft));a("Stop",`POST status=${Re}`,`traceId=${n.traceId}`),C("TRACE_SENT",{latencyMs:tt,totalTools:E,errorTools:m,inputTokens:T,outputTokens:h,costUsd:et}),bt(e),O(t);}var F=class t{static passthroughStdin(){let e=[];process.stdin.on("data",r=>e.push(r)),process.stdin.on("end",()=>process.stdout.write(Buffer.concat(e)));}static async userPromptSubmit(){let e=await q(),r;try{r=await v();}catch{process.stdout.write(JSON.stringify(e));return}r.authError?await Ut(e,true):r.length>0?await Ut(e):process.stdout.write(JSON.stringify(e));}static async preToolUse(){if(!await ut()){t.passthroughStdin();return}let e=await q();await ce(e);}static async postToolUse(){if(!await ut()){t.passthroughStdin();return}let e=await q();await ye(e);}static async stop(){if(!await ut()){t.passthroughStdin();return}let e=await q();await we(e);}};async function Yr(){let t=process.argv[2];switch(t){case "UserPromptSubmit":await F.userPromptSubmit();break;case "PreToolUse":await F.preToolUse();break;case "PostToolUse":await F.postToolUse();break;case "Stop":await F.stop();break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
|
|
15
|
+
`),process.stdin.on("data",e=>process.stdout.write(e));}}Yr().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
|
|
16
16
|
`),process.exit(0);});
|
package/dist/setup.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var child_process=require('child_process'),util=require('util'),i=require('fs'),d=require('path'),u=require('os'),de=require('https');require('readline/promises');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var i__namespace=/*#__PURE__*/_interopNamespace(i);var d__namespace=/*#__PURE__*/_interopNamespace(d);var u__namespace=/*#__PURE__*/_interopNamespace(u);var de__default=/*#__PURE__*/_interopDefault(de);var I=Object.defineProperty;var Lt=Object.getOwnPropertyDescriptor;var Rt=Object.getOwnPropertyNames;var kt=Object.prototype.hasOwnProperty;var O=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var A=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var Pt=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(n){throw e=0,n}},L=(t,e)=>{for(var n in e)I(t,n,{get:e[n],enumerable:true});},It=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Rt(e))!kt.call(t,s)&&s!==n&&I(t,s,{get:()=>e[s],enumerable:!(r=Lt(e,s))||r.enumerable});return t};var Ct=t=>It(I({},"__esModule",{value:true}),t);var J={};L(J,{BUFFER:()=>Dt,CONFIG_DIR_NAME:()=>E,CONFIG_FILE_NAME:()=>T,DEBUG_LOG_FILENAME:()=>U,ENV:()=>p,FEATURES:()=>$t,FLOW_URLS:()=>bt,HOOK_TIMEOUTS:()=>b,INSTALLER:()=>N,NATIVE_OTEL:()=>C,OTLP:()=>Ut,STATE_FILE_PREFIX:()=>Mt,TRACE_LIMITS:()=>xt,VAULT:()=>y,getFlowBaseUrl:()=>h,getFlowUrls:()=>R,getLlmProxy:()=>Ft,getMetrics:()=>Ht});function h(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():Nt}function R(){let t=h();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${t}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${t}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${t}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${t}/otel`}}function Ft(){let t=h();return {ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${t}/flow-llm-proxy/`,ANTHROPIC_MODEL:process.env.FLOW_LLM_PROXY_MODEL??"anthropic.claude-4-6-sonnet",ANTHROPIC_SMALL_FAST_MODEL:process.env.FLOW_LLM_PROXY_SMALL_MODEL??"anthropic.claude-4-6-haiku",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"}}function Ht(){let t=h();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Nt,bt,y,E,T,Ut,C,p,$t,N,b,Dt,U,xt,Mt,l=A(()=>{"use strict";Nt="https://flow.ciandt.com";bt=R(),y={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},E="FLOW-nodejs",T="config.json",Ut={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};C={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},p={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"},$t={KEYCHAIN_ENABLED:!1},N={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},b={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},Dt={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},U="flow-ai-obs-debug.log",xt={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};Mt="flow-obs-";});var X={};L(X,{MacOsKeyVaultProvider:()=>x});var D,x,q=A(()=>{"use strict";D=util.promisify(child_process.execFile),x=class{static async isAvailable(){try{return i.accessSync("/usr/bin/security",i.constants.X_OK),!0}catch{return !1}}async getSecret(e,n){try{let{stdout:r}=await D("security",["find-generic-password","-w","-a",n,"-s",e]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await D("security",["add-generic-password","-U","-a",n,"-s",e,"-w",r]);}async deleteSecret(e,n){try{return await D("security",["delete-generic-password","-a",n,"-s",e]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var Z={};L(Z,{LinuxKeyVaultProvider:()=>H});var z,H,Q=A(()=>{"use strict";z=util.promisify(child_process.execFile),H=class{static async isAvailable(){let e=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let n of e)try{return i.accessSync(n,i.constants.X_OK),!0}catch{}return !1}async getSecret(e,n){try{let{stdout:r}=await z("secret-tool",["lookup","service",e,"account",n]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await new Promise((s,o)=>{let a=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",n]);a.on("error",o),a.on("close",m=>{m===0?s():o(new Error(`secret-tool exited with code ${m}`));}),a.stdin.write(r),a.stdin.end();});}async deleteSecret(e,n){try{return await z("secret-tool",["clear","service",e,"account",n]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var tt={};L(tt,{WindowsKeyVaultProvider:()=>M});var M,et=A(()=>{"use strict";M=class{static async isAvailable(){try{return await O("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,n){return O("keytar").getPassword(e,n)}async setSecret(e,n,r){await O("keytar").setPassword(e,n,r);}async deleteSecret(e,n){return O("keytar").deletePassword(e,n)}getStoragePath(){return "Windows Credential Manager"}};});var mt=Pt((On,pe)=>{pe.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.9.1",description:"Claude Code hooks for Langfuse OTLP tracing \u2014 cross-platform",main:"dist/index.js",bin:{"flow-ai-obs":"dist/cli.js","flow-ai-obs-setup":"dist/setup.js"},scripts:{build:"tsup",test:"jest",typecheck:"tsc --noEmit",lint:"eslint src bin scripts",format:'prettier --write "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"format:check":'prettier --check "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"security-scan":"trufflehog filesystem src/ --fail --no-update --exclude-paths .trufflehogignore",postinstall:`node -e "require('fs').existsSync('dist/setup.js') && require('child_process').execFileSync(process.execPath, ['dist/setup.js'], {stdio:'inherit'})"`,prepublishOnly:"npm run security-scan && npm run build","release:npm":"changeset publish",changeset:"changeset","version-packages":"changeset version","install:hooks":"node dist/cli.js install","auth:login":"node dist/cli.js auth login","auth:logout":"node dist/cli.js auth logout","auth:status":"node dist/cli.js auth status",smoke:"bash scripts/smoke-test.sh","smoke:debug":"bash scripts/smoke-test.sh --debug","smoke:send":"bash scripts/smoke-test.sh --send --allow-http --debug"},files:["dist/","README.md","LICENSE.md"],keywords:["claude-code","langfuse","observability","otlp","hooks","flow","ciandt"],author:"CI&T Flow Team",license:"SEE LICENSE IN LICENSE.md",private:!1,dependencies:{},optionalDependencies:{keytar:"7.9.0"},devDependencies:{"@changesets/changelog-github":"^0.6.0","@changesets/cli":"^2.30.0","@types/jest":"^30.0.0","@types/node":"^25.8.0",jest:"^30.4.2","ts-jest":"^29.4.9",tsup:"^8.5.1","eslint-config-prettier":"^10.1.5",prettier:"^3.5.3",typescript:"^6.0.3","typescript-eslint":"^8.33.0"},engines:{node:">=18.0.0"},overrides:{esbuild:"^0.28.1"},publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/CI-T-HyperX/flow-codeassistant-observability.git"}};});l();var F={credentials:"credentials","token-cache":"tokenCache"};function _(){let t=u__namespace.default.homedir();if(process.platform==="darwin")return d__namespace.default.join(t,"Library","Preferences",E,T);if(process.platform==="win32"){let n=process.env.APPDATA??d__namespace.default.join(t,"AppData","Roaming");return d__namespace.default.join(n,E,T)}let e=process.env.XDG_CONFIG_HOME??d__namespace.default.join(t,".config");return d__namespace.default.join(e,E,T)}function $(){try{let t=i__namespace.default.readFileSync(_(),"utf8");return JSON.parse(t)}catch{return {}}}function K(t){let e=_();i__namespace.default.mkdirSync(d__namespace.default.dirname(e),{recursive:true}),i__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var k=class{static isAvailable(){return true}static hasExistingData(){try{if(!i__namespace.default.existsSync(_()))return !1;let e=JSON.parse(i__namespace.default.readFileSync(_(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,n){let r=$(),s=F[n]??n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(e,n,r){let s=$(),o=F[n]??n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;K(s);}async deleteSecret(e,n){let r=$(),s=F[n]??n;return s in r?(delete r[s],K(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${_()}`}};async function nt(){return await zt()??new k}async function zt(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(q(),X));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Q(),Z));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(et(),tt));return await t.isAvailable()?new t:null}default:return null}}l();var Zt=y.SERVICE,Qt=y.ACCOUNT_CREDS;y.ACCOUNT_TOKEN;var V=null;function te(){return V||(V=nt()),V}async function rt(){let e=await(await te()).getSecret(Zt,Qt);if(!e)return null;try{return JSON.parse(e)}catch{return null}}l();l();l();d.join(u.tmpdir(),U);!process.env.NO_COLOR&&process.stdout.isTTY;function j(){return process.platform==="win32"?false:process.getuid?.()===0}function st(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return {home:e,username:process.env.SUDO_USER}}return {home:u__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||u__namespace.userInfo().username}}function P(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.USERPROFILE;if(!t){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(t=n);}if(t){let e=t.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return d__namespace.join(e,".claude","settings.json")}return d__namespace.join(u__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||u__namespace.homedir();return d__namespace.join(t,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return d__namespace.join(e,".claude","settings.json")}return d__namespace.join(u__namespace.homedir(),".claude","settings.json")}var ot="flow-ai-obs",it="config.json";function ct(){if(process.platform==="win32"){let n=process.env.APPDATA||d__namespace.join(u__namespace.homedir(),"AppData","Roaming");return d__namespace.join(n,ot,it)}let t=st(),e=process.env.XDG_CONFIG_HOME||d__namespace.join(t.home,".config");return d__namespace.join(e,ot,it)}var ce=N.LOCK_STALE_MS;function lt(t){try{let e=i__namespace.statSync(t);Date.now()-e.mtimeMs>ce&&i__namespace.unlinkSync(t);}catch{}try{i__namespace.writeFileSync(t,String(process.pid),{flag:"wx"});}catch(e){throw e.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+t):e}}function ut(t){try{i__namespace.unlinkSync(t);}catch{}}function le(t,e){let r=(Array.isArray(t)?t:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(a=>!a.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [e,...r]}function pt(t,e){let n=P(),r=n+".lock",s=[];i__namespace.mkdirSync(d__namespace.dirname(n),{recursive:true}),lt(r);try{if(i__namespace.existsSync(n)){i__namespace.copyFileSync(n,n+".bkp");try{i__namespace.chmodSync(n+".bkp",384);}catch{}}let o=ct();if(i__namespace.existsSync(o)){let c=o+".bkp";i__namespace.copyFileSync(o,c);try{i__namespace.chmodSync(c,384);}catch{}}let a={};try{a=JSON.parse(i__namespace.readFileSync(n,"utf8"));}catch{}let m=a.env&&typeof a.env=="object"?a.env:{};delete m.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:St}=(l(),Ct(J)),wt=St().OTEL_ENDPOINT,vt={...C,OTEL_EXPORTER_OTLP_ENDPOINT:t??wt};a.env={...m,...vt,...e??{}},a.otelHeadersHelper="flow-ai-obs otel-headers",(!a.hooks||typeof a.hooks!="object"||Array.isArray(a.hooks))&&(a.hooks={});let Ot=(c,v)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${c}`,timeout:v}]}),At=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],B=a.hooks;for(let c of At){let v=le(B[c],Ot(c,b[c]));v.length>1&&s.push(c),B[c]=v;}i__namespace.writeFileSync(n,JSON.stringify(a,null,2)+`
|
|
3
|
-
`,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(n,384);}catch{}}finally{ut(r);}return {settingsPath:n,preserved:
|
|
4
|
-
`,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(e,384);}catch{}}finally{ut(n);}}l();function ft(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:
|
|
2
|
+
'use strict';var child_process=require('child_process'),util=require('util'),i=require('fs'),d=require('path'),u=require('os'),fe=require('https');require('readline/promises');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var i__namespace=/*#__PURE__*/_interopNamespace(i);var d__namespace=/*#__PURE__*/_interopNamespace(d);var u__namespace=/*#__PURE__*/_interopNamespace(u);var fe__default=/*#__PURE__*/_interopDefault(fe);var I=Object.defineProperty;var Lt=Object.getOwnPropertyDescriptor;var Rt=Object.getOwnPropertyNames;var Pt=Object.prototype.hasOwnProperty;var O=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var A=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var kt=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(n){throw e=0,n}},L=(t,e)=>{for(var n in e)I(t,n,{get:e[n],enumerable:true});},It=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Rt(e))!Pt.call(t,o)&&o!==n&&I(t,o,{get:()=>e[o],enumerable:!(r=Lt(e,o))||r.enumerable});return t};var Nt=t=>It(I({},"__esModule",{value:true}),t);var J={};L(J,{BUFFER:()=>xt,CONFIG_DIR_NAME:()=>y,CONFIG_FILE_NAME:()=>T,COPILOT_OTEL:()=>$t,DEBUG_LOG_FILENAME:()=>U,ENV:()=>p,FEATURES:()=>Dt,FLOW_URLS:()=>bt,HOOK_TIMEOUTS:()=>b,INSTALLER:()=>C,NATIVE_OTEL:()=>N,OTLP:()=>Ut,STATE_FILE_PREFIX:()=>Vt,TRACE_LIMITS:()=>Ht,VAULT:()=>E,getFlowBaseUrl:()=>h,getFlowUrls:()=>R,getLlmProxy:()=>Ft,getMetrics:()=>Mt});function h(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():Ct}function R(){let t=h();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${t}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${t}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${t}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${t}/otel`}}function Ft(){let t=h();return {ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${t}/flow-llm-proxy/`,ANTHROPIC_MODEL:process.env.FLOW_LLM_PROXY_MODEL??"anthropic.claude-4-6-sonnet",ANTHROPIC_SMALL_FAST_MODEL:process.env.FLOW_LLM_PROXY_SMALL_MODEL??"anthropic.claude-4-6-haiku",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"}}function Mt(){let t=h();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var Ct,bt,E,y,T,Ut,N,$t,p,Dt,C,b,xt,U,Ht,Vt,l=A(()=>{"use strict";Ct="https://flow.ciandt.com";bt=R(),E={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},y="FLOW-nodejs",T="config.json",Ut={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};N={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"},$t={ENABLED_KEY:"github.copilot.chat.otel.enabled",EXPORTER_TYPE_KEY:"github.copilot.chat.otel.exporterType",ENDPOINT_KEY:"github.copilot.chat.otel.otlpEndpoint",ENABLED_VALUE:!0,EXPORTER_TYPE_VALUE:"otlp-http"},p={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_MODEL:"ANTHROPIC_MODEL",ANTHROPIC_AUTH_TOKEN:"ANTHROPIC_AUTH_TOKEN",FLOW_OBS_DEBUG:"FLOW_TELEMETRY_DEBUG",FLOW_OBS_ALLOW_HTTP:"FLOW_TELEMETRY_ALLOW_HTTP",BUFFER_TTL_DAYS:"FLOW_TELEMETRY_BUFFER_TTL_DAYS",BUFFER_MAX_FILES:"FLOW_TELEMETRY_BUFFER_MAX_FILES"},Dt={KEYCHAIN_ENABLED:!1},C={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3,CLI:"flow-ai-obs "},b={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},xt={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},U="flow-ai-obs-debug.log",Ht={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};Vt="flow-obs-";});var X={};L(X,{MacOsKeyVaultProvider:()=>x});var D,x,q=A(()=>{"use strict";D=util.promisify(child_process.execFile),x=class{static async isAvailable(){try{return i.accessSync("/usr/bin/security",i.constants.X_OK),!0}catch{return !1}}async getSecret(e,n){try{let{stdout:r}=await D("security",["find-generic-password","-w","-a",n,"-s",e]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await D("security",["add-generic-password","-U","-a",n,"-s",e,"-w",r]);}async deleteSecret(e,n){try{return await D("security",["delete-generic-password","-a",n,"-s",e]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var Z={};L(Z,{LinuxKeyVaultProvider:()=>H});var z,H,Q=A(()=>{"use strict";z=util.promisify(child_process.execFile),H=class{static async isAvailable(){let e=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let n of e)try{return i.accessSync(n,i.constants.X_OK),!0}catch{}return !1}async getSecret(e,n){try{let{stdout:r}=await z("secret-tool",["lookup","service",e,"account",n]);return r.trim()||null}catch{return null}}async setSecret(e,n,r){await new Promise((o,s)=>{let a=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",n]);a.on("error",s),a.on("close",m=>{m===0?o():s(new Error(`secret-tool exited with code ${m}`));}),a.stdin.write(r),a.stdin.end();});}async deleteSecret(e,n){try{return await z("secret-tool",["clear","service",e,"account",n]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var tt={};L(tt,{WindowsKeyVaultProvider:()=>M});var M,et=A(()=>{"use strict";M=class{static async isAvailable(){try{return await O("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,n){return O("keytar").getPassword(e,n)}async setSecret(e,n,r){await O("keytar").setPassword(e,n,r);}async deleteSecret(e,n){return O("keytar").deletePassword(e,n)}getStoragePath(){return "Windows Credential Manager"}};});var mt=kt((An,de)=>{de.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.10.0-beta.693",description:"Claude Code hooks for Langfuse OTLP tracing \u2014 cross-platform",main:"dist/index.js",bin:{"flow-ai-obs":"dist/cli.js","flow-ai-obs-setup":"dist/setup.js"},scripts:{build:"tsup",test:"jest",typecheck:"tsc --noEmit",lint:"eslint src bin scripts",format:'prettier --write "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"format:check":'prettier --check "src/**/*.ts" "bin/**/*.ts" "scripts/**/*.ts"',"security-scan":"trufflehog filesystem src/ --fail --no-update --exclude-paths .trufflehogignore",postinstall:`node -e "require('fs').existsSync('dist/setup.js') && require('child_process').execFileSync(process.execPath, ['dist/setup.js'], {stdio:'inherit'})"`,prepublishOnly:"npm run security-scan && npm run build","release:npm":"changeset publish",changeset:"changeset","version-packages":"changeset version","install:hooks":"node dist/cli.js install","auth:login":"node dist/cli.js auth login","auth:logout":"node dist/cli.js auth logout","auth:status":"node dist/cli.js auth status",smoke:"bash scripts/smoke-test.sh","smoke:debug":"bash scripts/smoke-test.sh --debug","smoke:send":"bash scripts/smoke-test.sh --send --allow-http --debug"},files:["dist/","README.md","LICENSE.md"],keywords:["claude-code","langfuse","observability","otlp","hooks","flow","ciandt"],author:"CI&T Flow Team",license:"SEE LICENSE IN LICENSE.md",private:!1,dependencies:{},optionalDependencies:{keytar:"7.9.0"},devDependencies:{"@changesets/changelog-github":"^0.6.0","@changesets/cli":"^2.30.0","@types/jest":"^30.0.0","@types/node":"^25.8.0",jest:"^30.4.2","ts-jest":"^29.4.9",tsup:"^8.5.1","eslint-config-prettier":"^10.1.5",prettier:"^3.5.3",typescript:"^6.0.3","typescript-eslint":"^8.33.0"},engines:{node:">=18.0.0"},overrides:{esbuild:"^0.28.1"},publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/CI-T-HyperX/flow-codeassistant-observability.git"}};});l();var F={credentials:"credentials","token-cache":"tokenCache"};function _(){let t=u__namespace.default.homedir();if(process.platform==="darwin")return d__namespace.default.join(t,"Library","Preferences",y,T);if(process.platform==="win32"){let n=process.env.APPDATA??d__namespace.default.join(t,"AppData","Roaming");return d__namespace.default.join(n,y,T)}let e=process.env.XDG_CONFIG_HOME??d__namespace.default.join(t,".config");return d__namespace.default.join(e,y,T)}function $(){try{let t=i__namespace.default.readFileSync(_(),"utf8");return JSON.parse(t)}catch{return {}}}function K(t){let e=_();i__namespace.default.mkdirSync(d__namespace.default.dirname(e),{recursive:true}),i__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var P=class{static isAvailable(){return true}static hasExistingData(){try{if(!i__namespace.default.existsSync(_()))return !1;let e=JSON.parse(i__namespace.default.readFileSync(_(),"utf8"));return !!(e&&e.credentials)}catch{return false}}async getSecret(e,n){let r=$(),o=F[n]??n,s=r[o];return s?typeof s=="string"?s:JSON.stringify(s):null}async setSecret(e,n,r){let o=$(),s=F[n]??n;if(n==="token-cache")try{o[s]=JSON.parse(r);}catch{o[s]=r;}else o[s]=r;K(o);}async deleteSecret(e,n){let r=$(),o=F[n]??n;return o in r?(delete r[o],K(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${_()}`}};async function nt(){return await Zt()??new P}async function Zt(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(q(),X));return await t.isAvailable()?new t:null}case "linux":{if(process.env.WSL_DISTRO_NAME)return null;let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Q(),Z));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(et(),tt));return await t.isAvailable()?new t:null}default:return null}}l();var Qt=E.SERVICE,te=E.ACCOUNT_CREDS;E.ACCOUNT_TOKEN;var V=null;function ee(){return V||(V=nt()),V}async function rt(){let e=await(await ee()).getSecret(Qt,te);if(!e)return null;try{return JSON.parse(e)}catch{return null}}l();l();l();d.join(u.tmpdir(),U);!process.env.NO_COLOR&&process.stdout.isTTY;function Y(){return process.platform==="win32"?false:process.getuid?.()===0}function ot(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return {home:e,username:process.env.SUDO_USER}}return {home:u__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||u__namespace.userInfo().username}}function k(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.USERPROFILE;if(!t){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(t=n);}if(t){let e=t.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return d__namespace.join(e,".claude","settings.json")}return d__namespace.join(u__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||u__namespace.homedir();return d__namespace.join(t,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let e=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(e)return d__namespace.join(e,".claude","settings.json")}return d__namespace.join(u__namespace.homedir(),".claude","settings.json")}var st="flow-ai-obs",it="config.json";function ct(){if(process.platform==="win32"){let n=process.env.APPDATA||d__namespace.join(u__namespace.homedir(),"AppData","Roaming");return d__namespace.join(n,st,it)}let t=ot(),e=process.env.XDG_CONFIG_HOME||d__namespace.join(t.home,".config");return d__namespace.join(e,st,it)}var le=C.LOCK_STALE_MS;function lt(t){try{let e=i__namespace.statSync(t);Date.now()-e.mtimeMs>le&&i__namespace.unlinkSync(t);}catch{}try{i__namespace.writeFileSync(t,String(process.pid),{flag:"wx"});}catch(e){throw e.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+t):e}}function ut(t){try{i__namespace.unlinkSync(t);}catch{}}function ue(t,e){let r=(Array.isArray(t)?t:[]).map(o=>{if(!Array.isArray(o?.hooks))return null;let s=o.hooks.filter(a=>!a.command?.startsWith?.("flow-ai-obs "));return s.length>0?{...o,hooks:s}:null}).filter(o=>o!=null);return [e,...r]}function pt(t,e){let n=k(),r=n+".lock",o=[];i__namespace.mkdirSync(d__namespace.dirname(n),{recursive:true}),lt(r);try{if(i__namespace.existsSync(n)){i__namespace.copyFileSync(n,n+".bkp");try{i__namespace.chmodSync(n+".bkp",384);}catch{}}let s=ct();if(i__namespace.existsSync(s)){let c=s+".bkp";i__namespace.copyFileSync(s,c);try{i__namespace.chmodSync(c,384);}catch{}}let a={};try{a=JSON.parse(i__namespace.readFileSync(n,"utf8"));}catch{}let m=a.env&&typeof a.env=="object"?a.env:{};delete m.OTEL_EXPORTER_OTLP_HEADERS;let{getFlowUrls:St}=(l(),Nt(J)),wt=St().OTEL_ENDPOINT,vt={...N,OTEL_EXPORTER_OTLP_ENDPOINT:t??wt};a.env={...m,...vt,...e??{}},a.otelHeadersHelper="flow-ai-obs otel-headers",(!a.hooks||typeof a.hooks!="object"||Array.isArray(a.hooks))&&(a.hooks={});let Ot=(c,v)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${c}`,timeout:v}]}),At=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],B=a.hooks;for(let c of At){let v=ue(B[c],Ot(c,b[c]));v.length>1&&o.push(c),B[c]=v;}i__namespace.writeFileSync(n,JSON.stringify(a,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(n,384);}catch{}}finally{ut(r);}return {settingsPath:n,preserved:o}}function dt(t){let e=k(),n=e+".lock";i__namespace.mkdirSync(d__namespace.dirname(e),{recursive:true}),lt(n);try{let r={};try{r=JSON.parse(i__namespace.readFileSync(e,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,t),i__namespace.writeFileSync(e,JSON.stringify(r,null,2)+`
|
|
4
|
+
`,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(e,384);}catch{}}finally{ut(n);}}l();function ft(t){if(!t)return null;try{let e=t.split(".");if(e.length<2)return null;let n=JSON.parse(Buffer.from(e[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:o,tenant:s}=n;return !r||!o||!s?null:{clientId:r,clientSecret:o,tenant:s}}catch{return null}}function gt(t){let e=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),n=Buffer.from(JSON.stringify({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant})).toString("base64url");return `${e}.${n}.`}l();var W;function Et(){return W||(W=mt()),W}var yt=d__namespace.default.join(u__namespace.default.tmpdir(),"flow-obs-update-cache.json"),he=1440*60*1e3,Ee=3e3;function ye(t,e){let n=s=>{let a=String(s).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return a?[+a[1],+a[2],+a[3]]:null},r=n(t),o=n(e);return !r||!o?false:o[0]!==r[0]?o[0]>r[0]:o[1]!==r[1]?o[1]>r[1]:o[2]>r[2]}function Te(){try{let t=JSON.parse(i__namespace.default.readFileSync(yt,"utf8"));return typeof t.latestVersion!="string"||Date.now()-t.checkedAt>=he?null:t}catch{return null}}function _e(t,e,n=Date.now()){try{i__namespace.default.writeFileSync(yt,JSON.stringify({latestVersion:t,updatePriority:e??null,checkedAt:n}),{mode:384});}catch{}}function Se(t){let e=Et().name,n=fe__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`,{timeout:Ee},r=>{if(r.statusCode!==200)return r.resume(),t(new Error(`HTTP ${r.statusCode}`));let o="";r.setEncoding("utf8"),r.on("data",s=>{o+=s;}),r.on("end",()=>{try{let s=JSON.parse(o);if(typeof s.version!="string")throw new Error("no version field");t(null,{version:s.version,updatePriority:typeof s.updatePriority=="string"?s.updatePriority:null});}catch(s){t(s);}});});n.on("error",t),n.on("timeout",()=>{n.destroy(new Error("timeout"));});}function Tt(){try{if(Te())return;setImmediate(()=>{Se((t,e)=>{t||!e||ye(Et().version,e.version)&&_e(e.version,e.updatePriority,0);});});}catch{}}var we=d__namespace.default.resolve(__dirname,".."),ve=process.env.INIT_CWD?d__namespace.default.resolve(process.env.INIT_CWD):null;ve===we&&process.exit(0);Y()&&(process.stderr.write(`
|
|
5
5
|
[flow-ai-obs] \u2717 Do not install with sudo.
|
|
6
6
|
Run without sudo: npm install -g @ciandt-flow/flow-ai-obs
|
|
7
7
|
|
|
8
|
-
`),process.exit(1));async function
|
|
8
|
+
`),process.exit(1));async function Oe(){try{pt();}catch{}let t=await rt();if(!t){process.stderr.write(`
|
|
9
9
|
[flow-ai-obs] No credentials found.
|
|
10
10
|
Run \`flow-ai-obs auth login\` to authenticate and enable telemetry.
|
|
11
11
|
|
|
12
|
-
`);return}let e=ft(process.env[p.ANTHROPIC_AUTH_TOKEN]);if(!e||e.clientId!==t.clientId||e.clientSecret!==t.clientSecret||e.tenant!==t.tenant)try{let r=gt(t);dt({[p.ANTHROPIC_AUTH_TOKEN]:r});}catch{}}
|
|
12
|
+
`);return}let e=ft(process.env[p.ANTHROPIC_AUTH_TOKEN]);if(!e||e.clientId!==t.clientId||e.clientSecret!==t.clientSecret||e.tenant!==t.tenant)try{let r=gt(t);dt({[p.ANTHROPIC_AUTH_TOKEN]:r});}catch{}}Oe().catch(()=>{}).finally(()=>Tt());
|