aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/assistant/Files.js
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-16 16:20:01 +0200
committerDanilo M. <danix@danix.xyz>2026-10-16 16:20:01 +0200
commit12d6830424d24f5a2ed8056b53a12cc4b978ece2 (patch)
treea52a30ab446acd718aa67e1c8dc2887a472954cb /desktop/assistant/Files.js
parentf6ceae477979b32869c0c17e2b1fc05477d6eb81 (diff)
downloadquickshell-12d6830424d24f5a2ed8056b53a12cc4b978ece2.tar.gz
quickshell-12d6830424d24f5a2ed8056b53a12cc4b978ece2.zip
feat(assistant): tell a nameless file's kind from its content
A script with no suffix staged as 'other' and was refused. A staged file the name says nothing about is now handed to file(1) once, and its mime type gives the kind, so a shell script is code and gets Explain and Review. The daemon makes its own call on the content. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/assistant/Files.js')
-rw-r--r--desktop/assistant/Files.js24
1 files changed, 21 insertions, 3 deletions
diff --git a/desktop/assistant/Files.js b/desktop/assistant/Files.js
index 825aed1..a75e693 100644
--- a/desktop/assistant/Files.js
+++ b/desktop/assistant/Files.js
@@ -14,9 +14,8 @@
// What a staged file is, for its chip and the actions offered on it. The
// text and image lists match desktop-assistant's, which decides what chat
// accepts; this only decides what the card offers.
-// ponytail: the daemon also takes any text/* mime type; a file of such a
-// type with a suffix not listed here reads as "other" and is not offered
-// chat. Add the suffix when one shows up.
+// A suffix not listed here reads as "other" at first; Assistant.qml then
+// asks file(1) and fromMime() gives the kind.
// Text splits into prose and data (text) and code or configuration (code),
// so each gets the presets that fit it; the daemon sees one text kind.
const TEXT = [".md", ".rst", ".txt", ".csv"];
@@ -49,6 +48,25 @@ function kind(path) {
function chats(k) { return CHAT.includes(k); }
+// For a file the name says nothing about (a script with no suffix), from
+// the mime type `file -b --mime-type` reports. Prose and data are text;
+// any other text type, scripts and source among them, is code.
+const ARCHIVE_MIMES = ["application/zip", "application/x-tar", "application/gzip",
+ "application/x-xz", "application/x-bzip2", "application/zstd",
+ "application/x-7z-compressed", "application/x-rar",
+ "application/vnd.rar"];
+
+function fromMime(m) {
+ if (["text/plain", "text/markdown", "text/csv"].includes(m)) return "text";
+ if (m.startsWith("text/") || ["application/json", "application/xml",
+ "application/javascript"].includes(m)) return "code";
+ if (["image/png", "image/jpeg", "image/gif", "image/webp"].includes(m)) return "image";
+ if (m === "application/pdf") return "pdf";
+ if (m.startsWith("video/")) return "video";
+ if (ARCHIVE_MIMES.includes(m)) return "archive";
+ return "other";
+}
+
// A dropped URL to a local path, or "" for anything that is not a local
// file: file:///path, or file://localhost/path; any other host is remote.
function fromUrl(url) {