@turmind/halo 1.0.3 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin-out/404.html +1 -1
- package/admin-out/_next/static/chunks/212-8ac9dfe9c24e512c.js +1 -0
- package/admin-out/_next/static/chunks/220.e5a2532bda77e816.js +1 -0
- package/admin-out/_next/static/chunks/438-866a1a20e9efa78a.js +1 -0
- package/admin-out/_next/static/chunks/442.68ed26e27eb1d84f.js +1 -0
- package/admin-out/_next/static/chunks/515.4d98fae302278913.js +1 -0
- package/admin-out/_next/static/chunks/635-d7fd95bff8674116.js +1 -0
- package/admin-out/_next/static/chunks/896.ed21ec1e0846d20d.js +1 -0
- package/admin-out/_next/static/chunks/935.543aeec8456b6061.js +1 -0
- package/admin-out/_next/static/chunks/app/page-686cd94fdf9df63b.js +1 -0
- package/admin-out/_next/static/chunks/webpack-fc1574554e7b1108.js +1 -0
- package/admin-out/_next/static/css/0d0ca7b3c8cc5562.css +3 -0
- package/admin-out/index.html +1 -1
- package/admin-out/index.txt +5 -5
- package/bundled-docs/design/agent.md +11 -0
- package/bundled-docs/design/agentcore.md +10 -0
- package/bundled-docs/design/architecture.md +28 -29
- package/bundled-docs/design/background-dispatch.md +30 -43
- package/bundled-docs/design/cron.md +10 -1
- package/bundled-docs/design/evolution.md +18 -2
- package/bundled-docs/design/feishu.md +19 -6
- package/bundled-docs/design/goal-mode.md +2 -2
- package/bundled-docs/design/halo-city.md +7 -0
- package/bundled-docs/design/session.md +62 -2
- package/bundled-docs/design/slack.md +20 -6
- package/bundled-docs/design/storage.md +39 -2
- package/bundled-docs/design/telegram.md +20 -8
- package/bundled-docs/design/web.md +1 -0
- package/bundled-docs/design/wechat.md +13 -17
- package/bundled-docs/design/ws.md +35 -9
- package/bundled-docs/dev/add-channel.md +49 -37
- package/bundled-docs/dev/api.md +123 -35
- package/bundled-docs/dev/deploy.md +48 -0
- package/bundled-docs/dev/desktop-packaging.md +41 -7
- package/bundled-docs/dev/env.md +1 -0
- package/bundled-docs/dev/previews.md +58 -3
- package/bundled-docs/guide/channels/wechat.md +3 -3
- package/bundled-docs/guide/cli.md +24 -5
- package/bundled-docs/requirements/chat.md +13 -2
- package/bundled-docs/requirements/editor.md +5 -2
- package/bundled-docs/requirements/explorer.md +1 -0
- package/bundled-docs/requirements/session.md +5 -3
- package/bundled-docs/requirements/source-control.md +1 -0
- package/dist/index.js +14342 -13200
- package/package.json +4 -1
- package/templates/schema.sql +8 -10
- package/admin-out/_next/static/chunks/212-c5f046048be9c367.js +0 -1
- package/admin-out/_next/static/chunks/220.3dc41cd6269b88e6.js +0 -1
- package/admin-out/_next/static/chunks/4-e7ba0b1ced30190b.js +0 -1
- package/admin-out/_next/static/chunks/442.f4302087bddb1ec1.js +0 -1
- package/admin-out/_next/static/chunks/635-3dd0043ed0520b9d.js +0 -1
- package/admin-out/_next/static/chunks/app/page-5a6cf2b73a12b849.js +0 -1
- package/admin-out/_next/static/chunks/webpack-47520cdc55be63e7.js +0 -1
- package/admin-out/_next/static/css/62b8bf49e6404ffc.css +0 -3
- /package/admin-out/_next/static/{CWrUwTypkebkhwZ5i82_G → Qre3-OObLUgfkv8BEU08q}/_buildManifest.js +0 -0
- /package/admin-out/_next/static/{CWrUwTypkebkhwZ5i82_G → Qre3-OObLUgfkv8BEU08q}/_ssgManifest.js +0 -0
|
@@ -53,13 +53,13 @@ The QR is valid for ~3 minutes; if it expires the admin UI auto-refreshes. If yo
|
|
|
53
53
|
|
|
54
54
|
The bot's name in your WeChat contacts is whatever the iLink platform set it to (typically a generic placeholder like `小助手`; you can rename it locally). Open the bot's chat in WeChat and send `hello` → expect a streamed reply.
|
|
55
55
|
|
|
56
|
-
If nothing happens, check halo server logs for `[
|
|
56
|
+
If nothing happens, check halo server logs for `[wechat]` lines.
|
|
57
57
|
|
|
58
58
|
## How halo handles inbound
|
|
59
59
|
|
|
60
60
|
- **Text** — sent to the agent
|
|
61
61
|
- **Images** — passed to the LLM as multimodal content
|
|
62
|
-
- **Voice** — decrypted, saved under `<workspace>/.halo/assets/weixin/inbound/<accountId>/<date
|
|
62
|
+
- **Voice** — decrypted, saved under `<workspace>/.halo/assets/weixin/inbound/<accountId>/<date>/` (the `weixin` directory name is kept for backward compatibility with existing workspaces), path included in the agent's input
|
|
63
63
|
- **Video / files** — same as voice
|
|
64
64
|
- **Group chats** — not supported in v1 (group messages are dropped)
|
|
65
65
|
- **Self-loop** — bot-authored messages are filtered out
|
|
@@ -106,5 +106,5 @@ Each scan = one account = one workspace binding. To use a second workspace, open
|
|
|
106
106
|
|
|
107
107
|
- Code: `packages/server/src/channels/wechat/`
|
|
108
108
|
- Login flow: `packages/server/src/channels/wechat/login.ts`
|
|
109
|
-
- Admin UI: `packages/admin/src/features/
|
|
109
|
+
- Admin UI: `packages/admin/src/features/wechat/wechat-settings.tsx`
|
|
110
110
|
- Design notes: [../../design/wechat.md](../../design/wechat.md)
|
|
@@ -110,6 +110,12 @@ halo tui -s sid_abc123 # resume session
|
|
|
110
110
|
halo tui -n # always start a new session
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
+
`halo tui` needs an interactive terminal — the keyboard layer can't enter raw
|
|
114
|
+
mode without one. When stdin isn't a TTY (CI, `halo tui < file`,
|
|
115
|
+
`echo x | halo tui`) it exits immediately with code 1 and points you at `halo
|
|
116
|
+
cli "<prompt>"`, rather than failing a couple of seconds later inside the
|
|
117
|
+
rendering layer.
|
|
118
|
+
|
|
113
119
|
Multi-turn conversation. Supports all standard Halo slash commands:
|
|
114
120
|
|
|
115
121
|
| Command | Description |
|
|
@@ -149,9 +155,10 @@ Bare `/<obj>` (or `/<obj> help`) lists the verbs you may run. Verbs gated above
|
|
|
149
155
|
|
|
150
156
|
| Key | Action |
|
|
151
157
|
|---|---|
|
|
152
|
-
| `Esc`
|
|
153
|
-
| `Ctrl+C` |
|
|
154
|
-
| `Ctrl+O` |
|
|
158
|
+
| `Esc` | **With nothing else open, while a turn is running**: interrupt it immediately — the in-flight tool or command is aborted, then any messages typed while it ran fold into one follow-up turn (same as `/session interrupt`; repeat presses are idempotent, the "interrupting…" notice is throttled). **While the log viewer, the sub-agent navigator, or a completion popup is open**: Esc only closes that surface — a running turn is never touched, so leaving a live log you opened with `Ctrl+O` can't kill it. The popup keeps your typed text when dismissed. Once nothing is open, the next Esc interrupts again. |
|
|
159
|
+
| `Ctrl+C` | Exit — first press arms a confirm (the input hint flips to "press Ctrl+C again to exit" for 1.5s), second press exits. Works even while a modal is open (unlike Esc, nothing swallows it). Exit is graceful: a running turn is stopped, the conversation repaired, and the session flushed to disk. |
|
|
160
|
+
| `Ctrl+O` | Open the session-log navigator (no-op while a log surface is already open) — lists the session tree, the root session plus every sub-agent spawned under it, each showing its agent name, task title (same as the session list), and status (`●` running green / `○` idle grey / `✕` stopped red, plus a `▢ archived` marker when the session is archived); `↑↓` to move, `Enter` to view that session's log, `Esc`/`q` to close. (Was `Shift+Tab`, but Windows terminals consume that as backtab.) Inside the log viewer: `j`/`k` or `↑`/`↓` scroll by line, `d`/`u` (or `Ctrl+F`/`Ctrl+B`, PgDn/PgUp) by half a page, `g`/`G` jump to top/bottom, `q`/`Esc` close. The viewer auto-refreshes while the viewed session is still running (a `● live` hint shows in the header) and follows the bottom as new output lands — unless you've scrolled up to read, in which case it stays put (`G` jumps back to the bottom and resumes following). |
|
|
161
|
+
| `Tab` / `Enter` (popup open) | Complete the highlighted suggestion — slash commands and their verbs while typing `/…`, paths after `@`/`@file`/`@image`/`@scope`. `↑`/`↓` move the highlight; `Esc` dismisses the popup without clearing what you typed (any edit brings it back). A picked directory completes with a trailing `/` and keeps the popup open so you can keep descending; a picked file closes it. With no popup open, Enter submits. |
|
|
155
162
|
| `↑` / `↓` | Walk input history (when no popup is open). History persists across restarts in `~/.halo/global/tui-history.json` (last 100 entries, shared across workspaces) |
|
|
156
163
|
| `←` / `→`, `Home` / `End` | Move the cursor within the input; text is inserted/deleted at the cursor (CJK and emoji safe) |
|
|
157
164
|
| `Ctrl+A` / `Ctrl+E` | Jump to start / end of input |
|
|
@@ -176,11 +183,11 @@ Attach files or images to your message with `@file` and `@image`, or pull a dire
|
|
|
176
183
|
|
|
177
184
|
- `@file path` — reads the file and inlines its content in the message as `<file>` block
|
|
178
185
|
- `@image path` — reads the image as base64 and sends it via the model's vision input
|
|
179
|
-
- `@file photo.png` — image extensions (`.png`, `.jpg`, `.gif`, `.webp`, `.bmp`) are auto-detected as images
|
|
186
|
+
- `@file photo.png` — image extensions (`.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.bmp`) are auto-detected as images
|
|
180
187
|
- `@scope dir` — injects the directory-scoped `.halo/INSTRUCTIONS.md` along the path from the workspace root down to `dir` (root level excluded — it's already in the system prompt) into **this turn only**. Use it to bring a sub-directory's conventions into scope for one request. It does not change where tools run.
|
|
181
188
|
- Paths are relative to the workspace; absolute paths also work
|
|
182
189
|
- Quoted paths supported for filenames with spaces: `@file "my file.txt"`
|
|
183
|
-
- **
|
|
190
|
+
- **Path completion** in TUI mode: the suggestion popup opens by itself as you type after `@file ` / `@image ` (images and directories only) / `@scope ` (directories only) — `Tab` or `Enter` completes the highlighted entry, directories stay open for descending (see Keybindings)
|
|
184
191
|
|
|
185
192
|
### Limits
|
|
186
193
|
|
|
@@ -188,6 +195,18 @@ Attach files or images to your message with `@file` and `@image`, or pull a dire
|
|
|
188
195
|
- **Images**: skipped if larger than 5MB
|
|
189
196
|
- If the current model does not support vision, a warning is shown and images are ignored
|
|
190
197
|
|
|
198
|
+
## Server Mode (background daemon)
|
|
199
|
+
|
|
200
|
+
`halo server start|stop|restart|status|logs` manages a local server from the
|
|
201
|
+
same binary. `start -d` runs it in the background **with a bounded respawn
|
|
202
|
+
supervisor**: the detached process supervises the server and brings it back on
|
|
203
|
+
a crash (non-zero exit, or a kill by anything other than SIGTERM/SIGINT), at
|
|
204
|
+
most 5 times per 5 minutes with a 2s pause, logging each decision as
|
|
205
|
+
`[respawn] …` into `~/.halo/global/logs/server.log`. `halo server stop` is
|
|
206
|
+
recognized as intentional and never respawns; `halo server stop|restart|status`
|
|
207
|
+
still target the server's own pid. Full policy in
|
|
208
|
+
[dev/deploy.md](../dev/deploy.md#crash-semantics--why-restarton-failure-is-load-bearing).
|
|
209
|
+
|
|
191
210
|
## Architecture
|
|
192
211
|
|
|
193
212
|
```
|
|
@@ -21,12 +21,23 @@ The primary surface for talking to an agent.
|
|
|
21
21
|
Hover actions on user-role turns: the blue sticky user bubble, plus the sub-agent-report (green) and compact-summary (purple) callouts — all three share the same Copy/Delete pair. On the callouts, Copy copies the body only (the `(from: session X)` / `[Conversation Summary…]` marker line is stripped); a deleted callout greys out and gains a "deleted" badge like the bubble does:
|
|
22
22
|
- **Copy** — copies the prompt text to the clipboard
|
|
23
23
|
- **Show more/less** — the existing clamp toggle, shown when the text overflows
|
|
24
|
-
- **Delete** (confirm dialog) — removes the whole exchange (the user turn + all responses up to the next user turn) with **two-layer semantics**: the LLM context (`rawMessages`) drops the turn physically — the model never sees it again, freeing context; the UI keeps the messages, rendered greyed-out with a "deleted" tag, as an audit trail. No undo; a deleted exchange loses its Delete button. Rejected with an error toast while the agent is running or compacting. Root sessions only (sub-session logs don't offer Delete). If the turn was already compacted out of raw context, only the UI marking happens (silent degrade). Design details in [design/session.md](../design/session.md#exchange-deletion-soft-ui--hard-raw), protocol in [design/ws.md](../design/ws.md).
|
|
24
|
+
- **Delete** (confirm dialog) — removes the whole exchange (the user turn + all responses up to the next user turn) with **two-layer semantics**: the LLM context (`rawMessages`) drops the turn physically — the model never sees it again, freeing context; the UI keeps the messages, rendered greyed-out with a "deleted" tag, as an audit trail. No undo; a deleted exchange loses its Delete button. Rejected with an error toast while the agent is running or compacting. Root sessions only (sub-session logs don't offer Delete). If the turn was already compacted out of raw context, only the UI marking happens (silent degrade). Once a session has **archived history** the action is refused for the whole session with a plain explanatory notice (not an `Error:` bubble) — per-turn positions can no longer be mapped once older turns left the active file. Design details in [design/session.md](../design/session.md#exchange-deletion-soft-ui--hard-raw), protocol in [design/ws.md](../design/ws.md).
|
|
25
|
+
|
|
26
|
+
### Archived history (scroll up to load)
|
|
27
|
+
Long sessions get their older exchanges moved out of the active log on compact, so opening a session stays fast no matter how long it has run. Loading older messages is **two-tiered** — a local, no-network tier first, then the network-backed archive:
|
|
28
|
+
|
|
29
|
+
- A session opens rendering only the **most recent 30 exchanges**; older ones already sit in memory (loaded with the session) but aren't mounted, so a long session doesn't cost a slow first render
|
|
30
|
+
- Scrolling to the very top (or clicking the **"Show earlier messages"** row) widens this local window by 30 more exchanges at a time, straight from memory — no request. This can repeat until every in-memory exchange is shown
|
|
31
|
+
- Only once the local window is fully expanded does the next scroll-to-top (or the "Load earlier messages" row that takes over the same slot) reach for the **network** tier: it loads one archived segment per gesture, oldest-newer order preserved, and becomes "No earlier messages" once everything is loaded. The two tiers can't be skipped or reordered — the archive row only appears once there's nothing left to expand locally
|
|
32
|
+
- Either tier preserves the reading position when older messages prepend — the view doesn't jump
|
|
33
|
+
- Loaded archive segments sit in a **collapsed** block ("Archived · N segment(s) · M messages") — the user scrolled up for older context, not to have hundreds of exchanges re-flow the view; expanding renders them like normal messages, growing **upward** so the viewport stays pinned to the newest end, with the expand/collapse toggle below the revealed content
|
|
34
|
+
- Archived exchanges are **read-only**: Copy still works, Delete is absent (the server refuses it for archived sessions)
|
|
35
|
+
- Segments already loaded aren't re-fetched; a failed load can simply be retried with the same row
|
|
25
36
|
|
|
26
37
|
### Session sidebar (right side)
|
|
27
38
|
A fixed, collapsible list of the workspace's root sessions on the right edge of the chat panel (terminal-list style, ~200px). Replaces the old popup dropdown — the History button (with count badge) left of the composer and the "N previous sessions" link in the empty state both just toggle it now. Open/collapsed state persists globally in `localStorage` (`halo_session_sidebar_open`), default open.
|
|
28
39
|
|
|
29
|
-
- Each row: 🎯 goal badge, title, `N msgs · time-ago`, model tail; hover reveals **rename** (pencil) and **delete** buttons; infinite scroll pages older sessions; "+ New Session" footer
|
|
40
|
+
- Each row: 🎯 goal badge, title, `N msgs · time-ago`, model tail; hover reveals **rename** (pencil) and **delete** buttons; infinite scroll pages older sessions; "+ New Session" footer. `N` counts the session's user turns **over its whole lifetime** — compacting or archiving history never makes it go backwards
|
|
30
41
|
- **Inline rename**: pencil → input in place, Enter/blur commits (`PATCH /sessions/logs/:id`), Esc cancels; empty or unchanged title is a no-op. Other session-list consumers refresh via the `session:changed` WS push
|
|
31
42
|
- **Switch loading**: clicking a row shows a spinner on that row + a "Loading session…" state in the message area, cleared only when the server's `state:snapshot` for that exact sessionId arrives (empty sessions included). Past 30s it degrades to "Slow network — still loading…" plus a Retry button (re-subscribes) — slow ≠ failed, nothing aborts on its own
|
|
32
43
|
|
|
@@ -34,14 +34,17 @@ When agents write files through tools, the canvas detects it:
|
|
|
34
34
|
Open tabs and the active tab live in localStorage; survive refresh.
|
|
35
35
|
|
|
36
36
|
### Diff view
|
|
37
|
-
- Tracked files → `GET /api/
|
|
37
|
+
- Tracked files → `GET /api/git/diff` (returns `{ original, modified }`) for git diff
|
|
38
38
|
- Monaco left/right compare view
|
|
39
39
|
|
|
40
40
|
### Binary previews
|
|
41
41
|
Non-text files go through `FilePreview`, which looks up a **plugin** in the preview registry by file extension. Built-in plugins:
|
|
42
42
|
- **PDF** — browser-native iframe
|
|
43
43
|
- **DOCX / DOC** — `mammoth` → HTML (parsed in a Web Worker so the UI stays responsive)
|
|
44
|
-
- **XLSX / XLS
|
|
44
|
+
- **XLSX / XLS** — `xlsx` (SheetJS) → table, parsed whole in a Web Worker (zip can't stream); rendered with client-side paging (500 rows/page over the in-memory parse — no truncation, just paged)
|
|
45
|
+
- **CSV / TSV** — server-paginated table: each page (100 rows) is parsed and fetched from the server on demand, so large files open instantly. Delimiter is sniffed from the header line (comma/semicolon/tab; `.tsv` forces tab); total row count is a lazy lower bound ("N+") until the last page is reached
|
|
46
|
+
- **Parquet** — server-paginated table (schema + 100-row pages), same pager as CSV/SQLite
|
|
47
|
+
- **SQLite / DB (.db / .sqlite / .sqlite3)** — server-paginated table with a table-selector sidebar (name + row count per table); opened read-only, one page (100 rows) per request
|
|
45
48
|
- **PPTX / PPT** — `pptx-preview` list mode. Fidelity is approximate — complex animations / SmartArt / embedded fonts may not render perfectly; users can download for the exact source. Flagged `heavy: true` so only the *active* pptx mounts (canvas-based rendering needs the main thread). **Speaker-notes sidebar**: notes are extracted from the pptx zip in presentation (play) order and listed on the left; clicking a note scrolls to the corresponding slide (a domIndex mapping bridges play order to pptx-preview's part-filename render order, so reordered decks still land on the right slide). Collapsible with the state remembered in localStorage (`halo.pptxNotesHidden`); the sidebar doesn't appear at all when no slide has notes. Decks with dangling `[Content_Types].xml` overrides (e.g. some WPS exports) are repaired before rendering; if zero slides render anyway, a real error UI is shown instead of a silent black wrapper
|
|
46
49
|
- **Images / video / audio** — native `<img>` / `<video>` / `<audio>`, supports HTTP Range for seek-without-full-download
|
|
47
50
|
|
|
@@ -43,6 +43,7 @@ Visual directory browser opened by the 📁🔍 button:
|
|
|
43
43
|
- No max depth limit
|
|
44
44
|
- Expansion state lives in localStorage; restored on refresh and lazily reloaded
|
|
45
45
|
- WebSocket `file:changed` events incrementally update loaded branches; unloaded branches are left alone (re-fetched on expand)
|
|
46
|
+
- **Reconnect reconciliation**: because the tree is kept in sync purely by `file:changed` deltas, events missed while the socket was down (laptop lid, network drop) would leave it stale forever. On WS *re*connect (not first connect) the root level is silently refetched; expanded directories self-heal because their fresh nodes come back without children, which re-arms the lazy-load along the persisted expanded-paths spine
|
|
46
47
|
|
|
47
48
|
### Selection model
|
|
48
49
|
VS Code-style highlight selection (no checkboxes):
|
|
@@ -6,7 +6,7 @@ Session history viewer: hierarchy tree, message playback, debug mode, system pro
|
|
|
6
6
|
|
|
7
7
|
### Session tree view
|
|
8
8
|
- Top-level sessions (no parentSessionId) act as roots; child sessions render indented
|
|
9
|
-
- Each row shows: title, agent-name badge, message count, relative time, and status icons (StopCircle for stopped, amber Archive for archived)
|
|
9
|
+
- Each row shows: title, agent-name badge, message count (user turns over the session's lifetime — never shrinks when history is compacted/archived), relative time, and status icons (StopCircle for stopped, amber Archive for archived)
|
|
10
10
|
- Clicking loads the full message list into SessionChatPanel
|
|
11
11
|
- Collapse / expand via arrow buttons
|
|
12
12
|
- Clicking the count badge (e.g. "+3") shows total descendant count
|
|
@@ -17,6 +17,7 @@ Session history viewer: hierarchy tree, message playback, debug mode, system pro
|
|
|
17
17
|
- All messages rendered by role
|
|
18
18
|
- Assistant messages render Markdown
|
|
19
19
|
- System messages summarise tool calls
|
|
20
|
+
- For a session whose history was compacted, scrolling to the top shows a "load earlier messages" row; scrolling further or clicking it pulls one archived segment at a time. Pulled history renders expanded above the active log, with a divider marking where it ends, and is read-only (no delete)
|
|
20
21
|
|
|
21
22
|
### Debug mode
|
|
22
23
|
Top Debug toggle (Bug icon). When on:
|
|
@@ -35,8 +36,8 @@ The Prompt button (FileText icon) shows the system prompt used by this session.
|
|
|
35
36
|
- Created on the first `chat` WS message (with a new sessionId)
|
|
36
37
|
- Auto-saved after every `complete` event
|
|
37
38
|
- Sessions restore from disk on refresh / WS reconnect (loaded at subscribe time; running sessions reattach from the detached pool)
|
|
38
|
-
- Deleting a session removes the JSON file and cascade-deletes all descendants in SQLite
|
|
39
|
-
- Assistant messages
|
|
39
|
+
- Deleting a session removes the JSON file (plus any archived history segments) and cascade-deletes all descendants in SQLite
|
|
40
|
+
- Assistant messages persist their `contentBlocks` (text / thinking / tool calls, in the order they happened) so tool-call cards survive a refresh in the right places. Sessions written before content blocks existed carry a flat `toolCalls` array instead and still render, as a fallback
|
|
40
41
|
|
|
41
42
|
### Non-destructive /session new
|
|
42
43
|
`/session new` (session:clear) **does not** destroy the old session:
|
|
@@ -63,6 +64,7 @@ Unified session logs API (recommended):
|
|
|
63
64
|
|---|---|
|
|
64
65
|
| List | `GET /api/sessions/logs?projectId=...` |
|
|
65
66
|
| Read | `GET /api/sessions/logs/:id?projectId=...` |
|
|
67
|
+
| Read archived history | `GET /api/sessions/logs/:id/archive/:n?projectId=...` |
|
|
66
68
|
| Delete | `DELETE /api/sessions/logs/:id?projectId=...` |
|
|
67
69
|
|
|
68
70
|
The List endpoint serves two consumers: this tree view (default — roots + all
|
|
@@ -46,6 +46,7 @@ The panel, the history graph, and the Explorer git decorations all refresh on th
|
|
|
46
46
|
|
|
47
47
|
- **Panel-driven writes**: every git mutation route (stage/unstage/commit/push/pull/init/remote) re-broadcasts `file:changed` (path `.git`) itself, because the workspace file watcher deliberately ignores `.git`. So after a commit the CHANGES list auto-clears with no manual refresh.
|
|
48
48
|
- **Command-line writes**: a lightweight, **non-recursive** watch on the `.git` directory's top-level `HEAD` / `index` files (separate from the recursive workspace watcher, which excludes `.git` to avoid being overwhelmed by object-store inodes) catches terminal `git commit` / `checkout` / `add` / `reset` and broadcasts the same `file:changed`. `.lock` churn is filtered; the operation's events are debounced into a single refresh. So a commit made in the integrated terminal updates the panel without a manual refresh.
|
|
49
|
+
- **Reconnect reconciliation**: `file:changed` is a fire-and-forget push, so anything that happened while the socket was down (laptop lid, network drop) is simply lost. Panel, history graph and Explorer decorations therefore also refresh once on WS *re*connect (first connect is skipped — the initial load already fetched), which is the only way a terminal commit made during the outage shows up without a manual refresh.
|
|
49
50
|
- **Two-phase watcher**: `GitDirWatcher` adapts to whether the workspace is a repo yet. A real work-tree watches `.git` directly (the steady state above). A **non-git folder** instead watches the workspace *root* (still non-recursive) for one thing only — `.git` appearing — so a terminal `git init` / `git clone` is noticed and upgrades the watcher onto `.git`, firing once so the [entry auto-surfaces](#entry-visibility-git-gated). The root-watch handler compares the event filename before any disk IO (ordinary file churn costs one string compare), and a real repo never enters this degraded mode.
|
|
50
51
|
|
|
51
52
|
## Explorer git decorations
|