zot/internal
patriceckhart ef80f9cd80 feat(session): /session export + import with portable .zotsession file
Lets one user hand a conversation off to another machine or
user. New slash command:

  /session                    picker with export / import rows
  /session export             defaults to ~/Downloads/<name>.zotsession
  /session export ~/foo       writes ~/foo.zotsession
  /session export ~/bar/x.zs  writes to that exact path (ext added if missing)
  /session import <path>      loads and switches to it

Exported file is the same jsonl the live session writes, with
the meta row rewritten to strip the source user's cwd. The
importer rotates the id and cwd to claim the copy, so the
imported session becomes a first-class entry in the current
user's sessions/ directory and shows up in /sessions,
/jump, and on-disk summaries like any other.

core/session_portable.go (new)
  - ExportSession(src, dst) string  returns the resolved
    output path. dst can be a file, a directory, or a bare
    name missing the .zotsession ext; all three shapes land
    somewhere sensible.
  - ImportSession(src, root, cwd, version) string  returns
    the newly-created session file path, ready for
    OpenSession.
  - firstUserPrompt() + slugify() build descriptive
    "20260420-080305-3f268850-say-hello-in-one-sentence.zotsession"
    filenames when exporting into a directory.

core/session_portable_test.go (new)
  - Full round trip: write → export → import into a
    different cwd → OpenSession → message payloads match.
  - Verifies the exported meta drops the original cwd.
  - Verifies the .zotsession extension is appended when
    missing from dst.

modes/session_ops_dialog.go (new)
  - Tiny picker matching the telegramDialog / logoutDialog
    shape: arrow keys, enter, esc. Two rows (export / import)
    with muted hint text.

modes/interactive.go
  - sessionOpsDialog field + constructor + key dispatch +
    render selector, identical boilerplate to the other small
    dialogs.
  - openSessionOpsDialog, doSessionOp, doSessionExport,
    doSessionImport. Export uses CurrentSessionPath (new
    config hook); import calls core.ImportSession then routes
    through the existing LoadSession so the agent switches to
    the new file.
  - defaultExportDir (~/Downloads → ~ → /tmp fallback),
    expandTilde, friendlyPath helpers.

cli.go
  - CurrentSessionPath: sess.Path getter wired into the
    interactive config.

slash_suggest.go + README
  - /session listed in the slash catalog and the README
    commands table, with a short description of the two
    direct forms.

Not wired into the session_dialog.go picker (which stays
resume-only); a later change could add "export this one"
directly from the picker rows if that's useful.
2026-04-20 10:04:33 +02:00
..
agent feat(session): /session export + import with portable .zotsession file 2026-04-20 10:04:33 +02:00
assets add logo to callback page 2026-04-18 10:15:53 +02:00
auth feat(auth,tui): dark login pages + /logout picker 2026-04-19 20:14:22 +02:00
core feat(session): /session export + import with portable .zotsession file 2026-04-20 10:04:33 +02:00
extproto feat(ext): phase 4 - full-event interception, arg rewrites, /reload-ext 2026-04-19 17:02:04 +02:00
provider perf(anthropic): fix cost double-count, tighten caching, correct catalog 2026-04-19 18:57:18 +02:00
skills perf(prompt): cut system prompt to the bone (410 -> 54 tokens) 2026-04-19 17:39:38 +02:00
tui feat(tui): /telegram connect | disconnect | status 2026-04-20 09:18:04 +02:00