@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/LICENSE.md +674 -0
- package/README.md +227 -0
- package/dist/client/200.html +1 -0
- package/dist/client/404.html +1 -0
- package/dist/client/_nuxt/BkeABxse.js +1 -0
- package/dist/client/_nuxt/D_J0GzWk.js +9 -0
- package/dist/client/_nuxt/Kn4Iaa8g.js +1 -0
- package/dist/client/_nuxt/N02BnA5h.js +4 -0
- package/dist/client/_nuxt/W-9jjdUG.js +1 -0
- package/dist/client/_nuxt/builds/latest.json +1 -0
- package/dist/client/_nuxt/builds/meta/b0257768-6ba6-4f04-9da1-ec8a65a9539b.json +1 -0
- package/dist/client/_nuxt/entry.DbfI69ZY.css +1 -0
- package/dist/client/_nuxt/error-404.BLrjNXsr.css +1 -0
- package/dist/client/_nuxt/error-500.DLkAwcfL.css +1 -0
- package/dist/client/_nuxt/nSemZUqJ.js +1 -0
- package/dist/client/index.html +1 -0
- package/dist/module.d.mts +77 -0
- package/dist/module.json +12 -0
- package/dist/module.mjs +144 -0
- package/dist/runtime/composables/useTunnel.d.ts +12 -0
- package/dist/runtime/composables/useTunnel.js +12 -0
- package/dist/runtime/plugin.d.ts +12 -0
- package/dist/runtime/plugin.js +20 -0
- package/dist/runtime/server/api/__claude-devtools-bc-config.get.d.ts +2 -0
- package/dist/runtime/server/api/__claude-devtools-bc-config.get.js +12 -0
- package/dist/types.d.mts +3 -0
- package/package.json +74 -0
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};
|