AI Folder Brief Sidebar Panel#476
Open
LukasHirt wants to merge 14 commits into
Open
Conversation
… package.json, vite.config.ts, tsconfig.json, playwright.config.ts, l10n/translations.json skeleton, and l10n/.tx/config; run pnpm install to register the workspace package Signed-off-by: Lukas Hirt <info@hirt.cz>
Signed-off-by: Lukas Hirt <info@hirt.cz>
Signed-off-by: Lukas Hirt <info@hirt.cz>
Signed-off-by: Lukas Hirt <info@hirt.cz>
Signed-off-by: Lukas Hirt <info@hirt.cz>
…h unit tests — create src/composables/useLlm.ts and src/composables/useFolderBrief.ts (WebDAV listing, LLM call, static fallback, error handling); write and pass tests/unit/useLlm.spec.ts and tests/unit/useFolderBrief.spec.ts Signed-off-by: Lukas Hirt <info@hirt.cz>
Signed-off-by: Lukas Hirt <info@hirt.cz>
…ponent with unit tests — create src/components/FolderBriefPanel.vue (all render states: loading, error, static brief, LLM brief, Regenerate button); write and pass tests/unit/FolderBriefPanel.spec.ts Signed-off-by: Lukas Hirt <info@hirt.cz>
…— create src/index.ts with defineWebApplication, sidebarPanel registration, isVisible folder guard, and componentAttrs wiring; verify with check:types and a full build Signed-off-by: Lukas Hirt <info@hirt.cz>
…and run final validation — create tests/e2e/folderBrief.spec.ts; run the full unit suite, type-check, and lint to confirm the package is clean Signed-off-by: Lukas Hirt <info@hirt.cz>
Signed-off-by: Lukas Hirt <info@hirt.cz>
Signed-off-by: Lukas Hirt <info@hirt.cz>
…d if present) for the extension Signed-off-by: Lukas Hirt <info@hirt.cz>
…I matrix, and oCIS apps config Signed-off-by: Lukas Hirt <info@hirt.cz>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When navigating an unfamiliar folder — a project handover, a shared space —
there is no quick way to understand what it contains or why it is structured
that way. Users must manually browse and open files.
Solution
When a folder (not a file) is selected, a "Folder Brief" panel appears in the
right sidebar. It reads the file listing (names, types, sizes, dates — no
content download) and sends it to the LLM, which returns a short narrative:
folder purpose, main content categories, and a note on recent activity. With
structured-output models, output is sectioned (Summary / Files by type /
Recent changes); with basic text models, a single paragraph is returned.
Without a configured LLM, the panel renders a static file-type breakdown
from the listing alone.
Extension points
global.files.sidebarWhy ship this now
Project spaces and handover folders are daily friction for oCIS collaborators;
folder-level AI context removes that friction with no new backend and no file
content transfer.
What was built
web-app-ai-folder-brief-sidebaris a new oCIS Web extension that registers a singleglobal.files.sidebarpanel, visible only when exactly one folder is selected — the inverse of the existingglobal.files.sidebarguards used by the AI doc summary package. The panel reads the folder's child listing (names, MIME types, sizes, modification dates; no file content is downloaded) and surfaces a contextual brief in the right sidebar.The core logic lives in two composables.
useLlmmanages LLM configuration and status, setting the panel to'ready'or'unconfigured'depending on whether the application config provides an endpoint.useFolderBriefhandles the full brief lifecycle: it fetches the folder's children via WebDAV at depth 1, serialises a compact listing (capped at 8 000 characters), and — when an LLM is configured — posts it to/chat/completions. The response is parsed as structured JSON into{ summary, filesByType, recentChanges }; if parsing fails, the raw text is returned as a single-paragraph fallback. When no LLM is configured, the composable computes a static MIME-category breakdown instead, withisStatic: trueto suppress the Regenerate button. Error handling covers HTTP 401, 403, 404, 429, and 5xx responses, networkTypeError, andDOMExceptiontimeouts, with per-class messaging and an error-clearing path on retry.FolderBriefPanel.vuerenders five distinct states: a loading placeholder, an error alert, a static breakdown, a full structured LLM brief, and the empty-folder short-circuit. It auto-triggers on mount viaonMounted(() => { ensureReady(); triggerBrief(); })and exposes a Regenerate button only for LLM-generated briefs. The entry point (src/index.ts) wires the composables to the panel viacomponentAttrs, readsapplicationConfig?.llmto construct theLlmConfig, and registers the extension with theisVisibleguarditems?.length === 1 && items[0]?.isFolder === true.The extension ships 12 unit tests across the two composables and the panel component, plus four Playwright acceptance tests covering tab visibility, LLM-mocked brief rendering, server-error display, and Regenerate invocation. No backend changes are required; the extension is purely client-side and degrades gracefully to a static file-type breakdown when no LLM endpoint is configured.
Gate
Effort: S · 🤖 Generated by extctl