Skip to content

feat(linux): add Waybar and Quickshell shell - #1

Open
EaeDave wants to merge 3 commits into
JohnC0de:mainfrom
EaeDave:feat/linux-shell
Open

feat(linux): add Waybar and Quickshell shell#1
EaeDave wants to merge 3 commits into
JohnC0de:mainfrom
EaeDave:feat/linux-shell

Conversation

@EaeDave

@EaeDave EaeDave commented Aug 7, 2026

Copy link
Copy Markdown

Summary

  • add a Linux CLI backed by ss and /proc, reusing the shared enrichment contracts
  • add a Waybar count module and a polished Quickshell popover with grouped open/kill actions
  • handle shared listeners, POSIX command paths, local installation, and Linux documentation

Testing

  • npm test
  • npm run build:linux
  • live Omarchy smoke tests for discovery, Waybar count, empty/active popovers, and process-tree kill

Summary by cubic

Adds a Linux shell preview with a dev-tray-linux CLI, a Waybar count module, and a Quickshell popover. This adds branch-aware sessions and stronger error handling while keeping the desktop app Windows-only.

  • New Features
    • dev-tray-linux: scans via ss + /proc, enriches with @dev-tray/core, and exposes scan, waybar, open <port>, and kill <pid>; validates PIDs, selects the real listener owner via parent-chain, and kills process trees (SIGTERM then SIGKILL).
    • Session state: persists branchAtStart per PID/start time under XDG state to flag branch drift; includes tests.
    • Shell UI (Waybar + Quickshell): Waybar JSON with escaped tooltip and active|idle|error classes; popover with project grouping (flat rows show project names), open/kill with confirm, 5s auto-refresh, 15s scan timeout, rescan-after-finish, and clear PATH errors with a retry action.
    • Core/docs/tooling: extracts absolute POSIX paths in commands with tests; local install script and npm scripts (build:linux, install:linux, scan:linux); README and ARCHITECTURE updated.

Written for commit f9a5873. Summary will update on new commits.

Review in cubic

Keep Linux discovery and UI modular while reusing the shared enrichment contracts.
@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Novos Recursos

    • Adicionado preview Linux para monitorar, abrir e encerrar servidores locais.
    • Disponibilizadas integrações com Waybar e Quickshell, incluindo atualização automática, estados de carregamento e tratamento de erros.
    • Incluída CLI Linux para escanear processos e controlar servidores.
  • Melhorias

    • Adicionado instalador local e novos comandos de build, instalação e inspeção.
    • Detecção de caminhos ampliada para ambientes Windows e Linux.
  • Documentação

    • README e documentação de arquitetura atualizados com suporte multiplataforma e instruções de uso.

Walkthrough

A alteração adiciona um preview Linux para descoberta, visualização, abertura e encerramento de servidores locais. O fluxo usa ss, /proc, Waybar e Quickshell. A resolução de caminhos agora aceita formatos POSIX e Windows.

Changes

Preview Linux

