Skip to content

feat(AppKit): add skill for Files plugin#45

Open
atilafassina wants to merge 3 commits intomainfrom
appkit-files-skill
Open

feat(AppKit): add skill for Files plugin#45
atilafassina wants to merge 3 commits intomainfrom
appkit-files-skill

Conversation

@atilafassina
Copy link
Copy Markdown
Contributor

this PR adds a skill to use the appKit files plugin to perform UC operations

Documentation safety checklist

  • Examples use least-privilege permissions (no unnecessary ALL PRIVILEGES, admin tokens, or broad scopes)
  • Elevated permissions are explicitly called out where required
  • Sensitive values are obfuscated (placeholder workspace IDs, URLs, no real tokens)
  • No insecure patterns introduced (e.g. disabled TLS verification, hardcoded credentials)

@atilafassina atilafassina requested review from a team and lennartkats-db as code owners April 2, 2026 12:10
Copilot AI review requested due to automatic review settings April 2, 2026 12:10
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds AppKit documentation for using the files() plugin to perform Unity Catalog Volume operations, and wires the new reference into the Databricks Apps skill index/manifest.

Changes:

  • Add a new AppKit reference page documenting UC Volume file operations via the files() plugin.
  • Link the new Files guide from the Databricks Apps SKILL “Required Reading by Phase” table.
  • Register the new reference file in manifest.json so it’s included in the skill bundle.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
skills/databricks-apps/SKILL.md Adds a “Managing files in UC Volumes” pointer to the new Files guide.
skills/databricks-apps/references/appkit/files.md New documentation page covering scaffolding, configuration, APIs, routes, and UI examples for the Files plugin.
manifest.json Includes the new Files reference in the databricks-apps skill file list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +195 to +199
Button,
DirectoryList,
FileBreadcrumb,
FilePreviewPanel,
NewFolderInput,
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the File Browser Example, Button and NewFolderInput are imported but never used. With this template’s noUnusedLocals setting, copy/pasting this snippet will fail to compile unless those imports are removed or the example demonstrates their usage.

Suggested change
Button,
DirectoryList,
FileBreadcrumb,
FilePreviewPanel,
NewFolderInput,
DirectoryList,
FileBreadcrumb,
FilePreviewPanel,

Copilot uses AI. Check for mistakes.
Comment on lines +203 to +206
export function FilesPage() {
const [volumeKey, setVolumeKey] = useState('uploads');
const [currentPath, setCurrentPath] = useState('');
const [entries, setEntries] = useState<DirectoryEntry[]>([]);
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setVolumeKey is declared but unused (const [volumeKey, setVolumeKey] = useState(...)). With noUnusedLocals, this will be a TypeScript error for anyone copying the snippet; either remove the setter or add UI showing how to switch volumes.

Copilot uses AI. Check for mistakes.
Comment on lines +221 to +228
const res = await fetch(url);
const data: DirectoryEntry[] = await res.json();
// Sort: directories first, then alphabetically
data.sort((a, b) => {
if (a.is_directory && !b.is_directory) return -1;
if (!a.is_directory && b.is_directory) return 1;
return (a.name ?? '').localeCompare(b.name ?? '');
});
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loadDirectory assumes the response is always a DirectoryEntry[] and immediately calls res.json() + data.sort(...). Since the docs state errors return { error, plugin }, a non-2xx response will break at runtime; please check res.ok and surface data.error (or throw) before sorting.

Copilot uses AI. Check for mistakes.
Comment on lines +259 to +260
.then((r) => r.json())
.then(setPreview);
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The preview fetch path doesn’t check response.ok before parsing JSON and calling setPreview. On error responses ({ error, plugin }), this will set an invalid shape into preview and likely break rendering; handle non-2xx explicitly (similar to the upload/delete patterns below).

Suggested change
.then((r) => r.json())
.then(setPreview);
.then(async (r) => {
if (!r.ok) {
// Handle non-2xx responses without updating preview state
const errBody = await r.json().catch(() => null);
console.error('Failed to load file preview', errBody ?? r.statusText);
return null;
}
return r.json();
})
.then((data) => {
if (data) {
setPreview(data);
}
});

Copilot uses AI. Check for mistakes.
selectedFile={selectedFile}
preview={preview}
onDownload={(path) =>
window.open(apiUrl('download', { path }), '_blank')
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using window.open(..., '_blank') without noopener/noreferrer can enable reverse-tabnabbing. Consider adding noopener,noreferrer (or using an <a target="_blank" rel="noopener noreferrer"> pattern) in the example.

Suggested change
window.open(apiUrl('download', { path }), '_blank')
window.open(apiUrl('download', { path }), '_blank', 'noopener,noreferrer')

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants