Commit Graph

34 Commits

Author SHA1 Message Date
Peter Steinberger 58025dd33c fix(fs): adopt fs-safe 0.5.2 untrusted filename sanitization (#119363)
* fix(fs): adopt fs-safe 0.5.2 untrusted filename sanitization

* fix(media): classify pre-open identity drift as access denial

* chore(checks): refresh SDK baseline and env-var budget for fs-safe adoption

* test(media): compact sanitizer cases under max-lines

* fix(agents): keep workspace symlink contract under fs-safe 0.5.2

* fix(infra): align path normalization and atomic-write proofs with fs-safe 0.5.2

* fix(fs): keep operator symlink contracts on config, control-ui, skills, hooks

* fix(fs): restore sandbox and session-lock contracts under fs-safe 0.5.2

* test(claws): expect symlink diagnostic for tampered plan parents

* fix(agents): canonicalize apply-patch mutations through contained aliases

* test(agents): split alias-update regression into focused file

---------

Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
2026-08-04 17:53:44 -07:00
Peter Steinberger 702e0277bd test(agents): realpath apply-patch temp dir fixture (#119353)
withTempDir used a raw fs.mkdtemp(os.tmpdir()) path. On macOS os.tmpdir()
is a /var -> /private/var symlink while the production sandbox guard
compares against canonical paths, so the symlink-delete test failed with
"Path escapes sandbox root". Realpath the mkdtemp result so the fixture
matches the canonical form the guard expects.

Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
2026-08-04 15:07:03 -07:00
Yuval Dinodia 8ce1e18d2f fix(agents): apply_patch rewrites bytes on hunk context lines (#116128)
* fix(agents): apply_patch rewrites bytes on hunk context lines

A fuzzy apply_patch update replaced the entire matched span with the
model-authored patch text, so trailing whitespace, typographic punctuation,
and tab indentation on lines the hunk marked as context were overwritten
while the tool reported plain success.

The parser now records which emitted lines came in as context and which old
line each one came from, and the update applier keeps the file's own bytes
for those lines. Added and removed lines are still written from the patch.

* test(agents): cover apply_patch context preservation

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 09:04:04 +08:00
Yuval Dinodia 8ae0a896bc fix(agents): apply_patch converts CRLF files to mixed line endings (#115943)
* fix(agents): preserve CRLF line endings in apply_patch update hunks

applyUpdateHunk split file contents on "\n" and rejoined with "\n", so
every line the hunk covered lost its carriage return, including the
context lines the patch declares unchanged. On a CRLF working tree a
one-line patch left a mixed-ending file on disk.

Detect the file line ending, run the hunk matcher on LF-normalized lines,
and restore the original ending on write. The line-ending helpers move
out of the edit tool into src/agents/line-endings.ts so both file-mutating
tools share one implementation.

* fix(agents): avoid normalizing mixed line endings

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 00:59:44 +08:00
Yuval Dinodia edf4aca7bc fix(agents): apply_patch destroys an existing file when a patch creates that path (#114911)
* fix(agents): stop apply_patch from silently overwriting existing files

An "*** Add File:" hunk wrote its target unconditionally. When the path
already existed, apply_patch replaced the entire file, returned Success,
and listed the path under "added", so neither the model nor the UI got
any signal that existing content had been destroyed. The "*** Move to:"
destination of an update hunk had the same gap and reported the clobbered
path as merely modified.

The add and move-to branches now check the destination through the patch
file ops before writing and fail closed when it exists. Routing the check
through fileOps keeps it correct on all three backends (workspace-scoped
fs-safe root, raw fs, sandbox bridge). The check runs per hunk in patch
order, so deleting a path earlier in the same patch and recreating it
still works.

* fix(agents): make apply_patch destination creation atomic

The previous guard checked that an add or move-to destination was absent
and then wrote it. A competing writer could create the path in that gap,
after which the write still replaced it, so the no-clobber guarantee did
not hold under contention.

Destination creation now goes through a single exclusive create-if-absent
operation on every patch backend: Root.create for the workspace-scoped
default, an O_EXCL write for the raw filesystem, and a new pinned create
operation in the sandbox mutation helper that opens the target with
O_CREAT|O_EXCL and reports a reserved exit code when it already exists.
PatchFileOps drops its separate existence check.

Resolving the host ops behind an early return removes the repeated
workspaceOnly branch inside each operation and the optional-call dance
that let a missing root silently skip a write.

* fix(agents): complete atomic apply-patch creation

* fix(agents): preserve raced create replacements

* fix(agents): handle fs-safe patch collisions

* fix(agents): publish sandbox creates atomically

* test(agents): cover exclusive create provenance rollback

* fix(agents): use typed exclusive-create signal

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-29 20:17:54 +08:00
Peter Steinberger b6bebfa73c fix(agents): prevent silent corruption when editing non-UTF-8 files (#115088) 2026-07-28 06:46:01 -04:00
Peter Steinberger 9497450511 refactor: eliminate dead-export baseline (#108376)
Burn the grandfathered unused-export baseline to zero and enforce a hard-zero Knip gate.
2026-07-15 17:05:07 +01:00
Vincent Koc 71e4ff5e80 refactor(agents): simplify apply patch matching (#105395) 2026-07-12 16:20:58 +02:00
zw-xysk ab966c214b fix(tools): treat no-op writes and edits as terminal tool-loop failures (fixes #96983) (#97044)
* fix(tools): treat no-op writes and edits as terminal tool-loop failures

Fixes #96983

* fix(tools): treat no-op writes and edits as terminal tool-loop failures

Fixes #96983

* fix(tools): preserve valid sibling edits in mixed no-op batches

Fixes #96983

* fix(tools): terminate apply_patch no-ops safely

* fix(tools): validate no-op edits independently

* fix(tools): preserve no-op edit overlap checks

* fix(tools): preserve no-op patch file formatting

* fix(tools): preserve move no-op formatting

* fix(tools): narrow same-path move no-op typing

* fix(tools): distinguish edit no-op errors

* fix(tools): keep edit previews aligned with execution

* fix(tools): align no-op validation and formatting

* fix(tools): preserve empty patch and preview no-ops

* fix(tools): preview fuzzy edit no-ops cleanly

* fix(tools): isolate fuzzy-equivalent edit no-ops

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-27 06:41:26 +08:00
Peter Steinberger f7ef52e66d docs: document apply patch helpers 2026-06-04 05:47:45 -04:00
Peter Steinberger 48f7db23f0 fix: harden clawpatch-reported edge cases 2026-05-18 03:18:55 +01:00
Vincent Koc 43c53174c5 fix(agents): harden spawn cleanup and patch paths 2026-05-17 01:42:19 +08:00
Vincent Koc c04bbd3cbb fix(agents): allow dot-prefixed sandbox paths 2026-05-14 12:52:24 +08:00
Peter Steinberger 8a8c3d7fa3 test: tighten apply patch assertions 2026-05-09 16:57:52 +01:00
Peter Steinberger 9ef37d1907 test: tighten assertions and harness coverage 2026-05-08 05:28:12 +01:00
Peter Steinberger 777c539daf fix: harden sandboxed patch parent paths 2026-05-06 04:44:14 +01:00
Peter Steinberger 8294229592 test: refresh fs-safe boundary expectations 2026-05-06 02:50:36 +01:00
Peter Steinberger 538605ff44 [codex] Extract filesystem safety primitives (#77918)
* refactor: extract filesystem safety primitives

* refactor: use fs-safe for file access helpers

* refactor: reuse fs-safe for media reads

* refactor: use fs-safe for image reads

* refactor: reuse fs-safe in qqbot media opener

* refactor: reuse fs-safe for local media checks

* refactor: consume cleaner fs-safe api

* refactor: align fs-safe json option names

* fix: preserve fs-safe migration contracts

* refactor: use fs-safe primitive subpaths

* refactor: use grouped fs-safe subpaths

* refactor: align fs-safe api usage

* refactor: adapt private state store api

* chore: refresh proof gate

* refactor: follow fs-safe json api split

* refactor: follow reduced fs-safe surface

* build: default fs-safe python helper off

* fix: preserve fs-safe plugin sdk aliases

* refactor: consolidate fs-safe usage

* refactor: unify fs-safe store usage

* refactor: trim fs-safe temp workspace usage

* refactor: hide low-level fs-safe primitives

* build: use published fs-safe package

* fix: preserve outbound recovery durability after rebase

* chore: refresh pr checks
2026-05-06 02:15:17 +01:00
Peter Steinberger 2c814d33e6 perf(test): slim bash tool imports 2026-04-20 12:26:39 +01:00
Peter Steinberger ecfd6cfa73 test: drop redundant apply patch absolute write 2026-04-18 23:34:49 +01:00
Peter Steinberger 16bd427cb6 test: speed apply-patch and exec approval hotspots 2026-04-18 18:33:16 +01:00
Jacob Tomlinson 32a4a47d60 Agents: pin apply-patch workspace mutations (#56016)
* Agents: pin apply-patch file ops to workspace

* Agents: resolve apply-patch review feedback

* Infra: fallback pinned path helper spawn failures
2026-03-30 16:49:49 +01:00
Peter Steinberger 3fac0d11fa test: fix base vitest thread regressions 2026-03-22 23:37:31 -07:00
Peter Steinberger ae7f18e503 feat: add remote openshell sandbox mode 2026-03-15 20:28:19 -07:00
Vincent Koc 8e97b752d0 Tools: revalidate workspace-only patch targets (#46803)
* Tools: revalidate workspace-only patch targets

* Tests: narrow apply-patch delete-path assertion
2026-03-15 09:45:58 -07:00
Artale 1b462ed174 fix(test): use NTFS junctions and platform guards for symlink tests on Windows (openclaw#28747) thanks @arosstale
Verified:
- pnpm install --frozen-lockfile
- pnpm test src/agents/apply-patch.test.ts src/agents/sandbox/fs-bridge.test.ts src/agents/sandbox/validate-sandbox-security.test.ts src/infra/archive.test.ts

Co-authored-by: arosstale <117890364+arosstale@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-02 10:45:19 -06:00
Peter Steinberger 4fd29a35bb fix: block broken-symlink sandbox path escapes 2026-02-26 13:30:45 +01:00
Peter Steinberger 04d91d0319 fix(security): block workspace hardlink alias escapes 2026-02-26 03:42:54 +01:00
Peter Steinberger fcb86408fd test: move embedded and tool agent suites out of e2e 2026-02-22 11:17:47 +00:00
Peter Steinberger 9131b22a28 test: migrate suites to e2e coverage layout 2026-02-13 14:28:22 +00:00
cpojer f06dd8df06 chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
Peter Steinberger 9a7160786a refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
Peter Steinberger 6d16a658e5 refactor: rename clawdbot to moltbot with legacy compat 2026-01-27 12:21:02 +00:00
Peter Steinberger 8b4bdaa8a4 feat: add apply_patch tool (exec-gated) 2026-01-12 03:42:56 +00:00