Repository navigation
Conversation
Default spawns to the session project and inject the V2 plugin location into tool contexts. Relative workdirs now resolve against the project; explicit directory permission checks receive the resolved absolute path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pty_spawnignores the project directory of the session. Aworkdiris used exactly as typed, and when it is left out the PTY starts in the directory of the host process. In V2 the tool context has no directory at all. The directory permission check also receives the raw string, so it answers wrongly in both directions (see Cause).In plain terms: when an agent asks for a terminal in
src, the plugin does not know which projectsrcbelongs to. It can start the terminal in the wrong place, refuse a folder that is inside the project, or let through a path that climbs out of it. Now every working directory is resolved against the session's project first.Cause
execute()passedargs.workdirstraight tomanager.spawn(), which falls back toprocess.cwd()when it is undefined (session-lifecycle.ts:59).checkWorkdirPermission()got the same raw string.V1PermissionAuthorizer.checkWorkdirdecides withworkdir.startsWith(project), so a relativesrcnever matches the absolute project path, and/project/../../etcdoes.registerV2Tools()handed the host's tool context to each tool unchanged. In V2 that context has nodirectory; the project is onctx.location.directory. There was nothing to resolve against.I called
ptySpawn.executewithmanager.spawnstubbed,external_directory: "deny"and the project at/tmp/proj:src/tmp/proj/src/tmp/proj/../../etc/tmp/proj/../../etc/tmp/proj/src/tmp/projChanges
spawn.ts:workdir = resolve(ctx.directory ?? '', args.workdir ?? ''). The permission check (still only when a workdir was given) andmanager.spawnboth receive the resolved absolute path.v2/index.ts: readlocation.directorybefore registering the tools and pass it toregisterV2Tools. The block only moves up.v2/tools.ts:registerV2Tools(draft, directory?)fillsdirectoryinto the context it hands to each tool. Adirectorythe host already provides wins.Behavior changes
workdiris relative to the session project, not to the host process.workdirstarts the PTY in the session project instead of the host's current directory. Where the two are the same directory, nothing changes.permission.external_directory: "deny", aworkdirinside the project is no longer refused for being relative, and one that climbs out with..is now refused.Validation
Two new tests:
test/pty-tools.test.tschecks that a relativeworkdiris resolved before the permission check and the spawn, andtest/v2.test.tschecks that the project directory reaches a tool context that has none. One existing test changes: the minimal spawn case now expects the context directory asworkdirinstead ofundefined.With
srcreset to main and the tests from this branch, those three tests fail. Replacing theresolve(...)with the rawargs.workdirfails the twopty-toolstests, and removing the injection intools.tsfails the V2 test.bun testovertest/*.test.ts, without the npm-pack and live suites, gives 186 passing.bun run typecheck,bun run lintandbunx biome format .are clean. The CI workflow passes on this commit in my fork, including the Playwright e2e. I did not run it against a live V2 host.Diff
Production: +5 lines (+15/-10) in
src/plugin/pty/tools/spawn.ts,src/v2/index.tsandsrc/v2/tools.ts.Tests: +56 lines (+59/-3) in
test/pty-tools.test.tsandtest/v2.test.ts.