Make origin session mirror opt-in per job.

Default mirrorToSession to false so cron summaries stay in run history unless the sidebar checkbox or mirror_to_session is enabled.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-09-08 21:00:20 +08:00
parent 933bad9201
commit 819feed310
10 changed files with 128 additions and 17 deletions

View file

@ -974,3 +974,58 @@ test('migrateJobOwners assigns unassigned for legacy jobs', async () => {
assert.equal(next.jobs[1].ownerEmpNo, 'from-session')
assert.equal(next.jobs[2].ownerEmpNo, 'u1')
})
test('session mirror is off by default and runs only when mirrorToSession is true', async (t) => {
const dir = await mkdtemp(join(tmpdir(), 'dsh-ops-cron-'))
t.after(() => rm(dir, { recursive: true, force: true }))
const appended = []
const agents = {
get(sessionId) {
if (sessionId !== 'origin-web') return null
return {
session: {
append(...args) { appended.push(args) },
},
}
},
}
const service = createTestHost({
filePath: join(dir, 'store.json'),
now: () => Date.parse('2026-08-24T01:00:00.000Z'),
getAgents: () => agents,
sessionPort: {
async createAndPrompt({ job }) {
return { sessionId: `run-${job.id}`, status: 'succeeded', summary: `done ${job.name}` }
},
async archiveSession() {},
},
})
const off = await service.createJob({
name: 'no-mirror',
prompt: 'p',
schedule: { kind: 'at', at: '2099-01-01T00:00:00.000Z', timezone: 'UTC' },
origin: { kind: 'web', sessionId: 'origin-web' },
})
assert.equal(off.mirrorToSession, false)
await service.dispatchRun(off.id, 'run-now')
assert.equal(appended.length, 0)
const on = await service.createJob({
name: 'with-mirror',
prompt: 'p',
schedule: { kind: 'at', at: '2099-01-02T00:00:00.000Z', timezone: 'UTC' },
origin: { kind: 'web', sessionId: 'origin-web' },
mirrorToSession: true,
})
assert.equal(on.mirrorToSession, true)
await service.dispatchRun(on.id, 'run-now')
assert.equal(appended.length, 1)
assert.match(appended[0][1].content[0].text, /with-mirror/)
const patched = await service.updateJob(off.id, { mirrorToSession: true })
assert.equal(patched.mirrorToSession, true)
await service.dispatchRun(off.id, 'run-now')
assert.equal(appended.length, 2)
})

View file

@ -45,6 +45,7 @@ test('installable bundle declares host apply, client half, unique id, and no @de
assert.match(host, /agentDefaultModel/)
assert.match(host, /deliverRunToIm/)
assert.match(host, /mirrorRunToSession/)
assert.match(host, /mirrorToSession/)
assert.match(host, /getAgents/)
assert.match(host, /PLUGIN_NAME = 'dsh-ops-cron'/)
assert.match(host, /API_PREFIX = '\/dsh-ops-cron'/)
@ -65,6 +66,7 @@ test('installable bundle declares host apply, client half, unique id, and no @de
assert.match(client, /ModelField/)
assert.match(client, /PresetField/)
assert.match(client, /agentPreset/)
assert.match(client, /mirrorToSession/)
assert.match(client, /inject = \['slots', 'locale', 'settingsScope'\]/)
const preset = await readFile(join(root, 'lib/preset.js'), 'utf8')
assert.match(preset, /resolveCreateAgentPreset/)

View file

@ -19,6 +19,27 @@ test('createJobRecord persists agentPreset', () => {
assert.equal(job.agentPreset, 'ops-desk')
})
test('createJobRecord defaults mirrorToSession off and accepts explicit true', () => {
const base = {
name: 'n',
prompt: 'p',
schedule: { kind: 'cron', expr: '0 9 * * *', timezone: 'Asia/Shanghai' },
}
assert.equal(createJobRecord(base, emptyState(), Date.now()).mirrorToSession, false)
assert.equal(
createJobRecord({ ...base, mirrorToSession: true }, emptyState(), Date.now()).mirrorToSession,
true,
)
assert.equal(
createJobRecord({ ...base, mirror_to_session: true }, emptyState(), Date.now()).mirrorToSession,
true,
)
assert.equal(
createJobRecord({ ...base, mirrorToSession: 'yes' }, emptyState(), Date.now()).mirrorToSession,
false,
)
})
test('resolveCreateAgentPreset prefers explicit then peer then session then host default', async () => {
assert.equal(
await resolveCreateAgentPreset({ agent_preset: 'explicit' }, {}, {}),