Skip to content

feat(kiloclaw): workspace file editor for /root/.openclaw/#1140

Merged
iscekic merged 70 commits intomainfrom
feat/workspace-file-editor
Mar 18, 2026
Merged

feat(kiloclaw): workspace file editor for /root/.openclaw/#1140
iscekic merged 70 commits intomainfrom
feat/workspace-file-editor

Conversation

@iscekic
Copy link
Contributor

@iscekic iscekic commented Mar 16, 2026

Summary

  • Replace the single-file "Edit Config" button with a full file browser and editor for the /root/.openclaw/ directory tree
  • Users can browse, view, and edit all workspace files (SOUL.md, AGENTS.md, credentials, openclaw.json, etc.) from the dashboard
  • Admin panel gets the same file editor for any user's instance
  • File tree with expand/collapse (collapsed by default), Monaco editor with language detection, diff toggle, ETag-based conflict detection, unsaved changes guard

Changes

Controller (kiloclaw/controller/)

  • New endpoints: /_kilo/files/tree, /_kilo/files/read, /_kilo/files/write
  • safe-path.ts: path traversal protection (rejects .., absolute paths, null bytes, symlink escapes via verifyCanonicalized)
  • backup-file.ts: pre-write backups to .kilo-backups/ directory with sanitized filenames (path/to/file.md.kilo-backups/path__to__file.md.<timestamp>.bak), 5-backup rotation
  • atomic-write.ts: temp file + rename for crash-safe writes
  • No file filtering — users see the full tree including credentials

tRPC router (src/routers/kiloclaw-router.ts)

  • fileTree, readFile, writeFile procedures behind clawAccessProcedure (billing gate)
  • openclaw.json write validates JSON object shape (server-side + client-side)
  • No secret redaction — users own their secrets
  • handleFileOperationError maps controller 400/404/409 to proper tRPC error codes

Admin (src/routers/admin-kiloclaw-instances-router.ts)

  • Admin file endpoints behind adminProcedure — same unfiltered access

UI

  • FileTree: collapsible directory tree, directories collapsed by default
  • FileEditorPane: Monaco editor with diff view, ETag conflict detection, optimistic save updates
  • FileEditorShell: resizable sidebar, unsaved-changes confirmation dialog, min-height 500px
  • WorkspaceFileEditor / AdminFileEditor: wiring for user and admin contexts
  • SettingsTab: "Edit Files" button is open-only (closing goes through unsaved-changes guard)

Test plan

  • Kiloclaw controller tests pass (836/836)
  • Full typecheck clean across all packages
  • Lint clean
  • Navigate to claw dashboard Settings → "Edit Files"
  • File tree loads showing full /root/.openclaw/ contents (including credentials, .kilo-backups)
  • Directories collapsed by default, expand on click
  • Click a file → editor opens with correct syntax highlighting
  • Edit content → "modified" indicator appears
  • "Show diff" toggle works
  • Save → success toast, ETag updated
  • Discard → reverts to server content
  • Switch files with unsaved changes → confirmation dialog
  • Edit openclaw.json → validates JSON object before saving
  • ETag conflict → preserves user edits, shows diff against server version
  • Admin panel: can browse and edit any user's files

@iscekic iscekic self-assigned this Mar 16, 2026
@kilo-code-bot
Copy link
Contributor

kilo-code-bot bot commented Mar 16, 2026

Code Review Summary

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
src/routers/kiloclaw-router.ts 956 User file reads now expose raw openclaw.json / credentials/ secrets to the browser.
src/routers/admin-kiloclaw-instances-router.ts 486 Admin writeFile lacks server-side openclaw.json JSON/object validation.
Other Observations (not in diff)

No additional summary-only issues.

Files Reviewed (29 files)
  • kiloclaw/controller/src/backup-file.test.ts - 0 issues
  • kiloclaw/controller/src/backup-file.ts - 0 issues
  • kiloclaw/controller/src/index.ts - 0 issues
  • kiloclaw/controller/src/routes/files.test.ts - 0 issues
  • kiloclaw/controller/src/routes/files.ts - 0 issues
  • kiloclaw/controller/src/safe-path.test.ts - 0 issues
  • kiloclaw/controller/src/safe-path.ts - 0 new issues
  • kiloclaw/src/durable-objects/kiloclaw-instance/gateway.ts - 0 issues
  • kiloclaw/src/durable-objects/kiloclaw-instance/index.ts - 0 issues
  • kiloclaw/src/routes/platform.ts - 0 issues
  • src/app/(app)/claw/components/FileEditorPane.tsx - 0 issues
  • src/app/(app)/claw/components/FileEditorShell.tsx - 0 issues
  • src/app/(app)/claw/components/FileTree.tsx - 0 issues
  • src/app/(app)/claw/components/OpenclawConfigEditor.tsx - 0 issues
  • src/app/(app)/claw/components/SettingsTab.tsx - 0 issues
  • src/app/(app)/claw/components/WorkspaceFileEditor.tsx - 0 issues
  • src/app/(app)/claw/components/changelog-data.ts - 0 issues
  • src/app/(app)/claw/components/validateOpenclawJson.ts - 0 issues
  • src/app/(app)/claw/components/withStatusQueryBoundary.test.ts - 0 issues
  • src/app/admin/components/KiloclawInstances/AdminFileEditor.tsx - 0 issues
  • src/app/admin/components/KiloclawInstances/KiloclawInstanceDetail.tsx - 0 issues
  • src/hooks/useKiloClaw.ts - 0 issues
  • src/hooks/useResizableSidebar.ts - 0 issues
  • src/lib/kiloclaw/config-redaction.test.ts - 0 issues
  • src/lib/kiloclaw/config-redaction.ts - 0 issues
  • src/lib/kiloclaw/kiloclaw-internal-client.ts - 0 issues
  • src/lib/kiloclaw/types.ts - 0 issues
  • src/routers/admin-kiloclaw-instances-router.ts - 1 issue
  • src/routers/kiloclaw-router.ts - 1 issue

