fix: stop skipping every WorkBuddy permission check in write mode

28127b3 added --dangerously-skip-permissions next to acceptEdits when a
conversation allows workspace writes. That flag lets the CLI run any
command and write anywhere on the machine without confirmation, which
goes beyond Meldwork's opt-in workspace-write boundary and differs from
every other Agent. Write mode now relies on acceptEdits, which accepts
file edits in the working directory.

The local machine has no CodeBuddy CLI, so an edit-only tool allowlist
was not added; an unverified flag could break every WorkBuddy turn.

Checks: new cli-adapters test for WorkBuddy write/read-only arguments;
WorkBuddy adapter and protocol tests (7 pass). Full desktop suite: 1537.
This commit is contained in:
Ryder Sun committed 2026-10-15 19:04:42 +08:00
1 parent 6e0becfb70
commit b2249f0859
2 files changed
+11 -1

No files matched your search

+3 -1
View File
@@ -145,8 +145,10 @@ function invocation(kind, executable, workdir, sessionRef = '', options = {}) {
'--print', '--print',
'--output-format', 'stream-json', '--output-format', 'stream-json',
'--include-partial-messages', '--include-partial-messages',
// Workspace write access means accepting file edits in the working
// directory. Skipping every permission check would also let the CLI
// run any command anywhere on the machine without confirmation.
'--permission-mode', options.sandbox === 'workspace-write' ? 'acceptEdits' : 'plan', '--permission-mode', options.sandbox === 'workspace-write' ? 'acceptEdits' : 'plan',
...(options.sandbox === 'workspace-write' ? ['--dangerously-skip-permissions'] : []),
...(maxTurns ? ['--max-turns', String(maxTurns)] : []), ...(maxTurns ? ['--max-turns', String(maxTurns)] : []),
...(sessionRef ? ['--resume', sessionRef] : []), ...(sessionRef ? ['--resume', sessionRef] : []),
], ],
@@ -1653,6 +1653,14 @@ test('Pi uses non-interactive JSON flags and keeps provider settings out of argu
assert.equal(typeof parsePiOutput, 'function') assert.equal(typeof parsePiOutput, 'function')
}) })
test('WorkBuddy write mode accepts edits without skipping every permission check', () => {
const writable = invocation('workbuddy', '/tmp/codebuddy', '/tmp', '', { sandbox: 'workspace-write' })
assert.equal(writable.args[writable.args.indexOf('--permission-mode') + 1], 'acceptEdits')
assert.equal(writable.args.includes('--dangerously-skip-permissions'), false)
const readOnly = invocation('workbuddy', '/tmp/codebuddy', '/tmp', '', { sandbox: 'read-only' })
assert.equal(readOnly.args[readOnly.args.indexOf('--permission-mode') + 1], 'plan')
})
test('Hermes forwards one image and rejects additional images instead of dropping them', () => { test('Hermes forwards one image and rejects additional images instead of dropping them', () => {
const first = path.resolve('diagram-one.png') const first = path.resolve('diagram-one.png')
const second = path.resolve('diagram-two.png') const second = path.resolve('diagram-two.png')