@ciandt-flow/flow-ai-obs 0.8.1 → 0.8.2
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 +142 -145
- package/dist/setup.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,198 +1,197 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var
|
|
3
|
-
`);}catch(i){throw r.close(),i}if(r.close(),e!==void 0)return e;throw new Error("Too many invalid attempts for yes/no prompt")}async function Sr(t,e){let r=
|
|
2
|
+
'use strict';var Re=require('readline/promises'),us=require('https'),S=require('fs'),lt=require('os'),Rt=require('path'),child_process=require('child_process'),vs=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 Re__namespace=/*#__PURE__*/_interopNamespace(Re);var us__default=/*#__PURE__*/_interopDefault(us);var S__namespace=/*#__PURE__*/_interopNamespace(S);var lt__namespace=/*#__PURE__*/_interopNamespace(lt);var Rt__namespace=/*#__PURE__*/_interopNamespace(Rt);var vs__default=/*#__PURE__*/_interopDefault(vs);var ve=Object.defineProperty;var ns=Object.getOwnPropertyDescriptor;var ss=Object.getOwnPropertyNames;var os=Object.prototype.hasOwnProperty;var xt=(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 f=(t,e,r)=>()=>{if(r)throw r[0];try{return t&&(e=t(t=0)),e}catch(n){throw r=[n],n}};var is=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(r){throw e=0,r}},j=(t,e)=>{for(var r in e)ve(t,r,{get:e[r],enumerable:true});},as=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ss(e))!os.call(t,s)&&s!==r&&ve(t,s,{get:()=>e[s],enumerable:!(n=ns(e,s))||n.enumerable});return t};var R=t=>as(ve({},"__esModule",{value:true}),t);var oe=is((Qo,cs)=>{cs.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.8.2",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"}};});var Le={};j(Le,{bold:()=>W,cyan:()=>I,dim:()=>w,green:()=>C,red:()=>L,yellow:()=>A});function Et(t,e){return ls?r=>`\x1B[${t}m${r}\x1B[${e}m`:r=>r}var ls,C,L,A,I,W,w,at=f(()=>{"use strict";ls=!process.env.NO_COLOR&&process.stdout.isTTY;C=Et("32","39"),L=Et("31","39"),A=Et("33","39"),I=Et("36","39"),W=Et("1","22"),w=Et("2","22");});function Tt(){return process.stdout.isTTY===true&&process.stdin.isTTY===true&&!process.argv.includes("--no-interactive")}async function Ie(t,e){let r=Re__namespace.createInterface({input:process.stdin,output:process.stdout}),s=`${t} ${e===true?"(Y/n)":e===false?"(y/N)":"(y/n)"}: `;for(let o=1;o<=3;o++)try{let i=(await r.question(s)).trim().toLowerCase();if(i===""&&e!==void 0)return r.close(),e;if(i==="y"||i==="yes")return r.close(),!0;if(i==="n"||i==="no")return r.close(),!1;o<3&&process.stdout.write(` Invalid input. Please answer "y" or "n".
|
|
3
|
+
`);}catch(i){throw r.close(),i}if(r.close(),e!==void 0)return e;throw new Error("Too many invalid attempts for yes/no prompt")}async function Sr(t,e){let r=Re__namespace.createInterface({input:process.stdin,output:process.stdout});try{let n=(await r.question(`${t}: `)).trim();if(e);return n}catch(n){throw n}finally{r.close();}}var be=f(()=>{"use strict";});var _t={};j(_t,{checkForUpdate:()=>ws,checkForUpdateInteractive:()=>Ss,fetchLatestVersionAsync:()=>_r,isNewer:()=>yt,primeUpdateCache:()=>Es});function N(){return Pe||(Pe=oe()),Pe}function yt(t,e){let r=o=>{let i=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return i?[+i[1],+i[2],+i[3]]:null},n=r(t),s=r(e);return !n||!s?false:s[0]!==n[0]?s[0]>n[0]:s[1]!==n[1]?s[1]>n[1]:s[2]>n[2]}function Ue(){try{let t=JSON.parse(S__namespace.default.readFileSync(yr,"utf8"));return typeof t.latestVersion!="string"||Date.now()-t.checkedAt>=fs?null:t}catch{return null}}function $e(t,e,r=Date.now()){try{S__namespace.default.writeFileSync(yr,JSON.stringify({latestVersion:t,updatePriority:e??null,checkedAt:r}),{mode:384});}catch{}}function Fe(t){let e=N().name,r=us__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`,{timeout:ms},n=>{if(n.statusCode!==200)return n.resume(),t(new Error(`HTTP ${n.statusCode}`));let s="";n.setEncoding("utf8"),n.on("data",o=>{s+=o;}),n.on("end",()=>{try{let o=JSON.parse(s);if(typeof o.version!="string")throw new Error("no version field");t(null,{version:o.version,updatePriority:typeof o.updatePriority=="string"?o.updatePriority:null});}catch(o){t(o);}});});r.on("error",t),r.on("timeout",()=>{r.destroy(new Error("timeout"));});}function Ce(t){let e=N().name,n=` Update available: ${N().version} \u2192 ${t}`,s=` Run: npm install -g ${e}`,o=Math.max(n.length,s.length)+2,i="\u2500".repeat(o);process.stderr.write(`
|
|
4
4
|
\u256D${i}\u256E
|
|
5
5
|
\u2502${n.padEnd(o)}\u2502
|
|
6
6
|
\u2502${s.padEnd(o)}\u2502
|
|
7
7
|
\u2570${i}\u256F
|
|
8
8
|
|
|
9
|
-
`);}function
|
|
9
|
+
`);}function Ne(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 gs(t,e=1e4){let r=xt("readline"),n=N().name,o=` Update available: ${N().version} \u2192 ${t}`,i=` Run: npm install -g ${n}`,c=" Install now? [y/N]: ",a=Math.max(o.length,i.length,c.length-2)+2,l="\u2500".repeat(a);return process.stderr.write(`
|
|
13
13
|
\u256D${l}\u256E
|
|
14
|
-
\u2502${o.padEnd(
|
|
15
|
-
\u2502${i.padEnd(
|
|
16
|
-
\u2502${
|
|
14
|
+
\u2502${o.padEnd(a)}\u2502
|
|
15
|
+
\u2502${i.padEnd(a)}\u2502
|
|
16
|
+
\u2502${c.padEnd(a)}\u2502
|
|
17
17
|
\u2570${l}\u256F
|
|
18
|
-
`),new Promise(
|
|
19
|
-
`),
|
|
18
|
+
`),new Promise(h=>{let g=r.createInterface({input:process.stdin,output:void 0,terminal:false}),m=false;function E(O){m||(m=true,clearTimeout(k),g.close(),process.stderr.write(`
|
|
19
|
+
`),h(O));}let k=setTimeout(()=>E(false),e);g.once("line",O=>E(O.trim().toLowerCase()==="y")),g.once("close",()=>E(false));})}async function hs(t){let e=N().name;return process.stderr.write(` Installing ${e}@${t}...
|
|
20
20
|
`),new Promise(r=>{let n=child_process.spawn("npm",["install","-g",`${e}@${t}`],{stdio:"inherit"});n.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
|
`),r();}),n.on("error",()=>{process.stderr.write(` \u2717 Update failed \u2014 continuing with current version.
|
|
25
25
|
|
|
26
|
-
`),r();});})}function
|
|
27
|
-
`;try{
|
|
28
|
-
`);}}var
|
|
26
|
+
`),r();});})}function _r(){return new Promise(t=>{Fe((e,r)=>t(e||!r?null:r));})}function ws(){try{let t=Ue();if(t){yt(N().version,t.latestVersion)&&(t.updatePriority==="auto"?Ne(t.latestVersion):Ce(t.latestVersion));return}setImmediate(()=>{Fe((e,r)=>{e||!r||($e(r.version,r.updatePriority),yt(N().version,r.version)&&(r.updatePriority==="auto"?Ne(r.version):Ce(r.version)));});});}catch{}}async function Ss(t={}){try{let e=Ue();if(e){if(!yt(N().version,e.latestVersion))return}else {let n=await _r();if(!n||($e(n.version,n.updatePriority),!yt(N().version,n.version)))return;e={latestVersion:n.version,updatePriority:n.updatePriority,checkedAt:Date.now()};}if(e.updatePriority==="auto"){Ne(e.latestVersion);return}if(!Tt()){Ce(e.latestVersion);return}await gs(e.latestVersion,t.timeoutMs)&&await hs(e.latestVersion);}catch{}}function Es(){try{if(Ue())return;setImmediate(()=>{Fe((t,e)=>{t||!e||yt(N().version,e.version)&&$e(e.version,e.updatePriority,0);});});}catch{}}var Pe,yr,fs,ms,kt=f(()=>{"use strict";be();yr=Rt__namespace.default.join(lt__namespace.default.tmpdir(),"flow-obs-update-cache.json"),fs=1440*60*1e3,ms=3e3;});function U(){let t=process.env.FLOW_BASE_URL;return t&&t.trim()?t.trim():b}function Ot(){let t=U();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 Dt(){let t=U();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-sonnet",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"}}function Be(){let t=U();return {API_URL:process.env.FLOW_METRICS_URL||`${t}/metrics-collector-api/log-event`,BOOSTER:"flow-ai-obs"}}var b,Ts,ie,ae,ce,xe,X,d,kr,De,B,Or,V,_=f(()=>{"use strict";b="https://flow.ciandt.com";Ts=Ot(),ie={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials",ACCOUNT_TOKEN:"token-cache"},ae="FLOW-nodejs",ce="config.json",xe={SCOPE_NAME:"flow-ai-obs",SCOPE_VERSION:"0.1.0"};X={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:Ts.OTEL_ENDPOINT,OTEL_EXPORTER_OTLP_PROTOCOL:"http/json",OTEL_METRICS_EXPORTER:"otlp",OTEL_LOGS_EXPORTER:"otlp",OTEL_LOG_TOOL_DETAILS:"1",OTEL_LOG_USER_PROMPTS:"1"},d={FLOW_TELEMETRY:"FLOW_TELEMETRY",FLOW_TELEMETRY_GATEWAY:"FLOW_TELEMETRY_GATEWAY_URL",LANGFUSE_BASE_URL:"LANGFUSE_BASE_URL",LANGFUSE_PUBLIC_KEY:"LANGFUSE_PUBLIC_KEY",LANGFUSE_SECRET_KEY:"LANGFUSE_SECRET_KEY",ANTHROPIC_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"},kr={LOCK_STALE_MS:3e4,CONNECTIVITY_MAX_RETRY:3,CONNECTIVITY_RETRY_MS:2e3},De={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15},B={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},Or="flow-ai-obs-debug.log",V={TOOL_INPUT:2e4,TOOL_OUTPUT:2e4,TRACE_OUTPUT:2e4,USER_INSTRUCTION:1e4,TRACE_INPUT:5e4,TOOL_BRIEF:60};});function u(...t){if(process.env[d.FLOW_OBS_DEBUG]!=="1")return;let e=`[${new Date().toISOString()}] ${t.join(" ")}
|
|
27
|
+
`;try{S.writeFileSync(Os,e,{flag:"a"});}catch(r){process.stderr.write(`[flow-obs debug ERROR] ${r.message}
|
|
28
|
+
`);}}var Os,M=f(()=>{"use strict";_();Os=Rt.join(lt.tmpdir(),Or);});function Rs(t){if(!Ls.test(t))throw new Error(`Invalid tenant value: "${t}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}function Is(t,e){let r=e.length>400?e.slice(0,400)+"\u2026":e;u("toAuthError",`status=${t} body=${r}`);try{let n=JSON.parse(e);if(typeof n.error=="string"&&(u("toAuthError",`api_error_code=${n.error}`+(n.message?` api_message=${n.message}`:"")),Ar[n.error]))return new ct(Ar[n.error])}catch{}return t===401||t===403||t===500?new ct("Invalid credentials"):t>=400&&t<500?new ct("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}function Y(t){return new Promise((e,r)=>{try{Rs(t.tenant);}catch(l){return r(l)}let n=JSON.stringify({clientSecret:t.clientSecret}),s=new URL(Ot().AUTH_ENGINE),o=s.protocol==="https:",i={hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname+s.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(n),FlowTenant:t.tenant}};u("getToken",`requesting token tenant=${t.tenant} host=${i.hostname} path=${i.path}`);let a=(o?us__default.default:vs__default.default).request(i,l=>{let h=[];l.on("data",g=>h.push(g)),l.on("end",()=>{let g=h.join("");if((l.statusCode??0)>=400)return r(Is(l.statusCode??0,g));let m;try{m=JSON.parse(g);}catch{return r(new Error("Invalid response from auth engine"))}let E=m.expires_at??new Date(Date.now()+(m.expires_in??3600)*1e3).toISOString();e({accessToken:m.access_token??"",expiresAt:E});});});a.on("error",l=>r(new Error(`Network error: ${l.message}`))),a.write(n),a.end();})}var ct,Ls,Ar,At=f(()=>{"use strict";_();M();ct=class extends Error{constructor(e){super(e),this.name="AuthError";}},Ls=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;Ar={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 vr(){return process.platform==="win32"?false:process.getuid?.()===0}function vt(){if(vr())return process.stderr.write(`
|
|
29
29
|
`+L(` \u2717 flow-ai-obs is not supported in a sudo context.
|
|
30
30
|
|
|
31
|
-
`)+
|
|
31
|
+
`)+I(` 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{
|
|
36
|
-
`,{encoding:"utf8",mode:384});try{g__namespace.chmodSync(t,384);}catch{}}finally{fe(e);}return {settingsPath:t,preserved:r}}function xr(t){let e=v(),r=e+".lock";g__namespace.mkdirSync(It__namespace.dirname(e),{recursive:true}),pe(r);try{let n={};try{n=JSON.parse(g__namespace.readFileSync(e,"utf8"));}catch{return}if(!n.env||typeof n.env!="object")return;for(let s of t)delete n.env[s];g__namespace.writeFileSync(e,JSON.stringify(n,null,2)+`
|
|
37
|
-
`,{encoding:"utf8",mode:384});try{g__namespace.chmodSync(e,384);}catch{}}finally{fe(r);}}var Us,Vt=m(()=>{"use strict";O();vt();ue();We();Us=Ar.LOCK_STALE_MS;});function Wt(){let t=lt__namespace.default.homedir();if(process.platform==="darwin")return It__namespace.default.join(t,"Library","Preferences",ae,ce);if(process.platform==="win32"){let r=process.env.APPDATA??It__namespace.default.join(t,"AppData","Roaming");return It__namespace.default.join(r,ae,ce)}let e=process.env.XDG_CONFIG_HOME??It__namespace.default.join(t,".config");return It__namespace.default.join(e,ae,ce)}function Ge(){try{let t=g__namespace.default.readFileSync(Wt(),"utf8");return JSON.parse(t)}catch{return {}}}function Dr(t){let e=Wt();g__namespace.default.mkdirSync(It__namespace.default.dirname(e),{recursive:true}),g__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var Ye,me,Br=m(()=>{"use strict";O();Ye={credentials:"credentials","token-cache":"tokenCache"};me=class{static isAvailable(){return !0}static hasExistingData(){try{if(!g__namespace.default.existsSync(Wt()))return !1;let e=JSON.parse(g__namespace.default.readFileSync(Wt(),"utf8"));return !!(e&&e.credentials)}catch{return !1}}async getSecret(e,r){let n=Ge(),s=Ye[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(e,r,n){let s=Ge(),o=Ye[r]??r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;Dr(s);}async deleteSecret(e,r){let n=Ge(),s=Ye[r]??r;return s in n?(delete n[s],Dr(n),!0):!1}getStoragePath(){return `config.json (unencrypted) \u2014 ${Wt()}`}};});var Mr={};M(Mr,{MacOsKeyVaultProvider:()=>Ke});var Je,Ke,Hr=m(()=>{"use strict";Je=util.promisify(child_process.execFile),Ke=class{static async isAvailable(){try{return g.accessSync("/usr/bin/security",g.constants.X_OK),!0}catch{return !1}}async getSecret(e,r){try{let{stdout:n}=await Je("security",["find-generic-password","-w","-a",r,"-s",e]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await Je("security",["add-generic-password","-U","-a",r,"-s",e,"-w",n]);}async deleteSecret(e,r){try{return await Je("security",["delete-generic-password","-a",r,"-s",e]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var Vr={};M(Vr,{LinuxKeyVaultProvider:()=>qe});var jr,qe,Wr=m(()=>{"use strict";jr=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 r of e)try{return g.accessSync(r,g.constants.X_OK),!0}catch{}return !1}async getSecret(e,r){try{let{stdout:n}=await jr("secret-tool",["lookup","service",e,"account",r]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await new Promise((s,o)=>{let i=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",r]);i.on("error",o),i.on("close",a=>{a===0?s():o(new Error(`secret-tool exited with code ${a}`));}),i.stdin.write(n),i.stdin.end();});}async deleteSecret(e,r){try{return await jr("secret-tool",["clear","service",e,"account",r]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var Yr={};M(Yr,{WindowsKeyVaultProvider:()=>Xe});var Xe,Gr=m(()=>{"use strict";Xe=class{static async isAvailable(){try{return await xt("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,r){return xt("keytar").getPassword(e,r)}async setSecret(e,r,n){await xt("keytar").setPassword(e,r,n);}async deleteSecret(e,r){return xt("keytar").deletePassword(e,r)}getStoragePath(){return "Windows Credential Manager"}};});async function Jr(){return await Ys()??new me}async function Ys(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Hr(),Mr));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Wr(),Vr));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Gr(),Yr));return await t.isAvailable()?new t:null}default:return null}}var Kr=m(()=>{"use strict";Br();});function zr(){return ze||(ze=Jr()),ze}async function Gt(t){await(await zr()).setSecret(qr,Xr,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function Pt(){let e=await(await zr()).getSecret(qr,Xr);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 ge(){let t=await Pt();return t?new Date(t.expiresAt)>new Date:false}async function Jt(){let t=await Pt();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 qr,zi,Xr,ze,he=m(()=>{"use strict";Kr();O();qr=ie.SERVICE,zi=ie.ACCOUNT_CREDS,Xr=ie.ACCOUNT_TOKEN,ze=null;});function Js(t){return Gs.some(e=>e.test(t))}function Ks(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 b(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:s,tenant:o}=r;return !n||!s||!o?null:{clientId:n,clientSecret:s,tenant:o}}catch{return null}}function Zr(t){let e=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),r=Buffer.from(JSON.stringify({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant})).toString("base64url");return `${e}.${r}.`}function dt(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let r=process.env[p.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&&Js(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function Qr(){let t=b(process.env[p.ANTHROPIC_AUTH_TOKEN]);return t?{user:await Jt().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function qs(){return new Date().toISOString().slice(0,10)}async function Xs(t){let e=qs(),r=await Pt();if(r?.lastAuthCheckAt!==e){u("getOrRefreshToken",`daily auth check (last: ${r?.lastAuthCheckAt??"never"})`);try{let o=await W(t);try{await Gt({...o,lastAuthCheckAt:e});}catch{}return u("getOrRefreshToken",`daily check passed, expires=${o.expiresAt}`),o.accessToken}catch(o){if(o instanceof ct)throw o;u("getOrRefreshToken",`daily check network error \u2014 using cache: ${o.message}`);}}let n=r!=null&&new Date(r.expiresAt)>new Date;if(u("getOrRefreshToken",`cacheValid=${n}`),n)return u("getOrRefreshToken",`using cached token, expires=${r.expiresAt}`),r.accessToken;u("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let s=await W(t);try{await Gt({...s,lastAuthCheckAt:e});}catch(o){u("getOrRefreshToken",`token cache save failed (non-fatal): ${o.message}`);}return u("getOrRefreshToken",`token refreshed, expires=${s.expiresAt}`),s.accessToken}function zs(t,e){let r=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function Zs(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 K(){let t=[],e=process.env[p.ANTHROPIC_MODEL]??"",r=b(process.env[p.ANTHROPIC_AUTH_TOKEN]);u("resolveCredentials",r?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),r&&u("resolveCredentials",`clientId=${r.clientId}`,`tenant=${r.tenant}`);let n=r?r.tenant:"",s=process.env[p.FLOW_TELEMETRY]==="true",o=process.env[p.LANGFUSE_BASE_URL],i=process.env[p.LANGFUSE_PUBLIC_KEY],a=process.env[p.LANGFUSE_SECRET_KEY];if(s&&o&&i&&a){let w="",T=n;r&&(w=await Jt().catch(()=>null)??r.clientId);let A={user:w??"",tenant:T??"",team:"",project:"",model:e};t.push({mode:"direct",...Zs(dt(o),i,a),...A}),u("resolveCredentials","direct mode active",`user=${A.user}`,`tenant=${A.tenant}`);}if(!r){if(t.length===0){let w=[];return w.authError=false,w}return t}let c;try{c=await Xs(r);}catch(w){if(u("resolveCredentials",`token refresh failed: ${w.message}`,`(tenant=${r.tenant} clientId=${r.clientId})`),t.length>0)return t.authError=true,t;let T=[];return T.authError=true,T}let d={user:Ks(c)??r.clientId,tenant:n,team:"",project:"",model:e},h=process.env[p.FLOW_TELEMETRY_GATEWAY]??at();return t.push({mode:"gateway",...zs(dt(h),{accessToken:c}),...d}),t}async function tn(){return (await K()).length>0}var Gs,Y=m(()=>{"use strict";he();vt();O();D();Gs=[/^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 we(){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 Qe(){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}}function en(){if(child_process.spawnSync("node",["--version"],{encoding:"utf8",timeout:5e3}).status!==0)return {success:false,error:"no_nodejs",message:`Node.js is not installed. Install Node.js 18+ and try again:
|
|
33
|
+
`),1}var Bt=f(()=>{"use strict";at();});function Lr(){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:lt__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||lt__namespace.userInfo().username}}function v(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let t=process.env.USERPROFILE;if(!t){let r=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();r&&/^[A-Za-z]:\\/.test(r)&&(t=r);}if(t){let e=t.replace(/^([A-Za-z]):/,(r,n)=>`/mnt/${n.toLowerCase()}`).replace(/\\/g,"/");return Rt__namespace.join(e,".claude","settings.json")}return Rt__namespace.join(lt__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let t=process.env.USERPROFILE||lt__namespace.homedir();return Rt__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 Rt__namespace.join(e,".claude","settings.json")}return Rt__namespace.join(lt__namespace.homedir(),".claude","settings.json")}var le=f(()=>{"use strict";Bt();});function ue(){if(process.platform==="win32"){let r=process.env.APPDATA||Rt__namespace.join(lt__namespace.homedir(),"AppData","Roaming");return Rt__namespace.join(r,Rr,Ir)}let t=Lr(),e=process.env.XDG_CONFIG_HOME||Rt__namespace.join(t.home,".config");return Rt__namespace.join(e,Rr,Ir)}function K(){try{let t=S__namespace.readFileSync(v(),"utf8"),r=JSON.parse(t).env?.FLOW_BASE_URL;return typeof r=="string"&&r.trim()?r.trim():null}catch{return null}}var Rr,Ir,Ht=f(()=>{"use strict";le();Rr="flow-ai-obs",Ir="config.json";});function He(t){try{let e=S__namespace.statSync(t);Date.now()-e.mtimeMs>bs&&S__namespace.unlinkSync(t);}catch{}try{S__namespace.writeFileSync(t,String(process.pid),{flag:"wx"});}catch(e){throw e.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+t):e}}function je(t){try{S__namespace.unlinkSync(t);}catch{}}function Cr(t,e){let n=(Array.isArray(t)?t:[]).map(s=>{if(!Array.isArray(s?.hooks))return null;let o=s.hooks.filter(i=>!i.command?.startsWith?.("flow-ai-obs "));return o.length>0?{...s,hooks:o}:null}).filter(s=>s!=null);return [e,...n]}function Nr(){let t=v(),e=t+".lock",r=[];S__namespace.mkdirSync(Rt__namespace.dirname(t),{recursive:true}),He(e);try{if(S__namespace.existsSync(t)){S__namespace.copyFileSync(t,t+".bkp");try{S__namespace.chmodSync(t+".bkp",384);}catch{}}let n=ue();if(S__namespace.existsSync(n)){let l=n+".bkp";S__namespace.copyFileSync(n,l);try{S__namespace.chmodSync(l,384);}catch{}}let s={};try{s=JSON.parse(S__namespace.readFileSync(t,"utf8"));}catch{}let o=s.env&&typeof s.env=="object"?s.env:{};delete o.OTEL_EXPORTER_OTLP_HEADERS,s.env={...o,...X,...Dt()},s.otelHeadersHelper="flow-ai-obs otel-headers",(!s.hooks||typeof s.hooks!="object"||Array.isArray(s.hooks))&&(s.hooks={});let i=(l,h)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${l}`,timeout:h}]}),c=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],a=s.hooks;for(let l of c){let h=Cr(a[l],i(l,De[l]));h.length>1&&r.push(l),a[l]=h;}S__namespace.writeFileSync(t,JSON.stringify(s,null,2)+`
|
|
34
|
+
`,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(t,384);}catch{}}finally{je(e);}return {settingsPath:t,preserved:r}}function Z(t){try{let e=S__namespace.readFileSync(v(),"utf8"),n=JSON.parse(e).env?.[t];return typeof n=="string"?n:null}catch{return null}}function q(t){let e=v(),r=e+".lock";S__namespace.mkdirSync(Rt__namespace.dirname(e),{recursive:true}),He(r);try{let n={};try{n=JSON.parse(S__namespace.readFileSync(e,"utf8"));}catch{}(!n.env||typeof n.env!="object")&&(n.env={}),Object.assign(n.env,t),S__namespace.writeFileSync(e,JSON.stringify(n,null,2)+`
|
|
35
|
+
`,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(e,384);}catch{}}finally{je(r);}}function Ur(){let t=v(),e=t+".lock",r=[];S__namespace.mkdirSync(Rt__namespace.dirname(t),{recursive:true}),He(e);try{if(S__namespace.existsSync(t)){S__namespace.copyFileSync(t,t+".bkp");try{S__namespace.chmodSync(t+".bkp",384);}catch{}}let n={};try{n=JSON.parse(S__namespace.readFileSync(t,"utf8"));}catch{}n.otelHeadersHelper="flow-ai-obs otel-headers",(!n.hooks||typeof n.hooks!="object"||Array.isArray(n.hooks))&&(n.hooks={});let s=(c,a)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${c}`,timeout:a}]}),o=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],i=n.hooks;for(let c of o){let a=Cr(i[c],s(c,De[c]));a.length>1&&r.push(c),i[c]=a;}S__namespace.writeFileSync(t,JSON.stringify(n,null,2)+`
|
|
36
|
+
`,{encoding:"utf8",mode:384});try{S__namespace.chmodSync(t,384);}catch{}}finally{je(e);}return {settingsPath:t,preserved:r}}var bs,jt=f(()=>{"use strict";_();At();le();Ht();bs=kr.LOCK_STALE_MS;});function Wt(){let t=lt__namespace.default.homedir();if(process.platform==="darwin")return Rt__namespace.default.join(t,"Library","Preferences",ae,ce);if(process.platform==="win32"){let r=process.env.APPDATA??Rt__namespace.default.join(t,"AppData","Roaming");return Rt__namespace.default.join(r,ae,ce)}let e=process.env.XDG_CONFIG_HOME??Rt__namespace.default.join(t,".config");return Rt__namespace.default.join(e,ae,ce)}function Ve(){try{let t=S__namespace.default.readFileSync(Wt(),"utf8");return JSON.parse(t)}catch{return {}}}function $r(t){let e=Wt();S__namespace.default.mkdirSync(Rt__namespace.default.dirname(e),{recursive:true}),S__namespace.default.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384});}var We,pe,Fr=f(()=>{"use strict";_();We={credentials:"credentials","token-cache":"tokenCache"};pe=class{static isAvailable(){return !0}static hasExistingData(){try{if(!S__namespace.default.existsSync(Wt()))return !1;let e=JSON.parse(S__namespace.default.readFileSync(Wt(),"utf8"));return !!(e&&e.credentials)}catch{return !1}}async getSecret(e,r){let n=Ve(),s=We[r]??r,o=n[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(e,r,n){let s=Ve(),o=We[r]??r;if(r==="token-cache")try{s[o]=JSON.parse(n);}catch{s[o]=n;}else s[o]=n;$r(s);}async deleteSecret(e,r){let n=Ve(),s=We[r]??r;return s in n?(delete n[s],$r(n),!0):!1}getStoragePath(){return `config.json (unencrypted) \u2014 ${Wt()}`}};});var xr={};j(xr,{MacOsKeyVaultProvider:()=>Ge});var Ye,Ge,Dr=f(()=>{"use strict";Ye=util.promisify(child_process.execFile),Ge=class{static async isAvailable(){try{return S.accessSync("/usr/bin/security",S.constants.X_OK),!0}catch{return !1}}async getSecret(e,r){try{let{stdout:n}=await Ye("security",["find-generic-password","-w","-a",r,"-s",e]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await Ye("security",["add-generic-password","-U","-a",r,"-s",e,"-w",n]);}async deleteSecret(e,r){try{return await Ye("security",["delete-generic-password","-a",r,"-s",e]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var Mr={};j(Mr,{LinuxKeyVaultProvider:()=>Je});var Br,Je,Hr=f(()=>{"use strict";Br=util.promisify(child_process.execFile),Je=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 S.accessSync(r,S.constants.X_OK),!0}catch{}return !1}async getSecret(e,r){try{let{stdout:n}=await Br("secret-tool",["lookup","service",e,"account",r]);return n.trim()||null}catch{return null}}async setSecret(e,r,n){await new Promise((s,o)=>{let i=child_process.spawn("secret-tool",["store","--label",e,"service",e,"account",r]);i.on("error",o),i.on("close",c=>{c===0?s():o(new Error(`secret-tool exited with code ${c}`));}),i.stdin.write(n),i.stdin.end();});}async deleteSecret(e,r){try{return await Br("secret-tool",["clear","service",e,"account",r]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var jr={};j(jr,{WindowsKeyVaultProvider:()=>Ke});var Ke,Wr=f(()=>{"use strict";Ke=class{static async isAvailable(){try{return await xt("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(e,r){return xt("keytar").getPassword(e,r)}async setSecret(e,r,n){await xt("keytar").setPassword(e,r,n);}async deleteSecret(e,r){return xt("keytar").deletePassword(e,r)}getStoragePath(){return "Windows Credential Manager"}};});async function Vr(){return await Hs()??new pe}async function Hs(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Dr(),xr));return await t.isAvailable()?new t:null}case "linux":{let{LinuxKeyVaultProvider:t}=await Promise.resolve().then(()=>(Hr(),Mr));return await t.isAvailable()?new t:null}case "win32":{let{WindowsKeyVaultProvider:t}=await Promise.resolve().then(()=>(Wr(),jr));return await t.isAvailable()?new t:null}default:return null}}var Yr=f(()=>{"use strict";Fr();});function Kr(){return qe||(qe=Vr()),qe}async function Yt(t){await(await Kr()).setSecret(Gr,Jr,JSON.stringify({accessToken:t.accessToken,expiresAt:t.expiresAt,lastAuthCheckAt:t.lastAuthCheckAt}));}async function It(){let e=await(await Kr()).getSecret(Gr,Jr);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 fe(){let t=await It();return t?new Date(t.expiresAt)>new Date:false}async function Gt(){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 Gr,Yi,Jr,qe,me=f(()=>{"use strict";Yr();_();Gr=ie.SERVICE,Yi=ie.ACCOUNT_CREDS,Jr=ie.ACCOUNT_TOKEN,qe=null;});function Ws(t){return js.some(e=>e.test(t))}function Vs(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 $(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:s,tenant:o}=r;return !n||!s||!o?null:{clientId:n,clientSecret:s,tenant:o}}catch{return null}}function qr(t){let e=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),r=Buffer.from(JSON.stringify({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant})).toString("base64url");return `${e}.${r}.`}function ut(t){let e;try{e=new URL(t);}catch{throw new Error(`Invalid URL: ${t}`)}let r=process.env[d.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&&Ws(e.hostname))throw new Error(`SSRF: private/loopback host not allowed: ${e.hostname}`);return t}async function zr(){let t=$(process.env[d.ANTHROPIC_AUTH_TOKEN]);return t?{user:await Gt().catch(()=>null)??t.clientId,tenant:t.tenant}:{user:"",tenant:""}}function Ys(){return new Date().toISOString().slice(0,10)}async function Gs(t){let e=Ys(),r=await It();if(r?.lastAuthCheckAt!==e){u("getOrRefreshToken",`daily auth check (last: ${r?.lastAuthCheckAt??"never"})`);try{let o=await Y(t);try{await Yt({...o,lastAuthCheckAt:e});}catch{}return u("getOrRefreshToken",`daily check passed, expires=${o.expiresAt}`),o.accessToken}catch(o){if(o instanceof ct)throw o;u("getOrRefreshToken",`daily check network error \u2014 using cache: ${o.message}`);}}let n=r!=null&&new Date(r.expiresAt)>new Date;if(u("getOrRefreshToken",`cacheValid=${n}`),n)return u("getOrRefreshToken",`using cached token, expires=${r.expiresAt}`),r.accessToken;u("getOrRefreshToken",`token expired \u2014 refreshing via auth-engine (tenant=${t.tenant} clientId=${t.clientId})`);let s=await Y(t);try{await Yt({...s,lastAuthCheckAt:e});}catch(o){u("getOrRefreshToken",`token cache save failed (non-fatal): ${o.message}`);}return u("getOrRefreshToken",`token refreshed, expires=${s.expiresAt}`),s.accessToken}function Js(t,e){let r=e&&e.accessToken?e.accessToken:"";return {endpoint:t.replace(/\/$/,"")+"/flow-langfuse-gateway/v1/traces",authHeader:`Bearer ${r}`}}function Ks(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 z(){let t=[],e=process.env[d.ANTHROPIC_MODEL]??"",r=$(process.env[d.ANTHROPIC_AUTH_TOKEN]);u("resolveCredentials",r?"credentials resolved from ANTHROPIC_AUTH_TOKEN":"ANTHROPIC_AUTH_TOKEN absent or invalid"),r&&u("resolveCredentials",`clientId=${r.clientId}`,`tenant=${r.tenant}`);let n=r?r.tenant:"",s=process.env[d.FLOW_TELEMETRY]==="true",o=process.env[d.LANGFUSE_BASE_URL],i=process.env[d.LANGFUSE_PUBLIC_KEY],c=process.env[d.LANGFUSE_SECRET_KEY];if(s&&o&&i&&c){let m="",E=n;r&&(m=await Gt().catch(()=>null)??r.clientId);let k={user:m??"",tenant:E??"",team:"",project:"",model:e};t.push({mode:"direct",...Ks(ut(o),i,c),...k}),u("resolveCredentials","direct mode active",`user=${k.user}`,`tenant=${k.tenant}`);}if(!r){if(t.length===0){let m=[];return m.authError=false,m}return t}let a;try{a=await Gs(r);}catch(m){if(u("resolveCredentials",`token refresh failed: ${m.message}`,`(tenant=${r.tenant} clientId=${r.clientId})`),t.length>0)return t.authError=true,t;let E=[];return E.authError=true,E}let h={user:Vs(a)??r.clientId,tenant:n,team:"",project:"",model:e},g=process.env[d.FLOW_TELEMETRY_GATEWAY]??U();return t.push({mode:"gateway",...Js(ut(g),{accessToken:a}),...h}),t}async function Xr(){return (await z()).length>0}var js,G=f(()=>{"use strict";me();At();_();M();js=[/^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 ge(){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 Xe(){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}}function Zr(){if(child_process.spawnSync("node",["--version"],{encoding:"utf8",timeout:5e3}).status!==0)return {success:false,error:"no_nodejs",message:`Node.js is not installed. Install Node.js 18+ and try again:
|
|
38
37
|
${{darwin:`brew install node
|
|
39
38
|
or download from: https://nodejs.org`,win32:`winget install OpenJS.NodeJS
|
|
40
|
-
or download from: https://nodejs.org`,linux:"See package manager instructions at: https://nodejs.org/en/download/package-manager"}[process.platform]??"Download from: https://nodejs.org"}`};let e=child_process.spawnSync("npm",["install","-g",
|
|
41
|
-
npm install -g ${
|
|
42
|
-
sudo npm install -g ${
|
|
39
|
+
or download from: https://nodejs.org`,linux:"See package manager instructions at: https://nodejs.org/en/download/package-manager"}[process.platform]??"Download from: https://nodejs.org"}`};let e=child_process.spawnSync("npm",["install","-g",ze],{encoding:"utf8",stdio:["inherit","inherit","pipe"],timeout:12e4});if(e.status===0)return {success:true};let r=String(e.stderr??""),n=e.error,s=n instanceof Error?n.message:r;return s.includes("EACCES")||s.includes("permission denied")||s.includes("EPERM")||r.includes("EACCES")||r.includes("EPERM")?{success:false,error:"permission_denied",message:process.platform==="win32"?`Run this terminal as Administrator and try again:
|
|
40
|
+
npm install -g ${ze}`:`Try with elevated permissions:
|
|
41
|
+
sudo npm install -g ${ze}`}:{success:false,error:"unknown",message:s||"npm install failed"}}var ze,Ze=f(()=>{"use strict";ze="@anthropic-ai/claude-code";});function tn(){return Rt__namespace.default.join(lt__namespace.default.homedir(),".claude","flow-obs",".logged-out")}function en(){try{S__namespace.default.unlinkSync(tn());}catch{}}function Qe(){try{return S__namespace.default.existsSync(tn())}catch{return false}}var rn=f(()=>{"use strict";});var tr={};j(tr,{promptRaw:()=>dt,runLogin:()=>pt,runStatus:()=>to});function Q(t){return typeof t=="string"?t.replace(Xs,""):t}function dt(t,e={}){return new Promise((r,n)=>{if(typeof process.stdin.setRawMode!="function"){n(new Error("NOT_A_TTY"));return}let{masked:s=false,defaultValue:o=""}=e;process.stdout.write(t+o);let i=o;function c(){try{process.stdin.setRawMode(!1);}catch{}}process.once("uncaughtException",c),process.once("unhandledRejection",c);let a=h=>{if(h===""){l(),n(new Error("SIGINT"));return}if(h==="\r"||h===`
|
|
43
42
|
`){l(),process.stdout.write(`
|
|
44
|
-
`),r(i);return}if(
|
|
43
|
+
`),r(i);return}if(h==="\x7F"){i.length>0&&(i=i.slice(0,-1),process.stdout.write("\b \b"));return}h.startsWith("\x1B")||(i+=h,process.stdout.write(s?"*".repeat(h.length):h));};function l(){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 nn(t){let{accessToken:e,expiresAt:r}=await Y(t),n=qr(t);q({[d.ANTHROPIC_AUTH_TOKEN]:n}),en(),await Yt({accessToken:e,expiresAt:r});}async function Zs(t){try{return await nn(t),process.stdout.write(C(` \u2713 Setup complete. Tenant: ${Q(t.tenant)}
|
|
45
44
|
|
|
46
|
-
`)),0}catch(e){return process.stderr.write(L(` \u2717 Authentication failed: ${
|
|
47
|
-
`)),1}}async function
|
|
48
|
-
`);let t=(await
|
|
49
|
-
`)),1;try{await
|
|
50
|
-
`)),1}return process.stdout.write(
|
|
45
|
+
`)),0}catch(e){return process.stderr.write(L(` \u2717 Authentication failed: ${Q(e.message)}
|
|
46
|
+
`)),1}}async function Qs(){try{process.stdout.write(`
|
|
47
|
+
`);let t=(await dt(I(" ? ")+"Client ID: ")).trim(),e=(await dt(I(" ? ")+"Client Secret: ",{masked:!0})).trim(),r=(await dt(I(" ? ")+"Tenant: ")).trim();if(!t||!e||!r)return process.stderr.write(L(` \u2717 All fields are required
|
|
48
|
+
`)),1;try{await nn({clientId:t,clientSecret:e,tenant:r});}catch(n){return process.stderr.write(L(` \u2717 Authentication failed: ${Q(n.message)}
|
|
49
|
+
`)),1}return process.stdout.write(C(` \u2713 Setup complete. Tenant: ${Q(r)}
|
|
51
50
|
`)),process.stdout.write(` Storage: ANTHROPIC_AUTH_TOKEN (settings.json)
|
|
52
51
|
|
|
53
52
|
`),0}catch(t){if(t.message==="SIGINT"||t.message==="NOT_A_TTY")throw t;return process.stderr.write(L(` \u2717 Unexpected error: ${t.message}
|
|
54
|
-
`)),1}}async function pt(t={}){let e=
|
|
55
|
-
|
|
56
|
-
`)),
|
|
57
|
-
`),process.stdout.write(
|
|
53
|
+
`)),1}}async function pt(t={}){let e=vt();if(e)return e;let r=K()??Z(b)??process.env[b]??U();if(process.stdout.write(w(` Base URL: ${r}
|
|
54
|
+
|
|
55
|
+
`)),t.clientId&&t.clientSecret&&t.tenant)return Zs({clientId:t.clientId,clientSecret:t.clientSecret,tenant:t.tenant});let s=Qe()?null:$(Z(d.ANTHROPIC_AUTH_TOKEN)??process.env[d.ANTHROPIC_AUTH_TOKEN]);if(s){process.stdout.write(`
|
|
56
|
+
`),process.stdout.write(W(` Already authenticated
|
|
57
|
+
`)),process.stdout.write(w(" Tenant: ")+Q(s.tenant)+`
|
|
58
|
+
`),process.stdout.write(w(" Client ID: ")+Q(s.clientId)+`
|
|
58
59
|
`),process.stdout.write(`
|
|
59
|
-
`);let
|
|
60
|
-
`),130;if(
|
|
61
|
-
|
|
62
|
-
`)),0;throw
|
|
63
|
-
|
|
64
|
-
`)),0}try{return await
|
|
65
|
-
`),130;if(
|
|
66
|
-
`)+" Pass --client-id, --client-secret and --tenant, or run `flow-ai-obs auth login` in a terminal.\n\n"),1;throw
|
|
67
|
-
|
|
68
|
-
`)),0)
|
|
69
|
-
|
|
70
|
-
`)),
|
|
71
|
-
`)
|
|
72
|
-
`)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
`),
|
|
76
|
-
`),
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
`),0}var to,Kt=m(()=>{"use strict";he();on();vt();Y();Vt();O();it();Mt();to=/[\x00-\x08\x0B-\x1F\x7F]|\x1b\[[0-9;]*[a-zA-Z]/g;});var or={};M(or,{normalizeCustomUrl:()=>ln,runInit:()=>co,validateCustomUrl:()=>sr});function io(){try{let t=g__namespace.readFileSync(v(),"utf8"),e=JSON.parse(t);return !!(e.env&&e.env[p.ANTHROPIC_AUTH_TOKEN])}catch{return false}}function ao(){let t=de();if(!t)return null;J({FLOW_BASE_URL:t});try{let e=le(),r={};try{r=JSON.parse(g__namespace.readFileSync(e,"utf8"));}catch{return t}delete r.baseUrl,Object.keys(r).length===0?g__namespace.unlinkSync(e):g__namespace.writeFileSync(e,JSON.stringify(r,null,2)+`
|
|
80
|
-
`,{encoding:"utf8",mode:384});}catch{}return t}function ln(t){let e=t.trim().replace(/\\/g,"/");/^https?:\/\//i.test(e)||(e=`https://${e}`);try{let r=new URL(e);return `${r.protocol}//${r.host}`}catch{return e}}function sr(t,e=false){if(e){let o;try{o=new URL(t);}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.
|
|
60
|
+
`);let o;try{o=await dt(I(" ? ")+"Re-authenticate? (y/N): ");}catch(i){if(i.message==="SIGINT")return process.stdout.write(`
|
|
61
|
+
`),130;if(i.message==="NOT_A_TTY")return process.stdout.write(C(` \u2713 Using existing credentials.
|
|
62
|
+
|
|
63
|
+
`)),0;throw i}if(o.trim().toLowerCase()!=="y")return process.stdout.write(C(` \u2713 Using existing credentials.
|
|
64
|
+
|
|
65
|
+
`)),0}try{return await Qs()}catch(o){if(o.message==="SIGINT")return process.stdout.write(`
|
|
66
|
+
`),130;if(o.message==="NOT_A_TTY")return process.stderr.write(L(` \u2717 No credentials found and no TTY available for interactive login.
|
|
67
|
+
`)+" Pass --client-id, --client-secret and --tenant, or run `flow-ai-obs auth login` in a terminal.\n\n"),1;throw o}}async function to(){let t=K()??Z(b)??process.env[b]??U();if(process.stdout.write(w(` Base URL: ${t}
|
|
68
|
+
|
|
69
|
+
`)),Qe())return process.stdout.write(A(" \u26A0 Not authenticated. Run `flow-ai-obs auth login` to set up.\n")),0;let e=$(Z(d.ANTHROPIC_AUTH_TOKEN)??process.env[d.ANTHROPIC_AUTH_TOKEN]);if(!e)return process.stdout.write(A(" \u26A0 Not authenticated. Run `flow-ai-obs auth login` to set up.\n")),0;if(!await fe())return process.stdout.write(A(" \u26A0 Session expired. Run `flow-ai-obs auth login` to re-authenticate.\n")),0;let r=e.clientSecret.length>4?"****...****"+e.clientSecret.slice(-4):"****";return process.stdout.write(`
|
|
70
|
+
`+W(` Authenticated
|
|
71
|
+
`)),process.stdout.write(w(" Tenant: ")+Q(e.tenant)+`
|
|
72
|
+
`),process.stdout.write(w(" Client ID: ")+Q(e.clientId)+`
|
|
73
|
+
`),process.stdout.write(w(" Client Secret: ")+r+`
|
|
74
|
+
`),process.stdout.write(w(" Storage: ")+`ANTHROPIC_AUTH_TOKEN (settings.json)
|
|
75
|
+
|
|
76
|
+
`),0}var Xs,Jt=f(()=>{"use strict";me();rn();At();G();jt();_();at();Bt();Ht();Xs=/[\x00-\x08\x0B-\x1F\x7F]|\x1b\[[0-9;]*[a-zA-Z]/g;});var nr={};j(nr,{normalizeCustomUrl:()=>on,runInit:()=>no,validateCustomUrl:()=>rr});function eo(){try{let t=S__namespace.readFileSync(v(),"utf8"),e=JSON.parse(t);return !!(e.env&&e.env[d.ANTHROPIC_AUTH_TOKEN])}catch{return false}}function ro(){let t=K();if(!t)return null;q({FLOW_BASE_URL:t});try{let e=ue(),r={};try{r=JSON.parse(S__namespace.readFileSync(e,"utf8"));}catch{return t}delete r.baseUrl,Object.keys(r).length===0?S__namespace.unlinkSync(e):S__namespace.writeFileSync(e,JSON.stringify(r,null,2)+`
|
|
77
|
+
`,{encoding:"utf8",mode:384});}catch{}return t}function on(t){let e=t.trim().replace(/\\/g,"/");/^https?:\/\//i.test(e)||(e=`https://${e}`);try{let r=new URL(e);return `${r.protocol}//${r.host}`}catch{return e}}function rr(t,e=false){if(e){let o=/^https?:\/\//i.test(t.trim())?t.trim().replace(/\\/g,"/"):`https://${t.trim().replace(/\\/g,"/")}`,i;try{i=new URL(o);}catch{throw new Error(`Invalid URL: ${t}`)}if(i.protocol!=="https:")throw new Error(`Custom URL must use HTTPS: ${t}`);if(i.pathname!=="/"&&i.pathname!=="")throw new Error(`Custom URL must be a base URL with no path beyond the root.
|
|
78
|
+
Received: ${t}
|
|
79
|
+
Expected: https://tenant.example.com`);if(i.search)throw new Error(`Custom URL must not contain query parameters.
|
|
81
80
|
Received: ${t}
|
|
82
|
-
Expected: https://tenant.example.com`);if(
|
|
81
|
+
Expected: https://tenant.example.com`);if(i.hash)throw new Error(`Custom URL must not contain a fragment.
|
|
83
82
|
Received: ${t}
|
|
84
|
-
Expected: https://tenant.example.com`);if(
|
|
83
|
+
Expected: https://tenant.example.com`);if(i.username||i.password)throw new Error(`Custom URL must not contain embedded credentials.
|
|
85
84
|
Received: ${t}
|
|
86
|
-
Expected: https://tenant.example.com`);let i=process.env[
|
|
85
|
+
Expected: https://tenant.example.com`);if(!i.hostname.includes("."))throw new Error(`Invalid domain: ${i.hostname}. Expected format: tenant.example.com`);let c=`${i.protocol}//${i.host}`,a=process.env[d.FLOW_OBS_ALLOW_HTTP];try{delete process.env[d.FLOW_OBS_ALLOW_HTTP],ut(c);}finally{a!==void 0&&(process.env[d.FLOW_OBS_ALLOW_HTTP]=a);}return c}let r=on(t),n;try{n=new URL(r);}catch{throw new Error(`Invalid URL: ${t}`)}if(n.protocol!=="https:")throw new Error(`Custom URL must use HTTPS: ${t}`);if(!n.hostname.includes("."))throw new Error(`Invalid domain: ${n.hostname}. Expected format: tenant.example.com`);let s=process.env[d.FLOW_OBS_ALLOW_HTTP];try{delete process.env[d.FLOW_OBS_ALLOW_HTTP],ut(r);}finally{s!==void 0&&(process.env[d.FLOW_OBS_ALLOW_HTTP]=s);}return r.replace(/\/$/,"")}async function sn(){for(let t=1;t<=3;t++)try{let e=await Sr(" Enter your Flow domain (e.g., tenant.ciandt.com)");return rr(e)}catch(e){if(process.stderr.write(A(` \u2717 ${e.message}
|
|
87
86
|
|
|
88
87
|
`)),t===3)throw process.stderr.write(L(` Too many invalid attempts.
|
|
89
88
|
|
|
90
|
-
`)),new Error("Too many invalid URL attempts")}throw new Error("Too many invalid URL attempts")}function
|
|
89
|
+
`)),new Error("Too many invalid URL attempts")}throw new Error("Too many invalid URL attempts")}function er(){try{let t=S__namespace.readFileSync(v(),"utf8"),r=JSON.parse(t).env?.FLOW_BASE_URL;return typeof r=="string"&&r.trim()?r.trim():null}catch{return null}}async function no(t={}){let e=vt();if(e)return e;let r=t.url;if(!ge())return process.stderr.write(`
|
|
91
90
|
`+L(` \u2717 Claude Code is not installed or not found in PATH.
|
|
92
91
|
|
|
93
92
|
`)+` flow-ai-obs requires Claude Code to function.
|
|
94
93
|
Install it with:
|
|
95
94
|
|
|
96
|
-
`+
|
|
95
|
+
`+I(" npm install -g @anthropic-ai/claude-code")+`
|
|
97
96
|
|
|
98
|
-
`),1;process.env.WSL_DISTRO_NAME&&process.platform==="linux"&&process.stdout.write(
|
|
99
|
-
`)+
|
|
100
|
-
`)+
|
|
97
|
+
`),1;process.env.WSL_DISTRO_NAME&&process.platform==="linux"&&process.stdout.write(A(` \u26A0 WSL detected. If Claude Code is installed on Windows, install flow-ai-obs
|
|
98
|
+
`)+A(" on Windows too: ")+I(`npm install -g @ciandt-flow/flow-ai-obs
|
|
99
|
+
`)+A(` Running Claude (Windows) + flow-ai-obs (WSL) is not a supported configuration.
|
|
101
100
|
|
|
102
|
-
`));let n=
|
|
103
|
-
`)+
|
|
104
|
-
`)+
|
|
101
|
+
`));let n=ro();if(n&&process.stdout.write(A(` \u26A0 Legacy config migrated.
|
|
102
|
+
`)+w(` Custom URL moved from ~/.config/flow-ai-obs/config.json
|
|
103
|
+
`)+w(` to FLOW_BASE_URL in ~/.claude/settings.json: ${n}
|
|
105
104
|
|
|
106
|
-
`)),!r&&!t.noInteractive&&
|
|
107
|
-
Current base URL: ${
|
|
108
|
-
`),await
|
|
109
|
-
`),await
|
|
110
|
-
`);}if(!r&&!t.noInteractive&&!
|
|
111
|
-
`)+
|
|
112
|
-
`)+(
|
|
105
|
+
`)),!r&&!t.noInteractive&&Tt()){let g=er();try{g?(process.stdout.write(`
|
|
106
|
+
Current base URL: ${W(g)}
|
|
107
|
+
`),await Ie(" Keep this URL?",!0)||(r=await sn())):(process.stdout.write(`
|
|
108
|
+
`),await Ie(" Does your organization use a custom Flow URL?",!1)&&(r=await sn()));}catch{return 1}process.stdout.write(`
|
|
109
|
+
`);}if(!r&&!t.noInteractive&&!Tt()){let g=er(),m=process.env.FLOW_BASE_URL,E=g??m??b,k=!!(g??m);process.stdout.write(A(` \u26A0 Non-interactive environment detected.
|
|
110
|
+
`)+w(` Using URL: ${E}
|
|
111
|
+
`)+(k?"":w(` Run with --custom-url to configure a custom domain.
|
|
113
112
|
`))+`
|
|
114
|
-
`);}let s=null,o
|
|
115
|
-
\u2717 Invalid --custom-url: ${
|
|
113
|
+
`);}let s=null,o;if(r){let g;try{g=rr(r,!0);}catch(E){return process.stderr.write(`
|
|
114
|
+
\u2717 Invalid --custom-url: ${E.message}
|
|
116
115
|
|
|
117
|
-
`),1}let
|
|
118
|
-
`)+
|
|
119
|
-
`)+
|
|
116
|
+
`),1}let m=K();o=g,s=g,m&&m!==g?process.stdout.write(A(` \u26A0 Base URL updated.
|
|
117
|
+
`)+w(` Previous: ${m}
|
|
118
|
+
`)+w(` New: ${g}
|
|
120
119
|
|
|
121
|
-
`)):process.stdout.write(
|
|
120
|
+
`)):process.stdout.write(C(` \u2713 Base URL configured: ${g}
|
|
122
121
|
|
|
123
|
-
`));}if(
|
|
122
|
+
`));}else o=er()??b;let i={FLOW_BASE_URL:o,OTEL_EXPORTER_OTLP_ENDPOINT:`${o}/otel`,ANTHROPIC_BASE_URL:`${o}/flow-llm-proxy/`};if(q(i),process.env.FLOW_BASE_URL=o,!eo())if(t.noInteractive||!Tt())process.stdout.write(A(" \u26A0 No credentials found in settings.json \u2014 run `flow-ai-obs auth login` to authenticate.\n\n"));else {process.stdout.write(A(` \u26A0 No credentials found in settings.json \u2014 authentication required.
|
|
124
123
|
|
|
125
|
-
`));let{runLogin:
|
|
124
|
+
`));let{runLogin:g}=await Promise.resolve().then(()=>(Jt(),tr)),m=await g();if(m!==0)return m}let c,a;try{({settingsPath:c,preserved:a}=Nr());}catch(g){return process.stderr.write(` \u2717 Failed to write settings: ${g.message}
|
|
126
125
|
`),1}process.stdout.write(`
|
|
127
|
-
`+
|
|
128
|
-
`);let
|
|
126
|
+
`+W(" Native OTEL configured")+` (metrics & logs)
|
|
127
|
+
`);let l={...X,OTEL_EXPORTER_OTLP_ENDPOINT:i.OTEL_EXPORTER_OTLP_ENDPOINT};for(let[g,m]of Object.entries(l))process.stdout.write(w(` ${g.padEnd(36)}`)+m+`
|
|
129
128
|
`);process.stdout.write(`
|
|
130
|
-
`),process.stdout.write(
|
|
131
|
-
`),process.stdout.write(
|
|
132
|
-
`),process.stdout.write(
|
|
133
|
-
`),process.stdout.write(
|
|
134
|
-
`),process.stdout.write(
|
|
129
|
+
`),process.stdout.write(W(" Hooks registered")+` (Langfuse trace capture)
|
|
130
|
+
`),process.stdout.write(w(" UserPromptSubmit")+` \u2192 flow-ai-obs UserPromptSubmit (timeout: 5s)
|
|
131
|
+
`),process.stdout.write(w(" PreToolUse ")+` \u2192 flow-ai-obs PreToolUse (timeout: 3s)
|
|
132
|
+
`),process.stdout.write(w(" PostToolUse ")+` \u2192 flow-ai-obs PostToolUse (timeout: 10s)
|
|
133
|
+
`),process.stdout.write(w(" Stop ")+` \u2192 flow-ai-obs Stop (timeout: 15s)
|
|
135
134
|
`),a.length>0&&(process.stdout.write(`
|
|
136
|
-
`),process.stdout.write(
|
|
137
|
-
`)),process.stdout.write(
|
|
135
|
+
`),process.stdout.write(A(` \u26A0 Third-party hooks detected and preserved on: ${a.join(", ")}
|
|
136
|
+
`)),process.stdout.write(w(` flow-ai-obs was prepended \u2014 it executes first.
|
|
138
137
|
`))),process.stdout.write(`
|
|
139
|
-
`),process.stdout.write(
|
|
140
|
-
`),process.stdout.write(
|
|
141
|
-
`),process.stdout.write(
|
|
142
|
-
`));let
|
|
138
|
+
`),process.stdout.write(w(" Settings: ")+c+`
|
|
139
|
+
`),process.stdout.write(w(" Backup: ")+c+`.bkp
|
|
140
|
+
`),process.stdout.write(w(" OTEL auth: flow-ai-obs otel-headers")+w(` (reads ANTHROPIC_AUTH_TOKEN from settings.json)
|
|
141
|
+
`));let h=s??K()??process.env.FLOW_BASE_URL??b;return process.stdout.write(w(" Base URL: ")+h+`
|
|
143
142
|
`),process.stdout.write(`
|
|
144
|
-
`),t.skipHint||(process.stdout.write(
|
|
145
|
-
`)),process.stdout.write(
|
|
146
|
-
${
|
|
147
|
-
`);}function
|
|
148
|
-
`));}function
|
|
149
|
-
`));}function
|
|
150
|
-
`));}function
|
|
151
|
-
`));}async function
|
|
143
|
+
`),t.skipHint||(process.stdout.write(C(` \u2713 Ready. Native OTEL + Langfuse trace capture active.
|
|
144
|
+
`)),process.stdout.write(w(" Run `flow-ai-obs setup` to configure a full environment from scratch.\n\n"))),0}var sr=f(()=>{"use strict";jt();_();at();le();Bt();Ht();G();Ze();be();});var ln={};j(ln,{runSetup:()=>co});function so(){try{return JSON.parse(S__namespace.readFileSync(v(),"utf8"))}catch{return {}}}function oo(t){return !!(t.env??{}).ANTHROPIC_BASE_URL}function io(t){let e=t.hooks??{};return ["UserPromptSubmit","PreToolUse","PostToolUse","Stop"].every(n=>{let s=e[n];return Array.isArray(s)?s.some(o=>{let i=o;return Array.isArray(i?.hooks)&&i.hooks.some(c=>c?.command?.startsWith("flow-ai-obs "))}):false})}async function ao(t){return (await dt(t)).trim().toLowerCase()==="y"}function he(t,e,r){process.stdout.write(`
|
|
145
|
+
${W(`[${t}/${e}]`)} ${r}
|
|
146
|
+
`);}function ft(t){process.stdout.write(C(` \u2713 ${t}
|
|
147
|
+
`));}function an(t){process.stdout.write(A(` \u26A0 ${t}
|
|
148
|
+
`));}function Kt(t){process.stderr.write(L(` \u2717 ${t}
|
|
149
|
+
`));}function mt(t){process.stdout.write(w(` ${t}
|
|
150
|
+
`));}async function co(t={}){let e=vt();if(e)return e;let r=4;process.stdout.write(`
|
|
152
151
|
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
153
152
|
`),process.stdout.write(`\u2551 flow-ai-obs \u2014 setup \u2551
|
|
154
153
|
`),process.stdout.write(`\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
155
154
|
`),process.stdout.write(`
|
|
156
155
|
This will configure your development environment:
|
|
157
|
-
`),process.stdout.write(
|
|
158
|
-
`)),process.stdout.write(
|
|
159
|
-
`)),process.stdout.write(
|
|
160
|
-
`)),process.stdout.write(
|
|
156
|
+
`),process.stdout.write(w(` [1/4] Claude Code Install @anthropic-ai/claude-code (if needed)
|
|
157
|
+
`)),process.stdout.write(w(` [2/4] Proxy Configure Flow LLM routing
|
|
158
|
+
`)),process.stdout.write(w(` [3/4] AI Usage Enable native OTEL telemetry
|
|
159
|
+
`)),process.stdout.write(w(` [4/4] Langfuse Register trace capture hooks
|
|
161
160
|
`)),process.stdout.write(`
|
|
162
|
-
`);let n=
|
|
163
|
-
`)),1;let o=
|
|
164
|
-
`),130;throw
|
|
165
|
-
`+
|
|
166
|
-
`),1;let e;try{e=(await
|
|
161
|
+
`);let n=so();if(he(1,r,"Checking Claude Code..."),ge()){let s=Xe();ft(s?`Already installed (${s}) \u2014 skipping.`:"Already installed \u2014 skipping.");}else {mt("Not found. Installing via npm...");let s=Zr();if(!s.success)return Kt(s.message??"Failed to install Claude Code."),process.stderr.write(L(` Setup aborted at step 1. Resolve the error above and try again.
|
|
162
|
+
`)),1;let o=Xe();ft(o?`Claude Code ${o} installed.`:"Claude Code installed.");}if(he(2,r,"Configuring proxy..."),oo(n)){let s=n.env.ANTHROPIC_BASE_URL;an(`Proxy already configured (${s})`);let o=t.nonInteractive||!process.stdin.isTTY,i=false;if(!o)try{i=await ao(I(" ? ")+"Replace existing proxy configuration? [y/N]: ");}catch(c){if(c.message==="SIGINT")return process.stdout.write(`
|
|
163
|
+
`),130;throw c}if(!i)mt("Keeping existing proxy configuration.");else {let c=await pt(t);if(c!==0)return c;try{q(Dt()),ft("Proxy reconfigured.");}catch(a){return Kt(`Could not write proxy config: ${a.message}`),1}}}else {let s=await pt(t);if(s!==0)return s;try{q(Dt()),ft("Proxy configured."),mt(`Settings: ${v()}`);}catch(o){return Kt(`Could not write proxy config: ${o.message}`),1}}he(3,r,"Configuring AI Usage...");try{if(t.url){let{runInit:s}=await Promise.resolve().then(()=>(sr(),nr)),o=await s({noInteractive:!0,url:t.url,skipHint:!0});if(o!==0)return o}else q(X);ft("AI Usage configured."),mt(`Settings: ${v()}`);}catch(s){return Kt(`Could not write AI Usage config: ${s.message}`),1}if(he(4,r,"Configuring Langfuse..."),io(n))ft("Already configured \u2014 skipping.");else {let s,o;try{({settingsPath:s,preserved:o}=Ur());}catch(i){return Kt(`Could not write hooks: ${i.message}`),1}ft("Hooks registered (UserPromptSubmit, PreToolUse, PostToolUse, Stop)"),o.length>0&&(an(`Third-party hooks preserved on: ${o.join(", ")}`),mt("flow-ai-obs was prepended \u2014 it executes first.")),mt(`Settings: ${s}`),mt(`Backup: ${s}.bkp`);}return process.stdout.write(`
|
|
164
|
+
`+C(" \u2713 Setup complete. Run `claude` to start.\n\n")),0}var un=f(()=>{"use strict";_();at();Bt();Jt();jt();Ze();});var dn={};j(dn,{runOtelHeaders:()=>lo});async function lo(){let t=$(process.env[d.ANTHROPIC_AUTH_TOKEN]);if(!t)return process.stderr.write(`[flow-ai-obs otel-headers] Not authenticated \u2014 run: flow-ai-obs auth login
|
|
165
|
+
`),1;let e;try{e=(await Y(t)).accessToken;}catch(r){return process.stderr.write(`[flow-ai-obs otel-headers] Token fetch failed: ${r.message}
|
|
167
166
|
`),1}return e?(process.stdout.write(`{"Authorization": "Bearer ${e}"}
|
|
168
167
|
`),0):(process.stderr.write(`[flow-ai-obs otel-headers] Empty token received
|
|
169
|
-
`),1)}var
|
|
170
|
-
`);}function
|
|
171
|
-
`);}function
|
|
172
|
-
`);}function
|
|
173
|
-
`);}function
|
|
174
|
-
`);}async function
|
|
175
|
-
`),
|
|
176
|
-
`);let t=()=>
|
|
177
|
-
`);}if(!await
|
|
178
|
-
`);}let r=await
|
|
179
|
-
`);let
|
|
180
|
-
`),process.env[
|
|
181
|
-
`),
|
|
182
|
-
`)[0].slice(0,e).trim()}function
|
|
183
|
-
`);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
|
|
184
|
-
`),r=[],n=0,s=0;for(let o=e.length-1;o>=0;o--)try{let i=JSON.parse(e[o]);if(i.type==="user")break;if(i.type==="assistant"){let
|
|
185
|
-
|
|
186
|
-
`),inputTokens:n,outputTokens:s}}catch{}return null}var
|
|
187
|
-
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function
|
|
188
|
-
`);return}let n=!!(await
|
|
189
|
-
`,{flag:"a",encoding:"utf8",mode:384}),u("sendTraces:dump",`request appendada em ${
|
|
190
|
-
${
|
|
191
|
-
${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${
|
|
192
|
-
`)),
|
|
193
|
-
`),process.stdout.write(JSON.stringify(e));}}var
|
|
194
|
-
`),process.exit(0);});});var
|
|
195
|
-
`),process.exit(0);}else if(
|
|
168
|
+
`),1)}var pn=f(()=>{"use strict";At();G();_();});var mn={};j(mn,{runCheck:()=>uo});function or(t){return !t||t.length<=8?"****":t.slice(0,4)+"****...****"+t.slice(-4)}function qt(t){process.stdout.write(` \u2713 ${t}
|
|
169
|
+
`);}function we(t){process.stdout.write(` \u26A0 ${t}
|
|
170
|
+
`);}function Se(t){process.stdout.write(` \u2717 ${t}
|
|
171
|
+
`);}function P(t){process.stdout.write(` ${t}
|
|
172
|
+
`);}function F(){process.stdout.write(`
|
|
173
|
+
`);}async function uo(){F(),process.stdout.write(` flow-claude-observability \u2014 configuration check
|
|
174
|
+
`),F(),process.stdout.write(` Auth
|
|
175
|
+
`);let t=()=>Z(d.ANTHROPIC_AUTH_TOKEN)??process.env[d.ANTHROPIC_AUTH_TOKEN],e=$(t());if(!e){we("Not authenticated \u2014 starting setup..."),F();let a=await pt();if(a!==0)return a;if(e=$(t()),!e)return Se("Authentication failed"),F(),1;F(),process.stdout.write(` Auth
|
|
176
|
+
`);}if(!await fe()){we("Session expired \u2014 re-authenticating..."),F();let a=await pt();if(a!==0)return a;F(),process.stdout.write(` Auth
|
|
177
|
+
`);}let r=await Gt()||e.clientId,n=K()??Z(b)??process.env[b]??U();qt("Authenticated"),P(`URL: ${n}`),P(`Tenant: ${e.tenant}`),P(`User: ${r}`),F(),process.stdout.write(` Native OTEL
|
|
178
|
+
`);let s={};try{let a=S__namespace.readFileSync(v(),"utf8");s=JSON.parse(a).env||{};}catch{}let o=Object.keys(X).filter(a=>!s[a]);if(o.length===0?(qt("All OTEL env vars present in settings.json"),P(`Endpoint: ${s.OTEL_EXPORTER_OTLP_ENDPOINT}`)):(we(`${o.length} OTEL var(s) missing from settings.json \u2014 native metrics/logs disabled`),o.forEach(a=>Se(`Missing: ${a}`)),P("Run: flow-ai-obs init (restores missing vars automatically)")),F(),process.stdout.write(` Tracing
|
|
179
|
+
`),process.env[d.FLOW_TELEMETRY]==="true"){qt("FLOW_TELEMETRY=true (direct mode enabled)");let a=[d.LANGFUSE_BASE_URL,d.LANGFUSE_PUBLIC_KEY,d.LANGFUSE_SECRET_KEY].filter(l=>!process.env[l]);a.length>0&&a.forEach(l=>we(`Missing: ${l}`));}else P("FLOW_TELEMETRY not set \u2014 direct mode inactive (gateway mode may still be active)");let c=await z();if(!c||c.length===0)return c&&c.authError?Se("Token refresh failed \u2014 gateway mode could not activate"):(Se("No active destinations \u2014 no traces will be sent"),P("For direct mode: set FLOW_TELEMETRY=true + LANGFUSE_BASE_URL + LANGFUSE_PUBLIC_KEY + LANGFUSE_SECRET_KEY"),P("For gateway mode: run flow-claude-observability auth login")),F(),1;for(let a of c)if(a.mode==="gateway"){let l=await It();qt("Mode: gateway"),P(`Endpoint: ${a.endpoint}`),P(`Token: ${or(l?.accessToken)}`);}else a.mode==="direct"&&(qt("Mode: direct"),P(`Endpoint: ${a.endpoint}`),P(`PK: ${or(process.env[d.LANGFUSE_PUBLIC_KEY])}`),P(`SK: ${or(process.env[d.LANGFUSE_SECRET_KEY])}`));return F(),process.stdout.write(` All checks passed \u2014 observability is active.
|
|
180
|
+
`),F(),0}var gn=f(()=>{"use strict";me();G();jt();_();Ht();Jt();});function J(t,e){let r=typeof t=="object"?JSON.stringify(t):String(t??"");return r.length>e?r.slice(0,e)+" \u2026[truncated]":r}function Ee(t,e=100){return String(t??"").split(`
|
|
181
|
+
`)[0].slice(0,e).trim()}function ir(){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 H(t){process.stdout.write(JSON.stringify(t));}var Pt=f(()=>{"use strict";});function et(){return String(BigInt(Date.now())*1000000n)}var ar,gt,zt=f(()=>{"use strict";ar=()=>crypto.randomBytes(16).toString("hex"),gt=()=>crypto.randomBytes(8).toString("hex");});function _o(t,e){let r=Rt.resolve(t);if(!r.startsWith(e))throw new Error(`Path traversal detected: ${t}`);return r}function cr(t){if(!To.test(t))throw new Error(`Invalid session ID: ${t}`);return _o(Rt.join(lt.tmpdir(),`flow-obs-${t}.json`),yo)}function Ct(t){let e=cr(t);if(!S.existsSync(e))return null;try{return JSON.parse(S.readFileSync(e,"utf8"))}catch{return null}}function Nt(t,e){S.writeFileSync(cr(t),JSON.stringify(e),{encoding:"utf8",mode:384});}function lr(t){try{S.unlinkSync(cr(t));}catch{}}var To,yo,Xt=f(()=>{"use strict";To=/^[0-9a-f-]{1,64}$/i,yo=Rt.normalize(lt.tmpdir())+Rt.sep;});function Tn(t){if(!t||!S.existsSync(t))return null;try{let e=S.readFileSync(t,"utf8").trimEnd().split(`
|
|
182
|
+
`);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 ur(t){if(!t||!S.existsSync(t))return null;try{let e=S.readFileSync(t,"utf8").trimEnd().split(`
|
|
183
|
+
`),r=[],n=0,s=0;for(let o=e.length-1;o>=0;o--)try{let i=JSON.parse(e[o]);if(i.type==="user")break;if(i.type==="assistant"){let a=(i.message?.content??[]).filter(h=>h.type==="text").map(h=>h.text??"").join("");a&&r.unshift(a);let l=i.message?.usage??{};n+=(l.input_tokens??0)+(l.cache_read_input_tokens??0)+(l.cache_creation_input_tokens??0),s+=l.output_tokens??0;}}catch{}return !r.length&&n===0?null:{text:r.join(`
|
|
184
|
+
|
|
185
|
+
`),inputTokens:n,outputTokens:s}}catch{}return null}var dr=f(()=>{"use strict";});function kn(t){return t.replace(":","/")}function Te(t,e){if(!t)return null;let r=kn(t),n=[Rt.join(lt.homedir(),".claude","skills",r,"SKILL.md"),Rt.join(e??"",".claude","skills",r,"SKILL.md")];for(let s of n)if(S.existsSync(s))try{return S.readFileSync(s,"utf8")}catch{}return null}function On(t){return t.split(`
|
|
186
|
+
`)[0].match(/^\/([a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?)(?:\s.*)?$/i)?.[1]??null}function An(t){return !!t.slashSkill||t.toolCalls.some(n=>n.tool==="Skill")?t.toolCalls.some(n=>n.tool==="Skill"&&!n.synthetic||Io.has(n.tool))?"complete":"prerequisite_required":null}function ye(t,e){if(!t)return null;let r=kn(t),n=[Rt.join(lt.homedir(),".claude","skills",r),Rt.join(e??"",".claude","skills",r)],s=null;for(let c of n)if(S.existsSync(Rt.join(c,"SKILL.md"))){s=c;break}if(!s)return null;let o=[];function i(c,a){for(let l of S.readdirSync(c,{withFileTypes:true})){if(vo.has(l.name)||Ro.has(l.name)||Lo.has(Rt.extname(l.name)))continue;let h=a?`${a}/${l.name}`:l.name;l.isDirectory()?i(Rt.join(c,l.name),h):o.push(h);}}return i(s,""),o.length>0?o:null}var vo,Lo,Ro,Io,_e=f(()=>{"use strict";vo=new Set([".venv","__pycache__",".git","node_modules"]),Lo=new Set([".pyc",".pyo"]),Ro=new Set(["SKILL.md",".DS_Store",".gitignore"]);Io=new Set(["Read","Write","Edit","MultiEdit","Bash","Glob","Grep","TodoWrite","WebFetch","WebSearch","Agent","Task"]);});function Co(t){try{let e=t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(Buffer.from(e,"base64").toString())}catch{return null}}function No(t,e,r,n){return new Promise(s=>{let o=new URL(t),i=o.protocol==="https:",c=(i?us__default.default:vs__default.default).request({hostname:o.hostname,port:o.port||(i?443:80),path:o.pathname+o.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(e),Authorization:`Bearer ${String(r).replace(/[\r\n]/g,"")}`,FlowTenant:String(n).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 ht(t,e={}){try{let r=$(process.env[d.ANTHROPIC_AUTH_TOKEN]);if(!r)return;let n,s=new Promise((g,m)=>{n=setTimeout(()=>m(new Error("getToken timeout")),4e3),n.unref();}),{accessToken:o}=await Promise.race([Y(r),s]);clearTimeout(n);let i=Co(o);if(!i)return;let c=i.tenant||r.tenant,a=JSON.stringify({action:t,booster:Be().BOOSTER,metadata:e,success:!0,tenant:c,timestamp:new Date().toISOString(),os:process.platform,user:{email:i.email||"",id:i.sub||"",name:i.name||i.email||""}}),l=ut(Be().API_URL),h=await No(l,a,o,c);u("metrics.logEvent",`action=${t} status=${h}`);}catch(r){u("metrics.logEvent",`silenced error: ${r.message}`);}}var ke=f(()=>{"use strict";_();At();G();M();});async function pr(t,e=false){if(e){process.stdout.write(JSON.stringify({decision:"block",reason:Uo})+`
|
|
187
|
+
`);return}let n=!!(await z()).authError,s=t.session_id||"unknown",o=t.prompt||"",i=t.cwd||"",c=Tn(t.transcript_path)||ar(),a=On(o),l=a?Te(a,i):null,h=a?ye(a,i):null;Nt(s,{traceId:ar(),spanId:gt(),startNs:et(),sessionId:s,prompt:o,cwd:i,traceName:c,transcriptPath:t.transcript_path||"",model:process.env[d.ANTHROPIC_MODEL]||"",toolCalls:[],spans:[],pendingTool:null,slashSkill:a,skillContent:l,skillArtifacts:h}),ht("SESSION_STARTED",{traceType:a?"skill":"prompt",slashSkill:a,clientIdExpired:n}),u("UserPromptSubmit",`sid=${s}`,`traceName=${c}`,`slashSkill=${a}`),H(t);}var Uo,vn=f(()=>{"use strict";zt();Xt();dr();_e();Pt();M();_();G();ke();Uo=`\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 ${U()}/settings/api-keys to generate a new API key, then run: flow-ai-obs auth login`;});async function Ln(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=Ct(e);s&&(s.pendingTool={name:r,inputStr:J(n,V.TOOL_INPUT),startNs:et()},Nt(e,s)),u("PreToolUse",`sid=${e}`,`tool=${r}`,`stateFound=${!!s}`),H(t);}var Rn=f(()=>{"use strict";zt();Xt();Pt();M();_();});function p(t,e){return e==null||e===""?null:{key:t,value:{stringValue:String(e)}}}function wt(...t){return t.filter(e=>e!==null)}function In(t,e){return {resourceSpans:[{resource:{attributes:t},scopeSpans:[{scope:$o,spans:Array.isArray(e)?e:[e]}]}]}}var $o,y,bn=f(()=>{"use strict";_();$o={name:xe.SCOPE_NAME,version:xe.SCOPE_VERSION},y={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 Cn(t,e,r,n,s){if(process.env[d.FLOW_OBS_DEBUG]!=="1")return;let o=JSON.stringify({ts:new Date().toISOString(),request:{method:"POST",url:t,headers:e,body:JSON.parse(r)},response:{status:n,body:s}});try{S.writeFileSync(Pn,o+`
|
|
188
|
+
`,{flag:"a",encoding:"utf8",mode:384}),u("sendTraces:dump",`request appendada em ${Pn}`);}catch(i){u("sendTraces:dump",`falha ao salvar: ${i.message}`);}}function Ho(t){let e=new URL(t),r=new URL(Ot().GATEWAY_HEALTH);return r.hostname=e.hostname,r.port=e.port,r.protocol=e.protocol,r}function Nn(t,e){return new Promise((r,n)=>{let s=t._isSSL?us__default.default:vs__default.default;t.headers=Object.assign({},t.headers,{Connection:"close"});let o=s.request(t,i=>{let c=[];i.on("data",a=>c.push(a)),i.on("end",()=>r({statusCode:i.statusCode??0,body:c.join("")}));});o.setTimeout(1e4,()=>{o.destroy(new Error("Request timeout"));}),o.on("error",i=>n(new Error(`Network error: ${i.message}`))),e&&o.write(e),o.end();})}async function Un(t,e){let r;try{r=Ho(t);}catch{return false}let n=r.protocol==="https:";try{let s={};e&&(s.Authorization=String(e).replace(/[\r\n]/g,""));let o=await Nn({hostname:r.hostname,port:r.port||(n?443:80),path:r.pathname,method:"GET",headers:s,_isSSL:n},null);return u("checkHealth",`url=${r.href} status=${o.statusCode}`),o.statusCode>=200&&o.statusCode<300}catch{return false}}async function Oe(t,e,r){let n=JSON.stringify(t),s=new URL(e),o=s.protocol==="https:",i=String(r).replace(/[\r\n]/g,""),c={"Content-Type":"application/json",Authorization:i,"Content-Length":Buffer.byteLength(n)};u("sendTraces:request",`POST ${e}`),u("sendTraces:request",`headers=${JSON.stringify({...c,Authorization:i.slice(0,20)+"\u2026"})}`),u("sendTraces:request",`body=${n.slice(0,500)}${n.length>500?"\u2026":""}`);try{let a=await Nn({hostname:s.hostname,port:s.port||(o?443:80),path:s.pathname,method:"POST",headers:c,_isSSL:o},n);return u("sendTraces:response",`status=${a.statusCode}`),Cn(e,c,n,a.statusCode,a.body),a.statusCode}catch(a){return u("sendTraces:error",a.message),Cn(e,c,n,0,a.message),0}}var Pn,$n=f(()=>{"use strict";_();M();Pn=Rt.join(lt.tmpdir(),"flow-obs-requests.ndjson");});function jo(){let t=parseInt(process.env[d.BUFFER_TTL_DAYS]??"",10);return (Number.isFinite(t)?Math.max(B.MIN_TTL_DAYS,Math.min(B.MAX_TTL_DAYS,t)):B.DEFAULT_TTL_DAYS)*24*60*60*1e3}function Wo(){let t=parseInt(process.env[d.BUFFER_MAX_FILES]??"",10);return Number.isFinite(t)?Math.max(B.MIN_MAX_FILES,Math.min(B.MAX_MAX_FILES,t)):B.DEFAULT_MAX_FILES}function xn(t){if(/[/\\]/.test(t))throw new Error(`Invalid buffer fileId: ${t}`);return Rt__namespace.default.join(lt__namespace.default.tmpdir(),`${B.FILE_PREFIX}${t}.json`)}function mr(){let t=lt__namespace.default.tmpdir(),e;try{e=S__namespace.default.readdirSync(t);}catch{return []}return e.filter(r=>r.startsWith(B.FILE_PREFIX)&&r.endsWith(".json")).map(r=>{let n=Rt__namespace.default.join(t,r),s=0;try{s=S__namespace.default.statSync(n).mtimeMs;}catch{}return {full:n,mtime:s}}).sort((r,n)=>r.mtime-n.mtime).map(r=>r.full)}function Zt(t){try{let e=Wo(),r=mr();if(r.length>=e){let o=r.slice(0,r.length-e+1);for(let i of o)try{S__namespace.default.unlinkSync(i);}catch{}}let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s={fileId:n,bufferedAt:Date.now(),payload:t};return S__namespace.default.writeFileSync(xn(n),JSON.stringify(s),{encoding:"utf8",mode:384}),u("buffer",`saved fileId=${n}`),n}catch(e){return u("buffer",`saveToBuffer failed: ${e.message}`),null}}function Dn(t){let e=mr(),r=t!=null&&t>0?t:e.length,n=[];for(let s of e){if(n.length>=r)break;try{let o=S__namespace.default.readFileSync(s,"utf8"),i=JSON.parse(o);i&&i.fileId&&i.payload&&n.push(i);}catch{u("buffer",`skipping malformed file: ${s}`);}}return n}function Bn(t){try{S__namespace.default.unlinkSync(xn(t)),u("buffer",`deleted fileId=${t}`);}catch{}}function Mn(){let t=Date.now()-jo();for(let e of mr())try{let{mtimeMs:r}=S__namespace.default.statSync(e);r<t&&(S__namespace.default.unlinkSync(e),u("buffer",`evicted stale: ${Rt__namespace.default.basename(e)}`));}catch{}}var Hn=f(()=>{"use strict";_();M();});async function Vo(t){Mn();let e=Dn(B.REPLAY_BATCH_SIZE);e.length&&(u("replayBufferedTraces",`replaying ${e.length} buffered trace(s)`),await Promise.allSettled(e.map(async r=>{try{let n=await Oe(r.payload,t.endpoint,t.authHeader);n>=200&&n<300?(Bn(r.fileId),u("replayBufferedTraces",`replayed fileId=${r.fileId} status=${n}`)):u("replayBufferedTraces",`replay failed fileId=${r.fileId} status=${n}`);}catch(n){u("replayBufferedTraces",`replay error fileId=${r.fileId}: ${n.message}`);}})));}async function jn(t){let e=await z();if(!e.length)return e.authError&&(u("postToLangfuse","auth refresh failed \u2014 buffering trace"),Zt(t)),0;let r=await Promise.all(e.map(async o=>{if(o.mode!=="gateway")return {creds:o,healthy:true};let i=await Un(o.endpoint,o.authHeader);return {creds:o,healthy:i}})),n=r.find(o=>o.creds.mode==="gateway"&&o.healthy)?.creds??r.find(o=>o.creds.mode==="direct")?.creds;return n&&await Vo(n),(await Promise.all(r.map(async({creds:o,healthy:i})=>{if(o.mode==="gateway"){if(!i)return u("postToLangfuse","gateway health check failed \u2014 buffering trace"),Zt(t),0;let a=await Oe(t,o.endpoint,o.authHeader);return (a===0||a>=500)&&(u("postToLangfuse",`gateway send failed (status ${a}) \u2014 buffering trace`),Zt(t)),a}let c=await Oe(t,o.endpoint,o.authHeader);return (c===0||c>=500)&&(u("postToLangfuse",`direct endpoint unavailable (status ${c}) \u2014 buffering trace`),Zt(t)),c}))).find(o=>o!==0)??0}var Wn=f(()=>{"use strict";G();M();$n();Hn();_();});var gr=f(()=>{"use strict";bn();Wn();});function nt(t){if(t==null)return "";let e=typeof t=="string"?t:JSON.stringify(t);return Ko.reduce((r,{re:n,replace:s})=>r.replace(n,s),e)}var x,Yo,Go,Jo,Vn,Ko,hr=f(()=>{"use strict";x="[REDACTED]",Yo="[REDACTED-EMAIL]",Go="[REDACTED-CPF]",Jo="[REDACTED-CNPJ]",Vn="[REDACTED-PHONE]",Ko=[{re:/\b(sk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`sk-${x}`},{re:/\b(pk-[A-Za-z0-9_\-]{20,})/g,replace:()=>`pk-${x}`},{re:/\b(Bearer\s+)[A-Za-z0-9\-._~+/]+=*/gi,replace:(t,e)=>`${e}${x}`},{re:/\b(Basic\s+)[A-Za-z0-9+/]+=*/gi,replace:(t,e)=>`${e}${x}`},{re:/(-----BEGIN [A-Z ]+-----)[^-]*(-----END [A-Z ]+-----)/g,replace:(t,e,r)=>`${e}
|
|
189
|
+
${x}
|
|
190
|
+
${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${x}`},{re:/(aws_secret_access_key\s*[=:]\s*)([A-Za-z0-9/+]{40})/gi,replace:(t,e)=>`${e}${x}`},{re:/\b(ghp_[A-Za-z0-9]{36,})/g,replace:()=>`ghp_${x}`},{re:/\b(github_pat_[A-Za-z0-9_]{36,})/gi,replace:()=>`github_pat_${x}`},{re:/\b(eyJ[A-Za-z0-9_\-]+\.eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)/g,replace:()=>`eyJ.${x}`},{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}${x}${r}`},{re:/([a-z][a-z0-9+\-.]*:\/\/[^:/?#\s]*):([^@\s]+)@/gi,replace:(t,e)=>`${e}:${x}@`},{re:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replace:()=>Yo},{re:/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,replace:()=>Go},{re:/\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/g,replace:()=>Jo},{re:/\(\d{2}\)\s?\d{4,5}[-\s]?\d{4}/g,replace:()=>Vn},{re:/\+55[\s-]?\d{2}[\s-]?\d{4,5}[-\s]?\d{4}/g,replace:()=>Vn}];});async function Yn(t){let e=t.session_id||"unknown",r=t.tool_name||"unknown",n=t.tool_input||{},s=t.tool_response,o=s!==null&&typeof s=="object"?s.output??JSON.stringify(s):s??"",i=Ct(e);if(!i){H(t);return}let c=et(),a=i.pendingTool,l=a?.name===r,h=l?a.startNs:String(BigInt(c)-200000000n),g=l?a.inputStr:J(n,V.TOOL_INPUT),m=g,E=null;if(r==="Skill"){let se=typeof n=="object"&&n!==null?n.skill||n.name||n.skillName||n.commandName||String(Object.values(n)[0]??""):String(n);E=se?String(se).trim():null;let ot=E?Te(E,i.cwd):null;ot&&(m=ot,i.skillContent||(i.skillContent=ot),i.skillArtifacts||(i.skillArtifacts=ye(E,i.cwd))),E&&!i.slashSkill&&(i.slashSkill=E),u("PostToolUse","Skill tool detected",`skillName=${E}`,`contentFound=${!!ot}`);}let k=nt(J(o,V.TOOL_OUTPUT)),O=/\b(error|exception|failed|failure|traceback|errno)\b/i.test(k.slice(0,500)),Qt=O?"ERROR":"DEFAULT",$t=gt(),te=Math.round(Number(BigInt(c)-BigInt(h))/1e6),re={Agent:"AGENT",Task:"AGENT"}[r]??"TOOL",ne=r==="Skill"&&E?E:Ee(g,60);i.toolCalls.push({tool:r,brief:ne,error:O,durationMs:te});let Ft=i.spans;Ft.push({traceId:i.traceId,spanId:$t,parentSpanId:i.spanId,name:r,kind:3,startTimeUnixNano:h,endTimeUnixNano:c,attributes:wt(p(y.OBS_NAME,r),p(y.OBS_TYPE,re),p(y.OBS_LEVEL,Qt),p(y.OBS_INPUT,nt(m)),p(y.OBS_OUTPUT,k),p("tool.name",r),p("tool.error",String(O)),r==="Skill"&&E?p("skill.name",E):null,r==="Skill"?p("skill.invocation","slash-command"):null),status:{code:O?2:1}}),i.pendingTool=null,Nt(e,i),O&&ht("TOOL_ERROR",{toolName:r}),u("PostToolUse",`sid=${e}`,`tool=${r}`,`error=${O}`,`durationMs=${te}`,`totalSpans=${Ft.length}`),H(t);}var Gn=f(()=>{"use strict";zt();Xt();gr();Pt();_e();M();_();hr();ke();});function Kn(t,e,r){let n=Object.keys(Jn).find(i=>(t??"").toLowerCase().includes(i));if(!n)return;let s=Jn[n],o=(e*s.input+r*s.output)/1e6;return Math.round(o*1e6)/1e6}var Jn,qn=f(()=>{"use strict";Jn={"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 zn(t){let e=t.session_id||"unknown",r=t.stop_reason||"end_turn",n=Ct(e);if(!n){H(t);return}n.slashSkill&&!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/i.test(n.slashSkill)&&(u("Stop",`sid=${e}`,`slashSkill rejected post-disk: "${n.slashSkill}"`),n.slashSkill=null);let s=et(),o=await zr(),i=n.toolCalls,c=n.spans;if(n.slashSkill&&!i.some(T=>T.tool==="Skill")){let T=gt(),it=n.skillContent?n.skillContent:JSON.stringify({skill:n.slashSkill});i.push({tool:"Skill",brief:n.slashSkill,error:false,durationMs:0,synthetic:true}),c.push({traceId:n.traceId,spanId:T,parentSpanId:n.spanId,name:"Skill",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:n.startNs,attributes:wt(p(y.OBS_NAME,"Skill"),p(y.OBS_TYPE,"TOOL"),p(y.OBS_LEVEL,"DEFAULT"),p(y.OBS_INPUT,it),p(y.OBS_OUTPUT,"loaded via slash command"),p("tool.name","Skill"),p("tool.error","false"),p("skill.name",n.slashSkill),p("skill.invocation","slash-command")),status:{code:1}}),u("Stop",`slashSkill=${n.slashSkill}`,"synthetic span injected");}let a=t.transcript_path||n.transcriptPath||"",l=ur(a);if(a&&(i.some(T=>T.tool==="Skill"&&!T.synthetic)||!!n.slashSkill)&&!l?.text){await new Promise(it=>setTimeout(it,500));let T=ur(a);T?.text&&(l=T);}u("Stop",`transcriptPath=${a||"(empty)"}`,`assistantOut=${l?`text=${l.text.length}chars`:"null"}`);let g=i.length,m=i.filter(T=>T.error).length,E=nt(l?.text?J(l.text,V.TRACE_OUTPUT):g===0?"No tools used":i.map((T,it)=>`${it+1}. ${T.tool}${T.brief?` \u2192 ${T.brief}`:""}${T.error?" [ERROR]":""}`).join(`
|
|
191
|
+
`)),k=l?.inputTokens??0,O=l?.outputTokens??0,Qt=i.map((T,it)=>`${it+1}. ${T.tool}${T.brief?` \u2192 ${T.brief}`:""}${T.error?" [ERROR]":""} (${T.durationMs}ms)`),$t=!!(n.slashSkill||i.some(T=>T.tool==="Skill")),te=i.some(T=>T.tool==="Agent");if(!$t&&!te){u("Stop",`sid=${e}`,"skipping trace \u2014 no Skill or Agent calls found"),ht("TRACE_SKIPPED",{reason:"no_skill_or_agent"}),lr(e),H(t);return}let ee=$t?"skill":"agent",re=Math.round(Number(BigInt(s)-BigInt(n.startNs))/1e6),ne=Kn(n.model,k,O),St=An(n);St==="prerequisite_required"&&l?.text&&(St="complete"),St==="prerequisite_required"&&(c.push({traceId:n.traceId,spanId:gt(),parentSpanId:n.spanId,name:"prerequisite-check",kind:3,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:wt(p(y.OBS_NAME,"prerequisite-check"),p(y.OBS_TYPE,"EVENT"),p(y.OBS_LEVEL,"WARNING"),p(y.OBS_OUTPUT,E),p("skill.name",n.slashSkill||void 0),p("execution_status","prerequisite_required")),status:{code:1}}),u("Stop",`sid=${e}`,"prerequisite-check span injected",`skill=${n.slashSkill}`));let Ft=(()=>{if(!(!$t||!n.prompt)){if(n.slashSkill){let T=n.prompt.replace(new RegExp(`^\\/${n.slashSkill}\\s*`,"i"),"").trim();return T?J(nt(T),V.USER_INSTRUCTION):void 0}return J(nt(n.prompt),V.USER_INSTRUCTION)||void 0}})(),se=JSON.stringify({trace_type:ee,...St!==null&&{execution_status:St},...n.slashSkill?{skill_name:n.slashSkill}:{},...n.skillArtifacts?.length&&{skill_artifacts:n.skillArtifacts},...Ft!==void 0&&{user_instruction:Ft},latency_ms:re,...k&&{tokens_input:k},...O&&{tokens_output:O},cost_usd:ne,...n.model?{model:n.model}:{},toolCount:g,errorCount:m,stopReason:r,sessionId:n.sessionId,tools:Qt.length?Qt:void 0}),ot=nt(J(n.prompt,V.TRACE_INPUT)),Qn=wt(p(y.TRACE_NAME,n.traceName),p(y.TRACE_INPUT,ot),p(y.TRACE_OUTPUT,E),p(y.OBS_INPUT,ot),p(y.OBS_OUTPUT,E),p(y.TRACE_METADATA,se),p(y.SESSION_ID,n.sessionId),p(y.USER_ID,o.user),p(y.OBS_TYPE,"GENERATION"),p(y.MODEL,n.model),k?p(y.INPUT_TOKENS,k):null,O?p(y.OUTPUT_TOKENS,O):null,p("claude.stop_reason",r),p("claude.tool_count",String(g)),p("claude.error_count",String(m)),p("claude.session_id",n.sessionId),p("flow.trace_type",ee),{key:y.TRACE_TAGS,value:{arrayValue:{values:[{stringValue:ee}]}}}),ts={traceId:n.traceId,spanId:n.spanId,name:n.traceName,kind:1,startTimeUnixNano:n.startNs,endTimeUnixNano:s,attributes:Qn,status:{code:m>0?2:1}},es=wt(p("service.name",process.env.LANGFUSE_PROJECT_NAME||"claude-code"),p("deployment.environment",process.env.LANGFUSE_ENVIRONMENT||"default")),wr=[...c,ts];u("Stop",`sid=${e}`,`totalTools=${g}`,`errorTools=${m}`,`spans=${wr.length}`,`inputTokens=${k}`,`outputTokens=${O}`,`traceOutput="${Ee(E,80)}"`);let rs=await jn(In(es,wr));u("Stop",`POST status=${rs}`,`traceId=${n.traceId}`),ht("TRACE_SENT",{latencyMs:re,totalTools:g,errorTools:m,inputTokens:k,outputTokens:O,costUsd:ne}),lr(e),H(t);}var Xn=f(()=>{"use strict";zt();Xt();gr();G();qn();dr();Pt();M();_e();hr();_();ke();});async function qo(){let t=process.argv[2];if(t==="UserPromptSubmit"){let r=await ir(),n;try{n=await z();}catch{process.stdout.write(JSON.stringify(r));return}n.authError?await pr(r,true):n.length>0?await pr(r):process.stdout.write(JSON.stringify(r));return}if(!await Xr()){let r=[];process.stdin.on("data",n=>r.push(n)),process.stdin.on("end",()=>process.stdout.write(r.join("")));return}let e=await ir();switch(t){case "PreToolUse":await Ln(e);break;case "PostToolUse":await Yn(e);break;case "Stop":await zn(e);break;default:process.stderr.write(`[flow-obs] unknown event: ${t}
|
|
192
|
+
`),process.stdout.write(JSON.stringify(e));}}var Zn=f(()=>{"use strict";G();Pt();vn();Rn();Gn();Xn();qo().catch(t=>{process.stderr.write(`[flow-obs] fatal: ${t.message}
|
|
193
|
+
`),process.exit(0);});});var Xo=new Set(["UserPromptSubmit","PreToolUse","PostToolUse","Stop"]),[,,D,Ae]=process.argv;function st(t,e){let r=t.indexOf(e);return r!==-1?t[r+1]:void 0}if(D==="--version"||D==="-v"){let{version:t}=oe();process.stdout.write(t+`
|
|
194
|
+
`),process.exit(0);}else if(D==="--help"||D==="-h"){let{bold:t,cyan:e,dim:r}=(at(),R(Le)),{version:n}=oe();process.stdout.write(`
|
|
196
195
|
`+t(" flow-ai-obs")+r(" v"+n)+`
|
|
197
196
|
|
|
198
197
|
`),process.stdout.write(e(" init")+r(` Auth (if needed) + hooks + native OTEL
|
|
@@ -200,7 +199,6 @@ ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${$}`},{re:/(aws_secret_ac
|
|
|
200
199
|
`)),process.stdout.write(r(` --no-interactive Suppress interactive prompts (for CI/CD)
|
|
201
200
|
`)),process.stdout.write(e(" setup")+r(` Full Flow wizard: auth + hooks + OTEL + LLM proxy + connectivity
|
|
202
201
|
`)),process.stdout.write(e(" auth login")+r(` Authenticate with Flow (clientId / clientSecret / tenant)
|
|
203
|
-
`)),process.stdout.write(e(" auth logout")+r(` Remove credentials
|
|
204
202
|
`)),process.stdout.write(e(" auth status")+r(` Show current auth status
|
|
205
203
|
`)),process.stdout.write(e(" check")+r(` Validate full observability setup
|
|
206
204
|
|
|
@@ -212,13 +210,13 @@ ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${$}`},{re:/(aws_secret_ac
|
|
|
212
210
|
|
|
213
211
|
`)),process.stdout.write(r(` (Hook events: UserPromptSubmit | PreToolUse | PostToolUse | Stop)
|
|
214
212
|
|
|
215
|
-
`)),process.exit(0);}else if(
|
|
216
|
-
`),await(kt(),
|
|
217
|
-
`),process.exit(1);});else if(
|
|
218
|
-
`),process.exit(1);});else if(
|
|
219
|
-
`),process.stderr.write(`Usage: flow-ai-obs auth [login|
|
|
220
|
-
`),
|
|
221
|
-
`),process.exit(1);});else if(
|
|
213
|
+
`)),process.exit(0);}else if(D==="init"||D==="install")(async()=>{D==="install"&&process.stderr.write(`Warning: "install" is deprecated, use "init" instead
|
|
214
|
+
`),await(kt(),R(_t)).checkForUpdateInteractive();let{runInit:t}=(sr(),R(nr)),e=process.argv.slice(3);process.exit(await t({url:st(e,"--custom-url"),noInteractive:e.includes("--no-interactive")}));})().catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
|
|
215
|
+
`),process.exit(1);});else if(D==="setup")(async()=>{await(kt(),R(_t)).checkForUpdateInteractive();let{runSetup:t}=(un(),R(ln)),e=process.argv.slice(3);process.exit(await t({clientId:st(e,"--client-id"),clientSecret:st(e,"--client-secret"),tenant:st(e,"--tenant"),nonInteractive:e.includes("--non-interactive"),url:st(e,"--custom-url")}));})().catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
|
|
216
|
+
`),process.exit(1);});else if(D==="auth")(async()=>{let{runLogin:t,runStatus:e}=(Jt(),R(tr)),r=0;if(Ae==="login"||!Ae){await(kt(),R(_t)).checkForUpdateInteractive();let n=process.argv.slice(4);r=await t({clientId:st(n,"--client-id"),clientSecret:st(n,"--client-secret"),tenant:st(n,"--tenant")});}else Ae==="status"?(await(kt(),R(_t)).checkForUpdateInteractive(),r=await e()):(process.stderr.write(`Unknown auth subcommand: ${Ae}
|
|
217
|
+
`),process.stderr.write(`Usage: flow-ai-obs auth [login|status]
|
|
218
|
+
`),r=1);process.exit(r);})();else if(D==="otel-headers"){let{runOtelHeaders:t}=(pn(),R(dn));t().then(e=>process.exit(e)).catch(()=>process.exit(1));}else if(D==="check")(async()=>{await(kt(),R(_t)).checkForUpdateInteractive();let{runCheck:t}=(gn(),R(mn));process.exit(await t());})().catch(t=>{process.stderr.write(`Unexpected error: ${t.message}
|
|
219
|
+
`),process.exit(1);});else if(Xo.has(D))Zn();else {let{bold:t,cyan:e,dim:r}=(at(),R(Le));process.stdout.write(`
|
|
222
220
|
`+t(" flow-ai-obs")+`
|
|
223
221
|
|
|
224
222
|
`),process.stdout.write(e(" init")+r(` Auth (if needed) + hooks + native OTEL
|
|
@@ -226,7 +224,6 @@ ${r}`},{re:/\b(AKIA[0-9A-Z]{16})\b/g,replace:()=>`AKIA${$}`},{re:/(aws_secret_ac
|
|
|
226
224
|
`)),process.stdout.write(r(` --no-interactive Suppress interactive prompts (for CI/CD)
|
|
227
225
|
`)),process.stdout.write(e(" setup")+r(` Full Flow wizard: auth + hooks + OTEL + LLM proxy + connectivity
|
|
228
226
|
`)),process.stdout.write(e(" auth login")+r(` Authenticate with Flow (clientId / clientSecret / tenant)
|
|
229
|
-
`)),process.stdout.write(e(" auth logout")+r(` Remove credentials
|
|
230
227
|
`)),process.stdout.write(e(" auth status")+r(` Show current auth status
|
|
231
228
|
`)),process.stdout.write(e(" check")+r(` Validate full observability setup
|
|
232
229
|
|
package/dist/setup.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var child_process=require('child_process'),util=require('util'),i=require('fs'),u=require('path'),l=require('os'),Ke=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 u__namespace=/*#__PURE__*/_interopNamespace(u);var l__namespace=/*#__PURE__*/_interopNamespace(l);var Ke__default=/*#__PURE__*/_interopDefault(Ke);var Te=Object.defineProperty;var T=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var A=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var _e=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(n){throw t=0,n}},L=(e,t)=>{for(var n in t)Te(e,n,{get:t[n],enumerable:true});};var J={};L(J,{MacOsKeyVaultProvider:()=>N});var C,N,K=A(()=>{"use strict";C=util.promisify(child_process.execFile),N=class{static async isAvailable(){try{return i.accessSync("/usr/bin/security",i.constants.X_OK),!0}catch{return !1}}async getSecret(t,n){try{let{stdout:r}=await C("security",["find-generic-password","-w","-a",n,"-s",t]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await C("security",["add-generic-password","-U","-a",n,"-s",t,"-w",r]);}async deleteSecret(t,n){try{return await C("security",["delete-generic-password","-a",n,"-s",t]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var q={};L(q,{LinuxKeyVaultProvider:()=>b});var X,b,z=A(()=>{"use strict";X=util.promisify(child_process.execFile),b=class{static async isAvailable(){let t=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let n of t)try{return i.accessSync(n,i.constants.X_OK),!0}catch{}return !1}async getSecret(t,n){try{let{stdout:r}=await X("secret-tool",["lookup","service",t,"account",n]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await new Promise((s,o)=>{let a=child_process.spawn("secret-tool",["store","--label",t,"service",t,"account",n]);a.on("error",o),a.on("close",y=>{y===0?s():o(new Error(`secret-tool exited with code ${y}`));}),a.stdin.write(r),a.stdin.end();});}async deleteSecret(t,n){try{return await X("secret-tool",["clear","service",t,"account",n]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var Z={};L(Z,{WindowsKeyVaultProvider:()=>U});var U,Q=A(()=>{"use strict";U=class{static async isAvailable(){try{return await T("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(t,n){return T("keytar").getPassword(t,n)}async setSecret(t,n,r){await T("keytar").setPassword(t,n,r);}async deleteSecret(t,n){return T("keytar").deletePassword(t,n)}getStoragePath(){return "Windows Credential Manager"}};});var fe=_e((an,Je)=>{Je.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.8.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"}};});var Se="https://flow.ciandt.com";function R(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Se}function k(){let e=R();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${e}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${e}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${e}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${e}/otel`}}var we=k(),_={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials"},S="FLOW-nodejs",w="config.json";function V(){let e=R();return {ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${e}/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-sonnet",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"}}var j={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:we.OTEL_ENDPOINT,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={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 Y={LOCK_STALE_MS:3e4},G={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15};var W="flow-ai-obs-debug.log";var P={credentials:"credentials","token-cache":"tokenCache"};function m(){let e=l__namespace.default.homedir();if(process.platform==="darwin")return u__namespace.default.join(e,"Library","Preferences",S,w);if(process.platform==="win32"){let n=process.env.APPDATA??u__namespace.default.join(e,"AppData","Roaming");return u__namespace.default.join(n,S,w)}let t=process.env.XDG_CONFIG_HOME??u__namespace.default.join(e,".config");return u__namespace.default.join(t,S,w)}function I(){try{let e=i__namespace.default.readFileSync(m(),"utf8");return JSON.parse(e)}catch{return {}}}function B(e){let t=m();i__namespace.default.mkdirSync(u__namespace.default.dirname(t),{recursive:true}),i__namespace.default.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var v=class{static isAvailable(){return true}static hasExistingData(){try{if(!i__namespace.default.existsSync(m()))return !1;let t=JSON.parse(i__namespace.default.readFileSync(m(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,n){let r=I(),s=P[n]??n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,n,r){let s=I(),o=P[n]??n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;B(s);}async deleteSecret(t,n){let r=I(),s=P[n]??n;return s in r?(delete r[s],B(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${m()}`}};async function ee(){return await be()??new v}async function be(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=await Promise.resolve().then(()=>(K(),J));return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=await Promise.resolve().then(()=>(z(),q));return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=await Promise.resolve().then(()=>(Q(),Z));return await e.isAvailable()?new e:null}default:return null}}var Ue=_.SERVICE,Fe=_.ACCOUNT_CREDS,F=null;function $e(){return F||(F=ee()),F}async function te(){let t=await(await $e()).getSecret(Ue,Fe);if(!t)return null;try{return JSON.parse(t)}catch{return null}}u.join(l.tmpdir(),W);!process.env.NO_COLOR&&process.stdout.isTTY;function $(){return process.platform==="win32"?false:process.getuid?.()===0}function ne(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let t=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(t)return {home:t,username:process.env.SUDO_USER}}return {home:l__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||l__namespace.userInfo().username}}function O(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(e=n);}if(e){let t=e.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return u__namespace.join(t,".claude","settings.json")}return u__namespace.join(l__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||l__namespace.homedir();return u__namespace.join(e,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let t=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(t)return u__namespace.join(t,".claude","settings.json")}return u__namespace.join(l__namespace.homedir(),".claude","settings.json")}var re="flow-ai-obs",se="config.json";function ie(){if(process.platform==="win32"){let n=process.env.APPDATA||u__namespace.join(l__namespace.homedir(),"AppData","Roaming");return u__namespace.join(n,re,se)}let e=ne(),t=process.env.XDG_CONFIG_HOME||u__namespace.join(e.home,".config");return u__namespace.join(t,re,se)}var Ge=Y.LOCK_STALE_MS;function ae(e){try{let t=i__namespace.statSync(e);Date.now()-t.mtimeMs>Ge&&i__namespace.unlinkSync(e);}catch{}try{i__namespace.writeFileSync(e,String(process.pid),{flag:"wx"});}catch(t){throw t.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+e):t}}function ce(e){try{i__namespace.unlinkSync(e);}catch{}}function We(e,t){let r=(Array.isArray(e)?e:[]).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 [t,...r]}function le(){let e=O(),t=e+".lock",n=[];i__namespace.mkdirSync(u__namespace.dirname(e),{recursive:true}),ae(t);try{if(i__namespace.existsSync(e)){i__namespace.copyFileSync(e,e+".bkp");try{i__namespace.chmodSync(e+".bkp",384);}catch{}}let r=ie();if(i__namespace.existsSync(r)){let c=r+".bkp";i__namespace.copyFileSync(r,c);try{i__namespace.chmodSync(c,384);}catch{}}let s={};try{s=JSON.parse(i__namespace.readFileSync(e,"utf8"));}catch{}let o=s.env&&typeof s.env=="object"?s.env:{};delete o.OTEL_EXPORTER_OTLP_HEADERS,s.env={...o,...j,...V()},s.otelHeadersHelper="flow-ai-obs otel-headers",(!s.hooks||typeof s.hooks!="object"||Array.isArray(s.hooks))&&(s.hooks={});let a=(c,E)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${c}`,timeout:E}]}),y=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],M=s.hooks;for(let c of y){let E=We(M[c],a(c,G[c]));E.length>1&&n.push(c),M[c]=E;}i__namespace.writeFileSync(e,JSON.stringify(s,null,2)+`
|
|
2
|
+
'use strict';var child_process=require('child_process'),util=require('util'),i=require('fs'),u=require('path'),l=require('os'),Ke=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 u__namespace=/*#__PURE__*/_interopNamespace(u);var l__namespace=/*#__PURE__*/_interopNamespace(l);var Ke__default=/*#__PURE__*/_interopDefault(Ke);var Te=Object.defineProperty;var T=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var A=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var _e=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(n){throw t=0,n}},L=(e,t)=>{for(var n in t)Te(e,n,{get:t[n],enumerable:true});};var J={};L(J,{MacOsKeyVaultProvider:()=>N});var C,N,K=A(()=>{"use strict";C=util.promisify(child_process.execFile),N=class{static async isAvailable(){try{return i.accessSync("/usr/bin/security",i.constants.X_OK),!0}catch{return !1}}async getSecret(t,n){try{let{stdout:r}=await C("security",["find-generic-password","-w","-a",n,"-s",t]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await C("security",["add-generic-password","-U","-a",n,"-s",t,"-w",r]);}async deleteSecret(t,n){try{return await C("security",["delete-generic-password","-a",n,"-s",t]),!0}catch{return !1}}getStoragePath(){return "macOS Keychain"}};});var q={};L(q,{LinuxKeyVaultProvider:()=>b});var X,b,z=A(()=>{"use strict";X=util.promisify(child_process.execFile),b=class{static async isAvailable(){let t=["/usr/bin/secret-tool","/bin/secret-tool","/usr/local/bin/secret-tool"];for(let n of t)try{return i.accessSync(n,i.constants.X_OK),!0}catch{}return !1}async getSecret(t,n){try{let{stdout:r}=await X("secret-tool",["lookup","service",t,"account",n]);return r.trim()||null}catch{return null}}async setSecret(t,n,r){await new Promise((s,o)=>{let a=child_process.spawn("secret-tool",["store","--label",t,"service",t,"account",n]);a.on("error",o),a.on("close",y=>{y===0?s():o(new Error(`secret-tool exited with code ${y}`));}),a.stdin.write(r),a.stdin.end();});}async deleteSecret(t,n){try{return await X("secret-tool",["clear","service",t,"account",n]),!0}catch{return !1}}getStoragePath(){return "Linux Secret Service (libsecret)"}};});var Z={};L(Z,{WindowsKeyVaultProvider:()=>U});var U,Q=A(()=>{"use strict";U=class{static async isAvailable(){try{return await T("keytar").getPassword("__flow_probe__","__flow_probe__"),!0}catch{return !1}}async getSecret(t,n){return T("keytar").getPassword(t,n)}async setSecret(t,n,r){await T("keytar").setPassword(t,n,r);}async deleteSecret(t,n){return T("keytar").deletePassword(t,n)}getStoragePath(){return "Windows Credential Manager"}};});var fe=_e((an,Je)=>{Je.exports={name:"@ciandt-flow/flow-ai-obs",version:"0.8.2",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"}};});var Se="https://flow.ciandt.com";function R(){let e=process.env.FLOW_BASE_URL;return e&&e.trim()?e.trim():Se}function k(){let e=R();return {AUTH_ENGINE:process.env.FLOW_AUTH_ENGINE_URL||`${e}/auth-engine-api/v2/api-key/token`,GATEWAY_TRACES:process.env.FLOW_GATEWAY_TRACES_URL||`${e}/flow-langfuse-gateway/v1/traces`,GATEWAY_HEALTH:process.env.FLOW_GATEWAY_HEALTH_URL||`${e}/flow-langfuse-gateway/v1/health`,OTEL_ENDPOINT:process.env.FLOW_OTEL_ENDPOINT_URL||`${e}/otel`}}var we=k(),_={SERVICE:"flow-plugins-cli",ACCOUNT_CREDS:"credentials"},S="FLOW-nodejs",w="config.json";function V(){let e=R();return {ANTHROPIC_BASE_URL:process.env.FLOW_LLM_PROXY_URL??`${e}/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-sonnet",CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"}}var j={CLAUDE_CODE_ENABLE_TELEMETRY:"1",OTEL_EXPORTER_OTLP_ENDPOINT:we.OTEL_ENDPOINT,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={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 Y={LOCK_STALE_MS:3e4},G={UserPromptSubmit:5,PreToolUse:3,PostToolUse:10,Stop:15};var W="flow-ai-obs-debug.log";var P={credentials:"credentials","token-cache":"tokenCache"};function m(){let e=l__namespace.default.homedir();if(process.platform==="darwin")return u__namespace.default.join(e,"Library","Preferences",S,w);if(process.platform==="win32"){let n=process.env.APPDATA??u__namespace.default.join(e,"AppData","Roaming");return u__namespace.default.join(n,S,w)}let t=process.env.XDG_CONFIG_HOME??u__namespace.default.join(e,".config");return u__namespace.default.join(t,S,w)}function I(){try{let e=i__namespace.default.readFileSync(m(),"utf8");return JSON.parse(e)}catch{return {}}}function B(e){let t=m();i__namespace.default.mkdirSync(u__namespace.default.dirname(t),{recursive:true}),i__namespace.default.writeFileSync(t,JSON.stringify(e,null,2),{encoding:"utf8",mode:384});}var v=class{static isAvailable(){return true}static hasExistingData(){try{if(!i__namespace.default.existsSync(m()))return !1;let t=JSON.parse(i__namespace.default.readFileSync(m(),"utf8"));return !!(t&&t.credentials)}catch{return false}}async getSecret(t,n){let r=I(),s=P[n]??n,o=r[s];return o?typeof o=="string"?o:JSON.stringify(o):null}async setSecret(t,n,r){let s=I(),o=P[n]??n;if(n==="token-cache")try{s[o]=JSON.parse(r);}catch{s[o]=r;}else s[o]=r;B(s);}async deleteSecret(t,n){let r=I(),s=P[n]??n;return s in r?(delete r[s],B(r),true):false}getStoragePath(){return `config.json (unencrypted) \u2014 ${m()}`}};async function ee(){return await be()??new v}async function be(){switch(process.platform){case "darwin":{let{MacOsKeyVaultProvider:e}=await Promise.resolve().then(()=>(K(),J));return await e.isAvailable()?new e:null}case "linux":{let{LinuxKeyVaultProvider:e}=await Promise.resolve().then(()=>(z(),q));return await e.isAvailable()?new e:null}case "win32":{let{WindowsKeyVaultProvider:e}=await Promise.resolve().then(()=>(Q(),Z));return await e.isAvailable()?new e:null}default:return null}}var Ue=_.SERVICE,Fe=_.ACCOUNT_CREDS,F=null;function $e(){return F||(F=ee()),F}async function te(){let t=await(await $e()).getSecret(Ue,Fe);if(!t)return null;try{return JSON.parse(t)}catch{return null}}u.join(l.tmpdir(),W);!process.env.NO_COLOR&&process.stdout.isTTY;function $(){return process.platform==="win32"?false:process.getuid?.()===0}function ne(){if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let t=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(t)return {home:t,username:process.env.SUDO_USER}}return {home:l__namespace.homedir(),username:process.env.SUDO_USER||process.env.USER||l__namespace.userInfo().username}}function O(){if(process.env.WSL_DISTRO_NAME&&process.platform==="linux"){let e=process.env.USERPROFILE;if(!e){let n=child_process.spawnSync("cmd.exe",["/c","echo","%USERPROFILE%"],{encoding:"utf8",timeout:5e3}).stdout?.trim();n&&/^[A-Za-z]:\\/.test(n)&&(e=n);}if(e){let t=e.replace(/^([A-Za-z]):/,(n,r)=>`/mnt/${r.toLowerCase()}`).replace(/\\/g,"/");return u__namespace.join(t,".claude","settings.json")}return u__namespace.join(l__namespace.homedir(),".claude","settings.json")}if(process.platform==="win32"){let e=process.env.USERPROFILE||l__namespace.homedir();return u__namespace.join(e,".claude","settings.json")}if(process.platform==="linux"&&process.getuid?.()===0&&process.env.SUDO_USER){let t=child_process.spawnSync("getent",["passwd",process.env.SUDO_USER],{encoding:"utf8",timeout:5e3}).stdout?.split(":")[5]?.trim();if(t)return u__namespace.join(t,".claude","settings.json")}return u__namespace.join(l__namespace.homedir(),".claude","settings.json")}var re="flow-ai-obs",se="config.json";function ie(){if(process.platform==="win32"){let n=process.env.APPDATA||u__namespace.join(l__namespace.homedir(),"AppData","Roaming");return u__namespace.join(n,re,se)}let e=ne(),t=process.env.XDG_CONFIG_HOME||u__namespace.join(e.home,".config");return u__namespace.join(t,re,se)}var Ge=Y.LOCK_STALE_MS;function ae(e){try{let t=i__namespace.statSync(e);Date.now()-t.mtimeMs>Ge&&i__namespace.unlinkSync(e);}catch{}try{i__namespace.writeFileSync(e,String(process.pid),{flag:"wx"});}catch(t){throw t.code==="EEXIST"?new Error("Another install is already in progress. If this is stale, remove: "+e):t}}function ce(e){try{i__namespace.unlinkSync(e);}catch{}}function We(e,t){let r=(Array.isArray(e)?e:[]).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 [t,...r]}function le(){let e=O(),t=e+".lock",n=[];i__namespace.mkdirSync(u__namespace.dirname(e),{recursive:true}),ae(t);try{if(i__namespace.existsSync(e)){i__namespace.copyFileSync(e,e+".bkp");try{i__namespace.chmodSync(e+".bkp",384);}catch{}}let r=ie();if(i__namespace.existsSync(r)){let c=r+".bkp";i__namespace.copyFileSync(r,c);try{i__namespace.chmodSync(c,384);}catch{}}let s={};try{s=JSON.parse(i__namespace.readFileSync(e,"utf8"));}catch{}let o=s.env&&typeof s.env=="object"?s.env:{};delete o.OTEL_EXPORTER_OTLP_HEADERS,s.env={...o,...j,...V()},s.otelHeadersHelper="flow-ai-obs otel-headers",(!s.hooks||typeof s.hooks!="object"||Array.isArray(s.hooks))&&(s.hooks={});let a=(c,E)=>({matcher:"",hooks:[{type:"command",command:`flow-ai-obs ${c}`,timeout:E}]}),y=["UserPromptSubmit","PreToolUse","PostToolUse","Stop"],M=s.hooks;for(let c of y){let E=We(M[c],a(c,G[c]));E.length>1&&n.push(c),M[c]=E;}i__namespace.writeFileSync(e,JSON.stringify(s,null,2)+`
|
|
3
3
|
`,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(e,384);}catch{}}finally{ce(t);}return {settingsPath:e,preserved:n}}function ue(e){let t=O(),n=t+".lock";i__namespace.mkdirSync(u__namespace.dirname(t),{recursive:true}),ae(n);try{let r={};try{r=JSON.parse(i__namespace.readFileSync(t,"utf8"));}catch{}(!r.env||typeof r.env!="object")&&(r.env={}),Object.assign(r.env,e),i__namespace.writeFileSync(t,JSON.stringify(r,null,2)+`
|
|
4
4
|
`,{encoding:"utf8",mode:384});try{i__namespace.chmodSync(t,384);}catch{}}finally{ce(n);}}function pe(e){if(!e)return null;try{let t=e.split(".");if(t.length<2)return null;let n=JSON.parse(Buffer.from(t[1].replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),{clientId:r,clientSecret:s,tenant:o}=n;return !r||!s||!o?null:{clientId:r,clientSecret:s,tenant:o}}catch{return null}}function de(e){let t=Buffer.from(JSON.stringify({alg:"none",typ:"JWT"})).toString("base64url"),n=Buffer.from(JSON.stringify({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant})).toString("base64url");return `${t}.${n}.`}var H;function ge(){return H||(H=fe()),H}var he=u__namespace.default.join(l__namespace.default.tmpdir(),"flow-obs-update-cache.json"),ze=1440*60*1e3,Ze=3e3;function Qe(e,t){let n=o=>{let a=String(o).replace(/^v/,"").match(/^(\d+)\.(\d+)\.(\d+)/);return a?[+a[1],+a[2],+a[3]]:null},r=n(e),s=n(t);return !r||!s?false:s[0]!==r[0]?s[0]>r[0]:s[1]!==r[1]?s[1]>r[1]:s[2]>r[2]}function et(){try{let e=JSON.parse(i__namespace.default.readFileSync(he,"utf8"));return typeof e.latestVersion!="string"||Date.now()-e.checkedAt>=ze?null:e}catch{return null}}function tt(e,t,n=Date.now()){try{i__namespace.default.writeFileSync(he,JSON.stringify({latestVersion:e,updatePriority:t??null,checkedAt:n}),{mode:384});}catch{}}function nt(e){let t=ge().name,n=Ke__default.default.get(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{timeout:Ze},r=>{if(r.statusCode!==200)return r.resume(),e(new Error(`HTTP ${r.statusCode}`));let s="";r.setEncoding("utf8"),r.on("data",o=>{s+=o;}),r.on("end",()=>{try{let o=JSON.parse(s);if(typeof o.version!="string")throw new Error("no version field");e(null,{version:o.version,updatePriority:typeof o.updatePriority=="string"?o.updatePriority:null});}catch(o){e(o);}});});n.on("error",e),n.on("timeout",()=>{n.destroy(new Error("timeout"));});}function ye(){try{if(et())return;setImmediate(()=>{nt((e,t)=>{e||!t||Qe(ge().version,t.version)&&tt(t.version,t.updatePriority,0);});});}catch{}}var rt=u__namespace.default.resolve(__dirname,".."),st=process.env.INIT_CWD?u__namespace.default.resolve(process.env.INIT_CWD):null;st===rt&&process.exit(0);$()&&(process.stderr.write(`
|
|
5
5
|
[flow-ai-obs] \u2717 Do not install with sudo.
|