feat: v0.5.0 header, switcher, phone key bar, shared polling, Matrix "needs you"
- Header: no SSO chip ("Sign in again" only on expiry), state dot on the
session chip, LIVE as a dot, ⋯ menu for text size/notifications/fullscreen,
Panels badge for waiting sessions and alerts.
- Session switcher on the chip; bare URL reattaches the last session; + New
opens the panel form with project folders.
- Notifications when other sessions start waiting; alerts polled with the
panels closed; one tab polls for all tabs over BroadcastChannel.
- Sidebar: context bar per session instead of the Context panel; compact
Repo/CI with "Ask Claude to fix CI"; legible labels.
- Phone: key bar, drawer with backdrop, visualViewport-aware layout, DOM
renderer on touch, compact connection dot.
- devdesk-notify-matrix: one Matrix message per wait that lasts
DEVDESK_MATRIX_DELAY seconds with nobody attached.
Closes #8
Closes #13
Closes #14
Closes #15
Closes #16
Closes #17
Closes #28
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+16
-11
@@ -21,21 +21,21 @@ function link(href, text) {
|
||||
export function renderRepo(root, repo) {
|
||||
const field = (name) => root.querySelector(`[data-field="${name}"]`);
|
||||
const set = (name, value) => field(name).replaceChildren(value);
|
||||
const grid = root.querySelector('.dd-repo-grid');
|
||||
const note = root.querySelector('.dd-repo-note');
|
||||
const fix = root.querySelector('.dd-fix-ci');
|
||||
fix.hidden = true;
|
||||
|
||||
// No repository: one line instead of a grid of dashes (devdesk#17).
|
||||
if (!repo || !repo.git) {
|
||||
root.dataset.state = 'empty';
|
||||
for (const f of ['repo', 'branch', 'dirty', 'prs']) set(f, '—');
|
||||
const ci = field('ci');
|
||||
ci.className = 'lt-status lt-status-pending';
|
||||
ci.textContent = 'no data';
|
||||
note.textContent = repo
|
||||
? `${repo.dir} is not a git repository.`
|
||||
: 'Open a session to see its repository.';
|
||||
grid.hidden = true;
|
||||
note.textContent = repo ? `Not a git repository: ${repo.dir}` : 'Open a session to see its repository.';
|
||||
return;
|
||||
}
|
||||
|
||||
root.dataset.state = 'live';
|
||||
grid.hidden = false;
|
||||
set('repo', repo.url ? link(repo.url, repo.repo) : (repo.remote || 'no remote'));
|
||||
const sync = repo.upstream
|
||||
? [repo.ahead ? `↑${repo.ahead}` : '', repo.behind ? `↓${repo.behind}` : ''].filter(Boolean).join(' ') || 'in sync'
|
||||
@@ -45,12 +45,17 @@ export function renderRepo(root, repo) {
|
||||
|
||||
const ci = field('ci');
|
||||
const [label, cls] = repo.ci?.total ? (CI[repo.ci.state] || [repo.ci.state, 'lt-status-pending'])
|
||||
: [repo.ahead ? 'not pushed' : 'no CI', 'lt-status-pending'];
|
||||
: [repo.ahead ? 'not pushed' : 'no CI', ''];
|
||||
ci.className = `lt-status ${cls}`;
|
||||
ci.replaceChildren(repo.ci?.url ? link(repo.ci.url, label) : label);
|
||||
|
||||
set('prs', repo.url && repo.prs != null
|
||||
? link(`${repo.url}/pulls`, `${repo.prs} open`)
|
||||
: '—');
|
||||
set('prs', repo.url && repo.prs != null ? link(`${repo.url}/pulls`, `${repo.prs} open`) : '—');
|
||||
note.textContent = repo.repo ? '' : 'Not a Gitea repository; CI status unavailable.';
|
||||
|
||||
if (repo.ci?.total && ['failure', 'error'].includes(repo.ci.state)) {
|
||||
fix.hidden = false;
|
||||
fix.dataset.askClaude = `CI is failing for ${repo.repo} on ${repo.branch} at ${repo.sha}`
|
||||
+ ` (${repo.ci.url || 'see Gitea Actions'}). Use the gitea MCP server to read the failed job's log,`
|
||||
+ ' find the cause, and fix it. Tell me the plan before pushing anything.';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user