Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/sweet-bugs-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"roo-cline": patch
---

Automatically generate .d.ts from zod schemas
10 changes: 9 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,12 @@ else
npx_cmd="npx"
fi

"$npx_cmd" lint-staged
npm run generate-types

if [ -n "$(git diff --name-only src/exports/roo-code.d.ts)" ]; then
echo "Error: There are unstaged changes to roo-code.d.ts after running 'npm run generate-types'."
echo "Please review and stage the changes before committing."
exit 1
fi

"$npx_cmd" lint-staged
2 changes: 1 addition & 1 deletion e2e/src/suite/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type WaitForOptions = {

export const waitFor = (
condition: (() => Promise<boolean>) | (() => boolean),
{ timeout = 30_000, interval = 250 }: WaitForOptions = {},
{ timeout = 60_000, interval = 250 }: WaitForOptions = {},
) => {
let timeoutId: NodeJS.Timeout | undefined = undefined

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,8 @@
"clean:webview": "cd webview-ui && npm run clean",
"clean:e2e": "cd e2e && npm run clean",
"clean:benchmark": "cd benchmark && npm run clean",
"update-contributors": "node scripts/update-contributors.js"
"update-contributors": "node scripts/update-contributors.js",
"generate-types": "tsx scripts/generate-types.mts"
},
"dependencies": {
"@anthropic-ai/bedrock-sdk": "^0.10.2",
Expand Down
26 changes: 26 additions & 0 deletions scripts/generate-types.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import fs from "fs/promises"

import { zodToTs, createTypeAlias, printNode } from "zod-to-ts"
import { $ } from "execa"

import { typeDefinitions } from "../src/schemas"

async function main() {
const types: string[] = [
"// This file is automatically generated by running `npm run generate-types`\n// Do not edit it directly.",
]

for (const { schema, identifier } of typeDefinitions) {
types.push(printNode(createTypeAlias(zodToTs(schema, identifier).node, identifier)))
types.push(`export type { ${identifier} }`)
}

await fs.writeFile("src/exports/types.ts", types.join("\n\n"))

await $`npx tsup src/exports/interface.ts --dts-only -d out`
await fs.copyFile('out/interface.d.ts', 'src/exports/roo-code.d.ts')

await $`npx prettier --write src/exports/types.ts src/exports/roo-code.d.ts`
}

main()
4 changes: 2 additions & 2 deletions src/core/Cline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ import pWaitFor from "p-wait-for"
import getFolderSize from "get-folder-size"
import { serializeError } from "serialize-error"
import * as vscode from "vscode"
import { isPathOutsideWorkspace } from "../utils/pathUtils"

import { TokenUsage } from "../exports/roo-code"
import { TokenUsage } from "../schemas"
import { ApiHandler, buildApiHandler } from "../api"
import { ApiStream } from "../api/transform/stream"
import { DIFF_VIEW_URI_SCHEME, DiffViewProvider } from "../integrations/editor/DiffViewProvider"
Expand Down Expand Up @@ -65,6 +64,7 @@ import { defaultModeSlug, getModeBySlug, getFullModeDetails } from "../shared/mo
import { EXPERIMENT_IDS, experiments as Experiments, ExperimentId } from "../shared/experiments"
import { calculateApiCostAnthropic } from "../utils/cost"
import { fileExistsAtPath } from "../utils/fs"
import { isPathOutsideWorkspace } from "../utils/pathUtils"
import { arePathsEqual, getReadablePath } from "../utils/path"
import { parseMentions } from "./mentions"
import { RooIgnoreController } from "./ignore/RooIgnoreController"
Expand Down
11 changes: 6 additions & 5 deletions src/core/__tests__/mode-validator.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Mode, isToolAllowedForMode, getModeConfig, modes } from "../../shared/modes"
import { validateToolUse } from "../mode-validator"
import { isToolAllowedForMode, getModeConfig, modes, ModeConfig } from "../../shared/modes"
import { TOOL_GROUPS } from "../../shared/tool-groups"
import { validateToolUse } from "../mode-validator"

const [codeMode, architectMode, askMode] = modes.map((mode) => mode.slug)

describe("mode-validator", () => {
Expand Down Expand Up @@ -49,7 +50,7 @@ describe("mode-validator", () => {

describe("custom modes", () => {
it("allows tools from custom mode configuration", () => {
const customModes = [
const customModes: ModeConfig[] = [
{
slug: "custom-mode",
name: "Custom Mode",
Expand All @@ -65,7 +66,7 @@ describe("mode-validator", () => {
})

it("allows custom mode to override built-in mode", () => {
const customModes = [
const customModes: ModeConfig[] = [
{
slug: codeMode,
name: "Custom Code Mode",
Expand All @@ -80,7 +81,7 @@ describe("mode-validator", () => {
})

it("respects tool requirements in custom modes", () => {
const customModes = [
const customModes: ModeConfig[] = [
{
slug: "custom-mode",
name: "Custom Mode",
Expand Down
34 changes: 18 additions & 16 deletions src/core/config/ContextProxy.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import * as vscode from "vscode"

import { logger } from "../../utils/logging"
import type {
ProviderSettings,
RooCodeSettings,
RooCodeSettingsKey,
GlobalStateKey,
GlobalState,
SecretStateKey,
SecretState,
GlobalSettings,
} from "../../exports/roo-code"
import {
PROVIDER_SETTINGS_KEYS,
GLOBAL_STATE_KEYS,
ProviderSettings,
providerSettingsSchema,
GlobalSettings,
globalSettingsSchema,
RooCodeSettings,
SECRET_STATE_KEYS,
SecretState,
isSecretStateKey,
isPassThroughStateKey,
globalSettingsSchema,
providerSettingsSchema,
} from "../../shared/globalState"
GLOBAL_STATE_KEYS,
GlobalState,
} from "../../schemas"
import { logger } from "../../utils/logging"

type GlobalStateKey = keyof GlobalState
type SecretStateKey = keyof SecretState
type RooCodeSettingsKey = keyof RooCodeSettings

const PASS_THROUGH_STATE_KEYS = ["taskHistory"]

export const isPassThroughStateKey = (key: string) => PASS_THROUGH_STATE_KEYS.includes(key)

const globalSettingsExportSchema = globalSettingsSchema.omit({
taskHistory: true,
Expand Down
3 changes: 1 addition & 2 deletions src/core/config/ProviderSettingsManager.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { ExtensionContext } from "vscode"
import { z } from "zod"

import { providerSettingsSchema } from "../../shared/globalState"
import { providerSettingsSchema, ApiConfigMeta } from "../../schemas"
import { Mode } from "../../shared/modes"
import { ApiConfigMeta } from "../../shared/ExtensionMessage"

const providerSettingsWithIdSchema = providerSettingsSchema.extend({ id: z.string().optional() })

Expand Down
5 changes: 1 addition & 4 deletions src/core/config/__tests__/ContextProxy.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
// npx jest src/core/config/__tests__/ContextProxy.test.ts

import fs from "fs/promises"

import * as vscode from "vscode"
import { ContextProxy } from "../ContextProxy"

import { logger } from "../../../utils/logging"
import { GLOBAL_STATE_KEYS, SECRET_STATE_KEYS } from "../../../shared/globalState"
import { GLOBAL_STATE_KEYS, SECRET_STATE_KEYS } from "../../../schemas"

jest.mock("vscode", () => ({
Uri: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { ExtensionContext } from "vscode"

import { ProviderSettings } from "../../../exports/roo-code"
import { ProviderSettings } from "../../../schemas"
import { ProviderSettingsManager, ProviderProfiles } from "../ProviderSettingsManager"

// Mock VSCode ExtensionContext
Expand Down
2 changes: 1 addition & 1 deletion src/core/config/__tests__/importExport.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import os from "os"

import * as vscode from "vscode"

import { ProviderName } from "../../../schemas"
import { importSettings, exportSettings } from "../importExport"
import { ProviderSettingsManager } from "../ProviderSettingsManager"
import { ContextProxy } from "../ContextProxy"
import { ProviderName } from "../../../exports/roo-code"

// Mock VSCode modules
jest.mock("vscode", () => ({
Expand Down
2 changes: 1 addition & 1 deletion src/core/config/importExport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import fs from "fs/promises"
import * as vscode from "vscode"
import { z } from "zod"

import { globalSettingsSchema } from "../../shared/globalState"
import { globalSettingsSchema } from "../../schemas"
import { ProviderSettingsManager, providerProfilesSchema } from "./ProviderSettingsManager"
import { ContextProxy } from "./ContextProxy"

Expand Down
2 changes: 1 addition & 1 deletion src/core/mode-validator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Mode, isToolAllowedForMode, getModeConfig, ModeConfig, FileRestrictionError } from "../shared/modes"
import { Mode, isToolAllowedForMode, ModeConfig } from "../shared/modes"
import { ToolName } from "../shared/tool-groups"

export { isToolAllowedForMode }
Expand Down
15 changes: 6 additions & 9 deletions src/core/prompts/__tests__/system.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import * as vscode from "vscode"

import { SYSTEM_PROMPT } from "../system"
import { McpHub } from "../../../services/mcp/McpHub"
import { McpServer } from "../../../shared/mcp"
import { ClineProvider } from "../../../core/webview/ClineProvider"
import { SearchReplaceDiffStrategy } from "../../../core/diff/strategies/search-replace"
import * as vscode from "vscode"
import fs from "fs/promises"
import os from "os"
import { defaultModeSlug, modes, Mode, isToolAllowedForMode } from "../../../shared/modes"
// Import path utils to get access to toPosix string extension
import "../../../utils/path"
import { defaultModeSlug, modes, Mode, ModeConfig } from "../../../shared/modes"
import "../../../utils/path" // Import path utils to get access to toPosix string extension.
import { addCustomInstructions } from "../sections/custom-instructions"
import * as modesSection from "../sections/modes"
import { EXPERIMENT_IDS } from "../../../shared/experiments"

// Mock the sections
Expand Down Expand Up @@ -386,7 +382,8 @@ describe("SYSTEM_PROMPT", () => {

it("should include custom mode role definition at top and instructions at bottom", async () => {
const modeCustomInstructions = "Custom mode instructions"
const customModes = [

const customModes: ModeConfig[] = [
{
slug: "custom-mode",
name: "Custom Mode",
Expand Down
3 changes: 1 addition & 2 deletions src/core/prompts/sections/custom-instructions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import fs from "fs/promises"
import path from "path"

import { LANGUAGES } from "../../../shared/language"
import { isLanguage } from "../../../shared/globalState"
import { LANGUAGES, isLanguage } from "../../../shared/language"

async function safeReadFile(filePath: string): Promise<string> {
try {
Expand Down
16 changes: 8 additions & 8 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import * as vscode from "vscode"
import {
CheckpointStorage,
GlobalState,
SecretState,
Language,
ProviderSettings,
RooCodeSettings,
GlobalStateKey,
SecretStateKey,
} from "../../exports/roo-code"
ApiConfigMeta,
} from "../../schemas"
import { changeLanguage, t } from "../../i18n"
import { setPanel } from "../../activate/registerCommands"
import {
Expand All @@ -35,7 +35,7 @@ import { findLast } from "../../shared/array"
import { supportPrompt } from "../../shared/support-prompt"
import { GlobalFileNames } from "../../shared/globalFileNames"
import { HistoryItem } from "../../shared/HistoryItem"
import { ApiConfigMeta, ExtensionMessage } from "../../shared/ExtensionMessage"
import { ExtensionMessage } from "../../shared/ExtensionMessage"
import { checkoutDiffPayloadSchema, checkoutRestorePayloadSchema, WebviewMessage } from "../../shared/WebviewMessage"
import { Mode, PromptComponent, defaultModeSlug, getModeBySlug, getGroupName } from "../../shared/modes"
import { checkExistKey } from "../../shared/checkExistApiConfig"
Expand Down Expand Up @@ -2804,21 +2804,21 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements

// global

public async updateGlobalState<K extends GlobalStateKey>(key: K, value: GlobalState[K]) {
public async updateGlobalState<K extends keyof GlobalState>(key: K, value: GlobalState[K]) {
await this.contextProxy.setValue(key, value)
}

public getGlobalState<K extends GlobalStateKey>(key: K) {
public getGlobalState<K extends keyof GlobalState>(key: K) {
return this.contextProxy.getValue(key)
}

// secrets

public async storeSecret(key: SecretStateKey, value?: string) {
public async storeSecret(key: keyof SecretState, value?: string) {
await this.contextProxy.setValue(key, value)
}

private getSecret(key: SecretStateKey) {
private getSecret(key: keyof SecretState) {
return this.contextProxy.getValue(key)
}

Expand Down
Loading