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