195 lines
6.8 KiB
Markdown
195 lines
6.8 KiB
Markdown
# v0.19.1 — Active Projects, Project System Prompt, Project Detail Panel
|
|
|
|
**Status:** Implementation
|
|
**Depends on:** v0.19.0 Projects/Workspaces
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
Three tightly-scoped improvements that make projects genuinely usable
|
|
for daily workflow rather than just organizational containers:
|
|
|
|
1. **Active Project** — one-click project activation so new chats
|
|
auto-assign without drag-drop.
|
|
2. **Project System Prompt** — per-project instructions injected into
|
|
every chat within the project at completion time.
|
|
3. **Project Detail Panel** — side panel UI for managing a project's
|
|
system prompt, KB bindings, and notes.
|
|
|
|
---
|
|
|
|
## 1. Active Project
|
|
|
|
### State
|
|
|
|
| Location | Key | Type |
|
|
|----------|-----|------|
|
|
| `App.activeProjectId` | runtime | `string \| null` |
|
|
| `localStorage` | `cs-active-project` | `string \| null` |
|
|
|
|
### Behavior
|
|
|
|
- Click project header's **pin icon** (or "Set as active" in ⋯ menu)
|
|
to activate.
|
|
- Active project gets a visual indicator: left accent border + subtle
|
|
background tint using the project's color.
|
|
- Creating a new chat (via `sendMessage` when `!App.currentChatId`)
|
|
auto-calls `addChannelToProject(activeProjectId, newChannelId)` and
|
|
sets `chat.projectId` client-side.
|
|
- Only one project can be active at a time. Clicking the pin on an
|
|
already-active project deactivates it.
|
|
- Active state persists across page reloads via `localStorage`.
|
|
- If the active project is deleted, `activeProjectId` is cleared.
|
|
|
|
### Files Changed
|
|
|
|
| File | Change |
|
|
|------|--------|
|
|
| `src/js/app.js` | Add `activeProjectId: null` to App, restore from localStorage on init |
|
|
| `src/js/projects-ui.js` | `setActiveProject(id)`, `clearActiveProject()`, menu items, pin icon |
|
|
| `src/js/chat.js` | Auto-assign in `sendMessage` after channel creation |
|
|
| `src/js/ui-core.js` | `.active` class on project group in `renderChatList` |
|
|
| `src/css/styles.css` | `.project-group.active` styling |
|
|
|
|
---
|
|
|
|
## 2. Project System Prompt
|
|
|
|
### Injection Order
|
|
|
|
```
|
|
1. Admin system prompt (global policy — no opt-out)
|
|
2. Persona OR channel prompt (role/character definition)
|
|
3. ▸ PROJECT system prompt (project-specific context) ← NEW
|
|
4. KB hint (available knowledge bases)
|
|
5. Memory hint (user facts from v0.18.0)
|
|
6. Summary / conversation (message history)
|
|
```
|
|
|
|
The project prompt sits between the role definition and the KB hint.
|
|
This lets a persona define "you are a coding assistant" while the
|
|
project adds "this project is the React dashboard for client X."
|
|
|
|
### Backend Flow (completion.go)
|
|
|
|
In `loadConversation`, after the persona/channel system prompt block:
|
|
|
|
```go
|
|
// ── Project system prompt (v0.19.1) ──
|
|
if h.stores.Projects != nil {
|
|
projID, _ := h.stores.Projects.GetProjectIDForChannel(ctx, channelID)
|
|
if projID != "" {
|
|
proj, err := h.stores.Projects.GetByID(ctx, projID)
|
|
if err == nil {
|
|
if sp, ok := proj.Settings["system_prompt"].(string); ok && sp != "" {
|
|
messages = append(messages, providers.Message{
|
|
Role: "system",
|
|
Content: sp,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Storage
|
|
|
|
Uses existing `projects.settings` JSONB column. No migration needed.
|
|
|
|
```json
|
|
{
|
|
"system_prompt": "You are helping build the Chat Switchboard project..."
|
|
}
|
|
```
|
|
|
|
### Files Changed
|
|
|
|
| File | Change |
|
|
|------|--------|
|
|
| `server/handlers/completion.go` | Inject project system prompt in `loadConversation` |
|
|
|
|
---
|
|
|
|
## 3. Project Detail Panel
|
|
|
|
### Registration
|
|
|
|
Follows the same `PanelRegistry.register()` pattern as notes and
|
|
preview panels. Registered during app init via `_registerProjectPanel()`.
|
|
|
|
### Panel Layout
|
|
|
|
```
|
|
┌─────────────────────────────┐
|
|
│ Project: <name> [✕] │ ← header (editable name)
|
|
├─────────────────────────────┤
|
|
│ System Prompt │
|
|
│ ┌─────────────────────────┐ │
|
|
│ │ textarea (auto-resize) │ │
|
|
│ └─────────────────────────┘ │
|
|
│ [Save] │
|
|
├─────────────────────────────┤
|
|
│ Knowledge Bases [+] │
|
|
│ ┌─────────────────────────┐ │
|
|
│ │ • KB Alpha [✕] │ │
|
|
│ │ • KB Beta [✕] │ │
|
|
│ └─────────────────────────┘ │
|
|
│ (empty: "No KBs bound") │
|
|
├─────────────────────────────┤
|
|
│ Notes │
|
|
│ ┌─────────────────────────┐ │
|
|
│ │ • Meeting notes [✕] │ │
|
|
│ │ • Design spec [✕] │ │
|
|
│ └─────────────────────────┘ │
|
|
│ (empty: "No notes") │
|
|
├─────────────────────────────┤
|
|
│ Color [●] │
|
|
│ Archived [ ] │
|
|
└─────────────────────────────┘
|
|
```
|
|
|
|
### Interactions
|
|
|
|
- **System prompt:** Textarea with debounced save (1s) or explicit Save
|
|
button. Writes to `PUT /projects/:id` with
|
|
`settings: { system_prompt: "..." }`.
|
|
- **KB add:** [+] opens a dropdown of available KBs (from
|
|
`GET /knowledge-bases`), filtered to exclude already-bound ones.
|
|
Calls `POST /projects/:id/knowledge-bases`.
|
|
- **KB remove:** [✕] calls `DELETE /projects/:id/knowledge-bases/:kbId`.
|
|
- **Notes:** Read-only list with [✕] to unbind. Notes are auto-associated
|
|
from channel creation (v0.19.0).
|
|
- **Color:** Reuses the invisible color picker pattern from
|
|
`setProjectColor()`.
|
|
- **Open trigger:** Click project name in sidebar header, or
|
|
"Project details" in ⋯ menu.
|
|
|
|
### Files Changed
|
|
|
|
| File | Change |
|
|
|------|--------|
|
|
| `src/index.html` | Add `#sidePanelProject` div inside `#sidePanelBody` |
|
|
| `src/js/projects-ui.js` | `openProjectPanel(id)`, `_registerProjectPanel()`, panel rendering, KB/note management |
|
|
| `src/js/app.js` | Call `_registerProjectPanel()` in init |
|
|
| `src/css/styles.css` | `.project-panel-*` styles |
|
|
|
|
---
|
|
|
|
## Files Summary
|
|
|
|
| File | Phase | Type |
|
|
|------|-------|------|
|
|
| `server/handlers/completion.go` | 2 | Modified |
|
|
| `src/js/app.js` | 1,3 | Modified |
|
|
| `src/js/projects-ui.js` | 1,3 | Modified |
|
|
| `src/js/chat.js` | 1 | Modified |
|
|
| `src/js/ui-core.js` | 1 | Modified |
|
|
| `src/css/styles.css` | 1,3 | Modified |
|
|
| `src/index.html` | 3 | Modified |
|
|
| `VERSION` | — | Modified (0.19.0 → 0.19.1) |
|
|
| `CHANGELOG.md` | — | Modified |
|
|
|
|
No new files. No migrations. Backend change is a single injection
|
|
point in completion.go.
|