@oro.ad/nuxt-claude-devtools-bc 1.0.0

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 ADDED
@@ -0,0 +1,227 @@
1
+ # @oro.ad/nuxt-claude-devtools-bc
2
+
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
+ [![License][license-src]][license-href]
6
+ [![Nuxt][nuxt-src]][nuxt-href]
7
+
8
+ Nuxt module for automatic Vite dev server configuration with tunnels (Cloudflare, ngrok, etc.) and DevTools integration for Business Console.
9
+
10
+ ## Problem
11
+
12
+ When running Nuxt dev server through a tunnel (e.g., `bc-xxx.domain.com` -> `localhost:3000`):
13
+
14
+ 1. **MIME type errors** - Vite serves CSS as module script
15
+ 2. **HMR doesn't work** - WebSocket tries to connect to localhost instead of public domain
16
+ 3. **Modules don't load** - `origin` points to localhost
17
+
18
+ ```
19
+ Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/css"
20
+ WebSocket connection to 'wss://localhost:5173/_nuxt/' failed
21
+ [vite] failed to connect to websocket
22
+ ```
23
+
24
+ ## Solution
25
+
26
+ This module automatically configures Vite dev server for tunnel environments by reading the `DEV_TUNNEL_HOST` environment variable.
27
+
28
+ ## Features
29
+
30
+ - Automatic Vite dev server configuration for tunnels
31
+ - Support for Cloudflare Tunnel, ngrok, and other reverse proxies
32
+ - Nuxt DevTools integration with tunnel status display
33
+ - **Auto-disable DevTools authorization** for tunnel access
34
+ - `useTunnel()` composable for runtime access to tunnel config
35
+ - Environment variable and config-based configuration
36
+
37
+ ## Quick Setup
38
+
39
+ 1. Add `@oro.ad/nuxt-claude-devtools-bc` dependency to your project
40
+
41
+ ```bash
42
+ npm install @oro.ad/nuxt-claude-devtools-bc
43
+ ```
44
+
45
+ 2. Add module to `nuxt.config.ts`
46
+
47
+ ```ts
48
+ export default defineNuxtConfig({
49
+ modules: ['@oro.ad/nuxt-claude-devtools-bc'],
50
+ })
51
+ ```
52
+
53
+ 3. Run with tunnel host
54
+
55
+ ```bash
56
+ # Option 1: Inline environment variable
57
+ DEV_TUNNEL_HOST=my-app.trycloudflare.com npm run dev
58
+
59
+ # Option 2: .env.local (gitignored)
60
+ echo "DEV_TUNNEL_HOST=my-app.trycloudflare.com" > .env.local
61
+ npm run dev
62
+ ```
63
+
64
+ ## Configuration
65
+
66
+ ### Environment Variables
67
+
68
+ | Variable | Description | Default |
69
+ |----------|-------------|---------|
70
+ | `DEV_TUNNEL_HOST` | Public tunnel domain (without protocol) | - |
71
+ | `DEV_TUNNEL_PROTOCOL` | Protocol (`http` or `https`) | `https` |
72
+ | `DEV_TUNNEL_PORT` | HMR WebSocket port | `443` for https, `80` for http |
73
+
74
+ ### nuxt.config.ts Options
75
+
76
+ ```ts
77
+ export default defineNuxtConfig({
78
+ modules: ['@oro.ad/nuxt-claude-devtools-bc'],
79
+
80
+ claudeDevtoolsBc: {
81
+ tunnel: {
82
+ // Explicit host (overrides env variable)
83
+ host: 'my-tunnel.domain.com',
84
+ protocol: 'https',
85
+ port: 443,
86
+
87
+ // Additional allowed hosts
88
+ additionalHosts: ['staging.domain.com'],
89
+
90
+ // Disable tunnel configuration
91
+ enabled: true,
92
+ },
93
+
94
+ // Enable/disable DevTools tab
95
+ devtools: true,
96
+
97
+ // Auto-disable DevTools authorization when tunnel is active (default: true)
98
+ // Set to false to keep authorization enabled
99
+ disableDevtoolsAuth: true,
100
+ },
101
+ })
102
+ ```
103
+
104
+ ### DevTools Authorization
105
+
106
+ When a tunnel is configured, the module **automatically disables Nuxt DevTools authorization**. This is required because DevTools auth doesn't work through tunnels/proxies.
107
+
108
+ To keep authorization enabled (not recommended for tunnel usage):
109
+
110
+ ```ts
111
+ claudeDevtoolsBc: {
112
+ disableDevtoolsAuth: false,
113
+ }
114
+ ```
115
+
116
+ ## Usage
117
+
118
+ ### useTunnel() Composable
119
+
120
+ Access tunnel configuration in your components:
121
+
122
+ ```vue
123
+ <script setup>
124
+ const tunnel = useTunnel()
125
+ </script>
126
+
127
+ <template>
128
+ <div v-if="tunnel.isActive.value">
129
+ Tunnel active: {{ tunnel.origin.value }}
130
+ </div>
131
+ </template>
132
+ ```
133
+
134
+ ### DevTools Integration
135
+
136
+ Open Nuxt DevTools and navigate to the "Claude BC" tab to see:
137
+ - Current tunnel status
138
+ - Connection details (host, protocol, HMR config)
139
+ - Environment variables
140
+
141
+ ## Testing with Cloudflare Tunnel
142
+
143
+ ```bash
144
+ # Terminal 1: Start tunnel
145
+ cloudflared tunnel --url http://localhost:3000
146
+ # Get URL like: https://random-words.trycloudflare.com
147
+
148
+ # Terminal 2: Start Nuxt
149
+ DEV_TUNNEL_HOST=random-words.trycloudflare.com npm run dev
150
+ ```
151
+
152
+ ## Business Console Integration
153
+
154
+ For Business Console spawner scripts:
155
+
156
+ ```bash
157
+ #!/bin/bash
158
+ SESSION_CODE=$1
159
+ DEV_DOMAIN=$2
160
+
161
+ export DEV_TUNNEL_HOST="bc-${SESSION_CODE}.${DEV_DOMAIN}"
162
+ npm run dev
163
+ ```
164
+
165
+ ## What This Module Configures
166
+
167
+ When `DEV_TUNNEL_HOST` is set, the module automatically configures:
168
+
169
+ ### Vite Dev Server
170
+
171
+ ```ts
172
+ {
173
+ vite: {
174
+ server: {
175
+ allowedHosts: [tunnelHost, 'localhost'],
176
+ origin: `https://${tunnelHost}`,
177
+ hmr: {
178
+ protocol: 'wss',
179
+ host: tunnelHost,
180
+ clientPort: 443
181
+ }
182
+ }
183
+ }
184
+ }
185
+ ```
186
+
187
+ ### DevTools Authorization
188
+
189
+ ```ts
190
+ {
191
+ devtools: {
192
+ disableAuthorization: true // Allows access through tunnel
193
+ }
194
+ }
195
+ ```
196
+
197
+ ## Development
198
+
199
+ ```bash
200
+ # Install dependencies
201
+ npm install
202
+
203
+ # Generate type stubs
204
+ npm run dev:prepare
205
+
206
+ # Develop with playground
207
+ npm run dev
208
+
209
+ # Run ESLint
210
+ npm run lint
211
+
212
+ # Build
213
+ npm run prepack
214
+ ```
215
+
216
+ <!-- Badges -->
217
+ [npm-version-src]: https://img.shields.io/npm/v/@oro.ad/nuxt-claude-devtools-bc/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
218
+ [npm-version-href]: https://npmjs.com/package/@oro.ad/nuxt-claude-devtools-bc
219
+
220
+ [npm-downloads-src]: https://img.shields.io/npm/dm/@oro.ad/nuxt-claude-devtools-bc.svg?style=flat&colorA=18181B&colorB=28CF8D
221
+ [npm-downloads-href]: https://npmjs.com/package/@oro.ad/nuxt-claude-devtools-bc
222
+
223
+ [license-src]: https://img.shields.io/npm/l/@oro.ad/nuxt-claude-devtools-bc.svg?style=flat&colorA=18181B&colorB=28CF8D
224
+ [license-href]: https://npmjs.com/package/@oro.ad/nuxt-claude-devtools-bc
225
+
226
+ [nuxt-src]: https://img.shields.io/badge/Nuxt-18181B?logo=nuxt
227
+ [nuxt-href]: https://nuxt.com
@@ -0,0 +1 @@
1
+ <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__claude-devtools-bc/_nuxt/entry.DbfI69ZY.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__claude-devtools-bc/_nuxt/N02BnA5h.js"><script type="module" src="/__claude-devtools-bc/_nuxt/N02BnA5h.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__claude-devtools-bc",buildId:"b0257768-6ba6-4f04-9da1-ec8a65a9539b",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1768513752316,false]</script></body></html>
@@ -0,0 +1 @@
1
+ <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__claude-devtools-bc/_nuxt/entry.DbfI69ZY.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__claude-devtools-bc/_nuxt/N02BnA5h.js"><script type="module" src="/__claude-devtools-bc/_nuxt/N02BnA5h.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__claude-devtools-bc",buildId:"b0257768-6ba6-4f04-9da1-ec8a65a9539b",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1768513752316,false]</script></body></html>
@@ -0,0 +1 @@
1
+ import{k as O,y as q,s as B,p as N,e as R,q as T,z as j,A as E,B as U,C as I,l as A,D as L,E as D,G as w,H,I as b,J as P,K as F,L as V,M as z,N as M,O as W,P as G}from"./N02BnA5h.js";const $=(...t)=>t.find(o=>o!==void 0);function J(t){const o=t.componentName||"NuxtLink";function v(e){return typeof e=="string"&&e.startsWith("#")}function S(e,u,f){const r=f??t.trailingSlash;if(!e||r!=="append"&&r!=="remove")return e;if(typeof e=="string")return C(e,r);const l="path"in e&&e.path!==void 0?e.path:u(e).path;return{...e,name:void 0,path:C(l,r)}}function k(e){const u=q(),f=V(),r=b(()=>!!e.target&&e.target!=="_self"),l=b(()=>{const i=e.to||e.href||"";return typeof i=="string"&&P(i,{acceptRelative:!0})}),p=L("RouterLink"),h=typeof p!="string"?p.useLink:void 0,c=b(()=>{if(e.external)return!0;const i=e.to||e.href||"";return typeof i=="object"?!1:i===""||l.value}),n=b(()=>{const i=e.to||e.href||"";return c.value?i:S(i,u.resolve,e.trailingSlash)}),g=c.value?void 0:h?.({...e,to:n}),y=b(()=>{const i=e.trailingSlash??t.trailingSlash;if(!n.value||l.value||v(n.value))return n.value;if(c.value){const m=typeof n.value=="object"&&"path"in n.value?w(n.value):n.value,x=typeof m=="object"?u.resolve(m).href:m;return C(x,i)}return typeof n.value=="object"?u.resolve(n.value)?.href??null:C(F(f.app.baseURL,n.value),i)});return{to:n,hasTarget:r,isAbsoluteUrl:l,isExternal:c,href:y,isActive:g?.isActive??b(()=>n.value===u.currentRoute.value.path),isExactActive:g?.isExactActive??b(()=>n.value===u.currentRoute.value.path),route:g?.route??b(()=>u.resolve(n.value)),async navigate(i){await z(y.value,{replace:e.replace,external:c.value||r.value})}}}return O({name:o,props:{to:{type:[String,Object],default:void 0,required:!1},href:{type:[String,Object],default:void 0,required:!1},target:{type:String,default:void 0,required:!1},rel:{type:String,default:void 0,required:!1},noRel:{type:Boolean,default:void 0,required:!1},prefetch:{type:Boolean,default:void 0,required:!1},prefetchOn:{type:[String,Object],default:void 0,required:!1},noPrefetch:{type:Boolean,default:void 0,required:!1},activeClass:{type:String,default:void 0,required:!1},exactActiveClass:{type:String,default:void 0,required:!1},prefetchedClass:{type:String,default:void 0,required:!1},replace:{type:Boolean,default:void 0,required:!1},ariaCurrentValue:{type:String,default:void 0,required:!1},external:{type:Boolean,default:void 0,required:!1},custom:{type:Boolean,default:void 0,required:!1},trailingSlash:{type:String,default:void 0,required:!1}},useLink:k,setup(e,{slots:u}){const f=q(),{to:r,href:l,navigate:p,isExternal:h,hasTarget:c,isAbsoluteUrl:n}=k(e),g=B(!1),y=N(null),i=s=>{y.value=e.custom?s?.$el?.nextElementSibling:s?.$el};function m(s){return!g.value&&(typeof e.prefetchOn=="string"?e.prefetchOn===s:e.prefetchOn?.[s]??t.prefetchOn?.[s])&&(e.prefetch??t.prefetch)!==!1&&e.noPrefetch!==!0&&e.target!=="_blank"&&!X()}async function x(s=R()){if(g.value)return;g.value=!0;const d=typeof r.value=="string"?r.value:h.value?w(r.value):f.resolve(r.value).fullPath,a=h.value?new URL(d,window.location.href).href:d;await Promise.all([s.hooks.callHook("link:prefetch",a).catch(()=>{}),!h.value&&!c.value&&H(r.value,f).catch(()=>{})])}if(m("visibility")){const s=R();let d,a=null;T(()=>{const _=K();j(()=>{d=E(()=>{y?.value?.tagName&&(a=_.observe(y.value,async()=>{a?.(),a=null,await x(s)}))})})}),U(()=>{d&&I(d),a?.(),a=null})}return()=>{if(!h.value&&!c.value&&!v(r.value)){const a={ref:i,to:r.value,activeClass:e.activeClass||t.activeClass,exactActiveClass:e.exactActiveClass||t.exactActiveClass,replace:e.replace,ariaCurrentValue:e.ariaCurrentValue,custom:e.custom};return e.custom||(m("interaction")&&(a.onPointerenter=x.bind(null,void 0),a.onFocus=x.bind(null,void 0)),g.value&&(a.class=e.prefetchedClass||t.prefetchedClass),a.rel=e.rel||void 0),A(L("RouterLink"),a,u.default)}const s=e.target||null,d=$(e.noRel?"":e.rel,t.externalRelAttribute,n.value||c.value?"noopener noreferrer":"")||null;return e.custom?u.default?u.default({href:l.value,navigate:p,prefetch:x,get route(){if(!l.value)return;const a=new URL(l.value,window.location.href);return{path:a.pathname,fullPath:a.pathname,get query(){return D(a.search)},hash:a.hash,params:{},name:void 0,matched:[],redirectedFrom:void 0,meta:{},href:l.value}},rel:d,target:s,isExternal:h.value||c.value,isActive:!1,isExactActive:!1}):null:A("a",{ref:y,href:l.value||null,rel:d,target:s,onClick:a=>{if(!(h.value||c.value))return a.preventDefault(),e.replace?f.replace(l.value):f.push(l.value)}},u.default?.())}}})}const Z=J(G);function C(t,o){const v=o==="append"?M:W;return P(t)&&!t.startsWith("http")?t:v(t,!0)}function K(){const t=R();if(t._observer)return t._observer;let o=null;const v=new Map,S=(e,u)=>(o||=new IntersectionObserver(f=>{for(const r of f){const l=v.get(r.target);(r.isIntersecting||r.intersectionRatio>0)&&l&&l()}}),v.set(e,u),o.observe(e),()=>{v.delete(e),o?.unobserve(e),v.size===0&&(o?.disconnect(),o=null)});return t._observer={observe:S}}const Q=/2g/;function X(){const t=navigator.connection;return!!(t&&(t.saveData||Q.test(t.effectiveType)))}export{Z as _};
@@ -0,0 +1,9 @@
1
+ import{c as a,o as l,n as w,r as m,a as t,g as L,j as E,k as O,l as N,_ as V,s as S,m as U,p as y,q as j,d as r,b as d,w as u,t as i,F as B,v as H,x as T}from"./N02BnA5h.js";import{_ as R}from"./BkeABxse.js";const h={__name:"NIcon",props:{icon:{type:String,required:!1}},setup(o){return(s,n)=>(l(),a("div",{class:w(["n-icon",o.icon])},null,2))}},$={class:"n-tip n-tip-base"},P={__name:"NTip",props:{icon:{type:String,required:!1}},setup(o){return(s,n)=>{const p=h;return l(),a("div",$,[m(s.$slots,"icon",{},()=>[o.icon?(l(),L(p,{key:0,icon:o.icon,class:"n-tip-icon"},null,8,["icon"])):E("",!0)]),t("div",null,[m(s.$slots,"default")])])}}},F=O({name:"NButton",props:{to:String,icon:String,border:{type:Boolean,default:!0},disabled:Boolean,type:{type:String,default:"button"}},setup(o,{attrs:s,slots:n}){return()=>N(o.to?R:"button",{to:o.to,...s,...!o.to&&{type:o.type},...o.disabled?{disabled:!0}:{tabindex:0},class:[o.border?"n-button-base active:n-button-active focus-visible:n-focus-base hover:n-button-hover":"",n.default?"":"n-icon-button","n-button n-transition n-disabled:n-disabled"].join(" ")},{default:()=>[m(n,"icon",{},()=>o.icon?[N(h,{icon:o.icon,class:n.default?"n-button-icon":""})]:[]),m(n,"default")]})}}),q={},I={class:"n-card n-card-base"};function X(o,s){return l(),a("div",I,[m(o.$slots,"default")])}const A=Object.assign(V(q,[["render",X]]),{__name:"NCard"});let f;const _=[];function M(o){if(_.push(o),!(typeof window>"u"))return window.__NUXT_DEVTOOLS__&&_.forEach(s=>s(window.__NUXT_DEVTOOLS__)),Object.defineProperty(window,"__NUXT_DEVTOOLS__",{set(s){s&&_.forEach(n=>n(s))},get(){return f.value},configurable:!0}),()=>{_.splice(_.indexOf(o),1)}}function z(){f||(f=S(),M(s));function o(){f&&U(f)}function s(n){f.value=n,n.host&&n.host.hooks.hook("host:update:reactivity",o)}return f}const W={class:"relative p-6 n-bg-base flex flex-col h-screen"},G={class:"flex items-center gap-3 mb-4"},J={key:0,class:"flex items-center gap-2 text-gray"},K={key:1},Q={key:2,class:"flex flex-col gap-4"},Y={class:"grid gap-3"},Z={class:"flex items-center justify-between p-2 rounded bg-gray/10"},tt={class:"flex items-center gap-2"},et={class:"text-green font-mono text-sm"},nt={class:"flex items-center justify-between p-2 rounded bg-gray/10"},ot={class:"font-mono text-sm"},st={class:"flex items-center justify-between p-2 rounded bg-gray/10"},it={class:"font-mono text-sm"},lt={class:"flex items-center justify-between p-2 rounded bg-gray/10"},at={class:"font-mono text-sm"},rt={class:"flex items-start justify-between p-2 rounded bg-gray/10"},ct={class:"flex flex-col items-end gap-1"},dt={class:"grid gap-2"},ut={class:"flex items-center justify-between p-2 rounded bg-gray/10"},ft={class:"text-sm"},pt={class:"flex items-center justify-between p-2 rounded bg-gray/10"},_t={class:"text-sm"},mt={class:"flex items-center justify-between p-2 rounded bg-gray/10"},vt={class:"text-sm"},gt={key:3,class:"flex flex-col gap-4"},xt={key:4,class:"mt-4 pt-4 border-t border-gray/20"},bt={class:"flex items-center gap-2 text-sm opacity-50"},Tt=O({__name:"index",setup(o){const s=z(),n=y(null),p=y(!0),g=y(null);async function k(){try{p.value=!0;const c=await fetch("/api/__claude-devtools-bc-config");if(!c.ok)throw new Error(`HTTP ${c.status}`);n.value=await c.json()}catch(c){g.value=c instanceof Error?c.message:"Failed to load config"}finally{p.value=!1}}function C(c){navigator.clipboard.writeText(c)}return j(()=>{k()}),(c,e)=>{const x=P,D=F,v=A;return l(),a("div",W,[t("div",G,[t("div",{class:w(["i-carbon-connection-signal text-2xl",n.value?.tunnel?"text-green":"text-gray"])},null,2),e[1]||(e[1]=t("h1",{class:"text-2xl font-bold"}," Claude DevTools BC ",-1))]),e[20]||(e[20]=t("div",{class:"opacity-50 mb-6"}," Tunnel Configuration for Business Console ",-1)),p.value?(l(),a("div",J,[...e[2]||(e[2]=[t("div",{class:"i-carbon-circle-dash animate-spin"},null,-1),r(" Loading configuration... ",-1)])])):g.value?(l(),a("div",K,[d(x,{n:"red",icon:"carbon-warning"},{default:u(()=>[r(" Failed to load configuration: "+i(g.value),1)]),_:1})])):n.value?.tunnel?(l(),a("div",Q,[d(x,{n:"green",icon:"carbon-checkmark"},{default:u(()=>[...e[3]||(e[3]=[r(" Tunnel is active and configured ",-1)])]),_:1}),d(v,{class:"p-4"},{default:u(()=>[e[9]||(e[9]=t("h3",{class:"font-semibold mb-3 flex items-center gap-2"},[t("div",{class:"i-carbon-link"}),r(" Connection Details ")],-1)),t("div",Y,[t("div",Z,[e[4]||(e[4]=t("span",{class:"text-sm opacity-70"},"Public URL",-1)),t("div",tt,[t("code",et,i(n.value.tunnel.origin),1),d(D,{n:"xs",icon:"carbon-copy",title:"Copy URL",onClick:e[0]||(e[0]=b=>C(n.value.tunnel.origin))})])]),t("div",nt,[e[5]||(e[5]=t("span",{class:"text-sm opacity-70"},"Host",-1)),t("code",ot,i(n.value.tunnel.host),1)]),t("div",st,[e[6]||(e[6]=t("span",{class:"text-sm opacity-70"},"Protocol",-1)),t("code",it,i(n.value.tunnel.protocol),1)]),t("div",lt,[e[7]||(e[7]=t("span",{class:"text-sm opacity-70"},"HMR WebSocket",-1)),t("code",at,i(n.value.tunnel.wsProtocol)+"://"+i(n.value.tunnel.host)+":"+i(n.value.tunnel.port),1)]),t("div",rt,[e[8]||(e[8]=t("span",{class:"text-sm opacity-70"},"Allowed Hosts",-1)),t("div",ct,[(l(!0),a(B,null,H(n.value.tunnel.allowedHosts,b=>(l(),a("code",{key:b,class:"font-mono text-xs"},i(b),1))),128))])])])]),_:1}),d(v,{class:"p-4"},{default:u(()=>[e[13]||(e[13]=t("h3",{class:"font-semibold mb-3 flex items-center gap-2"},[t("div",{class:"i-carbon-terminal"}),r(" Environment Variables ")],-1)),t("div",dt,[t("div",ut,[e[10]||(e[10]=t("span",{class:"font-mono text-xs"},"DEV_TUNNEL_HOST",-1)),t("code",ft,i(n.value.env.DEV_TUNNEL_HOST||"-"),1)]),t("div",pt,[e[11]||(e[11]=t("span",{class:"font-mono text-xs"},"DEV_TUNNEL_PROTOCOL",-1)),t("code",_t,i(n.value.env.DEV_TUNNEL_PROTOCOL||"-"),1)]),t("div",mt,[e[12]||(e[12]=t("span",{class:"font-mono text-xs"},"DEV_TUNNEL_PORT",-1)),t("code",vt,i(n.value.env.DEV_TUNNEL_PORT||"-"),1)])])]),_:1})])):(l(),a("div",gt,[d(x,{n:"yellow",icon:"carbon-information"},{default:u(()=>[...e[14]||(e[14]=[r(" No tunnel configured ",-1)])]),_:1}),d(v,{class:"p-4"},{default:u(()=>[...e[15]||(e[15]=[t("h3",{class:"font-semibold mb-3"}," How to configure ",-1),t("p",{class:"text-sm opacity-70 mb-3"},[r(" Set the "),t("code",{class:"bg-gray/20 px-1 rounded"},"DEV_TUNNEL_HOST"),r(" environment variable: ")],-1),t("div",{class:"bg-gray/10 p-3 rounded font-mono text-sm"},[t("div",{class:"opacity-50"}," # Option 1: Inline "),t("div",{class:"text-green"}," DEV_TUNNEL_HOST=my-app.trycloudflare.com npm run dev "),t("div",{class:"mt-2 opacity-50"}," # Option 2: .env.local "),t("div",{class:"text-green"},' echo "DEV_TUNNEL_HOST=my-app.trycloudflare.com" > .env.local ')],-1)])]),_:1}),d(v,{class:"p-4"},{default:u(()=>[...e[16]||(e[16]=[t("h3",{class:"font-semibold mb-3"}," Or configure in nuxt.config.ts ",-1),t("div",{class:"bg-gray/10 p-3 rounded font-mono text-sm"},[t("pre",{class:"text-green"},`export default defineNuxtConfig({
2
+ claudeDevtoolsBc: {
3
+ tunnel: {
4
+ host: 'my-app.trycloudflare.com',
5
+ protocol: 'https',
6
+ port: 443,
7
+ }
8
+ }
9
+ })`)],-1)])]),_:1})])),e[21]||(e[21]=t("div",{class:"flex-auto"},null,-1)),T(s)?(l(),a("div",xt,[t("div",bt,[e[17]||(e[17]=t("div",{class:"i-carbon-checkmark text-green"},null,-1)),e[18]||(e[18]=r(" DevTools connected ",-1)),e[19]||(e[19]=t("span",{class:"opacity-50"},"|",-1)),r(" Vue "+i(T(s).host.nuxt.vueApp.version),1)])])):E("",!0)])}}});export{Tt as default};
@@ -0,0 +1 @@
1
+ import{_ as o,c as s,o as a,a as t,t as r}from"./N02BnA5h.js";import{u as i}from"./W-9jjdUG.js";const u={class:"antialiased bg-white dark:bg-[#020420] dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-[#020420] tracking-wide"},l={class:"max-w-520px text-center"},c=["textContent"],d=["textContent"],p=["textContent"],f={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},statusCode:{type:Number,default:500},statusMessage:{type:String,default:"Internal server error"},description:{type:String,default:"This page is temporarily unavailable."},refresh:{type:String,default:"Refresh this page"}},setup(e){const n=e;return i({title:`${n.statusCode} - ${n.statusMessage} | ${n.appName}`,script:[{innerHTML:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:'*,:after,:before{border-color:var(--un-default-border-color,#e5e7eb);border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}h1,h2{font-size:inherit;font-weight:inherit}h1,h2,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(g,h)=>(a(),s("div",u,[t("div",l,[t("h1",{class:"font-semibold leading-none mb-4 sm:text-[110px] tabular-nums text-[80px]",textContent:r(e.statusCode)},null,8,c),t("h2",{class:"font-semibold mb-2 sm:text-3xl text-2xl",textContent:r(e.statusMessage)},null,8,d),t("p",{class:"mb-4 px-2 text-[#64748B] text-md",textContent:r(e.description)},null,8,p)])]))}},x=o(f,[["__scopeId","data-v-8851f357"]]);export{x as default};