Layer / File(s) Summary
Resolução de caminhos multiplataforma
packages/core/src/enrich/candidate-dirs.ts, packages/core/test/enrich-pipeline.test.ts
A extração de caminhos aceita caminhos POSIX e Windows, argumentos citados e valores com =. Os testes cobrem caminhos POSIX com espaços.
Scanner e controle de processos Linux
apps/linux/src/linux-scanner.ts, apps/linux/test/linux-scanner.test.ts
O scanner interpreta listeners do ss, seleciona proprietários por relações de parentesco, lê metadados de /proc, resolve branches Git e encerra árvores de processos. Os testes cobrem parsing, deduplicação e seleção ancestral.
CLI e interfaces de desktop
apps/linux/src/cli.ts, apps/linux/waybar-module.jsonc, apps/linux/waybar-style.css, apps/linux/quickshell/shell.qml
A CLI adiciona os comandos scan, waybar, kill e open. Waybar exibe o payload JSON. Quickshell agrupa servidores, mostra estados de carregamento, vazio e erro, e permite abrir ou encerrar servidores.
Build, instalação e documentação Linux
apps/linux/package.json, apps/linux/tsconfig.json, apps/linux/vitest.config.ts, apps/linux/install-local.sh, package.json, README.md, docs/ARCHITECTURE.md
O pacote Linux recebe scripts de build, teste e instalação local. O repositório documenta os fluxos Windows e Linux, os requisitos e a configuração das interfaces Linux.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Waybar
  participant Quickshell
  participant CLI
  participant linuxScanner
  participant ss
  participant proc
  Waybar->>CLI: executar dev-tray-linux waybar
  Quickshell->>CLI: executar scan, open ou kill
  CLI->>linuxScanner: consultar ou alterar servidores
  linuxScanner->>ss: ler listeners TCP
  linuxScanner->>proc: ler processos e diretórios de trabalho
  linuxScanner-->>CLI: retornar entradas ou resultado
  CLI-->>Waybar: retornar JSON
  CLI-->>Quickshell: retornar dados da operação
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed O título descreve corretamente a adição das integrações Waybar e Quickshell no suporte Linux.
Description check ✅ Passed A descrição aborda diretamente a CLI Linux, os módulos Waybar e Quickshell, a instalação, a documentação e os testes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 20

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/linux/install-local.sh`:
- Around line 7-9: Atualize o script de instalação local para usar
`${XDG_CONFIG_HOME:-$HOME/.config}/quickshell` ao criar o link do Quickshell e
garantir que o diretório de binários instalado esteja disponível no PATH.
Informe explicitamente ao usuário as configurações necessárias para que `qs -c
dev-tray` e os chamadores de `dev-tray-linux` em `shell.qml` e
`waybar-module.jsonc` funcionem no ambiente gráfico.
- Line 12: Update the README’s dev-tray usage instructions to include the -d
daemonize flag, matching the command printed by the installer’s start message.
Keep the documented command consistent with `qs -c dev-tray -d`.

In `@apps/linux/quickshell/shell.qml`:
- Line 495: Atualize os Accessible.name dos botões de abrir e encerrar
associados a groupBlock para incluir também a porta do servidor, além de
groupBlock.group.name, garantindo que cada linha seja distinguível e que as
ações destrutivas tenham identificação única.
- Around line 279-318: Padronize para um único idioma todo o texto visível ao
usuário nas superfícies Linux: atualize os textos em português do painel
Quickshell neste bloco e as mensagens em inglês do tooltip do Waybar e do
scanner, incluindo a saída associada a “No dev servers” e “PID ${pid} is not a
listed dev server”. Preserve o significado e a consistência entre as mensagens.
- Around line 82-86: Atualize o catch do fluxo de leitura do scanner para
registrar o erro original no console, preservando a limpeza de entries e groups
e a mensagem exibida ao usuário. Também valide e trate o exitCode de
scanProcess, distinguindo falhas de execução, como dev-tray-linux ausente no
PATH, das respostas inválidas antes de processar o conteúdo.
- Around line 107-109: Atualize o fluxo de confirmação de encerramento em torno
de killProcess.exec para não iniciar uma nova execução enquanto
killProcess.running estiver ativo. Bloqueie novas ações de encerramento durante
a execução ou enfileire cada requestKill para processamento sequencial,
garantindo que o comando anterior termine antes do próximo começar.
- Around line 164-172: Atualize o PanelWindow identificado por id panel para
fechar o painel ao pressionar Escape, atribuindo false a root.panelVisible, e
encaminhe o foco para o conteúdo quando a visibilidade mudar para true. Preserve
o comportamento atual de dimensões e visibilidade, garantindo que o foco inicial
permita a navegação por Tab.

In `@apps/linux/src/cli.ts`:
- Around line 58-64: Share the resolved command from main with its error handler
so the default 'scan' command is preserved when no argument is provided. Update
the main/handler flow around main and the catch block to use that resolved
command for branching, ensuring scan failures emit the expected JSON on stdout.
- Around line 50-51: Atualize o fluxo que abre URLs para usar spawn com
detached: true e stdio: 'ignore', substituindo execFile e child.unref. Não
descarte falhas silenciosamente: preserve um mecanismo de erro apropriado para
informar quando xdg-open não existir ou falhar, sem criar pipes de
stdout/stderr.
- Around line 30-32: Atualize a construção de tooltip próxima à variável tooltip
para escapar projectName e framework antes de interpolá-los, convertendo &amp;,
&lt; e &gt; conforme necessário para o markup Pango do Waybar. Preserve o
formato atual das entradas, separadores e a mensagem “No dev servers”.

In `@apps/linux/src/linux-scanner.ts`:
- Around line 73-92: Rename the local process variables in the grouping and
scoring callbacks around the owners calculation, and in killEntry, to socket or
candidateProcess so they no longer shadow Node’s global process object; update
all references within those scopes consistently, preserving the existing
behavior.
- Around line 115-118: Prevent indefinite Linux scans at both affected sites: in
apps/linux/src/linux-scanner.ts:115-118, update collectSocketProcesses and its
execFileAsync('ss', ...) options to include timeout and maxBuffer consistent
with execGitBranch; in apps/linux/quickshell/shell.qml:89-97, add a protection
Timer that cancels scanProcess, sets errorMessage, and clears loading when the
scan exceeds the expected duration.
- Around line 142-154: Atualize o fluxo de scan em torno de scanEntries e
sessions.merge para persistir branchAtStart por PID fora da memória do processo,
reutilizando esse estado nas chamadas subsequentes da CLI Linux. Preserve a
detecção de branchDrifted quando branchCurrent divergir do valor persistido;
caso não seja possível adicionar persistência, remova explicitamente o suporte a
drift em vez de apresentar comparações incorretas.
- Around line 182-195: Atualize o fluxo que coleta `tree` e executa o segundo
loop de sinais para capturar o `starttime` de cada PID no momento da coleta.
Antes de chamar `process.kill(target, 'SIGKILL')`, releia o `starttime`
correspondente em `/proc` e só envie o sinal quando o valor permanecer idêntico;
trate processos ausentes ou leituras inválidas como inelegíveis para o SIGKILL.

In `@apps/linux/test/linux-scanner.test.ts`:
- Around line 34-46: Expand the selectListenerOwners tests to cover grouping
processes by different ports, terminating ancestor traversal when the injected
parentOf chain cycles via the seen set, and selecting the lowest PID when
candidates are unrelated. Use injected parent mappings in each case and preserve
the existing direct-ancestor assertion.

In `@apps/linux/waybar-module.jsonc`:
- Around line 1-7: Make apps/linux/waybar-module.jsonc a valid standalone JSONC
document by wrapping the existing "custom/dev-tray" configuration in a top-level
object, preserving all current module properties and values.

In `@apps/linux/waybar-style.css`:
- Around line 1-3: Update the `#custom-dev-tray` styles to add a .error rule for
the CLI-emitted error class, applying visible emphasis to the error state while
preserving the existing margin styling.

