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
14 changes: 14 additions & 0 deletions .changeset/fix-migration-legacy-shared-slugify.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
"@moonshot-ai/agent-core": patch
"@moonshot-ai/kimi-code": patch
Comment on lines +2 to +3
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include the changed migrator package in the changeset

This changeset omits @moonshot-ai/migration-legacy even though the commit changes packages/migration-legacy/src/sessions/workdir-bucket.ts, so changeset version will not bump that package or update its changelog for the migrator output change. The repo's changeset rules require listing packages whose source/output changed, with @moonshot-ai/kimi-code added separately when the internal change enters the CLI bundle; please add the migrator package to the frontmatter.

Useful? React with 👍 / 👎.

"@moonshot-ai/migration-legacy": patch
---

fix(migration-legacy): use shared slugifyWorkDirName from agent-core

Exports `slugifyWorkDirName` from `@moonshot-ai/agent-core` and removes the
duplicate local implementation in `packages/migration-legacy/src/sessions/workdir-bucket.ts`.

No user-visible behavior change. The migrator now imports the canonical
slugifier, so migrated bucket names stay byte-identical to agent-core
without manual sync.
1 change: 1 addition & 0 deletions packages/agent-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export {
resolveGlobalLogPath,
} from './logging/logger';
export { resolveLoggingConfig } from './logging/resolve-config';
export { slugifyWorkDirName } from './utils/workdir-slug';
export type { ResolveLoggingInput } from './logging/resolve-config';
export type {
LogContext,
Expand Down
28 changes: 5 additions & 23 deletions packages/migration-legacy/src/sessions/workdir-bucket.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
import { basename, resolve } from 'node:path';
import { createHash } from 'node:crypto';

import { slugifyWorkDirName } from '@moonshot-ai/agent-core';

const WORKDIR_KEY_PREFIX = 'wd_';
const HASH_LENGTH = 12;

/**
* Compute the v2 bucket directory name `wd_<slug>_<hash12>` for a workdir
* path. Hash function and slug rules mirror
* `packages/kimi-core/src/utils/workdir-slug.ts` and
* `packages/kimi-core/src/harness/session-manager/workdir-key.ts:13–18`.
* path. Slug rules use `slugifyWorkDirName` from `@moonshot-ai/agent-core`
* (file: `packages/agent-core/src/utils/workdir-slug.ts`); hash and resolve
* logic mirror `packages/agent-core/src/harness/session-manager/workdir-key.ts`.
*
* IMPORTANT: agent-core's `encodeWorkDirKey` runs `resolve()` on the workdir
* before hashing/slugifying, and the session picker locates sessions purely
* by `readdir(encodeWorkDirKey(...))` — it never consults `session_index.jsonl`.
* We MUST apply the same `resolve()` here or migrated sessions become
* invisible in the picker.
*
* TODO: The canonical slugifier is `slugifyWorkDirName` in
* `@moonshot-ai/agent-core` (file: `src/utils/workdir-slug.ts`). It is not part
* of that package's public export surface today. When/if it becomes public,
* delete the local duplicate below and import it from agent-core directly so
* buckets stay byte-identical between the running app and this migrator.
*/
export function computeWorkdirBucket(workdirPath: string): string {
const normalized = resolve(workdirPath);
Expand All @@ -34,18 +30,4 @@ export function oldMd5BucketName(workdirPath: string): string {
return createHash('md5').update(workdirPath).digest('hex');
}

const MAX_WORKDIR_SLUG_LENGTH = 40;

/**
* Local copy of kimi-core's `slugifyWorkDirName`. Keep byte-identical to the
* canonical implementation in `packages/kimi-core/src/utils/workdir-slug.ts`.
*/
function slugifyWorkDirName(name: string): string {
const slug = name
.toLowerCase()
.replaceAll(/[^a-z0-9._-]+/g, '-')
.replaceAll(/^-+|-+$/g, '')
.slice(0, MAX_WORKDIR_SLUG_LENGTH)
.replaceAll(/^-+|-+$/g, '');
return slug === '' || slug === '.' || slug === '..' ? 'workspace' : slug;
}