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