mirror of
https://github.com/hansjone/dsh-ops-cron.git
synced 2026-10-10 05:53:24 +08:00
Add sidebar run permission preset for scheduled jobs.
Default inherits Host new-session access mode; humans can raise to workspace-write or full access. Agents never see or set the field. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
ad6e90f197
commit
8cf624ce7f
8 changed files with 140 additions and 4 deletions
|
|
@ -596,6 +596,51 @@ test('makeLiveSessionPort creates with default model and setup', async () => {
|
|||
assert.equal(assembled.variables.model, 'deepseek-chat')
|
||||
})
|
||||
|
||||
test('makeLiveSessionPort applies job permissionPreset when Host supports it', async () => {
|
||||
const applied = []
|
||||
const fakeSession = { id: 'sess-perm' }
|
||||
const ctx = {
|
||||
get(name) {
|
||||
if (name === 'agentDefaultModel') {
|
||||
return { currentSelection: () => ({ provider: 'deepseek', model: 'deepseek-chat' }) }
|
||||
}
|
||||
if (name === 'permissionPresets') {
|
||||
return {
|
||||
set(session, preset) {
|
||||
applied.push({ session, preset })
|
||||
},
|
||||
}
|
||||
}
|
||||
if (name === 'agents') {
|
||||
return {
|
||||
async create() {
|
||||
const agent = createFakeAgent()
|
||||
agent.session = fakeSession
|
||||
return { agent, dispose: async () => {} }
|
||||
},
|
||||
get() {},
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
}
|
||||
const port = makeLiveSessionPort(ctx)
|
||||
await port.createAndPrompt({
|
||||
job: { name: 'elevated', timeoutMinutes: 1, permissionPreset: 'danger-full-access' },
|
||||
run: {},
|
||||
text: 'hi',
|
||||
})
|
||||
assert.deepEqual(applied, [{ session: fakeSession, preset: 'danger-full-access' }])
|
||||
|
||||
applied.length = 0
|
||||
await port.createAndPrompt({
|
||||
job: { name: 'default', timeoutMinutes: 1, permissionPreset: '' },
|
||||
run: {},
|
||||
text: 'hi',
|
||||
})
|
||||
assert.deepEqual(applied, [])
|
||||
})
|
||||
|
||||
test('resolveDefaultModel fails loud when Models has no selection', async () => {
|
||||
await assert.rejects(
|
||||
() => resolveDefaultModel({ get: () => undefined }, { waitMs: 0 }),
|
||||
|
|
|
|||
|
|
@ -473,13 +473,15 @@ test('agentAccess deny is hidden from tools and blocks pause/delete', async (t)
|
|||
timezone: 'Asia/Shanghai',
|
||||
}, {})
|
||||
assert.equal(created.job.agentAccess, undefined)
|
||||
assert.equal(created.job.permissionPreset, undefined)
|
||||
assert.equal(created.job.id != null, true)
|
||||
|
||||
await service.updateJob(created.job.id, { agentAccess: 'deny' })
|
||||
await service.updateJob(created.job.id, { agentAccess: 'deny', permissionPreset: 'danger-full-access' })
|
||||
const listed = await tools.cron_list.execute({}, {})
|
||||
const row = listed.jobs.find((job) => job.id === created.job.id)
|
||||
assert.ok(row)
|
||||
assert.equal(row.agentAccess, undefined)
|
||||
assert.equal(row.permissionPreset, undefined)
|
||||
|
||||
await assert.rejects(
|
||||
() => tools.cron_pause.execute({ id: created.job.id }, {}),
|
||||
|
|
@ -492,6 +494,17 @@ test('agentAccess deny is hidden from tools and blocks pause/delete', async (t)
|
|||
|
||||
const httpView = await service.getJob(created.job.id)
|
||||
assert.equal(httpView.agentAccess, 'deny')
|
||||
assert.equal(httpView.permissionPreset, 'danger-full-access')
|
||||
})
|
||||
|
||||
test('normalizePermissionPreset maps UI aliases and rejects junk', async () => {
|
||||
const { normalizePermissionPreset } = await import('../lib/store.js')
|
||||
assert.equal(normalizePermissionPreset(''), '')
|
||||
assert.equal(normalizePermissionPreset({ permissionPreset: 'inherit' }), '')
|
||||
assert.equal(normalizePermissionPreset('read-only'), 'read-only')
|
||||
assert.equal(normalizePermissionPreset('workspace-write'), 'workspace-write')
|
||||
assert.equal(normalizePermissionPreset('full'), 'danger-full-access')
|
||||
assert.throws(() => normalizePermissionPreset('nope'), (err) => err.code === 'INVALID_PERMISSION_PRESET')
|
||||
})
|
||||
|
||||
test('registerCronTools registers each definition and disposer unregisters', () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue