Automation editor with graphical schedule and assistant; movable chat list groups
Automations
- Job files hold only the instructions; name, schedule, mode, model, approval
mode and time limit are settings in the database (jobs.settings). Existing
files are adopted on start-up (frontmatter into the database and removed from
the file); plain Markdown files registered later get default settings and stay
switched off until scheduled.
- New automation: name, project and a starting point (blank example structure or
a template) create .codecraft/jobs/<name>.md and open the editor: settings with
a graphical cron builder (next runs in server time via /jobs/schedule), the
instructions in the Markdown editor and an assistant chat
(POST /jobs/{id}/assistant) whose model edits the file; the editor reloads it
after each turn and warns about conflicts with unsaved edits.
- The schedule tool writes prompt-only files with settings.
Chat list
- Folders and projects keep a user-defined order and can be pinned (drag and
drop, or the group's menu), stored per user via /account/sidebar. A new
message moves the chat to the top of its group, no longer the project itself.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
872ebb94dd
commit
05c215f685
19 files changed
+1661
-356
No files matched your search
@@ -231,6 +231,23 @@ pub async fn put_prefs(Extension(user): Extension<User>, State(app): State<AppSt
|
||||
Ok(Json(b))
|
||||
}
|
||||
|
||||
/// Order and pinning of the groups (folders, projects) in the chat list – per user, so
|
||||
/// every device shows the same order: {"order": [group ids], "pinned": [group ids]}.
|
||||
pub async fn get_sidebar(Extension(user): Extension<User>, State(app): State<AppState>) -> ApiResult {
|
||||
let v: Value = app.store.user_setting(&user.id, "sidebar")?;
|
||||
Ok(Json(if v.is_null() { json!({"order": [], "pinned": []}) } else { v }))
|
||||
}
|
||||
|
||||
pub async fn put_sidebar(Extension(user): Extension<User>, State(app): State<AppState>, Json(b): Json<Value>) -> ApiResult {
|
||||
let ids = |k: &str| b[k].as_array().is_some_and(|a| a.iter().all(|x| x.as_str().is_some_and(|s| s.len() <= 1000)));
|
||||
if !ids("order") || !ids("pinned") || b.to_string().len() > 100_000 {
|
||||
return Err(ApiError(StatusCode::BAD_REQUEST, "invalid chat list layout".into()));
|
||||
}
|
||||
let v = json!({"order": b["order"], "pinned": b["pinned"]});
|
||||
app.store.set_user_setting(&user.id, "sidebar", &v)?;
|
||||
Ok(Json(v))
|
||||
}
|
||||
|
||||
/// Personal memory (applies to all projects, web and CLI).
|
||||
pub async fn get_memory(Extension(user): Extension<User>, State(app): State<AppState>) -> ApiResult {
|
||||
let m: String = app.store.user_setting(&user.id, "memory")?;
|
||||
|
||||
Reference in new issue
Block a user