mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-10-25 05:53:57 +00:00
fix(pr4-review): address PR review issues and fix nightly build
- Fix HTTP-Referer URLs to point to DavinciDreams/Morse-Code - Update src/package.json repository and homepage URLs - Replace WeakRef<any>/setProvider(any) with typed TelemetryPropertiesProvider interface - Remove dead AbortController boilerplate from RetryQueue.retryRequest - Fix WebAuthService.initialize() to emit auth-state-changed event (fixes webview spinner) - Fix nightly esbuild PKG_NAME to match stable so commands resolve correctly - Fix .gitignore corruption (remove backtick-nnul, add proper 'nul' entry) - Update .roo-hooks.json.example branding to Morse Code - Update all stale test assertions (HTTP-Referer, X-Title, User-Agent) - Add docs/cloud-backend.md — implementation plan for future cloud feature branch - Add scripts/build-pr.js — PR test build tool with nightly slot support - Update scripts/install-vsix.js branding Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
11b0bdef9d
commit
272a6acfed
19 changed files with 396 additions and 83 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -55,4 +55,6 @@ qdrant_storage/
|
|||
plans/
|
||||
|
||||
roo-cli-*.tar.gz*
|
||||
`nnul
|
||||
|
||||
# Windows null device artifact
|
||||
nul
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_comment": "Example hooks configuration file for Roo Code. Rename to .roo-hooks.json to use.",
|
||||
"_comment": "Example hooks configuration file for Morse Code. Rename to .roo-hooks.json to use.",
|
||||
"_comment2": "Hooks are executed before (PreCompact) and after (PostCompact) context condensation.",
|
||||
"_comment3": "Each hook can be a command (shell command) or http (HTTP POST request).",
|
||||
"PreCompact": [
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ async function main() {
|
|||
sourcesContent: false,
|
||||
platform: "node",
|
||||
define: {
|
||||
"process.env.PKG_NAME": '"roo-code-nightly"',
|
||||
"process.env.PKG_NAME": '"morse-code"',
|
||||
"process.env.PKG_VERSION": `"${overrideJson.version}"`,
|
||||
"process.env.PKG_OUTPUT_CHANNEL": '"Roo-Code-Nightly"',
|
||||
"process.env.PKG_OUTPUT_CHANNEL": '"Morse-Code-Nightly"',
|
||||
...(gitSha ? { "process.env.PKG_SHA": `"${gitSha}"` } : {}),
|
||||
},
|
||||
}
|
||||
|
|
|
|||
186
docs/cloud-backend.md
Normal file
186
docs/cloud-backend.md
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
# Morse Code Cloud Backend — Implementation Plan
|
||||
|
||||
**Status:** Planned — future feature branch (`feature/morse-cloud-backend`)
|
||||
|
||||
The extension's cloud package (`packages/cloud/`) was disabled in the standalone fork (PR #4).
|
||||
This document sketches what's needed to re-enable it against a Morse Code backend.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
| Item | Status |
|
||||
| ----------------------------------- | ----------------------------------------------- |
|
||||
| Clerk account | ✓ Done |
|
||||
| `CLERK_BASE_URL` in .env | ✓ Done (`closing-mantis-16.clerk.accounts.dev`) |
|
||||
| Restore stubbed cloud code from git | Pending |
|
||||
| Morse Code backend deployed | Pending |
|
||||
| Sign-in landing page | Pending |
|
||||
|
||||
---
|
||||
|
||||
## Step 1 — Restore stubbed cloud code
|
||||
|
||||
Three files were gutted in PR #4 and need to be restored from git history:
|
||||
|
||||
```bash
|
||||
git show 2fc779842^:packages/cloud/src/WebAuthService.ts > packages/cloud/src/WebAuthService.ts
|
||||
git show 2fc779842^:packages/cloud/src/TelemetryClient.ts > packages/cloud/src/TelemetryClient.ts
|
||||
git show 2fc779842^:packages/cloud/src/retry-queue/RetryQueue.ts > packages/cloud/src/retry-queue/RetryQueue.ts
|
||||
```
|
||||
|
||||
Then update `packages/cloud/src/config.ts` to point at the Morse Code backend:
|
||||
|
||||
```ts
|
||||
export const PRODUCTION_CLERK_BASE_URL = "https://closing-mantis-16.clerk.accounts.dev"
|
||||
export const PRODUCTION_ROO_CODE_API_URL = "https://api.morse-code.com"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2 — Backend API (9 endpoints)
|
||||
|
||||
The extension calls two base URLs — Clerk (auth) and the Morse Code API (everything else).
|
||||
|
||||
### Clerk handles automatically (no backend code needed)
|
||||
|
||||
| Method | Path | Purpose |
|
||||
| ------ | --------------------------------- | --------------------------- |
|
||||
| `POST` | `/v1/client/sign_ins` | Exchange ticket → sessionId |
|
||||
| `POST` | `/v1/client/sessions/{id}/tokens` | sessionId → JWT |
|
||||
| `GET` | `/v1/me` | Current user info |
|
||||
| `GET` | `/v1/me/organization_memberships` | Org list |
|
||||
| `POST` | `/v1/client/sessions/{id}/remove` | Logout |
|
||||
|
||||
### Morse Code API to build
|
||||
|
||||
#### Auth flow glue
|
||||
|
||||
```
|
||||
GET /extension/sign-in?state={csrf}
|
||||
```
|
||||
|
||||
Landing page that starts the Clerk OAuth flow and redirects back to the extension
|
||||
with `vscode://morse-code/auth?code={ticket}&state={csrf}`.
|
||||
|
||||
#### Settings
|
||||
|
||||
```
|
||||
GET /api/extension-settings
|
||||
Authorization: Bearer {jwt}
|
||||
→ { organization: OrganizationSettings, user: UserSettingsData }
|
||||
|
||||
PATCH /api/user-settings
|
||||
Authorization: Bearer {jwt}
|
||||
Body: { settings: Partial<UserSettingsConfig>, version?: number }
|
||||
→ UserSettingsData
|
||||
```
|
||||
|
||||
`OrganizationSettings` shape (from `packages/types/src/`):
|
||||
|
||||
```ts
|
||||
{
|
||||
version: number
|
||||
cloudSettings: { taskSyncEnabled: boolean }
|
||||
defaultSettings: GlobalSettings
|
||||
allowList: string[] // allowed shell commands
|
||||
features: Record<string, boolean>
|
||||
hiddenMcps: string[]
|
||||
}
|
||||
```
|
||||
|
||||
#### Telemetry
|
||||
|
||||
```
|
||||
POST /api/events
|
||||
Authorization: Bearer {jwt}
|
||||
Body: { type: TelemetryEventName, properties: Record<string, unknown> }
|
||||
|
||||
POST /api/events/backfill
|
||||
Authorization: Bearer {jwt}
|
||||
Body: FormData { taskId, properties (JSON string), file (JSON array of ClineMessage[]) }
|
||||
```
|
||||
|
||||
Return `429` with `Retry-After` header to rate-limit — the client will pause and retry automatically.
|
||||
|
||||
#### Task sharing
|
||||
|
||||
```
|
||||
POST /api/extension/share
|
||||
Authorization: Bearer {jwt}
|
||||
Body: { taskId: string, visibility: "organization" | "public" }
|
||||
→ { success: boolean, shareUrl?: string, isNewShare?: boolean, manageUrl?: string }
|
||||
```
|
||||
|
||||
Return `404` if `taskId` is unknown — the extension will automatically backfill the message
|
||||
history via `/api/events/backfill` and retry.
|
||||
|
||||
#### Optional / lower priority
|
||||
|
||||
```
|
||||
GET /api/extension/credit-balance
|
||||
→ { balance: number }
|
||||
|
||||
GET /api/extension/bridge/config
|
||||
→ { userId: string, socketBridgeUrl: string, token: string }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3 — JWT verification
|
||||
|
||||
All `/api/*` routes must verify the Clerk JWT. Use the Clerk backend SDK:
|
||||
|
||||
```ts
|
||||
import { createClerkClient } from "@clerk/backend"
|
||||
|
||||
const clerk = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })
|
||||
|
||||
async function verifyToken(req) {
|
||||
const token = req.headers.authorization?.replace("Bearer ", "")
|
||||
const payload = await clerk.verifyToken(token)
|
||||
return { userId: payload.sub, orgId: payload.org_id }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 4 — Sign-in landing page
|
||||
|
||||
The simplest approach is a single Next.js route (or Express endpoint):
|
||||
|
||||
```
|
||||
/extension/sign-in?state={csrf}&landingPageSlug={slug}
|
||||
```
|
||||
|
||||
1. Start Clerk sign-in with `strategy: "oauth_google"` (or show a sign-in form)
|
||||
2. On success, get the one-time ticket from Clerk
|
||||
3. Redirect to `vscode://morse-code/auth?code={ticket}&state={csrf}`
|
||||
|
||||
The extension's `handleCallback()` takes it from there.
|
||||
|
||||
---
|
||||
|
||||
## Tech stack recommendation
|
||||
|
||||
| Layer | Recommendation |
|
||||
| -------------- | --------------------------------------------------------- |
|
||||
| Runtime | Node.js (Bun or Express) — Clerk SDK is Node-first |
|
||||
| Auth | Clerk (already have account) |
|
||||
| Database | Postgres (for settings, task shares, telemetry) |
|
||||
| Hosting | Fly.io / Railway / Vercel (easy Postgres integration) |
|
||||
| Telemetry sink | Write to DB initially; swap for ClickHouse later at scale |
|
||||
|
||||
---
|
||||
|
||||
## Environment variables summary
|
||||
|
||||
```bash
|
||||
# Extension (.env at repo root)
|
||||
CLERK_BASE_URL=https://closing-mantis-16.clerk.accounts.dev
|
||||
ROO_CODE_API_URL=https://api.morse-code.com
|
||||
|
||||
# Backend server
|
||||
CLERK_SECRET_KEY=sk_test_...
|
||||
DATABASE_URL=postgres://...
|
||||
```
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
"clean": "turbo clean --log-order grouped --output-logs new-only && rimraf dist out bin .vite-port .turbo",
|
||||
"install:vsix": "pnpm install --frozen-lockfile && pnpm clean && pnpm vsix && node scripts/install-vsix.js",
|
||||
"install:vsix:nightly": "pnpm install --frozen-lockfile && pnpm clean && pnpm vsix:nightly && node scripts/install-vsix.js --nightly",
|
||||
"test:pr": "node scripts/build-pr.js",
|
||||
"code-server:install": "node scripts/code-server.js",
|
||||
"changeset:version": "cp CHANGELOG.md src/CHANGELOG.md && changeset version && cp -vf src/CHANGELOG.md .",
|
||||
"knip": "knip --include files",
|
||||
|
|
|
|||
|
|
@ -8,9 +8,12 @@ import {
|
|||
TelemetryEventSubscription,
|
||||
} from "@roo-code/types"
|
||||
|
||||
interface TelemetryPropertiesProvider {
|
||||
getTelemetryProperties(): Promise<TelemetryEvent["properties"]>
|
||||
}
|
||||
|
||||
abstract class BaseTelemetryClient implements TelemetryClient {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
protected providerRef: WeakRef<any> | null = null
|
||||
protected providerRef: WeakRef<TelemetryPropertiesProvider> | null = null
|
||||
protected telemetryEnabled: boolean = false
|
||||
|
||||
constructor(
|
||||
|
|
@ -67,8 +70,7 @@ abstract class BaseTelemetryClient implements TelemetryClient {
|
|||
|
||||
public async captureException(_error: Error, _additionalProperties?: Record<string, unknown>): Promise<void> {}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public setProvider(provider: any): void {
|
||||
public setProvider(provider: TelemetryPropertiesProvider): void {
|
||||
this.providerRef = new WeakRef(provider)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@ export class WebAuthService extends EventEmitter<AuthServiceEvents> implements A
|
|||
}
|
||||
|
||||
// Start in logged-out state — no credentials loading, no timer, no HTTP calls.
|
||||
const previousState = this.state
|
||||
this.state = "logged-out"
|
||||
this.emit("auth-state-changed", { state: this.state, previousState })
|
||||
this.log("[auth] Cloud features disabled — initialized in logged-out state")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { EventEmitter } from "events"
|
||||
import { EventEmitter } from "events"
|
||||
import type { ExtensionContext } from "vscode"
|
||||
import type { QueuedRequest, QueueStats, RetryQueueConfig, RetryQueueEvents } from "./types.js"
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ export class RetryQueue extends EventEmitter<RetryQueueEvents> {
|
|||
}
|
||||
}
|
||||
|
||||
// Cloud features disabled — enqueue is a no-op to prevent any HTTP calls
|
||||
// Cloud features disabled - enqueue is a no-op to prevent any HTTP calls
|
||||
public async enqueue(
|
||||
_url: string,
|
||||
_options: RequestInit,
|
||||
|
|
@ -173,47 +173,9 @@ export class RetryQueue extends EventEmitter<RetryQueueEvents> {
|
|||
}
|
||||
}
|
||||
|
||||
private async retryRequest(request: QueuedRequest): Promise<Response> {
|
||||
this.log(`[RetryQueue] Retrying request: ${request.url}`)
|
||||
|
||||
// Cloud features disabled — skip actual HTTP fetch, return fake success
|
||||
this.log(`[RetryQueue] Cloud features disabled - skipping request to ${request.url}`)
|
||||
|
||||
const controller = new AbortController()
|
||||
const timeoutId = setTimeout(() => controller.abort(), this.config.requestTimeout)
|
||||
|
||||
try {
|
||||
// Return a fake successful response instead of making a real HTTP call
|
||||
const response = new Response(JSON.stringify({ success: true }), {
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
})
|
||||
|
||||
clearTimeout(timeoutId)
|
||||
|
||||
// Check for error status codes that should trigger retry
|
||||
if (!response.ok) {
|
||||
// Handle different status codes appropriately
|
||||
if (response.status >= 500) {
|
||||
// Server errors (5xx) should be retried
|
||||
throw new Error(`Server error: ${response.status} ${response.statusText}`)
|
||||
} else if (response.status === 429) {
|
||||
// Rate limiting - return response to let caller handle Retry-After
|
||||
return response
|
||||
} else if (response.status >= 400 && response.status < 500) {
|
||||
// Client errors (4xx including 401/403) should NOT be retried
|
||||
// These errors indicate problems with the request itself that won't be fixed by retrying
|
||||
this.log(`[RetryQueue] Non-retryable client error ${response.status}, removing from queue`)
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
return response
|
||||
} catch (error) {
|
||||
clearTimeout(timeoutId)
|
||||
throw error
|
||||
}
|
||||
private async retryRequest(_request: QueuedRequest): Promise<Response> {
|
||||
// Cloud features disabled - retries never execute
|
||||
throw new Error("Cloud features disabled")
|
||||
}
|
||||
|
||||
private startRetryTimer(): void {
|
||||
|
|
|
|||
158
scripts/build-pr.js
Normal file
158
scripts/build-pr.js
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* Build and install a PR-stamped VSIX for local testing.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/build-pr.js --pr=4 # stable slot: morse-code-3.52.1-pr.4.vsix
|
||||
* node scripts/build-pr.js --pr=4 --nightly # nightly slot: morse-code-nightly-0.4.0.vsix (coexists with stable)
|
||||
* node scripts/build-pr.js --pr=4 -y # non-interactive
|
||||
* node scripts/build-pr.js --pr=4 --editor=cursor
|
||||
* node scripts/build-pr.js --pr=4 --no-install # build only, skip install
|
||||
*
|
||||
* --nightly installs into the separate morse-code-nightly extension slot so it
|
||||
* coexists with your stable morse-code build. Use this during PR testing.
|
||||
*/
|
||||
|
||||
const { execSync } = require("child_process")
|
||||
const fs = require("fs")
|
||||
const path = require("path")
|
||||
const readline = require("readline")
|
||||
|
||||
// ── Args ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
const args = process.argv.slice(2)
|
||||
|
||||
const prArg = args.find((a) => a.startsWith("--pr="))
|
||||
if (!prArg) {
|
||||
console.error(
|
||||
"Usage: node scripts/build-pr.js --pr=<number> [--nightly] [-y] [--editor=code|cursor] [--no-install]",
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const prNumber = prArg.split("=")[1]
|
||||
const isNightly = args.includes("--nightly")
|
||||
const autoYes = args.includes("-y")
|
||||
const noInstall = args.includes("--no-install")
|
||||
const editorArg = args.find((a) => a.startsWith("--editor="))
|
||||
const editor = editorArg ? editorArg.split("=")[1] : "code"
|
||||
|
||||
// ── Paths & metadata ──────────────────────────────────────────────────────────
|
||||
|
||||
const stablePkgPath = path.resolve(__dirname, "../src/package.json")
|
||||
const nightlyPkgPath = path.resolve(__dirname, "../apps/vscode-nightly/package.nightly.json")
|
||||
|
||||
const stablePkg = JSON.parse(fs.readFileSync(stablePkgPath, "utf-8"))
|
||||
|
||||
let pkgPath, pkg, prVersion, vsixName, extensionId
|
||||
|
||||
if (isNightly) {
|
||||
const nightlyPkg = JSON.parse(fs.readFileSync(nightlyPkgPath, "utf-8"))
|
||||
pkgPath = nightlyPkgPath
|
||||
pkg = nightlyPkg
|
||||
// Use 0.<pr>.<build> so version increments clearly per PR
|
||||
prVersion = `0.${prNumber}.0`
|
||||
vsixName = `./bin/${nightlyPkg.name}-${prVersion}.vsix`
|
||||
extensionId = `${stablePkg.publisher}.${nightlyPkg.name}`
|
||||
} else {
|
||||
pkgPath = stablePkgPath
|
||||
pkg = stablePkg
|
||||
const baseVersion = stablePkg.version.split("-")[0]
|
||||
prVersion = `${baseVersion}-pr.${prNumber}`
|
||||
vsixName = `./bin/${stablePkg.name}-${prVersion}.vsix`
|
||||
extensionId = `${stablePkg.publisher}.${stablePkg.name}`
|
||||
}
|
||||
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
function patchVersion(version) {
|
||||
const updated = { ...pkg, version }
|
||||
fs.writeFileSync(pkgPath, JSON.stringify(updated, null, "\t") + "\n")
|
||||
}
|
||||
|
||||
function restoreVersion() {
|
||||
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, "\t") + "\n")
|
||||
}
|
||||
|
||||
function run(cmd) {
|
||||
execSync(cmd, { stdio: "inherit", shell: true })
|
||||
}
|
||||
|
||||
// On Windows, the VS Code CLI is code.cmd not code.exe
|
||||
function resolveEditor(name) {
|
||||
if (process.platform !== "win32") return name
|
||||
const { execSync: ex } = require("child_process")
|
||||
try {
|
||||
const p = ex(`where ${name}.cmd 2>nul`, { encoding: "utf8" }).trim().split("\n")[0].trim()
|
||||
if (p) return `"${p}"`
|
||||
} catch {}
|
||||
return name
|
||||
}
|
||||
|
||||
// ── Main ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
async function main() {
|
||||
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
|
||||
const ask = (q) => new Promise((r) => rl.question(q, r))
|
||||
|
||||
const resolvedEditor = resolveEditor(editor)
|
||||
const slot = isNightly ? "nightly (coexists with stable)" : "stable"
|
||||
|
||||
console.log("\nMorse Code - PR Build Tool")
|
||||
console.log("==========================")
|
||||
console.log(` PR: #${prNumber}`)
|
||||
console.log(` Slot: ${slot}`)
|
||||
console.log(` Version: ${pkg.version} -> ${prVersion}`)
|
||||
console.log(` VSIX: ${vsixName}`)
|
||||
if (!noInstall) {
|
||||
console.log(` Editor: ${editor}`)
|
||||
console.log(` Extension: ${extensionId}`)
|
||||
}
|
||||
console.log()
|
||||
|
||||
if (!autoYes) {
|
||||
const answer = await ask("Continue? (y/n): ")
|
||||
if (answer.toLowerCase() !== "y") {
|
||||
console.log("Cancelled.")
|
||||
rl.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
rl.close()
|
||||
|
||||
console.log(`\n-> Patching version to ${prVersion}...`)
|
||||
patchVersion(prVersion)
|
||||
|
||||
try {
|
||||
const buildCmd = isNightly ? "pnpm vsix:nightly" : "pnpm vsix"
|
||||
console.log(`-> Building VSIX (${buildCmd})...`)
|
||||
run(buildCmd)
|
||||
|
||||
console.log(`\nBuilt: ${vsixName}`)
|
||||
|
||||
if (!noInstall) {
|
||||
if (!fs.existsSync(vsixName)) {
|
||||
console.error(`\nVSIX not found at ${vsixName}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log(`-> Installing ${vsixName}...`)
|
||||
run(`${resolvedEditor} --install-extension ${vsixName}`)
|
||||
|
||||
console.log(`\nInstalled PR #${prNumber} build (${prVersion}) into ${slot} slot`)
|
||||
console.log("Restart VS Code to activate the updated extension.\n")
|
||||
}
|
||||
} finally {
|
||||
console.log(`-> Restoring version to ${pkg.version}...`)
|
||||
restoreVersion()
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("\nBuild failed:", err.message)
|
||||
try {
|
||||
restoreVersion()
|
||||
} catch {}
|
||||
process.exit(1)
|
||||
})
|
||||
|
|
@ -49,10 +49,10 @@ async function main() {
|
|||
const extensionId = `${publisher}.${name}`
|
||||
const buildType = isNightly ? "Nightly" : "Regular"
|
||||
|
||||
console.log(`\n🚀 Roo Code VSIX Installer (${buildType})`)
|
||||
console.log(`\n🚀 Morse Code VSIX Installer (${buildType})`)
|
||||
console.log("========================")
|
||||
console.log("\nThis script will:")
|
||||
console.log("1. Uninstall any existing version of the Roo Code extension")
|
||||
console.log("1. Uninstall any existing version of the Morse Code extension")
|
||||
console.log("2. Install the newly built VSIX package")
|
||||
console.log(`\nExtension: ${extensionId}`)
|
||||
console.log(`VSIX file: ${vsixFileName}`)
|
||||
|
|
|
|||
|
|
@ -11,16 +11,16 @@ describe("DEFAULT_HEADERS", () => {
|
|||
})
|
||||
|
||||
it("should have correct HTTP-Referer value", () => {
|
||||
expect(DEFAULT_HEADERS["HTTP-Referer"]).toBe("https://github.com/RooVetGit/Roo-Cline")
|
||||
expect(DEFAULT_HEADERS["HTTP-Referer"]).toBe("https://github.com/DavinciDreams/Morse-Code")
|
||||
})
|
||||
|
||||
it("should have correct X-Title value", () => {
|
||||
expect(DEFAULT_HEADERS["X-Title"]).toBe("Roo Code")
|
||||
expect(DEFAULT_HEADERS["X-Title"]).toBe("Morse Code")
|
||||
})
|
||||
|
||||
it("should have correct User-Agent format", () => {
|
||||
const userAgent = DEFAULT_HEADERS["User-Agent"]
|
||||
expect(userAgent).toBe(`RooCode/${Package.version}`)
|
||||
expect(userAgent).toBe(`MorseCode/${Package.version}`)
|
||||
|
||||
// Verify it follows the tool_name/version pattern
|
||||
expect(userAgent).toMatch(/^[a-zA-Z-]+\/\d+\.\d+\.\d+$/)
|
||||
|
|
@ -28,7 +28,7 @@ describe("DEFAULT_HEADERS", () => {
|
|||
|
||||
it("should have User-Agent with correct tool name", () => {
|
||||
const userAgent = DEFAULT_HEADERS["User-Agent"]
|
||||
expect(userAgent.startsWith("RooCode/")).toBe(true)
|
||||
expect(userAgent.startsWith("MorseCode/")).toBe(true)
|
||||
})
|
||||
|
||||
it("should have User-Agent with semantic version format", () => {
|
||||
|
|
|
|||
|
|
@ -111,9 +111,9 @@ describe("OpenAiHandler", () => {
|
|||
baseURL: expect.any(String),
|
||||
apiKey: expect.any(String),
|
||||
defaultHeaders: {
|
||||
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
|
||||
"X-Title": "Roo Code",
|
||||
"User-Agent": `RooCode/${Package.version}`,
|
||||
"HTTP-Referer": "https://github.com/DavinciDreams/Morse-Code",
|
||||
"X-Title": "Morse Code",
|
||||
"User-Agent": `MorseCode/${Package.version}`,
|
||||
},
|
||||
timeout: expect.any(Number),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -100,9 +100,9 @@ describe("OpenRouterHandler", () => {
|
|||
baseURL: "https://openrouter.ai/api/v1",
|
||||
apiKey: mockOptions.openRouterApiKey,
|
||||
defaultHeaders: {
|
||||
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
|
||||
"X-Title": "Roo Code",
|
||||
"User-Agent": `RooCode/${Package.version}`,
|
||||
"HTTP-Referer": "https://github.com/DavinciDreams/Morse-Code",
|
||||
"X-Title": "Morse Code",
|
||||
"User-Agent": `MorseCode/${Package.version}`,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ describe("RequestyHandler", () => {
|
|||
baseURL: "https://router.requesty.ai/v1",
|
||||
apiKey: mockOptions.requestyApiKey,
|
||||
defaultHeaders: {
|
||||
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
|
||||
"X-Title": "Roo Code",
|
||||
"User-Agent": `RooCode/${Package.version}`,
|
||||
"HTTP-Referer": "https://github.com/DavinciDreams/Morse-Code",
|
||||
"X-Title": "Morse Code",
|
||||
"User-Agent": `MorseCode/${Package.version}`,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
|
@ -73,9 +73,9 @@ describe("RequestyHandler", () => {
|
|||
baseURL: "https://custom.requesty.ai/v1",
|
||||
apiKey: mockOptions.requestyApiKey,
|
||||
defaultHeaders: {
|
||||
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
|
||||
"X-Title": "Roo Code",
|
||||
"User-Agent": `RooCode/${Package.version}`,
|
||||
"HTTP-Referer": "https://github.com/DavinciDreams/Morse-Code",
|
||||
"X-Title": "Morse Code",
|
||||
"User-Agent": `MorseCode/${Package.version}`,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -96,9 +96,9 @@ describe("VercelAiGatewayHandler", () => {
|
|||
baseURL: "https://ai-gateway.vercel.sh/v1",
|
||||
apiKey: mockOptions.vercelAiGatewayApiKey,
|
||||
defaultHeaders: expect.objectContaining({
|
||||
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
|
||||
"X-Title": "Roo Code",
|
||||
"User-Agent": expect.stringContaining("RooCode/"),
|
||||
"HTTP-Referer": "https://github.com/DavinciDreams/Morse-Code",
|
||||
"X-Title": "Morse Code",
|
||||
"User-Agent": expect.stringContaining("MorseCode/"),
|
||||
}),
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Package } from "../../shared/package"
|
||||
|
||||
export const DEFAULT_HEADERS = {
|
||||
"HTTP-Referer": "https://github.com/moo-code/Moo-Code",
|
||||
"X-Title": "Moo Code",
|
||||
"User-Agent": `MooCode/${Package.version}`,
|
||||
"HTTP-Referer": "https://github.com/DavinciDreams/Morse-Code",
|
||||
"X-Title": "Morse Code",
|
||||
"User-Agent": `MorseCode/${Package.version}`,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,8 +70,8 @@ export async function generateImageWithProvider(options: ImageGenerationOptions)
|
|||
headers: {
|
||||
Authorization: `Bearer ${authToken}`,
|
||||
"Content-Type": "application/json",
|
||||
"HTTP-Referer": "https://github.com/moo-code/Moo-Code",
|
||||
"X-Title": "Moo Code",
|
||||
"HTTP-Referer": "https://github.com/DavinciDreams/Morse-Code",
|
||||
"X-Title": "Morse Code",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model,
|
||||
|
|
@ -216,8 +216,8 @@ export async function generateImageWithImagesApi(options: ImagesApiOptions): Pro
|
|||
headers: {
|
||||
Authorization: `Bearer ${authToken}`,
|
||||
"Content-Type": "application/json",
|
||||
"HTTP-Referer": "https://github.com/moo-code/Moo-Code",
|
||||
"X-Title": "Moo Code",
|
||||
"HTTP-Referer": "https://github.com/DavinciDreams/Morse-Code",
|
||||
"X-Title": "Morse Code",
|
||||
},
|
||||
body: JSON.stringify(requestBody),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@
|
|||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DavinciDreams/Roo-Code"
|
||||
"url": "https://github.com/DavinciDreams/Morse-Code"
|
||||
},
|
||||
"homepage": "https://github.com/DavinciDreams/Roo-Code",
|
||||
"homepage": "https://github.com/DavinciDreams/Morse-Code",
|
||||
"categories": [
|
||||
"AI",
|
||||
"Chat",
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@ export class OpenRouterEmbedder implements IEmbedder {
|
|||
baseURL: this.baseUrl,
|
||||
apiKey: apiKey,
|
||||
defaultHeaders: {
|
||||
"HTTP-Referer": "https://github.com/moo-code/Moo-Code",
|
||||
"X-Title": "Moo Code",
|
||||
"HTTP-Referer": "https://github.com/DavinciDreams/Morse-Code",
|
||||
"X-Title": "Morse Code",
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue