123module cli45import json6import src.fmt7import src.history8import src.snapshot910pub fn cmd_save(raw []string, is_checkpoint bool) int {11 verb := if is_checkpoint { 'checkpoint' } else { 'save' }12 args := parse(verb, raw, Options{13 values: ['agent', 'session']14 flags: ['json']15 }) or { return usage_error(err.msg()) }16 message := args.positional_at(0)17 if message == '' {18 example := if is_checkpoint {19 'before combine replay engine'20 } else {21 'fix off-by-one in chunk boundary'22 }23 return usage_error('${verb} needs a message, e.g. koh ${verb} "${example}"')24 }25 store := open_store() or { return refuse(args.json(), err.msg()) }26 defer {27 store.close()28 }29 if snapshot.restore_pending(store) {30 return refuse(args.json(), snapshot.restore_unfinished)31 }32 save := history.commit_worktree(store, store.root, snapshot.load(store.root), history.SaveInput{33 message: message34 agent: args.value('agent')35 session: args.value('session')36 is_checkpoint: is_checkpoint37 }) or { return refuse(args.json(), err.msg()) }3839 files := history.files_of(store, save.id) or { []snapshot.FileEntry{} }40 if args.json() {41 emit_json(json.encode(SaveOut{42 id: save.id43 parent: save.parent44 message: save.message45 created_at: save.created_at46 machine: save.machine47 is_checkpoint: save.is_checkpoint48 agent: save.agent49 session: save.session50 files: files.len51 size_bytes: save.size_bytes52 }))53 auto_offer(store, true)54 return 055 }56 ok('saved [${save.id}] ${save.message}')57 mut detail := []string{}58 if save.is_checkpoint {59 detail << 'checkpoint'60 }61 detail << fmt.stamp(save.created_at)62 detail << fmt.plural(files.len, 'file')63 detail << fmt.human_bytes(save.size_bytes)64 note(detail.join(' · '))65 mut attribution := []string{}66 if save.agent != '' {67 attribution << 'agent: ${save.agent}'68 }69 if save.session != '' {70 attribution << 'session: ${save.session}'71 }72 if attribution.len > 0 {73 note(attribution.join(' · '))74 }75 auto_offer(store, false)76 return 077}78798081struct SaveOut {82 id string83 parent string84 message string85 created_at i6486 machine string87 is_checkpoint bool88 agent string89 session string90 files int91 size_bytes i6492}