In `@docs/ARCHITECTURE.md`:
- Line 70: Atualize o fence Markdown iniciado na seção de layout de
docs/ARCHITECTURE.md para declarar explicitamente a linguagem text, preservando
o conteúdo e o fechamento do bloco.

In `@packages/core/src/enrich/candidate-dirs.ts`:
- Around line 28-38: Atualize o laço de tokenização em extractPaths em
packages/core/src/enrich/candidate-dirs.ts#L28-L38 para reconhecer valores entre
aspas em qualquer posição do token, evitar cortar no primeiro '=' quando o
trecho anterior já for um caminho absoluto e remover as aspas somente após esse
corte. Em packages/core/test/enrich-pipeline.test.ts#L69-L77, adicione um caso
para --config="/home/dev/my app/config.js" e verifique a extração desse caminho.

In `@packages/core/test/enrich-pipeline.test.ts`:
- Around line 69-77: Extend the `extracts absolute POSIX command-line paths`
test for `extractPaths` with an option assignment whose quoted value contains
spaces, such as `--config="/path with space/config.js"`, and assert that the
quoted path is extracted correctly.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8a2822a1-cf39-490c-930d-8e81f5e8570f

📥 Commits

Reviewing files that changed from the base of the PR and between fea2331 and 635492b.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (15)
  • README.md
  • apps/linux/install-local.sh
  • apps/linux/package.json
  • apps/linux/quickshell/shell.qml
  • apps/linux/src/cli.ts
  • apps/linux/src/linux-scanner.ts
  • apps/linux/test/linux-scanner.test.ts
  • apps/linux/tsconfig.json
  • apps/linux/vitest.config.ts
  • apps/linux/waybar-module.jsonc
  • apps/linux/waybar-style.css
  • docs/ARCHITECTURE.md
  • package.json
  • packages/core/src/enrich/candidate-dirs.ts
  • packages/core/test/enrich-pipeline.test.ts

Comment thread apps/linux/install-local.sh Outdated
Comment thread apps/linux/install-local.sh
Comment thread apps/linux/quickshell/shell.qml
Comment thread apps/linux/quickshell/shell.qml Outdated
Comment thread apps/linux/quickshell/shell.qml
Comment thread apps/linux/waybar-module.jsonc Outdated
Comment thread apps/linux/waybar-style.css
Comment thread docs/ARCHITECTURE.md Outdated
Comment thread packages/core/src/enrich/candidate-dirs.ts Outdated
Comment thread packages/core/test/enrich-pipeline.test.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 16 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread apps/linux/src/linux-scanner.ts Outdated
Comment thread packages/core/src/enrich/candidate-dirs.ts Outdated
Comment thread packages/core/src/enrich/candidate-dirs.ts Outdated
Comment thread apps/linux/src/cli.ts Outdated
Comment thread apps/linux/src/cli.ts Outdated
Comment thread apps/linux/quickshell/shell.qml
Comment thread apps/linux/quickshell/shell.qml Outdated
Comment thread README.md
Comment thread apps/linux/quickshell/shell.qml Outdated
Comment thread apps/linux/src/linux-scanner.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

7 issues found across 13 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/core/src/enrich/candidate-dirs.ts">

<violation number="1" location="packages/core/src/enrich/candidate-dirs.ts:37">
P2: Linux command-line project detection breaks for valid paths containing quote characters when the process cwd is unavailable: `commandTokens` treats the literal apostrophe as shell syntax and removes it. Preserving literal argv characters (or serializing every argument with quotes/escapes before tokenizing) keeps fallback attribution correct.</violation>
</file>

<file name="apps/linux/quickshell/shell.qml">

<violation number="1" location="apps/linux/quickshell/shell.qml:190">
P2: A failed browser launch hides the discovered server list under the “Server scan failed” panel and stops auto-refresh, even though scanning itself may still work. Keeping action errors separate from scan state, or retaining the list while showing the action error, would avoid making a transient open failure look like a scan failure.</violation>

<violation number="2" location="apps/linux/quickshell/shell.qml:484">
P2: The new group collapse/expand control doesn't persist: its state lives in the delegate-local `collapsed` property, but the 5s auto-refresh rebuilds `root.groups` via `groupEntries` on every scan, which recreates all delegates and resets `collapsed` to `false`. In practice a collapsed group springs back open within seconds, making the collapse feature effectively unusable with auto-refresh enabled. Consider persisting collapsed state keyed by group key (e.g., a `collapsedKeys` set on the root, or tracking per-group keys) rather than in the delegate so it survives model rebuilds.</violation>

<violation number="3" location="apps/linux/quickshell/shell.qml:593">
P2: Slow probes are displayed and announced as unknown because this new mapping handles only alive and dead. Adding an explicit `slow` branch would preserve the health distinction exposed by the core and desktop UI.</violation>
</file>

<file name="apps/linux/src/linux-scanner.ts">

<violation number="1" location="apps/linux/src/linux-scanner.ts:251">
P2: Concurrent Waybar and Quickshell scans can lose persisted session records: the last scan to rename its snapshot wins even when it started from stale state. Locking the state update or reloading/merging immediately before writing would keep branch-at-start records stable across overlapping scans.</violation>

<violation number="2" location="apps/linux/src/linux-scanner.ts:299">
P1: The kill workflow can still terminate an unrelated process after PID reuse because descendant discovery, identity checking, and `process.kill` are not atomic. Using Linux pidfds (or another identity-bound signal handle) for each discovered process would preserve the start-time safety guarantee through both signals.</violation>
</file>

<file name="apps/linux/install-local.sh">

<violation number="1" location="apps/linux/install-local.sh:13">
P2: The new PATH guard hard-fails the whole install (`exit 1` before creating anything) whenever `~/.local/bin` isn't already on PATH. For a first-time user that's a chicken-and-egg: they run the installer expecting it to set up the binary, but it aborts and creates nothing, forcing a manual two-step. It also checks the installer's own transient shell PATH rather than the graphical session's — the README already tells users to keep the two in sync precisely because they can differ — so the guard gives a false sense of certainty about the actual goal. Consider downgrading the hard failure to a clear warning (install anyway) or offering to create `~/.local/bin`, so a fresh setup isn't a dead end; and use an exact equality on a `:`-delimited entry (rather than a `case` glob) so homedirs containing glob metacharacters don't produce a false mismatch.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic


