Skip to content

feat: report a file's modified time through every listing that can - #104

Merged
DEENUU1 merged 1 commit into
mainfrom
feat/fileinfo-modified-at
Aug 16, 2026
Merged

feat: report a file's modified time through every listing that can#104
DEENUU1 merged 1 commit into
mainfrom
feat/fileinfo-modified-at

Conversation

@DEENUU1

@DEENUU1 DEENUU1 commented Aug 16, 2026

Copy link
Copy Markdown
Member

FileInfo gains an optional modified_at (ISO 8601, UTC), so a listing can say when a file changed instead of stopping at its size. The consumer that needs it is vstorm-co/agenticos#500 — the shared file viewer's header reads MD · 3 B · modified 2 minutes ago for a knowledge-base document and stops at the size for a workspace file, because this library's listings had no time to give.

Filled where a real timestamp exists, absent where none does:

  • StateBackendFileData already records modified_at on every write; the listing now surfaces it. A document persisted before the key existed lists None rather than inventing a time.
  • LocalBackendst_mtime, on ls and glob. A directory entry carries None.
  • Stored workspace archives (sandboxd)st_mtime through the wire. wire.FileEntry.modified_at defaults to None, so a client and a service on either side of this release keep understanding each other; a row from an older service validates to None.
  • KubernetesPodSandbox (http mode) — read from the in-pod server's row when it sends one.
  • Shell-derived listings (docker/daytona exec) stay absent: ls -la output has no timestamp that survives locale, busybox and timezone, and a guessed time is worse than none. FileInfo's docstring says to read the key with .get() and treat a missing one as unknown.

Additive only — the key is optional (total=False, matching the FileData split), so no existing constructor or consumer changes meaning.

Verified: 1670 tests, 100% coverage, ruff/pyright/mypy clean.

FileInfo gains an optional modified_at — ISO 8601, UTC — so a consumer
listing a workspace can say when a file changed instead of stopping at
its size. Downstream, vstorm-co/agenticos#500 is the file viewer header
that has nowhere to get one today.

Filled where a real timestamp exists, absent where none does:

- StateBackend: FileData already records modified_at on every write;
  the listing now surfaces it. A document persisted before the key
  existed lists None rather than inventing a time.
- LocalBackend: st_mtime, on ls and glob. A directory entry carries
  None — its mtime says when the directory changed, not any file.
- Stored workspace archives (sandboxd): st_mtime through the wire.
  wire.FileEntry.modified_at defaults to None, so a client and a
  service on either side of this release keep understanding each
  other; a row from an older service validates to None.
- KubernetesPodSandbox (http mode): read from the in-pod server's row
  when it sends one; the server ships with the user's image, so an
  older one simply does not.
- Shell-derived listings (docker/daytona exec) stay absent: ls -la
  output has no timestamp that survives locale, busybox and timezone,
  and a guessed time is worse than none.

1670 tests, 100% coverage, ruff/pyright/mypy clean.
@github-project-automation github-project-automation Bot moved this to Triage in Vstorm OSS Aug 16, 2026
@DEENUU1
DEENUU1 merged commit 60c70b2 into main Aug 16, 2026
15 checks passed
@DEENUU1
DEENUU1 deleted the feat/fileinfo-modified-at branch August 16, 2026 18:44
@DEENUU1 DEENUU1 mentioned this pull request Aug 16, 2026
DEENUU1 added a commit that referenced this pull request Aug 16, 2026
Cuts 0.2.26 for #104 — `FileInfo.modified_at`, an optional ISO 8601
timestamp on every listing that has a real one to give. Additive: the
key is optional and `wire.FileEntry` defaults it to `None`, so a client
and a service on either side of the release keep understanding each
other.

Version and changelog only. Verified on #104 before merge: 1670 tests,
100% coverage, ruff/pyright/mypy clean.
DEENUU1 added a commit to vstorm-co/agenticos that referenced this pull request Aug 16, 2026
The shared file viewer's header reads `MD · 3 B · modified 2 minutes
ago` — and the third part only ever appeared for a knowledge base
document. A workspace file, which is most of what people open, stopped
at the size. Not a viewer bug: `ViewerFile.modifiedAt` existed and the
header rendered it; the listing simply had no time to give.

**Upstream first.** `pydantic-ai-backend` 0.2.26
([vstorm-co/pydantic-ai-backend#104](vstorm-co/pydantic-ai-backend#104),
released) adds `FileInfo.modified_at` (ISO 8601, optional), filled where
a real timestamp exists: a stored workspace records one on every write
inside its JSONB document, a workspace archive reports `st_mtime`
through the wire, and a live container's shell listing honestly reports
none — `null` is the answer there, never a guess.
`wire.FileEntry.modified_at` defaults to `None`, so a client and a
sandboxd on either side of the release keep understanding each other.

**This PR carries it through:**

- Bumps the pin to `>=0.2.26`.
- `WorkspaceFileRead` (and `FlatFileRead` through it) gains
`modified_at: datetime | None` — the flat all-files listing gets the
field now because #138 sorts on it.
- The three listing routes pass `entry.get("modified_at")` through.
- `WorkspaceFile` / `ConversationFile` carry it into
`ViewerFile.modifiedAt` in the chat panel, the workspace explorer and
the flat browser.

**Verified:**

- An integration test proves the timestamp survives the JSONB round trip
through Postgres for a `state` workspace — the backend every deployment
has.
- An API test proves a row carrying a time serializes it and a legacy
row serializes `null`.
- A panel test proves the header now says `modified …` for a file the
agent wrote, opened from the chat panel.
- `make check` green (lint, backend 5281 tests at 100% platform
coverage, frontend gate, db-check, builds, audit).

No docs page describes listing rows field by field; the schema docstring
carries the reasoning.

Closes #500
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

1 participant