Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Examples: `fix(tui): simplify thinking toggle styling`, `docs: update contributi
- Rely on type inference when possible; avoid explicit type annotations or interfaces unless necessary for exports or clarity
- Prefer functional array methods (flatMap, filter, map) over for loops; use type guards on filter to maintain type inference downstream
- In `src/config`, follow the existing self-export pattern at the top of the file (for example `export * as ConfigAgent from "./agent"`) when adding a new config module.
- In Effect generators, bind services to named variables before calling methods. Do not use nested service yields such as `yield* (yield* Foo.Service).bar()`.

Reduce total variable count by inlining when a value is only used once.

Expand Down
36 changes: 27 additions & 9 deletions packages/core/src/control-plane/move-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,20 @@ export const layer = Layer.effect(
return yield* new DestinationProjectMismatchError({ expected: current.projectID, actual: destination.id })
}

const patch =
input.moveChanges && source.directory !== destination.directory
? yield* git
.patch(current.location.directory)
.pipe(Effect.mapError((error) => new CaptureChangesError({ message: error.message })))
: ""
const moveChanges = input.moveChanges && source.directory !== destination.directory
const sourceRepository = moveChanges ? yield* git.repo.discover(current.location.directory) : undefined
if (moveChanges && !sourceRepository)
return yield* new CaptureChangesError({ message: "Source is not a Git repository" })
const patch = sourceRepository
? yield* git.change
.capture({ repository: sourceRepository, path: current.location.directory })
.pipe(Effect.mapError((error) => new CaptureChangesError({ message: error.message })))
: Git.ChangeSet.make("")
if (patch) {
const repository = yield* git.repo.discover(directory)
if (!repository) return yield* new ApplyChangesError({ message: "Destination is not a Git repository" })
yield* git
.applyPatch({ directory, patch })
.change.apply({ repository, path: directory, changes: patch })
.pipe(Effect.mapError((error) => new ApplyChangesError({ message: error.message })))
}

Expand All @@ -104,7 +109,20 @@ export const layer = Layer.effect(
})

if (patch) {
yield* git.softResetChanges(current.location.directory).pipe(
const repository = yield* git.repo.discover(current.location.directory)
if (!repository)
return yield* new ResetSourceChangesError({
directory: current.location.directory,
message: "Source is not a Git repository",
})
yield* git.change
.discard({
repository,
path: current.location.directory,
index: "preserve",
untracked: "remove",
})
.pipe(
Effect.mapError(
(error) =>
new ResetSourceChangesError({
Expand All @@ -113,7 +131,7 @@ export const layer = Layer.effect(
cause: error.cause,
}),
),
)
)
}
})

Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * as File from "./file"

import { Revert } from "@opencode-ai/schema/revert"

export const Diff = Revert.FileDiff
export type Diff = typeof Diff.Type
2 changes: 1 addition & 1 deletion packages/core/src/filesystem/watcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export const layer = Layer.effect(
}

if (location.vcs?.type === "git") {
const resolved = yield* git.dir(location.directory)
const resolved = (yield* git.repo.discover(location.directory))?.gitDirectory
const vcs = resolved ? yield* fs.realPath(resolved).pipe(Effect.catch(() => Effect.succeed(resolved))) : undefined
if (vcs && !config.includes(".git") && !config.includes(vcs) && (!resolved || !config.includes(resolved))) {
const ignore = (yield* fs.readDirectoryEntries(vcs).pipe(Effect.catch(() => Effect.succeed([])))).flatMap(
Expand Down
Loading
Loading