mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
Add a share button when logged into cloud (#4448)
* Add a share button when logged into cloud * Only show share button if enabled * PR feedback
This commit is contained in:
parent
73e4418c12
commit
540d4fb94f
48 changed files with 513 additions and 50 deletions
|
|
@ -9,6 +9,7 @@ import type { CloudUserInfo } from "@roo-code/types"
|
|||
|
||||
import { getClerkBaseUrl, getRooCodeApiUrl } from "./Config"
|
||||
import { RefreshTimer } from "./RefreshTimer"
|
||||
import { getUserAgent } from "./utils"
|
||||
|
||||
export interface AuthServiceEvents {
|
||||
"inactive-session": [data: { previousState: AuthState }]
|
||||
|
|
@ -435,7 +436,7 @@ export class AuthService extends EventEmitter<AuthServiceEvents> {
|
|||
}
|
||||
|
||||
private userAgent(): string {
|
||||
return `Roo-Code ${this.context.extension?.packageJSON?.version}`
|
||||
return getUserAgent(this.context)
|
||||
}
|
||||
|
||||
private static _instance: AuthService | null = null
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { CloudServiceCallbacks } from "./types"
|
|||
import { AuthService } from "./AuthService"
|
||||
import { SettingsService } from "./SettingsService"
|
||||
import { TelemetryClient } from "./TelemetryClient"
|
||||
import { ShareService } from "./ShareService"
|
||||
|
||||
export class CloudService {
|
||||
private static _instance: CloudService | null = null
|
||||
|
|
@ -17,6 +18,7 @@ export class CloudService {
|
|||
private authService: AuthService | null = null
|
||||
private settingsService: SettingsService | null = null
|
||||
private telemetryClient: TelemetryClient | null = null
|
||||
private shareService: ShareService | null = null
|
||||
private isInitialized = false
|
||||
private log: (...args: unknown[]) => void
|
||||
|
||||
|
|
@ -48,6 +50,8 @@ export class CloudService {
|
|||
|
||||
this.telemetryClient = new TelemetryClient(this.authService, this.settingsService)
|
||||
|
||||
this.shareService = new ShareService(this.authService, this.settingsService, this.log)
|
||||
|
||||
try {
|
||||
TelemetryService.instance.register(this.telemetryClient)
|
||||
} catch (error) {
|
||||
|
|
@ -112,6 +116,18 @@ export class CloudService {
|
|||
this.telemetryClient!.capture(event)
|
||||
}
|
||||
|
||||
// ShareService
|
||||
|
||||
public async shareTask(taskId: string): Promise<boolean> {
|
||||
this.ensureInitialized()
|
||||
return this.shareService!.shareTask(taskId)
|
||||
}
|
||||
|
||||
public async canShareTask(): Promise<boolean> {
|
||||
this.ensureInitialized()
|
||||
return this.shareService!.canShareTask()
|
||||
}
|
||||
|
||||
// Lifecycle
|
||||
|
||||
public dispose(): void {
|
||||
|
|
@ -128,7 +144,13 @@ export class CloudService {
|
|||
}
|
||||
|
||||
private ensureInitialized(): void {
|
||||
if (!this.isInitialized || !this.authService || !this.settingsService || !this.telemetryClient) {
|
||||
if (
|
||||
!this.isInitialized ||
|
||||
!this.authService ||
|
||||
!this.settingsService ||
|
||||
!this.telemetryClient ||
|
||||
!this.shareService
|
||||
) {
|
||||
throw new Error("CloudService not initialized.")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
76
packages/cloud/src/ShareService.ts
Normal file
76
packages/cloud/src/ShareService.ts
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import axios from "axios"
|
||||
import * as vscode from "vscode"
|
||||
|
||||
import { shareResponseSchema } from "@roo-code/types"
|
||||
import { getRooCodeApiUrl } from "./Config"
|
||||
import type { AuthService } from "./AuthService"
|
||||
import type { SettingsService } from "./SettingsService"
|
||||
import { getUserAgent } from "./utils"
|
||||
|
||||
export class ShareService {
|
||||
private authService: AuthService
|
||||
private settingsService: SettingsService
|
||||
private log: (...args: unknown[]) => void
|
||||
|
||||
constructor(authService: AuthService, settingsService: SettingsService, log?: (...args: unknown[]) => void) {
|
||||
this.authService = authService
|
||||
this.settingsService = settingsService
|
||||
this.log = log || console.log
|
||||
}
|
||||
|
||||
/**
|
||||
* Share a task: Create link and copy to clipboard
|
||||
* Returns true if successful, false if failed
|
||||
*/
|
||||
async shareTask(taskId: string): Promise<boolean> {
|
||||
try {
|
||||
const sessionToken = this.authService.getSessionToken()
|
||||
if (!sessionToken) {
|
||||
return false
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${getRooCodeApiUrl()}/api/extension/share`,
|
||||
{ taskId },
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${sessionToken}`,
|
||||
"User-Agent": getUserAgent(),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
const data = shareResponseSchema.parse(response.data)
|
||||
this.log("[share] Share link created successfully:", data)
|
||||
|
||||
if (data.success && data.shareUrl) {
|
||||
// Copy to clipboard
|
||||
await vscode.env.clipboard.writeText(data.shareUrl)
|
||||
return true
|
||||
} else {
|
||||
this.log("[share] Share failed:", data.error)
|
||||
return false
|
||||
}
|
||||
} catch (error) {
|
||||
this.log("[share] Error sharing task:", error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if sharing is available
|
||||
*/
|
||||
async canShareTask(): Promise<boolean> {
|
||||
try {
|
||||
if (!this.authService.isAuthenticated()) {
|
||||
return false
|
||||
}
|
||||
|
||||
return !!this.settingsService.getSettings()?.cloudSettings?.enableTaskSharing
|
||||
} catch (error) {
|
||||
this.log("[share] Error checking if task can be shared:", error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
224
packages/cloud/src/__tests__/ShareService.test.ts
Normal file
224
packages/cloud/src/__tests__/ShareService.test.ts
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { describe, it, expect, beforeEach, vi, type MockedFunction } from "vitest"
|
||||
import axios from "axios"
|
||||
import * as vscode from "vscode"
|
||||
|
||||
import { ShareService } from "../ShareService"
|
||||
import type { AuthService } from "../AuthService"
|
||||
import type { SettingsService } from "../SettingsService"
|
||||
|
||||
// Mock axios
|
||||
vi.mock("axios")
|
||||
const mockedAxios = axios as any
|
||||
|
||||
// Mock vscode
|
||||
vi.mock("vscode", () => ({
|
||||
window: {
|
||||
showInformationMessage: vi.fn(),
|
||||
showErrorMessage: vi.fn(),
|
||||
},
|
||||
env: {
|
||||
clipboard: {
|
||||
writeText: vi.fn(),
|
||||
},
|
||||
openExternal: vi.fn(),
|
||||
},
|
||||
Uri: {
|
||||
parse: vi.fn(),
|
||||
},
|
||||
extensions: {
|
||||
getExtension: vi.fn(() => ({
|
||||
packageJSON: { version: "1.0.0" },
|
||||
})),
|
||||
},
|
||||
}))
|
||||
|
||||
// Mock config
|
||||
vi.mock("../Config", () => ({
|
||||
getRooCodeApiUrl: () => "https://app.roocode.com",
|
||||
}))
|
||||
|
||||
// Mock utils
|
||||
vi.mock("../utils", () => ({
|
||||
getUserAgent: () => "Roo-Code 1.0.0",
|
||||
}))
|
||||
|
||||
describe("ShareService", () => {
|
||||
let shareService: ShareService
|
||||
let mockAuthService: AuthService
|
||||
let mockSettingsService: SettingsService
|
||||
let mockLog: MockedFunction<(...args: unknown[]) => void>
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
|
||||
mockLog = vi.fn()
|
||||
mockAuthService = {
|
||||
hasActiveSession: vi.fn(),
|
||||
getSessionToken: vi.fn(),
|
||||
isAuthenticated: vi.fn(),
|
||||
} as any
|
||||
|
||||
mockSettingsService = {
|
||||
getSettings: vi.fn(),
|
||||
} as any
|
||||
|
||||
shareService = new ShareService(mockAuthService, mockSettingsService, mockLog)
|
||||
})
|
||||
|
||||
describe("shareTask", () => {
|
||||
it("should share task and copy to clipboard", async () => {
|
||||
const mockResponse = {
|
||||
data: {
|
||||
success: true,
|
||||
shareUrl: "https://app.roocode.com/share/abc123",
|
||||
},
|
||||
}
|
||||
|
||||
;(mockAuthService.hasActiveSession as any).mockReturnValue(true)
|
||||
;(mockAuthService.getSessionToken as any).mockReturnValue("session-token")
|
||||
mockedAxios.post.mockResolvedValue(mockResponse)
|
||||
|
||||
const result = await shareService.shareTask("task-123")
|
||||
|
||||
expect(result).toBe(true)
|
||||
expect(mockedAxios.post).toHaveBeenCalledWith(
|
||||
"https://app.roocode.com/api/extension/share",
|
||||
{ taskId: "task-123" },
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: "Bearer session-token",
|
||||
"User-Agent": "Roo-Code 1.0.0",
|
||||
},
|
||||
},
|
||||
)
|
||||
expect(vscode.env.clipboard.writeText).toHaveBeenCalledWith("https://app.roocode.com/share/abc123")
|
||||
})
|
||||
|
||||
it("should handle API error response", async () => {
|
||||
const mockResponse = {
|
||||
data: {
|
||||
success: false,
|
||||
error: "Task not found",
|
||||
},
|
||||
}
|
||||
|
||||
;(mockAuthService.hasActiveSession as any).mockReturnValue(true)
|
||||
;(mockAuthService.getSessionToken as any).mockReturnValue("session-token")
|
||||
mockedAxios.post.mockResolvedValue(mockResponse)
|
||||
|
||||
const result = await shareService.shareTask("task-123")
|
||||
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
|
||||
it("should handle authentication errors", async () => {
|
||||
;(mockAuthService.hasActiveSession as any).mockReturnValue(false)
|
||||
|
||||
const result = await shareService.shareTask("task-123")
|
||||
|
||||
expect(result).toBe(false)
|
||||
expect(mockedAxios.post).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("should handle 403 error for disabled sharing", async () => {
|
||||
;(mockAuthService.hasActiveSession as any).mockReturnValue(true)
|
||||
;(mockAuthService.getSessionToken as any).mockReturnValue("session-token")
|
||||
|
||||
const error = {
|
||||
isAxiosError: true,
|
||||
response: {
|
||||
status: 403,
|
||||
data: {
|
||||
error: "Task sharing is not enabled for this organization",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
mockedAxios.isAxiosError.mockReturnValue(true)
|
||||
mockedAxios.post.mockRejectedValue(error)
|
||||
|
||||
const result = await shareService.shareTask("task-123")
|
||||
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
|
||||
it("should handle unexpected errors", async () => {
|
||||
;(mockAuthService.hasActiveSession as any).mockReturnValue(true)
|
||||
;(mockAuthService.getSessionToken as any).mockReturnValue("session-token")
|
||||
|
||||
mockedAxios.post.mockRejectedValue(new Error("Network error"))
|
||||
|
||||
const result = await shareService.shareTask("task-123")
|
||||
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe("canShareTask", () => {
|
||||
it("should return true when authenticated and sharing is enabled", async () => {
|
||||
;(mockAuthService.isAuthenticated as any).mockReturnValue(true)
|
||||
;(mockSettingsService.getSettings as any).mockReturnValue({
|
||||
cloudSettings: {
|
||||
enableTaskSharing: true,
|
||||
},
|
||||
})
|
||||
|
||||
const result = await shareService.canShareTask()
|
||||
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
|
||||
it("should return false when authenticated but sharing is disabled", async () => {
|
||||
;(mockAuthService.isAuthenticated as any).mockReturnValue(true)
|
||||
;(mockSettingsService.getSettings as any).mockReturnValue({
|
||||
cloudSettings: {
|
||||
enableTaskSharing: false,
|
||||
},
|
||||
})
|
||||
|
||||
const result = await shareService.canShareTask()
|
||||
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
|
||||
it("should return false when authenticated and sharing setting is undefined (default)", async () => {
|
||||
;(mockAuthService.isAuthenticated as any).mockReturnValue(true)
|
||||
;(mockSettingsService.getSettings as any).mockReturnValue({
|
||||
cloudSettings: {},
|
||||
})
|
||||
|
||||
const result = await shareService.canShareTask()
|
||||
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
|
||||
it("should return false when authenticated and no settings available (default)", async () => {
|
||||
;(mockAuthService.isAuthenticated as any).mockReturnValue(true)
|
||||
;(mockSettingsService.getSettings as any).mockReturnValue(undefined)
|
||||
|
||||
const result = await shareService.canShareTask()
|
||||
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
|
||||
it("should return false when not authenticated", async () => {
|
||||
;(mockAuthService.isAuthenticated as any).mockReturnValue(false)
|
||||
|
||||
const result = await shareService.canShareTask()
|
||||
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
|
||||
it("should handle errors gracefully", async () => {
|
||||
;(mockAuthService.isAuthenticated as any).mockImplementation(() => {
|
||||
throw new Error("Auth error")
|
||||
})
|
||||
|
||||
const result = await shareService.canShareTask()
|
||||
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
10
packages/cloud/src/utils.ts
Normal file
10
packages/cloud/src/utils.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import * as vscode from "vscode"
|
||||
|
||||
/**
|
||||
* Get the User-Agent string for API requests
|
||||
* @param context Optional extension context for more accurate version detection
|
||||
* @returns User-Agent string in format "Roo-Code {version}"
|
||||
*/
|
||||
export function getUserAgent(context?: vscode.ExtensionContext): string {
|
||||
return `Roo-Code ${context?.extension?.packageJSON?.version || "unknown"}`
|
||||
}
|
||||
|
|
@ -104,3 +104,15 @@ export const ORGANIZATION_DEFAULT: OrganizationSettings = {
|
|||
defaultSettings: {},
|
||||
allowList: ORGANIZATION_ALLOW_ALL,
|
||||
} as const
|
||||
|
||||
/**
|
||||
* Share Types
|
||||
*/
|
||||
|
||||
export const shareResponseSchema = z.object({
|
||||
success: z.boolean(),
|
||||
shareUrl: z.string().optional(),
|
||||
error: z.string().optional(),
|
||||
})
|
||||
|
||||
export type ShareResponse = z.infer<typeof shareResponseSchema>
|
||||
|
|
|
|||
|
|
@ -1306,6 +1306,7 @@ export class ClineProvider
|
|||
historyPreviewCollapsed,
|
||||
cloudUserInfo,
|
||||
cloudIsAuthenticated,
|
||||
sharingEnabled,
|
||||
organizationAllowList,
|
||||
maxConcurrentFileReads,
|
||||
condensingApiConfigId,
|
||||
|
|
@ -1405,6 +1406,7 @@ export class ClineProvider
|
|||
historyPreviewCollapsed: historyPreviewCollapsed ?? false,
|
||||
cloudUserInfo,
|
||||
cloudIsAuthenticated: cloudIsAuthenticated ?? false,
|
||||
sharingEnabled: sharingEnabled ?? false,
|
||||
organizationAllowList,
|
||||
condensingApiConfigId,
|
||||
customCondensingPrompt,
|
||||
|
|
@ -1470,6 +1472,16 @@ export class ClineProvider
|
|||
)
|
||||
}
|
||||
|
||||
let sharingEnabled: boolean = false
|
||||
|
||||
try {
|
||||
sharingEnabled = await CloudService.instance.canShareTask()
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`[getState] failed to get sharing enabled state: ${error instanceof Error ? error.message : String(error)}`,
|
||||
)
|
||||
}
|
||||
|
||||
// Return the same structure as before
|
||||
return {
|
||||
apiConfiguration: providerSettings,
|
||||
|
|
@ -1546,6 +1558,7 @@ export class ClineProvider
|
|||
historyPreviewCollapsed: stateValues.historyPreviewCollapsed ?? false,
|
||||
cloudUserInfo,
|
||||
cloudIsAuthenticated,
|
||||
sharingEnabled,
|
||||
organizationAllowList,
|
||||
// Explicitly add condensing settings
|
||||
condensingApiConfigId: stateValues.condensingApiConfigId,
|
||||
|
|
|
|||
|
|
@ -428,6 +428,7 @@ describe("ClineProvider", () => {
|
|||
autoCondenseContext: true,
|
||||
autoCondenseContextPercent: 100,
|
||||
cloudIsAuthenticated: false,
|
||||
sharingEnabled: false,
|
||||
}
|
||||
|
||||
const message: ExtensionMessage = {
|
||||
|
|
|
|||
|
|
@ -207,6 +207,27 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We
|
|||
provider.exportTaskWithId(currentTaskId)
|
||||
}
|
||||
break
|
||||
case "shareCurrentTask":
|
||||
const shareTaskId = provider.getCurrentCline()?.taskId
|
||||
if (!shareTaskId) {
|
||||
vscode.window.showErrorMessage(t("common:errors.share_no_active_task"))
|
||||
break
|
||||
}
|
||||
|
||||
try {
|
||||
const success = await CloudService.instance.shareTask(shareTaskId)
|
||||
if (success) {
|
||||
// Show success message
|
||||
vscode.window.showInformationMessage(t("common:info.share_link_copied"))
|
||||
} else {
|
||||
// Show generic failure message
|
||||
vscode.window.showErrorMessage(t("common:errors.share_task_failed"))
|
||||
}
|
||||
} catch (error) {
|
||||
// Show generic failure message
|
||||
vscode.window.showErrorMessage(t("common:errors.share_task_failed"))
|
||||
}
|
||||
break
|
||||
case "showTaskWithId":
|
||||
provider.showTaskWithId(message.text!)
|
||||
break
|
||||
|
|
|
|||
|
|
@ -63,7 +63,9 @@
|
|||
"condense_not_enough_messages": "No hi ha prou missatges per condensar el context",
|
||||
"condensed_recently": "El context s'ha condensat recentment; s'omet aquest intent",
|
||||
"condense_handler_invalid": "El gestor de l'API per condensar el context no és vàlid",
|
||||
"condense_context_grew": "La mida del context ha augmentat durant la condensació; s'omet aquest intent"
|
||||
"condense_context_grew": "La mida del context ha augmentat durant la condensació; s'omet aquest intent",
|
||||
"share_task_failed": "Ha fallat compartir la tasca. Si us plau, torna-ho a provar.",
|
||||
"share_no_active_task": "No hi ha cap tasca activa per compartir"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "No s'ha seleccionat contingut de terminal",
|
||||
|
|
@ -79,7 +81,8 @@
|
|||
"mcp_server_not_found": "Servidor \"{{serverName}}\" no trobat a la configuració",
|
||||
"custom_storage_path_set": "Ruta d'emmagatzematge personalitzada establerta: {{path}}",
|
||||
"default_storage_path": "S'ha reprès l'ús de la ruta d'emmagatzematge predeterminada",
|
||||
"settings_imported": "Configuració importada correctament."
|
||||
"settings_imported": "Configuració importada correctament.",
|
||||
"share_link_copied": "Enllaç de compartició copiat al portapapers"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Sí",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "Nicht genügend Nachrichten zum Verdichten des Kontexts",
|
||||
"condensed_recently": "Kontext wurde kürzlich verdichtet; dieser Versuch wird übersprungen",
|
||||
"condense_handler_invalid": "API-Handler zum Verdichten des Kontexts ist ungültig",
|
||||
"condense_context_grew": "Kontextgröße ist während der Verdichtung gewachsen; dieser Versuch wird übersprungen"
|
||||
"condense_context_grew": "Kontextgröße ist während der Verdichtung gewachsen; dieser Versuch wird übersprungen",
|
||||
"share_task_failed": "Teilen der Aufgabe fehlgeschlagen. Bitte versuche es erneut.",
|
||||
"share_no_active_task": "Keine aktive Aufgabe zum Teilen"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "Kein Terminal-Inhalt ausgewählt",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "Server \"{{serverName}}\" nicht in der Konfiguration gefunden",
|
||||
"custom_storage_path_set": "Benutzerdefinierter Speicherpfad festgelegt: {{path}}",
|
||||
"default_storage_path": "Auf Standardspeicherpfad zurückgesetzt",
|
||||
"settings_imported": "Einstellungen erfolgreich importiert."
|
||||
"settings_imported": "Einstellungen erfolgreich importiert.",
|
||||
"share_link_copied": "Share-Link in die Zwischenablage kopiert"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Ja",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "Not enough messages to condense context",
|
||||
"condensed_recently": "Context was condensed recently; skipping this attempt",
|
||||
"condense_handler_invalid": "API handler for condensing context is invalid",
|
||||
"condense_context_grew": "Context size increased during condensing; skipping this attempt"
|
||||
"condense_context_grew": "Context size increased during condensing; skipping this attempt",
|
||||
"share_task_failed": "Failed to share task. Please try again.",
|
||||
"share_no_active_task": "No active task to share"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "No terminal content selected",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "Server \"{{serverName}}\" not found in configuration",
|
||||
"custom_storage_path_set": "Custom storage path set: {{path}}",
|
||||
"default_storage_path": "Reverted to using default storage path",
|
||||
"settings_imported": "Settings imported successfully."
|
||||
"settings_imported": "Settings imported successfully.",
|
||||
"share_link_copied": "Share link copied to clipboard"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Yes",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "No hay suficientes mensajes para condensar el contexto",
|
||||
"condensed_recently": "El contexto se condensó recientemente; se omite este intento",
|
||||
"condense_handler_invalid": "El manejador de API para condensar el contexto no es válido",
|
||||
"condense_context_grew": "El tamaño del contexto aumentó durante la condensación; se omite este intento"
|
||||
"condense_context_grew": "El tamaño del contexto aumentó durante la condensación; se omite este intento",
|
||||
"share_task_failed": "Error al compartir la tarea. Por favor, inténtalo de nuevo.",
|
||||
"share_no_active_task": "No hay tarea activa para compartir"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "No hay contenido de terminal seleccionado",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "Servidor \"{{serverName}}\" no encontrado en la configuración",
|
||||
"custom_storage_path_set": "Ruta de almacenamiento personalizada establecida: {{path}}",
|
||||
"default_storage_path": "Se ha vuelto a usar la ruta de almacenamiento predeterminada",
|
||||
"settings_imported": "Configuración importada correctamente."
|
||||
"settings_imported": "Configuración importada correctamente.",
|
||||
"share_link_copied": "Enlace de compartir copiado al portapapeles"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Sí",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "Pas assez de messages pour condenser le contexte",
|
||||
"condensed_recently": "Le contexte a été condensé récemment ; cette tentative est ignorée",
|
||||
"condense_handler_invalid": "Le gestionnaire d'API pour condenser le contexte est invalide",
|
||||
"condense_context_grew": "La taille du contexte a augmenté pendant la condensation ; cette tentative est ignorée"
|
||||
"condense_context_grew": "La taille du contexte a augmenté pendant la condensation ; cette tentative est ignorée",
|
||||
"share_task_failed": "Échec du partage de la tâche. Veuillez réessayer.",
|
||||
"share_no_active_task": "Aucune tâche active à partager"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "Aucun contenu de terminal sélectionné",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "Serveur \"{{serverName}}\" introuvable dans la configuration",
|
||||
"custom_storage_path_set": "Chemin de stockage personnalisé défini : {{path}}",
|
||||
"default_storage_path": "Retour au chemin de stockage par défaut",
|
||||
"settings_imported": "Paramètres importés avec succès."
|
||||
"settings_imported": "Paramètres importés avec succès.",
|
||||
"share_link_copied": "Lien de partage copié dans le presse-papiers"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Oui",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "संदर्भ को संक्षिप्त करने के लिए पर्याप्त संदेश नहीं हैं",
|
||||
"condensed_recently": "संदर्भ हाल ही में संक्षिप्त किया गया था; इस प्रयास को छोड़ा जा रहा है",
|
||||
"condense_handler_invalid": "संदर्भ को संक्षिप्त करने के लिए API हैंडलर अमान्य है",
|
||||
"condense_context_grew": "संक्षिप्तीकरण के दौरान संदर्भ का आकार बढ़ गया; इस प्रयास को छोड़ा जा रहा है"
|
||||
"condense_context_grew": "संक्षिप्तीकरण के दौरान संदर्भ का आकार बढ़ गया; इस प्रयास को छोड़ा जा रहा है",
|
||||
"share_task_failed": "कार्य साझा करने में विफल। कृपया पुनः प्रयास करें।",
|
||||
"share_no_active_task": "साझा करने के लिए कोई सक्रिय कार्य नहीं"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "कोई टर्मिनल सामग्री चयनित नहीं",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "सर्वर \"{{serverName}}\" कॉन्फ़िगरेशन में नहीं मिला",
|
||||
"custom_storage_path_set": "कस्टम स्टोरेज पाथ सेट किया गया: {{path}}",
|
||||
"default_storage_path": "डिफ़ॉल्ट स्टोरेज पाथ का उपयोग पुनः शुरू किया गया",
|
||||
"settings_imported": "सेटिंग्स सफलतापूर्वक इम्पोर्ट की गईं।"
|
||||
"settings_imported": "सेटिंग्स सफलतापूर्वक इम्पोर्ट की गईं।",
|
||||
"share_link_copied": "साझा लिंक क्लिपबोर्ड पर कॉपी किया गया"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "हां",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "Non ci sono abbastanza messaggi per condensare il contesto",
|
||||
"condensed_recently": "Il contesto è stato condensato di recente; questo tentativo viene saltato",
|
||||
"condense_handler_invalid": "Il gestore API per condensare il contesto non è valido",
|
||||
"condense_context_grew": "La dimensione del contesto è aumentata durante la condensazione; questo tentativo viene saltato"
|
||||
"condense_context_grew": "La dimensione del contesto è aumentata durante la condensazione; questo tentativo viene saltato",
|
||||
"share_task_failed": "Condivisione dell'attività fallita. Riprova.",
|
||||
"share_no_active_task": "Nessuna attività attiva da condividere"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "Nessun contenuto del terminale selezionato",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "Server \"{{serverName}}\" non trovato nella configurazione",
|
||||
"custom_storage_path_set": "Percorso di archiviazione personalizzato impostato: {{path}}",
|
||||
"default_storage_path": "Tornato al percorso di archiviazione predefinito",
|
||||
"settings_imported": "Impostazioni importate con successo."
|
||||
"settings_imported": "Impostazioni importate con successo.",
|
||||
"share_link_copied": "Link di condivisione copiato negli appunti"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Sì",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "コンテキストを圧縮するのに十分なメッセージがありません",
|
||||
"condensed_recently": "コンテキストは最近圧縮されました;この試行をスキップします",
|
||||
"condense_handler_invalid": "コンテキストを圧縮するためのAPIハンドラーが無効です",
|
||||
"condense_context_grew": "圧縮中にコンテキストサイズが増加しました;この試行をスキップします"
|
||||
"condense_context_grew": "圧縮中にコンテキストサイズが増加しました;この試行をスキップします",
|
||||
"share_task_failed": "タスクの共有に失敗しました",
|
||||
"share_no_active_task": "共有するアクティブなタスクがありません"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "選択されたターミナルコンテンツがありません",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "サーバー\"{{serverName}}\"が設定内に見つかりません",
|
||||
"custom_storage_path_set": "カスタムストレージパスが設定されました:{{path}}",
|
||||
"default_storage_path": "デフォルトのストレージパスに戻りました",
|
||||
"settings_imported": "設定が正常にインポートされました。"
|
||||
"settings_imported": "設定が正常にインポートされました。",
|
||||
"share_link_copied": "共有リンクがクリップボードにコピーされました"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "はい",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "컨텍스트를 압축할 메시지가 충분하지 않습니다",
|
||||
"condensed_recently": "컨텍스트가 최근 압축되었습니다; 이 시도를 건너뜁니다",
|
||||
"condense_handler_invalid": "컨텍스트 압축을 위한 API 핸들러가 유효하지 않습니다",
|
||||
"condense_context_grew": "압축 중 컨텍스트 크기가 증가했습니다; 이 시도를 건너뜁니다"
|
||||
"condense_context_grew": "압축 중 컨텍스트 크기가 증가했습니다; 이 시도를 건너뜁니다",
|
||||
"share_task_failed": "작업 공유에 실패했습니다",
|
||||
"share_no_active_task": "공유할 활성 작업이 없습니다"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "선택된 터미널 내용이 없습니다",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "구성에서 서버 \"{{serverName}}\"을(를) 찾을 수 없습니다",
|
||||
"custom_storage_path_set": "사용자 지정 저장 경로 설정됨: {{path}}",
|
||||
"default_storage_path": "기본 저장 경로로 되돌아갔습니다",
|
||||
"settings_imported": "설정이 성공적으로 가져와졌습니다."
|
||||
"settings_imported": "설정이 성공적으로 가져와졌습니다.",
|
||||
"share_link_copied": "공유 링크가 클립보드에 복사되었습니다"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "예",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "Niet genoeg berichten om context te comprimeren",
|
||||
"condensed_recently": "Context is recent gecomprimeerd; deze poging wordt overgeslagen",
|
||||
"condense_handler_invalid": "API-handler voor het comprimeren van context is ongeldig",
|
||||
"condense_context_grew": "Contextgrootte nam toe tijdens comprimeren; deze poging wordt overgeslagen"
|
||||
"condense_context_grew": "Contextgrootte nam toe tijdens comprimeren; deze poging wordt overgeslagen",
|
||||
"share_task_failed": "Delen van taak mislukt",
|
||||
"share_no_active_task": "Geen actieve taak om te delen"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "Geen terminalinhoud geselecteerd",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "Server \"{{serverName}}\" niet gevonden in configuratie",
|
||||
"custom_storage_path_set": "Aangepast opslagpad ingesteld: {{path}}",
|
||||
"default_storage_path": "Terug naar standaard opslagpad",
|
||||
"settings_imported": "Instellingen succesvol geïmporteerd."
|
||||
"settings_imported": "Instellingen succesvol geïmporteerd.",
|
||||
"share_link_copied": "Deellink gekopieerd naar klembord"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Ja",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "Za mało wiadomości do skondensowania kontekstu",
|
||||
"condensed_recently": "Kontekst został niedawno skondensowany; pomijanie tej próby",
|
||||
"condense_handler_invalid": "Nieprawidłowy handler API do kondensowania kontekstu",
|
||||
"condense_context_grew": "Rozmiar kontekstu wzrósł podczas kondensacji; pomijanie tej próby"
|
||||
"condense_context_grew": "Rozmiar kontekstu wzrósł podczas kondensacji; pomijanie tej próby",
|
||||
"share_task_failed": "Nie udało się udostępnić zadania",
|
||||
"share_no_active_task": "Brak aktywnego zadania do udostępnienia"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "Nie wybrano zawartości terminala",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "Serwer \"{{serverName}}\" nie znaleziony w konfiguracji",
|
||||
"custom_storage_path_set": "Ustawiono niestandardową ścieżkę przechowywania: {{path}}",
|
||||
"default_storage_path": "Wznowiono używanie domyślnej ścieżki przechowywania",
|
||||
"settings_imported": "Ustawienia zaimportowane pomyślnie."
|
||||
"settings_imported": "Ustawienia zaimportowane pomyślnie.",
|
||||
"share_link_copied": "Link udostępniania skopiowany do schowka"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Tak",
|
||||
|
|
|
|||
|
|
@ -63,7 +63,9 @@
|
|||
"condense_not_enough_messages": "Não há mensagens suficientes para condensar o contexto",
|
||||
"condensed_recently": "O contexto foi condensado recentemente; pulando esta tentativa",
|
||||
"condense_handler_invalid": "O manipulador de API para condensar o contexto é inválido",
|
||||
"condense_context_grew": "O tamanho do contexto aumentou durante a condensação; pulando esta tentativa"
|
||||
"condense_context_grew": "O tamanho do contexto aumentou durante a condensação; pulando esta tentativa",
|
||||
"share_task_failed": "Falha ao compartilhar tarefa",
|
||||
"share_no_active_task": "Nenhuma tarefa ativa para compartilhar"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "Nenhum conteúdo do terminal selecionado",
|
||||
|
|
@ -79,7 +81,8 @@
|
|||
"mcp_server_not_found": "Servidor \"{{serverName}}\" não encontrado na configuração",
|
||||
"custom_storage_path_set": "Caminho de armazenamento personalizado definido: {{path}}",
|
||||
"default_storage_path": "Retornado ao caminho de armazenamento padrão",
|
||||
"settings_imported": "Configurações importadas com sucesso."
|
||||
"settings_imported": "Configurações importadas com sucesso.",
|
||||
"share_link_copied": "Link de compartilhamento copiado para a área de transferência"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Sim",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "Недостаточно сообщений для сжатия контекста",
|
||||
"condensed_recently": "Контекст был недавно сжат; пропускаем эту попытку",
|
||||
"condense_handler_invalid": "Обработчик API для сжатия контекста недействителен",
|
||||
"condense_context_grew": "Размер контекста увеличился во время сжатия; пропускаем эту попытку"
|
||||
"condense_context_grew": "Размер контекста увеличился во время сжатия; пропускаем эту попытку",
|
||||
"share_task_failed": "Не удалось поделиться задачей",
|
||||
"share_no_active_task": "Нет активной задачи для совместного использования"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "Не выбрано содержимое терминала",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "Сервер \"{{serverName}}\" не найден в конфигурации",
|
||||
"custom_storage_path_set": "Установлен пользовательский путь хранения: {{path}}",
|
||||
"default_storage_path": "Возвращено использование пути хранения по умолчанию",
|
||||
"settings_imported": "Настройки успешно импортированы."
|
||||
"settings_imported": "Настройки успешно импортированы.",
|
||||
"share_link_copied": "Ссылка для совместного использования скопирована в буфер обмена"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Да",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "Bağlamı sıkıştırmak için yeterli mesaj yok",
|
||||
"condensed_recently": "Bağlam yakın zamanda sıkıştırıldı; bu deneme atlanıyor",
|
||||
"condense_handler_invalid": "Bağlamı sıkıştırmak için API işleyicisi geçersiz",
|
||||
"condense_context_grew": "Sıkıştırma sırasında bağlam boyutu arttı; bu deneme atlanıyor"
|
||||
"condense_context_grew": "Sıkıştırma sırasında bağlam boyutu arttı; bu deneme atlanıyor",
|
||||
"share_task_failed": "Görev paylaşılamadı",
|
||||
"share_no_active_task": "Paylaşılacak aktif görev yok"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "Seçili terminal içeriği yok",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "Yapılandırmada \"{{serverName}}\" sunucusu bulunamadı",
|
||||
"custom_storage_path_set": "Özel depolama yolu ayarlandı: {{path}}",
|
||||
"default_storage_path": "Varsayılan depolama yoluna geri dönüldü",
|
||||
"settings_imported": "Ayarlar başarıyla içe aktarıldı."
|
||||
"settings_imported": "Ayarlar başarıyla içe aktarıldı.",
|
||||
"share_link_copied": "Paylaşım bağlantısı panoya kopyalandı"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Evet",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "Không đủ tin nhắn để nén ngữ cảnh",
|
||||
"condensed_recently": "Ngữ cảnh đã được nén gần đây; bỏ qua lần thử này",
|
||||
"condense_handler_invalid": "Trình xử lý API để nén ngữ cảnh không hợp lệ",
|
||||
"condense_context_grew": "Kích thước ngữ cảnh tăng lên trong quá trình nén; bỏ qua lần thử này"
|
||||
"condense_context_grew": "Kích thước ngữ cảnh tăng lên trong quá trình nén; bỏ qua lần thử này",
|
||||
"share_task_failed": "Không thể chia sẻ nhiệm vụ",
|
||||
"share_no_active_task": "Không có nhiệm vụ hoạt động để chia sẻ"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "Không có nội dung terminal được chọn",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "Không tìm thấy máy chủ \"{{serverName}}\" trong cấu hình",
|
||||
"custom_storage_path_set": "Đã thiết lập đường dẫn lưu trữ tùy chỉnh: {{path}}",
|
||||
"default_storage_path": "Đã quay lại sử dụng đường dẫn lưu trữ mặc định",
|
||||
"settings_imported": "Cài đặt đã được nhập thành công."
|
||||
"settings_imported": "Cài đặt đã được nhập thành công.",
|
||||
"share_link_copied": "Liên kết chia sẻ đã được sao chép vào clipboard"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "Có",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "没有足够的对话来压缩上下文",
|
||||
"condensed_recently": "上下文最近已压缩;跳过此次尝试",
|
||||
"condense_handler_invalid": "压缩上下文的API处理程序无效",
|
||||
"condense_context_grew": "压缩过程中上下文大小增加;跳过此次尝试"
|
||||
"condense_context_grew": "压缩过程中上下文大小增加;跳过此次尝试",
|
||||
"share_task_failed": "分享任务失败。请重试。",
|
||||
"share_no_active_task": "没有活跃任务可分享"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "没有选择终端内容",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "在配置中未找到服务器\"{{serverName}}\"",
|
||||
"custom_storage_path_set": "自定义存储路径已设置:{{path}}",
|
||||
"default_storage_path": "已恢复使用默认存储路径",
|
||||
"settings_imported": "设置已成功导入。"
|
||||
"settings_imported": "设置已成功导入。",
|
||||
"share_link_copied": "分享链接已复制到剪贴板"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "是",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
"condense_not_enough_messages": "沒有足夠的訊息來壓縮上下文",
|
||||
"condensed_recently": "上下文最近已壓縮;跳過此次嘗試",
|
||||
"condense_handler_invalid": "壓縮上下文的 API 處理程式無效",
|
||||
"condense_context_grew": "壓縮過程中上下文大小增加;跳過此次嘗試"
|
||||
"condense_context_grew": "壓縮過程中上下文大小增加;跳過此次嘗試",
|
||||
"share_task_failed": "分享工作失敗。請重試。",
|
||||
"share_no_active_task": "沒有活躍的工作可分享"
|
||||
},
|
||||
"warnings": {
|
||||
"no_terminal_content": "沒有選擇終端機內容",
|
||||
|
|
@ -75,7 +77,8 @@
|
|||
"mcp_server_not_found": "在設定中沒有找到伺服器\"{{serverName}}\"",
|
||||
"custom_storage_path_set": "自訂儲存路徑已設定:{{path}}",
|
||||
"default_storage_path": "已恢復使用預設儲存路徑",
|
||||
"settings_imported": "設定已成功匯入。"
|
||||
"settings_imported": "設定已成功匯入。",
|
||||
"share_link_copied": "分享連結已複製到剪貼簿"
|
||||
},
|
||||
"answers": {
|
||||
"yes": "是",
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ export type ExtensionState = Pick<
|
|||
|
||||
cloudUserInfo: CloudUserInfo | null
|
||||
cloudIsAuthenticated: boolean
|
||||
sharingEnabled: boolean
|
||||
organizationAllowList: OrganizationAllowList
|
||||
|
||||
autoCondenseContext: boolean
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ export interface WebviewMessage {
|
|||
| "didShowAnnouncement"
|
||||
| "selectImages"
|
||||
| "exportCurrentTask"
|
||||
| "shareCurrentTask"
|
||||
| "showTaskWithId"
|
||||
| "deleteTaskWithId"
|
||||
| "exportTaskWithId"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next"
|
|||
import type { HistoryItem } from "@roo-code/types"
|
||||
|
||||
import { vscode } from "@/utils/vscode"
|
||||
import { useExtensionState } from "@/context/ExtensionStateContext"
|
||||
|
||||
import { DeleteTaskDialog } from "../history/DeleteTaskDialog"
|
||||
import { IconButton } from "./IconButton"
|
||||
|
|
@ -17,9 +18,18 @@ interface TaskActionsProps {
|
|||
export const TaskActions = ({ item, buttonsDisabled }: TaskActionsProps) => {
|
||||
const [deleteTaskId, setDeleteTaskId] = useState<string | null>(null)
|
||||
const { t } = useTranslation()
|
||||
const { sharingEnabled } = useExtensionState()
|
||||
|
||||
return (
|
||||
<div className="flex flex-row gap-1">
|
||||
{item?.id && sharingEnabled && (
|
||||
<IconButton
|
||||
iconClass="codicon-link"
|
||||
title={t("chat:task.share")}
|
||||
disabled={buttonsDisabled}
|
||||
onClick={() => vscode.postMessage({ type: "shareCurrentTask" })}
|
||||
/>
|
||||
)}
|
||||
<IconButton
|
||||
iconClass="codicon-desktop-download"
|
||||
title={t("chat:task.export")}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ export interface ExtensionStateContextType extends ExtensionState {
|
|||
openedTabs: Array<{ label: string; isActive: boolean; path?: string }>
|
||||
organizationAllowList: OrganizationAllowList
|
||||
cloudIsAuthenticated: boolean
|
||||
sharingEnabled: boolean
|
||||
maxConcurrentFileReads?: number
|
||||
condensingApiConfigId?: string
|
||||
setCondensingApiConfigId: (value: string) => void
|
||||
|
|
@ -201,6 +202,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
|
|||
historyPreviewCollapsed: false, // Initialize the new state (default to expanded)
|
||||
cloudUserInfo: null,
|
||||
cloudIsAuthenticated: false,
|
||||
sharingEnabled: false,
|
||||
organizationAllowList: ORGANIZATION_ALLOW_ALL,
|
||||
autoCondenseContext: true,
|
||||
autoCondenseContextPercent: 100,
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ describe("mergeExtensionState", () => {
|
|||
autoCondenseContext: true,
|
||||
autoCondenseContextPercent: 100,
|
||||
cloudIsAuthenticated: false,
|
||||
sharingEnabled: false,
|
||||
}
|
||||
|
||||
const prevState: ExtensionState = {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "Tancar tasca i iniciar-ne una de nova",
|
||||
"export": "Exportar historial de tasques",
|
||||
"delete": "Eliminar tasca (Shift + Clic per ometre confirmació)",
|
||||
"condenseContext": "Condensar context de forma intel·ligent"
|
||||
"condenseContext": "Condensar context de forma intel·ligent",
|
||||
"share": "Compartir tasca"
|
||||
},
|
||||
"unpin": "Desfixar",
|
||||
"pin": "Fixar",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
"closeAndStart": "Aufgabe schließen und neue starten",
|
||||
"export": "Aufgabenverlauf exportieren",
|
||||
"delete": "Aufgabe löschen (Shift + Klick zum Überspringen der Bestätigung)",
|
||||
"share": "Aufgabe teilen",
|
||||
"condenseContext": "Kontext intelligent komprimieren"
|
||||
},
|
||||
"unpin": "Lösen von oben",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
"contextWindow": "Context Length:",
|
||||
"closeAndStart": "Close task and start a new one",
|
||||
"export": "Export task history",
|
||||
"share": "Share task",
|
||||
"delete": "Delete Task (Shift + Click to skip confirmation)"
|
||||
},
|
||||
"unpin": "Unpin",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "Cerrar tarea e iniciar una nueva",
|
||||
"export": "Exportar historial de tareas",
|
||||
"delete": "Eliminar tarea (Shift + Clic para omitir confirmación)",
|
||||
"condenseContext": "Condensar contexto de forma inteligente"
|
||||
"condenseContext": "Condensar contexto de forma inteligente",
|
||||
"share": "Compartir tarea"
|
||||
},
|
||||
"unpin": "Desfijar",
|
||||
"pin": "Fijar",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "Fermer la tâche et en commencer une nouvelle",
|
||||
"export": "Exporter l'historique des tâches",
|
||||
"delete": "Supprimer la tâche (Shift + Clic pour ignorer la confirmation)",
|
||||
"condenseContext": "Condenser intelligemment le contexte"
|
||||
"condenseContext": "Condenser intelligemment le contexte",
|
||||
"share": "Partager la tâche"
|
||||
},
|
||||
"unpin": "Désépingler",
|
||||
"pin": "Épingler",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "कार्य बंद करें और नया शुरू करें",
|
||||
"export": "कार्य इतिहास निर्यात करें",
|
||||
"delete": "कार्य हटाएं (पुष्टि को छोड़ने के लिए Shift + क्लिक)",
|
||||
"condenseContext": "संदर्भ को बुद्धिमानी से संघनित करें"
|
||||
"condenseContext": "संदर्भ को बुद्धिमानी से संघनित करें",
|
||||
"share": "कार्य साझा करें"
|
||||
},
|
||||
"unpin": "पिन करें",
|
||||
"pin": "अवपिन करें",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "Chiudi attività e iniziane una nuova",
|
||||
"export": "Esporta cronologia attività",
|
||||
"delete": "Elimina attività (Shift + Clic per saltare la conferma)",
|
||||
"condenseContext": "Condensa contesto in modo intelligente"
|
||||
"condenseContext": "Condensa contesto in modo intelligente",
|
||||
"share": "Condividi attività"
|
||||
},
|
||||
"unpin": "Rilascia",
|
||||
"pin": "Fissa",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "タスクを閉じて新しいタスクを開始",
|
||||
"export": "タスク履歴をエクスポート",
|
||||
"delete": "タスクを削除(Shift + クリックで確認をスキップ)",
|
||||
"condenseContext": "コンテキストをインテリジェントに圧縮"
|
||||
"condenseContext": "コンテキストをインテリジェントに圧縮",
|
||||
"share": "タスクを共有"
|
||||
},
|
||||
"unpin": "ピン留めを解除",
|
||||
"pin": "ピン留め",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "작업 닫고 새 작업 시작",
|
||||
"export": "작업 기록 내보내기",
|
||||
"delete": "작업 삭제 (Shift + 클릭으로 확인 생략)",
|
||||
"condenseContext": "컨텍스트 지능적으로 압축"
|
||||
"condenseContext": "컨텍스트 지능적으로 압축",
|
||||
"share": "작업 공유"
|
||||
},
|
||||
"unpin": "고정 해제하기",
|
||||
"pin": "고정하기",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "Taak sluiten en een nieuwe starten",
|
||||
"export": "Taakgeschiedenis exporteren",
|
||||
"delete": "Taak verwijderen (Shift + Klik om bevestiging over te slaan)",
|
||||
"condenseContext": "Context intelligent samenvatten"
|
||||
"condenseContext": "Context intelligent samenvatten",
|
||||
"share": "Taak delen"
|
||||
},
|
||||
"unpin": "Losmaken",
|
||||
"pin": "Vastmaken",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "Zamknij zadanie i rozpocznij nowe",
|
||||
"export": "Eksportuj historię zadań",
|
||||
"delete": "Usuń zadanie (Shift + Kliknięcie, aby pominąć potwierdzenie)",
|
||||
"condenseContext": "Inteligentnie skondensuj kontekst"
|
||||
"condenseContext": "Inteligentnie skondensuj kontekst",
|
||||
"share": "Udostępnij zadanie"
|
||||
},
|
||||
"unpin": "Odepnij",
|
||||
"pin": "Przypnij",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "Fechar tarefa e iniciar nova",
|
||||
"export": "Exportar histórico de tarefas",
|
||||
"delete": "Excluir tarefa (Shift + Clique para pular confirmação)",
|
||||
"condenseContext": "Condensar contexto de forma inteligente"
|
||||
"condenseContext": "Condensar contexto de forma inteligente",
|
||||
"share": "Compartilhar tarefa"
|
||||
},
|
||||
"unpin": "Desfixar",
|
||||
"pin": "Fixar",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "Закрыть задачу и начать новую",
|
||||
"export": "Экспортировать историю задач",
|
||||
"delete": "Удалить задачу (Shift + клик для пропуска подтверждения)",
|
||||
"condenseContext": "Интеллектуально сжать контекст"
|
||||
"condenseContext": "Интеллектуально сжать контекст",
|
||||
"share": "Поделиться задачей"
|
||||
},
|
||||
"unpin": "Открепить",
|
||||
"pin": "Закрепить",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "Görevi kapat ve yeni bir görev başlat",
|
||||
"export": "Görev geçmişini dışa aktar",
|
||||
"delete": "Görevi sil (Onayı atlamak için Shift + Tıkla)",
|
||||
"condenseContext": "Bağlamı akıllıca yoğunlaştır"
|
||||
"condenseContext": "Bağlamı akıllıca yoğunlaştır",
|
||||
"share": "Görevi paylaş"
|
||||
},
|
||||
"unpin": "Sabitlemeyi iptal et",
|
||||
"pin": "Sabitle",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "Đóng nhiệm vụ và bắt đầu nhiệm vụ mới",
|
||||
"export": "Xuất lịch sử nhiệm vụ",
|
||||
"delete": "Xóa nhiệm vụ (Shift + Click để bỏ qua xác nhận)",
|
||||
"condenseContext": "Cô đọng ngữ cảnh thông minh"
|
||||
"condenseContext": "Cô đọng ngữ cảnh thông minh",
|
||||
"share": "Chia sẻ nhiệm vụ"
|
||||
},
|
||||
"unpin": "Bỏ ghim khỏi đầu",
|
||||
"pin": "Ghim lên đầu",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
"closeAndStart": "关闭任务并开始新任务",
|
||||
"export": "导出任务历史",
|
||||
"delete": "删除任务(Shift + 点击跳过确认)",
|
||||
"share": "分享任务",
|
||||
"condenseContext": "智能压缩上下文"
|
||||
},
|
||||
"unpin": "取消置顶",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"closeAndStart": "關閉現有工作並開始一項新的工作",
|
||||
"export": "匯出工作紀錄",
|
||||
"delete": "刪除工作(按住 Shift 並點選可跳過確認)",
|
||||
"condenseContext": "智慧壓縮上下文"
|
||||
"condenseContext": "智慧壓縮上下文",
|
||||
"share": "分享工作"
|
||||
},
|
||||
"unpin": "取消置頂",
|
||||
"pin": "置頂",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue