Skip to content

Commit a7a8015

Browse files
author
Oliver Marks
committed
fix #2 suppor for resume.
1 parent f668898 commit a7a8015

6 files changed

Lines changed: 49 additions & 7 deletions

File tree

‎Panel.qml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import qs.Ui
99
// editor is involved. Middle-click toggles the pop-out chat window.
1010
Panel {
1111
id: root
12-
moduleName: "eca"
12+
moduleName: "editor-code-assistant.eca-omarchy"
1313
ipcTarget: "eca-panel"
1414

1515
readonly property var service: bar && bar.shell && typeof bar.shell.serviceFor === "function"
16-
? bar.shell.serviceFor("eca") : null
16+
? bar.shell.serviceFor("editor-code-assistant.eca-omarchy") : null
1717
readonly property var session: service ? service.session : null
1818

1919
readonly property string iconGlyph: String.fromCodePoint(0xF0674) // nf-md-creation (sparkles)

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ the [ECA docs](https://eca.dev/config/introduction/).
129129

130130
```
131131
Panel.qml / ChatWindow.qml ── ChatView.qml (UI)
132-
│ bar.shell.serviceFor("eca")
132+
│ bar.shell.serviceFor("editor-code-assistant.eca-omarchy")
133133
Service.qml (singleton) ── Session.qml per workspace
134134
│ Quickshell Process, newline-delimited JSON
135135
eca_bridge.bb ── Content-Length framed JSON-RPC ── eca server

‎Service.qml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Quickshell.Io
44

55
// Headless ECA client service: owns one Session (one `eca server`) per
66
// workspace folder, shared by every bar on every monitor. Bar widgets reach it
7-
// with bar.shell.serviceFor("eca").
7+
// with bar.shell.serviceFor("editor-code-assistant.eca-omarchy").
88
Item {
99
id: root
1010
property string omarchyPath: ""

‎eca_workspaces.bb‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,40 @@
122122
{:dir (str d) :prefix prefix :hash hash}))))
123123
[]))
124124

125-
(defn resolve-paths [dirs]
125+
(defn index-workspaces
126+
"Workspace folders ECA recorded in the cache dir's chat index (written by
127+
every client, so this also covers sessions started from emacs/neovim in
128+
folders outside our search roots). Nil when unreadable."
129+
[dir]
130+
(try
131+
(let [idx (json/parse-string (slurp (str (fs/path dir "chats" "index.transit.json"))))
132+
;; transit-JSON map: ["^ " k1 v1 k2 v2 ...]
133+
ws (when (and (sequential? idx) (= "^ " (first idx)))
134+
(->> (rest idx) (partition 2) (some (fn [[k v]] (when (= k "~:workspaces") v)))))]
135+
(when (and (sequential? ws) (every? string? ws)) (vec ws)))
136+
(catch Exception _ nil)))
137+
138+
(defn resolve-by-hash [dirs]
126139
(let [wanted (set (map :prefix dirs))
127140
by-hash (->> (candidate-dirs)
128141
(filter #(contains? wanted (sanitize-name (fs/file-name %))))
129142
(map #(str (fs/absolutize %)))
130143
(reduce (fn [m p] (assoc m (paths-hash [p]) p)) {}))]
131144
(keep #(when-let [path (get by-hash (:hash %))] (assoc % :path path)) dirs)))
132145

146+
(defn resolve-paths
147+
"Maps cache dirs to folders. The chat index is authoritative; hashing
148+
candidate folders is the fallback. Multi-root workspaces are skipped since
149+
a session is opened on a single folder."
150+
[dirs]
151+
(let [from-index (keep (fn [d]
152+
(let [ws (index-workspaces (:dir d))]
153+
(when (and (= 1 (count ws)) (fs/directory? (first ws)))
154+
(assoc d :path (first ws)))))
155+
dirs)
156+
done (set (map :dir from-index))]
157+
(concat from-index (resolve-by-hash (remove #(done (:dir %)) dirs)))))
158+
133159
(defn history [eca dir]
134160
(if-not eca
135161
{:chatCount 0}

‎install.sh‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ import json, sys
4848
d = json.load(open('$shell_json'))
4949
# Check plugins list (services / overlays / panels)
5050
for p in d.get('plugins', []):
51-
if p.get('id') == 'eca':
51+
if p.get('id') in ('eca', 'editor-code-assistant.eca-omarchy'):
5252
sys.exit(0)
5353
# Check bar layout sections
5454
for section in d.get('bar', {}).get('layout', {}).values():
5555
for w in section:
56-
if w.get('id') == 'eca':
56+
if w.get('id') in ('eca', 'editor-code-assistant.eca-omarchy'):
5757
sys.exit(0)
5858
sys.exit(1)
5959
" 2>/dev/null

‎test/eca_workspaces_test.bb‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,19 @@
9393
(doseq [ws (:workspaces (eca-workspaces/-main))]
9494
(is (int? (:chatCount ws)))
9595
(is (>= (:chatCount ws) 0)))))
96+
97+
(deftest test-index-workspaces
98+
(let [dir (str (babashka.fs/create-temp-dir))]
99+
(babashka.fs/create-dirs (str dir "/chats"))
100+
(testing "reads workspaces from the transit chat index"
101+
(spit (str dir "/chats/index.transit.json")
102+
"[\"^ \",\"~:version\",7,\"~:workspaces\",[\"/tmp\"],\"~:chats\",[\"^ \"]]")
103+
(is (= ["/tmp"] (eca-workspaces/index-workspaces dir))))
104+
(testing "resolve-paths uses the index even outside the search roots"
105+
(is (= "/tmp" (:path (first (eca-workspaces/resolve-paths [{:dir dir :prefix "x" :hash "y"}]))))))
106+
(testing "multi-root workspaces are skipped"
107+
(spit (str dir "/chats/index.transit.json")
108+
"[\"^ \",\"~:workspaces\",[\"/tmp\",\"/usr\"]]")
109+
(is (empty? (eca-workspaces/resolve-paths [{:dir dir :prefix "x" :hash "y"}]))))
110+
(testing "missing index returns nil"
111+
(is (nil? (eca-workspaces/index-workspaces "/nonexistent"))))))

0 commit comments

Comments
 (0)