feat: assistant workspace V2 — indexing, retrieval, security hardening & workspace switching

Assistant Workspace V2:
- Markdown indexing engine (incremental manifest + chunks JSONL)
- Keyword retrieval with CJK bigram support and hotset boosting
- Directory taxonomy inference and evolution suggestions
- Workspace config management (.assistant/config.json)
- Organize API: capture, classify, move, archive, suggest-evolution

Workspace switching:
- Inspect API (GET /api/workspace/inspect) for pre-switch validation
- Two-phase switching with confirmation dialogs (5 workspace statuses)
- Atomic save: init/reset runs before setSetting(), rollback on failure
- Auto-navigate to new/reused session after switch
- Mismatch banner in ChatView (only for former assistant sessions)
- Debounced path validation with visual indicators

Security hardening:
- Completion fence (onboarding-complete/checkin-complete) only processes
  when session.workingDirectory === assistant_workspace_path (frontend)
  AND session.working_directory === workspacePath (backend double-check)
- assertContained() in workspace-organizer: rejects absolute paths, ~/,
  ../ traversal, and symlink escapes for captureNote/moveFile
- organize API validates all path params at entry (validateRelativePath)
- captureDefault sanitized to relative path on onboarding write
- R_OK + W_OK validation on GET settings, session creation, and PUT

Bug fixes:
- hookTriggeredSessionId now read before auto-trigger; allows retry if
  session has no messages (previous trigger failed silently)
- workspace-switched event listener matches oldPath (not just != newPath)
  so normal project chats never show the mismatch banner
- Daily check-in card hidden when onboarding not complete
- Refresh docs now calls generateRootDocs() + generateDirectoryDocs()
- Banner "Open" button reuses latest session (checkin mode) instead of
  always creating new onboarding session

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
7418andClaude Opus 4.6 committed 2026-03-07 00:37:02 +08:00
1 parent 19aba25c8f
commit 94fdd36d27
28 files changed
+3855 -181

No files matched your search

+6 -5
View File
@@ -1,6 +1,6 @@
import { NextResponse } from 'next/server';
import { getSetting } from '@/lib/db';
import { generateDirectoryDocs } from '@/lib/assistant-workspace';
import { generateDirectoryDocs, generateRootDocs } from '@/lib/assistant-workspace';
export async function POST() {
try {
@@ -12,12 +12,13 @@ export async function POST() {
);
}
const files = generateDirectoryDocs(workspacePath);
return NextResponse.json({ files });
const rootFiles = generateRootDocs(workspacePath);
const directoryFiles = generateDirectoryDocs(workspacePath);
return NextResponse.json({ root: rootFiles, directory: directoryFiles, files: [...rootFiles, ...directoryFiles] });
} catch (e) {
console.error('[workspace/docs] Failed to generate directory docs:', e);
console.error('[workspace/docs] Failed to generate docs:', e);
return NextResponse.json(
{ error: 'Failed to generate directory docs' },
{ error: 'Failed to generate docs' },
{ status: 500 },
);
}