Stamp and reclaim chat-created cron jobs for the current user.

Tool creates often left ownerEmpNo unassigned so the sidebar hid them while runs still fired; infer identity from session/cwd, claim legacy orphans on list, and keep cron rows visible without leaking run sessions into the workspace list.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-09-08 16:19:59 +08:00
parent d298c77f3f
commit a0dc070372
7 changed files with 254 additions and 25 deletions

View file

@ -110,3 +110,40 @@ export function viewerPayload(identity) {
workspacePath: identity.workspacePath || null,
}
}
/**
* Claim unassigned jobs that clearly belong to the viewer (origin session / cwd).
* Returns { state, changed }.
*/
export function claimUnassignedForViewer(state, identity, deps = {}) {
if (!identity?.empNo || canViewAllJobs(identity)) {
return { state, changed: false }
}
const jobs = Array.isArray(state?.jobs) ? state.jobs : []
let changed = false
const nextJobs = jobs.map((job) => {
if (!job || normalizeOwnerEmpNo(job.ownerEmpNo) !== UNASSIGNED_OWNER) return job
const sessionId = job.origin?.kind === 'web' && typeof job.origin.sessionId === 'string'
? job.origin.sessionId.trim()
: ''
let mine = false
// Prefer explicit session ownership / user-workspaces path — do not trust a loose isUserPath.
if (sessionId && typeof deps.getSessionOwner === 'function') {
mine = deps.getSessionOwner(sessionId) === identity.empNo
}
if (!mine && job.cwd) {
const norm = String(job.cwd).replace(/\\/g, '/')
const match = norm.match(/\/user-workspaces\/([^/]+)(?:\/|$)/)
mine = !!(match && decodeURIComponent(match[1]) === identity.empNo)
}
if (!mine) return job
changed = true
return {
...job,
ownerEmpNo: identity.empNo,
ownerDisplayName: identity.displayName || identity.empNo,
}
})
if (!changed) return { state, changed: false }
return { state: { ...state, jobs: nextJobs }, changed: true }
}