Fix these issues in Kilo Cloud


Reviewed by gpt-5.4-20260305 · 2,349,190 tokens

- buildTree: skip unreadable directories instead of crashing
- buildTree: filter files by allowed extensions to avoid info disclosure
- backupFile: wrap in try/catch so backup failures don't block writes
iscekic added 3 commits March 16, 2026 21:08
… validation

- Close button now prompts when unsaved changes exist (same dialog as file switch)
- After save, use savedContentRef to avoid flashing stale content while query refetches
- Server-side validation rejects non-object JSON for openclaw.json writes
- resolveSafePath/verifyCanonicalized now check all path segments for
  'credentials', not just the first — prevents access to nested
  credentials dirs like workspace/credentials/key.json
- backupFile test now includes the newly created backup in the mock
  directory listing to match real call order (copyFileSync before
  readdirSync)
…, handle corrupt openclaw.json

- Add unit tests for verifyCanonicalized (symlink escape, credentials
  at any depth)
- Wrap onDirtyChange in useCallback to prevent unnecessary effect
  firings on parent re-renders
- readFile tRPC: return raw content when openclaw.json is unparseable
  instead of 500, so the user can fix it in the editor
…ding

On file_etag_conflict, keep editedContent and show diff view so the user
can compare their version against the server's, instead of silently
clearing their work.
…ave path

- Add redactRawText() for regex-based secret redaction when JSON.parse
  fails, so broken openclaw.json doesn't leak raw API keys to the browser
- Handle broken current file in save path — skip secret restoration when
  on-disk JSON is unparseable so the user can actually save their repair
iscekic added 2 commits March 16, 2026 22:47
Remove redactRawText and broken-file save workaround. Both read and
write paths now throw a clear error directing users to contact support
when openclaw.json contains invalid JSON.
…ditor

# Conflicts:
#	src/routers/kiloclaw-router.ts
iscekic added 4 commits March 17, 2026 17:57
Only treat bare 404s (no error code) as "unknown route" from old
controllers. 404s with a specific code like file_not_found should
propagate so callers get the correct error instead of "controller too old".
Wrap atomicWrite in try-catch to return a structured 500 response on
write failure (disk full, permissions) instead of an unhandled exception.
…coded string

Export BLOCKED_SEGMENTS from safe-path and use it in buildTree's
directory filter to maintain a single source of truth for blocked paths.
Add explicit check for '..' and '.' path segments at the tRPC layer
so path traversal attempts are rejected before reaching the controller.
iscekic added a commit that referenced this pull request Mar 17, 2026
The credentials directory was blocked at both the controller level
(BLOCKED_SEGMENTS in safe-path) and the Next.js router level
(USER_FILTERED_DIRS). Remove both layers so users can see and
access credentials folders in the workspace file editor.

Closes #1140
iscekic added 2 commits March 17, 2026 18:27
The credentials directory was blocked at both the controller level
(BLOCKED_SEGMENTS in safe-path) and the Next.js router level
(USER_FILTERED_DIRS). Remove both layers so users can see and
access credentials folders in the workspace file editor.
Move backup files from alongside the original file to a centralized
.kilo-backups folder at the root. Backup filenames use sanitized
paths (slashes replaced with __) with format: name.timestamp.bak
@iscekic iscekic force-pushed the feat/workspace-file-editor branch from 23b8a11 to 26cde25 Compare March 17, 2026 17:28
Users now see the full unfiltered tree and can read/write any file
the controller allows. The controller's resolveSafePath already
handles path traversal protection.
@iscekic iscekic force-pushed the feat/workspace-file-editor branch from 7189460 to a2f2241 Compare March 17, 2026 17:45
iscekic added 2 commits March 17, 2026 18:55
Backup copies of openclaw.json (.kilo-backups/openclaw.json.*.bak)
now go through the same secret redaction as the original file.

Also make the Edit Files button open-only so closing goes through
the unsaved-changes confirmation dialog.
Users own their secrets — no need to redact them in their own editor.
This removes the redact-on-read / restore-on-write dance, simplifying
both the read and write paths for openclaw.json.
@iscekic iscekic enabled auto-merge March 18, 2026 10:47
@iscekic iscekic merged commit c74572f into main Mar 18, 2026
32 of 33 checks passed
@iscekic iscekic deleted the feat/workspace-file-editor branch March 18, 2026 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants