whose-turn 1.0.0-alpha.3 → 1.0.0-alpha.4
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/CHANGELOG.md +8 -1
- package/README.md +5 -6
- package/config.example.json +0 -16
- package/connectors/index.mjs +1 -2
- package/dist/assets/{index-p8D7awn0.css → index-B23uRijc.css} +1 -1
- package/dist/assets/index-D-P2XKhJ.js +3 -0
- package/dist/index.html +2 -2
- package/lib/config.mjs +1 -1
- package/lib/facts.mjs +1 -1
- package/lib/update.mjs +2 -1
- package/package.json +1 -1
- package/connectors/demo.mjs +0 -146
- package/dist/assets/index-CuyWocyb.js +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to whose-turn are recorded here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow [Semantic Versioning](https://semver.org/).
|
|
4
4
|
|
|
5
|
-
## [
|
|
5
|
+
## [1.0.0-alpha.4] - 2026-11-03
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- The repository is public, and every release is published with npm provenance again. RMA-237.
|
|
9
|
+
- The self-update installs the new version with `--ignore-scripts`, as the plugin's first install does. RMA-236.
|
|
10
|
+
|
|
11
|
+
### Removed
|
|
12
|
+
- The demo connector and the first-run "Try a demo workspace" button. A pre-made workspace belongs to the demo, which is separate work; the scenarios live on as test fixtures. A config that still names a `demo` source reports it as an unknown connector type. RMA-208.
|
|
6
13
|
|
|
7
14
|
## [1.0.0-alpha.3] - 2026-11-03
|
|
8
15
|
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A local monitor that answers "what is waiting on me right now" across the places your work arrives: GitHub pull requests, Jira and Linear tickets, and your own to-dos. It polls each source about once a minute, decides once, on the server, whose turn every ticket is, shows the result in a window that updates live, sends a desktop notification when something becomes your move, and hands any item to an AI assistant as Markdown with its context. Its Claude Code plugin, `whose-turn@bladeforge`, makes a session start with "N your move · M unread · K to-do" already in context.
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|
|
|
7
7
|
Everything runs on your machine: a Node 22 server on `127.0.0.1`, a window built with Vue, and no account anywhere but the sources you already use. Nothing that names an employer, an account or a team process lives in this repository; it all sits in one config file on the machine that owns it.
|
|
8
8
|
|
|
@@ -27,7 +27,7 @@ claude plugin install whose-turn@bladeforge
|
|
|
27
27
|
|
|
28
28
|
## First run
|
|
29
29
|
|
|
30
|
-
The window opens on one card: add a source through the settings sheet (the gear at the bottom of the rail)
|
|
30
|
+
The window opens on one card: add a source through the settings sheet (the gear at the bottom of the rail). A source needs an account and its filters; a token typed into a secret field goes to the platform's secret store, never into the config file. Claude can set a workspace up too, through the `whose_turn_config` MCP tool. From then on the server polls, the window follows, and the Claude Code plugin reads the same server.
|
|
31
31
|
|
|
32
32
|
## Workspaces and connectors
|
|
33
33
|
|
|
@@ -67,7 +67,6 @@ Nothing that names an employer, an account or a team process lives in this repos
|
|
|
67
67
|
| `workspaces[].links` | quick links shown in the header, as `"Label https://…"` strings or `{label, url}`; the repository, the Jira site and the Linear team come from the connectors by themselves |
|
|
68
68
|
| `workspaces[].rules` | the team's process, see Rules below; `statuses` groups, `automation_authors` and `question_words` must be lists of strings (statuses non-empty) or the save is refused |
|
|
69
69
|
| `…connectors.linear.workspace`, `team`, `project` | the Linear workspace slug (the part after linear.app/), and optionally one team key or one project name; the personal API key goes to the secret store under the workspace slug |
|
|
70
|
-
| `…connectors.demo.scenario` | `northwind` (a web team with Jira-like tickets and PRs), `atlas` (a mobile team with other status names) or `garden` (a side project, PRs only); invented data, no network |
|
|
71
70
|
| `workspaces[].theme.seed` | optional hex colour, `#rrggbb`; the window derives its light and dark Material 3 scheme from it (`lib/palette.mjs`); without it the stylesheet's blue stays |
|
|
72
71
|
| `workspaces[].theme.accent` | optional second hex that sets the tertiary hue; defaults to the seed's hue turned by 80 degrees |
|
|
73
72
|
|
|
@@ -99,7 +98,7 @@ On Windows, run `schtasks /Create /SC ONLOGON /TN whose-turn /TR "\"<path to nod
|
|
|
99
98
|
| `lib/api.mjs` | the local HTTP API, SSE stream and static files |
|
|
100
99
|
| `lib/window.mjs` | the app window's remembered size and the launcher behind "Open as app" |
|
|
101
100
|
| `lib/http-client.mjs`, `lib/secrets.mjs` (with `lib/platform/credential.ps1`), `lib/notify.mjs`, `lib/store.mjs`, `lib/errors.mjs`, `lib/text.mjs` | ETag fetch, secret lookup, desktop notification, files on disk, the error envelope, text helpers |
|
|
102
|
-
| `connectors/` | one module per source type
|
|
101
|
+
| `connectors/` | one module per source type |
|
|
103
102
|
| `web/` | the window: a Vue 3 app in TypeScript built with Vite (`web/src/App.vue`, primitives in `web/src/ui/`, one folder per island in `web/src/features/` with its components, composables and tests, shared composables in `web/src/composables/` (ADR 0006), each component's styles in a scoped BEM block (layout and shared primitives in `web/src/styles/base.css`, ADR 0005), pure logic in `web/src/lib/`, the dot-drawn animal in `web/src/backdrop.ts`, Tippy.js 6.3.7 and Popper 2.11.8 pinned in `web/public/vendor/`); `npm run build` writes `dist/`, which the server serves and git ignores (ADR 0001) |
|
|
104
103
|
| `install.sh` | bash installer that picks by `uname`: on macOS the launch agent `local.whose-turn` (log in `~/Library/Logs/whose-turn.log`); on Linux the user unit `~/.config/systemd/user/whose-turn.service` (log in `journalctl --user -u whose-turn`); both start at login and restart on a crash; on other systems it prints the Windows `schtasks` line. The node path is read with `command -v node` at install time |
|
|
105
104
|
| `open.sh` | opens the window as its own app window (Chrome on macOS; Chrome, Chromium or Edge on Linux) at the size it last had, or in a browser tab with `--browser` or when none of those is installed; bash, not zsh, so it runs on Linux too; Windows: open the URL yourself |
|
|
@@ -198,7 +197,7 @@ Requests must carry the local `Host`; a POST must be `application/json`. An erro
|
|
|
198
197
|
|
|
199
198
|
- Material 3 plus glass: tonal surfaces seeded from the workspace's `theme.seed`, or from a seed derived from its id without one, so every workspace has its own colour; translucent blurred islands with 12 px corners, dark and light schemes, a gradient header with stat tiles.
|
|
200
199
|
- Under the glass, an animal drawn in dots (`web/src/backdrop.ts`): one species out of the JSON files in `web/src/species/`, built from shapes whose proportions come from a seeded random, in one of its poses (sitting, walking, sleeping, facing the camera). Each workspace gets its own seed for the session, so switching tabs changes the animal; `window.whoseTurnBackdrop.show({ workspace, seed, species, pose })` picks one and `.species` lists the names (the hook for pinning an animal per workspace, RMA-94). A new animal is a new JSON file, see [`docs/mechanisms/species-dsl.md`](docs/mechanisms/species-dsl.md); `/sheet` draws every species over several seeds without the glass.
|
|
201
|
-
- First run: while the open workspace has no sources, one card replaces the islands. It says what the window does, offers "Add a source" (the settings sheet on this workspace, at its connectors) and
|
|
200
|
+
- First run: while the open workspace has no sources, one card replaces the islands. It says what the window does, offers "Add a source" (the settings sheet on this workspace, at its connectors) and says Claude can set it up too.
|
|
202
201
|
- Two columns. Left: Your move, To do, Waiting on others. Right: the feed. The page never scrolls; each island scrolls inside, with sticky table headers. A PR cell shows the checks or state pill under the PR number.
|
|
203
202
|
- Every header is one line, truncated with an ellipsis. Anything that hides more text gets a "?" icon at the end. Tooltips are Tippy: instant, also on click, interactive, keep line breaks.
|
|
204
203
|
- Your move: one row per thing to do, with a "?" for why it is there, an age chip (amber after 24 h) and a Handled button. Handled rows leave this list; the Handled view in the head lists them, dimmed, with Undo.
|
|
@@ -216,7 +215,7 @@ Requests must carry the local `Host`; a POST must be `application/json`. An erro
|
|
|
216
215
|
|
|
217
216
|
The Claude Code plugin is `whose-turn@bladeforge` in the [BladeForge marketplace](https://github.com/aquivalabs/BladeForge); this repository holds the monitor only. The plugin brings:
|
|
218
217
|
|
|
219
|
-
- the skill `whose-turn:whose-turn`: answers "what's on me" from `/api/summary`, sets up a first workspace
|
|
218
|
+
- the skill `whose-turn:whose-turn`: answers "what's on me" from `/api/summary`, sets up a first workspace, edits the config, opens the window, files feedback and manages to-dos;
|
|
220
219
|
- `/whose-turn`, which opens the window;
|
|
221
220
|
- the SessionStart hook, which starts the monitor if it is down and puts "N your move · M unread · K to-do" into context, marked as data from other people;
|
|
222
221
|
- the prompt hook, which takes waiting hand-offs from the inbox queue into your next message;
|
package/config.example.json
CHANGED
|
@@ -107,22 +107,6 @@
|
|
|
107
107
|
"team": "PROJ"
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
"id": "demo",
|
|
113
|
-
"name": "Demo",
|
|
114
|
-
"key_pattern": "\\bNW-\\d+\\b",
|
|
115
|
-
"theme": {
|
|
116
|
-
"seed": "#3d7a5c",
|
|
117
|
-
"accent": "#c27a2c"
|
|
118
|
-
},
|
|
119
|
-
"connectors": [
|
|
120
|
-
{
|
|
121
|
-
"type": "demo",
|
|
122
|
-
"scenario": "northwind",
|
|
123
|
-
"label": "Demo tracker"
|
|
124
|
-
}
|
|
125
|
-
]
|
|
126
110
|
}
|
|
127
111
|
],
|
|
128
112
|
"feedback": {
|
package/connectors/index.mjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/** The connector registry: every source type the server knows, and the catalogue the settings form and Claude read. */
|
|
2
2
|
import * as github from './github.mjs';
|
|
3
3
|
import * as jira from './jira.mjs';
|
|
4
|
-
import * as demo from './demo.mjs';
|
|
5
4
|
import * as linear from './linear.mjs';
|
|
6
5
|
|
|
7
|
-
export const CONNECTORS = { github, jira, linear
|
|
6
|
+
export const CONNECTORS = { github, jira, linear };
|
|
8
7
|
|
|
9
8
|
/** What a workspace calls each of its connectors: the entry's own label, else its id when another entry has the same type, else the type's label (RMA-167). */
|
|
10
9
|
export const connectorSummaries = (entries) => entries.map((entry) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.rail[data-v-be863916]{position:fixed;inset:0 auto 0 0;z-index:30;box-sizing:border-box;display:flex;flex-direction:column;gap:4px;width:60px;padding:12px 8px;overflow:hidden;border-right:1px solid var(--glass-edge);background:rgb(var(--glass),.72);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);font-family:var(--md-font);color:var(--md-on-surface);transition:width .18s ease,box-shadow .18s ease}.rail[data-v-be863916]:hover,.rail[data-v-be863916]:has(:focus-visible){width:232px;box-shadow:12px 0 32px #0000001f}.app:has(.modal) .rail[data-v-be863916]{z-index:0}.rail__item[data-v-be863916]{position:relative;display:flex;align-items:center;gap:12px;height:44px;padding:0 4px;border-radius:12px;color:inherit;text-decoration:none;white-space:nowrap;cursor:pointer;-webkit-user-select:none;user-select:none}.rail__item[data-v-be863916]:focus-visible{outline:var(--focus-ring);outline-offset:-2px}.rail__item--dragging[data-v-be863916]{opacity:.4}.rail__item[data-drop=before][data-v-be863916]{box-shadow:0 -2px 0 0 var(--md-primary)}.rail__item[data-drop=after][data-v-be863916]{box-shadow:0 2px 0 0 var(--md-primary)}.rail__item[data-v-be863916]:hover{background:var(--state-hover)}.rail__item[aria-selected=true][data-v-be863916]{background:var(--md-secondary-container);color:var(--md-on-secondary-container)}.rail__icon[data-v-be863916]{flex:none;display:block;width:36px;height:36px;border-radius:10px}.rail__gear[data-v-be863916]{flex:none;display:grid;place-items:center;width:36px;height:36px;color:var(--md-on-surface-variant)}.rail__label[data-v-be863916]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;font-size:14px;font-weight:500;opacity:0;transition:opacity .12s ease}.rail:hover .rail__label[data-v-be863916],.rail:has(:focus-visible) .rail__label[data-v-be863916]{opacity:1}.rail__badge[data-v-be863916]{position:absolute;top:2px;left:30px;box-sizing:border-box;min-width:18px;height:18px;padding:0 5px;border-radius:999px;background:var(--md-primary);color:var(--md-on-primary);font-size:10px;font-weight:700;line-height:18px;text-align:center}.rail:hover .rail__badge[data-v-be863916],.rail:has(:focus-visible) .rail__badge[data-v-be863916]{position:static;flex:none}.rail__spacer[data-v-be863916]{flex:1}.ai-button[data-v-d32a60c7]{display:inline-grid;place-items:center;width:26px;height:26px;border-radius:50%;cursor:pointer;color:var(--md-primary);background:rgb(var(--md-state),.06);vertical-align:middle;transition:background .12s ease,transform .12s ease}.ai-button__icon[data-v-d32a60c7]{width:15px;height:15px}.ai-button[data-v-d32a60c7]:hover{background:var(--md-secondary-container);transform:scale(1.08)}.ai-button[data-v-d32a60c7]:focus-visible{outline:var(--focus-ring);outline-offset:1px}.ai-button.ai-button--sent[data-v-d32a60c7]{background:var(--md-tertiary-container);color:var(--md-on-tertiary-container)}.ai-button.ai-button--failed[data-v-d32a60c7]{background:var(--md-error-container);color:var(--md-on-error-container)}.ai-button--big[data-v-d32a60c7]{width:32px;height:32px;background:rgb(var(--glass),.7)}.ai-button--big .ai-button__icon[data-v-d32a60c7]{width:18px;height:18px}.update-chip[data-v-f70d2aed]{display:inline-flex;align-items:center;height:26px;padding:0 12px;font:inherit;color:var(--md-on-primary-container);cursor:pointer;background:var(--md-primary-container);border:0;border-radius:var(--md-r-chip)}.update-chip--busy[data-v-f70d2aed],.update-chip--done[data-v-f70d2aed]{cursor:default}.update-chip--busy[data-v-f70d2aed]{opacity:.7}.update-chip--failed[data-v-f70d2aed]{color:var(--md-on-error-container);background:var(--md-error-container)}.status-bar[data-v-eefe1de8]{display:flex;align-items:center;gap:10px;margin:0 4px 8px;font-family:var(--md-font);font-size:12px;color:var(--md-on-surface-variant)}.status-bar__btn[data-v-eefe1de8]{height:26px;padding:0 12px;font-size:12px;text-decoration:none}.status-bar__btn--busy[data-v-eefe1de8]{opacity:.6;pointer-events:none}.status-bar__report[data-v-eefe1de8]{gap:6px;color:var(--md-error);border-color:var(--md-error)}.status-bar__icon[data-v-eefe1de8]{width:16px;height:16px}.status-bar__live[data-v-eefe1de8]{width:8px;height:8px;border-radius:50%;background:var(--live-on);box-shadow:0 0 0 0 var(--live-pulse-rest);animation:status-bar-pulse-eefe1de8 2s infinite}.status-bar__live--off[data-v-eefe1de8]{background:var(--live-off);animation:none}.status-bar__live--warn[data-v-eefe1de8]{background:var(--live-warn);animation:none}.status-bar__notice[data-v-eefe1de8]{color:var(--live-off)}.status-bar__ai-hint[data-v-eefe1de8]{margin-left:-4px}@keyframes status-bar-pulse-eefe1de8{0%{box-shadow:0 0 0 0 var(--live-pulse-from)}70%{box-shadow:0 0 0 8px var(--live-pulse-to)}to{box-shadow:0 0 0 0 var(--live-pulse-to)}}@media(prefers-reduced-motion:reduce){.status-bar__live[data-v-eefe1de8]{animation:none}}.workspace-header[data-v-0f4b6d6e]{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,2fr) 32px;gap:8px;padding:8px;background:linear-gradient(135deg,var(--blob-1),var(--blob-2));color:var(--header-ink, var(--md-on-primary-container))}@media(prefers-reduced-transparency:reduce){.workspace-header[data-v-0f4b6d6e]{background:var(--md-s-low)}}.workspace-header__title[data-v-0f4b6d6e]{display:grid;align-content:center;gap:4px;padding:12px 16px}.workspace-header__name[data-v-0f4b6d6e]{margin:0;font-size:28px;font-weight:400;line-height:36px;color:var(--md-on-primary-container)}.workspace-header__line[data-v-0f4b6d6e]{margin:0;font-size:14px;opacity:.85}.workspace-header__count[data-v-0f4b6d6e]{font-weight:700;font-variant-numeric:tabular-nums}.workspace-header__give[data-v-0f4b6d6e]{display:flex;align-items:center;gap:8px;margin-top:8px}.workspace-header__links[data-v-0f4b6d6e]{display:inline-flex;flex-wrap:wrap;gap:6px;margin-left:10px}.workspace-header__links a[data-v-0f4b6d6e]{display:inline-flex;align-items:center;height:24px;padding:0 10px;border:1px solid var(--glass-edge);border-radius:999px;background:rgb(var(--glass),.55);color:inherit;font-size:12px;font-weight:500}.workspace-header__links a[data-v-0f4b6d6e]:hover{background:rgb(var(--glass),.85)}.workspace-header__fold[data-v-0f4b6d6e]{grid-row:1;grid-column:3;place-self:center center;margin:0;color:inherit}.workspace-header__tiles[data-v-0f4b6d6e]{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}.workspace-header__tile[data-v-0f4b6d6e]{display:grid;align-content:start;gap:4px;padding:12px 16px;border:1px solid var(--glass-edge);border-radius:var(--md-r-card);background:rgb(var(--glass),calc(var(--glass-a) + .1));-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);color:var(--md-on-surface)}@media(prefers-reduced-transparency:reduce){.workspace-header__tile[data-v-0f4b6d6e]{background:var(--md-s-low);-webkit-backdrop-filter:none;backdrop-filter:none}}.workspace-header__tile-label[data-v-0f4b6d6e]{color:var(--md-on-surface-variant);font-size:12px;font-weight:500;line-height:16px;letter-spacing:.03em}.workspace-header__tile-value[data-v-0f4b6d6e]{min-height:40px;font-size:32px;font-weight:400;line-height:40px;font-variant-numeric:tabular-nums}.workspace-header__tile--you[data-v-0f4b6d6e]{border-color:transparent;background:var(--md-primary);color:var(--md-on-primary)}.workspace-header__tile--you .workspace-header__tile-label[data-v-0f4b6d6e]{color:var(--md-on-primary);opacity:.85}.workspace-header__tile--fail .workspace-header__tile-value[data-v-0f4b6d6e]{color:var(--md-error)}.workspace-header--collapsed[data-v-0f4b6d6e]{grid-template-columns:minmax(0,1fr) 32px;padding:4px 8px}.workspace-header--collapsed .workspace-header__title[data-v-0f4b6d6e]{display:flex;flex-wrap:wrap;align-items:baseline;gap:14px;padding:4px 8px}.workspace-header--collapsed .workspace-header__name[data-v-0f4b6d6e]{font-size:18px;line-height:28px}.workspace-header--collapsed .workspace-header__tiles[data-v-0f4b6d6e],.workspace-header--collapsed .workspace-header__give[data-v-0f4b6d6e],.workspace-header--collapsed .workspace-header__sentence[data-v-0f4b6d6e]{display:none}.workspace-header--collapsed .workspace-header__fold[data-v-0f4b6d6e]{grid-column:2}.workspace-header--collapsed .workspace-header__strip[data-v-0f4b6d6e]{font-size:13px}@media(max-width:900px){.workspace-header[data-v-0f4b6d6e],.workspace-header--collapsed[data-v-0f4b6d6e]{grid-template-columns:minmax(0,1fr) 32px}.workspace-header__fold[data-v-0f4b6d6e]{grid-column:2}.workspace-header__tiles[data-v-0f4b6d6e]{grid-column:1 / -1}}@media(max-width:640px){.workspace-header__tiles[data-v-0f4b6d6e]{grid-template-columns:repeat(2,minmax(0,1fr))}}.island__head[data-v-a03b7f62]{display:flex;flex-wrap:nowrap;align-items:center;justify-content:space-between;gap:16px;padding:12px 20px}.island__title[data-v-a03b7f62]{flex:none;margin:0;font-size:16px;line-height:24px;font-weight:500;letter-spacing:.01em;white-space:nowrap}.island__note[data-v-a03b7f62]{display:flex;flex:1 1 auto;align-items:center;justify-content:flex-end;gap:6px;min-width:0;margin:0;overflow:visible;color:var(--md-on-surface-variant);font-size:12px;line-height:16px;letter-spacing:.03em;text-align:right;white-space:nowrap;text-overflow:ellipsis}.island__note-text[data-v-a03b7f62]{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.island__body[data-v-a03b7f62]{padding:0 20px 12px}.island--column .island__head[data-v-a03b7f62]{gap:4px}.island--column .island__body[data-v-a03b7f62]{display:flex;flex-direction:column;min-height:0;padding-top:4px}.island.island--collapsed .island__body[data-v-a03b7f62]{display:none}@media(min-width:901px){.dashboard--fit .dashboard__main .island__body[data-v-a03b7f62]{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;padding-bottom:0}.dashboard--fit .dashboard__main .island.island--collapsed .island__body[data-v-a03b7f62]{display:none}}.segmented[data-v-7901b5d6]{display:inline-flex;overflow:hidden;border:1px solid var(--md-outline);border-radius:999px;vertical-align:middle}.segmented--chips[data-v-7901b5d6]{flex:none;align-self:flex-start;background:rgb(var(--glass),.4)}.segmented__option[data-v-7901b5d6]{display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 11px;border-left:1px solid var(--md-outline);font-size:12px;font-weight:500;color:var(--md-on-surface);cursor:pointer;-webkit-user-select:none;user-select:none}.segmented__option[data-v-7901b5d6]:first-child{border-left:0}.segmented__count[data-v-7901b5d6]{font-weight:700;font-variant-numeric:tabular-nums}.segmented__option[aria-pressed=true][data-v-7901b5d6]{background:var(--md-secondary-container);color:var(--md-on-secondary-container)}.segmented__option[data-v-7901b5d6]:focus-visible{outline:var(--focus-ring);outline-offset:-2px}.segmented--chips .segmented__option[data-v-7901b5d6]{gap:normal;height:32px;padding:0 14px;font-family:var(--md-font);font-size:14px;letter-spacing:.01em}.segmented--chips .segmented__option[data-v-7901b5d6]:hover{background:var(--state-hover)}.segmented--chips .segmented__option[aria-pressed=true][data-v-7901b5d6]{background:var(--md-secondary-container);color:var(--md-on-secondary-container)}.ticket-cell__summary[data-v-8436de88]{display:block;max-width:44ch;margin-top:2px;color:var(--md-on-surface-variant);font-size:12px;line-height:16px;letter-spacing:.03em}.pr-cell[data-v-75c443c3]{display:flex;flex-direction:column;align-items:flex-start;gap:4px}.pr-cell__link[data-v-75c443c3]{max-width:100%;overflow-wrap:anywhere}.recently-done[data-v-12ee20e8]{display:flex;flex:0 1 auto;flex-direction:column;min-height:33px;margin:0 -20px;padding:0 20px;overflow:hidden;border-top:1px solid var(--md-outline-variant)}.recently-done[open][data-v-12ee20e8]{min-height:128px}.recently-done__summary[data-v-12ee20e8]{display:flex;flex:none;align-items:center;gap:4px;min-height:40px;list-style:none;color:var(--md-on-surface-variant);font-size:14px;font-weight:500;cursor:pointer}.recently-done__summary[data-v-12ee20e8]::-webkit-details-marker{display:none}.recently-done__summary[data-v-12ee20e8]:before{content:"▾";display:inline-grid;place-items:center;width:24px;font-size:18px;transform:rotate(-90deg);transition:transform .15s ease}.recently-done[open] .recently-done__summary[data-v-12ee20e8]:before{transform:none}.recently-done__count[data-v-12ee20e8]{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;margin-left:6px;padding:0 6px;border-radius:10px;background:var(--md-s-high);color:var(--md-on-surface-variant);font-size:12px;font-weight:700}.recently-done__list[data-v-12ee20e8]{flex:1 1 auto;min-height:0;max-height:min(30vh,240px);margin:0 -20px;padding-bottom:8px;overflow:auto}.row-scroll[data-v-7bd9ace7]{overflow-x:auto;margin:0 -20px}@media(min-width:901px){.dashboard--fit .dashboard__main .row-scroll[data-v-7bd9ace7]{flex:1 1 auto;min-height:0;overflow:auto}.dashboard--fit .row-scroll[data-v-7bd9ace7]::-webkit-scrollbar{width:8px;height:8px}.dashboard--fit .row-scroll[data-v-7bd9ace7]::-webkit-scrollbar-thumb{border-radius:4px;background:var(--md-outline-variant)}}.dashboard--fit .dashboard__main .row-scroll--floor[data-v-7bd9ace7]{min-height:5rem}.row-scroll__more[data-v-7bd9ace7]{flex:none;display:block;margin:0 -20px;padding:4px 20px 6px;border-top:1px solid var(--md-outline-variant);color:var(--md-primary);font-size:13px;font-weight:500;cursor:pointer}.row-scroll__more[data-v-7bd9ace7]:hover{background:rgb(var(--md-state),.06)}.row-scroll__more[data-v-7bd9ace7]:focus-visible{outline:var(--focus-ring);outline-offset:-2px}.your-move__view[data-v-e3e1502a]{margin-left:10px}.your-move__next[data-v-e3e1502a]{font-weight:500}.your-move__quote[data-v-e3e1502a]{max-width:48ch;color:var(--md-on-surface-variant);font-size:12px;line-height:16px}.your-move__quote a[data-v-e3e1502a]{color:var(--md-on-surface-variant)}.your-move__problem[data-v-e3e1502a]{margin:4px 0 0;padding:4px 10px;font-size:12px}.your-move__mark[data-v-e3e1502a]{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 12px;border:1px solid var(--md-outline);border-radius:999px;color:var(--md-on-surface);font-size:12px;font-weight:600;white-space:nowrap;cursor:pointer;-webkit-user-select:none;user-select:none}.your-move__mark[data-v-e3e1502a]:hover{background:var(--state-hover)}.your-move__mark[data-v-e3e1502a]:before{content:"";width:9px;height:5px;border-bottom:2px solid currentcolor;border-left:2px solid currentcolor;transform:translateY(-2px) rotate(-45deg)}.your-move__mark--undo[data-v-e3e1502a]:before{display:none}.your-move__mark[data-v-e3e1502a]:focus-visible{outline:var(--focus-ring);outline-offset:2px}.your-move__row--handled td[data-v-e3e1502a]{opacity:.55}.your-move__row--handled .your-move__next[data-v-e3e1502a]{text-decoration:line-through;text-decoration-color:var(--md-outline)}.your-move__row--handled .table__actions[data-v-e3e1502a]{opacity:1}.todos__view[data-v-6f034e1e]{margin-left:10px}.todos__add[data-v-6f034e1e]{display:flex;align-items:center;gap:8px;padding:8px 0}.todos__input[data-v-6f034e1e]{flex:1;min-width:0;height:32px;padding:0 12px;background:rgb(var(--md-state),.04);font-size:14px}.todos__list[data-v-6f034e1e]{margin:0 -20px;padding:0;overflow-y:auto;list-style:none}.todos__item[data-v-6f034e1e]{display:grid;grid-template-columns:20px minmax(0,1fr) auto 20px;align-items:center;gap:10px;padding:7px 20px;border-top:1px solid var(--md-outline-variant)}.todos__item[data-v-6f034e1e]:first-child{border-top:0}.todos__item[data-v-6f034e1e]:hover{background:rgb(var(--md-state),.06)}.todos__text[data-v-6f034e1e]{overflow-wrap:anywhere}.todos__item--done .todos__text[data-v-6f034e1e]{color:var(--md-on-surface-variant);text-decoration:line-through}.todos__empty[data-v-6f034e1e]{display:block;padding:6px 20px 10px}.todos__check[data-v-6f034e1e]{box-sizing:border-box;display:grid;place-items:center;width:18px;height:18px;border:2px solid var(--md-outline);border-radius:5px;cursor:pointer}.todos__check--on[data-v-6f034e1e]{border-color:var(--md-primary);background:var(--md-primary)}.todos__check--on[data-v-6f034e1e]:after{content:"";width:8px;height:4px;border-bottom:2px solid var(--md-on-primary);border-left:2px solid var(--md-on-primary);transform:translateY(-1px) rotate(-45deg)}.todos__meta[data-v-6f034e1e]{color:var(--md-on-surface-variant);font-size:11px;white-space:nowrap}.todos__delete[data-v-6f034e1e]{color:var(--md-on-surface-variant);font-size:16px;line-height:1;text-align:center;cursor:pointer;opacity:0}.todos__delete[data-v-6f034e1e]:focus-visible{opacity:1}.todos__item:hover .todos__delete[data-v-6f034e1e]{opacity:1}@media(min-width:901px){.dashboard--fit .dashboard__todo .todos__list[data-v-6f034e1e]{flex:1 1 auto;min-height:0}.dashboard--fit .dashboard__todo .todos__list[data-v-6f034e1e]:not(:has(.todos__item)){display:none}}.waiting__table[data-v-a632447c]{table-layout:fixed}.waiting__col--ticket[data-v-a632447c]{width:22%}.waiting__col--status[data-v-a632447c],.waiting__col--with[data-v-a632447c]{width:6.5rem}.waiting__col--pr[data-v-a632447c]{width:4.5rem}.waiting__col--actions[data-v-a632447c]{width:2rem}.waiting__reason[data-v-a632447c]{display:block;min-width:0;max-width:44ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feed-item[data-v-27e556e1]{display:grid;grid-template-columns:32px minmax(0,1fr);align-items:start;gap:12px;padding:10px 20px;cursor:default}.feed-item[data-v-27e556e1]:hover{background:var(--state-hover)}.feed-item.feed-item--open[data-v-27e556e1]{background:rgb(var(--md-state),.05)}.feed-item.feed-item--new[data-v-27e556e1]{background:var(--new-bg);box-shadow:inset 4px 0 0 var(--new),inset 0 0 0 1px var(--new-edge)}.feed-item__icon[data-v-27e556e1]{flex:none;display:grid;place-items:center;width:32px;height:32px;border-radius:50%;background:var(--md-s-highest);color:var(--md-on-surface-variant);font-size:11px;font-weight:700;letter-spacing:.02em}.feed-item__icon--jira[data-v-27e556e1]{background:var(--md-primary-container);color:var(--md-on-primary-container)}.feed-item__icon--bad[data-v-27e556e1]{background:var(--md-error-container);color:var(--md-on-error-container)}.feed-item__icon--ok[data-v-27e556e1]{background:var(--md-tertiary-container);color:var(--md-on-tertiary-container)}.feed-item__body[data-v-27e556e1]{display:grid;gap:2px;min-width:0}.feed-item__top[data-v-27e556e1]{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px;font-size:14px}.feed-item__right[data-v-27e556e1]{flex:none;display:inline-flex;align-items:center;gap:4px;margin-left:auto}.feed-item__kind[data-v-27e556e1]{font-weight:500}.feed-item__kind--bad[data-v-27e556e1]{color:var(--md-error)}.feed-item__who[data-v-27e556e1]{color:var(--md-on-surface-variant)}.feed-item__text[data-v-27e556e1]{display:-webkit-box;overflow:hidden;color:var(--md-on-surface-variant);font-size:12px;line-height:16px;letter-spacing:.03em;overflow-wrap:anywhere;-webkit-line-clamp:2;-webkit-box-orient:vertical}.feed-item__toggle[data-v-27e556e1]{display:inline-grid;place-items:center;width:24px;height:24px;margin-left:2px;border-radius:50%;color:var(--md-on-surface-variant);font-size:0;line-height:1;cursor:pointer;-webkit-user-select:none;user-select:none;transition:transform .15s ease}.feed-item__toggle[data-v-27e556e1]:before{content:"";width:7px;height:7px;border-right:2px solid currentcolor;border-bottom:2px solid currentcolor;transform:translateY(-2px) rotate(45deg)}.feed-item__toggle[data-v-27e556e1]:hover{background:rgb(var(--md-state),.1)}.feed-item__toggle[aria-expanded=true][data-v-27e556e1]{transform:rotate(180deg)}.feed-item__toggle[data-v-27e556e1]:focus-visible{outline:var(--focus-ring)}.feed-item__full[data-v-27e556e1]{max-height:16rem;margin-top:6px;padding:10px 12px;overflow:auto;border:1px solid var(--glass-edge);border-radius:var(--md-r-chip);background:rgb(var(--glass),.55);color:var(--md-on-surface);font-size:13px;line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere}.feed-item__actions[data-v-27e556e1]{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}.feed-item--new .feed-item__kind[data-v-27e556e1],.feed-item--lit .feed-item__kind[data-v-27e556e1]{color:var(--md-on-surface);font-weight:700}.feed-item--new .feed-item__text[data-v-27e556e1],.feed-item--lit .feed-item__text[data-v-27e556e1]{color:var(--md-on-surface)}.feed-item--new .feed-item__icon[data-v-27e556e1],.feed-item--lit .feed-item__icon[data-v-27e556e1]{box-shadow:0 0 0 2px var(--new)}.feed-item--new .feed-item__when[data-v-27e556e1]:before,.feed-item--lit .feed-item__when[data-v-27e556e1]:before{content:"NEW";display:inline-block;margin-right:6px;padding:1px 6px;border-radius:4px;background:var(--new);color:var(--new-ink);font-size:10px;font-weight:800;letter-spacing:.06em;vertical-align:1px}.feed-item:not(.feed-item--new) .feed-item__body[data-v-27e556e1]{opacity:.78}.feed__bar[data-v-d92a7c74]{display:flex;flex:none;flex-wrap:nowrap;align-items:center;justify-content:space-between;gap:8px;margin:0 0 8px}.feed__new-count[data-v-d92a7c74]{display:inline-flex;align-items:center;height:22px;padding:0 9px;border-radius:999px;background:var(--new);color:var(--new-ink);box-shadow:0 0 12px var(--new-glow);font-size:12px;font-weight:800}.feed__mark-read[data-v-d92a7c74]{flex:none;padding:4px 8px;border-radius:999px;color:var(--md-primary);font-size:13px;font-weight:500;cursor:pointer;-webkit-user-select:none;user-select:none}.feed__mark-read[data-v-d92a7c74]:hover{background:var(--state-hover)}.feed__mark-read[data-v-d92a7c74]:focus-visible{outline:var(--focus-ring)}.feed__search[data-v-d92a7c74]{display:flex;flex:none;align-items:center;gap:8px;margin:0 0 8px}.feed__search-input[data-v-d92a7c74]{flex:1;min-width:0;height:30px;padding:0 10px;font-size:13px}.feed__search-count[data-v-d92a7c74]{flex:none;color:var(--md-on-surface-variant);font-size:12px}.feed__list[data-v-d92a7c74]{flex:1 1 auto;min-height:12rem;margin:0 -20px;padding:0 0 4px;overflow-y:auto;list-style:none}.feed__group[data-v-d92a7c74]{display:grid;grid-template-columns:minmax(0,1fr);align-items:start;gap:0;padding:0;cursor:default}.feed__group[data-v-d92a7c74]:hover{background:var(--state-hover)}.feed__group.feed__group--open[data-v-d92a7c74]{background:rgb(var(--md-state),.05)}.feed__group.feed__group--new[data-v-d92a7c74]{background:var(--new-bg);box-shadow:inset 4px 0 0 var(--new),inset 0 0 0 1px var(--new-edge)}.feed__group-head[data-v-d92a7c74]{display:grid;grid-template-columns:32px minmax(0,1fr) auto;align-items:center;gap:12px;padding:10px 20px;cursor:pointer}.feed__group-copy[data-v-d92a7c74]{opacity:.55}.feed__group-head:hover .feed__group-copy[data-v-d92a7c74]{opacity:1}.feed__group-head[data-v-d92a7c74]:hover{background:var(--state-hover)}.feed__group--new>.feed__group-head[data-v-d92a7c74]{background:var(--new-bg);box-shadow:inset 4px 0 0 var(--new)}.feed__group--move[data-v-d92a7c74],.feed__group--move>.feed__group-head[data-v-d92a7c74]{box-shadow:inset 4px 0 0 var(--move)}.feed__group.feed__group--new.feed__group--move[data-v-d92a7c74]{box-shadow:inset 4px 0 0 var(--move),inset 0 0 0 1px var(--new-edge)}.feed__group-text[data-v-d92a7c74]{min-width:0}.feed__group-key[data-v-d92a7c74]{display:flex;align-items:baseline;gap:8px;font-size:14px}.feed__group-ticket[data-v-d92a7c74]{flex:none;font-weight:600}.feed__group-sum[data-v-d92a7c74]{overflow:hidden;color:var(--md-on-surface-variant);font-size:13px;text-overflow:ellipsis;white-space:nowrap}.feed__group-meta[data-v-d92a7c74]{display:flex;align-items:center;gap:8px;margin-top:2px;color:var(--md-on-surface-variant);font-size:12px}.feed__group-kinds[data-v-d92a7c74]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feed__group-when[data-v-d92a7c74]{margin-left:auto}.feed__group-count[data-v-d92a7c74]{flex:none;display:inline-flex;align-items:center;height:18px;padding:0 7px;border-radius:999px;background:var(--md-s-highest);color:var(--md-on-surface-variant);font-size:11px;font-weight:700}.feed__group-count--new[data-v-d92a7c74]{background:var(--new);color:var(--new-ink)}.feed__children[data-v-d92a7c74]{margin:0 0 0 35px;padding:0 0 4px;border-left:2px solid var(--md-outline-variant);list-style:none}.feed__children .feed-item[data-v-d92a7c74]{padding-left:14px}.feed__group-caret[data-v-d92a7c74]{flex:none;display:grid;place-items:center;width:32px;height:32px;border-radius:50%;background:var(--md-s-highest);color:var(--md-on-surface-variant);font-size:14px;transition:transform .15s ease}.feed__group-caret[data-v-d92a7c74]:focus-visible{outline:var(--focus-ring)}.feed__group--open .feed__group-caret[data-v-d92a7c74]{transform:rotate(90deg)}@media(min-width:901px){.dashboard--fit .feed__list[data-v-d92a7c74]::-webkit-scrollbar{width:8px;height:8px}.dashboard--fit .feed__list[data-v-d92a7c74]::-webkit-scrollbar-thumb{border-radius:4px;background:var(--md-outline-variant)}}@media(max-width:900px){.feed__list[data-v-d92a7c74]{max-height:28rem}}.first-run[data-v-ef746675]{display:grid;place-self:start center;gap:14px;width:min(640px,100%);padding:28px 32px}.first-run__title[data-v-ef746675]{margin:0;font-size:22px;font-weight:400;line-height:28px}.first-run__text[data-v-ef746675]{margin:0;color:var(--md-on-surface-variant)}.first-run__actions[data-v-ef746675]{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}.first-run__ai[data-v-ef746675]{font-size:13px}.markdown-view[data-v-dcf42e95]{padding:16px 20px 20px;overflow:auto;overflow-wrap:anywhere;font-size:14px;line-height:1.6}.markdown-view[data-v-dcf42e95] h4,.markdown-view[data-v-dcf42e95] h5{margin:16px 0 6px;font-weight:600}.markdown-view[data-v-dcf42e95] h4{font-size:16px}.markdown-view[data-v-dcf42e95] h5{font-size:14px}.markdown-view[data-v-dcf42e95] p{margin:0 0 10px}.markdown-view[data-v-dcf42e95] ul,.markdown-view[data-v-dcf42e95] ol{margin:0 0 10px;padding-left:22px}.markdown-view[data-v-dcf42e95] li{margin:2px 0}.markdown-view[data-v-dcf42e95] code{padding:1px 5px;border-radius:4px;background:rgb(var(--md-state),.1);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em}.markdown-view[data-v-dcf42e95] pre{margin:0 0 12px;padding:12px 14px;overflow:auto;border-radius:8px;background:#00000047}.markdown-view[data-v-dcf42e95] pre code{padding:0;background:none;font-size:12.5px;line-height:1.5;white-space:pre}.markdown-view[data-v-dcf42e95] blockquote{margin:0 0 10px;padding:4px 12px;border-left:3px solid var(--md-primary);color:var(--md-on-surface-variant)}.markdown-view[data-v-dcf42e95] strong{font-weight:600}.markdown-view[data-v-dcf42e95] .markdown-view__mention{color:var(--md-primary);font-weight:500}.feedback-sheet__card[data-v-ec34adcc]{width:min(640px,100%)}.feedback-sheet__text[data-v-ec34adcc]{min-height:7rem;resize:vertical}.feedback-sheet__note[data-v-ec34adcc]{margin:0;color:var(--md-on-surface-variant);font-size:12px}.feedback-sheet__report[data-v-ec34adcc]{display:flex;align-items:baseline;gap:8px;padding:4px 0;border-top:1px solid var(--md-outline-variant);font-size:13px}.feedback-sheet__report-title[data-v-ec34adcc]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.field-row[data-v-2ba0ba86]{display:grid;grid-template-columns:170px minmax(0,1fr);align-items:center;gap:4px 14px}.field-row__label[data-v-2ba0ba86]{color:var(--md-on-surface);font-size:13px}.field-row__hint[data-v-2ba0ba86]{grid-column:2;color:var(--md-on-surface-variant);font-size:11px}.field-row__check[data-v-2ba0ba86]{display:flex;align-items:center;gap:8px;color:var(--md-on-surface-variant);font-size:11px}.field-row__colour[data-v-2ba0ba86]{width:44px;height:30px;padding:2px}.field-row__inline[data-v-2ba0ba86]{display:flex;align-items:center;gap:8px}.settings-sheet__card[data-v-779d567d]{width:min(1040px,100%);height:min(760px,100%)}.settings-sheet__dirty[data-v-779d567d]{color:var(--md-error);font-size:12px;font-weight:600}.settings-sheet__confirm[data-v-779d567d]{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:12px 20px 0;padding:8px 12px;border-radius:10px;background:var(--md-warn-container);color:var(--md-on-warn-container);font-size:13px}.settings-sheet__confirm-text[data-v-779d567d]{flex:1}.settings-sheet__alert[data-v-779d567d]{margin:12px 20px 0}.settings-sheet__body[data-v-779d567d]{display:grid;flex:1;grid-template-columns:220px minmax(0,1fr);gap:0;min-height:0}.settings-sheet__list[data-v-779d567d]{display:flex;flex-direction:column;gap:4px;margin:0;padding:12px;overflow:auto;border-right:1px solid var(--md-outline-variant);list-style:none}.settings-sheet__workspace[data-v-779d567d]{box-sizing:border-box;display:block;width:100%;padding:8px 12px;overflow:hidden;border-radius:10px;font-size:14px;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.settings-sheet__workspace[data-v-779d567d]:hover{background:var(--state-hover)}.settings-sheet__workspace[aria-current=true][data-v-779d567d]{background:var(--md-secondary-container);color:var(--md-on-secondary-container)}.settings-sheet__workspace[data-v-779d567d]:focus-visible{outline:var(--focus-ring);outline-offset:-2px}.settings-sheet__workspace--add[data-v-779d567d]{color:var(--md-primary);font-weight:500}.settings-sheet__connector[data-v-779d567d]{display:flex;flex-direction:column;gap:10px;padding:12px 14px;border:1px solid var(--md-outline-variant);border-radius:12px;background:rgb(var(--glass),.35)}.settings-sheet__connector-head[data-v-779d567d]{display:flex;align-items:center;gap:10px}.settings-sheet__connector-name[data-v-779d567d]{flex:1;font-weight:600}.settings-sheet__actions[data-v-779d567d]{display:flex;flex-wrap:wrap;align-items:center;gap:10px}.settings-sheet__rules[data-v-779d567d]{display:flex;flex-direction:column;gap:6px;margin:0;padding:0 0 0 28px;font-size:13px}.settings-sheet__rule[data-v-779d567d]{display:grid;grid-template-columns:minmax(0,3fr) minmax(0,2fr);gap:12px;padding:4px 0;border-bottom:1px solid var(--md-outline-variant)}.settings-sheet__rule-when[data-v-779d567d]{color:var(--md-on-surface-variant);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;overflow-wrap:anywhere}.settings-sheet__rule-then[data-v-779d567d]{overflow-wrap:anywhere}.settings-sheet__rules-note[data-v-779d567d]{margin:0;color:var(--md-on-surface-variant)}.app__shell[data-v-f146b085]{box-sizing:border-box;display:flex;flex-direction:column;height:100%;padding:12px 12px 12px 72px}.app__shell>.dashboard[data-v-f146b085]{flex:1 1 auto;min-height:0}@media(min-width:901px){.app__shell>.dashboard.dashboard--fit[data-v-f146b085]{height:auto}}@media(max-width:900px){.app__shell[data-v-f146b085]{height:auto}}
|
|
1
|
+
.rail[data-v-be863916]{position:fixed;inset:0 auto 0 0;z-index:30;box-sizing:border-box;display:flex;flex-direction:column;gap:4px;width:60px;padding:12px 8px;overflow:hidden;border-right:1px solid var(--glass-edge);background:rgb(var(--glass),.72);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);font-family:var(--md-font);color:var(--md-on-surface);transition:width .18s ease,box-shadow .18s ease}.rail[data-v-be863916]:hover,.rail[data-v-be863916]:has(:focus-visible){width:232px;box-shadow:12px 0 32px #0000001f}.app:has(.modal) .rail[data-v-be863916]{z-index:0}.rail__item[data-v-be863916]{position:relative;display:flex;align-items:center;gap:12px;height:44px;padding:0 4px;border-radius:12px;color:inherit;text-decoration:none;white-space:nowrap;cursor:pointer;-webkit-user-select:none;user-select:none}.rail__item[data-v-be863916]:focus-visible{outline:var(--focus-ring);outline-offset:-2px}.rail__item--dragging[data-v-be863916]{opacity:.4}.rail__item[data-drop=before][data-v-be863916]{box-shadow:0 -2px 0 0 var(--md-primary)}.rail__item[data-drop=after][data-v-be863916]{box-shadow:0 2px 0 0 var(--md-primary)}.rail__item[data-v-be863916]:hover{background:var(--state-hover)}.rail__item[aria-selected=true][data-v-be863916]{background:var(--md-secondary-container);color:var(--md-on-secondary-container)}.rail__icon[data-v-be863916]{flex:none;display:block;width:36px;height:36px;border-radius:10px}.rail__gear[data-v-be863916]{flex:none;display:grid;place-items:center;width:36px;height:36px;color:var(--md-on-surface-variant)}.rail__label[data-v-be863916]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;font-size:14px;font-weight:500;opacity:0;transition:opacity .12s ease}.rail:hover .rail__label[data-v-be863916],.rail:has(:focus-visible) .rail__label[data-v-be863916]{opacity:1}.rail__badge[data-v-be863916]{position:absolute;top:2px;left:30px;box-sizing:border-box;min-width:18px;height:18px;padding:0 5px;border-radius:999px;background:var(--md-primary);color:var(--md-on-primary);font-size:10px;font-weight:700;line-height:18px;text-align:center}.rail:hover .rail__badge[data-v-be863916],.rail:has(:focus-visible) .rail__badge[data-v-be863916]{position:static;flex:none}.rail__spacer[data-v-be863916]{flex:1}.ai-button[data-v-d32a60c7]{display:inline-grid;place-items:center;width:26px;height:26px;border-radius:50%;cursor:pointer;color:var(--md-primary);background:rgb(var(--md-state),.06);vertical-align:middle;transition:background .12s ease,transform .12s ease}.ai-button__icon[data-v-d32a60c7]{width:15px;height:15px}.ai-button[data-v-d32a60c7]:hover{background:var(--md-secondary-container);transform:scale(1.08)}.ai-button[data-v-d32a60c7]:focus-visible{outline:var(--focus-ring);outline-offset:1px}.ai-button.ai-button--sent[data-v-d32a60c7]{background:var(--md-tertiary-container);color:var(--md-on-tertiary-container)}.ai-button.ai-button--failed[data-v-d32a60c7]{background:var(--md-error-container);color:var(--md-on-error-container)}.ai-button--big[data-v-d32a60c7]{width:32px;height:32px;background:rgb(var(--glass),.7)}.ai-button--big .ai-button__icon[data-v-d32a60c7]{width:18px;height:18px}.update-chip[data-v-f70d2aed]{display:inline-flex;align-items:center;height:26px;padding:0 12px;font:inherit;color:var(--md-on-primary-container);cursor:pointer;background:var(--md-primary-container);border:0;border-radius:var(--md-r-chip)}.update-chip--busy[data-v-f70d2aed],.update-chip--done[data-v-f70d2aed]{cursor:default}.update-chip--busy[data-v-f70d2aed]{opacity:.7}.update-chip--failed[data-v-f70d2aed]{color:var(--md-on-error-container);background:var(--md-error-container)}.status-bar[data-v-eefe1de8]{display:flex;align-items:center;gap:10px;margin:0 4px 8px;font-family:var(--md-font);font-size:12px;color:var(--md-on-surface-variant)}.status-bar__btn[data-v-eefe1de8]{height:26px;padding:0 12px;font-size:12px;text-decoration:none}.status-bar__btn--busy[data-v-eefe1de8]{opacity:.6;pointer-events:none}.status-bar__report[data-v-eefe1de8]{gap:6px;color:var(--md-error);border-color:var(--md-error)}.status-bar__icon[data-v-eefe1de8]{width:16px;height:16px}.status-bar__live[data-v-eefe1de8]{width:8px;height:8px;border-radius:50%;background:var(--live-on);box-shadow:0 0 0 0 var(--live-pulse-rest);animation:status-bar-pulse-eefe1de8 2s infinite}.status-bar__live--off[data-v-eefe1de8]{background:var(--live-off);animation:none}.status-bar__live--warn[data-v-eefe1de8]{background:var(--live-warn);animation:none}.status-bar__notice[data-v-eefe1de8]{color:var(--live-off)}.status-bar__ai-hint[data-v-eefe1de8]{margin-left:-4px}@keyframes status-bar-pulse-eefe1de8{0%{box-shadow:0 0 0 0 var(--live-pulse-from)}70%{box-shadow:0 0 0 8px var(--live-pulse-to)}to{box-shadow:0 0 0 0 var(--live-pulse-to)}}@media(prefers-reduced-motion:reduce){.status-bar__live[data-v-eefe1de8]{animation:none}}.workspace-header[data-v-0f4b6d6e]{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,2fr) 32px;gap:8px;padding:8px;background:linear-gradient(135deg,var(--blob-1),var(--blob-2));color:var(--header-ink, var(--md-on-primary-container))}@media(prefers-reduced-transparency:reduce){.workspace-header[data-v-0f4b6d6e]{background:var(--md-s-low)}}.workspace-header__title[data-v-0f4b6d6e]{display:grid;align-content:center;gap:4px;padding:12px 16px}.workspace-header__name[data-v-0f4b6d6e]{margin:0;font-size:28px;font-weight:400;line-height:36px;color:var(--md-on-primary-container)}.workspace-header__line[data-v-0f4b6d6e]{margin:0;font-size:14px;opacity:.85}.workspace-header__count[data-v-0f4b6d6e]{font-weight:700;font-variant-numeric:tabular-nums}.workspace-header__give[data-v-0f4b6d6e]{display:flex;align-items:center;gap:8px;margin-top:8px}.workspace-header__links[data-v-0f4b6d6e]{display:inline-flex;flex-wrap:wrap;gap:6px;margin-left:10px}.workspace-header__links a[data-v-0f4b6d6e]{display:inline-flex;align-items:center;height:24px;padding:0 10px;border:1px solid var(--glass-edge);border-radius:999px;background:rgb(var(--glass),.55);color:inherit;font-size:12px;font-weight:500}.workspace-header__links a[data-v-0f4b6d6e]:hover{background:rgb(var(--glass),.85)}.workspace-header__fold[data-v-0f4b6d6e]{grid-row:1;grid-column:3;place-self:center center;margin:0;color:inherit}.workspace-header__tiles[data-v-0f4b6d6e]{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}.workspace-header__tile[data-v-0f4b6d6e]{display:grid;align-content:start;gap:4px;padding:12px 16px;border:1px solid var(--glass-edge);border-radius:var(--md-r-card);background:rgb(var(--glass),calc(var(--glass-a) + .1));-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);color:var(--md-on-surface)}@media(prefers-reduced-transparency:reduce){.workspace-header__tile[data-v-0f4b6d6e]{background:var(--md-s-low);-webkit-backdrop-filter:none;backdrop-filter:none}}.workspace-header__tile-label[data-v-0f4b6d6e]{color:var(--md-on-surface-variant);font-size:12px;font-weight:500;line-height:16px;letter-spacing:.03em}.workspace-header__tile-value[data-v-0f4b6d6e]{min-height:40px;font-size:32px;font-weight:400;line-height:40px;font-variant-numeric:tabular-nums}.workspace-header__tile--you[data-v-0f4b6d6e]{border-color:transparent;background:var(--md-primary);color:var(--md-on-primary)}.workspace-header__tile--you .workspace-header__tile-label[data-v-0f4b6d6e]{color:var(--md-on-primary);opacity:.85}.workspace-header__tile--fail .workspace-header__tile-value[data-v-0f4b6d6e]{color:var(--md-error)}.workspace-header--collapsed[data-v-0f4b6d6e]{grid-template-columns:minmax(0,1fr) 32px;padding:4px 8px}.workspace-header--collapsed .workspace-header__title[data-v-0f4b6d6e]{display:flex;flex-wrap:wrap;align-items:baseline;gap:14px;padding:4px 8px}.workspace-header--collapsed .workspace-header__name[data-v-0f4b6d6e]{font-size:18px;line-height:28px}.workspace-header--collapsed .workspace-header__tiles[data-v-0f4b6d6e],.workspace-header--collapsed .workspace-header__give[data-v-0f4b6d6e],.workspace-header--collapsed .workspace-header__sentence[data-v-0f4b6d6e]{display:none}.workspace-header--collapsed .workspace-header__fold[data-v-0f4b6d6e]{grid-column:2}.workspace-header--collapsed .workspace-header__strip[data-v-0f4b6d6e]{font-size:13px}@media(max-width:900px){.workspace-header[data-v-0f4b6d6e],.workspace-header--collapsed[data-v-0f4b6d6e]{grid-template-columns:minmax(0,1fr) 32px}.workspace-header__fold[data-v-0f4b6d6e]{grid-column:2}.workspace-header__tiles[data-v-0f4b6d6e]{grid-column:1 / -1}}@media(max-width:640px){.workspace-header__tiles[data-v-0f4b6d6e]{grid-template-columns:repeat(2,minmax(0,1fr))}}.island__head[data-v-a03b7f62]{display:flex;flex-wrap:nowrap;align-items:center;justify-content:space-between;gap:16px;padding:12px 20px}.island__title[data-v-a03b7f62]{flex:none;margin:0;font-size:16px;line-height:24px;font-weight:500;letter-spacing:.01em;white-space:nowrap}.island__note[data-v-a03b7f62]{display:flex;flex:1 1 auto;align-items:center;justify-content:flex-end;gap:6px;min-width:0;margin:0;overflow:visible;color:var(--md-on-surface-variant);font-size:12px;line-height:16px;letter-spacing:.03em;text-align:right;white-space:nowrap;text-overflow:ellipsis}.island__note-text[data-v-a03b7f62]{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.island__body[data-v-a03b7f62]{padding:0 20px 12px}.island--column .island__head[data-v-a03b7f62]{gap:4px}.island--column .island__body[data-v-a03b7f62]{display:flex;flex-direction:column;min-height:0;padding-top:4px}.island.island--collapsed .island__body[data-v-a03b7f62]{display:none}@media(min-width:901px){.dashboard--fit .dashboard__main .island__body[data-v-a03b7f62]{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;padding-bottom:0}.dashboard--fit .dashboard__main .island.island--collapsed .island__body[data-v-a03b7f62]{display:none}}.segmented[data-v-7901b5d6]{display:inline-flex;overflow:hidden;border:1px solid var(--md-outline);border-radius:999px;vertical-align:middle}.segmented--chips[data-v-7901b5d6]{flex:none;align-self:flex-start;background:rgb(var(--glass),.4)}.segmented__option[data-v-7901b5d6]{display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 11px;border-left:1px solid var(--md-outline);font-size:12px;font-weight:500;color:var(--md-on-surface);cursor:pointer;-webkit-user-select:none;user-select:none}.segmented__option[data-v-7901b5d6]:first-child{border-left:0}.segmented__count[data-v-7901b5d6]{font-weight:700;font-variant-numeric:tabular-nums}.segmented__option[aria-pressed=true][data-v-7901b5d6]{background:var(--md-secondary-container);color:var(--md-on-secondary-container)}.segmented__option[data-v-7901b5d6]:focus-visible{outline:var(--focus-ring);outline-offset:-2px}.segmented--chips .segmented__option[data-v-7901b5d6]{gap:normal;height:32px;padding:0 14px;font-family:var(--md-font);font-size:14px;letter-spacing:.01em}.segmented--chips .segmented__option[data-v-7901b5d6]:hover{background:var(--state-hover)}.segmented--chips .segmented__option[aria-pressed=true][data-v-7901b5d6]{background:var(--md-secondary-container);color:var(--md-on-secondary-container)}.ticket-cell__summary[data-v-8436de88]{display:block;max-width:44ch;margin-top:2px;color:var(--md-on-surface-variant);font-size:12px;line-height:16px;letter-spacing:.03em}.pr-cell[data-v-75c443c3]{display:flex;flex-direction:column;align-items:flex-start;gap:4px}.pr-cell__link[data-v-75c443c3]{max-width:100%;overflow-wrap:anywhere}.recently-done[data-v-12ee20e8]{display:flex;flex:0 1 auto;flex-direction:column;min-height:33px;margin:0 -20px;padding:0 20px;overflow:hidden;border-top:1px solid var(--md-outline-variant)}.recently-done[open][data-v-12ee20e8]{min-height:128px}.recently-done__summary[data-v-12ee20e8]{display:flex;flex:none;align-items:center;gap:4px;min-height:40px;list-style:none;color:var(--md-on-surface-variant);font-size:14px;font-weight:500;cursor:pointer}.recently-done__summary[data-v-12ee20e8]::-webkit-details-marker{display:none}.recently-done__summary[data-v-12ee20e8]:before{content:"▾";display:inline-grid;place-items:center;width:24px;font-size:18px;transform:rotate(-90deg);transition:transform .15s ease}.recently-done[open] .recently-done__summary[data-v-12ee20e8]:before{transform:none}.recently-done__count[data-v-12ee20e8]{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;margin-left:6px;padding:0 6px;border-radius:10px;background:var(--md-s-high);color:var(--md-on-surface-variant);font-size:12px;font-weight:700}.recently-done__list[data-v-12ee20e8]{flex:1 1 auto;min-height:0;max-height:min(30vh,240px);margin:0 -20px;padding-bottom:8px;overflow:auto}.row-scroll[data-v-7bd9ace7]{overflow-x:auto;margin:0 -20px}@media(min-width:901px){.dashboard--fit .dashboard__main .row-scroll[data-v-7bd9ace7]{flex:1 1 auto;min-height:0;overflow:auto}.dashboard--fit .row-scroll[data-v-7bd9ace7]::-webkit-scrollbar{width:8px;height:8px}.dashboard--fit .row-scroll[data-v-7bd9ace7]::-webkit-scrollbar-thumb{border-radius:4px;background:var(--md-outline-variant)}}.dashboard--fit .dashboard__main .row-scroll--floor[data-v-7bd9ace7]{min-height:5rem}.row-scroll__more[data-v-7bd9ace7]{flex:none;display:block;margin:0 -20px;padding:4px 20px 6px;border-top:1px solid var(--md-outline-variant);color:var(--md-primary);font-size:13px;font-weight:500;cursor:pointer}.row-scroll__more[data-v-7bd9ace7]:hover{background:rgb(var(--md-state),.06)}.row-scroll__more[data-v-7bd9ace7]:focus-visible{outline:var(--focus-ring);outline-offset:-2px}.your-move__view[data-v-e3e1502a]{margin-left:10px}.your-move__next[data-v-e3e1502a]{font-weight:500}.your-move__quote[data-v-e3e1502a]{max-width:48ch;color:var(--md-on-surface-variant);font-size:12px;line-height:16px}.your-move__quote a[data-v-e3e1502a]{color:var(--md-on-surface-variant)}.your-move__problem[data-v-e3e1502a]{margin:4px 0 0;padding:4px 10px;font-size:12px}.your-move__mark[data-v-e3e1502a]{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 12px;border:1px solid var(--md-outline);border-radius:999px;color:var(--md-on-surface);font-size:12px;font-weight:600;white-space:nowrap;cursor:pointer;-webkit-user-select:none;user-select:none}.your-move__mark[data-v-e3e1502a]:hover{background:var(--state-hover)}.your-move__mark[data-v-e3e1502a]:before{content:"";width:9px;height:5px;border-bottom:2px solid currentcolor;border-left:2px solid currentcolor;transform:translateY(-2px) rotate(-45deg)}.your-move__mark--undo[data-v-e3e1502a]:before{display:none}.your-move__mark[data-v-e3e1502a]:focus-visible{outline:var(--focus-ring);outline-offset:2px}.your-move__row--handled td[data-v-e3e1502a]{opacity:.55}.your-move__row--handled .your-move__next[data-v-e3e1502a]{text-decoration:line-through;text-decoration-color:var(--md-outline)}.your-move__row--handled .table__actions[data-v-e3e1502a]{opacity:1}.todos__view[data-v-6f034e1e]{margin-left:10px}.todos__add[data-v-6f034e1e]{display:flex;align-items:center;gap:8px;padding:8px 0}.todos__input[data-v-6f034e1e]{flex:1;min-width:0;height:32px;padding:0 12px;background:rgb(var(--md-state),.04);font-size:14px}.todos__list[data-v-6f034e1e]{margin:0 -20px;padding:0;overflow-y:auto;list-style:none}.todos__item[data-v-6f034e1e]{display:grid;grid-template-columns:20px minmax(0,1fr) auto 20px;align-items:center;gap:10px;padding:7px 20px;border-top:1px solid var(--md-outline-variant)}.todos__item[data-v-6f034e1e]:first-child{border-top:0}.todos__item[data-v-6f034e1e]:hover{background:rgb(var(--md-state),.06)}.todos__text[data-v-6f034e1e]{overflow-wrap:anywhere}.todos__item--done .todos__text[data-v-6f034e1e]{color:var(--md-on-surface-variant);text-decoration:line-through}.todos__empty[data-v-6f034e1e]{display:block;padding:6px 20px 10px}.todos__check[data-v-6f034e1e]{box-sizing:border-box;display:grid;place-items:center;width:18px;height:18px;border:2px solid var(--md-outline);border-radius:5px;cursor:pointer}.todos__check--on[data-v-6f034e1e]{border-color:var(--md-primary);background:var(--md-primary)}.todos__check--on[data-v-6f034e1e]:after{content:"";width:8px;height:4px;border-bottom:2px solid var(--md-on-primary);border-left:2px solid var(--md-on-primary);transform:translateY(-1px) rotate(-45deg)}.todos__meta[data-v-6f034e1e]{color:var(--md-on-surface-variant);font-size:11px;white-space:nowrap}.todos__delete[data-v-6f034e1e]{color:var(--md-on-surface-variant);font-size:16px;line-height:1;text-align:center;cursor:pointer;opacity:0}.todos__delete[data-v-6f034e1e]:focus-visible{opacity:1}.todos__item:hover .todos__delete[data-v-6f034e1e]{opacity:1}@media(min-width:901px){.dashboard--fit .dashboard__todo .todos__list[data-v-6f034e1e]{flex:1 1 auto;min-height:0}.dashboard--fit .dashboard__todo .todos__list[data-v-6f034e1e]:not(:has(.todos__item)){display:none}}.waiting__table[data-v-a632447c]{table-layout:fixed}.waiting__col--ticket[data-v-a632447c]{width:22%}.waiting__col--status[data-v-a632447c],.waiting__col--with[data-v-a632447c]{width:6.5rem}.waiting__col--pr[data-v-a632447c]{width:4.5rem}.waiting__col--actions[data-v-a632447c]{width:2rem}.waiting__reason[data-v-a632447c]{display:block;min-width:0;max-width:44ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feed-item[data-v-27e556e1]{display:grid;grid-template-columns:32px minmax(0,1fr);align-items:start;gap:12px;padding:10px 20px;cursor:default}.feed-item[data-v-27e556e1]:hover{background:var(--state-hover)}.feed-item.feed-item--open[data-v-27e556e1]{background:rgb(var(--md-state),.05)}.feed-item.feed-item--new[data-v-27e556e1]{background:var(--new-bg);box-shadow:inset 4px 0 0 var(--new),inset 0 0 0 1px var(--new-edge)}.feed-item__icon[data-v-27e556e1]{flex:none;display:grid;place-items:center;width:32px;height:32px;border-radius:50%;background:var(--md-s-highest);color:var(--md-on-surface-variant);font-size:11px;font-weight:700;letter-spacing:.02em}.feed-item__icon--jira[data-v-27e556e1]{background:var(--md-primary-container);color:var(--md-on-primary-container)}.feed-item__icon--bad[data-v-27e556e1]{background:var(--md-error-container);color:var(--md-on-error-container)}.feed-item__icon--ok[data-v-27e556e1]{background:var(--md-tertiary-container);color:var(--md-on-tertiary-container)}.feed-item__body[data-v-27e556e1]{display:grid;gap:2px;min-width:0}.feed-item__top[data-v-27e556e1]{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px;font-size:14px}.feed-item__right[data-v-27e556e1]{flex:none;display:inline-flex;align-items:center;gap:4px;margin-left:auto}.feed-item__kind[data-v-27e556e1]{font-weight:500}.feed-item__kind--bad[data-v-27e556e1]{color:var(--md-error)}.feed-item__who[data-v-27e556e1]{color:var(--md-on-surface-variant)}.feed-item__text[data-v-27e556e1]{display:-webkit-box;overflow:hidden;color:var(--md-on-surface-variant);font-size:12px;line-height:16px;letter-spacing:.03em;overflow-wrap:anywhere;-webkit-line-clamp:2;-webkit-box-orient:vertical}.feed-item__toggle[data-v-27e556e1]{display:inline-grid;place-items:center;width:24px;height:24px;margin-left:2px;border-radius:50%;color:var(--md-on-surface-variant);font-size:0;line-height:1;cursor:pointer;-webkit-user-select:none;user-select:none;transition:transform .15s ease}.feed-item__toggle[data-v-27e556e1]:before{content:"";width:7px;height:7px;border-right:2px solid currentcolor;border-bottom:2px solid currentcolor;transform:translateY(-2px) rotate(45deg)}.feed-item__toggle[data-v-27e556e1]:hover{background:rgb(var(--md-state),.1)}.feed-item__toggle[aria-expanded=true][data-v-27e556e1]{transform:rotate(180deg)}.feed-item__toggle[data-v-27e556e1]:focus-visible{outline:var(--focus-ring)}.feed-item__full[data-v-27e556e1]{max-height:16rem;margin-top:6px;padding:10px 12px;overflow:auto;border:1px solid var(--glass-edge);border-radius:var(--md-r-chip);background:rgb(var(--glass),.55);color:var(--md-on-surface);font-size:13px;line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere}.feed-item__actions[data-v-27e556e1]{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}.feed-item--new .feed-item__kind[data-v-27e556e1],.feed-item--lit .feed-item__kind[data-v-27e556e1]{color:var(--md-on-surface);font-weight:700}.feed-item--new .feed-item__text[data-v-27e556e1],.feed-item--lit .feed-item__text[data-v-27e556e1]{color:var(--md-on-surface)}.feed-item--new .feed-item__icon[data-v-27e556e1],.feed-item--lit .feed-item__icon[data-v-27e556e1]{box-shadow:0 0 0 2px var(--new)}.feed-item--new .feed-item__when[data-v-27e556e1]:before,.feed-item--lit .feed-item__when[data-v-27e556e1]:before{content:"NEW";display:inline-block;margin-right:6px;padding:1px 6px;border-radius:4px;background:var(--new);color:var(--new-ink);font-size:10px;font-weight:800;letter-spacing:.06em;vertical-align:1px}.feed-item:not(.feed-item--new) .feed-item__body[data-v-27e556e1]{opacity:.78}.feed__bar[data-v-d92a7c74]{display:flex;flex:none;flex-wrap:nowrap;align-items:center;justify-content:space-between;gap:8px;margin:0 0 8px}.feed__new-count[data-v-d92a7c74]{display:inline-flex;align-items:center;height:22px;padding:0 9px;border-radius:999px;background:var(--new);color:var(--new-ink);box-shadow:0 0 12px var(--new-glow);font-size:12px;font-weight:800}.feed__mark-read[data-v-d92a7c74]{flex:none;padding:4px 8px;border-radius:999px;color:var(--md-primary);font-size:13px;font-weight:500;cursor:pointer;-webkit-user-select:none;user-select:none}.feed__mark-read[data-v-d92a7c74]:hover{background:var(--state-hover)}.feed__mark-read[data-v-d92a7c74]:focus-visible{outline:var(--focus-ring)}.feed__search[data-v-d92a7c74]{display:flex;flex:none;align-items:center;gap:8px;margin:0 0 8px}.feed__search-input[data-v-d92a7c74]{flex:1;min-width:0;height:30px;padding:0 10px;font-size:13px}.feed__search-count[data-v-d92a7c74]{flex:none;color:var(--md-on-surface-variant);font-size:12px}.feed__list[data-v-d92a7c74]{flex:1 1 auto;min-height:12rem;margin:0 -20px;padding:0 0 4px;overflow-y:auto;list-style:none}.feed__group[data-v-d92a7c74]{display:grid;grid-template-columns:minmax(0,1fr);align-items:start;gap:0;padding:0;cursor:default}.feed__group[data-v-d92a7c74]:hover{background:var(--state-hover)}.feed__group.feed__group--open[data-v-d92a7c74]{background:rgb(var(--md-state),.05)}.feed__group.feed__group--new[data-v-d92a7c74]{background:var(--new-bg);box-shadow:inset 4px 0 0 var(--new),inset 0 0 0 1px var(--new-edge)}.feed__group-head[data-v-d92a7c74]{display:grid;grid-template-columns:32px minmax(0,1fr) auto;align-items:center;gap:12px;padding:10px 20px;cursor:pointer}.feed__group-copy[data-v-d92a7c74]{opacity:.55}.feed__group-head:hover .feed__group-copy[data-v-d92a7c74]{opacity:1}.feed__group-head[data-v-d92a7c74]:hover{background:var(--state-hover)}.feed__group--new>.feed__group-head[data-v-d92a7c74]{background:var(--new-bg);box-shadow:inset 4px 0 0 var(--new)}.feed__group--move[data-v-d92a7c74],.feed__group--move>.feed__group-head[data-v-d92a7c74]{box-shadow:inset 4px 0 0 var(--move)}.feed__group.feed__group--new.feed__group--move[data-v-d92a7c74]{box-shadow:inset 4px 0 0 var(--move),inset 0 0 0 1px var(--new-edge)}.feed__group-text[data-v-d92a7c74]{min-width:0}.feed__group-key[data-v-d92a7c74]{display:flex;align-items:baseline;gap:8px;font-size:14px}.feed__group-ticket[data-v-d92a7c74]{flex:none;font-weight:600}.feed__group-sum[data-v-d92a7c74]{overflow:hidden;color:var(--md-on-surface-variant);font-size:13px;text-overflow:ellipsis;white-space:nowrap}.feed__group-meta[data-v-d92a7c74]{display:flex;align-items:center;gap:8px;margin-top:2px;color:var(--md-on-surface-variant);font-size:12px}.feed__group-kinds[data-v-d92a7c74]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feed__group-when[data-v-d92a7c74]{margin-left:auto}.feed__group-count[data-v-d92a7c74]{flex:none;display:inline-flex;align-items:center;height:18px;padding:0 7px;border-radius:999px;background:var(--md-s-highest);color:var(--md-on-surface-variant);font-size:11px;font-weight:700}.feed__group-count--new[data-v-d92a7c74]{background:var(--new);color:var(--new-ink)}.feed__children[data-v-d92a7c74]{margin:0 0 0 35px;padding:0 0 4px;border-left:2px solid var(--md-outline-variant);list-style:none}.feed__children .feed-item[data-v-d92a7c74]{padding-left:14px}.feed__group-caret[data-v-d92a7c74]{flex:none;display:grid;place-items:center;width:32px;height:32px;border-radius:50%;background:var(--md-s-highest);color:var(--md-on-surface-variant);font-size:14px;transition:transform .15s ease}.feed__group-caret[data-v-d92a7c74]:focus-visible{outline:var(--focus-ring)}.feed__group--open .feed__group-caret[data-v-d92a7c74]{transform:rotate(90deg)}@media(min-width:901px){.dashboard--fit .feed__list[data-v-d92a7c74]::-webkit-scrollbar{width:8px;height:8px}.dashboard--fit .feed__list[data-v-d92a7c74]::-webkit-scrollbar-thumb{border-radius:4px;background:var(--md-outline-variant)}}@media(max-width:900px){.feed__list[data-v-d92a7c74]{max-height:28rem}}.first-run[data-v-84359c2d]{display:grid;place-self:start center;gap:14px;width:min(640px,100%);padding:28px 32px}.first-run__title[data-v-84359c2d]{margin:0;font-size:22px;font-weight:400;line-height:28px}.first-run__text[data-v-84359c2d]{margin:0;color:var(--md-on-surface-variant)}.first-run__actions[data-v-84359c2d]{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}.first-run__ai[data-v-84359c2d]{font-size:13px}.markdown-view[data-v-dcf42e95]{padding:16px 20px 20px;overflow:auto;overflow-wrap:anywhere;font-size:14px;line-height:1.6}.markdown-view[data-v-dcf42e95] h4,.markdown-view[data-v-dcf42e95] h5{margin:16px 0 6px;font-weight:600}.markdown-view[data-v-dcf42e95] h4{font-size:16px}.markdown-view[data-v-dcf42e95] h5{font-size:14px}.markdown-view[data-v-dcf42e95] p{margin:0 0 10px}.markdown-view[data-v-dcf42e95] ul,.markdown-view[data-v-dcf42e95] ol{margin:0 0 10px;padding-left:22px}.markdown-view[data-v-dcf42e95] li{margin:2px 0}.markdown-view[data-v-dcf42e95] code{padding:1px 5px;border-radius:4px;background:rgb(var(--md-state),.1);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em}.markdown-view[data-v-dcf42e95] pre{margin:0 0 12px;padding:12px 14px;overflow:auto;border-radius:8px;background:#00000047}.markdown-view[data-v-dcf42e95] pre code{padding:0;background:none;font-size:12.5px;line-height:1.5;white-space:pre}.markdown-view[data-v-dcf42e95] blockquote{margin:0 0 10px;padding:4px 12px;border-left:3px solid var(--md-primary);color:var(--md-on-surface-variant)}.markdown-view[data-v-dcf42e95] strong{font-weight:600}.markdown-view[data-v-dcf42e95] .markdown-view__mention{color:var(--md-primary);font-weight:500}.feedback-sheet__card[data-v-ec34adcc]{width:min(640px,100%)}.feedback-sheet__text[data-v-ec34adcc]{min-height:7rem;resize:vertical}.feedback-sheet__note[data-v-ec34adcc]{margin:0;color:var(--md-on-surface-variant);font-size:12px}.feedback-sheet__report[data-v-ec34adcc]{display:flex;align-items:baseline;gap:8px;padding:4px 0;border-top:1px solid var(--md-outline-variant);font-size:13px}.feedback-sheet__report-title[data-v-ec34adcc]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.field-row[data-v-2ba0ba86]{display:grid;grid-template-columns:170px minmax(0,1fr);align-items:center;gap:4px 14px}.field-row__label[data-v-2ba0ba86]{color:var(--md-on-surface);font-size:13px}.field-row__hint[data-v-2ba0ba86]{grid-column:2;color:var(--md-on-surface-variant);font-size:11px}.field-row__check[data-v-2ba0ba86]{display:flex;align-items:center;gap:8px;color:var(--md-on-surface-variant);font-size:11px}.field-row__colour[data-v-2ba0ba86]{width:44px;height:30px;padding:2px}.field-row__inline[data-v-2ba0ba86]{display:flex;align-items:center;gap:8px}.settings-sheet__card[data-v-779d567d]{width:min(1040px,100%);height:min(760px,100%)}.settings-sheet__dirty[data-v-779d567d]{color:var(--md-error);font-size:12px;font-weight:600}.settings-sheet__confirm[data-v-779d567d]{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:12px 20px 0;padding:8px 12px;border-radius:10px;background:var(--md-warn-container);color:var(--md-on-warn-container);font-size:13px}.settings-sheet__confirm-text[data-v-779d567d]{flex:1}.settings-sheet__alert[data-v-779d567d]{margin:12px 20px 0}.settings-sheet__body[data-v-779d567d]{display:grid;flex:1;grid-template-columns:220px minmax(0,1fr);gap:0;min-height:0}.settings-sheet__list[data-v-779d567d]{display:flex;flex-direction:column;gap:4px;margin:0;padding:12px;overflow:auto;border-right:1px solid var(--md-outline-variant);list-style:none}.settings-sheet__workspace[data-v-779d567d]{box-sizing:border-box;display:block;width:100%;padding:8px 12px;overflow:hidden;border-radius:10px;font-size:14px;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.settings-sheet__workspace[data-v-779d567d]:hover{background:var(--state-hover)}.settings-sheet__workspace[aria-current=true][data-v-779d567d]{background:var(--md-secondary-container);color:var(--md-on-secondary-container)}.settings-sheet__workspace[data-v-779d567d]:focus-visible{outline:var(--focus-ring);outline-offset:-2px}.settings-sheet__workspace--add[data-v-779d567d]{color:var(--md-primary);font-weight:500}.settings-sheet__connector[data-v-779d567d]{display:flex;flex-direction:column;gap:10px;padding:12px 14px;border:1px solid var(--md-outline-variant);border-radius:12px;background:rgb(var(--glass),.35)}.settings-sheet__connector-head[data-v-779d567d]{display:flex;align-items:center;gap:10px}.settings-sheet__connector-name[data-v-779d567d]{flex:1;font-weight:600}.settings-sheet__actions[data-v-779d567d]{display:flex;flex-wrap:wrap;align-items:center;gap:10px}.settings-sheet__rules[data-v-779d567d]{display:flex;flex-direction:column;gap:6px;margin:0;padding:0 0 0 28px;font-size:13px}.settings-sheet__rule[data-v-779d567d]{display:grid;grid-template-columns:minmax(0,3fr) minmax(0,2fr);gap:12px;padding:4px 0;border-bottom:1px solid var(--md-outline-variant)}.settings-sheet__rule-when[data-v-779d567d]{color:var(--md-on-surface-variant);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;overflow-wrap:anywhere}.settings-sheet__rule-then[data-v-779d567d]{overflow-wrap:anywhere}.settings-sheet__rules-note[data-v-779d567d]{margin:0;color:var(--md-on-surface-variant)}.app__shell[data-v-f146b085]{box-sizing:border-box;display:flex;flex-direction:column;height:100%;padding:12px 12px 12px 72px}.app__shell>.dashboard[data-v-f146b085]{flex:1 1 auto;min-height:0}@media(min-width:901px){.app__shell>.dashboard.dashboard--fit[data-v-f146b085]{height:auto}}@media(max-width:900px){.app__shell[data-v-f146b085]{height:auto}}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{w as X,t as qe,r as Ye,s as Kt,c as g,d as W,o as l,a as i,F as V,b as N,e as K,u as p,n as U,f as o,g as h,h as C,i as I,_ as j,j as F,k as O,l as q,m as Ue,p as vt,q as We,v as te,x as Gt,y as Le,z as Ne,A as He,B as Jt,C as mt,D as Zt,E as Qt,G as es,H as ts}from"./_plugin-vue_export-helper-DHr5RHTx.js";import{s as ss,m as kt,u as yt,a as gt,r as bt,p as ns,b as os,i as nt,l as wt,c as as,M as G,d as ge,e as me,f as ls,g as Xe,h as Te,j as rs,k as Me,n as is,o as cs,q as ds,t as us,v as ot,w as ps}from"./scheme-DJ3WNw60.js";import{g as Ae,r as _s,a as hs,e as fs,w as xt,p as ae,b as oe,T as je,S as we,c as ne,h as vs,s as Ke,m as he,d as ms,f as $t,i as Ge,j as ks,k as Je,l as ys,y as gs,n as bs,o as ws,q as Ct}from"./bem-COKTjsky.js";const pe=ss(bt),at=(e,t)=>{const s=G,a=new Float32Array(s*s);for(let r=0;r<a.length;r+=1)a[r]=e[r]===t?1e6:0;const n=(r,c,u)=>{a[c]+u<a[r]&&(a[r]=a[c]+u)};for(let r=0;r<s;r+=1)for(let c=0;c<s;c+=1){const u=r*s+c;c>0&&n(u,u-1,1),r>0&&n(u,u-s,1),c>0&&r>0&&n(u,u-s-1,Math.SQRT2),c<s-1&&r>0&&n(u,u-s+1,Math.SQRT2)}for(let r=s-1;r>=0;r-=1)for(let c=s-1;c>=0;c-=1){const u=r*s+c;c<s-1&&n(u,u+1,1),r<s-1&&n(u,u+s,1),c<s-1&&r<s-1&&n(u,u+s+1,Math.SQRT2),c>0&&r<s-1&&n(u,u+s-1,Math.SQRT2)}return a},De=e=>{const t=String(e||"").trim(),s=/^#([0-9a-f]{6})$/i.exec(t);if(s)return[0,2,4].map(n=>parseInt(s[1].slice(n,n+2),16));const a=t.match(/[\d.]+/g);return a&&a.length>=3?a.slice(0,3).map(Number):null},xs=e=>{const t=getComputedStyle(e),s=De(t.getPropertyValue("--md-primary"))||[44,86,151],a=De(t.getPropertyValue("--md-on-primary-container"))||s;return{core:nt()?s:s.map((n,r)=>wt(n,a[r],.35)),rim:De(t.getPropertyValue("--blob-3"))||[23,223,220],strength:nt()?.9:1}},$s=(e,t,s)=>({size:e.range(.85,1.05)*Math.min(t,s),right:e.chance(.4),bottom:e.chance(.7),overflowX:e.range(-.02,.06),overflowY:e.range(-.02,.04)}),Cs=e=>{const t={minX:G,maxX:0,minY:G,maxY:0};for(let a=0;a<e.length;a+=1)if(e[a]){const n=a%G,r=Math.floor(a/G);t.minX=Math.min(t.minX,n),t.maxX=Math.max(t.maxX,n),t.minY=Math.min(t.minY,r),t.maxY=Math.max(t.maxY,r)}const s=a=>(a-G/2)/ge;return{minX:s(t.minX),maxX:s(t.maxX),minY:s(t.minY),maxY:s(t.maxY)}},Ss=(e,t,s,a)=>{const n=t.maxX-t.minX,r=t.maxY-t.minY,c=Math.min(e.size,2*s*.95/n,2*a*.98/r),u=c/2,v=-e.overflowX*c,_=-e.overflowY*c;return{size:c,centerX:e.right?s-v-t.maxX*u:v-t.minX*u,centerY:e.bottom?a-_-t.maxY*u:_-t.minY*u}},Ts=(e,t,s)=>"rgba("+e.core.map((n,r)=>Math.round(wt(n,e.rim[r],t))).join(",")+","+s.toFixed(3)+")",Ms=(e,t,s)=>{const a=[],n=t.size/62,r=t.size/2/ge,c=t.size*ls/4,u=n*.866;for(let v=0,_=t.centerY-c;_<t.centerY+c;v+=1,_+=u)for(let y=t.centerX-c+v%2*n/2;y<t.centerX+c;y+=n){const A=y+e.range(-.3,.3)*n,E=_+e.range(-.3,.3)*n,R=Math.floor((A-t.centerX)/r+G/2),S=Math.floor((E-t.centerY)/r+G/2);if(R<0||S<0||R>=G||S>=G)continue;const d=S*G+R,k=e.next(),f=e.range(.75,1.25),B=e.range(-.15,.15);if(s.inside[d]){const z=s.depth[d]/ge,L=me(z/.035),J=me(z/.3);if(k>.5+.5*L)continue;a.push({x:A,y:E,radius:n*.5*(.45+.55*L)*(.95+.3*J)*f,alpha:.5+.25*L+.25*J,tint:me(.65-.65*J+B)})}else{const z=s.gap[d]/ge;if(k>.14*Math.exp(-z/.05)+.004)continue;a.push({x:A,y:E,radius:n*e.range(.1,.24),alpha:.35,tint:me(.8+B)})}}return a},As=()=>document.getElementById("wt"),Rs=()=>document.getElementById("backdrop"),St=()=>Math.floor(Math.random()*4294967296),ke={},D={workspace:"",seed:St(),species:"",wantedSpecies:"",wantedPose:"",built:null},Es=(e,t)=>{const s=as(D.seed),a=pe[Math.floor(s.next()*pe.length)];D.species=pe.includes(D.wantedSpecies)?D.wantedSpecies:a;const n=$s(s,e,t),r={facing:n.right?-1:1,tilt:s.range(-.07,.07),stretchX:s.range(.92,1.08),stretchY:s.range(.92,1.08)};s.chance(.25)&&(r.facing=-r.facing);const c=ns(os(bt,D.species,s,{pose:D.wantedPose}).shapes,r),u={inside:c,depth:at(c,1),gap:at(c,0)},v=Ss(n,Cs(c),e,t);return{key:D.seed+":"+D.species+":"+e+"x"+t,dots:Ms(s,v,u)}},xe=()=>{const e=Rs();if(!e)return;const t=e.clientWidth,s=e.clientHeight,a=window.devicePixelRatio||1,n=Math.round(t*a),r=Math.round(s*a);(e.width!==n||e.height!==r)&&(e.width=n,e.height=r);const c=e.getContext("2d");if(!c||(c.setTransform(a,0,0,a,0,0),c.clearRect(0,0,t,s),!t||!s))return;const u=D.seed+":"+(D.wantedSpecies||"?")+":"+t+"x"+s;(!D.built||D.built.key.split(":")[0]!==String(D.seed)||!D.built.key.endsWith(t+"x"+s)||D.wantedSpecies&&D.species!==D.wantedSpecies)&&(D.built=Es(t,s));const v=As();if(!v)return u;const _=xs(v);return D.built.dots.forEach(y=>{c.fillStyle=Ts(_,y.tint,y.alpha*_.strength),c.beginPath(),c.arc(y.x,y.y,y.radius,0,Math.PI*2),c.fill()}),u};window.whoseTurnBackdrop={species:pe.slice(),seeded:kt,get current(){return{workspace:D.workspace,species:D.species,seed:D.seed}},show:e=>{const t=e||{},s=String(t.workspace||"");ke[s]||(ke[s]=St());const a=t.seed!==void 0?Number(t.seed)>>>0:ke[s];ke[s]=a;const n=t.species&&pe.includes(t.species)?t.species:"",r=String(t.pose||"");return s===D.workspace&&a===D.seed&&n===D.wantedSpecies&&r===D.wantedPose&&D.built||(D.workspace=s,D.seed=a,D.wantedSpecies=n,D.wantedPose=r,D.built=null,xe()),window.whoseTurnBackdrop.current},repaint:xe};X(Xe,xe);yt(window,"resize",gt(xe,200));const{show:Tt,repaint:Os,seeded:Pr}=window.whoseTurnBackdrop,Is=()=>{window.tippy&&window.tippy.delegate(document.body,{target:"[data-tip]",content:e=>e.dataset.tip||"",trigger:"mouseenter focus click",delay:[0,80],duration:[120,80],interactive:!0,maxWidth:440,placement:"top",theme:"wt",appendTo:()=>document.body})},Ds=()=>{let e=0;return{next:()=>++e,accepts:t=>t===e}},lt=e=>{const t=structuredClone(qe(e)),s=t.connectors||{},a=t.rules||{};return a.statuses=a.statuses||{},{...t,connectors:Array.isArray(s)?s:Object.entries(s).map(([n,r])=>({type:n,...r})),rules:a,theme:t.theme||{}}},Bs=e=>{const t=structuredClone(qe(e));return t.theme&&!Object.keys(t.theme).length&&delete t.theme,t.rules&&!Object.keys(t.rules.statuses||{}).length&&delete t.rules.statuses,t.rules&&!Object.keys(t.rules).length&&delete t.rules,t},rt=new WeakMap;let Vs=0;const it=e=>{const t=qe(e);let s=rt.get(t);return s||(s=++Vs,rt.set(t,s)),s},ct=e=>JSON.stringify(e),Us=(e,t)=>{const s=[];return e.forEach(a=>a.connectors.forEach(n=>{const r=t.get(n)||{};Object.keys(r).forEach(c=>{r[c]&&s.push({ws:a.id,connector:n.id||n.type,key:c,value:r[c]})})})),s},le=(e,t,s)=>{typeof s=="boolean"||s&&s.length?e[t]=s:delete e[t]},Ws=(e,t)=>{const s=a=>{const n=t.indexOf(a.id);return n<0?t.length:n};return[...e].sort((a,n)=>s(a)-s(n))},Ns=(e,t,s,a)=>{const n=e.filter(r=>r!==t);return n.splice(n.indexOf(s)+(a?0:1),0,t),n},js={gt:">",gte:"≥",lt:"<",lte:"≤",prefix:"starts with"},Ps=(e,t)=>`${e} is ${t?"present":"absent"}`,Fs=(e,t)=>Array.isArray(t)?`${e} in ${t.join(", ")}`:t&&typeof t=="object"?Object.entries(t).map(([s,a])=>s==="present"?Ps(e,a):`${e} ${js[s]} ${JSON.stringify(a)}`).join(" and "):`${e} = ${t}`,zs=e=>({when:Object.entries(e.when).map(([t,s])=>Fs(t,s)).join(" and ")||"anything else",then:e.then.whose==="hidden"?"hidden":`${e.then.whose}: ${e.then.next}`}),qs=e=>e.modal?"modal":e.settings?"settings":e.feedback?"feedback":null,Ys=(e,t)=>{const s=new URLSearchParams(e).get("mode");return s==="app"||s==="tab"?s:t==="app"?"app":"tab"},Ls=e=>"/?mode=tab"+(e?"&ws="+encodeURIComponent(e):""),Hs=e=>({width:e.outerWidth,height:e.outerHeight}),Mt={writeDefaults:!1},At=Te("wt-ws","",Mt),Rt=rs("wt-mode","",Mt),m=Kt({workspaces:[],workspace:{id:"",name:"",connectors:[],links:[],key_pattern:"",theme:null},turn:[],feed:[],marks:{seen:[],base:0,handled:{}},counts:{mine:0,others:0,failing:0,done:0},todos:[],errors:{},health:{ok:!0,stale:!1,fresh_at:"",failing:[],alerts:[]},problems:[],polled_at:"",update:{current:"",latest:"",available:!1,state:"idle"}}),b=Ye({ws:new URLSearchParams(location.search).get("ws")||At.value,open:new Set,mode:Ys(location.search,Rt.value),live:!1,reconnects:0,status:"Connecting…",modal:null,feedback:!1,settings:!1,settingsDirty:!1,settingsAsk:!1,settingsAt:""});Rt.value=b.mode;const $e=Me("",6e3),ie=(e,t)=>{const s=oe(e,t);return s&&($e.value=s),!s},Xs=()=>{b.mode==="app"&&yt(window,"resize",gt(()=>ae("/api/window",Hs(window)).catch(ie),600))},Et={resume:()=>{}},ce=cs({scheduler:e=>{const t=ds(e,3e4,{immediate:!1});return Et.resume=t.resume,t}}),dt=g(()=>{const e=m.workspace.theme;return e&&e.light&&e.dark?e[Xe.value?"dark":"light"]:{}}),H=g(()=>m.counts),ut=g(()=>[...m.problems||[],...m.health.alerts.map(e=>e.text),...Object.entries(m.errors||{}).map(([e,t])=>e+": "+t)]),Ks=(e="")=>{b.settingsAt=e,b.settings=!0},Ot=g(()=>qs(b)),Gs=()=>{const e=Ot.value;if(e==="modal"&&(b.modal=null),e==="feedback"&&(b.feedback=!1),e==="settings"){if(b.settingsDirty){b.settingsAsk=!0;return}b.settings=!1}},Pe=new Map,Js=(e,t)=>{t&&Pe.set(e,document.activeElement)},Zs=(e,t)=>{if(t)return;const s=Pe.get(e);Pe.delete(e),s instanceof HTMLElement&&s.focus()},Qs={modal:()=>!!b.modal,settings:()=>b.settings,feedback:()=>b.feedback};Object.entries(Qs).forEach(([e,t])=>{X(t,s=>Js(e,s),{flush:"sync"}),X(t,s=>Zs(e,s),{flush:"post"})});let Ce=-1,Fe=0;const pt=Ds(),fe=(e=b.ws)=>{const t=pt.next();return Ae("/api/state"+(e?"?ws="+encodeURIComponent(e):"")).then(s=>pt.accepts(t)?s.error?_s(s.error)!=="NO_SUCH_WORKSPACE"||!hs(e)?(b.status=fs(s.error,"Could not load"),m):fe(""):(Object.assign(m,s),b.ws=m.workspace.id,b.status="",Tt({workspace:m.workspace.id}),document.title="Whose Turn · "+m.workspace.name,m):m)},It=()=>(Ce=-1,fe()),_e=is("/api/stream",[],{immediate:!1,autoConnect:!1,autoReconnect:!0,serializer:{read:e=>JSON.parse(e||"null")}});X(_e.status,e=>{b.live=e==="OPEN",b.live&&(b.status="",b.reconnects++)},{flush:"sync"});X(_e.error,e=>{e&&(b.status="Disconnected from the local server, retrying…")},{flush:"sync"});X(_e.data,e=>{if(e){if("update"in e){m.update=e.update;return}typeof e.open_moves=="number"&&(m.workspaces=xt(m.workspaces,e.ws,e.open_moves)),!(m.workspace.id&&e.ws!==m.workspace.id)&&(b.status="",e.version!==Ce?(Ce=e.version,Fe===0&&fe()):m.polled_at=e.polled_at)}},{flush:"sync"});const en=()=>{_e.eventSource.value||_e.open()},tn=()=>(Et.resume(),fe().then(en)),sn=e=>e===m.workspace.id?Promise.resolve():(Ce=-1,Fe++,fe(e).then(()=>{b.ws===e&&(At.value=b.ws,b.open.clear())},()=>{$e.value=we+"; staying on "+m.workspace.name+"."}).finally(()=>{Fe--})),Dt=(e,t)=>ae(e,{ws:m.workspace.id,...t}),ze=e=>Dt("/api/marks",e).then(t=>{const s=oe(t);return s||(Object.assign(m,{marks:t.marks,turn:t.turn,counts:t.counts}),m.workspaces=xt(m.workspaces,m.workspace.id,t.counts.mine)),s},t=>oe(t)),nn=e=>Dt("/api/todos",e).then(t=>{const s=oe(t,{unreachable:je});return!s&&Array.isArray(t)&&(m.todos=t),s},t=>oe(t,{unreachable:je})),on=e=>Ae("/api/config").then(t=>ae("/api/config",{workspaces:Ws(t.workspaces,e),secrets:[]})).then(t=>{ie(t,{refused:"The order was not saved"})&&It()},t=>ie(t,{refused:"The order was not saved"})),_t=()=>{b.status="Checking now…",ae("/api/refresh").catch(e=>{b.status="",ie(e)}),Tt({workspace:m.workspace.id,seed:Math.floor(Math.random()*4294967296)})},an="M12 2.5l1.9 5.6 5.6 1.9-5.6 1.9L12 17.5l-1.9-5.6L4.5 10l5.6-1.9L12 2.5zM5 15l.9 2.6 2.6.9-2.6.9L5 22l-.9-2.6-2.6-.9 2.6-.9L5 15zm14-2l.7 2 2 .7-2 .7-.7 2-.7-2-2-.7 2-.7.7-2z",ln="M19.4 13a7.6 7.6 0 0 0 0-2l2-1.5-2-3.4-2.4 1a7.5 7.5 0 0 0-1.7-1L15 3.5H9l-.3 2.6a7.5 7.5 0 0 0-1.7 1l-2.4-1-2 3.4 2 1.5a7.6 7.6 0 0 0 0 2l-2 1.5 2 3.4 2.4-1a7.5 7.5 0 0 0 1.7 1l.3 2.6h6l.3-2.6a7.5 7.5 0 0 0 1.7-1l2.4 1 2-3.4-2-1.5zM12 15.5a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7z",rn="M19 8h-1.8a5.9 5.9 0 0 0-1.3-1.9l1.6-1.6-1.4-1.4-1.9 1.9A5.7 5.7 0 0 0 12 4.5a5.7 5.7 0 0 0-2.2.5L7.9 3.1 6.5 4.5l1.6 1.6A5.9 5.9 0 0 0 6.8 8H5v2h1.2a7 7 0 0 0 0 1v1H5v2h1.3a6 6 0 0 0 11.4 0H19v-2h-1.2v-1a7 7 0 0 0 0-1H19V8zm-7 10a4 4 0 0 1-4-4v-3a4 4 0 0 1 8 0v3a4 4 0 0 1-4 4zm-1-7h2v5h-2z",cn=e=>{let t=2166136261;for(let s=0;s<e.length;s+=1)t^=e.charCodeAt(s),t=Math.imul(t,16777619);return t>>>0},Bt=e=>{const t=String(e||"").trim().split(/[\s_-]+/).filter(Boolean);return(t.length>=2?t.slice(0,3).map(a=>a.charAt(0)):(t[0]||"?").slice(0,2).split("")).join("").toUpperCase()},dn=e=>({1:17,2:14,3:11})[e.length]||11,un=(e,t)=>{const s=t(cn(e.id)),a=[],n=3+Math.floor(s()*3);for(let c=0;c<n;c+=1){const u=s()*Math.PI*2,v=9+s()*7;a.push({cx:(18+Math.cos(u)*v).toFixed(1),cy:(18+Math.sin(u)*v).toFixed(1),r:(1.6+s()*2.2).toFixed(1),opacity:(.35+s()*.4).toFixed(2)})}const r=Bt(e.name||e.id);return{dots:a,glyph:r,fontSize:dn(r)}},pn={class:"rail","aria-label":"Workspaces"},_n=["data-drop","href","aria-label","aria-selected","onClick","onDragstart","onDragover","onDrop"],hn={viewBox:"0 0 36 36",class:"rail__icon","aria-hidden":"true"},fn=["fill"],vn=["cx","cy","r","fill","opacity"],mn=["y","font-size","fill"],kn={class:"rail__label"},yn={key:0,class:"rail__badge"},gn={viewBox:"0 0 24 24",class:"rail__gear","aria-hidden":"true"},bn=["d"],wn=W({__name:"Rail",emits:["settings"],setup(e,{emit:t}){const s=t,a=g(()=>Object.fromEntries(m.workspaces.map(d=>[d.id,un(d,kt)]))),n=g(()=>Object.fromEntries(m.workspaces.map(d=>{const k=d.theme?d.theme[Xe.value?"dark":"light"]:null;return[d.id,{fill:k?k["--md-primary-container"]:"var(--md-primary-container)",ink:k?k["--md-on-primary-container"]:"var(--md-on-primary-container)",dot:k?k["--md-primary"]:"var(--md-primary)"}]}))),r=d=>{d.detail>0&&d.currentTarget.blur()},c=(d,k)=>{r(d),sn(k)},u=d=>{s("settings"),r(d)},v=I(""),_=I({}),y=d=>{const k=d.currentTarget;return d.clientY-k.getBoundingClientRect().top<k.offsetHeight/2},A=(d,k)=>{v.value=k.id,d.dataTransfer&&(d.dataTransfer.effectAllowed="move",d.dataTransfer.setData("text/plain",k.id))},E=()=>{v.value="",_.value={}},R=(d,k)=>{if(!v.value||v.value===k.id)return;d.preventDefault(),d.dataTransfer&&(d.dataTransfer.dropEffect="move");const f=y(d)?"before":"after";(_.value.id!==k.id||_.value.side!==f)&&(_.value={id:k.id,side:f})},S=(d,k)=>{if(!v.value||v.value===k.id)return;d.preventDefault();const f=Ns(m.workspaces.map(B=>B.id),v.value,k.id,y(d));_.value={},on(f)};return(d,k)=>(l(),i("nav",pn,[(l(!0),i(V,null,N(p(m).workspaces,f=>(l(),i("a",{key:f.id,class:U(["rail__item",{"rail__item--dragging":v.value===f.id}]),"data-drop":_.value.id===f.id?_.value.side:null,href:"?ws="+encodeURIComponent(f.id),"aria-label":f.name,"aria-selected":f.id===p(m).workspace.id,draggable:"true",onClick:K(B=>c(B,f.id),["prevent"]),onDragstart:B=>A(B,f),onDragend:E,onDragover:B=>R(B,f),onDragleave:k[0]||(k[0]=B=>_.value={}),onDrop:B=>S(B,f)},[(l(),i("svg",hn,[o("rect",{x:"0",y:"0",width:"36",height:"36",rx:"10",fill:n.value[f.id].fill},null,8,fn),(l(!0),i(V,null,N(a.value[f.id].dots,(B,z)=>(l(),i("circle",{key:z,cx:B.cx,cy:B.cy,r:B.r,fill:n.value[f.id].dot,opacity:B.opacity},null,8,vn))),128)),o("text",{x:"18",y:a.value[f.id].fontSize>=17?24:23,"text-anchor":"middle","font-size":a.value[f.id].fontSize,"font-weight":"700","letter-spacing":"-0.5","font-family":"Roboto, Inter, system-ui, sans-serif",fill:n.value[f.id].ink},h(a.value[f.id].glyph),9,mn)])),o("span",kn,h(f.name),1),f.open_moves?(l(),i("span",yn,h(f.open_moves),1)):C("",!0)],42,_n))),128)),k[2]||(k[2]=o("span",{class:"rail__spacer"},null,-1)),o("a",{class:"rail__item",href:"#settings","aria-label":"Settings",onClick:K(u,["prevent"])},[(l(),i("svg",gn,[o("path",{d:p(ln),fill:"currentColor"},null,8,bn)])),k[1]||(k[1]=o("span",{class:"rail__label"},"Settings",-1))])]))}}),xn=j(wn,[["__scopeId","data-v-be863916"]]),Be=" · checks every minute",Vt=(e,t,s,a)=>{const n=e.failing.map(c=>c.source),r=t?ne(t):"—";return n.length&&n.length>=s?{dot:"off",text:"No data: "+n.join(", ")+" failing · last data "+ne(e.fresh_at),failing:n,noData:!0}:e.stale?{dot:"off",text:"Stale · last data "+ne(e.fresh_at)+Be,failing:n,noData:!1}:n.length?{dot:a?"warn":"off",text:n.join(", ")+" failing · last check "+r+Be,failing:n,noData:!1}:{dot:a?"ok":"off",text:"Live · last check "+r+Be,failing:n,noData:!1}},$n=["data-tip"],Cn={class:"ai-button__icon",viewBox:"0 0 24 24","aria-hidden":"true"},Sn=["d"],Tn=W({__name:"AiButton",props:{query:{},big:{type:Boolean}},setup(e){const t=e,s={"":"Copy for AI: this with its context as text, ready to paste into Claude or any other assistant",sent:"Copied",failed:"Could not copy"},a=Me("",1600),n=g(()=>s[a.value]),r=()=>vs(t.query).then(c=>navigator.clipboard.writeText(c)).then(()=>{a.value="sent"},()=>{a.value="failed"});return(c,u)=>(l(),i("button",{type:"button",class:U(["ai-button",{"ai-button--big":e.big,"ai-button--sent":p(a)==="sent","ai-button--failed":p(a)==="failed"}]),"aria-label":"Copy for AI","data-tip":n.value,onClick:K(r,["stop"])},[(l(),i("svg",Cn,[o("path",{d:p(an),fill:"currentColor"},null,8,Sn)]))],10,$n))}}),de=j(Tn,[["__scopeId","data-v-d32a60c7"]]),Mn={key:0,class:"update-chip update-chip--done",role:"status"},An={key:1,class:"update-chip update-chip--busy",role:"status"},Rn=["title"],En=15e3,On=W({__name:"UpdateChip",setup(e){const t=I(!1),s=I(""),a=Me("",En),n=g(()=>m.update),r=g(()=>t.value||n.value.state==="installing"||n.value.state==="restarting");X(()=>n.value.current,u=>{s.value&&u&&u!==s.value&&(a.value=u,s.value="")});const c=()=>{if(r.value)return;t.value=!0,s.value=n.value.current;const u=v=>{if(t.value=!1,!ie(v,{refused:"The update did not start"})){s.value="";return}m.update=v.update};ae("/api/update").then(u,u)};return(u,v)=>p(a)?(l(),i("span",Mn,"Updated to "+h(p(a)),1)):r.value?(l(),i("span",An,"Updating…")):n.value.available&&n.value.state==="failed"?(l(),i("button",{key:2,type:"button",class:"update-chip update-chip--failed",title:n.value.reason,onClick:c}," Update failed · Retry ",8,Rn)):n.value.available?(l(),i("button",{key:3,type:"button",class:"update-chip",onClick:c},h(n.value.latest)+" is out · Update ",1)):C("",!0)}}),In=j(On,[["__scopeId","data-v-f70d2aed"]]),Dn={class:"status-bar"},Bn={class:"status-bar__icon",viewBox:"0 0 24 24","aria-hidden":"true"},Vn=["d"],Un={key:0,class:"status-bar__notice",role:"alert"},Wn=["href"],Nn=["aria-disabled"],jn=5e3,Pn=W({__name:"StatusBar",emits:["report"],setup(e,{emit:t}){const s=t,a=g(()=>(ce.value,Vt(m.health,m.polled_at,m.workspace.connectors.length,b.live))),n=I(!1),r=I(!1),c=g(()=>r.value?"Opened in the app window. You can close this tab.":b.status||a.value.text),u=_=>ie(_,{refused:"The app window did not open"}),v=()=>{if(n.value)return;n.value=!0,setTimeout(()=>n.value=!1,jn);const _=y=>{u(y),r.value=!oe(y)};ae("/api/open",{mode:"app"}).then(_,_)};return(_,y)=>(l(),i("div",Dn,[o("button",{type:"button",class:"btn status-bar__btn status-bar__report",title:"A bug or a wish about this monitor, straight to its backlog",onClick:y[0]||(y[0]=A=>s("report"))},[(l(),i("svg",Bn,[o("path",{d:p(rn),fill:"currentColor"},null,8,Vn)])),y[2]||(y[2]=F("Report ",-1))]),o("span",{class:U(["status-bar__live",{"status-bar__live--off":a.value.dot==="off","status-bar__live--warn":a.value.dot==="warn"}])},null,2),o("span",null,h(c.value),1),p($e)?(l(),i("span",Un,h(p($e)),1)):C("",!0),O(In),o("button",{type:"button",class:"btn status-bar__btn",onClick:y[1]||(y[1]=(...A)=>p(_t)&&p(_t)(...A))},"Refresh now"),p(b).mode==="app"?(l(),i("a",{key:1,class:"btn status-bar__btn",href:p(Ls)(p(b).ws),target:"_blank",rel:"noopener"},"Open in browser",8,Wn)):(l(),i("button",{key:2,type:"button",class:U(["btn status-bar__btn",{"status-bar__btn--busy":n.value}]),"aria-disabled":n.value,onClick:v},h(n.value?"Opening…":"Open as app"),11,Nn)),O(de,{query:{all:"1"}}),y[3]||(y[3]=o("span",{class:"ai-hint status-bar__ai-hint"},"AI: copy everything",-1))]))}}),Fn=j(Pn,[["__scopeId","data-v-eefe1de8"]]),Ut=e=>{const t=Te("wt-collapsed",[],{writeDefaults:!1}),s=g(()=>t.value.includes(e));return{collapsed:s,toggle:()=>{t.value=s.value?t.value.filter(n=>n!==e):[...t.value,e]}}},zn=["href"],qn={key:1},se=W({__name:"ExtLink",props:{text:{default:""},url:{default:""}},setup(e){const t=e,s=g(()=>Ke(t.url));return(a,n)=>s.value?(l(),i("a",{key:0,href:s.value,target:"_blank",rel:"noopener"},h(e.text),9,zn)):(l(),i("span",qn,h(e.text),1))}}),Yn={class:"workspace-header__title"},Ln={class:"workspace-header__name"},Hn={class:"workspace-header__line workspace-header__sentence"},Xn={class:"workspace-header__count"},Kn={class:"workspace-header__count"},Gn={key:0},Jn={class:"workspace-header__count"},Zn={key:0,class:"workspace-header__line workspace-header__strip"},Qn={class:"workspace-header__count"},eo={class:"workspace-header__count"},to={class:"workspace-header__count"},so={class:"workspace-header__count"},no={class:"workspace-header__line workspace-header__give"},oo={class:"workspace-header__links"},ao={class:"workspace-header__tiles"},lo={class:"workspace-header__tile workspace-header__tile--you"},ro={class:"workspace-header__tile-value"},io={class:"workspace-header__tile"},co={class:"workspace-header__tile-value"},uo={class:"workspace-header__tile-value"},po={class:"workspace-header__tile"},_o={class:"workspace-header__tile-value"},ho=W({__name:"WorkspaceHeader",setup(e){const{collapsed:t,toggle:s}=Ut("header");return(a,n)=>(l(),i("header",{id:"summary",class:U(["island workspace-header",{"workspace-header--collapsed":p(t)}])},[o("div",Yn,[o("h1",Ln,h(p(m).workspace.name||"Whose Turn"),1),o("p",Hn,[o("b",Xn,h(p(H).mine),1),n[3]||(n[3]=F(" waiting on you, ",-1)),o("b",Kn,h(p(H).others),1),n[4]||(n[4]=F(" waiting on someone else",-1)),p(H).failing?(l(),i("span",Gn,[n[1]||(n[1]=F(", ",-1)),o("b",Jn,h(p(H).failing),1),n[2]||(n[2]=F(" failing",-1))])):C("",!0),n[5]||(n[5]=F(". ",-1))]),p(t)?(l(),i("p",Zn,[n[6]||(n[6]=F(" Your move ",-1)),o("b",Qn,h(p(H).mine),1),n[7]||(n[7]=F(" · Waiting on others ",-1)),o("b",eo,h(p(H).others),1),n[8]||(n[8]=F(" · Failing ",-1)),o("b",to,h(p(H).failing),1),n[9]||(n[9]=F(" · Done ",-1)),o("b",so,h(p(H).done),1)])):C("",!0),o("p",no,[O(de,{query:{ws:p(m).workspace.id,kind:"workspace"},big:""},null,8,["query"]),n[10]||(n[10]=o("span",{class:"ai-hint"},"AI: copy this workspace",-1)),o("span",oo,[(l(!0),i(V,null,N(p(m).workspace.links||[],r=>(l(),q(se,{key:r.url,text:r.label,url:r.url,title:r.url},null,8,["text","url","title"]))),128))])])]),o("button",{type:"button",class:U(["fold-toggle workspace-header__fold",{"fold-toggle--folded":p(t)}]),"aria-label":"Collapse or expand header","data-tip":"Fold the header; it stays folded until you open it again",onClick:n[0]||(n[0]=K((...r)=>p(s)&&p(s)(...r),["stop"]))}," ▾ ",2),o("div",ao,[o("div",lo,[n[11]||(n[11]=o("span",{class:"workspace-header__tile-label"},"Your move",-1)),o("strong",ro,h(p(H).mine),1)]),o("div",io,[n[12]||(n[12]=o("span",{class:"workspace-header__tile-label"},"Waiting on others",-1)),o("strong",co,h(p(H).others),1)]),o("div",{class:U(["workspace-header__tile",{"workspace-header__tile--fail":p(H).failing}])},[n[13]||(n[13]=o("span",{class:"workspace-header__tile-label"},"Open PRs with failing checks",-1)),o("strong",uo,h(p(H).failing),1)],2),o("div",po,[n[14]||(n[14]=o("span",{class:"workspace-header__tile-label"},"Done in the last 30 days",-1)),o("strong",_o,h(p(H).done),1)])])],2))}}),fo=j(ho,[["__scopeId","data-v-0f4b6d6e"]]),Ze=e=>{X(()=>b.reconnects,e)},vo=["id"],mo={class:"island__head"},ko={class:"island__title"},yo={class:"island__note"},go={class:"island__note-text"},bo=["data-tip"],wo=["aria-label"],xo={class:"island__body"},$o=W({__name:"Island",props:{id:{},title:{},note:{default:""},tip:{default:""},column:{type:Boolean}},setup(e){const t=e,{collapsed:s,toggle:a}=Ut(t.id);return(n,r)=>(l(),i("section",{id:e.id,class:U(["island",{"island--collapsed":p(s),"island--column":e.column}])},[o("div",mo,[o("h2",ko,[F(h(e.title)+" ",1),Ue(n.$slots,"head",{},void 0)]),o("p",yo,[o("span",go,h(e.note),1),e.tip?(l(),i("button",{key:0,type:"button",class:"hint-icon","aria-label":"More info","data-tip":e.tip}," ? ",8,bo)):C("",!0),o("button",{type:"button",class:U(["fold-toggle",{"fold-toggle--folded":p(s)}]),"aria-label":"Collapse or expand "+e.id,"data-tip":"Fold this panel; it stays folded until you open it again",onClick:r[0]||(r[0]=K((...c)=>p(a)&&p(a)(...c),["stop"]))}," ▾ ",10,wo)])]),o("div",xo,[Ue(n.$slots,"default",{},void 0)])],10,vo))}}),Re=j($o,[["__scopeId","data-v-a03b7f62"]]),Co=["aria-label"],So=["aria-pressed","onClick"],To={key:0,class:"segmented__count"},Mo=W({__name:"Segmented",props:We({options:{},label:{default:""},chips:{type:Boolean}},{modelValue:{required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(e){const t=vt(e,"modelValue");return(s,a)=>(l(),i("span",{class:U(["segmented",{"segmented--chips":e.chips}]),role:"group","aria-label":e.label},[(l(!0),i(V,null,N(e.options,n=>(l(),i("button",{key:n.id,type:"button",class:"segmented__option","aria-pressed":t.value===n.id,onClick:r=>t.value=n.id},[F(h(n.label),1),n.count!==void 0?(l(),i("b",To,h(n.count),1)):C("",!0)],8,So))),128))],10,Co))}}),Se=j(Mo,[["__scopeId","data-v-7901b5d6"]]),Ao={class:"ticket-cell"},Ro={class:"ticket-cell__summary"},Eo=W({__name:"TicketCell",props:{row:{}},setup(e){return(t,s)=>(l(),i("td",Ao,[O(se,{text:e.row.key,url:e.row.ticket_url,class:"ticket-key"},null,8,["text","url"]),o("span",Ro,h(e.row.summary),1)]))}}),Qe=j(Eo,[["__scopeId","data-v-8436de88"]]),Oo={key:0,class:"pr-cell"},Io={key:1,class:"pill"},Do=W({__name:"PrCell",props:{row:{}},setup(e){return(t,s)=>(l(),i("td",null,[e.row.pr?(l(),i("span",Oo,[O(se,{text:e.row.pr,url:e.row.pr_url,class:"pr-cell__link"},null,8,["text","url"]),e.row.pr_state==="OPEN"&&e.row.checks?(l(),i("span",{key:0,class:U(["pill",p(he)("pill",p(ms)(e.row.checks))])},h(e.row.checks),3)):e.row.pr_state?(l(),i("span",Io,h(e.row.pr_state.toLowerCase()),1)):C("",!0)])):C("",!0)]))}}),Wt=j(Do,[["__scopeId","data-v-75c443c3"]]),Bo=["open"],Vo={class:"recently-done__summary"},Uo={class:"recently-done__count"},Wo={class:"recently-done__list"},No={class:"table"},jo=["data-tip"],Po={class:"table__actions"},Fo=W({__name:"RecentlyDone",setup(e){const t=Te("wt-recent-open",!1,{writeDefaults:!1,serializer:{read:n=>n==="1",write:n=>n?"1":"0"}}),s=n=>{t.value=n.target.open},a=g(()=>(ce.value,ks(m.turn).map(n=>({row:n,since:Je(n.status_since||n.updated)}))));return(n,r)=>a.value.length?(l(),i("details",{key:0,class:"recently-done",open:p(t),onToggle:s},[o("summary",Vo,[r[0]||(r[0]=F(" Recently done ",-1)),o("span",Uo,h(a.value.length),1)]),o("div",Wo,[o("table",No,[r[1]||(r[1]=o("thead",null,[o("tr",null,[o("th",null,"Ticket"),o("th",null,"Status"),o("th",null,"Done"),o("th",{class:"table__actions-col"},[o("span",{class:"visually-hidden"},"Copy for AI")])])],-1)),o("tbody",null,[(l(!0),i(V,null,N(a.value,({row:c,since:u})=>(l(),i("tr",{key:c.row_id},[O(Qe,{row:c},null,8,["row"]),o("td",null,[o("span",{class:U(["pill",p(he)("pill",p($t)(c.status_group))])},h(c.status),3)]),o("td",null,[o("span",{class:"age","data-tip":"Done "+p(Ge)(c.status_since||c.updated)},h(u.text),9,jo)]),o("td",Po,[O(de,{class:"table__ai",query:{ws:p(m).workspace.id,kind:"row",ref:c.row_id}},null,8,["query"])])]))),128))])])])],40,Bo)):C("",!0)}}),zo=j(Fo,[["__scopeId","data-v-12ee20e8"]]),qo=13,Yo=W({__name:"RowScroll",props:{floor:{type:Boolean}},setup(e){const t=I(null),s=I(null),{y:a}=us(t),{height:n}=ot(t),{height:r}=ot(s),c=()=>{var y,A,E;return[...((E=(A=(y=s.value)==null?void 0:y.querySelector("table"))==null?void 0:A.tBodies[0])==null?void 0:E.rows)||[]]},u=()=>{const y=t.value;return y?y.getBoundingClientRect().top+y.clientTop+y.clientHeight:0},v=g(()=>(a.value,n.value,r.value,ys(c().map(y=>y.getBoundingClientRect().bottom),u(),qo))),_=()=>{var d,k;const y=t.value,A=c(),E=A[A.length-v.value];if(!y||!E)return;const S=((k=(d=s.value)==null?void 0:d.querySelector("thead"))==null?void 0:k.getBoundingClientRect().bottom)??y.getBoundingClientRect().top;y.scrollBy({top:E.getBoundingClientRect().top-S,behavior:"smooth"})};return(y,A)=>(l(),i(V,null,[o("div",{ref_key:"scroller",ref:t,class:U(["row-scroll",{"row-scroll--floor":e.floor}])},[o("div",{ref_key:"content",ref:s},[Ue(y.$slots,"default",{},void 0)],512)],2),v.value?(l(),i("button",{key:0,type:"button",class:"row-scroll__more",onClick:_}," +"+h(v.value)+" more ",1)):C("",!0)],64))}}),Nt=j(Yo,[["__scopeId","data-v-7bd9ace7"]]),Lo=I("open"),Ho=()=>Lo,Xo={class:"table"},Ko={class:"hint-row"},Go={class:"your-move__next"},Jo=["data-tip"],Zo=["data-tip"],Qo=["data-tip"],ea={key:0,class:"alert alert--inline your-move__problem",role:"alert"},ta={class:"table__actions"},sa=["aria-label","onClick"],na={key:0,class:"empty"},oa=W({__name:"YourMove",setup(e){const t=Ho(),s=g(()=>{ce.value;const u=gs(m.turn,t.value);return{...u,rows:u.rows.map(v=>({...v,age:Je(v.row.activity_at)}))}}),a=g(()=>[{id:"open",label:"Open",count:s.value.open},{id:"handled",label:"Handled",count:s.value.handled}]),n=g(()=>{if(t.value==="handled")return"Nothing marked as handled.";const{noData:u,failing:v}=Vt(m.health,m.polled_at,m.workspace.connectors.length,b.live);return u?"No data: "+v.join(", ")+(v.length===1?" is":" are")+" failing. Check Settings.":"Nothing is waiting on you."}),r=Ye(new Map);Ze(()=>r.clear());const c=async u=>{const v=u.row.row_id,_=await ze({handled:{[v]:u.handled?null:new Date().toISOString()}});_?r.set(v,_):r.delete(v)};return(u,v)=>(l(),q(Re,{id:"your-move",title:"Your move",note:"Next step is yours",tip:"Each row is something where the next step is yours. Ticket, PR and comment open in a new tab."},{head:te(()=>[O(Se,{modelValue:p(t),"onUpdate:modelValue":v[0]||(v[0]=_=>Gt(t)?t.value=_:null),options:a.value,label:"Show",class:"your-move__view"},null,8,["modelValue","options"])]),default:te(()=>[O(Nt,{floor:""},{default:te(()=>[o("table",Xo,[v[1]||(v[1]=o("thead",null,[o("tr",null,[o("th",null,"Ticket"),o("th",null,"Next step"),o("th",null,"PR"),o("th",{class:"hide-narrow"},"Last comment"),o("th",{class:"table__actions-col"},[o("span",{class:"visually-hidden"},"Mark")])])],-1)),o("tbody",null,[(l(!0),i(V,null,N(s.value.rows,_=>(l(),i("tr",{key:_.row.row_id,class:U(["your-move__row",{"your-move__row--handled":_.handled}])},[O(Qe,{row:_.row},null,8,["row"]),o("td",null,[o("span",Ko,[o("span",Go,h(_.row.next),1),_.age.text?(l(),i("span",{key:0,class:U(["age",{"age--old":_.age.old}]),"data-tip":"Waiting since "+p(Ge)(_.row.activity_at)},h(_.age.text),11,Jo)):C("",!0),_.row.why?(l(),i("button",{key:1,type:"button",class:"hint-icon","aria-label":"Why this is your move","data-tip":_.row.why}," ? ",8,Zo)):C("",!0),_.handled?(l(),i("span",{key:2,class:"handled-chip","data-tip":"Marked "+p(ne)(p(m).marks.handled[_.row.row_id]||"")+". Comes back in 7 days if it is still open, or sooner when something new happens."},"handled",8,Qo)):C("",!0)]),r.get(_.row.row_id)?(l(),i("p",ea,h(r.get(_.row.row_id)),1)):C("",!0)]),O(Wt,{row:_.row},null,8,["row"]),o("td",{class:U(["hide-narrow",{"your-move__quote":_.row.comment}])},[_.row.comment?(l(),q(se,{key:0,text:_.row.comment,url:_.row.comment_url},null,8,["text","url"])):C("",!0)],2),o("td",ta,[O(de,{class:"table__ai",query:{ws:p(m).workspace.id,kind:"row",ref:_.row.row_id}},null,8,["query"]),o("button",{type:"button",class:U(["your-move__mark",{"your-move__mark--undo":_.handled}]),"aria-label":(_.handled?"Move back to open: ":"Mark as handled: ")+_.row.key,onClick:K(y=>c(_),["stop"])},h(_.handled?"Undo":"Handled"),11,sa)])],2))),128))])])]),_:1}),s.value.rows.length?C("",!0):(l(),i("p",na,h(n.value),1)),p(t)==="open"?(l(),q(zo,{key:1})):C("",!0)]),_:1}))}}),aa=j(oa,[["__scopeId","data-v-e3e1502a"]]),la=I(!1),ra=()=>la,ia={class:"todos__add"},ca={key:0,class:"alert alert--inline",role:"alert"},da={class:"todos__list"},ua=["aria-checked","aria-label","onClick"],pa={class:"todos__text"},_a={class:"todos__meta"},ha=["onClick"],fa={key:0,class:"empty todos__empty"},va=W({__name:"Todos",setup(e){const t=ra(),s=I(""),a=g(()=>(m.todos||[]).filter(d=>!d.done)),n=g(()=>(m.todos||[]).filter(d=>d.done)),r=g(()=>new RegExp(m.workspace.key_pattern||"(?!)","g")),c=d=>{const k=[];let f=0;const B=d.text;for(const z of B.matchAll(r.value))z.index>f&&k.push({text:B.slice(f,z.index)}),k.push({text:z[0],url:z[0]===d.key?d.ticket_url:""}),f=z.index+z[0].length;return f<B.length&&k.push({text:B.slice(f)}),k},u=g(()=>(ce.value,(t.value?a.value.concat(n.value):a.value).map(d=>({todo:d,parts:c(d),meta:(d.by&&d.by!=="you"?d.by+" · ":"")+ne(d.created)})))),v=I("");Ze(()=>{v.value=""});const _=async d=>(v.value=await nn(d),!v.value),y=async()=>{const d=s.value.trim();d&&await _({action:"add",text:d})&&s.value.trim()===d&&(s.value="")},A=d=>_({action:d.done?"undo":"done",id:d.id}),E=d=>_({action:"delete",id:d.id}),R=g({get:()=>t.value?"done":"open",set:d=>{t.value=d==="done"}}),S=g(()=>[{id:"open",label:"Open",count:a.value.length},{id:"done",label:"Done",count:n.value.length}]);return(d,k)=>(l(),q(Re,{id:"todo",title:"To do",note:"Your own notes",tip:'Your personal to-dos, kept on this machine. Add here, or ask Claude: "add to my to-do: …". A ticket key like PROJ-123 in the text becomes a link.'},{head:te(()=>[O(Se,{modelValue:R.value,"onUpdate:modelValue":k[0]||(k[0]=f=>R.value=f),options:S.value,label:"Show",class:"todos__view"},null,8,["modelValue","options"])]),default:te(()=>[o("div",ia,[Le(o("input",{"onUpdate:modelValue":k[1]||(k[1]=f=>s.value=f),class:"input todos__input",type:"text",placeholder:"Add a to-do and press Enter","aria-label":"New to-do",autocomplete:"off",onKeydown:Ne(y,["enter"])},null,544),[[He,s.value]]),o("button",{type:"button",class:"btn btn--tonal",onClick:y},"Add")]),v.value?(l(),i("p",ca,h(v.value),1)):C("",!0),o("ul",da,[(l(!0),i(V,null,N(u.value,({todo:f,parts:B,meta:z})=>(l(),i("li",{key:f.id,class:U(["todos__item",{"todos__item--done":f.done}])},[o("button",{type:"button",class:U(["todos__check",{"todos__check--on":f.done}]),role:"checkbox","aria-checked":!!f.done,"aria-label":f.done?"Mark not done":"Mark done",onClick:L=>A(f)},null,10,ua),o("span",pa,[(l(!0),i(V,null,N(B,(L,J)=>(l(),i(V,{key:J},[L.url!==void 0?(l(),q(se,{key:0,text:L.text,url:L.url},null,8,["text","url"])):(l(),i(V,{key:1},[F(h(L.text),1)],64))],64))),128))]),o("span",_a,h(z),1),o("button",{type:"button",class:"todos__delete","aria-label":"Delete to-do",onClick:L=>E(f)}," × ",8,ha)],2))),128)),u.value.length?C("",!0):(l(),i("span",fa,h(p(t)?"Nothing here yet.":"Nothing to do. Add one above, or ask Claude."),1))])]),_:1}))}}),ma=j(va,[["__scopeId","data-v-6f034e1e"]]),ka={key:0,class:"empty"},ya={class:"table waiting__table"},ga=["data-tip"],ba={class:"hide-narrow"},wa={key:0,class:"hint-row"},xa=["data-tip"],$a={class:"table__actions"},Ca=W({__name:"Waiting",setup(e){const t=g(()=>(ce.value,bs(m.turn).map(s=>({row:s,since:s.status_since?Je(s.status_since):null}))));return(s,a)=>(l(),q(Re,{id:"waiting",title:"Waiting on others",note:"Someone else holds the next step",tip:"Tickets you touched in the last 30 days where someone else holds the next step: a reviewer, QA, or a new owner."},{default:te(()=>[t.value.length?(l(),q(Nt,{key:1},{default:te(()=>[o("table",ya,[a[0]||(a[0]=o("thead",null,[o("tr",null,[o("th",{class:"waiting__col waiting__col--ticket"},"Ticket"),o("th",{class:"waiting__col waiting__col--status"},"Status"),o("th",{class:"waiting__col waiting__col--with"},"With"),o("th",{class:"hide-narrow"},"Waiting for"),o("th",{class:"waiting__col waiting__col--pr"},"PR"),o("th",{class:"table__actions-col waiting__col waiting__col--actions"},[o("span",{class:"visually-hidden"},"Copy for AI")])])],-1)),o("tbody",null,[(l(!0),i(V,null,N(t.value,({row:n,since:r})=>(l(),i("tr",{key:n.row_id},[O(Qe,{row:n},null,8,["row"]),o("td",null,[o("span",{class:U(["pill",p(he)("pill",p($t)(n.status_group))])},h(n.status),3)]),o("td",null,[F(h(n.whose)+" ",1),r?(l(),i("span",{key:0,class:U(["age",{"age--old":r.hours>=72}]),"data-tip":n.status+" since "+p(Ge)(n.status_since)},h(r.text),11,ga)):C("",!0)]),o("td",ba,[n.hold_url?(l(),i("span",wa,[O(se,{text:n.next,url:n.hold_url,class:"waiting__reason"},null,8,["text","url"]),o("button",{type:"button",class:"hint-icon","aria-label":"Full reason","data-tip":n.hold_full||n.next}," ? ",8,xa)])):(l(),i(V,{key:1},[F(h(n.next),1)],64))]),O(Wt,{row:n},null,8,["row"]),o("td",$a,[O(de,{class:"table__ai",query:{ws:p(m).workspace.id,kind:"row",ref:n.row_id}},null,8,["query"])])]))),128))])])]),_:1})):(l(),i("p",ka,"Nothing is waiting on someone else."))]),_:1}))}}),Sa=j(Ca,[["__scopeId","data-v-a632447c"]]),Ta=(e,t)=>e.seen instanceof Set?e.seen.has(t):e.seen.includes(t),jt=(e,t)=>new Date(e.at).getTime()>(t.base||0)&&!Ta(t,e.id),Ma=(e,t)=>{const s=String(t||"").toLowerCase().split(/\s+/).filter(Boolean);if(!s.length)return!0;const a=[e.ref,e.key,e.title,e.kind,e.who,e.text,e.body].join(" ").toLowerCase();return s.every(n=>a.includes(n))},Aa=e=>e.key||e.ref||e.id,Ra=(e,t)=>{const s=new Map;for(const a of e){const n=Aa(a),r=s.get(n)||{id:n,items:[],newest:a.at,unread:0,title:""};s.set(n,r),r.items.push(a),r.title||(r.title=a.title||""),a.at>r.newest&&(r.newest=a.at),jt(a,t)&&(r.unread+=1)}return[...s.values()].sort((a,n)=>String(n.newest).localeCompare(String(a.newest)))},Ea=e=>new Set(e.filter(t=>t.group==="you"&&!t.handled).map(t=>t.key)),Oa=(e,t=2)=>{const s=[...new Set(e.map(n=>n.kind))],a=s.length-t;return s.slice(0,t).join(" · ")+(a>0?` +${a}`:"")},Ia=e=>/fail|changes/.test(e)?"bad":/approved|merged|passed/.test(e)?"ok":"",Da=e=>/comment|approved|changes|mentioned|review requested/.test(e.kind)&&String(e.body||"").trim()!=="",Pt=e=>e.ref!==e.key&&(e.key||e.title)||"",Ba=e=>[Pt(e),e.text===e.title?"":e.text].filter(Boolean).join(" · "),Va=e=>e.type==="github"&&e.label==="GitHub"?"GH":Bt(e.label),Ua={class:"feed-item__body"},Wa={class:"feed-item__top"},Na={key:0,class:"feed-item__who"},ja={key:1,class:"at-you"},Pa={class:"feed-item__right"},Fa={class:"timestamp feed-item__when"},za=["aria-label","aria-expanded"],qa={key:0,class:"feed-item__text"},Ya={class:"feed-item__full"},La={class:"feed-item__actions"},Ha={key:1,class:"feed-item__text"},Xa=W({__name:"FeedItem",props:{item:{},source:{},fresh:{type:Boolean},lit:{type:Boolean},expanded:{type:Boolean}},emits:["open","toggle","seen"],setup(e,{emit:t}){const s=e,a=t,n=g(()=>Va(s.source)),r=g(()=>Pt(s.item)),c=g(()=>Ba(s.item)),u=g(()=>Ia(s.item.kind)),v=g(()=>u.value||(s.source.type==="github"?"":"jira")),_=g(()=>Da(s.item)),y=g(()=>_.value&&s.expanded),A=g(()=>(ce.value,ne(s.item.at))),E=()=>{s.fresh&&a("seen",s.item.id)},R=()=>{a("toggle",s.item.id),E()};return(S,d)=>(l(),i("li",{class:U(["feed-item",{"feed-item--new":e.fresh,"feed-item--lit":e.lit,"feed-item--open":y.value}]),onClick:E},[o("span",{class:U(["feed-item__icon",p(he)("feed-item__icon",v.value)])},h(n.value),3),o("div",Ua,[o("div",Wa,[O(se,{text:e.item.ref,url:e.item.url},null,8,["text","url"]),o("span",{class:U(["feed-item__kind",{"feed-item__kind--bad":u.value==="bad"}])},h(e.item.kind),3),e.item.who?(l(),i("span",Na,h(e.item.who),1)):C("",!0),e.item.mention?(l(),i("span",ja,"@you")):C("",!0),o("span",Pa,[o("span",Fa,h(A.value),1),_.value?(l(),i("button",{key:0,type:"button",class:"feed-item__toggle","aria-label":y.value?"Collapse":"Expand","aria-expanded":y.value,onClick:K(R,["stop"])},null,8,za)):C("",!0)])]),y.value?(l(),i(V,{key:0},[r.value?(l(),i("span",qa,h(r.value),1)):C("",!0),o("div",Ya,h(e.item.body),1),o("div",La,[o("button",{type:"button",class:"btn btn--tonal",onClick:d[0]||(d[0]=K(k=>a("open",e.item),["stop"]))}," Open formatted "),O(de,{query:{ws:p(m).workspace.id,kind:"feed",ref:e.item.id}},null,8,["query"]),O(se,{text:"Open in "+e.source.label,url:e.item.url,class:"btn"},null,8,["text","url"])])],64)):c.value?(l(),i("span",Ha,h(c.value),1)):C("",!0)])],2))}}),ht=j(Xa,[["__scopeId","data-v-27e556e1"]]),Ka=Ye({source:"all",view:Te("wt-feed-view","ticket",{writeDefaults:!1}),query:"",openGroups:new Set}),Ga=()=>Ka,Ja={key:0,class:"feed__new-count"},Za={class:"feed__bar"},Qa={key:0,class:"alert alert--inline",role:"alert"},el={class:"feed__search"},tl={class:"feed__search-count"},sl={key:1,class:"empty"},nl={key:2,class:"feed__list"},ol=["title","onClick"],al=["aria-expanded","aria-label"],ll={class:"feed__group-text"},rl={class:"feed__group-key"},il={key:0,class:"feed__group-sum"},cl={class:"feed__group-meta"},dl={class:"feed__group-kinds"},ul={class:"timestamp feed__group-when"},pl={key:0,class:"feed__children"},_l=W({__name:"Feed",emits:["open"],setup(e,{emit:t}){const s=t,a=Ga(),n=[{id:"ticket",label:"By ticket"},{id:"flat",label:"Flat"}],r=g(()=>m.workspace.connectors||[]),c=g(()=>Object.fromEntries(r.value.map(x=>[x.id,x]))),u=x=>c.value[x]||{id:x,type:x,label:x},v=g(()=>r.value.length>1?[{id:"all",label:"All"}].concat(r.value.map(x=>({id:x.id,label:x.label}))):[]),_=g({get:()=>v.value.some(x=>x.id===a.source)?a.source:"all",set:x=>{a.source=x}}),y=g(()=>({base:m.marks.base,seen:new Set(m.marks.seen)})),A=x=>jt(x,y.value),E=g(()=>m.feed.filter(A).length),R=g(()=>m.feed.filter(x=>_.value==="all"||x.source===_.value)),S=g(()=>R.value.filter(x=>Ma(x,a.query)).slice(0,200)),d=g(()=>new Map(m.turn.map(x=>[x.key,x]))),k=g(()=>Ea(m.turn)),f=g(()=>(ce.value,Ra(S.value,y.value).map(x=>({...x,row:d.value.get(x.id),move:k.value.has(x.id),when:ne(x.newest),kinds:Oa(x.items),open:a.openGroups.has(x.id)||!!a.query})))),B=(x,Y)=>{x.has(Y)?x.delete(Y):x.add(Y)},z=x=>B(a.openGroups,x.id),L=x=>B(b.open,x),J=x=>ze({seen:[x]}).then(ie),ue=I("");Ze(()=>{ue.value=""});const Q=async()=>{ue.value=await ze({seen:m.feed.map(x=>x.id),base:Date.now()})};return(x,Y)=>(l(),q(Re,{id:"feed",title:"What changed",note:"Newest first, every source",tip:"Newest first: comments, reviews, merges and failed checks on your PRs, and ticket changes. Each item opens where it happened.",class:"feed",column:""},{head:te(()=>[E.value?(l(),i("span",Ja,h(E.value)+" new",1)):C("",!0)]),default:te(()=>[o("div",Za,[v.value.length?(l(),q(Se,{key:0,modelValue:_.value,"onUpdate:modelValue":Y[0]||(Y[0]=M=>_.value=M),options:v.value,label:"Feed source"},null,8,["modelValue","options"])):C("",!0),O(Se,{modelValue:p(a).view,"onUpdate:modelValue":Y[1]||(Y[1]=M=>p(a).view=M),options:n,label:"Feed view"},null,8,["modelValue"])]),ue.value?(l(),i("p",Qa,h(ue.value),1)):C("",!0),o("div",el,[Le(o("input",{"onUpdate:modelValue":Y[2]||(Y[2]=M=>p(a).query=M),class:"input feed__search-input",type:"search",placeholder:"Search the feed: key, author, words…","aria-label":"Search the feed",autocomplete:"off"},null,512),[[He,p(a).query,void 0,{trim:!0}]]),o("span",tl,h(p(a).query?S.value.length+" of "+R.value.length:""),1),o("button",{type:"button",class:"feed__mark-read",onClick:Q},"Mark all read")]),p(m).feed.length?(l(),i("ol",nl,[p(a).view==="ticket"?(l(!0),i(V,{key:0},N(f.value,M=>(l(),i("li",{key:M.id,class:U(["feed__group",{"feed__group--new":M.unread,"feed__group--open":M.open,"feed__group--move":M.move}])},[o("div",{class:"feed__group-head",title:M.move?"Your move on this ticket":void 0,onClick:Z=>z(M)},[o("button",{type:"button",class:"feed__group-caret","aria-expanded":M.open,"aria-label":"Collapse or expand "+M.id}," › ",8,al),o("div",ll,[o("div",rl,[O(se,{text:M.id,url:M.row?M.row.ticket_url:M.items[0].url,class:"ticket-key feed__group-ticket"},null,8,["text","url"]),M.row||M.title?(l(),i("span",il,h(M.row?M.row.summary:M.title),1)):C("",!0)]),o("div",cl,[o("span",{class:U(["feed__group-count",{"feed__group-count--new":M.unread}])},h(M.unread?M.unread+" new":M.items.length),3),o("span",dl,h(M.kinds),1),o("span",ul,h(M.when),1)])]),O(de,{class:"feed__group-copy",query:{ws:p(m).workspace.id,kind:"thread",ref:M.id}},null,8,["query"])],8,ol),M.open?(l(),i("ul",pl,[(l(!0),i(V,null,N(M.items,Z=>(l(),q(ht,{key:Z.id,item:Z,source:u(Z.source),fresh:A(Z),lit:!!M.unread,expanded:p(b).open.has(Z.id),onOpen:Y[3]||(Y[3]=Ee=>s("open",Ee)),onToggle:L,onSeen:J},null,8,["item","source","fresh","lit","expanded"]))),128))])):C("",!0)],2))),128)):(l(!0),i(V,{key:1},N(S.value,M=>(l(),q(ht,{key:M.id,item:M,source:u(M.source),fresh:A(M),expanded:p(b).open.has(M.id),onOpen:Y[4]||(Y[4]=Z=>s("open",Z)),onToggle:L,onSeen:J},null,8,["item","source","fresh","expanded"]))),128))])):(l(),i("p",sl," No changes yet. New comments, reviews and status changes show up here. "))]),_:1}))}}),hl=j(_l,[["__scopeId","data-v-d92a7c74"]]),fl={id:"first-run",class:"island first-run","aria-labelledby":"first-run-title"},vl={class:"first-run__text"},ml=W({__name:"FirstRun",setup(e){const t=()=>Ks("connectors");return(s,a)=>(l(),i("section",fl,[a[1]||(a[1]=o("h2",{id:"first-run-title",class:"first-run__title"}," Whose Turn watches your tickets and pull requests and shows what is waiting on you. ",-1)),o("p",vl,[o("b",null,h(p(m).workspace.name),1),a[0]||(a[0]=F(" has no sources yet, so there is nothing to watch. Connect a repository or a tracker. ",-1))]),o("div",{class:"first-run__actions"},[o("button",{type:"button",class:"btn btn--tonal",onClick:t},"Add a source")]),a[2]||(a[2]=o("p",{class:"first-run__text first-run__ai"},' Or ask Claude: "add my GitHub repository to Whose Turn." ',-1))]))}}),kl=j(ml,[["__scopeId","data-v-84359c2d"]]),yl=new RegExp("(`[^`]{1,500}`)|(\\*\\*[^*]{1,500}\\*\\*)|(\\[[^\\]]{1,300}\\]\\(https?:\\/\\/[^)\\s]{1,2000}\\))|(https?:\\/\\/[^\\s<>()]{1,2000})|(@[A-Za-z0-9-]+(?: [A-Z][a-z]+)?)|((?<![A-Za-z0-9])\\*[^*\\s][^*]{0,500}\\*(?![A-Za-z0-9])|(?<![A-Za-z0-9])_[^_\\s][^_]{0,500}_(?![A-Za-z0-9]))","g"),ft=(e,t)=>{const s=Ke(t);return s?{type:"link",text:e,href:s}:{type:"text",text:e}},gl=e=>{const t=e[0];if(e[1])return{type:"code",text:t.slice(1,-1)};if(e[2])return{type:"strong",text:t.slice(2,-2)};if(e[3]){const s=t.indexOf("](");return ft(t.slice(1,s),t.slice(s+2,-1))}return e[4]?ft(t,t):e[5]?{type:"mention",text:t}:{type:"em",text:t.slice(1,-1)}},ye=e=>{const t=new RegExp(yl),s=[];let a=0,n;for(;n=t.exec(e);)n.index>a&&s.push({type:"text",text:e.slice(a,n.index)}),s.push(gl(n)),a=n.index+n[0].length;return a<e.length&&s.push({type:"text",text:e.slice(a)}),s},bl=e=>{const t=String(e||"").replace(/<!--[\s\S]*?-->/g,"").split(`
|
|
2
|
+
`),s=[];let a=[],n=null;const r=()=>{a.length&&(s.push({type:"paragraph",lines:a.map(ye)}),a=[]),n=null};for(let c=0;c<t.length;c++){const u=t[c];if(/^\s*```/.test(u)){r();const A=[];for(c++;c<t.length&&!/^\s*```/.test(t[c]);c++)A.push(t[c]);s.push({type:"fence",text:A.join(`
|
|
3
|
+
`)});continue}const v=u.match(/^(#{1,6})\s+(.*)$/);if(v){r(),s.push({type:"heading",level:v[1].length<=2?4:5,inline:ye(v[2])});continue}const _=u.match(/^>\s?(.*)$/);if(_){r(),s.push({type:"quote",inline:ye(_[1])});continue}const y=u.match(/^\s*([-*+]|\d+[.)])\s+(.*)$/);if(y){const A=n;a.length&&(r(),n=A);const E=/\d/.test(y[1]),R=n,S=R&&R.ordered===E?R:{type:"list",ordered:E,items:[]};S!==R&&s.push(S),n=S,S.items.push(ye(y[2]));continue}if(!u.trim()){r();continue}n=null,a.push(u)}return r(),s},be=(e,t,s="")=>{const a=document.createElement(e);return a.textContent=t,s&&(a.className=s),a},wl=e=>{if(e.type==="text")return document.createTextNode(e.text);if(e.type==="link"){const t=be("a",e.text);return t.setAttribute("href",e.href),t.setAttribute("target","_blank"),t.setAttribute("rel","noopener"),t}return e.type==="mention"?be("span",e.text,"markdown-view__mention"):be(e.type,e.text)},Ft=(e,t)=>{e.forEach(s=>t.append(wl(s)))},Ve=(e,t)=>{const s=document.createElement(e);return Ft(t,s),s},xl=e=>{if(e.type==="fence"){const s=document.createElement("pre");return s.append(be("code",e.text)),s}if(e.type==="heading")return Ve(`h${e.level}`,e.inline);if(e.type==="quote")return Ve("blockquote",e.inline);if(e.type==="list"){const s=document.createElement(e.ordered?"ol":"ul");return e.items.forEach(a=>s.append(Ve("li",a))),s}const t=document.createElement("p");return e.lines.forEach((s,a)=>{a&&t.append(document.createElement("br")),Ft(s,t)}),t},$l=e=>{const t=document.createDocumentFragment();return bl(e).forEach(s=>t.append(xl(s))),t},Cl=W({__name:"MarkdownView",props:{source:{default:""}},setup(e){const t=e,s=I(null);return Jt(()=>{s.value&&s.value.replaceChildren($l(t.source))}),(a,n)=>(l(),i("div",{ref_key:"host",ref:s,class:"markdown-view"},null,512))}}),Sl=j(Cl,[["__scopeId","data-v-dcf42e95"]]),Tl={class:"modal__card"},Ml={class:"modal__head"},Al={id:"modal-title",class:"modal__title"},Rl=["href"],El=W({__name:"CommentModal",setup(e){const t=g(()=>b.modal),s=g(()=>t.value?[t.value.ref,t.value.kind,t.value.who].filter(Boolean).join(" · "):""),a=g(()=>t.value?Ke(t.value.url):""),n=g(()=>{var u;const c=(m.workspace.connectors||[]).find(v=>{var _;return v.id===((_=t.value)==null?void 0:_.source)});return"Open in "+(c?c.label:(u=t.value)==null?void 0:u.source)}),r=()=>{b.modal=null};return(c,u)=>t.value?(l(),i("div",{key:0,class:"modal",role:"dialog","aria-modal":"true","aria-labelledby":"modal-title",onClick:K(r,["self"])},[o("div",Tl,[o("div",Ml,[o("h3",Al,h(s.value),1),a.value?(l(),i("a",{key:0,class:"btn",href:a.value,target:"_blank",rel:"noopener"},h(n.value),9,Rl)):C("",!0),o("button",{type:"button",class:"btn btn--tonal",onClick:r},"Close")]),O(Sl,{source:t.value.body||t.value.text||""},null,8,["source"])])])):C("",!0)}}),Ol={class:"modal__card feedback-sheet__card"},Il={class:"modal__head"},Dl={class:"modal__meta"},Bl=["aria-disabled"],Vl={key:0,class:"alert"},Ul={class:"sheet-form"},Wl=["placeholder","onKeydown"],Nl={key:0,class:"feedback-sheet__note"},jl={key:1,class:"feedback-sheet__note"},Pl={key:2,class:"empty"},Fl=["href"],zl={key:3,class:"feedback-sheet__reports"},ql=["href"],Yl={class:"feedback-sheet__report-title"},Ll={class:"timestamp"},Hl=W({__name:"FeedbackSheet",setup(e){const t=I(""),s=I(null),a=I(!1),n=I([]),r=I(null),c=I(""),u=I(!0),v=Me("",1600),_=I([]),y=d=>"/report?id="+encodeURIComponent(d),A=()=>Ae("/api/feedback").then(d=>{u.value=d.configured,c.value=d.configured?"Linear · "+d.project:"not connected",_.value=d.reports||[]},()=>{n.value=[we+"; past reports cannot be loaded."]}),E=()=>{b.feedback=!1},R=()=>{const d=t.value.trim();if(!d){n.value=["Write at least one line."];return}n.value=[],navigator.clipboard.writeText(d).then(()=>{v.value="sent"},()=>{v.value="failed"})},S=()=>{if(!u.value||a.value)return;const d=t.value.trim();if(!d){n.value=["Write at least one line."];return}a.value=!0,ae("/api/feedback",{text:d,from:"the window",ws:m.workspace.id,kind_ref:{kind:"workspace",ref:m.workspace.id}}).then(k=>{if(a.value=!1,k.error){n.value=Ct(k.error);return}r.value=k.issue||null,t.value="",_.value=k.reports||_.value}).catch(k=>{a.value=!1,n.value=[oe(k,{refused:"Not sent",unreachable:je})]})};return X(()=>b.feedback,d=>{d&&(n.value=[],r.value=null,A().then(()=>mt(()=>{var k;return(k=s.value)==null?void 0:k.focus()})))}),(d,k)=>p(b).feedback?(l(),i("div",{key:0,class:"modal",role:"dialog","aria-modal":"true","aria-labelledby":"feedback-title",onClick:K(E,["self"])},[o("div",Ol,[o("div",Il,[k[1]||(k[1]=o("h3",{id:"feedback-title",class:"modal__title"},"To the Whose Turn backlog",-1)),o("span",Dl,h(c.value),1),o("button",{type:"button",class:"btn btn--tonal","aria-disabled":!u.value||a.value,onClick:S},h(a.value?"Composing…":"Send"),9,Bl),o("button",{type:"button",class:"btn",onClick:E},"Close")]),n.value.length?(l(),i("div",Vl,h(n.value.join(" · ")),1)):C("",!0),o("div",Ul,[Le(o("textarea",{ref_key:"field",ref:s,"onUpdate:modelValue":k[0]||(k[0]=f=>t.value=f),class:"input feedback-sheet__text",rows:"5",placeholder:"Describe the problem or the wish in your own words."+(u.value?" Cmd+Enter sends.":""),autocomplete:"off",onKeydown:[Ne(K(S,["meta","prevent"]),["enter"]),Ne(K(S,["ctrl","prevent"]),["enter"])]},null,40,Wl),[[He,t.value]]),u.value?(l(),i("p",jl," An assistant turns it into a proper issue (title, kind, description) and files it in the Whose Turn backlog with this workspace's summary attached. ")):(l(),i("p",Nl,[k[2]||(k[2]=F(" The maintainer's tracker is not connected on this machine, so nothing can be sent from here. Copy your remark and pass it on yourself. ",-1)),o("button",{type:"button",class:"btn",onClick:R},h(p(v)==="sent"?"Copied":p(v)==="failed"?"Could not copy":"Copy remark"),1)])),r.value?(l(),i("p",Pl,[k[3]||(k[3]=F(" Filed as ",-1)),o("a",{href:y(r.value.identifier),target:"_blank",rel:"noopener"},h(r.value.identifier),9,Fl),F(" · "+h(r.value.title),1)])):C("",!0),_.value.length?(l(),i("div",zl,[k[4]||(k[4]=o("h4",{class:"sheet-form__heading"},"Your reports",-1)),(l(!0),i(V,null,N(_.value,f=>(l(),i("div",{key:f.id,class:"feedback-sheet__report"},[o("a",{href:y(f.id),target:"_blank",rel:"noopener"},h(f.id),9,ql),o("span",Yl,h(f.title),1),o("span",{class:U(["pill",p(he)("pill",p(ws)(f.outcome))])},h(f.state||"filed"),3),o("span",Ll,h(p(ne)(f.changed_at||f.filed_at)),1)]))),128))])):C("",!0)])])])):C("",!0)}}),Xl=j(Hl,[["__scopeId","data-v-ec34adcc"]]),Kl={class:"field-row"},Gl={class:"field-row__label"},Jl={key:0,class:"field-row__check"},Zl=["checked"],Ql={key:2,class:"field-row__inline"},er=["value"],tr=["value"],sr=["value"],nr=["placeholder","value"],or={key:5,class:"field-row__hint"},ar=W({__name:"FieldRow",props:We({spec:{},placeholder:{default:""},hint:{default:""}},{modelValue:{type:[String,Array,Boolean]},modelModifiers:{}}),emits:We(["secret"],["update:modelValue"]),setup(e,{emit:t}){const s=e,a=t,n=vt(e,"modelValue"),r=/^#[0-9a-f]{6}$/i,c=()=>String(n.value??""),u=()=>n.value||[],v=R=>{n.value=R},_=()=>n.value??s.spec.default??!1,y=R=>{n.value=R===(s.spec.default??!1)?void 0:R},A=R=>R.target.value,E=R=>v(R.split(",").map(S=>S.trim()).filter(Boolean));return(R,S)=>(l(),i("div",Kl,[o("label",Gl,h(e.spec.label)+h(e.spec.required?" *":""),1),e.spec.boolean?(l(),i("label",Jl,[o("input",{type:"checkbox",checked:_(),onChange:S[0]||(S[0]=d=>y(d.target.checked))},null,40,Zl),F(" "+h(e.hint||e.spec.hint),1)])):e.spec.secret?(l(),i("input",{key:1,class:"input",type:"password",placeholder:"paste to replace",autocomplete:"off",onInput:S[1]||(S[1]=d=>a("secret",e.spec.key,A(d)))},null,32)):e.spec.colour?(l(),i("div",Ql,[o("input",{class:"input field-row__colour",type:"color",value:r.test(c())?c():"#888888",onInput:S[2]||(S[2]=d=>v(A(d)))},null,40,er),o("input",{class:"input",type:"text",placeholder:"#rrggbb",value:c(),onInput:S[3]||(S[3]=d=>v(A(d)))},null,40,tr),o("button",{type:"button",class:"btn",onClick:S[4]||(S[4]=d=>v(""))},"None")])):e.spec.list?(l(),i("input",{key:3,class:"input",type:"text",value:u().join(", "),onInput:S[5]||(S[5]=d=>E(A(d)))},null,40,sr)):(l(),i("input",{key:4,class:"input",type:"text",placeholder:e.placeholder,value:c(),onInput:S[6]||(S[6]=d=>v(A(d)))},null,40,nr)),!e.spec.boolean&&(e.hint||e.spec.hint)?(l(),i("small",or,h(e.hint||e.spec.hint),1)):C("",!0)]))}}),re=j(ar,[["__scopeId","data-v-2ba0ba86"]]),lr={class:"modal__card settings-sheet__card"},rr={class:"modal__head"},ir={class:"modal__meta"},cr={key:0,class:"settings-sheet__dirty"},dr={key:0,class:"settings-sheet__confirm",role:"alertdialog"},ur={class:"settings-sheet__confirm-text"},pr={key:1,class:"alert settings-sheet__alert",role:"alert"},_r={key:2,class:"alert settings-sheet__alert"},hr={key:3,class:"settings-sheet__body"},fr={class:"settings-sheet__list"},vr=["aria-current","onClick"],mr={class:"sheet-form"},kr={key:0,class:"empty"},yr={ref:"connectors-head",class:"sheet-form__heading"},gr={class:"settings-sheet__connector-head"},br={class:"settings-sheet__connector-name"},wr=["onClick"],xr={class:"settings-sheet__actions"},$r=["onClick"],Cr={key:0,class:"settings-sheet__rules"},Sr={class:"settings-sheet__rule-when"},Tr={class:"settings-sheet__rule-then"},Mr={key:1,class:"empty"},Ar=W({__name:"SettingsSheet",setup(e){const t=I([]),s=I(0),a=I([]),n=I({workspace:[],theme:[],rules:[],statuses:[]}),r=I(""),c=I([]),u=I({}),v=Zt("connectors-head"),_=new Map,y=I(0),A=I(""),E=I(null),R=I(""),S=g(()=>b.settings&&!R.value&&(y.value>0||ct(t.value)!==A.value)),d={key:"id",label:"Entry id"},k={key:"label",label:"Label"},f=g(()=>t.value[s.value]),B=g(()=>(f.value&&u.value[f.value.id]||[]).map(zs)),z=w=>a.value.find(T=>T.type===w.type)||{type:w.type,label:w.type,fields:[]},L=g(()=>t.value.map((w,T)=>({uid:it(w),label:w.name||w.id||"Workspace "+(T+1)}))),J=g(()=>{var w;return(((w=f.value)==null?void 0:w.connectors)||[]).map(T=>({entry:T,uid:it(T),spec:z(T)}))}),ue=w=>{var $;const T=($=m.workspaces.find(P=>P.id===w))==null?void 0:$.theme_seed;return T?`empty: ${T}, derived from the workspace id`:"empty derives one from the workspace id"},Q=(w,T)=>w[T],x=(w,T,$)=>{_.set(w,Object.assign(_.get(w)||{},{[T]:$})),y.value+=1},Y=()=>{t.value.push(lt({id:"new-"+(t.value.length+1),name:"New workspace"})),s.value=t.value.length-1},M=()=>{t.value.splice(s.value,1),s.value=Math.max(0,s.value-1)},Z=()=>{f.value&&(E.value={text:`Delete ${f.value.name||f.value.id}? Its to-dos and marks stay on disk.`,yes:"Delete",no:"Keep",run:M})},Ee=w=>{var T;return(T=f.value)==null?void 0:T.connectors.push({type:w.type})},zt=w=>{f.value&&(_.delete(f.value.connectors[w]),f.value.connectors.splice(w,1))},qt=w=>{if(!f.value)return;const T=z(f.value.connectors[w]).label;E.value={text:`Remove the ${T} connector from ${f.value.name||f.value.id}?`,yes:"Remove",no:"Keep",run:()=>zt(w)}},Yt=()=>Ae("/api/config").then(w=>{R.value="",t.value=(w.workspaces||[]).map(lt),a.value=w.connectors||[],n.value=w.fields,_.clear(),y.value=0,E.value=null,s.value=Math.max(0,t.value.findIndex(T=>T.id===m.workspace.id)),r.value=w.config_file||"",c.value=w.problems||[],u.value=w.tables||{},A.value=ct(t.value)}).catch(()=>{R.value=we+"; settings cannot be loaded."}).then(mt).then(()=>{var w;b.settingsAt==="connectors"&&((w=v.value)==null||w.scrollIntoView({block:"start"})),b.settingsAt=""}),Oe=()=>{b.settings=!1},et=()=>{E.value={text:"Discard changes?",yes:"Discard",no:"Keep editing",run:Oe}},tt=()=>S.value?et():Oe(),st=w=>{const T=E.value;E.value=null,w&&(T==null||T.run())},Lt=async()=>{try{const w=await ae("/api/config",{workspaces:t.value.map(T=>Bs(T)),secrets:Us(t.value,_)});if(w.error){c.value=Ct(w.error);return}Oe(),It()}catch(w){c.value=[oe(w,{unreachable:we+"; your changes are kept, save again."})]}};return X(S,w=>{b.settingsDirty=w},{immediate:!0}),X(()=>b.settingsAsk,w=>{w&&(b.settingsAsk=!1,et())}),X(()=>b.settings,w=>{w&&Yt()}),(w,T)=>p(b).settings?(l(),i("div",{key:0,class:"modal",role:"dialog","aria-modal":"true","aria-labelledby":"settings-title",onClick:K(tt,["self"])},[o("div",lr,[o("div",rr,[T[2]||(T[2]=o("h3",{id:"settings-title",class:"modal__title"},"Workspaces",-1)),o("span",ir,h(r.value),1),S.value?(l(),i("span",cr,"Unsaved changes")):C("",!0),R.value?C("",!0):(l(),i("button",{key:1,type:"button",class:"btn btn--tonal",onClick:Lt},"Save")),o("button",{type:"button",class:"btn",onClick:tt},"Close")]),E.value?(l(),i("div",dr,[o("span",ur,h(E.value.text),1),o("button",{type:"button",class:"btn btn--danger",onClick:T[0]||(T[0]=$=>st(!0))},h(E.value.yes),1),o("button",{type:"button",class:"btn",onClick:T[1]||(T[1]=$=>st(!1))},h(E.value.no),1)])):C("",!0),R.value?(l(),i("div",pr,h(R.value),1)):c.value.length?(l(),i("div",_r,h(c.value.join(" · ")),1)):C("",!0),R.value?C("",!0):(l(),i("div",hr,[o("ul",fr,[(l(!0),i(V,null,N(L.value,($,P)=>(l(),i("li",{key:$.uid},[o("button",{type:"button",class:"settings-sheet__workspace","aria-current":P===s.value,onClick:ve=>s.value=P},h($.label),9,vr)]))),128)),o("li",null,[o("button",{type:"button",class:"settings-sheet__workspace settings-sheet__workspace--add",onClick:Y}," + Add workspace ")])]),o("div",mr,[f.value?(l(),i(V,{key:1},[T[3]||(T[3]=o("h4",{class:"sheet-form__heading"},"Workspace",-1)),(l(!0),i(V,null,N(n.value.workspace,$=>(l(),q(re,{key:$.key,spec:$,"model-value":Q(f.value,$.key),"onUpdate:modelValue":P=>p(le)(f.value,$.key,P)},null,8,["spec","model-value","onUpdate:modelValue"]))),128)),T[4]||(T[4]=o("h4",{class:"sheet-form__heading"},"Theme",-1)),(l(!0),i(V,null,N(n.value.theme,$=>{var P;return l(),q(re,{key:$.key,spec:$,hint:$.key==="seed"&&!((P=f.value.theme)!=null&&P.seed)?ue(f.value.id):"","model-value":Q(f.value.theme,$.key),"onUpdate:modelValue":ve=>p(le)(f.value.theme,$.key,ve)},null,8,["spec","hint","model-value","onUpdate:modelValue"])}),128)),o("h4",yr,"Connectors",512),(l(!0),i(V,null,N(J.value,({entry:$,spec:P,uid:ve},Ht)=>(l(),i("div",{key:ve,class:"settings-sheet__connector"},[o("div",gr,[o("strong",br,h(P.label),1),o("button",{type:"button",class:"btn btn--danger",onClick:ee=>qt(Ht)}," Remove ",8,wr)]),O(re,{spec:d,placeholder:P.type,hint:"only needed when one type appears twice","model-value":Q($,"id"),"onUpdate:modelValue":ee=>p(le)($,"id",ee)},null,8,["placeholder","model-value","onUpdate:modelValue"]),O(re,{spec:k,placeholder:P.label,hint:"shown in the feed filter","model-value":Q($,"label"),"onUpdate:modelValue":ee=>p(le)($,"label",ee)},null,8,["placeholder","model-value","onUpdate:modelValue"]),(l(!0),i(V,null,N(P.fields,ee=>(l(),q(re,{key:ee.key,spec:ee,"model-value":Q($,ee.key),"onUpdate:modelValue":Ie=>p(le)($,ee.key,Ie),onSecret:(Ie,Xt)=>x($,Ie,Xt)},null,8,["spec","model-value","onUpdate:modelValue","onSecret"]))),128))]))),128)),o("div",xr,[(l(!0),i(V,null,N(a.value,$=>(l(),i("button",{key:$.type,type:"button",class:"btn",onClick:P=>Ee($)}," + "+h($.label),9,$r))),128))]),T[5]||(T[5]=o("h4",{class:"sheet-form__heading"},"Rules",-1)),(l(!0),i(V,null,N(n.value.rules,$=>(l(),q(re,{key:$.key,spec:$,"model-value":Q(f.value.rules,$.key),"onUpdate:modelValue":P=>p(le)(f.value.rules,$.key,P)},null,8,["spec","model-value","onUpdate:modelValue"]))),128)),(l(!0),i(V,null,N(n.value.statuses,$=>(l(),q(re,{key:$.key,spec:$,"model-value":Q(f.value.rules.statuses,$.key),"onUpdate:modelValue":P=>p(le)(f.value.rules.statuses,$.key,P)},null,8,["spec","model-value","onUpdate:modelValue"]))),128)),T[6]||(T[6]=o("h4",{class:"sheet-form__heading"},"Whose turn table",-1)),T[7]||(T[7]=o("p",{class:"settings-sheet__rules-note"}," The rows in force, first match wins. Read-only here: ask Claude to change rules.table through /api/config. ",-1)),B.value.length?(l(),i("ol",Cr,[(l(!0),i(V,null,N(B.value,($,P)=>(l(),i("li",{key:P,class:"settings-sheet__rule"},[o("span",Sr,h($.when),1),o("span",Tr,h($.then),1)]))),128))])):(l(),i("p",Mr,"Save the workspace to see its rows.")),o("div",{class:"settings-sheet__actions"},[o("button",{type:"button",class:"btn btn--danger",onClick:Z}," Delete workspace ")])],64)):(l(),i("p",kr,"No workspaces yet. Add one on the left."))])]))])])):C("",!0)}}),Rr=j(Ar,[["__scopeId","data-v-779d567d"]]),Er={class:"app__shell"},Or=["inert"],Ir={id:"wt",class:"dashboard dashboard--fit"},Dr=["inert"],Br={class:"dashboard__main"},Vr=W({__name:"App",setup(e){const t=g(()=>!!m.workspace.id&&!m.workspace.connectors.length),s=g(()=>Ot.value!==null);return X(dt,Os,{flush:"post"}),ps("Escape",Gs,{target:document}),Qt(()=>{Xs()}),(a,n)=>(l(),i("div",{class:"app",style:es(p(dt))},[O(xn,{inert:s.value,onSettings:n[0]||(n[0]=r=>p(b).settings=!0)},null,8,["inert"]),o("div",Er,[O(Fn,{inert:s.value,onReport:n[1]||(n[1]=r=>p(b).feedback=!0)},null,8,["inert"]),p(ut).length?(l(),i("div",{key:0,class:"alert",inert:s.value},h(p(ut).join(" · ")),9,Or)):C("",!0),o("div",Ir,[n[3]||(n[3]=o("canvas",{id:"backdrop",class:"dashboard__backdrop","aria-hidden":"true"},null,-1)),O(fo,{inert:s.value},null,8,["inert"]),t.value?(l(),q(kl,{key:0,inert:s.value},null,8,["inert"])):(l(),i("div",{key:1,class:"dashboard__layout",inert:s.value},[o("div",Br,[O(aa,{class:"dashboard__move"}),O(ma,{class:"dashboard__todo"}),O(Sa,{class:"dashboard__waiting"})]),O(hl,{class:"dashboard__feed",onOpen:n[2]||(n[2]=r=>p(b).modal=r)})],8,Dr)),O(Xl),O(Rr),O(El)])])],4))}}),Ur=j(Vr,[["__scopeId","data-v-f146b085"]]);ts(Ur).mount("#app");tn();Is();
|
package/dist/index.html
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
<title>Whose Turn</title>
|
|
7
7
|
<script src="/vendor/popper.min.js"></script>
|
|
8
8
|
<script src="/vendor/tippy-bundle.umd.min.js"></script>
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-D-P2XKhJ.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-DHr5RHTx.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/scheme-DJ3WNw60.js">
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/assets/bem-COKTjsky.js">
|
|
13
13
|
<link rel="stylesheet" crossorigin href="/assets/_plugin-vue_export-helper-BKveAJb2.css">
|
|
14
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
14
|
+
<link rel="stylesheet" crossorigin href="/assets/index-B23uRijc.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body class="page">
|
|
17
17
|
<div id="app" class="page__mount"></div>
|
package/lib/config.mjs
CHANGED
|
@@ -206,7 +206,7 @@ export const loadConfig = (env = process.env) => {
|
|
|
206
206
|
const raw = readJson(configFile);
|
|
207
207
|
const problems = [];
|
|
208
208
|
if (raw === null) {
|
|
209
|
-
problems.push(`No workspace config yet: open Settings (the gear) to add a source
|
|
209
|
+
problems.push(`No workspace config yet: open Settings (the gear) to add a source. It will be written to ${configFile}.`);
|
|
210
210
|
} else if (raw.parse_error) {
|
|
211
211
|
problems.push(`Cannot parse ${configFile}: ${raw.parse_error}`);
|
|
212
212
|
}
|
package/lib/facts.mjs
CHANGED
|
@@ -9,7 +9,7 @@ const CHAIN_GROUPS = ['backlog', 'passed', 'code_review', 'qa', 'on_hold'];
|
|
|
9
9
|
/** Every fact a table row may test or quote: its type, the closed values when there are any, and where it comes from. */
|
|
10
10
|
export const FACTS = {
|
|
11
11
|
connector: { type: 'string', from: 'the connector entry id the ticket came from' },
|
|
12
|
-
'ticket.key': { type: 'string', from: 'tracker connectors (jira, linear
|
|
12
|
+
'ticket.key': { type: 'string', from: 'tracker connectors (jira, linear)' },
|
|
13
13
|
'ticket.status': { type: 'string', values: 'status groups', from: 'the ticket status matched against rules.statuses; else todo, in_progress or done from the status category' },
|
|
14
14
|
'ticket.status_name': { type: 'string', from: 'the status as the tracker names it' },
|
|
15
15
|
'ticket.assignee': { type: 'string', from: '"me" when the ticket is on you, else the assignee name' },
|
package/lib/update.mjs
CHANGED
|
@@ -101,8 +101,9 @@ export const createUpdater = ({ http, dataDir, version, installed, notify, regis
|
|
|
101
101
|
return status();
|
|
102
102
|
};
|
|
103
103
|
|
|
104
|
+
// `--ignore-scripts`: the package declares no install scripts, so a release that gained one runs nothing on the user's machine.
|
|
104
105
|
const install = async () => {
|
|
105
|
-
const failure = await run(npm, ['install', '--prefix', join(dataDir, 'app'), '--no-audit', '--no-fund', '--no-save', `${PACKAGE}@${latest}`]);
|
|
106
|
+
const failure = await run(npm, ['install', '--prefix', join(dataDir, 'app'), '--no-audit', '--no-fund', '--no-save', '--ignore-scripts', `${PACKAGE}@${latest}`]);
|
|
106
107
|
if (failure) {
|
|
107
108
|
return move('failed', failure);
|
|
108
109
|
}
|
package/package.json
CHANGED
package/connectors/demo.mjs
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/** Demo connector: three invented projects with every state the rules know, timestamps relative to now, and a little life on later polls. No network. */
|
|
2
|
-
import { toIsoUtc } from '../lib/text.mjs';
|
|
3
|
-
|
|
4
|
-
export const id = 'demo';
|
|
5
|
-
export const label = 'Demo';
|
|
6
|
-
export const links = () => [{ label: 'Demo tracker', url: 'https://demo.example/' }];
|
|
7
|
-
export const fields = [
|
|
8
|
-
{ key: 'scenario', label: 'Scenario', hint: 'northwind, atlas or garden', required: true },
|
|
9
|
-
{ key: 'part', label: 'Part', hint: 'tickets (the tracker side), code (PRs and asks), or empty for both' },
|
|
10
|
-
];
|
|
11
|
-
|
|
12
|
-
const HOUR = 3600000;
|
|
13
|
-
let base = Date.now();
|
|
14
|
-
const ago = (hours) => toIsoUtc(base - hours * HOUR);
|
|
15
|
-
const SITE = 'https://demo.example/browse/';
|
|
16
|
-
const REPO = 'https://github.com/example/';
|
|
17
|
-
|
|
18
|
-
const ticket = (key, summary, status, category, assignee, hoursAgo, sinceHours, changedBy) => ({
|
|
19
|
-
key, summary, status, status_category: category, assignee, updated: ago(hoursAgo), url: `${SITE}${key}`,
|
|
20
|
-
status_change: sinceHours === undefined ? null : { since: ago(sinceHours), by: changedBy || assignee },
|
|
21
|
-
});
|
|
22
|
-
const comment = (id, key, hoursAgo, author, body) => ({ id, key, at: ago(hoursAgo), author, body, url: `${SITE}${key}?focusedCommentId=${id}` });
|
|
23
|
-
const pr = (number, key, title, repo, overrides = {}) => ({
|
|
24
|
-
pr: number, key, title, base: 'main', state: 'OPEN', review: '', checks: 'passing', merged_at: '', updated_at: ago(5), url: `${REPO}${repo}/pull/${number}`,
|
|
25
|
-
last_comment_by: '', last_comment_at: '', last_comment_url: '', last_comment: '', unanswered: false, ...overrides,
|
|
26
|
-
});
|
|
27
|
-
const activity = (hoursAgo, number, key, kind, who, repo, text, body) => ({ at: ago(hoursAgo), pr: `${repo}#${number}`, key, kind, who, url: `${REPO}${repo}/pull/${number}`, text, body: body || text });
|
|
28
|
-
const failedRun = (id, repo, workflow, hoursAgo, title) => ({
|
|
29
|
-
id, ref: `${repo}:${workflow}@main`, repo: `example/${repo}`, workflow, branch: 'main', failed: true, mine: true, actor: 'alex', title, url: `${REPO}${repo}/actions/runs/${id}`, at: ago(hoursAgo), streak: id,
|
|
30
|
-
});
|
|
31
|
-
const runActivity = (run) => ({ at: run.at, pr: run.ref, key: '', title: run.title, kind: 'check failed', who: run.workflow, url: run.url, text: `${run.workflow} on ${run.branch}`, body: '' });
|
|
32
|
-
const ask = (noteId, repo, number, title, key, kind, who, hoursAgo, text) => ({ id: `gha:${noteId}`, repo: `example/${repo}`, number, ref: `${repo}#${number}`, title, key, kind, who, at: ago(hoursAgo), url: `${REPO}${repo}/pull/${number}`, text, body: text });
|
|
33
|
-
|
|
34
|
-
const northwind = (polls) => {
|
|
35
|
-
const me = 'Alex Doe';
|
|
36
|
-
const tickets = [
|
|
37
|
-
ticket('NW-142', 'Rounds: due dates differ between locales', 'Passed', 'indeterminate', me, 1, 1, 'Sam Tester'),
|
|
38
|
-
ticket('NW-151', 'Export to CSV loses the header row on retry', 'In Progress', 'indeterminate', me, 3, 30),
|
|
39
|
-
ticket('NW-137', 'Login page: remember the last used organisation', polls >= 3 ? 'Ready for QA' : 'Code Review', 'indeterminate', polls >= 3 ? 'Sam Tester' : me, polls >= 3 ? 0.1 : 20, polls >= 3 ? 0.1 : 26, polls >= 3 ? me : undefined),
|
|
40
|
-
ticket('NW-171', 'Spike: search index on Postgres', 'In Progress', 'indeterminate', me, 9, 9),
|
|
41
|
-
ticket('NW-129', 'Audit log keeps the deleted user name', 'Ready for QA', 'indeterminate', 'Sam Tester', 30, 29, me),
|
|
42
|
-
ticket('NW-118', 'Nightly report email arrives twice', 'In QA', 'indeterminate', 'Sam Tester', 80, 79, me),
|
|
43
|
-
ticket('NW-104', 'Invoice PDF: wrong currency symbol for CHF', 'On Hold', 'indeterminate', me, 120, 118, 'Pat Owner'),
|
|
44
|
-
ticket('NW-160', 'Import wizard for legacy spreadsheets', 'Backlog', 'new', 'Unassigned', 200),
|
|
45
|
-
ticket('NW-099', 'Dashboard tiles: tooltip on hover', 'Done', 'done', me, 50),
|
|
46
|
-
ticket('NW-088', 'Rate limit on the search endpoint', 'Done', 'done', me, 140),
|
|
47
|
-
];
|
|
48
|
-
const comments = [
|
|
49
|
-
comment('c1', 'NW-142', 1, 'Sam Tester', 'Have tested this on staging and it is now QA passed. Please also test it in the customer org once merged.'),
|
|
50
|
-
comment('c2', 'NW-151', 4, 'Pat Owner', `@${me} can you confirm the retry keeps the original delimiter? The client asked twice.`),
|
|
51
|
-
comment('c3', 'NW-151', 6, me, '@Pat Owner yes, the delimiter comes from the first attempt; adding a test for it.'),
|
|
52
|
-
comment('c4', 'NW-151', 2, 'Pat Owner', `@${me} and one more: does it cover TSV as well?`),
|
|
53
|
-
comment('c5', 'NW-104', 118, 'Pat Owner', 'On hold: waiting for the vendor to confirm the CHF rounding rule, they promised an answer next week.'),
|
|
54
|
-
comment('c6', 'NW-104', 140, me, 'Reproduced with the sample invoice, fix is a one-liner once we know the rule.'),
|
|
55
|
-
comment('c7', 'NW-118', 70, 'Sam Tester', `@${me} fyi, moved to In QA, will run the nightly job twice tonight.`),
|
|
56
|
-
comment('c8', 'NW-129', 28, 'Automation for Jira', 'Transitioned by rule "Ready for QA when PR approved".'),
|
|
57
|
-
...(polls >= 3 ? [comment('c9', 'NW-137', 0.1, 'Sam Tester', `@${me} picked it up, first pass looks good, one question: should the choice survive logout?`)] : []),
|
|
58
|
-
];
|
|
59
|
-
const prs = [
|
|
60
|
-
pr(3978, 'NW-142', 'NW-142 fix week start per locale', 'northwind-web', { base: 'release/2.5', review: 'APPROVED', updated_at: ago(2), last_comment_by: 'Chris Reviewer', last_comment_at: ago(3), last_comment: 'Nice find on the locale changing the week start.', last_comment_url: `${REPO}northwind-web/pull/3978#issuecomment-1` }),
|
|
61
|
-
pr(3991, 'NW-151', 'NW-151 keep the header row on CSV retry', 'northwind-web', { checks: 'failing', updated_at: ago(1) }),
|
|
62
|
-
pr(3985, 'NW-137', 'NW-137 remember the last organisation on login', 'northwind-web', { review: polls >= 3 ? 'APPROVED' : 'CHANGES_REQUESTED', updated_at: ago(polls >= 3 ? 0.2 : 19), last_comment_by: 'Chris Reviewer', last_comment_at: ago(19), last_comment: 'Please do not store the org id in localStorage without a namespace.', last_comment_url: `${REPO}northwind-web/pull/3985#discussion_r1`, unanswered: polls < 3 }),
|
|
63
|
-
pr(3960, 'NW-129', 'NW-129 keep the user name in the audit log', 'northwind-web', { state: 'MERGED', merged_at: ago(31), updated_at: ago(31) }),
|
|
64
|
-
pr(3940, 'NW-099', 'NW-099 dashboard tile tooltips', 'northwind-web', { state: 'MERGED', merged_at: ago(52), updated_at: ago(52) }),
|
|
65
|
-
];
|
|
66
|
-
const acts = [
|
|
67
|
-
activity(1, 3991, 'NW-151', 'check failed', 'unit-tests', 'northwind-web', ''),
|
|
68
|
-
activity(3, 3978, 'NW-142', 'comment', 'Chris Reviewer', 'northwind-web', 'Nice find on the locale changing the week start.'),
|
|
69
|
-
activity(19, 3985, 'NW-137', 'changes requested', 'Chris Reviewer', 'northwind-web', 'Please do not store the org id in localStorage without a namespace.', 'Please do not store the org id in `localStorage` without a namespace.\n\nTwo tabs with two organisations would overwrite each other. A `nw:` prefix plus the user id is enough.'),
|
|
70
|
-
activity(31, 3960, 'NW-129', 'merged', '', 'northwind-web', ''),
|
|
71
|
-
activity(52, 3940, 'NW-099', 'merged', '', 'northwind-web', ''),
|
|
72
|
-
...(polls >= 3 ? [activity(0.2, 3985, 'NW-137', 'approved', 'Chris Reviewer', 'northwind-web', 'Namespace added, looks good now.')] : []),
|
|
73
|
-
];
|
|
74
|
-
const asks = [
|
|
75
|
-
ask('n1', 'northwind-api', 512, 'Paginate the audit endpoint', 'NW-133', 'review requested', 'Chris Reviewer', 7, 'Paginate the audit endpoint'),
|
|
76
|
-
ask('n2', 'northwind-infra', 77, 'Rotate the staging certificates', '', 'mentioned you', 'Pat Owner', 26, `@alex could you check whether the cron on staging still runs after the rotation?`),
|
|
77
|
-
];
|
|
78
|
-
const runs = [failedRun(9001, 'northwind-web', 'scout-publish', 0.5, 'Merge pull request #3940 from example/nw-099-tooltips')];
|
|
79
|
-
return { me, tickets, comments, prs, activity: [...acts, ...runs.map(runActivity)], asks, runs };
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
const atlas = (polls) => {
|
|
83
|
-
const me = 'Alex Doe';
|
|
84
|
-
const tickets = [
|
|
85
|
-
ticket('ATL-77', 'Offline mode: queue edits made without network', 'In Review', 'indeterminate', me, 10, 12),
|
|
86
|
-
ticket('ATL-81', 'Crash on rotating the map while loading', 'Testing', 'indeterminate', 'Jo Qa', 40, 36, me),
|
|
87
|
-
ticket('ATL-64', 'Dark theme for the trip summary', 'Blocked', 'indeterminate', me, 90, 88, 'Dana Lead'),
|
|
88
|
-
ticket('ATL-85', 'Accessibility labels on the bottom bar', 'Todo', 'indeterminate', me, 5),
|
|
89
|
-
ticket('ATL-59', 'Share a trip as a link', 'Done', 'done', me, 100),
|
|
90
|
-
ticket('ATL-90', 'Replace the deprecated map SDK', 'Backlog', 'new', 'Dana Lead', 300),
|
|
91
|
-
];
|
|
92
|
-
const comments = [
|
|
93
|
-
comment('a1', 'ATL-64', 88, 'Dana Lead', 'Blocked until design delivers the dark palette, see the Figma thread.'),
|
|
94
|
-
comment('a2', 'ATL-77', 9, 'Dana Lead', `@${me} please add a screenshot of the queue indicator to the PR description`),
|
|
95
|
-
comment('a3', 'ATL-81', 35, 'Jo Qa', 'Testing on the three devices now.'),
|
|
96
|
-
...(polls >= 4 ? [comment('a4', 'ATL-81', 0.1, 'Jo Qa', `@${me} reproduced once more on the small device, log attached, can you have a look?`)] : []),
|
|
97
|
-
];
|
|
98
|
-
const prs = [
|
|
99
|
-
pr(214, 'ATL-77', 'ATL-77 offline edit queue', 'atlas-mobile', { base: 'develop', updated_at: ago(9), last_comment_by: 'Dana Lead', last_comment_at: ago(9), last_comment: 'please add a screenshot of the queue indicator', last_comment_url: `${REPO}atlas-mobile/pull/214#issuecomment-3`, unanswered: true }),
|
|
100
|
-
pr(209, 'ATL-81', 'ATL-81 guard the map rotation during load', 'atlas-mobile', { base: 'develop', state: 'MERGED', merged_at: ago(41), updated_at: ago(41) }),
|
|
101
|
-
pr(198, 'ATL-59', 'ATL-59 share trip link', 'atlas-mobile', { base: 'develop', state: 'MERGED', merged_at: ago(101), updated_at: ago(101) }),
|
|
102
|
-
];
|
|
103
|
-
const acts = [
|
|
104
|
-
activity(9, 214, 'ATL-77', 'comment', 'Dana Lead', 'atlas-mobile', 'please add a screenshot of the queue indicator'),
|
|
105
|
-
activity(41, 209, 'ATL-81', 'merged', '', 'atlas-mobile', ''),
|
|
106
|
-
activity(101, 198, 'ATL-59', 'merged', '', 'atlas-mobile', ''),
|
|
107
|
-
];
|
|
108
|
-
return { me, tickets, comments, prs, activity: acts, asks: [] };
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const garden = () => {
|
|
112
|
-
const me = 'alex';
|
|
113
|
-
const prs = [
|
|
114
|
-
pr(12, '', 'Water schedule: skip rainy days', 'garden-bot', { updated_at: ago(2), checks: 'running' }),
|
|
115
|
-
pr(11, '', 'Soil sensor calibration', 'garden-bot', { state: 'MERGED', merged_at: ago(30), updated_at: ago(30) }),
|
|
116
|
-
pr(9, '', 'Add the greenhouse zone', 'garden-bot', { state: 'MERGED', merged_at: ago(120), updated_at: ago(120) }),
|
|
117
|
-
];
|
|
118
|
-
const acts = [
|
|
119
|
-
activity(2, 12, '', 'comment', 'you', 'garden-bot', 'Rebased on the sensor change.'),
|
|
120
|
-
activity(30, 11, '', 'merged', '', 'garden-bot', ''),
|
|
121
|
-
activity(120, 9, '', 'merged', '', 'garden-bot', ''),
|
|
122
|
-
];
|
|
123
|
-
return { me, tickets: [], comments: [], prs, activity: acts, asks: [ask('g1', 'garden-bot', 13, 'Frost warning notifications', '', 'review requested', 'Sam Friend', 4, 'Frost warning notifications')] };
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const SCENARIOS = { northwind, atlas, garden };
|
|
127
|
-
|
|
128
|
-
export const poll = async ({ settings, cache }) => {
|
|
129
|
-
const scenario = SCENARIOS[settings.scenario];
|
|
130
|
-
if (!scenario) {
|
|
131
|
-
throw new Error(`Unknown demo scenario "${settings.scenario}"; use northwind, atlas or garden`);
|
|
132
|
-
}
|
|
133
|
-
cache.polls = (cache.polls || 0) + 1;
|
|
134
|
-
cache.base = cache.base || Date.now();
|
|
135
|
-
base = cache.base;
|
|
136
|
-
const scenarioData = scenario(cache.polls);
|
|
137
|
-
const titles = new Map(scenarioData.prs.map((entry) => [entry.url, entry.title]));
|
|
138
|
-
const data = { runs: [], ...scenarioData, activity: scenarioData.activity.map((item) => ({ ...item, title: item.title || titles.get(item.url) || '' })) };
|
|
139
|
-
if (settings.part === 'tickets') {
|
|
140
|
-
return { me: data.me, tickets: data.tickets, comments: data.comments, ticket_base: SITE, errors: {} };
|
|
141
|
-
}
|
|
142
|
-
if (settings.part === 'code') {
|
|
143
|
-
return { me: data.me, prs: data.prs, activity: data.activity, asks: data.asks, runs: data.runs, errors: {} };
|
|
144
|
-
}
|
|
145
|
-
return { ...data, ticket_base: SITE, errors: {} };
|
|
146
|
-
};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{w as X,t as Ye,r as Le,s as Jt,c as g,d as U,o as r,a as i,F as V,b as N,e as K,u as p,n as W,f as o,g as h,h as C,i as D,_ as j,j as F,k as O,l as q,m as Ue,p as mt,q as Ne,v as te,x as Zt,y as He,z as je,A as Xe,B as Qt,C as kt,D as es,E as ts,G as ss,H as ns}from"./_plugin-vue_export-helper-DHr5RHTx.js";import{s as os,m as yt,u as gt,a as bt,r as wt,p as as,b as ls,i as ot,l as $t,c as rs,M as G,d as be,e as ke,f as is,g as Ke,h as Me,j as cs,k as Ae,n as ds,o as us,q as ps,t as _s,v as at,w as hs}from"./scheme-DJ3WNw60.js";import{g as he,r as fs,a as vs,e as ms,w as xt,p as oe,b as le,T as Pe,S as $e,c as ae,h as ks,s as Ge,m as fe,d as ys,f as Ct,i as Je,j as gs,k as Ze,l as bs,y as ws,n as $s,o as xs,q as St}from"./bem-COKTjsky.js";const pe=os(wt),lt=(e,t)=>{const s=G,a=new Float32Array(s*s);for(let l=0;l<a.length;l+=1)a[l]=e[l]===t?1e6:0;const n=(l,c,u)=>{a[c]+u<a[l]&&(a[l]=a[c]+u)};for(let l=0;l<s;l+=1)for(let c=0;c<s;c+=1){const u=l*s+c;c>0&&n(u,u-1,1),l>0&&n(u,u-s,1),c>0&&l>0&&n(u,u-s-1,Math.SQRT2),c<s-1&&l>0&&n(u,u-s+1,Math.SQRT2)}for(let l=s-1;l>=0;l-=1)for(let c=s-1;c>=0;c-=1){const u=l*s+c;c<s-1&&n(u,u+1,1),l<s-1&&n(u,u+s,1),c<s-1&&l<s-1&&n(u,u+s+1,Math.SQRT2),c>0&&l<s-1&&n(u,u+s-1,Math.SQRT2)}return a},Ie=e=>{const t=String(e||"").trim(),s=/^#([0-9a-f]{6})$/i.exec(t);if(s)return[0,2,4].map(n=>parseInt(s[1].slice(n,n+2),16));const a=t.match(/[\d.]+/g);return a&&a.length>=3?a.slice(0,3).map(Number):null},Cs=e=>{const t=getComputedStyle(e),s=Ie(t.getPropertyValue("--md-primary"))||[44,86,151],a=Ie(t.getPropertyValue("--md-on-primary-container"))||s;return{core:ot()?s:s.map((n,l)=>$t(n,a[l],.35)),rim:Ie(t.getPropertyValue("--blob-3"))||[23,223,220],strength:ot()?.9:1}},Ss=(e,t,s)=>({size:e.range(.85,1.05)*Math.min(t,s),right:e.chance(.4),bottom:e.chance(.7),overflowX:e.range(-.02,.06),overflowY:e.range(-.02,.04)}),Ts=e=>{const t={minX:G,maxX:0,minY:G,maxY:0};for(let a=0;a<e.length;a+=1)if(e[a]){const n=a%G,l=Math.floor(a/G);t.minX=Math.min(t.minX,n),t.maxX=Math.max(t.maxX,n),t.minY=Math.min(t.minY,l),t.maxY=Math.max(t.maxY,l)}const s=a=>(a-G/2)/be;return{minX:s(t.minX),maxX:s(t.maxX),minY:s(t.minY),maxY:s(t.maxY)}},Ms=(e,t,s,a)=>{const n=t.maxX-t.minX,l=t.maxY-t.minY,c=Math.min(e.size,2*s*.95/n,2*a*.98/l),u=c/2,v=-e.overflowX*c,_=-e.overflowY*c;return{size:c,centerX:e.right?s-v-t.maxX*u:v-t.minX*u,centerY:e.bottom?a-_-t.maxY*u:_-t.minY*u}},As=(e,t,s)=>"rgba("+e.core.map((n,l)=>Math.round($t(n,e.rim[l],t))).join(",")+","+s.toFixed(3)+")",Rs=(e,t,s)=>{const a=[],n=t.size/62,l=t.size/2/be,c=t.size*is/4,u=n*.866;for(let v=0,_=t.centerY-c;_<t.centerY+c;v+=1,_+=u)for(let y=t.centerX-c+v%2*n/2;y<t.centerX+c;y+=n){const A=y+e.range(-.3,.3)*n,E=_+e.range(-.3,.3)*n,R=Math.floor((A-t.centerX)/l+G/2),S=Math.floor((E-t.centerY)/l+G/2);if(R<0||S<0||R>=G||S>=G)continue;const d=S*G+R,k=e.next(),f=e.range(.75,1.25),B=e.range(-.15,.15);if(s.inside[d]){const z=s.depth[d]/be,L=ke(z/.035),J=ke(z/.3);if(k>.5+.5*L)continue;a.push({x:A,y:E,radius:n*.5*(.45+.55*L)*(.95+.3*J)*f,alpha:.5+.25*L+.25*J,tint:ke(.65-.65*J+B)})}else{const z=s.gap[d]/be;if(k>.14*Math.exp(-z/.05)+.004)continue;a.push({x:A,y:E,radius:n*e.range(.1,.24),alpha:.35,tint:ke(.8+B)})}}return a},Es=()=>document.getElementById("wt"),Os=()=>document.getElementById("backdrop"),Tt=()=>Math.floor(Math.random()*4294967296),ye={},I={workspace:"",seed:Tt(),species:"",wantedSpecies:"",wantedPose:"",built:null},Ds=(e,t)=>{const s=rs(I.seed),a=pe[Math.floor(s.next()*pe.length)];I.species=pe.includes(I.wantedSpecies)?I.wantedSpecies:a;const n=Ss(s,e,t),l={facing:n.right?-1:1,tilt:s.range(-.07,.07),stretchX:s.range(.92,1.08),stretchY:s.range(.92,1.08)};s.chance(.25)&&(l.facing=-l.facing);const c=as(ls(wt,I.species,s,{pose:I.wantedPose}).shapes,l),u={inside:c,depth:lt(c,1),gap:lt(c,0)},v=Ms(n,Ts(c),e,t);return{key:I.seed+":"+I.species+":"+e+"x"+t,dots:Rs(s,v,u)}},xe=()=>{const e=Os();if(!e)return;const t=e.clientWidth,s=e.clientHeight,a=window.devicePixelRatio||1,n=Math.round(t*a),l=Math.round(s*a);(e.width!==n||e.height!==l)&&(e.width=n,e.height=l);const c=e.getContext("2d");if(!c||(c.setTransform(a,0,0,a,0,0),c.clearRect(0,0,t,s),!t||!s))return;const u=I.seed+":"+(I.wantedSpecies||"?")+":"+t+"x"+s;(!I.built||I.built.key.split(":")[0]!==String(I.seed)||!I.built.key.endsWith(t+"x"+s)||I.wantedSpecies&&I.species!==I.wantedSpecies)&&(I.built=Ds(t,s));const v=Es();if(!v)return u;const _=Cs(v);return I.built.dots.forEach(y=>{c.fillStyle=As(_,y.tint,y.alpha*_.strength),c.beginPath(),c.arc(y.x,y.y,y.radius,0,Math.PI*2),c.fill()}),u};window.whoseTurnBackdrop={species:pe.slice(),seeded:yt,get current(){return{workspace:I.workspace,species:I.species,seed:I.seed}},show:e=>{const t=e||{},s=String(t.workspace||"");ye[s]||(ye[s]=Tt());const a=t.seed!==void 0?Number(t.seed)>>>0:ye[s];ye[s]=a;const n=t.species&&pe.includes(t.species)?t.species:"",l=String(t.pose||"");return s===I.workspace&&a===I.seed&&n===I.wantedSpecies&&l===I.wantedPose&&I.built||(I.workspace=s,I.seed=a,I.wantedSpecies=n,I.wantedPose=l,I.built=null,xe()),window.whoseTurnBackdrop.current},repaint:xe};X(Ke,xe);gt(window,"resize",bt(xe,200));const{show:Mt,repaint:Is,seeded:Yr}=window.whoseTurnBackdrop,Bs=()=>{window.tippy&&window.tippy.delegate(document.body,{target:"[data-tip]",content:e=>e.dataset.tip||"",trigger:"mouseenter focus click",delay:[0,80],duration:[120,80],interactive:!0,maxWidth:440,placement:"top",theme:"wt",appendTo:()=>document.body})},Vs=()=>{let e=0;return{next:()=>++e,accepts:t=>t===e}},rt=e=>{const t=structuredClone(Ye(e)),s=t.connectors||{},a=t.rules||{};return a.statuses=a.statuses||{},{...t,connectors:Array.isArray(s)?s:Object.entries(s).map(([n,l])=>({type:n,...l})),rules:a,theme:t.theme||{}}},Ws=e=>{const t=structuredClone(Ye(e));return t.theme&&!Object.keys(t.theme).length&&delete t.theme,t.rules&&!Object.keys(t.rules.statuses||{}).length&&delete t.rules.statuses,t.rules&&!Object.keys(t.rules).length&&delete t.rules,t},it=new WeakMap;let Us=0;const ct=e=>{const t=Ye(e);let s=it.get(t);return s||(s=++Us,it.set(t,s)),s},dt=e=>JSON.stringify(e),Ns=(e,t)=>{const s=[];return e.forEach(a=>a.connectors.forEach(n=>{const l=t.get(n)||{};Object.keys(l).forEach(c=>{l[c]&&s.push({ws:a.id,connector:n.id||n.type,key:c,value:l[c]})})})),s},re=(e,t,s)=>{typeof s=="boolean"||s&&s.length?e[t]=s:delete e[t]},js=(e,t)=>{const s=a=>{const n=t.indexOf(a.id);return n<0?t.length:n};return[...e].sort((a,n)=>s(a)-s(n))},Ps=(e,t,s,a)=>{const n=e.filter(l=>l!==t);return n.splice(n.indexOf(s)+(a?0:1),0,t),n},Fs={gt:">",gte:"≥",lt:"<",lte:"≤",prefix:"starts with"},zs=(e,t)=>`${e} is ${t?"present":"absent"}`,qs=(e,t)=>Array.isArray(t)?`${e} in ${t.join(", ")}`:t&&typeof t=="object"?Object.entries(t).map(([s,a])=>s==="present"?zs(e,a):`${e} ${Fs[s]} ${JSON.stringify(a)}`).join(" and "):`${e} = ${t}`,Ys=e=>({when:Object.entries(e.when).map(([t,s])=>qs(t,s)).join(" and ")||"anything else",then:e.then.whose==="hidden"?"hidden":`${e.then.whose}: ${e.then.next}`}),Ls=e=>e.modal?"modal":e.settings?"settings":e.feedback?"feedback":null,Hs=(e,t)=>{const s=new URLSearchParams(e).get("mode");return s==="app"||s==="tab"?s:t==="app"?"app":"tab"},Xs=e=>"/?mode=tab"+(e?"&ws="+encodeURIComponent(e):""),Ks=e=>({width:e.outerWidth,height:e.outerHeight}),At={writeDefaults:!1},Rt=Me("wt-ws","",At),Et=cs("wt-mode","",At),m=Jt({workspaces:[],workspace:{id:"",name:"",connectors:[],links:[],key_pattern:"",theme:null},turn:[],feed:[],marks:{seen:[],base:0,handled:{}},counts:{mine:0,others:0,failing:0,done:0},todos:[],errors:{},health:{ok:!0,stale:!1,fresh_at:"",failing:[],alerts:[]},problems:[],polled_at:"",update:{current:"",latest:"",available:!1,state:"idle"}}),b=Le({ws:new URLSearchParams(location.search).get("ws")||Rt.value,open:new Set,mode:Hs(location.search,Et.value),live:!1,reconnects:0,status:"Connecting…",modal:null,feedback:!1,settings:!1,settingsDirty:!1,settingsAsk:!1,settingsAt:""});Et.value=b.mode;const Ce=Ae("",6e3),se=(e,t)=>{const s=le(e,t);return s&&(Ce.value=s),!s},Gs=()=>{b.mode==="app"&>(window,"resize",bt(()=>oe("/api/window",Ks(window)).catch(se),600))},Ot={resume:()=>{}},ce=us({scheduler:e=>{const t=ps(e,3e4,{immediate:!1});return Ot.resume=t.resume,t}}),ut=g(()=>{const e=m.workspace.theme;return e&&e.light&&e.dark?e[Ke.value?"dark":"light"]:{}}),H=g(()=>m.counts),pt=g(()=>[...m.problems||[],...m.health.alerts.map(e=>e.text),...Object.entries(m.errors||{}).map(([e,t])=>e+": "+t)]),Js=(e="")=>{b.settingsAt=e,b.settings=!0},Dt=g(()=>Ls(b)),Zs=()=>{const e=Dt.value;if(e==="modal"&&(b.modal=null),e==="feedback"&&(b.feedback=!1),e==="settings"){if(b.settingsDirty){b.settingsAsk=!0;return}b.settings=!1}},Fe=new Map,Qs=(e,t)=>{t&&Fe.set(e,document.activeElement)},en=(e,t)=>{if(t)return;const s=Fe.get(e);Fe.delete(e),s instanceof HTMLElement&&s.focus()},tn={modal:()=>!!b.modal,settings:()=>b.settings,feedback:()=>b.feedback};Object.entries(tn).forEach(([e,t])=>{X(t,s=>Qs(e,s),{flush:"sync"}),X(t,s=>en(e,s),{flush:"post"})});let Se=-1,ze=0;const _t=Vs(),ve=(e=b.ws)=>{const t=_t.next();return he("/api/state"+(e?"?ws="+encodeURIComponent(e):"")).then(s=>_t.accepts(t)?s.error?fs(s.error)!=="NO_SUCH_WORKSPACE"||!vs(e)?(b.status=ms(s.error,"Could not load"),m):ve(""):(Object.assign(m,s),b.ws=m.workspace.id,b.status="",Mt({workspace:m.workspace.id}),document.title="Whose Turn · "+m.workspace.name,m):m)},It=()=>(Se=-1,ve()),_e=ds("/api/stream",[],{immediate:!1,autoConnect:!1,autoReconnect:!0,serializer:{read:e=>JSON.parse(e||"null")}});X(_e.status,e=>{b.live=e==="OPEN",b.live&&(b.status="",b.reconnects++)},{flush:"sync"});X(_e.error,e=>{e&&(b.status="Disconnected from the local server, retrying…")},{flush:"sync"});X(_e.data,e=>{if(e){if("update"in e){m.update=e.update;return}typeof e.open_moves=="number"&&(m.workspaces=xt(m.workspaces,e.ws,e.open_moves)),!(m.workspace.id&&e.ws!==m.workspace.id)&&(b.status="",e.version!==Se?(Se=e.version,ze===0&&ve()):m.polled_at=e.polled_at)}},{flush:"sync"});const sn=()=>{_e.eventSource.value||_e.open()},nn=()=>(Ot.resume(),ve().then(sn)),Bt=e=>e===m.workspace.id?Promise.resolve():(Se=-1,ze++,ve(e).then(()=>{b.ws===e&&(Rt.value=b.ws,b.open.clear())},()=>{Ce.value=$e+"; staying on "+m.workspace.name+"."}).finally(()=>{ze--})),Vt=(e,t)=>oe(e,{ws:m.workspace.id,...t}),qe=e=>Vt("/api/marks",e).then(t=>{const s=le(t);return s||(Object.assign(m,{marks:t.marks,turn:t.turn,counts:t.counts}),m.workspaces=xt(m.workspaces,m.workspace.id,t.counts.mine)),s},t=>le(t)),on=e=>Vt("/api/todos",e).then(t=>{const s=le(t,{unreachable:Pe});return!s&&Array.isArray(t)&&(m.todos=t),s},t=>le(t,{unreachable:Pe})),an=e=>he("/api/config").then(t=>oe("/api/config",{workspaces:js(t.workspaces,e),secrets:[]})).then(t=>{se(t,{refused:"The order was not saved"})&&It()},t=>se(t,{refused:"The order was not saved"})),Be={id:"demo",name:"Demo",key_pattern:"\\bNW-\\d+\\b",theme:{seed:"#3d7a5c",accent:"#c27a2c"},connectors:[{type:"demo",scenario:"northwind",label:"Demo tracker"}]},ln=()=>he("/api/config").then(e=>e.workspaces.some(t=>t.id===Be.id)?null:oe("/api/config",{workspaces:[...e.workspaces,Be],secrets:[]})).then(e=>{if(se(e,{refused:"The demo workspace was not added"}))return Bt(Be.id)},e=>se(e,{refused:"The demo workspace was not added"})),ht=()=>{b.status="Checking now…",oe("/api/refresh").catch(e=>{b.status="",se(e)}),Mt({workspace:m.workspace.id,seed:Math.floor(Math.random()*4294967296)})},rn="M12 2.5l1.9 5.6 5.6 1.9-5.6 1.9L12 17.5l-1.9-5.6L4.5 10l5.6-1.9L12 2.5zM5 15l.9 2.6 2.6.9-2.6.9L5 22l-.9-2.6-2.6-.9 2.6-.9L5 15zm14-2l.7 2 2 .7-2 .7-.7 2-.7-2-2-.7 2-.7.7-2z",cn="M19.4 13a7.6 7.6 0 0 0 0-2l2-1.5-2-3.4-2.4 1a7.5 7.5 0 0 0-1.7-1L15 3.5H9l-.3 2.6a7.5 7.5 0 0 0-1.7 1l-2.4-1-2 3.4 2 1.5a7.6 7.6 0 0 0 0 2l-2 1.5 2 3.4 2.4-1a7.5 7.5 0 0 0 1.7 1l.3 2.6h6l.3-2.6a7.5 7.5 0 0 0 1.7-1l2.4 1 2-3.4-2-1.5zM12 15.5a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7z",dn="M19 8h-1.8a5.9 5.9 0 0 0-1.3-1.9l1.6-1.6-1.4-1.4-1.9 1.9A5.7 5.7 0 0 0 12 4.5a5.7 5.7 0 0 0-2.2.5L7.9 3.1 6.5 4.5l1.6 1.6A5.9 5.9 0 0 0 6.8 8H5v2h1.2a7 7 0 0 0 0 1v1H5v2h1.3a6 6 0 0 0 11.4 0H19v-2h-1.2v-1a7 7 0 0 0 0-1H19V8zm-7 10a4 4 0 0 1-4-4v-3a4 4 0 0 1 8 0v3a4 4 0 0 1-4 4zm-1-7h2v5h-2z",un=e=>{let t=2166136261;for(let s=0;s<e.length;s+=1)t^=e.charCodeAt(s),t=Math.imul(t,16777619);return t>>>0},Wt=e=>{const t=String(e||"").trim().split(/[\s_-]+/).filter(Boolean);return(t.length>=2?t.slice(0,3).map(a=>a.charAt(0)):(t[0]||"?").slice(0,2).split("")).join("").toUpperCase()},pn=e=>({1:17,2:14,3:11})[e.length]||11,_n=(e,t)=>{const s=t(un(e.id)),a=[],n=3+Math.floor(s()*3);for(let c=0;c<n;c+=1){const u=s()*Math.PI*2,v=9+s()*7;a.push({cx:(18+Math.cos(u)*v).toFixed(1),cy:(18+Math.sin(u)*v).toFixed(1),r:(1.6+s()*2.2).toFixed(1),opacity:(.35+s()*.4).toFixed(2)})}const l=Wt(e.name||e.id);return{dots:a,glyph:l,fontSize:pn(l)}},hn={class:"rail","aria-label":"Workspaces"},fn=["data-drop","href","aria-label","aria-selected","onClick","onDragstart","onDragover","onDrop"],vn={viewBox:"0 0 36 36",class:"rail__icon","aria-hidden":"true"},mn=["fill"],kn=["cx","cy","r","fill","opacity"],yn=["y","font-size","fill"],gn={class:"rail__label"},bn={key:0,class:"rail__badge"},wn={viewBox:"0 0 24 24",class:"rail__gear","aria-hidden":"true"},$n=["d"],xn=U({__name:"Rail",emits:["settings"],setup(e,{emit:t}){const s=t,a=g(()=>Object.fromEntries(m.workspaces.map(d=>[d.id,_n(d,yt)]))),n=g(()=>Object.fromEntries(m.workspaces.map(d=>{const k=d.theme?d.theme[Ke.value?"dark":"light"]:null;return[d.id,{fill:k?k["--md-primary-container"]:"var(--md-primary-container)",ink:k?k["--md-on-primary-container"]:"var(--md-on-primary-container)",dot:k?k["--md-primary"]:"var(--md-primary)"}]}))),l=d=>{d.detail>0&&d.currentTarget.blur()},c=(d,k)=>{l(d),Bt(k)},u=d=>{s("settings"),l(d)},v=D(""),_=D({}),y=d=>{const k=d.currentTarget;return d.clientY-k.getBoundingClientRect().top<k.offsetHeight/2},A=(d,k)=>{v.value=k.id,d.dataTransfer&&(d.dataTransfer.effectAllowed="move",d.dataTransfer.setData("text/plain",k.id))},E=()=>{v.value="",_.value={}},R=(d,k)=>{if(!v.value||v.value===k.id)return;d.preventDefault(),d.dataTransfer&&(d.dataTransfer.dropEffect="move");const f=y(d)?"before":"after";(_.value.id!==k.id||_.value.side!==f)&&(_.value={id:k.id,side:f})},S=(d,k)=>{if(!v.value||v.value===k.id)return;d.preventDefault();const f=Ps(m.workspaces.map(B=>B.id),v.value,k.id,y(d));_.value={},an(f)};return(d,k)=>(r(),i("nav",hn,[(r(!0),i(V,null,N(p(m).workspaces,f=>(r(),i("a",{key:f.id,class:W(["rail__item",{"rail__item--dragging":v.value===f.id}]),"data-drop":_.value.id===f.id?_.value.side:null,href:"?ws="+encodeURIComponent(f.id),"aria-label":f.name,"aria-selected":f.id===p(m).workspace.id,draggable:"true",onClick:K(B=>c(B,f.id),["prevent"]),onDragstart:B=>A(B,f),onDragend:E,onDragover:B=>R(B,f),onDragleave:k[0]||(k[0]=B=>_.value={}),onDrop:B=>S(B,f)},[(r(),i("svg",vn,[o("rect",{x:"0",y:"0",width:"36",height:"36",rx:"10",fill:n.value[f.id].fill},null,8,mn),(r(!0),i(V,null,N(a.value[f.id].dots,(B,z)=>(r(),i("circle",{key:z,cx:B.cx,cy:B.cy,r:B.r,fill:n.value[f.id].dot,opacity:B.opacity},null,8,kn))),128)),o("text",{x:"18",y:a.value[f.id].fontSize>=17?24:23,"text-anchor":"middle","font-size":a.value[f.id].fontSize,"font-weight":"700","letter-spacing":"-0.5","font-family":"Roboto, Inter, system-ui, sans-serif",fill:n.value[f.id].ink},h(a.value[f.id].glyph),9,yn)])),o("span",gn,h(f.name),1),f.open_moves?(r(),i("span",bn,h(f.open_moves),1)):C("",!0)],42,fn))),128)),k[2]||(k[2]=o("span",{class:"rail__spacer"},null,-1)),o("a",{class:"rail__item",href:"#settings","aria-label":"Settings",onClick:K(u,["prevent"])},[(r(),i("svg",wn,[o("path",{d:p(cn),fill:"currentColor"},null,8,$n)])),k[1]||(k[1]=o("span",{class:"rail__label"},"Settings",-1))])]))}}),Cn=j(xn,[["__scopeId","data-v-be863916"]]),Ve=" · checks every minute",Ut=(e,t,s,a)=>{const n=e.failing.map(c=>c.source),l=t?ae(t):"—";return n.length&&n.length>=s?{dot:"off",text:"No data: "+n.join(", ")+" failing · last data "+ae(e.fresh_at),failing:n,noData:!0}:e.stale?{dot:"off",text:"Stale · last data "+ae(e.fresh_at)+Ve,failing:n,noData:!1}:n.length?{dot:a?"warn":"off",text:n.join(", ")+" failing · last check "+l+Ve,failing:n,noData:!1}:{dot:a?"ok":"off",text:"Live · last check "+l+Ve,failing:n,noData:!1}},Sn=["data-tip"],Tn={class:"ai-button__icon",viewBox:"0 0 24 24","aria-hidden":"true"},Mn=["d"],An=U({__name:"AiButton",props:{query:{},big:{type:Boolean}},setup(e){const t=e,s={"":"Copy for AI: this with its context as text, ready to paste into Claude or any other assistant",sent:"Copied",failed:"Could not copy"},a=Ae("",1600),n=g(()=>s[a.value]),l=()=>ks(t.query).then(c=>navigator.clipboard.writeText(c)).then(()=>{a.value="sent"},()=>{a.value="failed"});return(c,u)=>(r(),i("button",{type:"button",class:W(["ai-button",{"ai-button--big":e.big,"ai-button--sent":p(a)==="sent","ai-button--failed":p(a)==="failed"}]),"aria-label":"Copy for AI","data-tip":n.value,onClick:K(l,["stop"])},[(r(),i("svg",Tn,[o("path",{d:p(rn),fill:"currentColor"},null,8,Mn)]))],10,Sn))}}),de=j(An,[["__scopeId","data-v-d32a60c7"]]),Rn={key:0,class:"update-chip update-chip--done",role:"status"},En={key:1,class:"update-chip update-chip--busy",role:"status"},On=["title"],Dn=15e3,In=U({__name:"UpdateChip",setup(e){const t=D(!1),s=D(""),a=Ae("",Dn),n=g(()=>m.update),l=g(()=>t.value||n.value.state==="installing"||n.value.state==="restarting");X(()=>n.value.current,u=>{s.value&&u&&u!==s.value&&(a.value=u,s.value="")});const c=()=>{if(l.value)return;t.value=!0,s.value=n.value.current;const u=v=>{if(t.value=!1,!se(v,{refused:"The update did not start"})){s.value="";return}m.update=v.update};oe("/api/update").then(u,u)};return(u,v)=>p(a)?(r(),i("span",Rn,"Updated to "+h(p(a)),1)):l.value?(r(),i("span",En,"Updating…")):n.value.available&&n.value.state==="failed"?(r(),i("button",{key:2,type:"button",class:"update-chip update-chip--failed",title:n.value.reason,onClick:c}," Update failed · Retry ",8,On)):n.value.available?(r(),i("button",{key:3,type:"button",class:"update-chip",onClick:c},h(n.value.latest)+" is out · Update ",1)):C("",!0)}}),Bn=j(In,[["__scopeId","data-v-f70d2aed"]]),Vn={class:"status-bar"},Wn={class:"status-bar__icon",viewBox:"0 0 24 24","aria-hidden":"true"},Un=["d"],Nn={key:0,class:"status-bar__notice",role:"alert"},jn=["href"],Pn=["aria-disabled"],Fn=5e3,zn=U({__name:"StatusBar",emits:["report"],setup(e,{emit:t}){const s=t,a=g(()=>(ce.value,Ut(m.health,m.polled_at,m.workspace.connectors.length,b.live))),n=D(!1),l=D(!1),c=g(()=>l.value?"Opened in the app window. You can close this tab.":b.status||a.value.text),u=_=>se(_,{refused:"The app window did not open"}),v=()=>{if(n.value)return;n.value=!0,setTimeout(()=>n.value=!1,Fn);const _=y=>{u(y),l.value=!le(y)};oe("/api/open",{mode:"app"}).then(_,_)};return(_,y)=>(r(),i("div",Vn,[o("button",{type:"button",class:"btn status-bar__btn status-bar__report",title:"A bug or a wish about this monitor, straight to its backlog",onClick:y[0]||(y[0]=A=>s("report"))},[(r(),i("svg",Wn,[o("path",{d:p(dn),fill:"currentColor"},null,8,Un)])),y[2]||(y[2]=F("Report ",-1))]),o("span",{class:W(["status-bar__live",{"status-bar__live--off":a.value.dot==="off","status-bar__live--warn":a.value.dot==="warn"}])},null,2),o("span",null,h(c.value),1),p(Ce)?(r(),i("span",Nn,h(p(Ce)),1)):C("",!0),O(Bn),o("button",{type:"button",class:"btn status-bar__btn",onClick:y[1]||(y[1]=(...A)=>p(ht)&&p(ht)(...A))},"Refresh now"),p(b).mode==="app"?(r(),i("a",{key:1,class:"btn status-bar__btn",href:p(Xs)(p(b).ws),target:"_blank",rel:"noopener"},"Open in browser",8,jn)):(r(),i("button",{key:2,type:"button",class:W(["btn status-bar__btn",{"status-bar__btn--busy":n.value}]),"aria-disabled":n.value,onClick:v},h(n.value?"Opening…":"Open as app"),11,Pn)),O(de,{query:{all:"1"}}),y[3]||(y[3]=o("span",{class:"ai-hint status-bar__ai-hint"},"AI: copy everything",-1))]))}}),qn=j(zn,[["__scopeId","data-v-eefe1de8"]]),Nt=e=>{const t=Me("wt-collapsed",[],{writeDefaults:!1}),s=g(()=>t.value.includes(e));return{collapsed:s,toggle:()=>{t.value=s.value?t.value.filter(n=>n!==e):[...t.value,e]}}},Yn=["href"],Ln={key:1},ne=U({__name:"ExtLink",props:{text:{default:""},url:{default:""}},setup(e){const t=e,s=g(()=>Ge(t.url));return(a,n)=>s.value?(r(),i("a",{key:0,href:s.value,target:"_blank",rel:"noopener"},h(e.text),9,Yn)):(r(),i("span",Ln,h(e.text),1))}}),Hn={class:"workspace-header__title"},Xn={class:"workspace-header__name"},Kn={class:"workspace-header__line workspace-header__sentence"},Gn={class:"workspace-header__count"},Jn={class:"workspace-header__count"},Zn={key:0},Qn={class:"workspace-header__count"},eo={key:0,class:"workspace-header__line workspace-header__strip"},to={class:"workspace-header__count"},so={class:"workspace-header__count"},no={class:"workspace-header__count"},oo={class:"workspace-header__count"},ao={class:"workspace-header__line workspace-header__give"},lo={class:"workspace-header__links"},ro={class:"workspace-header__tiles"},io={class:"workspace-header__tile workspace-header__tile--you"},co={class:"workspace-header__tile-value"},uo={class:"workspace-header__tile"},po={class:"workspace-header__tile-value"},_o={class:"workspace-header__tile-value"},ho={class:"workspace-header__tile"},fo={class:"workspace-header__tile-value"},vo=U({__name:"WorkspaceHeader",setup(e){const{collapsed:t,toggle:s}=Nt("header");return(a,n)=>(r(),i("header",{id:"summary",class:W(["island workspace-header",{"workspace-header--collapsed":p(t)}])},[o("div",Hn,[o("h1",Xn,h(p(m).workspace.name||"Whose Turn"),1),o("p",Kn,[o("b",Gn,h(p(H).mine),1),n[3]||(n[3]=F(" waiting on you, ",-1)),o("b",Jn,h(p(H).others),1),n[4]||(n[4]=F(" waiting on someone else",-1)),p(H).failing?(r(),i("span",Zn,[n[1]||(n[1]=F(", ",-1)),o("b",Qn,h(p(H).failing),1),n[2]||(n[2]=F(" failing",-1))])):C("",!0),n[5]||(n[5]=F(". ",-1))]),p(t)?(r(),i("p",eo,[n[6]||(n[6]=F(" Your move ",-1)),o("b",to,h(p(H).mine),1),n[7]||(n[7]=F(" · Waiting on others ",-1)),o("b",so,h(p(H).others),1),n[8]||(n[8]=F(" · Failing ",-1)),o("b",no,h(p(H).failing),1),n[9]||(n[9]=F(" · Done ",-1)),o("b",oo,h(p(H).done),1)])):C("",!0),o("p",ao,[O(de,{query:{ws:p(m).workspace.id,kind:"workspace"},big:""},null,8,["query"]),n[10]||(n[10]=o("span",{class:"ai-hint"},"AI: copy this workspace",-1)),o("span",lo,[(r(!0),i(V,null,N(p(m).workspace.links||[],l=>(r(),q(ne,{key:l.url,text:l.label,url:l.url,title:l.url},null,8,["text","url","title"]))),128))])])]),o("button",{type:"button",class:W(["fold-toggle workspace-header__fold",{"fold-toggle--folded":p(t)}]),"aria-label":"Collapse or expand header","data-tip":"Fold the header; it stays folded until you open it again",onClick:n[0]||(n[0]=K((...l)=>p(s)&&p(s)(...l),["stop"]))}," ▾ ",2),o("div",ro,[o("div",io,[n[11]||(n[11]=o("span",{class:"workspace-header__tile-label"},"Your move",-1)),o("strong",co,h(p(H).mine),1)]),o("div",uo,[n[12]||(n[12]=o("span",{class:"workspace-header__tile-label"},"Waiting on others",-1)),o("strong",po,h(p(H).others),1)]),o("div",{class:W(["workspace-header__tile",{"workspace-header__tile--fail":p(H).failing}])},[n[13]||(n[13]=o("span",{class:"workspace-header__tile-label"},"Open PRs with failing checks",-1)),o("strong",_o,h(p(H).failing),1)],2),o("div",ho,[n[14]||(n[14]=o("span",{class:"workspace-header__tile-label"},"Done in the last 30 days",-1)),o("strong",fo,h(p(H).done),1)])])],2))}}),mo=j(vo,[["__scopeId","data-v-0f4b6d6e"]]),Qe=e=>{X(()=>b.reconnects,e)},ko=["id"],yo={class:"island__head"},go={class:"island__title"},bo={class:"island__note"},wo={class:"island__note-text"},$o=["data-tip"],xo=["aria-label"],Co={class:"island__body"},So=U({__name:"Island",props:{id:{},title:{},note:{default:""},tip:{default:""},column:{type:Boolean}},setup(e){const t=e,{collapsed:s,toggle:a}=Nt(t.id);return(n,l)=>(r(),i("section",{id:e.id,class:W(["island",{"island--collapsed":p(s),"island--column":e.column}])},[o("div",yo,[o("h2",go,[F(h(e.title)+" ",1),Ue(n.$slots,"head",{},void 0)]),o("p",bo,[o("span",wo,h(e.note),1),e.tip?(r(),i("button",{key:0,type:"button",class:"hint-icon","aria-label":"More info","data-tip":e.tip}," ? ",8,$o)):C("",!0),o("button",{type:"button",class:W(["fold-toggle",{"fold-toggle--folded":p(s)}]),"aria-label":"Collapse or expand "+e.id,"data-tip":"Fold this panel; it stays folded until you open it again",onClick:l[0]||(l[0]=K((...c)=>p(a)&&p(a)(...c),["stop"]))}," ▾ ",10,xo)])]),o("div",Co,[Ue(n.$slots,"default",{},void 0)])],10,ko))}}),Re=j(So,[["__scopeId","data-v-a03b7f62"]]),To=["aria-label"],Mo=["aria-pressed","onClick"],Ao={key:0,class:"segmented__count"},Ro=U({__name:"Segmented",props:Ne({options:{},label:{default:""},chips:{type:Boolean}},{modelValue:{required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(e){const t=mt(e,"modelValue");return(s,a)=>(r(),i("span",{class:W(["segmented",{"segmented--chips":e.chips}]),role:"group","aria-label":e.label},[(r(!0),i(V,null,N(e.options,n=>(r(),i("button",{key:n.id,type:"button",class:"segmented__option","aria-pressed":t.value===n.id,onClick:l=>t.value=n.id},[F(h(n.label),1),n.count!==void 0?(r(),i("b",Ao,h(n.count),1)):C("",!0)],8,Mo))),128))],10,To))}}),Te=j(Ro,[["__scopeId","data-v-7901b5d6"]]),Eo={class:"ticket-cell"},Oo={class:"ticket-cell__summary"},Do=U({__name:"TicketCell",props:{row:{}},setup(e){return(t,s)=>(r(),i("td",Eo,[O(ne,{text:e.row.key,url:e.row.ticket_url,class:"ticket-key"},null,8,["text","url"]),o("span",Oo,h(e.row.summary),1)]))}}),et=j(Do,[["__scopeId","data-v-8436de88"]]),Io={key:0,class:"pr-cell"},Bo={key:1,class:"pill"},Vo=U({__name:"PrCell",props:{row:{}},setup(e){return(t,s)=>(r(),i("td",null,[e.row.pr?(r(),i("span",Io,[O(ne,{text:e.row.pr,url:e.row.pr_url,class:"pr-cell__link"},null,8,["text","url"]),e.row.pr_state==="OPEN"&&e.row.checks?(r(),i("span",{key:0,class:W(["pill",p(fe)("pill",p(ys)(e.row.checks))])},h(e.row.checks),3)):e.row.pr_state?(r(),i("span",Bo,h(e.row.pr_state.toLowerCase()),1)):C("",!0)])):C("",!0)]))}}),jt=j(Vo,[["__scopeId","data-v-75c443c3"]]),Wo=["open"],Uo={class:"recently-done__summary"},No={class:"recently-done__count"},jo={class:"recently-done__list"},Po={class:"table"},Fo=["data-tip"],zo={class:"table__actions"},qo=U({__name:"RecentlyDone",setup(e){const t=Me("wt-recent-open",!1,{writeDefaults:!1,serializer:{read:n=>n==="1",write:n=>n?"1":"0"}}),s=n=>{t.value=n.target.open},a=g(()=>(ce.value,gs(m.turn).map(n=>({row:n,since:Ze(n.status_since||n.updated)}))));return(n,l)=>a.value.length?(r(),i("details",{key:0,class:"recently-done",open:p(t),onToggle:s},[o("summary",Uo,[l[0]||(l[0]=F(" Recently done ",-1)),o("span",No,h(a.value.length),1)]),o("div",jo,[o("table",Po,[l[1]||(l[1]=o("thead",null,[o("tr",null,[o("th",null,"Ticket"),o("th",null,"Status"),o("th",null,"Done"),o("th",{class:"table__actions-col"},[o("span",{class:"visually-hidden"},"Copy for AI")])])],-1)),o("tbody",null,[(r(!0),i(V,null,N(a.value,({row:c,since:u})=>(r(),i("tr",{key:c.row_id},[O(et,{row:c},null,8,["row"]),o("td",null,[o("span",{class:W(["pill",p(fe)("pill",p(Ct)(c.status_group))])},h(c.status),3)]),o("td",null,[o("span",{class:"age","data-tip":"Done "+p(Je)(c.status_since||c.updated)},h(u.text),9,Fo)]),o("td",zo,[O(de,{class:"table__ai",query:{ws:p(m).workspace.id,kind:"row",ref:c.row_id}},null,8,["query"])])]))),128))])])])],40,Wo)):C("",!0)}}),Yo=j(qo,[["__scopeId","data-v-12ee20e8"]]),Lo=13,Ho=U({__name:"RowScroll",props:{floor:{type:Boolean}},setup(e){const t=D(null),s=D(null),{y:a}=_s(t),{height:n}=at(t),{height:l}=at(s),c=()=>{var y,A,E;return[...((E=(A=(y=s.value)==null?void 0:y.querySelector("table"))==null?void 0:A.tBodies[0])==null?void 0:E.rows)||[]]},u=()=>{const y=t.value;return y?y.getBoundingClientRect().top+y.clientTop+y.clientHeight:0},v=g(()=>(a.value,n.value,l.value,bs(c().map(y=>y.getBoundingClientRect().bottom),u(),Lo))),_=()=>{var d,k;const y=t.value,A=c(),E=A[A.length-v.value];if(!y||!E)return;const S=((k=(d=s.value)==null?void 0:d.querySelector("thead"))==null?void 0:k.getBoundingClientRect().bottom)??y.getBoundingClientRect().top;y.scrollBy({top:E.getBoundingClientRect().top-S,behavior:"smooth"})};return(y,A)=>(r(),i(V,null,[o("div",{ref_key:"scroller",ref:t,class:W(["row-scroll",{"row-scroll--floor":e.floor}])},[o("div",{ref_key:"content",ref:s},[Ue(y.$slots,"default",{},void 0)],512)],2),v.value?(r(),i("button",{key:0,type:"button",class:"row-scroll__more",onClick:_}," +"+h(v.value)+" more ",1)):C("",!0)],64))}}),Pt=j(Ho,[["__scopeId","data-v-7bd9ace7"]]),Xo=D("open"),Ko=()=>Xo,Go={class:"table"},Jo={class:"hint-row"},Zo={class:"your-move__next"},Qo=["data-tip"],ea=["data-tip"],ta=["data-tip"],sa={key:0,class:"alert alert--inline your-move__problem",role:"alert"},na={class:"table__actions"},oa=["aria-label","onClick"],aa={key:0,class:"empty"},la=U({__name:"YourMove",setup(e){const t=Ko(),s=g(()=>{ce.value;const u=ws(m.turn,t.value);return{...u,rows:u.rows.map(v=>({...v,age:Ze(v.row.activity_at)}))}}),a=g(()=>[{id:"open",label:"Open",count:s.value.open},{id:"handled",label:"Handled",count:s.value.handled}]),n=g(()=>{if(t.value==="handled")return"Nothing marked as handled.";const{noData:u,failing:v}=Ut(m.health,m.polled_at,m.workspace.connectors.length,b.live);return u?"No data: "+v.join(", ")+(v.length===1?" is":" are")+" failing. Check Settings.":"Nothing is waiting on you."}),l=Le(new Map);Qe(()=>l.clear());const c=async u=>{const v=u.row.row_id,_=await qe({handled:{[v]:u.handled?null:new Date().toISOString()}});_?l.set(v,_):l.delete(v)};return(u,v)=>(r(),q(Re,{id:"your-move",title:"Your move",note:"Next step is yours",tip:"Each row is something where the next step is yours. Ticket, PR and comment open in a new tab."},{head:te(()=>[O(Te,{modelValue:p(t),"onUpdate:modelValue":v[0]||(v[0]=_=>Zt(t)?t.value=_:null),options:a.value,label:"Show",class:"your-move__view"},null,8,["modelValue","options"])]),default:te(()=>[O(Pt,{floor:""},{default:te(()=>[o("table",Go,[v[1]||(v[1]=o("thead",null,[o("tr",null,[o("th",null,"Ticket"),o("th",null,"Next step"),o("th",null,"PR"),o("th",{class:"hide-narrow"},"Last comment"),o("th",{class:"table__actions-col"},[o("span",{class:"visually-hidden"},"Mark")])])],-1)),o("tbody",null,[(r(!0),i(V,null,N(s.value.rows,_=>(r(),i("tr",{key:_.row.row_id,class:W(["your-move__row",{"your-move__row--handled":_.handled}])},[O(et,{row:_.row},null,8,["row"]),o("td",null,[o("span",Jo,[o("span",Zo,h(_.row.next),1),_.age.text?(r(),i("span",{key:0,class:W(["age",{"age--old":_.age.old}]),"data-tip":"Waiting since "+p(Je)(_.row.activity_at)},h(_.age.text),11,Qo)):C("",!0),_.row.why?(r(),i("button",{key:1,type:"button",class:"hint-icon","aria-label":"Why this is your move","data-tip":_.row.why}," ? ",8,ea)):C("",!0),_.handled?(r(),i("span",{key:2,class:"handled-chip","data-tip":"Marked "+p(ae)(p(m).marks.handled[_.row.row_id]||"")+". Comes back in 7 days if it is still open, or sooner when something new happens."},"handled",8,ta)):C("",!0)]),l.get(_.row.row_id)?(r(),i("p",sa,h(l.get(_.row.row_id)),1)):C("",!0)]),O(jt,{row:_.row},null,8,["row"]),o("td",{class:W(["hide-narrow",{"your-move__quote":_.row.comment}])},[_.row.comment?(r(),q(ne,{key:0,text:_.row.comment,url:_.row.comment_url},null,8,["text","url"])):C("",!0)],2),o("td",na,[O(de,{class:"table__ai",query:{ws:p(m).workspace.id,kind:"row",ref:_.row.row_id}},null,8,["query"]),o("button",{type:"button",class:W(["your-move__mark",{"your-move__mark--undo":_.handled}]),"aria-label":(_.handled?"Move back to open: ":"Mark as handled: ")+_.row.key,onClick:K(y=>c(_),["stop"])},h(_.handled?"Undo":"Handled"),11,oa)])],2))),128))])])]),_:1}),s.value.rows.length?C("",!0):(r(),i("p",aa,h(n.value),1)),p(t)==="open"?(r(),q(Yo,{key:1})):C("",!0)]),_:1}))}}),ra=j(la,[["__scopeId","data-v-e3e1502a"]]),ia=D(!1),ca=()=>ia,da={class:"todos__add"},ua={key:0,class:"alert alert--inline",role:"alert"},pa={class:"todos__list"},_a=["aria-checked","aria-label","onClick"],ha={class:"todos__text"},fa={class:"todos__meta"},va=["onClick"],ma={key:0,class:"empty todos__empty"},ka=U({__name:"Todos",setup(e){const t=ca(),s=D(""),a=g(()=>(m.todos||[]).filter(d=>!d.done)),n=g(()=>(m.todos||[]).filter(d=>d.done)),l=g(()=>new RegExp(m.workspace.key_pattern||"(?!)","g")),c=d=>{const k=[];let f=0;const B=d.text;for(const z of B.matchAll(l.value))z.index>f&&k.push({text:B.slice(f,z.index)}),k.push({text:z[0],url:z[0]===d.key?d.ticket_url:""}),f=z.index+z[0].length;return f<B.length&&k.push({text:B.slice(f)}),k},u=g(()=>(ce.value,(t.value?a.value.concat(n.value):a.value).map(d=>({todo:d,parts:c(d),meta:(d.by&&d.by!=="you"?d.by+" · ":"")+ae(d.created)})))),v=D("");Qe(()=>{v.value=""});const _=async d=>(v.value=await on(d),!v.value),y=async()=>{const d=s.value.trim();d&&await _({action:"add",text:d})&&s.value.trim()===d&&(s.value="")},A=d=>_({action:d.done?"undo":"done",id:d.id}),E=d=>_({action:"delete",id:d.id}),R=g({get:()=>t.value?"done":"open",set:d=>{t.value=d==="done"}}),S=g(()=>[{id:"open",label:"Open",count:a.value.length},{id:"done",label:"Done",count:n.value.length}]);return(d,k)=>(r(),q(Re,{id:"todo",title:"To do",note:"Your own notes",tip:'Your personal to-dos, kept on this machine. Add here, or ask Claude: "add to my to-do: …". A ticket key like PROJ-123 in the text becomes a link.'},{head:te(()=>[O(Te,{modelValue:R.value,"onUpdate:modelValue":k[0]||(k[0]=f=>R.value=f),options:S.value,label:"Show",class:"todos__view"},null,8,["modelValue","options"])]),default:te(()=>[o("div",da,[He(o("input",{"onUpdate:modelValue":k[1]||(k[1]=f=>s.value=f),class:"input todos__input",type:"text",placeholder:"Add a to-do and press Enter","aria-label":"New to-do",autocomplete:"off",onKeydown:je(y,["enter"])},null,544),[[Xe,s.value]]),o("button",{type:"button",class:"btn btn--tonal",onClick:y},"Add")]),v.value?(r(),i("p",ua,h(v.value),1)):C("",!0),o("ul",pa,[(r(!0),i(V,null,N(u.value,({todo:f,parts:B,meta:z})=>(r(),i("li",{key:f.id,class:W(["todos__item",{"todos__item--done":f.done}])},[o("button",{type:"button",class:W(["todos__check",{"todos__check--on":f.done}]),role:"checkbox","aria-checked":!!f.done,"aria-label":f.done?"Mark not done":"Mark done",onClick:L=>A(f)},null,10,_a),o("span",ha,[(r(!0),i(V,null,N(B,(L,J)=>(r(),i(V,{key:J},[L.url!==void 0?(r(),q(ne,{key:0,text:L.text,url:L.url},null,8,["text","url"])):(r(),i(V,{key:1},[F(h(L.text),1)],64))],64))),128))]),o("span",fa,h(z),1),o("button",{type:"button",class:"todos__delete","aria-label":"Delete to-do",onClick:L=>E(f)}," × ",8,va)],2))),128)),u.value.length?C("",!0):(r(),i("span",ma,h(p(t)?"Nothing here yet.":"Nothing to do. Add one above, or ask Claude."),1))])]),_:1}))}}),ya=j(ka,[["__scopeId","data-v-6f034e1e"]]),ga={key:0,class:"empty"},ba={class:"table waiting__table"},wa=["data-tip"],$a={class:"hide-narrow"},xa={key:0,class:"hint-row"},Ca=["data-tip"],Sa={class:"table__actions"},Ta=U({__name:"Waiting",setup(e){const t=g(()=>(ce.value,$s(m.turn).map(s=>({row:s,since:s.status_since?Ze(s.status_since):null}))));return(s,a)=>(r(),q(Re,{id:"waiting",title:"Waiting on others",note:"Someone else holds the next step",tip:"Tickets you touched in the last 30 days where someone else holds the next step: a reviewer, QA, or a new owner."},{default:te(()=>[t.value.length?(r(),q(Pt,{key:1},{default:te(()=>[o("table",ba,[a[0]||(a[0]=o("thead",null,[o("tr",null,[o("th",{class:"waiting__col waiting__col--ticket"},"Ticket"),o("th",{class:"waiting__col waiting__col--status"},"Status"),o("th",{class:"waiting__col waiting__col--with"},"With"),o("th",{class:"hide-narrow"},"Waiting for"),o("th",{class:"waiting__col waiting__col--pr"},"PR"),o("th",{class:"table__actions-col waiting__col waiting__col--actions"},[o("span",{class:"visually-hidden"},"Copy for AI")])])],-1)),o("tbody",null,[(r(!0),i(V,null,N(t.value,({row:n,since:l})=>(r(),i("tr",{key:n.row_id},[O(et,{row:n},null,8,["row"]),o("td",null,[o("span",{class:W(["pill",p(fe)("pill",p(Ct)(n.status_group))])},h(n.status),3)]),o("td",null,[F(h(n.whose)+" ",1),l?(r(),i("span",{key:0,class:W(["age",{"age--old":l.hours>=72}]),"data-tip":n.status+" since "+p(Je)(n.status_since)},h(l.text),11,wa)):C("",!0)]),o("td",$a,[n.hold_url?(r(),i("span",xa,[O(ne,{text:n.next,url:n.hold_url,class:"waiting__reason"},null,8,["text","url"]),o("button",{type:"button",class:"hint-icon","aria-label":"Full reason","data-tip":n.hold_full||n.next}," ? ",8,Ca)])):(r(),i(V,{key:1},[F(h(n.next),1)],64))]),O(jt,{row:n},null,8,["row"]),o("td",Sa,[O(de,{class:"table__ai",query:{ws:p(m).workspace.id,kind:"row",ref:n.row_id}},null,8,["query"])])]))),128))])])]),_:1})):(r(),i("p",ga,"Nothing is waiting on someone else."))]),_:1}))}}),Ma=j(Ta,[["__scopeId","data-v-a632447c"]]),Aa=(e,t)=>e.seen instanceof Set?e.seen.has(t):e.seen.includes(t),Ft=(e,t)=>new Date(e.at).getTime()>(t.base||0)&&!Aa(t,e.id),Ra=(e,t)=>{const s=String(t||"").toLowerCase().split(/\s+/).filter(Boolean);if(!s.length)return!0;const a=[e.ref,e.key,e.title,e.kind,e.who,e.text,e.body].join(" ").toLowerCase();return s.every(n=>a.includes(n))},Ea=e=>e.key||e.ref||e.id,Oa=(e,t)=>{const s=new Map;for(const a of e){const n=Ea(a),l=s.get(n)||{id:n,items:[],newest:a.at,unread:0,title:""};s.set(n,l),l.items.push(a),l.title||(l.title=a.title||""),a.at>l.newest&&(l.newest=a.at),Ft(a,t)&&(l.unread+=1)}return[...s.values()].sort((a,n)=>String(n.newest).localeCompare(String(a.newest)))},Da=e=>new Set(e.filter(t=>t.group==="you"&&!t.handled).map(t=>t.key)),Ia=(e,t=2)=>{const s=[...new Set(e.map(n=>n.kind))],a=s.length-t;return s.slice(0,t).join(" · ")+(a>0?` +${a}`:"")},Ba=e=>/fail|changes/.test(e)?"bad":/approved|merged|passed/.test(e)?"ok":"",Va=e=>/comment|approved|changes|mentioned|review requested/.test(e.kind)&&String(e.body||"").trim()!=="",zt=e=>e.ref!==e.key&&(e.key||e.title)||"",Wa=e=>[zt(e),e.text===e.title?"":e.text].filter(Boolean).join(" · "),Ua=e=>e.type==="github"&&e.label==="GitHub"?"GH":Wt(e.label),Na={class:"feed-item__body"},ja={class:"feed-item__top"},Pa={key:0,class:"feed-item__who"},Fa={key:1,class:"at-you"},za={class:"feed-item__right"},qa={class:"timestamp feed-item__when"},Ya=["aria-label","aria-expanded"],La={key:0,class:"feed-item__text"},Ha={class:"feed-item__full"},Xa={class:"feed-item__actions"},Ka={key:1,class:"feed-item__text"},Ga=U({__name:"FeedItem",props:{item:{},source:{},fresh:{type:Boolean},lit:{type:Boolean},expanded:{type:Boolean}},emits:["open","toggle","seen"],setup(e,{emit:t}){const s=e,a=t,n=g(()=>Ua(s.source)),l=g(()=>zt(s.item)),c=g(()=>Wa(s.item)),u=g(()=>Ba(s.item.kind)),v=g(()=>u.value||(s.source.type==="github"?"":"jira")),_=g(()=>Va(s.item)),y=g(()=>_.value&&s.expanded),A=g(()=>(ce.value,ae(s.item.at))),E=()=>{s.fresh&&a("seen",s.item.id)},R=()=>{a("toggle",s.item.id),E()};return(S,d)=>(r(),i("li",{class:W(["feed-item",{"feed-item--new":e.fresh,"feed-item--lit":e.lit,"feed-item--open":y.value}]),onClick:E},[o("span",{class:W(["feed-item__icon",p(fe)("feed-item__icon",v.value)])},h(n.value),3),o("div",Na,[o("div",ja,[O(ne,{text:e.item.ref,url:e.item.url},null,8,["text","url"]),o("span",{class:W(["feed-item__kind",{"feed-item__kind--bad":u.value==="bad"}])},h(e.item.kind),3),e.item.who?(r(),i("span",Pa,h(e.item.who),1)):C("",!0),e.item.mention?(r(),i("span",Fa,"@you")):C("",!0),o("span",za,[o("span",qa,h(A.value),1),_.value?(r(),i("button",{key:0,type:"button",class:"feed-item__toggle","aria-label":y.value?"Collapse":"Expand","aria-expanded":y.value,onClick:K(R,["stop"])},null,8,Ya)):C("",!0)])]),y.value?(r(),i(V,{key:0},[l.value?(r(),i("span",La,h(l.value),1)):C("",!0),o("div",Ha,h(e.item.body),1),o("div",Xa,[o("button",{type:"button",class:"btn btn--tonal",onClick:d[0]||(d[0]=K(k=>a("open",e.item),["stop"]))}," Open formatted "),O(de,{query:{ws:p(m).workspace.id,kind:"feed",ref:e.item.id}},null,8,["query"]),O(ne,{text:"Open in "+e.source.label,url:e.item.url,class:"btn"},null,8,["text","url"])])],64)):c.value?(r(),i("span",Ka,h(c.value),1)):C("",!0)])],2))}}),ft=j(Ga,[["__scopeId","data-v-27e556e1"]]),Ja=Le({source:"all",view:Me("wt-feed-view","ticket",{writeDefaults:!1}),query:"",openGroups:new Set}),Za=()=>Ja,Qa={key:0,class:"feed__new-count"},el={class:"feed__bar"},tl={key:0,class:"alert alert--inline",role:"alert"},sl={class:"feed__search"},nl={class:"feed__search-count"},ol={key:1,class:"empty"},al={key:2,class:"feed__list"},ll=["title","onClick"],rl=["aria-expanded","aria-label"],il={class:"feed__group-text"},cl={class:"feed__group-key"},dl={key:0,class:"feed__group-sum"},ul={class:"feed__group-meta"},pl={class:"feed__group-kinds"},_l={class:"timestamp feed__group-when"},hl={key:0,class:"feed__children"},fl=U({__name:"Feed",emits:["open"],setup(e,{emit:t}){const s=t,a=Za(),n=[{id:"ticket",label:"By ticket"},{id:"flat",label:"Flat"}],l=g(()=>m.workspace.connectors||[]),c=g(()=>Object.fromEntries(l.value.map($=>[$.id,$]))),u=$=>c.value[$]||{id:$,type:$,label:$},v=g(()=>l.value.length>1?[{id:"all",label:"All"}].concat(l.value.map($=>({id:$.id,label:$.label}))):[]),_=g({get:()=>v.value.some($=>$.id===a.source)?a.source:"all",set:$=>{a.source=$}}),y=g(()=>({base:m.marks.base,seen:new Set(m.marks.seen)})),A=$=>Ft($,y.value),E=g(()=>m.feed.filter(A).length),R=g(()=>m.feed.filter($=>_.value==="all"||$.source===_.value)),S=g(()=>R.value.filter($=>Ra($,a.query)).slice(0,200)),d=g(()=>new Map(m.turn.map($=>[$.key,$]))),k=g(()=>Da(m.turn)),f=g(()=>(ce.value,Oa(S.value,y.value).map($=>({...$,row:d.value.get($.id),move:k.value.has($.id),when:ae($.newest),kinds:Ia($.items),open:a.openGroups.has($.id)||!!a.query})))),B=($,Y)=>{$.has(Y)?$.delete(Y):$.add(Y)},z=$=>B(a.openGroups,$.id),L=$=>B(b.open,$),J=$=>qe({seen:[$]}).then(se),ue=D("");Qe(()=>{ue.value=""});const Q=async()=>{ue.value=await qe({seen:m.feed.map($=>$.id),base:Date.now()})};return($,Y)=>(r(),q(Re,{id:"feed",title:"What changed",note:"Newest first, every source",tip:"Newest first: comments, reviews, merges and failed checks on your PRs, and ticket changes. Each item opens where it happened.",class:"feed",column:""},{head:te(()=>[E.value?(r(),i("span",Qa,h(E.value)+" new",1)):C("",!0)]),default:te(()=>[o("div",el,[v.value.length?(r(),q(Te,{key:0,modelValue:_.value,"onUpdate:modelValue":Y[0]||(Y[0]=M=>_.value=M),options:v.value,label:"Feed source"},null,8,["modelValue","options"])):C("",!0),O(Te,{modelValue:p(a).view,"onUpdate:modelValue":Y[1]||(Y[1]=M=>p(a).view=M),options:n,label:"Feed view"},null,8,["modelValue"])]),ue.value?(r(),i("p",tl,h(ue.value),1)):C("",!0),o("div",sl,[He(o("input",{"onUpdate:modelValue":Y[2]||(Y[2]=M=>p(a).query=M),class:"input feed__search-input",type:"search",placeholder:"Search the feed: key, author, words…","aria-label":"Search the feed",autocomplete:"off"},null,512),[[Xe,p(a).query,void 0,{trim:!0}]]),o("span",nl,h(p(a).query?S.value.length+" of "+R.value.length:""),1),o("button",{type:"button",class:"feed__mark-read",onClick:Q},"Mark all read")]),p(m).feed.length?(r(),i("ol",al,[p(a).view==="ticket"?(r(!0),i(V,{key:0},N(f.value,M=>(r(),i("li",{key:M.id,class:W(["feed__group",{"feed__group--new":M.unread,"feed__group--open":M.open,"feed__group--move":M.move}])},[o("div",{class:"feed__group-head",title:M.move?"Your move on this ticket":void 0,onClick:Z=>z(M)},[o("button",{type:"button",class:"feed__group-caret","aria-expanded":M.open,"aria-label":"Collapse or expand "+M.id}," › ",8,rl),o("div",il,[o("div",cl,[O(ne,{text:M.id,url:M.row?M.row.ticket_url:M.items[0].url,class:"ticket-key feed__group-ticket"},null,8,["text","url"]),M.row||M.title?(r(),i("span",dl,h(M.row?M.row.summary:M.title),1)):C("",!0)]),o("div",ul,[o("span",{class:W(["feed__group-count",{"feed__group-count--new":M.unread}])},h(M.unread?M.unread+" new":M.items.length),3),o("span",pl,h(M.kinds),1),o("span",_l,h(M.when),1)])]),O(de,{class:"feed__group-copy",query:{ws:p(m).workspace.id,kind:"thread",ref:M.id}},null,8,["query"])],8,ll),M.open?(r(),i("ul",hl,[(r(!0),i(V,null,N(M.items,Z=>(r(),q(ft,{key:Z.id,item:Z,source:u(Z.source),fresh:A(Z),lit:!!M.unread,expanded:p(b).open.has(Z.id),onOpen:Y[3]||(Y[3]=Ee=>s("open",Ee)),onToggle:L,onSeen:J},null,8,["item","source","fresh","lit","expanded"]))),128))])):C("",!0)],2))),128)):(r(!0),i(V,{key:1},N(S.value,M=>(r(),q(ft,{key:M.id,item:M,source:u(M.source),fresh:A(M),expanded:p(b).open.has(M.id),onOpen:Y[4]||(Y[4]=Z=>s("open",Z)),onToggle:L,onSeen:J},null,8,["item","source","fresh","expanded"]))),128))])):(r(),i("p",ol," No changes yet. New comments, reviews and status changes show up here. "))]),_:1}))}}),vl=j(fl,[["__scopeId","data-v-d92a7c74"]]),ml={id:"first-run",class:"island first-run","aria-labelledby":"first-run-title"},kl={class:"first-run__text"},yl={class:"first-run__actions"},gl=["aria-disabled"],bl=U({__name:"FirstRun",setup(e){const t=D(!1),s=()=>Js("connectors"),a=()=>{t.value||(t.value=!0,ln().finally(()=>{t.value=!1}))};return(n,l)=>(r(),i("section",ml,[l[1]||(l[1]=o("h2",{id:"first-run-title",class:"first-run__title"}," Whose Turn watches your tickets and pull requests and shows what is waiting on you. ",-1)),o("p",kl,[o("b",null,h(p(m).workspace.name),1),l[0]||(l[0]=F(" has no sources yet, so there is nothing to watch. Connect a repository or a tracker, or look around a demo workspace with invented data first. ",-1))]),o("div",yl,[o("button",{type:"button",class:"btn btn--tonal",onClick:s},"Add a source"),o("button",{type:"button",class:"btn","aria-disabled":t.value,onClick:a}," Try a demo workspace ",8,gl)]),l[2]||(l[2]=o("p",{class:"first-run__text first-run__ai"},' Or ask Claude: "add my GitHub repository to Whose Turn." ',-1))]))}}),wl=j(bl,[["__scopeId","data-v-ef746675"]]),$l=new RegExp("(`[^`]{1,500}`)|(\\*\\*[^*]{1,500}\\*\\*)|(\\[[^\\]]{1,300}\\]\\(https?:\\/\\/[^)\\s]{1,2000}\\))|(https?:\\/\\/[^\\s<>()]{1,2000})|(@[A-Za-z0-9-]+(?: [A-Z][a-z]+)?)|((?<![A-Za-z0-9])\\*[^*\\s][^*]{0,500}\\*(?![A-Za-z0-9])|(?<![A-Za-z0-9])_[^_\\s][^_]{0,500}_(?![A-Za-z0-9]))","g"),vt=(e,t)=>{const s=Ge(t);return s?{type:"link",text:e,href:s}:{type:"text",text:e}},xl=e=>{const t=e[0];if(e[1])return{type:"code",text:t.slice(1,-1)};if(e[2])return{type:"strong",text:t.slice(2,-2)};if(e[3]){const s=t.indexOf("](");return vt(t.slice(1,s),t.slice(s+2,-1))}return e[4]?vt(t,t):e[5]?{type:"mention",text:t}:{type:"em",text:t.slice(1,-1)}},ge=e=>{const t=new RegExp($l),s=[];let a=0,n;for(;n=t.exec(e);)n.index>a&&s.push({type:"text",text:e.slice(a,n.index)}),s.push(xl(n)),a=n.index+n[0].length;return a<e.length&&s.push({type:"text",text:e.slice(a)}),s},Cl=e=>{const t=String(e||"").replace(/<!--[\s\S]*?-->/g,"").split(`
|
|
2
|
-
`),s=[];let a=[],n=null;const l=()=>{a.length&&(s.push({type:"paragraph",lines:a.map(ge)}),a=[]),n=null};for(let c=0;c<t.length;c++){const u=t[c];if(/^\s*```/.test(u)){l();const A=[];for(c++;c<t.length&&!/^\s*```/.test(t[c]);c++)A.push(t[c]);s.push({type:"fence",text:A.join(`
|
|
3
|
-
`)});continue}const v=u.match(/^(#{1,6})\s+(.*)$/);if(v){l(),s.push({type:"heading",level:v[1].length<=2?4:5,inline:ge(v[2])});continue}const _=u.match(/^>\s?(.*)$/);if(_){l(),s.push({type:"quote",inline:ge(_[1])});continue}const y=u.match(/^\s*([-*+]|\d+[.)])\s+(.*)$/);if(y){const A=n;a.length&&(l(),n=A);const E=/\d/.test(y[1]),R=n,S=R&&R.ordered===E?R:{type:"list",ordered:E,items:[]};S!==R&&s.push(S),n=S,S.items.push(ge(y[2]));continue}if(!u.trim()){l();continue}n=null,a.push(u)}return l(),s},we=(e,t,s="")=>{const a=document.createElement(e);return a.textContent=t,s&&(a.className=s),a},Sl=e=>{if(e.type==="text")return document.createTextNode(e.text);if(e.type==="link"){const t=we("a",e.text);return t.setAttribute("href",e.href),t.setAttribute("target","_blank"),t.setAttribute("rel","noopener"),t}return e.type==="mention"?we("span",e.text,"markdown-view__mention"):we(e.type,e.text)},qt=(e,t)=>{e.forEach(s=>t.append(Sl(s)))},We=(e,t)=>{const s=document.createElement(e);return qt(t,s),s},Tl=e=>{if(e.type==="fence"){const s=document.createElement("pre");return s.append(we("code",e.text)),s}if(e.type==="heading")return We(`h${e.level}`,e.inline);if(e.type==="quote")return We("blockquote",e.inline);if(e.type==="list"){const s=document.createElement(e.ordered?"ol":"ul");return e.items.forEach(a=>s.append(We("li",a))),s}const t=document.createElement("p");return e.lines.forEach((s,a)=>{a&&t.append(document.createElement("br")),qt(s,t)}),t},Ml=e=>{const t=document.createDocumentFragment();return Cl(e).forEach(s=>t.append(Tl(s))),t},Al=U({__name:"MarkdownView",props:{source:{default:""}},setup(e){const t=e,s=D(null);return Qt(()=>{s.value&&s.value.replaceChildren(Ml(t.source))}),(a,n)=>(r(),i("div",{ref_key:"host",ref:s,class:"markdown-view"},null,512))}}),Rl=j(Al,[["__scopeId","data-v-dcf42e95"]]),El={class:"modal__card"},Ol={class:"modal__head"},Dl={id:"modal-title",class:"modal__title"},Il=["href"],Bl=U({__name:"CommentModal",setup(e){const t=g(()=>b.modal),s=g(()=>t.value?[t.value.ref,t.value.kind,t.value.who].filter(Boolean).join(" · "):""),a=g(()=>t.value?Ge(t.value.url):""),n=g(()=>{var u;const c=(m.workspace.connectors||[]).find(v=>{var _;return v.id===((_=t.value)==null?void 0:_.source)});return"Open in "+(c?c.label:(u=t.value)==null?void 0:u.source)}),l=()=>{b.modal=null};return(c,u)=>t.value?(r(),i("div",{key:0,class:"modal",role:"dialog","aria-modal":"true","aria-labelledby":"modal-title",onClick:K(l,["self"])},[o("div",El,[o("div",Ol,[o("h3",Dl,h(s.value),1),a.value?(r(),i("a",{key:0,class:"btn",href:a.value,target:"_blank",rel:"noopener"},h(n.value),9,Il)):C("",!0),o("button",{type:"button",class:"btn btn--tonal",onClick:l},"Close")]),O(Rl,{source:t.value.body||t.value.text||""},null,8,["source"])])])):C("",!0)}}),Vl={class:"modal__card feedback-sheet__card"},Wl={class:"modal__head"},Ul={class:"modal__meta"},Nl=["aria-disabled"],jl={key:0,class:"alert"},Pl={class:"sheet-form"},Fl=["placeholder","onKeydown"],zl={key:0,class:"feedback-sheet__note"},ql={key:1,class:"feedback-sheet__note"},Yl={key:2,class:"empty"},Ll=["href"],Hl={key:3,class:"feedback-sheet__reports"},Xl=["href"],Kl={class:"feedback-sheet__report-title"},Gl={class:"timestamp"},Jl=U({__name:"FeedbackSheet",setup(e){const t=D(""),s=D(null),a=D(!1),n=D([]),l=D(null),c=D(""),u=D(!0),v=Ae("",1600),_=D([]),y=d=>"/report?id="+encodeURIComponent(d),A=()=>he("/api/feedback").then(d=>{u.value=d.configured,c.value=d.configured?"Linear · "+d.project:"not connected",_.value=d.reports||[]},()=>{n.value=[$e+"; past reports cannot be loaded."]}),E=()=>{b.feedback=!1},R=()=>{const d=t.value.trim();if(!d){n.value=["Write at least one line."];return}n.value=[],navigator.clipboard.writeText(d).then(()=>{v.value="sent"},()=>{v.value="failed"})},S=()=>{if(!u.value||a.value)return;const d=t.value.trim();if(!d){n.value=["Write at least one line."];return}a.value=!0,oe("/api/feedback",{text:d,from:"the window",ws:m.workspace.id,kind_ref:{kind:"workspace",ref:m.workspace.id}}).then(k=>{if(a.value=!1,k.error){n.value=St(k.error);return}l.value=k.issue||null,t.value="",_.value=k.reports||_.value}).catch(k=>{a.value=!1,n.value=[le(k,{refused:"Not sent",unreachable:Pe})]})};return X(()=>b.feedback,d=>{d&&(n.value=[],l.value=null,A().then(()=>kt(()=>{var k;return(k=s.value)==null?void 0:k.focus()})))}),(d,k)=>p(b).feedback?(r(),i("div",{key:0,class:"modal",role:"dialog","aria-modal":"true","aria-labelledby":"feedback-title",onClick:K(E,["self"])},[o("div",Vl,[o("div",Wl,[k[1]||(k[1]=o("h3",{id:"feedback-title",class:"modal__title"},"To the Whose Turn backlog",-1)),o("span",Ul,h(c.value),1),o("button",{type:"button",class:"btn btn--tonal","aria-disabled":!u.value||a.value,onClick:S},h(a.value?"Composing…":"Send"),9,Nl),o("button",{type:"button",class:"btn",onClick:E},"Close")]),n.value.length?(r(),i("div",jl,h(n.value.join(" · ")),1)):C("",!0),o("div",Pl,[He(o("textarea",{ref_key:"field",ref:s,"onUpdate:modelValue":k[0]||(k[0]=f=>t.value=f),class:"input feedback-sheet__text",rows:"5",placeholder:"Describe the problem or the wish in your own words."+(u.value?" Cmd+Enter sends.":""),autocomplete:"off",onKeydown:[je(K(S,["meta","prevent"]),["enter"]),je(K(S,["ctrl","prevent"]),["enter"])]},null,40,Fl),[[Xe,t.value]]),u.value?(r(),i("p",ql," An assistant turns it into a proper issue (title, kind, description) and files it in the Whose Turn backlog with this workspace's summary attached. ")):(r(),i("p",zl,[k[2]||(k[2]=F(" The maintainer's tracker is not connected on this machine, so nothing can be sent from here. Copy your remark and pass it on yourself. ",-1)),o("button",{type:"button",class:"btn",onClick:R},h(p(v)==="sent"?"Copied":p(v)==="failed"?"Could not copy":"Copy remark"),1)])),l.value?(r(),i("p",Yl,[k[3]||(k[3]=F(" Filed as ",-1)),o("a",{href:y(l.value.identifier),target:"_blank",rel:"noopener"},h(l.value.identifier),9,Ll),F(" · "+h(l.value.title),1)])):C("",!0),_.value.length?(r(),i("div",Hl,[k[4]||(k[4]=o("h4",{class:"sheet-form__heading"},"Your reports",-1)),(r(!0),i(V,null,N(_.value,f=>(r(),i("div",{key:f.id,class:"feedback-sheet__report"},[o("a",{href:y(f.id),target:"_blank",rel:"noopener"},h(f.id),9,Xl),o("span",Kl,h(f.title),1),o("span",{class:W(["pill",p(fe)("pill",p(xs)(f.outcome))])},h(f.state||"filed"),3),o("span",Gl,h(p(ae)(f.changed_at||f.filed_at)),1)]))),128))])):C("",!0)])])])):C("",!0)}}),Zl=j(Jl,[["__scopeId","data-v-ec34adcc"]]),Ql={class:"field-row"},er={class:"field-row__label"},tr={key:0,class:"field-row__check"},sr=["checked"],nr={key:2,class:"field-row__inline"},or=["value"],ar=["value"],lr=["value"],rr=["placeholder","value"],ir={key:5,class:"field-row__hint"},cr=U({__name:"FieldRow",props:Ne({spec:{},placeholder:{default:""},hint:{default:""}},{modelValue:{type:[String,Array,Boolean]},modelModifiers:{}}),emits:Ne(["secret"],["update:modelValue"]),setup(e,{emit:t}){const s=e,a=t,n=mt(e,"modelValue"),l=/^#[0-9a-f]{6}$/i,c=()=>String(n.value??""),u=()=>n.value||[],v=R=>{n.value=R},_=()=>n.value??s.spec.default??!1,y=R=>{n.value=R===(s.spec.default??!1)?void 0:R},A=R=>R.target.value,E=R=>v(R.split(",").map(S=>S.trim()).filter(Boolean));return(R,S)=>(r(),i("div",Ql,[o("label",er,h(e.spec.label)+h(e.spec.required?" *":""),1),e.spec.boolean?(r(),i("label",tr,[o("input",{type:"checkbox",checked:_(),onChange:S[0]||(S[0]=d=>y(d.target.checked))},null,40,sr),F(" "+h(e.hint||e.spec.hint),1)])):e.spec.secret?(r(),i("input",{key:1,class:"input",type:"password",placeholder:"paste to replace",autocomplete:"off",onInput:S[1]||(S[1]=d=>a("secret",e.spec.key,A(d)))},null,32)):e.spec.colour?(r(),i("div",nr,[o("input",{class:"input field-row__colour",type:"color",value:l.test(c())?c():"#888888",onInput:S[2]||(S[2]=d=>v(A(d)))},null,40,or),o("input",{class:"input",type:"text",placeholder:"#rrggbb",value:c(),onInput:S[3]||(S[3]=d=>v(A(d)))},null,40,ar),o("button",{type:"button",class:"btn",onClick:S[4]||(S[4]=d=>v(""))},"None")])):e.spec.list?(r(),i("input",{key:3,class:"input",type:"text",value:u().join(", "),onInput:S[5]||(S[5]=d=>E(A(d)))},null,40,lr)):(r(),i("input",{key:4,class:"input",type:"text",placeholder:e.placeholder,value:c(),onInput:S[6]||(S[6]=d=>v(A(d)))},null,40,rr)),!e.spec.boolean&&(e.hint||e.spec.hint)?(r(),i("small",ir,h(e.hint||e.spec.hint),1)):C("",!0)]))}}),ie=j(cr,[["__scopeId","data-v-2ba0ba86"]]),dr={class:"modal__card settings-sheet__card"},ur={class:"modal__head"},pr={class:"modal__meta"},_r={key:0,class:"settings-sheet__dirty"},hr={key:0,class:"settings-sheet__confirm",role:"alertdialog"},fr={class:"settings-sheet__confirm-text"},vr={key:1,class:"alert settings-sheet__alert",role:"alert"},mr={key:2,class:"alert settings-sheet__alert"},kr={key:3,class:"settings-sheet__body"},yr={class:"settings-sheet__list"},gr=["aria-current","onClick"],br={class:"sheet-form"},wr={key:0,class:"empty"},$r={ref:"connectors-head",class:"sheet-form__heading"},xr={class:"settings-sheet__connector-head"},Cr={class:"settings-sheet__connector-name"},Sr=["onClick"],Tr={class:"settings-sheet__actions"},Mr=["onClick"],Ar={key:0,class:"settings-sheet__rules"},Rr={class:"settings-sheet__rule-when"},Er={class:"settings-sheet__rule-then"},Or={key:1,class:"empty"},Dr=U({__name:"SettingsSheet",setup(e){const t=D([]),s=D(0),a=D([]),n=D({workspace:[],theme:[],rules:[],statuses:[]}),l=D(""),c=D([]),u=D({}),v=es("connectors-head"),_=new Map,y=D(0),A=D(""),E=D(null),R=D(""),S=g(()=>b.settings&&!R.value&&(y.value>0||dt(t.value)!==A.value)),d={key:"id",label:"Entry id"},k={key:"label",label:"Label"},f=g(()=>t.value[s.value]),B=g(()=>(f.value&&u.value[f.value.id]||[]).map(Ys)),z=w=>a.value.find(T=>T.type===w.type)||{type:w.type,label:w.type,fields:[]},L=g(()=>t.value.map((w,T)=>({uid:ct(w),label:w.name||w.id||"Workspace "+(T+1)}))),J=g(()=>{var w;return(((w=f.value)==null?void 0:w.connectors)||[]).map(T=>({entry:T,uid:ct(T),spec:z(T)}))}),ue=w=>{var x;const T=(x=m.workspaces.find(P=>P.id===w))==null?void 0:x.theme_seed;return T?`empty: ${T}, derived from the workspace id`:"empty derives one from the workspace id"},Q=(w,T)=>w[T],$=(w,T,x)=>{_.set(w,Object.assign(_.get(w)||{},{[T]:x})),y.value+=1},Y=()=>{t.value.push(rt({id:"new-"+(t.value.length+1),name:"New workspace"})),s.value=t.value.length-1},M=()=>{t.value.splice(s.value,1),s.value=Math.max(0,s.value-1)},Z=()=>{f.value&&(E.value={text:`Delete ${f.value.name||f.value.id}? Its to-dos and marks stay on disk.`,yes:"Delete",no:"Keep",run:M})},Ee=w=>{var T;return(T=f.value)==null?void 0:T.connectors.push({type:w.type})},Yt=w=>{f.value&&(_.delete(f.value.connectors[w]),f.value.connectors.splice(w,1))},Lt=w=>{if(!f.value)return;const T=z(f.value.connectors[w]).label;E.value={text:`Remove the ${T} connector from ${f.value.name||f.value.id}?`,yes:"Remove",no:"Keep",run:()=>Yt(w)}},Ht=()=>he("/api/config").then(w=>{R.value="",t.value=(w.workspaces||[]).map(rt),a.value=w.connectors||[],n.value=w.fields,_.clear(),y.value=0,E.value=null,s.value=Math.max(0,t.value.findIndex(T=>T.id===m.workspace.id)),l.value=w.config_file||"",c.value=w.problems||[],u.value=w.tables||{},A.value=dt(t.value)}).catch(()=>{R.value=$e+"; settings cannot be loaded."}).then(kt).then(()=>{var w;b.settingsAt==="connectors"&&((w=v.value)==null||w.scrollIntoView({block:"start"})),b.settingsAt=""}),Oe=()=>{b.settings=!1},tt=()=>{E.value={text:"Discard changes?",yes:"Discard",no:"Keep editing",run:Oe}},st=()=>S.value?tt():Oe(),nt=w=>{const T=E.value;E.value=null,w&&(T==null||T.run())},Xt=async()=>{try{const w=await oe("/api/config",{workspaces:t.value.map(T=>Ws(T)),secrets:Ns(t.value,_)});if(w.error){c.value=St(w.error);return}Oe(),It()}catch(w){c.value=[le(w,{unreachable:$e+"; your changes are kept, save again."})]}};return X(S,w=>{b.settingsDirty=w},{immediate:!0}),X(()=>b.settingsAsk,w=>{w&&(b.settingsAsk=!1,tt())}),X(()=>b.settings,w=>{w&&Ht()}),(w,T)=>p(b).settings?(r(),i("div",{key:0,class:"modal",role:"dialog","aria-modal":"true","aria-labelledby":"settings-title",onClick:K(st,["self"])},[o("div",dr,[o("div",ur,[T[2]||(T[2]=o("h3",{id:"settings-title",class:"modal__title"},"Workspaces",-1)),o("span",pr,h(l.value),1),S.value?(r(),i("span",_r,"Unsaved changes")):C("",!0),R.value?C("",!0):(r(),i("button",{key:1,type:"button",class:"btn btn--tonal",onClick:Xt},"Save")),o("button",{type:"button",class:"btn",onClick:st},"Close")]),E.value?(r(),i("div",hr,[o("span",fr,h(E.value.text),1),o("button",{type:"button",class:"btn btn--danger",onClick:T[0]||(T[0]=x=>nt(!0))},h(E.value.yes),1),o("button",{type:"button",class:"btn",onClick:T[1]||(T[1]=x=>nt(!1))},h(E.value.no),1)])):C("",!0),R.value?(r(),i("div",vr,h(R.value),1)):c.value.length?(r(),i("div",mr,h(c.value.join(" · ")),1)):C("",!0),R.value?C("",!0):(r(),i("div",kr,[o("ul",yr,[(r(!0),i(V,null,N(L.value,(x,P)=>(r(),i("li",{key:x.uid},[o("button",{type:"button",class:"settings-sheet__workspace","aria-current":P===s.value,onClick:me=>s.value=P},h(x.label),9,gr)]))),128)),o("li",null,[o("button",{type:"button",class:"settings-sheet__workspace settings-sheet__workspace--add",onClick:Y}," + Add workspace ")])]),o("div",br,[f.value?(r(),i(V,{key:1},[T[3]||(T[3]=o("h4",{class:"sheet-form__heading"},"Workspace",-1)),(r(!0),i(V,null,N(n.value.workspace,x=>(r(),q(ie,{key:x.key,spec:x,"model-value":Q(f.value,x.key),"onUpdate:modelValue":P=>p(re)(f.value,x.key,P)},null,8,["spec","model-value","onUpdate:modelValue"]))),128)),T[4]||(T[4]=o("h4",{class:"sheet-form__heading"},"Theme",-1)),(r(!0),i(V,null,N(n.value.theme,x=>{var P;return r(),q(ie,{key:x.key,spec:x,hint:x.key==="seed"&&!((P=f.value.theme)!=null&&P.seed)?ue(f.value.id):"","model-value":Q(f.value.theme,x.key),"onUpdate:modelValue":me=>p(re)(f.value.theme,x.key,me)},null,8,["spec","hint","model-value","onUpdate:modelValue"])}),128)),o("h4",$r,"Connectors",512),(r(!0),i(V,null,N(J.value,({entry:x,spec:P,uid:me},Kt)=>(r(),i("div",{key:me,class:"settings-sheet__connector"},[o("div",xr,[o("strong",Cr,h(P.label),1),o("button",{type:"button",class:"btn btn--danger",onClick:ee=>Lt(Kt)}," Remove ",8,Sr)]),O(ie,{spec:d,placeholder:P.type,hint:"only needed when one type appears twice","model-value":Q(x,"id"),"onUpdate:modelValue":ee=>p(re)(x,"id",ee)},null,8,["placeholder","model-value","onUpdate:modelValue"]),O(ie,{spec:k,placeholder:P.label,hint:"shown in the feed filter","model-value":Q(x,"label"),"onUpdate:modelValue":ee=>p(re)(x,"label",ee)},null,8,["placeholder","model-value","onUpdate:modelValue"]),(r(!0),i(V,null,N(P.fields,ee=>(r(),q(ie,{key:ee.key,spec:ee,"model-value":Q(x,ee.key),"onUpdate:modelValue":De=>p(re)(x,ee.key,De),onSecret:(De,Gt)=>$(x,De,Gt)},null,8,["spec","model-value","onUpdate:modelValue","onSecret"]))),128))]))),128)),o("div",Tr,[(r(!0),i(V,null,N(a.value,x=>(r(),i("button",{key:x.type,type:"button",class:"btn",onClick:P=>Ee(x)}," + "+h(x.label),9,Mr))),128))]),T[5]||(T[5]=o("h4",{class:"sheet-form__heading"},"Rules",-1)),(r(!0),i(V,null,N(n.value.rules,x=>(r(),q(ie,{key:x.key,spec:x,"model-value":Q(f.value.rules,x.key),"onUpdate:modelValue":P=>p(re)(f.value.rules,x.key,P)},null,8,["spec","model-value","onUpdate:modelValue"]))),128)),(r(!0),i(V,null,N(n.value.statuses,x=>(r(),q(ie,{key:x.key,spec:x,"model-value":Q(f.value.rules.statuses,x.key),"onUpdate:modelValue":P=>p(re)(f.value.rules.statuses,x.key,P)},null,8,["spec","model-value","onUpdate:modelValue"]))),128)),T[6]||(T[6]=o("h4",{class:"sheet-form__heading"},"Whose turn table",-1)),T[7]||(T[7]=o("p",{class:"settings-sheet__rules-note"}," The rows in force, first match wins. Read-only here: ask Claude to change rules.table through /api/config. ",-1)),B.value.length?(r(),i("ol",Ar,[(r(!0),i(V,null,N(B.value,(x,P)=>(r(),i("li",{key:P,class:"settings-sheet__rule"},[o("span",Rr,h(x.when),1),o("span",Er,h(x.then),1)]))),128))])):(r(),i("p",Or,"Save the workspace to see its rows.")),o("div",{class:"settings-sheet__actions"},[o("button",{type:"button",class:"btn btn--danger",onClick:Z}," Delete workspace ")])],64)):(r(),i("p",wr,"No workspaces yet. Add one on the left."))])]))])])):C("",!0)}}),Ir=j(Dr,[["__scopeId","data-v-779d567d"]]),Br={class:"app__shell"},Vr=["inert"],Wr={id:"wt",class:"dashboard dashboard--fit"},Ur=["inert"],Nr={class:"dashboard__main"},jr=U({__name:"App",setup(e){const t=g(()=>!!m.workspace.id&&!m.workspace.connectors.length),s=g(()=>Dt.value!==null);return X(ut,Is,{flush:"post"}),hs("Escape",Zs,{target:document}),ts(()=>{Gs()}),(a,n)=>(r(),i("div",{class:"app",style:ss(p(ut))},[O(Cn,{inert:s.value,onSettings:n[0]||(n[0]=l=>p(b).settings=!0)},null,8,["inert"]),o("div",Br,[O(qn,{inert:s.value,onReport:n[1]||(n[1]=l=>p(b).feedback=!0)},null,8,["inert"]),p(pt).length?(r(),i("div",{key:0,class:"alert",inert:s.value},h(p(pt).join(" · ")),9,Vr)):C("",!0),o("div",Wr,[n[3]||(n[3]=o("canvas",{id:"backdrop",class:"dashboard__backdrop","aria-hidden":"true"},null,-1)),O(mo,{inert:s.value},null,8,["inert"]),t.value?(r(),q(wl,{key:0,inert:s.value},null,8,["inert"])):(r(),i("div",{key:1,class:"dashboard__layout",inert:s.value},[o("div",Nr,[O(ra,{class:"dashboard__move"}),O(ya,{class:"dashboard__todo"}),O(Ma,{class:"dashboard__waiting"})]),O(vl,{class:"dashboard__feed",onOpen:n[2]||(n[2]=l=>p(b).modal=l)})],8,Ur)),O(Zl),O(Ir),O(Bl)])])],4))}}),Pr=j(jr,[["__scopeId","data-v-f146b085"]]);ns(Pr).mount("#app");nn();Bs();
|