Wick · Project

Project — Bundle of Defaults + Folder

1 Project = 1 Folder + Defaults + Pinned. Session bound to 1 project at create. Move-to-project allowed; mid-project folder switch is not — folder is part of project identity.

Paired with design.md. Update keduanya barengan kalau layout / kontrak berubah.

⓪ First boot after upgrade — auto-migrate banner

Idempotent boot-time migration: each existing workspace becomes a project with the same folder. Sessions re-linked automatically.

Migrated 3 workspaces to projects
Each workspace became a project; folder + defaults preserved. Sessions re-linked. No data loss.
Before
workspaces/
  wick/files/
  sandbox/files/
  docs/  (custom path)
After
projects/
  <id1>/files/        (was wick)
  <id2>/files/        (was sandbox)
  <id3>/              (was docs; custom)
Sessions
sessions/<sid>/meta.json
  - workspace: "wick"
  + project_id: <id1>

① Unscoped landing (default)

Projects section above. Recent shows all chats across projects, each row tagged with its project. New session = no project unless picked.

my-app · Agents
New session
Overview
Projects
📁 Wick Backend 12
🧪 Sandbox 3
📚 Learning 7
Recent · all chats
Debug auth middleware
📁 Wick Backend · 2m ago
Try haiku speed
🧪 Sandbox · 1h ago
Pagi standup notes
no project · today
Refactor connector pkg
📁 Wick Backend · yesterday
Learn drawflow events
📚 Learning · 2d ago

New session

Pick a project (or skip for unscoped). Session is created when you send the first message.

Pick a project to auto-prefill provider + preset. Folder follows the project.

② Scoped to project — defaults auto-prefilled

Klik project di sidebar → swap ke scoped. Provider + preset auto-prefill dari project defaults. Folder implicit (1 folder per project).

📌 Pinned
Auth migration tracker
pinned
Recent · Wick Backend 12 chats
Debug auth middleware
2m ago
Refactor connector pkg
yesterday
Trace failing E2E test
2d ago
SSE replay bug
last week
📁 Wick Backend /d/code/work/wick ⚙ Project settings

New session in 📁 Wick Backend

Provider + preset inherited from project. Override anything per-session.

Teal dropdowns = inherited from project. Click any to override.

③ Move chat to project — 1-level menu

Right-click row → submenu list projects. Atomic meta.project_id update. Folder of target project becomes the new cwd context.

Recent
Pagi standup notes
no project · today
Try haiku speed
no project · 2h ago
Debug auth middleware
📁 Wick Backend · 3h ago
📌 Pin
✏️ Rename
📂 Move to project
🗑 Delete
📁 Wick Backend
🧪 Sandbox
📚 Learning
— No project —
+ New project…

Move semantics

  1. Read sessions/<sid>/meta.json
  2. Write meta.project_id = newPid (atomic via storage.WriteJSON)
  3. Registry: upsertSession dgn meta baru

Session ID + path stable → workflows / channels / agent spawn yg pegang sid gak break. Filesystem unchanged. Agent next-spawn pakai folder dari new project.

Cwd shift caveat

Pindah session ke project lain = cwd berubah saat next agent spawn. Lama (terminated) subprocess gak ke-touch; live subprocess perlu kill + respawn buat pickup cwd baru.

Drag-and-drop alternative

Drag chat row dari Recent ke project node di sidebar = same move op. Discoverable via right-click; power-user via drag.

④ Project settings — single folder + defaults

Folder is part of project identity — single field (managed or custom path). Defaults bundled. Pinned sessions managed inline.

📁

12 chats · created 2026-05-20

Folder

CUSTOM

Absolute path to an existing folder. Wick will use this as the agent cwd.

MANAGED

Wick creates and owns the folder at projects/<id>/files/. Useful for scratch sessions.

Defaults

📌 Pinned sessions

Auth migration tracker
+ Pin a session from Recent

Project meta preview

# projects/01J.../meta.json
id:           "01J..."
name:         "Wick Backend"
icon:         "📁"
custom_path:  "/d/code/work/wick"
defaults:
  preset:     "engineer"
  provider:   "claude/claude"
pinned_sessions: ["01J..."]

Folder change semantics

  • Managed → custom: managed files/ kept on disk (orphaned backup; user-deletable manual)
  • Custom → managed: new managed dir created; custom path untouched (wick never owned it)
  • Custom A → custom B: meta-only change; no folder touched
  • Live sessions: cwd shifts at next spawn; running subprocess unaffected until restart

⑤ Storage layout (cheat sheet)

Project = single folder. Managed = nested. Custom = referenced by absolute path only.

<BaseDir>/
  presets/                              unchanged
  workflows/                            unchanged
  sessions/
    <sid>/
      meta.json                        ← + project_id (replaces workspace)
      conversation.jsonl
      ...
  projects/                            ← NEW (replaces workspaces/)
    <project-id>/
      meta.json                        ← defaults, pinned, folder ref
      files/                           ← managed cwd (only if custom_path empty)
Authoritative (truth)
  • sessions/<sid>/meta.json
  • projects/<pid>/meta.json
Derived (rebuildable)
  • Registry in-memory cache (project + session maps)

Per-project sessions.jsonl dropped — in-memory filter via registry.sessions by Meta.ProjectID cukup utk v1 (sessions < 10k).

⑥ Migration detail (workspaces/ → projects/)

Idempotent boot-time scan. 1:1 mapping — each workspace becomes a project with the same folder.

for each workspaces/<name>/:
  pid = uuid.new()
  project.Create({
    id:          pid,
    name:        name,                         # display = old workspace name
    description: ws.description,
    custom_path: ws.custom_path,
    defaults: {
      preset:   ws.default_preset,
      provider: ws.default_provider,
    },
    tags: ws.tags,
  })
  if ws.custom_path == "":
    # managed → move folder (atomic same-FS rename)
    os.Rename(
      "workspaces/<name>/files",
      "projects/<pid>/files"
    )
  # else: custom path unchanged, only referenced from meta

for each sessions/<sid>/ where meta.workspace != "":
  pid = workspaceToProject[meta.workspace]
  meta.project_id = pid
  meta.workspace = ""                              # drop legacy field
  session.SaveMeta(sid, meta)

Idempotency: skip if projects/ already non-empty. Legacy workspaces/ dir kept defensively; cleanup deferred to v1.1.