- Allow POST /flows/0/assistants/ to create a new flow together with the assistant, mirroring the existing GraphQL createAssistant(flowID: 0) behavior
- Require both assistants.create and flows.create permissions when flowID=0
- Add explicit flow ownership check for non-zero flowID using flows.admin scope
- Load flow data in the response by fetching it via assistant.FlowID after creation, ensuring AssistantFlow is fully populated in all cases
- replace plain textarea with a tiptap-based markdown editor (StarterKit, tiptap-markdown, placeholder) and a basic formatting toolbar so authors can edit knowledge content with rich formatting while keeping markdown as the storage format for embeddings
- introduce a reusable MarkdownEditor shared component and a tiptap Storage type augmentation
- move the save action from the input addon into the page header on the right
- give each desktop resizable panel its own internal scroll so long meta or content no longer makes the whole page scroll
Co-authored-by: Cursor <cursoragent@cursor.com>
Wire up KnowledgesProvider with Apollo subscriptions and cache policies,
add /knowledges routes and sidebar entry, plus minor formatting cleanups
across file-manager, upload-validation and resources upload helpers.
Co-authored-by: Cursor <cursoragent@cursor.com>
- File manager core:
- Chevron click on folder rows now drills in via `onOpenDirectory`
(when set), matching the existing double-click / Enter semantics.
Consumers that don't wire the prop keep the legacy expand/collapse
behaviour, so flow-files / resources trees stay unchanged.
- Bulk actions bar wraps and collapses to icon-only buttons (Cancel
included) on small viewports so the bar stays usable on mobile.
- Fix tri-state subtree toggle requiring two clicks when the
directory's own path was never in the selection (e.g. user ticked
children one-by-one). \`toggleSubtreeOnSet\` now accepts an optional
\`rootPath\` and ignores it for the "all selected?" check, mirroring
what \`computeDirSelectionState\` shows on the visible checkbox.
Covered by new regression tests in \`file-manager-utils.test.ts\`.
- Built-in icons swapped: copy-path uses \`ClipboardCopy\` instead of
\`Copy\`; bulk \"Save as resources\" uses \`FolderOutput\` instead of
\`BookmarkPlus\`.
- Pull dialog: flatten the container listing (\`name\` as \`path\`,
absolute path in \`id\`) so the chevron / double-click drill into
real subfolders instead of toggling a synthetic \`work/\` wrapper that
has no meaningful navigation target. Selection is mapped back to
absolute paths via a name → absolute lookup before pulling.
- Resources page: drop the focus-derived \`currentDir\` plumbing —
toolbar mkdir / upload always target the library root, row context
menu loses \"Upload files here\" and renames \"New folder here\" to
\"New folder\". Page wraps in \`h-[calc(100dvh-3rem)]\` so the bulk
bar stays inside the viewport. Tooltips simplified accordingly.
- Flow files toolbar: replace the standalone Info icon with rich
per-button tooltips that explain where each gesture lands
(/work/uploads, /work/resources, separate Container snapshot area);
upload button uses the standard \`Upload\` glyph.
- Attach resources dialog: switch the ad-hoc footer to a proper
\`DialogFooter\` with responsive layout, tighten the dialog title.
- \`Dialog\` / \`Sheet\` footers always apply the inter-button gap,
not only at the \`sm+\` breakpoint.
Co-authored-by: Cursor <cursoragent@cursor.com>
Two cleanups closing the remaining P2/P3 gaps in the flow-files / resources
upload + delete paths.
A.4 — unify upload-batch validation
- New shared validator at `frontend/src/lib/upload-validation.ts` (with
tests) exposing `validateUploadBatch(files, limits)`. Mirrors the
per-file / per-batch / empty-file rules enforced by both backends
(`pkg/resources/resources.go`, `pkg/flowfiles/files.go`).
- `useResourcesUpload` migrated off its private validator onto the shared
helper; behaviour and toast strings unchanged.
- `useFlowFilesUpload` now runs the same preflight before constructing
the FormData. Hitting any of the 300 MB / 1000 files / 2 GB / 0-byte
rules surfaces a synchronous toast instead of a network round-trip
followed by a generic 413.
- Added `FLOW_FILES_MAX_FILE_SIZE_MB`, `FLOW_FILES_MAX_UPLOAD_TOTAL_SIZE_MB`
and `FLOW_FILES_MAX_UPLOAD_FILES_PER_REQUEST` to flow-files-constants
alongside the existing resources constants — kept as a separate set so
the two backends can diverge later without touching unrelated call
sites.
C.2 — drop redundant refetchFiles() after flow-file mutations
- The backend already publishes per-file flowFileAdded / flowFileDeleted
events (with directory expansion on delete), `lib/apollo.ts` already
maps them through the universal subscriptionCacheLink, and
`useFlowFilesRealtime` already wires the three subscriptions. Only the
imperative `await refetchFiles()` in upload/delete plus the
`onSuccess={refetchFiles}` props on pull/attach dialogs were left over
from the pre-subscription era.
- Dropped `refetchFiles` from `useFlowFilesUpload` and `useFlowFilesDelete`
param types and removed the matching `await` calls. Added optional
`onAfterDelete` to the delete hook (mirrors `useResourcesDelete`) for
callers that want a UI hook without driving a refetch.
- Made `onSuccess` optional on `FlowFilesPullDialog` and
`FlowFilesAttachResourcesDialog`; removed the `onSuccess={refetchFiles}`
passthroughs in `flow-files.tsx`. The pull dialog's internal
`refetchListing` over the container listing (a separate hook) is kept.
Verified: vitest 140/140, eslint clean on touched files, tsc shows only
the same pre-existing errors as before this change (`User.ts`/`user.ts`
casing; `single possibly undefined` in unrelated delete branches).
Co-authored-by: Cursor <cursoragent@cursor.com>
- Send `sources[]` (was single `source`) to /resources/copy,
/resources/move and /files/to-resources so multi-select operations
execute in one DB transaction; replace the per-feature 409 aggregation
state and the now-unused `resources-conflict-dialog` with the shared
`useOverwriteAction` workflow returning `OverwriteOutcome`.
- Extend `FileManager` with `emptyAreaActions` (right-click context menu
over the tree's empty area), `appliesToFiles` filter (companion to
`appliesToDirs`), `onActiveRowChange` focus reporting and row-level
external-file drop (`onExternalFileDrop`).
- `useFilesDragAndDrop`: capture-phase `onDropCapture` resets the
internal counter / `isDragging` flag before any descendant claims the
drop with `stopPropagation`, fixing the page-level upload overlay
staying stuck after a row-level drop.
- `useResourcesUpload` gains `defaultDir` (read via ref so `uploadFiles`
stays reference-stable) and `openFilePickerForDir` so toolbar /
sidebar / CTA pickers upload into the focused folder by default and
per-row "Upload here" actions can target a specific directory.
Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the single `onBulkDelete` prop with a generic `bulkActions` array so the
host owns which gestures appear in the footer bar. Built-in helpers (`bulkDeleteAction`,
`bulkCopyPathsAction`, `bulkMoveAction`, `bulkCopyAction`, `bulkPromoteAction`)
match the row-action pattern; each entry supports inline button or trailing
overflow menu, optional confirm dialog, isDisabled / isHidden predicates, and
receives the deduped FileNode[]. The bar also surfaces a cumulative size
summary alongside the item count.
Fix Shift+click range selection so it matches user expectations and the rest
of the file-manager's folder semantics:
- Range clicks are now ADDITIVE: the visible-order slice is unioned onto the
previous selection instead of replacing it, so Cmd-clicked picks, earlier
shift-ranges, and explicitly clicked folder subtrees survive a follow-up
Shift+click.
- Folders inside the slice expand to their full subtree via `dirSubtreePaths`,
mirroring the contract of a plain folder click. Without this, a Shift+click
across collapsed sibling folders left the folder paths in `selectedPaths`
but rendered their tri-state checkboxes as unchecked because no descendants
had been added to the selection.
- Anchor preservation across chained Shift+clicks is unchanged; toggle/single
still move the anchor.
Migrate `flow-files`, `resources`, and the move/copy/promote dialogs to the
new `bulkActions` API.
Tests: 131 passing — covers reverse direction, expanded vs. collapsed folders,
nested folders, mixed file/folder anchors, empty folders in range, omitted
`dirSubtreePaths` (tree-less callers), anchor=null and off-screen anchor
fallbacks, chained shift-clicks accumulating subtrees, toggle + shift-click
combinations, idempotent same-row range clicks, and the additive contract's
explicit divergence from Finder/Explorer (range never shrinks the selection).
Co-authored-by: Cursor <cursoragent@cursor.com>
- Introduced new fields `version` and `isDevelopMode` in the Settings model to provide application versioning and development mode status.
- Updated GraphQL schema and resolvers to support the new fields, ensuring they are accessible via the Settings query.
- Enhanced Swagger documentation to reflect the changes in the Settings API endpoint.
- Added necessary validation and response handling for the new fields in the Settings service.
- Add Sources []string to MoveResourceRequest, CopyResourceRequest and AddResourceFromFlowRequest; merged with Source, deduplicated; multi-source uses destination as base dir and runs in a single atomic DB transaction
- Fix MoveResource response to return Added + Updated (not Updated only) so Apollo cache receives new parent directory entries alongside moved items
- Add missing errResourceNotFound case in CopyResource (was 500 instead of 404)
- Cover all new behaviour with table-driven tests (basename conflict, force overwrite, missing source, empty input, dir-into-itself guard, etc.)
- GraphQL/REST CRUD + semantic search for knowledge documents
- KnowledgeStore with admin/user-scoped filtering, re-embedding on update
- Real-time subscriptions (created/updated/deleted) per user and admin
- user_id tracking in all agent-stored documents (guide/answer/code/memory)
- sqlc queries, goose migrations, privilege grants, user_id backfill
- Memory cleanup on flow deletion; stale orphan purge via migration
- Unit tests for all KnowledgeStore operations including security cases
- Frontend GraphQL schema and TypeScript types regenerated
- Added `paths[]` query/body parameter to DeleteFlowFile, DownloadFlowFile,
GetFlowContainerFiles, PullFlowFiles, ListResources, DeleteResource, and
DownloadResource; single `path` parameter retained for backward compatibility.
- Introduced `DeduplicatePaths` in flowfiles package with coverage-based
deduplication (parent covers children), path normalization, and traversal safety.
- Added `ZipRelativePaths` to create ZIP archives from cache-relative paths,
sharing `zipWriteFile` helper with refactored `ZipDirectory`.
- Switched all ZIP and single-file responses to buffered `DataFromReader` with
explicit `Content-Length`, fixing Swagger UI download rendering.
- Expanded response payloads: delete and pull operations now enumerate all
affected nested files; list responses include ancestor directories for tree
completeness.
- Extended test coverage across flowfiles, flow_files, and resources packages
with batch, deduplication, atomicity, Docker exec, and security scenarios.
- Implemented `SanitizeJSONControlChars` to escape literal control characters in JSON string values, ensuring compliance with the JSON specification.
- Enhanced `SanitizeToolCallArguments` method to apply sanitization across tool call arguments in the chain.
- Added comprehensive tests for both sanitization functions to validate behavior with various input scenarios.
- Updated the logic in `determineRecentSectionsToKeep` to clamp the lower bound of the recent sections to keep, ensuring it does not exceed the available sections. This prevents potential out-of-range errors when `keepQASections` is greater than the total number of sections.
- Updated `getHTML` and `getMD` methods to return warnings for small content instead of errors.
- Implemented checks for binary URLs, returning descriptive errors when such URLs are encountered.
- Added new tests to validate the updated behavior for small and empty content handling.
- Added TryLock mechanism to avoid deadlock situations when reading from the channel while the mutex is held.
- Enhanced timer handling to reset when the mutex is not available, ensuring continuous operation of the stream.
- Added new provider configurations for vLLM Qwen 3.6 in both thinking and non-thinking modes.
- Updated the Dockerfile to include the new configuration files for vLLM Qwen 3.6 and ensure proper setup for deployment.
- Folder rows now surface a tri-state checkbox derived from descendant selection;
clicking / shift-clicking / toggling a folder flips the entire subtree in one
gesture, including descendants of a collapsed folder.
- Files get a new onOpen prop, fired on double-click and Enter; directories keep
expanding/collapsing. The resources page wires it to the existing download flow.
- Drop on a file row forwards to its parent folder so the whole folder acts as a
single drop zone (Finder/Explorer semantics), with a shared drag-enter counter
so highlight stays stable when moving the cursor between sibling rows.
- Extract pure data layer into useFileManagerData and pure selection reducers
(computeRowClickSelection / computeToggleSelection / computeToggleSelectAll /
computeDirSelectionState) into file-manager-utils; bundle per-tree row props
into display / handlers so memoized rows stay reference-stable across parent
re-renders, keyboard expansion, and selection changes.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Updated resource ID handling to ensure consistent string coercion for numeric IDs across components.
- Enhanced sorting of resources in the FlowForm to use alphabetical order based on path.
- Improved resource attachment logic in the FlowFilesAttachResourcesDialog to avoid deduplication of descendants.
- Introduced utility functions for converting REST resource entries to a consistent format for Apollo cache.
- Adjusted upload handling to ensure proper type consistency between REST and GraphQL responses.
- Refactored promote functionality to align with updated resource ID handling and improve clarity in parameters.
- Adjusted descriptions in API documentation to clarify paths for uploads, resources, and containers.
- Updated data models to use consistent naming conventions (e.g., `isDir` to `is_dir`, `modifiedAt` to `modified_at`).
- Changed resource ID types from string to uint64 for better consistency across the application.
- Enhanced flow file upload functionality to support batch processing of resource files.
- Removed deprecated code related to resource entry responses in tests.
- Replace resources feature mocks with real GraphQL + REST integration
(Apollo subscriptions-backed cache, dedicated hooks for search, upload,
copy, move, mkdir, delete, plus conflict / mkdir / copy / move dialogs
and a shared FileDropZone UI component).
- Let flows attach user resources on creation and in chat messages:
FlowForm exposes resourceIds as a form field with a multi-select
dropdown (file/folder icons), wired through createFlow, createAssistant,
putUserInput and callAssistant mutations.
- Add attach-resources and save-as-resource (promote) dialogs to the
flow files page; unify drag-and-drop via a shared
hooks/use-files-drag-and-drop.
- Harden file manager: align skeleton layout (grid + column config) with
real rows, extract use-file-manager-dnd, add group selection state and
tree-node accessibility fixes.
- Normalize numeric id/userId from REST /resources/ responses to strings
so GraphQL ID-typed consumers (zod-validated resource picker) work.
Marked with TODO(backend) for removal once the REST endpoint matches
the GraphQL ID scalar.
- Ignore *.tsbuildinfo artifacts.
Made-with: Cursor
Drops `components/ai/file-tree.tsx` and `components/blocks/{crud,skeleton}/*`
reference snippets that were never imported anywhere; the real
file manager lives under `components/file-manager/` and is the only
implementation in use.
Made-with: Cursor
- split monolithic FileManager into FileManagerTreeNode, FileManagerBulkActionsBar, and useFileManagerKeyboardNavigation
- group FileManagerProps columns/search into nested configs and rename visibility booleans from show* to is*Visible per project convention
- replace abbreviations (idx, i, Sep, Item) with full names across components, hooks, and tests
- add ARIA tree-pattern attributes (aria-level, aria-posinset, aria-setsize, aria-multiselectable) and fix aria-hidden hiding the Select-all checkbox
- add labels.formatModified to localize the date column
- make walkTree strictly pure by hiding its internal accumulator
- move side effects out of the setState updater in useFileManagerSelection
- drop redundant stopPropagation in favor of the data-fm-skip-row-click marker
Made-with: Cursor
- vendor the shadcn ai/file-tree primitive (recursive collapsible tree with shared expand/select context) for future AI chat surfaces
- vendor the shadcn crud-file-manager and skeleton-file-manager demo blocks as design references; not wired into any route yet
Made-with: Cursor
- handleConfirm now accepts () => Promise<void> | void; the dialog awaits the promise before closing
- show a Loader2 spinner on the confirm button while the handler is in flight, and disable both confirm and cancel
- block onOpenChange and outside-clicks while processing so the dialog can't be dismissed mid-action
- caller no longer needs to manage its own loading state for confirm-then-async flows
Made-with: Cursor
- add ApiResponse<T> / ApiSuccessResponse<T> / ApiErrorResponse / ApiHttpError types describing the backend protocol
- expose a typed api wrapper with helper methods (api.get / api.post / api.put / api.delete) that returns ApiResponse<T> directly and accepts per-call AxiosRequestConfig
- add unwrapApiResponse(...) and getApiErrorMessage(...) helpers so callers no longer reimplement success/error branching
- set a sensible default request timeout (30s) on the shared axios instance; long uploads still opt out via { timeout: 0 }
- migrate user-provider and password-change-form from the raw axios instance to the new typed api helpers, dropping their bespoke error-shape interfaces
Made-with: Cursor
- replace the inline file tree implementation in flow-files with the new FileManager component
- compose row actions via factory helpers (downloadAction / copyPathAction / deleteAction) instead of bespoke menus
- delegate search highlighting, expand/collapse, multi-select and bulk delete to the shared component; the page now only owns upload, drag-and-drop, pull-from-container and per-file delete confirmation
- switch to the typed axios helpers (api / unwrapApiResponse / getApiErrorMessage) for upload, pull and delete calls
Made-with: Cursor
- introduce src/components/file-manager with tree rendering, search highlighting, multi-select (single / toggle / shift-range), keyboard navigation (arrows, Home/End, Space, Cmd+A, Esc) and bulk delete
- expose unified actions[] API with downloadAction / copyPathAction / deleteAction factory helpers instead of separate built-in props
- split orchestration into useFileManagerExpansion and useFileManagerSelection hooks; derive expanded/selected state during render without useEffect, preserving Set identity for memo-friendly downstream
- add ARIA tree semantics (role=tree on the container, treeitem rows, roving tabindex via activeRowPath, aria-expanded/aria-selected)
- pure tree utils: O(1) folder lookup via Map, normalizeRootGroups, dedupeOverlappingPaths, findNodeByPath, plus 37 vitest unit tests
- ship shadcn checkbox primitive (depends on @radix-ui/react-checkbox) which the file manager uses for row and select-all controls
Made-with: Cursor
- Replaced ambiguous "user's language" guidance in tools/args.go with explicit engagement-log vs technical-channel markers per field, with strong English-only requirement for vector-store and search-engine queries.
- Added a unified LANGUAGE POLICY block to every agent prompt (primary_agent, assistant, pentester, coder, installer, searcher, memorist, generator, refiner, reporter, enricher), tailored per agent based on its actual tool set.
- Extended template variables and tool access (TerminalToolName, FileToolName) for coder, pentester, installer, memorist, generator, refiner, and enricher to match their runtime tool registrations.
- Fixed inverted UseAgents condition and removed misleading vector-store write references in assistant prompt; corrected MEMORY SYSTEM INTEGRATION for mode-specific tool references.
- Compressed COMPLETION REQUIREMENTS across templates and aligned closing-tool guidance with the channel mapping (engagement-log message vs technical-channel result).
Fixes#285.
Co-Authored-By: Octopus <liyuan851277048@icloud.com>
- Added table-driven scenarios for all 8 endpoints (Get/Upload/Delete/Download flow files, Pull from container, GetContainerFiles, AddResourcesToFlow, AddResourceFromFlow) covering success paths, all privilege combinations (view/upload/admin/cross-user), error responses (forbidden/not-found/conflict/invalid request), and security checks (path traversal, symlink rejection).
- Introduced reusable test infrastructure: sqlite-backed flows/user_resources schema, fakeDockerClient implementing the full docker.DockerClient interface, flowFileCaptureSubscriptions recording both FlowPublisher and ResourcePublisher events, and helpers for multipart upload bodies and container TAR fixtures.
- Added direct unit tests for shellQuote, parseFlowIDParam, cleanupPendingUploads, and flowScopeForFiles privilege matrix.
- Lifts handler coverage from 0% to 60-90% across the file and total services package coverage from 10.2% to 28.6%.