Skip to content

Commit 76a1410

Browse files
authored
chore: delete filetime module (#22999)
1 parent 4bd5a15 commit 76a1410

34 files changed

Lines changed: 59 additions & 766 deletions

File tree

.opencode/agent/translator.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,6 @@ OPENCODE_DISABLE_CLAUDE_CODE
594594
OPENCODE_DISABLE_CLAUDE_CODE_PROMPT
595595
OPENCODE_DISABLE_CLAUDE_CODE_SKILLS
596596
OPENCODE_DISABLE_DEFAULT_PLUGINS
597-
OPENCODE_DISABLE_FILETIME_CHECK
598597
OPENCODE_DISABLE_LSP_DOWNLOAD
599598
OPENCODE_DISABLE_MODELS_FETCH
600599
OPENCODE_DISABLE_PRUNE

packages/opencode/specs/effect/migration.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Use `InstanceState` (from `src/effect/instance-state.ts`) for services that need
99
Use `makeRuntime` (from `src/effect/run-service.ts`) to create a per-service `ManagedRuntime` that lazily initializes and shares layers via a global `memoMap`. Returns `{ runPromise, runFork, runCallback }`.
1010

1111
- Global services (no per-directory state): Account, Auth, AppFileSystem, Installation, Truncate, Worktree
12-
- Instance-scoped (per-directory state via InstanceState): Agent, Bus, Command, Config, File, FileTime, FileWatcher, Format, LSP, MCP, Permission, Plugin, ProviderAuth, Pty, Question, SessionStatus, Skill, Snapshot, ToolRegistry, Vcs
12+
- Instance-scoped (per-directory state via InstanceState): Agent, Bus, Command, Config, File, FileWatcher, Format, LSP, MCP, Permission, Plugin, ProviderAuth, Pty, Question, SessionStatus, Skill, Snapshot, ToolRegistry, Vcs
1313

1414
Rule of thumb: if two open directories should not share one copy of the service, it needs `InstanceState`.
1515

@@ -195,7 +195,6 @@ This checklist is only about the service shape migration. Many of these services
195195
- [x] `Config``config/config.ts`
196196
- [x] `Discovery``skill/discovery.ts` (dependency-only layer, no standalone runtime)
197197
- [x] `File``file/index.ts`
198-
- [x] `FileTime``file/time.ts`
199198
- [x] `FileWatcher``file/watcher.ts`
200199
- [x] `Format``format/index.ts`
201200
- [x] `Installation``installation/index.ts`
@@ -301,7 +300,6 @@ For each service, the migration is roughly:
301300
- `SessionRunState` — migrated 2026-04-11. Single caller in `server/instance/session.ts` converted; facade removed.
302301
- `Account` — migrated 2026-04-11. Callers in `server/instance/experimental.ts` and `cli/cmd/account.ts` converted; facade removed.
303302
- `Instruction` — migrated 2026-04-11. Test-only callers converted; facade removed.
304-
- `FileTime` — migrated 2026-04-11. Test-only callers converted; facade removed.
305303
- `FileWatcher` — migrated 2026-04-11. Callers in `project/bootstrap.ts` and test converted; facade removed.
306304
- `Question` — migrated 2026-04-11. Callers in `server/instance/question.ts` and test converted; facade removed.
307305
- `Truncate` — migrated 2026-04-11. Caller in `tool/tool.ts` and test converted; facade removed.

packages/opencode/src/effect/app-runtime.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { Account } from "@/account/account"
99
import { Config } from "@/config"
1010
import { Git } from "@/git"
1111
import { Ripgrep } from "@/file/ripgrep"
12-
import { FileTime } from "@/file/time"
1312
import { File } from "@/file"
1413
import { FileWatcher } from "@/file/watcher"
1514
import { Storage } from "@/storage"
@@ -58,7 +57,6 @@ export const AppLayer = Layer.mergeAll(
5857
Config.defaultLayer,
5958
Git.defaultLayer,
6059
Ripgrep.defaultLayer,
61-
FileTime.defaultLayer,
6260
File.defaultLayer,
6361
FileWatcher.defaultLayer,
6462
Storage.defaultLayer,

packages/opencode/src/file/time.ts

Lines changed: 0 additions & 113 deletions
This file was deleted.

packages/opencode/src/flag/flag.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ export const Flag = {
7070
OPENCODE_EXPERIMENTAL_OXFMT: OPENCODE_EXPERIMENTAL || truthy("OPENCODE_EXPERIMENTAL_OXFMT"),
7171
OPENCODE_EXPERIMENTAL_LSP_TY: truthy("OPENCODE_EXPERIMENTAL_LSP_TY"),
7272
OPENCODE_EXPERIMENTAL_LSP_TOOL: OPENCODE_EXPERIMENTAL || truthy("OPENCODE_EXPERIMENTAL_LSP_TOOL"),
73-
OPENCODE_DISABLE_FILETIME_CHECK: Config.boolean("OPENCODE_DISABLE_FILETIME_CHECK").pipe(Config.withDefault(false)),
7473
OPENCODE_EXPERIMENTAL_PLAN_MODE: OPENCODE_EXPERIMENTAL || truthy("OPENCODE_EXPERIMENTAL_PLAN_MODE"),
7574
OPENCODE_EXPERIMENTAL_MARKDOWN: !falsy("OPENCODE_EXPERIMENTAL_MARKDOWN"),
7675
OPENCODE_MODELS_URL: process.env["OPENCODE_MODELS_URL"],

packages/opencode/src/session/prompt.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import MAX_STEPS from "../session/prompt/max-steps.txt"
2323
import { ToolRegistry } from "../tool"
2424
import { MCP } from "../mcp"
2525
import { LSP } from "../lsp"
26-
import { FileTime } from "../file/time"
2726
import { Flag } from "../flag/flag"
2827
import { ulid } from "ulid"
2928
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"
@@ -94,7 +93,6 @@ export const layer = Layer.effect(
9493
const fsys = yield* AppFileSystem.Service
9594
const mcp = yield* MCP.Service
9695
const lsp = yield* LSP.Service
97-
const filetime = yield* FileTime.Service
9896
const registry = yield* ToolRegistry.Service
9997
const truncate = yield* Truncate.Service
10098
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner
@@ -1183,7 +1181,6 @@ NOTE: At any point in time through this workflow you should feel free to ask the
11831181
]
11841182
}
11851183

1186-
yield* filetime.read(input.sessionID, filepath)
11871184
return [
11881185
{
11891186
messageID: info.id,
@@ -1684,7 +1681,6 @@ export const defaultLayer = Layer.suspend(() =>
16841681
Layer.provide(Permission.defaultLayer),
16851682
Layer.provide(MCP.defaultLayer),
16861683
Layer.provide(LSP.defaultLayer),
1687-
Layer.provide(FileTime.defaultLayer),
16881684
Layer.provide(ToolRegistry.defaultLayer),
16891685
Layer.provide(Truncate.defaultLayer),
16901686
Layer.provide(Provider.defaultLayer),

packages/opencode/src/tool/edit.ts

Lines changed: 56 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { File } from "../file"
1414
import { FileWatcher } from "../file/watcher"
1515
import { Bus } from "../bus"
1616
import { Format } from "../format"
17-
import { FileTime } from "../file/time"
1817
import { Instance } from "../project/instance"
1918
import { Snapshot } from "@/snapshot"
2019
import { assertExternalDirectoryEffect } from "./external-directory"
@@ -44,7 +43,6 @@ export const EditTool = Tool.define(
4443
"edit",
4544
Effect.gen(function* () {
4645
const lsp = yield* LSP.Service
47-
const filetime = yield* FileTime.Service
4846
const afs = yield* AppFileSystem.Service
4947
const format = yield* Format.Service
5048
const bus = yield* Bus.Service
@@ -70,52 +68,11 @@ export const EditTool = Tool.define(
7068
let diff = ""
7169
let contentOld = ""
7270
let contentNew = ""
73-
yield* filetime.withLock(filePath, () =>
74-
Effect.gen(function* () {
75-
if (params.oldString === "") {
76-
const existed = yield* afs.existsSafe(filePath)
77-
contentNew = params.newString
78-
diff = trimDiff(createTwoFilesPatch(filePath, filePath, contentOld, contentNew))
79-
yield* ctx.ask({
80-
permission: "edit",
81-
patterns: [path.relative(Instance.worktree, filePath)],
82-
always: ["*"],
83-
metadata: {
84-
filepath: filePath,
85-
diff,
86-
},
87-
})
88-
yield* afs.writeWithDirs(filePath, params.newString)
89-
yield* format.file(filePath)
90-
yield* bus.publish(File.Event.Edited, { file: filePath })
91-
yield* bus.publish(FileWatcher.Event.Updated, {
92-
file: filePath,
93-
event: existed ? "change" : "add",
94-
})
95-
yield* filetime.read(ctx.sessionID, filePath)
96-
return
97-
}
98-
99-
const info = yield* afs.stat(filePath).pipe(Effect.catch(() => Effect.succeed(undefined)))
100-
if (!info) throw new Error(`File ${filePath} not found`)
101-
if (info.type === "Directory") throw new Error(`Path is a directory, not a file: ${filePath}`)
102-
yield* filetime.assert(ctx.sessionID, filePath)
103-
contentOld = yield* afs.readFileString(filePath)
104-
105-
const ending = detectLineEnding(contentOld)
106-
const old = convertToLineEnding(normalizeLineEndings(params.oldString), ending)
107-
const next = convertToLineEnding(normalizeLineEndings(params.newString), ending)
108-
109-
contentNew = replace(contentOld, old, next, params.replaceAll)
110-
111-
diff = trimDiff(
112-
createTwoFilesPatch(
113-
filePath,
114-
filePath,
115-
normalizeLineEndings(contentOld),
116-
normalizeLineEndings(contentNew),
117-
),
118-
)
71+
yield* Effect.gen(function* () {
72+
if (params.oldString === "") {
73+
const existed = yield* afs.existsSafe(filePath)
74+
contentNew = params.newString
75+
diff = trimDiff(createTwoFilesPatch(filePath, filePath, contentOld, contentNew))
11976
yield* ctx.ask({
12077
permission: "edit",
12178
patterns: [path.relative(Instance.worktree, filePath)],
@@ -125,26 +82,62 @@ export const EditTool = Tool.define(
12582
diff,
12683
},
12784
})
128-
129-
yield* afs.writeWithDirs(filePath, contentNew)
85+
yield* afs.writeWithDirs(filePath, params.newString)
13086
yield* format.file(filePath)
13187
yield* bus.publish(File.Event.Edited, { file: filePath })
13288
yield* bus.publish(FileWatcher.Event.Updated, {
13389
file: filePath,
134-
event: "change",
90+
event: existed ? "change" : "add",
13591
})
136-
contentNew = yield* afs.readFileString(filePath)
137-
diff = trimDiff(
138-
createTwoFilesPatch(
139-
filePath,
140-
filePath,
141-
normalizeLineEndings(contentOld),
142-
normalizeLineEndings(contentNew),
143-
),
144-
)
145-
yield* filetime.read(ctx.sessionID, filePath)
146-
}).pipe(Effect.orDie),
147-
)
92+
return
93+
}
94+
95+
const info = yield* afs.stat(filePath).pipe(Effect.catch(() => Effect.succeed(undefined)))
96+
if (!info) throw new Error(`File ${filePath} not found`)
97+
if (info.type === "Directory") throw new Error(`Path is a directory, not a file: ${filePath}`)
98+
contentOld = yield* afs.readFileString(filePath)
99+
100+
const ending = detectLineEnding(contentOld)
101+
const old = convertToLineEnding(normalizeLineEndings(params.oldString), ending)
102+
const next = convertToLineEnding(normalizeLineEndings(params.newString), ending)
103+
104+
contentNew = replace(contentOld, old, next, params.replaceAll)
105+
106+
diff = trimDiff(
107+
createTwoFilesPatch(
108+
filePath,
109+
filePath,
110+
normalizeLineEndings(contentOld),
111+
normalizeLineEndings(contentNew),
112+
),
113+
)
114+
yield* ctx.ask({
115+
permission: "edit",
116+
patterns: [path.relative(Instance.worktree, filePath)],
117+
always: ["*"],
118+
metadata: {
119+
filepath: filePath,
120+
diff,
121+
},
122+
})
123+
124+
yield* afs.writeWithDirs(filePath, contentNew)
125+
yield* format.file(filePath)
126+
yield* bus.publish(File.Event.Edited, { file: filePath })
127+
yield* bus.publish(FileWatcher.Event.Updated, {
128+
file: filePath,
129+
event: "change",
130+
})
131+
contentNew = yield* afs.readFileString(filePath)
132+
diff = trimDiff(
133+
createTwoFilesPatch(
134+
filePath,
135+
filePath,
136+
normalizeLineEndings(contentOld),
137+
normalizeLineEndings(contentNew),
138+
),
139+
)
140+
}).pipe(Effect.orDie)
148141

149142
const filediff: Snapshot.FileDiff = {
150143
file: filePath,

packages/opencode/src/tool/read.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { createInterface } from "readline"
77
import * as Tool from "./tool"
88
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
99
import { LSP } from "../lsp"
10-
import { FileTime } from "../file/time"
1110
import DESCRIPTION from "./read.txt"
1211
import { Instance } from "../project/instance"
1312
import { assertExternalDirectoryEffect } from "./external-directory"
@@ -31,7 +30,6 @@ export const ReadTool = Tool.define(
3130
const fs = yield* AppFileSystem.Service
3231
const instruction = yield* Instruction.Service
3332
const lsp = yield* LSP.Service
34-
const time = yield* FileTime.Service
3533
const scope = yield* Scope.Scope
3634

3735
const miss = Effect.fn("ReadTool.miss")(function* (filepath: string) {
@@ -75,9 +73,8 @@ export const ReadTool = Tool.define(
7573
).pipe(Effect.map((items: string[]) => items.sort((a, b) => a.localeCompare(b))))
7674
})
7775

78-
const warm = Effect.fn("ReadTool.warm")(function* (filepath: string, sessionID: Tool.Context["sessionID"]) {
76+
const warm = Effect.fn("ReadTool.warm")(function* (filepath: string) {
7977
yield* lsp.touchFile(filepath, false).pipe(Effect.ignore, Effect.forkIn(scope))
80-
yield* time.read(sessionID, filepath)
8178
})
8279

8380
const run = Effect.fn("ReadTool.execute")(function* (params: z.infer<typeof parameters>, ctx: Tool.Context) {
@@ -196,7 +193,7 @@ export const ReadTool = Tool.define(
196193
}
197194
output += "\n</content>"
198195

199-
yield* warm(filepath, ctx.sessionID)
196+
yield* warm(filepath)
200197

201198
if (loaded.length > 0) {
202199
output += `\n\n<system-reminder>\n${loaded.map((item) => item.content).join("\n\n")}\n</system-reminder>`

0 commit comments

Comments
 (0)