diff --git a/.dockerignore b/.dockerignore
index 8855740d..efc0965a 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -31,13 +31,6 @@ testdata/
.env.local
wasm.sh
-# Node.js (not needed in the image)
-web/node_modules/
-
-# Front-end build artifacts not needed by the binary-only image.
-frontend-integration/node_modules/
-web/vue-demo/
-
# Temporary files
tmp/
temp/
diff --git a/.github/workflows/wasm-publish.yaml b/.github/workflows/wasm-publish.yaml
index a2f01d8a..5fc1c5cd 100644
--- a/.github/workflows/wasm-publish.yaml
+++ b/.github/workflows/wasm-publish.yaml
@@ -1,6 +1,7 @@
name: Publish WASM to S3
-# Builds the browser/WASM CLI static site and publishes it to S3 + CloudFront.
+# Builds the browser/WASM CLI's static assets (megaport.wasm + wasm_exec.js) and
+# publishes them to S3 + CloudFront.
#
# CONFIGURATION REQUIRED BEFORE MERGE (ESD-1506):
# AWS access is provisioned via the shared github_runners_iam Terraform module in
@@ -27,10 +28,9 @@ name: Publish WASM to S3
# See the "Check required configuration" step, which fails early with a clear message.
#
# WHAT GETS PUBLISHED:
-# Stable filenames under each prefix: megaport.wasm (brotli, Content-Encoding: br),
-# wasm_exec.js, and the rest of the static site. The portal references megaport.wasm
-# and wasm_exec.js by URL, so the names are kept stable rather than content-hashed;
-# the version/latest prefix provides the cache-busting instead.
+# Stable filenames under each prefix: megaport.wasm (brotli, Content-Encoding: br) and
+# wasm_exec.js. The portal references both by URL, so the names are kept stable rather
+# than content-hashed; the version/latest prefix provides the cache-busting instead.
#
# PORTAL INTEGRATION:
# Point the portal's wasmUrl/wasmExecUrl at the latest/ alias while iterating, then
@@ -108,12 +108,6 @@ jobs:
go-version-file: 'go.mod'
cache: true
- - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
- with:
- node-version: 20
- cache: npm
- cache-dependency-path: frontend-integration/package-lock.json
-
- name: Resolve version label
id: version
env:
@@ -142,7 +136,7 @@ jobs:
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "Publishing version: $version"
- - name: Build static site
+ - name: Build static assets
run: make web-static
- name: Compress WASM
@@ -151,7 +145,7 @@ jobs:
# cmd/wasmcompress writes .br (and .gz) next to the source file (ESD-1268).
# CloudFront auto-compression caps at 10 MB; the raw wasm is well over that,
# so it must be pre-compressed at origin and served with Content-Encoding: br.
- GOWORK=off go run ./cmd/wasmcompress web/vue-demo/megaport.wasm
+ GOWORK=off go run ./cmd/wasmcompress web/dist/megaport.wasm
- name: Compute integrity hashes
id: hashes
@@ -215,15 +209,14 @@ jobs:
PUBLISH_LATEST: ${{ inputs.publish_latest }}
run: |
set -euo pipefail
- src=web/vue-demo
+ src=web/dist
publish() {
local dest="s3://${BUCKET}/${PREFIX}/$1"
local cache="$2"
echo "==> Publishing to ${dest}"
- # Sync the static site; the wasm and wasm_exec.js are uploaded separately below
- # so we can pin their Content-Type/Content-Encoding instead of relying on
- # aws s3 sync's MIME inference.
+ # The wasm and wasm_exec.js are uploaded separately below so we can pin their
+ # Content-Type/Content-Encoding instead of relying on aws s3 sync's MIME inference.
aws s3 sync "$src/" "$dest/" --delete \
--exclude 'megaport.wasm' \
--exclude 'megaport.wasm.br' \
diff --git a/.gitignore b/.gitignore
index cf8b53f2..7a736d1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,14 +21,6 @@ web/megaport.wasm
*.wasm.br
*.wasm.gz
-# Node.js / npm
-node_modules/
-web/node_modules/
-package-lock.json
-web/package-lock.json
-# Committed so browser/WASM builds resolve identical dependency versions via npm ci.
-!frontend-integration/package-lock.json
-
# Go build artifacts
/megaport-cli
megaport-cli
diff --git a/Makefile b/Makefile
index f4cb7868..02e0b90a 100644
--- a/Makefile
+++ b/Makefile
@@ -97,10 +97,11 @@ wasm-smoke: wasm
wasm-compress: wasm
go run ./cmd/wasmcompress web/megaport.wasm
-# Build the static browser/WASM site into web/vue-demo/ (for CDN hosting)
+# Build the WASM binary + wasm_exec.js loader into web/dist/ (for CDN hosting)
web-static:
./scripts/build-web.sh
# Clean build artifacts
clean:
- rm -f megaport-cli cover*.out coverage*.out coverage.html web/megaport.wasm web/megaport.wasm.br web/megaport.wasm.gz web/vue-demo/megaport.wasm web/vue-demo/megaport.wasm.br web/vue-demo/megaport.wasm.gz
+ rm -f megaport-cli cover*.out coverage*.out coverage.html web/megaport.wasm web/megaport.wasm.br web/megaport.wasm.gz web/wasm_exec.js
+ rm -rf web/dist
diff --git a/WASM_README.md b/WASM_README.md
index 2e6c05f5..285563ed 100644
--- a/WASM_README.md
+++ b/WASM_README.md
@@ -88,9 +88,8 @@ Instead, whenever the API rejects a request with 401/403, whether that's because
token expired or because the host revoked it, the failing command's output contains
the substring `MEGAPORT_SESSION_EXPIRED`. The host is responsible for watching command
output for this marker and, on a match, prompting the user to re-authenticate and
-calling `setAuthToken` again with a fresh token. See
-[`frontend-integration/types/megaport-wasm.d.ts`](frontend-integration/types/megaport-wasm.d.ts)
-for the full type signature and doc comments.
+calling `setAuthToken` again with a fresh token. The registration and doc comments
+for `setAuthToken` live inline in `internal/wasm/wasm.go`.
Separately, the browser-cached OAuth token used by credentials-based logins
(`window.tokenManager.getToken(environment)`, checked to avoid re-authenticating on
@@ -120,43 +119,102 @@ always returns `{ error: "synchronous execution is not supported; use executeMeg
It will be removed in a future release; new integrations should not call it.
Full type definitions for the whole JS surface (auth, config file, prompts, telemetry)
-live in [`frontend-integration/types/megaport-wasm.d.ts`](frontend-integration/types/megaport-wasm.d.ts).
+are documented inline in `internal/wasm/`; there is no separate reference front end in
+this repo. Front-end integrators (e.g. the Portal) own their own wrapper around the
+`window.executeMegaportCommandAsync` API described above.
-## Building
+## Interactive Mode
-The browser CLI is two pieces: the WASM binary and the Vue front end that hosts it.
+Some commands prompt for input (interactive `buy`/`update` flows, confirmations, secrets).
+In the browser there is no stdin, so the WASM asks the host page for each value through a
+small set of JavaScript functions. Wire these up and run the command through
+`executeMegaportCommandAsync` (see [JavaScript API](#javascript-api)), or interactive
+commands will never receive a response.
-```bash
-# WASM binary only (writes web/megaport.wasm)
-make wasm
+### Host functions
-# Full static site: WASM + Vue front end, assembled into web/vue-demo/
-make web-static # or: ./scripts/build-web.sh
+The WASM registers these on `window` at startup:
+
+| Function | Purpose |
+|---|---|
+| `registerPromptHandler(cb)` | Register a callback the WASM invokes with each prompt request. |
+| `submitPromptResponse(id, response)` | Reply to the prompt `id` with the user's input (a string). |
+| `cancelPrompt(id)` | Cancel the prompt `id`. A value prompt fails with a "prompt cancelled by user" error; a confirmation is treated as declined. |
+
+### Prompt request shape
+
+Your handler receives a single object:
+
+```js
+{
+ id: "prompt_1_1700000000000000000", // unique id; echo it back in submit/cancel
+ message: "Enter port name:", // text to show the user
+ type: "text", // "text" | "confirm" | "password" | "resource"
+ resourceType: "port" // set for resource and secret-resource prompts (port, mcr, vxc, ...), else ""
+}
+```
+
+Mask the input when `type === "password"`: render an `` or otherwise
+hide the characters. Password prompts and secret-resource prompts (for example VXC/MVE
+passwords and pre-shared keys) set this type. Note that some other secret-bearing inputs
+(such as partner auth/service/shared keys and MVE registration keys) are currently sent as
+`type === "resource"`, so don't rely on the password type alone if you want to mask every
+possible secret.
+
+### Lifecycle
+
+```js
+registerPromptHandler((request) => {
+ const masked = request.type === 'password';
+ showPrompt(request.message, { masked }).then((answer) => {
+ if (answer === null) {
+ cancelPrompt(request.id); // user dismissed the prompt
+ } else {
+ submitPromptResponse(request.id, answer);
+ }
+ });
+});
+
+executeMegaportCommandAsync('vxc buy --interactive', (result) => {
+ console.log(result.output || result.error);
+});
+```
+
+A prompt left unanswered times out after 10 minutes and the command receives an error.
+
+### Live output streaming
+
+By default a command's output arrives once, in the async callback's result. To render
+output as it is produced instead, register a handler before running the command:
+
+```js
+registerOutputHandler((chunk) => terminal.write(chunk)); // chunk is a string
```
-`web-static` needs the Go toolchain and Node/npm on `PATH`. It produces a self-contained
-**`web/vue-demo/`** directory (Vue build + `megaport.wasm` + `wasm_exec.js`) ready to
-publish to a CDN. See [`web/README.md`](web/README.md) for the wasm pre-compression and
-cache-header details.
+The contract:
-## Local Development
+- Only narrative output (progress and status messages) streams. Structured document
+ output (table/JSON/CSV/XML) is never streamed; it arrives once in the completion result.
+- If your handler received at least one chunk without throwing, the completion result does
+ **not** repeat the streamed narrative, so don't render both.
+- If the handler throws or no chunk was delivered, streaming is disabled for the rest of
+ that command and the completion result falls back to the full captured output
+ (already-streamed chunks may then appear twice).
-The front end lives in `frontend-integration/` and has its own Vite dev server. The dev
-server serves files from that directory's root and has no `public/` dir, so build the wasm
-and copy the loader into `frontend-integration/` first, then start the server:
+## Building
```bash
-# From the repo root: build the wasm + loader into the dev server's root.
-GOOS=js GOARCH=wasm go build -tags js,wasm -o frontend-integration/megaport.wasm .
-cp "$(go env GOROOT)/lib/wasm/wasm_exec.js" frontend-integration/wasm_exec.js
+# WASM binary only (writes web/megaport.wasm)
+make wasm
-cd frontend-integration
-npm install
-npm run dev:demo
+# WASM binary + wasm_exec.js loader, assembled into web/dist/
+make web-static # or: ./scripts/build-web.sh
```
-Vite serves `megaport.wasm` with the correct `application/wasm` MIME type and reloads the
-front end on change. Rerun the build command above after changing Go code.
+`web-static` needs the Go toolchain on `PATH`. It produces a self-contained
+**`web/dist/`** directory (`megaport.wasm` + `wasm_exec.js`) ready to publish to a CDN.
+See [`web/README.md`](web/README.md) for the wasm pre-compression and cache-header
+details.
## Enabling a Module for WASM
@@ -230,16 +288,13 @@ aws s3 cp web/megaport.wasm s3://media.megaport.com/portal/megaport-cli/megaport
aws s3 cp web/wasm_exec.js s3://media.megaport.com/portal/megaport-cli/wasm_exec.js
```
-For CDN hosting (S3 + CloudFront) of the full static site, sync the assembled
-`web/vue-demo/` directory and serve it from the site root:
-
-```bash
-make web-static
-aws s3 sync web/vue-demo/ s3://// --delete
-```
-
-`--delete` prunes stale hashed assets from old builds, so point it at a prefix dedicated
-to this site, since it removes anything else under that prefix.
+For CDN hosting (S3 + CloudFront), publish via the `.github/workflows/wasm-publish.yaml`
+workflow rather than a plain sync. It runs `make web-static`, brotli pre-compresses the
+wasm (`cmd/wasmcompress`), then uploads `megaport.wasm` with `Content-Encoding: br` and
+pins `Content-Type` on both the wasm and `wasm_exec.js`. It syncs only the remaining
+static assets, so a bare `aws s3 sync web/dist/` would instead serve the wasm
+uncompressed and let the CDN mis-infer its MIME type, which breaks
+`WebAssembly.instantiateStreaming`.
## Troubleshooting
diff --git a/cmd/wasmhash/main_test.go b/cmd/wasmhash/main_test.go
index f2161110..71bc3a8a 100644
--- a/cmd/wasmhash/main_test.go
+++ b/cmd/wasmhash/main_test.go
@@ -58,8 +58,8 @@ func TestHashFileDeterministicAndContentSensitive(t *testing.T) {
}
func TestInsertHash(t *testing.T) {
- got := insertHash(filepath.FromSlash("web/vue-demo/megaport.wasm"), "abcd1234")
- want := filepath.FromSlash("web/vue-demo/megaport.abcd1234.wasm")
+ got := insertHash(filepath.FromSlash("web/dist/megaport.wasm"), "abcd1234")
+ want := filepath.FromSlash("web/dist/megaport.abcd1234.wasm")
if got != want {
t.Fatalf("insertHash = %q, want %q", got, want)
}
diff --git a/frontend-integration/.gitignore b/frontend-integration/.gitignore
deleted file mode 100644
index 2c6eecc7..00000000
--- a/frontend-integration/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-# Dependencies
-node_modules/
-
-# Build output
-dist/
-*.local
-
-# Local dev WASM artifacts (built into this dir for the dev server)
-/megaport.wasm
-/wasm_exec.js
-
-# IDE
-.vscode/
-.idea/
-*.swp
-*.swo
-*~
-
-# OS
-.DS_Store
-Thumbs.db
-
-# Logs
-logs/
-*.log
-npm-debug.log*
-
-# Environment
-.env
-.env.local
-.env.*.local
diff --git a/frontend-integration/INTEGRATION_GUIDE.md b/frontend-integration/INTEGRATION_GUIDE.md
deleted file mode 100644
index 439b04ff..00000000
--- a/frontend-integration/INTEGRATION_GUIDE.md
+++ /dev/null
@@ -1,508 +0,0 @@
-# Portal Integration Guide
-
-The Megaport CLI has been compiled to WebAssembly and packaged as Vue 3 components for portal integration.
-
-**What you get:**
-
-- Native CLI functionality in the browser
-- No backend required
-- TypeScript support
-- Works with existing portal auth
-- Full test coverage
-
----
-
-## What's Included
-
-### WebAssembly Binary
-
-- `megaport.wasm` (~2-5 MB) - Complete CLI compiled to WASM
-- `wasm_exec.js` (~15 KB) - Go WASM runtime
-- Runs entirely in the browser
-
-### Vue 3 Components
-
-```
-frontend-integration/
-├── components/
-│ └── MegaportTerminal.vue # Ready-to-use terminal component
-├── composables/
-│ └── useMegaportWASM.ts # Core WASM integration composable
-├── types/
-│ └── megaport-wasm.d.ts # TypeScript definitions
-├── utils/
-│ └── type-guards.ts # Runtime type validation
-└── __tests__/ # Comprehensive test suite
-```
-
-## Quick Start
-
-### Step 1: Copy Files to Your Project
-
-```bash
-# In your Megaport Portal project
-mkdir -p components/megaport-cli
-mkdir -p composables/megaport-cli
-mkdir -p types/megaport-cli
-mkdir -p public/wasm
-
-# Copy the integration files
-cp frontend-integration/components/* components/megaport-cli/
-cp frontend-integration/composables/* composables/megaport-cli/
-cp frontend-integration/types/* types/megaport-cli/
-cp frontend-integration/utils/* utils/megaport-cli/
-
-# Build the WASM artifacts (writes web/megaport.wasm + web/wasm_exec.js)
-./wasm.sh
-
-# Copy WASM files to public directory
-cp web/megaport.wasm public/wasm/
-cp web/wasm_exec.js public/wasm/
-```
-
-### 2. Install Dependencies
-
-```bash
-npm install xterm @xterm/addon-fit @xterm/addon-web-links
-```
-
-### 3. Use the Component
-
-```vue
-
-
-
-
-
-
-
-```
-
-## Authentication
-
-The CLI uses in-memory credentials (no localStorage) and integrates with your existing portal auth.
-
-### Integration Pattern
-
-```typescript
-// In your auth middleware or store
-import { useMegaportWASM } from '~/composables/megaport-cli/useMegaportWASM';
-
-// After user logs in via portal
-const { setAuth } = useMegaportWASM();
-
-onUserLogin((credentials) => {
- setAuth(
- credentials.accessKey,
- credentials.secretKey,
- credentials.environment // 'production', 'staging', or 'development'
- );
-});
-
-// On logout
-onUserLogout(() => {
- const { clearAuth } = useMegaportWASM();
- clearAuth();
-});
-```
-
-### Security
-
-**Important:** Both Access Key and Secret Key are sensitive:
-
-- Use `type="password"` for both input fields
-- Never log credentials
-- Call `clearAuth()` on logout
-- Use HTTPS in production
-
-## Architecture
-
-```
-┌─────────────────────────────────────────────────────────┐
-│ Megaport Portal (Vue 3) │
-│ │
-│ ┌──────────────────────────────────────────────────┐ │
-│ │ Your Portal Components │ │
-│ │ (Dashboard, Resources, Settings, etc.) │ │
-│ └───────────────────┬──────────────────────────────┘ │
-│ │ │
-│ ▼ │
-│ ┌──────────────────────────────────────────────────┐ │
-│ │ MegaportTerminal.vue │ │
-│ │ (Reusable CLI Terminal Component) │ │
-│ └───────────────────┬──────────────────────────────┘ │
-│ │ │
-│ ▼ │
-│ ┌──────────────────────────────────────────────────┐ │
-│ │ useMegaportWASM() Composable │ │
-│ │ - WASM initialization │ │
-│ │ - Command execution │ │
-│ │ - Auth management │ │
-│ │ - Error handling │ │
-│ └───────────────────┬──────────────────────────────┘ │
-│ │ │
-│ ▼ │
-│ ┌──────────────────────────────────────────────────┐ │
-│ │ Browser WebAssembly Runtime │ │
-│ │ ┌────────────────────────────────────────────┐ │ │
-│ │ │ megaport.wasm (Go WASM Binary) │ │ │
-│ │ │ - Browser-compatible subset of the CLI │ │ │
-│ │ │ - Megaport API integration │ │ │
-│ │ │ - Resource modules: ports, vxc, mcr, mve, │ │ │
-│ │ │ locations, partners, servicekeys │ │ │
-│ │ └────────────────────────────────────────────┘ │ │
-│ └──────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────┘
- │
- ▼
- ┌──────────────────────┐
- │ Megaport API │
- │ (REST endpoints) │
- └──────────────────────┘
-```
-
-## Output Streaming
-
-Command narrative (progress lines, echoes, warnings, validation errors) streams
-to the host as the command runs, instead of arriving only when it completes.
-Register a handler with `registerOutputHandler(callback)`; the callback is
-invoked with each output chunk as it is written.
-
-```typescript
-const { registerOutputHandler } = useMegaportWASM();
-
-registerOutputHandler((chunk) => {
- // Chunks use `\n` line endings; xterm needs `\r\n`.
- terminal.write(chunk.replace(/\n/g, '\r\n'));
-});
-```
-
-**Completion contract (avoid double-rendering).** When an output handler is
-registered:
-
-- Narrative output is delivered live through the handler and is **not** repeated
- in the `execute()` result.
-- The result's `output` then carries **only** structured document output
- (JSON/CSV/XML/table), or is empty when the command produced only streamed
- narrative.
-- So render the streamed chunks as they arrive, and render `result.output`
- (the structured document) once at completion. Do not render both for the same
- content.
-
-Exception: if the handler throws or delivers nothing, the WASM side disables
-streaming for the rest of that command and `result.output` falls back to the
-full captured narrative, so already-streamed chunks may appear there too. This
-keeps output from being lost when a handler misbehaves.
-
-When no handler is registered, `result.output` falls back to the full captured
-output at completion, preserving the original non-streaming behavior.
-
-`MegaportTerminal.vue` implements this pattern end-to-end.
-
-## Integration Examples
-
-### Admin CLI Page
-
-```vue
-
-
-
-
-
-
-
-
-
-```
-
-### Dashboard Actions
-
-```vue
-
-
-
-
-
-
-
-
-```
-
-### Resource Actions
-
-```vue
-
-
-
-
-
-
-
-
-
-
-
-```
-
-## Telemetry
-
-Track CLI usage:
-
-```typescript
-const { execute } = useMegaportWASM({
- onTelemetry: (event) => {
- // Send to your analytics platform
- analytics.track(event.type, {
- timestamp: event.timestamp,
- duration: event.duration,
- ...event.metadata,
- });
-
- // Monitor for errors
- if (event.type.endsWith('_error')) {
- errorTracking.captureEvent({
- message: event.metadata?.error,
- context: { command: event.metadata?.command },
- });
- }
-
- // Performance monitoring
- if (event.duration && event.duration > 5000) {
- console.warn(`Slow command: ${event.type} took ${event.duration}ms`);
- }
- },
-});
-```
-
-**Events:**
-
-- Init: `wasm_init_start`, `wasm_init_success`, `wasm_init_error`
-- Commands: `command_execute_start`, `command_execute_success`, `command_execute_error`
-- Auth: `auth_set`, `auth_clear`
-- UI: `spinner_start`, `spinner_stop`
-
-## Testing
-
-The integration includes comprehensive tests you can run:
-
-```bash
-cd frontend-integration
-npm test # Run all tests
-npm run test:coverage # Run with coverage report
-npm run test:ui # Interactive test UI
-```
-
-Tests cover component lifecycle, WASM initialization, command execution, auth, telemetry, type guards, and error handling.
-
-## Configuration
-
-### Nuxt 3 Configuration
-
-Update your `nuxt.config.ts`:
-
-```typescript
-export default defineNuxtConfig({
- vite: {
- optimizeDeps: {
- exclude: ['xterm', '@xterm/addon-fit', '@xterm/addon-web-links'],
- },
- server: {
- fs: {
- allow: ['..'], // If WASM files are outside public/
- },
- },
- },
-
- // For production builds
- nitro: {
- compressPublicAssets: true,
- publicAssets: [
- {
- dir: 'public/wasm',
- maxAge: 60 * 60 * 24 * 365, // Cache WASM for 1 year
- },
- ],
- },
-});
-```
-
-### TypeScript Configuration
-
-Ensure your `tsconfig.json` includes:
-
-```json
-{
- "compilerOptions": {
- "types": ["vite/client"],
- "moduleResolution": "bundler"
- },
- "include": ["types/**/*", "components/**/*", "composables/**/*"]
-}
-```
-
-## Error Handling
-
-The integration includes robust error handling:
-
-```typescript
-const { execute, error, isReady } = useMegaportWASM({
- maxRetries: 3, // Retry failed init 3 times
- retryDelay: 1000, // Start with 1s delay (exponential backoff)
- initTimeout: 30000, // 30s timeout for initialization
-});
-
-// Check for initialization errors
-watchEffect(() => {
- if (error.value) {
- console.error('WASM initialization failed:', error.value);
- showErrorNotification({
- title: 'CLI Unavailable',
- message: 'The CLI terminal could not be loaded. Please refresh the page.',
- });
- }
-});
-
-// Handle command errors
-try {
- const result = await execute('ports list');
- if (result.error) {
- console.error('Command failed:', result.error);
- showErrorNotification({
- title: 'Command Failed',
- message: result.error,
- });
- }
-} catch (err) {
- console.error('Execution error:', err);
-}
-```
-
-## Performance
-
-### 1. Lazy Loading
-
-Load WASM only when needed:
-
-```vue
-
-
-
-
-
-
-
-
-
-```
-
-### Service Worker Caching
-
-```typescript
-// sw.js or your service worker
-workbox.precaching.precacheAndRoute([
- { url: '/wasm/megaport.wasm', revision: 'v1.0.0' },
- { url: '/wasm/wasm_exec.js', revision: 'v1.0.0' },
-]);
-```
-
-### CDN Distribution
-
-```vue
-
-```
-
-## Troubleshooting
-
-**WASM fails to load**
-
-```typescript
-// Enable debug mode
-const { execute, error } = useMegaportWASM({ debug: true });
-
-// Check browser console for detailed logs
-// Verify WASM files are accessible: http://localhost:3000/wasm/megaport.wasm
-```
-
-**Commands return no output**
-
-```typescript
-// Ensure auth is set
-const { setAuth, getAuthInfo } = useMegaportWASM();
-setAuth(accessKey, secretKey, 'production');
-
-// Check auth status
-console.log(getAuthInfo());
-```
-
-**TypeScript errors**
-
-```bash
-npm run type-check
-# Ensure type definitions are in tsconfig.json: "include": ["types/**/*"]
-```
diff --git a/frontend-integration/README.md b/frontend-integration/README.md
deleted file mode 100644
index 84bad8b2..00000000
--- a/frontend-integration/README.md
+++ /dev/null
@@ -1,528 +0,0 @@
-# Megaport CLI WebAssembly - Vue 3 Integration Guide
-
-## 🎯 Overview
-
-This package provides Vue 3 + Vite integration for the Megaport CLI WebAssembly module. It's designed specifically for integration into the **Megaport Portal** (Vue 3 + Nuxt 3 + Vite stack).
-
-## 📦 Package Contents
-
-```
-frontend-integration/
-├── types/
-│ └── megaport-wasm.d.ts # TypeScript definitions
-├── composables/
-│ └── useMegaportWASM.ts # Vue composable for WASM
-├── components/
-│ └── MegaportTerminal.vue # Terminal component with xterm.js
-├── utils/
-│ └── type-guards.ts # Runtime type validation
-├── demo/
-│ ├── App.vue # Demo application
-│ └── main.ts # Demo entry point
-├── package.json
-├── vite.config.ts
-├── tsconfig.json
-└── README.md (this file)
-```
-
-## 🚀 Quick Start
-
-### 1. Installation
-
-```bash
-npm install xterm xterm-addon-fit xterm-addon-web-links
-```
-
-### 2. Copy WASM Files
-
-Copy these files to your `public/` directory:
-
-```bash
-# From the CLI build output
-cp dist/megaport.wasm public/
-cp dist/wasm_exec.js public/
-```
-
-### 3. Basic Usage in Vue 3
-
-```vue
-
-