Skip to content

Commit c6a29ff

Browse files
committed
Add option to delete source code when removing component
1 parent 0eee9fc commit c6a29ff

22 files changed

Lines changed: 200 additions & 199 deletions

File tree

extensions/roopik-roo/src/api/providers/human-relay.ts

Lines changed: 0 additions & 134 deletions
This file was deleted.

extensions/roopik-roo/src/core/prompts/tools/native-tools/roopik.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ export const component_remove: OpenAI.Chat.ChatCompletionTool = {
496496
function: {
497497
name: "component_remove",
498498
description:
499-
"[Roopik IDE] Remove a component from its canvas. This stops the build watcher but does not delete the source files.",
499+
"[Roopik IDE] Remove component from canvas. Set deleteSourceCode=true to automatically delete source files - do NOT use terminal commands to delete files manually.",
500500
strict: true,
501501
parameters: {
502502
type: "object",
@@ -505,6 +505,10 @@ export const component_remove: OpenAI.Chat.ChatCompletionTool = {
505505
type: "string",
506506
description: "The component's unique ID (from component_list)",
507507
},
508+
deleteSourceCode: {
509+
type: "boolean",
510+
description: "If true, also delete the source code files from disk (default: false)",
511+
},
508512
},
509513
required: ["componentId"],
510514
additionalProperties: false,

extensions/roopik-roo/src/core/prompts/tools/roopik/roopik-tools.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,14 @@ Usage:
323323

324324
export function getComponentRemoveDescription(): string {
325325
return `## component_remove
326-
Description: [Roopik IDE] Remove a component from its canvas. This stops the build watcher but does not delete the source files.
326+
Description: [Roopik IDE] Remove a component from its canvas. Set deleteSourceCode=true to automatically delete source files from disk - DO NOT manually delete files with terminal commands.
327327
Parameters:
328328
- componentId: (required) The component's unique ID (from component_list)
329+
- deleteSourceCode: (optional) Set to true to delete source code from disk (default: false). When true, both UI removal and file deletion are handled automatically internally.
329330
Usage:
330331
<component_remove>
331332
<componentId>component-id</componentId>
333+
<deleteSourceCode>true</deleteSourceCode>
332334
</component_remove>`
333335
}
334336

@@ -440,7 +442,7 @@ These tools integrate with Roopik IDE's browser preview, canvas, and component f
440442
2. \`component_add\` - Add component folder to canvas (Once you write a component code, you have to pass the absolute path of the component file to the canvas add tool which shows the live preview of the component in the canvas UI)
441443
3. \`component_list\` - See all components on canvas (this will show the list of all components added to the canvas to you if you need to see the list of components added to the canvas or get info about a specific component use \`component_get_info\`)
442444
4. \`component_rebuild\` - Force rebuild after changes (use this tool if you make changes to the component code and want to rebuild the component)
443-
5. \`component_remove\` - Remove component from canvas (IMPORTANT: This only removes the component from the canvas UI visually, it does NOT delete the code files. To fully remove a component: first call \`component_remove\` to remove from canvas, then delete the component folder for a clean removal)
445+
5. \`component_remove\` - Remove component (set deleteSourceCode=true to delete files automatically - never use terminal commands to delete files)
444446
6. User views live preview in canvas UI
445447
- **IMPORTANT**: DO NOT use browser_open or browser_screenshot for canvas components. The canvas UI shows live preview automatically after component_add. Browser tools are only for projects with dev servers.
446448

extensions/roopik-roo/src/core/tools/roopik/RoopikToolHandler.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ async function handleRemoveComponent(task: Task, block: ToolUse, callbacks: Tool
408408
if (!componentId) {
409409
return { success: false, error: "Missing required parameter: componentId" }
410410
}
411-
return roopikClient.removeComponent(componentId)
411+
const deleteSourceCode = block.params.deleteSourceCode === true || block.params.deleteSourceCode === "true"
412+
return roopikClient.removeComponent(componentId, deleteSourceCode)
412413
}
413414

414415
async function handleGetComponentInfo(task: Task, block: ToolUse, callbacks: ToolCallbacks): Promise<RoopikToolResult> {

extensions/roopik-roo/src/services/roopik/RoopikToolClient.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ export interface AddComponentsData {
268268
*/
269269
export interface RemoveComponentData {
270270
componentId: string
271+
deletedSourceCode: boolean
271272
}
272273

273274
/**
@@ -558,10 +559,13 @@ export class RoopikToolClient {
558559

559560
/**
560561
* Remove a component from its canvas
562+
* @param componentId The component's unique ID
563+
* @param deleteSourceCode If true, also delete the source code files from disk (default: false)
561564
*/
562-
async removeComponent(componentId: string): Promise<RoopikToolResult<RemoveComponentData>> {
565+
async removeComponent(componentId: string, deleteSourceCode?: boolean): Promise<RoopikToolResult<RemoveComponentData>> {
563566
return this.executeCommand<RemoveComponentData>("roopik.tools.removeComponent", {
564567
componentId,
568+
deleteSourceCode,
565569
})
566570
}
567571

extensions/roopik-roo/src/shared/tools.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export const toolParamNames = [
9494
"entryFile", // component_add
9595
"framework", // component_add
9696
"componentId", // component_remove, component_get_info, component_rebuild
97+
"deleteSourceCode", // component_remove
9798
"components", // component_add_batch
9899
// browser_action parameters
99100
"key", // browser_action (press)
@@ -404,17 +405,17 @@ export const TOOL_ALIASES: Record<string, ToolName> = {
404405
export type DiffResult =
405406
| { success: true; content: string; failParts?: DiffResult[] }
406407
| ({
407-
success: false
408-
error?: string
409-
details?: {
410-
similarity?: number
411-
threshold?: number
412-
matchedRange?: { start: number; end: number }
413-
searchContent?: string
414-
bestMatch?: string
415-
}
416-
failParts?: DiffResult[]
417-
} & ({ error: string } | { failParts: DiffResult[] }))
408+
success: false
409+
error?: string
410+
details?: {
411+
similarity?: number
412+
threshold?: number
413+
matchedRange?: { start: number; end: number }
414+
searchContent?: string
415+
bestMatch?: string
416+
}
417+
failParts?: DiffResult[]
418+
} & ({ error: string } | { failParts: DiffResult[] }))
418419

419420
export interface DiffItem {
420421
content: string

extensions/roopik/src/canvasPanel.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ export class CanvasPanel implements vscode.Disposable {
407407
break;
408408

409409
case 'deleteComponent':
410-
await this.handleDeleteComponent(message.payload as { componentId: string });
410+
await this.handleDeleteComponent(message.payload as { componentId: string; deleteSourceCode?: boolean });
411411
break;
412412

413413
case 'saveCanvas':
@@ -677,9 +677,8 @@ export class CanvasPanel implements vscode.Disposable {
677677
/**
678678
* Handle delete component request from webview
679679
*/
680-
private async handleDeleteComponent(payload: { componentId: string }): Promise<void> {
681-
this.logger.info(`Deleting component: ${payload.componentId}`);
682-
await this.manager.deleteComponent(payload.componentId);
680+
private async handleDeleteComponent(payload: { componentId: string; deleteSourceCode?: boolean }): Promise<void> {
681+
await this.manager.deleteComponent(payload.componentId, payload.deleteSourceCode);
683682
// onComponentDeleted event will be routed back
684683
}
685684

extensions/roopik/src/roopikExtensionManager.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -427,13 +427,13 @@ export class RoopikExtensionManager implements vscode.Disposable {
427427
/**
428428
* Delete a component via Core's ComponentService
429429
*/
430-
public async deleteComponent(componentId: string): Promise<void> {
431-
this.logger.info(`Deleting component: ${componentId}`);
430+
public async deleteComponent(componentId: string, deleteSourceCode?: boolean): Promise<void> {
431+
const deleteSourceCodeValue = deleteSourceCode ?? false;
432432

433433
// TODO: Call Core via IPC
434-
// return this.componentClient.deleteComponent(componentId);
434+
// return this.componentClient.deleteComponent(componentId, deleteSourceCode);
435435

436-
await vscode.commands.executeCommand('roopik.core.deleteComponent', componentId);
436+
await vscode.commands.executeCommand('roopik.core.deleteComponent', componentId, deleteSourceCodeValue);
437437
}
438438

439439
/**

extensions/roopik/webview/src/canvasView/components/InfiniteCanvas/InfiniteCanvas.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,17 @@ export interface InfiniteCanvasProps {
3535
onSandboxClick: (id: string) => void;
3636
onSandboxDoubleClick: (id: string) => void;
3737
onSandboxUpdate: (id: string, updates: Partial<Sandbox>) => void;
38-
onSandboxDelete: (id: string) => void;
38+
onSandboxDelete: (id: string, deleteSourceCode?: boolean) => void;
3939
/** Called when user clicks code icon to view sandbox code */
4040
onSandboxShowCode: (id: string) => void;
4141
/** Called when user clicks reload icon to force rebuild */
4242
onSandboxRebuild: (id: string) => void;
4343
/** Called when clicking on canvas background (not on a sandbox) */
4444
onCanvasBackgroundClick?: () => void;
45+
/** Delete source code preference from parent */
46+
deleteSourceCodePref?: boolean;
47+
/** Callback when delete source code preference changes */
48+
onDeleteSourceCodePrefChange?: (value: boolean) => void;
4549
}
4650

4751
// ============================================================
@@ -64,10 +68,12 @@ interface SandboxLayerProps {
6468
onSandboxDragStart: (e: React.MouseEvent, sandboxId: string) => void;
6569
onSandboxClick: (id: string) => void;
6670
onSandboxDoubleClick: (id: string) => void;
67-
onSandboxDelete: (id: string) => void;
71+
onSandboxDelete: (id: string, deleteSourceCode?: boolean) => void;
6872
onSandboxShowCode: (id: string) => void;
6973
onSandboxRebuild: (id: string) => void;
7074
onSandboxUpdate: (id: string, updates: Partial<Sandbox>) => void;
75+
deleteSourceCodePref?: boolean;
76+
onDeleteSourceCodePrefChange?: (value: boolean) => void;
7177
}
7278

7379
/**
@@ -90,6 +96,8 @@ function SandboxLayer({
9096
onSandboxShowCode,
9197
onSandboxRebuild,
9298
onSandboxUpdate,
99+
deleteSourceCodePref,
100+
onDeleteSourceCodePrefChange
93101
}: SandboxLayerProps) {
94102
// Debug log for inspect mode
95103

@@ -122,10 +130,12 @@ function SandboxLayer({
122130
onMouseDown={(e) => onSandboxDragStart(e, sandbox.id)}
123131
onClick={() => onSandboxClick(sandbox.id)}
124132
onDoubleClick={() => onSandboxDoubleClick(sandbox.id)}
125-
onDelete={() => onSandboxDelete(sandbox.id)}
133+
onDelete={(deleteSourceCode) => onSandboxDelete(sandbox.id, deleteSourceCode)}
126134
onShowCode={() => onSandboxShowCode(sandbox.id)}
127135
onRebuild={() => onSandboxRebuild(sandbox.id)}
128136
onDeviceModeChange={(mode) => onSandboxUpdate(sandbox.id, { deviceMode: mode })}
137+
deleteSourceCodePref={deleteSourceCodePref}
138+
onDeleteSourceCodePrefChange={onDeleteSourceCodePrefChange}
129139
/>
130140
);
131141
})}
@@ -167,6 +177,8 @@ export function InfiniteCanvas({
167177
onSandboxShowCode,
168178
onSandboxRebuild,
169179
onCanvasBackgroundClick,
180+
deleteSourceCodePref,
181+
onDeleteSourceCodePrefChange,
170182
}: InfiniteCanvasProps) {
171183
const canvasRef = useRef<HTMLDivElement>(null);
172184

@@ -237,6 +249,8 @@ export function InfiniteCanvas({
237249
onSandboxShowCode={onSandboxShowCode}
238250
onSandboxRebuild={onSandboxRebuild}
239251
onSandboxUpdate={onSandboxUpdate}
252+
deleteSourceCodePref={deleteSourceCodePref}
253+
onDeleteSourceCodePrefChange={onDeleteSourceCodePrefChange}
240254
/>
241255
</div>
242256
</div>

0 commit comments

Comments
 (0)