feat(02-02): update resolveDefaultAgentWorkspaceDir to use slugified agent names
- Change signature from (agentId: string) to (agent: { id: string; name?: string | null })
- Use sanitizeFriendlyPathSegment(name) for human-readable workspace dirs
- Fall back to sanitized id when name is empty/null
- Update all 4 call sites in heartbeat.ts with { id, name } objects
- Add agentName field to resolveRuntimeSessionParamsForWorkspace input type
- Update both test call sites in heartbeat-workspace-session.test.ts
This commit is contained in:
parent
e803935b33
commit
09343ad034
3 changed files with 16 additions and 13 deletions
|
|
@ -59,7 +59,7 @@ function buildAgent(adapterType: string, runtimeConfig: Record<string, unknown>
|
|||
describe("resolveRuntimeSessionParamsForWorkspace", () => {
|
||||
it("migrates fallback workspace sessions to project workspace when project cwd becomes available", () => {
|
||||
const agentId = "agent-123";
|
||||
const fallbackCwd = resolveDefaultAgentWorkspaceDir(agentId);
|
||||
const fallbackCwd = resolveDefaultAgentWorkspaceDir({ id: agentId });
|
||||
|
||||
const result = resolveRuntimeSessionParamsForWorkspace({
|
||||
agentId,
|
||||
|
|
@ -100,7 +100,7 @@ describe("resolveRuntimeSessionParamsForWorkspace", () => {
|
|||
|
||||
it("does not migrate when resolved workspace id differs from previous session workspace id", () => {
|
||||
const agentId = "agent-123";
|
||||
const fallbackCwd = resolveDefaultAgentWorkspaceDir(agentId);
|
||||
const fallbackCwd = resolveDefaultAgentWorkspaceDir({ id: agentId });
|
||||
|
||||
const result = resolveRuntimeSessionParamsForWorkspace({
|
||||
agentId,
|
||||
|
|
|
|||
|
|
@ -73,12 +73,13 @@ export function resolveDefaultBackupDir(): string {
|
|||
return path.resolve(resolvePaperclipInstanceRoot(), "data", "backups");
|
||||
}
|
||||
|
||||
export function resolveDefaultAgentWorkspaceDir(agentId: string): string {
|
||||
const trimmed = agentId.trim();
|
||||
if (!PATH_SEGMENT_RE.test(trimmed)) {
|
||||
throw new Error(`Invalid agent id for workspace path '${agentId}'.`);
|
||||
}
|
||||
return path.resolve(resolvePaperclipInstanceRoot(), "workspaces", trimmed);
|
||||
// [nexus] Accept agent object for human-readable slugified workspace dirs
|
||||
export function resolveDefaultAgentWorkspaceDir(agent: { id: string; name?: string | null }): string {
|
||||
// Use slugified name for human-readable dirs; fall back to sanitized id
|
||||
const segment = agent.name?.trim()
|
||||
? sanitizeFriendlyPathSegment(agent.name, agent.id)
|
||||
: sanitizeFriendlyPathSegment(agent.id, agent.id);
|
||||
return path.resolve(resolvePaperclipInstanceRoot(), "workspaces", segment);
|
||||
}
|
||||
|
||||
function sanitizeFriendlyPathSegment(value: string | null | undefined, fallback = "_default"): string {
|
||||
|
|
|
|||
|
|
@ -525,10 +525,11 @@ export function parseSessionCompactionPolicy(agent: typeof agents.$inferSelect):
|
|||
|
||||
export function resolveRuntimeSessionParamsForWorkspace(input: {
|
||||
agentId: string;
|
||||
agentName?: string | null; // [nexus] added for slug workspace dirs
|
||||
previousSessionParams: Record<string, unknown> | null;
|
||||
resolvedWorkspace: ResolvedWorkspaceForRun;
|
||||
}) {
|
||||
const { agentId, previousSessionParams, resolvedWorkspace } = input;
|
||||
const { agentId, agentName, previousSessionParams, resolvedWorkspace } = input;
|
||||
const previousSessionId = readNonEmptyString(previousSessionParams?.sessionId);
|
||||
const previousCwd = readNonEmptyString(previousSessionParams?.cwd);
|
||||
if (!previousSessionId || !previousCwd) {
|
||||
|
|
@ -550,7 +551,7 @@ export function resolveRuntimeSessionParamsForWorkspace(input: {
|
|||
warning: null as string | null,
|
||||
};
|
||||
}
|
||||
const fallbackAgentHomeCwd = resolveDefaultAgentWorkspaceDir(agentId);
|
||||
const fallbackAgentHomeCwd = resolveDefaultAgentWorkspaceDir({ id: agentId, name: agentName });
|
||||
if (path.resolve(previousCwd) !== path.resolve(fallbackAgentHomeCwd)) {
|
||||
return {
|
||||
sessionParams: previousSessionParams,
|
||||
|
|
@ -1295,7 +1296,7 @@ export function heartbeatService(db: Db) {
|
|||
missingProjectCwds.push(projectCwd);
|
||||
}
|
||||
|
||||
const fallbackCwd = resolveDefaultAgentWorkspaceDir(agent.id);
|
||||
const fallbackCwd = resolveDefaultAgentWorkspaceDir({ id: agent.id, name: agent.name });
|
||||
await fs.mkdir(fallbackCwd, { recursive: true });
|
||||
const warnings: string[] = [];
|
||||
if (preferredWorkspaceWarning) {
|
||||
|
|
@ -1364,7 +1365,7 @@ export function heartbeatService(db: Db) {
|
|||
}
|
||||
}
|
||||
|
||||
const cwd = resolveDefaultAgentWorkspaceDir(agent.id);
|
||||
const cwd = resolveDefaultAgentWorkspaceDir({ id: agent.id, name: agent.name });
|
||||
await fs.mkdir(cwd, { recursive: true });
|
||||
const warnings: string[] = [];
|
||||
if (sessionCwd) {
|
||||
|
|
@ -2391,6 +2392,7 @@ export function heartbeatService(db: Db) {
|
|||
}
|
||||
const runtimeSessionResolution = resolveRuntimeSessionParamsForWorkspace({
|
||||
agentId: agent.id,
|
||||
agentName: agent.name, // [nexus] pass agent name for slug workspace dirs
|
||||
previousSessionParams,
|
||||
resolvedWorkspace: {
|
||||
...resolvedWorkspace,
|
||||
|
|
@ -2422,7 +2424,7 @@ export function heartbeatService(db: Db) {
|
|||
branchName: executionWorkspace.branchName,
|
||||
worktreePath: executionWorkspace.worktreePath,
|
||||
agentHome: await (async () => {
|
||||
const home = resolveDefaultAgentWorkspaceDir(agent.id);
|
||||
const home = resolveDefaultAgentWorkspaceDir({ id: agent.id, name: agent.name });
|
||||
await fs.mkdir(home, { recursive: true });
|
||||
return home;
|
||||
})(),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue