Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changeset/session-workdir-resume-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---

Restore older working-directory sessions in `/sessions` and `kimi --continue`.
4 changes: 3 additions & 1 deletion apps/kimi-code/src/cli/v2/run-v2-print.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,9 @@ async function resolveNativeSession(

if (opts.continue) {
const page = await index.listRecent({});
const previous = page.items.find((summary) => summary.cwd === workDir);
const previous = page.items.find(
(summary) => summary.cwd !== undefined && resolve(summary.cwd) === resolve(workDir),
);
if (previous !== undefined) {
const session = await resumeById(previous.id);
const agentContext = await ensureMainAgent(session);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,20 @@ export class FileSessionIndex extends Disposable implements ISessionIndex {

async listRecent(query: SessionListQuery): Promise<Page<SessionSummary>> {
return this.withReadModel(
(generation) => this.listRecentFromReadModel(generation, query),
async (generation) => {
const page = await this.listRecentFromReadModel(generation, query);
// A workspace-scoped read that returns nothing can still hide sessions
// that exist on disk but were not projected into the read model (e.g.
// legacy/v1-era sessions recorded with only `workDir`, or sessions in
// alias buckets). Coalesce onto the authoritative source so `/sessions`
// (working-directory scope) and `--continue` never hide them. Unscooped
Comment on lines +302 to +306

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Move method-body narration into the file header

This newly added explanatory block sits inside listRecent and narrates the implementation, while the scoped v2 guide requires comments to live solely in the top-of-file /** */ block and describe external responsibilities. Remove the inline narration or fold the relevant responsibility-level context into the existing module header.

AGENTS.md reference: packages/agent-core-v2/AGENTS.md:L36-L38

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 67f00e0

// reads stay on the projected recency column.
if (page.items.length === 0 && query.workspaceIds !== undefined) {
Comment thread
creatiVision marked this conversation as resolved.
const legacy = await this.listLegacy(query);
if (legacy.items.length > 0) return legacy;
}
return page;
},
() => this.listLegacy(query),
);
}
Expand Down
16 changes: 16 additions & 0 deletions packages/agent-core-v2/test/app/sessionIndex/sessionIndex.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,22 @@ describe('FileSessionIndex (read model)', () => {
expect(fileStorage.listCalls).toBe(0);
});

it('coalesces a workspace-scoped miss onto the authoritative directory', async () => {
const store = build();
await store.prepare();
store.stopReconcileLoop();
// A legacy/v1-era session recorded with only `workDir` (no `cwd`) that
// exists on disk but was never projected into the read model.
await seedSession('legacy', { workDir: WORK_DIR, createdAt: 1, updatedAt: 2 });

// Read model answers empty for the workspace; the built-in fallback must
// surface the on-disk session so `/sessions` (cwd scope) and --continue
// do not hide it.
const page = await store.listRecent({ workspaceIds: [workspaceId] });
expect(page.items.map((s) => s.id)).toEqual(['legacy']);
expect(page.items[0]).toMatchObject({ cwd: WORK_DIR });
});

it('paginates exactly through same-millisecond ties', async () => {
const specs: [string, number][] = [
['a', 100],
Expand Down