tasks: inline flag (quick tasks stay in the modal) plumbed through parser + endpoints
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,11 @@ Favor power-user affordances over guardrails. See memory `sole-user-assume-compe
|
|||||||
navigates there instead of mounting the modal. One code path, phone-friendly.
|
navigates there instead of mounting the modal. One code path, phone-friendly.
|
||||||
- **Deep-link:** query params, not hash — `/jobs/new?task=convert-video&root=home&path=<dir>&entry=<name>`.
|
- **Deep-link:** query params, not hash — `/jobs/new?task=convert-video&root=home&path=<dir>&entry=<name>`.
|
||||||
- **Phone:** already has a file browser, so it can pick a target path and POST a job. No blocker.
|
- **Phone:** already has a file browser, so it can pick a target path and POST a job. No blocker.
|
||||||
|
- **`inline` tasks stay in the modal.** A top-level `inline: true` in `TASK.md` marks quick/interactive
|
||||||
|
tasks that run in the modal (ephemeral) instead of as a job. Default = job. Currently flagged:
|
||||||
|
`remove-jelly-meta`, `analyze-video`, `clean-playlist-files`. So the modal is **not** retired — it's
|
||||||
|
the inline path; the shared input form serves both the modal and `/jobs/new`. The flag is plumbed
|
||||||
|
through the parser + task list/detail endpoints (`task.inline`), so the FileBrowser menu can branch.
|
||||||
|
|
||||||
## Plan
|
## Plan
|
||||||
|
|
||||||
@@ -76,6 +81,8 @@ Favor power-user affordances over guardrails. See memory `sole-user-assume-compe
|
|||||||
`PipelineJobDetail`). Script jobs are now viewable at `/jobs/:id`.
|
`PipelineJobDetail`). Script jobs are now viewable at `/jobs/:id`.
|
||||||
- [ ] 3b `/jobs/new` page — extract the input UI (TaskInputForm + per-group config + folder probing)
|
- [ ] 3b `/jobs/new` page — extract the input UI (TaskInputForm + per-group config + folder probing)
|
||||||
from `TaskRunnerModal` into a shared component; Run/Queue → `POST /jobs` → navigate.
|
from `TaskRunnerModal` into a shared component; Run/Queue → `POST /jobs` → navigate.
|
||||||
- [ ] 3c FileBrowser task action navigates to `/jobs/new?...`; retire modal/dialog/useTaskRunner.
|
- [x] `inline` flag plumbed (parser + list/detail endpoints); 3 quick tasks flagged.
|
||||||
|
- [ ] 3c FileBrowser task action: `task.inline ? openModal : navigate('/jobs/new?...')`. Modal stays
|
||||||
|
for inline tasks (not retired); shared input form used by both.
|
||||||
- [ ] 3d header running-jobs indicator (`GET /jobs?live=1`).
|
- [ ] 3d header running-jobs indicator (`GET /jobs?live=1`).
|
||||||
- [ ] 4 push notifications
|
- [ ] 4 push notifications
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export type TaskFrontmatter = {
|
|||||||
description: string | null;
|
description: string | null;
|
||||||
version: number;
|
version: number;
|
||||||
mode: string;
|
mode: string;
|
||||||
|
inline: boolean; // quick/interactive tasks run in the modal instead of as a background job
|
||||||
language: string | null;
|
language: string | null;
|
||||||
args: string[] | null;
|
args: string[] | null;
|
||||||
tags: string[] | null;
|
tags: string[] | null;
|
||||||
@@ -37,6 +38,7 @@ export type TaskSummary = {
|
|||||||
name: string;
|
name: string;
|
||||||
description: string | null;
|
description: string | null;
|
||||||
mode: string;
|
mode: string;
|
||||||
|
inline: boolean;
|
||||||
version: number;
|
version: number;
|
||||||
trigger: unknown;
|
trigger: unknown;
|
||||||
};
|
};
|
||||||
@@ -47,6 +49,7 @@ const FM_KEYS = [
|
|||||||
'description',
|
'description',
|
||||||
'version',
|
'version',
|
||||||
'mode',
|
'mode',
|
||||||
|
'inline',
|
||||||
'language',
|
'language',
|
||||||
'args',
|
'args',
|
||||||
'tags',
|
'tags',
|
||||||
@@ -105,6 +108,7 @@ function parseTaskMd(raw: string): { fm: TaskFrontmatter; body: string } {
|
|||||||
description: parsed.description == null ? null : String(parsed.description),
|
description: parsed.description == null ? null : String(parsed.description),
|
||||||
version,
|
version,
|
||||||
mode: parsed.mode == null ? 'agentic' : String(parsed.mode),
|
mode: parsed.mode == null ? 'agentic' : String(parsed.mode),
|
||||||
|
inline: parsed.inline === true,
|
||||||
language: parsed.language == null ? null : String(parsed.language),
|
language: parsed.language == null ? null : String(parsed.language),
|
||||||
args: asArray(parsed.args),
|
args: asArray(parsed.args),
|
||||||
tags: asArray(parsed.tags),
|
tags: asArray(parsed.tags),
|
||||||
@@ -160,6 +164,7 @@ export async function listTasks(): Promise<TaskSummary[]> {
|
|||||||
name: fm.name || entry.name,
|
name: fm.name || entry.name,
|
||||||
description: fm.description,
|
description: fm.description,
|
||||||
mode: fm.mode,
|
mode: fm.mode,
|
||||||
|
inline: fm.inline,
|
||||||
version: fm.version,
|
version: fm.version,
|
||||||
trigger: fm.trigger ?? [],
|
trigger: fm.trigger ?? [],
|
||||||
});
|
});
|
||||||
@@ -205,6 +210,7 @@ export async function createTask(input: CreateTaskInput): Promise<TaskSummary &
|
|||||||
name,
|
name,
|
||||||
description: input.description ?? null,
|
description: input.description ?? null,
|
||||||
mode,
|
mode,
|
||||||
|
inline: false,
|
||||||
version: 1,
|
version: 1,
|
||||||
trigger: [],
|
trigger: [],
|
||||||
filePath: taskFile(dirName),
|
filePath: taskFile(dirName),
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ tasksRouter.get('/:name', async (ctx) => {
|
|||||||
name: task.name,
|
name: task.name,
|
||||||
description: task.description,
|
description: task.description,
|
||||||
mode: task.mode,
|
mode: task.mode,
|
||||||
|
inline: task.inline,
|
||||||
language: task.language,
|
language: task.language,
|
||||||
body: task.body,
|
body: task.body,
|
||||||
implementation: task.implementation,
|
implementation: task.implementation,
|
||||||
|
|||||||
Reference in New Issue
Block a user