diff options
| author | Danilo M. <danix@danix.xyz> | 2026-11-10 12:15:23 +0100 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-11-10 12:15:23 +0100 |
| commit | 80306b3a3ad59e3a06a7e694c69be3ada976ff03 (patch) | |
| tree | 6d9652b779203a45ce3715770c5de25ba37ca0bf /desktop | |
| parent | 4736a1a80ba984d3dfb9ff3bcfef6b63b570c6a1 (diff) | |
| download | quickshell-80306b3a3ad59e3a06a7e694c69be3ada976ff03.tar.gz quickshell-80306b3a3ad59e3a06a7e694c69be3ada976ff03.zip | |
feat(assistant): catalog IPC for deck-it, presets sent as written
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop')
| -rw-r--r-- | desktop/assistant/Files.js | 5 | ||||
| -rw-r--r-- | desktop/assistant/Ops.js | 7 | ||||
| -rw-r--r-- | desktop/assistant/Presets.js | 25 | ||||
| -rw-r--r-- | desktop/assistant/README.md | 7 | ||||
| -rw-r--r-- | desktop/assistant/test_presets.js | 8 | ||||
| -rw-r--r-- | desktop/shell.qml | 15 |
6 files changed, 52 insertions, 15 deletions
diff --git a/desktop/assistant/Files.js b/desktop/assistant/Files.js index a75e693..bcbd9bc 100644 --- a/desktop/assistant/Files.js +++ b/desktop/assistant/Files.js @@ -48,6 +48,11 @@ function kind(path) { function chats(k) { return CHAT.includes(k); } +// kind -> suffixes, for a file dialog's filter (deck-it's picker). +function exts() { + return { text: TEXT, code: CODE, image: IMAGE, video: VIDEO, archive: ARCHIVE, pdf: [".pdf"] }; +} + // 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. diff --git a/desktop/assistant/Ops.js b/desktop/assistant/Ops.js index 4d7ef96..2fb6ab0 100644 --- a/desktop/assistant/Ops.js +++ b/desktop/assistant/Ops.js @@ -42,6 +42,13 @@ var COMPRESS = [ { label: ".tar.bz2", icon: "\uf1c6", op: "tbz2" }, ]; +// Every operation as one flat list, for deck-it's tablet tab: the Compress +// submenu's formats become ops of their own, for any kind. +function catalog() { + return OPS.filter(o => o.op !== "compress") + .concat(COMPRESS.map(c => Object.assign({ kinds: ["any"] }, c))); +} + function ext(name) { const n = name.toLowerCase(), dot = n.lastIndexOf("."); return dot > 0 ? n.slice(dot) : ""; diff --git a/desktop/assistant/Presets.js b/desktop/assistant/Presets.js index 0fd6f31..f7cce1c 100644 --- a/desktop/assistant/Presets.js +++ b/desktop/assistant/Presets.js @@ -18,15 +18,15 @@ // more files are staged. The list in use is Prefs.presets when one is // saved (the settings window's Ask presets page edits it), these otherwise. const DEFAULTS = [ - { label: "Summarize", icon: "\uf036", kinds: ["pdf", "text"], prompt: "Summarize this in a few short paragraphs." }, - { label: "Key points", icon: "\uf0ca", kinds: ["pdf"], prompt: "List the key points as bullets." }, - { label: "Explain simply", icon: "\uf0eb", kinds: ["pdf", "text"], prompt: "Explain this simply, as to a non-expert." }, - { label: "Describe", icon: "\uf06e", kinds: ["image"], prompt: "Describe this image." }, - { label: "Extract text", icon: "\uf031", kinds: ["image", "pdf"], prompt: "Transcribe all the text, keeping the layout where it helps." }, - { label: "What is this?", icon: "\uf059", kinds: ["image"], prompt: "What is this, and what is it for?" }, - { label: "Explain", icon: "\uf121", kinds: ["code"], prompt: "Explain what this code does." }, - { label: "Review", icon: "\uf188", kinds: ["code"], prompt: "Review this code: bugs, risks, and simplifications." }, - { label: "Compare", icon: "\uf0db", kinds: ["many"], prompt: "Compare these files: what they share and how they differ." }, + { label: "Summarize", icon: "\uf036", kinds: ["pdf", "text"], prompt: "Summarize this in a few short paragraphs. Answer in the language of the document." }, + { label: "Key points", icon: "\uf0ca", kinds: ["pdf"], prompt: "List the key points as bullets. Answer in the language of the document." }, + { label: "Explain simply", icon: "\uf0eb", kinds: ["pdf", "text"], prompt: "Explain this simply, as to a non-expert. Answer in the language of the document." }, + { label: "Describe", icon: "\uf06e", kinds: ["image"], prompt: "Describe this image. Answer in the language of the document." }, + { label: "Extract text", icon: "\uf031", kinds: ["image", "pdf"], prompt: "Transcribe all the text, keeping the layout where it helps. Answer in the language of the document." }, + { label: "What is this?", icon: "\uf059", kinds: ["image"], prompt: "What is this, and what is it for? Answer in the language of the document." }, + { label: "Explain", icon: "\uf121", kinds: ["code"], prompt: "Explain what this code does. Answer in the language of the document." }, + { label: "Review", icon: "\uf188", kinds: ["code"], prompt: "Review this code: bugs, risks, and simplifications. Answer in the language of the document." }, + { label: "Compare", icon: "\uf0db", kinds: ["many"], prompt: "Compare these files: what they share and how they differ. Answer in the language of the document." }, ]; var FALLBACK = "\uf086"; @@ -45,6 +45,7 @@ function offered(presets, files) { : files.every(f => p.kinds.includes(f.kind))); } -// The model answers in the language it is asked in; a preset is asked in -// English, so it says which language to use. -function prompt(p) { return p.prompt + " Answer in the language of the document."; } +// Sent as written: a preset says which language to answer in, so a +// Translate preset can name its target. The defaults ask for the +// document's own language. +function prompt(p) { return p.prompt; } diff --git a/desktop/assistant/README.md b/desktop/assistant/README.md index 4c76a66..a76e9c7 100644 --- a/desktop/assistant/README.md +++ b/desktop/assistant/README.md @@ -9,6 +9,13 @@ what is typed. The protocol is specified in that repo, `docs/superpowers/specs/2026-10-16-text-daemon-design.md`. qs -p ./desktop ipc call assistant toggle + qs -p ./desktop ipc call assistant catalog + +`catalog` answers one JSON line for deck-it's tablet tab: the Ask presets +in use, the Do ops (Compress's formats as ops of their own), kind → +suffixes, the fileops path, the output folder, the To .md prompt and the +preferred model. Presets are sent as written, so each says which language +to answer in. | File | Does | | --- | --- | diff --git a/desktop/assistant/test_presets.js b/desktop/assistant/test_presets.js index e4a18f4..c2cbcf3 100644 --- a/desktop/assistant/test_presets.js +++ b/desktop/assistant/test_presets.js @@ -32,9 +32,11 @@ assert.deepStrictEqual(labels(files("image")), ["Describe", "Extract text", "Wha assert.deepStrictEqual(labels(files("video")), []); assert.deepStrictEqual(labels([]), []); -// Every prompt asks for the document's language. -for (const p of P.DEFAULTS) - assert.ok(P.prompt(p).endsWith(" Answer in the language of the document."), p.label); +// A prompt is sent as written; the defaults ask for the document's language. +for (const p of P.DEFAULTS) { + assert.strictEqual(P.prompt(p), p.prompt, p.label); + assert.ok(p.prompt.endsWith(" Answer in the language of the document."), p.label); +} // A saved list is used when valid; anything else reads as the defaults. const mine = [{ label: "Mine", prompt: "Do it.", kinds: ["pdf"] }]; diff --git a/desktop/shell.qml b/desktop/shell.qml index cf7084a..798aa2d 100644 --- a/desktop/shell.qml +++ b/desktop/shell.qml @@ -46,6 +46,9 @@ import "modules/user" import "modules/vm" import "island" import "assistant" +import "assistant/Presets.js" as Presets +import "assistant/Ops.js" as Ops +import "assistant/Files.js" as Files ShellRoot { // Quickshell exits once no window is visible, and the drawer is closed @@ -198,8 +201,20 @@ ShellRoot { } // qs -p <this dir> ipc call assistant toggle -> SUPER+Home + // qs -p <this dir> ipc call assistant catalog -> JSON for deck-it's tablet tab IpcHandler { target: "assistant" function toggle() { assistant.toggle(); } + function catalog(): string { + return JSON.stringify({ + presets: Presets.list(Prefs.presets), + ops: Ops.catalog(), + kinds: Files.exts(), + fileops: assistant.fileops, + outDir: assistant.outDir, + mdPrompt: assistant.mdPrompt, + preferred: Prefs.assistantModel + }); + } } } |