const seen = new Set<number>();
const tree = selected.flatMap((entry) => processTree(entry.pid, seen));
const startTimes = new Map(tree.map((target) => [target, readProcessStartTime(target)]));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: The kill workflow can still terminate an unrelated process after PID reuse because descendant discovery, identity checking, and process.kill are not atomic. Using Linux pidfds (or another identity-bound signal handle) for each discovered process would preserve the start-time safety guarantee through both signals.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/linux/src/linux-scanner.ts, line 299:

<comment>The kill workflow can still terminate an unrelated process after PID reuse because descendant discovery, identity checking, and `process.kill` are not atomic. Using Linux pidfds (or another identity-bound signal handle) for each discovered process would preserve the start-time safety guarantee through both signals.</comment>

<file context>
@@ -172,24 +278,46 @@ function processTree(pid: number, seen = new Set<number>()): number[] {
   const seen = new Set<number>();
-  const tree = socketPids.flatMap((socketPid) => processTree(socketPid, seen));
+  const tree = selected.flatMap((entry) => processTree(entry.pid, seen));
+  const startTimes = new Map(tree.map((target) => [target, readProcessStartTime(target)]));
+  for (const entry of selected) {
+    if (startTimes.get(entry.pid) !== entry.startTime) {
</file context>

token += quote;
index += 1;
} else token += character;
} else if (character === '"' || character === "'") {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Linux command-line project detection breaks for valid paths containing quote characters when the process cwd is unavailable: commandTokens treats the literal apostrophe as shell syntax and removes it. Preserving literal argv characters (or serializing every argument with quotes/escapes before tokenizing) keeps fallback attribution correct.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/enrich/candidate-dirs.ts, line 37:

<comment>Linux command-line project detection breaks for valid paths containing quote characters when the process cwd is unavailable: `commandTokens` treats the literal apostrophe as shell syntax and removes it. Preserving literal argv characters (or serializing every argument with quotes/escapes before tokenizing) keeps fallback attribution correct.</comment>

<file context>
@@ -21,21 +21,52 @@ export function dirOf(
+        token += quote;
+        index += 1;
+      } else token += character;
+    } else if (character === '"' || character === "'") {
+      quote = character;
+    } else if (/\s/.test(character)) {
</file context>

radius: 3
color: serverRow.entry.health === "alive" ? root.colorAlive
: serverRow.entry.health === "dead" ? root.colorDanger
: root.colorSubtle

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Slow probes are displayed and announced as unknown because this new mapping handles only alive and dead. Adding an explicit slow branch would preserve the health distinction exposed by the core and desktop UI.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/linux/quickshell/shell.qml, line 593:

<comment>Slow probes are displayed and announced as unknown because this new mapping handles only alive and dead. Adding an explicit `slow` branch would preserve the health distinction exposed by the core and desktop UI.</comment>

<file context>
@@ -451,30 +588,55 @@ Scope {
-                                                    Accessible.name: "Servidor ativo"
+                                                    color: serverRow.entry.health === "alive" ? root.colorAlive
+                                                           : serverRow.entry.health === "dead" ? root.colorDanger
+                                                           : root.colorSubtle
+                                                    Accessible.name: serverRow.entry.health === "alive"
+                                                                     ? "Server healthy"
</file context>


onExited: (exitCode, exitStatus) => {
if (exitCode !== 0)
root.errorMessage = "Could not open the server in your browser."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: A failed browser launch hides the discovered server list under the “Server scan failed” panel and stops auto-refresh, even though scanning itself may still work. Keeping action errors separate from scan state, or retaining the list while showing the action error, would avoid making a transient open failure look like a scan failure.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/linux/quickshell/shell.qml, line 190:

<comment>A failed browser launch hides the discovered server list under the “Server scan failed” panel and stops auto-refresh, even though scanning itself may still work. Keeping action errors separate from scan state, or retaining the list while showing the action error, would avoid making a transient open failure look like a scan failure.</comment>

<file context>
@@ -123,42 +161,78 @@ Scope {
+
+        onExited: (exitCode, exitStatus) => {
+            if (exitCode !== 0)
+                root.errorMessage = "Could not open the server in your browser."
+        }
     }
</file context>

execGitBranch,
}, caches);
const merged = mergeSessionState(partial, loadSessionState());
saveSessionState(merged.state);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Concurrent Waybar and Quickshell scans can lose persisted session records: the last scan to rename its snapshot wins even when it started from stale state. Locking the state update or reloading/merging immediately before writing would keep branch-at-start records stable across overlapping scans.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/linux/src/linux-scanner.ts, line 251:

<comment>Concurrent Waybar and Quickshell scans can lose persisted session records: the last scan to rename its snapshot wins even when it started from stale state. Locking the state update or reloading/merging immediately before writing would keep branch-at-start records stable across overlapping scans.</comment>

<file context>
@@ -128,29 +225,38 @@ export async function collectScanRows(): Promise<ScanRow[]> {
     execGitBranch,
   }, caches);
+  const merged = mergeSessionState(partial, loadSessionState());
+  saveSessionState(merged.state);
 
-  return sessions.merge(partial).map((entry) => ({
</file context>

width: groupsColumn.width

property bool grouped: group.items.length > 1
property bool collapsed: false

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The new group collapse/expand control doesn't persist: its state lives in the delegate-local collapsed property, but the 5s auto-refresh rebuilds root.groups via groupEntries on every scan, which recreates all delegates and resets collapsed to false. In practice a collapsed group springs back open within seconds, making the collapse feature effectively unusable with auto-refresh enabled. Consider persisting collapsed state keyed by group key (e.g., a collapsedKeys set on the root, or tracking per-group keys) rather than in the delegate so it survives model rebuilds.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/linux/quickshell/shell.qml, line 484:

<comment>The new group collapse/expand control doesn't persist: its state lives in the delegate-local `collapsed` property, but the 5s auto-refresh rebuilds `root.groups` via `groupEntries` on every scan, which recreates all delegates and resets `collapsed` to `false`. In practice a collapsed group springs back open within seconds, making the collapse feature effectively unusable with auto-refresh enabled. Consider persisting collapsed state keyed by group key (e.g., a `collapsedKeys` set on the root, or tracking per-group keys) rather than in the delegate so it survives model rebuilds.</comment>

<file context>
@@ -395,34 +480,86 @@ Scope {
                                     width: groupsColumn.width
 
+                                    property bool grouped: group.items.length > 1
+                                    property bool collapsed: false
+
                                     RowLayout {
</file context>

*)
echo "Dev Tray needs $bin_dir on PATH in the graphical session." >&2
echo "Add 'export PATH=\"\$HOME/.local/bin:\$PATH\"' to your session environment, then rerun this installer." >&2
exit 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The new PATH guard hard-fails the whole install (exit 1 before creating anything) whenever ~/.local/bin isn't already on PATH. For a first-time user that's a chicken-and-egg: they run the installer expecting it to set up the binary, but it aborts and creates nothing, forcing a manual two-step. It also checks the installer's own transient shell PATH rather than the graphical session's — the README already tells users to keep the two in sync precisely because they can differ — so the guard gives a false sense of certainty about the actual goal. Consider downgrading the hard failure to a clear warning (install anyway) or offering to create ~/.local/bin, so a fresh setup isn't a dead end; and use an exact equality on a :-delimited entry (rather than a case glob) so homedirs containing glob metacharacters don't produce a false mismatch.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/linux/install-local.sh, line 13:

<comment>The new PATH guard hard-fails the whole install (`exit 1` before creating anything) whenever `~/.local/bin` isn't already on PATH. For a first-time user that's a chicken-and-egg: they run the installer expecting it to set up the binary, but it aborts and creates nothing, forcing a manual two-step. It also checks the installer's own transient shell PATH rather than the graphical session's — the README already tells users to keep the two in sync precisely because they can differ — so the guard gives a false sense of certainty about the actual goal. Consider downgrading the hard failure to a clear warning (install anyway) or offering to create `~/.local/bin`, so a fresh setup isn't a dead end; and use an exact equality on a `:`-delimited entry (rather than a `case` glob) so homedirs containing glob metacharacters don't produce a false mismatch.</comment>

<file context>
@@ -2,11 +2,23 @@
+  *)
+    echo "Dev Tray needs $bin_dir on PATH in the graphical session." >&2
+    echo "Add 'export PATH=\"\$HOME/.local/bin:\$PATH\"' to your session environment, then rerun this installer." >&2
+    exit 1
+    ;;
+esac
</file context>

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.

1 participant